diff --git a/src/game/Entities/Object/Object.cpp b/src/game/Entities/Object/Object.cpp index f3091758f..9590bd35e 100644 --- a/src/game/Entities/Object/Object.cpp +++ b/src/game/Entities/Object/Object.cpp @@ -2402,123 +2402,33 @@ void WorldObject::GetNearPoint(WorldObject const* searcher, float &x, float &y, else UpdateAllowedPositionZ(x, y, z); - /* // if detection disabled, return first point - if (!sWorld->getIntConfig(CONFIG_DETECT_POS_COLLISION)) - { - UpdateGroundPositionZ(x, y, z); // update to LOS height if available + if (!sWorld->getBoolConfig(CONFIG_DETECT_POS_COLLISION)) return; - } - // or remember first point + // return if the point is already in LoS + if (IsWithinLOS(x, y, z)) + return; + + // remember first point float first_x = x; float first_y = y; - bool first_los_conflict = false; // first point LOS problems + float first_z = z; - // prepare selector for work - ObjectPosSelector selector(GetPositionX(), GetPositionY(), GetObjectSize(), distance2d+searcher_size); - - // adding used positions around object + // loop in a circle to look for a point in LoS using small steps + for (float angle = float(M_PI) / 8; angle < float(M_PI) * 2; angle += float(M_PI) / 8) { - CellCoord p(Trinity::ComputeCellCoord(GetPositionX(), GetPositionY())); - Cell cell(p); - cell.SetNoCreate(); - - Trinity::NearUsedPosDo u_do(*this, searcher, absAngle, selector); - Trinity::WorldObjectWorker worker(this, u_do); - - TypeContainerVisitor, GridTypeMapContainer > grid_obj_worker(worker); - TypeContainerVisitor, WorldTypeMapContainer > world_obj_worker(worker); - - CellLock cell_lock(cell, p); - cell_lock->Visit(cell_lock, grid_obj_worker, *GetMap(), *this, distance2d); - cell_lock->Visit(cell_lock, world_obj_worker, *GetMap(), *this, distance2d); - } - - // maybe can just place in primary position - if (selector.CheckOriginal()) - { - UpdateGroundPositionZ(x, y, z); // update to LOS height if available - - if (IsWithinLOS(x, y, z)) - return; - - first_los_conflict = true; // first point have LOS problems - } - - float angle; // candidate of angle for free pos - - // special case when one from list empty and then empty side preferred - if (selector.FirstAngle(angle)) - { - GetNearPoint2D(x, y, distance2d, absAngle+angle); + GetNearPoint2D(x, y, distance2d + searcher_size, absAngle + angle); z = GetPositionZ(); - UpdateGroundPositionZ(x, y, z); // update to LOS height if available - + UpdateAllowedPositionZ(x, y, z); if (IsWithinLOS(x, y, z)) return; } - // set first used pos in lists - selector.InitializeAngle(); - - // select in positions after current nodes (selection one by one) - while (selector.NextAngle(angle)) // angle for free pos - { - GetNearPoint2D(x, y, distance2d, absAngle+angle); - z = GetPositionZ(); - UpdateGroundPositionZ(x, y, z); // update to LOS height if available - - if (IsWithinLOS(x, y, z)) - return; - } - - // BAD NEWS: not free pos (or used or have LOS problems) - // Attempt find _used_ pos without LOS problem - - if (!first_los_conflict) - { - x = first_x; - y = first_y; - - UpdateGroundPositionZ(x, y, z); // update to LOS height if available - return; - } - - // special case when one from list empty and then empty side preferred - if (selector.IsNonBalanced()) - { - if (!selector.FirstAngle(angle)) // _used_ pos - { - GetNearPoint2D(x, y, distance2d, absAngle+angle); - z = GetPositionZ(); - UpdateGroundPositionZ(x, y, z); // update to LOS height if available - - if (IsWithinLOS(x, y, z)) - return; - } - } - - // set first used pos in lists - selector.InitializeAngle(); - - // select in positions after current nodes (selection one by one) - while (selector.NextUsedAngle(angle)) // angle for used pos but maybe without LOS problem - { - GetNearPoint2D(x, y, distance2d, absAngle+angle); - z = GetPositionZ(); - UpdateGroundPositionZ(x, y, z); // update to LOS height if available - - if (IsWithinLOS(x, y, z)) - return; - } - - // BAD BAD NEWS: all found pos (free and used) have LOS problem :( + // still not in LoS, give up and return first position found x = first_x; y = first_y; - - UpdateGroundPositionZ(x, y, z); // update to LOS height if available - */ + z = first_z; } bool WorldObject::GetClosePoint(float &x, float &y, float &z, float size, float distance2d, float angle, const WorldObject* forWho, bool force) const diff --git a/src/game/Spells/Spell.cpp b/src/game/Spells/Spell.cpp index faa6c12c0..28fed7f77 100644 --- a/src/game/Spells/Spell.cpp +++ b/src/game/Spells/Spell.cpp @@ -1306,7 +1306,8 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis; float x, y, z, angle; angle = (float)rand_norm() * static_cast(M_PI * 35.0f / 180.0f) - static_cast(M_PI * 17.5f / 180.0f); - m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dis, angle); + //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dis, angle); this contains extra code that breaks fishing + m_caster->GetNearPoint(m_caster, x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dis, m_caster->GetOrientation() + angle); float ground = m_caster->GetMap()->GetHeight(m_caster->GetPhaseMask(), x, y, z, true, 120.0f); float liquidLevel = VMAP_INVALID_HEIGHT_VALUE;