From abc4dc3a76acdb03827afab78db900a690ce77d9 Mon Sep 17 00:00:00 2001 From: Major- Date: Tue, 28 Aug 2018 19:32:26 +0100 Subject: [PATCH] Rename walk-to to pathing --- game/plugin/entity/following/build.gradle | 2 +- .../entity/{walk-to => pathing}/build.gradle | 0 .../apollo/plugin/entity/pathing/Pathing.kt | 83 +++++++++++++++++++ game/plugin/entity/walk-to/src/walk_to.kt | 66 --------------- 4 files changed, 84 insertions(+), 67 deletions(-) rename game/plugin/entity/{walk-to => pathing}/build.gradle (100%) create mode 100644 game/plugin/entity/pathing/src/org/apollo/plugin/entity/pathing/Pathing.kt delete mode 100644 game/plugin/entity/walk-to/src/walk_to.kt diff --git a/game/plugin/entity/following/build.gradle b/game/plugin/entity/following/build.gradle index e81c73d4..4aca75d5 100644 --- a/game/plugin/entity/following/build.gradle +++ b/game/plugin/entity/following/build.gradle @@ -5,7 +5,7 @@ dependencies { implementation project(':cache') implementation project(':net') implementation project(':util') - implementation project(':game:plugin:entity:walk-to') + implementation project(':game:plugin:entity:pathing') implementation project(':game:plugin:entity:actions') testImplementation project(':game:plugin-testing') } diff --git a/game/plugin/entity/walk-to/build.gradle b/game/plugin/entity/pathing/build.gradle similarity index 100% rename from game/plugin/entity/walk-to/build.gradle rename to game/plugin/entity/pathing/build.gradle diff --git a/game/plugin/entity/pathing/src/org/apollo/plugin/entity/pathing/Pathing.kt b/game/plugin/entity/pathing/src/org/apollo/plugin/entity/pathing/Pathing.kt new file mode 100644 index 00000000..93adb699 --- /dev/null +++ b/game/plugin/entity/pathing/src/org/apollo/plugin/entity/pathing/Pathing.kt @@ -0,0 +1,83 @@ +package org.apollo.plugin.entity.pathing + +import org.apollo.game.model.Direction +import org.apollo.game.model.Position +import org.apollo.game.model.entity.Entity +import org.apollo.game.model.entity.Mob +import org.apollo.game.model.entity.Npc +import org.apollo.game.model.entity.Player +import org.apollo.game.model.entity.obj.GameObject +import org.apollo.game.model.entity.path.SimplePathfindingAlgorithm + +/** + * Adds a path from this [Mob] to the [target] [Entity], with the final position determined by the [facing] [Direction]. + */ +fun Mob.walkTo(target: Entity, facing: Direction? = null) { + val (width, length) = bounds(this) + val (targetWidth, targetLength) = bounds(target) + + val direction = facing ?: Direction.between(position, target.position) + val dx = direction.deltaX() + val dy = direction.deltaY() + + val targetX = if (dx <= 0) target.position.x else target.position.x + targetWidth - 1 + val targetY = if (dy <= 0) target.position.y else target.position.y + targetLength - 1 + val offsetX = if (dx < 0) -width else if (dx > 0) 1 else 0 + val offsetY = if (dy < 0) -length else if (dy > 0) 1 else 0 + + walkTo(Position(targetX + offsetX, targetY + offsetY, position.height)) +} + +/** + * Adds a path for this [Mob] to the target [Mob]s last position. + */ +fun Mob.walkBehind(target: Mob) { + walkTo(target, target.lastDirection.opposite()) +} + +/** + * Adds a path from this [Mob] to the [target] [Position], ending the path as soon as [positionPredicate] returns + * `false` (if provided). + */ +fun Mob.walkTo(target: Position, positionPredicate: ((Position) -> Boolean)? = null) { + if (position == target) { + return + } + + val pathfinder = SimplePathfindingAlgorithm(world.collisionManager) + val path = pathfinder.find(position, target) + + if (positionPredicate == null) { + path.forEach(walkingQueue::addStep) + } else { + for (step in path) { + if (!positionPredicate(step)) { + return + } + + walkingQueue.addStep(step) + } + } +} + +/** + * Returns the bounding size of the specified [Entity], in [x-size, y-size] format. + */ +private fun bounds(target: Entity): Pair { + return when (target) { + is GameObject -> { + val orientation = Direction.WNES[target.orientation] + val rotated = (orientation == Direction.WEST || orientation == Direction.EAST) + + val definition = target.definition + + val width = if (rotated) definition.length else definition.width + val height = if (rotated) definition.width else definition.length + + Pair(width, height) + } + is Npc -> Pair(target.definition.size, target.definition.size) + is Player -> Pair(1, 1) + else -> error("Invalid entity type") + } +} \ No newline at end of file diff --git a/game/plugin/entity/walk-to/src/walk_to.kt b/game/plugin/entity/walk-to/src/walk_to.kt deleted file mode 100644 index 87a1135d..00000000 --- a/game/plugin/entity/walk-to/src/walk_to.kt +++ /dev/null @@ -1,66 +0,0 @@ -package org.apollo.plugin.entity.walkto - -import org.apollo.game.model.Direction -import org.apollo.game.model.Position -import org.apollo.game.model.entity.Entity -import org.apollo.game.model.entity.Mob -import org.apollo.game.model.entity.Npc -import org.apollo.game.model.entity.Player -import org.apollo.game.model.entity.obj.GameObject -import org.apollo.game.model.entity.path.SimplePathfindingAlgorithm - -private fun bounds(target: Entity): Pair = when (target) { - is GameObject -> { - val orientation = Direction.WNES[target.orientation] - val rotated = (orientation == Direction.WEST || orientation == Direction.EAST) - - val width = if (rotated) target.definition.length else target.definition.width - val height = if (rotated) target.definition.width else target.definition.length - - Pair(width, height) - } - is Npc -> Pair(target.definition.size, target.definition.size) - is Player -> Pair(1, 1) - else -> error("Invalid entity type") -} - -fun Mob.walkTo(target: Entity, positioningDirection: Direction? = null) { - val (sourceWidth, sourceHeight) = bounds(target) - val (targetWidth, targetHeight) = bounds(target) - - val direction = positioningDirection ?: Direction.between(position, target.position) - val dx = direction.deltaX() - val dy = direction.deltaY() - - val targetX = if (dx <= 0) target.position.x else target.position.x + targetWidth - 1 - val targetY = if (dy <= 0) target.position.y else target.position.y + targetHeight - 1 - val offsetX = if (dx < 0) -sourceWidth else if (dx > 0) 1 else 0 - val offsetY = if (dy < 0) -sourceHeight else if (dy > 0) 1 else 0 - - walkTo(Position(targetX + offsetX, targetY + offsetY, position.height)) -} - -fun Mob.walkBehind(target: Mob) { - walkTo(target, target.lastDirection.opposite()) -} - -fun Mob.walkTo(target: Position, positionPredicate: ((Position) -> Boolean)? = null) { - if (position == target) { - return - } - - val pathfinder = SimplePathfindingAlgorithm(world.collisionManager) - val path = pathfinder.find(position, target) - - if (positionPredicate == null) { - path.forEach(walkingQueue::addStep) - } else { - for (step in path) { - if (!positionPredicate.invoke(step)) { - return - } - - walkingQueue.addStep(step) - } - } -} \ No newline at end of file