Pathfinder now correctly paths to the closest accessible tile of an object, not the closest tile numerically. This should fix instances where you end up running around an object before interacting with it.

This commit is contained in:
Ceikry
2022-06-11 12:35:16 +00:00
committed by Ryan
parent 7249aaed5e
commit 5c28375c3b
5 changed files with 121 additions and 11 deletions
@@ -5,6 +5,7 @@ import core.game.node.entity.Entity;
import core.game.node.entity.impl.WalkingQueue; import core.game.node.entity.impl.WalkingQueue;
import core.game.node.entity.npc.NPC; import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player; import core.game.node.entity.player.Player;
import core.game.node.scenery.Scenery;
import core.game.system.task.Pulse; import core.game.system.task.Pulse;
import core.game.world.map.Direction; import core.game.world.map.Direction;
import core.game.world.map.Location; import core.game.world.map.Location;
@@ -241,26 +242,33 @@ public abstract class MovementPulse extends Pulse {
if (last != null && last.equals(destination.getLocation()) && !inside) { if (last != null && last.equals(destination.getLocation()) && !inside) {
return; return;
} }
Location loc = null; Location loc = null;
if (destinationFlag != null && overrideMethod == null) { if (destinationFlag != null && overrideMethod == null) {
loc = destinationFlag.getDestination(mover, destination); loc = destinationFlag.getDestination(mover, destination);
} }
if(overrideMethod != null){ else if(overrideMethod != null){
loc = overrideMethod.invoke(mover,destination); loc = overrideMethod.invoke(mover,destination);
if(loc == destination.getLocation()) loc = destinationFlag.getDestination(mover,destination); if(loc == destination.getLocation()) loc = destinationFlag.getDestination(mover,destination);
} }
if (loc == null && optionHandler != null) {
if (loc == null) {
if (optionHandler != null) {
loc = optionHandler.getDestination(mover, destination); loc = optionHandler.getDestination(mover, destination);
} }
if (loc == null && useHandler != null) { else if (useHandler != null) {
loc = useHandler.getDestination((Player) mover, destination); loc = useHandler.getDestination((Player) mover, destination);
} }
if (loc == null && inside) { else if (inside) {
loc = findBorderLocation(); loc = findBorderLocation();
} }
}
if (destination == null) { if (destination == null) {
return; return;
} }
Location ml = mover.getLocation(); Location ml = mover.getLocation();
Location dl = destination.getLocation(); Location dl = destination.getLocation();
// Lead the target if they're walking/running, unless they're already within interaction range // Lead the target if they're walking/running, unless they're already within interaction range
@@ -10,6 +10,11 @@ import core.game.node.entity.player.Player;
import core.game.system.task.Pulse; import core.game.system.task.Pulse;
import core.game.world.map.Direction; import core.game.world.map.Direction;
import core.game.world.map.Location; import core.game.world.map.Location;
import org.jetbrains.annotations.NotNull;
import rs09.game.system.SystemLogger;
import java.util.ArrayList;
import java.util.List;
/** /**
* Represents a scenery. * Represents a scenery.
@@ -30,7 +35,7 @@ public class Scenery extends Node {
/** /**
* The rotation. * The rotation.
*/ */
private final int rotation; private int rotation;
/** /**
* The object's definition. * The object's definition.
@@ -309,6 +314,10 @@ public class Scenery extends Node {
return rotation; return rotation;
} }
public void setRotation(int rot) {
rotation = rot;
}
/** /**
* @return the location * @return the location
*/ */
@@ -426,4 +435,37 @@ public class Scenery extends Node {
this.wrapper = wrapper; this.wrapper = wrapper;
} }
@SuppressWarnings("SuspiciousNameCombination")
@NotNull
public List<Location> getOccupiedTiles() {
List<Location> occupied = new ArrayList<>();
occupied.add(location);
int sizeX = getSizeX();
int sizeY = getSizeY();
if (rotation % 2 == 1) {
int tmp = sizeX;
sizeX = sizeY;
sizeY = tmp;
}
boolean sub = rotation >= 2;
if (sizeX > 1) {
for (int i = 1; i < sizeX; i++) {
int modifier = sub ? -i : i;
occupied.add(location.transform(modifier, 0, 0));
}
}
if (sizeY > 1) {
for (int i = 1; i < sizeY; i++) {
int modifier = sub ? -i : i;
occupied.add(location.transform(0, modifier, 0));
}
}
return occupied;
}
} }
@@ -207,7 +207,7 @@ object InteractionListeners {
val flag = when(type){ val flag = when(type){
3 -> DestinationFlag.ITEM 3 -> DestinationFlag.ITEM
2 -> DestinationFlag.ENTITY 2 -> DestinationFlag.ENTITY
1 -> DestinationFlag.OBJECT 1 -> null
else -> DestinationFlag.OBJECT else -> DestinationFlag.OBJECT
} }
@@ -149,6 +149,13 @@ object ManagementEvents {
} }
is FriendUpdate -> {
val remove = event.type == FriendUpdate.Type.REMOVE
val f = Repository.getPlayerByName(event.friend)
val p = Repository.getPlayerByName(event.username)
val world = if (f != null) GameWorld.settings!!.worldId else 0
}
is PrivateMessage -> { is PrivateMessage -> {
val sender = Repository.getPlayerByName(event.sender) val sender = Repository.getPlayerByName(event.sender)
val receiver = Repository.getPlayerByName(event.receiver) val receiver = Repository.getPlayerByName(event.receiver)
@@ -0,0 +1,53 @@
package core
import TestUtils
import api.replaceScenery
import core.cache.def.impl.SceneryDefinition
import core.game.interaction.MovementPulse
import core.game.node.scenery.Scenery
import core.game.world.map.Location
import core.game.world.map.RegionManager
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import rs09.game.interaction.InteractionListener
import rs09.game.interaction.InteractionListeners
import rs09.game.node.entity.skill.gather.GatheringSkillOptionListeners
import rs09.game.system.SystemLogger
import rs09.game.world.GameWorld
class PathfinderTests {
companion object {init {TestUtils.preTestSetup(); GatheringSkillOptionListeners().defineListeners() }}
@Test fun getOccupiedTilesShouldReturnCorrectSetOfTilesThatAnObjectOccupiesAtAllRotations() {
//clay fireplace - 13609 - sizex: 1, sizey: 2
val scenery = Scenery(13609, Location.create(50, 50, 0))
scenery.rotation = 0
val occupiedAt0 = scenery.occupiedTiles.toTypedArray()
Assertions.assertArrayEquals(arrayOf(Location.create(50, 50), Location.create(50,51)), occupiedAt0)
scenery.rotation = 1
val occupiedAt1 = scenery.occupiedTiles.toTypedArray()
Assertions.assertArrayEquals(arrayOf(Location.create(50,50), Location.create(51,50)), occupiedAt1)
scenery.rotation = 2
val occupiedAt2 = scenery.occupiedTiles.toTypedArray()
Assertions.assertArrayEquals(arrayOf(Location.create(50,50), Location.create(50,49)), occupiedAt2)
scenery.rotation = 3
val occupiedAt3 = scenery.occupiedTiles.toTypedArray()
Assertions.assertArrayEquals(arrayOf(Location.create(50,50), Location.create(49,50)), occupiedAt3)
}
@Test fun movementPulseShouldStopEarlyIfNextToATileOccupiedByTargetObject() {
val start = Location.create(2731, 3481)
val dest = RegionManager.getObject(0, 2720, 3475, 1307)
val p = TestUtils.getMockPlayer("treefindtest")
p.location = start
p.init()
Assertions.assertEquals(true, InteractionListeners.run(1307, InteractionListener.SCENERY, "chop-down", p, dest!!))
TestUtils.advanceTicks(20)
Assertions.assertEquals(Location.create(2722, 3475, 0), p.location)
}
}