[8589] Merge branch '320' - Switch to support client version 3.2.2A

You need extract new dbc/map/vmaps for correct work.
And apply ofc sql updates that including character convertion.

Special thanks to TOM_RUS for prepering this switch :)

Signed-off-by: VladimirMangos <vladimir@getmangos.com>
This commit is contained in:
VladimirMangos 2009-10-06 12:11:22 +04:00
commit f37f27d3c2
99 changed files with 2645 additions and 1697 deletions

View file

@ -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';
--

View file

@ -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),

View file

@ -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');

View file

@ -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`;

View file

@ -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`;

View file

@ -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`;

View file

@ -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`;

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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),' ');

View file

@ -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

View file

@ -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])

View file

@ -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
{

View file

@ -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
*/

View file

@ -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);
}
};

View file

@ -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;
if(ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId))
{
arenateam->Query(this);
arenateam->Stats(this);
}
}
void WorldSession::HandleArenaTeamRosterOpcode(WorldPacket & recv_data)
@ -69,10 +68,7 @@ void WorldSession::HandleArenaTeamRosterOpcode(WorldPacket & recv_data)
uint32 ArenaTeamId; // arena team id
recv_data >> ArenaTeamId;
ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId);
if(!arenateam)
return;
if(ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId))
arenateam->Roster(this);
}
@ -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->IsFighting())
if(at->IsFighting())
return;
at->Disband(this);
delete at;
}
}
void WorldSession::HandleArenaTeamRemoveOpcode(WorldPacket & recv_data)

View file

@ -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<uint32>(); // const 1?
recv_data >> item;
recv_data.read_skip<uint32>(); // 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;

View file

@ -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
{

View file

@ -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 */

View file

@ -0,0 +1,81 @@
/*
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* 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<uint64, BattleGroundScore*>::iterator itr = m_PlayerScores.find(Source->GetGUID());
if(itr == m_PlayerScores.end()) // player not found...
return;
BattleGround::UpdatePlayerScore(Source,type,value);
}

View file

@ -0,0 +1,54 @@
/*
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* 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

View file

@ -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

View file

@ -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)

View file

@ -0,0 +1,81 @@
/*
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* 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<uint64, BattleGroundScore*>::iterator itr = m_PlayerScores.find(Source->GetGUID());
if(itr == m_PlayerScores.end()) // player not found...
return;
BattleGround::UpdatePlayerScore(Source,type,value);
}

54
src/game/BattleGroundIC.h Normal file
View file

@ -0,0 +1,54 @@
/*
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* 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

View file

@ -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:

View file

@ -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)
{

View file

@ -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 (pos<str_motd.length())
if (pos < str_motd.length())
{
data << str_motd.substr(pos);
++linecount;
@ -619,11 +619,6 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
DEBUG_LOG( "WORLD: Sent motd (SMSG_MOTD)" );
}
data.Initialize(SMSG_LEARNED_DANCE_MOVES, 4+4);
data << uint32(0);
data << uint32(0);
SendPacket(&data);
//QueryResult *result = CharacterDatabase.PQuery("SELECT guildid,rank FROM guild_member WHERE guid = '%u'",pCurrChar->GetGUIDLow());
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

View file

@ -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 },

View file

@ -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);

View file

@ -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)

View file

@ -217,7 +217,7 @@ struct CreatureInfo
float unk16;
float unk17;
bool RacialLeader;
uint32 questItems[4];
uint32 questItems[6];
uint32 movementId;
bool RegenHealth;
uint32 equipmentId;

View file

@ -96,6 +96,12 @@ DBCStorage <LockEntry> sLockStore(LockEntryfmt);
DBCStorage <MailTemplateEntry> sMailTemplateStore(MailTemplateEntryfmt);
DBCStorage <MapEntry> sMapStore(MapEntryfmt);
// DBC used only for initialization sMapDifficultyMap at startup.
DBCStorage <MapDifficultyEntry> sMapDifficultyStore(MapDifficultyEntryfmt); // only for loading
typedef std::map<uint32/*pair32(map,diff)*/,MapDifficulty> MapDifficultyMap;
MapDifficultyMap sMapDifficultyMap;
DBCStorage <MovieEntry> sMovieStore(MovieEntryfmt);
DBCStorage <QuestSortEntry> sQuestSortStore(QuestSortEntryfmt);
@ -129,7 +135,7 @@ TalentSpellPosMap sTalentSpellPosMap;
DBCStorage <TalentTabEntry> 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 <TaxiNodesEntry> sTaxiNodesStore(TaxiNodesEntryfmt);
TaxiMask sTaxiNodesMask;
@ -139,10 +145,10 @@ TaxiMask sOldContinentsNodesMask;
TaxiPathSetBySource sTaxiPathSetBySource;
DBCStorage <TaxiPathEntry> sTaxiPathStore(TaxiPathEntryfmt);
// DBC used only for initialization sTaxiPathSetBySource at startup.
// DBC used only for initialization sTaxiPathNodeStore at startup.
TaxiPathNodesByPath sTaxiPathNodesByPath;
static DBCStorage <TaxiPathNodeEntry> sTaxiPathNodeStore(TaxiPathNodeEntryfmt);
DBCStorage <TotemCategoryEntry> sTotemCategoryStore(TotemCategoryEntryfmt);
DBCStorage <VehicleEntry> sVehicleStore(VehicleEntryfmt);
DBCStorage <VehicleSeatEntry> 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];

