diff --git a/sql/characters.sql b/sql/characters.sql index 48fcd5fd3..bfca6983d 100644 --- a/sql/characters.sql +++ b/sql/characters.sql @@ -21,7 +21,7 @@ DROP TABLE IF EXISTS `character_db_version`; CREATE TABLE `character_db_version` ( - `required_8505_01_characters_character_spell` bit(1) default NULL + `required_8589_11_characters_characters` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB'; -- diff --git a/sql/mangos.sql b/sql/mangos.sql index 3d3ddfcc5..ca02823f3 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -24,7 +24,7 @@ CREATE TABLE `db_version` ( `version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL, `cache_id` int(10) default '0', - `required_8573_01_mangos_mangos_string` bit(1) default NULL + `required_8589_10_mangos_spell_proc_event` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -1837,7 +1837,7 @@ CREATE TABLE `item_template` ( `InventoryType` tinyint(3) unsigned NOT NULL default '0', `AllowableClass` mediumint(9) NOT NULL default '-1', `AllowableRace` mediumint(9) NOT NULL default '-1', - `ItemLevel` tinyint(3) unsigned NOT NULL default '0', + `ItemLevel` smallint(5) unsigned NOT NULL default '0', `RequiredLevel` tinyint(3) unsigned NOT NULL default '0', `RequiredSkill` smallint(5) unsigned NOT NULL default '0', `RequiredSkillRank` smallint(5) unsigned NOT NULL default '0', @@ -16931,11 +16931,6 @@ INSERT INTO spell_chain VALUES (55265,55090,55090,2,0), (55270,55265,55090,3,0), (55271,55270,55090,4,0), -/*UnholyBlight*/ -(49194,0,49194,1,0), -(51376,49194,49194,2,0), -(51378,51376,49194,3,0), -(51379,51378,49194,4,0), /*------------------ -- (773) Inscription ------------------*/ @@ -17809,7 +17804,6 @@ INSERT INTO `spell_proc_event` VALUES (44394, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0.000000, 0.000000, 0), (44395, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0.000000, 0.000000, 0), (44396, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0.000000, 0.000000, 0), -(44401, 0x00000000, 3, 0x00200000, 0x00000000, 0x00000000, 0x00000000, 0x00000FFF, 0.000000, 0.000000, 0), (44404, 0x00000000, 3, 0x20000021, 0x00009000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (44442, 0x00000000, 3, 0x00800000, 0x00000040, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 1), (44443, 0x00000000, 3, 0x00800000, 0x00000040, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 1), @@ -18072,10 +18066,8 @@ INSERT INTO `spell_proc_event` VALUES (58620, 0x00000000, 15, 0x00000000, 0x00004000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (58626, 0x00000000, 15, 0x02000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (58631, 0x00000000, 15, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(58642, 0x00000000, 15, 0x00000000, 0x08000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (58644, 0x00000000, 15, 0x00000000, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (58647, 0x00000000, 15, 0x00000000, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(58676, 0x00000000, 15, 0x00000000, 0x00000008, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (58677, 0x00000000, 15, 0x00002000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (58872, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), (58874, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), diff --git a/sql/mangos_spell_check.sql b/sql/mangos_spell_check.sql index a6b8c3cde..aa401c50f 100644 --- a/sql/mangos_spell_check.sql +++ b/sql/mangos_spell_check.sql @@ -38,7 +38,6 @@ CREATE TABLE `spell_check` ( 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 */ -(781, 9, -1, -1, -1, -1, -1, 3, -1,-1,'Disengage', 'Spell::EffectDummy'), (1454, 5,0x0000000000040000,0x00000000, -1, -1, -1, 3, -1,-1,'Life Tap', 'Spell::EffectDummy'), (1455, 5,0x0000000000040000,0x00000000, -1, -1, -1, 3, -1,-1,'Life Tap', 'Spell::EffectDummy'), (1456, 5,0x0000000000040000,0x00000000, -1, -1, -1, 3, -1,-1,'Life Tap', 'Spell::EffectDummy'), @@ -46,9 +45,9 @@ INSERT INTO spell_check (spellid,SpellFamilyName,SpellFamilyMaskA,SpellFamilyMas (4073, -1, -1, -1, -1, -1, -1, -1, -1,-1,'Mechanical Dragonling', 'Spell::EffectDummy'), (5938, 8, -1, -1, -1, -1, -1, 3, -1,-1,'Shiv', 'Spell::EffectDummy'), (5940, -1, -1, -1, -1, -1, -1, -1, -1,-1,'Shiv', 'Spell::EffectDummy'), -(8017, 11,0x0000000000400000,0x00000000, -1, -1, -1, 3, -1,-1,'Rockbiter Weapon', 'Spell::EffectDummy'), -(8018, 11,0x0000000000400000,0x00000000, -1, -1, -1, 3, -1,-1,'Rockbiter Weapon', 'Spell::EffectDummy'), -(8019, 11,0x0000000000400000,0x00000000, -1, -1, -1, 3, -1,-1,'Rockbiter Weapon', 'Spell::EffectDummy'), +(8017, 11,0x0000000000400000,0x00000000, -1, -1, -1, 54, -1,-1,'Rockbiter Weapon', 'Spell::EffectEnchantItemTmp'), +(8018, 11,0x0000000000400000,0x00000000, -1, -1, -1, 54, -1,-1,'Rockbiter Weapon', 'Spell::EffectEnchantItemTmp'), +(8019, 11,0x0000000000400000,0x00000000, -1, -1, -1, 54, -1,-1,'Rockbiter Weapon', 'Spell::EffectEnchantItemTmp'), (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'), @@ -61,7 +60,7 @@ INSERT INTO spell_check (spellid,SpellFamilyName,SpellFamilyMaskA,SpellFamilyMas (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'), -(10399,11,0x0000000000400000,0x00000000, -1, -1, -1, 3, -1,-1,'Rockbiter Weapon', 'Spell::EffectDummy'), +(10399,11,0x0000000000400000,0x00000000, -1, -1, -1, 54, -1,-1,'Rockbiter Weapon', 'Spell::EffectEnchantItemTmp'), (11687, 5,0x0000000000040000,0x00000000, -1, -1, -1, 3, -1,-1,'Life Tap', 'Spell::EffectDummy'), (11688, 5,0x0000000000040000,0x00000000, -1, -1, -1, 3, -1,-1,'Life Tap', 'Spell::EffectDummy'), (11689, 5,0x0000000000040000,0x00000000, -1, -1, -1, 3, -1,-1,'Life Tap', 'Spell::EffectDummy'), @@ -152,9 +151,6 @@ INSERT INTO spell_check (spellid,SpellFamilyName,SpellFamilyMaskA,SpellFamilyMas (26464,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Mercurial Shield', 'Spell::EffectTriggerSpell'), (26467,-1, -1, -1, -1, -1, -1, 6, 42, 0,'Persistent Shield', 'Spell::EffectDummy'), (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'), (27174,10, -1, -1, 156, -1, -1, 3, -1,-1,'Holy Shock', 'Spell::EffectDummy'), (27175,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Holy Shock', 'Spell::EffectDummy'), @@ -211,10 +207,14 @@ INSERT INTO spell_check (spellid,SpellFamilyName,SpellFamilyMaskA,SpellFamilyMas (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'), -(36494,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Rockbiter Weapon', 'Spell::EffectDummy'), -(36750,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Rockbiter Weapon', 'Spell::EffectDummy'), -(36755,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Rockbiter Weapon', 'Spell::EffectDummy'), -(36759,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Rockbiter Weapon', 'Spell::EffectDummy'), +(36744,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Rockbiter Weapon', 'Spell::EffectEnchantItemTmp'), +(36751,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Rockbiter Weapon', 'Spell::EffectEnchantItemTmp'), +(36753,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Rockbiter Weapon', 'Spell::EffectEnchantItemTmp'), +(36754,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Rockbiter Weapon', 'Spell::EffectEnchantItemTmp'), +(36755,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Rockbiter Weapon', 'Spell::EffectEnchantItemTmp'), +(36758,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Rockbiter Weapon', 'Spell::EffectEnchantItemTmp'), +(36760,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Rockbiter Weapon', 'Spell::EffectEnchantItemTmp'), +(36761,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Rockbiter Weapon', 'Spell::EffectEnchantItemTmp'), (36837, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Meteor', 'Spell::EffectSchoolDMG'), (36890,-1, -1, -1, -1, -1, -1, 5, -1,-1,'Area52 Transporter', 'Spell::EffectTeleportUnits'), (36893,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Transporter Malfunction', 'Spell::EffectTeleportUnits'), @@ -346,7 +346,6 @@ INSERT INTO spell_check (spellid,SpellFamilyName,SpellFamilyMaskA,SpellFamilyMas ( 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, 4,0x0000000000000001,0x00000000, -1, 867, -1, 3, -1,-1,'Charge', 'Spell::EffectDummy'), ( 0,11,0x0000000004000000,0x00000000,1673, -1, -1, 3, -1,-1,'Cleansing Totem', 'Spell::EffectDummy'), @@ -394,7 +393,7 @@ INSERT INTO spell_check (spellid,SpellFamilyName,SpellFamilyMaskA,SpellFamilyMas ( 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,11,0x0000000000400000,0x00000000, -1, -1, -1, 3, -1,-1,'Rockbiter Weapon', 'Spell::EffectDummy'), +( 0,11,0x0000000000400000,0x00000000, -1, -1, -1, 54, -1,-1,'Rockbiter Weapon', 'Spell::EffectEnchantItemTmp'), ( 0, 6,0x0000000200000000,0x00000000, -1, -1, -1, 2, -1,-1,'Shadow Word: Death', 'Spell::EffectSchoolDMG'), ( 0, 5,0x0000000000000000,0x00000002, -1, -1, -1, -1, 3,-1,'Shadowflame', 'Spell::EffectSchoolDMG'), /* dot */ ( 0, 5,0x0001000000000000,0x00000000, -1, -1, -1, 2, -1,-1,'Shadowflame', 'Spell::EffectSchoolDMG'), /* explcit damage */ @@ -414,4 +413,5 @@ INSERT INTO spell_check (spellid,SpellFamilyName,SpellFamilyMaskA,SpellFamilyMas /* some random spells from not proccessed files sorted by spell ids */ /*id fm familyMaskA fmMaskB icon vis cat eff aur ef name code */ -(53563,-1, -1, -1, -1, -1, -1, -1, 4,-1,'Beacon of Light', 'Aura::HandleAuraDummy'); /* will outdated in 3.2.x */ +(53563,-1, -1, -1, -1, -1, -1, -1, 23,-1,'Beacon of Light', 'Aura::HandlePeriodicTriggerSpell'), +(53563,-1, -1, -1, -1, -1, -1, -1, 23,-1,'Beacon of Light', 'Unit::HandleDummyAuraProc'); diff --git a/sql/updates/8589_01_mangos_creature_template.sql b/sql/updates/8589_01_mangos_creature_template.sql new file mode 100644 index 000000000..44b5826f4 --- /dev/null +++ b/sql/updates/8589_01_mangos_creature_template.sql @@ -0,0 +1,5 @@ +ALTER TABLE db_version CHANGE COLUMN required_8573_01_mangos_mangos_string required_8589_01_mangos_creature_template bit; + +alter table `creature_template` + add column `questItem5` int(11) UNSIGNED DEFAULT '0' NOT NULL after `questItem4`, + add column `questItem6` int(11) UNSIGNED DEFAULT '0' NOT NULL after `questItem5`; diff --git a/sql/updates/8589_02_mangos_gameobject_template.sql b/sql/updates/8589_02_mangos_gameobject_template.sql new file mode 100644 index 000000000..c97e8403c --- /dev/null +++ b/sql/updates/8589_02_mangos_gameobject_template.sql @@ -0,0 +1,5 @@ +ALTER TABLE db_version CHANGE COLUMN required_8589_01_mangos_creature_template required_8589_02_mangos_gameobject_template bit; + +alter table `gameobject_template` + add column `questItem5` int(11) UNSIGNED DEFAULT '0' NOT NULL after `questItem4`, + add column `questItem6` int(11) UNSIGNED DEFAULT '0' NOT NULL after `questItem5`; diff --git a/sql/updates/8589_03_mangos_item_template.sql b/sql/updates/8589_03_mangos_item_template.sql new file mode 100644 index 000000000..872c4dbdc --- /dev/null +++ b/sql/updates/8589_03_mangos_item_template.sql @@ -0,0 +1,4 @@ +ALTER TABLE db_version CHANGE COLUMN required_8589_02_mangos_gameobject_template required_8589_03_mangos_item_template bit; + +alter table `item_template` + add column `Faction` int(11) UNSIGNED DEFAULT '0' NOT NULL after `Flags`; diff --git a/sql/updates/8589_04_characters_groups.sql b/sql/updates/8589_04_characters_groups.sql new file mode 100644 index 000000000..80a9dc4bc --- /dev/null +++ b/sql/updates/8589_04_characters_groups.sql @@ -0,0 +1,4 @@ +ALTER TABLE character_db_version CHANGE COLUMN required_8505_01_characters_character_spell required_8589_04_characters_groups bit; + +alter table `groups` + add column `raiddifficulty` int(11) UNSIGNED DEFAULT '0' NOT NULL after `difficulty`; diff --git a/sql/updates/8589_05_mangos_battleground_template.sql b/sql/updates/8589_05_mangos_battleground_template.sql new file mode 100644 index 000000000..514e5d3a3 --- /dev/null +++ b/sql/updates/8589_05_mangos_battleground_template.sql @@ -0,0 +1,4 @@ +ALTER TABLE db_version CHANGE COLUMN required_8589_03_mangos_item_template required_8589_05_mangos_battleground_template bit; + +insert into `battleground_template`(`id`,`MinPlayersPerTeam`,`MaxPlayersPerTeam`,`MinLvl`,`MaxLvl`,`AllianceStartLoc`,`AllianceStartO`,`HordeStartLoc`,`HordeStartO`) values (30,20,40,71,80,1485,0,1486,0); +insert into `battleground_template`(`id`,`MinPlayersPerTeam`,`MaxPlayersPerTeam`,`MinLvl`,`MaxLvl`,`AllianceStartLoc`,`AllianceStartO`,`HordeStartLoc`,`HordeStartO`) values (32,0,40,0,80,0,0,0,0); diff --git a/sql/updates/8589_06_characters_bugreport.sql b/sql/updates/8589_06_characters_bugreport.sql new file mode 100644 index 000000000..801c16c0c --- /dev/null +++ b/sql/updates/8589_06_characters_bugreport.sql @@ -0,0 +1,5 @@ +ALTER TABLE character_db_version CHANGE COLUMN required_8589_04_characters_groups required_8589_06_characters_bugreport bit; + +alter table `characters`.`bugreport` + change `type` `type` longtext NOT NULL, + change `content` `content` longtext NOT NULL; diff --git a/sql/updates/8589_07_mangos_spell_elixir.sql b/sql/updates/8589_07_mangos_spell_elixir.sql new file mode 100644 index 000000000..24f1769a2 --- /dev/null +++ b/sql/updates/8589_07_mangos_spell_elixir.sql @@ -0,0 +1,7 @@ +ALTER TABLE db_version CHANGE COLUMN required_8589_05_mangos_battleground_template required_8589_07_mangos_spell_elixir bit; + +DELETE FROM `spell_elixir` WHERE `entry`=67019; + +/* Flasks added in 3.2.x */ +INSERT INTO `spell_elixir` (`entry`, `mask`) VALUES +(67019,0x3); diff --git a/sql/updates/8589_08_mangos_item_template.sql b/sql/updates/8589_08_mangos_item_template.sql new file mode 100644 index 000000000..333408801 --- /dev/null +++ b/sql/updates/8589_08_mangos_item_template.sql @@ -0,0 +1,4 @@ +ALTER TABLE db_version CHANGE COLUMN required_8589_07_mangos_spell_elixir required_8589_08_mangos_item_template bit; + +ALTER TABLE item_template + CHANGE COLUMN ItemLevel ItemLevel smallint(5) unsigned NOT NULL DEFAULT 0; diff --git a/sql/updates/8589_09_mangos_spell_chain.sql b/sql/updates/8589_09_mangos_spell_chain.sql new file mode 100644 index 000000000..af393cf3d --- /dev/null +++ b/sql/updates/8589_09_mangos_spell_chain.sql @@ -0,0 +1,4 @@ +ALTER TABLE db_version CHANGE COLUMN required_8589_08_mangos_item_template required_8589_09_mangos_spell_chain bit; + +/* UnholyBlight non ranked now */ +DELETE FROM spell_chain WHERE first_spell = 49194; diff --git a/sql/updates/8589_10_mangos_spell_proc_event.sql b/sql/updates/8589_10_mangos_spell_proc_event.sql new file mode 100644 index 000000000..0ac64eef5 --- /dev/null +++ b/sql/updates/8589_10_mangos_spell_proc_event.sql @@ -0,0 +1,3 @@ +ALTER TABLE db_version CHANGE COLUMN required_8589_09_mangos_spell_chain required_8589_10_mangos_spell_proc_event bit; + +DELETE FROM spell_proc_event WHERE entry IN (58642,58676,44401); diff --git a/sql/updates/8589_11_characters_characters.sql b/sql/updates/8589_11_characters_characters.sql new file mode 100644 index 000000000..663f13518 --- /dev/null +++ b/sql/updates/8589_11_characters_characters.sql @@ -0,0 +1,17 @@ +ALTER TABLE character_db_version CHANGE COLUMN required_8589_06_characters_bugreport required_8589_11_characters_characters bit; + +UPDATE characters SET data = REPLACE(data,' ',' '); +UPDATE characters SET data = CONCAT(TRIM(data),' '); + +UPDATE `characters` SET `data` = CONCAT( + SUBSTRING_INDEX(`data`, ' ', 1167 + 1), ' ', + '0 0 ', + SUBSTRING_INDEX(SUBSTRING_INDEX(`data`, ' ', 1246 + 1), ' ', -1246 + 1168 - 1), ' ', + '0 0 0 ', + SUBSTRING_INDEX(SUBSTRING_INDEX(`data`, ' ', 1294 + 1), ' ', -1294 + 1247 - 1), ' ', + '0 ' + ) +WHERE length(SUBSTRING_INDEX(data, ' ', 1294)) < length(data) and length(SUBSTRING_INDEX(data, ' ', 1294+1)) >= length(data); + +UPDATE characters SET data = REPLACE(data,' ',' '); +UPDATE characters SET data = CONCAT(TRIM(data),' '); diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 457efe5b4..8040a6a77 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -117,6 +117,17 @@ pkgdata_DATA = \ 8548_02_mangos_gameobject_battleground.sql \ 8549_03_mangos_battleground_events.sql \ 8573_01_mangos_mangos_string.sql \ + 8589_01_mangos_creature_template.sql \ + 8589_02_mangos_gameobject_template.sql \ + 8589_03_mangos_item_template.sql \ + 8589_04_characters_groups.sql \ + 8589_05_mangos_battleground_template.sql \ + 8589_06_characters_bugreport.sql \ + 8589_07_mangos_spell_elixir.sql \ + 8589_08_mangos_item_template.sql \ + 8589_09_mangos_spell_chain.sql \ + 8589_10_mangos_spell_proc_event.sql \ + 8589_11_characters_characters.sql \ README ## Additional files to include when running 'make dist' @@ -214,4 +225,15 @@ EXTRA_DIST = \ 8548_02_mangos_gameobject_battleground.sql \ 8549_03_mangos_battleground_events.sql \ 8573_01_mangos_mangos_string.sql \ + 8589_01_mangos_creature_template.sql \ + 8589_02_mangos_gameobject_template.sql \ + 8589_03_mangos_item_template.sql \ + 8589_04_characters_groups.sql \ + 8589_05_mangos_battleground_template.sql \ + 8589_06_characters_bugreport.sql \ + 8589_07_mangos_spell_elixir.sql \ + 8589_08_mangos_item_template.sql \ + 8589_09_mangos_spell_chain.sql \ + 8589_10_mangos_spell_proc_event.sql \ + 8589_11_characters_characters.sql \ README diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index d3c72bc76..b21bb0571 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -196,10 +196,10 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) } return true; case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY: - if (difficalty.difficalty >= TOTAL_DIFFICULTIES) + if (difficulty.difficulty >= MAX_DIFFICULTY) { sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY (%u) have wrong difficulty in value1 (%u), ignore.", - criteria->ID, criteria->requiredType,dataType,difficalty.difficalty); + criteria->ID, criteria->requiredType,dataType,difficulty.difficulty); return false; } return true; @@ -294,7 +294,7 @@ bool AchievementCriteriaData::Meets(Player const* source, Unit const* target, ui case ACHIEVEMENT_CRITERIA_DATA_TYPE_DISABLED: return false; // always fail case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY: - return source->GetMap()->GetSpawnMode()==difficalty.difficalty; + return source->GetMap()->GetSpawnMode()==difficulty.difficulty; case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT: return source->GetMap()->GetPlayersCountExceptGMs() <= map_players.maxcount; case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM: @@ -902,7 +902,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if(!achievIdForDangeon[j][2]) break; // for } - else if(GetPlayer()->GetDifficulty()==DIFFICULTY_NORMAL) + else if(GetPlayer()->GetDungeonDifficulty()==DUNGEON_DIFFICULTY_NORMAL) { // dungeon in normal mode accepted if(!achievIdForDangeon[j][1]) diff --git a/src/game/AchievementMgr.h b/src/game/AchievementMgr.h index d0b0b90a5..eedd74700 100644 --- a/src/game/AchievementMgr.h +++ b/src/game/AchievementMgr.h @@ -125,8 +125,8 @@ struct AchievementCriteriaData // ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY = 12 struct { - uint32 difficalty; - } difficalty; + uint32 difficulty; + } difficulty; // ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT = 13 struct { diff --git a/src/game/ArenaTeam.cpp b/src/game/ArenaTeam.cpp index dbd785006..b9615a57c 100644 --- a/src/game/ArenaTeam.cpp +++ b/src/game/ArenaTeam.cpp @@ -99,7 +99,7 @@ bool ArenaTeam::AddMember(const uint64& PlayerGuid) return false; } - plClass = (uint8)pl->getClass(); + plClass = pl->getClass(); plName = pl->GetName(); } else @@ -150,13 +150,13 @@ bool ArenaTeam::AddMember(const uint64& PlayerGuid) if(pl) { - pl->SetInArenaTeam(m_TeamId, GetSlot()); + pl->SetInArenaTeam(m_TeamId, GetSlot(), GetType()); pl->SetArenaTeamIdInvited(0); - pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5, newmember.personal_rating ); + pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * ARENA_TEAM_END) + ARENA_TEAM_PERSONAL_RATING, newmember.personal_rating ); // hide promote/remove buttons if(m_CaptainGuid != PlayerGuid) - pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6) + 1, 1); + pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * ARENA_TEAM_END) + ARENA_TEAM_MEMBER, 1); } return true; } @@ -252,7 +252,7 @@ void ArenaTeam::SetCaptain(const uint64& guid) // disable remove/promote buttons Player *oldcaptain = objmgr.GetPlayer(GetCaptain()); if(oldcaptain) - oldcaptain->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1); + oldcaptain->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * ARENA_TEAM_END) + ARENA_TEAM_MEMBER, 1); // set new captain m_CaptainGuid = guid; @@ -263,7 +263,7 @@ void ArenaTeam::SetCaptain(const uint64& guid) // enable remove/promote buttons Player *newcaptain = objmgr.GetPlayer(guid); if(newcaptain) - newcaptain->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 0); + newcaptain->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * ARENA_TEAM_END) + ARENA_TEAM_MEMBER, 0); } void ArenaTeam::DelMember(uint64 guid) @@ -277,17 +277,12 @@ void ArenaTeam::DelMember(uint64 guid) } } - Player *player = objmgr.GetPlayer(guid); - - if(player) + if(Player *player = objmgr.GetPlayer(guid)) { - player->SetInArenaTeam(0, GetSlot()); player->GetSession()->SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, GetName(), "", 0); // delete all info regarding this team - for(int i = 0; i < 6; ++i) - { - player->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6) + i, 0); - } + for(int i = 0; i < ARENA_TEAM_END; ++i) + player->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * ARENA_TEAM_END) + i, 0); } CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid = '%u' AND guid = '%u'", GetId(), GUID_LOPART(guid)); @@ -540,14 +535,12 @@ void ArenaTeam::FinishGame(int32 mod) if (i->second->GetType() == this->m_Type && i->second->GetStats().rating > m_stats.rating) ++m_stats.rank; } - - } int32 ArenaTeam::WonAgainst(uint32 againstRating) { // called when the team has won - //'chance' calculation - to beat the opponent + // 'chance' calculation - to beat the opponent float chance = GetChanceAgainst(m_stats.rating, againstRating); // calculate the rating modification (ELO system with k=32) int32 mod = (int32)floor(32.0f * (1.0f - chance)); @@ -586,11 +579,11 @@ void ArenaTeam::MemberLost(Player * plr, uint32 againstRating) int32 mod = (int32)ceil(32.0f * (0.0f - chance)); itr->ModifyPersonalRating(plr, mod, GetSlot()); // update personal played stats - itr->games_week +=1; - itr->games_season +=1; + itr->games_week += 1; + itr->games_season += 1; // update the unit fields - plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 6 * GetSlot() + 2, itr->games_week); - plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 6 * GetSlot() + 3, itr->games_season); + plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * ARENA_TEAM_END) + ARENA_TEAM_GAMES_WEEK, itr->games_week); + plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * ARENA_TEAM_END) + ARENA_TEAM_GAMES_SEASON, itr->games_season); return; } } @@ -611,8 +604,8 @@ void ArenaTeam::OfflineMemberLost(uint64 guid, uint32 againstRating) else itr->personal_rating += mod; // update personal played stats - itr->games_week +=1; - itr->games_season +=1; + itr->games_week += 1; + itr->games_season += 1; return; } } @@ -630,13 +623,13 @@ void ArenaTeam::MemberWon(Player * plr, uint32 againstRating) int32 mod = (int32)floor(32.0f * (1.0f - chance)); itr->ModifyPersonalRating(plr, mod, GetSlot()); // update personal stats - itr->games_week +=1; - itr->games_season +=1; + itr->games_week += 1; + itr->games_season += 1; itr->wins_season += 1; itr->wins_week += 1; // update unit fields - plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 6 * GetSlot() + 2, itr->games_week); - plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 6 * GetSlot() + 3, itr->games_season); + plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * ARENA_TEAM_END) + ARENA_TEAM_GAMES_WEEK, itr->games_week); + plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * ARENA_TEAM_END) + ARENA_TEAM_GAMES_SEASON, itr->games_season); return; } } @@ -707,25 +700,3 @@ bool ArenaTeam::IsFighting() const } return false; } - -/* -arenateam fields (id from 2.3.3 client): -1414 - arena team id 2v2 -1415 - 0=captain, 1=member -1416 - played this week -1417 - played this season -1418 - unk - rank? -1419 - personal arena rating -1420 - arena team id 3v3 -1421 - 0=captain, 1=member -1422 - played this week -1423 - played this season -1424 - unk - rank? -1425 - personal arena rating -1426 - arena team id 5v5 -1427 - 0=captain, 1=member -1428 - played this week -1429 - played this season -1430 - unk - rank? -1431 - personal arena rating -*/ diff --git a/src/game/ArenaTeam.h b/src/game/ArenaTeam.h index b9e90ef27..822444b75 100644 --- a/src/game/ArenaTeam.h +++ b/src/game/ArenaTeam.h @@ -101,7 +101,7 @@ struct ArenaTeamMember else personal_rating += mod; if(plr) - plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot*6) + 5, personal_rating); + plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * ARENA_TEAM_END) + ARENA_TEAM_PERSONAL_RATING, personal_rating); } }; diff --git a/src/game/ArenaTeamHandler.cpp b/src/game/ArenaTeamHandler.cpp index ce5dda707..0fdfdadfc 100644 --- a/src/game/ArenaTeamHandler.cpp +++ b/src/game/ArenaTeamHandler.cpp @@ -54,12 +54,11 @@ void WorldSession::HandleArenaTeamQueryOpcode(WorldPacket & recv_data) uint32 ArenaTeamId; recv_data >> ArenaTeamId; - ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId); - if(!arenateam) // arena team not found - return; - - arenateam->Query(this); - arenateam->Stats(this); + if(ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId)) + { + arenateam->Query(this); + arenateam->Stats(this); + } } void WorldSession::HandleArenaTeamRosterOpcode(WorldPacket & recv_data) @@ -69,11 +68,8 @@ void WorldSession::HandleArenaTeamRosterOpcode(WorldPacket & recv_data) uint32 ArenaTeamId; // arena team id recv_data >> ArenaTeamId; - ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId); - if(!arenateam) - return; - - arenateam->Roster(this); + if(ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId)) + arenateam->Roster(this); } void WorldSession::HandleArenaTeamInviteOpcode(WorldPacket & recv_data) @@ -203,12 +199,14 @@ void WorldSession::HandleArenaTeamLeaveOpcode(WorldPacket & recv_data) ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId); if(!at) return; + if(_player->GetGUID() == at->GetCaptain() && at->GetMembersSize() > 1) { // check for correctness SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, "", "", ERR_ARENA_TEAM_LEADER_LEAVE_S); return; } + // arena team has only one member (=captain) if(_player->GetGUID() == at->GetCaptain()) { @@ -235,18 +233,17 @@ void WorldSession::HandleArenaTeamDisbandOpcode(WorldPacket & recv_data) uint32 ArenaTeamId; // arena team id recv_data >> ArenaTeamId; - ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId); - if(!at) - return; + if(ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId)) + { + if(at->GetCaptain() != _player->GetGUID()) + return; - if(at->GetCaptain() != _player->GetGUID()) - return; + if(at->IsFighting()) + return; - if (at->IsFighting()) - return; - - at->Disband(this); - delete at; + at->Disband(this); + delete at; + } } void WorldSession::HandleArenaTeamRemoveOpcode(WorldPacket & recv_data) diff --git a/src/game/AuctionHouseHandler.cpp b/src/game/AuctionHouseHandler.cpp index 80b3dee84..605b10e8e 100644 --- a/src/game/AuctionHouseHandler.cpp +++ b/src/game/AuctionHouseHandler.cpp @@ -151,8 +151,14 @@ void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data ) { uint64 auctioneer, item; uint32 etime, bid, buyout; - recv_data >> auctioneer >> item; - recv_data >> bid >> buyout >> etime; + recv_data >> auctioneer; + recv_data.read_skip(); // const 1? + recv_data >> item; + recv_data.read_skip(); // unk 3.2.2, const 1? + recv_data >> bid; + recv_data >> buyout; + recv_data >> etime; + Player *pl = GetPlayer(); if (!item || !bid || !etime) @@ -172,7 +178,6 @@ void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data ) return; } - // client send time in minutes, convert to common used sec time etime *= MINUTE; diff --git a/src/game/BattleGround.h b/src/game/BattleGround.h index ef7b3af24..6c24828ec 100644 --- a/src/game/BattleGround.h +++ b/src/game/BattleGround.h @@ -96,9 +96,9 @@ enum BattleGroundSpells enum BattleGroundTimeIntervals { RESURRECTION_INTERVAL = 30000, // ms - REMIND_INTERVAL = 30000, // ms - INVITATION_REMIND_TIME = 60000, // ms - INVITE_ACCEPT_WAIT_TIME = 80000, // ms + //REMIND_INTERVAL = 10000, // ms + INVITATION_REMIND_TIME = 20000, // ms + INVITE_ACCEPT_WAIT_TIME = 40000, // ms TIME_TO_AUTOREMOVE = 120000, // ms MAX_OFFLINE_TIME = 300, // secs RESPAWN_ONE_DAY = 86400, // secs @@ -158,11 +158,12 @@ enum BattleGroundQueueTypeId BATTLEGROUND_QUEUE_AB = 3, BATTLEGROUND_QUEUE_EY = 4, BATTLEGROUND_QUEUE_SA = 5, - BATTLEGROUND_QUEUE_2v2 = 6, - BATTLEGROUND_QUEUE_3v3 = 7, - BATTLEGROUND_QUEUE_5v5 = 8 + BATTLEGROUND_QUEUE_IC = 6, + BATTLEGROUND_QUEUE_2v2 = 7, + BATTLEGROUND_QUEUE_3v3 = 8, + BATTLEGROUND_QUEUE_5v5 = 9 }; -#define MAX_BATTLEGROUND_QUEUE_TYPES 9 +#define MAX_BATTLEGROUND_QUEUE_TYPES 10 enum BGQueueIdBasedOnLevel // queue_id for level ranges { diff --git a/src/game/BattleGroundAB.h b/src/game/BattleGroundAB.h index 22718e4f8..fdaa74c2b 100644 --- a/src/game/BattleGroundAB.h +++ b/src/game/BattleGroundAB.h @@ -96,8 +96,8 @@ enum BG_AB_Timers enum BG_AB_Score { - BG_AB_WARNING_NEAR_VICTORY_SCORE = 1800, - BG_AB_MAX_TEAM_SCORE = 2000 + BG_AB_WARNING_NEAR_VICTORY_SCORE = 1400, + BG_AB_MAX_TEAM_SCORE = 1600 }; /* do NOT change the order, else wrong behaviour */ diff --git a/src/game/BattleGroundABG.cpp b/src/game/BattleGroundABG.cpp new file mode 100644 index 000000000..0d934659f --- /dev/null +++ b/src/game/BattleGroundABG.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2005-2009 MaNGOS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Player.h" +#include "BattleGround.h" +#include "BattleGroundABG.h" +#include "Language.h" + +BattleGroundABG::BattleGroundABG() +{ + //TODO FIX ME! + m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_WS_START_TWO_MINUTES; + m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_WS_START_ONE_MINUTE; + m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_WS_START_HALF_MINUTE; + m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_WS_HAS_BEGUN; +} + +BattleGroundABG::~BattleGroundABG() +{ + +} + +void BattleGroundABG::Update(uint32 diff) +{ + BattleGround::Update(diff); +} + +void BattleGroundABG::StartingEventCloseDoors() +{ +} + +void BattleGroundABG::StartingEventOpenDoors() +{ +} + +void BattleGroundABG::AddPlayer(Player *plr) +{ + BattleGround::AddPlayer(plr); + //create score and add it to map, default values are set in constructor + BattleGroundABGScore* sc = new BattleGroundABGScore; + + m_PlayerScores[plr->GetGUID()] = sc; +} + +void BattleGroundABG::RemovePlayer(Player* /*plr*/,uint64 /*guid*/) +{ + +} + +void BattleGroundABG::HandleAreaTrigger(Player * /*Source*/, uint32 /*Trigger*/) +{ + // this is wrong way to implement these things. On official it done by gameobject spell cast. + if (GetStatus() != STATUS_IN_PROGRESS) + return; +} + +void BattleGroundABG::UpdatePlayerScore(Player* Source, uint32 type, uint32 value) +{ + + std::map::iterator itr = m_PlayerScores.find(Source->GetGUID()); + + if(itr == m_PlayerScores.end()) // player not found... + return; + + BattleGround::UpdatePlayerScore(Source,type,value); +} diff --git a/src/game/BattleGroundABG.h b/src/game/BattleGroundABG.h new file mode 100644 index 000000000..7d3e65ed3 --- /dev/null +++ b/src/game/BattleGroundABG.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2005-2009 MaNGOS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __BATTLEGROUNDABG_H +#define __BATTLEGROUNDABG_H + +class BattleGround; + +class BattleGroundABGScore : public BattleGroundScore +{ + public: + BattleGroundABGScore() {}; + virtual ~BattleGroundABGScore() {}; +}; + +class BattleGroundABG : public BattleGround +{ + friend class BattleGroundMgr; + + public: + BattleGroundABG(); + ~BattleGroundABG(); + void Update(uint32 diff); + + /* inherited from BattlegroundClass */ + virtual void AddPlayer(Player *plr); + virtual void StartingEventCloseDoors(); + virtual void StartingEventOpenDoors(); + + void RemovePlayer(Player *plr,uint64 guid); + void HandleAreaTrigger(Player *Source, uint32 Trigger); + //bool SetupBattleGround(); + + /* Scorekeeping */ + void UpdatePlayerScore(Player *Source, uint32 type, uint32 value); + + private: +}; +#endif diff --git a/src/game/BattleGroundEY.h b/src/game/BattleGroundEY.h index 7e688f4dd..d0bd7e75a 100644 --- a/src/game/BattleGroundEY.h +++ b/src/game/BattleGroundEY.h @@ -164,8 +164,8 @@ enum EYBattleGroundObjectTypes enum BG_EY_Score { - BG_EY_WARNING_NEAR_VICTORY_SCORE = 1800, - BG_EY_MAX_TEAM_SCORE = 2000 + BG_EY_WARNING_NEAR_VICTORY_SCORE = 1400, + BG_EY_MAX_TEAM_SCORE = 1600 }; enum BG_EY_FlagState diff --git a/src/game/BattleGroundHandler.cpp b/src/game/BattleGroundHandler.cpp index 6e8fafd29..56576a6d7 100644 --- a/src/game/BattleGroundHandler.cpp +++ b/src/game/BattleGroundHandler.cpp @@ -277,7 +277,10 @@ void WorldSession::HandleBattlefieldListOpcode( WorldPacket &recv_data ) recv_data >> bgTypeId; // id from DBC uint8 fromWhere; - recv_data >> fromWhere; // 0 - battlemaster, 1 - UI + recv_data >> fromWhere; // 0 - battlemaster (lua: ShowBattlefieldList), 1 - UI (lua: RequestBattlegroundInstanceInfo) + + uint8 unk1; + recv_data >> unk1; // unknown 3.2.2 BattlemasterListEntry const* bl = sBattlemasterListStore.LookupEntry(bgTypeId); if (!bl) @@ -708,7 +711,7 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data ) Player *member = itr->getSource(); // calc avg personal rating - avg_pers_rating += member->GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (arenaslot*6) + 5); + avg_pers_rating += member->GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (arenaslot * ARENA_TEAM_END) + ARENA_TEAM_PERSONAL_RATING); } if (arenatype) diff --git a/src/game/BattleGroundIC.cpp b/src/game/BattleGroundIC.cpp new file mode 100644 index 000000000..829dbcdb1 --- /dev/null +++ b/src/game/BattleGroundIC.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2005-2009 MaNGOS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Player.h" +#include "BattleGround.h" +#include "BattleGroundIC.h" +#include "Language.h" + +BattleGroundIC::BattleGroundIC() +{ + //TODO FIX ME! + m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_WS_START_TWO_MINUTES; + m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_WS_START_ONE_MINUTE; + m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_WS_START_HALF_MINUTE; + m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_WS_HAS_BEGUN; +} + +BattleGroundIC::~BattleGroundIC() +{ + +} + +void BattleGroundIC::Update(uint32 diff) +{ + BattleGround::Update(diff); +} + +void BattleGroundIC::StartingEventCloseDoors() +{ +} + +void BattleGroundIC::StartingEventOpenDoors() +{ +} + +void BattleGroundIC::AddPlayer(Player *plr) +{ + BattleGround::AddPlayer(plr); + //create score and add it to map, default values are set in constructor + BattleGroundICScore* sc = new BattleGroundICScore; + + m_PlayerScores[plr->GetGUID()] = sc; +} + +void BattleGroundIC::RemovePlayer(Player* /*plr*/,uint64 /*guid*/) +{ + +} + +void BattleGroundIC::HandleAreaTrigger(Player * /*Source*/, uint32 /*Trigger*/) +{ + // this is wrong way to implement these things. On official it done by gameobject spell cast. + if (GetStatus() != STATUS_IN_PROGRESS) + return; +} + +void BattleGroundIC::UpdatePlayerScore(Player* Source, uint32 type, uint32 value) +{ + + std::map::iterator itr = m_PlayerScores.find(Source->GetGUID()); + + if(itr == m_PlayerScores.end()) // player not found... + return; + + BattleGround::UpdatePlayerScore(Source,type,value); +} diff --git a/src/game/BattleGroundIC.h b/src/game/BattleGroundIC.h new file mode 100644 index 000000000..9ca0f6d13 --- /dev/null +++ b/src/game/BattleGroundIC.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2005-2009 MaNGOS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __BATTLEGROUNDIC_H +#define __BATTLEGROUNDIC_H + +class BattleGround; + +class BattleGroundICScore : public BattleGroundScore +{ + public: + BattleGroundICScore() {}; + virtual ~BattleGroundICScore() {}; +}; + +class BattleGroundIC : public BattleGround +{ + friend class BattleGroundMgr; + + public: + BattleGroundIC(); + ~BattleGroundIC(); + void Update(uint32 diff); + + /* inherited from BattlegroundClass */ + virtual void AddPlayer(Player *plr); + virtual void StartingEventCloseDoors(); + virtual void StartingEventOpenDoors(); + + void RemovePlayer(Player *plr,uint64 guid); + void HandleAreaTrigger(Player *Source, uint32 Trigger); + //bool SetupBattleGround(); + + /* Scorekeeping */ + void UpdatePlayerScore(Player *Source, uint32 type, uint32 value); + + private: +}; +#endif diff --git a/src/game/BattleGroundMgr.cpp b/src/game/BattleGroundMgr.cpp index 6d28ff0cc..b885595aa 100644 --- a/src/game/BattleGroundMgr.cpp +++ b/src/game/BattleGroundMgr.cpp @@ -31,6 +31,8 @@ #include "BattleGroundSA.h" #include "BattleGroundDS.h" #include "BattleGroundRV.h" +#include "BattleGroundIC.h" +#include "BattleGroundABG.h" #include "MapManager.h" #include "Map.h" #include "MapInstanced.h" @@ -1404,6 +1406,8 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg) case BATTLEGROUND_SA: // wotlk case BATTLEGROUND_DS: // wotlk case BATTLEGROUND_RV: // wotlk + case BATTLEGROUND_IC: // wotlk + case BATTLEGROUND_ABG: // wotlk *data << (int32)0; // 0 break; default: @@ -1581,6 +1585,12 @@ BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeI case BATTLEGROUND_RV: bg = new BattleGroundRV(*(BattleGroundRV*)bg_template); break; + case BATTLEGROUND_IC: + bg = new BattleGroundIC(*(BattleGroundIC*)bg_template); + break; + case BATTLEGROUND_ABG: + bg = new BattleGroundABG(*(BattleGroundABG*)bg_template); + break; default: //error, but it is handled few lines above return 0; @@ -1620,7 +1630,9 @@ uint32 BattleGroundMgr::CreateBattleGround(BattleGroundTypeId bgTypeId, bool IsA case BATTLEGROUND_SA: bg = new BattleGroundSA; break; case BATTLEGROUND_DS: bg = new BattleGroundDS; break; case BATTLEGROUND_RV: bg = new BattleGroundRV; break; - default: bg = new BattleGround; break; // placeholder for non implemented BG + case BATTLEGROUND_IC: bg = new BattleGroundIC; break; + case BATTLEGROUND_ABG: bg = new BattleGroundABG; break; + default:bg = new BattleGround; break; // placeholder for non implemented BG } bg->SetMapId(MapID); @@ -1714,7 +1726,7 @@ void BattleGroundMgr::CreateInitialBattleGrounds() AStartLoc[2] = start->z; AStartLoc[3] = fields[6].GetFloat(); } - else if (bgTypeID == BATTLEGROUND_AA) + else if (bgTypeID == BATTLEGROUND_AA || bgTypeID == BATTLEGROUND_ABG) { AStartLoc[0] = 0; AStartLoc[1] = 0; @@ -1737,7 +1749,7 @@ void BattleGroundMgr::CreateInitialBattleGrounds() HStartLoc[2] = start->z; HStartLoc[3] = fields[8].GetFloat(); } - else if (bgTypeID == BATTLEGROUND_AA) + else if (bgTypeID == BATTLEGROUND_AA || bgTypeID == BATTLEGROUND_ABG) { HStartLoc[0] = 0; HStartLoc[1] = 0; @@ -1912,6 +1924,10 @@ BattleGroundQueueTypeId BattleGroundMgr::BGQueueTypeId(BattleGroundTypeId bgType return BATTLEGROUND_QUEUE_EY; case BATTLEGROUND_SA: return BATTLEGROUND_QUEUE_SA; + case BATTLEGROUND_IC: + return BATTLEGROUND_QUEUE_IC; + case BATTLEGROUND_ABG: + return BATTLEGROUND_QUEUE_NONE; case BATTLEGROUND_AA: case BATTLEGROUND_NA: case BATTLEGROUND_RL: @@ -1948,6 +1964,8 @@ BattleGroundTypeId BattleGroundMgr::BGTemplateId(BattleGroundQueueTypeId bgQueue return BATTLEGROUND_EY; case BATTLEGROUND_QUEUE_SA: return BATTLEGROUND_SA; + case BATTLEGROUND_QUEUE_IC: + return BATTLEGROUND_IC; case BATTLEGROUND_QUEUE_2v2: case BATTLEGROUND_QUEUE_3v3: case BATTLEGROUND_QUEUE_5v5: diff --git a/src/game/CalendarHandler.cpp b/src/game/CalendarHandler.cpp index 944197dee..84c4c5aab 100644 --- a/src/game/CalendarHandler.cpp +++ b/src/game/CalendarHandler.cpp @@ -44,7 +44,7 @@ void WorldSession::HandleCalendarGetCalendar(WorldPacket &recv_data) size_t p_counter = data.wpos(); data << uint32(counter); // instance save count - for(int i = 0; i < TOTAL_DIFFICULTIES; ++i) + for(int i = 0; i < MAX_DIFFICULTY; ++i) { for (Player::BoundInstancesMap::const_iterator itr = _player->m_boundInstances[i].begin(); itr != _player->m_boundInstances[i].end(); ++itr) { diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index 753c6be83..20ac51d75 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -69,16 +69,16 @@ bool LoginQueryHolder::Initialize() res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADREPUTATION, "SELECT faction,standing,flags FROM character_reputation WHERE guid = '%u'", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADINVENTORY, "SELECT data,bag,slot,item,item_template FROM character_inventory JOIN item_instance ON character_inventory.item = item_instance.guid WHERE character_inventory.guid = '%u' ORDER BY bag,slot", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADACTIONS, "SELECT button,action,type FROM character_action WHERE guid = '%u' ORDER BY button", GUID_LOPART(m_guid)); - res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADMAILCOUNT, "SELECT COUNT(id) FROM mail WHERE receiver = '%u' AND (checked & 1)=0 AND deliver_time <= '" UI64FMTD "'", GUID_LOPART(m_guid),(uint64)time(NULL)); + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADMAILCOUNT, "SELECT COUNT(id) FROM mail WHERE receiver = '%u' AND (checked & 1)=0 AND deliver_time <= '" UI64FMTD "'", GUID_LOPART(m_guid), (uint64)time(NULL)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADMAILDATE, "SELECT MIN(deliver_time) FROM mail WHERE receiver = '%u' AND (checked & 1)=0", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSOCIALLIST, "SELECT friend,flags,note FROM character_social WHERE guid = '%u' LIMIT 255", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADHOMEBIND, "SELECT map,zone,position_x,position_y,position_z FROM character_homebind WHERE guid = '%u'", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSPELLCOOLDOWNS, "SELECT spell,item,time FROM character_spell_cooldown WHERE guid = '%u'", GUID_LOPART(m_guid)); if(sWorld.getConfig(CONFIG_DECLINED_NAMES_USED)) - res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADDECLINEDNAMES, "SELECT genitive, dative, accusative, instrumental, prepositional FROM character_declinedname WHERE guid = '%u'",GUID_LOPART(m_guid)); + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADDECLINEDNAMES, "SELECT genitive, dative, accusative, instrumental, prepositional FROM character_declinedname WHERE guid = '%u'", GUID_LOPART(m_guid)); // in other case still be dummy query res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGUILD, "SELECT guildid,rank FROM guild_member WHERE guid = '%u'", GUID_LOPART(m_guid)); - res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADARENAINFO, "SELECT arenateamid, played_week, played_season, personal_rating FROM arena_team_member WHERE guid='%u'", GUID_LOPART(m_guid)); + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADARENAINFO, "SELECT arenateamid, played_week, played_season, wons_season, personal_rating FROM arena_team_member WHERE guid='%u'", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADACHIEVEMENTS, "SELECT achievement, date FROM character_achievement WHERE guid = '%u'", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADCRITERIAPROGRESS,"SELECT criteria, counter, date FROM character_achievement_progress WHERE guid = '%u'", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADEQUIPMENTSETS, "SELECT setguid, setindex, name, iconname, item0, item1, item2, item3, item4, item5, item6, item7, item8, item9, item10, item11, item12, item13, item14, item15, item16, item17, item18 FROM character_equipmentsets WHERE guid = '%u' ORDER BY setindex", GUID_LOPART(m_guid)); @@ -130,7 +130,7 @@ void WorldSession::HandleCharEnum(QueryResult * result) do { uint32 guidlow = (*result)[0].GetUInt32(); - sLog.outDetail("Loading char guid %u from account %u.",guidlow,GetAccountId()); + sLog.outDetail("Loading char guid %u from account %u.", guidlow, GetAccountId()); if(Player::BuildEnumData(result, &data)) ++num; } @@ -171,13 +171,13 @@ void WorldSession::HandleCharEnumOpcode( WorldPacket & /*recv_data*/ ) "LEFT JOIN character_declinedname ON characters.guid = character_declinedname.guid " "LEFT JOIN guild_member ON characters.guid = guild_member.guid " "WHERE characters.account = '%u' ORDER BY characters.guid", - PET_SAVE_AS_CURRENT,GetAccountId()); + PET_SAVE_AS_CURRENT, GetAccountId()); } void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) { std::string name; - uint8 race_,class_; + uint8 race_, class_; recv_data >> name; @@ -195,8 +195,8 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) uint32 team = Player::TeamForRace(race_); switch(team) { - case ALLIANCE: disabled = mask & (1<<0); break; - case HORDE: disabled = mask & (1<<1); break; + case ALLIANCE: disabled = mask & (1 << 0); break; + case HORDE: disabled = mask & (1 << 1); break; } if(disabled) @@ -220,19 +220,19 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) } // prevent character creating Expansion race without Expansion account - if (raceEntry->addon > Expansion()) + if (raceEntry->expansion > Expansion()) { data << (uint8)CHAR_CREATE_EXPANSION; - sLog.outError("Expansion %u account:[%d] tried to Create character with expansion %u race (%u)",Expansion(),GetAccountId(),raceEntry->addon,race_); + sLog.outError("Expansion %u account:[%d] tried to Create character with expansion %u race (%u)", Expansion(), GetAccountId(), raceEntry->expansion, race_); SendPacket( &data ); return; } // prevent character creating Expansion class without Expansion account - if (classEntry->addon > Expansion()) + if (classEntry->expansion > Expansion()) { data << (uint8)CHAR_CREATE_EXPANSION_CLASS; - sLog.outError("Expansion %u account:[%d] tried to Create character with expansion %u class (%u)",Expansion(),GetAccountId(),classEntry->addon,class_); + sLog.outError("Expansion %u account:[%d] tried to Create character with expansion %u class (%u)", Expansion(), GetAccountId(), classEntry->expansion, class_); SendPacket( &data ); return; } @@ -242,12 +242,12 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) { data << (uint8)CHAR_NAME_NO_NAME; SendPacket( &data ); - sLog.outError("Account:[%d] but tried to Create character with empty [name] ",GetAccountId()); + sLog.outError("Account:[%d] but tried to Create character with empty [name]", GetAccountId()); return; } // check name limitations - uint8 res = ObjectMgr::CheckPlayerName(name,true); + uint8 res = ObjectMgr::CheckPlayerName(name, true); if (res != CHAR_NAME_SUCCESS) { data << uint8(res); @@ -288,7 +288,7 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) uint8 charcount = 0; if ( result ) { - Field *fields=result->Fetch(); + Field *fields = result->Fetch(); charcount = fields[0].GetUInt8(); delete result; @@ -302,7 +302,7 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) // speedup check for heroic class disabled case uint32 heroic_free_slots = sWorld.getConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM); - if(heroic_free_slots==0 && GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT) + if(heroic_free_slots == 0 && GetSecurity() == SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT) { data << (uint8)CHAR_CREATE_UNIQUE_CLASS_LIMIT; SendPacket( &data ); @@ -311,14 +311,14 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) // speedup check for heroic class disabled case uint32 req_level_for_heroic = sWorld.getConfig(CONFIG_MIN_LEVEL_FOR_HEROIC_CHARACTER_CREATING); - if(GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT && req_level_for_heroic > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) + if(GetSecurity() == SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT && req_level_for_heroic > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) { data << (uint8)CHAR_CREATE_LEVEL_REQUIREMENT; SendPacket( &data ); return; } - bool AllowTwoSideAccounts = !sWorld.IsPvPRealm() || sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || GetSecurity() > SEC_PLAYER; + bool AllowTwoSideAccounts = sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || GetSecurity() > SEC_PLAYER; uint32 skipCinematics = sWorld.getConfig(CONFIG_SKIP_CINEMATICS); bool have_same_race = false; @@ -337,7 +337,7 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) Field* field = result2->Fetch(); uint8 acc_race = field[1].GetUInt32(); - if(GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT) + if(GetSecurity() == SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT) { uint8 acc_class = field[2].GetUInt32(); if(acc_class == CLASS_DEATH_KNIGHT) @@ -345,7 +345,7 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) if(heroic_free_slots > 0) --heroic_free_slots; - if(heroic_free_slots==0) + if(heroic_free_slots == 0) { data << (uint8)CHAR_CREATE_UNIQUE_CLASS_LIMIT; SendPacket( &data ); @@ -365,7 +365,7 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) // TODO: what to if account already has characters of both races? if (!AllowTwoSideAccounts) { - uint32 acc_team=0; + uint32 acc_team = 0; if(acc_race > 0) acc_team = Player::TeamForRace(acc_race); @@ -391,7 +391,7 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) if(!have_same_race) have_same_race = race_ == acc_race; - if(GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT) + if(GetSecurity() == SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT) { uint8 acc_class = field[2].GetUInt32(); if(acc_class == CLASS_DEATH_KNIGHT) @@ -399,7 +399,7 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) if(heroic_free_slots > 0) --heroic_free_slots; - if(heroic_free_slots==0) + if(heroic_free_slots == 0) { data << (uint8)CHAR_CREATE_UNIQUE_CLASS_LIMIT; SendPacket( &data ); @@ -419,7 +419,7 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) } } - if(GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT && !have_req_level_for_heroic) + if(GetSecurity() == SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT && !have_req_level_for_heroic) { data << (uint8)CHAR_CREATE_LEVEL_REQUIREMENT; SendPacket( &data ); @@ -431,7 +431,7 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) recv_data >> gender >> skin >> face; recv_data >> hairStyle >> hairColor >> facialHair >> outfitId; - Player * pNewChar = new Player(this); + Player *pNewChar = new Player(this); if(!pNewChar->Create( objmgr.GenerateLowGuid(HIGHGUID_PLAYER), name, race_, class_, gender, skin, face, hairStyle, hairColor, facialHair, outfitId )) { // Player not create (race/class problem?) @@ -448,7 +448,7 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) // Player created, save it now pNewChar->SaveToDB(); - charcount+=1; + charcount += 1; loginDatabase.PExecute("DELETE FROM realmcharacters WHERE acctid= '%d' AND realmid = '%d'", GetAccountId(), realmID); loginDatabase.PExecute("INSERT INTO realmcharacters (numchars, acctid, realmid) VALUES (%u, %u, %u)", charcount, GetAccountId(), realmID); @@ -459,8 +459,8 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) SendPacket( &data ); std::string IP_str = GetRemoteAddress(); - sLog.outBasic("Account: %d (IP: %s) Create Character:[%s]",GetAccountId(),IP_str.c_str(),name.c_str()); - sLog.outChar("Account: %d (IP: %s) Create Character:[%s]",GetAccountId(),IP_str.c_str(),name.c_str()); + sLog.outBasic("Account: %d (IP: %s) Create Character:[%s]", GetAccountId(), IP_str.c_str(), name.c_str()); + sLog.outChar("Account: %d (IP: %s) Create Character:[%s]", GetAccountId(), IP_str.c_str(), name.c_str()); } void WorldSession::HandleCharDeleteOpcode( WorldPacket & recv_data ) @@ -507,13 +507,13 @@ void WorldSession::HandleCharDeleteOpcode( WorldPacket & recv_data ) return; std::string IP_str = GetRemoteAddress(); - sLog.outBasic("Account: %d (IP: %s) Delete Character:[%s] (guid: %u)",GetAccountId(),IP_str.c_str(),name.c_str(),GUID_LOPART(guid)); - sLog.outChar("Account: %d (IP: %s) Delete Character:[%s] (guid: %u)",GetAccountId(),IP_str.c_str(),name.c_str(),GUID_LOPART(guid)); + sLog.outBasic("Account: %d (IP: %s) Delete Character:[%s] (guid: %u)", GetAccountId(), IP_str.c_str(), name.c_str(), GUID_LOPART(guid)); + sLog.outChar("Account: %d (IP: %s) Delete Character:[%s] (guid: %u)", GetAccountId(), IP_str.c_str(), name.c_str(), GUID_LOPART(guid)); if(sLog.IsOutCharDump()) // optimize GetPlayerDump call { std::string dump = PlayerDumpWriter().GetDump(GUID_LOPART(guid)); - sLog.outCharDump(dump.c_str(),GetAccountId(),GUID_LOPART(guid),name.c_str()); + sLog.outCharDump(dump.c_str(), GetAccountId(), GUID_LOPART(guid), name.c_str()); } Player::DeleteFromDB(guid, GetAccountId()); @@ -527,7 +527,7 @@ void WorldSession::HandlePlayerLoginOpcode( WorldPacket & recv_data ) { if(PlayerLoading() || GetPlayer() != NULL) { - sLog.outError("Player tryes to login again, AccountId = %d",GetAccountId()); + sLog.outError("Player tryes to login again, AccountId = %d", GetAccountId()); return; } @@ -549,11 +549,11 @@ void WorldSession::HandlePlayerLoginOpcode( WorldPacket & recv_data ) CharacterDatabase.DelayQueryHolder(&chrHandler, &CharacterHandler::HandlePlayerLoginCallback, holder); } -void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) +void WorldSession::HandlePlayerLogin(LoginQueryHolder *holder) { uint64 playerGuid = holder->GetGuid(); - Player* pCurrChar = new Player(this); + Player *pCurrChar = new Player(this); pCurrChar->GetMotionMaster()->Initialize(); // "GetAccountId()==db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools) @@ -580,7 +580,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) // load player specific part before send times LoadAccountData(holder->GetResult(PLAYER_LOGIN_QUERY_LOADACCOUNTDATA),PER_CHARACTER_CACHE_MASK); - SendAccountDataTimes(); + SendAccountDataTimes(PER_CHARACTER_CACHE_MASK); data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 2); // added in 2.2.0 data << uint8(2); // unknown value @@ -601,13 +601,13 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) { if (nextpos != pos) { - data << str_motd.substr(pos,nextpos-pos); + data << str_motd.substr(pos, nextpos-pos); ++linecount; } - pos = nextpos+1; + pos = nextpos + 1; } - if (posGetGUIDLow()); QueryResult *resultGuild = holder->GetResult(PLAYER_LOGIN_QUERY_LOADGUILD); @@ -671,6 +666,11 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) } } + data.Initialize(SMSG_LEARNED_DANCE_MOVES, 4+4); + data << uint32(0); + data << uint32(0); + SendPacket(&data); + if(!pCurrChar->isAlive()) pCurrChar->SendCorpseReclaimDelay(true); @@ -774,7 +774,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) std::string IP_str = GetRemoteAddress(); sLog.outChar("Account: %d (IP: %s) Login Character:[%s] (guid:%u)", - GetAccountId(),IP_str.c_str(),pCurrChar->GetName() ,pCurrChar->GetGUIDLow()); + GetAccountId(), IP_str.c_str(), pCurrChar->GetName(), pCurrChar->GetGUIDLow()); if(!pCurrChar->IsStandState() && !pCurrChar->hasUnitState(UNIT_STAT_STUNNED)) pCurrChar->SetStandState(UNIT_STAND_STATE_STAND); @@ -793,7 +793,7 @@ void WorldSession::HandleSetFactionAtWar( WorldPacket & recv_data ) recv_data >> repListID; recv_data >> flag; - GetPlayer()->GetReputationMgr().SetAtWar(repListID,flag); + GetPlayer()->GetReputationMgr().SetAtWar(repListID, flag); } //I think this function is never used :/ I dunno, but i guess this opcode not exists diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index 123572e02..c024989ff 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -157,11 +157,12 @@ ChatCommand * ChatHandler::getCommandTable() { "getitemstate", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugGetItemStateCommand, "", NULL }, { "lootrecipient", SEC_GAMEMASTER, false, &ChatHandler::HandleDebugGetLootRecipientCommand, "", NULL }, { "getvalue", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugGetValueCommand, "", NULL }, + { "getitemvalue", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugGetItemValueCommand, "", 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 }, + { "setitemvalue", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSetItemValueCommand, "", NULL }, { "setvalue", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSetValueCommand, "", NULL }, { "spellcheck", SEC_CONSOLE, true, &ChatHandler::HandleDebugSpellCheckCommand, "", NULL }, { "spawnvehicle", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSpawnVehicle, "", NULL }, diff --git a/src/game/Chat.h b/src/game/Chat.h index ece18768e..45a029346 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -133,9 +133,10 @@ class ChatHandler bool HandleDebugGetItemStateCommand(const char * args); bool HandleDebugGetLootRecipientCommand(const char * args); bool HandleDebugGetValueCommand(const char* args); + bool HandleDebugGetItemValueCommand(const char* args); bool HandleDebugMod32ValueCommand(const char* args); bool HandleDebugSetAuraStateCommand(const char * args); - bool HandleDebugSetItemFlagCommand(const char * args); + bool HandleDebugSetItemValueCommand(const char * args); bool HandleDebugSetValueCommand(const char* args); bool HandleDebugSpawnVehicle(const char * args); bool HandleDebugSpellCheckCommand(const char* args); diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 35da7f57c..4872e282d 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -1526,7 +1526,7 @@ void Creature::setDeathState(DeathState s) if(s == JUST_DIED) { - SetUInt64Value(UNIT_FIELD_TARGET,0); // remove target selection in any cases (can be set at aura remove in Unit::setDeathState) + SetTargetGUID(0); // remove target selection in any cases (can be set at aura remove in Unit::setDeathState) SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE); if(!isPet() && GetCreatureInfo()->SkinLootId) diff --git a/src/game/Creature.h b/src/game/Creature.h index 617b1fcbc..1e2f01076 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -217,7 +217,7 @@ struct CreatureInfo float unk16; float unk17; bool RacialLeader; - uint32 questItems[4]; + uint32 questItems[6]; uint32 movementId; bool RegenHealth; uint32 equipmentId; diff --git a/src/game/DBCStores.cpp b/src/game/DBCStores.cpp index 9050a1b52..62782159b 100644 --- a/src/game/DBCStores.cpp +++ b/src/game/DBCStores.cpp @@ -96,6 +96,12 @@ DBCStorage sLockStore(LockEntryfmt); DBCStorage sMailTemplateStore(MailTemplateEntryfmt); DBCStorage sMapStore(MapEntryfmt); + +// DBC used only for initialization sMapDifficultyMap at startup. +DBCStorage sMapDifficultyStore(MapDifficultyEntryfmt); // only for loading +typedef std::map MapDifficultyMap; +MapDifficultyMap sMapDifficultyMap; + DBCStorage sMovieStore(MovieEntryfmt); DBCStorage sQuestSortStore(QuestSortEntryfmt); @@ -129,7 +135,7 @@ TalentSpellPosMap sTalentSpellPosMap; DBCStorage sTalentTabStore(TalentTabEntryfmt); // store absolute bit position for first rank for talent inspect -static uint32 sTalentTabPages[12/*MAX_CLASSES*/][3]; +static uint32 sTalentTabPages[MAX_CLASSES][3]; DBCStorage sTaxiNodesStore(TaxiNodesEntryfmt); TaxiMask sTaxiNodesMask; @@ -139,10 +145,10 @@ TaxiMask sOldContinentsNodesMask; TaxiPathSetBySource sTaxiPathSetBySource; DBCStorage sTaxiPathStore(TaxiPathEntryfmt); -// DBC used only for initialization sTaxiPathSetBySource at startup. +// DBC used only for initialization sTaxiPathNodeStore at startup. TaxiPathNodesByPath sTaxiPathNodesByPath; - static DBCStorage sTaxiPathNodeStore(TaxiPathNodeEntryfmt); + DBCStorage sTotemCategoryStore(TotemCategoryEntryfmt); DBCStorage sVehicleStore(VehicleEntryfmt); DBCStorage sVehicleSeatStore(VehicleSeatEntryfmt); @@ -200,7 +206,7 @@ void LoadDBCStores(const std::string& dataPath) { std::string dbcPath = dataPath+"dbc/"; - const uint32 DBCFilesCount = 79; + const uint32 DBCFilesCount = 80; barGoLink bar( DBCFilesCount ); @@ -232,7 +238,6 @@ void LoadDBCStores(const std::string& dataPath) LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBattlemasterListStore, dbcPath,"BattlemasterList.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBarberShopStyleStore, dbcPath,"BarberShopStyle.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharStartOutfitStore, dbcPath,"CharStartOutfit.dbc"); - LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharTitlesStore, dbcPath,"CharTitles.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChatChannelsStore, dbcPath,"ChatChannels.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrClassesStore, dbcPath,"ChrClasses.dbc"); @@ -290,6 +295,14 @@ void LoadDBCStores(const std::string& dataPath) LoadDBC(availableDbcLocales,bar,bad_dbc_files,sLockStore, dbcPath,"Lock.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMailTemplateStore, dbcPath,"MailTemplate.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMapStore, dbcPath,"Map.dbc"); + + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMapDifficultyStore, dbcPath,"MapDifficulty.dbc"); + // fill data + for(uint32 i = 1; i < sMapDifficultyStore.GetNumRows(); ++i) + if(MapDifficultyEntry const* entry = sMapDifficultyStore.LookupEntry(i)) + sMapDifficultyMap[MAKE_PAIR32(entry->MapId,entry->Difficulty)] = MapDifficulty(entry->resetTime,entry->maxPlayers); + sMapDifficultyStore.Clear(); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMovieStore, dbcPath,"Movie.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestSortStore, dbcPath,"QuestSort.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sRandomPropertiesPointsStore, dbcPath,"RandPropPoints.dbc"); @@ -659,6 +672,12 @@ void Map2ZoneCoordinates(float& x,float& y,uint32 zone) std::swap(x,y); // client have map coords swapped } +MapDifficulty const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty) +{ + MapDifficultyMap::const_iterator itr = sMapDifficultyMap.find(MAKE_PAIR32(mapId,difficulty)); + return itr != sMapDifficultyMap.end() ? &itr->second : NULL; +} + uint32 const* GetTalentTabPages(uint32 cls) { return sTalentTabPages[cls]; diff --git a/src/game/DBCStores.h b/src/game/DBCStores.h index b41a3c94e..4a4761620 100644 --- a/src/game/DBCStores.h +++ b/src/game/DBCStores.h @@ -54,6 +54,8 @@ bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId, uint32 requiredT void Zone2MapCoordinates(float& x,float& y,uint32 zone); void Map2ZoneCoordinates(float& x,float& y,uint32 zone); +MapDifficulty const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty); + uint32 const* /*[3]*/ GetTalentTabPages(uint32 cls); extern DBCStorage sAchievementStore; @@ -109,6 +111,7 @@ extern DBCStorage sItemSetStore; extern DBCStorage sLockStore; extern DBCStorage sMailTemplateStore; extern DBCStorage sMapStore; +//extern DBCStorage sMapDifficultyStore; -- use GetMapDifficultyData insteed extern DBCStorage sMovieStore; extern DBCStorage sQuestSortStore; extern DBCStorage sRandomPropertiesPointsStore; diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h index b7ea2724c..ce364eba9 100644 --- a/src/game/DBCStructure.h +++ b/src/game/DBCStructure.h @@ -630,7 +630,7 @@ struct ChrClassesEntry uint32 spellfamily; // 56 // 57, unused uint32 CinematicSequence; // 58 id from CinematicSequences.dbc - uint32 addon; // 59 (0 - original race, 1 - tbc addon, ...) + uint32 expansion; // 59 (0 - original race, 1 - tbc addon, ...) }; struct ChrRacesEntry @@ -641,10 +641,11 @@ struct ChrRacesEntry // 3 unused uint32 model_m; // 4 uint32 model_f; // 5 - // 6-7 unused - uint32 TeamID; // 8 (7-Alliance 1-Horde) - // 9-12 unused - uint32 CinematicSequence; // 13 id from CinematicSequences.dbc + // 6 unused + uint32 TeamID; // 7 (7-Alliance 1-Horde) + // 8-11 unused + uint32 CinematicSequence; // 12 id from CinematicSequences.dbc + //uint32 unk_322; // 13 faction (0 alliance, 1 horde, 2 not available?) char* name[16]; // 14-29 used for DBC language detection/selection // 30 string flags, unused //char* nameFemale[16]; // 31-46, if different from base (male) case @@ -652,7 +653,7 @@ struct ChrRacesEntry //char* nameNeutralGender[16]; // 48-63, if different from base (male) case // 64 string flags, unused // 65-67 unused - uint32 addon; // 68 (0 - original race, 1 - tbc addon, ...) + uint32 expansion; // 68 (0 - original race, 1 - tbc addon, ...) }; /* not used @@ -962,7 +963,7 @@ struct ItemEntry { uint32 ID; // 0 uint32 Class; // 1 - uint32 SubClass; // 2 some items have strnage subclasses + uint32 SubClass; // 2 some items have strange subclasses int32 Unk0; // 3 int32 Material; // 4 uint32 DisplayId; // 5 @@ -1006,9 +1007,10 @@ struct ItemExtendedCostEntry uint32 ID; // 0 extended-cost entry id uint32 reqhonorpoints; // 1 required honor points uint32 reqarenapoints; // 2 required arena points - uint32 reqitem[5]; // 3-7 required item id - uint32 reqitemcount[5]; // 8-12 required count of 1st item - uint32 reqpersonalarenarating; // 13 required personal arena rating + //uint32 unk1; // 4 probably indicates new 2v2 bracket restrictions + uint32 reqitem[5]; // 5-8 required item id + uint32 reqitemcount[5]; // 9-13 required count of 1st item + uint32 reqpersonalarenarating; // 14 required personal arena rating }; struct ItemLimitCategoryEntry @@ -1085,21 +1087,13 @@ struct MapEntry // 55 intro text flags uint32 multimap_id; // 56 // 57 - //chat* unknownText1[16]; // 58-73 unknown empty text fields, possible normal Intro text. - // 74 text flags - //chat* heroicIntroText[16]; // 75-90 heroic mode requirement text - // 91 text flags - //chat* unknownText2[16]; // 92-107 unknown empty text fields - // 108 text flags - int32 entrance_map; // 109 map_id of entrance map - float entrance_x; // 110 entrance x coordinate (if exist single entry) - float entrance_y; // 111 entrance y coordinate (if exist single entry) - uint32 resetTimeRaid; // 112 - uint32 resetTimeHeroic; // 113 - // 114 all 0 - // 115 -1, 0 and 720 - uint32 addon; // 116 (0-original maps,1-tbc addon) - // 117 some kind of time? + int32 entrance_map; // 58 map_id of entrance map + float entrance_x; // 59 entrance x coordinate (if exist single entry) + float entrance_y; // 60 entrance y coordinate (if exist single entry) + // 61 -1, 0 and 720 + uint32 addon; // 62 (0-original maps,1-tbc addon) + // 63 some kind of time? + //uint32 maxPlayers; // 64 max players // Helpers uint32 Expansion() const { return addon; } @@ -1111,8 +1105,6 @@ struct MapEntry bool IsBattleGround() const { return map_type == MAP_BATTLEGROUND; } bool IsBattleArena() const { return map_type == MAP_ARENA; } bool IsBattleGroundOrArena() const { return map_type == MAP_BATTLEGROUND || map_type == MAP_ARENA; } - bool SupportsHeroicMode() const { return resetTimeHeroic != 0; } - bool HasResetTime() const { return resetTimeHeroic || resetTimeRaid; } bool IsMountAllowed() const { @@ -1129,6 +1121,18 @@ struct MapEntry } }; +struct MapDifficultyEntry +{ + //uint32 Id; // 0 + uint32 MapId; // 1 + uint32 Difficulty; // 2 (for arenas: arena slot) + //char* areaTriggerText[16]; // 3-18 text showed when transfer to map failed (missing requirements) + //uint32 textFlags; // 19 + uint32 resetTime; // 20 + uint32 maxPlayers; // 21 + //char* difficultyString; // 22 +}; + struct MovieEntry { uint32 Id; // 0 index @@ -1154,66 +1158,80 @@ struct RandomPropertiesPointsEntry struct ScalingStatDistributionEntry { - uint32 Id; - int32 StatMod[10]; - uint32 Modifier[10]; - uint32 MaxLevel; + uint32 Id; // 0 + int32 StatMod[10]; // 1-10 + uint32 Modifier[10]; // 11-20 + uint32 MaxLevel; // 21 }; struct ScalingStatValuesEntry { - uint32 Id; - uint32 Level; - uint32 ssdMultiplier[5]; // Multiplier for ScalingStatDistribution - uint32 armorMod[4]; // Armor for level - uint32 dpsMod[6]; // DPS mod for level - uint32 spellBonus; // not sure.. TODO: need more info about - uint32 feralBonus; // Feral AP bonus + uint32 Id; // 0 + uint32 Level; // 1 + uint32 ssdMultiplier[4]; // 2-5 Multiplier for ScalingStatDistribution + uint32 armorMod[4]; // 6-9 Armor for level + uint32 dpsMod[6]; // 10-15 DPS mod for level + uint32 spellBonus; // 16 spell power for level + uint32 ssdMultiplier2; // 17 there's data from 3.1 dbc ssdMultiplier[3] + //uint32 unk1; // 18 all fields equal to 0 + //uint32 unk2; // 19 unk, probably also Armor for level + uint32 armorMod2[4]; // 20-23 Armor for level uint32 getssdMultiplier(uint32 mask) const { - if (mask&0x001F) + if (mask & 0x001F) { if(mask & 0x00000001) return ssdMultiplier[0]; if(mask & 0x00000002) return ssdMultiplier[1]; if(mask & 0x00000004) return ssdMultiplier[2]; - if(mask & 0x00000008) return ssdMultiplier[3]; - if(mask & 0x00000010) return ssdMultiplier[4]; + if(mask & 0x00000008) return ssdMultiplier2; + if(mask & 0x00000010) return ssdMultiplier[3]; } return 0; } + uint32 getArmorMod(uint32 mask) const { - if (mask&0x01E0) + if (mask & 0x00F001E0) { if(mask & 0x00000020) return armorMod[0]; if(mask & 0x00000040) return armorMod[1]; if(mask & 0x00000080) return armorMod[2]; if(mask & 0x00000100) return armorMod[3]; + + if(mask & 0x00100000) return armorMod2[0]; // cloth + if(mask & 0x00200000) return armorMod2[1]; // leather + if(mask & 0x00400000) return armorMod2[2]; // mail + if(mask & 0x00800000) return armorMod2[3]; // plate } return 0; } + uint32 getDPSMod(uint32 mask) const { - if (mask&0x7E00) + if (mask & 0x7E00) { if(mask & 0x00000200) return dpsMod[0]; if(mask & 0x00000400) return dpsMod[1]; if(mask & 0x00000800) return dpsMod[2]; if(mask & 0x00001000) return dpsMod[3]; if(mask & 0x00002000) return dpsMod[4]; - if(mask & 0x00004000) return dpsMod[5]; + if(mask & 0x00004000) return dpsMod[5]; // not used? } return 0; } + uint32 getSpellBonus(uint32 mask) const { - if (mask & 0x00008000) return spellBonus; + if (mask & 0x00008000) + return spellBonus; return 0; } - uint32 getFeralBonus(uint32 mask) const + + uint32 getFeralBonus(uint32 mask) const // removed in 3.2.x? { - if (mask & 0x00010000) return feralBonus; + if (mask & 0x00010000) // not used? + return 0; return 0; } }; @@ -1303,103 +1321,108 @@ struct SpellEntry uint32 AttributesEx4; // 8 m_attributesExD uint32 AttributesEx5; // 9 m_attributesExE uint32 AttributesEx6; // 10 m_attributesExF - uint32 Stances; // 11 m_shapeshiftMask - uint32 StancesNot; // 12 m_shapeshiftExclude - uint32 Targets; // 13 m_targets - uint32 TargetCreatureType; // 14 m_targetCreatureType - uint32 RequiresSpellFocus; // 15 m_requiresSpellFocus - uint32 FacingCasterFlags; // 16 m_facingCasterFlags - uint32 CasterAuraState; // 17 m_casterAuraState - uint32 TargetAuraState; // 18 m_targetAuraState - uint32 CasterAuraStateNot; // 19 m_excludeCasterAuraState - uint32 TargetAuraStateNot; // 20 m_excludeTargetAuraState - uint32 casterAuraSpell; // 21 m_casterAuraSpell - uint32 targetAuraSpell; // 22 m_targetAuraSpell - uint32 excludeCasterAuraSpell; // 23 m_excludeCasterAuraSpell - uint32 excludeTargetAuraSpell; // 24 m_excludeTargetAuraSpell - uint32 CastingTimeIndex; // 25 m_castingTimeIndex - uint32 RecoveryTime; // 26 m_recoveryTime - uint32 CategoryRecoveryTime; // 27 m_categoryRecoveryTime - uint32 InterruptFlags; // 28 m_interruptFlags - uint32 AuraInterruptFlags; // 29 m_auraInterruptFlags - uint32 ChannelInterruptFlags; // 30 m_channelInterruptFlags - uint32 procFlags; // 31 m_procTypeMask - uint32 procChance; // 32 m_procChance - uint32 procCharges; // 33 m_procCharges - uint32 maxLevel; // 34 m_maxLevel - uint32 baseLevel; // 35 m_baseLevel - uint32 spellLevel; // 36 m_spellLevel - uint32 DurationIndex; // 37 m_durationIndex - uint32 powerType; // 38 m_powerType - uint32 manaCost; // 39 m_manaCost - uint32 manaCostPerlevel; // 40 m_manaCostPerLevel - uint32 manaPerSecond; // 41 m_manaPerSecond - uint32 manaPerSecondPerLevel; // 42 m_manaPerSecondPerLeve - uint32 rangeIndex; // 43 m_rangeIndex - float speed; // 44 m_speed - //uint32 modalNextSpell; // 45 m_modalNextSpell not used - uint32 StackAmount; // 46 m_cumulativeAura - uint32 Totem[2]; // 47-48 m_totem - int32 Reagent[8]; // 49-56 m_reagent - uint32 ReagentCount[8]; // 57-64 m_reagentCount - int32 EquippedItemClass; // 65 m_equippedItemClass (value) - int32 EquippedItemSubClassMask; // 66 m_equippedItemSubclass (mask) - int32 EquippedItemInventoryTypeMask; // 67 m_equippedItemInvTypes (mask) - uint32 Effect[3]; // 68-70 m_effect - int32 EffectDieSides[3]; // 71-73 m_effectDieSides - uint32 EffectBaseDice[3]; // 74-76 m_effectBaseDice - float EffectDicePerLevel[3]; // 77-79 m_effectDicePerLevel - float EffectRealPointsPerLevel[3]; // 80-82 m_effectRealPointsPerLevel - int32 EffectBasePoints[3]; // 83-85 m_effectBasePoints (don't must be used in spell/auras explicitly, must be used cached Spell::m_currentBasePoints) - uint32 EffectMechanic[3]; // 86-88 m_effectMechanic - uint32 EffectImplicitTargetA[3]; // 89-91 m_implicitTargetA - uint32 EffectImplicitTargetB[3]; // 92-94 m_implicitTargetB - uint32 EffectRadiusIndex[3]; // 95-97 m_effectRadiusIndex - spellradius.dbc - uint32 EffectApplyAuraName[3]; // 98-100 m_effectAura - uint32 EffectAmplitude[3]; // 101-103 m_effectAuraPeriod - float EffectMultipleValue[3]; // 104-106 m_effectAmplitude - uint32 EffectChainTarget[3]; // 107-109 m_effectChainTargets - uint32 EffectItemType[3]; // 110-112 m_effectItemType - int32 EffectMiscValue[3]; // 113-115 m_effectMiscValue - int32 EffectMiscValueB[3]; // 116-118 m_effectMiscValueB - uint32 EffectTriggerSpell[3]; // 119-121 m_effectTriggerSpell - float EffectPointsPerComboPoint[3]; // 122-124 m_effectPointsPerCombo - uint32 EffectSpellClassMaskA[3]; // 125-127 m_effectSpellClassMaskA - uint32 EffectSpellClassMaskB[3]; // 128-130 m_effectSpellClassMaskB - uint32 EffectSpellClassMaskC[3]; // 131-133 m_effectSpellClassMaskC - uint32 SpellVisual[2]; // 134-135 m_spellVisualID - uint32 SpellIconID; // 136 m_spellIconID - uint32 activeIconID; // 137 m_activeIconID - //uint32 spellPriority; // 138 m_spellPriority not used - char* SpellName[16]; // 139-154 m_name_lang - //uint32 SpellNameFlag; // 155 not used - char* Rank[16]; // 156-171 m_nameSubtext_lang - //uint32 RankFlags; // 172 not used - //char* Description[16]; // 173-188 m_description_lang not used - //uint32 DescriptionFlags; // 189 not used - //char* ToolTip[16]; // 190-205 m_auraDescription_lang not used - //uint32 ToolTipFlags; // 206 not used - uint32 ManaCostPercentage; // 207 m_manaCostPct - uint32 StartRecoveryCategory; // 208 m_startRecoveryCategory - uint32 StartRecoveryTime; // 209 m_startRecoveryTime - uint32 MaxTargetLevel; // 210 m_maxTargetLevel - uint32 SpellFamilyName; // 211 m_spellClassSet - uint64 SpellFamilyFlags; // 212-213 m_spellClassMask NOTE: size is 12 bytes!!! - uint32 SpellFamilyFlags2; // 214 addition to m_spellClassMask - uint32 MaxAffectedTargets; // 215 m_maxTargets - uint32 DmgClass; // 216 m_defenseType - uint32 PreventionType; // 217 m_preventionType - //uint32 StanceBarOrder; // 218 m_stanceBarOrder not used - float DmgMultiplier[3]; // 219-221 m_effectChainAmplitude - //uint32 MinFactionId; // 222 m_minFactionID not used - //uint32 MinReputation; // 223 m_minReputation not used - //uint32 RequiredAuraVision; // 224 m_requiredAuraVision not used - uint32 TotemCategory[2]; // 225-226 m_requiredTotemCategoryID - int32 AreaGroupId; // 227 m_requiredAreaGroupId - uint32 SchoolMask; // 228 m_schoolMask - uint32 runeCostID; // 229 m_runeCostID - //uint32 spellMissileID; // 230 m_spellMissileID not used - //uint32 PowerDisplayId; // 231 PowerDisplay.dbc, new in 3.1 + // uint32 unk_320_1; // 11 3.2.0 (0x20 - totems, 0x4 - paladin auras, etc...) + uint32 Stances; // 12 m_shapeshiftMask + // uint32 unk_320_2; // 13 3.2.0 + uint32 StancesNot; // 14 m_shapeshiftExclude + // uint32 unk_320_3; // 15 3.2.0 + uint32 Targets; // 16 m_targets + uint32 TargetCreatureType; // 17 m_targetCreatureType + uint32 RequiresSpellFocus; // 18 m_requiresSpellFocus + uint32 FacingCasterFlags; // 19 m_facingCasterFlags + uint32 CasterAuraState; // 20 m_casterAuraState + uint32 TargetAuraState; // 21 m_targetAuraState + uint32 CasterAuraStateNot; // 22 m_excludeCasterAuraState + uint32 TargetAuraStateNot; // 23 m_excludeTargetAuraState + uint32 casterAuraSpell; // 24 m_casterAuraSpell + uint32 targetAuraSpell; // 25 m_targetAuraSpell + uint32 excludeCasterAuraSpell; // 26 m_excludeCasterAuraSpell + uint32 excludeTargetAuraSpell; // 27 m_excludeTargetAuraSpell + uint32 CastingTimeIndex; // 28 m_castingTimeIndex + uint32 RecoveryTime; // 29 m_recoveryTime + uint32 CategoryRecoveryTime; // 30 m_categoryRecoveryTime + uint32 InterruptFlags; // 31 m_interruptFlags + uint32 AuraInterruptFlags; // 32 m_auraInterruptFlags + uint32 ChannelInterruptFlags; // 33 m_channelInterruptFlags + uint32 procFlags; // 34 m_procTypeMask + uint32 procChance; // 35 m_procChance + uint32 procCharges; // 36 m_procCharges + uint32 maxLevel; // 37 m_maxLevel + uint32 baseLevel; // 38 m_baseLevel + uint32 spellLevel; // 39 m_spellLevel + uint32 DurationIndex; // 40 m_durationIndex + uint32 powerType; // 41 m_powerType + uint32 manaCost; // 42 m_manaCost + uint32 manaCostPerlevel; // 43 m_manaCostPerLevel + uint32 manaPerSecond; // 44 m_manaPerSecond + uint32 manaPerSecondPerLevel; // 45 m_manaPerSecondPerLeve + uint32 rangeIndex; // 46 m_rangeIndex + float speed; // 47 m_speed + //uint32 modalNextSpell; // 48 m_modalNextSpell not used + uint32 StackAmount; // 49 m_cumulativeAura + uint32 Totem[2]; // 50-51 m_totem + int32 Reagent[8]; // 52-59 m_reagent + uint32 ReagentCount[8]; // 60-67 m_reagentCount + int32 EquippedItemClass; // 68 m_equippedItemClass (value) + int32 EquippedItemSubClassMask; // 69 m_equippedItemSubclass (mask) + int32 EquippedItemInventoryTypeMask; // 70 m_equippedItemInvTypes (mask) + uint32 Effect[3]; // 71-73 m_effect + int32 EffectDieSides[3]; // 74-76 m_effectDieSides + uint32 EffectBaseDice[3]; // 77-79 m_effectBaseDice + float EffectDicePerLevel[3]; // 80-82 m_effectDicePerLevel + float EffectRealPointsPerLevel[3]; // 83-85 m_effectRealPointsPerLevel + int32 EffectBasePoints[3]; // 86-88 m_effectBasePoints (don't must be used in spell/auras explicitly, must be used cached Spell::m_currentBasePoints) + uint32 EffectMechanic[3]; // 89-91 m_effectMechanic + uint32 EffectImplicitTargetA[3]; // 92-94 m_implicitTargetA + uint32 EffectImplicitTargetB[3]; // 95-97 m_implicitTargetB + uint32 EffectRadiusIndex[3]; // 98-100 m_effectRadiusIndex - spellradius.dbc + uint32 EffectApplyAuraName[3]; // 101-103 m_effectAura + uint32 EffectAmplitude[3]; // 104-106 m_effectAuraPeriod + float EffectMultipleValue[3]; // 107-109 m_effectAmplitude + uint32 EffectChainTarget[3]; // 110-112 m_effectChainTargets + uint32 EffectItemType[3]; // 113-115 m_effectItemType + int32 EffectMiscValue[3]; // 116-118 m_effectMiscValue + int32 EffectMiscValueB[3]; // 119-121 m_effectMiscValueB + uint32 EffectTriggerSpell[3]; // 122-124 m_effectTriggerSpell + float EffectPointsPerComboPoint[3]; // 125-127 m_effectPointsPerCombo + uint32 EffectSpellClassMaskA[3]; // 128-130 m_effectSpellClassMaskA + uint32 EffectSpellClassMaskB[3]; // 131-133 m_effectSpellClassMaskB + uint32 EffectSpellClassMaskC[3]; // 134-136 m_effectSpellClassMaskC + uint32 SpellVisual[2]; // 137-138 m_spellVisualID + uint32 SpellIconID; // 139 m_spellIconID + uint32 activeIconID; // 140 m_activeIconID + //uint32 spellPriority; // 141 m_spellPriority not used + char* SpellName[16]; // 142-157 m_name_lang + //uint32 SpellNameFlag; // 158 not used + char* Rank[16]; // 159-174 m_nameSubtext_lang + //uint32 RankFlags; // 175 not used + //char* Description[16]; // 176-191 m_description_lang not used + //uint32 DescriptionFlags; // 192 not used + //char* ToolTip[16]; // 193-208 m_auraDescription_lang not used + //uint32 ToolTipFlags; // 209 not used + uint32 ManaCostPercentage; // 210 m_manaCostPct + uint32 StartRecoveryCategory; // 211 m_startRecoveryCategory + uint32 StartRecoveryTime; // 212 m_startRecoveryTime + uint32 MaxTargetLevel; // 213 m_maxTargetLevel + uint32 SpellFamilyName; // 214 m_spellClassSet + uint64 SpellFamilyFlags; // 215-216 m_spellClassMask NOTE: size is 12 bytes!!! + uint32 SpellFamilyFlags2; // 217 addition to m_spellClassMask + uint32 MaxAffectedTargets; // 218 m_maxTargets + uint32 DmgClass; // 219 m_defenseType + uint32 PreventionType; // 220 m_preventionType + //uint32 StanceBarOrder; // 221 m_stanceBarOrder not used + float DmgMultiplier[3]; // 222-224 m_effectChainAmplitude + //uint32 MinFactionId; // 225 m_minFactionID not used + //uint32 MinReputation; // 226 m_minReputation not used + //uint32 RequiredAuraVision; // 227 m_requiredAuraVision not used + uint32 TotemCategory[2]; // 228-229 m_requiredTotemCategoryID + int32 AreaGroupId; // 230 m_requiredAreaGroupId + uint32 SchoolMask; // 231 m_schoolMask + uint32 runeCostID; // 232 m_runeCostID + //uint32 spellMissileID; // 233 m_spellMissileID not used + //uint32 PowerDisplayId; // 234 PowerDisplay.dbc, new in 3.1 + //float unk_320_4[3]; // 235-237 3.2.0 + //uint32 spellDescriptionVariableID; // 238 3.2.0 // helpers int32 CalculateSimpleValue(uint8 eff) const { return EffectBasePoints[eff]+int32(EffectBaseDice[eff]); } @@ -1710,6 +1733,7 @@ struct WorldMapAreaEntry float x2; // 7 int32 virtual_map_id; // 8 -1 (map_id have correct map) other: virtual map where zone show (map_id - where zone in fact internally) // int32 dungeonMap_id; // 9 pointer to DungeonMap.dbc (owerride x1,x2,y1,y2 coordinates) + // uint32 someMapID; // 10 }; #define MAX_WORLD_MAP_OVERLAY_AREA_IDX 4 @@ -1743,6 +1767,15 @@ struct WorldSafeLocsEntry #endif // Structures not used for casting to loaded DBC data and not required then packing +struct MapDifficulty +{ + MapDifficulty() : resetTime(0), maxPlayers(0) {} + MapDifficulty(uint32 _resetTime, uint32 _maxPlayers) : resetTime(_resetTime), maxPlayers(_maxPlayers) {} + + uint32 resetTime; + uint32 maxPlayers; +}; + struct TalentSpellPos { TalentSpellPos() : talent_id(0), rank(0) {} diff --git a/src/game/DBCfmt.h b/src/game/DBCfmt.h index da26a14f7..32c18ecfa 100644 --- a/src/game/DBCfmt.h +++ b/src/game/DBCfmt.h @@ -33,7 +33,7 @@ const char CharTitlesEntryfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi"; const char ChatChannelsEntryfmt[]="iixssssssssssssssssxxxxxxxxxxxxxxxxxx"; // ChatChannelsEntryfmt, index not used (more compact store) const char ChrClassesEntryfmt[]="nxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii"; -const char ChrRacesEntryfmt[]="nxixiixxixxxxissssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi"; +const char ChrRacesEntryfmt[]="nxixiixixxxxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi"; const char CinematicSequencesEntryfmt[]="nxxxxxxxxx"; const char CreatureDisplayInfofmt[]="nxxxfxxxxxxxxxxx"; const char CreatureFamilyfmt[]="nfifiiiiixssssssssssssssssxx"; @@ -65,25 +65,26 @@ const char Itemfmt[]="niiiiiii"; const char ItemBagFamilyfmt[]="nxxxxxxxxxxxxxxxxx"; //const char ItemDisplayTemplateEntryfmt[]="nxxxxxxxxxxixxxxxxxxxxx"; //const char ItemCondExtCostsEntryfmt[]="xiii"; -const char ItemExtendedCostEntryfmt[]="niiiiiiiiiiiiix"; +const char ItemExtendedCostEntryfmt[]="niixiiiiiiiiiiix"; const char ItemLimitCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxix"; const char ItemRandomPropertiesfmt[]="nxiiiiixxxxxxxxxxxxxxxxx"; const char ItemRandomSuffixfmt[]="nxxxxxxxxxxxxxxxxxxiiiiiiiiii"; const char ItemSetEntryfmt[]="dssssssssssssssssxxxxxxxxxxxxxxxxxxiiiiiiiiiiiiiiiiii"; const char LockEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx"; const char MailTemplateEntryfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; -const char MapEntryfmt[]="nxixssssssssssssssssxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiffiixxix"; +const char MapEntryfmt[]="nxixssssssssssssssssxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixiffxixx"; +const char MapDifficultyEntryfmt[]="diixxxxxxxxxxxxxxxxxiix"; const char MovieEntryfmt[]="nxx"; const char QuestSortEntryfmt[]="nxxxxxxxxxxxxxxxxx"; const char RandomPropertiesPointsfmt[]="niiiiiiiiiiiiiii"; const char ScalingStatDistributionfmt[]="niiiiiiiiiiiiiiiiiiiii"; -const char ScalingStatValuesfmt[]="iniiiiiiiiiiiiiiiii"; +const char ScalingStatValuesfmt[]="iniiiiiiiiiiiiiiiixxiiii"; const char SkillLinefmt[]="nixssssssssssssssssxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxi"; const char SkillLineAbilityfmt[]="niiiixxiiiiixx"; const char SoundEntriesfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; const char SpellCastTimefmt[]="nixx"; const char SpellDurationfmt[]="niii"; -const char SpellEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffffffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiixx"; +const char SpellEntryfmt[]="niiiiiiiiiixixixiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffffffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiixxxxxx"; const char SpellFocusObjectfmt[]="nxxxxxxxxxxxxxxxxx"; const char SpellItemEnchantmentfmt[]="nxiiiiiixxxiiissssssssssssssssxiiiixxx"; const char SpellItemEnchantmentConditionfmt[]="nbbbbbxxxxxbbbbbbbbbbiiiiiXXXXX"; @@ -101,7 +102,7 @@ const char TaxiPathNodeEntryfmt[]="diiifffiixx"; const char TotemCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxii"; const char VehicleEntryfmt[]="niffffiiiiiiiifffffffffffffffssssfifixxx"; const char VehicleSeatEntryfmt[]="niiffffffffffiiiiiifffffffiiifffiiiiiiiffiiiiixxxxxxxxxxxx"; -const char WorldMapAreaEntryfmt[]="xinxffffix"; +const char WorldMapAreaEntryfmt[]="xinxffffixx"; const char WorldMapOverlayEntryfmt[]="nxiiiixxxxxxxxxxx"; const char WorldSafeLocsEntryfmt[]="nifffxxxxxxxxxxxxxxxxx"; diff --git a/src/game/DuelHandler.cpp b/src/game/DuelHandler.cpp index 0fa58ea2b..6f253af2e 100644 --- a/src/game/DuelHandler.cpp +++ b/src/game/DuelHandler.cpp @@ -42,17 +42,15 @@ void WorldSession::HandleDuelAcceptedOpcode(WorldPacket& recvPacket) return; //sLog.outDebug( "WORLD: received CMSG_DUEL_ACCEPTED" ); - DEBUG_LOG("Player 1 is: %u (%s)", pl->GetGUIDLow(),pl->GetName()); - DEBUG_LOG("Player 2 is: %u (%s)", plTarget->GetGUIDLow(),plTarget->GetName()); + DEBUG_LOG("Player 1 is: %u (%s)", pl->GetGUIDLow(), pl->GetName()); + DEBUG_LOG("Player 2 is: %u (%s)", plTarget->GetGUIDLow(), plTarget->GetName()); time_t now = time(NULL); pl->duel->startTimer = now; plTarget->duel->startTimer = now; - WorldPacket data(SMSG_DUEL_COUNTDOWN, 4); - data << (uint32)3000; // 3 seconds - pl->GetSession()->SendPacket(&data); - plTarget->GetSession()->SendPacket(&data); + pl->SendDuelCountdown(3000); + plTarget->SendDuelCountdown(3000); } void WorldSession::HandleDuelCancelledOpcode(WorldPacket& recvPacket) diff --git a/src/game/DynamicObject.cpp b/src/game/DynamicObject.cpp index 95f16e25b..92db7e25b 100644 --- a/src/game/DynamicObject.cpp +++ b/src/game/DynamicObject.cpp @@ -32,7 +32,7 @@ DynamicObject::DynamicObject() : WorldObject(), m_isActiveObject(false) m_objectType |= TYPEMASK_DYNAMICOBJECT; m_objectTypeId = TYPEID_DYNAMICOBJECT; - m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION); + m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_POSITION); m_valuesCount = DYNAMICOBJECT_END; } @@ -73,9 +73,6 @@ bool DynamicObject::Create( uint32 guidlow, Unit *caster, uint32 spellId, uint32 SetUInt32Value( DYNAMICOBJECT_BYTES, 0x00000001 ); SetUInt32Value( DYNAMICOBJECT_SPELLID, spellId ); SetFloatValue( DYNAMICOBJECT_RADIUS, radius); - SetFloatValue( DYNAMICOBJECT_POS_X, x ); - SetFloatValue( DYNAMICOBJECT_POS_Y, y ); - SetFloatValue( DYNAMICOBJECT_POS_Z, z ); SetUInt32Value( DYNAMICOBJECT_CASTTIME, getMSTime() ); // new 2.4.0 m_aliveDuration = duration; diff --git a/src/game/DynamicObject.h b/src/game/DynamicObject.h index 066361b8c..089175f3c 100644 --- a/src/game/DynamicObject.h +++ b/src/game/DynamicObject.h @@ -61,7 +61,6 @@ class DynamicObject : public WorldObject uint32 m_spellId; uint32 m_effIndex; int32 m_aliveDuration; - time_t m_nextThinkTime; float m_radius; // radius apply persistent effect, 0 = no persistent effect AffectedSet m_affected; private: diff --git a/src/game/FleeingMovementGenerator.cpp b/src/game/FleeingMovementGenerator.cpp index a74790d9a..172934340 100644 --- a/src/game/FleeingMovementGenerator.cpp +++ b/src/game/FleeingMovementGenerator.cpp @@ -314,7 +314,7 @@ FleeingMovementGenerator::_Init(Creature &owner) return; owner.RemoveMonsterMoveFlag(MONSTER_MOVE_WALK); - owner.SetUInt64Value(UNIT_FIELD_TARGET, 0); + owner.SetTargetGUID(0); is_water_ok = owner.canSwim(); is_land_ok = owner.canWalk(); } diff --git a/src/game/GMTicketHandler.cpp b/src/game/GMTicketHandler.cpp index ffdfae504..4e062ac9f 100644 --- a/src/game/GMTicketHandler.cpp +++ b/src/game/GMTicketHandler.cpp @@ -89,8 +89,9 @@ void WorldSession::HandleGMTicketCreateOpcode( WorldPacket & recv_data ) recv_data >> ticketText; recv_data.read_skip(); // unk1, 0 - recv_data.read_skip(); // unk2, 1 + recv_data.read_skip(); // unk2, 1 recv_data.read_skip(); // unk3, 0 + recv_data.read_skip(); // unk4, 0 sLog.outDebug("TicketCreate: map %u, x %f, y %f, z %f, text %s", map, x, y, z, ticketText.c_str()); diff --git a/src/game/GameObject.h b/src/game/GameObject.h index 11d9b3160..06ebfa278 100644 --- a/src/game/GameObject.h +++ b/src/game/GameObject.h @@ -45,7 +45,7 @@ struct GameObjectInfo uint32 faction; uint32 flags; float size; - uint32 questItems[4]; + uint32 questItems[6]; union // different GO types have different data field { //0 GAMEOBJECT_TYPE_DOOR diff --git a/src/game/GossipDef.cpp b/src/game/GossipDef.cpp index ab229d9f1..7a221a59f 100644 --- a/src/game/GossipDef.cpp +++ b/src/game/GossipDef.cpp @@ -545,13 +545,13 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest ) WorldPacket data( SMSG_QUEST_QUERY_RESPONSE, 100 ); // guess size - data << uint32(pQuest->GetQuestId()); + data << uint32(pQuest->GetQuestId()); // quest id data << uint32(pQuest->GetQuestMethod()); // Accepted values: 0, 1 or 2. 0==IsAutoComplete() (skip objectives/details) data << uint32(pQuest->GetQuestLevel()); // may be 0, static data, in other cases must be used dynamic level: Player::GetQuestLevel data << uint32(pQuest->GetZoneOrSort()); // zone or sort to display in quest log - data << uint32(pQuest->GetType()); - data << uint32(pQuest->GetSuggestedPlayers()); + data << uint32(pQuest->GetType()); // quest type + data << uint32(pQuest->GetSuggestedPlayers()); // suggested players count data << uint32(pQuest->GetRepObjectiveFaction()); // shown in quest log as part of quest objective data << uint32(pQuest->GetRepObjectiveValue()); // shown in quest log as part of quest objective @@ -564,7 +564,7 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest ) if (pQuest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS)) data << uint32(0); // Hide money rewarded else - data << uint32(pQuest->GetRewOrReqMoney()); + data << uint32(pQuest->GetRewOrReqMoney()); // reward money (below max lvl) data << uint32(pQuest->GetRewMoneyMaxLevel()); // used in XP calculation at client data << uint32(pQuest->GetRewSpell()); // reward spell, this spell will display (icon) (casted if RewSpellCast==0) @@ -572,8 +572,8 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest ) // rewarded honor points data << uint32(MaNGOS::Honor::hk_honor_at_level(pSession->GetPlayer()->getLevel(), pQuest->GetRewHonorableKills())); - data << uint32(pQuest->GetSrcItemId()); - data << uint32(pQuest->GetFlags() & 0xFFFF); + data << uint32(pQuest->GetSrcItemId()); // source item id + data << uint32(pQuest->GetFlags() & 0xFFFF); // quest flags data << uint32(pQuest->GetCharTitleId()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles) data << uint32(pQuest->GetPlayersSlain()); // players slain data << uint32(pQuest->GetBonusTalents()); // bonus talents @@ -634,6 +634,8 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest ) data << uint32(0); // TODO: 5 item objective data << uint32(0); + data << uint32(0); // TODO: 6 item objective + data << uint32(0); for (iI = 0; iI < QUEST_OBJECTIVES_COUNT; ++iI) data << ObjectiveText[iI]; diff --git a/src/game/Group.cpp b/src/game/Group.cpp index 5c83df614..7edee6eb1 100644 --- a/src/game/Group.cpp +++ b/src/game/Group.cpp @@ -69,7 +69,7 @@ Group::~Group() // it is undefined whether objectmgr (which stores the groups) or instancesavemgr // will be unloaded first so we must be prepared for both cases // this may unload some instance saves - for(uint8 i = 0; i < TOTAL_DIFFICULTIES; ++i) + for(uint8 i = 0; i < MAX_DIFFICULTY; ++i) for(BoundInstancesMap::iterator itr2 = m_boundInstances[i].begin(); itr2 != m_boundInstances[i].end(); ++itr2) itr2->second.save->RemoveGroup(this); @@ -92,11 +92,16 @@ bool Group::Create(const uint64 &guid, const char * name) m_lootThreshold = ITEM_QUALITY_UNCOMMON; m_looterGuid = guid; - m_difficulty = DIFFICULTY_NORMAL; + m_dungeonDifficulty = DUNGEON_DIFFICULTY_NORMAL; + m_raidDifficulty = RAID_DIFFICULTY_10MAN_NORMAL; if(!isBGGroup()) { Player *leader = objmgr.GetPlayer(guid); - if(leader) m_difficulty = leader->GetDifficulty(); + if(leader) + { + m_dungeonDifficulty = leader->GetDungeonDifficulty(); + m_raidDifficulty = leader->GetRaidDifficulty(); + } Player::ConvertInstancesToGroup(leader, this, guid); @@ -104,10 +109,10 @@ bool Group::Create(const uint64 &guid, const char * name) CharacterDatabase.BeginTransaction(); CharacterDatabase.PExecute("DELETE FROM groups WHERE leaderGuid ='%u'", GUID_LOPART(m_leaderGuid)); CharacterDatabase.PExecute("DELETE FROM group_member WHERE leaderGuid ='%u'", GUID_LOPART(m_leaderGuid)); - CharacterDatabase.PExecute("INSERT INTO groups(leaderGuid,mainTank,mainAssistant,lootMethod,looterGuid,lootThreshold,icon1,icon2,icon3,icon4,icon5,icon6,icon7,icon8,isRaid,difficulty) " - "VALUES('%u','%u','%u','%u','%u','%u','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','%u','%u')", + CharacterDatabase.PExecute("INSERT INTO groups (leaderGuid,mainTank,mainAssistant,lootMethod,looterGuid,lootThreshold,icon1,icon2,icon3,icon4,icon5,icon6,icon7,icon8,isRaid,difficulty,raiddifficulty) " + "VALUES ('%u','%u','%u','%u','%u','%u','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','%u','%u','%u')", GUID_LOPART(m_leaderGuid), GUID_LOPART(m_mainTank), GUID_LOPART(m_mainAssistant), uint32(m_lootMethod), - GUID_LOPART(m_looterGuid), uint32(m_lootThreshold), m_targetIcons[0], m_targetIcons[1], m_targetIcons[2], m_targetIcons[3], m_targetIcons[4], m_targetIcons[5], m_targetIcons[6], m_targetIcons[7], isRaidGroup(), m_difficulty); + GUID_LOPART(m_looterGuid), uint32(m_lootThreshold), m_targetIcons[0], m_targetIcons[1], m_targetIcons[2], m_targetIcons[3], m_targetIcons[4], m_targetIcons[5], m_targetIcons[6], m_targetIcons[7], isRaidGroup(), uint32(m_dungeonDifficulty), m_raidDifficulty); } if(!AddMember(guid, name)) @@ -127,8 +132,8 @@ bool Group::LoadGroupFromDB(const uint64 &leaderGuid, QueryResult *result, bool if(!result) { external = false; - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 - result = CharacterDatabase.PQuery("SELECT mainTank, mainAssistant, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8, isRaid, difficulty FROM groups WHERE leaderGuid ='%u'", GUID_LOPART(leaderGuid)); + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + result = CharacterDatabase.PQuery("SELECT mainTank, mainAssistant, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8, isRaid, difficulty, raiddifficulty FROM groups WHERE leaderGuid ='%u'", GUID_LOPART(leaderGuid)); if(!result) return false; } @@ -147,7 +152,16 @@ bool Group::LoadGroupFromDB(const uint64 &leaderGuid, QueryResult *result, bool if (m_groupType == GROUPTYPE_RAID) _initRaidSubGroupsCounter(); - m_difficulty = (*result)[14].GetUInt8(); + uint32 diff = (*result)[14].GetUInt8(); + if (diff >= MAX_DUNGEON_DIFFICULTY) + diff = DUNGEON_DIFFICULTY_NORMAL; + m_dungeonDifficulty = Difficulty(diff); + + uint32 r_diff = (*result)[15].GetUInt8(); + if (r_diff >= MAX_RAID_DIFFICULTY) + r_diff = RAID_DIFFICULTY_10MAN_NORMAL; + m_raidDifficulty = Difficulty(r_diff); + m_mainTank = (*result)[0].GetUInt64(); m_mainAssistant = (*result)[1].GetUInt64(); m_lootMethod = (LootMethod)(*result)[2].GetUInt8(); @@ -289,18 +303,27 @@ bool Group::AddMember(const uint64 &guid, const char* name) { // reset the new member's instances, unless he is currently in one of them // including raid/heroic instances that they are not permanently bound to! - player->ResetInstances(INSTANCE_RESET_GROUP_JOIN); + player->ResetInstances(INSTANCE_RESET_GROUP_JOIN,false); + player->ResetInstances(INSTANCE_RESET_GROUP_JOIN,true); - if(player->getLevel() >= LEVELREQUIREMENT_HEROIC && player->GetDifficulty() != GetDifficulty() ) + if (player->getLevel() >= LEVELREQUIREMENT_HEROIC) { - player->SetDifficulty(m_difficulty); - player->SendDungeonDifficulty(true); + if (player->GetDungeonDifficulty() != GetDungeonDifficulty()) + { + player->SetDungeonDifficulty(GetDungeonDifficulty()); + player->SendDungeonDifficulty(true); + } + if (player->GetRaidDifficulty() != GetRaidDifficulty()) + { + player->SetRaidDifficulty(GetRaidDifficulty()); + player->SendRaidDifficulty(true); + } } } player->SetGroupUpdateFlag(GROUP_UPDATE_FULL); UpdatePlayerOutOfRange(player); - // quest related GO state dependent from raid memebership + // quest related GO state dependent from raid membership if(isRaidGroup()) player->UpdateForQuestWorldObjects(); } @@ -364,7 +387,7 @@ void Group::ChangeLeader(const uint64 &guid) { member_citerator slot = _getMemberCSlot(guid); - if(slot==m_memberSlots.end()) + if(slot == m_memberSlots.end()) return; _setLeader(guid); @@ -437,7 +460,8 @@ void Group::Disband(bool hideDestroy) CharacterDatabase.PExecute("DELETE FROM groups WHERE leaderGuid='%u'", GUID_LOPART(m_leaderGuid)); CharacterDatabase.PExecute("DELETE FROM group_member WHERE leaderGuid='%u'", GUID_LOPART(m_leaderGuid)); CharacterDatabase.CommitTransaction(); - ResetInstances(INSTANCE_RESET_GROUP_DISBAND, NULL); + ResetInstances(INSTANCE_RESET_GROUP_DISBAND, false, NULL); + ResetInstances(INSTANCE_RESET_GROUP_DISBAND, true, NULL); } m_leaderGuid = 0; @@ -955,7 +979,8 @@ void Group::SendUpdate() data << (uint8)m_lootMethod; // loot method data << (uint64)m_looterGuid; // looter guid data << (uint8)m_lootThreshold; // loot threshold - data << (uint8)m_difficulty; // Heroic Mod Group + data << (uint8)m_dungeonDifficulty; // Dungeon Difficulty + data << (uint8)m_raidDifficulty; // Raid Difficulty } player->GetSession()->SendPacket( &data ); } @@ -1072,7 +1097,7 @@ bool Group::_addMember(const uint64 &guid, const char* name, bool isAssistant, u else player->SetGroup(this, group); // if the same group invites the player back, cancel the homebind timer - InstanceGroupBind *bind = GetBoundInstance(player->GetMapId(), player->GetDifficulty()); + InstanceGroupBind *bind = GetBoundInstance(player); if(bind && bind->save->GetInstanceId() == player->GetInstanceId()) player->m_InstanceValid = true; } @@ -1158,7 +1183,7 @@ void Group::_setLeader(const uint64 &guid) Player *player = objmgr.GetPlayer(slot->guid); if(player) { - for(uint8 i = 0; i < TOTAL_DIFFICULTIES; ++i) + for(uint8 i = 0; i < MAX_DIFFICULTY; ++i) { for(BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end();) { @@ -1445,21 +1470,38 @@ void Roll::targetObjectBuildLink() getTarget()->addLootValidatorRef(this); } -void Group::SetDifficulty(uint8 difficulty) +void Group::SetDungeonDifficulty(Difficulty difficulty) { - m_difficulty = difficulty; - if(!isBGGroup()) CharacterDatabase.PExecute("UPDATE groups SET difficulty = %u WHERE leaderGuid ='%u'", m_difficulty, GUID_LOPART(m_leaderGuid)); + m_dungeonDifficulty = difficulty; + if(!isBGGroup()) + CharacterDatabase.PExecute("UPDATE groups SET difficulty = %u WHERE leaderGuid ='%u'", m_dungeonDifficulty, GUID_LOPART(m_leaderGuid)); for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next()) { Player *player = itr->getSource(); if(!player->GetSession() || player->getLevel() < LEVELREQUIREMENT_HEROIC) continue; - player->SetDifficulty(difficulty); + player->SetDungeonDifficulty(difficulty); player->SendDungeonDifficulty(true); } } +void Group::SetRaidDifficulty(Difficulty difficulty) +{ + m_raidDifficulty = difficulty; + if(!isBGGroup()) + CharacterDatabase.PExecute("UPDATE groups SET raiddifficulty = %u WHERE leaderGuid ='%u'", m_raidDifficulty, GUID_LOPART(m_leaderGuid)); + + for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player *player = itr->getSource(); + if(!player->GetSession() || player->getLevel() < LEVELREQUIREMENT_HEROIC) + continue; + player->SetRaidDifficulty(difficulty); + player->SendRaidDifficulty(true); + } +} + bool Group::InCombatToInstance(uint32 instanceId) { for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next()) @@ -1471,7 +1513,7 @@ bool Group::InCombatToInstance(uint32 instanceId) return false; } -void Group::ResetInstances(uint8 method, Player* SendMsgTo) +void Group::ResetInstances(uint8 method, bool isRaid, Player* SendMsgTo) { if(isBGGroup()) return; @@ -1479,13 +1521,13 @@ void Group::ResetInstances(uint8 method, Player* SendMsgTo) // method can be INSTANCE_RESET_ALL, INSTANCE_RESET_CHANGE_DIFFICULTY, INSTANCE_RESET_GROUP_DISBAND // we assume that when the difficulty changes, all instances that can be reset will be - uint8 dif = GetDifficulty(); + Difficulty diff = GetDifficulty(isRaid); - for(BoundInstancesMap::iterator itr = m_boundInstances[dif].begin(); itr != m_boundInstances[dif].end();) + for(BoundInstancesMap::iterator itr = m_boundInstances[diff].begin(); itr != m_boundInstances[diff].end();) { InstanceSave *p = itr->second.save; const MapEntry *entry = sMapStore.LookupEntry(itr->first); - if(!entry || (!p->CanReset() && method != INSTANCE_RESET_GROUP_DISBAND)) + if(!entry || entry->IsRaid() != isRaid || !p->CanReset() && method != INSTANCE_RESET_GROUP_DISBAND) { ++itr; continue; @@ -1494,7 +1536,7 @@ void Group::ResetInstances(uint8 method, Player* SendMsgTo) if(method == INSTANCE_RESET_ALL) { // the "reset all instances" method can only reset normal maps - if(dif == DIFFICULTY_HEROIC || entry->map_type == MAP_RAID) + if (entry->map_type == MAP_RAID || diff == DUNGEON_DIFFICULTY_HEROIC) { ++itr; continue; @@ -1519,8 +1561,8 @@ void Group::ResetInstances(uint8 method, Player* SendMsgTo) if(p->CanReset()) p->DeleteFromDB(); else CharacterDatabase.PExecute("DELETE FROM group_instance WHERE instance = '%u'", p->GetInstanceId()); // i don't know for sure if hash_map iterators - m_boundInstances[dif].erase(itr); - itr = m_boundInstances[dif].begin(); + m_boundInstances[diff].erase(itr); + itr = m_boundInstances[diff].begin(); // this unloads the instance save unless online players are bound to it // (eg. permanent binds or GM solo binds) p->RemoveGroup(this); @@ -1530,11 +1572,19 @@ void Group::ResetInstances(uint8 method, Player* SendMsgTo) } } -InstanceGroupBind* Group::GetBoundInstance(uint32 mapid, uint8 difficulty) +InstanceGroupBind* Group::GetBoundInstance(Player* player) { + uint32 mapid = player->GetMapId(); + MapEntry const* mapEntry = sMapStore.LookupEntry(mapid); + if(!mapEntry) + return NULL; + + Difficulty difficulty = player->GetDifficulty(mapEntry->IsRaid()); + // some instances only have one difficulty - const MapEntry* entry = sMapStore.LookupEntry(mapid); - if(!entry || !entry->SupportsHeroicMode()) difficulty = DIFFICULTY_NORMAL; + MapDifficulty const* mapDiff = GetMapDifficultyData(mapid,difficulty); + if(!mapDiff) + difficulty = DUNGEON_DIFFICULTY_NORMAL; BoundInstancesMap::iterator itr = m_boundInstances[difficulty].find(mapid); if(itr != m_boundInstances[difficulty].end()) @@ -1543,6 +1593,23 @@ InstanceGroupBind* Group::GetBoundInstance(uint32 mapid, uint8 difficulty) return NULL; } +InstanceGroupBind* Group::GetBoundInstance(Map* aMap) +{ + // Currently spawn numbering not different from map difficulty + Difficulty difficulty = Difficulty(aMap->GetSpawnMode()); + + // some instances only have one difficulty + MapDifficulty const* mapDiff = GetMapDifficultyData(aMap->GetId(),difficulty); + if(!mapDiff) + return NULL; + + BoundInstancesMap::iterator itr = m_boundInstances[difficulty].find(aMap->GetId()); + if(itr != m_boundInstances[difficulty].end()) + return &itr->second; + else + return NULL; +} + InstanceGroupBind* Group::BindToInstance(InstanceSave *save, bool permanent, bool load) { if(save && !isBGGroup()) diff --git a/src/game/Group.h b/src/game/Group.h index 478b7c5cb..3b852fa8e 100644 --- a/src/game/Group.h +++ b/src/game/Group.h @@ -279,11 +279,15 @@ class MANGOS_DLL_SPEC Group } void SetTargetIcon(uint8 id, uint64 guid); - void SetDifficulty(uint8 difficulty); - uint8 GetDifficulty() { return m_difficulty; } + + Difficulty GetDifficulty(bool isRaid) const { return isRaid ? m_raidDifficulty : m_dungeonDifficulty; } + Difficulty GetDungeonDifficulty() const { return m_dungeonDifficulty; } + Difficulty GetRaidDifficulty() const { return m_raidDifficulty; } + void SetDungeonDifficulty(Difficulty difficulty); + void SetRaidDifficulty(Difficulty difficulty); uint16 InInstance(); bool InCombatToInstance(uint32 instanceId); - void ResetInstances(uint8 method, Player* SendMsgTo); + void ResetInstances(uint8 method, bool isRaid, Player* SendMsgTo); // -no description- //void SendInit(WorldSession *session); @@ -327,8 +331,9 @@ class MANGOS_DLL_SPEC Group InstanceGroupBind* BindToInstance(InstanceSave *save, bool permanent, bool load = false); void UnbindInstance(uint32 mapid, uint8 difficulty, bool unload = false); - InstanceGroupBind* GetBoundInstance(uint32 mapid, uint8 difficulty); - BoundInstancesMap& GetBoundInstances(uint8 difficulty) { return m_boundInstances[difficulty]; } + InstanceGroupBind* GetBoundInstance(Player* player); + InstanceGroupBind* GetBoundInstance(Map* aMap); + BoundInstancesMap& GetBoundInstances(Difficulty difficulty) { return m_boundInstances[difficulty]; } protected: bool _addMember(const uint64 &guid, const char* name, bool isAssistant=false); @@ -397,14 +402,15 @@ class MANGOS_DLL_SPEC Group uint64 m_mainTank; uint64 m_mainAssistant; GroupType m_groupType; - uint8 m_difficulty; + Difficulty m_dungeonDifficulty; + Difficulty m_raidDifficulty; BattleGround* m_bgGroup; uint64 m_targetIcons[TARGETICONCOUNT]; LootMethod m_lootMethod; ItemQualities m_lootThreshold; uint64 m_looterGuid; Rolls RollId; - BoundInstancesMap m_boundInstances[TOTAL_DIFFICULTIES]; + BoundInstancesMap m_boundInstances[MAX_DIFFICULTY]; uint8* m_subGroupsCounts; }; #endif diff --git a/src/game/GuildHandler.cpp b/src/game/GuildHandler.cpp index 90741d3af..7aecaaa77 100644 --- a/src/game/GuildHandler.cpp +++ b/src/game/GuildHandler.cpp @@ -29,36 +29,32 @@ void WorldSession::HandleGuildQueryOpcode(WorldPacket& recvPacket) { + sLog.outDebug("WORLD: Received CMSG_GUILD_QUERY"); + uint32 guildId; - Guild *guild; - - //sLog.outDebug("WORLD: Received CMSG_GUILD_QUERY"); - recvPacket >> guildId; - guild = objmgr.GetGuildById(guildId); - if(!guild) + if(Guild *guild = objmgr.GetGuildById(guildId)) { - SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); + guild->Query(this); return; } - guild->Query(this); + SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); } void WorldSession::HandleGuildCreateOpcode(WorldPacket& recvPacket) { + sLog.outDebug("WORLD: Received CMSG_GUILD_CREATE"); + std::string gname; - - //sLog.outDebug("WORLD: Received CMSG_GUILD_CREATE"); - recvPacket >> gname; - if(GetPlayer()->GetGuildId()) + if(GetPlayer()->GetGuildId()) // already in guild return; Guild *guild = new Guild; - if(!guild->Create(GetPlayer(),gname)) + if(!guild->Create(GetPlayer(), gname)) { delete guild; return; @@ -69,10 +65,9 @@ void WorldSession::HandleGuildCreateOpcode(WorldPacket& recvPacket) void WorldSession::HandleGuildInviteOpcode(WorldPacket& recvPacket) { + sLog.outDebug("WORLD: Received CMSG_GUILD_INVITE"); + std::string Invitedname, plname; - - //sLog.outDebug("WORLD: Received CMSG_GUILD_INVITE"); - Player * player = NULL; recvPacket >> Invitedname; @@ -135,15 +130,14 @@ void WorldSession::HandleGuildInviteOpcode(WorldPacket& recvPacket) data << guild->GetName(); player->GetSession()->SendPacket(&data); - //sLog.outDebug("WORLD: Sent (SMSG_GUILD_INVITE)"); + sLog.outDebug("WORLD: Sent (SMSG_GUILD_INVITE)"); } void WorldSession::HandleGuildRemoveOpcode(WorldPacket& recvPacket) { + sLog.outDebug("WORLD: Received CMSG_GUILD_REMOVE"); + std::string plName; - - //sLog.outDebug("WORLD: Received CMSG_GUILD_REMOVE"); - recvPacket >> plName; if(!normalizePlayerName(plName)) @@ -200,7 +194,7 @@ void WorldSession::HandleGuildAcceptOpcode(WorldPacket& /*recvPacket*/) Guild *guild; Player *player = GetPlayer(); - //sLog.outDebug("WORLD: Received CMSG_GUILD_ACCEPT"); + sLog.outDebug("WORLD: Received CMSG_GUILD_ACCEPT"); guild = objmgr.GetGuildById(player->GetGuildIdInvited()); if(!guild || player->GetGuildId()) @@ -221,12 +215,12 @@ void WorldSession::HandleGuildAcceptOpcode(WorldPacket& /*recvPacket*/) data << player->GetName(); guild->BroadcastPacket(&data); - //sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)"); + sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)"); } void WorldSession::HandleGuildDeclineOpcode(WorldPacket& /*recvPacket*/) { - //sLog.outDebug("WORLD: Received CMSG_GUILD_DECLINE"); + sLog.outDebug("WORLD: Received CMSG_GUILD_DECLINE"); GetPlayer()->SetGuildIdInvited(0); GetPlayer()->SetInGuild(0); @@ -234,10 +228,9 @@ void WorldSession::HandleGuildDeclineOpcode(WorldPacket& /*recvPacket*/) void WorldSession::HandleGuildInfoOpcode(WorldPacket& /*recvPacket*/) { - Guild *guild; - //sLog.outDebug("WORLD: Received CMSG_GUILD_INFO"); + sLog.outDebug("WORLD: Received CMSG_GUILD_INFO"); - guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); + Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); if(!guild) { SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); @@ -257,21 +250,17 @@ void WorldSession::HandleGuildInfoOpcode(WorldPacket& /*recvPacket*/) void WorldSession::HandleGuildRosterOpcode(WorldPacket& /*recvPacket*/) { - //sLog.outDebug("WORLD: Received CMSG_GUILD_ROSTER"); + sLog.outDebug("WORLD: Received CMSG_GUILD_ROSTER"); - Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); - if(!guild) - return; - - guild->Roster(this); + if(Guild* guild = objmgr.GetGuildById(_player->GetGuildId())) + guild->Roster(this); } void WorldSession::HandleGuildPromoteOpcode(WorldPacket& recvPacket) { + sLog.outDebug("WORLD: Received CMSG_GUILD_PROMOTE"); + std::string plName; - - //sLog.outDebug("WORLD: Received CMSG_GUILD_PROMOTE"); - recvPacket >> plName; if(!normalizePlayerName(plName)) @@ -330,10 +319,9 @@ void WorldSession::HandleGuildPromoteOpcode(WorldPacket& recvPacket) void WorldSession::HandleGuildDemoteOpcode(WorldPacket& recvPacket) { + sLog.outDebug("WORLD: Received CMSG_GUILD_DEMOTE"); + std::string plName; - - //sLog.outDebug("WORLD: Received CMSG_GUILD_DEMOTE"); - recvPacket >> plName; if(!normalizePlayerName(plName)) @@ -399,17 +387,15 @@ void WorldSession::HandleGuildDemoteOpcode(WorldPacket& recvPacket) void WorldSession::HandleGuildLeaveOpcode(WorldPacket& /*recvPacket*/) { - std::string plName; - Guild *guild; + sLog.outDebug("WORLD: Received CMSG_GUILD_LEAVE"); - //sLog.outDebug("WORLD: Received CMSG_GUILD_LEAVE"); - - guild = objmgr.GetGuildById(_player->GetGuildId()); + Guild *guild = objmgr.GetGuildById(_player->GetGuildId()); if(!guild) { SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); return; } + if(_player->GetGUID() == guild->GetLeader() && guild->GetMemberSize() > 1) { SendGuildCommandResult(GUILD_QUIT_S, "", GUILD_LEADER_LEAVE); @@ -422,8 +408,6 @@ void WorldSession::HandleGuildLeaveOpcode(WorldPacket& /*recvPacket*/) return; } - plName = _player->GetName(); - guild->DelMember(_player->GetGUID()); // Put record into guildlog guild->LogGuildEvent(GUILD_EVENT_LOG_LEAVE_GUILD, _player->GetGUIDLow(), 0, 0); @@ -431,27 +415,25 @@ void WorldSession::HandleGuildLeaveOpcode(WorldPacket& /*recvPacket*/) WorldPacket data(SMSG_GUILD_EVENT, (2+10)); // guess size data << (uint8)GE_LEFT; data << (uint8)1; // strings count - data << plName; + data << _player->GetName(); guild->BroadcastPacket(&data); - //sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)"); + sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)"); SendGuildCommandResult(GUILD_QUIT_S, guild->GetName(), GUILD_PLAYER_NO_MORE_IN_GUILD); } void WorldSession::HandleGuildDisbandOpcode(WorldPacket& /*recvPacket*/) { - std::string name; - Guild *guild; + sLog.outDebug("WORLD: Received CMSG_GUILD_DISBAND"); - //sLog.outDebug("WORLD: Received CMSG_GUILD_DISBAND"); - - guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); + Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); if(!guild) { SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); return; } + if(GetPlayer()->GetGUID() != guild->GetLeader()) { SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS); @@ -460,23 +442,22 @@ void WorldSession::HandleGuildDisbandOpcode(WorldPacket& /*recvPacket*/) guild->Disband(); - //sLog.outDebug("WORLD: Guild Sucefully Disbanded"); + sLog.outDebug("WORLD: Guild Successfully Disbanded"); } void WorldSession::HandleGuildLeaderOpcode(WorldPacket& recvPacket) { + sLog.outDebug("WORLD: Received CMSG_GUILD_LEADER"); + std::string name; - Player *oldLeader = GetPlayer(); - Guild *guild; - - //sLog.outDebug("WORLD: Received CMSG_GUILD_LEADER"); - recvPacket >> name; + Player *oldLeader = GetPlayer(); + if(!normalizePlayerName(name)) return; - guild = objmgr.GetGuildById(oldLeader->GetGuildId()); + Guild *guild = objmgr.GetGuildById(oldLeader->GetGuildId()); if (!guild) { @@ -509,17 +490,21 @@ void WorldSession::HandleGuildLeaderOpcode(WorldPacket& recvPacket) data << name.c_str(); guild->BroadcastPacket(&data); - //sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)"); + sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)"); } void WorldSession::HandleGuildMOTDOpcode(WorldPacket& recvPacket) { - Guild *guild; + sLog.outDebug("WORLD: Received CMSG_GUILD_MOTD"); + std::string MOTD; - //sLog.outDebug("WORLD: Received CMSG_GUILD_MOTD"); + if(!recvPacket.empty()) + recvPacket >> MOTD; + else + MOTD = ""; - guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); + Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); if(!guild) { SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); @@ -531,11 +516,6 @@ void WorldSession::HandleGuildMOTDOpcode(WorldPacket& recvPacket) return; } - if(!recvPacket.empty()) - recvPacket >> MOTD; - else - MOTD = ""; - guild->SetMOTD(MOTD); WorldPacket data(SMSG_GUILD_EVENT, (2+MOTD.size()+1)); @@ -544,15 +524,14 @@ void WorldSession::HandleGuildMOTDOpcode(WorldPacket& recvPacket) data << MOTD; guild->BroadcastPacket(&data); - //sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)"); + sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)"); } void WorldSession::HandleGuildSetPublicNoteOpcode(WorldPacket& recvPacket) { + sLog.outDebug("WORLD: Received CMSG_GUILD_SET_PUBLIC_NOTE"); + std::string name,PNOTE; - - //sLog.outDebug("WORLD: Received CMSG_GUILD_SET_PUBLIC_NOTE"); - recvPacket >> name; if(!normalizePlayerName(name)) @@ -589,10 +568,9 @@ void WorldSession::HandleGuildSetPublicNoteOpcode(WorldPacket& recvPacket) void WorldSession::HandleGuildSetOfficerNoteOpcode(WorldPacket& recvPacket) { + sLog.outDebug("WORLD: Received CMSG_GUILD_SET_OFFICER_NOTE"); + std::string plName, OFFNOTE; - - //sLog.outDebug("WORLD: Received CMSG_GUILD_SET_OFFICER_NOTE"); - recvPacket >> plName; if (!normalizePlayerName(plName)) @@ -628,23 +606,19 @@ void WorldSession::HandleGuildSetOfficerNoteOpcode(WorldPacket& recvPacket) void WorldSession::HandleGuildRankOpcode(WorldPacket& recvPacket) { - //recvPacket.hexlike(); - - Guild *guild; std::string rankname; uint32 rankId; uint32 rights, MoneyPerDay; - //sLog.outDebug("WORLD: Received CMSG_GUILD_RANK"); + sLog.outDebug("WORLD: Received CMSG_GUILD_RANK"); - guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); + Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); if(!guild) { recvPacket.rpos(recvPacket.wpos()); // set to end to avoid warnings spam SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); return; } - else if(GetPlayer()->GetGUID() != guild->GetLeader()) { recvPacket.rpos(recvPacket.wpos()); // set to end to avoid warnings spam @@ -683,12 +657,12 @@ void WorldSession::HandleGuildRankOpcode(WorldPacket& recvPacket) void WorldSession::HandleGuildAddRankOpcode(WorldPacket& recvPacket) { - Guild *guild; + sLog.outDebug("WORLD: Received CMSG_GUILD_ADD_RANK"); + std::string rankname; + recvPacket >> rankname; - //sLog.outDebug("WORLD: Received CMSG_GUILD_ADD_RANK"); - - guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); + Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); if(!guild) { SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); @@ -704,8 +678,6 @@ void WorldSession::HandleGuildAddRankOpcode(WorldPacket& recvPacket) if(guild->GetRanksSize() >= GUILD_RANKS_MAX_COUNT) // client not let create more 10 than ranks return; - recvPacket >> rankname; - guild->CreateRank(rankname, GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK); guild->Query(this); @@ -714,18 +686,14 @@ void WorldSession::HandleGuildAddRankOpcode(WorldPacket& recvPacket) void WorldSession::HandleGuildDelRankOpcode(WorldPacket& /*recvPacket*/) { - Guild *guild; - std::string rankname; + sLog.outDebug("WORLD: Received CMSG_GUILD_DEL_RANK"); - //sLog.outDebug("WORLD: Received CMSG_GUILD_DEL_RANK"); - - guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); + Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); if(!guild) { SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD); return; } - else if(GetPlayer()->GetGUID() != guild->GetLeader()) { SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS); @@ -746,15 +714,14 @@ void WorldSession::SendGuildCommandResult(uint32 typecmd, const std::string& str data << cmdresult; SendPacket(&data); - //sLog.outDebug("WORLD: Sent (SMSG_GUILD_COMMAND_RESULT)"); + sLog.outDebug("WORLD: Sent (SMSG_GUILD_COMMAND_RESULT)"); } void WorldSession::HandleGuildChangeInfoTextOpcode(WorldPacket& recvPacket) { - //sLog.outDebug("WORLD: Received CMSG_GUILD_INFO_TEXT"); + sLog.outDebug("WORLD: Received CMSG_GUILD_INFO_TEXT"); std::string GINFO; - recvPacket >> GINFO; Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); @@ -775,17 +742,13 @@ void WorldSession::HandleGuildChangeInfoTextOpcode(WorldPacket& recvPacket) void WorldSession::HandleSaveGuildEmblemOpcode(WorldPacket& recvPacket) { - //sLog.outDebug("WORLD: Received MSG_SAVE_GUILD_EMBLEM"); + sLog.outDebug("WORLD: Received MSG_SAVE_GUILD_EMBLEM"); uint64 vendorGuid; - - uint32 EmblemStyle; - uint32 EmblemColor; - uint32 BorderStyle; - uint32 BorderColor; - uint32 BackgroundColor; + uint32 EmblemStyle, EmblemColor, BorderStyle, BorderColor, BackgroundColor; recvPacket >> vendorGuid; + recvPacket >> EmblemStyle >> EmblemColor >> BorderStyle >> BorderColor >> BackgroundColor; Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(vendorGuid,UNIT_NPC_FLAG_TABARDDESIGNER); if (!pCreature) @@ -800,12 +763,6 @@ void WorldSession::HandleSaveGuildEmblemOpcode(WorldPacket& recvPacket) if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); - recvPacket >> EmblemStyle; - recvPacket >> EmblemColor; - recvPacket >> BorderStyle; - recvPacket >> BorderColor; - recvPacket >> BackgroundColor; - Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); if(!guild) { @@ -841,17 +798,10 @@ void WorldSession::HandleGuildEventLogQueryOpcode(WorldPacket& /* recvPacket */) { // empty sLog.outDebug("WORLD: Received (MSG_GUILD_EVENT_LOG_QUERY)"); - //recvPacket.hexlike(); - uint32 GuildId = GetPlayer()->GetGuildId(); - if (GuildId == 0) - return; - - Guild *pGuild = objmgr.GetGuildById(GuildId); - if(!pGuild) - return; - - pGuild->DisplayGuildEventLog(this); + if(uint32 GuildId = GetPlayer()->GetGuildId()) + if(Guild *pGuild = objmgr.GetGuildById(GuildId)) + pGuild->DisplayGuildEventLog(this); } /****** GUILD BANK *******/ @@ -859,53 +809,45 @@ void WorldSession::HandleGuildEventLogQueryOpcode(WorldPacket& /* recvPacket */) void WorldSession::HandleGuildBankMoneyWithdrawn( WorldPacket & /* recv_data */ ) { sLog.outDebug("WORLD: Received (MSG_GUILD_BANK_MONEY_WITHDRAWN)"); - //recv_data.hexlike(); - uint32 GuildId = GetPlayer()->GetGuildId(); - if (GuildId == 0) - return; - - Guild *pGuild = objmgr.GetGuildById(GuildId); - if(!pGuild) - return; - - pGuild->SendMoneyInfo(this, GetPlayer()->GetGUIDLow()); + if(uint32 GuildId = GetPlayer()->GetGuildId()) + if(Guild *pGuild = objmgr.GetGuildById(GuildId)) + pGuild->SendMoneyInfo(this, GetPlayer()->GetGUIDLow()); } void WorldSession::HandleGuildPermissions( WorldPacket& /* recv_data */ ) { sLog.outDebug("WORLD: Received (MSG_GUILD_PERMISSIONS)"); - uint32 GuildId = GetPlayer()->GetGuildId(); - if (GuildId == 0) - return; - - Guild *pGuild = objmgr.GetGuildById(GuildId); - if(!pGuild) - return; - - uint32 rankId = GetPlayer()->GetRank(); - - WorldPacket data(MSG_GUILD_PERMISSIONS, 4*15+1); - data << uint32(rankId); // guild rank id - data << uint32(pGuild->GetRankRights(rankId)); // rank rights - // money per day left - data << uint32(pGuild->GetMemberMoneyWithdrawRem(GetPlayer()->GetGUIDLow())); - data << uint8(pGuild->GetPurchasedTabs()); // tabs count - // why sending all info when not all tabs are purchased??? - for(int i = 0; i < GUILD_BANK_MAX_TABS; ++i) + if(uint32 GuildId = GetPlayer()->GetGuildId()) { - data << uint32(pGuild->GetBankRights(rankId, uint8(i))); - data << uint32(pGuild->GetMemberSlotWithdrawRem(GetPlayer()->GetGUIDLow(), uint8(i))); + if(Guild *pGuild = objmgr.GetGuildById(GuildId)) + { + uint32 rankId = GetPlayer()->GetRank(); + + WorldPacket data(MSG_GUILD_PERMISSIONS, 4*15+1); + data << uint32(rankId); // guild rank id + data << uint32(pGuild->GetRankRights(rankId)); // rank rights + // money per day left + data << uint32(pGuild->GetMemberMoneyWithdrawRem(GetPlayer()->GetGUIDLow())); + data << uint8(pGuild->GetPurchasedTabs()); // tabs count + // why sending all info when not all tabs are purchased??? + for(int i = 0; i < GUILD_BANK_MAX_TABS; ++i) + { + data << uint32(pGuild->GetBankRights(rankId, uint8(i))); + data << uint32(pGuild->GetMemberSlotWithdrawRem(GetPlayer()->GetGUIDLow(), uint8(i))); + } + SendPacket(&data); + sLog.outDebug("WORLD: Sent (MSG_GUILD_PERMISSIONS)"); + } } - SendPacket(&data); - sLog.outDebug("WORLD: Sent (MSG_GUILD_PERMISSIONS)"); } /* Called when clicking on Guild bank gameobject */ void WorldSession::HandleGuildBankerActivate( WorldPacket & recv_data ) { sLog.outDebug("WORLD: Received (CMSG_GUILD_BANKER_ACTIVATE)"); + uint64 GoGuid; uint8 unk; recv_data >> GoGuid >> unk; @@ -929,31 +871,31 @@ void WorldSession::HandleGuildBankerActivate( WorldPacket & recv_data ) void WorldSession::HandleGuildBankQueryTab( WorldPacket & recv_data ) { sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_QUERY_TAB)"); + uint64 GoGuid; - uint8 TabId,unk1; + uint8 TabId, unk1; recv_data >> GoGuid >> TabId >> unk1; if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK)) return; - uint32 GuildId = GetPlayer()->GetGuildId(); - if (GuildId == 0) - return; + if(uint32 GuildId = GetPlayer()->GetGuildId()) + { + if(Guild *pGuild = objmgr.GetGuildById(GuildId)) + { + // Let's update the amount of gold the player can withdraw before displaying the content + // This is useful if money withdraw right has changed + pGuild->SendMoneyInfo(this, GetPlayer()->GetGUIDLow()); - Guild *pGuild = objmgr.GetGuildById(GuildId); - if(!pGuild) - return; - - // Let's update the amount of gold the player can withdraw before displaying the content - // This is usefull if money withdraw right has changed - pGuild->SendMoneyInfo(this, GetPlayer()->GetGUIDLow()); - - pGuild->DisplayGuildBankContent(this, TabId); + pGuild->DisplayGuildBankContent(this, TabId); + } + } } void WorldSession::HandleGuildBankDepositMoney( WorldPacket & recv_data ) { sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_DEPOSIT_MONEY)"); + uint64 GoGuid; uint32 money; recv_data >> GoGuid >> money; @@ -964,43 +906,42 @@ void WorldSession::HandleGuildBankDepositMoney( WorldPacket & recv_data ) if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK)) return; - uint32 GuildId = GetPlayer()->GetGuildId(); - if (GuildId == 0) - return; - - Guild *pGuild = objmgr.GetGuildById(GuildId); - if(!pGuild) - return; - if (GetPlayer()->GetMoney() < money) return; - CharacterDatabase.BeginTransaction(); - - pGuild->SetBankMoney(pGuild->GetGuildBankMoney()+money); - GetPlayer()->ModifyMoney(-int(money)); - GetPlayer()->SaveGoldToDB(); - - CharacterDatabase.CommitTransaction(); - - // logging money - if(_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE)) + if(uint32 GuildId = GetPlayer()->GetGuildId()) { - sLog.outCommand(_player->GetSession()->GetAccountId(),"GM %s (Account: %u) deposit money (Amount: %u) to guild bank (Guild ID %u)", - _player->GetName(),_player->GetSession()->GetAccountId(),money,GuildId); + if(Guild *pGuild = objmgr.GetGuildById(GuildId)) + { + CharacterDatabase.BeginTransaction(); + + pGuild->SetBankMoney(pGuild->GetGuildBankMoney()+money); + GetPlayer()->ModifyMoney(-int(money)); + GetPlayer()->SaveGoldToDB(); + + CharacterDatabase.CommitTransaction(); + + // logging money + if(_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE)) + { + sLog.outCommand(_player->GetSession()->GetAccountId(),"GM %s (Account: %u) deposit money (Amount: %u) to guild bank (Guild ID %u)", + _player->GetName(),_player->GetSession()->GetAccountId(),money,GuildId); + } + + // log + pGuild->LogBankEvent(GUILD_BANK_LOG_DEPOSIT_MONEY, uint8(0), GetPlayer()->GetGUIDLow(), money); + + pGuild->DisplayGuildBankTabsInfo(this); + pGuild->DisplayGuildBankContent(this, 0); + pGuild->DisplayGuildBankMoneyUpdate(); + } } - - // log - pGuild->LogBankEvent(GUILD_BANK_LOG_DEPOSIT_MONEY, uint8(0), GetPlayer()->GetGUIDLow(), money); - - pGuild->DisplayGuildBankTabsInfo(this); - pGuild->DisplayGuildBankContent(this, 0); - pGuild->DisplayGuildBankMoneyUpdate(); } void WorldSession::HandleGuildBankWithdrawMoney( WorldPacket & recv_data ) { sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_WITHDRAW_MONEY)"); + uint64 GoGuid; uint32 money; recv_data >> GoGuid >> money; @@ -1050,7 +991,6 @@ void WorldSession::HandleGuildBankWithdrawMoney( WorldPacket & recv_data ) void WorldSession::HandleGuildBankSwapItems( WorldPacket & recv_data ) { sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_SWAP_ITEMS)"); - //recv_data.hexlike(); uint64 GoGuid; uint8 BankToBank; @@ -1112,43 +1052,39 @@ void WorldSession::HandleGuildBankSwapItems( WorldPacket & recv_data ) if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK)) return; - uint32 GuildId = GetPlayer()->GetGuildId(); - if (GuildId == 0) - return; - - Guild *pGuild = objmgr.GetGuildById(GuildId); - if(!pGuild) - return; - - Player *pl = GetPlayer(); - - // Bank <-> Bank - if (BankToBank) + if(uint32 GuildId = GetPlayer()->GetGuildId()) { - pGuild->SwapItems(pl, BankTab, BankTabSlot, BankTabDst, BankTabSlotDst, SplitedAmount); - return; + if(Guild *pGuild = objmgr.GetGuildById(GuildId)) + { + // Bank <-> Bank + if (BankToBank) + { + pGuild->SwapItems(_player, BankTab, BankTabSlot, BankTabDst, BankTabSlotDst, SplitedAmount); + return; + } + + // Player <-> Bank + + // allow work with inventory only + if(!Player::IsInventoryPos(PlayerBag, PlayerSlot) && !(PlayerBag == NULL_BAG && PlayerSlot == NULL_SLOT) ) + { + _player->SendEquipError( EQUIP_ERR_NONE, NULL, NULL ); + return; + } + + // BankToChar swap or char to bank remaining + if (ToChar) // Bank -> Char cases + pGuild->MoveFromBankToChar(_player, BankTab, BankTabSlot, PlayerBag, PlayerSlot, SplitedAmount); + else // Char -> Bank cases + pGuild->MoveFromCharToBank(_player, PlayerBag, PlayerSlot, BankTab, BankTabSlot, SplitedAmount); + } } - - // Player <-> Bank - - // allow work with inventory only - if(!Player::IsInventoryPos(PlayerBag,PlayerSlot) && !(PlayerBag == NULL_BAG && PlayerSlot == NULL_SLOT) ) - { - _player->SendEquipError( EQUIP_ERR_NONE, NULL, NULL ); - return; - } - - // BankToChar swap or char to bank remaining - if (ToChar) // Bank -> Char cases - pGuild->MoveFromBankToChar(pl, BankTab, BankTabSlot, PlayerBag, PlayerSlot, SplitedAmount); - else // Char -> Bank cases - pGuild->MoveFromCharToBank(pl, PlayerBag, PlayerSlot, BankTab, BankTabSlot, SplitedAmount); } void WorldSession::HandleGuildBankBuyTab( WorldPacket & recv_data ) { sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_BUY_TAB)"); - //recv_data.hexlike(); + uint64 GoGuid; uint8 TabId; @@ -1175,7 +1111,7 @@ void WorldSession::HandleGuildBankBuyTab( WorldPacket & recv_data ) if (TabId != pGuild->GetPurchasedTabs()) // m_PurchasedTabs = 0 when buying Tab 0, that is why this check can be made { - sLog.outError("Error: trying to buy a tab non contigous to owned ones"); + sLog.outError("Error: trying to buy a tab non contiguous to owned ones"); return; } @@ -1194,7 +1130,7 @@ void WorldSession::HandleGuildBankBuyTab( WorldPacket & recv_data ) void WorldSession::HandleGuildBankUpdateTab( WorldPacket & recv_data ) { sLog.outDebug("WORLD: Received (CMSG_GUILD_BANK_UPDATE_TAB)"); - //recv_data.hexlike(); + uint64 GoGuid; uint8 TabId; std::string Name; @@ -1214,72 +1150,53 @@ void WorldSession::HandleGuildBankUpdateTab( WorldPacket & recv_data ) if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK)) return; - uint32 GuildId = GetPlayer()->GetGuildId(); - if (GuildId==0) - return; - - Guild *pGuild = objmgr.GetGuildById(GuildId); - if(!pGuild) - return; - - pGuild->SetGuildBankTabInfo(TabId, Name, IconIndex); - pGuild->DisplayGuildBankTabsInfo(this); - pGuild->DisplayGuildBankContent(this, TabId); + if(uint32 GuildId = GetPlayer()->GetGuildId()) + { + if(Guild *pGuild = objmgr.GetGuildById(GuildId)) + { + pGuild->SetGuildBankTabInfo(TabId, Name, IconIndex); + pGuild->DisplayGuildBankTabsInfo(this); + pGuild->DisplayGuildBankContent(this, TabId); + } + } } void WorldSession::HandleGuildBankLogQuery( WorldPacket & recv_data ) { sLog.outDebug("WORLD: Received (MSG_GUILD_BANK_LOG_QUERY)"); - uint32 GuildId = GetPlayer()->GetGuildId(); - if (GuildId == 0) - return; - - Guild *pGuild = objmgr.GetGuildById(GuildId); - if(!pGuild) - return; - uint8 TabId; recv_data >> TabId; - pGuild->DisplayGuildBankLogs(this, TabId); + if(uint32 GuildId = GetPlayer()->GetGuildId()) + if(Guild *pGuild = objmgr.GetGuildById(GuildId)) + pGuild->DisplayGuildBankLogs(this, TabId); } void WorldSession::HandleQueryGuildBankTabText(WorldPacket &recv_data) { sLog.outDebug("WORLD: Received MSG_QUERY_GUILD_BANK_TEXT"); - uint32 GuildId = GetPlayer()->GetGuildId(); - if (GuildId == 0) - return; - - Guild *pGuild = objmgr.GetGuildById(GuildId); - if(!pGuild) - return; - uint8 TabId; recv_data >> TabId; - pGuild->SendGuildBankTabText(this, TabId); + if(uint32 GuildId = GetPlayer()->GetGuildId()) + if(Guild *pGuild = objmgr.GetGuildById(GuildId)) + pGuild->SendGuildBankTabText(this, TabId); } void WorldSession::HandleSetGuildBankTabText(WorldPacket &recv_data) { sLog.outDebug("WORLD: Received CMSG_SET_GUILD_BANK_TEXT"); - uint32 GuildId = GetPlayer()->GetGuildId(); - if (GuildId == 0) - return; - - Guild *pGuild = objmgr.GetGuildById(GuildId); - if(!pGuild) - return; uint8 TabId; std::string Text; recv_data >> TabId; recv_data >> Text; - pGuild->SetGuildBankTabText(TabId, Text); + if(uint32 GuildId = GetPlayer()->GetGuildId()) + if(Guild *pGuild = objmgr.GetGuildById(GuildId)) + pGuild->SetGuildBankTabText(TabId, Text); } void WorldSession::SendSaveGuildEmblem( uint32 msg ) diff --git a/src/game/InstanceSaveMgr.cpp b/src/game/InstanceSaveMgr.cpp index c19462472..2db0c49d4 100644 --- a/src/game/InstanceSaveMgr.cpp +++ b/src/game/InstanceSaveMgr.cpp @@ -72,15 +72,27 @@ InstanceSaveManager::~InstanceSaveManager() - adding instance into manager - called from InstanceMap::Add, _LoadBoundInstances, LoadGroups */ -InstanceSave* InstanceSaveManager::AddInstanceSave(uint32 mapId, uint32 instanceId, uint8 difficulty, time_t resetTime, bool canReset, bool load) +InstanceSave* InstanceSaveManager::AddInstanceSave(uint32 mapId, uint32 instanceId, Difficulty difficulty, time_t resetTime, bool canReset, bool load) { - InstanceSave *save = GetInstanceSave(instanceId); - if(save) return save; + if(InstanceSave *old_save = GetInstanceSave(instanceId)) + return old_save; const MapEntry* entry = sMapStore.LookupEntry(mapId); - if(!entry || instanceId == 0) + if (!entry) { - sLog.outError("InstanceSaveManager::AddInstanceSave: mapid = %d, instanceid = %d!", mapId, instanceId); + sLog.outError("InstanceSaveManager::AddInstanceSave: wrong mapid = %d!", mapId, instanceId); + return NULL; + } + + if (instanceId == 0) + { + sLog.outError("InstanceSaveManager::AddInstanceSave: mapid = %d, wrong instanceid = %d!", mapId, instanceId); + return NULL; + } + + if (difficulty >= (entry->IsRaid() ? MAX_RAID_DIFFICULTY : MAX_DUNGEON_DIFFICULTY)) + { + sLog.outError("InstanceSaveManager::AddInstanceSave: mapid = %d, instanceid = %d, wrong dificalty %u!", mapId, instanceId, difficulty); return NULL; } @@ -88,7 +100,7 @@ InstanceSave* InstanceSaveManager::AddInstanceSave(uint32 mapId, uint32 instance { // initialize reset time // for normal instances if no creatures are killed the instance will reset in two hours - if(entry->map_type == MAP_RAID || difficulty == DIFFICULTY_HEROIC) + if(entry->map_type == MAP_RAID || difficulty == DUNGEON_DIFFICULTY_HEROIC) resetTime = GetResetTimeFor(mapId); else { @@ -100,7 +112,7 @@ InstanceSave* InstanceSaveManager::AddInstanceSave(uint32 mapId, uint32 instance sLog.outDebug("InstanceSaveManager::AddInstanceSave: mapid = %d, instanceid = %d", mapId, instanceId); - save = new InstanceSave(mapId, instanceId, difficulty, resetTime, canReset); + InstanceSave *save = new InstanceSave(mapId, instanceId, difficulty, resetTime, canReset); if(!load) save->SaveToDB(); m_instanceSaveById[instanceId] = save; @@ -136,7 +148,7 @@ void InstanceSaveManager::RemoveInstanceSave(uint32 InstanceId) } } -InstanceSave::InstanceSave(uint16 MapId, uint32 InstanceId, uint8 difficulty, time_t resetTime, bool canReset) +InstanceSave::InstanceSave(uint16 MapId, uint32 InstanceId, Difficulty difficulty, time_t resetTime, bool canReset) : m_resetTime(resetTime), m_instanceid(InstanceId), m_mapid(MapId), m_difficulty(difficulty), m_canReset(canReset) { @@ -175,7 +187,7 @@ time_t InstanceSave::GetResetTimeForDB() { // only save the reset time for normal instances const MapEntry *entry = sMapStore.LookupEntry(GetMapId()); - if(!entry || entry->map_type == MAP_RAID || GetDifficulty() == DIFFICULTY_HEROIC) + if(!entry || entry->map_type == MAP_RAID || GetDifficulty() == DUNGEON_DIFFICULTY_HEROIC) return 0; else return GetResetTime(); @@ -446,10 +458,7 @@ void InstanceSaveManager::LoadResetTimes() for(uint32 i = 0; i < sInstanceTemplate.MaxEntry; i++) { InstanceTemplate const* temp = objmgr.GetInstanceTemplate(i); - if(!temp) continue; - // only raid/heroic maps have a global reset time - const MapEntry* entry = sMapStore.LookupEntry(temp->map); - if(!entry || !entry->HasResetTime()) + if(!temp || temp->reset_delay == 0) continue; uint32 period = temp->reset_delay * DAY; diff --git a/src/game/InstanceSaveMgr.h b/src/game/InstanceSaveMgr.h index 5f573313a..f1d08e8f2 100644 --- a/src/game/InstanceSaveMgr.h +++ b/src/game/InstanceSaveMgr.h @@ -47,7 +47,7 @@ class InstanceSave - any new instance is being generated - the first time a player bound to InstanceId logs in - when a group bound to the instance is loaded */ - InstanceSave(uint16 MapId, uint32 InstanceId, uint8 difficulty, time_t resetTime, bool canReset); + InstanceSave(uint16 MapId, uint32 InstanceId, Difficulty difficulty, time_t resetTime, bool canReset); /* Unloaded when m_playerList and m_groupList become empty or when the instance is reset */ @@ -92,7 +92,7 @@ class InstanceSave /* currently it is possible to omit this information from this structure but that would depend on a lot of things that can easily change in future */ - uint8 GetDifficulty() { return m_difficulty; } + Difficulty GetDifficulty() { return m_difficulty; } typedef std::list PlayerListType; typedef std::list GroupListType; @@ -105,8 +105,8 @@ class InstanceSave GroupListType m_groupList; time_t m_resetTime; uint32 m_instanceid; - uint16 m_mapid; - uint8 m_difficulty; + uint32 m_mapid; + Difficulty m_difficulty; bool m_canReset; }; @@ -143,7 +143,7 @@ class MANGOS_DLL_DECL InstanceSaveManager : public MaNGOS::SingletonIsValidPos(srcbag,srcslot)) + if(!_player->IsValidPos(srcbag, srcslot)) { _player->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); return; } - if(!_player->IsValidPos(dstbag,dstslot)) + if(!_player->IsValidPos(dstbag, dstslot)) { _player->SendEquipError( EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, NULL, NULL ); return; @@ -64,14 +64,14 @@ void WorldSession::HandleSwapInvItemOpcode( WorldPacket & recv_data ) //sLog.outDebug("WORLD: CMSG_SWAP_INV_ITEM"); uint8 srcslot, dstslot; - recv_data >> srcslot >> dstslot; + recv_data >> dstslot >> srcslot; //sLog.outDebug("STORAGE: receive srcslot = %u, dstslot = %u", srcslot, dstslot); - // prevent attempt swap same item to current position generated by client at special checting sequence - if(srcslot==dstslot) + // prevent attempt swap same item to current position generated by client at special cheating sequence + if(srcslot == dstslot) return; - if(!_player->IsValidPos(INVENTORY_SLOT_BAG_0,srcslot)) + if(!_player->IsValidPos(INVENTORY_SLOT_BAG_0, srcslot)) { _player->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); return; @@ -119,17 +119,17 @@ void WorldSession::HandleSwapItem( WorldPacket & recv_data ) uint16 src = ( (srcbag << 8) | srcslot ); uint16 dst = ( (dstbag << 8) | dstslot ); - // prevent attempt swap same item to current position generated by client at special checting sequence - if(src==dst) + // prevent attempt swap same item to current position generated by client at special cheating sequence + if(src == dst) return; - if(!_player->IsValidPos(srcbag,srcslot)) + if(!_player->IsValidPos(srcbag, srcslot)) { _player->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); return; } - if(!_player->IsValidPos(dstbag,dstslot)) + if(!_player->IsValidPos(dstbag, dstslot)) { _player->SendEquipError( EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, NULL, NULL ); return; @@ -166,7 +166,7 @@ void WorldSession::HandleAutoEquipItemOpcode( WorldPacket & recv_data ) } uint16 src = pSrcItem->GetPos(); - if(dest==src) // prevent equip in same slot, only at cheat + if(dest == src) // prevent equip in same slot, only at cheat return; Item *pDstItem = _player->GetItemByPos( dest ); @@ -316,6 +316,7 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data ) data << pProto->DisplayInfoID; data << pProto->Quality; data << pProto->Flags; + data << pProto->Faction; // 3.2 faction? data << pProto->BuyPrice; data << pProto->SellPrice; data << pProto->InventoryType; @@ -431,7 +432,7 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data ) } else { - sLog.outDebug( "WORLD: CMSG_ITEM_QUERY_SINGLE - NO item INFO! (ENTRY: %u)", item ); + sLog.outDebug( "WORLD: CMSG_ITEM_QUERY_SINGLE - NO item INFO! (ENTRY: %u)", item ); WorldPacket data( SMSG_ITEM_QUERY_SINGLE_RESPONSE, 4); data << uint32(item | 0x80000000); SendPacket( &data ); @@ -473,7 +474,7 @@ void WorldSession::HandleReadItem( WorldPacket & recv_data ) void WorldSession::HandlePageQuerySkippedOpcode( WorldPacket & recv_data ) { - sLog.outDebug( "WORLD: Received CMSG_PAGE_TEXT_QUERY" ); + sLog.outDebug( "WORLD: Received CMSG_PAGE_TEXT_QUERY" ); uint32 itemid; uint64 guid; @@ -495,7 +496,7 @@ void WorldSession::HandleSellItemOpcode( WorldPacket & recv_data ) if(!itemguid) return; - Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(vendorguid,UNIT_NPC_FLAG_VENDOR); + Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(vendorguid, UNIT_NPC_FLAG_VENDOR); if (!pCreature) { sLog.outDebug( "WORLD: HandleSellItemOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(vendorguid)) ); @@ -511,7 +512,7 @@ void WorldSession::HandleSellItemOpcode( WorldPacket & recv_data ) if( pItem ) { // prevent sell not owner item - if(_player->GetGUID()!=pItem->GetOwnerGUID()) + if(_player->GetGUID() != pItem->GetOwnerGUID()) { _player->SendSellError( SELL_ERR_CANT_SELL_ITEM, pCreature, itemguid, 0); return; @@ -525,20 +526,20 @@ void WorldSession::HandleSellItemOpcode( WorldPacket & recv_data ) } // prevent sell currently looted item - if(_player->GetLootGUID()==pItem->GetGUID()) + if(_player->GetLootGUID() == pItem->GetGUID()) { _player->SendSellError( SELL_ERR_CANT_SELL_ITEM, pCreature, itemguid, 0); return; } // special case at auto sell (sell all) - if(count==0) + if(count == 0) { count = pItem->GetCount(); } else { - // prevent sell more items that exist in stack (possable only not from client) + // prevent sell more items that exist in stack (possible only not from client) if(count > pItem->GetCount()) { _player->SendSellError( SELL_ERR_CANT_SELL_ITEM, pCreature, itemguid, 0); @@ -592,13 +593,13 @@ void WorldSession::HandleSellItemOpcode( WorldPacket & recv_data ) void WorldSession::HandleBuybackItem(WorldPacket & recv_data) { - sLog.outDebug( "WORLD: Received CMSG_BUYBACK_ITEM" ); + sLog.outDebug( "WORLD: Received CMSG_BUYBACK_ITEM" ); uint64 vendorguid; uint32 slot; recv_data >> vendorguid >> slot; - Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(vendorguid,UNIT_NPC_FLAG_VENDOR); + Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(vendorguid, UNIT_NPC_FLAG_VENDOR); if (!pCreature) { sLog.outDebug( "WORLD: HandleBuybackItem - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(vendorguid)) ); @@ -639,7 +640,7 @@ void WorldSession::HandleBuybackItem(WorldPacket & recv_data) void WorldSession::HandleBuyItemInSlotOpcode( WorldPacket & recv_data ) { - sLog.outDebug( "WORLD: Received CMSG_BUY_ITEM_IN_SLOT" ); + sLog.outDebug( "WORLD: Received CMSG_BUY_ITEM_IN_SLOT" ); uint64 vendorguid, bagguid; uint32 item, slot, count; uint8 bagslot; @@ -670,19 +671,19 @@ void WorldSession::HandleBuyItemInSlotOpcode( WorldPacket & recv_data ) if (bag == NULL_BAG) return; - GetPlayer()->BuyItemFromVendor(vendorguid,item,count,bag,bagslot); + GetPlayer()->BuyItemFromVendor(vendorguid, item, count, bag, bagslot); } void WorldSession::HandleBuyItemOpcode( WorldPacket & recv_data ) { - sLog.outDebug( "WORLD: Received CMSG_BUY_ITEM" ); + sLog.outDebug( "WORLD: Received CMSG_BUY_ITEM" ); uint64 vendorguid; uint32 item, slot, count; uint8 unk1; recv_data >> vendorguid >> item >> slot >> count >> unk1; - GetPlayer()->BuyItemFromVendor(vendorguid,item,count,NULL_BAG,NULL_SLOT); + GetPlayer()->BuyItemFromVendor(vendorguid, item, count, NULL_BAG, NULL_SLOT); } void WorldSession::HandleListInventoryOpcode( WorldPacket & recv_data ) @@ -694,16 +695,16 @@ void WorldSession::HandleListInventoryOpcode( WorldPacket & recv_data ) if(!GetPlayer()->isAlive()) return; - sLog.outDebug( "WORLD: Recvd CMSG_LIST_INVENTORY" ); + sLog.outDebug( "WORLD: Recvd CMSG_LIST_INVENTORY" ); SendListInventory( guid ); } void WorldSession::SendListInventory( uint64 vendorguid ) { - sLog.outDebug( "WORLD: Sent SMSG_LIST_INVENTORY" ); + sLog.outDebug( "WORLD: Sent SMSG_LIST_INVENTORY" ); - Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(vendorguid,UNIT_NPC_FLAG_VENDOR); + Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(vendorguid, UNIT_NPC_FLAG_VENDOR); if (!pCreature) { sLog.outDebug( "WORLD: SendListInventory - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(vendorguid)) ); @@ -779,7 +780,7 @@ void WorldSession::HandleAutoStoreBagItemOpcode( WorldPacket & recv_data ) if( !pItem ) return; - if(!_player->IsValidPos(dstbag,NULL_SLOT)) + if(!_player->IsValidPos(dstbag, NULL_SLOT)) { _player->SendEquipError( EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, NULL, NULL ); return; @@ -807,9 +808,9 @@ void WorldSession::HandleAutoStoreBagItemOpcode( WorldPacket & recv_data ) } // no-op: placed in same slot - if(dest.size()==1 && dest[0].pos==src) + if(dest.size() == 1 && dest[0].pos == src) { - // just remove grey item state + // just remove gray item state _player->SendEquipError( EQUIP_ERR_NONE, pItem, NULL ); return; } @@ -944,10 +945,10 @@ void WorldSession::HandleSetAmmoOpcode(WorldPacket & recv_data) void WorldSession::SendEnchantmentLog(uint64 Target, uint64 Caster,uint32 ItemID,uint32 SpellID) { WorldPacket data(SMSG_ENCHANTMENTLOG, (8+8+4+4+1)); // last check 2.0.10 - data << Target; - data << Caster; - data << ItemID; - data << SpellID; + data << uint64(Target); + data << uint64(Caster); + data << uint32(ItemID); + data << uint32(SpellID); data << uint8(0); SendPacket(&data); } @@ -1037,7 +1038,7 @@ void WorldSession::HandleWrapItemOpcode(WorldPacket& recv_data) return; } - if(item==gift) // not possable with pacjket from real client + if(item == gift) // not possible with packet from real client { _player->SendEquipError( EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED, item, NULL ); return; @@ -1074,7 +1075,7 @@ void WorldSession::HandleWrapItemOpcode(WorldPacket& recv_data) } // maybe not correct check (it is better than nothing) - if(item->GetProto()->MaxCount>0) + if(item->GetProto()->MaxCount > 0) { _player->SendEquipError( EQUIP_ERR_UNIQUE_CANT_BE_WRAPPED, item, NULL ); return; @@ -1097,7 +1098,7 @@ void WorldSession::HandleWrapItemOpcode(WorldPacket& recv_data) item->SetUInt32Value(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED); item->SetState(ITEM_CHANGED, _player); - if(item->GetState()==ITEM_NEW) // save new item, to have alway for `character_gifts` record in `item_instance` + if(item->GetState() == ITEM_NEW) // save new item, to have alway for `character_gifts` record in `item_instance` { // after save it will be impossible to remove the item from the queue item->RemoveFromUpdateQueueOf(_player); @@ -1159,8 +1160,8 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recv_data) if(!itemTarget->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT)) return; - // not first not-colored (not normaly used) socket - if(i!=0 && !itemProto->Socket[i-1].Color && (i+1 >= MAX_GEM_SOCKETS || itemProto->Socket[i+1].Color)) + // not first not-colored (not normally used) socket + if(i != 0 && !itemProto->Socket[i - 1].Color && (i + 1 >= MAX_GEM_SOCKETS || itemProto->Socket[i + 1].Color)) return; // ok, this is first not colored socket for item with prismatic socket @@ -1180,7 +1181,7 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recv_data) for(int i = 0; i < MAX_GEM_SOCKETS; ++i) //get new and old enchantments { GemEnchants[i] = (GemProps[i]) ? GemProps[i]->spellitemenchantement : 0; - OldEnchants[i] = itemTarget->GetEnchantmentId(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+i)); + OldEnchants[i] = itemTarget->GetEnchantmentId(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT + i)); } // check unique-equipped conditions @@ -1197,7 +1198,7 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recv_data) { for (int j = 0; j < MAX_GEM_SOCKETS; ++j) { - if(i==j) // skip self + if(i == j) // skip self continue; if (Gems[j]) @@ -1267,7 +1268,7 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recv_data) // for equipped item check all equipment for duplicate equipped gems if(itemTarget->IsEquipped()) { - if(uint8 res = _player->CanEquipUniqueItem(Gems[i],slot,limit_newcount >= 0 ? limit_newcount : 0)) + if(uint8 res = _player->CanEquipUniqueItem(Gems[i], slot, limit_newcount >= 0 ? limit_newcount : 0)) { _player->SendEquipError( res, itemTarget, NULL ); return; @@ -1281,32 +1282,32 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recv_data) //if a meta gem is being equipped, all information has to be written to the item before testing if the conditions for the gem are met //remove ALL enchants - for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot) - _player->ApplyEnchantment(itemTarget,EnchantmentSlot(enchant_slot),false); + for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT + MAX_GEM_SOCKETS; ++enchant_slot) + _player->ApplyEnchantment(itemTarget, EnchantmentSlot(enchant_slot), false); for(int i = 0; i < MAX_GEM_SOCKETS; ++i) { if(GemEnchants[i]) { - itemTarget->SetEnchantment(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+i), GemEnchants[i],0,0); + itemTarget->SetEnchantment(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT + i), GemEnchants[i], 0, 0); if(Item* guidItem = _player->GetItemByGuid(gem_guids[i])) _player->DestroyItem(guidItem->GetBagSlot(), guidItem->GetSlot(), true ); } } - for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot) - _player->ApplyEnchantment(itemTarget,EnchantmentSlot(enchant_slot),true); + for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT + MAX_GEM_SOCKETS; ++enchant_slot) + _player->ApplyEnchantment(itemTarget, EnchantmentSlot(enchant_slot), true); - bool SocketBonusToBeActivated = itemTarget->GemsFitSockets();//current socketbonus state - if(SocketBonusActivated != SocketBonusToBeActivated) //if there was a change... + bool SocketBonusToBeActivated = itemTarget->GemsFitSockets();// current socketbonus state + if(SocketBonusActivated != SocketBonusToBeActivated) // if there was a change... { - _player->ApplyEnchantment(itemTarget,BONUS_ENCHANTMENT_SLOT,false); + _player->ApplyEnchantment(itemTarget,BONUS_ENCHANTMENT_SLOT, false); itemTarget->SetEnchantment(BONUS_ENCHANTMENT_SLOT, (SocketBonusToBeActivated ? itemTarget->GetProto()->socketBonus : 0), 0, 0); - _player->ApplyEnchantment(itemTarget,BONUS_ENCHANTMENT_SLOT,true); + _player->ApplyEnchantment(itemTarget, BONUS_ENCHANTMENT_SLOT, true); //it is not displayed, client has an inbuilt system to determine if the bonus is activated } - _player->ToggleMetaGemsActive(slot, true); //turn on all metagems (except for target item) + _player->ToggleMetaGemsActive(slot, true); // turn on all metagems (except for target item) } void WorldSession::HandleCancelTempEnchantmentOpcode(WorldPacket& recv_data) @@ -1318,7 +1319,7 @@ void WorldSession::HandleCancelTempEnchantmentOpcode(WorldPacket& recv_data) recv_data >> eslot; // apply only to equipped item - if(!Player::IsEquipmentPos(INVENTORY_SLOT_BAG_0,eslot)) + if(!Player::IsEquipmentPos(INVENTORY_SLOT_BAG_0, eslot)) return; Item* item = GetPlayer()->GetItemByPos(INVENTORY_SLOT_BAG_0, eslot); @@ -1329,6 +1330,30 @@ void WorldSession::HandleCancelTempEnchantmentOpcode(WorldPacket& recv_data) if(!item->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT)) return; - GetPlayer()->ApplyEnchantment(item,TEMP_ENCHANTMENT_SLOT,false); + GetPlayer()->ApplyEnchantment(item, TEMP_ENCHANTMENT_SLOT, false); item->ClearEnchantment(TEMP_ENCHANTMENT_SLOT); } + +void WorldSession::HandleItemRefundInfoRequest(WorldPacket& recv_data) +{ + sLog.outDebug("WORLD: CMSG_ITEM_REFUND_INFO_REQUEST"); + + uint64 guid; + recv_data >> guid; // item guid + + Item *item = _player->GetItemByGuid(guid); + + if(!item) + { + sLog.outDebug("Item refund: item not found!"); + return; + } + + if(!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE)) + { + sLog.outDebug("Item refund: item not refundable!"); + return; + } + + // item refund system not implemented yet +} diff --git a/src/game/ItemPrototype.h b/src/game/ItemPrototype.h index af7c29e1a..cae4fd3f5 100644 --- a/src/game/ItemPrototype.h +++ b/src/game/ItemPrototype.h @@ -63,10 +63,13 @@ enum ItemModType ITEM_MOD_SPELL_DAMAGE_DONE = 42, // deprecated ITEM_MOD_MANA_REGENERATION = 43, ITEM_MOD_ARMOR_PENETRATION_RATING = 44, - ITEM_MOD_SPELL_POWER = 45 + ITEM_MOD_SPELL_POWER = 45, + ITEM_MOD_HEALTH_REGEN = 46, + ITEM_MOD_SPELL_PENETRATION = 47, + ITEM_MOD_BLOCK_VALUE = 48 }; -#define MAX_ITEM_MOD 46 +#define MAX_ITEM_MOD 49 enum ItemSpelltriggerType { @@ -106,16 +109,22 @@ enum ITEM_FLAGS ITEM_FLAGS_OPENABLE = 0x00000004, ITEM_FLAGS_WRAPPED = 0x00000008, ITEM_FLAGS_BROKEN = 0x00000010, // appears red icon (like when item durability==0) + ITEM_FLAGS_TOTEM = 0x00000020, // ? + ITEM_FLAGS_USABLE = 0x00000040, // ? ITEM_FLAGS_WRAPPER = 0x00000200, // used or not used wrapper ITEM_FLAGS_PARTY_LOOT = 0x00000800, // determines if item is party loot or not + ITEM_FLAGS_REFUNDABLE = 0x00001000, // item cost can be refunded within 2 hours after purchase ITEM_FLAGS_CHARTER = 0x00002000, // arena/guild charter + ITEM_FLAGS_REFUNDABLE_2 = 0x00008000, ITEM_FLAGS_PROSPECTABLE = 0x00040000, ITEM_FLAGS_UNIQUE_EQUIPPED = 0x00080000, ITEM_FLAGS_USEABLE_IN_ARENA = 0x00200000, ITEM_FLAGS_THROWABLE = 0x00400000, // not used in game for check trow possibility, only for item in game tooltip ITEM_FLAGS_SPECIALUSE = 0x00800000, // last used flag in 2.3.0 ITEM_FLAGS_BOA = 0x08000000, // bind on account (set in template for items that can binded in like way) - ITEM_FLAGS_MILLABLE = 0x20000000 + ITEM_FLAGS_ENCHANT_SCROLL = 0x10000000, // for enchant scrolls + ITEM_FLAGS_MILLABLE = 0x20000000, + ITEM_FLAGS_BOP_TRADEABLE = 0x80000000 }; enum BAG_FAMILY_MASK @@ -508,6 +517,7 @@ struct ItemPrototype uint32 DisplayInfoID; // id from ItemDisplayInfo.dbc uint32 Quality; uint32 Flags; + uint32 Faction; uint32 BuyCount; uint32 BuyPrice; uint32 SellPrice; diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp index ceff91a76..e65542d3e 100644 --- a/src/game/Level1.cpp +++ b/src/game/Level1.cpp @@ -537,19 +537,22 @@ bool ChatHandler::HandleGonameCommand(const char* args) // if the player or the player's group is bound to another instance // the player will not be bound to another one - InstancePlayerBind *pBind = _player->GetBoundInstance(target->GetMapId(), target->GetDifficulty()); + InstancePlayerBind *pBind = _player->GetBoundInstance(target->GetMapId(), target->GetDifficulty(cMap->IsRaid())); if (!pBind) { Group *group = _player->GetGroup(); // if no bind exists, create a solo bind - InstanceGroupBind *gBind = group ? group->GetBoundInstance(target->GetMapId(), target->GetDifficulty()) : NULL; + InstanceGroupBind *gBind = group ? group->GetBoundInstance(target) : NULL; // if no bind exists, create a solo bind if (!gBind) if (InstanceSave *save = sInstanceSaveManager.GetInstanceSave(target->GetInstanceId())) _player->BindToInstance(save, !save->CanReset()); } - _player->SetDifficulty(target->GetDifficulty()); + if(cMap->IsRaid()) + _player->SetRaidDifficulty(target->GetRaidDifficulty()); + else + _player->SetDungeonDifficulty(target->GetDungeonDifficulty()); } PSendSysMessage(LANG_APPEARING_AT, chrNameLink.c_str()); diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 9e526da8a..623f70631 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -5912,14 +5912,14 @@ bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/) Player* player = getSelectedPlayer(); if (!player) player = m_session->GetPlayer(); uint32 counter = 0; - for(uint8 i = 0; i < TOTAL_DIFFICULTIES; ++i) + for(uint8 i = 0; i < MAX_DIFFICULTY; ++i) { - Player::BoundInstancesMap &binds = player->GetBoundInstances(i); + Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i)); for(Player::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr) { InstanceSave *save = itr->second.save; std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); - PSendSysMessage("map: %d inst: %d perm: %s diff: %s canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty() == DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str()); + PSendSysMessage("map: %d inst: %d perm: %s diff: %s canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty() == DUNGEON_DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str()); counter++; } } @@ -5928,14 +5928,14 @@ bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/) Group *group = player->GetGroup(); if(group) { - for(uint8 i = 0; i < TOTAL_DIFFICULTIES; ++i) + for(uint8 i = 0; i < MAX_DIFFICULTY; ++i) { - Group::BoundInstancesMap &binds = group->GetBoundInstances(i); + Group::BoundInstancesMap &binds = group->GetBoundInstances(Difficulty(i)); for(Group::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr) { InstanceSave *save = itr->second.save; std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); - PSendSysMessage("map: %d inst: %d perm: %s diff: %s canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty() == DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str()); + PSendSysMessage("map: %d inst: %d perm: %s diff: %s canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty() == DUNGEON_DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str()); counter++; } } @@ -5956,17 +5956,17 @@ bool ChatHandler::HandleInstanceUnbindCommand(const char* args) Player* player = getSelectedPlayer(); if (!player) player = m_session->GetPlayer(); uint32 counter = 0; - for(uint8 i = 0; i < TOTAL_DIFFICULTIES; ++i) + for(uint8 i = 0; i < MAX_DIFFICULTY; ++i) { - Player::BoundInstancesMap &binds = player->GetBoundInstances(i); + Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i)); for(Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();) { if(itr->first != player->GetMapId()) { InstanceSave *save = itr->second.save; std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); - PSendSysMessage("unbinding map: %d inst: %d perm: %s diff: %s canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty() == DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str()); - player->UnbindInstance(itr, i); + PSendSysMessage("unbinding map: %d inst: %d perm: %s diff: %s canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty() == DUNGEON_DIFFICULTY_NORMAL ? "normal" : "heroic", save->CanReset() ? "yes" : "no", timeleft.c_str()); + player->UnbindInstance(itr, Difficulty(i)); counter++; } else diff --git a/src/game/LootHandler.cpp b/src/game/LootHandler.cpp index 76008c6e9..67cb4dc59 100644 --- a/src/game/LootHandler.cpp +++ b/src/game/LootHandler.cpp @@ -489,7 +489,7 @@ void WorldSession::HandleLootMasterGiveOpcode( WorldPacket & recv_data ) return; } - // not move item from loot to target inventory + // now move item from loot to target inventory Item * newitem = target->StoreNewItem( dest, item.itemid, true, item.randomPropertyId ); target->SendNewItem(newitem, uint32(item.count), false, false, true ); target->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item.itemid, item.count); @@ -499,7 +499,6 @@ void WorldSession::HandleLootMasterGiveOpcode( WorldPacket & recv_data ) item.count=0; item.is_looted=true; - pLoot->NotifyItemRemoved(slotid); --pLoot->unlootedCount; } diff --git a/src/game/Mail.cpp b/src/game/Mail.cpp index bf7b14ee1..98b85dbbd 100644 --- a/src/game/Mail.cpp +++ b/src/game/Mail.cpp @@ -46,7 +46,7 @@ void MailItem::deleteItem( bool inDB ) CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid='%u'", item->GetGUIDLow()); delete item; - item=NULL; + item = NULL; } } @@ -123,7 +123,7 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data ) return; } - uint32 cost = items_count ? 30 * items_count : 30; // price hardcoded in client + uint32 cost = items_count ? 30 * items_count : 30; // price hardcoded in client uint32 reqmoney = cost + money; @@ -136,7 +136,7 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data ) Player *receive = objmgr.GetPlayer(rc); uint32 rc_team = 0; - uint8 mails_count = 0; //do not allow to send to one player more than 100 mails + uint8 mails_count = 0; // do not allow to send to one player more than 100 mails if(receive) { @@ -154,13 +154,15 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data ) delete result; } } + //do not allow to have more than 100 mails in mailbox.. mails count is in opcode uint8!!! - so max can be 255.. if (mails_count > 100) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_CAP_REACHED); return; } - // test the receiver's Faction... + + // check the receiver's Faction... if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL) && pl->GetTeam() != rc_team && GetSecurity() == SEC_PLAYER) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_YOUR_TEAM); @@ -251,7 +253,7 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data ) pl->MoveItemFromInventory(mailItem.item->GetBagSlot(), mailItem.item->GetSlot(), true); CharacterDatabase.BeginTransaction(); - mailItem.item->DeleteFromInventoryDB(); //deletes item from character's inventory + mailItem.item->DeleteFromInventoryDB(); // deletes item from character's inventory mailItem.item->SaveToDB(); // recursive and not have transaction guard into self, item not in inventory and can be save standalone // owner in data will set at mail receive and item extracting CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'", GUID_LOPART(rc), mailItem.item->GetGUIDLow()); @@ -298,7 +300,7 @@ void WorldSession::HandleMailMarkAsRead(WorldPacket & recv_data ) if (pl->unReadMails) --pl->unReadMails; m->checked = m->checked | MAIL_CHECK_MASK_READ; - // m->expire_time = time(NULL) + (30 * DAY); // Expire time do not change at reading mail + // m->expire_time = time(NULL) + (30 * DAY); // Expire time do not change at reading mail pl->m_mailsUpdated = true; m->state = MAIL_STATE_CHANGED; } @@ -378,7 +380,7 @@ void WorldSession::HandleMailReturnToSender(WorldPacket & recv_data ) SendReturnToSender(MAIL_NORMAL, GetAccountId(), m->receiver, m->sender, m->subject, m->itemTextId, &mi, m->money, m->mailTemplateId); - delete m; //we can deallocate old mail + delete m; // we can deallocate old mail pl->SendMailResult(mailId, MAIL_RETURNED_TO_SENDER, MAIL_OK); } @@ -415,7 +417,7 @@ void WorldSession::SendReturnToSender(uint8 messageType, uint32 sender_acc, uint for(MailItemMap::iterator mailItemIter = mi->begin(); mailItemIter != mi->end(); ++mailItemIter) { MailItem& mailItem = mailItemIter->second; - mailItem.item->SaveToDB(); // item not in inventory and can be save standalone + mailItem.item->SaveToDB(); // item not in inventory and can be save standalone // owner in data will set at mail receive and item extracting CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'", receiver_guid, mailItem.item->GetGUIDLow()); } @@ -426,7 +428,7 @@ void WorldSession::SendReturnToSender(uint8 messageType, uint32 sender_acc, uint uint32 deliver_delay = needItemDelay ? sWorld.getConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0; // will delete item or place to receiver mail list - WorldSession::SendMailTo(receiver, MAIL_NORMAL, MAIL_STATIONERY_NORMAL, sender_guid, receiver_guid, subject, itemTextId, mi, money, 0, MAIL_CHECK_MASK_RETURNED,deliver_delay,mailTemplateId); + WorldSession::SendMailTo(receiver, MAIL_NORMAL, MAIL_STATIONERY_NORMAL, sender_guid, receiver_guid, subject, itemTextId, mi, money, 0, MAIL_CHECK_MASK_RETURNED, deliver_delay, mailTemplateId); } //called when player takes item attached in mail @@ -467,7 +469,7 @@ void WorldSession::HandleMailTakeItem(WorldPacket & recv_data ) m->RemoveItem(itemId); m->removedItems.push_back(itemId); - if (m->COD > 0) //if there is COD, take COD money from player and send them to sender by mail + if (m->COD > 0) // if there is COD, take COD money from player and send them to sender by mail { uint64 sender_guid = MAKE_NEW_GUID(m->sender, 0, HIGHGUID_PLAYER); Player *receive = objmgr.GetPlayer(sender_guid); @@ -487,11 +489,11 @@ void WorldSession::HandleMailTakeItem(WorldPacket & recv_data ) // can be calculated early sender_accId = objmgr.GetPlayerAccountIdByGUID(sender_guid); - if(!objmgr.GetPlayerNameByGUID(sender_guid,sender_name)) + if(!objmgr.GetPlayerNameByGUID(sender_guid, sender_name)) sender_name = objmgr.GetMangosStringForDBCLocale(LANG_UNKNOWN); } - sLog.outCommand(GetAccountId(),"GM %s (Account: %u) receive mail item: %s (Entry: %u Count: %u) and send COD money: %u to player: %s (Account: %u)", - GetPlayerName(),GetAccountId(),it->GetProto()->Name1,it->GetEntry(),it->GetCount(),m->COD,sender_name.c_str(),sender_accId); + sLog.outCommand(GetAccountId(), "GM %s (Account: %u) receive mail item: %s (Entry: %u Count: %u) and send COD money: %u to player: %s (Account: %u)", + GetPlayerName(), GetAccountId(), it->GetProto()->Name1, it->GetEntry(), it->GetCount(), m->COD, sender_name.c_str(), sender_accId); } else if(!receive) sender_accId = objmgr.GetPlayerAccountIdByGUID(sender_guid); @@ -510,7 +512,7 @@ void WorldSession::HandleMailTakeItem(WorldPacket & recv_data ) pl->RemoveMItem(it->GetGUIDLow()); uint32 count = it->GetCount(); // save counts before store and possible merge with deleting - pl->MoveItemToInventory(dest,it,true); + pl->MoveItemToInventory(dest, it, true); CharacterDatabase.BeginTransaction(); pl->SaveInventoryAndGoldToDB(); @@ -565,22 +567,22 @@ void WorldSession::HandleGetMailList(WorldPacket & recv_data ) if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) return; - Player* pl = _player; - - //load players mails, and mailed items - if(!pl->m_mailsLoaded) - pl ->_LoadMail(); + // load players mails, and mailed items + if(!_player->m_mailsLoaded) + _player->_LoadMail(); // client can't work with packets > max int16 value const uint32 maxPacketSize = 32767; - uint32 mails_count = 0; // real send to client mails amount + uint32 mailsCount = 0; // send to client mails amount + uint32 realCount = 0; // real mails amount - WorldPacket data(SMSG_MAIL_LIST_RESULT, (200)); // guess size + WorldPacket data(SMSG_MAIL_LIST_RESULT, 200); // guess size + data << uint32(0); // real mail's count data << uint8(0); // mail's count time_t cur_time = time(NULL); - for(PlayerMails::iterator itr = pl->GetmailBegin(); itr != pl->GetmailEnd(); ++itr) + for(PlayerMails::iterator itr = _player->GetMailBegin(); itr != _player->GetMailEnd(); ++itr) { // skip deleted or not delivered (deliver delay not expired) mails if ((*itr)->state == MAIL_STATE_DELETED || cur_time < (*itr)->deliver_time) @@ -591,7 +593,10 @@ void WorldSession::HandleGetMailList(WorldPacket & recv_data ) size_t next_mail_size = 2+4+1+8+4*8+((*itr)->subject.size()+1)+1+item_count*(1+4+4+6*3*4+4+4+1+4+4+4); if(data.wpos()+next_mail_size > maxPacketSize) - break; + { + realCount += 1; + continue; + } uint32 show_flags = 0; if ((*itr)->messageType != MAIL_NORMAL) @@ -601,9 +606,9 @@ void WorldSession::HandleGetMailList(WorldPacket & recv_data ) if ((*itr)->HasItems() && (*itr)->messageType == MAIL_NORMAL) show_flags |= MAIL_SHOW_RETURN; - data << (uint16) 0x0040; // unknown 2.3.0, different values - data << (uint32) (*itr)->messageID; // Message ID - data << (uint8) (*itr)->messageType; // Message Type + data << uint16(0x0040); // unknown 2.3.0, different values + data << uint32((*itr)->messageID); // Message ID + data << uint8((*itr)->messageType); // Message Type switch((*itr)->messageType) { @@ -613,63 +618,65 @@ void WorldSession::HandleGetMailList(WorldPacket & recv_data ) case MAIL_CREATURE: case MAIL_GAMEOBJECT: case MAIL_AUCTION: - data << (uint32) (*itr)->sender; // creature/gameobject entry, auction id + data << uint32((*itr)->sender); // creature/gameobject entry, auction id break; case MAIL_ITEM: // item entry (?) sender = "Unknown", NYI + data << uint32(0); // item entry break; } - data << (uint32) (*itr)->COD; // COD - data << (uint32) (*itr)->itemTextId; // sure about this - data << (uint32) 0; // unknown - data << (uint32) (*itr)->stationery; // stationery (Stationery.dbc) - data << (uint32) (*itr)->money; // Gold - data << (uint32) show_flags; // unknown, 0x4 - auction, 0x10 - normal - // Time - data << (float) ((*itr)->expire_time-time(NULL))/DAY; - data << (uint32) (*itr)->mailTemplateId; // mail template (MailTemplate.dbc) + data << uint32((*itr)->COD); // COD + data << uint32((*itr)->itemTextId); // sure about this + data << uint32(0); // unknown + data << uint32((*itr)->stationery); // stationery (Stationery.dbc) + data << uint32((*itr)->money); // Gold + data << uint32(show_flags); // unknown, 0x4 - auction, 0x10 - normal + data << float(((*itr)->expire_time-time(NULL))/DAY);// Time + data << uint32((*itr)->mailTemplateId); // mail template (MailTemplate.dbc) data << (*itr)->subject; // Subject string - once 00, when mail type = 3 - data << (uint8) item_count; // client limit is 0x10 + data << uint8(item_count); // client limit is 0x10 for(uint8 i = 0; i < item_count; ++i) { - Item *item = pl->GetMItem((*itr)->items[i].item_guid); + Item *item = _player->GetMItem((*itr)->items[i].item_guid); // item index (0-6?) - data << (uint8) i; + data << uint8(i); // item guid low? - data << (uint32) (item ? item->GetGUIDLow() : 0); + data << uint32(item ? item->GetGUIDLow() : 0); // entry - data << (uint32) (item ? item->GetEntry() : 0); + data << uint32(item ? item->GetEntry() : 0); for(uint8 j = 0; j < MAX_INSPECTED_ENCHANTMENT_SLOT; ++j) { // unsure - data << (uint32) (item ? item->GetEnchantmentCharges((EnchantmentSlot)j) : 0); + data << uint32(item ? item->GetEnchantmentCharges((EnchantmentSlot)j) : 0); // unsure - data << (uint32) (item ? item->GetEnchantmentDuration((EnchantmentSlot)j) : 0); + data << uint32(item ? item->GetEnchantmentDuration((EnchantmentSlot)j) : 0); // unsure - data << (uint32) (item ? item->GetEnchantmentId((EnchantmentSlot)j) : 0); + data << uint32(item ? item->GetEnchantmentId((EnchantmentSlot)j) : 0); } // can be negative - data << (uint32) (item ? item->GetItemRandomPropertyId() : 0); + data << uint32(item ? item->GetItemRandomPropertyId() : 0); // unk - data << (uint32) (item ? item->GetItemSuffixFactor() : 0); + data << uint32(item ? item->GetItemSuffixFactor() : 0); // stack count - data << (uint32) (item ? item->GetCount() : 0); + data << uint32(item ? item->GetCount() : 0); // charges - data << (uint32) (item ? item->GetSpellCharges() : 0); + data << uint32(item ? item->GetSpellCharges() : 0); // durability - data << (uint32) (item ? item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY) : 0); + data << uint32(item ? item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY) : 0); // durability - data << (uint32) (item ? item->GetUInt32Value(ITEM_FIELD_DURABILITY) : 0); + data << uint32(item ? item->GetUInt32Value(ITEM_FIELD_DURABILITY) : 0); // unknown wotlk - data << (uint8) 0; + data << uint8(0); } - mails_count += 1; + mailsCount += 1; + realCount += 1; } - data.put(0, mails_count); // set real send mails to client + data.put(0, realCount); // this will display warning about undelivered mail to player if realCount > mailsCount + data.put(4, mailsCount); // set real send mails to client SendPacket(&data); // recalculate m_nextMailDelivereTime and unReadMails @@ -680,8 +687,8 @@ void WorldSession::HandleGetMailList(WorldPacket & recv_data ) void WorldSession::HandleItemTextQuery(WorldPacket & recv_data ) { uint32 itemTextId; - uint32 mailId; //this value can be item id in bag, but it is also mail id - uint32 unk; //maybe something like state - 0x70000000 + uint32 mailId; // this value can be item id in bag, but it is also mail id + uint32 unk; // maybe something like state - 0x70000000 recv_data >> itemTextId >> mailId >> unk; @@ -722,7 +729,7 @@ void WorldSession::HandleMailCreateTextItem(WorldPacket & recv_data ) return; } - bodyItem->SetUInt32Value( ITEM_FIELD_ITEM_TEXT_ID , m->itemTextId ); + bodyItem->SetUInt32Value( ITEM_FIELD_ITEM_TEXT_ID, m->itemTextId ); bodyItem->SetUInt32Value( ITEM_FIELD_CREATOR, m->sender); sLog.outDetail("HandleMailCreateTextItem mailid=%u",mailId); @@ -756,12 +763,12 @@ void WorldSession::HandleQueryNextMailTime(WorldPacket & /*recv_data*/ ) if( _player->unReadMails > 0 ) { - data << (uint32) 0; // float - data << (uint32) 0; // count + data << uint32(0); // float + data << uint32(0); // count uint32 count = 0; time_t now = time(NULL); - for(PlayerMails::iterator itr = _player->GetmailBegin(); itr != _player->GetmailEnd(); ++itr) + for(PlayerMails::iterator itr = _player->GetMailBegin(); itr != _player->GetMailEnd(); ++itr) { Mail *m = (*itr); // must be not checked yet @@ -772,22 +779,23 @@ void WorldSession::HandleQueryNextMailTime(WorldPacket & /*recv_data*/ ) if(now < m->deliver_time) continue; - data << (uint64) m->sender; // sender guid + data << uint64(m->sender); // sender guid switch(m->messageType) { case MAIL_AUCTION: - data << (uint32) 2; - data << (uint32) 2; - data << (uint32) m->stationery; + data << uint32(2); + data << uint32(2); + data << uint32(m->stationery); break; default: - data << (uint32) 0; - data << (uint32) 0; - data << (uint32) m->stationery; + data << uint32(0); + data << uint32(0); + data << uint32(m->stationery); break; } - data << (uint32) 0xC6000000; // float unk, time or something + + data << uint32(0xC6000000); // float unk, time or something ++count; if(count == 2) // do not display more than 2 mails @@ -797,8 +805,8 @@ void WorldSession::HandleQueryNextMailTime(WorldPacket & /*recv_data*/ ) } else { - data << (uint32) 0xC7A8C000; - data << (uint32) 0x00000000; + data << uint32(0xC7A8C000); + data << uint32(0x00000000); } SendPacket(&data); } @@ -809,12 +817,12 @@ void WorldSession::SendMailTo(Player* receiver, uint8 messageType, uint8 station time_t deliver_time = time(NULL) + deliver_delay; - //expire time if COD 3 days, if no COD 30 days, if auction sale pending 1 hour + // expire time if COD 3 days, if no COD 30 days, if auction sale pending 1 hour uint32 expire_delay; if(messageType == MAIL_AUCTION && !mi && !money) // auction mail without any items and money expire_delay = HOUR; else - expire_delay = (COD > 0) ? 3*DAY : 30*DAY; + expire_delay = (COD > 0) ? 3 * DAY : 30 * DAY; time_t expire_time = deliver_time + expire_delay; @@ -830,7 +838,7 @@ void WorldSession::SendMailTo(Player* receiver, uint8 messageType, uint8 station if ( receiver->IsMailsLoaded() ) { - Mail * m = new Mail; + Mail *m = new Mail; m->messageID = mailId; m->messageType = messageType; m->stationery = stationery; @@ -850,7 +858,7 @@ void WorldSession::SendMailTo(Player* receiver, uint8 messageType, uint8 station m->checked = checked; m->state = MAIL_STATE_UNCHANGED; - receiver->AddMail(m); //to insert new mail to beginning of maillist + receiver->AddMail(m); // to insert new mail to beginning of maillist if(mi) { @@ -879,7 +887,7 @@ void WorldSession::SendMailTo(Player* receiver, uint8 messageType, uint8 station for(MailItemMap::const_iterator mailItemIter = mi->begin(); mailItemIter != mi->end(); ++mailItemIter) { MailItem const& mailItem = mailItemIter->second; - CharacterDatabase.PExecute("INSERT INTO mail_items (mail_id,item_guid,item_template,receiver) VALUES ('%u', '%u', '%u','%u')", mailId, mailItem.item_guidlow, mailItem.item_template,receiver_guidlow); + CharacterDatabase.PExecute("INSERT INTO mail_items (mail_id,item_guid,item_template,receiver) VALUES ('%u', '%u', '%u','%u')", mailId, mailItem.item_guidlow, mailItem.item_template, receiver_guidlow); } } CharacterDatabase.CommitTransaction(); diff --git a/src/game/Makefile.am b/src/game/Makefile.am index b06ebbee6..2feb09216 100644 --- a/src/game/Makefile.am +++ b/src/game/Makefile.am @@ -46,10 +46,12 @@ libmangosgame_a_SOURCES = \ BattleGround.cpp \ BattleGroundAA.cpp \ BattleGroundAB.cpp \ + BattleGroundABG.cpp \ BattleGroundAV.cpp \ BattleGroundBE.cpp \ BattleGroundDS.cpp \ BattleGroundEY.cpp \ + BattleGroundIC.cpp \ BattleGroundNA.cpp \ BattleGroundRL.cpp \ BattleGroundRV.cpp \ @@ -58,10 +60,12 @@ libmangosgame_a_SOURCES = \ BattleGround.h \ BattleGroundAA.h \ BattleGroundAB.h \ + BattleGroundABG.h \ BattleGroundAV.h \ BattleGroundBE.h \ BattleGroundDS.h \ BattleGroundEY.h \ + BattleGroundIC.h \ BattleGroundNA.h \ BattleGroundRL.h \ BattleGroundRV.h \ diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 95d9b8791..7e4fdfba9 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -2334,11 +2334,11 @@ bool InstanceMap::Add(Player *player) if(!mapSave) { sLog.outDetail("InstanceMap::Add: creating instance save for map %d spawnmode %d with instance id %d", GetId(), GetSpawnMode(), GetInstanceId()); - mapSave = sInstanceSaveManager.AddInstanceSave(GetId(), GetInstanceId(), GetSpawnMode(), 0, true); + mapSave = sInstanceSaveManager.AddInstanceSave(GetId(), GetInstanceId(), Difficulty(GetSpawnMode()), 0, true); } // check for existing instance binds - InstancePlayerBind *playerBind = player->GetBoundInstance(GetId(), GetSpawnMode()); + InstancePlayerBind *playerBind = player->GetBoundInstance(GetId(), Difficulty(GetSpawnMode())); if(playerBind && playerBind->perm) { // cannot enter other instances if bound permanently @@ -2354,7 +2354,7 @@ bool InstanceMap::Add(Player *player) if(pGroup) { // solo saves should be reset when entering a group - InstanceGroupBind *groupBind = pGroup->GetBoundInstance(GetId(), GetSpawnMode()); + InstanceGroupBind *groupBind = pGroup->GetBoundInstance(this); if(playerBind) { sLog.outError("InstanceMap::Add: player %s(%d) is being put in instance %d,%d,%d,%d,%d,%d but he is in group %d and is bound to instance %d,%d,%d,%d,%d,%d!", player->GetName(), player->GetGUIDLow(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset(), GUID_LOPART(pGroup->GetLeaderGUID()), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset()); @@ -2573,7 +2573,7 @@ void InstanceMap::UnloadAll(bool pForce) void InstanceMap::SendResetWarnings(uint32 timeLeft) const { for(MapRefManager::const_iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr) - itr->getSource()->SendInstanceResetWarning(GetId(), itr->getSource()->GetDifficulty(), timeLeft); + itr->getSource()->SendInstanceResetWarning(GetId(), itr->getSource()->GetDifficulty(IsRaid()), timeLeft); } void InstanceMap::SetResetSchedule(bool on) @@ -2600,7 +2600,7 @@ uint32 InstanceMap::GetMaxPlayers() const /* ******* Battleground Instance Maps ******* */ BattleGroundMap::BattleGroundMap(uint32 id, time_t expiry, uint32 InstanceId, Map* _parent) - : Map(id, expiry, InstanceId, DIFFICULTY_NORMAL, _parent) + : Map(id, expiry, InstanceId, DUNGEON_DIFFICULTY_NORMAL, _parent) { //lets initialize visibility distance for BG/Arenas BattleGroundMap::InitVisibilityDistance(); diff --git a/src/game/Map.h b/src/game/Map.h index 26cb5722f..6fe6fdf3b 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -365,7 +365,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj // NOTE: this duplicate of Instanceable(), but Instanceable() can be changed when BG also will be instanceable bool IsDungeon() const { return i_mapEntry && i_mapEntry->IsDungeon(); } bool IsRaid() const { return i_mapEntry && i_mapEntry->IsRaid(); } - bool IsHeroic() const { return i_spawnMode == DIFFICULTY_HEROIC; } + bool IsHeroic() const { return IsRaid() ? i_spawnMode >= RAID_DIFFICULTY_10MAN_HEROIC : i_spawnMode >= DUNGEON_DIFFICULTY_HEROIC; } bool IsBattleGround() const { return i_mapEntry && i_mapEntry->IsBattleGround(); } bool IsBattleArena() const { return i_mapEntry && i_mapEntry->IsBattleArena(); } bool IsBattleGroundOrArena() const { return i_mapEntry && i_mapEntry->IsBattleGroundOrArena(); } diff --git a/src/game/MapInstanced.cpp b/src/game/MapInstanced.cpp index 7cc88e87e..0aa985ffe 100644 --- a/src/game/MapInstanced.cpp +++ b/src/game/MapInstanced.cpp @@ -139,7 +139,7 @@ Map* MapInstanced::CreateInstance(const uint32 mapId, Player * player) } else { - InstancePlayerBind *pBind = player->GetBoundInstance(GetId(), player->GetDifficulty()); + InstancePlayerBind *pBind = player->GetBoundInstance(GetId(), player->GetDifficulty(IsRaid())); InstanceSave *pSave = pBind ? pBind->save : NULL; // the player's permanent player bind is taken into consideration first @@ -149,7 +149,7 @@ Map* MapInstanced::CreateInstance(const uint32 mapId, Player * player) 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->GetDifficulty()))) + if(group && (groupBind = group->GetBoundInstance(this))) pSave = groupBind->save; } @@ -167,14 +167,14 @@ Map* MapInstanced::CreateInstance(const uint32 mapId, Player * player) // 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->GetDifficulty()); + map = CreateInstance(NewInstanceId, NULL, player->GetDifficulty(IsRaid())); } } return map; } -InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave *save, uint8 difficulty) +InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave *save, Difficulty difficulty) { // load/create a map Guard guard(*this); @@ -194,7 +194,9 @@ InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave *save, } // some instances only have one difficulty - if (entry && !entry->SupportsHeroicMode()) difficulty = DIFFICULTY_NORMAL; + MapDifficulty const* mapDiff = GetMapDifficultyData(GetId(),difficulty); + if (!mapDiff) + difficulty = DUNGEON_DIFFICULTY_NORMAL; sLog.outDebug("MapInstanced::CreateInstance: %s map instance %d for %d created with difficulty %s", save?"":"new ", InstanceId, GetId(), difficulty?"heroic":"normal"); diff --git a/src/game/MapInstanced.h b/src/game/MapInstanced.h index 5e8183bac..baa78eeb6 100644 --- a/src/game/MapInstanced.h +++ b/src/game/MapInstanced.h @@ -61,7 +61,7 @@ class MANGOS_DLL_DECL MapInstanced : public Map private: - InstanceMap* CreateInstance(uint32 InstanceId, InstanceSave *save, uint8 difficulty); + InstanceMap* CreateInstance(uint32 InstanceId, InstanceSave *save, Difficulty difficulty); BattleGroundMap* CreateBattleGroundMap(uint32 InstanceId, BattleGround* bg); InstancedMaps m_InstancedMaps; diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp index 6afd379e4..624e3b884 100644 --- a/src/game/MapManager.cpp +++ b/src/game/MapManager.cpp @@ -182,10 +182,16 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player) } //The player has a heroic mode and tries to enter into instance which has no a heroic mode - if (!entry->SupportsHeroicMode() && player->GetDifficulty() == DIFFICULTY_HEROIC) + MapDifficulty const* mapDiff = GetMapDifficultyData(entry->MapID,player->GetDifficulty(entry->map_type == MAP_RAID)); + if (!mapDiff) { + bool isHeroicTargetMap = entry->map_type == MAP_RAID + ? (player->GetRaidDifficulty() >= RAID_DIFFICULTY_10MAN_HEROIC) + : (player->GetDungeonDifficulty() >= DUNGEON_DIFFICULTY_HEROIC); + //Send aborted message - player->SendTransferAborted(mapid, TRANSFER_ABORT_DIFFICULTY, DIFFICULTY_HEROIC); + // FIX ME: what about absent normal/heroic mode with specific players limit... + player->SendTransferAborted(mapid, TRANSFER_ABORT_DIFFICULTY, isHeroicTargetMap ? DUNGEON_DIFFICULTY_HEROIC : DUNGEON_DIFFICULTY_NORMAL); return false; } diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp index 954d79a1c..776277d2a 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -46,7 +46,7 @@ void WorldSession::HandleRepopRequestOpcode( WorldPacket & recv_data ) recv_data.read_skip(); - if(GetPlayer()->isAlive()||GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) + if(GetPlayer()->isAlive() || GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) return; // the world update order is sessions, players, creatures @@ -247,8 +247,8 @@ void WorldSession::HandleWhoOpcode( WorldPacket & recv_data ) break; } - data.put( 0, clientcount ); //insert right count - data.put( sizeof(uint32), clientcount ); //insert right count + data.put( 0, clientcount ); // insert right count + data.put( sizeof(uint32), clientcount ); // insert right count SendPacket(&data); sLog.outDebug( "WORLD: Send SMSG_WHO Message" ); @@ -373,8 +373,8 @@ void WorldSession::HandleZoneUpdateOpcode( WorldPacket & recv_data ) // use server size data uint32 newzone, newarea; - GetPlayer()->GetZoneAndAreaId(newzone,newarea); - GetPlayer()->UpdateZone(newzone,newarea); + GetPlayer()->GetZoneAndAreaId(newzone, newarea); + GetPlayer()->UpdateZone(newzone, newarea); } void WorldSession::HandleSetTargetOpcode( WorldPacket & recv_data ) @@ -383,7 +383,7 @@ void WorldSession::HandleSetTargetOpcode( WorldPacket & recv_data ) uint64 guid ; recv_data >> guid; - _player->SetUInt32Value(UNIT_FIELD_TARGET,guid); + _player->SetTargetGUID(guid); // update reputation list if need Unit* unit = ObjectAccessor::GetUnit(*_player, guid ); @@ -546,7 +546,7 @@ void WorldSession::HandleAddIgnoreOpcodeCallBack(QueryResult *result, uint32 acc FriendsResult ignoreResult = FRIEND_IGNORE_NOT_FOUND; if(IgnoreGuid) { - if(IgnoreGuid==session->GetPlayer()->GetGUID()) //not add yourself + if(IgnoreGuid == session->GetPlayer()->GetGUID()) //not add yourself ignoreResult = FRIEND_IGNORE_SELF; else if( session->GetPlayer()->GetSocial()->HasIgnore(GUID_LOPART(IgnoreGuid)) ) ignoreResult = FRIEND_IGNORE_ALREADY; @@ -591,10 +591,8 @@ void WorldSession::HandleSetContactNotesOpcode( WorldPacket & recv_data ) void WorldSession::HandleBugOpcode( WorldPacket & recv_data ) { - uint32 suggestion, contentlen; - std::string content; - uint32 typelen; - std::string type; + uint32 suggestion, contentlen, typelen; + std::string content, type; recv_data >> suggestion >> contentlen >> content; @@ -683,22 +681,22 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data) uint32 Trigger_ID; recv_data >> Trigger_ID; - sLog.outDebug("Trigger ID:%u",Trigger_ID); + sLog.outDebug("Trigger ID: %u", Trigger_ID); if(GetPlayer()->isInFlight()) { - sLog.outDebug("Player '%s' (GUID: %u) in flight, ignore Area Trigger ID:%u",GetPlayer()->GetName(),GetPlayer()->GetGUIDLow(), Trigger_ID); + sLog.outDebug("Player '%s' (GUID: %u) in flight, ignore Area Trigger ID: %u", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), Trigger_ID); return; } AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(Trigger_ID); if(!atEntry) { - sLog.outDebug("Player '%s' (GUID: %u) send unknown (by DBC) Area Trigger ID:%u",GetPlayer()->GetName(),GetPlayer()->GetGUIDLow(), Trigger_ID); + sLog.outDebug("Player '%s' (GUID: %u) send unknown (by DBC) Area Trigger ID: %u", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), Trigger_ID); return; } - if (GetPlayer()->GetMapId()!=atEntry->mapid) + if (GetPlayer()->GetMapId() != atEntry->mapid) { sLog.outDebug("Player '%s' (GUID: %u) too far (trigger map: %u player map: %u), ignore Area Trigger ID: %u", GetPlayer()->GetName(), atEntry->mapid, GetPlayer()->GetMapId(), GetPlayer()->GetGUIDLow(), Trigger_ID); return; @@ -712,7 +710,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data) if (atEntry->radius > 0) { // if we have radius check it - float dist = pl->GetDistance(atEntry->x,atEntry->y,atEntry->z); + float dist = pl->GetDistance(atEntry->x, atEntry->y, atEntry->z); if(dist > atEntry->radius + delta) { sLog.outDebug("Player '%s' (GUID: %u) too far (radius: %f distance: %f), ignore Area Trigger ID: %u", @@ -811,8 +809,16 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data) else if(at->requiredItem2 && !GetPlayer()->HasItemCount(at->requiredItem2, 1)) missingItem = at->requiredItem2; + MapEntry const* mapEntry = sMapStore.LookupEntry(at->target_mapId); + if(!mapEntry) + return; + + bool isHeroicTargetMap = mapEntry->IsRaid() + ? (GetPlayer()->GetRaidDifficulty() >= RAID_DIFFICULTY_10MAN_HEROIC) + : (GetPlayer()->GetDungeonDifficulty() >= DUNGEON_DIFFICULTY_HEROIC); + uint32 missingKey = 0; - if(GetPlayer()->GetDifficulty() == DIFFICULTY_HEROIC) + if(isHeroicTargetMap) { if(at->heroicKey) { @@ -825,7 +831,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data) } uint32 missingQuest = 0; - if(GetPlayer()->GetDifficulty() == DIFFICULTY_HEROIC) + if(isHeroicTargetMap) { if (at->requiredQuestHeroic && !GetPlayer()->GetQuestRewardStatus(at->requiredQuestHeroic)) missingQuest = at->requiredQuestHeroic; @@ -842,7 +848,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data) if(missingItem) SendAreaTriggerMessage(GetMangosString(LANG_LEVEL_MINREQUIRED_AND_ITEM), at->requiredLevel, objmgr.GetItemPrototype(missingItem)->Name1); else if(missingKey) - GetPlayer()->SendTransferAborted(at->target_mapId, TRANSFER_ABORT_DIFFICULTY, DIFFICULTY_HEROIC); + GetPlayer()->SendTransferAborted(at->target_mapId, TRANSFER_ABORT_DIFFICULTY, isHeroicTargetMap ? DUNGEON_DIFFICULTY_HEROIC : DUNGEON_DIFFICULTY_NORMAL); else if(missingQuest) SendAreaTriggerMessage(at->requiredFailedText.c_str()); else if(missingLevel) @@ -851,7 +857,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data) } } - GetPlayer()->TeleportTo(at->target_mapId,at->target_X,at->target_Y,at->target_Z,at->target_Orientation,TELE_TO_NOT_LEAVE_TRANSPORT); + GetPlayer()->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, at->target_Orientation, TELE_TO_NOT_LEAVE_TRANSPORT); } void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data) @@ -891,7 +897,7 @@ void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data) uLongf realSize = decompressedSize; if(uncompress(const_cast(dest.contents()), &realSize, const_cast(recv_data.contents() + recv_data.rpos()), recv_data.size() - recv_data.rpos()) != Z_OK) { - recv_data.rpos(recv_data.wpos()); // unnneded warning spam in this case + recv_data.rpos(recv_data.wpos()); // unneded warning spam in this case sLog.outError("UAD: Failed to decompress account data"); return; } @@ -938,8 +944,8 @@ void WorldSession::HandleRequestAccountData(WorldPacket& recv_data) dest.resize(destSize); - WorldPacket data (SMSG_UPDATE_ACCOUNT_DATA, 8+4+4+4+destSize); - data << uint64(_player->GetGUID()); // player guid + WorldPacket data(SMSG_UPDATE_ACCOUNT_DATA, 8+4+4+4+destSize); + data << uint64(_player ? _player->GetGUID() : 0); // player guid data << uint32(type); // type (0-7) data << uint32(adata->Time); // unix time data << uint32(size); // decompressed length @@ -984,7 +990,7 @@ void WorldSession::HandleSetActionButtonOpcode(WorldPacket& recv_data) sLog.outError( "MISC: Unknown action button type %u for action %u into button %u", type, action, button ); return; } - GetPlayer()->addActionButton(button,action,type); + GetPlayer()->addActionButton(button, action, type); } } @@ -1003,7 +1009,12 @@ void WorldSession::HandleMoveTimeSkippedOpcode( WorldPacket & recv_data ) /* WorldSession::Update( getMSTime() );*/ DEBUG_LOG( "WORLD: Time Lag/Synchronization Resent/Update" ); - recv_data.read_skip(); + uint64 guid; + if(!recv_data.readPackGUID(guid)) + { + recv_data.rpos(recv_data.wpos()); + return; + } recv_data.read_skip(); /* uint64 guid; @@ -1081,8 +1092,8 @@ void WorldSession::HandleSetActionBarToggles(WorldPacket& recv_data) if(!GetPlayer()) // ignore until not logged (check needed because STATUS_AUTHED) { - if(ActionBar!=0) - sLog.outError("WorldSession::HandleSetActionBarToggles in not logged state with value: %u, ignored",uint32(ActionBar)); + if(ActionBar != 0) + sLog.outError("WorldSession::HandleSetActionBarToggles in not logged state with value: %u, ignored", uint32(ActionBar)); return; } @@ -1095,7 +1106,7 @@ void WorldSession::HandleWardenDataOpcode(WorldPacket& recv_data) /* uint8 tmp; recv_data >> tmp; - sLog.outDebug("Received opcode CMSG_WARDEN_DATA, not resolve.uint8 = %u",tmp); + sLog.outDebug("Received opcode CMSG_WARDEN_DATA, not resolve.uint8 = %u", tmp); */ } @@ -1195,7 +1206,7 @@ void WorldSession::HandleWorldTeleportOpcode(WorldPacket& recv_data) DEBUG_LOG("Time %u sec, map=%u, x=%f, y=%f, z=%f, orient=%f", time/1000, mapid, PositionX, PositionY, PositionZ, Orientation); if (GetSecurity() >= SEC_ADMINISTRATOR) - GetPlayer()->TeleportTo(mapid,PositionX,PositionY,PositionZ,Orientation); + GetPlayer()->TeleportTo(mapid, PositionX, PositionY, PositionZ, Orientation); else SendNotification(LANG_YOU_NOT_HAVE_PERMISSION); sLog.outDebug("Received worldport command from player %s", GetPlayer()->GetName()); @@ -1368,7 +1379,7 @@ void WorldSession::HandleTimeSyncResp( WorldPacket & recv_data ) recv_data >> counter >> time_; // time_ seems always more than getMSTime() - uint32 diff = getMSTimeDiff(getMSTime(),time_); + uint32 diff = getMSTimeDiff(getMSTime(), time_); sLog.outDebug("response sent: counter %u, time %u (HEX: %X), ms. time %u, diff %u", counter, time_, time_, getMSTime(), diff); } @@ -1376,14 +1387,20 @@ void WorldSession::HandleTimeSyncResp( WorldPacket & recv_data ) void WorldSession::HandleResetInstancesOpcode( WorldPacket & /*recv_data*/ ) { sLog.outDebug("WORLD: CMSG_RESET_INSTANCES"); - Group *pGroup = _player->GetGroup(); - if(pGroup) + + if(Group *pGroup = _player->GetGroup()) { if(pGroup->IsLeader(_player->GetGUID())) - pGroup->ResetInstances(INSTANCE_RESET_ALL, _player); + { + pGroup->ResetInstances(INSTANCE_RESET_ALL, false, _player); + pGroup->ResetInstances(INSTANCE_RESET_ALL, true,_player); + } } else - _player->ResetInstances(INSTANCE_RESET_ALL); + { + _player->ResetInstances(INSTANCE_RESET_ALL, false); + _player->ResetInstances(INSTANCE_RESET_ALL, true); + } } void WorldSession::HandleSetDungeonDifficultyOpcode( WorldPacket & recv_data ) @@ -1393,15 +1410,15 @@ void WorldSession::HandleSetDungeonDifficultyOpcode( WorldPacket & recv_data ) uint32 mode; recv_data >> mode; - if(mode == _player->GetDifficulty()) - return; - - if(mode > DIFFICULTY_HEROIC) + if(mode >= MAX_DUNGEON_DIFFICULTY) { sLog.outError("WorldSession::HandleSetDungeonDifficultyOpcode: player %d sent an invalid instance mode %d!", _player->GetGUIDLow(), mode); return; } + if(Difficulty(mode) == _player->GetDungeonDifficulty()) + return; + // cannot reset while in an instance Map *map = _player->GetMap(); if(map && map->IsDungeon()) @@ -1412,28 +1429,71 @@ void WorldSession::HandleSetDungeonDifficultyOpcode( WorldPacket & recv_data ) if(_player->getLevel() < LEVELREQUIREMENT_HEROIC) return; - Group *pGroup = _player->GetGroup(); - if(pGroup) + + if(Group *pGroup = _player->GetGroup()) { if(pGroup->IsLeader(_player->GetGUID())) { // the difficulty is set even if the instances can't be reset //_player->SendDungeonDifficulty(true); - pGroup->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, _player); - pGroup->SetDifficulty(mode); + pGroup->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, false, _player); + pGroup->SetDungeonDifficulty(Difficulty(mode)); } } else { - _player->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY); - _player->SetDifficulty(mode); + _player->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, false); + _player->SetDungeonDifficulty(Difficulty(mode)); + } +} + +void WorldSession::HandleSetRaidDifficultyOpcode( WorldPacket & recv_data ) +{ + sLog.outDebug("MSG_SET_RAID_DIFFICULTY"); + + uint32 mode; + recv_data >> mode; + + if(mode >= MAX_RAID_DIFFICULTY) + { + sLog.outError("WorldSession::HandleSetRaidDifficultyOpcode: player %d sent an invalid instance mode %d!", _player->GetGUIDLow(), mode); + return; + } + + if(RaidDifficulties(mode) == _player->GetRaidDifficulty()) + return; + + // cannot reset while in an instance + Map *map = _player->GetMap(); + if(map && map->IsDungeon()) + { + sLog.outError("WorldSession::HandleSetRaidDifficultyOpcode: player %d tried to reset the instance while inside!", _player->GetGUIDLow()); + return; + } + + if(_player->getLevel() < LEVELREQUIREMENT_HEROIC) + return; + + if(Group *pGroup = _player->GetGroup()) + { + if(pGroup->IsLeader(_player->GetGUID())) + { + // the difficulty is set even if the instances can't be reset + //_player->SendDungeonDifficulty(true); + pGroup->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, true, _player); + pGroup->SetRaidDifficulty(Difficulty(mode)); + } + } + else + { + _player->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, true); + _player->SetRaidDifficulty(Difficulty(mode)); } } void WorldSession::HandleCancelMountAuraOpcode( WorldPacket & /*recv_data*/ ) { sLog.outDebug("WORLD: CMSG_CANCEL_MOUNT_AURA"); - //recv_data.hexlike(); //If player is not mounted, so go out :) if (!_player->IsMounted()) // not blizz like; no any messages on blizz @@ -1491,9 +1551,16 @@ void WorldSession::HandleQueryInspectAchievements( WorldPacket & recv_data ) if(!recv_data.readPackGUID(guid)) return; - Player *player = objmgr.GetPlayer(guid); - if(!player) - return; - - player->GetAchievementMgr().SendRespondInspectAchievements(_player); + if(Player *player = objmgr.GetPlayer(guid)) + player->GetAchievementMgr().SendRespondInspectAchievements(_player); +} + +void WorldSession::HandleWorldStateUITimerUpdate(WorldPacket& recv_data) +{ + // empty opcode + sLog.outDebug("WORLD: CMSG_WORLD_STATE_UI_TIMER_UPDATE"); + + WorldPacket data(SMSG_WORLD_STATE_UI_TIMER_UPDATE, 4); + data << uint32(time(NULL)); + SendPacket(&data); } diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp index 369ef1eed..3d10973c6 100644 --- a/src/game/MovementHandler.cpp +++ b/src/game/MovementHandler.cpp @@ -137,10 +137,21 @@ void WorldSession::HandleMoveWorldportAckOpcode() } } - if((mEntry->IsRaid() || (mEntry->IsNonRaidDungeon() && mEntry->SupportsHeroicMode() && GetPlayer()->IsHeroic())) && mInstance) + if (mInstance) { - uint32 timeleft = sInstanceSaveManager.GetResetTimeFor(GetPlayer()->GetMapId()) - time(NULL); - GetPlayer()->SendInstanceResetWarning(GetPlayer()->GetMapId(), GetPlayer()->GetDifficulty(), timeleft); + if(mEntry->IsRaid()) + { + uint32 timeleft = sInstanceSaveManager.GetResetTimeFor(GetPlayer()->GetMapId()) - time(NULL); + GetPlayer()->SendInstanceResetWarning(GetPlayer()->GetMapId(), GetPlayer()->GetRaidDifficulty(), timeleft); + } + else if(mEntry->IsNonRaidDungeon() && GetPlayer()->GetDungeonDifficulty() > DUNGEON_DIFFICULTY_NORMAL) + { + if(MapDifficulty const* mapDiff = GetMapDifficultyData(mEntry->MapID,GetPlayer()->GetDungeonDifficulty())) + { + uint32 timeleft = sInstanceSaveManager.GetResetTimeFor(GetPlayer()->GetMapId()) - time(NULL); + GetPlayer()->SendInstanceResetWarning(GetPlayer()->GetMapId(), GetPlayer()->GetDungeonDifficulty(), timeleft); + } + } } // mount allow check @@ -162,9 +173,11 @@ void WorldSession::HandleMoveTeleportAck(WorldPacket& recv_data) { sLog.outDebug("MSG_MOVE_TELEPORT_ACK"); uint64 guid; - uint32 flags, time; - recv_data >> guid; + if(!recv_data.readPackGUID(guid)) + return; + + uint32 flags, time; recv_data >> flags >> time; DEBUG_LOG("Guid " UI64FMTD, guid); DEBUG_LOG("Flags %u, time %u", flags, time/IN_MILISECONDS); @@ -209,9 +222,10 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) { uint32 opcode = recv_data.GetOpcode(); sLog.outDebug("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(opcode), opcode, opcode); + recv_data.hexlike(); Unit *mover = _player->m_mover; - Player *plMover = mover->GetTypeId()==TYPEID_PLAYER ? (Player*)mover : NULL; + Player *plMover = mover->GetTypeId() == TYPEID_PLAYER ? (Player*)mover : NULL; // ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck if(plMover && plMover->IsBeingTeleported()) @@ -221,18 +235,17 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) } /* extract packet */ + uint64 guid; + + if(!recv_data.readPackGUID(guid)) + return; + MovementInfo movementInfo; + movementInfo.guid = guid; ReadMovementInfo(recv_data, &movementInfo); /*----------------*/ - if(recv_data.size() != recv_data.rpos()) - { - sLog.outError("MovementHandler: player %s (guid %d, account %u) sent a packet (opcode %u) that is " SIZEFMTD " bytes larger than it should be. Kicked as cheater.", _player->GetName(), _player->GetGUIDLow(), _player->GetSession()->GetAccountId(), recv_data.GetOpcode(), recv_data.size() - recv_data.rpos()); - KickPlayer(); recv_data.rpos(recv_data.wpos()); // prevent warnings spam - return; - } - if (!MaNGOS::IsValidMapCoord(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o)) { recv_data.rpos(recv_data.wpos()); // prevent warnings spam @@ -297,17 +310,17 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) /*----------------------*/ /* process position-change */ - recv_data.put(6, getMSTime()); // fix time, offset flags(4) + unk(2) - WorldPacket data(recv_data.GetOpcode(), (mover->GetPackGUID().size()+recv_data.size())); - data.append(mover->GetPackGUID()); // use mover guid - data.append(recv_data.contents(), recv_data.size()); + WorldPacket data(opcode, recv_data.size()); + movementInfo.time = getMSTime(); + movementInfo.guid = mover->GetGUID(); + WriteMovementInfo(&data, &movementInfo); GetPlayer()->SendMessageToSet(&data, false); if(plMover) // nothing is charmed, or player charmed { plMover->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); plMover->m_movementInfo = movementInfo; - plMover->UpdateFallInformationIfNeed(movementInfo, recv_data.GetOpcode()); + plMover->UpdateFallInformationIfNeed(movementInfo, opcode); if(plMover->isMovingOrTurning()) plMover->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); @@ -352,14 +365,15 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data) { - sLog.outDebug("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(recv_data.GetOpcode()), recv_data.GetOpcode(), recv_data.GetOpcode()); - + uint32 opcode = recv_data.GetOpcode(); + sLog.outDebug("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(opcode), opcode, opcode); /* extract packet */ uint64 guid; uint32 unk1; float newspeed; - recv_data >> guid; + if(!recv_data.readPackGUID(guid)) + return; // now can skip not our packet if(_player->GetGUID() != guid) @@ -369,10 +383,10 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data) } // continue parse packet - recv_data >> unk1; // counter or moveEvent MovementInfo movementInfo; + movementInfo.guid = guid; ReadMovementInfo(recv_data, &movementInfo); recv_data >> newspeed; @@ -385,7 +399,6 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data) static char const* move_type_name[MAX_MOVE_TYPE] = { "Walk", "Run", "RunBack", "Swim", "SwimBack", "TurnRate", "Flight", "FlightBack", "PitchRate" }; - uint16 opcode = recv_data.GetOpcode(); switch(opcode) { case CMSG_FORCE_WALK_SPEED_CHANGE_ACK: move_type = MOVE_WALK; force_move_type = MOVE_WALK; break; @@ -449,7 +462,9 @@ void WorldSession::HandleMoveNotActiveMover(WorldPacket &recv_data) recv_data.hexlike(); uint64 old_mover_guid; - recv_data >> old_mover_guid; + + if(!recv_data.readPackGUID(old_mover_guid)) + return; if(_player->m_mover->GetGUID() == old_mover_guid) { @@ -459,7 +474,9 @@ void WorldSession::HandleMoveNotActiveMover(WorldPacket &recv_data) } MovementInfo mi; + mi.guid = old_mover_guid; ReadMovementInfo(recv_data, &mi); + _player->m_movementInfo = mi; } @@ -476,8 +493,15 @@ void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data) return; } + uint64 guid; + + if(!recv_data.readPackGUID(guid)) + return; + MovementInfo mi; + mi.guid = guid; ReadMovementInfo(recv_data, &mi); + _player->m_movementInfo = mi; // using charm guid, because we don't have vehicle guid... @@ -502,7 +526,8 @@ void WorldSession::HandleMoveKnockBackAck( WorldPacket & recv_data ) { sLog.outDebug("CMSG_MOVE_KNOCK_BACK_ACK"); - recv_data.read_skip(); // guid + uint64 guid; + recv_data.readPackGUID(guid); recv_data.read_skip(); // unk MovementInfo movementInfo; @@ -513,7 +538,8 @@ void WorldSession::HandleMoveHoverAck( WorldPacket& recv_data ) { sLog.outDebug("CMSG_MOVE_HOVER_ACK"); - recv_data.read_skip(); // guid + uint64 guid; + recv_data.readPackGUID(guid); recv_data.read_skip(); // unk MovementInfo movementInfo; @@ -526,7 +552,8 @@ void WorldSession::HandleMoveWaterWalkAck(WorldPacket& recv_data) { sLog.outDebug("CMSG_MOVE_WATER_WALK_ACK"); - recv_data.read_skip(); // guid + uint64 guid; + recv_data.readPackGUID(guid); recv_data.read_skip(); // unk MovementInfo movementInfo; diff --git a/src/game/Object.cpp b/src/game/Object.cpp index ced58786f..222b8efad 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -177,7 +177,7 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) c if(isType(TYPEMASK_UNIT)) { - if(((Unit*)this)->getVictim()) + if(((Unit*)this)->GetTargetGUID()) flags |= UPDATEFLAG_HAS_TARGET; } } @@ -554,10 +554,7 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2 // 0x4 if(flags & UPDATEFLAG_HAS_TARGET) // packed guid (current target guid) { - if(Unit *victim = ((Unit*)this)->getVictim()) - data->append(victim->GetPackGUID()); - else - *data << uint8(0); + data->appendPackGUID(((Unit*)this)->GetTargetGUID()); } // 0x2 diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 72b9c5371..6791db917 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -1226,9 +1226,15 @@ void ObjectMgr::LoadGameobjects() continue; } + if(!gInfo->displayId) + { + sLog.outErrorDb("Gameobject (GUID: %u Entry %u GoType: %u) doesn't have displayId (%u), not loaded.", guid, entry, gInfo->type, gInfo->displayId); + continue; + } + if (gInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(gInfo->displayId)) { - sLog.outErrorDb("Gameobject (GUID: %u Entry %u GoType: %u) have invalid displayId (%u), not loaded.",guid, entry, gInfo->type, gInfo->displayId); + sLog.outErrorDb("Gameobject (GUID: %u Entry %u GoType: %u) have invalid displayId (%u), not loaded.", guid, entry, gInfo->type, gInfo->displayId); continue; } @@ -1246,9 +1252,9 @@ void ObjectMgr::LoadGameobjects() data.rotation3 = fields[10].GetFloat(); data.spawntimesecs = fields[11].GetInt32(); - if (data.spawntimesecs==0 && gInfo->IsDespawnAtAction()) + 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); + 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(); @@ -1256,7 +1262,7 @@ void ObjectMgr::LoadGameobjects() uint32 go_state = fields[13].GetUInt32(); if (go_state >= MAX_GO_STATE) { - sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) with invalid `state` (%u) value, skip",guid,data.id,go_state); + sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) with invalid `state` (%u) value, skip", guid, data.id, go_state); continue; } data.go_state = GOState(go_state); @@ -1268,29 +1274,29 @@ void ObjectMgr::LoadGameobjects() if (data.rotation2 < -1.0f || data.rotation2 > 1.0f) { - sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) with invalid rotation2 (%f) value, skip",guid,data.id,data.rotation2 ); + sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) with invalid rotation2 (%f) value, skip", guid, data.id, data.rotation2); continue; } if (data.rotation3 < -1.0f || data.rotation3 > 1.0f) { - sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) with invalid rotation3 (%f) value, skip",guid,data.id,data.rotation3 ); + sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) with invalid rotation3 (%f) value, skip", guid, data.id, data.rotation3); continue; } - if (!MapManager::IsValidMapCoord(data.mapid,data.posX,data.posY,data.posZ,data.orientation)) + if(!MapManager::IsValidMapCoord(data.mapid, data.posX, data.posY, data.posZ, data.orientation)) { - sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) with invalid coordinates, skip",guid,data.id ); + sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) with invalid coordinates, skip", guid, data.id); continue; } - if (data.phaseMask==0) + if(data.phaseMask == 0) { - sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) with `phaseMask`=0 (not visible for anyone), set to 1.",guid,data.id ); + sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) with `phaseMask`=0 (not visible for anyone), set to 1.", guid, data.id); data.phaseMask = 1; } - if (gameEvent==0 && PoolId==0) // if not this is to be managed by GameEvent System or Pool system + if (gameEvent == 0 && PoolId == 0) // if not this is to be managed by GameEvent System or Pool system AddGameobjectToGrid(guid, &data); ++count; @@ -1460,6 +1466,12 @@ bool ObjectMgr::GetPlayerNameByGUID(const uint64 &guid, std::string &name) const uint32 ObjectMgr::GetPlayerTeamByGUID(const uint64 &guid) const { + // prevent DB access for online player + if(Player* player = GetPlayer(guid)) + { + return Player::TeamForRace(player->getRace()); + } + QueryResult *result = CharacterDatabase.PQuery("SELECT race FROM characters WHERE guid = '%u'", GUID_LOPART(guid)); if(result) @@ -1474,6 +1486,12 @@ uint32 ObjectMgr::GetPlayerTeamByGUID(const uint64 &guid) const uint32 ObjectMgr::GetPlayerAccountIdByGUID(const uint64 &guid) const { + // prevent DB access for online player + if(Player* player = GetPlayer(guid)) + { + return player->GetSession()->GetAccountId(); + } + QueryResult *result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE guid = '%u'", GUID_LOPART(guid)); if(result) { @@ -2995,8 +3013,8 @@ void ObjectMgr::LoadGroups() Group *group = NULL; uint64 leaderGuid = 0; uint32 count = 0; - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - QueryResult *result = CharacterDatabase.Query("SELECT mainTank, mainAssistant, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8, isRaid, difficulty, leaderGuid FROM groups"); + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 + QueryResult *result = CharacterDatabase.Query("SELECT mainTank, mainAssistant, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8, isRaid, difficulty, raiddifficulty, leaderGuid FROM groups"); if( !result ) { @@ -3016,7 +3034,7 @@ void ObjectMgr::LoadGroups() bar.step(); Field *fields = result->Fetch(); ++count; - leaderGuid = MAKE_NEW_GUID(fields[15].GetUInt32(),0,HIGHGUID_PLAYER); + leaderGuid = MAKE_NEW_GUID(fields[16].GetUInt32(),0,HIGHGUID_PLAYER); group = new Group; if(!group->LoadGroupFromDB(leaderGuid, result, false)) @@ -3130,7 +3148,14 @@ void ObjectMgr::LoadGroups() continue; } - InstanceSave *save = sInstanceSaveManager.AddInstanceSave(mapEntry->MapID, fields[2].GetUInt32(), fields[4].GetUInt8(), (time_t)fields[5].GetUInt64(), (fields[6].GetUInt32() == 0), true); + uint32 diff = fields[4].GetUInt8(); + if(diff >= (mapEntry->IsRaid() ? MAX_RAID_DIFFICULTY : MAX_DUNGEON_DIFFICULTY)) + { + sLog.outErrorDb("Wrong dungeon difficulty use in group_instance table: %d", diff); + diff = 0; // default for both difficaly types + } + + InstanceSave *save = sInstanceSaveManager.AddInstanceSave(mapEntry->MapID, fields[2].GetUInt32(), Difficulty(diff), (time_t)fields[5].GetUInt64(), (fields[6].GetUInt32() == 0), true); group->BindToInstance(save, fields[3].GetBool(), true); }while( result->NextRow() ); delete result; @@ -4459,15 +4484,15 @@ void ObjectMgr::LoadInstanceTemplate() for(uint32 i = 0; i < sInstanceTemplate.MaxEntry; i++) { InstanceTemplate* temp = (InstanceTemplate*)GetInstanceTemplate(i); - if(!temp) continue; + if(!temp) + continue; + const MapEntry* entry = sMapStore.LookupEntry(temp->map); if(!entry) { sLog.outErrorDb("ObjectMgr::LoadInstanceTemplate: bad mapid %d for template!", temp->map); continue; } - else if(!entry->HasResetTime()) - continue; //FIXME: now exist heroic instance, normal/heroic raid instances // entry->resetTimeHeroic store reset time for both heroic mode instance (raid and non-raid) @@ -4476,15 +4501,23 @@ void ObjectMgr::LoadInstanceTemplate() // but at some point wee need implement reset time dependent from raid instance mode if(temp->reset_delay == 0) { + MapDifficulty const* mapDiffNorm = GetMapDifficultyData(temp->map,DUNGEON_DIFFICULTY_NORMAL); + MapDifficulty const* mapDiffHeroic = GetMapDifficultyData(temp->map,DUNGEON_DIFFICULTY_HEROIC); + + // no reset time + if ((!mapDiffNorm || mapDiffNorm->resetTime == 0) && + (!mapDiffHeroic || mapDiffHeroic->resetTime == 0)) + continue; + // use defaults from the DBC - if(entry->resetTimeHeroic) // for both raid and non raids, read above + if(mapDiffHeroic && mapDiffHeroic->resetTime) // for both raid and non raids, read above { - temp->reset_delay = entry->resetTimeHeroic / DAY; + temp->reset_delay = mapDiffHeroic->resetTime / DAY; } - else if (entry->resetTimeRaid && entry->map_type == MAP_RAID) + else if (mapDiffNorm && mapDiffNorm->resetTime && entry->map_type == MAP_RAID) // for normal raid only { - temp->reset_delay = entry->resetTimeRaid / DAY; + temp->reset_delay = mapDiffNorm->resetTime / DAY; } } diff --git a/src/game/Opcodes.cpp b/src/game/Opcodes.cpp index a79a5efad..78fbcef0a 100644 --- a/src/game/Opcodes.cpp +++ b/src/game/Opcodes.cpp @@ -345,7 +345,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x13C*/ { "SMSG_AI_REACTION", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x13D*/ { "CMSG_SET_SELECTION", STATUS_LOGGEDIN, &WorldSession::HandleSetSelectionOpcode }, /*0x13E*/ { "CMSG_EQUIPMENT_SET_DELETE", STATUS_LOGGEDIN, &WorldSession::HandleEquipmentSetDelete }, - /*0x13F*/ { "CMSG_INSTANCE_LOCK_RESPONSE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x13F*/ { "CMSG_INSTANCE_LOCK_WARNING_RESPONSE", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x140*/ { "CMSG_UNUSED2", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x141*/ { "CMSG_ATTACKSWING", STATUS_LOGGEDIN, &WorldSession::HandleAttackSwingOpcode }, /*0x142*/ { "CMSG_ATTACKSTOP", STATUS_LOGGEDIN, &WorldSession::HandleAttackStopOpcode }, @@ -353,7 +353,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x144*/ { "SMSG_ATTACKSTOP", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x145*/ { "SMSG_ATTACKSWING_NOTINRANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x146*/ { "SMSG_ATTACKSWING_BADFACING", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x147*/ { "SMSG_ATTACKSWING_NOTSTANDING", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x147*/ { "SMSG_INSTANCE_LOCK_WARNING_QUERY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x148*/ { "SMSG_ATTACKSWING_DEADTARGET", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x149*/ { "SMSG_ATTACKSWING_CANT_ATTACK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x14A*/ { "SMSG_ATTACKERSTATEUPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, @@ -548,8 +548,8 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x207*/ { "CMSG_GMTICKET_UPDATETEXT", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketUpdateTextOpcode }, /*0x208*/ { "SMSG_GMTICKET_UPDATETEXT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x209*/ { "SMSG_ACCOUNT_DATA_TIMES", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x20A*/ { "CMSG_REQUEST_ACCOUNT_DATA", STATUS_LOGGEDIN, &WorldSession::HandleRequestAccountData }, - /*0x20B*/ { "CMSG_UPDATE_ACCOUNT_DATA", STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT, &WorldSession::HandleUpdateAccountData}, + /*0x20A*/ { "CMSG_REQUEST_ACCOUNT_DATA", STATUS_AUTHED, &WorldSession::HandleRequestAccountData }, + /*0x20B*/ { "CMSG_UPDATE_ACCOUNT_DATA", STATUS_AUTHED, &WorldSession::HandleUpdateAccountData}, /*0x20C*/ { "SMSG_UPDATE_ACCOUNT_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x20D*/ { "SMSG_CLEAR_FAR_SIGHT_IMMEDIATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x20E*/ { "SMSG_POWERGAINLOG_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, @@ -684,8 +684,8 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x28F*/ { "CMSG_GROUP_ASSISTANT_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleGroupAssistantLeaderOpcode}, /*0x290*/ { "CMSG_BUYBACK_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleBuybackItem }, /*0x291*/ { "SMSG_SERVER_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x292*/ { "CMSG_MEETINGSTONE_JOIN", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x293*/ { "CMSG_MEETINGSTONE_LEAVE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x292*/ { "CMSG_SET_SAVED_INSTANCE_EXTEND", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x293*/ { "SMSG_MEETINGSTONE_LEAVE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x294*/ { "CMSG_MEETINGSTONE_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x295*/ { "SMSG_MEETINGSTONE_SETQUEUE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x296*/ { "CMSG_MEETINGSTONE_INFO", STATUS_LOGGEDIN, &WorldSession::HandleMeetingStoneInfo }, @@ -1067,7 +1067,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x40E*/ { "CMSG_REFER_A_FRIEND", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x40F*/ { "MSG_GM_CHANGE_ARENA_RATING", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x410*/ { "CMSG_DECLINE_CHANNEL_INVITE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x411*/ { "CMSG_GROUPACTION_THROTTLED", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x411*/ { "SMSG_GROUPACTION_THROTTLED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x412*/ { "SMSG_OVERRIDE_LIGHT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x413*/ { "SMSG_TOTEM_CREATED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x414*/ { "CMSG_TOTEM_DESTROYED", STATUS_LOGGEDIN, &WorldSession::HandleTotemDestroyed }, @@ -1229,11 +1229,11 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x4B0*/ { "UMSG_UNKNOWN_1200", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x4B1*/ { "UMSG_UNKNOWN_1201", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x4B2*/ { "SMSG_UNKNOWN_1202", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x4B3*/ { "UMSG_UNKNOWN_1203", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x4B4*/ { "UMSG_UNKNOWN_1204", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x4B3*/ { "CMSG_ITEM_REFUND_INFO_REQUEST", STATUS_LOGGEDIN, &WorldSession::HandleItemRefundInfoRequest }, + /*0x4B4*/ { "CMSG_UNKNOWN_1204", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x4B5*/ { "SMSG_UNKNOWN_1205", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x4B6*/ { "CMSG_UNKNOWN_1206", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x4B7*/ { "SMSG_UNKNOWN_1207", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4B6*/ { "CMSG_CORPSE_MAP_POSITION_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleCorpseMapPositionQuery }, + /*0x4B7*/ { "CMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x4B8*/ { "CMSG_LFG_SET_ROLES", STATUS_LOGGEDIN, &WorldSession::HandleLfgSetRoles }, /*0x4B9*/ { "UMSG_UNKNOWN_1209", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x4BA*/ { "CMSG_UNKNOWN_1210", STATUS_NEVER, &WorldSession::Handle_NULL }, @@ -1253,6 +1253,50 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x4C8*/ { "SMSG_UNKNOWN_1224", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x4C9*/ { "UMSG_UNKNOWN_1225", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x4CA*/ { "UMSG_UNKNOWN_1226", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x4CB*/ { "CMSG_EQUIPMENT_SET_USE", STATUS_LOGGEDIN, &WorldSession::HandleEquipmentSetUse }, - /*0x4CC*/ { "SMSG_EQUIPMENT_SET_USE_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4CB*/ { "UMSG_UNKNOWN_1227", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x4CC*/ { "UMSG_UNKNOWN_1228", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x4CD*/ { "SMSG_UNKNOWN_1229", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4CE*/ { "SMSG_UNKNOWN_1230", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4CF*/ { "CMSG_UNKNOWN_1231_ACK", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x4D0*/ { "SMSG_UNKNOWN_1232", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4D1*/ { "CMSG_UNKNOWN_1233_ACK", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x4D2*/ { "SMSG_UNKNOWN_1234", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4D3*/ { "SMSG_UNKNOWN_1235", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4D4*/ { "SMSG_UNKNOWN_1236", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4D5*/ { "CMSG_EQUIPMENT_SET_USE", STATUS_LOGGEDIN, &WorldSession::HandleEquipmentSetUse }, + /*0x4D6*/ { "SMSG_EQUIPMENT_SET_USE_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4D7*/ { "UMSG_UNKNOWN_1239", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x4D8*/ { "SMSG_UNKNOWN_1240", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4D9*/ { "CMSG_UNKNOWN_1241", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x4DA*/ { "SMSG_UNKNOWN_1242", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4DB*/ { "UMSG_UNKNOWN_1243", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x4DC*/ { "UMSG_UNKNOWN_1244", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x4DD*/ { "UMSG_UNKNOWN_1245", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x4DE*/ { "SMSG_UNKNOWN_1246", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4DF*/ { "CMSG_UNKNOWN_1247", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x4E0*/ { "SMSG_UNKNOWN_1248", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4E1*/ { "SMSG_UNKNOWN_1249", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4E2*/ { "CMSG_UNKNOWN_1250", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x4E3*/ { "CMSG_UNKNOWN_1251", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x4E4*/ { "SMSG_UNKNOWN_1252", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4E5*/ { "SMSG_UNKNOWN_1253", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4E6*/ { "SMSG_UNKNOWN_1254", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4E7*/ { "CMSG_UNKNOWN_1255", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x4E8*/ { "SMSG_UNKNOWN_1256", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4E9*/ { "UMSG_UNKNOWN_1257", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x4EA*/ { "UMSG_UNKNOWN_1258", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x4EB*/ { "MSG_SET_RAID_DIFFICULTY", STATUS_LOGGEDIN, &WorldSession::HandleSetRaidDifficultyOpcode }, + /*0x4EC*/ { "UMSG_UNKNOWN_1260", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x4ED*/ { "SMSG_TOGGLE_XP_GAIN", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4EE*/ { "SMSG_UNKNOWN_1262", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4EF*/ { "SMSG_UNKNOWN_1263", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4F0*/ { "CMSG_UNKNOWN_1264", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x4F1*/ { "SMSG_UNKNOWN_1265", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4F2*/ { "UMSG_UNKNOWN_1266", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x4F3*/ { "UMSG_UNKNOWN_1267", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x4F4*/ { "UMSG_UNKNOWN_1268", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x4F5*/ { "UMSG_UNKNOWN_1269", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x4F6*/ { "CMSG_WORLD_STATE_UI_TIMER_UPDATE", STATUS_LOGGEDIN, &WorldSession::HandleWorldStateUITimerUpdate }, + /*0x4F7*/ { "SMSG_WORLD_STATE_UI_TIMER_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4F8*/ { "CMSG_UNKNOWN_1272", STATUS_NEVER, &WorldSession::Handle_NULL }, }; diff --git a/src/game/Opcodes.h b/src/game/Opcodes.h index 7e5f9707c..66b52fa54 100644 --- a/src/game/Opcodes.h +++ b/src/game/Opcodes.h @@ -353,7 +353,7 @@ enum Opcodes SMSG_AI_REACTION = 0x13C, CMSG_SET_SELECTION = 0x13D, CMSG_EQUIPMENT_SET_DELETE = 0x13E, - CMSG_INSTANCE_LOCK_RESPONSE = 0x13F, + CMSG_INSTANCE_LOCK_WARNING_RESPONSE = 0x13F, CMSG_UNUSED2 = 0x140, CMSG_ATTACKSWING = 0x141, CMSG_ATTACKSTOP = 0x142, @@ -361,7 +361,7 @@ enum Opcodes SMSG_ATTACKSTOP = 0x144, SMSG_ATTACKSWING_NOTINRANGE = 0x145, SMSG_ATTACKSWING_BADFACING = 0x146, - SMSG_INSTANCE_LOCK_QUERY = 0x147, + SMSG_INSTANCE_LOCK_WARNING_QUERY = 0x147, SMSG_ATTACKSWING_DEADTARGET = 0x148, SMSG_ATTACKSWING_CANT_ATTACK = 0x149, SMSG_ATTACKERSTATEUPDATE = 0x14A, @@ -517,8 +517,8 @@ enum Opcodes CMSG_SETSHEATHED = 0x1E0, SMSG_COOLDOWN_CHEAT = 0x1E1, SMSG_SPELL_DELAYED = 0x1E2, - CMSG_PLAYER_MACRO_OBSOLETE = 0x1E3, - SMSG_PLAYER_MACRO_OBSOLETE = 0x1E4, + CMSG_QUEST_POI_QUERY = 0x1E3, + SMSG_QUEST_POI_QUERY_RESPONSE = 0x1E4, CMSG_GHOST = 0x1E5, CMSG_GM_INVIS = 0x1E6, SMSG_INVALID_PROMOTION_CODE = 0x1E7, @@ -692,7 +692,7 @@ enum Opcodes CMSG_GROUP_ASSISTANT_LEADER = 0x28F, CMSG_BUYBACK_ITEM = 0x290, SMSG_SERVER_MESSAGE = 0x291, - CMSG_MEETINGSTONE_JOIN = 0x292, // lua: SetSavedInstanceExtend + CMSG_SET_SAVED_INSTANCE_EXTEND = 0x292, // lua: SetSavedInstanceExtend SMSG_MEETINGSTONE_LEAVE = 0x293, CMSG_MEETINGSTONE_CHEAT = 0x294, SMSG_MEETINGSTONE_SETQUEUE = 0x295, @@ -1075,7 +1075,7 @@ enum Opcodes CMSG_REFER_A_FRIEND = 0x40E, MSG_GM_CHANGE_ARENA_RATING = 0x40F, CMSG_DECLINE_CHANNEL_INVITE = 0x410, - CMSG_GROUPACTION_THROTTLED = 0x411, + SMSG_GROUPACTION_THROTTLED = 0x411, // SMSG? SMSG_OVERRIDE_LIGHT = 0x412, SMSG_TOTEM_CREATED = 0x413, CMSG_TOTEM_DESTROYED = 0x414, @@ -1224,7 +1224,7 @@ enum Opcodes SMSG_SERVER_BUCK_DATA_START = 0x4A3, // not found CMSG_QUERY_VEHICLE_STATUS = 0x4A4, // not found UMSG_UNKNOWN_1189 = 0x4A5, // not found, old SMSG_PET_GUIDS - SMSG_UNKNOWN_1190 = 0x4A6, // smsg unk, old SMSG_CLIENTCACHE_VERSION + SMSG_UNKNOWN_1190 = 0x4A6, // smsg unk, "You can't do that yet" SMSG_UNKNOWN_1191 = 0x4A7, // smsg guid+uint32 (vehicle) CMSG_UNKNOWN_1192 = 0x4A8, // cmsg uint64 CMSG_EJECT_PASSENGER = 0x4A9, // cmsg uint64 @@ -1237,11 +1237,11 @@ enum Opcodes UMSG_UNKNOWN_1200 = 0x4B0, // not found UMSG_UNKNOWN_1201 = 0x4B1, // not found SMSG_UNKNOWN_1202 = 0x4B2, // refund something - CMSG_UNKNOWN_1203 = 0x4B3, // refund request? + CMSG_ITEM_REFUND_INFO_REQUEST = 0x4B3, // refund request? CMSG_UNKNOWN_1204 = 0x4B4, // lua: ContainerRefundItemPurchase SMSG_UNKNOWN_1205 = 0x4B5, // refund something - CMSG_UNKNOWN_1206 = 0x4B6, // CMSG, uint32 - SMSG_UNKNOWN_1207 = 0x4B7, // SMSG, string+float + CMSG_CORPSE_MAP_POSITION_QUERY = 0x4B6, // CMSG, uint32 + CMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE = 0x4B7, // SMSG, 3*float+float CMSG_LFG_SET_ROLES = 0x4B8, // CMSG, empty, lua: SetLFGRoles UMSG_UNKNOWN_1209 = 0x4B9, // not found CMSG_UNKNOWN_1210 = 0x4BA, // CMSG, uint64, lua: CalendarContextEventSignUp @@ -1253,17 +1253,61 @@ enum Opcodes SMSG_TALENTS_INFO = 0x4C0, // SMSG, talents related CMSG_LEARN_PREVIEW_TALENTS = 0x4C1, // CMSG, lua: LearnPreviewTalents (for player?) CMSG_LEARN_PREVIEW_TALENTS_PET = 0x4C2, // CMSG, lua: LearnPreviewTalents (for pet?) - UMSG_UNKNOWN_1219 = 0x4C3, // not found - UMSG_UNKNOWN_1220 = 0x4C4, // not found - UMSG_UNKNOWN_1221 = 0x4C5, // not found - UMSG_UNKNOWN_1222 = 0x4C6, // not found - SMSG_UNKNOWN_1223 = 0x4C7, // uint64, arena pet? - SMSG_UNKNOWN_1224 = 0x4C8, // uint32 "Can't change arena team..." - UMSG_UNKNOWN_1225 = 0x4C9, // not found - UMSG_UNKNOWN_1226 = 0x4CA, // not found - CMSG_EQUIPMENT_SET_USE = 0x4CB, // CMSG, lua: UseEquipmentSet - SMSG_EQUIPMENT_SET_USE_RESULT = 0x4CC, // SMSG, UseEquipmentSetResult? - NUM_MSG_TYPES = 0x4CD + UMSG_UNKNOWN_1219 = 0x4C3, // not found 3.2 + UMSG_UNKNOWN_1220 = 0x4C4, // not found 3.2 + UMSG_UNKNOWN_1221 = 0x4C5, // not found 3.2 + UMSG_UNKNOWN_1222 = 0x4C6, // not found 3.2 + SMSG_UNKNOWN_1223 = 0x4C7, // uint64, arena pet? 3.2 + SMSG_UNKNOWN_1224 = 0x4C8, // uint32 "Can't modify arena team while queued or in a match." 3.2 + UMSG_UNKNOWN_1225 = 0x4C9, // not found 3.2 + UMSG_UNKNOWN_1226 = 0x4CA, // not found 3.2 + UMSG_UNKNOWN_1227 = 0x4CB, // not found 3.2 + UMSG_UNKNOWN_1228 = 0x4CC, // not found 3.2 + SMSG_UNKNOWN_1229 = 0x4CD, // SMSG, any opcode? + SMSG_UNKNOWN_1230 = 0x4CE, // SMSG, movement related + CMSG_UNKNOWN_1231_ACK = 0x4CF, // movement related + SMSG_UNKNOWN_1232 = 0x4D0, // SMSG, movement related + CMSG_UNKNOWN_1233_ACK = 0x4D1, // movement related + SMSG_UNKNOWN_1234 = 0x4D2, // SMSG, movement related + SMSG_UNKNOWN_1235 = 0x4D3, // SMSG, movement related + SMSG_UNKNOWN_1236 = 0x4D4, // SMSG, movement related + CMSG_EQUIPMENT_SET_USE = 0x4D5, // CMSG, lua: UseEquipmentSet + SMSG_EQUIPMENT_SET_USE_RESULT = 0x4D6, // SMSG, UseEquipmentSetResult? + UMSG_UNKNOWN_1239 = 0x4D7, // not found 3.2 + SMSG_UNKNOWN_1240 = 0x4D8, // SMSG, uint64, string + CMSG_CHAR_FACTION_CHANGE = 0x4D9, // lua: CreateCharacter (PFC client response) + SMSG_CHAR_FACTION_CHANGE = 0x4DA, // response to 1241 (PFC server response) + UMSG_UNKNOWN_1243 = 0x4DB, // not found 3.2 + UMSG_UNKNOWN_1244 = 0x4DC, // not found 3.2 + UMSG_UNKNOWN_1245 = 0x4DD, // not found 3.2 + SMSG_UNKNOWN_1246 = 0x4DE, // uint32, BattlefieldMgrEntryInvite + CMSG_UNKNOWN_1247 = 0x4DF, // lua: BattlefieldMgrEntryInviteResponse + SMSG_UNKNOWN_1248 = 0x4E0, // uint32, uint8, uint8 + SMSG_UNKNOWN_1249 = 0x4E1, // uint32 BattlefieldMgrQueueInvite + CMSG_UNKNOWN_1250 = 0x4E2, // lua: BattlefieldMgrQueueInviteResponse + CMSG_UNKNOWN_1251 = 0x4E3, // lua: BattlefieldMgrQueueRequest + SMSG_UNKNOWN_1252 = 0x4E4, // uint32, uint8 queue full/can't join + SMSG_UNKNOWN_1253 = 0x4E5, // uint32 wintergrasp is full, you'll be ejected soon + SMSG_UNKNOWN_1254 = 0x4E6, // uint32, uint32, uint8 + CMSG_UNKNOWN_1255 = 0x4E7, // lua: BattlefieldMgrExitRequest + SMSG_UNKNOWN_1256 = 0x4E8, // uint32, uint32 + UMSG_UNKNOWN_1257 = 0x4E9, // not found 3.2 + UMSG_UNKNOWN_1258 = 0x4EA, // not found 3.2 + MSG_SET_RAID_DIFFICULTY = 0x4EB, // lua: SetRaidDifficulty + UMSG_UNKNOWN_1260 = 0x4EC, // not found 3.2 + SMSG_TOGGLE_XP_GAIN = 0x4ED, // enable/disable XP gain console message + SMSG_UNKNOWN_1262 = 0x4EE, + SMSG_UNKNOWN_1263 = 0x4EF, + CMSG_UNKNOWN_1264 = 0x4F0, // lua: GMResponseResolve + SMSG_UNKNOWN_1265 = 0x4F1, + UMSG_UNKNOWN_1266 = 0x4F2, // not found 3.2 + UMSG_UNKNOWN_1267 = 0x4F3, // not found 3.2 + UMSG_UNKNOWN_1268 = 0x4F4, // not found 3.2 + UMSG_UNKNOWN_1269 = 0x4F5, // not found 3.2 + CMSG_WORLD_STATE_UI_TIMER_UPDATE = 0x4F6, + SMSG_WORLD_STATE_UI_TIMER_UPDATE = 0x4F7, + CMSG_UNKNOWN_1272 = 0x4F8, // called from lua: CreateCharacter, paid race change + NUM_MSG_TYPES = 0x4F9 }; /// Player state diff --git a/src/game/PetitionsHandler.cpp b/src/game/PetitionsHandler.cpp index a4a1201cd..4deaf34d6 100644 --- a/src/game/PetitionsHandler.cpp +++ b/src/game/PetitionsHandler.cpp @@ -48,30 +48,35 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recv_data) { sLog.outDebug("Received opcode CMSG_PETITION_BUY"); - //recv_data.hexlike(); + recv_data.hexlike(); uint64 guidNPC; - uint64 unk1, unk3, unk4, unk5, unk6, unk7; - uint32 unk2; + uint32 clientIndex; // 1 for guild and arenaslot+1 for arenas in client std::string name; - uint16 unk8; - uint8 unk9; - uint32 unk10; // selected index - uint32 unk11; - recv_data >> guidNPC; // NPC GUID - recv_data >> unk1; // 0 - recv_data >> unk2; // 0 - recv_data >> name; // name - recv_data >> unk3; // 0 - recv_data >> unk4; // 0 - recv_data >> unk5; // 0 - recv_data >> unk6; // 0 - recv_data >> unk7; // 0 - recv_data >> unk8; // 0 - recv_data >> unk9; // 0 - recv_data >> unk10; // index - recv_data >> unk11; // 0 + recv_data >> guidNPC; // NPC GUID + recv_data.read_skip(); // 0 + recv_data.read_skip(); // 0 + recv_data >> name; // name + recv_data.read_skip(); // some string + recv_data.read_skip(); // 0 + recv_data.read_skip(); // 0 + recv_data.read_skip(); // 0 + recv_data.read_skip(); // 0 + recv_data.read_skip(); // 0 + recv_data.read_skip(); // 0 + recv_data.read_skip(); // 0 + recv_data.read_skip(); // 0 + recv_data.read_skip(); // 0 + recv_data.read_skip(); // 0 + recv_data.read_skip(); // 0 + + for (int i = 0; i < 10; ++i) + recv_data.read_skip(); + + recv_data >> clientIndex; // index + recv_data.read_skip(); // 0 + sLog.outDebug("Petitioner with GUID %u tried sell petition: name %s", GUID_LOPART(guidNPC), name.c_str()); // prevent cheating @@ -109,7 +114,7 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recv_data) return; } - switch(unk10) + switch(clientIndex) // arenaSlot+1 as received from client (1 from 3 case) { case 1: charterid = ARENA_TEAM_CHARTER_2v2; @@ -127,11 +132,11 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recv_data) type = 5; // 5v5 break; default: - sLog.outDebug("unknown selection at buy petition: %u", unk10); + sLog.outDebug("unknown selection at buy arena petition: %u", clientIndex); return; } - if(_player->GetArenaTeamId(unk10-1)) + if(_player->GetArenaTeamId(clientIndex - 1)) // arenaSlot+1 as received from client { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ALREADY_IN_ARENA_TEAM); return; @@ -206,7 +211,6 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recv_data) if (result) { - do { Field *fields = result->Fetch(); @@ -326,11 +330,11 @@ void WorldSession::SendPetitionQueryOpcode(uint64 petitionguid) return; } - WorldPacket data(SMSG_PETITION_QUERY_RESPONSE, (4+8+name.size()+1+1+4*13)); - data << GUID_LOPART(petitionguid); // guild/team guid (in mangos always same as GUID_LOPART(petition guid) - data << ownerguid; // charter owner guid + WorldPacket data(SMSG_PETITION_QUERY_RESPONSE, (4+8+name.size()+1+1+4*12+2+10)); + data << uint32(GUID_LOPART(petitionguid)); // guild/team guid (in mangos always same as GUID_LOPART(petition guid) + data << uint64(ownerguid); // charter owner guid data << name; // name (guild/arena team) - data << uint8(0); // 1 + data << uint8(0); // some string if(type == 9) { data << uint32(9); @@ -339,9 +343,9 @@ void WorldSession::SendPetitionQueryOpcode(uint64 petitionguid) } else { - data << type-1; - data << type-1; - data << type; // bypass client - side limitation, a different value is needed here for each petition + data << uint32(type-1); + data << uint32(type-1); + data << uint32(type); // bypass client - side limitation, a different value is needed here for each petition } data << uint32(0); // 5 data << uint32(0); // 6 @@ -351,11 +355,17 @@ void WorldSession::SendPetitionQueryOpcode(uint64 petitionguid) data << uint32(0); // 10 data << uint32(0); // 11 data << uint32(0); // 13 count of next strings? + + for(int i = 0; i < 10; ++i) + data << uint8(0); // some string + data << uint32(0); // 14 + if(type == 9) data << uint32(0); // 15 0 - guild, 1 - arena team else data << uint32(1); + SendPacket(&data); } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index bae8ce3d5..185551340 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -112,6 +112,14 @@ enum CharacterFlags CHARACTER_FLAG_UNK32 = 0x80000000 }; +enum CharacterCustomizeFlags +{ + CHAR_CUSTOMIZE_FLAG_NONE = 0x00000000, + CHAR_CUSTOMIZE_FLAG_CUSTOMIZE = 0x00000001, // name, gender, etc... + CHAR_CUSTOMIZE_FLAG_FACTION = 0x00010000, // name, gender, faction, etc... + CHAR_CUSTOMIZE_FLAG_RACE = 0x00100000 // name, gender, race, etc... +}; + // corpse reclaim times #define DEATH_EXPIRE_STEP (5*MINUTE) #define MAX_DEATH_COUNT 3 @@ -420,7 +428,8 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa m_HomebindTimer = 0; m_InstanceValid = true; - m_dungeonDifficulty = DIFFICULTY_NORMAL; + m_dungeonDifficulty = DUNGEON_DIFFICULTY_NORMAL; + m_raidDifficulty = RAID_DIFFICULTY_10MAN_NORMAL; m_lastPotionId = 0; @@ -500,7 +509,7 @@ Player::~Player () delete ItemSetEff[x]; // clean up player-instance binds, may unload some instance saves - for(uint8 i = 0; i < TOTAL_DIFFICULTIES; ++i) + for(uint8 i = 0; i < MAX_DIFFICULTY; ++i) for(BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr) itr->second.save->RemovePlayer(this); @@ -1450,8 +1459,8 @@ bool Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) char_flags |= CHARACTER_FLAG_DECLINED; *p_data << uint32(char_flags); // character flags - // character customize (flags?) - *p_data << uint32(atLoginFlags & AT_LOGIN_CUSTOMIZE ? 1 : 0); + // character customize flags + *p_data << uint32(atLoginFlags & AT_LOGIN_CUSTOMIZE ? CHAR_CUSTOMIZE_FLAG_CUSTOMIZE : CHAR_CUSTOMIZE_FLAG_NONE); *p_data << uint8(1); // unknown // Pets info @@ -1600,6 +1609,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati m_movementInfo.t_y = 0.0f; m_movementInfo.t_z = 0.0f; m_movementInfo.t_o = 0.0f; + m_movementInfo.t_seat = -1; m_movementInfo.t_time = 0; } @@ -4248,17 +4258,17 @@ void Player::CreateCorpse() corpse->SetUInt32Value( CORPSE_FIELD_GUILD, GetGuildId() ); uint32 iDisplayID; - uint16 iIventoryType; + uint32 iIventoryType; uint32 _cfi; for (int i = 0; i < EQUIPMENT_SLOT_END; ++i) { if(m_items[i]) { iDisplayID = m_items[i]->GetProto()->DisplayInfoID; - iIventoryType = (uint16)m_items[i]->GetProto()->InventoryType; + iIventoryType = m_items[i]->GetProto()->InventoryType; - _cfi = (uint16(iDisplayID)) | (iIventoryType)<< 24; - corpse->SetUInt32Value(CORPSE_FIELD_ITEM + i,_cfi); + _cfi = iDisplayID | (iIventoryType << 24); + corpse->SetUInt32Value(CORPSE_FIELD_ITEM + i, _cfi); } } @@ -5555,7 +5565,7 @@ ActionButton* Player::addActionButton(uint8 button, uint32 action, uint8 type) { if(button >= MAX_ACTION_BUTTONS) { - sLog.outError( "Action %u not added into button %u for player %s: button must be < 132", action, button, GetName() ); + sLog.outError( "Action %u not added into button %u for player %s: button must be < 144", action, button, GetName() ); return NULL; } @@ -6232,29 +6242,19 @@ void Player::UpdateArea(uint32 newArea) void Player::UpdateZone(uint32 newZone, uint32 newArea) { - if(m_zoneUpdateId != newZone) - SendInitWorldStates(newZone, newArea); // only if really enters to new zone, not just area change, works strange... - - m_zoneUpdateId = newZone; - m_zoneUpdateTimer = ZONE_UPDATE_INTERVAL; - - // zone changed, so area changed as well, update it - UpdateArea(newArea); - AreaTableEntry const* zone = GetAreaEntryByAreaID(newZone); if(!zone) return; - if (sWorld.getConfig(CONFIG_WEATHER)) + if(m_zoneUpdateId != newZone) { - Weather *wth = sWorld.FindWeather(zone->ID); - if(wth) + SendInitWorldStates(newZone, newArea); // only if really enters to new zone, not just area change, works strange... + + if (sWorld.getConfig(CONFIG_WEATHER)) { - wth->SendWeatherUpdateToPlayer(this); - } - else - { - if(!sWorld.AddWeather(zone->ID)) + if(Weather *wth = sWorld.FindWeather(zone->ID)) + wth->SendWeatherUpdateToPlayer(this); + else if(!sWorld.AddWeather(zone->ID)) { // send fine weather packet to remove old zone's weather Weather::SendFineWeatherUpdateToPlayer(this); @@ -6262,6 +6262,12 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) } } + m_zoneUpdateId = newZone; + m_zoneUpdateTimer = ZONE_UPDATE_INTERVAL; + + // zone changed, so area changed as well, update it + UpdateArea(newArea); + // in PvP, any not controlled zone (except zone->team == 6, default case) // in PvE, only opposition team capital switch(zone->team) @@ -6987,7 +6993,7 @@ void Player::UpdateEquipSpellsAtFormChange() void Player::CastItemCombatSpell(Unit* Target, WeaponAttackType attType) { - Item *item = GetWeaponForAttack(attType, true); + Item *item = GetWeaponForAttack(attType, false); if(!item || item->IsBroken()) return; @@ -13823,7 +13829,7 @@ void Player::SendQuestFailed( uint32 quest_id ) if( quest_id ) { WorldPacket data( SMSG_QUESTGIVER_QUEST_FAILED, 4+4 ); - data << quest_id; + data << uint32(quest_id); data << uint32(0); // failed reason (4 for inventory is full) GetSession()->SendPacket( &data ); sLog.outDebug("WORLD: Sent SMSG_QUESTGIVER_QUEST_FAILED"); @@ -13835,7 +13841,7 @@ void Player::SendQuestTimerFailed( uint32 quest_id ) if( quest_id ) { WorldPacket data( SMSG_QUESTUPDATE_FAILEDTIMER, 4 ); - data << quest_id; + data << uint32(quest_id); GetSession()->SendPacket( &data ); sLog.outDebug("WORLD: Sent SMSG_QUESTUPDATE_FAILEDTIMER"); } @@ -13916,7 +13922,7 @@ void Player::_LoadDeclinedNames(QueryResult* result) void Player::_LoadArenaTeamInfo(QueryResult *result) { // arenateamid, played_week, played_season, personal_rating - memset((void*)&m_uint32Values[PLAYER_FIELD_ARENA_TEAM_INFO_1_1], 0, sizeof(uint32)*18); + memset((void*)&m_uint32Values[PLAYER_FIELD_ARENA_TEAM_INFO_1_1], 0, sizeof(uint32) * MAX_ARENA_SLOT * ARENA_TEAM_END); if (!result) return; @@ -13927,24 +13933,26 @@ void Player::_LoadArenaTeamInfo(QueryResult *result) uint32 arenateamid = fields[0].GetUInt32(); uint32 played_week = fields[1].GetUInt32(); uint32 played_season = fields[2].GetUInt32(); - uint32 personal_rating = fields[3].GetUInt32(); + uint32 wons_season = fields[3].GetUInt32(); + uint32 personal_rating = fields[4].GetUInt32(); ArenaTeam* aTeam = objmgr.GetArenaTeamById(arenateamid); if(!aTeam) { - sLog.outError("Player::_LoadArenaTeamInfo: couldn't load arenateam %u, week %u, season %u, rating %u", arenateamid, played_week, played_season, personal_rating); + sLog.outError("Player::_LoadArenaTeamInfo: couldn't load arenateam %u", arenateamid); continue; } uint8 arenaSlot = aTeam->GetSlot(); - m_uint32Values[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + arenaSlot * 6] = arenateamid; // TeamID - m_uint32Values[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + arenaSlot * 6 + 1] = ((aTeam->GetCaptain() == GetGUID()) ? (uint32)0 : (uint32)1); // Captain 0, member 1 - m_uint32Values[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + arenaSlot * 6 + 2] = played_week; // Played Week - m_uint32Values[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + arenaSlot * 6 + 3] = played_season; // Played Season - m_uint32Values[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + arenaSlot * 6 + 4] = 0; // Unk - m_uint32Values[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + arenaSlot * 6 + 5] = personal_rating; // Personal Rating + m_uint32Values[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (arenaSlot * ARENA_TEAM_END) + ARENA_TEAM_ID] = arenateamid; // TeamID + m_uint32Values[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (arenaSlot * ARENA_TEAM_END) + ARENA_TEAM_TYPE] = aTeam->GetType(); // team type + m_uint32Values[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (arenaSlot * ARENA_TEAM_END) + ARENA_TEAM_MEMBER] = ((aTeam->GetCaptain() == GetGUID()) ? (uint32)0 : (uint32)1); // Captain 0, member 1 + m_uint32Values[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (arenaSlot * ARENA_TEAM_END) + ARENA_TEAM_GAMES_WEEK] = played_week; // Played Week + m_uint32Values[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (arenaSlot * ARENA_TEAM_END) + ARENA_TEAM_GAMES_SEASON] = played_season; // Played Season + m_uint32Values[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (arenaSlot * ARENA_TEAM_END) + ARENA_TEAM_WINS_SEASON] = wons_season; // wins season + m_uint32Values[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (arenaSlot * ARENA_TEAM_END) + ARENA_TEAM_PERSONAL_RATING] = personal_rating; // Personal Rating - }while (result->NextRow()); + } while (result->NextRow()); delete result; } @@ -14174,7 +14182,11 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) uint32 transGUID = fields[31].GetUInt32(); Relocate(fields[13].GetFloat(),fields[14].GetFloat(),fields[15].GetFloat(),fields[17].GetFloat()); SetLocationMapId(fields[16].GetUInt32()); - SetDifficulty(fields[39].GetUInt32()); // may be changed in _LoadGroup + + uint32 difficulty = fields[39].GetUInt32(); + if(difficulty >= MAX_DUNGEON_DIFFICULTY) + difficulty = DUNGEON_DIFFICULTY_NORMAL; + SetDungeonDifficulty(Difficulty(difficulty)); // may be changed in _LoadGroup _LoadGroup(holder->GetResult(PLAYER_LOGIN_QUERY_LOADGROUP)); @@ -14198,8 +14210,8 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) continue; // arena team not exist or not member, cleanup fields - for(int j =0; j < 6; ++j) - SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + arena_slot * 6 + j, 0); + for(int j = 0; j < ARENA_TEAM_END; ++j) + SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (arena_slot * ARENA_TEAM_END) + j, 0); } _LoadBoundInstances(holder->GetResult(PLAYER_LOGIN_QUERY_LOADBOUNDINSTANCES)); @@ -14215,6 +14227,8 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) m_movementInfo.t_y = 0.0f; m_movementInfo.t_z = 0.0f; m_movementInfo.t_o = 0.0f; + m_movementInfo.t_time = 0; + m_movementInfo.t_seat = -1; } _LoadBGData(holder->GetResult(PLAYER_LOGIN_QUERY_LOADBGDATA)); @@ -14250,7 +14264,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) { MapEntry const* mapEntry = sMapStore.LookupEntry(GetMapId()); // if server restart after player save in BG or area - // player can have current coordinates in to BG/Arean map, fix this + // player can have current coordinates in to BG/Arena map, fix this if(!mapEntry || mapEntry->IsBattleGroundOrArena()) { const WorldLocation& _loc = GetBattleGroundEntryPoint(); @@ -14282,6 +14296,8 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) m_movementInfo.t_y = 0.0f; m_movementInfo.t_z = 0.0f; m_movementInfo.t_o = 0.0f; + m_movementInfo.t_time = 0; + m_movementInfo.t_seat = -1; transGUID = 0; } @@ -14319,6 +14335,8 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) m_movementInfo.t_y = 0.0f; m_movementInfo.t_z = 0.0f; m_movementInfo.t_o = 0.0f; + m_movementInfo.t_time = 0; + m_movementInfo.t_seat = -1; transGUID = 0; } @@ -14421,7 +14439,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) delete result; // clear channel spell data (if saved at channel spell casting) - SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, 0); + SetChannelObjectGUID(0); SetUInt32Value(UNIT_CHANNEL_SPELL,0); // clear charm/summon related fields @@ -15267,19 +15285,20 @@ void Player::_LoadSpells(QueryResult *result) void Player::_LoadGroup(QueryResult *result) { //QueryResult *result = CharacterDatabase.PQuery("SELECT leaderGuid FROM group_member WHERE memberGuid='%u'", GetGUIDLow()); - if(result) + if (result) { uint64 leaderGuid = MAKE_NEW_GUID((*result)[0].GetUInt32(), 0, HIGHGUID_PLAYER); delete result; - Group* group = objmgr.GetGroupByLeader(leaderGuid); - if(group) + + if (Group* group = objmgr.GetGroupByLeader(leaderGuid)) { uint8 subgroup = group->GetMemberGroup(GetGUID()); SetGroup(group, subgroup); - if(getLevel() >= LEVELREQUIREMENT_HEROIC) + if (getLevel() >= LEVELREQUIREMENT_HEROIC) { // the group leader may change the instance difficulty while the player is offline - SetDifficulty(group->GetDifficulty()); + SetDungeonDifficulty(group->GetDungeonDifficulty()); + SetRaidDifficulty(group->GetRaidDifficulty()); } } } @@ -15287,7 +15306,7 @@ void Player::_LoadGroup(QueryResult *result) void Player::_LoadBoundInstances(QueryResult *result) { - for(uint8 i = 0; i < TOTAL_DIFFICULTIES; ++i) + for(uint8 i = 0; i < MAX_DIFFICULTY; ++i) m_boundInstances[i].clear(); Group *group = GetGroup(); @@ -15302,6 +15321,7 @@ void Player::_LoadBoundInstances(QueryResult *result) uint32 mapId = fields[2].GetUInt32(); uint32 instanceId = fields[0].GetUInt32(); uint8 difficulty = fields[3].GetUInt8(); + time_t resetTime = (time_t)fields[4].GetUInt64(); // the resettime for normal instances is only saved when the InstanceSave is unloaded // so the value read from the DB may be wrong here but only if the InstanceSave is loaded @@ -15315,6 +15335,21 @@ void Player::_LoadBoundInstances(QueryResult *result) continue; } + if(difficulty >= MAX_DIFFICULTY) + { + sLog.outError("_LoadBoundInstances: player %s(%d) has bind to not existed difficulty %d instance for map %u", GetName(), GetGUIDLow(), difficulty, mapId); + CharacterDatabase.PExecute("DELETE FROM character_instance WHERE guid = '%d' AND instance = '%d'", GetGUIDLow(), instanceId); + continue; + } + + MapDifficulty const* mapDiff = GetMapDifficultyData(mapId,Difficulty(difficulty)); + if(!mapDiff) + { + sLog.outError("_LoadBoundInstances: player %s(%d) has bind to not existed difficulty %d instance for map %u", GetName(), GetGUIDLow(), difficulty, mapId); + CharacterDatabase.PExecute("DELETE FROM character_instance WHERE guid = '%d' AND instance = '%d'", GetGUIDLow(), instanceId); + continue; + } + if(!perm && group) { sLog.outError("_LoadBoundInstances: player %s(%d) is in group %d but has a non-permanent character bind to map %d,%d,%d", GetName(), GetGUIDLow(), GUID_LOPART(group->GetLeaderGUID()), mapId, instanceId, difficulty); @@ -15323,18 +15358,19 @@ void Player::_LoadBoundInstances(QueryResult *result) } // since non permanent binds are always solo bind, they can always be reset - InstanceSave *save = sInstanceSaveManager.AddInstanceSave(mapId, instanceId, difficulty, resetTime, !perm, true); + InstanceSave *save = sInstanceSaveManager.AddInstanceSave(mapId, instanceId, Difficulty(difficulty), resetTime, !perm, true); if(save) BindToInstance(save, perm, true); } while(result->NextRow()); delete result; } } -InstancePlayerBind* Player::GetBoundInstance(uint32 mapid, uint8 difficulty) +InstancePlayerBind* Player::GetBoundInstance(uint32 mapid, Difficulty difficulty) { // some instances only have one difficulty - const MapEntry* entry = sMapStore.LookupEntry(mapid); - if(!entry || !entry->SupportsHeroicMode()) difficulty = DIFFICULTY_NORMAL; + MapDifficulty const* mapDiff = GetMapDifficultyData(mapid,difficulty); + if(!mapDiff) + return NULL; BoundInstancesMap::iterator itr = m_boundInstances[difficulty].find(mapid); if(itr != m_boundInstances[difficulty].end()) @@ -15343,13 +15379,13 @@ InstancePlayerBind* Player::GetBoundInstance(uint32 mapid, uint8 difficulty) return NULL; } -void Player::UnbindInstance(uint32 mapid, uint8 difficulty, bool unload) +void Player::UnbindInstance(uint32 mapid, Difficulty difficulty, bool unload) { BoundInstancesMap::iterator itr = m_boundInstances[difficulty].find(mapid); UnbindInstance(itr, difficulty, unload); } -void Player::UnbindInstance(BoundInstancesMap::iterator &itr, uint8 difficulty, bool unload) +void Player::UnbindInstance(BoundInstancesMap::iterator &itr, Difficulty difficulty, bool unload) { if(itr != m_boundInstances[difficulty].end()) { @@ -15401,7 +15437,7 @@ void Player::SendRaidInfo() time_t now = time(NULL); - for(int i = 0; i < TOTAL_DIFFICULTIES; ++i) + for(int i = 0; i < MAX_DIFFICULTY; ++i) { for (BoundInstancesMap::const_iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr) { @@ -15411,8 +15447,9 @@ void Player::SendRaidInfo() data << uint32(save->GetMapId()); // map id data << uint32(save->GetDifficulty()); // difficulty data << uint64(save->GetInstanceId()); // instance id + data << uint8(1); // expired = 0 + data << uint8(0); // extended = 1 data << uint32(save->GetResetTime() - now); // reset time - data << uint32(0); // is extended ++counter; } } @@ -15429,7 +15466,7 @@ void Player::SendSavedInstances() bool hasBeenSaved = false; WorldPacket data; - for(uint8 i = 0; i < TOTAL_DIFFICULTIES; ++i) + for(uint8 i = 0; i < MAX_DIFFICULTY; ++i) { for (BoundInstancesMap::const_iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr) { @@ -15449,7 +15486,7 @@ void Player::SendSavedInstances() if(!hasBeenSaved) return; - for(uint8 i = 0; i < TOTAL_DIFFICULTIES; ++i) + for(uint8 i = 0; i < MAX_DIFFICULTY; ++i) { for (BoundInstancesMap::const_iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr) { @@ -15477,7 +15514,7 @@ void Player::ConvertInstancesToGroup(Player *player, Group *group, uint64 player if(player) { - for(uint8 i = 0; i < TOTAL_DIFFICULTIES; ++i) + for(uint8 i = 0; i < MAX_DIFFICULTY; ++i) { for (BoundInstancesMap::iterator itr = player->m_boundInstances[i].begin(); itr != player->m_boundInstances[i].end();) { @@ -15486,7 +15523,8 @@ void Player::ConvertInstancesToGroup(Player *player, Group *group, uint64 player // permanent binds are not removed if(!itr->second.perm) { - player->UnbindInstance(itr, i, true); // increments itr + // increments itr in call + player->UnbindInstance(itr, Difficulty(i), true); has_solo = true; } else @@ -15603,7 +15641,7 @@ void Player::SaveToDB() if(!IsBeingTeleported()) { ss << GetMapId() << ", " - << (uint32)GetDifficulty() << ", " + << (uint32)GetDungeonDifficulty() << ", " << finiteAlways(GetPositionX()) << ", " << finiteAlways(GetPositionY()) << ", " << finiteAlways(GetPositionZ()) << ", " @@ -15612,7 +15650,7 @@ void Player::SaveToDB() else { ss << GetTeleportDest().mapid << ", " - << (uint32)GetDifficulty() << ", " + << (uint32)GetDungeonDifficulty() << ", " << finiteAlways(GetTeleportDest().coord_x) << ", " << finiteAlways(GetTeleportDest().coord_y) << ", " << finiteAlways(GetTeleportDest().coord_z) << ", " @@ -16170,7 +16208,17 @@ void Player::SendDungeonDifficulty(bool IsInGroup) { uint8 val = 0x00000001; WorldPacket data(MSG_SET_DUNGEON_DIFFICULTY, 12); - data << (uint32)GetDifficulty(); + data << (uint32)GetDungeonDifficulty(); + data << uint32(val); + data << uint32(IsInGroup); + GetSession()->SendPacket(&data); +} + +void Player::SendRaidDifficulty(bool IsInGroup) +{ + uint8 val = 0x00000001; + WorldPacket data(MSG_SET_RAID_DIFFICULTY, 12); + data << uint32(GetRaidDifficulty()); data << uint32(val); data << uint32(IsInGroup); GetSession()->SendPacket(&data); @@ -16184,18 +16232,18 @@ void Player::SendResetFailedNotify(uint32 mapid) } /// Reset all solo instances and optionally send a message on success for each -void Player::ResetInstances(uint8 method) +void Player::ResetInstances(uint8 method, bool isRaid) { // method can be INSTANCE_RESET_ALL, INSTANCE_RESET_CHANGE_DIFFICULTY, INSTANCE_RESET_GROUP_JOIN // we assume that when the difficulty changes, all instances that can be reset will be - uint8 dif = GetDifficulty(); + Difficulty diff = GetDifficulty(isRaid); - for (BoundInstancesMap::iterator itr = m_boundInstances[dif].begin(); itr != m_boundInstances[dif].end();) + for (BoundInstancesMap::iterator itr = m_boundInstances[diff].begin(); itr != m_boundInstances[diff].end();) { InstanceSave *p = itr->second.save; const MapEntry *entry = sMapStore.LookupEntry(itr->first); - if(!entry || !p->CanReset()) + if(!entry || entry->IsRaid() != isRaid || !p->CanReset()) { ++itr; continue; @@ -16204,7 +16252,7 @@ void Player::ResetInstances(uint8 method) if(method == INSTANCE_RESET_ALL) { // the "reset all instances" method can only reset normal maps - if(dif == DIFFICULTY_HEROIC || entry->map_type == MAP_RAID) + if(entry->map_type == MAP_RAID || diff == DUNGEON_DIFFICULTY_HEROIC) { ++itr; continue; @@ -16221,7 +16269,7 @@ void Player::ResetInstances(uint8 method) SendResetInstanceSuccess(p->GetMapId()); p->DeleteFromDB(); - m_boundInstances[dif].erase(itr++); + m_boundInstances[diff].erase(itr++); // the following should remove the instance save from the manager and delete it as well p->RemovePlayer(this); @@ -17375,10 +17423,10 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint uint32 new_count = pCreature->UpdateVendorItemCurrentCount(crItem,pProto->BuyCount * count); WorldPacket data(SMSG_BUY_ITEM, (8+4+4+4)); - data << pCreature->GetGUID(); - data << (uint32)(vendor_slot+1); // numbered from 1 at client - data << (uint32)(crItem->maxcount > 0 ? new_count : 0xFFFFFFFF); - data << (uint32)count; + data << uint64(pCreature->GetGUID()); + data << uint32(vendor_slot+1); // numbered from 1 at client + data << uint32(crItem->maxcount > 0 ? new_count : 0xFFFFFFFF); + data << uint32(count); GetSession()->SendPacket(&data); SendNewItem(it, pProto->BuyCount*count, true, false, false); @@ -17420,10 +17468,10 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint uint32 new_count = pCreature->UpdateVendorItemCurrentCount(crItem,pProto->BuyCount * count); WorldPacket data(SMSG_BUY_ITEM, (8+4+4+4)); - data << pCreature->GetGUID(); - data << (uint32)(vendor_slot+1); // numbered from 1 at client - data << (uint32)(crItem->maxcount > 0 ? new_count : 0xFFFFFFFF); - data << (uint32)count; + data << uint64(pCreature->GetGUID()); + data << uint32(vendor_slot + 1); // numbered from 1 at client + data << uint32(crItem->maxcount > 0 ? new_count : 0xFFFFFFFF); + data << uint32(count); GetSession()->SendPacket(&data); SendNewItem(it, pProto->BuyCount*count, true, false, false); @@ -17450,9 +17498,9 @@ uint32 Player::GetMaxPersonalArenaRatingRequirement() { if(ArenaTeam * at = objmgr.GetArenaTeamById(GetArenaTeamId(i))) { - uint32 p_rating = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (i * 6) + 5); + uint32 p_rating = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (i * ARENA_TEAM_END) + ARENA_TEAM_PERSONAL_RATING); uint32 t_rating = at->GetRating(); - p_rating = p_ratingSendPacket(&data); sLog.outDebug("PLAYER: Player '%s' (GUID: %u) will be teleported to homebind in 60 seconds", GetName(),GetGUIDLow()); @@ -17622,12 +17670,12 @@ void Player::AddSpellCooldown(uint32 spellid, uint32 itemid, time_t end_time) void Player::SendCooldownEvent(SpellEntry const *spellInfo, uint32 itemId, Spell* spell) { // start cooldowns at server side, if any - AddSpellAndCategoryCooldowns(spellInfo,itemId,spell); + AddSpellAndCategoryCooldowns(spellInfo, itemId, spell); // Send activate cooldown timer (possible 0) at client side WorldPacket data(SMSG_COOLDOWN_EVENT, (4+8)); - data << spellInfo->Id; - data << GetGUID(); + data << uint32(spellInfo->Id); + data << uint64(GetGUID()); SendDirectMessage(&data); } @@ -17773,7 +17821,7 @@ void Player::CorrectMetaGemEnchants(uint8 exceptslot, bool apply) { // ignore item gem conditions //if state changed, (dis)apply enchant - ApplyEnchantment(pItem,EnchantmentSlot(enchant_slot),!wasactive,true,true); + ApplyEnchantment(pItem, EnchantmentSlot(enchant_slot), !wasactive, true, true); } } } @@ -17914,7 +17962,7 @@ void Player::ReportedAfkBy(Player* reporter) return; // check if player has 'Idle' or 'Inactive' debuff - if(m_bgData.bgAfkReporter.find(reporter->GetGUIDLow())==m_bgData.bgAfkReporter.end() && !HasAura(43680,0) && !HasAura(43681,0) && reporter->CanReportAfkDueToLimit()) + if(m_bgData.bgAfkReporter.find(reporter->GetGUIDLow()) == m_bgData.bgAfkReporter.end() && !HasAura(43680, 0) && !HasAura(43681, 0) && reporter->CanReportAfkDueToLimit()) { m_bgData.bgAfkReporter.insert(reporter->GetGUIDLow()); // 3 players have to complain to apply debuff @@ -18174,23 +18222,26 @@ void Player::SetGroup(Group *group, int8 subgroup) void Player::SendInitialPacketsBeforeAddToMap() { - WorldPacket data(SMSG_SET_REST_START_OBSOLETE, 4); - data << uint32(0); // unknown, may be rest state time or experience - GetSession()->SendPacket(&data); - GetSocial()->SendSocialList(); + // guild bank list wtf? + // Homebind - data.Initialize(SMSG_BINDPOINTUPDATE, 5*4); + WorldPacket data(SMSG_BINDPOINTUPDATE, 5*4); data << m_homebindX << m_homebindY << m_homebindZ; data << (uint32) m_homebindMapId; data << (uint32) m_homebindZoneId; GetSession()->SendPacket(&data); // SMSG_SET_PROFICIENCY + // SMSG_SET_PCT_SPELL_MODIFIER + // SMSG_SET_FLAT_SPELL_MODIFIER // SMSG_UPDATE_AURA_DURATION SendTalentsInfoData(false); + + // SMSG_INSTANCE_DIFFICULTY + SendInitialSpells(); data.Initialize(SMSG_SEND_UNLEARN_SPELLS, 4); @@ -18199,6 +18250,7 @@ void Player::SendInitialPacketsBeforeAddToMap() SendInitialActionButtons(); m_reputationMgr.SendInitialReputations(); + // SMSG_INIT_WORLD_STATES m_achievementMgr.SendAllAchievementData(); SendEquipmentSetList(); @@ -18209,6 +18261,11 @@ void Player::SendInitialPacketsBeforeAddToMap() data << uint32(0); // added in 3.1.2 GetSession()->SendPacket( &data ); + // SMSG_TALENTS_INFO x 2 for pet (unspent points and talents in separate packets...) + // SMSG_PET_GUIDS + // SMSG_UPDATE_WORLD_STATE + // SMSG_POWER_UPDATE + // set fly flag if in fly form or taxi flight to prevent visually drop at ground in showup moment if(HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED) || HasAuraType(SPELL_AURA_FLY) || isInFlight()) m_movementInfo.AddMovementFlag(MOVEMENTFLAG_FLYING2); @@ -18291,7 +18348,7 @@ void Player::SendTransferAborted(uint32 mapid, uint8 reason, uint8 arg) GetSession()->SendPacket(&data); } -void Player::SendInstanceResetWarning( uint32 mapid, uint32 difficulty, uint32 time ) +void Player::SendInstanceResetWarning( uint32 mapid, Difficulty difficulty, uint32 time ) { // type of warning, based on the time remaining until reset uint32 type; @@ -18596,12 +18653,8 @@ bool Player::GetBGAccessByLevel(BattleGroundTypeId bgTypeId) const BGQueueIdBasedOnLevel Player::GetBattleGroundQueueIdFromLevel(BattleGroundTypeId bgTypeId) const { - //returned to hardcoded version of this function, because there is no way to code it dynamic - uint32 level = getLevel(); - if( bgTypeId == BATTLEGROUND_AV ) - level--; - - uint32 queue_id = (level / 10) - 1; // for ranges 0 - 19, 20 - 29, 30 - 39, 40 - 49, 50 - 59, 60 - 69, 70 -79, 80 + // for ranges 0 - 19, 20 - 29, 30 - 39, 40 - 49, 50 - 59, 60 - 69, 70 - 79, 80 + uint32 queue_id = ( getLevel() / 10) - 1; if( queue_id >= MAX_BATTLEGROUND_QUEUES ) { sLog.outError("BattleGround: too high queue_id %u this shouldn't happen", queue_id); @@ -20645,7 +20698,7 @@ bool Player::HasMovementFlag( MovementFlags f ) const void Player::SetFarSightGUID( uint64 guid ) { - if(GetFarSight()==guid) + if(GetFarSight() == guid) return; SetUInt64Value(PLAYER_FARSIGHT, guid); @@ -20675,3 +20728,9 @@ void Player::UpdateVisibilityForPlayer() m->UpdateObjectsVisibilityFor(this, cell, p); } +void Player::SendDuelCountdown(uint32 counter) +{ + WorldPacket data(SMSG_DUEL_COUNTDOWN, 4); + data << uint32(counter); // seconds + GetSession()->SendPacket(&data); +} diff --git a/src/game/Player.h b/src/game/Player.h index cd0ea2619..20835baf1 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -169,7 +169,7 @@ struct ActionButton } }; -#define MAX_ACTION_BUTTONS 132 //checked in 2.3.0 +#define MAX_ACTION_BUTTONS 144 //checked in 3.2.0 typedef std::map ActionButtonList; @@ -316,20 +316,20 @@ typedef std::list ItemDurationList; enum LfgType { - LFG_TYPE_NONE = 0, - LFG_TYPE_DUNGEON = 1, - LFG_TYPE_RAID = 2, - LFG_TYPE_QUEST = 3, - LFG_TYPE_ZONE = 4, - LFG_TYPE_HEROIC_DUNGEON = 5 + LFG_TYPE_NONE = 0, + LFG_TYPE_DUNGEON = 1, + LFG_TYPE_RAID = 2, + LFG_TYPE_QUEST = 3, + LFG_TYPE_ZONE = 4, + LFG_TYPE_HEROIC_DUNGEON = 5 }; enum LfgRoles { - LEADER = 1, - TANK = 2, - HEALER = 4, - DAMAGE = 8 + LEADER = 0x01, + TANK = 0x02, + HEALER = 0x04, + DAMAGE = 0x08 }; struct LookingForGroupSlot @@ -426,7 +426,7 @@ enum PlayerFlags PLAYER_FLAGS_UNK23 = 0x00400000, PLAYER_FLAGS_UNK24 = 0x00800000, // disabled all abilitys on tab except autoattack PLAYER_FLAGS_UNK25 = 0x01000000, // disabled all melee ability on tab include autoattack - + PLAYER_FLAGS_NO_XP_GAIN = 0x02000000, }; // used for PLAYER__FIELD_KNOWN_TITLES field (uint64), (1<m_InstanceID, - /// when player is teleported to BG - (it is battleground's GUID) + uint32 bgInstanceID; ///< This variable is set to bg->m_InstanceID, + /// when player is teleported to BG - (it is battleground's GUID) BattleGroundTypeId bgTypeID; std::set bgAfkReporter; uint8 bgAfkReportedCount; time_t bgAfkReportedTimer; - uint32 bgTeam; ///< What side the player will be added to + uint32 bgTeam; ///< What side the player will be added to uint32 mountSpell; uint32 taxiPath[2]; - WorldLocation joinPos; ///< From where player entered BG + WorldLocation joinPos; ///< From where player entered BG void ClearTaxiPath() { taxiPath[0] = taxiPath[1] = 0; } bool HasTaxiPath() const { return taxiPath[0] && taxiPath[1]; } @@ -1027,7 +1042,7 @@ class MANGOS_DLL_SPEC Player : public Unit void SendInitialPacketsBeforeAddToMap(); void SendInitialPacketsAfterAddToMap(); void SendTransferAborted(uint32 mapid, uint8 reason, uint8 arg = 0); - void SendInstanceResetWarning(uint32 mapid, uint32 difficulty, uint32 time); + void SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time); Creature* GetNPCIfCanInteractWith(uint64 guid, uint32 npcflagmask); bool CanInteractWithNPCs(bool alive = true) const; @@ -1037,8 +1052,8 @@ class MANGOS_DLL_SPEC Player : public Unit bool ToggleAFK(); bool ToggleDND(); - bool isAFK() const { return HasFlag(PLAYER_FLAGS,PLAYER_FLAGS_AFK); }; - bool isDND() const { return HasFlag(PLAYER_FLAGS,PLAYER_FLAGS_DND); }; + bool isAFK() const { return HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_AFK); } + bool isDND() const { return HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_DND); } uint8 chatTag() const; std::string afkMsg; std::string dndMsg; @@ -1076,33 +1091,33 @@ class MANGOS_DLL_SPEC Player : public Unit time_t m_logintime; time_t m_Last_tick; uint32 m_Played_time[MAX_PLAYED_TIME_INDEX]; - uint32 GetTotalPlayedTime() { return m_Played_time[PLAYED_TIME_TOTAL]; }; - uint32 GetLevelPlayedTime() { return m_Played_time[PLAYED_TIME_LEVEL]; }; + uint32 GetTotalPlayedTime() { return m_Played_time[PLAYED_TIME_TOTAL]; } + uint32 GetLevelPlayedTime() { return m_Played_time[PLAYED_TIME_LEVEL]; } void setDeathState(DeathState s); // overwrite Unit::setDeathState - void InnEnter (int time,uint32 mapid, float x,float y,float z) + void InnEnter (int time, uint32 mapid, float x, float y, float z) { inn_pos_mapid = mapid; inn_pos_x = x; inn_pos_y = y; inn_pos_z = z; time_inn_enter = time; - }; + } - float GetRestBonus() const { return m_rest_bonus; }; + float GetRestBonus() const { return m_rest_bonus; } void SetRestBonus(float rest_bonus_new); - RestType GetRestType() const { return rest_type; }; - void SetRestType(RestType n_r_type) { rest_type = n_r_type; }; + RestType GetRestType() const { return rest_type; } + void SetRestType(RestType n_r_type) { rest_type = n_r_type; } - uint32 GetInnPosMapId() const { return inn_pos_mapid; }; - float GetInnPosX() const { return inn_pos_x; }; - float GetInnPosY() const { return inn_pos_y; }; - float GetInnPosZ() const { return inn_pos_z; }; + uint32 GetInnPosMapId() const { return inn_pos_mapid; } + float GetInnPosX() const { return inn_pos_x; } + float GetInnPosY() const { return inn_pos_y; } + float GetInnPosZ() const { return inn_pos_z; } - int GetTimeInnEnter() const { return time_inn_enter; }; - void UpdateInnerTime (int time) { time_inn_enter = time; }; + int GetTimeInnEnter() const { return time_inn_enter; } + void UpdateInnerTime (int time) { time_inn_enter = time; } void RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent = false); void RemoveMiniPet(); @@ -1132,14 +1147,14 @@ class MANGOS_DLL_SPEC Player : public Unit Item* GetShield(bool useable = false) const; static uint32 GetAttackBySlot( uint8 slot ); // MAX_ATTACK if not weapon slot std::vector &GetItemUpdateQueue() { return m_itemUpdateQueue; } - static bool IsInventoryPos( uint16 pos ) { return IsInventoryPos(pos >> 8,pos & 255); } + static bool IsInventoryPos( uint16 pos ) { return IsInventoryPos(pos >> 8, pos & 255); } static bool IsInventoryPos( uint8 bag, uint8 slot ); - static bool IsEquipmentPos( uint16 pos ) { return IsEquipmentPos(pos >> 8,pos & 255); } + static bool IsEquipmentPos( uint16 pos ) { return IsEquipmentPos(pos >> 8, pos & 255); } static bool IsEquipmentPos( uint8 bag, uint8 slot ); static bool IsBagPos( uint16 pos ); - static bool IsBankPos( uint16 pos ) { return IsBankPos(pos >> 8,pos & 255); } + static bool IsBankPos( uint16 pos ) { return IsBankPos(pos >> 8, pos & 255); } static bool IsBankPos( uint8 bag, uint8 slot ); - bool IsValidPos( uint16 pos ) { return IsBankPos(pos >> 8,pos & 255); } + bool IsValidPos( uint16 pos ) { return IsBankPos(pos >> 8, pos & 255); } bool IsValidPos( uint8 bag, uint8 slot ); uint8 GetBankBagSlotCount() const { return GetByteValue(PLAYER_BYTES_2, 2); } void SetBankBagSlotCount(uint8 count) { SetByteValue(PLAYER_BYTES_2, 2, count); } @@ -1148,8 +1163,8 @@ class MANGOS_DLL_SPEC Player : public Unit bool CanNoReagentCast(SpellEntry const* spellInfo) const; bool HasItemOrGemWithIdEquipped( uint32 item, uint32 count, uint8 except_slot = NULL_SLOT) const; bool HasItemOrGemWithLimitCategoryEquipped( uint32 limitCategory, uint32 count, uint8 except_slot = NULL_SLOT) const; - uint8 CanTakeMoreSimilarItems(Item* pItem) const { return _CanTakeMoreSimilarItems(pItem->GetEntry(),pItem->GetCount(),pItem); } - uint8 CanTakeMoreSimilarItems(uint32 entry, uint32 count) const { return _CanTakeMoreSimilarItems(entry,count,NULL); } + uint8 CanTakeMoreSimilarItems(Item* pItem) const { return _CanTakeMoreSimilarItems(pItem->GetEntry(), pItem->GetCount(), pItem); } + uint8 CanTakeMoreSimilarItems(uint32 entry, uint32 count) const { return _CanTakeMoreSimilarItems(entry, count, NULL); } uint8 CanStoreNewItem( uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 item, uint32 count, uint32* no_space_count = NULL ) const { return _CanStoreItem(bag, slot, dest, item, count, NULL, false, no_space_count ); @@ -1357,12 +1372,12 @@ class MANGOS_DLL_SPEC Player : public Unit void SendQuestUpdateAddItem( Quest const* pQuest, uint32 item_idx, uint32 count ); void SendQuestUpdateAddCreatureOrGo( Quest const* pQuest, uint64 guid, uint32 creatureOrGO_idx, uint32 old_count, uint32 add_count ); - uint64 GetDivider() { return m_divider; }; - void SetDivider( uint64 guid ) { m_divider = guid; }; + uint64 GetDivider() { return m_divider; } + void SetDivider( uint64 guid ) { m_divider = guid; } - uint32 GetInGameTime() { return m_ingametime; }; + uint32 GetInGameTime() { return m_ingametime; } - void SetInGameTime( uint32 time ) { m_ingametime = time; }; + void SetInGameTime( uint32 time ) { m_ingametime = time; } void AddTimedQuest( uint32 quest_id ) { m_timedquests.insert(quest_id); } void RemoveTimedQuest( uint32 quest_id ) { m_timedquests.erase(quest_id); } @@ -1434,7 +1449,7 @@ class MANGOS_DLL_SPEC Player : public Unit QuestStatusMap& getQuestStatusMap() { return mQuestStatus; }; const uint64& GetSelection( ) const { return m_curSelection; } - void SetSelection(const uint64 &guid) { m_curSelection = guid; SetUInt64Value(UNIT_FIELD_TARGET, guid); } + void SetSelection(const uint64 &guid) { m_curSelection = guid; SetTargetGUID(guid); } uint8 GetComboPoints() { return m_comboPoints; } const uint64& GetComboTarget() const { return m_comboTarget; } @@ -1449,15 +1464,14 @@ class MANGOS_DLL_SPEC Player : public Unit void AddNewMailDeliverTime(time_t deliver_time); bool IsMailsLoaded() const { return m_mailsLoaded; } - //void SetMail(Mail *m); void RemoveMail(uint32 id); void AddMail(Mail* mail) { m_mail.push_front(mail);}// for call from WorldSession::SendMailTo - uint32 GetMailSize() { return m_mail.size();}; + uint32 GetMailSize() { return m_mail.size(); } Mail* GetMail(uint32 id); - PlayerMails::iterator GetmailBegin() { return m_mail.begin();}; - PlayerMails::iterator GetmailEnd() { return m_mail.end();}; + PlayerMails::iterator GetMailBegin() { return m_mail.begin();} + PlayerMails::iterator GetMailEnd() { return m_mail.end();} /*********************************************************/ /*** MAILED ITEMS SYSTEM ***/ @@ -1468,7 +1482,7 @@ class MANGOS_DLL_SPEC Player : public Unit typedef UNORDERED_MAP ItemMap; - ItemMap mMitems; //template defined in objectmgr.cpp + ItemMap mMitems; // template defined in objectmgr.cpp Item* GetMItem(uint32 id) { @@ -1587,7 +1601,7 @@ class MANGOS_DLL_SPEC Player : public Unit m_resurrectZ = Z; m_resurrectHealth = health; m_resurrectMana = mana; - }; + } void clearResurrectRequestData() { setResurrectRequestData(0,0,0.0f,0.0f,0.0f,0,0); } bool isRessurectRequestedBy(uint64 guid) const { return m_resurrectGUID == guid; } bool isRessurectRequested() const { return m_resurrectGUID != 0; } @@ -1630,6 +1644,7 @@ class MANGOS_DLL_SPEC Player : public Unit void UpdateDuelFlag(time_t currTime); void CheckDuelDistance(time_t currTime); void DuelComplete(DuelCompleteType type); + void SendDuelCountdown(uint32 counter); bool IsGroupVisibleFor(Player* p) const; bool IsInSameGroupWith(Player const* p) const; @@ -1650,19 +1665,22 @@ class MANGOS_DLL_SPEC Player : public Unit static void RemovePetitionsAndSigns(uint64 guid, uint32 type); // Arena Team - void SetInArenaTeam(uint32 ArenaTeamId, uint8 slot) + void SetInArenaTeam(uint32 ArenaTeamId, uint8 slot, uint8 type) { - SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * 6), ArenaTeamId); + SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * ARENA_TEAM_END) + ARENA_TEAM_ID, ArenaTeamId); + SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * ARENA_TEAM_END) + ARENA_TEAM_TYPE, type); } - uint32 GetArenaTeamId(uint8 slot) { return GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * 6)); } + uint32 GetArenaTeamId(uint8 slot) { return GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * ARENA_TEAM_END)); } static uint32 GetArenaTeamIdFromDB(uint64 guid, uint8 slot); void SetArenaTeamIdInvited(uint32 ArenaTeamId) { m_ArenaTeamIdInvited = ArenaTeamId; } uint32 GetArenaTeamIdInvited() { return m_ArenaTeamIdInvited; } static void LeaveAllArenaTeams(uint64 guid); - void SetDifficulty(uint32 dungeon_difficulty) { m_dungeonDifficulty = dungeon_difficulty; } - uint8 GetDifficulty() { return m_dungeonDifficulty; } - bool IsHeroic() { return m_dungeonDifficulty == DIFFICULTY_HEROIC; } + Difficulty GetDifficulty(bool isRaid) const { return isRaid ? m_raidDifficulty : m_dungeonDifficulty; } + Difficulty GetDungeonDifficulty() const { return m_dungeonDifficulty; } + Difficulty GetRaidDifficulty() const { return m_raidDifficulty; } + void SetDungeonDifficulty(Difficulty dungeon_difficulty) { m_dungeonDifficulty = dungeon_difficulty; } + void SetRaidDifficulty(Difficulty raid_difficulty) { m_raidDifficulty = raid_difficulty; } bool UpdateSkill(uint32 skill_id, uint32 step); bool UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step); @@ -1749,7 +1767,8 @@ class MANGOS_DLL_SPEC Player : public Unit void SendExplorationExperience(uint32 Area, uint32 Experience); void SendDungeonDifficulty(bool IsInGroup); - void ResetInstances(uint8 method); + void SendRaidDifficulty(bool IsInGroup); + void ResetInstances(uint8 method, bool isRaid); void SendResetInstanceSuccess(uint32 MapId); void SendResetInstanceFailed(uint32 reason, uint32 MapId); void SendResetFailedNotify(uint32 mapid); @@ -1874,7 +1893,7 @@ class MANGOS_DLL_SPEC Player : public Unit void SetCanBlock(bool value); bool CanDualWield() const { return m_canDualWield; } void SetCanDualWield(bool value) { m_canDualWield = value; } - bool CanTitanGrip() const { return m_canTitanGrip ; } + bool CanTitanGrip() const { return m_canTitanGrip; } void SetCanTitanGrip(bool value) { m_canTitanGrip = value; } bool CanTameExoticPets() const { return isGameMaster() || HasAuraType(SPELL_AURA_ALLOW_TAME_PET_TYPE); } @@ -2041,8 +2060,8 @@ class MANGOS_DLL_SPEC Player : public Unit bool isRested() const { return GetRestTime() >= 10*IN_MILISECONDS; } uint32 GetXPRestBonus(uint32 xp); - uint32 GetRestTime() const { return m_restTime;}; - void SetRestTime(uint32 v) { m_restTime = v;}; + uint32 GetRestTime() const { return m_restTime; } + void SetRestTime(uint32 v) { m_restTime = v; } /*********************************************************/ /*** ENVIROMENTAL SYSTEM ***/ @@ -2167,11 +2186,11 @@ class MANGOS_DLL_SPEC Player : public Unit uint32 m_HomebindTimer; bool m_InstanceValid; // permanent binds and solo binds by difficulty - BoundInstancesMap m_boundInstances[TOTAL_DIFFICULTIES]; - InstancePlayerBind* GetBoundInstance(uint32 mapid, uint8 difficulty); - BoundInstancesMap& GetBoundInstances(uint8 difficulty) { return m_boundInstances[difficulty]; } - void UnbindInstance(uint32 mapid, uint8 difficulty, bool unload = false); - void UnbindInstance(BoundInstancesMap::iterator &itr, uint8 difficulty, bool unload = false); + BoundInstancesMap m_boundInstances[MAX_DIFFICULTY]; + InstancePlayerBind* GetBoundInstance(uint32 mapid, Difficulty difficulty); + BoundInstancesMap& GetBoundInstances(Difficulty difficulty) { return m_boundInstances[difficulty]; } + void UnbindInstance(uint32 mapid, Difficulty difficulty, bool unload = false); + void UnbindInstance(BoundInstancesMap::iterator &itr, Difficulty difficulty, bool unload = false); InstancePlayerBind* BindToInstance(InstanceSave *save, bool permanent, bool load = false); void SendRaidInfo(); void SendSavedInstances(); @@ -2323,7 +2342,8 @@ class MANGOS_DLL_SPEC Player : public Unit uint32 m_nextSave; time_t m_speakTime; uint32 m_speakCount; - uint32 m_dungeonDifficulty; + Difficulty m_dungeonDifficulty; + Difficulty m_raidDifficulty; uint32 m_atLoginFlags; @@ -2383,8 +2403,6 @@ class MANGOS_DLL_SPEC Player : public Unit uint16 tradeItems[TRADE_SLOT_COUNT]; uint32 tradeGold; - time_t m_nextThinkTime; - bool m_DailyQuestChanged; time_t m_lastDailyQuestTime; diff --git a/src/game/QueryHandler.cpp b/src/game/QueryHandler.cpp index 2b836521d..e7ae81462 100644 --- a/src/game/QueryHandler.cpp +++ b/src/game/QueryHandler.cpp @@ -36,11 +36,10 @@ void WorldSession::SendNameQueryOpcode(Player *p) { if(!p) return; - // guess size WorldPacket data( SMSG_NAME_QUERY_RESPONSE, (8+1+1+1+1+1+10) ); data.append(p->GetPackGUID()); // player guid - data << uint8(0); // added in 3.1 + data << uint8(0); // added in 3.1; if > 1, then end of packet data << p->GetName(); // played name data << uint8(0); // realm name for cross realm BG usage data << uint8(p->getRace()); @@ -100,11 +99,10 @@ void WorldSession::SendNameQueryOpcodeFromDBCallBack(QueryResult *result, uint32 pGender = fields[3].GetUInt8(); pClass = fields[4].GetUInt8(); } - // guess size WorldPacket data( SMSG_NAME_QUERY_RESPONSE, (8+1+1+1+1+1+1+10) ); data.appendPackGUID(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER)); - data << uint8(0); // added in 3.1 + data << uint8(0); // added in 3.1; if > 1, then end of packet data << name; data << uint8(0); // realm name for cross realm BG usage data << uint8(pRace); // race @@ -152,7 +150,8 @@ void WorldSession::HandleCreatureQueryOpcode( WorldPacket & recv_data ) { uint32 entry; recv_data >> entry; - recv_data.read_skip(); // guid + uint64 guid; + recv_data >> guid; CreatureInfo const *ci = objmgr.GetCreatureTemplate(entry); if (ci) @@ -195,17 +194,14 @@ void WorldSession::HandleCreatureQueryOpcode( WorldPacket & recv_data ) data << float(ci->unk16); // unk data << float(ci->unk17); // unk data << uint8(ci->RacialLeader); - for(uint32 i = 0; i < 4; ++i) - data << uint32(ci->questItems[i]); // itemId[4], quest drop + for(uint32 i = 0; i < 6; ++i) + data << uint32(ci->questItems[i]); // itemId[6], quest drop data << uint32(ci->movementId); // CreatureMovementInfo.dbc SendPacket( &data ); sLog.outDebug( "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE" ); } else { - uint64 guid; - recv_data >> guid; - sLog.outDebug("WORLD: CMSG_CREATURE_QUERY - NO CREATURE INFO! (GUID: %u, ENTRY: %u)", GUID_LOPART(guid), entry); WorldPacket data( SMSG_CREATURE_QUERY_RESPONSE, 4 ); @@ -220,7 +216,8 @@ void WorldSession::HandleGameObjectQueryOpcode( WorldPacket & recv_data ) { uint32 entryID; recv_data >> entryID; - recv_data.read_skip(); // guid + uint64 guid; + recv_data >> guid; const GameObjectInfo *info = objmgr.GetGameObjectInfo(entryID); if(info) @@ -257,17 +254,13 @@ void WorldSession::HandleGameObjectQueryOpcode( WorldPacket & recv_data ) data << info->unk1; // 2.0.3, string data.append(info->raw.data, 24); data << float(info->size); // go size - for(uint32 i = 0; i < 4; ++i) - data << uint32(info->questItems[i]); // itemId[4], quest drop + for(uint32 i = 0; i < 6; ++i) + data << uint32(info->questItems[i]); // itemId[6], quest drop SendPacket( &data ); sLog.outDebug( "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE" ); } else { - - uint64 guid; - recv_data >> guid; - sLog.outDebug( "WORLD: CMSG_GAMEOBJECT_QUERY - Missing gameobject info for (GUID: %u, ENTRY: %u)", GUID_LOPART(guid), entryID ); WorldPacket data ( SMSG_GAMEOBJECT_QUERY_RESPONSE, 4 ); @@ -317,13 +310,14 @@ void WorldSession::HandleCorpseQueryOpcode(WorldPacket & /*recv_data*/) } } - WorldPacket data(MSG_CORPSE_QUERY, 1+(5*4)); + WorldPacket data(MSG_CORPSE_QUERY, 1+(6*4)); data << uint8(1); // corpse found data << int32(mapid); data << float(x); data << float(y); data << float(z); data << int32(corpsemapid); + data << uint32(0); // unknown SendPacket(&data); } @@ -336,7 +330,7 @@ void WorldSession::HandleNpcTextQueryOpcode( WorldPacket & recv_data ) sLog.outDetail("WORLD: CMSG_NPC_TEXT_QUERY ID '%u'", textID); recv_data >> guid; - GetPlayer()->SetUInt64Value(UNIT_FIELD_TARGET, guid); + _player->SetTargetGUID(guid); GossipText const* pGossip = objmgr.GetGossipText(textID); @@ -415,10 +409,12 @@ void WorldSession::HandleNpcTextQueryOpcode( WorldPacket & recv_data ) void WorldSession::HandlePageTextQueryOpcode( WorldPacket & recv_data ) { - uint32 pageID; + sLog.outDetail("WORLD: Received CMSG_PAGE_TEXT_QUERY"); + recv_data.hexlike(); + uint32 pageID; recv_data >> pageID; - sLog.outDetail("WORLD: Received CMSG_PAGE_TEXT_QUERY for pageID '%u'", pageID); + recv_data.read_skip(); // guid while (pageID) { @@ -457,3 +453,18 @@ void WorldSession::HandlePageTextQueryOpcode( WorldPacket & recv_data ) sLog.outDebug( "WORLD: Sent SMSG_PAGE_TEXT_QUERY_RESPONSE" ); } } + +void WorldSession::HandleCorpseMapPositionQuery( WorldPacket & recv_data ) +{ + sLog.outDebug( "WORLD: Recv CMSG_CORPSE_MAP_POSITION_QUERY" ); + + uint32 unk; + recv_data >> unk; + + WorldPacket data(CMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE, 4+4+4+4); + data << float(0); + data << float(0); + data << float(0); + data << float(0); + SendPacket(&data); +} diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index 88803c59c..282791706 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -93,7 +93,7 @@ enum Classes #define CLASSMASK_WAND_USERS ((1<<(CLASS_PRIEST-1))|(1<<(CLASS_MAGE-1))|(1<<(CLASS_WARLOCK-1))) -#define PLAYER_MAX_BATTLEGROUND_QUEUES 3 +#define PLAYER_MAX_BATTLEGROUND_QUEUES 2 enum ReputationRank { @@ -695,192 +695,193 @@ enum SpellEffects enum SpellCastResult { - SPELL_FAILED_AFFECTING_COMBAT = 0x00, - SPELL_FAILED_ALREADY_AT_FULL_HEALTH = 0x01, - SPELL_FAILED_ALREADY_AT_FULL_MANA = 0x02, - SPELL_FAILED_ALREADY_AT_FULL_POWER = 0x03, - SPELL_FAILED_ALREADY_BEING_TAMED = 0x04, - SPELL_FAILED_ALREADY_HAVE_CHARM = 0x05, - SPELL_FAILED_ALREADY_HAVE_SUMMON = 0x06, - SPELL_FAILED_ALREADY_OPEN = 0x07, - SPELL_FAILED_AURA_BOUNCED = 0x08, - SPELL_FAILED_AUTOTRACK_INTERRUPTED = 0x09, - SPELL_FAILED_BAD_IMPLICIT_TARGETS = 0x0A, - SPELL_FAILED_BAD_TARGETS = 0x0B, - SPELL_FAILED_CANT_BE_CHARMED = 0x0C, - SPELL_FAILED_CANT_BE_DISENCHANTED = 0x0D, - SPELL_FAILED_CANT_BE_DISENCHANTED_SKILL = 0x0E, - SPELL_FAILED_CANT_BE_MILLED = 0x0F, - SPELL_FAILED_CANT_BE_PROSPECTED = 0x10, - SPELL_FAILED_CANT_CAST_ON_TAPPED = 0x11, - SPELL_FAILED_CANT_DUEL_WHILE_INVISIBLE = 0x12, - SPELL_FAILED_CANT_DUEL_WHILE_STEALTHED = 0x13, - SPELL_FAILED_CANT_STEALTH = 0x14, - SPELL_FAILED_CASTER_AURASTATE = 0x15, - SPELL_FAILED_CASTER_DEAD = 0x16, - SPELL_FAILED_CHARMED = 0x17, - SPELL_FAILED_CHEST_IN_USE = 0x18, - SPELL_FAILED_CONFUSED = 0x19, - SPELL_FAILED_DONT_REPORT = 0x1A, - SPELL_FAILED_EQUIPPED_ITEM = 0x1B, - SPELL_FAILED_EQUIPPED_ITEM_CLASS = 0x1C, - SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND = 0x1D, - SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND = 0x1E, - SPELL_FAILED_ERROR = 0x1F, - SPELL_FAILED_FIZZLE = 0x20, - SPELL_FAILED_FLEEING = 0x21, - SPELL_FAILED_FOOD_LOWLEVEL = 0x22, - SPELL_FAILED_HIGHLEVEL = 0x23, - SPELL_FAILED_HUNGER_SATIATED = 0x24, - SPELL_FAILED_IMMUNE = 0x25, - SPELL_FAILED_INCORRECT_AREA = 0x26, - SPELL_FAILED_INTERRUPTED = 0x27, - SPELL_FAILED_INTERRUPTED_COMBAT = 0x28, - SPELL_FAILED_ITEM_ALREADY_ENCHANTED = 0x29, - SPELL_FAILED_ITEM_GONE = 0x2A, - SPELL_FAILED_ITEM_NOT_FOUND = 0x2B, - SPELL_FAILED_ITEM_NOT_READY = 0x2C, - SPELL_FAILED_LEVEL_REQUIREMENT = 0x2D, - SPELL_FAILED_LINE_OF_SIGHT = 0x2E, - SPELL_FAILED_LOWLEVEL = 0x2F, - SPELL_FAILED_LOW_CASTLEVEL = 0x30, - SPELL_FAILED_MAINHAND_EMPTY = 0x31, - SPELL_FAILED_MOVING = 0x32, - SPELL_FAILED_NEED_AMMO = 0x33, - SPELL_FAILED_NEED_AMMO_POUCH = 0x34, - SPELL_FAILED_NEED_EXOTIC_AMMO = 0x35, - SPELL_FAILED_NEED_MORE_ITEMS = 0x36, - SPELL_FAILED_NOPATH = 0x37, - SPELL_FAILED_NOT_BEHIND = 0x38, - SPELL_FAILED_NOT_FISHABLE = 0x39, - SPELL_FAILED_NOT_FLYING = 0x3A, - SPELL_FAILED_NOT_HERE = 0x3B, - SPELL_FAILED_NOT_INFRONT = 0x3C, - SPELL_FAILED_NOT_IN_CONTROL = 0x3D, - SPELL_FAILED_NOT_KNOWN = 0x3E, - SPELL_FAILED_NOT_MOUNTED = 0x3F, - SPELL_FAILED_NOT_ON_TAXI = 0x40, - SPELL_FAILED_NOT_ON_TRANSPORT = 0x41, - SPELL_FAILED_NOT_READY = 0x42, - SPELL_FAILED_NOT_SHAPESHIFT = 0x43, - SPELL_FAILED_NOT_STANDING = 0x44, - SPELL_FAILED_NOT_TRADEABLE = 0x45, - SPELL_FAILED_NOT_TRADING = 0x46, - SPELL_FAILED_NOT_UNSHEATHED = 0x47, - SPELL_FAILED_NOT_WHILE_GHOST = 0x48, - SPELL_FAILED_NOT_WHILE_LOOTING = 0x49, - SPELL_FAILED_NO_AMMO = 0x4A, - SPELL_FAILED_NO_CHARGES_REMAIN = 0x4B, - SPELL_FAILED_NO_CHAMPION = 0x4C, - SPELL_FAILED_NO_COMBO_POINTS = 0x4D, - SPELL_FAILED_NO_DUELING = 0x4E, - SPELL_FAILED_NO_ENDURANCE = 0x4F, - SPELL_FAILED_NO_FISH = 0x50, - SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED = 0x51, - SPELL_FAILED_NO_MOUNTS_ALLOWED = 0x52, - SPELL_FAILED_NO_PET = 0x53, - SPELL_FAILED_NO_POWER = 0x54, - SPELL_FAILED_NOTHING_TO_DISPEL = 0x55, - SPELL_FAILED_NOTHING_TO_STEAL = 0x56, - SPELL_FAILED_ONLY_ABOVEWATER = 0x57, - SPELL_FAILED_ONLY_DAYTIME = 0x58, - SPELL_FAILED_ONLY_INDOORS = 0x59, - SPELL_FAILED_ONLY_MOUNTED = 0x5A, - SPELL_FAILED_ONLY_NIGHTTIME = 0x5B, - SPELL_FAILED_ONLY_OUTDOORS = 0x5C, - SPELL_FAILED_ONLY_SHAPESHIFT = 0x5D, - SPELL_FAILED_ONLY_STEALTHED = 0x5E, - SPELL_FAILED_ONLY_UNDERWATER = 0x5F, - SPELL_FAILED_OUT_OF_RANGE = 0x60, - SPELL_FAILED_PACIFIED = 0x61, - SPELL_FAILED_POSSESSED = 0x62, - SPELL_FAILED_REAGENTS = 0x63, - SPELL_FAILED_REQUIRES_AREA = 0x64, - SPELL_FAILED_REQUIRES_SPELL_FOCUS = 0x65, - SPELL_FAILED_ROOTED = 0x66, - SPELL_FAILED_SILENCED = 0x67, - SPELL_FAILED_SPELL_IN_PROGRESS = 0x68, - SPELL_FAILED_SPELL_LEARNED = 0x69, - SPELL_FAILED_SPELL_UNAVAILABLE = 0x6A, - SPELL_FAILED_STUNNED = 0x6B, - SPELL_FAILED_TARGETS_DEAD = 0x6C, - SPELL_FAILED_TARGET_AFFECTING_COMBAT = 0x6D, - SPELL_FAILED_TARGET_AURASTATE = 0x6E, - SPELL_FAILED_TARGET_DUELING = 0x6F, - SPELL_FAILED_TARGET_ENEMY = 0x70, - SPELL_FAILED_TARGET_ENRAGED = 0x71, - SPELL_FAILED_TARGET_FRIENDLY = 0x72, - SPELL_FAILED_TARGET_IN_COMBAT = 0x73, - SPELL_FAILED_TARGET_IS_PLAYER = 0x74, - SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED = 0x75, - SPELL_FAILED_TARGET_NOT_DEAD = 0x76, - SPELL_FAILED_TARGET_NOT_IN_PARTY = 0x77, - SPELL_FAILED_TARGET_NOT_LOOTED = 0x78, - SPELL_FAILED_TARGET_NOT_PLAYER = 0x79, - SPELL_FAILED_TARGET_NO_POCKETS = 0x7A, - SPELL_FAILED_TARGET_NO_WEAPONS = 0x7B, - SPELL_FAILED_TARGET_NO_RANGED_WEAPONS = 0x7C, - SPELL_FAILED_TARGET_UNSKINNABLE = 0x7D, - SPELL_FAILED_THIRST_SATIATED = 0x7E, - SPELL_FAILED_TOO_CLOSE = 0x7F, - SPELL_FAILED_TOO_MANY_OF_ITEM = 0x80, - SPELL_FAILED_TOTEM_CATEGORY = 0x81, - SPELL_FAILED_TOTEMS = 0x82, - SPELL_FAILED_TRY_AGAIN = 0x83, - SPELL_FAILED_UNIT_NOT_BEHIND = 0x84, - SPELL_FAILED_UNIT_NOT_INFRONT = 0x85, - SPELL_FAILED_WRONG_PET_FOOD = 0x86, - SPELL_FAILED_NOT_WHILE_FATIGUED = 0x87, - SPELL_FAILED_TARGET_NOT_IN_INSTANCE = 0x88, - SPELL_FAILED_NOT_WHILE_TRADING = 0x89, - SPELL_FAILED_TARGET_NOT_IN_RAID = 0x8A, - SPELL_FAILED_TARGET_FREEFORALL = 0x8B, - SPELL_FAILED_NO_EDIBLE_CORPSES = 0x8C, - SPELL_FAILED_ONLY_BATTLEGROUNDS = 0x8D, - SPELL_FAILED_TARGET_NOT_GHOST = 0x8E, - SPELL_FAILED_TRANSFORM_UNUSABLE = 0x8F, - SPELL_FAILED_WRONG_WEATHER = 0x90, - SPELL_FAILED_DAMAGE_IMMUNE = 0x91, - SPELL_FAILED_PREVENTED_BY_MECHANIC = 0x92, - SPELL_FAILED_PLAY_TIME = 0x93, - SPELL_FAILED_REPUTATION = 0x94, - SPELL_FAILED_MIN_SKILL = 0x95, - SPELL_FAILED_NOT_IN_ARENA = 0x96, - SPELL_FAILED_NOT_ON_SHAPESHIFT = 0x97, - SPELL_FAILED_NOT_ON_STEALTHED = 0x98, - SPELL_FAILED_NOT_ON_DAMAGE_IMMUNE = 0x99, - SPELL_FAILED_NOT_ON_MOUNTED = 0x9A, - SPELL_FAILED_TOO_SHALLOW = 0x9B, - SPELL_FAILED_TARGET_NOT_IN_SANCTUARY = 0x9C, - SPELL_FAILED_TARGET_IS_TRIVIAL = 0x9D, - SPELL_FAILED_BM_OR_INVISGOD = 0x9E, - SPELL_FAILED_EXPERT_RIDING_REQUIREMENT = 0x9F, - SPELL_FAILED_ARTISAN_RIDING_REQUIREMENT = 0xA0, - SPELL_FAILED_NOT_IDLE = 0xA1, - SPELL_FAILED_NOT_INACTIVE = 0xA2, - SPELL_FAILED_PARTIAL_PLAYTIME = 0xA3, - SPELL_FAILED_NO_PLAYTIME = 0xA4, - SPELL_FAILED_NOT_IN_BATTLEGROUND = 0xA5, - SPELL_FAILED_NOT_IN_RAID_INSTANCE = 0xA6, - SPELL_FAILED_ONLY_IN_ARENA = 0xA7, - SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE = 0xA8, - SPELL_FAILED_ON_USE_ENCHANT = 0xA9, - SPELL_FAILED_NOT_ON_GROUND = 0xAA, - SPELL_FAILED_CUSTOM_ERROR = 0xAB, - SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW = 0xAC, - SPELL_FAILED_TOO_MANY_SOCKETS = 0xAD, - SPELL_FAILED_INVALID_GLYPH = 0xAE, - SPELL_FAILED_UNIQUE_GLYPH = 0xAF, - SPELL_FAILED_GLYPH_SOCKET_LOCKED = 0xB0, - SPELL_FAILED_NO_VALID_TARGETS = 0xB1, - SPELL_FAILED_ITEM_AT_MAX_CHARGES = 0xB2, - SPELL_FAILED_NOT_IN_BARBERSHOP = 0xB3, - SPELL_FAILED_FISHING_TOO_LOW = 0xB4, - SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW = 0xB5, - SPELL_FAILED_SUMMON_PENDING = 0xB6, - SPELL_FAILED_MAX_SOCKETS = 0xB7, - SPELL_FAILED_PET_CAN_RENAME = 0xB8, - SPELL_FAILED_UNKNOWN = 0xB9, + SPELL_FAILED_SUCCESS = 0x00, + SPELL_FAILED_AFFECTING_COMBAT = 0x01, + SPELL_FAILED_ALREADY_AT_FULL_HEALTH = 0x02, + SPELL_FAILED_ALREADY_AT_FULL_MANA = 0x03, + SPELL_FAILED_ALREADY_AT_FULL_POWER = 0x04, + SPELL_FAILED_ALREADY_BEING_TAMED = 0x05, + SPELL_FAILED_ALREADY_HAVE_CHARM = 0x06, + SPELL_FAILED_ALREADY_HAVE_SUMMON = 0x07, + SPELL_FAILED_ALREADY_OPEN = 0x08, + SPELL_FAILED_AURA_BOUNCED = 0x09, + SPELL_FAILED_AUTOTRACK_INTERRUPTED = 0x0A, + SPELL_FAILED_BAD_IMPLICIT_TARGETS = 0x0B, + SPELL_FAILED_BAD_TARGETS = 0x0C, + SPELL_FAILED_CANT_BE_CHARMED = 0x0D, + SPELL_FAILED_CANT_BE_DISENCHANTED = 0x0E, + SPELL_FAILED_CANT_BE_DISENCHANTED_SKILL = 0x0F, + SPELL_FAILED_CANT_BE_MILLED = 0x10, + SPELL_FAILED_CANT_BE_PROSPECTED = 0x11, + SPELL_FAILED_CANT_CAST_ON_TAPPED = 0x12, + SPELL_FAILED_CANT_DUEL_WHILE_INVISIBLE = 0x13, + SPELL_FAILED_CANT_DUEL_WHILE_STEALTHED = 0x14, + SPELL_FAILED_CANT_STEALTH = 0x15, + SPELL_FAILED_CASTER_AURASTATE = 0x16, + SPELL_FAILED_CASTER_DEAD = 0x17, + SPELL_FAILED_CHARMED = 0x18, + SPELL_FAILED_CHEST_IN_USE = 0x19, + SPELL_FAILED_CONFUSED = 0x1A, + SPELL_FAILED_DONT_REPORT = 0x1B, + SPELL_FAILED_EQUIPPED_ITEM = 0x1C, + SPELL_FAILED_EQUIPPED_ITEM_CLASS = 0x1D, + SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND = 0x1E, + SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND = 0x1F, + SPELL_FAILED_ERROR = 0x20, + SPELL_FAILED_FIZZLE = 0x21, + SPELL_FAILED_FLEEING = 0x22, + SPELL_FAILED_FOOD_LOWLEVEL = 0x23, + SPELL_FAILED_HIGHLEVEL = 0x24, + SPELL_FAILED_HUNGER_SATIATED = 0x25, + SPELL_FAILED_IMMUNE = 0x26, + SPELL_FAILED_INCORRECT_AREA = 0x27, + SPELL_FAILED_INTERRUPTED = 0x28, + SPELL_FAILED_INTERRUPTED_COMBAT = 0x29, + SPELL_FAILED_ITEM_ALREADY_ENCHANTED = 0x2A, + SPELL_FAILED_ITEM_GONE = 0x2B, + SPELL_FAILED_ITEM_NOT_FOUND = 0x2C, + SPELL_FAILED_ITEM_NOT_READY = 0x2D, + SPELL_FAILED_LEVEL_REQUIREMENT = 0x2E, + SPELL_FAILED_LINE_OF_SIGHT = 0x2F, + SPELL_FAILED_LOWLEVEL = 0x30, + SPELL_FAILED_LOW_CASTLEVEL = 0x31, + SPELL_FAILED_MAINHAND_EMPTY = 0x32, + SPELL_FAILED_MOVING = 0x33, + SPELL_FAILED_NEED_AMMO = 0x34, + SPELL_FAILED_NEED_AMMO_POUCH = 0x35, + SPELL_FAILED_NEED_EXOTIC_AMMO = 0x36, + SPELL_FAILED_NEED_MORE_ITEMS = 0x37, + SPELL_FAILED_NOPATH = 0x38, + SPELL_FAILED_NOT_BEHIND = 0x39, + SPELL_FAILED_NOT_FISHABLE = 0x3A, + SPELL_FAILED_NOT_FLYING = 0x3B, + SPELL_FAILED_NOT_HERE = 0x3C, + SPELL_FAILED_NOT_INFRONT = 0x3D, + SPELL_FAILED_NOT_IN_CONTROL = 0x3E, + SPELL_FAILED_NOT_KNOWN = 0x3F, + SPELL_FAILED_NOT_MOUNTED = 0x40, + SPELL_FAILED_NOT_ON_TAXI = 0x41, + SPELL_FAILED_NOT_ON_TRANSPORT = 0x42, + SPELL_FAILED_NOT_READY = 0x43, + SPELL_FAILED_NOT_SHAPESHIFT = 0x44, + SPELL_FAILED_NOT_STANDING = 0x45, + SPELL_FAILED_NOT_TRADEABLE = 0x46, + SPELL_FAILED_NOT_TRADING = 0x47, + SPELL_FAILED_NOT_UNSHEATHED = 0x48, + SPELL_FAILED_NOT_WHILE_GHOST = 0x49, + SPELL_FAILED_NOT_WHILE_LOOTING = 0x4A, + SPELL_FAILED_NO_AMMO = 0x4B, + SPELL_FAILED_NO_CHARGES_REMAIN = 0x4C, + SPELL_FAILED_NO_CHAMPION = 0x4D, + SPELL_FAILED_NO_COMBO_POINTS = 0x4E, + SPELL_FAILED_NO_DUELING = 0x4F, + SPELL_FAILED_NO_ENDURANCE = 0x50, + SPELL_FAILED_NO_FISH = 0x51, + SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED = 0x52, + SPELL_FAILED_NO_MOUNTS_ALLOWED = 0x53, + SPELL_FAILED_NO_PET = 0x54, + SPELL_FAILED_NO_POWER = 0x55, + SPELL_FAILED_NOTHING_TO_DISPEL = 0x56, + SPELL_FAILED_NOTHING_TO_STEAL = 0x57, + SPELL_FAILED_ONLY_ABOVEWATER = 0x58, + SPELL_FAILED_ONLY_DAYTIME = 0x59, + SPELL_FAILED_ONLY_INDOORS = 0x5A, + SPELL_FAILED_ONLY_MOUNTED = 0x5B, + SPELL_FAILED_ONLY_NIGHTTIME = 0x5C, + SPELL_FAILED_ONLY_OUTDOORS = 0x5D, + SPELL_FAILED_ONLY_SHAPESHIFT = 0x5E, + SPELL_FAILED_ONLY_STEALTHED = 0x5F, + SPELL_FAILED_ONLY_UNDERWATER = 0x60, + SPELL_FAILED_OUT_OF_RANGE = 0x61, + SPELL_FAILED_PACIFIED = 0x62, + SPELL_FAILED_POSSESSED = 0x63, + SPELL_FAILED_REAGENTS = 0x64, + SPELL_FAILED_REQUIRES_AREA = 0x65, + SPELL_FAILED_REQUIRES_SPELL_FOCUS = 0x66, + SPELL_FAILED_ROOTED = 0x67, + SPELL_FAILED_SILENCED = 0x68, + SPELL_FAILED_SPELL_IN_PROGRESS = 0x69, + SPELL_FAILED_SPELL_LEARNED = 0x6A, + SPELL_FAILED_SPELL_UNAVAILABLE = 0x6B, + SPELL_FAILED_STUNNED = 0x6C, + SPELL_FAILED_TARGETS_DEAD = 0x6D, + SPELL_FAILED_TARGET_AFFECTING_COMBAT = 0x6E, + SPELL_FAILED_TARGET_AURASTATE = 0x6F, + SPELL_FAILED_TARGET_DUELING = 0x70, + SPELL_FAILED_TARGET_ENEMY = 0x71, + SPELL_FAILED_TARGET_ENRAGED = 0x72, + SPELL_FAILED_TARGET_FRIENDLY = 0x73, + SPELL_FAILED_TARGET_IN_COMBAT = 0x74, + SPELL_FAILED_TARGET_IS_PLAYER = 0x75, + SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED = 0x76, + SPELL_FAILED_TARGET_NOT_DEAD = 0x77, + SPELL_FAILED_TARGET_NOT_IN_PARTY = 0x78, + SPELL_FAILED_TARGET_NOT_LOOTED = 0x79, + SPELL_FAILED_TARGET_NOT_PLAYER = 0x7A, + SPELL_FAILED_TARGET_NO_POCKETS = 0x7B, + SPELL_FAILED_TARGET_NO_WEAPONS = 0x7C, + SPELL_FAILED_TARGET_NO_RANGED_WEAPONS = 0x7D, + SPELL_FAILED_TARGET_UNSKINNABLE = 0x7E, + SPELL_FAILED_THIRST_SATIATED = 0x7F, + SPELL_FAILED_TOO_CLOSE = 0x80, + SPELL_FAILED_TOO_MANY_OF_ITEM = 0x81, + SPELL_FAILED_TOTEM_CATEGORY = 0x82, + SPELL_FAILED_TOTEMS = 0x83, + SPELL_FAILED_TRY_AGAIN = 0x84, + SPELL_FAILED_UNIT_NOT_BEHIND = 0x85, + SPELL_FAILED_UNIT_NOT_INFRONT = 0x86, + SPELL_FAILED_WRONG_PET_FOOD = 0x87, + SPELL_FAILED_NOT_WHILE_FATIGUED = 0x88, + SPELL_FAILED_TARGET_NOT_IN_INSTANCE = 0x89, + SPELL_FAILED_NOT_WHILE_TRADING = 0x8A, + SPELL_FAILED_TARGET_NOT_IN_RAID = 0x8B, + SPELL_FAILED_TARGET_FREEFORALL = 0x8C, + SPELL_FAILED_NO_EDIBLE_CORPSES = 0x8D, + SPELL_FAILED_ONLY_BATTLEGROUNDS = 0x8E, + SPELL_FAILED_TARGET_NOT_GHOST = 0x8F, + SPELL_FAILED_TRANSFORM_UNUSABLE = 0x90, + SPELL_FAILED_WRONG_WEATHER = 0x91, + SPELL_FAILED_DAMAGE_IMMUNE = 0x92, + SPELL_FAILED_PREVENTED_BY_MECHANIC = 0x93, + SPELL_FAILED_PLAY_TIME = 0x94, + SPELL_FAILED_REPUTATION = 0x95, + SPELL_FAILED_MIN_SKILL = 0x96, + SPELL_FAILED_NOT_IN_ARENA = 0x97, + SPELL_FAILED_NOT_ON_SHAPESHIFT = 0x98, + SPELL_FAILED_NOT_ON_STEALTHED = 0x99, + SPELL_FAILED_NOT_ON_DAMAGE_IMMUNE = 0x9A, + SPELL_FAILED_NOT_ON_MOUNTED = 0x9B, + SPELL_FAILED_TOO_SHALLOW = 0x9C, + SPELL_FAILED_TARGET_NOT_IN_SANCTUARY = 0x9D, + SPELL_FAILED_TARGET_IS_TRIVIAL = 0x9E, + SPELL_FAILED_BM_OR_INVISGOD = 0x9F, + SPELL_FAILED_EXPERT_RIDING_REQUIREMENT = 0xA0, + SPELL_FAILED_ARTISAN_RIDING_REQUIREMENT = 0xA1, + SPELL_FAILED_NOT_IDLE = 0xA2, + SPELL_FAILED_NOT_INACTIVE = 0xA3, + SPELL_FAILED_PARTIAL_PLAYTIME = 0xA4, + SPELL_FAILED_NO_PLAYTIME = 0xA5, + SPELL_FAILED_NOT_IN_BATTLEGROUND = 0xA6, + SPELL_FAILED_NOT_IN_RAID_INSTANCE = 0xA7, + SPELL_FAILED_ONLY_IN_ARENA = 0xA8, + SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE = 0xA9, + SPELL_FAILED_ON_USE_ENCHANT = 0xAA, + SPELL_FAILED_NOT_ON_GROUND = 0xAB, + SPELL_FAILED_CUSTOM_ERROR = 0xAC, + SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW = 0xAD, + SPELL_FAILED_TOO_MANY_SOCKETS = 0xAE, + SPELL_FAILED_INVALID_GLYPH = 0xAF, + SPELL_FAILED_UNIQUE_GLYPH = 0xB0, + SPELL_FAILED_GLYPH_SOCKET_LOCKED = 0xB1, + SPELL_FAILED_NO_VALID_TARGETS = 0xB2, + SPELL_FAILED_ITEM_AT_MAX_CHARGES = 0xB3, + SPELL_FAILED_NOT_IN_BARBERSHOP = 0xB4, + SPELL_FAILED_FISHING_TOO_LOW = 0xB5, + SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW = 0xB6, + SPELL_FAILED_SUMMON_PENDING = 0xB7, + SPELL_FAILED_MAX_SOCKETS = 0xB8, + SPELL_FAILED_PET_CAN_RENAME = 0xB9, + SPELL_FAILED_UNKNOWN = 0xBA, SPELL_CAST_OK = 0xFF // custom value, don't must be send to client }; @@ -2282,8 +2283,8 @@ enum ChatMsg CHAT_MSG_OFFICER = 0x05, CHAT_MSG_YELL = 0x06, CHAT_MSG_WHISPER = 0x07, - CHAT_MSG_WHISPER_INFORM = 0x08, - CHAT_MSG_REPLY = 0x09, + CHAT_MSG_WHISPER_INFORM = 0x08, // WHISPER_FOREIGN? + CHAT_MSG_REPLY = 0x09, // WHISPER_INFORM? CHAT_MSG_EMOTE = 0x0A, CHAT_MSG_TEXT_EMOTE = 0x0B, CHAT_MSG_MONSTER_SAY = 0x0C, @@ -2407,11 +2408,23 @@ enum DiminishingGroup DIMINISHING_LIMITONLY }; -enum DungeonDifficulties +enum Difficulty +{ + DUNGEON_DIFFICULTY_NORMAL = 0, + DUNGEON_DIFFICULTY_HEROIC = 1, + + RAID_DIFFICULTY_10MAN_NORMAL = 0, + RAID_DIFFICULTY_25MAN_NORMAL = 1, + RAID_DIFFICULTY_10MAN_HEROIC = 2, + RAID_DIFFICULTY_25MAN_HEROIC = 3, +}; + +#define MAX_DUNGEON_DIFFICULTY 2 +#define MAX_RAID_DIFFICULTY 4 +#define MAX_DIFFICULTY 4 + +enum RaidDifficulties { - DIFFICULTY_NORMAL = 0, - DIFFICULTY_HEROIC = 1, - TOTAL_DIFFICULTIES }; enum SummonType @@ -2514,42 +2527,50 @@ enum ResponseCodes CHAR_CREATE_EXPANSION_CLASS = 0x3A, CHAR_CREATE_LEVEL_REQUIREMENT = 0x3B, CHAR_CREATE_UNIQUE_CLASS_LIMIT = 0x3C, + CHAR_CREATE_CHARACTER_IN_GUILD = 0x3D, + CHAR_CREATE_RESTRICTED_RACECLASS = 0x3E, + CHAR_CREATE_CHARACTER_CHOOSE_RACE = 0x3F, + CHAR_CREATE_CHARACTER_ARENA_LEADER = 0x40, + CHAR_CREATE_CHARACTER_DELETE_MAIL = 0x41, + CHAR_CREATE_CHARACTER_SWAP_FACTION = 0x42, + CHAR_CREATE_CHARACTER_RACE_ONLY = 0x43, + CHAR_CREATE_CHARACTER_GOLD_LIMIT = 0x44, - CHAR_DELETE_IN_PROGRESS = 0x3D, - CHAR_DELETE_SUCCESS = 0x3E, - CHAR_DELETE_FAILED = 0x3F, - CHAR_DELETE_FAILED_LOCKED_FOR_TRANSFER = 0x40, - CHAR_DELETE_FAILED_GUILD_LEADER = 0x41, - CHAR_DELETE_FAILED_ARENA_CAPTAIN = 0x42, + CHAR_DELETE_IN_PROGRESS = 0x45, + CHAR_DELETE_SUCCESS = 0x46, + CHAR_DELETE_FAILED = 0x47, + CHAR_DELETE_FAILED_LOCKED_FOR_TRANSFER = 0x48, + CHAR_DELETE_FAILED_GUILD_LEADER = 0x49, + CHAR_DELETE_FAILED_ARENA_CAPTAIN = 0x4A, - CHAR_LOGIN_IN_PROGRESS = 0x43, - CHAR_LOGIN_SUCCESS = 0x44, - CHAR_LOGIN_NO_WORLD = 0x45, - CHAR_LOGIN_DUPLICATE_CHARACTER = 0x46, - CHAR_LOGIN_NO_INSTANCES = 0x47, - CHAR_LOGIN_FAILED = 0x48, - CHAR_LOGIN_DISABLED = 0x49, - CHAR_LOGIN_NO_CHARACTER = 0x4A, - CHAR_LOGIN_LOCKED_FOR_TRANSFER = 0x4B, - CHAR_LOGIN_LOCKED_BY_BILLING = 0x4C, + CHAR_LOGIN_IN_PROGRESS = 0x4B, + CHAR_LOGIN_SUCCESS = 0x4C, + CHAR_LOGIN_NO_WORLD = 0x4D, + CHAR_LOGIN_DUPLICATE_CHARACTER = 0x4E, + CHAR_LOGIN_NO_INSTANCES = 0x4F, + CHAR_LOGIN_FAILED = 0x50, + CHAR_LOGIN_DISABLED = 0x51, + CHAR_LOGIN_NO_CHARACTER = 0x52, + CHAR_LOGIN_LOCKED_FOR_TRANSFER = 0x53, + CHAR_LOGIN_LOCKED_BY_BILLING = 0x54, - CHAR_NAME_SUCCESS = 0x4D, - CHAR_NAME_FAILURE = 0x4E, - CHAR_NAME_NO_NAME = 0x4F, - CHAR_NAME_TOO_SHORT = 0x50, - CHAR_NAME_TOO_LONG = 0x51, - CHAR_NAME_INVALID_CHARACTER = 0x52, - CHAR_NAME_MIXED_LANGUAGES = 0x53, - CHAR_NAME_PROFANE = 0x54, - CHAR_NAME_RESERVED = 0x55, - CHAR_NAME_INVALID_APOSTROPHE = 0x56, - CHAR_NAME_MULTIPLE_APOSTROPHES = 0x57, - CHAR_NAME_THREE_CONSECUTIVE = 0x58, - CHAR_NAME_INVALID_SPACE = 0x59, - CHAR_NAME_CONSECUTIVE_SPACES = 0x5A, - CHAR_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS = 0x5B, - CHAR_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END = 0x5C, - CHAR_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 0x5D + CHAR_NAME_SUCCESS = 0x55, + CHAR_NAME_FAILURE = 0x56, + CHAR_NAME_NO_NAME = 0x57, + CHAR_NAME_TOO_SHORT = 0x58, + CHAR_NAME_TOO_LONG = 0x59, + CHAR_NAME_INVALID_CHARACTER = 0x5A, + CHAR_NAME_MIXED_LANGUAGES = 0x5B, + CHAR_NAME_PROFANE = 0x5C, + CHAR_NAME_RESERVED = 0x5D, + CHAR_NAME_INVALID_APOSTROPHE = 0x5E, + CHAR_NAME_MULTIPLE_APOSTROPHES = 0x5F, + CHAR_NAME_THREE_CONSECUTIVE = 0x60, + CHAR_NAME_INVALID_SPACE = 0x61, + CHAR_NAME_CONSECUTIVE_SPACES = 0x62, + CHAR_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS = 0x63, + CHAR_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END = 0x64, + CHAR_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 0x65 }; /// Ban function modes @@ -2582,9 +2603,11 @@ enum BattleGroundTypeId BATTLEGROUND_RL = 8, BATTLEGROUND_SA = 9, BATTLEGROUND_DS = 10, - BATTLEGROUND_RV = 11 + BATTLEGROUND_RV = 11, + BATTLEGROUND_IC = 30, + BATTLEGROUND_ABG = 32 }; -#define MAX_BATTLEGROUND_TYPE_ID 12 +#define MAX_BATTLEGROUND_TYPE_ID 33 enum MailResponseType { diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 17c72034e..8a68ea7ff 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -239,7 +239,10 @@ bool SpellCastTargets::read ( WorldPacket * data, Unit *caster ) if( m_targetMask & TARGET_FLAG_SOURCE_LOCATION ) { - if(data->rpos() + 4 + 4 + 4 > data->size()) + if(data->rpos() + 1 + 4 + 4 + 4 > data->size()) + return false; + + if(!data->readPackGUID(m_unitTargetGUID)) return false; *data >> m_srcX >> m_srcY >> m_srcZ; @@ -308,7 +311,14 @@ void SpellCastTargets::write ( WorldPacket * data ) } if( m_targetMask & TARGET_FLAG_SOURCE_LOCATION ) + { + if(m_unitTarget) + data->append(m_unitTarget->GetPackGUID()); + else + *data << uint8(0); + *data << m_srcX << m_srcY << m_srcZ; + } if( m_targetMask & TARGET_FLAG_DEST_LOCATION ) { @@ -3119,6 +3129,12 @@ void Spell::SendSpellStart() if ( castFlags & CAST_FLAG_AMMO ) WriteAmmoToPacket(&data); + if ( castFlags & CAST_FLAG_UNKNOWN21 ) + { + data << uint32(0); + data << uint32(0); + } + m_caster->SendMessageToSet(&data, true); } @@ -3449,7 +3465,7 @@ void Spell::SendChannelUpdate(uint32 time) { if(time == 0) { - m_caster->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, 0); + m_caster->SetChannelObjectGUID(0); m_caster->SetUInt32Value(UNIT_CHANNEL_SPELL, 0); } @@ -3503,7 +3519,7 @@ void Spell::SendChannelStart(uint32 duration) m_timer = duration; if(target) - m_caster->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, target->GetGUID()); + m_caster->SetChannelObjectGUID(target->GetGUID()); m_caster->SetUInt32Value(UNIT_CHANNEL_SPELL, m_spellInfo->Id); } @@ -5687,9 +5703,7 @@ bool Spell::CheckTargetCreatureType(Unit* target) const uint32 spellCreatureTargetMask = m_spellInfo->TargetCreatureType; // Curse of Doom & Exorcism: not find another way to fix spell target check :/ - if (m_spellInfo->SpellFamilyName==SPELLFAMILY_WARLOCK && m_spellInfo->Category == 1179 || - // TODO: will be removed in 3.2.x - m_spellInfo->SpellFamilyName==SPELLFAMILY_PALADIN && m_spellInfo->Category == 19) + if (m_spellInfo->SpellFamilyName==SPELLFAMILY_WARLOCK && m_spellInfo->Category == 1179) { // not allow cast at player if(target->GetTypeId()==TYPEID_PLAYER) diff --git a/src/game/Spell.h b/src/game/Spell.h index 4dbccc58a..bda3a1871 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -77,7 +77,8 @@ enum SpellCastFlags CAST_FLAG_UNKNOWN10 = 0x00040000, CAST_FLAG_UNKNOWN5 = 0x00080000, // wotlk CAST_FLAG_UNKNOWN20 = 0x00100000, - CAST_FLAG_UNKNOWN7 = 0x00200000 // wotlk, rune cooldown list + CAST_FLAG_UNKNOWN7 = 0x00200000, // wotlk, rune cooldown list + CAST_FLAG_UNKNOWN21 = 0x04000000 }; enum SpellNotifyPushType diff --git a/src/game/SpellAuraDefines.h b/src/game/SpellAuraDefines.h index 602a3050b..10b4fd3e5 100644 --- a/src/game/SpellAuraDefines.h +++ b/src/game/SpellAuraDefines.h @@ -337,7 +337,19 @@ enum AuraType SPELL_AURA_292, SPELL_AURA_293, SPELL_AURA_294, - TOTAL_AURAS = 295 + SPELL_AURA_295, + SPELL_AURA_296, + SPELL_AURA_297, + SPELL_AURA_298, + SPELL_AURA_299, + SPELL_AURA_300, + SPELL_AURA_301, + SPELL_AURA_302, + SPELL_AURA_303, + SPELL_AURA_304, + SPELL_AURA_305, + SPELL_AURA_306, + TOTAL_AURAS = 307 }; enum AreaAuraType diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index bbcb5f041..606fd3f9c 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -311,8 +311,8 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleNULL, //258 SPELL_AURA_MOD_SPELL_VISUAL &Aura::HandleNULL, //259 corrupt healing over time spell &Aura::HandleNoImmediateEffect, //260 SPELL_AURA_SCREEN_EFFECT (miscvalue = id in ScreenEffect.dbc) not required any code - &Aura::HandlePhase, //261 SPELL_AURA_PHASE undetactable invisibility? implemented in Unit::isVisibleForOrDetect - &Aura::HandleNULL, //262 + &Aura::HandlePhase, //261 SPELL_AURA_PHASE undetectable invisibility? implemented in Unit::isVisibleForOrDetect + &Aura::HandleNULL, //262 ignore combat/aura state? &Aura::HandleNULL, //263 SPELL_AURA_ALLOW_ONLY_ABILITY player can use only abilities set in SpellClassMask &Aura::HandleUnused, //264 unused (3.0.8a) &Aura::HandleUnused, //265 unused (3.0.8a) @@ -323,7 +323,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleNULL, //270 SPELL_AURA_MOD_IGNORE_TARGET_RESIST &Aura::HandleNoImmediateEffect, //271 SPELL_AURA_MOD_DAMAGE_FROM_CASTER implemented in Unit::SpellDamageBonus &Aura::HandleNULL, //272 reduce spell cast time? - &Aura::HandleNULL, //273 + &Aura::HandleNULL, //273 x-ray effect &Aura::HandleNULL, //274 proc free shot? &Aura::HandleNoImmediateEffect, //275 SPELL_AURA_MOD_IGNORE_SHAPESHIFT Use SpellClassMask for spell select &Aura::HandleNULL, //276 mod damage % mechanic? @@ -334,17 +334,29 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleNULL, //281 SPELL_AURA_MOD_HONOR_GAIN &Aura::HandleAuraIncreaseBaseHealthPercent, //282 SPELL_AURA_INCREASE_BASE_HEALTH_PERCENT &Aura::HandleNoImmediateEffect, //283 SPELL_AURA_MOD_HEALING_RECEIVED implemented in Unit::SpellHealingBonus - &Aura::HandleUnused, //284 not used by any spells (3.08a) + &Aura::HandleUnused, //284 51 spells &Aura::HandleAuraModAttackPowerOfArmor, //285 SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR implemented in Player::UpdateAttackPowerAndDamage &Aura::HandleNoImmediateEffect, //286 SPELL_AURA_ABILITY_PERIODIC_CRIT implemented in Aura::IsCritFromAbilityAura called from Aura::PeriodicTick &Aura::HandleNoImmediateEffect, //287 SPELL_AURA_DEFLECT_SPELLS implemented in Unit::MagicSpellHitResult and Unit::MeleeSpellHitResult - &Aura::HandleUnused, //288 not used by any spells (3.09) except 1 test spell. + &Aura::HandleUnused, //288 increase parry/deflect, prevent attack &Aura::HandleUnused, //289 unused &Aura::HandleAuraModAllCritChance, //290 SPELL_AURA_MOD_ALL_CRIT_CHANCE - &Aura::HandleUnused, //291 unused + &Aura::HandleUnused, //291 1 spell (+pct experience bonus) &Aura::HandleNULL, //292 call stabled pet - &Aura::HandleNULL, //293 2 test spells - &Aura::HandleNULL //294 2 spells, possible prevent mana regen + &Aura::HandleNULL, //293 3 spells + &Aura::HandleNULL, //294 2 spells, possible prevent mana regen + &Aura::HandleNULL, //295 unused + &Aura::HandleNULL, //296 2 spells + &Aura::HandleNULL, //297 1 spell (counter spell school?) + &Aura::HandleNULL, //298 unused + &Aura::HandleNULL, //299 unused + &Aura::HandleNULL, //300 3 spells (share damage?) + &Aura::HandleNULL, //301 5 spells + &Aura::HandleNULL, //302 unused + &Aura::HandleNULL, //303 17 spells + &Aura::HandleNULL, //304 2 spells (alcohol effect?) + &Aura::HandleNULL, //305 2 spells + &Aura::HandleNULL //306 1 spell }; static AuraType const frozenAuraTypes[] = { SPELL_AURA_MOD_ROOT, SPELL_AURA_MOD_STUN, SPELL_AURA_NONE }; @@ -529,7 +541,7 @@ SingleEnemyTargetAura::SingleEnemyTargetAura(SpellEntry const* spellproto, uint3 Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target, caster, castItem) { if (caster) - m_casters_target_guid = caster->GetTypeId()==TYPEID_PLAYER ? ((Player*)caster)->GetSelection() : caster->GetUInt64Value(UNIT_FIELD_TARGET); + m_casters_target_guid = caster->GetTypeId()==TYPEID_PLAYER ? ((Player*)caster)->GetSelection() : caster->GetTargetGUID(); else m_casters_target_guid = 0; } @@ -2133,6 +2145,11 @@ void Aura::TriggerSpell() case 33525: target->CastSpell(target, trigger_spell_id, true); return; + // Beacon of Light + case 53563: + // original caster must be target (beacon) + m_target->CastSpell(m_target,trigger_spell_id,true,NULL,this,m_target->GetGUID()); + return; } } @@ -2439,9 +2456,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real) break; } case SPELLFAMILY_MAGE: - { break; - } case SPELLFAMILY_PRIEST: { // Pain and Suffering @@ -2465,19 +2480,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real) break; } case SPELLFAMILY_PALADIN: - { - // Beacon of Light - if (GetId() == 53563) - { - if(apply) - // original caster must be target (beacon) - m_target->CastSpell(m_target,53651,true,NULL,this,m_target->GetGUID()); - else - m_target->RemoveAurasByCasterSpell(53651,m_target->GetGUID()); - return; - } break; - } case SPELLFAMILY_DRUID: { switch(GetId()) @@ -2550,8 +2553,8 @@ void Aura::HandleAuraDummy(bool apply, bool Real) return; // have a look if there is still some other Lifebloom dummy aura - Unit::AuraList auras = m_target->GetAurasByType(SPELL_AURA_DUMMY); - for(Unit::AuraList::iterator itr = auras.begin(); itr!=auras.end(); ++itr) + Unit::AuraList const& auras = m_target->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr) if((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID && ((*itr)->GetSpellProto()->SpellFamilyFlags & UI64LIT(0x1000000000))) return; @@ -3652,7 +3655,7 @@ void Aura::HandleAuraModStun(bool apply, bool Real) m_target->ModifyAuraState(AURA_STATE_FROZEN, apply); m_target->addUnitState(UNIT_STAT_STUNNED); - m_target->SetUInt64Value(UNIT_FIELD_TARGET, 0); + m_target->SetTargetGUID(0); m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); m_target->CastStop(m_target->GetGUID() == GetCasterGUID() ? GetId() : 0); @@ -3722,7 +3725,7 @@ void Aura::HandleAuraModStun(bool apply, bool Real) if(!m_target->hasUnitState(UNIT_STAT_ROOT)) // prevent allow move if have also root effect { if(m_target->getVictim() && m_target->isAlive()) - m_target->SetUInt64Value(UNIT_FIELD_TARGET,m_target->getVictim()->GetGUID() ); + m_target->SetTargetGUID(m_target->getVictim()->GetGUID()); WorldPacket data(SMSG_FORCE_MOVE_UNROOT, 8+4); data.append(m_target->GetPackGUID()); @@ -3926,8 +3929,8 @@ void Aura::HandleAuraModRoot(bool apply, bool Real) m_target->ModifyAuraState(AURA_STATE_FROZEN, apply); m_target->addUnitState(UNIT_STAT_ROOT); - m_target->SetUInt64Value (UNIT_FIELD_TARGET, 0); - // probably wrong (this add skinable flag) + m_target->SetTargetGUID(0); + // probably wrong (this add skinnable flag) // TODO: find correct flag //m_target->SetFlag(UNIT_FIELD_FLAGS,(apply_stat<<16)); @@ -3978,14 +3981,14 @@ void Aura::HandleAuraModRoot(bool apply, bool Real) return; m_target->clearUnitState(UNIT_STAT_ROOT); - // probably wrong (this add skinable flag) + // probably wrong (this add skinnable flag) // TODO: find correct flag //m_target->RemoveFlag(UNIT_FIELD_FLAGS,(apply_stat<<16)); if(!m_target->hasUnitState(UNIT_STAT_STUNNED)) // prevent allow move if have also stun effect { if(m_target->getVictim() && m_target->isAlive()) - m_target->SetUInt64Value (UNIT_FIELD_TARGET, m_target->getVictim()->GetGUID() ); + m_target->SetTargetGUID(m_target->getVictim()->GetGUID()); if(m_target->GetTypeId() == TYPEID_PLAYER) { @@ -4988,8 +4991,7 @@ void Aura::HandleAuraModIncreaseHealth(bool apply, bool Real) case 12976: // Warrior Last Stand triggered spell case 28726: // Nightmare Seed ( Nightmare Seed ) case 34511: // Valor (Bulwark of Kings, Bulwark of the Ancient Kings) - // FIXME: add case 67596: in 3.2.x - case 44055: case 55915: case 55917: // Tremendous Fortitude (Battlemaster's Alacrity) + case 44055: case 55915: case 55917: case 67596: // Tremendous Fortitude (Battlemaster's Alacrity) case 50322: // Survival Instincts case 54443: // Demonic Empowerment (Voidwalker) { diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index c8dcaa97c..e7d9587cc 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -543,7 +543,7 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) for (int i=0; i< doses; i++) unitTarget->RemoveSingleSpellAurasFromStack(spellId); damage *= doses; - damage += int32(((Player*)m_caster)->GetTotalAttackPowerValue(BASE_ATTACK) * 0.03f * doses); + damage += int32(((Player*)m_caster)->GetTotalAttackPowerValue(BASE_ATTACK) * 0.09f * doses); } // Eviscerate and Envenom Bonus Damage (item set effect) if(m_caster->GetDummyAura(37169)) @@ -907,10 +907,6 @@ void Spell::EffectDummy(uint32 i) DEBUG_LOG("AddObject at SpellEfects.cpp EffectDummy"); map->Add(pGameObj); - WorldPacket data(SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE, 8); - data << uint64(pGameObj->GetGUID()); - m_caster->SendMessageToSet(&data, true); - return; } case 23074: // Arcanite Dragonling @@ -1268,30 +1264,6 @@ void Spell::EffectDummy(uint32 i) m_caster->CastSpell(unitTarget,60934,true,NULL); return; } - - //All IconID Check in there - switch(m_spellInfo->SpellIconID) - { - // Berserking (troll racial traits) - case 1661: - { - uint32 healthPerc = uint32((float(m_caster->GetHealth())/m_caster->GetMaxHealth())*100); - int32 melee_mod = 10; - if (healthPerc <= 40) - melee_mod = 30; - if (healthPerc < 100 && healthPerc > 40) - melee_mod = 10+(100-healthPerc)/3; - - int32 hasteModBasePoints0 = melee_mod; // (EffectBasePoints[0]+1)-1+(5-melee_mod) = (melee_mod-1+1)-1+5-melee_mod = 5-1 - int32 hasteModBasePoints1 = (5-melee_mod); - int32 hasteModBasePoints2 = 5; - - // FIXME: custom spell required this aura state by some unknown reason, we not need remove it anyway - m_caster->ModifyAuraState(AURA_STATE_BERSERKING,true); - m_caster->CastCustomSpell(m_caster, 26635, &hasteModBasePoints0, &hasteModBasePoints1, &hasteModBasePoints2, true, NULL); - return; - } - } break; } case SPELLFAMILY_MAGE: @@ -1608,10 +1580,6 @@ void Spell::EffectDummy(uint32 i) uint32 spellid; switch(m_spellInfo->Id) { - case 781: // player case - target = m_caster; - spellid = 56446; - break; case 57635: spellid = 57636; break; // one from creature cases case 61507: spellid = 61508; break; // one from creature cases default: @@ -1788,55 +1756,6 @@ void Spell::EffectDummy(uint32 i) } break; case SPELLFAMILY_SHAMAN: - // Rockbiter Weapon - if (m_spellInfo->SpellFamilyFlags & 0x400000) - { - // TODO: use expect spell for enchant (if exist talent) - // In 3.0.3 no mods present for rockbiter - uint32 spell_id = 0; - switch(m_spellInfo->Id) - { - case 8017: spell_id = 36494; break; // Rank 1 - case 8018: spell_id = 36750; break; // Rank 2 - case 8019: spell_id = 36755; break; // Rank 3 - case 10399: spell_id = 36759; break; // Rank 4 - default: - sLog.outError("Spell::EffectDummy: Spell %u not handled in RW", m_spellInfo->Id); - return; - } - - SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id); - - if (!spellInfo) - { - sLog.outError("WORLD: unknown spell id %i", spell_id); - return; - } - - if (m_caster->GetTypeId() != TYPEID_PLAYER) - return; - - for(int j = BASE_ATTACK; j <= OFF_ATTACK; ++j) - { - if (Item* item = ((Player*)m_caster)->GetWeaponForAttack(WeaponAttackType(j))) - { - if (item->IsFitToSpellRequirements(m_spellInfo)) - { - Spell *spell = new Spell(m_caster, spellInfo, true); - - // enchanting spell selected by calculated damage-per-sec in enchanting effect - // at calculation applied affect from Elemental Weapons talent - // real enchantment damage-1 - spell->m_currentBasePoints[1] = damage-1; - - SpellCastTargets targets; - targets.setItemTarget( item ); - spell->prepare(&targets); - } - } - } - return; - } // Cleansing Totem if ((m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000004000000)) && m_spellInfo->SpellIconID==1673) { @@ -4055,65 +3974,62 @@ void Spell::EffectEnchantItemTmp(uint32 i) Player* p_caster = (Player*)m_caster; + // Rockbiter Weapon apply to both weapon + if (m_spellInfo->SpellFamilyName == SPELLFAMILY_SHAMAN && m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000400000)) + { + uint32 spell_id = 0; + + // enchanting spell selected by calculated damage-per-sec stored in Effect[1] base value + // Note: damage calculated (correctly) with rounding int32(float(v)) but + // RW enchantments applied damage int32(float(v)+0.5), this create 0..1 difference sometime + switch(damage) + { + // Rank 1 + case 2: spell_id = 36744; break; // 0% [ 7% == 2, 14% == 2, 20% == 2] + // Rank 2 + case 4: spell_id = 36753; break; // 0% [ 7% == 4, 14% == 4] + case 5: spell_id = 36751; break; // 20% + // Rank 3 + case 6: spell_id = 36754; break; // 0% [ 7% == 6, 14% == 6] + case 7: spell_id = 36755; break; // 20% + // Rank 4 + case 9: spell_id = 36761; break; // 0% [ 7% == 6] + case 10: spell_id = 36758; break; // 14% + case 11: spell_id = 36760; break; // 20% + default: + sLog.outError("Spell::EffectEnchantItemTmp: Damage %u not handled in S'RW",damage); + return; + } + + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id); + if (!spellInfo) + { + sLog.outError("Spell::EffectEnchantItemTmp: unknown spell id %i", spell_id); + return; + } + + for(int j = BASE_ATTACK; j <= OFF_ATTACK; ++j) + { + if (Item* item = p_caster->GetWeaponForAttack(WeaponAttackType(j))) + { + if (item->IsFitToSpellRequirements(m_spellInfo)) + { + Spell *spell = new Spell(m_caster, spellInfo, true); + SpellCastTargets targets; + targets.setItemTarget( item ); + spell->prepare(&targets); + } + } + } + return; + } + if (!itemTarget) return; uint32 enchant_id = m_spellInfo->EffectMiscValue[i]; - // Shaman Rockbiter Weapon - if (i==0 && m_spellInfo->Effect[1]==SPELL_EFFECT_DUMMY) - { - int32 enchnting_damage = m_currentBasePoints[1]+1; - - // enchanting id selected by calculated damage-per-sec stored in Effect[1] base value - // with already applied percent bonus from Elemental Weapons talent - // Note: damage calculated (correctly) with rounding int32(float(v)) but - // RW enchantments applied damage int32(float(v)+0.5), this create 0..1 difference sometime - switch(enchnting_damage) - { - // Rank 1 - case 2: enchant_id = 29; break; // 0% [ 7% == 2, 14% == 2, 20% == 2] - // Rank 2 - case 4: enchant_id = 6; break; // 0% [ 7% == 4, 14% == 4] - case 5: enchant_id = 3025; break; // 20% - // Rank 3 - case 6: enchant_id = 1; break; // 0% [ 7% == 6, 14% == 6] - case 7: enchant_id = 3027; break; // 20% - // Rank 4 - case 9: enchant_id = 3032; break; // 0% [ 7% == 6] - case 10: enchant_id = 503; break; // 14% - case 11: enchant_id = 3031; break; // 20% - // Rank 5 - case 15: enchant_id = 3035; break; // 0% - case 16: enchant_id = 1663; break; // 7% - case 17: enchant_id = 3033; break; // 14% - case 18: enchant_id = 3034; break; // 20% - // Rank 6 - case 28: enchant_id = 3038; break; // 0% - case 29: enchant_id = 683; break; // 7% - case 31: enchant_id = 3036; break; // 14% - case 33: enchant_id = 3037; break; // 20% - // Rank 7 - case 40: enchant_id = 3041; break; // 0% - case 42: enchant_id = 1664; break; // 7% - case 45: enchant_id = 3039; break; // 14% - case 48: enchant_id = 3040; break; // 20% - // Rank 8 - case 49: enchant_id = 3044; break; // 0% - case 52: enchant_id = 2632; break; // 7% - case 55: enchant_id = 3042; break; // 14% - case 58: enchant_id = 3043; break; // 20% - // Rank 9 - case 62: enchant_id = 2633; break; // 0% - case 66: enchant_id = 3018; break; // 7% - case 70: enchant_id = 3019; break; // 14% - case 74: enchant_id = 3020; break; // 20% - default: - sLog.outError("Spell::EffectEnchantItemTmp: Damage %u not handled in S'RW",enchnting_damage); - return; - } - } - if (!enchant_id) { sLog.outError("Spell %u Effect %u (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have 0 as enchanting id",m_spellInfo->Id,i); @@ -4603,15 +4519,37 @@ void Spell::EffectWeaponDmg(uint32 i) if (count) { // Effect 1(for Blood-Caked Strike)/3(other) damage is bonus - double bonus = count * CalculateDamage(m_spellInfo->SpellIconID == 1736 ? 0 : 2, unitTarget) / 100.0f; + float bonus = count * CalculateDamage(m_spellInfo->SpellIconID == 1736 ? 0 : 2, unitTarget) / 100.0f; // Blood Strike, Blood-Caked Strike and Obliterate store bonus*2 if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0002000000400000) || m_spellInfo->SpellIconID == 1736) bonus /= 2.0f; - totalDamagePercentMod += bonus; + totalDamagePercentMod *= 1.0f + bonus; } } + // Glyph of Blood Strike + if( m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000400000) && + m_caster->HasAura(59332) && + unitTarget->HasAuraType(SPELL_AURA_MOD_DECREASE_SPEED)) + { + totalDamagePercentMod *= 1.2f; // 120% if snared + } + // Glyph of Death Strike + if( m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000010) && + m_caster->HasAura(59336)) + { + int32 rp = m_caster->GetPower(POWER_RUNIC_POWER) / 10; + if(rp > 25) + rp = 25; + totalDamagePercentMod *= 1.0f + rp / 100.0f; + } + // Glyph of Plague Strike + if( m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000001) && + m_caster->HasAura(58657) ) + { + totalDamagePercentMod *= 1.2f; + } break; } } @@ -5530,6 +5468,37 @@ void Spell::EffectScriptEffect(uint32 effIndex) } break; } + case SPELLFAMILY_DEATHKNIGHT: + { + switch(m_spellInfo->Id) + { + // Pestilence + case 50842: + { + if(!unitTarget) + return; + + Unit* mainTarget = m_targets.getUnitTarget(); + if(!mainTarget) + return; + + // do only refresh diseases on main target if caster has Glyph of Disease + if(mainTarget == unitTarget && !m_caster->HasAura(63334)) + return; + + // Blood Plague + if(mainTarget->HasAura(55078)) + m_caster->CastSpell(unitTarget, 55078, true); + + // Frost Fever + if(mainTarget->HasAura(55095)) + m_caster->CastSpell(unitTarget, 55095, true); + + break; + } + } + break; + } } // normal DB scripted effect @@ -6017,9 +5986,6 @@ void Spell::EffectSummonObject(uint32 i) m_caster->AddGameObject(pGameObj); map->Add(pGameObj); - WorldPacket data(SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE, 8); - data << uint64(pGameObj->GetGUID()); - m_caster->SendMessageToSet(&data, true); m_caster->m_ObjectSlot[slot] = pGameObj->GetGUID(); } @@ -6582,7 +6548,7 @@ void Spell::EffectTransmitted(uint32 effIndex) { case GAMEOBJECT_TYPE_FISHINGNODE: { - m_caster->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT,pGameObj->GetGUID()); + m_caster->SetChannelObjectGUID(pGameObj->GetGUID()); m_caster->AddGameObject(pGameObj); // will removed at spell cancel // end time of range when possible catch fish (FISHING_BOBBER_READY_TIME..GetDuration(m_spellInfo)) @@ -6627,10 +6593,6 @@ void Spell::EffectTransmitted(uint32 effIndex) cMap->Add(pGameObj); - WorldPacket data(SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE, 8); - data << uint64(pGameObj->GetGUID()); - m_caster->SendMessageToSet(&data,true); - if(uint32 linkedEntry = pGameObj->GetGOInfo()->GetLinkedGameObjectEntry()) { GameObject* linkedGO = new GameObject; diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp index 2112325f2..2372dfd4b 100644 --- a/src/game/SpellHandler.cpp +++ b/src/game/SpellHandler.cpp @@ -340,10 +340,16 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) { recvPacket.read_skip(); // unk1, coords? recvPacket.read_skip(); // unk1, coords? - recvPacket.read_skip(); // >> 1 - recvPacket.read_skip(); // >> MSG_MOVE_STOP - MovementInfo movementInfo; - ReadMovementInfo(recvPacket, &movementInfo); + uint8 unk1; + recvPacket >> unk1; // >> 1 or 0 + if(unk1) + { + recvPacket.read_skip(); // >> MSG_MOVE_STOP + uint64 guid; + recvPacket.readPackGUID(guid); + MovementInfo movementInfo; + ReadMovementInfo(recvPacket, &movementInfo); + } } // auto-selection buff level base at target level (in spellInfo) diff --git a/src/game/TaxiHandler.cpp b/src/game/TaxiHandler.cpp index 271b978b1..be879ab9b 100644 --- a/src/game/TaxiHandler.cpp +++ b/src/game/TaxiHandler.cpp @@ -155,9 +155,9 @@ void WorldSession::HandleActivateTaxiExpressOpcode ( WorldPacket & recv_data ) sLog.outDebug( "WORLD: Received CMSG_ACTIVATETAXIEXPRESS" ); uint64 guid; - uint32 node_count, _totalcost; + uint32 node_count; - recv_data >> guid >> _totalcost >> node_count; + recv_data >> guid >> node_count; Creature *npc = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_FLIGHTMASTER); if (!npc) diff --git a/src/game/Totem.cpp b/src/game/Totem.cpp index cded5d44e..1bfcc7e22 100644 --- a/src/game/Totem.cpp +++ b/src/game/Totem.cpp @@ -53,7 +53,6 @@ void Totem::Update( uint32 time ) void Totem::Summon(Unit* owner) { - sLog.outDebug("AddObject at Totem.cpp line 49"); owner->GetMap()->Add((Creature*)this); // select totem model in dependent from owner team @@ -67,10 +66,6 @@ void Totem::Summon(Unit* owner) SetDisplayId(display_id); } - WorldPacket data(SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE, 8); - data << GetGUID(); - SendMessageToSet(&data,true); - AIM_Initialize(); switch(m_type) @@ -87,12 +82,10 @@ void Totem::Summon(Unit* owner) void Totem::UnSummon() { - SendObjectDeSpawnAnim(GetGUID()); - CombatStop(); RemoveAurasDueToSpell(GetSpell()); - Unit *owner = GetOwner(); - if (owner) + + if (Unit *owner = GetOwner()) { // clear owner's totem slot for(int i = 0; i < MAX_TOTEM; ++i) @@ -109,8 +102,10 @@ void Totem::UnSummon() //remove aura all party members too if (owner->GetTypeId() == TYPEID_PLAYER) { + ((Player*)owner)->SendAutoRepeatCancel(this); + // Not only the player can summon the totem (scripted AI) - if(Group *pGroup = ((Player*)owner)->GetGroup()) + if (Group *pGroup = ((Player*)owner)->GetGroup()) { for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) { diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index fe01fdd83..55cca34bd 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -5850,7 +5850,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu // find caster main aura at beacon Aura* dummy = NULL; - Unit::AuraList const& baa = beacon->GetAurasByType(SPELL_AURA_DUMMY); + Unit::AuraList const& baa = beacon->GetAurasByType(SPELL_AURA_PERIODIC_TRIGGER_SPELL); for(Unit::AuraList::const_iterator i = baa.begin(); i != baa.end(); ++i) { if ((*i)->GetId() == 53563 && (*i)->GetCasterGUID() == pVictim->GetGUID()) @@ -7658,8 +7658,8 @@ bool Unit::Attack(Unit *victim, bool meleeAttack) ((Creature*)this)->SetCombatStartPosition(GetPositionX(), GetPositionY(), GetPositionZ()); } - //Set our target - SetUInt64Value(UNIT_FIELD_TARGET, victim->GetGUID()); + // Set our target + SetTargetGUID(victim->GetGUID()); if(meleeAttack) addUnitState(UNIT_STAT_MELEE_ATTACKING); @@ -7697,8 +7697,8 @@ bool Unit::AttackStop(bool targetSwitch /*=false*/) m_attacking->_removeAttacker(this); m_attacking = NULL; - //Clear our target - SetUInt64Value(UNIT_FIELD_TARGET, 0); + // Clear our target + SetTargetGUID(0); clearUnitState(UNIT_STAT_MELEE_ATTACKING); @@ -7860,6 +7860,7 @@ void Unit::ModifyAuraState(AuraState flag, bool apply) } } } + Unit *Unit::GetOwner() const { if(uint64 ownerid = GetOwnerGUID()) @@ -7923,7 +7924,7 @@ float Unit::GetCombatDistance( const Unit* target ) const void Unit::SetPet(Pet* pet) { - SetUInt64Value(UNIT_FIELD_SUMMON, pet ? pet->GetGUID() : 0); + SetPetGUID(pet ? pet->GetGUID() : 0); // FIXME: hack, speed must be set only at follow if(pet && GetTypeId()==TYPEID_PLAYER) @@ -7933,16 +7934,14 @@ void Unit::SetPet(Pet* pet) void Unit::SetCharm(Unit* pet) { - SetUInt64Value(UNIT_FIELD_CHARM, pet ? pet->GetGUID() : 0); + SetCharmGUID(pet ? pet->GetGUID() : 0); } - void Unit::AddGuardian( Pet* pet ) { m_guardianPets.insert(pet->GetGUID()); } - void Unit::RemoveGuardian( Pet* pet ) { m_guardianPets.erase(pet->GetGUID()); @@ -8277,6 +8276,38 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 } break; } + case SPELLFAMILY_DEATHKNIGHT: + { + // Icy Touch, Howling Blast and Frost Strike + if (spellProto->SpellFamilyFlags & UI64LIT(0x0000000600000002)) + { + // search disease + bool found = false; + Unit::AuraMap const& auras = pVictim->GetAuras(); + for(Unit::AuraMap::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr) + { + if(itr->second->GetSpellProto()->Dispel == DISPEL_DISEASE) + { + found = true; + break; + } + } + if(!found) + break; + + // search for Glacier Rot dummy aura + Unit::AuraList const& dummyAuras = GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator i = dummyAuras.begin(); i != dummyAuras.end(); ++i) + { + if ((*i)->GetSpellProto()->EffectMiscValue[(*i)->GetEffIndex()] == 7244) + { + DoneTotalMod *= ((*i)->GetModifier()->m_amount+100.0f) / 100.0f; + break; + } + } + } + break; + } default: break; } @@ -12098,9 +12129,6 @@ bool Unit::IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura* aura, SpellEntry con else item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED); - if (!((Player*)this)->IsUseEquipedWeapon(attType==BASE_ATTACK)) - return false; - if(!item || item->IsBroken() || item->GetProto()->Class != ITEM_CLASS_WEAPON || !((1<GetProto()->SubClass) & spellProto->EquippedItemSubClassMask)) return false; } @@ -12190,7 +12218,7 @@ bool Unit::HandleMendingAuraProc( Aura* triggeredByAura ) void Unit::RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo) { - uint64 target_guid = GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT); + uint64 target_guid = GetChannelObjectGUID(); if(!IS_UNIT_GUID(target_guid)) return; diff --git a/src/game/Unit.h b/src/game/Unit.h index 5903ba3b9..f3f20e233 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1155,10 +1155,16 @@ class MANGOS_DLL_SPEC Unit : public WorldObject void SetOwnerGUID(uint64 owner) { SetUInt64Value(UNIT_FIELD_SUMMONEDBY, owner); } uint64 GetCreatorGUID() const { return GetUInt64Value(UNIT_FIELD_CREATEDBY); } void SetCreatorGUID(uint64 creator) { SetUInt64Value(UNIT_FIELD_CREATEDBY, creator); } - uint64 GetPetGUID() const { return GetUInt64Value(UNIT_FIELD_SUMMON); } + uint64 GetPetGUID() const { return GetUInt64Value(UNIT_FIELD_SUMMON); } + void SetPetGUID(uint64 pet) { SetUInt64Value(UNIT_FIELD_SUMMON, pet); } uint64 GetCharmerGUID() const { return GetUInt64Value(UNIT_FIELD_CHARMEDBY); } void SetCharmerGUID(uint64 owner) { SetUInt64Value(UNIT_FIELD_CHARMEDBY, owner); } - uint64 GetCharmGUID() const { return GetUInt64Value(UNIT_FIELD_CHARM); } + uint64 GetCharmGUID() const { return GetUInt64Value(UNIT_FIELD_CHARM); } + void SetCharmGUID(uint64 charm) { SetUInt64Value(UNIT_FIELD_CHARM, charm); } + uint64 GetTargetGUID() const { return GetUInt64Value(UNIT_FIELD_TARGET); } + void SetTargetGUID(uint64 targetGuid) { SetUInt64Value(UNIT_FIELD_TARGET, targetGuid); } + uint64 GetChannelObjectGUID() const { return GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT); } + void SetChannelObjectGUID(uint64 targetGuid) { SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, targetGuid); } uint64 GetCharmerOrOwnerGUID() const { return GetCharmerGUID() ? GetCharmerGUID() : GetOwnerGUID(); } uint64 GetCharmerOrOwnerOrOwnGUID() const diff --git a/src/game/UpdateFields.h b/src/game/UpdateFields.h index 0ae175ae9..4240e6a4a 100644 --- a/src/game/UpdateFields.h +++ b/src/game/UpdateFields.h @@ -19,7 +19,7 @@ #ifndef _UPDATEFIELDS_AUTO_H #define _UPDATEFIELDS_AUTO_H -// Auto generated for version 3, 1, 3, 9947 +// Auto generated for version 3, 2, 2, 10505 enum EObjectFields { @@ -70,7 +70,7 @@ enum EItemFields ITEM_FIELD_ITEM_TEXT_ID = OBJECT_END + 0x0036, // Size: 1, Type: INT, Flags: OWNER ITEM_FIELD_DURABILITY = OBJECT_END + 0x0037, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER ITEM_FIELD_MAXDURABILITY = OBJECT_END + 0x0038, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER - ITEM_FIELD_PAD = OBJECT_END + 0x0039, // Size: 1, Type: INT, Flags: NONE + ITEM_FIELD_CREATE_PLAYED_TIME = OBJECT_END + 0x0039, // Size: 1, Type: INT, Flags: PUBLIC ITEM_END = OBJECT_END + 0x003A, }; @@ -323,7 +323,7 @@ enum EUnitFields PLAYER_VISIBLE_ITEM_19_ENTRYID = UNIT_END + 0x0092, // Size: 1, Type: INT, Flags: PUBLIC PLAYER_VISIBLE_ITEM_19_ENCHANTMENT = UNIT_END + 0x0093, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC PLAYER_CHOSEN_TITLE = UNIT_END + 0x0094, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_FIELD_PAD_0 = UNIT_END + 0x0095, // Size: 1, Type: INT, Flags: NONE + PLAYER_FAKE_INEBRIATION = UNIT_END + 0x0095, // Size: 1, Type: INT, Flags: PUBLIC PLAYER_FIELD_INV_SLOT_HEAD = UNIT_END + 0x0096, // Size: 46, Type: LONG, Flags: PRIVATE PLAYER_FIELD_PACK_SLOT_1 = UNIT_END + 0x00C4, // Size: 32, Type: LONG, Flags: PRIVATE PLAYER_FIELD_BANK_SLOT_1 = UNIT_END + 0x00E4, // Size: 56, Type: LONG, Flags: PRIVATE @@ -361,32 +361,35 @@ enum EUnitFields PLAYER_FIELD_MOD_DAMAGE_DONE_NEG = UNIT_END + 0x03EC, // Size: 7, Type: INT, Flags: PRIVATE PLAYER_FIELD_MOD_DAMAGE_DONE_PCT = UNIT_END + 0x03F3, // Size: 7, Type: INT, Flags: PRIVATE PLAYER_FIELD_MOD_HEALING_DONE_POS = UNIT_END + 0x03FA, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MOD_TARGET_RESISTANCE = UNIT_END + 0x03FB, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE = UNIT_END + 0x03FC, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_BYTES = UNIT_END + 0x03FD, // Size: 1, Type: BYTES, Flags: PRIVATE - PLAYER_AMMO_ID = UNIT_END + 0x03FE, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_SELF_RES_SPELL = UNIT_END + 0x03FF, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_PVP_MEDALS = UNIT_END + 0x0400, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_BUYBACK_PRICE_1 = UNIT_END + 0x0401, // Size: 12, Type: INT, Flags: PRIVATE - PLAYER_FIELD_BUYBACK_TIMESTAMP_1 = UNIT_END + 0x040D, // Size: 12, Type: INT, Flags: PRIVATE - PLAYER_FIELD_KILLS = UNIT_END + 0x0419, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_FIELD_TODAY_CONTRIBUTION = UNIT_END + 0x041A, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_YESTERDAY_CONTRIBUTION = UNIT_END + 0x041B, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_LIFETIME_HONORBALE_KILLS = UNIT_END + 0x041C, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_BYTES2 = UNIT_END + 0x041D, // Size: 1, Type: BYTES, Flags: PRIVATE - PLAYER_FIELD_WATCHED_FACTION_INDEX = UNIT_END + 0x041E, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_COMBAT_RATING_1 = UNIT_END + 0x041F, // Size: 25, Type: INT, Flags: PRIVATE - PLAYER_FIELD_ARENA_TEAM_INFO_1_1 = UNIT_END + 0x0438, // Size: 18, Type: INT, Flags: PRIVATE - PLAYER_FIELD_HONOR_CURRENCY = UNIT_END + 0x044A, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_ARENA_CURRENCY = UNIT_END + 0x044B, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MAX_LEVEL = UNIT_END + 0x044C, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_DAILY_QUESTS_1 = UNIT_END + 0x044D, // Size: 25, Type: INT, Flags: PRIVATE - PLAYER_RUNE_REGEN_1 = UNIT_END + 0x0466, // Size: 4, Type: FLOAT, Flags: PRIVATE - PLAYER_NO_REAGENT_COST_1 = UNIT_END + 0x046A, // Size: 3, Type: INT, Flags: PRIVATE - PLAYER_FIELD_GLYPH_SLOTS_1 = UNIT_END + 0x046D, // Size: 6, Type: INT, Flags: PRIVATE - PLAYER_FIELD_GLYPHS_1 = UNIT_END + 0x0473, // Size: 6, Type: INT, Flags: PRIVATE - PLAYER_GLYPHS_ENABLED = UNIT_END + 0x0479, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_END = UNIT_END + 0x047A, + PLAYER_FIELD_MOD_HEALING_PCT = UNIT_END + 0x03FB, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_FIELD_MOD_HEALING_DONE_PCT = UNIT_END + 0x03FC, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_FIELD_MOD_TARGET_RESISTANCE = UNIT_END + 0x03FD, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE = UNIT_END + 0x03FE, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_BYTES = UNIT_END + 0x03FF, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_AMMO_ID = UNIT_END + 0x0400, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_SELF_RES_SPELL = UNIT_END + 0x0401, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_PVP_MEDALS = UNIT_END + 0x0402, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_BUYBACK_PRICE_1 = UNIT_END + 0x0403, // Size: 12, Type: INT, Flags: PRIVATE + PLAYER_FIELD_BUYBACK_TIMESTAMP_1 = UNIT_END + 0x040F, // Size: 12, Type: INT, Flags: PRIVATE + PLAYER_FIELD_KILLS = UNIT_END + 0x041B, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE + PLAYER_FIELD_TODAY_CONTRIBUTION = UNIT_END + 0x041C, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_YESTERDAY_CONTRIBUTION = UNIT_END + 0x041D, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_LIFETIME_HONORBALE_KILLS = UNIT_END + 0x041E, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_BYTES2 = UNIT_END + 0x041F, // Size: 1, Type: 6, Flags: PRIVATE + PLAYER_FIELD_WATCHED_FACTION_INDEX = UNIT_END + 0x0420, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_COMBAT_RATING_1 = UNIT_END + 0x0421, // Size: 25, Type: INT, Flags: PRIVATE + PLAYER_FIELD_ARENA_TEAM_INFO_1_1 = UNIT_END + 0x043A, // Size: 21, Type: INT, Flags: PRIVATE + PLAYER_FIELD_HONOR_CURRENCY = UNIT_END + 0x044F, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_ARENA_CURRENCY = UNIT_END + 0x0450, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MAX_LEVEL = UNIT_END + 0x0451, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_DAILY_QUESTS_1 = UNIT_END + 0x0452, // Size: 25, Type: INT, Flags: PRIVATE + PLAYER_RUNE_REGEN_1 = UNIT_END + 0x046B, // Size: 4, Type: FLOAT, Flags: PRIVATE + PLAYER_NO_REAGENT_COST_1 = UNIT_END + 0x046F, // Size: 3, Type: INT, Flags: PRIVATE + PLAYER_FIELD_GLYPH_SLOTS_1 = UNIT_END + 0x0472, // Size: 6, Type: INT, Flags: PRIVATE + PLAYER_FIELD_GLYPHS_1 = UNIT_END + 0x0478, // Size: 6, Type: INT, Flags: PRIVATE + PLAYER_GLYPHS_ENABLED = UNIT_END + 0x047E, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_PADDING = UNIT_END + 0x047F, // Size: 1, Type: INT, Flags: NONE + PLAYER_END = UNIT_END + 0x0480, }; enum EGameObjectFields @@ -408,12 +411,8 @@ enum EDynamicObjectFields DYNAMICOBJECT_BYTES = OBJECT_END + 0x0002, // Size: 1, Type: BYTES, Flags: PUBLIC DYNAMICOBJECT_SPELLID = OBJECT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC DYNAMICOBJECT_RADIUS = OBJECT_END + 0x0004, // Size: 1, Type: FLOAT, Flags: PUBLIC - DYNAMICOBJECT_POS_X = OBJECT_END + 0x0005, // Size: 1, Type: FLOAT, Flags: PUBLIC - DYNAMICOBJECT_POS_Y = OBJECT_END + 0x0006, // Size: 1, Type: FLOAT, Flags: PUBLIC - DYNAMICOBJECT_POS_Z = OBJECT_END + 0x0007, // Size: 1, Type: FLOAT, Flags: PUBLIC - DYNAMICOBJECT_FACING = OBJECT_END + 0x0008, // Size: 1, Type: FLOAT, Flags: PUBLIC - DYNAMICOBJECT_CASTTIME = OBJECT_END + 0x0009, // Size: 1, Type: INT, Flags: PUBLIC - DYNAMICOBJECT_END = OBJECT_END + 0x000A, + DYNAMICOBJECT_CASTTIME = OBJECT_END + 0x0005, // Size: 1, Type: INT, Flags: PUBLIC + DYNAMICOBJECT_END = OBJECT_END + 0x0006, }; enum ECorpseFields diff --git a/src/game/Weather.cpp b/src/game/Weather.cpp index 5065761fd..64e3ff979 100644 --- a/src/game/Weather.cpp +++ b/src/game/Weather.cpp @@ -186,7 +186,7 @@ bool Weather::ReGenerate() void Weather::SendWeatherUpdateToPlayer(Player *player) { - WorldPacket data( SMSG_WEATHER, (4+4+4) ); + WorldPacket data( SMSG_WEATHER, (4+4+1) ); data << uint32(GetWeatherState()) << (float)m_grade << uint8(0); player->GetSession()->SendPacket( &data ); @@ -194,7 +194,7 @@ void Weather::SendWeatherUpdateToPlayer(Player *player) void Weather::SendFineWeatherUpdateToPlayer(Player *player) { - WorldPacket data( SMSG_WEATHER, (4+4+4) ); + WorldPacket data( SMSG_WEATHER, (4+4+1) ); data << (uint32)WEATHER_STATE_FINE << (float)0.0f << uint8(0); player->GetSession()->SendPacket( &data ); @@ -215,7 +215,7 @@ bool Weather::UpdateWeather() WeatherState state = GetWeatherState(); - WorldPacket data( SMSG_WEATHER, (4+4+4) ); + WorldPacket data( SMSG_WEATHER, (4+4+1) ); data << uint32(state) << (float)m_grade << uint8(0); player->SendMessageToSet( &data, true ); diff --git a/src/game/World.cpp b/src/game/World.cpp index 1784e5d1a..b3260ddf4 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -245,6 +245,8 @@ World::AddSession_ (WorldSession* s) pkt << uint32(sWorld.getConfig(CONFIG_CLIENTCACHE_VERSION)); s->SendPacket(&pkt); + s->SendAccountDataTimes(GLOBAL_CACHE_MASK); + s->SendTutorialsData(); UpdateMaxSessionCounters (); @@ -324,6 +326,15 @@ bool World::RemoveQueuedPlayer(WorldSession* sess) WorldSession* pop_sess = m_QueuedPlayer.front(); pop_sess->SetInQueue(false); pop_sess->SendAuthWaitQue(0); + pop_sess->SendAddonsInfo(); + + WorldPacket pkt(SMSG_CLIENTCACHE_VERSION, 4); + pkt << uint32(sWorld.getConfig(CONFIG_CLIENTCACHE_VERSION)); + pop_sess->SendPacket(&pkt); + + pop_sess->SendAccountDataTimes(GLOBAL_CACHE_MASK); + pop_sess->SendTutorialsData(); + m_QueuedPlayer.pop_front(); // update iter to point first queued socket or end() if queue is empty now diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp index 2533ccfdf..3a7c61181 100644 --- a/src/game/WorldSession.cpp +++ b/src/game/WorldSession.cpp @@ -644,13 +644,15 @@ void WorldSession::SetAccountData(AccountDataType type, time_t time_, std::strin m_accountData[type].Data = data; } -void WorldSession::SendAccountDataTimes() +void WorldSession::SendAccountDataTimes(uint32 mask) { - WorldPacket data( SMSG_ACCOUNT_DATA_TIMES, 4+1+8*4 ); // changed in WotLK + WorldPacket data( SMSG_ACCOUNT_DATA_TIMES, 4+1+4+8*4 ); // changed in WotLK data << uint32(time(NULL)); // unix time of something data << uint8(1); - for(int i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i) - data << uint32(m_accountData[i].Time); // also unix time + data << uint32(mask); // type mask + for(uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i) + if(mask & (1 << i)) + data << uint32(GetAccountData(AccountDataType(i))->Time);// also unix time SendPacket(&data); } @@ -757,6 +759,51 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi) } } +void WorldSession::WriteMovementInfo(WorldPacket *data, MovementInfo *mi) +{ + data->appendPackGUID(mi->guid); + + *data << mi->flags; + *data << mi->unk1; + *data << mi->time; + *data << mi->x; + *data << mi->y; + *data << mi->z; + *data << mi->o; + + if(mi->HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) + { + data->appendPackGUID(mi->t_guid); + + *data << mi->t_x; + *data << mi->t_y; + *data << mi->t_z; + *data << mi->t_o; + *data << mi->t_time; + *data << mi->t_seat; + } + + if((mi->HasMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2))) || (mi->unk1 & 0x20)) + { + *data << mi->s_pitch; + } + + *data << mi->fallTime; + + if(mi->HasMovementFlag(MOVEMENTFLAG_JUMPING)) + { + *data << mi->j_unk; + *data << mi->j_sinAngle; + *data << mi->j_cosAngle; + *data << mi->j_xyspeed; + } + + if(mi->HasMovementFlag(MOVEMENTFLAG_SPLINE)) + { + *data << mi->u_unk1; + } +} + void WorldSession::ReadAddonsInfo(WorldPacket &data) { if (data.rpos() + 4 > data.size()) diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h index 58f97a6ce..cf8ca9cb5 100644 --- a/src/game/WorldSession.h +++ b/src/game/WorldSession.h @@ -54,10 +54,9 @@ enum AccountDataType PER_CHARACTER_MACROS_CACHE = 5, // 0x20 p PER_CHARACTER_LAYOUT_CACHE = 6, // 0x40 p PER_CHARACTER_CHAT_CACHE = 7, // 0x80 p + NUM_ACCOUNT_DATA_TYPES = 8 }; -#define NUM_ACCOUNT_DATA_TYPES 8 - #define GLOBAL_CACHE_MASK 0x15 #define PER_CHARACTER_CACHE_MASK 0xEA @@ -123,6 +122,7 @@ class MANGOS_DLL_SPEC WorldSession void SendAddonsInfo(); void ReadMovementInfo(WorldPacket &data, MovementInfo *mi); + void WriteMovementInfo(WorldPacket *data, MovementInfo *mi); void SendPacket(WorldPacket const* packet); void SendNotification(const char *format,...) ATTR_PRINTF(2,3); @@ -201,7 +201,7 @@ class MANGOS_DLL_SPEC WorldSession // Account Data AccountData *GetAccountData(AccountDataType type) { return &m_accountData[type]; } void SetAccountData(AccountDataType type, time_t time_, std::string data); - void SendAccountDataTimes(); + void SendAccountDataTimes(uint32 mask); void LoadGlobalAccountData(); void LoadAccountData(QueryResult* result, uint32 mask); void LoadTutorialsData(); @@ -571,6 +571,7 @@ class MANGOS_DLL_SPEC WorldSession void HandleReclaimCorpseOpcode( WorldPacket& recvPacket ); void HandleCorpseQueryOpcode( WorldPacket& recvPacket ); + void HandleCorpseMapPositionQuery( WorldPacket& recvPacket ); void HandleResurrectResponseOpcode(WorldPacket& recvPacket); void HandleSummonResponseOpcode(WorldPacket& recv_data); @@ -643,6 +644,7 @@ class MANGOS_DLL_SPEC WorldSession void HandleFarSightOpcode(WorldPacket& recv_data); void HandleSetLfgOpcode(WorldPacket& recv_data); void HandleSetDungeonDifficultyOpcode(WorldPacket& recv_data); + void HandleSetRaidDifficultyOpcode(WorldPacket& recv_data); void HandleMoveSetCanFlyAckOpcode(WorldPacket& recv_data); void HandleLfgSetAutoJoinOpcode(WorldPacket& recv_data); void HandleLfgClearAutoJoinOpcode(WorldPacket& recv_data); @@ -682,6 +684,7 @@ class MANGOS_DLL_SPEC WorldSession void HandleSocketOpcode(WorldPacket& recv_data); void HandleCancelTempEnchantmentOpcode(WorldPacket& recv_data); + void HandleItemRefundInfoRequest(WorldPacket& recv_data); void HandleChannelVoiceOnOpcode(WorldPacket & recv_data); void HandleVoiceSessionEnableOpcode(WorldPacket& recv_data); @@ -728,6 +731,7 @@ class MANGOS_DLL_SPEC WorldSession void HandleEquipmentSetSave(WorldPacket& recv_data); void HandleEquipmentSetDelete(WorldPacket& recv_data); void HandleEquipmentSetUse(WorldPacket& recv_data); + void HandleWorldStateUITimerUpdate(WorldPacket& recv_data); private: // private trade methods void moveItems(Item* myItems[], Item* hisItems[]); diff --git a/src/game/WorldSocket.cpp b/src/game/WorldSocket.cpp index 69dd9ba2f..1de190ba5 100644 --- a/src/game/WorldSocket.cpp +++ b/src/game/WorldSocket.cpp @@ -263,8 +263,13 @@ int WorldSocket::open (void *a) m_Address = remote_addr.get_host_addr (); // Send startup packet. - WorldPacket packet (SMSG_AUTH_CHALLENGE, 4); + WorldPacket packet (SMSG_AUTH_CHALLENGE, 24); + packet << uint32(1); // 1...31 packet << m_Seed; + packet << uint32(0xF3539DA3); // random data + packet << uint32(0x6E8547B9); // random data + packet << uint32(0x9A6AA2F8); // random data + packet << uint32(0xA4F170F4); // random data if (SendPacket (packet) == -1) return -1; @@ -755,6 +760,7 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket) uint8 digest[20]; uint32 clientSeed; uint32 unk2, unk3; + uint64 unk4; uint32 BuiltNumberClient; uint32 id, security; uint8 expansion = 0; @@ -772,6 +778,7 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket) recvPacket >> account; recvPacket >> unk3; recvPacket >> clientSeed; + recvPacket >> unk4; recvPacket.read (digest, 20); DEBUG_LOG ("WorldSocket::HandleAuthSession: client %u, unk2 %u, account %s, unk3 %u, clientseed %u", diff --git a/src/game/debugcmds.cpp b/src/game/debugcmds.cpp index 684c2e0b4..d0f186f89 100644 --- a/src/game/debugcmds.cpp +++ b/src/game/debugcmds.cpp @@ -657,7 +657,6 @@ bool ChatHandler::HandleDebugSpellCheckCommand(const char* /*args*/) 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. "; @@ -678,7 +677,7 @@ bool ChatHandler::HandleDebugSendSetPhaseShiftCommand(const char* args) return true; } -bool ChatHandler::HandleDebugSetItemFlagCommand(const char* args) +bool ChatHandler::HandleDebugGetItemValueCommand(const char* args) { if (!*args) return false; @@ -690,14 +689,48 @@ bool ChatHandler::HandleDebugSetItemFlagCommand(const char* args) return false; uint32 guid = (uint32)atoi(e); - uint32 flag = (uint32)atoi(f); + uint32 index = (uint32)atoi(f); Item *i = m_session->GetPlayer()->GetItemByGuid(MAKE_NEW_GUID(guid, 0, HIGHGUID_ITEM)); if (!i) return false; - i->SetUInt32Value(ITEM_FIELD_FLAGS, flag); + if (index >= i->GetValuesCount()) + return false; + + uint32 value = i->GetUInt32Value(index); + + PSendSysMessage("Item %u: value at %u is %u", guid, index, value); + + return true; +} + +bool ChatHandler::HandleDebugSetItemValueCommand(const char* args) +{ + if (!*args) + return false; + + char* e = strtok((char*)args, " "); + char* f = strtok(NULL, " "); + char* g = strtok(NULL, " "); + + if (!e || !f || !g) + return false; + + uint32 guid = (uint32)atoi(e); + uint32 index = (uint32)atoi(f); + uint32 value = (uint32)atoi(g); + + Item *i = m_session->GetPlayer()->GetItemByGuid(MAKE_NEW_GUID(guid, 0, HIGHGUID_ITEM)); + + if (!i) + return false; + + if (index >= i->GetValuesCount()) + return false; + + i->SetUInt32Value(index, value); return true; } diff --git a/src/realmd/AuthCodes.h b/src/realmd/AuthCodes.h index 81483eb0a..7df23ad42 100644 --- a/src/realmd/AuthCodes.h +++ b/src/realmd/AuthCodes.h @@ -66,9 +66,9 @@ enum LoginResult // we need to stick to 1 version or half of the stuff will work for someone // others will not and opposite -// will only support WoW, WoW:TBC and WoW:WotLK 3.1.3 client build 9947... +// will only support WoW, WoW:TBC and WoW:WotLK 3.2.2a client build 10505... -#define EXPECTED_MANGOS_CLIENT_BUILD {9947, 0} +#define EXPECTED_MANGOS_CLIENT_BUILD {10505, 0} // At update excepted builds please update if need define DEFAULT_MAX_LEVEL // in DBCEnum.h to default max player level expected by build diff --git a/src/shared/Database/SQLStorage.cpp b/src/shared/Database/SQLStorage.cpp index e4f5f99ca..2cf69db0f 100644 --- a/src/shared/Database/SQLStorage.cpp +++ b/src/shared/Database/SQLStorage.cpp @@ -25,16 +25,16 @@ extern DatabasePostgre WorldDatabase; extern DatabaseMysql WorldDatabase; #endif -const char CreatureInfosrcfmt[]="iiiiiiiisssiiiiiiiiiiffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiliiis"; -const char CreatureInfodstfmt[]="iiiiiiiisssiiiiiiiiiiffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiliiii"; +const char CreatureInfosrcfmt[]="iiiiiiiisssiiiiiiiiiiffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiis"; +const char CreatureInfodstfmt[]="iiiiiiiisssiiiiiiiiiiffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiii"; const char CreatureDataAddonInfofmt[]="iiiiiis"; const char CreatureModelfmt[]="iffbi"; const char CreatureInfoAddonInfofmt[]="iiiiiis"; const char EquipmentInfofmt[]="iiii"; -const char GameObjectInfosrcfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiis"; -const char GameObjectInfodstfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiii"; -const char ItemPrototypesrcfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiiisiiii"; -const char ItemPrototypedstfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiiiiiiii"; +const char GameObjectInfosrcfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiis"; +const char GameObjectInfodstfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"; +const char ItemPrototypesrcfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiiisiiii"; +const char ItemPrototypedstfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiiiiiiii"; const char PageTextfmt[]="isi"; const char InstanceTemplatesrcfmt[]="iiiiiiiffffs"; const char InstanceTemplatedstfmt[]="iiiiiiiffffi"; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 686c1f525..78be3ef88 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8588" + #define REVISION_NR "8589" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index c04ff11f5..306d807bc 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ - #define REVISION_DB_CHARACTERS "required_8505_01_characters_character_spell" - #define REVISION_DB_MANGOS "required_8573_01_mangos_mangos_string" + #define REVISION_DB_CHARACTERS "required_8589_11_characters_characters" + #define REVISION_DB_MANGOS "required_8589_10_mangos_spell_proc_event" #define REVISION_DB_REALMD "required_8332_01_realmd_realmcharacters" #endif // __REVISION_SQL_H__ diff --git a/win/VC100/game.vcxproj b/win/VC100/game.vcxproj index dcc65401e..7b26ec3df 100644 --- a/win/VC100/game.vcxproj +++ b/win/VC100/game.vcxproj @@ -355,11 +355,13 @@ + + @@ -502,10 +504,12 @@ + + diff --git a/win/VC80/game.vcproj b/win/VC80/game.vcproj index e457cb7dc..db509f9b2 100644 --- a/win/VC80/game.vcproj +++ b/win/VC80/game.vcproj @@ -565,6 +565,14 @@ RelativePath="..\..\src\game\BattleGroundAB.h" > + + + + @@ -601,6 +609,14 @@ RelativePath="..\..\src\game\BattleGroundHandler.cpp" > + + + + diff --git a/win/VC90/game.vcproj b/win/VC90/game.vcproj index ca0233dcf..8386ec9d7 100644 --- a/win/VC90/game.vcproj +++ b/win/VC90/game.vcproj @@ -566,6 +566,14 @@ RelativePath="..\..\src\game\BattleGroundAB.h" > + + + + @@ -602,6 +610,14 @@ RelativePath="..\..\src\game\BattleGroundHandler.cpp" > + + + +