Core/Collision: Ported dynamic line of sight patch by Silverice from MaNGOS and

added lots of improvements
Please re-extract vmaps
This commit is contained in:
Subv2112
2012-02-09 13:58:22 -05:00
committed by Subv
parent 229d4119e8
commit 93d199f043
60 changed files with 1857 additions and 438 deletions
@@ -51,15 +51,19 @@ void BattlegroundDS::PostUpdateImpl(uint32 diff)
if (isWaterFallActive())
{
setWaterFallTimer(urand(BG_DS_WATERFALL_TIMER_MIN, BG_DS_WATERFALL_TIMER_MAX));
for (uint32 i = BG_DS_OBJECT_WATER_1; i <= BG_DS_OBJECT_WATER_2; ++i)
SpawnBGObject(i, getWaterFallTimer());
SpawnBGObject(BG_DS_OBJECT_WATER_2, getWaterFallTimer());
// turn off collision
if (GameObject* gob = GetBgMap()->GetGameObject(m_BgObjects[BG_DS_OBJECT_WATER_1]))
gob->EnableCollision(false);
setWaterFallActive(false);
}
else
{
setWaterFallTimer(BG_DS_WATERFALL_DURATION);
for (uint32 i = BG_DS_OBJECT_WATER_1; i <= BG_DS_OBJECT_WATER_2; ++i)
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
SpawnBGObject(BG_DS_OBJECT_WATER_2, RESPAWN_IMMEDIATELY);
// Turn on collision
if (GameObject* gob = GetBgMap()->GetGameObject(m_BgObjects[BG_DS_OBJECT_WATER_1]))
gob->EnableCollision(true);
setWaterFallActive(true);
}
}
@@ -25,7 +25,7 @@ enum BattlegroundDSObjectTypes
{
BG_DS_OBJECT_DOOR_1 = 0,
BG_DS_OBJECT_DOOR_2 = 1,
BG_DS_OBJECT_WATER_1 = 2,
BG_DS_OBJECT_WATER_1 = 2, // Collision
BG_DS_OBJECT_WATER_2 = 3,
BG_DS_OBJECT_BUFF_1 = 4,
BG_DS_OBJECT_BUFF_2 = 5,
@@ -36,7 +36,7 @@ enum BattlegroundDSObjects
{
BG_DS_OBJECT_TYPE_DOOR_1 = 192642,
BG_DS_OBJECT_TYPE_DOOR_2 = 192643,
BG_DS_OBJECT_TYPE_WATER_1 = 194395,
BG_DS_OBJECT_TYPE_WATER_1 = 194395, // Collision
BG_DS_OBJECT_TYPE_WATER_2 = 191877,
BG_DS_OBJECT_TYPE_BUFF_1 = 184663,
BG_DS_OBJECT_TYPE_BUFF_2 = 184664
@@ -63,6 +63,7 @@ void BattlegroundRV::PostUpdateImpl(uint32 diff)
case BG_RV_STATE_OPEN_PILARS:
for (uint8 i = BG_RV_OBJECT_PILAR_1; i <= BG_RV_OBJECT_PULLEY_2; ++i)
DoorOpen(i);
TogglePillarCollision(false);
setTimer(BG_RV_PILAR_TO_FIRE_TIMER);
setState(BG_RV_STATE_OPEN_FIRE);
break;
@@ -76,6 +77,7 @@ void BattlegroundRV::PostUpdateImpl(uint32 diff)
case BG_RV_STATE_CLOSE_PILARS:
for (uint8 i = BG_RV_OBJECT_PILAR_1; i <= BG_RV_OBJECT_PULLEY_2; ++i)
DoorOpen(i);
TogglePillarCollision(true);
setTimer(BG_RV_PILAR_TO_FIRE_TIMER);
setState(BG_RV_STATE_CLOSE_FIRE);
break;
@@ -207,13 +209,13 @@ bool BattlegroundRV::SetupBattleground()
|| !AddObject(BG_RV_OBJECT_PILAR_2, BG_RV_OBJECT_TYPE_PILAR_2, 723.644287f, -284.493256f, 24.648525f, 3.141593f, 0, 0, 0, RESPAWN_IMMEDIATELY)
|| !AddObject(BG_RV_OBJECT_PILAR_3, BG_RV_OBJECT_TYPE_PILAR_3, 763.611145f, -261.856750f, 25.909504f, 0.000000f, 0, 0, 0, RESPAWN_IMMEDIATELY)
|| !AddObject(BG_RV_OBJECT_PILAR_4, BG_RV_OBJECT_TYPE_PILAR_4, 802.211609f, -284.493256f, 24.648525f, 0.000000f, 0, 0, 0, RESPAWN_IMMEDIATELY)
/*
// Pilars Collision - Fixme: Use the collision pilars - should make u break LoS
// Pilars Collision
|| !AddObject(BG_RV_OBJECT_PILAR_COLLISION_1, BG_RV_OBJECT_TYPE_PILAR_COLLISION_1, 763.632385f, -306.162384f, 30.639660f, 3.141593f, 0, 0, 0, RESPAWN_IMMEDIATELY)
|| !AddObject(BG_RV_OBJECT_PILAR_COLLISION_2, BG_RV_OBJECT_TYPE_PILAR_COLLISION_2, 723.644287f, -284.493256f, 32.382710f, 0.000000f, 0, 0, 0, RESPAWN_IMMEDIATELY)
|| !AddObject(BG_RV_OBJECT_PILAR_COLLISION_3, BG_RV_OBJECT_TYPE_PILAR_COLLISION_3, 763.611145f, -261.856750f, 30.639660f, 0.000000f, 0, 0, 0, RESPAWN_IMMEDIATELY)
|| !AddObject(BG_RV_OBJECT_PILAR_COLLISION_4, BG_RV_OBJECT_TYPE_PILAR_COLLISION_4, 802.211609f, -284.493256f, 32.382710f, 3.141593f, 0, 0, 0, RESPAWN_IMMEDIATELY)
*/
)
{
sLog->outErrorDb("BatteGroundRV: Failed to spawn some object!");
@@ -221,3 +223,23 @@ bool BattlegroundRV::SetupBattleground()
}
return true;
}
void BattlegroundRV::TogglePillarCollision(bool apply)
{
for (uint8 i = BG_RV_OBJECT_PILAR_1; i <= BG_RV_OBJECT_PILAR_COLLISION_4; ++i)
{
if (GameObject* gob = GetBgMap()->GetGameObject(m_BgObjects[i]))
{
bool startOpen = (gob->GetGoType() == GAMEOBJECT_TYPE_DOOR || gob->GetGoType() == GAMEOBJECT_TYPE_BUTTON ? gob->GetGOInfo()->door.startOpen : false);
if (startOpen)
gob->EnableCollision(!apply);
else
gob->EnableCollision(apply);
for (BattlegroundPlayerMap::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
if (Player* player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)))
gob->SendUpdateToPlayer(player);
}
}
}
@@ -38,12 +38,12 @@ enum BattlegroundRVObjectTypes
BG_RV_OBJECT_PILAR_4,
BG_RV_OBJECT_PULLEY_1,
BG_RV_OBJECT_PULLEY_2,
/*
BG_RV_OBJECT_PILAR_COLLISION_1,
BG_RV_OBJECT_PILAR_COLLISION_2,
BG_RV_OBJECT_PILAR_COLLISION_3,
BG_RV_OBJECT_PILAR_COLLISION_4,
*/
BG_RV_OBJECT_ELEVATOR_1,
BG_RV_OBJECT_ELEVATOR_2,
BG_RV_OBJECT_MAX,
@@ -64,12 +64,12 @@ enum BattlegroundRVObjects
BG_RV_OBJECT_TYPE_GEAR_2 = 192394,
BG_RV_OBJECT_TYPE_ELEVATOR_1 = 194582,
BG_RV_OBJECT_TYPE_ELEVATOR_2 = 194586,
/*
BG_RV_OBJECT_TYPE_PILAR_COLLISION_1 = 194580, // axe
BG_RV_OBJECT_TYPE_PILAR_COLLISION_2 = 194579, // arena
BG_RV_OBJECT_TYPE_PILAR_COLLISION_3 = 194581, // lightning
BG_RV_OBJECT_TYPE_PILAR_COLLISION_4 = 194578, // ivory
*/
BG_RV_OBJECT_TYPE_PILAR_1 = 194583, // axe
BG_RV_OBJECT_TYPE_PILAR_2 = 194584, // arena
BG_RV_OBJECT_TYPE_PILAR_3 = 194585, // lightning
@@ -129,5 +129,6 @@ class BattlegroundRV : public Battleground
uint32 getState() { return State; };
void setState(uint32 state) { State = state; };
void TogglePillarCollision(bool apply);
};
#endif
+2
View File
@@ -110,6 +110,8 @@ include_directories(
${CMAKE_SOURCE_DIR}/dep/zlib
${CMAKE_SOURCE_DIR}/src/server/collision
${CMAKE_SOURCE_DIR}/src/server/collision/Management
${CMAKE_SOURCE_DIR}/src/server/collision/Models
${CMAKE_SOURCE_DIR}/src/server/collision/Maps
${CMAKE_SOURCE_DIR}/src/server/shared
${CMAKE_SOURCE_DIR}/src/server/shared/Configuration
${CMAKE_SOURCE_DIR}/src/server/shared/Cryptography
+1 -1
View File
@@ -955,7 +955,7 @@ struct FactionTemplateEntry
struct GameObjectDisplayInfoEntry
{
uint32 Displayid; // 0 m_ID
// char* filename; // 1
char* filename; // 1
//uint32 unk1[10]; //2-11
float minX;
float minY;
+1 -1
View File
@@ -52,7 +52,7 @@ const char EmotesEntryfmt[]="nxxiiix";
const char EmotesTextEntryfmt[]="nxixxxxxxxxxxxxxxxx";
const char FactionEntryfmt[]="niiiiiiiiiiiiiiiiiiffixssssssssssssssssxxxxxxxxxxxxxxxxxx";
const char FactionTemplateEntryfmt[]="niiiiiiiiiiiii";
const char GameObjectDisplayInfofmt[]="nxxxxxxxxxxxffffffx";
const char GameObjectDisplayInfofmt[]="nsxxxxxxxxxxffffffx";
const char GemPropertiesEntryfmt[]="nixxi";
const char GlyphPropertiesfmt[]="niii";
const char GlyphSlotfmt[]="nii";
@@ -1289,7 +1289,7 @@ bool Creature::LoadCreatureFromDB(uint32 guid, Map* map, bool addToMap)
m_deathState = DEAD;
if (canFly())
{
float tz = map->GetHeight(data->posX, data->posY, data->posZ, false);
float tz = map->GetHeight(GetPhaseMask(), data->posX, data->posY, data->posZ, false);
if (data->posZ - tz > 0.1f)
Relocate(data->posX, data->posY, tz);
}
@@ -30,7 +30,10 @@
#include "CreatureAISelector.h"
#include "Group.h"
GameObject::GameObject() : WorldObject(false), m_goValue(new GameObjectValue), m_AI(NULL)
#include "GameObjectModel.h"
#include "DynamicTree.h"
GameObject::GameObject() : WorldObject(false), m_goValue(new GameObjectValue), m_AI(NULL), m_model(NULL)
{
m_objectType |= TYPEMASK_GAMEOBJECT;
m_objectTypeId = TYPEID_GAMEOBJECT;
@@ -62,6 +65,7 @@ GameObject::~GameObject()
{
delete m_goValue;
delete m_AI;
delete m_model;
//if (m_uint32Values) // field array can be not exist if GameOBject not loaded
// CleanupsBeforeDelete();
}
@@ -127,6 +131,11 @@ void GameObject::AddToWorld()
m_zoneScript->OnGameObjectCreate(this);
sObjectAccessor->AddObject(this);
bool startOpen = (GetGoType() == GAMEOBJECT_TYPE_DOOR || GetGoType() == GAMEOBJECT_TYPE_BUTTON ? GetGOInfo()->door.startOpen : false);
if (m_model/* && (GetGoType() == GAMEOBJECT_TYPE_DOOR || GetGoType() == GAMEOBJECT_TYPE_BUTTON ? !GetGOInfo()->door.startOpen : true)*/)
GetMap()->Insert(*m_model);
if (startOpen)
EnableCollision(false);
WorldObject::AddToWorld();
}
}
@@ -140,6 +149,9 @@ void GameObject::RemoveFromWorld()
m_zoneScript->OnGameObjectRemove(this);
RemoveFromOwner();
if (m_model)
if (GetMap()->Contains(*m_model))
GetMap()->Remove(*m_model);
WorldObject::RemoveFromWorld();
sObjectAccessor->RemoveObject(this);
}
@@ -199,14 +211,16 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMa
// set name for logs usage, doesn't affect anything ingame
SetName(goinfo->name);
SetUInt32Value(GAMEOBJECT_DISPLAYID, goinfo->displayId);
SetDisplayId(goinfo->displayId);
m_model = GameObjectModel::Create(*this);
// GAMEOBJECT_BYTES_1, index at 0, 1, 2 and 3
SetGoState(go_state);
SetGoType(GameobjectTypes(goinfo->type));
SetGoState(go_state);
SetGoArtKit(0); // unknown what this is
SetByteValue(GAMEOBJECT_BYTES_1, 2, artKit);
switch (goinfo->type)
{
@@ -1779,7 +1793,7 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player*
{
case GO_DESTRUCTIBLE_INTACT:
RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED | GO_FLAG_DESTROYED);
SetUInt32Value(GAMEOBJECT_DISPLAYID, m_goInfo->displayId);
SetDisplayId(m_goInfo->displayId);
if (setHealth)
{
m_goValue->Building.Health = m_goValue->Building.MaxHealth;
@@ -1801,7 +1815,7 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player*
if (DestructibleModelDataEntry const* modelData = sDestructibleModelDataStore.LookupEntry(m_goInfo->building.destructibleData))
if (modelData->DamagedDisplayId)
modelId = modelData->DamagedDisplayId;
SetUInt32Value(GAMEOBJECT_DISPLAYID, modelId);
SetDisplayId(modelId);
if (setHealth)
{
@@ -1834,7 +1848,7 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player*
if (DestructibleModelDataEntry const* modelData = sDestructibleModelDataStore.LookupEntry(m_goInfo->building.destructibleData))
if (modelData->DestroyedDisplayId)
modelId = modelData->DestroyedDisplayId;
SetUInt32Value(GAMEOBJECT_DISPLAYID, modelId);
SetDisplayId(modelId);
if (setHealth)
{
@@ -1852,7 +1866,7 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player*
if (DestructibleModelDataEntry const* modelData = sDestructibleModelDataStore.LookupEntry(m_goInfo->building.destructibleData))
if (modelData->RebuildingDisplayId)
modelId = modelData->RebuildingDisplayId;
SetUInt32Value(GAMEOBJECT_DISPLAYID, modelId);
SetDisplayId(modelId);
// restores to full health
if (setHealth)
@@ -1865,8 +1879,78 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player*
}
}
void GameObject::SetLootState(LootState s, Unit* unit)
void GameObject::SetLootState(LootState state, Unit* unit)
{
m_lootState = s;
AI()->OnStateChanged(s, unit);
m_lootState = state;
AI()->OnStateChanged(state, unit);
if (m_model)
{
// startOpen determines whether we are going to add or remove the LoS on activation
bool startOpen = (GetGoType() == GAMEOBJECT_TYPE_DOOR || GetGoType() == GAMEOBJECT_TYPE_BUTTON ? GetGOInfo()->door.startOpen : false);
if (GetGOData()->go_state == GO_NOT_READY)
startOpen = !startOpen;
if (state == GO_ACTIVATED || state == GO_JUST_DEACTIVATED)
EnableCollision(startOpen);
else if (state == GO_READY)
EnableCollision(!startOpen);
}
}
void GameObject::SetGoState(GOState state)
{
SetByteValue(GAMEOBJECT_BYTES_1, 0, state);
if (m_model)
{
if (!IsInWorld())
return;
// startOpen determines whether we are going to add or remove the LoS on activation
bool startOpen = (GetGoType() == GAMEOBJECT_TYPE_DOOR || GetGoType() == GAMEOBJECT_TYPE_BUTTON ? GetGOInfo()->door.startOpen : false);
if (GetGOData()->go_state == GO_NOT_READY)
startOpen = !startOpen;
if (state == GO_STATE_ACTIVE || state == GO_STATE_ACTIVE_ALTERNATIVE)
EnableCollision(startOpen);
else if (state == GO_STATE_READY)
EnableCollision(!startOpen);
}
}
void GameObject::SetDisplayId(uint32 displayid)
{
SetUInt32Value(GAMEOBJECT_DISPLAYID, displayid);
UpdateModel();
}
void GameObject::SetPhaseMask(uint32 newPhaseMask, bool update)
{
WorldObject::SetPhaseMask(newPhaseMask, update);
EnableCollision(true);
}
void GameObject::EnableCollision(bool enable)
{
if (!m_model)
return;
/*if (enable && !GetMap()->Contains(*m_model))
GetMap()->Insert(*m_model);*/
m_model->enable(enable ? GetPhaseMask() : 0);
}
void GameObject::UpdateModel()
{
if (!IsInWorld())
return;
if (m_model)
if (GetMap()->Contains(*m_model))
GetMap()->Remove(*m_model);
delete m_model;
m_model = GameObjectModel::Create(*this);
if (m_model)
GetMap()->Insert(*m_model);
}
@@ -609,6 +609,7 @@ enum LootState
};
class Unit;
class GameObjectModel;
// 5 sec for bobber catch
#define FISHING_BOBBER_READY_TIME 5
@@ -703,12 +704,15 @@ class GameObject : public WorldObject, public GridObject<GameObject>
GameobjectTypes GetGoType() const { return GameobjectTypes(GetByteValue(GAMEOBJECT_BYTES_1, 1)); }
void SetGoType(GameobjectTypes type) { SetByteValue(GAMEOBJECT_BYTES_1, 1, type); }
GOState GetGoState() const { return GOState(GetByteValue(GAMEOBJECT_BYTES_1, 0)); }
void SetGoState(GOState state) { SetByteValue(GAMEOBJECT_BYTES_1, 0, state); }
void SetGoState(GOState state);
uint8 GetGoArtKit() const { return GetByteValue(GAMEOBJECT_BYTES_1, 2); }
void SetGoArtKit(uint8 artkit);
uint8 GetGoAnimProgress() const { return GetByteValue(GAMEOBJECT_BYTES_1, 3); }
void SetGoAnimProgress(uint8 animprogress) { SetByteValue(GAMEOBJECT_BYTES_1, 3, animprogress); }
static void SetGoArtKit(uint8 artkit, GameObject* go, uint32 lowguid = 0);
void SetPhaseMask(uint32 newPhaseMask, bool update);
void EnableCollision(bool enable);
void Use(Unit* user);
@@ -790,6 +794,9 @@ class GameObject : public WorldObject, public GridObject<GameObject>
GameObjectAI* AI() const { return m_AI; }
std::string GetAIName() const;
void SetDisplayId(uint32 displayid);
GameObjectModel * m_model;
protected:
bool AIM_Initialize();
uint32 m_spellId;
@@ -819,6 +826,7 @@ class GameObject : public WorldObject, public GridObject<GameObject>
private:
void RemoveFromOwner();
void SwitchDoorOrButton(bool activate, bool alternative = false);
void UpdateModel(); // updates model in case displayId were changed
//! Object distance/size - overridden from Object::_IsWithinDist. Needs to take in account proper GO size.
bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool /*is3D*/) const
+17 -12
View File
@@ -46,6 +46,7 @@
#include "Totem.h"
#include "OutdoorPvPMgr.h"
#include "MovementPacketBuilder.h"
#include "DynamicTree.h"
uint32 GuidHigh2TypeId(uint32 guid_hi)
{
@@ -1300,15 +1301,19 @@ bool WorldObject::IsWithinLOSInMap(const WorldObject* obj) const
float ox, oy, oz;
obj->GetPosition(ox, oy, oz);
return(IsWithinLOS(ox, oy, oz));
return IsWithinLOS(ox, oy, oz);
}
bool WorldObject::IsWithinLOS(float ox, float oy, float oz) const
{
float x, y, z;
/*float x, y, z;
GetPosition(x, y, z);
VMAP::IVMapManager* vMapManager = VMAP::VMapFactory::createOrGetVMapManager();
return vMapManager->isInLineOfSight(GetMapId(), x, y, z+2.0f, ox, oy, oz+2.0f);
return vMapManager->isInLineOfSight(GetMapId(), x, y, z+2.0f, ox, oy, oz+2.0f);*/
if (IsInWorld())
return GetMap()->isInLineOfSight(GetPositionX(), GetPositionY(), GetPositionZ()+2.f, ox, oy, oz+2.f, GetPhaseMask());
return true;
}
bool WorldObject::GetDistanceOrder(WorldObject const* obj1, WorldObject const* obj2, bool is3D /* = true */) const
@@ -1530,7 +1535,7 @@ void WorldObject::GetRandomPoint(const Position &pos, float distance, float &ran
void WorldObject::UpdateGroundPositionZ(float x, float y, float &z) const
{
float new_z = GetBaseMap()->GetHeight(x, y, z, true);
float new_z = GetBaseMap()->GetHeight(GetPhaseMask(), x, y, z, true);
if (new_z > INVALID_HEIGHT)
z = new_z+ 0.05f; // just to be sure that we are not a few pixel under the surface
}
@@ -1549,7 +1554,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
float ground_z = z;
float max_z = canSwim
? GetBaseMap()->GetWaterOrGroundLevel(x, y, z, &ground_z, !ToUnit()->HasAuraType(SPELL_AURA_WATER_WALK))
: ((ground_z = GetBaseMap()->GetHeight(x, y, z, true)));
: ((ground_z = GetBaseMap()->GetHeight(GetPhaseMask(), x, y, z, true)));
if (max_z > INVALID_HEIGHT)
{
if (z > max_z)
@@ -1560,7 +1565,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
}
else
{
float ground_z = GetBaseMap()->GetHeight(x, y, z, true);
float ground_z = GetBaseMap()->GetHeight(GetPhaseMask(), x, y, z, true);
if (z < ground_z)
z = ground_z;
}
@@ -1583,7 +1588,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
}
else
{
float ground_z = GetBaseMap()->GetHeight(x, y, z, true);
float ground_z = GetBaseMap()->GetHeight(GetPhaseMask(), x, y, z, true);
if (z < ground_z)
z = ground_z;
}
@@ -1591,7 +1596,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
}
default:
{
float ground_z = GetBaseMap()->GetHeight(x, y, z, true);
float ground_z = GetBaseMap()->GetHeight(GetPhaseMask(), x, y, z, true);
if(ground_z > INVALID_HEIGHT)
z = ground_z;
break;
@@ -2665,8 +2670,8 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float
destx = pos.m_positionX + dist * cos(angle);
desty = pos.m_positionY + dist * sin(angle);
ground = GetMap()->GetHeight(destx, desty, MAX_HEIGHT, true);
floor = GetMap()->GetHeight(destx, desty, pos.m_positionZ, true);
ground = GetMap()->GetHeight(GetPhaseMask(), destx, desty, MAX_HEIGHT, true);
floor = GetMap()->GetHeight(GetPhaseMask(), destx, desty, pos.m_positionZ, true);
destz = fabs(ground - pos.m_positionZ) <= fabs(floor - pos.m_positionZ) ? ground : floor;
bool col = VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(GetMapId(), pos.m_positionX, pos.m_positionY, pos.m_positionZ+0.5f, destx, desty, destz+0.5f, destx, desty, destz, -0.5f);
@@ -2689,8 +2694,8 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float
{
destx -= step * cos(angle);
desty -= step * sin(angle);
ground = GetMap()->GetHeight(destx, desty, MAX_HEIGHT, true);
floor = GetMap()->GetHeight(destx, desty, pos.m_positionZ, true);
ground = GetMap()->GetHeight(GetPhaseMask(), destx, desty, MAX_HEIGHT, true);
floor = GetMap()->GetHeight(GetPhaseMask(), destx, desty, pos.m_positionZ, true);
destz = fabs(ground - pos.m_positionZ) <= fabs(floor - pos.m_positionZ) ? ground : floor;
}
// we have correct destz now
@@ -222,7 +222,7 @@ bool Transport::Create(uint32 guidlow, uint32 entry, uint32 mapid, float x, floa
SetUInt32Value(GAMEOBJECT_LEVEL, m_period);
SetEntry(goinfo->entry);
SetUInt32Value(GAMEOBJECT_DISPLAYID, goinfo->displayId);
SetDisplayId(goinfo->displayId);
SetGoState(GO_STATE_READY);
SetGoType(GameobjectTypes(goinfo->type));
+1 -1
View File
@@ -251,7 +251,7 @@ void WorldSession::HandleCorpseQueryOpcode(WorldPacket & /*recv_data*/)
mapid = corpseMapEntry->entrance_map;
x = corpseMapEntry->entrance_x;
y = corpseMapEntry->entrance_y;
z = entranceMap->GetHeight(x, y, MAX_HEIGHT);
z = entranceMap->GetHeight(GetPlayer()->GetPhaseMask(), x, y, MAX_HEIGHT);
}
}
}
+15 -1
View File
@@ -31,6 +31,7 @@
#include "ObjectMgr.h"
#include "Group.h"
#include "LFGMgr.h"
#include "DynamicTree.h"
union u_map_magic
{
@@ -368,6 +369,7 @@ bool Map::EnsureGridLoaded(const Cell &cell)
// Add resurrectable corpses to world object list in grid
sObjectAccessor->AddCorpsesToGrid(GridCoord(cell.GridX(), cell.GridY()), grid->GetGridType(cell.CellX(), cell.CellY()), this);
Balance();
return true;
}
@@ -498,6 +500,7 @@ void Map::VisitNearbyCellsOf(WorldObject* obj, TypeContainerVisitor<Trinity::Obj
void Map::Update(const uint32 t_diff)
{
m_dyn_tree.update(t_diff);
/// update worldsessions for existing players
for (m_mapRefIter = m_mapRefManager.begin(); m_mapRefIter != m_mapRefManager.end(); ++m_mapRefIter)
{
@@ -1544,7 +1547,7 @@ float Map::GetWaterOrGroundLevel(float x, float y, float z, float* ground /*= NU
if (const_cast<Map*>(this)->GetGrid(x, y))
{
// we need ground level (including grid height version) for proper return water level in point
float ground_z = GetHeight(x, y, z, true, 50.0f);
float ground_z = GetHeight(PHASEMASK_NORMAL, x, y, z, true, 50.0f);
if (ground)
*ground = ground_z;
@@ -1793,6 +1796,17 @@ void Map::GetZoneAndAreaIdByAreaFlag(uint32& zoneid, uint32& areaid, uint16 area
zoneid = entry ? ((entry->zone != 0) ? entry->zone : entry->ID) : 0;
}
bool Map::isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask) const
{
return VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(GetId(), x1, y1, z1, x2, y2, z2)
&& m_dyn_tree.isInLineOfSight(x1, y1, z1, x2, y2, z2, phasemask);
}
float Map::GetHeight(uint32 phasemask, float x, float y, float z, bool vmap/*=true*/, float maxSearchDist/*=DEFAULT_HEIGHT_SEARCH*/) const
{
return std::max<float>(GetHeight(x, y, z, vmap, maxSearchDist), m_dyn_tree.getHeight(x, y, z, maxSearchDist, phasemask));
}
bool Map::IsInWater(float x, float y, float pZ, LiquidData* data) const
{
// Check surface in x, y point for liquid
+9 -1
View File
@@ -30,6 +30,8 @@
#include "SharedDefines.h"
#include "GridRefManager.h"
#include "MapRefManager.h"
#include "DynamicTree.h"
#include "GameObjectModel.h"
#include <bitset>
#include <list>
@@ -425,7 +427,12 @@ class Map : public GridRefManager<NGridType>
InstanceMap* ToInstanceMap(){ if (IsDungeon()) return reinterpret_cast<InstanceMap*>(this); else return NULL; }
const InstanceMap* ToInstanceMap() const { if (IsDungeon()) return (const InstanceMap*)((InstanceMap*)this); else return NULL; }
float GetWaterOrGroundLevel(float x, float y, float z, float* ground = NULL, bool swim = false) const;
float GetHeight(uint32 phasemask, float x, float y, float z, bool vmap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const;
bool isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask) const;
void Balance() { m_dyn_tree.balance(); }
void Remove(const GameObjectModel& mdl) { m_dyn_tree.remove(mdl); }
void Insert(const GameObjectModel& mdl) { m_dyn_tree.insert(mdl); }
bool Contains(const GameObjectModel& mdl) const { return m_dyn_tree.contains(mdl);}
private:
void LoadMapAndVMap(int gx, int gy);
void LoadVMap(int gx, int gy);
@@ -481,6 +488,7 @@ class Map : public GridRefManager<NGridType>
uint32 i_InstanceId;
uint32 m_unloadTimer;
float m_VisibleDistance;
DynamicMapTree m_dyn_tree;
MapRefManager m_mapRefManager;
MapRefManager::iterator m_mapRefIter;
+2 -2
View File
@@ -374,7 +374,7 @@ void MotionMaster::MoveJump(float x, float y, float z, float speedXY, float spee
void MotionMaster::MoveFall(uint32 id/*=0*/)
{
// use larger distance for vmap height search than in most other cases
float tz = i_owner->GetMap()->GetHeight(i_owner->GetPositionX(), i_owner->GetPositionY(), i_owner->GetPositionZ(), true, MAX_FALL_DISTANCE);
float tz = i_owner->GetMap()->GetHeight(i_owner->GetPhaseMask(), i_owner->GetPositionX(), i_owner->GetPositionY(), i_owner->GetPositionZ(), true, MAX_FALL_DISTANCE);
if (tz <= INVALID_HEIGHT)
{
sLog->outStaticDebug("MotionMaster::MoveFall: unable retrive a proper height at map %u (x: %f, y: %f, z: %f).",
@@ -387,7 +387,7 @@ void MotionMaster::MoveFall(uint32 id/*=0*/)
return;
Movement::MoveSplineInit init(*i_owner);
init.MoveTo(i_owner->GetPositionX(),i_owner->GetPositionY(),tz);
init.MoveTo(i_owner->GetPositionX(), i_owner->GetPositionY(), tz);
init.SetFall();
init.Launch();
Mutate(new EffectMovementGenerator(id), MOTION_SLOT_CONTROLLED);
@@ -157,7 +157,7 @@ FleeingMovementGenerator<T>::_getPoint(T &owner, float &x, float &y, float &z)
y = temp_y;
return true;
}
float new_z = _map->GetHeight(temp_x, temp_y, z, true);
float new_z = _map->GetHeight(owner.GetPhaseMask(), temp_x, temp_y, z, true);
if (new_z <= INVALID_HEIGHT)
continue;
@@ -169,8 +169,8 @@ FleeingMovementGenerator<T>::_getPoint(T &owner, float &x, float &y, float &z)
if (!(new_z - z) || distance / fabs(new_z - z) > 1.0f)
{
float new_z_left = _map->GetHeight(temp_x + 1.0f*cos(angle+static_cast<float>(M_PI/2)),temp_y + 1.0f*sin(angle+static_cast<float>(M_PI/2)),z,true);
float new_z_right = _map->GetHeight(temp_x + 1.0f*cos(angle-static_cast<float>(M_PI/2)),temp_y + 1.0f*sin(angle-static_cast<float>(M_PI/2)),z,true);
float new_z_left = _map->GetHeight(owner.GetPhaseMask(), temp_x + 1.0f*cos(angle+static_cast<float>(M_PI/2)),temp_y + 1.0f*sin(angle+static_cast<float>(M_PI/2)),z,true);
float new_z_right = _map->GetHeight(owner.GetPhaseMask(), temp_x + 1.0f*cos(angle-static_cast<float>(M_PI/2)),temp_y + 1.0f*sin(angle-static_cast<float>(M_PI/2)),z,true);
if (fabs(new_z_left - new_z) < 1.2f && fabs(new_z_right - new_z) < 1.2f)
{
x = temp_x;
@@ -33,7 +33,7 @@
#endif
template<>
void RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature)
void RandomMovementGenerator<Creature>::_setRandomLocation(Creature& creature)
{
float respX, respY, respZ, respO, currZ, destX, destY, destZ, travelDistZ;
creature.GetHomePosition(respX, respY, respZ, respO);
@@ -78,17 +78,17 @@ void RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature)
// The fastest way to get an accurate result 90% of the time.
// Better result can be obtained like 99% accuracy with a ray light, but the cost is too high and the code is too long.
destZ = map->GetHeight(destX, destY, respZ+travelDistZ-2.0f, false);
destZ = map->GetHeight(creature.GetPhaseMask(), destX, destY, respZ+travelDistZ-2.0f, false);
if (fabs(destZ - respZ) > travelDistZ) // Map check
{
// Vmap Horizontal or above
destZ = map->GetHeight(destX, destY, respZ - 2.0f, true);
destZ = map->GetHeight(creature.GetPhaseMask(), destX, destY, respZ - 2.0f, true);
if (fabs(destZ - respZ) > travelDistZ)
{
// Vmap Higher
destZ = map->GetHeight(destX, destY, respZ+travelDistZ-2.0f, true);
destZ = map->GetHeight(creature.GetPhaseMask(), destX, destY, respZ+travelDistZ-2.0f, true);
// let's forget this bad coords where a z cannot be find and retry at next tick
if (fabs(destZ - respZ) > travelDistZ)
+1 -1
View File
@@ -5299,7 +5299,7 @@ SpellCastResult Spell::CheckCast(bool strict)
{
float x, y, z;
m_caster->GetPosition(x, y, z);
float ground_Z = m_caster->GetMap()->GetHeight(x, y, z);
float ground_Z = m_caster->GetMap()->GetHeight(m_caster->GetPhaseMask(), x, y, z);
if (fabs(ground_Z - z) < 0.1f)
return SPELL_FAILED_DONT_REPORT;
break;
+5
View File
@@ -1192,6 +1192,8 @@ void World::LoadConfigSettings(bool reload)
sScriptMgr->OnConfigLoad(reload);
}
extern void LoadGameObjectModelList();
/// Initialize the World
void World::SetInitialWorldSettings()
{
@@ -1270,6 +1272,9 @@ void World::SetInitialWorldSettings()
sLog->outString("Loading spell custom attributes...");
sSpellMgr->LoadSpellCustomAttr();
sLog->outString("Loading GameObject models...");
LoadGameObjectModelList();
sLog->outString("Loading Script Names...");
sObjectMgr->LoadScriptNames();