Merge commit 'origin/master' into 320

This commit is contained in:
tomrus88 2009-09-22 18:14:06 +04:00
commit 258e19a4a3
48 changed files with 744 additions and 206 deletions

View file

@ -21,7 +21,7 @@
DROP TABLE IF EXISTS `character_db_version`; DROP TABLE IF EXISTS `character_db_version`;
CREATE TABLE `character_db_version` ( CREATE TABLE `character_db_version` (
`required_8469_01_characters_character_spell` bit(1) default NULL `required_8505_01_characters_character_spell` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB'; ) 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, `version` varchar(120) default NULL,
`creature_ai_version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL,
`cache_id` int(10) default '0', `cache_id` int(10) default '0',
`required_8499_01_mangos_spell_elixir` bit(1) default NULL `required_8521_01_mangos_spell_proc_event` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
-- --
@ -9746,7 +9746,7 @@ INSERT INTO `playercreateinfo_action` VALUES
(1,1,96,6603,0), (1,1,96,6603,0),
(1,1,108,6603,0), (1,1,108,6603,0),
(1,2,0,6603,0), (1,2,0,6603,0),
(1,2,1,20154,0), (1,2,1,21084,0),
(1,2,2,635,0), (1,2,2,635,0),
(1,2,9,59752,0), (1,2,9,59752,0),
(1,2,10,159,128), (1,2,10,159,128),
@ -9833,7 +9833,7 @@ INSERT INTO `playercreateinfo_action` VALUES
(3,1,96,6603,0), (3,1,96,6603,0),
(3,1,108,6603,0), (3,1,108,6603,0),
(3,2,0,6603,0), (3,2,0,6603,0),
(3,2,1,20154,0), (3,2,1,21084,0),
(3,2,2,635,0), (3,2,2,635,0),
(3,2,3,20594,0), (3,2,3,20594,0),
(3,2,4,2481,0), (3,2,4,2481,0),
@ -10295,7 +10295,7 @@ INSERT INTO `playercreateinfo_spell` VALUES
(1,2,9078,'Cloth'), (1,2,9078,'Cloth'),
(1,2,9116,'Shield'), (1,2,9116,'Shield'),
(1,2,9125,'Generic'), (1,2,9125,'Generic'),
(1,2,20154,'Seal of Righteousness'), (1,2,21084,'Seal of Righteousness'),
(1,2,20597,'Sword Specialization'), (1,2,20597,'Sword Specialization'),
(1,2,20598,'The Human Spirit'), (1,2,20598,'The Human Spirit'),
(1,2,20599,'Diplomacy'), (1,2,20599,'Diplomacy'),
@ -10882,7 +10882,7 @@ INSERT INTO `playercreateinfo_spell` VALUES
(3,2,9078,'Cloth'), (3,2,9078,'Cloth'),
(3,2,9116,'Shield'), (3,2,9116,'Shield'),
(3,2,9125,'Generic'), (3,2,9125,'Generic'),
(3,2,20154,'Seal of Righteousness'), (3,2,21084,'Seal of Righteousness'),
(3,2,20594,'Stoneform'), (3,2,20594,'Stoneform'),
(3,2,20595,'Gun Specialization'), (3,2,20595,'Gun Specialization'),
(3,2,20596,'Frost Resistance'), (3,2,20596,'Frost Resistance'),
@ -13659,6 +13659,7 @@ INSERT INTO `spell_bonus_data` VALUES
(20925, 0.09, 0, 0.056, 'Paladin - Holy Shield'), (20925, 0.09, 0, 0.056, 'Paladin - Holy Shield'),
(31803, 0, 0.0156, 0.03, 'Paladin - Holy Vengeance'), (31803, 0, 0.0156, 0.03, 'Paladin - Holy Vengeance'),
(2812, 0.07, 0, 0.07, 'Paladin - Holy Wrath'), (2812, 0.07, 0, 0.07, 'Paladin - Holy Wrath'),
(54158, 0.25, 0, 0, 'Paladin - Judgement'),
(31898, 0.18, 0, 0.11, 'Paladin - Judgement of Blood Enemy'), (31898, 0.18, 0, 0.11, 'Paladin - Judgement of Blood Enemy'),
(32220, 0.0594, 0, 0.0363,'Paladin - Judgement of Blood Self'), (32220, 0.0594, 0, 0.0363,'Paladin - Judgement of Blood Self'),
(20467, 0.25, 0, 0.16, 'Paladin - Judgement of Command'), (20467, 0.25, 0, 0.16, 'Paladin - Judgement of Command'),
@ -17929,6 +17930,7 @@ INSERT INTO `spell_proc_event` VALUES
(56344, 0x00000000, 9, 0x00004000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (56344, 0x00000000, 9, 0x00004000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(56355, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), (56355, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0),
(56364, 0x00000000, 3, 0x00000000, 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (56364, 0x00000000, 3, 0x00000000, 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(56372, 0x00000000, 3, 0x00000000, 0x00000080, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0),
(56451, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), (56451, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3),
(56611, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (56611, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
(56612, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (56612, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
@ -17942,6 +17944,8 @@ INSERT INTO `spell_proc_event` VALUES
(56834, 0x00000000, 15, 0x00440000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (56834, 0x00000000, 15, 0x00440000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(56835, 0x00000000, 15, 0x00440000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (56835, 0x00000000, 15, 0x00440000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(57352, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00010154, 0x00000003, 0.000000, 0.000000, 45), (57352, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00010154, 0x00000003, 0.000000, 0.000000, 45),
(57470, 0x00000000, 6, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(57472, 0x00000000, 6, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(57878, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0.000000, 0.000000, 0), (57878, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0.000000, 0.000000, 0),
(57880, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0.000000, 0.000000, 0), (57880, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0.000000, 0.000000, 0),
(57881, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0.000000, 0.000000, 0), (57881, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0.000000, 0.000000, 0),

View file

@ -308,8 +308,11 @@ INSERT INTO spell_check (spellid,SpellFamilyName,SpellFamilyMaskA,SpellFamilyMas
(53196, 7,0x0000000000000000,0x00000100, -1, -1, -1, 3, -1,-1,'Starfall', 'Spell::EffectDummy'), (53196, 7,0x0000000000000000,0x00000100, -1, -1, -1, 3, -1,-1,'Starfall', 'Spell::EffectDummy'),
(53197, 7,0x0000000000000000,0x00000100, -1, -1, -1, 3, -1,-1,'Starfall', 'Spell::EffectDummy'), (53197, 7,0x0000000000000000,0x00000100, -1, -1, -1, 3, -1,-1,'Starfall', 'Spell::EffectDummy'),
(53198, 7,0x0000000000000000,0x00000100, -1, -1, -1, 3, -1,-1,'Starfall', 'Spell::EffectDummy'), (53198, 7,0x0000000000000000,0x00000100, -1, -1, -1, 3, -1,-1,'Starfall', 'Spell::EffectDummy'),
(53271,-1, -1, -1, -1, -1, -1, 3, -1,-1,'Master''s Call', 'Spell::EffectDummy'),
(53271,-1, -1, -1, -1, -1, -1, 77, -1,-1,'Master''s Call', 'Spell::EffectScriptEffect'),
(53341, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Rune of Cinderglacier', 'Spell::EffectDummy'), (53341, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Rune of Cinderglacier', 'Spell::EffectDummy'),
(53343, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Rune of Razorice', 'Spell::EffectDummy'), (53343, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Rune of Razorice', 'Spell::EffectDummy'),
(54216,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Master''s Call', 'Spell::EffectDummy'),
(54586,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Runeforging Credit', 'Spell::EffectDummy'), (54586,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Runeforging Credit', 'Spell::EffectDummy'),
(54824,-1, -1, -1, -1, -1, -1, -1, 4,-1,'Glyph of Swiftmend', 'Spell::EffectHeal'), (54824,-1, -1, -1, -1, -1, -1, -1, 4,-1,'Glyph of Swiftmend', 'Spell::EffectHeal'),
(54861,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Nitro Boosts', 'Spell::EffectDummy'), (54861,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Nitro Boosts', 'Spell::EffectDummy'),
@ -335,6 +338,7 @@ INSERT INTO spell_check (spellid,SpellFamilyName,SpellFamilyMaskA,SpellFamilyMas
(61491, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Intercept', 'Spell::EffectSchoolDMG'), (61491, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Intercept', 'Spell::EffectSchoolDMG'),
(61507, 9, -1, -1, -1, -1, -1, 3, -1,-1,'Disengage', 'Spell::EffectDummy'), (61507, 9, -1, -1, -1, -1, -1, 3, -1,-1,'Disengage', 'Spell::EffectDummy'),
(61508,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Disengage', 'Spell::EffectDummy'), (61508,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Disengage', 'Spell::EffectDummy'),
(62305,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Master''s Call', 'Spell::EffectScriptEffect'),
(63375,-1, -1, -1, -1, -1, -1, 30, -1,-1,'Improved Stormstrike', 'Spell::EffectEnergize'), (63375,-1, -1, -1, -1, -1, -1, 30, -1,-1,'Improved Stormstrike', 'Spell::EffectEnergize'),
/* sorted by spell names */ /* sorted by spell names */

View file

@ -0,0 +1,5 @@
ALTER TABLE db_version CHANGE COLUMN required_8499_01_mangos_spell_elixir required_8504_01_mangos_playercreateinfo_spell bit;
UPDATE `playercreateinfo_spell`
SET `spell` = 21084
WHERE `spell` = 20154;

View file

@ -0,0 +1,5 @@
ALTER TABLE db_version CHANGE COLUMN required_8504_01_mangos_playercreateinfo_spell required_8504_02_mangos_playercreateinfo_action bit;
UPDATE `playercreateinfo_action`
SET `action` = 21084
WHERE `action` = 20154 AND `type` = 0;

View file

@ -0,0 +1,3 @@
ALTER TABLE character_db_version CHANGE COLUMN required_8469_01_characters_character_spell required_8505_01_characters_character_spell bit;
UPDATE character_spell SET active=1 WHERE spell=16857;

View file

@ -0,0 +1,7 @@
ALTER TABLE db_version CHANGE COLUMN required_8504_02_mangos_playercreateinfo_action required_8511_01_mangos_spell_proc_event bit;
DELETE FROM `spell_proc_event` WHERE `entry` IN (57470, 57472);
INSERT INTO spell_proc_event VALUES
(57470, 0x00000000, 6, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(57472, 0x00000000, 6, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0);

View file

@ -0,0 +1,6 @@
ALTER TABLE db_version CHANGE COLUMN required_8511_01_mangos_spell_proc_event required_8514_01_mangos_spell_bonus_data bit;
DELETE FROM `spell_bonus_data` WHERE `entry` IN (54158);
INSERT INTO `spell_bonus_data` VALUES
(54158, 0.25, 0, 0, 'Paladin - Judgement');

View file

@ -0,0 +1,6 @@
ALTER TABLE db_version CHANGE COLUMN required_8514_01_mangos_spell_bonus_data required_8521_01_mangos_spell_proc_event bit;
DELETE FROM `spell_proc_event` WHERE `entry` = 56372;
INSERT INTO `spell_proc_event` VALUES
(56372, 0x00, 3, 0x00000000, 0x00000080, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0);

View file

@ -107,6 +107,12 @@ pkgdata_DATA = \
8488_02_mangos_spell_bonus_data.sql \ 8488_02_mangos_spell_bonus_data.sql \
8498_01_mangos_spell_proc_event.sql \ 8498_01_mangos_spell_proc_event.sql \
8499_01_mangos_spell_elixir.sql \ 8499_01_mangos_spell_elixir.sql \
8504_01_mangos_playercreateinfo_spell.sql \
8504_02_mangos_playercreateinfo_action.sql \
8505_01_characters_character_spell.sql \
8511_01_mangos_spell_proc_event.sql \
8514_01_mangos_spell_bonus_data.sql \
8521_01_mangos_spell_proc_event.sql \
README README
## Additional files to include when running 'make dist' ## Additional files to include when running 'make dist'
@ -194,4 +200,10 @@ EXTRA_DIST = \
8488_02_mangos_spell_bonus_data.sql \ 8488_02_mangos_spell_bonus_data.sql \
8498_01_mangos_spell_proc_event.sql \ 8498_01_mangos_spell_proc_event.sql \
8499_01_mangos_spell_elixir.sql \ 8499_01_mangos_spell_elixir.sql \
8504_01_mangos_playercreateinfo_spell.sql \
8504_02_mangos_playercreateinfo_action.sql \
8505_01_characters_character_spell.sql \
8511_01_mangos_spell_proc_event.sql \
8514_01_mangos_spell_bonus_data.sql \
8521_01_mangos_spell_proc_event.sql \
README README

View file

@ -79,8 +79,19 @@ class MANGOS_DLL_DECL NGrid
i_GridInfo = GridInfo(expiry, unload); i_GridInfo = GridInfo(expiry, unload);
} }
const GridType& operator()(unsigned short x, unsigned short y) const { return i_cells[x][y]; } const GridType& operator()(unsigned short x, unsigned short y) const
GridType& operator()(unsigned short x, unsigned short y) { return i_cells[x][y]; } {
ASSERT(x < N);
ASSERT(y < N);
return i_cells[x][y];
}
GridType& operator()(unsigned short x, unsigned short y)
{
ASSERT(x < N);
ASSERT(y < N);
return i_cells[x][y];
}
const uint32& GetGridId(void) const { return i_gridId; } const uint32& GetGridId(void) const { return i_gridId; }
void SetGridId(const uint32 id) const { i_gridId = id; } void SetGridId(const uint32 id) const { i_gridId = id; }
@ -108,12 +119,12 @@ class MANGOS_DLL_DECL NGrid
template<class SPECIFIC_OBJECT> void AddWorldObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl) template<class SPECIFIC_OBJECT> void AddWorldObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl)
{ {
i_cells[x][y].AddWorldObject(obj, hdl); getGridType(x, y).AddWorldObject(obj, hdl);
} }
template<class SPECIFIC_OBJECT> void RemoveWorldObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl) template<class SPECIFIC_OBJECT> void RemoveWorldObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl)
{ {
i_cells[x][y].RemoveWorldObject(obj, hdl); getGridType(x, y).RemoveWorldObject(obj, hdl);
} }
template<class T, class TT> void Visit(TypeContainerVisitor<T, TypeMapContainer<TT> > &visitor) template<class T, class TT> void Visit(TypeContainerVisitor<T, TypeMapContainer<TT> > &visitor)
@ -125,7 +136,7 @@ class MANGOS_DLL_DECL NGrid
template<class T, class TT> void Visit(const uint32 &x, const uint32 &y, TypeContainerVisitor<T, TypeMapContainer<TT> > &visitor) template<class T, class TT> void Visit(const uint32 &x, const uint32 &y, TypeContainerVisitor<T, TypeMapContainer<TT> > &visitor)
{ {
i_cells[x][y].Visit(visitor); getGridType(x, y).Visit(visitor);
} }
unsigned int ActiveObjectsInGrid(void) const unsigned int ActiveObjectsInGrid(void) const
@ -139,26 +150,33 @@ class MANGOS_DLL_DECL NGrid
template<class SPECIFIC_OBJECT> const SPECIFIC_OBJECT* GetGridObject(const uint32 x, const uint32 y, OBJECT_HANDLE hdl) const template<class SPECIFIC_OBJECT> const SPECIFIC_OBJECT* GetGridObject(const uint32 x, const uint32 y, OBJECT_HANDLE hdl) const
{ {
return i_cells[x][y].template GetGridObject<SPECIFIC_OBJECT>(hdl); return getGridType(x, y).template GetGridObject<SPECIFIC_OBJECT>(hdl);
} }
template<class SPECIFIC_OBJECT> SPECIFIC_OBJECT* GetGridObject(const uint32 x, const uint32 y, OBJECT_HANDLE hdl) template<class SPECIFIC_OBJECT> SPECIFIC_OBJECT* GetGridObject(const uint32 x, const uint32 y, OBJECT_HANDLE hdl)
{ {
return i_cells[x][y].template GetGridObject<SPECIFIC_OBJECT>(hdl); return getGridType(x, y).template GetGridObject<SPECIFIC_OBJECT>(hdl);
} }
template<class SPECIFIC_OBJECT> bool AddGridObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl) template<class SPECIFIC_OBJECT> bool AddGridObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl)
{ {
return i_cells[x][y].AddGridObject(hdl, obj); return getGridType(x, y).AddGridObject(hdl, obj);
} }
template<class SPECIFIC_OBJECT> bool RemoveGridObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl) template<class SPECIFIC_OBJECT> bool RemoveGridObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl)
{ {
return i_cells[x][y].RemoveGridObject(obj, hdl); return getGridType(x, y).RemoveGridObject(obj, hdl);
} }
private: private:
GridType& getGridType(const uint32& x, const uint32& y)
{
ASSERT(x < N);
ASSERT(y < N);
return i_cells[x][y];
}
uint32 i_gridId; uint32 i_gridId;
GridInfo i_GridInfo; GridInfo i_GridInfo;
GridReference<NGrid<N, ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES, ThreadModel> > i_Reference; GridReference<NGrid<N, ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES, ThreadModel> > i_Reference;

View file

@ -605,7 +605,7 @@ void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement)
MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::AchievementChatBuilder> > say_worker(GetPlayer(),sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY),say_do); MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::AchievementChatBuilder> > say_worker(GetPlayer(),sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY),say_do);
TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::AchievementChatBuilder> >, WorldTypeMapContainer > message(say_worker); TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::AchievementChatBuilder> >, WorldTypeMapContainer > message(say_worker);
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, message, *GetPlayer()->GetMap()); cell_lock->Visit(cell_lock, message, *GetPlayer()->GetMap(), *GetPlayer(), sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY));
} }
WorldPacket data(SMSG_ACHIEVEMENT_EARNED, 8+4+8); WorldPacket data(SMSG_ACHIEVEMENT_EARNED, 8+4+8);

View file

@ -25,6 +25,7 @@
#include <cmath> #include <cmath>
class Map; class Map;
class WorldObject;
enum District enum District
{ {
@ -42,6 +43,26 @@ enum District
template<class T> struct CellLock; template<class T> struct CellLock;
struct MANGOS_DLL_DECL CellArea
{
CellArea() : right_offset(0), left_offset(0), upper_offset(0), lower_offset(0) {}
CellArea(int right, int left, int upper, int lower) : right_offset(right), left_offset(left), upper_offset(upper), lower_offset(lower) {}
bool operator!() const { return !right_offset && !left_offset && !upper_offset && !lower_offset; }
void ResizeBorders(CellPair& begin_cell, CellPair& end_cell) const
{
begin_cell << left_offset;
begin_cell -= lower_offset;
end_cell >> right_offset;
end_cell += upper_offset;
}
int right_offset;
int left_offset;
int upper_offset;
int lower_offset;
};
struct MANGOS_DLL_DECL Cell struct MANGOS_DLL_DECL Cell
{ {
Cell() { data.All = 0; } Cell() { data.All = 0; }
@ -131,15 +152,21 @@ struct MANGOS_DLL_DECL Cell
{ {
unsigned grid_x : 6; unsigned grid_x : 6;
unsigned grid_y : 6; unsigned grid_y : 6;
unsigned cell_x : 4; unsigned cell_x : 6;
unsigned cell_y : 4; unsigned cell_y : 6;
unsigned nocreate : 1; unsigned nocreate : 1;
unsigned reserved : 11; unsigned reserved : 7;
} Part; } Part;
uint32 All; uint32 All;
} data; } data;
template<class LOCK_TYPE, class T, class CONTAINER> void Visit(const CellLock<LOCK_TYPE> &, TypeContainerVisitor<T, CONTAINER> &visitor, Map &) const; template<class LOCK_TYPE, class T, class CONTAINER> void Visit(const CellLock<LOCK_TYPE> &, TypeContainerVisitor<T, CONTAINER> &visitor, Map &) const;
template<class LOCK_TYPE, class T, class CONTAINER> void Visit(const CellLock<LOCK_TYPE> &, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, const WorldObject &obj, float radius) const;
static CellArea CalculateCellArea(const WorldObject &obj, float radius);
private:
template<class LOCK_TYPE, class T, class CONTAINER> void VisitCircle(const CellLock<LOCK_TYPE> &, TypeContainerVisitor<T, CONTAINER> &, Map &, const CellPair& , const CellPair& ) const;
}; };
template<class T> template<class T>

View file

@ -127,4 +127,163 @@ Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &vi
} }
} }
} }
inline int CellHelper(const float radius)
{
if(radius < 1.0f)
return 0;
return (int)ceilf(radius/SIZE_OF_GRID_CELL);
}
inline CellArea Cell::CalculateCellArea(const WorldObject &obj, float radius)
{
if(radius <= 0.0f)
return CellArea();
//we should increase search radius by object's radius, otherwise
//we could have problems with huge creatures, which won't attack nearest players etc
radius += obj.GetObjectSize();
//lets calculate object coord offsets from cell borders.
//TODO: add more correct/generic method for this task
const float x_offset = (obj.GetPositionX() - CENTER_GRID_CELL_OFFSET)/SIZE_OF_GRID_CELL;
const float y_offset = (obj.GetPositionY() - CENTER_GRID_CELL_OFFSET)/SIZE_OF_GRID_CELL;
const float x_val = floor(x_offset + CENTER_GRID_CELL_ID + 0.5f);
const float y_val = floor(y_offset + CENTER_GRID_CELL_ID + 0.5f);
const float x_off = (x_offset - x_val + CENTER_GRID_CELL_ID) * SIZE_OF_GRID_CELL;
const float y_off = (y_offset - y_val + CENTER_GRID_CELL_ID) * SIZE_OF_GRID_CELL;
const float tmp_diff = radius - CENTER_GRID_CELL_OFFSET;
//lets calculate upper/lower/right/left corners for cell search
int right = CellHelper(tmp_diff + x_off);
int left = CellHelper(tmp_diff - x_off);
int upper = CellHelper(tmp_diff + y_off);
int lower = CellHelper(tmp_diff - y_off);
return CellArea(right, left, upper, lower);
}
template<class LOCK_TYPE, class T, class CONTAINER>
inline void
Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, const WorldObject &obj, float radius) const
{
const CellPair &standing_cell = l.i_cellPair;
if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
return;
//no jokes here... Actually placing ASSERT() here was good idea, but
//we had some problems with DynamicObjects, which pass radius = 0.0f (DB issue?)
//maybe it is better to just return when radius <= 0.0f?
if(radius <= 0.0f)
{
m.Visit(l, visitor);
return;
}
//lets limit the upper value for search radius
if(radius > 333.0f)
radius = 333.0f;
//lets calculate object coord offsets from cell borders.
CellArea area = Cell::CalculateCellArea(obj, radius);
//if radius fits inside standing cell
if(!area)
{
m.Visit(l, visitor);
return;
}
CellPair begin_cell = standing_cell;
CellPair end_cell = standing_cell;
area.ResizeBorders(begin_cell, end_cell);
//visit all cells, found in CalculateCellArea()
//if radius is known to reach cell area more than 4x4 then we should call optimized VisitCircle
//currently this technique works with MAX_NUMBER_OF_CELLS 16 and higher, with lower values
//there are nothing to optimize because SIZE_OF_GRID_CELL is too big...
if(((end_cell.x_coord - begin_cell.x_coord) > 4) && ((end_cell.y_coord - begin_cell.y_coord) > 4))
{
VisitCircle(l, visitor, m, begin_cell, end_cell);
return;
}
//ALWAYS visit standing cell first!!! Since we deal with small radiuses
//it is very essential to call visitor for standing cell firstly...
m.Visit(l, visitor);
// loop the cell range
for(uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; x++)
{
for(uint32 y = begin_cell.y_coord; y <= end_cell.y_coord; y++)
{
CellPair cell_pair(x,y);
//lets skip standing cell since we already visited it
if(cell_pair != standing_cell)
{
Cell r_zone(cell_pair);
r_zone.data.Part.nocreate = l->data.Part.nocreate;
CellLock<LOCK_TYPE> lock(r_zone, cell_pair);
m.Visit(lock, visitor);
}
}
}
}
template<class LOCK_TYPE, class T, class CONTAINER>
inline void
Cell::VisitCircle(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, const CellPair& begin_cell, const CellPair& end_cell) const
{
//here is an algorithm for 'filling' circum-squared octagon
uint32 x_shift = (uint32)ceilf((end_cell.x_coord - begin_cell.x_coord) * 0.3f - 0.5f);
//lets calculate x_start/x_end coords for central strip...
const uint32 x_start = begin_cell.x_coord + x_shift;
const uint32 x_end = end_cell.x_coord - x_shift;
//visit central strip with constant width...
for(uint32 x = x_start; x <= x_end; ++x)
{
for(uint32 y = begin_cell.y_coord; y <= end_cell.y_coord; ++y)
{
CellPair cell_pair(x,y);
Cell r_zone(cell_pair);
r_zone.data.Part.nocreate = l->data.Part.nocreate;
CellLock<LOCK_TYPE> lock(r_zone, cell_pair);
m.Visit(lock, visitor);
}
}
//if x_shift == 0 then we have too small cell area, which were already
//visited at previous step, so just return from procedure...
if(x_shift == 0)
return;
uint32 y_start = end_cell.y_coord;
uint32 y_end = begin_cell.y_coord;
//now we are visiting borders of an octagon...
for (uint32 step = 1; step <= (x_start - begin_cell.x_coord); ++step)
{
//each step reduces strip height by 2 cells...
y_end += 1;
y_start -= 1;
for (uint32 y = y_start; y >= y_end; --y)
{
//we visit cells symmetrically from both sides, heading from center to sides and from up to bottom
//e.g. filling 2 trapezoids after filling central cell strip...
CellPair cell_pair_left(x_start - step, y);
Cell r_zone_left(cell_pair_left);
r_zone_left.data.Part.nocreate = l->data.Part.nocreate;
CellLock<LOCK_TYPE> lock_left(r_zone_left, cell_pair_left);
m.Visit(lock_left, visitor);
//right trapezoid cell visit
CellPair cell_pair_right(x_end + step, y);
Cell r_zone_right(cell_pair_right);
r_zone_right.data.Part.nocreate = l->data.Part.nocreate;
CellLock<LOCK_TYPE> lock_right(r_zone_right, cell_pair_right);
m.Visit(lock_right, visitor);
}
}
}
#endif #endif

View file

@ -584,7 +584,7 @@ void WorldSession::HandleTextEmoteOpcode( WorldPacket & recv_data )
MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::EmoteChatBuilder > > emote_worker(GetPlayer(),sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),emote_do); MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::EmoteChatBuilder > > emote_worker(GetPlayer(),sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),emote_do);
TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::EmoteChatBuilder > >, WorldTypeMapContainer > message(emote_worker); TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::EmoteChatBuilder > >, WorldTypeMapContainer > message(emote_worker);
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, message, *GetPlayer()->GetMap()); cell_lock->Visit(cell_lock, message, *GetPlayer()->GetMap(), *GetPlayer(), sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit); GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit);

View file

@ -534,7 +534,7 @@ void Creature::DoFleeToGetAssistance()
TypeContainerVisitor<MaNGOS::CreatureLastSearcher<MaNGOS::NearestAssistCreatureInCreatureRangeCheck>, GridTypeMapContainer > grid_creature_searcher(searcher); TypeContainerVisitor<MaNGOS::CreatureLastSearcher<MaNGOS::NearestAssistCreatureInCreatureRangeCheck>, GridTypeMapContainer > grid_creature_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, grid_creature_searcher, *GetMap()); cell_lock->Visit(cell_lock, grid_creature_searcher, *GetMap(), *this, radius);
SetNoSearchAssistance(true); SetNoSearchAssistance(true);
if(!pCreature) if(!pCreature)
@ -1776,7 +1776,7 @@ void Creature::CallAssistance()
TypeContainerVisitor<MaNGOS::CreatureListSearcher<MaNGOS::AnyAssistCreatureInRangeCheck>, GridTypeMapContainer > grid_creature_searcher(searcher); TypeContainerVisitor<MaNGOS::CreatureListSearcher<MaNGOS::AnyAssistCreatureInRangeCheck>, GridTypeMapContainer > grid_creature_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, grid_creature_searcher, *GetMap()); cell_lock->Visit(cell_lock, grid_creature_searcher, *GetMap(), *this, radius);
} }
if (!assistList.empty()) if (!assistList.empty())
@ -1810,7 +1810,7 @@ void Creature::CallForHelp(float fRadius)
TypeContainerVisitor<MaNGOS::CreatureWorker<MaNGOS::CallOfHelpCreatureInRangeDo>, GridTypeMapContainer > grid_creature_searcher(worker); TypeContainerVisitor<MaNGOS::CreatureWorker<MaNGOS::CallOfHelpCreatureInRangeDo>, GridTypeMapContainer > grid_creature_searcher(worker);
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, grid_creature_searcher, *GetMap()); cell_lock->Visit(cell_lock, grid_creature_searcher, *GetMap(), *this, fRadius);
} }
bool Creature::CanAssistTo(const Unit* u, const Unit* enemy, bool checkfaction /*= true*/) const bool Creature::CanAssistTo(const Unit* u, const Unit* enemy, bool checkfaction /*= true*/) const

View file

@ -1214,7 +1214,7 @@ Unit* CreatureEventAI::DoSelectLowestHpFriendly(float range, uint32 MinHPDiff)
TypeContainerVisitor<MaNGOS::UnitLastSearcher<MaNGOS::MostHPMissingInRange>, GridTypeMapContainer > grid_unit_searcher(searcher); TypeContainerVisitor<MaNGOS::UnitLastSearcher<MaNGOS::MostHPMissingInRange>, GridTypeMapContainer > grid_unit_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, grid_unit_searcher, *m_creature->GetMap()); cell_lock->Visit(cell_lock, grid_unit_searcher, *m_creature->GetMap(), *m_creature, range);
return pUnit; return pUnit;
} }
@ -1231,7 +1231,7 @@ void CreatureEventAI::DoFindFriendlyCC(std::list<Creature*>& _list, float range)
TypeContainerVisitor<MaNGOS::CreatureListSearcher<MaNGOS::FriendlyCCedInRange>, GridTypeMapContainer > grid_creature_searcher(searcher); TypeContainerVisitor<MaNGOS::CreatureListSearcher<MaNGOS::FriendlyCCedInRange>, GridTypeMapContainer > grid_creature_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, grid_creature_searcher, *m_creature->GetMap()); cell_lock->Visit(cell_lock, grid_creature_searcher, *m_creature->GetMap(), *m_creature, range);
} }
void CreatureEventAI::DoFindFriendlyMissingBuff(std::list<Creature*>& _list, float range, uint32 spellid) void CreatureEventAI::DoFindFriendlyMissingBuff(std::list<Creature*>& _list, float range, uint32 spellid)
@ -1247,7 +1247,7 @@ void CreatureEventAI::DoFindFriendlyMissingBuff(std::list<Creature*>& _list, flo
TypeContainerVisitor<MaNGOS::CreatureListSearcher<MaNGOS::FriendlyMissingBuffInRange>, GridTypeMapContainer > grid_creature_searcher(searcher); TypeContainerVisitor<MaNGOS::CreatureListSearcher<MaNGOS::FriendlyMissingBuffInRange>, GridTypeMapContainer > grid_creature_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, grid_creature_searcher, *m_creature->GetMap()); cell_lock->Visit(cell_lock, grid_creature_searcher, *m_creature->GetMap(), *m_creature, range);
} }
//********************************* //*********************************

View file

@ -125,8 +125,8 @@ void DynamicObject::Update(uint32 p_time)
TypeContainerVisitor<MaNGOS::DynamicObjectUpdater, GridTypeMapContainer > grid_object_notifier(notifier); TypeContainerVisitor<MaNGOS::DynamicObjectUpdater, GridTypeMapContainer > grid_object_notifier(notifier);
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, world_object_notifier, *GetMap()); cell_lock->Visit(cell_lock, world_object_notifier, *GetMap(), *this, m_radius);
cell_lock->Visit(cell_lock, grid_object_notifier, *GetMap()); cell_lock->Visit(cell_lock, grid_object_notifier, *GetMap(), *this, m_radius);
} }
if(deleteThis) if(deleteThis)

View file

@ -319,13 +319,13 @@ void GameObject::Update(uint32 /*p_time*/)
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
TypeContainerVisitor<MaNGOS::UnitSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker); TypeContainerVisitor<MaNGOS::UnitSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker);
cell_lock->Visit(cell_lock, grid_object_checker, *GetMap()); cell_lock->Visit(cell_lock, grid_object_checker, *GetMap(), *this, radius);
// or unfriendly player/pet // or unfriendly player/pet
if(!ok) if(!ok)
{ {
TypeContainerVisitor<MaNGOS::UnitSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker); TypeContainerVisitor<MaNGOS::UnitSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker);
cell_lock->Visit(cell_lock, world_object_checker, *GetMap()); cell_lock->Visit(cell_lock, world_object_checker, *GetMap(), *this, radius);
} }
} }
else // environmental trap else // environmental trap
@ -340,7 +340,7 @@ void GameObject::Update(uint32 /*p_time*/)
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
TypeContainerVisitor<MaNGOS::PlayerSearcher<MaNGOS::AnyPlayerInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker); TypeContainerVisitor<MaNGOS::PlayerSearcher<MaNGOS::AnyPlayerInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker);
cell_lock->Visit(cell_lock, world_object_checker, *GetMap()); cell_lock->Visit(cell_lock, world_object_checker, *GetMap(), *this, radius);
ok = p_ok; ok = p_ok;
} }
@ -784,7 +784,7 @@ void GameObject::TriggeringLinkedGameObject( uint32 trapEntry, Unit* target)
TypeContainerVisitor<MaNGOS::GameObjectLastSearcher<MaNGOS::NearestGameObjectEntryInObjectRangeCheck>, GridTypeMapContainer > object_checker(checker); TypeContainerVisitor<MaNGOS::GameObjectLastSearcher<MaNGOS::NearestGameObjectEntryInObjectRangeCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, object_checker, *GetMap()); cell_lock->Visit(cell_lock, object_checker, *GetMap(), *target, range);
} }
// found correct GO // found correct GO
@ -806,7 +806,7 @@ GameObject* GameObject::LookupFishingHoleAround(float range)
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
TypeContainerVisitor<MaNGOS::GameObjectSearcher<MaNGOS::NearestGameObjectFishingHole>, GridTypeMapContainer > grid_object_checker(checker); TypeContainerVisitor<MaNGOS::GameObjectSearcher<MaNGOS::NearestGameObjectFishingHole>, GridTypeMapContainer > grid_object_checker(checker);
cell_lock->Visit(cell_lock, grid_object_checker, *GetMap()); cell_lock->Visit(cell_lock, grid_object_checker, *GetMap(), *this, range);
return ok; return ok;
} }
@ -1031,7 +1031,8 @@ void GameObject::Use(Unit* user)
//fish catched //fish catched
player->UpdateFishingSkill(); player->UpdateFishingSkill();
GameObject* ok = LookupFishingHoleAround(DEFAULT_VISIBILITY_DISTANCE); //TODO: find reasonable value for fishing hole search
GameObject* ok = LookupFishingHoleAround(20.0f + CONTACT_DISTANCE);
if (ok) if (ok)
{ {
player->SendLoot(ok->GetGUID(),LOOT_FISHINGHOLE); player->SendLoot(ok->GetGUID(),LOOT_FISHINGHOLE);

View file

@ -41,7 +41,7 @@ class Player;
#define MIN_GRID_DELAY (MINUTE*IN_MILISECONDS) #define MIN_GRID_DELAY (MINUTE*IN_MILISECONDS)
#define MIN_MAP_UPDATE_DELAY 50 #define MIN_MAP_UPDATE_DELAY 50
#define MAX_NUMBER_OF_CELLS 4 #define MAX_NUMBER_OF_CELLS 8
#define SIZE_OF_GRID_CELL (SIZE_OF_GRIDS/MAX_NUMBER_OF_CELLS) #define SIZE_OF_GRID_CELL (SIZE_OF_GRIDS/MAX_NUMBER_OF_CELLS)
#define CENTER_GRID_CELL_ID (MAX_NUMBER_OF_CELLS*MAX_NUMBER_OF_GRIDS/2) #define CENTER_GRID_CELL_ID (MAX_NUMBER_OF_CELLS*MAX_NUMBER_OF_GRIDS/2)
@ -86,26 +86,34 @@ struct MANGOS_DLL_DECL CoordPair
void operator<<(const uint32 val) void operator<<(const uint32 val)
{ {
if( x_coord >= val ) if( x_coord > val )
x_coord -= val; x_coord -= val;
else
x_coord = 0;
} }
void operator>>(const uint32 val) void operator>>(const uint32 val)
{ {
if( x_coord+val < LIMIT ) if( x_coord+val < LIMIT )
x_coord += val; x_coord += val;
else
x_coord = LIMIT - 1;
} }
void operator-=(const uint32 val) void operator-=(const uint32 val)
{ {
if( y_coord >= val ) if( y_coord > val )
y_coord -= val; y_coord -= val;
else
y_coord = 0;
} }
void operator+=(const uint32 val) void operator+=(const uint32 val)
{ {
if( y_coord+val < LIMIT ) if( y_coord+val < LIMIT )
y_coord += val; y_coord += val;
else
y_coord = LIMIT - 1;
} }
uint32 x_coord; uint32 x_coord;

View file

@ -190,6 +190,7 @@ bool ChatHandler::HandleReloadConfigCommand(const char* /*args*/)
{ {
sLog.outString( "Re-Loading config settings..." ); sLog.outString( "Re-Loading config settings..." );
sWorld.LoadConfigSettings(true); sWorld.LoadConfigSettings(true);
MapManager::Instance().InitializeVisibilityDistanceInfo();
SendGlobalSysMessage("World config settings reloaded."); SendGlobalSysMessage("World config settings reloaded.");
return true; return true;
} }

View file

@ -41,6 +41,7 @@
#define DEFAULT_GRID_EXPIRY 300 #define DEFAULT_GRID_EXPIRY 300
#define MAX_GRID_LOAD_TIME 50 #define MAX_GRID_LOAD_TIME 50
#define MAX_CREATURE_ATTACK_RADIUS (45.0f * sWorld.getRate(RATE_CREATURE_AGGRO))
GridState* si_GridStates[MAX_GRID_STATE]; GridState* si_GridStates[MAX_GRID_STATE];
@ -198,7 +199,8 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _par
: i_mapEntry (sMapStore.LookupEntry(id)), i_spawnMode(SpawnMode), : i_mapEntry (sMapStore.LookupEntry(id)), i_spawnMode(SpawnMode),
i_id(id), i_InstanceId(InstanceId), m_unloadTimer(0), i_id(id), i_InstanceId(InstanceId), m_unloadTimer(0),
m_activeNonPlayersIter(m_activeNonPlayers.end()), m_activeNonPlayersIter(m_activeNonPlayers.end()),
i_gridExpiry(expiry), m_parentMap(_parent ? _parent : this) i_gridExpiry(expiry), m_parentMap(_parent ? _parent : this),
m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE)
{ {
for(unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx) for(unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx)
{ {
@ -209,6 +211,15 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _par
setNGrid(NULL, idx, j); setNGrid(NULL, idx, j);
} }
} }
//lets initialize visibility distance for map
Map::InitVisibilityDistance();
}
void Map::InitVisibilityDistance()
{
//init visibility for continents
m_VisibleDistance = sWorld.GetMaxVisibleDistanceOnContinents();
} }
// Template specialization of utility methods // Template specialization of utility methods
@ -346,8 +357,8 @@ Map::EnsureGridCreated(const GridPair &p)
getNGrid(p.x_coord, p.y_coord)->SetGridState(GRID_STATE_IDLE); getNGrid(p.x_coord, p.y_coord)->SetGridState(GRID_STATE_IDLE);
//z coord //z coord
int gx=63-p.x_coord; int gx = (MAX_NUMBER_OF_GRIDS - 1) - p.x_coord;
int gy=63-p.y_coord; int gy = (MAX_NUMBER_OF_GRIDS - 1) - p.y_coord;
if(!GridMaps[gx][gy]) if(!GridMaps[gx][gy])
LoadMapAndVMap(gx,gy); LoadMapAndVMap(gx,gy);
@ -491,7 +502,7 @@ void Map::MessageBroadcast(Player *player, WorldPacket *msg, bool to_self)
MaNGOS::MessageDeliverer post_man(*player, msg, to_self); MaNGOS::MessageDeliverer post_man(*player, msg, to_self);
TypeContainerVisitor<MaNGOS::MessageDeliverer, WorldTypeMapContainer > message(post_man); TypeContainerVisitor<MaNGOS::MessageDeliverer, WorldTypeMapContainer > message(post_man);
CellLock<ReadGuard> cell_lock(cell, p); CellLock<ReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, message, *this); cell_lock->Visit(cell_lock, message, *this, *player, GetVisibilityDistance());
} }
void Map::MessageBroadcast(WorldObject *obj, WorldPacket *msg) void Map::MessageBroadcast(WorldObject *obj, WorldPacket *msg)
@ -511,10 +522,12 @@ void Map::MessageBroadcast(WorldObject *obj, WorldPacket *msg)
if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) ) if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) )
return; return;
//TODO: currently on continents when Visibility.Distance.InFlight > Visibility.Distance.Continents
//we have alot of blinking mobs because monster move packet send is broken...
MaNGOS::ObjectMessageDeliverer post_man(*obj,msg); MaNGOS::ObjectMessageDeliverer post_man(*obj,msg);
TypeContainerVisitor<MaNGOS::ObjectMessageDeliverer, WorldTypeMapContainer > message(post_man); TypeContainerVisitor<MaNGOS::ObjectMessageDeliverer, WorldTypeMapContainer > message(post_man);
CellLock<ReadGuard> cell_lock(cell, p); CellLock<ReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, message, *this); cell_lock->Visit(cell_lock, message, *this, *obj, GetVisibilityDistance());
} }
void Map::MessageDistBroadcast(Player *player, WorldPacket *msg, float dist, bool to_self, bool own_team_only) void Map::MessageDistBroadcast(Player *player, WorldPacket *msg, float dist, bool to_self, bool own_team_only)
@ -537,7 +550,7 @@ void Map::MessageDistBroadcast(Player *player, WorldPacket *msg, float dist, boo
MaNGOS::MessageDistDeliverer post_man(*player, msg, dist, to_self, own_team_only); MaNGOS::MessageDistDeliverer post_man(*player, msg, dist, to_self, own_team_only);
TypeContainerVisitor<MaNGOS::MessageDistDeliverer , WorldTypeMapContainer > message(post_man); TypeContainerVisitor<MaNGOS::MessageDistDeliverer , WorldTypeMapContainer > message(post_man);
CellLock<ReadGuard> cell_lock(cell, p); CellLock<ReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, message, *this); cell_lock->Visit(cell_lock, message, *this, *player, dist);
} }
void Map::MessageDistBroadcast(WorldObject *obj, WorldPacket *msg, float dist) void Map::MessageDistBroadcast(WorldObject *obj, WorldPacket *msg, float dist)
@ -557,10 +570,10 @@ void Map::MessageDistBroadcast(WorldObject *obj, WorldPacket *msg, float dist)
if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) ) if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) )
return; return;
MaNGOS::ObjectMessageDistDeliverer post_man(*obj, msg,dist); MaNGOS::ObjectMessageDistDeliverer post_man(*obj, msg, dist);
TypeContainerVisitor<MaNGOS::ObjectMessageDistDeliverer, WorldTypeMapContainer > message(post_man); TypeContainerVisitor<MaNGOS::ObjectMessageDistDeliverer, WorldTypeMapContainer > message(post_man);
CellLock<ReadGuard> cell_lock(cell, p); CellLock<ReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, message, *this); cell_lock->Visit(cell_lock, message, *this, *obj, dist);
} }
bool Map::loaded(const GridPair &p) const bool Map::loaded(const GridPair &p) const
@ -605,8 +618,9 @@ void Map::Update(const uint32 &t_diff)
// the overloaded operators handle range checking // the overloaded operators handle range checking
// so ther's no need for range checking inside the loop // so ther's no need for range checking inside the loop
CellPair begin_cell(standing_cell), end_cell(standing_cell); CellPair begin_cell(standing_cell), end_cell(standing_cell);
begin_cell << 1; begin_cell -= 1; // upper left //lets update mobs/objects in ALL visible cells around player!
end_cell >> 1; end_cell += 1; // lower right CellArea area = Cell::CalculateCellArea(*plr, GetVisibilityDistance());
area.ResizeBorders(begin_cell, end_cell);
for(uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; ++x) for(uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; ++x)
{ {
@ -1044,8 +1058,9 @@ bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool pForce)
delete getNGrid(x, y); delete getNGrid(x, y);
setNGrid(NULL, x, y); setNGrid(NULL, x, y);
} }
int gx=63-x;
int gy=63-y; int gx = (MAX_NUMBER_OF_GRIDS - 1) - x;
int gy = (MAX_NUMBER_OF_GRIDS - 1) - y;
// delete grid map, but don't delete if it is from parent map (and thus only reference) // delete grid map, but don't delete if it is from parent map (and thus only reference)
//+++if (GridMaps[gx][gy]) don't check for GridMaps[gx][gy], we might have to unload vmaps //+++if (GridMaps[gx][gy]) don't check for GridMaps[gx][gy], we might have to unload vmaps
@ -1921,7 +1936,7 @@ void Map::UpdateObjectVisibility( WorldObject* obj, Cell cell, CellPair cellpair
MaNGOS::VisibleChangesNotifier notifier(*obj); MaNGOS::VisibleChangesNotifier notifier(*obj);
TypeContainerVisitor<MaNGOS::VisibleChangesNotifier, WorldTypeMapContainer > player_notifier(notifier); TypeContainerVisitor<MaNGOS::VisibleChangesNotifier, WorldTypeMapContainer > player_notifier(notifier);
CellLock<GridReadGuard> cell_lock(cell, cellpair); CellLock<GridReadGuard> cell_lock(cell, cellpair);
cell_lock->Visit(cell_lock, player_notifier, *this); cell_lock->Visit(cell_lock, player_notifier, *this, *obj, GetVisibilityDistance());
} }
void Map::UpdatePlayerVisibility( Player* player, Cell cell, CellPair cellpair ) void Map::UpdatePlayerVisibility( Player* player, Cell cell, CellPair cellpair )
@ -1932,7 +1947,7 @@ void Map::UpdatePlayerVisibility( Player* player, Cell cell, CellPair cellpair )
TypeContainerVisitor<MaNGOS::PlayerNotifier, WorldTypeMapContainer > player_notifier(pl_notifier); TypeContainerVisitor<MaNGOS::PlayerNotifier, WorldTypeMapContainer > player_notifier(pl_notifier);
CellLock<ReadGuard> cell_lock(cell, cellpair); CellLock<ReadGuard> cell_lock(cell, cellpair);
cell_lock->Visit(cell_lock, player_notifier, *this); cell_lock->Visit(cell_lock, player_notifier, *this, *player, GetVisibilityDistance());
} }
void Map::UpdateObjectsVisibilityFor( Player* player, Cell cell, CellPair cellpair ) void Map::UpdateObjectsVisibilityFor( Player* player, Cell cell, CellPair cellpair )
@ -1944,8 +1959,8 @@ void Map::UpdateObjectsVisibilityFor( Player* player, Cell cell, CellPair cellpa
TypeContainerVisitor<MaNGOS::VisibleNotifier, WorldTypeMapContainer > world_notifier(notifier); TypeContainerVisitor<MaNGOS::VisibleNotifier, WorldTypeMapContainer > world_notifier(notifier);
TypeContainerVisitor<MaNGOS::VisibleNotifier, GridTypeMapContainer > grid_notifier(notifier); TypeContainerVisitor<MaNGOS::VisibleNotifier, GridTypeMapContainer > grid_notifier(notifier);
CellLock<GridReadGuard> cell_lock(cell, cellpair); CellLock<GridReadGuard> cell_lock(cell, cellpair);
cell_lock->Visit(cell_lock, world_notifier, *this); cell_lock->Visit(cell_lock, world_notifier, *this, *player, GetVisibilityDistance());
cell_lock->Visit(cell_lock, grid_notifier, *this); cell_lock->Visit(cell_lock, grid_notifier, *this, *player, GetVisibilityDistance());
// send data // send data
notifier.Notify(); notifier.Notify();
@ -1960,8 +1975,8 @@ void Map::PlayerRelocationNotify( Player* player, Cell cell, CellPair cellpair )
TypeContainerVisitor<MaNGOS::PlayerRelocationNotifier, GridTypeMapContainer > p2grid_relocation(relocationNotifier); TypeContainerVisitor<MaNGOS::PlayerRelocationNotifier, GridTypeMapContainer > p2grid_relocation(relocationNotifier);
TypeContainerVisitor<MaNGOS::PlayerRelocationNotifier, WorldTypeMapContainer > p2world_relocation(relocationNotifier); TypeContainerVisitor<MaNGOS::PlayerRelocationNotifier, WorldTypeMapContainer > p2world_relocation(relocationNotifier);
cell_lock->Visit(cell_lock, p2grid_relocation, *this); cell_lock->Visit(cell_lock, p2grid_relocation, *this, *player, MAX_CREATURE_ATTACK_RADIUS);
cell_lock->Visit(cell_lock, p2world_relocation, *this); cell_lock->Visit(cell_lock, p2world_relocation, *this, *player, MAX_CREATURE_ATTACK_RADIUS);
} }
void Map::CreatureRelocationNotify(Creature *creature, Cell cell, CellPair cellpair) void Map::CreatureRelocationNotify(Creature *creature, Cell cell, CellPair cellpair)
@ -1974,8 +1989,8 @@ void Map::CreatureRelocationNotify(Creature *creature, Cell cell, CellPair cellp
TypeContainerVisitor<MaNGOS::CreatureRelocationNotifier, WorldTypeMapContainer > c2world_relocation(relocationNotifier); TypeContainerVisitor<MaNGOS::CreatureRelocationNotifier, WorldTypeMapContainer > c2world_relocation(relocationNotifier);
TypeContainerVisitor<MaNGOS::CreatureRelocationNotifier, GridTypeMapContainer > c2grid_relocation(relocationNotifier); TypeContainerVisitor<MaNGOS::CreatureRelocationNotifier, GridTypeMapContainer > c2grid_relocation(relocationNotifier);
cell_lock->Visit(cell_lock, c2world_relocation, *this); cell_lock->Visit(cell_lock, c2world_relocation, *this, *creature, MAX_CREATURE_ATTACK_RADIUS);
cell_lock->Visit(cell_lock, c2grid_relocation, *this); cell_lock->Visit(cell_lock, c2grid_relocation, *this, *creature, MAX_CREATURE_ATTACK_RADIUS);
} }
void Map::SendInitSelf( Player * player ) void Map::SendInitSelf( Player * player )
@ -2145,12 +2160,20 @@ void Map::SendToPlayers(WorldPacket const* data) const
bool Map::ActiveObjectsNearGrid(uint32 x, uint32 y) const bool Map::ActiveObjectsNearGrid(uint32 x, uint32 y) const
{ {
ASSERT(x < MAX_NUMBER_OF_GRIDS);
ASSERT(y < MAX_NUMBER_OF_GRIDS);
CellPair cell_min(x*MAX_NUMBER_OF_CELLS, y*MAX_NUMBER_OF_CELLS); CellPair cell_min(x*MAX_NUMBER_OF_CELLS, y*MAX_NUMBER_OF_CELLS);
CellPair cell_max(cell_min.x_coord + MAX_NUMBER_OF_CELLS, cell_min.y_coord+MAX_NUMBER_OF_CELLS); CellPair cell_max(cell_min.x_coord + MAX_NUMBER_OF_CELLS, cell_min.y_coord+MAX_NUMBER_OF_CELLS);
cell_min << 2;
cell_min -= 2; //we must find visible range in cells so we unload only non-visible cells...
cell_max >> 2; float viewDist = GetVisibilityDistance();
cell_max += 2; int cell_range = (int)ceilf(viewDist / SIZE_OF_GRID_CELL) + 1;
cell_min << cell_range;
cell_min -= cell_range;
cell_max >> cell_range;
cell_max += cell_range;
for(MapRefManager::const_iterator iter = m_mapRefManager.begin(); iter != m_mapRefManager.end(); ++iter) for(MapRefManager::const_iterator iter = m_mapRefManager.begin(); iter != m_mapRefManager.end(); ++iter)
{ {
@ -2234,6 +2257,9 @@ InstanceMap::InstanceMap(uint32 id, time_t expiry, uint32 InstanceId, uint8 Spaw
m_resetAfterUnload(false), m_unloadWhenEmpty(false), m_resetAfterUnload(false), m_unloadWhenEmpty(false),
i_data(NULL), i_script_id(0) i_data(NULL), i_script_id(0)
{ {
//lets initialize visibility distance for dungeons
InstanceMap::InitVisibilityDistance();
// the timer is started by default, and stopped when the first player joins // the timer is started by default, and stopped when the first player joins
// this make sure it gets unloaded if for some reason no player joins // this make sure it gets unloaded if for some reason no player joins
m_unloadTimer = std::max(sWorld.getConfig(CONFIG_INSTANCE_UNLOAD_DELAY), (uint32)MIN_UNLOAD_DELAY); m_unloadTimer = std::max(sWorld.getConfig(CONFIG_INSTANCE_UNLOAD_DELAY), (uint32)MIN_UNLOAD_DELAY);
@ -2248,6 +2274,12 @@ InstanceMap::~InstanceMap()
} }
} }
void InstanceMap::InitVisibilityDistance()
{
//init visibility distance for instances
m_VisibleDistance = sWorld.GetMaxVisibleDistanceInInstances();
}
/* /*
Do map specific checks to see if the player can enter Do map specific checks to see if the player can enter
*/ */
@ -2570,12 +2602,20 @@ uint32 InstanceMap::GetMaxPlayers() const
BattleGroundMap::BattleGroundMap(uint32 id, time_t expiry, uint32 InstanceId, Map* _parent) BattleGroundMap::BattleGroundMap(uint32 id, time_t expiry, uint32 InstanceId, Map* _parent)
: Map(id, expiry, InstanceId, DUNGEON_DIFFICULTY_NORMAL, _parent) : Map(id, expiry, InstanceId, DUNGEON_DIFFICULTY_NORMAL, _parent)
{ {
//lets initialize visibility distance for BG/Arenas
BattleGroundMap::InitVisibilityDistance();
} }
BattleGroundMap::~BattleGroundMap() BattleGroundMap::~BattleGroundMap()
{ {
} }
void BattleGroundMap::InitVisibilityDistance()
{
//init visibility distance for BG/Arenas
m_VisibleDistance = sWorld.GetMaxVisibleDistanceInBGArenas();
}
bool BattleGroundMap::CanEnter(Player * player) bool BattleGroundMap::CanEnter(Player * player)
{ {
if(player->GetMapRef().getTarget() == this) if(player->GetMapRef().getTarget() == this)

View file

@ -279,6 +279,10 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
void MessageDistBroadcast(Player *, WorldPacket *, float dist, bool to_self, bool own_team_only = false); void MessageDistBroadcast(Player *, WorldPacket *, float dist, bool to_self, bool own_team_only = false);
void MessageDistBroadcast(WorldObject *, WorldPacket *, float dist); void MessageDistBroadcast(WorldObject *, WorldPacket *, float dist);
float GetVisibilityDistance() const { return m_VisibleDistance; }
//function for setting up visibility distance for maps on per-type/per-Id basis
virtual void InitVisibilityDistance();
void PlayerRelocation(Player *, float x, float y, float z, float angl); void PlayerRelocation(Player *, float x, float y, float z, float angl);
void CreatureRelocation(Creature *creature, float x, float y, float, float); void CreatureRelocation(Creature *creature, float x, float y, float, float);
@ -424,7 +428,6 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
GridMap *GetGrid(float x, float y); GridMap *GetGrid(float x, float y);
void SetTimer(uint32 t) { i_gridExpiry = t < MIN_GRID_DELAY ? MIN_GRID_DELAY : t; } void SetTimer(uint32 t) { i_gridExpiry = t < MIN_GRID_DELAY ? MIN_GRID_DELAY : t; }
//uint64 CalculateGridMask(const uint32 &y) const;
void SendInitSelf( Player * player ); void SendInitSelf( Player * player );
@ -451,6 +454,8 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
NGridType* getNGrid(uint32 x, uint32 y) const NGridType* getNGrid(uint32 x, uint32 y) const
{ {
ASSERT(x < MAX_NUMBER_OF_GRIDS);
ASSERT(y < MAX_NUMBER_OF_GRIDS);
return i_grids[x][y]; return i_grids[x][y];
} }
@ -470,6 +475,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
uint32 i_id; uint32 i_id;
uint32 i_InstanceId; uint32 i_InstanceId;
uint32 m_unloadTimer; uint32 m_unloadTimer;
float m_VisibleDistance;
MapRefManager m_mapRefManager; MapRefManager m_mapRefManager;
MapRefManager::iterator m_mapRefIter; MapRefManager::iterator m_mapRefIter;
@ -557,6 +563,8 @@ class MANGOS_DLL_SPEC InstanceMap : public Map
void SendResetWarnings(uint32 timeLeft) const; void SendResetWarnings(uint32 timeLeft) const;
void SetResetSchedule(bool on); void SetResetSchedule(bool on);
uint32 GetMaxPlayers() const; uint32 GetMaxPlayers() const;
virtual void InitVisibilityDistance();
private: private:
bool m_resetAfterUnload; bool m_resetAfterUnload;
bool m_unloadWhenEmpty; bool m_unloadWhenEmpty;
@ -575,6 +583,8 @@ class MANGOS_DLL_SPEC BattleGroundMap : public Map
bool CanEnter(Player* player); bool CanEnter(Player* player);
void SetUnload(); void SetUnload();
void UnloadAll(bool pForce); void UnloadAll(bool pForce);
virtual void InitVisibilityDistance();
}; };
/*inline /*inline

View file

@ -32,6 +32,17 @@ MapInstanced::MapInstanced(uint32 id, time_t expiry) : Map(id, expiry, 0, 0)
memset(&GridMapReference, 0, MAX_NUMBER_OF_GRIDS*MAX_NUMBER_OF_GRIDS*sizeof(uint16)); memset(&GridMapReference, 0, MAX_NUMBER_OF_GRIDS*MAX_NUMBER_OF_GRIDS*sizeof(uint16));
} }
void MapInstanced::InitVisibilityDistance()
{
if(m_InstancedMaps.empty())
return;
//initialize visibility distances for all instance copies
for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); ++i)
{
(*i).second->InitVisibilityDistance();
}
}
void MapInstanced::Update(const uint32& t) void MapInstanced::Update(const uint32& t)
{ {
// take care of loaded GridMaps (when unused, unload it!) // take care of loaded GridMaps (when unused, unload it!)

View file

@ -57,6 +57,7 @@ class MANGOS_DLL_DECL MapInstanced : public Map
} }
InstancedMaps &GetInstancedMaps() { return m_InstancedMaps; } InstancedMaps &GetInstancedMaps() { return m_InstancedMaps; }
virtual void InitVisibilityDistance();
private: private:

View file

@ -70,6 +70,12 @@ MapManager::Initialize()
InitMaxInstanceId(); InitMaxInstanceId();
} }
void MapManager::InitializeVisibilityDistanceInfo()
{
for(MapMapType::iterator iter=i_maps.begin(); iter != i_maps.end(); ++iter)
(*iter).second->InitVisibilityDistance();
}
// debugging code, should be deleted some day // debugging code, should be deleted some day
void MapManager::checkAndCorrectGridStatesArray() void MapManager::checkAndCorrectGridStatesArray()
{ {

View file

@ -122,6 +122,7 @@ class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton<MapManager, MaNGOS::
void RemoveBonesFromMap(uint32 mapid, uint64 guid, float x, float y); void RemoveBonesFromMap(uint32 mapid, uint64 guid, float x, float y);
uint32 GenerateInstanceId() { return ++i_MaxInstanceId; } uint32 GenerateInstanceId() { return ++i_MaxInstanceId; }
void InitMaxInstanceId(); void InitMaxInstanceId();
void InitializeVisibilityDistanceInfo();
/* statistics */ /* statistics */
uint32 GetNumInstances(); uint32 GetNumInstances();

View file

@ -1479,7 +1479,7 @@ void WorldObject::MonsterSay(int32 textId, uint32 language, uint64 TargetGuid)
MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> > say_worker(this,sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY),say_do); MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> > say_worker(this,sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY),say_do);
TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> >, WorldTypeMapContainer > message(say_worker); TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> >, WorldTypeMapContainer > message(say_worker);
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, message, *GetMap()); cell_lock->Visit(cell_lock, message, *GetMap(), *this, sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY));
} }
void WorldObject::MonsterYell(int32 textId, uint32 language, uint64 TargetGuid) void WorldObject::MonsterYell(int32 textId, uint32 language, uint64 TargetGuid)
@ -1495,7 +1495,7 @@ void WorldObject::MonsterYell(int32 textId, uint32 language, uint64 TargetGuid)
MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> > say_worker(this,sWorld.getConfig(CONFIG_LISTEN_RANGE_YELL),say_do); MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> > say_worker(this,sWorld.getConfig(CONFIG_LISTEN_RANGE_YELL),say_do);
TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> >, WorldTypeMapContainer > message(say_worker); TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> >, WorldTypeMapContainer > message(say_worker);
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, message, *GetMap()); cell_lock->Visit(cell_lock, message, *GetMap(), *this, sWorld.getConfig(CONFIG_LISTEN_RANGE_YELL));
} }
void WorldObject::MonsterYellToZone(int32 textId, uint32 language, uint64 TargetGuid) void WorldObject::MonsterYellToZone(int32 textId, uint32 language, uint64 TargetGuid)
@ -1524,7 +1524,7 @@ void WorldObject::MonsterTextEmote(int32 textId, uint64 TargetGuid, bool IsBossE
MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> > say_worker(this,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),say_do); MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> > say_worker(this,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),say_do);
TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> >, WorldTypeMapContainer > message(say_worker); TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> >, WorldTypeMapContainer > message(say_worker);
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, message, *GetMap()); cell_lock->Visit(cell_lock, message, *GetMap(), *this, sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
} }
void WorldObject::MonsterWhisper(int32 textId, uint64 receiver, bool IsBossWhisper) void WorldObject::MonsterWhisper(int32 textId, uint64 receiver, bool IsBossWhisper)
@ -1755,8 +1755,8 @@ void WorldObject::GetNearPoint(WorldObject const* searcher, float &x, float &y,
TypeContainerVisitor<MaNGOS::WorldObjectWorker<MaNGOS::NearUsedPosDo>, WorldTypeMapContainer > world_obj_worker(worker); TypeContainerVisitor<MaNGOS::WorldObjectWorker<MaNGOS::NearUsedPosDo>, WorldTypeMapContainer > world_obj_worker(worker);
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, grid_obj_worker, *GetMap()); cell_lock->Visit(cell_lock, grid_obj_worker, *GetMap(), *this, distance2d);
cell_lock->Visit(cell_lock, world_obj_worker, *GetMap()); cell_lock->Visit(cell_lock, world_obj_worker, *GetMap(), *this, distance2d);
} }
// maybe can just place in primary position // maybe can just place in primary position

View file

@ -32,10 +32,13 @@
#define CONTACT_DISTANCE 0.5f #define CONTACT_DISTANCE 0.5f
#define INTERACTION_DISTANCE 5.0f #define INTERACTION_DISTANCE 5.0f
#define ATTACK_DISTANCE 5.0f #define ATTACK_DISTANCE 5.0f
#define MAX_VISIBILITY_DISTANCE (5*SIZE_OF_GRID_CELL/2.0f) // max distance for visible object show, limited by active zone for player based at cell size (active zone = 5x5 cells) #define MAX_VISIBILITY_DISTANCE 333.0f // max distance for visible object show, limited in 333 yards
#define DEFAULT_VISIBILITY_DISTANCE (SIZE_OF_GRID_CELL) // default visible distance #define DEFAULT_VISIBILITY_DISTANCE 90.0f // default visible distance, 90 yards on continents
#define DEFAULT_VISIBILITY_INSTANCE 120.0f // default visible distance in instances, 120 yards
#define DEFAULT_VISIBILITY_BGARENAS 180.0f // default visible distance in BG/Arenas, 180 yards
#define DEFAULT_WORLD_OBJECT_SIZE 0.388999998569489f // player size, also currently used (correctly?) for any non Unit world objects #define DEFAULT_WORLD_OBJECT_SIZE 0.388999998569489f // player size, also currently used (correctly?) for any non Unit world objects
#define MAX_STEALTH_DETECT_RANGE 45.0f
enum TypeMask enum TypeMask
{ {

View file

@ -254,7 +254,9 @@ ObjectAccessor::_buildChangeObjectForPlayer(WorldObject *obj, UpdateDataMapType
WorldObjectChangeAccumulator notifier(*obj, update_players); WorldObjectChangeAccumulator notifier(*obj, update_players);
TypeContainerVisitor<WorldObjectChangeAccumulator, WorldTypeMapContainer > player_notifier(notifier); TypeContainerVisitor<WorldObjectChangeAccumulator, WorldTypeMapContainer > player_notifier(notifier);
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, player_notifier, *obj->GetMap()); Map& map = *obj->GetMap();
//we must build packets for all visible players
cell_lock->Visit(cell_lock, player_notifier, map, *obj, map.GetVisibilityDistance());
} }
Pet* Pet*

View file

@ -12137,34 +12137,36 @@ void Player::PrepareQuestMenu( uint64 guid )
} }
} }
void Player::SendPreparedQuest( uint64 guid ) void Player::SendPreparedQuest(uint64 guid)
{ {
QuestMenu& questMenu = PlayerTalkClass->GetQuestMenu(); QuestMenu& questMenu = PlayerTalkClass->GetQuestMenu();
if( questMenu.Empty() )
if (questMenu.Empty())
return; return;
QuestMenuItem const& qmi0 = questMenu.GetItem( 0 ); QuestMenuItem const& qmi0 = questMenu.GetItem(0);
uint32 status = qmi0.m_qIcon; uint32 status = qmi0.m_qIcon;
// single element case // single element case
if ( questMenu.MenuItemCount() == 1 ) if (questMenu.MenuItemCount() == 1)
{ {
// Auto open -- maybe also should verify there is no greeting // Auto open -- maybe also should verify there is no greeting
uint32 quest_id = qmi0.m_qId; uint32 quest_id = qmi0.m_qId;
Quest const* pQuest = objmgr.GetQuestTemplate(quest_id); Quest const* pQuest = objmgr.GetQuestTemplate(quest_id);
if ( pQuest ) if (pQuest)
{ {
if( status == DIALOG_STATUS_UNK2 && !GetQuestRewardStatus( quest_id ) ) if (status == DIALOG_STATUS_UNK2 && !GetQuestRewardStatus(quest_id))
PlayerTalkClass->SendQuestGiverRequestItems( pQuest, guid, CanRewardQuest(pQuest, false), true ); PlayerTalkClass->SendQuestGiverRequestItems(pQuest, guid, CanRewardQuest(pQuest, false), true);
else if( status == DIALOG_STATUS_UNK2 ) else if (status == DIALOG_STATUS_UNK2)
PlayerTalkClass->SendQuestGiverRequestItems( pQuest, guid, CanRewardQuest(pQuest, false), true ); PlayerTalkClass->SendQuestGiverRequestItems(pQuest, guid, CanRewardQuest(pQuest, false), true);
// Send completable on repeatable quest if player don't have quest // Send completable on repeatable and autoCompletable quest if player don't have quest
else if( pQuest->IsRepeatable() && !pQuest->IsDaily() ) // TODO: verify if check for !pQuest->IsDaily() is really correct (possibly not)
PlayerTalkClass->SendQuestGiverRequestItems( pQuest, guid, CanCompleteRepeatableQuest(pQuest), true ); else if (pQuest->IsAutoComplete() && pQuest->IsRepeatable() && !pQuest->IsDaily())
PlayerTalkClass->SendQuestGiverRequestItems(pQuest, guid, CanCompleteRepeatableQuest(pQuest), true);
else else
PlayerTalkClass->SendQuestGiverQuestDetails( pQuest, guid, true ); PlayerTalkClass->SendQuestGiverQuestDetails(pQuest, guid, true);
} }
} }
// multiply entries // multiply entries
@ -12177,11 +12179,11 @@ void Player::SendPreparedQuest( uint64 guid )
// need pet case for some quests // need pet case for some quests
Creature *pCreature = ObjectAccessor::GetCreatureOrPetOrVehicle(*this,guid); Creature *pCreature = ObjectAccessor::GetCreatureOrPetOrVehicle(*this,guid);
if( pCreature ) if (pCreature)
{ {
uint32 textid = pCreature->GetNpcTextId(); uint32 textid = pCreature->GetNpcTextId();
GossipText const* gossiptext = objmgr.GetGossipText(textid); GossipText const* gossiptext = objmgr.GetGossipText(textid);
if( !gossiptext ) if (!gossiptext)
{ {
qe._Delay = 0; //TEXTEMOTE_MESSAGE; //zyg: player emote qe._Delay = 0; //TEXTEMOTE_MESSAGE; //zyg: player emote
qe._Emote = 0; //TEXTEMOTE_HELLO; //zyg: NPC emote qe._Emote = 0; //TEXTEMOTE_HELLO; //zyg: NPC emote
@ -12223,7 +12225,7 @@ void Player::SendPreparedQuest( uint64 guid )
} }
} }
} }
PlayerTalkClass->SendQuestGiverQuestList( qe, title, guid ); PlayerTalkClass->SendQuestGiverQuestList(qe, title, guid);
} }
} }
@ -16819,8 +16821,8 @@ void Player::HandleStealthedUnitsDetection()
TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyStealthedCheck >, GridTypeMapContainer > grid_unit_searcher(searcher); TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyStealthedCheck >, GridTypeMapContainer > grid_unit_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, world_unit_searcher, *GetMap()); cell_lock->Visit(cell_lock, world_unit_searcher, *GetMap(), *this, MAX_PLAYER_STEALTH_DETECT_RANGE);
cell_lock->Visit(cell_lock, grid_unit_searcher, *GetMap()); cell_lock->Visit(cell_lock, grid_unit_searcher, *GetMap(), *this, MAX_PLAYER_STEALTH_DETECT_RANGE);
WorldObject const* viewPoint = GetViewPoint(); WorldObject const* viewPoint = GetViewPoint();
@ -19631,7 +19633,7 @@ void Player::SetTitle(CharTitlesEntry const* title, bool lost)
GetSession()->SendPacket(&data); GetSession()->SendPacket(&data);
} }
void Player::ConvertRune(uint8 index, uint8 newType) void Player::ConvertRune(uint8 index, RuneType newType)
{ {
SetCurrentRune(index, newType); SetCurrentRune(index, newType);
@ -19659,6 +19661,15 @@ void Player::AddRunePower(uint8 index)
GetSession()->SendPacket(&data); GetSession()->SendPacket(&data);
} }
static RuneType runeSlotTypes[MAX_RUNES] = {
/*0*/ RUNE_BLOOD,
/*1*/ RUNE_BLOOD,
/*2*/ RUNE_UNHOLY,
/*3*/ RUNE_UNHOLY,
/*4*/ RUNE_FROST,
/*5*/ RUNE_FROST
};
void Player::InitRunes() void Player::InitRunes()
{ {
if(getClass() != CLASS_DEATH_KNIGHT) if(getClass() != CLASS_DEATH_KNIGHT)
@ -19670,8 +19681,8 @@ void Player::InitRunes()
for(uint32 i = 0; i < MAX_RUNES; ++i) for(uint32 i = 0; i < MAX_RUNES; ++i)
{ {
SetBaseRune(i, i / 2); // init base types SetBaseRune(i, runeSlotTypes[i]); // init base types
SetCurrentRune(i, i / 2); // init current types SetCurrentRune(i, runeSlotTypes[i]); // init current types
SetRuneCooldown(i, 0); // reset cooldowns SetRuneCooldown(i, 0); // reset cooldowns
m_runes->SetRuneState(i); m_runes->SetRuneState(i);
} }
@ -19680,6 +19691,16 @@ void Player::InitRunes()
SetFloatValue(PLAYER_RUNE_REGEN_1 + i, 0.1f); SetFloatValue(PLAYER_RUNE_REGEN_1 + i, 0.1f);
} }
bool Player::IsBaseRuneSlotsOnCooldown( RuneType runeType ) const
{
for(uint32 i = 0; i < MAX_RUNES; ++i)
if (GetBaseRune(i) == runeType && GetRuneCooldown(i) == 0)
return false;
return true;
}
void Player::AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore const& store, bool broadcast) void Player::AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore const& store, bool broadcast)
{ {
Loot loot; Loot loot;

View file

@ -2222,13 +2222,14 @@ class MANGOS_DLL_SPEC Player : public Unit
DeclinedName const* GetDeclinedNames() const { return m_declinedname; } DeclinedName const* GetDeclinedNames() const { return m_declinedname; }
uint8 GetRunesState() const { return m_runes->runeState; } uint8 GetRunesState() const { return m_runes->runeState; }
uint8 GetBaseRune(uint8 index) const { return m_runes->runes[index].BaseRune; } RuneType GetBaseRune(uint8 index) const { return RuneType(m_runes->runes[index].BaseRune); }
uint8 GetCurrentRune(uint8 index) const { return m_runes->runes[index].CurrentRune; } RuneType GetCurrentRune(uint8 index) const { return RuneType(m_runes->runes[index].CurrentRune); }
uint16 GetRuneCooldown(uint8 index) const { return m_runes->runes[index].Cooldown; } uint16 GetRuneCooldown(uint8 index) const { return m_runes->runes[index].Cooldown; }
void SetBaseRune(uint8 index, uint8 baseRune) { m_runes->runes[index].BaseRune = baseRune; } bool IsBaseRuneSlotsOnCooldown(RuneType runeType) const;
void SetCurrentRune(uint8 index, uint8 currentRune) { m_runes->runes[index].CurrentRune = currentRune; } void SetBaseRune(uint8 index, RuneType baseRune) { m_runes->runes[index].BaseRune = baseRune; }
void SetCurrentRune(uint8 index, RuneType currentRune) { m_runes->runes[index].CurrentRune = currentRune; }
void SetRuneCooldown(uint8 index, uint16 cooldown) { m_runes->runes[index].Cooldown = cooldown; m_runes->SetRuneState(index, (cooldown == 0) ? true : false); } void SetRuneCooldown(uint8 index, uint16 cooldown) { m_runes->runes[index].Cooldown = cooldown; m_runes->SetRuneState(index, (cooldown == 0) ? true : false); }
void ConvertRune(uint8 index, uint8 newType); void ConvertRune(uint8 index, RuneType newType);
void ResyncRunes(uint8 count); void ResyncRunes(uint8 count);
void AddRunePower(uint8 index); void AddRunePower(uint8 index);
void InitRunes(); void InitRunes();

View file

@ -31,7 +31,8 @@ INSTANTIATE_SINGLETON_1(PoolHandler);
template <class T> template <class T>
PoolGroup<T>::PoolGroup() PoolGroup<T>::PoolGroup()
{ {
Spawned = 0; m_SpawnedPoolAmount = 0;
m_LastDespawnedNode = 0;
} }
// Method to add a gameobject/creature guid to the proper list depending on pool type and chance value // Method to add a gameobject/creature guid to the proper list depending on pool type and chance value
@ -107,12 +108,14 @@ void PoolGroup<T>::DespawnObject(uint32 guid)
if (!guid || EqualChanced[i].guid == guid) if (!guid || EqualChanced[i].guid == guid)
{ {
if (guid) if (guid)
CacheValue = EqualChanced[i].guid; m_LastDespawnedNode = EqualChanced[i].guid;
else else
Despawn1Object(EqualChanced[i].guid); Despawn1Object(EqualChanced[i].guid);
EqualChanced[i].spawned = false; EqualChanced[i].spawned = false;
Spawned--;
if (m_SpawnedPoolAmount > 0)
--m_SpawnedPoolAmount;
} }
} }
} }
@ -182,36 +185,40 @@ void PoolGroup<T>::SpawnObject(uint32 limit, bool cache)
if (limit == 1) // This is the only case where explicit chance is used if (limit == 1) // This is the only case where explicit chance is used
{ {
uint32 roll = RollOne(); uint32 roll = RollOne();
if (cache && CacheValue != roll) if (cache && m_LastDespawnedNode != roll)
Despawn1Object(CacheValue); Despawn1Object(m_LastDespawnedNode);
CacheValue = Spawn1Object(roll);
m_LastDespawnedNode = 0;
Spawn1Object(roll);
} }
else if (limit < EqualChanced.size() && Spawned < limit) else if (limit < EqualChanced.size() && m_SpawnedPoolAmount < limit)
{ {
std::vector<uint32> IndexList; std::vector<uint32> IndexList;
for (size_t i = 0; i < EqualChanced.size(); ++i) for (size_t i = 0; i < EqualChanced.size(); ++i)
if (!EqualChanced[i].spawned) if (!EqualChanced[i].spawned)
IndexList.push_back(i); IndexList.push_back(i);
while (Spawned < limit && IndexList.size() > 0) while (m_SpawnedPoolAmount < limit && IndexList.size() > 0)
{ {
uint32 roll = urand(1, IndexList.size()) - 1; uint32 roll = urand(1, IndexList.size()) - 1;
uint32 index = IndexList[roll]; uint32 index = IndexList[roll];
if (!cache || (cache && EqualChanced[index].guid != CacheValue)) if (!cache || (cache && EqualChanced[index].guid != m_LastDespawnedNode))
{ {
if (cache) if (cache)
Despawn1Object(CacheValue); Despawn1Object(m_LastDespawnedNode);
EqualChanced[index].spawned = Spawn1Object(EqualChanced[index].guid); EqualChanced[index].spawned = Spawn1Object(EqualChanced[index].guid);
} }
else else
EqualChanced[index].spawned = ReSpawn1Object(EqualChanced[index].guid); EqualChanced[index].spawned = ReSpawn1Object(EqualChanced[index].guid);
if (EqualChanced[index].spawned) if (EqualChanced[index].spawned)
++Spawned; // limited group use the Spawned variable to store the number of actualy spawned creatures ++m_SpawnedPoolAmount; // limited group use the Spawned variable to store the number of actualy spawned creatures
std::vector<uint32>::iterator itr = IndexList.begin()+roll; std::vector<uint32>::iterator itr = IndexList.begin()+roll;
IndexList.erase(itr); IndexList.erase(itr);
} }
CacheValue = 0; m_LastDespawnedNode = 0;
} }
else // Not enough objects in pool, so spawn all else // Not enough objects in pool, so spawn all
{ {
@ -330,7 +337,7 @@ bool PoolGroup<Pool>::ReSpawn1Object(uint32 /*guid*/)
PoolHandler::PoolHandler() PoolHandler::PoolHandler()
{ {
isSystemInit = false; m_IsPoolSystemStarted = false;
} }
void PoolHandler::LoadFromDB() void PoolHandler::LoadFromDB()
@ -624,7 +631,7 @@ void PoolHandler::Initialize()
} }
sLog.outBasic("Pool handling system initialized, %u pools spawned.", count); sLog.outBasic("Pool handling system initialized, %u pools spawned.", count);
isSystemInit = true; m_IsPoolSystemStarted = true;
} }
// Call to spawn a pool, if cache if true the method will spawn only if cached entry is different // Call to spawn a pool, if cache if true the method will spawn only if cached entry is different

View file

@ -56,10 +56,10 @@ class PoolGroup
void RemoveOneRelation(uint16 child_pool_id); void RemoveOneRelation(uint16 child_pool_id);
private: private:
typedef std::vector<PoolObject> PoolObjectList; typedef std::vector<PoolObject> PoolObjectList;
uint32 CacheValue; // Store the guid of the removed creature/gameobject during a pool update
PoolObjectList ExplicitlyChanced; PoolObjectList ExplicitlyChanced;
PoolObjectList EqualChanced; PoolObjectList EqualChanced;
uint32 Spawned; // Used to know the number of spawned objects uint32 m_LastDespawnedNode; // Store the guid of the removed creature/gameobject during a pool update
uint32 m_SpawnedPoolAmount; // Used to know the number of spawned objects
}; };
class Pool // for Pool of Pool case class Pool // for Pool of Pool case
@ -81,7 +81,7 @@ class PoolHandler
void Initialize(); void Initialize();
protected: protected:
bool isSystemInit; bool m_IsPoolSystemStarted;
uint16 max_pool_id; uint16 max_pool_id;
typedef std::vector<PoolTemplateData> PoolTemplateDataMap; typedef std::vector<PoolTemplateData> PoolTemplateDataMap;
typedef std::vector<PoolGroup<Creature> > PoolGroupCreatureMap; typedef std::vector<PoolGroup<Creature> > PoolGroupCreatureMap;

View file

@ -2433,9 +2433,12 @@ enum SummonType
SUMMON_TYPE_UNKNOWN5 = 409, SUMMON_TYPE_UNKNOWN5 = 409,
SUMMON_TYPE_UNKNOWN2 = 427, SUMMON_TYPE_UNKNOWN2 = 427,
SUMMON_TYPE_POSESSED2 = 428, SUMMON_TYPE_POSESSED2 = 428,
SUMMON_TYPE_QUEST_CRITTER = 487,
SUMMON_TYPE_QUEST_WILD = 587,
SUMMON_TYPE_INFERNO = 711, SUMMON_TYPE_INFERNO = 711,
SUMMON_TYPE_GUARDIAN2 = 713, SUMMON_TYPE_GUARDIAN2 = 713,
SUMMON_TYPE_GUARDIAN3 = 1161, SUMMON_TYPE_GUARDIAN3 = 1161,
SUMMON_TYPE_CREATURE = 1302,
SUMMON_TYPE_ELEMENTAL = 1561, SUMMON_TYPE_ELEMENTAL = 1561,
SUMMON_TYPE_FORCE_OF_NATURE = 1562 SUMMON_TYPE_FORCE_OF_NATURE = 1562
}; };

View file

@ -476,12 +476,12 @@ WorldObject* Spell::FindCorpseUsing()
TypeContainerVisitor<MaNGOS::WorldObjectSearcher<T>, GridTypeMapContainer > grid_searcher(searcher); TypeContainerVisitor<MaNGOS::WorldObjectSearcher<T>, GridTypeMapContainer > grid_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, grid_searcher, *m_caster->GetMap()); cell_lock->Visit(cell_lock, grid_searcher, *m_caster->GetMap(), *m_caster, max_range);
if (!result) if (!result)
{ {
TypeContainerVisitor<MaNGOS::WorldObjectSearcher<T>, WorldTypeMapContainer > world_searcher(searcher); TypeContainerVisitor<MaNGOS::WorldObjectSearcher<T>, WorldTypeMapContainer > world_searcher(searcher);
cell_lock->Visit(cell_lock, world_searcher, *m_caster->GetMap()); cell_lock->Visit(cell_lock, world_searcher, *m_caster->GetMap(), *m_caster, max_range);
} }
return result; return result;
@ -970,7 +970,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
// Do healing and triggers // Do healing and triggers
if (m_healing) if (m_healing)
{ {
bool crit = caster->isSpellCrit(NULL, m_spellInfo, m_spellSchoolMask); bool crit = caster->isSpellCrit(unitTarget, m_spellInfo, m_spellSchoolMask);
uint32 addhealth = m_healing; uint32 addhealth = m_healing;
if (crit) if (crit)
{ {
@ -1356,8 +1356,8 @@ void Spell::SetTargetMap(uint32 effIndex,uint32 targetMode,UnitList& TagUnitMap)
TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyAoETargetUnitInObjectRangeCheck>, GridTypeMapContainer > grid_unit_searcher(searcher); TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyAoETargetUnitInObjectRangeCheck>, GridTypeMapContainer > grid_unit_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, world_unit_searcher, *m_caster->GetMap()); cell_lock->Visit(cell_lock, world_unit_searcher, *m_caster->GetMap(), *m_caster, max_range);
cell_lock->Visit(cell_lock, grid_unit_searcher, *m_caster->GetMap()); cell_lock->Visit(cell_lock, grid_unit_searcher, *m_caster->GetMap(), *m_caster, max_range);
} }
if(tempUnitMap.empty()) if(tempUnitMap.empty())
@ -1426,8 +1426,8 @@ void Spell::SetTargetMap(uint32 effIndex,uint32 targetMode,UnitList& TagUnitMap)
TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyFriendlyUnitInObjectRangeCheck>, GridTypeMapContainer > grid_unit_searcher(searcher); TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyFriendlyUnitInObjectRangeCheck>, GridTypeMapContainer > grid_unit_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, world_unit_searcher, *m_caster->GetMap()); cell_lock->Visit(cell_lock, world_unit_searcher, *m_caster->GetMap(), *m_caster, max_range);
cell_lock->Visit(cell_lock, grid_unit_searcher, *m_caster->GetMap()); cell_lock->Visit(cell_lock, grid_unit_searcher, *m_caster->GetMap(), *m_caster, max_range);
} }
if(tempUnitMap.empty()) if(tempUnitMap.empty())
@ -1522,8 +1522,8 @@ void Spell::SetTargetMap(uint32 effIndex,uint32 targetMode,UnitList& TagUnitMap)
TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyAoETargetUnitInObjectRangeCheck>, GridTypeMapContainer> grid_unit_searcher(searcher); TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyAoETargetUnitInObjectRangeCheck>, GridTypeMapContainer> grid_unit_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, world_unit_searcher, *m_caster->GetMap()); cell_lock->Visit(cell_lock, world_unit_searcher, *m_caster->GetMap(), *pUnitTarget, max_range);
cell_lock->Visit(cell_lock, grid_unit_searcher, *m_caster->GetMap()); cell_lock->Visit(cell_lock, grid_unit_searcher, *m_caster->GetMap(), *pUnitTarget, max_range);
} }
if (tempUnitMap.empty()) if (tempUnitMap.empty())
break; break;
@ -3556,7 +3556,7 @@ SpellCastResult Spell::CheckRuneCost(uint32 runeCostID)
for(uint32 i = 0; i < MAX_RUNES; ++i) for(uint32 i = 0; i < MAX_RUNES; ++i)
{ {
uint8 rune = plr->GetCurrentRune(i); RuneType rune = plr->GetCurrentRune(i);
if((plr->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0)) if((plr->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0))
runeCost[rune]--; runeCost[rune]--;
} }
@ -3599,7 +3599,7 @@ void Spell::TakeRunePower()
for(uint32 i = 0; i < MAX_RUNES; ++i) for(uint32 i = 0; i < MAX_RUNES; ++i)
{ {
uint8 rune = plr->GetCurrentRune(i); RuneType rune = plr->GetCurrentRune(i);
if((plr->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0)) if((plr->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0))
{ {
plr->SetRuneCooldown(i, RUNE_COOLDOWN); // 5*2=10 sec plr->SetRuneCooldown(i, RUNE_COOLDOWN); // 5*2=10 sec
@ -3613,7 +3613,7 @@ void Spell::TakeRunePower()
{ {
for(uint32 i = 0; i < MAX_RUNES; ++i) for(uint32 i = 0; i < MAX_RUNES; ++i)
{ {
uint8 rune = plr->GetCurrentRune(i); RuneType rune = plr->GetCurrentRune(i);
if((plr->GetRuneCooldown(i) == 0) && (rune == RUNE_DEATH)) if((plr->GetRuneCooldown(i) == 0) && (rune == RUNE_DEATH))
{ {
plr->SetRuneCooldown(i, RUNE_COOLDOWN); // 5*2=10 sec plr->SetRuneCooldown(i, RUNE_COOLDOWN); // 5*2=10 sec
@ -4089,7 +4089,7 @@ SpellCastResult Spell::CheckCast(bool strict)
TypeContainerVisitor<MaNGOS::GameObjectLastSearcher<MaNGOS::NearestGameObjectEntryInObjectRangeCheck>, GridTypeMapContainer > object_checker(checker); TypeContainerVisitor<MaNGOS::GameObjectLastSearcher<MaNGOS::NearestGameObjectEntryInObjectRangeCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, object_checker, *m_caster->GetMap()); cell_lock->Visit(cell_lock, object_checker, *m_caster->GetMap(), *m_caster, range);
if (p_GameObject) if (p_GameObject)
{ {
@ -4128,7 +4128,7 @@ SpellCastResult Spell::CheckCast(bool strict)
TypeContainerVisitor<MaNGOS::CreatureLastSearcher<MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck>, GridTypeMapContainer > grid_creature_searcher(searcher); TypeContainerVisitor<MaNGOS::CreatureLastSearcher<MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck>, GridTypeMapContainer > grid_creature_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, grid_creature_searcher, *m_caster->GetMap()); cell_lock->Visit(cell_lock, grid_creature_searcher, *m_caster->GetMap(), *m_caster, range);
if(p_Creature ) if(p_Creature )
{ {
@ -5189,7 +5189,8 @@ SpellCastResult Spell::CheckItems()
TypeContainerVisitor<MaNGOS::GameObjectSearcher<MaNGOS::GameObjectFocusCheck>, GridTypeMapContainer > object_checker(checker); TypeContainerVisitor<MaNGOS::GameObjectSearcher<MaNGOS::GameObjectFocusCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, object_checker, *m_caster->GetMap()); Map& map = *m_caster->GetMap();
cell_lock->Visit(cell_lock, object_checker, map, *m_caster, map.GetVisibilityDistance());
if(!ok) if(!ok)
return SPELL_FAILED_REQUIRES_SPELL_FOCUS; return SPELL_FAILED_REQUIRES_SPELL_FOCUS;

View file

@ -460,6 +460,13 @@ m_isRemovedOnShapeLost(true), m_in_use(0), m_deleted(false)
m_spellProto->Stances && m_spellProto->Stances &&
!(m_spellProto->AttributesEx2 & SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT) && !(m_spellProto->AttributesEx2 & SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT) &&
!(m_spellProto->Attributes & SPELL_ATTR_NOT_SHAPESHIFT)); !(m_spellProto->Attributes & SPELL_ATTR_NOT_SHAPESHIFT));
if (caster && m_spellProto->Id == 22959) // Improved Scorch
{
// Glyph of Improved Scorch
if (Aura* glyph = caster->GetDummyAura(56371))
m_stackAmount = glyph->GetModifier()->m_amount;
}
} }
Aura::~Aura() Aura::~Aura()
@ -754,8 +761,8 @@ void AreaAura::Update(uint32 diff)
TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyFriendlyUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher); TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyFriendlyUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher);
TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyFriendlyUnitInObjectRangeCheck>, GridTypeMapContainer > grid_unit_searcher(searcher); TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyFriendlyUnitInObjectRangeCheck>, GridTypeMapContainer > grid_unit_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, world_unit_searcher, *caster->GetMap()); cell_lock->Visit(cell_lock, world_unit_searcher, *caster->GetMap(), *caster, m_radius);
cell_lock->Visit(cell_lock, grid_unit_searcher, *caster->GetMap()); cell_lock->Visit(cell_lock, grid_unit_searcher, *caster->GetMap(), *caster, m_radius);
break; break;
} }
case AREA_AURA_ENEMY: case AREA_AURA_ENEMY:
@ -770,8 +777,8 @@ void AreaAura::Update(uint32 diff)
TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyAoETargetUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher); TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyAoETargetUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher);
TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyAoETargetUnitInObjectRangeCheck>, GridTypeMapContainer > grid_unit_searcher(searcher); TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyAoETargetUnitInObjectRangeCheck>, GridTypeMapContainer > grid_unit_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, world_unit_searcher, *caster->GetMap()); cell_lock->Visit(cell_lock, world_unit_searcher, *caster->GetMap(), *caster, m_radius);
cell_lock->Visit(cell_lock, grid_unit_searcher, *caster->GetMap()); cell_lock->Visit(cell_lock, grid_unit_searcher, *caster->GetMap(), *caster, m_radius);
break; break;
} }
case AREA_AURA_OWNER: case AREA_AURA_OWNER:
@ -5001,7 +5008,8 @@ void Aura::HandleAuraModIncreaseHealth(bool apply, bool Real)
case 12976: // Warrior Last Stand triggered spell case 12976: // Warrior Last Stand triggered spell
case 28726: // Nightmare Seed ( Nightmare Seed ) case 28726: // Nightmare Seed ( Nightmare Seed )
case 34511: // Valor (Bulwark of Kings, Bulwark of the Ancient Kings) case 34511: // Valor (Bulwark of Kings, Bulwark of the Ancient Kings)
case 44055: // Tremendous Fortitude (Battlemaster's Alacrity) // FIXME: add case 67596: in 3.2.x
case 44055: case 55915: case 55917: // Tremendous Fortitude (Battlemaster's Alacrity)
case 50322: // Survival Instincts case 50322: // Survival Instincts
case 54443: // Demonic Empowerment (Voidwalker) case 54443: // Demonic Empowerment (Voidwalker)
{ {
@ -6141,6 +6149,15 @@ void Aura::HandleSchoolAbsorb(bool apply, bool Real)
//+30% from +spell bonus //+30% from +spell bonus
DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.30f; DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.30f;
break; break;
case SPELLFAMILY_PALADIN:
// Sacred Shield
// (check not strictly needed, only Sacred Shield has SPELL_AURA_SCHOOL_ABSORB in SPELLFAMILY_PALADIN at this time)
if (m_spellProto->SpellFamilyFlags & UI64LIT(0x0008000000000000))
{
// +75% from spell power
DoneActualBenefit = caster->SpellBaseHealingBonus(GetSpellSchoolMask(m_spellProto)) * 0.75f;
}
break;
case SPELLFAMILY_DRUID: case SPELLFAMILY_DRUID:
// Savage Defense (amount store original percent of attack power applied) // Savage Defense (amount store original percent of attack power applied)
if (m_spellProto->SpellIconID == 50) // only spell with this aura fit if (m_spellProto->SpellIconID == 50) // only spell with this aura fit
@ -6153,6 +6170,26 @@ void Aura::HandleSchoolAbsorb(bool apply, bool Real)
DoneActualBenefit *= caster->CalculateLevelPenalty(GetSpellProto()); DoneActualBenefit *= caster->CalculateLevelPenalty(GetSpellProto());
m_modifier.m_amount += (int32)DoneActualBenefit; m_modifier.m_amount += (int32)DoneActualBenefit;
// now that the correct amount is computed, apply caster aura, if any
switch(m_spellProto->SpellFamilyName)
{
case SPELLFAMILY_PRIEST:
// Power Word: Shield
if (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000001))
{
// Glyph of Power Word: Shield
if(Aura* glyph = caster->GetAura(55672,0))
{
// instant heal glyph m_amount% of the absorbed amount
int32 heal = (glyph->GetModifier()->m_amount * m_modifier.m_amount)/100;
caster->CastCustomSpell(m_target, 56160, &heal, NULL, NULL, true, 0, this);
}
}
break;
default:
break;
}
} }
} }
else else
@ -7025,8 +7062,8 @@ void Aura::PeriodicDummyTick()
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, grid_object_checker, *caster->GetMap()); cell_lock->Visit(cell_lock, grid_object_checker, *caster->GetMap(), *caster, radius);
cell_lock->Visit(cell_lock, world_object_checker, *caster->GetMap()); cell_lock->Visit(cell_lock, world_object_checker, *caster->GetMap(), *caster, radius);
} }
if(targets.empty()) if(targets.empty())
@ -7175,7 +7212,7 @@ void Aura::HandleManaShield(bool apply, bool Real)
switch(m_spellProto->SpellFamilyName) switch(m_spellProto->SpellFamilyName)
{ {
case SPELLFAMILY_MAGE: case SPELLFAMILY_MAGE:
if(m_spellProto->SpellFamilyFlags & UI64LIT(0x8000)) if(m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000008000))
{ {
// Mana Shield // Mana Shield
// +50% from +spd bonus // +50% from +spd bonus
@ -7256,13 +7293,13 @@ void Aura::HandleAuraConvertRune(bool apply, bool Real)
{ {
if(!plr->GetRuneCooldown(i)) if(!plr->GetRuneCooldown(i))
{ {
plr->ConvertRune(i, GetSpellProto()->EffectMiscValueB[m_effIndex]); plr->ConvertRune(i, RuneType(GetSpellProto()->EffectMiscValueB[m_effIndex]));
break; break;
} }
} }
else else
{ {
if(plr->GetCurrentRune(i) == GetSpellProto()->EffectMiscValueB[m_effIndex]) if(plr->GetCurrentRune(i) == RuneType(GetSpellProto()->EffectMiscValueB[m_effIndex]))
{ {
plr->ConvertRune(i, plr->GetBaseRune(i)); plr->ConvertRune(i, plr->GetBaseRune(i));
break; break;

View file

@ -262,7 +262,7 @@ class MANGOS_DLL_SPEC Aura
m_procCharges = charges; m_procCharges = charges;
SendAuraUpdate(false); SendAuraUpdate(false);
} }
bool DropAuraCharge() // return true if last charge dropped bool DropAuraCharge() // return true if last charge dropped
{ {
if (m_procCharges == 0) if (m_procCharges == 0)
return false; return false;

View file

@ -669,6 +669,12 @@ void Spell::EffectSchoolDMG(uint32 effect_idx)
{ {
damage+=int32(m_caster->GetShieldBlockValue()); damage+=int32(m_caster->GetShieldBlockValue());
} }
// Judgement
else if (m_spellInfo->Id == 54158)
{
// [1 + 0.25 * SPH + 0.16 * AP]
damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.16f);
}
break; break;
} }
} }
@ -1636,6 +1642,25 @@ void Spell::EffectDummy(uint32 i)
((Player*)m_caster)->SendAttackSwingCancelAttack(); ((Player*)m_caster)->SendAttackSwingCancelAttack();
return; return;
} }
// Last Stand
case 53478:
{
if (!unitTarget)
return;
int32 healthModSpellBasePoints0 = int32(unitTarget->GetMaxHealth() * 0.3);
unitTarget->CastCustomSpell(unitTarget, 53479, &healthModSpellBasePoints0, NULL, NULL, true, NULL);
return;
}
// Master's Call
case 53271:
{
Pet* pet = m_caster->GetPet();
if (!pet || !unitTarget)
return;
pet->CastSpell(unitTarget, m_spellInfo->CalculateSimpleValue(i), true);
return;
}
} }
break; break;
case SPELLFAMILY_PALADIN: case SPELLFAMILY_PALADIN:
@ -3297,6 +3322,8 @@ void Spell::EffectSummonType(uint32 i)
EffectSummonGuardian(i); EffectSummonGuardian(i);
break; break;
case SUMMON_TYPE_WILD: case SUMMON_TYPE_WILD:
case SUMMON_TYPE_QUEST_WILD:
case SUMMON_TYPE_CREATURE:
EffectSummonWild(i); EffectSummonWild(i);
break; break;
case SUMMON_TYPE_DEMON: case SUMMON_TYPE_DEMON:
@ -3310,6 +3337,7 @@ void Spell::EffectSummonType(uint32 i)
case SUMMON_TYPE_CRITTER: case SUMMON_TYPE_CRITTER:
case SUMMON_TYPE_CRITTER2: case SUMMON_TYPE_CRITTER2:
case SUMMON_TYPE_CRITTER3: case SUMMON_TYPE_CRITTER3:
case SUMMON_TYPE_QUEST_CRITTER:
EffectSummonCritter(i); EffectSummonCritter(i);
break; break;
case SUMMON_TYPE_TOTEM_SLOT1: case SUMMON_TYPE_TOTEM_SLOT1:
@ -5374,6 +5402,16 @@ void Spell::EffectScriptEffect(uint32 effIndex)
} }
return; return;
} }
// Master's Call
case 53271:
{
if (!unitTarget)
return;
// script effect have in value, but this outdated removed part
unitTarget->CastSpell(unitTarget, 62305, true);
return;
}
default: default:
break; break;
} }
@ -5400,13 +5438,12 @@ void Spell::EffectScriptEffect(uint32 effIndex)
sLog.outError("Unsupported Judgement (seal trigger) spell (Id: %u) in Spell::EffectScriptEffect",m_spellInfo->Id); sLog.outError("Unsupported Judgement (seal trigger) spell (Id: %u) in Spell::EffectScriptEffect",m_spellInfo->Id);
return; return;
} }
// all seals have aura dummy in 2 effect // offensive seals have aura dummy in 2 effect
Unit::AuraList const& m_dummyAuras = m_caster->GetAurasByType(SPELL_AURA_DUMMY); Unit::AuraList const& m_dummyAuras = m_caster->GetAurasByType(SPELL_AURA_DUMMY);
for(Unit::AuraList::const_iterator itr = m_dummyAuras.begin(); itr != m_dummyAuras.end(); ++itr) for(Unit::AuraList::const_iterator itr = m_dummyAuras.begin(); itr != m_dummyAuras.end(); ++itr)
{ {
SpellEntry const *spellInfo = (*itr)->GetSpellProto(); // search seal (offensive seals have judgement's aura dummy spell id in 2 effect
// search seal (all seals have judgement's aura dummy spell id in 2 effect if ((*itr)->GetEffIndex() != 2 || !IsSealSpell((*itr)->GetSpellProto()))
if ((*itr)->GetEffIndex() != 2 || !spellInfo || !IsSealSpell(spellInfo))
continue; continue;
spellId2 = (*itr)->GetModifier()->m_amount; spellId2 = (*itr)->GetModifier()->m_amount;
SpellEntry const *judge = sSpellStore.LookupEntry(spellId2); SpellEntry const *judge = sSpellStore.LookupEntry(spellId2);
@ -5414,6 +5451,18 @@ void Spell::EffectScriptEffect(uint32 effIndex)
continue; continue;
break; break;
} }
// if there were no offensive seals than there is seal with proc trigger aura
if (!spellId2)
{
Unit::AuraList const& procTriggerAuras = m_caster->GetAurasByType(SPELL_AURA_PROC_TRIGGER_SPELL);
for(Unit::AuraList::const_iterator itr = procTriggerAuras.begin(); itr != procTriggerAuras.end(); ++itr)
{
if ((*itr)->GetEffIndex() != 0 || !IsSealSpell((*itr)->GetSpellProto()))
continue;
spellId2 = 54158;
break;
}
}
if (spellId1) if (spellId1)
m_caster->CastSpell(unitTarget, spellId1, true); m_caster->CastSpell(unitTarget, spellId1, true);
if (spellId2) if (spellId2)
@ -6830,7 +6879,7 @@ void Spell::EffectActivateRune(uint32 eff_idx)
for(uint32 j = 0; j < MAX_RUNES; ++j) for(uint32 j = 0; j < MAX_RUNES; ++j)
{ {
if(plr->GetRuneCooldown(j) && plr->GetCurrentRune(j) == m_spellInfo->EffectMiscValue[eff_idx]) if(plr->GetRuneCooldown(j) && plr->GetCurrentRune(j) == RuneType(m_spellInfo->EffectMiscValue[eff_idx]))
{ {
plr->SetRuneCooldown(j, 0); plr->SetRuneCooldown(j, 0);
} }

View file

@ -1501,6 +1501,10 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons
// Savage Roar and Savage Roar (triggered) // Savage Roar and Savage Roar (triggered)
if (spellInfo_1->SpellIconID == 2865 && spellInfo_2->SpellIconID == 2865) if (spellInfo_1->SpellIconID == 2865 && spellInfo_2->SpellIconID == 2865)
return false; return false;
// Frenzied Regeneration and Savage Defense
if( spellInfo_1->Id == 22842 && spellInfo_2->Id == 62606 || spellInfo_2->Id == 22842 && spellInfo_1->Id == 62606 )
return false;
} }
// Leader of the Pack and Scroll of Stamina (multi-family check) // Leader of the Pack and Scroll of Stamina (multi-family check)

View file

@ -156,7 +156,9 @@ inline bool IsSealSpell(SpellEntry const *spellInfo)
{ {
//Collection of all the seal family flags. No other paladin spell has any of those. //Collection of all the seal family flags. No other paladin spell has any of those.
return spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && return spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN &&
( spellInfo->SpellFamilyFlags & SPELLFAMILYFLAG_PALADIN_SEALS ); ( spellInfo->SpellFamilyFlags & SPELLFAMILYFLAG_PALADIN_SEALS ) &&
// avoid counting target triggered effect as seal for avoid remove it or seal by it.
spellInfo->EffectImplicitTargetA[0] == TARGET_SELF;
} }
inline bool IsElementalShield(SpellEntry const *spellInfo) inline bool IsElementalShield(SpellEntry const *spellInfo)

View file

@ -91,8 +91,8 @@ TotemAI::UpdateAI(const uint32 /*diff*/)
TypeContainerVisitor<MaNGOS::UnitLastSearcher<MaNGOS::NearestAttackableUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker); TypeContainerVisitor<MaNGOS::UnitLastSearcher<MaNGOS::NearestAttackableUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, grid_object_checker, *m_creature->GetMap()); cell_lock->Visit(cell_lock, grid_object_checker, *m_creature->GetMap(), *m_creature, max_range);
cell_lock->Visit(cell_lock, world_object_checker, *m_creature->GetMap()); cell_lock->Visit(cell_lock, world_object_checker, *m_creature->GetMap(), *m_creature, max_range);
} }
// If have target // If have target

View file

@ -1862,6 +1862,8 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
// Reduce shield amount // Reduce shield amount
mod->m_amount-=currentAbsorb; mod->m_amount-=currentAbsorb;
if((*i)->DropAuraCharge())
mod->m_amount = 0;
// Need remove it later // Need remove it later
if (mod->m_amount<=0) if (mod->m_amount<=0)
existExpired = true; existExpired = true;
@ -3436,7 +3438,8 @@ bool Unit::AddAura(Aura *Aur)
// Aura can stack on self -> Stack it; // Aura can stack on self -> Stack it;
if(aurSpellInfo->StackAmount) if(aurSpellInfo->StackAmount)
{ {
i2->second->modStackAmount(1); // can be created with >1 stack by some spell mods
i2->second->modStackAmount(Aur->GetStackAmount());
delete Aur; delete Aur;
return false; return false;
} }
@ -5134,6 +5137,16 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
CastSpell(this, 28682, true, castItem, triggeredByAura); CastSpell(this, 28682, true, castItem, triggeredByAura);
return (procEx & PROC_EX_CRITICAL_HIT); // charge update only at crit hits, no hidden cooldowns return (procEx & PROC_EX_CRITICAL_HIT); // charge update only at crit hits, no hidden cooldowns
} }
// Glyph of Ice Block
case 56372:
{
if (GetTypeId() != TYPEID_PLAYER)
return false;
// not 100% safe with client version switches but for 3.1.3 no spells with cooldown that can have mage player except Frost Nova.
((Player*)this)->RemoveSpellCategoryCooldown(35, true);
return true;
}
} }
break; break;
} }
@ -6121,8 +6134,16 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
// Earth Shield // Earth Shield
if (dummySpell->SpellFamilyFlags & UI64LIT(0x0000040000000000)) if (dummySpell->SpellFamilyFlags & UI64LIT(0x0000040000000000))
{ {
basepoints0 = triggerAmount;
target = this; target = this;
basepoints0 = triggerAmount;
// Glyph of Earth Shield
if (Aura* aur = GetDummyAura(63279))
{
int32 aur_mod = aur->GetModifier()->m_amount;
basepoints0 = int32(basepoints0 * (aur_mod + 100.0f) / 100.0f);
}
triggered_spell_id = 379; triggered_spell_id = 379;
break; break;
} }
@ -6983,6 +7004,12 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
break; break;
} }
} }
// Blade Barrier
if (auraSpellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && auraSpellInfo->SpellIconID == 85)
{
if (this->GetTypeId() != TYPEID_PLAYER || !((Player*)this)->IsBaseRuneSlotsOnCooldown(RUNE_BLOOD))
return false;
}
// Custom basepoints/target for exist spell // Custom basepoints/target for exist spell
// dummy basepoints or other customs // dummy basepoints or other customs
@ -8218,7 +8245,17 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
if (spellProto->SpellIconID == 186) if (spellProto->SpellIconID == 186)
{ {
if (pVictim->isFrozen()) if (pVictim->isFrozen())
DoneTotalMod *= 3.0f; {
float multiplier = 3.0f;
// if target have higher level
if (pVictim->getLevel() > getLevel())
// Glyph of Ice Lance
if (Aura* glyph = GetDummyAura(56377))
multiplier = glyph->GetModifier()->m_amount;
DoneTotalMod *= multiplier;
}
} }
// Torment the weak affected (Arcane Barrage, Arcane Blast, Frostfire Bolt, Arcane Missiles, Fireball) // Torment the weak affected (Arcane Barrage, Arcane Blast, Frostfire Bolt, Arcane Missiles, Fireball)
if ((spellProto->SpellFamilyFlags & UI64LIT(0x0000900020200021)) && if ((spellProto->SpellFamilyFlags & UI64LIT(0x0000900020200021)) &&
@ -8475,7 +8512,8 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM
crit_chance -= ((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_SPELL); crit_chance -= ((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_SPELL);
} }
// scripted (increase crit chance ... against ... target by x% // scripted (increase crit chance ... against ... target by x%)
// scripted (Increases the critical effect chance of your .... by x% on targets ...)
AuraList const& mOverrideClassScript = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); AuraList const& mOverrideClassScript = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
for(AuraList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i) for(AuraList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
{ {
@ -8486,21 +8524,15 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM
case 849: if (pVictim->isFrozen()) crit_chance+= 17.0f; break; //Shatter Rank 1 case 849: if (pVictim->isFrozen()) crit_chance+= 17.0f; break; //Shatter Rank 1
case 910: if (pVictim->isFrozen()) crit_chance+= 34.0f; break; //Shatter Rank 2 case 910: if (pVictim->isFrozen()) crit_chance+= 34.0f; break; //Shatter Rank 2
case 911: if (pVictim->isFrozen()) crit_chance+= 50.0f; break; //Shatter Rank 3 case 911: if (pVictim->isFrozen()) crit_chance+= 50.0f; break; //Shatter Rank 3
case 7917: // Glyph of Shadowburn case 7917: // Glyph of Shadowburn
if (pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT)) if (pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT))
crit_chance+=(*i)->GetModifier()->m_amount; crit_chance+=(*i)->GetModifier()->m_amount;
break; break;
case 7997: // Renewed Hope case 7997: // Renewed Hope
case 7998: case 7998:
if (pVictim->HasAura(6788)) if (pVictim->HasAura(6788))
crit_chance+=(*i)->GetModifier()->m_amount; crit_chance+=(*i)->GetModifier()->m_amount;
break; break;
case 21: // Test of Faith
case 6935:
case 6918:
if (pVictim->GetHealth() < pVictim->GetMaxHealth()/2)
crit_chance+=(*i)->GetModifier()->m_amount;
break;
default: default:
break; break;
} }
@ -8508,23 +8540,40 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM
// Custom crit by class // Custom crit by class
switch(spellProto->SpellFamilyName) switch(spellProto->SpellFamilyName)
{ {
case SPELLFAMILY_PRIEST:
// Flash Heal
if (spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000800))
{
if (pVictim->GetHealth() > pVictim->GetMaxHealth()/2)
break;
AuraList const& mDummyAuras = GetAurasByType(SPELL_AURA_DUMMY);
for(AuraList::const_iterator i = mDummyAuras.begin(); i!= mDummyAuras.end(); ++i)
{
// Improved Flash Heal
if ((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_PRIEST &&
(*i)->GetSpellProto()->SpellIconID == 2542)
{
crit_chance+=(*i)->GetModifier()->m_amount;
break;
}
}
}
break;
case SPELLFAMILY_PALADIN: case SPELLFAMILY_PALADIN:
// Sacred Shield // Sacred Shield
if (spellProto->SpellFamilyFlags & UI64LIT(0x0000000040000000)) if (spellProto->SpellFamilyFlags & UI64LIT(0x0000000040000000))
{ {
Aura *aura = pVictim->GetDummyAura(58597); Aura *aura = pVictim->GetDummyAura(58597);
if (aura && aura->GetCasterGUID() == GetGUID()) if (aura && aura->GetCasterGUID() == GetGUID())
crit_chance+=aura->GetModifier()->m_amount; crit_chance+=aura->GetModifier()->m_amount;
break;
} }
// Exorcism // Exorcism
else if (spellProto->Category == 19) else if (spellProto->Category == 19)
{ {
if (pVictim->GetCreatureTypeMask() & CREATURE_TYPEMASK_DEMON_OR_UNDEAD) if (pVictim->GetCreatureTypeMask() & CREATURE_TYPEMASK_DEMON_OR_UNDEAD)
return true; return true;
break;
} }
break; break;
case SPELLFAMILY_SHAMAN: case SPELLFAMILY_SHAMAN:
// Lava Burst // Lava Burst
if (spellProto->SpellFamilyFlags & UI64LIT(0x0000100000000000)) if (spellProto->SpellFamilyFlags & UI64LIT(0x0000100000000000))
@ -8536,9 +8585,8 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM
pVictim->RemoveAurasByCasterSpell(flameShock->GetId(), GetGUID()); pVictim->RemoveAurasByCasterSpell(flameShock->GetId(), GetGUID());
return true; return true;
} }
break;
} }
break; break;
} }
} }
break; break;
@ -9417,7 +9465,7 @@ int32 Unit::ModifyPower(Powers power, int32 dVal)
bool Unit::isVisibleForOrDetect(Unit const* u, WorldObject const* viewPoint, bool detect, bool inVisibleList, bool is3dDistance) const bool Unit::isVisibleForOrDetect(Unit const* u, WorldObject const* viewPoint, bool detect, bool inVisibleList, bool is3dDistance) const
{ {
if(!u) if(!u || !IsInMap(u))
return false; return false;
// Always can see self // Always can see self
@ -9440,6 +9488,7 @@ bool Unit::isVisibleForOrDetect(Unit const* u, WorldObject const* viewPoint, boo
if(m_Visibility==VISIBILITY_RESPAWN) if(m_Visibility==VISIBILITY_RESPAWN)
return false; return false;
Map& _map = *u->GetMap();
// Grid dead/alive checks // Grid dead/alive checks
if( u->GetTypeId()==TYPEID_PLAYER) if( u->GetTypeId()==TYPEID_PLAYER)
{ {
@ -9483,26 +9532,26 @@ bool Unit::isVisibleForOrDetect(Unit const* u, WorldObject const* viewPoint, boo
if(u->GetTypeId()==TYPEID_PLAYER) if(u->GetTypeId()==TYPEID_PLAYER)
{ {
// Players far than max visible distance for player or not in our map are not visible too // Players far than max visible distance for player or not in our map are not visible too
if (!at_same_transport && !IsWithinDistInMap(viewPoint,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance)) if (!at_same_transport && !IsWithinDistInMap(viewPoint, _map.GetVisibilityDistance() + (inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
return false; return false;
} }
else else
{ {
// Units far than max visible distance for creature or not in our map are not visible too // Units far than max visible distance for creature or not in our map are not visible too
if (!IsWithinDistInMap(viewPoint,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance)) if (!IsWithinDistInMap(viewPoint, _map.GetVisibilityDistance() + (inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
return false; return false;
} }
} }
else if(GetCharmerOrOwnerGUID()) // distance for show pet/charmed else if(GetCharmerOrOwnerGUID()) // distance for show pet/charmed
{ {
// Pet/charmed far than max visible distance for player or not in our map are not visible too // Pet/charmed far than max visible distance for player or not in our map are not visible too
if (!IsWithinDistInMap(viewPoint,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance)) if (!IsWithinDistInMap(viewPoint, _map.GetVisibilityDistance() + (inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
return false; return false;
} }
else // distance for show creature else // distance for show creature
{ {
// Units far than max visible distance for creature or not in our map are not visible too // Units far than max visible distance for creature or not in our map are not visible too
if (!IsWithinDistInMap(viewPoint,World::GetMaxVisibleDistanceForCreature()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance)) if (!IsWithinDistInMap(viewPoint, _map.GetVisibilityDistance() + (inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
return false; return false;
} }
@ -11690,8 +11739,8 @@ Unit* Unit::SelectNearbyTarget(Unit* except /*= NULL*/) const
TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck>, GridTypeMapContainer > grid_unit_searcher(searcher); TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck>, GridTypeMapContainer > grid_unit_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p); CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, world_unit_searcher, *GetMap()); cell_lock->Visit(cell_lock, world_unit_searcher, *GetMap(), *this, ATTACK_DISTANCE);
cell_lock->Visit(cell_lock, grid_unit_searcher, *GetMap()); cell_lock->Visit(cell_lock, grid_unit_searcher, *GetMap(), *this, ATTACK_DISTANCE);
} }
// remove current target // remove current target

View file

@ -69,9 +69,11 @@ volatile bool World::m_stopEvent = false;
uint8 World::m_ExitCode = SHUTDOWN_EXIT_CODE; uint8 World::m_ExitCode = SHUTDOWN_EXIT_CODE;
volatile uint32 World::m_worldLoopCounter = 0; volatile uint32 World::m_worldLoopCounter = 0;
float World::m_MaxVisibleDistanceForCreature = DEFAULT_VISIBILITY_DISTANCE; float World::m_MaxVisibleDistanceOnContinents = DEFAULT_VISIBILITY_DISTANCE;
float World::m_MaxVisibleDistanceForPlayer = DEFAULT_VISIBILITY_DISTANCE; float World::m_MaxVisibleDistanceInInctances = DEFAULT_VISIBILITY_INSTANCE;
float World::m_MaxVisibleDistanceInBGArenas = DEFAULT_VISIBILITY_BGARENAS;
float World::m_MaxVisibleDistanceForObject = DEFAULT_VISIBILITY_DISTANCE; float World::m_MaxVisibleDistanceForObject = DEFAULT_VISIBILITY_DISTANCE;
float World::m_MaxVisibleDistanceInFlight = DEFAULT_VISIBILITY_DISTANCE; float World::m_MaxVisibleDistanceInFlight = DEFAULT_VISIBILITY_DISTANCE;
float World::m_VisibleUnitGreyDistance = 0; float World::m_VisibleUnitGreyDistance = 0;
float World::m_VisibleObjectGreyDistance = 0; float World::m_VisibleObjectGreyDistance = 0;
@ -1007,28 +1009,45 @@ void World::LoadConfigSettings(bool reload)
m_VisibleObjectGreyDistance = MAX_VISIBILITY_DISTANCE; m_VisibleObjectGreyDistance = MAX_VISIBILITY_DISTANCE;
} }
m_MaxVisibleDistanceForCreature = sConfig.GetFloatDefault("Visibility.Distance.Creature", DEFAULT_VISIBILITY_DISTANCE); //visibility on continents
if(m_MaxVisibleDistanceForCreature < 45*sWorld.getRate(RATE_CREATURE_AGGRO)) m_MaxVisibleDistanceOnContinents = sConfig.GetFloatDefault("Visibility.Distance.Continents", DEFAULT_VISIBILITY_DISTANCE);
if(m_MaxVisibleDistanceOnContinents < 45*sWorld.getRate(RATE_CREATURE_AGGRO))
{ {
sLog.outError("Visibility.Distance.Creature can't be less max aggro radius %f",45*sWorld.getRate(RATE_CREATURE_AGGRO)); sLog.outError("Visibility.Distance.Continents can't be less max aggro radius %f", 45*sWorld.getRate(RATE_CREATURE_AGGRO));
m_MaxVisibleDistanceForCreature = 45*sWorld.getRate(RATE_CREATURE_AGGRO); m_MaxVisibleDistanceOnContinents = 45*sWorld.getRate(RATE_CREATURE_AGGRO);
} }
else if(m_MaxVisibleDistanceForCreature + m_VisibleUnitGreyDistance > MAX_VISIBILITY_DISTANCE) else if(m_MaxVisibleDistanceOnContinents + m_VisibleUnitGreyDistance > MAX_VISIBILITY_DISTANCE)
{ {
sLog.outError("Visibility. Distance .Creature can't be greater %f",MAX_VISIBILITY_DISTANCE - m_VisibleUnitGreyDistance); sLog.outError("Visibility.Distance.Continents can't be greater %f",MAX_VISIBILITY_DISTANCE - m_VisibleUnitGreyDistance);
m_MaxVisibleDistanceForCreature = MAX_VISIBILITY_DISTANCE-m_VisibleUnitGreyDistance; m_MaxVisibleDistanceOnContinents = MAX_VISIBILITY_DISTANCE - m_VisibleUnitGreyDistance;
} }
m_MaxVisibleDistanceForPlayer = sConfig.GetFloatDefault("Visibility.Distance.Player", DEFAULT_VISIBILITY_DISTANCE);
if(m_MaxVisibleDistanceForPlayer < 45*sWorld.getRate(RATE_CREATURE_AGGRO)) //visibility in instances
m_MaxVisibleDistanceInInctances = sConfig.GetFloatDefault("Visibility.Distance.Instances", DEFAULT_VISIBILITY_INSTANCE);
if(m_MaxVisibleDistanceInInctances < 45*sWorld.getRate(RATE_CREATURE_AGGRO))
{ {
sLog.outError("Visibility.Distance.Player can't be less max aggro radius %f",45*sWorld.getRate(RATE_CREATURE_AGGRO)); sLog.outError("Visibility.Distance.Instances can't be less max aggro radius %f",45*sWorld.getRate(RATE_CREATURE_AGGRO));
m_MaxVisibleDistanceForPlayer = 45*sWorld.getRate(RATE_CREATURE_AGGRO); m_MaxVisibleDistanceInInctances = 45*sWorld.getRate(RATE_CREATURE_AGGRO);
} }
else if(m_MaxVisibleDistanceForPlayer + m_VisibleUnitGreyDistance > MAX_VISIBILITY_DISTANCE) else if(m_MaxVisibleDistanceInInctances + m_VisibleUnitGreyDistance > MAX_VISIBILITY_DISTANCE)
{ {
sLog.outError("Visibility.Distance.Player can't be greater %f",MAX_VISIBILITY_DISTANCE - m_VisibleUnitGreyDistance); sLog.outError("Visibility.Distance.Instances can't be greater %f",MAX_VISIBILITY_DISTANCE - m_VisibleUnitGreyDistance);
m_MaxVisibleDistanceForPlayer = MAX_VISIBILITY_DISTANCE - m_VisibleUnitGreyDistance; m_MaxVisibleDistanceInInctances = MAX_VISIBILITY_DISTANCE - m_VisibleUnitGreyDistance;
} }
//visibility in BG/Arenas
m_MaxVisibleDistanceInBGArenas = sConfig.GetFloatDefault("Visibility.Distance.BGArenas", DEFAULT_VISIBILITY_BGARENAS);
if(m_MaxVisibleDistanceInBGArenas < 45*sWorld.getRate(RATE_CREATURE_AGGRO))
{
sLog.outError("Visibility.Distance.BGArenas can't be less max aggro radius %f",45*sWorld.getRate(RATE_CREATURE_AGGRO));
m_MaxVisibleDistanceInBGArenas = 45*sWorld.getRate(RATE_CREATURE_AGGRO);
}
else if(m_MaxVisibleDistanceInBGArenas + m_VisibleUnitGreyDistance > MAX_VISIBILITY_DISTANCE)
{
sLog.outError("Visibility.Distance.BGArenas can't be greater %f",MAX_VISIBILITY_DISTANCE - m_VisibleUnitGreyDistance);
m_MaxVisibleDistanceInBGArenas = MAX_VISIBILITY_DISTANCE - m_VisibleUnitGreyDistance;
}
m_MaxVisibleDistanceForObject = sConfig.GetFloatDefault("Visibility.Distance.Object", DEFAULT_VISIBILITY_DISTANCE); m_MaxVisibleDistanceForObject = sConfig.GetFloatDefault("Visibility.Distance.Object", DEFAULT_VISIBILITY_DISTANCE);
if(m_MaxVisibleDistanceForObject < INTERACTION_DISTANCE) if(m_MaxVisibleDistanceForObject < INTERACTION_DISTANCE)
{ {

View file

@ -494,12 +494,14 @@ class World
bool IsScriptScheduled() const { return m_scheduledScripts > 0; } bool IsScriptScheduled() const { return m_scheduledScripts > 0; }
// for max speed access // for max speed access
static float GetMaxVisibleDistanceForCreature() { return m_MaxVisibleDistanceForCreature; } static float GetMaxVisibleDistanceOnContinents() { return m_MaxVisibleDistanceOnContinents; }
static float GetMaxVisibleDistanceForPlayer() { return m_MaxVisibleDistanceForPlayer; } static float GetMaxVisibleDistanceInInstances() { return m_MaxVisibleDistanceInInctances; }
static float GetMaxVisibleDistanceForObject() { return m_MaxVisibleDistanceForObject; } static float GetMaxVisibleDistanceInBGArenas() { return m_MaxVisibleDistanceInBGArenas; }
static float GetMaxVisibleDistanceInFlight() { return m_MaxVisibleDistanceInFlight; } static float GetMaxVisibleDistanceForObject() { return m_MaxVisibleDistanceForObject; }
static float GetVisibleUnitGreyDistance() { return m_VisibleUnitGreyDistance; }
static float GetVisibleObjectGreyDistance() { return m_VisibleObjectGreyDistance; } static float GetMaxVisibleDistanceInFlight() { return m_MaxVisibleDistanceInFlight; }
static float GetVisibleUnitGreyDistance() { return m_VisibleUnitGreyDistance; }
static float GetVisibleObjectGreyDistance() { return m_VisibleObjectGreyDistance; }
void ProcessCliCommands(); void ProcessCliCommands();
void QueueCliCommand( CliCommandHolder::Print* zprintf, char const* input ) { cliCmdQueue.add(new CliCommandHolder(input, zprintf)); } void QueueCliCommand( CliCommandHolder::Print* zprintf, char const* input ) { cliCmdQueue.add(new CliCommandHolder(input, zprintf)); }
@ -560,9 +562,11 @@ class World
std::string m_dataPath; std::string m_dataPath;
// for max speed access // for max speed access
static float m_MaxVisibleDistanceForCreature; static float m_MaxVisibleDistanceOnContinents;
static float m_MaxVisibleDistanceForPlayer; static float m_MaxVisibleDistanceInInctances;
static float m_MaxVisibleDistanceInBGArenas;
static float m_MaxVisibleDistanceForObject; static float m_MaxVisibleDistanceForObject;
static float m_MaxVisibleDistanceInFlight; static float m_MaxVisibleDistanceInFlight;
static float m_VisibleUnitGreyDistance; static float m_VisibleUnitGreyDistance;
static float m_VisibleObjectGreyDistance; static float m_VisibleObjectGreyDistance;

View file

@ -962,12 +962,12 @@ GM.AllowAchievementGain = 1
# 1 (raid members 100% auto detect invisible player from same raid) # 1 (raid members 100% auto detect invisible player from same raid)
# 2 (players from same team can 100% auto detect invisible player) # 2 (players from same team can 100% auto detect invisible player)
# #
# Visibility.Distance.Creature # Visibility.Distance.Continents
# Visibility.Distance.Player # Visibility.Distance.Instances
# Visibility distance for different in game object # Visibility.Distance.BGArenas
# Visibility distance for different ingame object in different maps.
# Visibility on continents on offy ~90 yards. In BG/Arenas ~180. For instances default ~120.
# Max limited by active player zone: ~ 333 # Max limited by active player zone: ~ 333
# Min limit dependent from objects
# Default: 132 (cell size)
# Min limit is max aggro radius (45) * Rate.Creature.Aggro # Min limit is max aggro radius (45) * Rate.Creature.Aggro
# #
# Visibility.Distance.Object # Visibility.Distance.Object
@ -993,8 +993,9 @@ GM.AllowAchievementGain = 1
################################################################################################################### ###################################################################################################################
Visibility.GroupMode = 0 Visibility.GroupMode = 0
Visibility.Distance.Creature = 100 Visibility.Distance.Continents = 90
Visibility.Distance.Player = 100 Visibility.Distance.Instances = 120
Visibility.Distance.BGArenas = 180
Visibility.Distance.Object = 100 Visibility.Distance.Object = 100
Visibility.Distance.InFlight = 100 Visibility.Distance.InFlight = 100
Visibility.Distance.Grey.Unit = 1 Visibility.Distance.Grey.Unit = 1

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "8502" #define REVISION_NR "8526"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__

View file

@ -1,6 +1,6 @@
#ifndef __REVISION_SQL_H__ #ifndef __REVISION_SQL_H__
#define __REVISION_SQL_H__ #define __REVISION_SQL_H__
#define REVISION_DB_CHARACTERS "required_8469_01_characters_character_spell" #define REVISION_DB_CHARACTERS "required_8505_01_characters_character_spell"
#define REVISION_DB_MANGOS "required_8499_01_mangos_spell_elixir" #define REVISION_DB_MANGOS "required_8521_01_mangos_spell_proc_event"
#define REVISION_DB_REALMD "required_8332_01_realmd_realmcharacters" #define REVISION_DB_REALMD "required_8332_01_realmd_realmcharacters"
#endif // __REVISION_SQL_H__ #endif // __REVISION_SQL_H__