-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Navigation interface, implement CharacterNavigation
. test stub . minimal movement implementation . make it async, add movement type . goForwardToLocation . remove debug prints . address some review comments . add test mock data Use Duration for timeouts. . address review comments. Use the CharacterMovement interface. . address review comments . test update . test defaults
- Loading branch information
1 parent
0ff5f3d
commit a9a847e
Showing
3 changed files
with
128 additions
and
0 deletions.
There are no files selected for viewing
82 changes: 82 additions & 0 deletions
82
JvmClient/src/commonMain/kotlin/spaceEngineers/navigation/Navigation.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package spaceEngineers.navigation | ||
|
||
import kotlinx.coroutines.delay | ||
import kotlinx.coroutines.withTimeout | ||
import spaceEngineers.controller.SpaceEngineers | ||
import spaceEngineers.controller.extensions.distanceTo | ||
import spaceEngineers.model.CharacterMovementType | ||
import spaceEngineers.model.Vec3F | ||
import spaceEngineers.movement.CharacterMovement | ||
import spaceEngineers.movement.CompositeDirection3d | ||
import spaceEngineers.movement.VectorMovement | ||
import kotlin.time.Duration | ||
import kotlin.time.Duration.Companion.seconds | ||
|
||
interface Navigation { | ||
suspend fun moveInLine( | ||
targetLocation: Vec3F, | ||
movementType: CharacterMovementType = CharacterMovementType.RUN, | ||
timeout: Duration = 20.seconds | ||
) | ||
} | ||
|
||
class CharacterNavigation( | ||
val spaceEngineers: SpaceEngineers, | ||
val movement: CharacterMovement = VectorMovement(spaceEngineers) | ||
) : Navigation { | ||
|
||
override suspend fun moveInLine( | ||
targetLocation: Vec3F, | ||
movementType: CharacterMovementType, | ||
timeout: Duration | ||
) = withTimeout(timeout) { | ||
moveInLine(targetLocation, movementType) | ||
} | ||
|
||
private suspend fun moveInLine( | ||
targetLocation: Vec3F, | ||
movementType: CharacterMovementType | ||
) = with(spaceEngineers) { | ||
val me = observer.observe() | ||
val direction = (targetLocation - me.position).normalized() | ||
|
||
// TODO("Replace this teleport hack") | ||
admin.character.teleport(me.position, direction, me.orientationUp) | ||
|
||
goForwardToLocation(spaceEngineers, targetLocation, movementType, stepTicks = 20, tolerance = 1.2f) | ||
goForwardToLocation(spaceEngineers, targetLocation, movementType, stepTicks = 6, tolerance = 0.4f) | ||
} | ||
|
||
private suspend fun goForwardToLocation( | ||
spaceEngineers: SpaceEngineers, | ||
targetLocation: Vec3F, | ||
movementType: CharacterMovementType, | ||
stepTicks: Int, tolerance: Float | ||
) = with(spaceEngineers) { | ||
var lastDistance = Float.MAX_VALUE; | ||
|
||
fun isNotYetThereButProgressing(maxDistanceRegression: Float = 0.01f): Boolean { | ||
val distance = observer.distanceTo(targetLocation) | ||
if (distance < tolerance) { | ||
return false | ||
} | ||
if (distance > lastDistance + maxDistanceRegression) { // Allow very small worsening of distance. | ||
return false | ||
} | ||
lastDistance = distance | ||
return true | ||
} | ||
|
||
while (isNotYetThereButProgressing()) { | ||
// TODO("Correct the course from time to time") | ||
|
||
movement.move(CompositeDirection3d.FORWARD, movementType, ticks = stepTicks) | ||
delay((stepTicks * DELAY_PER_TICKS_MS).toLong()) | ||
} | ||
} | ||
|
||
companion object { | ||
const val DELAY_PER_TICKS_MS = 12 // One tick lasts ~16.7 ms, wait slightly less to avoid character freezes. | ||
} | ||
} | ||
|
25 changes: 25 additions & 0 deletions
25
JvmClient/src/jvmTest/kotlin/spaceEngineers/game/mockable/NavigationTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package spaceEngineers.game.mockable | ||
|
||
import spaceEngineers.controller.extensions.navigationGraph | ||
import spaceEngineers.navigation.CharacterNavigation | ||
import testhelp.MockOrRealGameTest | ||
import testhelp.assertGreaterThan | ||
import testhelp.assertLessThan | ||
import kotlin.test.Test | ||
|
||
|
||
class NavigationTest : MockOrRealGameTest( | ||
//forceRealGame = true | ||
) { | ||
@Test | ||
fun navigateToLocation() = testContext { | ||
val navGraph = observer.navigationGraph() | ||
assertGreaterThan(navGraph.nodes.size, 30) | ||
|
||
val targetLocation = navGraph.nodes[25].position | ||
val navigator = CharacterNavigation(this) | ||
|
||
navigator.moveInLine(targetLocation) | ||
assertLessThan(lower = observer.observe().position.distanceTo(targetLocation), higher = 0.6f) | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
JvmClient/src/jvmTest/resources/mock/NavigationTest-navigateToLocation.txt
Large diffs are not rendered by default.
Oops, something went wrong.