From 05da44aa52ee3f4146fce28a920e0d24151a9c8b Mon Sep 17 00:00:00 2001 From: RiL <13897849-RiL0@users.noreply.gitlab.com> Date: Tue, 25 Apr 2023 14:21:00 +0000 Subject: [PATCH] Optimised, fixed and refactored container (bank/inventory/equipment) checks --- .../global/handlers/npc/NPCDepositListener.kt | 6 +- .../shortcuts/CatherbyGrappleShortcut.kt | 18 +-- .../falador/diary/FaladorAchievementDiary.kt | 6 +- .../BKFortressPlugin.java | 4 +- .../quest/arena/FightArenaListeners.kt | 4 +- .../quest/arena/FightslaveDialogue.kt | 4 +- .../ardougne/quest/arena/GeneralKhazardNPC.kt | 3 +- .../ardougne/quest/arena/GuardsDialogue.kt | 10 +- .../ardougne/quest/arena/JoeDialogue.kt | 4 +- .../ardougne/quest/arena/KelvinDialogue.kt | 4 +- .../diary/SeersVillageAchivementDiary.kt | 5 +- .../misc/zanaris/handlers/FairyRingPlugin.kt | 6 +- Server/src/main/core/api/ContentAPI.kt | 143 ++++++++++-------- 13 files changed, 114 insertions(+), 103 deletions(-) diff --git a/Server/src/main/content/global/handlers/npc/NPCDepositListener.kt b/Server/src/main/content/global/handlers/npc/NPCDepositListener.kt index 33c1f886a..31a928df7 100644 --- a/Server/src/main/content/global/handlers/npc/NPCDepositListener.kt +++ b/Server/src/main/content/global/handlers/npc/NPCDepositListener.kt @@ -1,6 +1,6 @@ package content.global.handlers.npc -import core.api.isEquipped +import core.api.anyInEquipment import core.api.openDepositBox import core.api.sendNPCDialogue import core.api.setInterfaceText @@ -14,9 +14,7 @@ class NPCDepositListener : InteractionListener { override fun defineListeners() { on(NPCs.PEER_THE_SEER_1288, IntType.NPC, "deposit") { player, _ -> - if (isEquipped(player, Items.FREMENNIK_SEA_BOOTS_1_14571) || - isEquipped(player, Items.FREMENNIK_SEA_BOOTS_2_14572) || - isEquipped(player, Items.FREMENNIK_SEA_BOOTS_3_14573)) { + if (anyInEquipment(player, Items.FREMENNIK_SEA_BOOTS_1_14571, Items.FREMENNIK_SEA_BOOTS_2_14572, Items.FREMENNIK_SEA_BOOTS_3_14573)) { openDepositBox(player) setInterfaceText(player, "Peer the Seer's Deposits", 11, 12) } else { diff --git a/Server/src/main/content/global/skill/agility/shortcuts/CatherbyGrappleShortcut.kt b/Server/src/main/content/global/skill/agility/shortcuts/CatherbyGrappleShortcut.kt index 90090ed16..2cefab3da 100644 --- a/Server/src/main/content/global/skill/agility/shortcuts/CatherbyGrappleShortcut.kt +++ b/Server/src/main/content/global/skill/agility/shortcuts/CatherbyGrappleShortcut.kt @@ -42,7 +42,7 @@ class CatherbyGrappleShortcut : InteractionListener { on(Scenery.ROCKS_17042, IntType.SCENERY, "grapple") { player, _ -> if (isPlayerInRangeToGrapple(player)) { - forceWalk(player, content.global.skill.agility.shortcuts.CatherbyGrappleShortcut.Companion.START_LOCATION, "smart") + forceWalk(player, START_LOCATION, "smart") } else { sendMessage(player, "Nothing interesting happens.") return@on true @@ -56,10 +56,10 @@ class CatherbyGrappleShortcut : InteractionListener { if (!doesPlayerHaveRequiredLevels(player)) { sendDialogueLines(player, "You need at least " + - content.global.skill.agility.shortcuts.CatherbyGrappleShortcut.Companion.REQUIREMENTS[Skills.AGILITY] + " " + Skills.SKILL_NAME[Skills.AGILITY] + ", " + - content.global.skill.agility.shortcuts.CatherbyGrappleShortcut.Companion.REQUIREMENTS[Skills.RANGE] + " " + Skills.SKILL_NAME[Skills.RANGE] + ", ", + REQUIREMENTS[Skills.AGILITY] + " " + Skills.SKILL_NAME[Skills.AGILITY] + ", " + + REQUIREMENTS[Skills.RANGE] + " " + Skills.SKILL_NAME[Skills.RANGE] + ", ", "and " + - content.global.skill.agility.shortcuts.CatherbyGrappleShortcut.Companion.REQUIREMENTS[Skills.STRENGTH] + " " + Skills.SKILL_NAME[Skills.STRENGTH] + " to use this shortcut." + REQUIREMENTS[Skills.STRENGTH] + " " + Skills.SKILL_NAME[Skills.STRENGTH] + " to use this shortcut." ) return@on true } @@ -70,7 +70,7 @@ class CatherbyGrappleShortcut : InteractionListener { override fun pulse() : Boolean { when (counter++) { 1 -> { - face(player, content.global.skill.agility.shortcuts.CatherbyGrappleShortcut.Companion.END_LOCATION) + face(player, END_LOCATION) // Audit: shows player climbing (probably a wall), need a cliff climb animation animate(player, Animation(4455)) } @@ -79,7 +79,7 @@ class CatherbyGrappleShortcut : InteractionListener { replaceScenery(rocks!!, rocks!!.id + 1, 10) } 8 -> { - teleport(player, content.global.skill.agility.shortcuts.CatherbyGrappleShortcut.Companion.END_LOCATION) + teleport(player, END_LOCATION) } 9 -> { sendMessage(player, "You successfully grapple the rock and climb the cliffside.") @@ -96,11 +96,11 @@ class CatherbyGrappleShortcut : InteractionListener { } private fun doesPlayerHaveRequiredItemsEquipped(player: Player): Boolean { - return isEquipped(player, Items.MITH_GRAPPLE_9419) && areAnyEquipped(player, *content.global.skill.agility.shortcuts.CatherbyGrappleShortcut.Companion.VALID_CROSSBOWS) + return inEquipment(player, Items.MITH_GRAPPLE_9419) && anyInEquipment(player, *VALID_CROSSBOWS) } private fun doesPlayerHaveRequiredLevels(player: Player): Boolean { - for ((skill, requiredLevel) in content.global.skill.agility.shortcuts.CatherbyGrappleShortcut.Companion.REQUIREMENTS) { + for ((skill, requiredLevel) in REQUIREMENTS) { if (!hasLevelDyn(player, skill, requiredLevel)) { return false } @@ -109,6 +109,6 @@ class CatherbyGrappleShortcut : InteractionListener { } private fun isPlayerInRangeToGrapple(player: Player): Boolean { - return inBorders(player, content.global.skill.agility.shortcuts.CatherbyGrappleShortcut.Companion.START_LOCATION.x - 2, content.global.skill.agility.shortcuts.CatherbyGrappleShortcut.Companion.START_LOCATION.y - 2, content.global.skill.agility.shortcuts.CatherbyGrappleShortcut.Companion.START_LOCATION.x, content.global.skill.agility.shortcuts.CatherbyGrappleShortcut.Companion.START_LOCATION.y) + return inBorders(player, START_LOCATION.x - 2, START_LOCATION.y - 2, START_LOCATION.x, START_LOCATION.y) } } diff --git a/Server/src/main/content/region/asgarnia/falador/diary/FaladorAchievementDiary.kt b/Server/src/main/content/region/asgarnia/falador/diary/FaladorAchievementDiary.kt index cf6ca2186..326146126 100644 --- a/Server/src/main/content/region/asgarnia/falador/diary/FaladorAchievementDiary.kt +++ b/Server/src/main/content/region/asgarnia/falador/diary/FaladorAchievementDiary.kt @@ -1,6 +1,6 @@ package content.region.asgarnia.falador.diary -import core.api.areEquipped +import core.api.allInEquipment import core.api.inBorders import core.game.node.entity.player.Player import core.game.node.entity.player.link.diary.DiaryType @@ -131,8 +131,8 @@ class FaladorAchievementDiary : DiaryEventHookBase(DiaryType.FALADOR) { DiaryLevel.HARD, HardTasks.DARK_WIZARDS_TOWER_ASCEND_IN_FULL_PROSELYTE_ARMOR, ) { player -> - areEquipped(player, *PROSELYTE_FULL_ARMOR_MALE) - || areEquipped(player, *PROSELYTE_FULL_ARMOR_FEMALE) + allInEquipment(player, *PROSELYTE_FULL_ARMOR_MALE) + || allInEquipment(player, *PROSELYTE_FULL_ARMOR_FEMALE) } ) diff --git a/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BKFortressPlugin.java b/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BKFortressPlugin.java index c97ef487b..9f3c3ad6d 100644 --- a/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BKFortressPlugin.java +++ b/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BKFortressPlugin.java @@ -18,7 +18,7 @@ import core.game.world.update.flag.context.Graphics; import core.plugin.Plugin; import org.rs09.consts.Items; -import static core.api.ContentAPIKt.isEquipped; +import static core.api.ContentAPIKt.allInEquipment; /** * Represents the black knights fortress node option plugin. @@ -140,7 +140,7 @@ public final class BKFortressPlugin extends OptionHandler { case 2337: // Guard Door - only check for uniform from outside switch (player.getLocation().getY()) { case 3514: // Outside constant Y location, block the player for checks - if(isEquipped(player, Items.BRONZE_MED_HELM_1139) && isEquipped(player, Items.IRON_CHAINBODY_1101)){ + if(allInEquipment(player, Items.BRONZE_MED_HELM_1139, Items.IRON_CHAINBODY_1101)){ DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); } else player.getDialogueInterpreter().open(4605, Repository.findNPC(4604), true); diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/FightArenaListeners.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/FightArenaListeners.kt index 135d41253..21ffa2068 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/arena/FightArenaListeners.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/FightArenaListeners.kt @@ -115,7 +115,7 @@ class FightArenaListeners : InteractionListener { when (player.location.y) { 3171 -> DoorActionHandler.handleAutowalkDoor(player, maingate.asScenery()) 3172 -> { - if (isEquipped(player, HELMET) && isEquipped(player, ARMOUR)) { + if (allInEquipment(player, HELMET, ARMOUR)) { openDialogue(player, EastDoorSupportDialogue()) } else { sendPlayerDialogue(player, "This door appears to be locked.") @@ -126,7 +126,7 @@ class FightArenaListeners : InteractionListener { when (player.location.x) { 2585 -> DoorActionHandler.handleAutowalkDoor(player, maingate.asScenery()) 2584 -> { - if (isEquipped(player, HELMET) && isEquipped(player, ARMOUR)) { + if (allInEquipment(player, HELMET, ARMOUR)) { openDialogue(player, WestDoorSupportDialogue()) } else { sendPlayerDialogue(player, "This door appears to be locked.") diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/FightslaveDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/FightslaveDialogue.kt index 25ac997a1..91f94752b 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/arena/FightslaveDialogue.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/FightslaveDialogue.kt @@ -1,6 +1,6 @@ package content.region.kandarin.ardougne.quest.arena -import core.api.isEquipped +import core.api.allInEquipment import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression import core.game.node.entity.npc.NPC @@ -14,7 +14,7 @@ import org.rs09.consts.NPCs class FightslaveDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (isEquipped(player!!, Items.KHAZARD_HELMET_74) && isEquipped(player!!, Items.KHAZARD_ARMOUR_75)) { + if (allInEquipment(player, Items.KHAZARD_HELMET_74, Items.KHAZARD_ARMOUR_75)) { playerl(FacialExpression.FRIENDLY, "Do you know of a Justin or Jeremy in this arena?").also { stage = 0 } } else { playerl(FacialExpression.FRIENDLY, "Do you know of a Justin or Jeremy in this arena?").also { stage = 1 } diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/GeneralKhazardNPC.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/GeneralKhazardNPC.kt index 73ace0354..974636182 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/arena/GeneralKhazardNPC.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/GeneralKhazardNPC.kt @@ -7,6 +7,7 @@ import core.game.dialogue.FacialExpression import core.game.node.entity.npc.NPC import core.game.world.map.RegionManager import core.tools.END_DIALOGUE +import org.rs09.consts.Items import org.rs09.consts.NPCs.GENERAL_KHAZARD_258 class GeneralKhazardDialogue : DialogueFile() { @@ -20,7 +21,7 @@ class GeneralKhazardDialogue : DialogueFile() { (questStage == 71) -> { when (stage) { - 0 -> if (!isEquipped(player!!, 74) && !isEquipped(player!!, 75)) { + 0 -> if (!anyInEquipment(player!!, Items.KHAZARD_HELMET_74, Items.KHAZARD_ARMOUR_75)) { sendPlayerDialogue(player!!, "General Khazard?").also { stage = 2 } } else { sendNPCDialogue(player!!, 258, "Who dares enter my home? You? A feeble traveller?").also { stage = 6 } diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/GuardsDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/GuardsDialogue.kt index 7b6cdd6f2..bc1082ffe 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/arena/GuardsDialogue.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/GuardsDialogue.kt @@ -1,6 +1,6 @@ package content.region.kandarin.ardougne.quest.arena -import core.api.isEquipped +import core.api.allInEquipment import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression import core.game.node.entity.npc.NPC @@ -16,7 +16,7 @@ class GuardsDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (isEquipped(player!!, Items.KHAZARD_HELMET_74) && isEquipped(player!!, Items.KHAZARD_ARMOUR_75)) { + if (allInEquipment(player, Items.KHAZARD_HELMET_74, Items.KHAZARD_ARMOUR_75)) { playerl(FacialExpression.FRIENDLY, "Hello.").also { stage = 0 } } else { playerl(FacialExpression.FRIENDLY, "Hi.").also { stage = 2 } @@ -49,7 +49,7 @@ class GuardsDialogue(player: Player? = null) : DialoguePlugin(player) { class KhazardGuard254Dialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (isEquipped(player!!, Items.KHAZARD_HELMET_74) && isEquipped(player!!, Items.KHAZARD_ARMOUR_75)) { + if (allInEquipment(player, Items.KHAZARD_HELMET_74, Items.KHAZARD_ARMOUR_75)) { playerl(FacialExpression.FRIENDLY, "Hello.").also { stage = 0 } } else { playerl(FacialExpression.FRIENDLY, "Hi.").also { stage = 7 } @@ -90,7 +90,7 @@ class KhazardGuard254Dialogue(player: Player? = null) : DialoguePlugin(player) { class KhazardGuard255Dialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (isEquipped(player!!, Items.KHAZARD_HELMET_74) && isEquipped(player!!, Items.KHAZARD_ARMOUR_75)) { + if (allInEquipment(player, Items.KHAZARD_HELMET_74, Items.KHAZARD_ARMOUR_75)) { playerl(FacialExpression.FRIENDLY, "Hello.").also { stage = 0 } } else { playerl(FacialExpression.FRIENDLY, "Hi.").also { stage = 2 } @@ -123,7 +123,7 @@ class KhazardGuard255Dialogue(player: Player? = null) : DialoguePlugin(player) { class KhazardGuard256Dialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (isEquipped(player!!, Items.KHAZARD_HELMET_74) && isEquipped(player!!, Items.KHAZARD_ARMOUR_75)) { + if (allInEquipment(player, Items.KHAZARD_HELMET_74, Items.KHAZARD_ARMOUR_75)) { playerl(FacialExpression.FRIENDLY, "Hello.").also { stage = 0 } } else { playerl(FacialExpression.FRIENDLY, "Hi.").also { stage = 3 } diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/JoeDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/JoeDialogue.kt index 27531da01..34ba25eae 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/arena/JoeDialogue.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/JoeDialogue.kt @@ -1,6 +1,6 @@ package content.region.kandarin.ardougne.quest.arena -import core.api.isEquipped +import core.api.allInEquipment import core.api.sendNPCDialogue import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression @@ -16,7 +16,7 @@ class JoeDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (isEquipped(player!!, Items.KHAZARD_HELMET_74) && isEquipped(player!!, Items.KHAZARD_ARMOUR_75)) { + if (allInEquipment(player, Items.KHAZARD_HELMET_74, Items.KHAZARD_ARMOUR_75)) { playerl(FacialExpression.FRIENDLY, "Do you know of a Justin or Jeremy in this arena?").also { stage = 0 } } else { playerl(FacialExpression.FRIENDLY, "Do you know of a Justin or Jeremy in this arena?").also { stage = 3 } diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/KelvinDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/KelvinDialogue.kt index 71096d4cd..8890881ee 100644 --- a/Server/src/main/content/region/kandarin/ardougne/quest/arena/KelvinDialogue.kt +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/KelvinDialogue.kt @@ -1,6 +1,6 @@ package content.region.kandarin.ardougne.quest.arena -import core.api.isEquipped +import core.api.allInEquipment import core.api.sendNPCDialogue import core.game.dialogue.DialoguePlugin import core.game.dialogue.FacialExpression @@ -15,7 +15,7 @@ import org.rs09.consts.NPCs class KelvinDialogue(player: Player? = null) : DialoguePlugin(player) { override fun open(vararg args: Any?): Boolean { npc = args[0] as NPC - if (isEquipped(player, Items.KHAZARD_HELMET_74) && isEquipped(player, Items.KHAZARD_ARMOUR_75)) { + if (allInEquipment(player, Items.KHAZARD_HELMET_74, Items.KHAZARD_ARMOUR_75)) { sendNPCDialogue(player, NPCs.KELVIN_260, "Get away, get away. One day I'll have my revenge, and I'll have all your heads.", FacialExpression.ANNOYED).also { stage = END_DIALOGUE } } else { sendNPCDialogue(player, NPCs.KELVIN_260, "You're not safe here traveller. Leave while you still can", FacialExpression.FRIENDLY).also { stage = END_DIALOGUE } diff --git a/Server/src/main/content/region/kandarin/seers/diary/SeersVillageAchivementDiary.kt b/Server/src/main/content/region/kandarin/seers/diary/SeersVillageAchivementDiary.kt index b2e7eb072..015578c9c 100644 --- a/Server/src/main/content/region/kandarin/seers/diary/SeersVillageAchivementDiary.kt +++ b/Server/src/main/content/region/kandarin/seers/diary/SeersVillageAchivementDiary.kt @@ -1,6 +1,5 @@ package content.region.kandarin.seers.diary -import core.api.* import core.game.node.entity.player.Player import core.game.node.entity.player.link.diary.DiaryType import core.game.node.item.Item @@ -10,6 +9,8 @@ import org.rs09.consts.Items import org.rs09.consts.NPCs import content.global.handlers.iface.FairyRing import content.global.handlers.item.withnpc.PoisonChaliceOnKingArthurDialogue +import core.api.inBorders +import core.api.inEquipment import core.game.diary.DiaryEventHookBase import core.game.diary.DiaryLevel import core.game.event.* @@ -142,7 +143,7 @@ class SeersVillageAchivementDiary : DiaryEventHookBase(DiaryType.SEERS_VILLAGE) } Items.SHARK_385 -> { - if (isEquipped(player, Items.COOKING_GAUNTLETS_775)) { + if (inEquipment(player, Items.COOKING_GAUNTLETS_775)) { progressIncrementalTask( player, DiaryLevel.HARD, diff --git a/Server/src/main/content/region/misc/zanaris/handlers/FairyRingPlugin.kt b/Server/src/main/content/region/misc/zanaris/handlers/FairyRingPlugin.kt index a6b08daf5..01f468038 100644 --- a/Server/src/main/content/region/misc/zanaris/handlers/FairyRingPlugin.kt +++ b/Server/src/main/content/region/misc/zanaris/handlers/FairyRingPlugin.kt @@ -1,6 +1,6 @@ package content.region.misc.zanaris.handlers -import core.api.isEquipped +import core.api.anyInEquipment import core.api.isQuestComplete import core.game.component.Component import core.game.node.entity.player.Player @@ -42,11 +42,11 @@ class FairyRingPlugin : InteractionListener { } private fun fairyMagic(player: Player) : Boolean { - if(!isQuestComplete(player,"Lost City")) { // should be converted to a FTP2 stage requirement once FTP2 is implemented + if (!isQuestComplete(player,"Lost City")) { // should be converted to a FTP2 stage requirement once FTP2 is implemented player.sendMessage("The fairy ring is inert.") return false } - if(!isEquipped(player, Items.DRAMEN_STAFF_772) && !isEquipped(player,Items.LUNAR_STAFF_9084)) { + if (!anyInEquipment(player, Items.DRAMEN_STAFF_772, Items.LUNAR_STAFF_9084)) { player.sendMessage("The fairy ring only works for those who wield fairy magic.") return false } diff --git a/Server/src/main/core/api/ContentAPI.kt b/Server/src/main/core/api/ContentAPI.kt index 1ef6b9a1e..7f35d5de0 100644 --- a/Server/src/main/core/api/ContentAPI.kt +++ b/Server/src/main/core/api/ContentAPI.kt @@ -107,17 +107,6 @@ fun hasLevelStat(player: Player, skill: Int, level: Int): Boolean { return player.skills.getStaticLevel(skill) >= level } -/** - * Check if an item exists in a player's inventory - * @param player the player whose inventory to check - * @param item the ID of the item to check for - * @param amount the amount to check for - * @return true if the player has >= the given item in the given amount, false otherwise. - */ -fun inInventory(player: Player, item: Int, amount: Int = 1): Boolean { - return player.inventory.contains(item, amount) -} - /** * Check the amount of a given item in the player's inventory * @param player the player whose inventory to check @@ -132,10 +121,25 @@ fun amountInInventory(player: Player, id: Int): Int { * Check the amount of a given item in the player's bank * @param player the player to check * @param id the ID of the item to check for + * @param includeSecondary if the secondary bank should be included in the search * @return the amount of the ID in the player's bank. */ fun amountInBank(player: Player, id: Int, includeSecondary: Boolean = true): Int { - return player.bank.getAmount(id) + if (includeSecondary) player.bankSecondary.getAmount(id) else 0 + return getAmountInBank(player, id) + if (includeSecondary) getAmountInBank(player, id, true) else 0 +} + +/** + * More performant way to check the amount of a given item in the player's bank + * Uses the alwaysStack property of banks to short circuit the search. + * @param player the player to check + * @param id the ID of the item to check for + * @param secondary if the secondary bank should be searched instead + * @return the amount of the ID in the player's bank. + */ +private fun getAmountInBank(player: Player, id: Int, secondary: Boolean = false): Int { + val bank = if (secondary) player.bankSecondary.toArray() else player.bankPrimary.toArray() + bank.forEach { if (it?.id == id) return it.amount } + return 0 } /** @@ -145,22 +149,63 @@ fun amountInBank(player: Player, id: Int, includeSecondary: Boolean = true): Int * @return the amount of the ID in the player's equipment. */ fun amountInEquipment(player: Player, id: Int): Int { - return player.equipment.getAmount(id) + val slot = itemDefinition(id).getConfiguration(ItemConfigParser.EQUIP_SLOT, -1) + val equipped = player.equipment[slot] ?: return 0 + return if (equipped.id == id) equipped.amount else 0 } /** - * Check that an item is equipped by the given player + * Check if an item exists in a player's inventory + * @param player the player whose inventory to check + * @param id the ID of the item to check for + * @param amount the amount to check for + * @return true if the player has >= the given item in the given amount, false otherwise. */ -fun isEquipped(player: Player, id: Int): Boolean { - return amountInEquipment(player, id) > 0 +fun inInventory(player: Player, id: Int, amount: Int = 1): Boolean { + return player.inventory.contains(id, amount) +} + +/** + * Check if an item exists in a player's bank + * @param player the player whose bank to check + * @param id the ID of the item to check for + * @param amount the amount to check for, defaults to 1 + * @return true if the item exists in the given amount in the player's bank + */ +fun inBank(player: Player, id: Int, amount: Int = 1): Boolean { + return amountInBank(player, id) >= amount +} + +/** + * Check if an item exists in a player's equipment + * @param player the player whose equipment to check + * @param id the ID of the item to check for + * @param amount the amount to check for, defaults to 1 + * @return true if the item exists in the given amount in the player's equipment + */ +fun inEquipment(player: Player, id: Int, amount: Int = 1): Boolean { + return amountInEquipment(player, id) >= amount +} + +/** + * Check if an item exists in a player's equipment or inventory + * @param player the player whose equipment to check + * @param id the ID of the item to check for + * @param amount the amount to check for, defaults to 1 + * @return true if the item exists in the given amount in the player's equipment or inventory + */ +fun inEquipmentOrInventory(player: Player, id: Int, amount: Int = 1): Boolean { + // Proper, but slower implementation. Use faster unless need to check amounts split between equip/inv + //return amountInEquipment(player, id) + amountInInventory(player, id) >= amount + return inEquipment(player, id, amount) || inInventory(player, id, amount) } /** * Check that a set of items is equipped by the given player */ -fun areEquipped(player: Player, vararg ids: Int): Boolean { +fun allInEquipment(player: Player, vararg ids: Int): Boolean { return ids.all { id -> - amountInEquipment(player, id) > 0 + inEquipment(player, id) } } @@ -170,12 +215,22 @@ fun areEquipped(player: Player, vararg ids: Int): Boolean { * @param ids the set of item ids to check * @return true if the player has at least one of the items equipped, false if none are equipped */ -fun areAnyEquipped(player: Player, vararg ids: Int): Boolean { +fun anyInEquipment(player: Player, vararg ids: Int): Boolean { return ids.any { id -> - amountInEquipment(player, id) > 0 + inEquipment(player, id) } } +/** + * Gets the item in the given equipment slot for the given player + * @param player the player whose equipment to pull from + * @param slot the Equipment slot to use, EquipmentSlot enum contains the options. + * @return the Item in the given slot, or null if none. + */ +fun getItemFromEquipment(player: Player, slot: EquipmentSlot): Item? { + return player.equipment.get(slot.ordinal) +} + class ContainerisedItem(val container: core.game.container.Container?, val itemId: Int) { fun remove() : Boolean { return this.container?.remove(this.itemId.asItem()) ?: false @@ -207,7 +262,7 @@ fun hasAnItem(player: Player, vararg ids: Int): ContainerisedItem { * @return true if the player has an item corresponding to the given god, false otherwise */ fun hasGodItem(player: Player, god: God): Boolean { - god.validItems.forEach { if (amountInEquipment(player, it) > 0) return true } + god.validItems.forEach { if (inEquipment(player, it)) return true } return false } @@ -321,39 +376,6 @@ fun poofClear(npc: NPC) { }) } -/** - * Check if an item exists in a player's bank - * @param player the player whose bank to check - * @param item the ID of the item to check for - * @param amount the amount to check for, defaults to 1 - * @return true if the item exists in the given amount in the player's bank - */ -fun inBank(player: Player, item: Int, amount: Int = 1): Boolean { - return player.bank.contains(item, amount) || player.bankSecondary.contains(item, amount) -} - -/** - * Check if an item exists in a player's equipment - * @param player the player whose equipment to check - * @param item the ID of the item to check for - * @param amount the amount to check for, defaults to 1 - * @return true if the item exists in the given amount in the player's equipment - */ -fun inEquipment(player: Player, item: Int, amount: Int = 1): Boolean { - return player.equipment.contains(item, amount) -} - -/** - * Check if an item exists in a player's equipment or inventory - * @param player the player whose equipment to check - * @param item the ID of the item to check for - * @param amount the amount to check for, defaults to 1 - * @return true if the item exists in the given amount in the player's equipment or inventory - */ -fun inEquipmentOrInventory(player: Player, item: Int, amount: Int = 1): Boolean { - return inInventory(player, item, amount) || inEquipment(player, item, amount) -} - /** * Get number of free slots in a player's inventory * @param player the player to check @@ -1068,16 +1090,6 @@ fun stopWalk(entity: Entity) { entity.walkingQueue.reset() } -/** - * Gets the item in the given equipment slot for the given player - * @param player the player whose equipment to pull from - * @param slot the Equipment slot to use, EquipmentSlot enum contains the options. - * @return the Item in the given slot, or null if none. - */ -fun getItemFromEquipment(player: Player, slot: EquipmentSlot): Item? { - return player.equipment.get(slot.ordinal) -} - /** * Returns a list of all valid children IDs for a given scenery ID */ @@ -1746,8 +1758,7 @@ fun unnote(item: Item): Item { * @return True if Seal of Passage present, false otherwise. */ fun hasSealOfPassage(player: Player): Boolean { - return isEquipped(player, Items.SEAL_OF_PASSAGE_9083) - || inInventory(player, Items.SEAL_OF_PASSAGE_9083) + return inEquipmentOrInventory(player, Items.SEAL_OF_PASSAGE_9083) } /**