aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Maps/Map.cpp
diff options
context:
space:
mode:
authorkaelima <kaelima@live.se>2012-05-30 08:01:02 +0200
committerkaelima <kaelima@live.se>2012-05-30 08:01:02 +0200
commit3d14384c32971096b49f88ff785d92879480af76 (patch)
treec1ade41c9d04583a717a705132ca09dde7a8ad56 /src/server/game/Maps/Map.cpp
parentbdf6cf5146b884591e3a033a31ca5b729fdff0ff (diff)
Merge git://github.com/TrinityCore/TrinityCore into 4.x
Conflicts: dep/PackageList.txt sql/base/auth_database.sql src/server/authserver/Server/AuthSocket.cpp src/server/game/Battlegrounds/BattlegroundMgr.cpp src/server/game/Chat/Commands/Level1.cpp src/server/game/Chat/Commands/Level3.cpp src/server/game/DataStores/DBCEnums.h src/server/game/DataStores/DBCStores.cpp src/server/game/DataStores/DBCStores.h src/server/game/DataStores/DBCStructure.h src/server/game/DataStores/DBCfmt.h src/server/game/Entities/Corpse/Corpse.cpp src/server/game/Entities/Creature/Creature.cpp src/server/game/Entities/DynamicObject/DynamicObject.cpp src/server/game/Entities/GameObject/GameObject.cpp src/server/game/Entities/Item/Item.cpp src/server/game/Entities/Object/Object.cpp src/server/game/Entities/Object/Updates/UpdateData.h src/server/game/Entities/Pet/Pet.cpp src/server/game/Entities/Player/Player.cpp src/server/game/Entities/Player/Player.h src/server/game/Entities/Transport/Transport.cpp src/server/game/Entities/Unit/Unit.cpp src/server/game/Globals/ObjectMgr.cpp src/server/game/Globals/ObjectMgr.h src/server/game/Guilds/Guild.cpp src/server/game/Handlers/CharacterHandler.cpp src/server/game/Handlers/MiscHandler.cpp src/server/game/Handlers/MovementHandler.cpp src/server/game/Handlers/QuestHandler.cpp src/server/game/Loot/LootMgr.cpp src/server/game/Miscellaneous/SharedDefines.h src/server/game/Quests/QuestDef.cpp src/server/game/Server/Protocol/Opcodes.cpp src/server/game/Server/Protocol/Opcodes.h src/server/game/Server/WorldSession.cpp src/server/game/Server/WorldSocket.cpp src/server/game/Spells/Auras/SpellAuraEffects.cpp src/server/game/Spells/Spell.cpp src/server/game/Spells/Spell.h src/server/game/Spells/SpellEffects.cpp src/server/game/Tickets/TicketMgr.cpp src/server/scripts/Commands/cs_gps.cpp src/server/scripts/Commands/cs_modify.cpp src/server/shared/Database/Implementation/CharacterDatabase.cpp src/server/shared/Logging/Log.h src/tools/map_extractor/CMakeLists.txt src/tools/map_extractor/System.cpp src/tools/map_extractor/mpq_libmpq04.h src/tools/vmap4_extractor/CMakeLists.txt
Diffstat (limited to 'src/server/game/Maps/Map.cpp')
-rwxr-xr-xsrc/server/game/Maps/Map.cpp173
1 files changed, 137 insertions, 36 deletions
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 81b4f958e5d..073ceae5b62 100755
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -32,6 +32,7 @@
#include "Group.h"
#include "LFGMgr.h"
#include "DynamicTree.h"
+#include "Vehicle.h"
union u_map_magic
{
@@ -40,7 +41,7 @@ union u_map_magic
};
u_map_magic MapMagic = { {'M','A','P','S'} };
-u_map_magic MapVersionMagic = { {'v','1','.','1'} };
+u_map_magic MapVersionMagic = { {'v','1','.','2'} };
u_map_magic MapAreaMagic = { {'A','R','E','A'} };
u_map_magic MapHeightMagic = { {'M','H','G','T'} };
u_map_magic MapLiquidMagic = { {'M','L','I','Q'} };
@@ -492,6 +493,7 @@ void Map::VisitNearbyCellsOf(WorldObject* obj, TypeContainerVisitor<Trinity::Obj
markCell(cell_id);
CellCoord pair(x, y);
Cell cell(pair);
+ cell.SetNoCreate();
Visit(cell, gridVisitor);
Visit(cell, worldVisitor);
}
@@ -508,9 +510,9 @@ void Map::Update(const uint32 t_diff)
if (player && player->IsInWorld())
{
//player->Update(t_diff);
- WorldSession* pSession = player->GetSession();
- MapSessionFilter updater(pSession);
- pSession->Update(t_diff, updater);
+ WorldSession* session = player->GetSession();
+ MapSessionFilter updater(session);
+ session->Update(t_diff, updater);
}
}
/// update active cells around players and active objects
@@ -701,7 +703,15 @@ void Map::PlayerRelocation(Player* player, float x, float y, float z, float orie
Cell old_cell(player->GetPositionX(), player->GetPositionY());
Cell new_cell(x, y);
+ //! If hovering, always increase our server-side Z position
+ //! Client automatically projects correct position based on Z coord sent in monster move
+ //! and UNIT_FIELD_HOVERHEIGHT sent in object updates
+ if (player->HasUnitMovementFlag(MOVEMENTFLAG_HOVER))
+ z += player->GetFloatValue(UNIT_FIELD_HOVERHEIGHT);
+
player->Relocate(x, y, z, orientation);
+ if (player->IsVehicle())
+ player->GetVehicleKit()->RelocatePassengers(x, y, z, orientation);
if (old_cell.DiffGrid(new_cell) || old_cell.DiffCell(new_cell))
{
@@ -728,6 +738,12 @@ void Map::CreatureRelocation(Creature* creature, float x, float y, float z, floa
if (!respawnRelocationOnFail && !getNGrid(new_cell.GridX(), new_cell.GridY()))
return;
+ //! If hovering, always increase our server-side Z position
+ //! Client automatically projects correct position based on Z coord sent in monster move
+ //! and UNIT_FIELD_HOVERHEIGHT sent in object updates
+ if (creature->HasUnitMovementFlag(MOVEMENTFLAG_HOVER))
+ z += creature->GetFloatValue(UNIT_FIELD_HOVERHEIGHT);
+
// delay creature move for grid/cell to grid/cell moves
if (old_cell.DiffCell(new_cell) || old_cell.DiffGrid(new_cell))
{
@@ -740,6 +756,8 @@ void Map::CreatureRelocation(Creature* creature, float x, float y, float z, floa
else
{
creature->Relocate(x, y, z, ang);
+ if (creature->IsVehicle())
+ creature->GetVehicleKit()->RelocatePassengers(x, y, z, ang);
creature->UpdateObjectVisibility(false);
RemoveCreatureFromMoveList(creature);
}
@@ -769,20 +787,20 @@ void Map::RemoveCreatureFromMoveList(Creature* c)
void Map::MoveAllCreaturesInMoveList()
{
_creatureToMoveLock = true;
- for(std::vector<Creature*>::iterator itr = _creaturesToMove.begin(); itr != _creaturesToMove.end(); ++itr)
+ for (std::vector<Creature*>::iterator itr = _creaturesToMove.begin(); itr != _creaturesToMove.end(); ++itr)
{
Creature* c = *itr;
- if(c->FindMap() != this) //pet is teleported to another map
+ if (c->FindMap() != this) //pet is teleported to another map
continue;
- if(c->_moveState != CREATURE_CELL_MOVE_ACTIVE)
+ if (c->_moveState != CREATURE_CELL_MOVE_ACTIVE)
{
c->_moveState = CREATURE_CELL_MOVE_NONE;
continue;
}
c->_moveState = CREATURE_CELL_MOVE_NONE;
- if(!c->IsInWorld())
+ if (!c->IsInWorld())
continue;
// do move or do move to respawn or remove creature if previous all fail
@@ -1039,7 +1057,8 @@ GridMap::GridMap()
_liquidWidth = 0;
_liquidHeight = 0;
_liquidLevel = INVALID_HEIGHT;
- _liquidData = NULL;
+ _liquidEntry = NULL;
+ _liquidFlags = NULL;
_liquidMap = NULL;
}
@@ -1101,12 +1120,14 @@ void GridMap::unloadData()
delete[] _areaMap;
delete[] m_V9;
delete[] m_V8;
- delete[] _liquidData;
+ delete[] _liquidEntry;
+ delete[] _liquidFlags;
delete[] _liquidMap;
_areaMap = NULL;
m_V9 = NULL;
m_V8 = NULL;
- _liquidData = NULL;
+ _liquidEntry = NULL;
+ _liquidFlags = NULL;
_liquidMap = NULL;
_gridGetHeight = &GridMap::getHeightFromFlat;
}
@@ -1187,18 +1208,22 @@ bool GridMap::loadLiquidData(FILE* in, uint32 offset, uint32 /*size*/)
_liquidOffX = header.offsetX;
_liquidOffY = header.offsetY;
_liquidWidth = header.width;
- _liquidHeight= header.height;
+ _liquidHeight = header.height;
_liquidLevel = header.liquidLevel;
if (!(header.flags & MAP_LIQUID_NO_TYPE))
{
- _liquidData = new uint8 [16*16];
- if (fread(_liquidData, sizeof(uint8), 16*16, in) != 16*16)
+ _liquidEntry = new uint16[16*16];
+ if (fread(_liquidEntry, sizeof(uint16), 16*16, in) != 16*16)
+ return false;
+
+ _liquidFlags = new uint8[16*16];
+ if (fread(_liquidFlags, sizeof(uint8), 16*16, in) != 16*16)
return false;
}
if (!(header.flags & MAP_LIQUID_NO_HEIGHT))
{
- _liquidMap = new float [_liquidWidth*_liquidHeight];
+ _liquidMap = new float[_liquidWidth*_liquidHeight];
if (fread(_liquidMap, sizeof(float), _liquidWidth*_liquidHeight, in) != _liquidWidth*_liquidHeight)
return false;
}
@@ -1457,23 +1482,24 @@ float GridMap::getLiquidLevel(float x, float y)
return _liquidMap[cx_int*_liquidWidth + cy_int];
}
+// Why does this return LIQUID data?
uint8 GridMap::getTerrainType(float x, float y)
{
- if (!_liquidData)
+ if (!_liquidFlags)
return 0;
x = 16 * (32 - x/SIZE_OF_GRIDS);
y = 16 * (32 - y/SIZE_OF_GRIDS);
int lx = (int)x & 15;
int ly = (int)y & 15;
- return _liquidData[lx*16 + ly];
+ return _liquidFlags[lx*16 + ly];
}
// Get water state on map
inline ZLiquidStatus GridMap::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data)
{
// Check water type (if no water return)
- if (!_liquidType && !_liquidData)
+ if (!_liquidType && !_liquidFlags)
return LIQUID_MAP_NO_WATER;
// Get cell
@@ -1484,7 +1510,40 @@ inline ZLiquidStatus GridMap::getLiquidStatus(float x, float y, float z, uint8 R
int y_int = (int)cy & (MAP_RESOLUTION-1);
// Check water type in cell
- uint8 type = _liquidData ? _liquidData[(x_int>>3)*16 + (y_int>>3)] : _liquidType;
+ int idx=(x_int>>3)*16 + (y_int>>3);
+ uint8 type = _liquidFlags ? _liquidFlags[idx] : _liquidType;
+ uint32 entry = 0;
+ if (_liquidEntry)
+ {
+ if (LiquidTypeEntry const* liquidEntry = sLiquidTypeStore.LookupEntry(_liquidEntry[idx]))
+ {
+ entry = liquidEntry->Id;
+ type &= MAP_LIQUID_TYPE_DARK_WATER;
+ uint32 liqTypeIdx = liquidEntry->Type;
+ if (entry < 21)
+ {
+ if (AreaTableEntry const* area = GetAreaEntryByAreaFlagAndMap(getArea(x, y), MAPID_INVALID))
+ {
+ uint32 overrideLiquid = area->LiquidTypeOverride[liquidEntry->Type];
+ if (!overrideLiquid && area->zone)
+ {
+ area = GetAreaEntryByAreaID(area->zone);
+ if (area)
+ overrideLiquid = area->LiquidTypeOverride[liquidEntry->Type];
+ }
+
+ if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(overrideLiquid))
+ {
+ entry = overrideLiquid;
+ liqTypeIdx = liq->Type;
+ }
+ }
+ }
+
+ type |= 1 << liqTypeIdx;
+ }
+ }
+
if (type == 0)
return LIQUID_MAP_NO_WATER;
@@ -1513,20 +1572,20 @@ inline ZLiquidStatus GridMap::getLiquidStatus(float x, float y, float z, uint8 R
// All ok in water -> store data
if (data)
{
- data->type = type;
+ data->entry = entry;
+ data->type_flags = type;
data->level = liquid_level;
data->depth_level = ground_level;
}
// For speed check as int values
- int delta = int((liquid_level - z) * 10);
+ float delta = liquid_level - z;
- // Get position delta
- if (delta > 20) // Under water
+ if (delta > 2.0f) // Under water
return LIQUID_MAP_UNDER_WATER;
- if (delta > 0) // In water
+ if (delta > 0.0f) // In water
return LIQUID_MAP_IN_WATER;
- if (delta > -1) // Walk on water
+ if (delta > -0.1f) // Walk on water
return LIQUID_MAP_WATER_WALK;
// Above water
return LIQUID_MAP_ABOVE_WATER;
@@ -1717,8 +1776,9 @@ ZLiquidStatus Map::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidTyp
{
ZLiquidStatus result = LIQUID_MAP_NO_WATER;
VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
- float liquid_level, ground_level = INVALID_HEIGHT;
- uint32 liquid_type;
+ float liquid_level = INVALID_HEIGHT;
+ float ground_level = INVALID_HEIGHT;
+ uint32 liquid_type = 0;
if (vmgr->GetLiquidLevel(GetId(), x, y, z, ReqLiquidType, liquid_level, ground_level, liquid_type))
{
sLog->outDebug(LOG_FILTER_MAPS, "getLiquidStatus(): vmap liquid level: %f ground: %f type: %u", liquid_level, ground_level, liquid_type);
@@ -1728,20 +1788,49 @@ ZLiquidStatus Map::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidTyp
// All ok in water -> store data
if (data)
{
- data->type = liquid_type;
+ // hardcoded in client like this
+ if (GetId() == 530 && liquid_type == 2)
+ liquid_type = 15;
+
+ uint32 liquidFlagType = 0;
+ if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(liquid_type))
+ liquidFlagType = liq->Type;
+
+ if (liquid_type && liquid_type < 21)
+ {
+ if (AreaTableEntry const* area = GetAreaEntryByAreaFlagAndMap(GetAreaFlag(x, y, z), GetId()))
+ {
+ uint32 overrideLiquid = area->LiquidTypeOverride[liquidFlagType];
+ if (!overrideLiquid && area->zone)
+ {
+ area = GetAreaEntryByAreaID(area->zone);
+ if (area)
+ overrideLiquid = area->LiquidTypeOverride[liquidFlagType];
+ }
+
+ if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(overrideLiquid))
+ {
+ liquid_type = overrideLiquid;
+ liquidFlagType = liq->Type;
+ }
+ }
+ }
+
data->level = liquid_level;
data->depth_level = ground_level;
+
+ data->entry = liquid_type;
+ data->type_flags = 1 << liquidFlagType;
}
- // For speed check as int values
- int delta = int((liquid_level - z) * 10);
+ float delta = liquid_level - z;
// Get position delta
- if (delta > 20) // Under water
+ if (delta > 2.0f) // Under water
return LIQUID_MAP_UNDER_WATER;
- if (delta > 0 ) // In water
+ if (delta > 0.0f) // In water
return LIQUID_MAP_IN_WATER;
- if (delta > -1) // Walk on water
+ if (delta > -0.1f) // Walk on water
return LIQUID_MAP_WATER_WALK;
result = LIQUID_MAP_ABOVE_WATER;
}
@@ -1755,7 +1844,13 @@ ZLiquidStatus Map::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidTyp
if (map_result != LIQUID_MAP_NO_WATER && (map_data.level > ground_level))
{
if (data)
+ {
+ // hardcoded in client like this
+ if (GetId() == 530 && map_data.entry == 2)
+ map_data.entry = 15;
+
*data = map_data;
+ }
return map_result;
}
}
@@ -2260,7 +2355,7 @@ bool InstanceMap::CanEnter(Player* player)
return false;
}
// player inside instance has no group or his groups is different to entering player's one, deny entry
- if (!iPlayer->GetGroup() || iPlayer->GetGroup() != player->GetGroup() )
+ if (!iPlayer->GetGroup() || iPlayer->GetGroup() != player->GetGroup())
{
player->SendTransferAborted(GetId(), TRANSFER_ABORT_MAX_PLAYERS);
return false;
@@ -2376,7 +2471,7 @@ bool InstanceMap::AddPlayerToMap(Player* player)
if (uint32 dungeonId = sLFGMgr->GetDungeon(group->GetGUID(), true))
if (LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(dungeonId))
if (LFGDungeonEntry const* randomDungeon = sLFGDungeonStore.LookupEntry(*(sLFGMgr->GetSelectedDungeons(player->GetGUID()).begin())))
- if (uint32(dungeon->map) == GetId() && dungeon->difficulty == GetDifficulty() && randomDungeon->type == LFG_TYPE_RANDOM)
+ if (uint32(dungeon->map) == GetId() && dungeon->difficulty == uint32(GetDifficulty()) && randomDungeon->type == uint32(LFG_TYPE_RANDOM))
player->CastSpell(player, LFG_SPELL_LUCK_OF_THE_DRAW, true);
}
@@ -2439,7 +2534,11 @@ void InstanceMap::CreateInstanceData(bool load)
if (load)
{
// TODO: make a global storage for this
- QueryResult result = CharacterDatabase.PQuery("SELECT data, completedEncounters FROM instance WHERE map = '%u' AND id = '%u'", GetId(), i_InstanceId);
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_INSTANCE);
+ stmt->setUInt16(0, uint16(GetId()));
+ stmt->setUInt32(1, i_InstanceId);
+ PreparedQueryResult result = CharacterDatabase.Query(stmt);
+
if (result)
{
Field* fields = result->Fetch();
@@ -2519,6 +2618,8 @@ void InstanceMap::PermBindAllPlayers(Player* source)
WorldPacket data(SMSG_INSTANCE_SAVE_CREATED, 4);
data << uint32(0);
player->GetSession()->SendPacket(&data);
+
+ player->GetSession()->SendCalendarRaidLockout(save, true);
}
// if the leader is not in the instance the group will not get a perm bind