mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 16:37:01 +00:00
Merge remote branch 'origin/master' into 335
This commit is contained in:
commit
af0402789e
101 changed files with 1749 additions and 2180 deletions
1
NEWS
1
NEWS
|
|
@ -17,6 +17,7 @@ Version 0.16
|
||||||
* Under discussion.
|
* Under discussion.
|
||||||
* OpenSSL lib upgrade to OpenSSL 1.0.0.
|
* OpenSSL lib upgrade to OpenSSL 1.0.0.
|
||||||
* Sockets lib use dropped.
|
* Sockets lib use dropped.
|
||||||
|
* dotconfpp lib use dropped.
|
||||||
* Upgrade to client version 3.3.3a (build 11723).
|
* Upgrade to client version 3.3.3a (build 11723).
|
||||||
|
|
||||||
Version 0.15
|
Version 0.15
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ CREATE TABLE `db_version` (
|
||||||
`version` varchar(120) default NULL,
|
`version` varchar(120) default NULL,
|
||||||
`creature_ai_version` varchar(120) default NULL,
|
`creature_ai_version` varchar(120) default NULL,
|
||||||
`cache_id` int(10) default '0',
|
`cache_id` int(10) default '0',
|
||||||
`required_10045_01_mangos_spell_proc_event` bit(1) default NULL
|
`required_10089_01_mangos_game_event_pool` bit(1) default NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
|
||||||
|
|
||||||
--
|
--
|
||||||
|
|
@ -577,6 +577,7 @@ INSERT INTO `command` VALUES
|
||||||
('gm ingame',0,'Syntax: .gm ingame\r\n\r\nDisplay a list of available in game Game Masters.'),
|
('gm ingame',0,'Syntax: .gm ingame\r\n\r\nDisplay a list of available in game Game Masters.'),
|
||||||
('gm list',3,'Syntax: .gm list\r\n\r\nDisplay a list of all Game Masters accounts and security levels.'),
|
('gm list',3,'Syntax: .gm list\r\n\r\nDisplay a list of all Game Masters accounts and security levels.'),
|
||||||
('gm visible',1,'Syntax: .gm visible on/off\r\n\r\nOutput current visibility state or make GM visible(on) and invisible(off) for other players.'),
|
('gm visible',1,'Syntax: .gm visible on/off\r\n\r\nOutput current visibility state or make GM visible(on) and invisible(off) for other players.'),
|
||||||
|
('go',1,'Syntax: .go [$playername|pointlink|#x #y #z [#mapid]]\r\nTeleport your character to point with coordinates of player $playername, or coordinates of one from shift-link types: player, tele, taxinode, creature, gameobject, or explicit #x #y #z #mapid coordinates.'),
|
||||||
('go creature',1,'Syntax: .go creature #creature_guid\r\nTeleport your character to creature with guid #creature_guid.\r\n.gocreature #creature_name\r\nTeleport your character to creature with this name.\r\n.gocreature id #creature_id\r\nTeleport your character to a creature that was spawned from the template with this entry.\r\n*If* more than one creature is found, then you are teleported to the first that is found inside the database.'),
|
('go creature',1,'Syntax: .go creature #creature_guid\r\nTeleport your character to creature with guid #creature_guid.\r\n.gocreature #creature_name\r\nTeleport your character to creature with this name.\r\n.gocreature id #creature_id\r\nTeleport your character to a creature that was spawned from the template with this entry.\r\n*If* more than one creature is found, then you are teleported to the first that is found inside the database.'),
|
||||||
('go graveyard',1,'Syntax: .go graveyard #graveyardId\r\n Teleport to graveyard with the graveyardId specified.'),
|
('go graveyard',1,'Syntax: .go graveyard #graveyardId\r\n Teleport to graveyard with the graveyardId specified.'),
|
||||||
('go grid',1,'Syntax: .go grid #gridX #gridY [#mapId]\r\n\r\nTeleport the gm to center of grid with provided indexes at map #mapId (or current map if it not provided).'),
|
('go grid',1,'Syntax: .go grid #gridX #gridY [#mapId]\r\n\r\nTeleport the gm to center of grid with provided indexes at map #mapId (or current map if it not provided).'),
|
||||||
|
|
@ -1571,7 +1572,7 @@ UNLOCK TABLES;
|
||||||
DROP TABLE IF EXISTS `game_event_creature`;
|
DROP TABLE IF EXISTS `game_event_creature`;
|
||||||
CREATE TABLE `game_event_creature` (
|
CREATE TABLE `game_event_creature` (
|
||||||
`guid` int(10) unsigned NOT NULL,
|
`guid` int(10) unsigned NOT NULL,
|
||||||
`event` smallint(6) NOT NULL default '0' COMMENT 'Put negatives values to remove during event',
|
`event` smallint(6) NOT NULL default '0' COMMENT 'Negatives value to remove during event and ignore pool grouping, positive value for spawn during event and if guid is part of pool then al pool memebers must be listed as part of event spawn.',
|
||||||
PRIMARY KEY (`guid`)
|
PRIMARY KEY (`guid`)
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
|
@ -1612,7 +1613,7 @@ UNLOCK TABLES;
|
||||||
DROP TABLE IF EXISTS `game_event_gameobject`;
|
DROP TABLE IF EXISTS `game_event_gameobject`;
|
||||||
CREATE TABLE `game_event_gameobject` (
|
CREATE TABLE `game_event_gameobject` (
|
||||||
`guid` int(10) unsigned NOT NULL,
|
`guid` int(10) unsigned NOT NULL,
|
||||||
`event` smallint(6) NOT NULL default '0' COMMENT 'Put negatives values to remove during event',
|
`event` smallint(6) NOT NULL default '0' COMMENT 'Negatives value to remove during event and ignore pool grouping, positive value for spawn during event and if guid is part of pool then al pool memebers must be listed as part of event spawn.',
|
||||||
PRIMARY KEY (`guid`)
|
PRIMARY KEY (`guid`)
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
|
@ -13704,26 +13705,6 @@ LOCK TABLES `pool_template` WRITE;
|
||||||
/*!40000 ALTER TABLE `pool_template` ENABLE KEYS */;
|
/*!40000 ALTER TABLE `pool_template` ENABLE KEYS */;
|
||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
|
|
||||||
--
|
|
||||||
-- Table structure for table `game_event_pool`
|
|
||||||
--
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `game_event_pool`;
|
|
||||||
CREATE TABLE `game_event_pool` (
|
|
||||||
`pool_entry` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Id of the pool',
|
|
||||||
`event` smallint(6) NOT NULL default '0' COMMENT 'Put negatives values to remove during event',
|
|
||||||
PRIMARY KEY (`pool_entry`)
|
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Dumping data for table `game_event_pool`
|
|
||||||
--
|
|
||||||
|
|
||||||
LOCK TABLES `game_event_pool` WRITE;
|
|
||||||
/*!40000 ALTER TABLE `game_event_pool` DISABLE KEYS */;
|
|
||||||
/*!40000 ALTER TABLE `game_event_pool` ENABLE KEYS */;
|
|
||||||
UNLOCK TABLES;
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Table structure for table `prospecting_loot_template`
|
-- Table structure for table `prospecting_loot_template`
|
||||||
--
|
--
|
||||||
|
|
@ -17930,6 +17911,7 @@ INSERT INTO `spell_proc_event` VALUES
|
||||||
(31244, 0x00, 8, 0x003E0000, 0x00000009, 0x00000000, 0x00000000, 0x00002034, 0.000000, 0.000000, 0),
|
(31244, 0x00, 8, 0x003E0000, 0x00000009, 0x00000000, 0x00000000, 0x00002034, 0.000000, 0.000000, 0),
|
||||||
(31394, 0x20, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
(31394, 0x20, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
||||||
(31569, 0x00, 3, 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
(31569, 0x00, 3, 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
||||||
|
(31571, 0x00, 3, 0x00000000, 0x00000000, 0x00000008, 0x00004000, 0x00000000, 0.000000, 0.000000, 0),
|
||||||
(31785, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00008800, 0x00000000, 0.000000, 0.000000, 0),
|
(31785, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00008800, 0x00000000, 0.000000, 0.000000, 0),
|
||||||
(31794, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0),
|
(31794, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0),
|
||||||
(31801, 0x01, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
(31801, 0x01, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
||||||
|
|
@ -18290,7 +18272,7 @@ INSERT INTO `spell_proc_event` VALUES
|
||||||
(61618, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45),
|
(61618, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45),
|
||||||
(61846, 0x00, 9, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
(61846, 0x00, 9, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
||||||
(62600, 0x00, 7, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
(62600, 0x00, 7, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
|
||||||
(63108, 0x00, 5, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
(63108, 0x00, 5, 0x00000002, 0x00000000, 0x00000000, 0x00040000, 0x00000000, 0.000000, 0.000000, 0),
|
||||||
(63156, 0x00, 0, 0x00000001, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
(63156, 0x00, 0, 0x00000001, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
||||||
(63280, 0x00, 11, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
(63280, 0x00, 11, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
|
||||||
(63320, 0x00, 5, 0x00040000, 0x00000000, 0x00008000, 0x00004000, 0x00000001, 0.000000, 0.000000, 0),
|
(63320, 0x00, 5, 0x00040000, 0x00000000, 0x00008000, 0x00004000, 0x00000001, 0.000000, 0.000000, 0),
|
||||||
|
|
|
||||||
5
sql/updates/10056_01_mangos_spell_proc_event.sql
Normal file
5
sql/updates/10056_01_mangos_spell_proc_event.sql
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
ALTER TABLE db_version CHANGE COLUMN required_10045_01_mangos_spell_proc_event required_10056_01_mangos_spell_proc_event bit;
|
||||||
|
|
||||||
|
DELETE FROM spell_proc_event WHERE entry IN (31571, 31572);
|
||||||
|
INSERT INTO spell_proc_event VALUES
|
||||||
|
(31571, 0x00, 3, 0x00000000, 0x00000000, 0x00000008, 0x00004000, 0x00000000, 0.000000, 0.000000, 0);
|
||||||
5
sql/updates/10086_01_mangos_command.sql
Normal file
5
sql/updates/10086_01_mangos_command.sql
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
ALTER TABLE db_version CHANGE COLUMN required_10056_01_mangos_spell_proc_event required_10086_01_mangos_command bit;
|
||||||
|
|
||||||
|
DELETE FROM command WHERE name IN('go');
|
||||||
|
INSERT INTO command (name, security, help) VALUES
|
||||||
|
('go',1,'Syntax: .go [$playername|pointlink|#x #y #z [#mapid]]\r\nTeleport your character to point with coordinates of player $playername, or coordinates of one from shift-link types: player, tele, taxinode, creature, gameobject, or explicit #x #y #z #mapid coordinates.');
|
||||||
3
sql/updates/10089_01_mangos_game_event_pool.sql
Normal file
3
sql/updates/10089_01_mangos_game_event_pool.sql
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
ALTER TABLE db_version CHANGE COLUMN required_10086_01_mangos_command required_10089_01_mangos_game_event_pool bit;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `game_event_pool`;
|
||||||
|
|
@ -88,6 +88,9 @@ pkgdata_DATA = \
|
||||||
10044_02_mangos_spell_proc_event.sql \
|
10044_02_mangos_spell_proc_event.sql \
|
||||||
10045_01_mangos_spell_proc_event.sql \
|
10045_01_mangos_spell_proc_event.sql \
|
||||||
10051_01_characters_character_aura.sql \
|
10051_01_characters_character_aura.sql \
|
||||||
|
10056_01_mangos_spell_proc_event.sql \
|
||||||
|
10086_01_mangos_command.sql \
|
||||||
|
10089_01_mangos_game_event_pool.sql \
|
||||||
README
|
README
|
||||||
|
|
||||||
## Additional files to include when running 'make dist'
|
## Additional files to include when running 'make dist'
|
||||||
|
|
@ -156,4 +159,7 @@ EXTRA_DIST = \
|
||||||
10044_02_mangos_spell_proc_event.sql \
|
10044_02_mangos_spell_proc_event.sql \
|
||||||
10045_01_mangos_spell_proc_event.sql \
|
10045_01_mangos_spell_proc_event.sql \
|
||||||
10051_01_characters_character_aura.sql \
|
10051_01_characters_character_aura.sql \
|
||||||
|
10056_01_mangos_spell_proc_event.sql \
|
||||||
|
10086_01_mangos_command.sql \
|
||||||
|
10089_01_mangos_game_event_pool.sql \
|
||||||
README
|
README
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ class MANGOS_DLL_DECL NGrid
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32& GetGridId() const { return i_gridId; }
|
const uint32& GetGridId() const { return i_gridId; }
|
||||||
void SetGridId(const uint32 id) const { i_gridId = id; }
|
void SetGridId(const uint32 id) { i_gridId = id; }
|
||||||
grid_state_t GetGridState() const { return i_cellstate; }
|
grid_state_t GetGridState() const { return i_cellstate; }
|
||||||
void SetGridState(grid_state_t s) { i_cellstate = s; }
|
void SetGridState(grid_state_t s) { i_cellstate = s; }
|
||||||
uint32 getX() const { return i_x; }
|
uint32 getX() const { return i_x; }
|
||||||
|
|
|
||||||
|
|
@ -639,7 +639,7 @@ void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement)
|
||||||
{
|
{
|
||||||
MaNGOS::AchievementChatBuilder say_builder(*GetPlayer(), CHAT_MSG_ACHIEVEMENT, LANG_ACHIEVEMENT_EARNED,achievement->ID);
|
MaNGOS::AchievementChatBuilder say_builder(*GetPlayer(), CHAT_MSG_ACHIEVEMENT, LANG_ACHIEVEMENT_EARNED,achievement->ID);
|
||||||
MaNGOS::LocalizedPacketDo<MaNGOS::AchievementChatBuilder> say_do(say_builder);
|
MaNGOS::LocalizedPacketDo<MaNGOS::AchievementChatBuilder> say_do(say_builder);
|
||||||
MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::AchievementChatBuilder> > say_worker(GetPlayer(),sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_SAY),say_do);
|
MaNGOS::CameraDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::AchievementChatBuilder> > say_worker(GetPlayer(),sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_SAY),say_do);
|
||||||
|
|
||||||
Cell::VisitWorldObjects(GetPlayer(), say_worker, sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_SAY));
|
Cell::VisitWorldObjects(GetPlayer(), say_worker, sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_SAY));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
141
src/game/Camera.cpp
Normal file
141
src/game/Camera.cpp
Normal file
|
|
@ -0,0 +1,141 @@
|
||||||
|
#include "Camera.h"
|
||||||
|
#include "GridNotifiersImpl.h"
|
||||||
|
#include "CellImpl.h"
|
||||||
|
#include "Log.h"
|
||||||
|
#include "Errors.h"
|
||||||
|
#include "Player.h"
|
||||||
|
|
||||||
|
Camera::Camera(Player* pl) : m_owner(*pl), m_source(pl)
|
||||||
|
{
|
||||||
|
m_source->GetViewPoint().Attach(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Camera::~Camera()
|
||||||
|
{
|
||||||
|
// view of camera should be already reseted to owner (RemoveFromWorld -> Event_RemovedFromWorld -> ResetView)
|
||||||
|
ASSERT(m_source == &m_owner);
|
||||||
|
|
||||||
|
// for symmetry with constructor and way to make viewpoint's list empty
|
||||||
|
m_source->GetViewPoint().Detach(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::ReceivePacket(WorldPacket *data)
|
||||||
|
{
|
||||||
|
m_owner.SendDirectMessage(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::UpdateForCurrentViewPoint()
|
||||||
|
{
|
||||||
|
m_gridRef.unlink();
|
||||||
|
|
||||||
|
if (GridType* grid = m_source->GetViewPoint().m_grid)
|
||||||
|
grid->AddWorldObject(this);
|
||||||
|
|
||||||
|
m_owner.SetUInt64Value(PLAYER_FARSIGHT, (m_source == &m_owner ? 0 : m_source->GetGUID()));
|
||||||
|
UpdateVisibilityForOwner();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::SetView(WorldObject *obj)
|
||||||
|
{
|
||||||
|
ASSERT(obj);
|
||||||
|
|
||||||
|
if (m_source == obj)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!m_owner.IsInMap(obj))
|
||||||
|
{
|
||||||
|
sLog.outError("Camera::SetView, viewpoint is not in map with camera's owner");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!obj->isType(TYPEMASK_DYNAMICOBJECT | TYPEMASK_UNIT))
|
||||||
|
{
|
||||||
|
sLog.outError("Camera::SetView, viewpoint type is not available for client");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// detach and deregister from active objects if there are no more reasons to be active
|
||||||
|
m_source->GetViewPoint().Detach(this);
|
||||||
|
if (!m_source->isActiveObject())
|
||||||
|
m_source->GetMap()->RemoveFromActive(m_source);
|
||||||
|
|
||||||
|
m_source = obj;
|
||||||
|
|
||||||
|
if (!m_source->isActiveObject())
|
||||||
|
m_source->GetMap()->AddToActive(m_source);
|
||||||
|
|
||||||
|
m_source->GetViewPoint().Attach(this);
|
||||||
|
|
||||||
|
UpdateForCurrentViewPoint();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::Event_ViewPointVisibilityChanged()
|
||||||
|
{
|
||||||
|
if (!m_owner.HaveAtClient(m_source))
|
||||||
|
ResetView();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::ResetView()
|
||||||
|
{
|
||||||
|
SetView(&m_owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::Event_AddedToWorld()
|
||||||
|
{
|
||||||
|
GridType* grid = m_source->GetViewPoint().m_grid;
|
||||||
|
ASSERT(grid);
|
||||||
|
grid->AddWorldObject(this);
|
||||||
|
|
||||||
|
UpdateVisibilityForOwner();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::Event_RemovedFromWorld()
|
||||||
|
{
|
||||||
|
if (m_source == &m_owner)
|
||||||
|
{
|
||||||
|
m_gridRef.unlink();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResetView();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::Event_Moved()
|
||||||
|
{
|
||||||
|
m_gridRef.unlink();
|
||||||
|
m_source->GetViewPoint().m_grid->AddWorldObject(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::UpdateVisibilityOf(WorldObject* target)
|
||||||
|
{
|
||||||
|
m_owner.UpdateVisibilityOf(m_source, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void Camera::UpdateVisibilityOf(T * target, UpdateData &data, std::set<WorldObject*>& vis)
|
||||||
|
{
|
||||||
|
m_owner.template UpdateVisibilityOf<T>(m_source, target,data,vis);
|
||||||
|
}
|
||||||
|
|
||||||
|
template void Camera::UpdateVisibilityOf(Player* , UpdateData& , std::set<WorldObject*>& );
|
||||||
|
template void Camera::UpdateVisibilityOf(Creature* , UpdateData& , std::set<WorldObject*>& );
|
||||||
|
template void Camera::UpdateVisibilityOf(Corpse* , UpdateData& , std::set<WorldObject*>& );
|
||||||
|
template void Camera::UpdateVisibilityOf(GameObject* , UpdateData& , std::set<WorldObject*>& );
|
||||||
|
template void Camera::UpdateVisibilityOf(DynamicObject* , UpdateData& , std::set<WorldObject*>& );
|
||||||
|
|
||||||
|
void Camera::UpdateVisibilityForOwner()
|
||||||
|
{
|
||||||
|
MaNGOS::VisibleNotifier notifier(*this);
|
||||||
|
Cell::VisitAllObjects(m_source, notifier, m_source->GetMap()->GetVisibilityDistance(), false);
|
||||||
|
notifier.Notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////
|
||||||
|
|
||||||
|
ViewPoint::~ViewPoint()
|
||||||
|
{
|
||||||
|
if (!m_cameras.empty())
|
||||||
|
{
|
||||||
|
sLog.outError("ViewPoint destructor called, but some cameras referenced to it");
|
||||||
|
}
|
||||||
|
}
|
||||||
132
src/game/Camera.h
Normal file
132
src/game/Camera.h
Normal file
|
|
@ -0,0 +1,132 @@
|
||||||
|
|
||||||
|
#ifndef MANGOSSERVER_CAMERA_H
|
||||||
|
#define MANGOSSERVER_CAMERA_H
|
||||||
|
|
||||||
|
#include "GridDefines.h"
|
||||||
|
|
||||||
|
class ViewPoint;
|
||||||
|
class WorldObject;
|
||||||
|
class UpdateData;
|
||||||
|
class WorldPacket;
|
||||||
|
class Player;
|
||||||
|
|
||||||
|
/// Camera - object-receiver. Receives broadcast packets from nearby worldobjects, object visibility changes and sends them to client
|
||||||
|
class MANGOS_DLL_SPEC Camera
|
||||||
|
{
|
||||||
|
friend class ViewPoint;
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit Camera(Player* pl);
|
||||||
|
~Camera();
|
||||||
|
|
||||||
|
WorldObject* GetBody() { return m_source;}
|
||||||
|
Player* GetOwner() { return &m_owner;}
|
||||||
|
|
||||||
|
// set camera's view to any worldobject
|
||||||
|
// Note: this worldobject must be in same map, in same phase with camera's owner(player)
|
||||||
|
// client supports only unit and dynamic objects as farsight objects
|
||||||
|
void SetView(WorldObject *obj);
|
||||||
|
|
||||||
|
// set view to camera's owner
|
||||||
|
void ResetView();
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void UpdateVisibilityOf(T * obj, UpdateData &d, std::set<WorldObject*>& vis);
|
||||||
|
void UpdateVisibilityOf(WorldObject* obj);
|
||||||
|
|
||||||
|
void ReceivePacket(WorldPacket *data);
|
||||||
|
|
||||||
|
// updates visibility of worldobjects around viewpoint for camera's owner
|
||||||
|
void UpdateVisibilityForOwner();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// called when viewpoint changes visibility state
|
||||||
|
void Event_AddedToWorld();
|
||||||
|
void Event_RemovedFromWorld();
|
||||||
|
void Event_Moved();
|
||||||
|
void Event_ViewPointVisibilityChanged();
|
||||||
|
|
||||||
|
Player& m_owner;
|
||||||
|
WorldObject* m_source;
|
||||||
|
|
||||||
|
void UpdateForCurrentViewPoint();
|
||||||
|
|
||||||
|
public:
|
||||||
|
GridReference<Camera>& GetGridRef() { return m_gridRef; }
|
||||||
|
bool isActiveObject() const { return false; }
|
||||||
|
private:
|
||||||
|
GridReference<Camera> m_gridRef;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Object-observer, notifies farsight object state to cameras that attached to it
|
||||||
|
class MANGOS_DLL_SPEC ViewPoint
|
||||||
|
{
|
||||||
|
friend class Camera;
|
||||||
|
|
||||||
|
std::list<Camera*> m_cameras;
|
||||||
|
std::list<Camera*>::iterator m_camera_iter;
|
||||||
|
GridType * m_grid;
|
||||||
|
|
||||||
|
void Attach(Camera* c) { m_cameras.push_back(c); }
|
||||||
|
|
||||||
|
void Detach(Camera* c)
|
||||||
|
{
|
||||||
|
if (m_camera_iter != m_cameras.end() && *m_camera_iter == c) // detach called during the loop
|
||||||
|
m_camera_iter = m_cameras.erase(m_camera_iter);
|
||||||
|
else
|
||||||
|
m_cameras.remove(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraCall(void (Camera::*handler)())
|
||||||
|
{
|
||||||
|
if (!m_cameras.empty())
|
||||||
|
{
|
||||||
|
for(m_camera_iter = m_cameras.begin(); m_camera_iter != m_cameras.end(); ++m_camera_iter)
|
||||||
|
{
|
||||||
|
((*m_camera_iter)->*handler)();
|
||||||
|
|
||||||
|
// can be end() after handler
|
||||||
|
if (m_camera_iter == m_cameras.end())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ViewPoint() : m_grid(0), m_camera_iter(m_cameras.end()) {}
|
||||||
|
~ViewPoint();
|
||||||
|
|
||||||
|
bool hasViewers() const { return !m_cameras.empty(); }
|
||||||
|
|
||||||
|
// these events are called when viewpoint changes visibility state
|
||||||
|
void Event_AddedToWorld(GridType *grid)
|
||||||
|
{
|
||||||
|
m_grid = grid;
|
||||||
|
CameraCall(&Camera::Event_AddedToWorld);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Event_RemovedFromWorld()
|
||||||
|
{
|
||||||
|
m_grid = NULL;
|
||||||
|
CameraCall(&Camera::Event_RemovedFromWorld);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Event_GridChanged(GridType *grid)
|
||||||
|
{
|
||||||
|
m_grid = grid;
|
||||||
|
CameraCall(&Camera::Event_Moved);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Event_ViewPointVisibilityChanged()
|
||||||
|
{
|
||||||
|
CameraCall(&Camera::Event_ViewPointVisibilityChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Call_UpdateVisibilityForOwner()
|
||||||
|
{
|
||||||
|
CameraCall(&Camera::UpdateVisibilityForOwner);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -703,6 +703,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder *holder)
|
||||||
|
|
||||||
if (!pCurrChar->GetMap()->Add(pCurrChar))
|
if (!pCurrChar->GetMap()->Add(pCurrChar))
|
||||||
{
|
{
|
||||||
|
// normal delayed teleport protection not applied (and this correct) for this case (Player object just created)
|
||||||
AreaTrigger const* at = sObjectMgr.GetGoBackTrigger(pCurrChar->GetMapId());
|
AreaTrigger const* at = sObjectMgr.GetGoBackTrigger(pCurrChar->GetMapId());
|
||||||
if(at)
|
if(at)
|
||||||
pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation());
|
pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation());
|
||||||
|
|
|
||||||
|
|
@ -216,7 +216,7 @@ ChatCommand * ChatHandler::getCommandTable()
|
||||||
{ "zonexy", SEC_MODERATOR, false, &ChatHandler::HandleGoZoneXYCommand, "", NULL },
|
{ "zonexy", SEC_MODERATOR, false, &ChatHandler::HandleGoZoneXYCommand, "", NULL },
|
||||||
{ "xy", SEC_MODERATOR, false, &ChatHandler::HandleGoXYCommand, "", NULL },
|
{ "xy", SEC_MODERATOR, false, &ChatHandler::HandleGoXYCommand, "", NULL },
|
||||||
{ "xyz", SEC_MODERATOR, false, &ChatHandler::HandleGoXYZCommand, "", NULL },
|
{ "xyz", SEC_MODERATOR, false, &ChatHandler::HandleGoXYZCommand, "", NULL },
|
||||||
{ "", SEC_MODERATOR, false, &ChatHandler::HandleGoXYZCommand, "", NULL },
|
{ "", SEC_MODERATOR, false, &ChatHandler::HandleGoCommand, "", NULL },
|
||||||
{ NULL, 0, false, NULL, "", NULL }
|
{ NULL, 0, false, NULL, "", NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -2057,7 +2057,7 @@ GameTele const* ChatHandler::extractGameTeleFromLink(char* text)
|
||||||
// id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r
|
// id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r
|
||||||
char* cId = extractKeyFromLink(text,"Htele");
|
char* cId = extractKeyFromLink(text,"Htele");
|
||||||
if(!cId)
|
if(!cId)
|
||||||
return false;
|
return NULL;
|
||||||
|
|
||||||
// id case (explicit or from shift link)
|
// id case (explicit or from shift link)
|
||||||
if(cId[0] >= '0' || cId[0] >= '9')
|
if(cId[0] >= '0' || cId[0] >= '9')
|
||||||
|
|
@ -2079,7 +2079,7 @@ static char const* const guidKeys[] =
|
||||||
"Hplayer",
|
"Hplayer",
|
||||||
"Hcreature",
|
"Hcreature",
|
||||||
"Hgameobject",
|
"Hgameobject",
|
||||||
0
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
uint64 ChatHandler::extractGuidFromLink(char* text)
|
uint64 ChatHandler::extractGuidFromLink(char* text)
|
||||||
|
|
@ -2133,6 +2133,130 @@ uint64 ChatHandler::extractGuidFromLink(char* text)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum LocationLinkType
|
||||||
|
{
|
||||||
|
LOCATION_LINK_PLAYER = 0, // must be first for selection in not link case
|
||||||
|
LOCATION_LINK_TELE = 1,
|
||||||
|
LOCATION_LINK_TAXINODE = 2,
|
||||||
|
LOCATION_LINK_CREATURE = 3,
|
||||||
|
LOCATION_LINK_GAMEOBJECT = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
static char const* const locationKeys[] =
|
||||||
|
{
|
||||||
|
"Htele",
|
||||||
|
"Htaxinode",
|
||||||
|
"Hplayer",
|
||||||
|
"Hcreature",
|
||||||
|
"Hgameobject",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
bool ChatHandler::extractLocationFromLink(char* text, uint32& mapid, float& x, float& y, float& z)
|
||||||
|
{
|
||||||
|
int type = 0;
|
||||||
|
|
||||||
|
// |color|Hplayer:name|h[name]|h|r
|
||||||
|
// |color|Htele:id|h[name]|h|r
|
||||||
|
// |color|Htaxinode:id|h[name]|h|r
|
||||||
|
// |color|Hcreature:creature_guid|h[name]|h|r
|
||||||
|
// |color|Hgameobject:go_guid|h[name]|h|r
|
||||||
|
char* idS = extractKeyFromLink(text,locationKeys,&type);
|
||||||
|
if(!idS)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
// it also fail case
|
||||||
|
case LOCATION_LINK_PLAYER:
|
||||||
|
{
|
||||||
|
// not link and not name, possible coordinates/etc
|
||||||
|
if (isNumeric(idS[0]))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::string name = idS;
|
||||||
|
if(!normalizePlayerName(name))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(Player* player = sObjectMgr.GetPlayer(name.c_str()))
|
||||||
|
{
|
||||||
|
mapid = player->GetMapId();
|
||||||
|
x = player->GetPositionX();
|
||||||
|
y = player->GetPositionY();
|
||||||
|
z = player->GetPositionZ();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(uint64 guid = sObjectMgr.GetPlayerGUIDByName(name))
|
||||||
|
{
|
||||||
|
// to point where player stay (if loaded)
|
||||||
|
float o;
|
||||||
|
bool in_flight;
|
||||||
|
return Player::LoadPositionFromDB(mapid, x, y, z, o, in_flight, guid);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
case LOCATION_LINK_TELE:
|
||||||
|
{
|
||||||
|
uint32 id = (uint32)atol(idS);
|
||||||
|
GameTele const* tele = sObjectMgr.GetGameTele(id);
|
||||||
|
if (!tele)
|
||||||
|
return false;
|
||||||
|
mapid = tele->mapId;
|
||||||
|
x = tele->position_x;
|
||||||
|
y = tele->position_y;
|
||||||
|
z = tele->position_z;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case LOCATION_LINK_TAXINODE:
|
||||||
|
{
|
||||||
|
uint32 id = (uint32)atol(idS);
|
||||||
|
TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(id);
|
||||||
|
if (!node)
|
||||||
|
return false;
|
||||||
|
mapid = node->map_id;
|
||||||
|
x = node->x;
|
||||||
|
y = node->y;
|
||||||
|
z = node->z;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case LOCATION_LINK_CREATURE:
|
||||||
|
{
|
||||||
|
uint32 lowguid = (uint32)atol(idS);
|
||||||
|
|
||||||
|
if(CreatureData const* data = sObjectMgr.GetCreatureData(lowguid) )
|
||||||
|
{
|
||||||
|
mapid = data->mapid;
|
||||||
|
x = data->posX;
|
||||||
|
y = data->posY;
|
||||||
|
z = data->posZ;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
case LOCATION_LINK_GAMEOBJECT:
|
||||||
|
{
|
||||||
|
uint32 lowguid = (uint32)atol(idS);
|
||||||
|
|
||||||
|
if(GameObjectData const* data = sObjectMgr.GetGOData(lowguid) )
|
||||||
|
{
|
||||||
|
mapid = data->mapid;
|
||||||
|
x = data->posX;
|
||||||
|
y = data->posY;
|
||||||
|
z = data->posZ;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// unknown type?
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
std::string ChatHandler::extractPlayerNameFromLink(char* text)
|
std::string ChatHandler::extractPlayerNameFromLink(char* text)
|
||||||
{
|
{
|
||||||
// |color|Hplayer:name|h[name]|h|r
|
// |color|Hplayer:name|h[name]|h|r
|
||||||
|
|
@ -2229,7 +2353,7 @@ char* ChatHandler::extractQuotedArg( char* args )
|
||||||
{
|
{
|
||||||
char* space = strtok(args, "\"");
|
char* space = strtok(args, "\"");
|
||||||
if(!space)
|
if(!space)
|
||||||
return false;
|
return NULL;
|
||||||
return strtok(NULL, "\"");
|
return strtok(NULL, "\"");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -535,6 +535,7 @@ class ChatHandler
|
||||||
uint32 extractSpellIdFromLink(char* text);
|
uint32 extractSpellIdFromLink(char* text);
|
||||||
uint64 extractGuidFromLink(char* text);
|
uint64 extractGuidFromLink(char* text);
|
||||||
GameTele const* extractGameTeleFromLink(char* text);
|
GameTele const* extractGameTeleFromLink(char* text);
|
||||||
|
bool extractLocationFromLink(char* text, uint32& mapid, float& x, float& y, float& z);
|
||||||
std::string extractPlayerNameFromLink(char* text);
|
std::string extractPlayerNameFromLink(char* text);
|
||||||
// select by arg (name/link) or in-game selection online/offline player
|
// select by arg (name/link) or in-game selection online/offline player
|
||||||
bool extractPlayerTarget(char* args, Player** player, uint64* player_guid = NULL, std::string* player_name = NULL);
|
bool extractPlayerTarget(char* args, Player** player, uint64* player_guid = NULL, std::string* player_name = NULL);
|
||||||
|
|
@ -558,6 +559,8 @@ class ChatHandler
|
||||||
void HandleCharacterLevel(Player* player, uint64 player_guid, uint32 oldlevel, uint32 newlevel);
|
void HandleCharacterLevel(Player* player, uint64 player_guid, uint32 oldlevel, uint32 newlevel);
|
||||||
void HandleLearnSkillRecipesHelper(Player* player,uint32 skill_id);
|
void HandleLearnSkillRecipesHelper(Player* player,uint32 skill_id);
|
||||||
void ShowSpellListHelper(Player* target, SpellEntry const* spellInfo, LocaleConstant loc);
|
void ShowSpellListHelper(Player* target, SpellEntry const* spellInfo, LocaleConstant loc);
|
||||||
|
bool HandleGoHelper(Player* _player, uint32 mapid, float x, float y, float const* zPtr = NULL);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores informations about a deleted character
|
* Stores informations about a deleted character
|
||||||
|
|
|
||||||
|
|
@ -574,7 +574,7 @@ void WorldSession::HandleTextEmoteOpcode( WorldPacket & recv_data )
|
||||||
|
|
||||||
MaNGOS::EmoteChatBuilder emote_builder(*GetPlayer(), text_emote, emoteNum, unit);
|
MaNGOS::EmoteChatBuilder emote_builder(*GetPlayer(), text_emote, emoteNum, unit);
|
||||||
MaNGOS::LocalizedPacketDo<MaNGOS::EmoteChatBuilder > emote_do(emote_builder);
|
MaNGOS::LocalizedPacketDo<MaNGOS::EmoteChatBuilder > emote_do(emote_builder);
|
||||||
MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::EmoteChatBuilder > > emote_worker(GetPlayer(), sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_TEXTEMOTE), emote_do);
|
MaNGOS::CameraDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::EmoteChatBuilder > > emote_worker(GetPlayer(), sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_TEXTEMOTE), emote_do);
|
||||||
Cell::VisitWorldObjects(GetPlayer(), emote_worker, sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_TEXTEMOTE));
|
Cell::VisitWorldObjects(GetPlayer(), emote_worker, sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_TEXTEMOTE));
|
||||||
|
|
||||||
GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit);
|
GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit);
|
||||||
|
|
|
||||||
|
|
@ -90,8 +90,6 @@ class Corpse : public WorldObject
|
||||||
|
|
||||||
GridReference<Corpse> &GetGridRef() { return m_gridRef; }
|
GridReference<Corpse> &GetGridRef() { return m_gridRef; }
|
||||||
|
|
||||||
bool isActiveObject() const { return false; }
|
|
||||||
|
|
||||||
bool IsExpired(time_t t) const;
|
bool IsExpired(time_t t) const;
|
||||||
private:
|
private:
|
||||||
GridReference<Corpse> m_gridRef;
|
GridReference<Corpse> m_gridRef;
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ m_subtype(subtype), m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m
|
||||||
m_AlreadyCallAssistance(false), m_AlreadySearchedAssistance(false),
|
m_AlreadyCallAssistance(false), m_AlreadySearchedAssistance(false),
|
||||||
m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false), m_needNotify(false),
|
m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false), m_needNotify(false),
|
||||||
m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),
|
m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),
|
||||||
m_creatureInfo(NULL), m_isActiveObject(false), m_splineFlags(SPLINEFLAG_WALKMODE)
|
m_creatureInfo(NULL), m_splineFlags(SPLINEFLAG_WALKMODE)
|
||||||
{
|
{
|
||||||
m_regenTimer = 200;
|
m_regenTimer = 200;
|
||||||
m_valuesCount = UNIT_END;
|
m_valuesCount = UNIT_END;
|
||||||
|
|
@ -248,11 +248,14 @@ bool Creature::InitEntry(uint32 Entry, uint32 team, const CreatureData *data )
|
||||||
SetByteValue(UNIT_FIELD_BYTES_0, 2, minfo->gender);
|
SetByteValue(UNIT_FIELD_BYTES_0, 2, minfo->gender);
|
||||||
|
|
||||||
// Load creature equipment
|
// Load creature equipment
|
||||||
if(!data || data->equipmentId == 0)
|
if (!data || data->equipmentId == 0)
|
||||||
{ // use default from the template
|
{
|
||||||
LoadEquipment(cinfo->equipmentId);
|
if (cinfo->equipmentId == 0)
|
||||||
|
LoadEquipment(normalInfo->equipmentId); // use default from normal template if diff does not have any
|
||||||
|
else
|
||||||
|
LoadEquipment(cinfo->equipmentId); // else use from diff template
|
||||||
}
|
}
|
||||||
else if(data && data->equipmentId != -1)
|
else if (data && data->equipmentId != -1)
|
||||||
{ // override, -1 means no equipment
|
{ // override, -1 means no equipment
|
||||||
LoadEquipment(data->equipmentId);
|
LoadEquipment(data->equipmentId);
|
||||||
}
|
}
|
||||||
|
|
@ -788,29 +791,6 @@ bool Creature::isCanTrainingAndResetTalentsOf(Player* pPlayer) const
|
||||||
&& pPlayer->getClass() == GetCreatureInfo()->trainer_class;
|
&& pPlayer->getClass() == GetCreatureInfo()->trainer_class;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Creature::AI_SendMoveToPacket(float x, float y, float z, uint32 time, SplineFlags flags, SplineType type)
|
|
||||||
{
|
|
||||||
/* uint32 timeElap = getMSTime();
|
|
||||||
if ((timeElap - m_startMove) < m_moveTime)
|
|
||||||
{
|
|
||||||
oX = (dX - oX) * ( (timeElap - m_startMove) / m_moveTime );
|
|
||||||
oY = (dY - oY) * ( (timeElap - m_startMove) / m_moveTime );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
oX = dX;
|
|
||||||
oY = dY;
|
|
||||||
}
|
|
||||||
|
|
||||||
dX = x;
|
|
||||||
dY = y;
|
|
||||||
m_orientation = atan2((oY - dY), (oX - dX));
|
|
||||||
|
|
||||||
m_startMove = getMSTime();
|
|
||||||
m_moveTime = time;*/
|
|
||||||
SendMonsterMove(x, y, z, type, flags, time);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Creature::PrepareBodyLootState()
|
void Creature::PrepareBodyLootState()
|
||||||
{
|
{
|
||||||
loot.clear();
|
loot.clear();
|
||||||
|
|
@ -2218,4 +2198,4 @@ void Creature::RelocationNotify()
|
||||||
MaNGOS::CreatureRelocationNotifier relocationNotifier(*this);
|
MaNGOS::CreatureRelocationNotifier relocationNotifier(*this);
|
||||||
float radius = MAX_CREATURE_ATTACK_RADIUS * sWorld.getConfig(CONFIG_FLOAT_RATE_CREATURE_AGGRO);
|
float radius = MAX_CREATURE_ATTACK_RADIUS * sWorld.getConfig(CONFIG_FLOAT_RATE_CREATURE_AGGRO);
|
||||||
Cell::VisitAllObjects(this, relocationNotifier, radius);
|
Cell::VisitAllObjects(this, relocationNotifier, radius);
|
||||||
}
|
}
|
||||||
|
|
@ -444,7 +444,6 @@ class MANGOS_DLL_SPEC Creature : public Unit
|
||||||
|
|
||||||
bool AIM_Initialize();
|
bool AIM_Initialize();
|
||||||
|
|
||||||
void AI_SendMoveToPacket(float x, float y, float z, uint32 time, SplineFlags MovementFlags, SplineType type);
|
|
||||||
CreatureAI* AI() { return i_AI; }
|
CreatureAI* AI() { return i_AI; }
|
||||||
|
|
||||||
void AddSplineFlag(SplineFlags f)
|
void AddSplineFlag(SplineFlags f)
|
||||||
|
|
@ -627,7 +626,6 @@ class MANGOS_DLL_SPEC Creature : public Unit
|
||||||
|
|
||||||
void SetDeadByDefault (bool death_state) { m_isDeadByDefault = death_state; }
|
void SetDeadByDefault (bool death_state) { m_isDeadByDefault = death_state; }
|
||||||
|
|
||||||
bool isActiveObject() const { return m_isActiveObject || HasAuraType(SPELL_AURA_BIND_SIGHT) || HasAuraType(SPELL_AURA_FAR_SIGHT); }
|
|
||||||
void SetActiveObjectState(bool on);
|
void SetActiveObjectState(bool on);
|
||||||
|
|
||||||
void SetNeedNotify() { m_needNotify = true; }
|
void SetNeedNotify() { m_needNotify = true; }
|
||||||
|
|
@ -692,7 +690,6 @@ class MANGOS_DLL_SPEC Creature : public Unit
|
||||||
private:
|
private:
|
||||||
GridReference<Creature> m_gridRef;
|
GridReference<Creature> m_gridRef;
|
||||||
CreatureInfo const* m_creatureInfo; // in difficulty mode > 0 can different from ObjMgr::GetCreatureTemplate(GetEntry())
|
CreatureInfo const* m_creatureInfo; // in difficulty mode > 0 can different from ObjMgr::GetCreatureTemplate(GetEntry())
|
||||||
bool m_isActiveObject;
|
|
||||||
SplineFlags m_splineFlags;
|
SplineFlags m_splineFlags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ CanCastResult CreatureAI::CanCastSpell(Unit* pTarget, const SpellEntry *pSpell,
|
||||||
if (!isTriggered)
|
if (!isTriggered)
|
||||||
{
|
{
|
||||||
// State does not allow
|
// State does not allow
|
||||||
if (m_creature->hasUnitState(UNIT_STAT_CAN_NOT_REACT))
|
if (m_creature->hasUnitState(UNIT_STAT_CAN_NOT_REACT_OR_LOST_CONTROL))
|
||||||
return CAST_FAIL_STATE;
|
return CAST_FAIL_STATE;
|
||||||
|
|
||||||
if (pSpell->PreventionType == SPELL_PREVENTION_TYPE_SILENCE && m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))
|
if (pSpell->PreventionType == SPELL_PREVENTION_TYPE_SILENCE && m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,8 @@ namespace FactorySelector
|
||||||
{
|
{
|
||||||
MovementGeneratorRegistry &mv_registry(MovementGeneratorRepository::Instance());
|
MovementGeneratorRegistry &mv_registry(MovementGeneratorRepository::Instance());
|
||||||
ASSERT( creature->GetCreatureInfo() != NULL );
|
ASSERT( creature->GetCreatureInfo() != NULL );
|
||||||
const MovementGeneratorCreator *mv_factory = mv_registry.GetRegistryItem( creature->GetDefaultMovementType());
|
MovementGeneratorCreator const * mv_factory = mv_registry.GetRegistryItem(
|
||||||
|
IS_PLAYER_GUID(creature->GetOwnerGUID()) ? FOLLOW_MOTION_TYPE : creature->GetDefaultMovementType());
|
||||||
|
|
||||||
/* if( mv_factory == NULL )
|
/* if( mv_factory == NULL )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1319,7 +1319,7 @@ bool CreatureEventAI::CanCast(Unit* Target, SpellEntry const *Spell, bool Trigge
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//Silenced so we can't cast
|
//Silenced so we can't cast
|
||||||
if (!Triggered && (m_creature->hasUnitState(UNIT_STAT_CAN_NOT_REACT) ||
|
if (!Triggered && (m_creature->hasUnitState(UNIT_STAT_CAN_NOT_REACT_OR_LOST_CONTROL) ||
|
||||||
m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED)))
|
m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,12 @@ DestinationHolder<TRAVELLER>::StartTravel(TRAVELLER &traveller, bool sendMove)
|
||||||
i_totalTravelTime = traveller.GetTotalTrevelTimeTo(i_destX,i_destY,i_destZ);
|
i_totalTravelTime = traveller.GetTotalTrevelTimeTo(i_destX,i_destY,i_destZ);
|
||||||
i_timeElapsed = 0;
|
i_timeElapsed = 0;
|
||||||
if(sendMove)
|
if(sendMove)
|
||||||
traveller.MoveTo(i_destX, i_destY, i_destZ, i_totalTravelTime);
|
{
|
||||||
|
if (i_totalTravelTime)
|
||||||
|
traveller.MoveTo(i_destX, i_destY, i_destZ, i_totalTravelTime);
|
||||||
|
else
|
||||||
|
traveller.Stop();
|
||||||
|
}
|
||||||
return i_totalTravelTime;
|
return i_totalTravelTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
#include "GridNotifiersImpl.h"
|
#include "GridNotifiersImpl.h"
|
||||||
#include "SpellMgr.h"
|
#include "SpellMgr.h"
|
||||||
|
|
||||||
DynamicObject::DynamicObject() : WorldObject(), m_isActiveObject(false)
|
DynamicObject::DynamicObject() : WorldObject()
|
||||||
{
|
{
|
||||||
m_objectType |= TYPEMASK_DYNAMICOBJECT;
|
m_objectType |= TYPEMASK_DYNAMICOBJECT;
|
||||||
m_objectTypeId = TYPEID_DYNAMICOBJECT;
|
m_objectTypeId = TYPEID_DYNAMICOBJECT;
|
||||||
|
|
@ -50,7 +50,10 @@ void DynamicObject::RemoveFromWorld()
|
||||||
{
|
{
|
||||||
///- Remove the dynamicObject from the accessor
|
///- Remove the dynamicObject from the accessor
|
||||||
if(IsInWorld())
|
if(IsInWorld())
|
||||||
|
{
|
||||||
GetMap()->GetObjectsStore().erase<DynamicObject>(GetGUID(), (DynamicObject*)NULL);
|
GetMap()->GetObjectsStore().erase<DynamicObject>(GetGUID(), (DynamicObject*)NULL);
|
||||||
|
GetViewPoint().Event_RemovedFromWorld();
|
||||||
|
}
|
||||||
|
|
||||||
Object::RemoveFromWorld();
|
Object::RemoveFromWorld();
|
||||||
}
|
}
|
||||||
|
|
@ -80,10 +83,6 @@ bool DynamicObject::Create( uint32 guidlow, Unit *caster, uint32 spellId, SpellE
|
||||||
m_effIndex = effIndex;
|
m_effIndex = effIndex;
|
||||||
m_spellId = spellId;
|
m_spellId = spellId;
|
||||||
|
|
||||||
// set to active for far sight case
|
|
||||||
if(SpellEntry const* spellEntry = sSpellStore.LookupEntry(spellId))
|
|
||||||
m_isActiveObject = IsSpellHaveEffect(spellEntry,SPELL_EFFECT_ADD_FARSIGHT);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,6 @@ class DynamicObject : public WorldObject
|
||||||
|
|
||||||
GridReference<DynamicObject> &GetGridRef() { return m_gridRef; }
|
GridReference<DynamicObject> &GetGridRef() { return m_gridRef; }
|
||||||
|
|
||||||
bool isActiveObject() const { return m_isActiveObject; }
|
|
||||||
protected:
|
protected:
|
||||||
uint32 m_spellId;
|
uint32 m_spellId;
|
||||||
SpellEffectIndex m_effIndex;
|
SpellEffectIndex m_effIndex;
|
||||||
|
|
@ -70,6 +69,5 @@ class DynamicObject : public WorldObject
|
||||||
AffectedSet m_affected;
|
AffectedSet m_affected;
|
||||||
private:
|
private:
|
||||||
GridReference<DynamicObject> m_gridRef;
|
GridReference<DynamicObject> m_gridRef;
|
||||||
bool m_isActiveObject;
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -171,6 +171,13 @@ void GameEventMgr::LoadFromDB()
|
||||||
sLog.outString( ">> Loaded %u game events", count );
|
sLog.outString( ">> Loaded %u game events", count );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::map<uint16,int16> pool2event; // for check unique spawn event associated with pool
|
||||||
|
std::map<uint32,int16> creature2event; // for check unique spawn event associated with creature
|
||||||
|
std::map<uint32,int16> go2event; // for check unique spawn event associated with gameobject
|
||||||
|
|
||||||
|
// list only positive event top pools, filled at creature/gameobject loading
|
||||||
|
mGameEventSpawnPoolIds.resize(mGameEvent.size());
|
||||||
|
|
||||||
mGameEventCreatureGuids.resize(mGameEvent.size()*2-1);
|
mGameEventCreatureGuids.resize(mGameEvent.size()*2-1);
|
||||||
// 1 2
|
// 1 2
|
||||||
result = WorldDatabase.Query("SELECT creature.guid, game_event_creature.event "
|
result = WorldDatabase.Query("SELECT creature.guid, game_event_creature.event "
|
||||||
|
|
@ -198,6 +205,12 @@ void GameEventMgr::LoadFromDB()
|
||||||
uint32 guid = fields[0].GetUInt32();
|
uint32 guid = fields[0].GetUInt32();
|
||||||
int16 event_id = fields[1].GetInt16();
|
int16 event_id = fields[1].GetInt16();
|
||||||
|
|
||||||
|
if (event_id == 0)
|
||||||
|
{
|
||||||
|
sLog.outErrorDb("`game_event_creature` game event id (%i) not allowed",event_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
int32 internal_event_id = mGameEvent.size() + event_id - 1;
|
int32 internal_event_id = mGameEvent.size() + event_id - 1;
|
||||||
|
|
||||||
if(internal_event_id < 0 || (size_t)internal_event_id >= mGameEventCreatureGuids.size())
|
if(internal_event_id < 0 || (size_t)internal_event_id >= mGameEventCreatureGuids.size())
|
||||||
|
|
@ -207,6 +220,32 @@ void GameEventMgr::LoadFromDB()
|
||||||
}
|
}
|
||||||
|
|
||||||
++count;
|
++count;
|
||||||
|
|
||||||
|
// spawn objects at event can be grouped in pools and then affected pools have stricter requirements for this case
|
||||||
|
if (event_id > 0)
|
||||||
|
{
|
||||||
|
creature2event[guid] = event_id;
|
||||||
|
|
||||||
|
// not list explicitly creatures from pools in event creature list
|
||||||
|
if (uint16 topPoolId = sPoolMgr.IsPartOfTopPool<Creature>(guid))
|
||||||
|
{
|
||||||
|
int16& eventRef = pool2event[topPoolId];
|
||||||
|
if (eventRef != 0)
|
||||||
|
{
|
||||||
|
if (eventRef != event_id)
|
||||||
|
sLog.outErrorDb("`game_event_creature` have creature (GUID: %u) for event %i from pool or subpool of pool (ID: %u) but pool have already content from event %i. Pool don't must have content for different events!", guid, event_id, topPoolId, eventRef);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
eventRef = event_id;
|
||||||
|
mGameEventSpawnPoolIds[event_id].push_back(topPoolId);
|
||||||
|
sPoolMgr.RemoveAutoSpawnForPool(topPoolId);
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GuidList& crelist = mGameEventCreatureGuids[internal_event_id];
|
GuidList& crelist = mGameEventCreatureGuids[internal_event_id];
|
||||||
crelist.push_back(guid);
|
crelist.push_back(guid);
|
||||||
|
|
||||||
|
|
@ -244,6 +283,12 @@ void GameEventMgr::LoadFromDB()
|
||||||
uint32 guid = fields[0].GetUInt32();
|
uint32 guid = fields[0].GetUInt32();
|
||||||
int16 event_id = fields[1].GetInt16();
|
int16 event_id = fields[1].GetInt16();
|
||||||
|
|
||||||
|
if (event_id == 0)
|
||||||
|
{
|
||||||
|
sLog.outErrorDb("`game_event_gameobject` game event id (%i) not allowed",event_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
int32 internal_event_id = mGameEvent.size() + event_id - 1;
|
int32 internal_event_id = mGameEvent.size() + event_id - 1;
|
||||||
|
|
||||||
if(internal_event_id < 0 || (size_t)internal_event_id >= mGameEventGameobjectGuids.size())
|
if(internal_event_id < 0 || (size_t)internal_event_id >= mGameEventGameobjectGuids.size())
|
||||||
|
|
@ -253,6 +298,32 @@ void GameEventMgr::LoadFromDB()
|
||||||
}
|
}
|
||||||
|
|
||||||
++count;
|
++count;
|
||||||
|
|
||||||
|
// spawn objects at event can be grouped in pools and then affected pools have stricter requirements for this case
|
||||||
|
if (event_id > 0)
|
||||||
|
{
|
||||||
|
go2event[guid] = event_id;
|
||||||
|
|
||||||
|
// not list explicitly gameobjects from pools in event gameobject list
|
||||||
|
if (uint16 topPoolId = sPoolMgr.IsPartOfTopPool<GameObject>(guid))
|
||||||
|
{
|
||||||
|
int16& eventRef = pool2event[topPoolId];
|
||||||
|
if (eventRef != 0)
|
||||||
|
{
|
||||||
|
if (eventRef != event_id)
|
||||||
|
sLog.outErrorDb("`game_event_gameobject` have gameobject (GUID: %u) for event %i from pool or subpool of pool (ID: %u) but pool have already content from event %i. Pool don't must have content for different events!", guid, event_id, topPoolId, eventRef);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
eventRef = event_id;
|
||||||
|
mGameEventSpawnPoolIds[event_id].push_back(topPoolId);
|
||||||
|
sPoolMgr.RemoveAutoSpawnForPool(topPoolId);
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GuidList& golist = mGameEventGameobjectGuids[internal_event_id];
|
GuidList& golist = mGameEventGameobjectGuids[internal_event_id];
|
||||||
golist.push_back(guid);
|
golist.push_back(guid);
|
||||||
|
|
||||||
|
|
@ -263,6 +334,15 @@ void GameEventMgr::LoadFromDB()
|
||||||
sLog.outString( ">> Loaded %u gameobjects in game events", count );
|
sLog.outString( ">> Loaded %u gameobjects in game events", count );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// now recheck that all eventPools linked with events after our skip pools with parents
|
||||||
|
for(std::map<uint16,int16>::const_iterator itr = pool2event.begin(); itr != pool2event.end(); ++itr)
|
||||||
|
{
|
||||||
|
uint16 pool_id = itr->first;
|
||||||
|
int16 event_id = itr->second;
|
||||||
|
|
||||||
|
sPoolMgr.CheckEventLinkAndReport(pool_id, event_id, creature2event, go2event);
|
||||||
|
}
|
||||||
|
|
||||||
mGameEventModelEquip.resize(mGameEvent.size());
|
mGameEventModelEquip.resize(mGameEvent.size());
|
||||||
// 0 1 2
|
// 0 1 2
|
||||||
result = WorldDatabase.Query("SELECT creature.guid, game_event_model_equip.event, game_event_model_equip.modelid,"
|
result = WorldDatabase.Query("SELECT creature.guid, game_event_model_equip.event, game_event_model_equip.modelid,"
|
||||||
|
|
@ -365,57 +445,6 @@ void GameEventMgr::LoadFromDB()
|
||||||
sLog.outString();
|
sLog.outString();
|
||||||
sLog.outString( ">> Loaded %u quests additions in game events", count );
|
sLog.outString( ">> Loaded %u quests additions in game events", count );
|
||||||
}
|
}
|
||||||
|
|
||||||
mGameEventPoolIds.resize(mGameEvent.size()*2-1);
|
|
||||||
// 1 2
|
|
||||||
result = WorldDatabase.Query("SELECT pool_template.entry, game_event_pool.event "
|
|
||||||
"FROM pool_template JOIN game_event_pool ON pool_template.entry = game_event_pool.pool_entry");
|
|
||||||
|
|
||||||
count = 0;
|
|
||||||
if( !result )
|
|
||||||
{
|
|
||||||
barGoLink bar2(1);
|
|
||||||
bar2.step();
|
|
||||||
|
|
||||||
sLog.outString();
|
|
||||||
sLog.outString(">> Loaded %u pools in game events", count );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
barGoLink bar2( (int)result->GetRowCount() );
|
|
||||||
do
|
|
||||||
{
|
|
||||||
Field *fields = result->Fetch();
|
|
||||||
|
|
||||||
bar2.step();
|
|
||||||
|
|
||||||
uint32 entry = fields[0].GetUInt16();
|
|
||||||
int16 event_id = fields[1].GetInt16();
|
|
||||||
|
|
||||||
int32 internal_event_id = mGameEvent.size() + event_id - 1;
|
|
||||||
|
|
||||||
if (internal_event_id < 0 || (size_t)internal_event_id >= mGameEventPoolIds.size())
|
|
||||||
{
|
|
||||||
sLog.outErrorDb("`game_event_pool` game event id (%i) is out of range compared to max event id in `game_event`",event_id);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sPoolMgr.CheckPool(entry))
|
|
||||||
{
|
|
||||||
sLog.outErrorDb("Pool Id (%u) has all creatures or gameobjects with explicit chance sum <>100 and no equal chance defined. The pool system cannot pick one to spawn.", entry);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
++count;
|
|
||||||
IdList& poollist = mGameEventPoolIds[internal_event_id];
|
|
||||||
poollist.push_back(entry);
|
|
||||||
|
|
||||||
} while( result->NextRow() );
|
|
||||||
sLog.outString();
|
|
||||||
sLog.outString( ">> Loaded %u pools in game events", count );
|
|
||||||
delete result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 GameEventMgr::Initialize() // return the next event delay in ms
|
uint32 GameEventMgr::Initialize() // return the next event delay in ms
|
||||||
|
|
@ -516,6 +545,18 @@ void GameEventMgr::GameEventSpawn(int16 event_id)
|
||||||
CreatureData const* data = sObjectMgr.GetCreatureData(*itr);
|
CreatureData const* data = sObjectMgr.GetCreatureData(*itr);
|
||||||
if (data)
|
if (data)
|
||||||
{
|
{
|
||||||
|
// negative event id for pool element meaning allow be used in next pool spawn
|
||||||
|
if (event_id < 0)
|
||||||
|
{
|
||||||
|
if (uint16 pool_id = sPoolMgr.IsPartOfAPool<Creature>(*itr))
|
||||||
|
{
|
||||||
|
// will have chance at next pool update
|
||||||
|
sPoolMgr.SetExcludeObject<Creature>(pool_id, *itr, false);
|
||||||
|
sPoolMgr.UpdatePool<Creature>(pool_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sObjectMgr.AddCreatureToGrid(*itr, data);
|
sObjectMgr.AddCreatureToGrid(*itr, data);
|
||||||
|
|
||||||
// Spawn if necessary (loaded grids only)
|
// Spawn if necessary (loaded grids only)
|
||||||
|
|
@ -549,7 +590,20 @@ void GameEventMgr::GameEventSpawn(int16 event_id)
|
||||||
GameObjectData const* data = sObjectMgr.GetGOData(*itr);
|
GameObjectData const* data = sObjectMgr.GetGOData(*itr);
|
||||||
if (data)
|
if (data)
|
||||||
{
|
{
|
||||||
|
// negative event id for pool element meaning allow be used in next pool spawn
|
||||||
|
if (event_id < 0)
|
||||||
|
{
|
||||||
|
if (uint16 pool_id = sPoolMgr.IsPartOfAPool<GameObject>(*itr))
|
||||||
|
{
|
||||||
|
// will have chance at next pool update
|
||||||
|
sPoolMgr.SetExcludeObject<GameObject>(pool_id, *itr, false);
|
||||||
|
sPoolMgr.UpdatePool<GameObject>(pool_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sObjectMgr.AddGameobjectToGrid(*itr, data);
|
sObjectMgr.AddGameobjectToGrid(*itr, data);
|
||||||
|
|
||||||
// Spawn if necessary (loaded grids only)
|
// Spawn if necessary (loaded grids only)
|
||||||
// this base map checked as non-instanced and then only existed
|
// this base map checked as non-instanced and then only existed
|
||||||
Map* map = const_cast<Map*>(sMapMgr.CreateBaseMap(data->mapid));
|
Map* map = const_cast<Map*>(sMapMgr.CreateBaseMap(data->mapid));
|
||||||
|
|
@ -571,14 +625,17 @@ void GameEventMgr::GameEventSpawn(int16 event_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (internal_event_id < 0 || (size_t)internal_event_id >= mGameEventPoolIds.size())
|
if (event_id > 0)
|
||||||
{
|
{
|
||||||
sLog.outError("GameEventMgr::GameEventSpawn attempt access to out of range mGameEventPoolIds element %i (size: " SIZEFMTD ")",internal_event_id,mGameEventPoolIds.size());
|
if((size_t)event_id >= mGameEventSpawnPoolIds.size())
|
||||||
return;
|
{
|
||||||
}
|
sLog.outError("GameEventMgr::GameEventSpawn attempt access to out of range mGameEventSpawnPoolIds element %i (size: " SIZEFMTD ")", event_id, mGameEventSpawnPoolIds.size());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (IdList::iterator itr = mGameEventPoolIds[internal_event_id].begin();itr != mGameEventPoolIds[internal_event_id].end();++itr)
|
for (IdList::iterator itr = mGameEventSpawnPoolIds[event_id].begin();itr != mGameEventSpawnPoolIds[event_id].end();++itr)
|
||||||
sPoolMgr.SpawnPool(*itr, true);
|
sPoolMgr.SpawnPool(*itr, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameEventMgr::GameEventUnspawn(int16 event_id)
|
void GameEventMgr::GameEventUnspawn(int16 event_id)
|
||||||
|
|
@ -596,6 +653,17 @@ void GameEventMgr::GameEventUnspawn(int16 event_id)
|
||||||
// Remove the creature from grid
|
// Remove the creature from grid
|
||||||
if( CreatureData const* data = sObjectMgr.GetCreatureData(*itr) )
|
if( CreatureData const* data = sObjectMgr.GetCreatureData(*itr) )
|
||||||
{
|
{
|
||||||
|
// negative event id for pool element meaning unspawn in pool and exclude for next spawns
|
||||||
|
if (event_id < 0)
|
||||||
|
{
|
||||||
|
if (uint16 poolid = sPoolMgr.IsPartOfAPool<Creature>(*itr))
|
||||||
|
{
|
||||||
|
sPoolMgr.SetExcludeObject<Creature>(poolid, *itr, true);
|
||||||
|
sPoolMgr.UpdatePool<Creature>(poolid, *itr);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sObjectMgr.RemoveCreatureFromGrid(*itr, data);
|
sObjectMgr.RemoveCreatureFromGrid(*itr, data);
|
||||||
|
|
||||||
if (Creature* pCreature = ObjectAccessor::GetCreatureInWorld(ObjectGuid(HIGHGUID_UNIT, data->id, *itr)))
|
if (Creature* pCreature = ObjectAccessor::GetCreatureInWorld(ObjectGuid(HIGHGUID_UNIT, data->id, *itr)))
|
||||||
|
|
@ -614,21 +682,36 @@ void GameEventMgr::GameEventUnspawn(int16 event_id)
|
||||||
// Remove the gameobject from grid
|
// Remove the gameobject from grid
|
||||||
if(GameObjectData const* data = sObjectMgr.GetGOData(*itr))
|
if(GameObjectData const* data = sObjectMgr.GetGOData(*itr))
|
||||||
{
|
{
|
||||||
|
// negative event id for pool element meaning unspawn in pool and exclude for next spawns
|
||||||
|
if (event_id < 0)
|
||||||
|
{
|
||||||
|
if (uint16 poolid = sPoolMgr.IsPartOfAPool<GameObject>(*itr))
|
||||||
|
{
|
||||||
|
sPoolMgr.SetExcludeObject<GameObject>(poolid, *itr, true);
|
||||||
|
sPoolMgr.UpdatePool<GameObject>(poolid, *itr);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sObjectMgr.RemoveGameobjectFromGrid(*itr, data);
|
sObjectMgr.RemoveGameobjectFromGrid(*itr, data);
|
||||||
|
|
||||||
if( GameObject* pGameobject = ObjectAccessor::GetGameObjectInWorld(ObjectGuid(HIGHGUID_GAMEOBJECT, data->id, *itr)) )
|
if( GameObject* pGameobject = ObjectAccessor::GetGameObjectInWorld(ObjectGuid(HIGHGUID_GAMEOBJECT, data->id, *itr)) )
|
||||||
pGameobject->AddObjectToRemoveList();
|
pGameobject->AddObjectToRemoveList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (internal_event_id < 0 || (size_t)internal_event_id >= mGameEventPoolIds.size())
|
|
||||||
{
|
|
||||||
sLog.outError("GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventPoolIds element %i (size: " SIZEFMTD ")",internal_event_id,mGameEventPoolIds.size());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (IdList::iterator itr = mGameEventPoolIds[internal_event_id].begin();itr != mGameEventPoolIds[internal_event_id].end();++itr)
|
if (event_id > 0)
|
||||||
{
|
{
|
||||||
sPoolMgr.DespawnPool(*itr);
|
if ((size_t)event_id >= mGameEventSpawnPoolIds.size())
|
||||||
|
{
|
||||||
|
sLog.outError("GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventSpawnPoolIds element %i (size: " SIZEFMTD ")", event_id, mGameEventSpawnPoolIds.size());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (IdList::iterator itr = mGameEventSpawnPoolIds[event_id].begin();itr != mGameEventSpawnPoolIds[event_id].end();++itr)
|
||||||
|
{
|
||||||
|
sPoolMgr.DespawnPool(*itr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -88,11 +88,11 @@ class GameEventMgr
|
||||||
typedef std::pair<uint32, uint32> QuestRelation;
|
typedef std::pair<uint32, uint32> QuestRelation;
|
||||||
typedef std::list<QuestRelation> QuestRelList;
|
typedef std::list<QuestRelation> QuestRelList;
|
||||||
typedef std::vector<QuestRelList> GameEventQuestMap;
|
typedef std::vector<QuestRelList> GameEventQuestMap;
|
||||||
GameEventQuestMap mGameEventQuests;
|
GameEventQuestMap mGameEventQuests; // events*2-1
|
||||||
GameEventModelEquipMap mGameEventModelEquip;
|
GameEventModelEquipMap mGameEventModelEquip; // events*2-1
|
||||||
GameEventGuidMap mGameEventCreatureGuids;
|
GameEventGuidMap mGameEventCreatureGuids; // events*2-1
|
||||||
GameEventGuidMap mGameEventGameobjectGuids;
|
GameEventGuidMap mGameEventGameobjectGuids; // events*2-1
|
||||||
GameEventIdMap mGameEventPoolIds;
|
GameEventIdMap mGameEventSpawnPoolIds; // events size, only positive event case
|
||||||
GameEventDataMap mGameEvent;
|
GameEventDataMap mGameEvent;
|
||||||
ActiveEvents m_ActiveEvents;
|
ActiveEvents m_ActiveEvents;
|
||||||
bool m_IsGameEventsInit;
|
bool m_IsGameEventsInit;
|
||||||
|
|
|
||||||
|
|
@ -703,7 +703,6 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
|
||||||
|
|
||||||
GridReference<GameObject> &GetGridRef() { return m_gridRef; }
|
GridReference<GameObject> &GetGridRef() { return m_gridRef; }
|
||||||
|
|
||||||
bool isActiveObject() const { return false; }
|
|
||||||
uint64 GetRotation() const { return m_rotation; }
|
uint64 GetRotation() const { return m_rotation; }
|
||||||
protected:
|
protected:
|
||||||
uint32 m_spellId;
|
uint32 m_spellId;
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ class DynamicObject;
|
||||||
class GameObject;
|
class GameObject;
|
||||||
class Pet;
|
class Pet;
|
||||||
class Player;
|
class Player;
|
||||||
|
class Camera;
|
||||||
|
|
||||||
#define MAX_NUMBER_OF_GRIDS 64
|
#define MAX_NUMBER_OF_GRIDS 64
|
||||||
|
|
||||||
|
|
@ -56,10 +57,12 @@ class Player;
|
||||||
#define MAP_HALFSIZE (MAP_SIZE/2)
|
#define MAP_HALFSIZE (MAP_SIZE/2)
|
||||||
|
|
||||||
// Creature used instead pet to simplify *::Visit templates (not required duplicate code for Creature->Pet case)
|
// Creature used instead pet to simplify *::Visit templates (not required duplicate code for Creature->Pet case)
|
||||||
typedef TYPELIST_3(Player, Creature/*pets*/, Corpse/*resurrectable*/) AllWorldObjectTypes;
|
// Cameras in world list just because linked with Player objects
|
||||||
|
typedef TYPELIST_4(Player, Creature/*pets*/, Corpse/*resurrectable*/, Camera) AllWorldObjectTypes;
|
||||||
typedef TYPELIST_4(GameObject, Creature/*except pets*/, DynamicObject, Corpse/*Bones*/) AllGridObjectTypes;
|
typedef TYPELIST_4(GameObject, Creature/*except pets*/, DynamicObject, Corpse/*Bones*/) AllGridObjectTypes;
|
||||||
typedef TYPELIST_5(Creature, Pet, Vehicle, GameObject, DynamicObject) AllMapStoredObjectTypes;
|
typedef TYPELIST_5(Creature, Pet, Vehicle, GameObject, DynamicObject) AllMapStoredObjectTypes;
|
||||||
|
|
||||||
|
typedef GridRefManager<Camera> CameraMapType;
|
||||||
typedef GridRefManager<Corpse> CorpseMapType;
|
typedef GridRefManager<Corpse> CorpseMapType;
|
||||||
typedef GridRefManager<Creature> CreatureMapType;
|
typedef GridRefManager<Creature> CreatureMapType;
|
||||||
typedef GridRefManager<DynamicObject> DynamicObjectMapType;
|
typedef GridRefManager<DynamicObject> DynamicObjectMapType;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@
|
||||||
#include "GridStates.h"
|
#include "GridStates.h"
|
||||||
#include "CellImpl.h"
|
#include "CellImpl.h"
|
||||||
#include "Map.h"
|
#include "Map.h"
|
||||||
#include "Config/ConfigEnv.h"
|
|
||||||
#include "DBCEnums.h"
|
#include "DBCEnums.h"
|
||||||
#include "DBCStores.h"
|
#include "DBCStores.h"
|
||||||
#include "GridMap.h"
|
#include "GridMap.h"
|
||||||
|
|
|
||||||
|
|
@ -28,32 +28,29 @@
|
||||||
using namespace MaNGOS;
|
using namespace MaNGOS;
|
||||||
|
|
||||||
void
|
void
|
||||||
VisibleChangesNotifier::Visit(PlayerMapType &m)
|
VisibleChangesNotifier::Visit(CameraMapType &m)
|
||||||
{
|
{
|
||||||
for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
|
for(CameraMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
|
||||||
{
|
{
|
||||||
Player* player = iter->getSource();
|
iter->getSource()->UpdateVisibilityOf(&i_object);
|
||||||
if(player == &i_object)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
player->UpdateVisibilityOf(player->GetViewPoint(),&i_object);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
VisibleNotifier::Notify()
|
VisibleNotifier::Notify()
|
||||||
{
|
{
|
||||||
|
Player& player = *i_camera.GetOwner();
|
||||||
// at this moment i_clientGUIDs have guids that not iterate at grid level checks
|
// at this moment i_clientGUIDs have guids that not iterate at grid level checks
|
||||||
// but exist one case when this possible and object not out of range: transports
|
// but exist one case when this possible and object not out of range: transports
|
||||||
if(Transport* transport = i_player.GetTransport())
|
if(Transport* transport = player.GetTransport())
|
||||||
{
|
{
|
||||||
for(Transport::PlayerSet::const_iterator itr = transport->GetPassengers().begin();itr!=transport->GetPassengers().end();++itr)
|
for(Transport::PlayerSet::const_iterator itr = transport->GetPassengers().begin();itr!=transport->GetPassengers().end();++itr)
|
||||||
{
|
{
|
||||||
if(i_clientGUIDs.find((*itr)->GetGUID())!=i_clientGUIDs.end())
|
if (i_clientGUIDs.find((*itr)->GetGUID()) != i_clientGUIDs.end())
|
||||||
{
|
{
|
||||||
// ignore far sight case
|
// ignore far sight case
|
||||||
(*itr)->UpdateVisibilityOf((*itr),&i_player);
|
(*itr)->UpdateVisibilityOf(*itr, &player);
|
||||||
i_player.UpdateVisibilityOf(&i_player,(*itr),i_data,i_visibleNow);
|
player.UpdateVisibilityOf(&player, *itr, i_data, i_visibleNow);
|
||||||
i_clientGUIDs.erase((*itr)->GetGUID());
|
i_clientGUIDs.erase((*itr)->GetGUID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -63,27 +60,28 @@ VisibleNotifier::Notify()
|
||||||
i_data.AddOutOfRangeGUID(i_clientGUIDs);
|
i_data.AddOutOfRangeGUID(i_clientGUIDs);
|
||||||
for(ObjectGuidSet::iterator itr = i_clientGUIDs.begin();itr!=i_clientGUIDs.end();++itr)
|
for(ObjectGuidSet::iterator itr = i_clientGUIDs.begin();itr!=i_clientGUIDs.end();++itr)
|
||||||
{
|
{
|
||||||
i_player.m_clientGUIDs.erase(*itr);
|
player.m_clientGUIDs.erase(*itr);
|
||||||
|
|
||||||
DEBUG_FILTER_LOG(LOG_FILTER_VISIBILITY_CHANGES, "%s is out of range (no in active cells set) now for player %u",itr->GetString().c_str(),i_player.GetGUIDLow());
|
DEBUG_FILTER_LOG(LOG_FILTER_VISIBILITY_CHANGES, "%s is out of range (no in active cells set) now for %s",
|
||||||
|
itr->GetString().c_str(), player.GetObjectGuid().GetString().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if( i_data.HasData() )
|
if (i_data.HasData())
|
||||||
{
|
{
|
||||||
// send create/outofrange packet to player (except player create updates that already sent using SendUpdateToPlayer)
|
// send create/outofrange packet to player (except player create updates that already sent using SendUpdateToPlayer)
|
||||||
WorldPacket packet;
|
WorldPacket packet;
|
||||||
i_data.BuildPacket(&packet);
|
i_data.BuildPacket(&packet);
|
||||||
i_player.GetSession()->SendPacket(&packet);
|
player.GetSession()->SendPacket(&packet);
|
||||||
|
|
||||||
// send out of range to other players if need
|
// send out of range to other players if need
|
||||||
ObjectGuidSet const& oor = i_data.GetOutOfRangeGUIDs();
|
ObjectGuidSet const& oor = i_data.GetOutOfRangeGUIDs();
|
||||||
for(ObjectGuidSet::const_iterator iter = oor.begin(); iter != oor.end(); ++iter)
|
for(ObjectGuidSet::const_iterator iter = oor.begin(); iter != oor.end(); ++iter)
|
||||||
{
|
{
|
||||||
if(!iter->IsPlayer())
|
if (!iter->IsPlayer())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (Player* plr = ObjectAccessor::FindPlayer(*iter))
|
if (Player* plr = ObjectAccessor::FindPlayer(*iter))
|
||||||
plr->UpdateVisibilityOf(plr->GetViewPoint(),&i_player);
|
plr->UpdateVisibilityOf(plr->GetCamera().GetBody(), &player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -93,87 +91,92 @@ VisibleNotifier::Notify()
|
||||||
for(std::set<WorldObject*>::const_iterator vItr = i_visibleNow.begin(); vItr != i_visibleNow.end(); ++vItr)
|
for(std::set<WorldObject*>::const_iterator vItr = i_visibleNow.begin(); vItr != i_visibleNow.end(); ++vItr)
|
||||||
{
|
{
|
||||||
// target aura duration for caster show only if target exist at caster client
|
// target aura duration for caster show only if target exist at caster client
|
||||||
if((*vItr)!=&i_player && (*vItr)->isType(TYPEMASK_UNIT))
|
if ((*vItr) != &player && (*vItr)->isType(TYPEMASK_UNIT))
|
||||||
i_player.SendAurasForTarget((Unit*)(*vItr));
|
player.SendAurasForTarget((Unit*)(*vItr));
|
||||||
|
|
||||||
// non finished movements show to player
|
// non finished movements show to player
|
||||||
if((*vItr)->GetTypeId()==TYPEID_UNIT && ((Creature*)(*vItr))->isAlive())
|
if ((*vItr)->GetTypeId()==TYPEID_UNIT && ((Creature*)(*vItr))->isAlive())
|
||||||
((Creature*)(*vItr))->SendMonsterMoveWithSpeedToCurrentDestination(&i_player);
|
((Creature*)(*vItr))->SendMonsterMoveWithSpeedToCurrentDestination(&player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MessageDeliverer::Visit(PlayerMapType &m)
|
MessageDeliverer::Visit(CameraMapType &m)
|
||||||
{
|
{
|
||||||
for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
|
for(CameraMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||||
{
|
{
|
||||||
if (i_toSelf || iter->getSource() != &i_player)
|
Player* owner = iter->getSource()->GetOwner();
|
||||||
|
|
||||||
|
if (i_toSelf || owner != &i_player)
|
||||||
{
|
{
|
||||||
if (!i_player.InSamePhase(iter->getSource()))
|
if (!i_player.InSamePhase(iter->getSource()->GetBody()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(WorldSession* session = iter->getSource()->GetSession())
|
if (WorldSession* session = owner->GetSession())
|
||||||
session->SendPacket(i_message);
|
session->SendPacket(i_message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageDelivererExcept::Visit(PlayerMapType &m)
|
void MessageDelivererExcept::Visit(CameraMapType &m)
|
||||||
{
|
{
|
||||||
for(PlayerMapType::iterator it = m.begin(); it!= m.end(); ++it)
|
for(CameraMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||||
{
|
{
|
||||||
Player* player = it->getSource();
|
Player* owner = iter->getSource()->GetOwner();
|
||||||
if(!player->InSamePhase(i_phaseMask) || player == i_skipped_receiver)
|
|
||||||
|
if (!owner->InSamePhase(i_phaseMask) || owner == i_skipped_receiver)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (WorldSession* session = player->GetSession())
|
if (WorldSession* session = owner->GetSession())
|
||||||
session->SendPacket(i_message);
|
session->SendPacket(i_message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ObjectMessageDeliverer::Visit(PlayerMapType &m)
|
ObjectMessageDeliverer::Visit(CameraMapType &m)
|
||||||
{
|
{
|
||||||
for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
|
for(CameraMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||||
{
|
{
|
||||||
if(!iter->getSource()->InSamePhase(i_phaseMask))
|
if(!iter->getSource()->GetBody()->InSamePhase(i_phaseMask))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(WorldSession* session = iter->getSource()->GetSession())
|
if(WorldSession* session = iter->getSource()->GetOwner()->GetSession())
|
||||||
session->SendPacket(i_message);
|
session->SendPacket(i_message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MessageDistDeliverer::Visit(PlayerMapType &m)
|
MessageDistDeliverer::Visit(CameraMapType &m)
|
||||||
{
|
{
|
||||||
for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
|
for(CameraMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
|
||||||
{
|
{
|
||||||
if ((i_toSelf || iter->getSource() != &i_player ) &&
|
Player * owner = iter->getSource()->GetOwner();
|
||||||
(!i_ownTeamOnly || iter->getSource()->GetTeam() == i_player.GetTeam() ) &&
|
|
||||||
(!i_dist || iter->getSource()->IsWithinDist(&i_player,i_dist)))
|
if ((i_toSelf || owner != &i_player) &&
|
||||||
|
(!i_ownTeamOnly || owner->GetTeam() == i_player.GetTeam()) &&
|
||||||
|
(!i_dist || iter->getSource()->GetBody()->IsWithinDist(&i_player,i_dist)))
|
||||||
{
|
{
|
||||||
if (!i_player.InSamePhase(iter->getSource()))
|
if (!i_player.InSamePhase(iter->getSource()->GetBody()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (WorldSession* session = iter->getSource()->GetSession())
|
if (WorldSession* session = owner->GetSession())
|
||||||
session->SendPacket(i_message);
|
session->SendPacket(i_message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ObjectMessageDistDeliverer::Visit(PlayerMapType &m)
|
ObjectMessageDistDeliverer::Visit(CameraMapType &m)
|
||||||
{
|
{
|
||||||
for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
|
for(CameraMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
|
||||||
{
|
{
|
||||||
if (!i_dist || iter->getSource()->IsWithinDist(&i_object,i_dist))
|
if (!i_dist || iter->getSource()->GetBody()->IsWithinDist(&i_object,i_dist))
|
||||||
{
|
{
|
||||||
if (!i_object.InSamePhase(iter->getSource()))
|
if (!i_object.InSamePhase(iter->getSource()->GetBody()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (WorldSession* session = iter->getSource()->GetSession())
|
if (WorldSession* session = iter->getSource()->GetOwner()->GetSession())
|
||||||
session->SendPacket(i_message);
|
session->SendPacket(i_message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,13 +38,14 @@ namespace MaNGOS
|
||||||
{
|
{
|
||||||
struct MANGOS_DLL_DECL VisibleNotifier
|
struct MANGOS_DLL_DECL VisibleNotifier
|
||||||
{
|
{
|
||||||
Player &i_player;
|
Camera& i_camera;
|
||||||
UpdateData i_data;
|
UpdateData i_data;
|
||||||
ObjectGuidSet i_clientGUIDs;
|
ObjectGuidSet i_clientGUIDs;
|
||||||
std::set<WorldObject*> i_visibleNow;
|
std::set<WorldObject*> i_visibleNow;
|
||||||
|
|
||||||
explicit VisibleNotifier(Player &player) : i_player(player),i_clientGUIDs(player.m_clientGUIDs) {}
|
explicit VisibleNotifier(Camera &c) : i_camera(c), i_clientGUIDs(c.GetOwner()->m_clientGUIDs) {}
|
||||||
template<class T> void Visit(GridRefManager<T> &m);
|
template<class T> void Visit(GridRefManager<T> &m);
|
||||||
|
void Visit(CameraMapType &m) {}
|
||||||
void Notify(void);
|
void Notify(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -54,7 +55,7 @@ namespace MaNGOS
|
||||||
|
|
||||||
explicit VisibleChangesNotifier(WorldObject &object) : i_object(object) {}
|
explicit VisibleChangesNotifier(WorldObject &object) : i_object(object) {}
|
||||||
template<class T> void Visit(GridRefManager<T> &) {}
|
template<class T> void Visit(GridRefManager<T> &) {}
|
||||||
void Visit(PlayerMapType &);
|
void Visit(CameraMapType &);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MANGOS_DLL_DECL GridUpdater
|
struct MANGOS_DLL_DECL GridUpdater
|
||||||
|
|
@ -82,7 +83,7 @@ namespace MaNGOS
|
||||||
WorldPacket *i_message;
|
WorldPacket *i_message;
|
||||||
bool i_toSelf;
|
bool i_toSelf;
|
||||||
MessageDeliverer(Player &pl, WorldPacket *msg, bool to_self) : i_player(pl), i_message(msg), i_toSelf(to_self) {}
|
MessageDeliverer(Player &pl, WorldPacket *msg, bool to_self) : i_player(pl), i_message(msg), i_toSelf(to_self) {}
|
||||||
void Visit(PlayerMapType &m);
|
void Visit(CameraMapType &m);
|
||||||
template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
|
template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -95,7 +96,7 @@ namespace MaNGOS
|
||||||
MessageDelivererExcept(WorldObject const* obj, WorldPacket *msg, Player const* skipped)
|
MessageDelivererExcept(WorldObject const* obj, WorldPacket *msg, Player const* skipped)
|
||||||
: i_phaseMask(obj->GetPhaseMask()), i_message(msg), i_skipped_receiver(skipped) {}
|
: i_phaseMask(obj->GetPhaseMask()), i_message(msg), i_skipped_receiver(skipped) {}
|
||||||
|
|
||||||
void Visit(PlayerMapType &m);
|
void Visit(CameraMapType &m);
|
||||||
template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
|
template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -105,7 +106,7 @@ namespace MaNGOS
|
||||||
WorldPacket *i_message;
|
WorldPacket *i_message;
|
||||||
explicit ObjectMessageDeliverer(WorldObject& obj, WorldPacket *msg)
|
explicit ObjectMessageDeliverer(WorldObject& obj, WorldPacket *msg)
|
||||||
: i_phaseMask(obj.GetPhaseMask()), i_message(msg) {}
|
: i_phaseMask(obj.GetPhaseMask()), i_message(msg) {}
|
||||||
void Visit(PlayerMapType &m);
|
void Visit(CameraMapType &m);
|
||||||
template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
|
template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -119,7 +120,7 @@ namespace MaNGOS
|
||||||
|
|
||||||
MessageDistDeliverer(Player &pl, WorldPacket *msg, float dist, bool to_self, bool ownTeamOnly)
|
MessageDistDeliverer(Player &pl, WorldPacket *msg, float dist, bool to_self, bool ownTeamOnly)
|
||||||
: i_player(pl), i_message(msg), i_toSelf(to_self), i_ownTeamOnly(ownTeamOnly), i_dist(dist) {}
|
: i_player(pl), i_message(msg), i_toSelf(to_self), i_ownTeamOnly(ownTeamOnly), i_dist(dist) {}
|
||||||
void Visit(PlayerMapType &m);
|
void Visit(CameraMapType &m);
|
||||||
template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
|
template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -129,7 +130,7 @@ namespace MaNGOS
|
||||||
WorldPacket *i_message;
|
WorldPacket *i_message;
|
||||||
float i_dist;
|
float i_dist;
|
||||||
ObjectMessageDistDeliverer(WorldObject &obj, WorldPacket *msg, float dist) : i_object(obj), i_message(msg), i_dist(dist) {}
|
ObjectMessageDistDeliverer(WorldObject &obj, WorldPacket *msg, float dist) : i_object(obj), i_message(msg), i_dist(dist) {}
|
||||||
void Visit(PlayerMapType &m);
|
void Visit(CameraMapType &m);
|
||||||
template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
|
template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -140,6 +141,7 @@ namespace MaNGOS
|
||||||
template<class T> void Visit(GridRefManager<T> &m);
|
template<class T> void Visit(GridRefManager<T> &m);
|
||||||
void Visit(PlayerMapType &) {}
|
void Visit(PlayerMapType &) {}
|
||||||
void Visit(CorpseMapType &) {}
|
void Visit(CorpseMapType &) {}
|
||||||
|
void Visit(CameraMapType &) {}
|
||||||
void Visit(CreatureMapType &);
|
void Visit(CreatureMapType &);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -476,22 +478,21 @@ namespace MaNGOS
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class Do>
|
template<class Do>
|
||||||
struct MANGOS_DLL_DECL PlayerDistWorker
|
struct MANGOS_DLL_DECL CameraDistWorker
|
||||||
{
|
{
|
||||||
WorldObject const* i_searcher;
|
WorldObject const* i_searcher;
|
||||||
float i_dist;
|
float i_dist;
|
||||||
Do& i_do;
|
Do& i_do;
|
||||||
|
|
||||||
PlayerDistWorker(WorldObject const* searcher, float _dist, Do& _do)
|
CameraDistWorker(WorldObject const* searcher, float _dist, Do& _do)
|
||||||
: i_searcher(searcher), i_dist(_dist), i_do(_do) {}
|
: i_searcher(searcher), i_dist(_dist), i_do(_do) {}
|
||||||
|
|
||||||
void Visit(PlayerMapType &m)
|
void Visit(CameraMapType &m)
|
||||||
{
|
{
|
||||||
for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
for(CameraMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||||
if (itr->getSource()->InSamePhase(i_searcher) && itr->getSource()->IsWithinDist(i_searcher,i_dist))
|
if (itr->getSource()->GetBody()->InSamePhase(i_searcher) && itr->getSource()->GetBody()->IsWithinDist(i_searcher,i_dist))
|
||||||
i_do(itr->getSource());
|
i_do(itr->getSource()->GetOwner());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
|
template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,11 +31,9 @@
|
||||||
template<class T>
|
template<class T>
|
||||||
inline void MaNGOS::VisibleNotifier::Visit(GridRefManager<T> &m)
|
inline void MaNGOS::VisibleNotifier::Visit(GridRefManager<T> &m)
|
||||||
{
|
{
|
||||||
WorldObject const* viewPoint = i_player.GetViewPoint();
|
|
||||||
|
|
||||||
for(typename GridRefManager<T>::iterator iter = m.begin(); iter != m.end(); ++iter)
|
for(typename GridRefManager<T>::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||||
{
|
{
|
||||||
i_player.UpdateVisibilityOf(viewPoint,iter->getSource(), i_data, i_visibleNow);
|
i_camera.UpdateVisibilityOf(iter->getSource(), i_data, i_visibleNow);
|
||||||
i_clientGUIDs.erase(iter->getSource()->GetGUID());
|
i_clientGUIDs.erase(iter->getSource()->GetGUID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -69,7 +67,7 @@ inline void PlayerCreatureRelocationWorker(Player* pl, WorldObject const* viewPo
|
||||||
pl->UpdateVisibilityOf(viewPoint,c);
|
pl->UpdateVisibilityOf(viewPoint,c);
|
||||||
|
|
||||||
// Creature AI reaction
|
// Creature AI reaction
|
||||||
if (!c->hasUnitState(UNIT_STAT_FLEEING))
|
if (!c->hasUnitState(UNIT_STAT_LOST_CONTROL))
|
||||||
{
|
{
|
||||||
if (c->AI() && c->AI()->IsVisible(pl) && !c->IsInEvadeMode())
|
if (c->AI() && c->AI()->IsVisible(pl) && !c->IsInEvadeMode())
|
||||||
c->AI()->MoveInLineOfSight(pl);
|
c->AI()->MoveInLineOfSight(pl);
|
||||||
|
|
@ -78,13 +76,13 @@ inline void PlayerCreatureRelocationWorker(Player* pl, WorldObject const* viewPo
|
||||||
|
|
||||||
inline void CreatureCreatureRelocationWorker(Creature* c1, Creature* c2)
|
inline void CreatureCreatureRelocationWorker(Creature* c1, Creature* c2)
|
||||||
{
|
{
|
||||||
if (!c1->hasUnitState(UNIT_STAT_FLEEING))
|
if (!c1->hasUnitState(UNIT_STAT_LOST_CONTROL))
|
||||||
{
|
{
|
||||||
if (c1->AI() && c1->AI()->IsVisible(c2) && !c1->IsInEvadeMode())
|
if (c1->AI() && c1->AI()->IsVisible(c2) && !c1->IsInEvadeMode())
|
||||||
c1->AI()->MoveInLineOfSight(c2);
|
c1->AI()->MoveInLineOfSight(c2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!c2->hasUnitState(UNIT_STAT_FLEEING))
|
if (!c2->hasUnitState(UNIT_STAT_LOST_CONTROL))
|
||||||
{
|
{
|
||||||
if (c2->AI() && c2->AI()->IsVisible(c1) && !c2->IsInEvadeMode())
|
if (c2->AI() && c2->AI()->IsVisible(c1) && !c2->IsInEvadeMode())
|
||||||
c2->AI()->MoveInLineOfSight(c1);
|
c2->AI()->MoveInLineOfSight(c1);
|
||||||
|
|
@ -96,7 +94,7 @@ inline void MaNGOS::PlayerRelocationNotifier::Visit(CreatureMapType &m)
|
||||||
if (!i_player.isAlive() || i_player.isInFlight())
|
if (!i_player.isAlive() || i_player.isInFlight())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
WorldObject const* viewPoint = i_player.GetViewPoint();
|
WorldObject const* viewPoint = i_player.GetCamera().GetBody();
|
||||||
|
|
||||||
for(CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
for(CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||||
if (iter->getSource()->isAlive())
|
if (iter->getSource()->isAlive())
|
||||||
|
|
@ -106,13 +104,13 @@ inline void MaNGOS::PlayerRelocationNotifier::Visit(CreatureMapType &m)
|
||||||
template<>
|
template<>
|
||||||
inline void MaNGOS::CreatureRelocationNotifier::Visit(PlayerMapType &m)
|
inline void MaNGOS::CreatureRelocationNotifier::Visit(PlayerMapType &m)
|
||||||
{
|
{
|
||||||
if(!i_creature.isAlive())
|
if (!i_creature.isAlive())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
|
for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
|
||||||
if (Player* player = iter->getSource())
|
if (Player* player = iter->getSource())
|
||||||
if (player->isAlive() && !player->isInFlight())
|
if (player->isAlive() && !player->isInFlight())
|
||||||
PlayerCreatureRelocationWorker(player, player->GetViewPoint(), &i_creature);
|
PlayerCreatureRelocationWorker(player, player->GetCamera().GetBody(), &i_creature);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
|
||||||
|
|
@ -771,7 +771,7 @@ void Group::CountTheRoll(Rolls::iterator& rollI)
|
||||||
if (itr->second != ROLL_NEED)
|
if (itr->second != ROLL_NEED)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
uint8 randomN = urand(1, 99);
|
uint8 randomN = urand(1, 100);
|
||||||
SendLootRoll(itr->first, randomN, ROLL_NEED, *roll);
|
SendLootRoll(itr->first, randomN, ROLL_NEED, *roll);
|
||||||
if (maxresul < randomN)
|
if (maxresul < randomN)
|
||||||
{
|
{
|
||||||
|
|
@ -819,7 +819,7 @@ void Group::CountTheRoll(Rolls::iterator& rollI)
|
||||||
if (itr->second != ROLL_GREED && itr->second != ROLL_DISENCHANT)
|
if (itr->second != ROLL_GREED && itr->second != ROLL_DISENCHANT)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
uint8 randomN = urand(1, 99);
|
uint8 randomN = urand(1, 100);
|
||||||
SendLootRoll(itr->first, randomN, itr->second, *roll);
|
SendLootRoll(itr->first, randomN, itr->second, *roll);
|
||||||
if (maxresul < randomN)
|
if (maxresul < randomN)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@
|
||||||
#include "InstanceSaveMgr.h"
|
#include "InstanceSaveMgr.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "GridNotifiersImpl.h"
|
#include "GridNotifiersImpl.h"
|
||||||
#include "Config/ConfigEnv.h"
|
|
||||||
#include "Transports.h"
|
#include "Transports.h"
|
||||||
#include "ObjectMgr.h"
|
#include "ObjectMgr.h"
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
|
|
|
||||||
|
|
@ -2226,6 +2226,51 @@ bool ChatHandler::HandleGroupgoCommand(const char* args)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ChatHandler::HandleGoHelper( Player* player, uint32 mapid, float x, float y, float const* zPtr )
|
||||||
|
{
|
||||||
|
float z;
|
||||||
|
|
||||||
|
if (zPtr)
|
||||||
|
{
|
||||||
|
z = *zPtr;
|
||||||
|
|
||||||
|
// check full provided coordinates
|
||||||
|
if(!MapManager::IsValidMapCoord(mapid,x,y,z))
|
||||||
|
{
|
||||||
|
PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
|
||||||
|
SetSentErrorMessage(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we need check x,y before ask Z or can crash at invalide coordinates
|
||||||
|
if(!MapManager::IsValidMapCoord(mapid,x,y))
|
||||||
|
{
|
||||||
|
PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
|
||||||
|
SetSentErrorMessage(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map const *map = sMapMgr.CreateBaseMap(mapid);
|
||||||
|
z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
// stop flight if need
|
||||||
|
if(player->isInFlight())
|
||||||
|
{
|
||||||
|
player->GetMotionMaster()->MovementExpired();
|
||||||
|
player->m_taxi.ClearTaxiDestinations();
|
||||||
|
}
|
||||||
|
// save only in non-flight case
|
||||||
|
else
|
||||||
|
player->SaveRecallPosition();
|
||||||
|
|
||||||
|
player->TeleportTo(mapid, x, y, z, player->GetOrientation());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ChatHandler::HandleGoTaxinodeCommand(const char* args)
|
bool ChatHandler::HandleGoTaxinodeCommand(const char* args)
|
||||||
{
|
{
|
||||||
Player* _player = m_session->GetPlayer();
|
Player* _player = m_session->GetPlayer();
|
||||||
|
|
@ -2249,28 +2294,55 @@ bool ChatHandler::HandleGoTaxinodeCommand(const char* args)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((node->x == 0.0f && node->y == 0.0f && node->z == 0.0f) ||
|
if (node->x == 0.0f && node->y == 0.0f && node->z == 0.0f)
|
||||||
!MapManager::IsValidMapCoord(node->map_id,node->x,node->y,node->z))
|
|
||||||
{
|
{
|
||||||
PSendSysMessage(LANG_INVALID_TARGET_COORD,node->x,node->y,node->map_id);
|
PSendSysMessage(LANG_INVALID_TARGET_COORD,node->x,node->y,node->map_id);
|
||||||
SetSentErrorMessage(true);
|
SetSentErrorMessage(true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// stop flight if need
|
return HandleGoHelper(_player, node->map_id, node->x, node->y, &node->z);
|
||||||
if (_player->isInFlight())
|
|
||||||
{
|
|
||||||
_player->GetMotionMaster()->MovementExpired();
|
|
||||||
_player->m_taxi.ClearTaxiDestinations();
|
|
||||||
}
|
|
||||||
// save only in non-flight case
|
|
||||||
else
|
|
||||||
_player->SaveRecallPosition();
|
|
||||||
|
|
||||||
_player->TeleportTo(node->map_id, node->x, node->y, node->z, _player->GetOrientation());
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ChatHandler::HandleGoCommand(const char* args)
|
||||||
|
{
|
||||||
|
if(!*args)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Player* _player = m_session->GetPlayer();
|
||||||
|
|
||||||
|
uint32 mapid;
|
||||||
|
float x, y, z;
|
||||||
|
|
||||||
|
// raw coordinates case
|
||||||
|
if (isNumeric(args[0]))
|
||||||
|
{
|
||||||
|
char* px = strtok((char*)args, " ");
|
||||||
|
char* py = strtok(NULL, " ");
|
||||||
|
char* pz = strtok(NULL, " ");
|
||||||
|
char* pmapid = strtok(NULL, " ");
|
||||||
|
|
||||||
|
if (!px || !py || !pz)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
x = (float)atof(px);
|
||||||
|
y = (float)atof(py);
|
||||||
|
z = (float)atof(pz);
|
||||||
|
if (pmapid)
|
||||||
|
mapid = (uint32)atoi(pmapid);
|
||||||
|
else
|
||||||
|
mapid = _player->GetMapId();
|
||||||
|
|
||||||
|
}
|
||||||
|
// link case
|
||||||
|
else if (!extractLocationFromLink((char*)args, mapid, x, y, z))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return HandleGoHelper(_player, mapid, x, y, &z);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//teleport at coordinates
|
//teleport at coordinates
|
||||||
bool ChatHandler::HandleGoXYCommand(const char* args)
|
bool ChatHandler::HandleGoXYCommand(const char* args)
|
||||||
{
|
{
|
||||||
|
|
@ -2293,29 +2365,7 @@ bool ChatHandler::HandleGoXYCommand(const char* args)
|
||||||
mapid = (uint32)atoi(pmapid);
|
mapid = (uint32)atoi(pmapid);
|
||||||
else mapid = _player->GetMapId();
|
else mapid = _player->GetMapId();
|
||||||
|
|
||||||
if(!MapManager::IsValidMapCoord(mapid,x,y))
|
return HandleGoHelper(_player, mapid, x, y);
|
||||||
{
|
|
||||||
PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
|
|
||||||
SetSentErrorMessage(true);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// stop flight if need
|
|
||||||
if(_player->isInFlight())
|
|
||||||
{
|
|
||||||
_player->GetMotionMaster()->MovementExpired();
|
|
||||||
_player->m_taxi.ClearTaxiDestinations();
|
|
||||||
}
|
|
||||||
// save only in non-flight case
|
|
||||||
else
|
|
||||||
_player->SaveRecallPosition();
|
|
||||||
|
|
||||||
Map const *map = sMapMgr.CreateBaseMap(mapid);
|
|
||||||
float z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y));
|
|
||||||
|
|
||||||
_player->TeleportTo(mapid, x, y, z, _player->GetOrientation());
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//teleport at coordinates, including Z
|
//teleport at coordinates, including Z
|
||||||
|
|
@ -2343,26 +2393,7 @@ bool ChatHandler::HandleGoXYZCommand(const char* args)
|
||||||
else
|
else
|
||||||
mapid = _player->GetMapId();
|
mapid = _player->GetMapId();
|
||||||
|
|
||||||
if(!MapManager::IsValidMapCoord(mapid,x,y,z))
|
return HandleGoHelper(_player, mapid, x, y, &z);
|
||||||
{
|
|
||||||
PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
|
|
||||||
SetSentErrorMessage(true);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// stop flight if need
|
|
||||||
if(_player->isInFlight())
|
|
||||||
{
|
|
||||||
_player->GetMotionMaster()->MovementExpired();
|
|
||||||
_player->m_taxi.ClearTaxiDestinations();
|
|
||||||
}
|
|
||||||
// save only in non-flight case
|
|
||||||
else
|
|
||||||
_player->SaveRecallPosition();
|
|
||||||
|
|
||||||
_player->TeleportTo(mapid, x, y, z, _player->GetOrientation());
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//teleport at coordinates
|
//teleport at coordinates
|
||||||
|
|
@ -2403,49 +2434,33 @@ bool ChatHandler::HandleGoZoneXYCommand(const char* args)
|
||||||
// update to parent zone if exist (client map show only zones without parents)
|
// update to parent zone if exist (client map show only zones without parents)
|
||||||
AreaTableEntry const* zoneEntry = areaEntry->zone ? GetAreaEntryByAreaID(areaEntry->zone) : areaEntry;
|
AreaTableEntry const* zoneEntry = areaEntry->zone ? GetAreaEntryByAreaID(areaEntry->zone) : areaEntry;
|
||||||
|
|
||||||
Map const *map = sMapMgr.CreateBaseMap(zoneEntry->mapid);
|
MapEntry const *mapEntry = sMapStore.LookupEntry(zoneEntry->mapid);
|
||||||
|
|
||||||
if(map->Instanceable())
|
if (mapEntry->Instanceable())
|
||||||
{
|
{
|
||||||
PSendSysMessage(LANG_INVALID_ZONE_MAP,areaEntry->ID,areaEntry->area_name[GetSessionDbcLocale()],map->GetId(),map->GetMapName());
|
PSendSysMessage(LANG_INVALID_ZONE_MAP, areaEntry->ID, areaEntry->area_name[GetSessionDbcLocale()],
|
||||||
|
mapEntry->MapID, mapEntry->name[GetSessionDbcLocale()]);
|
||||||
SetSentErrorMessage(true);
|
SetSentErrorMessage(true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Zone2MapCoordinates(x,y,zoneEntry->ID))
|
if (!Zone2MapCoordinates(x,y,zoneEntry->ID))
|
||||||
{
|
{
|
||||||
PSendSysMessage(LANG_INVALID_ZONE_MAP,areaEntry->ID,areaEntry->area_name[GetSessionDbcLocale()],map->GetId(),map->GetMapName());
|
PSendSysMessage(LANG_INVALID_ZONE_MAP, areaEntry->ID, areaEntry->area_name[GetSessionDbcLocale()],
|
||||||
|
mapEntry->MapID, mapEntry->name[GetSessionDbcLocale()]);
|
||||||
SetSentErrorMessage(true);
|
SetSentErrorMessage(true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!MapManager::IsValidMapCoord(zoneEntry->mapid,x,y))
|
return HandleGoHelper(_player, mapEntry->MapID, x, y);
|
||||||
{
|
|
||||||
PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,zoneEntry->mapid);
|
|
||||||
SetSentErrorMessage(true);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// stop flight if need
|
|
||||||
if(_player->isInFlight())
|
|
||||||
{
|
|
||||||
_player->GetMotionMaster()->MovementExpired();
|
|
||||||
_player->m_taxi.ClearTaxiDestinations();
|
|
||||||
}
|
|
||||||
// save only in non-flight case
|
|
||||||
else
|
|
||||||
_player->SaveRecallPosition();
|
|
||||||
|
|
||||||
float z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y));
|
|
||||||
_player->TeleportTo(zoneEntry->mapid, x, y, z, _player->GetOrientation());
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//teleport to grid
|
//teleport to grid
|
||||||
bool ChatHandler::HandleGoGridCommand(const char* args)
|
bool ChatHandler::HandleGoGridCommand(const char* args)
|
||||||
{
|
{
|
||||||
if(!*args) return false;
|
if (!*args)
|
||||||
|
return false;
|
||||||
|
|
||||||
Player* _player = m_session->GetPlayer();
|
Player* _player = m_session->GetPlayer();
|
||||||
|
|
||||||
char* px = strtok((char*)args, " ");
|
char* px = strtok((char*)args, " ");
|
||||||
|
|
@ -2457,37 +2472,13 @@ bool ChatHandler::HandleGoGridCommand(const char* args)
|
||||||
|
|
||||||
float grid_x = (float)atof(px);
|
float grid_x = (float)atof(px);
|
||||||
float grid_y = (float)atof(py);
|
float grid_y = (float)atof(py);
|
||||||
uint32 mapid;
|
uint32 mapid = pmapid ? (uint32)atoi(pmapid) : _player->GetMapId();
|
||||||
if (pmapid)
|
|
||||||
mapid = (uint32)atoi(pmapid);
|
|
||||||
else mapid = _player->GetMapId();
|
|
||||||
|
|
||||||
// center of grid
|
// center of grid
|
||||||
float x = (grid_x-CENTER_GRID_ID+0.5f)*SIZE_OF_GRIDS;
|
float x = (grid_x-CENTER_GRID_ID+0.5f)*SIZE_OF_GRIDS;
|
||||||
float y = (grid_y-CENTER_GRID_ID+0.5f)*SIZE_OF_GRIDS;
|
float y = (grid_y-CENTER_GRID_ID+0.5f)*SIZE_OF_GRIDS;
|
||||||
|
|
||||||
if(!MapManager::IsValidMapCoord(mapid,x,y))
|
return HandleGoHelper(_player, mapid, x, y);
|
||||||
{
|
|
||||||
PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
|
|
||||||
SetSentErrorMessage(true);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// stop flight if need
|
|
||||||
if(_player->isInFlight())
|
|
||||||
{
|
|
||||||
_player->GetMotionMaster()->MovementExpired();
|
|
||||||
_player->m_taxi.ClearTaxiDestinations();
|
|
||||||
}
|
|
||||||
// save only in non-flight case
|
|
||||||
else
|
|
||||||
_player->SaveRecallPosition();
|
|
||||||
|
|
||||||
Map const *map = sMapMgr.CreateBaseMap(mapid);
|
|
||||||
float z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y));
|
|
||||||
_player->TeleportTo(mapid, x, y, z, _player->GetOrientation());
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChatHandler::HandleModifyDrunkCommand(const char* args)
|
bool ChatHandler::HandleModifyDrunkCommand(const char* args)
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
#include "SkillDiscovery.h"
|
#include "SkillDiscovery.h"
|
||||||
#include "SkillExtraItems.h"
|
#include "SkillExtraItems.h"
|
||||||
#include "SystemConfig.h"
|
#include "SystemConfig.h"
|
||||||
#include "Config/ConfigEnv.h"
|
#include "Config/Config.h"
|
||||||
#include "Mail.h"
|
#include "Mail.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "ItemEnchantmentMgr.h"
|
#include "ItemEnchantmentMgr.h"
|
||||||
|
|
@ -2832,7 +2832,7 @@ void ChatHandler::ShowSpellListHelper(Player* target, SpellEntry const* spellInf
|
||||||
uint32 talentCost = GetTalentSpellCost(id);
|
uint32 talentCost = GetTalentSpellCost(id);
|
||||||
|
|
||||||
bool talent = (talentCost > 0);
|
bool talent = (talentCost > 0);
|
||||||
bool passive = IsPassiveSpell(id);
|
bool passive = IsPassiveSpell(spellInfo);
|
||||||
bool active = target && target->HasAura(id);
|
bool active = target && target->HasAura(id);
|
||||||
|
|
||||||
// unit32 used to prevent interpreting uint8 as char at output
|
// unit32 used to prevent interpreting uint8 as char at output
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,8 @@ libmangosgame_a_SOURCES = \
|
||||||
Calendar.cpp \
|
Calendar.cpp \
|
||||||
Calendar.h \
|
Calendar.h \
|
||||||
CalendarHandler.cpp \
|
CalendarHandler.cpp \
|
||||||
|
Camera.cpp \
|
||||||
|
Camera.h \
|
||||||
Cell.h \
|
Cell.h \
|
||||||
CellImpl.h \
|
CellImpl.h \
|
||||||
Channel.cpp \
|
Channel.cpp \
|
||||||
|
|
|
||||||
118
src/game/Map.cpp
118
src/game/Map.cpp
|
|
@ -26,7 +26,6 @@
|
||||||
#include "InstanceData.h"
|
#include "InstanceData.h"
|
||||||
#include "Map.h"
|
#include "Map.h"
|
||||||
#include "GridNotifiersImpl.h"
|
#include "GridNotifiersImpl.h"
|
||||||
#include "Config/ConfigEnv.h"
|
|
||||||
#include "Transports.h"
|
#include "Transports.h"
|
||||||
#include "ObjectAccessor.h"
|
#include "ObjectAccessor.h"
|
||||||
#include "ObjectMgr.h"
|
#include "ObjectMgr.h"
|
||||||
|
|
@ -367,8 +366,9 @@ bool Map::Add(Player *player)
|
||||||
SendInitSelf(player);
|
SendInitSelf(player);
|
||||||
SendInitTransports(player);
|
SendInitTransports(player);
|
||||||
|
|
||||||
|
NGridType* grid = getNGrid(cell.GridX(), cell.GridY());
|
||||||
|
player->GetViewPoint().Event_AddedToWorld(&(*grid)(cell.CellX(), cell.CellY()));
|
||||||
UpdateObjectVisibility(player,cell,p);
|
UpdateObjectVisibility(player,cell,p);
|
||||||
UpdateObjectsVisibilityFor(player,cell,p);
|
|
||||||
|
|
||||||
AddNotifier(player,cell,p);
|
AddNotifier(player,cell,p);
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -406,6 +406,7 @@ Map::Add(T *obj)
|
||||||
|
|
||||||
DEBUG_LOG("Object %u enters grid[%u,%u]", GUID_LOPART(obj->GetGUID()), cell.GridX(), cell.GridY());
|
DEBUG_LOG("Object %u enters grid[%u,%u]", GUID_LOPART(obj->GetGUID()), cell.GridX(), cell.GridY());
|
||||||
|
|
||||||
|
obj->GetViewPoint().Event_AddedToWorld(&(*grid)(cell.CellX(), cell.CellY()));
|
||||||
UpdateObjectVisibility(obj,cell,p);
|
UpdateObjectVisibility(obj,cell,p);
|
||||||
|
|
||||||
AddNotifier(obj,cell,p);
|
AddNotifier(obj,cell,p);
|
||||||
|
|
@ -682,7 +683,6 @@ void Map::Remove(Player *player, bool remove)
|
||||||
|
|
||||||
SendRemoveTransports(player);
|
SendRemoveTransports(player);
|
||||||
UpdateObjectVisibility(player,cell,p);
|
UpdateObjectVisibility(player,cell,p);
|
||||||
UpdateObjectsVisibilityFor(player,cell,p);
|
|
||||||
|
|
||||||
player->ResetMap();
|
player->ResetMap();
|
||||||
if( remove )
|
if( remove )
|
||||||
|
|
@ -716,10 +716,9 @@ Map::Remove(T *obj, bool remove)
|
||||||
else
|
else
|
||||||
obj->RemoveFromWorld();
|
obj->RemoveFromWorld();
|
||||||
|
|
||||||
|
UpdateObjectVisibility(obj,cell,p); // i think will be better to call this function while object still in grid, this changes nothing but logically is better(as for me)
|
||||||
RemoveFromGrid(obj,grid,cell);
|
RemoveFromGrid(obj,grid,cell);
|
||||||
|
|
||||||
UpdateObjectVisibility(obj,cell,p);
|
|
||||||
|
|
||||||
obj->ResetMap();
|
obj->ResetMap();
|
||||||
if( remove )
|
if( remove )
|
||||||
{
|
{
|
||||||
|
|
@ -759,10 +758,13 @@ Map::PlayerRelocation(Player *player, float x, float y, float z, float orientati
|
||||||
AddToGrid(player, oldGrid,new_cell);
|
AddToGrid(player, oldGrid,new_cell);
|
||||||
else
|
else
|
||||||
EnsureGridLoadedAtEnter(new_cell, player);
|
EnsureGridLoadedAtEnter(new_cell, player);
|
||||||
|
|
||||||
|
NGridType* newGrid = getNGrid(new_cell.GridX(), new_cell.GridY());
|
||||||
|
player->GetViewPoint().Event_GridChanged(&(*newGrid)(new_cell.CellX(),new_cell.CellY()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
player->GetViewPoint().Call_UpdateVisibilityForOwner();
|
||||||
// if move then update what player see and who seen
|
// if move then update what player see and who seen
|
||||||
UpdateObjectsVisibilityFor(player,new_cell,new_val);
|
|
||||||
UpdateObjectVisibility(player, new_cell, new_val);
|
UpdateObjectVisibility(player, new_cell, new_val);
|
||||||
PlayerRelocationNotify(player,new_cell,new_val);
|
PlayerRelocationNotify(player,new_cell,new_val);
|
||||||
|
|
||||||
|
|
@ -816,6 +818,7 @@ Map::CreatureRelocation(Creature *creature, float x, float y, float z, float ang
|
||||||
creature->SetNeedNotify();
|
creature->SetNeedNotify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
creature->GetViewPoint().Call_UpdateVisibilityForOwner();
|
||||||
ASSERT(CheckGridIntegrity(creature,true));
|
ASSERT(CheckGridIntegrity(creature,true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -829,12 +832,12 @@ bool Map::CreatureCellRelocation(Creature *c, Cell new_cell)
|
||||||
{
|
{
|
||||||
DEBUG_FILTER_LOG(LOG_FILTER_CREATURE_MOVES, "Creature (GUID: %u Entry: %u) moved in grid[%u,%u] from cell[%u,%u] to cell[%u,%u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.CellX(), new_cell.CellY());
|
DEBUG_FILTER_LOG(LOG_FILTER_CREATURE_MOVES, "Creature (GUID: %u Entry: %u) moved in grid[%u,%u] from cell[%u,%u] to cell[%u,%u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.CellX(), new_cell.CellY());
|
||||||
|
|
||||||
if( !old_cell.DiffGrid(new_cell) )
|
RemoveFromGrid(c,getNGrid(old_cell.GridX(), old_cell.GridY()),old_cell);
|
||||||
{
|
|
||||||
RemoveFromGrid(c,getNGrid(old_cell.GridX(), old_cell.GridY()),old_cell);
|
NGridType* new_grid = getNGrid(new_cell.GridX(), new_cell.GridY());
|
||||||
AddToGrid(c,getNGrid(new_cell.GridX(), new_cell.GridY()),new_cell);
|
AddToGrid(c,new_grid,new_cell);
|
||||||
c->SetCurrentCell(new_cell);
|
|
||||||
}
|
c->GetViewPoint().Event_GridChanged( &(*new_grid)(new_cell.CellX(),new_cell.CellY()) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -852,7 +855,10 @@ bool Map::CreatureCellRelocation(Creature *c, Cell new_cell)
|
||||||
DEBUG_FILTER_LOG(LOG_FILTER_CREATURE_MOVES, "Active creature (GUID: %u Entry: %u) moved from grid[%u,%u]cell[%u,%u] to grid[%u,%u]cell[%u,%u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
|
DEBUG_FILTER_LOG(LOG_FILTER_CREATURE_MOVES, "Active creature (GUID: %u Entry: %u) moved from grid[%u,%u]cell[%u,%u] to grid[%u,%u]cell[%u,%u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
|
||||||
|
|
||||||
RemoveFromGrid(c,getNGrid(old_cell.GridX(), old_cell.GridY()),old_cell);
|
RemoveFromGrid(c,getNGrid(old_cell.GridX(), old_cell.GridY()),old_cell);
|
||||||
AddToGrid(c,getNGrid(new_cell.GridX(), new_cell.GridY()),new_cell);
|
|
||||||
|
NGridType* new_grid = getNGrid(new_cell.GridX(), new_cell.GridY());
|
||||||
|
AddToGrid(c,new_grid,new_cell);
|
||||||
|
c->GetViewPoint().Event_GridChanged( &(*new_grid)(new_cell.CellX(),new_cell.CellY()) );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -865,7 +871,9 @@ bool Map::CreatureCellRelocation(Creature *c, Cell new_cell)
|
||||||
RemoveFromGrid(c,getNGrid(old_cell.GridX(), old_cell.GridY()),old_cell);
|
RemoveFromGrid(c,getNGrid(old_cell.GridX(), old_cell.GridY()),old_cell);
|
||||||
{
|
{
|
||||||
EnsureGridCreated(GridPair(new_cell.GridX(), new_cell.GridY()));
|
EnsureGridCreated(GridPair(new_cell.GridX(), new_cell.GridY()));
|
||||||
AddToGrid(c,getNGrid(new_cell.GridX(), new_cell.GridY()),new_cell);
|
NGridType* new_grid = getNGrid(new_cell.GridX(), new_cell.GridY());
|
||||||
|
AddToGrid(c,new_grid,new_cell);
|
||||||
|
c->GetViewPoint().Event_GridChanged( &(*new_grid)(new_cell.CellX(),new_cell.CellY()) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1420,21 +1428,6 @@ void Map::UpdateObjectVisibility( WorldObject* obj, Cell cell, CellPair cellpair
|
||||||
cell.Visit(cellpair, player_notifier, *this, *obj, GetVisibilityDistance());
|
cell.Visit(cellpair, player_notifier, *this, *obj, GetVisibilityDistance());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::UpdateObjectsVisibilityFor( Player* player, Cell cell, CellPair cellpair )
|
|
||||||
{
|
|
||||||
MaNGOS::VisibleNotifier notifier(*player);
|
|
||||||
|
|
||||||
cell.data.Part.reserved = ALL_DISTRICT;
|
|
||||||
//cell.SetNoCreate(); need trigger cell loading around the player
|
|
||||||
TypeContainerVisitor<MaNGOS::VisibleNotifier, WorldTypeMapContainer > world_notifier(notifier);
|
|
||||||
TypeContainerVisitor<MaNGOS::VisibleNotifier, GridTypeMapContainer > grid_notifier(notifier);
|
|
||||||
cell.Visit(cellpair, world_notifier, *this, *player, GetVisibilityDistance());
|
|
||||||
cell.Visit(cellpair, grid_notifier, *this, *player, GetVisibilityDistance());
|
|
||||||
|
|
||||||
// send data
|
|
||||||
notifier.Notify();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Map::PlayerRelocationNotify( Player* player, Cell cell, CellPair cellpair )
|
void Map::PlayerRelocationNotify( Player* player, Cell cell, CellPair cellpair )
|
||||||
{
|
{
|
||||||
MaNGOS::PlayerRelocationNotifier relocationNotifier(*player);
|
MaNGOS::PlayerRelocationNotifier relocationNotifier(*player);
|
||||||
|
|
@ -1646,44 +1639,63 @@ bool Map::ActiveObjectsNearGrid(uint32 x, uint32 y) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::AddToActive( Creature* c )
|
void Map::AddToActive( WorldObject* obj )
|
||||||
{
|
{
|
||||||
AddToActiveHelper(c);
|
m_activeNonPlayers.insert(obj);
|
||||||
|
|
||||||
// also not allow unloading spawn grid to prevent creating creature clone at load
|
// also not allow unloading spawn grid to prevent creating creature clone at load
|
||||||
if(!c->isPet() && c->GetDBTableGUIDLow())
|
if (obj->GetTypeId()==TYPEID_UNIT)
|
||||||
{
|
{
|
||||||
float x,y,z;
|
Creature* c= (Creature*)obj;
|
||||||
c->GetRespawnCoord(x,y,z);
|
|
||||||
GridPair p = MaNGOS::ComputeGridPair(x, y);
|
if (!c->isPet() && c->GetDBTableGUIDLow())
|
||||||
if(getNGrid(p.x_coord, p.y_coord))
|
|
||||||
getNGrid(p.x_coord, p.y_coord)->incUnloadActiveLock();
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
GridPair p2 = MaNGOS::ComputeGridPair(c->GetPositionX(), c->GetPositionY());
|
float x,y,z;
|
||||||
sLog.outError("Active creature (GUID: %u Entry: %u) added to grid[%u,%u] but spawn grid[%u,%u] not loaded.",
|
c->GetRespawnCoord(x,y,z);
|
||||||
c->GetGUIDLow(), c->GetEntry(), p.x_coord, p.y_coord, p2.x_coord, p2.y_coord);
|
GridPair p = MaNGOS::ComputeGridPair(x, y);
|
||||||
|
if(getNGrid(p.x_coord, p.y_coord))
|
||||||
|
getNGrid(p.x_coord, p.y_coord)->incUnloadActiveLock();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GridPair p2 = MaNGOS::ComputeGridPair(c->GetPositionX(), c->GetPositionY());
|
||||||
|
sLog.outError("Active creature (GUID: %u Entry: %u) added to grid[%u,%u] but spawn grid[%u,%u] not loaded.",
|
||||||
|
c->GetGUIDLow(), c->GetEntry(), p.x_coord, p.y_coord, p2.x_coord, p2.y_coord);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::RemoveFromActive( Creature* c )
|
void Map::RemoveFromActive( WorldObject* obj )
|
||||||
{
|
{
|
||||||
RemoveFromActiveHelper(c);
|
// Map::Update for active object in proccess
|
||||||
|
if(m_activeNonPlayersIter != m_activeNonPlayers.end())
|
||||||
|
{
|
||||||
|
ActiveNonPlayers::iterator itr = m_activeNonPlayers.find(obj);
|
||||||
|
if(itr==m_activeNonPlayersIter)
|
||||||
|
++m_activeNonPlayersIter;
|
||||||
|
m_activeNonPlayers.erase(itr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_activeNonPlayers.erase(obj);
|
||||||
|
|
||||||
// also allow unloading spawn grid
|
// also allow unloading spawn grid
|
||||||
if(!c->isPet() && c->GetDBTableGUIDLow())
|
if (obj->GetTypeId()==TYPEID_UNIT)
|
||||||
{
|
{
|
||||||
float x,y,z;
|
Creature* c= (Creature*)obj;
|
||||||
c->GetRespawnCoord(x,y,z);
|
|
||||||
GridPair p = MaNGOS::ComputeGridPair(x, y);
|
if(!c->isPet() && c->GetDBTableGUIDLow())
|
||||||
if(getNGrid(p.x_coord, p.y_coord))
|
|
||||||
getNGrid(p.x_coord, p.y_coord)->decUnloadActiveLock();
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
GridPair p2 = MaNGOS::ComputeGridPair(c->GetPositionX(), c->GetPositionY());
|
float x,y,z;
|
||||||
sLog.outError("Active creature (GUID: %u Entry: %u) removed from grid[%u,%u] but spawn grid[%u,%u] not loaded.",
|
c->GetRespawnCoord(x,y,z);
|
||||||
c->GetGUIDLow(), c->GetEntry(), p.x_coord, p.y_coord, p2.x_coord, p2.y_coord);
|
GridPair p = MaNGOS::ComputeGridPair(x, y);
|
||||||
|
if(getNGrid(p.x_coord, p.y_coord))
|
||||||
|
getNGrid(p.x_coord, p.y_coord)->decUnloadActiveLock();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GridPair p2 = MaNGOS::ComputeGridPair(c->GetPositionX(), c->GetPositionY());
|
||||||
|
sLog.outError("Active creature (GUID: %u Entry: %u) removed from grid[%u,%u] but spawn grid[%u,%u] not loaded.",
|
||||||
|
c->GetGUIDLow(), c->GetEntry(), p.x_coord, p.y_coord, p2.x_coord, p2.y_coord);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,8 @@ enum LevelRequirementVsMode
|
||||||
class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::ObjectLevelLockable<Map, ACE_Thread_Mutex>
|
class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::ObjectLevelLockable<Map, ACE_Thread_Mutex>
|
||||||
{
|
{
|
||||||
friend class MapReference;
|
friend class MapReference;
|
||||||
|
friend class ObjectGridLoader;
|
||||||
|
friend class ObjectWorldLoader;
|
||||||
public:
|
public:
|
||||||
Map(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode, Map* _parent = NULL);
|
Map(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode, Map* _parent = NULL);
|
||||||
virtual ~Map();
|
virtual ~Map();
|
||||||
|
|
@ -211,7 +213,6 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
|
||||||
void AddObjectToRemoveList(WorldObject *obj);
|
void AddObjectToRemoveList(WorldObject *obj);
|
||||||
|
|
||||||
void UpdateObjectVisibility(WorldObject* obj, Cell cell, CellPair cellpair);
|
void UpdateObjectVisibility(WorldObject* obj, Cell cell, CellPair cellpair);
|
||||||
void UpdateObjectsVisibilityFor(Player* player, Cell cell, CellPair cellpair);
|
|
||||||
|
|
||||||
void resetMarkedCells() { marked_cells.reset(); }
|
void resetMarkedCells() { marked_cells.reset(); }
|
||||||
bool isCellMarked(uint32 pCellId) { return marked_cells.test(pCellId); }
|
bool isCellMarked(uint32 pCellId) { return marked_cells.test(pCellId); }
|
||||||
|
|
@ -231,16 +232,9 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
|
||||||
void ScriptCommandStart(ScriptInfo const& script, uint32 delay, Object* source, Object* target);
|
void ScriptCommandStart(ScriptInfo const& script, uint32 delay, Object* source, Object* target);
|
||||||
|
|
||||||
// must called with AddToWorld
|
// must called with AddToWorld
|
||||||
template<class T>
|
void AddToActive(WorldObject* obj);
|
||||||
void AddToActive(T* obj) { AddToActiveHelper(obj); }
|
|
||||||
|
|
||||||
void AddToActive(Creature* obj);
|
|
||||||
|
|
||||||
// must called with RemoveFromWorld
|
// must called with RemoveFromWorld
|
||||||
template<class T>
|
void RemoveFromActive(WorldObject* obj);
|
||||||
void RemoveFromActive(T* obj) { RemoveFromActiveHelper(obj); }
|
|
||||||
|
|
||||||
void RemoveFromActive(Creature* obj);
|
|
||||||
|
|
||||||
Creature* GetCreature(ObjectGuid guid);
|
Creature* GetCreature(ObjectGuid guid);
|
||||||
Vehicle* GetVehicle(ObjectGuid guid);
|
Vehicle* GetVehicle(ObjectGuid guid);
|
||||||
|
|
@ -357,27 +351,6 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void DeleteFromWorld(T*);
|
void DeleteFromWorld(T*);
|
||||||
|
|
||||||
template<class T>
|
|
||||||
void AddToActiveHelper(T* obj)
|
|
||||||
{
|
|
||||||
m_activeNonPlayers.insert(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
void RemoveFromActiveHelper(T* obj)
|
|
||||||
{
|
|
||||||
// Map::Update for active object in proccess
|
|
||||||
if(m_activeNonPlayersIter != m_activeNonPlayers.end())
|
|
||||||
{
|
|
||||||
ActiveNonPlayers::iterator itr = m_activeNonPlayers.find(obj);
|
|
||||||
if(itr==m_activeNonPlayersIter)
|
|
||||||
++m_activeNonPlayersIter;
|
|
||||||
m_activeNonPlayers.erase(itr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_activeNonPlayers.erase(obj);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum InstanceResetMethod
|
enum InstanceResetMethod
|
||||||
|
|
|
||||||
|
|
@ -1293,10 +1293,10 @@ void WorldSession::HandleFarSightOpcode( WorldPacket & recv_data )
|
||||||
//WorldPacket data(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, 0)
|
//WorldPacket data(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, 0)
|
||||||
//SendPacket(&data);
|
//SendPacket(&data);
|
||||||
//_player->SetUInt64Value(PLAYER_FARSIGHT, 0);
|
//_player->SetUInt64Value(PLAYER_FARSIGHT, 0);
|
||||||
DEBUG_LOG("Removed FarSight from player %u", _player->GetGUIDLow());
|
DEBUG_LOG("Removed FarSight from %s", _player->GetObjectGuid().GetString().c_str());
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
DEBUG_LOG("Added FarSight (GUID:%u TypeId:%u) to player %u", GUID_LOPART(_player->GetFarSight()), GuidHigh2TypeId(GUID_HIPART(_player->GetFarSight())), _player->GetGUIDLow());
|
DEBUG_LOG("Added FarSight %s to %s", _player->GetFarSightGuid().GetString().c_str(), _player->GetObjectGuid().GetString().c_str());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,11 +40,15 @@ inline bool isStatic(MovementGenerator *mv)
|
||||||
void
|
void
|
||||||
MotionMaster::Initialize()
|
MotionMaster::Initialize()
|
||||||
{
|
{
|
||||||
|
// stop current move
|
||||||
|
if (!i_owner->IsStopped())
|
||||||
|
i_owner->StopMoving();
|
||||||
|
|
||||||
// clear ALL movement generators (including default)
|
// clear ALL movement generators (including default)
|
||||||
Clear(false,true);
|
Clear(false,true);
|
||||||
|
|
||||||
// set new default movement generator
|
// set new default movement generator
|
||||||
if (i_owner->GetTypeId() == TYPEID_UNIT)
|
if (i_owner->GetTypeId() == TYPEID_UNIT && !i_owner->hasUnitState(UNIT_STAT_CONTROLLED))
|
||||||
{
|
{
|
||||||
MovementGenerator* movement = FactorySelector::selectMovementGenerator((Creature*)i_owner);
|
MovementGenerator* movement = FactorySelector::selectMovementGenerator((Creature*)i_owner);
|
||||||
push(movement == NULL ? &si_idleMovement : movement);
|
push(movement == NULL ? &si_idleMovement : movement);
|
||||||
|
|
@ -226,7 +230,7 @@ void MotionMaster::MoveRandom()
|
||||||
void
|
void
|
||||||
MotionMaster::MoveTargetedHome()
|
MotionMaster::MoveTargetedHome()
|
||||||
{
|
{
|
||||||
if(i_owner->hasUnitState(UNIT_STAT_FLEEING))
|
if(i_owner->hasUnitState(UNIT_STAT_LOST_CONTROL))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Clear(false);
|
Clear(false);
|
||||||
|
|
@ -281,6 +285,9 @@ MotionMaster::MoveChase(Unit* target, float dist, float angle)
|
||||||
void
|
void
|
||||||
MotionMaster::MoveFollow(Unit* target, float dist, float angle)
|
MotionMaster::MoveFollow(Unit* target, float dist, float angle)
|
||||||
{
|
{
|
||||||
|
if(i_owner->hasUnitState(UNIT_STAT_LOST_CONTROL))
|
||||||
|
return;
|
||||||
|
|
||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
// ignore movement request if target not exist
|
// ignore movement request if target not exist
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ void WorldSession::HandleMoveTeleportAck(WorldPacket& recv_data)
|
||||||
DEBUG_LOG("Guid: %s", guid.GetString().c_str());
|
DEBUG_LOG("Guid: %s", guid.GetString().c_str());
|
||||||
DEBUG_LOG("Flags %u, time %u", flags, time/IN_MILLISECONDS);
|
DEBUG_LOG("Flags %u, time %u", flags, time/IN_MILLISECONDS);
|
||||||
|
|
||||||
Unit *mover = _player->m_mover;
|
Unit *mover = _player->GetMover();
|
||||||
Player *plMover = mover->GetTypeId() == TYPEID_PLAYER ? (Player*)mover : NULL;
|
Player *plMover = mover->GetTypeId() == TYPEID_PLAYER ? (Player*)mover : NULL;
|
||||||
|
|
||||||
if(!plMover || !plMover->IsBeingTeleportedNear())
|
if(!plMover || !plMover->IsBeingTeleportedNear())
|
||||||
|
|
@ -223,7 +223,7 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
|
||||||
DEBUG_LOG("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(opcode), opcode, opcode);
|
DEBUG_LOG("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(opcode), opcode, opcode);
|
||||||
recv_data.hexlike();
|
recv_data.hexlike();
|
||||||
|
|
||||||
Unit *mover = _player->m_mover;
|
Unit *mover = _player->GetMover();
|
||||||
Player *plMover = mover->GetTypeId() == TYPEID_PLAYER ? (Player*)mover : NULL;
|
Player *plMover = mover->GetTypeId() == TYPEID_PLAYER ? (Player*)mover : NULL;
|
||||||
|
|
||||||
// ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck
|
// ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck
|
||||||
|
|
@ -335,7 +335,7 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
|
||||||
// TODO: discard movement packets after the player is rooted
|
// TODO: discard movement packets after the player is rooted
|
||||||
if(plMover->isAlive())
|
if(plMover->isAlive())
|
||||||
{
|
{
|
||||||
plMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth());
|
plMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, plMover->GetMaxHealth());
|
||||||
// pl can be alive if GM/etc
|
// pl can be alive if GM/etc
|
||||||
if(!plMover->isAlive())
|
if(!plMover->isAlive())
|
||||||
{
|
{
|
||||||
|
|
@ -434,12 +434,13 @@ void WorldSession::HandleSetActiveMoverOpcode(WorldPacket &recv_data)
|
||||||
DEBUG_LOG("WORLD: Recvd CMSG_SET_ACTIVE_MOVER");
|
DEBUG_LOG("WORLD: Recvd CMSG_SET_ACTIVE_MOVER");
|
||||||
recv_data.hexlike();
|
recv_data.hexlike();
|
||||||
|
|
||||||
uint64 guid;
|
ObjectGuid guid;
|
||||||
recv_data >> guid;
|
recv_data >> guid;
|
||||||
|
|
||||||
if(_player->m_mover->GetGUID() != guid)
|
if(_player->GetMover()->GetObjectGuid() != guid)
|
||||||
{
|
{
|
||||||
sLog.outError("HandleSetActiveMoverOpcode: incorrect mover guid: mover is " I64FMT " and should be " I64FMT, _player->m_mover->GetGUID(), guid);
|
sLog.outError("HandleSetActiveMoverOpcode: incorrect mover guid: mover is %s and should be %s",
|
||||||
|
_player->GetMover()->GetObjectGuid().GetString().c_str(), guid.GetString().c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -455,9 +456,12 @@ void WorldSession::HandleMoveNotActiveMover(WorldPacket &recv_data)
|
||||||
recv_data >> old_mover_guid.ReadAsPacked();
|
recv_data >> old_mover_guid.ReadAsPacked();
|
||||||
recv_data >> mi;
|
recv_data >> mi;
|
||||||
|
|
||||||
if(_player->m_mover->GetObjectGuid() == old_mover_guid)
|
if(_player->GetMover()->GetObjectGuid() == old_mover_guid)
|
||||||
{
|
{
|
||||||
sLog.outError("HandleMoveNotActiveMover: incorrect mover guid: mover is " I64FMT " and should be " I64FMT " instead of " UI64FMTD, _player->m_mover->GetGUID(), _player->GetGUID(), old_mover_guid.GetRawValue());
|
sLog.outError("HandleMoveNotActiveMover: incorrect mover guid: mover is %s and should be %s instead of %s",
|
||||||
|
_player->GetMover()->GetObjectGuid().GetString().c_str(),
|
||||||
|
_player->GetObjectGuid().GetString().c_str(),
|
||||||
|
old_mover_guid.GetString().c_str());
|
||||||
recv_data.rpos(recv_data.wpos()); // prevent warnings spam
|
recv_data.rpos(recv_data.wpos()); // prevent warnings spam
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -397,11 +397,17 @@ void WorldSession::SendSpiritResurrect()
|
||||||
_player->TeleportTo(corpseGrave->map_id, corpseGrave->x, corpseGrave->y, corpseGrave->z, _player->GetOrientation());
|
_player->TeleportTo(corpseGrave->map_id, corpseGrave->x, corpseGrave->y, corpseGrave->z, _player->GetOrientation());
|
||||||
// or update at original position
|
// or update at original position
|
||||||
else
|
else
|
||||||
_player->UpdateVisibilityForPlayer();
|
{
|
||||||
|
_player->GetCamera().UpdateVisibilityForOwner();
|
||||||
|
_player->UpdateObjectVisibility();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// or update at original position
|
// or update at original position
|
||||||
else
|
else
|
||||||
_player->UpdateVisibilityForPlayer();
|
{
|
||||||
|
_player->GetCamera().UpdateVisibilityForOwner();
|
||||||
|
_player->UpdateObjectVisibility();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandleBinderActivateOpcode( WorldPacket & recv_data )
|
void WorldSession::HandleBinderActivateOpcode( WorldPacket & recv_data )
|
||||||
|
|
|
||||||
|
|
@ -1084,7 +1084,7 @@ void Object::BuildUpdateData( UpdateDataMapType& /*update_players */)
|
||||||
}
|
}
|
||||||
|
|
||||||
WorldObject::WorldObject()
|
WorldObject::WorldObject()
|
||||||
: m_currMap(NULL), m_mapId(0), m_InstanceId(0), m_phaseMask(PHASEMASK_NORMAL),
|
: m_isActiveObject(false), m_currMap(NULL), m_mapId(0), m_InstanceId(0), m_phaseMask(PHASEMASK_NORMAL),
|
||||||
m_positionX(0.0f), m_positionY(0.0f), m_positionZ(0.0f), m_orientation(0.0f)
|
m_positionX(0.0f), m_positionY(0.0f), m_positionZ(0.0f), m_orientation(0.0f)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -1496,7 +1496,7 @@ void WorldObject::MonsterSay(int32 textId, uint32 language, uint64 TargetGuid)
|
||||||
{
|
{
|
||||||
MaNGOS::MonsterChatBuilder say_build(*this, CHAT_MSG_MONSTER_SAY, textId,language,TargetGuid);
|
MaNGOS::MonsterChatBuilder say_build(*this, CHAT_MSG_MONSTER_SAY, textId,language,TargetGuid);
|
||||||
MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> say_do(say_build);
|
MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> say_do(say_build);
|
||||||
MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> > say_worker(this,sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_SAY),say_do);
|
MaNGOS::CameraDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> > say_worker(this,sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_SAY),say_do);
|
||||||
Cell::VisitWorldObjects(this, say_worker, sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_SAY));
|
Cell::VisitWorldObjects(this, say_worker, sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_SAY));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1507,7 +1507,7 @@ void WorldObject::MonsterYell(int32 textId, uint32 language, uint64 TargetGuid)
|
||||||
|
|
||||||
MaNGOS::MonsterChatBuilder say_build(*this, CHAT_MSG_MONSTER_YELL, textId,language,TargetGuid);
|
MaNGOS::MonsterChatBuilder say_build(*this, CHAT_MSG_MONSTER_YELL, textId,language,TargetGuid);
|
||||||
MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> say_do(say_build);
|
MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> say_do(say_build);
|
||||||
MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> > say_worker(this,range,say_do);
|
MaNGOS::CameraDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> > say_worker(this,range,say_do);
|
||||||
Cell::VisitWorldObjects(this, say_worker, sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_YELL));
|
Cell::VisitWorldObjects(this, say_worker, sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_YELL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1530,7 +1530,7 @@ void WorldObject::MonsterTextEmote(int32 textId, uint64 TargetGuid, bool IsBossE
|
||||||
|
|
||||||
MaNGOS::MonsterChatBuilder say_build(*this, IsBossEmote ? CHAT_MSG_RAID_BOSS_EMOTE : CHAT_MSG_MONSTER_EMOTE, textId,LANG_UNIVERSAL,TargetGuid);
|
MaNGOS::MonsterChatBuilder say_build(*this, IsBossEmote ? CHAT_MSG_RAID_BOSS_EMOTE : CHAT_MSG_MONSTER_EMOTE, textId,LANG_UNIVERSAL,TargetGuid);
|
||||||
MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> say_do(say_build);
|
MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> say_do(say_build);
|
||||||
MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> > say_worker(this,range,say_do);
|
MaNGOS::CameraDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::MonsterChatBuilder> > say_worker(this,range,say_do);
|
||||||
Cell::VisitWorldObjects(this, say_worker, range);
|
Cell::VisitWorldObjects(this, say_worker, range);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1864,7 +1864,10 @@ void WorldObject::SetPhaseMask(uint32 newPhaseMask, bool update)
|
||||||
m_phaseMask = newPhaseMask;
|
m_phaseMask = newPhaseMask;
|
||||||
|
|
||||||
if(update && IsInWorld())
|
if(update && IsInWorld())
|
||||||
|
{
|
||||||
UpdateObjectVisibility();
|
UpdateObjectVisibility();
|
||||||
|
GetViewPoint().Event_ViewPointVisibilityChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldObject::PlayDistanceSound( uint32 sound_id, Player* target /*= NULL*/ )
|
void WorldObject::PlayDistanceSound( uint32 sound_id, Player* target /*= NULL*/ )
|
||||||
|
|
@ -1910,12 +1913,22 @@ struct WorldObjectChangeAccumulator
|
||||||
{
|
{
|
||||||
UpdateDataMapType &i_updateDatas;
|
UpdateDataMapType &i_updateDatas;
|
||||||
WorldObject &i_object;
|
WorldObject &i_object;
|
||||||
WorldObjectChangeAccumulator(WorldObject &obj, UpdateDataMapType &d) : i_updateDatas(d), i_object(obj) {}
|
WorldObjectChangeAccumulator(WorldObject &obj, UpdateDataMapType &d) : i_updateDatas(d), i_object(obj)
|
||||||
void Visit(PlayerMapType &m)
|
|
||||||
{
|
{
|
||||||
for(PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
// send self fields changes in another way, otherwise
|
||||||
if(iter->getSource()->HaveAtClient(&i_object))
|
// with new camera system when player's camera too far from player, camera wouldn't receive packets and changes from player
|
||||||
i_object.BuildUpdateDataForPlayer(iter->getSource(), i_updateDatas);
|
if(i_object.isType(TYPEMASK_PLAYER))
|
||||||
|
i_object.BuildUpdateDataForPlayer((Player*)&i_object, i_updateDatas);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Visit(CameraMapType &m)
|
||||||
|
{
|
||||||
|
for(CameraMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||||
|
{
|
||||||
|
Player* owner = iter->getSource()->GetOwner();
|
||||||
|
if(owner != &i_object && owner->HaveAtClient(&i_object))
|
||||||
|
i_object.BuildUpdateDataForPlayer(owner, i_updateDatas);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
|
template<class SKIP> void Visit(GridRefManager<SKIP> &) {}
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@
|
||||||
#include "ByteBuffer.h"
|
#include "ByteBuffer.h"
|
||||||
#include "UpdateFields.h"
|
#include "UpdateFields.h"
|
||||||
#include "UpdateData.h"
|
#include "UpdateData.h"
|
||||||
#include "GameSystem/GridReference.h"
|
|
||||||
#include "ObjectGuid.h"
|
#include "ObjectGuid.h"
|
||||||
|
#include "Camera.h"
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
@ -108,11 +108,11 @@ class MANGOS_DLL_SPEC Object
|
||||||
m_inWorld = false;
|
m_inWorld = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectGuid const& GetObjectGuid() const { return *reinterpret_cast<ObjectGuid const*>(&GetUInt64Value(0)); }
|
ObjectGuid const& GetObjectGuid() const { return GetGuidValue(OBJECT_FIELD_GUID); }
|
||||||
|
const uint64& GetGUID() const { return GetUInt64Value(OBJECT_FIELD_GUID); }
|
||||||
const uint64& GetGUID() const { return GetUInt64Value(0); }
|
uint32 GetGUIDLow() const { return GUID_LOPART(GetUInt64Value(OBJECT_FIELD_GUID)); }
|
||||||
uint32 GetGUIDLow() const { return GUID_LOPART(GetUInt64Value(0)); }
|
|
||||||
PackedGuid const& GetPackGUID() const { return m_PackGUID; }
|
PackedGuid const& GetPackGUID() const { return m_PackGUID; }
|
||||||
|
|
||||||
uint32 GetEntry() const { return GetUInt32Value(OBJECT_FIELD_ENTRY); }
|
uint32 GetEntry() const { return GetUInt32Value(OBJECT_FIELD_ENTRY); }
|
||||||
void SetEntry(uint32 entry) { SetUInt32Value(OBJECT_FIELD_ENTRY, entry); }
|
void SetEntry(uint32 entry) { SetUInt32Value(OBJECT_FIELD_ENTRY, entry); }
|
||||||
|
|
||||||
|
|
@ -171,6 +171,8 @@ class MANGOS_DLL_SPEC Object
|
||||||
return *(((uint16*)&m_uint32Values[ index ])+offset);
|
return *(((uint16*)&m_uint32Values[ index ])+offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ObjectGuid const& GetGuidValue( uint16 index ) const { return *reinterpret_cast<ObjectGuid const*>(&GetUInt64Value(index)); }
|
||||||
|
|
||||||
void SetInt32Value( uint16 index, int32 value );
|
void SetInt32Value( uint16 index, int32 value );
|
||||||
void SetUInt32Value( uint16 index, uint32 value );
|
void SetUInt32Value( uint16 index, uint32 value );
|
||||||
void SetUInt64Value( uint16 index, const uint64 &value );
|
void SetUInt64Value( uint16 index, const uint64 &value );
|
||||||
|
|
@ -178,6 +180,7 @@ class MANGOS_DLL_SPEC Object
|
||||||
void SetByteValue( uint16 index, uint8 offset, uint8 value );
|
void SetByteValue( uint16 index, uint8 offset, uint8 value );
|
||||||
void SetUInt16Value( uint16 index, uint8 offset, uint16 value );
|
void SetUInt16Value( uint16 index, uint8 offset, uint16 value );
|
||||||
void SetInt16Value( uint16 index, uint8 offset, int16 value ) { SetUInt16Value(index,offset,(uint16)value); }
|
void SetInt16Value( uint16 index, uint8 offset, int16 value ) { SetUInt16Value(index,offset,(uint16)value); }
|
||||||
|
void SetGuidValue( uint16 index, ObjectGuid const& value ) { SetUInt64Value(index, value.GetRawValue()); }
|
||||||
void SetStatFloatValue( uint16 index, float value);
|
void SetStatFloatValue( uint16 index, float value);
|
||||||
void SetStatInt32Value( uint16 index, int32 value);
|
void SetStatInt32Value( uint16 index, int32 value);
|
||||||
|
|
||||||
|
|
@ -476,6 +479,10 @@ class MANGOS_DLL_SPEC WorldObject : public Object
|
||||||
void BuildUpdateData(UpdateDataMapType &);
|
void BuildUpdateData(UpdateDataMapType &);
|
||||||
|
|
||||||
Creature* SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime);
|
Creature* SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime);
|
||||||
|
|
||||||
|
bool isActiveObject() const { return m_isActiveObject || m_viewPoint.hasViewers(); }
|
||||||
|
|
||||||
|
ViewPoint& GetViewPoint() { return m_viewPoint; }
|
||||||
protected:
|
protected:
|
||||||
explicit WorldObject();
|
explicit WorldObject();
|
||||||
|
|
||||||
|
|
@ -487,6 +494,7 @@ class MANGOS_DLL_SPEC WorldObject : public Object
|
||||||
|
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
|
|
||||||
|
bool m_isActiveObject;
|
||||||
private:
|
private:
|
||||||
Map * m_currMap; //current object's Map location
|
Map * m_currMap; //current object's Map location
|
||||||
|
|
||||||
|
|
@ -498,6 +506,8 @@ class MANGOS_DLL_SPEC WorldObject : public Object
|
||||||
float m_positionY;
|
float m_positionY;
|
||||||
float m_positionZ;
|
float m_positionZ;
|
||||||
float m_orientation;
|
float m_orientation;
|
||||||
|
|
||||||
|
ViewPoint m_viewPoint;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
#include "Corpse.h"
|
#include "Corpse.h"
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
#include "CellImpl.h"
|
#include "CellImpl.h"
|
||||||
|
#include "GridDefines.h"
|
||||||
|
|
||||||
class MANGOS_DLL_DECL ObjectGridRespawnMover
|
class MANGOS_DLL_DECL ObjectGridRespawnMover
|
||||||
{
|
{
|
||||||
|
|
@ -105,7 +106,7 @@ template<> void addUnitState(Creature *obj, CellPair const& cell_pair)
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void LoadHelper(CellGuidSet const& guid_set, CellPair &cell, GridRefManager<T> &m, uint32 &count, Map* map)
|
void LoadHelper(CellGuidSet const& guid_set, CellPair &cell, GridRefManager<T> &m, uint32 &count, Map* map, GridType& grid)
|
||||||
{
|
{
|
||||||
BattleGround* bg = map->IsBattleGroundOrArena() ? ((BattleGroundMap*)map)->GetBG() : NULL;
|
BattleGround* bg = map->IsBattleGroundOrArena() ? ((BattleGroundMap*)map)->GetBG() : NULL;
|
||||||
|
|
||||||
|
|
@ -121,13 +122,16 @@ void LoadHelper(CellGuidSet const& guid_set, CellPair &cell, GridRefManager<T> &
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
obj->GetGridRef().link(&m, obj);
|
grid.AddGridObject(obj);
|
||||||
|
|
||||||
addUnitState(obj,cell);
|
addUnitState(obj,cell);
|
||||||
obj->SetMap(map);
|
obj->SetMap(map);
|
||||||
obj->AddToWorld();
|
obj->AddToWorld();
|
||||||
if(obj->isActiveObject())
|
if(obj->isActiveObject())
|
||||||
map->AddToActive(obj);
|
map->AddToActive(obj);
|
||||||
|
|
||||||
|
obj->GetViewPoint().Event_AddedToWorld(&grid);
|
||||||
|
|
||||||
if (bg)
|
if (bg)
|
||||||
bg->OnObjectDBLoad(obj);
|
bg->OnObjectDBLoad(obj);
|
||||||
|
|
||||||
|
|
@ -135,7 +139,7 @@ void LoadHelper(CellGuidSet const& guid_set, CellPair &cell, GridRefManager<T> &
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadHelper(CellCorpseSet const& cell_corpses, CellPair &cell, CorpseMapType &m, uint32 &count, Map* map)
|
void LoadHelper(CellCorpseSet const& cell_corpses, CellPair &cell, CorpseMapType &m, uint32 &count, Map* map, GridType& grid)
|
||||||
{
|
{
|
||||||
if(cell_corpses.empty())
|
if(cell_corpses.empty())
|
||||||
return;
|
return;
|
||||||
|
|
@ -151,7 +155,7 @@ void LoadHelper(CellCorpseSet const& cell_corpses, CellPair &cell, CorpseMapType
|
||||||
if(!obj)
|
if(!obj)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
obj->GetGridRef().link(&m, obj);
|
grid.AddWorldObject(obj);
|
||||||
|
|
||||||
addUnitState(obj,cell);
|
addUnitState(obj,cell);
|
||||||
obj->SetMap(map);
|
obj->SetMap(map);
|
||||||
|
|
@ -173,7 +177,8 @@ ObjectGridLoader::Visit(GameObjectMapType &m)
|
||||||
|
|
||||||
CellObjectGuids const& cell_guids = sObjectMgr.GetCellObjectGuids(i_map->GetId(), i_map->GetSpawnMode(), cell_id);
|
CellObjectGuids const& cell_guids = sObjectMgr.GetCellObjectGuids(i_map->GetId(), i_map->GetSpawnMode(), cell_id);
|
||||||
|
|
||||||
LoadHelper(cell_guids.gameobjects, cell_pair, m, i_gameObjects, i_map);
|
GridType& grid = (*i_map->getNGrid(i_cell.GridX(),i_cell.GridY())) (i_cell.CellX(),i_cell.CellY());
|
||||||
|
LoadHelper(cell_guids.gameobjects, cell_pair, m, i_gameObjects, i_map, grid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -186,7 +191,8 @@ ObjectGridLoader::Visit(CreatureMapType &m)
|
||||||
|
|
||||||
CellObjectGuids const& cell_guids = sObjectMgr.GetCellObjectGuids(i_map->GetId(), i_map->GetSpawnMode(), cell_id);
|
CellObjectGuids const& cell_guids = sObjectMgr.GetCellObjectGuids(i_map->GetId(), i_map->GetSpawnMode(), cell_id);
|
||||||
|
|
||||||
LoadHelper(cell_guids.creatures, cell_pair, m, i_creatures, i_map);
|
GridType& grid = (*i_map->getNGrid(i_cell.GridX(),i_cell.GridY())) (i_cell.CellX(),i_cell.CellY());
|
||||||
|
LoadHelper(cell_guids.creatures, cell_pair, m, i_creatures, i_map, grid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -199,7 +205,8 @@ ObjectWorldLoader::Visit(CorpseMapType &m)
|
||||||
|
|
||||||
// corpses are always added to spawn mode 0 and they are spawned by their instance id
|
// corpses are always added to spawn mode 0 and they are spawned by their instance id
|
||||||
CellObjectGuids const& cell_guids = sObjectMgr.GetCellObjectGuids(i_map->GetId(), 0, cell_id);
|
CellObjectGuids const& cell_guids = sObjectMgr.GetCellObjectGuids(i_map->GetId(), 0, cell_id);
|
||||||
LoadHelper(cell_guids.corpses, cell_pair, m, i_corpses, i_map);
|
GridType& grid = (*i_map->getNGrid(i_cell.GridX(),i_cell.GridY())) (i_cell.CellX(),i_cell.CellY());
|
||||||
|
LoadHelper(cell_guids.corpses, cell_pair, m, i_corpses, i_map, grid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -929,7 +929,8 @@ void ObjectMgr::LoadEquipmentTemplates()
|
||||||
dbcitem->InventoryType != INVTYPE_WEAPONOFFHAND &&
|
dbcitem->InventoryType != INVTYPE_WEAPONOFFHAND &&
|
||||||
dbcitem->InventoryType != INVTYPE_HOLDABLE &&
|
dbcitem->InventoryType != INVTYPE_HOLDABLE &&
|
||||||
dbcitem->InventoryType != INVTYPE_THROWN &&
|
dbcitem->InventoryType != INVTYPE_THROWN &&
|
||||||
dbcitem->InventoryType != INVTYPE_RANGEDRIGHT)
|
dbcitem->InventoryType != INVTYPE_RANGEDRIGHT &&
|
||||||
|
dbcitem->InventoryType != INVTYPE_RELIC)
|
||||||
{
|
{
|
||||||
sLog.outErrorDb("Item (entry=%u) in creature_equip_template.equipentry%u for entry = %u is not equipable in a hand, forced to 0.", eqInfo->equipentry[j], j+1, i);
|
sLog.outErrorDb("Item (entry=%u) in creature_equip_template.equipentry%u for entry = %u is not equipable in a hand, forced to 0.", eqInfo->equipentry[j], j+1, i);
|
||||||
const_cast<EquipmentInfo*>(eqInfo)->equipentry[j] = 0;
|
const_cast<EquipmentInfo*>(eqInfo)->equipentry[j] = 0;
|
||||||
|
|
|
||||||
|
|
@ -359,7 +359,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
|
||||||
/*0x14A*/ { "SMSG_ATTACKERSTATEUPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
/*0x14A*/ { "SMSG_ATTACKERSTATEUPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||||
/*0x14B*/ { "SMSG_BATTLEFIELD_PORT_DENIED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
/*0x14B*/ { "SMSG_BATTLEFIELD_PORT_DENIED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||||
/*0x14C*/ { "SMSG_DAMAGE_DONE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
/*0x14C*/ { "SMSG_DAMAGE_DONE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||||
/*0x14D*/ { "SMSG_DAMAGE_TAKEN_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
/*0x14D*/ { "SMSG_UNIT_SPELLCAST_START", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||||
/*0x14E*/ { "SMSG_CANCEL_COMBAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
/*0x14E*/ { "SMSG_CANCEL_COMBAT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||||
/*0x14F*/ { "SMSG_SPELLBREAKLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
/*0x14F*/ { "SMSG_SPELLBREAKLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||||
/*0x150*/ { "SMSG_SPELLHEALLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
/*0x150*/ { "SMSG_SPELLHEALLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||||
|
|
@ -568,7 +568,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
|
||||||
/*0x21B*/ { "SMSG_GMTICKET_SYSTEMSTATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
/*0x21B*/ { "SMSG_GMTICKET_SYSTEMSTATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||||
/*0x21C*/ { "CMSG_SPIRIT_HEALER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleSpiritHealerActivateOpcode},
|
/*0x21C*/ { "CMSG_SPIRIT_HEALER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleSpiritHealerActivateOpcode},
|
||||||
/*0x21D*/ { "CMSG_SET_STAT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
|
/*0x21D*/ { "CMSG_SET_STAT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||||
/*0x21E*/ { "SMSG_SET_REST_START_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
/*0x21E*/ { "SMSG_QUEST_FORCE_REMOVE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||||
/*0x21F*/ { "CMSG_SKILL_BUY_STEP", STATUS_NEVER, &WorldSession::Handle_NULL },
|
/*0x21F*/ { "CMSG_SKILL_BUY_STEP", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||||
/*0x220*/ { "CMSG_SKILL_BUY_RANK", STATUS_NEVER, &WorldSession::Handle_NULL },
|
/*0x220*/ { "CMSG_SKILL_BUY_RANK", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||||
/*0x221*/ { "CMSG_XP_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
|
/*0x221*/ { "CMSG_XP_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||||
|
|
@ -1146,8 +1146,8 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
|
||||||
/*0x45D*/ { "CMSG_FORCE_PITCH_RATE_CHANGE_ACK", STATUS_NEVER, &WorldSession::Handle_NULL },
|
/*0x45D*/ { "CMSG_FORCE_PITCH_RATE_CHANGE_ACK", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||||
/*0x45E*/ { "SMSG_SPLINE_SET_PITCH_RATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
/*0x45E*/ { "SMSG_SPLINE_SET_PITCH_RATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||||
/*0x45F*/ { "SMSG_MOVE_ABANDON_TRANSPORT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
/*0x45F*/ { "SMSG_MOVE_ABANDON_TRANSPORT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||||
/*0x460*/ { "MSG_MOVE_ABANDON_TRANSPORT", STATUS_NEVER, &WorldSession::Handle_NULL },
|
/*0x460*/ { "SMSG_CALENDAR_UPDATE_INVITE_LIST", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||||
/*0x461*/ { "CMSG_MOVE_ABANDON_TRANSPORT_ACK", STATUS_NEVER, &WorldSession::Handle_NULL },
|
/*0x461*/ { "SMSG_CALENDAR_UPDATE_INVITE_LIST2", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||||
/*0x462*/ { "CMSG_UPDATE_MISSILE_TRAJECTORY", STATUS_NEVER, &WorldSession::Handle_NULL },
|
/*0x462*/ { "CMSG_UPDATE_MISSILE_TRAJECTORY", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||||
/*0x463*/ { "SMSG_UPDATE_ACCOUNT_DATA_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
/*0x463*/ { "SMSG_UPDATE_ACCOUNT_DATA_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||||
/*0x464*/ { "SMSG_TRIGGER_MOVIE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
/*0x464*/ { "SMSG_TRIGGER_MOVIE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||||
|
|
@ -1163,7 +1163,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
|
||||||
/*0x46E*/ { "CMSG_COMPLETE_ACHIEVEMENT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
|
/*0x46E*/ { "CMSG_COMPLETE_ACHIEVEMENT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||||
/*0x46F*/ { "SMSG_QUESTUPDATE_ADD_PVP_KILL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
/*0x46F*/ { "SMSG_QUESTUPDATE_ADD_PVP_KILL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||||
/*0x470*/ { "CMSG_SET_CRITERIA_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
|
/*0x470*/ { "CMSG_SET_CRITERIA_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||||
/*0x471*/ { "SMSG_GROUP_SWAP_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
/*0x471*/ { "SMSG_CALENDAR_UPDATE_INVITE_LIST3", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||||
/*0x472*/ { "CMSG_UNITANIMTIER_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
|
/*0x472*/ { "CMSG_UNITANIMTIER_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||||
/*0x473*/ { "CMSG_CHAR_CUSTOMIZE", STATUS_AUTHED, &WorldSession::HandleCharCustomize },
|
/*0x473*/ { "CMSG_CHAR_CUSTOMIZE", STATUS_AUTHED, &WorldSession::HandleCharCustomize },
|
||||||
/*0x474*/ { "SMSG_CHAR_CUSTOMIZE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
/*0x474*/ { "SMSG_CHAR_CUSTOMIZE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||||
|
|
@ -1256,13 +1256,13 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
|
||||||
/*0x4CB*/ { "UMSG_UNKNOWN_1227", STATUS_NEVER, &WorldSession::Handle_NULL },
|
/*0x4CB*/ { "UMSG_UNKNOWN_1227", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||||
/*0x4CC*/ { "UMSG_UNKNOWN_1228", STATUS_NEVER, &WorldSession::Handle_NULL },
|
/*0x4CC*/ { "UMSG_UNKNOWN_1228", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||||
/*0x4CD*/ { "SMSG_MULTIPLE_PACKETS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
/*0x4CD*/ { "SMSG_MULTIPLE_PACKETS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||||
/*0x4CE*/ { "SMSG_UNKNOWN_1230", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
/*0x4CE*/ { "SMSG_FORCE_UNK1_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||||
/*0x4CF*/ { "CMSG_UNKNOWN_1231_ACK", STATUS_NEVER, &WorldSession::Handle_NULL },
|
/*0x4CF*/ { "CMSG_FORCE_UNK1_SPEED_CHANGE_ACK", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||||
/*0x4D0*/ { "SMSG_UNKNOWN_1232", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
/*0x4D0*/ { "SMSG_FORCE_UNK2_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||||
/*0x4D1*/ { "CMSG_UNKNOWN_1233_ACK", STATUS_NEVER, &WorldSession::Handle_NULL },
|
/*0x4D1*/ { "CMSG_FORCE_UNK2_SPEED_CHANGE_ACK", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||||
/*0x4D2*/ { "SMSG_UNKNOWN_1234", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
/*0x4D2*/ { "MSG_MOVE_UNKNOWN_1234", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||||
/*0x4D3*/ { "SMSG_UNKNOWN_1235", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
/*0x4D3*/ { "SMSG_SPLINE_MOVE_UNKNOWN_1235", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||||
/*0x4D4*/ { "SMSG_UNKNOWN_1236", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
/*0x4D4*/ { "SMSG_SPLINE_MOVE_UNKNOWN_1236", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||||
/*0x4D5*/ { "CMSG_EQUIPMENT_SET_USE", STATUS_LOGGEDIN, &WorldSession::HandleEquipmentSetUse },
|
/*0x4D5*/ { "CMSG_EQUIPMENT_SET_USE", STATUS_LOGGEDIN, &WorldSession::HandleEquipmentSetUse },
|
||||||
/*0x4D6*/ { "SMSG_EQUIPMENT_SET_USE_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
/*0x4D6*/ { "SMSG_EQUIPMENT_SET_USE_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||||
/*0x4D7*/ { "UMSG_UNKNOWN_1239", STATUS_NEVER, &WorldSession::Handle_NULL },
|
/*0x4D7*/ { "UMSG_UNKNOWN_1239", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||||
|
|
@ -1273,7 +1273,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
|
||||||
/*0x4DC*/ { "UMSG_UNKNOWN_1244", STATUS_NEVER, &WorldSession::Handle_NULL },
|
/*0x4DC*/ { "UMSG_UNKNOWN_1244", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||||
/*0x4DD*/ { "UMSG_UNKNOWN_1245", STATUS_NEVER, &WorldSession::Handle_NULL },
|
/*0x4DD*/ { "UMSG_UNKNOWN_1245", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||||
/*0x4DE*/ { "SMSG_BATTLEFIELD_MGR_ENTRY_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
/*0x4DE*/ { "SMSG_BATTLEFIELD_MGR_ENTRY_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||||
/*0x4DF*/ { "CMSG_BATTLEFIELD_MGR_ENTRY_INVITE_RESPONS", STATUS_NEVER, &WorldSession::Handle_NULL },
|
/*0x4DF*/ { "CMSG_BATTLEFIELD_MGR_ENTRY_INVITE_RESPONSE", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||||
/*0x4E0*/ { "SMSG_BATTLEFIELD_MGR_ENTERED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
/*0x4E0*/ { "SMSG_BATTLEFIELD_MGR_ENTERED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||||
/*0x4E1*/ { "SMSG_BATTLEFIELD_MGR_QUEUE_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
/*0x4E1*/ { "SMSG_BATTLEFIELD_MGR_QUEUE_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||||
/*0x4E2*/ { "CMSG_BATTLEFIELD_MGR_QUEUE_INVITE_RESPONSE", STATUS_NEVER, &WorldSession::Handle_NULL },
|
/*0x4E2*/ { "CMSG_BATTLEFIELD_MGR_QUEUE_INVITE_RESPONSE", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||||
|
|
|
||||||
|
|
@ -1242,7 +1242,7 @@ enum Opcodes
|
||||||
SMSG_ITEM_REFUND_RESULT = 0x4B5, // refund item result
|
SMSG_ITEM_REFUND_RESULT = 0x4B5, // refund item result
|
||||||
CMSG_CORPSE_MAP_POSITION_QUERY = 0x4B6, // CMSG, uint32
|
CMSG_CORPSE_MAP_POSITION_QUERY = 0x4B6, // CMSG, uint32
|
||||||
SMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE = 0x4B7, // SMSG, 3*float+float
|
SMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE = 0x4B7, // SMSG, 3*float+float
|
||||||
UMSG_UNKNOWN_1208 = 0x4B8, // not found
|
CMSG_LFG_SET_ROLES_2 = 0x4B8, // not found
|
||||||
UMSG_UNKNOWN_1209 = 0x4B9, // not found
|
UMSG_UNKNOWN_1209 = 0x4B9, // not found
|
||||||
CMSG_CALENDAR_CONTEXT_EVENT_SIGNUP = 0x4BA, // CMSG, uint64, lua: CalendarContextEventSignUp
|
CMSG_CALENDAR_CONTEXT_EVENT_SIGNUP = 0x4BA, // CMSG, uint64, lua: CalendarContextEventSignUp
|
||||||
SMSG_CALENDAR_ACTION_PENDING = 0x4BB, // SMSG, calendar related EVENT_CALENDAR_ACTION_PENDING
|
SMSG_CALENDAR_ACTION_PENDING = 0x4BB, // SMSG, calendar related EVENT_CALENDAR_ACTION_PENDING
|
||||||
|
|
|
||||||
|
|
@ -1313,7 +1313,7 @@ bool Pet::addSpell(uint32 spell_id,ActiveStates active /*= ACT_DECIDE*/, PetSpel
|
||||||
|
|
||||||
if(active == ACT_DECIDE) //active was not used before, so we save it's autocast/passive state here
|
if(active == ACT_DECIDE) //active was not used before, so we save it's autocast/passive state here
|
||||||
{
|
{
|
||||||
if(IsPassiveSpell(spell_id))
|
if(IsPassiveSpell(spellInfo))
|
||||||
newspell.active = ACT_PASSIVE;
|
newspell.active = ACT_PASSIVE;
|
||||||
else
|
else
|
||||||
newspell.active = ACT_DISABLED;
|
newspell.active = ACT_DISABLED;
|
||||||
|
|
@ -1369,7 +1369,7 @@ bool Pet::addSpell(uint32 spell_id,ActiveStates active /*= ACT_DECIDE*/, PetSpel
|
||||||
|
|
||||||
m_spells[spell_id] = newspell;
|
m_spells[spell_id] = newspell;
|
||||||
|
|
||||||
if (IsPassiveSpell(spell_id))
|
if (IsPassiveSpell(spellInfo))
|
||||||
CastSpell(this, spell_id, true);
|
CastSpell(this, spell_id, true);
|
||||||
else
|
else
|
||||||
m_charmInfo->AddSpellToActionBar(spell_id, ActiveStates(newspell.active));
|
m_charmInfo->AddSpellToActionBar(spell_id, ActiveStates(newspell.active));
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
|
||||||
{
|
{
|
||||||
case COMMAND_STAY: //flat=1792 //STAY
|
case COMMAND_STAY: //flat=1792 //STAY
|
||||||
pet->StopMoving();
|
pet->StopMoving();
|
||||||
pet->GetMotionMaster()->Clear();
|
pet->GetMotionMaster()->Clear(false);
|
||||||
pet->GetMotionMaster()->MoveIdle();
|
pet->GetMotionMaster()->MoveIdle();
|
||||||
charmInfo->SetCommandState( COMMAND_STAY );
|
charmInfo->SetCommandState( COMMAND_STAY );
|
||||||
break;
|
break;
|
||||||
|
|
@ -191,7 +191,7 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
|
||||||
}
|
}
|
||||||
|
|
||||||
// do not cast not learned spells
|
// do not cast not learned spells
|
||||||
if(!pet->HasSpell(spellid) || IsPassiveSpell(spellid))
|
if(!pet->HasSpell(spellid) || IsPassiveSpell(spellInfo))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pet->clearUnitState(UNIT_STAT_MOVING);
|
pet->clearUnitState(UNIT_STAT_MOVING);
|
||||||
|
|
@ -626,7 +626,7 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
|
||||||
}
|
}
|
||||||
|
|
||||||
// do not cast not learned spells
|
// do not cast not learned spells
|
||||||
if (!pet->HasSpell(spellid) || IsPassiveSpell(spellid))
|
if (!pet->HasSpell(spellid) || IsPassiveSpell(spellInfo))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SpellCastTargets targets;
|
SpellCastTargets targets;
|
||||||
|
|
|
||||||
|
|
@ -405,7 +405,7 @@ void TradeData::SetAccepted(bool state, bool crosssend /*= false*/)
|
||||||
|
|
||||||
UpdateMask Player::updateVisualBits;
|
UpdateMask Player::updateVisualBits;
|
||||||
|
|
||||||
Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputationMgr(this)
|
Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputationMgr(this), m_mover(this), m_camera(this)
|
||||||
{
|
{
|
||||||
m_transport = 0;
|
m_transport = 0;
|
||||||
|
|
||||||
|
|
@ -417,6 +417,8 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa
|
||||||
|
|
||||||
m_valuesCount = PLAYER_END;
|
m_valuesCount = PLAYER_END;
|
||||||
|
|
||||||
|
m_isActiveObject = true; // player is always active object
|
||||||
|
|
||||||
m_session = session;
|
m_session = session;
|
||||||
|
|
||||||
m_divider = 0;
|
m_divider = 0;
|
||||||
|
|
@ -478,6 +480,7 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa
|
||||||
m_DelayedOperations = 0;
|
m_DelayedOperations = 0;
|
||||||
m_bCanDelayTeleport = false;
|
m_bCanDelayTeleport = false;
|
||||||
m_bHasDelayedTeleport = false;
|
m_bHasDelayedTeleport = false;
|
||||||
|
m_bHasBeenAliveAtDelayedTeleport = true; // overwrite always at setup teleport data, so not used infact
|
||||||
m_teleport_options = 0;
|
m_teleport_options = 0;
|
||||||
|
|
||||||
m_trade = NULL;
|
m_trade = NULL;
|
||||||
|
|
@ -584,8 +587,6 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa
|
||||||
m_summon_y = 0.0f;
|
m_summon_y = 0.0f;
|
||||||
m_summon_z = 0.0f;
|
m_summon_z = 0.0f;
|
||||||
|
|
||||||
m_mover = this;
|
|
||||||
|
|
||||||
m_miniPet = 0;
|
m_miniPet = 0;
|
||||||
m_contestedPvPTimer = 0;
|
m_contestedPvPTimer = 0;
|
||||||
|
|
||||||
|
|
@ -1474,9 +1475,7 @@ void Player::Update( uint32 p_time )
|
||||||
RemovePet(pet, PET_SAVE_NOT_IN_SLOT, true);
|
RemovePet(pet, PET_SAVE_NOT_IN_SLOT, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//we should execute delayed teleports only for alive(!) players
|
if (IsHasDelayedTeleport())
|
||||||
//because we don't want player's ghost teleported from graveyard
|
|
||||||
if(IsHasDelayedTeleport() && isAlive())
|
|
||||||
TeleportTo(m_teleport_dest, m_teleport_options);
|
TeleportTo(m_teleport_dest, m_teleport_options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1775,10 +1774,9 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
|
||||||
//lets reset far teleport flag if it wasn't reset during chained teleports
|
//lets reset far teleport flag if it wasn't reset during chained teleports
|
||||||
SetSemaphoreTeleportFar(false);
|
SetSemaphoreTeleportFar(false);
|
||||||
//setup delayed teleport flag
|
//setup delayed teleport flag
|
||||||
SetDelayedTeleportFlag(IsCanDelayTeleport());
|
|
||||||
//if teleport spell is casted in Unit::Update() func
|
//if teleport spell is casted in Unit::Update() func
|
||||||
//then we need to delay it until update process will be finished
|
//then we need to delay it until update process will be finished
|
||||||
if(IsHasDelayedTeleport())
|
if (SetDelayedTeleportFlagIfCan())
|
||||||
{
|
{
|
||||||
SetSemaphoreTeleportNear(true);
|
SetSemaphoreTeleportNear(true);
|
||||||
//lets save teleport destination for player
|
//lets save teleport destination for player
|
||||||
|
|
@ -1794,7 +1792,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
|
||||||
UnsummonPetTemporaryIfAny();
|
UnsummonPetTemporaryIfAny();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(options & TELE_TO_NOT_LEAVE_COMBAT))
|
if (!(options & TELE_TO_NOT_LEAVE_COMBAT))
|
||||||
CombatStop();
|
CombatStop();
|
||||||
|
|
||||||
// this will be used instead of the current location in SaveToDB
|
// this will be used instead of the current location in SaveToDB
|
||||||
|
|
@ -1831,10 +1829,9 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
|
||||||
//lets reset near teleport flag if it wasn't reset during chained teleports
|
//lets reset near teleport flag if it wasn't reset during chained teleports
|
||||||
SetSemaphoreTeleportNear(false);
|
SetSemaphoreTeleportNear(false);
|
||||||
//setup delayed teleport flag
|
//setup delayed teleport flag
|
||||||
SetDelayedTeleportFlag(IsCanDelayTeleport());
|
|
||||||
//if teleport spell is casted in Unit::Update() func
|
//if teleport spell is casted in Unit::Update() func
|
||||||
//then we need to delay it until update process will be finished
|
//then we need to delay it until update process will be finished
|
||||||
if(IsHasDelayedTeleport())
|
if (SetDelayedTeleportFlagIfCan())
|
||||||
{
|
{
|
||||||
SetSemaphoreTeleportFar(true);
|
SetSemaphoreTeleportFar(true);
|
||||||
//lets save teleport destination for player
|
//lets save teleport destination for player
|
||||||
|
|
@ -1850,7 +1847,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
|
||||||
ResetContestedPvP();
|
ResetContestedPvP();
|
||||||
|
|
||||||
// remove player from battleground on far teleport (when changing maps)
|
// remove player from battleground on far teleport (when changing maps)
|
||||||
if(BattleGround const* bg = GetBattleGround())
|
if (BattleGround const* bg = GetBattleGround())
|
||||||
{
|
{
|
||||||
// Note: at battleground join battleground id set before teleport
|
// Note: at battleground join battleground id set before teleport
|
||||||
// and we already will found "current" battleground
|
// and we already will found "current" battleground
|
||||||
|
|
@ -1868,14 +1865,14 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
|
||||||
|
|
||||||
// stop spellcasting
|
// stop spellcasting
|
||||||
// not attempt interrupt teleportation spell at caster teleport
|
// not attempt interrupt teleportation spell at caster teleport
|
||||||
if(!(options & TELE_TO_SPELL))
|
if (!(options & TELE_TO_SPELL))
|
||||||
if(IsNonMeleeSpellCasted(true))
|
if (IsNonMeleeSpellCasted(true))
|
||||||
InterruptNonMeleeSpells(true);
|
InterruptNonMeleeSpells(true);
|
||||||
|
|
||||||
//remove auras before removing from map...
|
//remove auras before removing from map...
|
||||||
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CHANGE_MAP | AURA_INTERRUPT_FLAG_MOVE | AURA_INTERRUPT_FLAG_TURNING);
|
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CHANGE_MAP | AURA_INTERRUPT_FLAG_MOVE | AURA_INTERRUPT_FLAG_TURNING);
|
||||||
|
|
||||||
if(!GetSession()->PlayerLogout())
|
if (!GetSession()->PlayerLogout())
|
||||||
{
|
{
|
||||||
// send transfer packets
|
// send transfer packets
|
||||||
WorldPacket data(SMSG_TRANSFER_PENDING, (4+4+4));
|
WorldPacket data(SMSG_TRANSFER_PENDING, (4+4+4));
|
||||||
|
|
@ -1909,7 +1906,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove from old map now
|
// remove from old map now
|
||||||
if(oldmap)
|
if (oldmap)
|
||||||
oldmap->Remove(this, false);
|
oldmap->Remove(this, false);
|
||||||
|
|
||||||
// new final coordinates
|
// new final coordinates
|
||||||
|
|
@ -1918,7 +1915,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
|
||||||
float final_z = z;
|
float final_z = z;
|
||||||
float final_o = orientation;
|
float final_o = orientation;
|
||||||
|
|
||||||
if(m_transport)
|
if (m_transport)
|
||||||
{
|
{
|
||||||
final_x += m_movementInfo.GetTransportPos()->x;
|
final_x += m_movementInfo.GetTransportPos()->x;
|
||||||
final_y += m_movementInfo.GetTransportPos()->y;
|
final_y += m_movementInfo.GetTransportPos()->y;
|
||||||
|
|
@ -2236,7 +2233,7 @@ Creature* Player::GetNPCIfCanInteractWith(ObjectGuid guid, uint32 npcflagmask)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// not in interactive state
|
// not in interactive state
|
||||||
if (hasUnitState(UNIT_STAT_CAN_NOT_REACT))
|
if (hasUnitState(UNIT_STAT_CAN_NOT_REACT_OR_LOST_CONTROL))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// exist (we need look pets also for some interaction (quest/etc)
|
// exist (we need look pets also for some interaction (quest/etc)
|
||||||
|
|
@ -2290,7 +2287,7 @@ GameObject* Player::GetGameObjectIfCanInteractWith(ObjectGuid guid, uint32 gameo
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// not in interactive state
|
// not in interactive state
|
||||||
if (hasUnitState(UNIT_STAT_CAN_NOT_REACT))
|
if (hasUnitState(UNIT_STAT_CAN_NOT_REACT_OR_LOST_CONTROL))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (GameObject *go = GetMap()->GetGameObject(guid))
|
if (GameObject *go = GetMap()->GetGameObject(guid))
|
||||||
|
|
@ -2409,7 +2406,8 @@ void Player::SetGameMaster(bool on)
|
||||||
getHostileRefManager().setOnlineOfflineState(true);
|
getHostileRefManager().setOnlineOfflineState(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateVisibilityForPlayer();
|
m_camera.UpdateVisibilityForOwner();
|
||||||
|
UpdateObjectVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::SetGMVisible(bool on)
|
void Player::SetGMVisible(bool on)
|
||||||
|
|
@ -3062,7 +3060,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
||||||
|
|
||||||
if(active)
|
if(active)
|
||||||
{
|
{
|
||||||
if (IsPassiveSpell(spell_id) && IsNeedCastPassiveSpellAtLearn(spellInfo))
|
if (IsPassiveSpell(spellInfo) && IsNeedCastPassiveSpellAtLearn(spellInfo))
|
||||||
CastSpell (this, spell_id, true);
|
CastSpell (this, spell_id, true);
|
||||||
}
|
}
|
||||||
else if(IsInWorld())
|
else if(IsInWorld())
|
||||||
|
|
@ -3253,7 +3251,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
||||||
CastSpell(this, spell_id, true);
|
CastSpell(this, spell_id, true);
|
||||||
}
|
}
|
||||||
// also cast passive spells (including all talents without SPELL_EFFECT_LEARN_SPELL) with additional checks
|
// also cast passive spells (including all talents without SPELL_EFFECT_LEARN_SPELL) with additional checks
|
||||||
else if (IsPassiveSpell(spell_id))
|
else if (IsPassiveSpell(spellInfo))
|
||||||
{
|
{
|
||||||
if (IsNeedCastPassiveSpellAtLearn(spellInfo))
|
if (IsNeedCastPassiveSpellAtLearn(spellInfo))
|
||||||
CastSpell(this, spell_id, true);
|
CastSpell(this, spell_id, true);
|
||||||
|
|
@ -4490,8 +4488,10 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
|
||||||
GetZoneAndAreaId(newzone,newarea);
|
GetZoneAndAreaId(newzone,newarea);
|
||||||
UpdateZone(newzone,newarea);
|
UpdateZone(newzone,newarea);
|
||||||
|
|
||||||
// update visibility
|
// update visibility of world around viewpoint
|
||||||
UpdateVisibilityForPlayer();
|
m_camera.UpdateVisibilityForOwner();
|
||||||
|
// update visibility of player for nearby cameras
|
||||||
|
UpdateObjectVisibility();
|
||||||
|
|
||||||
if(!applySickness)
|
if(!applySickness)
|
||||||
return;
|
return;
|
||||||
|
|
@ -6073,42 +6073,30 @@ void Player::SaveRecallPosition()
|
||||||
|
|
||||||
void Player::SendMessageToSet(WorldPacket *data, bool self)
|
void Player::SendMessageToSet(WorldPacket *data, bool self)
|
||||||
{
|
{
|
||||||
Map * _map = IsInWorld() ? GetMap() : sMapMgr.FindMap(GetMapId(), GetInstanceId());
|
if (Map * _map = IsInWorld() ? GetMap() : sMapMgr.FindMap(GetMapId(), GetInstanceId()))
|
||||||
if(_map)
|
_map->MessageBroadcast(this, data, false);
|
||||||
{
|
|
||||||
_map->MessageBroadcast(this, data, self);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if player is not in world and map in not created/already destroyed
|
//if player is not in world and map in not created/already destroyed
|
||||||
//no need to create one, just send packet for itself!
|
//no need to create one, just send packet for itself!
|
||||||
if(self)
|
if (self)
|
||||||
GetSession()->SendPacket(data);
|
GetSession()->SendPacket(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::SendMessageToSetInRange(WorldPacket *data, float dist, bool self)
|
void Player::SendMessageToSetInRange(WorldPacket *data, float dist, bool self)
|
||||||
{
|
{
|
||||||
Map * _map = IsInWorld() ? GetMap() : sMapMgr.FindMap(GetMapId(), GetInstanceId());
|
if (Map * _map = IsInWorld() ? GetMap() : sMapMgr.FindMap(GetMapId(), GetInstanceId()))
|
||||||
if(_map)
|
_map->MessageDistBroadcast(this, data, dist, false);
|
||||||
{
|
|
||||||
_map->MessageDistBroadcast(this, data, dist, self);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(self)
|
if (self)
|
||||||
GetSession()->SendPacket(data);
|
GetSession()->SendPacket(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::SendMessageToSetInRange(WorldPacket *data, float dist, bool self, bool own_team_only)
|
void Player::SendMessageToSetInRange(WorldPacket *data, float dist, bool self, bool own_team_only)
|
||||||
{
|
{
|
||||||
Map * _map = IsInWorld() ? GetMap() : sMapMgr.FindMap(GetMapId(), GetInstanceId());
|
if (Map * _map = IsInWorld() ? GetMap() : sMapMgr.FindMap(GetMapId(), GetInstanceId()))
|
||||||
if(_map)
|
_map->MessageDistBroadcast(this, data, dist, false, own_team_only);
|
||||||
{
|
|
||||||
_map->MessageDistBroadcast(this, data, dist, self, own_team_only);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(self)
|
if (self)
|
||||||
GetSession()->SendPacket(data);
|
GetSession()->SendPacket(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -13547,10 +13535,6 @@ void Player::IncompleteQuest( uint32 quest_id )
|
||||||
|
|
||||||
void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver, bool announce )
|
void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver, bool announce )
|
||||||
{
|
{
|
||||||
//this THING should be here to protect code from quest, which cast on player far teleport as a reward
|
|
||||||
//should work fine, cause far teleport will be executed in Player::Update()
|
|
||||||
SetCanDelayTeleport(true);
|
|
||||||
|
|
||||||
uint32 quest_id = pQuest->GetQuestId();
|
uint32 quest_id = pQuest->GetQuestId();
|
||||||
|
|
||||||
for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i )
|
for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i )
|
||||||
|
|
@ -13702,9 +13686,6 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver
|
||||||
if (!HasAura(itr->second->spellId, EFFECT_INDEX_0))
|
if (!HasAura(itr->second->spellId, EFFECT_INDEX_0))
|
||||||
CastSpell(this,itr->second->spellId,true);
|
CastSpell(this,itr->second->spellId,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//lets remove flag for delayed teleports
|
|
||||||
SetCanDelayTeleport(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::FailQuest(uint32 questId)
|
void Player::FailQuest(uint32 questId)
|
||||||
|
|
@ -15322,7 +15303,8 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
||||||
SetCreatorGUID(0);
|
SetCreatorGUID(0);
|
||||||
|
|
||||||
// reset some aura modifiers before aura apply
|
// reset some aura modifiers before aura apply
|
||||||
SetFarSightGUID(0);
|
|
||||||
|
SetUInt64Value(PLAYER_FARSIGHT, 0);
|
||||||
SetUInt32Value(PLAYER_TRACK_CREATURES, 0 );
|
SetUInt32Value(PLAYER_TRACK_CREATURES, 0 );
|
||||||
SetUInt32Value(PLAYER_TRACK_RESOURCES, 0 );
|
SetUInt32Value(PLAYER_TRACK_RESOURCES, 0 );
|
||||||
|
|
||||||
|
|
@ -17605,7 +17587,7 @@ void Player::RemoveMiniPet()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Pet* Player::GetMiniPet()
|
Pet* Player::GetMiniPet() const
|
||||||
{
|
{
|
||||||
if (!m_miniPet)
|
if (!m_miniPet)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -18058,7 +18040,7 @@ void Player::HandleStealthedUnitsDetection()
|
||||||
MaNGOS::UnitListSearcher<MaNGOS::AnyStealthedCheck > searcher(this,stealthedUnits, u_check);
|
MaNGOS::UnitListSearcher<MaNGOS::AnyStealthedCheck > searcher(this,stealthedUnits, u_check);
|
||||||
Cell::VisitAllObjects(this, searcher, MAX_PLAYER_STEALTH_DETECT_RANGE);
|
Cell::VisitAllObjects(this, searcher, MAX_PLAYER_STEALTH_DETECT_RANGE);
|
||||||
|
|
||||||
WorldObject const* viewPoint = GetViewPoint();
|
WorldObject const* viewPoint = GetCamera().GetBody();
|
||||||
|
|
||||||
for (std::list<Unit*>::const_iterator i = stealthedUnits.begin(); i != stealthedUnits.end(); ++i)
|
for (std::list<Unit*>::const_iterator i = stealthedUnits.begin(); i != stealthedUnits.end(); ++i)
|
||||||
{
|
{
|
||||||
|
|
@ -19154,17 +19136,6 @@ void Player::ReportedAfkBy(Player* reporter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WorldObject const* Player::GetViewPoint() const
|
|
||||||
{
|
|
||||||
if(uint64 far_sight = GetFarSight())
|
|
||||||
{
|
|
||||||
WorldObject const* viewPoint = GetMap()->GetWorldObject(far_sight);
|
|
||||||
return viewPoint ? viewPoint : this; // always expected not NULL
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Player::IsVisibleInGridForPlayer( Player* pl ) const
|
bool Player::IsVisibleInGridForPlayer( Player* pl ) const
|
||||||
{
|
{
|
||||||
// gamemaster in GM mode see all, including ghosts
|
// gamemaster in GM mode see all, including ghosts
|
||||||
|
|
@ -19461,7 +19432,7 @@ void Player::SendInitialPacketsBeforeAddToMap()
|
||||||
if(HasAuraType(SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED) || HasAuraType(SPELL_AURA_FLY) || isInFlight())
|
if(HasAuraType(SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED) || HasAuraType(SPELL_AURA_FLY) || isInFlight())
|
||||||
m_movementInfo.AddMovementFlag(MOVEFLAG_FLYING);
|
m_movementInfo.AddMovementFlag(MOVEFLAG_FLYING);
|
||||||
|
|
||||||
m_mover = this;
|
SetMover(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::SendInitialPacketsAfterAddToMap()
|
void Player::SendInitialPacketsAfterAddToMap()
|
||||||
|
|
@ -20736,7 +20707,7 @@ void Player::EnterVehicle(Vehicle *vehicle)
|
||||||
vehicle->setFaction(getFaction());
|
vehicle->setFaction(getFaction());
|
||||||
|
|
||||||
SetCharm(vehicle); // charm
|
SetCharm(vehicle); // charm
|
||||||
SetFarSightGUID(vehicle->GetGUID()); // set view
|
m_camera.SetView(vehicle); // set view
|
||||||
|
|
||||||
SetClientControl(vehicle, 1); // redirect controls to vehicle
|
SetClientControl(vehicle, 1); // redirect controls to vehicle
|
||||||
SetMover(vehicle);
|
SetMover(vehicle);
|
||||||
|
|
@ -20788,7 +20759,7 @@ void Player::ExitVehicle(Vehicle *vehicle)
|
||||||
vehicle->setFaction((GetTeam() == ALLIANCE) ? vehicle->GetCreatureInfo()->faction_A : vehicle->GetCreatureInfo()->faction_H);
|
vehicle->setFaction((GetTeam() == ALLIANCE) ? vehicle->GetCreatureInfo()->faction_A : vehicle->GetCreatureInfo()->faction_H);
|
||||||
|
|
||||||
SetCharm(NULL);
|
SetCharm(NULL);
|
||||||
SetFarSightGUID(0);
|
m_camera.ResetView();
|
||||||
|
|
||||||
SetClientControl(vehicle, 0);
|
SetClientControl(vehicle, 0);
|
||||||
SetMover(NULL);
|
SetMover(NULL);
|
||||||
|
|
@ -21230,6 +21201,23 @@ void Player::UpdateAchievementCriteria( AchievementCriteriaTypes type, uint32 mi
|
||||||
GetAchievementMgr().UpdateAchievementCriteria(type, miscvalue1,miscvalue2,unit,time);
|
GetAchievementMgr().UpdateAchievementCriteria(type, miscvalue1,miscvalue2,unit,time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PlayerTalent const* Player::GetKnownTalentById(int32 talentId) const
|
||||||
|
{
|
||||||
|
PlayerTalentMap::const_iterator itr = m_talents[m_activeSpec].find(talentId);
|
||||||
|
if (itr != m_talents[m_activeSpec].end() && itr->second.state != PLAYERSPELL_REMOVED)
|
||||||
|
return &itr->second;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SpellEntry const* Player::GetKnownTalentRankById(int32 talentId) const
|
||||||
|
{
|
||||||
|
if (PlayerTalent const* talent = GetKnownTalentById(talentId))
|
||||||
|
return sSpellStore.LookupEntry(talent->m_talentEntry->RankID[talent->currentRank]);
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void Player::LearnTalent(uint32 talentId, uint32 talentRank)
|
void Player::LearnTalent(uint32 talentId, uint32 talentRank)
|
||||||
{
|
{
|
||||||
uint32 CurTalentPoints = GetFreeTalentPoints();
|
uint32 CurTalentPoints = GetFreeTalentPoints();
|
||||||
|
|
@ -21256,9 +21244,8 @@ void Player::LearnTalent(uint32 talentId, uint32 talentRank)
|
||||||
|
|
||||||
// find current max talent rank
|
// find current max talent rank
|
||||||
uint32 curtalent_maxrank = 0;
|
uint32 curtalent_maxrank = 0;
|
||||||
PlayerTalentMap::iterator itr = m_talents[m_activeSpec].find(talentId);
|
if (PlayerTalent const* talent = GetKnownTalentById(talentId))
|
||||||
if (itr != m_talents[m_activeSpec].end() && itr->second.state != PLAYERSPELL_REMOVED)
|
curtalent_maxrank = talent->currentRank + 1;
|
||||||
curtalent_maxrank = itr->second.currentRank + 1;
|
|
||||||
|
|
||||||
// we already have same or higher talent rank learned
|
// we already have same or higher talent rank learned
|
||||||
if(curtalent_maxrank >= (talentRank + 1))
|
if(curtalent_maxrank >= (talentRank + 1))
|
||||||
|
|
@ -21894,17 +21881,16 @@ void Player::ActivateSpec(uint8 specNum)
|
||||||
|
|
||||||
// learn talent spells if they not in new spec (old spec copy)
|
// learn talent spells if they not in new spec (old spec copy)
|
||||||
// and if they have different rank
|
// and if they have different rank
|
||||||
PlayerTalentMap::iterator specIter = m_talents[m_activeSpec].find(tempIter->first);
|
if (PlayerTalent const* cur_talent = GetKnownTalentById(tempIter->first))
|
||||||
if (specIter != m_talents[m_activeSpec].end() && specIter->second.state != PLAYERSPELL_REMOVED)
|
|
||||||
{
|
{
|
||||||
if ((*specIter).second.currentRank != talent.currentRank)
|
if (cur_talent->currentRank != talent.currentRank)
|
||||||
learnSpell(talentSpellId, false);
|
learnSpell(talentSpellId, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
learnSpell(talentSpellId, false);
|
learnSpell(talentSpellId, false);
|
||||||
|
|
||||||
// sync states - original state is changed in addSpell that learnSpell calls
|
// sync states - original state is changed in addSpell that learnSpell calls
|
||||||
specIter = m_talents[m_activeSpec].find(tempIter->first);
|
PlayerTalentMap::iterator specIter = m_talents[m_activeSpec].find(tempIter->first);
|
||||||
if (specIter != m_talents[m_activeSpec].end())
|
if (specIter != m_talents[m_activeSpec].end())
|
||||||
(*specIter).second.state = talent.state;
|
(*specIter).second.state = talent.state;
|
||||||
else
|
else
|
||||||
|
|
@ -21925,11 +21911,20 @@ void Player::ActivateSpec(uint8 specNum)
|
||||||
|
|
||||||
// recheck action buttons (not checked at loading/spec copy)
|
// recheck action buttons (not checked at loading/spec copy)
|
||||||
ActionButtonList const& currentActionButtonList = m_actionButtons[m_activeSpec];
|
ActionButtonList const& currentActionButtonList = m_actionButtons[m_activeSpec];
|
||||||
for(ActionButtonList::const_iterator itr = currentActionButtonList.begin(); itr != currentActionButtonList.end(); ++itr)
|
for(ActionButtonList::const_iterator itr = currentActionButtonList.begin(); itr != currentActionButtonList.end(); )
|
||||||
|
{
|
||||||
if (itr->second.uState != ACTIONBUTTON_DELETED)
|
if (itr->second.uState != ACTIONBUTTON_DELETED)
|
||||||
|
{
|
||||||
// remove broken without any output (it can be not correct because talents not copied at spec creating)
|
// remove broken without any output (it can be not correct because talents not copied at spec creating)
|
||||||
if (!IsActionButtonDataValid(itr->first,itr->second.GetAction(),itr->second.GetType(), this, false))
|
if (!IsActionButtonDataValid(itr->first,itr->second.GetAction(),itr->second.GetType(), this, false))
|
||||||
|
{
|
||||||
removeActionButton(m_activeSpec,itr->first);
|
removeActionButton(m_activeSpec,itr->first);
|
||||||
|
itr = currentActionButtonList.begin();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++itr;
|
||||||
|
}
|
||||||
|
|
||||||
ResummonPetTemporaryUnSummonedIfAny();
|
ResummonPetTemporaryUnSummonedIfAny();
|
||||||
|
|
||||||
|
|
@ -22022,38 +22017,6 @@ bool Player::HasMovementFlag( MovementFlags f ) const
|
||||||
return m_movementInfo.HasMovementFlag(f);
|
return m_movementInfo.HasMovementFlag(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::SetFarSightGUID( uint64 guid )
|
|
||||||
{
|
|
||||||
if(GetFarSight() == guid)
|
|
||||||
return;
|
|
||||||
|
|
||||||
SetUInt64Value(PLAYER_FARSIGHT, guid);
|
|
||||||
|
|
||||||
// need triggering load grids around new view point
|
|
||||||
UpdateVisibilityForPlayer();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Player::UpdateVisibilityForPlayer()
|
|
||||||
{
|
|
||||||
WorldObject const* viewPoint = GetViewPoint();
|
|
||||||
Map* m = GetMap();
|
|
||||||
|
|
||||||
CellPair p(MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY()));
|
|
||||||
Cell cell(p);
|
|
||||||
|
|
||||||
m->UpdateObjectVisibility(this, cell, p);
|
|
||||||
|
|
||||||
if (this != viewPoint)
|
|
||||||
{
|
|
||||||
CellPair pView(MaNGOS::ComputeCellPair(viewPoint->GetPositionX(), viewPoint->GetPositionY()));
|
|
||||||
Cell cellView(pView);
|
|
||||||
|
|
||||||
m->UpdateObjectsVisibilityFor(this, cellView, pView);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m->UpdateObjectsVisibilityFor(this, cell, p);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Player::ResetTimeSync()
|
void Player::ResetTimeSync()
|
||||||
{
|
{
|
||||||
m_timeSyncCounter = 0;
|
m_timeSyncCounter = 0;
|
||||||
|
|
|
||||||
|
|
@ -1128,8 +1128,6 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
Creature* GetNPCIfCanInteractWith(ObjectGuid guid, uint32 npcflagmask);
|
Creature* GetNPCIfCanInteractWith(ObjectGuid guid, uint32 npcflagmask);
|
||||||
GameObject* GetGameObjectIfCanInteractWith(ObjectGuid guid, uint32 gameobject_type = MAX_GAMEOBJECT_TYPE) const;
|
GameObject* GetGameObjectIfCanInteractWith(ObjectGuid guid, uint32 gameobject_type = MAX_GAMEOBJECT_TYPE) const;
|
||||||
|
|
||||||
void UpdateVisibilityForPlayer();
|
|
||||||
|
|
||||||
bool ToggleAFK();
|
bool ToggleAFK();
|
||||||
bool ToggleDND();
|
bool ToggleDND();
|
||||||
bool isAFK() const { return HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_AFK); }
|
bool isAFK() const { return HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_AFK); }
|
||||||
|
|
@ -1191,7 +1189,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
|
|
||||||
void RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent = false);
|
void RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent = false);
|
||||||
void RemoveMiniPet();
|
void RemoveMiniPet();
|
||||||
Pet* GetMiniPet();
|
Pet* GetMiniPet() const;
|
||||||
void SetMiniPet(Pet* pet) { m_miniPet = pet->GetGUID(); }
|
void SetMiniPet(Pet* pet) { m_miniPet = pet->GetGUID(); }
|
||||||
|
|
||||||
template<typename Func>
|
template<typename Func>
|
||||||
|
|
@ -1666,6 +1664,9 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
|
|
||||||
SpellCooldowns const& GetSpellCooldownMap() const { return m_spellCooldowns; }
|
SpellCooldowns const& GetSpellCooldownMap() const { return m_spellCooldowns; }
|
||||||
|
|
||||||
|
PlayerTalent const* GetKnownTalentById(int32 talentId) const;
|
||||||
|
SpellEntry const* GetKnownTalentRankById(int32 talentId) const;
|
||||||
|
|
||||||
void AddSpellMod(SpellModifier* mod, bool apply);
|
void AddSpellMod(SpellModifier* mod, bool apply);
|
||||||
bool IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mod, Spell const* spell = NULL);
|
bool IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mod, Spell const* spell = NULL);
|
||||||
template <class T> T ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell const* spell = NULL);
|
template <class T> T ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell const* spell = NULL);
|
||||||
|
|
@ -2191,7 +2192,6 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
/*********************************************************/
|
/*********************************************************/
|
||||||
bool HasMovementFlag(MovementFlags f) const; // for script access to m_movementInfo.HasMovementFlag
|
bool HasMovementFlag(MovementFlags f) const; // for script access to m_movementInfo.HasMovementFlag
|
||||||
void UpdateFallInformationIfNeed(MovementInfo const& minfo,uint16 opcode);
|
void UpdateFallInformationIfNeed(MovementInfo const& minfo,uint16 opcode);
|
||||||
Unit *m_mover;
|
|
||||||
void SetFallInformation(uint32 time, float z)
|
void SetFallInformation(uint32 time, float z)
|
||||||
{
|
{
|
||||||
m_lastFallTime = time;
|
m_lastFallTime = time;
|
||||||
|
|
@ -2210,12 +2210,13 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
|
|
||||||
void SetClientControl(Unit* target, uint8 allowMove);
|
void SetClientControl(Unit* target, uint8 allowMove);
|
||||||
void SetMover(Unit* target) { m_mover = target ? target : this; }
|
void SetMover(Unit* target) { m_mover = target ? target : this; }
|
||||||
|
Unit* GetMover() const { return m_mover; }
|
||||||
|
bool IsSelfMover() const { return m_mover == this; }// normal case for player not controlling other unit
|
||||||
|
|
||||||
void EnterVehicle(Vehicle *vehicle);
|
void EnterVehicle(Vehicle *vehicle);
|
||||||
void ExitVehicle(Vehicle *vehicle);
|
void ExitVehicle(Vehicle *vehicle);
|
||||||
|
|
||||||
uint64 GetFarSight() const { return GetUInt64Value(PLAYER_FARSIGHT); }
|
ObjectGuid const& GetFarSightGuid() const { return GetGuidValue(PLAYER_FARSIGHT); }
|
||||||
void SetFarSightGUID(uint64 guid);
|
|
||||||
|
|
||||||
// Transports
|
// Transports
|
||||||
Transport * GetTransport() const { return m_transport; }
|
Transport * GetTransport() const { return m_transport; }
|
||||||
|
|
@ -2250,7 +2251,6 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
|
|
||||||
bool HaveAtClient(WorldObject const* u) { return u==this || m_clientGUIDs.find(u->GetGUID())!=m_clientGUIDs.end(); }
|
bool HaveAtClient(WorldObject const* u) { return u==this || m_clientGUIDs.find(u->GetGUID())!=m_clientGUIDs.end(); }
|
||||||
|
|
||||||
WorldObject const* GetViewPoint() const;
|
|
||||||
bool IsVisibleInGridForPlayer(Player* pl) const;
|
bool IsVisibleInGridForPlayer(Player* pl) const;
|
||||||
bool IsVisibleGloballyFor(Player* pl) const;
|
bool IsVisibleGloballyFor(Player* pl) const;
|
||||||
|
|
||||||
|
|
@ -2262,6 +2262,8 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
// Stealth detection system
|
// Stealth detection system
|
||||||
void HandleStealthedUnitsDetection();
|
void HandleStealthedUnitsDetection();
|
||||||
|
|
||||||
|
Camera& GetCamera() { return m_camera; }
|
||||||
|
|
||||||
uint8 m_forced_speed_changes[MAX_MOVE_TYPE];
|
uint8 m_forced_speed_changes[MAX_MOVE_TYPE];
|
||||||
|
|
||||||
bool HasAtLoginFlag(AtLoginFlags f) const { return m_atLoginFlags & f; }
|
bool HasAtLoginFlag(AtLoginFlags f) const { return m_atLoginFlags & f; }
|
||||||
|
|
@ -2353,7 +2355,6 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
bool HasTitle(CharTitlesEntry const* title) { return HasTitle(title->bit_index); }
|
bool HasTitle(CharTitlesEntry const* title) { return HasTitle(title->bit_index); }
|
||||||
void SetTitle(CharTitlesEntry const* title, bool lost = false);
|
void SetTitle(CharTitlesEntry const* title, bool lost = false);
|
||||||
|
|
||||||
bool isActiveObject() const { return true; }
|
|
||||||
bool canSeeSpellClickOn(Creature const* creature) const;
|
bool canSeeSpellClickOn(Creature const* creature) const;
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
@ -2592,17 +2593,30 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
int32 CalculateReputationGain(uint32 creatureOrQuestLevel, int32 rep, int32 faction, bool for_quest);
|
int32 CalculateReputationGain(uint32 creatureOrQuestLevel, int32 rep, int32 faction, bool for_quest);
|
||||||
void AdjustQuestReqItemCount( Quest const* pQuest, QuestStatusData& questStatusData );
|
void AdjustQuestReqItemCount( Quest const* pQuest, QuestStatusData& questStatusData );
|
||||||
|
|
||||||
bool IsCanDelayTeleport() const { return m_bCanDelayTeleport; }
|
|
||||||
void SetCanDelayTeleport(bool setting) { m_bCanDelayTeleport = setting; }
|
void SetCanDelayTeleport(bool setting) { m_bCanDelayTeleport = setting; }
|
||||||
bool IsHasDelayedTeleport() const { return m_bHasDelayedTeleport; }
|
bool IsHasDelayedTeleport() const
|
||||||
void SetDelayedTeleportFlag(bool setting) { m_bHasDelayedTeleport = setting; }
|
{
|
||||||
|
// we should not execute delayed teleports for now dead players but has been alive at teleport
|
||||||
|
// because we don't want player's ghost teleported from graveyard
|
||||||
|
return m_bHasDelayedTeleport && (isAlive() || !m_bHasBeenAliveAtDelayedTeleport);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SetDelayedTeleportFlagIfCan()
|
||||||
|
{
|
||||||
|
m_bHasDelayedTeleport = m_bCanDelayTeleport;
|
||||||
|
m_bHasBeenAliveAtDelayedTeleport = isAlive();
|
||||||
|
return m_bHasDelayedTeleport;
|
||||||
|
}
|
||||||
|
|
||||||
void ScheduleDelayedOperation(uint32 operation)
|
void ScheduleDelayedOperation(uint32 operation)
|
||||||
{
|
{
|
||||||
if(operation < DELAYED_END)
|
if (operation < DELAYED_END)
|
||||||
m_DelayedOperations |= operation;
|
m_DelayedOperations |= operation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Unit *m_mover;
|
||||||
|
Camera m_camera;
|
||||||
|
|
||||||
GridReference<Player> m_gridRef;
|
GridReference<Player> m_gridRef;
|
||||||
MapReference m_mapRef;
|
MapReference m_mapRef;
|
||||||
|
|
||||||
|
|
@ -2630,6 +2644,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
uint32 m_DelayedOperations;
|
uint32 m_DelayedOperations;
|
||||||
bool m_bCanDelayTeleport;
|
bool m_bCanDelayTeleport;
|
||||||
bool m_bHasDelayedTeleport;
|
bool m_bHasDelayedTeleport;
|
||||||
|
bool m_bHasBeenAliveAtDelayedTeleport;
|
||||||
|
|
||||||
uint32 m_DetectInvTimer;
|
uint32 m_DetectInvTimer;
|
||||||
|
|
||||||
|
|
@ -2710,7 +2725,7 @@ template<typename Func>
|
||||||
bool Player::CheckAllControlledUnits(Func const& func, bool withTotems, bool withGuardians, bool withCharms, bool withMiniPet) const
|
bool Player::CheckAllControlledUnits(Func const& func, bool withTotems, bool withGuardians, bool withCharms, bool withMiniPet) const
|
||||||
{
|
{
|
||||||
if (withMiniPet)
|
if (withMiniPet)
|
||||||
if(Unit* mini = GetMiniPet())
|
if(Unit const* mini = GetMiniPet())
|
||||||
if (func(mini))
|
if (func(mini))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,30 @@ void SpawnedPoolData::RemoveSpawn<Pool>(uint32 sub_pool_id, uint32 pool_id)
|
||||||
--val;
|
--val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// Methods of class PoolObject
|
||||||
|
template<>
|
||||||
|
void PoolObject::CheckEventLinkAndReport<Creature>(uint32 poolId, int16 event_id, std::map<uint32, int16> const& creature2event, std::map<uint32, int16> const& /*go2event*/) const
|
||||||
|
{
|
||||||
|
std::map<uint32, int16>::const_iterator itr = creature2event.find(guid);
|
||||||
|
if (itr == creature2event.end() || itr->second != event_id)
|
||||||
|
sLog.outErrorDb("Creature (GUID: %u) expected to be listed in `game_event_creature` for event %u as part pool %u", guid, event_id, poolId);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void PoolObject::CheckEventLinkAndReport<GameObject>(uint32 poolId, int16 event_id, std::map<uint32, int16> const& /*creature2event*/, std::map<uint32, int16> const& go2event) const
|
||||||
|
{
|
||||||
|
std::map<uint32, int16>::const_iterator itr = go2event.find(guid);
|
||||||
|
if (itr == go2event.end() || itr->second != event_id)
|
||||||
|
sLog.outErrorDb("Gameobject (GUID: %u) expected to be listed in `game_event_gameobject` for event %u as part pool %u", guid, event_id, poolId);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void PoolObject::CheckEventLinkAndReport<Pool>(uint32 poolId, int16 event_id, std::map<uint32, int16> const& creature2event, std::map<uint32, int16> const& go2event) const
|
||||||
|
{
|
||||||
|
sPoolMgr.CheckEventLinkAndReport(guid, event_id, creature2event, go2event);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Methods of template class PoolGroup
|
// Methods of template class PoolGroup
|
||||||
|
|
||||||
|
|
@ -134,6 +158,40 @@ bool PoolGroup<T>::CheckPool() const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method to check event linking
|
||||||
|
template <class T>
|
||||||
|
void PoolGroup<T>::CheckEventLinkAndReport(int16 event_id, std::map<uint32, int16> const& creature2event, std::map<uint32, int16> const& go2event) const
|
||||||
|
{
|
||||||
|
for (uint32 i=0; i < EqualChanced.size(); ++i)
|
||||||
|
EqualChanced[i].CheckEventLinkAndReport<T>(poolId, event_id, creature2event, go2event);
|
||||||
|
|
||||||
|
for (uint32 i=0; i<ExplicitlyChanced.size(); ++i)
|
||||||
|
ExplicitlyChanced[i].CheckEventLinkAndReport<T>(poolId, event_id, creature2event, go2event);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void PoolGroup<T>::SetExcludeObject(uint32 guid, bool state)
|
||||||
|
{
|
||||||
|
for (uint32 i=0; i < EqualChanced.size(); ++i)
|
||||||
|
{
|
||||||
|
if (EqualChanced[i].guid == guid)
|
||||||
|
{
|
||||||
|
EqualChanced[i].exclude = state;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32 i=0; i<ExplicitlyChanced.size(); ++i)
|
||||||
|
{
|
||||||
|
if (ExplicitlyChanced[i].guid == guid)
|
||||||
|
{
|
||||||
|
ExplicitlyChanced[i].exclude = state;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
PoolObject* PoolGroup<T>::RollOne(SpawnedPoolData& spawns, uint32 triggerFrom)
|
PoolObject* PoolGroup<T>::RollOne(SpawnedPoolData& spawns, uint32 triggerFrom)
|
||||||
{
|
{
|
||||||
|
|
@ -146,7 +204,7 @@ PoolObject* PoolGroup<T>::RollOne(SpawnedPoolData& spawns, uint32 triggerFrom)
|
||||||
roll -= ExplicitlyChanced[i].chance;
|
roll -= ExplicitlyChanced[i].chance;
|
||||||
// Triggering object is marked as spawned at this time and can be also rolled (respawn case)
|
// Triggering object is marked as spawned at this time and can be also rolled (respawn case)
|
||||||
// so this need explicit check for this case
|
// so this need explicit check for this case
|
||||||
if (roll < 0 && (ExplicitlyChanced[i].guid == triggerFrom || !spawns.IsSpawnedObject<T>(ExplicitlyChanced[i].guid)))
|
if (roll < 0 && !ExplicitlyChanced[i].exclude && (ExplicitlyChanced[i].guid == triggerFrom || !spawns.IsSpawnedObject<T>(ExplicitlyChanced[i].guid)))
|
||||||
return &ExplicitlyChanced[i];
|
return &ExplicitlyChanced[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -156,7 +214,7 @@ PoolObject* PoolGroup<T>::RollOne(SpawnedPoolData& spawns, uint32 triggerFrom)
|
||||||
int32 index = irand(0, EqualChanced.size()-1);
|
int32 index = irand(0, EqualChanced.size()-1);
|
||||||
// Triggering object is marked as spawned at this time and can be also rolled (respawn case)
|
// Triggering object is marked as spawned at this time and can be also rolled (respawn case)
|
||||||
// so this need explicit check for this case
|
// so this need explicit check for this case
|
||||||
if (EqualChanced[index].guid == triggerFrom || !spawns.IsSpawnedObject<T>(EqualChanced[index].guid))
|
if (!EqualChanced[index].exclude && (EqualChanced[index].guid == triggerFrom || !spawns.IsSpawnedObject<T>(EqualChanced[index].guid)))
|
||||||
return &EqualChanced[index];
|
return &EqualChanced[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -263,7 +321,12 @@ void PoolGroup<T>::SpawnObject(SpawnedPoolData& spawns, uint32 limit, uint32 tri
|
||||||
// and also counted into m_SpawnedPoolAmount so we need increase count to be
|
// and also counted into m_SpawnedPoolAmount so we need increase count to be
|
||||||
// spawned by 1
|
// spawned by 1
|
||||||
if (triggerFrom)
|
if (triggerFrom)
|
||||||
++count;
|
{
|
||||||
|
if (spawns.IsSpawnedObject<T>(triggerFrom))
|
||||||
|
++count;
|
||||||
|
else
|
||||||
|
triggerFrom = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// This will try to spawn the rest of pool, not guaranteed
|
// This will try to spawn the rest of pool, not guaranteed
|
||||||
for (int i = 0; i < count; ++i)
|
for (int i = 0; i < count; ++i)
|
||||||
|
|
@ -462,6 +525,7 @@ void PoolManager::LoadFromDB()
|
||||||
|
|
||||||
PoolTemplateData& pPoolTemplate = mPoolTemplate[pool_id];
|
PoolTemplateData& pPoolTemplate = mPoolTemplate[pool_id];
|
||||||
pPoolTemplate.MaxLimit = fields[1].GetUInt32();
|
pPoolTemplate.MaxLimit = fields[1].GetUInt32();
|
||||||
|
pPoolTemplate.AutoSpawn = true; // will update and later data loading
|
||||||
|
|
||||||
} while (result->NextRow());
|
} while (result->NextRow());
|
||||||
|
|
||||||
|
|
@ -661,6 +725,9 @@ void PoolManager::LoadFromDB()
|
||||||
SearchPair p(child_pool_id, mother_pool_id);
|
SearchPair p(child_pool_id, mother_pool_id);
|
||||||
mPoolSearchMap.insert(p);
|
mPoolSearchMap.insert(p);
|
||||||
|
|
||||||
|
// update top independent pool flag
|
||||||
|
mPoolTemplate[child_pool_id].AutoSpawn = false;
|
||||||
|
|
||||||
} while( result->NextRow() );
|
} while( result->NextRow() );
|
||||||
|
|
||||||
// Now check for circular reference
|
// Now check for circular reference
|
||||||
|
|
@ -692,17 +759,15 @@ void PoolManager::LoadFromDB()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The initialize method will spawn all pools not in an event and not in another pool, this is why there is 2 left joins with 2 null checks
|
// The initialize method will spawn all pools not in an event and not in another pool
|
||||||
void PoolManager::Initialize()
|
void PoolManager::Initialize()
|
||||||
{
|
{
|
||||||
QueryResult *result = WorldDatabase.Query("SELECT DISTINCT pool_template.entry FROM pool_template LEFT JOIN game_event_pool ON pool_template.entry=game_event_pool.pool_entry LEFT JOIN pool_pool ON pool_template.entry=pool_pool.pool_id WHERE game_event_pool.pool_entry IS NULL AND pool_pool.pool_id IS NULL");
|
uint32 count = 0;
|
||||||
uint32 count=0;
|
|
||||||
if (result)
|
for(uint16 pool_entry = 0; pool_entry < mPoolTemplate.size(); ++pool_entry)
|
||||||
{
|
{
|
||||||
do
|
if (mPoolTemplate[pool_entry].AutoSpawn)
|
||||||
{
|
{
|
||||||
Field *fields = result->Fetch();
|
|
||||||
uint16 pool_entry = fields[0].GetUInt16();
|
|
||||||
if (!CheckPool(pool_entry))
|
if (!CheckPool(pool_entry))
|
||||||
{
|
{
|
||||||
sLog.outErrorDb("Pool Id (%u) has all creatures or gameobjects with explicit chance sum <>100 and no equal chance defined. The pool system cannot pick one to spawn.", pool_entry);
|
sLog.outErrorDb("Pool Id (%u) has all creatures or gameobjects with explicit chance sum <>100 and no equal chance defined. The pool system cannot pick one to spawn.", pool_entry);
|
||||||
|
|
@ -710,8 +775,7 @@ void PoolManager::Initialize()
|
||||||
}
|
}
|
||||||
SpawnPool(pool_entry, true);
|
SpawnPool(pool_entry, true);
|
||||||
count++;
|
count++;
|
||||||
} while (result->NextRow());
|
}
|
||||||
delete result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BASIC_LOG("Pool handling system initialized, %u pools spawned.", count);
|
BASIC_LOG("Pool handling system initialized, %u pools spawned.", count);
|
||||||
|
|
@ -775,6 +839,27 @@ bool PoolManager::CheckPool(uint16 pool_id) const
|
||||||
mPoolPoolGroups[pool_id].CheckPool();
|
mPoolPoolGroups[pool_id].CheckPool();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method that check linking all elements to event
|
||||||
|
void PoolManager::CheckEventLinkAndReport(uint16 pool_id, int16 event_id, std::map<uint32, int16> const& creature2event, std::map<uint32, int16> const& go2event) const
|
||||||
|
{
|
||||||
|
mPoolGameobjectGroups[pool_id].CheckEventLinkAndReport(event_id, creature2event, go2event);
|
||||||
|
mPoolCreatureGroups[pool_id].CheckEventLinkAndReport(event_id, creature2event, go2event);
|
||||||
|
mPoolPoolGroups[pool_id].CheckEventLinkAndReport(event_id, creature2event, go2event);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method that exclude some elements from next spawn
|
||||||
|
template<>
|
||||||
|
void PoolManager::SetExcludeObject<Creature>(uint16 pool_id, uint32 db_guid_or_pool_id, bool state)
|
||||||
|
{
|
||||||
|
mPoolCreatureGroups[pool_id].SetExcludeObject(db_guid_or_pool_id, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void PoolManager::SetExcludeObject<GameObject>(uint16 pool_id, uint32 db_guid_or_pool_id, bool state)
|
||||||
|
{
|
||||||
|
mPoolGameobjectGroups[pool_id].SetExcludeObject(db_guid_or_pool_id, state);
|
||||||
|
}
|
||||||
|
|
||||||
// Call to update the pool when a gameobject/creature part of pool [pool_id] is ready to respawn
|
// Call to update the pool when a gameobject/creature part of pool [pool_id] is ready to respawn
|
||||||
// Here we cache only the creature/gameobject whose guid is passed as parameter
|
// Here we cache only the creature/gameobject whose guid is passed as parameter
|
||||||
// Then the spawn pool call will use this cache to decide
|
// Then the spawn pool call will use this cache to decide
|
||||||
|
|
|
||||||
|
|
@ -27,13 +27,19 @@
|
||||||
struct PoolTemplateData
|
struct PoolTemplateData
|
||||||
{
|
{
|
||||||
uint32 MaxLimit;
|
uint32 MaxLimit;
|
||||||
|
bool AutoSpawn; // spawn at pool system start (not part of another pool and not part of event spawn)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PoolObject
|
struct PoolObject
|
||||||
{
|
{
|
||||||
uint32 guid;
|
uint32 guid;
|
||||||
float chance;
|
float chance;
|
||||||
PoolObject(uint32 _guid, float _chance): guid(_guid), chance(fabs(_chance)) {}
|
bool exclude;
|
||||||
|
|
||||||
|
PoolObject(uint32 _guid, float _chance): guid(_guid), chance(fabs(_chance)), exclude(false) {}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void CheckEventLinkAndReport(uint32 poolId, int16 event_id, std::map<uint32, int16> const& creature2event, std::map<uint32, int16> const& go2event) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Pool // for Pool of Pool case
|
class Pool // for Pool of Pool case
|
||||||
|
|
@ -73,10 +79,12 @@ class PoolGroup
|
||||||
bool isEmpty() const { return ExplicitlyChanced.empty() && EqualChanced.empty(); }
|
bool isEmpty() const { return ExplicitlyChanced.empty() && EqualChanced.empty(); }
|
||||||
void AddEntry(PoolObject& poolitem, uint32 maxentries);
|
void AddEntry(PoolObject& poolitem, uint32 maxentries);
|
||||||
bool CheckPool() const;
|
bool CheckPool() const;
|
||||||
|
void CheckEventLinkAndReport(int16 event_id, std::map<uint32, int16> const& creature2event, std::map<uint32, int16> const& go2event) const;
|
||||||
PoolObject* RollOne(SpawnedPoolData& spawns, uint32 triggerFrom);
|
PoolObject* RollOne(SpawnedPoolData& spawns, uint32 triggerFrom);
|
||||||
void DespawnObject(SpawnedPoolData& spawns, uint32 guid=0);
|
void DespawnObject(SpawnedPoolData& spawns, uint32 guid=0);
|
||||||
void Despawn1Object(uint32 guid);
|
void Despawn1Object(uint32 guid);
|
||||||
void SpawnObject(SpawnedPoolData& spawns, uint32 limit, uint32 triggerFrom, bool instantly);
|
void SpawnObject(SpawnedPoolData& spawns, uint32 limit, uint32 triggerFrom, bool instantly);
|
||||||
|
void SetExcludeObject(uint32 guid, bool state);
|
||||||
|
|
||||||
void Spawn1Object(PoolObject* obj, bool instantly);
|
void Spawn1Object(PoolObject* obj, bool instantly);
|
||||||
void ReSpawn1Object(PoolObject* obj);
|
void ReSpawn1Object(PoolObject* obj);
|
||||||
|
|
@ -99,17 +107,37 @@ class PoolManager
|
||||||
template<typename T>
|
template<typename T>
|
||||||
uint16 IsPartOfAPool(uint32 db_guid_or_pool_id) const;
|
uint16 IsPartOfAPool(uint32 db_guid_or_pool_id) const;
|
||||||
|
|
||||||
|
// Method that tell if the creature/gameobject/pool is part of top level pool and return the pool id if yes
|
||||||
|
template<typename T>
|
||||||
|
uint16 IsPartOfTopPool(uint32 db_guid_or_pool_id) const
|
||||||
|
{
|
||||||
|
if (uint16 pool_id = IsPartOfAPool<T>(db_guid_or_pool_id))
|
||||||
|
{
|
||||||
|
if (uint16 top_pool_id = IsPartOfTopPool<Pool>(pool_id))
|
||||||
|
return top_pool_id;
|
||||||
|
|
||||||
|
return pool_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool IsSpawnedObject(uint32 db_guid_or_pool_id) const { return mSpawnedData.IsSpawnedObject<T>(db_guid_or_pool_id); }
|
bool IsSpawnedObject(uint32 db_guid_or_pool_id) const { return mSpawnedData.IsSpawnedObject<T>(db_guid_or_pool_id); }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void SetExcludeObject(uint16 pool_id, uint32 db_guid_or_pool_id, bool state);
|
||||||
|
|
||||||
bool CheckPool(uint16 pool_id) const;
|
bool CheckPool(uint16 pool_id) const;
|
||||||
|
void CheckEventLinkAndReport(uint16 pool_id, int16 event_id, std::map<uint32, int16> const& creature2event, std::map<uint32, int16> const& go2event) const;
|
||||||
|
|
||||||
void SpawnPool(uint16 pool_id, bool instantly);
|
void SpawnPool(uint16 pool_id, bool instantly);
|
||||||
void DespawnPool(uint16 pool_id);
|
void DespawnPool(uint16 pool_id);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void UpdatePool(uint16 pool_id, uint32 db_guid_or_pool_id);
|
void UpdatePool(uint16 pool_id, uint32 db_guid_or_pool_id = 0);
|
||||||
|
|
||||||
|
void RemoveAutoSpawnForPool(uint16 pool_id) { mPoolTemplate[pool_id].AutoSpawn = false; }
|
||||||
protected:
|
protected:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void SpawnPoolGroup(uint16 pool_id, uint32 db_guid_or_pool_id, bool instantly);
|
void SpawnPoolGroup(uint16 pool_id, uint32 db_guid_or_pool_id, bool instantly);
|
||||||
|
|
|
||||||
|
|
@ -4253,21 +4253,11 @@ SpellCastResult Spell::CheckCast(bool strict)
|
||||||
|
|
||||||
// auto selection spell rank implemented in WorldSession::HandleCastSpellOpcode
|
// auto selection spell rank implemented in WorldSession::HandleCastSpellOpcode
|
||||||
// this case can be triggered if rank not found (too low-level target for first rank)
|
// this case can be triggered if rank not found (too low-level target for first rank)
|
||||||
if (m_caster->GetTypeId() == TYPEID_PLAYER && !IsPassiveSpell(m_spellInfo->Id) && !m_CastItem)
|
if (m_caster->GetTypeId() == TYPEID_PLAYER && !m_CastItem && !m_IsTriggeredSpell)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < MAX_EFFECT_INDEX; ++i)
|
// spell expected to be auto-downranking in cast handle, so must be same
|
||||||
{
|
if (m_spellInfo != sSpellMgr.SelectAuraRankForLevel(m_spellInfo, target->getLevel()))
|
||||||
// check only spell that apply positive auras
|
return SPELL_FAILED_LOWLEVEL;
|
||||||
if (m_spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA &&
|
|
||||||
IsPositiveEffect(m_spellInfo->Id, SpellEffectIndex(i)) &&
|
|
||||||
// at not self target
|
|
||||||
!IsCasterSourceTarget(m_spellInfo->EffectImplicitTargetA[i]) &&
|
|
||||||
// and target low level
|
|
||||||
target->getLevel() + 10 < m_spellInfo->spellLevel)
|
|
||||||
{
|
|
||||||
return SPELL_FAILED_LOWLEVEL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_caster == target)
|
else if (m_caster == target)
|
||||||
|
|
@ -4448,7 +4438,7 @@ SpellCastResult Spell::CheckCast(bool strict)
|
||||||
|
|
||||||
// not let players cast spells at mount (and let do it to creatures)
|
// not let players cast spells at mount (and let do it to creatures)
|
||||||
if (m_caster->IsMounted() && m_caster->GetTypeId()==TYPEID_PLAYER && !m_IsTriggeredSpell &&
|
if (m_caster->IsMounted() && m_caster->GetTypeId()==TYPEID_PLAYER && !m_IsTriggeredSpell &&
|
||||||
!IsPassiveSpell(m_spellInfo->Id) && !(m_spellInfo->Attributes & SPELL_ATTR_CASTABLE_WHILE_MOUNTED))
|
!IsPassiveSpell(m_spellInfo) && !(m_spellInfo->Attributes & SPELL_ATTR_CASTABLE_WHILE_MOUNTED))
|
||||||
{
|
{
|
||||||
if (m_caster->isInFlight())
|
if (m_caster->isInFlight())
|
||||||
return SPELL_FAILED_NOT_ON_TAXI;
|
return SPELL_FAILED_NOT_ON_TAXI;
|
||||||
|
|
@ -4457,7 +4447,7 @@ SpellCastResult Spell::CheckCast(bool strict)
|
||||||
}
|
}
|
||||||
|
|
||||||
// always (except passive spells) check items (focus object can be required for any type casts)
|
// always (except passive spells) check items (focus object can be required for any type casts)
|
||||||
if (!IsPassiveSpell(m_spellInfo->Id))
|
if (!IsPassiveSpell(m_spellInfo))
|
||||||
{
|
{
|
||||||
SpellCastResult castResult = CheckItems();
|
SpellCastResult castResult = CheckItems();
|
||||||
if(castResult != SPELL_CAST_OK)
|
if(castResult != SPELL_CAST_OK)
|
||||||
|
|
|
||||||
|
|
@ -23,11 +23,14 @@
|
||||||
#include "SharedDefines.h"
|
#include "SharedDefines.h"
|
||||||
#include "DBCEnums.h"
|
#include "DBCEnums.h"
|
||||||
#include "ObjectGuid.h"
|
#include "ObjectGuid.h"
|
||||||
|
#include "LootMgr.h"
|
||||||
|
#include "Unit.h"
|
||||||
|
#include "Player.h"
|
||||||
|
|
||||||
class WorldSession;
|
class WorldSession;
|
||||||
class Unit;
|
class WorldPacket;
|
||||||
class DynamicObj;
|
class DynamicObj;
|
||||||
class Player;
|
class Item;
|
||||||
class GameObject;
|
class GameObject;
|
||||||
class Group;
|
class Group;
|
||||||
class Aura;
|
class Aura;
|
||||||
|
|
@ -808,6 +811,7 @@ namespace MaNGOS
|
||||||
template<> inline void Visit(CorpseMapType & ) {}
|
template<> inline void Visit(CorpseMapType & ) {}
|
||||||
template<> inline void Visit(GameObjectMapType & ) {}
|
template<> inline void Visit(GameObjectMapType & ) {}
|
||||||
template<> inline void Visit(DynamicObjectMapType & ) {}
|
template<> inline void Visit(DynamicObjectMapType & ) {}
|
||||||
|
template<> inline void Visit(CameraMapType & ) {}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -815,6 +819,7 @@ namespace MaNGOS
|
||||||
template<> inline void SpellNotifierCreatureAndPlayer::Visit(CorpseMapType& ) {}
|
template<> inline void SpellNotifierCreatureAndPlayer::Visit(CorpseMapType& ) {}
|
||||||
template<> inline void SpellNotifierCreatureAndPlayer::Visit(GameObjectMapType& ) {}
|
template<> inline void SpellNotifierCreatureAndPlayer::Visit(GameObjectMapType& ) {}
|
||||||
template<> inline void SpellNotifierCreatureAndPlayer::Visit(DynamicObjectMapType& ) {}
|
template<> inline void SpellNotifierCreatureAndPlayer::Visit(DynamicObjectMapType& ) {}
|
||||||
|
template<> inline void SpellNotifierCreatureAndPlayer::Visit(CameraMapType& ) {}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -386,7 +386,7 @@ m_isRemovedOnShapeLost(true), m_in_use(0), m_deleted(false)
|
||||||
|
|
||||||
m_currentBasePoints = currentBasePoints ? *currentBasePoints : m_spellProto->CalculateSimpleValue(eff);
|
m_currentBasePoints = currentBasePoints ? *currentBasePoints : m_spellProto->CalculateSimpleValue(eff);
|
||||||
|
|
||||||
m_isPassive = IsPassiveSpell(GetId());
|
m_isPassive = IsPassiveSpell(GetSpellProto());
|
||||||
m_positive = IsPositiveEffect(GetId(), m_effIndex);
|
m_positive = IsPositiveEffect(GetId(), m_effIndex);
|
||||||
|
|
||||||
m_isSingleTargetAura = IsSingleTargetSpell(m_spellProto);
|
m_isSingleTargetAura = IsSingleTargetSpell(m_spellProto);
|
||||||
|
|
@ -633,7 +633,7 @@ void Aura::Update(uint32 diff)
|
||||||
Unit* caster = GetCaster();
|
Unit* caster = GetCaster();
|
||||||
if(!caster)
|
if(!caster)
|
||||||
{
|
{
|
||||||
m_target->RemoveAura(GetId(), GetEffIndex());
|
m_target->RemoveAurasByCasterSpell(GetId(), GetEffIndex(), GetCasterGUID());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -648,7 +648,7 @@ void Aura::Update(uint32 diff)
|
||||||
|
|
||||||
if(!caster->IsWithinDistInMap(m_target, max_range))
|
if(!caster->IsWithinDistInMap(m_target, max_range))
|
||||||
{
|
{
|
||||||
m_target->RemoveAura(GetId(), GetEffIndex());
|
m_target->RemoveAurasByCasterSpell(GetId(), GetEffIndex(), GetCasterGUID());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -813,7 +813,7 @@ void AreaAura::Update(uint32 diff)
|
||||||
if(!apply)
|
if(!apply)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(SpellEntry const *actualSpellInfo = sSpellMgr.SelectAuraRankForPlayerLevel(GetSpellProto(), (*tIter)->getLevel()))
|
if(SpellEntry const *actualSpellInfo = sSpellMgr.SelectAuraRankForLevel(GetSpellProto(), (*tIter)->getLevel()))
|
||||||
{
|
{
|
||||||
int32 actualBasePoints = m_currentBasePoints;
|
int32 actualBasePoints = m_currentBasePoints;
|
||||||
// recalculate basepoints for lower rank (all AreaAura spell not use custom basepoints?)
|
// recalculate basepoints for lower rank (all AreaAura spell not use custom basepoints?)
|
||||||
|
|
@ -2380,7 +2380,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
|
||||||
(GetSpellProto()->EffectApplyAuraName[EFFECT_INDEX_0] == 1 || GetSpellProto()->EffectApplyAuraName[EFFECT_INDEX_0] == 128)))
|
(GetSpellProto()->EffectApplyAuraName[EFFECT_INDEX_0] == 1 || GetSpellProto()->EffectApplyAuraName[EFFECT_INDEX_0] == 128)))
|
||||||
{
|
{
|
||||||
// spells with SpellEffect=72 and aura=4: 6196, 6197, 21171, 21425
|
// spells with SpellEffect=72 and aura=4: 6196, 6197, 21171, 21425
|
||||||
((Player*)target)->SetFarSightGUID(0);
|
((Player*)target)->GetCamera().ResetView();
|
||||||
WorldPacket data(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, 0);
|
WorldPacket data(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, 0);
|
||||||
((Player*)target)->GetSession()->SendPacket(&data);
|
((Player*)target)->GetSession()->SendPacket(&data);
|
||||||
return;
|
return;
|
||||||
|
|
@ -3543,7 +3543,11 @@ void Aura::HandleBindSight(bool apply, bool /*Real*/)
|
||||||
if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
|
if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
((Player*)caster)->SetFarSightGUID(apply ? GetTarget()->GetGUID() : 0);
|
Camera& camera = ((Player*)caster)->GetCamera();
|
||||||
|
if (apply)
|
||||||
|
camera.SetView(m_target);
|
||||||
|
else
|
||||||
|
camera.ResetView();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Aura::HandleFarSight(bool apply, bool /*Real*/)
|
void Aura::HandleFarSight(bool apply, bool /*Real*/)
|
||||||
|
|
@ -3552,7 +3556,11 @@ void Aura::HandleFarSight(bool apply, bool /*Real*/)
|
||||||
if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
|
if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
((Player*)caster)->SetFarSightGUID(apply ? GetTarget()->GetGUID() : 0);
|
Camera& camera = ((Player*)caster)->GetCamera();
|
||||||
|
if (apply)
|
||||||
|
camera.SetView(GetTarget());
|
||||||
|
else
|
||||||
|
camera.ResetView();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Aura::HandleAuraTrackCreatures(bool apply, bool /*Real*/)
|
void Aura::HandleAuraTrackCreatures(bool apply, bool /*Real*/)
|
||||||
|
|
@ -3607,10 +3615,12 @@ void Aura::HandleModPossess(bool apply, bool Real)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Player* p_caster = (Player*)caster;
|
Player* p_caster = (Player*)caster;
|
||||||
|
Camera& camera = p_caster->GetCamera();
|
||||||
|
|
||||||
if( apply )
|
if( apply )
|
||||||
{
|
{
|
||||||
|
target->addUnitState(UNIT_STAT_CONTROLLED);
|
||||||
|
|
||||||
target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
|
target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
|
||||||
|
|
||||||
target->SetCharmerGUID(p_caster->GetGUID());
|
target->SetCharmerGUID(p_caster->GetGUID());
|
||||||
|
|
@ -3618,35 +3628,39 @@ void Aura::HandleModPossess(bool apply, bool Real)
|
||||||
|
|
||||||
p_caster->SetCharm(target);
|
p_caster->SetCharm(target);
|
||||||
|
|
||||||
p_caster->SetFarSightGUID(target->GetGUID());
|
camera.SetView(target);
|
||||||
p_caster->SetClientControl(target, 1);
|
p_caster->SetClientControl(target, 1);
|
||||||
p_caster->SetMover(target);
|
p_caster->SetMover(target);
|
||||||
|
|
||||||
target->CombatStop();
|
target->CombatStop(true);
|
||||||
target->DeleteThreatList();
|
target->DeleteThreatList();
|
||||||
|
target->getHostileRefManager().deleteReferences();
|
||||||
|
|
||||||
|
if(CharmInfo *charmInfo = target->InitCharmInfo(target))
|
||||||
|
{
|
||||||
|
charmInfo->InitPossessCreateSpells();
|
||||||
|
charmInfo->SetReactState(REACT_PASSIVE);
|
||||||
|
charmInfo->SetCommandState(COMMAND_STAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
p_caster->PossessSpellInitialize();
|
||||||
|
|
||||||
if(target->GetTypeId() == TYPEID_UNIT)
|
if(target->GetTypeId() == TYPEID_UNIT)
|
||||||
{
|
{
|
||||||
target->StopMoving();
|
((Creature*)target)->AIM_Initialize();
|
||||||
target->GetMotionMaster()->Clear();
|
|
||||||
target->GetMotionMaster()->MoveIdle();
|
|
||||||
}
|
}
|
||||||
else if(target->GetTypeId() == TYPEID_PLAYER)
|
else if(target->GetTypeId() == TYPEID_PLAYER)
|
||||||
{
|
{
|
||||||
((Player*)target)->SetClientControl(target, 0);
|
((Player*)target)->SetClientControl(target, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(CharmInfo *charmInfo = target->InitCharmInfo(target))
|
|
||||||
charmInfo->InitPossessCreateSpells();
|
|
||||||
|
|
||||||
p_caster->PossessSpellInitialize();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
p_caster->InterruptSpell(CURRENT_CHANNELED_SPELL); // the spell is not automatically canceled when interrupted, do it now
|
p_caster->InterruptSpell(CURRENT_CHANNELED_SPELL); // the spell is not automatically canceled when interrupted, do it now
|
||||||
p_caster->SetCharm(NULL);
|
p_caster->SetCharm(NULL);
|
||||||
|
|
||||||
p_caster->SetFarSightGUID(0);
|
camera.ResetView();
|
||||||
p_caster->SetClientControl(target, 0);
|
p_caster->SetClientControl(target, 0);
|
||||||
p_caster->SetMover(NULL);
|
p_caster->SetMover(NULL);
|
||||||
|
|
||||||
|
|
@ -3656,6 +3670,12 @@ void Aura::HandleModPossess(bool apply, bool Real)
|
||||||
if(m_removeMode == AURA_REMOVE_BY_DELETE)
|
if(m_removeMode == AURA_REMOVE_BY_DELETE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
target->clearUnitState(UNIT_STAT_CONTROLLED);
|
||||||
|
|
||||||
|
target->CombatStop(true);
|
||||||
|
target->DeleteThreatList();
|
||||||
|
target->getHostileRefManager().deleteReferences();
|
||||||
|
|
||||||
target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
|
target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
|
||||||
|
|
||||||
target->SetCharmerGUID(0);
|
target->SetCharmerGUID(0);
|
||||||
|
|
@ -3690,30 +3710,40 @@ void Aura::HandleModPossessPet(bool apply, bool Real)
|
||||||
if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
|
if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Pet *pet = caster->GetPet();
|
Unit* target = GetTarget();
|
||||||
if(!pet || pet != GetTarget())
|
if (target->GetTypeId() != TYPEID_UNIT)
|
||||||
return;
|
return;
|
||||||
|
Creature* pet = (Creature*)target; // not need more stricted type check
|
||||||
|
|
||||||
Player* p_caster = (Player*)caster;
|
Player* p_caster = (Player*)caster;
|
||||||
|
Camera& camera = p_caster->GetCamera();
|
||||||
|
|
||||||
if(apply)
|
if (apply)
|
||||||
pet->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
|
|
||||||
else
|
|
||||||
pet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
|
|
||||||
|
|
||||||
p_caster->SetFarSightGUID(apply ? pet->GetGUID() : 0);
|
|
||||||
p_caster->SetCharm(apply ? pet : NULL);
|
|
||||||
p_caster->SetClientControl(pet, apply ? 1 : 0);
|
|
||||||
((Player*)caster)->SetMover(apply ? pet : NULL);
|
|
||||||
|
|
||||||
if(apply)
|
|
||||||
{
|
{
|
||||||
|
camera.SetView(pet);
|
||||||
|
p_caster->SetCharm(pet);
|
||||||
|
p_caster->SetClientControl(pet, 1);
|
||||||
|
((Player*)caster)->SetMover(pet);
|
||||||
|
|
||||||
|
pet->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
|
||||||
|
|
||||||
pet->StopMoving();
|
pet->StopMoving();
|
||||||
pet->GetMotionMaster()->Clear();
|
pet->GetMotionMaster()->Clear(false);
|
||||||
pet->GetMotionMaster()->MoveIdle();
|
pet->GetMotionMaster()->MoveIdle();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
camera.ResetView();
|
||||||
|
p_caster->SetCharm(NULL);
|
||||||
|
p_caster->SetClientControl(pet, 0);
|
||||||
|
p_caster->SetMover(NULL);
|
||||||
|
|
||||||
|
// on delete only do caster related effects
|
||||||
|
if(m_removeMode == AURA_REMOVE_BY_DELETE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
|
||||||
|
|
||||||
pet->AttackStop();
|
pet->AttackStop();
|
||||||
pet->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
|
pet->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
|
||||||
pet->AddSplineFlag(SPLINEFLAG_WALKMODE);
|
pet->AddSplineFlag(SPLINEFLAG_WALKMODE);
|
||||||
|
|
@ -3758,8 +3788,9 @@ void Aura::HandleModCharm(bool apply, bool Real)
|
||||||
target->CastStop(target == caster ? GetId() : 0);
|
target->CastStop(target == caster ? GetId() : 0);
|
||||||
caster->SetCharm(target);
|
caster->SetCharm(target);
|
||||||
|
|
||||||
target->CombatStop();
|
target->CombatStop(true);
|
||||||
target->DeleteThreatList();
|
target->DeleteThreatList();
|
||||||
|
target->getHostileRefManager().deleteReferences();
|
||||||
|
|
||||||
if(target->GetTypeId() == TYPEID_UNIT)
|
if(target->GetTypeId() == TYPEID_UNIT)
|
||||||
{
|
{
|
||||||
|
|
@ -3834,6 +3865,10 @@ void Aura::HandleModCharm(bool apply, bool Real)
|
||||||
if(caster->GetTypeId() == TYPEID_PLAYER)
|
if(caster->GetTypeId() == TYPEID_PLAYER)
|
||||||
((Player*)caster)->RemovePetActionBar();
|
((Player*)caster)->RemovePetActionBar();
|
||||||
|
|
||||||
|
target->CombatStop(true);
|
||||||
|
target->DeleteThreatList();
|
||||||
|
target->getHostileRefManager().deleteReferences();
|
||||||
|
|
||||||
if(target->GetTypeId() == TYPEID_UNIT)
|
if(target->GetTypeId() == TYPEID_UNIT)
|
||||||
{
|
{
|
||||||
((Creature*)target)->AIM_Initialize();
|
((Creature*)target)->AIM_Initialize();
|
||||||
|
|
@ -4182,7 +4217,7 @@ void Aura::HandleInvisibilityDetect(bool apply, bool Real)
|
||||||
target->m_detectInvisibilityMask |= (1 << m_modifier.m_miscvalue);
|
target->m_detectInvisibilityMask |= (1 << m_modifier.m_miscvalue);
|
||||||
}
|
}
|
||||||
if(Real && target->GetTypeId()==TYPEID_PLAYER)
|
if(Real && target->GetTypeId()==TYPEID_PLAYER)
|
||||||
((Player*)target)->UpdateVisibilityForPlayer();
|
((Player*)target)->GetCamera().UpdateVisibilityForOwner();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Aura::HandleAuraModRoot(bool apply, bool Real)
|
void Aura::HandleAuraModRoot(bool apply, bool Real)
|
||||||
|
|
@ -4924,16 +4959,6 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SPELLFAMILY_WARLOCK:
|
|
||||||
{
|
|
||||||
// Drain Soul
|
|
||||||
if (spellProto->SpellFamilyFlags & UI64LIT(0x0000000000004000))
|
|
||||||
{
|
|
||||||
if (target->GetHealth() * 100 / target->GetMaxHealth() <= 25)
|
|
||||||
m_modifier.m_amount *= 4;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SPELLFAMILY_DRUID:
|
case SPELLFAMILY_DRUID:
|
||||||
{
|
{
|
||||||
// Rake
|
// Rake
|
||||||
|
|
@ -8241,9 +8266,13 @@ void Aura::HandleAuraControlVehicle(bool apply, bool Real)
|
||||||
if(!Real)
|
if(!Real)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Unit* target = GetTarget();
|
||||||
|
if (target->GetTypeId() != TYPEID_UNIT || !((Creature*)target)->isVehicle())
|
||||||
|
return;
|
||||||
|
Vehicle* vehicle = (Vehicle*)target;
|
||||||
|
|
||||||
Unit *player = GetCaster();
|
Unit *player = GetCaster();
|
||||||
Vehicle *vehicle = dynamic_cast<Vehicle*>(GetTarget());
|
if(!player || player->GetTypeId() != TYPEID_PLAYER)
|
||||||
if(!player || player->GetTypeId() != TYPEID_PLAYER || !vehicle)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (apply)
|
if (apply)
|
||||||
|
|
|
||||||
|
|
@ -4244,7 +4244,8 @@ void Spell::EffectAddFarsight(SpellEffectIndex eff_idx)
|
||||||
dynObj->SetUInt32Value(DYNAMICOBJECT_BYTES, 0x80000002);
|
dynObj->SetUInt32Value(DYNAMICOBJECT_BYTES, 0x80000002);
|
||||||
m_caster->AddDynObject(dynObj);
|
m_caster->AddDynObject(dynObj);
|
||||||
m_caster->GetMap()->Add(dynObj);
|
m_caster->GetMap()->Add(dynObj);
|
||||||
((Player*)m_caster)->SetFarSightGUID(dynObj->GetGUID());
|
|
||||||
|
((Player*)m_caster)->GetCamera().SetView(dynObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spell::DoSummonWild(SpellEffectIndex eff_idx, uint32 forceFaction)
|
void Spell::DoSummonWild(SpellEffectIndex eff_idx, uint32 forceFaction)
|
||||||
|
|
|
||||||
|
|
@ -31,13 +31,6 @@
|
||||||
|
|
||||||
void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
|
void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
|
||||||
{
|
{
|
||||||
// TODO: add targets.read() check
|
|
||||||
Player* pUser = _player;
|
|
||||||
|
|
||||||
// ignore for remote control state
|
|
||||||
if(pUser->m_mover != pUser)
|
|
||||||
return;
|
|
||||||
|
|
||||||
uint8 bagIndex, slot;
|
uint8 bagIndex, slot;
|
||||||
uint8 unk_flags; // flags (if 0x02 - some additional data are received)
|
uint8 unk_flags; // flags (if 0x02 - some additional data are received)
|
||||||
uint8 cast_count; // next cast if exists (single or not)
|
uint8 cast_count; // next cast if exists (single or not)
|
||||||
|
|
@ -47,9 +40,20 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
|
||||||
|
|
||||||
recvPacket >> bagIndex >> slot >> cast_count >> spellid >> item_guid >> glyphIndex >> unk_flags;
|
recvPacket >> bagIndex >> slot >> cast_count >> spellid >> item_guid >> glyphIndex >> unk_flags;
|
||||||
|
|
||||||
|
// TODO: add targets.read() check
|
||||||
|
Player* pUser = _player;
|
||||||
|
|
||||||
|
// ignore for remote control state
|
||||||
|
if (!pUser->IsSelfMover())
|
||||||
|
{
|
||||||
|
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// reject fake data
|
// reject fake data
|
||||||
if (glyphIndex >= MAX_GLYPH_SLOT_INDEX)
|
if (glyphIndex >= MAX_GLYPH_SLOT_INDEX)
|
||||||
{
|
{
|
||||||
|
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
|
||||||
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL );
|
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -57,12 +61,14 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
|
||||||
Item *pItem = pUser->GetItemByPos(bagIndex, slot);
|
Item *pItem = pUser->GetItemByPos(bagIndex, slot);
|
||||||
if (!pItem)
|
if (!pItem)
|
||||||
{
|
{
|
||||||
|
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
|
||||||
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL );
|
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pItem->GetGUID() != item_guid)
|
if (pItem->GetGUID() != item_guid)
|
||||||
{
|
{
|
||||||
|
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
|
||||||
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL );
|
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -72,6 +78,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
|
||||||
ItemPrototype const *proto = pItem->GetProto();
|
ItemPrototype const *proto = pItem->GetProto();
|
||||||
if (!proto)
|
if (!proto)
|
||||||
{
|
{
|
||||||
|
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
|
||||||
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL );
|
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -79,6 +86,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
|
||||||
// some item classes can be used only in equipped state
|
// some item classes can be used only in equipped state
|
||||||
if (proto->InventoryType != INVTYPE_NON_EQUIP && !pItem->IsEquipped())
|
if (proto->InventoryType != INVTYPE_NON_EQUIP && !pItem->IsEquipped())
|
||||||
{
|
{
|
||||||
|
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
|
||||||
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL );
|
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -86,6 +94,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
|
||||||
uint8 msg = pUser->CanUseItem(pItem);
|
uint8 msg = pUser->CanUseItem(pItem);
|
||||||
if (msg != EQUIP_ERR_OK)
|
if (msg != EQUIP_ERR_OK)
|
||||||
{
|
{
|
||||||
|
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
|
||||||
pUser->SendEquipError( msg, pItem, NULL );
|
pUser->SendEquipError( msg, pItem, NULL );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -95,6 +104,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
|
||||||
!(proto->Flags & ITEM_FLAGS_USEABLE_IN_ARENA) &&
|
!(proto->Flags & ITEM_FLAGS_USEABLE_IN_ARENA) &&
|
||||||
pUser->InArena())
|
pUser->InArena())
|
||||||
{
|
{
|
||||||
|
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
|
||||||
pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH,pItem,NULL);
|
pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH,pItem,NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -107,6 +117,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
|
||||||
{
|
{
|
||||||
if (IsNonCombatSpell(spellInfo))
|
if (IsNonCombatSpell(spellInfo))
|
||||||
{
|
{
|
||||||
|
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
|
||||||
pUser->SendEquipError(EQUIP_ERR_NOT_IN_COMBAT,pItem,NULL);
|
pUser->SendEquipError(EQUIP_ERR_NOT_IN_COMBAT,pItem,NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -116,6 +127,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
|
||||||
// Prevent potion drink if another potion in processing (client have potions disabled in like case)
|
// Prevent potion drink if another potion in processing (client have potions disabled in like case)
|
||||||
if (pItem->IsPotion() && pUser->GetLastPotionId())
|
if (pItem->IsPotion() && pUser->GetLastPotionId())
|
||||||
{
|
{
|
||||||
|
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
|
||||||
pUser->SendEquipError(EQUIP_ERR_OBJECT_IS_BUSY,pItem,NULL);
|
pUser->SendEquipError(EQUIP_ERR_OBJECT_IS_BUSY,pItem,NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -174,18 +186,18 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket)
|
||||||
{
|
{
|
||||||
DETAIL_LOG("WORLD: CMSG_OPEN_ITEM packet, data length = %i",(uint32)recvPacket.size());
|
DETAIL_LOG("WORLD: CMSG_OPEN_ITEM packet, data length = %i",(uint32)recvPacket.size());
|
||||||
|
|
||||||
Player* pUser = _player;
|
|
||||||
|
|
||||||
// ignore for remote control state
|
|
||||||
if(pUser->m_mover != pUser)
|
|
||||||
return;
|
|
||||||
|
|
||||||
uint8 bagIndex, slot;
|
uint8 bagIndex, slot;
|
||||||
|
|
||||||
recvPacket >> bagIndex >> slot;
|
recvPacket >> bagIndex >> slot;
|
||||||
|
|
||||||
DETAIL_LOG("bagIndex: %u, slot: %u",bagIndex,slot);
|
DETAIL_LOG("bagIndex: %u, slot: %u",bagIndex,slot);
|
||||||
|
|
||||||
|
Player* pUser = _player;
|
||||||
|
|
||||||
|
// ignore for remote control state
|
||||||
|
if (!pUser->IsSelfMover())
|
||||||
|
return;
|
||||||
|
|
||||||
Item *pItem = pUser->GetItemByPos(bagIndex, slot);
|
Item *pItem = pUser->GetItemByPos(bagIndex, slot);
|
||||||
if(!pItem)
|
if(!pItem)
|
||||||
{
|
{
|
||||||
|
|
@ -257,7 +269,7 @@ void WorldSession::HandleGameObjectUseOpcode( WorldPacket & recv_data )
|
||||||
DEBUG_LOG( "WORLD: Recvd CMSG_GAMEOBJ_USE Message [guid=%u]", GUID_LOPART(guid));
|
DEBUG_LOG( "WORLD: Recvd CMSG_GAMEOBJ_USE Message [guid=%u]", GUID_LOPART(guid));
|
||||||
|
|
||||||
// ignore for remote control state
|
// ignore for remote control state
|
||||||
if(_player->m_mover != _player)
|
if (!_player->IsSelfMover())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GameObject *obj = GetPlayer()->GetMap()->GetGameObject(guid);
|
GameObject *obj = GetPlayer()->GetMap()->GetGameObject(guid);
|
||||||
|
|
@ -276,7 +288,7 @@ void WorldSession::HandleGameobjectReportUse(WorldPacket& recvPacket)
|
||||||
DEBUG_LOG( "WORLD: Recvd CMSG_GAMEOBJ_REPORT_USE Message [in game guid: %u]", GUID_LOPART(guid));
|
DEBUG_LOG( "WORLD: Recvd CMSG_GAMEOBJ_REPORT_USE Message [in game guid: %u]", GUID_LOPART(guid));
|
||||||
|
|
||||||
// ignore for remote control state
|
// ignore for remote control state
|
||||||
if(_player->m_mover != _player)
|
if (!_player->IsSelfMover())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GameObject* go = GetPlayer()->GetMap()->GetGameObject(guid);
|
GameObject* go = GetPlayer()->GetMap()->GetGameObject(guid);
|
||||||
|
|
@ -298,8 +310,8 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
|
||||||
recvPacket >> unk_flags; // flags (if 0x02 - some additional data are received)
|
recvPacket >> unk_flags; // flags (if 0x02 - some additional data are received)
|
||||||
|
|
||||||
// ignore for remote control state (for player case)
|
// ignore for remote control state (for player case)
|
||||||
Unit* mover = _player->m_mover;
|
Unit* mover = _player->GetMover();
|
||||||
if(mover != _player && mover->GetTypeId()==TYPEID_PLAYER)
|
if (mover != _player && mover->GetTypeId()==TYPEID_PLAYER)
|
||||||
{
|
{
|
||||||
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
|
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
|
||||||
return;
|
return;
|
||||||
|
|
@ -317,10 +329,10 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mover->GetTypeId()==TYPEID_PLAYER)
|
if (mover->GetTypeId()==TYPEID_PLAYER)
|
||||||
{
|
{
|
||||||
// not have spell in spellbook or spell passive and not casted by client
|
// not have spell in spellbook or spell passive and not casted by client
|
||||||
if (!((Player*)mover)->HasActiveSpell (spellId) || IsPassiveSpell(spellId) )
|
if (!((Player*)mover)->HasActiveSpell (spellId) || IsPassiveSpell(spellInfo))
|
||||||
{
|
{
|
||||||
sLog.outError("World: Player %u casts spell %u which he shouldn't have", mover->GetGUIDLow(), spellId);
|
sLog.outError("World: Player %u casts spell %u which he shouldn't have", mover->GetGUIDLow(), spellId);
|
||||||
//cheater? kick? ban?
|
//cheater? kick? ban?
|
||||||
|
|
@ -331,7 +343,7 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// not have spell in spellbook or spell passive and not casted by client
|
// not have spell in spellbook or spell passive and not casted by client
|
||||||
if (!((Creature*)mover)->HasSpell(spellId) || IsPassiveSpell(spellId) )
|
if (!((Creature*)mover)->HasSpell(spellId) || IsPassiveSpell(spellInfo))
|
||||||
{
|
{
|
||||||
//cheater? kick? ban?
|
//cheater? kick? ban?
|
||||||
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
|
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
|
||||||
|
|
@ -364,12 +376,10 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
|
||||||
}
|
}
|
||||||
|
|
||||||
// auto-selection buff level base at target level (in spellInfo)
|
// auto-selection buff level base at target level (in spellInfo)
|
||||||
if(targets.getUnitTarget())
|
if (Unit* target = targets.getUnitTarget())
|
||||||
{
|
{
|
||||||
SpellEntry const *actualSpellInfo = sSpellMgr.SelectAuraRankForPlayerLevel(spellInfo,targets.getUnitTarget()->getLevel());
|
|
||||||
|
|
||||||
// if rank not found then function return NULL but in explicit cast case original spell can be casted and later failed with appropriate error message
|
// if rank not found then function return NULL but in explicit cast case original spell can be casted and later failed with appropriate error message
|
||||||
if(actualSpellInfo)
|
if (SpellEntry const *actualSpellInfo = sSpellMgr.SelectAuraRankForLevel(spellInfo, target->getLevel()))
|
||||||
spellInfo = actualSpellInfo;
|
spellInfo = actualSpellInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -380,16 +390,16 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
|
||||||
|
|
||||||
void WorldSession::HandleCancelCastOpcode(WorldPacket& recvPacket)
|
void WorldSession::HandleCancelCastOpcode(WorldPacket& recvPacket)
|
||||||
{
|
{
|
||||||
// ignore for remote control state (for player case)
|
|
||||||
Unit* mover = _player->m_mover;
|
|
||||||
if(mover != _player && mover->GetTypeId()==TYPEID_PLAYER)
|
|
||||||
return;
|
|
||||||
|
|
||||||
uint32 spellId;
|
uint32 spellId;
|
||||||
|
|
||||||
recvPacket.read_skip<uint8>(); // counter, increments with every CANCEL packet, don't use for now
|
recvPacket.read_skip<uint8>(); // counter, increments with every CANCEL packet, don't use for now
|
||||||
recvPacket >> spellId;
|
recvPacket >> spellId;
|
||||||
|
|
||||||
|
// ignore for remote control state (for player case)
|
||||||
|
Unit* mover = _player->GetMover();
|
||||||
|
if (mover != _player && mover->GetTypeId()==TYPEID_PLAYER)
|
||||||
|
return;
|
||||||
|
|
||||||
//FIXME: hack, ignore unexpected client cancel Deadly Throw cast
|
//FIXME: hack, ignore unexpected client cancel Deadly Throw cast
|
||||||
if(spellId==26679)
|
if(spellId==26679)
|
||||||
return;
|
return;
|
||||||
|
|
@ -410,10 +420,13 @@ void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket)
|
||||||
if (spellInfo->Attributes & SPELL_ATTR_CANT_CANCEL)
|
if (spellInfo->Attributes & SPELL_ATTR_CANT_CANCEL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(!IsPositiveSpell(spellId))
|
if (IsPassiveSpell(spellInfo))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!IsPositiveSpell(spellId))
|
||||||
{
|
{
|
||||||
// ignore for remote control state
|
// ignore for remote control state
|
||||||
if (_player->m_mover != _player)
|
if (!_player->IsSelfMover())
|
||||||
{
|
{
|
||||||
// except own aura spells
|
// except own aura spells
|
||||||
bool allow = false;
|
bool allow = false;
|
||||||
|
|
@ -450,16 +463,16 @@ void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket)
|
||||||
|
|
||||||
void WorldSession::HandlePetCancelAuraOpcode( WorldPacket& recvPacket)
|
void WorldSession::HandlePetCancelAuraOpcode( WorldPacket& recvPacket)
|
||||||
{
|
{
|
||||||
// ignore for remote control state
|
|
||||||
if(_player->m_mover != _player)
|
|
||||||
return;
|
|
||||||
|
|
||||||
uint64 guid;
|
uint64 guid;
|
||||||
uint32 spellId;
|
uint32 spellId;
|
||||||
|
|
||||||
recvPacket >> guid;
|
recvPacket >> guid;
|
||||||
recvPacket >> spellId;
|
recvPacket >> spellId;
|
||||||
|
|
||||||
|
// ignore for remote control state
|
||||||
|
if (!_player->IsSelfMover())
|
||||||
|
return;
|
||||||
|
|
||||||
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );
|
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );
|
||||||
if(!spellInfo)
|
if(!spellInfo)
|
||||||
{
|
{
|
||||||
|
|
@ -501,7 +514,7 @@ void WorldSession::HandleCancelAutoRepeatSpellOpcode( WorldPacket& /*recvPacket*
|
||||||
{
|
{
|
||||||
// cancel and prepare for deleting
|
// cancel and prepare for deleting
|
||||||
// do not send SMSG_CANCEL_AUTO_REPEAT! client will send this Opcode again (loop)
|
// do not send SMSG_CANCEL_AUTO_REPEAT! client will send this Opcode again (loop)
|
||||||
_player->m_mover->InterruptSpell(CURRENT_AUTOREPEAT_SPELL, true, false);
|
_player->GetMover()->InterruptSpell(CURRENT_AUTOREPEAT_SPELL, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandleCancelChanneling( WorldPacket & recv_data)
|
void WorldSession::HandleCancelChanneling( WorldPacket & recv_data)
|
||||||
|
|
@ -509,8 +522,8 @@ void WorldSession::HandleCancelChanneling( WorldPacket & recv_data)
|
||||||
recv_data.read_skip<uint32>(); // spellid, not used
|
recv_data.read_skip<uint32>(); // spellid, not used
|
||||||
|
|
||||||
// ignore for remote control state (for player case)
|
// ignore for remote control state (for player case)
|
||||||
Unit* mover = _player->m_mover;
|
Unit* mover = _player->GetMover();
|
||||||
if(mover != _player && mover->GetTypeId()==TYPEID_PLAYER)
|
if (mover != _player && mover->GetTypeId()==TYPEID_PLAYER)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mover->InterruptSpell(CURRENT_CHANNELED_SPELL);
|
mover->InterruptSpell(CURRENT_CHANNELED_SPELL);
|
||||||
|
|
@ -518,14 +531,14 @@ void WorldSession::HandleCancelChanneling( WorldPacket & recv_data)
|
||||||
|
|
||||||
void WorldSession::HandleTotemDestroyed( WorldPacket& recvPacket)
|
void WorldSession::HandleTotemDestroyed( WorldPacket& recvPacket)
|
||||||
{
|
{
|
||||||
// ignore for remote control state
|
|
||||||
if(_player->m_mover != _player)
|
|
||||||
return;
|
|
||||||
|
|
||||||
uint8 slotId;
|
uint8 slotId;
|
||||||
|
|
||||||
recvPacket >> slotId;
|
recvPacket >> slotId;
|
||||||
|
|
||||||
|
// ignore for remote control state
|
||||||
|
if (!_player->IsSelfMover())
|
||||||
|
return;
|
||||||
|
|
||||||
if (int(slotId) >= MAX_TOTEM_SLOT)
|
if (int(slotId) >= MAX_TOTEM_SLOT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -283,6 +283,11 @@ bool IsPassiveSpell(uint32 spellId)
|
||||||
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId);
|
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId);
|
||||||
if (!spellInfo)
|
if (!spellInfo)
|
||||||
return false;
|
return false;
|
||||||
|
return IsPassiveSpell(spellInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsPassiveSpell(SpellEntry const *spellInfo)
|
||||||
|
{
|
||||||
return (spellInfo->Attributes & SPELL_ATTR_PASSIVE) != 0;
|
return (spellInfo->Attributes & SPELL_ATTR_PASSIVE) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1607,7 +1612,7 @@ bool SpellMgr::IsRankSpellDueToSpell(SpellEntry const *spellInfo_1,uint32 spellI
|
||||||
|
|
||||||
bool SpellMgr::canStackSpellRanks(SpellEntry const *spellInfo)
|
bool SpellMgr::canStackSpellRanks(SpellEntry const *spellInfo)
|
||||||
{
|
{
|
||||||
if(IsPassiveSpell(spellInfo->Id)) // ranked passive spell
|
if(IsPassiveSpell(spellInfo)) // ranked passive spell
|
||||||
return false;
|
return false;
|
||||||
if(spellInfo->powerType != POWER_MANA && spellInfo->powerType != POWER_HEALTH)
|
if(spellInfo->powerType != POWER_MANA && spellInfo->powerType != POWER_HEALTH)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -2211,37 +2216,44 @@ bool SpellMgr::IsSkillBonusSpell(uint32 spellId) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SpellEntry const* SpellMgr::SelectAuraRankForPlayerLevel(SpellEntry const* spellInfo, uint32 playerLevel) const
|
SpellEntry const* SpellMgr::SelectAuraRankForLevel(SpellEntry const* spellInfo, uint32 level) const
|
||||||
{
|
{
|
||||||
// ignore passive spells
|
// fast case
|
||||||
if(IsPassiveSpell(spellInfo->Id))
|
if (level + 10 >= spellInfo->spellLevel)
|
||||||
|
return spellInfo;
|
||||||
|
|
||||||
|
// ignore selection for passive spells
|
||||||
|
if (IsPassiveSpell(spellInfo))
|
||||||
return spellInfo;
|
return spellInfo;
|
||||||
|
|
||||||
bool needRankSelection = false;
|
bool needRankSelection = false;
|
||||||
for(int i = 0; i < MAX_EFFECT_INDEX; ++i)
|
for(int i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||||
{
|
{
|
||||||
if (IsPositiveEffect(spellInfo->Id, SpellEffectIndex(i)) && (
|
// for simple aura in check apply to any non caster based targets, in rank search mode to any explicit targets
|
||||||
spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA ||
|
if (((spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA &&
|
||||||
|
(IsExplicitPositiveTarget(spellInfo->EffectImplicitTargetA[i]) ||
|
||||||
|
IsAreaEffectPossitiveTarget(Targets(spellInfo->EffectImplicitTargetA[i])))) ||
|
||||||
spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PARTY ||
|
spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PARTY ||
|
||||||
spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_RAID))
|
spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_RAID) &&
|
||||||
|
IsPositiveEffect(spellInfo->Id, SpellEffectIndex(i)))
|
||||||
{
|
{
|
||||||
needRankSelection = true;
|
needRankSelection = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// not required
|
// not required (rank check more slow so check it here)
|
||||||
if(!needRankSelection)
|
if (!needRankSelection || GetSpellRank(spellInfo->Id) == 0)
|
||||||
return spellInfo;
|
return spellInfo;
|
||||||
|
|
||||||
for(uint32 nextSpellId = spellInfo->Id; nextSpellId != 0; nextSpellId = GetPrevSpellInChain(nextSpellId))
|
for(uint32 nextSpellId = spellInfo->Id; nextSpellId != 0; nextSpellId = GetPrevSpellInChain(nextSpellId))
|
||||||
{
|
{
|
||||||
SpellEntry const *nextSpellInfo = sSpellStore.LookupEntry(nextSpellId);
|
SpellEntry const *nextSpellInfo = sSpellStore.LookupEntry(nextSpellId);
|
||||||
if(!nextSpellInfo)
|
if (!nextSpellInfo)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// if found appropriate level
|
// if found appropriate level
|
||||||
if(playerLevel + 10 >= nextSpellInfo->spellLevel)
|
if (level + 10 >= spellInfo->spellLevel)
|
||||||
return nextSpellInfo;
|
return nextSpellInfo;
|
||||||
|
|
||||||
// one rank less then
|
// one rank less then
|
||||||
|
|
@ -2588,7 +2600,7 @@ void SpellMgr::LoadSpellLearnSpells()
|
||||||
// talent or passive spells or skill-step spells auto-casted and not need dependent learning,
|
// talent or passive spells or skill-step spells auto-casted and not need dependent learning,
|
||||||
// pet teaching spells don't must be dependent learning (casted)
|
// pet teaching spells don't must be dependent learning (casted)
|
||||||
// other required explicit dependent learning
|
// other required explicit dependent learning
|
||||||
dbc_node.autoLearned = entry->EffectImplicitTargetA[i]==TARGET_PET || GetTalentSpellCost(spell) > 0 || IsPassiveSpell(spell) || IsSpellHaveEffect(entry,SPELL_EFFECT_SKILL_STEP);
|
dbc_node.autoLearned = entry->EffectImplicitTargetA[i]==TARGET_PET || GetTalentSpellCost(spell) > 0 || IsPassiveSpell(entry) || IsSpellHaveEffect(entry,SPELL_EFFECT_SKILL_STEP);
|
||||||
|
|
||||||
SpellLearnSpellMapBounds db_node_bounds = GetSpellLearnSpellMapBounds(spell);
|
SpellLearnSpellMapBounds db_node_bounds = GetSpellLearnSpellMapBounds(spell);
|
||||||
|
|
||||||
|
|
@ -3974,4 +3986,4 @@ SpellEntry const* GetSpellEntryByDifficulty(uint32 id, Difficulty difficulty)
|
||||||
|
|
||||||
SpellEntry const* spellEntry = sSpellStore.LookupEntry(spellDiff->spellId[difficulty]);
|
SpellEntry const* spellEntry = sSpellStore.LookupEntry(spellDiff->spellId[difficulty]);
|
||||||
return spellEntry;
|
return spellEntry;
|
||||||
}
|
}
|
||||||
|
|
@ -210,10 +210,11 @@ bool IsSingleFromSpellSpecificSpellRanksPerTarget(SpellSpecific spellSpec1,Spell
|
||||||
bool IsSingleFromSpellSpecificPerTarget(SpellSpecific spellSpec1,SpellSpecific spellSpec2);
|
bool IsSingleFromSpellSpecificPerTarget(SpellSpecific spellSpec1,SpellSpecific spellSpec2);
|
||||||
|
|
||||||
bool IsPassiveSpell(uint32 spellId);
|
bool IsPassiveSpell(uint32 spellId);
|
||||||
|
bool IsPassiveSpell(SpellEntry const* spellProto);
|
||||||
|
|
||||||
inline bool IsPassiveSpellStackableWithRanks(SpellEntry const* spellProto)
|
inline bool IsPassiveSpellStackableWithRanks(SpellEntry const* spellProto)
|
||||||
{
|
{
|
||||||
if(!IsPassiveSpell(spellProto->Id))
|
if(!IsPassiveSpell(spellProto))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return !IsSpellHaveEffect(spellProto,SPELL_EFFECT_APPLY_AURA);
|
return !IsSpellHaveEffect(spellProto,SPELL_EFFECT_APPLY_AURA);
|
||||||
|
|
@ -319,6 +320,25 @@ inline bool IsPointEffectTarget( Targets target )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool IsAreaEffectPossitiveTarget( Targets target )
|
||||||
|
{
|
||||||
|
switch (target )
|
||||||
|
{
|
||||||
|
case TARGET_ALL_PARTY_AROUND_CASTER:
|
||||||
|
case TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER:
|
||||||
|
case TARGET_ALL_FRIENDLY_UNITS_IN_AREA:
|
||||||
|
case TARGET_ALL_PARTY:
|
||||||
|
case TARGET_ALL_PARTY_AROUND_CASTER_2:
|
||||||
|
case TARGET_AREAEFFECT_PARTY:
|
||||||
|
case TARGET_ALL_RAID_AROUND_CASTER:
|
||||||
|
case TARGET_AREAEFFECT_PARTY_AND_CLASS:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool IsAreaEffectTarget( Targets target )
|
inline bool IsAreaEffectTarget( Targets target )
|
||||||
{
|
{
|
||||||
switch (target )
|
switch (target )
|
||||||
|
|
@ -371,12 +391,9 @@ inline bool IsAreaAuraEffect(uint32 effect)
|
||||||
|
|
||||||
inline bool IsDispelSpell(SpellEntry const *spellInfo)
|
inline bool IsDispelSpell(SpellEntry const *spellInfo)
|
||||||
{
|
{
|
||||||
if (spellInfo->Effect[EFFECT_INDEX_0] == SPELL_EFFECT_DISPEL ||
|
return IsSpellHaveEffect(spellInfo, SPELL_EFFECT_DISPEL);
|
||||||
spellInfo->Effect[EFFECT_INDEX_1] == SPELL_EFFECT_DISPEL ||
|
|
||||||
spellInfo->Effect[EFFECT_INDEX_2] == SPELL_EFFECT_DISPEL )
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isSpellBreakStealth(SpellEntry const* spellInfo)
|
inline bool isSpellBreakStealth(SpellEntry const* spellInfo)
|
||||||
{
|
{
|
||||||
return !(spellInfo->AttributesEx & SPELL_ATTR_EX_NOT_BREAK_STEALTH);
|
return !(spellInfo->AttributesEx & SPELL_ATTR_EX_NOT_BREAK_STEALTH);
|
||||||
|
|
@ -906,7 +923,7 @@ class SpellMgr
|
||||||
static bool canStackSpellRanks(SpellEntry const *spellInfo);
|
static bool canStackSpellRanks(SpellEntry const *spellInfo);
|
||||||
bool IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) const;
|
bool IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) const;
|
||||||
|
|
||||||
SpellEntry const* SelectAuraRankForPlayerLevel(SpellEntry const* spellInfo, uint32 playerLevel) const;
|
SpellEntry const* SelectAuraRankForLevel(SpellEntry const* spellInfo, uint32 Level) const;
|
||||||
|
|
||||||
// Spell learning
|
// Spell learning
|
||||||
SpellLearnSkillNode const* GetSpellLearnSkill(uint32 spell_id) const
|
SpellLearnSkillNode const* GetSpellLearnSkill(uint32 spell_id) const
|
||||||
|
|
@ -1064,4 +1081,4 @@ class SpellMgr
|
||||||
};
|
};
|
||||||
|
|
||||||
#define sSpellMgr SpellMgr::Instance()
|
#define sSpellMgr SpellMgr::Instance()
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -37,12 +37,17 @@ void TargetedMovementGeneratorMedium<T,D>::_setTargetLocation(T &owner)
|
||||||
if (owner.hasUnitState(UNIT_STAT_NOT_MOVE))
|
if (owner.hasUnitState(UNIT_STAT_NOT_MOVE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
float x, y, z;
|
||||||
|
|
||||||
// prevent redundant micro-movement for pets, other followers.
|
// prevent redundant micro-movement for pets, other followers.
|
||||||
if (i_offset && i_target->IsWithinDistInMap(&owner,2*i_offset))
|
if (i_offset && i_target->IsWithinDistInMap(&owner,2*i_offset))
|
||||||
return;
|
{
|
||||||
|
if (i_destinationHolder.HasDestination())
|
||||||
|
return;
|
||||||
|
|
||||||
float x, y, z;
|
owner.GetPosition(x, y, z);
|
||||||
if (!i_offset)
|
}
|
||||||
|
else if (!i_offset)
|
||||||
{
|
{
|
||||||
// to nearest contact position
|
// to nearest contact position
|
||||||
i_target->GetContactPoint( &owner, x, y, z );
|
i_target->GetContactPoint( &owner, x, y, z );
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ struct MANGOS_DLL_DECL Traveller
|
||||||
void Relocation(float x, float y, float z, float orientation) {}
|
void Relocation(float x, float y, float z, float orientation) {}
|
||||||
void Relocation(float x, float y, float z) { Relocation(x, y, z, i_traveller.GetOrientation()); }
|
void Relocation(float x, float y, float z) { Relocation(x, y, z, i_traveller.GetOrientation()); }
|
||||||
void MoveTo(float x, float y, float z, uint32 t) {}
|
void MoveTo(float x, float y, float z, uint32 t) {}
|
||||||
|
void Stop() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
|
|
@ -102,7 +103,13 @@ inline float Traveller<Creature>::GetMoveDestinationTo(float x, float y, float z
|
||||||
template<>
|
template<>
|
||||||
inline void Traveller<Creature>::MoveTo(float x, float y, float z, uint32 t)
|
inline void Traveller<Creature>::MoveTo(float x, float y, float z, uint32 t)
|
||||||
{
|
{
|
||||||
i_traveller.AI_SendMoveToPacket(x, y, z, t, i_traveller.GetSplineFlags(), SPLINETYPE_NORMAL);
|
i_traveller.SendMonsterMove(x, y, z, SPLINETYPE_NORMAL, i_traveller.GetSplineFlags(), t);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline void Traveller<Creature>::Stop()
|
||||||
|
{
|
||||||
|
i_traveller.SendMonsterMove(i_traveller.GetPositionX(), i_traveller.GetPositionY(), i_traveller.GetPositionZ(), SPLINETYPE_STOP, i_traveller.GetSplineFlags(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// specialization for players
|
// specialization for players
|
||||||
|
|
@ -141,6 +148,13 @@ inline void Traveller<Player>::MoveTo(float x, float y, float z, uint32 t)
|
||||||
i_traveller.SendMonsterMove(x, y, z, SPLINETYPE_NORMAL, SPLINEFLAG_WALKMODE, t);
|
i_traveller.SendMonsterMove(x, y, z, SPLINETYPE_NORMAL, SPLINEFLAG_WALKMODE, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline void Traveller<Player>::Stop()
|
||||||
|
{
|
||||||
|
//Only send SPLINEFLAG_WALKMODE, client has strange issues with other move flags
|
||||||
|
i_traveller.SendMonsterMove(i_traveller.GetPositionX(), i_traveller.GetPositionY(), i_traveller.GetPositionZ(), SPLINETYPE_STOP, SPLINEFLAG_WALKMODE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
typedef Traveller<Creature> CreatureTraveller;
|
typedef Traveller<Creature> CreatureTraveller;
|
||||||
typedef Traveller<Player> PlayerTraveller;
|
typedef Traveller<Player> PlayerTraveller;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -382,12 +382,7 @@ void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, SplineTy
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
data << uint32(flags);
|
data << uint32(flags); // splineflags
|
||||||
|
|
||||||
// enable me if things goes wrong or looks ugly, it is however an old hack
|
|
||||||
// if(flags & SPLINEFLAG_WALKMODE)
|
|
||||||
// moveTime *= 1.05f;
|
|
||||||
|
|
||||||
data << uint32(moveTime); // Time in between points
|
data << uint32(moveTime); // Time in between points
|
||||||
data << uint32(1); // 1 single waypoint
|
data << uint32(1); // 1 single waypoint
|
||||||
data << NewPosX << NewPosY << NewPosZ; // the single waypoint Point B
|
data << NewPosX << NewPosY << NewPosZ; // the single waypoint Point B
|
||||||
|
|
@ -4011,7 +4006,7 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur)
|
||||||
SpellEffectIndex effIndex = Aur->GetEffIndex();
|
SpellEffectIndex effIndex = Aur->GetEffIndex();
|
||||||
|
|
||||||
// passive spell special case (only non stackable with ranks)
|
// passive spell special case (only non stackable with ranks)
|
||||||
if(IsPassiveSpell(spellId))
|
if(IsPassiveSpell(spellProto))
|
||||||
{
|
{
|
||||||
if(IsPassiveSpellStackableWithRanks(spellProto))
|
if(IsPassiveSpellStackableWithRanks(spellProto))
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -4034,7 +4029,7 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur)
|
||||||
uint32 i_spellId = i_spellProto->Id;
|
uint32 i_spellId = i_spellProto->Id;
|
||||||
|
|
||||||
// early checks that spellId is passive non stackable spell
|
// early checks that spellId is passive non stackable spell
|
||||||
if(IsPassiveSpell(i_spellId))
|
if(IsPassiveSpell(i_spellProto))
|
||||||
{
|
{
|
||||||
// passive non-stackable spells not stackable only for same caster
|
// passive non-stackable spells not stackable only for same caster
|
||||||
if(Aur->GetCasterGUID()!=i->second->GetCasterGUID())
|
if(Aur->GetCasterGUID()!=i->second->GetCasterGUID())
|
||||||
|
|
@ -4516,7 +4511,20 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
|
||||||
DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Aura %u now is remove mode %d",Aur->GetModifier()->m_auraname, mode);
|
DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Aura %u now is remove mode %d",Aur->GetModifier()->m_auraname, mode);
|
||||||
|
|
||||||
// some auras also need to apply modifier (on caster) on remove
|
// some auras also need to apply modifier (on caster) on remove
|
||||||
if (mode != AURA_REMOVE_BY_DELETE || Aur->GetModifier()->m_auraname == SPELL_AURA_MOD_POSSESS)
|
if (mode == AURA_REMOVE_BY_DELETE)
|
||||||
|
{
|
||||||
|
switch (Aur->GetModifier()->m_auraname)
|
||||||
|
{
|
||||||
|
// need properly undo any auras with player-caster mover set (or will crash at next caster move packet)
|
||||||
|
case SPELL_AURA_MOD_POSSESS:
|
||||||
|
case SPELL_AURA_MOD_POSSESS_PET:
|
||||||
|
case SPELL_AURA_CONTROL_VEHICLE:
|
||||||
|
Aur->ApplyModifier(false,true);
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
Aur->ApplyModifier(false,true);
|
Aur->ApplyModifier(false,true);
|
||||||
|
|
||||||
if (Aur->_RemoveAura())
|
if (Aur->_RemoveAura())
|
||||||
|
|
@ -8549,7 +8557,7 @@ void Unit::CombatStopWithPets(bool includingCast)
|
||||||
struct IsAttackingPlayerHelper
|
struct IsAttackingPlayerHelper
|
||||||
{
|
{
|
||||||
explicit IsAttackingPlayerHelper() {}
|
explicit IsAttackingPlayerHelper() {}
|
||||||
bool operator()(Unit* unit) const { return unit->isAttackingPlayer(); }
|
bool operator()(Unit const* unit) const { return unit->isAttackingPlayer(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
bool Unit::isAttackingPlayer() const
|
bool Unit::isAttackingPlayer() const
|
||||||
|
|
@ -8615,7 +8623,7 @@ void Unit::ModifyAuraState(AuraState flag, bool apply)
|
||||||
{
|
{
|
||||||
if(itr->second.state == PLAYERSPELL_REMOVED) continue;
|
if(itr->second.state == PLAYERSPELL_REMOVED) continue;
|
||||||
SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first);
|
SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first);
|
||||||
if (!spellInfo || !IsPassiveSpell(itr->first)) continue;
|
if (!spellInfo || !IsPassiveSpell(spellInfo)) continue;
|
||||||
if (spellInfo->CasterAuraState == flag)
|
if (spellInfo->CasterAuraState == flag)
|
||||||
CastSpell(this, itr->first, true, NULL);
|
CastSpell(this, itr->first, true, NULL);
|
||||||
}
|
}
|
||||||
|
|
@ -8925,7 +8933,18 @@ int32 Unit::SpellBonusWithCoeffs(SpellEntry const *spellProto, int32 total, int3
|
||||||
|
|
||||||
// apply ap bonus at done part calculation only (it flat total mod so common with taken)
|
// apply ap bonus at done part calculation only (it flat total mod so common with taken)
|
||||||
if (donePart && bonus->ap_bonus)
|
if (donePart && bonus->ap_bonus)
|
||||||
total += int32(bonus->ap_bonus * (GetTotalAttackPowerValue(BASE_ATTACK) + ap_benefit));
|
{
|
||||||
|
float ap_bonus = bonus->ap_bonus;
|
||||||
|
|
||||||
|
// Impurity
|
||||||
|
if (GetTypeId() == TYPEID_PLAYER && spellProto->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT)
|
||||||
|
{
|
||||||
|
if (SpellEntry const* spell = ((Player*)this)->GetKnownTalentRankById(2005))
|
||||||
|
ap_bonus += ((spell->CalculateSimpleValue(EFFECT_INDEX_0) * ap_bonus) / 100.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
total += int32(ap_bonus * (GetTotalAttackPowerValue(BASE_ATTACK) + ap_benefit));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Default calculation
|
// Default calculation
|
||||||
else if (benefit)
|
else if (benefit)
|
||||||
|
|
@ -9158,7 +9177,15 @@ uint32 Unit::SpellDamageBonusDone(Unit *pVictim, SpellEntry const *spellProto, u
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SPELLFAMILY_WARLOCK:
|
case SPELLFAMILY_WARLOCK:
|
||||||
|
{
|
||||||
|
// Drain Soul
|
||||||
|
if (spellProto->SpellFamilyFlags & UI64LIT(0x0000000000004000))
|
||||||
|
{
|
||||||
|
if (pVictim->GetHealth() * 100 / pVictim->GetMaxHealth() <= 25)
|
||||||
|
DoneTotalMod *= 4;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case SPELLFAMILY_PRIEST:
|
case SPELLFAMILY_PRIEST:
|
||||||
{
|
{
|
||||||
// Glyph of Smite
|
// Glyph of Smite
|
||||||
|
|
@ -10579,10 +10606,6 @@ bool Unit::isVisibleForOrDetect(Unit const* u, WorldObject const* viewPoint, boo
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// always seen by far sight caster
|
|
||||||
if (u->GetTypeId()==TYPEID_PLAYER && ((Player*)u)->GetFarSight()==GetGUID())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// different visible distance checks
|
// different visible distance checks
|
||||||
if (u->isInFlight()) // what see player in flight
|
if (u->isInFlight()) // what see player in flight
|
||||||
{
|
{
|
||||||
|
|
@ -10781,12 +10804,41 @@ void Unit::SetVisibility(UnitVisibility x)
|
||||||
|
|
||||||
if(IsInWorld())
|
if(IsInWorld())
|
||||||
{
|
{
|
||||||
|
// some auras requires visible target
|
||||||
|
if(m_Visibility == VISIBILITY_GROUP_NO_DETECT || m_Visibility == VISIBILITY_OFF)
|
||||||
|
{
|
||||||
|
static const AuraType auratypes[] = {SPELL_AURA_BIND_SIGHT, SPELL_AURA_FAR_SIGHT, SPELL_AURA_NONE};
|
||||||
|
for (AuraType const* type = &auratypes[0]; *type != SPELL_AURA_NONE; ++type)
|
||||||
|
{
|
||||||
|
AuraList& alist = m_modAuras[*type];
|
||||||
|
if(alist.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (AuraList::iterator it = alist.begin(); it != alist.end();)
|
||||||
|
{
|
||||||
|
Aura* aura = (*it);
|
||||||
|
Unit* owner = aura->GetCaster();
|
||||||
|
|
||||||
|
if (!owner || !isVisibleForOrDetect(owner,this,false))
|
||||||
|
{
|
||||||
|
alist.erase(it);
|
||||||
|
RemoveAura(aura);
|
||||||
|
it = alist.begin();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Map *m = GetMap();
|
Map *m = GetMap();
|
||||||
|
|
||||||
if(GetTypeId()==TYPEID_PLAYER)
|
if(GetTypeId()==TYPEID_PLAYER)
|
||||||
m->PlayerRelocation((Player*)this,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
|
m->PlayerRelocation((Player*)this,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
|
||||||
else
|
else
|
||||||
m->CreatureRelocation((Creature*)this,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
|
m->CreatureRelocation((Creature*)this,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
|
||||||
|
|
||||||
|
GetViewPoint().Event_ViewPointVisibilityChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -12039,6 +12091,7 @@ void Unit::RemoveFromWorld()
|
||||||
RemoveAllGameObjects();
|
RemoveAllGameObjects();
|
||||||
RemoveAllDynObjects();
|
RemoveAllDynObjects();
|
||||||
CleanupDeletedAuras();
|
CleanupDeletedAuras();
|
||||||
|
GetViewPoint().Event_RemovedFromWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
Object::RemoveFromWorld();
|
Object::RemoveFromWorld();
|
||||||
|
|
@ -12740,9 +12793,13 @@ void Unit::StopMoving()
|
||||||
{
|
{
|
||||||
clearUnitState(UNIT_STAT_MOVING);
|
clearUnitState(UNIT_STAT_MOVING);
|
||||||
|
|
||||||
|
// not need send any packets if not in world
|
||||||
|
if (!IsInWorld())
|
||||||
|
return;
|
||||||
|
|
||||||
// send explicit stop packet
|
// send explicit stop packet
|
||||||
// player expected for correct work SPLINEFLAG_WALKMODE
|
// player expected for correct work SPLINEFLAG_WALKMODE
|
||||||
SendMonsterMove(GetPositionX(), GetPositionY(), GetPositionZ(), SPLINETYPE_NORMAL, GetTypeId() == TYPEID_PLAYER ? SPLINEFLAG_WALKMODE : SPLINEFLAG_NONE, 0);
|
SendMonsterMove(GetPositionX(), GetPositionY(), GetPositionZ(), SPLINETYPE_STOP, GetTypeId() == TYPEID_PLAYER ? SPLINEFLAG_WALKMODE : SPLINEFLAG_NONE, 0);
|
||||||
|
|
||||||
// update position and orientation for near players
|
// update position and orientation for near players
|
||||||
WorldPacket data;
|
WorldPacket data;
|
||||||
|
|
@ -13710,4 +13767,4 @@ bool Unit::CheckAndIncreaseCastCounter()
|
||||||
|
|
||||||
++m_castCounter;
|
++m_castCounter;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -420,24 +420,25 @@ enum UnitState
|
||||||
UNIT_STAT_STUNNED = 0x00000008, // Aura::HandleAuraModStun
|
UNIT_STAT_STUNNED = 0x00000008, // Aura::HandleAuraModStun
|
||||||
UNIT_STAT_ROOT = 0x00000010, // Aura::HandleAuraModRoot
|
UNIT_STAT_ROOT = 0x00000010, // Aura::HandleAuraModRoot
|
||||||
UNIT_STAT_ISOLATED = 0x00000020, // area auras do not affect other players, Aura::HandleAuraModSchoolImmunity
|
UNIT_STAT_ISOLATED = 0x00000020, // area auras do not affect other players, Aura::HandleAuraModSchoolImmunity
|
||||||
|
UNIT_STAT_CONTROLLED = 0x00000040, // Aura::HandleAuraModPossess
|
||||||
|
|
||||||
// persistent movement generator state (all time while movement generator applied to unit (independent from top state of movegen)
|
// persistent movement generator state (all time while movement generator applied to unit (independent from top state of movegen)
|
||||||
UNIT_STAT_IN_FLIGHT = 0x00000040, // player is in flight mode (in fact interrupted at far teleport until next map telport landing)
|
UNIT_STAT_IN_FLIGHT = 0x00000080, // player is in flight mode (in fact interrupted at far teleport until next map telport landing)
|
||||||
UNIT_STAT_DISTRACTED = 0x00000080, // DistractedMovementGenerator active
|
UNIT_STAT_DISTRACTED = 0x00000100, // DistractedMovementGenerator active
|
||||||
|
|
||||||
// persistent movement generator state with non-persistent mirror states for stop support
|
// persistent movement generator state with non-persistent mirror states for stop support
|
||||||
// (can be removed temporary by stop command or another movement generator apply)
|
// (can be removed temporary by stop command or another movement generator apply)
|
||||||
// not use _MOVE versions for generic movegen state, it can be removed temporary for unit stop and etc
|
// not use _MOVE versions for generic movegen state, it can be removed temporary for unit stop and etc
|
||||||
UNIT_STAT_CONFUSED = 0x00000100, // ConfusedMovementGenerator active/onstack
|
UNIT_STAT_CONFUSED = 0x00000200, // ConfusedMovementGenerator active/onstack
|
||||||
UNIT_STAT_CONFUSED_MOVE = 0x00000200,
|
UNIT_STAT_CONFUSED_MOVE = 0x00000400,
|
||||||
UNIT_STAT_ROAMING = 0x00000400, // RandomMovementGenerator/PointMovementGenerator/WaypointMovementGenerator active (now always set)
|
UNIT_STAT_ROAMING = 0x00000800, // RandomMovementGenerator/PointMovementGenerator/WaypointMovementGenerator active (now always set)
|
||||||
UNIT_STAT_ROAMING_MOVE = 0x00000800,
|
UNIT_STAT_ROAMING_MOVE = 0x00001000,
|
||||||
UNIT_STAT_CHASE = 0x00001000, // ChaseMovementGenerator active
|
UNIT_STAT_CHASE = 0x00002000, // ChaseMovementGenerator active
|
||||||
UNIT_STAT_CHASE_MOVE = 0x00002000,
|
UNIT_STAT_CHASE_MOVE = 0x00004000,
|
||||||
UNIT_STAT_FOLLOW = 0x00004000, // FollowMovementGenerator active
|
UNIT_STAT_FOLLOW = 0x00008000, // FollowMovementGenerator active
|
||||||
UNIT_STAT_FOLLOW_MOVE = 0x00008000,
|
UNIT_STAT_FOLLOW_MOVE = 0x00010000,
|
||||||
UNIT_STAT_FLEEING = 0x00010000, // FleeMovementGenerator/TimedFleeingMovementGenerator active/onstack
|
UNIT_STAT_FLEEING = 0x00020000, // FleeMovementGenerator/TimedFleeingMovementGenerator active/onstack
|
||||||
UNIT_STAT_FLEEING_MOVE = 0x00020000,
|
UNIT_STAT_FLEEING_MOVE = 0x00040000,
|
||||||
|
|
||||||
// masks (only for check)
|
// masks (only for check)
|
||||||
|
|
||||||
|
|
@ -457,6 +458,12 @@ enum UnitState
|
||||||
UNIT_STAT_CAN_NOT_REACT = UNIT_STAT_STUNNED | UNIT_STAT_DIED |
|
UNIT_STAT_CAN_NOT_REACT = UNIT_STAT_STUNNED | UNIT_STAT_DIED |
|
||||||
UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING,
|
UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING,
|
||||||
|
|
||||||
|
// AI disabled by some reason
|
||||||
|
UNIT_STAT_LOST_CONTROL = UNIT_STAT_FLEEING | UNIT_STAT_CONTROLLED,
|
||||||
|
|
||||||
|
// above 2 state cases
|
||||||
|
UNIT_STAT_CAN_NOT_REACT_OR_LOST_CONTROL = UNIT_STAT_CAN_NOT_REACT | UNIT_STAT_LOST_CONTROL,
|
||||||
|
|
||||||
// masks (for check or reset)
|
// masks (for check or reset)
|
||||||
|
|
||||||
// for real move using movegen check and stop (except unstoppable flight)
|
// for real move using movegen check and stop (except unstoppable flight)
|
||||||
|
|
@ -1943,14 +1950,14 @@ void Unit::CallForAllControlledUnits(Func const& func, bool withTotems, bool wit
|
||||||
template<typename Func>
|
template<typename Func>
|
||||||
bool Unit::CheckAllControlledUnits(Func const& func, bool withTotems, bool withGuardians, bool withCharms) const
|
bool Unit::CheckAllControlledUnits(Func const& func, bool withTotems, bool withGuardians, bool withCharms) const
|
||||||
{
|
{
|
||||||
if (Pet* pet = GetPet())
|
if (Pet const* pet = GetPet())
|
||||||
if (func(pet))
|
if (func(pet))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (withGuardians)
|
if (withGuardians)
|
||||||
{
|
{
|
||||||
for(GuardianPetList::const_iterator itr = m_guardianPets.begin(); itr != m_guardianPets.end(); ++itr)
|
for(GuardianPetList::const_iterator itr = m_guardianPets.begin(); itr != m_guardianPets.end(); ++itr)
|
||||||
if (Unit* guardian = Unit::GetUnit(*this,*itr))
|
if (Unit const* guardian = Unit::GetUnit(*this,*itr))
|
||||||
if (func(guardian))
|
if (func(guardian))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
@ -1959,13 +1966,13 @@ bool Unit::CheckAllControlledUnits(Func const& func, bool withTotems, bool withG
|
||||||
if (withTotems)
|
if (withTotems)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < MAX_TOTEM_SLOT; ++i)
|
for (int i = 0; i < MAX_TOTEM_SLOT; ++i)
|
||||||
if (Unit *totem = _GetTotem(TotemSlot(i)))
|
if (Unit const* totem = _GetTotem(TotemSlot(i)))
|
||||||
if (func(totem))
|
if (func(totem))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (withCharms)
|
if (withCharms)
|
||||||
if(Unit* charm = GetCharm())
|
if(Unit const* charm = GetCharm())
|
||||||
if (func(charm))
|
if (func(charm))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "Database/DatabaseEnv.h"
|
#include "Database/DatabaseEnv.h"
|
||||||
#include "Config/ConfigEnv.h"
|
#include "Config/Config.h"
|
||||||
#include "SystemConfig.h"
|
#include "SystemConfig.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Opcodes.h"
|
#include "Opcodes.h"
|
||||||
|
|
@ -402,9 +402,9 @@ Weather* World::AddWeather(uint32 zone_id)
|
||||||
/// Initialize config values
|
/// Initialize config values
|
||||||
void World::LoadConfigSettings(bool reload)
|
void World::LoadConfigSettings(bool reload)
|
||||||
{
|
{
|
||||||
if(reload)
|
if (reload)
|
||||||
{
|
{
|
||||||
if(!sConfig.Reload())
|
if (!sConfig.Reload())
|
||||||
{
|
{
|
||||||
sLog.outError("World settings reload fail: can't read settings from %s.",sConfig.GetFilename().c_str());
|
sLog.outError("World settings reload fail: can't read settings from %s.",sConfig.GetFilename().c_str());
|
||||||
return;
|
return;
|
||||||
|
|
@ -413,7 +413,7 @@ void World::LoadConfigSettings(bool reload)
|
||||||
|
|
||||||
///- Read the version of the configuration file and warn the user in case of emptiness or mismatch
|
///- Read the version of the configuration file and warn the user in case of emptiness or mismatch
|
||||||
uint32 confVersion = sConfig.GetIntDefault("ConfVersion", 0);
|
uint32 confVersion = sConfig.GetIntDefault("ConfVersion", 0);
|
||||||
if(!confVersion)
|
if (!confVersion)
|
||||||
{
|
{
|
||||||
sLog.outError("*****************************************************************************");
|
sLog.outError("*****************************************************************************");
|
||||||
sLog.outError(" WARNING: mangosd.conf does not include a ConfVersion variable.");
|
sLog.outError(" WARNING: mangosd.conf does not include a ConfVersion variable.");
|
||||||
|
|
@ -1032,7 +1032,7 @@ void World::SetInitialWorldSettings()
|
||||||
sLog.outString( "Loading Objects Pooling Data...");
|
sLog.outString( "Loading Objects Pooling Data...");
|
||||||
sPoolMgr.LoadFromDB();
|
sPoolMgr.LoadFromDB();
|
||||||
|
|
||||||
sLog.outString( "Loading Game Event Data...");
|
sLog.outString( "Loading Game Event Data..."); // must be after sPoolMgr.LoadFromDB for proper load pool events
|
||||||
sLog.outString();
|
sLog.outString();
|
||||||
sGameEventMgr.LoadFromDB();
|
sGameEventMgr.LoadFromDB();
|
||||||
sLog.outString( ">>> Game Event Data loaded" );
|
sLog.outString( ">>> Game Event Data loaded" );
|
||||||
|
|
|
||||||
|
|
@ -171,7 +171,7 @@ bool WorldSession::Update(uint32 /*diff*/)
|
||||||
packet->GetOpcode());
|
packet->GetOpcode());
|
||||||
#endif*/
|
#endif*/
|
||||||
|
|
||||||
OpcodeHandler& opHandle = opcodeTable[packet->GetOpcode()];
|
OpcodeHandler const& opHandle = opcodeTable[packet->GetOpcode()];
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
switch (opHandle.status)
|
switch (opHandle.status)
|
||||||
|
|
@ -184,11 +184,8 @@ bool WorldSession::Update(uint32 /*diff*/)
|
||||||
LogUnexpectedOpcode(packet, "the player has not logged in yet");
|
LogUnexpectedOpcode(packet, "the player has not logged in yet");
|
||||||
}
|
}
|
||||||
else if(_player->IsInWorld())
|
else if(_player->IsInWorld())
|
||||||
{
|
ExecuteOpcode(opHandle, packet);
|
||||||
(this->*opHandle.handler)(*packet);
|
|
||||||
if (packet->rpos() < packet->wpos() && sLog.HasLogLevelOrHigher(LOG_LVL_DEBUG))
|
|
||||||
LogUnprocessedTail(packet);
|
|
||||||
}
|
|
||||||
// lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer
|
// lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer
|
||||||
break;
|
break;
|
||||||
case STATUS_LOGGEDIN_OR_RECENTLY_LOGGEDOUT:
|
case STATUS_LOGGEDIN_OR_RECENTLY_LOGGEDOUT:
|
||||||
|
|
@ -197,12 +194,8 @@ bool WorldSession::Update(uint32 /*diff*/)
|
||||||
LogUnexpectedOpcode(packet, "the player has not logged in yet and not recently logout");
|
LogUnexpectedOpcode(packet, "the player has not logged in yet and not recently logout");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
// not expected _player or must checked in packet hanlder
|
// not expected _player or must checked in packet hanlder
|
||||||
(this->*opHandle.handler)(*packet);
|
ExecuteOpcode(opHandle, packet);
|
||||||
if (packet->rpos() < packet->wpos() && sLog.HasLogLevelOrHigher(LOG_LVL_DEBUG))
|
|
||||||
LogUnprocessedTail(packet);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case STATUS_TRANSFER:
|
case STATUS_TRANSFER:
|
||||||
if(!_player)
|
if(!_player)
|
||||||
|
|
@ -210,11 +203,7 @@ bool WorldSession::Update(uint32 /*diff*/)
|
||||||
else if(_player->IsInWorld())
|
else if(_player->IsInWorld())
|
||||||
LogUnexpectedOpcode(packet, "the player is still in world");
|
LogUnexpectedOpcode(packet, "the player is still in world");
|
||||||
else
|
else
|
||||||
{
|
ExecuteOpcode(opHandle, packet);
|
||||||
(this->*opHandle.handler)(*packet);
|
|
||||||
if (packet->rpos() < packet->wpos() && sLog.HasLogLevelOrHigher(LOG_LVL_DEBUG))
|
|
||||||
LogUnprocessedTail(packet);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case STATUS_AUTHED:
|
case STATUS_AUTHED:
|
||||||
// prevent cheating with skip queue wait
|
// prevent cheating with skip queue wait
|
||||||
|
|
@ -229,9 +218,7 @@ bool WorldSession::Update(uint32 /*diff*/)
|
||||||
if (packet->GetOpcode() != CMSG_SET_ACTIVE_VOICE_CHANNEL)
|
if (packet->GetOpcode() != CMSG_SET_ACTIVE_VOICE_CHANNEL)
|
||||||
m_playerRecentlyLogout = false;
|
m_playerRecentlyLogout = false;
|
||||||
|
|
||||||
(this->*opHandle.handler)(*packet);
|
ExecuteOpcode(opHandle, packet);
|
||||||
if (packet->rpos() < packet->wpos() && sLog.HasLogLevelOrHigher(LOG_LVL_DEBUG))
|
|
||||||
LogUnprocessedTail(packet);
|
|
||||||
break;
|
break;
|
||||||
case STATUS_NEVER:
|
case STATUS_NEVER:
|
||||||
sLog.outError( "SESSION: received not allowed opcode %s (0x%.4X)",
|
sLog.outError( "SESSION: received not allowed opcode %s (0x%.4X)",
|
||||||
|
|
@ -872,3 +859,27 @@ void WorldSession::SendRedirectClient(std::string& ip, uint16 port)
|
||||||
|
|
||||||
SendPacket(&pkt);
|
SendPacket(&pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WorldSession::ExecuteOpcode( OpcodeHandler const& opHandle, WorldPacket* packet )
|
||||||
|
{
|
||||||
|
// need prevent do internal far teleports in handlers because some handlers do lot steps
|
||||||
|
// or call code that can do far teleports in some conditions unexpectedly for generic way work code
|
||||||
|
if (_player)
|
||||||
|
_player->SetCanDelayTeleport(true);
|
||||||
|
|
||||||
|
(this->*opHandle.handler)(*packet);
|
||||||
|
|
||||||
|
if (_player)
|
||||||
|
{
|
||||||
|
// can be not set in fact for login opcode, but this not create porblems.
|
||||||
|
_player->SetCanDelayTeleport(false);
|
||||||
|
|
||||||
|
//we should execute delayed teleports only for alive(!) players
|
||||||
|
//because we don't want player's ghost teleported from graveyard
|
||||||
|
if (_player->IsHasDelayedTeleport())
|
||||||
|
_player->TeleportTo(_player->m_teleport_dest, _player->m_teleport_options);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packet->rpos() < packet->wpos() && sLog.HasLogLevelOrHigher(LOG_LVL_DEBUG))
|
||||||
|
LogUnprocessedTail(packet);
|
||||||
|
}
|
||||||
|
|
@ -43,6 +43,8 @@ class LoginQueryHolder;
|
||||||
class CharacterHandler;
|
class CharacterHandler;
|
||||||
class GMTicket;
|
class GMTicket;
|
||||||
|
|
||||||
|
struct OpcodeHandler;
|
||||||
|
|
||||||
enum AccountDataType
|
enum AccountDataType
|
||||||
{
|
{
|
||||||
GLOBAL_CONFIG_CACHE = 0, // 0x01 g
|
GLOBAL_CONFIG_CACHE = 0, // 0x01 g
|
||||||
|
|
@ -773,6 +775,8 @@ class MANGOS_DLL_SPEC WorldSession
|
||||||
// private trade methods
|
// private trade methods
|
||||||
void moveItems(Item* myItems[], Item* hisItems[]);
|
void moveItems(Item* myItems[], Item* hisItems[]);
|
||||||
|
|
||||||
|
void ExecuteOpcode( OpcodeHandler const& opHandle, WorldPacket* packet );
|
||||||
|
|
||||||
// logging helper
|
// logging helper
|
||||||
void LogUnexpectedOpcode(WorldPacket *packet, const char * reason);
|
void LogUnexpectedOpcode(WorldPacket *packet, const char * reason);
|
||||||
void LogUnprocessedTail(WorldPacket *packet);
|
void LogUnprocessedTail(WorldPacket *packet);
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
|
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "Config/ConfigEnv.h"
|
#include "Config/Config.h"
|
||||||
#include "Database/DatabaseEnv.h"
|
#include "Database/DatabaseEnv.h"
|
||||||
#include "WorldSocket.h"
|
#include "WorldSocket.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
#include "ScriptCalls.h"
|
#include "ScriptCalls.h"
|
||||||
#include "ObjectMgr.h"
|
#include "ObjectMgr.h"
|
||||||
#include "WorldSession.h"
|
#include "WorldSession.h"
|
||||||
#include "Config/ConfigEnv.h"
|
#include "Config/Config.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "AccountMgr.h"
|
#include "AccountMgr.h"
|
||||||
#include "CliRunnable.h"
|
#include "CliRunnable.h"
|
||||||
|
|
@ -593,7 +593,7 @@ bool ChatHandler::HandleServerLogLevelCommand(const char *args)
|
||||||
{
|
{
|
||||||
if(!*args)
|
if(!*args)
|
||||||
{
|
{
|
||||||
PSendSysMessage("Log level: %u");
|
PSendSysMessage("Log level: %u", sLog.GetLogLevel());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -629,7 +629,7 @@ void CliRunnable::run()
|
||||||
///- Display the list of available CLI functions then beep
|
///- Display the list of available CLI functions then beep
|
||||||
sLog.outString();
|
sLog.outString();
|
||||||
|
|
||||||
if(sConfig.GetBoolDefault("BeepAtStart", true))
|
if (sConfig.GetBoolDefault("BeepAtStart", true))
|
||||||
printf("\a"); // \a = Alert
|
printf("\a"); // \a = Alert
|
||||||
|
|
||||||
// print this here the first time
|
// print this here the first time
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "Database/DatabaseEnv.h"
|
#include "Database/DatabaseEnv.h"
|
||||||
#include "Config/ConfigEnv.h"
|
#include "Config/Config.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Master.h"
|
#include "Master.h"
|
||||||
#include "SystemConfig.h"
|
#include "SystemConfig.h"
|
||||||
|
|
@ -31,6 +31,7 @@
|
||||||
#include <openssl/opensslv.h>
|
#include <openssl/opensslv.h>
|
||||||
#include <openssl/crypto.h>
|
#include <openssl/crypto.h>
|
||||||
#include <ace/Version.h>
|
#include <ace/Version.h>
|
||||||
|
#include <ace/Get_Opt.h>
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include "ServiceWin32.h"
|
#include "ServiceWin32.h"
|
||||||
|
|
@ -56,11 +57,11 @@ uint32 realmID; ///< Id of the realm
|
||||||
void usage(const char *prog)
|
void usage(const char *prog)
|
||||||
{
|
{
|
||||||
sLog.outString("Usage: \n %s [<options>]\n"
|
sLog.outString("Usage: \n %s [<options>]\n"
|
||||||
" --version print version and exist\n\r"
|
" -v, --version print version and exist\n\r"
|
||||||
" -c config_file use config_file as configuration file\n\r"
|
" -c config_file use config_file as configuration file\n\r"
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
" Running as service functions:\n\r"
|
" Running as service functions:\n\r"
|
||||||
" --service run as service\n\r"
|
" -s run run as service\n\r"
|
||||||
" -s install install service\n\r"
|
" -s install install service\n\r"
|
||||||
" -s uninstall uninstall service\n\r"
|
" -s uninstall uninstall service\n\r"
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -75,69 +76,69 @@ extern int main(int argc, char **argv)
|
||||||
|
|
||||||
//char *leak = new char[1000]; // test leak detection
|
//char *leak = new char[1000]; // test leak detection
|
||||||
|
|
||||||
///- Command line parsing to get the configuration file name
|
///- Command line parsing
|
||||||
char const* cfg_file = _MANGOSD_CONFIG;
|
char const* cfg_file = _MANGOSD_CONFIG;
|
||||||
int c=1;
|
|
||||||
while( c < argc )
|
#ifdef WIN32
|
||||||
|
char const *options = ":c:s:";
|
||||||
|
#else
|
||||||
|
char const *options = ":c:";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ACE_Get_Opt cmd_opts(argc, argv, options);
|
||||||
|
cmd_opts.long_option("version", 'v');
|
||||||
|
|
||||||
|
int option;
|
||||||
|
while ((option = cmd_opts()) != EOF)
|
||||||
{
|
{
|
||||||
if( strcmp(argv[c],"-c") == 0)
|
switch (option)
|
||||||
{
|
{
|
||||||
if( ++c >= argc )
|
case 'c':
|
||||||
|
cfg_file = cmd_opts.opt_arg();
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
printf("%s\n", _FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_NR,REVISION_ID));
|
||||||
|
return 0;
|
||||||
|
#ifdef WIN32
|
||||||
|
case 's':
|
||||||
{
|
{
|
||||||
sLog.outError("Runtime-Error: -c option requires an input argument");
|
const char *mode = cmd_opts.opt_arg();
|
||||||
usage(argv[0]);
|
|
||||||
return 1;
|
if (!strcmp(mode, "install"))
|
||||||
|
{
|
||||||
|
if (WinServiceInstall())
|
||||||
|
sLog.outString("Installing service");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (!strcmp(mode, "uninstall"))
|
||||||
|
{
|
||||||
|
if (WinServiceUninstall())
|
||||||
|
sLog.outString("Uninstalling service");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (!strcmp(mode, "run"))
|
||||||
|
WinServiceRun();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sLog.outError("Runtime-Error: -%c unsupported argument %s", cmd_opts.opt_opt(), mode);
|
||||||
|
usage(argv[0]);
|
||||||
|
Log::WaitBeforeContinueIfNeed();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
#endif
|
||||||
cfg_file = argv[c];
|
case ':':
|
||||||
}
|
sLog.outError("Runtime-Error: -%c option requires an input argument", cmd_opts.opt_opt());
|
||||||
|
|
||||||
if( strcmp(argv[c],"--version") == 0)
|
|
||||||
{
|
|
||||||
printf("%s\n", _FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_NR,REVISION_ID));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
////////////
|
|
||||||
//Services//
|
|
||||||
////////////
|
|
||||||
if( strcmp(argv[c],"-s") == 0)
|
|
||||||
{
|
|
||||||
if( ++c >= argc )
|
|
||||||
{
|
|
||||||
sLog.outError("Runtime-Error: -s option requires an input argument");
|
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
Log::WaitBeforeContinueIfNeed();
|
Log::WaitBeforeContinueIfNeed();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
default:
|
||||||
if( strcmp(argv[c],"install") == 0)
|
sLog.outError("Runtime-Error: bad format of commandline arguments");
|
||||||
{
|
|
||||||
if (WinServiceInstall())
|
|
||||||
sLog.outString("Installing service");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else if( strcmp(argv[c],"uninstall") == 0)
|
|
||||||
{
|
|
||||||
if(WinServiceUninstall())
|
|
||||||
sLog.outString("Uninstalling service");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sLog.outError("Runtime-Error: unsupported option %s",argv[c]);
|
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
Log::WaitBeforeContinueIfNeed();
|
Log::WaitBeforeContinueIfNeed();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if( strcmp(argv[c],"--service") == 0)
|
|
||||||
{
|
|
||||||
WinServiceRun();
|
|
||||||
}
|
|
||||||
////
|
|
||||||
#endif
|
|
||||||
++c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sConfig.SetSource(cfg_file))
|
if (!sConfig.SetSource(cfg_file))
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "Policies/SingletonImp.h"
|
#include "Policies/SingletonImp.h"
|
||||||
#include "SystemConfig.h"
|
#include "SystemConfig.h"
|
||||||
#include "Config/ConfigEnv.h"
|
#include "Config/Config.h"
|
||||||
#include "Database/DatabaseEnv.h"
|
#include "Database/DatabaseEnv.h"
|
||||||
#include "CliRunnable.h"
|
#include "CliRunnable.h"
|
||||||
#include "RASocket.h"
|
#include "RASocket.h"
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "RASocket.h"
|
#include "RASocket.h"
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
#include "Config/ConfigEnv.h"
|
#include "Config/Config.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "AccountMgr.h"
|
#include "AccountMgr.h"
|
||||||
#include "Language.h"
|
#include "Language.h"
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
#####################################
|
#####################################
|
||||||
# MaNGOS Configuration file #
|
# MaNGOS Configuration file #
|
||||||
#####################################
|
#####################################
|
||||||
ConfVersion=2010051901
|
|
||||||
|
[MangosdConf]
|
||||||
|
ConfVersion=2010062001
|
||||||
|
|
||||||
###################################################################################################################
|
###################################################################################################################
|
||||||
# CONNECTIONS AND DIRECTORIES
|
# CONNECTIONS AND DIRECTORIES
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "Database/DatabaseEnv.h"
|
#include "Database/DatabaseEnv.h"
|
||||||
#include "Config/ConfigEnv.h"
|
#include "Config/Config.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "RealmList.h"
|
#include "RealmList.h"
|
||||||
#include "AuthSocket.h"
|
#include "AuthSocket.h"
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
#include "Database/DatabaseEnv.h"
|
#include "Database/DatabaseEnv.h"
|
||||||
#include "RealmList.h"
|
#include "RealmList.h"
|
||||||
|
|
||||||
#include "Config/ConfigEnv.h"
|
#include "Config/Config.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "AuthSocket.h"
|
#include "AuthSocket.h"
|
||||||
#include "SystemConfig.h"
|
#include "SystemConfig.h"
|
||||||
|
|
@ -35,6 +35,7 @@
|
||||||
#include <openssl/opensslv.h>
|
#include <openssl/opensslv.h>
|
||||||
#include <openssl/crypto.h>
|
#include <openssl/crypto.h>
|
||||||
|
|
||||||
|
#include <ace/Get_Opt.h>
|
||||||
#include <ace/Dev_Poll_Reactor.h>
|
#include <ace/Dev_Poll_Reactor.h>
|
||||||
#include <ace/TP_Reactor.h>
|
#include <ace/TP_Reactor.h>
|
||||||
#include <ace/ACE.h>
|
#include <ace/ACE.h>
|
||||||
|
|
@ -67,11 +68,11 @@ DatabaseType loginDatabase; ///< Accessor to the
|
||||||
void usage(const char *prog)
|
void usage(const char *prog)
|
||||||
{
|
{
|
||||||
sLog.outString("Usage: \n %s [<options>]\n"
|
sLog.outString("Usage: \n %s [<options>]\n"
|
||||||
" --version print version and exist\n\r"
|
" -v, --version print version and exist\n\r"
|
||||||
" -c config_file use config_file as configuration file\n\r"
|
" -c config_file use config_file as configuration file\n\r"
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
" Running as service functions:\n\r"
|
" Running as service functions:\n\r"
|
||||||
" --service run as service\n\r"
|
" -s run run as service\n\r"
|
||||||
" -s install install service\n\r"
|
" -s install install service\n\r"
|
||||||
" -s uninstall uninstall service\n\r"
|
" -s uninstall uninstall service\n\r"
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -81,70 +82,69 @@ void usage(const char *prog)
|
||||||
/// Launch the realm server
|
/// Launch the realm server
|
||||||
extern int main(int argc, char **argv)
|
extern int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
///- Command line parsing to get the configuration file name
|
///- Command line parsing
|
||||||
char const* cfg_file = _REALMD_CONFIG;
|
char const* cfg_file = _REALMD_CONFIG;
|
||||||
int c=1;
|
|
||||||
while( c < argc )
|
#ifdef WIN32
|
||||||
|
char const *options = ":c:s:";
|
||||||
|
#else
|
||||||
|
char const *options = ":c:";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ACE_Get_Opt cmd_opts(argc, argv, options);
|
||||||
|
cmd_opts.long_option("version", 'v');
|
||||||
|
|
||||||
|
int option;
|
||||||
|
while ((option = cmd_opts()) != EOF)
|
||||||
{
|
{
|
||||||
if( strcmp(argv[c],"-c") == 0)
|
switch (option)
|
||||||
{
|
{
|
||||||
if( ++c >= argc )
|
case 'c':
|
||||||
|
cfg_file = cmd_opts.opt_arg();
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
printf("%s\n", _FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_NR,REVISION_ID));
|
||||||
|
return 0;
|
||||||
|
#ifdef WIN32
|
||||||
|
case 's':
|
||||||
{
|
{
|
||||||
sLog.outError("Runtime-Error: -c option requires an input argument");
|
const char *mode = cmd_opts.opt_arg();
|
||||||
usage(argv[0]);
|
|
||||||
Log::WaitBeforeContinueIfNeed();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
cfg_file = argv[c];
|
|
||||||
}
|
|
||||||
|
|
||||||
if( strcmp(argv[c],"--version") == 0)
|
if (!strcmp(mode, "install"))
|
||||||
{
|
{
|
||||||
printf("%s\n", _FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_NR,REVISION_ID));
|
if (WinServiceInstall())
|
||||||
return 0;
|
sLog.outString("Installing service");
|
||||||
}
|
return 1;
|
||||||
|
}
|
||||||
#ifdef WIN32
|
else if (!strcmp(mode, "uninstall"))
|
||||||
////////////
|
{
|
||||||
//Services//
|
if (WinServiceUninstall())
|
||||||
////////////
|
sLog.outString("Uninstalling service");
|
||||||
if( strcmp(argv[c],"-s") == 0)
|
return 1;
|
||||||
{
|
}
|
||||||
if( ++c >= argc )
|
else if (!strcmp(mode, "run"))
|
||||||
{
|
WinServiceRun();
|
||||||
sLog.outError("Runtime-Error: -s option requires an input argument");
|
else
|
||||||
|
{
|
||||||
|
sLog.outError("Runtime-Error: -%c unsupported argument %s", cmd_opts.opt_opt(), mode);
|
||||||
|
usage(argv[0]);
|
||||||
|
Log::WaitBeforeContinueIfNeed();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
case ':':
|
||||||
|
sLog.outError("Runtime-Error: -%c option requires an input argument", cmd_opts.opt_opt());
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
Log::WaitBeforeContinueIfNeed();
|
Log::WaitBeforeContinueIfNeed();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
default:
|
||||||
if( strcmp(argv[c],"install") == 0)
|
sLog.outError("Runtime-Error: bad format of commandline arguments");
|
||||||
{
|
|
||||||
if (WinServiceInstall())
|
|
||||||
sLog.outString("Installing service");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else if( strcmp(argv[c],"uninstall") == 0)
|
|
||||||
{
|
|
||||||
if(WinServiceUninstall())
|
|
||||||
sLog.outString("Uninstalling service");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sLog.outError("Runtime-Error: unsupported option %s",argv[c]);
|
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
Log::WaitBeforeContinueIfNeed();
|
Log::WaitBeforeContinueIfNeed();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if( strcmp(argv[c],"--service") == 0)
|
|
||||||
{
|
|
||||||
WinServiceRun();
|
|
||||||
}
|
|
||||||
////
|
|
||||||
#endif
|
|
||||||
++c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sConfig.SetSource(cfg_file))
|
if (!sConfig.SetSource(cfg_file))
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
############################################
|
############################################
|
||||||
# MaNGOS realmd configuration file #
|
# MaNGOS realmd configuration file #
|
||||||
############################################
|
############################################
|
||||||
ConfVersion=2007062001
|
|
||||||
|
[RealmdConf]
|
||||||
|
ConfVersion=2010062001
|
||||||
|
|
||||||
###################################################################################################################
|
###################################################################################################################
|
||||||
# REALMD SETTINGS
|
# REALMD SETTINGS
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,36 @@
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ConfigEnv.h"
|
#include "Config.h"
|
||||||
|
#include "ace/Configuration_Import_Export.h"
|
||||||
|
|
||||||
#include "Policies/SingletonImp.h"
|
#include "Policies/SingletonImp.h"
|
||||||
|
|
||||||
INSTANTIATE_SINGLETON_1(Config);
|
INSTANTIATE_SINGLETON_1(Config);
|
||||||
|
|
||||||
|
static bool GetValueHelper(ACE_Configuration_Heap *mConf, const char *name, ACE_TString &result)
|
||||||
|
{
|
||||||
|
if (!mConf)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ACE_TString section_name;
|
||||||
|
ACE_Configuration_Section_Key section_key;
|
||||||
|
ACE_Configuration_Section_Key root_key = mConf->root_section();
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (mConf->enumerate_sections(root_key, i, section_name) == 0)
|
||||||
|
{
|
||||||
|
mConf->open_section(root_key, section_name.c_str(), 0, section_key);
|
||||||
|
if (mConf->get_string_value(section_key, name, result) == 0)
|
||||||
|
return true;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Config::Config()
|
Config::Config()
|
||||||
: mIgnoreCase(true), mConf(NULL)
|
: mConf(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -31,9 +54,8 @@ Config::~Config()
|
||||||
delete mConf;
|
delete mConf;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Config::SetSource(const char *file, bool ignorecase)
|
bool Config::SetSource(const char *file)
|
||||||
{
|
{
|
||||||
mIgnoreCase = ignorecase;
|
|
||||||
mFilename = file;
|
mFilename = file;
|
||||||
|
|
||||||
return Reload();
|
return Reload();
|
||||||
|
|
@ -42,43 +64,33 @@ bool Config::SetSource(const char *file, bool ignorecase)
|
||||||
bool Config::Reload()
|
bool Config::Reload()
|
||||||
{
|
{
|
||||||
delete mConf;
|
delete mConf;
|
||||||
|
mConf = new ACE_Configuration_Heap;
|
||||||
|
|
||||||
mConf = new DOTCONFDocument(mIgnoreCase ?
|
if (mConf->open() == 0)
|
||||||
DOTCONFDocument::CASEINSENSETIVE :
|
|
||||||
DOTCONFDocument::CASESENSITIVE);
|
|
||||||
|
|
||||||
if (mConf->setContent(mFilename.c_str()) == -1)
|
|
||||||
{
|
{
|
||||||
delete mConf;
|
ACE_Ini_ImpExp config_importer(*mConf);
|
||||||
mConf = NULL;
|
if (config_importer.import_config(mFilename.c_str()) == 0)
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
delete mConf;
|
||||||
|
mConf = NULL;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Config::GetStringDefault(const char* name, const char* def)
|
std::string Config::GetStringDefault(const char* name, const char* def)
|
||||||
{
|
{
|
||||||
if (!mConf)
|
ACE_TString val;
|
||||||
return std::string(def);
|
return GetValueHelper(mConf, name, val) ? val.c_str() : def;
|
||||||
|
|
||||||
DOTCONFDocumentNode const *node = mConf->findNode(name);
|
|
||||||
if (!node || !node->getValue())
|
|
||||||
return std::string(def);
|
|
||||||
|
|
||||||
return std::string(node->getValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Config::GetBoolDefault(const char* name, bool def)
|
bool Config::GetBoolDefault(const char* name, bool def)
|
||||||
{
|
{
|
||||||
if (!mConf)
|
ACE_TString val;
|
||||||
|
if (!GetValueHelper(mConf, name, val))
|
||||||
return def;
|
return def;
|
||||||
|
|
||||||
DOTCONFDocumentNode const *node = mConf->findNode(name);
|
const char* str = val.c_str();
|
||||||
if (!node || !node->getValue())
|
|
||||||
return def;
|
|
||||||
|
|
||||||
const char* str = node->getValue();
|
|
||||||
if (strcmp(str, "true") == 0 || strcmp(str, "TRUE") == 0 ||
|
if (strcmp(str, "true") == 0 || strcmp(str, "TRUE") == 0 ||
|
||||||
strcmp(str, "yes") == 0 || strcmp(str, "YES") == 0 ||
|
strcmp(str, "yes") == 0 || strcmp(str, "YES") == 0 ||
|
||||||
strcmp(str, "1") == 0)
|
strcmp(str, "1") == 0)
|
||||||
|
|
@ -90,25 +102,13 @@ bool Config::GetBoolDefault(const char* name, bool def)
|
||||||
|
|
||||||
int32 Config::GetIntDefault(const char* name, int32 def)
|
int32 Config::GetIntDefault(const char* name, int32 def)
|
||||||
{
|
{
|
||||||
if (!mConf)
|
ACE_TString val;
|
||||||
return def;
|
return GetValueHelper(mConf, name, val) ? atoi(val.c_str()) : def;
|
||||||
|
|
||||||
DOTCONFDocumentNode const *node = mConf->findNode(name);
|
|
||||||
if (!node || !node->getValue())
|
|
||||||
return def;
|
|
||||||
|
|
||||||
return atoi(node->getValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float Config::GetFloatDefault(const char* name, float def)
|
float Config::GetFloatDefault(const char* name, float def)
|
||||||
{
|
{
|
||||||
if (!mConf)
|
ACE_TString val;
|
||||||
return def;
|
return GetValueHelper(mConf, name, val) ? (float)atof(val.c_str()) : def;
|
||||||
|
|
||||||
DOTCONFDocumentNode const *node = mConf->findNode(name);
|
|
||||||
if (!node || !node->getValue())
|
|
||||||
return def;
|
|
||||||
|
|
||||||
return (float)atof(node->getValue());
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,11 @@
|
||||||
#ifndef CONFIG_H
|
#ifndef CONFIG_H
|
||||||
#define CONFIG_H
|
#define CONFIG_H
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
#include <Policies/Singleton.h>
|
#include <Policies/Singleton.h>
|
||||||
#include "Platform/Define.h"
|
#include "Platform/Define.h"
|
||||||
|
|
||||||
class DOTCONFDocument;
|
class ACE_Configuration_Heap;
|
||||||
|
|
||||||
class MANGOS_DLL_SPEC Config
|
class MANGOS_DLL_SPEC Config
|
||||||
{
|
{
|
||||||
|
|
@ -31,7 +32,7 @@ class MANGOS_DLL_SPEC Config
|
||||||
Config();
|
Config();
|
||||||
~Config();
|
~Config();
|
||||||
|
|
||||||
bool SetSource(const char *file, bool ignorecase = true);
|
bool SetSource(const char *file);
|
||||||
bool Reload();
|
bool Reload();
|
||||||
|
|
||||||
std::string GetStringDefault(const char* name, const char* def);
|
std::string GetStringDefault(const char* name, const char* def);
|
||||||
|
|
@ -44,8 +45,7 @@ class MANGOS_DLL_SPEC Config
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::string mFilename;
|
std::string mFilename;
|
||||||
bool mIgnoreCase;
|
ACE_Configuration_Heap *mConf;
|
||||||
DOTCONFDocument *mConf;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define sConfig MaNGOS::Singleton<Config>::Instance()
|
#define sConfig MaNGOS::Singleton<Config>::Instance()
|
||||||
|
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(CONFIGENVIRONMENT_H)
|
|
||||||
|
|
||||||
#define CONFIGENVIRONMENT_H
|
|
||||||
|
|
||||||
#include "Common.h"
|
|
||||||
#include "dotconfpp/dotconfpp.h"
|
|
||||||
#include "Config.h"
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,137 +0,0 @@
|
||||||
<?xml version="1.0" encoding="Windows-1252"?>
|
|
||||||
<VisualStudioProject
|
|
||||||
ProjectType="Visual C++"
|
|
||||||
Version="7.10"
|
|
||||||
Name="ConfigLibrary"
|
|
||||||
ProjectGUID="{C849D54F-32A6-4025-95BE-E64D1CF0686E}"
|
|
||||||
Keyword="Win32Proj">
|
|
||||||
<Platforms>
|
|
||||||
<Platform
|
|
||||||
Name="Win32"/>
|
|
||||||
</Platforms>
|
|
||||||
<Configurations>
|
|
||||||
<Configuration
|
|
||||||
Name="Debug|Win32"
|
|
||||||
OutputDirectory="Debug"
|
|
||||||
IntermediateDirectory="Debug"
|
|
||||||
ConfigurationType="4"
|
|
||||||
CharacterSet="2">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="0"
|
|
||||||
AdditionalIncludeDirectories=""
|
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
|
||||||
MinimalRebuild="TRUE"
|
|
||||||
BasicRuntimeChecks="3"
|
|
||||||
RuntimeLibrary="1"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
WarningLevel="3"
|
|
||||||
Detect64BitPortabilityProblems="TRUE"
|
|
||||||
DebugInformationFormat="4"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCustomBuildTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCLibrarianTool"
|
|
||||||
OutputFile="$(OutDir)/ConfigLibrary.lib"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCMIDLTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPostBuildEventTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreBuildEventTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreLinkEventTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCResourceCompilerTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebServiceProxyGeneratorTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXMLDataGeneratorTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManagedWrapperGeneratorTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
|
||||||
</Configuration>
|
|
||||||
<Configuration
|
|
||||||
Name="Release|Win32"
|
|
||||||
OutputDirectory="Release"
|
|
||||||
IntermediateDirectory="Release"
|
|
||||||
ConfigurationType="4"
|
|
||||||
CharacterSet="2">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
AdditionalIncludeDirectories=""
|
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
|
|
||||||
RuntimeLibrary="0"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
WarningLevel="3"
|
|
||||||
Detect64BitPortabilityProblems="TRUE"
|
|
||||||
DebugInformationFormat="3"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCustomBuildTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCLibrarianTool"
|
|
||||||
OutputFile="$(OutDir)/ConfigLibrary.lib"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCMIDLTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPostBuildEventTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreBuildEventTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreLinkEventTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCResourceCompilerTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebServiceProxyGeneratorTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXMLDataGeneratorTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManagedWrapperGeneratorTool"/>
|
|
||||||
<Tool
|
|
||||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
|
||||||
</Configuration>
|
|
||||||
</Configurations>
|
|
||||||
<References>
|
|
||||||
</References>
|
|
||||||
<Files>
|
|
||||||
<Filter
|
|
||||||
Name="Source Files"
|
|
||||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
|
||||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
|
||||||
<File
|
|
||||||
RelativePath=".\Config.cpp">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\dotconfpp\dotconfpp.cpp">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\dotconfpp\mempool.cpp">
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
|
||||||
Name="Header Files"
|
|
||||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
|
||||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
|
|
||||||
<File
|
|
||||||
RelativePath=".\Config.h">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\ConfigEnv.h">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\dotconfpp\dotconfpp.h">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\dotconfpp\mempool.h">
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
|
||||||
Name="Resource Files"
|
|
||||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
|
|
||||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
|
|
||||||
</Filter>
|
|
||||||
</Files>
|
|
||||||
<Globals>
|
|
||||||
</Globals>
|
|
||||||
</VisualStudioProject>
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
## Sub-directories to parse
|
## Sub-directories to parse
|
||||||
|
|
||||||
## CPP flags for includes, defines, etc.
|
## CPP flags for includes, defines, etc.
|
||||||
AM_CPPFLAGS = $(MANGOS_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(srcdir)/../../../dep/include -I$(srcdir)/../../framework -I$(srcdir)/../../shared -I$(srcdir)/../../../dep/include/g3dlite
|
AM_CPPFLAGS = $(MANGOS_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(srcdir)/../../../dep/include -I$(srcdir)/../../framework -I$(srcdir)/../../shared
|
||||||
|
|
||||||
## Build MaNGOS shared library and its parts as convenience library.
|
## Build MaNGOS shared library and its parts as convenience library.
|
||||||
# All libraries will be convenience libraries. Might be changed to shared
|
# All libraries will be convenience libraries. Might be changed to shared
|
||||||
|
|
@ -27,14 +27,5 @@ AM_CPPFLAGS = $(MANGOS_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(sr
|
||||||
noinst_LIBRARIES = libmangosconfig.a
|
noinst_LIBRARIES = libmangosconfig.a
|
||||||
|
|
||||||
libmangosconfig_a_SOURCES = \
|
libmangosconfig_a_SOURCES = \
|
||||||
dotconfpp/dotconfpp.cpp \
|
|
||||||
dotconfpp/dotconfpp.h \
|
|
||||||
dotconfpp/mempool.cpp \
|
|
||||||
dotconfpp/mempool.h \
|
|
||||||
Config.cpp \
|
Config.cpp \
|
||||||
Config.h \
|
Config.h
|
||||||
ConfigEnv.h
|
|
||||||
|
|
||||||
# VC++ project workspace for dotconfpp
|
|
||||||
EXTRA_DIST = \
|
|
||||||
ConfigLibrary.vcproj
|
|
||||||
|
|
|
||||||
|
|
@ -1,703 +0,0 @@
|
||||||
#include "Common.h"
|
|
||||||
#include "dotconfpp.h"
|
|
||||||
#include <ace/OS_NS_stdlib.h>
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
# define strcasecmp stricmp
|
|
||||||
# include <io.h>
|
|
||||||
#else
|
|
||||||
# include <unistd.h>
|
|
||||||
# include <limits.h>
|
|
||||||
# include <stdint.h>
|
|
||||||
# include <strings.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(R_OK)
|
|
||||||
# define R_OK 04
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DOTCONFDocumentNode::DOTCONFDocumentNode()
|
|
||||||
: previousNode(NULL), nextNode(NULL), parentNode(NULL), childNode(NULL),
|
|
||||||
values(NULL), valuesCount(0), name(NULL), lineNum(0),
|
|
||||||
fileName(NULL), closed(true)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
DOTCONFDocumentNode::~DOTCONFDocumentNode()
|
|
||||||
{
|
|
||||||
free(name);
|
|
||||||
|
|
||||||
if (values != NULL)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < valuesCount; ++i)
|
|
||||||
free(values[i]);
|
|
||||||
|
|
||||||
free(values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DOTCONFDocumentNode::pushValue(char* _value)
|
|
||||||
{
|
|
||||||
++valuesCount;
|
|
||||||
values = (char**)realloc(values, valuesCount * sizeof(char*));
|
|
||||||
values[valuesCount - 1] = strdup(_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* DOTCONFDocumentNode::getValue(int index) const
|
|
||||||
{
|
|
||||||
if (index >= valuesCount)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return values[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
DOTCONFDocument::DOTCONFDocument(DOTCONFDocument::CaseSensitive caseSensitivity)
|
|
||||||
: mempool(NULL), curParent(NULL), curPrev(NULL), curLine(0), file(NULL), fileName(NULL)
|
|
||||||
{
|
|
||||||
switch (caseSensitivity)
|
|
||||||
{
|
|
||||||
case CASESENSITIVE:
|
|
||||||
cmp_func = strcmp;
|
|
||||||
break;
|
|
||||||
case CASEINSENSETIVE:
|
|
||||||
cmp_func = strcasecmp;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
mempool = new AsyncDNSMemPool(1024);
|
|
||||||
mempool->initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
DOTCONFDocument::~DOTCONFDocument()
|
|
||||||
{
|
|
||||||
for (NodeList::iterator i = nodeTree.begin(); i != nodeTree.end(); ++i)
|
|
||||||
delete(*i);
|
|
||||||
|
|
||||||
for (CharList::iterator i = requiredOptions.begin(); i != requiredOptions.end(); ++i)
|
|
||||||
free(*i);
|
|
||||||
|
|
||||||
for (CharList::iterator i = processedFiles.begin(); i != processedFiles.end(); ++i)
|
|
||||||
free(*i);
|
|
||||||
|
|
||||||
free(fileName);
|
|
||||||
delete mempool;
|
|
||||||
}
|
|
||||||
|
|
||||||
int DOTCONFDocument::cleanupLine(char* line)
|
|
||||||
{
|
|
||||||
char* start = line;
|
|
||||||
char* bg = line;
|
|
||||||
bool multiline = false;
|
|
||||||
bool concat = false;
|
|
||||||
char* word = NULL;
|
|
||||||
|
|
||||||
if (!words.empty() && quoted)
|
|
||||||
concat = true;
|
|
||||||
|
|
||||||
while (*line)
|
|
||||||
{
|
|
||||||
if ((*line == '#' || *line == ';') && !quoted)
|
|
||||||
{
|
|
||||||
*bg = 0;
|
|
||||||
if (strlen(start))
|
|
||||||
{
|
|
||||||
if (concat)
|
|
||||||
{
|
|
||||||
word = (char*)mempool->Alloc(strlen(words.back()) + strlen(start) + 1);
|
|
||||||
strcpy(word, words.back());
|
|
||||||
strcat(word, start);
|
|
||||||
words.pop_back();
|
|
||||||
concat = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
word = mempool->Strdup(start);
|
|
||||||
|
|
||||||
words.push_back(word);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*line == '=' && !quoted)
|
|
||||||
{
|
|
||||||
*line = ' ';
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allowing \" in there causes problems with directory paths
|
|
||||||
// like "C:\MaNGOS\"
|
|
||||||
//if(*line == '\\' && (*(line+1) == '"' || *(line+1) == '\'')){
|
|
||||||
if (*line == '\\' && (*(line + 1) == '\''))
|
|
||||||
{
|
|
||||||
*bg++ = *(line + 1);
|
|
||||||
line += 2;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*line == '\\' && *(line + 1) == 'n')
|
|
||||||
{
|
|
||||||
*bg++ = '\n';
|
|
||||||
line += 2;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*line == '\\' && *(line + 1) == 'r')
|
|
||||||
{
|
|
||||||
*bg++ = '\r';
|
|
||||||
line += 2;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*line == '\\' && (*(line + 1) == '\n' || *(line + 1) == '\r'))
|
|
||||||
{
|
|
||||||
*bg = 0;
|
|
||||||
if (strlen(start))
|
|
||||||
{
|
|
||||||
if (concat)
|
|
||||||
{
|
|
||||||
word = (char*)mempool->Alloc(strlen(words.back()) + strlen(start) + 1);
|
|
||||||
strcpy(word, words.back());
|
|
||||||
strcat(word, start);
|
|
||||||
words.pop_back();
|
|
||||||
concat = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
word = mempool->Strdup(start);
|
|
||||||
|
|
||||||
words.push_back(word);
|
|
||||||
}
|
|
||||||
|
|
||||||
multiline = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*line == '"' || *line == '\'')
|
|
||||||
{
|
|
||||||
quoted = !quoted;
|
|
||||||
++line;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isspace((unsigned char)*line) && !quoted)
|
|
||||||
{
|
|
||||||
*bg++ = 0;
|
|
||||||
if (strlen(start))
|
|
||||||
{
|
|
||||||
if (concat)
|
|
||||||
{
|
|
||||||
word = (char*)mempool->Alloc(strlen(words.back()) + strlen(start) + 1);
|
|
||||||
strcpy(word, words.back());
|
|
||||||
strcat(word, start);
|
|
||||||
words.pop_back();
|
|
||||||
concat = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
word = mempool->Strdup(start);
|
|
||||||
|
|
||||||
words.push_back(word);
|
|
||||||
}
|
|
||||||
|
|
||||||
start = bg;
|
|
||||||
while (isspace((unsigned char)*++line))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
*bg++ = *line++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (quoted && !multiline)
|
|
||||||
{
|
|
||||||
error(curLine, fileName, "unterminated quote");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return multiline ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int DOTCONFDocument::parseLine()
|
|
||||||
{
|
|
||||||
char* word = NULL;
|
|
||||||
char* nodeName = NULL;
|
|
||||||
char* nodeValue = NULL;
|
|
||||||
DOTCONFDocumentNode* tagNode = NULL;
|
|
||||||
bool newNode = false;
|
|
||||||
|
|
||||||
for (CharList::iterator i = words.begin(); i != words.end(); ++i)
|
|
||||||
{
|
|
||||||
word = *i;
|
|
||||||
|
|
||||||
if (*word == '<')
|
|
||||||
newNode = true;
|
|
||||||
|
|
||||||
if (newNode)
|
|
||||||
{
|
|
||||||
nodeValue = NULL;
|
|
||||||
nodeName = NULL;
|
|
||||||
newNode = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t wordLen = strlen(word);
|
|
||||||
if (word[wordLen - 1] == '>')
|
|
||||||
{
|
|
||||||
word[wordLen - 1] = 0;
|
|
||||||
newNode = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nodeName == NULL)
|
|
||||||
{
|
|
||||||
nodeName = word;
|
|
||||||
bool closed = true;
|
|
||||||
if (*nodeName == '<')
|
|
||||||
{
|
|
||||||
if (*(nodeName + 1) != '/')
|
|
||||||
{
|
|
||||||
++nodeName;
|
|
||||||
closed = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NodeList::reverse_iterator itr = nodeTree.rbegin();
|
|
||||||
nodeName += 2;
|
|
||||||
for (; itr != nodeTree.rend(); ++itr)
|
|
||||||
{
|
|
||||||
if (!cmp_func(nodeName, (*itr)->name) && !(*itr)->closed)
|
|
||||||
{
|
|
||||||
(*itr)->closed = true;
|
|
||||||
curParent = (*itr)->parentNode;
|
|
||||||
curPrev = *itr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(itr == nodeTree.rend())
|
|
||||||
{
|
|
||||||
error(curLine, fileName, "not matched closing tag </%s>", nodeName);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tagNode = new DOTCONFDocumentNode;
|
|
||||||
tagNode->name = strdup(nodeName);
|
|
||||||
tagNode->document = this;
|
|
||||||
tagNode->fileName = processedFiles.back();
|
|
||||||
tagNode->lineNum = curLine;
|
|
||||||
tagNode->closed = closed;
|
|
||||||
|
|
||||||
if(!nodeTree.empty())
|
|
||||||
{
|
|
||||||
DOTCONFDocumentNode* prev = nodeTree.back();
|
|
||||||
if (prev->closed)
|
|
||||||
{
|
|
||||||
curPrev->nextNode = tagNode;
|
|
||||||
tagNode->previousNode = curPrev;
|
|
||||||
tagNode->parentNode = curParent;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
prev->childNode = tagNode;
|
|
||||||
tagNode->parentNode = prev;
|
|
||||||
curParent = prev;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nodeTree.push_back(tagNode);
|
|
||||||
curPrev = tagNode;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nodeValue = word;
|
|
||||||
tagNode->pushValue(nodeValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int DOTCONFDocument::parseFile(DOTCONFDocumentNode* _parent)
|
|
||||||
{
|
|
||||||
char str[512];
|
|
||||||
int ret = 0;
|
|
||||||
curLine = 0;
|
|
||||||
curParent = _parent;
|
|
||||||
|
|
||||||
quoted = false;
|
|
||||||
size_t slen = 0;
|
|
||||||
|
|
||||||
while (fgets(str, 511, file))
|
|
||||||
{
|
|
||||||
++curLine;
|
|
||||||
slen = strlen(str);
|
|
||||||
if (slen >= 510)
|
|
||||||
error(curLine, fileName, "warning: line too long");
|
|
||||||
|
|
||||||
if (str[slen - 1] != '\n')
|
|
||||||
{
|
|
||||||
str[slen] = '\n';
|
|
||||||
str[slen + 1] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ret = cleanupLine(str)) == -1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (ret == 0)
|
|
||||||
{
|
|
||||||
if (!words.empty())
|
|
||||||
{
|
|
||||||
ret = parseLine();
|
|
||||||
mempool->Free();
|
|
||||||
words.clear();
|
|
||||||
|
|
||||||
if(ret == -1)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int DOTCONFDocument::checkConfig(const NodeList::iterator& from)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
DOTCONFDocumentNode* tagNode = NULL;
|
|
||||||
int vi = 0;
|
|
||||||
for (NodeList::iterator i = from; i != nodeTree.end(); ++i)
|
|
||||||
{
|
|
||||||
tagNode = *i;
|
|
||||||
if (!tagNode->closed)
|
|
||||||
{
|
|
||||||
error(tagNode->lineNum, tagNode->fileName, "unclosed tag %s", tagNode->name);
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
vi = 0;
|
|
||||||
while (vi < tagNode->valuesCount)
|
|
||||||
{
|
|
||||||
if (strstr(tagNode->values[vi], "${") && strchr(tagNode->values[vi], '}'))
|
|
||||||
{
|
|
||||||
ret = macroSubstitute(tagNode, vi);
|
|
||||||
mempool->Free();
|
|
||||||
if (ret == -1)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
++vi;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == -1)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int DOTCONFDocument::setContent(const char* _fileName)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
char realpathBuf[MANGOS_PATH_MAX];
|
|
||||||
|
|
||||||
if (ACE_OS::realpath(_fileName, realpathBuf) == NULL)
|
|
||||||
{
|
|
||||||
error(0, NULL, "realpath (%s) failed: %s", _fileName, strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
fileName = strdup(realpathBuf);
|
|
||||||
|
|
||||||
processedFiles.push_back(strdup(realpathBuf));
|
|
||||||
|
|
||||||
if ((file = fopen(fileName, "r")) == NULL)
|
|
||||||
{
|
|
||||||
error(0, NULL, "failed to open file '%s': %s", fileName, strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try read utf8 header and skip it if exist
|
|
||||||
unsigned int utf8header = 0;
|
|
||||||
fgets((char*)&utf8header, 4, file); // Try read header
|
|
||||||
if (utf8header != 0x00BFBBEF) // If not exist
|
|
||||||
fseek(file, 0, SEEK_SET); // Reset read position
|
|
||||||
|
|
||||||
ret = parseFile();
|
|
||||||
|
|
||||||
fclose(file);
|
|
||||||
|
|
||||||
if (!ret)
|
|
||||||
{
|
|
||||||
if ((ret = checkConfig(nodeTree.begin())) == -1)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
NodeList::iterator from;
|
|
||||||
DOTCONFDocumentNode* tagNode = NULL;
|
|
||||||
int vi = 0;
|
|
||||||
for (NodeList::iterator i = nodeTree.begin(); i != nodeTree.end(); ++i)
|
|
||||||
{
|
|
||||||
tagNode = *i;
|
|
||||||
if (!cmp_func("DOTCONFPPIncludeFile", tagNode->name))
|
|
||||||
{
|
|
||||||
vi = 0;
|
|
||||||
while (vi < tagNode->valuesCount)
|
|
||||||
{
|
|
||||||
if (access(tagNode->values[vi], R_OK) == -1)
|
|
||||||
{
|
|
||||||
error(tagNode->lineNum, tagNode->fileName, "%s: %s", tagNode->values[vi], strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ACE_OS::realpath(tagNode->values[vi], realpathBuf) == NULL)
|
|
||||||
{
|
|
||||||
error(tagNode->lineNum, tagNode->fileName, "realpath (%s) failed: %s", tagNode->values[vi], strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool processed = false;
|
|
||||||
for (CharList::const_iterator itInode = processedFiles.begin(); itInode != processedFiles.end(); ++itInode)
|
|
||||||
{
|
|
||||||
if (!strcmp(*itInode, realpathBuf))
|
|
||||||
{
|
|
||||||
processed = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(processed)
|
|
||||||
break;
|
|
||||||
|
|
||||||
processedFiles.push_back(strdup(realpathBuf));
|
|
||||||
|
|
||||||
file = fopen(tagNode->values[vi], "r");
|
|
||||||
if(file == NULL)
|
|
||||||
{
|
|
||||||
error(tagNode->lineNum, fileName, "failed to open file '%s': %s", tagNode->values[vi], strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
fileName = strdup(realpathBuf);
|
|
||||||
from = nodeTree.end();
|
|
||||||
--from;
|
|
||||||
|
|
||||||
ret = parseFile();
|
|
||||||
fclose(file);
|
|
||||||
|
|
||||||
if (ret == -1)
|
|
||||||
return -1;
|
|
||||||
if (checkConfig(++from) == -1)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
++vi;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!requiredOptions.empty())
|
|
||||||
ret = checkRequiredOptions();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int DOTCONFDocument::checkRequiredOptions()
|
|
||||||
{
|
|
||||||
for (CharList::const_iterator ci = requiredOptions.begin(); ci != requiredOptions.end(); ++ci)
|
|
||||||
{
|
|
||||||
bool matched = false;
|
|
||||||
for (NodeList::iterator i = nodeTree.begin(); i != nodeTree.end(); ++i)
|
|
||||||
{
|
|
||||||
if (!cmp_func((*i)->name, *ci))
|
|
||||||
{
|
|
||||||
matched = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!matched)
|
|
||||||
{
|
|
||||||
error(0, NULL, "required option '%s' not specified", *ci);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DOTCONFDocument::error(int lineNum, const char* fileName_, const char* fmt, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
va_start(args, fmt);
|
|
||||||
|
|
||||||
size_t len = (lineNum != 0 ? strlen(fileName_) : 0) + strlen(fmt) + 50;
|
|
||||||
char* buf = (char*)mempool->Alloc(len);
|
|
||||||
|
|
||||||
if (lineNum)
|
|
||||||
snprintf(buf, len, "DOTCONF++: file '%s', line %d: %s\n", fileName_, lineNum, fmt);
|
|
||||||
else
|
|
||||||
snprintf(buf, len, "DOTCONF++: %s\n", fmt);
|
|
||||||
|
|
||||||
vfprintf(stderr, buf, args);
|
|
||||||
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
char* DOTCONFDocument::getSubstitution(char* macro, int lineNum)
|
|
||||||
{
|
|
||||||
char* buf = NULL;
|
|
||||||
char* variable = macro + 2;
|
|
||||||
|
|
||||||
char* endBr = strchr(macro, '}');
|
|
||||||
|
|
||||||
if (!endBr)
|
|
||||||
{
|
|
||||||
error(lineNum, fileName, "unterminated '{'");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
*endBr = 0;
|
|
||||||
|
|
||||||
char* defaultValue = strchr(variable, ':');
|
|
||||||
|
|
||||||
if (defaultValue)
|
|
||||||
{
|
|
||||||
*defaultValue++ = 0;
|
|
||||||
if (*defaultValue != '-')
|
|
||||||
{
|
|
||||||
error(lineNum, fileName, "incorrect macro substitution syntax");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
++defaultValue;
|
|
||||||
if (*defaultValue == '"' || *defaultValue == '\'')
|
|
||||||
{
|
|
||||||
++defaultValue;
|
|
||||||
defaultValue[strlen(defaultValue) - 1] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
defaultValue = NULL;
|
|
||||||
|
|
||||||
char* subs = getenv(variable);
|
|
||||||
if (subs)
|
|
||||||
buf = mempool->Strdup(subs);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NodeList::iterator i = nodeTree.begin();
|
|
||||||
DOTCONFDocumentNode* tagNode = NULL;
|
|
||||||
for (; i != nodeTree.end(); ++i)
|
|
||||||
{
|
|
||||||
tagNode = *i;
|
|
||||||
if (!cmp_func(tagNode->name, variable))
|
|
||||||
{
|
|
||||||
if (tagNode->valuesCount != 0)
|
|
||||||
{
|
|
||||||
buf = mempool->Strdup(tagNode->values[0]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == nodeTree.end())
|
|
||||||
{
|
|
||||||
if (defaultValue)
|
|
||||||
buf = mempool->Strdup(defaultValue);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
error(lineNum, fileName, "substitution not found and default value not given");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
int DOTCONFDocument::macroSubstitute(DOTCONFDocumentNode* tagNode, int valueIndex)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
char* macro = tagNode->values[valueIndex];
|
|
||||||
size_t valueLen = strlen(tagNode->values[valueIndex]) + 1;
|
|
||||||
char* value = (char*)mempool->Alloc(valueLen);
|
|
||||||
char* v = value;
|
|
||||||
char* subs = NULL;
|
|
||||||
|
|
||||||
while (*macro)
|
|
||||||
{
|
|
||||||
if (*macro == '$' && *(macro + 1) == '{')
|
|
||||||
{
|
|
||||||
char* m = strchr(macro, '}');
|
|
||||||
subs = getSubstitution(macro, tagNode->lineNum);
|
|
||||||
if(subs == NULL)
|
|
||||||
{
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
macro = m + 1;
|
|
||||||
*v = 0;
|
|
||||||
v = (char*)mempool->Alloc(strlen(value) + strlen(subs) + valueLen);
|
|
||||||
strcpy(v, value);
|
|
||||||
value = strcat(v, subs);
|
|
||||||
v = value + strlen(value);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
*v++ = *macro++;
|
|
||||||
}
|
|
||||||
|
|
||||||
*v = 0;
|
|
||||||
|
|
||||||
free(tagNode->values[valueIndex]);
|
|
||||||
tagNode->values[valueIndex] = strdup(value);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
const DOTCONFDocumentNode* DOTCONFDocument::getFirstNode() const
|
|
||||||
{
|
|
||||||
if (!nodeTree.empty())
|
|
||||||
return *nodeTree.begin();
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
const DOTCONFDocumentNode* DOTCONFDocument::findNode(const char* nodeName, const DOTCONFDocumentNode* parentNode, const DOTCONFDocumentNode* startNode) const
|
|
||||||
{
|
|
||||||
NodeList::const_iterator i = nodeTree.begin();
|
|
||||||
|
|
||||||
if (startNode == NULL)
|
|
||||||
startNode = parentNode;
|
|
||||||
|
|
||||||
if (startNode != NULL)
|
|
||||||
{
|
|
||||||
while (i != nodeTree.end() && (*i) != startNode)
|
|
||||||
++i;
|
|
||||||
|
|
||||||
if (i != nodeTree.end())
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; i != nodeTree.end(); ++i)
|
|
||||||
{
|
|
||||||
if ((*i)->parentNode != parentNode)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!cmp_func(nodeName, (*i)->name))
|
|
||||||
return *i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DOTCONFDocument::setRequiredOptionNames(const char** requiredOptionNames)
|
|
||||||
{
|
|
||||||
while (*requiredOptionNames)
|
|
||||||
{
|
|
||||||
requiredOptions.push_back(strdup(*requiredOptionNames));
|
|
||||||
++requiredOptionNames;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,111 +0,0 @@
|
||||||
#ifndef DOTCONFPP_H
|
|
||||||
#define DOTCONFPP_H
|
|
||||||
|
|
||||||
#include <list>
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#include "mempool.h"
|
|
||||||
|
|
||||||
class DOTCONFDocument;
|
|
||||||
|
|
||||||
class DOTCONFDocumentNode
|
|
||||||
{
|
|
||||||
friend class DOTCONFDocument;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
DOTCONFDocumentNode* previousNode;
|
|
||||||
DOTCONFDocumentNode* nextNode;
|
|
||||||
DOTCONFDocumentNode* parentNode;
|
|
||||||
DOTCONFDocumentNode* childNode;
|
|
||||||
char** values;
|
|
||||||
int valuesCount;
|
|
||||||
char* name;
|
|
||||||
const DOTCONFDocument* document;
|
|
||||||
int lineNum;
|
|
||||||
char* fileName;
|
|
||||||
bool closed;
|
|
||||||
|
|
||||||
void pushValue(char* _value);
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
DOTCONFDocumentNode();
|
|
||||||
~DOTCONFDocumentNode();
|
|
||||||
|
|
||||||
const char* getConfigurationFileName() const { return fileName; }
|
|
||||||
int getConfigurationLineNumber() const { return lineNum; }
|
|
||||||
|
|
||||||
const DOTCONFDocumentNode* getNextNode() const { return nextNode; }
|
|
||||||
const DOTCONFDocumentNode* getPreviuosNode() const { return previousNode; }
|
|
||||||
const DOTCONFDocumentNode* getParentNode() const { return parentNode; }
|
|
||||||
const DOTCONFDocumentNode* getChildNode() const { return childNode; }
|
|
||||||
const char* getValue(int index = 0) const;
|
|
||||||
const char* getName() const { return name; }
|
|
||||||
const DOTCONFDocument * getDocument() const { return document; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class DOTCONFDocument
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
enum CaseSensitive
|
|
||||||
{
|
|
||||||
CASESENSITIVE,
|
|
||||||
CASEINSENSETIVE
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
AsyncDNSMemPool* mempool;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
typedef std::list<char*> CharList;
|
|
||||||
typedef std::list<DOTCONFDocumentNode*> NodeList;
|
|
||||||
|
|
||||||
DOTCONFDocumentNode* curParent;
|
|
||||||
DOTCONFDocumentNode* curPrev;
|
|
||||||
int curLine;
|
|
||||||
bool quoted;
|
|
||||||
NodeList nodeTree;
|
|
||||||
CharList requiredOptions;
|
|
||||||
CharList processedFiles;
|
|
||||||
FILE* file;
|
|
||||||
char* fileName;
|
|
||||||
CharList words;
|
|
||||||
int (*cmp_func)(const char*, const char*);
|
|
||||||
|
|
||||||
int checkRequiredOptions();
|
|
||||||
int parseLine();
|
|
||||||
int parseFile(DOTCONFDocumentNode* _parent = NULL);
|
|
||||||
int checkConfig(const NodeList::iterator& from);
|
|
||||||
int cleanupLine(char* line);
|
|
||||||
char* getSubstitution(char* macro, int lineNum);
|
|
||||||
int macroSubstitute(DOTCONFDocumentNode* tagNode, int valueIndex);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
virtual void error(int lineNum, const char* fileName, const char* fmt, ...) ATTR_PRINTF(4,5);
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
DOTCONFDocument(CaseSensitive caseSensitivity = CASESENSITIVE);
|
|
||||||
virtual ~DOTCONFDocument();
|
|
||||||
|
|
||||||
int setContent(const char* _fileName);
|
|
||||||
|
|
||||||
void setRequiredOptionNames(const char** requiredOptionNames);
|
|
||||||
const DOTCONFDocumentNode * getFirstNode() const;
|
|
||||||
const DOTCONFDocumentNode * findNode(const char* nodeName, const DOTCONFDocumentNode* parentNode = NULL, const DOTCONFDocumentNode* startNode = NULL) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,106 +0,0 @@
|
||||||
#include "mempool.h"
|
|
||||||
|
|
||||||
AsyncDNSMemPool::PoolChunk::PoolChunk(size_t _size)
|
|
||||||
: pool(NULL), pos(0), size(_size)
|
|
||||||
{
|
|
||||||
pool = malloc(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
AsyncDNSMemPool::PoolChunk::~PoolChunk()
|
|
||||||
{
|
|
||||||
::free(pool);
|
|
||||||
}
|
|
||||||
|
|
||||||
AsyncDNSMemPool::AsyncDNSMemPool(size_t _defaultSize)
|
|
||||||
: chunks(NULL), chunksCount(0), defaultSize(_defaultSize),
|
|
||||||
poolUsage(0), poolUsageCounter(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
AsyncDNSMemPool::~AsyncDNSMemPool()
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < chunksCount; ++i)
|
|
||||||
delete chunks[i];
|
|
||||||
|
|
||||||
::free(chunks);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AsyncDNSMemPool::initialize()
|
|
||||||
{
|
|
||||||
chunksCount = 1;
|
|
||||||
chunks = (PoolChunk**)malloc(sizeof(PoolChunk*));
|
|
||||||
if (chunks == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
chunks[chunksCount - 1] = new PoolChunk(defaultSize);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AsyncDNSMemPool::addNewChunk(size_t size)
|
|
||||||
{
|
|
||||||
++chunksCount;
|
|
||||||
|
|
||||||
chunks = (PoolChunk**)realloc(chunks, chunksCount * sizeof(PoolChunk*));
|
|
||||||
if (size <= defaultSize)
|
|
||||||
chunks[chunksCount - 1] = new PoolChunk(defaultSize);
|
|
||||||
else
|
|
||||||
chunks[chunksCount - 1] = new PoolChunk(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void* AsyncDNSMemPool::Alloc(size_t size)
|
|
||||||
{
|
|
||||||
PoolChunk* chunk = NULL;
|
|
||||||
for (size_t i = 0; i < chunksCount; ++i)
|
|
||||||
{
|
|
||||||
chunk = chunks[i];
|
|
||||||
if ((chunk->size - chunk->pos) >= size)
|
|
||||||
{
|
|
||||||
chunk->pos += size;
|
|
||||||
return ((char*)chunk->pool) + chunk->pos - size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addNewChunk(size);
|
|
||||||
chunks[chunksCount - 1]->pos = size;
|
|
||||||
return chunks[chunksCount - 1]->pool;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AsyncDNSMemPool::Free()
|
|
||||||
{
|
|
||||||
size_t pu = 0;
|
|
||||||
size_t psz = 0;
|
|
||||||
++poolUsageCounter;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < chunksCount; ++i)
|
|
||||||
{
|
|
||||||
pu += chunks[i]->pos;
|
|
||||||
psz += chunks[i]->size;
|
|
||||||
chunks[i]->pos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
poolUsage = poolUsage > pu ? poolUsage : pu;
|
|
||||||
|
|
||||||
if (poolUsageCounter >= 10 && chunksCount > 1)
|
|
||||||
{
|
|
||||||
psz -= chunks[chunksCount - 1]->size;
|
|
||||||
if (poolUsage < psz)
|
|
||||||
{
|
|
||||||
--chunksCount;
|
|
||||||
delete chunks[chunksCount];
|
|
||||||
}
|
|
||||||
|
|
||||||
poolUsage = 0;
|
|
||||||
poolUsageCounter = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void* AsyncDNSMemPool::Calloc(size_t size)
|
|
||||||
{
|
|
||||||
return ::memset(Alloc(size), 0, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
char* AsyncDNSMemPool::Strdup(const char *str)
|
|
||||||
{
|
|
||||||
return ::strcpy((char*)Alloc(strlen(str) + 1), str);
|
|
||||||
}
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
#ifndef ASYNC_DNS_MEMPOOL_H
|
|
||||||
#define ASYNC_DNS_MEMPOOL_H
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
class AsyncDNSMemPool
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
struct PoolChunk
|
|
||||||
{
|
|
||||||
void* pool;
|
|
||||||
size_t pos;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
PoolChunk(size_t _size);
|
|
||||||
~PoolChunk();
|
|
||||||
};
|
|
||||||
|
|
||||||
PoolChunk** chunks;
|
|
||||||
size_t chunksCount;
|
|
||||||
size_t defaultSize;
|
|
||||||
|
|
||||||
size_t poolUsage;
|
|
||||||
size_t poolUsageCounter;
|
|
||||||
|
|
||||||
void addNewChunk(size_t size);
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
AsyncDNSMemPool(size_t _defaultSize = 4096);
|
|
||||||
virtual ~AsyncDNSMemPool();
|
|
||||||
|
|
||||||
bool initialize();
|
|
||||||
void Free();
|
|
||||||
void* Alloc(size_t size);
|
|
||||||
void* Calloc(size_t size);
|
|
||||||
char* Strdup(const char *str);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "DatabaseEnv.h"
|
#include "DatabaseEnv.h"
|
||||||
#include "Config/ConfigEnv.h"
|
#include "Config/Config.h"
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,6 @@ if (!(CONDITION)) \
|
||||||
#define WPWarning(CONDITION) \
|
#define WPWarning(CONDITION) \
|
||||||
if (!(CONDITION)) \
|
if (!(CONDITION)) \
|
||||||
{ \
|
{ \
|
||||||
ACE_Stack_Trace st; \
|
|
||||||
printf("%s:%i: Warning: Assertion in %s failed: %s",\
|
printf("%s:%i: Warning: Assertion in %s failed: %s",\
|
||||||
__FILE__, __LINE__, __FUNCTION__, STRINGIZE(CONDITION)); \
|
__FILE__, __LINE__, __FUNCTION__, STRINGIZE(CONDITION)); \
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Policies/SingletonImp.h"
|
#include "Policies/SingletonImp.h"
|
||||||
#include "Config/ConfigEnv.h"
|
#include "Config/Config.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "ByteBuffer.h"
|
#include "ByteBuffer.h"
|
||||||
#include "ProgressBar.h"
|
#include "ProgressBar.h"
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ bool WinServiceInstall()
|
||||||
if (GetModuleFileName( 0, path, sizeof(path)/sizeof(path[0]) ) > 0)
|
if (GetModuleFileName( 0, path, sizeof(path)/sizeof(path[0]) ) > 0)
|
||||||
{
|
{
|
||||||
SC_HANDLE service;
|
SC_HANDLE service;
|
||||||
std::strcat(path, " --service");
|
std::strcat(path, " -s run");
|
||||||
service = CreateService(serviceControlManager,
|
service = CreateService(serviceControlManager,
|
||||||
serviceName, // name of service
|
serviceName, // name of service
|
||||||
serviceLongName, // service name to display
|
serviceLongName, // service name to display
|
||||||
|
|
|
||||||
|
|
@ -36,10 +36,10 @@
|
||||||
// Format is YYYYMMDDRR where RR is the change in the conf file
|
// Format is YYYYMMDDRR where RR is the change in the conf file
|
||||||
// for that day.
|
// for that day.
|
||||||
#ifndef _MANGOSDCONFVERSION
|
#ifndef _MANGOSDCONFVERSION
|
||||||
# define _MANGOSDCONFVERSION 2010051901
|
# define _MANGOSDCONFVERSION 2010062001
|
||||||
#endif
|
#endif
|
||||||
#ifndef _REALMDCONFVERSION
|
#ifndef _REALMDCONFVERSION
|
||||||
# define _REALMDCONFVERSION 2007062001
|
# define _REALMDCONFVERSION 2010062001
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MANGOS_ENDIAN == MANGOS_BIGENDIAN
|
#if MANGOS_ENDIAN == MANGOS_BIGENDIAN
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "10051"
|
#define REVISION_NR "10091"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#ifndef __REVISION_SQL_H__
|
#ifndef __REVISION_SQL_H__
|
||||||
#define __REVISION_SQL_H__
|
#define __REVISION_SQL_H__
|
||||||
#define REVISION_DB_CHARACTERS "required_10051_01_characters_character_aura"
|
#define REVISION_DB_CHARACTERS "required_10051_01_characters_character_aura"
|
||||||
#define REVISION_DB_MANGOS "required_10045_01_mangos_spell_proc_event"
|
#define REVISION_DB_MANGOS "required_10089_01_mangos_game_event_pool"
|
||||||
#define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version"
|
#define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version"
|
||||||
#endif // __REVISION_SQL_H__
|
#endif // __REVISION_SQL_H__
|
||||||
|
|
|
||||||
|
|
@ -370,6 +370,7 @@
|
||||||
<ClCompile Include="..\..\src\game\BattleGroundWS.cpp" />
|
<ClCompile Include="..\..\src\game\BattleGroundWS.cpp" />
|
||||||
<ClCompile Include="..\..\src\game\Calendar.cpp" />
|
<ClCompile Include="..\..\src\game\Calendar.cpp" />
|
||||||
<ClCompile Include="..\..\src\game\CalendarHandler.cpp" />
|
<ClCompile Include="..\..\src\game\CalendarHandler.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\game\Camera.cpp" />
|
||||||
<ClCompile Include="..\..\src\game\Channel.cpp" />
|
<ClCompile Include="..\..\src\game\Channel.cpp" />
|
||||||
<ClCompile Include="..\..\src\game\ChannelHandler.cpp" />
|
<ClCompile Include="..\..\src\game\ChannelHandler.cpp" />
|
||||||
<ClCompile Include="..\..\src\game\ChannelMgr.cpp" />
|
<ClCompile Include="..\..\src\game\ChannelMgr.cpp" />
|
||||||
|
|
@ -517,6 +518,7 @@
|
||||||
<ClInclude Include="..\..\src\game\BattleGroundSA.h" />
|
<ClInclude Include="..\..\src\game\BattleGroundSA.h" />
|
||||||
<ClInclude Include="..\..\src\game\BattleGroundWS.h" />
|
<ClInclude Include="..\..\src\game\BattleGroundWS.h" />
|
||||||
<ClInclude Include="..\..\src\game\Calendar.h" />
|
<ClInclude Include="..\..\src\game\Calendar.h" />
|
||||||
|
<ClInclude Include="..\..\src\game\Camera.h" />
|
||||||
<ClInclude Include="..\..\src\game\Cell.h" />
|
<ClInclude Include="..\..\src\game\Cell.h" />
|
||||||
<ClInclude Include="..\..\src\game\CellImpl.h" />
|
<ClInclude Include="..\..\src\game\CellImpl.h" />
|
||||||
<ClInclude Include="..\..\src\game\Channel.h" />
|
<ClInclude Include="..\..\src\game\Channel.h" />
|
||||||
|
|
|
||||||
|
|
@ -442,6 +442,9 @@
|
||||||
<ClCompile Include="..\..\src\game\CharacterDatabaseCleaner.cpp">
|
<ClCompile Include="..\..\src\game\CharacterDatabaseCleaner.cpp">
|
||||||
<Filter>Tool</Filter>
|
<Filter>Tool</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\game\Camera.cpp">
|
||||||
|
<Filter>Object</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\src\game\AccountMgr.h">
|
<ClInclude Include="..\..\src\game\AccountMgr.h">
|
||||||
|
|
@ -832,5 +835,8 @@
|
||||||
<ClInclude Include="..\..\src\game\CharacterDatabaseCleaner.h">
|
<ClInclude Include="..\..\src\game\CharacterDatabaseCleaner.h">
|
||||||
<Filter>Tool</Filter>
|
<Filter>Tool</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\src\game\Camera.h">
|
||||||
|
<Filter>Object</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -437,8 +437,6 @@
|
||||||
<ClCompile Include="..\..\src\shared\Auth\Sha1.cpp" />
|
<ClCompile Include="..\..\src\shared\Auth\Sha1.cpp" />
|
||||||
<ClCompile Include="..\..\src\shared\Common.cpp" />
|
<ClCompile Include="..\..\src\shared\Common.cpp" />
|
||||||
<ClCompile Include="..\..\src\shared\Config\Config.cpp" />
|
<ClCompile Include="..\..\src\shared\Config\Config.cpp" />
|
||||||
<ClCompile Include="..\..\src\shared\Config\dotconfpp\dotconfpp.cpp" />
|
|
||||||
<ClCompile Include="..\..\src\shared\Config\dotconfpp\mempool.cpp" />
|
|
||||||
<ClCompile Include="..\..\src\shared\Database\Database.cpp" />
|
<ClCompile Include="..\..\src\shared\Database\Database.cpp" />
|
||||||
<ClCompile Include="..\..\src\shared\Database\DatabaseMysql.cpp" />
|
<ClCompile Include="..\..\src\shared\Database\DatabaseMysql.cpp" />
|
||||||
<ClCompile Include="..\..\src\shared\Database\DBCFileLoader.cpp" />
|
<ClCompile Include="..\..\src\shared\Database\DBCFileLoader.cpp" />
|
||||||
|
|
@ -475,9 +473,6 @@
|
||||||
<ClInclude Include="..\..\src\shared\WorldPacket.h" />
|
<ClInclude Include="..\..\src\shared\WorldPacket.h" />
|
||||||
<ClInclude Include="..\..\src\shared\Common.h" />
|
<ClInclude Include="..\..\src\shared\Common.h" />
|
||||||
<ClInclude Include="..\..\src\shared\Config\Config.h" />
|
<ClInclude Include="..\..\src\shared\Config\Config.h" />
|
||||||
<ClInclude Include="..\..\src\shared\Config\ConfigEnv.h" />
|
|
||||||
<ClInclude Include="..\..\src\shared\Config\dotconfpp\dotconfpp.h" />
|
|
||||||
<ClInclude Include="..\..\src\shared\Config\dotconfpp\mempool.h" />
|
|
||||||
<ClInclude Include="..\..\src\shared\Database\Database.h" />
|
<ClInclude Include="..\..\src\shared\Database\Database.h" />
|
||||||
<ClInclude Include="..\..\src\shared\Database\DatabaseEnv.h" />
|
<ClInclude Include="..\..\src\shared\Database\DatabaseEnv.h" />
|
||||||
<ClInclude Include="..\..\src\shared\Database\DatabaseImpl.h" />
|
<ClInclude Include="..\..\src\shared\Database\DatabaseImpl.h" />
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,6 @@
|
||||||
<Filter Include="Config">
|
<Filter Include="Config">
|
||||||
<UniqueIdentifier>{adb98dec-d22a-40b3-84be-51eaf2974a15}</UniqueIdentifier>
|
<UniqueIdentifier>{adb98dec-d22a-40b3-84be-51eaf2974a15}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter Include="Config\dotconfpp">
|
|
||||||
<UniqueIdentifier>{dff0e90b-cab5-4d0b-bd5d-3cacbb638630}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Auth">
|
<Filter Include="Auth">
|
||||||
<UniqueIdentifier>{e35fd108-bd39-46ae-83f9-09cf1ebf4ea8}</UniqueIdentifier>
|
<UniqueIdentifier>{e35fd108-bd39-46ae-83f9-09cf1ebf4ea8}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
|
@ -66,12 +63,6 @@
|
||||||
<ClCompile Include="..\..\src\shared\Config\Config.cpp">
|
<ClCompile Include="..\..\src\shared\Config\Config.cpp">
|
||||||
<Filter>Config</Filter>
|
<Filter>Config</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\shared\Config\dotconfpp\dotconfpp.cpp">
|
|
||||||
<Filter>Config\dotconfpp</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\src\shared\Config\dotconfpp\mempool.cpp">
|
|
||||||
<Filter>Config\dotconfpp</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\src\shared\Auth\AuthCrypt.cpp">
|
<ClCompile Include="..\..\src\shared\Auth\AuthCrypt.cpp">
|
||||||
<Filter>Auth</Filter>
|
<Filter>Auth</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|
@ -194,15 +185,6 @@
|
||||||
<ClInclude Include="..\..\src\shared\Config\Config.h">
|
<ClInclude Include="..\..\src\shared\Config\Config.h">
|
||||||
<Filter>Config</Filter>
|
<Filter>Config</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\src\shared\Config\ConfigEnv.h">
|
|
||||||
<Filter>Config</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\src\shared\Config\dotconfpp\dotconfpp.h">
|
|
||||||
<Filter>Config\dotconfpp</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\src\shared\Config\dotconfpp\mempool.h">
|
|
||||||
<Filter>Config\dotconfpp</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\src\shared\Auth\AuthCrypt.h">
|
<ClInclude Include="..\..\src\shared\Auth\AuthCrypt.h">
|
||||||
<Filter>Auth</Filter>
|
<Filter>Auth</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
||||||
|
|
@ -669,6 +669,14 @@
|
||||||
RelativePath="..\..\src\game\CalendarHandler.cpp"
|
RelativePath="..\..\src\game\CalendarHandler.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\src\game\Camera.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\src\game\Camera.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\src\game\Cell.h"
|
RelativePath="..\..\src\game\Cell.h"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -672,30 +672,6 @@
|
||||||
RelativePath="..\..\src\shared\Config\Config.h"
|
RelativePath="..\..\src\shared\Config\Config.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\..\src\shared\Config\ConfigEnv.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<Filter
|
|
||||||
Name="dotconfpp"
|
|
||||||
>
|
|
||||||
<File
|
|
||||||
RelativePath="..\..\src\shared\Config\dotconfpp\dotconfpp.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\..\src\shared\Config\dotconfpp\dotconfpp.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\..\src\shared\Config\dotconfpp\mempool.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\..\src\shared\Config\dotconfpp\mempool.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Auth"
|
Name="Auth"
|
||||||
|
|
|
||||||
|
|
@ -1162,6 +1162,14 @@
|
||||||
RelativePath="..\..\src\game\Calendar.h"
|
RelativePath="..\..\src\game\Calendar.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\src\game\Camera.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\src\game\Camera.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\src\game\Corpse.cpp"
|
RelativePath="..\..\src\game\Corpse.cpp"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue