From 187c51304448352469a6fd94609bc09d19056d8b Mon Sep 17 00:00:00 2001 From: Player Name Date: Wed, 1 Apr 2026 14:20:48 +0000 Subject: [PATCH] Fixed amulet of glory teleport destination for Al-Kharid Fixed amulet of glory destination spelling Mounted amulet of glory fixes Fixed some examine texts Fixed POH portal build requirements Fixed some related typos Corrected teleport location for Draynor Village Fixed bug where random events could interrupt teleports Enabled the Burgh de Rott star location Rewrote enchanted jewellery teleports Improved replacement of spent slayer rings --- Server/data/configs/object_configs.json | 42 +++---- .../main/content/data/EnchantedJewellery.kt | 109 ++++++++++-------- .../activity/shootingstar/ShootingStar.kt | 2 +- .../shootingstar/ShootingStarPlugin.kt | 4 +- .../item/EnchantedJewelleryListener.kt | 6 +- .../skill/construction/BuildingUtils.java | 37 ++---- .../global/skill/construction/Decoration.java | 79 +++++++++---- .../portalchamber/PortalChamberPlugin.java | 13 ++- .../decoration/questhall/MountedGlory.kt | 55 ++++----- .../questhall/MountedGloryPlugin.java | 98 ---------------- Server/src/main/core/api/ContentAPI.kt | 7 +- .../node/entity/combat/ImpactHandler.java | 2 +- .../entity/player/link/TeleportManager.java | 1 + 13 files changed, 191 insertions(+), 264 deletions(-) delete mode 100644 Server/src/main/content/global/skill/construction/decoration/questhall/MountedGloryPlugin.java diff --git a/Server/data/configs/object_configs.json b/Server/data/configs/object_configs.json index ae364fd37..1dffc0568 100644 --- a/Server/data/configs/object_configs.json +++ b/Server/data/configs/object_configs.json @@ -19168,87 +19168,87 @@ "ids": "13614" }, { - "examine": "A gateway to Varrock", + "examine": "A gateway to Varrock.", "ids": "13615" }, { - "examine": "A gateway to Lumbridge", + "examine": "A gateway to Lumbridge.", "ids": "13616" }, { - "examine": "A gateway to Falador", + "examine": "A gateway to Falador.", "ids": "13617" }, { - "examine": "A gateway to Camelot", + "examine": "A gateway to Camelot.", "ids": "13618" }, { - "examine": "A gateway to Ardougne", + "examine": "A gateway to Ardougne.", "ids": "13619" }, { - "examine": "A gateway to the Yanille watchtower", + "examine": "A gateway to the Yanille watchtower.", "ids": "13620" }, { - "examine": "A gateway to Trollheim", + "examine": "A gateway to Kharyrll.", "ids": "13621" }, { - "examine": "A gateway to Varrock", + "examine": "A gateway to Varrock.", "ids": "13622" }, { - "examine": "A gateway to Lumbridge", + "examine": "A gateway to Lumbridge.", "ids": "13623" }, { - "examine": "A gateway to Falador", + "examine": "A gateway to Falador.", "ids": "13624" }, { - "examine": "A gateway to Camelot", + "examine": "A gateway to Camelot.", "ids": "13625" }, { - "examine": "A gateway to Ardougne", + "examine": "A gateway to Ardougne.", "ids": "13626" }, { - "examine": "A gateway to the Yanille watchtower", + "examine": "A gateway to the Yanille watchtower.", "ids": "13627" }, { - "examine": "A gateway to Trollheim", + "examine": "A gateway to Kharyrll.", "ids": "13628" }, { - "examine": "A gateway to Varrock", + "examine": "A gateway to Varrock.", "ids": "13629" }, { - "examine": "A gateway to Lumbridge", + "examine": "A gateway to Lumbridge.", "ids": "13630" }, { - "examine": "A gateway to Falador", + "examine": "A gateway to Falador.", "ids": "13631" }, { - "examine": "A gateway to Camelot", + "examine": "A gateway to Camelot.", "ids": "13632" }, { - "examine": "A gateway to Ardougne", + "examine": "A gateway to Ardougne.", "ids": "13633" }, { - "examine": "A gateway to the Yanille watchtower", + "examine": "A gateway to the Yanille watchtower.", "ids": "13634" }, { - "examine": "A gateway to Trollheim", + "examine": "A gateway to Kharyrll.", "ids": "13635" }, { diff --git a/Server/src/main/content/data/EnchantedJewellery.kt b/Server/src/main/content/data/EnchantedJewellery.kt index cb94545e5..a0c53ad00 100644 --- a/Server/src/main/content/data/EnchantedJewellery.kt +++ b/Server/src/main/content/data/EnchantedJewellery.kt @@ -11,11 +11,13 @@ import core.game.node.entity.player.Player import core.game.node.entity.player.link.TeleportManager import core.game.node.item.Item import core.game.system.task.Pulse +import core.game.world.GameWorld import core.game.world.map.Location import core.game.world.update.flag.context.Animation import core.game.world.update.flag.context.Graphics import org.rs09.consts.Items import core.game.world.GameWorld.Pulser +import core.tools.Log import org.rs09.consts.Sounds import java.util.* @@ -73,17 +75,17 @@ enum class EnchantedJewellery( ), AMULET_OF_GLORY( arrayOf( - "Edgeville.", - "Karamja.", - "Draynor Village.", - "Al-Kharid.", - "Nowhere." + "Edgeville", + "Karamja", + "Draynor Village", + "Al Kharid", + "Nowhere" ), arrayOf( Location.create(3087, 3495, 0), Location.create(2919, 3175, 0), Location.create(3104, 3249, 0), - Location.create(3304, 3124, 0) + Location.create(3292, 3175, 0) ), Items.AMULET_OF_GLORY4_1712, Items.AMULET_OF_GLORY3_1710, @@ -209,7 +211,7 @@ enum class EnchantedJewellery( constructor(options: Array, locations: Array, vararg ids: Int) : this(options, locations, false, *ids) /** - * Method used when the player "Use"s the jewellery piece. + * Method used when the player clicks one of the options in the jewellery piece's options dialog. * @param player the player. * @param item the used jewellery item. * @param buttonID the button id. @@ -222,7 +224,7 @@ enum class EnchantedJewellery( } return } - attemptTeleport(player, item, buttonID, isEquipped) + attemptTeleport(player, item, buttonID, true, isEquipped) } /** @@ -230,43 +232,69 @@ enum class EnchantedJewellery( * @param player the player. * @param item the used jewellery item. * @param buttonID the button id. + * @param replace Whether to attempt replacing the item with its lower-charge version. Always true unless you generated a fake item in code. * @param isEquipped If the player is operating. */ - fun attemptTeleport(player: Player, item: Item, buttonID: Int, isEquipped: Boolean): Boolean { + fun attemptTeleport(player: Player, item: Item, buttonID: Int, replace: Boolean, isEquipped: Boolean): Boolean { val itemIndex = getItemIndex(item) val nextJewellery = Item(getNext(itemIndex)) if (!canTeleport(player, nextJewellery)) { return false } - Pulser.submit(object : Pulse(0) { - private var count = 0 - private var location = getLocation(buttonID) - override fun pulse(): Boolean { - when (count) { - 0 -> { - lock(player,4) - visualize(player, ANIMATION, GRAPHICS) - playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200) - player.impactHandler.disabledTicks = 4 - closeInterface(player) + val location = getLocation(buttonID) + player.scripts.delay = GameWorld.ticks + 4 + queueScript(player, 0, QueueStrength.SOFT) { stage -> + when (stage) { + 0 -> { + lock(player, 4) + visualize(player, ANIMATION, GRAPHICS) + playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200) + player.impactHandler.disabledTicks = 4 + closeInterface(player) + return@queueScript delayScript(player, 3) + } + 1 -> { + teleport(player, location) + resetAnimator(player) + unlock(player) + player.dispatch(TeleportEvent(TeleportManager.TeleportType.NORMAL, TeleportMethod.JEWELRY, item, location)) + if (!replace) { + return@queueScript stopExecuting(player) } - 3 -> { - teleport(player,location) - resetAnimator(player) - if (isLastItemIndex(itemIndex)) { - if (isCrumble) crumbleJewellery(player, item, isEquipped) - } else { - replaceJewellery(player, item, nextJewellery, isEquipped) + if (isLastItemIndex(itemIndex)) { + if (isSlayerRing(item)) { + if (isEquipped) { + // Remove it now, but only addItemOrDrop the gem after the teleport has procced + if (removeItem(player, item, Container.EQUIPMENT)) { + return@queueScript delayScript(player, 1) + } + log(this.javaClass, Log.ERR, "Error replacing slayer ring with enchanted gem (removeItem from equipment)") + } + // Not equipped -> can replace fluently + if (replaceSlot(player, item.slot, Item(Items.ENCHANTED_GEM_4155), item) == item) { + return@queueScript stopExecuting(player) + } + log(this.javaClass, Log.ERR, "Error replacing slayer ring with enchanted gem (replaceSlot)") } - unlock(player) - player.dispatch(TeleportEvent(TeleportManager.TeleportType.NORMAL, TeleportMethod.JEWELRY, item, location)) - return true + // Not slayer ring + if (isCrumble) { + val removeFrom = if (isEquipped) Container.EQUIPMENT else Container.INVENTORY + if (removeItem(player, item, removeFrom)) { + return@queueScript stopExecuting(player) + } + log(this.javaClass, Log.ERR, "Error crumbling jewelry") + } + } else { + replaceJewellery(player, item, nextJewellery, isEquipped) } } - count += 1 - return false + 2 -> { + addItemOrDrop(player, Items.ENCHANTED_GEM_4155) + sendMessage(player, "Your Ring of Slaying reverts back into a regular enchanted gem.") + } } - }) + return@queueScript stopExecuting(player) + } return true } @@ -278,21 +306,6 @@ enum class EnchantedJewellery( } } - private fun crumbleJewellery(player: Player, item: Item, isEquipped: Boolean) { - if (isEquipped) { - removeItem(player, item, Container.EQUIPMENT) - } else { - removeItem(player, item) - } - if (isSlayerRing(item)) { - queueScript(player, 1, QueueStrength.SOFT) { - addItemOrDrop(player, Items.ENCHANTED_GEM_4155) - sendMessage(player, "Your Ring of Slaying reverts back into a regular enchanted gem.") - return@queueScript stopExecuting(player) - } - } - } - private fun isSlayerRing(item: Item): Boolean { return (item.id in RING_OF_SLAYING.ids) } diff --git a/Server/src/main/content/global/activity/shootingstar/ShootingStar.kt b/Server/src/main/content/global/activity/shootingstar/ShootingStar.kt index 9432ea009..074ab27a6 100644 --- a/Server/src/main/content/global/activity/shootingstar/ShootingStar.kt +++ b/Server/src/main/content/global/activity/shootingstar/ShootingStar.kt @@ -49,7 +49,7 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando "South-west Varrock mine" to Location.create(3176, 3362, 0), // South-west Varrock mine / Champion's Guild mine "Varrock east bank" to Location.create(3259, 3407, 0), // Varrock east bank / Rune shop "Lumbridge Swamp south-east mine" to Location.create(3227, 3150, 0), // Lumbridge Swamp south-east mine - //"Burgh de Rott bank" to Location.create(3500, 3219, 0), // Burgh de Rott bank (requires quest to enter) + "Burgh de Rott bank" to Location.create(3500, 3219, 0), // Burgh de Rott bank (requires quest to enter) "Canifis Bank" to Location.create(3504, 3487, 0), // Canifis bank "Mos Le'Harmless bank" to Location.create(3687, 2969, 0), // Mos Le'Harmless bank (requires quest to enter but is currently accessible for Slayer) "Gnome stronghold Bank" to Location.create(2460, 3432, 0), // Gnome stronghold bank diff --git a/Server/src/main/content/global/activity/shootingstar/ShootingStarPlugin.kt b/Server/src/main/content/global/activity/shootingstar/ShootingStarPlugin.kt index 234c49c61..7368b7689 100644 --- a/Server/src/main/content/global/activity/shootingstar/ShootingStarPlugin.kt +++ b/Server/src/main/content/global/activity/shootingstar/ShootingStarPlugin.kt @@ -97,7 +97,7 @@ class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Com fun teleportToStar(player: Player) { val condition: (p: Player) -> Boolean = when (star.location.toLowerCase()) { "canifis bank" -> {p -> requireQuest(p, Quests.PRIEST_IN_PERIL, "to access this.")} - //"burgh de rott bank" -> {p -> hasRequirement(p, Quests.IN_AID_OF_THE_MYREQUE)} //disabled: crash + "burgh de rott bank" -> {p -> hasRequirement(p, Quests.IN_AID_OF_THE_MYREQUE)} "crafting guild" -> {p -> hasLevelStat(p, Skills.CRAFTING, 40)} "lletya bank" -> {p -> hasRequirement(p, Quests.MOURNINGS_END_PART_I)} "jatizso mine" -> {p -> hasRequirement(p, Quests.THE_FREMENNIK_ISLES)} @@ -120,7 +120,7 @@ class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Com 1 -> dialogue("WARNING: The star is located in the wilderness.").also { stage++ } 2 -> player.dialogueInterpreter.sendOptions("Teleport to the star?", "Yes", "No").also { stage++ } 3 -> when (buttonID) { - 1 -> end().also { teleportToStar(player) } + 1 -> teleportToStar(player) 2 -> end() } } diff --git a/Server/src/main/content/global/handlers/item/EnchantedJewelleryListener.kt b/Server/src/main/content/global/handlers/item/EnchantedJewelleryListener.kt index 2878628ac..549b69051 100644 --- a/Server/src/main/content/global/handlers/item/EnchantedJewelleryListener.kt +++ b/Server/src/main/content/global/handlers/item/EnchantedJewelleryListener.kt @@ -50,15 +50,15 @@ class EnchantedJewelleryListener : InteractionListener { jewellery.use(player, item, 0, isEquipped) return } - openDialogue(player,EnchantedJewelleryDialogueFile(jewellery,item,isEquipped)) + openDialogue(player,EnchantedJewelleryDialogueFile(jewellery, item, true, isEquipped)) } } - class EnchantedJewelleryDialogueFile(val jewellery: EnchantedJewellery, val item: Item, val isEquipped: Boolean) : DialogueFile() { + class EnchantedJewelleryDialogueFile(val jewellery: EnchantedJewellery, val item: Item, val replace: Boolean, val isEquipped: Boolean) : DialogueFile() { override fun handle(componentID: Int, buttonID: Int) { when (stage) { START_DIALOGUE -> { - interpreter!!.sendOptions("Where would you like to go?", *jewellery.options) + interpreter!!.sendOptions("Where would you like to teleport to?", *jewellery.options) stage++ } 1 -> end().also { jewellery.use(player!!, item, buttonID - 1, isEquipped) } diff --git a/Server/src/main/content/global/skill/construction/BuildingUtils.java b/Server/src/main/content/global/skill/construction/BuildingUtils.java index 02bfbd9c2..2ee636337 100644 --- a/Server/src/main/content/global/skill/construction/BuildingUtils.java +++ b/Server/src/main/content/global/skill/construction/BuildingUtils.java @@ -90,8 +90,6 @@ public final class BuildingUtils { for (int menuIndex = 0; menuIndex < 7; menuIndex++) { int itemsStringOffset = 97 + (menuIndex * 5); - - //97 + if (menuIndex >= hotspot.getDecorations().length || (hotspot.getDecorations()[menuIndex] != null && hotspot.getDecorations()[menuIndex].isInvisibleNode())) { for (int j = 0; j < 5; j++) { player.getPacketDispatch().sendString("", 396, itemsStringOffset + j); @@ -104,43 +102,24 @@ public final class BuildingUtils { Decoration decoration = hotspot.getDecorations()[menuIndex]; items[BUILD_INDEXES[menuIndex]] = new Item(decoration.getInterfaceItem()); player.getPacketDispatch().sendString(ItemDefinition.forId(decoration.getInterfaceItem()).getName(), 396, itemsStringOffset); - boolean hasRequirements = player.getSkills().getLevel(Skills.CONSTRUCTION) >= decoration.getLevel(); + boolean hasRequirements = player.getSkills().getLevel(Skills.CONSTRUCTION) >= decoration.getLevel(); //nails are checked in buildDecoration + Item[] reqItems = decoration.getItems(); + String[] reqsText = decoration.getReqsText(); for (int j = 0; j < 4; j++) { - if (j >= decoration.getItems().length) { - if (j == decoration.getItems().length && decoration.getNailAmount() > 0) { - player.getPacketDispatch().sendString("Nails: " + decoration.getNailAmount(), 396, (itemsStringOffset + 1) + j); - } else { - player.getPacketDispatch().sendString("", 396, (itemsStringOffset + 1) + j); - } - } else { - Item item = decoration.getItems()[j]; - if (!player.getInventory().containsItem(item)) { - hasRequirements = false; - } - String s = item.getName() + ": " + item.getAmount(); - /*if (j > 1 && (decoration == Decoration.RUNE_CASE1 || decoration == Decoration.RUNE_CASE2)) { - if (j == 3) { - offset--; - item = decoration.getItems()[++j]; - s = item.getName() + ": " + item.getAmount(); - } - item = decoration.getItems()[j + 1]; - s += ", " + item.getName() + ": " + item.getAmount(); - player.getPacketDispatch().sendString(s, 396, 15 + offset + j); - continue; - }*/ - player.getPacketDispatch().sendString(s, 396, (itemsStringOffset + 1) + j); + if (j < reqItems.length && !player.getInventory().containsItem(reqItems[j])) { + hasRequirements = false; } + player.getPacketDispatch().sendString(reqsText[j], 396, (itemsStringOffset + 1) + j); } if (hasRequirements) { c261Value += (1 << (menuIndex + 1)); } - setVarp(player, 1485 + menuIndex, hasRequirements || player.isStaff() ? 1 : 0); + setVarp(player, 1485 + menuIndex, hasRequirements || player.isStaff() ? 1 : 0); player.getPacketDispatch().sendString("Level " + decoration.getLevel(), 396, 140 + menuIndex); //player.getPacketDispatch().sendItemZoomOnInterface(items[i].protocol(), 50000, 396, 49 + i); } - setVarp(player, 261, c261Value); + setVarp(player, 261, c261Value); PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 396, 132, 8, items, false)); } diff --git a/Server/src/main/content/global/skill/construction/Decoration.java b/Server/src/main/content/global/skill/construction/Decoration.java index 6229dff82..4191cb1a9 100644 --- a/Server/src/main/content/global/skill/construction/Decoration.java +++ b/Server/src/main/content/global/skill/construction/Decoration.java @@ -454,7 +454,7 @@ public enum Decoration { * Quest hall decorations. */ ANTIDRAGON_SHIELD(13522, 8282, 47, 280, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.ANTI_DRAGON_SHIELD_1540) }, new Item[] { new Item(Items.ANTI_DRAGON_SHIELD_1540) }), - AMULET_OF_GLORY (13523, 8283, 47, 290, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.AMULET_OF_GLORY_1704) }, new Item[] { new Item(Items.AMULET_OF_GLORY_1704) }), + AMULET_OF_GLORY (13523, 8283, 47, 290, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.AMULET_OF_GLORY_1704) }, new Item[] { new Item(Items.AMULET_OF_GLORY_1704) }, new String[] { "Teak plank: 3", "Amulet of Glory", "(uncharged): 1" }), CAPE_OF_LEGENDS (13524, 8284, 47, 300, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.CAPE_OF_LEGENDS_1052) }, new Item[] { new Item(Items.CAPE_OF_LEGENDS_1052) }), KING_ARTHUR (13510, 8285, 35, 211, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.ARTHUR_PORTRAIT_7995) }), ELENA (13511, 8286, 35, 211, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.ELENA_PORTRAIT_7996) }), @@ -727,23 +727,42 @@ public enum Decoration { private final int[] objectIds; /** - * If this node should be invisible to user build options + * If this node should be invisible to user build options. */ private boolean invisibleNode; /** - * Constructs a new object, no items, no tools, no refund items. + * The requirements text to show for this node. + */ + private String[] reqsText = {"", "", "", ""}; + + private String[] generateDefaultReqsText(Item[] items, int nailAmount) { + String[] ret = {"", "", "", ""}; + for (int i = 0; i < 4; i++) { + if (i >= items.length) { + if (i == items.length && nailAmount > 0) { + ret[i] = "Nails: " + nailAmount; + } + } else { + ret[i] = items[i].getName() + ": " + items[i].getAmount(); + } + } + return ret; + } + + /** + * Constructs a new object, default items, default tools, default refund items, default requirements text. * @param objectId The object id. * @param interfaceItem The item id for the building interface. * @param level The level required. * @param experience The experience gained. */ Decoration(int objectId, int interfaceItem, int level, int experience) { - this(objectId, interfaceItem, level, experience, new int[] { Items.HAMMER_2347, Items.SAW_8794 }, new Item[] {}, new Item[] {}); + this(objectId, interfaceItem, level, experience, new int[] { Items.HAMMER_2347, Items.SAW_8794 }, new Item[] {}, new Item[] {}, new String[] {}); } /** - * Constructs a new object, no tools, no refund items. + * Constructs a new object, default tools, default refund items, default requirements text. * @param objectId The object id. * @param interfaceItem The item id for the building interface. * @param level The level required. @@ -751,11 +770,12 @@ public enum Decoration { * @param items The items required. */ Decoration(int objectId, int interfaceItem, int level, int experience, Item[] items) { - this(objectId, interfaceItem, level, experience, new int[] { Items.HAMMER_2347, Items.SAW_8794 }, items, new Item[] {}); + this(objectId, interfaceItem, level, experience, new int[] { Items.HAMMER_2347, Items.SAW_8794 }, items, new Item[] {}, new String[] {}); + this.reqsText = generateDefaultReqsText(items, getNailAmount()); } /** - * Constructs a new object, no refund items. + * Constructs a new object, default refund items, default requirements text. * @param objectId The object id. * @param interfaceItem The item id for the building interface. * @param level The level required. @@ -764,7 +784,8 @@ public enum Decoration { * @param items The items required. */ Decoration(int objectId, int interfaceItem, int level, int experience, int[] tools, Item[] items) { - this(objectId, interfaceItem, level, experience, tools, items, new Item[] {}); + this(objectId, interfaceItem, level, experience, tools, items, new Item[] {}, new String[] {}); + this.reqsText = generateDefaultReqsText(items, getNailAmount()); } /** @@ -777,7 +798,21 @@ public enum Decoration { * @param refundItems The items to be refunded when the item is removed. */ Decoration(int objectId, int interfaceItem, int level, int experience, Item[] items, Item[] refundItems) { - this(objectId, interfaceItem, level, experience, new int[] { Items.HAMMER_2347, Items.SAW_8794 }, items, refundItems); + this(objectId, interfaceItem, level, experience, new int[] { Items.HAMMER_2347, Items.SAW_8794 }, items, refundItems, new String[] {}); + this.reqsText = generateDefaultReqsText(items, getNailAmount()); + } + + /** + * Constructs a new object, default tools. + * @param objectId The object id. + * @param interfaceItem The item id for the building interface. + * @param level The level required. + * @param experience The experience gained. + * @param items The items required. + * @param refundItems The items to be refunded when the item is removed. + */ + Decoration(int objectId, int interfaceItem, int level, int experience, Item[] items, Item[] refundItems, String[] reqsText) { + this(objectId, interfaceItem, level, experience, new int[] { Items.HAMMER_2347, Items.SAW_8794 }, items, refundItems, reqsText); } /** @@ -789,8 +824,9 @@ public enum Decoration { * @param tools The tools needed. * @param items The items required. * @param refundItems The items to be refunded when the item is removed. + * @param reqsText The requirements text to be shown in the interface. */ - Decoration(int objectId, int interfaceItem, int level, int experience, int[] tools, Item[] items, Item[] refundItems) { + Decoration(int objectId, int interfaceItem, int level, int experience, int[] tools, Item[] items, Item[] refundItems, String[] reqsText) { this.objectId = objectId; this.objectIds = null; this.interfaceItem = interfaceItem; @@ -799,6 +835,9 @@ public enum Decoration { this.tools = tools; this.items = items; this.refundItems = refundItems; + if (reqsText.length > 0) { + System.arraycopy(reqsText, 0, this.reqsText, 0, reqsText.length); + } } /** @@ -822,18 +861,6 @@ public enum Decoration { Decoration(int[] objectIds, int interfaceItem, int level, int experience, Item[] items) { this(objectIds, interfaceItem, level, experience, new int[] { Items.HAMMER_2347, Items.SAW_8794 }, items, new Item[] {}); } - /** - * Constructs a new object no refund items. - * @param objectIds The object id. - * @param interfaceItem The item id for the building interface. - * @param level The level required. - * @param experience The experience gained. - * @param tools The tools needed. - * @param items The items required. - */ - Decoration(int[] objectIds, int interfaceItem, int level, int experience, int[] tools, Item[] items) { - this(objectIds, interfaceItem, level, experience, tools, items, new Item[] {}); - } /** * Constructs a new object. @@ -1000,4 +1027,12 @@ public enum Decoration { public boolean isInvisibleNode() { return invisibleNode; } + + /** + * Gets the requirements text. + * @return The requirements text. + */ + public String[] getReqsText() { + return reqsText; + } } diff --git a/Server/src/main/content/global/skill/construction/decoration/portalchamber/PortalChamberPlugin.java b/Server/src/main/content/global/skill/construction/decoration/portalchamber/PortalChamberPlugin.java index bf1f26c54..c154bef68 100644 --- a/Server/src/main/content/global/skill/construction/decoration/portalchamber/PortalChamberPlugin.java +++ b/Server/src/main/content/global/skill/construction/decoration/portalchamber/PortalChamberPlugin.java @@ -1,6 +1,7 @@ package content.global.skill.construction.decoration.portalchamber; +import content.data.Quests; import content.global.skill.construction.Hotspot; import content.global.skill.runecrafting.Rune; import core.cache.def.impl.SceneryDefinition; @@ -18,6 +19,7 @@ import core.plugin.Plugin; import core.plugin.ClassScanner; import static content.region.kandarin.ardougne.quest.plaguecity.PlagueCityListeners.ARDOUGNE_TELE_ATTRIBUTE; +import static core.api.ContentAPIKt.*; /** * PortalChamberPlugin @@ -89,15 +91,14 @@ public class PortalChamberPlugin extends OptionHandler { } for (Locations l : Locations.values()) { if (l.name().contains(identifier)) { - if (l == Locations.ARDOUGNE){ - if (!player.getAttribute(ARDOUGNE_TELE_ATTRIBUTE, false)) { - player.sendMessage("You do not have the requirements to direct the portal there"); - return; - } + if ((l == Locations.ARDOUGNE && !getAttribute(player, ARDOUGNE_TELE_ATTRIBUTE, false)) || + (l == Locations.KHARYRLL && !isQuestComplete(player, Quests.DESERT_TREASURE))) { + sendMessage(player, "You do not have the requirements to direct the portal there."); + return; } Item[] runes = l.runes; if (!player.getInventory().containsItems(runes)) { - player.sendMessage("You do not have the required runes to build this portal"); + sendMessage(player, "You do not have the required runes to build this portal."); return; } player.getInventory().remove(runes); diff --git a/Server/src/main/content/global/skill/construction/decoration/questhall/MountedGlory.kt b/Server/src/main/content/global/skill/construction/decoration/questhall/MountedGlory.kt index 47051e46f..b5196af4d 100644 --- a/Server/src/main/content/global/skill/construction/decoration/questhall/MountedGlory.kt +++ b/Server/src/main/content/global/skill/construction/decoration/questhall/MountedGlory.kt @@ -1,53 +1,53 @@ package content.global.skill.construction.decoration.questhall +import content.data.EnchantedJewellery +import content.global.handlers.item.EnchantedJewelleryListener.EnchantedJewelleryDialogueFile +import core.api.delayScript +import core.api.lock +import core.api.openDialogue import core.api.playGlobalAudio +import core.api.queueScript +import core.api.resetAnimator +import core.api.stopExecuting import core.api.teleport +import core.api.visualize import core.game.interaction.IntType import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength import core.game.node.Node import core.game.node.entity.player.Player import core.game.node.item.Item import core.game.node.scenery.Scenery -import core.game.system.task.Pulse -import core.game.world.map.Location import core.game.world.update.flag.context.Animation import core.game.world.update.flag.context.Graphics import org.rs09.consts.Items import org.rs09.consts.Sounds -import java.util.concurrent.Executors -import java.util.concurrent.TimeUnit class MountedGlory : InteractionListener { - val MOUNTED_GLORY = 13523 - - val TELEPORTS = arrayOf( - Location.create(3087, 3495, 0), - Location.create(2919, 3175, 0), - Location.create(3104, 3249, 0), - Location.create(3304, 3124, 0) - ) + val TELEPORTS = EnchantedJewellery.AMULET_OF_GLORY.locations override fun defineListeners() { on(MOUNTED_GLORY, IntType.SCENERY, "Edgeville") { player, `object` -> mountedGloryAction(player, `object`, 0) return@on true } - on(MOUNTED_GLORY, IntType.SCENERY, "Karamja") { player, `object` -> mountedGloryAction(player, `object`, 1) return@on true } - on(MOUNTED_GLORY, IntType.SCENERY, "Draynor Village") { player, `object` -> mountedGloryAction(player, `object`, 2) return@on true } - on(MOUNTED_GLORY, IntType.SCENERY, "Al Kharid") { player, `object` -> mountedGloryAction(player, `object`, 3) return@on true } + on(MOUNTED_GLORY, IntType.SCENERY, "Rub") { player, _ -> + openDialogue(player,EnchantedJewelleryDialogueFile(EnchantedJewellery.AMULET_OF_GLORY, Item(Items.AMULET_OF_GLORY4_1712), false, false)) + return@on true + } } private fun mountedGloryAction(player : Player, `object` : Node, int : Int) { if (player.houseManager.isBuildingMode) { @@ -57,21 +57,16 @@ class MountedGlory : InteractionListener { if (!player.zoneMonitor.teleport(1, Item(Items.AMULET_OF_GLORY_1704))) { return } - Executors.newSingleThreadScheduledExecutor().schedule({ - player.pulseManager.run(object : Pulse() { - var counter = 0 - override fun pulse(): Boolean { - when (counter++) { - 1 -> { - player.lock(5) - player.visualize(Animation(714), Graphics(308, 100, 50)) - playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200) - } - 4 -> player.animator.reset().also { teleport(player, TELEPORTS[int]) } - } - return false + queueScript(player, 0, QueueStrength.SOFT) { stage -> + if (stage == 0) { + lock(player, 4) + visualize(player, Animation(714), Graphics(308, 100, 50)) + playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200) + return@queueScript delayScript(player, 3) } - }) - }, 0, TimeUnit.SECONDS) + resetAnimator(player) + teleport(player, TELEPORTS[int]) + return@queueScript stopExecuting(player) + } } } diff --git a/Server/src/main/content/global/skill/construction/decoration/questhall/MountedGloryPlugin.java b/Server/src/main/content/global/skill/construction/decoration/questhall/MountedGloryPlugin.java deleted file mode 100644 index 90d96eb80..000000000 --- a/Server/src/main/content/global/skill/construction/decoration/questhall/MountedGloryPlugin.java +++ /dev/null @@ -1,98 +0,0 @@ -package content.global.skill.construction.decoration.questhall; - - -import core.cache.def.impl.SceneryDefinition; -import core.game.dialogue.DialogueAction; -import core.game.dialogue.DialogueInterpreter; -import core.game.interaction.OptionHandler; -import core.game.node.Node; -import core.game.node.entity.player.Player; -import core.game.system.task.Pulse; -import core.game.world.GameWorld; -import core.game.world.map.Location; -import core.game.world.update.flag.context.Animation; -import core.game.world.update.flag.context.Graphics; -import core.plugin.Initializable; -import core.plugin.Plugin; -import org.rs09.consts.Sounds; - -import static core.api.ContentAPIKt.playGlobalAudio; - -/** - * Handles the POH Mounted Glory. - * @author Splinter - */ -@Initializable -public class MountedGloryPlugin extends OptionHandler { - - /** - * Represents the teleport animation. - */ - private static final Animation ANIMATION = new Animation(714); - - /** - * Represents the graphics to use. - */ - private static final Graphics GRAPHICS = new Graphics(308, 100, 50); - - @Override - public Plugin newInstance(Object arg) throws Throwable { - SceneryDefinition.forId(13523).getHandlers().put("option:rub", this); - return this; - } - - @Override - public boolean handle(Player player, Node node, String option) { - DialogueInterpreter interpreter = player.getDialogueInterpreter(); - interpreter.sendOptions("Select a location.", "Edgeville", "Karamja", "Draynor Village", "Al-Kharid", "Nowhere."); - interpreter.addAction(new DialogueAction() { - - @Override - public void handle(Player player, int buttonId) { - switch (buttonId) { - case 2: - teleport(player, Location.create(3087, 3495, 0)); - break; - case 3: - teleport(player, Location.create(2919, 3175, 0)); - break; - case 4: - teleport(player, Location.create(3081, 3250, 0)); - break; - case 5: - teleport(player, Location.create(3304, 3124, 0)); - break; - } - } - - }); - return true; - } - - /** - * Method used to teleport to a location. - * @param player the player. - * @param location the location. - */ - private boolean teleport(final Player player, final Location location) { - if (player.isTeleBlocked()) { - player.sendMessage("A magical force has stopped you from teleporting."); - return false; - } - player.lock(); - player.visualize(ANIMATION, GRAPHICS); - playGlobalAudio(player.getLocation(), Sounds.TELEPORT_ALL_200); - player.getImpactHandler().setDisabledTicks(4); - GameWorld.getPulser().submit(new Pulse(4, player) { - @Override - public boolean pulse() { - player.unlock(); - player.getProperties().setTeleportLocation(location); - player.getAnimator().reset(); - return true; - } - }); - return true; - } - -} \ No newline at end of file diff --git a/Server/src/main/core/api/ContentAPI.kt b/Server/src/main/core/api/ContentAPI.kt index f5b12c1e4..39c27cc05 100644 --- a/Server/src/main/core/api/ContentAPI.kt +++ b/Server/src/main/core/api/ContentAPI.kt @@ -418,7 +418,7 @@ fun replaceSlot(player: Player, slot: Int, item: Item, currentItem: Item? = null } if (cont.remove(currentItem, slot, true)) { - return cont.replace(item, slot) + return cont.replace(item, slot) ?: currentItem } PlayerMonitor.log(player, LogType.DUPE_ALERT, "Potential slot-replacement-based dupe attempt, slot: $slot, item: $item") @@ -426,8 +426,9 @@ fun replaceSlot(player: Player, slot: Int, item: Item, currentItem: Item? = null Container.INVENTORY -> Container.EQUIPMENT else -> Container.INVENTORY } - if (removeItem(player, currentItem, other)) - return cont.replace(item, slot) + if (removeItem(player, currentItem, other)) { + return cont.replace(item, slot) ?: currentItem + } return null } diff --git a/Server/src/main/core/game/node/entity/combat/ImpactHandler.java b/Server/src/main/core/game/node/entity/combat/ImpactHandler.java index 6e49734ec..b3a6a6bec 100644 --- a/Server/src/main/core/game/node/entity/combat/ImpactHandler.java +++ b/Server/src/main/core/game/node/entity/combat/ImpactHandler.java @@ -212,7 +212,7 @@ public final class ImpactHandler { int percentage = (int) (entity.getSkills().getStaticLevel(Skills.HITPOINTS) * 0.10); if (p.getSkills().getLifepoints() <= percentage) { Item rolItem = new Item(Items.RING_OF_LIFE_2570); - if (EnchantedJewellery.RING_OF_LIFE.attemptTeleport(p, rolItem, 0, true)) { + if (EnchantedJewellery.RING_OF_LIFE.attemptTeleport(p, rolItem, 0, true, true)) { p.sendMessage("Your ring of life saves you and in the process is destroyed."); } } diff --git a/Server/src/main/core/game/node/entity/player/link/TeleportManager.java b/Server/src/main/core/game/node/entity/player/link/TeleportManager.java index 3da78d55b..723b62b48 100644 --- a/Server/src/main/core/game/node/entity/player/link/TeleportManager.java +++ b/Server/src/main/core/game/node/entity/player/link/TeleportManager.java @@ -97,6 +97,7 @@ public class TeleportManager { if (teleportType != -1) { if (entity instanceof Player) { Player p = (Player) entity; + p.scripts.setDelay(GameWorld.getTicks() + 12); p.getDialogueInterpreter().close(); } }