mirror of
https://github.com/mangosfour/server.git
synced 2025-12-12 19:37:03 +00:00
Merge commit 'origin/master' into 320
This commit is contained in:
commit
258e19a4a3
48 changed files with 744 additions and 206 deletions
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
DROP TABLE IF EXISTS `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';
|
||||
|
||||
--
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ CREATE TABLE `db_version` (
|
|||
`version` varchar(120) default NULL,
|
||||
`creature_ai_version` varchar(120) default NULL,
|
||||
`cache_id` int(10) default '0',
|
||||
`required_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';
|
||||
|
||||
--
|
||||
|
|
@ -9746,7 +9746,7 @@ INSERT INTO `playercreateinfo_action` VALUES
|
|||
(1,1,96,6603,0),
|
||||
(1,1,108,6603,0),
|
||||
(1,2,0,6603,0),
|
||||
(1,2,1,20154,0),
|
||||
(1,2,1,21084,0),
|
||||
(1,2,2,635,0),
|
||||
(1,2,9,59752,0),
|
||||
(1,2,10,159,128),
|
||||
|
|
@ -9833,7 +9833,7 @@ INSERT INTO `playercreateinfo_action` VALUES
|
|||
(3,1,96,6603,0),
|
||||
(3,1,108,6603,0),
|
||||
(3,2,0,6603,0),
|
||||
(3,2,1,20154,0),
|
||||
(3,2,1,21084,0),
|
||||
(3,2,2,635,0),
|
||||
(3,2,3,20594,0),
|
||||
(3,2,4,2481,0),
|
||||
|
|
@ -10295,7 +10295,7 @@ INSERT INTO `playercreateinfo_spell` VALUES
|
|||
(1,2,9078,'Cloth'),
|
||||
(1,2,9116,'Shield'),
|
||||
(1,2,9125,'Generic'),
|
||||
(1,2,20154,'Seal of Righteousness'),
|
||||
(1,2,21084,'Seal of Righteousness'),
|
||||
(1,2,20597,'Sword Specialization'),
|
||||
(1,2,20598,'The Human Spirit'),
|
||||
(1,2,20599,'Diplomacy'),
|
||||
|
|
@ -10882,7 +10882,7 @@ INSERT INTO `playercreateinfo_spell` VALUES
|
|||
(3,2,9078,'Cloth'),
|
||||
(3,2,9116,'Shield'),
|
||||
(3,2,9125,'Generic'),
|
||||
(3,2,20154,'Seal of Righteousness'),
|
||||
(3,2,21084,'Seal of Righteousness'),
|
||||
(3,2,20594,'Stoneform'),
|
||||
(3,2,20595,'Gun Specialization'),
|
||||
(3,2,20596,'Frost Resistance'),
|
||||
|
|
@ -13659,6 +13659,7 @@ INSERT INTO `spell_bonus_data` VALUES
|
|||
(20925, 0.09, 0, 0.056, 'Paladin - Holy Shield'),
|
||||
(31803, 0, 0.0156, 0.03, 'Paladin - Holy Vengeance'),
|
||||
(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'),
|
||||
(32220, 0.0594, 0, 0.0363,'Paladin - Judgement of Blood Self'),
|
||||
(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),
|
||||
(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),
|
||||
(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),
|
||||
(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),
|
||||
|
|
@ -17942,6 +17944,8 @@ INSERT INTO `spell_proc_event` VALUES
|
|||
(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),
|
||||
(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),
|
||||
(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),
|
||||
|
|
|
|||
|
|
@ -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'),
|
||||
(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'),
|
||||
(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'),
|
||||
(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'),
|
||||
(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'),
|
||||
|
|
@ -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'),
|
||||
(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'),
|
||||
(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'),
|
||||
|
||||
/* sorted by spell names */
|
||||
|
|
|
|||
5
sql/updates/8504_01_mangos_playercreateinfo_spell.sql
Normal file
5
sql/updates/8504_01_mangos_playercreateinfo_spell.sql
Normal 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;
|
||||
5
sql/updates/8504_02_mangos_playercreateinfo_action.sql
Normal file
5
sql/updates/8504_02_mangos_playercreateinfo_action.sql
Normal 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;
|
||||
3
sql/updates/8505_01_characters_character_spell.sql
Normal file
3
sql/updates/8505_01_characters_character_spell.sql
Normal 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;
|
||||
7
sql/updates/8511_01_mangos_spell_proc_event.sql
Normal file
7
sql/updates/8511_01_mangos_spell_proc_event.sql
Normal 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);
|
||||
6
sql/updates/8514_01_mangos_spell_bonus_data.sql
Normal file
6
sql/updates/8514_01_mangos_spell_bonus_data.sql
Normal 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');
|
||||
6
sql/updates/8521_01_mangos_spell_proc_event.sql
Normal file
6
sql/updates/8521_01_mangos_spell_proc_event.sql
Normal 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);
|
||||
|
|
@ -107,6 +107,12 @@ pkgdata_DATA = \
|
|||
8488_02_mangos_spell_bonus_data.sql \
|
||||
8498_01_mangos_spell_proc_event.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
|
||||
|
||||
## Additional files to include when running 'make dist'
|
||||
|
|
@ -194,4 +200,10 @@ EXTRA_DIST = \
|
|||
8488_02_mangos_spell_bonus_data.sql \
|
||||
8498_01_mangos_spell_proc_event.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
|
||||
|
|
|
|||
|
|
@ -79,8 +79,19 @@ class MANGOS_DLL_DECL NGrid
|
|||
i_GridInfo = GridInfo(expiry, unload);
|
||||
}
|
||||
|
||||
const GridType& operator()(unsigned short x, unsigned short y) const { return i_cells[x][y]; }
|
||||
GridType& operator()(unsigned short x, unsigned short y) { return i_cells[x][y]; }
|
||||
const GridType& operator()(unsigned short x, unsigned short y) const
|
||||
{
|
||||
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; }
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
|
|
@ -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)
|
||||
{
|
||||
i_cells[x][y].Visit(visitor);
|
||||
getGridType(x, y).Visit(visitor);
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
return i_cells[x][y].RemoveGridObject(obj, hdl);
|
||||
return getGridType(x, y).RemoveGridObject(obj, hdl);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
GridType& getGridType(const uint32& x, const uint32& y)
|
||||
{
|
||||
ASSERT(x < N);
|
||||
ASSERT(y < N);
|
||||
return i_cells[x][y];
|
||||
}
|
||||
|
||||
uint32 i_gridId;
|
||||
GridInfo i_GridInfo;
|
||||
GridReference<NGrid<N, ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES, ThreadModel> > i_Reference;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::AchievementChatBuilder> >, WorldTypeMapContainer > message(say_worker);
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include <cmath>
|
||||
|
||||
class Map;
|
||||
class WorldObject;
|
||||
|
||||
enum District
|
||||
{
|
||||
|
|
@ -42,6 +43,26 @@ enum District
|
|||
|
||||
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
|
||||
{
|
||||
Cell() { data.All = 0; }
|
||||
|
|
@ -131,15 +152,21 @@ struct MANGOS_DLL_DECL Cell
|
|||
{
|
||||
unsigned grid_x : 6;
|
||||
unsigned grid_y : 6;
|
||||
unsigned cell_x : 4;
|
||||
unsigned cell_y : 4;
|
||||
unsigned cell_x : 6;
|
||||
unsigned cell_y : 6;
|
||||
unsigned nocreate : 1;
|
||||
unsigned reserved : 11;
|
||||
unsigned reserved : 7;
|
||||
} Part;
|
||||
uint32 All;
|
||||
} 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 &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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::EmoteChatBuilder > >, WorldTypeMapContainer > message(emote_worker);
|
||||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -534,7 +534,7 @@ void Creature::DoFleeToGetAssistance()
|
|||
TypeContainerVisitor<MaNGOS::CreatureLastSearcher<MaNGOS::NearestAssistCreatureInCreatureRangeCheck>, GridTypeMapContainer > grid_creature_searcher(searcher);
|
||||
|
||||
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);
|
||||
if(!pCreature)
|
||||
|
|
@ -1776,7 +1776,7 @@ void Creature::CallAssistance()
|
|||
TypeContainerVisitor<MaNGOS::CreatureListSearcher<MaNGOS::AnyAssistCreatureInRangeCheck>, GridTypeMapContainer > grid_creature_searcher(searcher);
|
||||
|
||||
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())
|
||||
|
|
@ -1810,7 +1810,7 @@ void Creature::CallForHelp(float fRadius)
|
|||
TypeContainerVisitor<MaNGOS::CreatureWorker<MaNGOS::CallOfHelpCreatureInRangeDo>, GridTypeMapContainer > grid_creature_searcher(worker);
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -1214,7 +1214,7 @@ Unit* CreatureEventAI::DoSelectLowestHpFriendly(float range, uint32 MinHPDiff)
|
|||
TypeContainerVisitor<MaNGOS::UnitLastSearcher<MaNGOS::MostHPMissingInRange>, GridTypeMapContainer > grid_unit_searcher(searcher);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -1231,7 +1231,7 @@ void CreatureEventAI::DoFindFriendlyCC(std::list<Creature*>& _list, float range)
|
|||
TypeContainerVisitor<MaNGOS::CreatureListSearcher<MaNGOS::FriendlyCCedInRange>, GridTypeMapContainer > grid_creature_searcher(searcher);
|
||||
|
||||
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)
|
||||
|
|
@ -1247,7 +1247,7 @@ void CreatureEventAI::DoFindFriendlyMissingBuff(std::list<Creature*>& _list, flo
|
|||
TypeContainerVisitor<MaNGOS::CreatureListSearcher<MaNGOS::FriendlyMissingBuffInRange>, GridTypeMapContainer > grid_creature_searcher(searcher);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
//*********************************
|
||||
|
|
|
|||
|
|
@ -125,8 +125,8 @@ void DynamicObject::Update(uint32 p_time)
|
|||
TypeContainerVisitor<MaNGOS::DynamicObjectUpdater, GridTypeMapContainer > grid_object_notifier(notifier);
|
||||
|
||||
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||
cell_lock->Visit(cell_lock, world_object_notifier, *GetMap());
|
||||
cell_lock->Visit(cell_lock, grid_object_notifier, *GetMap());
|
||||
cell_lock->Visit(cell_lock, world_object_notifier, *GetMap(), *this, m_radius);
|
||||
cell_lock->Visit(cell_lock, grid_object_notifier, *GetMap(), *this, m_radius);
|
||||
}
|
||||
|
||||
if(deleteThis)
|
||||
|
|
|
|||
|
|
@ -319,13 +319,13 @@ void GameObject::Update(uint32 /*p_time*/)
|
|||
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||
|
||||
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
|
||||
if(!ok)
|
||||
{
|
||||
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
|
||||
|
|
@ -340,7 +340,7 @@ void GameObject::Update(uint32 /*p_time*/)
|
|||
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -784,7 +784,7 @@ void GameObject::TriggeringLinkedGameObject( uint32 trapEntry, Unit* target)
|
|||
|
||||
TypeContainerVisitor<MaNGOS::GameObjectLastSearcher<MaNGOS::NearestGameObjectEntryInObjectRangeCheck>, GridTypeMapContainer > object_checker(checker);
|
||||
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
|
||||
|
|
@ -806,7 +806,7 @@ GameObject* GameObject::LookupFishingHoleAround(float range)
|
|||
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -1031,7 +1031,8 @@ void GameObject::Use(Unit* user)
|
|||
//fish catched
|
||||
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)
|
||||
{
|
||||
player->SendLoot(ok->GetGUID(),LOOT_FISHINGHOLE);
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class Player;
|
|||
#define MIN_GRID_DELAY (MINUTE*IN_MILISECONDS)
|
||||
#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 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)
|
||||
{
|
||||
if( x_coord >= val )
|
||||
if( x_coord > val )
|
||||
x_coord -= val;
|
||||
else
|
||||
x_coord = 0;
|
||||
}
|
||||
|
||||
void operator>>(const uint32 val)
|
||||
{
|
||||
if( x_coord+val < LIMIT )
|
||||
x_coord += val;
|
||||
else
|
||||
x_coord = LIMIT - 1;
|
||||
}
|
||||
|
||||
void operator-=(const uint32 val)
|
||||
{
|
||||
if( y_coord >= val )
|
||||
if( y_coord > val )
|
||||
y_coord -= val;
|
||||
else
|
||||
y_coord = 0;
|
||||
}
|
||||
|
||||
void operator+=(const uint32 val)
|
||||
{
|
||||
if( y_coord+val < LIMIT )
|
||||
y_coord += val;
|
||||
else
|
||||
y_coord = LIMIT - 1;
|
||||
}
|
||||
|
||||
uint32 x_coord;
|
||||
|
|
|
|||
|
|
@ -190,6 +190,7 @@ bool ChatHandler::HandleReloadConfigCommand(const char* /*args*/)
|
|||
{
|
||||
sLog.outString( "Re-Loading config settings..." );
|
||||
sWorld.LoadConfigSettings(true);
|
||||
MapManager::Instance().InitializeVisibilityDistanceInfo();
|
||||
SendGlobalSysMessage("World config settings reloaded.");
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
#define DEFAULT_GRID_EXPIRY 300
|
||||
#define MAX_GRID_LOAD_TIME 50
|
||||
#define MAX_CREATURE_ATTACK_RADIUS (45.0f * sWorld.getRate(RATE_CREATURE_AGGRO))
|
||||
|
||||
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_id(id), i_InstanceId(InstanceId), m_unloadTimer(0),
|
||||
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)
|
||||
{
|
||||
|
|
@ -209,6 +211,15 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _par
|
|||
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
|
||||
|
|
@ -346,8 +357,8 @@ Map::EnsureGridCreated(const GridPair &p)
|
|||
getNGrid(p.x_coord, p.y_coord)->SetGridState(GRID_STATE_IDLE);
|
||||
|
||||
//z coord
|
||||
int gx=63-p.x_coord;
|
||||
int gy=63-p.y_coord;
|
||||
int gx = (MAX_NUMBER_OF_GRIDS - 1) - p.x_coord;
|
||||
int gy = (MAX_NUMBER_OF_GRIDS - 1) - p.y_coord;
|
||||
|
||||
if(!GridMaps[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);
|
||||
TypeContainerVisitor<MaNGOS::MessageDeliverer, WorldTypeMapContainer > message(post_man);
|
||||
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)
|
||||
|
|
@ -511,10 +522,12 @@ void Map::MessageBroadcast(WorldObject *obj, WorldPacket *msg)
|
|||
if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) )
|
||||
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);
|
||||
TypeContainerVisitor<MaNGOS::ObjectMessageDeliverer, WorldTypeMapContainer > message(post_man);
|
||||
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)
|
||||
|
|
@ -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);
|
||||
TypeContainerVisitor<MaNGOS::MessageDistDeliverer , WorldTypeMapContainer > message(post_man);
|
||||
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)
|
||||
|
|
@ -560,7 +573,7 @@ void Map::MessageDistBroadcast(WorldObject *obj, WorldPacket *msg, float dist)
|
|||
MaNGOS::ObjectMessageDistDeliverer post_man(*obj, msg, dist);
|
||||
TypeContainerVisitor<MaNGOS::ObjectMessageDistDeliverer, WorldTypeMapContainer > message(post_man);
|
||||
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
|
||||
|
|
@ -605,8 +618,9 @@ void Map::Update(const uint32 &t_diff)
|
|||
// the overloaded operators handle range checking
|
||||
// so ther's no need for range checking inside the loop
|
||||
CellPair begin_cell(standing_cell), end_cell(standing_cell);
|
||||
begin_cell << 1; begin_cell -= 1; // upper left
|
||||
end_cell >> 1; end_cell += 1; // lower right
|
||||
//lets update mobs/objects in ALL visible cells around player!
|
||||
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)
|
||||
{
|
||||
|
|
@ -1044,8 +1058,9 @@ bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool pForce)
|
|||
delete getNGrid(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)
|
||||
//+++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);
|
||||
TypeContainerVisitor<MaNGOS::VisibleChangesNotifier, WorldTypeMapContainer > player_notifier(notifier);
|
||||
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 )
|
||||
|
|
@ -1932,7 +1947,7 @@ void Map::UpdatePlayerVisibility( Player* player, Cell cell, CellPair cellpair )
|
|||
TypeContainerVisitor<MaNGOS::PlayerNotifier, WorldTypeMapContainer > player_notifier(pl_notifier);
|
||||
|
||||
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 )
|
||||
|
|
@ -1944,8 +1959,8 @@ void Map::UpdateObjectsVisibilityFor( Player* player, Cell cell, CellPair cellpa
|
|||
TypeContainerVisitor<MaNGOS::VisibleNotifier, WorldTypeMapContainer > world_notifier(notifier);
|
||||
TypeContainerVisitor<MaNGOS::VisibleNotifier, GridTypeMapContainer > grid_notifier(notifier);
|
||||
CellLock<GridReadGuard> cell_lock(cell, cellpair);
|
||||
cell_lock->Visit(cell_lock, world_notifier, *this);
|
||||
cell_lock->Visit(cell_lock, grid_notifier, *this);
|
||||
cell_lock->Visit(cell_lock, world_notifier, *this, *player, GetVisibilityDistance());
|
||||
cell_lock->Visit(cell_lock, grid_notifier, *this, *player, GetVisibilityDistance());
|
||||
|
||||
// send data
|
||||
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, WorldTypeMapContainer > p2world_relocation(relocationNotifier);
|
||||
|
||||
cell_lock->Visit(cell_lock, p2grid_relocation, *this);
|
||||
cell_lock->Visit(cell_lock, p2world_relocation, *this);
|
||||
cell_lock->Visit(cell_lock, p2grid_relocation, *this, *player, MAX_CREATURE_ATTACK_RADIUS);
|
||||
cell_lock->Visit(cell_lock, p2world_relocation, *this, *player, MAX_CREATURE_ATTACK_RADIUS);
|
||||
}
|
||||
|
||||
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, GridTypeMapContainer > c2grid_relocation(relocationNotifier);
|
||||
|
||||
cell_lock->Visit(cell_lock, c2world_relocation, *this);
|
||||
cell_lock->Visit(cell_lock, c2grid_relocation, *this);
|
||||
cell_lock->Visit(cell_lock, c2world_relocation, *this, *creature, MAX_CREATURE_ATTACK_RADIUS);
|
||||
cell_lock->Visit(cell_lock, c2grid_relocation, *this, *creature, MAX_CREATURE_ATTACK_RADIUS);
|
||||
}
|
||||
|
||||
void Map::SendInitSelf( Player * player )
|
||||
|
|
@ -2145,12 +2160,20 @@ void Map::SendToPlayers(WorldPacket const* data) 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_max(cell_min.x_coord + MAX_NUMBER_OF_CELLS, cell_min.y_coord+MAX_NUMBER_OF_CELLS);
|
||||
cell_min << 2;
|
||||
cell_min -= 2;
|
||||
cell_max >> 2;
|
||||
cell_max += 2;
|
||||
|
||||
//we must find visible range in cells so we unload only non-visible cells...
|
||||
float viewDist = GetVisibilityDistance();
|
||||
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)
|
||||
{
|
||||
|
|
@ -2234,6 +2257,9 @@ InstanceMap::InstanceMap(uint32 id, time_t expiry, uint32 InstanceId, uint8 Spaw
|
|||
m_resetAfterUnload(false), m_unloadWhenEmpty(false),
|
||||
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
|
||||
// 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);
|
||||
|
|
@ -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
|
||||
*/
|
||||
|
|
@ -2570,12 +2602,20 @@ uint32 InstanceMap::GetMaxPlayers() const
|
|||
BattleGroundMap::BattleGroundMap(uint32 id, time_t expiry, uint32 InstanceId, Map* _parent)
|
||||
: Map(id, expiry, InstanceId, DUNGEON_DIFFICULTY_NORMAL, _parent)
|
||||
{
|
||||
//lets initialize visibility distance for BG/Arenas
|
||||
BattleGroundMap::InitVisibilityDistance();
|
||||
}
|
||||
|
||||
BattleGroundMap::~BattleGroundMap()
|
||||
{
|
||||
}
|
||||
|
||||
void BattleGroundMap::InitVisibilityDistance()
|
||||
{
|
||||
//init visibility distance for BG/Arenas
|
||||
m_VisibleDistance = sWorld.GetMaxVisibleDistanceInBGArenas();
|
||||
}
|
||||
|
||||
bool BattleGroundMap::CanEnter(Player * player)
|
||||
{
|
||||
if(player->GetMapRef().getTarget() == this)
|
||||
|
|
|
|||
|
|
@ -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(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 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);
|
||||
|
||||
void SetTimer(uint32 t) { i_gridExpiry = t < MIN_GRID_DELAY ? MIN_GRID_DELAY : t; }
|
||||
//uint64 CalculateGridMask(const uint32 &y) const;
|
||||
|
||||
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
|
||||
{
|
||||
ASSERT(x < MAX_NUMBER_OF_GRIDS);
|
||||
ASSERT(y < MAX_NUMBER_OF_GRIDS);
|
||||
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_InstanceId;
|
||||
uint32 m_unloadTimer;
|
||||
float m_VisibleDistance;
|
||||
|
||||
MapRefManager m_mapRefManager;
|
||||
MapRefManager::iterator m_mapRefIter;
|
||||
|
|
@ -557,6 +563,8 @@ class MANGOS_DLL_SPEC InstanceMap : public Map
|
|||
void SendResetWarnings(uint32 timeLeft) const;
|
||||
void SetResetSchedule(bool on);
|
||||
uint32 GetMaxPlayers() const;
|
||||
|
||||
virtual void InitVisibilityDistance();
|
||||
private:
|
||||
bool m_resetAfterUnload;
|
||||
bool m_unloadWhenEmpty;
|
||||
|
|
@ -575,6 +583,8 @@ class MANGOS_DLL_SPEC BattleGroundMap : public Map
|
|||
bool CanEnter(Player* player);
|
||||
void SetUnload();
|
||||
void UnloadAll(bool pForce);
|
||||
|
||||
virtual void InitVisibilityDistance();
|
||||
};
|
||||
|
||||
/*inline
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
// take care of loaded GridMaps (when unused, unload it!)
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ class MANGOS_DLL_DECL MapInstanced : public Map
|
|||
}
|
||||
|
||||
InstancedMaps &GetInstancedMaps() { return m_InstancedMaps; }
|
||||
virtual void InitVisibilityDistance();
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
|||
|
|
@ -70,6 +70,12 @@ MapManager::Initialize()
|
|||
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
|
||||
void MapManager::checkAndCorrectGridStatesArray()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton<MapManager, MaNGOS::
|
|||
void RemoveBonesFromMap(uint32 mapid, uint64 guid, float x, float y);
|
||||
uint32 GenerateInstanceId() { return ++i_MaxInstanceId; }
|
||||
void InitMaxInstanceId();
|
||||
void InitializeVisibilityDistanceInfo();
|
||||
|
||||
/* statistics */
|
||||
uint32 GetNumInstances();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> >, WorldTypeMapContainer > message(say_worker);
|
||||
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)
|
||||
|
|
@ -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);
|
||||
TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> >, WorldTypeMapContainer > message(say_worker);
|
||||
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)
|
||||
|
|
@ -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);
|
||||
TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> >, WorldTypeMapContainer > message(say_worker);
|
||||
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)
|
||||
|
|
@ -1755,8 +1755,8 @@ void WorldObject::GetNearPoint(WorldObject const* searcher, float &x, float &y,
|
|||
TypeContainerVisitor<MaNGOS::WorldObjectWorker<MaNGOS::NearUsedPosDo>, WorldTypeMapContainer > world_obj_worker(worker);
|
||||
|
||||
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||
cell_lock->Visit(cell_lock, grid_obj_worker, *GetMap());
|
||||
cell_lock->Visit(cell_lock, world_obj_worker, *GetMap());
|
||||
cell_lock->Visit(cell_lock, grid_obj_worker, *GetMap(), *this, distance2d);
|
||||
cell_lock->Visit(cell_lock, world_obj_worker, *GetMap(), *this, distance2d);
|
||||
}
|
||||
|
||||
// maybe can just place in primary position
|
||||
|
|
|
|||
|
|
@ -32,10 +32,13 @@
|
|||
#define CONTACT_DISTANCE 0.5f
|
||||
#define INTERACTION_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 DEFAULT_VISIBILITY_DISTANCE (SIZE_OF_GRID_CELL) // default visible distance
|
||||
#define MAX_VISIBILITY_DISTANCE 333.0f // max distance for visible object show, limited in 333 yards
|
||||
#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 MAX_STEALTH_DETECT_RANGE 45.0f
|
||||
|
||||
enum TypeMask
|
||||
{
|
||||
|
|
|
|||
|
|
@ -254,7 +254,9 @@ ObjectAccessor::_buildChangeObjectForPlayer(WorldObject *obj, UpdateDataMapType
|
|||
WorldObjectChangeAccumulator notifier(*obj, update_players);
|
||||
TypeContainerVisitor<WorldObjectChangeAccumulator, WorldTypeMapContainer > player_notifier(notifier);
|
||||
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*
|
||||
|
|
|
|||
|
|
@ -12140,6 +12140,7 @@ void Player::PrepareQuestMenu( uint64 guid )
|
|||
void Player::SendPreparedQuest(uint64 guid)
|
||||
{
|
||||
QuestMenu& questMenu = PlayerTalkClass->GetQuestMenu();
|
||||
|
||||
if (questMenu.Empty())
|
||||
return;
|
||||
|
||||
|
|
@ -12160,8 +12161,9 @@ void Player::SendPreparedQuest( uint64 guid )
|
|||
PlayerTalkClass->SendQuestGiverRequestItems(pQuest, guid, CanRewardQuest(pQuest, false), true);
|
||||
else if (status == DIALOG_STATUS_UNK2)
|
||||
PlayerTalkClass->SendQuestGiverRequestItems(pQuest, guid, CanRewardQuest(pQuest, false), true);
|
||||
// Send completable on repeatable quest if player don't have quest
|
||||
else if( pQuest->IsRepeatable() && !pQuest->IsDaily() )
|
||||
// Send completable on repeatable and autoCompletable quest if player don't have quest
|
||||
// TODO: verify if check for !pQuest->IsDaily() is really correct (possibly not)
|
||||
else if (pQuest->IsAutoComplete() && pQuest->IsRepeatable() && !pQuest->IsDaily())
|
||||
PlayerTalkClass->SendQuestGiverRequestItems(pQuest, guid, CanCompleteRepeatableQuest(pQuest), true);
|
||||
else
|
||||
PlayerTalkClass->SendQuestGiverQuestDetails(pQuest, guid, true);
|
||||
|
|
@ -16819,8 +16821,8 @@ void Player::HandleStealthedUnitsDetection()
|
|||
TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyStealthedCheck >, GridTypeMapContainer > grid_unit_searcher(searcher);
|
||||
|
||||
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||
cell_lock->Visit(cell_lock, world_unit_searcher, *GetMap());
|
||||
cell_lock->Visit(cell_lock, grid_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(), *this, MAX_PLAYER_STEALTH_DETECT_RANGE);
|
||||
|
||||
WorldObject const* viewPoint = GetViewPoint();
|
||||
|
||||
|
|
@ -19631,7 +19633,7 @@ void Player::SetTitle(CharTitlesEntry const* title, bool lost)
|
|||
GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
void Player::ConvertRune(uint8 index, uint8 newType)
|
||||
void Player::ConvertRune(uint8 index, RuneType newType)
|
||||
{
|
||||
SetCurrentRune(index, newType);
|
||||
|
||||
|
|
@ -19659,6 +19661,15 @@ void Player::AddRunePower(uint8 index)
|
|||
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()
|
||||
{
|
||||
if(getClass() != CLASS_DEATH_KNIGHT)
|
||||
|
|
@ -19670,8 +19681,8 @@ void Player::InitRunes()
|
|||
|
||||
for(uint32 i = 0; i < MAX_RUNES; ++i)
|
||||
{
|
||||
SetBaseRune(i, i / 2); // init base types
|
||||
SetCurrentRune(i, i / 2); // init current types
|
||||
SetBaseRune(i, runeSlotTypes[i]); // init base types
|
||||
SetCurrentRune(i, runeSlotTypes[i]); // init current types
|
||||
SetRuneCooldown(i, 0); // reset cooldowns
|
||||
m_runes->SetRuneState(i);
|
||||
}
|
||||
|
|
@ -19680,6 +19691,16 @@ void Player::InitRunes()
|
|||
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)
|
||||
{
|
||||
Loot loot;
|
||||
|
|
|
|||
|
|
@ -2222,13 +2222,14 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
|
||||
DeclinedName const* GetDeclinedNames() const { return m_declinedname; }
|
||||
uint8 GetRunesState() const { return m_runes->runeState; }
|
||||
uint8 GetBaseRune(uint8 index) const { return m_runes->runes[index].BaseRune; }
|
||||
uint8 GetCurrentRune(uint8 index) const { return m_runes->runes[index].CurrentRune; }
|
||||
RuneType GetBaseRune(uint8 index) const { return RuneType(m_runes->runes[index].BaseRune); }
|
||||
RuneType GetCurrentRune(uint8 index) const { return RuneType(m_runes->runes[index].CurrentRune); }
|
||||
uint16 GetRuneCooldown(uint8 index) const { return m_runes->runes[index].Cooldown; }
|
||||
void SetBaseRune(uint8 index, uint8 baseRune) { m_runes->runes[index].BaseRune = baseRune; }
|
||||
void SetCurrentRune(uint8 index, uint8 currentRune) { m_runes->runes[index].CurrentRune = currentRune; }
|
||||
bool IsBaseRuneSlotsOnCooldown(RuneType runeType) const;
|
||||
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 ConvertRune(uint8 index, uint8 newType);
|
||||
void ConvertRune(uint8 index, RuneType newType);
|
||||
void ResyncRunes(uint8 count);
|
||||
void AddRunePower(uint8 index);
|
||||
void InitRunes();
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ INSTANTIATE_SINGLETON_1(PoolHandler);
|
|||
template <class T>
|
||||
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
|
||||
|
|
@ -107,12 +108,14 @@ void PoolGroup<T>::DespawnObject(uint32 guid)
|
|||
if (!guid || EqualChanced[i].guid == guid)
|
||||
{
|
||||
if (guid)
|
||||
CacheValue = EqualChanced[i].guid;
|
||||
m_LastDespawnedNode = EqualChanced[i].guid;
|
||||
else
|
||||
Despawn1Object(EqualChanced[i].guid);
|
||||
|
||||
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
|
||||
{
|
||||
uint32 roll = RollOne();
|
||||
if (cache && CacheValue != roll)
|
||||
Despawn1Object(CacheValue);
|
||||
CacheValue = Spawn1Object(roll);
|
||||
if (cache && m_LastDespawnedNode != roll)
|
||||
Despawn1Object(m_LastDespawnedNode);
|
||||
|
||||
m_LastDespawnedNode = 0;
|
||||
Spawn1Object(roll);
|
||||
}
|
||||
else if (limit < EqualChanced.size() && Spawned < limit)
|
||||
else if (limit < EqualChanced.size() && m_SpawnedPoolAmount < limit)
|
||||
{
|
||||
std::vector<uint32> IndexList;
|
||||
for (size_t i = 0; i < EqualChanced.size(); ++i)
|
||||
if (!EqualChanced[i].spawned)
|
||||
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 index = IndexList[roll];
|
||||
if (!cache || (cache && EqualChanced[index].guid != CacheValue))
|
||||
if (!cache || (cache && EqualChanced[index].guid != m_LastDespawnedNode))
|
||||
{
|
||||
if (cache)
|
||||
Despawn1Object(CacheValue);
|
||||
Despawn1Object(m_LastDespawnedNode);
|
||||
|
||||
EqualChanced[index].spawned = Spawn1Object(EqualChanced[index].guid);
|
||||
}
|
||||
else
|
||||
EqualChanced[index].spawned = ReSpawn1Object(EqualChanced[index].guid);
|
||||
|
||||
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;
|
||||
IndexList.erase(itr);
|
||||
}
|
||||
CacheValue = 0;
|
||||
m_LastDespawnedNode = 0;
|
||||
}
|
||||
else // Not enough objects in pool, so spawn all
|
||||
{
|
||||
|
|
@ -330,7 +337,7 @@ bool PoolGroup<Pool>::ReSpawn1Object(uint32 /*guid*/)
|
|||
|
||||
PoolHandler::PoolHandler()
|
||||
{
|
||||
isSystemInit = false;
|
||||
m_IsPoolSystemStarted = false;
|
||||
}
|
||||
|
||||
void PoolHandler::LoadFromDB()
|
||||
|
|
@ -624,7 +631,7 @@ void PoolHandler::Initialize()
|
|||
}
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -56,10 +56,10 @@ class PoolGroup
|
|||
void RemoveOneRelation(uint16 child_pool_id);
|
||||
private:
|
||||
typedef std::vector<PoolObject> PoolObjectList;
|
||||
uint32 CacheValue; // Store the guid of the removed creature/gameobject during a pool update
|
||||
PoolObjectList ExplicitlyChanced;
|
||||
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
|
||||
|
|
@ -81,7 +81,7 @@ class PoolHandler
|
|||
void Initialize();
|
||||
|
||||
protected:
|
||||
bool isSystemInit;
|
||||
bool m_IsPoolSystemStarted;
|
||||
uint16 max_pool_id;
|
||||
typedef std::vector<PoolTemplateData> PoolTemplateDataMap;
|
||||
typedef std::vector<PoolGroup<Creature> > PoolGroupCreatureMap;
|
||||
|
|
|
|||
|
|
@ -2433,9 +2433,12 @@ enum SummonType
|
|||
SUMMON_TYPE_UNKNOWN5 = 409,
|
||||
SUMMON_TYPE_UNKNOWN2 = 427,
|
||||
SUMMON_TYPE_POSESSED2 = 428,
|
||||
SUMMON_TYPE_QUEST_CRITTER = 487,
|
||||
SUMMON_TYPE_QUEST_WILD = 587,
|
||||
SUMMON_TYPE_INFERNO = 711,
|
||||
SUMMON_TYPE_GUARDIAN2 = 713,
|
||||
SUMMON_TYPE_GUARDIAN3 = 1161,
|
||||
SUMMON_TYPE_CREATURE = 1302,
|
||||
SUMMON_TYPE_ELEMENTAL = 1561,
|
||||
SUMMON_TYPE_FORCE_OF_NATURE = 1562
|
||||
};
|
||||
|
|
|
|||
|
|
@ -476,12 +476,12 @@ WorldObject* Spell::FindCorpseUsing()
|
|||
|
||||
TypeContainerVisitor<MaNGOS::WorldObjectSearcher<T>, GridTypeMapContainer > grid_searcher(searcher);
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
|
@ -970,7 +970,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
|
|||
// Do healing and triggers
|
||||
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;
|
||||
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);
|
||||
|
||||
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||
cell_lock->Visit(cell_lock, world_unit_searcher, *m_caster->GetMap());
|
||||
cell_lock->Visit(cell_lock, grid_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(), *m_caster, max_range);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||
cell_lock->Visit(cell_lock, world_unit_searcher, *m_caster->GetMap());
|
||||
cell_lock->Visit(cell_lock, grid_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(), *m_caster, max_range);
|
||||
}
|
||||
|
||||
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);
|
||||
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||
|
||||
cell_lock->Visit(cell_lock, world_unit_searcher, *m_caster->GetMap());
|
||||
cell_lock->Visit(cell_lock, grid_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(), *pUnitTarget, max_range);
|
||||
}
|
||||
if (tempUnitMap.empty())
|
||||
break;
|
||||
|
|
@ -3556,7 +3556,7 @@ SpellCastResult Spell::CheckRuneCost(uint32 runeCostID)
|
|||
|
||||
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))
|
||||
runeCost[rune]--;
|
||||
}
|
||||
|
|
@ -3599,7 +3599,7 @@ void Spell::TakeRunePower()
|
|||
|
||||
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))
|
||||
{
|
||||
plr->SetRuneCooldown(i, RUNE_COOLDOWN); // 5*2=10 sec
|
||||
|
|
@ -3613,7 +3613,7 @@ void Spell::TakeRunePower()
|
|||
{
|
||||
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))
|
||||
{
|
||||
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);
|
||||
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)
|
||||
{
|
||||
|
|
@ -4128,7 +4128,7 @@ SpellCastResult Spell::CheckCast(bool strict)
|
|||
TypeContainerVisitor<MaNGOS::CreatureLastSearcher<MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck>, GridTypeMapContainer > grid_creature_searcher(searcher);
|
||||
|
||||
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 )
|
||||
{
|
||||
|
|
@ -5189,7 +5189,8 @@ SpellCastResult Spell::CheckItems()
|
|||
|
||||
TypeContainerVisitor<MaNGOS::GameObjectSearcher<MaNGOS::GameObjectFocusCheck>, GridTypeMapContainer > object_checker(checker);
|
||||
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)
|
||||
return SPELL_FAILED_REQUIRES_SPELL_FOCUS;
|
||||
|
|
|
|||
|
|
@ -460,6 +460,13 @@ m_isRemovedOnShapeLost(true), m_in_use(0), m_deleted(false)
|
|||
m_spellProto->Stances &&
|
||||
!(m_spellProto->AttributesEx2 & SPELL_ATTR_EX2_NOT_NEED_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()
|
||||
|
|
@ -754,8 +761,8 @@ void AreaAura::Update(uint32 diff)
|
|||
TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyFriendlyUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher);
|
||||
TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyFriendlyUnitInObjectRangeCheck>, GridTypeMapContainer > grid_unit_searcher(searcher);
|
||||
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||
cell_lock->Visit(cell_lock, world_unit_searcher, *caster->GetMap());
|
||||
cell_lock->Visit(cell_lock, grid_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(), *caster, m_radius);
|
||||
break;
|
||||
}
|
||||
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>, GridTypeMapContainer > grid_unit_searcher(searcher);
|
||||
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||
cell_lock->Visit(cell_lock, world_unit_searcher, *caster->GetMap());
|
||||
cell_lock->Visit(cell_lock, grid_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(), *caster, m_radius);
|
||||
break;
|
||||
}
|
||||
case AREA_AURA_OWNER:
|
||||
|
|
@ -5001,7 +5008,8 @@ void Aura::HandleAuraModIncreaseHealth(bool apply, bool Real)
|
|||
case 12976: // Warrior Last Stand triggered spell
|
||||
case 28726: // Nightmare Seed ( Nightmare Seed )
|
||||
case 34511: // Valor (Bulwark of Kings, Bulwark of the Ancient Kings)
|
||||
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 54443: // Demonic Empowerment (Voidwalker)
|
||||
{
|
||||
|
|
@ -6141,6 +6149,15 @@ void Aura::HandleSchoolAbsorb(bool apply, bool Real)
|
|||
//+30% from +spell bonus
|
||||
DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.30f;
|
||||
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:
|
||||
// Savage Defense (amount store original percent of attack power applied)
|
||||
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());
|
||||
|
||||
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
|
||||
|
|
@ -7025,8 +7062,8 @@ void Aura::PeriodicDummyTick()
|
|||
|
||||
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||
|
||||
cell_lock->Visit(cell_lock, grid_object_checker, *caster->GetMap());
|
||||
cell_lock->Visit(cell_lock, world_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(), *caster, radius);
|
||||
}
|
||||
|
||||
if(targets.empty())
|
||||
|
|
@ -7175,7 +7212,7 @@ void Aura::HandleManaShield(bool apply, bool Real)
|
|||
switch(m_spellProto->SpellFamilyName)
|
||||
{
|
||||
case SPELLFAMILY_MAGE:
|
||||
if(m_spellProto->SpellFamilyFlags & UI64LIT(0x8000))
|
||||
if(m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000008000))
|
||||
{
|
||||
// Mana Shield
|
||||
// +50% from +spd bonus
|
||||
|
|
@ -7256,13 +7293,13 @@ void Aura::HandleAuraConvertRune(bool apply, bool Real)
|
|||
{
|
||||
if(!plr->GetRuneCooldown(i))
|
||||
{
|
||||
plr->ConvertRune(i, GetSpellProto()->EffectMiscValueB[m_effIndex]);
|
||||
plr->ConvertRune(i, RuneType(GetSpellProto()->EffectMiscValueB[m_effIndex]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(plr->GetCurrentRune(i) == GetSpellProto()->EffectMiscValueB[m_effIndex])
|
||||
if(plr->GetCurrentRune(i) == RuneType(GetSpellProto()->EffectMiscValueB[m_effIndex]))
|
||||
{
|
||||
plr->ConvertRune(i, plr->GetBaseRune(i));
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -669,6 +669,12 @@ void Spell::EffectSchoolDMG(uint32 effect_idx)
|
|||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1636,6 +1642,25 @@ void Spell::EffectDummy(uint32 i)
|
|||
((Player*)m_caster)->SendAttackSwingCancelAttack();
|
||||
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;
|
||||
case SPELLFAMILY_PALADIN:
|
||||
|
|
@ -3297,6 +3322,8 @@ void Spell::EffectSummonType(uint32 i)
|
|||
EffectSummonGuardian(i);
|
||||
break;
|
||||
case SUMMON_TYPE_WILD:
|
||||
case SUMMON_TYPE_QUEST_WILD:
|
||||
case SUMMON_TYPE_CREATURE:
|
||||
EffectSummonWild(i);
|
||||
break;
|
||||
case SUMMON_TYPE_DEMON:
|
||||
|
|
@ -3310,6 +3337,7 @@ void Spell::EffectSummonType(uint32 i)
|
|||
case SUMMON_TYPE_CRITTER:
|
||||
case SUMMON_TYPE_CRITTER2:
|
||||
case SUMMON_TYPE_CRITTER3:
|
||||
case SUMMON_TYPE_QUEST_CRITTER:
|
||||
EffectSummonCritter(i);
|
||||
break;
|
||||
case SUMMON_TYPE_TOTEM_SLOT1:
|
||||
|
|
@ -5374,6 +5402,16 @@ void Spell::EffectScriptEffect(uint32 effIndex)
|
|||
}
|
||||
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:
|
||||
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);
|
||||
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);
|
||||
for(Unit::AuraList::const_iterator itr = m_dummyAuras.begin(); itr != m_dummyAuras.end(); ++itr)
|
||||
{
|
||||
SpellEntry const *spellInfo = (*itr)->GetSpellProto();
|
||||
// search seal (all seals have judgement's aura dummy spell id in 2 effect
|
||||
if ((*itr)->GetEffIndex() != 2 || !spellInfo || !IsSealSpell(spellInfo))
|
||||
// search seal (offensive seals have judgement's aura dummy spell id in 2 effect
|
||||
if ((*itr)->GetEffIndex() != 2 || !IsSealSpell((*itr)->GetSpellProto()))
|
||||
continue;
|
||||
spellId2 = (*itr)->GetModifier()->m_amount;
|
||||
SpellEntry const *judge = sSpellStore.LookupEntry(spellId2);
|
||||
|
|
@ -5414,6 +5451,18 @@ void Spell::EffectScriptEffect(uint32 effIndex)
|
|||
continue;
|
||||
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)
|
||||
m_caster->CastSpell(unitTarget, spellId1, true);
|
||||
if (spellId2)
|
||||
|
|
@ -6830,7 +6879,7 @@ void Spell::EffectActivateRune(uint32 eff_idx)
|
|||
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1501,6 +1501,10 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons
|
|||
// Savage Roar and Savage Roar (triggered)
|
||||
if (spellInfo_1->SpellIconID == 2865 && spellInfo_2->SpellIconID == 2865)
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -91,8 +91,8 @@ TotemAI::UpdateAI(const uint32 /*diff*/)
|
|||
TypeContainerVisitor<MaNGOS::UnitLastSearcher<MaNGOS::NearestAttackableUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker);
|
||||
|
||||
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||
cell_lock->Visit(cell_lock, grid_object_checker, *m_creature->GetMap());
|
||||
cell_lock->Visit(cell_lock, world_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(), *m_creature, max_range);
|
||||
}
|
||||
|
||||
// If have target
|
||||
|
|
|
|||
|
|
@ -1862,6 +1862,8 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
|
|||
|
||||
// Reduce shield amount
|
||||
mod->m_amount-=currentAbsorb;
|
||||
if((*i)->DropAuraCharge())
|
||||
mod->m_amount = 0;
|
||||
// Need remove it later
|
||||
if (mod->m_amount<=0)
|
||||
existExpired = true;
|
||||
|
|
@ -3436,7 +3438,8 @@ bool Unit::AddAura(Aura *Aur)
|
|||
// Aura can stack on self -> Stack it;
|
||||
if(aurSpellInfo->StackAmount)
|
||||
{
|
||||
i2->second->modStackAmount(1);
|
||||
// can be created with >1 stack by some spell mods
|
||||
i2->second->modStackAmount(Aur->GetStackAmount());
|
||||
delete Aur;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -5134,6 +5137,16 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
|
|||
CastSpell(this, 28682, true, castItem, triggeredByAura);
|
||||
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;
|
||||
}
|
||||
|
|
@ -6121,8 +6134,16 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
|
|||
// Earth Shield
|
||||
if (dummySpell->SpellFamilyFlags & UI64LIT(0x0000040000000000))
|
||||
{
|
||||
basepoints0 = triggerAmount;
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
|
@ -6983,6 +7004,12 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
|
|||
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
|
||||
// dummy basepoints or other customs
|
||||
|
|
@ -8218,7 +8245,17 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
|
|||
if (spellProto->SpellIconID == 186)
|
||||
{
|
||||
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)
|
||||
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);
|
||||
}
|
||||
|
||||
// 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);
|
||||
for(AuraList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
|
||||
{
|
||||
|
|
@ -8495,12 +8533,6 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM
|
|||
if (pVictim->HasAura(6788))
|
||||
crit_chance+=(*i)->GetModifier()->m_amount;
|
||||
break;
|
||||
case 21: // Test of Faith
|
||||
case 6935:
|
||||
case 6918:
|
||||
if (pVictim->GetHealth() < pVictim->GetMaxHealth()/2)
|
||||
crit_chance+=(*i)->GetModifier()->m_amount;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -8508,6 +8540,25 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM
|
|||
// Custom crit by class
|
||||
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:
|
||||
// Sacred Shield
|
||||
if (spellProto->SpellFamilyFlags & UI64LIT(0x0000000040000000))
|
||||
|
|
@ -8515,14 +8566,12 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM
|
|||
Aura *aura = pVictim->GetDummyAura(58597);
|
||||
if (aura && aura->GetCasterGUID() == GetGUID())
|
||||
crit_chance+=aura->GetModifier()->m_amount;
|
||||
break;
|
||||
}
|
||||
// Exorcism
|
||||
else if (spellProto->Category == 19)
|
||||
{
|
||||
if (pVictim->GetCreatureTypeMask() & CREATURE_TYPEMASK_DEMON_OR_UNDEAD)
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SPELLFAMILY_SHAMAN:
|
||||
|
|
@ -8536,7 +8585,6 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM
|
|||
pVictim->RemoveAurasByCasterSpell(flameShock->GetId(), GetGUID());
|
||||
return true;
|
||||
}
|
||||
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
|
||||
{
|
||||
if(!u)
|
||||
if(!u || !IsInMap(u))
|
||||
return false;
|
||||
|
||||
// Always can see self
|
||||
|
|
@ -9440,6 +9488,7 @@ bool Unit::isVisibleForOrDetect(Unit const* u, WorldObject const* viewPoint, boo
|
|||
if(m_Visibility==VISIBILITY_RESPAWN)
|
||||
return false;
|
||||
|
||||
Map& _map = *u->GetMap();
|
||||
// Grid dead/alive checks
|
||||
if( u->GetTypeId()==TYPEID_PLAYER)
|
||||
{
|
||||
|
|
@ -9483,26 +9532,26 @@ bool Unit::isVisibleForOrDetect(Unit const* u, WorldObject const* viewPoint, boo
|
|||
if(u->GetTypeId()==TYPEID_PLAYER)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
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
|
||||
if (!IsWithinDistInMap(viewPoint,World::GetMaxVisibleDistanceForPlayer()+(inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
|
||||
if (!IsWithinDistInMap(viewPoint, _map.GetVisibilityDistance() + (inVisibleList ? World::GetVisibleUnitGreyDistance() : 0.0f), is3dDistance))
|
||||
return false;
|
||||
}
|
||||
else // distance for show creature
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
|
@ -11690,8 +11739,8 @@ Unit* Unit::SelectNearbyTarget(Unit* except /*= NULL*/) const
|
|||
TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck>, GridTypeMapContainer > grid_unit_searcher(searcher);
|
||||
|
||||
CellLock<GridReadGuard> cell_lock(cell, p);
|
||||
cell_lock->Visit(cell_lock, world_unit_searcher, *GetMap());
|
||||
cell_lock->Visit(cell_lock, grid_unit_searcher, *GetMap());
|
||||
cell_lock->Visit(cell_lock, world_unit_searcher, *GetMap(), *this, ATTACK_DISTANCE);
|
||||
cell_lock->Visit(cell_lock, grid_unit_searcher, *GetMap(), *this, ATTACK_DISTANCE);
|
||||
}
|
||||
|
||||
// remove current target
|
||||
|
|
|
|||
|
|
@ -69,9 +69,11 @@ volatile bool World::m_stopEvent = false;
|
|||
uint8 World::m_ExitCode = SHUTDOWN_EXIT_CODE;
|
||||
volatile uint32 World::m_worldLoopCounter = 0;
|
||||
|
||||
float World::m_MaxVisibleDistanceForCreature = DEFAULT_VISIBILITY_DISTANCE;
|
||||
float World::m_MaxVisibleDistanceForPlayer = DEFAULT_VISIBILITY_DISTANCE;
|
||||
float World::m_MaxVisibleDistanceOnContinents = 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_MaxVisibleDistanceInFlight = DEFAULT_VISIBILITY_DISTANCE;
|
||||
float World::m_VisibleUnitGreyDistance = 0;
|
||||
float World::m_VisibleObjectGreyDistance = 0;
|
||||
|
|
@ -1007,28 +1009,45 @@ void World::LoadConfigSettings(bool reload)
|
|||
m_VisibleObjectGreyDistance = MAX_VISIBILITY_DISTANCE;
|
||||
}
|
||||
|
||||
m_MaxVisibleDistanceForCreature = sConfig.GetFloatDefault("Visibility.Distance.Creature", DEFAULT_VISIBILITY_DISTANCE);
|
||||
if(m_MaxVisibleDistanceForCreature < 45*sWorld.getRate(RATE_CREATURE_AGGRO))
|
||||
//visibility on continents
|
||||
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));
|
||||
m_MaxVisibleDistanceForCreature = 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_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);
|
||||
m_MaxVisibleDistanceForCreature = MAX_VISIBILITY_DISTANCE-m_VisibleUnitGreyDistance;
|
||||
sLog.outError("Visibility.Distance.Continents can't be greater %f",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));
|
||||
m_MaxVisibleDistanceForPlayer = 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_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);
|
||||
m_MaxVisibleDistanceForPlayer = MAX_VISIBILITY_DISTANCE - m_VisibleUnitGreyDistance;
|
||||
sLog.outError("Visibility.Distance.Instances can't be greater %f",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);
|
||||
if(m_MaxVisibleDistanceForObject < INTERACTION_DISTANCE)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -494,9 +494,11 @@ class World
|
|||
bool IsScriptScheduled() const { return m_scheduledScripts > 0; }
|
||||
|
||||
// for max speed access
|
||||
static float GetMaxVisibleDistanceForCreature() { return m_MaxVisibleDistanceForCreature; }
|
||||
static float GetMaxVisibleDistanceForPlayer() { return m_MaxVisibleDistanceForPlayer; }
|
||||
static float GetMaxVisibleDistanceOnContinents() { return m_MaxVisibleDistanceOnContinents; }
|
||||
static float GetMaxVisibleDistanceInInstances() { return m_MaxVisibleDistanceInInctances; }
|
||||
static float GetMaxVisibleDistanceInBGArenas() { return m_MaxVisibleDistanceInBGArenas; }
|
||||
static float GetMaxVisibleDistanceForObject() { return m_MaxVisibleDistanceForObject; }
|
||||
|
||||
static float GetMaxVisibleDistanceInFlight() { return m_MaxVisibleDistanceInFlight; }
|
||||
static float GetVisibleUnitGreyDistance() { return m_VisibleUnitGreyDistance; }
|
||||
static float GetVisibleObjectGreyDistance() { return m_VisibleObjectGreyDistance; }
|
||||
|
|
@ -560,9 +562,11 @@ class World
|
|||
std::string m_dataPath;
|
||||
|
||||
// for max speed access
|
||||
static float m_MaxVisibleDistanceForCreature;
|
||||
static float m_MaxVisibleDistanceForPlayer;
|
||||
static float m_MaxVisibleDistanceOnContinents;
|
||||
static float m_MaxVisibleDistanceInInctances;
|
||||
static float m_MaxVisibleDistanceInBGArenas;
|
||||
static float m_MaxVisibleDistanceForObject;
|
||||
|
||||
static float m_MaxVisibleDistanceInFlight;
|
||||
static float m_VisibleUnitGreyDistance;
|
||||
static float m_VisibleObjectGreyDistance;
|
||||
|
|
|
|||
|
|
@ -962,12 +962,12 @@ GM.AllowAchievementGain = 1
|
|||
# 1 (raid members 100% auto detect invisible player from same raid)
|
||||
# 2 (players from same team can 100% auto detect invisible player)
|
||||
#
|
||||
# Visibility.Distance.Creature
|
||||
# Visibility.Distance.Player
|
||||
# Visibility distance for different in game object
|
||||
# Visibility.Distance.Continents
|
||||
# Visibility.Distance.Instances
|
||||
# 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
|
||||
# Min limit dependent from objects
|
||||
# Default: 132 (cell size)
|
||||
# Min limit is max aggro radius (45) * Rate.Creature.Aggro
|
||||
#
|
||||
# Visibility.Distance.Object
|
||||
|
|
@ -993,8 +993,9 @@ GM.AllowAchievementGain = 1
|
|||
###################################################################################################################
|
||||
|
||||
Visibility.GroupMode = 0
|
||||
Visibility.Distance.Creature = 100
|
||||
Visibility.Distance.Player = 100
|
||||
Visibility.Distance.Continents = 90
|
||||
Visibility.Distance.Instances = 120
|
||||
Visibility.Distance.BGArenas = 180
|
||||
Visibility.Distance.Object = 100
|
||||
Visibility.Distance.InFlight = 100
|
||||
Visibility.Distance.Grey.Unit = 1
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "8502"
|
||||
#define REVISION_NR "8526"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#ifndef __REVISION_SQL_H__
|
||||
#define __REVISION_SQL_H__
|
||||
#define REVISION_DB_CHARACTERS "required_8469_01_characters_character_spell"
|
||||
#define REVISION_DB_MANGOS "required_8499_01_mangos_spell_elixir"
|
||||
#define REVISION_DB_CHARACTERS "required_8505_01_characters_character_spell"
|
||||
#define REVISION_DB_MANGOS "required_8521_01_mangos_spell_proc_event"
|
||||
#define REVISION_DB_REALMD "required_8332_01_realmd_realmcharacters"
|
||||
#endif // __REVISION_SQL_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue