mirror of
https://github.com/mangosfour/server.git
synced 2025-12-22 22:37:06 +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
|
|
@ -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__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue