diff --git a/Server/src/main/content/global/skill/hunter/implings/ImplingController.kt b/Server/src/main/content/global/skill/hunter/implings/ImplingController.kt index c00604ab4..c27316a2f 100644 --- a/Server/src/main/content/global/skill/hunter/implings/ImplingController.kt +++ b/Server/src/main/content/global/skill/hunter/implings/ImplingController.kt @@ -16,7 +16,7 @@ class ImplingController : TickListener, Commands { if (--nextCycle > getTicksBeforeNextCycleToDespawn()) return if (activeImplings.size > 0) { - clearSomeImplings(implingsClearedPerTick) + clearSomeImplings(min(activeImplings.size, implingsClearedPerTick)) return } generateSpawners() diff --git a/Server/src/main/core/game/interaction/MovementPulse.java b/Server/src/main/core/game/interaction/MovementPulse.java index f0ceab9ad..647d6e86f 100644 --- a/Server/src/main/core/game/interaction/MovementPulse.java +++ b/Server/src/main/core/game/interaction/MovementPulse.java @@ -269,62 +269,65 @@ public abstract class MovementPulse extends Pulse { return; } - Location ml = mover.getLocation(); - Location dl = destination.getLocation(); - // Lead the target if they're walking/running, unless they're already within interaction range - if(loc != null && destination instanceof Entity && Math.max(Math.abs(ml.getX() - dl.getX()), Math.abs(ml.getY() - dl.getY())) > 1) { - WalkingQueue wq = ((Entity)destination).getWalkingQueue(); - if(wq.hasPath()) { - Point[] points = wq.getQueue().toArray(new Point[0]); - if(points.length > 0) { - Point p = points[0]; - for(int i=0; i 1) { + WalkingQueue wq = ((Entity)destination).getWalkingQueue(); + if(wq.hasPath()) { + Point[] points = wq.getQueue().toArray(new Point[0]); + if(points.length > 0) { + Point p = points[0]; + for(int i=0; i npcPath = e.getWalkingQueue().getQueue(); - if (e.getWalkingQueue().hasPath() && e.getProperties().getCombatPulse().isRunning() && e.getProperties().getCombatPulse().getVictim() == mover) - canMove = false; - if (!canMove) { //If we normally shouldn't move, but the NPC's pathfinding is not letting them move, then move. - if (npcPath.size() == 1) { - Point pathElement = npcPath.peek(); - if (pathElement.getX() == l.getX() && pathElement.getY() == l.getY()) - canMove = true; + + Path path = Pathfinder.find(mover, loc != null ? loc : destination, true, pathfinder); + near = !path.isSuccessful() || path.isMoveNear(); + interactLocation = mover.getLocation(); + boolean canMove = true; + if (destination instanceof Entity) { + Entity e = (Entity) destination; + Location l = e.getLocation(); + Deque npcPath = e.getWalkingQueue().getQueue(); + if (e.getWalkingQueue().hasPath() && e.getProperties().getCombatPulse().isRunning() && e.getProperties().getCombatPulse().getVictim() == mover) + canMove = false; + if (!canMove) { //If we normally shouldn't move, but the NPC's pathfinding is not letting them move, then move. + if (npcPath.size() == 1) { + Point pathElement = npcPath.peek(); + if (pathElement.getX() == l.getX() && pathElement.getY() == l.getY()) + canMove = true; + } } } - } - if (!path.getPoints().isEmpty() && canMove) { - Point point = path.getPoints().getLast(); - interactLocation = Location.create(point.getX(), point.getY(), mover.getLocation().getZ()); - if (forceRun) { - mover.getWalkingQueue().reset(forceRun); - } else { - mover.getWalkingQueue().reset(); - } - int size = path.getPoints().toArray().length; - Deque points = path.getPoints(); - for (int i = 0; i < size; i++) { - point = path.getPoints().pop(); - mover.getWalkingQueue().addPath(point.getX(), point.getY()); - if (destination instanceof Entity) { - mover.face((Entity) destination); + if (!path.getPoints().isEmpty() && canMove) { + Point point = path.getPoints().getLast(); + interactLocation = Location.create(point.getX(), point.getY(), mover.getLocation().getZ()); + if (forceRun) { + mover.getWalkingQueue().reset(forceRun); } else { - mover.face(null); + mover.getWalkingQueue().reset(); + } + int size = path.getPoints().toArray().length; + Deque points = path.getPoints(); + for (int i = 0; i < size; i++) { + point = path.getPoints().pop(); + mover.getWalkingQueue().addPath(point.getX(), point.getY()); + if (destination instanceof Entity) { + mover.face((Entity) destination); + } else { + mover.face(null); + } } } } diff --git a/Server/src/main/core/game/interaction/ScriptProcessor.kt b/Server/src/main/core/game/interaction/ScriptProcessor.kt index f1cdfffc0..8967dce10 100644 --- a/Server/src/main/core/game/interaction/ScriptProcessor.kt +++ b/Server/src/main/core/game/interaction/ScriptProcessor.kt @@ -60,7 +60,7 @@ class ScriptProcessor(val entity: Entity) { fun postMovement(didMove: Boolean) { if (didMove) - entity.clocks[Clocks.MOVEMENT] = GameWorld.ticks + 1 + entity.clocks[Clocks.MOVEMENT] = GameWorld.ticks + if (entity.walkingQueue.isRunning) 0 else 1 var canProcess = !entity.delayed() if (entity is Player) canProcess = canProcess && !entity.interfaceManager.isOpened && !entity.interfaceManager.hasChatbox() @@ -80,7 +80,7 @@ class ScriptProcessor(val entity: Entity) { } } if (canProcess && (apScript != null || opScript != null)) { - if (!interacted && !didMove) { + if (!interacted && !didMove && finishedMoving(entity)) { sendMessage(entity, "I can't reach that!") reset() } diff --git a/Server/src/main/core/game/node/entity/impl/WalkingQueue.java b/Server/src/main/core/game/node/entity/impl/WalkingQueue.java index 048d3b632..6a5dbcf48 100644 --- a/Server/src/main/core/game/node/entity/impl/WalkingQueue.java +++ b/Server/src/main/core/game/node/entity/impl/WalkingQueue.java @@ -4,15 +4,19 @@ import content.global.skill.skillcapeperks.SkillcapePerks; import core.game.node.entity.Entity; import core.game.node.entity.player.Player; import core.game.node.entity.skill.Skills; +import core.game.node.item.Item; +import core.game.node.item.GroundItem; import core.game.world.map.Direction; import core.game.world.map.Location; import core.game.world.map.Point; import core.game.world.map.RegionManager; +import core.game.world.update.flag.chunk.ItemUpdateFlag; import core.tools.Log; import core.tools.SystemLogger; import java.util.Deque; import java.util.ArrayDeque; +import java.util.ArrayList; import static core.api.ContentAPIKt.log; @@ -58,6 +62,8 @@ public final class WalkingQueue { */ private Location footPrint; + public ArrayList routeItems = new ArrayList(); + /** * Constructs a new {@code WalkingQueue} {@code Object}. * @param entity The entity. @@ -84,8 +90,17 @@ public final class WalkingQueue { return; } Point point = walkingQueue.poll(); + boolean drawPath = entity.getAttribute("routedraw", false); if (point == null) { updateRunEnergy(false); + if (isPlayer && drawPath) { + for (GroundItem item : routeItems) { + if (item != null) { + RegionManager.getRegionPlane(item.getLocation()).remove(item); + } + } + routeItems.clear(); + } return; } if (isPlayer && ((Player) entity).getSettings().getRunEnergy() < 1.0) { @@ -300,6 +315,13 @@ public final class WalkingQueue { if (point == null) { return; } + boolean drawRoute = entity.getAttribute("routedraw", false); + if (drawRoute && entity instanceof Player) { + Player p = (Player) entity; + GroundItem item = new GroundItem(new Item(13444), Location.create(x, y, p.getLocation().getZ()), p); + routeItems.add (item); + RegionManager.getRegionPlane(item.getLocation()).add(item); + } int diffX = x - point.getX(), diffY = y - point.getY(); int max = Math.max(Math.abs(diffX), Math.abs(diffY)); for (int i = 0; i < max; i++) { diff --git a/Server/src/main/core/game/system/command/sets/DevelopmentCommandSet.kt b/Server/src/main/core/game/system/command/sets/DevelopmentCommandSet.kt index 8d83b735a..fb10da547 100644 --- a/Server/src/main/core/game/system/command/sets/DevelopmentCommandSet.kt +++ b/Server/src/main/core/game/system/command/sets/DevelopmentCommandSet.kt @@ -212,5 +212,17 @@ class DevelopmentCommandSet : CommandSet(Privilege.ADMIN) { addItem(player, item, 1000) } } + + define("drawchunks", Privilege.ADMIN, "", "Draws the border of the chunk you're standing in") {player, _ -> + setAttribute (player, "chunkdraw", !getAttribute(player, "chunkdraw", false)) + } + + define("drawregions", Privilege.ADMIN, "", "DRaws the border of the region you're standing in") {player, _ -> + setAttribute (player, "regiondraw", !getAttribute(player, "regiondraw", false)) + } + + define("drawroute", Privilege.ADMIN, "", "Visualizes the path your player is taking") {player, _ -> + setAttribute (player, "routedraw", !getAttribute(player, "routedraw", false)) + } } -} \ No newline at end of file +} diff --git a/Server/src/main/core/game/world/map/RegionChunk.java b/Server/src/main/core/game/world/map/RegionChunk.java index 8c7876095..e8b97a717 100644 --- a/Server/src/main/core/game/world/map/RegionChunk.java +++ b/Server/src/main/core/game/world/map/RegionChunk.java @@ -149,8 +149,52 @@ public class RegionChunk { } } } - if (items != null) { - for (Item item : items) { + ArrayList totalItems = items != null ? new ArrayList(items) : new ArrayList(); + + boolean drawChunks = player.getAttribute("chunkdraw", false); + boolean drawRegions = player.getAttribute("regiondraw", false); + + if (drawChunks) { + Location l = currentBase; + for (int x = 0; x < SIZE; x++) { + for (int y = 0; y < SIZE; y++) { + boolean add = false; + if (y == 0 || y == SIZE - 1) + add = true; + else if (x == 0 || x == SIZE - 1) + add = true; + if (add) + totalItems.add(new GroundItem(new Item(13444), l.transform(x, y, 0), player)); + } + } + } + + if (drawRegions) { + Location l = currentBase; + int localX = l.getLocalX(); + int localY = l.getLocalY(); + + for (int x = 0; x < SIZE; x++) + for (int y = 0; y < SIZE; y++) { + boolean add = false; + if (localY == 0 || localY == 56) + if (localY == 0 && y == 0) + add = true; + else if (localY == 56 && y == SIZE - 1) + add = true; + if (localX == 0 || localX == 56) + if (localX == 0 && x == 0) + add = true; + else if (localX == 56 && x == SIZE - 1) + add = true; + + if (add) + totalItems.add(new GroundItem(new Item(13444), l.transform(x,y,0), player)); + } + } + + if (totalItems != null) { + for (Item item : totalItems) { if (item != null && item.isActive() && item.getLocation() != null) { GroundItem g = (GroundItem) item; if (!g.isPrivate() || g.droppedBy(player)) { @@ -382,4 +426,4 @@ public class RegionChunk { } } -} \ No newline at end of file +}