diff --git a/Server/data/configs/npc_configs.json b/Server/data/configs/npc_configs.json index 05efb5979..3cff3b550 100644 --- a/Server/data/configs/npc_configs.json +++ b/Server/data/configs/npc_configs.json @@ -27038,6 +27038,7 @@ "name": "Rock lobster", "defence_level": "100", "safespot": null, + "movement_radius": "30", "lifepoints": "150", "strength_level": "100", "id": "2889", @@ -27045,6 +27046,25 @@ "range_level": "1", "attack_level": "100" }, + { + "examine": "A Rock.", + "melee_animation": "2860", + "range_animation": "2860", + "attack_speed": "2", + "defence_animation": "2861", + "weakness": "7", + "magic_animation": "2860", + "death_animation": "2861", + "name": "Large rock", + "defence_level": "100", + "safespot": null, + "lifepoints": "150", + "strength_level": "100", + "id": "2890", + "aggressive": "true", + "range_level": "1", + "attack_level": "100" + }, { "agg_radius": "12", "examine": "A sneaky, spiny, subterranean sea-dwelling scamp.", @@ -267720,4 +267740,4 @@ "name": "Pet shop owner", "id": "6750" } -] \ No newline at end of file +] diff --git a/Server/src/main/java/core/game/content/activity/pestcontrol/PCPortalNPC.java b/Server/src/main/java/core/game/content/activity/pestcontrol/PCPortalNPC.java index d06639a04..2ab59697a 100644 --- a/Server/src/main/java/core/game/content/activity/pestcontrol/PCPortalNPC.java +++ b/Server/src/main/java/core/game/content/activity/pestcontrol/PCPortalNPC.java @@ -151,6 +151,11 @@ public final class PCPortalNPC extends AbstractNPC { } } + @Override + public boolean shouldPreventStacking(Entity mover) { + return true; + } + @Override public void onImpact(final Entity entity, BattleState state) { updateLifepoints = true; @@ -324,4 +329,4 @@ public final class PCPortalNPC extends AbstractNPC { } return (getId() - 6142) % 4; } -} \ No newline at end of file +} diff --git a/Server/src/main/java/core/game/content/activity/pestcontrol/PestControlActivityPlugin.java b/Server/src/main/java/core/game/content/activity/pestcontrol/PestControlActivityPlugin.java index 71d2fa067..af996fd2e 100644 --- a/Server/src/main/java/core/game/content/activity/pestcontrol/PestControlActivityPlugin.java +++ b/Server/src/main/java/core/game/content/activity/pestcontrol/PestControlActivityPlugin.java @@ -227,6 +227,7 @@ public final class PestControlActivityPlugin extends ActivityPlugin { PluginManager.definePlugin(new PCShifterNPC()); PluginManager.definePlugin(new PCSplatterNPC()); PluginManager.definePlugin(new PCSpinnerNPC()); + PluginManager.definePlugin(new PCBrawlerNPC()); PluginManager.definePlugin(new PCObjectHandler()); PluginManager.definePlugin(new PestControlSquire()); PluginManager.definePlugin(new VoidSealPlugin()); @@ -362,4 +363,4 @@ public final class PestControlActivityPlugin extends ActivityPlugin { return requirement; } } -} \ No newline at end of file +} diff --git a/Server/src/main/java/core/game/content/activity/pestcontrol/VoidSealPlugin.java b/Server/src/main/java/core/game/content/activity/pestcontrol/VoidSealPlugin.java index f8d97511d..4e3962be0 100644 --- a/Server/src/main/java/core/game/content/activity/pestcontrol/VoidSealPlugin.java +++ b/Server/src/main/java/core/game/content/activity/pestcontrol/VoidSealPlugin.java @@ -63,7 +63,7 @@ public final class VoidSealPlugin extends OptionHandler { * @return {@code True} if so. */ private static boolean canTarget(NPC npc) { - return npc instanceof PCDefilerNPC || npc instanceof PCRavagerNPC || npc instanceof PCShifterNPC || npc instanceof PCSpinnerNPC || npc instanceof PCSplatterNPC || npc instanceof PCTorcherNPC; + return npc instanceof PCDefilerNPC || npc instanceof PCRavagerNPC || npc instanceof PCShifterNPC || npc instanceof PCSpinnerNPC || npc instanceof PCSplatterNPC || npc instanceof PCTorcherNPC || npc instanceof PCBrawlerNPC; } -} \ No newline at end of file +} diff --git a/Server/src/main/java/core/game/content/activity/pestcontrol/monsters/PCBrawlerNPC.java b/Server/src/main/java/core/game/content/activity/pestcontrol/monsters/PCBrawlerNPC.java new file mode 100644 index 000000000..830e3cca7 --- /dev/null +++ b/Server/src/main/java/core/game/content/activity/pestcontrol/monsters/PCBrawlerNPC.java @@ -0,0 +1,91 @@ +package core.game.content.activity.pestcontrol.monsters; + +import core.game.content.activity.pestcontrol.PestControlSession; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.InteractionType; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.tools.RandomFunction; +import rs09.game.node.entity.combat.CombatPulse; +import rs09.game.node.entity.combat.CombatSwingHandler; +import rs09.game.node.entity.combat.handlers.MeleeSwingHandler; +import rs09.game.world.GameWorld; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Handles the pest control brawler NPCs. + * @author Emperor + */ +public final class PCBrawlerNPC extends AbstractNPC { + /** + * The pest control session. + */ + private PestControlSession session; + + /** + * Constructs a new {@code PCBrawlerNPC} {@code Object}. + */ + public PCBrawlerNPC() { + super(3772, null); + } + + /** + * Constructs a new {@code PCBrawlerNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + public PCBrawlerNPC(int id, Location location) { + super(id, location); + } + + @Override + public void init() { + super.setAggressive(true); + super.init(); + super.getDefinition().setCombatDistance(1); + super.walkRadius = 64; + getProperties().getCombatPulse().setStyle(CombatStyle.MELEE); + session = getExtension(PestControlSession.class); + } + + @Override + public boolean shouldPreventStacking(Entity mover) { + return true; + } + + @Override + public void onImpact(final Entity entity, BattleState state) { + super.onImpact(entity, state); + if (session != null && state != null && entity instanceof Player) { + int total = 0; + if (state.getEstimatedHit() > 0) { + total += state.getEstimatedHit(); + } + if (state.getSecondaryHit() > 0) { + total += state.getSecondaryHit(); + } + session.addZealGained((Player) entity, total); + } + } + + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new PCBrawlerNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] { 3772, 3773, 3774, 3775, 3776 }; + } +} diff --git a/Server/src/main/java/core/game/content/activity/pestcontrol/monsters/PCDefilerNPC.java b/Server/src/main/java/core/game/content/activity/pestcontrol/monsters/PCDefilerNPC.java index c8caae317..711620778 100644 --- a/Server/src/main/java/core/game/content/activity/pestcontrol/monsters/PCDefilerNPC.java +++ b/Server/src/main/java/core/game/content/activity/pestcontrol/monsters/PCDefilerNPC.java @@ -6,6 +6,7 @@ import core.game.node.entity.combat.BattleState; import core.game.node.entity.combat.CombatStyle; import core.game.node.entity.combat.InteractionType; import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.game.world.map.Location; import core.game.world.map.MapDistance; @@ -77,6 +78,11 @@ public final class PCDefilerNPC extends AbstractNPC { } } + @Override + public boolean shouldPreventStacking(Entity mover) { + return mover instanceof NPC; + } + @Override public void onImpact(final Entity entity, BattleState state) { super.onImpact(entity, state); @@ -107,4 +113,4 @@ public final class PCDefilerNPC extends AbstractNPC { return new int[] { 3762, 3763, 3764, 3765, 3766, 3767, 3768, 3769, 3770, 3771 }; } -} \ No newline at end of file +} diff --git a/Server/src/main/java/core/game/content/activity/pestcontrol/monsters/PCRavagerNPC.java b/Server/src/main/java/core/game/content/activity/pestcontrol/monsters/PCRavagerNPC.java index a7dd30cf3..000846402 100644 --- a/Server/src/main/java/core/game/content/activity/pestcontrol/monsters/PCRavagerNPC.java +++ b/Server/src/main/java/core/game/content/activity/pestcontrol/monsters/PCRavagerNPC.java @@ -5,6 +5,7 @@ import core.game.node.Node; import core.game.node.entity.Entity; import core.game.node.entity.combat.BattleState; import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.game.node.scenery.Scenery; import core.game.node.scenery.SceneryBuilder; @@ -171,6 +172,11 @@ public class PCRavagerNPC extends AbstractNPC { return true; } + @Override + public boolean shouldPreventStacking(Entity mover) { + return mover instanceof NPC; + } + @Override public void onImpact(final Entity entity, BattleState state) { super.onImpact(entity, state); @@ -221,4 +227,4 @@ public class PCRavagerNPC extends AbstractNPC { this.portalIndex = portalIndex; } -} \ No newline at end of file +} diff --git a/Server/src/main/java/core/game/content/activity/pestcontrol/monsters/PCShifterNPC.java b/Server/src/main/java/core/game/content/activity/pestcontrol/monsters/PCShifterNPC.java index d1f4741f3..88a3a3261 100644 --- a/Server/src/main/java/core/game/content/activity/pestcontrol/monsters/PCShifterNPC.java +++ b/Server/src/main/java/core/game/content/activity/pestcontrol/monsters/PCShifterNPC.java @@ -6,6 +6,7 @@ import core.game.node.entity.combat.BattleState; import core.game.node.entity.combat.CombatStyle; import core.game.node.entity.combat.InteractionType; import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.game.system.task.Pulse; import core.game.world.map.Location; @@ -84,6 +85,11 @@ public final class PCShifterNPC extends AbstractNPC { } } + @Override + public boolean shouldPreventStacking(Entity mover) { + return mover instanceof NPC; + } + @Override public void onImpact(final Entity entity, BattleState state) { super.onImpact(entity, state); @@ -163,4 +169,4 @@ public final class PCShifterNPC extends AbstractNPC { return new int[] { 3732, 3733, 3734, 3735, 3736, 3737, 3738, 3739, 3740, 3741 }; } -} \ No newline at end of file +} diff --git a/Server/src/main/java/core/game/content/activity/pestcontrol/monsters/PCSpinnerNPC.java b/Server/src/main/java/core/game/content/activity/pestcontrol/monsters/PCSpinnerNPC.java index 66adbc20b..917b2dba2 100644 --- a/Server/src/main/java/core/game/content/activity/pestcontrol/monsters/PCSpinnerNPC.java +++ b/Server/src/main/java/core/game/content/activity/pestcontrol/monsters/PCSpinnerNPC.java @@ -111,6 +111,11 @@ public final class PCSpinnerNPC extends AbstractNPC { }); } + @Override + public boolean shouldPreventStacking(Entity mover) { + return mover instanceof NPC; + } + @Override public void onImpact(final Entity entity, BattleState state) { super.onImpact(entity, state); @@ -146,4 +151,4 @@ public final class PCSpinnerNPC extends AbstractNPC { return new int[] { 3747, 3748, 3749, 3750, 3751 }; } -} \ No newline at end of file +} diff --git a/Server/src/main/java/core/game/content/activity/pestcontrol/monsters/PCSplatterNPC.java b/Server/src/main/java/core/game/content/activity/pestcontrol/monsters/PCSplatterNPC.java index 3df492dce..a6eea8314 100644 --- a/Server/src/main/java/core/game/content/activity/pestcontrol/monsters/PCSplatterNPC.java +++ b/Server/src/main/java/core/game/content/activity/pestcontrol/monsters/PCSplatterNPC.java @@ -75,6 +75,11 @@ public final class PCSplatterNPC extends AbstractNPC { } } + @Override + public boolean shouldPreventStacking(Entity mover) { + return mover instanceof NPC; + } + @Override public void onImpact(final Entity entity, BattleState state) { super.onImpact(entity, state); @@ -162,4 +167,4 @@ public final class PCSplatterNPC extends AbstractNPC { return new int[] { 3727, 3728, 3729, 3730, 3731 }; } -} \ No newline at end of file +} diff --git a/Server/src/main/java/core/game/content/activity/pestcontrol/monsters/PCTorcherNPC.java b/Server/src/main/java/core/game/content/activity/pestcontrol/monsters/PCTorcherNPC.java index 1347ef3fc..276b46caf 100644 --- a/Server/src/main/java/core/game/content/activity/pestcontrol/monsters/PCTorcherNPC.java +++ b/Server/src/main/java/core/game/content/activity/pestcontrol/monsters/PCTorcherNPC.java @@ -10,6 +10,7 @@ import core.game.node.entity.combat.equipment.SpellType; import core.game.node.entity.impl.Animator.Priority; import core.game.node.entity.impl.Projectile; import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.SpellBookManager.SpellBook; import core.game.world.map.Location; @@ -91,6 +92,11 @@ public final class PCTorcherNPC extends AbstractNPC { } } + @Override + public boolean shouldPreventStacking(Entity mover) { + return mover instanceof NPC; + } + @Override public void onImpact(final Entity entity, BattleState state) { super.onImpact(entity, state); @@ -142,4 +148,4 @@ class TorcherSpell extends CombatSpell { return this; } -} \ No newline at end of file +} diff --git a/Server/src/main/java/core/game/content/activity/tzhaar/TzhaarFightCaveNPC.java b/Server/src/main/java/core/game/content/activity/tzhaar/TzhaarFightCaveNPC.java index 6fd478e16..abd27d066 100644 --- a/Server/src/main/java/core/game/content/activity/tzhaar/TzhaarFightCaveNPC.java +++ b/Server/src/main/java/core/game/content/activity/tzhaar/TzhaarFightCaveNPC.java @@ -98,6 +98,10 @@ public final class TzhaarFightCaveNPC extends AbstractNPC { } } } + @Override + public boolean shouldPreventStacking(Entity mover) { + return mover instanceof TzhaarFightCaveNPC; + } @Override public void finalizeDeath(Entity killer) { @@ -355,4 +359,4 @@ public final class TzhaarFightCaveNPC extends AbstractNPC { } } -} \ No newline at end of file +} diff --git a/Server/src/main/java/core/game/content/zone/wbisland/SpinolypNPC.java b/Server/src/main/java/core/game/content/zone/wbisland/SpinolypNPC.java index e521bc8dd..e374379c4 100644 --- a/Server/src/main/java/core/game/content/zone/wbisland/SpinolypNPC.java +++ b/Server/src/main/java/core/game/content/zone/wbisland/SpinolypNPC.java @@ -58,6 +58,7 @@ public final class SpinolypNPC extends AbstractNPC { super.init(); super.getLocks().lockMovement(Integer.MAX_VALUE); setSpell(); + getAggressiveHandler().setAllowTolerance(false); } /** diff --git a/Server/src/main/java/core/game/content/zone/wbisland/WaterBirthDungeonZone.java b/Server/src/main/java/core/game/content/zone/wbisland/WaterBirthDungeonZone.java index 02a44add7..eeea49007 100644 --- a/Server/src/main/java/core/game/content/zone/wbisland/WaterBirthDungeonZone.java +++ b/Server/src/main/java/core/game/content/zone/wbisland/WaterBirthDungeonZone.java @@ -24,9 +24,11 @@ import core.game.world.map.Location; import core.game.world.map.RegionManager; import core.game.world.map.zone.MapZone; import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; import core.game.world.map.zone.ZoneRestriction; import rs09.game.world.repository.Repository; import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; import core.plugin.Plugin; import rs09.plugin.PluginManager; @@ -34,6 +36,7 @@ import rs09.plugin.PluginManager; * Handles the waterbirth dungeon zone. * @author Vexia */ +@Initializable public final class WaterBirthDungeonZone extends MapZone implements Plugin { /** @@ -54,6 +57,7 @@ public final class WaterBirthDungeonZone extends MapZone implements Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); return this; } diff --git a/Server/src/main/java/core/game/content/zone/wbisland/WaterBirthIslandZone.java b/Server/src/main/java/core/game/content/zone/wbisland/WaterBirthIslandZone.java index b31ac824a..3a52ee15d 100644 --- a/Server/src/main/java/core/game/content/zone/wbisland/WaterBirthIslandZone.java +++ b/Server/src/main/java/core/game/content/zone/wbisland/WaterBirthIslandZone.java @@ -29,7 +29,6 @@ public final class WaterBirthIslandZone extends MapZone implements Plugin newInstance(Object arg) throws Throwable { ZoneBuilder.configure(this); - ZoneBuilder.configure(new WaterBirthDungeonZone()); return this; } diff --git a/Server/src/main/java/core/game/interaction/MovementPulse.java b/Server/src/main/java/core/game/interaction/MovementPulse.java index 40b5a1a7b..a9ab85eb0 100644 --- a/Server/src/main/java/core/game/interaction/MovementPulse.java +++ b/Server/src/main/java/core/game/interaction/MovementPulse.java @@ -405,4 +405,4 @@ public abstract class MovementPulse extends Pulse { this.last = last; } -} \ No newline at end of file +} diff --git a/Server/src/main/java/core/game/node/entity/Entity.java b/Server/src/main/java/core/game/node/entity/Entity.java index 54d48c6e5..b893242ab 100644 --- a/Server/src/main/java/core/game/node/entity/Entity.java +++ b/Server/src/main/java/core/game/node/entity/Entity.java @@ -249,6 +249,13 @@ public abstract class Entity extends Node { return false; } + /** + * Should this entity prevent the mover from moving through it? + */ + public boolean shouldPreventStacking(Entity mover) { + return false; + } + /** * Checks an impact before receiving it. */ diff --git a/Server/src/main/java/core/game/node/entity/combat/CombatSpell.java b/Server/src/main/java/core/game/node/entity/combat/CombatSpell.java index d35be9bf2..3761ffaf6 100644 --- a/Server/src/main/java/core/game/node/entity/combat/CombatSpell.java +++ b/Server/src/main/java/core/game/node/entity/combat/CombatSpell.java @@ -113,7 +113,7 @@ public abstract class CombatSpell extends MagicSpell { List list = new ArrayList<>(20); list.add(target); boolean npc = target instanceof NPC; - for (Entity e : npc ? RegionManager.getLocalNpcs(target, 1) : RegionManager.getLocalPlayers(target, 1)) { + for (Entity e : npc ? RegionManager.getSurroundingNPCs(target) : RegionManager.getSurroundingPlayers(target)) { if (e != target && e != entity && CombatStyle.MAGIC.getSwingHandler().canSwing(entity, e) != InteractionType.NO_INTERACT) { list.add(e); } @@ -236,4 +236,4 @@ public abstract class CombatSpell extends MagicSpell { return SPLASH_GRAPHIC; } -} \ No newline at end of file +} diff --git a/Server/src/main/java/core/game/node/entity/impl/WalkingQueue.java b/Server/src/main/java/core/game/node/entity/impl/WalkingQueue.java index d41cd1a5f..49fd4d737 100644 --- a/Server/src/main/java/core/game/node/entity/impl/WalkingQueue.java +++ b/Server/src/main/java/core/game/node/entity/impl/WalkingQueue.java @@ -123,10 +123,10 @@ public final class WalkingQueue { walk = walk.transform(point.getDiffX(), point.getDiffY(), 0); if (!entity.getZoneMonitor().move(entity.getLocation(), walk)) { reset(); - if (entity.getPulseManager().isMovingPulse()) { + /*if (entity.getPulseManager().isMovingPulse()) { entity.getPulseManager().clear(); // TODO: Check for // bugs - } + }*/ return; } } @@ -137,10 +137,10 @@ public final class WalkingQueue { runPoint = null; runDirection = -1; reset(); - if (entity.getPulseManager().isMovingPulse()) { + /*if (entity.getPulseManager().isMovingPulse()) { entity.getPulseManager().clear(); // TODO: Check for // bugs - } + }*/ } } if (runPoint != null) { @@ -446,4 +446,4 @@ public final class WalkingQueue { public void setRunDisabled(boolean runDisabled) { this.runDisabled = runDisabled; } -} \ No newline at end of file +} 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 a346e19cf..254926ad9 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 @@ -63,11 +63,6 @@ public class AggressiveBehavior { */ 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; } @@ -77,6 +72,9 @@ public class AggressiveBehavior { if (entity instanceof NPC && target instanceof Player) { NPC npc = (NPC) entity; if (npc.getAggressiveHandler() != null && npc.getAggressiveHandler().isAllowTolerance()) { + if (RegionManager.forId(regionId).isTolerated(target.asPlayer())) { + return false; + } int ticks = GameWorld.getTicks() - npc.getAggressiveHandler().getPlayerTolerance()[target.getIndex()]; if (ticks > 3000) { npc.getAggressiveHandler().getPlayerTolerance()[target.getIndex()] = GameWorld.getTicks(); @@ -86,12 +84,16 @@ public class AggressiveBehavior { } } int level = target.getProperties().getCurrentCombatLevel(); - if (level > entity.getProperties().getCurrentCombatLevel() << 1) { + if (level > entity.getProperties().getCurrentCombatLevel() << 1 && !ignoreCombatLevelDifference()) { return false; } return true; } + public boolean ignoreCombatLevelDifference() { + return false; + } + /** * Gets the priority flag. * @param target The target. @@ -146,4 +148,4 @@ public class AggressiveBehavior { } return target; } -} \ No newline at end of file +} 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 ff75bbb58..3d960d549 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 @@ -83,7 +83,7 @@ public final class AggressiveHandler { if (target.getAttribute("ignore_aggression", false)) { return false; } - if (((Player) target).getRights().equals(Rights.ADMINISTRATOR)) { + if (((Player) target).getRights().equals(Rights.ADMINISTRATOR) && !target.getAttribute("allow_admin_aggression", false)) { return false; } } @@ -198,4 +198,4 @@ public final class AggressiveHandler { this.allowTolerance = allowTolerance; } -} \ No newline at end of file +} diff --git a/Server/src/main/java/core/game/node/entity/npc/bosses/TormentedDemonNPC.java b/Server/src/main/java/core/game/node/entity/npc/bosses/TormentedDemonNPC.java index 9b294349f..30fee5e5e 100644 --- a/Server/src/main/java/core/game/node/entity/npc/bosses/TormentedDemonNPC.java +++ b/Server/src/main/java/core/game/node/entity/npc/bosses/TormentedDemonNPC.java @@ -92,6 +92,11 @@ public class TormentedDemonNPC extends AbstractNPC { setAggressive(true); this.setDefaultBehavior(); } + + @Override + public boolean shouldPreventStacking(Entity other) { + return other instanceof TormentedDemonNPC; + } @Override public void handleTickActions() { 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 b88aa0a26..4641439cc 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 @@ -17,32 +17,34 @@ import core.tools.RandomFunction; */ @Initializable public final class RockCrabNPC extends AbstractNPC { - /** * The aggresive behavior. */ private static final AggressiveBehavior AGGRO_BEHAVIOR = new AggressiveBehavior() { + @Override + public boolean ignoreCombatLevelDifference() { + return true; + } @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; - npc.target = target; - npc.transform(npc.getTransformId()); - return true; - } - return super.canSelectTarget(entity, target); + return super.canSelectTarget(entity, target) && + entity.getLocation().withinDistance(target.getLocation(), 3); } }; + @Override + public void onAttack(Entity target) { + this.aggressor = true; + this.target = target; + if(getId() == getOriginalId()) { + this.transform(getOriginalId() - 1); + } + } + /** - * If currently an aggresor. + * If currently an aggressor. */ - private boolean aggresor; + private boolean aggressor; /** * The target. @@ -71,9 +73,10 @@ public final class RockCrabNPC extends AbstractNPC { @Override public void handleTickActions() { super.handleTickActions(); - if (aggresor && !inCombat() && target.getLocation().getDistance(this.getLocation()) > 12) { + if ((aggressor && !inCombat() && target.getLocation().getDistance(this.getLocation()) > 12) || isInvisible()) { reTransform(); - aggresor = false; + aggressor = false; + target = null; getWalkingQueue().reset(); setWalks(false); } diff --git a/Server/src/main/java/core/game/world/map/RegionManager.kt b/Server/src/main/java/core/game/world/map/RegionManager.kt index 1e1cd7d40..9b1ec02f4 100644 --- a/Server/src/main/java/core/game/world/map/RegionManager.kt +++ b/Server/src/main/java/core/game/world/map/RegionManager.kt @@ -541,6 +541,9 @@ object RegionManager { val it = players.iterator() while (it.hasNext()) { val p = it.next() + if(p.isInvisible()) { + it.remove() + } if(!p.location.withinMaxnormDistance(n.location, 1)) { it.remove() continue @@ -584,6 +587,9 @@ object RegionManager { val it = npcs.iterator() while (it.hasNext()) { val p = it.next() + if(p.isInvisible()) { + it.remove() + } if(!p.location.withinMaxnormDistance(n.location, 1)) { it.remove() continue diff --git a/Server/src/main/java/core/game/world/map/zone/ZoneMonitor.java b/Server/src/main/java/core/game/world/map/zone/ZoneMonitor.java index 470b59bb4..e9fdd394e 100644 --- a/Server/src/main/java/core/game/world/map/zone/ZoneMonitor.java +++ b/Server/src/main/java/core/game/world/map/zone/ZoneMonitor.java @@ -427,4 +427,4 @@ public final class ZoneMonitor { return musicZones; } -} \ No newline at end of file +} diff --git a/Server/src/main/java/core/game/world/map/zone/impl/MultiwayCombatZone.java b/Server/src/main/java/core/game/world/map/zone/impl/MultiwayCombatZone.java index 8139fd86e..5ddbd964c 100644 --- a/Server/src/main/java/core/game/world/map/zone/impl/MultiwayCombatZone.java +++ b/Server/src/main/java/core/game/world/map/zone/impl/MultiwayCombatZone.java @@ -7,6 +7,7 @@ import core.game.world.map.Direction; import core.game.world.map.Location; import core.game.world.map.MapDistance; import core.game.world.map.RegionManager; +import core.game.world.map.path.Pathfinder; import core.game.world.map.zone.MapZone; import core.game.world.map.zone.ZoneBorders; import core.net.packet.PacketRepository; @@ -122,39 +123,21 @@ public final class MultiwayCombatZone extends MapZone { if (e.getProperties().isNPCWalkable()) { return true; } - boolean pestControl = e.getViewport().getRegion().getRegionId() == 10536; - boolean player = e instanceof Player; - if (!player) { - Direction dir = Direction.getDirection(loc, destination); - if (dir.getStepX() != 0 && dir.getStepY() != 0) { - return true; // Allow diagonal steps so people can still "stack" - // npcs (see barraging mummies) - } - } - if (e instanceof NPC || pestControl) { - for (NPC n : RegionManager.getLocalNpcs(e, MapDistance.RENDERING.getDistance() / 2)) { - if (n.isInvisible() || !n.getDefinition().hasAttackOption() || n == e) { - continue; - } - if (player && pestControl && !(n.getId() >= 3772 && n.getId() <= 3776)) { - continue; - } - Location l = n.getLocation(); - // TODO: Better support for sizes. - int s = n.size() - 1; - int x = destination.getX(); - int y = destination.getY(); - if (x > l.getX()) { - x += e.size() - 1; - } - if (y > l.getY()) { - y += e.size() - 1; - } - if (l.getX() <= x && l.getY() <= y && (l.getX() + s) >= x && (l.getY() + s) >= y) { - return false; - } - } - } + for (NPC n : RegionManager.getLocalNpcs(e, MapDistance.RENDERING.getDistance() / 2)) { + if (n.isInvisible() || !n.getDefinition().hasAttackOption() || n == e) { + continue; + } + if(n.shouldPreventStacking(e)) { + int s1 = e.size(); + int s2 = n.size(); + int x = destination.getX(); + int y = destination.getY(); + Location l = n.getLocation(); + if(Pathfinder.isStandingIn(x, y, s1, s1, l.getX(), l.getY(), s2, s2)) { + return false; + } + } + } return true; } @@ -166,4 +149,4 @@ public final class MultiwayCombatZone extends MapZone { return INSTANCE; } -} \ No newline at end of file +} diff --git a/Server/src/main/kotlin/rs09/game/system/command/sets/MiscCommandSet.kt b/Server/src/main/kotlin/rs09/game/system/command/sets/MiscCommandSet.kt index 93e1b2e4a..be7ff6000 100644 --- a/Server/src/main/kotlin/rs09/game/system/command/sets/MiscCommandSet.kt +++ b/Server/src/main/kotlin/rs09/game/system/command/sets/MiscCommandSet.kt @@ -473,6 +473,18 @@ class MiscCommandSet : CommandSet(Command.Privilege.ADMIN){ else -> reject(player, usageStr) } } + define("allow_aggro", Command.Privilege.ADMIN) { player, args -> + val usageStr = "Usage: ::allow_aggro true | false" + if(args.size < 2) { + reject(player, usageStr) + } + when(args[1]) { + "true" -> player.setAttribute("allow_admin_aggression", true) + "false" -> player.removeAttribute("allow_admin_aggression") + else -> reject(player, usageStr) + + } + } } fun showGeSell(player: Player){