From 2eb69ad54ab844806cee6e77f9545ebc1b4f2cb0 Mon Sep 17 00:00:00 2001 From: Ceikry Date: Mon, 27 Jun 2022 12:34:02 +0000 Subject: [PATCH] Made wilderness NPCs immune to aggression tolerance Unified wilderness and standard death code, wilderness death code now only rolls the extra loot drops Fixed a bug that would cause revenant/player combat levels to sometimes be calculated incorrectly --- .../entity/npc/agg/AggressiveBehavior.java | 9 +- .../node/entity/npc/revenant/RevenantNPC.java | 16 +-- .../world/map/zone/impl/WildernessZone.java | 131 ++++-------------- 3 files changed, 37 insertions(+), 119 deletions(-) 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 254926ad9..bb703f942 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 @@ -4,6 +4,7 @@ import core.game.node.entity.Entity; import core.game.node.entity.combat.DeathTask; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; +import core.game.world.map.zone.impl.WildernessZone; import rs09.game.world.GameWorld; import core.game.world.map.RegionManager; @@ -71,16 +72,10 @@ public class AggressiveBehavior { } if (entity instanceof NPC && target instanceof Player) { NPC npc = (NPC) entity; - if (npc.getAggressiveHandler() != null && npc.getAggressiveHandler().isAllowTolerance()) { + if (npc.getAggressiveHandler() != null && npc.getAggressiveHandler().isAllowTolerance() && WildernessZone.getWilderness(npc) == -1) { 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(); - } else if (ticks > 1500) { - return false; - } } } int level = target.getProperties().getCurrentCombatLevel(); diff --git a/Server/src/main/java/core/game/node/entity/npc/revenant/RevenantNPC.java b/Server/src/main/java/core/game/node/entity/npc/revenant/RevenantNPC.java index e4dbfa934..3ad53edc7 100644 --- a/Server/src/main/java/core/game/node/entity/npc/revenant/RevenantNPC.java +++ b/Server/src/main/java/core/game/node/entity/npc/revenant/RevenantNPC.java @@ -11,7 +11,6 @@ import core.game.node.entity.skill.Skills; import core.game.node.entity.skill.summoning.familiar.Familiar; import core.game.world.map.Location; import core.game.world.map.RegionManager; -import core.game.world.map.path.Pathfinder; import core.game.world.map.zone.ZoneBorders; import core.game.world.map.zone.impl.WildernessZone; import core.game.world.update.flag.context.Animation; @@ -188,13 +187,13 @@ public class RevenantNPC extends AbstractNPC { @Override public boolean continueAttack(Entity target, CombatStyle style, boolean message) { - return target instanceof Player ? checkCombatLevel(target.asPlayer()) : true; + return target instanceof Player ? hasAcceptableCombatLevel(target.asPlayer()) : true; } @Override public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { if (entity instanceof Player) { - if (!checkCombatLevel(entity.asPlayer()) && !entity.asPlayer().isAdmin()) { + if (!hasAcceptableCombatLevel(entity.asPlayer()) && !entity.asPlayer().isAdmin()) { if(message) { entity.asPlayer().sendMessage("The level difference between you and your opponent is too great."); } @@ -206,7 +205,7 @@ public class RevenantNPC extends AbstractNPC { if (owner == null) { return false; } - if (!checkCombatLevel(owner)) { + if (!hasAcceptableCombatLevel(owner)) { return false; } } @@ -218,7 +217,7 @@ public class RevenantNPC extends AbstractNPC { if (!(target instanceof Player)) { return false; } - return checkCombatLevel(target.asPlayer()); + return hasAcceptableCombatLevel(target.asPlayer()); } @Override @@ -252,17 +251,14 @@ public class RevenantNPC extends AbstractNPC { * @param player the player. * @return {@code True} if so. */ - private boolean checkCombatLevel(Player player) { + private boolean hasAcceptableCombatLevel(Player player) { int level = WildernessZone.getWilderness(this); if (player.getSkullManager().getLevel() < level) { level = player.getSkullManager().getLevel(); } int combat = getProperties().getCurrentCombatLevel(); int targetCombat = player.getProperties().getCurrentCombatLevel(); - if (combat - level > targetCombat || combat + level < targetCombat) { - return false; - } - return true; + return Math.abs(combat - targetCombat) <= level; } /** diff --git a/Server/src/main/java/core/game/world/map/zone/impl/WildernessZone.java b/Server/src/main/java/core/game/world/map/zone/impl/WildernessZone.java index 104b85204..9f27ecef6 100644 --- a/Server/src/main/java/core/game/world/map/zone/impl/WildernessZone.java +++ b/Server/src/main/java/core/game/world/map/zone/impl/WildernessZone.java @@ -94,115 +94,39 @@ public final class WildernessZone extends MapZone { */ @Override public boolean death(Entity e, Entity killer) { - try { - if (e instanceof UriNPC) { - e.finalizeDeath(killer); + if (e instanceof NPC) + rollWildernessExclusiveLoot(e, killer); + return false; //DONT override default death handling. + } + + private void rollWildernessExclusiveLoot(Entity e, Entity killer) { + //Roll for PVP gear and Brawling Gloves from revenants + if (e instanceof NPC && killer instanceof Player && (e.asNpc().getName().contains("Revenant") || e.getId() == NPCs.CHAOS_ELEMENTAL_3200)) { + + boolean gloveDrop = e.getId() == NPCs.CHAOS_ELEMENTAL_3200 ? RandomFunction.roll(75) : RandomFunction.roll(100); + if (gloveDrop) { + byte glove = (byte) RandomFunction.random(1, 13); + Item reward = new Item(BrawlingGloves.forIndicator(glove).getId()); + GroundItemManager.create(reward, e.asNpc().getDropLocation(), killer.asPlayer()); + Repository.sendNews(killer.getUsername() + " has received " + reward.getName().toLowerCase() + " from a " + e.asNpc().getName() + "!"); } - if(e instanceof Player){ - Player player = e.asPlayer(); - player.getSettings().setSpecialEnergy(100); - player.getSettings().updateRunEnergy(player.getSettings().getRunEnergy() - 100); - Player owner = killer instanceof Player ? (Player) killer : player; - player.getPacketDispatch().sendMessage("Oh dear, you are dead!"); - player.incrementAttribute("/save:"+STATS_BASE+":"+STATS_DEATHS); - //If player was a Hardcore Ironman, announce that they died - if (player.getIronmanManager().getMode().equals(IronmanMode.HARDCORE)){ //if this was checkRestriction, ultimate irons would be moved to HARDCORE_DEAD as well - String gender = player.isMale() ? "Man " : "Woman "; - Repository.sendNews("Hardcore Iron " + gender + " " + player.getUsername() +" has fallen. Total Level: " + player.getSkills().getTotalLevel()); // Not enough room for XP - player.getIronmanManager().setMode(IronmanMode.STANDARD); - player.getSavedData().getActivityData().setHardcoreDeath(true); - player.sendMessage("You have fallen as a Hardcore Iron Man, your Hardcore status has been revoked."); - } - - player.getPacketDispatch().sendTempMusic(90); - if (player.getDetails().getRights() != Rights.ADMINISTRATOR) { - GroundItemManager.create(new Item(526), player.getLocation(), owner); - final Container[] c = DeathTask.getContainers(player); - boolean gravestone = player.getGraveManager().generateable() && player.getIronmanManager().getMode() != IronmanMode.ULTIMATE && !(killer instanceof Player); - int seconds = player.getGraveManager().getType().getDecay() * 60; - int ticks = (1000 * seconds) / 600; - List items = new ArrayList<>(20); - for (Item item : c[1].toArray()) { - if (item != null) { - GroundItem ground; - if (item.hasItemPlugin()) { - item = item.getPlugin().getDeathItem(item); - } - if (!item.getDefinition().isTradeable()) { - ground = new GroundItem(item, player.getLocation(), gravestone ? ticks + 100 : 200, player); - } else { - ground = new GroundItem(item.getDropItem(), player.getLocation(), owner); - } - items.add(ground); - ground.setDropper(owner); //Checking for ironman mode in any circumstance for death items is inaccurate to how it works in both 2009scapes. - GroundItemManager.create(ground); - } - } - player.getEquipment().clear(); - player.getInventory().clear(); - if(!player.getSkullManager().isSkulled() || killer instanceof NPC) { - player.getInventory().addAll(c[0]); + int combatLevel = e.asNpc().getDefinition().getCombatLevel(); + int dropRate = getNewDropRate(combatLevel); + for (int j : PVP_GEAR) { + boolean chance = RandomFunction.roll(dropRate); + if (chance) { + Item reward; + if (j == 13879 || j == 13883) { // checks if it's a javelin or throwing axe + reward = new Item(j, RandomFunction.random(15, 50)); } else { - for(Item item : c[0].toArray()){ - GroundItemManager.create(item,player.getLocation(),owner); - } + reward = new Item(j); } - player.getFamiliarManager().dismiss(); - - } - player.getSkullManager().setSkulled(false); - player.removeAttribute("combat-time"); - player.getPrayer().reset(); - player.getAppearance().sync(); - if (GameWorld.isEconomyWorld() && !player.getSavedData().getGlobalData().isDeathScreenDisabled()) { - player.getInterfaceManager().open(new Component(153)); - } - if (!player.getSavedData().getGlobalData().isDeathScreenDisabled()) { - player.getInterfaceManager().open(new Component(153)); + Repository.sendNews(killer.asPlayer().getUsername() + " has received a " + reward.getName() + " from a " + e.asNpc().getName() + "!"); + GroundItemManager.create(reward, ((NPC) e).getDropLocation(), killer.asPlayer()); } } - - //Roll for PVP gear and Brawling Gloves from revenants - if (e instanceof NPC && killer instanceof Player && (e.asNpc().getName().contains("Revenant") || e.getId() == NPCs.CHAOS_ELEMENTAL_3200)) { - - boolean gloveDrop = e.getId() == NPCs.CHAOS_ELEMENTAL_3200 ? RandomFunction.roll(75) : RandomFunction.roll(100); - if (gloveDrop) { - byte glove = (byte) RandomFunction.random(1, 13); - Item reward = new Item(BrawlingGloves.forIndicator(glove).getId()); - GroundItemManager.create(reward, e.asNpc().getDropLocation(), killer.asPlayer()); - Repository.sendNews(killer.getUsername() + " has received " + reward.getName().toLowerCase() + " from a " + e.asNpc().getName() + "!"); - } - - int combatLevel = e.asNpc().getDefinition().getCombatLevel(); - int dropRate = getNewDropRate(combatLevel); - for (int j : PVP_GEAR) { - boolean chance = RandomFunction.roll(dropRate); - if (chance) { - Item reward; - if (j == 13879 || j == 13883) { // checks if it's a javelin or throwing axe - reward = new Item(j, RandomFunction.random(15, 50)); - } else { - reward = new Item(j); - } - Repository.sendNews(killer.asPlayer().getUsername() + " has received a " + reward.getName() + " from a " + e.asNpc().getName() + "!"); - GroundItemManager.create(reward, ((NPC) e).getDropLocation(), killer.asPlayer()); - return true; - } - } - } - - if (e instanceof NPC) { - e.asNpc().getDefinition().getDropTables().drop(e.asNpc(), killer); - e.asNpc().setRespawnTick(GameWorld.getTicks() + e.asNpc().getDefinition().getConfiguration(NPCConfigParser.RESPAWN_DELAY, 17)); - if (!e.asNpc().isRespawn()) { - e.asNpc().clear(); - } - } - } catch (Exception f){ - System.out.println("Unhandled NPC death in wilderness: " + e.getId()); } - return true; } /** @@ -392,6 +316,9 @@ public final class WildernessZone extends MapZone { * @return the level. */ public static int getWilderness(Entity e) { + if (e.getLocation().getY() < 3524) { + return -1; + } final int regionId = e.getViewport().getRegion().getId(); int offsetY = 3524; if (regionId == 12443 || e.getViewport().getRegion().getId() == 12444) {