*Improvements in map managing.
--HG-- branch : trunk
This commit is contained in:
1 parent
0db1fd6c26
commit
1d96091d2a
24 files changed
+276
-305
No files matched your search
@@ -1474,6 +1474,8 @@ BattleGround * BattleGroundMgr::GetBattleGroundThroughClientInstance(uint32 inst
|
||||
|
||||
BattleGround * BattleGroundMgr::GetBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId)
|
||||
{
|
||||
if (!InstanceID)
|
||||
return NULL;
|
||||
//search if needed
|
||||
BattleGroundSet::iterator itr;
|
||||
if (bgTypeId == BATTLEGROUND_TYPE_NONE)
|
||||
|
||||
@@ -64,7 +64,7 @@ bool LoginQueryHolder::Initialize()
|
||||
|
||||
// NOTE: all fields in `characters` must be read to prevent lost character data at next save in case wrong DB structure.
|
||||
// !!! NOTE: including unused `zone`,`online`
|
||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADFROM, "SELECT guid, account, data, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags, position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeon_difficulty, arena_pending_points,bgid,bgteam,bgmap,bgx,bgy,bgz,bgo,instance_id FROM characters WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADFROM, "SELECT guid, account, data, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags, position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeon_difficulty, arena_pending_points,instance_id,bgteam,bgmap,bgx,bgy,bgz,bgo FROM characters WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGROUP, "SELECT leaderGuid FROM group_member WHERE memberGuid ='%u'", GUID_LOPART(m_guid));
|
||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADBOUNDINSTANCES, "SELECT id, permanent, map, difficulty, resettime FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADAURAS, "SELECT caster_guid,spell,effect_mask,stackcount,amount0, amount1, amount2 ,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'", GUID_LOPART(m_guid));
|
||||
|
||||
+10
-10
@@ -76,13 +76,12 @@ bool Corpse::Create( uint32 guidlow, Player *owner)
|
||||
{
|
||||
ASSERT(owner);
|
||||
|
||||
WorldObject::_Create(guidlow, HIGHGUID_CORPSE, owner->GetPhaseMask());
|
||||
Relocate(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ(), owner->GetOrientation());
|
||||
|
||||
//we need to assign owner's map for corpse
|
||||
//in other way we will get a crash in Corpse::SaveToDB()
|
||||
SetMap(owner->GetMap());
|
||||
|
||||
Relocate(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ(), owner->GetOrientation());
|
||||
|
||||
if(!IsPositionValid())
|
||||
{
|
||||
sLog.outError("Corpse (guidlow %d, owner %s) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
|
||||
@@ -90,6 +89,8 @@ bool Corpse::Create( uint32 guidlow, Player *owner)
|
||||
return false;
|
||||
}
|
||||
|
||||
WorldObject::_Create(guidlow, HIGHGUID_CORPSE, owner->GetPhaseMask());
|
||||
|
||||
SetFloatValue( OBJECT_FIELD_SCALE_X, 1 );
|
||||
SetUInt64Value( CORPSE_FIELD_OWNER, owner->GetGUID() );
|
||||
|
||||
@@ -149,6 +150,7 @@ void Corpse::DeleteFromDB()
|
||||
CharacterDatabase.PExecute("DELETE FROM corpse WHERE player = '%d' AND corpse_type <> '0'", GUID_LOPART(GetOwnerGUID()));
|
||||
}
|
||||
|
||||
/*
|
||||
bool Corpse::LoadFromDB(uint32 guid, QueryResult *result, uint32 InstanceId)
|
||||
{
|
||||
bool external = (result != NULL);
|
||||
@@ -176,9 +178,9 @@ bool Corpse::LoadFromDB(uint32 guid, QueryResult *result, uint32 InstanceId)
|
||||
delete result;
|
||||
|
||||
return true;
|
||||
}
|
||||
}*/
|
||||
|
||||
bool Corpse::LoadFromDB(uint32 guid, Field *fields)
|
||||
bool Corpse::LoadFromDB(uint32 guid, Field *fields, uint32 & mapId, uint32 & instanceId)
|
||||
{
|
||||
// 0 1 2 3 4 5 6 7 8 9
|
||||
//result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map,data,time,corpse_type,instance,phaseMask FROM corpse WHERE guid = '%u'",guid);
|
||||
@@ -186,7 +188,6 @@ bool Corpse::LoadFromDB(uint32 guid, Field *fields)
|
||||
float positionY = fields[1].GetFloat();
|
||||
float positionZ = fields[2].GetFloat();
|
||||
float ort = fields[3].GetFloat();
|
||||
uint32 mapid = fields[4].GetUInt32();
|
||||
|
||||
Object::_Create(guid, 0, HIGHGUID_CORPSE);
|
||||
|
||||
@@ -196,6 +197,9 @@ bool Corpse::LoadFromDB(uint32 guid, Field *fields)
|
||||
return false;
|
||||
}
|
||||
|
||||
mapId = fields[4].GetUInt32();
|
||||
instanceId = fields[8].GetUInt32();
|
||||
|
||||
m_time = time_t(fields[6].GetUInt64());
|
||||
m_type = CorpseType(fields[7].GetUInt32());
|
||||
|
||||
@@ -205,15 +209,11 @@ bool Corpse::LoadFromDB(uint32 guid, Field *fields)
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 instanceid = fields[8].GetUInt32();
|
||||
uint32 phaseMask = fields[9].GetUInt32();
|
||||
|
||||
// overwrite possible wrong/corrupted guid
|
||||
SetUInt64Value(OBJECT_FIELD_GUID, MAKE_NEW_GUID(guid, 0, HIGHGUID_CORPSE));
|
||||
|
||||
// place
|
||||
SetLocationInstanceId(instanceid);
|
||||
SetLocationMapId(mapid);
|
||||
SetPhaseMask(phaseMask, false);
|
||||
Relocate(positionX, positionY, positionZ, ort);
|
||||
|
||||
|
||||
+2
-2
@@ -61,8 +61,8 @@ class Corpse : public WorldObject
|
||||
bool Create( uint32 guidlow, Player *owner );
|
||||
|
||||
void SaveToDB();
|
||||
bool LoadFromDB(uint32 guid, QueryResult *result, uint32 InstanceId);
|
||||
bool LoadFromDB(uint32 guid, Field *fields);
|
||||
//bool LoadFromDB(uint32 guid, QueryResult *result, uint32 InstanceId);
|
||||
bool LoadFromDB(uint32 guid, Field *fields, uint32 & mapId, uint32 & instanceId);
|
||||
|
||||
void DeleteBonesFromWorld();
|
||||
void DeleteFromDB();
|
||||
|
||||
@@ -691,17 +691,18 @@ void Creature::Motion_Initialize()
|
||||
|
||||
bool Creature::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 team, float x, float y, float z, float ang, const CreatureData *data)
|
||||
{
|
||||
ASSERT(map);
|
||||
SetMap(map);
|
||||
SetPhaseMask(phaseMask,false);
|
||||
|
||||
Relocate(x, y, z, ang);
|
||||
|
||||
if(!IsPositionValid())
|
||||
{
|
||||
sLog.outError("Creature (guidlow %d, entry %d) not loaded. Suggested coordinates isn't valid (X: %f Y: %f)",guidlow,Entry,x,y);
|
||||
return false;
|
||||
}
|
||||
|
||||
ASSERT(map);
|
||||
SetMap(map);
|
||||
SetPhaseMask(phaseMask,false);
|
||||
|
||||
//oX = x; oY = y; dX = x; dY = y; m_moveTime = 0; m_startMove = 0;
|
||||
const bool bResult = CreateFromProto(guidlow, Entry, team, data);
|
||||
|
||||
|
||||
@@ -72,8 +72,8 @@ void DynamicObject::RemoveFromWorld()
|
||||
|
||||
bool DynamicObject::Create( uint32 guidlow, Unit *caster, uint32 spellId, uint32 effIndex, float x, float y, float z, int32 duration, float radius )
|
||||
{
|
||||
WorldObject::_Create(guidlow, HIGHGUID_DYNAMICOBJECT, caster->GetPhaseMask());
|
||||
SetMap(caster->GetMap());
|
||||
|
||||
Relocate(x, y, z, 0);
|
||||
|
||||
if(!IsPositionValid())
|
||||
@@ -82,6 +82,8 @@ bool DynamicObject::Create( uint32 guidlow, Unit *caster, uint32 spellId, uint32
|
||||
return false;
|
||||
}
|
||||
|
||||
WorldObject::_Create(guidlow, HIGHGUID_DYNAMICOBJECT, caster->GetPhaseMask());
|
||||
|
||||
SetEntry(spellId);
|
||||
SetFloatValue( OBJECT_FIELD_SCALE_X, 1 );
|
||||
SetUInt64Value( DYNAMICOBJECT_CASTER, caster->GetGUID() );
|
||||
|
||||
@@ -137,16 +137,17 @@ void GameObject::RemoveFromWorld()
|
||||
bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, GOState go_state, uint32 ArtKit)
|
||||
{
|
||||
ASSERT(map);
|
||||
Relocate(x,y,z,ang);
|
||||
SetMap(map);
|
||||
SetPhaseMask(phaseMask,false);
|
||||
|
||||
Relocate(x,y,z,ang);
|
||||
if(!IsPositionValid())
|
||||
{
|
||||
sLog.outError("Gameobject (GUID: %u Entry: %u ) not created. Suggested coordinates isn't valid (X: %f Y: %f)",guidlow,name_id,x,y);
|
||||
return false;
|
||||
}
|
||||
|
||||
SetPhaseMask(phaseMask,false);
|
||||
|
||||
GameObjectInfo const* goinfo = objmgr.GetGameObjectInfo(name_id);
|
||||
if (!goinfo)
|
||||
{
|
||||
|
||||
+27
-29
@@ -155,7 +155,7 @@ void Map::LoadMap(int gx,int gy, bool reload)
|
||||
//map already load, delete it before reloading (Is it necessary? Do we really need the ability the reload maps during runtime?)
|
||||
if(GridMaps[gx][gy])
|
||||
{
|
||||
sLog.outDetail("Unloading already loaded map %u before reloading.",i_id);
|
||||
sLog.outDetail("Unloading already loaded map %u before reloading.",GetId());
|
||||
delete (GridMaps[gx][gy]);
|
||||
GridMaps[gx][gy]=NULL;
|
||||
}
|
||||
@@ -164,7 +164,7 @@ void Map::LoadMap(int gx,int gy, bool reload)
|
||||
char *tmp=NULL;
|
||||
int len = sWorld.GetDataPath().length()+strlen("maps/%03u%02u%02u.map")+1;
|
||||
tmp = new char[len];
|
||||
snprintf(tmp, len, (char *)(sWorld.GetDataPath()+"maps/%03u%02u%02u.map").c_str(),i_id,gx,gy);
|
||||
snprintf(tmp, len, (char *)(sWorld.GetDataPath()+"maps/%03u%02u%02u.map").c_str(),GetId(),gx,gy);
|
||||
sLog.outDetail("Loading map %s",tmp);
|
||||
// loading data
|
||||
GridMaps[gx][gy] = new GridMap();
|
||||
@@ -199,8 +199,7 @@ void Map::DeleteStateMachine()
|
||||
}
|
||||
|
||||
Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _parent)
|
||||
: i_mapEntry (sMapStore.LookupEntry(id)), i_spawnMode(SpawnMode),
|
||||
i_id(id), i_InstanceId(InstanceId), m_unloadTimer(0),
|
||||
: i_mapEntry (sMapStore.LookupEntry(id)), i_spawnMode(SpawnMode), i_InstanceId(InstanceId), m_unloadTimer(0),
|
||||
m_activeNonPlayersIter(m_activeNonPlayers.end()),
|
||||
i_gridExpiry(expiry), m_parentMap(_parent ? _parent : this)
|
||||
, i_lock(true)
|
||||
@@ -411,7 +410,7 @@ Map::EnsureGridCreated(const GridPair &p)
|
||||
Guard guard(*this);
|
||||
if(!getNGrid(p.x_coord, p.y_coord))
|
||||
{
|
||||
sLog.outDebug("Creating grid[%u,%u] for map %u instance %u", p.x_coord, p.y_coord, i_id, i_InstanceId);
|
||||
sLog.outDebug("Creating grid[%u,%u] for map %u instance %u", p.x_coord, p.y_coord, GetId(), i_InstanceId);
|
||||
|
||||
setNGrid(new NGridType(p.x_coord*MAX_NUMBER_OF_GRIDS + p.y_coord, p.x_coord, p.y_coord, i_gridExpiry, sWorld.getConfig(CONFIG_GRID_UNLOAD)),
|
||||
p.x_coord, p.y_coord);
|
||||
@@ -443,11 +442,11 @@ Map::EnsureGridLoadedAtEnter(const Cell &cell, Player *player)
|
||||
if (player)
|
||||
{
|
||||
player->SendDelayResponse(MAX_GRID_LOAD_TIME);
|
||||
DEBUG_LOG("Player %s enter cell[%u,%u] triggers of loading grid[%u,%u] on map %u", player->GetName(), cell.CellX(), cell.CellY(), cell.GridX(), cell.GridY(), i_id);
|
||||
DEBUG_LOG("Player %s enter cell[%u,%u] triggers of loading grid[%u,%u] on map %u", player->GetName(), cell.CellX(), cell.CellY(), cell.GridX(), cell.GridY(), GetId());
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG("Active object nearby triggers of loading grid [%u,%u] on map %u", cell.GridX(), cell.GridY(), i_id);
|
||||
DEBUG_LOG("Active object nearby triggers of loading grid [%u,%u] on map %u", cell.GridX(), cell.GridY(), GetId());
|
||||
}
|
||||
|
||||
ResetGridExpiry(*getNGrid(cell.GridX(), cell.GridY()), 0.1f);
|
||||
@@ -468,7 +467,7 @@ bool Map::EnsureGridLoaded(const Cell &cell)
|
||||
assert(grid != NULL);
|
||||
if( !isGridObjectDataLoaded(cell.GridX(), cell.GridY()) )
|
||||
{
|
||||
sLog.outDebug("Loading grid[%u,%u] for map %u instance %u", cell.GridX(), cell.GridY(), i_id, i_InstanceId);
|
||||
sLog.outDebug("Loading grid[%u,%u] for map %u instance %u", cell.GridX(), cell.GridY(), GetId(), i_InstanceId);
|
||||
|
||||
ObjectGridLoader loader(*grid, this, cell);
|
||||
loader.LoadN();
|
||||
@@ -492,9 +491,8 @@ void Map::LoadGrid(float x, float y)
|
||||
|
||||
bool Map::Add(Player *player)
|
||||
{
|
||||
player->GetMapRef().link(this, player);
|
||||
player->SetMap(this);
|
||||
|
||||
// Check if we are adding to correct map
|
||||
assert (player->GetMap() == this);
|
||||
// update player state for other player and visa-versa
|
||||
CellPair p = Trinity::ComputeCellPair(player->GetPositionX(), player->GetPositionY());
|
||||
Cell cell(p);
|
||||
@@ -812,14 +810,6 @@ void Map::Update(const uint32 &t_diff)
|
||||
|
||||
void Map::Remove(Player *player, bool remove)
|
||||
{
|
||||
// this may be called during Map::Update
|
||||
// after decrement+unlink, ++m_mapRefIter will continue correctly
|
||||
// when the first element of the list is being removed
|
||||
// nocheck_prev will return the padding element of the RefManager
|
||||
// instead of NULL in the case of prev
|
||||
if(m_mapRefIter == player->GetMapRef())
|
||||
m_mapRefIter = m_mapRefIter->nocheck_prev();
|
||||
player->GetMapRef().unlink();
|
||||
CellPair p = Trinity::ComputeCellPair(player->GetPositionX(), player->GetPositionY());
|
||||
if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
|
||||
{
|
||||
@@ -857,7 +847,6 @@ void Map::Remove(Player *player, bool remove)
|
||||
SendRemoveTransports(player);
|
||||
UpdateObjectVisibility(player,cell,p);
|
||||
|
||||
player->ResetMap();
|
||||
if( remove )
|
||||
DeleteFromWorld(player);
|
||||
}
|
||||
@@ -1152,7 +1141,7 @@ bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool unloadAll)
|
||||
if(!unloadAll && ActiveObjectsNearGrid(x, y) )
|
||||
return false;
|
||||
|
||||
sLog.outDebug("Unloading grid[%u,%u] for map %u", x,y, i_id);
|
||||
sLog.outDebug("Unloading grid[%u,%u] for map %u", x,y, GetId());
|
||||
|
||||
ObjectGridUnloader unloader(*grid);
|
||||
|
||||
@@ -1202,7 +1191,7 @@ bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool unloadAll)
|
||||
|
||||
GridMaps[gx][gy] = NULL;
|
||||
}
|
||||
DEBUG_LOG("Unloading grid[%u,%u] for map %u finished", x,y, i_id);
|
||||
DEBUG_LOG("Unloading grid[%u,%u] for map %u finished", x,y, GetId());
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1824,7 +1813,7 @@ uint16 Map::GetAreaFlag(float x, float y, float z) const
|
||||
areaflag = gmap->getArea(x, y);
|
||||
// this used while not all *.map files generated (instances)
|
||||
else
|
||||
areaflag = GetAreaFlagByMapId(i_id);
|
||||
areaflag = GetAreaFlagByMapId(GetId());
|
||||
|
||||
//FIXME: some hacks for areas above or underground for ground area
|
||||
// required for area specific spells/etc, until map/vmap data
|
||||
@@ -2129,7 +2118,7 @@ void Map::SendInitTransports( Player * player )
|
||||
for (MapManager::TransportSet::const_iterator i = tset.begin(); i != tset.end(); ++i)
|
||||
{
|
||||
// send data for current transport in other place
|
||||
if((*i) != player->GetTransport() && (*i)->GetMapId()==i_id)
|
||||
if((*i) != player->GetTransport() && (*i)->GetMapId()==GetId())
|
||||
{
|
||||
(*i)->BuildCreateUpdateBlockForPlayer(&transData, player);
|
||||
}
|
||||
@@ -2155,7 +2144,7 @@ void Map::SendRemoveTransports( Player * player )
|
||||
|
||||
// except used transport
|
||||
for (MapManager::TransportSet::const_iterator i = tset.begin(); i != tset.end(); ++i)
|
||||
if((*i) != player->GetTransport() && (*i)->GetMapId()!=i_id)
|
||||
if((*i) != player->GetTransport() && (*i)->GetMapId()!=GetId())
|
||||
(*i)->BuildOutOfRangeUpdateBlock(&transData);
|
||||
|
||||
WorldPacket packet;
|
||||
@@ -2422,8 +2411,9 @@ bool InstanceMap::Add(Player *player)
|
||||
|
||||
{
|
||||
Guard guard(*this);
|
||||
if(!CanEnter(player))
|
||||
return false;
|
||||
// Check moved to void WorldSession::HandleMoveWorldportAckOpcode()
|
||||
//if(!CanEnter(player))
|
||||
//return false;
|
||||
|
||||
// Dungeon only code
|
||||
if(IsDungeon())
|
||||
@@ -2726,8 +2716,9 @@ bool BattleGroundMap::Add(Player * player)
|
||||
{
|
||||
{
|
||||
Guard guard(*this);
|
||||
if(!CanEnter(player))
|
||||
return false;
|
||||
//Check moved to void WorldSession::HandleMoveWorldportAckOpcode()
|
||||
//if(!CanEnter(player))
|
||||
//return false;
|
||||
// reset instance validity, battleground maps do not homebind
|
||||
player->m_InstanceValid = true;
|
||||
}
|
||||
@@ -3638,3 +3629,10 @@ Map::GetDynamicObject(uint64 guid)
|
||||
return NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Map::UpdateIteratorBack(Player *player)
|
||||
{
|
||||
if(m_mapRefIter == player->GetMapRef())
|
||||
m_mapRefIter = m_mapRefIter->nocheck_prev();
|
||||
}
|
||||
|
||||
+7
-5
@@ -46,6 +46,7 @@ class InstanceSave;
|
||||
class Object;
|
||||
class WorldObject;
|
||||
class TempSummon;
|
||||
class Player;
|
||||
class CreatureGroup;
|
||||
struct ScriptInfo;
|
||||
struct ScriptAction;
|
||||
@@ -309,7 +310,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
|
||||
}
|
||||
|
||||
time_t GetGridExpiry(void) const { return i_gridExpiry; }
|
||||
uint32 GetId(void) const { return i_id; }
|
||||
uint32 GetId(void) const { return i_mapEntry->MapID; }
|
||||
|
||||
static bool ExistMap(uint32 mapid, int gx, int gy);
|
||||
static bool ExistVMap(uint32 mapid, int gx, int gy);
|
||||
@@ -338,17 +339,17 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
|
||||
|
||||
uint32 GetAreaId(float x, float y, float z) const
|
||||
{
|
||||
return GetAreaIdByAreaFlag(GetAreaFlag(x,y,z),i_id);
|
||||
return GetAreaIdByAreaFlag(GetAreaFlag(x,y,z),GetId());
|
||||
}
|
||||
|
||||
uint32 GetZoneId(float x, float y, float z) const
|
||||
{
|
||||
return GetZoneIdByAreaFlag(GetAreaFlag(x,y,z),i_id);
|
||||
return GetZoneIdByAreaFlag(GetAreaFlag(x,y,z),GetId());
|
||||
}
|
||||
|
||||
void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, float x, float y, float z) const
|
||||
{
|
||||
GetZoneAndAreaIdByAreaFlag(zoneid,areaid,GetAreaFlag(x,y,z),i_id);
|
||||
GetZoneAndAreaIdByAreaFlag(zoneid,areaid,GetAreaFlag(x,y,z),GetId());
|
||||
}
|
||||
|
||||
virtual void MoveAllCreaturesInMoveList();
|
||||
@@ -431,6 +432,8 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
|
||||
template<class NOTIFIER> void VisitGrid(const float &x, const float &y, float radius, NOTIFIER ¬ifier);
|
||||
CreatureGroupHolderType CreatureGroupHolder;
|
||||
|
||||
void UpdateIteratorBack(Player *player);
|
||||
|
||||
#ifdef MAP_BASED_RAND_GEN
|
||||
MTRand mtRand;
|
||||
int32 irand(int32 min, int32 max) { return int32 (mtRand.randInt(max - min)) + min; }
|
||||
@@ -492,7 +495,6 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
|
||||
|
||||
MapEntry const* i_mapEntry;
|
||||
uint8 i_spawnMode;
|
||||
uint32 i_id;
|
||||
uint32 i_InstanceId;
|
||||
uint32 m_unloadTimer;
|
||||
|
||||
|
||||
@@ -116,27 +116,16 @@ void MapInstanced::UnloadAll()
|
||||
- create the instance if it's not created already
|
||||
- the player is not actually added to the instance (only in InstanceMap::Add)
|
||||
*/
|
||||
Map* MapInstanced::CreateInstance(const uint32 mapId, Player * player)
|
||||
Map* MapInstanced::CreateInstance(const uint32 mapId, Player * player, uint32 instanceId)
|
||||
{
|
||||
uint32 instanceId = player->GetInstanceId();
|
||||
|
||||
if(instanceId)
|
||||
if(Map *map = _FindMap(instanceId))
|
||||
return map;
|
||||
|
||||
if(IsBattleGroundOrArena())
|
||||
{
|
||||
instanceId = player->GetBattleGroundId();
|
||||
|
||||
if(instanceId)
|
||||
{
|
||||
if(Map *map = _FindMap(instanceId))
|
||||
return map;
|
||||
else
|
||||
return CreateBattleGround(instanceId);
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
assert(player->GetBattleGroundId());
|
||||
return CreateBattleGround(player->GetBattleGroundId());
|
||||
}
|
||||
|
||||
if(InstanceSave *pSave = player->GetInstanceSave(GetId()))
|
||||
|
||||
@@ -42,7 +42,7 @@ class TRINITY_DLL_DECL MapInstanced : public Map
|
||||
void UnloadAll();
|
||||
bool CanEnter(Player* player);
|
||||
|
||||
Map* CreateInstance(const uint32 mapId, Player * player);
|
||||
Map* CreateInstance(const uint32 mapId, Player * player, uint32 instanceId);
|
||||
Map* FindMap(uint32 InstanceId) const { return _FindMap(InstanceId); }
|
||||
void DestroyInstance(uint32 InstanceId);
|
||||
void DestroyInstance(InstancedMaps::iterator &itr);
|
||||
|
||||
@@ -128,13 +128,13 @@ MapManager::_createBaseMap(uint32 id)
|
||||
return m;
|
||||
}
|
||||
|
||||
Map* MapManager::CreateMap(uint32 id, const WorldObject* obj)
|
||||
Map* MapManager::CreateMap(uint32 id, const WorldObject* obj, uint32 instanceId)
|
||||
{
|
||||
ASSERT(obj);
|
||||
//if(!obj->IsInWorld()) sLog.outError("GetMap: called for map %d with object (typeid %d, guid %d, mapid %d, instanceid %d) who is not in world!", id, obj->GetTypeId(), obj->GetGUIDLow(), obj->GetMapId(), obj->GetInstanceId());
|
||||
Map *m = _createBaseMap(id);
|
||||
|
||||
if (m && (obj->GetTypeId() == TYPEID_PLAYER) && m->Instanceable()) m = ((MapInstanced*)m)->CreateInstance(id, (Player*)obj);
|
||||
if (m && (obj->GetTypeId() == TYPEID_PLAYER) && m->Instanceable()) m = ((MapInstanced*)m)->CreateInstance(id, (Player*)obj, instanceId);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton<MapManager, MaNGOS::
|
||||
|
||||
public:
|
||||
|
||||
Map* CreateMap(uint32, const WorldObject* obj);
|
||||
Map* CreateMap(uint32, const WorldObject* obj, uint32 instanceId);
|
||||
Map const* CreateBaseMap(uint32 id) const { return const_cast<MapManager*>(this)->_createBaseMap(id); }
|
||||
Map* FindMap(uint32 mapid, uint32 instanceId = 0) const;
|
||||
|
||||
|
||||
@@ -66,13 +66,17 @@ void WorldSession::HandleMoveWorldportAckOpcode()
|
||||
|
||||
GetPlayer()->SetSemaphoreTeleportFar(false);
|
||||
|
||||
GetPlayer()->ResetMap();
|
||||
|
||||
// relocate the player to the teleport destination
|
||||
Map * newMap = MapManager::Instance().CreateMap(loc.mapid, GetPlayer());
|
||||
if (!newMap)
|
||||
Map * newMap = MapManager::Instance().CreateMap(loc.mapid, GetPlayer(), 0);
|
||||
// the CanEnter checks are done in TeleporTo but conditions may change
|
||||
// while the player is in transit, for example the map may get full
|
||||
if (!newMap->CanEnter(GetPlayer()))
|
||||
{
|
||||
sLog.outError("Map %d could not be created for player %d, porting player to homebind", loc.mapid, GetPlayer()->GetGUIDLow());
|
||||
GetPlayer()->RelocateToHomebind();
|
||||
newMap = MapManager::Instance().CreateMap(GetPlayer()->GetMapId(), GetPlayer());
|
||||
GetPlayer()->RelocateToHomebind(loc.mapid);
|
||||
newMap = MapManager::Instance().CreateMap(loc.mapid, GetPlayer(), 0);
|
||||
}
|
||||
else
|
||||
GetPlayer()->Relocate(loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation);
|
||||
@@ -80,22 +84,10 @@ void WorldSession::HandleMoveWorldportAckOpcode()
|
||||
GetPlayer()->SetMap(newMap);
|
||||
|
||||
GetPlayer()->SendInitialPacketsBeforeAddToMap();
|
||||
// the CanEnter checks are done in TeleporTo but conditions may change
|
||||
// while the player is in transit, for example the map may get full
|
||||
if(!GetPlayer()->GetMap()->Add(GetPlayer()))
|
||||
{
|
||||
//if player wasn't added to map, reset his map pointer!
|
||||
GetPlayer()->ResetMap();
|
||||
|
||||
sLog.outDebug("WORLD: teleport of player %s (%d) to location %d, %f, %f, %f, %f failed", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation);
|
||||
// teleport the player home
|
||||
if(!GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation()))
|
||||
{
|
||||
// the player must always be able to teleport home
|
||||
sLog.outError("WORLD: failed to teleport player %s (%d) to homebind location %d, %f, %f, %f, %f!", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation());
|
||||
assert(false);
|
||||
}
|
||||
return;
|
||||
sLog.outError("WORLD: failed to teleport player %s (%d) to map %d because of unknown reason!", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), loc.mapid);
|
||||
assert(false);
|
||||
}
|
||||
|
||||
// battleground state prepare (in case join to BG), at relogin/tele player not invited
|
||||
|
||||
+2
-4
@@ -1066,7 +1066,7 @@ bool Object::PrintIndexError(uint32 index, bool set) const
|
||||
}
|
||||
|
||||
WorldObject::WorldObject()
|
||||
: m_mapId(0), m_InstanceId(0), m_phaseMask(PHASEMASK_NORMAL),
|
||||
: m_phaseMask(PHASEMASK_NORMAL),
|
||||
m_positionX(0.0f), m_positionY(0.0f), m_positionZ(0.0f), m_orientation(0.0f), m_currMap(NULL)
|
||||
, m_zoneScript(NULL)
|
||||
, m_isActive(false), IsTempWorldObject(false)
|
||||
@@ -1691,11 +1691,9 @@ void WorldObject::SendObjectDeSpawnAnim(uint64 guid)
|
||||
|
||||
void WorldObject::SetMap(Map * map)
|
||||
{
|
||||
assert (!m_currMap);
|
||||
ASSERT(map);
|
||||
m_currMap = map;
|
||||
//lets save current map's Id/instanceId
|
||||
m_mapId = map->GetId();
|
||||
m_InstanceId = map->GetInstanceId();
|
||||
}
|
||||
|
||||
Map const* WorldObject::GetBaseMap() const
|
||||
|
||||
+10
-20
@@ -407,7 +407,7 @@ class TRINITY_DLL_SPEC WorldObject : public Object
|
||||
void GetPosition( float &x, float &y, float &z ) const
|
||||
{ x = m_positionX; y = m_positionY; z = m_positionZ; }
|
||||
void GetPosition( WorldLocation &loc ) const
|
||||
{ loc.mapid = m_mapId; GetPosition(loc.coord_x, loc.coord_y, loc.coord_z); loc.orientation = GetOrientation(); }
|
||||
{ loc.mapid = GetMapId(); GetPosition(loc.coord_x, loc.coord_y, loc.coord_z); loc.orientation = GetOrientation(); }
|
||||
void GetPosition(Position pos) const
|
||||
{ pos[0] = m_positionX; pos[1] = m_positionY; pos[2] = m_positionZ; pos[3] = m_orientation; }
|
||||
float GetOrientation( ) const { return m_orientation; }
|
||||
@@ -439,8 +439,8 @@ class TRINITY_DLL_SPEC WorldObject : public Object
|
||||
|
||||
void GetRandomPoint( float x, float y, float z, float distance, float &rand_x, float &rand_y, float &rand_z ) const;
|
||||
|
||||
uint32 GetMapId() const { return m_mapId; }
|
||||
uint32 GetInstanceId() const { return m_InstanceId; }
|
||||
uint32 GetMapId() const { return m_currMap ? m_currMap->GetId() : 0; }
|
||||
uint32 GetInstanceId() const { return m_currMap ? m_currMap->GetInstanceId() : 0; }
|
||||
|
||||
virtual void SetPhaseMask(uint32 newPhaseMask, bool update);
|
||||
uint32 GetPhaseMask() const { return m_phaseMask; }
|
||||
@@ -528,11 +528,11 @@ class TRINITY_DLL_SPEC WorldObject : public Object
|
||||
// Low Level Packets
|
||||
void SendPlaySound(uint32 Sound, bool OnlySelf);
|
||||
|
||||
void SetMap(Map * map);
|
||||
virtual void SetMap(Map * map);
|
||||
Map * GetMap() const { ASSERT(m_currMap); return m_currMap; }
|
||||
Map * FindMap() const { return m_currMap; }
|
||||
//used to check all object's GetMap() calls when object is not in world!
|
||||
void ResetMap() { m_currMap = NULL; }
|
||||
virtual void ResetMap() { assert(m_currMap); m_currMap = NULL; }
|
||||
|
||||
//this function should be removed in nearest time...
|
||||
Map const* GetBaseMap() const;
|
||||
@@ -560,12 +560,11 @@ class TRINITY_DLL_SPEC WorldObject : public Object
|
||||
bool IsTempWorldObject;
|
||||
|
||||
#ifdef MAP_BASED_RAND_GEN
|
||||
// Object may not have map assigned - use global scope rand in that case
|
||||
int32 irand(int32 min, int32 max) const { return FindMap() ? int32 (GetMap()->mtRand.randInt(max - min)) + min : ::irand(min, max); }
|
||||
uint32 urand(uint32 min, uint32 max) const { return FindMap() ? GetMap()->mtRand.randInt(max - min) + min : ::urand(min, max); }
|
||||
int32 rand32() const { return FindMap() ? GetMap()->mtRand.randInt(): ::rand32(); }
|
||||
double rand_norm() const { return FindMap() ? GetMap()->mtRand.randExc(): ::rand_norm(); }
|
||||
double rand_chance() const { return FindMap() ? GetMap()->mtRand.randExc(100.0): ::rand_chance(); }
|
||||
int32 irand(int32 min, int32 max) const { int32 (GetMap()->mtRand.randInt(max - min)) + min; }
|
||||
uint32 urand(uint32 min, uint32 max) const { GetMap()->mtRand.randInt(max - min) + min}
|
||||
int32 rand32() const { GetMap()->mtRand.randInt()}
|
||||
double rand_norm() const { GetMap()->mtRand.randExc()}
|
||||
double rand_chance() const { GetMap()->mtRand.randExc(100.0)}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
@@ -574,17 +573,8 @@ class TRINITY_DLL_SPEC WorldObject : public Object
|
||||
bool m_isActive;
|
||||
ZoneScript *m_zoneScript;
|
||||
|
||||
//these functions are used mostly for Relocate() and Corpse/Player specific stuff...
|
||||
//use them ONLY in LoadFromDB()/Create() funcs and nowhere else!
|
||||
//mapId/instanceId should be set in SetMap() function!
|
||||
void SetLocationMapId(uint32 _mapId) { m_mapId = _mapId; }
|
||||
void SetLocationInstanceId(uint32 _instanceId) { m_InstanceId = _instanceId; }
|
||||
|
||||
private:
|
||||
Map * m_currMap; //current object's Map location
|
||||
|
||||
uint32 m_mapId; // object at map with map_id
|
||||
uint32 m_InstanceId; // in map copy with instance id
|
||||
uint32 m_phaseMask; // in area phase state
|
||||
|
||||
float m_positionX;
|
||||
|
||||
@@ -268,7 +268,7 @@ ObjectAccessor::RemoveCorpse(Corpse *corpse)
|
||||
}
|
||||
|
||||
void
|
||||
ObjectAccessor::AddCorpse(Corpse *corpse)
|
||||
ObjectAccessor::AddCorpse(Corpse *corpse, uint32 mapId, uint32 instanceId)
|
||||
{
|
||||
assert(corpse && corpse->GetType() != CORPSE_BONES);
|
||||
|
||||
@@ -280,7 +280,7 @@ ObjectAccessor::AddCorpse(Corpse *corpse)
|
||||
CellPair cell_pair = Trinity::ComputeCellPair(corpse->GetPositionX(), corpse->GetPositionY());
|
||||
uint32 cell_id = (cell_pair.y_coord*TOTAL_NUMBER_OF_CELLS_PER_MAP) + cell_pair.x_coord;
|
||||
|
||||
objmgr.AddCorpseCellData(corpse->GetMapId(), cell_id, corpse->GetOwnerGUID(), corpse->GetInstanceId());
|
||||
objmgr.AddCorpseCellData(mapId, cell_id, corpse->GetOwnerGUID(), instanceId);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -210,7 +210,7 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
|
||||
|
||||
Corpse* GetCorpseForPlayerGUID(uint64 guid);
|
||||
void RemoveCorpse(Corpse *corpse);
|
||||
void AddCorpse(Corpse* corpse);
|
||||
void AddCorpse(Corpse *corpse, uint32 mapId, uint32 instanceId);
|
||||
void AddCorpsesToGrid(GridPair const& gridpair,GridType& grid,Map* map);
|
||||
Corpse* ConvertCorpseForPlayer(uint64 player_guid, bool insignia = false);
|
||||
|
||||
|
||||
@@ -6483,14 +6483,16 @@ void ObjectMgr::LoadCorpses()
|
||||
|
||||
uint32 guid = fields[result->GetFieldCount()-1].GetUInt32();
|
||||
|
||||
uint32 mapId;
|
||||
uint32 instanceId;
|
||||
Corpse *corpse = new Corpse;
|
||||
if(!corpse->LoadFromDB(guid,fields))
|
||||
if(!corpse->LoadFromDB(guid,fields,mapId,instanceId))
|
||||
{
|
||||
delete corpse;
|
||||
continue;
|
||||
}
|
||||
|
||||
ObjectAccessor::Instance().AddCorpse(corpse);
|
||||
ObjectAccessor::Instance().AddCorpse(corpse,mapId,instanceId);
|
||||
|
||||
++count;
|
||||
}
|
||||
|
||||
+2
-1
@@ -1778,9 +1778,10 @@ bool Pet::IsPermanentPetFor(Player* owner)
|
||||
|
||||
bool Pet::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 pet_number)
|
||||
{
|
||||
assert(map);
|
||||
SetMap(map);
|
||||
SetPhaseMask(phaseMask,false);
|
||||
|
||||
SetPhaseMask(phaseMask,false);
|
||||
Object::_Create(guidlow, pet_number, HIGHGUID_PET);
|
||||
|
||||
m_DBTableGuid = guidlow;
|
||||
|
||||
+166
-180
@@ -316,10 +316,6 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa
|
||||
|
||||
m_nextSave = sWorld.getConfig(CONFIG_INTERVAL_SAVE);
|
||||
|
||||
// randomize first save time in range [CONFIG_INTERVAL_SAVE] around [CONFIG_INTERVAL_SAVE]
|
||||
// this must help in case next save after mass player load after server startup
|
||||
m_nextSave = urand(m_nextSave/2,m_nextSave*3/2);
|
||||
|
||||
clearResurrectRequestData();
|
||||
|
||||
memset(m_items, 0, sizeof(Item*)*PLAYER_SLOTS_COUNT);
|
||||
@@ -485,6 +481,10 @@ Player::~Player ()
|
||||
// it must be unloaded already in PlayerLogout and accessed only for loggined player
|
||||
//m_social = NULL;
|
||||
|
||||
// Remove reference to map if still exists
|
||||
if (FindMap())
|
||||
ResetMap();
|
||||
|
||||
// Note: buy back item already deleted from DB when player was saved
|
||||
for(uint8 i = 0; i < PLAYER_SLOTS_COUNT; ++i)
|
||||
{
|
||||
@@ -548,7 +548,6 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
|
||||
for (uint8 i = 0; i < PLAYER_SLOTS_COUNT; i++)
|
||||
m_items[i] = NULL;
|
||||
|
||||
SetLocationMapId(info->mapId);
|
||||
Relocate(info->positionX,info->positionY,info->positionZ);
|
||||
|
||||
ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(class_);
|
||||
@@ -558,7 +557,7 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
|
||||
return false;
|
||||
}
|
||||
|
||||
SetMap(MapManager::Instance().CreateMap(info->mapId, this));
|
||||
SetMap(MapManager::Instance().CreateMap(info->mapId, this, 0));
|
||||
|
||||
uint8 powertype = cEntry->powerType;
|
||||
|
||||
@@ -4360,7 +4359,7 @@ void Player::CreateCorpse()
|
||||
corpse->SaveToDB();
|
||||
|
||||
// register for player, but not show
|
||||
ObjectAccessor::Instance().AddCorpse(corpse);
|
||||
ObjectAccessor::Instance().AddCorpse(corpse, corpse->GetMapId(), corpse->GetInstanceId());
|
||||
}
|
||||
|
||||
void Player::SpawnCorpseBones()
|
||||
@@ -14253,7 +14252,12 @@ bool Player::MinimalLoadFromDB( QueryResult *result, uint32 guid )
|
||||
m_name = fields[2].GetCppString();
|
||||
|
||||
Relocate(fields[3].GetFloat(),fields[4].GetFloat(),fields[5].GetFloat());
|
||||
SetLocationMapId(fields[6].GetUInt32());
|
||||
Map *map = MapManager::Instance().CreateMap(fields[6].GetUInt32(), this, 0);
|
||||
SetMap(map);
|
||||
|
||||
// randomize first save time in range [CONFIG_INTERVAL_SAVE] around [CONFIG_INTERVAL_SAVE]
|
||||
// this must help in case next save after mass player load after server startup
|
||||
m_nextSave = urand(m_nextSave/2,m_nextSave*3/2);
|
||||
|
||||
// the instance id is not needed at character enum
|
||||
|
||||
@@ -14560,14 +14564,8 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
||||
|
||||
InitPrimaryProfessions(); // to max set before any spell loaded
|
||||
|
||||
// init saved position, and fix it later if problematic
|
||||
uint32 transGUID = fields[31].GetUInt32();
|
||||
Relocate(fields[13].GetFloat(),fields[14].GetFloat(),fields[15].GetFloat(),fields[17].GetFloat());
|
||||
SetLocationMapId(fields[16].GetUInt32());
|
||||
SetDifficulty(fields[39].GetUInt32()); // may be changed in _LoadGroup
|
||||
|
||||
SetLocationInstanceId(fields[47].GetFloat());
|
||||
|
||||
_LoadGroup(holder->GetResult(PLAYER_LOGIN_QUERY_LOADGROUP));
|
||||
|
||||
_LoadArenaTeamInfo(holder->GetResult(PLAYER_LOGIN_QUERY_LOADARENAINFO));
|
||||
@@ -14596,35 +14594,42 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
||||
|
||||
_LoadBoundInstances(holder->GetResult(PLAYER_LOGIN_QUERY_LOADBOUNDINSTANCES));
|
||||
|
||||
// load player map related values
|
||||
uint32 transGUID = fields[31].GetUInt32();
|
||||
Relocate(fields[13].GetFloat(),fields[14].GetFloat(),fields[15].GetFloat(),fields[17].GetFloat());
|
||||
uint32 mapId = fields[16].GetUInt32();
|
||||
uint32 instanceId = fields[41].GetFloat();
|
||||
std::string taxi_nodes = fields[38].GetCppString();
|
||||
|
||||
MapEntry const * mapEntry = sMapStore.LookupEntry(mapId);
|
||||
if(!IsPositionValid())
|
||||
{
|
||||
sLog.outError("Player (guidlow %d) have invalid coordinates (X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.",guid,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
|
||||
RelocateToHomebind();
|
||||
RelocateToHomebind(mapId);
|
||||
|
||||
transGUID = 0;
|
||||
instanceId = 0;
|
||||
|
||||
m_movementInfo.t_x = 0.0f;
|
||||
m_movementInfo.t_y = 0.0f;
|
||||
m_movementInfo.t_z = 0.0f;
|
||||
m_movementInfo.t_o = 0.0f;
|
||||
}
|
||||
|
||||
uint32 bgid = fields[41].GetUInt32();
|
||||
uint32 bgteam = fields[42].GetUInt32();
|
||||
|
||||
if(bgid) //saved in BattleGround
|
||||
// Player was saved in Arena or Bg
|
||||
else if (mapEntry && mapEntry->IsBattleGroundOrArena())
|
||||
{
|
||||
// Get Entry Point(bg master) or Homebind
|
||||
SetBattleGroundEntryPoint(fields[43].GetUInt32(),fields[44].GetFloat(),fields[45].GetFloat(),fields[46].GetFloat(),fields[47].GetFloat());
|
||||
|
||||
// check entry point and fix to homebind if need
|
||||
MapEntry const* mapEntry = sMapStore.LookupEntry(m_bgEntryPoint.mapid);
|
||||
if(!mapEntry || mapEntry->Instanceable() || !MapManager::IsValidMapCoord(m_bgEntryPoint))
|
||||
MapEntry const* bgEntry = sMapStore.LookupEntry(m_bgEntryPoint.mapid);
|
||||
if(!bgEntry || bgEntry->Instanceable() || !MapManager::IsValidMapCoord(m_bgEntryPoint))
|
||||
SetBattleGroundEntryPoint(m_homebindMapId,m_homebindX,m_homebindY,m_homebindZ,0.0f);
|
||||
|
||||
BattleGround *currentBg = sBattleGroundMgr.GetBattleGround(bgid, BATTLEGROUND_TYPE_NONE);
|
||||
|
||||
// Bg still exists - join it!
|
||||
BattleGround *currentBg = sBattleGroundMgr.GetBattleGround(instanceId, BATTLEGROUND_TYPE_NONE);
|
||||
if(currentBg && currentBg->IsPlayerInBattleGround(GetGUID()))
|
||||
{
|
||||
uint32 bgteam = fields[42].GetUInt32();
|
||||
BattleGroundQueueTypeId bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(currentBg->GetTypeID(), currentBg->GetArenaType());
|
||||
AddBattleGroundQueueId(bgQueueTypeId);
|
||||
|
||||
@@ -14637,34 +14642,21 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
||||
|
||||
SetInviteForBattleGroundQueueType(bgQueueTypeId,currentBg->GetInstanceID());
|
||||
}
|
||||
// Bg was not found - go to Entry Point
|
||||
else
|
||||
{
|
||||
// Do not look for instance if bg not found
|
||||
instanceId = 0;
|
||||
const WorldLocation& _loc = GetBattleGroundEntryPoint();
|
||||
SetLocationMapId(_loc.mapid);
|
||||
mapId = _loc.mapid;
|
||||
Relocate(_loc.coord_x, _loc.coord_y, _loc.coord_z, _loc.orientation);
|
||||
//RemoveArenaAuras(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (transGUID != 0)
|
||||
{
|
||||
MapEntry const* mapEntry = sMapStore.LookupEntry(GetMapId());
|
||||
// if server restart after player save in BG or area
|
||||
// player can have current coordinates in to BG/Arean map, fix this
|
||||
if(!mapEntry || mapEntry->IsBattleGroundOrArena())
|
||||
{
|
||||
// return to BG master
|
||||
SetLocationMapId(fields[43].GetUInt32());
|
||||
Relocate(fields[44].GetFloat(),fields[45].GetFloat(),fields[46].GetFloat(),fields[47].GetFloat());
|
||||
// There are no transports on instances
|
||||
assert (!instanceId);
|
||||
|
||||
// check entry point and fix to homebind if need
|
||||
mapEntry = sMapStore.LookupEntry(GetMapId());
|
||||
if(!mapEntry || mapEntry->IsBattleGroundOrArena() || !IsPositionValid())
|
||||
RelocateToHomebind();
|
||||
}
|
||||
}
|
||||
|
||||
if (transGUID != 0)
|
||||
{
|
||||
m_movementInfo.t_x = fields[27].GetFloat();
|
||||
m_movementInfo.t_y = fields[28].GetFloat();
|
||||
m_movementInfo.t_z = fields[29].GetFloat();
|
||||
@@ -14680,7 +14672,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
||||
guid,GetPositionX()+m_movementInfo.t_x,GetPositionY()+m_movementInfo.t_y,
|
||||
GetPositionZ()+m_movementInfo.t_z,GetOrientation()+m_movementInfo.t_o);
|
||||
|
||||
RelocateToHomebind();
|
||||
RelocateToHomebind(mapId);
|
||||
|
||||
m_movementInfo.t_x = 0.0f;
|
||||
m_movementInfo.t_y = 0.0f;
|
||||
@@ -14689,111 +14681,135 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
||||
|
||||
transGUID = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (transGUID != 0)
|
||||
{
|
||||
for (MapManager::TransportSet::iterator iter = MapManager::Instance().m_Transports.begin(); iter != MapManager::Instance().m_Transports.end(); ++iter)
|
||||
{
|
||||
if( (*iter)->GetGUIDLow() == transGUID)
|
||||
{
|
||||
MapEntry const* transMapEntry = sMapStore.LookupEntry((*iter)->GetMapId());
|
||||
// client without expansion support
|
||||
if(GetSession()->Expansion() < transMapEntry->Expansion())
|
||||
{
|
||||
sLog.outDebug("Player %s using client without required expansion tried login at transport at non accessible map %u", GetName(), (*iter)->GetMapId());
|
||||
break;
|
||||
}
|
||||
|
||||
m_transport = *iter;
|
||||
m_transport->AddPassenger(this);
|
||||
SetLocationMapId(m_transport->GetMapId());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!m_transport)
|
||||
{
|
||||
sLog.outError("Player (guidlow %d) have problems with transport guid (%u). Teleport to default race/class locations.",
|
||||
guid,transGUID);
|
||||
|
||||
RelocateToHomebind();
|
||||
|
||||
m_movementInfo.t_x = 0.0f;
|
||||
m_movementInfo.t_y = 0.0f;
|
||||
m_movementInfo.t_z = 0.0f;
|
||||
m_movementInfo.t_o = 0.0f;
|
||||
|
||||
transGUID = 0;
|
||||
}
|
||||
}
|
||||
else // not transport case
|
||||
{
|
||||
MapEntry const* mapEntry = sMapStore.LookupEntry(GetMapId());
|
||||
// client without expansion support
|
||||
if(GetSession()->Expansion() < mapEntry->Expansion())
|
||||
{
|
||||
sLog.outDebug("Player %s using client without required expansion tried login at non accessible map %u", GetName(), GetMapId());
|
||||
RelocateToHomebind();
|
||||
}
|
||||
}
|
||||
|
||||
// In some old saves players' instance id are not correctly ordered
|
||||
// This fixes the crash. But it is not needed for a new db
|
||||
if(InstanceSave *pSave = GetInstanceSave(GetMapId()))
|
||||
if(pSave->GetInstanceId() != GetInstanceId())
|
||||
SetLocationInstanceId(pSave->GetInstanceId());
|
||||
|
||||
// NOW player must have valid map
|
||||
// load the player's map here if it's not already loaded
|
||||
Map *map = MapManager::Instance().CreateMap(GetMapId(), this);
|
||||
|
||||
if (!map)
|
||||
{
|
||||
AreaTrigger const* at = objmgr.GetGoBackTrigger(GetMapId());
|
||||
if(at)
|
||||
{
|
||||
SetLocationMapId(at->target_mapId);
|
||||
Relocate(at->target_X, at->target_Y, at->target_Z, GetOrientation());
|
||||
sLog.outError("Player (guidlow %d) is teleported to gobacktrigger (Map: %u X: %f Y: %f Z: %f O: %f).",guid,GetMapId(),GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
|
||||
}
|
||||
else
|
||||
{
|
||||
RelocateToHomebind();
|
||||
sLog.outError("Player (guidlow %d) is teleported to home (Map: %u X: %f Y: %f Z: %f O: %f).",guid,GetMapId(),GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
|
||||
for (MapManager::TransportSet::iterator iter = MapManager::Instance().m_Transports.begin(); iter != MapManager::Instance().m_Transports.end(); ++iter)
|
||||
{
|
||||
if( (*iter)->GetGUIDLow() == transGUID)
|
||||
{
|
||||
m_transport = *iter;
|
||||
m_transport->AddPassenger(this);
|
||||
mapId = (m_transport->GetMapId());
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!m_transport)
|
||||
{
|
||||
sLog.outError("Player (guidlow %d) have problems with transport guid (%u). Teleport to default race/class locations.",
|
||||
guid,transGUID);
|
||||
|
||||
RelocateToHomebind(mapId);
|
||||
|
||||
m_movementInfo.t_x = 0.0f;
|
||||
m_movementInfo.t_y = 0.0f;
|
||||
m_movementInfo.t_z = 0.0f;
|
||||
m_movementInfo.t_o = 0.0f;
|
||||
|
||||
transGUID = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!taxi_nodes.empty()) // Taxi Flight path loaded from db
|
||||
{
|
||||
// There are no flightpaths in instances
|
||||
assert (!instanceId);
|
||||
|
||||
if(!m_taxi.LoadTaxiDestinationsFromString(taxi_nodes,GetTeam()))
|
||||
{
|
||||
// problems with taxi path loading
|
||||
TaxiNodesEntry const* nodeEntry = NULL;
|
||||
if(uint32 node_id = m_taxi.GetTaxiSource())
|
||||
nodeEntry = sTaxiNodesStore.LookupEntry(node_id);
|
||||
|
||||
if(!nodeEntry) // don't know taxi start node, to homebind
|
||||
{
|
||||
sLog.outError("Character %u have wrong data in taxi destination list, teleport to homebind.",GetGUIDLow());
|
||||
RelocateToHomebind(mapId);
|
||||
}
|
||||
else // have start node, to it
|
||||
{
|
||||
sLog.outError("Character %u have too short taxi destination list, teleport to original node.",GetGUIDLow());
|
||||
mapId = nodeEntry->map_id;
|
||||
Relocate(nodeEntry->x, nodeEntry->y, nodeEntry->z,0.0f);
|
||||
}
|
||||
}
|
||||
// Taxi path loading succesfull
|
||||
else if(uint32 node_id = m_taxi.GetTaxiSource())
|
||||
{
|
||||
// save source node as recall coord to prevent recall and fall from sky
|
||||
TaxiNodesEntry const* nodeEntry = sTaxiNodesStore.LookupEntry(node_id);
|
||||
assert(nodeEntry); // checked in m_taxi.LoadTaxiDestinationsFromString
|
||||
Relocate(nodeEntry->x,nodeEntry->y,nodeEntry->z,0);
|
||||
mapId = nodeEntry->map_id;
|
||||
// flight will started later
|
||||
}
|
||||
}
|
||||
// Map could be changed before
|
||||
mapEntry = sMapStore.LookupEntry(mapId);
|
||||
// client without expansion support
|
||||
if(GetSession()->Expansion() < mapEntry->Expansion())
|
||||
{
|
||||
sLog.outDebug("Player %s using client without required expansion tried login at non accessible map %u", GetName(), mapId);
|
||||
RelocateToHomebind(mapId);
|
||||
instanceId = 0;
|
||||
}
|
||||
|
||||
// NOW player must have valid map
|
||||
// load the player's map here if it's not already loaded
|
||||
Map *map = MapManager::Instance().CreateMap(mapId, this, instanceId);
|
||||
|
||||
if (!map)
|
||||
{
|
||||
instanceId = 0;
|
||||
AreaTrigger const* at = objmgr.GetGoBackTrigger(mapId);
|
||||
if(at)
|
||||
{
|
||||
sLog.outError("Player (guidlow %d) is teleported to gobacktrigger (Map: %u X: %f Y: %f Z: %f O: %f).",guid,mapId,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
|
||||
Relocate(at->target_X, at->target_Y, at->target_Z, GetOrientation());
|
||||
mapId = at->target_mapId;
|
||||
}
|
||||
else
|
||||
{
|
||||
sLog.outError("Player (guidlow %d) is teleported to home (Map: %u X: %f Y: %f Z: %f O: %f).",guid,mapId,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
|
||||
RelocateToHomebind(mapId);
|
||||
}
|
||||
|
||||
map = MapManager::Instance().CreateMap(GetMapId(), this);
|
||||
map = MapManager::Instance().CreateMap(mapId, this, 0);
|
||||
if(!map)
|
||||
{
|
||||
sLog.outError("ERROR: Player (guidlow %d) have invalid coordinates (X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.",guid,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
|
||||
delete result;
|
||||
return false;
|
||||
|
||||
/*SetMapId(info->mapId);
|
||||
PlayerInfo const *info = objmgr.GetPlayerInfo(getRace(), getClass());
|
||||
mapId = info->mapId;
|
||||
Relocate(info->positionX,info->positionY,info->positionZ,0.0f);
|
||||
|
||||
map = GetMap();
|
||||
if(!map)
|
||||
sLog.outError("ERROR: Player (guidlow %d) have invalid coordinates (X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.",guid,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
|
||||
map = MapManager::Instance().CreateMap(mapId, this, 0);
|
||||
if (!map)
|
||||
{
|
||||
sLog.outError("ERROR: Player (guidlow %d) have invalid coordinates (X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.",guid,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
|
||||
sLog.outError("CRASH.");
|
||||
assert(false);
|
||||
}*/
|
||||
sLog.outError("ERROR: Player (guidlow %d) has invalid default map coordinates (X: %f Y: %f Z: %f O: %f). or instance couldn't be created",guid,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
|
||||
delete result;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if the player is in an instance and it has been reset in the meantime teleport him to the entrance
|
||||
if(instanceId && !sInstanceSaveManager.GetInstanceSave(instanceId))
|
||||
{
|
||||
AreaTrigger const* at = objmgr.GetMapEntranceTrigger(mapId);
|
||||
if(at)
|
||||
Relocate(at->target_X, at->target_Y, at->target_Z, at->target_Orientation);
|
||||
else
|
||||
{
|
||||
sLog.outError("Player %s(GUID: %u) logged in to a reset instance (map: %u) and there is no area-trigger leading to this map. Thus he can't be ported back to the entrance. This _might_ be an exploit attempt.", GetName(), GetGUIDLow(), mapId);
|
||||
RelocateToHomebind(mapId);
|
||||
instanceId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
SetMap(map);
|
||||
|
||||
// if the player is in an instance and it has been reset in the meantime teleport him to the entrance
|
||||
if(GetInstanceId() && !sInstanceSaveManager.GetInstanceSave(GetInstanceId()))
|
||||
{
|
||||
AreaTrigger const* at = objmgr.GetMapEntranceTrigger(GetMapId());
|
||||
if(at)
|
||||
Relocate(at->target_X, at->target_Y, at->target_Z, at->target_Orientation);
|
||||
else
|
||||
sLog.outError("Player %s(GUID: %u) logged in to a reset instance (map: %u) and there is no area-trigger leading to this map. Thus he can't be ported back to the entrance. This _might_ be an exploit attempt.", GetName(), GetGUIDLow(), GetMapId());
|
||||
}
|
||||
// randomize first save time in range [CONFIG_INTERVAL_SAVE] around [CONFIG_INTERVAL_SAVE]
|
||||
// this must help in case next save after mass player load after server startup
|
||||
m_nextSave = urand(m_nextSave/2,m_nextSave*3/2);
|
||||
|
||||
SaveRecallPosition();
|
||||
|
||||
@@ -14863,8 +14879,6 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
||||
if(m_deathExpireTime > now+MAX_DEATH_COUNT*DEATH_EXPIRE_STEP)
|
||||
m_deathExpireTime = now+MAX_DEATH_COUNT*DEATH_EXPIRE_STEP-1;
|
||||
|
||||
std::string taxi_nodes = fields[38].GetCppString();
|
||||
|
||||
delete result;
|
||||
|
||||
// clear channel spell data (if saved at channel spell casting)
|
||||
@@ -14950,46 +14964,6 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
||||
SetUInt32Value(PLAYER_CHOSEN_TITLE, 0);
|
||||
}
|
||||
|
||||
// Not finish taxi flight path
|
||||
if(!m_taxi.LoadTaxiDestinationsFromString(taxi_nodes,GetTeam()))
|
||||
{
|
||||
// problems with taxi path loading
|
||||
TaxiNodesEntry const* nodeEntry = NULL;
|
||||
if(uint32 node_id = m_taxi.GetTaxiSource())
|
||||
nodeEntry = sTaxiNodesStore.LookupEntry(node_id);
|
||||
|
||||
if(!nodeEntry) // don't know taxi start node, to homebind
|
||||
{
|
||||
sLog.outError("Character %u have wrong data in taxi destination list, teleport to homebind.",GetGUIDLow());
|
||||
RelocateToHomebind();
|
||||
}
|
||||
else // have start node, to it
|
||||
{
|
||||
sLog.outError("Character %u have too short taxi destination list, teleport to original node.",GetGUIDLow());
|
||||
SetLocationMapId(nodeEntry->map_id);
|
||||
Relocate(nodeEntry->x, nodeEntry->y, nodeEntry->z,0.0f);
|
||||
}
|
||||
|
||||
//we can be relocated from taxi and still have an outdated Map pointer!
|
||||
//so we need to get a new Map pointer!
|
||||
SetMap(MapManager::Instance().CreateMap(GetMapId(), this));
|
||||
SaveRecallPosition(); // save as recall also to prevent recall and fall from sky
|
||||
|
||||
m_taxi.ClearTaxiDestinations();
|
||||
}
|
||||
else if(uint32 node_id = m_taxi.GetTaxiSource())
|
||||
{
|
||||
// save source node as recall coord to prevent recall and fall from sky
|
||||
TaxiNodesEntry const* nodeEntry = sTaxiNodesStore.LookupEntry(node_id);
|
||||
assert(nodeEntry); // checked in m_taxi.LoadTaxiDestinationsFromString
|
||||
m_recallMap = nodeEntry->map_id;
|
||||
m_recallX = nodeEntry->x;
|
||||
m_recallY = nodeEntry->y;
|
||||
m_recallZ = nodeEntry->z;
|
||||
|
||||
// flight will started later
|
||||
}
|
||||
|
||||
// has to be called after last Relocate() in Player::LoadFromDB
|
||||
SetFallInformation(0, GetPositionZ());
|
||||
|
||||
@@ -21412,3 +21386,15 @@ void Player::SendClearCooldown( uint32 spell_id, Unit* target )
|
||||
data << uint64(target->GetGUID());
|
||||
SendDirectMessage(&data);
|
||||
}
|
||||
|
||||
void Player::ResetMap()
|
||||
{
|
||||
// this may be called during Map::Update
|
||||
// after decrement+unlink, ++m_mapRefIter will continue correctly
|
||||
// when the first element of the list is being removed
|
||||
// nocheck_prev will return the padding element of the RefManager
|
||||
// instead of NULL in the case of prev
|
||||
GetMap()->UpdateIteratorBack(this);
|
||||
Unit::ResetMap();
|
||||
GetMapRef().unlink();
|
||||
}
|
||||
+5
-1
@@ -2032,7 +2032,7 @@ class TRINITY_DLL_SPEC Player : public Unit
|
||||
float m_homebindX;
|
||||
float m_homebindY;
|
||||
float m_homebindZ;
|
||||
void RelocateToHomebind() { SetLocationMapId(m_homebindMapId); Relocate(m_homebindX,m_homebindY,m_homebindZ); }
|
||||
void RelocateToHomebind(uint32 & newMap) { newMap = m_homebindMapId; Relocate(m_homebindX,m_homebindY,m_homebindZ); }
|
||||
|
||||
// currently visible objects at player client
|
||||
typedef std::set<uint64> ClientGUIDs;
|
||||
@@ -2122,6 +2122,10 @@ class TRINITY_DLL_SPEC Player : public Unit
|
||||
GridReference<Player> &GetGridRef() { return m_gridRef; }
|
||||
MapReference &GetMapRef() { return m_mapRef; }
|
||||
|
||||
// Set map to player and add reference
|
||||
void SetMap(Map * map) {Unit::SetMap(map); m_mapRef.link(map, this);}
|
||||
void ResetMap();
|
||||
|
||||
bool isAllowedToLoot(Creature* creature);
|
||||
|
||||
DeclinedName const* GetDeclinedNames() const { return m_declinedname; }
|
||||
|
||||
@@ -5501,8 +5501,7 @@ void Spell::EffectScriptEffect(uint32 effIndex)
|
||||
|
||||
// normal DB scripted effect
|
||||
sLog.outDebug("Spell ScriptStart spellid %u in EffectScriptEffect ", m_spellInfo->Id);
|
||||
if (m_caster->FindMap())
|
||||
m_caster->GetMap()->ScriptsStart(sSpellScripts, m_spellInfo->Id, m_caster, unitTarget);
|
||||
m_caster->GetMap()->ScriptsStart(sSpellScripts, m_spellInfo->Id, m_caster, unitTarget);
|
||||
}
|
||||
|
||||
void Spell::EffectSanctuary(uint32 /*i*/)
|
||||
|
||||
@@ -106,7 +106,7 @@ void MapManager::LoadTransports()
|
||||
m_TransportsByMap[*i].insert(t);
|
||||
|
||||
//If we someday decide to use the grid to track transports, here:
|
||||
t->SetMap(MapManager::Instance().CreateMap(mapid, t));
|
||||
t->SetMap(MapManager::Instance().CreateMap(mapid, t, 0));
|
||||
|
||||
//t->GetMap()->Add<GameObject>((GameObject *)t);
|
||||
++count;
|
||||
@@ -459,8 +459,12 @@ void Transport::TeleportTransport(uint32 newMapid, float x, float y, float z)
|
||||
//we need to create and save new Map object with 'newMapid' because if not done -> lead to invalid Map object reference...
|
||||
//player far teleport would try to create same instance, but we need it NOW for transport...
|
||||
//correct me if I'm wrong O.o
|
||||
Map * newMap = MapManager::Instance().CreateMap(newMapid, this);
|
||||
//yes, you're right
|
||||
|
||||
ResetMap();
|
||||
Map * newMap = MapManager::Instance().CreateMap(newMapid, this, 0);
|
||||
SetMap(newMap);
|
||||
assert (GetMap());
|
||||
|
||||
if(oldMap != newMap)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user