View file

@ -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 <AchievementEntry> sAchievementStore;
@ -109,6 +111,7 @@ extern DBCStorage <ItemSetEntry> sItemSetStore;
extern DBCStorage <LockEntry> sLockStore;
extern DBCStorage <MailTemplateEntry> sMailTemplateStore;
extern DBCStorage <MapEntry> sMapStore;
//extern DBCStorage <MapDifficultyEntry> sMapDifficultyStore; -- use GetMapDifficultyData insteed
extern DBCStorage <MovieEntry> sMovieStore;
extern DBCStorage <QuestSortEntry> sQuestSortStore;
extern DBCStorage <RandomPropertiesPointsEntry> sRandomPropertiesPointsStore;

View file

@ -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) {}

View file

@ -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";

View file

@ -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)

View file

@ -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;

View file

@ -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:

View file

@ -314,7 +314,7 @@ FleeingMovementGenerator<Creature>::_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();
}

View file

@ -89,8 +89,9 @@ void WorldSession::HandleGMTicketCreateOpcode( WorldPacket & recv_data )
recv_data >> ticketText;
recv_data.read_skip<uint32>(); // unk1, 0
recv_data.read_skip<uint32>(); // unk2, 1
recv_data.read_skip<uint8>(); // unk2, 1
recv_data.read_skip<uint32>(); // unk3, 0
recv_data.read_skip<uint32>(); // unk4, 0
sLog.outDebug("TicketCreate: map %u, x %f, y %f, z %f, text %s", map, x, y, z, ticketText.c_str());

View file

@ -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

View file

@ -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];

View file

@ -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);
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())

View file

@ -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

View file

