]> git.lizzy.rs Git - shadowclad.git/commitdiff
Resolve slides before crossing cell boundaries so we don't get stuck on corners
authoroutfrost <kotlet.bahn@gmail.com>
Sun, 20 Sep 2020 23:58:33 +0000 (01:58 +0200)
committeroutfrost <kotlet.bahn@gmail.com>
Sun, 20 Sep 2020 23:58:33 +0000 (01:58 +0200)
src/game/player.c

index 52d747f96c3f31d320227dc0bacc774e732f2c05..a56cae9aab7f3d7a76fc8aee2744bc385e9b58f8 100644 (file)
@@ -82,9 +82,6 @@ static void movePlayer(Vector direction, float delta) {
        direction = clampMagnitude(direction, 1.0f);
        Vector displacement = scaleVector(direction, delta * movementSpeed);
 
-//{
-//Vector displacement = scaleVector(direction, 0.006944f * movementSpeed * 1000.0f);
-
        playerProjectedMovement->transform = playerCharacter->transform;
 
        Vector initialPosition = translationOf(playerCharacter->transform);
@@ -181,66 +178,65 @@ static void movePlayer(Vector direction, float delta) {
                distanceZp -= displacementToLimit.z;
                distanceZn -= displacementToLimit.z;
 
-               // Resolve slides and crossing cell boundaries
-               // in reverse order to direct movement limits, because
-               // we only want to cross the closest cell boundary.
-               if (reachedZn) {
-                       if (obstacle & OBSTACLE_ZN) {
-                               float dx = clamp(displacement.x, distanceXn, distanceXp);
-                               position.x += dx;
-                               displacement = scaleVector(displacement, 1.0f - (dx / displacement.x));
+               // Slide along obstacles
+               if ((reachedXp && obstacle & OBSTACLE_XP)
+                       || (reachedXn && obstacle & OBSTACLE_XN))
+               {
+                       float dz = displacement.z;
+                       if (dz > distanceZp) {
+                               dz = distanceZp;
+                               reachedZp = true;
                        }
-                       else {
-                               location.z -= 1;
-                               enteredNewCell = true;
+                       if (dz < distanceZn) {
+                               dz = distanceZn;
+                               reachedZn = true;
                        }
+                       position.z += dz;
+                       displacement = scaleVector(displacement, 1.0f - (dz / displacement.z));
                }
 
-               if (reachedZp) {
-                       if (obstacle & OBSTACLE_ZP) {
-                               float dx = clamp(displacement.x, distanceXn, distanceXp);
-                               position.x += dx;
-                               displacement = scaleVector(displacement, 1.0f - (dx / displacement.x));
+               if ((reachedZp && obstacle & OBSTACLE_ZP)
+                       || (reachedZn && obstacle & OBSTACLE_ZN))
+               {
+                       float dx = displacement.x;
+                       if (dx > distanceXp) {
+                               dx = distanceXp;
+                               reachedXp = true;
                        }
-                       else if (!enteredNewCell) {
-                               location.z += 1;
-                               enteredNewCell = true;
+                       if (dx < distanceXn) {
+                               dx = distanceXn;
+                               reachedXn = true;
                        }
+                       position.x += dx;
+                       displacement = scaleVector(displacement, 1.0f - (dx / displacement.x));
                }
 
-               if (reachedXn) {
-                       if (obstacle & OBSTACLE_XN) {
-                               float dz = clamp(displacement.z, distanceZn, distanceZp);
-                               position.z += dz;
-                               displacement = scaleVector(displacement, 1.0f - (dz / displacement.z));
-                       }
-                       else if (!enteredNewCell) {
-                               location.x -= 1;
-                               enteredNewCell = true;
-                       }
+               // Resolve crossing cell boundaries
+               // in reverse order to direct movement limits, because
+               // we only want to cross the closest cell boundary.
+               if (reachedZn && !(obstacle & OBSTACLE_ZN)) {
+                       // Enter new grid cell
+                       location.z -= 1;
+                       enteredNewCell = true;
                }
 
-               if (reachedXp) {
-                       if (obstacle & OBSTACLE_XP) {
-                               // Slide
-                               float dz = clamp(displacement.z, distanceZn, distanceZp);
-                               position.z += dz;
-                               displacement = scaleVector(displacement, 1.0f - (dz / displacement.z));
-                       }
-                       else if (!enteredNewCell) {
-                               // Enter new grid cell
-                               location.x += 1;
-                               enteredNewCell = true;
-                       }
+               if (!enteredNewCell && reachedZp && !(obstacle & OBSTACLE_ZP)) {
+                       location.z += 1;
+                       enteredNewCell = true;
                }
-       }
-       //translate(&playerProjectedMovement->transform, subtractVectors(position, initialPosition));
 
-       translate(&playerCharacter->transform, subtractVectors(position, initialPosition));
-//}
+               if (!enteredNewCell && reachedXn && !(obstacle & OBSTACLE_XN)) {
+                       location.x -= 1;
+                       enteredNewCell = true;
+               }
 
+               if (!enteredNewCell && reachedXp && !(obstacle & OBSTACLE_XP)) {
+                       location.x += 1;
+                       enteredNewCell = true;
+               }
+       }
 
-       //translate(&playerCharacter->transform, displacement);
+       translate(&playerCharacter->transform, subtractVectors(position, initialPosition));
 }
 
 static Vector worldMovementDirection(float x, float y) {