diff --git a/Server/src/main/java/core/game/interaction/MovementPulse.java b/Server/src/main/java/core/game/interaction/MovementPulse.java index fe10c2f98..a48b8009b 100644 --- a/Server/src/main/java/core/game/interaction/MovementPulse.java +++ b/Server/src/main/java/core/game/interaction/MovementPulse.java @@ -5,6 +5,7 @@ import core.game.node.entity.Entity; import core.game.node.entity.impl.WalkingQueue; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; import core.game.system.task.Pulse; import core.game.world.map.Direction; import core.game.world.map.Location; @@ -241,26 +242,33 @@ public abstract class MovementPulse extends Pulse { if (last != null && last.equals(destination.getLocation()) && !inside) { return; } + Location loc = null; + if (destinationFlag != null && overrideMethod == null) { loc = destinationFlag.getDestination(mover, destination); } - if(overrideMethod != null){ + else if(overrideMethod != null){ loc = overrideMethod.invoke(mover,destination); if(loc == destination.getLocation()) loc = destinationFlag.getDestination(mover,destination); } - if (loc == null && optionHandler != null) { - loc = optionHandler.getDestination(mover, destination); - } - if (loc == null && useHandler != null) { - loc = useHandler.getDestination((Player) mover, destination); - } - if (loc == null && inside) { - loc = findBorderLocation(); + + if (loc == null) { + if (optionHandler != null) { + loc = optionHandler.getDestination(mover, destination); + } + else if (useHandler != null) { + loc = useHandler.getDestination((Player) mover, destination); + } + else if (inside) { + loc = findBorderLocation(); + } } + if (destination == null) { return; } + Location ml = mover.getLocation(); Location dl = destination.getLocation(); // Lead the target if they're walking/running, unless they're already within interaction range diff --git a/Server/src/main/java/core/game/node/scenery/Scenery.java b/Server/src/main/java/core/game/node/scenery/Scenery.java index 4493620ff..c8c55b04b 100644 --- a/Server/src/main/java/core/game/node/scenery/Scenery.java +++ b/Server/src/main/java/core/game/node/scenery/Scenery.java @@ -10,6 +10,11 @@ import core.game.node.entity.player.Player; import core.game.system.task.Pulse; import core.game.world.map.Direction; 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. @@ -30,7 +35,7 @@ public class Scenery extends Node { /** * The rotation. */ - private final int rotation; + private int rotation; /** * The object's definition. @@ -309,6 +314,10 @@ public class Scenery extends Node { return rotation; } + public void setRotation(int rot) { + rotation = rot; + } + /** * @return the location */ @@ -426,4 +435,37 @@ public class Scenery extends Node { this.wrapper = wrapper; } + @SuppressWarnings("SuspiciousNameCombination") + @NotNull + public List getOccupiedTiles() { + List 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; + } } \ No newline at end of file diff --git a/Server/src/main/kotlin/rs09/game/interaction/InteractionListeners.kt b/Server/src/main/kotlin/rs09/game/interaction/InteractionListeners.kt index d37dffff3..7c17868b8 100644 --- a/Server/src/main/kotlin/rs09/game/interaction/InteractionListeners.kt +++ b/Server/src/main/kotlin/rs09/game/interaction/InteractionListeners.kt @@ -207,7 +207,7 @@ object InteractionListeners { val flag = when(type){ 3 -> DestinationFlag.ITEM 2 -> DestinationFlag.ENTITY - 1 -> DestinationFlag.OBJECT + 1 -> null else -> DestinationFlag.OBJECT } diff --git a/Server/src/main/kotlin/rs09/worker/ManagementEvents.kt b/Server/src/main/kotlin/rs09/worker/ManagementEvents.kt index 8a6f2da10..472fca3e6 100644 --- a/Server/src/main/kotlin/rs09/worker/ManagementEvents.kt +++ b/Server/src/main/kotlin/rs09/worker/ManagementEvents.kt @@ -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 -> { val sender = Repository.getPlayerByName(event.sender) val receiver = Repository.getPlayerByName(event.receiver) diff --git a/Server/src/test/kotlin/core/PathfinderTests.kt b/Server/src/test/kotlin/core/PathfinderTests.kt new file mode 100644 index 000000000..519902a66 --- /dev/null +++ b/Server/src/test/kotlin/core/PathfinderTests.kt @@ -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) + } +} \ No newline at end of file