diff options
| author | treeston <treeston.mmoc@gmail.com> | 2017-06-10 15:08:35 +0200 |
|---|---|---|
| committer | Carbenium <carbenium@outlook.com> | 2020-07-16 22:00:28 +0200 |
| commit | 5392212799b669d91c80cf0e9539a3aaa2abbe79 (patch) | |
| tree | 40db1efd019087e801f165ab4ad5f1640237b5f5 /src/server/game | |
| parent | 2e8ce5a70f90392e00bd3e7a76a678423b5432e8 (diff) | |
So, I came in trying to fix gameobject LoS. So I restructured some stuff.
Then it turned out that gameobject LoS is already fixed. So all this does, really, is restructure some stuff.
And remove the hack from Sapphiron because I could.
(cherry picked from commit d57307f63d8deb51003d61163adccce4e2c1bd47)
Diffstat (limited to 'src/server/game')
| -rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 46 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Object.h | 4 | ||||
| -rw-r--r-- | src/server/game/Maps/Map.cpp | 11 | ||||
| -rw-r--r-- | src/server/game/Maps/Map.h | 2 | ||||
| -rw-r--r-- | src/server/game/Miscellaneous/SharedDefines.h | 8 | ||||
| -rw-r--r-- | src/server/game/Spells/Spell.cpp | 18 | ||||
| -rw-r--r-- | src/server/game/World/World.cpp | 3 | ||||
| -rw-r--r-- | src/server/game/World/World.h | 1 |
8 files changed, 53 insertions, 40 deletions
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 0d6384ad52e..4321a39f172 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1003,20 +1003,6 @@ bool WorldObject::_IsWithinDist(WorldObject const* obj, float dist2compare, bool return thisOrTransport->IsInDist2d(objOrObjTransport, maxdist); } -bool WorldObject::IsWithinLOSInMap(const WorldObject* obj, VMAP::ModelIgnoreFlags ignoreFlags) const -{ - if (!IsInMap(obj)) - return false; - - float x, y, z; - if (obj->GetTypeId() == TYPEID_PLAYER) - obj->GetPosition(x, y, z); - else - obj->GetHitSpherePointFor(GetPosition(), x, y, z); - - return IsWithinLOS(x, y, z, ignoreFlags); -} - float WorldObject::GetDistance(const WorldObject* obj) const { float d = GetExactDist(obj) - GetCombatReach() - obj->GetCombatReach(); @@ -1091,12 +1077,17 @@ bool WorldObject::IsWithinDistInMap(WorldObject const* obj, float dist2compare, return obj && IsInMap(obj) && IsInPhase(obj) && _IsWithinDist(obj, dist2compare, is3D, incOwnRadius, incTargetRadius); } -bool WorldObject::IsWithinLOS(float ox, float oy, float oz, VMAP::ModelIgnoreFlags ignoreFlags) const +Position WorldObject::GetHitSpherePointFor(Position const& dest) const +{ + G3D::Vector3 vThis(GetPositionX(), GetPositionY(), GetPositionZ()); + G3D::Vector3 vObj(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ()); + G3D::Vector3 contactPoint = vThis + (vObj - vThis).directionOrZero() * std::min(dest.GetExactDist(GetPosition()), GetCombatReach()); + + return Position(contactPoint.x, contactPoint.y, contactPoint.z, GetAngle(contactPoint.x, contactPoint.y)); +} + +bool WorldObject::IsWithinLOS(float ox, float oy, float oz, LineOfSightChecks checks, VMAP::ModelIgnoreFlags ignoreFlags) const { - /*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);*/ if (IsInWorld()) { float x, y, z; @@ -1105,19 +1096,24 @@ bool WorldObject::IsWithinLOS(float ox, float oy, float oz, VMAP::ModelIgnoreFla else GetHitSpherePointFor({ ox, oy, oz }, x, y, z); - return GetMap()->isInLineOfSight(GetPhaseShift(), x, y, z + 2.0f, ox, oy, oz + 2.0f, ignoreFlags); + return GetMap()->isInLineOfSight(GetPhaseShift(), x, y, z + 2.0f, ox, oy, oz + 2.0f, checks, ignoreFlags); } return true; } -Position WorldObject::GetHitSpherePointFor(Position const& dest) const +bool WorldObject::IsWithinLOSInMap(const WorldObject* obj, LineOfSightChecks checks, VMAP::ModelIgnoreFlags ignoreFlags) const { - G3D::Vector3 vThis(GetPositionX(), GetPositionY(), GetPositionZ()); - G3D::Vector3 vObj(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ()); - G3D::Vector3 contactPoint = vThis + (vObj - vThis).directionOrZero() * std::min(dest.GetExactDist(GetPosition()), GetCombatReach()); + if (!IsInMap(obj)) + return false; - return Position(contactPoint.x, contactPoint.y, contactPoint.z, GetAngle(contactPoint.x, contactPoint.y)); + float x, y, z; + if (obj->GetTypeId() == TYPEID_PLAYER) + obj->GetPosition(x, y, z); + else + obj->GetHitSpherePointFor(GetPosition(), x, y, z); + + return IsWithinLOS(x, y, z, checks, ignoreFlags); } void WorldObject::GetHitSpherePointFor(Position const& dest, float& x, float& y, float& z) const diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 7339cc2df96..8b6f6dc8a5c 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -448,8 +448,8 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation // use only if you will sure about placing both object at same map bool IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D = true) const; bool IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D = true, bool incOwnRadius = true, bool incTargetRadius = true) const; - bool IsWithinLOS(float x, float y, float z, VMAP::ModelIgnoreFlags ignoreFlags = VMAP::ModelIgnoreFlags::Nothing) const; - bool IsWithinLOSInMap(WorldObject const* obj, VMAP::ModelIgnoreFlags ignoreFlags = VMAP::ModelIgnoreFlags::Nothing) const; + bool IsWithinLOS(float x, float y, float z, LineOfSightChecks checks = LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags ignoreFlags = VMAP::ModelIgnoreFlags::Nothing) const; + bool IsWithinLOSInMap(WorldObject const* obj, LineOfSightChecks checks = LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags ignoreFlags = VMAP::ModelIgnoreFlags::Nothing) const; Position GetHitSpherePointFor(Position const& dest) const; void GetHitSpherePointFor(Position const& dest, float& x, float& y, float& z) const; bool GetDistanceOrder(WorldObject const* obj1, WorldObject const* obj2, bool is3D = true) const; diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 715723f6425..fa2b4ec1508 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -3040,10 +3040,15 @@ float Map::GetWaterLevel(PhaseShift const& phaseShift, float x, float y) return 0; } -bool Map::isInLineOfSight(PhaseShift const& phaseShift, float x1, float y1, float z1, float x2, float y2, float z2, VMAP::ModelIgnoreFlags ignoreFlags) const +bool Map::isInLineOfSight(PhaseShift const& phaseShift, float x1, float y1, float z1, float x2, float y2, float z2, LineOfSightChecks checks, VMAP::ModelIgnoreFlags ignoreFlags) const { - return VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(PhasingHandler::GetTerrainMapId(phaseShift, this, x1, y1), x1, y1, z1, x2, y2, z2, ignoreFlags) - && _dynamicTree.isInLineOfSight({ x1, y1, z1 }, { x2, y2, z2 }, phaseShift); + if ((checks & LINEOFSIGHT_CHECK_VMAP) + && !VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(PhasingHandler::GetTerrainMapId(phaseShift, this, x1, y1), x1, y1, z1, x2, y2, z2, ignoreFlags)) + return false; + if (sWorld->getBoolConfig(CONFIG_CHECK_GOBJECT_LOS) && (checks & LINEOFSIGHT_CHECK_GOBJECT) + && !_dynamicTree.isInLineOfSight({ x1, y1, z1 }, { x2, y2, z2 }, phaseShift)) + return false; + return true; } bool Map::getObjectHitPos(PhaseShift const& phaseShift, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float& ry, float& rz, float modifyDist) diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index faf1fc4ca1b..d3cf1ab7136 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -526,7 +526,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType> float GetWaterOrGroundLevel(PhaseShift const& phaseShift, float x, float y, float z, float* ground = nullptr, bool swim = false); float GetHeight(PhaseShift const& phaseShift, float x, float y, float z, bool vmap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH); - bool isInLineOfSight(PhaseShift const& phaseShift, float x1, float y1, float z1, float x2, float y2, float z2, VMAP::ModelIgnoreFlags ignoreFlags) const; + bool isInLineOfSight(PhaseShift const& phaseShift, float x1, float y1, float z1, float x2, float y2, float z2, LineOfSightChecks checks, VMAP::ModelIgnoreFlags ignoreFlags) const; void Balance() { _dynamicTree.balance(); } void RemoveGameObjectModel(const GameObjectModel& model) { _dynamicTree.remove(model); } void InsertGameObjectModel(const GameObjectModel& model) { _dynamicTree.insert(model); } diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 378f8ad4217..068746b7e35 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -5486,6 +5486,14 @@ enum CharterTypes ARENA_TEAM_CHARTER_5v5_TYPE = 5 }; +enum LineOfSightChecks : uint8 +{ + LINEOFSIGHT_CHECK_VMAP = 0x1, // check static floor layout data + LINEOFSIGHT_CHECK_GOBJECT = 0x2, // check dynamic game object data + + LINEOFSIGHT_ALL_CHECKS = (LINEOFSIGHT_CHECK_VMAP | LINEOFSIGHT_CHECK_GOBJECT) +}; + enum TokenResult { TOKEN_RESULT_SUCCESS = 0, diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 938aa7da363..75b8a94a535 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -1940,7 +1940,7 @@ void Spell::SearchChainTargets(std::list<WorldObject*>& targets, uint32 chainTar if (Unit* unit = (*itr)->ToUnit()) { uint32 deficit = unit->GetMaxHealth() - unit->GetHealth(); - if ((deficit > maxHPDeficit || foundItr == tempTargets.end()) && target->IsWithinDist(unit, jumpRadius) && target->IsWithinLOSInMap(unit, VMAP::ModelIgnoreFlags::M2)) + if ((deficit > maxHPDeficit || foundItr == tempTargets.end()) && target->IsWithinDist(unit, jumpRadius) && target->IsWithinLOSInMap(unit, LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags::M2)) { foundItr = itr; maxHPDeficit = deficit; @@ -1955,10 +1955,10 @@ void Spell::SearchChainTargets(std::list<WorldObject*>& targets, uint32 chainTar { if (foundItr == tempTargets.end()) { - if ((!isBouncingFar || target->IsWithinDist(*itr, jumpRadius)) && target->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2)) + if ((!isBouncingFar || target->IsWithinDist(*itr, jumpRadius)) && target->IsWithinLOSInMap(*itr, LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags::M2)) foundItr = itr; } - else if (target->GetDistanceOrder(*itr, *foundItr) && target->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2)) + else if (target->GetDistanceOrder(*itr, *foundItr) && target->IsWithinLOSInMap(*itr, LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags::M2)) foundItr = itr; } } @@ -5090,7 +5090,7 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint if (DynamicObject* dynObj = m_caster->GetDynObject(m_triggeredByAuraSpell->Id)) losTarget = dynObj; - if (!m_spellInfo->HasAttribute(SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, NULL, SPELL_DISABLE_LOS) && !target->IsWithinLOSInMap(losTarget, VMAP::ModelIgnoreFlags::M2)) + if (!m_spellInfo->HasAttribute(SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, NULL, SPELL_DISABLE_LOS) && !target->IsWithinLOSInMap(losTarget, LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags::M2)) return SPELL_FAILED_LINE_OF_SIGHT; } } @@ -5102,7 +5102,7 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint float x, y, z; m_targets.GetDstPos()->GetPosition(x, y, z); - if (!m_spellInfo->HasAttribute(SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, NULL, SPELL_DISABLE_LOS) && !m_caster->IsWithinLOS(x, y, z, VMAP::ModelIgnoreFlags::M2)) + if (!m_spellInfo->HasAttribute(SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, NULL, SPELL_DISABLE_LOS) && !m_caster->IsWithinLOS(x, y, z, LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags::M2)) return SPELL_FAILED_LINE_OF_SIGHT; } @@ -7061,7 +7061,7 @@ bool Spell::CheckEffectTarget(Unit const* target, SpellEffectInfo const* effect, { if (!m_targets.GetCorpseTargetGUID()) { - if (target->IsWithinLOSInMap(m_caster, VMAP::ModelIgnoreFlags::M2) && target->HasUnitFlag(UNIT_FLAG_SKINNABLE)) + if (target->IsWithinLOSInMap(m_caster, LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags::M2) && target->HasUnitFlag(UNIT_FLAG_SKINNABLE)) return true; return false; @@ -7077,7 +7077,7 @@ bool Spell::CheckEffectTarget(Unit const* target, SpellEffectInfo const* effect, if (!corpse->HasDynamicFlag(CORPSE_DYNFLAG_LOOTABLE)) return false; - if (!corpse->IsWithinLOSInMap(m_caster, VMAP::ModelIgnoreFlags::M2)) + if (!corpse->IsWithinLOSInMap(m_caster, LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags::M2)) return false; break; @@ -7085,7 +7085,7 @@ bool Spell::CheckEffectTarget(Unit const* target, SpellEffectInfo const* effect, default: { if (losPosition) - return target->IsWithinLOS(losPosition->GetPositionX(), losPosition->GetPositionY(), losPosition->GetPositionZ(), VMAP::ModelIgnoreFlags::M2); + return target->IsWithinLOS(losPosition->GetPositionX(), losPosition->GetPositionY(), losPosition->GetPositionZ(), LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags::M2); else { // Get GO cast coordinates if original caster -> GO @@ -7094,7 +7094,7 @@ bool Spell::CheckEffectTarget(Unit const* target, SpellEffectInfo const* effect, caster = m_caster->GetMap()->GetGameObject(m_originalCasterGUID); if (!caster) caster = m_caster; - if (target != m_caster && !target->IsWithinLOSInMap(caster, VMAP::ModelIgnoreFlags::M2)) + if (target != m_caster && !target->IsWithinLOSInMap(caster, LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags::M2)) return false; } } diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index f397743689a..828db2cd210 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1496,6 +1496,9 @@ void World::LoadConfigSettings(bool reload) m_bool_configs[CONFIG_CREATURE_CHECK_INVALID_POSITION] = sConfigMgr->GetBoolDefault("Creature.CheckInvalidPosition", false); m_bool_configs[CONFIG_GAME_OBJECT_CHECK_INVALID_POSITION] = sConfigMgr->GetBoolDefault("GameObject.CheckInvalidPosition", false); + // Whether to use LoS from game objects + m_bool_configs[CONFIG_CHECK_GOBJECT_LOS] = sConfigMgr->GetBoolDefault("CheckGameObjectLoS", true); + // call ScriptMgr if we're reloading the configuration if (reload) sScriptMgr->OnConfigLoad(reload); diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index a352306edfc..d68b9726e87 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -192,6 +192,7 @@ enum WorldBoolConfigs CONFIG_CACHE_DATA_QUERIES, CONFIG_CREATURE_CHECK_INVALID_POSITION, CONFIG_GAME_OBJECT_CHECK_INVALID_POSITION, + CONFIG_CHECK_GOBJECT_LOS, BOOL_CONFIG_VALUE_COUNT }; |
