Merge commit 'origin/master' into 320

Conflicts:
	src/game/Map.cpp
	src/game/MapInstanced.cpp
	src/game/Player.cpp
	src/game/SpellEffects.cpp
	src/game/Totem.cpp
This commit is contained in:
tomrus88 2009-07-15 09:40:13 +04:00
commit 1a47420fe8
43 changed files with 1208 additions and 714 deletions

225
sql/mangos_spell_check.sql Normal file
View file

@ -0,0 +1,225 @@
/* This file contain expected by code spell properties from simple existance to spell family mask and icons. */
/* This data let easy detect spell properties change at client version */
/* support switch and update or drop problematic code associated with checked*/
/* spell data. */
/* sql file not required for server work but expected to be applied to */
/* MaNGOS DB if you plan use .debug spellcheck command in console. */
/* To code commiters: */
/* */
/* If you commit code that include explicit used spell id or checks base at */
/* spell family mask (and etc) please include same data in this table always.*/
/* At least for parts already added in table. */
/* File not required sql updates way to support, and always expected full */
/* re-adding before command use. So need just adding new line to file. */
/* Current table fill progress state: */
/* SpellEffect.cpp from start until end of SPELLFAMILY_GENERIC case of Spell::EffectDummy */
DROP TABLE IF EXISTS spell_check;
CREATE TABLE `spell_check` (
spellid mediumint(7) unsigned NOT NULL default '0',
SpellFamilyName smallint(5) NOT NULL default '-1',
SpellFamilyMaskA bigint(30) NOT NULL default '-1', /* 0xFFFFFFFFFFFFFFFF */
SpellFamilyMaskB int(10) NOT NULL default '-1', /* 0xFFFFFFFF */
SpellIcon int(10) NOT NULL default '-1',
SpellVisual int(10) NOT NULL default '-1',
SpellCategory int(10) NOT NULL default '-1',
EffectType int(10) NOT NULL default '-1',
EffectAura int(10) NOT NULL default '-1',
EffectIdx tinyint(3) NOT NULL default '-1',
Name varchar(40) NOT NULL default '',
Code varchar(40) NOT NULL default '',
PRIMARY KEY (spellid,SpellFamilyName,SpellFamilyMaskA,SpellFamilyMaskB,SpellIcon,SpellVisual,SpellCategory,EffectType,EffectAura,EffectIdx,Code)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO spell_check (spellid,SpellFamilyName,SpellFamilyMaskA,SpellFamilyMaskB,SpellIcon,SpellVisual,SpellCategory,EffectType,EffectAura,EffectIdx,Name,Code) VALUES
/* sorted by spell ids */
/*id fm familyMaskA fmMaskB icon vis cat eff aur ef name code */
(4073, -1, -1, -1, -1, -1, -1, -1, -1,-1,'Mechanical Dragonling', 'Spell::EffectDummy'),
(8063, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Deviate Fish', 'Spell::EffectDummy'),
(8064, -1, -1, -1, -1, -1, -1, -1, -1,-1,'Sleepy', 'Spell::EffectDummy'),
(8065, -1, -1, -1, -1, -1, -1, -1, -1,-1,'Invigorate', 'Spell::EffectDummy'),
(8066, -1, -1, -1, -1, -1, -1, -1, -1,-1,'Shrink', 'Spell::EffectDummy'),
(8067, -1, -1, -1, -1, -1, -1, -1, -1,-1,'Party Time!', 'Spell::EffectDummy'),
(8068, -1, -1, -1, -1, -1, -1, -1, -1,-1,'Healthy Spirit', 'Spell::EffectDummy'),
(8213, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Savory Deviate Delight', 'Spell::EffectDummy'),
(8219, -1, -1, -1, -1, -1, -1, -1, -1,-1,'Flip Out', 'Spell::EffectDummy'),
(8220, -1, -1, -1, -1, -1, -1, -1, -1,-1,'Flip Out', 'Spell::EffectDummy'),
(8221, -1, -1, -1, -1, -1, -1, -1, -1,-1,'Yaaarrrr', 'Spell::EffectDummy'),
(8222, -1, -1, -1, -1, -1, -1, -1, -1,-1,'Yaaarrrr', 'Spell::EffectDummy'),
(8593, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Symbol of life', 'Spell::EffectDummy'),
(12162, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Deep wounds', 'Spell::EffectDummy'),
(12749,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Mithril Mechanical Dragonling', 'Spell::EffectDummy'),
(12850, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Deep wounds', 'Spell::EffectDummy'),
(12868, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Deep wounds', 'Spell::EffectDummy'),
(12721,-1, -1, -1, -1, -1, -1, 6, 3, 0,'Deep wounds', 'Spell::EffectDummy'),
(13099,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Net-o-Matic', 'Spell::EffectDummy'),
(13119,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Net-o-Matic', 'Spell::EffectDummy'),
(13120, 0, -1, -1, -1, -1, -1, 3, -1,-1,'net-o-matic', 'Spell::EffectDummy'),
(13166,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Gnomish Battle Chicken', 'Spell::EffectDummy'),
(13567, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Dummy Trigger', 'Spell::EffectDummy'),
(15998, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Capture Worg Pup', 'Spell::EffectDummy'),
(16566,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Net-o-Matic', 'Spell::EffectDummy'),
(16589, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Noggenfogger Elixir', 'Spell::EffectDummy'),
(16591,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Noggenfogger Elixir', 'Spell::EffectDummy'),
(16593,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Noggenfogger Elixir', 'Spell::EffectDummy'),
(16595,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Noggenfogger Elixir', 'Spell::EffectDummy'),
(17251, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Spirit Healer Res', 'Spell::EffectDummy'),
(17269,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Create Resonating Skull', 'Spell::EffectDummy'),
(17270,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Create Bone Dust', 'Spell::EffectDummy'),
(17271, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Test Fetid Skull', 'Spell::EffectDummy'),
(18788,-1, -1, -1, -1, -1, -1, 1, -1,-1,'Demonic Sacrifice', 'Spell::EffectInstaKill'),
(18789,-1, -1, -1, -1, -1, -1, -1, -1,-1,'', 'Spell::EffectInstaKill'),
(18790,-1, -1, -1, -1, -1, -1, -1, -1,-1,'', 'Spell::EffectInstaKill'),
(18791,-1, -1, -1, -1, -1, -1, -1, -1,-1,'', 'Spell::EffectInstaKill'),
(18792,-1, -1, -1, -1, -1, -1, -1, -1,-1,'', 'Spell::EffectInstaKill'),
(19804,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Arcanite Dragonling', 'Spell::EffectDummy'),
(20253, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Intercept', 'Spell::EffectSchoolDMG'),
(20577, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Cannibalize', 'Spell::EffectDummy'),
(20578,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Cannibalize', 'Spell::EffectDummy'),
(23019, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Crystal Prison Dummy DND', 'Spell::EffectDummy'),
(23074, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Arcanite Dragonling', 'Spell::EffectDummy'),
(23075, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Mithril Mechanical Dragonling', 'Spell::EffectDummy'),
(23076, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Mechanical Dragonling', 'Spell::EffectDummy'),
(23133, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Gnomish Battle Chicken', 'Spell::EffectDummy'),
(23170,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Brood Affliction: Bronze', 'Spell::EffectDummy'),
(23441,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Gadgetzan Transporter', 'Spell::EffectDummy'),
(23444,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Transporter Malfunction', 'Spell::EffectDummy'),
(23445,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Evil Twin', 'Spell::EffectDummy'),
(23446,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Gadgetzan Transporter Failure', 'Spell::EffectDummy'),
(23448, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Transporter Arrival', 'Spell::EffectDummy'),
(23453, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Gnomish Transporter', 'Spell::EffectDummy'),
(23645, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Hourglass Sand', 'Spell::EffectDummy'),
(23725, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Gift of Life', 'Spell::EffectDummy'),
(23782,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Gift of Life', 'Spell::EffectDummy'),
(23783,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Gift of Life', 'Spell::EffectDummy'),
(24340, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Meteor', 'Spell::EffectSchoolDMG'),
(25599, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Thundercrash', 'Spell::EffectSchoolDMG'),
(25858,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Reindeer', 'Spell::EffectDummy'),
(25859,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Reindeer', 'Spell::EffectDummy'),
(25860, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Reindeer Transformation', 'Spell::EffectDummy'),
(26074, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Holiday Cheer', 'Spell::EffectDummy'),
(26467,-1, -1, -1, -1, -1, -1, 6, 42, 0,'Persistent Shield', 'Spell::EffectDummy'),
(26558, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Meteor', 'Spell::EffectSchoolDMG'),
(26635,-1, -1, -1, -1, -1, -1, 6, -1, 0,'Berserking', 'Spell::EffectDummy'),
(26635,-1, -1, -1, -1, -1, -1, 6, -1, 1,'Berserking', 'Spell::EffectDummy'),
(26635,-1, -1, -1, -1, -1, -1, 6, -1, 2,'Berserking', 'Spell::EffectDummy'),
(26789, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Shard of the Fallen Star', 'Spell::EffectSchoolDMG'),
(28006, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Arcane Cloaking', 'Spell::EffectDummy'),
(28884, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Meteor', 'Spell::EffectSchoolDMG'),
(29294,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Naxxramas Entry Flag Effect DND', 'Spell::EffectDummy'),
(29200, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Purify Helboar Meat', 'Spell::EffectDummy'),
(29277,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Summon Purified Helboar Meat', 'Spell::EffectDummy'),
(29278,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Summon Toxic Helboar Meat', 'Spell::EffectDummy'),
(29435, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Capture Female Kaliri Hatchling', 'Spell::EffectDummy'),
(29858, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Soulshatter', 'Spell::EffectDummy'),
(30452,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Rocket Boots Engaged', 'Spell::EffectDummy'),
(30456,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Nigh-Invulnerability', 'Spell::EffectDummy'),
(30457,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Complete Vulnerability', 'Spell::EffectDummy'),
(30458, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Nigh Invulnerability', 'Spell::EffectDummy'),
(30501,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Poultryized!', 'Spell::EffectDummy'),
(30504,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Poultryized!', 'Spell::EffectDummy'),
(30507, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Poultryizer', 'Spell::EffectDummy'),
(31225, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Shimmering Vessel', 'Spell::EffectDummy'),
(31436, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Malevolent Cleave', 'Spell::EffectSchoolDMG'),
(31803,-1, -1, -1, -1, -1, -1, 6, 3,-1,'Holy Vengeance', 'Spell::EffectSchoolDMG'),
(32409,-1, -1, -1, -1, -1, -1, 6, 3,-1,'Shadow Word: Death', 'Spell::EffectSchoolDMG'),
(32835,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Soulshatter', 'Spell::EffectDummy'),
(33053,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Mr Pinchy\'s Blessing', 'Spell::EffectDummy'),
(33057,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Summon Mighty Mr. Pinchy', 'Spell::EffectDummy'),
(33059,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Summon Furious Mr. Pinchy', 'Spell::EffectDummy'),
(33060, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Make a Wish', 'Spell::EffectDummy'),
(33062,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Tiny Magical Crawdad', 'Spell::EffectDummy'),
(33064,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Mr. Pinchy\'s Gift', 'Spell::EffectDummy'),
(34665, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Administer Antidote', 'Spell::EffectDummy'),
(35181, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Dive Bomb', 'Spell::EffectSchoolDMG'),
(35701,-1, -1, -1, -1, -1, -1, -1, -1,-1,'', 'Spell::EffectInstaKill'),
(35743,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Socrethar Portal', 'Spell::EffectDummy'),
(35744,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Socrethar Portal', 'Spell::EffectDummy'),
(35745, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Socrethar\'s Stone', 'Spell::EffectDummy'),
(36032,-1, -1, -1, -1, -1, -1, -1, -1,-1,'', 'Spell::EffectSchoolDMG'),
(36837, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Meteor', 'Spell::EffectSchoolDMG'),
(36902,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Transporter Malfunction', 'Spell::EffectDummy'),
(37169,-1, -1, -1, -1, -1, -1, 6, 4,-1,'Eviscerate and Envenom Bonus Damage','Spell::EffectSchoolDMG'),
(37674, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Chaos Blast', 'Spell::EffectDummy'),
(37675,-1, -1, -1, -1, -1, -1, 2, -1, 0,'Chaos Blast', 'Spell::EffectDummy'),
(38441, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Cataclysmic Bolt', 'Spell::EffectSchoolDMG'),
(38903, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Meteor', 'Spell::EffectSchoolDMG'),
(40810, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Saber Lash', 'Spell::EffectSchoolDMG'),
(41276, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Meteor', 'Spell::EffectSchoolDMG'),
(42384, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Brutal Swipe', 'Spell::EffectSchoolDMG'),
(43267, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Saber Lash', 'Spell::EffectSchoolDMG'),
(43268, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Saber Lash', 'Spell::EffectSchoolDMG'),
(43723, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Demon Broiled Surprise', 'Spell::EffectDummy'),
(43753,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Demon-Broiled Surprise', 'Spell::EffectDummy'),
(40802, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Mingo\'s Fortune Generator', 'Spell::EffectDummy'),
(42337,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Raptor Capture Credit', 'Spell::EffectDummy'),
(44824,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Flying Reindeer', 'Spell::EffectDummy'),
(44825,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Flying Reindeer', 'Spell::EffectDummy'),
(44827,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Flying Reindeer', 'Spell::EffectDummy'),
(44875, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Complete Raptor Capture', 'Spell::EffectDummy'),
(44997, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Converting Sentry', 'Spell::EffectDummy'),
(45009,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Converted Sentry Credit', 'Spell::EffectDummy'),
(45030, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Impale Emissary', 'Spell::EffectDummy'),
(45088,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Emissary of Hate Credit', 'Spell::EffectDummy'),
(45150, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Meteor Slash', 'Spell::EffectSchoolDMG'),
(46014,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Knocked Up', 'Spell::EffectDummy'),
(50242,-1, -1, -1, -1, -1, -1, -1, -1,-1,'1000001', 'Spell::EffectDummy'),
(50243, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Teach Language', 'Spell::EffectDummy'),
(50246,-1, -1, -1, -1, -1, -1, -1, -1,-1,'01001000', 'Spell::EffectDummy'),
(51582, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Rocket Boots Engaged', 'Spell::EffectDummy'),
(51592, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Pickup Primordial Hatchling', 'Spell::EffectDummy'),
(52308, 0, -1, -1, -1, -1, -1, 3, -1, 0,'Take Sputum Sample', 'Spell::EffectDummy'),
(52308, 0, -1, -1, -1, -1, -1, 3, -1, 1,'Take Sputum Sample', 'Spell::EffectDummy'),
(52752,-1, -1, -1, -1, -1, -1, 10, -1, 0,'Ancestral Awakening', 'Spell::EffectDummy'),
(52759, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Ancestral Awakening', 'Spell::EffectDummy'),
(53341, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Rune of Cinderglacier', 'Spell::EffectDummy'),
(53343, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Rune of Razorice', 'Spell::EffectDummy'),
(54586,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Runeforging Credit', 'Spell::EffectDummy'),
(54861,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Nitro Boosts', 'Spell::EffectDummy'),
(55004, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Nitro Boosts', 'Spell::EffectDummy'),
(58418, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Portal to Orgrimmar', 'Spell::EffectDummy'),
(58420, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Portal to Stormwind', 'Spell::EffectDummy'),
(61491, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Intercept', 'Spell::EffectSchoolDMG'),
/* sorted by spell names */
/*id fm familyMaskA fmMaskB icon vis cat eff aur ef name code */
( 0, 3,0x0000000020000000,0x00000000, -1, -1, -1, 2, -1,-1,'Arcane Blast', 'Spell::EffectSchoolDMG'),
( 0, 9,0x0000000000000800,0x00000000, -1, -1, -1, 2, -1,-1,'Arcane Shot', 'Spell::EffectSchoolDMG'),
( 0,10,0x0000000000004000,0x00000000, -1, -1, -1, 2, -1,-1,'Avenger\'s Shield', 'Spell::EffectSchoolDMG'),
( 0, 0, -1, -1,1661, -1, -1, 3, -1,-1,'Berserking', 'Spell::EffectDummy'),
( 0, 4,0x0000040000000000,0x00000000, -1, -1, -1, 2, -1,-1,'Bloodthirst', 'Spell::EffectSchoolDMG'),
( 0, 9,0x0008000000000000,0x00000000, -1, -1, -1, 2, -1,-1,'Counterattack', 'Spell::EffectSchoolDMG'),
( 0, 8,0x0000000000010000,0x00000000, -1, -1, -1, -1, 3,-1,'Deadly poison', 'Spell::EffectSchoolDMG'),
( 0, 8,0x0000000800000000,0x00000000, -1, -1, -1, 2, -1,-1,'Envenom', 'Spell::EffectSchoolDMG'),
( 0, 8,0x0000000000020000,0x00000000, -1, -1, -1, 2, -1,-1,'Eviscerate', 'Spell::EffectSchoolDMG'),
( 0, 9,0x0000000000000004,0x00000000, -1, -1, -1, 2, -1,-1,'Explosive Trap Effect', 'Spell::EffectSchoolDMG'),
( 0, 7,0x0000000000800000,0x00000000, -1,6587, -1, 2, -1,-1,'Ferocious Bite', 'Spell::EffectSchoolDMG'),
( 0, 9, -1, -1,1578, -1, -1, 2, -1,-1,'Gore', 'Spell::EffectSchoolDMG'),
( 0, 8,0x0000000000000008,0x00000000, -1, -1, -1, 2, -1,-1,'Gouge', 'Spell::EffectSchoolDMG'),
( 0,10,0x0000008000000000,0x00000000, -1, -1, -1, 2, -1,-1,'Hammer of Wrath', 'Spell::EffectSchoolDMG'),
( 0,10,0x0004000000000000,0x00000000, -1, -1, -1, 2, -1,-1,'Hammer of the Righteous', 'Spell::EffectSchoolDMG'),
( 0, 4,0x0000000100000000,0x00000000, -1, -1, -1, 2, -1,-1,'Heroic Throw', 'Spell::EffectSchoolDMG'),
( 0, 5,0x0000004000000000,0x00000000,2128, -1, -1, 2, -1,-1,'Incinerate', 'Spell::EffectSchoolDMG'),
( 0, 8,0x0000000000002000,0x00000000, -1, -1, -1, 2, -1,-1,'Instant Poison', 'Spell::EffectSchoolDMG'),
( 0,10,0x0000000800000000,0x00000000,2292, -1, -1, 2, -1,-1,'Judgement of Vengeance', 'Spell::EffectSchoolDMG'),
( 0, 7,0x0000010000000000,0x00000000,2246, -1, -1, 2, -1,-1,'Lacerate', 'Spell::EffectSchoolDMG'),
( 0, 7,0x0000044000000000,0x00000000, -1, -1, -1, -1, -1,-1,'Mangle (Cat) and Mangle (Bear)', 'Unit::HandleDummyAuraProc'),
( 0, 9,0x0000000000000002,0x00000000, -1, 342, -1, 2, -1,-1,'Mongoose Bite', 'Spell::EffectSchoolDMG'),
( 0, 7,0x0000000000001000,0x00000000, -1, -1, -1, 2, -1,-1,'Rake', 'Spell::EffectSchoolDMG'), /* used in */
( 0, 7,0x0000000000001000,0x00000000, -1, -1, -1, 80, -1, 2,'Rake', 'Spell::EffectSchoolDMG'), /* exactly selected */
( 0, 7,0x0000000000001000,0x00000000, -1, -1, -1, -1, 3,-1,'Rake', 'Aura::HandlePeriodicDamage'), /* used in */
( 0, 7,0x0000000000001000,0x00000000, -1, -1, -1, 80, -1, 2,'Rake', 'Aura::HandlePeriodicDamage'), /* exactly selected */
( 0, 4,0x0000000000000400,0x00000000, -1, -1, -1, 2, -1,-1,'Revenge', 'Spell::EffectSchoolDMG'),
( 0, 6,0x0000000200000000,0x00000000, -1, -1, -1, 2, -1,-1,'Shadow Word: Death', 'Spell::EffectSchoolDMG'),
( 0,10,0x0010000000000000,0x00000000, -1, -1, -1, 2, -1,-1,'Shield of Righteousness', 'Spell::EffectSchoolDMG'),
( 0, 4,0x0000020000000000,0x00000000, -1, -1,1209, 2, -1,-1,'Shield Slam', 'Spell::EffectSchoolDMG'),
( 0, 4,0x0000800000000000,0x00000000, -1, -1, -1, 2, -1,-1,'Shockwave', 'Spell::EffectSchoolDMG'),
( 0, 7,0x0000000000008000,0x00000000, -1, -1, -1, -1, -1,-1,'Shred', 'Unit::MeleeDamageBonus'),
( 0, 9,0x0000000100000000,0x00000000, -1, -1, -1, 2, -1,-1,'Steady Shot', 'Spell::EffectSchoolDMG'),
( 0, 7,0x0010000000000000,0x00000000, -1, -1, -1, 2, -1,-1,'Swipe', 'Spell::EffectSchoolDMG'),
( 0, 4,0x0000000000000080,0x00000000, -1, -1, -1, 2, -1,-1,'Thunder Clap', 'Spell::EffectSchoolDMG'),
( 0, 4,0x0000010000000000,0x00000000, -1, -1, -1, 2, -1,-1,'Victory Rush', 'Spell::EffectSchoolDMG'),
( 0, 8,0x0000000010000000,0x00000000, -1, -1, -1, 2, -1,-1,'Wound Poison', 'Spell::EffectSchoolDMG');

View file

@ -148,18 +148,19 @@ ChatCommand * ChatHandler::getCommandTable()
{ "anim", SEC_GAMEMASTER, false, &ChatHandler::HandleDebugAnimCommand, "", NULL },
{ "arena", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugArenaCommand, "", NULL },
{ "bg", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugBattlegroundCommand, "", NULL },
{ "getitemstate", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugGetItemState, "", NULL },
{ "lootrecipient", SEC_GAMEMASTER, false, &ChatHandler::HandleDebugGetLootRecipient, "", NULL },
{ "getvalue", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugGetValue, "", NULL },
{ "Mod32Value", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugMod32Value, "", NULL },
{ "getitemstate", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugGetItemStateCommand, "", NULL },
{ "lootrecipient", SEC_GAMEMASTER, false, &ChatHandler::HandleDebugGetLootRecipientCommand, "", NULL },
{ "getvalue", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugGetValueCommand, "", NULL },
{ "Mod32Value", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugMod32ValueCommand, "", NULL },
{ "play", SEC_MODERATOR, false, NULL, "", debugPlayCommandTable },
{ "send", SEC_ADMINISTRATOR, false, NULL, "", debugSendCommandTable },
{ "setaurastate", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSetAuraStateCommand, "", NULL },
{ "setitemflag", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSetItemFlagCommand, "", NULL },
{ "setvalue", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSetValue, "", NULL },
{ "setvalue", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSetValueCommand, "", NULL },
{ "spellcheck", SEC_CONSOLE, true, &ChatHandler::HandleDebugSpellCheckCommand, "", NULL },
{ "spawnvehicle", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSpawnVehicle, "", NULL },
{ "uws", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugUpdateWorldStateCommand, "", NULL },
{ "update", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugUpdate, "", NULL },
{ "update", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugUpdateCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
@ -566,7 +567,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "go", SEC_MODERATOR, false, NULL, "", goCommandTable },
{ "learn", SEC_MODERATOR, false, NULL, "", learnCommandTable },
{ "modify", SEC_MODERATOR, false, NULL, "", modifyCommandTable },
{ "debug", SEC_MODERATOR, false, NULL, "", debugCommandTable },
{ "debug", SEC_MODERATOR, true, NULL, "", debugCommandTable },
{ "tele", SEC_MODERATOR, true, NULL, "", teleCommandTable },
{ "character", SEC_GAMEMASTER, false, NULL, "", characterCommandTable},
{ "event", SEC_GAMEMASTER, false, NULL, "", eventCommandTable },

View file

@ -128,15 +128,16 @@ class ChatHandler
bool HandleDebugAnimCommand(const char* args);
bool HandleDebugArenaCommand(const char * args);
bool HandleDebugBattlegroundCommand(const char * args);
bool HandleDebugGetItemState(const char * args);
bool HandleDebugGetLootRecipient(const char * args);
bool HandleDebugGetValue(const char* args);
bool HandleDebugMod32Value(const char* args);
bool HandleDebugGetItemStateCommand(const char * args);
bool HandleDebugGetLootRecipientCommand(const char * args);
bool HandleDebugGetValueCommand(const char* args);
bool HandleDebugMod32ValueCommand(const char* args);
bool HandleDebugSetAuraStateCommand(const char * args);
bool HandleDebugSetItemFlagCommand(const char * args);
bool HandleDebugSetValue(const char* args);
bool HandleDebugSetValueCommand(const char* args);
bool HandleDebugSpawnVehicle(const char * args);
bool HandleDebugUpdate(const char* args);
bool HandleDebugSpellCheckCommand(const char* args);
bool HandleDebugUpdateCommand(const char* args);
bool HandleDebugUpdateWorldStateCommand(const char* args);
bool HandleDebugPlayCinematicCommand(const char* args);

View file

@ -72,12 +72,15 @@ bool Corpse::Create( uint32 guidlow )
bool Corpse::Create( uint32 guidlow, Player *owner)
{
SetInstanceId(owner->GetInstanceId());
WorldObject::_Create(guidlow, HIGHGUID_CORPSE, owner->GetMapId(), owner->GetPhaseMask());
ASSERT(owner);
WorldObject::_Create(guidlow, HIGHGUID_CORPSE, owner->GetPhaseMask());
Relocate(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ(), owner->GetOrientation());
//we need to assign owner's map for corpse
//in other way we will get a crash in Corpse::SaveToDB()
SetMap(owner->GetMap());
if(!IsPositionValid())
{
sLog.outError("Corpse (guidlow %d, owner %s) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
@ -207,8 +210,8 @@ bool Corpse::LoadFromDB(uint32 guid, Field *fields)
SetUInt64Value(OBJECT_FIELD_GUID, MAKE_NEW_GUID(guid, 0, HIGHGUID_CORPSE));
// place
SetInstanceId(instanceid);
SetMapId(mapid);
SetLocationInstanceId(instanceid);
SetLocationMapId(mapid);
SetPhaseMask(phaseMask, false);
Relocate(positionX, positionY, positionZ, ort);

View file

@ -563,8 +563,8 @@ bool Creature::AIM_Initialize()
bool Creature::Create (uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 team, const CreatureData *data)
{
SetMapId(map->GetId());
SetInstanceId(map->GetInstanceId());
ASSERT(map);
SetMap(map);
SetPhaseMask(phaseMask,false);
//oX = x; oY = y; dX = x; dY = y; m_moveTime = 0; m_startMove = 0;
@ -572,6 +572,12 @@ bool Creature::Create (uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry,
if (bResult)
{
//Notify the map's instance data.
//Only works if you create the object in it, not if it is moves to that map.
//Normally non-players do not teleport to other maps.
if(map->IsDungeon() && ((InstanceMap*)map)->GetInstanceData())
((InstanceMap*)map)->GetInstanceData()->OnCreatureCreate(this);
switch (GetCreatureInfo()->rank)
{
case CREATURE_ELITE_RARE:
@ -1312,15 +1318,6 @@ bool Creature::CreateFromProto(uint32 guidlow, uint32 Entry, uint32 team, const
if(!UpdateEntry(Entry, team, data))
return false;
//Notify the map's instance data.
//Only works if you create the object in it, not if it is moves to that map.
//Normally non-players do not teleport to other maps.
Map *map = MapManager::Instance().FindMap(GetMapId(), GetInstanceId());
if(map && map->IsDungeon() && ((InstanceMap*)map)->GetInstanceData())
{
((InstanceMap*)map)->GetInstanceData()->OnCreatureCreate(this);
}
return true;
}

View file

@ -56,9 +56,8 @@ void DynamicObject::RemoveFromWorld()
bool DynamicObject::Create( uint32 guidlow, Unit *caster, uint32 spellId, uint32 effIndex, float x, float y, float z, int32 duration, float radius )
{
SetInstanceId(caster->GetInstanceId());
WorldObject::_Create(guidlow, HIGHGUID_DYNAMICOBJECT, caster->GetMapId(), caster->GetPhaseMask());
WorldObject::_Create(guidlow, HIGHGUID_DYNAMICOBJECT, caster->GetPhaseMask());
SetMap(caster->GetMap());
Relocate(x, y, z, 0);
if(!IsPositionValid())

View file

@ -87,7 +87,7 @@ void GameObject::CleanupsBeforeDelete()
ownerType = "pet";
sLog.outError("Delete GameObject (GUID: %u Entry: %u SpellId %u LinkedGO %u) that lost references to owner (GUID %u Type '%s') GO list. Crash possible later.",
GetGUIDLow(), GetGOInfo()->id, m_spellId, GetLinkedGameObjectEntry(), GUID_LOPART(owner_guid), ownerType);
GetGUIDLow(), GetGOInfo()->id, m_spellId, GetGOInfo()->GetLinkedGameObjectEntry(), GUID_LOPART(owner_guid), ownerType);
}
}
}
@ -109,9 +109,9 @@ void GameObject::RemoveFromWorld()
bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, GOState go_state)
{
ASSERT(map);
Relocate(x,y,z,ang);
SetMapId(map->GetId());
SetInstanceId(map->GetInstanceId());
SetMap(map);
SetPhaseMask(phaseMask,false);
if(!IsPositionValid())
@ -383,7 +383,7 @@ void GameObject::Update(uint32 /*p_time*/)
{
case GAMEOBJECT_TYPE_DOOR:
case GAMEOBJECT_TYPE_BUTTON:
if (GetAutoCloseTime() && (m_cooldownTime < time(NULL)))
if (GetGOInfo()->GetAutoCloseTime() && (m_cooldownTime < time(NULL)))
ResetDoorOrButton();
break;
}
@ -423,7 +423,7 @@ void GameObject::Update(uint32 /*p_time*/)
}
//burning flags in some battlegrounds, if you find better condition, just add it
if (GetGoAnimProgress() > 0)
if (GetGOInfo()->IsDespawnAtAction() || GetGoAnimProgress() > 0)
{
SendObjectDeSpawnAnim(GetGUID());
//reset flags
@ -601,7 +601,7 @@ bool GameObject::LoadFromDB(uint32 guid, Map *map)
if (!Create(guid,entry, map, phaseMask, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, animprogress, go_state) )
return false;
if(!GetDespawnPossibility())
if(!GetGOInfo()->GetDespawnPossibility() && !GetGOInfo()->IsDespawnAtAction())
{
SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NODESPAWN);
m_spawnedByDefault = true;
@ -647,22 +647,6 @@ GameObjectInfo const *GameObject::GetGOInfo() const
return m_goInfo;
}
uint32 GameObject::GetLootId(GameObjectInfo const* ginfo)
{
if (!ginfo)
return 0;
switch(ginfo->type)
{
case GAMEOBJECT_TYPE_CHEST:
return ginfo->chest.lootId;
case GAMEOBJECT_TYPE_FISHINGHOLE:
return ginfo->fishinghole.lootId;
default:
return 0;
}
}
/*********************************************************/
/*** QUEST SYSTEM ***/
/*********************************************************/
@ -757,7 +741,7 @@ bool GameObject::ActivateToQuest( Player *pTarget)const
// scan GO chest with loot including quest items
case GAMEOBJECT_TYPE_CHEST:
{
if(LootTemplates_Gameobject.HaveQuestLootForPlayer(GetLootId(), pTarget))
if(LootTemplates_Gameobject.HaveQuestLootForPlayer(GetGOInfo()->GetLootId(), pTarget))
return true;
break;
}
@ -842,7 +826,7 @@ void GameObject::UseDoorOrButton(uint32 time_to_restore, bool alternative /* = f
return;
if(!time_to_restore)
time_to_restore = GetAutoCloseTime();
time_to_restore = GetGOInfo()->GetAutoCloseTime();
SwitchDoorOrButton(true,alternative);
SetLootState(GO_ACTIVATED);
@ -1294,7 +1278,7 @@ void GameObject::Use(Unit* user)
return;
}
Spell *spell = new Spell(spellCaster, spellInfo, triggered);
Spell *spell = new Spell(spellCaster, spellInfo, triggered,GetGUID());
// spell target is user of GO
SpellCastTargets targets;

View file

@ -397,6 +397,87 @@ struct GameObjectInfo
} raw;
};
uint32 ScriptId;
// helpers
bool IsDespawnAtAction() const
{
switch(type)
{
case GAMEOBJECT_TYPE_CHEST: return chest.consumable;
case GAMEOBJECT_TYPE_GOOBER: return goober.consumable;
default: return false;
}
}
uint32 GetLockId() const
{
switch(type)
{
case GAMEOBJECT_TYPE_DOOR: return door.lockId;
case GAMEOBJECT_TYPE_BUTTON: return button.lockId;
case GAMEOBJECT_TYPE_QUESTGIVER: return questgiver.lockId;
case GAMEOBJECT_TYPE_CHEST: return chest.lockId;
case GAMEOBJECT_TYPE_TRAP: return trap.lockId;
case GAMEOBJECT_TYPE_GOOBER: return goober.lockId;
case GAMEOBJECT_TYPE_AREADAMAGE: return areadamage.lockId;
case GAMEOBJECT_TYPE_CAMERA: return camera.lockId;
case GAMEOBJECT_TYPE_FLAGSTAND: return flagstand.lockId;
case GAMEOBJECT_TYPE_FISHINGHOLE:return fishinghole.lockId;
case GAMEOBJECT_TYPE_FLAGDROP: return flagdrop.lockId;
default: return 0;
}
}
bool GetDespawnPossibility() const // despawn at targeting of cast?
{
switch(type)
{
case GAMEOBJECT_TYPE_DOOR: return door.noDamageImmune;
case GAMEOBJECT_TYPE_BUTTON: return button.noDamageImmune;
case GAMEOBJECT_TYPE_QUESTGIVER: return questgiver.noDamageImmune;
case GAMEOBJECT_TYPE_GOOBER: return goober.noDamageImmune;
case GAMEOBJECT_TYPE_FLAGSTAND: return flagstand.noDamageImmune;
case GAMEOBJECT_TYPE_FLAGDROP: return flagdrop.noDamageImmune;
default: return true;
}
}
uint32 GetLinkedGameObjectEntry() const
{
switch(type)
{
case GAMEOBJECT_TYPE_CHEST: return chest.linkedTrapId;
case GAMEOBJECT_TYPE_SPELL_FOCUS: return spellFocus.linkedTrapId;
case GAMEOBJECT_TYPE_GOOBER: return goober.linkedTrapId;
default: return 0;
}
}
uint32 GetAutoCloseTime() const
{
uint32 autoCloseTime = 0;
switch(type)
{
case GAMEOBJECT_TYPE_DOOR: autoCloseTime = door.autoCloseTime; break;
case GAMEOBJECT_TYPE_BUTTON: autoCloseTime = button.autoCloseTime; break;
case GAMEOBJECT_TYPE_TRAP: autoCloseTime = trap.autoCloseTime; break;
case GAMEOBJECT_TYPE_GOOBER: autoCloseTime = goober.autoCloseTime; break;
case GAMEOBJECT_TYPE_TRANSPORT: autoCloseTime = transport.autoCloseTime; break;
case GAMEOBJECT_TYPE_AREADAMAGE: autoCloseTime = areadamage.autoCloseTime; break;
default: break;
}
return autoCloseTime / 0x10000;
}
uint32 GetLootId() const
{
switch(type)
{
case GAMEOBJECT_TYPE_CHEST: return chest.lootId;
case GAMEOBJECT_TYPE_FISHINGHOLE: return fishinghole.lootId;
default: return 0;
}
}
};
// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform
@ -500,40 +581,6 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask);
bool LoadFromDB(uint32 guid, Map *map);
void DeleteFromDB();
static uint32 GetLootId(GameObjectInfo const* info);
uint32 GetLootId() const { return GetLootId(GetGOInfo()); }
uint32 GetLockId() const
{
switch(GetGoType())
{
case GAMEOBJECT_TYPE_DOOR: return GetGOInfo()->door.lockId;
case GAMEOBJECT_TYPE_BUTTON: return GetGOInfo()->button.lockId;
case GAMEOBJECT_TYPE_QUESTGIVER: return GetGOInfo()->questgiver.lockId;
case GAMEOBJECT_TYPE_CHEST: return GetGOInfo()->chest.lockId;
case GAMEOBJECT_TYPE_TRAP: return GetGOInfo()->trap.lockId;
case GAMEOBJECT_TYPE_GOOBER: return GetGOInfo()->goober.lockId;
case GAMEOBJECT_TYPE_AREADAMAGE: return GetGOInfo()->areadamage.lockId;
case GAMEOBJECT_TYPE_CAMERA: return GetGOInfo()->camera.lockId;
case GAMEOBJECT_TYPE_FLAGSTAND: return GetGOInfo()->flagstand.lockId;
case GAMEOBJECT_TYPE_FISHINGHOLE:return GetGOInfo()->fishinghole.lockId;
case GAMEOBJECT_TYPE_FLAGDROP: return GetGOInfo()->flagdrop.lockId;
default: return 0;
}
}
bool GetDespawnPossibility() const
{
switch(GetGoType())
{
case GAMEOBJECT_TYPE_DOOR: return GetGOInfo()->door.noDamageImmune;
case GAMEOBJECT_TYPE_BUTTON: return GetGOInfo()->button.noDamageImmune;
case GAMEOBJECT_TYPE_QUESTGIVER: return GetGOInfo()->questgiver.noDamageImmune;
case GAMEOBJECT_TYPE_GOOBER: return GetGOInfo()->goober.noDamageImmune;
case GAMEOBJECT_TYPE_FLAGSTAND: return GetGOInfo()->flagstand.noDamageImmune;
case GAMEOBJECT_TYPE_FLAGDROP: return GetGOInfo()->flagdrop.noDamageImmune;
default: return true;
}
}
time_t GetRespawnTime() const { return m_respawnTime; }
time_t GetRespawnTimeEx() const
@ -603,34 +650,7 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
void UseDoorOrButton(uint32 time_to_restore = 0, bool alternative = false);
// 0 = use `gameobject`.`spawntimesecs`
void ResetDoorOrButton();
// 0 = use `gameobject`.`spawntimesecs`
uint32 GetLinkedGameObjectEntry() const
{
switch(GetGoType())
{
case GAMEOBJECT_TYPE_CHEST: return GetGOInfo()->chest.linkedTrapId;
case GAMEOBJECT_TYPE_SPELL_FOCUS: return GetGOInfo()->spellFocus.linkedTrapId;
case GAMEOBJECT_TYPE_GOOBER: return GetGOInfo()->goober.linkedTrapId;
default: return 0;
}
}
uint32 GetAutoCloseTime() const
{
uint32 autoCloseTime = 0;
switch(GetGoType())
{
case GAMEOBJECT_TYPE_DOOR: autoCloseTime = GetGOInfo()->door.autoCloseTime; break;
case GAMEOBJECT_TYPE_BUTTON: autoCloseTime = GetGOInfo()->button.autoCloseTime; break;
case GAMEOBJECT_TYPE_TRAP: autoCloseTime = GetGOInfo()->trap.autoCloseTime; break;
case GAMEOBJECT_TYPE_GOOBER: autoCloseTime = GetGOInfo()->goober.autoCloseTime; break;
case GAMEOBJECT_TYPE_TRANSPORT: autoCloseTime = GetGOInfo()->transport.autoCloseTime; break;
case GAMEOBJECT_TYPE_AREADAMAGE: autoCloseTime = GetGOInfo()->areadamage.autoCloseTime; break;
default: break;
}
return autoCloseTime / 0x10000;
}
void TriggeringLinkedGameObject( uint32 trapEntry, Unit* target);

View file

@ -3171,7 +3171,7 @@ bool ChatHandler::HandleLookupTaxiNodeCommand(const char * args)
}
}
if (counter == 0) // if counter == 0 then we found nth
SendSysMessage(LANG_COMMAND_NOSPELLFOUND);
SendSysMessage(LANG_COMMAND_NOTAXINODEFOUND);
return true;
}
@ -4085,57 +4085,6 @@ bool ChatHandler::HandleHideAreaCommand(const char* args)
return true;
}
bool ChatHandler::HandleDebugUpdate(const char* args)
{
if(!*args)
return false;
uint32 updateIndex;
uint32 value;
char* pUpdateIndex = strtok((char*)args, " ");
Unit* chr = getSelectedUnit();
if (chr == NULL)
{
SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
SetSentErrorMessage(true);
return false;
}
if(!pUpdateIndex)
{
return true;
}
updateIndex = atoi(pUpdateIndex);
//check updateIndex
if(chr->GetTypeId() == TYPEID_PLAYER)
{
if (updateIndex>=PLAYER_END) return true;
}
else
{
if (updateIndex>=UNIT_END) return true;
}
char* pvalue = strtok(NULL, " ");
if (!pvalue)
{
value=chr->GetUInt32Value(updateIndex);
PSendSysMessage(LANG_UPDATE, chr->GetGUIDLow(),updateIndex,value);
return true;
}
value=atoi(pvalue);
PSendSysMessage(LANG_UPDATE_CHANGE, chr->GetGUIDLow(),updateIndex,value);
chr->SetUInt32Value(updateIndex,value);
return true;
}
bool ChatHandler::HandleBankCommand(const char* /*args*/)
{
m_session->SendShowBank( m_session->GetPlayer()->GetGUID() );
@ -4185,106 +4134,6 @@ bool ChatHandler::HandleChangeWeather(const char* args)
return true;
}
bool ChatHandler::HandleDebugSetValue(const char* args)
{
if(!*args)
return false;
char* px = strtok((char*)args, " ");
char* py = strtok(NULL, " ");
char* pz = strtok(NULL, " ");
if (!px || !py)
return false;
Unit* target = getSelectedUnit();
if(!target)
{
SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
SetSentErrorMessage(true);
return false;
}
uint64 guid = target->GetGUID();
uint32 Opcode = (uint32)atoi(px);
if(Opcode >= target->GetValuesCount())
{
PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount());
return false;
}
uint32 iValue;
float fValue;
bool isint32 = true;
if(pz)
isint32 = (bool)atoi(pz);
if(isint32)
{
iValue = (uint32)atoi(py);
sLog.outDebug(GetMangosString(LANG_SET_UINT), GUID_LOPART(guid), Opcode, iValue);
target->SetUInt32Value( Opcode , iValue );
PSendSysMessage(LANG_SET_UINT_FIELD, GUID_LOPART(guid), Opcode,iValue);
}
else
{
fValue = (float)atof(py);
sLog.outDebug(GetMangosString(LANG_SET_FLOAT), GUID_LOPART(guid), Opcode, fValue);
target->SetFloatValue( Opcode , fValue );
PSendSysMessage(LANG_SET_FLOAT_FIELD, GUID_LOPART(guid), Opcode,fValue);
}
return true;
}
bool ChatHandler::HandleDebugGetValue(const char* args)
{
if(!*args)
return false;
char* px = strtok((char*)args, " ");
char* pz = strtok(NULL, " ");
if (!px)
return false;
Unit* target = getSelectedUnit();
if(!target)
{
SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
SetSentErrorMessage(true);
return false;
}
uint64 guid = target->GetGUID();
uint32 Opcode = (uint32)atoi(px);
if(Opcode >= target->GetValuesCount())
{
PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount());
return false;
}
uint32 iValue;
float fValue;
bool isint32 = true;
if(pz)
isint32 = (bool)atoi(pz);
if(isint32)
{
iValue = target->GetUInt32Value( Opcode );
sLog.outDebug(GetMangosString(LANG_GET_UINT), GUID_LOPART(guid), Opcode, iValue);
PSendSysMessage(LANG_GET_UINT_FIELD, GUID_LOPART(guid), Opcode, iValue);
}
else
{
fValue = target->GetFloatValue( Opcode );
sLog.outDebug(GetMangosString(LANG_GET_FLOAT), GUID_LOPART(guid), Opcode, fValue);
PSendSysMessage(LANG_GET_FLOAT_FIELD, GUID_LOPART(guid), Opcode, fValue);
}
return true;
}
bool ChatHandler::HandleSet32Bit(const char* args)
{
if(!*args)
@ -4309,38 +4158,6 @@ bool ChatHandler::HandleSet32Bit(const char* args)
return true;
}
bool ChatHandler::HandleDebugMod32Value(const char* args)
{
if(!*args)
return false;
char* px = strtok((char*)args, " ");
char* py = strtok(NULL, " ");
if (!px || !py)
return false;
uint32 Opcode = (uint32)atoi(px);
int Value = atoi(py);
if(Opcode >= m_session->GetPlayer()->GetValuesCount())
{
PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, m_session->GetPlayer()->GetGUIDLow(), m_session->GetPlayer( )->GetValuesCount());
return false;
}
sLog.outDebug(GetMangosString(LANG_CHANGE_32BIT), Opcode, Value);
int CurrentValue = (int)m_session->GetPlayer( )->GetUInt32Value( Opcode );
CurrentValue += Value;
m_session->GetPlayer( )->SetUInt32Value( Opcode , (uint32)CurrentValue );
PSendSysMessage(LANG_CHANGE_32BIT_FIELD, Opcode,CurrentValue);
return true;
}
bool ChatHandler::HandleTeleAddCommand(const char * args)
{
if(!*args)

View file

@ -1149,7 +1149,7 @@ void LoadLootTemplates_Gameobject()
{
if(GameObjectInfo const* gInfo = sGOStorage.LookupEntry<GameObjectInfo>(i))
{
if(uint32 lootid = GameObject::GetLootId(gInfo))
if(uint32 lootid = gInfo->GetLootId())
{
if(!ids_set.count(lootid))
LootTemplates_Gameobject.ReportNotExistedId(lootid);

View file

@ -124,14 +124,12 @@ void Map::LoadMap(int gx,int gy, bool reload)
if(GridMaps[gx][gy])
return;
Map* baseMap = const_cast<Map*>(MapManager::Instance().CreateBaseMap(i_id));
// load grid map for base map
if (!baseMap->GridMaps[gx][gy])
baseMap->EnsureGridCreated(GridPair(63-gx,63-gy));
if (!m_parentMap->GridMaps[gx][gy])
m_parentMap->EnsureGridCreated(GridPair(63-gx,63-gy));
((MapInstanced*)(baseMap))->AddGridMapReference(GridPair(gx,gy));
GridMaps[gx][gy] = baseMap->GridMaps[gx][gy];
((MapInstanced*)(m_parentMap))->AddGridMapReference(GridPair(gx,gy));
GridMaps[gx][gy] = m_parentMap->GridMaps[gx][gy];
return;
}
@ -184,11 +182,11 @@ void Map::DeleteStateMachine()
delete si_GridStates[GRID_STATE_REMOVAL];
}
Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode)
Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _parent)
: i_mapEntry (sMapStore.LookupEntry(id)), i_spawnMode(SpawnMode),
i_id(id), i_InstanceId(InstanceId), m_unloadTimer(0),
m_activeNonPlayersIter(m_activeNonPlayers.end()),
i_gridExpiry(expiry)
i_gridExpiry(expiry), m_parentMap(_parent ? _parent : this)
{
for(unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx)
{
@ -295,6 +293,13 @@ void Map::DeleteFromWorld(T* obj)
delete obj;
}
template<>
void Map::DeleteFromWorld(Player* pl)
{
ObjectAccessor::Instance().RemoveObject(pl);
delete pl;
}
template<class T>
void Map::AddNotifier(T* , Cell const& , CellPair const& )
{
@ -399,8 +404,7 @@ void Map::LoadGrid(const Cell& cell, bool no_unload)
bool Map::Add(Player *player)
{
player->GetMapRef().link(this, player);
player->SetInstanceId(GetInstanceId());
player->SetMap(this);
// update player state for other player and visa-versa
CellPair p = MaNGOS::ComputeCellPair(player->GetPositionX(), player->GetPositionY());
@ -431,6 +435,8 @@ Map::Add(T *obj)
return;
}
obj->SetMap(this);
Cell cell(p);
if(obj->isActiveObject())
EnsureGridLoadedAtEnter(cell);
@ -688,8 +694,12 @@ void Map::Remove(Player *player, bool remove)
CellPair p = MaNGOS::ComputeCellPair(player->GetPositionX(), player->GetPositionY());
if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
{
if(remove)
player->CleanupsBeforeDelete();
// invalid coordinates
player->RemoveFromWorld();
player->ResetMap();
if( remove )
DeleteFromWorld(player);
@ -709,13 +719,16 @@ void Map::Remove(Player *player, bool remove)
NGridType *grid = getNGrid(cell.GridX(), cell.GridY());
assert(grid != NULL);
if(remove)
player->CleanupsBeforeDelete();
player->RemoveFromWorld();
RemoveFromGrid(player,grid,cell);
SendRemoveTransports(player);
UpdateObjectsVisibilityFor(player,cell,p);
player->ResetMap();
if( remove )
DeleteFromWorld(player);
}
@ -760,6 +773,7 @@ Map::Remove(T *obj, bool remove)
UpdateObjectVisibility(obj,cell,p);
obj->ResetMap();
if( remove )
{
// if option set then object already saved at this moment
@ -1029,7 +1043,8 @@ bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool pForce)
VMAP::VMapFactory::createOrGetVMapManager()->unloadMap(GetId(), gy, gx);
}
else
((MapInstanced*)(MapManager::Instance().CreateBaseMap(i_id)))->RemoveGridMapReference(GridPair(gx, gy));
((MapInstanced*)m_parentMap)->RemoveGridMapReference(GridPair(gx, gy));
GridMaps[gx][gy] = NULL;
}
DEBUG_LOG("Unloading grid[%u,%u] for map %u finished", x,y, i_id);
@ -2196,8 +2211,8 @@ template void Map::Remove(DynamicObject *, bool);
/* ******* Dungeon Instance Maps ******* */
InstanceMap::InstanceMap(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode)
: Map(id, expiry, InstanceId, SpawnMode),
InstanceMap::InstanceMap(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _parent)
: Map(id, expiry, InstanceId, SpawnMode, _parent),
m_resetAfterUnload(false), m_unloadWhenEmpty(false),
i_data(NULL), i_script_id(0)
{
@ -2534,8 +2549,8 @@ uint32 InstanceMap::GetMaxPlayers() const
/* ******* Battleground Instance Maps ******* */
BattleGroundMap::BattleGroundMap(uint32 id, time_t expiry, uint32 InstanceId)
: Map(id, expiry, InstanceId, DUNGEON_DIFFICULTY_NORMAL)
BattleGroundMap::BattleGroundMap(uint32 id, time_t expiry, uint32 InstanceId, Map* _parent)
: Map(id, expiry, InstanceId, DUNGEON_DIFFICULTY_NORMAL, _parent)
{
}

View file

@ -245,7 +245,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
{
friend class MapReference;
public:
Map(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode);
Map(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode, Map* _parent = NULL);
virtual ~Map();
// currently unused for normal maps
@ -300,6 +300,8 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
static void InitStateMachine();
static void DeleteStateMachine();
Map const * GetParent() const { return m_parentMap; }
// some calls like isInWater should not use vmaps due to processor power
// can return INVALID_HEIGHT if under z+2 z coord not found height
float GetHeight(float x, float y, float z, bool pCheckVMap=true) const;
@ -461,6 +463,10 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
ActiveNonPlayers m_activeNonPlayers;
ActiveNonPlayers::iterator m_activeNonPlayersIter;
private:
//used for fast base_map (e.g. MapInstanced class object) search for
//InstanceMaps and BattleGroundMaps...
Map* m_parentMap;
typedef GridReadGuard ReadGuard;
typedef GridWriteGuard WriteGuard;
@ -520,7 +526,7 @@ enum InstanceResetMethod
class MANGOS_DLL_SPEC InstanceMap : public Map
{
public:
InstanceMap(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode);
InstanceMap(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode, Map* _parent);
~InstanceMap();
bool Add(Player *);
void Remove(Player *, bool);
@ -545,7 +551,7 @@ class MANGOS_DLL_SPEC InstanceMap : public Map
class MANGOS_DLL_SPEC BattleGroundMap : public Map
{
public:
BattleGroundMap(uint32 id, time_t, uint32 InstanceId);
BattleGroundMap(uint32 id, time_t, uint32 InstanceId, Map* _parent);
~BattleGroundMap();
bool Add(Player *);

View file

@ -108,84 +108,59 @@ void MapInstanced::UnloadAll(bool pForce)
- create the instance if it's not created already
- the player is not actually added to the instance (only in InstanceMap::Add)
*/
Map* MapInstanced::GetInstance(const WorldObject* obj)
Map* MapInstanced::CreateInstance(const uint32 mapId, Player * player)
{
uint32 CurInstanceId = obj->GetInstanceId();
Map* map = NULL;
if(GetId() != mapId || !player)
return NULL;
if (obj->GetMapId() == GetId() && CurInstanceId != 0)
Map* map = NULL;
uint32 NewInstanceId = 0; // instanceId of the resulting map
if(IsBattleGroundOrArena())
{
// the object wants to be put in a certain instance of this map
map = _FindMap(CurInstanceId);
// instantiate or find existing bg map for player
// the instance id is set in battlegroundid
NewInstanceId = player->GetBattleGroundId();
ASSERT(NewInstanceId);
map = _FindMap(NewInstanceId);
if(!map)
{
// For players if the instanceId is set, it's assumed they are already in a map,
// hence the map must be loaded. For Creatures, GameObjects etc the map must exist
// prior to calling GetMap, they are not allowed to create maps for themselves.
sLog.outError("GetInstance: object %s(%d), typeId %d, in world %d, should be in map %d,%d but that's not loaded yet.", obj->GetName(), obj->GetGUIDLow(), obj->GetTypeId(), obj->IsInWorld(), obj->GetMapId(), obj->GetInstanceId());
assert(false);
}
return(map);
map = CreateBattleGround(NewInstanceId);
}
else
{
// instance not specified, find an existing or create a new one
if(obj->GetTypeId() != TYPEID_PLAYER)
InstancePlayerBind *pBind = player->GetBoundInstance(GetId(), player->GetDungeonDifficulty());
InstanceSave *pSave = pBind ? pBind->save : NULL;
// the player's permanent player bind is taken into consideration first
// then the player's group bind and finally the solo bind.
if(!pBind || !pBind->perm)
{
sLog.outError("MAPINSTANCED: WorldObject '%u' (Entry: %u TypeID: %u) is in map %d,%d and requested base map instance of map %d, this must not happen", obj->GetGUIDLow(), obj->GetEntry(), obj->GetTypeId(), obj->GetMapId(), obj->GetInstanceId(), GetId());
assert(false);
return NULL;
InstanceGroupBind *groupBind = NULL;
Group *group = player->GetGroup();
// use the player's difficulty setting (it may not be the same as the group's)
if(group && (groupBind = group->GetBoundInstance(GetId(), player->GetDungeonDifficulty())))
pSave = groupBind->save;
}
if(pSave)
{
// solo/perm/group
NewInstanceId = pSave->GetInstanceId();
map = _FindMap(NewInstanceId);
// it is possible that the save exists but the map doesn't
if(!map)
map = CreateInstance(NewInstanceId, pSave, pSave->GetDifficulty());
}
else
{
uint32 NewInstanceId = 0; // instanceId of the resulting map
Player* player = (Player*)obj;
if(IsBattleGroundOrArena())
{
// instantiate or find existing bg map for player
// the instance id is set in battlegroundid
NewInstanceId = player->GetBattleGroundId();
assert(NewInstanceId);
map = _FindMap(NewInstanceId);
if(!map)
map = CreateBattleGround(NewInstanceId);
return map;
}
InstancePlayerBind *pBind = player->GetBoundInstance(GetId(), player->GetDungeonDifficulty());
InstanceSave *pSave = pBind ? pBind->save : NULL;
// the player's permanet player bind is taken into consideration first
// then the player's group bind and finally the solo bind.
if(!pBind || !pBind->perm)
{
InstanceGroupBind *groupBind = NULL;
Group *group = player->GetGroup();
// use the player's difficulty setting (it may not be the same as the group's)
if(group && (groupBind = group->GetBoundInstance(GetId(), player->GetDungeonDifficulty())))
pSave = groupBind->save;
}
if(pSave)
{
// solo/perm/group
NewInstanceId = pSave->GetInstanceId();
map = _FindMap(NewInstanceId);
// it is possible that the save exists but the map doesn't
if(!map)
map = CreateInstance(NewInstanceId, pSave, pSave->GetDifficulty());
return map;
}
else
{
// if no instanceId via group members or instance saves is found
// the instance will be created for the first time
NewInstanceId = MapManager::Instance().GenerateInstanceId();
return CreateInstance(NewInstanceId, NULL, player->GetDungeonDifficulty());
}
// if no instanceId via group members or instance saves is found
// the instance will be created for the first time
NewInstanceId = MapManager::Instance().GenerateInstanceId();
map = CreateInstance(NewInstanceId, NULL, player->GetDungeonDifficulty());
}
}
return map;
}
InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave *save, uint8 difficulty)
@ -210,10 +185,10 @@ InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave *save,
// some instances only have one difficulty
if (entry && !entry->SupportsHeroicMode()) difficulty = DUNGEON_DIFFICULTY_NORMAL;
sLog.outDebug("MapInstanced::CreateInstance: %smap instance %d for %d created with difficulty %s", save?"":"new ", InstanceId, GetId(), difficulty?"heroic":"normal");
sLog.outDebug("MapInstanced::CreateInstance: %s map instance %d for %d created with difficulty %s", save?"":"new ", InstanceId, GetId(), difficulty?"heroic":"normal");
InstanceMap *map = new InstanceMap(GetId(), GetGridExpiry(), InstanceId, difficulty);
assert(map->IsDungeon());
InstanceMap *map = new InstanceMap(GetId(), GetGridExpiry(), InstanceId, difficulty, this);
ASSERT(map->IsDungeon());
bool load_data = save != NULL;
map->CreateInstanceData(load_data);
@ -229,8 +204,8 @@ BattleGroundMap* MapInstanced::CreateBattleGround(uint32 InstanceId)
sLog.outDebug("MapInstanced::CreateBattleGround: map bg %d for %d created.", InstanceId, GetId());
BattleGroundMap *map = new BattleGroundMap(GetId(), GetGridExpiry(), InstanceId);
assert(map->IsBattleGroundOrArena());
BattleGroundMap *map = new BattleGroundMap(GetId(), GetGridExpiry(), InstanceId, this);
ASSERT(map->IsBattleGroundOrArena());
m_InstancedMaps[InstanceId] = map;
return map;

View file

@ -38,7 +38,7 @@ class MANGOS_DLL_DECL MapInstanced : public Map
bool RemoveBones(uint64 guid, float x, float y);
void UnloadAll(bool pForce);
Map* GetInstance(const WorldObject* obj);
Map* CreateInstance(const uint32 mapId, Player * player);
Map* FindMap(uint32 InstanceId) const { return _FindMap(InstanceId); }
void DestroyInstance(uint32 InstanceId);
void DestroyInstance(InstancedMaps::iterator &itr);

View file

@ -122,13 +122,13 @@ MapManager::_createBaseMap(uint32 id)
return m;
}
Map* MapManager::GetMap(uint32 id, const WorldObject* obj)
Map* MapManager::CreateMap(uint32 id, const WorldObject* obj)
{
ASSERT(obj);
//if(!obj->IsInWorld()) sLog.outError("GetMap: called for map %d with object (typeid %d, guid %d, mapid %d, instanceid %d) who is not in world!", id, obj->GetTypeId(), obj->GetGUIDLow(), obj->GetMapId(), obj->GetInstanceId());
Map *m = _createBaseMap(id);
if (m && obj && m->Instanceable()) m = ((MapInstanced*)m)->GetInstance(obj);
if (m && (obj->GetTypeId() == TYPEID_PLAYER) && m->Instanceable()) m = ((MapInstanced*)m)->CreateInstance(id, (Player*)obj);
return m;
}

View file

@ -37,7 +37,7 @@ class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton<MapManager, MaNGOS::
public:
Map* GetMap(uint32, const WorldObject* obj);
Map* CreateMap(uint32, const WorldObject* obj);
Map const* CreateBaseMap(uint32 id) const { return const_cast<MapManager*>(this)->_createBaseMap(id); }
Map* FindMap(uint32 mapid, uint32 instanceId = 0) const;

View file

@ -65,18 +65,17 @@ void WorldSession::HandleMoveWorldportAckOpcode()
GetPlayer()->SetSemaphoreTeleportFar(false);
// relocate the player to the teleport destination
GetPlayer()->SetMapId(loc.mapid);
GetPlayer()->SetMap(MapManager::Instance().CreateMap(loc.mapid, GetPlayer())); GetPlayer()->Relocate(loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation);
GetPlayer()->Relocate(loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation);
// since the MapId is set before the GetInstance call, the InstanceId must be set to 0
// to let GetInstance() determine the proper InstanceId based on the player's binds
GetPlayer()->SetInstanceId(0);
GetPlayer()->SendInitialPacketsBeforeAddToMap();
// the CanEnter checks are done in TeleporTo but conditions may change
// while the player is in transit, for example the map may get full
if(!GetPlayer()->GetMap()->Add(GetPlayer()))
{
//if player wasn't added to map, reset his map pointer!
GetPlayer()->ResetMap();
sLog.outDebug("WORLD: teleport of player %s (%d) to location %d, %f, %f, %f, %f failed", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation);
// teleport the player home
if(!GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation()))

View file

@ -1056,7 +1056,7 @@ bool Object::PrintIndexError(uint32 index, bool set) const
WorldObject::WorldObject()
: m_mapId(0), m_InstanceId(0), m_phaseMask(PHASEMASK_NORMAL),
m_positionX(0.0f), m_positionY(0.0f), m_positionZ(0.0f), m_orientation(0.0f)
m_positionX(0.0f), m_positionY(0.0f), m_positionZ(0.0f), m_orientation(0.0f), m_currMap(NULL)
{
}
@ -1064,11 +1064,9 @@ void WorldObject::CleanupsBeforeDelete()
{
}
void WorldObject::_Create( uint32 guidlow, HighGuid guidhigh, uint32 mapid, uint32 phaseMask )
void WorldObject::_Create( uint32 guidlow, HighGuid guidhigh, uint32 phaseMask )
{
Object::_Create(guidlow, 0, guidhigh);
m_mapId = mapid;
m_phaseMask = phaseMask;
}
@ -1545,14 +1543,19 @@ void WorldObject::SendObjectDeSpawnAnim(uint64 guid)
SendMessageToSet(&data, true);
}
Map* WorldObject::GetMap() const
void WorldObject::SetMap(Map * map)
{
return MapManager::Instance().GetMap(GetMapId(), this);
ASSERT(map);
m_currMap = map;
//lets save current map's Id/instanceId
m_mapId = map->GetId();
m_InstanceId = map->GetInstanceId();
}
Map const* WorldObject::GetBaseMap() const
{
return MapManager::Instance().CreateBaseMap(GetMapId());
ASSERT(m_currMap);
return m_currMap->GetParent();
}
void WorldObject::AddObjectToRemoveList()
@ -1564,7 +1567,6 @@ Creature* WorldObject::SummonCreature(uint32 id, float x, float y, float z, floa
{
TemporarySummon* pCreature = new TemporarySummon(GetGUID());
pCreature->SetInstanceId(GetInstanceId());
uint32 team = 0;
if (GetTypeId()==TYPEID_PLAYER)
team = ((Player*)this)->GetTeam();

View file

@ -346,7 +346,7 @@ class MANGOS_DLL_SPEC WorldObject : public Object
virtual void Update ( uint32 /*time_diff*/ ) { }
void _Create( uint32 guidlow, HighGuid guidhigh, uint32 mapid, uint32 phaseMask);
void _Create( uint32 guidlow, HighGuid guidhigh, uint32 phaseMask);
void Relocate(float x, float y, float z, float orientation)
{
@ -395,8 +395,8 @@ class MANGOS_DLL_SPEC WorldObject : public Object
void GetRandomPoint( float x, float y, float z, float distance, float &rand_x, float &rand_y, float &rand_z ) const;
void SetMapId(uint32 newMap) { m_mapId = newMap; }
uint32 GetMapId() const { return m_mapId; }
uint32 GetInstanceId() const { return m_InstanceId; }
virtual void SetPhaseMask(uint32 newPhaseMask, bool update);
uint32 GetPhaseMask() const { return m_phaseMask; }
@ -421,8 +421,7 @@ class MANGOS_DLL_SPEC WorldObject : public Object
float GetDistanceZ(const WorldObject* obj) const;
bool IsInMap(const WorldObject* obj) const
{
return IsInWorld() && obj->IsInWorld() && GetMapId()==obj->GetMapId() &&
GetInstanceId()==obj->GetInstanceId() && InSamePhase(obj);
return IsInWorld() && obj->IsInWorld() && (GetMap() == obj->GetMap()) && InSamePhase(obj);
}
bool IsWithinDist3d(float x, float y, float z, float dist2compare) const;
bool IsWithinDist2d(float x, float y, float dist2compare) const;
@ -469,10 +468,6 @@ class MANGOS_DLL_SPEC WorldObject : public Object
void SendObjectDeSpawnAnim(uint64 guid);
virtual void SaveRespawnTime() {}
uint32 GetInstanceId() const { return m_InstanceId; }
void SetInstanceId(uint32 val) { m_InstanceId = val; }
void AddObjectToRemoveList();
// main visibility check function in normal case (ignore grey zone distance check)
@ -481,15 +476,29 @@ class MANGOS_DLL_SPEC WorldObject : public Object
// low level function for visibility change code, must be define in all main world object subclasses
virtual bool isVisibleForInState(Player const* u, bool inVisibleList) const = 0;
Map * GetMap() const;
void SetMap(Map * map);
Map * GetMap() const { ASSERT(m_currMap); return m_currMap; }
//used to check all object's GetMap() calls when object is not in world!
void ResetMap() { m_currMap = NULL; }
//this function should be removed in nearest time...
Map const* GetBaseMap() const;
Creature* SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime);
protected:
explicit WorldObject();
std::string m_name;
//these functions are used mostly for Relocate() and Corpse/Player specific stuff...
//use them ONLY in LoadFromDB()/Create() funcs and nowhere else!
//mapId/instanceId should be set in SetMap() function!
void SetLocationMapId(uint32 _mapId) { m_mapId = _mapId; }
void SetLocationInstanceId(uint32 _instanceId) { m_InstanceId = _instanceId; }
private:
Map * m_currMap; //current object's Map location
uint32 m_mapId; // object at map with map_id
uint32 m_InstanceId; // in map copy with instance id
uint32 m_phaseMask; // in area phase state

View file

@ -363,8 +363,6 @@ ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid, bool insignia)
// bones->m_inWorld = m_inWorld; // don't overwrite world state
// bones->m_type = m_type; // don't overwrite type
bones->Relocate(corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ(), corpse->GetOrientation());
bones->SetMapId(corpse->GetMapId());
bones->SetInstanceId(corpse->GetInstanceId());
bones->SetPhaseMask(corpse->GetPhaseMask(), false);
bones->SetUInt32Value(CORPSE_FIELD_FLAGS, CORPSE_FLAG_UNK2 | CORPSE_FLAG_BONES);

View file

@ -123,6 +123,7 @@ void LoadHelper(CellGuidSet const& guid_set, CellPair &cell, GridRefManager<T> &
obj->GetGridRef().link(&m, obj);
addUnitState(obj,cell);
obj->SetMap(map);
obj->AddToWorld();
if(obj->isActiveObject())
map->AddToActive(obj);
@ -151,6 +152,7 @@ void LoadHelper(CellCorpseSet const& cell_corpses, CellPair &cell, CorpseMapType
obj->GetGridRef().link(&m, obj);
addUnitState(obj,cell);
obj->SetMap(map);
obj->AddToWorld();
if(obj->isActiveObject())
map->AddToActive(obj);

View file

@ -800,67 +800,59 @@ void ObjectMgr::ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const*
endAura.effect_idx = 0;
}
void ObjectMgr::LoadCreatureAddons(SQLStorage& creatureaddons, char const* entryName, char const* comment)
{
creatureaddons.Load();
sLog.outString(">> Loaded %u %s", creatureaddons.RecordCount, comment);
sLog.outString();
// check data correctness and convert 'auras'
for(uint32 i = 1; i < creatureaddons.MaxEntry; ++i)
{
CreatureDataAddon const* addon = creatureaddons.LookupEntry<CreatureDataAddon>(i);
if(!addon)
continue;
if (addon->mount)
{
if (!sCreatureDisplayInfoStore.LookupEntry(addon->mount))
{
sLog.outErrorDb("Creature (%s %u) have invalid displayInfoId for mount (%u) defined in `%s`.", entryName, addon->guidOrEntry, addon->mount, creatureaddons.GetTableName());
const_cast<CreatureDataAddon*>(addon)->mount = 0;
}
}
if (!sEmotesStore.LookupEntry(addon->emote))
sLog.outErrorDb("Creature (%s %u) have invalid emote (%u) defined in `%s`.", entryName, addon->guidOrEntry, addon->emote, creatureaddons.GetTableName());
if (addon->move_flags & (MONSTER_MOVE_UNK1|MONSTER_MOVE_UNK4))
{
sLog.outErrorDb("Creature (%s %u) movement flags mask defined in `%s` include forbidden flags (" I32FMT ") that can crash client, cleanup at load.", entryName, addon->guidOrEntry, creatureaddons.GetTableName(), (MONSTER_MOVE_UNK1|MONSTER_MOVE_UNK4));
const_cast<CreatureDataAddon*>(addon)->move_flags &= ~(MONSTER_MOVE_UNK1|MONSTER_MOVE_UNK4);
}
ConvertCreatureAddonAuras(const_cast<CreatureDataAddon*>(addon), creatureaddons.GetTableName(), entryName);
}
}
void ObjectMgr::LoadCreatureAddons()
{
sCreatureInfoAddonStorage.Load();
LoadCreatureAddons(sCreatureInfoAddonStorage,"Entry","creature template addons");
sLog.outString( ">> Loaded %u creature template addons", sCreatureInfoAddonStorage.RecordCount );
sLog.outString();
// check data correctness and convert 'auras'
// check entry ids
for(uint32 i = 1; i < sCreatureInfoAddonStorage.MaxEntry; ++i)
{
CreatureDataAddon const* addon = sCreatureInfoAddonStorage.LookupEntry<CreatureDataAddon>(i);
if(!addon)
continue;
if(CreatureDataAddon const* addon = sCreatureInfoAddonStorage.LookupEntry<CreatureDataAddon>(i))
if(!sCreatureStorage.LookupEntry<CreatureInfo>(addon->guidOrEntry))
sLog.outErrorDb("Creature (Entry: %u) does not exist but has a record in `%s`",addon->guidOrEntry, sCreatureInfoAddonStorage.GetTableName());
if (addon->mount)
{
if (!sCreatureDisplayInfoStore.LookupEntry(addon->mount))
{
sLog.outErrorDb("Creature (Entry %u) have invalid displayInfoId for mount (%u) defined in `creature_template_addon`.",addon->guidOrEntry, addon->mount);
const_cast<CreatureDataAddon*>(addon)->mount = 0;
}
}
LoadCreatureAddons(sCreatureDataAddonStorage,"GUID","creature addons");
if (!sEmotesStore.LookupEntry(addon->emote))
sLog.outErrorDb("Creature (Entry %u) have invalid emote (%u) defined in `creature_template_addon`.",addon->guidOrEntry, addon->emote);
ConvertCreatureAddonAuras(const_cast<CreatureDataAddon*>(addon), "creature_template_addon", "Entry");
if(!sCreatureStorage.LookupEntry<CreatureInfo>(addon->guidOrEntry))
sLog.outErrorDb("Creature (Entry: %u) does not exist but has a record in `creature_template_addon`",addon->guidOrEntry);
}
sCreatureDataAddonStorage.Load();
sLog.outString( ">> Loaded %u creature addons", sCreatureDataAddonStorage.RecordCount );
sLog.outString();
// check data correctness and convert 'auras'
// check entry ids
for(uint32 i = 1; i < sCreatureDataAddonStorage.MaxEntry; ++i)
{
CreatureDataAddon const* addon = sCreatureDataAddonStorage.LookupEntry<CreatureDataAddon>(i);
if(!addon)
continue;
if (addon->mount)
{
if (!sCreatureDisplayInfoStore.LookupEntry(addon->mount))
{
sLog.outErrorDb("Creature (GUID %u) have invalid displayInfoId for mount (%u) defined in `creature_addon`.",addon->guidOrEntry, addon->mount);
const_cast<CreatureDataAddon*>(addon)->mount = 0;
}
}
if (!sEmotesStore.LookupEntry(addon->emote))
sLog.outErrorDb("Creature (GUID %u) have invalid emote (%u) defined in `creature_addon`.",addon->guidOrEntry, addon->emote);
ConvertCreatureAddonAuras(const_cast<CreatureDataAddon*>(addon), "creature_addon", "GUIDLow");
if(mCreatureDataMap.find(addon->guidOrEntry)==mCreatureDataMap.end())
sLog.outErrorDb("Creature (GUID: %u) does not exist but has a record in `creature_addon`",addon->guidOrEntry);
}
if(CreatureDataAddon const* addon = sCreatureDataAddonStorage.LookupEntry<CreatureDataAddon>(i))
if(mCreatureDataMap.find(addon->guidOrEntry)==mCreatureDataMap.end())
sLog.outErrorDb("Creature (GUID: %u) does not exist but has a record in `creature_addon`",addon->guidOrEntry);
}
EquipmentInfo const* ObjectMgr::GetEquipmentInfo(uint32 entry)
@ -1238,6 +1230,12 @@ void ObjectMgr::LoadGameobjects()
data.rotation2 = fields[ 9].GetFloat();
data.rotation3 = fields[10].GetFloat();
data.spawntimesecs = fields[11].GetInt32();
if (data.spawntimesecs==0 && gInfo->IsDespawnAtAction())
{
sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) with `spawntimesecs` (0) value, but gameobejct marked as despawnable at action.",guid,data.id);
}
data.animprogress = fields[12].GetUInt32();
uint32 go_state = fields[13].GetUInt32();
@ -5725,6 +5723,16 @@ inline void CheckGONoDamageImmuneId(GameObjectInfo const* goInfo,uint32 dataN,ui
goInfo->id,goInfo->type,N,dataN);
}
inline void CheckGOConsumable(GameObjectInfo const* goInfo,uint32 dataN,uint32 N)
{
// 0/1 correct values
if (dataN <= 1)
return;
sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data%d=%u but expected boolean (0/1) consumable field value.",
goInfo->id,goInfo->type,N,dataN);
}
void ObjectMgr::LoadGameobjectInfo()
{
SQLGameObjectLoader loader;
@ -5767,6 +5775,8 @@ void ObjectMgr::LoadGameobjectInfo()
if (goInfo->chest.lockId)
CheckGOLockId(goInfo,goInfo->chest.lockId,0);
CheckGOConsumable(goInfo,goInfo->chest.consumable,3);
if (goInfo->chest.linkedTrapId) // linked trap
CheckGOLinkedTrapId(goInfo,goInfo->chest.linkedTrapId,7);
break;
@ -5802,6 +5812,8 @@ void ObjectMgr::LoadGameobjectInfo()
if (goInfo->goober.lockId)
CheckGOLockId(goInfo,goInfo->goober.lockId,0);
CheckGOConsumable(goInfo,goInfo->goober.consumable,3);
if (goInfo->goober.pageId) // pageId
{
if (!sPageTextStore.LookupEntry<PageText>(goInfo->goober.pageId))
@ -6765,7 +6777,7 @@ void ObjectMgr::LoadGameObjectForQuests()
// scan GO chest with loot including quest items
case GAMEOBJECT_TYPE_CHEST:
{
uint32 loot_id = GameObject::GetLootId(goInfo);
uint32 loot_id = goInfo->GetLootId();
// find quest loot for GO
if(LootTemplates_Gameobject.HaveQuestLootFor(loot_id))

View file

@ -844,6 +844,7 @@ class ObjectMgr
private:
void LoadScripts(ScriptMapMap& scripts, char const* tablename);
void CheckScripts(ScriptMapMap const& scripts,std::set<int32>& ids);
void LoadCreatureAddons(SQLStorage& creatureaddons, char const* entryName, char const* comment);
void ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* table, char const* guidEntryStr);
void LoadQuestRelationsHelper(QuestRelations& map,char const* table);

View file

@ -744,9 +744,6 @@ bool Pet::CreateBaseAtCreature(Creature* creature)
}
uint32 guid=objmgr.GenerateLowGuid(HIGHGUID_PET);
sLog.outBasic("SetInstanceID()");
SetInstanceId(creature->GetInstanceId());
sLog.outBasic("Create pet");
uint32 pet_number = objmgr.GeneratePetNumber();
if(!Create(guid, creature->GetMap(), creature->GetPhaseMask(), creature->GetEntry(), pet_number))
@ -1841,8 +1838,7 @@ bool Pet::IsPermanentPetFor(Player* owner)
bool Pet::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 pet_number)
{
SetMapId(map->GetId());
SetInstanceId(map->GetInstanceId());
SetMap(map);
SetPhaseMask(phaseMask,false);
Object::_Create(guidlow, pet_number, HIGHGUID_PET);

View file

@ -541,7 +541,7 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
for (int i = 0; i < PLAYER_SLOTS_COUNT; ++i)
m_items[i] = NULL;
SetMapId(info->mapId);
SetLocationMapId(info->mapId);
Relocate(info->positionX,info->positionY,info->positionZ);
ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(class_);
@ -551,6 +551,8 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
return false;
}
SetMap(MapManager::Instance().CreateMap(info->mapId, this));
uint8 powertype = cEntry->powerType;
SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE);
@ -1496,7 +1498,12 @@ bool Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )
uint32 enchants = GetUInt32ValueFromArray(data, visualbase + 1);
for(uint8 enchantSlot = PERM_ENCHANTMENT_SLOT; enchantSlot <= TEMP_ENCHANTMENT_SLOT; ++enchantSlot)
{
if(enchant = sSpellItemEnchantmentStore.LookupEntry(enchants >> enchantSlot*16))
// values stored in 2 uint16
uint32 enchantId = 0x0000FFFF & (enchants >> enchantSlot*16);
if(!enchantId)
continue;
if(enchant = sSpellItemEnchantmentStore.LookupEntry(enchantId))
break;
}
@ -7334,7 +7341,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
if (go->getLootState() == GO_READY)
{
uint32 lootid = go->GetLootId();
uint32 lootid = go->GetGOInfo()->GetLootId();
if (lootid)
{
@ -12027,7 +12034,11 @@ void Player::PrepareQuestMenu( uint64 guid )
}
else
{
GameObject *pGameObject = GetMap()->GetGameObject(guid);
//we should obtain map pointer from GetMap() in 99% of cases. Special case
//only for quests which cast teleport spells on player
Map * _map = IsInWorld() ? GetMap() : MapManager::Instance().FindMap(GetMapId(), GetInstanceId());
ASSERT(_map);
GameObject *pGameObject = _map->GetGameObject(guid);
if( pGameObject )
{
pObject = (Object*)pGameObject;
@ -12536,12 +12547,12 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver
if (pQuest->GetRewChoiceItemsCount() > 0)
{
if (pQuest->RewChoiceItemId[reward])
if (uint32 itemId = pQuest->RewChoiceItemId[reward])
{
ItemPosCountVec dest;
if (CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, pQuest->RewChoiceItemId[reward], pQuest->RewChoiceItemCount[reward] ) == EQUIP_ERR_OK)
if (CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, itemId, pQuest->RewChoiceItemCount[reward] ) == EQUIP_ERR_OK)
{
Item* item = StoreNewItem( dest, pQuest->RewChoiceItemId[reward], true);
Item* item = StoreNewItem( dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId));
SendNewItem(item, pQuest->RewChoiceItemCount[reward], true, false);
}
}
@ -12551,12 +12562,12 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver
{
for (uint32 i=0; i < pQuest->GetRewItemsCount(); ++i)
{
if (pQuest->RewItemId[i])
if (uint32 itemId = pQuest->RewItemId[i])
{
ItemPosCountVec dest;
if (CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, pQuest->RewItemId[i], pQuest->RewItemCount[i] ) == EQUIP_ERR_OK)
if (CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, itemId, pQuest->RewItemCount[i] ) == EQUIP_ERR_OK)
{
Item* item = StoreNewItem( dest, pQuest->RewItemId[i], true);
Item* item = StoreNewItem( dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId));
SendNewItem(item, pQuest->RewItemCount[i], true, false);
}
}
@ -13825,7 +13836,8 @@ bool Player::MinimalLoadFromDB( QueryResult *result, uint32 guid )
m_name = fields[2].GetCppString();
Relocate(fields[3].GetFloat(),fields[4].GetFloat(),fields[5].GetFloat());
SetMapId(fields[6].GetUInt32());
SetLocationMapId(fields[6].GetUInt32());
// the instance id is not needed at character enum
m_Played_time[0] = fields[7].GetUInt32();
@ -14106,7 +14118,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
// init saved position, and fix it later if problematic
uint32 transGUID = fields[31].GetUInt32();
Relocate(fields[13].GetFloat(),fields[14].GetFloat(),fields[15].GetFloat(),fields[17].GetFloat());
SetMapId(fields[16].GetUInt32());
SetLocationMapId(fields[16].GetUInt32());
SetDungeonDifficulty(fields[39].GetUInt32()); // may be changed in _LoadGroup
_LoadGroup(holder->GetResult(PLAYER_LOGIN_QUERY_LOADGROUP));
@ -14181,7 +14193,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
else
{
const WorldLocation& _loc = GetBattleGroundEntryPoint();
SetMapId(_loc.mapid);
SetLocationMapId(_loc.mapid);
Relocate(_loc.coord_x, _loc.coord_y, _loc.coord_z, _loc.orientation);
//RemoveArenaAuras(true);
}
@ -14194,7 +14206,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
if(!mapEntry || mapEntry->IsBattleGroundOrArena())
{
// return to BG master
SetMapId(fields[43].GetUInt32());
SetLocationMapId(fields[43].GetUInt32());
Relocate(fields[44].GetFloat(),fields[45].GetFloat(),fields[46].GetFloat(),fields[47].GetFloat());
// check entry point and fix to homebind if need
@ -14248,7 +14260,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
m_transport = *iter;
m_transport->AddPassenger(this);
SetMapId(m_transport->GetMapId());
SetLocationMapId(m_transport->GetMapId());
break;
}
}
@ -14281,11 +14293,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
// NOW player must have valid map
// load the player's map here if it's not already loaded
Map *map = GetMap();
// since the player may not be bound to the map yet, make sure subsequent
// getmap calls won't create new maps
SetInstanceId(map->GetInstanceId());
SetMap(MapManager::Instance().CreateMap(GetMapId(), this));
// if the player is in an instance and it has been reset in the meantime teleport him to the entrance
if(GetInstanceId() && !sInstanceSaveManager.GetInstanceSave(GetInstanceId()))
@ -14463,15 +14471,19 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
{
sLog.outError("Character %u have wrong data in taxi destination list, teleport to homebind.",GetGUIDLow());
RelocateToHomebind();
SaveRecallPosition(); // save as recall also to prevent recall and fall from sky
}
else // have start node, to it
{
sLog.outError("Character %u have too short taxi destination list, teleport to original node.",GetGUIDLow());
SetMapId(nodeEntry->map_id);
SetLocationMapId(nodeEntry->map_id);
Relocate(nodeEntry->x, nodeEntry->y, nodeEntry->z,0.0f);
SaveRecallPosition(); // save as recall also to prevent recall and fall from sky
}
//we can be relocated from taxi and still have an outdated Map pointer!
//so we need to get a new Map pointer!
SetMap(MapManager::Instance().CreateMap(GetMapId(), this));
SaveRecallPosition(); // save as recall also to prevent recall and fall from sky
m_taxi.ClearTaxiDestinations();
}
else if(uint32 node_id = m_taxi.GetTaxiSource())
@ -19600,7 +19612,8 @@ uint32 Player::CalculateTalentsPoints() const
if(getClass() != CLASS_DEATH_KNIGHT)
return uint32(base_talent * sWorld.getRate(RATE_TALENT));
uint32 talentPointsForLevel = getLevel() < 56 ? 0 : getLevel() - 55 + m_questRewardTalentCount;
uint32 talentPointsForLevel = getLevel() < 56 ? 0 : getLevel() - 55;
talentPointsForLevel += m_questRewardTalentCount;
if(talentPointsForLevel > base_talent)
talentPointsForLevel = base_talent;

View file

@ -2091,7 +2091,7 @@ class MANGOS_DLL_SPEC Player : public Unit
float m_homebindX;
float m_homebindY;
float m_homebindZ;
void RelocateToHomebind() { SetMapId(m_homebindMapId); Relocate(m_homebindX,m_homebindY,m_homebindZ); }
void RelocateToHomebind() { SetLocationMapId(m_homebindMapId); Relocate(m_homebindX,m_homebindY,m_homebindZ); }
// currently visible objects at player client
typedef std::set<uint64> ClientGUIDs;

View file

@ -1431,10 +1431,8 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap)
case TARGET_AREAEFFECT_CUSTOM:
case TARGET_AREAEFFECT_CUSTOM_2:
case TARGET_SUMMON:
{
TagUnitMap.push_back(m_caster);
break;
}
case TARGET_RANDOM_ENEMY_CHAIN_IN_AREA:
{
m_targets.m_targetMask = 0;
@ -1506,7 +1504,8 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap)
--t;
}
}break;
break;
}
case TARGET_RANDOM_FRIEND_CHAIN_IN_AREA:
{
m_targets.m_targetMask = 0;
@ -1573,7 +1572,8 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap)
next = tempUnitMap.begin();
--t;
}
}break;
break;
}
case TARGET_PET:
{
Pet* tmpUnit = m_caster->GetPet();
@ -1653,12 +1653,11 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap)
--t;
}
}
}break;
case TARGET_ALL_ENEMY_IN_AREA:
{
FillAreaTargets(TagUnitMap,m_targets.m_destX, m_targets.m_destY,radius,PUSH_DEST_CENTER,SPELL_TARGETS_AOE_DAMAGE);
break;
}
case TARGET_ALL_ENEMY_IN_AREA:
FillAreaTargets(TagUnitMap,m_targets.m_destX, m_targets.m_destY,radius,PUSH_DEST_CENTER,SPELL_TARGETS_AOE_DAMAGE);
break;
case TARGET_AREAEFFECT_INSTANT:
{
SpellTargets targetB = SPELL_TARGETS_AOE_DAMAGE;
@ -1670,6 +1669,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap)
// exclude caster
TagUnitMap.remove(m_caster);
break;
}
case TARGET_ALL_ENEMY_IN_AREA_INSTANT:
{
@ -1681,7 +1681,8 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap)
// exclude caster (this can be important if this not original caster)
TagUnitMap.remove(m_caster);
}
}break;
break;
}
case TARGET_DUELVSPLAYER_COORDINATES:
{
if(Unit* currentTarget = m_targets.getUnitTarget())
@ -1689,7 +1690,8 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap)
m_targets.setDestination(currentTarget->GetPositionX(), currentTarget->GetPositionY(), currentTarget->GetPositionZ());
TagUnitMap.push_back(currentTarget);
}
}break;
break;
}
case TARGET_ALL_PARTY_AROUND_CASTER:
case TARGET_ALL_PARTY_AROUND_CASTER_2:
case TARGET_ALL_PARTY:
@ -1707,16 +1709,14 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap)
}
case TARGET_SINGLE_FRIEND:
case TARGET_SINGLE_FRIEND_2:
{
if(m_targets.getUnitTarget())
TagUnitMap.push_back(m_targets.getUnitTarget());
}break;
break;
case TARGET_NONCOMBAT_PET:
{
if(Unit* target = m_targets.getUnitTarget())
if( target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isPet() && ((Pet*)target)->getPetType() == MINI_PET)
TagUnitMap.push_back(target);
}break;
break;
case TARGET_CASTER_COORDINATES:
{
// Check original caster is GO - set its coordinates as dst cast
@ -1727,7 +1727,8 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap)
caster = m_caster;
// Set dest for targets
m_targets.setDestination(caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ());
}break;
break;
}
case TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER:
// special target order
if (m_spellInfo->Id==64904) // Hymn of Hope
@ -1793,12 +1794,12 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap)
}
}
}
}break;
break;
}
case TARGET_GAMEOBJECT:
{
if(m_targets.getGOTarget())
AddGOTarget(m_targets.getGOTarget(), i);
}break;
break;
case TARGET_IN_FRONT_OF_CASTER:
{
bool inFront = m_spellInfo->SpellVisual[0] != 3879;
@ -1823,33 +1824,27 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap)
}
}
}
}break;
break;
}
case TARGET_GAMEOBJECT_ITEM:
{
if(m_targets.getGOTargetGUID())
AddGOTarget(m_targets.getGOTarget(), i);
else if(m_targets.getItemTarget())
AddItemTarget(m_targets.getItemTarget(), i);
break;
}
case TARGET_MASTER:
{
if(Unit* owner = m_caster->GetCharmerOrOwner())
TagUnitMap.push_back(owner);
break;
}
case TARGET_ALL_ENEMY_IN_AREA_CHANNELED:
{
// targets the ground, not the units in the area
if (m_spellInfo->Effect[i]!=SPELL_EFFECT_PERSISTENT_AREA_AURA)
FillAreaTargets(TagUnitMap, m_targets.m_destX, m_targets.m_destY, radius, PUSH_DEST_CENTER, SPELL_TARGETS_AOE_DAMAGE);
break;
}
case TARGET_MINION:
{
if(m_spellInfo->Effect[i] != SPELL_EFFECT_DUEL)
TagUnitMap.push_back(m_caster);
}break;
break;
case TARGET_SINGLE_ENEMY:
{
if(Unit* pUnitTarget = m_caster->SelectMagnetTarget(m_targets.getUnitTarget(), m_spellInfo))
@ -1857,7 +1852,8 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap)
m_targets.setUnitTarget(pUnitTarget);
TagUnitMap.push_back(pUnitTarget);
}
}break;
break;
}
case TARGET_AREAEFFECT_PARTY:
{
Unit* owner = m_caster->GetCharmerOrOwner();
@ -1922,19 +1918,19 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap)
if( m_caster->IsWithinDistInMap(pet, radius) )
TagUnitMap.push_back(pet);
}
}break;
break;
}
case TARGET_SCRIPT:
{
if(m_targets.getUnitTarget())
TagUnitMap.push_back(m_targets.getUnitTarget());
if(m_targets.getItemTarget())
AddItemTarget(m_targets.getItemTarget(), i);
}break;
break;
}
case TARGET_SELF_FISHING:
{
TagUnitMap.push_back(m_caster);
}break;
break;
case TARGET_CHAIN_HEAL:
{
Unit* pUnitTarget = m_targets.getUnitTarget();
@ -1994,7 +1990,8 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap)
--t;
}
}
}break;
break;
}
case TARGET_CURRENT_ENEMY_COORDINATES:
{
Unit* currentTarget = m_targets.getUnitTarget();
@ -2044,7 +2041,8 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap)
}
else
sLog.outError( "SPELL: unknown target coordinates for spell ID %u", m_spellInfo->Id );
}break;
break;
}
case TARGET_BEHIND_VICTIM:
{
Unit *pTarget = NULL;
@ -2071,12 +2069,10 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap)
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;
}
case TARGET_DIRECTLY_FORWARD:
{
if (!(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION))
@ -4215,7 +4211,7 @@ SpellCastResult Spell::CheckCast(bool strict)
uint32 lockId = 0;
if (GameObject* go = m_targets.getGOTarget())
{
lockId = go->GetLockId();
lockId = go->GetGOInfo()->GetLockId();
if (!lockId)
return SPELL_FAILED_BAD_TARGETS;
}

View file

@ -1190,24 +1190,23 @@ void Aura::SendAuraUpdate(bool remove)
void Aura::SetStackAmount(uint8 stackAmount)
{
if (stackAmount == m_stackAmount)
// Nothing changed
return;
Unit *target = GetTarget();
Unit *caster = GetCaster();
if (!target || !caster)
return;
bool refresh = stackAmount > m_stackAmount;
m_stackAmount = stackAmount;
int32 amount = m_stackAmount * caster->CalculateSpellDamage(m_spellProto, m_effIndex, m_currentBasePoints, target);
// Reapply if amount change
if (amount!=m_modifier.m_amount)
bool refresh = stackAmount >= m_stackAmount;
if (stackAmount != m_stackAmount)
{
ApplyModifier(false, true);
m_modifier.m_amount = amount;
ApplyModifier(true, true);
m_stackAmount = stackAmount;
int32 amount = m_stackAmount * caster->CalculateSpellDamage(m_spellProto, m_effIndex, m_currentBasePoints, target);
// Reapply if amount change
if (amount!=m_modifier.m_amount)
{
ApplyModifier(false, true);
m_modifier.m_amount = amount;
ApplyModifier(true, true);
}
}
if (refresh)
@ -3802,15 +3801,15 @@ void Aura::HandleAuraModSilence(bool apply, bool Real)
void Aura::HandleModThreat(bool apply, bool Real)
{
// only at real add/remove aura
if(!Real)
if (!Real)
return;
if(!m_target->isAlive())
if (!m_target->isAlive())
return;
Unit* caster = GetCaster();
if(!caster || !caster->isAlive())
if (!caster || !caster->isAlive())
return;
int level_diff = 0;
@ -3828,38 +3827,31 @@ void Aura::HandleModThreat(bool apply, bool Real)
multiplier = 1;
break;
}
if (level_diff > 0)
m_modifier.m_amount += multiplier * level_diff;
for(int8 x=0;x < MAX_SPELL_SCHOOL;x++)
{
if(m_modifier.m_miscvalue & int32(1<<x))
{
if(m_target->GetTypeId() == TYPEID_PLAYER)
ApplyPercentModFloatVar(m_target->m_threatModifier[x], m_positive ? m_modifier.m_amount : -m_modifier.m_amount, apply);
}
}
if (m_target->GetTypeId() == TYPEID_PLAYER)
for(int8 x=0;x < MAX_SPELL_SCHOOL;x++)
if (m_modifier.m_miscvalue & int32(1<<x))
ApplyPercentModFloatVar(m_target->m_threatModifier[x], m_modifier.m_amount, apply);
}
void Aura::HandleAuraModTotalThreat(bool apply, bool Real)
{
// only at real add/remove aura
if(!Real)
if (!Real)
return;
if(!m_target->isAlive() || m_target->GetTypeId()!= TYPEID_PLAYER)
if (!m_target->isAlive() || m_target->GetTypeId() != TYPEID_PLAYER)
return;
Unit* caster = GetCaster();
if(!caster || !caster->isAlive())
if (!caster || !caster->isAlive())
return;
float threatMod = 0.0f;
if(apply)
threatMod = float(m_modifier.m_amount);
else
threatMod = float(-m_modifier.m_amount);
float threatMod = apply ? float(m_modifier.m_amount) : float(-m_modifier.m_amount);
m_target->getHostilRefManager().threatAssist(caster, threatMod);
}
@ -3867,18 +3859,18 @@ void Aura::HandleAuraModTotalThreat(bool apply, bool Real)
void Aura::HandleModTaunt(bool apply, bool Real)
{
// only at real add/remove aura
if(!Real)
if (!Real)
return;
if(!m_target->isAlive() || !m_target->CanHaveThreatList())
if (!m_target->isAlive() || !m_target->CanHaveThreatList())
return;
Unit* caster = GetCaster();
if(!caster || !caster->isAlive())
if (!caster || !caster->isAlive())
return;
if(apply)
if (apply)
m_target->TauntApply(caster);
else
{
@ -4326,10 +4318,10 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)
case SPELLFAMILY_DRUID:
{
// Rake
if (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000001000))
if (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000001000) && m_spellProto->Effect[2]==SPELL_EFFECT_ADD_COMBO_POINTS)
{
// $AP*0.06 bonus per tick
m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 6 / 100);
// $AP*0.18 bonus per tick
m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 18 / 100);
return;
}
// Lacerate

View file

@ -310,12 +310,6 @@ void Spell::EffectSchoolDMG(uint32 effect_idx)
{
case SPELLFAMILY_GENERIC:
{
//Gore
if (m_spellInfo->SpellIconID == 2269 )
{
damage+= rand()%2 ? damage : 0;
}
switch(m_spellInfo->Id) // better way to check unknown
{
// Meteor like spells (divided damage to targets)
@ -436,8 +430,9 @@ void Spell::EffectSchoolDMG(uint32 effect_idx)
m_caster->SetPower(POWER_ENERGY,0);
}
// Rake
else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000001000))
else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000001000) && m_spellInfo->Effect[2]==SPELL_EFFECT_ADD_COMBO_POINTS)
{
// $AP*0.01 bonus
damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100);
}
// Swipe
@ -445,18 +440,6 @@ void Spell::EffectSchoolDMG(uint32 effect_idx)
{
damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.08f);
}
//Mangle Bonus for the initial damage of Lacerate and Rake
if ((m_spellInfo->SpellFamilyFlags==UI64LIT(0x0000000000001000) && m_spellInfo->SpellIconID==494) ||
(m_spellInfo->SpellFamilyFlags==UI64LIT(0x0000010000000000) && m_spellInfo->SpellIconID==2246))
{
Unit::AuraList const& mDummyAuras = unitTarget->GetAurasByType(SPELL_AURA_DUMMY);
for(Unit::AuraList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i)
if(((*i)->GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000044000000000)) && (*i)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_DRUID)
{
damage = int32(damage*(100.0f+(*i)->GetModifier()->m_amount)/100.0f);
break;
}
}
break;
}
case SPELLFAMILY_ROGUE:
@ -527,8 +510,13 @@ void Spell::EffectSchoolDMG(uint32 effect_idx)
}
case SPELLFAMILY_HUNTER:
{
//Gore
if (m_spellInfo->SpellIconID == 1578)
{
damage+= rand()%2 ? damage : 0;
}
// Mongoose Bite
if ((m_spellInfo->SpellFamilyFlags & UI64LIT(0x000000002)) && m_spellInfo->SpellVisual[0]==342)
else if ((m_spellInfo->SpellFamilyFlags & UI64LIT(0x000000002)) && m_spellInfo->SpellVisual[0]==342)
{
damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2f);
}
@ -787,7 +775,9 @@ void Spell::EffectDummy(uint32 i)
if(!itemTarget && m_caster->GetTypeId()!=TYPEID_PLAYER)
return;
uint32 spell_id = roll_chance_i(50) ? 17269 : 17270;
uint32 spell_id = roll_chance_i(50)
? 17269 // Create Resonating Skull
: 17270; // Create Bone Dust
m_caster->CastSpell(m_caster, spell_id, true, NULL);
return;
@ -846,25 +836,25 @@ void Spell::EffectDummy(uint32 i)
if (!m_CastItem) return;
m_caster->CastSpell(m_caster, 13166, true, m_CastItem);
return;
case 23448: // Ultrasafe Transporter: Gadgetzan - backfires
case 23448: // Transporter Arrival - Ultrasafe Transporter: Gadgetzan - backfires
{
int32 r = irand(0, 119);
if ( r < 20 ) // 1/6 polymorph
if ( r < 20 ) // Transporter Malfunction - 1/6 polymorph
m_caster->CastSpell(m_caster, 23444, true);
else if ( r < 100 ) // 4/6 evil twin
else if ( r < 100 ) // Evil Twin - 4/6 evil twin
m_caster->CastSpell(m_caster, 23445, true);
else // 1/6 miss the target
else // Transporter Malfunction - 1/6 miss the target
m_caster->CastSpell(m_caster, 36902, true);
return;
}
case 23453: // Ultrasafe Transporter: Gadgetzan
if ( roll_chance_i(50) ) // success
case 23453: // Gnomish Transporter - Ultrasafe Transporter: Gadgetzan
if ( roll_chance_i(50) ) // Gadgetzan Transporter - success
m_caster->CastSpell(m_caster, 23441, true);
else // failure
else // Gadgetzan Transporter Failure - failure
m_caster->CastSpell(m_caster, 23446, true);
return;
case 23645: // Hourglass Sand
m_caster->RemoveAurasDueToSpell(23170);
m_caster->RemoveAurasDueToSpell(23170); // Brood Affliction: Bronze
return;
case 23725: // Gift of Life (warrior bwl trinket)
m_caster->CastSpell(m_caster, 23782, true);
@ -882,43 +872,41 @@ void Spell::EffectDummy(uint32 i)
//5 different spells used depending on mounted speed and if mount can fly or not
if (flyspeed >= 4.1f)
// Flying Reindeer
m_caster->CastSpell(m_caster, 44827, true); //310% flying Reindeer
else if (flyspeed >= 3.8f)
// Flying Reindeer
m_caster->CastSpell(m_caster, 44825, true); //280% flying Reindeer
else if (flyspeed >= 1.6f)
// Flying Reindeer
m_caster->CastSpell(m_caster, 44824, true); //60% flying Reindeer
else if (speed >= 2.0f)
// Reindeer
m_caster->CastSpell(m_caster, 25859, true); //100% ground Reindeer
else
// Reindeer
m_caster->CastSpell(m_caster, 25858, true); //60% ground Reindeer
return;
}
//case 26074: // Holiday Cheer
// return; -- implemented at client side
case 26074: // Holiday Cheer
// implemented at client side
return;
case 28006: // Arcane Cloaking
{
if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER )
// Naxxramas Entry Flag Effect DND
m_caster->CastSpell(unitTarget, 29294, true);
return;
}
case 28730: // Arcane Torrent (Mana)
{
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);
}
return;
}
case 29200: // Purify Helboar Meat
{
if( m_caster->GetTypeId() != TYPEID_PLAYER )
return;
uint32 spell_id = roll_chance_i(50) ? 29277 : 29278;
uint32 spell_id = roll_chance_i(50)
? 29277 // Summon Purified Helboar Meat
: 29278; // Summon Toxic Helboar Meat
m_caster->CastSpell(m_caster,spell_id,true,NULL);
return;
@ -929,19 +917,19 @@ void Spell::EffectDummy(uint32 i)
return;
case 30458: // Nigh Invulnerability
if (!m_CastItem) return;
if(roll_chance_i(86)) // success
if(roll_chance_i(86)) // Nigh-Invulnerability - success
m_caster->CastSpell(m_caster, 30456, true, m_CastItem);
else // backfire in 14% casts
else // Complete Vulnerability - backfire in 14% casts
m_caster->CastSpell(m_caster, 30457, true, m_CastItem);
return;
case 30507: // Poultryizer
if (!m_CastItem) return;
if(roll_chance_i(80)) // success
if(roll_chance_i(80)) // Poultryized! - success
m_caster->CastSpell(unitTarget, 30501, true, m_CastItem);
else // backfire 20%
else // Poultryized! - backfire 20%
m_caster->CastSpell(unitTarget, 30504, true, m_CastItem);
return;
case 33060: // Make a Wish
case 33060: // Make a Wish
{
if(m_caster->GetTypeId()!=TYPEID_PLAYER)
return;
@ -950,23 +938,23 @@ void Spell::EffectDummy(uint32 i)
switch(urand(1,5))
{
case 1: spell_id = 33053; break;
case 2: spell_id = 33057; break;
case 3: spell_id = 33059; break;
case 4: spell_id = 33062; break;
case 5: spell_id = 33064; break;
case 1: spell_id = 33053; break; // Mr Pinchy's Blessing
case 2: spell_id = 33057; break; // Summon Mighty Mr. Pinchy
case 3: spell_id = 33059; break; // Summon Furious Mr. Pinchy
case 4: spell_id = 33062; break; // Tiny Magical Crawdad
case 5: spell_id = 33064; break; // Mr. Pinchy's Gift
}
m_caster->CastSpell(m_caster, spell_id, true, NULL);
return;
}
case 35745:
case 35745: // Socrethar's Stone
{
uint32 spell_id;
switch(m_caster->GetAreaId())
{
case 3900: spell_id = 35743; break;
case 3742: spell_id = 35744; break;
case 3900: spell_id = 35743; break; // Socrethar Portal
case 3742: spell_id = 35744; break; // Socrethar Portal
default: return;
}
@ -1076,6 +1064,13 @@ void Spell::EffectDummy(uint32 i)
m_caster->CastSpell(m_caster, 45088, true);
return;
}
case 55004: // Nitro Boosts
if(!m_CastItem) return;
if(roll_chance_i(95)) // Nitro Boosts - success
m_caster->CastSpell(m_caster, 54861, true, m_CastItem);
else // Knocked Up - backfire 5%
m_caster->CastSpell(m_caster, 46014, true, m_CastItem);
return;
case 50243: // Teach Language
{
if(m_caster->GetTypeId() != TYPEID_PLAYER)
@ -1119,7 +1114,7 @@ void Spell::EffectDummy(uint32 i)
return;
}
case 52308:
case 52308: // Take Sputum Sample
{
switch(i)
{
@ -1142,9 +1137,10 @@ void Spell::EffectDummy(uint32 i)
return;
m_caster->CastCustomSpell(unitTarget, 52752, &damage, NULL, NULL, true);
return;
case 53341:
case 53343:
case 53341: // Rune of Cinderglacier
case 53343: // Rune of Razorice
{
// Runeforging Credit
m_caster->CastSpell(m_caster, 54586, true);
return;
}
@ -2983,7 +2979,7 @@ void Spell::EffectOpenLock(uint32 effIndex)
return;
}
}
lockId = gameObjTarget->GetLockId();
lockId = goInfo->GetLockId();
guid = gameObjTarget->GetGUID();
}
else if(itemTarget)
@ -4080,7 +4076,6 @@ void Spell::EffectSummonPet(uint32 i)
return;
OldSummon->GetMap()->Remove((Creature*)OldSummon,false);
OldSummon->SetMapId(m_caster->GetMapId());
float px, py, pz;
m_caster->GetClosePoint(px, py, pz, OldSummon->GetObjectSize());
@ -4628,7 +4623,7 @@ void Spell::EffectSummonObjectWild(uint32 i)
}
}
if(uint32 linkedEntry = pGameObj->GetLinkedGameObjectEntry())
if(uint32 linkedEntry = pGameObj->GetGOInfo()->GetLinkedGameObjectEntry())
{
GameObject* linkedGO = new GameObject;
if(linkedGO->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), linkedEntry, map,
@ -6333,7 +6328,7 @@ void Spell::EffectTransmitted(uint32 effIndex)
cMap->Add(pGameObj);
if(uint32 linkedEntry = pGameObj->GetLinkedGameObjectEntry())
if(uint32 linkedEntry = pGameObj->GetGOInfo()->GetLinkedGameObjectEntry())
{
GameObject* linkedGO = new GameObject;
if(linkedGO->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), linkedEntry, cMap,

View file

@ -551,17 +551,6 @@ bool IsSingleTargetSpells(SpellEntry const *spellInfo1, SpellEntry const *spellI
return false;
}
bool IsAuraAddedBySpell(uint32 auraType, uint32 spellId)
{
SpellEntry const *spellproto = sSpellStore.LookupEntry(spellId);
if (!spellproto) return false;
for (int i = 0; i < 3; ++i)
if (spellproto->EffectApplyAuraName[i] == auraType)
return true;
return false;
}
SpellCastResult GetErrorAtShapeshiftedCast (SpellEntry const *spellInfo, uint32 form)
{
// talents that learn spells can have stance requirements that need ignore
@ -2726,6 +2715,260 @@ void SpellMgr::LoadSkillLineAbilityMap()
sLog.outString(">> Loaded %u SkillLineAbility MultiMap Data", count);
}
void SpellMgr::CheckUsedSpells(char const* table)
{
uint32 countSpells = 0;
uint32 countMasks = 0;
// 0 1 2 3 4 5 6 7 8 9 10 11
QueryResult *result = WorldDatabase.PQuery("SELECT spellid,SpellFamilyName,SpellFamilyMaskA,SpellFamilyMaskB,SpellIcon,SpellVisual,SpellCategory,EffectType,EffectAura,EffectIdx,Name,Code FROM %s",table);
if( !result )
{
barGoLink bar( 1 );
bar.step();
sLog.outString();
sLog.outErrorDb("`%s` table is empty!",table);
return;
}
barGoLink bar( result->GetRowCount() );
do
{
Field *fields = result->Fetch();
bar.step();
uint32 spell = fields[0].GetUInt32();
int32 family = fields[1].GetInt32();
uint64 familyMaskA = fields[2].GetUInt64();
uint32 familyMaskB = fields[3].GetUInt32();
int32 spellIcon = fields[4].GetInt32();
int32 spellVisual = fields[5].GetInt32();
int32 category = fields[6].GetInt32();
int32 effectType = fields[7].GetInt32();
int32 auraType = fields[8].GetInt32();
int32 effectIdx = fields[9].GetInt32();
std::string name = fields[10].GetCppString();
std::string code = fields[11].GetCppString();
// checks of correctness requirements itself
if (family < -1 || family > SPELLFAMILY_PET)
{
sLog.outError("Table '%s' for spell %u have wrong SpellFamily value(%u), skipped.",table,spell,family);
continue;
}
// TODO: spellIcon check need dbc loading
if (spellIcon < -1)
{
sLog.outError("Table '%s' for spell %u have wrong SpellIcon value(%u), skipped.",table,spell,spellIcon);
continue;
}
// TODO: spellVisual check need dbc loading
if (spellVisual < -1)
{
sLog.outError("Table '%s' for spell %u have wrong SpellVisual value(%u), skipped.",table,spell,spellVisual);
continue;
}
// TODO: for spellCategory better check need dbc loading
if (category < -1 || category >=0 && sSpellCategoryStore.find(category) == sSpellCategoryStore.end())
{
sLog.outError("Table '%s' for spell %u have wrong SpellCategory value(%u), skipped.",table,spell,category);
continue;
}
if (effectType < -1 || effectType >= TOTAL_SPELL_EFFECTS)
{
sLog.outError("Table '%s' for spell %u have wrong SpellEffect type value(%u), skipped.",table,spell,effectType);
continue;
}
if (auraType < -1 || auraType >= TOTAL_AURAS)
{
sLog.outError("Table '%s' for spell %u have wrong SpellAura type value(%u), skipped.",table,spell,auraType);
continue;
}
if (effectIdx < -1 || effectIdx >= 3)
{
sLog.outError("Table '%s' for spell %u have wrong EffectIdx value(%u), skipped.",table,spell,effectIdx);
continue;
}
// now checks of requirements
if(spell)
{
++countSpells;
SpellEntry const* spellEntry = sSpellStore.LookupEntry(spell);
if(!spellEntry)
{
sLog.outError("Spell %u '%s' not exist but used in %s.",spell,name.c_str(),code.c_str());
continue;
}
if(family >= 0 && spellEntry->SpellFamilyName != family)
{
sLog.outError("Spell %u '%s' family(%u) <> %u but used in %s.",spell,name.c_str(),spellEntry->SpellFamilyName,family,code.c_str());
continue;
}
if(familyMaskA != UI64LIT(0xFFFFFFFFFFFFFFFF) || familyMaskB != 0xFFFFFFFF)
{
if(familyMaskA == UI64LIT(0x0000000000000000) && familyMaskB == 0x00000000)
{
if(spellEntry->SpellFamilyFlags != 0 || spellEntry->SpellFamilyFlags2 != 0)
{
sLog.outError("Spell %u '%s' not fit to (" I64FMT "," I32FMT ") but used in %s.",spell,name.c_str(),familyMaskA,familyMaskB,code.c_str());
continue;
}
}
else
{
if((spellEntry->SpellFamilyFlags & familyMaskA)==0 && (spellEntry->SpellFamilyFlags2 & familyMaskB)==0)
{
sLog.outError("Spell %u '%s' not fit to (" I64FMT "," I32FMT ") but used in %s.",spell,name.c_str(),familyMaskA,familyMaskB,code.c_str());
continue;
}
}
}
if(spellIcon >= 0 && spellEntry->SpellIconID != spellIcon)
{
sLog.outError("Spell %u '%s' icon(%u) <> %u but used in %s.",spell,name.c_str(),spellEntry->SpellIconID,spellIcon,code.c_str());
continue;
}
if(spellVisual >= 0 && spellEntry->SpellVisual[0] != spellVisual)
{
sLog.outError("Spell %u '%s' visual(%u) <> %u but used in %s.",spell,name.c_str(),spellEntry->SpellVisual[0],spellVisual,code.c_str());
continue;
}
if(category >= 0 && spellEntry->Category != category)
{
sLog.outError("Spell %u '%s' category(%u) <> %u but used in %s.",spell,name.c_str(),spellEntry->Category,category,code.c_str());
continue;
}
if(effectIdx >= 0)
{
if(effectType >= 0 && spellEntry->Effect[effectIdx] != effectType)
{
sLog.outError("Spell %u '%s' effect%d <> %u but used in %s.",spell,name.c_str(),effectIdx+1,effectType,code.c_str());
continue;
}
if(auraType >= 0 && spellEntry->EffectApplyAuraName[effectIdx] != auraType)
{
sLog.outError("Spell %u '%s' aura%d <> %u but used in %s.",spell,name.c_str(),effectIdx+1,auraType,code.c_str());
continue;
}
}
else
{
if(effectType >= 0 && !IsSpellHaveEffect(spellEntry,SpellEffects(effectType)))
{
sLog.outError("Spell %u '%s' not have effect %u but used in %s.",spell,name.c_str(),effectType,code.c_str());
continue;
}
if(auraType >= 0 && !IsSpellHaveAura(spellEntry,AuraType(auraType)))
{
sLog.outError("Spell %u '%s' not have aura %u but used in %s.",spell,name.c_str(),auraType,code.c_str());
continue;
}
}
}
else
{
++countMasks;
bool found = false;
for(uint32 spellId = 1; spellId < sSpellStore.GetNumRows(); ++spellId)
{
SpellEntry const* spellEntry = sSpellStore.LookupEntry(spellId);
if(!spellEntry)
continue;
if(family >=0 && spellEntry->SpellFamilyName != family)
continue;
if(familyMaskA != UI64LIT(0xFFFFFFFFFFFFFFFF) || familyMaskB != 0xFFFFFFFF)
{
if(familyMaskA == UI64LIT(0x0000000000000000) && familyMaskB == 0x00000000)
{
if(spellEntry->SpellFamilyFlags != 0 || spellEntry->SpellFamilyFlags2 != 0)
continue;
}
else
{
if((spellEntry->SpellFamilyFlags & familyMaskA)==0 && (spellEntry->SpellFamilyFlags2 & familyMaskB)==0)
continue;
}
}
if(spellIcon >= 0 && spellEntry->SpellIconID != spellIcon)
continue;
if(spellVisual >= 0 && spellEntry->SpellVisual[0] != spellVisual)
continue;
if(category >= 0 && spellEntry->Category != category)
continue;
if(effectIdx >= 0)
{
if(effectType >=0 && spellEntry->Effect[effectIdx] != effectType)
continue;
if(auraType >=0 && spellEntry->EffectApplyAuraName[effectIdx] != auraType)
continue;
}
else
{
if(effectType >=0 && !IsSpellHaveEffect(spellEntry,SpellEffects(effectType)))
continue;
if(auraType >=0 && !IsSpellHaveAura(spellEntry,AuraType(auraType)))
continue;
}
found = true;
break;
}
if(!found)
{
if(effectIdx >= 0)
sLog.outError("Spells '%s' not found for family %i (" I64FMT "," I32FMT ") icon(%i) visual(%i) category(%i) effect%d(%i) aura%d(%i) but used in %s",
name.c_str(),family,familyMaskA,familyMaskB,spellIcon,spellVisual,category,effectIdx+1,effectType,effectIdx+1,auraType,code.c_str());
else
sLog.outError("Spells '%s' not found for family %i (" I64FMT "," I32FMT ") icon(%i) visual(%i) category(%i) effect(%i) aura(%i) but used in %s",
name.c_str(),family,familyMaskA,familyMaskB,spellIcon,spellVisual,category,effectType,auraType,code.c_str());
continue;
}
}
} while( result->NextRow() );
delete result;
sLog.outString();
sLog.outString( ">> Checked %u spells and %u spell masks", countSpells, countMasks );
}
DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto, bool triggered)
{
// Explicit Diminishing Groups

View file

@ -128,6 +128,14 @@ inline bool IsSpellHaveEffect(SpellEntry const *spellInfo, SpellEffects effect)
return false;
}
inline bool IsSpellHaveAura(SpellEntry const *spellInfo, AuraType aura)
{
for(int i= 0; i < 3; ++i)
if(AuraType(spellInfo->EffectApplyAuraName[i])==aura)
return true;
return false;
}
bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2);
inline bool IsSealSpell(SpellEntry const *spellInfo)
@ -186,8 +194,6 @@ bool IsPositiveTarget(uint32 targetA, uint32 targetB);
bool IsSingleTargetSpell(SpellEntry const *spellInfo);
bool IsSingleTargetSpells(SpellEntry const *spellInfo1, SpellEntry const *spellInfo2);
bool IsAuraAddedBySpell(uint32 auraType, uint32 spellId);
inline bool IsPointEffectTarget( Targets target )
{
switch (target )
@ -894,6 +900,8 @@ class SpellMgr
public:
static SpellMgr& Instance();
void CheckUsedSpells(char const* table);
// Loading data at server startup
void LoadSpellChains();
void LoadSpellLearnSkills();

View file

@ -165,13 +165,13 @@ void TemporarySummon::UnSummon()
{
CombatStop();
AddObjectToRemoveList();
Unit* sum = m_summoner ? ObjectAccessor::GetUnit(*this, m_summoner) : NULL;
if (sum && sum->GetTypeId() == TYPEID_UNIT && ((Creature*)sum)->AI())
{
((Creature*)sum)->AI()->SummonedCreatureDespawn(this);
}
AddObjectToRemoveList();
}
void TemporarySummon::SaveToDB()

View file

@ -32,11 +32,9 @@
// The pHatingUnit is not used yet
float ThreatCalcHelper::calcThreat(Unit* pHatedUnit, Unit* pHatingUnit, float pThreat, SpellSchoolMask schoolMask, SpellEntry const *pThreatSpell)
{
if(pThreatSpell)
{
if( Player* modOwner = pHatingUnit->GetSpellModOwner() )
if (pThreatSpell)
if (Player* modOwner = pHatedUnit->GetSpellModOwner())
modOwner->ApplySpellMod(pThreatSpell->Id, SPELLMOD_THREAT, pThreat);
}
float threat = pHatedUnit->ApplyTotalThreatModifier(pThreat, schoolMask);
return threat;

View file

@ -53,7 +53,6 @@ void Totem::Update( uint32 time )
void Totem::Summon(Unit* owner)
{
SetInstanceId(owner->GetInstanceId());
owner->GetMap()->Add((Creature*)this);
// select totem model in dependent from owner team

View file

@ -102,7 +102,8 @@ void MapManager::LoadTransports()
m_TransportsByMap[*i].insert(t);
//If we someday decide to use the grid to track transports, here:
//MapManager::Instance().LoadGrid(mapid,x,y,true);
t->SetMap(MapManager::Instance().CreateMap(mapid, t));
//t->GetMap()->Add<GameObject>((GameObject *)t);
++count;
} while(result->NextRow());
@ -138,8 +139,6 @@ Transport::Transport() : GameObject()
bool Transport::Create(uint32 guidlow, uint32 mapid, float x, float y, float z, float ang, uint32 animprogress, uint32 dynflags)
{
Relocate(x,y,z,ang);
SetMapId(mapid);
// instance id and phaseMask isn't set to values different from std.
if(!IsPositionValid())
@ -432,7 +431,6 @@ Transport::WayPointMap::const_iterator Transport::GetNextWayPoint()
void Transport::TeleportTransport(uint32 newMapid, float x, float y, float z)
{
Map const* oldMap = GetMap();
SetMapId(newMapid);
Relocate(x, y, z);
for(PlayerSet::iterator itr = m_passengers.begin(); itr != m_passengers.end();)
@ -458,7 +456,11 @@ void Transport::TeleportTransport(uint32 newMapid, float x, float y, float z)
//plr->GetSession()->SendPacket(&data);
}
Map const* newMap = GetMap();
//we need to create and save new Map object with 'newMapid' because if not done -> lead to invalid Map object reference...
//player far teleport would try to create same instance, but we need it NOW for transport...
//correct me if I'm wrong O.o
Map * newMap = MapManager::Instance().CreateMap(newMapid, this);
SetMap(newMap);
if(oldMap != newMap)
{

View file

@ -54,24 +54,11 @@ class TransportPath
std::vector<PathNode> i_nodes;
};
class Transport : protected GameObject
class Transport : public GameObject
{
public:
explicit Transport();
// prevent using Transports as normal GO, but allow call some inherited functions
using GameObject::IsTransport;
using GameObject::GetEntry;
using GameObject::GetGUID;
using GameObject::GetGUIDLow;
using GameObject::GetMapId;
using GameObject::GetPositionX;
using GameObject::GetPositionY;
using GameObject::GetPositionZ;
using GameObject::BuildCreateUpdateBlockForPlayer;
using GameObject::BuildOutOfRangeUpdateBlock;
using GameObject::GetPackGUID;
bool Create(uint32 guidlow, uint32 mapid, float x, float y, float z, float ang, uint32 animprogress, uint32 dynflags);
bool GenerateWaypoints(uint32 pathid, std::set<uint32> &mapids);
void Update(uint32 p_time);

View file

@ -431,10 +431,10 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
return 0;
}
if (!spellProto || !IsAuraAddedBySpell(SPELL_AURA_MOD_FEAR, spellProto->Id))
if (!spellProto || !IsSpellHaveAura(spellProto,SPELL_AURA_MOD_FEAR))
pVictim->RemoveSpellbyDamageTaken(SPELL_AURA_MOD_FEAR, damage);
// root type spells do not dispel the root effect
if (!spellProto || !(spellProto->Mechanic == MECHANIC_ROOT || IsAuraAddedBySpell(SPELL_AURA_MOD_ROOT, spellProto->Id)))
if (!spellProto || !(spellProto->Mechanic == MECHANIC_ROOT || IsSpellHaveAura(spellProto,SPELL_AURA_MOD_ROOT)))
pVictim->RemoveSpellbyDamageTaken(SPELL_AURA_MOD_ROOT, damage);
// no xp,health if type 8 /critters/
@ -5287,7 +5287,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
triggered_spell_id = 40446;
chance = 25.0f;
}
// Mangle (cat/bear)
// Mangle (Bear) and Mangle (Cat)
else if (procSpell->SpellFamilyFlags & UI64LIT(0x0000044000000000))
{
triggered_spell_id = 40452;
@ -7916,8 +7916,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
// Mod damage from spell mechanic
uint32 mechanicMask = GetAllSpellMechanicMask(spellProto);
if (mechanicMask)
if (uint32 mechanicMask = GetAllSpellMechanicMask(spellProto))
{
AuraList const& mDamageDoneMechanic = pVictim->GetAurasByType(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT);
for(AuraList::const_iterator i = mDamageDoneMechanic.begin();i != mDamageDoneMechanic.end(); ++i)
@ -8711,6 +8710,25 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage,WeaponAttackType attT
if((*i)->GetModifier()->m_miscvalue & GetMeleeDamageSchoolMask())
TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
// .. taken pct (special attacks)
if (spellProto)
{
uint32 mechanicMask = GetAllSpellMechanicMask(spellProto);
// Shred also have bonus as MECHANIC_BLEED damages
if(spellProto->SpellFamilyName==SPELLFAMILY_DRUID && (spellProto->SpellFamilyFlags & UI64LIT(0x00008000)))
mechanicMask |= (1 << MECHANIC_BLEED);
// Mod damage from spell mechanic
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;
}
}
// .. taken pct: dummy auras
AuraList const& mDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY);
for(AuraList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i)
@ -8729,14 +8747,6 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage,WeaponAttackType attT
TakenTotalMod *= (mod+100.0f)/100.0f;
}
break;
//Mangle
case 2312:
if(spellProto==NULL)
break;
// Should increase Shred (initial Damage of Lacerate and Rake handled in Spell::EffectSchoolDMG)
if(spellProto->SpellFamilyName==SPELLFAMILY_DRUID && (spellProto->SpellFamilyFlags == UI64LIT(0x00008000)))
TakenTotalMod *= (100.0f+(*i)->GetModifier()->m_amount)/100.0f;
break;
}
}
@ -9249,7 +9259,7 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList,
//based on wowwiki every 5 mod we have 1 more level diff in calculation
visibleDistance += (int32(u->GetTotalAuraModifier(SPELL_AURA_MOD_DETECT)) - stealthMod)/5.0f;
if(!IsWithinDist(u,visibleDistance))
if(visibleDistance <= 0 || !IsWithinDist(u,visibleDistance))
return false;
}

View file

@ -62,8 +62,7 @@ void Vehicle::Update(uint32 diff)
bool Vehicle::Create(uint32 guidlow, Map *map, uint32 Entry, uint32 vehicleId, uint32 team)
{
SetMapId(map->GetId());
SetInstanceId(map->GetInstanceId());
SetMap(map);
Object::_Create(guidlow, Entry, HIGHGUID_VEHICLE);

View file

@ -385,15 +385,9 @@ void WorldSession::LogoutPlayer(bool Save)
// the player may not be in the world when logging out
// e.g if he got disconnected during a transfer to another map
// calls to GetMap in this case may cause crashes
if(_player->IsInWorld()) _player->GetMap()->Remove(_player, false);
// RemoveFromWorld does cleanup that requires the player to be in the accessor
ObjectAccessor::Instance().RemoveObject(_player);
///- Delete the player object
_player->CleanupsBeforeDelete(); // do some cleanup before deleting to prevent crash at crossreferences to already deleted data
delete _player;
_player = NULL;
Map* _map = _player->GetMap();
_map->Remove(_player, true);
_player = NULL; // deleted in Remove call
///- Send the 'logout complete' packet to the client
WorldPacket data( SMSG_LOGOUT_COMPLETE, 0 );

View file

@ -30,6 +30,7 @@
#include "BattleGroundMgr.h"
#include <fstream>
#include "ObjectMgr.h"
#include "SpellMgr.h"
bool ChatHandler::HandleDebugSendSpellFailCommand(const char* args)
{
@ -336,7 +337,7 @@ bool ChatHandler::HandleDebugSendQuestPartyMsgCommand(const char* args)
return true;
}
bool ChatHandler::HandleDebugGetLootRecipient(const char* /*args*/)
bool ChatHandler::HandleDebugGetLootRecipientCommand(const char* /*args*/)
{
Creature* target = getSelectedCreature();
if (!target)
@ -353,7 +354,7 @@ bool ChatHandler::HandleDebugSendQuestInvalidMsgCommand(const char* args)
return true;
}
bool ChatHandler::HandleDebugGetItemState(const char* args)
bool ChatHandler::HandleDebugGetItemStateCommand(const char* args)
{
if (!*args)
return false;
@ -649,6 +650,14 @@ bool ChatHandler::HandleDebugSpawnVehicle(const char* args)
return true;
}
bool ChatHandler::HandleDebugSpellCheckCommand(const char* /*args*/)
{
sLog.outString( "Check expected in code spell properties base at table 'spell_check' content...");
spellmgr.CheckUsedSpells("spell_check");
return true;
}
bool ChatHandler::HandleDebugSendLargePacketCommand(const char* /*args*/)
{
const char* stuffingString = "This is a dummy string to push the packet's size beyond 128000 bytes. ";
@ -733,3 +742,186 @@ bool ChatHandler::HandleDebugSetAuraStateCommand(const char* args)
unit->ModifyAuraState(AuraState(abs(state)),state > 0);
return true;
}
bool ChatHandler::HandleDebugSetValueCommand(const char* args)
{
if(!*args)
return false;
char* px = strtok((char*)args, " ");
char* py = strtok(NULL, " ");
char* pz = strtok(NULL, " ");
if (!px || !py)
return false;
Unit* target = getSelectedUnit();
if(!target)
{
SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
SetSentErrorMessage(true);
return false;
}
uint64 guid = target->GetGUID();
uint32 Opcode = (uint32)atoi(px);
if(Opcode >= target->GetValuesCount())
{
PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount());
return false;
}
uint32 iValue;
float fValue;
bool isint32 = true;
if(pz)
isint32 = (bool)atoi(pz);
if(isint32)
{
iValue = (uint32)atoi(py);
sLog.outDebug(GetMangosString(LANG_SET_UINT), GUID_LOPART(guid), Opcode, iValue);
target->SetUInt32Value( Opcode , iValue );
PSendSysMessage(LANG_SET_UINT_FIELD, GUID_LOPART(guid), Opcode,iValue);
}
else
{
fValue = (float)atof(py);
sLog.outDebug(GetMangosString(LANG_SET_FLOAT), GUID_LOPART(guid), Opcode, fValue);
target->SetFloatValue( Opcode , fValue );
PSendSysMessage(LANG_SET_FLOAT_FIELD, GUID_LOPART(guid), Opcode,fValue);
}
return true;
}
bool ChatHandler::HandleDebugGetValueCommand(const char* args)
{
if(!*args)
return false;
char* px = strtok((char*)args, " ");
char* pz = strtok(NULL, " ");
if (!px)
return false;
Unit* target = getSelectedUnit();
if(!target)
{
SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
SetSentErrorMessage(true);
return false;
}
uint64 guid = target->GetGUID();
uint32 Opcode = (uint32)atoi(px);
if(Opcode >= target->GetValuesCount())
{
PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, GUID_LOPART(guid), target->GetValuesCount());
return false;
}
uint32 iValue;
float fValue;
bool isint32 = true;
if(pz)
isint32 = (bool)atoi(pz);
if(isint32)
{
iValue = target->GetUInt32Value( Opcode );
sLog.outDebug(GetMangosString(LANG_GET_UINT), GUID_LOPART(guid), Opcode, iValue);
PSendSysMessage(LANG_GET_UINT_FIELD, GUID_LOPART(guid), Opcode, iValue);
}
else
{
fValue = target->GetFloatValue( Opcode );
sLog.outDebug(GetMangosString(LANG_GET_FLOAT), GUID_LOPART(guid), Opcode, fValue);
PSendSysMessage(LANG_GET_FLOAT_FIELD, GUID_LOPART(guid), Opcode, fValue);
}
return true;
}
bool ChatHandler::HandleDebugMod32ValueCommand(const char* args)
{
if(!*args)
return false;
char* px = strtok((char*)args, " ");
char* py = strtok(NULL, " ");
if (!px || !py)
return false;
uint32 Opcode = (uint32)atoi(px);
int Value = atoi(py);
if(Opcode >= m_session->GetPlayer()->GetValuesCount())
{
PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, m_session->GetPlayer()->GetGUIDLow(), m_session->GetPlayer( )->GetValuesCount());
return false;
}
sLog.outDebug(GetMangosString(LANG_CHANGE_32BIT), Opcode, Value);
int CurrentValue = (int)m_session->GetPlayer( )->GetUInt32Value( Opcode );
CurrentValue += Value;
m_session->GetPlayer( )->SetUInt32Value( Opcode , (uint32)CurrentValue );
PSendSysMessage(LANG_CHANGE_32BIT_FIELD, Opcode,CurrentValue);
return true;
}
bool ChatHandler::HandleDebugUpdateCommand(const char* args)
{
if(!*args)
return false;
uint32 updateIndex;
uint32 value;
char* pUpdateIndex = strtok((char*)args, " ");
Unit* chr = getSelectedUnit();
if (chr == NULL)
{
SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
SetSentErrorMessage(true);
return false;
}
if(!pUpdateIndex)
{
return true;
}
updateIndex = atoi(pUpdateIndex);
//check updateIndex
if(chr->GetTypeId() == TYPEID_PLAYER)
{
if (updateIndex>=PLAYER_END) return true;
}
else
{
if (updateIndex>=UNIT_END) return true;
}
char* pvalue = strtok(NULL, " ");
if (!pvalue)
{
value=chr->GetUInt32Value(updateIndex);
PSendSysMessage(LANG_UPDATE, chr->GetGUIDLow(),updateIndex,value);
return true;
}
value=atoi(pvalue);
PSendSysMessage(LANG_UPDATE_CHANGE, chr->GetGUIDLow(),updateIndex,value);
chr->SetUInt32Value(updateIndex,value);
return true;
}

View file

@ -125,6 +125,7 @@
#include <float.h>
#define I32FMT "%08I32X"
#define I64FMT "%016I64X"
#define snprintf _snprintf
#define atoll __atoi64
@ -136,6 +137,7 @@
#define stricmp strcasecmp
#define strnicmp strncasecmp
#define I32FMT "%08X"
#define I64FMT "%016llX"
#endif

View file

@ -63,6 +63,8 @@ class SQLStorage
uint32 MaxEntry;
uint32 iNumFields;
char const* GetTableName() const { return table; }
void Load();
void Free();

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "8159"
#define REVISION_NR "8183"
#endif // __REVISION_NR_H__