@ -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");
Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
if(!guild)
return;
sLog.outDebug("WORLD: Received CMSG_GUILD_ROSTER");
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,16 +798,9 @@ 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;
if(uint32 GuildId = GetPlayer()->GetGuildId())
if(Guild *pGuild = objmgr.GetGuildById(GuildId))
pGuild->DisplayGuildEventLog(this);
}
@ -859,16 +809,9 @@ 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;
if(uint32 GuildId = GetPlayer()->GetGuildId())
if(Guild *pGuild = objmgr.GetGuildById(GuildId))
pGuild->SendMoneyInfo(this, GetPlayer()->GetGUIDLow());
}
@ -876,14 +819,10 @@ 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;
if(uint32 GuildId = GetPlayer()->GetGuildId())
{
if(Guild *pGuild = objmgr.GetGuildById(GuildId))
{
uint32 rankId = GetPlayer()->GetRank();
WorldPacket data(MSG_GUILD_PERMISSIONS, 4*15+1);
@ -900,12 +839,15 @@ void WorldSession::HandleGuildPermissions( WorldPacket& /* recv_data */ )
}
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;
Guild *pGuild = objmgr.GetGuildById(GuildId);
if(!pGuild)
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 usefull if money withdraw right has changed
// This is useful if money withdraw right has changed
pGuild->SendMoneyInfo(this, GetPlayer()->GetGUIDLow());
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,17 +906,13 @@ 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;
if(uint32 GuildId = GetPlayer()->GetGuildId())
{
if(Guild *pGuild = objmgr.GetGuildById(GuildId))
{
CharacterDatabase.BeginTransaction();
pGuild->SetBankMoney(pGuild->GetGuildBankMoney()+money);
@ -996,11 +934,14 @@ void WorldSession::HandleGuildBankDepositMoney( WorldPacket & recv_data )
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,27 +1052,21 @@ 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();
if(uint32 GuildId = GetPlayer()->GetGuildId())
{
if(Guild *pGuild = objmgr.GetGuildById(GuildId))
{
// Bank <-> Bank
if (BankToBank)
{
pGuild->SwapItems(pl, BankTab, BankTabSlot, BankTabDst, BankTabSlotDst, SplitedAmount);
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) )
if(!Player::IsInventoryPos(PlayerBag, PlayerSlot) && !(PlayerBag == NULL_BAG && PlayerSlot == NULL_SLOT) )
{
_player->SendEquipError( EQUIP_ERR_NONE, NULL, NULL );
return;
@ -1140,15 +1074,17 @@ void WorldSession::HandleGuildBankSwapItems( WorldPacket & recv_data )
// BankToChar swap or char to bank remaining
if (ToChar) // Bank -> Char cases
pGuild->MoveFromBankToChar(pl, BankTab, BankTabSlot, PlayerBag, PlayerSlot, SplitedAmount);
pGuild->MoveFromBankToChar(_player, BankTab, BankTabSlot, PlayerBag, PlayerSlot, SplitedAmount);
else // Char -> Bank cases
pGuild->MoveFromCharToBank(pl, PlayerBag, PlayerSlot, BankTab, BankTabSlot, SplitedAmount);
pGuild->MoveFromCharToBank(_player, 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,34 +1150,26 @@ 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;
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;
if(uint32 GuildId = GetPlayer()->GetGuildId())
if(Guild *pGuild = objmgr.GetGuildById(GuildId))
pGuild->DisplayGuildBankLogs(this, TabId);
}
@ -1249,36 +1177,25 @@ 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;
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;
if(uint32 GuildId = GetPlayer()->GetGuildId())
if(Guild *pGuild = objmgr.GetGuildById(GuildId))
pGuild->SetGuildBankTabText(TabId, Text);
}

View file

@ -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;

View file

@ -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<Player*> PlayerListType;
typedef std::list<Group*> 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::Singleton<InstanceSav
void Update();
InstanceSave* AddInstanceSave(uint32 mapId, uint32 instanceId, uint8 difficulty, time_t resetTime, bool canReset, bool load = false);
InstanceSave* AddInstanceSave(uint32 mapId, uint32 instanceId, Difficulty difficulty, time_t resetTime, bool canReset, bool load = false);
void RemoveInstanceSave(uint32 InstanceId);
static void DeleteInstanceFromDB(uint32 instanceid);

View file

@ -38,19 +38,19 @@ void WorldSession::HandleSplitItemOpcode( WorldPacket & recv_data )
uint16 src = ( (srcbag << 8) | srcslot );
uint16 dst = ( (dstbag << 8) | dstslot );
if(src==dst)
if(src == dst)
return;
if (count==0)
if (count == 0)
return; //check count - if zero it's fake packet
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;
@ -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;
@ -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);
@ -598,7 +599,7 @@ void WorldSession::HandleBuybackItem(WorldPacket & recv_data)
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)) );
@ -670,7 +671,7 @@ 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 )
@ -682,7 +683,7 @@ void WorldSession::HandleBuyItemOpcode( WorldPacket & recv_data )
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 )
@ -703,7 +704,7 @@ void WorldSession::SendListInventory( uint64 vendorguid )
{
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
}

