mirror of
https://github.com/mangosfour/server.git
synced 2025-12-15 19:37:02 +00:00
Merge commit 'origin/master' into 308
Conflicts: src/game/ObjectMgr.cpp src/shared/revision_nr.h
This commit is contained in:
commit
7a8a1a71bf
67 changed files with 1401 additions and 937 deletions
|
|
@ -3,6 +3,7 @@
|
|||
#include <stdio.h>
|
||||
#include <deque>
|
||||
#include <set>
|
||||
#include <cstdlib>
|
||||
|
||||
#ifdef WIN32
|
||||
#include "direct.h"
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
DROP TABLE IF EXISTS `db_version`;
|
||||
CREATE TABLE `db_version` (
|
||||
`version` varchar(120) default NULL,
|
||||
`required_7133_02_mangos_spell_loot_template` bit(1) default NULL
|
||||
`required_7156_01_mangos_spell_proc_event` bit(1) default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
|
||||
|
||||
--
|
||||
|
|
@ -819,7 +819,7 @@ CREATE TABLE `creature_template` (
|
|||
LOCK TABLES `creature_template` WRITE;
|
||||
/*!40000 ALTER TABLE `creature_template` DISABLE KEYS */;
|
||||
INSERT INTO `creature_template` VALUES
|
||||
(1,1,10045,0,10045,0,'Waypoint(Only GM can see it)','Visual',NULL,1,1,64,64,0,0,0,35,35,0,0.91,1,0,14,15,0,100,2000,2200,4096,0,8,0,0,0,0,1.76,2.42,100,8,5242886,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,3,0,1,0,0,0x82,'');
|
||||
(1,1,10045,0,10045,0,'Waypoint(Only GM can see it)','Visual',NULL,1,1,64,64,0,0,0,35,35,0,0.91,1,0,14,15,0,100,2000,2200,4096,0,0,0,0,0,0,1.76,2.42,100,8,5242886,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,3,0,1,0,0,0x82,'');
|
||||
/*!40000 ALTER TABLE `creature_template` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
|
|
@ -1445,6 +1445,7 @@ CREATE TABLE `instance_template` (
|
|||
`levelMin` tinyint(3) unsigned NOT NULL default '0',
|
||||
`levelMax` tinyint(3) unsigned NOT NULL default '0',
|
||||
`maxPlayers` tinyint(3) unsigned NOT NULL default '0',
|
||||
`maxPlayersHeroic` tinyint(3) unsigned NOT NULL default '0',
|
||||
`reset_delay` int(10) unsigned NOT NULL default '0',
|
||||
`startLocX` float default NULL,
|
||||
`startLocY` float default NULL,
|
||||
|
|
@ -1461,32 +1462,35 @@ CREATE TABLE `instance_template` (
|
|||
LOCK TABLES `instance_template` WRITE;
|
||||
/*!40000 ALTER TABLE `instance_template` DISABLE KEYS */;
|
||||
INSERT INTO `instance_template` VALUES
|
||||
(33,0,22,30,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(34,0,24,32,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(36,0,15,20,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(43,0,15,21,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(47,0,29,38,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(48,0,24,32,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(70,0,35,47,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(90,0,29,38,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(109,0,45,55,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(129,0,37,46,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(189,0,34,45,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(209,0,44,54,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(229,0,58,0,10,120000,78.5083,-225.044,49.839,5.1,''),
|
||||
(230,0,52,0,5,7200,NULL,NULL,NULL,NULL,''),
|
||||
(249,0,60,0,40,432000,NULL,NULL,NULL,NULL,''),
|
||||
(289,0,57,0,5,7200,NULL,NULL,NULL,NULL,''),
|
||||
(309,0,60,0,20,259200,NULL,NULL,NULL,NULL,''),
|
||||
(329,0,58,60,5,7200,NULL,NULL,NULL,NULL,''),
|
||||
(349,0,46,55,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(389,0,13,18,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(409,0,60,0,40,604800,NULL,NULL,NULL,NULL,''),
|
||||
(429,0,55,60,5,7200,NULL,NULL,NULL,NULL,''),
|
||||
(469,0,60,0,40,604800,NULL,NULL,NULL,NULL,''),
|
||||
(509,0,60,0,20,259200,NULL,NULL,NULL,NULL,''),
|
||||
(531,0,60,0,40,604800,NULL,NULL,NULL,NULL,''),
|
||||
(533,0,60,0,40,604800,NULL,NULL,NULL,NULL,'');
|
||||
(33,0,22,30,10,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(34,0,24,32,10,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(36,0,15,20,10,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(43,0,15,21,10,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(47,0,29,38,10,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(48,0,24,32,10,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(70,0,35,47,10,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(90,0,29,38,10,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(109,0,45,55,10,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(129,0,37,46,10,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(189,0,34,45,10,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(209,0,44,54,10,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(229,0,58,0,10,10,120000,78.5083,-225.044,49.839,5.1,''),
|
||||
(230,0,52,0,5,5,7200,NULL,NULL,NULL,NULL,''),
|
||||
(249,0,60,0,40,40,432000,NULL,NULL,NULL,NULL,''),
|
||||
(289,0,57,0,5,5,7200,NULL,NULL,NULL,NULL,''),
|
||||
(309,0,60,0,20,20,259200,NULL,NULL,NULL,NULL,''),
|
||||
(329,0,58,60,5,5,7200,NULL,NULL,NULL,NULL,''),
|
||||
(349,0,46,55,10,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(389,0,13,18,10,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(409,0,60,0,40,40,604800,NULL,NULL,NULL,NULL,''),
|
||||
(429,0,55,60,5,5,7200,NULL,NULL,NULL,NULL,''),
|
||||
(469,0,60,0,40,40,604800,NULL,NULL,NULL,NULL,''),
|
||||
(509,0,60,0,20,20,259200,NULL,NULL,NULL,NULL,''),
|
||||
(531,0,60,0,40,40,604800,NULL,NULL,NULL,NULL,''),
|
||||
(533,0,80,0,10,25,0,NULL,NULL,NULL,NULL,''),
|
||||
(615,0,80,0,10,25,0,NULL,NULL,NULL,NULL,''),
|
||||
(616,0,80,0,10,25,0,NULL,NULL,NULL,NULL,''),
|
||||
(624,0,80,0,10,25,0,NULL,NULL,NULL,NULL,'');
|
||||
/*!40000 ALTER TABLE `instance_template` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
|
|
@ -11765,6 +11769,7 @@ INSERT INTO `playercreateinfo_spell` VALUES
|
|||
(7,9,22027,'Remove Insignia'),
|
||||
(7,9,22810,'Opening - No Text'),
|
||||
(7,9,45927,'Summon Friend'),
|
||||
(7,9,58284,'Chaos Bolt Passive'),
|
||||
(7,9,61437,'Opening'),
|
||||
(8,1,78,'Heroic Strike'),
|
||||
(8,1,81,'Dodge'),
|
||||
|
|
@ -12379,6 +12384,7 @@ INSERT INTO `playercreateinfo_spell` VALUES
|
|||
(10,9,28730,'Arcane Torrent'),
|
||||
(10,9,28734,'Mana Tap'),
|
||||
(10,9,28877,'Arcane Affinity'),
|
||||
(10,9,58284,'Chaos Bolt Passive'),
|
||||
(11,1,78,'Heroic Strike'),
|
||||
(11,1,81,'Dodge'),
|
||||
(11,1,107,'Block'),
|
||||
|
|
@ -16856,6 +16862,7 @@ INSERT INTO `spell_proc_event` VALUES
|
|||
(44394, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0.000000, 0.000000, 0),
|
||||
(44395, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0.000000, 0.000000, 0),
|
||||
(44396, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0.000000, 0.000000, 0),
|
||||
(44401, 0x00000000, 3, 0x00200000, 0x00000000, 0x00000000, 0x00000000, 0x00000FFF, 0.000000, 0.000000, 0),
|
||||
(44404, 0x00000000, 3, 0x20000021, 0x00009000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
||||
(44445, 0x00000000, 3, 0x00000013, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
||||
(44446, 0x00000000, 3, 0x00000013, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
||||
|
|
@ -17042,8 +17049,8 @@ INSERT INTO `spell_proc_event` VALUES
|
|||
(53221, 0x00000000, 9, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
||||
(53222, 0x00000000, 9, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
||||
(53224, 0x00000000, 9, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
||||
(53228, 0x00000000, 9, 0x00000020, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
||||
(53232, 0x00000000, 9, 0x00000020, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
||||
(53228, 0x00000000, 9, 0x00000020, 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
||||
(53232, 0x00000000, 9, 0x00000020, 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
||||
(53256, 0x00000000, 9, 0x00000800, 0x00800001, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
(53259, 0x00000000, 9, 0x00000800, 0x00800001, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
(53260, 0x00000000, 9, 0x00000800, 0x00800001, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
|
|
@ -17059,6 +17066,9 @@ INSERT INTO `spell_proc_event` VALUES
|
|||
(53384, 0x00000000, 10, 0x00800000, 0x00020000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
(53486, 0x00000000, 10, 0x00800000, 0x00028000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
(53488, 0x00000000, 10, 0x00800000, 0x00028000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
(53501, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
(53502, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
(53503, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||
(53551, 0x00000000, 10, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
||||
(53552, 0x00000000, 10, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
||||
(53553, 0x00000000, 10, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ CREATE TABLE `spell_proc_event` (
|
|||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records
|
||||
-- Records
|
||||
-- ----------------------------
|
||||
INSERT INTO `spell_proc_event` VALUES
|
||||
(324, 0x00000000, 0, 0x0000000000000000, 0x00000000, 0x00000000, 0, 0, 3),
|
||||
|
|
@ -703,4 +703,4 @@ INSERT INTO `spell_proc_event` VALUES
|
|||
(60572, 0x00000000, 11, 0x0000000090100000, 0x00000000, 0x00000000, 0, 0, 0),
|
||||
(60617, 0x00000000, 0, 0x0000000000000000, 0x00000000, 0x00000020, 0, 0, 0),
|
||||
(60826, 0x00000000, 15, 0x0000000001400000, 0x00000000, 0x00000000, 0, 0, 0),
|
||||
(61324, 0x00000000, 10, 0x0002000000000000, 0x00000000, 0x00000000, 0, 0, 0);
|
||||
(61324, 0x00000000, 10, 0x0002000000000000, 0x00000000, 0x00000000, 0, 0, 0);
|
||||
|
|
|
|||
|
|
@ -14,4 +14,4 @@ INSERT INTO `spell_proc_event` VALUES (48111, 0x00, 0, 0x00000000, 0x00000000, 0
|
|||
|
||||
-- (48113) Prayer of Mending (Rank 3)
|
||||
DELETE FROM `spell_proc_event` WHERE `entry` IN (48113);
|
||||
INSERT INTO `spell_proc_event` VALUES (48113, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x000A02A8, 0x00000000, 0.000000, 0.000000, 0);
|
||||
INSERT INTO `spell_proc_event` VALUES (48113, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x000A02A8, 0x00000000, 0.000000, 0.000000, 0);
|
||||
|
|
|
|||
|
|
@ -10,4 +10,4 @@ DELETE FROM character_spell WHERE `spell` IN (
|
|||
|
||||
/*old Shadow Resistance, leaned as racial passive of race 5 */
|
||||
DELETE FROM character_spell USING character_spell INNER JOIN characters ON character_spell.guid = characters.guid
|
||||
WHERE character_spell.spell = 20579 AND characters.race <> 5;
|
||||
WHERE character_spell.spell = 20579 AND characters.race <> 5;
|
||||
|
|
|
|||
|
|
@ -20,4 +20,4 @@ INSERT INTO `spell_proc_event` VALUES (44395, 0x00, 0, 0x00000000, 0x00000000, 0
|
|||
DELETE FROM `spell_proc_event` WHERE `entry` IN (44396);
|
||||
INSERT INTO `spell_proc_event` VALUES (44396, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0.000000, 0.000000, 0);
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
12
sql/updates/7141_01_mangos_instance_template.sql
Normal file
12
sql/updates/7141_01_mangos_instance_template.sql
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_7133_02_mangos_spell_loot_template required_7141_01_mangos_instance_template bit;
|
||||
|
||||
ALTER TABLE instance_template ADD maxPlayersHeroic tinyint(3) unsigned NOT NULL default '0' AFTER maxPlayers;
|
||||
|
||||
UPDATE instance_template SET maxPlayersHeroic = maxPlayers;
|
||||
|
||||
DELETE FROM instance_template WHERE map IN (533,615,616,624);
|
||||
INSERT INTO instance_template VALUES
|
||||
(533,0,80,0,10,25,0,NULL,NULL,NULL,NULL,''),
|
||||
(615,0,80,0,10,25,0,NULL,NULL,NULL,NULL,''),
|
||||
(616,0,80,0,10,25,0,NULL,NULL,NULL,NULL,''),
|
||||
(624,0,80,0,10,25,0,NULL,NULL,NULL,NULL,'');
|
||||
4
sql/updates/7147_01_mangos_creature_template.sql
Normal file
4
sql/updates/7147_01_mangos_creature_template.sql
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_7141_01_mangos_instance_template required_7147_01_mangos_creature_template bit;
|
||||
|
||||
UPDATE creature_template
|
||||
SET family = 0 WHERE entry = 1;
|
||||
21
sql/updates/7149_01_mangos_spell_proc_event.sql
Normal file
21
sql/updates/7149_01_mangos_spell_proc_event.sql
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_7147_01_mangos_creature_template required_7149_01_mangos_spell_proc_event bit;
|
||||
|
||||
-- (53501) Sheath of Light (Rank 1)
|
||||
DELETE FROM `spell_proc_event` WHERE `entry` IN (53501);
|
||||
INSERT INTO `spell_proc_event` VALUES (53501, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0);
|
||||
|
||||
-- (53502) Sheath of Light (Rank 2)
|
||||
DELETE FROM `spell_proc_event` WHERE `entry` IN (53502);
|
||||
INSERT INTO `spell_proc_event` VALUES (53502, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0);
|
||||
|
||||
-- (53503) Sheath of Light (Rank 3)
|
||||
DELETE FROM `spell_proc_event` WHERE `entry` IN (53503);
|
||||
INSERT INTO `spell_proc_event` VALUES (53503, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0);
|
||||
|
||||
-- (53228) Rapid Recuperation (Rank 1)
|
||||
DELETE FROM `spell_proc_event` WHERE `entry` IN (53228);
|
||||
INSERT INTO `spell_proc_event` VALUES (53228, 0x00, 9, 0x00000020, 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0);
|
||||
|
||||
-- (53232) Rapid Recuperation (Rank 2)
|
||||
DELETE FROM `spell_proc_event` WHERE `entry` IN (53232);
|
||||
INSERT INTO `spell_proc_event` VALUES (53232, 0x00, 9, 0x00000020, 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0);
|
||||
10
sql/updates/7150_01_mangos_playercreateinfo_spell.sql
Normal file
10
sql/updates/7150_01_mangos_playercreateinfo_spell.sql
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_7149_01_mangos_spell_proc_event required_7150_01_mangos_playercreateinfo_spell bit;
|
||||
|
||||
DELETE FROM `playercreateinfo_spell` WHERE Spell = 58284;
|
||||
|
||||
INSERT INTO `playercreateinfo_spell` VALUES
|
||||
(1,9,58284,'Chaos Bolt Passive'),
|
||||
(2,9,58284,'Chaos Bolt Passive'),
|
||||
(5,9,58284,'Chaos Bolt Passive'),
|
||||
(7,9,58284,'Chaos Bolt Passive'),
|
||||
(10,9,58284,'Chaos Bolt Passive');
|
||||
5
sql/updates/7156_01_mangos_spell_proc_event.sql
Normal file
5
sql/updates/7156_01_mangos_spell_proc_event.sql
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_7150_01_mangos_playercreateinfo_spell required_7156_01_mangos_spell_proc_event bit;
|
||||
|
||||
-- (44401) Missile Barrage ()
|
||||
DELETE FROM `spell_proc_event` WHERE `entry` IN (44401);
|
||||
INSERT INTO `spell_proc_event` VALUES (44401, 0x00, 3, 0x00200000, 0x00000000, 0x00000000, 0x00000000, 0x00000FFF, 0.000000, 0.000000, 0);
|
||||
|
|
@ -145,6 +145,11 @@ pkgdata_DATA = \
|
|||
7118_01_mangos_skill_discovery_template.sql \
|
||||
7133_01_mangos_skill_discovery_template.sql \
|
||||
7133_02_mangos_spell_loot_template.sql \
|
||||
7141_01_mangos_instance_template.sql \
|
||||
7147_01_mangos_creature_template.sql \
|
||||
7149_01_mangos_spell_proc_event.sql \
|
||||
7150_01_mangos_playercreateinfo_spell.sql \
|
||||
7156_01_mangos_spell_proc_event.sql \
|
||||
README
|
||||
|
||||
## Additional files to include when running 'make dist'
|
||||
|
|
@ -270,4 +275,9 @@ EXTRA_DIST = \
|
|||
7118_01_mangos_skill_discovery_template.sql \
|
||||
7133_01_mangos_skill_discovery_template.sql \
|
||||
7133_02_mangos_spell_loot_template.sql \
|
||||
7141_01_mangos_instance_template.sql \
|
||||
7147_01_mangos_creature_template.sql \
|
||||
7149_01_mangos_spell_proc_event.sql \
|
||||
7150_01_mangos_playercreateinfo_spell.sql \
|
||||
7156_01_mangos_spell_proc_event.sql \
|
||||
README
|
||||
|
|
|
|||
|
|
@ -30,10 +30,10 @@ See an example below:
|
|||
| Counter show number of sql update in updates list for provided revision
|
||||
| and set proper order for sql updates for same revision
|
||||
|
|
||||
MaNGOS commit revison related to sql update.
|
||||
MaNGOS commit revison related to sql update.
|
||||
It included in commit description in form [6936] as you can see at http://github.com/mangos/mangos/commits/master
|
||||
|
||||
After appling this update DB compatiable with database that include this sql update.
|
||||
SQL update include special protection against multiply and wrong order SQL updates apply.
|
||||
So attempt apply sql update to more old DB without previous SQL update in list for targeted database
|
||||
So attempt apply sql update to more old DB without previous SQL update in list for targeted database
|
||||
or to DB with already applied this or later SQL update will generate error and not applied.
|
||||
|
|
|
|||
|
|
@ -325,6 +325,10 @@ void AchievementMgr::CheckAllAchievementCriteria()
|
|||
void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1, uint32 miscvalue2, Unit *unit, uint32 time)
|
||||
{
|
||||
sLog.outDetail("AchievementMgr::UpdateAchievementCriteria(%u, %u, %u, %u)", type, miscvalue1, miscvalue2, time);
|
||||
|
||||
if (!sWorld.getConfig(CONFIG_GM_ALLOW_ACHIEVEMENT_GAINS) && m_player->GetSession()->GetSecurity() > SEC_PLAYER)
|
||||
return;
|
||||
|
||||
AchievementCriteriaEntryList const& achievementCriteriaList = achievementmgr.GetAchievementCriteriaByType(type);
|
||||
for(AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i!=achievementCriteriaList.end(); ++i)
|
||||
{
|
||||
|
|
@ -907,14 +911,30 @@ AchievementCriteriaEntryList const& AchievementGlobalMgr::GetAchievementCriteria
|
|||
|
||||
void AchievementGlobalMgr::LoadAchievementCriteriaList()
|
||||
{
|
||||
if(sAchievementCriteriaStore.GetNumRows()==0)
|
||||
{
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
|
||||
sLog.outString("");
|
||||
sLog.outErrorDb(">> Loaded 0 achievement criteria.");
|
||||
return;
|
||||
}
|
||||
|
||||
barGoLink bar( sAchievementCriteriaStore.GetNumRows() );
|
||||
for (uint32 entryId = 0; entryId<sAchievementCriteriaStore.GetNumRows(); entryId++)
|
||||
{
|
||||
bar.step();
|
||||
|
||||
AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(entryId);
|
||||
if(!criteria)
|
||||
continue;
|
||||
|
||||
m_AchievementCriteriasByType[criteria->requiredType].push_back(criteria);
|
||||
}
|
||||
|
||||
sLog.outString();
|
||||
sLog.outErrorDb(">> Loaded %u achievement criteria.",m_AchievementCriteriasByType->size());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -923,15 +943,27 @@ void AchievementGlobalMgr::LoadCompletedAchievements()
|
|||
QueryResult *result = CharacterDatabase.Query("SELECT achievement FROM character_achievement GROUP BY achievement");
|
||||
|
||||
if(!result)
|
||||
return;
|
||||
{
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
|
||||
sLog.outString("");
|
||||
sLog.outString(">> Loaded 0 realm completed achievements . DB table `character_achievement` is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
barGoLink bar(result->GetRowCount());
|
||||
do
|
||||
{
|
||||
bar.step();
|
||||
Field *fields = result->Fetch();
|
||||
m_allCompletedAchievements.insert(fields[0].GetUInt32());
|
||||
} while(result->NextRow());
|
||||
|
||||
delete result;
|
||||
|
||||
sLog.outString("");
|
||||
sLog.outString(">> Loaded %u realm completed achievements.",m_allCompletedAchievements.size());
|
||||
}
|
||||
|
||||
void AchievementGlobalMgr::LoadRewards()
|
||||
|
|
@ -948,7 +980,7 @@ void AchievementGlobalMgr::LoadRewards()
|
|||
bar.step();
|
||||
|
||||
sLog.outString("");
|
||||
sLog.outString(">> Loaded 0 achievement rewards. DB table `achievement_reward` is empty.");
|
||||
sLog.outErrorDb(">> Loaded 0 achievement rewards. DB table `achievement_reward` is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -956,9 +988,9 @@ void AchievementGlobalMgr::LoadRewards()
|
|||
|
||||
do
|
||||
{
|
||||
Field *fields = result->Fetch();
|
||||
bar.step();
|
||||
|
||||
Field *fields = result->Fetch();
|
||||
uint32 entry = fields[0].GetUInt32();
|
||||
if (!sAchievementStore.LookupEntry(entry))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -409,9 +409,9 @@ void BattleGroundAB::_NodeDeOccupied(uint8 node)
|
|||
{
|
||||
WorldSafeLocsEntry const *ClosestGrave = NULL;
|
||||
Player *plr;
|
||||
for (std::vector<uint64>::iterator itr = ghost_list.begin(); itr != ghost_list.end(); ++itr)
|
||||
for (std::vector<uint64>::const_iterator itr = ghost_list.begin(); itr != ghost_list.end(); ++itr)
|
||||
{
|
||||
plr = objmgr.GetPlayer(*ghost_list.begin());
|
||||
plr = objmgr.GetPlayer(*itr);
|
||||
if( !plr )
|
||||
continue;
|
||||
if( !ClosestGrave )
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ bool LoginQueryHolder::Initialize()
|
|||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADDECLINEDNAMES, "SELECT genitive, dative, accusative, instrumental, prepositional FROM character_declinedname WHERE guid = '%u'",GUID_LOPART(m_guid));
|
||||
// in other case still be dummy query
|
||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGUILD, "SELECT guildid,rank FROM guild_member WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADARENAINFO, "SELECT arenateamid, played_week, played_season, personal_rating FROM arena_team_member WHERE guid='%u'", GUID_LOPART(m_guid));
|
||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADARENAINFO, "SELECT arenateamid, played_week, played_season, personal_rating FROM arena_team_member WHERE guid='%u'", GUID_LOPART(m_guid));
|
||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADACHIEVEMENTS, "SELECT achievement, date FROM character_achievement WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADCRITERIAPROGRESS,"SELECT criteria, counter, date FROM character_achievement_progress WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||
|
||||
|
|
|
|||
|
|
@ -1073,7 +1073,7 @@ Creature* ChatHandler::getSelectedCreature()
|
|||
if(!m_session)
|
||||
return NULL;
|
||||
|
||||
return ObjectAccessor::GetCreatureOrPet(*m_session->GetPlayer(),m_session->GetPlayer()->GetSelection());
|
||||
return ObjectAccessor::GetCreatureOrPetOrVehicle(*m_session->GetPlayer(),m_session->GetPlayer()->GetSelection());
|
||||
}
|
||||
|
||||
char* ChatHandler::extractKeyFromLink(char* text, char const* linkType, char** something1)
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ struct CreatureInfo
|
|||
uint32 rangeattacktime;
|
||||
uint32 unit_flags; // enum UnitFlags mask values
|
||||
uint32 dynamicflags;
|
||||
uint32 family; // enum CreatureFamily values for type==CREATURE_TYPE_BEAST, or 0 in another cases
|
||||
uint32 family; // enum CreatureFamily values (optional)
|
||||
uint32 trainer_type;
|
||||
uint32 trainer_spell;
|
||||
uint32 classNum;
|
||||
|
|
|
|||
|
|
@ -111,49 +111,51 @@ void GameEvent::LoadFromDB()
|
|||
if( !result )
|
||||
{
|
||||
mGameEvent.clear();
|
||||
sLog.outString(">> Table game_event is empty:");
|
||||
sLog.outString(">> Table game_event is empty!");
|
||||
sLog.outString();
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 count = 0;
|
||||
|
||||
barGoLink bar( result->GetRowCount() );
|
||||
do
|
||||
{
|
||||
++count;
|
||||
Field *fields = result->Fetch();
|
||||
|
||||
bar.step();
|
||||
|
||||
uint16 event_id = fields[0].GetUInt16();
|
||||
if(event_id==0)
|
||||
barGoLink bar( result->GetRowCount() );
|
||||
do
|
||||
{
|
||||
sLog.outErrorDb("`game_event` game event id (%i) is reserved and can't be used.",event_id);
|
||||
continue;
|
||||
}
|
||||
++count;
|
||||
Field *fields = result->Fetch();
|
||||
|
||||
GameEventData& pGameEvent = mGameEvent[event_id];
|
||||
uint64 starttime = fields[1].GetUInt64();
|
||||
pGameEvent.start = time_t(starttime);
|
||||
uint64 endtime = fields[2].GetUInt64();
|
||||
pGameEvent.end = time_t(endtime);
|
||||
pGameEvent.occurence = fields[3].GetUInt32();
|
||||
pGameEvent.length = fields[4].GetUInt32();
|
||||
bar.step();
|
||||
|
||||
if(pGameEvent.length==0) // length>0 is validity check
|
||||
{
|
||||
sLog.outErrorDb("`game_event` game event id (%i) have length 0 and can't be used.",event_id);
|
||||
continue;
|
||||
}
|
||||
uint16 event_id = fields[0].GetUInt16();
|
||||
if(event_id==0)
|
||||
{
|
||||
sLog.outErrorDb("`game_event` game event id (%i) is reserved and can't be used.",event_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
pGameEvent.description = fields[5].GetCppString();
|
||||
GameEventData& pGameEvent = mGameEvent[event_id];
|
||||
uint64 starttime = fields[1].GetUInt64();
|
||||
pGameEvent.start = time_t(starttime);
|
||||
uint64 endtime = fields[2].GetUInt64();
|
||||
pGameEvent.end = time_t(endtime);
|
||||
pGameEvent.occurence = fields[3].GetUInt32();
|
||||
pGameEvent.length = fields[4].GetUInt32();
|
||||
|
||||
} while( result->NextRow() );
|
||||
if(pGameEvent.length==0) // length>0 is validity check
|
||||
{
|
||||
sLog.outErrorDb("`game_event` game event id (%i) have length 0 and can't be used.",event_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Loaded %u game events", count );
|
||||
delete result;
|
||||
pGameEvent.description = fields[5].GetCppString();
|
||||
|
||||
} while( result->NextRow() );
|
||||
delete result;
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Loaded %u game events", count );
|
||||
}
|
||||
|
||||
mGameEventCreatureGuids.resize(mGameEvent.size()*2-1);
|
||||
// 1 2
|
||||
|
|
@ -163,8 +165,8 @@ void GameEvent::LoadFromDB()
|
|||
count = 0;
|
||||
if( !result )
|
||||
{
|
||||
barGoLink bar2(1);
|
||||
bar2.step();
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded %u creatures in game events", count );
|
||||
|
|
@ -172,12 +174,12 @@ void GameEvent::LoadFromDB()
|
|||
else
|
||||
{
|
||||
|
||||
barGoLink bar2( result->GetRowCount() );
|
||||
barGoLink bar( result->GetRowCount() );
|
||||
do
|
||||
{
|
||||
Field *fields = result->Fetch();
|
||||
|
||||
bar2.step();
|
||||
bar.step();
|
||||
|
||||
uint32 guid = fields[0].GetUInt32();
|
||||
int16 event_id = fields[1].GetInt16();
|
||||
|
|
@ -195,9 +197,10 @@ void GameEvent::LoadFromDB()
|
|||
crelist.push_back(guid);
|
||||
|
||||
} while( result->NextRow() );
|
||||
delete result;
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Loaded %u creatures in game events", count );
|
||||
delete result;
|
||||
}
|
||||
|
||||
mGameEventGameobjectGuids.resize(mGameEvent.size()*2-1);
|
||||
|
|
@ -208,8 +211,8 @@ void GameEvent::LoadFromDB()
|
|||
count = 0;
|
||||
if( !result )
|
||||
{
|
||||
barGoLink bar3(1);
|
||||
bar3.step();
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded %u gameobjects in game events", count );
|
||||
|
|
@ -217,12 +220,12 @@ void GameEvent::LoadFromDB()
|
|||
else
|
||||
{
|
||||
|
||||
barGoLink bar3( result->GetRowCount() );
|
||||
barGoLink bar( result->GetRowCount() );
|
||||
do
|
||||
{
|
||||
Field *fields = result->Fetch();
|
||||
|
||||
bar3.step();
|
||||
bar.step();
|
||||
|
||||
uint32 guid = fields[0].GetUInt32();
|
||||
int16 event_id = fields[1].GetInt16();
|
||||
|
|
@ -240,10 +243,10 @@ void GameEvent::LoadFromDB()
|
|||
golist.push_back(guid);
|
||||
|
||||
} while( result->NextRow() );
|
||||
delete result;
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Loaded %u gameobjects in game events", count );
|
||||
|
||||
delete result;
|
||||
}
|
||||
|
||||
mGameEventModelEquip.resize(mGameEvent.size());
|
||||
|
|
@ -256,8 +259,8 @@ void GameEvent::LoadFromDB()
|
|||
count = 0;
|
||||
if( !result )
|
||||
{
|
||||
barGoLink bar3(1);
|
||||
bar3.step();
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded %u model/equipment changes in game events", count );
|
||||
|
|
@ -265,12 +268,12 @@ void GameEvent::LoadFromDB()
|
|||
else
|
||||
{
|
||||
|
||||
barGoLink bar3( result->GetRowCount() );
|
||||
barGoLink bar( result->GetRowCount() );
|
||||
do
|
||||
{
|
||||
Field *fields = result->Fetch();
|
||||
|
||||
bar3.step();
|
||||
bar.step();
|
||||
uint32 guid = fields[0].GetUInt32();
|
||||
uint16 event_id = fields[1].GetUInt16();
|
||||
|
||||
|
|
@ -300,10 +303,10 @@ void GameEvent::LoadFromDB()
|
|||
equiplist.push_back(std::pair<uint32, ModelEquip>(guid, newModelEquipSet));
|
||||
|
||||
} while( result->NextRow() );
|
||||
delete result;
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Loaded %u model/equipment changes in game events", count );
|
||||
|
||||
delete result;
|
||||
}
|
||||
|
||||
mGameEventQuests.resize(mGameEvent.size());
|
||||
|
|
@ -313,8 +316,8 @@ void GameEvent::LoadFromDB()
|
|||
count = 0;
|
||||
if( !result )
|
||||
{
|
||||
barGoLink bar3(1);
|
||||
bar3.step();
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded %u quests additions in game events", count );
|
||||
|
|
@ -322,12 +325,12 @@ void GameEvent::LoadFromDB()
|
|||
else
|
||||
{
|
||||
|
||||
barGoLink bar3( result->GetRowCount() );
|
||||
barGoLink bar( result->GetRowCount() );
|
||||
do
|
||||
{
|
||||
Field *fields = result->Fetch();
|
||||
|
||||
bar3.step();
|
||||
bar.step();
|
||||
uint32 id = fields[0].GetUInt32();
|
||||
uint32 quest = fields[1].GetUInt32();
|
||||
uint16 event_id = fields[2].GetUInt16();
|
||||
|
|
@ -343,10 +346,10 @@ void GameEvent::LoadFromDB()
|
|||
questlist.push_back(QuestRelation(id, quest));
|
||||
|
||||
} while( result->NextRow() );
|
||||
delete result;
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Loaded %u quests additions in game events", count );
|
||||
|
||||
delete result;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -354,7 +354,7 @@ void GameObject::Update(uint32 /*p_time*/)
|
|||
{
|
||||
Unit *caster = owner ? owner : ok;
|
||||
|
||||
caster->CastSpell(ok, goInfo->trap.spellId, true);
|
||||
caster->CastSpell(ok, goInfo->trap.spellId, true, 0, 0, GetGUID());
|
||||
m_cooldownTime = time(NULL) + 4; // 4 seconds
|
||||
|
||||
if(NeedDespawn)
|
||||
|
|
@ -404,7 +404,7 @@ void GameObject::Update(uint32 /*p_time*/)
|
|||
for (; it != end; it++)
|
||||
{
|
||||
Unit* owner = Unit::GetUnit(*this, uint64(*it));
|
||||
if (owner) owner->CastSpell(owner, spellId, false);
|
||||
if (owner) owner->CastSpell(owner, spellId, false, 0, 0, GetGUID());
|
||||
}
|
||||
|
||||
m_unique_users.clear();
|
||||
|
|
@ -809,7 +809,7 @@ void GameObject::TriggeringLinkedGameObject( uint32 trapEntry, Unit* target)
|
|||
// found correct GO
|
||||
// FIXME: when GO casting will be implemented trap must cast spell to target
|
||||
if(trapGO)
|
||||
target->CastSpell(target,trapSpell,true);
|
||||
target->CastSpell(target,trapSpell,true, 0, 0, GetGUID());
|
||||
}
|
||||
|
||||
GameObject* GameObject::LookupFishingHoleAround(float range)
|
||||
|
|
|
|||
|
|
@ -349,7 +349,7 @@ struct GameObjectInfo
|
|||
uint32 state2Name; //3
|
||||
} destructibleBuilding;
|
||||
//34 GAMEOBJECT_TYPE_TRAPDOOR
|
||||
struct
|
||||
struct
|
||||
{
|
||||
uint32 whenToPause; // 0
|
||||
uint32 startOpen; // 1
|
||||
|
|
|
|||
|
|
@ -1586,7 +1586,7 @@ void Guild::DisplayGuildBankLogs(WorldSession *session, uint8 TabId)
|
|||
{
|
||||
data << uint8((*itr)->LogEntry);
|
||||
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_REPAIR_MONEY ||
|
||||
(*itr)->LogEntry == GUILD_BANK_LOG_UNK1 ||
|
||||
|
|
@ -1616,7 +1616,7 @@ void Guild::DisplayGuildBankLogs(WorldSession *session, uint8 TabId)
|
|||
{
|
||||
data << uint8((*itr)->LogEntry);
|
||||
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_REPAIR_MONEY ||
|
||||
(*itr)->LogEntry == GUILD_BANK_LOG_UNK1 ||
|
||||
|
|
|
|||
|
|
@ -356,8 +356,8 @@ void InstanceSaveManager::PackInstances()
|
|||
bar.step();
|
||||
}
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Instance numbers remapped, next instance id is %u", InstanceNumber );
|
||||
sLog.outString();
|
||||
}
|
||||
|
||||
void InstanceSaveManager::LoadResetTimes()
|
||||
|
|
@ -449,7 +449,7 @@ void InstanceSaveManager::LoadResetTimes()
|
|||
// add the global reset times to the priority queue
|
||||
for(uint32 i = 0; i < sInstanceTemplate.MaxEntry; i++)
|
||||
{
|
||||
InstanceTemplate* temp = (InstanceTemplate*)objmgr.GetInstanceTemplate(i);
|
||||
InstanceTemplate const* temp = objmgr.GetInstanceTemplate(i);
|
||||
if(!temp) continue;
|
||||
// only raid/heroic maps have a global reset time
|
||||
const MapEntry* entry = sMapStore.LookupEntry(temp->map);
|
||||
|
|
@ -578,7 +578,7 @@ void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, bool warn, uint32 timeLe
|
|||
{
|
||||
// global reset for all instances of the given map
|
||||
// note: this isn't fast but it's meant to be executed very rarely
|
||||
Map *map = (MapInstanced*)MapManager::Instance().GetBaseMap(mapid);
|
||||
Map const *map = MapManager::Instance().GetBaseMap(mapid);
|
||||
if(!map->Instanceable())
|
||||
return;
|
||||
uint64 now = (uint64)time(NULL);
|
||||
|
|
@ -586,7 +586,7 @@ void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, bool warn, uint32 timeLe
|
|||
if(!warn)
|
||||
{
|
||||
// this is called one minute before the reset time
|
||||
InstanceTemplate* temp = (InstanceTemplate*)objmgr.GetInstanceTemplate(mapid);
|
||||
InstanceTemplate const* temp = objmgr.GetInstanceTemplate(mapid);
|
||||
if(!temp || !temp->reset_delay)
|
||||
{
|
||||
sLog.outError("InstanceSaveManager::ResetOrWarnAll: no instance template or reset delay for map %d", mapid);
|
||||
|
|
|
|||
|
|
@ -3848,7 +3848,7 @@ bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/)
|
|||
if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
|
||||
continue;
|
||||
|
||||
m_session->GetPlayer()->learnSpell(skillLine->spellId);
|
||||
m_session->GetPlayer()->learnSpell(skillLine->spellId,false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3919,7 +3919,7 @@ bool ChatHandler::HandleLearnAllRecipesCommand(const char* args)
|
|||
continue;
|
||||
|
||||
if( !target->HasSpell(spellInfo->Id) )
|
||||
m_session->GetPlayer()->learnSpell(skillLine->spellId);
|
||||
m_session->GetPlayer()->learnSpell(skillLine->spellId,false);
|
||||
}
|
||||
|
||||
uint16 maxLevel = target->GetPureMaxSkillValue(skillInfo->id);
|
||||
|
|
|
|||
|
|
@ -1638,7 +1638,7 @@ bool ChatHandler::HandleLearnAllCommand(const char* /*args*/)
|
|||
continue;
|
||||
}
|
||||
|
||||
m_session->GetPlayer()->learnSpell(spell);
|
||||
m_session->GetPlayer()->learnSpell(spell,false);
|
||||
}
|
||||
|
||||
SendSysMessage(LANG_COMMAND_LEARN_MANY_SPELLS);
|
||||
|
|
@ -1678,7 +1678,7 @@ bool ChatHandler::HandleLearnAllGMCommand(const char* /*args*/)
|
|||
continue;
|
||||
}
|
||||
|
||||
m_session->GetPlayer()->learnSpell(spell);
|
||||
m_session->GetPlayer()->learnSpell(spell,false);
|
||||
}
|
||||
|
||||
SendSysMessage(LANG_LEARNING_GM_SKILLS);
|
||||
|
|
@ -1726,7 +1726,7 @@ bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)
|
|||
if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
|
||||
continue;
|
||||
|
||||
m_session->GetPlayer()->learnSpell(i);
|
||||
m_session->GetPlayer()->learnSpell(i,false);
|
||||
}
|
||||
|
||||
SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS);
|
||||
|
|
@ -1738,7 +1738,7 @@ static void learnAllHighRanks(Player* player, uint32 spellid)
|
|||
SpellChainMapNext const& nextMap = spellmgr.GetSpellChainNext();
|
||||
for(SpellChainMapNext::const_iterator itr = nextMap.lower_bound(spellid); itr != nextMap.upper_bound(spellid); ++itr)
|
||||
{
|
||||
player->learnSpell(itr->second);
|
||||
player->learnSpell(itr->second,false);
|
||||
learnAllHighRanks(player,itr->second);
|
||||
}
|
||||
}
|
||||
|
|
@ -1781,7 +1781,7 @@ bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/)
|
|||
continue;
|
||||
|
||||
// learn highest rank of talent
|
||||
player->learnSpell(spellid);
|
||||
player->learnSpell(spellid,false);
|
||||
|
||||
// and learn all non-talent spell ranks (recursive by tree)
|
||||
learnAllHighRanks(player,spellid);
|
||||
|
|
@ -1795,7 +1795,7 @@ bool ChatHandler::HandleLearnAllLangCommand(const char* /*args*/)
|
|||
{
|
||||
// skipping UNIVERSAL language (0)
|
||||
for(int i = 1; i < LANGUAGES_COUNT; ++i)
|
||||
m_session->GetPlayer()->learnSpell(lang_description[i].spell_id);
|
||||
m_session->GetPlayer()->learnSpell(lang_description[i].spell_id,false);
|
||||
|
||||
SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG);
|
||||
return true;
|
||||
|
|
@ -1869,7 +1869,7 @@ bool ChatHandler::HandleLearnCommand(const char* args)
|
|||
return false;
|
||||
}
|
||||
|
||||
targetPlayer->learnSpell(spell);
|
||||
targetPlayer->learnSpell(spell,false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ class LootStore
|
|||
{
|
||||
public:
|
||||
explicit LootStore(char const* name, char const* entryName, bool ratesAllowed)
|
||||
: m_name(name), m_entryName(entryName), m_ratesAllowed(m_ratesAllowed) {}
|
||||
: m_name(name), m_entryName(entryName), m_ratesAllowed(ratesAllowed) {}
|
||||
virtual ~LootStore() { Clear(); }
|
||||
|
||||
void Verify() const;
|
||||
|
|
|
|||
|
|
@ -1528,10 +1528,10 @@ bool InstanceMap::CanEnter(Player *player)
|
|||
}
|
||||
|
||||
// cannot enter if the instance is full (player cap), GMs don't count
|
||||
InstanceTemplate const* iTemplate = objmgr.GetInstanceTemplate(GetId());
|
||||
if (!player->isGameMaster() && GetPlayersCountExceptGMs() >= iTemplate->maxPlayers)
|
||||
uint32 maxPlayers = GetMaxPlayers();
|
||||
if (!player->isGameMaster() && GetPlayersCountExceptGMs() >= maxPlayers)
|
||||
{
|
||||
sLog.outDetail("MAP: Instance '%u' of map '%s' cannot have more than '%u' players. Player '%s' rejected", GetInstanceId(), GetMapName(), iTemplate->maxPlayers, player->GetName());
|
||||
sLog.outDetail("MAP: Instance '%u' of map '%s' cannot have more than '%u' players. Player '%s' rejected", GetInstanceId(), GetMapName(), maxPlayers, player->GetName());
|
||||
player->SendTransferAborted(GetId(), TRANSFER_ABORT_MAX_PLAYERS);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1824,6 +1824,14 @@ void InstanceMap::SetResetSchedule(bool on)
|
|||
}
|
||||
}
|
||||
|
||||
uint32 InstanceMap::GetMaxPlayers() const
|
||||
{
|
||||
InstanceTemplate const* iTemplate = objmgr.GetInstanceTemplate(GetId());
|
||||
if(!iTemplate)
|
||||
return 0;
|
||||
return IsHeroic() ? iTemplate->maxPlayersHeroic : iTemplate->maxPlayers;
|
||||
}
|
||||
|
||||
/* ******* Battleground Instance Maps ******* */
|
||||
|
||||
BattleGroundMap::BattleGroundMap(uint32 id, time_t expiry, uint32 InstanceId)
|
||||
|
|
|
|||
|
|
@ -98,7 +98,8 @@ struct InstanceTemplate
|
|||
uint32 levelMin;
|
||||
uint32 levelMax;
|
||||
uint32 maxPlayers;
|
||||
uint32 reset_delay;
|
||||
uint32 maxPlayersHeroic;
|
||||
uint32 reset_delay; // FIX ME: now exist normal/heroic raids with possible different time of reset.
|
||||
float startLocX;
|
||||
float startLocY;
|
||||
float startLocZ;
|
||||
|
|
@ -364,6 +365,7 @@ class MANGOS_DLL_SPEC InstanceMap : public Map
|
|||
bool CanEnter(Player* player);
|
||||
void SendResetWarnings(uint32 timeLeft) const;
|
||||
void SetResetSchedule(bool on);
|
||||
uint32 GetMaxPlayers() const;
|
||||
private:
|
||||
bool m_resetAfterUnload;
|
||||
bool m_unloadWhenEmpty;
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ void WorldSession::HandleTrainerBuySpellOpcode( WorldPacket & recv_data )
|
|||
data << uint64(_player->GetGUID()) << uint32(0x016A);
|
||||
SendPacket(&data);
|
||||
|
||||
_player->learnSpell(spellId);
|
||||
_player->learnSpell(spellId,false);
|
||||
}
|
||||
|
||||
WorldPacket data(SMSG_TRAINER_BUY_SUCCEEDED, 12);
|
||||
|
|
|
|||
|
|
@ -58,8 +58,9 @@ uint32 GuidHigh2TypeId(uint32 guid_hi)
|
|||
case HIGHGUID_DYNAMICOBJECT:return TYPEID_DYNAMICOBJECT;
|
||||
case HIGHGUID_CORPSE: return TYPEID_CORPSE;
|
||||
case HIGHGUID_MO_TRANSPORT: return TYPEID_GAMEOBJECT;
|
||||
case HIGHGUID_VEHICLE: return TYPEID_UNIT;
|
||||
}
|
||||
return 10; // unknown
|
||||
return MAX_TYPEID; // unknown
|
||||
}
|
||||
|
||||
Object::Object( )
|
||||
|
|
@ -258,7 +259,7 @@ void Object::DestroyForPlayer(Player *target) const
|
|||
void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2) const
|
||||
{
|
||||
uint16 unk_flags = ((GetTypeId() == TYPEID_PLAYER) ? ((Player*)this)->m_movementInfo.unk1 : 0);
|
||||
|
||||
|
||||
if(GetTypeId() == TYPEID_UNIT)
|
||||
if(((Creature*)this)->isVehicle())
|
||||
unk_flags |= 0x20; // always allow pitch
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ enum TypeID
|
|||
TYPEID_AIGROUP = 8,
|
||||
TYPEID_AREATRIGGER = 9
|
||||
};
|
||||
#define MAX_TYPEID 10
|
||||
|
||||
uint32 GuidHigh2TypeId(uint32 guid_hi);
|
||||
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ ObjectAccessor::GetNPCIfCanInteractWith(Player const &player, uint64 guid, uint3
|
|||
}
|
||||
|
||||
Creature*
|
||||
ObjectAccessor::GetCreatureOrPet(WorldObject const &u, uint64 guid)
|
||||
ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const &u, uint64 guid)
|
||||
{
|
||||
if(Creature *unit = GetPet(guid))
|
||||
return unit;
|
||||
|
|
@ -164,18 +164,23 @@ ObjectAccessor::GetUnit(WorldObject const &u, uint64 guid)
|
|||
if(IS_PLAYER_GUID(guid))
|
||||
return FindPlayer(guid);
|
||||
|
||||
return GetCreatureOrPet(u, guid);
|
||||
return GetCreatureOrPetOrVehicle(u, guid);
|
||||
}
|
||||
|
||||
Corpse*
|
||||
ObjectAccessor::GetCorpse(WorldObject const &u, uint64 guid)
|
||||
{
|
||||
Corpse * ret = GetObjectInWorld(guid, (Corpse*)NULL);
|
||||
if(ret && ret->GetMapId() != u.GetMapId()) ret = NULL;
|
||||
if(!ret)
|
||||
return NULL;
|
||||
if(ret->GetMapId() != u.GetMapId())
|
||||
ret = NULL;
|
||||
if(ret->GetInstanceId() != u.GetInstanceId())
|
||||
return NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Object* ObjectAccessor::GetObjectByTypeMask(Player const &p, uint64 guid, uint32 typemask)
|
||||
Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const &p, uint64 guid, uint32 typemask)
|
||||
{
|
||||
Object *obj = NULL;
|
||||
|
||||
|
|
@ -187,7 +192,7 @@ Object* ObjectAccessor::GetObjectByTypeMask(Player const &p, uint64 guid, uint32
|
|||
|
||||
if(typemask & TYPEMASK_UNIT)
|
||||
{
|
||||
obj = GetCreatureOrPet(p,guid);
|
||||
obj = GetCreatureOrPetOrVehicle(p,guid);
|
||||
if(obj) return obj;
|
||||
}
|
||||
|
||||
|
|
@ -203,9 +208,9 @@ Object* ObjectAccessor::GetObjectByTypeMask(Player const &p, uint64 guid, uint32
|
|||
if(obj) return obj;
|
||||
}
|
||||
|
||||
if(typemask & TYPEMASK_ITEM)
|
||||
if(typemask & TYPEMASK_ITEM && p.GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
obj = p.GetItemByGuid( guid );
|
||||
obj = ((Player const &)p).GetItemByGuid( guid );
|
||||
if(obj) return obj;
|
||||
}
|
||||
|
||||
|
|
@ -216,15 +221,25 @@ GameObject*
|
|||
ObjectAccessor::GetGameObject(WorldObject const &u, uint64 guid)
|
||||
{
|
||||
GameObject * ret = GetObjectInWorld(guid, (GameObject*)NULL);
|
||||
if(ret && ret->GetMapId() != u.GetMapId()) ret = NULL;
|
||||
if(!ret)
|
||||
return NULL;
|
||||
if(ret->GetMapId() != u.GetMapId())
|
||||
ret = NULL;
|
||||
if(ret->GetInstanceId() != u.GetInstanceId())
|
||||
return NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
DynamicObject*
|
||||
ObjectAccessor::GetDynamicObject(Unit const &u, uint64 guid)
|
||||
ObjectAccessor::GetDynamicObject(WorldObject const &u, uint64 guid)
|
||||
{
|
||||
DynamicObject * ret = GetObjectInWorld(guid, (DynamicObject*)NULL);
|
||||
if(ret && ret->GetMapId() != u.GetMapId()) ret = NULL;
|
||||
if(!ret)
|
||||
return NULL;
|
||||
if(ret->GetMapId() != u.GetMapId())
|
||||
ret = NULL;
|
||||
if(ret->GetInstanceId() != u.GetInstanceId())
|
||||
return NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -136,15 +136,15 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
|
|||
else return NULL;
|
||||
}
|
||||
|
||||
static Object* GetObjectByTypeMask(Player const &, uint64, uint32 typemask);
|
||||
static Object* GetObjectByTypeMask(WorldObject const &, uint64, uint32 typemask);
|
||||
static Creature* GetNPCIfCanInteractWith(Player const &player, uint64 guid, uint32 npcflagmask);
|
||||
static Creature* GetCreature(WorldObject const &, uint64);
|
||||
static Creature* GetCreatureOrPet(WorldObject const &, uint64);
|
||||
static Creature* GetCreatureOrPetOrVehicle(WorldObject const &, uint64);
|
||||
static Unit* GetUnit(WorldObject const &, uint64);
|
||||
static Pet* GetPet(Unit const &, uint64 guid) { return GetPet(guid); }
|
||||
static Player* GetPlayer(Unit const &, uint64 guid) { return FindPlayer(guid); }
|
||||
static GameObject* GetGameObject(WorldObject const &, uint64);
|
||||
static DynamicObject* GetDynamicObject(Unit const &, uint64);
|
||||
static DynamicObject* GetDynamicObject(WorldObject const &, uint64);
|
||||
static Corpse* GetCorpse(WorldObject const &u, uint64 guid);
|
||||
static Pet* GetPet(uint64 guid);
|
||||
static Vehicle* GetVehicle(uint64 guid);
|
||||
|
|
|
|||
|
|
@ -766,6 +766,19 @@ void ObjectMgr::LoadCreatureTemplates()
|
|||
if((cInfo->npcflag & UNIT_NPC_FLAG_TRAINER) && cInfo->trainer_type >= MAX_TRAINER_TYPE)
|
||||
sLog.outErrorDb("Creature (Entry: %u) has wrong trainer type %u",cInfo->Entry,cInfo->trainer_type);
|
||||
|
||||
if(cInfo->type && !sCreatureTypeStore.LookupEntry(cInfo->type))
|
||||
{
|
||||
sLog.outErrorDb("Creature (Entry: %u) has invalid creature type (%u) in `type`",cInfo->Entry,cInfo->type);
|
||||
const_cast<CreatureInfo*>(cInfo)->type = CREATURE_TYPE_HUMANOID;
|
||||
}
|
||||
|
||||
// must exist or used hidden but used in data horse case
|
||||
if(cInfo->family && !sCreatureFamilyStore.LookupEntry(cInfo->family) && cInfo->family != CREATURE_FAMILY_HORSE_CUSTOM )
|
||||
{
|
||||
sLog.outErrorDb("Creature (Entry: %u) has invalid creature family (%u) in `family`",cInfo->Entry,cInfo->family);
|
||||
const_cast<CreatureInfo*>(cInfo)->family = 0;
|
||||
}
|
||||
|
||||
if(cInfo->InhabitType <= 0 || cInfo->InhabitType > INHABIT_ANYWHERE)
|
||||
{
|
||||
sLog.outErrorDb("Creature (Entry: %u) has wrong value (%u) in `InhabitType`, creature will not correctly walk/swim/fly",cInfo->Entry,cInfo->InhabitType);
|
||||
|
|
@ -1447,18 +1460,36 @@ void ObjectMgr::LoadAuctions()
|
|||
{
|
||||
QueryResult *result = CharacterDatabase.Query("SELECT COUNT(*) FROM auctionhouse");
|
||||
if( !result )
|
||||
{
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
sLog.outString("");
|
||||
sLog.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
Field *fields = result->Fetch();
|
||||
uint32 AuctionCount=fields[0].GetUInt32();
|
||||
delete result;
|
||||
|
||||
if(!AuctionCount)
|
||||
{
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
sLog.outString("");
|
||||
sLog.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
result = CharacterDatabase.Query( "SELECT id,auctioneerguid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit,location FROM auctionhouse" );
|
||||
if( !result )
|
||||
{
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
sLog.outString("");
|
||||
sLog.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
barGoLink bar( AuctionCount );
|
||||
|
||||
|
|
@ -1499,7 +1530,6 @@ void ObjectMgr::LoadAuctions()
|
|||
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Loaded %u auctions", AuctionCount );
|
||||
sLog.outString();
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadItemLocales()
|
||||
|
|
@ -1933,7 +1963,13 @@ void ObjectMgr::LoadAuctionItems()
|
|||
QueryResult *result = CharacterDatabase.Query( "SELECT data,itemguid,item_template FROM auctionhouse JOIN item_instance ON itemguid = guid" );
|
||||
|
||||
if( !result )
|
||||
{
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
sLog.outString("");
|
||||
sLog.outString(">> Loaded 0 auction items");
|
||||
return;
|
||||
}
|
||||
|
||||
barGoLink bar( result->GetRowCount() );
|
||||
|
||||
|
|
@ -1968,7 +2004,6 @@ void ObjectMgr::LoadAuctionItems()
|
|||
++count;
|
||||
}
|
||||
while( result->NextRow() );
|
||||
|
||||
delete result;
|
||||
|
||||
sLog.outString();
|
||||
|
|
@ -4336,14 +4371,20 @@ void ObjectMgr::LoadInstanceTemplate()
|
|||
else if(!entry->HasResetTime())
|
||||
continue;
|
||||
|
||||
//FIXME: now exist heroic instance, normal/heroic raid instances
|
||||
// entry->resetTimeHeroic store reset time for both heroic mode instance (raid and non-raid)
|
||||
// entry->resetTimeRaid store reset time for normal raid only
|
||||
// for current state entry->resetTimeRaid == entry->resetTimeHeroic in case raid instances with heroic mode.
|
||||
// but at some point wee need implement reset time dependen from raid insatance mode
|
||||
if(temp->reset_delay == 0)
|
||||
{
|
||||
// use defaults from the DBC
|
||||
if(entry->SupportsHeroicMode())
|
||||
if(entry->resetTimeHeroic) // for both raid and non raids, read above
|
||||
{
|
||||
temp->reset_delay = entry->resetTimeHeroic / DAY;
|
||||
}
|
||||
else if (entry->resetTimeRaid && entry->map_type == MAP_RAID)
|
||||
// for normal raid only
|
||||
{
|
||||
temp->reset_delay = entry->resetTimeRaid / DAY;
|
||||
}
|
||||
|
|
@ -4521,14 +4562,27 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp)
|
|||
// 0 1 2 3 4 5 6 7 8 9
|
||||
QueryResult* result = CharacterDatabase.PQuery("SELECT id,messageType,sender,receiver,itemTextId,has_items,expire_time,cod,checked,mailTemplateId FROM mail WHERE expire_time < '" I64FMTD "'", (uint64)basetime);
|
||||
if ( !result )
|
||||
{
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
sLog.outString("");
|
||||
sLog.outString(">> Only expired mails (need to be return or delete) or DB table `mail` is empty.");
|
||||
return; // any mails need to be returned or deleted
|
||||
Field *fields;
|
||||
}
|
||||
|
||||
//std::ostringstream delitems, delmails; //will be here for optimization
|
||||
//bool deletemail = false, deleteitem = false;
|
||||
//delitems << "DELETE FROM item_instance WHERE guid IN ( ";
|
||||
//delmails << "DELETE FROM mail WHERE id IN ( "
|
||||
|
||||
barGoLink bar( result->GetRowCount() );
|
||||
uint32 count = 0;
|
||||
Field *fields;
|
||||
|
||||
do
|
||||
{
|
||||
bar.step();
|
||||
|
||||
fields = result->Fetch();
|
||||
Mail *m = new Mail;
|
||||
m->messageID = fields[0].GetUInt32();
|
||||
|
|
@ -4594,8 +4648,12 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp)
|
|||
//delmails << m->messageID << ", ";
|
||||
CharacterDatabase.PExecute("DELETE FROM mail WHERE id = '%u'", m->messageID);
|
||||
delete m;
|
||||
++count;
|
||||
} while (result->NextRow());
|
||||
delete result;
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Loaded %u mails", count );
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadQuestAreaTriggers()
|
||||
|
|
@ -4761,24 +4819,31 @@ uint32 ObjectMgr::GetNearestTaxiNode( float x, float y, float z, uint32 mapid, u
|
|||
for(uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i)
|
||||
{
|
||||
TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(i);
|
||||
if(node && node->map_id == mapid && node->MountCreatureID[team == ALLIANCE ? 1 : 0])
|
||||
if(!node || node->map_id != mapid || !node->MountCreatureID[team == ALLIANCE ? 1 : 0])
|
||||
continue;
|
||||
|
||||
uint8 field = (uint8)((i - 1) / 32);
|
||||
uint32 submask = 1<<((i-1)%32);
|
||||
|
||||
// skip not taxi network nodes
|
||||
if((sTaxiNodesMask[field] & submask)==0)
|
||||
continue;
|
||||
|
||||
float dist2 = (node->x - x)*(node->x - x)+(node->y - y)*(node->y - y)+(node->z - z)*(node->z - z);
|
||||
if(found)
|
||||
{
|
||||
float dist2 = (node->x - x)*(node->x - x)+(node->y - y)*(node->y - y)+(node->z - z)*(node->z - z);
|
||||
if(found)
|
||||
if(dist2 < dist)
|
||||
{
|
||||
if(dist2 < dist)
|
||||
{
|
||||
dist = dist2;
|
||||
id = i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
found = true;
|
||||
dist = dist2;
|
||||
id = i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
found = true;
|
||||
dist = dist2;
|
||||
id = i;
|
||||
}
|
||||
}
|
||||
|
||||
return id;
|
||||
|
|
@ -6250,11 +6315,18 @@ void ObjectMgr::LoadReservedPlayersNames()
|
|||
bar.step();
|
||||
fields = result->Fetch();
|
||||
std::string name= fields[0].GetCppString();
|
||||
if(normalizePlayerName(name))
|
||||
|
||||
std::wstring wstr;
|
||||
if(!Utf8toWStr (name,wstr))
|
||||
{
|
||||
m_ReservedNames.insert(name);
|
||||
++count;
|
||||
sLog.outError("Table `reserved_name` have invalid name: %s", name.c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
wstrToLower(wstr);
|
||||
|
||||
m_ReservedNames.insert(wstr);
|
||||
++count;
|
||||
} while ( result->NextRow() );
|
||||
|
||||
delete result;
|
||||
|
|
@ -6263,6 +6335,17 @@ void ObjectMgr::LoadReservedPlayersNames()
|
|||
sLog.outString( ">> Loaded %u reserved player names", count );
|
||||
}
|
||||
|
||||
bool ObjectMgr::IsReservedName( const std::string& name ) const
|
||||
{
|
||||
std::wstring wstr;
|
||||
if(!Utf8toWStr (name,wstr))
|
||||
return false;
|
||||
|
||||
wstrToLower(wstr);
|
||||
|
||||
return m_ReservedNames.find(wstr) != m_ReservedNames.end();
|
||||
}
|
||||
|
||||
enum LanguageType
|
||||
{
|
||||
LT_BASIC_LATIN = 0x0000,
|
||||
|
|
@ -6455,11 +6538,22 @@ void ObjectMgr::LoadGameObjectForQuests()
|
|||
{
|
||||
mGameObjectForQuestSet.clear(); // need for reload case
|
||||
|
||||
if( !sGOStorage.MaxEntry )
|
||||
{
|
||||
barGoLink bar( 1 );
|
||||
bar.step();
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Loaded 0 GameObjects for quests" );
|
||||
return;
|
||||
}
|
||||
|
||||
barGoLink bar( sGOStorage.MaxEntry - 1 );
|
||||
uint32 count = 0;
|
||||
|
||||
// collect GO entries for GO that must activated
|
||||
for(uint32 go_entry = 1; go_entry < sGOStorage.MaxEntry; ++go_entry)
|
||||
{
|
||||
bar.step();
|
||||
GameObjectInfo const* goInfo = sGOStorage.LookupEntry<GameObjectInfo>(go_entry);
|
||||
if(!goInfo)
|
||||
continue;
|
||||
|
|
@ -6494,7 +6588,7 @@ void ObjectMgr::LoadGameObjectForQuests()
|
|||
}
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Loaded %u GameObject for quests", count );
|
||||
sLog.outString( ">> Loaded %u GameObjects for quests", count );
|
||||
}
|
||||
|
||||
bool ObjectMgr::LoadMangosStrings(DatabaseType& db, char const* table, int32 min_value, int32 max_value)
|
||||
|
|
@ -6986,11 +7080,10 @@ void ObjectMgr::LoadGameTele()
|
|||
++count;
|
||||
}
|
||||
while (result->NextRow());
|
||||
|
||||
delete result;
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Loaded %u game tele's", count );
|
||||
sLog.outString( ">> Loaded %u GameTeleports", count );
|
||||
}
|
||||
|
||||
GameTele const* ObjectMgr::GetGameTele(const std::string& name) const
|
||||
|
|
@ -7160,7 +7253,7 @@ void ObjectMgr::LoadTrainerSpell()
|
|||
delete result;
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Loaded Trainers %d", count );
|
||||
sLog.outString( ">> Loaded %d Trainers", count );
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadVendors()
|
||||
|
|
@ -7438,16 +7531,30 @@ void ObjectMgr::LoadScriptNames()
|
|||
"SELECT DISTINCT(ScriptName) FROM areatrigger_scripts WHERE ScriptName <> '' "
|
||||
"UNION "
|
||||
"SELECT DISTINCT(script) FROM instance_template WHERE script <> ''");
|
||||
if(result)
|
||||
|
||||
if( !result )
|
||||
{
|
||||
do
|
||||
{
|
||||
m_scriptNames.push_back((*result)[0].GetString());
|
||||
} while (result->NextRow());
|
||||
delete result;
|
||||
barGoLink bar( 1 );
|
||||
bar.step();
|
||||
sLog.outString();
|
||||
sLog.outErrorDb(">> Loaded empty set of Script Names!");
|
||||
return;
|
||||
}
|
||||
|
||||
barGoLink bar( result->GetRowCount() );
|
||||
uint32 count = 0;
|
||||
|
||||
do
|
||||
{
|
||||
bar.step();
|
||||
m_scriptNames.push_back((*result)[0].GetString());
|
||||
++count;
|
||||
} while (result->NextRow());
|
||||
delete result;
|
||||
|
||||
std::sort(m_scriptNames.begin(), m_scriptNames.end());
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Loaded %d Script Names", count );
|
||||
}
|
||||
|
||||
uint32 ObjectMgr::GetScriptId(const char *name)
|
||||
|
|
|
|||
|
|
@ -702,10 +702,7 @@ class ObjectMgr
|
|||
|
||||
// reserved names
|
||||
void LoadReservedPlayersNames();
|
||||
bool IsReservedName(const std::string& name) const
|
||||
{
|
||||
return m_ReservedNames.find(name) != m_ReservedNames.end();
|
||||
}
|
||||
bool IsReservedName(const std::string& name) const;
|
||||
|
||||
// name with valid structure and symbols
|
||||
static bool IsValidName( const std::string& name, bool create = false );
|
||||
|
|
@ -834,7 +831,7 @@ class ObjectMgr
|
|||
PetCreateSpellMap mPetCreateSpell;
|
||||
|
||||
//character reserved names
|
||||
typedef std::set<std::string> ReservedNamesMap;
|
||||
typedef std::set<std::wstring> ReservedNamesMap;
|
||||
ReservedNamesMap m_ReservedNames;
|
||||
|
||||
GraveYardMap mGraveYardMap;
|
||||
|
|
|
|||
|
|
@ -39,25 +39,14 @@ char const* petTypeSuffix[MAX_PET_TYPE] =
|
|||
"'s Companion" // MINI_PET
|
||||
};
|
||||
|
||||
Pet::Pet(PetType type) : Creature()
|
||||
Pet::Pet(PetType type) :
|
||||
Creature(), m_petType(type), m_removed(false), m_happinessTimer(7500), m_duration(0), m_bonusdamage(0),
|
||||
m_resetTalentsCost(0), m_resetTalentsTime(0), m_usedTalentCount(0), m_auraUpdateMask(0), m_loading(false),
|
||||
m_declinedname(NULL)
|
||||
{
|
||||
m_isPet = true;
|
||||
m_name = "Pet";
|
||||
m_petType = type;
|
||||
|
||||
m_removed = false;
|
||||
m_regenTimer = 4000;
|
||||
m_happinessTimer = 7500;
|
||||
m_duration = 0;
|
||||
m_bonusdamage = 0;
|
||||
|
||||
m_resetTalentsCost = 0;
|
||||
m_resetTalentsTime = 0;
|
||||
m_usedTalentCount = 0;
|
||||
|
||||
m_auraUpdateMask = 0;
|
||||
|
||||
m_loading = false;
|
||||
|
||||
// pets always have a charminfo, even if they are not actually charmed
|
||||
CharmInfo* charmInfo = InitCharmInfo(this);
|
||||
|
|
@ -66,13 +55,6 @@ Pet::Pet(PetType type) : Creature()
|
|||
charmInfo->SetReactState(REACT_PASSIVE);
|
||||
else if(type == GUARDIAN_PET) // always aggressive
|
||||
charmInfo->SetReactState(REACT_AGGRESSIVE);
|
||||
|
||||
m_spells.clear();
|
||||
m_Auras.clear();
|
||||
m_CreatureSpellCooldowns.clear();
|
||||
m_CreatureCategoryCooldowns.clear();
|
||||
m_autospells.clear();
|
||||
m_declinedname = NULL;
|
||||
}
|
||||
|
||||
Pet::~Pet()
|
||||
|
|
@ -768,11 +750,10 @@ bool Pet::CreateBaseAtCreature(Creature* creature)
|
|||
SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, objmgr.GetXPForLevel(creature->getLevel())/4);
|
||||
SetUInt32Value(UNIT_NPC_FLAGS, 0);
|
||||
|
||||
CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(creature->GetCreatureInfo()->family);
|
||||
if( char* familyname = cFamily->Name[sWorld.GetDefaultDbcLocale()] )
|
||||
SetName(familyname);
|
||||
if(CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cinfo->family))
|
||||
SetName(cFamily->Name[sWorld.GetDefaultDbcLocale()]);
|
||||
else
|
||||
SetName(creature->GetName());
|
||||
SetName(creature->GetNameForLocaleIdx(objmgr.GetDBCLocaleIndex()));
|
||||
|
||||
if(cinfo->type == CREATURE_TYPE_BEAST)
|
||||
{
|
||||
|
|
@ -1088,7 +1069,7 @@ void Pet::_LoadSpells()
|
|||
{
|
||||
Field *fields = result->Fetch();
|
||||
|
||||
addSpell(fields[0].GetUInt16(), fields[1].GetUInt16(), PETSPELL_UNCHANGED);
|
||||
addSpell(fields[0].GetUInt32(), fields[1].GetUInt16(), PETSPELL_UNCHANGED);
|
||||
}
|
||||
while( result->NextRow() );
|
||||
|
||||
|
|
@ -1241,7 +1222,7 @@ void Pet::_SaveAuras()
|
|||
}
|
||||
}
|
||||
|
||||
bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, PetSpellType type)
|
||||
bool Pet::addSpell(uint32 spell_id, uint16 active, PetSpellState state, PetSpellType type)
|
||||
{
|
||||
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id);
|
||||
if (!spellInfo)
|
||||
|
|
@ -1354,7 +1335,7 @@ bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, PetSpell
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Pet::learnSpell(uint16 spell_id)
|
||||
bool Pet::learnSpell(uint32 spell_id)
|
||||
{
|
||||
// prevent duplicated entires in spell book
|
||||
if (!addSpell(spell_id))
|
||||
|
|
@ -1391,7 +1372,7 @@ void Pet::learnLevelupSpells()
|
|||
}
|
||||
}
|
||||
|
||||
bool Pet::unlearnSpell(uint16 spell_id)
|
||||
bool Pet::unlearnSpell(uint32 spell_id)
|
||||
{
|
||||
if(removeSpell(spell_id))
|
||||
{
|
||||
|
|
@ -1409,7 +1390,7 @@ bool Pet::unlearnSpell(uint16 spell_id)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Pet::removeSpell(uint16 spell_id)
|
||||
bool Pet::removeSpell(uint32 spell_id)
|
||||
{
|
||||
PetSpellMap::iterator itr = m_spells.find(spell_id);
|
||||
if (itr == m_spells.end())
|
||||
|
|
@ -1443,7 +1424,7 @@ bool Pet::removeSpell(uint16 spell_id)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Pet::_removeSpell(uint16 spell_id)
|
||||
bool Pet::_removeSpell(uint32 spell_id)
|
||||
{
|
||||
PetSpellMap::iterator itr = m_spells.find(spell_id);
|
||||
if (itr != m_spells.end())
|
||||
|
|
@ -1460,7 +1441,7 @@ void Pet::InitPetCreateSpells()
|
|||
m_charmInfo->InitPetActionBar();
|
||||
|
||||
m_spells.clear();
|
||||
int32 petspellid;
|
||||
uint32 petspellid;
|
||||
PetCreateSpellEntry const* CreateSpells = objmgr.GetPetCreateSpellEntry(GetEntry());
|
||||
if(CreateSpells)
|
||||
{
|
||||
|
|
@ -1480,7 +1461,7 @@ void Pet::InitPetCreateSpells()
|
|||
if(owner->GetTypeId() == TYPEID_PLAYER && !((Player*)owner)->HasSpell(learn_spellproto->Id))
|
||||
{
|
||||
if(IsPassiveSpell(petspellid)) //learn passive skills when tamed, not sure if thats right
|
||||
((Player*)owner)->learnSpell(learn_spellproto->Id);
|
||||
((Player*)owner)->learnSpell(learn_spellproto->Id,false);
|
||||
else
|
||||
AddTeachSpell(learn_spellproto->EffectTriggerSpell[0], learn_spellproto->Id);
|
||||
}
|
||||
|
|
@ -1514,7 +1495,7 @@ void Pet::CheckLearning(uint32 spellid)
|
|||
|
||||
if(urand(0, 100) < 10)
|
||||
{
|
||||
((Player*)owner)->learnSpell(itr->second);
|
||||
((Player*)owner)->learnSpell(itr->second,false);
|
||||
m_teachspells.erase(itr);
|
||||
}
|
||||
}
|
||||
|
|
@ -1655,7 +1636,7 @@ void Pet::ToggleAutocast(uint32 spellid, bool apply)
|
|||
if(IsPassiveSpell(spellid))
|
||||
return;
|
||||
|
||||
PetSpellMap::const_iterator itr = m_spells.find((uint16)spellid);
|
||||
PetSpellMap::const_iterator itr = m_spells.find(spellid);
|
||||
|
||||
int i;
|
||||
|
||||
|
|
@ -1709,7 +1690,7 @@ bool Pet::Create(uint32 guidlow, Map *map, uint32 Entry, uint32 pet_number)
|
|||
|
||||
bool Pet::HasSpell(uint32 spell) const
|
||||
{
|
||||
PetSpellMap::const_iterator itr = m_spells.find((uint16)spell);
|
||||
PetSpellMap::const_iterator itr = m_spells.find(spell);
|
||||
return (itr != m_spells.end() && itr->second->state != PETSPELL_REMOVED );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ enum PetNameInvalidReason
|
|||
PET_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 16
|
||||
};
|
||||
|
||||
typedef UNORDERED_MAP<uint16, PetSpell*> PetSpellMap;
|
||||
typedef UNORDERED_MAP<uint32, PetSpell*> PetSpellMap;
|
||||
typedef std::map<uint32,uint32> TeachSpellMap;
|
||||
typedef std::vector<uint32> AutoSpellList;
|
||||
|
||||
|
|
@ -188,12 +188,12 @@ class Pet : public Creature
|
|||
void _LoadSpells();
|
||||
void _SaveSpells();
|
||||
|
||||
bool addSpell(uint16 spell_id,uint16 active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, PetSpellType type = PETSPELL_NORMAL);
|
||||
bool learnSpell(uint16 spell_id);
|
||||
bool addSpell(uint32 spell_id,uint16 active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, PetSpellType type = PETSPELL_NORMAL);
|
||||
bool learnSpell(uint32 spell_id);
|
||||
void learnLevelupSpells();
|
||||
bool unlearnSpell(uint16 spell_id);
|
||||
bool removeSpell(uint16 spell_id);
|
||||
bool _removeSpell(uint16 spell_id);
|
||||
bool unlearnSpell(uint32 spell_id);
|
||||
bool removeSpell(uint32 spell_id);
|
||||
bool _removeSpell(uint32 spell_id);
|
||||
|
||||
PetSpellMap m_spells;
|
||||
TeachSpellMap m_teachspells;
|
||||
|
|
|
|||
|
|
@ -285,7 +285,7 @@ void WorldSession::HandlePetNameQuery( WorldPacket & recv_data )
|
|||
|
||||
void WorldSession::SendPetNameQuery( uint64 petguid, uint32 petnumber)
|
||||
{
|
||||
Creature* pet = ObjectAccessor::GetCreatureOrPet(*_player, petguid);
|
||||
Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, petguid);
|
||||
if(!pet || !pet->GetCharmInfo() || pet->GetCharmInfo()->GetPetNumber() != petnumber)
|
||||
return;
|
||||
|
||||
|
|
@ -327,7 +327,7 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data )
|
|||
if(ObjectAccessor::FindPlayer(petguid))
|
||||
return;
|
||||
|
||||
Creature* pet = ObjectAccessor::GetCreatureOrPet(*_player, petguid);
|
||||
Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, petguid);
|
||||
|
||||
if(!pet || (pet != _player->GetPet() && pet != _player->GetCharm()))
|
||||
{
|
||||
|
|
@ -464,7 +464,7 @@ void WorldSession::HandlePetAbandon( WorldPacket & recv_data )
|
|||
sLog.outDetail( "HandlePetAbandon. CMSG_PET_ABANDON pet guid is %u", GUID_LOPART(guid) );
|
||||
|
||||
// pet/charmed
|
||||
Creature* pet = ObjectAccessor::GetCreatureOrPet(*_player, guid);
|
||||
Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, guid);
|
||||
if(pet)
|
||||
{
|
||||
if(pet->isPet())
|
||||
|
|
@ -529,7 +529,7 @@ void WorldSession::HandlePetSpellAutocastOpcode( WorldPacket& recvPacket )
|
|||
if(ObjectAccessor::FindPlayer(guid))
|
||||
return;
|
||||
|
||||
Creature* pet=ObjectAccessor::GetCreatureOrPet(*_player,guid);
|
||||
Creature* pet=ObjectAccessor::GetCreatureOrPetOrVehicle(*_player,guid);
|
||||
|
||||
if(!pet || (pet != _player->GetPet() && pet != _player->GetCharm()))
|
||||
{
|
||||
|
|
@ -581,7 +581,7 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
|
|||
if (GUID_HIPART(guid) == HIGHGUID_PLAYER)
|
||||
return;
|
||||
|
||||
Creature* pet = ObjectAccessor::GetCreatureOrPet(*_player,guid);
|
||||
Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player,guid);
|
||||
|
||||
if(!pet || (pet != _player->GetPet() && pet!= _player->GetCharm()))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ void PlayerTaxi::AppendTaximaskTo( ByteBuffer& data, bool all )
|
|||
}
|
||||
}
|
||||
|
||||
bool PlayerTaxi::LoadTaxiDestinationsFromString( const std::string& values )
|
||||
bool PlayerTaxi::LoadTaxiDestinationsFromString( const std::string& values, uint32 team )
|
||||
{
|
||||
ClearTaxiDestinations();
|
||||
|
||||
|
|
@ -218,6 +218,10 @@ bool PlayerTaxi::LoadTaxiDestinationsFromString( const std::string& values )
|
|||
return false;
|
||||
}
|
||||
|
||||
// can't load taxi path without mount set (quest taxi path?)
|
||||
if(!objmgr.GetTaxiMount(GetTaxiSource(),team))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -293,6 +297,7 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this)
|
|||
m_comboPoints = 0;
|
||||
|
||||
m_usedTalentCount = 0;
|
||||
m_questRewardTalentCount = 0;
|
||||
|
||||
m_regenTimer = 0;
|
||||
m_weaponChangeTimer = 0;
|
||||
|
|
@ -422,7 +427,7 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this)
|
|||
|
||||
for (int i = 0; i < MAX_COMBAT_RATING; i++)
|
||||
m_baseRatingValue[i] = 0;
|
||||
|
||||
|
||||
m_baseSpellDamage = 0;
|
||||
m_baseSpellHealing = 0;
|
||||
m_baseFeralAP = 0;
|
||||
|
|
@ -2239,7 +2244,8 @@ void Player::InitTalentForLevel()
|
|||
}
|
||||
else
|
||||
{
|
||||
uint32 talentPointsForLevel = uint32((level-9)*sWorld.getRate(RATE_TALENT));
|
||||
uint32 talentPointsForLevel = CalculateTalentsPoints();
|
||||
|
||||
// if used more that have then reset
|
||||
if(m_usedTalentCount > talentPointsForLevel)
|
||||
{
|
||||
|
|
@ -2535,7 +2541,7 @@ void Player::AddNewMailDeliverTime(time_t deliver_time)
|
|||
}
|
||||
}
|
||||
|
||||
bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool disabled)
|
||||
bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependent, bool disabled)
|
||||
{
|
||||
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id);
|
||||
if (!spellInfo)
|
||||
|
|
@ -2568,29 +2574,78 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool disabled
|
|||
|
||||
PlayerSpellState state = learning ? PLAYERSPELL_NEW : PLAYERSPELL_UNCHANGED;
|
||||
|
||||
bool dependent_set = false;
|
||||
bool disabled_case = false;
|
||||
bool superceded_old = false;
|
||||
|
||||
PlayerSpellMap::iterator itr = m_spells.find(spell_id);
|
||||
if (itr != m_spells.end())
|
||||
{
|
||||
uint32 next_active_spell_id = 0;
|
||||
// fix activate state for non-stackable low rank (and find next spell for !active case)
|
||||
if(!SpellMgr::canStackSpellRanks(spellInfo) && spellmgr.GetSpellRank(spellInfo->Id) != 0)
|
||||
{
|
||||
SpellChainMapNext const& nextMap = spellmgr.GetSpellChainNext();
|
||||
for(SpellChainMapNext::const_iterator next_itr = nextMap.lower_bound(spell_id); next_itr != nextMap.upper_bound(spell_id); ++next_itr)
|
||||
{
|
||||
if(HasSpell(next_itr->second))
|
||||
{
|
||||
// high rank already known so this must !active
|
||||
active = false;
|
||||
next_active_spell_id = next_itr->second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// not do anything if already known in expected state
|
||||
if(itr->second->state != PLAYERSPELL_REMOVED && itr->second->active == active &&
|
||||
itr->second->dependent == dependent && itr->second->disabled == disabled)
|
||||
return false;
|
||||
|
||||
// dependent spell known as not dependent, overwrite state
|
||||
if (itr->second->state != PLAYERSPELL_REMOVED && !itr->second->dependent && dependent)
|
||||
{
|
||||
itr->second->dependent = dependent;
|
||||
if (itr->second->state != PLAYERSPELL_NEW)
|
||||
itr->second->state = PLAYERSPELL_CHANGED;
|
||||
dependent_set = true;
|
||||
}
|
||||
|
||||
// update active state for known spell
|
||||
if(itr->second->active != active && itr->second->state != PLAYERSPELL_REMOVED && !itr->second->disabled)
|
||||
{
|
||||
itr->second->active = active;
|
||||
|
||||
// !IsInWorld() && !learning == explicitly load from DB and then exist in it already and set correctly
|
||||
if(!IsInWorld() && !learning)
|
||||
if(!IsInWorld() && !learning && !dependent_set)
|
||||
itr->second->state = PLAYERSPELL_UNCHANGED;
|
||||
else if(itr->second->state != PLAYERSPELL_NEW)
|
||||
itr->second->state = PLAYERSPELL_CHANGED;
|
||||
|
||||
if(!active)
|
||||
if(active)
|
||||
{
|
||||
WorldPacket data(SMSG_REMOVED_SPELL, 4);
|
||||
data << uint16(spell_id);
|
||||
GetSession()->SendPacket(&data);
|
||||
if (IsPassiveSpell(spell_id) && IsNeedCastPassiveSpellAtLearn(spellInfo))
|
||||
CastSpell (this,spell_id,true);
|
||||
}
|
||||
else if(IsInWorld())
|
||||
{
|
||||
if(next_active_spell_id)
|
||||
{
|
||||
// update spell ranks in spellbook and action bar
|
||||
WorldPacket data(SMSG_SUPERCEDED_SPELL, (4));
|
||||
data << uint16(spell_id);
|
||||
data << uint16(next_active_spell_id);
|
||||
GetSession()->SendPacket( &data );
|
||||
}
|
||||
else
|
||||
{
|
||||
WorldPacket data(SMSG_REMOVED_SPELL, 4);
|
||||
data << uint16(spell_id);
|
||||
GetSession()->SendPacket(&data);
|
||||
}
|
||||
}
|
||||
|
||||
return active; // learn (show in spell book if active now)
|
||||
}
|
||||
|
||||
|
|
@ -2619,7 +2674,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool disabled
|
|||
default: // known not saved yet spell (new or modified)
|
||||
{
|
||||
// can be in case spell loading but learned at some previous spell loading
|
||||
if(!IsInWorld() && !learning)
|
||||
if(!IsInWorld() && !learning && !dependent_set)
|
||||
itr->second->state = PLAYERSPELL_UNCHANGED;
|
||||
|
||||
return false;
|
||||
|
|
@ -2652,16 +2707,17 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool disabled
|
|||
// non talent spell: learn low ranks (recursive call)
|
||||
else if(uint32 prev_spell = spellmgr.GetPrevSpellInChain(spell_id))
|
||||
{
|
||||
if(!IsInWorld()) // at spells loading, no output, but allow save
|
||||
addSpell(prev_spell,active,true,disabled);
|
||||
if(!IsInWorld() || disabled) // at spells loading, no output, but allow save
|
||||
addSpell(prev_spell,active,true,true,disabled);
|
||||
else // at normal learning
|
||||
learnSpell(prev_spell);
|
||||
learnSpell(prev_spell,true);
|
||||
}
|
||||
|
||||
PlayerSpell *newspell = new PlayerSpell;
|
||||
newspell->active = active;
|
||||
newspell->state = state;
|
||||
newspell->disabled = disabled;
|
||||
newspell->state = state;
|
||||
newspell->active = active;
|
||||
newspell->dependent = dependent;
|
||||
newspell->disabled = disabled;
|
||||
|
||||
// replace spells in action bars and spellbook to bigger rank if only one spell rank must be accessible
|
||||
if(newspell->active && !newspell->disabled && !SpellMgr::canStackSpellRanks(spellInfo) && spellmgr.GetSpellRank(spellInfo->Id) != 0)
|
||||
|
|
@ -2688,7 +2744,8 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool disabled
|
|||
|
||||
// mark old spell as disable (SMSG_SUPERCEDED_SPELL replace it in client by new)
|
||||
itr->second->active = false;
|
||||
itr->second->state = PLAYERSPELL_CHANGED;
|
||||
if(itr->second->state != PLAYERSPELL_NEW)
|
||||
itr->second->state = PLAYERSPELL_CHANGED;
|
||||
superceded_old = true; // new spell replace old in action bars and spell book.
|
||||
}
|
||||
else if(spellmgr.IsHighRankOfSpell(itr->first,spell_id))
|
||||
|
|
@ -2730,26 +2787,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool disabled
|
|||
// also cast passive spells (including all talents without SPELL_EFFECT_LEARN_SPELL) with additional checks
|
||||
else if (IsPassiveSpell(spell_id))
|
||||
{
|
||||
bool need_cast = false;
|
||||
|
||||
switch(spell_id)
|
||||
{
|
||||
// some spells not have stance data expacted cast at form change or present
|
||||
case 5420: need_cast = (m_form == FORM_TREE); break;
|
||||
case 5419: need_cast = (m_form == FORM_TRAVEL); break;
|
||||
case 7376: need_cast = (m_form == FORM_DEFENSIVESTANCE); break;
|
||||
case 7381: need_cast = (m_form == FORM_BERSERKERSTANCE); break;
|
||||
case 21156: need_cast = (m_form == FORM_BATTLESTANCE); break;
|
||||
case 21178: need_cast = (m_form == FORM_BEAR || m_form == FORM_DIREBEAR); break;
|
||||
case 33948: need_cast = (m_form == FORM_FLIGHT); break;
|
||||
case 34764: need_cast = (m_form == FORM_FLIGHT); break;
|
||||
case 40121: need_cast = (m_form == FORM_FLIGHT_EPIC); break;
|
||||
case 40122: need_cast = (m_form == FORM_FLIGHT_EPIC); break;
|
||||
// another spells have proper stance data
|
||||
default: need_cast = !spellInfo->Stances || m_form != 0 && (spellInfo->Stances & (1<<(m_form-1))); break;
|
||||
}
|
||||
//Check CasterAuraStates
|
||||
if (need_cast && (!spellInfo->CasterAuraState || HasAuraState(AuraState(spellInfo->CasterAuraState))))
|
||||
if(IsNeedCastPassiveSpellAtLearn(spellInfo))
|
||||
CastSpell(this, spell_id, true);
|
||||
}
|
||||
else if( IsSpellHaveEffect(spellInfo,SPELL_EFFECT_SKILL_STEP) )
|
||||
|
|
@ -2834,9 +2872,9 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool disabled
|
|||
if(!itr->second.autoLearned)
|
||||
{
|
||||
if(!IsInWorld() || !itr->second.active) // at spells loading, no output, but allow save
|
||||
addSpell(itr->second.spell,itr->second.active,true,false);
|
||||
addSpell(itr->second.spell,itr->second.active,true,true,false);
|
||||
else // at normal learning
|
||||
learnSpell(itr->second.spell);
|
||||
learnSpell(itr->second.spell,true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2850,14 +2888,39 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool disabled
|
|||
return active && !disabled && !superceded_old;
|
||||
}
|
||||
|
||||
void Player::learnSpell(uint32 spell_id)
|
||||
bool Player::IsNeedCastPassiveSpellAtLearn(SpellEntry const* spellInfo) const
|
||||
{
|
||||
bool need_cast = false;
|
||||
|
||||
switch(spellInfo->Id)
|
||||
{
|
||||
// some spells not have stance data expacted cast at form change or present
|
||||
case 5420: need_cast = (m_form == FORM_TREE); break;
|
||||
case 5419: need_cast = (m_form == FORM_TRAVEL); break;
|
||||
case 7376: need_cast = (m_form == FORM_DEFENSIVESTANCE); break;
|
||||
case 7381: need_cast = (m_form == FORM_BERSERKERSTANCE); break;
|
||||
case 21156: need_cast = (m_form == FORM_BATTLESTANCE); break;
|
||||
case 21178: need_cast = (m_form == FORM_BEAR || m_form == FORM_DIREBEAR); break;
|
||||
case 33948: need_cast = (m_form == FORM_FLIGHT); break;
|
||||
case 34764: need_cast = (m_form == FORM_FLIGHT); break;
|
||||
case 40121: need_cast = (m_form == FORM_FLIGHT_EPIC); break;
|
||||
case 40122: need_cast = (m_form == FORM_FLIGHT_EPIC); break;
|
||||
// another spells have proper stance data
|
||||
default: need_cast = !spellInfo->Stances || m_form != 0 && (spellInfo->Stances & (1<<(m_form-1))); break;
|
||||
}
|
||||
|
||||
//Check CasterAuraStates
|
||||
return need_cast && (!spellInfo->CasterAuraState || HasAuraState(AuraState(spellInfo->CasterAuraState)));
|
||||
}
|
||||
|
||||
void Player::learnSpell(uint32 spell_id, bool dependent)
|
||||
{
|
||||
PlayerSpellMap::iterator itr = m_spells.find(spell_id);
|
||||
|
||||
bool disabled = (itr != m_spells.end()) ? itr->second->disabled : false;
|
||||
bool active = disabled ? itr->second->active : true;
|
||||
|
||||
bool learning = addSpell(spell_id,active,true,false);
|
||||
bool learning = addSpell(spell_id,active,true,dependent,false);
|
||||
|
||||
// learn all disabled higher ranks (recursive)
|
||||
if(disabled)
|
||||
|
|
@ -2867,7 +2930,7 @@ void Player::learnSpell(uint32 spell_id)
|
|||
{
|
||||
PlayerSpellMap::iterator iter = m_spells.find(i->second);
|
||||
if (iter != m_spells.end() && iter->second->disabled)
|
||||
learnSpell(i->second);
|
||||
learnSpell(i->second,false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2895,10 +2958,8 @@ void Player::removeSpell(uint32 spell_id, bool disabled)
|
|||
if(HasSpell(itr2->second) && !GetTalentSpellPos(itr2->second))
|
||||
removeSpell(itr2->second,disabled);
|
||||
|
||||
// removing
|
||||
WorldPacket data(SMSG_REMOVED_SPELL, 4);
|
||||
data << uint16(spell_id);
|
||||
GetSession()->SendPacket(&data);
|
||||
bool cur_active = itr->second->active;
|
||||
bool cur_dependent = itr->second->dependent;
|
||||
|
||||
if (disabled)
|
||||
{
|
||||
|
|
@ -3011,7 +3072,54 @@ void Player::removeSpell(uint32 spell_id, bool disabled)
|
|||
for(SpellLearnSpellMap::const_iterator itr2 = spell_begin; itr2 != spell_end; ++itr2)
|
||||
removeSpell(itr2->second.spell, disabled);
|
||||
|
||||
// TODO: recast if need lesser ranks spell for passive with IsPassiveSpellStackableWithRanks
|
||||
// activate lesser rank in spellbook/action bar, and cast it if need
|
||||
bool prev_activate = false;
|
||||
|
||||
if(uint32 prev_id = spellmgr.GetPrevSpellInChain (spell_id))
|
||||
{
|
||||
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id);
|
||||
|
||||
// if talent then lesser rank also talen and need learn
|
||||
if(talentCosts)
|
||||
learnSpell (prev_id,false);
|
||||
// if ranked non-stackable spell: need activate lesser rank and update dendence state
|
||||
else if(cur_active && !SpellMgr::canStackSpellRanks(spellInfo) && spellmgr.GetSpellRank(spellInfo->Id) != 0)
|
||||
{
|
||||
// need manually update dependence state (learn spell ignore like attempts)
|
||||
PlayerSpellMap::iterator prev_itr = m_spells.find(prev_id);
|
||||
if (prev_itr != m_spells.end())
|
||||
{
|
||||
if(prev_itr->second->dependent != cur_dependent)
|
||||
{
|
||||
prev_itr->second->dependent = cur_dependent;
|
||||
if(prev_itr->second->state != PLAYERSPELL_NEW)
|
||||
prev_itr->second->state = PLAYERSPELL_CHANGED;
|
||||
}
|
||||
|
||||
// now re-learn if need re-activate
|
||||
if(cur_active && !prev_itr->second->active)
|
||||
{
|
||||
if(addSpell(prev_id,true,false,prev_itr->second->dependent,prev_itr->second->disabled))
|
||||
{
|
||||
// downgrade spell ranks in spellbook and action bar
|
||||
WorldPacket data(SMSG_SUPERCEDED_SPELL, (4));
|
||||
data << uint16(spell_id);
|
||||
data << uint16(prev_id);
|
||||
GetSession()->SendPacket( &data );
|
||||
prev_activate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove from spell book if not replaced by lesser rank
|
||||
if(!prev_activate)
|
||||
{
|
||||
WorldPacket data(SMSG_REMOVED_SPELL, 4);
|
||||
data << uint16(spell_id);
|
||||
GetSession()->SendPacket(&data);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::RemoveArenaSpellCooldowns()
|
||||
|
|
@ -3154,8 +3262,7 @@ bool Player::resetTalents(bool no_cost)
|
|||
CharacterDatabase.PExecute("UPDATE characters set at_login = at_login & ~ %u WHERE guid ='%u'", uint32(AT_LOGIN_RESET_TALENTS), GetGUIDLow());
|
||||
}
|
||||
|
||||
uint32 level = getLevel();
|
||||
uint32 talentPointsForLevel = level < 10 ? 0 : uint32((level-9)*sWorld.getRate(RATE_TALENT));
|
||||
uint32 talentPointsForLevel = CalculateTalentsPoints();
|
||||
|
||||
if (m_usedTalentCount == 0)
|
||||
{
|
||||
|
|
@ -3452,8 +3559,16 @@ void Player::DestroyForPlayer( Player *target ) const
|
|||
|
||||
bool Player::HasSpell(uint32 spell) const
|
||||
{
|
||||
PlayerSpellMap::const_iterator itr = m_spells.find((uint16)spell);
|
||||
return (itr != m_spells.end() && itr->second->state != PLAYERSPELL_REMOVED && !itr->second->disabled);
|
||||
PlayerSpellMap::const_iterator itr = m_spells.find(spell);
|
||||
return (itr != m_spells.end() && itr->second->state != PLAYERSPELL_REMOVED &&
|
||||
!itr->second->disabled);
|
||||
}
|
||||
|
||||
bool Player::HasActiveSpell(uint32 spell) const
|
||||
{
|
||||
PlayerSpellMap::const_iterator itr = m_spells.find(spell);
|
||||
return (itr != m_spells.end() && itr->second->state != PLAYERSPELL_REMOVED &&
|
||||
itr->second->active && !itr->second->disabled);
|
||||
}
|
||||
|
||||
TrainerSpellState Player::GetTrainerSpellState(TrainerSpell const* trainer_spell) const
|
||||
|
|
@ -4530,7 +4645,7 @@ float Player::OCTRegenMPPerSpirit()
|
|||
void Player::ApplyRatingMod(CombatRating cr, int32 value, bool apply)
|
||||
{
|
||||
m_baseRatingValue[cr]+=(apply ? value : -value);
|
||||
|
||||
|
||||
int32 amount = uint32(m_baseRatingValue[cr]);
|
||||
// Apply bonus from SPELL_AURA_MOD_RATING_FROM_STAT
|
||||
// stat used stored in miscValueB for this aura
|
||||
|
|
@ -4703,7 +4818,7 @@ bool Player::UpdateCraftSkill(uint32 spellid)
|
|||
if(spellEntry && spellEntry->Mechanic==MECHANIC_DISCOVERY)
|
||||
{
|
||||
if(uint32 discoveredSpell = GetSkillDiscoverySpell(_spell_idx->second->skillId, spellid, this))
|
||||
learnSpell(discoveredSpell);
|
||||
learnSpell(discoveredSpell,false);
|
||||
}
|
||||
|
||||
uint32 craft_skill_gain = sWorld.getConfig(CONFIG_SKILL_GAIN_CRAFTING);
|
||||
|
|
@ -4759,6 +4874,11 @@ bool Player::UpdateFishingSkill()
|
|||
return UpdateSkillPro(SKILL_FISHING,chance*10,gathering_skill_gain);
|
||||
}
|
||||
|
||||
// levels sync. with spell requirement for skill levels to learn
|
||||
// bonus abilities in sSkillLineAbilityStore
|
||||
// Used only to avoid scan DBC at each skill grow
|
||||
static uint32 bonusSkillLevels[] = {75,150,225,300,375,450};
|
||||
|
||||
bool Player::UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step)
|
||||
{
|
||||
sLog.outDebug("UpdateSkillPro(SkillId %d, Chance %3.1f%%)", SkillId, Chance/10.0);
|
||||
|
|
@ -4793,6 +4913,14 @@ bool Player::UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step)
|
|||
new_value = MaxValue;
|
||||
|
||||
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(new_value,MaxValue));
|
||||
for(uint32* bsl = &bonusSkillLevels[0]; *bsl; ++bsl)
|
||||
{
|
||||
if((SkillValue < *bsl && new_value >= *bsl))
|
||||
{
|
||||
learnSkillRewardedSpells( SkillId, new_value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL);
|
||||
sLog.outDebug("Player::UpdateSkillPro Chance=%3.1f%% taken", Chance/10.0);
|
||||
return true;
|
||||
|
|
@ -4969,6 +5097,7 @@ void Player::SetSkill(uint32 id, uint16 currVal, uint16 maxVal)
|
|||
if(currVal)
|
||||
{
|
||||
SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(currVal,maxVal));
|
||||
learnSkillRewardedSpells(id, currVal);
|
||||
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL);
|
||||
}
|
||||
else //remove
|
||||
|
|
@ -4979,26 +5108,7 @@ void Player::SetSkill(uint32 id, uint16 currVal, uint16 maxVal)
|
|||
SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i),0);
|
||||
|
||||
// remove spells that depend on this skill when removing the skill
|
||||
for (PlayerSpellMap::const_iterator itr = m_spells.begin(), next = m_spells.begin(); itr != m_spells.end(); itr = next)
|
||||
{
|
||||
++next;
|
||||
if(itr->second->state == PLAYERSPELL_REMOVED)
|
||||
continue;
|
||||
|
||||
SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(itr->first);
|
||||
SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(itr->first);
|
||||
|
||||
for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
|
||||
{
|
||||
if (_spell_idx->second->skillId == id)
|
||||
{
|
||||
// this may remove more than one spell (dependents)
|
||||
removeSpell(itr->first);
|
||||
next = m_spells.begin();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
learnSkillRewardedSpells(id, 0);
|
||||
}
|
||||
}
|
||||
else if(currVal) //add
|
||||
|
|
@ -5036,7 +5146,7 @@ void Player::SetSkill(uint32 id, uint16 currVal, uint16 maxVal)
|
|||
(*i)->ApplyModifier(true);
|
||||
|
||||
// Learn all spells for skill
|
||||
learnSkillRewardedSpells(id);
|
||||
learnSkillRewardedSpells(id, currVal);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -9931,7 +10041,7 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo
|
|||
if(!CanDualWield())
|
||||
return EQUIP_ERR_CANT_DUAL_WIELD;
|
||||
}
|
||||
else if (type == INVTYPE_2HWEAPON)
|
||||
else if (type == INVTYPE_2HWEAPON)
|
||||
{
|
||||
if(!CanDualWield() || !CanTitanGrip())
|
||||
return EQUIP_ERR_CANT_DUAL_WIELD;
|
||||
|
|
@ -12675,6 +12785,12 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver
|
|||
SetTitle(titleEntry);
|
||||
}
|
||||
|
||||
if(pQuest->GetBonusTalents())
|
||||
{
|
||||
m_questRewardTalentCount+=pQuest->GetBonusTalents();
|
||||
InitTalentForLevel();
|
||||
}
|
||||
|
||||
// Send reward mail
|
||||
if(pQuest->GetRewMailTemplateId())
|
||||
{
|
||||
|
|
@ -14325,16 +14441,15 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
|||
|
||||
_LoadSpells(holder->GetResult(PLAYER_LOGIN_QUERY_LOADSPELLS));
|
||||
|
||||
// after spell load
|
||||
InitTalentForLevel();
|
||||
learnSkillRewardedSpells();
|
||||
learnDefaultSpells();
|
||||
|
||||
|
||||
// after spell load, learn rewarded spell if need also
|
||||
_LoadQuestStatus(holder->GetResult(PLAYER_LOGIN_QUERY_LOADQUESTSTATUS));
|
||||
_LoadDailyQuestStatus(holder->GetResult(PLAYER_LOGIN_QUERY_LOADDAILYQUESTSTATUS));
|
||||
|
||||
// after spell and quest load
|
||||
InitTalentForLevel();
|
||||
learnSkillRewardedSpells();
|
||||
learnDefaultSpells();
|
||||
|
||||
_LoadTutorials(holder->GetResult(PLAYER_LOGIN_QUERY_LOADTUTORIALS));
|
||||
|
||||
// must be before inventory (some items required reputation check)
|
||||
|
|
@ -14364,7 +14479,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
|||
}
|
||||
|
||||
// Not finish taxi flight path
|
||||
if(!m_taxi.LoadTaxiDestinationsFromString(taxi_nodes))
|
||||
if(!m_taxi.LoadTaxiDestinationsFromString(taxi_nodes,GetTeam()))
|
||||
{
|
||||
// problems with taxi path loading
|
||||
TaxiNodesEntry const* nodeEntry = NULL;
|
||||
|
|
@ -14585,7 +14700,7 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff)
|
|||
damage = aura->GetModifier()->m_amount;
|
||||
aura->SetLoadedState(caster_guid,damage,maxduration,remaintime,remaincharges);
|
||||
AddAura(aura);
|
||||
sLog.outString("Added aura spellid %u, effect %u", spellproto->Id, effindex);
|
||||
sLog.outDetail("Added aura spellid %u, effect %u", spellproto->Id, effindex);
|
||||
}
|
||||
}
|
||||
while( result->NextRow() );
|
||||
|
|
@ -15008,6 +15123,9 @@ void Player::_LoadQuestStatus(QueryResult *result)
|
|||
if(CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(pQuest->GetCharTitleId()))
|
||||
SetTitle(titleEntry);
|
||||
}
|
||||
|
||||
if(pQuest->GetBonusTalents())
|
||||
m_questRewardTalentCount+=pQuest->GetBonusTalents();
|
||||
}
|
||||
|
||||
sLog.outDebug("Quest status is {%u} for quest {%u} for player (GUID: %u)", questStatusData.m_status, quest_id, GetGUIDLow());
|
||||
|
|
@ -15135,7 +15253,7 @@ void Player::_LoadSpells(QueryResult *result)
|
|||
{
|
||||
Field *fields = result->Fetch();
|
||||
|
||||
addSpell(fields[0].GetUInt16(), fields[1].GetBool(), false, fields[2].GetBool());
|
||||
addSpell(fields[0].GetUInt16(), fields[1].GetBool(), false, false, fields[2].GetBool());
|
||||
}
|
||||
while( result->NextRow() );
|
||||
|
||||
|
|
@ -15284,29 +15402,29 @@ InstancePlayerBind* Player::BindToInstance(InstanceSave *save, bool permanent, b
|
|||
|
||||
void Player::SendRaidInfo()
|
||||
{
|
||||
uint32 counter = 0;
|
||||
|
||||
WorldPacket data(SMSG_RAID_INSTANCE_INFO, 4);
|
||||
|
||||
uint32 counter = 0, i;
|
||||
for(i = 0; i < TOTAL_DIFFICULTIES; i++)
|
||||
for (BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr)
|
||||
if(itr->second.perm) counter++;
|
||||
size_t p_counter = data.wpos();
|
||||
data << uint32(counter); // placeholder
|
||||
|
||||
data << counter;
|
||||
for(i = 0; i < TOTAL_DIFFICULTIES; i++)
|
||||
for(int i = 0; i < TOTAL_DIFFICULTIES; ++i)
|
||||
{
|
||||
for (BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr)
|
||||
{
|
||||
if(itr->second.perm)
|
||||
{
|
||||
InstanceSave *save = itr->second.save;
|
||||
data << (save->GetMapId());
|
||||
data << (uint32)(save->GetResetTime() - time(NULL));
|
||||
data << save->GetInstanceId();
|
||||
data << uint32(counter);
|
||||
counter--;
|
||||
data << uint32(save->GetMapId());
|
||||
data << uint32(save->GetResetTime() - time(NULL));
|
||||
data << uint32(save->GetInstanceId());
|
||||
data << uint32(save->GetDifficulty());
|
||||
++counter;
|
||||
}
|
||||
}
|
||||
}
|
||||
data.put<uint32>(p_counter,counter);
|
||||
GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
|
|
@ -15897,7 +16015,9 @@ void Player::_SaveSpells()
|
|||
++next;
|
||||
if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->state == PLAYERSPELL_CHANGED)
|
||||
CharacterDatabase.PExecute("DELETE FROM character_spell WHERE guid = '%u' and spell = '%u'", GetGUIDLow(), itr->first);
|
||||
if (itr->second->state == PLAYERSPELL_NEW || itr->second->state == PLAYERSPELL_CHANGED)
|
||||
|
||||
// add only changed/new not dependent spells
|
||||
if (!itr->second->dependent && (itr->second->state == PLAYERSPELL_NEW || itr->second->state == PLAYERSPELL_CHANGED))
|
||||
CharacterDatabase.PExecute("INSERT INTO character_spell (guid,spell,active,disabled) VALUES ('%u', '%u', '%u', '%u')", GetGUIDLow(), itr->first, itr->second->active ? 1 : 0,itr->second->disabled ? 1 : 0);
|
||||
|
||||
if (itr->second->state == PLAYERSPELL_REMOVED)
|
||||
|
|
@ -18116,9 +18236,9 @@ void Player::learnDefaultSpells()
|
|||
uint32 tspell = *itr;
|
||||
sLog.outDebug("PLAYER (Class: %u Race: %u): Adding initial spell, id = %u",uint32(getClass()),uint32(getRace()), tspell);
|
||||
if(!IsInWorld()) // will send in INITIAL_SPELLS in list anyway at map add
|
||||
addSpell(tspell,true,true,false);
|
||||
addSpell(tspell,true,true,true,false);
|
||||
else // but send in normal spell in game learn case
|
||||
learnSpell(tspell);
|
||||
learnSpell(tspell,true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -18210,7 +18330,7 @@ void Player::learnQuestRewardedSpells()
|
|||
}
|
||||
}
|
||||
|
||||
void Player::learnSkillRewardedSpells(uint32 skill_id )
|
||||
void Player::learnSkillRewardedSpells(uint32 skill_id, uint32 skill_value )
|
||||
{
|
||||
uint32 raceMask = getRaceMask();
|
||||
uint32 classMask = getClassMask();
|
||||
|
|
@ -18228,8 +18348,14 @@ void Player::learnSkillRewardedSpells(uint32 skill_id )
|
|||
|
||||
if (sSpellStore.LookupEntry(pAbility->spellId))
|
||||
{
|
||||
// Ok need learn spell
|
||||
learnSpell(pAbility->spellId);
|
||||
// need unlearn spell
|
||||
if (skill_value < pAbility->req_skill_value)
|
||||
removeSpell(pAbility->spellId);
|
||||
// need learn
|
||||
else if (!IsInWorld())
|
||||
addSpell(pAbility->spellId,true,true,true,false);
|
||||
else
|
||||
learnSpell(pAbility->spellId,true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18241,9 +18367,10 @@ void Player::learnSkillRewardedSpells()
|
|||
if(!GetUInt32Value(PLAYER_SKILL_INDEX(i)))
|
||||
continue;
|
||||
|
||||
uint32 pskill = GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF;
|
||||
uint32 pskill = SKILL_VALUE(GetUInt32Value(PLAYER_SKILL_INDEX(i)));
|
||||
uint32 vskill = SKILL_VALUE(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i)));
|
||||
|
||||
learnSkillRewardedSpells(pskill);
|
||||
learnSkillRewardedSpells(pskill, vskill);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -18692,7 +18819,7 @@ bool Player::isHonorOrXPTarget(Unit* pVictim)
|
|||
|
||||
if(pVictim->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
if (((Creature*)pVictim)->isTotem() ||
|
||||
if (((Creature*)pVictim)->isTotem() ||
|
||||
((Creature*)pVictim)->isPet() ||
|
||||
((Creature*)pVictim)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_XP_AT_KILL)
|
||||
return false;
|
||||
|
|
@ -18859,8 +18986,7 @@ void Player::SetClientControl(Unit* target, uint8 allowMove)
|
|||
void Player::UpdateZoneDependentAuras( uint32 newZone )
|
||||
{
|
||||
// remove new continent flight forms
|
||||
uint32 v_map = GetVirtualMapForMapAndZone(GetMapId(), newZone);
|
||||
if( !isGameMaster() && v_map != 530 && v_map != 571)
|
||||
if( !IsAllowUseFlyMountsHere() )
|
||||
{
|
||||
RemoveSpellsCausingAura(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED);
|
||||
RemoveSpellsCausingAura(SPELL_AURA_FLY);
|
||||
|
|
@ -19268,7 +19394,7 @@ void Player::SetTitle(CharTitlesEntry const* title)
|
|||
void Player::ConvertRune(uint8 index, uint8 newType)
|
||||
{
|
||||
SetCurrentRune(index, newType);
|
||||
|
||||
|
||||
WorldPacket data(SMSG_CONVERT_RUNE, 2);
|
||||
data << uint8(index);
|
||||
data << uint8(newType);
|
||||
|
|
@ -19333,3 +19459,29 @@ void Player::AutoStoreLootItem(uint8 bag, uint8 slot, uint32 loot_id, LootStore
|
|||
|
||||
StoreNewItem (dest,lootItem->itemid,true,lootItem->randomPropertyId);
|
||||
}
|
||||
|
||||
uint32 Player::CalculateTalentsPoints() const
|
||||
{
|
||||
uint32 base_talent = getLevel() < 10 ? 0 : uint32((getLevel()-9)*sWorld.getRate(RATE_TALENT));
|
||||
|
||||
if(getClass() != CLASS_DEATH_KNIGHT)
|
||||
return base_talent;
|
||||
|
||||
uint32 talentPointsForLevel =
|
||||
(getLevel() < 56 ? 0 : uint32((getLevel()-55)*sWorld.getRate(RATE_TALENT)))
|
||||
+ m_questRewardTalentCount;
|
||||
|
||||
if(talentPointsForLevel > base_talent)
|
||||
talentPointsForLevel = base_talent;
|
||||
|
||||
return talentPointsForLevel;
|
||||
}
|
||||
|
||||
bool Player::IsAllowUseFlyMountsHere() const
|
||||
{
|
||||
if (isGameMaster())
|
||||
return true;
|
||||
|
||||
uint32 v_map = GetVirtualMapForMapAndZone(GetMapId(), GetZoneId());
|
||||
return v_map == 530 || v_map == 571 && HasSpell(54197);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,8 +85,9 @@ enum PlayerSpellState
|
|||
struct PlayerSpell
|
||||
{
|
||||
PlayerSpellState state : 8;
|
||||
bool active : 1;
|
||||
bool disabled : 1;
|
||||
bool active : 1; // show in spellbook
|
||||
bool dependent : 1; // learned as result another spell learn, skill grow, quest reward, etc
|
||||
bool disabled : 1; // first rank has been learned in result talent learn but currently talent unlearned, save max learned ranks
|
||||
};
|
||||
|
||||
// Spell modifier (used for modify other spells)
|
||||
|
|
@ -103,7 +104,7 @@ struct SpellModifier
|
|||
Spell const* lastAffected;
|
||||
};
|
||||
|
||||
typedef UNORDERED_MAP<uint16, PlayerSpell*> PlayerSpellMap;
|
||||
typedef UNORDERED_MAP<uint32, PlayerSpell*> PlayerSpellMap;
|
||||
typedef std::list<SpellModifier*> SpellModList;
|
||||
|
||||
struct SpellCooldown
|
||||
|
|
@ -440,7 +441,7 @@ enum PlayerFlags
|
|||
PLAYER_FLAGS_UNK18 = 0x00020000, // taxi benchmark mode (on/off) (2.0.1)
|
||||
PLAYER_FLAGS_PVP_TIMER = 0x00040000, // 3.0.2, pvp timer active (after you disable pvp manually)
|
||||
PLAYER_FLAGS_UNK20 = 0x00080000,
|
||||
PLAYER_FLAGS_UNK21 = 0x00100000,
|
||||
PLAYER_FLAGS_UNK21 = 0x00100000,
|
||||
PLAYER_FLAGS_UNK22 = 0x00200000,
|
||||
PLAYER_FLAGS_UNK23 = 0x00400000,
|
||||
PLAYER_FLAGS_UNK24 = 0x00800000, // disabled all abilitys on tab except autoattack
|
||||
|
|
@ -938,7 +939,7 @@ class MANGOS_DLL_SPEC PlayerTaxi
|
|||
void AppendTaximaskTo(ByteBuffer& data,bool all);
|
||||
|
||||
// Destinations
|
||||
bool LoadTaxiDestinationsFromString(const std::string& values);
|
||||
bool LoadTaxiDestinationsFromString(const std::string& values, uint32 team);
|
||||
std::string SaveTaxiDestinationsToString();
|
||||
|
||||
void ClearTaxiDestinations() { m_TaxiDestinations.clear(); }
|
||||
|
|
@ -1475,13 +1476,15 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
void CharmSpellInitialize();
|
||||
void PossessSpellInitialize();
|
||||
bool HasSpell(uint32 spell) const;
|
||||
bool HasActiveSpell(uint32 spell) const; // show in spellbook
|
||||
TrainerSpellState GetTrainerSpellState(TrainerSpell const* trainer_spell) const;
|
||||
bool IsSpellFitByClassAndRace( uint32 spell_id ) const;
|
||||
bool IsNeedCastPassiveSpellAtLearn(SpellEntry const* spellInfo) const;
|
||||
|
||||
void SendProficiency(uint8 pr1, uint32 pr2);
|
||||
void SendInitialSpells();
|
||||
bool addSpell(uint32 spell_id, bool active, bool learning, bool disabled);
|
||||
void learnSpell(uint32 spell_id);
|
||||
bool addSpell(uint32 spell_id, bool active, bool learning, bool dependent, bool disabled);
|
||||
void learnSpell(uint32 spell_id, bool dependent);
|
||||
void removeSpell(uint32 spell_id, bool disabled = false);
|
||||
void resetSpells();
|
||||
void learnDefaultSpells();
|
||||
|
|
@ -1494,6 +1497,8 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
uint32 resetTalentsCost() const;
|
||||
void InitTalentForLevel();
|
||||
|
||||
uint32 CalculateTalentsPoints() const;
|
||||
|
||||
void InitGlyphsForLevel();
|
||||
void SetGlyphSlot(uint8 slot, uint32 slottype) { SetUInt32Value(PLAYER_FIELD_GLYPH_SLOTS_1 + slot, slottype); }
|
||||
uint32 GetGlyphSlot(uint8 slot) { return GetUInt32Value(PLAYER_FIELD_GLYPH_SLOTS_1 + slot); }
|
||||
|
|
@ -1766,7 +1771,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
int16 GetSkillPermBonusValue(uint32 skill) const;
|
||||
int16 GetSkillTempBonusValue(uint32 skill) const;
|
||||
bool HasSkill(uint32 skill) const;
|
||||
void learnSkillRewardedSpells( uint32 id );
|
||||
void learnSkillRewardedSpells(uint32 id, uint32 value);
|
||||
void learnSkillRewardedSpells();
|
||||
|
||||
void SetDontMove(bool dontMove);
|
||||
|
|
@ -2049,6 +2054,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
|
||||
bool CanFly() const { return HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY); }
|
||||
bool IsFlying() const { return HasUnitMovementFlag(MOVEMENTFLAG_FLYING); }
|
||||
bool IsAllowUseFlyMountsHere() const;
|
||||
|
||||
void HandleDrowning();
|
||||
|
||||
|
|
@ -2393,6 +2399,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
uint32 m_resetTalentsCost;
|
||||
time_t m_resetTalentsTime;
|
||||
uint32 m_usedTalentCount;
|
||||
uint32 m_questRewardTalentCount;
|
||||
|
||||
// Social
|
||||
PlayerSocial *m_social;
|
||||
|
|
|
|||
|
|
@ -84,7 +84,8 @@ bool LoadScriptingModule(char const* libName)
|
|||
return false;
|
||||
}
|
||||
|
||||
printf("Scripts Library %s was successfully loaded.\n",name.c_str());
|
||||
sLog.outString();
|
||||
sLog.outString( ">>> Scripts Library %s was successfully loaded.\n", name.c_str() );
|
||||
|
||||
//heh we are still there :P we have a valid library
|
||||
//we reload script
|
||||
|
|
|
|||
|
|
@ -383,7 +383,7 @@ enum ItemQualities
|
|||
#define SPELL_ATTR_EX5_UNK6 0x00000040 // 6
|
||||
#define SPELL_ATTR_EX5_UNK7 0x00000080 // 7
|
||||
#define SPELL_ATTR_EX5_UNK8 0x00000100 // 8
|
||||
#define SPELL_ATTR_EX5_UNK9 0x00000200 // 9
|
||||
#define SPELL_ATTR_EX5_START_PERIODIC_AT_APPLY 0x00000200 // 9 begin periodic tick at aura apply
|
||||
#define SPELL_ATTR_EX5_UNK10 0x00000400 // 10
|
||||
#define SPELL_ATTR_EX5_UNK11 0x00000800 // 11
|
||||
#define SPELL_ATTR_EX5_UNK12 0x00001000 // 12
|
||||
|
|
@ -807,7 +807,7 @@ enum Targets
|
|||
TARGET_EFFECT_SELECT = 18, // highly depends on the spell effect
|
||||
TARGET_ALL_PARTY_AROUND_CASTER = 20,
|
||||
TARGET_SINGLE_FRIEND = 21,
|
||||
TARGET_ALL_AROUND_CASTER = 22, // used only in TargetA, target selection dependent from TargetB
|
||||
TARGET_CASTER_COORDINATES = 22, // used only in TargetA, target selection dependent from TargetB
|
||||
TARGET_GAMEOBJECT = 23,
|
||||
TARGET_IN_FRONT_OF_CASTER = 24,
|
||||
TARGET_DUELVSPLAYER = 25,
|
||||
|
|
@ -838,6 +838,7 @@ enum Targets
|
|||
TARGET_AREAEFFECT_PARTY_AND_CLASS = 61,
|
||||
TARGET_DUELVSPLAYER_COORDINATES = 63,
|
||||
TARGET_BEHIND_VICTIM = 65, // uses in teleport behind spells
|
||||
TARGET_DYNAMIC_OBJECT_COORDINATES = 76,
|
||||
TARGET_SINGLE_ENEMY = 77,
|
||||
TARGET_SELF2 = 87,
|
||||
TARGET_NONCOMBAT_PET = 90,
|
||||
|
|
@ -1505,6 +1506,7 @@ enum TrainerType // this is important
|
|||
|
||||
#define MAX_TRAINER_TYPE 4
|
||||
|
||||
// CreatureType.dbc
|
||||
enum CreatureType
|
||||
{
|
||||
CREATURE_TYPE_BEAST = 1,
|
||||
|
|
@ -1524,6 +1526,7 @@ enum CreatureType
|
|||
|
||||
uint32 const CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD = (1 << (CREATURE_TYPE_HUMANOID-1)) | (1 << (CREATURE_TYPE_UNDEAD-1));
|
||||
|
||||
// CreatureFamily.dbc
|
||||
enum CreatureFamily
|
||||
{
|
||||
CREATURE_FAMILY_WOLF = 1,
|
||||
|
|
@ -1535,6 +1538,7 @@ enum CreatureFamily
|
|||
CREATURE_FAMILY_CARRION_BIRD = 7,
|
||||
CREATURE_FAMILY_CRAB = 8,
|
||||
CREATURE_FAMILY_GORILLA = 9,
|
||||
CREATURE_FAMILY_HORSE_CUSTOM = 10, // not exist in DBC but used for horse like beasts in DB
|
||||
CREATURE_FAMILY_RAPTOR = 11,
|
||||
CREATURE_FAMILY_TALLSTRIDER = 12,
|
||||
CREATURE_FAMILY_FELHUNTER = 15,
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ void WorldSession::HandleLearnTalentOpcode( WorldPacket & recv_data )
|
|||
return;
|
||||
|
||||
// learn! (other talent ranks will unlearned at learning)
|
||||
GetPlayer( )->learnSpell(spellid);
|
||||
GetPlayer( )->learnSpell(spellid,false);
|
||||
sLog.outDetail("TalentID: %u Rank: %u Spell: %u\n", talent_id, requested_rank, spellid);
|
||||
|
||||
// update free talent points
|
||||
|
|
|
|||
|
|
@ -101,6 +101,14 @@ void SpellCastTargets::setDestination(float x, float y, float z)
|
|||
m_targetMask |= TARGET_FLAG_DEST_LOCATION;
|
||||
}
|
||||
|
||||
void SpellCastTargets::setSource(float x, float y, float z)
|
||||
{
|
||||
m_srcX = x;
|
||||
m_srcY = y;
|
||||
m_srcZ = z;
|
||||
m_targetMask |= TARGET_FLAG_SOURCE_LOCATION;
|
||||
}
|
||||
|
||||
void SpellCastTargets::setGOTarget(GameObject *target)
|
||||
{
|
||||
m_GOTarget = target;
|
||||
|
|
@ -349,6 +357,7 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
|
|||
focusObject = NULL;
|
||||
m_cast_count = 0;
|
||||
m_glyphIndex = 0;
|
||||
m_preCastSpell = 0;
|
||||
m_triggeredByAuraSpell = NULL;
|
||||
|
||||
//Auto Shot & Shoot (wand)
|
||||
|
|
@ -418,17 +427,11 @@ void Spell::FillTargetMap()
|
|||
// but need it support in some know cases
|
||||
switch(m_spellInfo->EffectImplicitTargetA[i])
|
||||
{
|
||||
case TARGET_ALL_AROUND_CASTER:
|
||||
if( m_spellInfo->EffectImplicitTargetB[i]==TARGET_ALL_PARTY ||
|
||||
m_spellInfo->EffectImplicitTargetB[i]==TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER ||
|
||||
m_spellInfo->EffectImplicitTargetB[i]==TARGET_ALL_RAID_AROUND_CASTER )
|
||||
{
|
||||
SetTargetMap(i,m_spellInfo->EffectImplicitTargetB[i],tmpUnitMap);
|
||||
}
|
||||
case TARGET_CASTER_COORDINATES:
|
||||
// Note: this hack with search required until GO casting not implemented
|
||||
// environment damage spells already have around enemies targeting but this not help in case not existed GO casting support
|
||||
// currently each enemy selected explicitly and self cast damage
|
||||
else if(m_spellInfo->EffectImplicitTargetB[i]==TARGET_ALL_ENEMY_IN_AREA && m_spellInfo->Effect[i]==SPELL_EFFECT_ENVIRONMENTAL_DAMAGE)
|
||||
if(m_spellInfo->EffectImplicitTargetB[i]==TARGET_ALL_ENEMY_IN_AREA && m_spellInfo->Effect[i]==SPELL_EFFECT_ENVIRONMENTAL_DAMAGE)
|
||||
{
|
||||
if(m_targets.getUnitTarget())
|
||||
tmpUnitMap.push_back(m_targets.getUnitTarget());
|
||||
|
|
@ -640,8 +643,6 @@ void Spell::FillTargetMap()
|
|||
break;
|
||||
}
|
||||
}
|
||||
if(IsChanneledSpell(m_spellInfo) && !tmpUnitMap.empty())
|
||||
m_needAliveTargetMask |= (1<<i);
|
||||
|
||||
if(m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
|
|
@ -709,11 +710,12 @@ void Spell::prepareDataForTriggerSystem()
|
|||
case SPELLFAMILY_ROGUE: // For poisons need do it
|
||||
if (m_spellInfo->SpellFamilyFlags & 0x000000101001E000LL) m_canTrigger = true;
|
||||
break;
|
||||
case SPELLFAMILY_HUNTER: // Hunter Rapid Killing/Explosive Trap Effect/Immolation Trap Effect/Frost Trap Aura/Snake Trap Effect
|
||||
if (m_spellInfo->SpellFamilyFlags & 0x0100200000000014LL) m_canTrigger = true;
|
||||
case SPELLFAMILY_HUNTER: // Hunter Rapid Killing/Explosive Trap Effect/Immolation Trap Effect/Frost Trap Aura/Snake Trap Effect/Explosive Shot
|
||||
if (m_spellInfo->SpellFamilyFlags & 0x0100200000000214LL ||
|
||||
m_spellInfo->SpellFamilyFlags2 & 0x200) m_canTrigger = true;
|
||||
break;
|
||||
case SPELLFAMILY_PALADIN: // For Holy Shock triggers need do it
|
||||
if (m_spellInfo->SpellFamilyFlags & 0x0001000000200000LL) m_canTrigger = true;
|
||||
case SPELLFAMILY_PALADIN: // For Judgements (all) / Holy Shock triggers need do it
|
||||
if (m_spellInfo->SpellFamilyFlags & 0x0001000900B80400LL) m_canTrigger = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -928,7 +930,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
|
|||
return;
|
||||
|
||||
// Get original caster (if exist) and calculate damage/healing from him data
|
||||
Unit *caster = m_originalCasterGUID ? m_originalCaster : m_caster;
|
||||
Unit *caster = m_originalCaster ? m_originalCaster : m_caster;
|
||||
|
||||
// Skip if m_originalCaster not avaiable
|
||||
if (!caster)
|
||||
|
|
@ -1010,25 +1012,6 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
|
|||
int32 damagePoint = damageInfo.damage * 33 / 100;
|
||||
m_caster->CastCustomSpell(m_caster, 32220, &damagePoint, NULL, NULL, true);
|
||||
}
|
||||
// Bloodthirst
|
||||
else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR && m_spellInfo->SpellFamilyFlags & 0x40000000000LL)
|
||||
{
|
||||
uint32 BTAura = 0;
|
||||
switch(m_spellInfo->Id)
|
||||
{
|
||||
case 23881: BTAura = 23885; break;
|
||||
case 23892: BTAura = 23886; break;
|
||||
case 23893: BTAura = 23887; break;
|
||||
case 23894: BTAura = 23888; break;
|
||||
case 25251: BTAura = 25252; break;
|
||||
case 30335: BTAura = 30339; break;
|
||||
default:
|
||||
sLog.outError("Spell::EffectSchoolDMG: Spell %u not handled in BTAura",m_spellInfo->Id);
|
||||
break;
|
||||
}
|
||||
if (BTAura)
|
||||
m_caster->CastSpell(m_caster,BTAura,true);
|
||||
}
|
||||
}
|
||||
// Passive spell hits/misses or active spells only misses (only triggers)
|
||||
else
|
||||
|
|
@ -1146,6 +1129,10 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
|
|||
if((GetDiminishingReturnsGroupType(m_diminishGroup) == DRTYPE_PLAYER && unit->GetTypeId() == TYPEID_PLAYER) || GetDiminishingReturnsGroupType(m_diminishGroup) == DRTYPE_ALL)
|
||||
unit->IncrDiminishing(m_diminishGroup);
|
||||
|
||||
// Apply additional spell effects to target
|
||||
if (m_preCastSpell)
|
||||
m_caster->CastSpell(unit,m_preCastSpell, true, m_CastItem);
|
||||
|
||||
for(uint32 effectNumber=0;effectNumber<3;effectNumber++)
|
||||
{
|
||||
if (effectMask & (1<<effectNumber))
|
||||
|
|
@ -1480,6 +1467,19 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
|
|||
}break;
|
||||
case TARGET_ALL_ENEMY_IN_AREA:
|
||||
{
|
||||
CellPair p(MaNGOS::ComputeCellPair(m_targets.m_destX, m_targets.m_destY));
|
||||
Cell cell(p);
|
||||
cell.data.Part.reserved = ALL_DISTRICT;
|
||||
cell.SetNoCreate();
|
||||
|
||||
MaNGOS::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius, PUSH_DEST_CENTER,SPELL_TARGETS_AOE_DAMAGE);
|
||||
|
||||
TypeContainerVisitor<MaNGOS::SpellNotifierCreatureAndPlayer, WorldTypeMapContainer > world_object_notifier(notifier);
|
||||
TypeContainerVisitor<MaNGOS::SpellNotifierCreatureAndPlayer, GridTypeMapContainer > grid_object_notifier(notifier);
|
||||
|
||||
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||
cell_lock->Visit(cell_lock, world_object_notifier, *m_caster->GetMap());
|
||||
cell_lock->Visit(cell_lock, grid_object_notifier, *m_caster->GetMap());
|
||||
}break;
|
||||
case TARGET_ALL_ENEMY_IN_AREA_INSTANT:
|
||||
{
|
||||
|
|
@ -1564,25 +1564,13 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
|
|||
if( target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isPet() && ((Pet*)target)->getPetType() == MINI_PET)
|
||||
TagUnitMap.push_back(target);
|
||||
}break;
|
||||
case TARGET_ALL_AROUND_CASTER:
|
||||
case TARGET_CASTER_COORDINATES:
|
||||
{
|
||||
CellPair p(MaNGOS::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY()));
|
||||
Cell cell(p);
|
||||
cell.data.Part.reserved = ALL_DISTRICT;
|
||||
cell.SetNoCreate();
|
||||
|
||||
MaNGOS::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius, PUSH_SELF_CENTER,SPELL_TARGETS_AOE_DAMAGE);
|
||||
|
||||
TypeContainerVisitor<MaNGOS::SpellNotifierCreatureAndPlayer, WorldTypeMapContainer > world_object_notifier(notifier);
|
||||
TypeContainerVisitor<MaNGOS::SpellNotifierCreatureAndPlayer, GridTypeMapContainer > grid_object_notifier(notifier);
|
||||
|
||||
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||
cell_lock->Visit(cell_lock, world_object_notifier, *m_caster->GetMap());
|
||||
cell_lock->Visit(cell_lock, grid_object_notifier, *m_caster->GetMap());
|
||||
m_targets.setDestination(m_targets.m_srcX, m_targets.m_srcY, m_targets.m_srcZ);
|
||||
}break;
|
||||
case TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER:
|
||||
{
|
||||
CellPair p(MaNGOS::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY()));
|
||||
CellPair p(MaNGOS::ComputeCellPair(m_targets.m_destX, m_targets.m_destY));
|
||||
Cell cell(p);
|
||||
cell.data.Part.reserved = ALL_DISTRICT;
|
||||
cell.SetNoCreate();
|
||||
|
|
@ -1725,7 +1713,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
|
|||
// targets the ground, not the units in the area
|
||||
if (m_spellInfo->Effect[i]!=SPELL_EFFECT_PERSISTENT_AREA_AURA)
|
||||
{
|
||||
CellPair p(MaNGOS::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY()));
|
||||
CellPair p(MaNGOS::ComputeCellPair(m_targets.m_destX, m_targets.m_destY));
|
||||
Cell cell(p);
|
||||
cell.data.Part.reserved = ALL_DISTRICT;
|
||||
cell.SetNoCreate();
|
||||
|
|
@ -1998,6 +1986,12 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
|
|||
m_targets.setDestination(_target_x, _target_y, _target_z);
|
||||
}
|
||||
}break;
|
||||
case TARGET_DYNAMIC_OBJECT_COORDINATES:
|
||||
{
|
||||
// if parent spell create dynamic object extract area from it
|
||||
if(DynamicObject* dynObj = m_caster->GetDynObject(m_triggeredByAuraSpell ? m_triggeredByAuraSpell->Id : m_spellInfo->Id))
|
||||
m_targets.setDestination(dynObj->GetPositionX(), dynObj->GetPositionY(), dynObj->GetPositionZ());
|
||||
}break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -2044,6 +2038,18 @@ void Spell::prepare(SpellCastTargets const* targets, Aura* triggeredByAura)
|
|||
|
||||
m_spellState = SPELL_STATE_PREPARING;
|
||||
|
||||
if (!(m_targets.m_targetMask & TARGET_FLAG_SOURCE_LOCATION))
|
||||
{
|
||||
// Check original caster is GO - set its coordinates as src cast
|
||||
WorldObject *caster = NULL;
|
||||
if (m_originalCasterGUID)
|
||||
caster = ObjectAccessor::GetGameObject(*m_caster, m_originalCasterGUID);
|
||||
if (!caster)
|
||||
caster = m_caster;
|
||||
// Set cast source for targets
|
||||
m_targets.setSource(caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ());
|
||||
}
|
||||
|
||||
m_castPositionX = m_caster->GetPositionX();
|
||||
m_castPositionY = m_caster->GetPositionY();
|
||||
m_castPositionZ = m_caster->GetPositionZ();
|
||||
|
|
@ -2192,6 +2198,47 @@ void Spell::cast(bool skipCheck)
|
|||
}
|
||||
}
|
||||
|
||||
switch(m_spellInfo->SpellFamilyName)
|
||||
{
|
||||
case SPELLFAMILY_GENERIC:
|
||||
{
|
||||
if (m_spellInfo->Mechanic == MECHANIC_BANDAGE) // Bandages
|
||||
m_preCastSpell = 11196; // Recently Bandaged
|
||||
else if(m_spellInfo->SpellIconID == 1662 && m_spellInfo->AttributesEx & 0x20) // Blood Fury (Racial)
|
||||
m_preCastSpell = 23230; // Blood Fury - Healing Reduction
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_MAGE:
|
||||
{
|
||||
if (m_spellInfo->SpellFamilyFlags&0x0000008000000000LL) // Ice Block
|
||||
m_preCastSpell = 41425; // Hypothermia
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_PRIEST:
|
||||
{
|
||||
if (m_spellInfo->Mechanic == MECHANIC_SHIELD &&
|
||||
m_spellInfo->SpellIconID == 566) // Power Word: Shield
|
||||
m_preCastSpell = 6788; // Weakened Soul
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_PALADIN:
|
||||
{
|
||||
if (m_spellInfo->SpellFamilyFlags&0x0000000000400080LL) // Divine Shield, Divine Protection or Hand of Protection
|
||||
m_preCastSpell = 25771; // Forbearance
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_SHAMAN:
|
||||
{
|
||||
if (m_spellInfo->Id == 2825) // Bloodlust
|
||||
m_preCastSpell = 57724; // Sated
|
||||
else if (m_spellInfo->Id == 32182) // Heroism
|
||||
m_preCastSpell = 57723; // Exhaustion
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Conflagrate - consumes immolate
|
||||
if ((m_spellInfo->TargetAuraState == AURA_STATE_IMMOLATE) && m_targets.getUnitTarget())
|
||||
{
|
||||
|
|
@ -2266,6 +2313,9 @@ void Spell::handle_immediate()
|
|||
int32 duration = GetSpellDuration(m_spellInfo);
|
||||
if (duration)
|
||||
{
|
||||
// Apply duration mod
|
||||
if(Player* modOwner = m_caster->GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
|
||||
m_spellState = SPELL_STATE_CASTING;
|
||||
SendChannelStart(duration);
|
||||
}
|
||||
|
|
@ -2684,68 +2734,6 @@ void Spell::finish(bool ok)
|
|||
((Player*)m_caster)->ClearComboPoints();
|
||||
}
|
||||
|
||||
// Post effects apply on spell targets in some spells
|
||||
if(!m_UniqueTargetInfo.empty())
|
||||
{
|
||||
uint32 spellId = 0;
|
||||
switch(m_spellInfo->SpellFamilyName)
|
||||
{
|
||||
case SPELLFAMILY_GENERIC:
|
||||
{
|
||||
if (m_spellInfo->Mechanic == MECHANIC_BANDAGE) // Bandages
|
||||
spellId = 11196; // Recently Bandaged
|
||||
else if(m_spellInfo->SpellIconID == 1662 && m_spellInfo->AttributesEx & 0x20) // Blood Fury (Racial)
|
||||
spellId = 23230; // Blood Fury - Healing Reduction
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_MAGE:
|
||||
{
|
||||
if (m_spellInfo->SpellFamilyFlags&0x0000008000000000LL) // Ice Block
|
||||
spellId = 41425; // Hypothermia
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_PRIEST:
|
||||
{
|
||||
if (m_spellInfo->Mechanic == MECHANIC_SHIELD &&
|
||||
m_spellInfo->SpellIconID == 566) // Power Word: Shield
|
||||
spellId = 6788; // Weakened Soul
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_PALADIN:
|
||||
{
|
||||
if (m_spellInfo->SpellFamilyFlags&0x0000000000400080LL) // Divine Shield, Divine Protection or Hand of Protection
|
||||
spellId = 25771; // Forbearance
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_SHAMAN:
|
||||
{
|
||||
if (m_spellInfo->Id == 2825) // Bloodlust
|
||||
spellId = 57724; // Sated
|
||||
else if (m_spellInfo->Id == 32182) // Heroism
|
||||
spellId = 57723; // Exhaustion
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (spellId)
|
||||
{
|
||||
for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
|
||||
{
|
||||
Unit* unit = m_caster->GetGUID()==ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
|
||||
if (unit)
|
||||
{
|
||||
// TODO: fix me use cast spell (now post spell can immune by this spell)
|
||||
// m_caster->CastSpell(unit, spellId, true, m_CastItem);
|
||||
SpellEntry const *AdditionalSpellInfo = sSpellStore.LookupEntry(spellId);
|
||||
if (!AdditionalSpellInfo)
|
||||
continue;
|
||||
Aura* AdditionalAura = CreateAura(AdditionalSpellInfo, 0, &m_currentBasePoints[0], unit, m_caster, m_CastItem);
|
||||
unit->AddAura(AdditionalAura);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// call triggered spell only at successful cast (after clear combo points -> for add some if need)
|
||||
if(!m_TriggerSpells.empty())
|
||||
TriggerSpell();
|
||||
|
|
@ -2892,6 +2880,7 @@ void Spell::SendSpellGo()
|
|||
}
|
||||
|
||||
WorldPacket data(SMSG_SPELL_GO, 50); // guess size
|
||||
|
||||
if(m_CastItem)
|
||||
data.append(m_CastItem->GetPackGUID());
|
||||
else
|
||||
|
|
@ -2989,6 +2978,8 @@ void Spell::WriteAmmoToPacket( WorldPacket * data )
|
|||
|
||||
void Spell::WriteSpellGoTargets( WorldPacket * data )
|
||||
{
|
||||
// This function also fill data for channeled spells:
|
||||
// m_needAliveTargetMask req for stop channelig if one target die
|
||||
uint32 hit = m_UniqueGOTargetInfo.size(); // Always hits on GO
|
||||
uint32 miss = 0;
|
||||
for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
|
||||
|
|
@ -3008,7 +2999,10 @@ void Spell::WriteSpellGoTargets( WorldPacket * data )
|
|||
*data << (uint8)hit;
|
||||
for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
|
||||
if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits
|
||||
{
|
||||
*data << uint64(ihit->targetGUID);
|
||||
m_needAliveTargetMask |=ihit->effectMask;
|
||||
}
|
||||
|
||||
for(std::list<GOTargetInfo>::iterator ighit= m_UniqueGOTargetInfo.begin();ighit != m_UniqueGOTargetInfo.end();++ighit)
|
||||
*data << uint64(ighit->targetGUID); // Always hits
|
||||
|
|
@ -3024,6 +3018,9 @@ void Spell::WriteSpellGoTargets( WorldPacket * data )
|
|||
*data << uint8(ihit->reflectResult);
|
||||
}
|
||||
}
|
||||
// Reset m_needAliveTargetMask for non channeled spell
|
||||
if(!IsChanneledSpell(m_spellInfo))
|
||||
m_needAliveTargetMask = 0;
|
||||
}
|
||||
|
||||
void Spell::SendLogExecute()
|
||||
|
|
@ -4247,7 +4244,7 @@ uint8 Spell::CanCast(bool strict)
|
|||
|
||||
break;
|
||||
}
|
||||
// This is generic summon effect
|
||||
// This is generic summon effect
|
||||
case SPELL_EFFECT_SUMMON:
|
||||
{
|
||||
switch(m_spellInfo->EffectMiscValueB[i])
|
||||
|
|
@ -4421,8 +4418,7 @@ uint8 Spell::CanCast(bool strict)
|
|||
// not allow cast fly spells at old maps by players (all spells is self target)
|
||||
if(m_caster->GetTypeId()==TYPEID_PLAYER)
|
||||
{
|
||||
uint32 v_map = GetVirtualMapForMapAndZone(m_caster->GetMapId(), m_caster->GetZoneId());
|
||||
if( !((Player*)m_caster)->isGameMaster() && v_map != 530 && !(v_map == 571 && ((Player*)m_caster)->HasSpell(54197)))
|
||||
if( !((Player*)m_caster)->IsAllowUseFlyMountsHere() )
|
||||
return SPELL_FAILED_NOT_HERE;
|
||||
}
|
||||
|
||||
|
|
@ -5407,7 +5403,13 @@ bool Spell::CheckTarget( Unit* target, uint32 eff )
|
|||
// all ok by some way or another, skip normal check
|
||||
break;
|
||||
default: // normal case
|
||||
if(target!=m_caster && !target->IsWithinLOSInMap(m_caster))
|
||||
// Get GO cast coordinates if original caster -> GO
|
||||
WorldObject *caster = NULL;
|
||||
if (m_originalCasterGUID)
|
||||
caster = ObjectAccessor::GetGameObject(*m_caster, m_originalCasterGUID);
|
||||
if (!caster)
|
||||
caster = m_caster;
|
||||
if(target!=m_caster && !target->IsWithinLOSInMap(caster))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -150,6 +150,7 @@ class SpellCastTargets
|
|||
Unit *getUnitTarget() const { return m_unitTarget; }
|
||||
void setUnitTarget(Unit *target);
|
||||
void setDestination(float x, float y, float z);
|
||||
void setSource(float x, float y, float z);
|
||||
|
||||
uint64 getGOTargetGUID() const { return m_GOTargetGUID; }
|
||||
GameObject *getGOTarget() const { return m_GOTarget; }
|
||||
|
|
@ -290,6 +291,7 @@ class Spell
|
|||
void EffectCharge(uint32 i);
|
||||
void EffectProspecting(uint32 i);
|
||||
void EffectMilling(uint32 i);
|
||||
void EffectRenamePet(uint32 i);
|
||||
void EffectSendTaxi(uint32 i);
|
||||
void EffectSummonCritter(uint32 i);
|
||||
void EffectKnockBack(uint32 i);
|
||||
|
|
@ -387,6 +389,7 @@ class Spell
|
|||
Item* m_CastItem;
|
||||
uint8 m_cast_count;
|
||||
uint32 m_glyphIndex;
|
||||
uint32 m_preCastSpell;
|
||||
SpellCastTargets m_targets;
|
||||
|
||||
int32 GetCastTime() const { return m_casttime; }
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ enum AuraType
|
|||
SPELL_AURA_HASTE_MELEE = 192,
|
||||
SPELL_AURA_MELEE_SLOW = 193,
|
||||
SPELL_AURA_MOD_IGNORE_ABSORB_SCHOOL = 194,
|
||||
SPELL_AURA_MOD_DEPRICATED_2 = 195, // not used now, old SPELL_AURA_MOD_SPELL_HEALING_OF_INTELLECT
|
||||
SPELL_AURA_MOD_IGNORE_ABSORB_FOR_SPELL = 195,
|
||||
SPELL_AURA_MOD_COOLDOWN = 196, // only 24818 Noxious Breath
|
||||
SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE = 197,
|
||||
SPELL_AURA_MOD_ALL_WEAPON_SKILLS = 198,
|
||||
|
|
@ -269,7 +269,7 @@ enum AuraType
|
|||
SPELL_AURA_224 = 224,
|
||||
SPELL_AURA_PRAYER_OF_MENDING = 225,
|
||||
SPELL_AURA_PERIODIC_DUMMY = 226,
|
||||
SPELL_AURA_227 = 227,
|
||||
SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE = 227,
|
||||
SPELL_AURA_DETECT_STEALTH = 228,
|
||||
SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE = 229,
|
||||
SPELL_AURA_230 = 230,
|
||||
|
|
@ -309,10 +309,10 @@ enum AuraType
|
|||
SPELL_AURA_264 = 264,
|
||||
SPELL_AURA_265 = 265,
|
||||
SPELL_AURA_266 = 266,
|
||||
SPELL_AURA_267 = 267,
|
||||
SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL = 267,
|
||||
SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT = 268,
|
||||
SPELL_AURA_269 = 269,
|
||||
SPELL_AURA_270 = 270,
|
||||
SPELL_AURA_MOD_IGNORE_TARGET_RESIST = 270, // Possibly need swap vs 195 aura used only in 1 spell Chaos Bolt Passive
|
||||
SPELL_AURA_MOD_DAMAGE_FROM_CASTER = 271,
|
||||
SPELL_AURA_272 = 272,
|
||||
SPELL_AURA_273 = 273,
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
|
|||
&Aura::HandleNoImmediateEffect, // 59 SPELL_AURA_MOD_DAMAGE_DONE_CREATURE implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
|
||||
&Aura::HandleAuraModPacifyAndSilence, // 60 SPELL_AURA_MOD_PACIFY_SILENCE
|
||||
&Aura::HandleAuraModScale, // 61 SPELL_AURA_MOD_SCALE
|
||||
&Aura::HandleNULL, // 62 SPELL_AURA_PERIODIC_HEALTH_FUNNEL
|
||||
&Aura::HandlePeriodicHealthFunnel, // 62 SPELL_AURA_PERIODIC_HEALTH_FUNNEL
|
||||
&Aura::HandleUnused, // 63 SPELL_AURA_PERIODIC_MANA_FUNNEL obsolete?
|
||||
&Aura::HandlePeriodicManaLeech, // 64 SPELL_AURA_PERIODIC_MANA_LEECH
|
||||
&Aura::HandleModCastingSpeed, // 65 SPELL_AURA_MOD_CASTING_SPEED
|
||||
|
|
@ -245,7 +245,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
|
|||
&Aura::HandleModMeleeRangedSpeedPct, //192 SPELL_AURA_HASTE_MELEE
|
||||
&Aura::HandleModCombatSpeedPct, //193 SPELL_AURA_MELEE_SLOW (in fact combat (any type attack) speed pct)
|
||||
&Aura::HandleUnused, //194 SPELL_AURA_MOD_IGNORE_ABSORB_SCHOOL
|
||||
&Aura::HandleUnused, //195 SPELL_AURA_MOD_DEPRICATED_2 not used now (old SPELL_AURA_MOD_SPELL_HEALING_OF_INTELLECT)
|
||||
&Aura::HandleNoImmediateEffect, //195 SPELL_AURA_MOD_IGNORE_ABSORB_FOR_SPELL implement in Unit::CalculateSpellDamage
|
||||
&Aura::HandleNULL, //196 SPELL_AURA_MOD_COOLDOWN
|
||||
&Aura::HandleNoImmediateEffect, //197 SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE implemented in Unit::SpellCriticalBonus Unit::GetUnitCriticalChance
|
||||
&Aura::HandleUnused, //198 SPELL_AURA_MOD_ALL_WEAPON_SKILLS
|
||||
|
|
@ -277,7 +277,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
|
|||
&Aura::HandleUnused, //224 unused
|
||||
&Aura::HandleNoImmediateEffect, //225 SPELL_AURA_PRAYER_OF_MENDING
|
||||
&Aura::HandleAuraPeriodicDummy, //226 SPELL_AURA_PERIODIC_DUMMY
|
||||
&Aura::HandleNULL, //227 periodic trigger spell
|
||||
&Aura::HandlePeriodicTriggerSpellWithValue, //227 SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE
|
||||
&Aura::HandleNoImmediateEffect, //228 stealth detection
|
||||
&Aura::HandleNULL, //229 SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE
|
||||
&Aura::HandleAuraModIncreaseMaxHealth, //230 Commanding Shout
|
||||
|
|
@ -305,7 +305,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
|
|||
&Aura::HandleNULL, //252 haste all?
|
||||
&Aura::HandleNULL, //253 SPELL_AURA_MOD_BLOCK_CRIT_CHANCE
|
||||
&Aura::HandleNULL, //254 SPELL_AURA_MOD_DISARM_SHIELD disarm Shield
|
||||
&Aura::HandleNULL, //255 SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT
|
||||
&Aura::HandleNoImmediateEffect, //255 SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT implemented in Unit::SpellDamageBonus
|
||||
&Aura::HandleNoReagentUseAura, //256 SPELL_AURA_NO_REAGENT_USE Use SpellClassMask for spell select
|
||||
&Aura::HandleNULL, //257 SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS Use SpellClassMask for spell select
|
||||
&Aura::HandleNULL, //258 SPELL_AURA_MOD_SPELL_VISUAL
|
||||
|
|
@ -317,10 +317,10 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
|
|||
&Aura::HandleNULL, //264 unused
|
||||
&Aura::HandleNULL, //265 unused
|
||||
&Aura::HandleNULL, //266 unused
|
||||
&Aura::HandleNULL, //267 some immunity?
|
||||
&Aura::HandleNoImmediateEffect, //267 SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL implemented in Unit::IsImmunedToSpellEffect
|
||||
&Aura::HandleAuraModAttackPowerOfStatPercent, //268 SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT
|
||||
&Aura::HandleNULL, //269 ignore DR effects?
|
||||
&Aura::HandleNULL, //270
|
||||
&Aura::HandleNULL, //270 SPELL_AURA_MOD_IGNORE_TARGET_RESIST
|
||||
&Aura::HandleNoImmediateEffect, //271 SPELL_AURA_MOD_DAMAGE_FROM_CASTER implemented in Unit::SpellDamageBonus
|
||||
&Aura::HandleNULL, //272 reduce spell cast time?
|
||||
&Aura::HandleNULL, //273
|
||||
|
|
@ -340,7 +340,7 @@ Aura::Aura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, U
|
|||
m_spellmod(NULL), m_caster_guid(0), m_castItemGuid(castItem?castItem->GetGUID():0), m_target(target),
|
||||
m_timeCla(1000), m_periodicTimer(0), m_removeMode(AURA_REMOVE_BY_DEFAULT), m_AuraDRGroup(DIMINISHING_NONE),
|
||||
m_effIndex(eff), m_auraSlot(MAX_AURAS), m_auraFlags(AFLAG_NONE), m_auraLevel(1), m_procCharges(0), m_stackAmount(1),
|
||||
m_positive(false), m_permanent(false), m_isPeriodic(false), m_isTrigger(false), m_isAreaAura(false), m_isPersistent(false),
|
||||
m_positive(false), m_permanent(false), m_isPeriodic(false), m_isAreaAura(false), m_isPersistent(false),
|
||||
m_updated(false), m_isRemovedOnShapeLost(true), m_in_use(false)
|
||||
{
|
||||
assert(target);
|
||||
|
|
@ -405,14 +405,19 @@ m_updated(false), m_isRemovedOnShapeLost(true), m_in_use(false)
|
|||
|
||||
m_duration = m_maxduration;
|
||||
|
||||
if(modOwner)
|
||||
modOwner->ApplySpellMod(GetId(), SPELLMOD_ACTIVATION_TIME, m_periodicTimer);
|
||||
|
||||
sLog.outDebug("Aura: construct Spellid : %u, Aura : %u Duration : %d Target : %d Damage : %d", m_spellProto->Id, m_spellProto->EffectApplyAuraName[eff], m_maxduration, m_spellProto->EffectImplicitTargetA[eff],damage);
|
||||
|
||||
m_effIndex = eff;
|
||||
SetModifier(AuraType(m_spellProto->EffectApplyAuraName[eff]), damage, m_spellProto->EffectAmplitude[eff], m_spellProto->EffectMiscValue[eff]);
|
||||
|
||||
// Apply periodic time mod
|
||||
if(modOwner && m_modifier.periodictime)
|
||||
modOwner->ApplySpellMod(GetId(), SPELLMOD_ACTIVATION_TIME, m_modifier.periodictime);
|
||||
|
||||
// Start periodic on next tick or at aura apply
|
||||
if (!(m_spellProto->AttributesEx5 & SPELL_ATTR_EX5_START_PERIODIC_AT_APPLY))
|
||||
m_periodicTimer += m_modifier.periodictime;
|
||||
|
||||
m_isDeathPersist = IsDeathPersistentSpell(m_spellProto);
|
||||
|
||||
m_procCharges = m_spellProto->procCharges;
|
||||
|
|
@ -606,25 +611,11 @@ void Aura::Update(uint32 diff)
|
|||
if(m_isPeriodic && (m_duration >= 0 || m_isPassive || m_permanent))
|
||||
{
|
||||
m_periodicTimer -= diff;
|
||||
if(m_periodicTimer <= 0) // tick also at m_periodicTimer==0 to prevent lost last tick in case max m_duration == (max m_periodicTimer)*N
|
||||
if(m_periodicTimer <= 0) // tick also at m_periodicTimer==0 to prevent lost last tick in case max m_duration == (max m_periodicTimer)*N
|
||||
{
|
||||
if( m_modifier.m_auraname == SPELL_AURA_MOD_REGEN ||
|
||||
m_modifier.m_auraname == SPELL_AURA_MOD_POWER_REGEN ||
|
||||
// Cannibalize, eating items and other spells
|
||||
m_modifier.m_auraname == SPELL_AURA_OBS_MOD_HEALTH ||
|
||||
// Eating items and other spells
|
||||
m_modifier.m_auraname == SPELL_AURA_OBS_MOD_MANA )
|
||||
{
|
||||
ApplyModifier(true);
|
||||
return;
|
||||
}
|
||||
// update before applying (aura can be removed in TriggerSpell or PeriodicTick calls)
|
||||
m_periodicTimer += m_modifier.periodictime;
|
||||
|
||||
if(m_isTrigger)
|
||||
TriggerSpell();
|
||||
else
|
||||
PeriodicTick();
|
||||
PeriodicTick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -927,19 +918,6 @@ void Aura::_AddAura()
|
|||
}
|
||||
}
|
||||
}
|
||||
// not call total regen auras at adding
|
||||
switch (m_modifier.m_auraname)
|
||||
{
|
||||
case SPELL_AURA_OBS_MOD_HEALTH:
|
||||
case SPELL_AURA_OBS_MOD_MANA:
|
||||
m_periodicTimer = m_modifier.periodictime;
|
||||
break;
|
||||
case SPELL_AURA_MOD_REGEN:
|
||||
case SPELL_AURA_MOD_POWER_REGEN:
|
||||
case SPELL_AURA_MOD_MANA_REGEN_FROM_STAT:
|
||||
m_periodicTimer = 5000;
|
||||
break;
|
||||
}
|
||||
|
||||
Unit* caster = GetCaster();
|
||||
|
||||
|
|
@ -963,6 +941,10 @@ void Aura::_AddAura()
|
|||
//*****************************************************
|
||||
if (!secondaura)
|
||||
{
|
||||
// Sitdown on apply aura req seated
|
||||
if (m_spellProto->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED && !m_target->IsSitState())
|
||||
m_target->SetStandState(PLAYER_STATE_SIT);
|
||||
|
||||
// register aura diminishing on apply
|
||||
if (getDiminishGroup() != DIMINISHING_NONE )
|
||||
m_target->ApplyDiminishingAura(getDiminishGroup(),true);
|
||||
|
|
@ -974,7 +956,7 @@ void Aura::_AddAura()
|
|||
// Conflagrate aura state on Immolate
|
||||
if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellProto->SpellFamilyFlags & 4)
|
||||
m_target->ModifyAuraState(AURA_STATE_IMMOLATE, true);
|
||||
|
||||
|
||||
// Faerie Fire (druid versions)
|
||||
if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags & 0x0000000000000400LL)
|
||||
m_target->ModifyAuraState(AURA_STATE_FAERIE_FIRE, true);
|
||||
|
|
@ -1097,7 +1079,7 @@ void Aura::_RemoveAura()
|
|||
for(Unit::AuraMap::iterator i = Auras.begin(); i != Auras.end(); ++i)
|
||||
{
|
||||
SpellEntry const *auraSpellInfo = (*i).second->GetSpellProto();
|
||||
if(auraSpellInfo->SpellFamilyName == m_spellProto->SpellFamilyName &&
|
||||
if(auraSpellInfo->SpellFamilyName == m_spellProto->SpellFamilyName &&
|
||||
auraSpellInfo->SpellFamilyFlags == m_spellProto->SpellFamilyFlags )
|
||||
{
|
||||
found = true;
|
||||
|
|
@ -1317,6 +1299,7 @@ void Aura::HandleAddTargetTrigger(bool apply, bool Real)
|
|||
m_spellmod = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void Aura::TriggerSpell()
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
|
|
@ -1328,8 +1311,6 @@ void Aura::TriggerSpell()
|
|||
// generic casting code with custom spells and target/caster customs
|
||||
uint32 trigger_spell_id = GetSpellProto()->EffectTriggerSpell[m_effIndex];
|
||||
|
||||
uint64 originalCasterGUID = GetCasterGUID();
|
||||
|
||||
SpellEntry const *triggeredSpellInfo = sSpellStore.LookupEntry(trigger_spell_id);
|
||||
SpellEntry const *auraSpellInfo = GetSpellProto();
|
||||
uint32 auraId = auraSpellInfo->Id;
|
||||
|
|
@ -1983,28 +1964,33 @@ void Aura::TriggerSpell()
|
|||
return;
|
||||
|
||||
caster = target;
|
||||
originalCasterGUID = 0;
|
||||
break;
|
||||
}
|
||||
// Mana Tide
|
||||
case 16191:
|
||||
{
|
||||
caster->CastCustomSpell(target, trigger_spell_id, &m_modifier.m_amount, NULL, NULL, true, NULL, this, originalCasterGUID);
|
||||
caster->CastCustomSpell(target, trigger_spell_id, &m_modifier.m_amount, NULL, NULL, true, NULL, this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// All ok cast by default case
|
||||
Spell *spell = new Spell(caster, triggeredSpellInfo, true, originalCasterGUID );
|
||||
caster->CastSpell(target, triggeredSpellInfo, true, 0, this);
|
||||
}
|
||||
|
||||
SpellCastTargets targets;
|
||||
targets.setUnitTarget( target );
|
||||
void Aura::TriggerSpellWithValue()
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
Unit* target = GetTriggerTarget();
|
||||
|
||||
// if spell create dynamic object extract area from it
|
||||
if(DynamicObject* dynObj = caster->GetDynObject(GetId()))
|
||||
targets.setDestination(dynObj->GetPositionX(),dynObj->GetPositionY(),dynObj->GetPositionZ());
|
||||
if(!caster || !target)
|
||||
return;
|
||||
|
||||
spell->prepare(&targets, this);
|
||||
// generic casting code with custom spells and target/caster customs
|
||||
uint32 trigger_spell_id = GetSpellProto()->EffectTriggerSpell[m_effIndex];
|
||||
int32 basepoints0 = this->GetModifier()->m_amount;
|
||||
|
||||
caster->CastCustomSpell(target, trigger_spell_id, &basepoints0, 0, 0, true, 0, this);
|
||||
}
|
||||
|
||||
/*********************************************************/
|
||||
|
|
@ -2146,14 +2132,14 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
|
|||
if (caster && m_removeMode == AURA_REMOVE_BY_DEATH)
|
||||
{
|
||||
// Stop caster Arcane Missle chanelling on death
|
||||
if (m_spellProto->SpellFamilyName == SPELLFAMILY_MAGE &&
|
||||
if (m_spellProto->SpellFamilyName == SPELLFAMILY_MAGE &&
|
||||
m_spellProto->SpellFamilyFlags&0x0000000000000800LL)
|
||||
{
|
||||
caster->InterruptSpell(CURRENT_CHANNELED_SPELL);
|
||||
return;
|
||||
}
|
||||
// Stop caster Penance chanelling on death
|
||||
if (m_spellProto->SpellFamilyName == SPELLFAMILY_PRIEST &&
|
||||
if (m_spellProto->SpellFamilyName == SPELLFAMILY_PRIEST &&
|
||||
m_spellProto->SpellFamilyFlags2 & 0x00000080)
|
||||
{
|
||||
caster->InterruptSpell(CURRENT_CHANNELED_SPELL);
|
||||
|
|
@ -2365,54 +2351,6 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
|
|||
}
|
||||
}
|
||||
|
||||
void Aura::HandleAuraPeriodicDummy(bool apply, bool Real)
|
||||
{
|
||||
// spells required only Real aura add/remove
|
||||
if(!Real)
|
||||
return;
|
||||
|
||||
Unit* caster = GetCaster();
|
||||
|
||||
SpellEntry const*spell = GetSpellProto();
|
||||
switch( spell->SpellFamilyName)
|
||||
{
|
||||
case SPELLFAMILY_ROGUE:
|
||||
{
|
||||
// Master of Subtlety
|
||||
if (spell->Id==31666 && !apply && Real)
|
||||
{
|
||||
m_target->RemoveAurasDueToSpell(31665);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_HUNTER:
|
||||
{
|
||||
// Aspect of the Viper
|
||||
if (spell->SpellFamilyFlags&0x0004000000000000LL)
|
||||
{
|
||||
// Update regen on remove
|
||||
if (!apply && m_target->GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)m_target)->UpdateManaRegen();
|
||||
break;
|
||||
}
|
||||
// Explosive Shot
|
||||
if (spell->SpellFamilyFlags & 0x8000000000000000LL)
|
||||
{
|
||||
if (apply && caster)
|
||||
{
|
||||
int32 damage = m_modifier.m_amount + caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 8 / 100;
|
||||
caster->CastCustomSpell(m_target, 53352, &damage, 0, 0, true, 0, this);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_isPeriodic = apply;
|
||||
}
|
||||
|
||||
void Aura::HandleAuraMounted(bool apply, bool Real)
|
||||
{
|
||||
// only at real add/remove aura
|
||||
|
|
@ -4066,26 +4004,71 @@ void Aura::HandleAuraModStalked(bool apply, bool Real)
|
|||
|
||||
void Aura::HandlePeriodicTriggerSpell(bool apply, bool Real)
|
||||
{
|
||||
if (m_periodicTimer <= 0)
|
||||
m_periodicTimer += m_modifier.periodictime;
|
||||
|
||||
m_isPeriodic = apply;
|
||||
m_isTrigger = apply;
|
||||
}
|
||||
|
||||
void Aura::HandlePeriodicTriggerSpellWithValue(bool apply, bool Real)
|
||||
{
|
||||
m_isPeriodic = apply;
|
||||
}
|
||||
|
||||
void Aura::HandlePeriodicEnergize(bool apply, bool Real)
|
||||
{
|
||||
if (m_periodicTimer <= 0)
|
||||
m_periodicTimer += m_modifier.periodictime;
|
||||
if (!Real)
|
||||
return;
|
||||
|
||||
m_isPeriodic = apply;
|
||||
|
||||
// Replenishment (0.25% from max)
|
||||
// Infinite Replenishment
|
||||
if (GetId() == 57669 ||
|
||||
GetId() == 61782)
|
||||
m_modifier.m_amount = m_target->GetMaxPower(POWER_MANA) * 25 / 10000;
|
||||
}
|
||||
|
||||
void Aura::HandleAuraPowerBurn(bool apply, bool Real)
|
||||
{
|
||||
m_isPeriodic = apply;
|
||||
}
|
||||
|
||||
void Aura::HandleAuraPeriodicDummy(bool apply, bool Real)
|
||||
{
|
||||
// spells required only Real aura add/remove
|
||||
if(!Real)
|
||||
return;
|
||||
|
||||
// For prevent double apply bonuses
|
||||
bool loading = (m_target->GetTypeId() == TYPEID_PLAYER && ((Player*)m_target)->GetSession()->PlayerLoading());
|
||||
|
||||
Unit* caster = GetCaster();
|
||||
|
||||
SpellEntry const*spell = GetSpellProto();
|
||||
switch( spell->SpellFamilyName)
|
||||
{
|
||||
case SPELLFAMILY_ROGUE:
|
||||
{
|
||||
// Master of Subtlety
|
||||
if (spell->Id==31666 && !apply)
|
||||
{
|
||||
m_target->RemoveAurasDueToSpell(31665);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_HUNTER:
|
||||
{
|
||||
// Explosive Shot
|
||||
if (apply && !loading && caster)
|
||||
m_modifier.m_amount +=caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 8 / 100;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_isPeriodic = apply;
|
||||
}
|
||||
|
||||
void Aura::HandlePeriodicHeal(bool apply, bool Real)
|
||||
{
|
||||
if (m_periodicTimer <= 0)
|
||||
m_periodicTimer += m_modifier.periodictime;
|
||||
|
||||
m_isPeriodic = apply;
|
||||
|
||||
// For prevent double apply bonuses
|
||||
|
|
@ -4129,18 +4112,17 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)
|
|||
if(!Real)
|
||||
return;
|
||||
|
||||
if (m_periodicTimer <= 0)
|
||||
m_periodicTimer += m_modifier.periodictime;
|
||||
|
||||
m_isPeriodic = apply;
|
||||
|
||||
// For prevent double apply bonuses
|
||||
bool loading = (m_target->GetTypeId() == TYPEID_PLAYER && ((Player*)m_target)->GetSession()->PlayerLoading());
|
||||
|
||||
Unit *caster = GetCaster();
|
||||
|
||||
// Custom damage calculation after
|
||||
if (!apply || loading || !caster)
|
||||
if (!apply || loading)
|
||||
return;
|
||||
|
||||
Unit *caster = GetCaster();
|
||||
if (!caster)
|
||||
return;
|
||||
|
||||
switch (m_spellProto->SpellFamilyName)
|
||||
|
|
@ -4315,25 +4297,21 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)
|
|||
|
||||
void Aura::HandlePeriodicDamagePCT(bool apply, bool Real)
|
||||
{
|
||||
if (m_periodicTimer <= 0)
|
||||
m_periodicTimer += m_modifier.periodictime;
|
||||
|
||||
m_isPeriodic = apply;
|
||||
}
|
||||
|
||||
void Aura::HandlePeriodicLeech(bool apply, bool Real)
|
||||
{
|
||||
if (m_periodicTimer <= 0)
|
||||
m_periodicTimer += m_modifier.periodictime;
|
||||
|
||||
m_isPeriodic = apply;
|
||||
}
|
||||
|
||||
void Aura::HandlePeriodicManaLeech(bool apply, bool Real)
|
||||
{
|
||||
if (m_periodicTimer <= 0)
|
||||
m_periodicTimer += m_modifier.periodictime;
|
||||
m_isPeriodic = apply;
|
||||
}
|
||||
|
||||
void Aura::HandlePeriodicHealthFunnel(bool apply, bool Real)
|
||||
{
|
||||
m_isPeriodic = apply;
|
||||
}
|
||||
|
||||
|
|
@ -4578,117 +4556,47 @@ void Aura::HandleAuraModResistenceOfStatPercent(bool /*apply*/, bool Real)
|
|||
/********************************/
|
||||
void Aura::HandleAuraModTotalHealthPercentRegen(bool apply, bool Real)
|
||||
{
|
||||
/*
|
||||
Need additional checking for auras who reduce or increase healing, magic effect like Dumpen Magic,
|
||||
so this aura not fully working.
|
||||
*/
|
||||
if(apply)
|
||||
{
|
||||
if(!m_target->isAlive())
|
||||
return;
|
||||
|
||||
if((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && !m_target->IsSitState())
|
||||
m_target->SetStandState(PLAYER_STATE_SIT);
|
||||
|
||||
if(m_periodicTimer <= 0)
|
||||
{
|
||||
m_periodicTimer += m_modifier.periodictime;
|
||||
|
||||
if(m_target->GetHealth() < m_target->GetMaxHealth())
|
||||
{
|
||||
// PeriodicTick can cast triggered spells with stats changes
|
||||
PeriodicTick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_isPeriodic = apply;
|
||||
}
|
||||
|
||||
void Aura::HandleAuraModTotalManaPercentRegen(bool apply, bool Real)
|
||||
{
|
||||
if((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && apply && !m_target->IsSitState())
|
||||
m_target->SetStandState(PLAYER_STATE_SIT);
|
||||
if(apply)
|
||||
{
|
||||
if(m_modifier.periodictime == 0)
|
||||
m_modifier.periodictime = 1000;
|
||||
if(m_periodicTimer <= 0 && m_target->getPowerType() == POWER_MANA)
|
||||
{
|
||||
m_periodicTimer += m_modifier.periodictime;
|
||||
|
||||
if(m_target->GetPower(POWER_MANA) < m_target->GetMaxPower(POWER_MANA))
|
||||
{
|
||||
// PeriodicTick can cast triggered spells with stats changes
|
||||
PeriodicTick();
|
||||
}
|
||||
}
|
||||
}
|
||||
if(m_modifier.periodictime == 0)
|
||||
m_modifier.periodictime = 1000;
|
||||
|
||||
m_periodicTimer = m_modifier.periodictime;
|
||||
m_isPeriodic = apply;
|
||||
}
|
||||
|
||||
void Aura::HandleModRegen(bool apply, bool Real) // eating
|
||||
{
|
||||
if(apply)
|
||||
{
|
||||
if(!m_target->isAlive())
|
||||
return;
|
||||
|
||||
if ((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && !m_target->IsSitState())
|
||||
m_target->SetStandState(PLAYER_STATE_SIT);
|
||||
|
||||
if(m_periodicTimer <= 0)
|
||||
{
|
||||
m_periodicTimer += 5000;
|
||||
int32 gain = m_target->ModifyHealth(m_modifier.m_amount);
|
||||
Unit *caster = GetCaster();
|
||||
if (caster)
|
||||
{
|
||||
SpellEntry const *spellProto = GetSpellProto();
|
||||
if (spellProto)
|
||||
m_target->getHostilRefManager().threatAssist(caster, float(gain) * 0.5f, spellProto);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(m_modifier.periodictime == 0)
|
||||
m_modifier.periodictime = 5000;
|
||||
|
||||
m_periodicTimer = 5000;
|
||||
m_isPeriodic = apply;
|
||||
}
|
||||
|
||||
void Aura::HandleModPowerRegen(bool apply, bool Real) // drinking
|
||||
{
|
||||
if ((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && apply && !m_target->IsSitState())
|
||||
m_target->SetStandState(PLAYER_STATE_SIT);
|
||||
if (!Real)
|
||||
return;
|
||||
|
||||
if(apply && m_periodicTimer <= 0)
|
||||
Powers pt = m_target->getPowerType();
|
||||
if(m_modifier.periodictime == 0)
|
||||
{
|
||||
m_periodicTimer += 2000;
|
||||
|
||||
Powers pt = m_target->getPowerType();
|
||||
if(int32(pt) != m_modifier.m_miscvalue)
|
||||
return;
|
||||
|
||||
if ( GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED )
|
||||
{
|
||||
// eating anim
|
||||
m_target->HandleEmoteCommand(EMOTE_ONESHOT_EAT);
|
||||
}
|
||||
else if( GetId() == 20577 )
|
||||
{
|
||||
// cannibalize anim
|
||||
m_target->HandleEmoteCommand(EMOTE_STATE_CANNIBALIZE);
|
||||
}
|
||||
|
||||
// Warrior talent, gain 1 rage every 3 seconds while in combat
|
||||
if(pt == POWER_RAGE && m_target->isInCombat())
|
||||
{
|
||||
m_target->ModifyPower(pt, m_modifier.m_amount*10/17);
|
||||
m_periodicTimer += 1000;
|
||||
}
|
||||
if (pt == POWER_RAGE)
|
||||
m_modifier.periodictime = 1000;
|
||||
else
|
||||
m_modifier.periodictime = 2000;
|
||||
}
|
||||
m_isPeriodic = apply;
|
||||
if (Real && m_target->GetTypeId() == TYPEID_PLAYER && m_modifier.m_miscvalue == POWER_MANA)
|
||||
|
||||
m_periodicTimer = 5000;
|
||||
|
||||
if (m_target->GetTypeId() == TYPEID_PLAYER && m_modifier.m_miscvalue == POWER_MANA)
|
||||
((Player*)m_target)->UpdateManaRegen();
|
||||
|
||||
m_isPeriodic = apply;
|
||||
}
|
||||
|
||||
void Aura::HandleModPowerRegenPCT(bool /*apply*/, bool Real)
|
||||
|
|
@ -5263,6 +5171,7 @@ void Aura::HandleShapeshiftBoosts(bool apply)
|
|||
break;
|
||||
case FORM_TREE:
|
||||
spellId = 5420;
|
||||
spellId2 = 34123;
|
||||
break;
|
||||
case FORM_TRAVEL:
|
||||
spellId = 5419;
|
||||
|
|
@ -5603,14 +5512,6 @@ void Aura::CleanupTriggeredSpells()
|
|||
m_target->RemoveAurasDueToSpell(tSpellId);
|
||||
}
|
||||
|
||||
void Aura::HandleAuraPowerBurn(bool apply, bool Real)
|
||||
{
|
||||
if (m_periodicTimer <= 0)
|
||||
m_periodicTimer += m_modifier.periodictime;
|
||||
|
||||
m_isPeriodic = apply;
|
||||
}
|
||||
|
||||
void Aura::HandleSchoolAbsorb(bool apply, bool Real)
|
||||
{
|
||||
if(!Real)
|
||||
|
|
@ -5792,6 +5693,7 @@ void Aura::PeriodicTick()
|
|||
break;
|
||||
}
|
||||
case SPELL_AURA_PERIODIC_LEECH:
|
||||
case SPELL_AURA_PERIODIC_HEALTH_FUNNEL:
|
||||
{
|
||||
Unit *pCaster = GetCaster();
|
||||
if(!pCaster)
|
||||
|
|
@ -5804,7 +5706,7 @@ void Aura::PeriodicTick()
|
|||
pCaster->SpellHitResult(m_target,GetSpellProto(),false)!=SPELL_MISS_NONE)
|
||||
return;
|
||||
|
||||
// Check for immune (not use charges)
|
||||
// Check for immune
|
||||
if(m_target->IsImmunedToDamage(GetSpellSchoolMask(GetSpellProto())))
|
||||
return;
|
||||
|
||||
|
|
@ -6188,12 +6090,51 @@ void Aura::PeriodicTick()
|
|||
pCaster->DealSpellDamage(&damageInfo, true);
|
||||
break;
|
||||
}
|
||||
case SPELL_AURA_MOD_REGEN:
|
||||
{
|
||||
int32 gain = m_target->ModifyHealth(m_modifier.m_amount);
|
||||
if (Unit *caster = GetCaster())
|
||||
m_target->getHostilRefManager().threatAssist(caster, float(gain) * 0.5f, GetSpellProto());
|
||||
break;
|
||||
}
|
||||
case SPELL_AURA_MOD_POWER_REGEN:
|
||||
{
|
||||
Powers pt = m_target->getPowerType();
|
||||
if(int32(pt) != m_modifier.m_miscvalue)
|
||||
return;
|
||||
|
||||
if ( GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED )
|
||||
{
|
||||
// eating anim
|
||||
m_target->HandleEmoteCommand(EMOTE_ONESHOT_EAT);
|
||||
}
|
||||
else if( GetId() == 20577 )
|
||||
{
|
||||
// cannibalize anim
|
||||
m_target->HandleEmoteCommand(EMOTE_STATE_CANNIBALIZE);
|
||||
}
|
||||
|
||||
// Warrior talent, gain 1 rage every 3 seconds while in combat
|
||||
if(pt == POWER_RAGE && m_target->isInCombat())
|
||||
m_target->ModifyPower(pt, m_modifier.m_amount*10/17);
|
||||
break;
|
||||
}
|
||||
// Here tick dummy auras
|
||||
case SPELL_AURA_PERIODIC_DUMMY:
|
||||
{
|
||||
PeriodicDummyTick();
|
||||
break;
|
||||
}
|
||||
case SPELL_AURA_PERIODIC_TRIGGER_SPELL:
|
||||
{
|
||||
TriggerSpell();
|
||||
break;
|
||||
}
|
||||
case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE:
|
||||
{
|
||||
TriggerSpellWithValue();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -6232,47 +6173,11 @@ void Aura::PeriodicDummyTick()
|
|||
{
|
||||
if ((*i)->GetId() == GetId())
|
||||
{
|
||||
// Get tick number
|
||||
int32 tick = (m_maxduration - m_duration) / m_modifier.periodictime;
|
||||
// Default case (not on arenas)
|
||||
if (tick == 0)
|
||||
{
|
||||
(*i)->GetModifier()->m_amount = m_modifier.m_amount;
|
||||
((Player*)m_target)->UpdateManaRegen();
|
||||
// Disable continue
|
||||
m_isPeriodic = false;
|
||||
}
|
||||
return;
|
||||
//**********************************************
|
||||
// Code commended since arena patch not added
|
||||
// This feature uses only in arenas
|
||||
//**********************************************
|
||||
// Here need increase mana regen per tick (6 second rule)
|
||||
// on 0 tick - 0 (handled in 2 second)
|
||||
// on 1 tick - 166% (handled in 4 second)
|
||||
// on 2 tick - 133% (handled in 6 second)
|
||||
// Not need update after 3 tick
|
||||
/*
|
||||
if (tick > 3)
|
||||
return;
|
||||
// Apply bonus for 0 - 3 tick
|
||||
switch (tick)
|
||||
{
|
||||
case 0: // 0%
|
||||
(*i)->GetModifier()->m_amount = m_modifier.m_amount = 0;
|
||||
break;
|
||||
case 1: // 166%
|
||||
(*i)->GetModifier()->m_amount = m_modifier.m_amount * 5 / 3;
|
||||
break;
|
||||
case 2: // 133%
|
||||
(*i)->GetModifier()->m_amount = m_modifier.m_amount * 4 / 3;
|
||||
break;
|
||||
default: // 100% - normal regen
|
||||
(*i)->GetModifier()->m_amount = m_modifier.m_amount;
|
||||
break;
|
||||
}
|
||||
(*i)->GetModifier()->m_amount = m_modifier.m_amount;
|
||||
((Player*)m_target)->UpdateManaRegen();
|
||||
return;*/
|
||||
// Disable continue
|
||||
m_isPeriodic = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
|
@ -6304,29 +6209,6 @@ void Aura::PeriodicDummyTick()
|
|||
// case 33208: break;
|
||||
// // Gossip NPC Periodic - Despawn
|
||||
// case 33209: break;
|
||||
|
||||
// TODO: now its not periodic dummy - need move out from here
|
||||
// Aspect of the Viper
|
||||
case 34074:
|
||||
{
|
||||
if (m_target->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
// Should be manauser
|
||||
if (m_target->getPowerType()!=POWER_MANA)
|
||||
return;
|
||||
if (!caster)
|
||||
return;
|
||||
// Regen amount is max (100% from spell) on 21% or less mana and min on 92.5% or greater mana (20% from spell)
|
||||
int mana = m_target->GetPower(POWER_MANA);
|
||||
int max_mana = m_target->GetMaxPower(POWER_MANA);
|
||||
int32 base_regen = caster->CalculateSpellDamage(m_spellProto, m_effIndex, m_currentBasePoints, m_target);
|
||||
float regen_pct = 1.20f - 1.1f * mana / max_mana;
|
||||
if (regen_pct > 1.0f) regen_pct = 1.0f;
|
||||
else if (regen_pct < 0.2f) regen_pct = 0.2f;
|
||||
m_modifier.m_amount = int32 (base_regen * regen_pct);
|
||||
((Player*)m_target)->UpdateManaRegen();
|
||||
return;
|
||||
}
|
||||
// // Steal Weapon
|
||||
// case 36207: break;
|
||||
// // Simon Game START timer, (DND)
|
||||
|
|
@ -6552,11 +6434,13 @@ void Aura::PeriodicDummyTick()
|
|||
{
|
||||
if (!caster)
|
||||
return;
|
||||
// Skip 0 tick
|
||||
int32 damage = m_modifier.m_amount;
|
||||
// Full damage to target at 0 tick
|
||||
if (m_duration > m_modifier.periodictime)
|
||||
{
|
||||
caster->CastCustomSpell(m_target, 53352, &damage, 0, 0, true, 0, this);
|
||||
return;
|
||||
int32 damage = caster->CalculateSpellDamage(spell, GetEffIndex(), GetBasePoints(), m_target);
|
||||
damage+=caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 8 / 100;
|
||||
}
|
||||
damage/=4;
|
||||
caster->CastCustomSpell(m_target, 56298, &damage, 0, 0, true, 0, this);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ class MANGOS_DLL_SPEC Aura
|
|||
void HandleAuraModRegenInterrupt(bool Apply, bool Real);
|
||||
void HandleHaste(bool Apply, bool Real);
|
||||
void HandlePeriodicTriggerSpell(bool Apply, bool Real);
|
||||
void HandlePeriodicTriggerSpellWithValue(bool apply, bool Real);
|
||||
void HandlePeriodicEnergize(bool Apply, bool Real);
|
||||
void HandleAuraModResistanceExclusive(bool Apply, bool Real);
|
||||
void HandleAuraModPetTalentsPoints(bool Apply, bool Real);
|
||||
|
|
@ -147,6 +148,7 @@ class MANGOS_DLL_SPEC Aura
|
|||
void HandleModSpellHitChance(bool Apply, bool Real);
|
||||
void HandleAuraModScale(bool Apply, bool Real);
|
||||
void HandlePeriodicManaLeech(bool Apply, bool Real);
|
||||
void HandlePeriodicHealthFunnel(bool apply, bool Real);
|
||||
void HandleModCastingSpeed(bool Apply, bool Real);
|
||||
void HandleAuraMounted(bool Apply, bool Real);
|
||||
void HandleWaterBreathing(bool Apply, bool Real);
|
||||
|
|
@ -257,7 +259,7 @@ class MANGOS_DLL_SPEC Aura
|
|||
uint8 GetAuraLevel() const { return m_auraLevel; }
|
||||
void SetAuraLevel(uint8 level) { m_auraLevel = level; }
|
||||
uint8 GetAuraCharges() const { return m_procCharges; }
|
||||
void SetAuraCharges(uint8 charges)
|
||||
void SetAuraCharges(uint8 charges)
|
||||
{
|
||||
if (m_procCharges == charges)
|
||||
return;
|
||||
|
|
@ -265,7 +267,7 @@ class MANGOS_DLL_SPEC Aura
|
|||
SendAuraUpdate(false);
|
||||
}
|
||||
bool DropAuraCharge() // return true if last charge dropped
|
||||
{
|
||||
{
|
||||
if (m_procCharges == 0)
|
||||
return false;
|
||||
m_procCharges--;
|
||||
|
|
@ -288,7 +290,6 @@ class MANGOS_DLL_SPEC Aura
|
|||
bool IsPermanent() const { return m_permanent; }
|
||||
bool IsAreaAura() const { return m_isAreaAura; }
|
||||
bool IsPeriodic() const { return m_isPeriodic; }
|
||||
bool IsTrigger() const { return m_isTrigger; }
|
||||
bool IsPassive() const { return m_isPassive; }
|
||||
bool IsPersistent() const { return m_isPersistent; }
|
||||
bool IsDeathPersistent() const { return m_isDeathPersist; }
|
||||
|
|
@ -315,6 +316,7 @@ class MANGOS_DLL_SPEC Aura
|
|||
DiminishingGroup getDiminishGroup() const { return m_AuraDRGroup; }
|
||||
|
||||
void TriggerSpell();
|
||||
void TriggerSpellWithValue();
|
||||
void PeriodicTick();
|
||||
void PeriodicDummyTick();
|
||||
|
||||
|
|
@ -351,7 +353,6 @@ class MANGOS_DLL_SPEC Aura
|
|||
bool m_positive:1;
|
||||
bool m_permanent:1;
|
||||
bool m_isPeriodic:1;
|
||||
bool m_isTrigger:1;
|
||||
bool m_isAreaAura:1;
|
||||
bool m_isPassive:1;
|
||||
bool m_isPersistent:1;
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
|
|||
&Spell::EffectSummonPlayer, // 85 SPELL_EFFECT_SUMMON_PLAYER
|
||||
&Spell::EffectActivateObject, // 86 SPELL_EFFECT_ACTIVATE_OBJECT
|
||||
&Spell::EffectUnused, // 87 SPELL_EFFECT_WMO_DAMAGE
|
||||
&Spell::EffectUnused, // 88 SPELL_EFFECT_WMO_REPAIR
|
||||
&Spell::EffectUnused, // 88 SPELL_EFFECT_WMO_REPAIR
|
||||
&Spell::EffectUnused, // 89 SPELL_EFFECT_WMO_CHANGE
|
||||
&Spell::EffectUnused, // 90 SPELL_EFFECT_KILL_CREDIT
|
||||
&Spell::EffectUnused, // 91 SPELL_EFFECT_THREAT_ALL one spell: zzOLDBrainwash
|
||||
|
|
@ -215,9 +215,9 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
|
|||
&Spell::EffectNULL, //154 unused
|
||||
&Spell::EffectTitanGrip, //155 SPELL_EFFECT_TITAN_GRIP Allows you to equip two-handed axes, maces and swords in one hand, but you attack $49152s1% slower than normal.
|
||||
&Spell::EffectNULL, //156 Add Socket
|
||||
&Spell::EffectCreateItem, //157 SPELL_EFFECT_CREATE_ITEM_2 create/learn item/spell for profession
|
||||
&Spell::EffectMilling, //158 milling
|
||||
&Spell::EffectNULL //159 allow rename pet once again
|
||||
&Spell::EffectCreateItem, //157 SPELL_EFFECT_CREATE_ITEM_2 create/learn item/spell for profession
|
||||
&Spell::EffectMilling, //158 SPELL_EFFECT_MILLING milling
|
||||
&Spell::EffectRenamePet //159 SPELL_EFFECT_ALLOW_RENAME_PET allow rename pet once again
|
||||
};
|
||||
|
||||
void Spell::EffectNULL(uint32 /*i*/)
|
||||
|
|
@ -493,7 +493,7 @@ void Spell::EffectSchoolDMG(uint32 effect_idx)
|
|||
// Lookup for Deadly poison (only attacker applied)
|
||||
Unit::AuraList const& auras = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
|
||||
for(Unit::AuraList::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr)
|
||||
if( (*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_ROGUE &&
|
||||
if( (*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_ROGUE &&
|
||||
(*itr)->GetSpellProto()->SpellFamilyFlags & 0x10000 &&
|
||||
(*itr)->GetCasterGUID()==m_caster->GetGUID() )
|
||||
{
|
||||
|
|
@ -928,7 +928,7 @@ void Spell::EffectDummy(uint32 i)
|
|||
{
|
||||
Aura * dummy = m_caster->GetDummyAura(28734);
|
||||
if (dummy)
|
||||
{
|
||||
{
|
||||
int32 bp = damage * dummy->GetStackAmount();
|
||||
m_caster->CastCustomSpell(m_caster, 28733, &bp, NULL, NULL, true);
|
||||
m_caster->RemoveAurasDueToSpell(28734);
|
||||
|
|
@ -1265,7 +1265,7 @@ void Spell::EffectDummy(uint32 i)
|
|||
if (Aura *aura = m_caster->GetDummyAura(58367))
|
||||
rage+=aura->GetModifier()->m_amount;
|
||||
|
||||
int32 basePoints0 = damage+int32(rage * m_spellInfo->DmgMultiplier[i] +
|
||||
int32 basePoints0 = damage+int32(rage * m_spellInfo->DmgMultiplier[i] +
|
||||
m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2f);
|
||||
m_caster->CastCustomSpell(unitTarget, 20647, &basePoints0, NULL, NULL, true, 0);
|
||||
m_caster->SetPower(POWER_RAGE,0);
|
||||
|
|
@ -1288,6 +1288,12 @@ void Spell::EffectDummy(uint32 i)
|
|||
m_caster->CastCustomSpell(m_caster, 12976, &healthModSpellBasePoints0, NULL, NULL, true, NULL);
|
||||
return;
|
||||
}
|
||||
// Bloodthirst
|
||||
case 23881:
|
||||
{
|
||||
m_caster->CastCustomSpell(unitTarget, 23885, &damage, NULL, NULL, true, NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SPELLFAMILY_WARLOCK:
|
||||
|
|
@ -1398,16 +1404,6 @@ void Spell::EffectDummy(uint32 i)
|
|||
}
|
||||
break;
|
||||
case SPELLFAMILY_DRUID:
|
||||
switch(m_spellInfo->Id )
|
||||
{
|
||||
case 5420: // Tree of Life passive
|
||||
{
|
||||
// Tree of Life area effect
|
||||
int32 health_mod = int32(m_caster->GetStat(STAT_SPIRIT)/4);
|
||||
m_caster->CastCustomSpell(m_caster,34123,&health_mod,NULL,NULL,true,NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SPELLFAMILY_ROGUE:
|
||||
switch(m_spellInfo->Id )
|
||||
|
|
@ -1754,7 +1750,7 @@ void Spell::EffectDummy(uint32 i)
|
|||
Unit::AuraList const& auraDummy = m_caster->GetAurasByType(SPELL_AURA_DUMMY);
|
||||
for(Unit::AuraList::const_iterator itr = auraDummy.begin(); itr != auraDummy.end(); ++itr)
|
||||
{
|
||||
if( (*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_SHAMAN &&
|
||||
if( (*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_SHAMAN &&
|
||||
(*itr)->GetSpellProto()->SpellFamilyFlags & 0x0000000000200000LL &&
|
||||
(*itr)->GetCastItemGUID() == item->GetGUID())
|
||||
{
|
||||
|
|
@ -2218,7 +2214,7 @@ void Spell::EffectApplyAura(uint32 i)
|
|||
(unitTarget->GetTypeId()!=TYPEID_PLAYER || !((Player*)unitTarget)->GetSession()->PlayerLoading()) )
|
||||
return;
|
||||
|
||||
Unit* caster = m_originalCasterGUID ? m_originalCaster : m_caster;
|
||||
Unit* caster = m_originalCaster ? m_originalCaster : m_caster;
|
||||
if(!caster)
|
||||
return;
|
||||
|
||||
|
|
@ -3345,7 +3341,7 @@ void Spell::EffectLearnSpell(uint32 i)
|
|||
Player *player = (Player*)unitTarget;
|
||||
|
||||
uint32 spellToLearn = ((m_spellInfo->Id==SPELL_ID_GENERIC_LEARN) || (m_spellInfo->Id==SPELL_ID_GENERIC_LEARN_PET)) ? damage : m_spellInfo->EffectTriggerSpell[i];
|
||||
player->learnSpell(spellToLearn);
|
||||
player->learnSpell(spellToLearn,false);
|
||||
|
||||
sLog.outDebug( "Spell: Player %u have learned spell %u from NpcGUID=%u", player->GetGUIDLow(), spellToLearn, m_caster->GetGUIDLow() );
|
||||
}
|
||||
|
|
@ -4285,8 +4281,8 @@ void Spell::EffectWeaponDmg(uint32 i)
|
|||
for(Unit::AuraMap::iterator itr = suAuras.begin(); itr != suAuras.end(); ++itr)
|
||||
{
|
||||
SpellEntry const *spellInfo = (*itr).second->GetSpellProto();
|
||||
if( spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR &&
|
||||
spellInfo->SpellFamilyFlags & 0x0000000000004000LL &&
|
||||
if( spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR &&
|
||||
spellInfo->SpellFamilyFlags & 0x0000000000004000LL &&
|
||||
(*itr).second->GetCasterGUID() == m_caster->GetGUID())
|
||||
{
|
||||
(*itr).second->RefreshAura();
|
||||
|
|
@ -4866,7 +4862,7 @@ void Spell::EffectScriptEffect(uint32 effIndex)
|
|||
|
||||
// learn random explicit discovery recipe (if any)
|
||||
if(uint32 discoveredSpell = GetExplicitDiscoverySpell(m_spellInfo->Id, player))
|
||||
player->learnSpell(discoveredSpell);
|
||||
player->learnSpell(discoveredSpell,false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -5926,6 +5922,12 @@ void Spell::EffectSendTaxi(uint32 i)
|
|||
case 34905: //Stealth Flight
|
||||
mountid = 6851;
|
||||
break;
|
||||
case 45883: //Amber Ledge to Beryl Point
|
||||
mountid = 23524;
|
||||
break;
|
||||
case 46064: //Amber Ledge to Coldarra
|
||||
mountid = 6371;
|
||||
break;
|
||||
case 53335: //Stormwind Harbor Flight - Peaceful
|
||||
mountid = 6852;
|
||||
break;
|
||||
|
|
@ -6426,7 +6428,7 @@ void Spell::EffectQuestFail(uint32 i)
|
|||
((Player*)unitTarget)->FailQuest(m_spellInfo->EffectMiscValue[i]);
|
||||
}
|
||||
|
||||
void Spell::EffectActivateRune(uint32 i)
|
||||
void Spell::EffectActivateRune(uint32 eff_idx)
|
||||
{
|
||||
if(m_caster->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
|
@ -6438,15 +6440,24 @@ void Spell::EffectActivateRune(uint32 i)
|
|||
|
||||
for(uint32 j = 0; j < MAX_RUNES; ++j)
|
||||
{
|
||||
if(plr->GetRuneCooldown(j) && plr->GetCurrentRune(j) == m_spellInfo->EffectMiscValue[i])
|
||||
if(plr->GetRuneCooldown(j) && plr->GetCurrentRune(j) == m_spellInfo->EffectMiscValue[eff_idx])
|
||||
{
|
||||
plr->SetRuneCooldown(j, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Spell::EffectTitanGrip(uint32 i)
|
||||
void Spell::EffectTitanGrip(uint32 /*eff_idx*/)
|
||||
{
|
||||
if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)unitTarget)->SetCanTitanGrip(true);
|
||||
}
|
||||
|
||||
void Spell::EffectRenamePet(uint32 /*eff_idx*/)
|
||||
{
|
||||
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT ||
|
||||
!((Creature*)unitTarget)->isPet() || ((Pet*)unitTarget)->getPetType() != HUNTER_PET)
|
||||
return;
|
||||
|
||||
unitTarget->SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_ALLOWED);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -261,8 +261,8 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
|
|||
return;
|
||||
}
|
||||
|
||||
// not have spell or spell passive and not casted by client
|
||||
if ( !_player->HasSpell (spellId) || IsPassiveSpell(spellId) )
|
||||
// not have spell in spellbook or spell passive and not casted by client
|
||||
if ( !_player->HasActiveSpell (spellId) || IsPassiveSpell(spellId) )
|
||||
{
|
||||
//cheater? kick? ban?
|
||||
return;
|
||||
|
|
@ -357,7 +357,7 @@ void WorldSession::HandlePetCancelAuraOpcode( WorldPacket& recvPacket)
|
|||
return;
|
||||
}
|
||||
|
||||
Creature* pet=ObjectAccessor::GetCreatureOrPet(*_player,guid);
|
||||
Creature* pet=ObjectAccessor::GetCreatureOrPetOrVehicle(*_player,guid);
|
||||
|
||||
if(!pet)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ SpellSpecific GetSpellSpecific(uint32 spellId)
|
|||
// only hunter aspects have this (but not all aspects in hunter family)
|
||||
if( spellInfo->SpellFamilyFlags & 0x0044000000380000LL || spellInfo->SpellFamilyFlags2 & 0x00003010)
|
||||
return SPELL_ASPECT;
|
||||
|
||||
|
||||
if( spellInfo->SpellFamilyFlags2 & 0x00000002 )
|
||||
return SPELL_TRACKER;
|
||||
|
||||
|
|
@ -273,7 +273,7 @@ bool IsPositiveTarget(uint32 targetA, uint32 targetB)
|
|||
case TARGET_CURRENT_ENEMY_COORDINATES:
|
||||
case TARGET_SINGLE_ENEMY:
|
||||
return false;
|
||||
case TARGET_ALL_AROUND_CASTER:
|
||||
case TARGET_CASTER_COORDINATES:
|
||||
return (targetB == TARGET_ALL_PARTY || targetB == TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER);
|
||||
default:
|
||||
break;
|
||||
|
|
@ -736,7 +736,7 @@ void SpellMgr::LoadSpellAffects()
|
|||
case 0: ptr = &spellInfo->EffectSpellClassMaskA[0]; break;
|
||||
case 1: ptr = &spellInfo->EffectSpellClassMaskB[0]; break;
|
||||
case 2: ptr = &spellInfo->EffectSpellClassMaskC[0]; break;
|
||||
default:
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
if(ptr[0] == affect.SpellClassMask[0] || ptr[1] == affect.SpellClassMask[1] || ptr[2] == affect.SpellClassMask[2])
|
||||
|
|
@ -776,7 +776,7 @@ void SpellMgr::LoadSpellAffects()
|
|||
case 0: ptr = &spellInfo->EffectSpellClassMaskA[0]; break;
|
||||
case 1: ptr = &spellInfo->EffectSpellClassMaskB[0]; break;
|
||||
case 2: ptr = &spellInfo->EffectSpellClassMaskC[0]; break;
|
||||
default:
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
if(ptr[0] || ptr[1] || ptr[2])
|
||||
|
|
@ -1016,28 +1016,38 @@ bool SpellMgr::IsRankSpellDueToSpell(SpellEntry const *spellInfo_1,uint32 spellI
|
|||
|
||||
bool SpellMgr::canStackSpellRanks(SpellEntry const *spellInfo)
|
||||
{
|
||||
if(IsPassiveSpell(spellInfo->Id)) // ranked passive spell
|
||||
return false;
|
||||
if(spellInfo->powerType != POWER_MANA && spellInfo->powerType != POWER_HEALTH)
|
||||
return false;
|
||||
if(IsProfessionOrRidingSpell(spellInfo->Id))
|
||||
return false;
|
||||
|
||||
if(spellmgr.IsSkillBonusSpell(spellInfo->Id))
|
||||
return false;
|
||||
|
||||
// All stance spells. if any better way, change it.
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
// Paladin aura Spell
|
||||
if(spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN
|
||||
&& spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AREA_AURA_RAID)
|
||||
return false;
|
||||
// Druid form Spell
|
||||
if(spellInfo->SpellFamilyName == SPELLFAMILY_DRUID
|
||||
&& spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AURA
|
||||
&& spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT)
|
||||
return false;
|
||||
// Rogue Stealth
|
||||
if(spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE
|
||||
&& spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AURA
|
||||
&& spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT)
|
||||
return false;
|
||||
switch(spellInfo->SpellFamilyName)
|
||||
{
|
||||
case SPELLFAMILY_PALADIN:
|
||||
// Paladin aura Spell
|
||||
if (spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AREA_AURA_RAID)
|
||||
return false;
|
||||
break;
|
||||
case SPELLFAMILY_DRUID:
|
||||
// Druid form Spell
|
||||
if (spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AURA &&
|
||||
spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT)
|
||||
return false;
|
||||
break;
|
||||
case SPELLFAMILY_ROGUE:
|
||||
// Rogue Stealth
|
||||
if (spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AURA &&
|
||||
spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1450,6 +1460,24 @@ bool SpellMgr::IsPrimaryProfessionFirstRankSpell(uint32 spellId) const
|
|||
return IsPrimaryProfessionSpell(spellId) && GetSpellRank(spellId)==1;
|
||||
}
|
||||
|
||||
bool SpellMgr::IsSkillBonusSpell(uint32 spellId) const
|
||||
{
|
||||
SkillLineAbilityMap::const_iterator lower = GetBeginSkillLineAbilityMap(spellId);
|
||||
SkillLineAbilityMap::const_iterator upper = GetEndSkillLineAbilityMap(spellId);
|
||||
|
||||
for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
|
||||
{
|
||||
SkillLineAbilityEntry const *pAbility = _spell_idx->second;
|
||||
if (!pAbility || pAbility->learnOnGetSkill != ABILITY_LEARNED_ON_GET_PROFESSION_SKILL)
|
||||
continue;
|
||||
|
||||
if(pAbility->req_skill_value > 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
SpellEntry const* SpellMgr::SelectAuraRankForPlayerLevel(SpellEntry const* spellInfo, uint32 playerLevel) const
|
||||
{
|
||||
// ignore passive spells
|
||||
|
|
@ -1667,8 +1695,10 @@ void SpellMgr::LoadSpellLearnSkills()
|
|||
|
||||
// search auto-learned skills and add its to map also for use in unlearn spells/talents
|
||||
uint32 dbc_count = 0;
|
||||
barGoLink bar( sSpellStore.GetNumRows() );
|
||||
for(uint32 spell = 0; spell < sSpellStore.GetNumRows(); ++spell)
|
||||
{
|
||||
bar.step();
|
||||
SpellEntry const* entry = sSpellStore.LookupEntry(spell);
|
||||
|
||||
if(!entry)
|
||||
|
|
@ -2358,10 +2388,12 @@ void SpellMgr::LoadSkillLineAbilityMap()
|
|||
{
|
||||
mSkillLineAbilityMap.clear();
|
||||
|
||||
barGoLink bar( sSkillLineAbilityStore.GetNumRows() );
|
||||
uint32 count = 0;
|
||||
|
||||
for (uint32 i = 0; i < sSkillLineAbilityStore.GetNumRows(); i++)
|
||||
{
|
||||
bar.step();
|
||||
SkillLineAbilityEntry const *SkillInfo = sSkillLineAbilityStore.LookupEntry(i);
|
||||
if(!SkillInfo)
|
||||
continue;
|
||||
|
|
@ -2371,7 +2403,7 @@ void SpellMgr::LoadSkillLineAbilityMap()
|
|||
}
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded %u SkillLineAbility MultiMap", count);
|
||||
sLog.outString(">> Loaded %u SkillLineAbility MultiMap Data", count);
|
||||
}
|
||||
|
||||
DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto, bool triggered)
|
||||
|
|
|
|||
|
|
@ -367,7 +367,6 @@ inline bool IsAreaEffectTarget( Targets target )
|
|||
case TARGET_ALL_ENEMY_IN_AREA:
|
||||
case TARGET_ALL_ENEMY_IN_AREA_INSTANT:
|
||||
case TARGET_ALL_PARTY_AROUND_CASTER:
|
||||
case TARGET_ALL_AROUND_CASTER:
|
||||
case TARGET_IN_FRONT_OF_CASTER:
|
||||
case TARGET_ALL_ENEMY_IN_AREA_CHANNELED:
|
||||
case TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER:
|
||||
|
|
@ -898,6 +897,9 @@ class SpellMgr
|
|||
static bool IsPrimaryProfessionSpell(uint32 spellId);
|
||||
bool IsPrimaryProfessionFirstRankSpell(uint32 spellId) const;
|
||||
|
||||
bool IsSkillBonusSpell(uint32 spellId) const;
|
||||
|
||||
|
||||
// Spell script targets
|
||||
SpellScriptTarget::const_iterator GetBeginSpellScriptTarget(uint32 spell_id) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1090,8 +1090,21 @@ void Unit::CalculateSpellDamage(SpellNonMeleeDamage *damageInfo, int32 damage, S
|
|||
// Calculate absorb resist
|
||||
if(damage > 0)
|
||||
{
|
||||
CalcAbsorbResist(pVictim, damageSchoolMask, SPELL_DIRECT_DAMAGE, damage, &damageInfo->absorb, &damageInfo->resist);
|
||||
damage-= damageInfo->absorb + damageInfo->resist;
|
||||
// lookup absorb/resist ignore auras on caster for spell
|
||||
bool ignore = false;
|
||||
Unit::AuraList const& ignoreAbsorb = GetAurasByType(SPELL_AURA_MOD_IGNORE_ABSORB_FOR_SPELL);
|
||||
for(Unit::AuraList::const_iterator i = ignoreAbsorb.begin(); i != ignoreAbsorb.end(); ++i)
|
||||
if ((*i)->isAffectedOnSpell(spellInfo))
|
||||
{
|
||||
ignore = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ignore)
|
||||
{
|
||||
CalcAbsorbResist(pVictim, damageSchoolMask, SPELL_DIRECT_DAMAGE, damage, &damageInfo->absorb, &damageInfo->resist);
|
||||
damage-= damageInfo->absorb + damageInfo->resist;
|
||||
}
|
||||
}
|
||||
else
|
||||
damage = 0;
|
||||
|
|
@ -1820,7 +1833,7 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
|
|||
// Remove all expired absorb auras
|
||||
if (existExpired)
|
||||
{
|
||||
for(AuraList::const_iterator i = vSchoolAbsorb.begin(), next; i != vSchoolAbsorb.end();)
|
||||
for(AuraList::const_iterator i = vSchoolAbsorb.begin(); i != vSchoolAbsorb.end();)
|
||||
{
|
||||
if ((*i)->GetModifier()->m_amount<=0)
|
||||
{
|
||||
|
|
@ -2386,7 +2399,7 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell)
|
|||
// Can`t dodge from behind in PvP (but its possible in PvE)
|
||||
if (GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER)
|
||||
canDodge = false;
|
||||
// Can`t parry
|
||||
// Can`t parry
|
||||
canParry = false;
|
||||
}
|
||||
// Check creatures flags_extra for disable parry
|
||||
|
|
@ -4731,7 +4744,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
|
|||
for(AuraMap::iterator iter = Auras.begin(); iter != Auras.end();)
|
||||
{
|
||||
SpellEntry const *spell = iter->second->GetSpellProto();
|
||||
if( spell->Mechanic == MECHANIC_STUN ||
|
||||
if( spell->Mechanic == MECHANIC_STUN ||
|
||||
spell->EffectMechanic[iter->second->GetEffIndex()] == MECHANIC_STUN)
|
||||
{
|
||||
pVictim->RemoveAurasDueToSpell(spell->Id);
|
||||
|
|
@ -5294,7 +5307,9 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
|
|||
// Rapid Recuperation
|
||||
if ( dummySpell->SpellIconID == 3560 )
|
||||
{
|
||||
// mane regen from Rapid Killing
|
||||
// This effect only from Rapid Killing (mana regen)
|
||||
if (!(procSpell->SpellFamilyFlags & 0x0100000000000000LL))
|
||||
return false;
|
||||
triggered_spell_id = 56654;
|
||||
target = this;
|
||||
break;
|
||||
|
|
@ -5320,6 +5335,22 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
|
|||
target = this;
|
||||
break;
|
||||
}
|
||||
// Righteous Vengeance
|
||||
if (dummySpell->SpellIconID == 3025)
|
||||
{
|
||||
// 4 damage tick
|
||||
basepoints0 = triggeredByAura->GetModifier()->m_amount*damage/400;
|
||||
triggered_spell_id = 61840;
|
||||
break;
|
||||
}
|
||||
// Sheath of Light
|
||||
if (dummySpell->SpellIconID == 3030)
|
||||
{
|
||||
// 4 healing tick
|
||||
basepoints0 = triggeredByAura->GetModifier()->m_amount*damage/400;
|
||||
triggered_spell_id = 54203;
|
||||
break;
|
||||
}
|
||||
switch(dummySpell->Id)
|
||||
{
|
||||
// Judgement of Light
|
||||
|
|
@ -5824,7 +5855,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
|
|||
// Mark of Blood
|
||||
if (dummySpell->Id == 49005)
|
||||
{
|
||||
// TODO: need more info (cooldowns/PPM)
|
||||
// TODO: need more info (cooldowns/PPM)
|
||||
triggered_spell_id = 50424;
|
||||
break;
|
||||
}
|
||||
|
|
@ -6481,6 +6512,15 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
|
|||
return false;
|
||||
break;
|
||||
}
|
||||
// Rapid Recuperation
|
||||
case 53228:
|
||||
case 53232:
|
||||
{
|
||||
// This effect only from Rapid Fire (ability cast)
|
||||
if (!(procSpell->SpellFamilyFlags & 0x0000000000000020LL))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Costum basepoints/target for exist spell
|
||||
|
|
@ -6510,11 +6550,16 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
|
|||
// Need add combopoint AFTER finish movie (or they dropped in finish phase)
|
||||
break;
|
||||
}
|
||||
// Bloodthirst (($m/100)% of max health)
|
||||
case 23880:
|
||||
{
|
||||
basepoints0 = int32(GetMaxHealth() * triggerAmount / 10000);
|
||||
break;
|
||||
}
|
||||
// Shamanistic Rage triggered spell
|
||||
case 30824:
|
||||
{
|
||||
basepoints0 = int32(GetTotalAttackPowerValue(BASE_ATTACK) * triggerAmount / 100);
|
||||
trigger_spell_id = 30824;
|
||||
break;
|
||||
}
|
||||
// Enlightenment (trigger only from mana cost spells)
|
||||
|
|
@ -7474,6 +7519,16 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
|
|||
if( (*i)->GetCasterGUID() == GetGUID() && (*i)->isAffectedOnSpell(spellProto))
|
||||
TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
|
||||
|
||||
// Mod damage from spell mechanic
|
||||
uint32 mechanicMask = GetAllSpellMechanicMask(spellProto);
|
||||
if (mechanicMask)
|
||||
{
|
||||
AuraList const& mDamageDoneMechanic = pVictim->GetAurasByType(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT);
|
||||
for(AuraList::const_iterator i = mDamageDoneMechanic.begin();i != mDamageDoneMechanic.end(); ++i)
|
||||
if(mechanicMask & uint32(1<<((*i)->GetModifier()->m_miscvalue)))
|
||||
TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
|
||||
}
|
||||
|
||||
// Distribute Damage over multiple effects, reduce by AoE
|
||||
CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime );
|
||||
|
||||
|
|
@ -7819,7 +7874,7 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM
|
|||
}
|
||||
// Glyph of Shadowburn
|
||||
if (spellProto->SpellFamilyName == SPELLFAMILY_WARLOCK &&
|
||||
spellProto->SpellFamilyFlags & 0x0000000000000080LL &&
|
||||
spellProto->SpellFamilyFlags & 0x0000000000000080LL &&
|
||||
pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT))
|
||||
{
|
||||
AuraList const& mOverrideClassScript = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
|
||||
|
|
@ -8204,6 +8259,13 @@ bool Unit::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) con
|
|||
for(SpellImmuneList::const_iterator itr = list.begin(); itr != list.end(); ++itr)
|
||||
if(itr->type == aura)
|
||||
return true;
|
||||
// Check for immune to application of harmful magical effects
|
||||
AuraList const& immuneAuraApply = GetAurasByType(SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL);
|
||||
for(AuraList::const_iterator iter = immuneAuraApply.begin(); iter != immuneAuraApply.end(); ++iter)
|
||||
if (spellInfo->Dispel == DISPEL_MAGIC && // Magic debuff
|
||||
((*iter)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellInfo)) && // Check school
|
||||
!IsPositiveEffect(spellInfo->Id, index)) // Harmful
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
@ -9292,6 +9354,8 @@ bool Unit::SelectHostilTarget()
|
|||
|
||||
assert(GetTypeId()== TYPEID_UNIT);
|
||||
|
||||
if (!this->isAlive())
|
||||
return false;
|
||||
//This function only useful once AI has been initialized
|
||||
if (!((Creature*)this)->AI())
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -650,7 +650,7 @@ struct UnitActionBarEntry
|
|||
|
||||
union
|
||||
{
|
||||
struct
|
||||
struct
|
||||
{
|
||||
uint16 SpellOrAction;
|
||||
uint16 Type;
|
||||
|
|
|
|||
|
|
@ -57,97 +57,105 @@ void WaypointManager::Load()
|
|||
uint32 total_behaviors = 0;
|
||||
|
||||
QueryResult *result = WorldDatabase.Query("SELECT id, COUNT(point) FROM creature_movement GROUP BY id");
|
||||
if(result)
|
||||
|
||||
if(!result)
|
||||
{
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Loaded 0 paths. DB table `creature_movement` is empty." );
|
||||
return;
|
||||
} else {
|
||||
total_paths = result->GetRowCount();
|
||||
barGoLink bar( total_paths );
|
||||
do
|
||||
{
|
||||
bar.step();
|
||||
Field *fields = result->Fetch();
|
||||
uint32 id = fields[0].GetUInt32();
|
||||
uint32 count = fields[1].GetUInt32();
|
||||
m_pathMap[id].resize(count);
|
||||
|
||||
total_nodes += count;
|
||||
bar.step();
|
||||
} while( result->NextRow() );
|
||||
delete result;
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Paths loaded" );
|
||||
}
|
||||
|
||||
result = WorldDatabase.Query("SELECT position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, id, point FROM creature_movement");
|
||||
if(result)
|
||||
|
||||
barGoLink bar( result->GetRowCount() );
|
||||
do
|
||||
{
|
||||
barGoLink bar( result->GetRowCount() );
|
||||
do
|
||||
bar.step();
|
||||
Field *fields = result->Fetch();
|
||||
uint32 point = fields[15].GetUInt32();
|
||||
uint32 id = fields[14].GetUInt32();
|
||||
WaypointPath &path = m_pathMap[id];
|
||||
// the cleanup queries make sure the following is true
|
||||
assert(point >= 1 && point <= path.size());
|
||||
WaypointNode &node = path[point-1];
|
||||
|
||||
node.x = fields[0].GetFloat();
|
||||
node.y = fields[1].GetFloat();
|
||||
node.z = fields[2].GetFloat();
|
||||
node.orientation = fields[3].GetFloat();
|
||||
node.delay = fields[6].GetUInt16();
|
||||
|
||||
// prevent using invalid coordinates
|
||||
if(!MaNGOS::IsValidMapCoord(node.x, node.y, node.z, node.orientation))
|
||||
{
|
||||
Field *fields = result->Fetch();
|
||||
uint32 point = fields[15].GetUInt32();
|
||||
uint32 id = fields[14].GetUInt32();
|
||||
|
||||
WaypointPath &path = m_pathMap[id];
|
||||
// the cleanup queries make sure the following is true
|
||||
assert(point >= 1 && point <= path.size());
|
||||
WaypointNode &node = path[point-1];
|
||||
|
||||
node.x = fields[0].GetFloat();
|
||||
node.y = fields[1].GetFloat();
|
||||
node.z = fields[2].GetFloat();
|
||||
node.orientation = fields[3].GetFloat();
|
||||
node.delay = fields[6].GetUInt16();
|
||||
|
||||
// prevent using invalid coordinates
|
||||
if(!MaNGOS::IsValidMapCoord(node.x, node.y, node.z, node.orientation))
|
||||
{
|
||||
QueryResult *result1 = WorldDatabase.PQuery("SELECT id, map FROM creature WHERE guid = '%u'", id);
|
||||
if(result1)
|
||||
sLog.outErrorDb("ERROR: Creature (guidlow %d, entry %d) have invalid coordinates in his waypoint %d (X: %f, Y: %f).",
|
||||
id, result1->Fetch()[0].GetUInt32(), point, node.x, node.y);
|
||||
else
|
||||
sLog.outErrorDb("ERROR: Waypoint path %d, have invalid coordinates in his waypoint %d (X: %f, Y: %f).",
|
||||
id, point, node.x, node.y);
|
||||
|
||||
MaNGOS::NormalizeMapCoord(node.x);
|
||||
MaNGOS::NormalizeMapCoord(node.y);
|
||||
if(result1)
|
||||
{
|
||||
node.z = MapManager::Instance ().GetBaseMap(result1->Fetch()[1].GetUInt32())->GetHeight(node.x, node.y, node.z);
|
||||
delete result1;
|
||||
}
|
||||
WorldDatabase.PExecute("UPDATE creature_movement SET position_x = '%f', position_y = '%f', position_z = '%f' WHERE id = '%u' AND point = '%u'", node.x, node.y, node.z, id, point);
|
||||
}
|
||||
|
||||
WaypointBehavior be;
|
||||
be.model1 = fields[4].GetUInt32();
|
||||
be.model2 = fields[5].GetUInt32();
|
||||
be.emote = fields[7].GetUInt32();
|
||||
be.spell = fields[8].GetUInt32();
|
||||
|
||||
for(int i = 0; i < MAX_WAYPOINT_TEXT; ++i)
|
||||
{
|
||||
be.textid[i] = fields[9+i].GetUInt32();
|
||||
if(be.textid[i])
|
||||
{
|
||||
if (be.textid[i] < MIN_DB_SCRIPT_STRING_ID || be.textid[i] >= MAX_DB_SCRIPT_STRING_ID)
|
||||
{
|
||||
sLog.outErrorDb( "Table `db_script_string` not have string id %u", be.textid[i]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// save memory by not storing empty behaviors
|
||||
if(!be.isEmpty())
|
||||
{
|
||||
node.behavior = new WaypointBehavior(be);
|
||||
++total_behaviors;
|
||||
}
|
||||
QueryResult *result1 = WorldDatabase.PQuery("SELECT id, map FROM creature WHERE guid = '%u'", id);
|
||||
if(result1)
|
||||
sLog.outErrorDb("ERROR: Creature (guidlow %d, entry %d) have invalid coordinates in his waypoint %d (X: %f, Y: %f).",
|
||||
id, result1->Fetch()[0].GetUInt32(), point, node.x, node.y);
|
||||
else
|
||||
node.behavior = NULL;
|
||||
bar.step();
|
||||
} while( result->NextRow() );
|
||||
delete result;
|
||||
}
|
||||
sLog.outString( ">> Loaded %u paths, %u nodes and %u behaviors", total_paths, total_nodes, total_behaviors);
|
||||
sLog.outErrorDb("ERROR: Waypoint path %d, have invalid coordinates in his waypoint %d (X: %f, Y: %f).",
|
||||
id, point, node.x, node.y);
|
||||
|
||||
MaNGOS::NormalizeMapCoord(node.x);
|
||||
MaNGOS::NormalizeMapCoord(node.y);
|
||||
if(result1)
|
||||
{
|
||||
node.z = MapManager::Instance ().GetBaseMap(result1->Fetch()[1].GetUInt32())->GetHeight(node.x, node.y, node.z);
|
||||
delete result1;
|
||||
}
|
||||
WorldDatabase.PExecute("UPDATE creature_movement SET position_x = '%f', position_y = '%f', position_z = '%f' WHERE id = '%u' AND point = '%u'", node.x, node.y, node.z, id, point);
|
||||
}
|
||||
WaypointBehavior be;
|
||||
be.model1 = fields[4].GetUInt32();
|
||||
be.model2 = fields[5].GetUInt32();
|
||||
be.emote = fields[7].GetUInt32();
|
||||
be.spell = fields[8].GetUInt32();
|
||||
for(int i = 0; i < MAX_WAYPOINT_TEXT; ++i)
|
||||
{
|
||||
be.textid[i] = fields[9+i].GetUInt32();
|
||||
if(be.textid[i])
|
||||
{
|
||||
if (be.textid[i] < MIN_DB_SCRIPT_STRING_ID || be.textid[i] >= MAX_DB_SCRIPT_STRING_ID)
|
||||
{
|
||||
sLog.outErrorDb( "Table `db_script_string` not have string id %u", be.textid[i]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// save memory by not storing empty behaviors
|
||||
if(!be.isEmpty())
|
||||
{
|
||||
node.behavior = new WaypointBehavior(be);
|
||||
++total_behaviors;
|
||||
}
|
||||
else
|
||||
node.behavior = NULL;
|
||||
} while( result->NextRow() );
|
||||
delete result;
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Waypoints and behaviors loaded" );
|
||||
sLog.outString();
|
||||
sLog.outString( ">>> Loaded %u paths, %u nodes and %u behaviors", total_paths, total_nodes, total_behaviors);
|
||||
}
|
||||
|
||||
void WaypointManager::Cleanup()
|
||||
|
|
|
|||
|
|
@ -799,6 +799,7 @@ void World::LoadConfigSettings(bool reload)
|
|||
m_configs[CONFIG_START_GM_LEVEL] = MAX_LEVEL;
|
||||
}
|
||||
m_configs[CONFIG_GM_LOWER_SECURITY] = sConfig.GetBoolDefault("GM.LowerSecurity", false);
|
||||
m_configs[CONFIG_GM_ALLOW_ACHIEVEMENT_GAINS] = sConfig.GetBoolDefault("GM.AllowAchievementGain", true);
|
||||
|
||||
m_configs[CONFIG_GROUP_VISIBILITY] = sConfig.GetIntDefault("Visibility.GroupMode",0);
|
||||
|
||||
|
|
@ -1069,7 +1070,7 @@ void World::SetInitialWorldSettings()
|
|||
sLog.outString( "Loading Script Names...");
|
||||
objmgr.LoadScriptNames();
|
||||
|
||||
sLog.outString( "Loading InstanceTemplate" );
|
||||
sLog.outString( "Loading InstanceTemplate..." );
|
||||
objmgr.LoadInstanceTemplate();
|
||||
|
||||
sLog.outString( "Loading SkillLineAbilityMultiMap Data..." );
|
||||
|
|
@ -1082,6 +1083,7 @@ void World::SetInitialWorldSettings()
|
|||
sLog.outString( "Packing instances..." );
|
||||
sInstanceSaveManager.PackInstances();
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString( "Loading Localization strings..." );
|
||||
objmgr.LoadCreatureLocales();
|
||||
objmgr.LoadGameObjectLocales();
|
||||
|
|
@ -1091,6 +1093,8 @@ void World::SetInitialWorldSettings()
|
|||
objmgr.LoadPageTextLocales();
|
||||
objmgr.LoadNpcOptionLocales();
|
||||
objmgr.SetDBCLocaleIndex(GetDefaultDbcLocale()); // Get once for all the locale index of DBC language (console/broadcasts)
|
||||
sLog.outString( ">>> Localization strings loaded" );
|
||||
sLog.outString();
|
||||
|
||||
sLog.outString( "Loading Page Texts..." );
|
||||
objmgr.LoadPageTexts();
|
||||
|
|
@ -1150,7 +1154,10 @@ void World::SetInitialWorldSettings()
|
|||
objmgr.LoadCreatures();
|
||||
|
||||
sLog.outString( "Loading Creature Addon Data..." );
|
||||
sLog.outString();
|
||||
objmgr.LoadCreatureAddons(); // must be after LoadCreatureTemplates() and LoadCreatures()
|
||||
sLog.outString( ">>> Creature Addon Data loaded" );
|
||||
sLog.outString();
|
||||
|
||||
sLog.outString( "Loading Creature Respawn Data..." ); // must be after PackInstances()
|
||||
objmgr.LoadCreatureRespawnTimes();
|
||||
|
|
@ -1162,7 +1169,10 @@ void World::SetInitialWorldSettings()
|
|||
objmgr.LoadGameobjectRespawnTimes();
|
||||
|
||||
sLog.outString( "Loading Game Event Data...");
|
||||
sLog.outString();
|
||||
gameeventmgr.LoadFromDB();
|
||||
sLog.outString( ">>> Game Event Data loaded" );
|
||||
sLog.outString();
|
||||
|
||||
sLog.outString( "Loading Weather Data..." );
|
||||
objmgr.LoadWeatherZoneChances();
|
||||
|
|
@ -1171,7 +1181,10 @@ void World::SetInitialWorldSettings()
|
|||
objmgr.LoadQuests(); // must be loaded after DBCs, creature_template, item_template, gameobject tables
|
||||
|
||||
sLog.outString( "Loading Quests Relations..." );
|
||||
sLog.outString();
|
||||
objmgr.LoadQuestRelations(); // must be after quest load
|
||||
sLog.outString( ">>> Quests Relations loaded" );
|
||||
sLog.outString();
|
||||
|
||||
sLog.outString( "Loading AreaTrigger definitions..." );
|
||||
objmgr.LoadAreaTriggerTeleports(); // must be after item template load
|
||||
|
|
@ -1200,8 +1213,11 @@ void World::SetInitialWorldSettings()
|
|||
sLog.outString( "Loading pet levelup spells..." );
|
||||
spellmgr.LoadPetLevelupSpellMap();
|
||||
|
||||
sLog.outString( "Loading player Create Info & Level Stats..." );
|
||||
sLog.outString( "Loading Player Create Info & Level Stats..." );
|
||||
sLog.outString();
|
||||
objmgr.LoadPlayerInfo();
|
||||
sLog.outString( ">>> Player Create Info & Level Stats loaded" );
|
||||
sLog.outString();
|
||||
|
||||
sLog.outString( "Loading Exploration BaseXP Data..." );
|
||||
objmgr.LoadExplorationBaseXP();
|
||||
|
|
@ -1219,7 +1235,10 @@ void World::SetInitialWorldSettings()
|
|||
objmgr.LoadCorpses();
|
||||
|
||||
sLog.outString( "Loading Loot Tables..." );
|
||||
sLog.outString();
|
||||
LoadLootTables();
|
||||
sLog.outString( ">>> Loot Tables loaded" );
|
||||
sLog.outString();
|
||||
|
||||
sLog.outString( "Loading Skill Discovery Table..." );
|
||||
LoadSkillDiscoveryTable();
|
||||
|
|
@ -1230,22 +1249,22 @@ void World::SetInitialWorldSettings()
|
|||
sLog.outString( "Loading Skill Fishing base level requirements..." );
|
||||
objmgr.LoadFishingBaseSkillLevel();
|
||||
|
||||
sLog.outString( "Loading AchievementCriteriaList..." );
|
||||
sLog.outString( "Loading Achievements..." );
|
||||
sLog.outString();
|
||||
achievementmgr.LoadAchievementCriteriaList();
|
||||
|
||||
sLog.outString( "Loading achievement rewards..." );
|
||||
achievementmgr.LoadRewards();
|
||||
|
||||
sLog.outString( "Loading achievement reward locale strings..." );
|
||||
achievementmgr.LoadRewardLocales();
|
||||
|
||||
sLog.outString( "Loading completed achievements..." );
|
||||
achievementmgr.LoadCompletedAchievements();
|
||||
sLog.outString( ">>> Achievements loaded" );
|
||||
sLog.outString();
|
||||
|
||||
///- Load dynamic data tables from the database
|
||||
sLog.outString( "Loading Auctions..." );
|
||||
sLog.outString();
|
||||
objmgr.LoadAuctionItems();
|
||||
objmgr.LoadAuctions();
|
||||
sLog.outString( ">>> Auctions loaded" );
|
||||
sLog.outString();
|
||||
|
||||
sLog.outString( "Loading Guilds..." );
|
||||
objmgr.LoadGuilds();
|
||||
|
|
@ -1259,7 +1278,7 @@ void World::SetInitialWorldSettings()
|
|||
sLog.outString( "Loading ReservedNames..." );
|
||||
objmgr.LoadReservedPlayersNames();
|
||||
|
||||
sLog.outString( "Loading GameObject for quests..." );
|
||||
sLog.outString( "Loading GameObjects for quests..." );
|
||||
objmgr.LoadGameObjectForQuests();
|
||||
|
||||
sLog.outString( "Loading BattleMasters..." );
|
||||
|
|
@ -1274,13 +1293,14 @@ void World::SetInitialWorldSettings()
|
|||
sLog.outString( "Loading Npc Options..." );
|
||||
objmgr.LoadNpcOptions();
|
||||
|
||||
sLog.outString( "Loading vendors..." );
|
||||
sLog.outString( "Loading Vendors..." );
|
||||
objmgr.LoadVendors(); // must be after load CreatureTemplate and ItemTemplate
|
||||
|
||||
sLog.outString( "Loading trainers..." );
|
||||
sLog.outString( "Loading Trainers..." );
|
||||
objmgr.LoadTrainerSpell(); // must be after load CreatureTemplate
|
||||
|
||||
sLog.outString( "Loading Waypoints..." );
|
||||
sLog.outString();
|
||||
WaypointMgr.Load();
|
||||
|
||||
sLog.outString( "Loading GM tickets...");
|
||||
|
|
@ -1292,11 +1312,14 @@ void World::SetInitialWorldSettings()
|
|||
|
||||
///- Load and initialize scripts
|
||||
sLog.outString( "Loading Scripts..." );
|
||||
sLog.outString();
|
||||
objmgr.LoadQuestStartScripts(); // must be after load Creature/Gameobject(Template/Data) and QuestTemplate
|
||||
objmgr.LoadQuestEndScripts(); // must be after load Creature/Gameobject(Template/Data) and QuestTemplate
|
||||
objmgr.LoadSpellScripts(); // must be after load Creature/Gameobject(Template/Data)
|
||||
objmgr.LoadGameObjectScripts(); // must be after load Creature/Gameobject(Template/Data)
|
||||
objmgr.LoadEventScripts(); // must be after load Creature/Gameobject(Template/Data)
|
||||
sLog.outString( ">>> Scripts loaded" );
|
||||
sLog.outString();
|
||||
|
||||
sLog.outString( "Loading Scripts text locales..." ); // must be after Load*Scripts calls
|
||||
objmgr.LoadDbScriptStrings();
|
||||
|
|
@ -1409,6 +1432,7 @@ void World::DetectDBCLang()
|
|||
m_defaultDbcLocale = LocaleConstant(default_locale);
|
||||
|
||||
sLog.outString("Using %s DBC Locale as default. All available DBC locales: %s",localeNames[m_defaultDbcLocale],availableLocalsStr.empty() ? "<none>" : availableLocalsStr.c_str());
|
||||
sLog.outString();
|
||||
}
|
||||
|
||||
/// Update the World !
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ enum WorldConfigs
|
|||
CONFIG_GM_LOG_TRADE,
|
||||
CONFIG_START_GM_LEVEL,
|
||||
CONFIG_GM_LOWER_SECURITY,
|
||||
CONFIG_GM_ALLOW_ACHIEVEMENT_GAINS,
|
||||
CONFIG_GROUP_VISIBILITY,
|
||||
CONFIG_MAIL_DELIVERY_DELAY,
|
||||
CONFIG_UPTIME_UPDATE,
|
||||
|
|
|
|||
|
|
@ -531,7 +531,7 @@ void WorldSession::LoadAccountData()
|
|||
if(!result)
|
||||
return;
|
||||
|
||||
do
|
||||
do
|
||||
{
|
||||
Field *fields = result->Fetch();
|
||||
|
||||
|
|
|
|||
|
|
@ -875,17 +875,23 @@ Channel.SilentlyGMJoin = 0
|
|||
# Default: 0 (disable)
|
||||
# 1 (enable)
|
||||
#
|
||||
# GM.AllowAchievementGain
|
||||
# If enabled it allows gaining achievements for GM characters
|
||||
# Default: 0 (disable)
|
||||
# 1 (enable) (default)
|
||||
#
|
||||
###################################################################################################################
|
||||
|
||||
GM.LoginState = 2
|
||||
GM.AcceptTickets = 2
|
||||
GM.Chat = 2
|
||||
GM.WhisperingTo = 2
|
||||
GM.InGMList = 0
|
||||
GM.InWhoList = 0
|
||||
GM.LogTrade = 1
|
||||
GM.StartLevel = 1
|
||||
GM.LowerSecurity = 0
|
||||
GM.LoginState = 2
|
||||
GM.AcceptTickets = 2
|
||||
GM.Chat = 2
|
||||
GM.WhisperingTo = 2
|
||||
GM.InGMList = 0
|
||||
GM.InWhoList = 0
|
||||
GM.LogTrade = 1
|
||||
GM.StartLevel = 1
|
||||
GM.LowerSecurity = 0
|
||||
GM.AllowAchievementGain = 1
|
||||
|
||||
###################################################################################################################
|
||||
# VISIBILITY AND RADIUSES
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ int DOTCONFDocument::cleanupLine(char * line)
|
|||
quoted = !quoted;
|
||||
++line; continue;
|
||||
}
|
||||
if(isspace(*line) && !quoted){
|
||||
if(isspace((unsigned char)*line) && !quoted){
|
||||
*bg++ = 0;
|
||||
if(strlen(start)){
|
||||
|
||||
|
|
@ -154,7 +154,7 @@ int DOTCONFDocument::cleanupLine(char * line)
|
|||
words.push_back(word);
|
||||
}
|
||||
start = bg;
|
||||
while(isspace(*++line)) {}
|
||||
while(isspace((unsigned char)*++line)) {}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ DBCStorage <ChrRacesEntry> sChrRacesStore(ChrRacesEntryfmt);
|
|||
DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore(CreatureDisplayInfofmt);
|
||||
DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore(CreatureFamilyfmt);
|
||||
DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore(CreatureSpellDatafmt);
|
||||
DBCStorage <CreatureTypeEntry> sCreatureTypeStore(CreatureTypefmt);
|
||||
|
||||
DBCStorage <DurabilityQualityEntry> sDurabilityQualityStore(DurabilityQualityfmt);
|
||||
DBCStorage <DurabilityCostsEntry> sDurabilityCostsStore(DurabilityCostsfmt);
|
||||
|
|
@ -190,7 +191,7 @@ void LoadDBCStores(const std::string& dataPath)
|
|||
{
|
||||
std::string dbcPath = dataPath+"dbc/";
|
||||
|
||||
const uint32 DBCFilesCount = 69;
|
||||
const uint32 DBCFilesCount = 70;
|
||||
|
||||
barGoLink bar( DBCFilesCount );
|
||||
|
||||
|
|
@ -221,7 +222,7 @@ void LoadDBCStores(const std::string& dataPath)
|
|||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBattlemasterListStore, dbcPath,"BattlemasterList.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBarberShopStyleStore, dbcPath,"BarberShopStyle.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharStartOutfitStore, dbcPath,"CharStartOutfit.dbc");
|
||||
|
||||
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharTitlesStore, dbcPath,"CharTitles.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChatChannelsStore, dbcPath,"ChatChannels.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrClassesStore, dbcPath,"ChrClasses.dbc");
|
||||
|
|
@ -229,6 +230,7 @@ void LoadDBCStores(const std::string& dataPath)
|
|||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureDisplayInfoStore, dbcPath,"CreatureDisplayInfo.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureFamilyStore, dbcPath,"CreatureFamily.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureSpellDataStore, dbcPath,"CreatureSpellData.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCreatureTypeStore, dbcPath,"CreatureType.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sDurabilityCostsStore, dbcPath,"DurabilityCosts.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sDurabilityQualityStore, dbcPath,"DurabilityQuality.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sEmotesTextStore, dbcPath,"EmotesText.dbc");
|
||||
|
|
@ -405,18 +407,6 @@ void LoadDBCStores(const std::string& dataPath)
|
|||
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiNodesStore, dbcPath,"TaxiNodes.dbc");
|
||||
|
||||
// Initialize global taxinodes mask
|
||||
memset(sTaxiNodesMask,0,sizeof(sTaxiNodesMask));
|
||||
for(uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i)
|
||||
{
|
||||
if(sTaxiNodesStore.LookupEntry(i))
|
||||
{
|
||||
uint8 field = (uint8)((i - 1) / 32);
|
||||
uint32 submask = 1<<((i-1)%32);
|
||||
sTaxiNodesMask[field] |= submask;
|
||||
}
|
||||
}
|
||||
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiPathStore, dbcPath,"TaxiPath.dbc");
|
||||
for(uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i)
|
||||
if(TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i))
|
||||
|
|
@ -444,6 +434,47 @@ void LoadDBCStores(const std::string& dataPath)
|
|||
sTaxiPathNodesByPath[entry->path][entry->index] = TaxiPathNode(entry->mapid,entry->x,entry->y,entry->z,entry->actionFlag,entry->delay);
|
||||
sTaxiPathNodeStore.Clear();
|
||||
|
||||
// Initialize global taxinodes mask
|
||||
// include existed nodes that have at least single not spell base (scripted) path
|
||||
{
|
||||
std::set<uint32> spellPaths;
|
||||
for(uint32 i = 1; i < sSpellStore.GetNumRows (); ++i)
|
||||
if(SpellEntry const* sInfo = sSpellStore.LookupEntry (i))
|
||||
for(int j=0; j < 3; ++j)
|
||||
if(sInfo->Effect[j]==123 /*SPELL_EFFECT_SEND_TAXI*/)
|
||||
spellPaths.insert(sInfo->EffectMiscValue[j]);
|
||||
|
||||
memset(sTaxiNodesMask,0,sizeof(sTaxiNodesMask));
|
||||
for(uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i)
|
||||
{
|
||||
if(!sTaxiNodesStore.LookupEntry(i))
|
||||
continue;
|
||||
|
||||
TaxiPathSetBySource::const_iterator src_i = sTaxiPathSetBySource.find(i);
|
||||
if(src_i!=sTaxiPathSetBySource.end() && !src_i->second.empty())
|
||||
{
|
||||
bool ok = false;
|
||||
for(TaxiPathSetForSource::const_iterator dest_i = src_i->second.begin();dest_i != src_i->second.end(); ++dest_i)
|
||||
{
|
||||
// not spell path
|
||||
if(spellPaths.find(dest_i->second.ID)==spellPaths.end())
|
||||
{
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!ok)
|
||||
continue;
|
||||
}
|
||||
|
||||
// valid taxi netowrk node
|
||||
uint8 field = (uint8)((i - 1) / 32);
|
||||
uint32 submask = 1<<((i-1)%32);
|
||||
sTaxiNodesMask[field] |= submask;
|
||||
}
|
||||
}
|
||||
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTotemCategoryStore, dbcPath,"TotemCategory.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sVehicleStore, dbcPath,"Vehicle.dbc");
|
||||
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sVehicleSeatStore, dbcPath,"VehicleSeat.dbc");
|
||||
|
|
@ -474,11 +505,11 @@ void LoadDBCStores(const std::string& dataPath)
|
|||
// check at up-to-date DBC files (2425 is last item extended cost added in 3.0.1)
|
||||
// check at up-to-date DBC files (76 is last char title added in 3.0.1)
|
||||
// check at up-to-date DBC files (2311 is last area added in 3.0.1)
|
||||
if( !sSpellStore.LookupEntry(54909) ||
|
||||
!sSkillLineAbilityStore.LookupEntry(19162) ||
|
||||
if( !sSpellStore.LookupEntry(54909) ||
|
||||
!sSkillLineAbilityStore.LookupEntry(19162) ||
|
||||
!sMapStore.LookupEntry(619) ||
|
||||
!sGemPropertiesStore.LookupEntry(1361) ||
|
||||
!sItemExtendedCostStore.LookupEntry(2425) ||
|
||||
!sGemPropertiesStore.LookupEntry(1361) ||
|
||||
!sItemExtendedCostStore.LookupEntry(2425) ||
|
||||
!sCharTitlesStore.LookupEntry(76) ||
|
||||
!sAreaStore.LookupEntry(2311) )
|
||||
{
|
||||
|
|
@ -487,8 +518,7 @@ void LoadDBCStores(const std::string& dataPath)
|
|||
}
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Loaded %d data stores", DBCFilesCount );
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Initialized %d data stores", DBCFilesCount );
|
||||
}
|
||||
|
||||
SimpleFactionsList const* GetFactionTeamList(uint32 faction)
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ extern DBCStorage <ChrRacesEntry> sChrRacesStore;
|
|||
extern DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore;
|
||||
extern DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore;
|
||||
extern DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore;
|
||||
extern DBCStorage <CreatureTypeEntry> sCreatureTypeStore;
|
||||
extern DBCStorage <DurabilityCostsEntry> sDurabilityCostsStore;
|
||||
extern DBCStorage <DurabilityQualityEntry> sDurabilityQualityStore;
|
||||
extern DBCStorage <EmotesTextEntry> sEmotesTextStore;
|
||||
|
|
|
|||
|
|
@ -664,6 +664,14 @@ struct CreatureSpellDataEntry
|
|||
//uint32 availability[4]; // 4-7 m_availability[4]
|
||||
};
|
||||
|
||||
struct CreatureTypeEntry
|
||||
{
|
||||
uint32 ID; // 0 m_ID
|
||||
//char* Name[16]; // 1-16 name
|
||||
// 17 string flags
|
||||
//uint32 no_expirience; // 18 no exp? critters, non-combat pets, gas cloud.
|
||||
};
|
||||
|
||||
struct DurabilityCostsEntry
|
||||
{
|
||||
uint32 Itemlvl; // 0
|
||||
|
|
@ -941,14 +949,16 @@ struct MapEntry
|
|||
bool IsBattleGround() const { return map_type == MAP_BATTLEGROUND; }
|
||||
bool IsBattleArena() const { return map_type == MAP_ARENA; }
|
||||
bool IsBattleGroundOrArena() const { return map_type == MAP_BATTLEGROUND || map_type == MAP_ARENA; }
|
||||
bool SupportsHeroicMode() const { return resetTimeHeroic && !resetTimeRaid; }
|
||||
bool SupportsHeroicMode() const { return resetTimeHeroic != 0; }
|
||||
bool HasResetTime() const { return resetTimeHeroic || resetTimeRaid; }
|
||||
|
||||
bool IsMountAllowed() const
|
||||
{
|
||||
return !IsDungeon() ||
|
||||
MapID==568 || MapID==309 || MapID==209 || MapID==534 ||
|
||||
MapID==560 || MapID==509 || MapID==269;
|
||||
MapID==209 || MapID==269 || MapID==309 || // TanarisInstance, CavernsOfTime, Zul'gurub
|
||||
MapID==509 || MapID==534 || MapID==560 || // AhnQiraj, HyjalPast, HillsbradPast
|
||||
MapID==568 || MapID==580 || MapID==615 || // ZulAman, Sunwell Plateau, Obsidian Sanctrum
|
||||
MapID==616; // Eye Of Eternity
|
||||
}
|
||||
|
||||
bool IsContinent() const
|
||||
|
|
@ -1409,7 +1419,7 @@ struct VehicleEntry
|
|||
uint32 m_uiSeatIndicatorType; // 42
|
||||
};
|
||||
|
||||
struct VehicleSeatEntry
|
||||
struct VehicleSeatEntry
|
||||
{
|
||||
uint32 m_ID; // 0
|
||||
uint32 m_flags; // 1
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ const char ChrRacesEntryfmt[]="nxixiixxixxxxissssssssssssssssxxxxxxxxxxxxxxxxxxx
|
|||
const char CreatureDisplayInfofmt[]="nxxxfxxxxxxxxxxx";
|
||||
const char CreatureFamilyfmt[]="nfifiiiiixssssssssssssssssxx";
|
||||
const char CreatureSpellDatafmt[]="nxxxxxxxx";
|
||||
const char CreatureTypefmt[]="nxxxxxxxxxxxxxxxxxx";
|
||||
const char DurabilityCostsfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiii";
|
||||
const char DurabilityQualityfmt[]="nf";
|
||||
const char EmoteEntryfmt[]="nxixxxxxxxxxxxxxxxx";
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ const char ItemPrototypesrcfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
|
|||
const char ItemPrototypedstfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiffiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiiiiiii";
|
||||
const char PageTextfmt[]="isi";
|
||||
const char SpellThreatfmt[]="ii";
|
||||
const char InstanceTemplatesrcfmt[]="iiiiiiffffs";
|
||||
const char InstanceTemplatedstfmt[]="iiiiiiffffi";
|
||||
const char InstanceTemplatesrcfmt[]="iiiiiiiffffs";
|
||||
const char InstanceTemplatedstfmt[]="iiiiiiiffffi";
|
||||
|
||||
SQLStorage sCreatureStorage(CreatureInfosrcfmt, CreatureInfodstfmt, "entry","creature_template");
|
||||
SQLStorage sCreatureDataAddonStorage(CreatureDataAddonInfofmt,"guid","creature_addon");
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "7135"
|
||||
#define REVISION_NR "7167"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue