diff --git a/rts/Game/TraceRay.cpp b/rts/Game/TraceRay.cpp index 3323b8f081..3e31f2c0bc 100644 --- a/rts/Game/TraceRay.cpp +++ b/rts/Game/TraceRay.cpp @@ -18,6 +18,7 @@ #include "Sim/Units/UnitTypes/Factory.h" #include "Sim/Weapons/PlasmaRepulser.h" #include "Sim/Weapons/WeaponDef.h" +#include "System/GlobalConfig.h" #include "System/SpringMath.h" #include @@ -403,10 +404,24 @@ float GuiTraceRay( if (groundOnly) return minRayLength; + // set maximum ray until ground intersection taking lenience into account later + float maxRayLength; + if (minRayLength >= 0.0) { + // normal intersection + maxRayLength = minRayLength; + } else if (waterRayLength >= 0.0) { + // out of map we still want to intersect somewhere if possible + maxRayLength = waterRayLength; + } else { + // pointing upwards + maxRayLength = length; + } + maxRayLength = std::min(maxRayLength + globalConfig.selectThroughGround, length); + CollisionQuery cq; QuadFieldQuery qfQuery; - quadField.GetQuadsOnRay(qfQuery, start, dir, length); + quadField.GetQuadsOnRay(qfQuery, start, dir, maxRayLength); for (const int quadIdx: *qfQuery.quads) { const CQuadField::Quad& quad = quadField.GetQuad(quadIdx); @@ -493,7 +508,7 @@ float GuiTraceRay( } } - if ((minRayLength > 0.0f) && ((minRayLength + 200.0f) < minIngressDist)) { + if ((minRayLength > 0.0f) && (maxRayLength < minIngressDist)) { minIngressDist = minRayLength; hitUnit = nullptr; diff --git a/rts/System/GlobalConfig.cpp b/rts/System/GlobalConfig.cpp index 725a72d949..a075d8a871 100644 --- a/rts/System/GlobalConfig.cpp +++ b/rts/System/GlobalConfig.cpp @@ -65,6 +65,8 @@ CONFIG(bool, DumpGameStateOnDesync).defaultValue(true).description("Enable writi CONFIG(float, MinSimDrawBalance).defaultValue(0.15f).description("Percent of the time for simulation is minimum spend for drawing. E.g. if set to 0.15 then 15% of the total cpu time is exclusively reserved for drawing."); CONFIG(int, MinDrawFPS).defaultValue(2).description("Defines how many frames per second should minimally be rendered. To reach this number we will delay simframes."); +CONFIG(float, SelectThroughGround).defaultValue(200.0f).minimumValue(0.0f).description("How far beyond the ground to allow selecting objects."); + void GlobalConfig::Init() { // Recommended semantics for "expert" type config values: @@ -98,6 +100,8 @@ void GlobalConfig::Init() minDrawFPS = configHandler->GetInt("MinDrawFPS"); teamHighlight = configHandler->GetInt("TeamHighlight"); + + selectThroughGround = configHandler->GetFloat("SelectThroughGround"); } #endif diff --git a/rts/System/GlobalConfig.h b/rts/System/GlobalConfig.h index fca18fec0d..014b404522 100644 --- a/rts/System/GlobalConfig.h +++ b/rts/System/GlobalConfig.h @@ -141,6 +141,13 @@ class GlobalConfig { * rendered. To reach this number we will delay simframes. */ int minDrawFPS; + + /** + * @brief selection ground penetration + * + * Defines how far beyond the ground to allow selecting objects. + */ + float selectThroughGround; }; extern GlobalConfig globalConfig;