View file

@ -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;

View file

@ -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());

View file

@ -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

View file

@ -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;
}

View file

@ -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;
}
}
@ -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());
@ -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);
}
@ -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<uint8>(0, mails_count); // set real send mails to client
data.put<uint32>(0, realCount); // this will display warning about undelivered mail to player if realCount > mailsCount
data.put<uint8>(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();

View file

@ -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 \

View file

@ -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();

View file

@ -365,7 +365,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, 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(); }

View file

@ -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");

View file

@ -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;

View file

@ -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;
}

View file

@ -46,7 +46,7 @@ void WorldSession::HandleRepopRequestOpcode( WorldPacket & recv_data )
recv_data.read_skip<uint8>();
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<uint8*>(dest.contents()), &realSize, const_cast<uint8*>(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>();
uint64 guid;
if(!recv_data.readPackGUID(guid))
{
recv_data.rpos(recv_data.wpos());
return;
}
recv_data.read_skip<uint32>();
/*
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;
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);
}

View file

@ -137,10 +137,21 @@ void WorldSession::HandleMoveWorldportAckOpcode()
}
}
if((mEntry->IsRaid() || (mEntry->IsNonRaidDungeon() && mEntry->SupportsHeroicMode() && GetPlayer()->IsHeroic())) && mInstance)
if (mInstance)
{
if(mEntry->IsRaid())
{
uint32 timeleft = sInstanceSaveManager.GetResetTimeFor(GetPlayer()->GetMapId()) - time(NULL);
GetPlayer()->SendInstanceResetWarning(GetPlayer()->GetMapId(), GetPlayer()->GetDifficulty(), timeleft);
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<uint32>(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<uint64>(); // guid
uint64 guid;
recv_data.readPackGUID(guid);
recv_data.read_skip<uint32>(); // unk
MovementInfo movementInfo;
@ -513,7 +538,8 @@ void WorldSession::HandleMoveHoverAck( WorldPacket& recv_data )
{
sLog.outDebug("CMSG_MOVE_HOVER_ACK");
recv_data.read_skip<uint64>(); // guid
uint64 guid;
recv_data.readPackGUID(guid);
recv_data.read_skip<uint32>(); // unk
MovementInfo movementInfo;
@ -526,7 +552,8 @@ void WorldSession::HandleMoveWaterWalkAck(WorldPacket& recv_data)
{
sLog.outDebug("CMSG_MOVE_WATER_WALK_ACK");
recv_data.read_skip<uint64>(); // guid
uint64 guid;
recv_data.readPackGUID(guid);
recv_data.read_skip<uint32>(); // unk
MovementInfo movementInfo;

View file

@ -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

View file

@ -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;
}
}

View file

@ -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 },
};

View file

@ -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

View file

@ -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<uint32>(); // 0
recv_data.read_skip<uint64>(); // 0
recv_data >> name; // name
recv_data.read_skip<std::string>(); // some string
recv_data.read_skip<uint32>(); // 0
recv_data.read_skip<uint32>(); // 0
recv_data.read_skip<uint32>(); // 0
recv_data.read_skip<uint32>(); // 0
recv_data.read_skip<uint32>(); // 0
recv_data.read_skip<uint32>(); // 0
recv_data.read_skip<uint32>(); // 0
recv_data.read_skip<uint16>(); // 0
recv_data.read_skip<uint32>(); // 0
recv_data.read_skip<uint32>(); // 0
recv_data.read_skip<uint32>(); // 0
for (int i = 0; i < 10; ++i)
recv_data.read_skip<std::string>();
recv_data >> clientIndex; // index
recv_data.read_skip<uint32>(); // 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);
}

View file

@ -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(m_zoneUpdateId != newZone)
{
SendInitWorldStates(newZone, newArea); // only if really enters to new zone, not just area change, works strange...
if (sWorld.getConfig(CONFIG_WEATHER))
{
Weather *wth = sWorld.FindWeather(zone->ID);
if(wth)
{
if(Weather *wth = sWorld.FindWeather(zone->ID))
wth->SendWeatherUpdateToPlayer(this);
}
else
{
if(!sWorld.AddWeather(zone->ID))
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_rating<t_rating? p_rating : t_rating;
p_rating = p_rating < t_rating ? p_rating : t_rating;
if(max_personal_rating < p_rating)
max_personal_rating = p_rating;
}
@ -17492,7 +17540,7 @@ void Player::UpdateHomebindTime(uint32 time)
m_HomebindTimer = 60000;
// send message to player
WorldPacket data(SMSG_RAID_GROUP_ONLY, 4+4);
data << m_HomebindTimer;
data << uint32(m_HomebindTimer);
data << uint32(1);
GetSession()->SendPacket(&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);
}

View file

@ -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<uint8,ActionButton> ActionButtonList;
@ -326,10 +326,10 @@ enum LfgType
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<<bit_index) without (-1)
@ -508,8 +508,6 @@ enum ActivateTaxiReplies
ERR_TAXINOTSTANDING = 12
};
enum MirrorTimerType
{
FATIGUE_TIMER = 0,
@ -706,6 +704,9 @@ enum TransferAbortReason
TRANSFER_ABORT_NEED_GROUP = 0x0B, // 3.1
TRANSFER_ABORT_NOT_FOUND2 = 0x0C, // 3.1
TRANSFER_ABORT_NOT_FOUND3 = 0x0D, // 3.1
TRANSFER_ABORT_NOT_FOUND4 = 0x0E, // 3.2
TRANSFER_ABORT_REALM_ONLY = 0x0F, // All players on party must be from the same realm.
TRANSFER_ABORT_MAP_NOT_ALLOWED = 0x10, // Map can't be entered at this time.
};
enum InstanceResetWarningType
@ -717,6 +718,19 @@ enum InstanceResetWarningType
RAID_INSTANCE_EXPIRED = 5
};
// PLAYER_FIELD_ARENA_TEAM_INFO_1_1 offsets
enum ArenaTeamInfoType
{
ARENA_TEAM_ID = 0,
ARENA_TEAM_TYPE = 1, // new in 3.2 - team type?
ARENA_TEAM_MEMBER = 2, // 0 - captain, 1 - member
ARENA_TEAM_GAMES_WEEK = 3,
ARENA_TEAM_GAMES_SEASON = 4,
ARENA_TEAM_WINS_SEASON = 5,
ARENA_TEAM_PERSONAL_RATING = 6,
ARENA_TEAM_END = 7
};
// used in most movement packets (send and received)
enum MovementFlags
{
@ -752,6 +766,7 @@ enum MovementFlags
struct MovementInfo
{
// common
uint64 guid;
uint32 flags; // see enum MovementFlags
uint16 unk1;
uint32 time;
@ -922,7 +937,7 @@ class MANGOS_DLL_SPEC PlayerTaxi
else
return false;
}
void AppendTaximaskTo(ByteBuffer& data,bool all);
void AppendTaximaskTo(ByteBuffer& data, bool all);
// Destinations
bool LoadTaxiDestinationsFromString(const std::string& values, uint32 team);
@ -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<Item *> &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<uint32, Item*> 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;

View file

@ -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<uint64>(); // 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<uint64>(); // 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<uint64>(); // 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);
}

View file

@ -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
{

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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)
{

View file

@ -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;

View file

@ -340,11 +340,17 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
{
recvPacket.read_skip<float>(); // unk1, coords?
recvPacket.read_skip<float>(); // unk1, coords?
recvPacket.read_skip<uint8>(); // >> 1
uint8 unk1;
recvPacket >> unk1; // >> 1 or 0
if(unk1)
{
recvPacket.read_skip<uint32>(); // >> MSG_MOVE_STOP
uint64 guid;
recvPacket.readPackGUID(guid);
MovementInfo movementInfo;
ReadMovementInfo(recvPacket, &movementInfo);
}
}
// auto-selection buff level base at target level (in spellInfo)
if(targets.getUnitTarget())

View file

@ -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)

View file

@ -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())
{

View file

@ -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<<item->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;

View file

@ -1156,9 +1156,15 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
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); }
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); }
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

View file

@ -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

View file

@ -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 );

View file

@ -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

View file

@ -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())

View file

@ -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[]);

View file

@ -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",

View file

@ -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;
}

View file

@ -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

View file

@ -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";

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "8588"
#define REVISION_NR "8589"
#endif // __REVISION_NR_H__

View file

@ -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__

View file

@ -355,11 +355,13 @@
<ClCompile Include="..\..\src\game\BattleGround.cpp" />
<ClCompile Include="..\..\src\game\BattleGroundAA.cpp" />
<ClCompile Include="..\..\src\game\BattleGroundAB.cpp" />
<ClCompile Include="..\..\src\game\BattleGroundABG.cpp" />
<ClCompile Include="..\..\src\game\BattleGroundAV.cpp" />
<ClCompile Include="..\..\src\game\BattleGroundBE.cpp" />
<ClCompile Include="..\..\src\game\BattleGroundDS.cpp" />
<ClCompile Include="..\..\src\game\BattleGroundEY.cpp" />
<ClCompile Include="..\..\src\game\BattleGroundHandler.cpp" />
<ClCompile Include="..\..\src\game\BattleGroundIC.cpp" />
<ClCompile Include="..\..\src\game\BattleGroundMgr.cpp" />
<ClCompile Include="..\..\src\game\BattleGroundNA.cpp" />
<ClCompile Include="..\..\src\game\BattleGroundRL.cpp" />
@ -502,10 +504,12 @@
<ClInclude Include="..\..\src\game\BattleGround.h" />
<ClInclude Include="..\..\src\game\BattleGroundAA.h" />
<ClInclude Include="..\..\src\game\BattleGroundAB.h" />
<ClInclude Include="..\..\src\game\BattleGroundABG.h" />
<ClInclude Include="..\..\src\game\BattleGroundAV.h" />
<ClInclude Include="..\..\src\game\BattleGroundBE.h" />
<ClInclude Include="..\..\src\game\BattleGroundDS.h" />
<ClInclude Include="..\..\src\game\BattleGroundEY.h" />
<ClInclude Include="..\..\src\game\BattleGroundIC.h" />
<ClInclude Include="..\..\src\game\BattleGroundMgr.h" />
<ClInclude Include="..\..\src\game\BattleGroundNA.h" />
<ClInclude Include="..\..\src\game\BattleGroundRL.h" />

View file

@ -565,6 +565,14 @@
RelativePath="..\..\src\game\BattleGroundAB.h"
>
</File>
<File
RelativePath="..\..\src\game\BattleGroundABG.cpp"
>
</File>
<File
RelativePath="..\..\src\game\BattleGroundABG.h"
>
</File>
<File
RelativePath="..\..\src\game\BattleGroundAV.cpp"
>
@ -601,6 +609,14 @@
RelativePath="..\..\src\game\BattleGroundHandler.cpp"
>
</File>
<File
RelativePath="..\..\src\game\BattleGroundIC.cpp"
>
</File>
<File
RelativePath="..\..\src\game\BattleGroundIC.h"
>
</File>
<File
RelativePath="..\..\src\game\BattleGroundMgr.cpp"
>

View file

@ -566,6 +566,14 @@
RelativePath="..\..\src\game\BattleGroundAB.h"
>
</File>
<File
RelativePath="..\..\src\game\BattleGroundABG.cpp"
>
</File>
<File
RelativePath="..\..\src\game\BattleGroundABG.h"
>
</File>
<File
RelativePath="..\..\src\game\BattleGroundAV.cpp"
>
@ -602,6 +610,14 @@
RelativePath="..\..\src\game\BattleGroundHandler.cpp"
>
</File>
<File
RelativePath="..\..\src\game\BattleGroundIC.cpp"
>
</File>
<File
RelativePath="..\..\src\game\BattleGroundIC.h"
>
</File>
<File
RelativePath="..\..\src\game\BattleGroundMgr.cpp"
>