Unit pushing: fix pairs of unit being allowed to overlap.

Following 40cbde1925, the minimum pushing force is 0.2. This also
happens to be the maximum pushing force any pair of units can exert on
each other, so they can freely overlap instead of being pushed.

This tweaks settings slightly to fix that problem.

Reported by: marder
Differential Revision: https://code.wildfiregames.com/D4129
This was SVN commit r25748.
This commit is contained in:
wraitii 2021-06-08 16:38:06 +00:00
parent 83703992c9
commit 870e689e5f
2 changed files with 10 additions and 4 deletions

View File

@ -26,6 +26,8 @@
<!-- if the value is below this number, treat it as effectively zero. -->
<!-- This nullifies very small pushes, and makes things look and behave nicer. -->
<!-- NB: This impacts the pushing max distance. -->
<!-- NB: If this is 0.25 or above, then pairs of units will overlap -->
<!-- See MAX_DISTANCE_FACTOR in CCmpUnitMotion_System.cpp for details.-->
<MinimalForce>0.2</MinimalForce>
</Pushing>

View File

@ -52,8 +52,11 @@ namespace {
/**
* Maximum distance multiplier.
* NB: this value interacts with the "minimal pushing" force,
* as two perfectly overlapping units exert MAX_DISTANCE_FACTOR * Turn length in ms / REDUCTION_FACTOR
* of force on each other each turn. If this is below the minimal pushing force, any 2 units can entirely overlap.
*/
static const entity_pos_t MAX_DISTANCE_FACTOR = entity_pos_t::FromInt(2);
static const entity_pos_t MAX_DISTANCE_FACTOR = entity_pos_t::FromInt(5) / 2;
}
CCmpUnitMotionManager::MotionState::MotionState(CmpPtr<ICmpPosition> cmpPos, CCmpUnitMotion* cmpMotion)
@ -297,7 +300,7 @@ void CCmpUnitMotionManager::Push(EntityMap<MotionState>::value_type& a, EntityMa
bool dir = a.first % 2;
offset.X = entity_pos_t::FromInt(dir ? 1 : 0);
offset.Y = entity_pos_t::FromInt(dir ? 0 : 1);
offsetLength = entity_pos_t::FromInt(1);
offsetLength = entity_pos_t::Epsilon() * 10;
}
else
{
@ -320,9 +323,10 @@ void CCmpUnitMotionManager::Push(EntityMap<MotionState>::value_type& a, EntityMa
offsetLength = fixed::Zero();
}
// The formula expects 'normal' pushing if the two entities edges are touching.
// The pushing distance factor is 1 if the edges are touching, >1 up to MAX if the units overlap, < 1 otherwise.
entity_pos_t distanceFactor = maxDist - combinedClearance;
if (distanceFactor <= entity_pos_t::Zero())
// Force units that overlap a lot to have the maximum factor.
if (distanceFactor <= entity_pos_t::Zero() || offsetLength < combinedClearance / 2)
distanceFactor = MAX_DISTANCE_FACTOR;
else
distanceFactor = Clamp((maxDist - offsetLength) / distanceFactor, entity_pos_t::Zero(), MAX_DISTANCE_FACTOR);