Index: src/game/Map.cpp =================================================================== --- src/game/Map.cpp (revision 5470) +++ src/game/Map.cpp (working copy) @@ -1166,6 +1166,87 @@ } } +float Map::GetBlinkHeight(float x, float y, float z, bool pUseVmaps) const +{ + GridPair p = MaNGOS::ComputeGridPair(x, y); + + int gx=(int)(32-x/SIZE_OF_GRIDS); + int gy=(int)(32-y/SIZE_OF_GRIDS); + + float lx=MAP_RESOLUTION*(32 -x/SIZE_OF_GRIDS - gx); + float ly=MAP_RESOLUTION*(32 -y/SIZE_OF_GRIDS - gy); + + const_cast(this)->EnsureGridCreated(GridPair(63-gx,63-gy)); + + float mapHeight; + if(GridMaps[gx][gy]) + { + float _mapheight = GridMaps[gx][gy]->Z[(int)(lx)][(int)(ly)]; + + if(z + 12 > _mapheight) + mapHeight = _mapheight; + else + mapHeight = VMAP_INVALID_HEIGHT_VALUE; + } + else + mapHeight = VMAP_INVALID_HEIGHT_VALUE; + + float vmapHeight; + if(pUseVmaps) + { + VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager(); + if(vmgr->isHeightCalcEnabled()) + { + float zz = z; + float _vmapheight; + vmapHeight = vmgr->getHeight(GetId(), x, y, zz); + if(vmapHeight < -499) + { + zz = z + 12; + vmapHeight = vmgr->getHeight(GetId(), x, y, zz); + } + if(vmapHeight < -499) + { + zz = z - 12; + vmapHeight = vmgr->getHeight(GetId(), x, y, zz); + } + zz = z + 20; + _vmapheight = vmgr->getHeight(GetId(), x, y, zz); + if(_vmapheight > -499) + vmapHeight = _vmapheight; + zz = z + 30; + _vmapheight = vmgr->getHeight(GetId(), x, y, zz); + if(_vmapheight > -499) + vmapHeight = _vmapheight; + // sLog.outError("BlinkHeight VMAPS: %f - z = %f", vmapHeight, z); + } + else + vmapHeight = VMAP_INVALID_HEIGHT_VALUE; + } + else + vmapHeight = VMAP_INVALID_HEIGHT_VALUE; + + if( vmapHeight > INVALID_HEIGHT ) + { + if( mapHeight > INVALID_HEIGHT ) + { + if(pUseVmaps) + return vmapHeight; + else + return mapHeight; + } + else + return vmapHeight; + } + else + { + if(!pUseVmaps) + return mapHeight; + else + return VMAP_INVALID_HEIGHT_VALUE; + } +} + uint16 Map::GetAreaFlag(float x, float y ) const { //local x,y coords Index: src/game/Map.h =================================================================== --- src/game/Map.h (revision 5470) +++ src/game/Map.h (working copy) @@ -171,6 +171,7 @@ // some calls like isInWater should not use vmaps due to processor power // can return INVALID_HEIGHT if under z+2 z coord not found height float GetHeight(float x, float y, float z, bool pCheckVMap=true) const; + float GetBlinkHeight(float x, float y, float z, bool pCheckVMap=true) const; bool IsInWater(float x, float y, float z) const; // does not use z pos. This is for future use uint16 GetAreaFlag(float x, float y ) const; Index: src/game/Spell.cpp =================================================================== --- src/game/Spell.cpp (revision 5470) +++ src/game/Spell.cpp (working copy) @@ -3288,16 +3288,25 @@ float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); float fx = m_caster->GetPositionX() + dis * cos(m_caster->GetOrientation()); float fy = m_caster->GetPositionY() + dis * sin(m_caster->GetOrientation()); + float caster_pos_z = m_caster->GetPositionZ(); // teleport a bit above terrainlevel to avoid falling below it - float fz = MapManager::Instance().GetBaseMap(m_caster->GetMapId())->GetHeight(fx,fy,m_caster->GetPositionZ(),true); - if(fz <= INVALID_HEIGHT) // note: this also will prevent use effect in instances without vmaps height enabled - return SPELL_FAILED_TRY_AGAIN; + float fz = MapManager::Instance().GetBaseMap(m_caster->GetMapId())->GetBlinkHeight(fx,fy,caster_pos_z,true); + float fz2 = MapManager::Instance().GetBaseMap(m_caster->GetMapId())->GetBlinkHeight(fx,fy,caster_pos_z,false); + float fz3 = MapManager::Instance().GetBaseMap(m_caster->GetMapId())->GetHeight(fx,fy,MAX_HEIGHT,false); + + if(fz > -499) + { + if(fz > caster_pos_z + 12 || fz < caster_pos_z - 12) + { + return SPELL_FAILED_TRY_AGAIN; + } + } + else + if((fz2 > caster_pos_z + 12 || fz2 < caster_pos_z - 12) || (fz2 > caster_pos_z - 12 && fz2 < fz3)) + { + return SPELL_FAILED_TRY_AGAIN; + } - float caster_pos_z = m_caster->GetPositionZ(); - // Control the caster to not climb or drop when +-fz > 8 - if(!(fz<=caster_pos_z+8 && fz>=caster_pos_z-8)) - return SPELL_FAILED_TRY_AGAIN; - // not allow use this effect at battleground until battleground start if(m_caster->GetTypeId()==TYPEID_PLAYER) if(BattleGround const *bg = ((Player*)m_caster)->GetBattleGround()) Index: src/game/SpellEffects.cpp =================================================================== --- src/game/SpellEffects.cpp (revision 5470) +++ src/game/SpellEffects.cpp (working copy) @@ -4272,24 +4272,25 @@ float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); // before caster - float fx,fy,fz; - unitTarget->GetClosePoint(fx,fy,fz,dis); - float ox,oy,oz; - unitTarget->GetPosition(ox,oy,oz); - - float fx2,fy2,fz2; // getObjectHitPos overwrite last args in any result case - if(VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(mapid, ox,oy,oz+0.5, fx,fy,oz+0.5,fx2,fy2,fz2, -0.5)) + float fx = m_caster->GetPositionX() + dis * cos(m_caster->GetOrientation()); + float fy = m_caster->GetPositionY() + dis * sin(m_caster->GetOrientation()); + float caster_pos_z = m_caster->GetPositionZ(); + float fz = MapManager::Instance().GetBaseMap(m_caster->GetMapId())->GetBlinkHeight(fx,fy,caster_pos_z,true); + float fz2 = MapManager::Instance().GetBaseMap(m_caster->GetMapId())->GetBlinkHeight(fx,fy,caster_pos_z,false); + float fz3 = MapManager::Instance().GetBaseMap(m_caster->GetMapId())->GetHeight(fx,fy,MAX_HEIGHT,false); + if(fz < fz3) { - fx = fx2; - fy = fy2; - fz = fz2; + if(fz2 > fz3) + fz = fz2; + else + fz = fz3; + } + else unitTarget->UpdateGroundPositionZ(fx,fy,fz); - } - if(unitTarget->GetTypeId() == TYPEID_PLAYER) - ((Player*)unitTarget)->TeleportTo(mapid, fx, fy, fz, unitTarget->GetOrientation(), false); + ((Player*)unitTarget)->TeleportTo(mapid, fx, fy, fz + 1, unitTarget->GetOrientation(), false); else - MapManager::Instance().GetMap(mapid, unitTarget)->CreatureRelocation((Creature*)unitTarget, fx, fy, fz, unitTarget->GetOrientation()); + MapManager::Instance().GetMap(mapid, unitTarget)->CreatureRelocation((Creature*)unitTarget, fx, fy, fz + 1, unitTarget->GetOrientation()); } }