diff --git a/Server/src/main/java/core/game/node/entity/npc/agg/AggressiveBehavior.java b/Server/src/main/java/core/game/node/entity/npc/agg/AggressiveBehavior.java index 087823be3..a346e19cf 100644 --- a/Server/src/main/java/core/game/node/entity/npc/agg/AggressiveBehavior.java +++ b/Server/src/main/java/core/game/node/entity/npc/agg/AggressiveBehavior.java @@ -62,6 +62,12 @@ public class AggressiveBehavior { * @return {@code True} if the NPC can select the entity as a target. */ public boolean canSelectTarget(Entity entity, Entity target) { + int regionId = target.getLocation().getRegionId(); + if(target instanceof Player) { + if (RegionManager.forId(regionId).isTolerated(target.asPlayer())) { + return false; + } + } if (!target.isActive() || DeathTask.isDead(target)) { return false; } diff --git a/Server/src/main/java/core/game/node/entity/npc/agg/AggressiveHandler.java b/Server/src/main/java/core/game/node/entity/npc/agg/AggressiveHandler.java index b8281035e..ff75bbb58 100644 --- a/Server/src/main/java/core/game/node/entity/npc/agg/AggressiveHandler.java +++ b/Server/src/main/java/core/game/node/entity/npc/agg/AggressiveHandler.java @@ -81,9 +81,10 @@ public final class AggressiveHandler { Entity target = behavior.getLogicalTarget(entity, behavior.getPossibleTargets(entity, radius)); if (target instanceof Player) { if (target.getAttribute("ignore_aggression", false)) { - if (((Player) target).getRights().equals(Rights.ADMINISTRATOR)) { - return false; - } + return false; + } + if (((Player) target).getRights().equals(Rights.ADMINISTRATOR)) { + return false; } } if (target != null) { diff --git a/Server/src/main/java/core/game/node/entity/npc/other/RockCrabNPC.java b/Server/src/main/java/core/game/node/entity/npc/other/RockCrabNPC.java index c827b0051..b88aa0a26 100644 --- a/Server/src/main/java/core/game/node/entity/npc/other/RockCrabNPC.java +++ b/Server/src/main/java/core/game/node/entity/npc/other/RockCrabNPC.java @@ -5,7 +5,9 @@ import core.game.node.entity.combat.BattleState; import core.game.node.entity.npc.AbstractNPC; import core.game.node.entity.npc.agg.AggressiveBehavior; import core.game.node.entity.npc.agg.AggressiveHandler; +import core.game.node.entity.player.Player; import core.game.world.map.Location; +import core.game.world.map.RegionManager; import core.plugin.Initializable; import core.tools.RandomFunction; @@ -22,6 +24,10 @@ public final class RockCrabNPC extends AbstractNPC { private static final AggressiveBehavior AGGRO_BEHAVIOR = new AggressiveBehavior() { @Override public boolean canSelectTarget(Entity entity, Entity target) { + int regionId = target.getLocation().getRegionId(); + if(target instanceof Player){ + if(RegionManager.forId(regionId).isTolerated(target.asPlayer())) return false; + } RockCrabNPC npc = (RockCrabNPC) entity; if (entity.getLocation().withinDistance(target.getLocation(), 3)) { npc.aggresor = true; diff --git a/Server/src/main/java/core/game/world/map/Region.java b/Server/src/main/java/core/game/world/map/Region.java index 12313de4f..71959a717 100644 --- a/Server/src/main/java/core/game/world/map/Region.java +++ b/Server/src/main/java/core/game/world/map/Region.java @@ -16,7 +16,9 @@ import rs09.game.world.repository.Repository; import java.nio.ByteBuffer; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.concurrent.TimeUnit; /** * Represents a region. @@ -60,6 +62,11 @@ public class Region { */ private final List musicZones = new ArrayList<>(20); + /** + * Keeps track of players and time in region for tolerance purposes + */ + private final HashMap tolerances = new HashMap<>(); + /** * If the region is active. */ @@ -146,6 +153,7 @@ public class Region { */ public void add(Player player) { planes[player.getLocation().getZ()].add(player); + tolerances.put(player.getUsername(), System.currentTimeMillis()); flagActive(); } @@ -175,9 +183,17 @@ public class Region { */ public void remove(Player player) { player.getViewport().getCurrentPlane().remove(player); + tolerances.remove(player.getUsername()); checkInactive(); } + /** + * Checks if player is tolerated by enemies in this region + */ + public boolean isTolerated(Player player){ + return System.currentTimeMillis() - tolerances.getOrDefault(player.getUsername(), System.currentTimeMillis()) > TimeUnit.MINUTES.toMillis(1); + } + /** * Checks if the region is inactive, if so it will start the inactivity flagging. * @return {@code True} if the region is inactive.