diff --git a/Server/data/ObjectParser.xml b/Server/data/ObjectParser.xml index 3a354d63b..b10a0d445 100644 --- a/Server/data/ObjectParser.xml +++ b/Server/data/ObjectParser.xml @@ -22,7 +22,6 @@ - diff --git a/Server/src/main/content/global/handlers/scenery/BankBoothListener.kt b/Server/src/main/content/global/handlers/scenery/BankBoothListener.kt index c5dc0ac8f..00b275e85 100644 --- a/Server/src/main/content/global/handlers/scenery/BankBoothListener.kt +++ b/Server/src/main/content/global/handlers/scenery/BankBoothListener.kt @@ -38,6 +38,34 @@ class BankBoothListener : InteractionListener { Scenery.BANK_BOOTH_29085, Scenery.BANK_BOOTH_30015, Scenery.BANK_BOOTH_30016, Scenery.BANK_BOOTH_34205, Scenery.BANK_BOOTH_34752, Scenery.BANK_BOOTH_35647, Scenery.BANK_BOOTH_36786, Scenery.BANK_BOOTH_37474 ) + + public fun convertToNotes (used: Node, player: Player) { + val item = used as Item + + if (item.noteChange != item.id) { + if (item.definition.isUnnoted) { + val amount = amountInInventory(player, item.id) + if (removeItem(player, Item(item.id, amount))) { + addItem(player, item.noteChange, amount) + } + } else { + var amount = item.amount + val freeSlotCount = freeSlots(player) + + if (amount > freeSlotCount) { + amount = freeSlotCount + } + + if (removeItem(player, Item(item.id, amount))) { + addItem(player, item.noteChange, amount) + } + } + + return + } + + sendMessage(player, "This item can't be noted.") + } } /** @@ -146,32 +174,8 @@ class BankBoothListener : InteractionListener { tryInvokeBankerDialogue(player, with) return true } - - val item = used as Item - - if (item.noteChange != item.id) { - if (item.definition.isUnnoted) { - val amount = amountInInventory(player, item.id) - if (removeItem(player, Item(item.id, amount))) { - addItem(player, item.noteChange, amount) - } - } else { - var amount = item.amount - val freeSlotCount = freeSlots(player) - - if (amount > freeSlotCount) { - amount = freeSlotCount - } - - if (removeItem(player, Item(item.id, amount))) { - addItem(player, item.noteChange, amount) - } - } - - return true - } - - sendMessage(player, "This item can't be noted.") + + convertToNotes (used, player) return true } @@ -184,4 +188,4 @@ class BankBoothListener : InteractionListener { onUseAnyWith(IntType.SCENERY, *BANK_BOOTHS, handler = ::attemptToConvertItems) } } -} \ No newline at end of file +} diff --git a/Server/src/main/content/minigame/allfiredup/BeaconTenderDialogue.kt b/Server/src/main/content/minigame/allfiredup/BeaconTenderDialogue.kt index 4933c0e29..c02ebd0e4 100644 --- a/Server/src/main/content/minigame/allfiredup/BeaconTenderDialogue.kt +++ b/Server/src/main/content/minigame/allfiredup/BeaconTenderDialogue.kt @@ -1,11 +1,13 @@ package content.minigame.allfiredup -import core.game.dialogue.DialoguePlugin +import core.ServerConstants +import core.game.dialogue.* import core.game.node.entity.npc.NPC import core.game.node.entity.player.Player import core.game.node.entity.skill.Skills import core.game.node.item.Item import core.plugin.Initializable +import content.region.wilderness.dialogue.* import org.rs09.consts.Items private val VALID_LOGS = arrayOf(Items.LOGS_1511, Items.OAK_LOGS_1521, Items.WILLOW_LOGS_1519, Items.MAPLE_LOGS_1517, Items.YEW_LOGS_1515, Items.MAGIC_LOGS_1513) @@ -20,6 +22,7 @@ class BeaconTenderDialogue(player: Player? = null) : core.game.dialogue.Dialogue } override fun open(vararg args: Any?): Boolean { + npc = (args[0] as NPC).getShownNPC(player) index = getIndexOf((args[0] as NPC).originalId) if(index == content.minigame.allfiredup.AFUBeacon.GWD.ordinal && player.skills.getLevel(Skills.SUMMONING) < 81){ npc("Awwf uurrrhur","(You need 81 Summoning to communicate with Nanuq.)") @@ -27,11 +30,10 @@ class BeaconTenderDialogue(player: Player? = null) : core.game.dialogue.Dialogue return true } if(index == content.minigame.allfiredup.AFUBeacon.MONASTERY.ordinal && player.skills.getLevel(Skills.PRAYER) < 53){ - npc("I will aid you when your devotion is","strong enough.","(You need 53 Prayer for him to watch the beacon.)") + npc("I will aid you when your devotion is","strong enough.","(You need 53 Prayer for him to assist you.)") stage = 1000 return true } - npc = (args[0] as NPC).getShownNPC(player) npc("Hello, adventurer.") return true } @@ -88,4 +90,4 @@ class BeaconTenderDialogue(player: Player? = null) : core.game.dialogue.Dialogue return intArrayOf(8067,8068,8069,8070,8071,8072,8073,8074,8075,8076) } -} \ No newline at end of file +} diff --git a/Server/src/main/content/region/wilderness/handlers/WildernessGateHandler.kt b/Server/src/main/content/region/wilderness/handlers/WildernessGateHandler.kt new file mode 100644 index 000000000..d8f8b099a --- /dev/null +++ b/Server/src/main/content/region/wilderness/handlers/WildernessGateHandler.kt @@ -0,0 +1,52 @@ +package content.region.wilderness.handlers + +import core.api.* +import core.game.interaction.* +import core.game.node.entity.player.Player +import core.game.node.scenery.Scenery +import core.game.node.Node +import core.game.global.action.DoorActionHandler +import core.game.dialogue.* +import core.tools.* + +class WildernessGateHandler : InteractionListener { + val gates = intArrayOf(1597, 1596) + + override fun defineListeners() { + on (gates, IntType.SCENERY, "open", handler = ::handleGate) + } + + private fun handleGate (player: Player, node: Node) : Boolean { + val isEntering = !player.skullManager.isDeepWilderness() + + if (isEntering) + openDialogue (player, GateDialogue(node.asScenery())) + else { + if (player.properties.combatPulse.isInCombat) + sendMessage (player, "You cannot leave while you are under attack.") + else { + DoorActionHandler.handleAutowalkDoor (player, node.asScenery()) + player.skullManager.isDeepWilderness = false + } + } + + return true + } + + class GateDialogue (val gate: Scenery) : DialogueFile() { + override fun handle (interfaceId: Int, buttonId: Int) { + when (stage) { + 0 -> sendDialogueLines(player!!, "WARNING!", "Beyond this gate you enter the deep wilderness!", "Anyone will be able to attack you without consequence!", "You WILL NOT be able to leave during combat!").also { stage++ } + 1 -> showTopics ( + Topic(FacialExpression.NEUTRAL, "I wish to proceed.", 10, true), + Topic(FacialExpression.NEUTRAL, "Nevermind.", END_DIALOGUE, true) + ) + 10 -> { + end() + DoorActionHandler.handleAutowalkDoor (player!!, gate) + player!!.skullManager.isDeepWilderness = true + } + } + } + } +} diff --git a/Server/src/main/content/region/wilderness/handlers/WildernessObeliskPlugin.java b/Server/src/main/content/region/wilderness/handlers/WildernessObeliskPlugin.java index 6c9b66448..ee3b0641f 100644 --- a/Server/src/main/content/region/wilderness/handlers/WildernessObeliskPlugin.java +++ b/Server/src/main/content/region/wilderness/handlers/WildernessObeliskPlugin.java @@ -43,6 +43,12 @@ public final class WildernessObeliskPlugin extends OptionHandler { if (stationObelisk == null) { return false; } + if (player.getSkullManager().isDeepWilderness()) { + if (player.getProperties().getCombatPulse().isInCombat()) { + player.sendMessage("You can't use this while in combat."); + return false; + } + } for (int i = 0; i < 4; i++) { int x = stationObelisk.getLocation().getX(); int y = stationObelisk.getLocation().getY(); diff --git a/Server/src/main/core/game/node/entity/player/Player.java b/Server/src/main/core/game/node/entity/player/Player.java index 3edc198fb..78055a720 100644 --- a/Server/src/main/core/game/node/entity/player/Player.java +++ b/Server/src/main/core/game/node/entity/player/Player.java @@ -86,6 +86,8 @@ import static core.api.ContentAPIKt.*; import static core.game.system.command.sets.StatAttributeKeysKt.STATS_BASE; import static core.game.system.command.sets.StatAttributeKeysKt.STATS_DEATHS; import static core.tools.GlobalsKt.colorize; +import static core.game.world.map.zone.impl.WildernessZone.WILDERNESS_PROT_ATTR; +import static core.game.world.map.zone.impl.WildernessZone.WILDERNESS_HIGHER_NEXTFEE; /** * Represents a player entity. @@ -549,6 +551,16 @@ public class Player extends Entity { return this.getIndex() | 0x8000; } + @Override + public void onAttack (Entity e) { + if (e instanceof Player) { + Player p = (Player) e; + if (skullManager.isWildernessDisabled()) { + return; + } + } + } + @Override public CombatSwingHandler getSwingHandler(boolean swing) { CombatStyle style = getProperties().getCombatPulse().getStyle(); @@ -716,6 +728,18 @@ public class Player extends Entity { if (entity instanceof NPC && !((NPC) entity).getDefinition().hasAction("attack") && !((NPC) entity).isIgnoreAttackRestrictions(this)) { return false; } + if (entity instanceof Player) { + Player p = (Player) entity; + if (p.getSkullManager().isWilderness() && skullManager.isWilderness()) { + if (!GameWorld.getSettings().getWild_pvp_enabled()) + return false; + if (p.getSkullManager().hasWildernessProtection()) + return false; + if (skullManager.hasWildernessProtection()) + return false; + return true; + } else return false; + } return super.isAttackable(entity, style, message); } diff --git a/Server/src/main/core/game/node/entity/player/link/SkullManager.java b/Server/src/main/core/game/node/entity/player/link/SkullManager.java index 2bba76e78..de4d4161c 100644 --- a/Server/src/main/core/game/node/entity/player/link/SkullManager.java +++ b/Server/src/main/core/game/node/entity/player/link/SkullManager.java @@ -3,10 +3,14 @@ package core.game.node.entity.player.link; import core.game.node.entity.Entity; import core.game.node.entity.player.Player; import core.game.node.entity.state.EntityState; +import core.ServerConstants; import java.util.ArrayList; import java.util.List; +import static core.tools.GlobalsKt.colorize; +import static core.game.world.map.zone.impl.WildernessZone.WILDERNESS_PROT_ATTR; + /** * Represents a managing class of the active player skulls. * @author Vexia @@ -49,6 +53,8 @@ public final class SkullManager { */ private boolean skullCheckDisabled; + private boolean deepWilderness; + /** * Constructs a new {@code SkullManager} {@code Object}. * @param player the player. @@ -95,6 +101,7 @@ public final class SkullManager { skullCauses.clear(); setSkullIcon(-1); setSkulled(false); + player.getAppearance().sync(); } /** @@ -118,6 +125,10 @@ public final class SkullManager { * @param level the level to set. */ public void setLevel(int level) { + if (!deepWilderness && level >= 49) + setDeepWilderness(true); + else if (deepWilderness && level < 48) + setDeepWilderness(false); this.level = level; } @@ -161,6 +172,10 @@ public final class SkullManager { return wildernessDisabled; } + public boolean hasWildernessProtection() { + return level < 49; + } + /** * Sets the wildernessDisabled. * @param wildernessDisabled The wildernessDisabled to set. @@ -174,9 +189,19 @@ public final class SkullManager { * @return The skulled. */ public boolean isSkulled() { - return skulled; + return skulled || deepWilderness; } + public boolean isDeepWilderness() { + return deepWilderness; + } + + public void setDeepWilderness (boolean deepWildy) { + setSkullIcon(deepWildy ? 1 : skulled ? 0 : -1); + setSkullCheckDisabled(deepWildy); + deepWilderness = deepWildy; + } + /** * Sets the skulled. * @param skulled The skulled to set. diff --git a/Server/src/main/core/game/world/map/zone/impl/WildernessZone.java b/Server/src/main/core/game/world/map/zone/impl/WildernessZone.java index 6d38f312b..6a0c77a05 100644 --- a/Server/src/main/core/game/world/map/zone/impl/WildernessZone.java +++ b/Server/src/main/core/game/world/map/zone/impl/WildernessZone.java @@ -39,6 +39,9 @@ public final class WildernessZone extends MapZone { */ private static final WildernessZone INSTANCE = new WildernessZone(new ZoneBorders(2944, 3525, 3400, 3975), new ZoneBorders(3070, 9924, 3135, 10002), ZoneBorders.forRegion(12193), ZoneBorders.forRegion(11937)); + public static final String WILDERNESS_PROT_ATTR = "/save:wilderness-protection-active"; + public static final String WILDERNESS_HIGHER_NEXTFEE = "/save:wilderness-higher-next-fee"; + /** * The zone borders. */ @@ -69,7 +72,7 @@ public final class WildernessZone extends MapZone { double x = combatLevel; double A = 44044.5491; double B = -7360.19548; - return (int) (A + (B * Math.log(x))) / 2; + return (int) (A + (B * Math.log(x))); } /** @@ -87,33 +90,40 @@ public final class WildernessZone extends MapZone { } 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)) { + if (!(killer instanceof Player)) return; + + boolean isDeepWildy = ((Player) killer).getSkullManager().isDeepWilderness(); + boolean isValidTarget = e instanceof NPC && (isDeepWildy || e.asNpc().getName().contains("Revenant") || e.getId() == NPCs.CHAOS_ELEMENTAL_3200); + + if (!isValidTarget) return; - 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 cEleGloveRate = isDeepWildy ? 50 : 150; + int normalGloveRate = isDeepWildy ? 75 : 150; - 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()); - } - } - } + int pvpGearRate = getNewDropRate(e.asNpc().getDefinition().getCombatLevel()); + if (isDeepWildy) + pvpGearRate /= 2; + + if (RandomFunction.roll(e.getId() == NPCs.CHAOS_ELEMENTAL_3200 ? cEleGloveRate : normalGloveRate)) { + 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() + "!"); + } + + for (int j : PVP_GEAR) { + boolean chance = RandomFunction.roll(pvpGearRate); + 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()); + } + } } /** diff --git a/Server/worldprops/default.conf b/Server/worldprops/default.conf index 7ae65e2d8..c80e4c6e4 100644 --- a/Server/worldprops/default.conf +++ b/Server/worldprops/default.conf @@ -67,7 +67,7 @@ increased_door_time = false enable_botting = false max_adv_bots = 100 enable_doubling_money_scammers = true -wild_pvp_enabled = false +wild_pvp_enabled = true jad_practice_enabled = true #minimum HA value for announcements of bots selling on ge ge_announcement_limit = 500