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.
|
||||
* OpenSSL lib upgrade to OpenSSL 1.0.0.
|
||||
* Sockets lib use dropped.
|
||||
* dotconfpp lib use dropped.
|
||||
* Upgrade to client version 3.3.3a (build 11723).
|
||||
|
||||
Version 0.15
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ CREATE TABLE `db_version` (
|
|||
`version` varchar(120) default NULL,
|
||||
`creature_ai_version` varchar(120) default NULL,
|
||||
`cache_id` int(10) default '0',
|
||||
`required_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';
|
||||
|
||||
--
|
||||
|
|
@ -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 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.'),
|
||||
('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 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).'),
|
||||
|
|
@ -1571,7 +1572,7 @@ UNLOCK TABLES;
|
|||
DROP TABLE IF EXISTS `game_event_creature`;
|
||||
CREATE TABLE `game_event_creature` (
|
||||
`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`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
|
|
@ -1612,7 +1613,7 @@ UNLOCK TABLES;
|
|||
DROP TABLE IF EXISTS `game_event_gameobject`;
|
||||
CREATE TABLE `game_event_gameobject` (
|
||||
`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`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
|
|
@ -13704,26 +13705,6 @@ LOCK TABLES `pool_template` WRITE;
|
|||
/*!40000 ALTER TABLE `pool_template` ENABLE KEYS */;
|
||||
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`
|
||||
--
|
||||
|
|
@ -17930,6 +17911,7 @@ INSERT INTO `spell_proc_event` VALUES
|
|||
(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),
|
||||
(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),
|
||||
(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),
|
||||
|
|
@ -18290,7 +18272,7 @@ INSERT INTO `spell_proc_event` VALUES
|
|||
(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),
|
||||
(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),
|
||||
(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),
|
||||
|
|
|
|||
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 \
|
||||
10045_01_mangos_spell_proc_event.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
|
||||
|
||||
## Additional files to include when running 'make dist'
|
||||
|
|
@ -156,4 +159,7 @@ EXTRA_DIST = \
|
|||
10044_02_mangos_spell_proc_event.sql \
|
||||
10045_01_mangos_spell_proc_event.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
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ class MANGOS_DLL_DECL NGrid
|
|||
}
|
||||
|
||||
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; }
|
||||
void SetGridState(grid_state_t s) { i_cellstate = s; }
|
||||
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::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));
|
||||
}
|
||||
|
|
|
|||
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))
|
||||
{
|
||||
// normal delayed teleport protection not applied (and this correct) for this case (Player object just created)
|
||||
AreaTrigger const* at = sObjectMgr.GetGoBackTrigger(pCurrChar->GetMapId());
|
||||
if(at)
|
||||
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 },
|
||||
{ "xy", SEC_MODERATOR, false, &ChatHandler::HandleGoXYCommand, "", 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 }
|
||||
};
|
||||
|
||||
|
|
@ -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
|
||||
char* cId = extractKeyFromLink(text,"Htele");
|
||||
if(!cId)
|
||||
return false;
|
||||
return NULL;
|
||||
|
||||
// id case (explicit or from shift link)
|
||||
if(cId[0] >= '0' || cId[0] >= '9')
|
||||
|
|
@ -2079,7 +2079,7 @@ static char const* const guidKeys[] =
|
|||
"Hplayer",
|
||||
"Hcreature",
|
||||
"Hgameobject",
|
||||
0
|
||||
NULL
|
||||
};
|
||||
|
||||
uint64 ChatHandler::extractGuidFromLink(char* text)
|
||||
|
|
@ -2133,6 +2133,130 @@ uint64 ChatHandler::extractGuidFromLink(char* text)
|
|||
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)
|
||||
{
|
||||
// |color|Hplayer:name|h[name]|h|r
|
||||
|
|
@ -2229,7 +2353,7 @@ char* ChatHandler::extractQuotedArg( char* args )
|
|||
{
|
||||
char* space = strtok(args, "\"");
|
||||
if(!space)
|
||||
return false;
|
||||
return NULL;
|
||||
return strtok(NULL, "\"");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -535,6 +535,7 @@ class ChatHandler
|
|||
uint32 extractSpellIdFromLink(char* text);
|
||||
uint64 extractGuidFromLink(char* text);
|
||||
GameTele const* extractGameTeleFromLink(char* text);
|
||||
bool extractLocationFromLink(char* text, uint32& mapid, float& x, float& y, float& z);
|
||||
std::string extractPlayerNameFromLink(char* text);
|
||||
// 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);
|
||||
|
|
@ -558,6 +559,8 @@ class ChatHandler
|
|||
void HandleCharacterLevel(Player* player, uint64 player_guid, uint32 oldlevel, uint32 newlevel);
|
||||
void HandleLearnSkillRecipesHelper(Player* player,uint32 skill_id);
|
||||
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
|
||||
|
|
|
|||
|
|
@ -574,7 +574,7 @@ void WorldSession::HandleTextEmoteOpcode( WorldPacket & recv_data )
|
|||
|
||||
MaNGOS::EmoteChatBuilder emote_builder(*GetPlayer(), text_emote, emoteNum, unit);
|
||||
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));
|
||||
|
||||
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; }
|
||||
|
||||
bool isActiveObject() const { return false; }
|
||||
|
||||
bool IsExpired(time_t t) const;
|
||||
private:
|
||||
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_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false), m_needNotify(false),
|
||||
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_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);
|
||||
|
||||
// Load creature equipment
|
||||
if(!data || data->equipmentId == 0)
|
||||
{ // use default from the template
|
||||
LoadEquipment(cinfo->equipmentId);
|
||||
if (!data || data->equipmentId == 0)
|
||||
{
|
||||
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
|
||||
LoadEquipment(data->equipmentId);
|
||||
}
|
||||
|
|
@ -788,29 +791,6 @@ bool Creature::isCanTrainingAndResetTalentsOf(Player* pPlayer) const
|
|||
&& 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()
|
||||
{
|
||||
loot.clear();
|
||||
|
|
@ -2218,4 +2198,4 @@ void Creature::RelocationNotify()
|
|||
MaNGOS::CreatureRelocationNotifier relocationNotifier(*this);
|
||||
float radius = MAX_CREATURE_ATTACK_RADIUS * sWorld.getConfig(CONFIG_FLOAT_RATE_CREATURE_AGGRO);
|
||||
Cell::VisitAllObjects(this, relocationNotifier, radius);
|
||||
}
|
||||
}
|
||||
|
|
@ -444,7 +444,6 @@ class MANGOS_DLL_SPEC Creature : public Unit
|
|||
|
||||
bool AIM_Initialize();
|
||||
|
||||
void AI_SendMoveToPacket(float x, float y, float z, uint32 time, SplineFlags MovementFlags, SplineType type);
|
||||
CreatureAI* AI() { return i_AI; }
|
||||
|
||||
void AddSplineFlag(SplineFlags f)
|
||||
|
|
@ -627,7 +626,6 @@ class MANGOS_DLL_SPEC Creature : public Unit
|
|||
|
||||
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 SetNeedNotify() { m_needNotify = true; }
|
||||
|
|
@ -692,7 +690,6 @@ class MANGOS_DLL_SPEC Creature : public Unit
|
|||
private:
|
||||
GridReference<Creature> m_gridRef;
|
||||
CreatureInfo const* m_creatureInfo; // in difficulty mode > 0 can different from ObjMgr::GetCreatureTemplate(GetEntry())
|
||||
bool m_isActiveObject;
|
||||
SplineFlags m_splineFlags;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ CanCastResult CreatureAI::CanCastSpell(Unit* pTarget, const SpellEntry *pSpell,
|
|||
if (!isTriggered)
|
||||
{
|
||||
// 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;
|
||||
|
||||
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());
|
||||
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 )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1319,7 +1319,7 @@ bool CreatureEventAI::CanCast(Unit* Target, SpellEntry const *Spell, bool Trigge
|
|||
return false;
|
||||
|
||||
//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)))
|
||||
return false;
|
||||
|
||||
|
|
|
|||
|
|
@ -86,7 +86,12 @@ DestinationHolder<TRAVELLER>::StartTravel(TRAVELLER &traveller, bool sendMove)
|
|||
i_totalTravelTime = traveller.GetTotalTrevelTimeTo(i_destX,i_destY,i_destZ);
|
||||
i_timeElapsed = 0;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
#include "GridNotifiersImpl.h"
|
||||
#include "SpellMgr.h"
|
||||
|
||||
DynamicObject::DynamicObject() : WorldObject(), m_isActiveObject(false)
|
||||
DynamicObject::DynamicObject() : WorldObject()
|
||||
{
|
||||
m_objectType |= TYPEMASK_DYNAMICOBJECT;
|
||||
m_objectTypeId = TYPEID_DYNAMICOBJECT;
|
||||
|
|
@ -50,7 +50,10 @@ void DynamicObject::RemoveFromWorld()
|
|||
{
|
||||
///- Remove the dynamicObject from the accessor
|
||||
if(IsInWorld())
|
||||
{
|
||||
GetMap()->GetObjectsStore().erase<DynamicObject>(GetGUID(), (DynamicObject*)NULL);
|
||||
GetViewPoint().Event_RemovedFromWorld();
|
||||
}
|
||||
|
||||
Object::RemoveFromWorld();
|
||||
}
|
||||
|
|
@ -80,10 +83,6 @@ bool DynamicObject::Create( uint32 guidlow, Unit *caster, uint32 spellId, SpellE
|
|||
m_effIndex = effIndex;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ class DynamicObject : public WorldObject
|
|||
|
||||
GridReference<DynamicObject> &GetGridRef() { return m_gridRef; }
|
||||
|
||||
bool isActiveObject() const { return m_isActiveObject; }
|
||||
protected:
|
||||
uint32 m_spellId;
|
||||
SpellEffectIndex m_effIndex;
|
||||
|
|
@ -70,6 +69,5 @@ class DynamicObject : public WorldObject
|
|||
AffectedSet m_affected;
|
||||
private:
|
||||
GridReference<DynamicObject> m_gridRef;
|
||||
bool m_isActiveObject;
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -171,6 +171,13 @@ void GameEventMgr::LoadFromDB()
|
|||
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);
|
||||
// 1 2
|
||||
result = WorldDatabase.Query("SELECT creature.guid, game_event_creature.event "
|
||||
|
|
@ -198,6 +205,12 @@ void GameEventMgr::LoadFromDB()
|
|||
uint32 guid = fields[0].GetUInt32();
|
||||
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;
|
||||
|
||||
if(internal_event_id < 0 || (size_t)internal_event_id >= mGameEventCreatureGuids.size())
|
||||
|
|
@ -207,6 +220,32 @@ void GameEventMgr::LoadFromDB()
|
|||
}
|
||||
|
||||
++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];
|
||||
crelist.push_back(guid);
|
||||
|
||||
|
|
@ -244,6 +283,12 @@ void GameEventMgr::LoadFromDB()
|
|||
uint32 guid = fields[0].GetUInt32();
|
||||
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;
|
||||
|
||||
if(internal_event_id < 0 || (size_t)internal_event_id >= mGameEventGameobjectGuids.size())
|
||||
|
|
@ -253,6 +298,32 @@ void GameEventMgr::LoadFromDB()
|
|||
}
|
||||
|
||||
++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];
|
||||
golist.push_back(guid);
|
||||
|
||||
|
|
@ -263,6 +334,15 @@ void GameEventMgr::LoadFromDB()
|
|||
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());
|
||||
// 0 1 2
|
||||
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( ">> 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
|
||||
|
|
@ -516,6 +545,18 @@ void GameEventMgr::GameEventSpawn(int16 event_id)
|
|||
CreatureData const* data = sObjectMgr.GetCreatureData(*itr);
|
||||
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);
|
||||
|
||||
// Spawn if necessary (loaded grids only)
|
||||
|
|
@ -549,7 +590,20 @@ void GameEventMgr::GameEventSpawn(int16 event_id)
|
|||
GameObjectData const* data = sObjectMgr.GetGOData(*itr);
|
||||
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);
|
||||
|
||||
// Spawn if necessary (loaded grids only)
|
||||
// this base map checked as non-instanced and then only existed
|
||||
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());
|
||||
return;
|
||||
}
|
||||
if((size_t)event_id >= mGameEventSpawnPoolIds.size())
|
||||
{
|
||||
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)
|
||||
sPoolMgr.SpawnPool(*itr, true);
|
||||
for (IdList::iterator itr = mGameEventSpawnPoolIds[event_id].begin();itr != mGameEventSpawnPoolIds[event_id].end();++itr)
|
||||
sPoolMgr.SpawnPool(*itr, true);
|
||||
}
|
||||
}
|
||||
|
||||
void GameEventMgr::GameEventUnspawn(int16 event_id)
|
||||
|
|
@ -596,6 +653,17 @@ void GameEventMgr::GameEventUnspawn(int16 event_id)
|
|||
// Remove the creature from grid
|
||||
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);
|
||||
|
||||
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
|
||||
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);
|
||||
|
||||
if( GameObject* pGameobject = ObjectAccessor::GetGameObjectInWorld(ObjectGuid(HIGHGUID_GAMEOBJECT, data->id, *itr)) )
|
||||
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::list<QuestRelation> QuestRelList;
|
||||
typedef std::vector<QuestRelList> GameEventQuestMap;
|
||||
GameEventQuestMap mGameEventQuests;
|
||||
GameEventModelEquipMap mGameEventModelEquip;
|
||||
GameEventGuidMap mGameEventCreatureGuids;
|
||||
GameEventGuidMap mGameEventGameobjectGuids;
|
||||
GameEventIdMap mGameEventPoolIds;
|
||||
GameEventQuestMap mGameEventQuests; // events*2-1
|
||||
GameEventModelEquipMap mGameEventModelEquip; // events*2-1
|
||||
GameEventGuidMap mGameEventCreatureGuids; // events*2-1
|
||||
GameEventGuidMap mGameEventGameobjectGuids; // events*2-1
|
||||
GameEventIdMap mGameEventSpawnPoolIds; // events size, only positive event case
|
||||
GameEventDataMap mGameEvent;
|
||||
ActiveEvents m_ActiveEvents;
|
||||
bool m_IsGameEventsInit;
|
||||
|
|
|
|||
|
|
@ -703,7 +703,6 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
|
|||
|
||||
GridReference<GameObject> &GetGridRef() { return m_gridRef; }
|
||||
|
||||
bool isActiveObject() const { return false; }
|
||||
uint64 GetRotation() const { return m_rotation; }
|
||||
protected:
|
||||
uint32 m_spellId;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ class DynamicObject;
|
|||
class GameObject;
|
||||
class Pet;
|
||||
class Player;
|
||||
class Camera;
|
||||
|
||||
#define MAX_NUMBER_OF_GRIDS 64
|
||||
|
||||
|
|
@ -56,10 +57,12 @@ class Player;
|
|||
#define MAP_HALFSIZE (MAP_SIZE/2)
|
||||
|
||||
// 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_5(Creature, Pet, Vehicle, GameObject, DynamicObject) AllMapStoredObjectTypes;
|
||||
|
||||
typedef GridRefManager<Camera> CameraMapType;
|
||||
typedef GridRefManager<Corpse> CorpseMapType;
|
||||
typedef GridRefManager<Creature> CreatureMapType;
|
||||
typedef GridRefManager<DynamicObject> DynamicObjectMapType;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
#include "GridStates.h"
|
||||
#include "CellImpl.h"
|
||||
#include "Map.h"
|
||||
#include "Config/ConfigEnv.h"
|
||||
#include "DBCEnums.h"
|
||||
#include "DBCStores.h"
|
||||
#include "GridMap.h"
|
||||
|
|
|
|||
|
|
@ -28,32 +28,29 @@
|
|||
using namespace MaNGOS;
|
||||
|
||||
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();
|
||||
if(player == &i_object)
|
||||
continue;
|
||||
|
||||
player->UpdateVisibilityOf(player->GetViewPoint(),&i_object);
|
||||
iter->getSource()->UpdateVisibilityOf(&i_object);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VisibleNotifier::Notify()
|
||||
{
|
||||
Player& player = *i_camera.GetOwner();
|
||||
// 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
|
||||
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)
|
||||
{
|
||||
if(i_clientGUIDs.find((*itr)->GetGUID())!=i_clientGUIDs.end())
|
||||
if (i_clientGUIDs.find((*itr)->GetGUID()) != i_clientGUIDs.end())
|
||||
{
|
||||
// ignore far sight case
|
||||
(*itr)->UpdateVisibilityOf((*itr),&i_player);
|
||||
i_player.UpdateVisibilityOf(&i_player,(*itr),i_data,i_visibleNow);
|
||||
(*itr)->UpdateVisibilityOf(*itr, &player);
|
||||
player.UpdateVisibilityOf(&player, *itr, i_data, i_visibleNow);
|
||||
i_clientGUIDs.erase((*itr)->GetGUID());
|
||||
}
|
||||
}
|
||||
|
|
@ -63,27 +60,28 @@ VisibleNotifier::Notify()
|
|||
i_data.AddOutOfRangeGUID(i_clientGUIDs);
|
||||
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)
|
||||
WorldPacket packet;
|
||||
i_data.BuildPacket(&packet);
|
||||
i_player.GetSession()->SendPacket(&packet);
|
||||
player.GetSession()->SendPacket(&packet);
|
||||
|
||||
// send out of range to other players if need
|
||||
ObjectGuidSet const& oor = i_data.GetOutOfRangeGUIDs();
|
||||
for(ObjectGuidSet::const_iterator iter = oor.begin(); iter != oor.end(); ++iter)
|
||||
{
|
||||
if(!iter->IsPlayer())
|
||||
if (!iter->IsPlayer())
|
||||
continue;
|
||||
|
||||
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)
|
||||
{
|
||||
// target aura duration for caster show only if target exist at caster client
|
||||
if((*vItr)!=&i_player && (*vItr)->isType(TYPEMASK_UNIT))
|
||||
i_player.SendAurasForTarget((Unit*)(*vItr));
|
||||
if ((*vItr) != &player && (*vItr)->isType(TYPEMASK_UNIT))
|
||||
player.SendAurasForTarget((Unit*)(*vItr));
|
||||
|
||||
// non finished movements show to player
|
||||
if((*vItr)->GetTypeId()==TYPEID_UNIT && ((Creature*)(*vItr))->isAlive())
|
||||
((Creature*)(*vItr))->SendMonsterMoveWithSpeedToCurrentDestination(&i_player);
|
||||
if ((*vItr)->GetTypeId()==TYPEID_UNIT && ((Creature*)(*vItr))->isAlive())
|
||||
((Creature*)(*vItr))->SendMonsterMoveWithSpeedToCurrentDestination(&player);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if(WorldSession* session = iter->getSource()->GetSession())
|
||||
if (WorldSession* session = owner->GetSession())
|
||||
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();
|
||||
if(!player->InSamePhase(i_phaseMask) || player == i_skipped_receiver)
|
||||
Player* owner = iter->getSource()->GetOwner();
|
||||
|
||||
if (!owner->InSamePhase(i_phaseMask) || owner == i_skipped_receiver)
|
||||
continue;
|
||||
|
||||
if (WorldSession* session = player->GetSession())
|
||||
if (WorldSession* session = owner->GetSession())
|
||||
session->SendPacket(i_message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
if(WorldSession* session = iter->getSource()->GetSession())
|
||||
if(WorldSession* session = iter->getSource()->GetOwner()->GetSession())
|
||||
session->SendPacket(i_message);
|
||||
}
|
||||
}
|
||||
|
||||
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 ) &&
|
||||
(!i_ownTeamOnly || iter->getSource()->GetTeam() == i_player.GetTeam() ) &&
|
||||
(!i_dist || iter->getSource()->IsWithinDist(&i_player,i_dist)))
|
||||
Player * owner = iter->getSource()->GetOwner();
|
||||
|
||||
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;
|
||||
|
||||
if (WorldSession* session = iter->getSource()->GetSession())
|
||||
if (WorldSession* session = owner->GetSession())
|
||||
session->SendPacket(i_message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (WorldSession* session = iter->getSource()->GetSession())
|
||||
if (WorldSession* session = iter->getSource()->GetOwner()->GetSession())
|
||||
session->SendPacket(i_message);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,13 +38,14 @@ namespace MaNGOS
|
|||
{
|
||||
struct MANGOS_DLL_DECL VisibleNotifier
|
||||
{
|
||||
Player &i_player;
|
||||
Camera& i_camera;
|
||||
UpdateData i_data;
|
||||
ObjectGuidSet i_clientGUIDs;
|
||||
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);
|
||||
void Visit(CameraMapType &m) {}
|
||||
void Notify(void);
|
||||
};
|
||||
|
||||
|
|
@ -54,7 +55,7 @@ namespace MaNGOS
|
|||
|
||||
explicit VisibleChangesNotifier(WorldObject &object) : i_object(object) {}
|
||||
template<class T> void Visit(GridRefManager<T> &) {}
|
||||
void Visit(PlayerMapType &);
|
||||
void Visit(CameraMapType &);
|
||||
};
|
||||
|
||||
struct MANGOS_DLL_DECL GridUpdater
|
||||
|
|
@ -82,7 +83,7 @@ namespace MaNGOS
|
|||
WorldPacket *i_message;
|
||||
bool i_toSelf;
|
||||
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> &) {}
|
||||
};
|
||||
|
||||
|
|
@ -95,7 +96,7 @@ namespace MaNGOS
|
|||
MessageDelivererExcept(WorldObject const* obj, WorldPacket *msg, Player const* 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> &) {}
|
||||
};
|
||||
|
||||
|
|
@ -105,7 +106,7 @@ namespace MaNGOS
|
|||
WorldPacket *i_message;
|
||||
explicit ObjectMessageDeliverer(WorldObject& obj, WorldPacket *msg)
|
||||
: i_phaseMask(obj.GetPhaseMask()), i_message(msg) {}
|
||||
void Visit(PlayerMapType &m);
|
||||
void Visit(CameraMapType &m);
|
||||
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)
|
||||
: 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> &) {}
|
||||
};
|
||||
|
||||
|
|
@ -129,7 +130,7 @@ namespace MaNGOS
|
|||
WorldPacket *i_message;
|
||||
float i_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> &) {}
|
||||
};
|
||||
|
||||
|
|
@ -140,6 +141,7 @@ namespace MaNGOS
|
|||
template<class T> void Visit(GridRefManager<T> &m);
|
||||
void Visit(PlayerMapType &) {}
|
||||
void Visit(CorpseMapType &) {}
|
||||
void Visit(CameraMapType &) {}
|
||||
void Visit(CreatureMapType &);
|
||||
};
|
||||
|
||||
|
|
@ -476,22 +478,21 @@ namespace MaNGOS
|
|||
};
|
||||
|
||||
template<class Do>
|
||||
struct MANGOS_DLL_DECL PlayerDistWorker
|
||||
struct MANGOS_DLL_DECL CameraDistWorker
|
||||
{
|
||||
WorldObject const* i_searcher;
|
||||
float i_dist;
|
||||
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) {}
|
||||
|
||||
void Visit(PlayerMapType &m)
|
||||
void Visit(CameraMapType &m)
|
||||
{
|
||||
for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
if (itr->getSource()->InSamePhase(i_searcher) && itr->getSource()->IsWithinDist(i_searcher,i_dist))
|
||||
i_do(itr->getSource());
|
||||
for(CameraMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
|
||||
if (itr->getSource()->GetBody()->InSamePhase(i_searcher) && itr->getSource()->GetBody()->IsWithinDist(i_searcher,i_dist))
|
||||
i_do(itr->getSource()->GetOwner());
|
||||
}
|
||||
|
||||
template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -31,11 +31,9 @@
|
|||
template<class T>
|
||||
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)
|
||||
{
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
|
@ -69,7 +67,7 @@ inline void PlayerCreatureRelocationWorker(Player* pl, WorldObject const* viewPo
|
|||
pl->UpdateVisibilityOf(viewPoint,c);
|
||||
|
||||
// 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())
|
||||
c->AI()->MoveInLineOfSight(pl);
|
||||
|
|
@ -78,13 +76,13 @@ inline void PlayerCreatureRelocationWorker(Player* pl, WorldObject const* viewPo
|
|||
|
||||
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())
|
||||
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())
|
||||
c2->AI()->MoveInLineOfSight(c1);
|
||||
|
|
@ -96,7 +94,7 @@ inline void MaNGOS::PlayerRelocationNotifier::Visit(CreatureMapType &m)
|
|||
if (!i_player.isAlive() || i_player.isInFlight())
|
||||
return;
|
||||
|
||||
WorldObject const* viewPoint = i_player.GetViewPoint();
|
||||
WorldObject const* viewPoint = i_player.GetCamera().GetBody();
|
||||
|
||||
for(CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
if (iter->getSource()->isAlive())
|
||||
|
|
@ -106,13 +104,13 @@ inline void MaNGOS::PlayerRelocationNotifier::Visit(CreatureMapType &m)
|
|||
template<>
|
||||
inline void MaNGOS::CreatureRelocationNotifier::Visit(PlayerMapType &m)
|
||||
{
|
||||
if(!i_creature.isAlive())
|
||||
if (!i_creature.isAlive())
|
||||
return;
|
||||
|
||||
for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
|
||||
if (Player* player = iter->getSource())
|
||||
if (player->isAlive() && !player->isInFlight())
|
||||
PlayerCreatureRelocationWorker(player, player->GetViewPoint(), &i_creature);
|
||||
PlayerCreatureRelocationWorker(player, player->GetCamera().GetBody(), &i_creature);
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
|
|||
|
|
@ -771,7 +771,7 @@ void Group::CountTheRoll(Rolls::iterator& rollI)
|
|||
if (itr->second != ROLL_NEED)
|
||||
continue;
|
||||
|
||||
uint8 randomN = urand(1, 99);
|
||||
uint8 randomN = urand(1, 100);
|
||||
SendLootRoll(itr->first, randomN, ROLL_NEED, *roll);
|
||||
if (maxresul < randomN)
|
||||
{
|
||||
|
|
@ -819,7 +819,7 @@ void Group::CountTheRoll(Rolls::iterator& rollI)
|
|||
if (itr->second != ROLL_GREED && itr->second != ROLL_DISENCHANT)
|
||||
continue;
|
||||
|
||||
uint8 randomN = urand(1, 99);
|
||||
uint8 randomN = urand(1, 100);
|
||||
SendLootRoll(itr->first, randomN, itr->second, *roll);
|
||||
if (maxresul < randomN)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
#include "InstanceSaveMgr.h"
|
||||
#include "Timer.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
#include "Config/ConfigEnv.h"
|
||||
#include "Transports.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "World.h"
|
||||
|
|
|
|||
|
|
@ -2226,6 +2226,51 @@ bool ChatHandler::HandleGroupgoCommand(const char* args)
|
|||
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)
|
||||
{
|
||||
Player* _player = m_session->GetPlayer();
|
||||
|
|
@ -2249,28 +2294,55 @@ bool ChatHandler::HandleGoTaxinodeCommand(const char* args)
|
|||
return false;
|
||||
}
|
||||
|
||||
if ((node->x == 0.0f && node->y == 0.0f && node->z == 0.0f) ||
|
||||
!MapManager::IsValidMapCoord(node->map_id,node->x,node->y,node->z))
|
||||
if (node->x == 0.0f && node->y == 0.0f && node->z == 0.0f)
|
||||
{
|
||||
PSendSysMessage(LANG_INVALID_TARGET_COORD,node->x,node->y,node->map_id);
|
||||
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(node->map_id, node->x, node->y, node->z, _player->GetOrientation());
|
||||
return true;
|
||||
return HandleGoHelper(_player, node->map_id, node->x, node->y, &node->z);
|
||||
}
|
||||
|
||||
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
|
||||
bool ChatHandler::HandleGoXYCommand(const char* args)
|
||||
{
|
||||
|
|
@ -2293,29 +2365,7 @@ bool ChatHandler::HandleGoXYCommand(const char* args)
|
|||
mapid = (uint32)atoi(pmapid);
|
||||
else mapid = _player->GetMapId();
|
||||
|
||||
if(!MapManager::IsValidMapCoord(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;
|
||||
return HandleGoHelper(_player, mapid, x, y);
|
||||
}
|
||||
|
||||
//teleport at coordinates, including Z
|
||||
|
|
@ -2343,26 +2393,7 @@ bool ChatHandler::HandleGoXYZCommand(const char* args)
|
|||
else
|
||||
mapid = _player->GetMapId();
|
||||
|
||||
if(!MapManager::IsValidMapCoord(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;
|
||||
return HandleGoHelper(_player, mapid, x, y, &z);
|
||||
}
|
||||
|
||||
//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)
|
||||
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);
|
||||
return false;
|
||||
}
|
||||
|
||||
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);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!MapManager::IsValidMapCoord(zoneEntry->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;
|
||||
return HandleGoHelper(_player, mapEntry->MapID, x, y);
|
||||
}
|
||||
|
||||
//teleport to grid
|
||||
bool ChatHandler::HandleGoGridCommand(const char* args)
|
||||
{
|
||||
if(!*args) return false;
|
||||
if (!*args)
|
||||
return false;
|
||||
|
||||
Player* _player = m_session->GetPlayer();
|
||||
|
||||
char* px = strtok((char*)args, " ");
|
||||
|
|
@ -2457,37 +2472,13 @@ bool ChatHandler::HandleGoGridCommand(const char* args)
|
|||
|
||||
float grid_x = (float)atof(px);
|
||||
float grid_y = (float)atof(py);
|
||||
uint32 mapid;
|
||||
if (pmapid)
|
||||
mapid = (uint32)atoi(pmapid);
|
||||
else mapid = _player->GetMapId();
|
||||
uint32 mapid = pmapid ? (uint32)atoi(pmapid) : _player->GetMapId();
|
||||
|
||||
// center of grid
|
||||
float x = (grid_x-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))
|
||||
{
|
||||
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;
|
||||
return HandleGoHelper(_player, mapid, x, y);
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleModifyDrunkCommand(const char* args)
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@
|
|||
#include "SkillDiscovery.h"
|
||||
#include "SkillExtraItems.h"
|
||||
#include "SystemConfig.h"
|
||||
#include "Config/ConfigEnv.h"
|
||||
#include "Config/Config.h"
|
||||
#include "Mail.h"
|
||||
#include "Util.h"
|
||||
#include "ItemEnchantmentMgr.h"
|
||||
|
|
@ -2832,7 +2832,7 @@ void ChatHandler::ShowSpellListHelper(Player* target, SpellEntry const* spellInf
|
|||
uint32 talentCost = GetTalentSpellCost(id);
|
||||
|
||||
bool talent = (talentCost > 0);
|
||||
bool passive = IsPassiveSpell(id);
|
||||
bool passive = IsPassiveSpell(spellInfo);
|
||||
bool active = target && target->HasAura(id);
|
||||
|
||||
// unit32 used to prevent interpreting uint8 as char at output
|
||||
|
|
|
|||
|
|
@ -76,6 +76,8 @@ libmangosgame_a_SOURCES = \
|
|||
Calendar.cpp \
|
||||
Calendar.h \
|
||||
CalendarHandler.cpp \
|
||||
Camera.cpp \
|
||||
Camera.h \
|
||||
Cell.h \
|
||||
CellImpl.h \
|
||||
Channel.cpp \
|
||||
|
|
|
|||
118
src/game/Map.cpp
118
src/game/Map.cpp
|
|
@ -26,7 +26,6 @@
|
|||
#include "InstanceData.h"
|
||||
#include "Map.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
#include "Config/ConfigEnv.h"
|
||||
#include "Transports.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ObjectMgr.h"
|
||||
|
|
@ -367,8 +366,9 @@ bool Map::Add(Player *player)
|
|||
SendInitSelf(player);
|
||||
SendInitTransports(player);
|
||||
|
||||
NGridType* grid = getNGrid(cell.GridX(), cell.GridY());
|
||||
player->GetViewPoint().Event_AddedToWorld(&(*grid)(cell.CellX(), cell.CellY()));
|
||||
UpdateObjectVisibility(player,cell,p);
|
||||
UpdateObjectsVisibilityFor(player,cell,p);
|
||||
|
||||
AddNotifier(player,cell,p);
|
||||
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());
|
||||
|
||||
obj->GetViewPoint().Event_AddedToWorld(&(*grid)(cell.CellX(), cell.CellY()));
|
||||
UpdateObjectVisibility(obj,cell,p);
|
||||
|
||||
AddNotifier(obj,cell,p);
|
||||
|
|
@ -682,7 +683,6 @@ void Map::Remove(Player *player, bool remove)
|
|||
|
||||
SendRemoveTransports(player);
|
||||
UpdateObjectVisibility(player,cell,p);
|
||||
UpdateObjectsVisibilityFor(player,cell,p);
|
||||
|
||||
player->ResetMap();
|
||||
if( remove )
|
||||
|
|
@ -716,10 +716,9 @@ Map::Remove(T *obj, bool remove)
|
|||
else
|
||||
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);
|
||||
|
||||
UpdateObjectVisibility(obj,cell,p);
|
||||
|
||||
obj->ResetMap();
|
||||
if( remove )
|
||||
{
|
||||
|
|
@ -759,10 +758,13 @@ Map::PlayerRelocation(Player *player, float x, float y, float z, float orientati
|
|||
AddToGrid(player, oldGrid,new_cell);
|
||||
else
|
||||
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
|
||||
UpdateObjectsVisibilityFor(player,new_cell,new_val);
|
||||
UpdateObjectVisibility(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->GetViewPoint().Call_UpdateVisibilityForOwner();
|
||||
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());
|
||||
|
||||
if( !old_cell.DiffGrid(new_cell) )
|
||||
{
|
||||
RemoveFromGrid(c,getNGrid(old_cell.GridX(), old_cell.GridY()),old_cell);
|
||||
AddToGrid(c,getNGrid(new_cell.GridX(), new_cell.GridY()),new_cell);
|
||||
c->SetCurrentCell(new_cell);
|
||||
}
|
||||
RemoveFromGrid(c,getNGrid(old_cell.GridX(), old_cell.GridY()),old_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()) );
|
||||
}
|
||||
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());
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -865,7 +871,9 @@ bool Map::CreatureCellRelocation(Creature *c, Cell new_cell)
|
|||
RemoveFromGrid(c,getNGrid(old_cell.GridX(), old_cell.GridY()),old_cell);
|
||||
{
|
||||
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;
|
||||
|
|
@ -1420,21 +1428,6 @@ void Map::UpdateObjectVisibility( WorldObject* obj, Cell cell, CellPair cellpair
|
|||
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 )
|
||||
{
|
||||
MaNGOS::PlayerRelocationNotifier relocationNotifier(*player);
|
||||
|
|
@ -1646,44 +1639,63 @@ bool Map::ActiveObjectsNearGrid(uint32 x, uint32 y) const
|
|||
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
|
||||
if(!c->isPet() && c->GetDBTableGUIDLow())
|
||||
if (obj->GetTypeId()==TYPEID_UNIT)
|
||||
{
|
||||
float x,y,z;
|
||||
c->GetRespawnCoord(x,y,z);
|
||||
GridPair p = MaNGOS::ComputeGridPair(x, y);
|
||||
if(getNGrid(p.x_coord, p.y_coord))
|
||||
getNGrid(p.x_coord, p.y_coord)->incUnloadActiveLock();
|
||||
else
|
||||
Creature* c= (Creature*)obj;
|
||||
|
||||
if (!c->isPet() && c->GetDBTableGUIDLow())
|
||||
{
|
||||
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);
|
||||
float x,y,z;
|
||||
c->GetRespawnCoord(x,y,z);
|
||||
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
|
||||
if(!c->isPet() && c->GetDBTableGUIDLow())
|
||||
if (obj->GetTypeId()==TYPEID_UNIT)
|
||||
{
|
||||
float x,y,z;
|
||||
c->GetRespawnCoord(x,y,z);
|
||||
GridPair p = MaNGOS::ComputeGridPair(x, y);
|
||||
if(getNGrid(p.x_coord, p.y_coord))
|
||||
getNGrid(p.x_coord, p.y_coord)->decUnloadActiveLock();
|
||||
else
|
||||
Creature* c= (Creature*)obj;
|
||||
|
||||
if(!c->isPet() && c->GetDBTableGUIDLow())
|
||||
{
|
||||
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);
|
||||
float x,y,z;
|
||||
c->GetRespawnCoord(x,y,z);
|
||||
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>
|
||||
{
|
||||
friend class MapReference;
|
||||
friend class ObjectGridLoader;
|
||||
friend class ObjectWorldLoader;
|
||||
public:
|
||||
Map(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode, Map* _parent = NULL);
|
||||
virtual ~Map();
|
||||
|
|
@ -211,7 +213,6 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
|
|||
void AddObjectToRemoveList(WorldObject *obj);
|
||||
|
||||
void UpdateObjectVisibility(WorldObject* obj, Cell cell, CellPair cellpair);
|
||||
void UpdateObjectsVisibilityFor(Player* player, Cell cell, CellPair cellpair);
|
||||
|
||||
void resetMarkedCells() { marked_cells.reset(); }
|
||||
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);
|
||||
|
||||
// must called with AddToWorld
|
||||
template<class T>
|
||||
void AddToActive(T* obj) { AddToActiveHelper(obj); }
|
||||
|
||||
void AddToActive(Creature* obj);
|
||||
|
||||
void AddToActive(WorldObject* obj);
|
||||
// must called with RemoveFromWorld
|
||||
template<class T>
|
||||
void RemoveFromActive(T* obj) { RemoveFromActiveHelper(obj); }
|
||||
|
||||
void RemoveFromActive(Creature* obj);
|
||||
void RemoveFromActive(WorldObject* obj);
|
||||
|
||||
Creature* GetCreature(ObjectGuid guid);
|
||||
Vehicle* GetVehicle(ObjectGuid guid);
|
||||
|
|
@ -357,27 +351,6 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
|
|||
|
||||
template<class 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
|
||||
|
|
|
|||
|
|
@ -1293,10 +1293,10 @@ void WorldSession::HandleFarSightOpcode( WorldPacket & recv_data )
|
|||
//WorldPacket data(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, 0)
|
||||
//SendPacket(&data);
|
||||
//_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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,11 +40,15 @@ inline bool isStatic(MovementGenerator *mv)
|
|||
void
|
||||
MotionMaster::Initialize()
|
||||
{
|
||||
// stop current move
|
||||
if (!i_owner->IsStopped())
|
||||
i_owner->StopMoving();
|
||||
|
||||
// clear ALL movement generators (including default)
|
||||
Clear(false,true);
|
||||
|
||||
// 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);
|
||||
push(movement == NULL ? &si_idleMovement : movement);
|
||||
|
|
@ -226,7 +230,7 @@ void MotionMaster::MoveRandom()
|
|||
void
|
||||
MotionMaster::MoveTargetedHome()
|
||||
{
|
||||
if(i_owner->hasUnitState(UNIT_STAT_FLEEING))
|
||||
if(i_owner->hasUnitState(UNIT_STAT_LOST_CONTROL))
|
||||
return;
|
||||
|
||||
Clear(false);
|
||||
|
|
@ -281,6 +285,9 @@ MotionMaster::MoveChase(Unit* target, float dist, float angle)
|
|||
void
|
||||
MotionMaster::MoveFollow(Unit* target, float dist, float angle)
|
||||
{
|
||||
if(i_owner->hasUnitState(UNIT_STAT_LOST_CONTROL))
|
||||
return;
|
||||
|
||||
Clear();
|
||||
|
||||
// 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("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;
|
||||
|
||||
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);
|
||||
recv_data.hexlike();
|
||||
|
||||
Unit *mover = _player->m_mover;
|
||||
Unit *mover = _player->GetMover();
|
||||
Player *plMover = mover->GetTypeId() == TYPEID_PLAYER ? (Player*)mover : NULL;
|
||||
|
||||
// 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
|
||||
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
|
||||
if(!plMover->isAlive())
|
||||
{
|
||||
|
|
@ -434,12 +434,13 @@ void WorldSession::HandleSetActiveMoverOpcode(WorldPacket &recv_data)
|
|||
DEBUG_LOG("WORLD: Recvd CMSG_SET_ACTIVE_MOVER");
|
||||
recv_data.hexlike();
|
||||
|
||||
uint64 guid;
|
||||
ObjectGuid 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -455,9 +456,12 @@ void WorldSession::HandleMoveNotActiveMover(WorldPacket &recv_data)
|
|||
recv_data >> old_mover_guid.ReadAsPacked();
|
||||
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
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -397,11 +397,17 @@ void WorldSession::SendSpiritResurrect()
|
|||
_player->TeleportTo(corpseGrave->map_id, corpseGrave->x, corpseGrave->y, corpseGrave->z, _player->GetOrientation());
|
||||
// or update at original position
|
||||
else
|
||||
_player->UpdateVisibilityForPlayer();
|
||||
{
|
||||
_player->GetCamera().UpdateVisibilityForOwner();
|
||||
_player->UpdateObjectVisibility();
|
||||
}
|
||||
}
|
||||
// or update at original position
|
||||
else
|
||||
_player->UpdateVisibilityForPlayer();
|
||||
{
|
||||
_player->GetCamera().UpdateVisibilityForOwner();
|
||||
_player->UpdateObjectVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandleBinderActivateOpcode( WorldPacket & recv_data )
|
||||
|
|
|
|||
|
|
@ -1084,7 +1084,7 @@ void Object::BuildUpdateData( UpdateDataMapType& /*update_players */)
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
|
@ -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::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));
|
||||
}
|
||||
|
||||
|
|
@ -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::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));
|
||||
}
|
||||
|
||||
|
|
@ -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::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);
|
||||
}
|
||||
|
||||
|
|
@ -1864,7 +1864,10 @@ void WorldObject::SetPhaseMask(uint32 newPhaseMask, bool update)
|
|||
m_phaseMask = newPhaseMask;
|
||||
|
||||
if(update && IsInWorld())
|
||||
{
|
||||
UpdateObjectVisibility();
|
||||
GetViewPoint().Event_ViewPointVisibilityChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void WorldObject::PlayDistanceSound( uint32 sound_id, Player* target /*= NULL*/ )
|
||||
|
|
@ -1910,12 +1913,22 @@ struct WorldObjectChangeAccumulator
|
|||
{
|
||||
UpdateDataMapType &i_updateDatas;
|
||||
WorldObject &i_object;
|
||||
WorldObjectChangeAccumulator(WorldObject &obj, UpdateDataMapType &d) : i_updateDatas(d), i_object(obj) {}
|
||||
void Visit(PlayerMapType &m)
|
||||
WorldObjectChangeAccumulator(WorldObject &obj, UpdateDataMapType &d) : i_updateDatas(d), i_object(obj)
|
||||
{
|
||||
for(PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
if(iter->getSource()->HaveAtClient(&i_object))
|
||||
i_object.BuildUpdateDataForPlayer(iter->getSource(), i_updateDatas);
|
||||
// send self fields changes in another way, otherwise
|
||||
// with new camera system when player's camera too far from player, camera wouldn't receive packets and changes from player
|
||||
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> &) {}
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@
|
|||
#include "ByteBuffer.h"
|
||||
#include "UpdateFields.h"
|
||||
#include "UpdateData.h"
|
||||
#include "GameSystem/GridReference.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include "Camera.h"
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
|
@ -108,11 +108,11 @@ class MANGOS_DLL_SPEC Object
|
|||
m_inWorld = false;
|
||||
}
|
||||
|
||||
ObjectGuid const& GetObjectGuid() const { return *reinterpret_cast<ObjectGuid const*>(&GetUInt64Value(0)); }
|
||||
|
||||
const uint64& GetGUID() const { return GetUInt64Value(0); }
|
||||
uint32 GetGUIDLow() const { return GUID_LOPART(GetUInt64Value(0)); }
|
||||
ObjectGuid const& GetObjectGuid() const { return GetGuidValue(OBJECT_FIELD_GUID); }
|
||||
const uint64& GetGUID() const { return GetUInt64Value(OBJECT_FIELD_GUID); }
|
||||
uint32 GetGUIDLow() const { return GUID_LOPART(GetUInt64Value(OBJECT_FIELD_GUID)); }
|
||||
PackedGuid const& GetPackGUID() const { return m_PackGUID; }
|
||||
|
||||
uint32 GetEntry() const { return GetUInt32Value(OBJECT_FIELD_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);
|
||||
}
|
||||
|
||||
ObjectGuid const& GetGuidValue( uint16 index ) const { return *reinterpret_cast<ObjectGuid const*>(&GetUInt64Value(index)); }
|
||||
|
||||
void SetInt32Value( uint16 index, int32 value );
|
||||
void SetUInt32Value( uint16 index, uint32 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 SetUInt16Value( uint16 index, uint8 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 SetStatInt32Value( uint16 index, int32 value);
|
||||
|
||||
|
|
@ -476,6 +479,10 @@ class MANGOS_DLL_SPEC WorldObject : public Object
|
|||
void BuildUpdateData(UpdateDataMapType &);
|
||||
|
||||
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:
|
||||
explicit WorldObject();
|
||||
|
||||
|
|
@ -487,6 +494,7 @@ class MANGOS_DLL_SPEC WorldObject : public Object
|
|||
|
||||
std::string m_name;
|
||||
|
||||
bool m_isActiveObject;
|
||||
private:
|
||||
Map * m_currMap; //current object's Map location
|
||||
|
||||
|
|
@ -498,6 +506,8 @@ class MANGOS_DLL_SPEC WorldObject : public Object
|
|||
float m_positionY;
|
||||
float m_positionZ;
|
||||
float m_orientation;
|
||||
|
||||
ViewPoint m_viewPoint;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "Corpse.h"
|
||||
#include "World.h"
|
||||
#include "CellImpl.h"
|
||||
#include "GridDefines.h"
|
||||
|
||||
class MANGOS_DLL_DECL ObjectGridRespawnMover
|
||||
{
|
||||
|
|
@ -105,7 +106,7 @@ template<> void addUnitState(Creature *obj, CellPair const& cell_pair)
|
|||
}
|
||||
|
||||
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;
|
||||
|
||||
|
|
@ -121,13 +122,16 @@ void LoadHelper(CellGuidSet const& guid_set, CellPair &cell, GridRefManager<T> &
|
|||
continue;
|
||||
}
|
||||
|
||||
obj->GetGridRef().link(&m, obj);
|
||||
grid.AddGridObject(obj);
|
||||
|
||||
addUnitState(obj,cell);
|
||||
obj->SetMap(map);
|
||||
obj->AddToWorld();
|
||||
if(obj->isActiveObject())
|
||||
map->AddToActive(obj);
|
||||
|
||||
obj->GetViewPoint().Event_AddedToWorld(&grid);
|
||||
|
||||
if (bg)
|
||||
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())
|
||||
return;
|
||||
|
|
@ -151,7 +155,7 @@ void LoadHelper(CellCorpseSet const& cell_corpses, CellPair &cell, CorpseMapType
|
|||
if(!obj)
|
||||
continue;
|
||||
|
||||
obj->GetGridRef().link(&m, obj);
|
||||
grid.AddWorldObject(obj);
|
||||
|
||||
addUnitState(obj,cell);
|
||||
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);
|
||||
|
||||
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
|
||||
|
|
@ -186,7 +191,8 @@ ObjectGridLoader::Visit(CreatureMapType &m)
|
|||
|
||||
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
|
||||
|
|
@ -199,7 +205,8 @@ ObjectWorldLoader::Visit(CorpseMapType &m)
|
|||
|
||||
// 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);
|
||||
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
|
||||
|
|
|
|||
|
|
@ -929,7 +929,8 @@ void ObjectMgr::LoadEquipmentTemplates()
|
|||
dbcitem->InventoryType != INVTYPE_WEAPONOFFHAND &&
|
||||
dbcitem->InventoryType != INVTYPE_HOLDABLE &&
|
||||
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);
|
||||
const_cast<EquipmentInfo*>(eqInfo)->equipentry[j] = 0;
|
||||
|
|
|
|||
|
|
@ -359,7 +359,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
|
|||
/*0x14A*/ { "SMSG_ATTACKERSTATEUPDATE", 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 },
|
||||
/*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 },
|
||||
/*0x14F*/ { "SMSG_SPELLBREAKLOG", 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 },
|
||||
/*0x21C*/ { "CMSG_SPIRIT_HEALER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleSpiritHealerActivateOpcode},
|
||||
/*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 },
|
||||
/*0x220*/ { "CMSG_SKILL_BUY_RANK", 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 },
|
||||
/*0x45E*/ { "SMSG_SPLINE_SET_PITCH_RATE", 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 },
|
||||
/*0x461*/ { "CMSG_MOVE_ABANDON_TRANSPORT_ACK", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||
/*0x460*/ { "SMSG_CALENDAR_UPDATE_INVITE_LIST", 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 },
|
||||
/*0x463*/ { "SMSG_UPDATE_ACCOUNT_DATA_COMPLETE", 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 },
|
||||
/*0x46F*/ { "SMSG_QUESTUPDATE_ADD_PVP_KILL", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||
/*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 },
|
||||
/*0x473*/ { "CMSG_CHAR_CUSTOMIZE", STATUS_AUTHED, &WorldSession::HandleCharCustomize },
|
||||
/*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 },
|
||||
/*0x4CC*/ { "UMSG_UNKNOWN_1228", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||
/*0x4CD*/ { "SMSG_MULTIPLE_PACKETS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||
/*0x4CE*/ { "SMSG_UNKNOWN_1230", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||
/*0x4CF*/ { "CMSG_UNKNOWN_1231_ACK", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||
/*0x4D0*/ { "SMSG_UNKNOWN_1232", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||
/*0x4D1*/ { "CMSG_UNKNOWN_1233_ACK", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||
/*0x4D2*/ { "SMSG_UNKNOWN_1234", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||
/*0x4D3*/ { "SMSG_UNKNOWN_1235", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||
/*0x4D4*/ { "SMSG_UNKNOWN_1236", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||
/*0x4CE*/ { "SMSG_FORCE_UNK1_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||
/*0x4CF*/ { "CMSG_FORCE_UNK1_SPEED_CHANGE_ACK", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||
/*0x4D0*/ { "SMSG_FORCE_UNK2_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||
/*0x4D1*/ { "CMSG_FORCE_UNK2_SPEED_CHANGE_ACK", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||
/*0x4D2*/ { "MSG_MOVE_UNKNOWN_1234", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||
/*0x4D3*/ { "SMSG_SPLINE_MOVE_UNKNOWN_1235", 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 },
|
||||
/*0x4D6*/ { "SMSG_EQUIPMENT_SET_USE_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||
/*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 },
|
||||
/*0x4DD*/ { "UMSG_UNKNOWN_1245", STATUS_NEVER, &WorldSession::Handle_NULL },
|
||||
/*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 },
|
||||
/*0x4E1*/ { "SMSG_BATTLEFIELD_MGR_QUEUE_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
|
||||
/*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
|
||||
CMSG_CORPSE_MAP_POSITION_QUERY = 0x4B6, // CMSG, uint32
|
||||
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
|
||||
CMSG_CALENDAR_CONTEXT_EVENT_SIGNUP = 0x4BA, // CMSG, uint64, lua: CalendarContextEventSignUp
|
||||
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(IsPassiveSpell(spell_id))
|
||||
if(IsPassiveSpell(spellInfo))
|
||||
newspell.active = ACT_PASSIVE;
|
||||
else
|
||||
newspell.active = ACT_DISABLED;
|
||||
|
|
@ -1369,7 +1369,7 @@ bool Pet::addSpell(uint32 spell_id,ActiveStates active /*= ACT_DECIDE*/, PetSpel
|
|||
|
||||
m_spells[spell_id] = newspell;
|
||||
|
||||
if (IsPassiveSpell(spell_id))
|
||||
if (IsPassiveSpell(spellInfo))
|
||||
CastSpell(this, spell_id, true);
|
||||
else
|
||||
m_charmInfo->AddSpellToActionBar(spell_id, ActiveStates(newspell.active));
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
|
|||
{
|
||||
case COMMAND_STAY: //flat=1792 //STAY
|
||||
pet->StopMoving();
|
||||
pet->GetMotionMaster()->Clear();
|
||||
pet->GetMotionMaster()->Clear(false);
|
||||
pet->GetMotionMaster()->MoveIdle();
|
||||
charmInfo->SetCommandState( COMMAND_STAY );
|
||||
break;
|
||||
|
|
@ -191,7 +191,7 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
|
|||
}
|
||||
|
||||
// do not cast not learned spells
|
||||
if(!pet->HasSpell(spellid) || IsPassiveSpell(spellid))
|
||||
if(!pet->HasSpell(spellid) || IsPassiveSpell(spellInfo))
|
||||
return;
|
||||
|
||||
pet->clearUnitState(UNIT_STAT_MOVING);
|
||||
|
|
@ -626,7 +626,7 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
|
|||
}
|
||||
|
||||
// do not cast not learned spells
|
||||
if (!pet->HasSpell(spellid) || IsPassiveSpell(spellid))
|
||||
if (!pet->HasSpell(spellid) || IsPassiveSpell(spellInfo))
|
||||
return;
|
||||
|
||||
SpellCastTargets targets;
|
||||
|
|
|
|||
|
|
@ -405,7 +405,7 @@ void TradeData::SetAccepted(bool state, bool crosssend /*= false*/)
|
|||
|
||||
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;
|
||||
|
||||
|
|
@ -417,6 +417,8 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa
|
|||
|
||||
m_valuesCount = PLAYER_END;
|
||||
|
||||
m_isActiveObject = true; // player is always active object
|
||||
|
||||
m_session = session;
|
||||
|
||||
m_divider = 0;
|
||||
|
|
@ -478,6 +480,7 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa
|
|||
m_DelayedOperations = 0;
|
||||
m_bCanDelayTeleport = false;
|
||||
m_bHasDelayedTeleport = false;
|
||||
m_bHasBeenAliveAtDelayedTeleport = true; // overwrite always at setup teleport data, so not used infact
|
||||
m_teleport_options = 0;
|
||||
|
||||
m_trade = NULL;
|
||||
|
|
@ -584,8 +587,6 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa
|
|||
m_summon_y = 0.0f;
|
||||
m_summon_z = 0.0f;
|
||||
|
||||
m_mover = this;
|
||||
|
||||
m_miniPet = 0;
|
||||
m_contestedPvPTimer = 0;
|
||||
|
||||
|
|
@ -1474,9 +1475,7 @@ void Player::Update( uint32 p_time )
|
|||
RemovePet(pet, PET_SAVE_NOT_IN_SLOT, true);
|
||||
}
|
||||
|
||||
//we should execute delayed teleports only for alive(!) players
|
||||
//because we don't want player's ghost teleported from graveyard
|
||||
if(IsHasDelayedTeleport() && isAlive())
|
||||
if (IsHasDelayedTeleport())
|
||||
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
|
||||
SetSemaphoreTeleportFar(false);
|
||||
//setup delayed teleport flag
|
||||
SetDelayedTeleportFlag(IsCanDelayTeleport());
|
||||
//if teleport spell is casted in Unit::Update() func
|
||||
//then we need to delay it until update process will be finished
|
||||
if(IsHasDelayedTeleport())
|
||||
if (SetDelayedTeleportFlagIfCan())
|
||||
{
|
||||
SetSemaphoreTeleportNear(true);
|
||||
//lets save teleport destination for player
|
||||
|
|
@ -1794,7 +1792,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
|
|||
UnsummonPetTemporaryIfAny();
|
||||
}
|
||||
|
||||
if(!(options & TELE_TO_NOT_LEAVE_COMBAT))
|
||||
if (!(options & TELE_TO_NOT_LEAVE_COMBAT))
|
||||
CombatStop();
|
||||
|
||||
// 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
|
||||
SetSemaphoreTeleportNear(false);
|
||||
//setup delayed teleport flag
|
||||
SetDelayedTeleportFlag(IsCanDelayTeleport());
|
||||
//if teleport spell is casted in Unit::Update() func
|
||||
//then we need to delay it until update process will be finished
|
||||
if(IsHasDelayedTeleport())
|
||||
if (SetDelayedTeleportFlagIfCan())
|
||||
{
|
||||
SetSemaphoreTeleportFar(true);
|
||||
//lets save teleport destination for player
|
||||
|
|
@ -1850,7 +1847,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
|
|||
ResetContestedPvP();
|
||||
|
||||
// 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
|
||||
// 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
|
||||
// not attempt interrupt teleportation spell at caster teleport
|
||||
if(!(options & TELE_TO_SPELL))
|
||||
if(IsNonMeleeSpellCasted(true))
|
||||
if (!(options & TELE_TO_SPELL))
|
||||
if (IsNonMeleeSpellCasted(true))
|
||||
InterruptNonMeleeSpells(true);
|
||||
|
||||
//remove auras before removing from map...
|
||||
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CHANGE_MAP | AURA_INTERRUPT_FLAG_MOVE | AURA_INTERRUPT_FLAG_TURNING);
|
||||
|
||||
if(!GetSession()->PlayerLogout())
|
||||
if (!GetSession()->PlayerLogout())
|
||||
{
|
||||
// send transfer packets
|
||||
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
|
||||
if(oldmap)
|
||||
if (oldmap)
|
||||
oldmap->Remove(this, false);
|
||||
|
||||
// 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_o = orientation;
|
||||
|
||||
if(m_transport)
|
||||
if (m_transport)
|
||||
{
|
||||
final_x += m_movementInfo.GetTransportPos()->x;
|
||||
final_y += m_movementInfo.GetTransportPos()->y;
|
||||
|
|
@ -2236,7 +2233,7 @@ Creature* Player::GetNPCIfCanInteractWith(ObjectGuid guid, uint32 npcflagmask)
|
|||
return NULL;
|
||||
|
||||
// not in interactive state
|
||||
if (hasUnitState(UNIT_STAT_CAN_NOT_REACT))
|
||||
if (hasUnitState(UNIT_STAT_CAN_NOT_REACT_OR_LOST_CONTROL))
|
||||
return NULL;
|
||||
|
||||
// exist (we need look pets also for some interaction (quest/etc)
|
||||
|
|
@ -2290,7 +2287,7 @@ GameObject* Player::GetGameObjectIfCanInteractWith(ObjectGuid guid, uint32 gameo
|
|||
return NULL;
|
||||
|
||||
// not in interactive state
|
||||
if (hasUnitState(UNIT_STAT_CAN_NOT_REACT))
|
||||
if (hasUnitState(UNIT_STAT_CAN_NOT_REACT_OR_LOST_CONTROL))
|
||||
return NULL;
|
||||
|
||||
if (GameObject *go = GetMap()->GetGameObject(guid))
|
||||
|
|
@ -2409,7 +2406,8 @@ void Player::SetGameMaster(bool on)
|
|||
getHostileRefManager().setOnlineOfflineState(true);
|
||||
}
|
||||
|
||||
UpdateVisibilityForPlayer();
|
||||
m_camera.UpdateVisibilityForOwner();
|
||||
UpdateObjectVisibility();
|
||||
}
|
||||
|
||||
void Player::SetGMVisible(bool on)
|
||||
|
|
@ -3062,7 +3060,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
|||
|
||||
if(active)
|
||||
{
|
||||
if (IsPassiveSpell(spell_id) && IsNeedCastPassiveSpellAtLearn(spellInfo))
|
||||
if (IsPassiveSpell(spellInfo) && IsNeedCastPassiveSpellAtLearn(spellInfo))
|
||||
CastSpell (this, spell_id, true);
|
||||
}
|
||||
else if(IsInWorld())
|
||||
|
|
@ -3253,7 +3251,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
|||
CastSpell(this, spell_id, true);
|
||||
}
|
||||
// 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))
|
||||
CastSpell(this, spell_id, true);
|
||||
|
|
@ -4490,8 +4488,10 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
|
|||
GetZoneAndAreaId(newzone,newarea);
|
||||
UpdateZone(newzone,newarea);
|
||||
|
||||
// update visibility
|
||||
UpdateVisibilityForPlayer();
|
||||
// update visibility of world around viewpoint
|
||||
m_camera.UpdateVisibilityForOwner();
|
||||
// update visibility of player for nearby cameras
|
||||
UpdateObjectVisibility();
|
||||
|
||||
if(!applySickness)
|
||||
return;
|
||||
|
|
@ -6073,42 +6073,30 @@ void Player::SaveRecallPosition()
|
|||
|
||||
void Player::SendMessageToSet(WorldPacket *data, bool self)
|
||||
{
|
||||
Map * _map = IsInWorld() ? GetMap() : sMapMgr.FindMap(GetMapId(), GetInstanceId());
|
||||
if(_map)
|
||||
{
|
||||
_map->MessageBroadcast(this, data, self);
|
||||
return;
|
||||
}
|
||||
if (Map * _map = IsInWorld() ? GetMap() : sMapMgr.FindMap(GetMapId(), GetInstanceId()))
|
||||
_map->MessageBroadcast(this, data, false);
|
||||
|
||||
//if player is not in world and map in not created/already destroyed
|
||||
//no need to create one, just send packet for itself!
|
||||
if(self)
|
||||
if (self)
|
||||
GetSession()->SendPacket(data);
|
||||
}
|
||||
|
||||
void Player::SendMessageToSetInRange(WorldPacket *data, float dist, bool self)
|
||||
{
|
||||
Map * _map = IsInWorld() ? GetMap() : sMapMgr.FindMap(GetMapId(), GetInstanceId());
|
||||
if(_map)
|
||||
{
|
||||
_map->MessageDistBroadcast(this, data, dist, self);
|
||||
return;
|
||||
}
|
||||
if (Map * _map = IsInWorld() ? GetMap() : sMapMgr.FindMap(GetMapId(), GetInstanceId()))
|
||||
_map->MessageDistBroadcast(this, data, dist, false);
|
||||
|
||||
if(self)
|
||||
if (self)
|
||||
GetSession()->SendPacket(data);
|
||||
}
|
||||
|
||||
void Player::SendMessageToSetInRange(WorldPacket *data, float dist, bool self, bool own_team_only)
|
||||
{
|
||||
Map * _map = IsInWorld() ? GetMap() : sMapMgr.FindMap(GetMapId(), GetInstanceId());
|
||||
if(_map)
|
||||
{
|
||||
_map->MessageDistBroadcast(this, data, dist, self, own_team_only);
|
||||
return;
|
||||
}
|
||||
if (Map * _map = IsInWorld() ? GetMap() : sMapMgr.FindMap(GetMapId(), GetInstanceId()))
|
||||
_map->MessageDistBroadcast(this, data, dist, false, own_team_only);
|
||||
|
||||
if(self)
|
||||
if (self)
|
||||
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 )
|
||||
{
|
||||
//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();
|
||||
|
||||
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))
|
||||
CastSpell(this,itr->second->spellId,true);
|
||||
}
|
||||
|
||||
//lets remove flag for delayed teleports
|
||||
SetCanDelayTeleport(false);
|
||||
}
|
||||
|
||||
void Player::FailQuest(uint32 questId)
|
||||
|
|
@ -15322,7 +15303,8 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
|||
SetCreatorGUID(0);
|
||||
|
||||
// reset some aura modifiers before aura apply
|
||||
SetFarSightGUID(0);
|
||||
|
||||
SetUInt64Value(PLAYER_FARSIGHT, 0);
|
||||
SetUInt32Value(PLAYER_TRACK_CREATURES, 0 );
|
||||
SetUInt32Value(PLAYER_TRACK_RESOURCES, 0 );
|
||||
|
||||
|
|
@ -17605,7 +17587,7 @@ void Player::RemoveMiniPet()
|
|||
}
|
||||
}
|
||||
|
||||
Pet* Player::GetMiniPet()
|
||||
Pet* Player::GetMiniPet() const
|
||||
{
|
||||
if (!m_miniPet)
|
||||
return NULL;
|
||||
|
|
@ -18058,7 +18040,7 @@ void Player::HandleStealthedUnitsDetection()
|
|||
MaNGOS::UnitListSearcher<MaNGOS::AnyStealthedCheck > searcher(this,stealthedUnits, u_check);
|
||||
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)
|
||||
{
|
||||
|
|
@ -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
|
||||
{
|
||||
// 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())
|
||||
m_movementInfo.AddMovementFlag(MOVEFLAG_FLYING);
|
||||
|
||||
m_mover = this;
|
||||
SetMover(this);
|
||||
}
|
||||
|
||||
void Player::SendInitialPacketsAfterAddToMap()
|
||||
|
|
@ -20736,7 +20707,7 @@ void Player::EnterVehicle(Vehicle *vehicle)
|
|||
vehicle->setFaction(getFaction());
|
||||
|
||||
SetCharm(vehicle); // charm
|
||||
SetFarSightGUID(vehicle->GetGUID()); // set view
|
||||
m_camera.SetView(vehicle); // set view
|
||||
|
||||
SetClientControl(vehicle, 1); // redirect controls to vehicle
|
||||
SetMover(vehicle);
|
||||
|
|
@ -20788,7 +20759,7 @@ void Player::ExitVehicle(Vehicle *vehicle)
|
|||
vehicle->setFaction((GetTeam() == ALLIANCE) ? vehicle->GetCreatureInfo()->faction_A : vehicle->GetCreatureInfo()->faction_H);
|
||||
|
||||
SetCharm(NULL);
|
||||
SetFarSightGUID(0);
|
||||
m_camera.ResetView();
|
||||
|
||||
SetClientControl(vehicle, 0);
|
||||
SetMover(NULL);
|
||||
|
|
@ -21230,6 +21201,23 @@ void Player::UpdateAchievementCriteria( AchievementCriteriaTypes type, uint32 mi
|
|||
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)
|
||||
{
|
||||
uint32 CurTalentPoints = GetFreeTalentPoints();
|
||||
|
|
@ -21256,9 +21244,8 @@ void Player::LearnTalent(uint32 talentId, uint32 talentRank)
|
|||
|
||||
// find current max talent rank
|
||||
uint32 curtalent_maxrank = 0;
|
||||
PlayerTalentMap::iterator itr = m_talents[m_activeSpec].find(talentId);
|
||||
if (itr != m_talents[m_activeSpec].end() && itr->second.state != PLAYERSPELL_REMOVED)
|
||||
curtalent_maxrank = itr->second.currentRank + 1;
|
||||
if (PlayerTalent const* talent = GetKnownTalentById(talentId))
|
||||
curtalent_maxrank = talent->currentRank + 1;
|
||||
|
||||
// we already have same or higher talent rank learned
|
||||
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)
|
||||
// and if they have different rank
|
||||
PlayerTalentMap::iterator specIter = m_talents[m_activeSpec].find(tempIter->first);
|
||||
if (specIter != m_talents[m_activeSpec].end() && specIter->second.state != PLAYERSPELL_REMOVED)
|
||||
if (PlayerTalent const* cur_talent = GetKnownTalentById(tempIter->first))
|
||||
{
|
||||
if ((*specIter).second.currentRank != talent.currentRank)
|
||||
if (cur_talent->currentRank != talent.currentRank)
|
||||
learnSpell(talentSpellId, false);
|
||||
}
|
||||
else
|
||||
learnSpell(talentSpellId, false);
|
||||
|
||||
// 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())
|
||||
(*specIter).second.state = talent.state;
|
||||
else
|
||||
|
|
@ -21925,11 +21911,20 @@ void Player::ActivateSpec(uint8 specNum)
|
|||
|
||||
// recheck action buttons (not checked at loading/spec copy)
|
||||
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)
|
||||
{
|
||||
// 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))
|
||||
{
|
||||
removeActionButton(m_activeSpec,itr->first);
|
||||
itr = currentActionButtonList.begin();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
++itr;
|
||||
}
|
||||
|
||||
ResummonPetTemporaryUnSummonedIfAny();
|
||||
|
||||
|
|
@ -22022,38 +22017,6 @@ bool Player::HasMovementFlag( MovementFlags f ) const
|
|||
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()
|
||||
{
|
||||
m_timeSyncCounter = 0;
|
||||
|
|
|
|||
|
|
@ -1128,8 +1128,6 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
Creature* GetNPCIfCanInteractWith(ObjectGuid guid, uint32 npcflagmask);
|
||||
GameObject* GetGameObjectIfCanInteractWith(ObjectGuid guid, uint32 gameobject_type = MAX_GAMEOBJECT_TYPE) const;
|
||||
|
||||
void UpdateVisibilityForPlayer();
|
||||
|
||||
bool ToggleAFK();
|
||||
bool ToggleDND();
|
||||
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 RemoveMiniPet();
|
||||
Pet* GetMiniPet();
|
||||
Pet* GetMiniPet() const;
|
||||
void SetMiniPet(Pet* pet) { m_miniPet = pet->GetGUID(); }
|
||||
|
||||
template<typename Func>
|
||||
|
|
@ -1666,6 +1664,9 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
|
||||
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);
|
||||
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);
|
||||
|
|
@ -2191,7 +2192,6 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
/*********************************************************/
|
||||
bool HasMovementFlag(MovementFlags f) const; // for script access to m_movementInfo.HasMovementFlag
|
||||
void UpdateFallInformationIfNeed(MovementInfo const& minfo,uint16 opcode);
|
||||
Unit *m_mover;
|
||||
void SetFallInformation(uint32 time, float z)
|
||||
{
|
||||
m_lastFallTime = time;
|
||||
|
|
@ -2210,12 +2210,13 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
|
||||
void SetClientControl(Unit* target, uint8 allowMove);
|
||||
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 ExitVehicle(Vehicle *vehicle);
|
||||
|
||||
uint64 GetFarSight() const { return GetUInt64Value(PLAYER_FARSIGHT); }
|
||||
void SetFarSightGUID(uint64 guid);
|
||||
ObjectGuid const& GetFarSightGuid() const { return GetGuidValue(PLAYER_FARSIGHT); }
|
||||
|
||||
// Transports
|
||||
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(); }
|
||||
|
||||
WorldObject const* GetViewPoint() const;
|
||||
bool IsVisibleInGridForPlayer(Player* pl) const;
|
||||
bool IsVisibleGloballyFor(Player* pl) const;
|
||||
|
||||
|
|
@ -2262,6 +2262,8 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
// Stealth detection system
|
||||
void HandleStealthedUnitsDetection();
|
||||
|
||||
Camera& GetCamera() { return m_camera; }
|
||||
|
||||
uint8 m_forced_speed_changes[MAX_MOVE_TYPE];
|
||||
|
||||
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); }
|
||||
void SetTitle(CharTitlesEntry const* title, bool lost = false);
|
||||
|
||||
bool isActiveObject() const { return true; }
|
||||
bool canSeeSpellClickOn(Creature const* creature) const;
|
||||
protected:
|
||||
|
||||
|
|
@ -2592,17 +2593,30 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
int32 CalculateReputationGain(uint32 creatureOrQuestLevel, int32 rep, int32 faction, bool for_quest);
|
||||
void AdjustQuestReqItemCount( Quest const* pQuest, QuestStatusData& questStatusData );
|
||||
|
||||
bool IsCanDelayTeleport() const { return m_bCanDelayTeleport; }
|
||||
void SetCanDelayTeleport(bool setting) { m_bCanDelayTeleport = setting; }
|
||||
bool IsHasDelayedTeleport() const { return m_bHasDelayedTeleport; }
|
||||
void SetDelayedTeleportFlag(bool setting) { m_bHasDelayedTeleport = setting; }
|
||||
bool IsHasDelayedTeleport() const
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
if(operation < DELAYED_END)
|
||||
if (operation < DELAYED_END)
|
||||
m_DelayedOperations |= operation;
|
||||
}
|
||||
|
||||
Unit *m_mover;
|
||||
Camera m_camera;
|
||||
|
||||
GridReference<Player> m_gridRef;
|
||||
MapReference m_mapRef;
|
||||
|
||||
|
|
@ -2630,6 +2644,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
uint32 m_DelayedOperations;
|
||||
bool m_bCanDelayTeleport;
|
||||
bool m_bHasDelayedTeleport;
|
||||
bool m_bHasBeenAliveAtDelayedTeleport;
|
||||
|
||||
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
|
||||
{
|
||||
if (withMiniPet)
|
||||
if(Unit* mini = GetMiniPet())
|
||||
if(Unit const* mini = GetMiniPet())
|
||||
if (func(mini))
|
||||
return true;
|
||||
|
||||
|
|
|
|||
|
|
@ -106,6 +106,30 @@ void SpawnedPoolData::RemoveSpawn<Pool>(uint32 sub_pool_id, uint32 pool_id)
|
|||
--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
|
||||
|
||||
|
|
@ -134,6 +158,40 @@ bool PoolGroup<T>::CheckPool() const
|
|||
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>
|
||||
PoolObject* PoolGroup<T>::RollOne(SpawnedPoolData& spawns, uint32 triggerFrom)
|
||||
{
|
||||
|
|
@ -146,7 +204,7 @@ PoolObject* PoolGroup<T>::RollOne(SpawnedPoolData& spawns, uint32 triggerFrom)
|
|||
roll -= ExplicitlyChanced[i].chance;
|
||||
// Triggering object is marked as spawned at this time and can be also rolled (respawn 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];
|
||||
}
|
||||
}
|
||||
|
|
@ -156,7 +214,7 @@ PoolObject* PoolGroup<T>::RollOne(SpawnedPoolData& spawns, uint32 triggerFrom)
|
|||
int32 index = irand(0, EqualChanced.size()-1);
|
||||
// Triggering object is marked as spawned at this time and can be also rolled (respawn 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];
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
// spawned by 1
|
||||
if (triggerFrom)
|
||||
++count;
|
||||
{
|
||||
if (spawns.IsSpawnedObject<T>(triggerFrom))
|
||||
++count;
|
||||
else
|
||||
triggerFrom = 0;
|
||||
}
|
||||
|
||||
// This will try to spawn the rest of pool, not guaranteed
|
||||
for (int i = 0; i < count; ++i)
|
||||
|
|
@ -462,6 +525,7 @@ void PoolManager::LoadFromDB()
|
|||
|
||||
PoolTemplateData& pPoolTemplate = mPoolTemplate[pool_id];
|
||||
pPoolTemplate.MaxLimit = fields[1].GetUInt32();
|
||||
pPoolTemplate.AutoSpawn = true; // will update and later data loading
|
||||
|
||||
} while (result->NextRow());
|
||||
|
||||
|
|
@ -661,6 +725,9 @@ void PoolManager::LoadFromDB()
|
|||
SearchPair p(child_pool_id, mother_pool_id);
|
||||
mPoolSearchMap.insert(p);
|
||||
|
||||
// update top independent pool flag
|
||||
mPoolTemplate[child_pool_id].AutoSpawn = false;
|
||||
|
||||
} while( result->NextRow() );
|
||||
|
||||
// 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()
|
||||
{
|
||||
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;
|
||||
if (result)
|
||||
uint32 count = 0;
|
||||
|
||||
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))
|
||||
{
|
||||
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);
|
||||
count++;
|
||||
} while (result->NextRow());
|
||||
delete result;
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
// 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
|
||||
// Here we cache only the creature/gameobject whose guid is passed as parameter
|
||||
// Then the spawn pool call will use this cache to decide
|
||||
|
|
|
|||
|
|
@ -27,13 +27,19 @@
|
|||
struct PoolTemplateData
|
||||
{
|
||||
uint32 MaxLimit;
|
||||
bool AutoSpawn; // spawn at pool system start (not part of another pool and not part of event spawn)
|
||||
};
|
||||
|
||||
struct PoolObject
|
||||
{
|
||||
uint32 guid;
|
||||
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
|
||||
|
|
@ -73,10 +79,12 @@ class PoolGroup
|
|||
bool isEmpty() const { return ExplicitlyChanced.empty() && EqualChanced.empty(); }
|
||||
void AddEntry(PoolObject& poolitem, uint32 maxentries);
|
||||
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);
|
||||
void DespawnObject(SpawnedPoolData& spawns, uint32 guid=0);
|
||||
void Despawn1Object(uint32 guid);
|
||||
void SpawnObject(SpawnedPoolData& spawns, uint32 limit, uint32 triggerFrom, bool instantly);
|
||||
void SetExcludeObject(uint32 guid, bool state);
|
||||
|
||||
void Spawn1Object(PoolObject* obj, bool instantly);
|
||||
void ReSpawn1Object(PoolObject* obj);
|
||||
|
|
@ -99,17 +107,37 @@ class PoolManager
|
|||
template<typename T>
|
||||
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>
|
||||
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;
|
||||
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 DespawnPool(uint16 pool_id);
|
||||
|
||||
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:
|
||||
template<typename T>
|
||||
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
|
||||
// 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)
|
||||
{
|
||||
// check only spell that apply positive auras
|
||||
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;
|
||||
}
|
||||
}
|
||||
// spell expected to be auto-downranking in cast handle, so must be same
|
||||
if (m_spellInfo != sSpellMgr.SelectAuraRankForLevel(m_spellInfo, target->getLevel()))
|
||||
return SPELL_FAILED_LOWLEVEL;
|
||||
}
|
||||
}
|
||||
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)
|
||||
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())
|
||||
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)
|
||||
if (!IsPassiveSpell(m_spellInfo->Id))
|
||||
if (!IsPassiveSpell(m_spellInfo))
|
||||
{
|
||||
SpellCastResult castResult = CheckItems();
|
||||
if(castResult != SPELL_CAST_OK)
|
||||
|
|
|
|||
|
|
@ -23,11 +23,14 @@
|
|||
#include "SharedDefines.h"
|
||||
#include "DBCEnums.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include "LootMgr.h"
|
||||
#include "Unit.h"
|
||||
#include "Player.h"
|
||||
|
||||
class WorldSession;
|
||||
class Unit;
|
||||
class WorldPacket;
|
||||
class DynamicObj;
|
||||
class Player;
|
||||
class Item;
|
||||
class GameObject;
|
||||
class Group;
|
||||
class Aura;
|
||||
|
|
@ -808,6 +811,7 @@ namespace MaNGOS
|
|||
template<> inline void Visit(CorpseMapType & ) {}
|
||||
template<> inline void Visit(GameObjectMapType & ) {}
|
||||
template<> inline void Visit(DynamicObjectMapType & ) {}
|
||||
template<> inline void Visit(CameraMapType & ) {}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
@ -815,6 +819,7 @@ namespace MaNGOS
|
|||
template<> inline void SpellNotifierCreatureAndPlayer::Visit(CorpseMapType& ) {}
|
||||
template<> inline void SpellNotifierCreatureAndPlayer::Visit(GameObjectMapType& ) {}
|
||||
template<> inline void SpellNotifierCreatureAndPlayer::Visit(DynamicObjectMapType& ) {}
|
||||
template<> inline void SpellNotifierCreatureAndPlayer::Visit(CameraMapType& ) {}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -386,7 +386,7 @@ m_isRemovedOnShapeLost(true), m_in_use(0), m_deleted(false)
|
|||
|
||||
m_currentBasePoints = currentBasePoints ? *currentBasePoints : m_spellProto->CalculateSimpleValue(eff);
|
||||
|
||||
m_isPassive = IsPassiveSpell(GetId());
|
||||
m_isPassive = IsPassiveSpell(GetSpellProto());
|
||||
m_positive = IsPositiveEffect(GetId(), m_effIndex);
|
||||
|
||||
m_isSingleTargetAura = IsSingleTargetSpell(m_spellProto);
|
||||
|
|
@ -633,7 +633,7 @@ void Aura::Update(uint32 diff)
|
|||
Unit* caster = GetCaster();
|
||||
if(!caster)
|
||||
{
|
||||
m_target->RemoveAura(GetId(), GetEffIndex());
|
||||
m_target->RemoveAurasByCasterSpell(GetId(), GetEffIndex(), GetCasterGUID());
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -648,7 +648,7 @@ void Aura::Update(uint32 diff)
|
|||
|
||||
if(!caster->IsWithinDistInMap(m_target, max_range))
|
||||
{
|
||||
m_target->RemoveAura(GetId(), GetEffIndex());
|
||||
m_target->RemoveAurasByCasterSpell(GetId(), GetEffIndex(), GetCasterGUID());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -813,7 +813,7 @@ void AreaAura::Update(uint32 diff)
|
|||
if(!apply)
|
||||
continue;
|
||||
|
||||
if(SpellEntry const *actualSpellInfo = sSpellMgr.SelectAuraRankForPlayerLevel(GetSpellProto(), (*tIter)->getLevel()))
|
||||
if(SpellEntry const *actualSpellInfo = sSpellMgr.SelectAuraRankForLevel(GetSpellProto(), (*tIter)->getLevel()))
|
||||
{
|
||||
int32 actualBasePoints = m_currentBasePoints;
|
||||
// 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)))
|
||||
{
|
||||
// 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);
|
||||
((Player*)target)->GetSession()->SendPacket(&data);
|
||||
return;
|
||||
|
|
@ -3543,7 +3543,11 @@ void Aura::HandleBindSight(bool apply, bool /*Real*/)
|
|||
if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
|
||||
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*/)
|
||||
|
|
@ -3552,7 +3556,11 @@ void Aura::HandleFarSight(bool apply, bool /*Real*/)
|
|||
if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
|
||||
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*/)
|
||||
|
|
@ -3607,10 +3615,12 @@ void Aura::HandleModPossess(bool apply, bool Real)
|
|||
return;
|
||||
|
||||
Player* p_caster = (Player*)caster;
|
||||
|
||||
Camera& camera = p_caster->GetCamera();
|
||||
|
||||
if( apply )
|
||||
{
|
||||
target->addUnitState(UNIT_STAT_CONTROLLED);
|
||||
|
||||
target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
|
||||
|
||||
target->SetCharmerGUID(p_caster->GetGUID());
|
||||
|
|
@ -3618,35 +3628,39 @@ void Aura::HandleModPossess(bool apply, bool Real)
|
|||
|
||||
p_caster->SetCharm(target);
|
||||
|
||||
p_caster->SetFarSightGUID(target->GetGUID());
|
||||
camera.SetView(target);
|
||||
p_caster->SetClientControl(target, 1);
|
||||
p_caster->SetMover(target);
|
||||
|
||||
target->CombatStop();
|
||||
target->CombatStop(true);
|
||||
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)
|
||||
{
|
||||
target->StopMoving();
|
||||
target->GetMotionMaster()->Clear();
|
||||
target->GetMotionMaster()->MoveIdle();
|
||||
((Creature*)target)->AIM_Initialize();
|
||||
}
|
||||
else if(target->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
((Player*)target)->SetClientControl(target, 0);
|
||||
}
|
||||
|
||||
if(CharmInfo *charmInfo = target->InitCharmInfo(target))
|
||||
charmInfo->InitPossessCreateSpells();
|
||||
|
||||
p_caster->PossessSpellInitialize();
|
||||
}
|
||||
else
|
||||
{
|
||||
p_caster->InterruptSpell(CURRENT_CHANNELED_SPELL); // the spell is not automatically canceled when interrupted, do it now
|
||||
p_caster->SetCharm(NULL);
|
||||
|
||||
p_caster->SetFarSightGUID(0);
|
||||
camera.ResetView();
|
||||
p_caster->SetClientControl(target, 0);
|
||||
p_caster->SetMover(NULL);
|
||||
|
||||
|
|
@ -3656,6 +3670,12 @@ void Aura::HandleModPossess(bool apply, bool Real)
|
|||
if(m_removeMode == AURA_REMOVE_BY_DELETE)
|
||||
return;
|
||||
|
||||
target->clearUnitState(UNIT_STAT_CONTROLLED);
|
||||
|
||||
target->CombatStop(true);
|
||||
target->DeleteThreatList();
|
||||
target->getHostileRefManager().deleteReferences();
|
||||
|
||||
target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
|
||||
|
||||
target->SetCharmerGUID(0);
|
||||
|
|
@ -3690,30 +3710,40 @@ void Aura::HandleModPossessPet(bool apply, bool Real)
|
|||
if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
Pet *pet = caster->GetPet();
|
||||
if(!pet || pet != GetTarget())
|
||||
Unit* target = GetTarget();
|
||||
if (target->GetTypeId() != TYPEID_UNIT)
|
||||
return;
|
||||
Creature* pet = (Creature*)target; // not need more stricted type check
|
||||
|
||||
Player* p_caster = (Player*)caster;
|
||||
Camera& camera = p_caster->GetCamera();
|
||||
|
||||
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)
|
||||
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->GetMotionMaster()->Clear();
|
||||
pet->GetMotionMaster()->Clear(false);
|
||||
pet->GetMotionMaster()->MoveIdle();
|
||||
}
|
||||
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->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
|
||||
pet->AddSplineFlag(SPLINEFLAG_WALKMODE);
|
||||
|
|
@ -3758,8 +3788,9 @@ void Aura::HandleModCharm(bool apply, bool Real)
|
|||
target->CastStop(target == caster ? GetId() : 0);
|
||||
caster->SetCharm(target);
|
||||
|
||||
target->CombatStop();
|
||||
target->CombatStop(true);
|
||||
target->DeleteThreatList();
|
||||
target->getHostileRefManager().deleteReferences();
|
||||
|
||||
if(target->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
|
|
@ -3834,6 +3865,10 @@ void Aura::HandleModCharm(bool apply, bool Real)
|
|||
if(caster->GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)caster)->RemovePetActionBar();
|
||||
|
||||
target->CombatStop(true);
|
||||
target->DeleteThreatList();
|
||||
target->getHostileRefManager().deleteReferences();
|
||||
|
||||
if(target->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
((Creature*)target)->AIM_Initialize();
|
||||
|
|
@ -4182,7 +4217,7 @@ void Aura::HandleInvisibilityDetect(bool apply, bool Real)
|
|||
target->m_detectInvisibilityMask |= (1 << m_modifier.m_miscvalue);
|
||||
}
|
||||
if(Real && target->GetTypeId()==TYPEID_PLAYER)
|
||||
((Player*)target)->UpdateVisibilityForPlayer();
|
||||
((Player*)target)->GetCamera().UpdateVisibilityForOwner();
|
||||
}
|
||||
|
||||
void Aura::HandleAuraModRoot(bool apply, bool Real)
|
||||
|
|
@ -4924,16 +4959,6 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)
|
|||
}
|
||||
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:
|
||||
{
|
||||
// Rake
|
||||
|
|
@ -8241,9 +8266,13 @@ void Aura::HandleAuraControlVehicle(bool apply, bool Real)
|
|||
if(!Real)
|
||||
return;
|
||||
|
||||
Unit* target = GetTarget();
|
||||
if (target->GetTypeId() != TYPEID_UNIT || !((Creature*)target)->isVehicle())
|
||||
return;
|
||||
Vehicle* vehicle = (Vehicle*)target;
|
||||
|
||||
Unit *player = GetCaster();
|
||||
Vehicle *vehicle = dynamic_cast<Vehicle*>(GetTarget());
|
||||
if(!player || player->GetTypeId() != TYPEID_PLAYER || !vehicle)
|
||||
if(!player || player->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
if (apply)
|
||||
|
|
|
|||
|
|
@ -4244,7 +4244,8 @@ void Spell::EffectAddFarsight(SpellEffectIndex eff_idx)
|
|||
dynObj->SetUInt32Value(DYNAMICOBJECT_BYTES, 0x80000002);
|
||||
m_caster->AddDynObject(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)
|
||||
|
|
|
|||
|
|
@ -31,13 +31,6 @@
|
|||
|
||||
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 unk_flags; // flags (if 0x02 - some additional data are received)
|
||||
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;
|
||||
|
||||
// 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
|
||||
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 );
|
||||
return;
|
||||
}
|
||||
|
|
@ -57,12 +61,14 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
|
|||
Item *pItem = pUser->GetItemByPos(bagIndex, slot);
|
||||
if (!pItem)
|
||||
{
|
||||
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
|
||||
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL );
|
||||
return;
|
||||
}
|
||||
|
||||
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 );
|
||||
return;
|
||||
}
|
||||
|
|
@ -72,6 +78,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
|
|||
ItemPrototype const *proto = pItem->GetProto();
|
||||
if (!proto)
|
||||
{
|
||||
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
|
||||
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL );
|
||||
return;
|
||||
}
|
||||
|
|
@ -79,6 +86,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
|
|||
// some item classes can be used only in equipped state
|
||||
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 );
|
||||
return;
|
||||
}
|
||||
|
|
@ -86,6 +94,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
|
|||
uint8 msg = pUser->CanUseItem(pItem);
|
||||
if (msg != EQUIP_ERR_OK)
|
||||
{
|
||||
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
|
||||
pUser->SendEquipError( msg, pItem, NULL );
|
||||
return;
|
||||
}
|
||||
|
|
@ -95,6 +104,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
|
|||
!(proto->Flags & ITEM_FLAGS_USEABLE_IN_ARENA) &&
|
||||
pUser->InArena())
|
||||
{
|
||||
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
|
||||
pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH,pItem,NULL);
|
||||
return;
|
||||
}
|
||||
|
|
@ -107,6 +117,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
|
|||
{
|
||||
if (IsNonCombatSpell(spellInfo))
|
||||
{
|
||||
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
|
||||
pUser->SendEquipError(EQUIP_ERR_NOT_IN_COMBAT,pItem,NULL);
|
||||
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)
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
|
@ -174,18 +186,18 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket)
|
|||
{
|
||||
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;
|
||||
|
||||
recvPacket >> 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);
|
||||
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));
|
||||
|
||||
// ignore for remote control state
|
||||
if(_player->m_mover != _player)
|
||||
if (!_player->IsSelfMover())
|
||||
return;
|
||||
|
||||
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));
|
||||
|
||||
// ignore for remote control state
|
||||
if(_player->m_mover != _player)
|
||||
if (!_player->IsSelfMover())
|
||||
return;
|
||||
|
||||
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)
|
||||
|
||||
// ignore for remote control state (for player case)
|
||||
Unit* mover = _player->m_mover;
|
||||
if(mover != _player && mover->GetTypeId()==TYPEID_PLAYER)
|
||||
Unit* mover = _player->GetMover();
|
||||
if (mover != _player && mover->GetTypeId()==TYPEID_PLAYER)
|
||||
{
|
||||
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
|
||||
return;
|
||||
|
|
@ -317,10 +329,10 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
|
|||
return;
|
||||
}
|
||||
|
||||
if(mover->GetTypeId()==TYPEID_PLAYER)
|
||||
if (mover->GetTypeId()==TYPEID_PLAYER)
|
||||
{
|
||||
// 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);
|
||||
//cheater? kick? ban?
|
||||
|
|
@ -331,7 +343,7 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
|
|||
else
|
||||
{
|
||||
// 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?
|
||||
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)
|
||||
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(actualSpellInfo)
|
||||
if (SpellEntry const *actualSpellInfo = sSpellMgr.SelectAuraRankForLevel(spellInfo, target->getLevel()))
|
||||
spellInfo = actualSpellInfo;
|
||||
}
|
||||
|
||||
|
|
@ -380,16 +390,16 @@ void WorldSession::HandleCastSpellOpcode(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;
|
||||
|
||||
recvPacket.read_skip<uint8>(); // counter, increments with every CANCEL packet, don't use for now
|
||||
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
|
||||
if(spellId==26679)
|
||||
return;
|
||||
|
|
@ -410,10 +420,13 @@ void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket)
|
|||
if (spellInfo->Attributes & SPELL_ATTR_CANT_CANCEL)
|
||||
return;
|
||||
|
||||
if(!IsPositiveSpell(spellId))
|
||||
if (IsPassiveSpell(spellInfo))
|
||||
return;
|
||||
|
||||
if (!IsPositiveSpell(spellId))
|
||||
{
|
||||
// ignore for remote control state
|
||||
if (_player->m_mover != _player)
|
||||
if (!_player->IsSelfMover())
|
||||
{
|
||||
// except own aura spells
|
||||
bool allow = false;
|
||||
|
|
@ -450,16 +463,16 @@ void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket)
|
|||
|
||||
void WorldSession::HandlePetCancelAuraOpcode( WorldPacket& recvPacket)
|
||||
{
|
||||
// ignore for remote control state
|
||||
if(_player->m_mover != _player)
|
||||
return;
|
||||
|
||||
uint64 guid;
|
||||
uint32 spellId;
|
||||
|
||||
recvPacket >> guid;
|
||||
recvPacket >> spellId;
|
||||
|
||||
// ignore for remote control state
|
||||
if (!_player->IsSelfMover())
|
||||
return;
|
||||
|
||||
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );
|
||||
if(!spellInfo)
|
||||
{
|
||||
|
|
@ -501,7 +514,7 @@ void WorldSession::HandleCancelAutoRepeatSpellOpcode( WorldPacket& /*recvPacket*
|
|||
{
|
||||
// cancel and prepare for deleting
|
||||
// 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)
|
||||
|
|
@ -509,8 +522,8 @@ void WorldSession::HandleCancelChanneling( WorldPacket & recv_data)
|
|||
recv_data.read_skip<uint32>(); // spellid, not used
|
||||
|
||||
// ignore for remote control state (for player case)
|
||||
Unit* mover = _player->m_mover;
|
||||
if(mover != _player && mover->GetTypeId()==TYPEID_PLAYER)
|
||||
Unit* mover = _player->GetMover();
|
||||
if (mover != _player && mover->GetTypeId()==TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
mover->InterruptSpell(CURRENT_CHANNELED_SPELL);
|
||||
|
|
@ -518,14 +531,14 @@ void WorldSession::HandleCancelChanneling( WorldPacket & recv_data)
|
|||
|
||||
void WorldSession::HandleTotemDestroyed( WorldPacket& recvPacket)
|
||||
{
|
||||
// ignore for remote control state
|
||||
if(_player->m_mover != _player)
|
||||
return;
|
||||
|
||||
uint8 slotId;
|
||||
|
||||
recvPacket >> slotId;
|
||||
|
||||
// ignore for remote control state
|
||||
if (!_player->IsSelfMover())
|
||||
return;
|
||||
|
||||
if (int(slotId) >= MAX_TOTEM_SLOT)
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -283,6 +283,11 @@ bool IsPassiveSpell(uint32 spellId)
|
|||
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId);
|
||||
if (!spellInfo)
|
||||
return false;
|
||||
return IsPassiveSpell(spellInfo);
|
||||
}
|
||||
|
||||
bool IsPassiveSpell(SpellEntry const *spellInfo)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if(IsPassiveSpell(spellInfo->Id)) // ranked passive spell
|
||||
if(IsPassiveSpell(spellInfo)) // ranked passive spell
|
||||
return false;
|
||||
if(spellInfo->powerType != POWER_MANA && spellInfo->powerType != POWER_HEALTH)
|
||||
return false;
|
||||
|
|
@ -2211,37 +2216,44 @@ bool SpellMgr::IsSkillBonusSpell(uint32 spellId) const
|
|||
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
|
||||
if(IsPassiveSpell(spellInfo->Id))
|
||||
// fast case
|
||||
if (level + 10 >= spellInfo->spellLevel)
|
||||
return spellInfo;
|
||||
|
||||
// ignore selection for passive spells
|
||||
if (IsPassiveSpell(spellInfo))
|
||||
return spellInfo;
|
||||
|
||||
bool needRankSelection = false;
|
||||
for(int i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
{
|
||||
if (IsPositiveEffect(spellInfo->Id, SpellEffectIndex(i)) && (
|
||||
spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA ||
|
||||
// for simple aura in check apply to any non caster based targets, in rank search mode to any explicit targets
|
||||
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_RAID))
|
||||
spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_RAID) &&
|
||||
IsPositiveEffect(spellInfo->Id, SpellEffectIndex(i)))
|
||||
{
|
||||
needRankSelection = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// not required
|
||||
if(!needRankSelection)
|
||||
// not required (rank check more slow so check it here)
|
||||
if (!needRankSelection || GetSpellRank(spellInfo->Id) == 0)
|
||||
return spellInfo;
|
||||
|
||||
for(uint32 nextSpellId = spellInfo->Id; nextSpellId != 0; nextSpellId = GetPrevSpellInChain(nextSpellId))
|
||||
{
|
||||
SpellEntry const *nextSpellInfo = sSpellStore.LookupEntry(nextSpellId);
|
||||
if(!nextSpellInfo)
|
||||
if (!nextSpellInfo)
|
||||
break;
|
||||
|
||||
// if found appropriate level
|
||||
if(playerLevel + 10 >= nextSpellInfo->spellLevel)
|
||||
if (level + 10 >= spellInfo->spellLevel)
|
||||
return nextSpellInfo;
|
||||
|
||||
// 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,
|
||||
// pet teaching spells don't must be dependent learning (casted)
|
||||
// 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);
|
||||
|
||||
|
|
@ -3974,4 +3986,4 @@ SpellEntry const* GetSpellEntryByDifficulty(uint32 id, Difficulty difficulty)
|
|||
|
||||
SpellEntry const* spellEntry = sSpellStore.LookupEntry(spellDiff->spellId[difficulty]);
|
||||
return spellEntry;
|
||||
}
|
||||
}
|
||||
|
|
@ -210,10 +210,11 @@ bool IsSingleFromSpellSpecificSpellRanksPerTarget(SpellSpecific spellSpec1,Spell
|
|||
bool IsSingleFromSpellSpecificPerTarget(SpellSpecific spellSpec1,SpellSpecific spellSpec2);
|
||||
|
||||
bool IsPassiveSpell(uint32 spellId);
|
||||
bool IsPassiveSpell(SpellEntry const* spellProto);
|
||||
|
||||
inline bool IsPassiveSpellStackableWithRanks(SpellEntry const* spellProto)
|
||||
{
|
||||
if(!IsPassiveSpell(spellProto->Id))
|
||||
if(!IsPassiveSpell(spellProto))
|
||||
return false;
|
||||
|
||||
return !IsSpellHaveEffect(spellProto,SPELL_EFFECT_APPLY_AURA);
|
||||
|
|
@ -319,6 +320,25 @@ inline bool IsPointEffectTarget( Targets target )
|
|||
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 )
|
||||
{
|
||||
switch (target )
|
||||
|
|
@ -371,12 +391,9 @@ inline bool IsAreaAuraEffect(uint32 effect)
|
|||
|
||||
inline bool IsDispelSpell(SpellEntry const *spellInfo)
|
||||
{
|
||||
if (spellInfo->Effect[EFFECT_INDEX_0] == SPELL_EFFECT_DISPEL ||
|
||||
spellInfo->Effect[EFFECT_INDEX_1] == SPELL_EFFECT_DISPEL ||
|
||||
spellInfo->Effect[EFFECT_INDEX_2] == SPELL_EFFECT_DISPEL )
|
||||
return true;
|
||||
return false;
|
||||
return IsSpellHaveEffect(spellInfo, SPELL_EFFECT_DISPEL);
|
||||
}
|
||||
|
||||
inline bool isSpellBreakStealth(SpellEntry const* spellInfo)
|
||||
{
|
||||
return !(spellInfo->AttributesEx & SPELL_ATTR_EX_NOT_BREAK_STEALTH);
|
||||
|
|
@ -906,7 +923,7 @@ class SpellMgr
|
|||
static bool canStackSpellRanks(SpellEntry const *spellInfo);
|
||||
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
|
||||
SpellLearnSkillNode const* GetSpellLearnSkill(uint32 spell_id) const
|
||||
|
|
@ -1064,4 +1081,4 @@ class SpellMgr
|
|||
};
|
||||
|
||||
#define sSpellMgr SpellMgr::Instance()
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -37,12 +37,17 @@ void TargetedMovementGeneratorMedium<T,D>::_setTargetLocation(T &owner)
|
|||
if (owner.hasUnitState(UNIT_STAT_NOT_MOVE))
|
||||
return;
|
||||
|
||||
float x, y, z;
|
||||
|
||||
// prevent redundant micro-movement for pets, other followers.
|
||||
if (i_offset && i_target->IsWithinDistInMap(&owner,2*i_offset))
|
||||
return;
|
||||
{
|
||||
if (i_destinationHolder.HasDestination())
|
||||
return;
|
||||
|
||||
float x, y, z;
|
||||
if (!i_offset)
|
||||
owner.GetPosition(x, y, z);
|
||||
}
|
||||
else if (!i_offset)
|
||||
{
|
||||
// to nearest contact position
|
||||
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) { Relocation(x, y, z, i_traveller.GetOrientation()); }
|
||||
void MoveTo(float x, float y, float z, uint32 t) {}
|
||||
void Stop() {}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
|
|
@ -102,7 +103,13 @@ inline float Traveller<Creature>::GetMoveDestinationTo(float x, float y, float z
|
|||
template<>
|
||||
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
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
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<Player> PlayerTraveller;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -382,12 +382,7 @@ void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, SplineTy
|
|||
break;
|
||||
}
|
||||
|
||||
data << uint32(flags);
|
||||
|
||||
// enable me if things goes wrong or looks ugly, it is however an old hack
|
||||
// if(flags & SPLINEFLAG_WALKMODE)
|
||||
// moveTime *= 1.05f;
|
||||
|
||||
data << uint32(flags); // splineflags
|
||||
data << uint32(moveTime); // Time in between points
|
||||
data << uint32(1); // 1 single waypoint
|
||||
data << NewPosX << NewPosY << NewPosZ; // the single waypoint Point B
|
||||
|
|
@ -4011,7 +4006,7 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur)
|
|||
SpellEffectIndex effIndex = Aur->GetEffIndex();
|
||||
|
||||
// passive spell special case (only non stackable with ranks)
|
||||
if(IsPassiveSpell(spellId))
|
||||
if(IsPassiveSpell(spellProto))
|
||||
{
|
||||
if(IsPassiveSpellStackableWithRanks(spellProto))
|
||||
return true;
|
||||
|
|
@ -4034,7 +4029,7 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur)
|
|||
uint32 i_spellId = i_spellProto->Id;
|
||||
|
||||
// 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
|
||||
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);
|
||||
|
||||
// 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);
|
||||
|
||||
if (Aur->_RemoveAura())
|
||||
|
|
@ -8549,7 +8557,7 @@ void Unit::CombatStopWithPets(bool includingCast)
|
|||
struct IsAttackingPlayerHelper
|
||||
{
|
||||
explicit IsAttackingPlayerHelper() {}
|
||||
bool operator()(Unit* unit) const { return unit->isAttackingPlayer(); }
|
||||
bool operator()(Unit const* unit) const { return unit->isAttackingPlayer(); }
|
||||
};
|
||||
|
||||
bool Unit::isAttackingPlayer() const
|
||||
|
|
@ -8615,7 +8623,7 @@ void Unit::ModifyAuraState(AuraState flag, bool apply)
|
|||
{
|
||||
if(itr->second.state == PLAYERSPELL_REMOVED) continue;
|
||||
SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first);
|
||||
if (!spellInfo || !IsPassiveSpell(itr->first)) continue;
|
||||
if (!spellInfo || !IsPassiveSpell(spellInfo)) continue;
|
||||
if (spellInfo->CasterAuraState == flag)
|
||||
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)
|
||||
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
|
||||
else if (benefit)
|
||||
|
|
@ -9158,7 +9177,15 @@ uint32 Unit::SpellDamageBonusDone(Unit *pVictim, SpellEntry const *spellProto, u
|
|||
break;
|
||||
}
|
||||
case SPELLFAMILY_WARLOCK:
|
||||
{
|
||||
// Drain Soul
|
||||
if (spellProto->SpellFamilyFlags & UI64LIT(0x0000000000004000))
|
||||
{
|
||||
if (pVictim->GetHealth() * 100 / pVictim->GetMaxHealth() <= 25)
|
||||
DoneTotalMod *= 4;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPELLFAMILY_PRIEST:
|
||||
{
|
||||
// Glyph of Smite
|
||||
|
|
@ -10579,10 +10606,6 @@ bool Unit::isVisibleForOrDetect(Unit const* u, WorldObject const* viewPoint, boo
|
|||
return false;
|
||||
}
|
||||
|
||||
// always seen by far sight caster
|
||||
if (u->GetTypeId()==TYPEID_PLAYER && ((Player*)u)->GetFarSight()==GetGUID())
|
||||
return true;
|
||||
|
||||
// different visible distance checks
|
||||
if (u->isInFlight()) // what see player in flight
|
||||
{
|
||||
|
|
@ -10781,12 +10804,41 @@ void Unit::SetVisibility(UnitVisibility x)
|
|||
|
||||
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();
|
||||
|
||||
if(GetTypeId()==TYPEID_PLAYER)
|
||||
m->PlayerRelocation((Player*)this,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
|
||||
else
|
||||
m->CreatureRelocation((Creature*)this,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
|
||||
|
||||
GetViewPoint().Event_ViewPointVisibilityChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -12039,6 +12091,7 @@ void Unit::RemoveFromWorld()
|
|||
RemoveAllGameObjects();
|
||||
RemoveAllDynObjects();
|
||||
CleanupDeletedAuras();
|
||||
GetViewPoint().Event_RemovedFromWorld();
|
||||
}
|
||||
|
||||
Object::RemoveFromWorld();
|
||||
|
|
@ -12740,9 +12793,13 @@ void Unit::StopMoving()
|
|||
{
|
||||
clearUnitState(UNIT_STAT_MOVING);
|
||||
|
||||
// not need send any packets if not in world
|
||||
if (!IsInWorld())
|
||||
return;
|
||||
|
||||
// send explicit stop packet
|
||||
// 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
|
||||
WorldPacket data;
|
||||
|
|
@ -13710,4 +13767,4 @@ bool Unit::CheckAndIncreaseCastCounter()
|
|||
|
||||
++m_castCounter;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -420,24 +420,25 @@ enum UnitState
|
|||
UNIT_STAT_STUNNED = 0x00000008, // Aura::HandleAuraModStun
|
||||
UNIT_STAT_ROOT = 0x00000010, // Aura::HandleAuraModRoot
|
||||
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)
|
||||
UNIT_STAT_IN_FLIGHT = 0x00000040, // player is in flight mode (in fact interrupted at far teleport until next map telport landing)
|
||||
UNIT_STAT_DISTRACTED = 0x00000080, // DistractedMovementGenerator active
|
||||
UNIT_STAT_IN_FLIGHT = 0x00000080, // player is in flight mode (in fact interrupted at far teleport until next map telport landing)
|
||||
UNIT_STAT_DISTRACTED = 0x00000100, // DistractedMovementGenerator active
|
||||
|
||||
// persistent movement generator state with non-persistent mirror states for stop support
|
||||
// (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
|
||||
UNIT_STAT_CONFUSED = 0x00000100, // ConfusedMovementGenerator active/onstack
|
||||
UNIT_STAT_CONFUSED_MOVE = 0x00000200,
|
||||
UNIT_STAT_ROAMING = 0x00000400, // RandomMovementGenerator/PointMovementGenerator/WaypointMovementGenerator active (now always set)
|
||||
UNIT_STAT_ROAMING_MOVE = 0x00000800,
|
||||
UNIT_STAT_CHASE = 0x00001000, // ChaseMovementGenerator active
|
||||
UNIT_STAT_CHASE_MOVE = 0x00002000,
|
||||
UNIT_STAT_FOLLOW = 0x00004000, // FollowMovementGenerator active
|
||||
UNIT_STAT_FOLLOW_MOVE = 0x00008000,
|
||||
UNIT_STAT_FLEEING = 0x00010000, // FleeMovementGenerator/TimedFleeingMovementGenerator active/onstack
|
||||
UNIT_STAT_FLEEING_MOVE = 0x00020000,
|
||||
UNIT_STAT_CONFUSED = 0x00000200, // ConfusedMovementGenerator active/onstack
|
||||
UNIT_STAT_CONFUSED_MOVE = 0x00000400,
|
||||
UNIT_STAT_ROAMING = 0x00000800, // RandomMovementGenerator/PointMovementGenerator/WaypointMovementGenerator active (now always set)
|
||||
UNIT_STAT_ROAMING_MOVE = 0x00001000,
|
||||
UNIT_STAT_CHASE = 0x00002000, // ChaseMovementGenerator active
|
||||
UNIT_STAT_CHASE_MOVE = 0x00004000,
|
||||
UNIT_STAT_FOLLOW = 0x00008000, // FollowMovementGenerator active
|
||||
UNIT_STAT_FOLLOW_MOVE = 0x00010000,
|
||||
UNIT_STAT_FLEEING = 0x00020000, // FleeMovementGenerator/TimedFleeingMovementGenerator active/onstack
|
||||
UNIT_STAT_FLEEING_MOVE = 0x00040000,
|
||||
|
||||
// masks (only for check)
|
||||
|
||||
|
|
@ -457,6 +458,12 @@ enum UnitState
|
|||
UNIT_STAT_CAN_NOT_REACT = UNIT_STAT_STUNNED | UNIT_STAT_DIED |
|
||||
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)
|
||||
|
||||
// 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>
|
||||
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))
|
||||
return true;
|
||||
|
||||
if (withGuardians)
|
||||
{
|
||||
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))
|
||||
return true;
|
||||
|
||||
|
|
@ -1959,13 +1966,13 @@ bool Unit::CheckAllControlledUnits(Func const& func, bool withTotems, bool withG
|
|||
if (withTotems)
|
||||
{
|
||||
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))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (withCharms)
|
||||
if(Unit* charm = GetCharm())
|
||||
if(Unit const* charm = GetCharm())
|
||||
if (func(charm))
|
||||
return true;
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#include "Common.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "Config/ConfigEnv.h"
|
||||
#include "Config/Config.h"
|
||||
#include "SystemConfig.h"
|
||||
#include "Log.h"
|
||||
#include "Opcodes.h"
|
||||
|
|
@ -402,9 +402,9 @@ Weather* World::AddWeather(uint32 zone_id)
|
|||
/// Initialize config values
|
||||
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());
|
||||
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
|
||||
uint32 confVersion = sConfig.GetIntDefault("ConfVersion", 0);
|
||||
if(!confVersion)
|
||||
if (!confVersion)
|
||||
{
|
||||
sLog.outError("*****************************************************************************");
|
||||
sLog.outError(" WARNING: mangosd.conf does not include a ConfVersion variable.");
|
||||
|
|
@ -1032,7 +1032,7 @@ void World::SetInitialWorldSettings()
|
|||
sLog.outString( "Loading Objects Pooling Data...");
|
||||
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();
|
||||
sGameEventMgr.LoadFromDB();
|
||||
sLog.outString( ">>> Game Event Data loaded" );
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ bool WorldSession::Update(uint32 /*diff*/)
|
|||
packet->GetOpcode());
|
||||
#endif*/
|
||||
|
||||
OpcodeHandler& opHandle = opcodeTable[packet->GetOpcode()];
|
||||
OpcodeHandler const& opHandle = opcodeTable[packet->GetOpcode()];
|
||||
try
|
||||
{
|
||||
switch (opHandle.status)
|
||||
|
|
@ -184,11 +184,8 @@ bool WorldSession::Update(uint32 /*diff*/)
|
|||
LogUnexpectedOpcode(packet, "the player has not logged in yet");
|
||||
}
|
||||
else if(_player->IsInWorld())
|
||||
{
|
||||
(this->*opHandle.handler)(*packet);
|
||||
if (packet->rpos() < packet->wpos() && sLog.HasLogLevelOrHigher(LOG_LVL_DEBUG))
|
||||
LogUnprocessedTail(packet);
|
||||
}
|
||||
ExecuteOpcode(opHandle, packet);
|
||||
|
||||
// lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer
|
||||
break;
|
||||
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");
|
||||
}
|
||||
else
|
||||
{
|
||||
// not expected _player or must checked in packet hanlder
|
||||
(this->*opHandle.handler)(*packet);
|
||||
if (packet->rpos() < packet->wpos() && sLog.HasLogLevelOrHigher(LOG_LVL_DEBUG))
|
||||
LogUnprocessedTail(packet);
|
||||
}
|
||||
ExecuteOpcode(opHandle, packet);
|
||||
break;
|
||||
case STATUS_TRANSFER:
|
||||
if(!_player)
|
||||
|
|
@ -210,11 +203,7 @@ bool WorldSession::Update(uint32 /*diff*/)
|
|||
else if(_player->IsInWorld())
|
||||
LogUnexpectedOpcode(packet, "the player is still in world");
|
||||
else
|
||||
{
|
||||
(this->*opHandle.handler)(*packet);
|
||||
if (packet->rpos() < packet->wpos() && sLog.HasLogLevelOrHigher(LOG_LVL_DEBUG))
|
||||
LogUnprocessedTail(packet);
|
||||
}
|
||||
ExecuteOpcode(opHandle, packet);
|
||||
break;
|
||||
case STATUS_AUTHED:
|
||||
// prevent cheating with skip queue wait
|
||||
|
|
@ -229,9 +218,7 @@ bool WorldSession::Update(uint32 /*diff*/)
|
|||
if (packet->GetOpcode() != CMSG_SET_ACTIVE_VOICE_CHANNEL)
|
||||
m_playerRecentlyLogout = false;
|
||||
|
||||
(this->*opHandle.handler)(*packet);
|
||||
if (packet->rpos() < packet->wpos() && sLog.HasLogLevelOrHigher(LOG_LVL_DEBUG))
|
||||
LogUnprocessedTail(packet);
|
||||
ExecuteOpcode(opHandle, packet);
|
||||
break;
|
||||
case STATUS_NEVER:
|
||||
sLog.outError( "SESSION: received not allowed opcode %s (0x%.4X)",
|
||||
|
|
@ -872,3 +859,27 @@ void WorldSession::SendRedirectClient(std::string& ip, uint16 port)
|
|||
|
||||
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 GMTicket;
|
||||
|
||||
struct OpcodeHandler;
|
||||
|
||||
enum AccountDataType
|
||||
{
|
||||
GLOBAL_CONFIG_CACHE = 0, // 0x01 g
|
||||
|
|
@ -773,6 +775,8 @@ class MANGOS_DLL_SPEC WorldSession
|
|||
// private trade methods
|
||||
void moveItems(Item* myItems[], Item* hisItems[]);
|
||||
|
||||
void ExecuteOpcode( OpcodeHandler const& opHandle, WorldPacket* packet );
|
||||
|
||||
// logging helper
|
||||
void LogUnexpectedOpcode(WorldPacket *packet, const char * reason);
|
||||
void LogUnprocessedTail(WorldPacket *packet);
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
#include "Log.h"
|
||||
#include "Common.h"
|
||||
#include "Config/ConfigEnv.h"
|
||||
#include "Config/Config.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "WorldSocket.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
#include "ScriptCalls.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "WorldSession.h"
|
||||
#include "Config/ConfigEnv.h"
|
||||
#include "Config/Config.h"
|
||||
#include "Util.h"
|
||||
#include "AccountMgr.h"
|
||||
#include "CliRunnable.h"
|
||||
|
|
@ -593,7 +593,7 @@ bool ChatHandler::HandleServerLogLevelCommand(const char *args)
|
|||
{
|
||||
if(!*args)
|
||||
{
|
||||
PSendSysMessage("Log level: %u");
|
||||
PSendSysMessage("Log level: %u", sLog.GetLogLevel());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -629,7 +629,7 @@ void CliRunnable::run()
|
|||
///- Display the list of available CLI functions then beep
|
||||
sLog.outString();
|
||||
|
||||
if(sConfig.GetBoolDefault("BeepAtStart", true))
|
||||
if (sConfig.GetBoolDefault("BeepAtStart", true))
|
||||
printf("\a"); // \a = Alert
|
||||
|
||||
// print this here the first time
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#include "Common.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "Config/ConfigEnv.h"
|
||||
#include "Config/Config.h"
|
||||
#include "Log.h"
|
||||
#include "Master.h"
|
||||
#include "SystemConfig.h"
|
||||
|
|
@ -31,6 +31,7 @@
|
|||
#include <openssl/opensslv.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <ace/Version.h>
|
||||
#include <ace/Get_Opt.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include "ServiceWin32.h"
|
||||
|
|
@ -56,11 +57,11 @@ uint32 realmID; ///< Id of the realm
|
|||
void usage(const char *prog)
|
||||
{
|
||||
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"
|
||||
#ifdef WIN32
|
||||
" 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 uninstall uninstall service\n\r"
|
||||
#endif
|
||||
|
|
@ -75,69 +76,69 @@ extern int main(int argc, char **argv)
|
|||
|
||||
//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;
|
||||
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");
|
||||
usage(argv[0]);
|
||||
return 1;
|
||||
const char *mode = cmd_opts.opt_arg();
|
||||
|
||||
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
|
||||
cfg_file = argv[c];
|
||||
}
|
||||
|
||||
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");
|
||||
#endif
|
||||
case ':':
|
||||
sLog.outError("Runtime-Error: -%c option requires an input argument", cmd_opts.opt_opt());
|
||||
usage(argv[0]);
|
||||
Log::WaitBeforeContinueIfNeed();
|
||||
return 1;
|
||||
}
|
||||
if( strcmp(argv[c],"install") == 0)
|
||||
{
|
||||
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]);
|
||||
default:
|
||||
sLog.outError("Runtime-Error: bad format of commandline arguments");
|
||||
usage(argv[0]);
|
||||
Log::WaitBeforeContinueIfNeed();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if( strcmp(argv[c],"--service") == 0)
|
||||
{
|
||||
WinServiceRun();
|
||||
}
|
||||
////
|
||||
#endif
|
||||
++c;
|
||||
}
|
||||
|
||||
if (!sConfig.SetSource(cfg_file))
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
#include "Timer.h"
|
||||
#include "Policies/SingletonImp.h"
|
||||
#include "SystemConfig.h"
|
||||
#include "Config/ConfigEnv.h"
|
||||
#include "Config/Config.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "CliRunnable.h"
|
||||
#include "RASocket.h"
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
#include "Log.h"
|
||||
#include "RASocket.h"
|
||||
#include "World.h"
|
||||
#include "Config/ConfigEnv.h"
|
||||
#include "Config/Config.h"
|
||||
#include "Util.h"
|
||||
#include "AccountMgr.h"
|
||||
#include "Language.h"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
#####################################
|
||||
# MaNGOS Configuration file #
|
||||
#####################################
|
||||
ConfVersion=2010051901
|
||||
|
||||
[MangosdConf]
|
||||
ConfVersion=2010062001
|
||||
|
||||
###################################################################################################################
|
||||
# CONNECTIONS AND DIRECTORIES
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#include "Common.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "Config/ConfigEnv.h"
|
||||
#include "Config/Config.h"
|
||||
#include "Log.h"
|
||||
#include "RealmList.h"
|
||||
#include "AuthSocket.h"
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
#include "Database/DatabaseEnv.h"
|
||||
#include "RealmList.h"
|
||||
|
||||
#include "Config/ConfigEnv.h"
|
||||
#include "Config/Config.h"
|
||||
#include "Log.h"
|
||||
#include "AuthSocket.h"
|
||||
#include "SystemConfig.h"
|
||||
|
|
@ -35,6 +35,7 @@
|
|||
#include <openssl/opensslv.h>
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
#include <ace/Get_Opt.h>
|
||||
#include <ace/Dev_Poll_Reactor.h>
|
||||
#include <ace/TP_Reactor.h>
|
||||
#include <ace/ACE.h>
|
||||
|
|
@ -67,11 +68,11 @@ DatabaseType loginDatabase; ///< Accessor to the
|
|||
void usage(const char *prog)
|
||||
{
|
||||
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"
|
||||
#ifdef WIN32
|
||||
" 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 uninstall uninstall service\n\r"
|
||||
#endif
|
||||
|
|
@ -81,70 +82,69 @@ void usage(const char *prog)
|
|||
/// Launch the realm server
|
||||
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;
|
||||
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");
|
||||
usage(argv[0]);
|
||||
Log::WaitBeforeContinueIfNeed();
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
cfg_file = argv[c];
|
||||
}
|
||||
const char *mode = cmd_opts.opt_arg();
|
||||
|
||||
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");
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
case ':':
|
||||
sLog.outError("Runtime-Error: -%c option requires an input argument", cmd_opts.opt_opt());
|
||||
usage(argv[0]);
|
||||
Log::WaitBeforeContinueIfNeed();
|
||||
return 1;
|
||||
}
|
||||
if( strcmp(argv[c],"install") == 0)
|
||||
{
|
||||
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]);
|
||||
default:
|
||||
sLog.outError("Runtime-Error: bad format of commandline arguments");
|
||||
usage(argv[0]);
|
||||
Log::WaitBeforeContinueIfNeed();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if( strcmp(argv[c],"--service") == 0)
|
||||
{
|
||||
WinServiceRun();
|
||||
}
|
||||
////
|
||||
#endif
|
||||
++c;
|
||||
}
|
||||
|
||||
if (!sConfig.SetSource(cfg_file))
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
############################################
|
||||
# MaNGOS realmd configuration file #
|
||||
############################################
|
||||
ConfVersion=2007062001
|
||||
|
||||
[RealmdConf]
|
||||
ConfVersion=2010062001
|
||||
|
||||
###################################################################################################################
|
||||
# REALMD SETTINGS
|
||||
|
|
|
|||
|
|
@ -16,13 +16,36 @@
|
|||
* 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"
|
||||
|
||||
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()
|
||||
: mIgnoreCase(true), mConf(NULL)
|
||||
: mConf(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -31,9 +54,8 @@ Config::~Config()
|
|||
delete mConf;
|
||||
}
|
||||
|
||||
bool Config::SetSource(const char *file, bool ignorecase)
|
||||
bool Config::SetSource(const char *file)
|
||||
{
|
||||
mIgnoreCase = ignorecase;
|
||||
mFilename = file;
|
||||
|
||||
return Reload();
|
||||
|
|
@ -42,43 +64,33 @@ bool Config::SetSource(const char *file, bool ignorecase)
|
|||
bool Config::Reload()
|
||||
{
|
||||
delete mConf;
|
||||
mConf = new ACE_Configuration_Heap;
|
||||
|
||||
mConf = new DOTCONFDocument(mIgnoreCase ?
|
||||
DOTCONFDocument::CASEINSENSETIVE :
|
||||
DOTCONFDocument::CASESENSITIVE);
|
||||
|
||||
if (mConf->setContent(mFilename.c_str()) == -1)
|
||||
if (mConf->open() == 0)
|
||||
{
|
||||
delete mConf;
|
||||
mConf = NULL;
|
||||
return false;
|
||||
ACE_Ini_ImpExp config_importer(*mConf);
|
||||
if (config_importer.import_config(mFilename.c_str()) == 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
delete mConf;
|
||||
mConf = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string Config::GetStringDefault(const char* name, const char* def)
|
||||
{
|
||||
if (!mConf)
|
||||
return std::string(def);
|
||||
|
||||
DOTCONFDocumentNode const *node = mConf->findNode(name);
|
||||
if (!node || !node->getValue())
|
||||
return std::string(def);
|
||||
|
||||
return std::string(node->getValue());
|
||||
ACE_TString val;
|
||||
return GetValueHelper(mConf, name, val) ? val.c_str() : def;
|
||||
}
|
||||
|
||||
bool Config::GetBoolDefault(const char* name, bool def)
|
||||
{
|
||||
if (!mConf)
|
||||
ACE_TString val;
|
||||
if (!GetValueHelper(mConf, name, val))
|
||||
return def;
|
||||
|
||||
DOTCONFDocumentNode const *node = mConf->findNode(name);
|
||||
if (!node || !node->getValue())
|
||||
return def;
|
||||
|
||||
const char* str = node->getValue();
|
||||
const char* str = val.c_str();
|
||||
if (strcmp(str, "true") == 0 || strcmp(str, "TRUE") == 0 ||
|
||||
strcmp(str, "yes") == 0 || strcmp(str, "YES") == 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)
|
||||
{
|
||||
if (!mConf)
|
||||
return def;
|
||||
|
||||
DOTCONFDocumentNode const *node = mConf->findNode(name);
|
||||
if (!node || !node->getValue())
|
||||
return def;
|
||||
|
||||
return atoi(node->getValue());
|
||||
ACE_TString val;
|
||||
return GetValueHelper(mConf, name, val) ? atoi(val.c_str()) : def;
|
||||
}
|
||||
|
||||
|
||||
float Config::GetFloatDefault(const char* name, float def)
|
||||
{
|
||||
if (!mConf)
|
||||
return def;
|
||||
|
||||
DOTCONFDocumentNode const *node = mConf->findNode(name);
|
||||
if (!node || !node->getValue())
|
||||
return def;
|
||||
|
||||
return (float)atof(node->getValue());
|
||||
ACE_TString val;
|
||||
return GetValueHelper(mConf, name, val) ? (float)atof(val.c_str()) : def;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,10 +19,11 @@
|
|||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#include "Common.h"
|
||||
#include <Policies/Singleton.h>
|
||||
#include "Platform/Define.h"
|
||||
|
||||
class DOTCONFDocument;
|
||||
class ACE_Configuration_Heap;
|
||||
|
||||
class MANGOS_DLL_SPEC Config
|
||||
{
|
||||
|
|
@ -31,7 +32,7 @@ class MANGOS_DLL_SPEC Config
|
|||
Config();
|
||||
~Config();
|
||||
|
||||
bool SetSource(const char *file, bool ignorecase = true);
|
||||
bool SetSource(const char *file);
|
||||
bool Reload();
|
||||
|
||||
std::string GetStringDefault(const char* name, const char* def);
|
||||
|
|
@ -44,8 +45,7 @@ class MANGOS_DLL_SPEC Config
|
|||
private:
|
||||
|
||||
std::string mFilename;
|
||||
bool mIgnoreCase;
|
||||
DOTCONFDocument *mConf;
|
||||
ACE_Configuration_Heap *mConf;
|
||||
};
|
||||
|
||||
#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
|
||||
|
||||
## 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.
|
||||
# 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
|
||||
|
||||
libmangosconfig_a_SOURCES = \
|
||||
dotconfpp/dotconfpp.cpp \
|
||||
dotconfpp/dotconfpp.h \
|
||||
dotconfpp/mempool.cpp \
|
||||
dotconfpp/mempool.h \
|
||||
Config.cpp \
|
||||
Config.h \
|
||||
ConfigEnv.h
|
||||
|
||||
# VC++ project workspace for dotconfpp
|
||||
EXTRA_DIST = \
|
||||
ConfigLibrary.vcproj
|
||||
Config.h
|
||||
|
|
|
|||
|
|
@ -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 "Config/ConfigEnv.h"
|
||||
#include "Config/Config.h"
|
||||
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
|
|
|
|||
|
|
@ -62,7 +62,6 @@ if (!(CONDITION)) \
|
|||
#define WPWarning(CONDITION) \
|
||||
if (!(CONDITION)) \
|
||||
{ \
|
||||
ACE_Stack_Trace st; \
|
||||
printf("%s:%i: Warning: Assertion in %s failed: %s",\
|
||||
__FILE__, __LINE__, __FUNCTION__, STRINGIZE(CONDITION)); \
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
#include "Common.h"
|
||||
#include "Log.h"
|
||||
#include "Policies/SingletonImp.h"
|
||||
#include "Config/ConfigEnv.h"
|
||||
#include "Config/Config.h"
|
||||
#include "Util.h"
|
||||
#include "ByteBuffer.h"
|
||||
#include "ProgressBar.h"
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ bool WinServiceInstall()
|
|||
if (GetModuleFileName( 0, path, sizeof(path)/sizeof(path[0]) ) > 0)
|
||||
{
|
||||
SC_HANDLE service;
|
||||
std::strcat(path, " --service");
|
||||
std::strcat(path, " -s run");
|
||||
service = CreateService(serviceControlManager,
|
||||
serviceName, // name of service
|
||||
serviceLongName, // service name to display
|
||||
|
|
|
|||
|
|
@ -36,10 +36,10 @@
|
|||
// Format is YYYYMMDDRR where RR is the change in the conf file
|
||||
// for that day.
|
||||
#ifndef _MANGOSDCONFVERSION
|
||||
# define _MANGOSDCONFVERSION 2010051901
|
||||
# define _MANGOSDCONFVERSION 2010062001
|
||||
#endif
|
||||
#ifndef _REALMDCONFVERSION
|
||||
# define _REALMDCONFVERSION 2007062001
|
||||
# define _REALMDCONFVERSION 2010062001
|
||||
#endif
|
||||
|
||||
#if MANGOS_ENDIAN == MANGOS_BIGENDIAN
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "10051"
|
||||
#define REVISION_NR "10091"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#ifndef __REVISION_SQL_H__
|
||||
#define __REVISION_SQL_H__
|
||||
#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"
|
||||
#endif // __REVISION_SQL_H__
|
||||
|
|
|
|||
|
|
@ -370,6 +370,7 @@
|
|||
<ClCompile Include="..\..\src\game\BattleGroundWS.cpp" />
|
||||
<ClCompile Include="..\..\src\game\Calendar.cpp" />
|
||||
<ClCompile Include="..\..\src\game\CalendarHandler.cpp" />
|
||||
<ClCompile Include="..\..\src\game\Camera.cpp" />
|
||||
<ClCompile Include="..\..\src\game\Channel.cpp" />
|
||||
<ClCompile Include="..\..\src\game\ChannelHandler.cpp" />
|
||||
<ClCompile Include="..\..\src\game\ChannelMgr.cpp" />
|
||||
|
|
@ -517,6 +518,7 @@
|
|||
<ClInclude Include="..\..\src\game\BattleGroundSA.h" />
|
||||
<ClInclude Include="..\..\src\game\BattleGroundWS.h" />
|
||||
<ClInclude Include="..\..\src\game\Calendar.h" />
|
||||
<ClInclude Include="..\..\src\game\Camera.h" />
|
||||
<ClInclude Include="..\..\src\game\Cell.h" />
|
||||
<ClInclude Include="..\..\src\game\CellImpl.h" />
|
||||
<ClInclude Include="..\..\src\game\Channel.h" />
|
||||
|
|
|
|||
|
|
@ -442,6 +442,9 @@
|
|||
<ClCompile Include="..\..\src\game\CharacterDatabaseCleaner.cpp">
|
||||
<Filter>Tool</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\game\Camera.cpp">
|
||||
<Filter>Object</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\game\AccountMgr.h">
|
||||
|
|
@ -832,5 +835,8 @@
|
|||
<ClInclude Include="..\..\src\game\CharacterDatabaseCleaner.h">
|
||||
<Filter>Tool</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\game\Camera.h">
|
||||
<Filter>Object</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -437,8 +437,6 @@
|
|||
<ClCompile Include="..\..\src\shared\Auth\Sha1.cpp" />
|
||||
<ClCompile Include="..\..\src\shared\Common.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\DatabaseMysql.cpp" />
|
||||
<ClCompile Include="..\..\src\shared\Database\DBCFileLoader.cpp" />
|
||||
|
|
@ -475,9 +473,6 @@
|
|||
<ClInclude Include="..\..\src\shared\WorldPacket.h" />
|
||||
<ClInclude Include="..\..\src\shared\Common.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\DatabaseEnv.h" />
|
||||
<ClInclude Include="..\..\src\shared\Database\DatabaseImpl.h" />
|
||||
|
|
|
|||
|
|
@ -16,9 +16,6 @@
|
|||
<Filter Include="Config">
|
||||
<UniqueIdentifier>{adb98dec-d22a-40b3-84be-51eaf2974a15}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Config\dotconfpp">
|
||||
<UniqueIdentifier>{dff0e90b-cab5-4d0b-bd5d-3cacbb638630}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Auth">
|
||||
<UniqueIdentifier>{e35fd108-bd39-46ae-83f9-09cf1ebf4ea8}</UniqueIdentifier>
|
||||
</Filter>
|
||||
|
|
@ -66,12 +63,6 @@
|
|||
<ClCompile Include="..\..\src\shared\Config\Config.cpp">
|
||||
<Filter>Config</Filter>
|
||||
</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">
|
||||
<Filter>Auth</Filter>
|
||||
</ClCompile>
|
||||
|
|
@ -194,15 +185,6 @@
|
|||
<ClInclude Include="..\..\src\shared\Config\Config.h">
|
||||
<Filter>Config</Filter>
|
||||
</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">
|
||||
<Filter>Auth</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
|||
|
|
@ -669,6 +669,14 @@
|
|||
RelativePath="..\..\src\game\CalendarHandler.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\game\Camera.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\game\Camera.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\game\Cell.h"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -672,30 +672,6 @@
|
|||
RelativePath="..\..\src\shared\Config\Config.h"
|
||||
>
|
||||
</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
|
||||
Name="Auth"
|
||||
|
|
|
|||
|
|
@ -1162,6 +1162,14 @@
|
|||
RelativePath="..\..\src\game\Calendar.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\game\Camera.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\game\Camera.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
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