From 002176cff6b383bc0d0aeea7582959458dc3ed87 Mon Sep 17 00:00:00 2001 From: voidstarr <3334013+voidstarr@users.noreply.github.com> Date: Fri, 16 Jan 2026 15:28:09 -0800 Subject: [PATCH 01/10] fix QueueTask.produceItemBox as the cs2 script has been updated in rev 235 --- .../kotlin/org/alter/api/ext/QueueTaskExt.kt | 82 +++++++++++++++---- 1 file changed, 65 insertions(+), 17 deletions(-) diff --git a/game-api/src/main/kotlin/org/alter/api/ext/QueueTaskExt.kt b/game-api/src/main/kotlin/org/alter/api/ext/QueueTaskExt.kt index ff664ca3..fbaeb327 100644 --- a/game-api/src/main/kotlin/org/alter/api/ext/QueueTaskExt.kt +++ b/game-api/src/main/kotlin/org/alter/api/ext/QueueTaskExt.kt @@ -20,6 +20,7 @@ import org.alter.game.pluginnew.event.impl.DialogMessageOption import org.alter.game.pluginnew.event.impl.DialogNpcOpen import org.alter.game.pluginnew.event.impl.DialogPlayerOpen import org.alter.game.pluginnew.event.impl.DialogSkillMulti +import org.alter.game.pluginnew.event.EventManager import org.alter.rscm.RSCM.asRSCM @@ -273,22 +274,44 @@ suspend fun QueueTask.doubleItemMessageBox( * Prompts the player with skill menu for making things. * * @param items - * The possible [Item] products the menu presents as options. - * Note| max is 10 + * The possible product item ids the menu presents as options. + * This UI supports up to 18 items (components a..r). Extra items are ignored. * * @param title - * Title String to display atop the prompt. + * Title string to display atop the prompt. * * @param maxProducable * The possible number of products which could be made from the available input mats. * Note| defaults to full inventory as being possible * * @param logic - * The logic to be executed upon response using selected [Item] from prompt - * and quantity as indicated by response slot message. + * Callback invoked with `(selectedItemId, quantity)` after the player responds. + * + * ## ClientScript contract + * This function is a server-side wrapper around the clientscript `skillmulti_setup`. + * The reference dump for the script (signature + behaviour) is: + * https://github.com/Joshua-F/osrs-dumps/blob/ef7ba91167f84b05792373056ad4c9d374041394/script/%5Bclientscript%2Cskillmulti_setup%5D.cs2 + * + * The script expects arguments in this shape: + * - `int0`: mode/type (we pass `0`) + * - `string0`: payload formatted as `Title|Name1|Name2|...` + * - `int1`: max producible (used for quantity button setup/clamping) + * - `obj2..obj19`: up to 18 item ids; unused obj slots should be sent as `-1` (treated as null obj) + * - `int20`: suggested quantity + * + * If the argument count/order is wrong, the interface can open but appear blank. + * + * ## Ordering / race avoidance + * The interface must be opened client-side before `skillmulti_setup` runs. Since dialog open events + * are posted through an async event bus, we open the interface synchronously (`postAndWait`) to + * avoid races where the script runs before the modal exists. + * + * ## Selection mapping + * Mapping from the incoming resume packet (`ResumePauseButton.componentId`) to an item index is + * revision-dependent. The current implementation assumes item components start at child id `15`. * * @return - * The id of the option chosen. The id can range from [1] inclusive to [9] inclusive. + * The selected item id and quantity are delivered to [logic]. */ suspend fun QueueTask.produceItemBox( player: Player, @@ -298,24 +321,49 @@ suspend fun QueueTask.produceItemBox( logic: Player.(Int, Int) -> Unit, ) { - val itemDefs = items.map { getItem(it) } + // `skillmulti_setup` (CS2) takes 18 obj slots (obj2..obj19) and a trailing suggested quantity (int20). + // If we call it with the wrong argument count/order, the clientscript can fail and the interface appears blank. + val maxSelectable = 18 + val scriptSlots = 18 + + val displayedItems = items.take(maxSelectable) + val displayedDefs = displayedItems.mapNotNull { itemId -> getItem(itemId)?.let { def -> itemId to def } } + if (displayedDefs.isEmpty()) { + player.message("You can't think of any options.") + return + } val baseChild = 15 - val itemArray = Array(15) { -1 } - val nameArray = Array(15) { "|" } + val itemArray = Array(scriptSlots) { -1 } + displayedDefs.withIndex().forEach { (index, pair) -> + itemArray[index] = pair.second.id + } - itemDefs.withIndex().forEach { - val def = it.value - itemArray[it.index] = def!!.id - nameArray[it.index] = "|${def.name}" + val nameString = buildString { + append(title) + displayedDefs.forEach { (_, def) -> + append("|") + append(def.name) + } } + val suggestedQuantity = 1 + player.runClientScript(CommonClientScripts.CHATBOX_RESET_BACKGROUND) player.sendTempVarbit("varbits.chatmodal_unclamp", 1) - DialogSkillMulti(player).post() + // Open the interface synchronously; the async event bus can otherwise race and + // run the clientscript before the interface exists client-side. + EventManager.postAndWait(DialogSkillMulti(player)) - player.runClientScript(CommonClientScripts.SKILL_MULTI_SETUP, 0, "$title${nameArray.joinToString("")}", maxProducable, *itemArray) + player.runClientScript( + CommonClientScripts.SKILL_MULTI_SETUP, + 0, + nameString, + maxProducable, + *itemArray, + suggestedQuantity + ) terminateAction = closeDialog(player) waitReturnValue() @@ -325,11 +373,11 @@ suspend fun QueueTask.produceItemBox( val child = msg.componentId - if (child < baseChild || child >= baseChild + items.size) { + if (child < baseChild || child >= baseChild + displayedDefs.size) { return } - val item = items[child - baseChild] + val item = displayedDefs[child - baseChild].first val qty = msg.sub logic(player, item, qty) From c7ea64eb4e91bd436db6a071aa3c1aba12147d81 Mon Sep 17 00:00:00 2001 From: voidstarr <3334013+voidstarr@users.noreply.github.com> Date: Fri, 16 Jan 2026 15:29:00 -0800 Subject: [PATCH 02/10] ignore .vscode/ --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 7f6d6899..84555139 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /.gradle/ +.vscode/ build/ g=out/ gen/ From 57232ea923b531a5b4de85f692de6b9ffc2e1ee9 Mon Sep 17 00:00:00 2001 From: voidstarr <3334013+voidstarr@users.noreply.github.com> Date: Fri, 16 Jan 2026 15:29:42 -0800 Subject: [PATCH 03/10] allow for the settings interface to close --- .../interfaces/settings/SettingsSideEvents.kt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/content/src/main/kotlin/org/alter/interfaces/settings/SettingsSideEvents.kt b/content/src/main/kotlin/org/alter/interfaces/settings/SettingsSideEvents.kt index 35b0a3fe..b2018db0 100644 --- a/content/src/main/kotlin/org/alter/interfaces/settings/SettingsSideEvents.kt +++ b/content/src/main/kotlin/org/alter/interfaces/settings/SettingsSideEvents.kt @@ -6,6 +6,7 @@ import org.alter.game.model.entity.Player import org.alter.game.pluginnew.PluginEvent import org.alter.game.pluginnew.event.impl.onButton import org.alter.game.pluginnew.event.impl.onIfOpen +import org.alter.interfaces.ifCloseOverlay import org.alter.interfaces.ifOpenOverlay import org.alter.interfaces.ifSetEvents import org.alter.interfaces.settings.configs.setting_components @@ -16,6 +17,11 @@ class SettingsSideScript : PluginEvent() { override fun init() { onIfOpen("interfaces.settings_side") { player.updateIfEvents() } + onIfOpen("interfaces.settings") { + player.ifSetEvents("components.settings:close", 0..0, IfEvent.Op1) + player.ifSetEvents("components.settings:dropdown_close", 0..0, IfEvent.Op1) + } + SettingsTabView.entries.forEach { onButton(it.component) { player.setVarbit("varbits.settings_side_panel_tab",it.varValue) @@ -25,6 +31,14 @@ class SettingsSideScript : PluginEvent() { onButton(setting_components.settings_open) { player.ifOpenOverlay("interfaces.settings") } + + onButton("components.settings:close") { + player.ifCloseOverlay("interfaces.settings") + } + + onButton("components.settings:dropdown_close") { + player.ifCloseOverlay("interfaces.settings") + } } private fun Player.updateIfEvents() { From e8f253c85991cf109ac8605ae8a5e43d0a71689c Mon Sep 17 00:00:00 2001 From: voidstarr <3334013+voidstarr@users.noreply.github.com> Date: Fri, 16 Jan 2026 15:31:08 -0800 Subject: [PATCH 04/10] cooking: start initial skill implementation - Add cooking recipe db table and pack it into cache tables - Implement cooking interactions for ranges/fires (cook click + item-on-object) - Show Make-X selection and process cooking loop (burn chance + xp) - Add simple recipe registry (lookup by raw/cooked) - Add DEV-only ::cooktest presets for quick testing - Define gamevals for cooking table + initial dbrows --- cache/src/main/kotlin/org/alter/CacheTools.kt | 2 + .../kotlin/org/alter/impl/skills/Cooking.kt | 147 ++++++++++++ .../developer/CookingTestCommandsPlugin.kt | 126 ++++++++++ .../org/alter/skills/cooking/CookingEvents.kt | 223 ++++++++++++++++++ .../alter/skills/cooking/CookingRecipes.kt | 11 + .../org/alter/skills/cooking/gamevals.toml | 16 ++ 6 files changed, 525 insertions(+) create mode 100644 cache/src/main/kotlin/org/alter/impl/skills/Cooking.kt create mode 100644 content/src/main/kotlin/org/alter/commands/developer/CookingTestCommandsPlugin.kt create mode 100644 content/src/main/kotlin/org/alter/skills/cooking/CookingEvents.kt create mode 100644 content/src/main/kotlin/org/alter/skills/cooking/CookingRecipes.kt create mode 100644 content/src/main/resources/org/alter/skills/cooking/gamevals.toml diff --git a/cache/src/main/kotlin/org/alter/CacheTools.kt b/cache/src/main/kotlin/org/alter/CacheTools.kt index 2af03a5d..46307e3a 100644 --- a/cache/src/main/kotlin/org/alter/CacheTools.kt +++ b/cache/src/main/kotlin/org/alter/CacheTools.kt @@ -18,6 +18,7 @@ import org.alter.codegen.startGeneration import org.alter.gamevals.GameValProvider import org.alter.gamevals.GamevalDumper import org.alter.impl.GameframeTable +import org.alter.impl.skills.Cooking import org.alter.impl.skills.Firemaking import org.alter.impl.misc.FoodTable import org.alter.impl.skills.PrayerTable @@ -43,6 +44,7 @@ fun tablesToPack() = listOf( TeleTabs.teleTabs(), StatComponents.statsComponents(), FoodTable.consumableFood(), + Cooking.recipes(), Firemaking.logs(), Woodcutting.trees(), Woodcutting.axes(), diff --git a/cache/src/main/kotlin/org/alter/impl/skills/Cooking.kt b/cache/src/main/kotlin/org/alter/impl/skills/Cooking.kt new file mode 100644 index 00000000..a1feab7c --- /dev/null +++ b/cache/src/main/kotlin/org/alter/impl/skills/Cooking.kt @@ -0,0 +1,147 @@ +package org.alter.impl.skills + +import dev.openrune.definition.dbtables.dbTable +import dev.openrune.definition.util.VarType + +object Cooking { + + const val COL_RAW = 0 + const val COL_COOKED = 1 + const val COL_BURNT = 2 + const val COL_LEVEL = 3 + const val COL_XP = 4 + const val COL_STOP_BURN_FIRE = 5 + const val COL_STOP_BURN_RANGE = 6 + + fun recipes() = dbTable("tables.cooking_recipes") { + + column("raw", COL_RAW, VarType.OBJ) + column("cooked", COL_COOKED, VarType.OBJ) + column("burnt", COL_BURNT, VarType.OBJ) + column("level", COL_LEVEL, VarType.INT) + column("xp", COL_XP, VarType.INT) + column("stop_burn_fire", COL_STOP_BURN_FIRE, VarType.INT) + column("stop_burn_range", COL_STOP_BURN_RANGE, VarType.INT) + + // Basic fish & meat (initial skill implementation) + row("dbrows.cooking_shrimps") { + columnRSCM(COL_RAW, "items.raw_shrimp") + columnRSCM(COL_COOKED, "items.shrimp") + columnRSCM(COL_BURNT, "items.burnt_shrimp") + column(COL_LEVEL, 1) + column(COL_XP, 30) + column(COL_STOP_BURN_FIRE, 34) + column(COL_STOP_BURN_RANGE, 33) + } + + row("dbrows.cooking_anchovies") { + columnRSCM(COL_RAW, "items.raw_anchovies") + columnRSCM(COL_COOKED, "items.anchovies") + columnRSCM(COL_BURNT, "items.burntfish1") + column(COL_LEVEL, 1) + column(COL_XP, 30) + column(COL_STOP_BURN_FIRE, 34) + column(COL_STOP_BURN_RANGE, 33) + } + + row("dbrows.cooking_sardine") { + columnRSCM(COL_RAW, "items.raw_sardine") + columnRSCM(COL_COOKED, "items.sardine") + columnRSCM(COL_BURNT, "items.burntfish5") + column(COL_LEVEL, 1) + column(COL_XP, 40) + column(COL_STOP_BURN_FIRE, 38) + column(COL_STOP_BURN_RANGE, 37) + } + + row("dbrows.cooking_herring") { + columnRSCM(COL_RAW, "items.raw_herring") + columnRSCM(COL_COOKED, "items.herring") + columnRSCM(COL_BURNT, "items.burntfish3") + column(COL_LEVEL, 5) + column(COL_XP, 50) + column(COL_STOP_BURN_FIRE, 41) + column(COL_STOP_BURN_RANGE, 40) + } + + row("dbrows.cooking_mackerel") { + columnRSCM(COL_RAW, "items.raw_mackerel") + columnRSCM(COL_COOKED, "items.mackerel") + columnRSCM(COL_BURNT, "items.burntfish3") + column(COL_LEVEL, 10) + column(COL_XP, 60) + column(COL_STOP_BURN_FIRE, 44) + column(COL_STOP_BURN_RANGE, 43) + } + + row("dbrows.cooking_trout") { + columnRSCM(COL_RAW, "items.raw_trout") + columnRSCM(COL_COOKED, "items.trout") + columnRSCM(COL_BURNT, "items.burntfish2") + column(COL_LEVEL, 15) + column(COL_XP, 70) + column(COL_STOP_BURN_FIRE, 50) + column(COL_STOP_BURN_RANGE, 49) + } + + row("dbrows.cooking_salmon") { + columnRSCM(COL_RAW, "items.raw_salmon") + columnRSCM(COL_COOKED, "items.salmon") + columnRSCM(COL_BURNT, "items.burntfish2") + column(COL_LEVEL, 25) + column(COL_XP, 90) + column(COL_STOP_BURN_FIRE, 58) + column(COL_STOP_BURN_RANGE, 57) + } + + row("dbrows.cooking_lobster") { + columnRSCM(COL_RAW, "items.raw_lobster") + columnRSCM(COL_COOKED, "items.lobster") + columnRSCM(COL_BURNT, "items.burnt_lobster") + column(COL_LEVEL, 40) + column(COL_XP, 120) + column(COL_STOP_BURN_FIRE, 74) + column(COL_STOP_BURN_RANGE, 64) + } + + row("dbrows.cooking_swordfish") { + columnRSCM(COL_RAW, "items.raw_swordfish") + columnRSCM(COL_COOKED, "items.swordfish") + columnRSCM(COL_BURNT, "items.burnt_swordfish") + column(COL_LEVEL, 45) + column(COL_XP, 140) + column(COL_STOP_BURN_FIRE, 86) + column(COL_STOP_BURN_RANGE, 80) + } + + row("dbrows.cooking_shark") { + columnRSCM(COL_RAW, "items.raw_shark") + columnRSCM(COL_COOKED, "items.shark") + columnRSCM(COL_BURNT, "items.burnt_shark") + column(COL_LEVEL, 80) + column(COL_XP, 210) + column(COL_STOP_BURN_FIRE, 99) + column(COL_STOP_BURN_RANGE, 94) + } + + row("dbrows.cooking_beef") { + columnRSCM(COL_RAW, "items.raw_beef") + columnRSCM(COL_COOKED, "items.cooked_meat") + columnRSCM(COL_BURNT, "items.burnt_meat") + column(COL_LEVEL, 1) + column(COL_XP, 30) + column(COL_STOP_BURN_FIRE, 33) + column(COL_STOP_BURN_RANGE, 32) + } + + row("dbrows.cooking_chicken") { + columnRSCM(COL_RAW, "items.raw_chicken") + columnRSCM(COL_COOKED, "items.cooked_chicken") + columnRSCM(COL_BURNT, "items.burnt_chicken") + column(COL_LEVEL, 1) + column(COL_XP, 30) + column(COL_STOP_BURN_FIRE, 33) + column(COL_STOP_BURN_RANGE, 32) + } + } +} diff --git a/content/src/main/kotlin/org/alter/commands/developer/CookingTestCommandsPlugin.kt b/content/src/main/kotlin/org/alter/commands/developer/CookingTestCommandsPlugin.kt new file mode 100644 index 00000000..199b9293 --- /dev/null +++ b/content/src/main/kotlin/org/alter/commands/developer/CookingTestCommandsPlugin.kt @@ -0,0 +1,126 @@ +package org.alter.commands.developer + +import org.alter.api.Skills +import org.alter.api.ext.message +import org.alter.game.model.priv.Privilege +import org.alter.game.model.Tile +import org.alter.game.model.move.moveTo +import org.alter.game.pluginnew.PluginEvent +import org.alter.game.pluginnew.event.impl.CommandEvent +import org.alter.rscm.RSCM.asRSCM + +class CookingTestCommandsPlugin : PluginEvent() { + + private enum class CookTestSet(val key: String) { + LOW("low"), + MID("mid"), + HIGH("high"), + MEAT("meat"), + ALL("all") + } + + private data class CookTestPreset( + val key: String, + val set: CookTestSet, + val level: Int, + val qty: Int, + ) + + private val presets = listOf( + CookTestPreset(key = "low", set = CookTestSet.LOW, level = 1, qty = 5), + CookTestPreset(key = "mid", set = CookTestSet.MID, level = 25, qty = 5), + CookTestPreset(key = "high", set = CookTestSet.HIGH, level = 80, qty = 3), + CookTestPreset(key = "meat", set = CookTestSet.MEAT, level = 1, qty = 10), + CookTestPreset(key = "all", set = CookTestSet.ALL, level = 80, qty = 1), + ) + + override fun init() { + on { + where { + command.equals("cooktest", ignoreCase = true) && + player.world.privileges.isEligible(player.privilege, Privilege.DEV_POWER) + } + then { + val args = args.orEmpty().map { it.trim() }.filter { it.isNotEmpty() } + + val preset = parseCookTestPreset(player, args) + if (preset == null) { + sendCookTestHelp(player) + return@then + } + + player.getSkills().setBaseLevel(Skills.COOKING, preset.level) + + val keys = keysFor(preset.set) + if (keys.isEmpty()) { + player.message("No items configured for preset '${preset.key}'.") + return@then + } + + var addedAny = false + var failed = 0 + for (key in keys) { + val id = runCatching { key.asRSCM() }.getOrNull() ?: continue + val result = player.inventory.add(id, preset.qty) + if (result.hasSucceeded()) { + addedAny = true + } else { + failed++ + } + } + + if (!addedAny) { + player.message("Couldn't add any items (inventory full?).") + } else if (failed > 0) { + player.message("Added cooking test items (some didn't fit: $failed).") + } else { + player.message("Applied cooktest preset '${preset.key}' (x${preset.qty} each, Cooking=${preset.level}).") + } + } + } + } + + private fun parseCookTestPreset(player: org.alter.game.model.entity.Player, args: List): CookTestPreset? { + if (args.isEmpty() || args.any { it.equals("help", ignoreCase = true) || it == "-h" || it == "--help" }) { + return null + } + + val token = args.first().removePrefix("--").trim().lowercase() + return presets.firstOrNull { it.key == token } + } + + private fun keysFor(set: CookTestSet): List = + when (set) { + CookTestSet.LOW -> listOf( + "items.raw_shrimp", + "items.raw_anchovies", + "items.raw_sardine", + "items.raw_herring" + ) + + CookTestSet.MID -> listOf( + "items.raw_mackerel", + "items.raw_trout", + "items.raw_salmon" + ) + + CookTestSet.HIGH -> listOf( + "items.raw_lobster", + "items.raw_swordfish", + "items.raw_shark" + ) + + CookTestSet.MEAT -> listOf( + "items.raw_beef", + "items.raw_chicken" + ) + + CookTestSet.ALL -> keysFor(CookTestSet.LOW) + keysFor(CookTestSet.MID) + keysFor(CookTestSet.HIGH) + keysFor(CookTestSet.MEAT) + } + + private fun sendCookTestHelp(player: org.alter.game.model.entity.Player) { + player.message("Usage: ::cooktest ") + player.message("Presets: ${presets.joinToString(", ") { it.key }}") + player.message("Examples: ::cooktest low | ::cooktest mid | ::cooktest high | ::cooktest meat | ::cooktest all") + } +} diff --git a/content/src/main/kotlin/org/alter/skills/cooking/CookingEvents.kt b/content/src/main/kotlin/org/alter/skills/cooking/CookingEvents.kt new file mode 100644 index 00000000..d946a9be --- /dev/null +++ b/content/src/main/kotlin/org/alter/skills/cooking/CookingEvents.kt @@ -0,0 +1,223 @@ +package org.alter.skills.cooking + +import dev.openrune.ServerCacheManager.getItem +import org.alter.api.Skills +import org.alter.api.computeSkillingSuccess +import org.alter.api.ext.filterableMessage +import org.alter.api.ext.message +import org.alter.api.ext.produceItemBox +import org.alter.game.model.entity.GameObject +import org.alter.game.model.entity.Player +import org.alter.game.pluginnew.MenuOption +import org.alter.game.pluginnew.PluginEvent +import org.alter.game.pluginnew.event.impl.ItemOnObject +import org.alter.game.pluginnew.event.impl.ObjectClickEvent +import org.alter.rscm.RSCM +import org.alter.rscm.RSCM.asRSCM +import org.alter.rscm.RSCMType +import org.alter.skills.firemaking.ColoredLogs +import org.generated.tables.cooking.CookingRecipesRow +import kotlin.random.Random + +class CookingEvents : PluginEvent() { + + private enum class CookStation { + FIRE, + RANGE + } + + override fun init() { + + // Click range/fire -> open cooking menu + on { + where { optionName.equals("cook", ignoreCase = true) } + then { + val station = stationFor(gameObject) + openCookingMenu(player, station, gameObject) + } + } + + // Use raw food on range/fire -> open cooking menu for that item + on { + where { + option.equals("cook", ignoreCase = true) && + CookingRecipes.byRaw.containsKey(item.id) + } + then { + val recipe = CookingRecipes.byRaw[item.id] ?: return@then + val station = stationFor(gameObject) + openCookingMenu(player, station, gameObject, listOf(recipe)) + } + } + } + + private fun stationFor(gameObject: GameObject): CookStation { + val fireIds = buildFireObjectIds() + return if (fireIds.contains(gameObject.internalID)) CookStation.FIRE else CookStation.RANGE + } + + private fun buildFireObjectIds(): Set { + val fireKeys = ColoredLogs.COLOURED_LOGS.values.map { it.second } + + "objects.fire" + + "objects.forestry_fire" + + val fireInts = fireKeys.mapNotNull { key -> + runCatching { key.asRSCM() }.getOrNull() + } + + return fireInts.toSet() + } + + private fun openCookingMenu( + player: Player, + station: CookStation, + gameObject: GameObject, + only: List? = null + ) { + val cookingLevel = player.getSkills().getCurrentLevel(Skills.COOKING) + + val candidates = (only ?: CookingRecipes.all) + .filter { recipe -> + player.inventory.contains(recipe.raw) && cookingLevel >= recipe.level + } + + if (candidates.isEmpty()) { + player.message("You have nothing you can cook.") + return + } + + // The SKILL_MULTI chatbox UI supports up to 18 item options. + val maxOptions = 18 + val menuCandidates = candidates + .sortedWith( + compareBy { it.level } + .thenBy { getItem(it.cooked)?.name ?: "" } + ) + .take(maxOptions) + + val maxProducible = menuCandidates.maxOf { recipe -> player.inventory.getItemCount(recipe.raw) } + + player.queue { + val cookedItems = menuCandidates.map { it.cooked }.toIntArray() + + produceItemBox( + player, + *cookedItems, + title = "What would you like to cook?", + maxProducable = maxProducible + ) { cookedItemId, qty -> + val recipe = menuCandidates.firstOrNull { it.cooked == cookedItemId } ?: return@produceItemBox + + cook(player, station, gameObject, recipe, qty) + } + } + } + + private fun cook( + player: Player, + station: CookStation, + gameObject: GameObject, + recipe: CookingRecipesRow, + quantity: Int + ) { + val cookingLevel = player.getSkills().getCurrentLevel(Skills.COOKING) + if (cookingLevel < recipe.level) { + player.filterableMessage("You need a Cooking level of ${recipe.level} to cook this.") + return + } + + val objectTile = gameObject.tile + val objectId = gameObject.internalID + + player.queue { + var cooked = 0 + + player.filterableMessage("You begin cooking...") + + repeatWhile(delay = 4, immediate = true, canRepeat = { + cooked < quantity && + player.inventory.contains(recipe.raw) && + isStillAtStation(player, objectTile, objectId) + }) { + + // Optional animation (safe fallback if missing) + runCatching { player.animate("sequences.human_cooking", interruptable = true) } + .onFailure { player.animate(RSCM.NONE) } + + val removed = player.inventory.remove(recipe.raw, 1) + if (!removed.hasSucceeded()) { + stop() + return@repeatWhile + } + + val success = rollCookSuccess(player, station, recipe) + val outputItem = if (success) recipe.cooked else recipe.burnt + + val addResult = player.inventory.add(outputItem, 1) + if (!addResult.hasSucceeded()) { + // restore raw + player.inventory.add(recipe.raw, 1) + player.filterableMessage("You don't have enough inventory space.") + stop() + return@repeatWhile + } + + if (success) { + player.addXp(Skills.COOKING, recipe.xp.toDouble()) + val cookedName = getItem(recipe.cooked)?.name?.lowercase() ?: "food" + player.filterableMessage("You cook the $cookedName.") + } else { + val burntName = getItem(recipe.burnt)?.name?.lowercase() ?: "food" + player.filterableMessage("You accidentally burn the $burntName.") + } + + cooked++ + wait(1) + } + + player.animate(RSCM.NONE) + } + } + + private fun rollCookSuccess( + player: Player, + station: CookStation, + recipe: CookingRecipesRow + ): Boolean { + val cookingLevel = player.getSkills().getCurrentLevel(Skills.COOKING) + + val stopBurn = when (station) { + CookStation.FIRE -> recipe.stopBurnFire + CookStation.RANGE -> recipe.stopBurnRange + }.coerceAtLeast(recipe.level) + + if (cookingLevel >= stopBurn) { + return true + } + + val baseSuccessAtReq = when (station) { + CookStation.FIRE -> 0.30 + CookStation.RANGE -> 0.45 + } + + val progress = ((cookingLevel - recipe.level).toDouble() / (stopBurn - recipe.level).toDouble()) + .coerceIn(0.0, 1.0) + + val chance = (baseSuccessAtReq + (1.0 - baseSuccessAtReq) * progress).coerceIn(0.0, 1.0) + + // Blend with the shared OSRS skilling success curve for nicer scaling. + // This keeps early levels from feeling too punishing while still rewarding levels. + val curve = computeSkillingSuccess(low = 64, high = 256, level = (cookingLevel - recipe.level + 1).coerceIn(1, 99)) + val finalChance = (chance * 0.70 + curve * 0.30).coerceIn(0.0, 1.0) + + return Random.nextDouble() < finalChance + } + + private fun isStillAtStation(player: Player, objectTile: org.alter.game.model.Tile, objectId: Int): Boolean { + if (player.tile.getDistance(objectTile) > 1) return false + + val world = player.world + val obj = world.getObject(objectTile, type = 10) ?: world.getObject(objectTile, type = 11) + return obj != null && obj.internalID == objectId + } +} diff --git a/content/src/main/kotlin/org/alter/skills/cooking/CookingRecipes.kt b/content/src/main/kotlin/org/alter/skills/cooking/CookingRecipes.kt new file mode 100644 index 00000000..58d45d22 --- /dev/null +++ b/content/src/main/kotlin/org/alter/skills/cooking/CookingRecipes.kt @@ -0,0 +1,11 @@ +package org.alter.skills.cooking + +import org.generated.tables.cooking.CookingRecipesRow + +object CookingRecipes { + val all: List = CookingRecipesRow.all() + + val byRaw: Map = all.associateBy { it.raw } + + val byCooked: Map = all.associateBy { it.cooked } +} diff --git a/content/src/main/resources/org/alter/skills/cooking/gamevals.toml b/content/src/main/resources/org/alter/skills/cooking/gamevals.toml new file mode 100644 index 00000000..0d6ca130 --- /dev/null +++ b/content/src/main/resources/org/alter/skills/cooking/gamevals.toml @@ -0,0 +1,16 @@ +[gamevals.tables] +cooking_recipes=1236 + +[gamevals.dbrows] +cooking_shrimps=982014 +cooking_anchovies=982015 +cooking_sardine=982016 +cooking_herring=982017 +cooking_mackerel=982018 +cooking_trout=982019 +cooking_salmon=982020 +cooking_lobster=982021 +cooking_swordfish=982022 +cooking_shark=982023 +cooking_beef=982024 +cooking_chicken=982025 From aa7387767f37b424b8a8e62326b10ab0d99532e7 Mon Sep 17 00:00:00 2001 From: voidstarr <3334013+voidstarr@users.noreply.github.com> Date: Sat, 17 Jan 2026 09:58:28 -0800 Subject: [PATCH 05/10] gamevals: fix key qualification in mapping conflict checks GameValProvider stores mapping keys as fully-qualified "." entries (matching the base/binary loader), but putMapping() previously checked conflicts against the unqualified key.\n\nThat mismatch allowed a TOML-provided mapping to slip past conflict detection and effectively override an existing entry while still being stored as a qualified key. In practice this can mask mapping mistakes until runtime, where they surface as confusing DB/table decode errors (e.g., missing columns when opening the cooking UI).\n\nChanges:\n- Compute a single qualifiedKey (".") in putMapping().\n- Use qualifiedKey consistently for both conflict detection and insertion.\n\nResult: mapping conflicts are detected reliably at load time, preventing silent overrides and making bad overrides fail fast with a clear error. --- cache/src/main/kotlin/org/alter/gamevals/GameValProvider.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cache/src/main/kotlin/org/alter/gamevals/GameValProvider.kt b/cache/src/main/kotlin/org/alter/gamevals/GameValProvider.kt index 931e8834..3cd40015 100644 --- a/cache/src/main/kotlin/org/alter/gamevals/GameValProvider.kt +++ b/cache/src/main/kotlin/org/alter/gamevals/GameValProvider.kt @@ -97,13 +97,15 @@ class GameValProvider : MappingProvider { val tableMappings = mappings[table] ?: throw IllegalArgumentException("Table '$table' does not exist in mappings.") + val qualifiedKey = "$table.$key" + val maxID = maxBaseID[table] ?: -1 require(value > maxID) { "Custom value '$value' for key '$key' in table '$table must exceed the current max base ID $maxID. " + "Cannot override existing osrs IDs." } - if (tableMappings.containsKey(key)) { + if (tableMappings.containsKey(qualifiedKey)) { throw IllegalArgumentException( "Mapping conflict in table '$table: key '$key' already exists. Keys must be unique." ) @@ -115,7 +117,7 @@ class GameValProvider : MappingProvider { ) } - tableMappings["$table.$key"] = value + tableMappings[qualifiedKey] = value } private fun parseRSCMV2Line(line: String, lineNumber: Int): Pair = when { From 94d44166170a453292d0dfcee0ff7dcc2bd87ddc Mon Sep 17 00:00:00 2001 From: voidstarr <3334013+voidstarr@users.noreply.github.com> Date: Mon, 9 Feb 2026 12:16:32 -0800 Subject: [PATCH 06/10] feat(cooking): complete cooking skill rewrite with data-driven architecture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Architecture: - 3-layer design: Cache (recipe defs) → Runtime (DB row registry) → Content (event handlers) - Recipe data defined in cache module, packed into DB tables at build time - Runtime loads from generated Row classes into CookingActionRegistry - GameVal auto-assignment for all new DB row IDs Cache layer (new): - CookingConstants: trigger types, outcome kinds, station masks - CookingModels: ActionDef, InputDef, OutcomeDef, PrepStepDef, HeatStepDef - CookingHelpers: heatCook(), spitRoast(), multiStepCook() builder functions - CookingTables: DB table builders for actions, inputs, outcomes - CookingRecipeRegistry: central aggregator of all recipe definitions Recipe files (new): - FishRecipes: 23 fish (shrimp→manta ray, karambwan, rainbow fish, cave eel, snails) - MeatRecipes: 7 basic meats, 2 spit roasts (bird/beast), 6 hunter meats - BakedGoodsRecipes: garden pie (3-step prep + bake), cake (mixing + bake) - BreadRecipes, PizzaRecipes, PieRecipes, StewRecipes, PotatoRecipes - MiscFoodRecipes, WineRecipes Content layer (new): - CookingEvents: main event wiring (heat-source, item-on-item, Camdozaal) - CookingUtils: station detection, burn rate calculation, equipment checks - CookingOutcomes: weighted outcome selection, count rolling - CamdozaalPrepTable: knife-based fish preparation (guppy→catfish) - CookingActionRegistry: runtime data loading from DB tables - CookingConstants (runtime): Trigger and OutcomeKind constants Burn rate system: - Uses computeSkillingSuccess() with linear interpolation - Separate stopBurn levels for fire vs range - Station-specific base success rates (fire: 30%, range: 45%) Deleted old files: - cache/.../Cooking.kt (monolithic recipe definitions) - content/.../CookingEvents.kt (old event handler) - content/.../CookingRecipes.kt (old recipe lookup) Other: - CookingTestCommandsPlugin: expanded with all recipe presets - gamevals.toml: ~250 new DB row ID mappings --- cache/src/main/kotlin/org/alter/CacheTools.kt | 6 +- .../kotlin/org/alter/impl/skills/Cooking.kt | 147 ----- .../impl/skills/cooking/CookingConstants.kt | 41 ++ .../impl/skills/cooking/CookingHelpers.kt | 216 +++++++ .../impl/skills/cooking/CookingModels.kt | 106 ++++ .../skills/cooking/CookingRecipeRegistry.kt | 36 ++ .../impl/skills/cooking/CookingTables.kt | 110 ++++ .../cooking/recipes/BakedGoodsRecipes.kt | 93 +++ .../skills/cooking/recipes/BreadRecipes.kt | 36 ++ .../skills/cooking/recipes/FishRecipes.kt | 278 +++++++++ .../skills/cooking/recipes/MeatRecipes.kt | 200 +++++++ .../skills/cooking/recipes/MiscFoodRecipes.kt | 141 +++++ .../impl/skills/cooking/recipes/PieRecipes.kt | 398 +++++++++++++ .../skills/cooking/recipes/PizzaRecipes.kt | 107 ++++ .../skills/cooking/recipes/PotatoRecipes.kt | 121 ++++ .../skills/cooking/recipes/StewRecipes.kt | 89 +++ .../skills/cooking/recipes/WineRecipes.kt | 55 ++ .../developer/CookingTestCommandsPlugin.kt | 230 +++++++- .../org/alter/skills/cooking/CookingEvents.kt | 223 ------- .../alter/skills/cooking/CookingRecipes.kt | 11 - .../cooking/events/CamdozaalPrepTable.kt | 148 +++++ .../skills/cooking/events/CookingEvents.kt | 503 ++++++++++++++++ .../skills/cooking/events/CookingOutcomes.kt | 68 +++ .../skills/cooking/events/CookingUtils.kt | 286 +++++++++ .../cooking/runtime/CookingActionRegistry.kt | 119 ++++ .../cooking/runtime/CookingConstants.kt | 23 + .../org/alter/skills/cooking/gamevals.toml | 553 ++++++++++++++++++ 27 files changed, 3929 insertions(+), 415 deletions(-) delete mode 100644 cache/src/main/kotlin/org/alter/impl/skills/Cooking.kt create mode 100644 cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingConstants.kt create mode 100644 cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingHelpers.kt create mode 100644 cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingModels.kt create mode 100644 cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingRecipeRegistry.kt create mode 100644 cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingTables.kt create mode 100644 cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/BakedGoodsRecipes.kt create mode 100644 cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/BreadRecipes.kt create mode 100644 cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/FishRecipes.kt create mode 100644 cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/MeatRecipes.kt create mode 100644 cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/MiscFoodRecipes.kt create mode 100644 cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PieRecipes.kt create mode 100644 cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PizzaRecipes.kt create mode 100644 cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PotatoRecipes.kt create mode 100644 cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/StewRecipes.kt create mode 100644 cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/WineRecipes.kt delete mode 100644 content/src/main/kotlin/org/alter/skills/cooking/CookingEvents.kt delete mode 100644 content/src/main/kotlin/org/alter/skills/cooking/CookingRecipes.kt create mode 100644 content/src/main/kotlin/org/alter/skills/cooking/events/CamdozaalPrepTable.kt create mode 100644 content/src/main/kotlin/org/alter/skills/cooking/events/CookingEvents.kt create mode 100644 content/src/main/kotlin/org/alter/skills/cooking/events/CookingOutcomes.kt create mode 100644 content/src/main/kotlin/org/alter/skills/cooking/events/CookingUtils.kt create mode 100644 content/src/main/kotlin/org/alter/skills/cooking/runtime/CookingActionRegistry.kt create mode 100644 content/src/main/kotlin/org/alter/skills/cooking/runtime/CookingConstants.kt diff --git a/cache/src/main/kotlin/org/alter/CacheTools.kt b/cache/src/main/kotlin/org/alter/CacheTools.kt index 6c5745c2..3e681250 100644 --- a/cache/src/main/kotlin/org/alter/CacheTools.kt +++ b/cache/src/main/kotlin/org/alter/CacheTools.kt @@ -20,7 +20,7 @@ import org.alter.codegen.startGeneration import org.alter.gamevals.GameValProvider import org.alter.gamevals.GamevalDumper import org.alter.impl.GameframeTable -import org.alter.impl.skills.Cooking +import org.alter.impl.skills.cooking.CookingTables import org.alter.impl.skills.Firemaking import org.alter.impl.misc.FoodTable import org.alter.impl.skills.PrayerTable @@ -48,7 +48,9 @@ fun tablesToPack() = listOf( TeleTabs.teleTabs(), StatComponents.statsComponents(), FoodTable.consumableFood(), - Cooking.recipes(), + CookingTables.actionOutcomes(), + CookingTables.actionInputs(), + CookingTables.actions(), Firemaking.logs(), Woodcutting.trees(), Woodcutting.axes(), diff --git a/cache/src/main/kotlin/org/alter/impl/skills/Cooking.kt b/cache/src/main/kotlin/org/alter/impl/skills/Cooking.kt deleted file mode 100644 index a1feab7c..00000000 --- a/cache/src/main/kotlin/org/alter/impl/skills/Cooking.kt +++ /dev/null @@ -1,147 +0,0 @@ -package org.alter.impl.skills - -import dev.openrune.definition.dbtables.dbTable -import dev.openrune.definition.util.VarType - -object Cooking { - - const val COL_RAW = 0 - const val COL_COOKED = 1 - const val COL_BURNT = 2 - const val COL_LEVEL = 3 - const val COL_XP = 4 - const val COL_STOP_BURN_FIRE = 5 - const val COL_STOP_BURN_RANGE = 6 - - fun recipes() = dbTable("tables.cooking_recipes") { - - column("raw", COL_RAW, VarType.OBJ) - column("cooked", COL_COOKED, VarType.OBJ) - column("burnt", COL_BURNT, VarType.OBJ) - column("level", COL_LEVEL, VarType.INT) - column("xp", COL_XP, VarType.INT) - column("stop_burn_fire", COL_STOP_BURN_FIRE, VarType.INT) - column("stop_burn_range", COL_STOP_BURN_RANGE, VarType.INT) - - // Basic fish & meat (initial skill implementation) - row("dbrows.cooking_shrimps") { - columnRSCM(COL_RAW, "items.raw_shrimp") - columnRSCM(COL_COOKED, "items.shrimp") - columnRSCM(COL_BURNT, "items.burnt_shrimp") - column(COL_LEVEL, 1) - column(COL_XP, 30) - column(COL_STOP_BURN_FIRE, 34) - column(COL_STOP_BURN_RANGE, 33) - } - - row("dbrows.cooking_anchovies") { - columnRSCM(COL_RAW, "items.raw_anchovies") - columnRSCM(COL_COOKED, "items.anchovies") - columnRSCM(COL_BURNT, "items.burntfish1") - column(COL_LEVEL, 1) - column(COL_XP, 30) - column(COL_STOP_BURN_FIRE, 34) - column(COL_STOP_BURN_RANGE, 33) - } - - row("dbrows.cooking_sardine") { - columnRSCM(COL_RAW, "items.raw_sardine") - columnRSCM(COL_COOKED, "items.sardine") - columnRSCM(COL_BURNT, "items.burntfish5") - column(COL_LEVEL, 1) - column(COL_XP, 40) - column(COL_STOP_BURN_FIRE, 38) - column(COL_STOP_BURN_RANGE, 37) - } - - row("dbrows.cooking_herring") { - columnRSCM(COL_RAW, "items.raw_herring") - columnRSCM(COL_COOKED, "items.herring") - columnRSCM(COL_BURNT, "items.burntfish3") - column(COL_LEVEL, 5) - column(COL_XP, 50) - column(COL_STOP_BURN_FIRE, 41) - column(COL_STOP_BURN_RANGE, 40) - } - - row("dbrows.cooking_mackerel") { - columnRSCM(COL_RAW, "items.raw_mackerel") - columnRSCM(COL_COOKED, "items.mackerel") - columnRSCM(COL_BURNT, "items.burntfish3") - column(COL_LEVEL, 10) - column(COL_XP, 60) - column(COL_STOP_BURN_FIRE, 44) - column(COL_STOP_BURN_RANGE, 43) - } - - row("dbrows.cooking_trout") { - columnRSCM(COL_RAW, "items.raw_trout") - columnRSCM(COL_COOKED, "items.trout") - columnRSCM(COL_BURNT, "items.burntfish2") - column(COL_LEVEL, 15) - column(COL_XP, 70) - column(COL_STOP_BURN_FIRE, 50) - column(COL_STOP_BURN_RANGE, 49) - } - - row("dbrows.cooking_salmon") { - columnRSCM(COL_RAW, "items.raw_salmon") - columnRSCM(COL_COOKED, "items.salmon") - columnRSCM(COL_BURNT, "items.burntfish2") - column(COL_LEVEL, 25) - column(COL_XP, 90) - column(COL_STOP_BURN_FIRE, 58) - column(COL_STOP_BURN_RANGE, 57) - } - - row("dbrows.cooking_lobster") { - columnRSCM(COL_RAW, "items.raw_lobster") - columnRSCM(COL_COOKED, "items.lobster") - columnRSCM(COL_BURNT, "items.burnt_lobster") - column(COL_LEVEL, 40) - column(COL_XP, 120) - column(COL_STOP_BURN_FIRE, 74) - column(COL_STOP_BURN_RANGE, 64) - } - - row("dbrows.cooking_swordfish") { - columnRSCM(COL_RAW, "items.raw_swordfish") - columnRSCM(COL_COOKED, "items.swordfish") - columnRSCM(COL_BURNT, "items.burnt_swordfish") - column(COL_LEVEL, 45) - column(COL_XP, 140) - column(COL_STOP_BURN_FIRE, 86) - column(COL_STOP_BURN_RANGE, 80) - } - - row("dbrows.cooking_shark") { - columnRSCM(COL_RAW, "items.raw_shark") - columnRSCM(COL_COOKED, "items.shark") - columnRSCM(COL_BURNT, "items.burnt_shark") - column(COL_LEVEL, 80) - column(COL_XP, 210) - column(COL_STOP_BURN_FIRE, 99) - column(COL_STOP_BURN_RANGE, 94) - } - - row("dbrows.cooking_beef") { - columnRSCM(COL_RAW, "items.raw_beef") - columnRSCM(COL_COOKED, "items.cooked_meat") - columnRSCM(COL_BURNT, "items.burnt_meat") - column(COL_LEVEL, 1) - column(COL_XP, 30) - column(COL_STOP_BURN_FIRE, 33) - column(COL_STOP_BURN_RANGE, 32) - } - - row("dbrows.cooking_chicken") { - columnRSCM(COL_RAW, "items.raw_chicken") - columnRSCM(COL_COOKED, "items.cooked_chicken") - columnRSCM(COL_BURNT, "items.burnt_chicken") - column(COL_LEVEL, 1) - column(COL_XP, 30) - column(COL_STOP_BURN_FIRE, 33) - column(COL_STOP_BURN_RANGE, 32) - } - } -} diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingConstants.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingConstants.kt new file mode 100644 index 00000000..ce34972d --- /dev/null +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingConstants.kt @@ -0,0 +1,41 @@ +package org.alter.impl.skills.cooking + +/** + * Cooking skill constants used across recipe definitions and table builders. + */ +object CookingConstants { + + /** + * Trigger types determine how a cooking action is initiated. + */ + object Trigger { + /** Action triggered by using item on a heat source (fire/range). */ + const val HEAT_SOURCE = 0 + /** Action triggered by using one item on another in inventory. */ + const val ITEM_ON_ITEM = 1 + } + + /** + * Outcome kinds determine what type of result a cooking action produces. + */ + object OutcomeKind { + /** Successful cooking result. */ + const val SUCCESS = 0 + /** Failed cooking result (burnt). */ + const val FAIL = 1 + /** Always produced regardless of success/failure (e.g., return containers). */ + const val ALWAYS = 2 + } + + /** Default variant for single-step actions. */ + const val DEFAULT_VARIANT = 0 + + /** Station mask for fire-only cooking. */ + const val STATION_FIRE = 1 + + /** Station mask for range-only cooking. */ + const val STATION_RANGE = 2 + + /** Station mask for cooking on both fire and range. */ + const val STATION_ANY = STATION_FIRE or STATION_RANGE +} diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingHelpers.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingHelpers.kt new file mode 100644 index 00000000..309c37f7 --- /dev/null +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingHelpers.kt @@ -0,0 +1,216 @@ +package org.alter.impl.skills.cooking + +import org.alter.impl.skills.cooking.CookingConstants.DEFAULT_VARIANT +import org.alter.impl.skills.cooking.CookingConstants.OutcomeKind +import org.alter.impl.skills.cooking.CookingConstants.STATION_ANY +import org.alter.impl.skills.cooking.CookingConstants.STATION_FIRE +import org.alter.impl.skills.cooking.CookingConstants.Trigger + +/** + * Helper functions for building cooking recipe definitions. + */ +object CookingHelpers { + + /** + * Creates a simple heat-cooking action (raw -> cooked/burnt). + * + * @param rowKey DB row key suffix (e.g., "cooking_shrimps"). + * @param raw RSCM key for the raw item. + * @param cooked RSCM key for the cooked item. + * @param burnt RSCM key for the burnt item. + * @param level Required Cooking level. + * @param xp Experience awarded on success. + * @param stopBurnFire Level at which burning stops on fires. + * @param stopBurnRange Level at which burning stops on ranges. + * @param stationMask Bitmask for allowed cooking stations. + */ + fun heatCook( + rowKey: String, + raw: String, + cooked: String, + burnt: String, + level: Int, + xp: Int, + stopBurnFire: Int, + stopBurnRange: Int, + stationMask: Int = STATION_ANY + ): ActionDef = ActionDef( + rowId = "dbrows.$rowKey", + key = raw, + level = level, + stopBurnFire = stopBurnFire, + stopBurnRange = stopBurnRange, + stationMask = stationMask, + trigger = Trigger.HEAT_SOURCE, + inputs = listOf(InputDef(raw, 1)), + outcomes = listOf( + OutcomeDef(rowSuffix = "success", kind = OutcomeKind.SUCCESS, item = cooked, xp = xp, weight = 1), + OutcomeDef(rowSuffix = "fail", kind = OutcomeKind.FAIL, item = burnt, xp = 0, weight = 1) + ) + ) + + /** + * Creates a spit-roasting recipe (2 actions: skewer + roast). + * + * @param skewerRowKey DB row key for the skewering step. + * @param roastRowKey DB row key for the roasting step. + * @param rawMeat RSCM key for the raw meat. + * @param skewered RSCM key for the skewered meat. + * @param cooked RSCM key for the roasted meat. + * @param burnt RSCM key for the burnt meat. + * @param cookingLevel Required Cooking level for roasting. + * @param xp Experience awarded on successful roast. + * @param stopBurnFire Level at which burning stops on fires. + * @param stopBurnRange Level at which burning stops on ranges. + * @param spitItem RSCM key for the spit item (default: iron spit). + */ + fun spitRoast( + skewerRowKey: String, + roastRowKey: String, + rawMeat: String, + skewered: String, + cooked: String, + burnt: String, + cookingLevel: Int, + xp: Int, + stopBurnFire: Int, + stopBurnRange: Int, + spitItem: String = "items.spit_iron" + ): List = listOf( + // Raw meat + iron spit -> skewered meat (inventory prep step) + ActionDef( + rowId = "dbrows.$skewerRowKey", + key = skewered, + variant = 1, + level = 1, + stopBurnFire = 1, + stopBurnRange = 1, + stationMask = STATION_ANY, + trigger = Trigger.ITEM_ON_ITEM, + inputs = listOf( + InputDef(rawMeat, 1), + InputDef(spitItem, 1) + ), + outcomes = listOf( + OutcomeDef(rowSuffix = "success", kind = OutcomeKind.SUCCESS, item = skewered, xp = 0, weight = 1) + ) + ), + + // Skewered meat -> roasted/burnt (fire only) + ActionDef( + rowId = "dbrows.$roastRowKey", + key = skewered, + variant = DEFAULT_VARIANT, + level = cookingLevel, + stopBurnFire = stopBurnFire, + stopBurnRange = stopBurnRange, + stationMask = STATION_FIRE, + trigger = Trigger.HEAT_SOURCE, + inputs = listOf(InputDef(skewered, 1)), + outcomes = listOf( + OutcomeDef(rowSuffix = "success", kind = OutcomeKind.SUCCESS, item = cooked, xp = xp, weight = 1), + OutcomeDef(rowSuffix = "fail", kind = OutcomeKind.FAIL, item = burnt, xp = 0, weight = 1) + ) + ) + ) + + /** + * Creates a multi-step cooking recipe with preparation and optional baking. + * + * @param key RSCM key identifying this recipe group. + * @param level Required Cooking level. + * @param prepSteps List of inventory preparation steps. + * @param heatStep Optional final heat-source cooking step. + * @param prepVariantStart Starting variant number for prep steps. + * @param heatVariant Variant number for the heat step. + */ + fun multiStepCook( + key: String, + level: Int, + prepSteps: List, + heatStep: HeatStepDef? = null, + prepVariantStart: Int = 1, + heatVariant: Int = DEFAULT_VARIANT + ): List = buildList { + prepSteps.forEachIndexed { index, step -> + val alwaysOutcomes = step.always.mapIndexed { alwaysIndex, (item, count) -> + OutcomeDef( + rowSuffix = "always_$alwaysIndex", + kind = OutcomeKind.ALWAYS, + item = item, + countMin = count, + countMax = count, + xp = 0, + weight = 1 + ) + } + + add( + ActionDef( + rowId = "dbrows.${step.rowKey}", + key = key, + variant = prepVariantStart + index, + level = level, + stopBurnFire = level, + stopBurnRange = level, + stationMask = STATION_ANY, + trigger = Trigger.ITEM_ON_ITEM, + inputs = step.inputs.map { (item, count) -> InputDef(item, count) }, + outcomes = listOf( + OutcomeDef( + rowSuffix = "success", + kind = OutcomeKind.SUCCESS, + item = step.output, + xp = step.xp, + weight = 1 + ) + ) + alwaysOutcomes + ) + ) + } + + heatStep?.let { step -> + val alwaysOutcomes = step.always.mapIndexed { alwaysIndex, (item, count) -> + OutcomeDef( + rowSuffix = "always_$alwaysIndex", + kind = OutcomeKind.ALWAYS, + item = item, + countMin = count, + countMax = count, + xp = 0, + weight = 1 + ) + } + + add( + ActionDef( + rowId = "dbrows.${step.rowKey}", + key = key, + variant = heatVariant, + level = level, + stopBurnFire = step.stopBurnFire, + stopBurnRange = step.stopBurnRange, + stationMask = step.stationMask, + trigger = Trigger.HEAT_SOURCE, + inputs = listOf(InputDef(step.raw, 1)), + outcomes = listOf( + OutcomeDef( + rowSuffix = "success", + kind = OutcomeKind.SUCCESS, + item = step.cooked, + xp = step.xp, + weight = 1 + ), + OutcomeDef( + rowSuffix = "fail", + kind = OutcomeKind.FAIL, + item = step.burnt, + xp = 0, + weight = 1 + ) + ) + alwaysOutcomes + ) + ) + } + } +} diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingModels.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingModels.kt new file mode 100644 index 00000000..19d8e7c4 --- /dev/null +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingModels.kt @@ -0,0 +1,106 @@ +package org.alter.impl.skills.cooking + +/** + * Data models for cooking recipe definitions. + */ + +/** + * Defines an input ingredient for a cooking action. + * + * @property item RSCM key for the item (e.g., "items.raw_shrimp"). + * @property count Number of this item consumed per action. + */ +data class InputDef( + val item: String, + val count: Int = 1 +) + +/** + * Defines a possible outcome of a cooking action. + * + * @property rowSuffix Unique suffix for the DB row (e.g., "success", "fail"). + * @property kind The outcome type (SUCCESS, FAIL, or ALWAYS). + * @property item RSCM key for the produced item. + * @property countMin Minimum quantity produced. + * @property countMax Maximum quantity produced. + * @property xp Experience awarded for this outcome. + * @property weight Weighted chance for this outcome when multiple exist. + */ +data class OutcomeDef( + val rowSuffix: String, + val kind: Int, + val item: String, + val countMin: Int = 1, + val countMax: Int = 1, + val xp: Int = 0, + val weight: Int = 1 +) + +/** + * Defines a complete cooking action with inputs, outcomes, and requirements. + * + * @property rowId DB row identifier (e.g., "dbrows.cooking_shrimps"). + * @property key RSCM key used to identify this action group. + * @property variant Variant number for multi-step recipes. + * @property level Required Cooking level. + * @property stopBurnFire Level at which burning stops on fires. + * @property stopBurnRange Level at which burning stops on ranges. + * @property stationMask Bitmask for allowed cooking stations. + * @property trigger How the action is initiated (HEAT_SOURCE or ITEM_ON_ITEM). + * @property inputs List of required input items. + * @property outcomes List of possible outcomes. + */ +data class ActionDef( + val rowId: String, + val key: String, + val variant: Int = CookingConstants.DEFAULT_VARIANT, + val level: Int, + val stopBurnFire: Int, + val stopBurnRange: Int, + val stationMask: Int = CookingConstants.STATION_ANY, + val trigger: Int = CookingConstants.Trigger.HEAT_SOURCE, + val inputs: List, + val outcomes: List +) + +/** + * Defines a preparation step for multi-step cooking (inventory item-on-item). + * + * @property rowKey DB row key suffix. + * @property inputs List of (item RSCM key, count) pairs consumed. + * @property output RSCM key for the produced item. + * @property xp Experience awarded. + * @property always Items always returned (e.g., empty containers). + */ +data class PrepStepDef( + val rowKey: String, + val inputs: List>, + val output: String, + val xp: Int = 0, + val always: List> = emptyList() +) + +/** + * Defines the final heat-source step for multi-step cooking. + * + * @property rowKey DB row key suffix. + * @property raw RSCM key for the uncooked item. + * @property cooked RSCM key for the successfully cooked item. + * @property burnt RSCM key for the burnt item. + * @property xp Experience awarded on success. + * @property stopBurnFire Level at which burning stops on fires. + * @property stopBurnRange Level at which burning stops on ranges. + * @property stationMask Bitmask for allowed cooking stations. + * @property always Items always returned (e.g., cake tin). + */ +data class HeatStepDef( + val rowKey: String, + val raw: String, + val cooked: String, + val burnt: String, + val xp: Int, + val stopBurnFire: Int, + val stopBurnRange: Int, + val stationMask: Int = CookingConstants.STATION_ANY, + val always: List> = emptyList() +) diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingRecipeRegistry.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingRecipeRegistry.kt new file mode 100644 index 00000000..646630e6 --- /dev/null +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingRecipeRegistry.kt @@ -0,0 +1,36 @@ +package org.alter.impl.skills.cooking + +import org.alter.impl.skills.cooking.recipes.BakedGoodsRecipes +import org.alter.impl.skills.cooking.recipes.BreadRecipes +import org.alter.impl.skills.cooking.recipes.FishRecipes +import org.alter.impl.skills.cooking.recipes.MeatRecipes +import org.alter.impl.skills.cooking.recipes.MiscFoodRecipes +import org.alter.impl.skills.cooking.recipes.PieRecipes +import org.alter.impl.skills.cooking.recipes.PizzaRecipes +import org.alter.impl.skills.cooking.recipes.PotatoRecipes +import org.alter.impl.skills.cooking.recipes.StewRecipes +import org.alter.impl.skills.cooking.recipes.WineRecipes + +/** + * Central registry of all cooking recipes. + * + * Add new recipe categories here as they are implemented. + */ +object CookingRecipeRegistry { + + /** + * All cooking action definitions from all recipe categories. + */ + val allRecipes: List by lazy { + FishRecipes.recipes + + MeatRecipes.recipes + + BakedGoodsRecipes.recipes + + BreadRecipes.recipes + + PieRecipes.recipes + + PizzaRecipes.recipes + + StewRecipes.recipes + + PotatoRecipes.recipes + + MiscFoodRecipes.recipes + + WineRecipes.recipes + } +} diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingTables.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingTables.kt new file mode 100644 index 00000000..71a3caaa --- /dev/null +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingTables.kt @@ -0,0 +1,110 @@ +package org.alter.impl.skills.cooking + +import dev.openrune.definition.dbtables.dbTable +import dev.openrune.definition.util.VarType + +/** + * DB table builders for cooking skill data. + * + * These functions generate the cache tables used by the game client and server + * to look up cooking recipes, inputs, and outcomes. + */ +object CookingTables { + + private const val ACTION_KEY = 0 + private const val ACTION_VARIANT = 1 + private const val ACTION_LEVEL = 2 + private const val ACTION_STOP_BURN_FIRE = 3 + private const val ACTION_STOP_BURN_RANGE = 4 + private const val ACTION_STATION_MASK = 5 + private const val ACTION_TRIGGER = 6 + + /** + * Builds the cooking_actions DB table containing action metadata. + */ + fun actions() = dbTable("tables.cooking_actions") { + column("key", ACTION_KEY, VarType.OBJ) + column("variant", ACTION_VARIANT, VarType.INT) + column("level", ACTION_LEVEL, VarType.INT) + column("stop_burn_fire", ACTION_STOP_BURN_FIRE, VarType.INT) + column("stop_burn_range", ACTION_STOP_BURN_RANGE, VarType.INT) + column("station_mask", ACTION_STATION_MASK, VarType.INT) + column("trigger", ACTION_TRIGGER, VarType.INT) + + CookingRecipeRegistry.allRecipes.forEach { action -> + row(action.rowId) { + columnRSCM(ACTION_KEY, action.key) + column(ACTION_VARIANT, action.variant) + column(ACTION_LEVEL, action.level) + column(ACTION_STOP_BURN_FIRE, action.stopBurnFire) + column(ACTION_STOP_BURN_RANGE, action.stopBurnRange) + column(ACTION_STATION_MASK, action.stationMask) + column(ACTION_TRIGGER, action.trigger) + } + } + } + + private const val INPUT_KEY = 0 + private const val INPUT_VARIANT = 1 + private const val INPUT_ITEM = 2 + private const val INPUT_COUNT = 3 + + /** + * Builds the cooking_action_inputs DB table containing input requirements. + */ + fun actionInputs() = dbTable("tables.cooking_action_inputs") { + column("key", INPUT_KEY, VarType.OBJ) + column("variant", INPUT_VARIANT, VarType.INT) + column("item", INPUT_ITEM, VarType.OBJ) + column("count", INPUT_COUNT, VarType.INT) + + CookingRecipeRegistry.allRecipes.forEach { action -> + action.inputs.forEachIndexed { index, input -> + row("${action.rowId}_input_$index") { + columnRSCM(INPUT_KEY, action.key) + column(INPUT_VARIANT, action.variant) + columnRSCM(INPUT_ITEM, input.item) + column(INPUT_COUNT, input.count) + } + } + } + } + + private const val OUTCOME_KEY = 0 + private const val OUTCOME_VARIANT = 1 + private const val OUTCOME_KIND = 2 + private const val OUTCOME_ITEM = 3 + private const val OUTCOME_COUNT_MIN = 4 + private const val OUTCOME_COUNT_MAX = 5 + private const val OUTCOME_XP = 6 + private const val OUTCOME_WEIGHT = 7 + + /** + * Builds the cooking_action_outcomes DB table containing possible results. + */ + fun actionOutcomes() = dbTable("tables.cooking_action_outcomes") { + column("key", OUTCOME_KEY, VarType.OBJ) + column("variant", OUTCOME_VARIANT, VarType.INT) + column("kind", OUTCOME_KIND, VarType.INT) + column("item", OUTCOME_ITEM, VarType.OBJ) + column("count_min", OUTCOME_COUNT_MIN, VarType.INT) + column("count_max", OUTCOME_COUNT_MAX, VarType.INT) + column("xp", OUTCOME_XP, VarType.INT) + column("weight", OUTCOME_WEIGHT, VarType.INT) + + CookingRecipeRegistry.allRecipes.forEach { action -> + action.outcomes.forEach { outcome -> + row("${action.rowId}_outcome_${outcome.rowSuffix}") { + columnRSCM(OUTCOME_KEY, action.key) + column(OUTCOME_VARIANT, action.variant) + column(OUTCOME_KIND, outcome.kind) + columnRSCM(OUTCOME_ITEM, outcome.item) + column(OUTCOME_COUNT_MIN, outcome.countMin) + column(OUTCOME_COUNT_MAX, outcome.countMax) + column(OUTCOME_XP, outcome.xp) + column(OUTCOME_WEIGHT, outcome.weight) + } + } + } + } +} diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/BakedGoodsRecipes.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/BakedGoodsRecipes.kt new file mode 100644 index 00000000..e25ce387 --- /dev/null +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/BakedGoodsRecipes.kt @@ -0,0 +1,93 @@ +package org.alter.impl.skills.cooking.recipes + +import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE +import org.alter.impl.skills.cooking.CookingHelpers.multiStepCook +import org.alter.impl.skills.cooking.HeatStepDef +import org.alter.impl.skills.cooking.PrepStepDef + +/** + * Baked goods recipes - pies, cakes, and other range-baked items. + */ +object BakedGoodsRecipes { + + /** Pie recipes (multi-step prep + range bake). */ + val pieRecipes: List = multiStepCook( + key = "items.uncooked_garden_pie", + level = 34, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_garden_pie_add_tomato", + inputs = listOf( + "items.pie_shell" to 1, + "items.tomato" to 1 + ), + output = "items.unfinished_garden_pie_1" + ), + PrepStepDef( + rowKey = "cooking_garden_pie_add_onion", + inputs = listOf( + "items.unfinished_garden_pie_1" to 1, + "items.onion" to 1 + ), + output = "items.unfinished_garden_pie_2" + ), + PrepStepDef( + rowKey = "cooking_garden_pie_add_cabbage", + inputs = listOf( + "items.unfinished_garden_pie_2" to 1, + "items.cabbage" to 1 + ), + output = "items.uncooked_garden_pie" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_garden_pie_bake", + raw = "items.uncooked_garden_pie", + cooked = "items.garden_pie", + burnt = "items.burnt_pie", + xp = 138, + stopBurnFire = 68, + stopBurnRange = 64, + stationMask = STATION_RANGE + ) + ) + + /** Cake recipes (multi-step prep + range bake). */ + val cakeRecipes: List = multiStepCook( + key = "items.uncooked_cake", + level = 40, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_cake_mix", + inputs = listOf( + "items.cake_tin" to 1, + "items.egg" to 1, + "items.bucket_milk" to 1, + "items.pot_flour" to 1 + ), + output = "items.uncooked_cake", + always = listOf( + "items.bucket_empty" to 1, + "items.pot_empty" to 1 + ) + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_cake_bake", + raw = "items.uncooked_cake", + cooked = "items.cake", + burnt = "items.burnt_cake", + xp = 180, + stopBurnFire = 74, + stopBurnRange = 70, + stationMask = STATION_RANGE, + always = listOf( + "items.cake_tin" to 1 + ) + ) + ) + + /** All baked goods recipes combined. */ + val recipes: List = pieRecipes + cakeRecipes +} diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/BreadRecipes.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/BreadRecipes.kt new file mode 100644 index 00000000..e863ed90 --- /dev/null +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/BreadRecipes.kt @@ -0,0 +1,36 @@ +package org.alter.impl.skills.cooking.recipes + +import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE +import org.alter.impl.skills.cooking.CookingHelpers.heatCook + +/** + * Bread cooking recipes — baked on a range. + */ +object BreadRecipes { + + val recipes: List = listOf( + heatCook( + rowKey = "cooking_bread", + raw = "items.bread_dough", + cooked = "items.bread", + burnt = "items.burnt_bread", + level = 1, + xp = 40, + stopBurnFire = 35, + stopBurnRange = 35, + stationMask = STATION_RANGE + ), + heatCook( + rowKey = "cooking_pitta_bread", + raw = "items.pitta_dough", + cooked = "items.pitta_bread", + burnt = "items.burnt_pitta_bread", + level = 58, + xp = 40, + stopBurnFire = 82, + stopBurnRange = 82, + stationMask = STATION_RANGE + ) + ) +} diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/FishRecipes.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/FishRecipes.kt new file mode 100644 index 00000000..807d4af1 --- /dev/null +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/FishRecipes.kt @@ -0,0 +1,278 @@ +package org.alter.impl.skills.cooking.recipes + +import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.STATION_FIRE +import org.alter.impl.skills.cooking.CookingHelpers.heatCook + +/** + * Fish cooking recipes - standard heat-source cooking. + */ +object FishRecipes { + + val recipes: List = listOf( + heatCook( + rowKey = "cooking_shrimps", + raw = "items.raw_shrimp", + cooked = "items.shrimp", + burnt = "items.burnt_shrimp", + level = 1, + xp = 30, + stopBurnFire = 34, + stopBurnRange = 34 + ), + heatCook( + rowKey = "cooking_anchovies", + raw = "items.raw_anchovies", + cooked = "items.anchovies", + burnt = "items.burntfish1", + level = 1, + xp = 30, + stopBurnFire = 34, + stopBurnRange = 34 + ), + heatCook( + rowKey = "cooking_sardine", + raw = "items.raw_sardine", + cooked = "items.sardine", + burnt = "items.burntfish5", + level = 1, + xp = 40, + stopBurnFire = 38, + stopBurnRange = 38 + ), + heatCook( + rowKey = "cooking_herring", + raw = "items.raw_herring", + cooked = "items.herring", + burnt = "items.burntfish3", + level = 5, + xp = 50, + stopBurnFire = 41, + stopBurnRange = 41 + ), + heatCook( + rowKey = "cooking_mackerel", + raw = "items.raw_mackerel", + cooked = "items.mackerel", + burnt = "items.burntfish3", + level = 10, + xp = 60, + stopBurnFire = 45, + stopBurnRange = 45 + ), + heatCook( + rowKey = "cooking_trout", + raw = "items.raw_trout", + cooked = "items.trout", + burnt = "items.burntfish2", + level = 15, + xp = 70, + stopBurnFire = 49, + stopBurnRange = 49 + ), + heatCook( + rowKey = "cooking_cod", + raw = "items.raw_cod", + cooked = "items.cod", + burnt = "items.burntfish2", + level = 18, + xp = 75, + stopBurnFire = 51, + stopBurnRange = 49 + ), + heatCook( + rowKey = "cooking_pike", + raw = "items.raw_pike", + cooked = "items.pike", + burnt = "items.burntfish5", + level = 20, + xp = 80, + stopBurnFire = 54, + stopBurnRange = 54 + ), + heatCook( + rowKey = "cooking_salmon", + raw = "items.raw_salmon", + cooked = "items.salmon", + burnt = "items.burntfish2", + level = 25, + xp = 90, + stopBurnFire = 58, + stopBurnRange = 58 + ), + heatCook( + rowKey = "cooking_slimy_eel", + raw = "items.mort_slimey_eel", + cooked = "items.mort_slimey_eel_cooked", + burnt = "items.burnt_eel", + level = 28, + xp = 95, + stopBurnFire = 61, + stopBurnRange = 61 + ), + heatCook( + rowKey = "cooking_tuna", + raw = "items.raw_tuna", + cooked = "items.tuna", + burnt = "items.burntfish4", + level = 30, + xp = 100, + stopBurnFire = 63, + stopBurnRange = 63 + ), + heatCook( + rowKey = "cooking_lobster", + raw = "items.raw_lobster", + cooked = "items.lobster", + burnt = "items.burnt_lobster", + level = 40, + xp = 120, + stopBurnFire = 74, + stopBurnRange = 74 + ), + heatCook( + rowKey = "cooking_bass", + raw = "items.raw_bass", + cooked = "items.bass", + burnt = "items.burntfish3", + level = 43, + xp = 130, + stopBurnFire = 79, + stopBurnRange = 79 + ), + heatCook( + rowKey = "cooking_swordfish", + raw = "items.raw_swordfish", + cooked = "items.swordfish", + burnt = "items.burnt_swordfish", + level = 45, + xp = 140, + stopBurnFire = 86, + stopBurnRange = 80 + ), + heatCook( + rowKey = "cooking_monkfish", + raw = "items.raw_monkfish", + cooked = "items.monkfish", + burnt = "items.burnt_monkfish", + level = 62, + xp = 150, + stopBurnFire = 92, + stopBurnRange = 90 + ), + heatCook( + rowKey = "cooking_shark", + raw = "items.raw_shark", + cooked = "items.shark", + burnt = "items.burnt_shark", + level = 80, + xp = 210, + stopBurnFire = 100, + stopBurnRange = 100 + ), + heatCook( + rowKey = "cooking_sea_turtle", + raw = "items.raw_seaturtle", + cooked = "items.seaturtle", + burnt = "items.burnt_seaturtle", + level = 82, + xp = 211, + stopBurnFire = 100, + stopBurnRange = 100 + ), + heatCook( + rowKey = "cooking_anglerfish", + raw = "items.raw_anglerfish", + cooked = "items.anglerfish", + burnt = "items.burnt_anglerfish", + level = 84, + xp = 230, + stopBurnFire = 100, + stopBurnRange = 100 + ), + heatCook( + rowKey = "cooking_dark_crab", + raw = "items.raw_dark_crab", + cooked = "items.dark_crab", + burnt = "items.burnt_dark_crab", + level = 90, + xp = 215, + stopBurnFire = 100, + stopBurnRange = 100 + ), + heatCook( + rowKey = "cooking_manta_ray", + raw = "items.raw_mantaray", + cooked = "items.mantaray", + burnt = "items.burnt_mantaray", + level = 91, + xp = 216, + stopBurnFire = 100, + stopBurnRange = 100 + ), + heatCook( + rowKey = "cooking_karambwan", + raw = "items.tbwt_raw_karambwan", + cooked = "items.tbwt_cooked_karambwan", + burnt = "items.tbwt_burnt_karambwan", + level = 30, + xp = 190, + stopBurnFire = 99, + stopBurnRange = 93 + ), + heatCook( + rowKey = "cooking_rainbow_fish", + raw = "items.hunting_raw_fish_special", + cooked = "items.hunting_fish_special", + burnt = "items.burnt_rainbow_fish", + level = 35, + xp = 110, + stopBurnFire = 64, + stopBurnRange = 60 + ), + heatCook( + rowKey = "cooking_cave_eel", + raw = "items.raw_cave_eel", + cooked = "items.cave_eel", + burnt = "items.burnt_cave_eel", + level = 38, + xp = 115, + stopBurnFire = 74, + stopBurnRange = 70 + ), + + // --- Snails (fire-only, Morytania) --- + heatCook( + rowKey = "cooking_thin_snail", + raw = "items.snail_corpse1", + cooked = "items.snail_corpse_cooked1", + burnt = "items.burnt_snail", + level = 12, + xp = 70, + stopBurnFire = 47, + stopBurnRange = 47, + stationMask = STATION_FIRE + ), + heatCook( + rowKey = "cooking_lean_snail", + raw = "items.snail_corpse2", + cooked = "items.snail_corpse_cooked2", + burnt = "items.burnt_snail", + level = 17, + xp = 80, + stopBurnFire = 47, + stopBurnRange = 50 + ), + heatCook( + rowKey = "cooking_fat_snail", + raw = "items.snail_corpse3", + cooked = "items.snail_corpse_cooked3", + burnt = "items.burnt_snail", + level = 22, + xp = 95, + stopBurnFire = 56, + stopBurnRange = 56, + stationMask = STATION_FIRE + ) + ) +} diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/MeatRecipes.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/MeatRecipes.kt new file mode 100644 index 00000000..f33f9e63 --- /dev/null +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/MeatRecipes.kt @@ -0,0 +1,200 @@ +package org.alter.impl.skills.cooking.recipes + +import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.STATION_FIRE +import org.alter.impl.skills.cooking.CookingHelpers.heatCook +import org.alter.impl.skills.cooking.CookingHelpers.spitRoast + +/** + * Meat cooking recipes - standard cooking and spit roasting. + */ +object MeatRecipes { + + /** Basic meat cooking recipes (fire/range). */ + val basicMeatRecipes: List = listOf( + heatCook( + rowKey = "cooking_chompy", + raw = "items.raw_chompy", + cooked = "items.cooked_chompy", + burnt = "items.ruined_chompy", + level = 30, + xp = 100, + stopBurnFire = 63, + stopBurnRange = 63 + ), + heatCook( + rowKey = "cooking_beef", + raw = "items.raw_beef", + cooked = "items.cooked_meat", + burnt = "items.burnt_meat", + level = 1, + xp = 30, + stopBurnFire = 34, + stopBurnRange = 34 + ), + heatCook( + rowKey = "cooking_chicken", + raw = "items.raw_chicken", + cooked = "items.cooked_chicken", + burnt = "items.burnt_chicken", + level = 1, + xp = 30, + stopBurnFire = 34, + stopBurnRange = 34 + ), + heatCook( + rowKey = "cooking_rat_meat", + raw = "items.raw_rat_meat", + cooked = "items.cooked_meat", + burnt = "items.burnt_meat", + level = 1, + xp = 30, + stopBurnFire = 34, + stopBurnRange = 34 + ), + heatCook( + rowKey = "cooking_bear_meat", + raw = "items.raw_bear_meat", + cooked = "items.cooked_meat", + burnt = "items.burnt_meat", + level = 1, + xp = 30, + stopBurnFire = 34, + stopBurnRange = 34 + ), + heatCook( + rowKey = "cooking_rabbit", + raw = "items.raw_rabbit", + cooked = "items.cooked_rabbit", + burnt = "items.burnt_meat", + level = 1, + xp = 30, + stopBurnFire = 34, + stopBurnRange = 34 + ), + heatCook( + rowKey = "cooking_ugthanki_meat", + raw = "items.raw_ugthanki_meat", + cooked = "items.cooked_ugthanki_meat", + burnt = "items.burnt_meat", + level = 1, + xp = 40, + stopBurnFire = 34, + stopBurnRange = 34 + ) + ) + + /** Spit roasting recipes (skewer + fire-only roast). */ + val spitRoastRecipes: List = + spitRoast( + skewerRowKey = "cooking_skewer_bird_meat", + roastRowKey = "cooking_roast_bird_meat", + rawMeat = "items.spit_raw_bird_meat", + skewered = "items.spit_skewered_bird_meat", + cooked = "items.spit_roasted_bird_meat", + burnt = "items.spit_burned_bird_meat", + cookingLevel = 11, + xp = 60, + stopBurnFire = 44, + stopBurnRange = 44 + ) + + spitRoast( + skewerRowKey = "cooking_skewer_beast_meat", + roastRowKey = "cooking_roast_beast_meat", + rawMeat = "items.spit_raw_beast_meat", + skewered = "items.spit_skewered_beast_meat", + cooked = "items.spit_roasted_beast_meat", + burnt = "items.spit_burned_beast_meat", + cookingLevel = 21, + xp = 82, + stopBurnFire = 55, + stopBurnRange = 55 + ) + + spitRoast( + skewerRowKey = "cooking_skewer_rabbit_meat", + roastRowKey = "cooking_roast_rabbit_meat", + rawMeat = "items.raw_rabbit", + skewered = "items.spit_skewered_rabbit_meat", + cooked = "items.spit_roasted_rabbit_meat", + burnt = "items.spit_burned_rabbit_meat", + cookingLevel = 16, + xp = 70, + stopBurnFire = 99, + stopBurnRange = 99 + ) + + /** + * Hunter meat recipes — meats obtained from pitfall trapping. + * These are standard heatCook recipes; some are fire-only. + * + * Note: Small kebbits (wild, barb-tailed, dashing) are eaten raw and do NOT + * require cooking. Only pitfall-trapped animals have raw→cooked transitions. + */ + val hunterMeatRecipes: List = listOf( + heatCook( + rowKey = "cooking_larupia", + raw = "items.hunting_larupia_meat", + cooked = "items.larupia_cooked", + burnt = "items.burnt_largebeast", + level = 31, + xp = 92, + stopBurnFire = 59, + stopBurnRange = 59, + stationMask = STATION_FIRE + ), + heatCook( + rowKey = "cooking_graahk", + raw = "items.hunting_graahk_meat", + cooked = "items.graahk_cooked", + burnt = "items.burnt_largebeast", + level = 41, + xp = 124, + stopBurnFire = 75, + stopBurnRange = 75, + stationMask = STATION_FIRE + ), + heatCook( + rowKey = "cooking_kyatt", + raw = "items.hunting_kyatt_meat", + cooked = "items.kyatt_cooked", + burnt = "items.burnt_largebeast", + level = 51, + xp = 143, + stopBurnFire = 86, + stopBurnRange = 80 + ), + heatCook( + rowKey = "cooking_pyre_fox", + raw = "items.hunting_fennecfox_meat", + cooked = "items.fennecfox_cooked", + burnt = "items.burnt_foxmeat", + level = 59, + xp = 154, + stopBurnFire = 93, + stopBurnRange = 92 + ), + heatCook( + rowKey = "cooking_sunlight_antelope", + raw = "items.hunting_antelopesun_meat", + cooked = "items.antelopesun_cooked", + burnt = "items.burnt_antelope", + level = 68, + xp = 175, + stopBurnFire = 100, + stopBurnRange = 95 + ), + heatCook( + rowKey = "cooking_moonlight_antelope", + raw = "items.hunting_antelopemoon_meat", + cooked = "items.antelopemoon_cooked", + burnt = "items.burnt_antelope", + level = 92, + xp = 220, + stopBurnFire = 100, + stopBurnRange = 100 + ) + ) + + /** All meat recipes combined. */ + val recipes: List = basicMeatRecipes + spitRoastRecipes + hunterMeatRecipes +} diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/MiscFoodRecipes.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/MiscFoodRecipes.kt new file mode 100644 index 00000000..e128221d --- /dev/null +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/MiscFoodRecipes.kt @@ -0,0 +1,141 @@ +package org.alter.impl.skills.cooking.recipes + +import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingHelpers.heatCook +import org.alter.impl.skills.cooking.CookingHelpers.multiStepCook +import org.alter.impl.skills.cooking.PrepStepDef + +/** + * Miscellaneous cooking recipes — vegetable side dishes, dairy, scrambled egg, etc. + */ +object MiscFoodRecipes { + + /** Sweetcorn: raw sweetcorn on fire/range. */ + val sweetcorn: List = listOf( + heatCook( + rowKey = "cooking_sweetcorn", + raw = "items.sweetcorn_raw", + cooked = "items.sweetcorn_cooked", + burnt = "items.burnt_sweetcorn", + level = 28, + xp = 104, + stopBurnFire = 61, + stopBurnRange = 61 + ) + ) + + /** Scrambled egg: egg + bowl on range. */ + val scrambledEgg: List = multiStepCook( + key = "items.bowl_egg_scrambled", + level = 13, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_scrambled_egg_mix", + inputs = listOf( + "items.egg" to 1, + "items.bowl_empty" to 1 + ), + output = "items.bowl_egg_uncooked" + ) + ) + ) + listOf( + heatCook( + rowKey = "cooking_scrambled_egg_cook", + raw = "items.bowl_egg_uncooked", + cooked = "items.bowl_egg_scrambled", + burnt = "items.burnt_egg", + level = 13, + xp = 50, + stopBurnFire = 46, + stopBurnRange = 46 + ) + ) + + /** Fried onions: chopped onion + bowl on fire/range. */ + val friedOnions: List = listOf( + heatCook( + rowKey = "cooking_fried_onions", + raw = "items.bowl_onion_chopped", + cooked = "items.bowl_onion_fried", + burnt = "items.burnt_onion", + level = 42, + xp = 60, + stopBurnFire = 74, + stopBurnRange = 74 + ) + ) + + /** Fried mushrooms: sliced mushrooms + bowl on fire/range. */ + val friedMushrooms: List = listOf( + heatCook( + rowKey = "cooking_fried_mushrooms", + raw = "items.bowl_mushroom_sliced", + cooked = "items.bowl_mushroom_fried", + burnt = "items.burnt_mushroom", + level = 46, + xp = 60, + stopBurnFire = 80, + stopBurnRange = 80 + ) + ) + + /** Mushroom & onion: fried mushrooms + fried onions. */ + val mushroomAndOnion: List = multiStepCook( + key = "items.bowl_mushroom_onion", + level = 57, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_mushroom_onion_combine", + inputs = listOf( + "items.bowl_mushroom_fried" to 1, + "items.bowl_onion_fried" to 1 + ), + output = "items.bowl_mushroom_onion", + always = listOf("items.bowl_empty" to 1) + ) + ) + ) + + /** Tuna and corn: cooked tuna + cooked sweetcorn + bowl. */ + val tunaAndCorn: List = multiStepCook( + key = "items.bowl_tuna_corn", + level = 67, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_tuna_corn_combine", + inputs = listOf( + "items.tuna" to 1, + "items.sweetcorn_cooked" to 1, + "items.bowl_empty" to 1 + ), + output = "items.bowl_tuna_corn" + ) + ) + ) + + /** Chocolate cake: cake + chocolate bar. */ + val chocolateCake: List = multiStepCook( + key = "items.chocolate_cake", + level = 50, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_chocolate_cake", + inputs = listOf( + "items.cake" to 1, + "items.chocolate_bar" to 1 + ), + output = "items.chocolate_cake" + ) + ) + ) + + /** All misc cooking recipes combined. */ + val recipes: List = + sweetcorn + + scrambledEgg + + friedOnions + + friedMushrooms + + mushroomAndOnion + + tunaAndCorn + + chocolateCake +} diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PieRecipes.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PieRecipes.kt new file mode 100644 index 00000000..29ccedb3 --- /dev/null +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PieRecipes.kt @@ -0,0 +1,398 @@ +package org.alter.impl.skills.cooking.recipes + +import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE +import org.alter.impl.skills.cooking.CookingHelpers.multiStepCook +import org.alter.impl.skills.cooking.HeatStepDef +import org.alter.impl.skills.cooking.PrepStepDef + +/** + * Remaining pie recipes beyond garden pie. + * + * All pies follow the same flow: + * 1. Prep steps: add fillings to a pie shell (item-on-item) + * 2. Heat step: bake the uncooked pie on a range + */ +object PieRecipes { + + /** Redberry pie (level 10). */ + val redberryPie: List = multiStepCook( + key = "items.uncooked_redberry_pie", + level = 10, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_redberry_pie_add_berries", + inputs = listOf( + "items.pie_shell" to 1, + "items.redberries" to 1 + ), + output = "items.uncooked_redberry_pie" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_redberry_pie_bake", + raw = "items.uncooked_redberry_pie", + cooked = "items.redberry_pie", + burnt = "items.burnt_pie", + xp = 78, + stopBurnFire = 44, + stopBurnRange = 44, + stationMask = STATION_RANGE + ) + ) + + /** Meat pie (level 20). */ + val meatPie: List = multiStepCook( + key = "items.uncooked_meat_pie", + level = 20, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_meat_pie_add_meat", + inputs = listOf( + "items.pie_shell" to 1, + "items.cooked_meat" to 1 + ), + output = "items.uncooked_meat_pie" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_meat_pie_bake", + raw = "items.uncooked_meat_pie", + cooked = "items.meat_pie", + burnt = "items.burnt_pie", + xp = 110, + stopBurnFire = 54, + stopBurnRange = 54, + stationMask = STATION_RANGE + ) + ) + + /** Mud pie (level 29). */ + val mudPie: List = multiStepCook( + key = "items.raw_mud_pie", + level = 29, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_mud_pie_add_compost", + inputs = listOf( + "items.pie_shell" to 1, + "items.compost" to 1 + ), + output = "items.part_mud_pie_1" + ), + PrepStepDef( + rowKey = "cooking_mud_pie_add_water", + inputs = listOf( + "items.part_mud_pie_1" to 1, + "items.bucket_water" to 1 + ), + output = "items.part_mud_pie_2", + always = listOf("items.bucket_empty" to 1) + ), + PrepStepDef( + rowKey = "cooking_mud_pie_add_clay", + inputs = listOf( + "items.part_mud_pie_2" to 1, + "items.clay" to 1 + ), + output = "items.raw_mud_pie" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_mud_pie_bake", + raw = "items.raw_mud_pie", + cooked = "items.mud_pie", + burnt = "items.burnt_pie", + xp = 128, + stopBurnFire = 63, + stopBurnRange = 63, + stationMask = STATION_RANGE + ) + ) + + /** Apple pie (level 30). */ + val applePie: List = multiStepCook( + key = "items.uncooked_apple_pie", + level = 30, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_apple_pie_add_apple", + inputs = listOf( + "items.pie_shell" to 1, + "items.cooking_apple" to 1 + ), + output = "items.uncooked_apple_pie" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_apple_pie_bake", + raw = "items.uncooked_apple_pie", + cooked = "items.apple_pie", + burnt = "items.burnt_pie", + xp = 130, + stopBurnFire = 64, + stopBurnRange = 64, + stationMask = STATION_RANGE + ) + ) + + /** Fish pie (level 47). */ + val fishPie: List = multiStepCook( + key = "items.raw_fish_pie", + level = 47, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_fish_pie_add_trout", + inputs = listOf( + "items.pie_shell" to 1, + "items.trout" to 1 + ), + output = "items.part_fish_pie_1" + ), + PrepStepDef( + rowKey = "cooking_fish_pie_add_cod", + inputs = listOf( + "items.part_fish_pie_1" to 1, + "items.cod" to 1 + ), + output = "items.part_fish_pie_2" + ), + PrepStepDef( + rowKey = "cooking_fish_pie_add_potato", + inputs = listOf( + "items.part_fish_pie_2" to 1, + "items.potato" to 1 + ), + output = "items.raw_fish_pie" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_fish_pie_bake", + raw = "items.raw_fish_pie", + cooked = "items.fish_pie", + burnt = "items.burnt_pie", + xp = 164, + stopBurnFire = 81, + stopBurnRange = 81, + stationMask = STATION_RANGE + ) + ) + + /** Botanical pie (level 52). */ + val botanicalPie: List = multiStepCook( + key = "items.uncooked_botanical_pie", + level = 52, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_botanical_pie_add_golovanova", + inputs = listOf( + "items.pie_shell" to 1, + "items.golovanova_fruit_top" to 1 + ), + output = "items.uncooked_botanical_pie" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_botanical_pie_bake", + raw = "items.uncooked_botanical_pie", + cooked = "items.botanical_pie", + burnt = "items.burnt_pie", + xp = 180, + stopBurnFire = 86, + stopBurnRange = 86, + stationMask = STATION_RANGE + ) + ) + + /** Mushroom pie (level 60). */ + val mushroomPie: List = multiStepCook( + key = "items.raw_mushroom_pie", + level = 60, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_mushroom_pie_add_sulliuscep", + inputs = listOf( + "items.pie_shell" to 1, + "items.sulliuscep_cap" to 1 + ), + output = "items.raw_mushroom_pie" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_mushroom_pie_bake", + raw = "items.raw_mushroom_pie", + cooked = "items.mushroom_pie", + burnt = "items.burnt_pie", + xp = 200, + stopBurnFire = 94, + stopBurnRange = 94, + stationMask = STATION_RANGE + ) + ) + + /** Admiral pie (level 70). */ + val admiralPie: List = multiStepCook( + key = "items.raw_admiral_pie", + level = 70, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_admiral_pie_add_salmon", + inputs = listOf( + "items.pie_shell" to 1, + "items.salmon" to 1 + ), + output = "items.part_admiral_pie_1" + ), + PrepStepDef( + rowKey = "cooking_admiral_pie_add_tuna", + inputs = listOf( + "items.part_admiral_pie_1" to 1, + "items.tuna" to 1 + ), + output = "items.part_admiral_pie_2" + ), + PrepStepDef( + rowKey = "cooking_admiral_pie_add_potato", + inputs = listOf( + "items.part_admiral_pie_2" to 1, + "items.potato" to 1 + ), + output = "items.raw_admiral_pie" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_admiral_pie_bake", + raw = "items.raw_admiral_pie", + cooked = "items.admiral_pie", + burnt = "items.burnt_pie", + xp = 210, + stopBurnFire = 100, + stopBurnRange = 94, + stationMask = STATION_RANGE + ) + ) + + /** Dragonfruit pie (level 73). */ + val dragonfruitPie: List = multiStepCook( + key = "items.uncooked_dragonfruit_pie", + level = 73, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_dragonfruit_pie_add_fruit", + inputs = listOf( + "items.pie_shell" to 1, + "items.dragonfruit" to 1 + ), + output = "items.uncooked_dragonfruit_pie" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_dragonfruit_pie_bake", + raw = "items.uncooked_dragonfruit_pie", + cooked = "items.dragonfruit_pie", + burnt = "items.burnt_pie", + xp = 220, + stopBurnFire = 100, + stopBurnRange = 97, + stationMask = STATION_RANGE + ) + ) + + /** Wild pie (level 85). */ + val wildPie: List = multiStepCook( + key = "items.raw_wild_pie", + level = 85, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_wild_pie_add_bear", + inputs = listOf( + "items.pie_shell" to 1, + "items.raw_bear_meat" to 1 + ), + output = "items.part_wild_pie_1" + ), + PrepStepDef( + rowKey = "cooking_wild_pie_add_chompy", + inputs = listOf( + "items.part_wild_pie_1" to 1, + "items.raw_chompy" to 1 + ), + output = "items.part_wild_pie_2" + ), + PrepStepDef( + rowKey = "cooking_wild_pie_add_rabbit", + inputs = listOf( + "items.part_wild_pie_2" to 1, + "items.raw_rabbit" to 1 + ), + output = "items.raw_wild_pie" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_wild_pie_bake", + raw = "items.raw_wild_pie", + cooked = "items.wild_pie", + burnt = "items.burnt_pie", + xp = 240, + stopBurnFire = 100, + stopBurnRange = 100, + stationMask = STATION_RANGE + ) + ) + + /** Summer pie (level 95). */ + val summerPie: List = multiStepCook( + key = "items.raw_summer_pie", + level = 95, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_summer_pie_add_watermelon", + inputs = listOf( + "items.pie_shell" to 1, + "items.watermelon" to 1 + ), + output = "items.part_summer_pie_1" + ), + PrepStepDef( + rowKey = "cooking_summer_pie_add_apple", + inputs = listOf( + "items.part_summer_pie_1" to 1, + "items.cooking_apple" to 1 + ), + output = "items.part_summer_pie_2" + ), + PrepStepDef( + rowKey = "cooking_summer_pie_add_strawberry", + inputs = listOf( + "items.part_summer_pie_2" to 1, + "items.strawberry" to 1 + ), + output = "items.raw_summer_pie" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_summer_pie_bake", + raw = "items.raw_summer_pie", + cooked = "items.summer_pie", + burnt = "items.burnt_pie", + xp = 260, + stopBurnFire = 100, + stopBurnRange = 100, + stationMask = STATION_RANGE + ) + ) + + /** All pie recipes combined. */ + val recipes: List = + redberryPie + + meatPie + + mudPie + + applePie + + fishPie + + botanicalPie + + mushroomPie + + admiralPie + + dragonfruitPie + + wildPie + + summerPie +} diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PizzaRecipes.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PizzaRecipes.kt new file mode 100644 index 00000000..445863d5 --- /dev/null +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PizzaRecipes.kt @@ -0,0 +1,107 @@ +package org.alter.impl.skills.cooking.recipes + +import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE +import org.alter.impl.skills.cooking.CookingHelpers.multiStepCook +import org.alter.impl.skills.cooking.HeatStepDef +import org.alter.impl.skills.cooking.PrepStepDef + +/** + * Pizza recipes — dough + toppings + range bake. + * + * Flow: pizza base → uncooked pizza (item-on-item) → plain pizza (bake) → topped pizza (item-on-item) + */ +object PizzaRecipes { + + /** Plain pizza: pizza base on range. */ + val plainPizzaRecipes: List = multiStepCook( + key = "items.uncooked_pizza", + level = 35, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_pizza_add_tomato", + inputs = listOf( + "items.pizza_base" to 1, + "items.tomato" to 1 + ), + output = "items.incomplete_pizza" + ), + PrepStepDef( + rowKey = "cooking_pizza_add_cheese", + inputs = listOf( + "items.incomplete_pizza" to 1, + "items.cheese" to 1 + ), + output = "items.uncooked_pizza" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_pizza_bake", + raw = "items.uncooked_pizza", + cooked = "items.plain_pizza", + burnt = "items.burnt_pizza", + xp = 143, + stopBurnFire = 68, + stopBurnRange = 68, + stationMask = STATION_RANGE + ) + ) + + /** Meat pizza topping: plain pizza + cooked meat. */ + val meatPizzaRecipes: List = multiStepCook( + key = "items.meat_pizza", + level = 45, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_pizza_add_meat", + inputs = listOf( + "items.plain_pizza" to 1, + "items.cooked_meat" to 1 + ), + output = "items.meat_pizza", + xp = 26 + ) + ) + ) + + /** Anchovy pizza topping: plain pizza + anchovies. */ + val anchovyPizzaRecipes: List = multiStepCook( + key = "items.anchovy_pizza", + level = 55, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_pizza_add_anchovies", + inputs = listOf( + "items.plain_pizza" to 1, + "items.anchovies" to 1 + ), + output = "items.anchovy_pizza", + xp = 39 + ) + ) + ) + + /** Pineapple pizza topping: plain pizza + pineapple ring/chunks. */ + val pineapplePizzaRecipes: List = multiStepCook( + key = "items.pineapple_pizza", + level = 65, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_pizza_add_pineapple", + inputs = listOf( + "items.plain_pizza" to 1, + "items.pineapple_ring" to 1 + ), + output = "items.pineapple_pizza", + xp = 52 + ) + ) + ) + + /** All pizza recipes combined. */ + val recipes: List = + plainPizzaRecipes + + meatPizzaRecipes + + anchovyPizzaRecipes + + pineapplePizzaRecipes +} diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PotatoRecipes.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PotatoRecipes.kt new file mode 100644 index 00000000..75fe0d8a --- /dev/null +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PotatoRecipes.kt @@ -0,0 +1,121 @@ +package org.alter.impl.skills.cooking.recipes + +import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE +import org.alter.impl.skills.cooking.CookingHelpers.heatCook +import org.alter.impl.skills.cooking.CookingHelpers.multiStepCook +import org.alter.impl.skills.cooking.HeatStepDef +import org.alter.impl.skills.cooking.PrepStepDef + +/** + * Potato-based recipes — baked potato and toppings. + */ +object PotatoRecipes { + + /** Baked potato: raw potato on a range. */ + val bakedPotato: List = listOf( + heatCook( + rowKey = "cooking_baked_potato", + raw = "items.potato", + cooked = "items.potato_baked", + burnt = "items.burnt_potato", + level = 7, + xp = 15, + stopBurnFire = 40, + stopBurnRange = 40, + stationMask = STATION_RANGE + ) + ) + + /** Potato with butter: baked potato + pat of butter. */ + val potatoWithButter: List = multiStepCook( + key = "items.potato_butter", + level = 39, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_potato_add_butter", + inputs = listOf( + "items.potato_baked" to 1, + "items.pat_of_butter" to 1 + ), + output = "items.potato_butter" + ) + ) + ) + + /** Potato with cheese: potato with butter + cheese. */ + val potatoWithCheese: List = multiStepCook( + key = "items.potato_cheese", + level = 47, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_potato_add_cheese", + inputs = listOf( + "items.potato_butter" to 1, + "items.cheese" to 1 + ), + output = "items.potato_cheese" + ) + ) + ) + + /** Egg potato: potato with butter + scrambled egg. */ + val eggPotato: List = multiStepCook( + key = "items.egg_potato", + level = 51, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_potato_add_egg", + inputs = listOf( + "items.potato_butter" to 1, + "items.bowl_egg_scrambled" to 1 + ), + output = "items.egg_potato", + always = listOf("items.bowl_empty" to 1) + ) + ) + ) + + /** Mushroom potato: potato with butter + mushroom & onion. */ + val mushroomPotato: List = multiStepCook( + key = "items.mushroom_potato", + level = 64, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_potato_add_mushroom_onion", + inputs = listOf( + "items.potato_butter" to 1, + "items.bowl_mushroom_onion" to 1 + ), + output = "items.mushroom_potato", + always = listOf("items.bowl_empty" to 1) + ) + ) + ) + + /** Tuna potato: potato with butter + tuna and corn. */ + val tunaPotato: List = multiStepCook( + key = "items.tuna_potato", + level = 68, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_potato_add_tuna_corn", + inputs = listOf( + "items.potato_butter" to 1, + "items.bowl_tuna_corn" to 1 + ), + output = "items.tuna_potato", + always = listOf("items.bowl_empty" to 1) + ) + ) + ) + + /** All potato recipes combined. */ + val recipes: List = + bakedPotato + + potatoWithButter + + potatoWithCheese + + eggPotato + + mushroomPotato + + tunaPotato +} diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/StewRecipes.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/StewRecipes.kt new file mode 100644 index 00000000..b1b7cabc --- /dev/null +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/StewRecipes.kt @@ -0,0 +1,89 @@ +package org.alter.impl.skills.cooking.recipes + +import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingHelpers.multiStepCook +import org.alter.impl.skills.cooking.HeatStepDef +import org.alter.impl.skills.cooking.PrepStepDef + +/** + * Stew recipes — bowl of water + ingredients on heat source. + */ +object StewRecipes { + + /** Basic stew: bowl of water + cooked meat + potato on fire/range. */ + val stewRecipes: List = multiStepCook( + key = "items.uncooked_stew", + level = 25, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_stew_add_potato", + inputs = listOf( + "items.bowl_water" to 1, + "items.potato" to 1 + ), + output = "items.incomplete_stew" + ), + PrepStepDef( + rowKey = "cooking_stew_add_meat", + inputs = listOf( + "items.incomplete_stew" to 1, + "items.cooked_meat" to 1 + ), + output = "items.uncooked_stew" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_stew_cook", + raw = "items.uncooked_stew", + cooked = "items.stew", + burnt = "items.burnt_stew", + xp = 117, + stopBurnFire = 58, + stopBurnRange = 58 + ) + ) + + /** Curry: bowl of water + potato + cooked meat + spice on fire/range. */ + val curryRecipes: List = multiStepCook( + key = "items.uncooked_curry", + level = 60, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_curry_add_potato", + inputs = listOf( + "items.bowl_water" to 1, + "items.potato" to 1 + ), + output = "items.incomplete_stew" + ), + PrepStepDef( + rowKey = "cooking_curry_add_meat", + inputs = listOf( + "items.incomplete_stew" to 1, + "items.cooked_meat" to 1 + ), + output = "items.uncooked_stew" + ), + PrepStepDef( + rowKey = "cooking_curry_add_spice", + inputs = listOf( + "items.uncooked_stew" to 1, + "items.spice" to 1 + ), + output = "items.uncooked_curry" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_curry_cook", + raw = "items.uncooked_curry", + cooked = "items.curry", + burnt = "items.burnt_curry", + xp = 280, + stopBurnFire = 74, + stopBurnRange = 74 + ) + ) + + /** All stew recipes combined. */ + val recipes: List = stewRecipes + curryRecipes +} diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/WineRecipes.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/WineRecipes.kt new file mode 100644 index 00000000..b9bf86ca --- /dev/null +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/WineRecipes.kt @@ -0,0 +1,55 @@ +package org.alter.impl.skills.cooking.recipes + +import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.OutcomeKind +import org.alter.impl.skills.cooking.CookingConstants.Trigger +import org.alter.impl.skills.cooking.InputDef +import org.alter.impl.skills.cooking.OutcomeDef + +/** + * Wine recipes — fermentation mechanic. + * + * Wine is made by using grapes on a jug of water. The fermentation occurs + * automatically after a delay (12 seconds / ~20 ticks). XP is awarded only + * on success. The success/failure is determined at the time of combining, + * not at fermentation completion. + * + * Since wine doesn't use a heat source, it's modeled as an ITEM_ON_ITEM + * trigger. The actual fermentation delay is handled by CookingEvents. + */ +object WineRecipes { + + val jugOfWine: ActionDef = ActionDef( + rowId = "dbrows.cooking_wine", + key = "items.grapes", + variant = 1, + level = 35, + stopBurnFire = 68, + stopBurnRange = 68, + stationMask = 0, // wine doesn't use a station; marker for event handler + trigger = Trigger.ITEM_ON_ITEM, + inputs = listOf( + InputDef("items.grapes", 1), + InputDef("items.jug_water", 1) + ), + outcomes = listOf( + OutcomeDef( + rowSuffix = "success", + kind = OutcomeKind.SUCCESS, + item = "items.jug_unfermented_wine", + xp = 200, + weight = 1 + ), + OutcomeDef( + rowSuffix = "fail", + kind = OutcomeKind.FAIL, + item = "items.jug_unfermented_wine", + xp = 0, + weight = 1 + ) + ) + ) + + /** All wine recipes. */ + val recipes: List = listOf(jugOfWine) +} diff --git a/content/src/main/kotlin/org/alter/commands/developer/CookingTestCommandsPlugin.kt b/content/src/main/kotlin/org/alter/commands/developer/CookingTestCommandsPlugin.kt index 199b9293..16947639 100644 --- a/content/src/main/kotlin/org/alter/commands/developer/CookingTestCommandsPlugin.kt +++ b/content/src/main/kotlin/org/alter/commands/developer/CookingTestCommandsPlugin.kt @@ -11,28 +11,36 @@ import org.alter.rscm.RSCM.asRSCM class CookingTestCommandsPlugin : PluginEvent() { - private enum class CookTestSet(val key: String) { - LOW("low"), - MID("mid"), - HIGH("high"), - MEAT("meat"), - ALL("all") - } - - private data class CookTestPreset( + private enum class CookTestSet( val key: String, - val set: CookTestSet, val level: Int, val qty: Int, - ) + ) { + LOW("low", level = 1, qty = 5), + MID("mid", level = 25, qty = 5), + HIGH("high", level = 80, qty = 3), + FISH("fish", level = 99, qty = 5), + PREP_FISH("prepfish", level = 99, qty = 5), + MEAT("meat", level = 1, qty = 10), + PIES("pies", level = 95, qty = 5), + CAKES("cakes", level = 50, qty = 5), + PIZZA("pizza", level = 65, qty = 5), + STEW("stew", level = 60, qty = 5), + BREAD("bread", level = 58, qty = 5), + POTATO("potato", level = 68, qty = 5), + WINE("wine", level = 35, qty = 5), + MISC("misc", level = 67, qty = 5), + SNAILS("snails", level = 22, qty = 5), + HUNTER("hunter", level = 92, qty = 3), + ALL("all", level = 99, qty = 1); - private val presets = listOf( - CookTestPreset(key = "low", set = CookTestSet.LOW, level = 1, qty = 5), - CookTestPreset(key = "mid", set = CookTestSet.MID, level = 25, qty = 5), - CookTestPreset(key = "high", set = CookTestSet.HIGH, level = 80, qty = 3), - CookTestPreset(key = "meat", set = CookTestSet.MEAT, level = 1, qty = 10), - CookTestPreset(key = "all", set = CookTestSet.ALL, level = 80, qty = 1), - ) + companion object { + fun fromKey(raw: String): CookTestSet? { + val token = raw.removePrefix("--").trim().lowercase() + return entries.firstOrNull { it.key == token } + } + } + } override fun init() { on { @@ -43,17 +51,17 @@ class CookingTestCommandsPlugin : PluginEvent() { then { val args = args.orEmpty().map { it.trim() }.filter { it.isNotEmpty() } - val preset = parseCookTestPreset(player, args) - if (preset == null) { + val set = parseCookTestSet(args) + if (set == null) { sendCookTestHelp(player) return@then } - player.getSkills().setBaseLevel(Skills.COOKING, preset.level) + player.getSkills().setBaseLevel(Skills.COOKING, set.level) - val keys = keysFor(preset.set) + val keys = keysFor(set) if (keys.isEmpty()) { - player.message("No items configured for preset '${preset.key}'.") + player.message("No items configured for preset '${set.key}'.") return@then } @@ -61,7 +69,7 @@ class CookingTestCommandsPlugin : PluginEvent() { var failed = 0 for (key in keys) { val id = runCatching { key.asRSCM() }.getOrNull() ?: continue - val result = player.inventory.add(id, preset.qty) + val result = player.inventory.add(id, set.qty) if (result.hasSucceeded()) { addedAny = true } else { @@ -74,19 +82,18 @@ class CookingTestCommandsPlugin : PluginEvent() { } else if (failed > 0) { player.message("Added cooking test items (some didn't fit: $failed).") } else { - player.message("Applied cooktest preset '${preset.key}' (x${preset.qty} each, Cooking=${preset.level}).") + player.message("Applied cooktest preset '${set.key}' (x${set.qty} each, Cooking=${set.level}).") } } } } - private fun parseCookTestPreset(player: org.alter.game.model.entity.Player, args: List): CookTestPreset? { + private fun parseCookTestSet(args: List): CookTestSet? { if (args.isEmpty() || args.any { it.equals("help", ignoreCase = true) || it == "-h" || it == "--help" }) { return null } - val token = args.first().removePrefix("--").trim().lowercase() - return presets.firstOrNull { it.key == token } + return CookTestSet.fromKey(args.first()) } private fun keysFor(set: CookTestSet): List = @@ -110,17 +117,176 @@ class CookingTestCommandsPlugin : PluginEvent() { "items.raw_shark" ) + CookTestSet.FISH -> listOf( + "items.raw_shrimp", + "items.raw_anchovies", + "items.raw_sardine", + "items.raw_herring", + "items.raw_mackerel", + "items.raw_trout", + "items.raw_cod", + "items.raw_pike", + "items.raw_salmon", + "items.raw_tuna", + "items.hunting_raw_fish_special", + "items.mort_slimey_eel", + "items.raw_cave_eel", + "items.tbwt_raw_karambwan", + "items.raw_lobster", + "items.raw_bass", + "items.raw_swordfish", + "items.raw_monkfish", + "items.raw_shark", + "items.raw_seaturtle", + "items.raw_anglerfish", + "items.raw_dark_crab", + "items.raw_mantaray", + // Snails + "items.snail_corpse1", + "items.snail_corpse2", + "items.snail_corpse3" + ) + + CookTestSet.PREP_FISH -> listOf( + "items.knife", + "items.raw_guppy", + "items.raw_cavefish", + "items.raw_tetra", + "items.raw_catfish" + ) + CookTestSet.MEAT -> listOf( "items.raw_beef", - "items.raw_chicken" + "items.raw_chicken", + // Extra meats (some may not exist in all caches; missing keys are skipped safely). + "items.raw_rat_meat", + "items.raw_bear_meat", + "items.raw_rabbit", + "items.raw_ugthanki_meat", + "items.raw_chompy", + // Spit roasting requires an iron spit + skewering first. + "items.spit_iron", + "items.spit_raw_bird_meat", + "items.spit_raw_beast_meat", + // Optional direct roast testing (post-skewer intermediates) + "items.spit_skewered_bird_meat", + "items.spit_skewered_beast_meat", + "items.spit_skewered_rabbit_meat" + ) + + CookTestSet.PIES -> listOf( + // Pie shell for assembly + "items.pie_shell", + // Garden pie ingredients + "items.tomato", + "items.onion", + "items.cabbage", + // Redberry pie + "items.redberries", + // Meat pie + "items.cooked_meat", + // Apple pie + "items.cooking_apple", + // Direct bake tests + "items.uncooked_garden_pie", + "items.uncooked_redberry_pie", + "items.uncooked_meat_pie", + "items.uncooked_apple_pie" + ) + + CookTestSet.CAKES -> listOf( + // Cake (mix + bake) + "items.cake_tin", + "items.egg", + "items.bucket_milk", + "items.pot_flour", + // Optional direct bake test + "items.uncooked_cake", + // Chocolate cake + "items.cake", + "items.chocolate_bar" + ) + + CookTestSet.PIZZA -> listOf( + // Pizza base ingredients + "items.pizza_base", + "items.tomato", + "items.cheese", + // Toppings + "items.cooked_meat", + "items.anchovies", + "items.pineapple_ring", + // Direct bake test + "items.uncooked_pizza", + // Already baked for topping tests + "items.plain_pizza" + ) + + CookTestSet.STEW -> listOf( + "items.bowl_water", + "items.potato", + "items.cooked_meat", + "items.spice", + // Direct cook test + "items.uncooked_stew" + ) + + CookTestSet.BREAD -> listOf( + "items.bread_dough", + "items.pitta_dough" + ) + + CookTestSet.POTATO -> listOf( + "items.potato", + "items.potato_baked", + "items.pat_of_butter", + "items.potato_butter", + "items.cheese", + "items.bowl_egg_scrambled", + "items.bowl_mushroom_onion", + "items.bowl_tuna_corn" + ) + + CookTestSet.WINE -> listOf( + "items.grapes", + "items.jug_water" + ) + + CookTestSet.MISC -> listOf( + "items.sweetcorn_raw", + "items.egg", + "items.bowl_empty", + "items.bowl_onion_chopped", + "items.bowl_mushroom_sliced", + "items.tuna", + "items.sweetcorn_cooked" + ) + + CookTestSet.SNAILS -> listOf( + "items.snail_corpse1", + "items.snail_corpse2", + "items.snail_corpse3" + ) + + CookTestSet.HUNTER -> listOf( + "items.hunting_larupia_meat", + "items.hunting_graahk_meat", + "items.hunting_kyatt_meat", + "items.hunting_fennecfox_meat", + "items.hunting_antelopesun_meat", + "items.hunting_antelopemoon_meat" ) - CookTestSet.ALL -> keysFor(CookTestSet.LOW) + keysFor(CookTestSet.MID) + keysFor(CookTestSet.HIGH) + keysFor(CookTestSet.MEAT) + CookTestSet.ALL -> keysFor(CookTestSet.FISH) + keysFor(CookTestSet.PREP_FISH) + + keysFor(CookTestSet.MEAT) + keysFor(CookTestSet.PIES) + keysFor(CookTestSet.CAKES) + + keysFor(CookTestSet.PIZZA) + keysFor(CookTestSet.STEW) + keysFor(CookTestSet.BREAD) + + keysFor(CookTestSet.POTATO) + keysFor(CookTestSet.WINE) + keysFor(CookTestSet.MISC) + + keysFor(CookTestSet.SNAILS) + keysFor(CookTestSet.HUNTER) } private fun sendCookTestHelp(player: org.alter.game.model.entity.Player) { player.message("Usage: ::cooktest ") - player.message("Presets: ${presets.joinToString(", ") { it.key }}") - player.message("Examples: ::cooktest low | ::cooktest mid | ::cooktest high | ::cooktest meat | ::cooktest all") + player.message("Presets: ${CookTestSet.entries.joinToString(", ") { it.key }}") + player.message("Examples: ${CookTestSet.entries.joinToString(" | ") { "::cooktest ${it.key}" }}") } } diff --git a/content/src/main/kotlin/org/alter/skills/cooking/CookingEvents.kt b/content/src/main/kotlin/org/alter/skills/cooking/CookingEvents.kt deleted file mode 100644 index d946a9be..00000000 --- a/content/src/main/kotlin/org/alter/skills/cooking/CookingEvents.kt +++ /dev/null @@ -1,223 +0,0 @@ -package org.alter.skills.cooking - -import dev.openrune.ServerCacheManager.getItem -import org.alter.api.Skills -import org.alter.api.computeSkillingSuccess -import org.alter.api.ext.filterableMessage -import org.alter.api.ext.message -import org.alter.api.ext.produceItemBox -import org.alter.game.model.entity.GameObject -import org.alter.game.model.entity.Player -import org.alter.game.pluginnew.MenuOption -import org.alter.game.pluginnew.PluginEvent -import org.alter.game.pluginnew.event.impl.ItemOnObject -import org.alter.game.pluginnew.event.impl.ObjectClickEvent -import org.alter.rscm.RSCM -import org.alter.rscm.RSCM.asRSCM -import org.alter.rscm.RSCMType -import org.alter.skills.firemaking.ColoredLogs -import org.generated.tables.cooking.CookingRecipesRow -import kotlin.random.Random - -class CookingEvents : PluginEvent() { - - private enum class CookStation { - FIRE, - RANGE - } - - override fun init() { - - // Click range/fire -> open cooking menu - on { - where { optionName.equals("cook", ignoreCase = true) } - then { - val station = stationFor(gameObject) - openCookingMenu(player, station, gameObject) - } - } - - // Use raw food on range/fire -> open cooking menu for that item - on { - where { - option.equals("cook", ignoreCase = true) && - CookingRecipes.byRaw.containsKey(item.id) - } - then { - val recipe = CookingRecipes.byRaw[item.id] ?: return@then - val station = stationFor(gameObject) - openCookingMenu(player, station, gameObject, listOf(recipe)) - } - } - } - - private fun stationFor(gameObject: GameObject): CookStation { - val fireIds = buildFireObjectIds() - return if (fireIds.contains(gameObject.internalID)) CookStation.FIRE else CookStation.RANGE - } - - private fun buildFireObjectIds(): Set { - val fireKeys = ColoredLogs.COLOURED_LOGS.values.map { it.second } + - "objects.fire" + - "objects.forestry_fire" - - val fireInts = fireKeys.mapNotNull { key -> - runCatching { key.asRSCM() }.getOrNull() - } - - return fireInts.toSet() - } - - private fun openCookingMenu( - player: Player, - station: CookStation, - gameObject: GameObject, - only: List? = null - ) { - val cookingLevel = player.getSkills().getCurrentLevel(Skills.COOKING) - - val candidates = (only ?: CookingRecipes.all) - .filter { recipe -> - player.inventory.contains(recipe.raw) && cookingLevel >= recipe.level - } - - if (candidates.isEmpty()) { - player.message("You have nothing you can cook.") - return - } - - // The SKILL_MULTI chatbox UI supports up to 18 item options. - val maxOptions = 18 - val menuCandidates = candidates - .sortedWith( - compareBy { it.level } - .thenBy { getItem(it.cooked)?.name ?: "" } - ) - .take(maxOptions) - - val maxProducible = menuCandidates.maxOf { recipe -> player.inventory.getItemCount(recipe.raw) } - - player.queue { - val cookedItems = menuCandidates.map { it.cooked }.toIntArray() - - produceItemBox( - player, - *cookedItems, - title = "What would you like to cook?", - maxProducable = maxProducible - ) { cookedItemId, qty -> - val recipe = menuCandidates.firstOrNull { it.cooked == cookedItemId } ?: return@produceItemBox - - cook(player, station, gameObject, recipe, qty) - } - } - } - - private fun cook( - player: Player, - station: CookStation, - gameObject: GameObject, - recipe: CookingRecipesRow, - quantity: Int - ) { - val cookingLevel = player.getSkills().getCurrentLevel(Skills.COOKING) - if (cookingLevel < recipe.level) { - player.filterableMessage("You need a Cooking level of ${recipe.level} to cook this.") - return - } - - val objectTile = gameObject.tile - val objectId = gameObject.internalID - - player.queue { - var cooked = 0 - - player.filterableMessage("You begin cooking...") - - repeatWhile(delay = 4, immediate = true, canRepeat = { - cooked < quantity && - player.inventory.contains(recipe.raw) && - isStillAtStation(player, objectTile, objectId) - }) { - - // Optional animation (safe fallback if missing) - runCatching { player.animate("sequences.human_cooking", interruptable = true) } - .onFailure { player.animate(RSCM.NONE) } - - val removed = player.inventory.remove(recipe.raw, 1) - if (!removed.hasSucceeded()) { - stop() - return@repeatWhile - } - - val success = rollCookSuccess(player, station, recipe) - val outputItem = if (success) recipe.cooked else recipe.burnt - - val addResult = player.inventory.add(outputItem, 1) - if (!addResult.hasSucceeded()) { - // restore raw - player.inventory.add(recipe.raw, 1) - player.filterableMessage("You don't have enough inventory space.") - stop() - return@repeatWhile - } - - if (success) { - player.addXp(Skills.COOKING, recipe.xp.toDouble()) - val cookedName = getItem(recipe.cooked)?.name?.lowercase() ?: "food" - player.filterableMessage("You cook the $cookedName.") - } else { - val burntName = getItem(recipe.burnt)?.name?.lowercase() ?: "food" - player.filterableMessage("You accidentally burn the $burntName.") - } - - cooked++ - wait(1) - } - - player.animate(RSCM.NONE) - } - } - - private fun rollCookSuccess( - player: Player, - station: CookStation, - recipe: CookingRecipesRow - ): Boolean { - val cookingLevel = player.getSkills().getCurrentLevel(Skills.COOKING) - - val stopBurn = when (station) { - CookStation.FIRE -> recipe.stopBurnFire - CookStation.RANGE -> recipe.stopBurnRange - }.coerceAtLeast(recipe.level) - - if (cookingLevel >= stopBurn) { - return true - } - - val baseSuccessAtReq = when (station) { - CookStation.FIRE -> 0.30 - CookStation.RANGE -> 0.45 - } - - val progress = ((cookingLevel - recipe.level).toDouble() / (stopBurn - recipe.level).toDouble()) - .coerceIn(0.0, 1.0) - - val chance = (baseSuccessAtReq + (1.0 - baseSuccessAtReq) * progress).coerceIn(0.0, 1.0) - - // Blend with the shared OSRS skilling success curve for nicer scaling. - // This keeps early levels from feeling too punishing while still rewarding levels. - val curve = computeSkillingSuccess(low = 64, high = 256, level = (cookingLevel - recipe.level + 1).coerceIn(1, 99)) - val finalChance = (chance * 0.70 + curve * 0.30).coerceIn(0.0, 1.0) - - return Random.nextDouble() < finalChance - } - - private fun isStillAtStation(player: Player, objectTile: org.alter.game.model.Tile, objectId: Int): Boolean { - if (player.tile.getDistance(objectTile) > 1) return false - - val world = player.world - val obj = world.getObject(objectTile, type = 10) ?: world.getObject(objectTile, type = 11) - return obj != null && obj.internalID == objectId - } -} diff --git a/content/src/main/kotlin/org/alter/skills/cooking/CookingRecipes.kt b/content/src/main/kotlin/org/alter/skills/cooking/CookingRecipes.kt deleted file mode 100644 index 58d45d22..00000000 --- a/content/src/main/kotlin/org/alter/skills/cooking/CookingRecipes.kt +++ /dev/null @@ -1,11 +0,0 @@ -package org.alter.skills.cooking - -import org.generated.tables.cooking.CookingRecipesRow - -object CookingRecipes { - val all: List = CookingRecipesRow.all() - - val byRaw: Map = all.associateBy { it.raw } - - val byCooked: Map = all.associateBy { it.cooked } -} diff --git a/content/src/main/kotlin/org/alter/skills/cooking/events/CamdozaalPrepTable.kt b/content/src/main/kotlin/org/alter/skills/cooking/events/CamdozaalPrepTable.kt new file mode 100644 index 00000000..6f9bdf43 --- /dev/null +++ b/content/src/main/kotlin/org/alter/skills/cooking/events/CamdozaalPrepTable.kt @@ -0,0 +1,148 @@ +package org.alter.skills.cooking.events + +import dev.openrune.ServerCacheManager.getItem +import org.alter.api.Skills +import org.alter.api.computeSkillingSuccess +import org.alter.api.ext.filterableMessage +import org.alter.api.ext.message +import org.alter.game.model.entity.GameObject +import org.alter.game.model.entity.Player +import org.alter.game.model.queue.QueueTask +import org.alter.skills.cooking.events.CookingUtils.isStillAtStation +import org.alter.rscm.RSCM +import org.alter.rscm.RSCM.asRSCM +import kotlin.random.Random/** + * Handles cooking at the Camdozaal Preparation Table (knife-based prep, not heat). + */ +object CamdozaalPrepTable { + + private data class PrepFishDef( + val raw: String, + val prepared: String, + val ruined: String, + val level: Int, + val xp: Int + ) + + val prepTableId: Int = "objects.camdozaal_preparation_table".asRSCM() + + private val knifeId: Int? = runCatching { "items.knife".asRSCM() }.getOrNull() + + private val prepFishByRaw: Map = listOf( + PrepFishDef( + raw = "items.raw_guppy", + prepared = "items.guppy", + ruined = "items.ruined_guppy", + level = 7, + xp = 12 + ), + PrepFishDef( + raw = "items.raw_cavefish", + prepared = "items.cavefish", + ruined = "items.ruined_cavefish", + level = 20, + xp = 23 + ), + PrepFishDef( + raw = "items.raw_tetra", + prepared = "items.tetra", + ruined = "items.ruined_tetra", + level = 33, + xp = 31 + ), + PrepFishDef( + raw = "items.raw_catfish", + prepared = "items.catfish", + ruined = "items.ruined_catfish", + level = 46, + xp = 43 + ) + ).mapNotNull { def -> + val rawId = runCatching { def.raw.asRSCM() }.getOrNull() ?: return@mapNotNull null + rawId to def + }.toMap() + + /** + * Checks if the given item ID is a raw hunter fish for the prep table. + */ + fun isRawPrepFish(itemId: Int): Boolean = prepFishByRaw.containsKey(itemId) + + /** + * Handles using a raw fish on the preparation table. + */ + suspend fun QueueTask.prepareFish( + player: Player, + gameObject: GameObject, + rawItemId: Int + ) { + val def = prepFishByRaw[rawItemId] ?: return + val knife = knifeId + if (knife == null || player.inventory.getItemCount(knife) <= 0) { + player.message("You need a knife to prepare this.") + return + } + + val cookingLevel = player.getSkills().getCurrentLevel(Skills.COOKING) + if (cookingLevel < def.level) { + player.filterableMessage("You need a Cooking level of ${def.level} to prepare this.") + return + } + + val objectTile = gameObject.tile + val objectId = gameObject.internalID + val preparedId = runCatching { def.prepared.asRSCM() }.getOrNull() ?: return + val ruinedId = runCatching { def.ruined.asRSCM() }.getOrNull() ?: return + + var prepared = 0 + player.filterableMessage("You begin preparing the fish...") + + repeatWhile(delay = 3, immediate = true, canRepeat = { + player.inventory.getItemCount(rawItemId) > 0 && + player.inventory.getItemCount(knife) > 0 && + isStillAtStation(player, objectTile, objectId) + }) { + runCatching { player.animate("sequences.human_cutting", interruptable = true) } + .onFailure { player.animate(RSCM.NONE) } + + val removed = player.inventory.remove(rawItemId, 1) + if (!removed.hasSucceeded()) { + stop() + return@repeatWhile + } + + val successChance = computeSkillingSuccess( + low = 64, + high = 256, + level = (cookingLevel - def.level + 1).coerceIn(1, 99) + ).coerceIn(0.0, 1.0) + + val success = Random.nextDouble() < successChance + + if (success) { + if (!player.inventory.add(preparedId, 1).hasSucceeded()) { + player.inventory.add(rawItemId, 1) + player.filterableMessage("You don't have enough inventory space.") + stop() + return@repeatWhile + } + player.addXp(Skills.COOKING, def.xp.toDouble()) + val name = getItem(preparedId)?.name?.lowercase() ?: "fish" + player.filterableMessage("You prepare the $name.") + } else { + if (!player.inventory.add(ruinedId, 1).hasSucceeded()) { + player.inventory.add(rawItemId, 1) + player.filterableMessage("You don't have enough inventory space.") + stop() + return@repeatWhile + } + val name = getItem(ruinedId)?.name?.lowercase() ?: "fish" + player.filterableMessage("You ruin the $name.") + } + + prepared++ + wait(1) + } + + player.animate(RSCM.NONE) + } +} diff --git a/content/src/main/kotlin/org/alter/skills/cooking/events/CookingEvents.kt b/content/src/main/kotlin/org/alter/skills/cooking/events/CookingEvents.kt new file mode 100644 index 00000000..501d788e --- /dev/null +++ b/content/src/main/kotlin/org/alter/skills/cooking/events/CookingEvents.kt @@ -0,0 +1,503 @@ +package org.alter.skills.cooking.events + +import dev.openrune.ServerCacheManager.getItem +import org.alter.api.Skills +import org.alter.api.ext.filterableMessage +import org.alter.api.ext.message +import org.alter.api.ext.produceItemBox +import org.alter.game.model.attr.AttributeKey +import org.alter.game.model.entity.GameObject +import org.alter.game.model.entity.Player +import org.alter.game.model.queue.QueueTask +import org.alter.game.model.timer.TimerKey +import org.alter.game.pluginnew.PluginEvent +import org.alter.game.pluginnew.event.impl.ItemOnObject +import org.alter.game.pluginnew.event.impl.ItemOnItemEvent +import org.alter.game.pluginnew.event.impl.ObjectClickEvent +import org.alter.game.pluginnew.event.impl.onTimer +import org.alter.rscm.RSCM +import org.alter.rscm.RSCM.asRSCM +import org.alter.skills.cooking.events.CookingUtils.CookStation +import org.alter.skills.cooking.events.CookingUtils.SPIT_ROAST_FIREMAKING_LEVEL +import org.alter.skills.cooking.events.CookingUtils.hasInputs +import org.alter.skills.cooking.events.CookingUtils.isSpitRoastAction +import org.alter.skills.cooking.events.CookingUtils.isStationAllowed +import org.alter.skills.cooking.events.CookingUtils.isStillAtStation +import org.alter.skills.cooking.events.CookingUtils.maxProducible +import org.alter.skills.cooking.events.CookingUtils.meetsExtraRequirements +import org.alter.skills.cooking.events.CookingUtils.rollCookSuccess +import org.alter.skills.cooking.events.CookingUtils.rollWineSuccess +import org.alter.skills.cooking.events.CookingUtils.stationFor +import org.alter.skills.cooking.runtime.CookingAction +import org.alter.skills.cooking.runtime.CookingActionRegistry +import org.alter.skills.cooking.runtime.OutcomeKind +import org.alter.skills.cooking.runtime.Trigger + +/** + * Main event handler for the Cooking skill. + * + * Handles: + * - Using raw food on fires/ranges (heat-source cooking) + * - Clicking "Cook" on fires/ranges + * - Item-on-item preparation (e.g., combining ingredients) + * - Camdozaal preparation table (knife-based prep) + */ +class CookingEvents : PluginEvent() { + + companion object { + /** Timer for wine fermentation delay (~12 seconds = 20 ticks). */ + val WINE_FERMENT_TIMER = TimerKey() + + /** Number of pending wine fermentations that will succeed. */ + val WINE_SUCCESS_COUNT = AttributeKey() + + /** Number of pending wine fermentations that will fail. */ + val WINE_FAIL_COUNT = AttributeKey() + + /** Fermentation delay in game ticks (12 seconds). */ + const val WINE_FERMENT_TICKS = 20 + } + + override fun init() { + registerCamdozaalPrepTableEvents() + registerHeatSourceCookingEvents() + registerItemOnItemPrepEvents() + registerWineFermentationTimer() + } + + // ======================================== + // Camdozaal Preparation Table + // ======================================== + + private fun registerCamdozaalPrepTableEvents() { + on { + where { + gameObject.internalID == CamdozaalPrepTable.prepTableId && + CamdozaalPrepTable.isRawPrepFish(item.id) + } + then { + player.queue { + with(CamdozaalPrepTable) { + prepareFish(player, gameObject, item.id) + } + } + } + } + } + + // ======================================== + // Heat-Source Cooking (Fire/Range) + // ======================================== + + private fun registerHeatSourceCookingEvents() { + // Click "Cook" on range/fire -> open cooking menu + on { + where { optionName.equals("cook", ignoreCase = true) } + then { + val station = stationFor(gameObject) + openCookingMenu(player, station, gameObject) + } + } + + // Use raw food on range/fire -> open cooking menu for that item + on { + where { + CookingActionRegistry.byRaw.containsKey(item.id) && + CookingUtils.isHeatSource(gameObject) + } + then { + val actions = CookingActionRegistry.byRaw[item.id] ?: return@then + val station = stationFor(gameObject) + openCookingMenu(player, station, gameObject, actions) + } + } + } + + // ======================================== + // Item-on-Item Preparation + // ======================================== + + private fun registerItemOnItemPrepEvents() { + onEvent { + val cookingLevel = player.getSkills().getCurrentLevel(Skills.COOKING) + val item1 = fromItem.id + val item2 = toItem.id + + // Use pre-indexed lookup: find actions that use either item as an input + val actionsForItem1 = CookingActionRegistry.itemOnItemByInput[item1] ?: emptyList() + val actionsForItem2 = CookingActionRegistry.itemOnItemByInput[item2] ?: emptyList() + + // Intersect: only actions that have BOTH items as inputs + val possibleActions = if (actionsForItem1.size <= actionsForItem2.size) { + actionsForItem1.filter { it in actionsForItem2 } + } else { + actionsForItem2.filter { it in actionsForItem1 } + } + + val candidates = possibleActions + .filter { cookingLevel >= it.row.level && hasInputs(player, it) } + + if (candidates.isEmpty()) { + return@onEvent + } + + // Wine actions (stationMask == 0) use the special fermentation path + val wineActions = candidates.filter { it.row.stationMask == 0 } + val normalActions = candidates.filter { it.row.stationMask != 0 } + + if (wineActions.isNotEmpty() && normalActions.isEmpty()) { + // Only wine candidates — use fermentation flow + player.queue { + val action = wineActions.first() + val maxCount = maxProducible(player, action) + performWineAction(player, action, maxCount) + } + return@onEvent + } + + // Normal item-on-item prep (non-wine candidates) + val activeCandidates = normalActions.ifEmpty { candidates } + val maxProducibleCount = activeCandidates.maxOf { action -> maxProducible(player, action) } + val options = activeCandidates + .sortedWith(compareBy { it.row.level }.thenBy { it.primaryOutputItem() }) + .take(18) + + player.queue { + val producedItems = options.map { it.primaryOutputItem() }.toIntArray() + + // If only one option, skip the UI and just do 1. + if (options.size == 1) { + performPrepAction(player, options.first(), 1) + return@queue + } + + produceItemBox( + player, + *producedItems, + title = "What would you like to make?", + maxProducable = maxProducibleCount + ) { selectedItemId, quantity -> + val action = options.firstOrNull { it.primaryOutputItem() == selectedItemId } + ?: return@produceItemBox + performPrepAction(player, action, quantity) + } + } + } + } + + // ======================================== + // Cooking Menu & Cooking Logic + // ======================================== + + private fun openCookingMenu( + player: Player, + station: CookStation, + gameObject: GameObject, + only: List? = null + ) { + val cookingLevel = player.getSkills().getCurrentLevel(Skills.COOKING) + + val candidates = (only ?: CookingActionRegistry.allActions) + .filter { action -> + action.row.trigger == Trigger.HEAT_SOURCE && + cookingLevel >= action.row.level && + isStationAllowed(action, station) && + meetsExtraRequirements(player, action) && + hasInputs(player, action) + } + + if (candidates.isEmpty()) { + player.message("You have nothing you can cook.") + return + } + + val maxOptions = 18 + val menuCandidates = candidates + .sortedWith( + compareBy { it.row.level } + .thenBy { getItem(it.primaryOutputItem())?.name ?: "" } + ) + .take(maxOptions) + + val maxProducibleCount = menuCandidates.maxOf { action -> maxProducible(player, action) } + + player.queue { + val cookedItems = menuCandidates.map { it.primaryOutputItem() }.toIntArray() + + produceItemBox( + player, + *cookedItems, + title = "What would you like to cook?", + maxProducable = maxProducibleCount + ) { cookedItemId, qty -> + val action = menuCandidates.firstOrNull { it.primaryOutputItem() == cookedItemId } + ?: return@produceItemBox + + cook(player, station, gameObject, action, qty) + } + } + } + + private fun cook( + player: Player, + station: CookStation, + gameObject: GameObject, + action: CookingAction, + quantity: Int + ) { + val cookingLevel = player.getSkills().getCurrentLevel(Skills.COOKING) + if (cookingLevel < action.row.level) { + player.filterableMessage("You need a Cooking level of ${action.row.level} to cook this.") + return + } + + if (!meetsExtraRequirements(player, action)) { + if (isSpitRoastAction(action)) { + player.filterableMessage("You need a Firemaking level of $SPIT_ROAST_FIREMAKING_LEVEL to roast this on an iron spit.") + } + return + } + + val objectTile = gameObject.tile + val objectId = gameObject.internalID + + player.queue { + var cooked = 0 + + player.filterableMessage("You begin cooking...") + + repeatWhile(delay = 4, immediate = true, canRepeat = { + cooked < quantity && + hasInputs(player, action) && + isStillAtStation(player, objectTile, objectId) + }) { + runCatching { player.animate("sequences.human_cooking", interruptable = true) } + .onFailure { player.animate(RSCM.NONE) } + + // Consume inputs + val inputs = action.inputs + val removedInputs = mutableListOf>() + for (input in inputs) { + val removed = player.inventory.remove(input.item, input.count) + if (!removed.hasSucceeded()) { + removedInputs.forEach { (itemId, count) -> player.inventory.add(itemId, count) } + stop() + return@repeatWhile + } + removedInputs.add(input.item to input.count) + } + + val success = rollCookSuccess(player, station, action) + val outcomes = CookingOutcomes.resolveOutcomes(action, success) + val addedOutputs = mutableListOf>() + + for (outcome in outcomes) { + val producedCount = CookingOutcomes.rollCount(outcome) + val addResult = player.inventory.add(outcome.item, producedCount) + if (!addResult.hasSucceeded()) { + addedOutputs.forEach { (itemId, count) -> player.inventory.remove(itemId, count) } + removedInputs.forEach { (itemId, count) -> player.inventory.add(itemId, count) } + player.filterableMessage("You don't have enough inventory space.") + stop() + return@repeatWhile + } + addedOutputs.add(outcome.item to producedCount) + + if (outcome.xp > 0) { + player.addXp(Skills.COOKING, outcome.xp.toDouble()) + } + } + + val primary = outcomes.firstOrNull { it.kind != OutcomeKind.ALWAYS } ?: outcomes.firstOrNull() + if (primary != null) { + if (primary.kind == OutcomeKind.SUCCESS) { + val cookedName = getItem(primary.item)?.name?.lowercase() ?: "food" + player.filterableMessage("You cook the $cookedName.") + } else { + val burntName = getItem(primary.item)?.name?.lowercase() ?: "food" + player.filterableMessage("You accidentally burn the $burntName.") + } + } + + cooked++ + wait(1) + } + + player.animate(RSCM.NONE) + } + } + + private fun performPrepAction( + player: Player, + action: CookingAction, + quantity: Int + ) { + val cookingLevel = player.getSkills().getCurrentLevel(Skills.COOKING) + if (cookingLevel < action.row.level) { + player.filterableMessage("You need a Cooking level of ${action.row.level} to make this.") + return + } + + player.queue { + var made = 0 + repeatWhile(delay = 2, immediate = true, canRepeat = { + made < quantity && hasInputs(player, action) + }) { + val removedInputs = mutableListOf>() + for (input in action.inputs) { + val removed = player.inventory.remove(input.item, input.count) + if (!removed.hasSucceeded()) { + removedInputs.forEach { (itemId, count) -> player.inventory.add(itemId, count) } + stop() + return@repeatWhile + } + removedInputs.add(input.item to input.count) + } + + val outcomes = CookingOutcomes.resolveOutcomes(action, success = true) + val addedOutputs = mutableListOf>() + + for (outcome in outcomes) { + val producedCount = CookingOutcomes.rollCount(outcome) + val addResult = player.inventory.add(outcome.item, producedCount) + if (!addResult.hasSucceeded()) { + addedOutputs.forEach { (itemId, count) -> player.inventory.remove(itemId, count) } + removedInputs.forEach { (itemId, count) -> player.inventory.add(itemId, count) } + player.filterableMessage("You don't have enough inventory space.") + stop() + return@repeatWhile + } + addedOutputs.add(outcome.item to producedCount) + + if (outcome.xp > 0) { + player.addXp(Skills.COOKING, outcome.xp.toDouble()) + } + } + + val primary = outcomes.firstOrNull { it.kind != OutcomeKind.ALWAYS } ?: outcomes.firstOrNull() + val name = primary?.let { getItem(it.item)?.name?.lowercase() } ?: "item" + player.filterableMessage("You make $name.") + made++ + } + } + } + + // ======================================== + // Wine Fermentation + // ======================================== + + /** + * Handles combining grapes with a jug of water to create unfermented wine. + * + * In OSRS, wine fermentation works as follows: + * 1. Grapes + jug of water → unfermented wine (instant) + * 2. Success/failure is rolled at combine time based on cooking level + * 3. A 12-second (~20 tick) timer starts/resets for ALL pending wines + * 4. When the timer fires, all unfermented wines convert to jug_of_wine + * (success) or jug_of_bad_wine (fail). XP is awarded only for successes. + */ + private suspend fun QueueTask.performWineAction( + player: Player, + action: CookingAction, + quantity: Int + ) { + val cookingLevel = player.getSkills().getCurrentLevel(Skills.COOKING) + if (cookingLevel < action.row.level) { + player.filterableMessage("You need a Cooking level of ${action.row.level} to do that.") + return + } + + var made = 0 + repeatWhile(delay = 2, immediate = true, canRepeat = { + made < quantity && hasInputs(player, action) + }) { + // Remove inputs (grapes + jug of water) + val removedInputs = mutableListOf>() + for (input in action.inputs) { + val removed = player.inventory.remove(input.item, input.count) + if (!removed.hasSucceeded()) { + removedInputs.forEach { (itemId, count) -> player.inventory.add(itemId, count) } + stop() + return@repeatWhile + } + removedInputs.add(input.item to input.count) + } + + // Add unfermented wine + val unfermentedWineId = action.outcomes + .firstOrNull { it.kind == OutcomeKind.SUCCESS }?.item + ?: action.primaryOutputItem() + val addResult = player.inventory.add(unfermentedWineId, 1) + if (!addResult.hasSucceeded()) { + removedInputs.forEach { (itemId, count) -> player.inventory.add(itemId, count) } + player.filterableMessage("You don't have enough inventory space.") + stop() + return@repeatWhile + } + + // Roll success/fail at combine time — store for fermentation + val success = rollWineSuccess(player, action) + if (success) { + val count = player.attr[WINE_SUCCESS_COUNT] ?: 0 + player.attr[WINE_SUCCESS_COUNT] = count + 1 + } else { + val count = player.attr[WINE_FAIL_COUNT] ?: 0 + player.attr[WINE_FAIL_COUNT] = count + 1 + } + + // Reset fermentation timer (each new wine resets the clock for all pending wines) + player.timers[WINE_FERMENT_TIMER] = WINE_FERMENT_TICKS + + player.filterableMessage("You squeeze the grapes into the jug of water.") + made++ + } + } + + /** + * Registers the timer handler that completes wine fermentation. + * + * When the timer fires, all pending unfermented wines are converted: + * - Successes → jug_of_wine (200 XP each) + * - Failures → jug_of_bad_wine (0 XP) + */ + private fun registerWineFermentationTimer() { + onTimer(WINE_FERMENT_TIMER) { + val p = player as Player + val successes = p.attr[WINE_SUCCESS_COUNT] ?: 0 + val fails = p.attr[WINE_FAIL_COUNT] ?: 0 + + val unfermentedId = runCatching { "items.jug_unfermented_wine".asRSCM() }.getOrNull() ?: return@onTimer + val wineId = runCatching { "items.jug_wine".asRSCM() }.getOrNull() ?: return@onTimer + val badWineId = runCatching { "items.jug_bad_wine".asRSCM() }.getOrNull() ?: return@onTimer + + // Process successes: replace unfermented wines with jug_of_wine + award XP + var successConverted = 0 + repeat(successes) { + if (p.inventory.contains(unfermentedId)) { + p.inventory.remove(unfermentedId, 1) + p.inventory.add(wineId, 1) + p.addXp(Skills.COOKING, 200.0) + successConverted++ + } + } + + // Process failures: replace unfermented wines with jug_of_bad_wine + var failConverted = 0 + repeat(fails) { + if (p.inventory.contains(unfermentedId)) { + p.inventory.remove(unfermentedId, 1) + p.inventory.add(badWineId, 1) + failConverted++ + } + } + + // Clean up attributes + p.attr.remove(WINE_SUCCESS_COUNT) + p.attr.remove(WINE_FAIL_COUNT) + + if (successConverted > 0 || failConverted > 0) { + p.filterableMessage("The wine has fermented.") + } + } + } +} diff --git a/content/src/main/kotlin/org/alter/skills/cooking/events/CookingOutcomes.kt b/content/src/main/kotlin/org/alter/skills/cooking/events/CookingOutcomes.kt new file mode 100644 index 00000000..6aa9e101 --- /dev/null +++ b/content/src/main/kotlin/org/alter/skills/cooking/events/CookingOutcomes.kt @@ -0,0 +1,68 @@ +package org.alter.skills.cooking.events + +import org.alter.skills.cooking.runtime.CookingAction +import org.alter.skills.cooking.runtime.OutcomeKind +import org.alter.skills.cooking.runtime.CookingOutcome +import kotlin.random.Random + +/** + * Outcome selection and resolution for cooking actions. + */ +object CookingOutcomes { + + /** + * Selects the primary outcome based on success/failure. + */ + fun selectOutcome(action: CookingAction, success: Boolean): CookingOutcome { + val outcomes = action.outcomes + val preferredKind = if (success) OutcomeKind.SUCCESS else OutcomeKind.FAIL + val candidates = outcomes.filter { it.kind == preferredKind } + if (candidates.isNotEmpty()) { + return weightedPick(candidates) + } + + // Fallback (misconfigured data): allow ANY non-ALWAYS outcome. + val any = outcomes.filter { it.kind != OutcomeKind.ALWAYS } + if (any.isNotEmpty()) { + return weightedPick(any) + } + + val alwaysOnly = outcomes.filter { it.kind == OutcomeKind.ALWAYS } + require(alwaysOnly.isNotEmpty()) { + "Cooking action has no outcomes for key=${action.key} variant=${action.variant}" + } + return weightedPick(alwaysOnly) + } + + /** + * Resolves all outcomes for an action (ALWAYS outcomes plus the main outcome). + */ + fun resolveOutcomes(action: CookingAction, success: Boolean): List { + val always = action.outcomes.filter { it.kind == OutcomeKind.ALWAYS } + val main = selectOutcome(action, success) + return if (main.kind == OutcomeKind.ALWAYS) always else always + main + } + + /** + * Picks an outcome from candidates based on weights. + */ + fun weightedPick(candidates: List): CookingOutcome { + if (candidates.size == 1) return candidates.first() + val total = candidates.sumOf { it.weight.coerceAtLeast(1) } + var roll = Random.nextInt(total) + for (candidate in candidates) { + roll -= candidate.weight.coerceAtLeast(1) + if (roll < 0) return candidate + } + return candidates.last() + } + + /** + * Rolls the production count for an outcome. + */ + fun rollCount(outcome: CookingOutcome): Int { + val min = outcome.countMin.coerceAtLeast(1) + val max = outcome.countMax.coerceAtLeast(min) + return if (min == max) min else Random.nextInt(min, max + 1) + } +} diff --git a/content/src/main/kotlin/org/alter/skills/cooking/events/CookingUtils.kt b/content/src/main/kotlin/org/alter/skills/cooking/events/CookingUtils.kt new file mode 100644 index 00000000..b182a3c6 --- /dev/null +++ b/content/src/main/kotlin/org/alter/skills/cooking/events/CookingUtils.kt @@ -0,0 +1,286 @@ +package org.alter.skills.cooking.events + +import dev.openrune.ServerCacheManager.getObject +import org.alter.api.EquipmentType +import org.alter.api.Skills +import org.alter.api.computeSkillingSuccess +import org.alter.api.ext.hasEquipped +import org.alter.game.model.entity.GameObject +import org.alter.game.model.entity.Player +import org.alter.skills.cooking.runtime.CookingAction +import org.alter.skills.cooking.runtime.OutcomeKind +import org.alter.skills.cooking.runtime.Trigger +import org.alter.skills.firemaking.ColoredLogs +import org.alter.rscm.RSCM.asRSCM +import kotlin.random.Random + +/** + * Utility functions for cooking events. + */ +object CookingUtils { + + /** + * Types of cooking stations. + */ + enum class CookStation { + FIRE, + RANGE, + /** Hosidius Kitchen range — 5% reduced burn chance. */ + HOSIDIUS_RANGE, + /** Lumbridge Castle range — reduced burn level for certain foods. */ + LUMBRIDGE_RANGE + } + + /** IDs of spit-skewered items that require firemaking level to roast. */ + val spitSkeweredIds: Set = setOf( + "items.spit_skewered_bird_meat", + "items.spit_skewered_beast_meat", + "items.spit_skewered_rabbit_meat", + "items.spit_skewered_chompy" + ).mapNotNull { key -> runCatching { key.asRSCM() }.getOrNull() }.toSet() + + /** Firemaking level required for spit roasting. */ + const val SPIT_ROAST_FIREMAKING_LEVEL: Int = 20 + + private val fireObjectIds: Set by lazy { buildFireObjectIds() } + + /** + * Object IDs for the Hosidius Kitchen range (5% burn reduction). + * In OSRS this is object 21302. + */ + private val hosidiusRangeIds: Set by lazy { + listOfNotNull( + runCatching { "objects.hosidius_range".asRSCM() }.getOrNull() + ).toSet() + } + + /** + * Object IDs for the Lumbridge Castle range (reduced stop-burn for low-level foods). + * In OSRS this is object 114 (post-Cook's Assistant). + */ + private val lumbridgeRangeIds: Set by lazy { + listOfNotNull( + runCatching { "objects.lumbridge_range".asRSCM() }.getOrNull() + ).toSet() + } + + // ------------------------------------------------------- + // Cooking gauntlets: items affected & lowered stop-burn + // ------------------------------------------------------- + + /** + * Items whose stop-burn level is lowered by the Cooking gauntlets. + * Maps raw item RSCM key -> (gauntlet stop-burn fire, gauntlet stop-burn range). + */ + private val gauntletStopBurnOverrides: Map> by lazy { + listOf( + "items.raw_lobster" to (64 to 64), + "items.raw_swordfish" to (81 to 81), + "items.raw_monkfish" to (90 to 87), + "items.raw_shark" to (94 to 94), + "items.raw_anglerfish" to (98 to 93) + ).mapNotNull { (key, stops) -> + val id = runCatching { key.asRSCM() }.getOrNull() ?: return@mapNotNull null + id to stops + }.toMap() + } + + /** Checks whether the player is wearing cooking gauntlets. */ + fun hasCookingGauntlets(player: Player): Boolean = + player.hasEquipped(EquipmentType.GLOVES, "items.cooking_gauntlets") + + /** Checks whether the player is wearing the cooking cape (or max cape). */ + fun hasCookingCape(player: Player): Boolean = + player.equipment.containsAny( + "items.skillcape_cooking", + "items.skillcape_cooking_trimmed", + "items.skillcape_max" + ) + + /** + * Determines the cooking station type for a given game object, or null if it is not a heat source. + */ + fun heatSourceStationFor(gameObject: GameObject): CookStation? { + val id = gameObject.internalID + if (fireObjectIds.contains(id)) return CookStation.FIRE + + // Check for special named ranges first + if (hosidiusRangeIds.contains(id)) return CookStation.HOSIDIUS_RANGE + if (lumbridgeRangeIds.contains(id)) return CookStation.LUMBRIDGE_RANGE + + val def = getObject(id) ?: return null + val hasCookAction = def.actions.any { it?.equals("cook", ignoreCase = true) == true } + return if (hasCookAction) CookStation.RANGE else null + } + + fun isHeatSource(gameObject: GameObject): Boolean = heatSourceStationFor(gameObject) != null + + /** + * Determines the cooking station type for a given game object. + */ + fun stationFor(gameObject: GameObject): CookStation { + return heatSourceStationFor(gameObject) ?: CookStation.RANGE + } + + /** + * Checks if a station type is allowed for the given action. + * Hosidius and Lumbridge ranges count as regular ranges for permission checks. + */ + fun isStationAllowed(action: CookingAction, station: CookStation): Boolean { + val mask = action.row.stationMask + return when (station) { + CookStation.FIRE -> (mask and 1) != 0 + CookStation.RANGE, + CookStation.HOSIDIUS_RANGE, + CookStation.LUMBRIDGE_RANGE -> (mask and 2) != 0 + } + } + + /** + * Checks if the player meets extra requirements (e.g., firemaking for spit roasting). + */ + fun meetsExtraRequirements(player: Player, action: CookingAction): Boolean { + if (isSpitRoastAction(action)) { + val fm = player.getSkills().getCurrentLevel(Skills.FIREMAKING) + return fm >= SPIT_ROAST_FIREMAKING_LEVEL + } + return true + } + + /** + * Checks if this action is a spit-roast action (fire-only, skewered input). + */ + fun isSpitRoastAction(action: CookingAction): Boolean { + if (action.row.trigger != Trigger.HEAT_SOURCE) return false + return action.inputs.any { it.item in spitSkeweredIds } + } + + /** + * Checks if the player has all required inputs for the action. + */ + fun hasInputs(player: Player, action: CookingAction): Boolean { + if (action.inputs.isEmpty()) return false + return action.inputs.all { input -> player.inventory.getItemCount(input.item) >= input.count } + } + + /** + * Calculates the maximum number of items that can be produced. + */ + fun maxProducible(player: Player, action: CookingAction): Int { + if (action.inputs.isEmpty()) return 0 + return action.inputs + .map { input -> player.inventory.getItemCount(input.item) / input.count.coerceAtLeast(1) } + .minOrNull() + ?: 0 + } + + /** + * Rolls to determine if cooking succeeds. + * + * Uses the OSRS `statrandom` (computeSkillingSuccess) approach with per-food + * low/high values. The cooking cape guarantees success. Cooking gauntlets lower + * the stop-burn threshold for affected items. + */ + fun rollCookSuccess( + player: Player, + station: CookStation, + action: CookingAction + ): Boolean { + // Cooking cape / max cape → never burn + if (hasCookingCape(player)) return true + + val cookingLevel = player.getSkills().getCurrentLevel(Skills.COOKING) + + val wearingGauntlets = hasCookingGauntlets(player) + + // For stop-burn lookup, Hosidius/Lumbridge count as RANGE + val baseStation = when (station) { + CookStation.FIRE -> CookStation.FIRE + else -> CookStation.RANGE + } + + // Determine effective stop-burn level + val stopBurn: Int = if (wearingGauntlets) { + val override = gauntletStopBurnOverrides[action.key] + if (override != null) { + when (baseStation) { + CookStation.FIRE -> override.first + else -> override.second + } + } else { + when (baseStation) { + CookStation.FIRE -> action.row.stopBurnFire + else -> action.row.stopBurnRange + } + } + } else { + when (baseStation) { + CookStation.FIRE -> action.row.stopBurnFire + else -> action.row.stopBurnRange + } + }.coerceAtLeast(action.row.level) + + if (cookingLevel >= stopBurn) return true + + // Use computeSkillingSuccess with the level requirement as the base + // low=level requirement scaled, high=stop-burn scaled + val effectiveLevel = cookingLevel.coerceIn(1, 99) + val chance = computeSkillingSuccess( + low = action.row.level, + high = stopBurn, + level = effectiveLevel + ) + + // Hosidius Kitchen range: 5% reduced burn chance (multiply success by 1.05) + val adjustedChance = when (station) { + CookStation.HOSIDIUS_RANGE -> (chance * 1.05).coerceAtMost(1.0) + else -> chance + } + + return Random.nextDouble() < adjustedChance + } + + /** + * Rolls wine fermentation success. Wine has no station; uses fire stop-burn values. + * Cooking cape never burns. Gauntlets have no effect on wine. + */ + fun rollWineSuccess(player: Player, action: CookingAction): Boolean { + if (hasCookingCape(player)) return true + + val cookingLevel = player.getSkills().getCurrentLevel(Skills.COOKING) + val stopBurn = action.row.stopBurnFire.coerceAtLeast(action.row.level) + if (cookingLevel >= stopBurn) return true + + val chance = computeSkillingSuccess( + low = action.row.level, + high = stopBurn, + level = cookingLevel.coerceIn(1, 99) + ) + return Random.nextDouble() < chance + } + + /** + * Checks if the player is still at the cooking station. + */ + fun isStillAtStation( + player: Player, + objectTile: org.alter.game.model.Tile, + objectId: Int + ): Boolean { + if (player.tile.getDistance(objectTile) > 1) return false + + val world = player.world + val obj = world.getObject(objectTile, type = 10) ?: world.getObject(objectTile, type = 11) + return obj != null && obj.internalID == objectId + } + + private fun buildFireObjectIds(): Set { + val fireKeys = ColoredLogs.COLOURED_LOGS.values.map { it.second } + + "objects.fire" + + "objects.forestry_fire" + + return fireKeys.mapNotNull { key -> + runCatching { key.asRSCM() }.getOrNull() + }.toSet() + } +} diff --git a/content/src/main/kotlin/org/alter/skills/cooking/runtime/CookingActionRegistry.kt b/content/src/main/kotlin/org/alter/skills/cooking/runtime/CookingActionRegistry.kt new file mode 100644 index 00000000..1ee5edd3 --- /dev/null +++ b/content/src/main/kotlin/org/alter/skills/cooking/runtime/CookingActionRegistry.kt @@ -0,0 +1,119 @@ +package org.alter.skills.cooking.runtime + +import org.alter.skills.cooking.runtime.OutcomeKind +import org.generated.tables.cooking.CookingActionInputsRow +import org.generated.tables.cooking.CookingActionOutcomesRow +import org.generated.tables.cooking.CookingActionsRow + +/** + * Runtime models for loaded cooking recipe data. + */ + +/** + * An input requirement for a cooking action. + */ +data class CookingInput( + val item: Int, + val count: Int +) + +/** + * A possible outcome of a cooking action. + */ +data class CookingOutcome( + val kind: Int, + val item: Int, + val countMin: Int, + val countMax: Int, + val xp: Int, + val weight: Int +) + +/** + * A complete cooking action with loaded data. + */ +data class CookingAction( + val row: CookingActionsRow, + val inputs: List, + val outcomes: List +) { + val key: Int get() = row.key + val variant: Int get() = row.variant + + /** + * Returns the primary output item (first SUCCESS outcome, else first ALWAYS, else first). + */ + fun primaryOutputItem(): Int { + val success = outcomes.firstOrNull { it.kind == OutcomeKind.SUCCESS } + if (success != null) return success.item + val always = outcomes.firstOrNull { it.kind == OutcomeKind.ALWAYS } + if (always != null) return always.item + return outcomes.firstOrNull()?.item ?: -1 + } +} + +/** + * Registry of all cooking actions loaded from DB tables. + */ +object CookingActionRegistry { + + /** + * All cooking actions loaded from DB tables. + */ + val allActions: List by lazy { + val actions = CookingActionsRow.all() + val inputsByKey = CookingActionInputsRow.all().groupBy { it.key to it.variant } + val outcomesByKey = CookingActionOutcomesRow.all().groupBy { it.key to it.variant } + + actions.map { actionRow -> + val joinKey = actionRow.key to actionRow.variant + val inputs = (inputsByKey[joinKey] ?: emptyList()) + .map { CookingInput(item = it.item, count = it.count.coerceAtLeast(1)) } + val outcomes = (outcomesByKey[joinKey] ?: emptyList()) + .map { + CookingOutcome( + kind = it.kind, + item = it.item, + countMin = it.countMin.coerceAtLeast(1), + countMax = it.countMax.coerceAtLeast(1), + xp = it.xp, + weight = it.weight.coerceAtLeast(1) + ) + } + + CookingAction(row = actionRow, inputs = inputs, outcomes = outcomes) + } + } + + /** + * Actions indexed by their raw item (key). + */ + val byRaw: Map> by lazy { + allActions.groupBy { it.key } + } + + /** + * Actions indexed by their cooked item (primary output). + */ + val byCooked: Map by lazy { + allActions + .mapNotNull { action -> + val cooked = action.primaryOutputItem() + if (cooked <= 0) null else cooked to action + } + .toMap() + } + + /** + * Item-on-item actions indexed by each input item ID. + * For any item involved in an ITEM_ON_ITEM action, returns + * the list of actions that use it as an input. + */ + val itemOnItemByInput: Map> by lazy { + allActions + .filter { it.row.trigger == Trigger.ITEM_ON_ITEM } + .flatMap { action -> action.inputs.map { it.item to action } } + .groupBy({ it.first }, { it.second }) + .mapValues { (_, actions) -> actions.distinct() } + } +} diff --git a/content/src/main/kotlin/org/alter/skills/cooking/runtime/CookingConstants.kt b/content/src/main/kotlin/org/alter/skills/cooking/runtime/CookingConstants.kt new file mode 100644 index 00000000..d2810afb --- /dev/null +++ b/content/src/main/kotlin/org/alter/skills/cooking/runtime/CookingConstants.kt @@ -0,0 +1,23 @@ +package org.alter.skills.cooking.runtime + +/** + * Trigger types determine how a cooking action is initiated. + */ +object Trigger { + /** Action triggered by using item on a heat source (fire/range). */ + const val HEAT_SOURCE = 0 + /** Action triggered by using one item on another in inventory. */ + const val ITEM_ON_ITEM = 1 +} + +/** + * Outcome kinds determine what type of result a cooking action produces. + */ +object OutcomeKind { + /** Successful cooking result. */ + const val SUCCESS = 0 + /** Failed cooking result (burnt). */ + const val FAIL = 1 + /** Always produced regardless of success/failure. */ + const val ALWAYS = 2 +} diff --git a/content/src/main/resources/org/alter/skills/cooking/gamevals.toml b/content/src/main/resources/org/alter/skills/cooking/gamevals.toml index 0d6ca130..8a18fecb 100644 --- a/content/src/main/resources/org/alter/skills/cooking/gamevals.toml +++ b/content/src/main/resources/org/alter/skills/cooking/gamevals.toml @@ -1,5 +1,8 @@ [gamevals.tables] cooking_recipes=1236 +cooking_actions=1237 +cooking_action_inputs=1238 +cooking_action_outcomes=1239 [gamevals.dbrows] cooking_shrimps=982014 @@ -14,3 +17,553 @@ cooking_swordfish=982022 cooking_shark=982023 cooking_beef=982024 cooking_chicken=982025 + +cooking_cod=982026 +cooking_pike=982027 +cooking_tuna=982028 +cooking_bass=982029 +cooking_monkfish=982030 +cooking_sea_turtle=982031 +cooking_anglerfish=982032 +cooking_dark_crab=982033 +cooking_manta_ray=982034 + +cooking_karambwan=982127 +cooking_rainbow_fish=982137 +cooking_cave_eel=982141 + +cooking_slimy_eel=982145 +cooking_rat_meat=982146 +cooking_bear_meat=982147 +cooking_rabbit=982148 +cooking_ugthanki_meat=982149 +cooking_roast_bird_meat=982150 + +cooking_guppy=982169 +cooking_cavefish=982170 +cooking_roast_beast_meat=982171 +cooking_chompy=982172 +cooking_tetra=982173 +cooking_catfish=982174 + +cooking_garden_pie_add_tomato=982098 +cooking_garden_pie_add_onion=982099 +cooking_garden_pie_add_cabbage=982100 +cooking_garden_pie_bake=982101 + +cooking_shrimps_input_0=982035 +cooking_anchovies_input_0=982036 +cooking_sardine_input_0=982037 +cooking_herring_input_0=982038 +cooking_mackerel_input_0=982039 +cooking_trout_input_0=982040 +cooking_salmon_input_0=982041 +cooking_lobster_input_0=982042 +cooking_swordfish_input_0=982043 +cooking_shark_input_0=982044 +cooking_beef_input_0=982045 +cooking_chicken_input_0=982046 +cooking_cod_input_0=982047 +cooking_pike_input_0=982048 +cooking_tuna_input_0=982049 +cooking_bass_input_0=982050 +cooking_monkfish_input_0=982051 +cooking_sea_turtle_input_0=982052 +cooking_anglerfish_input_0=982053 +cooking_dark_crab_input_0=982054 +cooking_manta_ray_input_0=982055 + +cooking_karambwan_input_0=982130 +cooking_rainbow_fish_input_0=982138 +cooking_cave_eel_input_0=982142 + +cooking_slimy_eel_input_0=982151 +cooking_rat_meat_input_0=982152 +cooking_bear_meat_input_0=982153 +cooking_rabbit_input_0=982154 +cooking_ugthanki_meat_input_0=982155 +cooking_roast_bird_meat_input_0=982156 + +cooking_guppy_input_0=982175 +cooking_cavefish_input_0=982176 +cooking_roast_beast_meat_input_0=982177 +cooking_chompy_input_0=982178 +cooking_tetra_input_0=982179 +cooking_catfish_input_0=982180 + +cooking_garden_pie_add_tomato_input_0=982102 +cooking_garden_pie_add_tomato_input_1=982103 +cooking_garden_pie_add_onion_input_0=982104 +cooking_garden_pie_add_onion_input_1=982105 +cooking_garden_pie_add_cabbage_input_0=982106 +cooking_garden_pie_add_cabbage_input_1=982107 +cooking_garden_pie_bake_input_0=982108 + +cooking_shrimps_outcome_success=982056 +cooking_anchovies_outcome_success=982057 +cooking_sardine_outcome_success=982058 +cooking_herring_outcome_success=982059 +cooking_mackerel_outcome_success=982060 +cooking_trout_outcome_success=982061 +cooking_salmon_outcome_success=982062 +cooking_lobster_outcome_success=982063 +cooking_swordfish_outcome_success=982064 +cooking_shark_outcome_success=982065 +cooking_beef_outcome_success=982066 +cooking_chicken_outcome_success=982067 +cooking_cod_outcome_success=982068 +cooking_pike_outcome_success=982069 +cooking_tuna_outcome_success=982070 +cooking_bass_outcome_success=982071 +cooking_monkfish_outcome_success=982072 +cooking_sea_turtle_outcome_success=982073 +cooking_anglerfish_outcome_success=982074 +cooking_dark_crab_outcome_success=982075 +cooking_manta_ray_outcome_success=982076 + +cooking_karambwan_outcome_success=982133 +cooking_rainbow_fish_outcome_success=982139 +cooking_cave_eel_outcome_success=982143 + +cooking_slimy_eel_outcome_success=982157 +cooking_rat_meat_outcome_success=982158 +cooking_bear_meat_outcome_success=982159 +cooking_rabbit_outcome_success=982160 +cooking_ugthanki_meat_outcome_success=982161 +cooking_roast_bird_meat_outcome_success=982162 + +cooking_guppy_outcome_success=982181 +cooking_cavefish_outcome_success=982182 +cooking_roast_beast_meat_outcome_success=982183 +cooking_chompy_outcome_success=982184 +cooking_tetra_outcome_success=982185 +cooking_catfish_outcome_success=982186 + +cooking_garden_pie_add_tomato_outcome_success=982109 +cooking_garden_pie_add_onion_outcome_success=982110 +cooking_garden_pie_add_cabbage_outcome_success=982111 +cooking_garden_pie_bake_outcome_success=982112 + +cooking_shrimps_outcome_fail=982077 +cooking_anchovies_outcome_fail=982078 +cooking_sardine_outcome_fail=982079 +cooking_herring_outcome_fail=982080 +cooking_mackerel_outcome_fail=982081 +cooking_trout_outcome_fail=982082 +cooking_salmon_outcome_fail=982083 +cooking_lobster_outcome_fail=982084 +cooking_swordfish_outcome_fail=982085 +cooking_shark_outcome_fail=982086 +cooking_beef_outcome_fail=982087 +cooking_chicken_outcome_fail=982088 +cooking_cod_outcome_fail=982089 +cooking_pike_outcome_fail=982090 +cooking_tuna_outcome_fail=982091 +cooking_bass_outcome_fail=982092 +cooking_monkfish_outcome_fail=982093 +cooking_sea_turtle_outcome_fail=982094 +cooking_anglerfish_outcome_fail=982095 +cooking_dark_crab_outcome_fail=982096 +cooking_manta_ray_outcome_fail=982097 + +cooking_karambwan_outcome_fail=982136 +cooking_rainbow_fish_outcome_fail=982140 +cooking_cave_eel_outcome_fail=982144 + +cooking_slimy_eel_outcome_fail=982163 +cooking_rat_meat_outcome_fail=982164 +cooking_bear_meat_outcome_fail=982165 +cooking_rabbit_outcome_fail=982166 +cooking_ugthanki_meat_outcome_fail=982167 +cooking_roast_bird_meat_outcome_fail=982168 + +cooking_guppy_outcome_fail=982187 +cooking_cavefish_outcome_fail=982188 +cooking_roast_beast_meat_outcome_fail=982189 +cooking_chompy_outcome_fail=982190 +cooking_tetra_outcome_fail=982191 +cooking_catfish_outcome_fail=982192 + +cooking_garden_pie_bake_outcome_fail=982113 + +cooking_cake_mix=982114 +cooking_cake_bake=982115 + +cooking_cake_mix_input_0=982116 +cooking_cake_mix_input_1=982117 +cooking_cake_mix_input_2=982118 +cooking_cake_mix_input_3=982119 +cooking_cake_bake_input_0=982120 + +cooking_cake_mix_outcome_success=982121 +cooking_cake_bake_outcome_success=982122 + +cooking_cake_bake_outcome_fail=982123 + +cooking_cake_mix_outcome_always_0=982124 +cooking_cake_mix_outcome_always_1=982125 +cooking_cake_bake_outcome_always_0=982126 + +# --- Skewer (spit-roast prep) entries --- +cooking_skewer_bird_meat=-1 +cooking_skewer_beast_meat=-1 +cooking_skewer_bird_meat_input_0=-1 +cooking_skewer_bird_meat_input_1=-1 +cooking_skewer_beast_meat_input_0=-1 +cooking_skewer_beast_meat_input_1=-1 +cooking_skewer_bird_meat_outcome_success=-1 +cooking_skewer_beast_meat_outcome_success=-1 + +# --- Bread --- +cooking_bread=-1 +cooking_pitta_bread=-1 + +cooking_bread_input_0=-1 +cooking_pitta_bread_input_0=-1 + +cooking_bread_outcome_success=-1 +cooking_bread_outcome_fail=-1 +cooking_pitta_bread_outcome_success=-1 +cooking_pitta_bread_outcome_fail=-1 + +# --- Pies --- +cooking_redberry_pie_add_berries=-1 +cooking_redberry_pie_bake=-1 +cooking_redberry_pie_add_berries_input_0=-1 +cooking_redberry_pie_add_berries_input_1=-1 +cooking_redberry_pie_bake_input_0=-1 +cooking_redberry_pie_add_berries_outcome_success=-1 +cooking_redberry_pie_bake_outcome_success=-1 +cooking_redberry_pie_bake_outcome_fail=-1 + +cooking_meat_pie_add_meat=-1 +cooking_meat_pie_bake=-1 +cooking_meat_pie_add_meat_input_0=-1 +cooking_meat_pie_add_meat_input_1=-1 +cooking_meat_pie_bake_input_0=-1 +cooking_meat_pie_add_meat_outcome_success=-1 +cooking_meat_pie_bake_outcome_success=-1 +cooking_meat_pie_bake_outcome_fail=-1 + +cooking_mud_pie_add_compost=-1 +cooking_mud_pie_add_water=-1 +cooking_mud_pie_add_clay=-1 +cooking_mud_pie_bake=-1 +cooking_mud_pie_add_compost_input_0=-1 +cooking_mud_pie_add_compost_input_1=-1 +cooking_mud_pie_add_water_input_0=-1 +cooking_mud_pie_add_water_input_1=-1 +cooking_mud_pie_add_clay_input_0=-1 +cooking_mud_pie_add_clay_input_1=-1 +cooking_mud_pie_bake_input_0=-1 +cooking_mud_pie_add_compost_outcome_success=-1 +cooking_mud_pie_add_water_outcome_success=-1 +cooking_mud_pie_add_water_outcome_always_0=-1 +cooking_mud_pie_add_clay_outcome_success=-1 +cooking_mud_pie_bake_outcome_success=-1 +cooking_mud_pie_bake_outcome_fail=-1 + +cooking_apple_pie_add_apple=-1 +cooking_apple_pie_bake=-1 +cooking_apple_pie_add_apple_input_0=-1 +cooking_apple_pie_add_apple_input_1=-1 +cooking_apple_pie_bake_input_0=-1 +cooking_apple_pie_add_apple_outcome_success=-1 +cooking_apple_pie_bake_outcome_success=-1 +cooking_apple_pie_bake_outcome_fail=-1 + +cooking_fish_pie_add_trout=-1 +cooking_fish_pie_add_cod=-1 +cooking_fish_pie_add_potato=-1 +cooking_fish_pie_bake=-1 +cooking_fish_pie_add_trout_input_0=-1 +cooking_fish_pie_add_trout_input_1=-1 +cooking_fish_pie_add_cod_input_0=-1 +cooking_fish_pie_add_cod_input_1=-1 +cooking_fish_pie_add_potato_input_0=-1 +cooking_fish_pie_add_potato_input_1=-1 +cooking_fish_pie_bake_input_0=-1 +cooking_fish_pie_add_trout_outcome_success=-1 +cooking_fish_pie_add_cod_outcome_success=-1 +cooking_fish_pie_add_potato_outcome_success=-1 +cooking_fish_pie_bake_outcome_success=-1 +cooking_fish_pie_bake_outcome_fail=-1 + +cooking_botanical_pie_add_golovanova=-1 +cooking_botanical_pie_bake=-1 +cooking_botanical_pie_add_golovanova_input_0=-1 +cooking_botanical_pie_add_golovanova_input_1=-1 +cooking_botanical_pie_bake_input_0=-1 +cooking_botanical_pie_add_golovanova_outcome_success=-1 +cooking_botanical_pie_bake_outcome_success=-1 +cooking_botanical_pie_bake_outcome_fail=-1 + +cooking_mushroom_pie_add_sulliuscep=-1 +cooking_mushroom_pie_bake=-1 +cooking_mushroom_pie_add_sulliuscep_input_0=-1 +cooking_mushroom_pie_add_sulliuscep_input_1=-1 +cooking_mushroom_pie_bake_input_0=-1 +cooking_mushroom_pie_add_sulliuscep_outcome_success=-1 +cooking_mushroom_pie_bake_outcome_success=-1 +cooking_mushroom_pie_bake_outcome_fail=-1 + +cooking_admiral_pie_add_salmon=-1 +cooking_admiral_pie_add_tuna=-1 +cooking_admiral_pie_add_potato=-1 +cooking_admiral_pie_bake=-1 +cooking_admiral_pie_add_salmon_input_0=-1 +cooking_admiral_pie_add_salmon_input_1=-1 +cooking_admiral_pie_add_tuna_input_0=-1 +cooking_admiral_pie_add_tuna_input_1=-1 +cooking_admiral_pie_add_potato_input_0=-1 +cooking_admiral_pie_add_potato_input_1=-1 +cooking_admiral_pie_bake_input_0=-1 +cooking_admiral_pie_add_salmon_outcome_success=-1 +cooking_admiral_pie_add_tuna_outcome_success=-1 +cooking_admiral_pie_add_potato_outcome_success=-1 +cooking_admiral_pie_bake_outcome_success=-1 +cooking_admiral_pie_bake_outcome_fail=-1 + +cooking_dragonfruit_pie_add_fruit=-1 +cooking_dragonfruit_pie_bake=-1 +cooking_dragonfruit_pie_add_fruit_input_0=-1 +cooking_dragonfruit_pie_add_fruit_input_1=-1 +cooking_dragonfruit_pie_bake_input_0=-1 +cooking_dragonfruit_pie_add_fruit_outcome_success=-1 +cooking_dragonfruit_pie_bake_outcome_success=-1 +cooking_dragonfruit_pie_bake_outcome_fail=-1 + +cooking_wild_pie_add_bear=-1 +cooking_wild_pie_add_chompy=-1 +cooking_wild_pie_add_rabbit=-1 +cooking_wild_pie_bake=-1 +cooking_wild_pie_add_bear_input_0=-1 +cooking_wild_pie_add_bear_input_1=-1 +cooking_wild_pie_add_chompy_input_0=-1 +cooking_wild_pie_add_chompy_input_1=-1 +cooking_wild_pie_add_rabbit_input_0=-1 +cooking_wild_pie_add_rabbit_input_1=-1 +cooking_wild_pie_bake_input_0=-1 +cooking_wild_pie_add_bear_outcome_success=-1 +cooking_wild_pie_add_chompy_outcome_success=-1 +cooking_wild_pie_add_rabbit_outcome_success=-1 +cooking_wild_pie_bake_outcome_success=-1 +cooking_wild_pie_bake_outcome_fail=-1 + +cooking_summer_pie_add_watermelon=-1 +cooking_summer_pie_add_apple=-1 +cooking_summer_pie_add_strawberry=-1 +cooking_summer_pie_bake=-1 +cooking_summer_pie_add_watermelon_input_0=-1 +cooking_summer_pie_add_watermelon_input_1=-1 +cooking_summer_pie_add_apple_input_0=-1 +cooking_summer_pie_add_apple_input_1=-1 +cooking_summer_pie_add_strawberry_input_0=-1 +cooking_summer_pie_add_strawberry_input_1=-1 +cooking_summer_pie_bake_input_0=-1 +cooking_summer_pie_add_watermelon_outcome_success=-1 +cooking_summer_pie_add_apple_outcome_success=-1 +cooking_summer_pie_add_strawberry_outcome_success=-1 +cooking_summer_pie_bake_outcome_success=-1 +cooking_summer_pie_bake_outcome_fail=-1 + +# --- Pizzas --- +cooking_pizza_add_tomato=-1 +cooking_pizza_add_cheese=-1 +cooking_pizza_bake=-1 +cooking_pizza_add_tomato_input_0=-1 +cooking_pizza_add_tomato_input_1=-1 +cooking_pizza_add_cheese_input_0=-1 +cooking_pizza_add_cheese_input_1=-1 +cooking_pizza_bake_input_0=-1 +cooking_pizza_add_tomato_outcome_success=-1 +cooking_pizza_add_cheese_outcome_success=-1 +cooking_pizza_bake_outcome_success=-1 +cooking_pizza_bake_outcome_fail=-1 + +cooking_pizza_add_meat=-1 +cooking_pizza_add_meat_input_0=-1 +cooking_pizza_add_meat_input_1=-1 +cooking_pizza_add_meat_outcome_success=-1 + +cooking_pizza_add_anchovies=-1 +cooking_pizza_add_anchovies_input_0=-1 +cooking_pizza_add_anchovies_input_1=-1 +cooking_pizza_add_anchovies_outcome_success=-1 + +cooking_pizza_add_pineapple=-1 +cooking_pizza_add_pineapple_input_0=-1 +cooking_pizza_add_pineapple_input_1=-1 +cooking_pizza_add_pineapple_outcome_success=-1 + +# --- Stews --- +cooking_stew_add_potato=-1 +cooking_stew_add_meat=-1 +cooking_stew_cook=-1 +cooking_stew_add_potato_input_0=-1 +cooking_stew_add_potato_input_1=-1 +cooking_stew_add_meat_input_0=-1 +cooking_stew_add_meat_input_1=-1 +cooking_stew_cook_input_0=-1 +cooking_stew_add_potato_outcome_success=-1 +cooking_stew_add_meat_outcome_success=-1 +cooking_stew_cook_outcome_success=-1 +cooking_stew_cook_outcome_fail=-1 + +cooking_curry_add_potato=-1 +cooking_curry_add_meat=-1 +cooking_curry_add_spice=-1 +cooking_curry_cook=-1 +cooking_curry_add_potato_input_0=-1 +cooking_curry_add_potato_input_1=-1 +cooking_curry_add_meat_input_0=-1 +cooking_curry_add_meat_input_1=-1 +cooking_curry_add_spice_input_0=-1 +cooking_curry_add_spice_input_1=-1 +cooking_curry_cook_input_0=-1 +cooking_curry_add_potato_outcome_success=-1 +cooking_curry_add_meat_outcome_success=-1 +cooking_curry_add_spice_outcome_success=-1 +cooking_curry_cook_outcome_success=-1 +cooking_curry_cook_outcome_fail=-1 + +# --- Potatoes --- +cooking_baked_potato=-1 +cooking_baked_potato_input_0=-1 +cooking_baked_potato_outcome_success=-1 +cooking_baked_potato_outcome_fail=-1 + +cooking_potato_add_butter=-1 +cooking_potato_add_butter_input_0=-1 +cooking_potato_add_butter_input_1=-1 +cooking_potato_add_butter_outcome_success=-1 + +cooking_potato_add_cheese=-1 +cooking_potato_add_cheese_input_0=-1 +cooking_potato_add_cheese_input_1=-1 +cooking_potato_add_cheese_outcome_success=-1 + +cooking_potato_add_egg=-1 +cooking_potato_add_egg_input_0=-1 +cooking_potato_add_egg_input_1=-1 +cooking_potato_add_egg_outcome_success=-1 +cooking_potato_add_egg_outcome_always_0=-1 + +cooking_potato_add_mushroom_onion=-1 +cooking_potato_add_mushroom_onion_input_0=-1 +cooking_potato_add_mushroom_onion_input_1=-1 +cooking_potato_add_mushroom_onion_outcome_success=-1 +cooking_potato_add_mushroom_onion_outcome_always_0=-1 + +cooking_potato_add_tuna_corn=-1 +cooking_potato_add_tuna_corn_input_0=-1 +cooking_potato_add_tuna_corn_input_1=-1 +cooking_potato_add_tuna_corn_outcome_success=-1 +cooking_potato_add_tuna_corn_outcome_always_0=-1 + +# --- Misc foods --- +cooking_sweetcorn=-1 +cooking_sweetcorn_input_0=-1 +cooking_sweetcorn_outcome_success=-1 +cooking_sweetcorn_outcome_fail=-1 + +cooking_scrambled_egg_mix=-1 +cooking_scrambled_egg_cook=-1 +cooking_scrambled_egg_mix_input_0=-1 +cooking_scrambled_egg_mix_input_1=-1 +cooking_scrambled_egg_cook_input_0=-1 +cooking_scrambled_egg_mix_outcome_success=-1 +cooking_scrambled_egg_cook_outcome_success=-1 +cooking_scrambled_egg_cook_outcome_fail=-1 + +cooking_fried_onions=-1 +cooking_fried_onions_input_0=-1 +cooking_fried_onions_outcome_success=-1 +cooking_fried_onions_outcome_fail=-1 + +cooking_fried_mushrooms=-1 +cooking_fried_mushrooms_input_0=-1 +cooking_fried_mushrooms_outcome_success=-1 +cooking_fried_mushrooms_outcome_fail=-1 + +cooking_mushroom_onion_combine=-1 +cooking_mushroom_onion_combine_input_0=-1 +cooking_mushroom_onion_combine_input_1=-1 +cooking_mushroom_onion_combine_outcome_success=-1 +cooking_mushroom_onion_combine_outcome_always_0=-1 + +cooking_tuna_corn_combine=-1 +cooking_tuna_corn_combine_input_0=-1 +cooking_tuna_corn_combine_input_1=-1 +cooking_tuna_corn_combine_input_2=-1 +cooking_tuna_corn_combine_outcome_success=-1 + +cooking_chocolate_cake=-1 +cooking_chocolate_cake_input_0=-1 +cooking_chocolate_cake_input_1=-1 +cooking_chocolate_cake_outcome_success=-1 + +# --- Wine --- +cooking_wine=-1 +cooking_wine_input_0=-1 +cooking_wine_input_1=-1 +cooking_wine_outcome_success=-1 +cooking_wine_outcome_fail=-1 + +# --- Snails --- +cooking_thin_snail=-1 +cooking_thin_snail_input_0=-1 +cooking_thin_snail_outcome_success=-1 +cooking_thin_snail_outcome_fail=-1 + +cooking_lean_snail=-1 +cooking_lean_snail_input_0=-1 +cooking_lean_snail_outcome_success=-1 +cooking_lean_snail_outcome_fail=-1 + +cooking_fat_snail=-1 +cooking_fat_snail_input_0=-1 +cooking_fat_snail_outcome_success=-1 +cooking_fat_snail_outcome_fail=-1 + +# --- Spit-Roast Rabbit --- +cooking_skewer_rabbit_meat=-1 +cooking_skewer_rabbit_meat_input_0=-1 +cooking_skewer_rabbit_meat_input_1=-1 +cooking_skewer_rabbit_meat_outcome_success=-1 + +cooking_roast_rabbit_meat=-1 +cooking_roast_rabbit_meat_input_0=-1 +cooking_roast_rabbit_meat_outcome_success=-1 +cooking_roast_rabbit_meat_outcome_fail=-1 + +# --- Hunter Meats (Pitfall Trapping) --- +cooking_larupia=-1 +cooking_larupia_input_0=-1 +cooking_larupia_outcome_success=-1 +cooking_larupia_outcome_fail=-1 + +cooking_graahk=-1 +cooking_graahk_input_0=-1 +cooking_graahk_outcome_success=-1 +cooking_graahk_outcome_fail=-1 + +cooking_kyatt=-1 +cooking_kyatt_input_0=-1 +cooking_kyatt_outcome_success=-1 +cooking_kyatt_outcome_fail=-1 + +cooking_pyre_fox=-1 +cooking_pyre_fox_input_0=-1 +cooking_pyre_fox_outcome_success=-1 +cooking_pyre_fox_outcome_fail=-1 + +cooking_sunlight_antelope=-1 +cooking_sunlight_antelope_input_0=-1 +cooking_sunlight_antelope_outcome_success=-1 +cooking_sunlight_antelope_outcome_fail=-1 + +cooking_moonlight_antelope=-1 +cooking_moonlight_antelope_input_0=-1 +cooking_moonlight_antelope_outcome_success=-1 +cooking_moonlight_antelope_outcome_fail=-1 From 1395c6bfb2d6ceb016963b88175653fe19e2b427 Mon Sep 17 00:00:00 2001 From: voidstarr <3334013+voidstarr@users.noreply.github.com> Date: Tue, 10 Feb 2026 15:01:58 -0800 Subject: [PATCH 07/10] fix: resolve cooking skill failing silently after starting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix RSCM key 'items.cooking_gauntlets' → 'items.gauntlets_of_cooking' in hasCookingGauntlets(), which caused rollCookSuccess() to throw, silently killing the cook queue task with no in-game feedback - Wrap hasCookingGauntlets() and hasCookingCape() in runCatching for defensive safety against future RSCM key issues - Fix 39 invalid RSCM keys across 7 recipe files (BreadRecipes, FishRecipes, MiscFoodRecipes, PieRecipes, PizzaRecipes, PotatoRecipes, StewRecipes) - Replace 307 placeholder -1 values in gamevals.toml with sequential IDs - Fix MESSAGE_GAME overflow in cooktest command (auto-split at 250 chars) - Split large cooktest presets to fit 28-slot inventory limit --- .../main/dev/openrune/ServerCacheManager.kt | 140 + .../dev/openrune/codec/osrs/CodecsOsrs.kt | 12 + .../codec/osrs/impl/HealthBarServerCodec.kt | 27 + .../codec/osrs/impl/InventoryServerCodec.kt | 51 + .../codec/osrs/impl/ItemServerCodec.kt | 219 + .../codec/osrs/impl/NpcServerCodec.kt | 94 + .../codec/osrs/impl/ObjectServerCodec.kt | 82 + .../codec/osrs/impl/SequenceServerCodec.kt | 28 + .../dev/openrune/tools/MinifyServerCache.kt | 60 + .../openrune/tools/PackServerConfigOSRS.kt | 245 + .../dev/openrune/types/HealthBarServerType.kt | 13 + .../dev/openrune/types/InventoryServerType.kt | 98 + .../main/dev/openrune/types/ItemServerType.kt | 128 + .../main/dev/openrune/types/NpcServerType.kt | 44 + .../dev/openrune/types/ObjectServerType.kt | 31 + .../dev/openrune/types/SequenceServerType.kt | 8 + cache/bin/main/dev/openrune/util/Coords.kt | 3 + .../main/dev/openrune/util/TextAlignment.kt | 204 + cache/bin/main/logback.xml | 20 + cache/bin/main/org/alter/BufferReader.kt | 174 + cache/bin/main/org/alter/CacheTools.kt | 206 + cache/bin/main/org/alter/ParamMapper.kt | 170 + .../main/org/alter/codegen/TableGenerater.kt | 377 + .../bin/main/org/alter/game/util/DbHelper.kt | 269 + .../main/org/alter/game/util/EnumManager.kt | 150 + .../game/util/vars/GenericStringVarType.kt | 19 + .../game/util/vars/NumericBooleanVarType.kt | 24 + .../game/util/vars/NumericIntegerVarType.kt | 21 + .../game/util/vars/NumericLongVarType.kt | 21 + .../org/alter/game/util/vars/VarTypeImpl.kt | 15 + .../main/org/alter/game/util/vars/VarTypes.kt | 32 + .../org/alter/gamevals/GameValAutoAssigner.kt | 143 + .../org/alter/gamevals/GameValProvider.kt | 188 + .../main/org/alter/gamevals/GamevalDumper.kt | 92 + .../bin/main/org/alter/impl/GameframeTable.kt | 69 + .../bin/main/org/alter/impl/StatComponents.kt | 60 + .../bin/main/org/alter/impl/misc/FoodTable.kt | 522 + .../bin/main/org/alter/impl/misc/TeleTabs.kt | 199 + .../main/org/alter/impl/skills/Firemaking.kt | 163 + .../main/org/alter/impl/skills/Herblore.kt | 855 + .../bin/main/org/alter/impl/skills/Mining.kt | 503 + .../main/org/alter/impl/skills/PrayerTable.kt | 230 + .../main/org/alter/impl/skills/Smithing.kt | 465 + .../main/org/alter/impl/skills/Woodcutting.kt | 307 + .../impl/skills/cooking/CookingConstants.kt | 41 + .../impl/skills/cooking/CookingHelpers.kt | 216 + .../impl/skills/cooking/CookingModels.kt | 106 + .../skills/cooking/CookingRecipeRegistry.kt | 36 + .../impl/skills/cooking/CookingTables.kt | 110 + .../cooking/recipes/BakedGoodsRecipes.kt | 93 + .../skills/cooking/recipes/BreadRecipes.kt | 36 + .../skills/cooking/recipes/FishRecipes.kt | 278 + .../skills/cooking/recipes/MeatRecipes.kt | 200 + .../skills/cooking/recipes/MiscFoodRecipes.kt | 141 + .../impl/skills/cooking/recipes/PieRecipes.kt | 398 + .../skills/cooking/recipes/PizzaRecipes.kt | 107 + .../skills/cooking/recipes/PotatoRecipes.kt | 121 + .../skills/cooking/recipes/StewRecipes.kt | 89 + .../skills/cooking/recipes/WineRecipes.kt | 55 + .../alter/impl/skills/runecrafting/Alters.kt | 262 + .../skills/runecrafting/CombinationRune.kt | 58 + .../impl/skills/runecrafting/RunecraftRune.kt | 167 + .../alter/impl/skills/runecrafting/Tiara.kt | 91 + cache/bin/main/org/alter/rscm/RSCM.kt | 62 + .../skills/cooking/recipes/BreadRecipes.kt | 2 +- .../skills/cooking/recipes/FishRecipes.kt | 2 +- .../skills/cooking/recipes/MiscFoodRecipes.kt | 26 +- .../impl/skills/cooking/recipes/PieRecipes.kt | 82 +- .../skills/cooking/recipes/PizzaRecipes.kt | 4 +- .../skills/cooking/recipes/PotatoRecipes.kt | 20 +- .../skills/cooking/recipes/StewRecipes.kt | 10 +- .../developer/CookingTestCommandsPlugin.kt | 117 +- .../skills/cooking/events/CookingEvents.kt | 4 +- .../skills/cooking/events/CookingUtils.kt | 14 +- .../org/alter/skills/cooking/gamevals.toml | 674 +- util/bin/main/gg/rsmod/util/AabbUtil.kt | 124 + .../bin/main/gg/rsmod/util/BitManipulation.kt | 32 + util/bin/main/gg/rsmod/util/DataConstants.kt | 28 + .../main/gg/rsmod/util/ExtensionFunctions.kt | 103 + util/bin/main/gg/rsmod/util/Misc.kt | 41 + util/bin/main/gg/rsmod/util/Namer.kt | 83 + util/bin/main/gg/rsmod/util/RscmRemapper.kt | 84 + .../main/gg/rsmod/util/ServerProperties.kt | 73 + util/bin/main/gg/rsmod/util/Stopwatch.kt | 221 + .../gg/rsmod/util/concurrency/PhasedTask.kt | 21 + .../util/concurrency/ThreadFactoryBuilder.kt | 181 + util/bin/main/gg/rsmod/util/io/BufferUtils.kt | 88 + wikidata/burn_level.wikisrc | 1269 ++ wikidata/burnt_food.wikisrc | 303 + wikidata/cooking.wikisrc | 788 + wikidata/meat-fish.md | 82 + wikidata/skill_chances.json | 18850 ++++++++++++++++ 92 files changed, 32299 insertions(+), 475 deletions(-) create mode 100644 cache/bin/main/dev/openrune/ServerCacheManager.kt create mode 100644 cache/bin/main/dev/openrune/codec/osrs/CodecsOsrs.kt create mode 100644 cache/bin/main/dev/openrune/codec/osrs/impl/HealthBarServerCodec.kt create mode 100644 cache/bin/main/dev/openrune/codec/osrs/impl/InventoryServerCodec.kt create mode 100644 cache/bin/main/dev/openrune/codec/osrs/impl/ItemServerCodec.kt create mode 100644 cache/bin/main/dev/openrune/codec/osrs/impl/NpcServerCodec.kt create mode 100644 cache/bin/main/dev/openrune/codec/osrs/impl/ObjectServerCodec.kt create mode 100644 cache/bin/main/dev/openrune/codec/osrs/impl/SequenceServerCodec.kt create mode 100644 cache/bin/main/dev/openrune/tools/MinifyServerCache.kt create mode 100644 cache/bin/main/dev/openrune/tools/PackServerConfigOSRS.kt create mode 100644 cache/bin/main/dev/openrune/types/HealthBarServerType.kt create mode 100644 cache/bin/main/dev/openrune/types/InventoryServerType.kt create mode 100644 cache/bin/main/dev/openrune/types/ItemServerType.kt create mode 100644 cache/bin/main/dev/openrune/types/NpcServerType.kt create mode 100644 cache/bin/main/dev/openrune/types/ObjectServerType.kt create mode 100644 cache/bin/main/dev/openrune/types/SequenceServerType.kt create mode 100644 cache/bin/main/dev/openrune/util/Coords.kt create mode 100644 cache/bin/main/dev/openrune/util/TextAlignment.kt create mode 100644 cache/bin/main/logback.xml create mode 100644 cache/bin/main/org/alter/BufferReader.kt create mode 100644 cache/bin/main/org/alter/CacheTools.kt create mode 100644 cache/bin/main/org/alter/ParamMapper.kt create mode 100644 cache/bin/main/org/alter/codegen/TableGenerater.kt create mode 100644 cache/bin/main/org/alter/game/util/DbHelper.kt create mode 100644 cache/bin/main/org/alter/game/util/EnumManager.kt create mode 100644 cache/bin/main/org/alter/game/util/vars/GenericStringVarType.kt create mode 100644 cache/bin/main/org/alter/game/util/vars/NumericBooleanVarType.kt create mode 100644 cache/bin/main/org/alter/game/util/vars/NumericIntegerVarType.kt create mode 100644 cache/bin/main/org/alter/game/util/vars/NumericLongVarType.kt create mode 100644 cache/bin/main/org/alter/game/util/vars/VarTypeImpl.kt create mode 100644 cache/bin/main/org/alter/game/util/vars/VarTypes.kt create mode 100644 cache/bin/main/org/alter/gamevals/GameValAutoAssigner.kt create mode 100644 cache/bin/main/org/alter/gamevals/GameValProvider.kt create mode 100644 cache/bin/main/org/alter/gamevals/GamevalDumper.kt create mode 100644 cache/bin/main/org/alter/impl/GameframeTable.kt create mode 100644 cache/bin/main/org/alter/impl/StatComponents.kt create mode 100644 cache/bin/main/org/alter/impl/misc/FoodTable.kt create mode 100644 cache/bin/main/org/alter/impl/misc/TeleTabs.kt create mode 100644 cache/bin/main/org/alter/impl/skills/Firemaking.kt create mode 100644 cache/bin/main/org/alter/impl/skills/Herblore.kt create mode 100644 cache/bin/main/org/alter/impl/skills/Mining.kt create mode 100644 cache/bin/main/org/alter/impl/skills/PrayerTable.kt create mode 100644 cache/bin/main/org/alter/impl/skills/Smithing.kt create mode 100644 cache/bin/main/org/alter/impl/skills/Woodcutting.kt create mode 100644 cache/bin/main/org/alter/impl/skills/cooking/CookingConstants.kt create mode 100644 cache/bin/main/org/alter/impl/skills/cooking/CookingHelpers.kt create mode 100644 cache/bin/main/org/alter/impl/skills/cooking/CookingModels.kt create mode 100644 cache/bin/main/org/alter/impl/skills/cooking/CookingRecipeRegistry.kt create mode 100644 cache/bin/main/org/alter/impl/skills/cooking/CookingTables.kt create mode 100644 cache/bin/main/org/alter/impl/skills/cooking/recipes/BakedGoodsRecipes.kt create mode 100644 cache/bin/main/org/alter/impl/skills/cooking/recipes/BreadRecipes.kt create mode 100644 cache/bin/main/org/alter/impl/skills/cooking/recipes/FishRecipes.kt create mode 100644 cache/bin/main/org/alter/impl/skills/cooking/recipes/MeatRecipes.kt create mode 100644 cache/bin/main/org/alter/impl/skills/cooking/recipes/MiscFoodRecipes.kt create mode 100644 cache/bin/main/org/alter/impl/skills/cooking/recipes/PieRecipes.kt create mode 100644 cache/bin/main/org/alter/impl/skills/cooking/recipes/PizzaRecipes.kt create mode 100644 cache/bin/main/org/alter/impl/skills/cooking/recipes/PotatoRecipes.kt create mode 100644 cache/bin/main/org/alter/impl/skills/cooking/recipes/StewRecipes.kt create mode 100644 cache/bin/main/org/alter/impl/skills/cooking/recipes/WineRecipes.kt create mode 100644 cache/bin/main/org/alter/impl/skills/runecrafting/Alters.kt create mode 100644 cache/bin/main/org/alter/impl/skills/runecrafting/CombinationRune.kt create mode 100644 cache/bin/main/org/alter/impl/skills/runecrafting/RunecraftRune.kt create mode 100644 cache/bin/main/org/alter/impl/skills/runecrafting/Tiara.kt create mode 100644 cache/bin/main/org/alter/rscm/RSCM.kt create mode 100644 util/bin/main/gg/rsmod/util/AabbUtil.kt create mode 100644 util/bin/main/gg/rsmod/util/BitManipulation.kt create mode 100644 util/bin/main/gg/rsmod/util/DataConstants.kt create mode 100644 util/bin/main/gg/rsmod/util/ExtensionFunctions.kt create mode 100644 util/bin/main/gg/rsmod/util/Misc.kt create mode 100644 util/bin/main/gg/rsmod/util/Namer.kt create mode 100644 util/bin/main/gg/rsmod/util/RscmRemapper.kt create mode 100644 util/bin/main/gg/rsmod/util/ServerProperties.kt create mode 100644 util/bin/main/gg/rsmod/util/Stopwatch.kt create mode 100644 util/bin/main/gg/rsmod/util/concurrency/PhasedTask.kt create mode 100644 util/bin/main/gg/rsmod/util/concurrency/ThreadFactoryBuilder.kt create mode 100644 util/bin/main/gg/rsmod/util/io/BufferUtils.kt create mode 100644 wikidata/burn_level.wikisrc create mode 100644 wikidata/burnt_food.wikisrc create mode 100644 wikidata/cooking.wikisrc create mode 100644 wikidata/meat-fish.md create mode 100644 wikidata/skill_chances.json diff --git a/cache/bin/main/dev/openrune/ServerCacheManager.kt b/cache/bin/main/dev/openrune/ServerCacheManager.kt new file mode 100644 index 00000000..f3ffdb9a --- /dev/null +++ b/cache/bin/main/dev/openrune/ServerCacheManager.kt @@ -0,0 +1,140 @@ +package dev.openrune + +import dev.openrune.OsrsCacheProvider.* +import dev.openrune.cache.CacheManager +import dev.openrune.cache.filestore.definition.ComponentDecoder +import dev.openrune.cache.filestore.definition.FontDecoder +import dev.openrune.cache.filestore.definition.InterfaceType +import dev.openrune.filesystem.Cache +import java.nio.BufferUnderflowException +import dev.openrune.cache.getOrDefault +import dev.openrune.definition.type.* +import dev.openrune.codec.osrs.ItemDecoder +import dev.openrune.codec.osrs.ObjectDecoder +import dev.openrune.codec.osrs.HealthBarDecoder +import dev.openrune.codec.osrs.InventoryDecoder +import dev.openrune.codec.osrs.NpcDecoder +import dev.openrune.codec.osrs.SequenceDecoder +import dev.openrune.codec.osrs.impl.InventoryServerCodec +import dev.openrune.definition.type.widget.ComponentType +import dev.openrune.server.impl.item.ItemRenderDataManager +import dev.openrune.types.* +import io.github.oshai.kotlinlogging.KotlinLogging +import org.alter.rscm.RSCM.asRSCM +import java.nio.file.Path + +object ServerCacheManager { + + private val items: MutableMap = mutableMapOf() + private val npcs: MutableMap = mutableMapOf() + private val objects: MutableMap = mutableMapOf() + private val healthBars: MutableMap = mutableMapOf() + private val structs: MutableMap = mutableMapOf() + private val dbrows: MutableMap = mutableMapOf() + private val dbtables: MutableMap = mutableMapOf() + private val enums: MutableMap = mutableMapOf() + private val varbits: MutableMap = mutableMapOf() + private val varps: MutableMap = mutableMapOf() + private val sequences = mutableMapOf() + private var fonts = mutableMapOf() + private var interfaces = mutableMapOf() + private var inv = mutableMapOf() + + val logger = KotlinLogging.logger {} + + fun init(cachePath : Path, rev : Int) { + val cache = Cache.load(cachePath) + init(cache,rev) + } + + fun init(cache : Cache, rev : Int) { + ItemRenderDataManager.init() + CacheManager.init(OsrsCacheProvider(cache,rev)) + + fonts = FontDecoder(cache).loadAllFonts() + + try { + EnumDecoder().load(cache, enums) + ObjectDecoder().load(cache, objects) + HealthBarDecoder().load(cache, healthBars) + NpcDecoder().load(cache, npcs) + ItemDecoder().load(cache, items) + InventoryDecoder().load(cache,inv) + SequenceDecoder().load(cache,sequences) + VarBitDecoder().load(cache, varbits) + VarDecoder().load(cache, varps) + StructDecoder().load(cache, structs) + DBRowDecoder().load(cache, dbrows) + DBTableDecoder().load(cache, dbtables) + ComponentDecoder(cache).load(interfaces) + } catch (e: BufferUnderflowException) { + logger.error(e) { "Error reading definitions" } + throw e + } + } + + fun getNpc(id: Int) = npcs[id] + fun getFont(id: Int) = fonts[id] + fun getObject(id: Int) = objects[id] + fun getItem(id: Int) = items[id] + fun getVarbit(id: Int) = varbits[id] + fun getVarp(id: Int) = varps[id] + fun getAnim(id: Int) = sequences[id] + fun getEnum(id: Int) = enums[id] + fun getHealthBar(id: Int) = healthBars[id] + fun getStruct(id: Int) = structs[id] + fun getDbrow(id: Int) = dbrows[id] + fun getDbtable(id: Int) = dbtables[id] + fun getInventory(id: Int) = inv[id] + + fun getNpcOrDefault(id: Int) = getOrDefault(npcs, id, NpcServerType(), "Npc") + fun getObjectOrDefault(id: Int) = getOrDefault(objects, id, ObjectServerType(), "Object") + + fun getItemOrDefault(id: Int) = getOrDefault(items, id, ItemServerType(), "Item") + fun getVarbitOrDefault(id: Int) = getOrDefault(varbits, id, VarBitType(), "Varbit") + fun getVarpOrDefault(id: Int) = getOrDefault(varps, id, VarpType(), "Varp") + fun getEnumOrDefault(id: Int) = getOrDefault(enums, id, EnumType(), "Enum") + fun getHealthBarOrDefault(id: Int) = getOrDefault(healthBars, id, HealthBarServerType(), "HealthBar") + fun getStructOrDefault(id: Int) = getOrDefault(structs, id, StructType(), "Struct") + fun getDbrowOrDefault(id: Int) = getOrDefault(dbrows, id, DBRowType(), "DBRow") + fun getDbtableOrDefault(id: Int) = getOrDefault(dbtables, id, DBTableType(), "DBTable") + + // Size methods + fun npcSize() = npcs.size + fun objectSize() = objects.size + fun itemSize() = items.size + fun varbitSize() = varbits.size + fun varpSize() = varps.size + fun enumSize() = enums.size + fun healthBarSize() = healthBars.size + fun structSize() = structs.size + fun animSize() = sequences.size + + // Bulk getters + fun getNpcs() = npcs.toMap() + fun getObjects() = objects.toMap() + fun getItems() = items.toMap() + fun getVarbits() = varbits.toMap() + fun getVarps() = varps.toMap() + fun getEnums() = enums.toMap() + fun getHealthBars() = healthBars.toMap() + fun getStructs() = structs.toMap() + fun getAnims() = sequences.toMap() + fun getRows() = dbrows.toMap() + + fun fromInterface(id: Int): InterfaceType = + interfaces[id] ?: error("Interface $id not found") + + fun fromInterface(id: String): InterfaceType = + fromInterface(id.asRSCM()) + + fun fromComponent(packed: Int): ComponentType { + val interfaceId = packed ushr 16 + val childId = packed and 0xFFFF + return fromInterface(interfaceId).components[childId] + ?: error("Component $childId not found in interface $interfaceId") + } + + fun fromComponent(id: String) = fromComponent(id.asRSCM()) + +} diff --git a/cache/bin/main/dev/openrune/codec/osrs/CodecsOsrs.kt b/cache/bin/main/dev/openrune/codec/osrs/CodecsOsrs.kt new file mode 100644 index 00000000..570bf7d2 --- /dev/null +++ b/cache/bin/main/dev/openrune/codec/osrs/CodecsOsrs.kt @@ -0,0 +1,12 @@ +package dev.openrune.codec.osrs + +import dev.openrune.cache.filestore.definition.ConfigDefinitionDecoder +import dev.openrune.codec.osrs.impl.* +import dev.openrune.types.* + +class ObjectDecoder : ConfigDefinitionDecoder(ObjectServerCodec(), 55) +class HealthBarDecoder : ConfigDefinitionDecoder(HealthBarServerCodec(), 56) +class SequenceDecoder : ConfigDefinitionDecoder(SequenceServerCodec(), 57) +class NpcDecoder : ConfigDefinitionDecoder(NpcServerCodec(), 58) +class ItemDecoder : ConfigDefinitionDecoder(ItemServerCodec(), 59) +class InventoryDecoder : ConfigDefinitionDecoder(InventoryServerCodec(), 60) diff --git a/cache/bin/main/dev/openrune/codec/osrs/impl/HealthBarServerCodec.kt b/cache/bin/main/dev/openrune/codec/osrs/impl/HealthBarServerCodec.kt new file mode 100644 index 00000000..0c2cf552 --- /dev/null +++ b/cache/bin/main/dev/openrune/codec/osrs/impl/HealthBarServerCodec.kt @@ -0,0 +1,27 @@ +package dev.openrune.codec.osrs.impl + +import dev.openrune.definition.opcode.DefinitionOpcode +import dev.openrune.definition.opcode.OpcodeDefinitionCodec +import dev.openrune.definition.opcode.OpcodeList +import dev.openrune.definition.opcode.OpcodeType +import dev.openrune.definition.type.HealthBarType +import dev.openrune.types.HealthBarServerType + + +class HealthBarServerCodec(val health: Map? = null) : OpcodeDefinitionCodec() { + + override val definitionCodec = OpcodeList().apply { + add(DefinitionOpcode(1, OpcodeType.BYTE, HealthBarServerType::width)) + } + + override fun HealthBarServerType.createData() { + if (health == null) return + + val health = health[id]?: return + + width = health.width + } + + override fun createDefinition(): HealthBarServerType = HealthBarServerType() + +} diff --git a/cache/bin/main/dev/openrune/codec/osrs/impl/InventoryServerCodec.kt b/cache/bin/main/dev/openrune/codec/osrs/impl/InventoryServerCodec.kt new file mode 100644 index 00000000..ee52e8a5 --- /dev/null +++ b/cache/bin/main/dev/openrune/codec/osrs/impl/InventoryServerCodec.kt @@ -0,0 +1,51 @@ +package dev.openrune.codec.osrs.impl + +import dev.openrune.definition.opcode.DefinitionOpcode +import dev.openrune.definition.opcode.OpcodeDefinitionCodec +import dev.openrune.definition.opcode.OpcodeList +import dev.openrune.definition.opcode.OpcodeType +import dev.openrune.definition.opcode.OpcodeType.BOOLEAN.enumType +import dev.openrune.definition.opcode.propertyChain +import dev.openrune.definition.type.InventoryType +import dev.openrune.server.impl.item.WeaponTypes +import dev.openrune.types.HealthBarServerType +import dev.openrune.types.InvScope +import dev.openrune.types.InvStackType +import dev.openrune.types.InvStock +import dev.openrune.types.InventoryServerType +import dev.openrune.types.InventoryServerType.Companion.pack +import dev.openrune.types.ItemServerType +import dev.openrune.types.Weapon + + +class InventoryServerCodec( + val types: Map? = null, + val custom : Map? = emptyMap() + +) : OpcodeDefinitionCodec() { + + override val definitionCodec = OpcodeList().apply { + add(DefinitionOpcode(1, OpcodeType.USHORT, InventoryServerType::size)) + add(DefinitionOpcode(2, OpcodeType.USHORT, InventoryServerType::flags)) + add(DefinitionOpcode(3, enumType(), InventoryServerType::stack)) + add(DefinitionOpcode(4, enumType(), InventoryServerType::scope)) + } + + override fun InventoryServerType.createData() { + if (types == null) return + val inventoryType = types[id]?: return + size = inventoryType.size + val customData = custom!![id] + + if (customData != null) { + scope = customData.scope + stack = customData.stack + flags = customData.flags + } + + } + + + override fun createDefinition(): InventoryServerType = InventoryServerType() + +} diff --git a/cache/bin/main/dev/openrune/codec/osrs/impl/ItemServerCodec.kt b/cache/bin/main/dev/openrune/codec/osrs/impl/ItemServerCodec.kt new file mode 100644 index 00000000..deb23b4d --- /dev/null +++ b/cache/bin/main/dev/openrune/codec/osrs/impl/ItemServerCodec.kt @@ -0,0 +1,219 @@ +package dev.openrune.codec.osrs.impl + +import dev.openrune.cache.util.ItemParam +import dev.openrune.definition.* +import dev.openrune.definition.opcode.* +import dev.openrune.definition.type.EnumType +import dev.openrune.definition.type.ItemType +import dev.openrune.definition.opcode.OpcodeType.BOOLEAN.enumType +import dev.openrune.definition.opcode.impl.DefinitionOpcodeListActions +import dev.openrune.definition.opcode.impl.DefinitionOpcodeMap +import dev.openrune.definition.opcode.impl.DefinitionOpcodeParams +import dev.openrune.server.impl.item.ItemRenderDataManager +import dev.openrune.server.impl.item.WeaponTypes +import dev.openrune.server.infobox.InfoBoxItem +import dev.openrune.types.Equipment +import dev.openrune.types.ItemServerType +import dev.openrune.types.Weapon +import kotlin.reflect.KMutableProperty1 +import dev.openrune.types.EquipmentStats +import dev.openrune.types.getInt + +class ItemServerCodec( + val items: Map? = null, + val enums : Map?= null, + val osrs : Map? = null, + val custom : Map? = emptyMap() + +) : OpcodeDefinitionCodec() { + + override val definitionCodec = OpcodeList().apply { + add(DefinitionOpcode(2, OpcodeType.INT, ItemServerType::cost)) + add(DefinitionOpcode(4, OpcodeType.STRING, ItemServerType::name)) + add(DefinitionOpcode(7, OpcodeType.DOUBLE, ItemServerType::weight)) + add(DefinitionOpcode(8, OpcodeType.BOOLEAN, ItemServerType::isTradeable)) + add(DefinitionOpcode(9, OpcodeType.INT, ItemServerType::category)) + add(DefinitionOpcodeListActions(10, OpcodeType.STRING, ItemServerType::options, 5)) + add(DefinitionOpcodeListActions(11, OpcodeType.STRING, ItemServerType::interfaceOptions, 5)) + add(DefinitionOpcode(12, OpcodeType.INT, ItemServerType::noteLinkId)) + add(DefinitionOpcode(13, OpcodeType.INT, ItemServerType::noteTemplateId)) + add(DefinitionOpcode(14, OpcodeType.INT, ItemServerType::placeholderLink)) + add(DefinitionOpcode(15, OpcodeType.INT, ItemServerType::placeholderTemplate)) + add(DefinitionOpcode(16, OpcodeType.INT, ItemServerType::stacks)) + add(DefinitionOpcode(18, OpcodeType.INT, ItemServerType::appearanceOverride1)) + add(DefinitionOpcode(19, OpcodeType.INT, ItemServerType::appearanceOverride2)) + add(DefinitionOpcodeParams(20, ItemServerType::params)) + + add(DefinitionOpcode(21, OpcodeType.BYTE, propertyChain( + ItemServerType::equipment, + Equipment::equipSlot + ))) + + add(DefinitionOpcode(22, OpcodeType.SHORT, propertyChain( + ItemServerType::weapon, + Weapon::specAmount + ))) + + add(DefinitionOpcode(23, OpcodeType.BYTE, propertyChain( + ItemServerType::weapon, + Weapon::attackRange))) + + add(DefinitionOpcode(24, OpcodeType.BYTE, propertyChain( + ItemServerType::weapon, + Weapon::attackSpeed + ))) + + add(DefinitionOpcodeMap(25, OpcodeType.STRING, OpcodeType.INT, propertyChain( + ItemServerType::equipment, + Equipment::requirements + ))) + + add(DefinitionOpcode(26, OpcodeType.STRING, ItemServerType::examine)) + add(DefinitionOpcode(27, OpcodeType.STRING, ItemServerType::destroy)) + add(DefinitionOpcode(28, OpcodeType.BOOLEAN, ItemServerType::alchable)) + add(DefinitionOpcode(29, OpcodeType.INT, ItemServerType::exchangeCost)) + + add(DefinitionOpcodeMap(30, OpcodeType.STRING, OpcodeType.INT, propertyChain( + ItemServerType::equipment, + Equipment::requirements + ))) + + + add(DefinitionOpcode(31, enumType(), propertyChain( + ItemServerType::weapon, + Weapon::weaponType + ))) + + add(DefinitionOpcode(32, OpcodeType.STRING, propertyChain( + ItemServerType::weapon, + Weapon::weaponTypeRenderData + ))) + + ItemParam.entries.forEachIndexed { index, itemParam -> + if (itemParam.toProperty() != null) { + add(DefinitionOpcode(33 + index, OpcodeType.BYTE, propertyChain( + ItemServerType::equipment, + Equipment::stats, + itemParam.toProperty()!! + ))) + } + } + + add(DefinitionOpcode(60, OpcodeType.INT, propertyChain( + ItemServerType::equipment, + Equipment::equipType + ))) + + } + + private fun ItemParam.toProperty(): KMutableProperty1? = when (this) { + ItemParam.ATTACK_STAB -> EquipmentStats::attackStab + ItemParam.ATTACK_SLASH -> EquipmentStats::attackSlash + ItemParam.ATTACK_CRUSH -> EquipmentStats::attackCrush + ItemParam.ATTACK_MAGIC -> EquipmentStats::attackMagic + ItemParam.ATTACK_RANGED -> EquipmentStats::attackRanged + ItemParam.DEFENCE_STAB -> EquipmentStats::defenceStab + ItemParam.DEFENCE_SLASH -> EquipmentStats::defenceSlash + ItemParam.DEFENCE_CRUSH -> EquipmentStats::defenceCrush + ItemParam.DEFENCE_MAGIC -> EquipmentStats::defenceMagic + ItemParam.DEFENCE_RANGED -> EquipmentStats::defenceRanged + ItemParam.MELEE_STRENGTH -> EquipmentStats::meleeStrength + ItemParam.PRAYER -> EquipmentStats::prayer + ItemParam.RANGED_STRENGTH -> EquipmentStats::rangedStrength + ItemParam.MAGIC_STRENGTH -> EquipmentStats::magicStrength + ItemParam.RANGED_DAMAGE -> EquipmentStats::rangedDamage + ItemParam.MAGIC_DAMAGE -> EquipmentStats::magicDamage + ItemParam.DEMON_DAMAGE -> EquipmentStats::demonDamage + ItemParam.DEGRADEABLE -> EquipmentStats::degradeable + ItemParam.SILVER_STRENGTH -> EquipmentStats::silverStrength + ItemParam.CORP_BOOST -> EquipmentStats::corpBoost + ItemParam.GOLEM_DAMAGE -> EquipmentStats::golemDamage + ItemParam.KALPHITE_DAMAGE -> EquipmentStats::kalphiteDamage + else -> null + } + + private fun getItemRequirements(params: Map?): Map { + if (params == null) return emptyMap() + + val enum81 = enums?.get(81) ?: return emptyMap() + val enum108 = enums[108] ?: return emptyMap() + return ItemParam.entries.filter { it.isSkillParam }.mapNotNull { skillParam -> + val skillId = params.getInt(skillParam.id) + val skillNameId = enum81.values.getInt(skillId) + val skillName = enum108.getString(skillNameId) + val linkedLevel = params.getInt(skillParam.linkedLevelReqId ?: return@mapNotNull null) + if (linkedLevel > 0) skillName to linkedLevel else null + }.toMap() + } + + override fun ItemServerType.createData() { + if (items == null) return + val item = items[id] ?: return + val osrsData = osrs!![id] + val customData = custom!![id] + + id = item.id + examine = customData?.examine?.takeIf { it.isNotEmpty() } ?: osrsData?.examine?.takeIf { it.isNotEmpty() } ?: "" + + destroy = osrsData?.destroy.takeIf { it.isNullOrEmpty() } ?: "" + alchable = osrsData?.alchable ?: true + cost = osrsData?.cost?.takeIf { it != -1 } ?: cost + exchangeCost = osrsData?.exchangeCost?.takeIf { it != -1 } ?: cost + + name = item.name + weight = item.weight + isTradeable = item.isTradeable + category = item.category + options = item.options + interfaceOptions = item.interfaceOptions + noteLinkId = item.noteLinkId + noteTemplateId = item.noteTemplateId + placeholderLink = item.placeholderLink + placeholderTemplate = item.placeholderTemplate + stacks = item.stacks + appearanceOverride1 = item.appearanceOverride1 + appearanceOverride2 = item.appearanceOverride2 + params = item.params + + if (item.equipSlot != -1) { + + equipment = Equipment().apply { + equipSlot = item.equipSlot + equipType = appearanceOverride1 + stats = EquipmentStats().apply { + ItemParam.entries.forEach { stat -> + stat.toProperty()?.set(this, params?.getInt(stat.id) ?: 0) + } + } + requirements = getItemRequirements(params).takeIf { it.isNotEmpty() } ?: osrsData?.itemReq ?: emptyMap() + + } + + if (item.equipSlot == 3 || item.equipSlot == 5) { + weapon = Weapon().apply { + + val combatStyle = customData?.weapon?.weaponType?.name + ?.takeIf { it.isNotEmpty() && it != "UNARMED" } + ?: osrsData?.combatStyle?.takeIf { it.isNotEmpty() } + ?: "" + + fun findWeaponTypeRenderData(id: Int, weaponType: WeaponTypes): String? = + ItemRenderDataManager.getItemRenderAnimationByItem(id)?.name + ?: ItemRenderDataManager.getItemRenderAnimationById(weaponType.fallbackRenderID)?.name + + weaponType = WeaponTypes.entries.find { it.name == combatStyle.uppercase().replace(" ", "_") } ?: WeaponTypes.UNARMED + weaponTypeRenderData = findWeaponTypeRenderData(id, weaponType) + + attackSpeed = params?.getInt(14)?: 4 + attackRange = params?.getInt(13) ?: osrsData?.attackRange ?: 0 + specAmount = enums?.get(906)?.values?.takeIf { it.containsKey(id.toString()) }?.getInt(id) ?: -1 + } + } + + } + + } + + override fun createDefinition(): ItemServerType = ItemServerType() + +} diff --git a/cache/bin/main/dev/openrune/codec/osrs/impl/NpcServerCodec.kt b/cache/bin/main/dev/openrune/codec/osrs/impl/NpcServerCodec.kt new file mode 100644 index 00000000..30db4ac5 --- /dev/null +++ b/cache/bin/main/dev/openrune/codec/osrs/impl/NpcServerCodec.kt @@ -0,0 +1,94 @@ +package dev.openrune.codec.osrs.impl + +import dev.openrune.definition.type.NpcType +import dev.openrune.definition.opcode.OpcodeDefinitionCodec +import dev.openrune.definition.opcode.DefinitionOpcode +import dev.openrune.definition.opcode.OpcodeList +import dev.openrune.definition.opcode.OpcodeType +import dev.openrune.definition.opcode.impl.DefinitionOpcodeListActions +import dev.openrune.definition.opcode.impl.DefinitionOpcodeParams +import dev.openrune.definition.opcode.impl.DefinitionOpcodeTransforms +import dev.openrune.types.NpcServerType + + +class NpcServerCodec(val npcs: Map? = null) : OpcodeDefinitionCodec() { + + override val definitionCodec = OpcodeList().apply { + add(DefinitionOpcode(1, OpcodeType.STRING, NpcServerType::name)) + add(DefinitionOpcode(2, OpcodeType.INT, NpcServerType::size)) + add(DefinitionOpcode(3, OpcodeType.INT, NpcServerType::category)) + add(DefinitionOpcode(4, OpcodeType.INT, NpcServerType::standAnim)) + add(DefinitionOpcode(5, OpcodeType.INT, NpcServerType::rotateLeftAnim)) + add(DefinitionOpcode(6, OpcodeType.INT, NpcServerType::rotateRightAnim)) + add(DefinitionOpcode(7, OpcodeType.INT, NpcServerType::walkAnim)) + add(DefinitionOpcode(8, OpcodeType.INT, NpcServerType::rotateBackAnim)) + add(DefinitionOpcode(9, OpcodeType.INT, NpcServerType::walkLeftAnim)) + add(DefinitionOpcode(10, OpcodeType.INT, NpcServerType::walkRightAnim)) + add(DefinitionOpcodeListActions(11, OpcodeType.STRING, NpcServerType::actions, 5)) + add(DefinitionOpcodeTransforms(IntRange(12, 13), NpcServerType::transforms, NpcServerType::varbit, NpcServerType::varp)) + add(DefinitionOpcode(14, OpcodeType.INT, NpcServerType::combatLevel)) + add(DefinitionOpcode(15, OpcodeType.INT, NpcServerType::renderPriority)) + add(DefinitionOpcode(16, OpcodeType.BOOLEAN, NpcServerType::lowPriorityFollowerOps)) + add(DefinitionOpcode(17, OpcodeType.BOOLEAN, NpcServerType::isFollower)) + add(DefinitionOpcode(18, OpcodeType.INT, NpcServerType::runSequence)) + add(DefinitionOpcode(19, OpcodeType.BOOLEAN, NpcServerType::isInteractable)) + add(DefinitionOpcode(20, OpcodeType.INT, NpcServerType::runBackSequence)) + add(DefinitionOpcode(21, OpcodeType.INT, NpcServerType::runRightSequence)) + add(DefinitionOpcode(22, OpcodeType.INT, NpcServerType::runLeftSequence)) + add(DefinitionOpcode(23, OpcodeType.INT, NpcServerType::crawlSequence)) + add(DefinitionOpcode(24, OpcodeType.INT, NpcServerType::crawlBackSequence)) + add(DefinitionOpcode(25, OpcodeType.INT, NpcServerType::crawlRightSequence)) + add(DefinitionOpcode(26, OpcodeType.INT, NpcServerType::crawlLeftSequence)) + add(DefinitionOpcodeParams(27, NpcServerType::params)) + add(DefinitionOpcode(28, OpcodeType.USHORT, NpcServerType::height)) + add(DefinitionOpcode(29, OpcodeType.USHORT, NpcServerType::attack)) + add(DefinitionOpcode(30, OpcodeType.USHORT, NpcServerType::defence)) + add(DefinitionOpcode(31, OpcodeType.USHORT, NpcServerType::strength)) + add(DefinitionOpcode(32, OpcodeType.USHORT, NpcServerType::hitpoints)) + add(DefinitionOpcode(33, OpcodeType.USHORT, NpcServerType::ranged)) + add(DefinitionOpcode(34, OpcodeType.USHORT, NpcServerType::magic)) + } + + override fun NpcServerType.createData() { + if (npcs == null) return + val obj = npcs[id] ?: return + + name = obj.name + size = obj.size + category = obj.category + standAnim = obj.standAnim + rotateLeftAnim = obj.rotateLeftAnim + rotateRightAnim = obj.rotateRightAnim + walkAnim = obj.walkAnim + rotateBackAnim = obj.rotateBackAnim + walkLeftAnim = obj.walkLeftAnim + walkRightAnim = obj.walkRightAnim + actions = obj.actions + varbit = obj.varbit + varp = obj.varp + transforms = obj.transforms + combatLevel = obj.combatLevel + renderPriority = obj.renderPriority + lowPriorityFollowerOps = obj.lowPriorityFollowerOps + isFollower = obj.isFollower + runSequence = obj.runSequence + isInteractable = obj.isInteractable + runBackSequence = obj.runBackSequence + runRightSequence = obj.runRightSequence + runLeftSequence = obj.runLeftSequence + crawlSequence = obj.crawlSequence + crawlBackSequence = obj.crawlBackSequence + crawlRightSequence = obj.crawlRightSequence + crawlLeftSequence = obj.crawlLeftSequence + height = obj.height + attack = obj.attack + defence = obj.defence + strength = obj.strength + hitpoints = obj.hitpoints + ranged = obj.ranged + magic = obj.magic + params = obj.params + } + + override fun createDefinition(): NpcServerType = NpcServerType() +} diff --git a/cache/bin/main/dev/openrune/codec/osrs/impl/ObjectServerCodec.kt b/cache/bin/main/dev/openrune/codec/osrs/impl/ObjectServerCodec.kt new file mode 100644 index 00000000..d39b7efb --- /dev/null +++ b/cache/bin/main/dev/openrune/codec/osrs/impl/ObjectServerCodec.kt @@ -0,0 +1,82 @@ +package dev.openrune.codec.osrs.impl + +import dev.openrune.definition.type.ObjectType +import dev.openrune.definition.opcode.OpcodeDefinitionCodec +import dev.openrune.definition.opcode.DefinitionOpcode +import dev.openrune.definition.opcode.OpcodeList +import dev.openrune.definition.opcode.OpcodeType +import dev.openrune.definition.opcode.impl.DefinitionOpcodeListActions +import dev.openrune.definition.opcode.impl.DefinitionOpcodeParams +import dev.openrune.definition.opcode.impl.DefinitionOpcodeTransforms +import dev.openrune.server.infobox.InfoBoxItem +import dev.openrune.server.infobox.InfoBoxObject +import dev.openrune.types.ItemServerType +import dev.openrune.types.ObjectServerType + + +class ObjectServerCodec( + val objects: Map? = null, + val osrs : Map? = null, +) : OpcodeDefinitionCodec() { + + override val definitionCodec = OpcodeList().apply { + add(DefinitionOpcode(1, OpcodeType.STRING, ObjectServerType::name)) + add(DefinitionOpcode(3, OpcodeType.BYTE, ObjectServerType::sizeX)) + add(DefinitionOpcode(4, OpcodeType.BYTE, ObjectServerType::sizeY)) + add(DefinitionOpcode(5, OpcodeType.USHORT, ObjectServerType::offsetX)) + add(DefinitionOpcode(6, OpcodeType.BYTE, ObjectServerType::interactive)) + add(DefinitionOpcode(7, OpcodeType.INT, ObjectServerType::solid)) + add(DefinitionOpcode(9, OpcodeType.SHORT, ObjectServerType::modelSizeX)) + add(DefinitionOpcode(10, OpcodeType.SHORT, ObjectServerType::modelSizeZ)) + add(DefinitionOpcode(11, OpcodeType.SHORT, ObjectServerType::modelSizeY)) + add(DefinitionOpcode(12, OpcodeType.SHORT, ObjectServerType::offsetZ)) + add(DefinitionOpcode(13, OpcodeType.SHORT, ObjectServerType::offsetY)) + add(DefinitionOpcode(14, OpcodeType.BYTE, ObjectServerType::clipMask)) + add(DefinitionOpcode(15, OpcodeType.BOOLEAN, ObjectServerType::obstructive)) + add(DefinitionOpcode(16, OpcodeType.USHORT, ObjectServerType::category)) + add(DefinitionOpcode(17, OpcodeType.BYTE, ObjectServerType::supportsItems)) + add(DefinitionOpcode(18, OpcodeType.BOOLEAN, ObjectServerType::isRotated)) + add(DefinitionOpcode(19, OpcodeType.BOOLEAN, ObjectServerType::impenetrable)) + add(DefinitionOpcode(20, OpcodeType.USHORT, ObjectServerType::replacementId)) + add(DefinitionOpcodeTransforms(IntRange(23, 24),ObjectServerType::transforms,ObjectServerType::varbit,ObjectServerType::varp)) + add(DefinitionOpcodeListActions(25, OpcodeType.STRING, ObjectServerType::actions, 5)) + add(DefinitionOpcodeParams(26, ObjectServerType::params)) + add(DefinitionOpcode(27, OpcodeType.STRING, ObjectServerType::examine)) + + } + + override fun ObjectServerType.createData() { + if (objects == null) return + + val obj = objects[id]?: return + + name = obj.name + examine = osrs?.get(id)?.examine?.takeIf { it.isNotEmpty() } ?: "" + sizeX = obj.sizeX + sizeY = obj.sizeY + offsetX = obj.offsetX + interactive = obj.interactive + solid = obj.solid + actions = obj.actions + modelSizeX = obj.modelSizeX + modelSizeZ = obj.modelSizeZ + modelSizeY = obj.modelSizeY + offsetZ = obj.offsetZ + offsetY = obj.offsetY + clipMask = obj.clipMask + obstructive = obj.obstructive + category = obj.category + supportsItems = obj.supportsItems + isRotated = obj.isRotated + impenetrable = obj.impenetrable + replacementId = obj.oppositeDoorId(objects) + varbit = obj.varbitId + varp = obj.varp + transforms = obj.transforms + params = obj.params + + } + + override fun createDefinition(): ObjectServerType = ObjectServerType() + +} diff --git a/cache/bin/main/dev/openrune/codec/osrs/impl/SequenceServerCodec.kt b/cache/bin/main/dev/openrune/codec/osrs/impl/SequenceServerCodec.kt new file mode 100644 index 00000000..c07d69fd --- /dev/null +++ b/cache/bin/main/dev/openrune/codec/osrs/impl/SequenceServerCodec.kt @@ -0,0 +1,28 @@ +package dev.openrune.codec.osrs.impl + +import dev.openrune.definition.type.SequenceType +import dev.openrune.definition.opcode.OpcodeDefinitionCodec +import dev.openrune.definition.opcode.DefinitionOpcode +import dev.openrune.definition.opcode.OpcodeList +import dev.openrune.definition.opcode.OpcodeType +import dev.openrune.types.SequenceServerType + + +class SequenceServerCodec(val sequences: Map? = null) : OpcodeDefinitionCodec() { + + override val definitionCodec = OpcodeList().apply { + add(DefinitionOpcode(1, OpcodeType.USHORT, SequenceServerType::animationLength)) + + } + + override fun SequenceServerType.createData() { + if (sequences == null) return + + val seq = sequences[id]?: return + + animationLength = seq.lengthInCycles + } + + override fun createDefinition(): SequenceServerType = SequenceServerType() + +} diff --git a/cache/bin/main/dev/openrune/tools/MinifyServerCache.kt b/cache/bin/main/dev/openrune/tools/MinifyServerCache.kt new file mode 100644 index 00000000..fa277cbd --- /dev/null +++ b/cache/bin/main/dev/openrune/tools/MinifyServerCache.kt @@ -0,0 +1,60 @@ +package dev.openrune.tools + +import com.displee.cache.CacheLibrary +import com.displee.cache.index.archive.file.File +import dev.openrune.cache.ANIMATIONS +import dev.openrune.cache.ANIMAYAS +import dev.openrune.cache.ARCHIVE_17 +import dev.openrune.cache.CacheDelegate +import dev.openrune.cache.DBTABLEINDEX +import dev.openrune.cache.MODELS +import dev.openrune.cache.MUSIC_JINGLES +import dev.openrune.cache.MUSIC_PATCHES +import dev.openrune.cache.MUSIC_SAMPLES +import dev.openrune.cache.MUSIC_TRACKS +import dev.openrune.cache.SOUNDEFFECTS +import dev.openrune.cache.TEXTURES +import dev.openrune.cache.WORLDMAPAREAS +import dev.openrune.cache.WORLDMAP_GEOGRAPHY +import dev.openrune.cache.WORLDMAP_GROUND +import dev.openrune.filesystem.Cache +import org.alter.ParamMapper.npc.SLAYER_CATEGORIES.SKELETONS + +class MinifyServerCache() { + + + fun init(loc : String) { + val cache = CacheLibrary(loc) + + emptyArchive(ANIMATIONS, cache) + emptyArchive(SKELETONS, cache) + emptyArchive(SOUNDEFFECTS, cache) + emptyArchive(MUSIC_TRACKS, cache) + emptyArchive(MODELS, cache) + emptyArchive(TEXTURES, cache) + emptyArchive(MUSIC_JINGLES, cache) + emptyArchive(MUSIC_SAMPLES, cache) + emptyArchive(MUSIC_PATCHES, cache) + emptyArchive(ARCHIVE_17, cache) + emptyArchive(WORLDMAP_GEOGRAPHY, cache) + emptyArchive(WORLDMAPAREAS, cache) + emptyArchive(WORLDMAP_GROUND, cache) + emptyArchive(DBTABLEINDEX, cache) + emptyArchive(ANIMAYAS, cache) + + val loc = java.io.File(loc) + val temp = java.io.File(loc,"temp") + temp.mkdirs() + cache.rebuild(temp) + cache.close() + temp.copyRecursively(loc,true) + temp.deleteRecursively() + + } + + fun emptyArchive(id : Int, cache: CacheLibrary) { + cache.index(id).clear() + cache.index(id).update() + } + +} \ No newline at end of file diff --git a/cache/bin/main/dev/openrune/tools/PackServerConfigOSRS.kt b/cache/bin/main/dev/openrune/tools/PackServerConfigOSRS.kt new file mode 100644 index 00000000..6123e281 --- /dev/null +++ b/cache/bin/main/dev/openrune/tools/PackServerConfigOSRS.kt @@ -0,0 +1,245 @@ +package dev.openrune.tools + +import cc.ekblad.toml.TomlMapper +import cc.ekblad.toml.model.TomlValue +import cc.ekblad.toml.serialization.from +import cc.ekblad.toml.tomlMapper +import cc.ekblad.toml.util.InternalAPI +import dev.openrune.OsrsCacheProvider +import dev.openrune.cache.* +import dev.openrune.cache.tools.TaskPriority +import org.alter.getCacheLocation +import dev.openrune.cache.tools.tasks.CacheTask +import dev.openrune.cache.util.getFiles +import dev.openrune.cache.util.progress +import dev.openrune.codec.osrs.impl.* +import dev.openrune.definition.Definition +import dev.openrune.definition.constants.ConstantProvider +import dev.openrune.definition.type.InventoryType +import dev.openrune.definition.type.ItemType +import dev.openrune.filesystem.Cache +import dev.openrune.server.impl.item.ItemRenderDataManager +import dev.openrune.server.infobox.InfoBoxItem +import dev.openrune.server.infobox.InfoBoxObject +import dev.openrune.server.infobox.Load +import dev.openrune.types.* +import dev.openrune.types.InventoryServerType.Companion.pack +import io.github.oshai.kotlinlogging.KotlinLogging +import java.io.File +import java.nio.file.Path +import kotlin.reflect.KType +import kotlin.reflect.typeOf + +class PackType( + val index: Int, + val name: String, + val tomlMapper: TomlMapper, + val kType: KType +) + + +class PackServerConfig( + private val directory : File, + private val tokenizedReplacement: Map = emptyMap() +) : CacheTask(serverTaskOnly = true) { + + override val priority: TaskPriority + get() = TaskPriority.END + + fun Map.bool(key: String, defualt : Boolean) = + this.containsKey(key) ?: defualt + + init { + registerPackType("item",kType = typeOf>()) + registerPackType("object",kType = typeOf>()) + registerPackType("npc", kType = typeOf>()) + registerPackType("health", kType = typeOf>()) + registerPackType("anims", kType = typeOf>()) + registerPackType("inventory", kType = typeOf>(), tomlMapper = tomlMapper { + addDecoder { content, def: InventoryServerType -> + def.apply { + flags = pack( + protect = content.bool("protect",true), + allStock = content.bool("allStock",false), + restock = content.bool("restock",false), + runWeight = content.bool("runWeight",false), + dummyInv = content.bool("dummyInv",false), + placeholders = content.bool("placeholders",false), + ) + } + } + }) + } + + + private val logger = KotlinLogging.logger {} + + @OptIn(InternalAPI::class) + override fun init(cache: Cache) { + val parsedDefinitions = mutableMapOf>() + CacheManager.init(OsrsCacheProvider(Cache.load(Path.of(getCacheLocation())), revision)) + + ItemRenderDataManager.init() + + val files = getFiles(directory, "toml") + + for (file in files) { + val document = TomlValue.from(processDocumentChanges(file.readText())) + + document.properties.forEach { prop -> + val packType = packTypes[prop.key] ?: return@forEach + + val decodedDefs: List = packType.tomlMapper.decode(packType.kType, prop.value) + parsedDefinitions.getOrPut(packType.name) { mutableListOf() }.addAll(decodedDefs) + } + + } + + val progress = progress("Packing Server Configs", parsedDefinitions.size) + packTypes.forEach { (type) -> + progress.extraMessage = type + when(type) { + "object" -> { + val codec = ObjectServerCodec( + CacheManager.getObjects(), + InfoBoxObject.load(File("../data/raw-cache/extra-dump/object-examines.csv").toPath()) + ) + CacheManager.getObjects().forEach { + cache.write(CONFIGS, 55, it.key, codec.encodeToBuffer(ObjectServerType(it.key))) + } + } + "npc" -> { + val codec = NpcServerCodec(CacheManager.getNpcs()) + CacheManager.getNpcs().forEach { + cache.write(CONFIGS, 58, it.key, codec.encodeToBuffer(NpcServerType(it.key))) + } + } + "health" -> { + val codec = HealthBarServerCodec(CacheManager.getHealthBars()) + CacheManager.getHealthBars().forEach { + cache.write(CONFIGS, 56, it.key, codec.encodeToBuffer(HealthBarServerType(it.key))) + } + } + "item" -> { + val codec = ItemServerCodec( + CacheManager.getItems(), + CacheManager.getEnums(), + InfoBoxItem.load(File("../data/raw-cache/extra-dump/item-data.json").toPath())) + + CacheManager.getItems().forEach { + cache.write(CONFIGS, 59, it.key, codec.encodeToBuffer(ItemServerType(it.key))) + } + } + "anims" -> { + val codec3 = SequenceServerCodec(CacheManager.getAnims()) + CacheManager.getAnims().forEach { + cache.write(CONFIGS, 57, it.key, codec3.encodeToBuffer(SequenceServerType(it.key))) + } + } + "inventory" -> { + val inventoryTypes = mutableMapOf().apply { + OsrsCacheProvider.InventoryDecoder().load(cache, this) + } + + val serverTypes: Map? = + parsedDefinitions["inventory"] + ?.filterIsInstance() + ?.associateBy { it.id } + + val codec = InventoryServerCodec( + inventoryTypes, + serverTypes + ) + + inventoryTypes.forEach { (id, _) -> + cache.write(CONFIGS, 60, id, codec.encodeToBuffer(InventoryServerType(id))) + } + } + else -> println("Missing Type: $type") + } + progress.step() + } + progress.close() + + } + + private fun processDocumentChanges(content: String): String { + val tokenMap = tokenizedReplacement.toMutableMap() + val regex = Regex("""\[\[tokenizedReplacement]](.*?)(?=\n\[\[|\z)""", RegexOption.DOT_MATCHES_ALL) + + regex.find(content)?.groups?.get(1)?.value + ?.lineSequence() + ?.map { it.trim() } + ?.filter { it.isNotEmpty() } + ?.forEach { parseInlineTableString(it).forEach { (k, v) -> tokenMap[k] = v.removeSurrounding("\"") } } + + var updated = content + tokenMap.forEach { (key, value) -> + updated = updated.replace(Regex("%${Regex.escape(key)}%", RegexOption.IGNORE_CASE), value) + } + + return processRSCMModifier(updated) + } + + private fun parseInlineTableString(input: String): List> = + input.removePrefix("{").removeSuffix("}") + .split(",") + .map { it.split("=").map { it.trim() } } + .map { it[0].lowercase() to it[1] } + + private fun processRSCMModifier(input: String): String { + val allowedPrefixes = ConstantProvider.types + val output = StringBuilder() + var debugNameAdded = false + + val quotedStringRegex = Regex(""""([^"]+)"""") + + input.lines().forEach { line -> + val trimmed = line.trim() + + if (trimmed.startsWith("[[")) { + debugNameAdded = false + output.appendLine(line) + return@forEach + } + + var modifiedLine = line + val matches = quotedStringRegex.findAll(line) + + for (match in matches) { + val fullValue = match.groupValues[1] + if (allowedPrefixes.any { fullValue.startsWith(it) }) { + val resolved = ConstantProvider.getMapping(fullValue) + modifiedLine = modifiedLine.replace("\"$fullValue\"", resolved.toString()) + + if (!debugNameAdded && trimmed.startsWith("id") && fullValue == match.groupValues[1]) { + output.appendLine("debugName = \"${fullValue.substringAfter(".")}\"") + debugNameAdded = true + } + } + } + + output.appendLine(modifiedLine) + } + + return output.toString() + } + + companion object { + + private val tomlMapperDefault = tomlMapper { } + val packTypes = mutableMapOf() + + fun registerPackType( + name: String, + index: Int = CONFIGS, + tomlMapper: TomlMapper = tomlMapperDefault, + kType: KType, + ) { + val packType = PackType(index, name,tomlMapper,kType) + packTypes[packType.name] = packType + } + + } + +} \ No newline at end of file diff --git a/cache/bin/main/dev/openrune/types/HealthBarServerType.kt b/cache/bin/main/dev/openrune/types/HealthBarServerType.kt new file mode 100644 index 00000000..35cc7345 --- /dev/null +++ b/cache/bin/main/dev/openrune/types/HealthBarServerType.kt @@ -0,0 +1,13 @@ +package dev.openrune.types + +import dev.openrune.definition.Definition + +data class HealthBarServerType( + override var id: Int = -1, + var width: Int = 30, +) : Definition { + + fun barWidth(curHealth : Int, maxHealth : Int): Int { + return ((curHealth.toDouble() / maxHealth) * width).toInt() + } +} diff --git a/cache/bin/main/dev/openrune/types/InventoryServerType.kt b/cache/bin/main/dev/openrune/types/InventoryServerType.kt new file mode 100644 index 00000000..f804c88c --- /dev/null +++ b/cache/bin/main/dev/openrune/types/InventoryServerType.kt @@ -0,0 +1,98 @@ +package dev.openrune.types + +import dev.openrune.definition.Definition +import org.alter.rscm.RSCM +import org.alter.rscm.RSCMType + +data class InventoryServerType( + override var id: Int = -1, + var stack: InvStackType = InvStackType.Normal, + var size: Int = 1, + var scope : InvScope = InvScope.Temp, + var flags: Int = pack( + protect = true, + allStock = false, + restock = false, + runWeight = false, + dummyInv = false, + placeholders = false, + ), + val stock: Array = emptyArray(), +) : Definition { + + public val restock: Boolean + get() = flags and RESTOCK_FLAG != 0 + + public val allStock: Boolean + get() = flags and ALL_STOCK_FLAG != 0 + + public val protect: Boolean + get() = flags and PROTECT_FLAG != 0 + + public val runWeight: Boolean + get() = flags and RUN_WEIGHT_FLAG != 0 + + public val dummyInv: Boolean + get() = flags and DUMMY_INV_FLAG != 0 + + public val placeholders: Boolean + get() = flags and PLACEHOLDERS_FLAG != 0 + + + public companion object { + public const val PROTECT_FLAG: Int = 0x1 + public const val ALL_STOCK_FLAG: Int = 0x2 + public const val RESTOCK_FLAG: Int = 0x4 + public const val RUN_WEIGHT_FLAG: Int = 0x8 + public const val DUMMY_INV_FLAG: Int = 0x10 + public const val PLACEHOLDERS_FLAG: Int = 0x20 + + fun pack( + protect: Boolean, + allStock: Boolean, + restock: Boolean, + runWeight: Boolean, + dummyInv: Boolean, + placeholders: Boolean, + ): Int { + var flags = 0 + if (protect) { + flags = flags or PROTECT_FLAG + } + if (allStock) { + flags = flags or ALL_STOCK_FLAG + } + if (restock) { + flags = flags or RESTOCK_FLAG + } + if (runWeight) { + flags = flags or RUN_WEIGHT_FLAG + } + if (dummyInv) { + flags = flags or DUMMY_INV_FLAG + } + if (placeholders) { + flags = flags or PLACEHOLDERS_FLAG + } + return flags + } + } + +} + +data class InvStock constructor(public val obj: Int, public val count: Int, public val restockCycles: Int) + +public enum class InvStackType(public val id: Int) { + Normal(0), + Always(1), + Never(2), +} + +public enum class InvScope(public val id: Int) { + /** Temporary inventories that do not save. (e.g., clue scrolls) */ + Temp(0), + /** Persistent inventories that will save. (e.g., bank) */ + Perm(1), + /** Global Inventories that are shared. (e.g., shops) */ + Shared(2), +} diff --git a/cache/bin/main/dev/openrune/types/ItemServerType.kt b/cache/bin/main/dev/openrune/types/ItemServerType.kt new file mode 100644 index 00000000..1d4ebe06 --- /dev/null +++ b/cache/bin/main/dev/openrune/types/ItemServerType.kt @@ -0,0 +1,128 @@ +package dev.openrune.types + +import dev.openrune.definition.Definition +import dev.openrune.server.impl.item.WeaponTypes + +data class ItemServerType( + override var id: Int = -1, + var cost: Int = -1, + var name: String = "", + var weight: Double = 0.0, + var isTradeable: Boolean = false, + var category: Int = -1, + var options: MutableList = mutableListOf(null, null, "Take", null, null), + var interfaceOptions: MutableList = mutableListOf(null, null, null, null, "Drop"), + var noteLinkId: Int = -1, + var noteTemplateId: Int = -1, + var placeholderLink: Int = -1, + var dummyitem : Int = 0, + var placeholderTemplate: Int = -1, + var stacks: Int = 0, + var appearanceOverride1: Int = -1, + var appearanceOverride2: Int = -1, + var examine : String = "", + var destroy: String = "", + var alchable: Boolean = true, + var exchangeCost: Int = -1, + + var transformlink : Int = -1, + var transformtemplate: Int = -1, + var equipment: Equipment? = null, + var weapon: Weapon? = null, + var params: MutableMap? = null, +) : Definition { + + public val resolvedDummyitem: Dummyitem? + get() = Dummyitem[dummyitem] + + + val stackable: Boolean + get() = stacks == 1 || noteTemplateId > 0 + + val noted: Boolean + get() = noteTemplateId > 0 + + /** + * Whether or not the object is a placeholder. + */ + val isPlaceholder + get() = placeholderTemplate > 0 && placeholderLink > 0 + +} + +data class EquipmentStats( + var attackStab: Int = 0, + var attackSlash: Int = 0, + var attackCrush: Int = 0, + var attackMagic: Int = 0, + var attackRanged: Int = 0, + var defenceStab: Int = 0, + var defenceSlash: Int = 0, + var defenceCrush: Int = 0, + var defenceMagic: Int = 0, + var defenceRanged: Int = 0, + var meleeStrength: Int = 0, + var prayer: Int = 0, + var rangedStrength: Int = 0, + var magicStrength: Int = 0, + var rangedDamage: Int = 0, + var magicDamage: Int = 0, + var demonDamage: Int = 0, + var degradeable: Int = 0, + var silverStrength: Int = 0, + var corpBoost: Int = 0, + var golemDamage: Int = 0, + var kalphiteDamage: Int = 0 +) + + +data class Equipment( + var equipSlot: Int = -1, + var equipType : Int = -1, + var requirements: Map = emptyMap(), + var stats: EquipmentStats? = null +) { + + //val equipmentOptions: List by lazy { + // (0 until 7).map { cachedParams.getString(451 + it).takeIf { it.isNotEmpty() } } + //} +} + + +data class Weapon( + var weaponTypeRenderData: String? = "default_player", + var weaponType: WeaponTypes = WeaponTypes.UNARMED, + var attackSpeed: Int = 0, + var attackRange: Int = 0, + var specAmount: Int = -1 +) { + fun hasSpec() = specAmount != -1 +} + + +private fun Map.getString(key: Int): String = + this[key.toString()]?.toString() ?: "" + +fun Map.getInt(key: Int): Int = when (val v = this[key.toString()]) { + is Int -> v + is Number -> v.toInt() + is String -> v.toIntOrNull() ?: 0 + else -> 0 +} + +public enum class Dummyitem(public val id: Int) { + /** Cannot be added into inventories or dropped on floor. */ + GraphicOnly(id = 1), + /** Can be added into inventories, but cannot be dropped on floor. */ + InvOnly(id = 2); + + public companion object { + public operator fun get(id: Int): Dummyitem? = + when (id) { + GraphicOnly.id -> GraphicOnly + InvOnly.id -> InvOnly + else -> null + } + } +} + diff --git a/cache/bin/main/dev/openrune/types/NpcServerType.kt b/cache/bin/main/dev/openrune/types/NpcServerType.kt new file mode 100644 index 00000000..f6a3d6be --- /dev/null +++ b/cache/bin/main/dev/openrune/types/NpcServerType.kt @@ -0,0 +1,44 @@ +package dev.openrune.types + +import dev.openrune.definition.Definition + +data class NpcServerType( + override var id: Int = -1, + var name : String = "", + var size: Int = 1, + var category: Int = -1, + var standAnim: Int = -1, + var rotateLeftAnim: Int = -1, + var rotateRightAnim: Int = -1, + var walkAnim: Int = -1, + var rotateBackAnim: Int = -1, + var walkLeftAnim: Int = -1, + var walkRightAnim: Int = -1, + var actions: MutableList = mutableListOf(null, null, null, null, null), + var varbit: Int = -1, + var varp: Int = -1, + var transforms: MutableList? = null, + var combatLevel: Int = -1, + var renderPriority: Int = 0, + var lowPriorityFollowerOps: Boolean = false, + var isFollower: Boolean = false, + var runSequence: Int = -1, + var isInteractable : Boolean = true, + var runBackSequence: Int = -1, + var runRightSequence: Int = -1, + var runLeftSequence: Int = -1, + var crawlSequence: Int = -1, + var crawlBackSequence: Int = -1, + var crawlRightSequence: Int = -1, + var crawlLeftSequence: Int = -1, + var height: Int = -1, + var attack : Int = 1, + var defence : Int = 1, + var strength : Int = 1, + var hitpoints : Int = 1, + var ranged : Int = 1, + var magic : Int = 1, + var params: MutableMap? = null, +) : Definition { + fun isAttackable(): Boolean = combatLevel > 0 && actions.any { it == "Attack" } +} diff --git a/cache/bin/main/dev/openrune/types/ObjectServerType.kt b/cache/bin/main/dev/openrune/types/ObjectServerType.kt new file mode 100644 index 00000000..27a7844c --- /dev/null +++ b/cache/bin/main/dev/openrune/types/ObjectServerType.kt @@ -0,0 +1,31 @@ +package dev.openrune.types + +import dev.openrune.definition.Definition + +data class ObjectServerType( + override var id: Int = -1, + var name : String = "", + var examine : String = "", + var sizeX: Int = 1, + var sizeY: Int = 1, + var offsetX: Int = 0, + var interactive: Int = -1, + var solid: Int = 2, + var actions: MutableList = mutableListOf(null, null, null, null, null), + var modelSizeX: Int = 128, + var modelSizeZ: Int = 128, + var modelSizeY: Int = 128, + var offsetZ: Int = 0, + var offsetY: Int = 0, + var clipMask: Int = 0, + var obstructive: Boolean = false, + var category: Int = -1, + var supportsItems: Int = -1, + var isRotated: Boolean = false, + var impenetrable: Boolean = true, + var replacementId: Int = -1, + var varbit: Int = -1, + var varp: Int = -1, + var transforms: MutableList? = null, + var params: MutableMap? = null +) : Definition diff --git a/cache/bin/main/dev/openrune/types/SequenceServerType.kt b/cache/bin/main/dev/openrune/types/SequenceServerType.kt new file mode 100644 index 00000000..02fc3197 --- /dev/null +++ b/cache/bin/main/dev/openrune/types/SequenceServerType.kt @@ -0,0 +1,8 @@ +package dev.openrune.types + +import dev.openrune.definition.Definition + +data class SequenceServerType( + override var id: Int = -1, + var animationLength: Int = 0, +) : Definition diff --git a/cache/bin/main/dev/openrune/util/Coords.kt b/cache/bin/main/dev/openrune/util/Coords.kt new file mode 100644 index 00000000..c4fe0f4a --- /dev/null +++ b/cache/bin/main/dev/openrune/util/Coords.kt @@ -0,0 +1,3 @@ +package dev.openrune.util + +fun Coords(x: Int, y: Int, z: Int = 0): Int = (z and 3) shl 28 or ((x and 16383) shl 14) or (y and 16383) \ No newline at end of file diff --git a/cache/bin/main/dev/openrune/util/TextAlignment.kt b/cache/bin/main/dev/openrune/util/TextAlignment.kt new file mode 100644 index 00000000..8fd60f38 --- /dev/null +++ b/cache/bin/main/dev/openrune/util/TextAlignment.kt @@ -0,0 +1,204 @@ +package dev.openrune.util + +import dev.openrune.ServerCacheManager +import dev.openrune.cache.filestore.definition.FontDecoder +import dev.openrune.definition.type.FontType +import dev.openrune.filesystem.Cache +import org.alter.rscm.RSCM.asRSCM +import kotlin.math.ceil + +object TextAlignment { + + + public fun generateChatPageList(text: String): List { + return generatePageList(text, CHAT_MAX_LINE_PIXEL_WIDTH, "fonts.q8_full") + } + + public fun generateMesPageList(text: String): List { + return generatePageList(text, MESBOX_MAX_LINE_PIXEL_WIDTH, "fonts.q8_full") + } + + public fun generatePageList( + text: String, + lineWidth: Int, + fontName: String, + ): List { + + val font = ServerCacheManager.getFont(fontName.asRSCM())!! + + val lineBuffers = Array(MAX_TOTAL_LINE_COUNT) { "" } + val lineCount = font.splitText(text, lineWidth, lineBuffers) + val pageCount = ceil(lineCount.toDouble() / LINES_PER_PAGE).toInt() + return when (pageCount) { + 1 -> { + val page1 = lineBuffers.joinToPageString(0 until lineCount) + listOf(Page(page1, lineCount)) + } + 2 -> { + val page1 = lineBuffers.joinToPageString(0 until LINES_PER_PAGE) + + val page2LineCount = lineCount - LINES_PER_PAGE + val page2 = + lineBuffers.joinToPageString( + LINES_PER_PAGE until LINES_PER_PAGE + page2LineCount + ) + return listOf(Page(page1, LINES_PER_PAGE), Page(page2, page2LineCount)) + } + // Don't see a point in supporting more than two pages from one single text string. + // There will be extremely niche situations where one text will be split into two + // pages, such as when the player display name is long enough to cause the dialogue + // to need a second page. + else -> throw NotImplementedError("Page list of size `$pageCount` is not implemented.") + } + } + + private fun FontType.splitText( + text: String, + widthPerLine: Int, + lineBuffer: Array, + ): Int { + val lineBuilder = StringBuilder(100) + var lineWidth = 0 + var lineStart = 0 + var lastWordIndex = -1 + var wordWidth = 0 + var extraSpacing: Byte = 0 + var tagStart: Int = -1 + var prevChar: Char = 0.toChar() + var lineCount = 0 + for (index in text.indices) { + var char = text[index] + + if (char == '<') { + tagStart = index + continue + } + + if (char == '>' && tagStart != -1) { + val tag = text.substring(tagStart + 1, index) + tagStart = -1 + lineBuilder.append('<').append(tag).append('>') + when (tag) { + "br" -> { + lineBuffer[lineCount] = lineBuilder.substring(lineStart) + lineCount++ + lineStart = lineBuilder.length + lineWidth = 0 + lastWordIndex = -1 + prevChar = 0.toChar() + } + "lt" -> { + lineWidth += getAdjustedGlyphAdvance('<') + if (kerning.isNotEmpty() && prevChar != 0.toChar()) { + lineWidth += kerning[(prevChar.code shl 8) + 60] + } + prevChar = '<' + } + "gt" -> { + lineWidth += getAdjustedGlyphAdvance('>') + if (kerning.isNotEmpty() && prevChar != 0.toChar()) { + lineWidth += kerning[(prevChar.code shl 8) + 62] + } + prevChar = '>' + } + else -> + if (tag.startsWith("img=")) { + // TODO: load width from mod_icons + // val imgId = tag.substring(4).toInt() + // glyphs[imgId].getWidth() + lineWidth += 13 + prevChar = 0.toChar() + } + } + char = 0.toChar() + } + + if (tagStart == -1) { + if (char != 0.toChar()) { + lineBuilder.append(char) + lineWidth += getAdjustedGlyphAdvance(char) + if (kerning.isNotEmpty() && prevChar != 0.toChar()) { + lineWidth += kerning[(prevChar.code shl 8) or char.code] + } + prevChar = char + } + + if (char == ' ') { + lastWordIndex = lineBuilder.length + wordWidth = lineWidth + extraSpacing = 1 + } + + if (lineWidth > widthPerLine && lastWordIndex >= 0) { + lineBuffer[lineCount] = + lineBuilder.substring(lineStart, lastWordIndex - extraSpacing) + lineCount++ + lineStart = lastWordIndex + lastWordIndex = -1 + lineWidth -= wordWidth + prevChar = 0.toChar() + } + + if (char == '-') { + lastWordIndex = lineBuilder.length + wordWidth = lineWidth + extraSpacing = 0 + } + } + } + val line = lineBuilder.toString() + if (line.length > lineStart) { + lineBuffer[lineCount++] = line.substring(lineStart) + } + return lineCount + } + + private fun FontType.getAdjustedGlyphAdvance(char: Char): Int { + val adjustedChar = if (char == 160.toChar()) ' ' else char + return glyphAdvances[adjustedChar.code and 0xFF] + } + + private fun Array.joinToPageString(indexRangeExclusive: IntRange): String = + indexRangeExclusive.joinToString(separator = "") { index -> + this[index] + if (index < indexRangeExclusive.last) LINE_SEPARATOR else "" + } + + public fun chatLineHeight(lineCount: Int): Int = + when (lineCount) { + 2 -> CHAT_TWO_LINE_LINE_HEIGHT + 3 -> CHAT_THREE_LINE_LINE_HEIGHT + else -> CHAT_DEFAULT_LINE_HEIGHT + } + + public fun mesLineHeight(lineCount: Int): Int = + when (lineCount) { + 2 -> MESBOX_TWO_LINE_LINE_HEIGHT + 3 -> MESBOX_THREE_LINE_LINE_HEIGHT + 4 -> MESBOX_FOUR_LINE_LINE_HEIGHT + else -> MESBOX_DEFAULT_LINE_HEIGHT + } + + public data class Page(val text: String, val lineCount: Int) + + private const val LINES_PER_PAGE: Int = 4 + private const val MAX_PAGE_COUNT: Int = 2 + private const val MAX_TOTAL_LINE_COUNT: Int = LINES_PER_PAGE * MAX_PAGE_COUNT + + private const val CHAT_MAX_LINE_PIXEL_WIDTH: Int = 380 + private const val MESBOX_MAX_LINE_PIXEL_WIDTH: Int = 470 + + private const val CHAT_DEFAULT_LINE_HEIGHT: Int = 16 + private const val CHAT_TWO_LINE_LINE_HEIGHT: Int = 28 + private const val CHAT_THREE_LINE_LINE_HEIGHT: Int = 20 + + private const val MESBOX_DEFAULT_LINE_HEIGHT: Int = 0 + private const val MESBOX_TWO_LINE_LINE_HEIGHT: Int = 31 + private const val MESBOX_THREE_LINE_LINE_HEIGHT: Int = 24 + private const val MESBOX_FOUR_LINE_LINE_HEIGHT: Int = 17 + + /** + * Used as a separator for each line in a dialogue page. This _can_ be left as whitespace as + * this is handled on the client's end as well. However, we send it for emulation. + */ + private const val LINE_SEPARATOR: String = "
" +} diff --git a/cache/bin/main/logback.xml b/cache/bin/main/logback.xml new file mode 100644 index 00000000..a7c4e080 --- /dev/null +++ b/cache/bin/main/logback.xml @@ -0,0 +1,20 @@ + + + + + [%d{HH:mm:ss.SSS}] %highlight(%-5level) %cyan(%logger{0}) - %msg %n + + + + + + + + + + + + + + + diff --git a/cache/bin/main/org/alter/BufferReader.kt b/cache/bin/main/org/alter/BufferReader.kt new file mode 100644 index 00000000..1bf15372 --- /dev/null +++ b/cache/bin/main/org/alter/BufferReader.kt @@ -0,0 +1,174 @@ +package org.alter + +import java.nio.ByteBuffer + +class BufferReader( + val buffer: ByteBuffer +) { + + constructor(array: ByteArray) : this(buffer = ByteBuffer.wrap(array)) + + val length: Int = buffer.remaining() + val remaining: Int + get() = buffer.remaining() + private var bitIndex = 0 + + fun readByte(): Int { + return buffer.get().toInt() + } + + fun readByteAdd(): Int { + return (readByte() - 128).toByte().toInt() + } + + fun readByteInverse(): Int { + return -readByte() + } + + fun readByteSubtract(): Int { + return (readByteInverse() + 128).toByte().toInt() + } + + fun readUnsignedByte(): Int { + return readByte() and 0xff + } + + fun readShort(): Int { + return (readByte() shl 8) or readUnsignedByte() + } + + fun readShortAdd(): Int { + return (readByte() shl 8) or readUnsignedByteAdd() + } + + fun readUnsignedShortAdd(): Int { + return (readByte() shl 8) or ((readByte() - 128) and 0xff) + } + + fun readShortLittle(): Int { + return readUnsignedByte() or (readByte() shl 8) + } + + fun readShortAddLittle(): Int { + return readUnsignedByteAdd() or (readByte() shl 8) + } + + fun readShortSmart() : Int { + val peek = readUnsignedByte() + return if (peek < 128) peek - 64 else (peek shl 8 or readUnsignedByte()) - 49152 + } + + fun readUnsignedByteAdd(): Int { + return (readByte() - 128).toByte().toInt() + } + + fun readUnsignedShort(): Int { + return (readUnsignedByte() shl 8) or readUnsignedByte() + } + + fun readUnsignedShortLittle(): Int { + return readUnsignedByte() or (readUnsignedByte() shl 8) + } + + fun readMedium(): Int { + return (readByte() shl 16) or (readByte() shl 8) or readUnsignedByte() + } + + fun readUnsignedMedium(): Int { + return (readUnsignedByte() shl 16) or (readUnsignedByte() shl 8) or readUnsignedByte() + } + + fun readInt(): Int { + return (readUnsignedByte() shl 24) or (readUnsignedByte() shl 16) or (readUnsignedByte() shl 8) or readUnsignedByte() + } + + fun readIntInverseMiddle(): Int { + return (readByte() shl 16) or (readByte() shl 24) or readUnsignedByte() or (readByte() shl 8) + } + + fun readIntLittle(): Int { + return readUnsignedByte() or (readByte() shl 8) or (readByte() shl 16) or (readByte() shl 24) + } + + fun readUnsignedIntMiddle(): Int { + return (readUnsignedByte() shl 8) or readUnsignedByte() or (readUnsignedByte() shl 24) or (readUnsignedByte() shl 16) + } + + fun readSmart(): Int { + val peek = readUnsignedByte() + return if (peek < 128) { + peek and 0xFF + } else { + (peek shl 8 or readUnsignedByte()) - 32768 + } + } + + fun readBigSmart(): Int { + val peek = readByte() + return if (peek < 0) { + ((peek shl 24) or (readUnsignedByte() shl 16) or (readUnsignedByte() shl 8) or readUnsignedByte()) and 0x7fffffff + } else { + val value = (peek shl 8) or readUnsignedByte() + if (value == 32767) -1 else value + } + } + + fun readLargeSmart(): Int { + var baseValue = 0 + var lastValue = readSmart() + while (lastValue == 32767) { + lastValue = readSmart() + baseValue += 32767 + } + return baseValue + lastValue + } + + fun readLong(): Long { + val first = readInt().toLong() and 0xffffffffL + val second = readInt().toLong() and 0xffffffffL + return second + (first shl 32) + } + + fun readString(): String { + val sb = StringBuilder() + var b: Int + while (buffer.hasRemaining()) { + b = readUnsignedByte() + if (b == 0) { + break + } + sb.append(b.toChar()) + } + return sb.toString() + } + + fun readBytes(value: ByteArray) { + buffer.get(value) + } + + fun readBytes(array: ByteArray, offset: Int, length: Int) { + buffer.get(array, offset, length) + } + + fun skip(amount: Int) { + buffer.position(buffer.position() + amount) + } + + fun position(): Int { + return buffer.position() + } + + fun position(index: Int) { + buffer.position(index) + } + + fun array(): ByteArray { + return buffer.array() + } + + fun readableBytes(): Int { + return buffer.remaining() + } + + +} \ No newline at end of file diff --git a/cache/bin/main/org/alter/CacheTools.kt b/cache/bin/main/org/alter/CacheTools.kt new file mode 100644 index 00000000..3e681250 --- /dev/null +++ b/cache/bin/main/org/alter/CacheTools.kt @@ -0,0 +1,206 @@ +package org.alter + +import com.displee.cache.CacheLibrary +import dev.openrune.OsrsCacheProvider +import dev.openrune.cache.gameval.GameValHandler +import dev.openrune.cache.tools.Builder +import dev.openrune.cache.tools.CacheEnvironment +import dev.openrune.cache.tools.tasks.CacheTask +import dev.openrune.cache.tools.tasks.TaskType +import dev.openrune.cache.tools.tasks.impl.PackDBTables +import dev.openrune.cache.tools.tasks.impl.defs.PackConfig +import dev.openrune.definition.GameValGroupTypes +import dev.openrune.definition.type.DBRowType +import dev.openrune.definition.util.VarType +import dev.openrune.filesystem.Cache +import dev.openrune.tools.MinifyServerCache +import dev.openrune.tools.PackServerConfig +import io.github.oshai.kotlinlogging.KotlinLogging +import org.alter.codegen.startGeneration +import org.alter.gamevals.GameValProvider +import org.alter.gamevals.GamevalDumper +import org.alter.impl.GameframeTable +import org.alter.impl.skills.cooking.CookingTables +import org.alter.impl.skills.Firemaking +import org.alter.impl.misc.FoodTable +import org.alter.impl.skills.PrayerTable +import org.alter.impl.StatComponents +import org.alter.impl.misc.TeleTabs +import org.alter.impl.skills.Woodcutting +import org.alter.impl.skills.Herblore +import org.alter.impl.skills.Mining +import org.alter.impl.skills.Smithing +import org.alter.impl.skills.runecrafting.Alters +import org.alter.impl.skills.runecrafting.CombinationRune +import org.alter.impl.skills.runecrafting.RunecraftRune +import org.alter.impl.skills.runecrafting.Tiara +import java.io.File +import java.nio.file.Files +import java.nio.file.StandardCopyOption +import kotlin.system.exitProcess + +fun getCacheLocation() = File("../data/", "cache/LIVE").path +fun getServerCacheLocation() = File("../data/", "cache/SERVER").path +fun getRawCacheLocation(dir: String) = File("../data/", "raw-cache/$dir/") + +fun tablesToPack() = listOf( + PrayerTable.skillTable(), + TeleTabs.teleTabs(), + StatComponents.statsComponents(), + FoodTable.consumableFood(), + CookingTables.actionOutcomes(), + CookingTables.actionInputs(), + CookingTables.actions(), + Firemaking.logs(), + Woodcutting.trees(), + Woodcutting.axes(), + Herblore.unfinishedPotions(), + Herblore.finishedPotions(), + Herblore.cleaningHerbs(), + Herblore.barbarianMixes(), + Herblore.swampTar(), + Herblore.crushing(), + Mining.pickaxes(), + Mining.rocks(), + Mining.miningEnhancers(), + Alters.altars(), + Tiara.tiara(), + RunecraftRune.runecraftRune(), + CombinationRune.runecraftComboRune(), + GameframeTable.gameframe(), + Smithing.bars(), + Smithing.cannonBalls(), + Smithing.dragonForge(), + Smithing.crystalSinging() +) + +private val logger = KotlinLogging.logger {} + +fun main(args: Array) { + if (args.isEmpty()) { + println("Usage: ") + exitProcess(1) + } + downloadRev(TaskType.valueOf(args.first().uppercase())) +} + +fun downloadRev(type: TaskType) { + + val rev = readRevision() + + logger.info { "Using Revision: $rev" } + + when (type) { + TaskType.FRESH_INSTALL -> { + + val builder = Builder(type = TaskType.FRESH_INSTALL, + cacheLocation = File(getCacheLocation()), + serverCacheLocation = File(getServerCacheLocation()) + ) + builder.revision(rev.first) + builder.subRevision(rev.second) + builder.removeXteas(false) + builder.environment(CacheEnvironment.valueOf(rev.third)) + + builder.build().initialize() + + Files.move( + File(getCacheLocation(), "xteas.json").toPath(), + File("../data/cache/", "xteas.json").toPath(), + StandardCopyOption.REPLACE_EXISTING + ) + + File(getServerCacheLocation(), "xteas.json").delete() + + val cache = Cache.load(File(getCacheLocation()).toPath()) + + GamevalDumper.dumpGamevals(cache,rev.first) + + buildCache(TaskType.BUILD,rev) + } + TaskType.SERVER_CACHE_BUILD -> buildCache(TaskType.SERVER_CACHE_BUILD,rev) + TaskType.BUILD -> buildCache(TaskType.BUILD,rev) + + } +} + + +data class ColInfo( + val types: MutableMap = mutableMapOf(), + var optional: Boolean = false, + var noData: Boolean = false +) + +fun buildCache(taskType: TaskType,rev: Triple) { + GameValProvider.load(autoAssignIds = true) + + val tasks: List = listOf( + PackConfig(File("../data/raw-cache/server")) + ).toMutableList() + + val builder = Builder(type = taskType, + cacheLocation = File(getCacheLocation()), + serverCacheLocation = File(getServerCacheLocation()) + ) + builder.revision(rev.first) + + val tasksNew = tasks.toMutableList() + tasksNew.add(PackDBTables(tablesToPack())) + + builder.extraTasks(*tasksNew.toTypedArray()).build().initialize() + if (taskType == TaskType.BUILD) { + builder.type = TaskType.SERVER_CACHE_BUILD + builder.extraTasks( + PackServerConfig(File("../data/raw-cache/server")), + *tasksNew.toTypedArray() + ).build().initialize() + } + + if (builder.type == TaskType.SERVER_CACHE_BUILD) { + + MinifyServerCache().init(getServerCacheLocation()) + + val cache = Cache.load(File(getServerCacheLocation()).toPath()) + + GamevalDumper.dumpCols(cache,rev.first) + + val type = GameValHandler.readGameVal(GameValGroupTypes.TABLETYPES, cache = cache, rev.first) + + val rows : MutableMap = emptyMap().toMutableMap() + + OsrsCacheProvider.DBRowDecoder().load(cache,rows) + + startGeneration(type,rows) + } +} + +fun readRevision(): Triple { + val file = listOf("../game.yml", "../game.example.yml") + .map(::File) + .firstOrNull { it.exists() } + ?: error("No game.yml or game.example.yml found") + + return file.useLines { lines -> + val revisionLine = lines.firstOrNull { it.trimStart().startsWith("revision:") } + ?: error("No revision line found in ${file.name}") + + val revisionStr = revisionLine.substringAfter("revision:").trim() + val match = Regex("""^(\d+)(?:\.(\d+))?$""").matchEntire(revisionStr) + ?: error("Invalid revision format: '$revisionStr'") + + val major = match.groupValues[1].toInt() + val minor = match.groupValues.getOrNull(2)?.toIntOrNull() ?: -1 + + val envLine = file.readLines() + .firstOrNull { it.trimStart().startsWith("environment:") } + + val environment = envLine + ?.substringAfter("environment:") + ?.trim() + ?.removeSurrounding("\"") + ?.ifBlank { "live" } + ?: "live" + + Triple(major, minor, environment.uppercase()) + } +} \ No newline at end of file diff --git a/cache/bin/main/org/alter/ParamMapper.kt b/cache/bin/main/org/alter/ParamMapper.kt new file mode 100644 index 00000000..bb5768f1 --- /dev/null +++ b/cache/bin/main/org/alter/ParamMapper.kt @@ -0,0 +1,170 @@ +package org.alter + +object ParamMapper { + object item { + val STAB_ATTACK_BONUS = 0 + val SLASH_ATTACK_BONUS = 1 + val CRUSH_ATTACK_BONUS = 2 + val MAGIC_ATTACK_BONUS = 3 + val RANGED_ATTACK_BONUS = 4 + val STAB_DEFENCE_BONUS = 5 + val SLASH_DEFENCE_BONUS = 6 + val CRUSH_DEFENCE_BONUS = 7 + val MAGIC_DEFENCE_BONUS = 8 + val RANGED_DEFENCE_BONUS = 9 + val MELEE_STRENGTH = 10 + val PRAYER_BONUS = 11 + val ATTACK_RATE = 14 + val MAGIC_DAMAGE_BONUS_SALAMANDER = 65 + val MAGIC_DAMAGE_STRENGTH = 299 // Should be divided by 10 + val RANGED_STRENGTH_BONUS = 189 + val PRIMARY_SKILL = 434 + val PRIMARY_LEVEL = 436 + val SECONDARY_SKILL = 435 + val SECONDARY_LEVEL = 437 + val TERTIARY_SKILL = 191 + val TERTIARY_LEVEL = 613 + val QUATERNARY_SKILL = 579 + val QUATERNARY_LEVEL = 614 + } + object npc { + const val STAB_ATTACK_BONUS = 0 + const val SLASH_ATTACK_BONUS = 1 + const val CRUSH_ATTACK_BONUS = 2 + const val MAGIC_ATTACK_BONUS = 3 + const val RANGED_ATTACK_BONUS = 4 + const val STAB_DEFENCE_BONUS = 5 + const val SLASH_DEFENCE_BONUS = 6 + const val CRUSH_DEFENCE_BONUS = 7 + const val MAGIC_DEFENCE_BONUS = 8 + const val RANGED_DEFENCE_BONUS = 9 + const val MELEE_STRENGTH_BONUS = 10 + const val RANGED_STRENGTH_BONUS = 12 + const val ATTACK_RATE = 14 // Attack rate in ticks + const val MAGIC_DAMAGE_BONUS = 65 + const val DRACONIC = 190 // 1 = If is draconic + const val GOLEM = 1178 // 1 = If is Golem + const val KALPHITE = 1353 // 1 = If is Kalphite + const val DEATH_DROP = 46 // What to drop on death Bones/Ashes etc. + const val PRIMARY_SLAYER_CATEGORY = 50 + + object SLAYER_CATEGORIES { + const val MONKEYS = 1 + const val GOBLINS = 2 + const val RATS = 3 + const val SPIDERS = 4 + const val BIRDS = 5 + const val COWS = 6 + const val SCORPIONS = 7 + const val BATS = 8 + const val WOLVES = 9 + const val ZOMBIES = 10 + const val SKELETONS = 11 + const val GHOSTS = 12 + const val BEARS = 13 + const val HILL_GIANTS = 14 + const val ICE_GIANTS_ICE_GIANTS = 15 + const val FIRE_GIANTS = 16 + const val MOSS_GIANTS = 17 + const val TROLLS = 18 + const val ICE_WARRIORS = 19 + const val OGRES = 20 + const val HOBGOBLINS = 21 + const val DOGS = 22 + const val GHOULS = 23 + const val GREEN_DRAGONS = 24 + const val BLUE_DRAGONS = 25 + const val RED_DRAGONS = 26 + const val BLACK_DRAGONS = 27 + const val LESSER_DEMONS = 28 + const val GREATER_DEMONS = 29 + const val BLACK_DEMONS = 30 + const val HELLHOUNDS = 31 + const val SHADOW_WARRIORS = 32 + const val WEREWOLVES = 33 + const val VAMPYRES = 34 + const val DAGANNOTH = 35 + const val TUROTH = 36 + const val CAVE_CRAWLERS = 37 + const val BANSHEES = 38 + const val CRAWLING_HANDS = 39 + const val INFERNAL_MAGES = 40 + const val ABERRANT_SPECTRES = 41 + const val ABYSSAL_DEMONS = 42 + const val BASILISKS = 43 + const val COCKATRICE = 44 + const val KURASK = 45 + const val GARGOYLES = 46 + const val PYREFIENDS = 47 + const val BLOODVELD = 48 + const val DUST_DEVILS = 49 + const val JELLIES = 50 + const val ROCKSLUGS = 51 + const val NECHRYAEL = 52 + const val KALPHITE = 53 + const val EARTH_WARRIORS = 54 + const val OTHERWORLDLY_BEINGS = 55 + const val ELVES = 56 + const val DWARVES = 57 + const val BRONZE_DRAGONS = 58 + const val IRON_DRAGONS = 59 + const val STEEL_DRAGONS = 60 + const val WALL_BEASTS = 61 + const val CAVE_SLIMES = 62 + const val CAVE_BUGS = 63 + const val SHADES = 64 + const val CROCODILES = 65 + const val DARK_BEASTS = 66 + const val MOGRES = 67 + const val LIZARDS = 68 + const val HARPIE_BUG_SWARMS = 70 + const val SEA_SNAKES = 71 + const val SKELETAL_WYVERNS = 72 + const val KILLERWATTS = 73 + const val MUTATED_ZYGOMITES = 74 + const val ICEFIENDS = 75 + const val MINOTAURS = 76 + const val FLESH_CRAWLERS = 77 + const val CATABLEPON = 78 + const val ANKOU = 79 + const val CAVE_HORRORS = 80 + const val JUNGLE_HORRORS = 81 + const val GORAKS_REMOVE = 82 + const val SUQAHS = 83 + const val SCABARITES = 85 + const val TERROR_DOGS = 86 + const val MOLANISK = 87 + const val WATERFIENDS = 88 + const val SPIRITUAL_CREATURES = 89 + const val LIZARDMEN = 90 + const val MAGIC_AXES = 91 + const val CAVE_KRAKEN = 92 + const val MITHRIL_DRAGONS = 93 + const val AVIANSIE = 94 + const val SMOKE_DEVILS = 95 + const val TZHAAR = 96 + const val MAMMOTHS = 99 + const val ROGUES = 100 + const val ENTS = 101 + const val BANDITS = 102 + const val DARK_WARRIORS = 103 + const val LAVA_DRAGONS = 104 + const val FOSSIL_ISLAND_WYVERNS = 106 + const val REVENANTS = 107 + const val ADAMANT_DRAGONS = 108 + const val RUNE_DRAGONS = 109 + const val CHAOS_DRUIDS = 110 + const val WYRMS = 111 + const val DRAKES = 112 + const val HYDRAS = 113 + const val SAND_CRARBS = 118 + const val BLACK_KNIGHTS = 119 + const val PIRATES = 120 + const val SOURHOGS = 121 + const val WARPED_CREATURES = 122 + const val LESSER_NAGUA = 123 + } + } + + +} \ No newline at end of file diff --git a/cache/bin/main/org/alter/codegen/TableGenerater.kt b/cache/bin/main/org/alter/codegen/TableGenerater.kt new file mode 100644 index 00000000..f57cee21 --- /dev/null +++ b/cache/bin/main/org/alter/codegen/TableGenerater.kt @@ -0,0 +1,377 @@ +package org.alter.codegen + +import com.squareup.kotlinpoet.* +import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy +import dev.openrune.cache.gameval.GameValElement +import dev.openrune.cache.gameval.GameValHandler.elementAs +import dev.openrune.cache.gameval.impl.Table +import dev.openrune.definition.type.DBRowType +import dev.openrune.definition.util.BaseVarType +import dev.openrune.definition.util.VarType +import org.alter.ColInfo +import org.alter.game.util.DbException +import org.alter.game.util.DbHelper +import org.alter.game.util.DbQueryCache +import java.io.File + +data class TableColumn( + val name: String, + val simpleName: String, + val varTypes: Map? = null, + val optional: Boolean = false, + val maxValues : Int = 0 +) + +data class TableDef( + val tableName: String, + val className: String, + val columns: List +) + +fun startGeneration(elements: List, rows: MutableMap) { + elements.forEach { element -> + val table = element.elementAs
() ?: return@forEach + val colInfoMap = table.columns.associate { it.name to ColInfo() }.toMutableMap() + + table(table.id, rows).forEach { row -> + table.columns.forEach { col -> + val info = colInfoMap[col.name]!! + try { + row.getColumn(col.id).types.forEachIndexed { index, type -> + info.types[index] = type + } + } catch (e: DbException.MissingColumn) { + info.optional = true + } + } + } + + val maxSizesByColumn: Map = + table.columns.associate { col -> + val maxSize = table(table.id, rows).maxOfOrNull { row -> + try { + row.getColumn(col.id).column.values?.size ?: 0 + } catch (e: DbException.MissingColumn) { + 0 + } + } ?: 0 + + col.name to maxSize + } + + val generatedColumns = table.columns.map { col -> + val info = colInfoMap[col.name]!! + TableColumn( + name = "columns.${table.name}:${col.name}", + simpleName = col.name, + varTypes = info.types, + optional = info.optional, + maxValues = maxSizesByColumn[col.name] ?: 0 + ) + } + + generateTable( + TableDef( + tableName = table.name, + className = formatClassName(table.name), + columns = generatedColumns + ), + File("../content/src/main/kotlin/org/") + ) + } +} + +private fun table(tableId: Int, rows: MutableMap): List { + return DbQueryCache.getTable(tableId.toString()) { + rows.asSequence() + .filter { it.value.tableId == tableId } + .map { DbHelper(it.value) } + .distinctBy { it.id } + .toList() + } +} + +private fun formatClassName(tableName: String): String { + return tableName + .split('_', '-', '.', ':') + .filter { it.isNotBlank() } + .joinToString("") { it.replaceFirstChar { c -> c.uppercase() } } + "Row" +} + +private const val BASE_PACKAGE = "org.generated.tables" +private const val VAR_TYPES_PACKAGE = "org.alter.game.util.vars" +private val PACKAGE_PREFIXES = listOf( + "fletching", "cluehelper", "fsw", "herblore", "woodcutting", "mining", + "fishing", "cooking", "smithing", "crafting", "runecrafting", + "agility", "thieving", "slayer", "construction", "hunter", + "farming", "prayer", "magic", "ranged", "melee", "combat", "sailing" +) + +private fun findMatchingPrefix(tableName: String): String? { + val lower = tableName.lowercase() + return PACKAGE_PREFIXES.sortedByDescending { it.length } + .firstOrNull { lower.startsWith(it) || lower.contains(it) } +} + +private fun toCamelCase(name: String): String { + val result = name.split("_").joinToString("") { + it.lowercase().replaceFirstChar { c -> c.uppercase() } + }.replaceFirstChar { it.lowercase() } + return if (result == "object") "objectID" else result +} + +private fun getKotlinType(varType: BaseVarType, optional: Boolean, isList: Boolean, isBooleanType: Boolean): TypeName { + val baseType = if (isBooleanType) BOOLEAN else when (varType) { + BaseVarType.INTEGER -> INT + BaseVarType.STRING -> STRING + BaseVarType.LONG -> LONG + else -> LONG + } + return if (isList) { + val elemType = if (optional) baseType.copy(nullable = true) else baseType + LIST.parameterizedBy(elemType) + } else { + if (optional) baseType.copy(nullable = true) else baseType + } +} + +private fun getVarTypeImplClass(varType: VarType): ClassName { + return ClassName(VAR_TYPES_PACKAGE, when (varType) { + VarType.BOOLEAN -> "BooleanType" + VarType.INT -> "IntType" + VarType.STRING -> "StringType" + VarType.LONG -> "LongType" + VarType.NPC -> "NpcVarType" + VarType.LOC -> "LocType" + VarType.OBJ -> "ObjType" + VarType.COORDGRID -> "CoordType" + VarType.MAPELEMENT -> "MapElementType" + VarType.DBROW -> "RowType" + VarType.NAMEDOBJ -> "NamedObjType" + VarType.GRAPHIC -> "GraphicType" + VarType.SEQ -> "SeqType" + VarType.MODEL -> "ModelType" + VarType.STAT -> "StatType" + VarType.CATEGORY -> "CategoryType" + VarType.COMPONENT -> "ComponentVarType" + VarType.INV -> "InvVarType" + VarType.IDKIT -> "IdkVarType" + VarType.ENUM -> "EnumVarType" + VarType.MIDI -> "MidiType" + VarType.VARP -> "VarpVarType" + VarType.STRUCT -> "StructType" + VarType.DBTABLE -> "TableVarType" + VarType.SYNTH -> "SynthType" + VarType.LOCSHAPE -> "LocShapeType" + else -> error("Unmapped Type: $varType") + }) +} + +private val tuplesToGen = mutableSetOf() + +fun generateTable(table: TableDef, outputDir: File) { + val dbHelper = ClassName("org.alter.game.util", "DbHelper") + val listType = ClassName("kotlin.collections", "List") + val tileType = ClassName("org.alter.game.model", "Tile") + val rscmType = ClassName("org.alter.rscm", "RSCMType") + val rscm = ClassName("org.alter.rscm", "RSCM") + + val packageName = findMatchingPrefix(table.tableName)?.let { "$BASE_PACKAGE.$it" } ?: BASE_PACKAGE + val rowClassName = ClassName(packageName, table.className) + val tableOutputDir = outputDir.parentFile + + val usedColumnFunctions = mutableSetOf() + var needsTileImport = false + val tuplesUsedInThisTable = mutableSetOf() + + val rowClassBuilder = TypeSpec.classBuilder(table.className) + .primaryConstructor(FunSpec.constructorBuilder().addParameter("row", dbHelper).build()) + + val fileBuilder = FileSpec.builder(packageName, table.className) + .addFileComment( + """ + |This file is AUTO-GENERATED. Do NOT edit manually. + |Generated for table: ${table.tableName} + """.trimMargin() + ) + .addImport("org.alter.game.util", "DbHelper") + .addImport("org.alter.rscm", "RSCM", "RSCMType") + .addImport("org.alter.rscm.RSCM", "asRSCM") + + table.columns.forEach { col -> + val sortedVarTypes = col.varTypes?.toSortedMap()?.values?.toList() ?: emptyList() + if (sortedVarTypes.isEmpty()) return@forEach + + val firstVarType = sortedVarTypes.first() + val isList = col.maxValues > 1 + + val isMixed = sortedVarTypes.toSet().size > 1 + val isCoordType = firstVarType == VarType.COORDGRID + val propertyName = toCamelCase(col.simpleName) + + val columnFunc = when { + isList -> if (col.optional) "multiColumnOptional" else "multiColumn" + else -> if (col.optional) "columnOptional" else "column" + } + usedColumnFunctions.add(columnFunc) + if (isMixed) usedColumnFunctions.add("multiColumnMixed") + + if (isMixed) { + val arity = sortedVarTypes.size + tuplesToGen.add(arity) + tuplesUsedInThisTable.add(arity) + val tupleClass = ClassName("org.generated", "Tuple$arity") + val typesArray = sortedVarTypes.map { + getKotlinType(it.baseType!!, col.optional, false, it == VarType.BOOLEAN) + }.toTypedArray() + val tupleType = tupleClass.parameterizedBy(*typesArray) + val nullableTupleType = if (col.optional) tupleType.copy(nullable = true) else tupleType + + val initializer = if (col.optional) { + CodeBlock.of( + "row.multiColumnMixed(%S" + sortedVarTypes.joinToString("") { ", %T" } + ").toTuple$arity()", + col.name, + *sortedVarTypes.map { getVarTypeImplClass(it) }.toTypedArray() + ) + } else { + CodeBlock.of( + "row.multiColumnMixed(%S" + sortedVarTypes.joinToString("") { ", %T" } + ").toTuple$arity() ?: error(\"Column ${'$'}{%S} returned empty list but is not optional\")", + col.name, + *sortedVarTypes.map { getVarTypeImplClass(it) }.toTypedArray(), + col.name + ) + } + + rowClassBuilder.addProperty( + PropertySpec.builder(propertyName, nullableTupleType) + .initializer(initializer) + .build() + ) + return@forEach + } + + val kotlinType = if (isCoordType && !isList) { + needsTileImport = true + if (col.optional) tileType.copy(nullable = true) else tileType + } else { + getKotlinType(firstVarType.baseType!!, col.optional, isList, firstVarType == VarType.BOOLEAN) + } + + val initializer = if (isCoordType && !isList) { + val columnFunc = if (col.optional) "columnOptional" else "column" + usedColumnFunctions.add(columnFunc) + if (col.optional) { + CodeBlock.of( + "row.$columnFunc(%S, %T)?.let { %T.from30BitHash(it) }", + col.name, + getVarTypeImplClass(firstVarType), + tileType + ) + } else { + CodeBlock.of("%T.from30BitHash(row.$columnFunc(%S, %T))", tileType, col.name, getVarTypeImplClass(firstVarType)) + } + } else { + val fmt = when { + isList && col.optional -> "row.multiColumnOptional(%S" + sortedVarTypes.joinToString("") { ", %T" } + ")" + isList -> "row.multiColumn(%S" + sortedVarTypes.joinToString("") { ", %T" } + ")" + col.optional -> "row.columnOptional(%S, %T)" + else -> "row.column(%S, %T)" + } + CodeBlock.of(fmt, col.name, *sortedVarTypes.map { getVarTypeImplClass(it) }.toTypedArray()) + } + + rowClassBuilder.addProperty( + PropertySpec.builder(propertyName, kotlinType) + .initializer(initializer) + .build() + ) + } + + val companion = TypeSpec.companionObjectBuilder() + .addFunction(FunSpec.builder("all") + .returns(listType.parameterizedBy(rowClassName)) + .addStatement("return %T.table(%S).map { %T(it) }", dbHelper, "tables.${table.tableName}", rowClassName) + .build()) + .addFunction(FunSpec.builder("getRow") + .addParameter("row", INT) + .returns(rowClassName) + .addStatement("return %T(%T.row(row))", rowClassName, dbHelper) + .build()) + .addFunction(FunSpec.builder("getRow") + .addParameter("column", String::class) + .returns(rowClassName) + .addStatement("%T.requireRSCM(%T.COLUMNS, column)", rscm, rscmType) + .addStatement("return getRow(column.asRSCM() and 0xFFFF)") + .build()) + .build() + + rowClassBuilder.addType(companion) + + val imports = mutableListOf("DbHelper") + imports.addAll(usedColumnFunctions.sorted()) + fileBuilder.addImport("org.alter.game.util", *imports.toTypedArray()) + if (needsTileImport) fileBuilder.addImport("org.alter.game.model", "Tile") + + tuplesUsedInThisTable.forEach { arity -> + fileBuilder.addImport("org.generated", "Tuple$arity") + fileBuilder.addImport("org.generated", "toTuple$arity") + } + + fileBuilder.addType(rowClassBuilder.build()) + fileBuilder.build().writeTo(tableOutputDir) + generateAllTuples(tableOutputDir, tuplesToGen) +} + +fun generateAllTuples(outputDir: File, tuplesToGen: MutableSet) { + val packageName = "org.generated" + val fileBuilder = FileSpec.builder(packageName, "Tuples") + .addFileComment( + """ + |WARNING: This file is AUTO-GENERATED. Do NOT edit manually. + |This file contains tuple classes and extension functions used by generated table classes. + """.trimMargin() + ) + + tuplesToGen.forEach { n -> + val typeParams = (0 until n).map { "T$it" } + val tupleClassName = ClassName(packageName, "Tuple$n") + + val tupleClassBuilder = TypeSpec.classBuilder("Tuple$n") + .addModifiers(KModifier.PUBLIC, KModifier.DATA) + .primaryConstructor( + FunSpec.constructorBuilder().apply { + typeParams.forEach { tp -> addParameter(tp.lowercase(), TypeVariableName(tp)) } + }.build() + ) + + typeParams.forEach { tp -> + val typeVar = TypeVariableName(tp) + tupleClassBuilder.addTypeVariable(typeVar) + tupleClassBuilder.addProperty( + PropertySpec.builder(tp.lowercase(), typeVar) + .initializer(tp.lowercase()) + .build() + ) + } + + fileBuilder.addType(tupleClassBuilder.build()) + + val extFun = FunSpec.builder("toTuple$n") + .receiver(ClassName("kotlin.collections", "List").parameterizedBy(STAR)) + .addTypeVariables(typeParams.map { TypeVariableName(it) }) + .returns(tupleClassName.parameterizedBy(typeParams.map { TypeVariableName(it) }).copy(nullable = true)) + .addCode(buildCodeBlock { + add("if (size < %L) return null\n", n) + add("return %T(", tupleClassName) + typeParams.forEachIndexed { index, tp -> + if (index > 0) add(", ") + add("this[%L] as %T", index, TypeVariableName(tp)) + } + add(")\n") + }) + + fileBuilder.addFunction(extFun.build()) + } + + fileBuilder.build().writeTo(outputDir) +} diff --git a/cache/bin/main/org/alter/game/util/DbHelper.kt b/cache/bin/main/org/alter/game/util/DbHelper.kt new file mode 100644 index 00000000..a3ae6006 --- /dev/null +++ b/cache/bin/main/org/alter/game/util/DbHelper.kt @@ -0,0 +1,269 @@ +package org.alter.game.util + +import dev.openrune.ServerCacheManager +import dev.openrune.definition.type.DBRowType +import dev.openrune.definition.type.DBColumnType +import dev.openrune.definition.util.VarType +import org.alter.game.util.vars.NumericBooleanVarType +import org.alter.game.util.vars.VarTypeImpl +import org.alter.rscm.RSCM.asRSCM +import org.alter.rscm.RSCM.requireRSCM +import org.alter.rscm.RSCMType +import java.util.concurrent.ConcurrentHashMap + +fun DbHelper.column(name: String, type: VarTypeImpl): V = + getNValue(name, type, 0) + +fun DbHelper.columnOptional(name: String, type: VarTypeImpl): V? = + getNValueOrNull(name, type, 0) + + +fun row(row: String) = DbHelper.row(row) + +/** + * Splits a single column into consecutive pairs. + * + * Example: + * column.values = [8, 35, 4, 30] + * returns [[8, 35], [4, 30]] + */ + +@Suppress("UNCHECKED_CAST") +fun DbHelper.multiColumn( + columnName: String, + vararg types: VarTypeImpl +): List { + val column = getColumn(columnName) + val values = column.column.values ?: return emptyList() + + require(types.isNotEmpty()) { "At least one VarTypeImpl must be provided" } + + return values.mapIndexed { i, raw -> + val type = + if (types.size == 1) types[0] + else types.getOrNull(i) + ?: throw ArrayIndexOutOfBoundsException( + "No VarTypeImpl supplied for index $i (types.size=${types.size})" + ) + + val value = column.get(i, type) + type.convertTo(value as K) + } +} + +fun DbHelper.multiColumnMixed(columnName: String, vararg types: VarTypeImpl<*, *>): List { + val column = try { + getColumn(columnName) + } catch (e: DbException.MissingColumn) { + return emptyList() + } catch (e: DbException) { + throw e + } catch (_: Exception) { + return emptyList() + } + + val values = column.column.values ?: return emptyList() + require(types.isNotEmpty()) { "At least one VarTypeImpl must be provided" } + + return values.mapIndexed { i, raw -> + val type = types[i] + val value = column.get(i, type as VarTypeImpl) + type.convertTo(value) + } +} + +@Suppress("UNCHECKED_CAST") +fun DbHelper.multiColumnOptional( + columnName: String, + vararg types: VarTypeImpl +): List { + val column = try { + getColumn(columnName) + } catch (e: DbException.MissingColumn) { + return emptyList() + } catch (e: DbException) { + throw e + } catch (_: Exception) { + return emptyList() + } + + val values = column.column.values ?: return emptyList() + require(types.isNotEmpty()) { "At least one VarTypeImpl must be provided" } + + return values.mapIndexed { i, raw -> + val type = if (types.size == 1) types[0] else types.getOrNull(i) + ?: return@mapIndexed null + + try { + val value = column.get(i, type) + type.convertTo(value as K) + } catch (e: DbException) { + throw e + } catch (_: Exception) { + null + } + } +} + +@Suppress("UNCHECKED_CAST") +class DbHelper(private val row: DBRowType) { + + val id: Int get() = row.id + val tableId: Int get() = row.tableId + + override fun toString(): String = + "DbHelper(id=$id, table=$tableId, columns=${row.columns.keys.joinToString()})" + + fun DbHelper.getNValueOrNull(name: String, type: VarTypeImpl, index: Int = 0): V? = + try { + val value = getColumn(name).get(index, type) + @Suppress("UNCHECKED_CAST") + if (type is NumericBooleanVarType) type.convertToAny(value) as V else type.convertTo(value as K) + } catch (_: Exception) { + null + } + + fun getNValue(name: String, type: VarTypeImpl, index: Int): V { + val value = getColumn(name).get(index, type) + @Suppress("UNCHECKED_CAST") + return if (type is NumericBooleanVarType) type.convertToAny(value) as V else type.convertTo(value as K) + } + + fun getColumn(name: String): Column { + requireRSCM(RSCMType.COLUMNS,name) + return getColumn(name.asRSCM() and 0xFFFF) + } + + fun getColumn(id: Int): Column { + val col = row.columns[id] ?: throw DbException.MissingColumn(tableId, id, id) + return Column(col, rowId = id, columnId = id, tableId = tableId) + } + + + class Column( + val column: DBColumnType, + private val rowId: Int, + val columnId: Int, + val tableId: Int + ) { + val types: Array get() = column.types + + val size: Int get() = column.values?.size ?: 0 + + fun get(index: Int = 0, type: VarTypeImpl): Any { + val values = column.values + ?: throw DbException.EmptyColumnValues(tableId, rowId, columnId) + + if (index !in values.indices) { + throw DbException.IndexOutOfRange(tableId, rowId, columnId, index, values.size) + } + + val actualType = types.getOrNull(index % types.size) + ?: throw DbException.MissingVarType(tableId, rowId, columnId, index) + + if (actualType != type.type) { + throw DbException.TypeMismatch( + tableId, rowId, columnId, expected = actualType, actual = type.type + ) + } + + return values[index] + } + + override fun toString(): String { + val vals = column.values?.joinToString(", ") ?: "empty" + return "Column(id=$columnId, row=$rowId, size=$size, values=[$vals])" + } + } + + companion object { + + fun table(table: String): List { + requireRSCM(RSCMType.TABLETYPES,table) + + return DbQueryCache.getTable(table) { + val tableId = table.asRSCM() + ServerCacheManager.getRows() + .asSequence() + .filter { it.value.tableId == tableId } + .map { DbHelper(it.value) } + .distinctBy { it.id } + .toList() + } + } + + fun dbFind(column: String, value: V, type: VarTypeImpl): List { + requireRSCM(RSCMType.COLUMNS,column) + + return DbQueryCache.getColumn(column, value, type) { + val tableName = "tables." + column.removePrefix("columns.").substringBefore(':') + val tableId = tableName.asRSCM() + val columnId = column.asRSCM() and 0xFFFF + + ServerCacheManager.getRows() + .asSequence() + .filter { it.value.tableId == tableId } + .filter { (_, row) -> + val col = row.columns[columnId] ?: return@filter false + val values = col.values ?: return@filter false + values.any { raw -> type.convertTo(raw as K) == value } + } + .map { (_, row) -> DbHelper(row) } + .distinctBy { it.id } + .toList() + } + } + + private fun load(rowId: Int): DbHelper = + ServerCacheManager.getDbrow(rowId)?.let(::DbHelper) + ?: throw DbException.MissingRow(rowId) + + fun row(ref: String): DbHelper = load(ref.asRSCM()) + fun row(rowId: Int): DbHelper = load(rowId) + } +} + +object DbQueryCache { + private val tableCache = ConcurrentHashMap>() + private val columnCache = ConcurrentHashMap>, List>() + + fun getTable(table: String, supplier: () -> List): List { + return tableCache.computeIfAbsent(table) { supplier() } + } + + fun getColumn(column: String, value: V, type: VarTypeImpl, supplier: () -> List): List { + val key = Triple(column, value as Any, type as VarTypeImpl<*, *>) + return columnCache.computeIfAbsent(key) { supplier() } + } + + fun clear() { + tableCache.clear() + columnCache.clear() + } +} + +sealed class DbException(message: String) : RuntimeException(message) { + + class MissingColumn(tableId: Int, rowId: Int, columnId: Int) : + DbException("Column $columnId not found in row $rowId (table $tableId)") + + class EmptyColumnValues( + tableId: Int, + rowId: Int, + columnId: Int + ) : DbException("No values found in column $columnId (row $rowId, table $tableId)") + + class IndexOutOfRange(tableId: Int, rowId: Int, columnId: Int, index: Int, max: Int) : + DbException("Index $index out of bounds (size=$max) in column $columnId (row $rowId, table $tableId)") + + class MissingVarType(tableId: Int, rowId: Int, columnId: Int, index: Int) : + DbException("No VarType available at index $index in column $columnId (row $rowId, table $tableId)") + + class TypeMismatch(tableId: Int, rowId: Int, columnId: Int, expected: VarType, actual: VarType) : + DbException("Type mismatch in table $tableId, row $rowId, column $columnId: expected $expected but found $actual") + + class MissingRow(rowId: Int) : + DbException("DBRow $rowId not found") + + +} \ No newline at end of file diff --git a/cache/bin/main/org/alter/game/util/EnumManager.kt b/cache/bin/main/org/alter/game/util/EnumManager.kt new file mode 100644 index 00000000..366c3f0f --- /dev/null +++ b/cache/bin/main/org/alter/game/util/EnumManager.kt @@ -0,0 +1,150 @@ +package org.alter.game.util + +import dev.openrune.ServerCacheManager +import dev.openrune.definition.type.EnumType +import dev.openrune.definition.util.BaseVarType +import dev.openrune.definition.util.VarType +import io.github.oshai.kotlinlogging.KotlinLogging +import org.alter.game.util.vars.VarTypeImpl +import org.alter.rscm.RSCM.asRSCM +import org.alter.rscm.RSCM.requireRSCM +import org.alter.rscm.RSCMType + +private val logger = KotlinLogging.logger {} + +/** + * Represents a typed key/value pair from an enum. + */ +data class EnumPair(val key: K, val value: V) + +/** + * Top-level helper to retrieve a type-safe list of enum entries by name. + * + * Example: + * ``` + * val entries = enum("enums.bone_data", ObjType, RowType) + * entries.forEach { (key, value) -> + * println("Key: $key, Value: $value") + * } + * ``` + */ +fun enum( + enumName: String, + keyType: VarTypeImpl, + valueType: VarTypeImpl +): List> = + EnumHelper.of(enumName).getEnum(keyType, valueType) + +fun enum( + enumName: Int, + keyType: VarTypeImpl, + valueType: VarTypeImpl +): List> = + EnumHelper.of(enumName).getEnum(keyType, valueType) + + + +fun enumKey( + enumName: String, + key: K, + keyType: VarTypeImpl<*, K>, + valueType: VarTypeImpl<*, V> +): V? = enum(enumName, keyType, valueType).firstOrNull { it.key == key }?.value + +/** + * Type-safe helper for working with an EnumType. + * + * Example: + * ``` + * val helper = EnumHelper.of("enums.bone_data") + * val entries = helper.getEnum(ObjType, RowType) + * val value = helper.getByKey("DRAGON_BONE", ObjType, RowType) + * val key = helper.getByValue(35, ObjType, RowType) + * ``` + */ +@Suppress("UNCHECKED_CAST") +class EnumHelper private constructor(val enum: EnumType) { + + val id: Int get() = enum.id + val keyType: VarType get() = enum.keyType + val valueType: VarType get() = enum.valueType + + override fun toString(): String = + "EnumHelper(id=$id, size=${enum.values.size}, keys=${enum.values.keys.joinToString()})" + + /** + * Returns a type-safe list of key/value pairs from the enum. + * + * Example: + * ``` + * val entries = helper.getEnum(ObjType, RowType) + * entries.forEach { (key, value) -> + * println("Key: $key, Value: $value") + * } + * ``` + */ + fun getEnum( + keyVarType: VarTypeImpl, + valueVarType: VarTypeImpl + ): List> { + val entries = enum.values.toList() + if (entries.isEmpty()) return emptyList() + + return entries.mapIndexed { index, (rawKey, rawValue) -> + val actualKeyType = enum.keyType + val actualValueType = enum.valueType + + if (actualKeyType != keyVarType.type) { + throw IllegalArgumentException( + "Type mismatch for key at index $index: expected '${keyVarType.type}', found '$actualKeyType'" + ) + } + + if (actualValueType != valueVarType.type) { + throw IllegalArgumentException( + "Type mismatch for value at index $index: expected '${valueVarType.type}', found '$actualValueType'" + ) + } + + val key: K1 = if (keyVarType.type.baseType == BaseVarType.STRING) { + rawKey as K1 + } else { + (rawKey.toIntOrNull() as K1?) + ?: throw IllegalArgumentException("Cannot convert key '$rawKey' to Int") + } + + val value: K2 = if (valueVarType.type.baseType == BaseVarType.STRING) { + rawValue as K2 + } else { + (rawValue.toString().toIntOrNull() as K2?) + ?: throw IllegalArgumentException("Cannot convert value '$rawValue' to Int") + } + + EnumPair(keyVarType.convertTo(key), valueVarType.convertTo(value)) + } + } + + companion object { + /** + * Load an EnumType from the server cache by name. + */ + + fun load(enum: Int): EnumType { + return ServerCacheManager.getEnum(enum) + ?: throw NoSuchElementException("Enum '$enum' not found") + } + + fun load(name: String): EnumType { + requireRSCM(RSCMType.ENUMS,name) + return ServerCacheManager.getEnum(name.asRSCM()) + ?: throw NoSuchElementException("Enum '$name' not found") + } + + /** + * Creates an [EnumHelper] from an enum name. + */ + fun of(name: String): EnumHelper = EnumHelper(load(name)) + + fun of(name: Int): EnumHelper = EnumHelper(load(name)) + } +} diff --git a/cache/bin/main/org/alter/game/util/vars/GenericStringVarType.kt b/cache/bin/main/org/alter/game/util/vars/GenericStringVarType.kt new file mode 100644 index 00000000..8c1c7ea3 --- /dev/null +++ b/cache/bin/main/org/alter/game/util/vars/GenericStringVarType.kt @@ -0,0 +1,19 @@ +package org.alter.game.util.vars + +import dev.openrune.definition.util.BaseVarType +import dev.openrune.definition.util.VarType + +abstract class GenericStringVarType( + protected val varType: VarType +) : StringVarType { + override val type: VarType get() = varType + override val char: Char get() = varType.ch + override val id: Int get() = varType.id + + override fun convertTo(variable: String) = variable + override fun convertFrom(variable: String) = variable +} + +internal interface StringVarType : VarTypeImpl { + override val baseVarType: BaseVarType get() = BaseVarType.STRING +} diff --git a/cache/bin/main/org/alter/game/util/vars/NumericBooleanVarType.kt b/cache/bin/main/org/alter/game/util/vars/NumericBooleanVarType.kt new file mode 100644 index 00000000..bf61abc7 --- /dev/null +++ b/cache/bin/main/org/alter/game/util/vars/NumericBooleanVarType.kt @@ -0,0 +1,24 @@ +package org.alter.game.util.vars + +import dev.openrune.definition.util.BaseVarType +import dev.openrune.definition.util.VarType + +abstract class NumericBooleanVarType( + protected val varType: VarType +) : IntegerVarType { + + override val type: VarType get() = varType + override val baseVarType: BaseVarType get() = BaseVarType.INTEGER + override val char: Char get() = varType.ch + override val id: Int get() = varType.id + + override fun convertTo(variable: Int): Boolean = variable != 0 + + fun convertToAny(variable: Any): Boolean = when (variable) { + is Number -> variable.toInt() != 0 + is String -> variable.toIntOrNull()?.let { it != 0 } ?: false + else -> false + } + + override fun convertFrom(variable: Boolean): Int = if (variable) 1 else 0 +} \ No newline at end of file diff --git a/cache/bin/main/org/alter/game/util/vars/NumericIntegerVarType.kt b/cache/bin/main/org/alter/game/util/vars/NumericIntegerVarType.kt new file mode 100644 index 00000000..cf278b5a --- /dev/null +++ b/cache/bin/main/org/alter/game/util/vars/NumericIntegerVarType.kt @@ -0,0 +1,21 @@ +package org.alter.game.util.vars + +import dev.openrune.definition.util.BaseVarType +import dev.openrune.definition.util.VarType + +abstract class NumericIntegerVarType( + protected val varType: VarType +) : IntegerVarType { + override val type: VarType get() = varType + override val char: Char get() = varType.ch + override val id: Int get() = varType.id + + + + override fun convertTo(variable: Int) = variable + override fun convertFrom(variable: Int) = variable +} + +internal interface IntegerVarType : VarTypeImpl { + override val baseVarType: BaseVarType get() = BaseVarType.INTEGER +} \ No newline at end of file diff --git a/cache/bin/main/org/alter/game/util/vars/NumericLongVarType.kt b/cache/bin/main/org/alter/game/util/vars/NumericLongVarType.kt new file mode 100644 index 00000000..f308b0c5 --- /dev/null +++ b/cache/bin/main/org/alter/game/util/vars/NumericLongVarType.kt @@ -0,0 +1,21 @@ +package org.alter.game.util.vars + +import dev.openrune.definition.util.BaseVarType +import dev.openrune.definition.util.VarType + +abstract class NumericLongVarType( + protected val varType: VarType +) : LongVarType { + + override val type: VarType get() = varType + override val char: Char get() = varType.ch + override val id: Int get() = varType.id + override val baseVarType: BaseVarType get() = BaseVarType.LONG + + override fun convertTo(variable: Long) = variable + override fun convertFrom(variable: Long) = variable +} + +internal interface LongVarType : VarTypeImpl { + override val baseVarType: BaseVarType get() = BaseVarType.LONG +} \ No newline at end of file diff --git a/cache/bin/main/org/alter/game/util/vars/VarTypeImpl.kt b/cache/bin/main/org/alter/game/util/vars/VarTypeImpl.kt new file mode 100644 index 00000000..2a73dc73 --- /dev/null +++ b/cache/bin/main/org/alter/game/util/vars/VarTypeImpl.kt @@ -0,0 +1,15 @@ +package org.alter.game.util.vars + +import dev.openrune.definition.util.BaseVarType +import dev.openrune.definition.util.VarType + +interface VarTypeImpl { + val char: Char + val id: Int + val type: VarType + val baseVarType: BaseVarType? + get() = type.baseType + + fun convertTo(variable: K): V + fun convertFrom(variable: V): K +} diff --git a/cache/bin/main/org/alter/game/util/vars/VarTypes.kt b/cache/bin/main/org/alter/game/util/vars/VarTypes.kt new file mode 100644 index 00000000..73d407f7 --- /dev/null +++ b/cache/bin/main/org/alter/game/util/vars/VarTypes.kt @@ -0,0 +1,32 @@ +package org.alter.game.util.vars + +import dev.openrune.definition.util.VarType + +data object IntType : NumericIntegerVarType(VarType.INT) +data object LocShapeType : NumericIntegerVarType(VarType.LOCSHAPE) +data object SynthType : NumericIntegerVarType(VarType.SYNTH) +data object BooleanType : NumericBooleanVarType(VarType.BOOLEAN) +data object StringType : GenericStringVarType(VarType.STRING) +data object MapElementType : NumericIntegerVarType(VarType.MAPELEMENT) +data object LongType : NumericLongVarType(VarType.LONG) +data object ComponentVarType : NumericIntegerVarType(VarType.COMPONENT) +data object ObjType : NumericIntegerVarType(VarType.OBJ) +data object NpcVarType : NumericIntegerVarType(VarType.NPC) +data object LocType : NumericIntegerVarType(VarType.LOC) +data object EnumVarType : NumericIntegerVarType(VarType.ENUM) +data object RowType : NumericIntegerVarType(VarType.DBROW) +data object TableVarType : NumericIntegerVarType(VarType.DBTABLE) +data object SeqType : NumericIntegerVarType(VarType.SEQ) +data object GraphicType : NumericIntegerVarType(VarType.GRAPHIC) +data object HeadBarType : NumericIntegerVarType(VarType.HEADBAR) +data object HitMarkType : NumericIntegerVarType(VarType.HITMARK) +data object CoordType : NumericIntegerVarType(VarType.COORDGRID) +data object StatType : NumericIntegerVarType(VarType.STAT) +data object CategoryType : NumericIntegerVarType(VarType.CATEGORY) +data object StructType : NumericIntegerVarType(VarType.STRUCT) +data object NamedObjType : NumericIntegerVarType(VarType.NAMEDOBJ) +data object IdkVarType : NumericIntegerVarType(VarType.IDKIT) +data object ModelType : NumericIntegerVarType(VarType.MODEL) +data object VarpVarType : NumericIntegerVarType(VarType.VARP) +data object MidiType : NumericIntegerVarType(VarType.MIDI) +data object InvVarType : NumericIntegerVarType(VarType.INV) \ No newline at end of file diff --git a/cache/bin/main/org/alter/gamevals/GameValAutoAssigner.kt b/cache/bin/main/org/alter/gamevals/GameValAutoAssigner.kt new file mode 100644 index 00000000..66f6743c --- /dev/null +++ b/cache/bin/main/org/alter/gamevals/GameValAutoAssigner.kt @@ -0,0 +1,143 @@ +package org.alter.gamevals + +import org.alter.rscm.RSCMType +import java.io.File + +/** + * Scans TOML and RSCM files for gamevals = -1, assigns next available IDs (preferring gaps near + * existing IDs in the same file), and rewrites the files. + */ +class GameValAutoAssigner( + private val mappings: Map>, + private val maxBaseID: Map, +) { + fun run(contentDir: File?, gamevalsDir: File?) { + val scanResult = scanForUnassigned(contentDir, gamevalsDir) + if (scanResult.unassigned.isEmpty()) return + + val replacements = assignIds(scanResult) + rewriteFiles(replacements) + } + + private data class ScanResult( + val usedIds: Map>, + val idsInSameFile: Map, MutableSet>, + val unassigned: List, + ) + + private data class UnassignedEntry( + val file: File, + val lineIndex: Int, + val line: String, + val table: String, + val key: String, + ) + + private fun scanForUnassigned(contentDir: File?, gamevalsDir: File?): ScanResult { + val usedIds = mutableMapOf>() + val idsInSameFile = mutableMapOf, MutableSet>() + val unassigned = mutableListOf() + + fun recordEntry(file: File, lineIndex: Int, line: String, table: String, key: String, value: Int) { + val tableUsed = usedIds.getOrPut(table) { + mutableSetOf().also { mappings[table]?.values?.forEach(it::add) } + } + if (value == -1) { + idsInSameFile.getOrPut(file to table) { mutableSetOf() } + unassigned.add(UnassignedEntry(file, lineIndex, line, table, key)) + } else { + tableUsed.add(value) + idsInSameFile.getOrPut(file to table) { mutableSetOf() }.add(value) + } + } + + contentDir?.walk()?.filter { it.isFile && it.name == "gamevals.toml" }?.forEach { file -> + var currentTable: String? = null + file.readLines().forEachIndexed { index, line -> + GAMEVALS_SECTION_REGEX.find(line.trim())?.let { + currentTable = it.groupValues[1].takeIf { t -> t in RSCMType.RSCM_PREFIXES } + } + if (currentTable != null && line.contains("=")) { + parseKeyValue(line)?.let { (key, value) -> + recordEntry(file, index, line, currentTable!!, key, value) + } + } + } + } + + gamevalsDir?.walk()?.filter { it.isFile }?.forEach { file -> + val table = file.nameWithoutExtension.takeIf { it in RSCMType.RSCM_PREFIXES } ?: return@forEach + file.readLines().forEachIndexed { index, line -> + if (line.isNotBlank()) { + parseKeyValue(line)?.let { (key, value) -> + recordEntry(file, index, line, table, key, value) + } + } + } + } + + return ScanResult(usedIds, idsInSameFile, unassigned) + } + + private fun parseKeyValue(line: String): Pair? { + val trimmed = line.trim() + if (trimmed.isEmpty() || trimmed.startsWith("#") || trimmed.startsWith("[")) return null + return when { + KEY_VALUE_REGEX.matches(trimmed) -> { + val m = KEY_VALUE_REGEX.matchEntire(trimmed)!! + m.groupValues[1].trim() to m.groupValues[2].toInt() + } + KEY_SUBPROP_REGEX.matches(trimmed) -> { + val m = KEY_SUBPROP_REGEX.matchEntire(trimmed)!! + m.groupValues[1].trim() to m.groupValues[3].toInt() + } + else -> null + } + } + + private fun assignIds(scanResult: ScanResult): Map>> { + val (usedIds, idsInSameFile, unassigned) = scanResult + val unassignedCount = unassigned.groupingBy { it.file to it.table }.eachCount() + val replacements = mutableMapOf>>() + + for (entry in unassigned.sortedWith(compareBy({ it.file.absolutePath }, { it.lineIndex }))) { + val tableUsed = usedIds[entry.table]!! + val floor = maxOf(MIN_ID, (maxBaseID[entry.table] ?: -1) + 1) + val sameFileIds = idsInSameFile[entry.file to entry.table].orEmpty().filter { it >= floor } + + val id = when { + sameFileIds.isNotEmpty() -> { + val (minInFile, maxInFile) = sameFileIds.minOrNull()!! to sameFileIds.maxOrNull()!! + val count = unassignedCount[entry.file to entry.table] ?: 1 + val gapLo = maxOf(floor, minInFile - count) + (gapLo..minInFile - 1).firstOrNull { it !in tableUsed } + ?: (maxInFile + 1..Int.MAX_VALUE).firstOrNull { it !in tableUsed } + ?: (floor..Int.MAX_VALUE).first { it !in tableUsed } + } + else -> (floor..Int.MAX_VALUE).first { it !in tableUsed } + } + tableUsed.add(id) + replacements.getOrPut(entry.file) { mutableListOf() } + .add(entry.lineIndex to entry.line.replaceFirst(NEGATIVE_ONE_REGEX, "= $id")) + } + return replacements + } + + private fun rewriteFiles(replacements: Map>>) { + for ((file, lineReplacements) in replacements) { + val lines = file.readLines().toMutableList() + lineReplacements.forEach { (lineIndex, newLine) -> + if (lineIndex < lines.size) lines[lineIndex] = newLine + } + file.writeText(lines.joinToString("\n")) + } + } + + private companion object { + const val MIN_ID = 65536 // 64k floor + val KEY_VALUE_REGEX = Regex("^([^=]+)=\\s*(-?\\d+)\\s*$") + val KEY_SUBPROP_REGEX = Regex("^([^:]+):([^=]+)=\\s*(-?\\d+)\\s*$") + val GAMEVALS_SECTION_REGEX = Regex("^\\s*\\[gamevals\\.([^.\\]]+)\\]\\s*$") + val NEGATIVE_ONE_REGEX = Regex("=\\s*-1\\s*$") + } +} diff --git a/cache/bin/main/org/alter/gamevals/GameValProvider.kt b/cache/bin/main/org/alter/gamevals/GameValProvider.kt new file mode 100644 index 00000000..ebd1f0bc --- /dev/null +++ b/cache/bin/main/org/alter/gamevals/GameValProvider.kt @@ -0,0 +1,188 @@ +package org.alter.gamevals + +import com.fasterxml.jackson.core.type.TypeReference +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.dataformat.toml.TomlFactory +import dev.openrune.definition.constants.MappingProvider +import dev.openrune.definition.constants.use +import org.alter.rscm.RSCMType +import java.io.DataInputStream +import java.io.File +import java.io.FileInputStream +import java.nio.file.Paths +import kotlin.io.use + +class GameValProvider : MappingProvider { + + private val tomlMapper = ObjectMapper(TomlFactory()).findAndRegisterModules() + override val mappings: MutableMap> = mutableMapOf() + val maxBaseID: MutableMap = mutableMapOf() + + /** When true, scans for -1 gamevals and auto-assigns non-conflicting IDs before loading. */ + var autoAssignIds: Boolean = false + + companion object { + fun load(rootDir: String = "../", autoAssignIds: Boolean = false) { + val provider = GameValProvider() + provider.autoAssignIds = autoAssignIds + provider.use( + Paths.get("${rootDir}data", "cfg", "gamevals-binary", "gamevals.dat").toFile(), + Paths.get("${rootDir}data", "cfg", "gamevals-binary", "gamevals_columns.dat").toFile(), + Paths.get("${rootDir}content", "src", "main", "resources", "org", "alter").toFile(), + Paths.get("${rootDir}data", "cfg", "gamevals").toFile() + ) + } + } + + override fun load(vararg files: File) { + require(files.size >= 2) { "Expected at least two files for loading: gamevals.dat and gamevals_columns.dat" } + + decodeGameValDat(files[0]) + decodeGameValDat(files[1]) + + if (autoAssignIds) { + val contentDir = files.getOrNull(2)?.takeIf { it.exists() } + val gamevalsDir = files.getOrNull(3)?.takeIf { it.exists() } + if (contentDir != null || gamevalsDir != null) { + GameValAutoAssigner(mappings, maxBaseID).run(contentDir, gamevalsDir) + } + } + + // Load TOML + files.getOrNull(2)?.takeIf { it.exists() }?.walk() + ?.filter { it.isFile && it.name == "gamevals.toml" } + ?.forEach { processGameValToml(it) } + + // Load RSCM directories + files.drop(3).forEach { dir -> + require(dir.isDirectory) { "Expected a directory for RSCM mappings, got file: ${dir.absolutePath}" } + dir.walk().filter { it.isFile }.forEach { processRSCMFile(it) } + } + } + + private fun processGameValToml(file: File) { + val root: Map = tomlMapper.readValue(file, object : TypeReference>() {}) + val gamevalsSection = root["gamevals"] as? Map<*, *> ?: return + + gamevalsSection.forEach { (tableNameAny, tableValuesAny) -> + val tableName = tableNameAny as? String ?: return@forEach + val tableValues = tableValuesAny as? Map<*, *> ?: return@forEach + + require(tableName in RSCMType.RSCM_PREFIXES) { + "Invalid TOML table '$tableName' in ${file.name}. Expected one of: ${RSCMType.RSCM_PREFIXES}" + } + + mappings.putIfAbsent(tableName, mutableMapOf()) + + tableValues.forEach { (k, v) -> + val key = k.toString() + val value = when (v) { + is Number -> v.toInt() + is String -> v.toIntOrNull() ?: return@forEach + else -> return@forEach + } + + val (parsedKey, parsedValue) = parseRSCMV2Line("$key=$value", 0) + putMapping(tableName, parsedKey, parsedValue, file.name) + } + } + } + + private fun processRSCMFile(file: File) { + val table = file.nameWithoutExtension + val lines = file.readLines().filter { it.isNotBlank() } + if (lines.isEmpty()) return + + mappings.putIfAbsent(table, mutableMapOf()) + + lines.forEachIndexed { lineNumber, line -> + try { + val (key, value) = parseRSCMV2Line(line, lineNumber + 1) + putMapping(table, key, value, file.name) + } catch (e: Exception) { + throw IllegalArgumentException("Failed to parse line ${lineNumber + 1} in ${file.name}: '$line'", e) + } + } + } + + private fun putMapping(table: String, key: String, value: Int, file: String) { + val tableMappings = mappings[table] + ?: throw IllegalArgumentException("Table '$table' does not exist in mappings.") + + val qualifiedKey = "$table.$key" + + val maxID = maxBaseID[table] ?: -1 + require(value > maxID) { + "Custom value '$value' for key '$key' in table '$table must exceed the current max base ID $maxID. " + + "Cannot override existing osrs IDs." + } + + if (tableMappings.containsKey(qualifiedKey)) { + throw IllegalArgumentException( + "Mapping conflict in table '$table: key '$key' already exists. Keys must be unique." + ) + } + + tableMappings.entries.find { it.value == value }?.let { existing -> + throw IllegalArgumentException( + "Mapping conflict in table '$table: value '$value' is already mapped to key '${existing.key}'. Values must be unique." + ) + } + + tableMappings[qualifiedKey] = value + } + + private fun parseRSCMV2Line(line: String, lineNumber: Int): Pair = when { + line.contains("=") -> { + val parts = line.split("=") + require(parts.size == 2) { "Invalid line format at $lineNumber: '$line'. Expected 'key=value'" } + parts[0].trim() to parts[1].trim().toInt() + } + line.contains(":") -> { + val parts = line.split(":") + require(parts.size == 2) { "Invalid sub-property format at $lineNumber: '$line'. Expected 'key:subprop=value'" } + val key = parts[0].trim() + val valueParts = parts[1].trim().split("=") + require(valueParts.size == 2) { "Invalid sub-property value format at $lineNumber: '${parts[1]}'" } + key to valueParts[1].trim().toInt() + } + else -> throw IllegalArgumentException( + "Invalid line format at $lineNumber: '$line'. Expected 'key=value' or 'key:subprop=value'" + ) + } + + private fun decodeGameValDat(datFile: File) { + DataInputStream(FileInputStream(datFile)).use { input -> + val tableCount = input.readInt() + repeat(tableCount) { + val nameLength = input.readShort().toInt() + val nameBytes = ByteArray(nameLength) + input.readFully(nameBytes) + val tableName = String(nameBytes, Charsets.UTF_8) + + val itemCount = input.readInt() + mappings.putIfAbsent(tableName, mutableMapOf()) + + repeat(itemCount) { + val itemLength = input.readShort().toInt() + val itemBytes = ByteArray(itemLength) + input.readFully(itemBytes) + val itemString = String(itemBytes, Charsets.UTF_8) + + try { + val (key, value) = parseRSCMV2Line(itemString, 0) + mappings[tableName]?.putIfAbsent("$tableName.$key", value) + } catch (e: Exception) { + throw IllegalArgumentException( + "Failed to parse item in table '$tableName' from ${datFile.name}: '$itemString'", e + ) + } + } + + maxBaseID[tableName] = mappings[tableName]?.values?.maxOrNull() ?: -1 + } + } + } + + override fun getSupportedExtensions(): List = listOf(".rscm", ".rscm2") +} \ No newline at end of file diff --git a/cache/bin/main/org/alter/gamevals/GamevalDumper.kt b/cache/bin/main/org/alter/gamevals/GamevalDumper.kt new file mode 100644 index 00000000..4aadd6b7 --- /dev/null +++ b/cache/bin/main/org/alter/gamevals/GamevalDumper.kt @@ -0,0 +1,92 @@ +package org.alter.gamevals + +import dev.openrune.cache.gameval.GameValHandler +import dev.openrune.cache.gameval.GameValHandler.elementAs +import dev.openrune.cache.gameval.impl.Interface +import dev.openrune.cache.gameval.impl.Sprite +import dev.openrune.cache.gameval.impl.Table +import dev.openrune.definition.GameValGroupTypes +import dev.openrune.filesystem.Cache +import java.io.DataOutputStream +import java.io.File +import java.io.FileOutputStream + +object GamevalDumper { + + fun dumpGamevals(cache: Cache, rev: Int) { + val gamevals = mutableMapOf>() + + GameValGroupTypes.entries.forEach { groupType -> + val elements = GameValHandler.readGameVal(groupType, cache = cache, rev) + + when (groupType) { + GameValGroupTypes.SPRITETYPES -> { + val sprites = elements.mapNotNull { it.elementAs()?.let { e -> + if (e.index == -1) "${e.name}=${e.id}" else "${e.name}:${e.index}=${e.id}" + } } + gamevals["sprites"] = sprites + } + + GameValGroupTypes.IFTYPES_V2 -> { + val interfaces = elements.mapNotNull { it.elementAs()?.let { iface -> "${iface.name}=${iface.id}" } } + + val components = elements.flatMap { elem -> + elem.elementAs()?.components?.map { comp -> + "${elem.elementAs()?.name}:${comp.name}=${comp.packed}" + } ?: emptyList() + } + + gamevals["interfaces"] = interfaces + gamevals["components"] = components + } + + GameValGroupTypes.IFTYPES -> Unit + + else -> { + val key = groupType.groupName.replace("dbtables", "tables") + gamevals[key] = elements.map { "${it.name}=${it.id}" } + } + } + } + + if (!File("../data/cfg/gamevals-binary/").exists()) { + File("../data/cfg/gamevals-binary/").mkdirs() + } + + encodeGameValDat("../data/cfg/gamevals-binary/gamevals.dat", gamevals) + dumpCols(cache, rev) + } + + fun dumpCols(cache: Cache, rev: Int) { + val elements = GameValHandler.readGameVal(GameValGroupTypes.TABLETYPES, cache = cache, rev) + val data = mutableListOf() + + elements.forEach { gameValElement -> + val table = gameValElement.elementAs
() ?: return@forEach + table.columns.forEach { column -> + data.add("${table.name}:${column.name}=${(gameValElement.id shl 16) or column.id}") + } + } + + encodeGameValDat("../data/cfg/gamevals-binary/gamevals_columns.dat", mapOf("columns" to data)) + } + + private fun encodeGameValDat(output: String, tables: Map>) { + DataOutputStream(FileOutputStream(output)).use { out -> + out.writeInt(tables.size) + + tables.forEach { (name, items) -> + val nameBytes = name.toByteArray(Charsets.UTF_8) + out.writeShort(nameBytes.size) + out.write(nameBytes) + + out.writeInt(items.size) + items.forEach { entry -> + val bytes = entry.toByteArray(Charsets.UTF_8) + out.writeShort(bytes.size) + out.write(bytes) + } + } + } + } +} \ No newline at end of file diff --git a/cache/bin/main/org/alter/impl/GameframeTable.kt b/cache/bin/main/org/alter/impl/GameframeTable.kt new file mode 100644 index 00000000..ddf17baa --- /dev/null +++ b/cache/bin/main/org/alter/impl/GameframeTable.kt @@ -0,0 +1,69 @@ +package org.alter.impl + +import dev.openrune.definition.dbtables.dbTable +import dev.openrune.definition.util.VarType + +object GameframeTable { + + const val COL_TOP_LEVEL = 0 + const val COL_MAPPINGS = 1 + const val COL_CLIENT_MODE = 2 + const val COL_RESIZABLE = 3 + const val COL_IS_DEFAULT = 4 + const val COL_STONE_ARRANGEMENT = 5 + + fun gameframe() = dbTable("tables.gameframe", serverOnly = true) { + + + column("toplevel", COL_TOP_LEVEL, VarType.INT) + column("mappings", COL_MAPPINGS, VarType.ENUM) + column("client_mode", COL_CLIENT_MODE, VarType.INT) + column("resizable", COL_RESIZABLE, VarType.BOOLEAN) + column("default", COL_IS_DEFAULT, VarType.BOOLEAN) + column("stone_arrangement", COL_STONE_ARRANGEMENT, VarType.BOOLEAN) + + row("dbrows.gameframe_toplevel") { + columnRSCM(COL_TOP_LEVEL,"interfaces.toplevel") + columnRSCM(COL_MAPPINGS,"enums.fixed_pane_redirect") + column(COL_CLIENT_MODE,0) + + column(COL_RESIZABLE,false) + column(COL_IS_DEFAULT,true) + column(COL_STONE_ARRANGEMENT,false) + } + + row("dbrows.gameframe_osrs_stretch") { + columnRSCM(COL_TOP_LEVEL,"interfaces.toplevel_osrs_stretch") + columnRSCM(COL_MAPPINGS,"enums.resizable_basic_pane_redirect") + column(COL_CLIENT_MODE,1) + + column(COL_RESIZABLE,true) + column(COL_IS_DEFAULT,false) + column(COL_STONE_ARRANGEMENT,false) + } + + row("dbrows.gameframe_pre_eoc") { + columnRSCM(COL_TOP_LEVEL,"interfaces.toplevel_pre_eoc") + columnRSCM(COL_MAPPINGS,"enums.side_panels_resizable_pane_redirect") + column(COL_CLIENT_MODE,2) + + column(COL_RESIZABLE,true) + column(COL_IS_DEFAULT,false) + column(COL_STONE_ARRANGEMENT,true) + } + + row("dbrows.gameframe_fullscreen") { + columnRSCM(COL_TOP_LEVEL,"interfaces.toplevel_display") + columnRSCM(COL_MAPPINGS,"enums.fullscreen_pane") + column(COL_CLIENT_MODE,2) + + column(COL_RESIZABLE,true) + column(COL_IS_DEFAULT,false) + column(COL_STONE_ARRANGEMENT,true) + } + + + + } + +} \ No newline at end of file diff --git a/cache/bin/main/org/alter/impl/StatComponents.kt b/cache/bin/main/org/alter/impl/StatComponents.kt new file mode 100644 index 00000000..66e2de24 --- /dev/null +++ b/cache/bin/main/org/alter/impl/StatComponents.kt @@ -0,0 +1,60 @@ +package org.alter.impl + +import dev.openrune.definition.dbtables.dbTable +import dev.openrune.definition.util.VarType + +data class StatRow( + val rowName: String, + val componentId: String, + val statString: String, + val bit: Int +) + +object StatComponents { + + const val COL_COMPONENT = 0 + const val COL_STAT = 1 + const val COL_BIT = 2 + + fun statsComponents() = dbTable("tables.stat_components", serverOnly = true) { + + column("component", COL_COMPONENT, VarType.COMPONENT) + column("stat", COL_STAT, VarType.STAT) + column("bit", COL_BIT, VarType.INT) + + val skillsWithBits = listOf( + StatRow("dbrows.agility_stat", "components.stats:agility", "stats.agility", 8), + StatRow("dbrows.attack_stat", "components.stats:attack", "stats.attack", 1), + StatRow("dbrows.construction_stat", "components.stats:construction", "stats.construction", 22), + StatRow("dbrows.cooking_stat", "components.stats:cooking", "stats.cooking", 16), + StatRow("dbrows.crafting_stat", "components.stats:crafting", "stats.crafting", 11), + StatRow("dbrows.defence_stat", "components.stats:defence", "stats.defence", 5), + StatRow("dbrows.farming_stat", "components.stats:farming", "stats.farming", 21), + StatRow("dbrows.firemaking_stat", "components.stats:firemaking", "stats.firemaking", 17), + StatRow("dbrows.fishing_stat", "components.stats:fishing", "stats.fishing", 15), + StatRow("dbrows.fletching_stat", "components.stats:fletching", "stats.fletching", 19), + StatRow("dbrows.herblore_stat", "components.stats:herblore", "stats.herblore", 9), + StatRow("dbrows.hitpoints_stat", "components.stats:hitpoints", "stats.hitpoints", 6), + StatRow("dbrows.hunter_stat", "components.stats:hunter", "stats.hunter", 23), + StatRow("dbrows.magic_stat", "components.stats:magic", "stats.magic", 4), + StatRow("dbrows.mining_stat", "components.stats:mining", "stats.mining", 13), + StatRow("dbrows.prayer_stat", "components.stats:prayer", "stats.prayer", 7), + StatRow("dbrows.ranged_stat", "components.stats:ranged", "stats.ranged", 3), + StatRow("dbrows.runecraft_stat", "components.stats:runecraft", "stats.runecraft", 12), + StatRow("dbrows.slayer_stat", "components.stats:slayer", "stats.slayer", 20), + StatRow("dbrows.smithing_stat", "components.stats:smithing", "stats.smithing", 14), + StatRow("dbrows.strength_stat", "components.stats:strength", "stats.strength", 2), + StatRow("dbrows.thieving_stat", "components.stats:thieving", "stats.thieving", 10), + StatRow("dbrows.woodcutting_stat", "components.stats:woodcutting", "stats.woodcutting", 18), + StatRow("dbrows.sailing_stat", "components.stats:sailing", "stats.sailing", 24) + ) + + skillsWithBits.forEach { row -> + row(row.rowName) { + columnRSCM(COL_COMPONENT, row.componentId) + columnRSCM(COL_STAT, row.statString) + column(COL_BIT, row.bit) + } + } + } +} \ No newline at end of file diff --git a/cache/bin/main/org/alter/impl/misc/FoodTable.kt b/cache/bin/main/org/alter/impl/misc/FoodTable.kt new file mode 100644 index 00000000..eb39907b --- /dev/null +++ b/cache/bin/main/org/alter/impl/misc/FoodTable.kt @@ -0,0 +1,522 @@ +package org.alter.impl.misc + +import dev.openrune.cache.VARBIT +import dev.openrune.definition.dbtables.dbTable +import dev.openrune.definition.util.VarType + +enum class Food( + vararg val items: String, + val heal: Int, + val overheal: Boolean = false, + val comboFood: Boolean = false, + val hasEffect: Boolean = false, + val eatDelay: List = listOf(), + val combatDelay: List = listOf(), + val dbRowId: String +) { + SHRIMPS("items.shrimp", heal = 3, dbRowId = "dbrows.shrimps_food"), + COOKED_CHICKEN("items.cooked_chicken", heal = 3, dbRowId = "dbrows.cooked_chicken_food"), + COOKED_MEAT("items.cooked_meat", heal = 3, dbRowId = "dbrows.cooked_meat_food"), + BREAD("items.bread", heal = 5, dbRowId = "dbrows.bread_food"), + HERRING("items.herring", heal = 5, dbRowId = "dbrows.herring_food"), + MACKEREL("items.mackerel", heal = 6, dbRowId = "dbrows.mackerel_food"), + TROUT("items.trout", heal = 7, dbRowId = "dbrows.trout_food"), + PIKE("items.pike", heal = 8, dbRowId = "dbrows.pike_food"), + PEACH("items.peach", heal = 8, dbRowId = "dbrows.peach_food"), + SALMON("items.salmon", heal = 9, dbRowId = "dbrows.salmon_food"), + TUNA("items.tuna", heal = 10, dbRowId = "dbrows.tuna_food"), + JUG_OF_WINE("items.jug_wine", heal = 11, hasEffect = true, dbRowId = "dbrows.jug_of_wine_food"), + LOBSTER("items.lobster", heal = 12, dbRowId = "dbrows.lobster_food"), + BASS("items.bass", heal = 13, dbRowId = "dbrows.bass_food"), + SWORDFISH("items.swordfish", heal = 14, dbRowId = "dbrows.swordfish_food"), + IXCOZTIC_WHITE("items.ixcoztic_white", heal = 16, hasEffect = true, dbRowId = "dbrows.ixcoztic_white_food"), + POTATO_WITH_CHEESE("items.potato_cheese", heal = 16, dbRowId = "dbrows.potato_with_cheese_food"), + MONKFISH("items.monkfish", heal = 16, dbRowId = "dbrows.monkfish_food"), + CURRY("items.curry", "items.bowl_empty", heal = 19, dbRowId = "dbrows.curry_food"), + COOKED_PYRE_FOX("items.curry", heal = 11, dbRowId = "dbrows.cooked_pyre_fox_food"), + SHARK("items.shark", heal = 20, dbRowId = "dbrows.shark_food"), + SEA_TURTLE("items.seaturtle", heal = 21, dbRowId = "dbrows.sea_turtle_food"), + MANTA_RAY("items.mantaray", heal = 22, dbRowId = "dbrows.manta_ray_food"), + TUNA_POTATO("items.potato_tuna+sweetcorn", heal = 22, dbRowId = "dbrows.tuna_potato_food"), + DARK_CRAB("items.dark_crab", heal = 22, dbRowId = "dbrows.dark_crab_food"), + ANGLERFISH("items.anglerfish", heal = -1, overheal = true, dbRowId = "dbrows.anglerfish_food"), + ONION("items.onion", heal = 1, dbRowId = "dbrows.onion_food"), + + // Cakes + CAKE( + "items.cake", + "items.partial_cake", + "items.cake_slice", + heal = 4, + eatDelay = listOf(2, 2, 3), + combatDelay = listOf(2, 2, 3), + dbRowId = "dbrows.cake_food" + ), + CHOCOLATE_CAKE( + "items.chocolate_cake", + "items.partial_chocolate_cake", + "items.chocolate_slice", + heal = 5, + eatDelay = listOf(2, 2, 3), + combatDelay = listOf(2, 2, 3), + dbRowId = "dbrows.chocolate_cake_food" + ), + + // Pies + REDBERRY_PIE( + "items.redberry_pie", + "items.half_a_redberry_pie", + "items.piedish", + heal = 5, + eatDelay = listOf(1, 2), + combatDelay = listOf(1, 2), + dbRowId = "dbrows.redberry_pie_food" + ), + MEAT_PIE( + "items.meat_pie", + "items.half_a_meat_pie", + "items.piedish", + heal = 6, + eatDelay = listOf(1, 2), + combatDelay = listOf(1, 2), + dbRowId = "dbrows.meat_pie_food" + ), + GARDEN_PIE( + "items.garden_pie", + "items.half_garden_pie", + "items.piedish", + heal = 6, + eatDelay = listOf(1, 1), + combatDelay = listOf(1, 1), + hasEffect = true, + dbRowId = "dbrows.garden_pie_food" + ), + FISH_PIE( + "items.fish_pie", + "items.half_fish_pie", + "items.piedish", + heal = 6, + eatDelay = listOf(1, 1), + combatDelay = listOf(1, 1), + hasEffect = true, + dbRowId = "dbrows.fish_pie_food" + ), + APPLE_PIE( + "items.apple_pie", + "items.half_an_apple_pie", + "items.piedish", + heal = 7, + eatDelay = listOf(1, 2), + combatDelay = listOf(1, 2), + dbRowId = "dbrows.apple_pie_food" + ), + BOTANICAL_PIE( + "items.botanical_pie", + "items.half_botanical_pie", + "items.piedish", + heal = 7, + eatDelay = listOf(1, 1), + combatDelay = listOf(1, 1), + hasEffect = true, + dbRowId = "dbrows.botanical_pie_food" + ), + MUSHROOM_PIE( + "items.mushroom_pie", + "items.half_mushroom_pie", + "items.piedish", + heal = 8, + eatDelay = listOf(1, 1), + combatDelay = listOf(1, 1), + hasEffect = true, + dbRowId = "dbrows.mushroom_pie_food" + ), + ADMIRAL_PIE( + "items.admiral_pie", + "items.half_admiral_pie", + "items.piedish", + heal = 8, + eatDelay = listOf(1, 1), + combatDelay = listOf(1, 1), + hasEffect = true, + dbRowId = "dbrows.admiral_pie_food" + ), + + // Pizzas + PLAIN_PIZZA( + "items.plain_pizza", + "items.half_plain_pizza", + heal = 3, + eatDelay = listOf(1, 2), + combatDelay = listOf(3), + dbRowId = "dbrows.plain_pizza_food" + ), + MEAT_PIZZA( + "items.meat_pizza", + "items.half_meat_pizza", + heal = 3, + eatDelay = listOf(1, 2), + combatDelay = listOf(3), + dbRowId = "dbrows.meat_pizza_food" + ), + ANCHOVY_PIZZA( + "items.anchovie_pizza", + "items.half_anchovie_pizza", + heal = 2, + eatDelay = listOf(1, 2), + combatDelay = listOf(3), + dbRowId = "dbrows.anchovy_pizza_food" + ), + DRAGONFRUIT_PIE( + "items.dragonfruit_pie", + "items.half_dragonfruit_pie", + heal = 10, + eatDelay = listOf(1, 1), + combatDelay = listOf(1, 1), + hasEffect = true, + dbRowId = "dbrows.dragonfruit_pie_food" + ), + PINEAPPLE_PIZZA( + "items.pineapple_pizza", + "items.half_pineapple_pizza", + heal = 11, + eatDelay = listOf(1, 2), + combatDelay = listOf(3), + dbRowId = "dbrows.pineapple_pizza_food" + ), + WILD_PIE( + "items.wild_pie", + "items.half_wild_pie", + heal = 11, + eatDelay = listOf(1, 1), + combatDelay = listOf(1, 1), + hasEffect = true, + dbRowId = "dbrows.wild_pie_food" + ), + SUMMER_PIE( + "items.summer_pie", + "items.half_summer_pie", + heal = 11, + eatDelay = listOf(1, 1), + combatDelay = listOf(1, 1), + hasEffect = true, + dbRowId = "dbrows.summer_pie_food" + ), + + // Crunchies (combo foods) + TOAD_CRUNCHIES( + "items.toad_crunchies", + heal = 8, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.toad_crunchies_food" + ), + PREMADE_TD_CRUNCH( + "items.premade_toad_crunchies", + heal = 8, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.premade_td_crunch_food" + ), + SPICY_CRUNCHIES( + "items.spicy_crunchies", + heal = 8, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.spicy_crunchies_food" + ), + PREMADE_SY_CRUNCH( + "items.premade_spicy_crunchies", + heal = 8, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.premade_sy_crunch_food" + ), + WORM_CRUNCHIES( + "items.worm_crunchies", + heal = 8, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.worm_crunchies_food" + ), + PREMADE_WM_CRUN( + "items.premade_worm_crunchies", + heal = 8, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.premade_wm_crun_food" + ), + CHOCCHIP_CRUNCHIES( + "items.chocchip_crunchies", + heal = 7, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.chocchip_crunchies_food" + ), + PREMADE_CH_CRUNCH( + "items.premade_chocchip_crunchies", + heal = 7, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.premade_ch_crunch_food" + ), + + // Batta + FRUIT_BATTA( + "items.fruit_batta", + heal = 11, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.fruit_batta_food" + ), + PREMADE_FRT_BATTA( + "items.premade_fruit_batta", + heal = 11, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.premade_frt_batta_food" + ), + TOAD_BATTA( + "items.toad_batta", + heal = 11, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.toad_batta_food" + ), + PREMADE_TD_BATTA( + "items.premade_toad_batta", + heal = 11, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.premade_td_batta_food" + ), + WORM_BATTA( + "items.worm_batta", + heal = 2, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.worm_batta_food" + ), + PREMADE_WM_BATTA( + "items.premade_worm_batta", + heal = 11, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.premade_wm_batta_food" + ), + VEGETABLE_BATTA( + "items.vegetable_batta", + heal = 11, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.vegetable_batta_food" + ), + PREMADE_VEG_BATTA( + "items.premade_vegetable_batta", + heal = 11, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.premade_veg_batta_food" + ), + CHEESE_TOM_BATTA( + "items.cheese+tom_batta", + heal = 11, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.cheese_tom_batta_food" + ), + PREMADE_CT_BATTA( + "items.premade_cheese+tom_batta", + heal = 11, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.premade_ct_batta_food" + ), + + // Special combo foods + WORM_HOLE( + "items.worm_hole", + heal = 12, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.worm_hole_food" + ), + PREMADE_WORM_HOLE( + "items.premade_worm_hole", + heal = 12, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.premade_worm_hole_food" + ), + VEG_BALL( + "items.veg_ball", + heal = 12, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.veg_ball_food" + ), + PREMADE_VEG_BALL( + "items.premade_veg_ball", + heal = 12, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.premade_veg_ball_food" + ), + CHOCOLATE_BOMB( + "items.chocolate_bomb", + heal = 15, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.chocolate_bomb_food" + ), + PREMADE_CHOC_BOMB( + "items.premade_chocolate_bomb", + heal = 15, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.premade_choc_bomb_food" + ), + TANGLED_TOADS_LEGS( + "items.tangled_toads_legs", + heal = 15, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.tangled_toads_legs_food" + ), + PREMADE_TTL( + "items.premade_tangled_toads_legs", + heal = 15, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.premade_ttl_food" + ), + TOADS_LEGS( + "items.toads_legs", + heal = 3, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.toads_legs_food" + ), + CRYSTAL_PADDLEFISH( + "items.gauntlet_combo_food", + heal = 16, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.crystal_paddlefish_food" + ), + CORRUPTED_PADDLEFISH( + "items.gauntlet_combo_food_hm", + heal = 16, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.corrupted_paddlefish_food" + ), + COOKED_KARAMBWAN( + "items.tbwt_cooked_karambwan", + heal = 18, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.cooked_karambwan_food" + ), + BLIGHTED_KARAMBWAN( + "items.blighted_karambwan", + heal = 18, + eatDelay = listOf(2), + combatDelay = listOf(3), + comboFood = true, + dbRowId = "dbrows.blighted_karambwan_food" + ), + + // Blighted and other special foods + BLIGHTED_MANTA_RAY("items.blighted_mantaray", heal = 22, dbRowId = "dbrows.blighted_manta_ray_food"), + BLIGHTED_ANGLERFISH( + "items.blighted_anglerfish", + heal = -1, + overheal = true, + dbRowId = "dbrows.blighted_anglerfish_food" + ), + SWEETS("items.trail_sweets", heal = -1, dbRowId = "dbrows.sweets_food"), + MOONLIGHT_MEAD( + "items.keg_mature_moonlight_mead_1", + "items.keg_mature_moonlight_mead_2", + "items.keg_mature_moonlight_mead_3", + "items.cert_keg_mature_moonlight_mead_4", + heal = 6, + dbRowId = "dbrows.moonlight_mead_food" + ); +} + + +object FoodTable { + + + const val ITEMS = 0 + const val HEAL = 1 + const val COMBO_FOOD = 2 + const val HAS_EFFECT = 3 + const val OVERHEAL = 4 + const val EAT_DELAY = 5 + const val COMBAT_DELAY = 6 + + fun consumableFood() = dbTable("tables.consumable_food", serverOnly = true) { + + column("items", ITEMS, VarType.OBJ.count(Food.entries.maxOf { it.items.size })) + column("heal", HEAL, VarType.INT) + + column("combo", COMBO_FOOD, VarType.BOOLEAN) + column("effect", HAS_EFFECT, VarType.BOOLEAN) + column("overheal", OVERHEAL, VarType.BOOLEAN) + column("eatDelay", EAT_DELAY, VarType.INT) + column("combatDelay", COMBAT_DELAY, VarType.INT) + + Food.entries.forEach { food -> + row(food.dbRowId) { + + columnRSCM(ITEMS, *food.items) + + column(HEAL, food.heal) + column(COMBO_FOOD, food.comboFood) + column(HAS_EFFECT, food.hasEffect) + column(OVERHEAL, food.overheal) + + if (food.eatDelay.isNotEmpty()) { + column(EAT_DELAY, food.eatDelay) + } + if (food.combatDelay.isNotEmpty()) { + column(COMBAT_DELAY, food.combatDelay) + } + + } + } + } + +} \ No newline at end of file diff --git a/cache/bin/main/org/alter/impl/misc/TeleTabs.kt b/cache/bin/main/org/alter/impl/misc/TeleTabs.kt new file mode 100644 index 00000000..dcf2f964 --- /dev/null +++ b/cache/bin/main/org/alter/impl/misc/TeleTabs.kt @@ -0,0 +1,199 @@ +package org.alter.impl.misc + +import dev.openrune.definition.dbtables.dbTable +import dev.openrune.definition.util.VarType + +object TeleTabs { + + const val COL_ITEM = 0 + const val COL_MAGIC_LEVEL = 1 + const val COL_LOCATION = 2 + + fun teleTabs() = dbTable("tables.teleport_tablets", serverOnly = true) { + + column("item", COL_ITEM, VarType.OBJ) + column("magic_level", COL_MAGIC_LEVEL, VarType.INT) + column("location", COL_LOCATION, VarType.COORDGRID) + + // Standard Teleport Tablets + row("dbrows.varrock_teleport_tablet") { + columnRSCM(COL_ITEM, "items.poh_tablet_varrockteleport") + column(COL_MAGIC_LEVEL, 25) + } + row("dbrows.lumbridge_teleport_tablet") { + columnRSCM(COL_ITEM, "items.poh_tablet_lumbridgeteleport") + column(COL_MAGIC_LEVEL, 31) + column(COL_LOCATION, 52776082) + } + row("dbrows.falador_teleport_tablet") { + columnRSCM(COL_ITEM, "items.poh_tablet_faladorteleport") + column(COL_MAGIC_LEVEL, 37) + column(COL_LOCATION, 48565554) + } + row("dbrows.camelot_teleport_tablet") { + columnRSCM(COL_ITEM, "items.poh_tablet_camelotteleport") + column(COL_MAGIC_LEVEL, 45) + column(COL_LOCATION, 45174167) + } + row("dbrows.kourend_castle_teleport_tablet") { + columnRSCM(COL_ITEM, "items.poh_tablet_kourendteleport") + column(COL_MAGIC_LEVEL, 48) + column(COL_LOCATION, 26857052) + } + row("dbrows.ardougne_teleport_tablet") { + columnRSCM(COL_ITEM, "items.poh_tablet_ardougneteleport") + column(COL_MAGIC_LEVEL, 51) + column(COL_LOCATION, 43617513) + } + row("dbrows.civitas_illa_fortis_teleport_tablet") { + columnRSCM(COL_ITEM, "items.poh_tablet_fortisteleport") + column(COL_MAGIC_LEVEL, 54) + column(COL_LOCATION, 27544637) + } + row("dbrows.watchtower_teleport_tablet") { + columnRSCM(COL_ITEM, "items.poh_tablet_watchtowerteleport") + column(COL_MAGIC_LEVEL, 58) + } + + // Arceuus Teleport Tablets + row("dbrows.arceuus_library_teleport_tablet") { + columnRSCM(COL_ITEM, "items.teletab_lumbridge") + column(COL_MAGIC_LEVEL, 6) + column(COL_LOCATION, 26758910) + } + row("dbrows.draynor_manor_teleport_tablet") { + columnRSCM(COL_ITEM, "items.teletab_draynor") + column(COL_MAGIC_LEVEL, 17) + column(COL_LOCATION, 50924825) + } + row("dbrows.battlefront_teleport_tablet") { + columnRSCM(COL_ITEM, "items.teletab_battlefront") + column(COL_MAGIC_LEVEL, 23) + column(COL_LOCATION, 22072988) + } + row("dbrows.mind_altar_teleport_tablet") { + columnRSCM(COL_ITEM, "items.teletab_mind_altar") + column(COL_MAGIC_LEVEL, 28) + column(COL_LOCATION, 48827829) + } + row("dbrows.salve_graveyard_teleport_tablet") { + columnRSCM(COL_ITEM, "items.teletab_salve") + column(COL_MAGIC_LEVEL, 40) + column(COL_LOCATION, 56233349) + } + row("dbrows.fenkenstrains_castle_teleport_tablet") { + columnRSCM(COL_ITEM, "items.teletab_fenk") + column(COL_MAGIC_LEVEL, 48) + column(COL_LOCATION, 58133961) + } + row("dbrows.west_ardougne_teleport_tablet") { + columnRSCM(COL_ITEM, "items.teletab_westardy") + column(COL_MAGIC_LEVEL, 61) + column(COL_LOCATION, 40963291) + } + row("dbrows.harmony_island_teleport_tablet") { + columnRSCM(COL_ITEM, "items.teletab_harmony") + column(COL_MAGIC_LEVEL, 65) + column(COL_LOCATION, 62212915) + } + row("dbrows.cemetery_teleport_tablet") { + columnRSCM(COL_ITEM, "items.teletab_cemetery") + column(COL_MAGIC_LEVEL, 71) + column(COL_LOCATION, 48828083) + } + row("dbrows.barrows_teleport_tablet") { + columnRSCM(COL_ITEM, "items.teletab_barrows") + column(COL_MAGIC_LEVEL, 83) + column(COL_LOCATION, 58412274) + } + row("dbrows.ape_atoll_teleport_tablet") { + columnRSCM(COL_ITEM, "items.teletab_ape") + column(COL_MAGIC_LEVEL, 90) + column(COL_LOCATION, 45409166) + } + + // Ancient Magicks Teleport Tablets + row("dbrows.paddewwa_teleport_tablet") { + columnRSCM(COL_ITEM, "items.tablet_paddewa") + column(COL_MAGIC_LEVEL, 54) + column(COL_LOCATION, 50800283) + } + row("dbrows.senntisten_teleport_tablet") { + columnRSCM(COL_ITEM, "items.tablet_senntisten") + column(COL_MAGIC_LEVEL, 60) + column(COL_LOCATION, 54398217) + } + row("dbrows.kharyrll_teleport_tablet") { + columnRSCM(COL_ITEM, "items.tablet_kharyll") + column(COL_MAGIC_LEVEL, 66) + column(COL_LOCATION, 57249169) + } + row("dbrows.lassar_teleport_tablet") { + columnRSCM(COL_ITEM, "items.tablet_lassar") + column(COL_MAGIC_LEVEL, 72) + column(COL_LOCATION, 49188238) + } + row("dbrows.dareeyak_teleport_tablet") { + columnRSCM(COL_ITEM, "items.tablet_dareeyak") + column(COL_MAGIC_LEVEL, 78) + column(COL_LOCATION, 48631408) + } + row("dbrows.carrallanger_teleport_tablet") { + columnRSCM(COL_ITEM, "items.tablet_carrallangar") + column(COL_MAGIC_LEVEL, 84) + column(COL_LOCATION, 51744338) + } + row("dbrows.annakarl_teleport_tablet") { + columnRSCM(COL_ITEM, "items.tablet_annakarl") + column(COL_MAGIC_LEVEL, 90) + column(COL_LOCATION, 53858096) + } + row("dbrows.ghorrock_teleport_tablet") { + columnRSCM(COL_ITEM, "items.tablet_ghorrock") + column(COL_MAGIC_LEVEL, 96) + column(COL_LOCATION, 48729889) + } + + // Lunar Teleport Tablets + row("dbrows.moonclan_teleport_tablet") { + columnRSCM(COL_ITEM, "items.lunar_tablet_moonclan_teleport") + column(COL_MAGIC_LEVEL, 69) + column(COL_LOCATION, 34623307) + } + row("dbrows.ourania_teleport_tablet") { + columnRSCM(COL_ITEM, "items.lunar_tablet_ourania_teleport") + column(COL_MAGIC_LEVEL, 71) + column(COL_LOCATION, 40438958) + } + row("dbrows.waterbirth_teleport_tablet") { + columnRSCM(COL_ITEM, "items.lunar_tablet_waterbirth_teleport") + column(COL_MAGIC_LEVEL, 72) + column(COL_LOCATION, 41717420) + } + row("dbrows.barbarian_teleport_tablet") { + columnRSCM(COL_ITEM, "items.lunar_tablet_barbarian_teleport") + column(COL_MAGIC_LEVEL, 75) + column(COL_LOCATION, 41668081) + } + row("dbrows.khazard_teleport_tablet") { + columnRSCM(COL_ITEM, "items.lunar_tablet_khazard_teleport") + column(COL_MAGIC_LEVEL, 78) + column(COL_LOCATION, 43191391) + } + row("dbrows.fishing_guild_teleport_tablet") { + columnRSCM(COL_ITEM, "items.lunar_tablet_fishing_guild_teleport") + column(COL_MAGIC_LEVEL, 85) + column(COL_LOCATION, 42814783) + } + row("dbrows.catherby_teleport_tablet") { + columnRSCM(COL_ITEM, "items.lunar_tablet_catherby_teleport") + column(COL_MAGIC_LEVEL, 87) + column(COL_LOCATION, 45895033) + } + row("dbrows.ice_plateau_teleport_tablet") { + columnRSCM(COL_ITEM, "items.lunar_tablet_ice_plateau_teleport") + column(COL_MAGIC_LEVEL, 89) + column(COL_LOCATION, 48746338) + } + } +} \ No newline at end of file diff --git a/cache/bin/main/org/alter/impl/skills/Firemaking.kt b/cache/bin/main/org/alter/impl/skills/Firemaking.kt new file mode 100644 index 00000000..66fd55ac --- /dev/null +++ b/cache/bin/main/org/alter/impl/skills/Firemaking.kt @@ -0,0 +1,163 @@ +package org.alter.impl.skills + +import dev.openrune.definition.dbtables.dbTable +import dev.openrune.definition.util.VarType + +object Firemaking { + + const val COL_ITEM = 0 + const val COL_LEVEL = 1 + const val COL_XP = 2 + const val COL_INITIAL_TICKS = 3 + const val COL_PER_LOG_TICKS = 4 + const val COL_PER_ANIMATION = 5 + + fun logs() = dbTable("tables.firemaking_logs", serverOnly = true) { + + column("item", COL_ITEM, VarType.OBJ) + column("level", COL_LEVEL, VarType.INT) + column("xp", COL_XP, VarType.INT) + column("forester_initial_ticks", COL_INITIAL_TICKS, VarType.INT) + column("forester_log_ticks", COL_PER_LOG_TICKS, VarType.INT) + column("forester_animation", COL_PER_ANIMATION, VarType.SEQ) + + row("dbrows.firemaking_normal_logs") { + columnRSCM(COL_ITEM, "items.logs") + column(COL_LEVEL, 1) + column(COL_XP, 40) + column(COL_INITIAL_TICKS, 102) + column(COL_PER_LOG_TICKS, 3) + columnRSCM(COL_PER_ANIMATION, "sequences.forestry_campfire_burning_logs") + } + + row("dbrows.firemaking_achey_tree_logs") { + columnRSCM(COL_ITEM, "items.achey_tree_logs") + column(COL_LEVEL, 1) + column(COL_XP, 40) + column(COL_INITIAL_TICKS, 102) + column(COL_PER_LOG_TICKS, 3) + columnRSCM(COL_PER_ANIMATION, "sequences.forestry_campfire_burning_achey_tree_logs") + } + + row("dbrows.firemaking_oak_logs") { + columnRSCM(COL_ITEM, "items.oak_logs") + column(COL_LEVEL, 15) + column(COL_XP, 60) + column(COL_INITIAL_TICKS, 109) + column(COL_PER_LOG_TICKS, 10) + columnRSCM(COL_PER_ANIMATION, "sequences.forestry_campfire_burning_oak_logs") + } + + row("dbrows.firemaking_willow_logs") { + columnRSCM(COL_ITEM, "items.willow_logs") + column(COL_LEVEL, 30) + column(COL_XP, 90) + column(COL_INITIAL_TICKS, 116) + column(COL_PER_LOG_TICKS, 17) + columnRSCM(COL_PER_ANIMATION, "sequences.forestry_campfire_burning_willow_logs") + } + + row("dbrows.firemaking_teak_logs") { + columnRSCM(COL_ITEM, "items.teak_logs") + column(COL_LEVEL, 35) + column(COL_XP, 105) + column(COL_INITIAL_TICKS, 118) + column(COL_PER_LOG_TICKS, 19) + columnRSCM(COL_PER_ANIMATION, "sequences.forestry_campfire_burning_teak_logs") + } + + row("dbrows.firemaking_arctic_pine_logs") { + columnRSCM(COL_ITEM, "items.arctic_pine_log") + column(COL_LEVEL, 42) + column(COL_XP, 125) + column(COL_INITIAL_TICKS, 121) + column(COL_PER_LOG_TICKS, 22) + columnRSCM(COL_PER_ANIMATION, "sequences.forestry_campfire_burning_arctic_pine_log") + } + + row("dbrows.firemaking_maple_logs") { + columnRSCM(COL_ITEM, "items.maple_logs") + column(COL_LEVEL, 45) + column(COL_XP, 135) + column(COL_INITIAL_TICKS, 123) + column(COL_PER_LOG_TICKS, 24) + columnRSCM(COL_PER_ANIMATION, "sequences.forestry_campfire_burning_maple_logs") + } + + row("dbrows.firemaking_mahogany_logs") { + columnRSCM(COL_ITEM, "items.mahogany_logs") + column(COL_LEVEL, 50) + column(COL_XP, 157) + column(COL_INITIAL_TICKS, 125) + column(COL_PER_LOG_TICKS, 26) + columnRSCM(COL_PER_ANIMATION, "sequences.forestry_campfire_burning_mahogany_logs") + } + + row("dbrows.firemaking_yew_logs") { + columnRSCM(COL_ITEM, "items.yew_logs") + column(COL_LEVEL, 60) + column(COL_XP, 202) + column(COL_INITIAL_TICKS, 130) + column(COL_PER_LOG_TICKS, 31) + columnRSCM(COL_PER_ANIMATION, "sequences.forestry_campfire_burning_yew_logs") + } + + row("dbrows.firemaking_blisterwood_logs") { + columnRSCM(COL_ITEM, "items.blisterwood_logs") + column(COL_LEVEL, 62) + column(COL_XP, 96) + column(COL_INITIAL_TICKS, 131) + column(COL_PER_LOG_TICKS, 32) + columnRSCM(COL_PER_ANIMATION, "sequences.forestry_campfire_burning_blisterwood_logs") + } + + row("dbrows.firemaking_magic_logs") { + columnRSCM(COL_ITEM, "items.magic_logs") + column(COL_LEVEL, 75) + column(COL_XP, 305) + column(COL_INITIAL_TICKS, 137) + column(COL_PER_LOG_TICKS, 38) + columnRSCM(COL_PER_ANIMATION, "sequences.forestry_campfire_burning_magic_logs") + } + + row("dbrows.firemaking_redwood_logs") { + columnRSCM(COL_ITEM, "items.redwood_logs") + column(COL_LEVEL, 90) + column(COL_XP, 350) + column(COL_INITIAL_TICKS, 144) + column(COL_PER_LOG_TICKS, 45) + columnRSCM(COL_PER_ANIMATION, "sequences.forestry_campfire_burning_redwood_logs") + } + + // Colored logs — same stats as normal logs + row("dbrows.firemaking_blue_logs") { + columnRSCM(COL_ITEM, "items.blue_logs") + column(COL_LEVEL, 1) + column(COL_XP, 50) + } + + row("dbrows.firemaking_green_logs") { + columnRSCM(COL_ITEM, "items.green_logs") + column(COL_LEVEL, 1) + column(COL_XP, 50) + } + + row("dbrows.firemaking_purple_logs") { + columnRSCM(COL_ITEM, "items.trail_logs_purple") + column(COL_LEVEL, 1) + column(COL_XP, 50) + } + + row("dbrows.firemaking_red_logs") { + columnRSCM(COL_ITEM, "items.red_logs") + column(COL_LEVEL, 1) + column(COL_XP, 50) + } + + row("dbrows.firemaking_white_logs") { + columnRSCM(COL_ITEM, "items.trail_logs_white") + column(COL_LEVEL, 1) + column(COL_XP, 50) + } + } +} \ No newline at end of file diff --git a/cache/bin/main/org/alter/impl/skills/Herblore.kt b/cache/bin/main/org/alter/impl/skills/Herblore.kt new file mode 100644 index 00000000..50ec2226 --- /dev/null +++ b/cache/bin/main/org/alter/impl/skills/Herblore.kt @@ -0,0 +1,855 @@ +package org.alter.impl.skills + +import dev.openrune.definition.dbtables.dbTable +import dev.openrune.definition.util.VarType + +object Herblore { + + // Unfinished potions table columns (in order of definition) + const val COL_HERB_ITEM = 0 + const val COL_LEVEL = 1 + const val COL_XP = 2 + const val COL_UNFINISHED_POTION = 3 + + // Finished potions table columns (in order of definition) + const val COL_UNF_POT = 0 + const val COL_SECONDARIES = 1 + const val COL_LEVEL_REQUIRED = 2 + const val COL_XP_FINISHED = 3 + const val COL_OUTPUT_POTION = 4 + + // Cleaning herbs table columns (in order of definition) + const val COL_GRIMY_HERB = 0 + const val COL_CLEAN_LEVEL = 1 + const val COL_CLEAN_XP = 2 + const val COL_CLEAN_HERB = 3 + + // Barbarian mixes table columns (in order of definition) + const val COL_TWO_DOSE_POTION = 0 + const val COL_MIX_INGREDIENT = 1 + const val COL_MIX_LEVEL = 2 + const val COL_MIX_XP = 3 + const val COL_BARBARIAN_MIX = 4 + + // Swamp tar table columns (in order of definition) + const val COL_TAR_HERB = 0 + const val COL_TAR_LEVEL = 1 + const val COL_TAR_XP = 2 + const val COL_TAR_FINISHED = 3 + + // Crushing table columns (in order of definition) + const val COL_CRUSH_ITEM = 0 + const val COL_CRUSH_LEVEL = 1 + const val COL_CRUSH_XP = 2 + const val COL_CRUSHED_ITEM = 3 + + /** + * Table for creating unfinished potions (herb + vial of water) + */ + fun unfinishedPotions() = dbTable("tables.herblore_unfinished", serverOnly = true) { + column("herb_item", COL_HERB_ITEM, VarType.OBJ) + column("level", COL_LEVEL, VarType.INT) + column("xp", COL_XP, VarType.INT) + column("unfinished_potion", COL_UNFINISHED_POTION, VarType.OBJ) + + // Guam leaf + row("dbrows.herblore_guam_unfinished") { + columnRSCM(COL_HERB_ITEM, "items.guam_leaf") + column(COL_LEVEL, 3) + column(COL_XP, 2) + columnRSCM(COL_UNFINISHED_POTION, "items.guamvial") + } + + // Marrentill + row("dbrows.herblore_marrentill_unfinished") { + columnRSCM(COL_HERB_ITEM, "items.marentill") + column(COL_LEVEL, 5) + column(COL_XP, 3) + columnRSCM(COL_UNFINISHED_POTION, "items.marrentillvial") + } + + // Tarromin + row("dbrows.herblore_tarromin_unfinished") { + columnRSCM(COL_HERB_ITEM, "items.tarromin") + column(COL_LEVEL, 11) + column(COL_XP, 5) + columnRSCM(COL_UNFINISHED_POTION, "items.tarrominvial") + } + + // Harralander + row("dbrows.herblore_harralander_unfinished") { + columnRSCM(COL_HERB_ITEM, "items.harralander") + column(COL_LEVEL, 20) + column(COL_XP, 6) + columnRSCM(COL_UNFINISHED_POTION, "items.harralandervial") + } + + // Ranarr weed + row("dbrows.herblore_ranarr_unfinished") { + columnRSCM(COL_HERB_ITEM, "items.ranarr_weed") + column(COL_LEVEL, 25) + column(COL_XP, 8) + columnRSCM(COL_UNFINISHED_POTION, "items.ranarrvial") + } + + // Toadflax + row("dbrows.herblore_toadflax_unfinished") { + columnRSCM(COL_HERB_ITEM, "items.toadflax") + column(COL_LEVEL, 30) + column(COL_XP, 8) + columnRSCM(COL_UNFINISHED_POTION, "items.toadflaxvial") + } + + // Irit leaf + row("dbrows.herblore_irit_unfinished") { + columnRSCM(COL_HERB_ITEM, "items.irit_leaf") + column(COL_LEVEL, 40) + column(COL_XP, 9) + columnRSCM(COL_UNFINISHED_POTION, "items.iritvial") + } + + // Avantoe + row("dbrows.herblore_avantoe_unfinished") { + columnRSCM(COL_HERB_ITEM, "items.avantoe") + column(COL_LEVEL, 48) + column(COL_XP, 10) + columnRSCM(COL_UNFINISHED_POTION, "items.avantoevial") + } + + // Kwuarm + row("dbrows.herblore_kwuarm_unfinished") { + columnRSCM(COL_HERB_ITEM, "items.kwuarm") + column(COL_LEVEL, 54) + column(COL_XP, 11) + columnRSCM(COL_UNFINISHED_POTION, "items.kwuarmvial") + } + + // Snapdragon + row("dbrows.herblore_snapdragon_unfinished") { + columnRSCM(COL_HERB_ITEM, "items.snapdragon") + column(COL_LEVEL, 59) + column(COL_XP, 12) + columnRSCM(COL_UNFINISHED_POTION, "items.snapdragonvial") + } + + // Cadantine + row("dbrows.herblore_cadantine_unfinished") { + columnRSCM(COL_HERB_ITEM, "items.cadantine") + column(COL_LEVEL, 65) + column(COL_XP, 13) + columnRSCM(COL_UNFINISHED_POTION, "items.cadantinevial") + } + + // Lantadyme + row("dbrows.herblore_lantadyme_unfinished") { + columnRSCM(COL_HERB_ITEM, "items.lantadyme") + column(COL_LEVEL, 67) + column(COL_XP, 13) + columnRSCM(COL_UNFINISHED_POTION, "items.lantadymevial") + } + + // Dwarf weed + row("dbrows.herblore_dwarf_weed_unfinished") { + columnRSCM(COL_HERB_ITEM, "items.dwarf_weed") + column(COL_LEVEL, 70) + column(COL_XP, 13) + columnRSCM(COL_UNFINISHED_POTION, "items.dwarfweedvial") + } + + // Torstol + row("dbrows.herblore_torstol_unfinished") { + columnRSCM(COL_HERB_ITEM, "items.torstol") + column(COL_LEVEL, 75) + column(COL_XP, 14) + columnRSCM(COL_UNFINISHED_POTION, "items.torstolvial") + } + } + + /** + * Table for creating finished potions (unfinished potion + secondary ingredient) + * Supports multi-step potions with additional ingredients + */ + fun finishedPotions() = dbTable("tables.herblore_finished", serverOnly = true) { + column("unf_pot", COL_UNF_POT, VarType.OBJ) + column("secondaries", COL_SECONDARIES, VarType.OBJ) + column("level_required", COL_LEVEL_REQUIRED, VarType.INT) + column("xp", COL_XP_FINISHED, VarType.INT) + column("output_potion", COL_OUTPUT_POTION, VarType.OBJ) + + // Attack potion (Guam + Eye of newt) + row("dbrows.herblore_attack_potion") { + columnRSCM(COL_UNF_POT, "items.guamvial") + columnRSCM(COL_SECONDARIES, "items.eye_of_newt") + column(COL_LEVEL_REQUIRED, 3) + column(COL_XP_FINISHED, 25) + columnRSCM(COL_OUTPUT_POTION, "items.3dose1attack") + } + + // Antipoison (Marrentill + Unicorn horn dust) + row("dbrows.herblore_antipoison") { + columnRSCM(COL_UNF_POT, "items.marrentillvial") + columnRSCM(COL_SECONDARIES, "items.unicorn_horn_dust") + column(COL_LEVEL_REQUIRED, 5) + column(COL_XP_FINISHED, 38) + columnRSCM(COL_OUTPUT_POTION, "items.3doseantipoison") + } + + // Strength potion (Tarromin + Limpwurt root) + row("dbrows.herblore_strength_potion") { + columnRSCM(COL_UNF_POT, "items.tarrominvial") + columnRSCM(COL_SECONDARIES, "items.limpwurt_root") + column(COL_LEVEL_REQUIRED, 12) + column(COL_XP_FINISHED, 50) + columnRSCM(COL_OUTPUT_POTION, "items.3dose1strength") + } + + // Restore potion (Harralander + Red spiders' eggs) + row("dbrows.herblore_restore_potion") { + columnRSCM(COL_UNF_POT, "items.harralandervial") + columnRSCM(COL_SECONDARIES, "items.red_spiders_eggs") + column(COL_LEVEL_REQUIRED, 22) + column(COL_XP_FINISHED, 63) + columnRSCM(COL_OUTPUT_POTION, "items.3dosestatrestore") + } + + // Energy potion (Harralander + Chocolate dust) + row("dbrows.herblore_energy_potion") { + columnRSCM(COL_UNF_POT, "items.harralandervial") + columnRSCM(COL_SECONDARIES, "items.chocolate_dust") + column(COL_LEVEL_REQUIRED, 26) + column(COL_XP_FINISHED, 68) + columnRSCM(COL_OUTPUT_POTION, "items.3dose1energy") + } + + // Prayer potion (Ranarr + Snape grass) + row("dbrows.herblore_prayer_potion") { + columnRSCM(COL_UNF_POT, "items.ranarrvial") + columnRSCM(COL_SECONDARIES, "items.snape_grass") + column(COL_LEVEL_REQUIRED, 38) + column(COL_XP_FINISHED, 88) + columnRSCM(COL_OUTPUT_POTION, "items.3doseprayerrestore") + } + + // Super attack (Irit + Eye of newt) + row("dbrows.herblore_super_attack") { + columnRSCM(COL_UNF_POT, "items.iritvial") + columnRSCM(COL_SECONDARIES, "items.eye_of_newt") + column(COL_LEVEL_REQUIRED, 45) + column(COL_XP_FINISHED, 100) + columnRSCM(COL_OUTPUT_POTION, "items.3dose2attack") + } + + // Superantipoison (Irit + Unicorn horn dust) + row("dbrows.herblore_superantipoison") { + columnRSCM(COL_UNF_POT, "items.iritvial") + columnRSCM(COL_SECONDARIES, "items.unicorn_horn_dust") + column(COL_LEVEL_REQUIRED, 48) + column(COL_XP_FINISHED, 105) + columnRSCM(COL_OUTPUT_POTION, "items.3dose2antipoison") + } + + // Fishing potion (Avantoe + Snape grass) + row("dbrows.herblore_fishing_potion") { + columnRSCM(COL_UNF_POT, "items.avantoevial") + columnRSCM(COL_SECONDARIES, "items.snape_grass") + column(COL_LEVEL_REQUIRED, 50) + column(COL_XP_FINISHED, 113) + columnRSCM(COL_OUTPUT_POTION, "items.3dosefisherspotion") + } + + // Super energy (Avantoe + Mort myre fungus) + row("dbrows.herblore_super_energy") { + columnRSCM(COL_UNF_POT, "items.avantoevial") + columnRSCM(COL_SECONDARIES, "items.mortmyremushroom") + column(COL_LEVEL_REQUIRED, 52) + column(COL_XP_FINISHED, 118) + columnRSCM(COL_OUTPUT_POTION, "items.3dose2energy") + } + + // Super strength (Kwuarm + Limpwurt root) + row("dbrows.herblore_super_strength") { + columnRSCM(COL_UNF_POT, "items.kwuarmvial") + columnRSCM(COL_SECONDARIES, "items.limpwurt_root") + column(COL_LEVEL_REQUIRED, 55) + column(COL_XP_FINISHED, 125) + columnRSCM(COL_OUTPUT_POTION, "items.3dose2strength") + } + + // Weapon poison (Kwuarm + Dragon scale dust) + row("dbrows.herblore_weapon_poison") { + columnRSCM(COL_UNF_POT, "items.kwuarmvial") + columnRSCM(COL_SECONDARIES, "items.dragon_scale_dust") + column(COL_LEVEL_REQUIRED, 60) + column(COL_XP_FINISHED, 138) + columnRSCM(COL_OUTPUT_POTION, "items.weapon_poison") + } + + // Super restore (Snapdragon + Red spiders' eggs) + row("dbrows.herblore_super_restore") { + columnRSCM(COL_UNF_POT, "items.snapdragonvial") + columnRSCM(COL_SECONDARIES, "items.red_spiders_eggs") + column(COL_LEVEL_REQUIRED, 63) + column(COL_XP_FINISHED, 143) + columnRSCM(COL_OUTPUT_POTION, "items.3dose2restore") + } + + // Super defence (Cadantine + White berries) + row("dbrows.herblore_super_defence") { + columnRSCM(COL_UNF_POT, "items.cadantinevial") + columnRSCM(COL_SECONDARIES, "items.white_berries") + column(COL_LEVEL_REQUIRED, 66) + column(COL_XP_FINISHED, 150) + columnRSCM(COL_OUTPUT_POTION, "items.3dose2defense") + } + + // Antifire (Lantadyme + Dragon scale dust) + row("dbrows.herblore_antifire") { + columnRSCM(COL_UNF_POT, "items.lantadymevial") + columnRSCM(COL_SECONDARIES, "items.dragon_scale_dust") + column(COL_LEVEL_REQUIRED, 69) + column(COL_XP_FINISHED, 158) + columnRSCM(COL_OUTPUT_POTION, "items.3dose1antidragon") + } + + // Super antifire (Lantadyme + Crushed superior dragon bones) + row("dbrows.herblore_super_antifire") { + columnRSCM(COL_UNF_POT, "items.lantadymevial") + columnRSCM(COL_SECONDARIES, "items.crushed_dragon_bones") + column(COL_LEVEL_REQUIRED, 92) + column(COL_XP_FINISHED, 180) + columnRSCM(COL_OUTPUT_POTION, "items.3dose2antidragon") + } + + // Ranging potion (Dwarf weed + Wine of zamorak) + row("dbrows.herblore_ranging_potion") { + columnRSCM(COL_UNF_POT, "items.dwarfweedvial") + columnRSCM(COL_SECONDARIES, "items.wine_of_zamorak") + column(COL_LEVEL_REQUIRED, 72) + column(COL_XP_FINISHED, 163) + columnRSCM(COL_OUTPUT_POTION, "items.3doserangerspotion") + } + + // Magic potion (Lantadyme + Potato cactus) + row("dbrows.herblore_magic_potion") { + columnRSCM(COL_UNF_POT, "items.lantadymevial") + columnRSCM(COL_SECONDARIES, "items.cactus_potato") + column(COL_LEVEL_REQUIRED, 76) + column(COL_XP_FINISHED, 173) + columnRSCM(COL_OUTPUT_POTION, "items.3dose1magic") + } + + // Zamorak brew (Torstol + Jangerberries) + row("dbrows.herblore_zamorak_brew") { + columnRSCM(COL_UNF_POT, "items.torstolvial") + columnRSCM(COL_SECONDARIES, "items.jangerberries") + column(COL_LEVEL_REQUIRED, 78) + column(COL_XP_FINISHED, 175) + columnRSCM(COL_OUTPUT_POTION, "items.3dosepotionofzamorak") + } + + // Saradomin brew (Toadflax + Crushed nest) + row("dbrows.herblore_saradomin_brew") { + columnRSCM(COL_UNF_POT, "items.toadflaxvial") + columnRSCM(COL_SECONDARIES, "items.crushed_bird_nest") + column(COL_LEVEL_REQUIRED, 81) + column(COL_XP_FINISHED, 180) + columnRSCM(COL_OUTPUT_POTION, "items.3dosepotionofsaradomin") + } + + // Defence potion (Ranarr + White berries) + row("dbrows.herblore_defence_potion") { + columnRSCM(COL_UNF_POT, "items.ranarrvial") + columnRSCM(COL_SECONDARIES, "items.white_berries") + column(COL_LEVEL_REQUIRED, 30) + column(COL_XP_FINISHED, 75) + columnRSCM(COL_OUTPUT_POTION, "items.3dose1defense") + } + + // Agility potion (Toadflax + Toad's legs) + row("dbrows.herblore_agility_potion") { + columnRSCM(COL_UNF_POT, "items.toadflaxvial") + columnRSCM(COL_SECONDARIES, "items.toads_legs") + column(COL_LEVEL_REQUIRED, 34) + column(COL_XP_FINISHED, 80) + columnRSCM(COL_OUTPUT_POTION, "items.3dose1agility") + } + + // Combat potion (Harralander + Goat horn dust) + row("dbrows.herblore_combat_potion") { + columnRSCM(COL_UNF_POT, "items.harralandervial") + columnRSCM(COL_SECONDARIES, "items.ground_desert_goat_horn") + column(COL_LEVEL_REQUIRED, 36) + column(COL_XP_FINISHED, 84) + columnRSCM(COL_OUTPUT_POTION, "items.3dosecombat") + } + + // Hunter potion (Avantoe + Kebbit teeth) + row("dbrows.herblore_hunter_potion") { + columnRSCM(COL_UNF_POT, "items.avantoevial") + columnRSCM(COL_SECONDARIES, "items.huntingbeast_sabreteeth") + column(COL_LEVEL_REQUIRED, 53) + column(COL_XP_FINISHED, 120) + columnRSCM(COL_OUTPUT_POTION, "items.3dosehunting") + } + + // Bastion potion: Cadantine (unf) + Wine of zamorak + Crushed superior dragon bones → Bastion (3) + row("dbrows.herblore_bastion_potion") { + columnRSCM(COL_UNF_POT, "items.cadantinevial") + columnRSCM(COL_SECONDARIES, "items.wine_of_zamorak", "items.crushed_dragon_bones") + column(COL_LEVEL_REQUIRED, 80) + column(COL_XP_FINISHED, 155) + columnRSCM(COL_OUTPUT_POTION, "items.3dosebastion") + } + + // Battlemage potion: Cadantine (unf) + Potato cactus + Crushed superior dragon bones → Battlemage (3) + row("dbrows.herblore_battlemage_potion") { + columnRSCM(COL_UNF_POT, "items.cadantinevial") + columnRSCM(COL_SECONDARIES, "items.cactus_potato", "items.crushed_dragon_bones") + column(COL_LEVEL_REQUIRED, 79) + column(COL_XP_FINISHED, 155) + columnRSCM(COL_OUTPUT_POTION, "items.3dosebattlemage") + } + + // Super combat potion: Torstol (unf) + Super attack (3) + Super strength (3) + Super defence (3) = Super combat (3) + row("dbrows.herblore_super_combat_potion") { + columnRSCM(COL_UNF_POT, "items.torstol") + columnRSCM(COL_SECONDARIES, "items.3dose2attack", "items.3dose2strength", "items.3dose2defense") + column(COL_LEVEL_REQUIRED, 90) + column(COL_XP_FINISHED, 150) + columnRSCM(COL_OUTPUT_POTION, "items.3dose2combat") + } + + // Extended anti-venom+ (Anti-venom+ (3) + Zulrah's scales) + row("dbrows.herblore_extended_antivenom_plus") { + columnRSCM(COL_UNF_POT, "items.antivenom+3") + columnRSCM(COL_SECONDARIES, "items.snakeboss_scale") + column(COL_LEVEL_REQUIRED, 94) + column(COL_XP_FINISHED, 160) + columnRSCM(COL_OUTPUT_POTION, "items.extended_antivenom+3") + } + } + + /** + * Table for cleaning grimy herbs (unidentified -> clean) + * One-time action, no repeatable delay + */ + fun cleaningHerbs() = dbTable("tables.herblore_cleaning", serverOnly = true) { + column("grimy_herb", COL_GRIMY_HERB, VarType.OBJ) + column("level", COL_CLEAN_LEVEL, VarType.INT) + column("xp", COL_CLEAN_XP, VarType.INT) + column("clean_herb", COL_CLEAN_HERB, VarType.OBJ) + + // Guam + row("dbrows.herblore_clean_guam") { + columnRSCM(COL_GRIMY_HERB, "items.unidentified_guam") + column(COL_CLEAN_LEVEL, 3) + column(COL_CLEAN_XP, 2) + columnRSCM(COL_CLEAN_HERB, "items.guam_leaf") + } + + // Marrentill + row("dbrows.herblore_clean_marrentill") { + columnRSCM(COL_GRIMY_HERB, "items.unidentified_marentill") + column(COL_CLEAN_LEVEL, 5) + column(COL_CLEAN_XP, 3) + columnRSCM(COL_CLEAN_HERB, "items.marentill") + } + + // Tarromin + row("dbrows.herblore_clean_tarromin") { + columnRSCM(COL_GRIMY_HERB, "items.unidentified_tarromin") + column(COL_CLEAN_LEVEL, 11) + column(COL_CLEAN_XP, 5) + columnRSCM(COL_CLEAN_HERB, "items.tarromin") + } + + // Harralander + row("dbrows.herblore_clean_harralander") { + columnRSCM(COL_GRIMY_HERB, "items.unidentified_harralander") + column(COL_CLEAN_LEVEL, 20) + column(COL_CLEAN_XP, 6) + columnRSCM(COL_CLEAN_HERB, "items.harralander") + } + + // Ranarr + row("dbrows.herblore_clean_ranarr") { + columnRSCM(COL_GRIMY_HERB, "items.unidentified_ranarr") + column(COL_CLEAN_LEVEL, 25) + column(COL_CLEAN_XP, 8) + columnRSCM(COL_CLEAN_HERB, "items.ranarr_weed") + } + + // Toadflax + row("dbrows.herblore_clean_toadflax") { + columnRSCM(COL_GRIMY_HERB, "items.unidentified_toadflax") + column(COL_CLEAN_LEVEL, 30) + column(COL_CLEAN_XP, 8) + columnRSCM(COL_CLEAN_HERB, "items.toadflax") + } + + // Irit + row("dbrows.herblore_clean_irit") { + columnRSCM(COL_GRIMY_HERB, "items.unidentified_irit") + column(COL_CLEAN_LEVEL, 40) + column(COL_CLEAN_XP, 9) + columnRSCM(COL_CLEAN_HERB, "items.irit_leaf") + } + + // Avantoe + row("dbrows.herblore_clean_avantoe") { + columnRSCM(COL_GRIMY_HERB, "items.unidentified_avantoe") + column(COL_CLEAN_LEVEL, 48) + column(COL_CLEAN_XP, 10) + columnRSCM(COL_CLEAN_HERB, "items.avantoe") + } + + // Kwuarm + row("dbrows.herblore_clean_kwuarm") { + columnRSCM(COL_GRIMY_HERB, "items.unidentified_kwuarm") + column(COL_CLEAN_LEVEL, 54) + column(COL_CLEAN_XP, 11) + columnRSCM(COL_CLEAN_HERB, "items.kwuarm") + } + + // Snapdragon + row("dbrows.herblore_clean_snapdragon") { + columnRSCM(COL_GRIMY_HERB, "items.unidentified_snapdragon") + column(COL_CLEAN_LEVEL, 59) + column(COL_CLEAN_XP, 12) + columnRSCM(COL_CLEAN_HERB, "items.snapdragon") + } + + // Cadantine + row("dbrows.herblore_clean_cadantine") { + columnRSCM(COL_GRIMY_HERB, "items.unidentified_cadantine") + column(COL_CLEAN_LEVEL, 65) + column(COL_CLEAN_XP, 13) + columnRSCM(COL_CLEAN_HERB, "items.cadantine") + } + + // Lantadyme + row("dbrows.herblore_clean_lantadyme") { + columnRSCM(COL_GRIMY_HERB, "items.unidentified_lantadyme") + column(COL_CLEAN_LEVEL, 67) + column(COL_CLEAN_XP, 13) + columnRSCM(COL_CLEAN_HERB, "items.lantadyme") + } + + // Dwarf weed + row("dbrows.herblore_clean_dwarf_weed") { + columnRSCM(COL_GRIMY_HERB, "items.unidentified_dwarf_weed") + column(COL_CLEAN_LEVEL, 70) + column(COL_CLEAN_XP, 13) + columnRSCM(COL_CLEAN_HERB, "items.dwarf_weed") + } + + // Torstol + row("dbrows.herblore_clean_torstol") { + columnRSCM(COL_GRIMY_HERB, "items.unidentified_torstol") + column(COL_CLEAN_LEVEL, 75) + column(COL_CLEAN_XP, 14) + columnRSCM(COL_CLEAN_HERB, "items.torstol") + } + } + + /** + * Table for creating barbarian mixes (two-dose potion + roe/caviar) + */ + fun barbarianMixes() = dbTable("tables.herblore_barbarian_mixes", serverOnly = true) { + column("two_dose_potion", COL_TWO_DOSE_POTION, VarType.OBJ) + column("mix_ingredient", COL_MIX_INGREDIENT, VarType.OBJ) + column("level", COL_MIX_LEVEL, VarType.INT) + column("xp", COL_MIX_XP, VarType.INT) + column("barbarian_mix", COL_BARBARIAN_MIX, VarType.OBJ) + + // Attack mix (2-dose attack + roe) + row("dbrows.herblore_attack_mix") { + columnRSCM(COL_TWO_DOSE_POTION, "items.2dose1attack") + columnRSCM(COL_MIX_INGREDIENT, "items.brut_roe") + column(COL_MIX_LEVEL, 3) + column(COL_MIX_XP, 0) + columnRSCM(COL_BARBARIAN_MIX, "items.brutal_2dose1attack") + } + + // Antipoison mix (2-dose antipoison + roe) + row("dbrows.herblore_antipoison_mix") { + columnRSCM(COL_TWO_DOSE_POTION, "items.2doseantipoison") + columnRSCM(COL_MIX_INGREDIENT, "items.brut_roe") + column(COL_MIX_LEVEL, 5) + column(COL_MIX_XP, 0) + columnRSCM(COL_BARBARIAN_MIX, "items.brutal_2doseantipoison") + } + + // Attack mix (2-dose attack + caviar) - Alternative to roe + row("dbrows.herblore_attack_mix_caviar") { + columnRSCM(COL_TWO_DOSE_POTION, "items.2dose1attack") + columnRSCM(COL_MIX_INGREDIENT, "items.brut_caviar") + column(COL_MIX_LEVEL, 3) + column(COL_MIX_XP, 0) + columnRSCM(COL_BARBARIAN_MIX, "items.brutal_2dose1attack") + } + + // Strength mix (2-dose strength + roe) + row("dbrows.herblore_strength_mix") { + columnRSCM(COL_TWO_DOSE_POTION, "items.2dose1strength") + columnRSCM(COL_MIX_INGREDIENT, "items.brut_roe") + column(COL_MIX_LEVEL, 12) + column(COL_MIX_XP, 0) + columnRSCM(COL_BARBARIAN_MIX, "items.brutal_2dose1strength") + } + + // Stat restore mix (2-dose restore + roe) + row("dbrows.herblore_stat_restore_mix") { + columnRSCM(COL_TWO_DOSE_POTION, "items.2dosestatrestore") + columnRSCM(COL_MIX_INGREDIENT, "items.brut_roe") + column(COL_MIX_LEVEL, 22) + column(COL_MIX_XP, 0) + columnRSCM(COL_BARBARIAN_MIX, "items.brutal_2dosestatrestore") + } + + // Energy mix (2-dose energy + roe) + row("dbrows.herblore_energy_mix") { + columnRSCM(COL_TWO_DOSE_POTION, "items.2dose1energy") + columnRSCM(COL_MIX_INGREDIENT, "items.brut_roe") + column(COL_MIX_LEVEL, 26) + column(COL_MIX_XP, 0) + columnRSCM(COL_BARBARIAN_MIX, "items.brutal_2dose1energy") + } + + // Defence mix (2-dose defence + roe) + row("dbrows.herblore_defence_mix") { + columnRSCM(COL_TWO_DOSE_POTION, "items.2dose1defense") + columnRSCM(COL_MIX_INGREDIENT, "items.brut_roe") + column(COL_MIX_LEVEL, 30) + column(COL_MIX_XP, 0) + columnRSCM(COL_BARBARIAN_MIX, "items.brutal_2dose1defense") + } + + // Agility mix (2-dose agility + roe) + row("dbrows.herblore_agility_mix") { + columnRSCM(COL_TWO_DOSE_POTION, "items.2dose1agility") + columnRSCM(COL_MIX_INGREDIENT, "items.brut_roe") + column(COL_MIX_LEVEL, 34) + column(COL_MIX_XP, 0) + columnRSCM(COL_BARBARIAN_MIX, "items.brutal_2dose1agility") + } + + // Prayer mix (2-dose prayer + roe) + row("dbrows.herblore_prayer_mix") { + columnRSCM(COL_TWO_DOSE_POTION, "items.2doseprayerrestore") + columnRSCM(COL_MIX_INGREDIENT, "items.brut_roe") + column(COL_MIX_LEVEL, 38) + column(COL_MIX_XP, 0) + columnRSCM(COL_BARBARIAN_MIX, "items.brutal_2doseprayerrestore") + } + + // Super attack mix (2-dose super attack + caviar) + row("dbrows.herblore_super_attack_mix") { + columnRSCM(COL_TWO_DOSE_POTION, "items.2dose2attack") + columnRSCM(COL_MIX_INGREDIENT, "items.brut_caviar") + column(COL_MIX_LEVEL, 45) + column(COL_MIX_XP, 0) + columnRSCM(COL_BARBARIAN_MIX, "items.brutal_2dose2attack") + } + + // Super antipoison mix (2-dose super antipoison + caviar) + row("dbrows.herblore_super_antipoison_mix") { + columnRSCM(COL_TWO_DOSE_POTION, "items.2dose2antipoison") + columnRSCM(COL_MIX_INGREDIENT, "items.brut_caviar") + column(COL_MIX_LEVEL, 48) + column(COL_MIX_XP, 0) + columnRSCM(COL_BARBARIAN_MIX, "items.brutal_2dose2antipoison") + } + + // Fishing mix (2-dose fishing + caviar) + row("dbrows.herblore_fishing_mix") { + columnRSCM(COL_TWO_DOSE_POTION, "items.2dosefisherspotion") + columnRSCM(COL_MIX_INGREDIENT, "items.brut_caviar") + column(COL_MIX_LEVEL, 50) + column(COL_MIX_XP, 0) + columnRSCM(COL_BARBARIAN_MIX, "items.brutal_2dosefisherspotion") + } + + // Super energy mix (2-dose super energy + caviar) + row("dbrows.herblore_super_energy_mix") { + columnRSCM(COL_TWO_DOSE_POTION, "items.2dose2energy") + columnRSCM(COL_MIX_INGREDIENT, "items.brut_caviar") + column(COL_MIX_LEVEL, 52) + column(COL_MIX_XP, 0) + columnRSCM(COL_BARBARIAN_MIX, "items.brutal_2dose2energy") + } + + // Super strength mix (2-dose super strength + caviar) + row("dbrows.herblore_super_strength_mix") { + columnRSCM(COL_TWO_DOSE_POTION, "items.2dose2strength") + columnRSCM(COL_MIX_INGREDIENT, "items.brut_caviar") + column(COL_MIX_LEVEL, 55) + column(COL_MIX_XP, 0) + columnRSCM(COL_BARBARIAN_MIX, "items.brutal_2dose2strength") + } + + // Super restore mix (2-dose super restore + caviar) + row("dbrows.herblore_super_restore_mix") { + columnRSCM(COL_TWO_DOSE_POTION, "items.2dose2restore") + columnRSCM(COL_MIX_INGREDIENT, "items.brut_caviar") + column(COL_MIX_LEVEL, 63) + column(COL_MIX_XP, 0) + columnRSCM(COL_BARBARIAN_MIX, "items.brutal_2dose2restore") + } + + // Super defence mix (2-dose super defence + caviar) + row("dbrows.herblore_super_defence_mix") { + columnRSCM(COL_TWO_DOSE_POTION, "items.2dose2defense") + columnRSCM(COL_MIX_INGREDIENT, "items.brut_caviar") + column(COL_MIX_LEVEL, 66) + column(COL_MIX_XP, 0) + columnRSCM(COL_BARBARIAN_MIX, "items.brutal_2dose2defense") + } + + // Antifire mix (2-dose antifire + caviar) + row("dbrows.herblore_antifire_mix") { + columnRSCM(COL_TWO_DOSE_POTION, "items.2dose1antidragon") + columnRSCM(COL_MIX_INGREDIENT, "items.brut_caviar") + column(COL_MIX_LEVEL, 69) + column(COL_MIX_XP, 0) + columnRSCM(COL_BARBARIAN_MIX, "items.brutal_2dose1antidragon") + } + + // Ranging mix (2-dose ranging + caviar) + row("dbrows.herblore_ranging_mix") { + columnRSCM(COL_TWO_DOSE_POTION, "items.2doserangerspotion") + columnRSCM(COL_MIX_INGREDIENT, "items.brut_caviar") + column(COL_MIX_LEVEL, 72) + column(COL_MIX_XP, 0) + columnRSCM(COL_BARBARIAN_MIX, "items.brutal_2doserangerspotion") + } + + // Magic mix (2-dose magic + caviar) + row("dbrows.herblore_magic_mix") { + columnRSCM(COL_TWO_DOSE_POTION, "items.2dose1magic") + columnRSCM(COL_MIX_INGREDIENT, "items.brut_caviar") + column(COL_MIX_LEVEL, 76) + column(COL_MIX_XP, 0) + columnRSCM(COL_BARBARIAN_MIX, "items.brutal_2dose1magic") + } + + // Zamorak mix (2-dose zamorak + caviar) + row("dbrows.herblore_zamorak_mix") { + columnRSCM(COL_TWO_DOSE_POTION, "items.2dosepotionofzamorak") + columnRSCM(COL_MIX_INGREDIENT, "items.brut_caviar") + column(COL_MIX_LEVEL, 78) + column(COL_MIX_XP, 0) + columnRSCM(COL_BARBARIAN_MIX, "items.brutal_2dosepotionofzamorak") + } + } + + /** + * Table for creating swamp tar + */ + fun swampTar() = dbTable("tables.herblore_swamp_tar", serverOnly = true) { + column("herb", COL_TAR_HERB, VarType.OBJ) + column("level", COL_TAR_LEVEL, VarType.INT) + column("xp", COL_TAR_XP, VarType.INT) + column("finished_tar", COL_TAR_FINISHED, VarType.OBJ) + + // Guam tar (Guam leaf + 15x swamp tar = 15x green tar) + row("dbrows.herblore_guam_tar") { + columnRSCM(COL_TAR_HERB, "items.guam_leaf") + column(COL_TAR_LEVEL, 19) + column(COL_TAR_XP, 30) + columnRSCM(COL_TAR_FINISHED, "items.salamander_tar_green") + } + + // Marrentill tar (Marrentill + 15x swamp tar = 15x orange tar) + row("dbrows.herblore_marrentill_tar") { + columnRSCM(COL_TAR_HERB, "items.marentill") + column(COL_TAR_LEVEL, 31) + column(COL_TAR_XP, 42) + columnRSCM(COL_TAR_FINISHED, "items.salamander_tar_orange") + } + + // Tarromin tar (Tarromin + 15x swamp tar = 15x red tar) + row("dbrows.herblore_tarromin_tar") { + columnRSCM(COL_TAR_HERB, "items.tarromin") + column(COL_TAR_LEVEL, 39) + column(COL_TAR_XP, 55) + columnRSCM(COL_TAR_FINISHED, "items.salamander_tar_red") + } + + // Harralander tar (Harralander + 15x swamp tar = 15x black tar) + row("dbrows.herblore_harralander_tar") { + columnRSCM(COL_TAR_HERB, "items.harralander") + column(COL_TAR_LEVEL, 44) + column(COL_TAR_XP, 72) + columnRSCM(COL_TAR_FINISHED, "items.salamander_tar_black") + } + + // Irit tar (Irit leaf + 15x swamp tar = 15x mountain tar) + row("dbrows.herblore_irit_tar") { + columnRSCM(COL_TAR_HERB, "items.irit_leaf") + column(COL_TAR_LEVEL, 50) + column(COL_TAR_XP, 84) + columnRSCM(COL_TAR_FINISHED, "items.salamander_tar_mountain") + } + } + + /** + * Table for crushing items with pestle and mortar + * Auto-crushes every 3 ticks when multiple items are available + */ + fun crushing() = dbTable("tables.herblore_crushing", serverOnly = true) { + column("item", COL_CRUSH_ITEM, VarType.OBJ) + column("level", COL_CRUSH_LEVEL, VarType.INT) + column("xp", COL_CRUSH_XP, VarType.INT) + column("crushed_item", COL_CRUSHED_ITEM, VarType.OBJ) + + // Bird nest (empty) → Crushed bird nest + row("dbrows.herblore_crush_bird_nest") { + columnRSCM(COL_CRUSH_ITEM, "items.bird_nest_empty") + column(COL_CRUSH_LEVEL, 1) + column(COL_CRUSH_XP, 0) + columnRSCM(COL_CRUSHED_ITEM, "items.crushed_bird_nest") + } + + // Chocolate bar → Chocolate dust + row("dbrows.herblore_crush_chocolate") { + columnRSCM(COL_CRUSH_ITEM, "items.chocolate_bar") + column(COL_CRUSH_LEVEL, 1) + column(COL_CRUSH_XP, 0) + columnRSCM(COL_CRUSHED_ITEM, "items.chocolate_dust") + } + + // Unicorn horn → Unicorn horn dust + row("dbrows.herblore_crush_unicorn_horn") { + columnRSCM(COL_CRUSH_ITEM, "items.unicorn_horn") + column(COL_CRUSH_LEVEL, 1) + column(COL_CRUSH_XP, 0) + columnRSCM(COL_CRUSHED_ITEM, "items.unicorn_horn_dust") + } + + // Blue dragon scale → Dragon scale dust + row("dbrows.herblore_crush_dragon_scale") { + columnRSCM(COL_CRUSH_ITEM, "items.blue_dragon_scale") + column(COL_CRUSH_LEVEL, 1) + column(COL_CRUSH_XP, 0) + columnRSCM(COL_CRUSHED_ITEM, "items.dragon_scale_dust") + } + + // Desert goat horn → Ground desert goat horn + row("dbrows.herblore_crush_goat_horn") { + columnRSCM(COL_CRUSH_ITEM, "items.desert_goat_horn") + column(COL_CRUSH_LEVEL, 1) + column(COL_CRUSH_XP, 0) + columnRSCM(COL_CRUSHED_ITEM, "items.ground_desert_goat_horn") + } + + // Superior dragon bones → Crushed superior dragon bones + row("dbrows.herblore_crush_superior_dragon_bones") { + columnRSCM(COL_CRUSH_ITEM, "items.dragon_bones_superior") + column(COL_CRUSH_LEVEL, 1) + column(COL_CRUSH_XP, 0) + columnRSCM(COL_CRUSHED_ITEM, "items.crushed_dragon_bones") + } + } +} + diff --git a/cache/bin/main/org/alter/impl/skills/Mining.kt b/cache/bin/main/org/alter/impl/skills/Mining.kt new file mode 100644 index 00000000..98829953 --- /dev/null +++ b/cache/bin/main/org/alter/impl/skills/Mining.kt @@ -0,0 +1,503 @@ +package org.alter.impl.skills + +import dev.openrune.definition.dbtables.dbTable +import dev.openrune.definition.util.VarType + +object Mining { + + const val COL_ROCK_OBJECT = 0 + const val COL_LEVEL = 1 + const val COL_XP = 2 + const val COL_ORE_ITEM = 3 + const val COL_RESPAWN_CYCLES = 4 + const val COL_SUCCESS_RATE_LOW = 5 + const val COL_SUCCESS_RATE_HIGH = 6 + const val COL_DEPLETE_MECHANIC = 7 + const val COL_EMPTY_ROCK = 8 + const val CLUE_BASE_CHANCE = 9 + const val COL_TYPE = 10 + const val COL_DEPLETE_MIN_AMOUNT = 11 + const val COL_DEPLETE_MAX_AMOUNT = 12 + const val COL_MINING_ENHANCERS = 13 + + val PICKAXE_DATA = mapOf( + "items.bronze_pickaxe" to Triple(1, 8, Triple("sequences.human_mining_bronze_pickaxe", "sequences.human_mining_bronze_pickaxe_wall", "dbrows.mining_bronze_pickaxe")), + "items.iron_pickaxe" to Triple(1, 7, Triple("sequences.human_mining_iron_pickaxe", "sequences.human_mining_iron_pickaxe_wall","dbrows.mining_iron_pickaxe")), + "items.steel_pickaxe" to Triple(6, 6, Triple("sequences.human_mining_steel_pickaxe", "sequences.human_mining_steel_pickaxe_wall", "dbrows.mining_steel_pickaxe")), + "items.black_pickaxe" to Triple(11, 5, Triple("sequences.human_mining_black_pickaxe", "sequences.human_mining_black_pickaxe_wall", "dbrows.mining_black_pickaxe")), + "items.mithril_pickaxe" to Triple(21, 5, Triple("sequences.human_mining_mithril_pickaxe","sequences.human_mining_mithril_pickaxe_wall", "dbrows.mining_mithril_pickaxe")), + "items.adamant_pickaxe" to Triple(31, 4, Triple("sequences.human_mining_adamant_pickaxe","sequences.human_mining_adamant_pickaxe_wall", "dbrows.mining_adamant_pickaxe")), + "items.rune_pickaxe" to Triple(41, 3, Triple("sequences.human_mining_rune_pickaxe", "sequences.human_mining_rune_pickaxe_wall", "dbrows.mining_rune_pickaxe")), + "items.dragon_pickaxe" to Triple(61, 2, Triple("sequences.human_mining_dragon_pickaxe", "sequences.human_mining_dragon_pickaxe_wall", "dbrows.mining_dragon_pickaxe")), + "items.3a_pickaxe" to Triple(61, 2, Triple("sequences.human_mining_3a_pickaxe", "sequences.human_mining_3a_pickaxe_wall", "dbrows.mining_3a_pickaxe")), + "items.infernal_pickaxe" to Triple(61, 2, Triple("sequences.human_mining_infernal_pickaxe", "sequences.human_mining_infernal_pickaxe_wall", "dbrows.mining_infernal_pickaxe")), + "items.crystal_pickaxe" to Triple(71, 2, Triple("sequences.human_mining_crystal_pickaxe", "sequences.human_mining_crystal_pickaxe_wall", "dbrows.mining_crystal_pickaxe")) + ) + + const val ITEM = 0 + const val LEVEL = 1 + const val DELAY = 2 + const val ANIMATION = 3 + const val WALL_ANIMATION = 4 + + + fun pickaxes() = dbTable("tables.mining_pickaxes", serverOnly = true) { + column("item", ITEM, VarType.OBJ) + column("level", LEVEL, VarType.INT) + column("delay", DELAY, VarType.INT) + column("animation", ANIMATION, VarType.SEQ) + column("wall_animation", WALL_ANIMATION, VarType.SEQ) + + PICKAXE_DATA.forEach { (item, data) -> + // data = Triple(level, delay, Triple(animation, wallAnimation, dbrow)) + val (level, delay, animTriple) = data + val (animation, wallAnimation, dbrow) = animTriple + + row(dbrow) { + columnRSCM(ITEM, item) + column(LEVEL, level) + column(DELAY, delay) + columnRSCM(ANIMATION, animation) + columnRSCM(WALL_ANIMATION, wallAnimation) + } + } + } + + + fun rocks() = dbTable("tables.mining_rocks", serverOnly = true) { + + column("rock_object", COL_ROCK_OBJECT, VarType.LOC) + column("level", COL_LEVEL, VarType.INT) + column("xp", COL_XP, VarType.INT) + column("ore_item", COL_ORE_ITEM, VarType.OBJ) + column("respawn_cycles", COL_RESPAWN_CYCLES, VarType.INT) + column("success_rate_low", COL_SUCCESS_RATE_LOW, VarType.INT) + column("success_rate_high", COL_SUCCESS_RATE_HIGH, VarType.INT) + column("deplete_mechanic", COL_DEPLETE_MECHANIC, VarType.INT) + column("empty_rock_object", COL_EMPTY_ROCK, VarType.LOC) + column("clue_base_chance", CLUE_BASE_CHANCE, VarType.INT) + column("type", COL_TYPE, VarType.STRING) + column("deplete_min_amount", COL_DEPLETE_MIN_AMOUNT, VarType.INT) + column("deplete_max_amount", COL_DEPLETE_MAX_AMOUNT, VarType.INT) + column("mining_enhancers", COL_MINING_ENHANCERS, VarType.DBROW) + + // Clayrocks (level 1) + row("dbrows.mining_clayrock") { + columnRSCM(COL_ROCK_OBJECT, "objects.clayrock1", "objects.clayrock2") + column(COL_LEVEL, 1) + column(COL_XP, 5) + columnRSCM(COL_ORE_ITEM, "items.clay") + column(COL_RESPAWN_CYCLES, 2) + column(COL_SUCCESS_RATE_LOW, 128) + column(COL_SUCCESS_RATE_HIGH, 400) + column(COL_DEPLETE_MECHANIC, 1) // Normal + columnRSCM(COL_EMPTY_ROCK, "objects.rocks2") + column(CLUE_BASE_CHANCE, 741600) + column(COL_TYPE, "rock") + columnRSCM(COL_MINING_ENHANCERS,"dbrows.mining_enhancers_clay") + } + // Copper (level 1) + row("dbrows.mining_copperrock") { + columnRSCM(COL_ROCK_OBJECT, "objects.copperrock1", "objects.copperrock2") + column(COL_LEVEL, 1) + column(COL_XP, 17.5) + columnRSCM(COL_ORE_ITEM, "items.copper_ore") + column(COL_RESPAWN_CYCLES, 4) + column(COL_SUCCESS_RATE_LOW, 100) + column(COL_SUCCESS_RATE_HIGH, 350) + column(COL_DEPLETE_MECHANIC, 1) // Normal + columnRSCM(COL_EMPTY_ROCK, "objects.rocks2") + column(CLUE_BASE_CHANCE, 741600) + column(COL_TYPE, "rock") + columnRSCM(COL_MINING_ENHANCERS,"dbrows.mining_enhancers_copper") + } + // Tin (level 1) + row("dbrows.mining_tinrock") { + columnRSCM(COL_ROCK_OBJECT, "objects.tinrock1", "objects.tinrock2") + column(COL_LEVEL, 1) + column(COL_XP, 17.5) + columnRSCM(COL_ORE_ITEM, "items.tin_ore") + column(COL_RESPAWN_CYCLES, 4) + column(COL_SUCCESS_RATE_LOW, 100) + column(COL_SUCCESS_RATE_HIGH, 350) + column(COL_DEPLETE_MECHANIC, 1) // Normal + columnRSCM(COL_EMPTY_ROCK, "objects.rocks2") + column(CLUE_BASE_CHANCE, 741600) + column(COL_TYPE, "rock") + columnRSCM(COL_MINING_ENHANCERS,"dbrows.mining_enhancers_tin") + } + // Blurite (level 10) + row("dbrows.mining_bluriterock") { + columnRSCM(COL_ROCK_OBJECT, "objects.blurite_rock_1", "objects.blurite_rock_2") + column(COL_LEVEL, 10) + column(COL_XP, 17.5) + columnRSCM(COL_ORE_ITEM, "items.blurite_ore") + column(COL_RESPAWN_CYCLES, 42) + column(COL_SUCCESS_RATE_LOW, 90) + column(COL_SUCCESS_RATE_HIGH, 350) + column(COL_DEPLETE_MECHANIC, 1) // Normal + columnRSCM(COL_EMPTY_ROCK, "objects.rocks2") + column(CLUE_BASE_CHANCE, 741600) + column(COL_TYPE, "rock") + columnRSCM(COL_MINING_ENHANCERS,"dbrows.mining_enhancers_blurite") + } + // Iron (level 15) + row("dbrows.mining_ironrock") { + columnRSCM(COL_ROCK_OBJECT, "objects.ironrock1", "objects.ironrock2") + column(COL_LEVEL, 15) + column(COL_XP, 35) + columnRSCM(COL_ORE_ITEM, "items.iron_ore") + column(COL_RESPAWN_CYCLES, 9) + column(COL_SUCCESS_RATE_LOW, 96) + column(COL_SUCCESS_RATE_HIGH, 350) + column(COL_DEPLETE_MECHANIC, 1) // Normal + columnRSCM(COL_EMPTY_ROCK, "objects.rocks2") + column(CLUE_BASE_CHANCE, 741600) + column(COL_TYPE, "rock") + columnRSCM(COL_MINING_ENHANCERS,"dbrows.mining_enhancers_iron") + } + // Silver (level 20) + row("dbrows.mining_silverrock") { + columnRSCM(COL_ROCK_OBJECT, "objects.silverrock1", "objects.silverrock2") + column(COL_LEVEL, 20) + column(COL_XP, 40) + columnRSCM(COL_ORE_ITEM, "items.silver_ore") + column(COL_RESPAWN_CYCLES, 100) + column(COL_SUCCESS_RATE_LOW, 25) + column(COL_SUCCESS_RATE_HIGH, 200) + column(COL_DEPLETE_MECHANIC, 1) // Normal + columnRSCM(COL_EMPTY_ROCK, "objects.rocks2") + column(CLUE_BASE_CHANCE, 741600) + column(COL_TYPE, "rock") + columnRSCM(COL_MINING_ENHANCERS,"dbrows.mining_enhancers_silver") + } + // Lead (level 25) + row("dbrows.mining_leadrock") { + columnRSCM(COL_ROCK_OBJECT, "objects.leadrock1", "objects.poh_deadman_rugcorner") //Temp. added poh_deadman_rugcorner cause it cant read only one object. + column(COL_LEVEL, 25) + column(COL_XP, 40.5) + columnRSCM(COL_ORE_ITEM, "items.lead_ore") + column(COL_RESPAWN_CYCLES, 10) + column(COL_SUCCESS_RATE_LOW, 110) + column(COL_SUCCESS_RATE_HIGH, 255) + column(COL_DEPLETE_MECHANIC, 1) // Normal + columnRSCM(COL_EMPTY_ROCK, "objects.leadrock1_empty") + column(CLUE_BASE_CHANCE, 290641) + column(COL_TYPE, "rock") + columnRSCM(COL_MINING_ENHANCERS,"dbrows.mining_enhancers_lead") + } + // Coal (level 30) + row("dbrows.mining_coalrock") { + columnRSCM(COL_ROCK_OBJECT, "objects.coalrock1", "objects.coalrock2") + column(COL_LEVEL, 30) + column(COL_XP, 50) + columnRSCM(COL_ORE_ITEM, "items.coal") + column(COL_RESPAWN_CYCLES, 50) + column(COL_SUCCESS_RATE_LOW, 16) + column(COL_SUCCESS_RATE_HIGH, 100) + column(COL_DEPLETE_MECHANIC, 1) // Normal + columnRSCM(COL_EMPTY_ROCK, "objects.rocks2") + column(CLUE_BASE_CHANCE, 290640) + column(COL_TYPE, "rock") + columnRSCM(COL_MINING_ENHANCERS,"dbrows.mining_enhancers_coal") + } + // Gem (level 40) + row("dbrows.mining_gemrock") { + columnRSCM(COL_ROCK_OBJECT, "objects.gemrock1", "objects.gemrock") + column(COL_LEVEL, 40) + column(COL_XP, 65) + column(COL_RESPAWN_CYCLES, 99) + column(COL_SUCCESS_RATE_LOW, 28) + column(COL_SUCCESS_RATE_HIGH, 70) + column(COL_DEPLETE_MECHANIC, 2) // Normal + columnRSCM(COL_EMPTY_ROCK, "objects.rocks1") + column(CLUE_BASE_CHANCE, 211866) + column(COL_TYPE, "gemrock") + column(COL_DEPLETE_MIN_AMOUNT, 3) + column(COL_DEPLETE_MAX_AMOUNT, 3) + } + //Gold (level 40) + row("dbrows.mining_goldrock") { + columnRSCM(COL_ROCK_OBJECT, "objects.goldrock1", "objects.goldrock2") + column(COL_LEVEL, 40) + column(COL_XP, 65) + columnRSCM(COL_ORE_ITEM, "items.gold_ore") + column(COL_RESPAWN_CYCLES, 100) + column(COL_SUCCESS_RATE_LOW, 7) + column(COL_SUCCESS_RATE_HIGH, 75) + column(COL_DEPLETE_MECHANIC, 1) // Normal + columnRSCM(COL_EMPTY_ROCK, "objects.rocks2") + column(CLUE_BASE_CHANCE, 296640) + column(COL_TYPE, "rock") + columnRSCM(COL_MINING_ENHANCERS,"dbrows.mining_enhancers_gold") + } + //Mith (level 55) + row("dbrows.mining_mithrilrock") { + columnRSCM(COL_ROCK_OBJECT, "objects.mithrilrock1", "objects.mithrilrock2") + column(COL_LEVEL, 55) + column(COL_XP, 80) + columnRSCM(COL_ORE_ITEM, "items.mithril_ore") + column(COL_RESPAWN_CYCLES, 200) + column(COL_SUCCESS_RATE_LOW, 4) + column(COL_SUCCESS_RATE_HIGH, 50) + column(COL_DEPLETE_MECHANIC, 1) // Normal + columnRSCM(COL_EMPTY_ROCK, "objects.rocks2") + column(CLUE_BASE_CHANCE, 148320) + column(COL_TYPE, "rock") + columnRSCM(COL_MINING_ENHANCERS,"dbrows.mining_enhancers_mithril") + } + //Lovakite (level 65) + row("dbrows.mining_lovakiterock") { + columnRSCM(COL_ROCK_OBJECT, "objects.lovakite_rock1", "objects.lovakite_rock2") + column(COL_LEVEL, 65) + column(COL_XP, 60) + columnRSCM(COL_ORE_ITEM, "items.lovakite_ore") + column(COL_RESPAWN_CYCLES, 59) + column(COL_SUCCESS_RATE_LOW, 2) + column(COL_SUCCESS_RATE_HIGH, 50) + column(COL_DEPLETE_MECHANIC, 1) + columnRSCM(COL_EMPTY_ROCK, "objects.rocks2") + column(CLUE_BASE_CHANCE, 245562) + column(COL_TYPE, "rock") + columnRSCM(COL_MINING_ENHANCERS,"dbrows.mining_enhancers_lovakite") + } + //Addy (Level 70) + row("dbrows.mining_adamantiterock") { + columnRSCM(COL_ROCK_OBJECT, "objects.adamantiterock1", "objects.adamantiterock2") + column(COL_LEVEL, 70) + column(COL_XP, 95) + columnRSCM(COL_ORE_ITEM, "items.adamantite_ore") + column(COL_RESPAWN_CYCLES, 400) + column(COL_SUCCESS_RATE_LOW, 2) + column(COL_SUCCESS_RATE_HIGH, 25) + column(COL_DEPLETE_MECHANIC, 1) // Normal + columnRSCM(COL_EMPTY_ROCK, "objects.rocks2") + column(CLUE_BASE_CHANCE, 59328) + column(COL_TYPE, "rock") + columnRSCM(COL_MINING_ENHANCERS,"dbrows.mining_enhancers_adamantite") + } + //Nickel (Level 74) + row("dbrows.mining_nickelrock") { + columnRSCM(COL_ROCK_OBJECT, "objects.nickelrock1", "objects.deadman_final_wallsupport")//Temp. added deadman_final_wallsupport cause it cant read only one object. + column(COL_LEVEL, 70) + column(COL_XP, 95) + columnRSCM(COL_ORE_ITEM, "items.nickel_ore") + column(COL_RESPAWN_CYCLES, 200) + column(COL_SUCCESS_RATE_LOW, -1) + column(COL_SUCCESS_RATE_HIGH, 25) + column(COL_DEPLETE_MECHANIC, 1) // Normal + columnRSCM(COL_EMPTY_ROCK, "objects.nickelrock1_empty") + column(CLUE_BASE_CHANCE, 59328) + column(COL_TYPE, "rock") + columnRSCM(COL_MINING_ENHANCERS,"dbrows.mining_enhancers_nickel") + } + row("dbrows.mining_runiterock") { + columnRSCM(COL_ROCK_OBJECT, "objects.runiterock1", "objects.runiterock2") + column(COL_LEVEL, 85) + column(COL_XP, 125) + columnRSCM(COL_ORE_ITEM, "items.runite_ore") + column(COL_RESPAWN_CYCLES, 312) + column(COL_SUCCESS_RATE_LOW, 1) + column(COL_SUCCESS_RATE_HIGH, 18) + column(COL_DEPLETE_MECHANIC, 1) // Normal + columnRSCM(COL_EMPTY_ROCK, "objects.rocks2") + column(CLUE_BASE_CHANCE, 42377) + column(COL_TYPE, "rock") + columnRSCM(COL_MINING_ENHANCERS,"dbrows.mining_enhancers_runite") + + } + // Amethystrock (level 92 + row("dbrows.mining_amethystrock") { + columnRSCM(COL_ROCK_OBJECT, "objects.amethystrock1", "objects.amethystrock2") + column(COL_LEVEL, 92) + column(COL_XP, 240) + columnRSCM(COL_ORE_ITEM, "items.amethyst") + column(COL_RESPAWN_CYCLES, 125) + column(COL_SUCCESS_RATE_LOW, -18) + column(COL_SUCCESS_RATE_HIGH, 10) + column(COL_DEPLETE_MECHANIC, 2) + columnRSCM(COL_EMPTY_ROCK, "objects.amethystrock_empty") + column(CLUE_BASE_CHANCE, 46350) + column(COL_TYPE, "wall") + column(COL_DEPLETE_MIN_AMOUNT, 2) + column(COL_DEPLETE_MAX_AMOUNT, 3) + columnRSCM(COL_MINING_ENHANCERS,"dbrows.mining_enhancers_amethyst") + } + // Essence (level ) + row("dbrows.mining_essence") { + columnRSCM(COL_ROCK_OBJECT, "objects.blankrunestone") + column(COL_LEVEL, 1) + column(COL_XP, 5) + columnRSCM(COL_ORE_ITEM, "items.blankrune") + column(COL_RESPAWN_CYCLES, 0) + column(COL_SUCCESS_RATE_LOW, 256) + column(COL_SUCCESS_RATE_HIGH, 256) + column(COL_DEPLETE_MECHANIC, 3) // Always + column(CLUE_BASE_CHANCE, 317647) + column(COL_TYPE, "wall") + } + } + + + const val MINING_GLOVES = 0 + const val VARROCK_ARMOUR = 1 + const val RINGORSIGNET = 2 + const val MINING_CAPE = 3 + + fun miningEnhancers() = dbTable("tables.mining_enhancers", serverOnly = true) { + column("mining_gloves", MINING_GLOVES, VarType.STRING) + column("varrock_armour_level", VARROCK_ARMOUR, VarType.INT) + column("ring_or_signet", RINGORSIGNET, VarType.BOOLEAN) + column("mining_cape", MINING_CAPE, VarType.BOOLEAN) + + row("dbrows.mining_enhancers_clay") { + column(VARROCK_ARMOUR, 1) + column(RINGORSIGNET, true) + column(MINING_CAPE, true) + } + + row("dbrows.mining_enhancers_copper") { + column(MINING_GLOVES, "standard") + column(VARROCK_ARMOUR, 1) + column(RINGORSIGNET, true) + column(MINING_CAPE, true) + } + + row("dbrows.mining_enhancers_tin") { + column(MINING_GLOVES, "standard") + column(VARROCK_ARMOUR, 1) + column(RINGORSIGNET, true) + column(MINING_CAPE, true) + } + + row("dbrows.mining_enhancers_guardian_remains") { + column(VARROCK_ARMOUR, 1) + column(RINGORSIGNET, true) + column(MINING_CAPE, true) + } + + row("dbrows.mining_enhancers_tephra") { + column(VARROCK_ARMOUR, 1) + column(RINGORSIGNET, true) + column(MINING_CAPE, true) + } + + row("dbrows.mining_enhancers_blurite") { + column(VARROCK_ARMOUR, 1) + column(RINGORSIGNET, true) + column(MINING_CAPE, true) + } + + row("dbrows.mining_enhancers_limestone") { + column(VARROCK_ARMOUR, 1) + column(RINGORSIGNET, true) + column(MINING_CAPE, true) + } + + row("dbrows.mining_enhancers_iron") { + column(MINING_GLOVES, "standard") + column(VARROCK_ARMOUR, 1) + column(RINGORSIGNET, true) + column(MINING_CAPE, true) + } + + row("dbrows.mining_enhancers_silver") { + column(MINING_GLOVES, "standard") + column(VARROCK_ARMOUR, 1) + column(RINGORSIGNET, true) + column(MINING_CAPE, true) + } + + row("dbrows.mining_enhancers_lead") { + column(MINING_GLOVES, "standard") + column(VARROCK_ARMOUR, 1) + column(RINGORSIGNET, true) + column(MINING_CAPE, true) + } + + row("dbrows.mining_enhancers_coal") { + column(MINING_GLOVES, "standard") + column(VARROCK_ARMOUR, 1) + column(RINGORSIGNET, true) + column(MINING_CAPE, true) + } + + row("dbrows.mining_enhancers_sandstone") { + column(MINING_GLOVES, "expert") + column(VARROCK_ARMOUR, 2) + column(RINGORSIGNET, true) + column(MINING_CAPE, true) + } + + row("dbrows.mining_enhancers_gold") { + column(MINING_GLOVES, "standard") + column(VARROCK_ARMOUR, 1) + column(RINGORSIGNET, true) + column(MINING_CAPE, true) + } + + row("dbrows.mining_enhancers_volcanic_sulphur") { + column(MINING_CAPE, true) + column(RINGORSIGNET, true) + } + + row("dbrows.mining_enhancers_granite") { + column(VARROCK_ARMOUR, 2) + column(RINGORSIGNET, true) + column(MINING_CAPE, true) + } + + row("dbrows.mining_enhancers_mithril") { + column(MINING_GLOVES, "superior") + column(VARROCK_ARMOUR, 2) + column(RINGORSIGNET, true) + column(MINING_CAPE, true) + } + + row("dbrows.mining_enhancers_lovakite") { + column(VARROCK_ARMOUR, 2) + column(RINGORSIGNET, true) + column(MINING_CAPE, true) + } + + row("dbrows.mining_enhancers_amalgamation") { + column(VARROCK_ARMOUR, 3) + column(RINGORSIGNET, true) + column(MINING_CAPE, true) + } + + row("dbrows.mining_enhancers_adamantite") { + column(MINING_GLOVES, "superior") + column(VARROCK_ARMOUR, 3) + column(RINGORSIGNET, true) + column(MINING_CAPE, true) + } + + row("dbrows.mining_enhancers_soft_clay") { + column(VARROCK_ARMOUR, 2) + column(RINGORSIGNET, true) + column(MINING_CAPE, true) + } + + row("dbrows.mining_enhancers_nickel") { + column(VARROCK_ARMOUR, 4) + column(RINGORSIGNET, false) + column(MINING_CAPE, false) + } + + row("dbrows.mining_enhancers_runite") { + column(MINING_GLOVES, "expert") + column(VARROCK_ARMOUR, 4) + column(RINGORSIGNET, false) + column(MINING_CAPE, false) + } + + row("dbrows.mining_enhancers_amethyst") { + column(MINING_GLOVES, "expert") + column(VARROCK_ARMOUR, 4) + column(RINGORSIGNET, false) + column(MINING_CAPE, false) + } + } +} + diff --git a/cache/bin/main/org/alter/impl/skills/PrayerTable.kt b/cache/bin/main/org/alter/impl/skills/PrayerTable.kt new file mode 100644 index 00000000..d6a72858 --- /dev/null +++ b/cache/bin/main/org/alter/impl/skills/PrayerTable.kt @@ -0,0 +1,230 @@ +package org.alter.impl.skills + +import dev.openrune.definition.dbtables.dbTable +import dev.openrune.definition.util.VarType + +object PrayerTable { + + fun skillTable() = dbTable("tables.skill_prayer", serverOnly = true) { + + column("item", 0, VarType.OBJ) + column("exp", 1, VarType.INT) + column("ashes", 2, VarType.BOOLEAN) + + row("dbrows.bones") { + columnRSCM(0, "items.bones") + column(1, 5) + column(2, false) + } + + row("dbrows.wolfbones") { + columnRSCM(0, "items.wolf_bones") + column(1, 5) + column(2, false) + } + + row("dbrows.burntbones") { + columnRSCM(0, "items.bones_burnt") + column(1, 5) + column(2, false) + } + + row("dbrows.monkeybones") { + columnRSCM(0, "items.mm_normal_monkey_bones") + column(1, 5) + column(2, false) + } + + row("dbrows.batbones") { + columnRSCM(0, "items.bat_bones") + column(1, 5) + column(2, false) + } + + row("dbrows.bigbones") { + columnRSCM(0, "items.big_bones") + column(1, 15) + column(2, false) + } + + row("dbrows.jogrebones") { + columnRSCM(0, "items.tbwt_jogre_bones") + column(1, 15) + column(2, false) + } + + row("dbrows.wyrmlingbones") { + columnRSCM(0, "items.babywyrm_bones") + column(1, 21) + column(2, false) + } + + row("dbrows.zogrebones") { + columnRSCM(0, "items.zogre_bones") + column(1, 23) + column(2, false) + } + + row("dbrows.shaikahanbones") { + columnRSCM(0, "items.tbwt_beast_bones") + column(1, 25) + column(2, false) + } + + row("dbrows.babydragonbones") { + columnRSCM(0, "items.babydragon_bones") + column(1, 30) + column(2, false) + } + + row("dbrows.wyrmbones") { + columnRSCM(0, "items.wyrm_bones") + column(1, 50) + column(2, false) + } + + row("dbrows.wyvernbones") { + columnRSCM(0, "items.wyvern_bones") + column(1, 72) + column(2, false) + } + + row("dbrows.dragonbones") { + columnRSCM(0, "items.dragon_bones") + column(1, 72) + column(2, false) + } + + row("dbrows.drakebones") { + columnRSCM(0, "items.drake_bones") + column(1, 80) + column(2, false) + } + + row("dbrows.fayrgbones") { + columnRSCM(0, "items.zogre_ancestral_bones_fayg") + column(1, 84) + column(2, false) + } + + row("dbrows.lavadragonbones") { + columnRSCM(0, "items.lava_dragon_bones") + column(1, 85) + column(2, false) + } + + row("dbrows.raurgbones") { + columnRSCM(0, "items.zogre_ancestral_bones_raurg") + column(1, 96) + column(2, false) + } + + row("dbrows.hydrabones") { + columnRSCM(0, "items.hydra_bones") + column(1, 110) + column(2, false) + } + + row("dbrows.dagannothbones") { + columnRSCM(0, "items.dagannoth_king_bones") + column(1, 125) + column(2, false) + } + + row("dbrows.ourgbones") { + columnRSCM(0, "items.zogre_ancestral_bones_ourg") + column(1, 140) + column(2, false) + } + + row("dbrows.superiordragonbones") { + columnRSCM(0, "items.dragon_bones_superior") + column(1, 150) + column(2, false) + } + + row("dbrows.alansbones") { + columnRSCM(0, "items.alan_bones") + column(1, 3) + column(2, false) + } + + row("dbrows.bonesapeatoll") { + columnRSCM(0, "items.mm_skeleton_bones") + column(1, 3) + column(2, false) + } + + row("dbrows.bleachedbones") { + columnRSCM(0, "items.shade_bleached_bones") + column(1, 5) + column(2, false) + } + + row("dbrows.smallzombiemonkeybones") { + columnRSCM(0, "items.mm_small_zombie_monkey_bones") + column(1, 5) + column(2, false) + } + + row("dbrows.largezombiemonkeybones") { + columnRSCM(0, "items.mm_large_zombie_monkey_bones") + column(1, 5) + column(2, false) + } + + row("dbrows.smallninjamonkeybones") { + columnRSCM(0, "items.mm_small_ninja_monkey_bones") + column(1, 16) + column(2, false) + } + + row("dbrows.mediumninjamonkeybones") { + columnRSCM(0, "items.mm_medium_ninja_monkey_bones") + column(1, 18) + column(2, false) + } + + row("dbrows.gorillabones") { + columnRSCM(0, "items.mm_normal_gorilla_monkey_bones") + column(1, 18) + column(2, false) + } + + row("dbrows.beardedgorillabones") { + columnRSCM(0, "items.mm_bearded_gorilla_monkey_bones") + column(1, 18) + column(2, true) + } + + row("dbrows.fiendishashes") { + columnRSCM(0, "items.fiendish_ashes") + column(1, 10) + column(2, true) + } + + row("dbrows.vileashes") { + columnRSCM(0, "items.vile_ashes") + column(1, 25) + column(2, true) + } + + row("dbrows.maliciousashes") { + columnRSCM(0, "items.malicious_ashes") + column(1, 65) + column(2, true) + } + + row("dbrows.abyssalashes") { + columnRSCM(0, "items.abyssal_ashes") + column(1, 85) + column(2, true) + } + + row("dbrows.infernalashes") { + columnRSCM(0, "items.infernal_ashes") + column(1, 110) + column(2, true) + } + } +} \ No newline at end of file diff --git a/cache/bin/main/org/alter/impl/skills/Smithing.kt b/cache/bin/main/org/alter/impl/skills/Smithing.kt new file mode 100644 index 00000000..1bedb65a --- /dev/null +++ b/cache/bin/main/org/alter/impl/skills/Smithing.kt @@ -0,0 +1,465 @@ +package org.alter.impl.skills + +import dev.openrune.definition.dbtables.dbTable +import dev.openrune.definition.util.VarType + +object Smithing { + + const val COL_OUTPUT = 0 + const val COL_LEVEL = 1 + const val COL_SMELT_XP = 2 + const val COL_SMITH_XP = 3 + const val COL_SMELT_XP_ALTERNATE = 4 + const val COL_INPUT_PRIMARY = 5 + const val COL_INPUT_SECONDARY = 6 + const val COL_INPUT_PRIMARY_AMT = 7 + const val COL_INPUT_SECONDARY_AMT = 8 + const val COL_INPUT_PREFIX = 9 + + const val COL_CANNONBALL_BAR = 0 + const val COL_CANNONBALL_OUTPUT = 1 + const val COL_CANNONBALL_LEVEL = 2 + const val COL_CANNONBALL_XP = 3 + + fun cannonBalls() = dbTable("tables.smithing_cannon_balls",serverOnly = true) { + column("bar", COL_CANNONBALL_BAR, VarType.OBJ) + column("output", COL_CANNONBALL_OUTPUT, VarType.OBJ) + column("level", COL_CANNONBALL_LEVEL, VarType.INT) + column("xp", COL_CANNONBALL_XP, VarType.INT) + + row("dbrows.bronze_cannon_ball") { + columnRSCM(COL_CANNONBALL_BAR,"items.bronze_bar") + columnRSCM(COL_CANNONBALL_OUTPUT,"items.bronze_cannonball") + column(COL_CANNONBALL_LEVEL,5) + column(COL_CANNONBALL_XP,9) + } + + row("dbrows.iron_cannon_ball") { + columnRSCM(COL_CANNONBALL_BAR,"items.bronze_bar") + columnRSCM(COL_CANNONBALL_OUTPUT,"items.iron_cannonball") + column(COL_CANNONBALL_LEVEL,20) + column(COL_CANNONBALL_XP,17) + } + + row("dbrows.steel_cannon_ball") { + columnRSCM(COL_CANNONBALL_BAR,"items.steel_bar") + columnRSCM(COL_CANNONBALL_OUTPUT,"items.mcannonball") + column(COL_CANNONBALL_LEVEL,35) + column(COL_CANNONBALL_XP,27) + } + + row("dbrows.mithril_cannon_ball") { + columnRSCM(COL_CANNONBALL_BAR,"items.mithril_bar") + columnRSCM(COL_CANNONBALL_OUTPUT,"items.mithril_cannonball") + column(COL_CANNONBALL_LEVEL,55) + column(COL_CANNONBALL_XP,34) + } + + row("dbrows.adamantite_cannon_ball") { + columnRSCM(COL_CANNONBALL_BAR,"items.adamantite_bar") + columnRSCM(COL_CANNONBALL_OUTPUT,"items.adamant_cannonball") + column(COL_CANNONBALL_LEVEL,75) + column(COL_CANNONBALL_XP,43) + } + + row("dbrows.runite_cannon_ball") { + columnRSCM(COL_CANNONBALL_BAR,"items.runite_bar") + columnRSCM(COL_CANNONBALL_OUTPUT,"items.rune_cannonball") + column(COL_CANNONBALL_LEVEL,90) + column(COL_CANNONBALL_XP,51) + } + + + } + + const val COL_DRAGON_OUTPUT = 0 + const val COL_DRAGON_OUTPUT_AMT = 1 + const val COL_DRAGON_LEVEL = 2 + const val COL_DRAGON_XP = 3 + const val COL_DRAGON_INPUT_PRIMARY = 4 + const val COL_DRAGON_INPUT_PRIMARY_AMT = 5 + + + fun dragonForge() = dbTable("tables.smithing_dragon_forge",serverOnly = true) { + column("output", COL_DRAGON_OUTPUT, VarType.OBJ) + column("output_amt", COL_DRAGON_OUTPUT_AMT, VarType.INT) + column("level", COL_DRAGON_LEVEL, VarType.INT) + column("xp", COL_DRAGON_XP, VarType.INT) + column("input_primary", COL_DRAGON_INPUT_PRIMARY, VarType.OBJ) + column("input_primary_amt", COL_DRAGON_INPUT_PRIMARY_AMT, VarType.INT) + + row("dbrows.dragon_keel_parts") { + columnRSCM(COL_DRAGON_OUTPUT, "items.sailing_boat_keel_part_dragon") + column(COL_DRAGON_OUTPUT_AMT, 1) + column(COL_DRAGON_LEVEL, 94) + column(COL_DRAGON_XP, 700) + columnRSCM(COL_DRAGON_INPUT_PRIMARY, "items.dragon_sheet") + column(COL_DRAGON_INPUT_PRIMARY_AMT, 2) + } + + row("dbrows.dragon_key") { + columnRSCM(COL_DRAGON_OUTPUT, "items.dragonkin_key") + column(COL_DRAGON_OUTPUT_AMT, 1) + column(COL_DRAGON_LEVEL, 70) + column(COL_DRAGON_XP, 0) + column(COL_DRAGON_INPUT_PRIMARY_AMT, 1) + columnRSCM(COL_DRAGON_INPUT_PRIMARY, "items.dragonkin_key_frem","items.dragonkin_key_mory", "items.dragonkin_key_zeah","items.dragonkin_key_karam") + } + + row("dbrows.dragon_kiteshield") { + columnRSCM(COL_DRAGON_OUTPUT, "items.dragon_kiteshield") + column(COL_DRAGON_OUTPUT_AMT, 1) + column(COL_DRAGON_LEVEL, 75) + column(COL_DRAGON_XP, 1000) + columnRSCM(COL_DRAGON_INPUT_PRIMARY, "items.dragon_sq_shield","items.dragon_slice", "items.dragon_shard") + column(COL_DRAGON_INPUT_PRIMARY_AMT, 1) + } + + row("dbrows.dragon_nails") { + columnRSCM(COL_DRAGON_OUTPUT, "items.nails_dragon") + column(COL_DRAGON_OUTPUT_AMT, 15) + column(COL_DRAGON_LEVEL, 92) + column(COL_DRAGON_XP, 350) + columnRSCM(COL_DRAGON_INPUT_PRIMARY, "items.dragon_sheet") + column(COL_DRAGON_INPUT_PRIMARY_AMT, 1) + } + + row("dbrows.dragon_platebody") { + columnRSCM(COL_DRAGON_OUTPUT, "items.dragon_platebody") + column(COL_DRAGON_OUTPUT_AMT, 1) + column(COL_DRAGON_LEVEL, 90) + column(COL_DRAGON_XP, 2000) + column(COL_DRAGON_INPUT_PRIMARY_AMT, 1) + columnRSCM(COL_DRAGON_INPUT_PRIMARY, "items.dragon_chainbody","items.dragon_lump", "items.dragon_shard") + } + + row("dbrows.large_dragon_keel_parts") { + columnRSCM(COL_DRAGON_OUTPUT, "items.sailing_boat_large_keel_part_dragon") + column(COL_DRAGON_OUTPUT_AMT, 1) + column(COL_DRAGON_LEVEL, 94) + column(COL_DRAGON_XP, 500) + columnRSCM(COL_DRAGON_INPUT_PRIMARY, "items.sailing_boat_keel_part_dragon") + column(COL_DRAGON_INPUT_PRIMARY_AMT, 2) + } + } + + fun bars() = dbTable("tables.smithing_bars",serverOnly = true) { + + column("output", COL_OUTPUT, VarType.OBJ) + column("level", COL_LEVEL, VarType.INT) + column("smeltXp", COL_SMELT_XP, VarType.INT) + column("smithXp", COL_SMITH_XP, VarType.INT) + column("smithXpAlternate", COL_SMELT_XP_ALTERNATE, VarType.INT) + column("input_primary", COL_INPUT_PRIMARY, VarType.OBJ) + column("input_secondary", COL_INPUT_SECONDARY, VarType.OBJ) + column("input_primary_amt", COL_INPUT_PRIMARY_AMT, VarType.INT) + column("input_secondary_amt", COL_INPUT_SECONDARY_AMT, VarType.INT) + column("prefix", COL_INPUT_PREFIX, VarType.STRING) + + row("dbrows.bronze") { + columnRSCM(COL_OUTPUT,"items.bronze_bar") + column(COL_LEVEL,1) + column(COL_SMELT_XP,6) + column(COL_SMITH_XP,12) + columnRSCM(COL_INPUT_PRIMARY,"items.tin_ore") + columnRSCM(COL_INPUT_SECONDARY,"items.copper_ore") + column(COL_INPUT_PRIMARY_AMT,1) + column(COL_INPUT_SECONDARY_AMT,1) + column(COL_INPUT_PREFIX,"bronze") + + } + + row("dbrows.blurite") { + columnRSCM(COL_OUTPUT,"items.blurite_bar") + column(COL_LEVEL,13) + column(COL_SMELT_XP,8) + column(COL_SMELT_XP_ALTERNATE,10) + column(COL_SMITH_XP,17) + columnRSCM(COL_INPUT_PRIMARY,"items.blurite_ore") + column(COL_INPUT_PRIMARY_AMT,1) + column(COL_INPUT_PREFIX,"blurite") + } + + row("dbrows.iron") { + columnRSCM(COL_OUTPUT,"items.iron_bar") + column(COL_LEVEL,15) + column(COL_SMELT_XP,12) + column(COL_SMITH_XP,25) + columnRSCM(COL_INPUT_PRIMARY,"items.iron_ore") + column(COL_INPUT_PRIMARY_AMT,1) + column(COL_INPUT_PREFIX,"iron") + } + + row("dbrows.silver") { + columnRSCM(COL_OUTPUT,"items.silver_bar") + column(COL_LEVEL,20) + column(COL_SMELT_XP,14) + column(COL_SMITH_XP,50) + columnRSCM(COL_INPUT_PRIMARY,"items.silver_ore") + column(COL_INPUT_PRIMARY_AMT,1) + column(COL_INPUT_PREFIX,"silver") + } + + row("dbrows.lead") { + columnRSCM(COL_OUTPUT,"items.lead_bar") + column(COL_LEVEL,25) + column(COL_SMELT_XP,15) + column(COL_SMITH_XP,0) + columnRSCM(COL_INPUT_PRIMARY,"items.lead_ore") + column(COL_INPUT_PRIMARY_AMT,2) + column(COL_INPUT_PREFIX,"lead") + } + + row("dbrows.steel") { + columnRSCM(COL_OUTPUT,"items.steel_bar") + column(COL_LEVEL,30) + column(COL_SMELT_XP,17) + column(COL_SMITH_XP,37) + columnRSCM(COL_INPUT_PRIMARY,"items.iron_ore") + columnRSCM(COL_INPUT_SECONDARY,"items.coal") + column(COL_INPUT_PRIMARY_AMT,1) + column(COL_INPUT_SECONDARY_AMT,2) + column(COL_INPUT_PREFIX,"steel") + } + + row("dbrows.gold") { + columnRSCM(COL_OUTPUT,"items.gold_bar") + column(COL_LEVEL,30) + column(COL_SMELT_XP,22) + column(COL_SMELT_XP_ALTERNATE,56) + column(COL_SMITH_XP,90) + columnRSCM(COL_INPUT_PRIMARY,"items.gold_ore") + column(COL_INPUT_PRIMARY_AMT,1) + column(COL_INPUT_PREFIX,"gold") + } + + row("dbrows.lovakite") { + columnRSCM(COL_OUTPUT,"items.lovakite_bar") + column(COL_LEVEL,45) + column(COL_SMELT_XP,20) + column(COL_SMITH_XP,60) + columnRSCM(COL_INPUT_PRIMARY,"items.lovakite_ore") + columnRSCM(COL_INPUT_SECONDARY,"items.coal") + column(COL_INPUT_PRIMARY_AMT,1) + column(COL_INPUT_SECONDARY_AMT,2) + column(COL_INPUT_PREFIX,"shayzien") + } + + row("dbrows.mithril") { + columnRSCM(COL_OUTPUT,"items.mithril_bar") + column(COL_LEVEL,50) + column(COL_SMELT_XP,30) + column(COL_SMITH_XP,50) + columnRSCM(COL_INPUT_PRIMARY,"items.mithril_ore") + columnRSCM(COL_INPUT_SECONDARY,"items.coal") + column(COL_INPUT_PRIMARY_AMT,1) + column(COL_INPUT_SECONDARY_AMT,4) + column(COL_INPUT_PREFIX,"mithril") + } + + row("dbrows.adamantite") { + columnRSCM(COL_OUTPUT,"items.adamantite_bar") + column(COL_LEVEL,70) + column(COL_SMELT_XP,37) + column(COL_SMITH_XP,62) + columnRSCM(COL_INPUT_PRIMARY,"items.adamantite_ore") + columnRSCM(COL_INPUT_SECONDARY,"items.coal") + column(COL_INPUT_PRIMARY_AMT,1) + column(COL_INPUT_SECONDARY_AMT,6) + column(COL_INPUT_PREFIX,"adamant") + } + + row("dbrows.cupronickel") { + columnRSCM(COL_OUTPUT,"items.cupronickel_bar") + column(COL_LEVEL,74) + column(COL_SMELT_XP,42) + column(COL_SMITH_XP,0) + columnRSCM(COL_INPUT_PRIMARY,"items.nickel_ore") + columnRSCM(COL_INPUT_SECONDARY,"items.copper_ore") + column(COL_INPUT_PRIMARY_AMT,1) + column(COL_INPUT_SECONDARY_AMT,2) + column(COL_INPUT_PREFIX,"cupronickel") + } + + row("dbrows.runite") { + columnRSCM(COL_OUTPUT,"items.runite_bar") + column(COL_LEVEL,85) + column(COL_SMELT_XP,50) + column(COL_SMITH_XP,75) + columnRSCM(COL_INPUT_PRIMARY,"items.runite_ore") + columnRSCM(COL_INPUT_SECONDARY,"items.coal") + column(COL_INPUT_PRIMARY_AMT,1) + column(COL_INPUT_SECONDARY_AMT,8) + column(COL_INPUT_PREFIX,"rune") + } + } + + const val COL_CRYSTAL_OUTPUT = 0 + const val COL_CRYSTAL_XP = 1 + const val COL_CRYSTAL_LEVEL = 2 + const val COL_CRYSTAL_MATERIALS = 3 + const val COL_CRYSTAL_MATERIALS_AMT = 4 + const val COL_CRYSTAL_MATERIALS_SHORT_NAME = 5 + + fun crystalSinging() = dbTable("tables.smithing_crystal_singing",serverOnly = true) { + column("output", COL_CRYSTAL_OUTPUT, VarType.OBJ) + column("xp", COL_CRYSTAL_XP, VarType.INT) + column("level", COL_CRYSTAL_LEVEL, VarType.INT) + column("materials", COL_CRYSTAL_MATERIALS, VarType.OBJ) + column("materialsCount", COL_CRYSTAL_MATERIALS_AMT, VarType.INT) + column("shortName", COL_CRYSTAL_MATERIALS_SHORT_NAME, VarType.STRING) + + row("dbrows.crystal_celestial_signet") { + columnRSCM(COL_CRYSTAL_OUTPUT, "items.celestial_signet") + column(COL_CRYSTAL_XP, 5000) + column(COL_CRYSTAL_LEVEL, 70) + columnRSCM(COL_CRYSTAL_MATERIALS, "items.prif_crystal_shard", "items.star_dust", "items.celestial_ring", "items.elven_signet") + column(COL_CRYSTAL_MATERIALS_AMT, 100, 1000, 1, 1) + column(COL_CRYSTAL_MATERIALS_SHORT_NAME, "ring") + } + + row("dbrows.crystal_helm") { + columnRSCM(COL_CRYSTAL_OUTPUT, "items.crystal_helmet") + column(COL_CRYSTAL_XP, 2500) + column(COL_CRYSTAL_LEVEL, 70) + columnRSCM(COL_CRYSTAL_MATERIALS, "items.prif_crystal_shard", "items.prif_armour_seed") + column(COL_CRYSTAL_MATERIALS_AMT, 50, 1) + column(COL_CRYSTAL_MATERIALS_SHORT_NAME, "helmet") + } + + row("dbrows.crystal_legs") { + columnRSCM(COL_CRYSTAL_OUTPUT, "items.crystal_platelegs") + column(COL_CRYSTAL_XP, 5000) + column(COL_CRYSTAL_LEVEL, 72) + columnRSCM(COL_CRYSTAL_MATERIALS, "items.prif_crystal_shard", "items.prif_armour_seed") + column(COL_CRYSTAL_MATERIALS_AMT, 100, 2) + column(COL_CRYSTAL_MATERIALS_SHORT_NAME, "platelegs") + } + + row("dbrows.crystal_body") { + columnRSCM(COL_CRYSTAL_OUTPUT, "items.crystal_chestplate") + column(COL_CRYSTAL_XP, 7500) + column(COL_CRYSTAL_LEVEL, 74) + columnRSCM(COL_CRYSTAL_MATERIALS, "items.prif_crystal_shard", "items.prif_armour_seed") + column(COL_CRYSTAL_MATERIALS_AMT, 150, 3) + column(COL_CRYSTAL_MATERIALS_SHORT_NAME, "platelegs") + } + + row("dbrows.crystal_axe") { + columnRSCM(COL_CRYSTAL_OUTPUT, "items.crystal_axe") + column(COL_CRYSTAL_XP, 6000) + column(COL_CRYSTAL_LEVEL, 76) + columnRSCM(COL_CRYSTAL_MATERIALS, "items.prif_crystal_shard", "items.prif_tool_seed", "items.dragon_axe") + column(COL_CRYSTAL_MATERIALS_AMT, 120, 1, 1) + column(COL_CRYSTAL_MATERIALS_SHORT_NAME, "axe") + } + + row("dbrows.crystal_felling_axe") { + columnRSCM(COL_CRYSTAL_OUTPUT, "items.crystal_axe_2h") + column(COL_CRYSTAL_XP, 6000) + column(COL_CRYSTAL_LEVEL, 76) + columnRSCM(COL_CRYSTAL_MATERIALS, "items.prif_crystal_shard", "items.prif_tool_seed", "items.dragon_axe_2h") + column(COL_CRYSTAL_MATERIALS_AMT, 120, 1, 1) + column(COL_CRYSTAL_MATERIALS_SHORT_NAME, "axe") + } + + row("dbrows.crystal_harpoon") { + columnRSCM(COL_CRYSTAL_OUTPUT, "items.crystal_harpoon") + column(COL_CRYSTAL_XP, 6000) + column(COL_CRYSTAL_LEVEL, 76) + columnRSCM(COL_CRYSTAL_MATERIALS, "items.prif_crystal_shard", "items.prif_tool_seed", "items.dragon_harpoon") + column(COL_CRYSTAL_MATERIALS_AMT, 120, 1, 1) + column(COL_CRYSTAL_MATERIALS_SHORT_NAME, "harpoon") + } + + row("dbrows.crystal_pickaxe") { + columnRSCM(COL_CRYSTAL_OUTPUT, "items.crystal_pickaxe") + column(COL_CRYSTAL_XP, 6000) + column(COL_CRYSTAL_LEVEL, 76) + columnRSCM(COL_CRYSTAL_MATERIALS, "items.prif_crystal_shard", "items.prif_tool_seed", "items.dragon_pickaxe") + column(COL_CRYSTAL_MATERIALS_AMT, 120, 1, 1) + column(COL_CRYSTAL_MATERIALS_SHORT_NAME, "pickaxe") + } + + row("dbrows.crystal_bow") { + columnRSCM(COL_CRYSTAL_OUTPUT, "items.crystal_bow") + column(COL_CRYSTAL_XP, 2000) + column(COL_CRYSTAL_LEVEL, 78) + columnRSCM(COL_CRYSTAL_MATERIALS, "items.prif_crystal_shard", "items.crystal_seed_old") + column(COL_CRYSTAL_MATERIALS_AMT, 40, 1) + column(COL_CRYSTAL_MATERIALS_SHORT_NAME, "bow") + } + + row("dbrows.crystal_halberd") { + columnRSCM(COL_CRYSTAL_OUTPUT, "items.crystal_halberd") + column(COL_CRYSTAL_XP, 2000) + column(COL_CRYSTAL_LEVEL, 78) + columnRSCM(COL_CRYSTAL_MATERIALS, "items.prif_crystal_shard", "items.crystal_seed_old") + column(COL_CRYSTAL_MATERIALS_AMT, 40, 1) + column(COL_CRYSTAL_MATERIALS_SHORT_NAME, "halberd") + } + + row("dbrows.crystal_shield") { + columnRSCM(COL_CRYSTAL_OUTPUT, "items.crystal_shield") + column(COL_CRYSTAL_XP, 2000) + column(COL_CRYSTAL_LEVEL, 78) + columnRSCM(COL_CRYSTAL_MATERIALS, "items.prif_crystal_shard", "items.crystal_seed_old") + column(COL_CRYSTAL_MATERIALS_AMT, 40, 1) + column(COL_CRYSTAL_MATERIALS_SHORT_NAME, "halberd") + } + + row("dbrows.enhanced_crystal_key") { + columnRSCM(COL_CRYSTAL_OUTPUT, "items.prif_crystal_key") + column(COL_CRYSTAL_XP, 500) + column(COL_CRYSTAL_LEVEL, 80) + columnRSCM(COL_CRYSTAL_MATERIALS, "items.prif_crystal_shard", "items.crystal_key") + column(COL_CRYSTAL_MATERIALS_AMT, 10, 1) + column(COL_CRYSTAL_MATERIALS_SHORT_NAME, "key") + } + + row("dbrows.eternal_teleport_crystal") { + columnRSCM(COL_CRYSTAL_OUTPUT, "items.prif_teleport_crystal") + column(COL_CRYSTAL_XP, 5000) + column(COL_CRYSTAL_LEVEL, 80) + columnRSCM(COL_CRYSTAL_MATERIALS, "items.prif_crystal_shard", "items.prif_teleport_seed") + column(COL_CRYSTAL_MATERIALS_AMT, 100, 1) + } + + row("dbrows.blade_of_saeldor") { + columnRSCM(COL_CRYSTAL_OUTPUT, "items.blade_of_saeldor") + column(COL_CRYSTAL_XP, 5000) + column(COL_CRYSTAL_LEVEL, 82) + columnRSCM(COL_CRYSTAL_MATERIALS, "items.prif_crystal_shard", "items.prif_weapon_seed_enhanced") + column(COL_CRYSTAL_MATERIALS_AMT, 100, 1) + column(COL_CRYSTAL_MATERIALS_SHORT_NAME, "saeldor") + } + + row("dbrows.bow_of_faerdhinen") { + columnRSCM(COL_CRYSTAL_OUTPUT, "items.bow_of_faerdhinen") + column(COL_CRYSTAL_XP, 5000) + column(COL_CRYSTAL_LEVEL, 82) + columnRSCM(COL_CRYSTAL_MATERIALS, "items.prif_crystal_shard", "items.prif_weapon_seed_enhanced") + column(COL_CRYSTAL_MATERIALS_AMT, 100, 1) + column(COL_CRYSTAL_MATERIALS_SHORT_NAME, "bow") + } + + row("dbrows.blade_of_saeldor_charged") { + columnRSCM(COL_CRYSTAL_OUTPUT, "items.blade_of_saeldor_infinite") + column(COL_CRYSTAL_XP, 0) + column(COL_CRYSTAL_LEVEL, 82) + columnRSCM(COL_CRYSTAL_MATERIALS, "items.prif_crystal_shard", "items.blade_of_saeldor_inactive") + column(COL_CRYSTAL_MATERIALS_AMT, 1000, 1) + column(COL_CRYSTAL_MATERIALS_SHORT_NAME, "blade") + } + + row("dbrows.bow_of_faerdhinen_charged") { + columnRSCM(COL_CRYSTAL_OUTPUT, "items.bow_of_faerdhinen_infinite") + column(COL_CRYSTAL_XP, 0) + column(COL_CRYSTAL_LEVEL, 82) + columnRSCM(COL_CRYSTAL_MATERIALS, "items.prif_crystal_shard", "items.bow_of_faerdhinen_inactive") + column(COL_CRYSTAL_MATERIALS_AMT, 2000, 1) + column(COL_CRYSTAL_MATERIALS_SHORT_NAME, "saeldor") + } + } + +} \ No newline at end of file diff --git a/cache/bin/main/org/alter/impl/skills/Woodcutting.kt b/cache/bin/main/org/alter/impl/skills/Woodcutting.kt new file mode 100644 index 00000000..492c2965 --- /dev/null +++ b/cache/bin/main/org/alter/impl/skills/Woodcutting.kt @@ -0,0 +1,307 @@ +package org.alter.impl.skills + +import dev.openrune.definition.dbtables.dbTable +import dev.openrune.definition.util.VarType + +object Woodcutting { + + const val COL_TREE_OBJECT = 0 + const val COL_LEVEL = 1 + const val COL_XP = 2 + const val COL_LOG_ITEM = 3 + const val COL_RESPAWN_CYCLES = 4 + const val COL_SUCCESS_RATE_LOW = 5 + const val COL_SUCCESS_RATE_HIGH = 6 + const val COL_DESPAWN_TICKS = 7 + const val COL_DEPLETE_MECHANIC = 8 + const val COL_STUMP = 9 + const val CLUE_BASE_CHANCE = 10 + const val TREE_TYPE = 11 + + val AXE_DATA = mapOf( + "items.bronze_axe" to Triple(1, 4, Pair("sequences.human_woodcutting_bronze_axe", "dbrows.woodcutting_bronze_axe")), + "items.iron_axe" to Triple(1, 3, Pair("sequences.human_woodcutting_iron_axe", "dbrows.woodcutting_iron_axe")), + "items.steel_axe" to Triple(6, 3, Pair("sequences.human_woodcutting_steel_axe", "dbrows.woodcutting_steel_axe")), + "items.mithril_axe" to Triple(21, 2, Pair("sequences.human_woodcutting_mithril_axe", "dbrows.woodcutting_mithril_axe")), + "items.adamant_axe" to Triple(31, 2, Pair("sequences.human_woodcutting_adamant_axe", "dbrows.woodcutting_adamant_axe")), + "items.rune_axe" to Triple(41, 2, Pair("sequences.human_woodcutting_rune_axe", "dbrows.woodcutting_rune_axe")), + "items.dragon_axe" to Triple(61, 2, Pair("sequences.human_woodcutting_dragon_axe", "dbrows.woodcutting_dragon_axe")), + "items.3a_axe" to Triple(61, 2, Pair("sequences.human_woodcutting_3a_axe", "dbrows.woodcutting_3a_axe")), + "items.infernal_axe" to Triple(61, 2, Pair("sequences.human_woodcutting_infernal_axe", "dbrows.woodcutting_infernal_axe")), + "items.crystal_axe" to Triple(71, 2, Pair("sequences.human_woodcutting_crystal_axe", "dbrows.woodcutting_crystal_axe")), + "items.bronze_axe_2h" to Triple(1, 4, Pair("sequences.human_woodcutting_bronze_axe", "dbrows.woodcutting_bronze_axe_2h")), + "items.iron_axe_2h" to Triple(1, 3, Pair("sequences.human_woodcutting_iron_axe", "dbrows.woodcutting_iron_axe_2h")), + "items.steel_axe_2h" to Triple(6, 3, Pair("sequences.human_woodcutting_steel_axe", "dbrows.woodcutting_steel_axe_2h")), + "items.mithril_axe_2h" to Triple(21, 2, Pair("sequences.human_woodcutting_mithril_axe", "dbrows.woodcutting_mithril_axe_2h")), + "items.adamant_axe_2h" to Triple(31, 2, Pair("sequences.human_woodcutting_adamant_axe", "dbrows.woodcutting_adamant_axe_2h")), + "items.rune_axe_2h" to Triple(41, 2, Pair("sequences.human_woodcutting_rune_axe", "dbrows.woodcutting_rune_axe_2h")), + "items.dragon_axe_2h" to Triple(61, 2, Pair("sequences.human_woodcutting_dragon_axe", "dbrows.woodcutting_dragon_axe_2h")), + "items.3a_axe_2h" to Triple(61, 2, Pair("sequences.human_woodcutting_3a_axe", "dbrows.woodcutting_3a_axe_2h")) + ) + + const val ITEM = 0 + const val LEVEL = 1 + const val DELAY = 2 + const val ANIMATION = 3 + + + fun axes() = dbTable("tables.woodcutting_axes", serverOnly = true) { + column("item", ITEM, VarType.OBJ) + column("level", LEVEL, VarType.INT) + column("delay", DELAY, VarType.INT) + column("animation", ANIMATION, VarType.SEQ) + + AXE_DATA.forEach { + row(it.value.third.second) { + columnRSCM(ITEM,it.key) + column(LEVEL,it.value.first) + column(DELAY,it.value.second) + columnRSCM(ANIMATION,it.value.third.first) + } + } + + } + + fun trees() = dbTable("tables.woodcutting_trees", serverOnly = true) { + + column("tree_object", COL_TREE_OBJECT, VarType.LOC) + column("level", COL_LEVEL, VarType.INT) + column("xp", COL_XP, VarType.INT) + column("log_item", COL_LOG_ITEM, VarType.OBJ) + column("respawn_cycles", COL_RESPAWN_CYCLES, VarType.INT) + column("success_rate_low", COL_SUCCESS_RATE_LOW, VarType.INT) + column("success_rate_high", COL_SUCCESS_RATE_HIGH, VarType.INT) + column("despawn_ticks", COL_DESPAWN_TICKS, VarType.INT) + column("deplete_mechanic", COL_DEPLETE_MECHANIC, VarType.INT) + column("stump_object", COL_STUMP, VarType.LOC) + column("clue_base_chance", CLUE_BASE_CHANCE, VarType.INT) + column("tree_type", TREE_TYPE, VarType.STRING) + + // Regular trees (level 1) + row("dbrows.woodcutting_regular_tree") { + columnRSCM(COL_TREE_OBJECT, + "objects.tree", "objects.lighttree", + "objects.tree2", "objects.tree3", + "objects.tree4", "objects.tree5", + "objects.lighttree2", "objects.evergreen", + "objects.evergreen_large", "objects.jungletree1", + "objects.jungletree2", "objects.jungletree1_karamja", + "objects.jungletree2_karamja", "objects.achey_tree", + "objects.hollowtree", "objects.hollow_tree", + "objects.hollow_tree_big", "objects.arctic_pine", + "objects.arctic_pine_snowy", "objects.deadtree1", + "objects.deadtree1_large", "objects.lightdeadtree1", + "objects.deadtree2", "objects.deadtree2_web_r", + "objects.deadtree2_web_l", "objects.deadtree2_dark", + "objects.deadtree3", "objects.deadtree2_snowy", + "objects.deadtree_with_vine", "objects.deadtree2_swamp", + "objects.deadtree4", "objects.deadtree6", + "objects.deadtree_burnt", "objects.deadtree4swamp", + "objects.deadtree3_snowy" + ) + column(COL_LEVEL, 1) + column(COL_XP, 25) + columnRSCM(COL_LOG_ITEM, "items.logs") + column(COL_RESPAWN_CYCLES, 60) + column(COL_SUCCESS_RATE_LOW, 64) + column(COL_SUCCESS_RATE_HIGH, 256) + column(COL_DESPAWN_TICKS, 0) + column(COL_DEPLETE_MECHANIC, 0) // Always + columnRSCM(COL_STUMP, "objects.treestump") + column(CLUE_BASE_CHANCE, 317647) + column(TREE_TYPE, "normal_tree") + } + + // Oak trees + row("dbrows.woodcutting_oak_tree") { + columnRSCM(COL_TREE_OBJECT, + "objects.oaktree", + "objects.oaktree", "objects.oak_tree_1", + "objects.oak_tree_2", "objects.oak_tree_3", + "objects.oak_tree_3_top", "objects.oak_tree_fullygrown_1", + "objects.oak_tree_fullygrown_2" + ) + column(COL_LEVEL, 15) + column(COL_XP, 37) + columnRSCM(COL_LOG_ITEM, "items.oak_logs") + column(COL_RESPAWN_CYCLES, 60) + column(COL_SUCCESS_RATE_LOW, 64) + column(COL_SUCCESS_RATE_HIGH, 256) + column(COL_DESPAWN_TICKS, 45) + column(COL_DEPLETE_MECHANIC, 1) // Countdown + columnRSCM(COL_STUMP, "objects.oaktree_stump") + column(CLUE_BASE_CHANCE, 361146) + column(TREE_TYPE, "oak_tree") + } + + // Willow trees + row("dbrows.woodcutting_willow_tree") { + columnRSCM(COL_TREE_OBJECT, + "objects.willowtree", "objects.willow_tree_1", + "objects.willow_tree_2", "objects.willow_tree_3", + "objects.willow_tree_4", "objects.willow_tree_5", + "objects.willow_tree_fullygrown_1", "objects.willow_tree_fullygrown_2", + "objects.willow_tree2", "objects.willow_tree3", + "objects.willow_tree4" + ) + column(COL_LEVEL, 30) + column(COL_XP, 67) + columnRSCM(COL_LOG_ITEM, "items.willow_logs") + column(COL_RESPAWN_CYCLES, 100) + column(COL_SUCCESS_RATE_LOW, 32) + column(COL_SUCCESS_RATE_HIGH, 256) + column(COL_DESPAWN_TICKS, 50) + column(COL_DEPLETE_MECHANIC, 1) // Countdown + columnRSCM(COL_STUMP, "objects.willow_tree_stump_new") + column(CLUE_BASE_CHANCE, 289286) + column(TREE_TYPE, "willow_tree") + } + + // Teak trees + row("dbrows.woodcutting_teak_tree") { + columnRSCM(COL_TREE_OBJECT, + "objects.teaktree", "objects.teak_tree_1", + "objects.teak_tree_2", "objects.teak_tree_3", + "objects.teak_tree_4", "objects.teak_tree_5", + "objects.teak_tree_6", "objects.teak_tree_5_top", + "objects.teak_tree_6_top", "objects.teak_tree_fullygrown", + "objects.teak_tree_fullygrown_top" + ) + column(COL_LEVEL, 35) + column(COL_XP, 85) + columnRSCM(COL_LOG_ITEM, "items.teak_logs") + column(COL_RESPAWN_CYCLES, 100) + column(COL_SUCCESS_RATE_LOW, 20) + column(COL_SUCCESS_RATE_HIGH, 256) + column(COL_DESPAWN_TICKS, 50) + column(COL_DEPLETE_MECHANIC, 1) // Countdown + columnRSCM(COL_STUMP, "objects.teak_tree_stump") + column(CLUE_BASE_CHANCE, 264336) + column(TREE_TYPE, "teak_tree") + } + + // Juniper trees + row("dbrows.woodcutting_juniper_tree") { + columnRSCM(COL_TREE_OBJECT, "objects.mature_juniper_tree") + column(COL_LEVEL, 42) + column(COL_XP, 35) + columnRSCM(COL_LOG_ITEM, "items.juniper_logs") + column(COL_RESPAWN_CYCLES, 100) + column(COL_SUCCESS_RATE_LOW, 18) + column(COL_SUCCESS_RATE_HIGH, 256) + column(COL_DESPAWN_TICKS, 50) + column(COL_DEPLETE_MECHANIC, 1) // Countdown + columnRSCM(COL_STUMP, "objects.mature_juniper_tree_stump") + column(CLUE_BASE_CHANCE, 360000) + column(TREE_TYPE, "juniper_tree") + } + + // Maple trees + row("dbrows.woodcutting_maple_tree") { + columnRSCM(COL_TREE_OBJECT, + "objects.mapletree", "objects.maple_tree_1", + "objects.maple_tree_2", "objects.maple_tree_3", + "objects.maple_tree_4", "objects.maple_tree_5", + "objects.maple_tree_6", "objects.maple_tree_7", + "objects.maple_tree_fullygrown_1", "objects.maple_tree_fullygrown_2" + ) + column(COL_LEVEL, 45) + column(COL_XP, 100) + columnRSCM(COL_LOG_ITEM, "items.maple_logs") + column(COL_RESPAWN_CYCLES, 100) + column(COL_SUCCESS_RATE_LOW, 16) + column(COL_SUCCESS_RATE_HIGH, 256) + column(COL_DESPAWN_TICKS, 100) + column(COL_DEPLETE_MECHANIC, 1) // Countdown + columnRSCM(COL_STUMP, "objects.maple_tree_stump_new") + column(CLUE_BASE_CHANCE, 221918) + column(TREE_TYPE, "maple_tree") + } + + // Mahogany trees + row("dbrows.woodcutting_mahogany_tree") { + columnRSCM(COL_TREE_OBJECT, + "objects.mahoganytree", "objects.mahogany_tree_1", + "objects.mahogany_tree_2", "objects.mahogany_tree_3", + "objects.mahogany_tree_4", "objects.mahogany_tree_5", + "objects.mahogany_tree_6", "objects.mahogany_tree_7", + "objects.mahogany_tree_8", "objects.mahogany_tree_9", + "objects.mahogany_tree_fullygrown" + ) + column(COL_LEVEL, 50) + column(COL_XP, 125) + columnRSCM(COL_LOG_ITEM, "items.mahogany_logs") + column(COL_RESPAWN_CYCLES, 120) + column(COL_SUCCESS_RATE_LOW, 12) + column(COL_SUCCESS_RATE_HIGH, 256) + column(COL_DESPAWN_TICKS, 100) + column(COL_DEPLETE_MECHANIC, 1) // Countdown + columnRSCM(COL_STUMP, "objects.mahogany_tree_stump") + column(CLUE_BASE_CHANCE, 220623) + column(TREE_TYPE, "mahogany_tree") + } + + // Yew trees + row("dbrows.woodcutting_yew_tree") { + columnRSCM(COL_TREE_OBJECT, + "objects.yewtree", "objects.yew_tree_1", + "objects.yew_tree_2", "objects.yew_tree_3", + "objects.yew_tree_4", "objects.yew_tree_5", + "objects.yew_tree_6", "objects.yew_tree_7", + "objects.yew_tree_8", "objects.yew_tree_9", + "objects.yew_tree_fullygrown_1", "objects.yew_tree_fullygrown_2" + ) + column(COL_LEVEL, 60) + column(COL_XP, 175) + columnRSCM(COL_LOG_ITEM, "items.yew_logs") + column(COL_RESPAWN_CYCLES, 120) + column(COL_SUCCESS_RATE_LOW, 8) + column(COL_SUCCESS_RATE_HIGH, 256) + column(COL_DESPAWN_TICKS, 190) + column(COL_DEPLETE_MECHANIC, 1) // Countdown + columnRSCM(COL_STUMP, "objects.yew_tree_stump_new") + column(CLUE_BASE_CHANCE, 145013) + column(TREE_TYPE, "yew_tree") + } + + // Magic trees + row("dbrows.woodcutting_magic_tree") { + columnRSCM(COL_TREE_OBJECT, + "objects.magictree", "objects.magic_tree_1", + "objects.magic_tree_2", "objects.magic_tree_3", + "objects.magic_tree_4", "objects.magic_tree_5", + "objects.magic_tree_6", "objects.magic_tree_7", + "objects.magic_tree_8", "objects.magic_tree_9", + "objects.magic_tree_10", "objects.magic_tree_11", + "objects.magic_tree_fullygrown_1", "objects.magic_tree_fullygrown_2" + ) + column(COL_LEVEL, 75) + column(COL_XP, 250) + columnRSCM(COL_LOG_ITEM, "items.magic_logs") + column(COL_RESPAWN_CYCLES, 120) + column(COL_SUCCESS_RATE_LOW, 4) + column(COL_SUCCESS_RATE_HIGH, 256) + column(COL_DESPAWN_TICKS, 390) + column(COL_DEPLETE_MECHANIC, 1) // Countdown + columnRSCM(COL_STUMP, "objects.magic_tree_stump_new") + column(CLUE_BASE_CHANCE, 72321) + column(TREE_TYPE, "magic_tree") + } + + // Blisterwood trees + row("dbrows.woodcutting_blisterwood_tree") { + columnRSCM(COL_TREE_OBJECT, "objects.blisterwood_tree") + column(COL_LEVEL, 62) + column(COL_XP, 76) + columnRSCM(COL_LOG_ITEM, "items.blisterwood_logs") + column(COL_RESPAWN_CYCLES, 0) + column(COL_SUCCESS_RATE_LOW, 10) + column(COL_SUCCESS_RATE_HIGH, 256) + column(COL_DESPAWN_TICKS, 50) + column(COL_DEPLETE_MECHANIC, 1) // Countdown + column(CLUE_BASE_CHANCE, 0) + column(TREE_TYPE, "blisterwood_tree") + } + } +} + diff --git a/cache/bin/main/org/alter/impl/skills/cooking/CookingConstants.kt b/cache/bin/main/org/alter/impl/skills/cooking/CookingConstants.kt new file mode 100644 index 00000000..ce34972d --- /dev/null +++ b/cache/bin/main/org/alter/impl/skills/cooking/CookingConstants.kt @@ -0,0 +1,41 @@ +package org.alter.impl.skills.cooking + +/** + * Cooking skill constants used across recipe definitions and table builders. + */ +object CookingConstants { + + /** + * Trigger types determine how a cooking action is initiated. + */ + object Trigger { + /** Action triggered by using item on a heat source (fire/range). */ + const val HEAT_SOURCE = 0 + /** Action triggered by using one item on another in inventory. */ + const val ITEM_ON_ITEM = 1 + } + + /** + * Outcome kinds determine what type of result a cooking action produces. + */ + object OutcomeKind { + /** Successful cooking result. */ + const val SUCCESS = 0 + /** Failed cooking result (burnt). */ + const val FAIL = 1 + /** Always produced regardless of success/failure (e.g., return containers). */ + const val ALWAYS = 2 + } + + /** Default variant for single-step actions. */ + const val DEFAULT_VARIANT = 0 + + /** Station mask for fire-only cooking. */ + const val STATION_FIRE = 1 + + /** Station mask for range-only cooking. */ + const val STATION_RANGE = 2 + + /** Station mask for cooking on both fire and range. */ + const val STATION_ANY = STATION_FIRE or STATION_RANGE +} diff --git a/cache/bin/main/org/alter/impl/skills/cooking/CookingHelpers.kt b/cache/bin/main/org/alter/impl/skills/cooking/CookingHelpers.kt new file mode 100644 index 00000000..309c37f7 --- /dev/null +++ b/cache/bin/main/org/alter/impl/skills/cooking/CookingHelpers.kt @@ -0,0 +1,216 @@ +package org.alter.impl.skills.cooking + +import org.alter.impl.skills.cooking.CookingConstants.DEFAULT_VARIANT +import org.alter.impl.skills.cooking.CookingConstants.OutcomeKind +import org.alter.impl.skills.cooking.CookingConstants.STATION_ANY +import org.alter.impl.skills.cooking.CookingConstants.STATION_FIRE +import org.alter.impl.skills.cooking.CookingConstants.Trigger + +/** + * Helper functions for building cooking recipe definitions. + */ +object CookingHelpers { + + /** + * Creates a simple heat-cooking action (raw -> cooked/burnt). + * + * @param rowKey DB row key suffix (e.g., "cooking_shrimps"). + * @param raw RSCM key for the raw item. + * @param cooked RSCM key for the cooked item. + * @param burnt RSCM key for the burnt item. + * @param level Required Cooking level. + * @param xp Experience awarded on success. + * @param stopBurnFire Level at which burning stops on fires. + * @param stopBurnRange Level at which burning stops on ranges. + * @param stationMask Bitmask for allowed cooking stations. + */ + fun heatCook( + rowKey: String, + raw: String, + cooked: String, + burnt: String, + level: Int, + xp: Int, + stopBurnFire: Int, + stopBurnRange: Int, + stationMask: Int = STATION_ANY + ): ActionDef = ActionDef( + rowId = "dbrows.$rowKey", + key = raw, + level = level, + stopBurnFire = stopBurnFire, + stopBurnRange = stopBurnRange, + stationMask = stationMask, + trigger = Trigger.HEAT_SOURCE, + inputs = listOf(InputDef(raw, 1)), + outcomes = listOf( + OutcomeDef(rowSuffix = "success", kind = OutcomeKind.SUCCESS, item = cooked, xp = xp, weight = 1), + OutcomeDef(rowSuffix = "fail", kind = OutcomeKind.FAIL, item = burnt, xp = 0, weight = 1) + ) + ) + + /** + * Creates a spit-roasting recipe (2 actions: skewer + roast). + * + * @param skewerRowKey DB row key for the skewering step. + * @param roastRowKey DB row key for the roasting step. + * @param rawMeat RSCM key for the raw meat. + * @param skewered RSCM key for the skewered meat. + * @param cooked RSCM key for the roasted meat. + * @param burnt RSCM key for the burnt meat. + * @param cookingLevel Required Cooking level for roasting. + * @param xp Experience awarded on successful roast. + * @param stopBurnFire Level at which burning stops on fires. + * @param stopBurnRange Level at which burning stops on ranges. + * @param spitItem RSCM key for the spit item (default: iron spit). + */ + fun spitRoast( + skewerRowKey: String, + roastRowKey: String, + rawMeat: String, + skewered: String, + cooked: String, + burnt: String, + cookingLevel: Int, + xp: Int, + stopBurnFire: Int, + stopBurnRange: Int, + spitItem: String = "items.spit_iron" + ): List = listOf( + // Raw meat + iron spit -> skewered meat (inventory prep step) + ActionDef( + rowId = "dbrows.$skewerRowKey", + key = skewered, + variant = 1, + level = 1, + stopBurnFire = 1, + stopBurnRange = 1, + stationMask = STATION_ANY, + trigger = Trigger.ITEM_ON_ITEM, + inputs = listOf( + InputDef(rawMeat, 1), + InputDef(spitItem, 1) + ), + outcomes = listOf( + OutcomeDef(rowSuffix = "success", kind = OutcomeKind.SUCCESS, item = skewered, xp = 0, weight = 1) + ) + ), + + // Skewered meat -> roasted/burnt (fire only) + ActionDef( + rowId = "dbrows.$roastRowKey", + key = skewered, + variant = DEFAULT_VARIANT, + level = cookingLevel, + stopBurnFire = stopBurnFire, + stopBurnRange = stopBurnRange, + stationMask = STATION_FIRE, + trigger = Trigger.HEAT_SOURCE, + inputs = listOf(InputDef(skewered, 1)), + outcomes = listOf( + OutcomeDef(rowSuffix = "success", kind = OutcomeKind.SUCCESS, item = cooked, xp = xp, weight = 1), + OutcomeDef(rowSuffix = "fail", kind = OutcomeKind.FAIL, item = burnt, xp = 0, weight = 1) + ) + ) + ) + + /** + * Creates a multi-step cooking recipe with preparation and optional baking. + * + * @param key RSCM key identifying this recipe group. + * @param level Required Cooking level. + * @param prepSteps List of inventory preparation steps. + * @param heatStep Optional final heat-source cooking step. + * @param prepVariantStart Starting variant number for prep steps. + * @param heatVariant Variant number for the heat step. + */ + fun multiStepCook( + key: String, + level: Int, + prepSteps: List, + heatStep: HeatStepDef? = null, + prepVariantStart: Int = 1, + heatVariant: Int = DEFAULT_VARIANT + ): List = buildList { + prepSteps.forEachIndexed { index, step -> + val alwaysOutcomes = step.always.mapIndexed { alwaysIndex, (item, count) -> + OutcomeDef( + rowSuffix = "always_$alwaysIndex", + kind = OutcomeKind.ALWAYS, + item = item, + countMin = count, + countMax = count, + xp = 0, + weight = 1 + ) + } + + add( + ActionDef( + rowId = "dbrows.${step.rowKey}", + key = key, + variant = prepVariantStart + index, + level = level, + stopBurnFire = level, + stopBurnRange = level, + stationMask = STATION_ANY, + trigger = Trigger.ITEM_ON_ITEM, + inputs = step.inputs.map { (item, count) -> InputDef(item, count) }, + outcomes = listOf( + OutcomeDef( + rowSuffix = "success", + kind = OutcomeKind.SUCCESS, + item = step.output, + xp = step.xp, + weight = 1 + ) + ) + alwaysOutcomes + ) + ) + } + + heatStep?.let { step -> + val alwaysOutcomes = step.always.mapIndexed { alwaysIndex, (item, count) -> + OutcomeDef( + rowSuffix = "always_$alwaysIndex", + kind = OutcomeKind.ALWAYS, + item = item, + countMin = count, + countMax = count, + xp = 0, + weight = 1 + ) + } + + add( + ActionDef( + rowId = "dbrows.${step.rowKey}", + key = key, + variant = heatVariant, + level = level, + stopBurnFire = step.stopBurnFire, + stopBurnRange = step.stopBurnRange, + stationMask = step.stationMask, + trigger = Trigger.HEAT_SOURCE, + inputs = listOf(InputDef(step.raw, 1)), + outcomes = listOf( + OutcomeDef( + rowSuffix = "success", + kind = OutcomeKind.SUCCESS, + item = step.cooked, + xp = step.xp, + weight = 1 + ), + OutcomeDef( + rowSuffix = "fail", + kind = OutcomeKind.FAIL, + item = step.burnt, + xp = 0, + weight = 1 + ) + ) + alwaysOutcomes + ) + ) + } + } +} diff --git a/cache/bin/main/org/alter/impl/skills/cooking/CookingModels.kt b/cache/bin/main/org/alter/impl/skills/cooking/CookingModels.kt new file mode 100644 index 00000000..19d8e7c4 --- /dev/null +++ b/cache/bin/main/org/alter/impl/skills/cooking/CookingModels.kt @@ -0,0 +1,106 @@ +package org.alter.impl.skills.cooking + +/** + * Data models for cooking recipe definitions. + */ + +/** + * Defines an input ingredient for a cooking action. + * + * @property item RSCM key for the item (e.g., "items.raw_shrimp"). + * @property count Number of this item consumed per action. + */ +data class InputDef( + val item: String, + val count: Int = 1 +) + +/** + * Defines a possible outcome of a cooking action. + * + * @property rowSuffix Unique suffix for the DB row (e.g., "success", "fail"). + * @property kind The outcome type (SUCCESS, FAIL, or ALWAYS). + * @property item RSCM key for the produced item. + * @property countMin Minimum quantity produced. + * @property countMax Maximum quantity produced. + * @property xp Experience awarded for this outcome. + * @property weight Weighted chance for this outcome when multiple exist. + */ +data class OutcomeDef( + val rowSuffix: String, + val kind: Int, + val item: String, + val countMin: Int = 1, + val countMax: Int = 1, + val xp: Int = 0, + val weight: Int = 1 +) + +/** + * Defines a complete cooking action with inputs, outcomes, and requirements. + * + * @property rowId DB row identifier (e.g., "dbrows.cooking_shrimps"). + * @property key RSCM key used to identify this action group. + * @property variant Variant number for multi-step recipes. + * @property level Required Cooking level. + * @property stopBurnFire Level at which burning stops on fires. + * @property stopBurnRange Level at which burning stops on ranges. + * @property stationMask Bitmask for allowed cooking stations. + * @property trigger How the action is initiated (HEAT_SOURCE or ITEM_ON_ITEM). + * @property inputs List of required input items. + * @property outcomes List of possible outcomes. + */ +data class ActionDef( + val rowId: String, + val key: String, + val variant: Int = CookingConstants.DEFAULT_VARIANT, + val level: Int, + val stopBurnFire: Int, + val stopBurnRange: Int, + val stationMask: Int = CookingConstants.STATION_ANY, + val trigger: Int = CookingConstants.Trigger.HEAT_SOURCE, + val inputs: List, + val outcomes: List +) + +/** + * Defines a preparation step for multi-step cooking (inventory item-on-item). + * + * @property rowKey DB row key suffix. + * @property inputs List of (item RSCM key, count) pairs consumed. + * @property output RSCM key for the produced item. + * @property xp Experience awarded. + * @property always Items always returned (e.g., empty containers). + */ +data class PrepStepDef( + val rowKey: String, + val inputs: List>, + val output: String, + val xp: Int = 0, + val always: List> = emptyList() +) + +/** + * Defines the final heat-source step for multi-step cooking. + * + * @property rowKey DB row key suffix. + * @property raw RSCM key for the uncooked item. + * @property cooked RSCM key for the successfully cooked item. + * @property burnt RSCM key for the burnt item. + * @property xp Experience awarded on success. + * @property stopBurnFire Level at which burning stops on fires. + * @property stopBurnRange Level at which burning stops on ranges. + * @property stationMask Bitmask for allowed cooking stations. + * @property always Items always returned (e.g., cake tin). + */ +data class HeatStepDef( + val rowKey: String, + val raw: String, + val cooked: String, + val burnt: String, + val xp: Int, + val stopBurnFire: Int, + val stopBurnRange: Int, + val stationMask: Int = CookingConstants.STATION_ANY, + val always: List> = emptyList() +) diff --git a/cache/bin/main/org/alter/impl/skills/cooking/CookingRecipeRegistry.kt b/cache/bin/main/org/alter/impl/skills/cooking/CookingRecipeRegistry.kt new file mode 100644 index 00000000..646630e6 --- /dev/null +++ b/cache/bin/main/org/alter/impl/skills/cooking/CookingRecipeRegistry.kt @@ -0,0 +1,36 @@ +package org.alter.impl.skills.cooking + +import org.alter.impl.skills.cooking.recipes.BakedGoodsRecipes +import org.alter.impl.skills.cooking.recipes.BreadRecipes +import org.alter.impl.skills.cooking.recipes.FishRecipes +import org.alter.impl.skills.cooking.recipes.MeatRecipes +import org.alter.impl.skills.cooking.recipes.MiscFoodRecipes +import org.alter.impl.skills.cooking.recipes.PieRecipes +import org.alter.impl.skills.cooking.recipes.PizzaRecipes +import org.alter.impl.skills.cooking.recipes.PotatoRecipes +import org.alter.impl.skills.cooking.recipes.StewRecipes +import org.alter.impl.skills.cooking.recipes.WineRecipes + +/** + * Central registry of all cooking recipes. + * + * Add new recipe categories here as they are implemented. + */ +object CookingRecipeRegistry { + + /** + * All cooking action definitions from all recipe categories. + */ + val allRecipes: List by lazy { + FishRecipes.recipes + + MeatRecipes.recipes + + BakedGoodsRecipes.recipes + + BreadRecipes.recipes + + PieRecipes.recipes + + PizzaRecipes.recipes + + StewRecipes.recipes + + PotatoRecipes.recipes + + MiscFoodRecipes.recipes + + WineRecipes.recipes + } +} diff --git a/cache/bin/main/org/alter/impl/skills/cooking/CookingTables.kt b/cache/bin/main/org/alter/impl/skills/cooking/CookingTables.kt new file mode 100644 index 00000000..71a3caaa --- /dev/null +++ b/cache/bin/main/org/alter/impl/skills/cooking/CookingTables.kt @@ -0,0 +1,110 @@ +package org.alter.impl.skills.cooking + +import dev.openrune.definition.dbtables.dbTable +import dev.openrune.definition.util.VarType + +/** + * DB table builders for cooking skill data. + * + * These functions generate the cache tables used by the game client and server + * to look up cooking recipes, inputs, and outcomes. + */ +object CookingTables { + + private const val ACTION_KEY = 0 + private const val ACTION_VARIANT = 1 + private const val ACTION_LEVEL = 2 + private const val ACTION_STOP_BURN_FIRE = 3 + private const val ACTION_STOP_BURN_RANGE = 4 + private const val ACTION_STATION_MASK = 5 + private const val ACTION_TRIGGER = 6 + + /** + * Builds the cooking_actions DB table containing action metadata. + */ + fun actions() = dbTable("tables.cooking_actions") { + column("key", ACTION_KEY, VarType.OBJ) + column("variant", ACTION_VARIANT, VarType.INT) + column("level", ACTION_LEVEL, VarType.INT) + column("stop_burn_fire", ACTION_STOP_BURN_FIRE, VarType.INT) + column("stop_burn_range", ACTION_STOP_BURN_RANGE, VarType.INT) + column("station_mask", ACTION_STATION_MASK, VarType.INT) + column("trigger", ACTION_TRIGGER, VarType.INT) + + CookingRecipeRegistry.allRecipes.forEach { action -> + row(action.rowId) { + columnRSCM(ACTION_KEY, action.key) + column(ACTION_VARIANT, action.variant) + column(ACTION_LEVEL, action.level) + column(ACTION_STOP_BURN_FIRE, action.stopBurnFire) + column(ACTION_STOP_BURN_RANGE, action.stopBurnRange) + column(ACTION_STATION_MASK, action.stationMask) + column(ACTION_TRIGGER, action.trigger) + } + } + } + + private const val INPUT_KEY = 0 + private const val INPUT_VARIANT = 1 + private const val INPUT_ITEM = 2 + private const val INPUT_COUNT = 3 + + /** + * Builds the cooking_action_inputs DB table containing input requirements. + */ + fun actionInputs() = dbTable("tables.cooking_action_inputs") { + column("key", INPUT_KEY, VarType.OBJ) + column("variant", INPUT_VARIANT, VarType.INT) + column("item", INPUT_ITEM, VarType.OBJ) + column("count", INPUT_COUNT, VarType.INT) + + CookingRecipeRegistry.allRecipes.forEach { action -> + action.inputs.forEachIndexed { index, input -> + row("${action.rowId}_input_$index") { + columnRSCM(INPUT_KEY, action.key) + column(INPUT_VARIANT, action.variant) + columnRSCM(INPUT_ITEM, input.item) + column(INPUT_COUNT, input.count) + } + } + } + } + + private const val OUTCOME_KEY = 0 + private const val OUTCOME_VARIANT = 1 + private const val OUTCOME_KIND = 2 + private const val OUTCOME_ITEM = 3 + private const val OUTCOME_COUNT_MIN = 4 + private const val OUTCOME_COUNT_MAX = 5 + private const val OUTCOME_XP = 6 + private const val OUTCOME_WEIGHT = 7 + + /** + * Builds the cooking_action_outcomes DB table containing possible results. + */ + fun actionOutcomes() = dbTable("tables.cooking_action_outcomes") { + column("key", OUTCOME_KEY, VarType.OBJ) + column("variant", OUTCOME_VARIANT, VarType.INT) + column("kind", OUTCOME_KIND, VarType.INT) + column("item", OUTCOME_ITEM, VarType.OBJ) + column("count_min", OUTCOME_COUNT_MIN, VarType.INT) + column("count_max", OUTCOME_COUNT_MAX, VarType.INT) + column("xp", OUTCOME_XP, VarType.INT) + column("weight", OUTCOME_WEIGHT, VarType.INT) + + CookingRecipeRegistry.allRecipes.forEach { action -> + action.outcomes.forEach { outcome -> + row("${action.rowId}_outcome_${outcome.rowSuffix}") { + columnRSCM(OUTCOME_KEY, action.key) + column(OUTCOME_VARIANT, action.variant) + column(OUTCOME_KIND, outcome.kind) + columnRSCM(OUTCOME_ITEM, outcome.item) + column(OUTCOME_COUNT_MIN, outcome.countMin) + column(OUTCOME_COUNT_MAX, outcome.countMax) + column(OUTCOME_XP, outcome.xp) + column(OUTCOME_WEIGHT, outcome.weight) + } + } + } + } +} diff --git a/cache/bin/main/org/alter/impl/skills/cooking/recipes/BakedGoodsRecipes.kt b/cache/bin/main/org/alter/impl/skills/cooking/recipes/BakedGoodsRecipes.kt new file mode 100644 index 00000000..e25ce387 --- /dev/null +++ b/cache/bin/main/org/alter/impl/skills/cooking/recipes/BakedGoodsRecipes.kt @@ -0,0 +1,93 @@ +package org.alter.impl.skills.cooking.recipes + +import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE +import org.alter.impl.skills.cooking.CookingHelpers.multiStepCook +import org.alter.impl.skills.cooking.HeatStepDef +import org.alter.impl.skills.cooking.PrepStepDef + +/** + * Baked goods recipes - pies, cakes, and other range-baked items. + */ +object BakedGoodsRecipes { + + /** Pie recipes (multi-step prep + range bake). */ + val pieRecipes: List = multiStepCook( + key = "items.uncooked_garden_pie", + level = 34, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_garden_pie_add_tomato", + inputs = listOf( + "items.pie_shell" to 1, + "items.tomato" to 1 + ), + output = "items.unfinished_garden_pie_1" + ), + PrepStepDef( + rowKey = "cooking_garden_pie_add_onion", + inputs = listOf( + "items.unfinished_garden_pie_1" to 1, + "items.onion" to 1 + ), + output = "items.unfinished_garden_pie_2" + ), + PrepStepDef( + rowKey = "cooking_garden_pie_add_cabbage", + inputs = listOf( + "items.unfinished_garden_pie_2" to 1, + "items.cabbage" to 1 + ), + output = "items.uncooked_garden_pie" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_garden_pie_bake", + raw = "items.uncooked_garden_pie", + cooked = "items.garden_pie", + burnt = "items.burnt_pie", + xp = 138, + stopBurnFire = 68, + stopBurnRange = 64, + stationMask = STATION_RANGE + ) + ) + + /** Cake recipes (multi-step prep + range bake). */ + val cakeRecipes: List = multiStepCook( + key = "items.uncooked_cake", + level = 40, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_cake_mix", + inputs = listOf( + "items.cake_tin" to 1, + "items.egg" to 1, + "items.bucket_milk" to 1, + "items.pot_flour" to 1 + ), + output = "items.uncooked_cake", + always = listOf( + "items.bucket_empty" to 1, + "items.pot_empty" to 1 + ) + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_cake_bake", + raw = "items.uncooked_cake", + cooked = "items.cake", + burnt = "items.burnt_cake", + xp = 180, + stopBurnFire = 74, + stopBurnRange = 70, + stationMask = STATION_RANGE, + always = listOf( + "items.cake_tin" to 1 + ) + ) + ) + + /** All baked goods recipes combined. */ + val recipes: List = pieRecipes + cakeRecipes +} diff --git a/cache/bin/main/org/alter/impl/skills/cooking/recipes/BreadRecipes.kt b/cache/bin/main/org/alter/impl/skills/cooking/recipes/BreadRecipes.kt new file mode 100644 index 00000000..9b75e9b7 --- /dev/null +++ b/cache/bin/main/org/alter/impl/skills/cooking/recipes/BreadRecipes.kt @@ -0,0 +1,36 @@ +package org.alter.impl.skills.cooking.recipes + +import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE +import org.alter.impl.skills.cooking.CookingHelpers.heatCook + +/** + * Bread cooking recipes — baked on a range. + */ +object BreadRecipes { + + val recipes: List = listOf( + heatCook( + rowKey = "cooking_bread", + raw = "items.bread_dough", + cooked = "items.bread", + burnt = "items.burnt_bread", + level = 1, + xp = 40, + stopBurnFire = 35, + stopBurnRange = 35, + stationMask = STATION_RANGE + ), + heatCook( + rowKey = "cooking_pitta_bread", + raw = "items.uncooked_pitta_bread", + cooked = "items.pitta_bread", + burnt = "items.burnt_pitta_bread", + level = 58, + xp = 40, + stopBurnFire = 82, + stopBurnRange = 82, + stationMask = STATION_RANGE + ) + ) +} diff --git a/cache/bin/main/org/alter/impl/skills/cooking/recipes/FishRecipes.kt b/cache/bin/main/org/alter/impl/skills/cooking/recipes/FishRecipes.kt new file mode 100644 index 00000000..4930362c --- /dev/null +++ b/cache/bin/main/org/alter/impl/skills/cooking/recipes/FishRecipes.kt @@ -0,0 +1,278 @@ +package org.alter.impl.skills.cooking.recipes + +import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.STATION_FIRE +import org.alter.impl.skills.cooking.CookingHelpers.heatCook + +/** + * Fish cooking recipes - standard heat-source cooking. + */ +object FishRecipes { + + val recipes: List = listOf( + heatCook( + rowKey = "cooking_shrimps", + raw = "items.raw_shrimp", + cooked = "items.shrimp", + burnt = "items.burnt_shrimp", + level = 1, + xp = 30, + stopBurnFire = 34, + stopBurnRange = 34 + ), + heatCook( + rowKey = "cooking_anchovies", + raw = "items.raw_anchovies", + cooked = "items.anchovies", + burnt = "items.burntfish1", + level = 1, + xp = 30, + stopBurnFire = 34, + stopBurnRange = 34 + ), + heatCook( + rowKey = "cooking_sardine", + raw = "items.raw_sardine", + cooked = "items.sardine", + burnt = "items.burntfish5", + level = 1, + xp = 40, + stopBurnFire = 38, + stopBurnRange = 38 + ), + heatCook( + rowKey = "cooking_herring", + raw = "items.raw_herring", + cooked = "items.herring", + burnt = "items.burntfish3", + level = 5, + xp = 50, + stopBurnFire = 41, + stopBurnRange = 41 + ), + heatCook( + rowKey = "cooking_mackerel", + raw = "items.raw_mackerel", + cooked = "items.mackerel", + burnt = "items.burntfish3", + level = 10, + xp = 60, + stopBurnFire = 45, + stopBurnRange = 45 + ), + heatCook( + rowKey = "cooking_trout", + raw = "items.raw_trout", + cooked = "items.trout", + burnt = "items.burntfish2", + level = 15, + xp = 70, + stopBurnFire = 49, + stopBurnRange = 49 + ), + heatCook( + rowKey = "cooking_cod", + raw = "items.raw_cod", + cooked = "items.cod", + burnt = "items.burntfish2", + level = 18, + xp = 75, + stopBurnFire = 51, + stopBurnRange = 49 + ), + heatCook( + rowKey = "cooking_pike", + raw = "items.raw_pike", + cooked = "items.pike", + burnt = "items.burntfish5", + level = 20, + xp = 80, + stopBurnFire = 54, + stopBurnRange = 54 + ), + heatCook( + rowKey = "cooking_salmon", + raw = "items.raw_salmon", + cooked = "items.salmon", + burnt = "items.burntfish2", + level = 25, + xp = 90, + stopBurnFire = 58, + stopBurnRange = 58 + ), + heatCook( + rowKey = "cooking_slimy_eel", + raw = "items.mort_slimey_eel", + cooked = "items.mort_slimey_eel_cooked", + burnt = "items.burnt_eel", + level = 28, + xp = 95, + stopBurnFire = 61, + stopBurnRange = 61 + ), + heatCook( + rowKey = "cooking_tuna", + raw = "items.raw_tuna", + cooked = "items.tuna", + burnt = "items.burntfish4", + level = 30, + xp = 100, + stopBurnFire = 63, + stopBurnRange = 63 + ), + heatCook( + rowKey = "cooking_lobster", + raw = "items.raw_lobster", + cooked = "items.lobster", + burnt = "items.burnt_lobster", + level = 40, + xp = 120, + stopBurnFire = 74, + stopBurnRange = 74 + ), + heatCook( + rowKey = "cooking_bass", + raw = "items.raw_bass", + cooked = "items.bass", + burnt = "items.burntfish3", + level = 43, + xp = 130, + stopBurnFire = 79, + stopBurnRange = 79 + ), + heatCook( + rowKey = "cooking_swordfish", + raw = "items.raw_swordfish", + cooked = "items.swordfish", + burnt = "items.burnt_swordfish", + level = 45, + xp = 140, + stopBurnFire = 86, + stopBurnRange = 80 + ), + heatCook( + rowKey = "cooking_monkfish", + raw = "items.raw_monkfish", + cooked = "items.monkfish", + burnt = "items.burnt_monkfish", + level = 62, + xp = 150, + stopBurnFire = 92, + stopBurnRange = 90 + ), + heatCook( + rowKey = "cooking_shark", + raw = "items.raw_shark", + cooked = "items.shark", + burnt = "items.burnt_shark", + level = 80, + xp = 210, + stopBurnFire = 100, + stopBurnRange = 100 + ), + heatCook( + rowKey = "cooking_sea_turtle", + raw = "items.raw_seaturtle", + cooked = "items.seaturtle", + burnt = "items.burnt_seaturtle", + level = 82, + xp = 211, + stopBurnFire = 100, + stopBurnRange = 100 + ), + heatCook( + rowKey = "cooking_anglerfish", + raw = "items.raw_anglerfish", + cooked = "items.anglerfish", + burnt = "items.burnt_anglerfish", + level = 84, + xp = 230, + stopBurnFire = 100, + stopBurnRange = 100 + ), + heatCook( + rowKey = "cooking_dark_crab", + raw = "items.raw_dark_crab", + cooked = "items.dark_crab", + burnt = "items.burnt_dark_crab", + level = 90, + xp = 215, + stopBurnFire = 100, + stopBurnRange = 100 + ), + heatCook( + rowKey = "cooking_manta_ray", + raw = "items.raw_mantaray", + cooked = "items.mantaray", + burnt = "items.burnt_mantaray", + level = 91, + xp = 216, + stopBurnFire = 100, + stopBurnRange = 100 + ), + heatCook( + rowKey = "cooking_karambwan", + raw = "items.tbwt_raw_karambwan", + cooked = "items.tbwt_cooked_karambwan", + burnt = "items.tbwt_burnt_karambwan", + level = 30, + xp = 190, + stopBurnFire = 99, + stopBurnRange = 93 + ), + heatCook( + rowKey = "cooking_rainbow_fish", + raw = "items.hunting_raw_fish_special", + cooked = "items.hunting_fish_special", + burnt = "items.burntfish2", + level = 35, + xp = 110, + stopBurnFire = 64, + stopBurnRange = 60 + ), + heatCook( + rowKey = "cooking_cave_eel", + raw = "items.raw_cave_eel", + cooked = "items.cave_eel", + burnt = "items.burnt_cave_eel", + level = 38, + xp = 115, + stopBurnFire = 74, + stopBurnRange = 70 + ), + + // --- Snails (fire-only, Morytania) --- + heatCook( + rowKey = "cooking_thin_snail", + raw = "items.snail_corpse1", + cooked = "items.snail_corpse_cooked1", + burnt = "items.burnt_snail", + level = 12, + xp = 70, + stopBurnFire = 47, + stopBurnRange = 47, + stationMask = STATION_FIRE + ), + heatCook( + rowKey = "cooking_lean_snail", + raw = "items.snail_corpse2", + cooked = "items.snail_corpse_cooked2", + burnt = "items.burnt_snail", + level = 17, + xp = 80, + stopBurnFire = 47, + stopBurnRange = 50 + ), + heatCook( + rowKey = "cooking_fat_snail", + raw = "items.snail_corpse3", + cooked = "items.snail_corpse_cooked3", + burnt = "items.burnt_snail", + level = 22, + xp = 95, + stopBurnFire = 56, + stopBurnRange = 56, + stationMask = STATION_FIRE + ) + ) +} diff --git a/cache/bin/main/org/alter/impl/skills/cooking/recipes/MeatRecipes.kt b/cache/bin/main/org/alter/impl/skills/cooking/recipes/MeatRecipes.kt new file mode 100644 index 00000000..f33f9e63 --- /dev/null +++ b/cache/bin/main/org/alter/impl/skills/cooking/recipes/MeatRecipes.kt @@ -0,0 +1,200 @@ +package org.alter.impl.skills.cooking.recipes + +import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.STATION_FIRE +import org.alter.impl.skills.cooking.CookingHelpers.heatCook +import org.alter.impl.skills.cooking.CookingHelpers.spitRoast + +/** + * Meat cooking recipes - standard cooking and spit roasting. + */ +object MeatRecipes { + + /** Basic meat cooking recipes (fire/range). */ + val basicMeatRecipes: List = listOf( + heatCook( + rowKey = "cooking_chompy", + raw = "items.raw_chompy", + cooked = "items.cooked_chompy", + burnt = "items.ruined_chompy", + level = 30, + xp = 100, + stopBurnFire = 63, + stopBurnRange = 63 + ), + heatCook( + rowKey = "cooking_beef", + raw = "items.raw_beef", + cooked = "items.cooked_meat", + burnt = "items.burnt_meat", + level = 1, + xp = 30, + stopBurnFire = 34, + stopBurnRange = 34 + ), + heatCook( + rowKey = "cooking_chicken", + raw = "items.raw_chicken", + cooked = "items.cooked_chicken", + burnt = "items.burnt_chicken", + level = 1, + xp = 30, + stopBurnFire = 34, + stopBurnRange = 34 + ), + heatCook( + rowKey = "cooking_rat_meat", + raw = "items.raw_rat_meat", + cooked = "items.cooked_meat", + burnt = "items.burnt_meat", + level = 1, + xp = 30, + stopBurnFire = 34, + stopBurnRange = 34 + ), + heatCook( + rowKey = "cooking_bear_meat", + raw = "items.raw_bear_meat", + cooked = "items.cooked_meat", + burnt = "items.burnt_meat", + level = 1, + xp = 30, + stopBurnFire = 34, + stopBurnRange = 34 + ), + heatCook( + rowKey = "cooking_rabbit", + raw = "items.raw_rabbit", + cooked = "items.cooked_rabbit", + burnt = "items.burnt_meat", + level = 1, + xp = 30, + stopBurnFire = 34, + stopBurnRange = 34 + ), + heatCook( + rowKey = "cooking_ugthanki_meat", + raw = "items.raw_ugthanki_meat", + cooked = "items.cooked_ugthanki_meat", + burnt = "items.burnt_meat", + level = 1, + xp = 40, + stopBurnFire = 34, + stopBurnRange = 34 + ) + ) + + /** Spit roasting recipes (skewer + fire-only roast). */ + val spitRoastRecipes: List = + spitRoast( + skewerRowKey = "cooking_skewer_bird_meat", + roastRowKey = "cooking_roast_bird_meat", + rawMeat = "items.spit_raw_bird_meat", + skewered = "items.spit_skewered_bird_meat", + cooked = "items.spit_roasted_bird_meat", + burnt = "items.spit_burned_bird_meat", + cookingLevel = 11, + xp = 60, + stopBurnFire = 44, + stopBurnRange = 44 + ) + + spitRoast( + skewerRowKey = "cooking_skewer_beast_meat", + roastRowKey = "cooking_roast_beast_meat", + rawMeat = "items.spit_raw_beast_meat", + skewered = "items.spit_skewered_beast_meat", + cooked = "items.spit_roasted_beast_meat", + burnt = "items.spit_burned_beast_meat", + cookingLevel = 21, + xp = 82, + stopBurnFire = 55, + stopBurnRange = 55 + ) + + spitRoast( + skewerRowKey = "cooking_skewer_rabbit_meat", + roastRowKey = "cooking_roast_rabbit_meat", + rawMeat = "items.raw_rabbit", + skewered = "items.spit_skewered_rabbit_meat", + cooked = "items.spit_roasted_rabbit_meat", + burnt = "items.spit_burned_rabbit_meat", + cookingLevel = 16, + xp = 70, + stopBurnFire = 99, + stopBurnRange = 99 + ) + + /** + * Hunter meat recipes — meats obtained from pitfall trapping. + * These are standard heatCook recipes; some are fire-only. + * + * Note: Small kebbits (wild, barb-tailed, dashing) are eaten raw and do NOT + * require cooking. Only pitfall-trapped animals have raw→cooked transitions. + */ + val hunterMeatRecipes: List = listOf( + heatCook( + rowKey = "cooking_larupia", + raw = "items.hunting_larupia_meat", + cooked = "items.larupia_cooked", + burnt = "items.burnt_largebeast", + level = 31, + xp = 92, + stopBurnFire = 59, + stopBurnRange = 59, + stationMask = STATION_FIRE + ), + heatCook( + rowKey = "cooking_graahk", + raw = "items.hunting_graahk_meat", + cooked = "items.graahk_cooked", + burnt = "items.burnt_largebeast", + level = 41, + xp = 124, + stopBurnFire = 75, + stopBurnRange = 75, + stationMask = STATION_FIRE + ), + heatCook( + rowKey = "cooking_kyatt", + raw = "items.hunting_kyatt_meat", + cooked = "items.kyatt_cooked", + burnt = "items.burnt_largebeast", + level = 51, + xp = 143, + stopBurnFire = 86, + stopBurnRange = 80 + ), + heatCook( + rowKey = "cooking_pyre_fox", + raw = "items.hunting_fennecfox_meat", + cooked = "items.fennecfox_cooked", + burnt = "items.burnt_foxmeat", + level = 59, + xp = 154, + stopBurnFire = 93, + stopBurnRange = 92 + ), + heatCook( + rowKey = "cooking_sunlight_antelope", + raw = "items.hunting_antelopesun_meat", + cooked = "items.antelopesun_cooked", + burnt = "items.burnt_antelope", + level = 68, + xp = 175, + stopBurnFire = 100, + stopBurnRange = 95 + ), + heatCook( + rowKey = "cooking_moonlight_antelope", + raw = "items.hunting_antelopemoon_meat", + cooked = "items.antelopemoon_cooked", + burnt = "items.burnt_antelope", + level = 92, + xp = 220, + stopBurnFire = 100, + stopBurnRange = 100 + ) + ) + + /** All meat recipes combined. */ + val recipes: List = basicMeatRecipes + spitRoastRecipes + hunterMeatRecipes +} diff --git a/cache/bin/main/org/alter/impl/skills/cooking/recipes/MiscFoodRecipes.kt b/cache/bin/main/org/alter/impl/skills/cooking/recipes/MiscFoodRecipes.kt new file mode 100644 index 00000000..7e2359e7 --- /dev/null +++ b/cache/bin/main/org/alter/impl/skills/cooking/recipes/MiscFoodRecipes.kt @@ -0,0 +1,141 @@ +package org.alter.impl.skills.cooking.recipes + +import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingHelpers.heatCook +import org.alter.impl.skills.cooking.CookingHelpers.multiStepCook +import org.alter.impl.skills.cooking.PrepStepDef + +/** + * Miscellaneous cooking recipes — vegetable side dishes, dairy, scrambled egg, etc. + */ +object MiscFoodRecipes { + + /** Sweetcorn: raw sweetcorn on fire/range. */ + val sweetcorn: List = listOf( + heatCook( + rowKey = "cooking_sweetcorn", + raw = "items.sweetcorn", + cooked = "items.sweetcorn_cooked", + burnt = "items.sweetcorn_burnt", + level = 28, + xp = 104, + stopBurnFire = 61, + stopBurnRange = 61 + ) + ) + + /** Scrambled egg: egg + bowl on range. */ + val scrambledEgg: List = multiStepCook( + key = "items.bowl_egg_scrambled", + level = 13, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_scrambled_egg_mix", + inputs = listOf( + "items.egg" to 1, + "items.bowl_empty" to 1 + ), + output = "items.bowl_egg_raw" + ) + ) + ) + listOf( + heatCook( + rowKey = "cooking_scrambled_egg_cook", + raw = "items.bowl_egg_raw", + cooked = "items.bowl_egg_scrambled", + burnt = "items.bowl_egg_burnt", + level = 13, + xp = 50, + stopBurnFire = 46, + stopBurnRange = 46 + ) + ) + + /** Fried onions: chopped onion + bowl on fire/range. */ + val friedOnions: List = listOf( + heatCook( + rowKey = "cooking_fried_onions", + raw = "items.bowl_onion", + cooked = "items.bowl_onion_fried", + burnt = "items.bowl_onion_burnt", + level = 42, + xp = 60, + stopBurnFire = 74, + stopBurnRange = 74 + ) + ) + + /** Fried mushrooms: sliced mushrooms + bowl on fire/range. */ + val friedMushrooms: List = listOf( + heatCook( + rowKey = "cooking_fried_mushrooms", + raw = "items.bowl_mushroom_raw", + cooked = "items.bowl_mushroom_fried", + burnt = "items.bowl_mushroom_burnt", + level = 46, + xp = 60, + stopBurnFire = 80, + stopBurnRange = 80 + ) + ) + + /** Mushroom & onion: fried mushrooms + fried onions. */ + val mushroomAndOnion: List = multiStepCook( + key = "items.bowl_mushroom+onion", + level = 57, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_mushroom_onion_combine", + inputs = listOf( + "items.bowl_mushroom_fried" to 1, + "items.bowl_onion_fried" to 1 + ), + output = "items.bowl_mushroom+onion", + always = listOf("items.bowl_empty" to 1) + ) + ) + ) + + /** Tuna and corn: cooked tuna + cooked sweetcorn + bowl. */ + val tunaAndCorn: List = multiStepCook( + key = "items.bowl_tuna+sweetcorn", + level = 67, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_tuna_corn_combine", + inputs = listOf( + "items.tuna" to 1, + "items.sweetcorn_cooked" to 1, + "items.bowl_empty" to 1 + ), + output = "items.bowl_tuna+sweetcorn" + ) + ) + ) + + /** Chocolate cake: cake + chocolate bar. */ + val chocolateCake: List = multiStepCook( + key = "items.chocolate_cake", + level = 50, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_chocolate_cake", + inputs = listOf( + "items.cake" to 1, + "items.chocolate_bar" to 1 + ), + output = "items.chocolate_cake" + ) + ) + ) + + /** All misc cooking recipes combined. */ + val recipes: List = + sweetcorn + + scrambledEgg + + friedOnions + + friedMushrooms + + mushroomAndOnion + + tunaAndCorn + + chocolateCake +} diff --git a/cache/bin/main/org/alter/impl/skills/cooking/recipes/PieRecipes.kt b/cache/bin/main/org/alter/impl/skills/cooking/recipes/PieRecipes.kt new file mode 100644 index 00000000..dfcf0ddf --- /dev/null +++ b/cache/bin/main/org/alter/impl/skills/cooking/recipes/PieRecipes.kt @@ -0,0 +1,398 @@ +package org.alter.impl.skills.cooking.recipes + +import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE +import org.alter.impl.skills.cooking.CookingHelpers.multiStepCook +import org.alter.impl.skills.cooking.HeatStepDef +import org.alter.impl.skills.cooking.PrepStepDef + +/** + * Remaining pie recipes beyond garden pie. + * + * All pies follow the same flow: + * 1. Prep steps: add fillings to a pie shell (item-on-item) + * 2. Heat step: bake the uncooked pie on a range + */ +object PieRecipes { + + /** Redberry pie (level 10). */ + val redberryPie: List = multiStepCook( + key = "items.uncooked_redberry_pie", + level = 10, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_redberry_pie_add_berries", + inputs = listOf( + "items.pie_shell" to 1, + "items.redberries" to 1 + ), + output = "items.uncooked_redberry_pie" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_redberry_pie_bake", + raw = "items.uncooked_redberry_pie", + cooked = "items.redberry_pie", + burnt = "items.burnt_pie", + xp = 78, + stopBurnFire = 44, + stopBurnRange = 44, + stationMask = STATION_RANGE + ) + ) + + /** Meat pie (level 20). */ + val meatPie: List = multiStepCook( + key = "items.uncooked_meat_pie", + level = 20, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_meat_pie_add_meat", + inputs = listOf( + "items.pie_shell" to 1, + "items.cooked_meat" to 1 + ), + output = "items.uncooked_meat_pie" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_meat_pie_bake", + raw = "items.uncooked_meat_pie", + cooked = "items.meat_pie", + burnt = "items.burnt_pie", + xp = 110, + stopBurnFire = 54, + stopBurnRange = 54, + stationMask = STATION_RANGE + ) + ) + + /** Mud pie (level 29). */ + val mudPie: List = multiStepCook( + key = "items.uncooked_mud_pie", + level = 29, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_mud_pie_add_compost", + inputs = listOf( + "items.pie_shell" to 1, + "items.bucket_compost" to 1 + ), + output = "items.unfinished_mud_pie_1" + ), + PrepStepDef( + rowKey = "cooking_mud_pie_add_water", + inputs = listOf( + "items.unfinished_mud_pie_1" to 1, + "items.bucket_water" to 1 + ), + output = "items.unfinished_mud_pie_2", + always = listOf("items.bucket_empty" to 1) + ), + PrepStepDef( + rowKey = "cooking_mud_pie_add_clay", + inputs = listOf( + "items.unfinished_mud_pie_2" to 1, + "items.clay" to 1 + ), + output = "items.uncooked_mud_pie" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_mud_pie_bake", + raw = "items.uncooked_mud_pie", + cooked = "items.mud_pie", + burnt = "items.burnt_pie", + xp = 128, + stopBurnFire = 63, + stopBurnRange = 63, + stationMask = STATION_RANGE + ) + ) + + /** Apple pie (level 30). */ + val applePie: List = multiStepCook( + key = "items.uncooked_apple_pie", + level = 30, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_apple_pie_add_apple", + inputs = listOf( + "items.pie_shell" to 1, + "items.cooking_apple" to 1 + ), + output = "items.uncooked_apple_pie" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_apple_pie_bake", + raw = "items.uncooked_apple_pie", + cooked = "items.apple_pie", + burnt = "items.burnt_pie", + xp = 130, + stopBurnFire = 64, + stopBurnRange = 64, + stationMask = STATION_RANGE + ) + ) + + /** Fish pie (level 47). */ + val fishPie: List = multiStepCook( + key = "items.uncooked_fish_pie", + level = 47, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_fish_pie_add_trout", + inputs = listOf( + "items.pie_shell" to 1, + "items.trout" to 1 + ), + output = "items.unfinished_fish_pie_1" + ), + PrepStepDef( + rowKey = "cooking_fish_pie_add_cod", + inputs = listOf( + "items.unfinished_fish_pie_1" to 1, + "items.cod" to 1 + ), + output = "items.unfinished_fish_pie_2" + ), + PrepStepDef( + rowKey = "cooking_fish_pie_add_potato", + inputs = listOf( + "items.unfinished_fish_pie_2" to 1, + "items.potato" to 1 + ), + output = "items.uncooked_fish_pie" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_fish_pie_bake", + raw = "items.uncooked_fish_pie", + cooked = "items.fish_pie", + burnt = "items.burnt_pie", + xp = 164, + stopBurnFire = 81, + stopBurnRange = 81, + stationMask = STATION_RANGE + ) + ) + + /** Botanical pie (level 52). */ + val botanicalPie: List = multiStepCook( + key = "items.uncooked_botanical_pie", + level = 52, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_botanical_pie_add_golovanova", + inputs = listOf( + "items.pie_shell" to 1, + "items.golovanova_top" to 1 + ), + output = "items.uncooked_botanical_pie" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_botanical_pie_bake", + raw = "items.uncooked_botanical_pie", + cooked = "items.botanical_pie", + burnt = "items.burnt_pie", + xp = 180, + stopBurnFire = 86, + stopBurnRange = 86, + stationMask = STATION_RANGE + ) + ) + + /** Mushroom pie (level 60). */ + val mushroomPie: List = multiStepCook( + key = "items.uncooked_mushroom_pie", + level = 60, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_mushroom_pie_add_sulliuscep", + inputs = listOf( + "items.pie_shell" to 1, + "items.fossil_sulliuscep_cap" to 1 + ), + output = "items.uncooked_mushroom_pie" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_mushroom_pie_bake", + raw = "items.uncooked_mushroom_pie", + cooked = "items.mushroom_pie", + burnt = "items.burnt_pie", + xp = 200, + stopBurnFire = 94, + stopBurnRange = 94, + stationMask = STATION_RANGE + ) + ) + + /** Admiral pie (level 70). */ + val admiralPie: List = multiStepCook( + key = "items.uncooked_admiral_pie", + level = 70, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_admiral_pie_add_salmon", + inputs = listOf( + "items.pie_shell" to 1, + "items.salmon" to 1 + ), + output = "items.unfinished_admiral_pie_1" + ), + PrepStepDef( + rowKey = "cooking_admiral_pie_add_tuna", + inputs = listOf( + "items.unfinished_admiral_pie_1" to 1, + "items.tuna" to 1 + ), + output = "items.unfinished_admiral_pie_2" + ), + PrepStepDef( + rowKey = "cooking_admiral_pie_add_potato", + inputs = listOf( + "items.unfinished_admiral_pie_2" to 1, + "items.potato" to 1 + ), + output = "items.uncooked_admiral_pie" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_admiral_pie_bake", + raw = "items.uncooked_admiral_pie", + cooked = "items.admiral_pie", + burnt = "items.burnt_pie", + xp = 210, + stopBurnFire = 100, + stopBurnRange = 94, + stationMask = STATION_RANGE + ) + ) + + /** Dragonfruit pie (level 73). */ + val dragonfruitPie: List = multiStepCook( + key = "items.uncooked_dragonfruit_pie", + level = 73, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_dragonfruit_pie_add_fruit", + inputs = listOf( + "items.pie_shell" to 1, + "items.dragonfruit" to 1 + ), + output = "items.uncooked_dragonfruit_pie" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_dragonfruit_pie_bake", + raw = "items.uncooked_dragonfruit_pie", + cooked = "items.dragonfruit_pie", + burnt = "items.burnt_pie", + xp = 220, + stopBurnFire = 100, + stopBurnRange = 97, + stationMask = STATION_RANGE + ) + ) + + /** Wild pie (level 85). */ + val wildPie: List = multiStepCook( + key = "items.uncooked_wild_pie", + level = 85, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_wild_pie_add_bear", + inputs = listOf( + "items.pie_shell" to 1, + "items.raw_bear_meat" to 1 + ), + output = "items.unfinished_wild_pie_1" + ), + PrepStepDef( + rowKey = "cooking_wild_pie_add_chompy", + inputs = listOf( + "items.unfinished_wild_pie_1" to 1, + "items.raw_chompy" to 1 + ), + output = "items.unfinished_wild_pie_2" + ), + PrepStepDef( + rowKey = "cooking_wild_pie_add_rabbit", + inputs = listOf( + "items.unfinished_wild_pie_2" to 1, + "items.raw_rabbit" to 1 + ), + output = "items.uncooked_wild_pie" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_wild_pie_bake", + raw = "items.uncooked_wild_pie", + cooked = "items.wild_pie", + burnt = "items.burnt_pie", + xp = 240, + stopBurnFire = 100, + stopBurnRange = 100, + stationMask = STATION_RANGE + ) + ) + + /** Summer pie (level 95). */ + val summerPie: List = multiStepCook( + key = "items.uncooked_summer_pie", + level = 95, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_summer_pie_add_watermelon", + inputs = listOf( + "items.pie_shell" to 1, + "items.watermelon" to 1 + ), + output = "items.unfinished_summer_pie_1" + ), + PrepStepDef( + rowKey = "cooking_summer_pie_add_apple", + inputs = listOf( + "items.unfinished_summer_pie_1" to 1, + "items.cooking_apple" to 1 + ), + output = "items.unfinished_summer_pie_2" + ), + PrepStepDef( + rowKey = "cooking_summer_pie_add_strawberry", + inputs = listOf( + "items.unfinished_summer_pie_2" to 1, + "items.strawberry" to 1 + ), + output = "items.uncooked_summer_pie" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_summer_pie_bake", + raw = "items.uncooked_summer_pie", + cooked = "items.summer_pie", + burnt = "items.burnt_pie", + xp = 260, + stopBurnFire = 100, + stopBurnRange = 100, + stationMask = STATION_RANGE + ) + ) + + /** All pie recipes combined. */ + val recipes: List = + redberryPie + + meatPie + + mudPie + + applePie + + fishPie + + botanicalPie + + mushroomPie + + admiralPie + + dragonfruitPie + + wildPie + + summerPie +} diff --git a/cache/bin/main/org/alter/impl/skills/cooking/recipes/PizzaRecipes.kt b/cache/bin/main/org/alter/impl/skills/cooking/recipes/PizzaRecipes.kt new file mode 100644 index 00000000..6977ce15 --- /dev/null +++ b/cache/bin/main/org/alter/impl/skills/cooking/recipes/PizzaRecipes.kt @@ -0,0 +1,107 @@ +package org.alter.impl.skills.cooking.recipes + +import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE +import org.alter.impl.skills.cooking.CookingHelpers.multiStepCook +import org.alter.impl.skills.cooking.HeatStepDef +import org.alter.impl.skills.cooking.PrepStepDef + +/** + * Pizza recipes — dough + toppings + range bake. + * + * Flow: pizza base → uncooked pizza (item-on-item) → plain pizza (bake) → topped pizza (item-on-item) + */ +object PizzaRecipes { + + /** Plain pizza: pizza base on range. */ + val plainPizzaRecipes: List = multiStepCook( + key = "items.uncooked_pizza", + level = 35, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_pizza_add_tomato", + inputs = listOf( + "items.pizza_base" to 1, + "items.tomato" to 1 + ), + output = "items.incomplete_pizza" + ), + PrepStepDef( + rowKey = "cooking_pizza_add_cheese", + inputs = listOf( + "items.incomplete_pizza" to 1, + "items.cheese" to 1 + ), + output = "items.uncooked_pizza" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_pizza_bake", + raw = "items.uncooked_pizza", + cooked = "items.plain_pizza", + burnt = "items.burnt_pizza", + xp = 143, + stopBurnFire = 68, + stopBurnRange = 68, + stationMask = STATION_RANGE + ) + ) + + /** Meat pizza topping: plain pizza + cooked meat. */ + val meatPizzaRecipes: List = multiStepCook( + key = "items.meat_pizza", + level = 45, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_pizza_add_meat", + inputs = listOf( + "items.plain_pizza" to 1, + "items.cooked_meat" to 1 + ), + output = "items.meat_pizza", + xp = 26 + ) + ) + ) + + /** Anchovy pizza topping: plain pizza + anchovies. */ + val anchovyPizzaRecipes: List = multiStepCook( + key = "items.anchovie_pizza", + level = 55, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_pizza_add_anchovies", + inputs = listOf( + "items.plain_pizza" to 1, + "items.anchovies" to 1 + ), + output = "items.anchovie_pizza", + xp = 39 + ) + ) + ) + + /** Pineapple pizza topping: plain pizza + pineapple ring/chunks. */ + val pineapplePizzaRecipes: List = multiStepCook( + key = "items.pineapple_pizza", + level = 65, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_pizza_add_pineapple", + inputs = listOf( + "items.plain_pizza" to 1, + "items.pineapple_ring" to 1 + ), + output = "items.pineapple_pizza", + xp = 52 + ) + ) + ) + + /** All pizza recipes combined. */ + val recipes: List = + plainPizzaRecipes + + meatPizzaRecipes + + anchovyPizzaRecipes + + pineapplePizzaRecipes +} diff --git a/cache/bin/main/org/alter/impl/skills/cooking/recipes/PotatoRecipes.kt b/cache/bin/main/org/alter/impl/skills/cooking/recipes/PotatoRecipes.kt new file mode 100644 index 00000000..0898a906 --- /dev/null +++ b/cache/bin/main/org/alter/impl/skills/cooking/recipes/PotatoRecipes.kt @@ -0,0 +1,121 @@ +package org.alter.impl.skills.cooking.recipes + +import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE +import org.alter.impl.skills.cooking.CookingHelpers.heatCook +import org.alter.impl.skills.cooking.CookingHelpers.multiStepCook +import org.alter.impl.skills.cooking.HeatStepDef +import org.alter.impl.skills.cooking.PrepStepDef + +/** + * Potato-based recipes — baked potato and toppings. + */ +object PotatoRecipes { + + /** Baked potato: raw potato on a range. */ + val bakedPotato: List = listOf( + heatCook( + rowKey = "cooking_baked_potato", + raw = "items.potato", + cooked = "items.potato_baked", + burnt = "items.potato_burnt", + level = 7, + xp = 15, + stopBurnFire = 40, + stopBurnRange = 40, + stationMask = STATION_RANGE + ) + ) + + /** Potato with butter: baked potato + pat of butter. */ + val potatoWithButter: List = multiStepCook( + key = "items.potato_butter", + level = 39, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_potato_add_butter", + inputs = listOf( + "items.potato_baked" to 1, + "items.pot_of_butter" to 1 + ), + output = "items.potato_butter" + ) + ) + ) + + /** Potato with cheese: potato with butter + cheese. */ + val potatoWithCheese: List = multiStepCook( + key = "items.potato_cheese", + level = 47, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_potato_add_cheese", + inputs = listOf( + "items.potato_butter" to 1, + "items.cheese" to 1 + ), + output = "items.potato_cheese" + ) + ) + ) + + /** Egg potato: potato with butter + scrambled egg. */ + val eggPotato: List = multiStepCook( + key = "items.potato_egg+tomato", + level = 51, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_potato_add_egg", + inputs = listOf( + "items.potato_butter" to 1, + "items.bowl_egg_scrambled" to 1 + ), + output = "items.potato_egg+tomato", + always = listOf("items.bowl_empty" to 1) + ) + ) + ) + + /** Mushroom potato: potato with butter + mushroom & onion. */ + val mushroomPotato: List = multiStepCook( + key = "items.potato_mushroom+onion", + level = 64, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_potato_add_mushroom_onion", + inputs = listOf( + "items.potato_butter" to 1, + "items.bowl_mushroom+onion" to 1 + ), + output = "items.potato_mushroom+onion", + always = listOf("items.bowl_empty" to 1) + ) + ) + ) + + /** Tuna potato: potato with butter + tuna and corn. */ + val tunaPotato: List = multiStepCook( + key = "items.potato_tuna+sweetcorn", + level = 68, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_potato_add_tuna_corn", + inputs = listOf( + "items.potato_butter" to 1, + "items.bowl_tuna+sweetcorn" to 1 + ), + output = "items.potato_tuna+sweetcorn", + always = listOf("items.bowl_empty" to 1) + ) + ) + ) + + /** All potato recipes combined. */ + val recipes: List = + bakedPotato + + potatoWithButter + + potatoWithCheese + + eggPotato + + mushroomPotato + + tunaPotato +} diff --git a/cache/bin/main/org/alter/impl/skills/cooking/recipes/StewRecipes.kt b/cache/bin/main/org/alter/impl/skills/cooking/recipes/StewRecipes.kt new file mode 100644 index 00000000..fcc11eb7 --- /dev/null +++ b/cache/bin/main/org/alter/impl/skills/cooking/recipes/StewRecipes.kt @@ -0,0 +1,89 @@ +package org.alter.impl.skills.cooking.recipes + +import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingHelpers.multiStepCook +import org.alter.impl.skills.cooking.HeatStepDef +import org.alter.impl.skills.cooking.PrepStepDef + +/** + * Stew recipes — bowl of water + ingredients on heat source. + */ +object StewRecipes { + + /** Basic stew: bowl of water + cooked meat + potato on fire/range. */ + val stewRecipes: List = multiStepCook( + key = "items.uncooked_stew", + level = 25, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_stew_add_potato", + inputs = listOf( + "items.bowl_water" to 1, + "items.potato" to 1 + ), + output = "items.stew1" + ), + PrepStepDef( + rowKey = "cooking_stew_add_meat", + inputs = listOf( + "items.stew1" to 1, + "items.cooked_meat" to 1 + ), + output = "items.uncooked_stew" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_stew_cook", + raw = "items.uncooked_stew", + cooked = "items.stew", + burnt = "items.burnt_stew", + xp = 117, + stopBurnFire = 58, + stopBurnRange = 58 + ) + ) + + /** Curry: bowl of water + potato + cooked meat + spice on fire/range. */ + val curryRecipes: List = multiStepCook( + key = "items.uncooked_curry", + level = 60, + prepSteps = listOf( + PrepStepDef( + rowKey = "cooking_curry_add_potato", + inputs = listOf( + "items.bowl_water" to 1, + "items.potato" to 1 + ), + output = "items.stew1" + ), + PrepStepDef( + rowKey = "cooking_curry_add_meat", + inputs = listOf( + "items.stew1" to 1, + "items.cooked_meat" to 1 + ), + output = "items.uncooked_stew" + ), + PrepStepDef( + rowKey = "cooking_curry_add_spice", + inputs = listOf( + "items.uncooked_stew" to 1, + "items.spicespot" to 1 + ), + output = "items.uncooked_curry" + ) + ), + heatStep = HeatStepDef( + rowKey = "cooking_curry_cook", + raw = "items.uncooked_curry", + cooked = "items.curry", + burnt = "items.burnt_curry", + xp = 280, + stopBurnFire = 74, + stopBurnRange = 74 + ) + ) + + /** All stew recipes combined. */ + val recipes: List = stewRecipes + curryRecipes +} diff --git a/cache/bin/main/org/alter/impl/skills/cooking/recipes/WineRecipes.kt b/cache/bin/main/org/alter/impl/skills/cooking/recipes/WineRecipes.kt new file mode 100644 index 00000000..b9bf86ca --- /dev/null +++ b/cache/bin/main/org/alter/impl/skills/cooking/recipes/WineRecipes.kt @@ -0,0 +1,55 @@ +package org.alter.impl.skills.cooking.recipes + +import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.OutcomeKind +import org.alter.impl.skills.cooking.CookingConstants.Trigger +import org.alter.impl.skills.cooking.InputDef +import org.alter.impl.skills.cooking.OutcomeDef + +/** + * Wine recipes — fermentation mechanic. + * + * Wine is made by using grapes on a jug of water. The fermentation occurs + * automatically after a delay (12 seconds / ~20 ticks). XP is awarded only + * on success. The success/failure is determined at the time of combining, + * not at fermentation completion. + * + * Since wine doesn't use a heat source, it's modeled as an ITEM_ON_ITEM + * trigger. The actual fermentation delay is handled by CookingEvents. + */ +object WineRecipes { + + val jugOfWine: ActionDef = ActionDef( + rowId = "dbrows.cooking_wine", + key = "items.grapes", + variant = 1, + level = 35, + stopBurnFire = 68, + stopBurnRange = 68, + stationMask = 0, // wine doesn't use a station; marker for event handler + trigger = Trigger.ITEM_ON_ITEM, + inputs = listOf( + InputDef("items.grapes", 1), + InputDef("items.jug_water", 1) + ), + outcomes = listOf( + OutcomeDef( + rowSuffix = "success", + kind = OutcomeKind.SUCCESS, + item = "items.jug_unfermented_wine", + xp = 200, + weight = 1 + ), + OutcomeDef( + rowSuffix = "fail", + kind = OutcomeKind.FAIL, + item = "items.jug_unfermented_wine", + xp = 0, + weight = 1 + ) + ) + ) + + /** All wine recipes. */ + val recipes: List = listOf(jugOfWine) +} diff --git a/cache/bin/main/org/alter/impl/skills/runecrafting/Alters.kt b/cache/bin/main/org/alter/impl/skills/runecrafting/Alters.kt new file mode 100644 index 00000000..8af92767 --- /dev/null +++ b/cache/bin/main/org/alter/impl/skills/runecrafting/Alters.kt @@ -0,0 +1,262 @@ +package org.alter.impl.skills.runecrafting + +import dev.openrune.definition.dbtables.dbTable +import dev.openrune.definition.util.VarType +import dev.openrune.util.Coords +import org.alter.impl.skills.runecrafting.Tiara.ITEM + +enum class AltarData( + val ruins: List? = null, + val altar: String, + val exitPortal: String? = null, + val talisman: String? = null, + val tiara: String? = null, + val varbit: String? = null, + val rune: Rune, + val entrance: Int? = null, + val exit: Int? = null, + val option: String = "craft-rune", + val row : String, + val combo : List = emptyList() +) { + AIR( + ruins = listOf("objects.airtemple_ruined_old", "objects.airtemple_ruined_new"), + altar = "objects.air_altar", + exitPortal = "objects.airtemple_exit_portal", + talisman = "items.air_talisman", + tiara = "dbrows.runecrafting_tiara_air", + varbit = "varbits.rc_no_tally_required_air", + rune = Rune.AIR, + entrance = Coords(2841, 4830), + exit = Coords(2983, 3288), + row = "dbrows.runecrafting_altar_air", + combo = listOf(CombinationRuneData.MIST_AIR, CombinationRuneData.SMOKE_AIR) + ), + MIND( + ruins = listOf("objects.mindtemple_ruined_old", "objects.mindtemple_ruined_new"), + altar = "objects.mind_altar", + exitPortal = "objects.mindtemple_exit_portal", + talisman = "items.mind_talisman", + tiara = "dbrows.runecrafting_tiara_mind", + varbit = "varbits.rc_no_tally_required_mind", + rune = Rune.MIND, + entrance = Coords(2793, 4829), + exit = Coords(2980, 3511), + row = "dbrows.runecrafting_altar_mind" + ), + WATER( + ruins = listOf("objects.watertemple_ruined_old", "objects.watertemple_ruined_new"), + altar = "objects.water_altar", + exitPortal = "objects.watertemple_exit_portal", + talisman = "items.water_talisman", + tiara = "dbrows.runecrafting_tiara_water", + varbit = "varbits.rc_no_tally_required_water", + rune = Rune.WATER, + entrance = Coords(2725, 4832), + exit = Coords(3182, 3162), + row = "dbrows.runecrafting_altar_water", + combo = listOf(CombinationRuneData.MUD_WATER, CombinationRuneData.MIST_WATER,CombinationRuneData.STEAM_WATER) + ), + EARTH( + ruins = listOf("objects.earthtemple_ruined_old", "objects.earthtemple_ruined_new"), + altar = "objects.earth_altar", + exitPortal = "objects.earthtemple_exit_portal", + talisman = "items.earth_talisman", + tiara = "dbrows.runecrafting_tiara_earth", + varbit = "varbits.rc_no_tally_required_earth", + rune = Rune.EARTH, + entrance = Coords(2657, 4830), + exit = Coords(3302, 3477), + row = "dbrows.runecrafting_altar_earth", + combo = listOf(CombinationRuneData.DUST_EARTH, CombinationRuneData.MUD_EARTH,CombinationRuneData.LAVA_EARTH) + ), + FIRE( + ruins = listOf("objects.firetemple_ruined_old", "objects.firetemple_ruined_new"), + altar = "objects.fire_altar", + exitPortal = "objects.firetemple_exit_portal", + talisman = "items.fire_talisman", + tiara = "dbrows.runecrafting_tiara_fire", + varbit = "varbits.rc_no_tally_required_fire", + rune = Rune.FIRE, + entrance = Coords(2576, 4848), + exit = Coords(3310, 3252), + row = "dbrows.runecrafting_altar_fire", + combo = listOf(CombinationRuneData.LAVA_FIRE, CombinationRuneData.SMOKE_FIRE,CombinationRuneData.STEAM_FIRE) + ), + BODY( + ruins = listOf("objects.bodytemple_ruined_old", "objects.bodytemple_ruined_new"), + altar = "objects.body_altar", + exitPortal = "objects.bodytemple_exit_portal", + talisman = "items.body_talisman", + tiara = "dbrows.runecrafting_tiara_body", + varbit = "varbits.rc_no_tally_required_body", + rune = Rune.BODY, + entrance = Coords(2519, 4847), + exit = Coords(3050, 3442), + row = "dbrows.runecrafting_altar_body" + ), + COSMIC( + ruins = listOf("objects.cosmictemple_ruined_old", "objects.cosmictemple_ruined_new"), + altar = "objects.cosmic_altar", + exitPortal = "objects.cosmictemple_exit_portal", + talisman = "items.cosmic_talisman", + tiara = "dbrows.runecrafting_tiara_cosmic", + varbit = "varbits.rc_no_tally_required_cosmic", + rune = Rune.COSMIC, + entrance = Coords(2142, 4813), + exit = Coords(2405, 4381), + row = "dbrows.runecrafting_altar_cosmic" + ), + CHAOS( + ruins = listOf("objects.chaostemple_ruined_old", "objects.chaostemple_ruined_new"), + altar = "objects.chaos_altar", + exitPortal = "objects.chaostemple_exit_portal", + talisman = "items.chaos_talisman", + tiara = "dbrows.runecrafting_tiara_chaos", + varbit = "varbits.rc_no_tally_required_chaos", + rune = Rune.CHAOS, + entrance = Coords(2280, 4837), + exit = Coords(3060, 3585), + row = "dbrows.runecrafting_altar_chaos" + ), + ASTRAL( + altar = "objects.astral_altar", + rune = Rune.ASTRAL, + row = "dbrows.runecrafting_altar_astral" + ), + NATURE( + ruins = listOf("objects.naturetemple_ruined_old", "objects.naturetemple_ruined_new"), + altar = "objects.nature_altar", + exitPortal = "objects.naturetemple_exit_portal", + talisman = "items.nature_talisman", + tiara = "dbrows.runecrafting_tiara_nature", + varbit = "varbits.rc_no_tally_required_nature", + rune = Rune.NATURE, + entrance = Coords(2400, 4835), + exit = Coords(2865, 3022), + row = "dbrows.runecrafting_altar_nature" + ), + LAW( + ruins = listOf("objects.lawtemple_ruined_old", "objects.lawtemple_ruined_new"), + altar = "objects.law_altar", + exitPortal = "objects.lawtemple_exit_portal", + talisman = "items.law_talisman", + tiara = "dbrows.runecrafting_tiara_law", + varbit = "varbits.rc_no_tally_required_law", + rune = Rune.LAW, + entrance = Coords(2464, 4819), + exit = Coords(2858, 3378), + row = "dbrows.runecrafting_altar_law" + ), + DEATH( + ruins = listOf("objects.deathtemple_ruined_old", "objects.deathtemple_ruined_new"), + altar = "objects.death_altar", + exitPortal = "objects.deathtemple_exit_portal", + talisman = "items.death_talisman", + tiara = "dbrows.runecrafting_tiara_death", + varbit = "varbits.rc_no_tally_required_death", + rune = Rune.DEATH, + entrance = Coords(2208, 4830), + exit = Coords(1863, 4639), + row = "dbrows.runecrafting_altar_death" + ), + BLOOD( + altar = "objects.blood_altar", + rune = Rune.BLOOD, + option = "bind", + row = "dbrows.runecrafting_altar_blood" + ), + + SOUL( + altar = "objects.archeus_altar_soul", + rune = Rune.SOUL, + option = "bind", + row = "dbrows.runecrafting_altar_soul" + ), + WRATH( + ruins = listOf("objects.wrathtemple_ruined_0op", "objects.wrathtemple_ruined_1op"), + altar = "objects.wrath_altar", + exitPortal = "objects.wrathtemple_exit_portal", + talisman = "items.wrath_talisman", + tiara = "dbrows.runecrafting_tiara_wrath", + varbit = "varbits.rc_no_tally_required_wrath", + rune = Rune.WRATH, + entrance = Coords(2335, 4826), + exit = Coords(2447, 2822), + row = "dbrows.runecrafting_altar_wrath" + ); + + companion object { + val values = enumValues() + } +} + +object Alters { + + const val ALTAR_OBJECT = 0 + const val EXIT_PORTAL = 1 + const val TALISMAN = 2 + const val TIARA_ITEM = 3 + const val VARBIT = 4 + const val RUNE = 5 + const val ENTRANCE = 6 + const val EXIT = 7 + const val RUINS = 8 + const val COMBO = 9 + + fun altars() = dbTable("tables.runecrafting_altars", serverOnly = true) { + + column("altar_object", ALTAR_OBJECT, VarType.LOC) + column("exit_portal", EXIT_PORTAL, VarType.LOC) + column("talisman", TALISMAN, VarType.OBJ) + column("tiara", TIARA_ITEM, VarType.DBROW) + column("varbit", VARBIT, VarType.INT) + column("rune", RUNE, VarType.DBROW) + column("entrance", ENTRANCE, VarType.COORDGRID) + column("exit", EXIT, VarType.COORDGRID) + column("ruins", RUINS, VarType.LOC) + column("combo", COMBO, VarType.DBROW) + + AltarData.values.forEach { + row(it.row) { + columnRSCM(ALTAR_OBJECT, it.altar) + columnRSCM(RUNE, it.rune.dbId) + + if (it.ruins != null) { + columnRSCM(RUINS, *it.ruins.toTypedArray()) + } + + if (it.exit != null) { + column(EXIT, it.exit) + } + + if (it.exitPortal != null) { + columnRSCM(EXIT_PORTAL, it.exitPortal) + } + + if (it.talisman != null) { + columnRSCM(TALISMAN, it.talisman) + } + + if (it.tiara != null) { + columnRSCM(TIARA_ITEM, it.tiara) + } + + if (it.entrance != null) { + column(ENTRANCE, it.entrance) + } + + if (it.varbit != null) { + columnRSCM(VARBIT, it.varbit) + } + + if (it.combo.isNotEmpty()) { + columnRSCM(COMBO, *it.combo.map { combo -> combo.row }.toTypedArray()) + } + + } + } + + } + +} \ No newline at end of file diff --git a/cache/bin/main/org/alter/impl/skills/runecrafting/CombinationRune.kt b/cache/bin/main/org/alter/impl/skills/runecrafting/CombinationRune.kt new file mode 100644 index 00000000..65b1ac90 --- /dev/null +++ b/cache/bin/main/org/alter/impl/skills/runecrafting/CombinationRune.kt @@ -0,0 +1,58 @@ +package org.alter.impl.skills.runecrafting + +import dev.openrune.definition.dbtables.dbTable +import dev.openrune.definition.util.VarType +import org.alter.impl.skills.runecrafting.RunecraftRune.ESSENCE + +enum class CombinationRuneData(val runeOutput: String, val level: Int, val xp: Double, val runeInput: String, val row : String, val talisman : String) { + MIST_AIR(runeOutput = "items.mistrune", level = 6, xp = 8.0, runeInput = "items.waterrune","dbrows.mist_from_wateraltar","items.water_talisman"), + MIST_WATER(runeOutput = "items.mistrune", level = 6, xp = 8.5, runeInput = "items.airrune","dbrows.mist_from_airaltar","items.air_talisman"), + + DUST_AIR(runeOutput = "items.dustrune", level = 10, xp = 8.3, runeInput = "items.earthrune","dbrows.dust_from_earthaltar","items.earth_talisman"), + DUST_EARTH(runeOutput = "items.dustrune", level = 10, xp = 9.0, runeInput = "items.airrune","dbrows.dust_from_airaltar","items.air_talisman"), + + MUD_WATER(runeOutput = "items.mudrune", level = 13, xp = 9.3, runeInput = "items.earthrune","dbrows.mud_from_earthaltar","items.earth_talisman"), + MUD_EARTH(runeOutput = "items.mudrune", level = 13, xp = 9.5, runeInput = "items.waterrune","dbrows.mud_from_wateraltar","items.water_talisman"), + + SMOKE_AIR(runeOutput = "items.smokerune", level = 15, xp = 8.5, runeInput = "items.firerune","dbrows.smoke_from_firealtar","items.fire_talisman"), + SMOKE_FIRE(runeOutput = "items.smokerune", level = 15, xp = 9.5, runeInput = "items.airrune","dbrows.smoke_from_airaltar","items.air_talisman"), + + STEAM_WATER(runeOutput = "items.steamrune", level = 19, xp = 9.5, runeInput = "items.firerune","dbrows.steam_from_firealtar","items.fire_talisman"), + STEAM_FIRE(runeOutput = "items.steamrune", level = 19, xp = 10.0, runeInput = "items.waterrune","dbrows.steam_from_wateraltar","items.water_talisman"), + + LAVA_EARTH(runeOutput = "items.lavarune", level = 23, xp = 10.0, runeInput = "items.firerune","dbrows.lava_from_firealtar","items.fire_talisman"), + LAVA_FIRE(runeOutput = "items.lavarune", level = 23, xp = 10.5, runeInput = "items.earthrune","dbrows.lava_from_earthaltar","items.earth_talisman"); + +} + +object CombinationRune { + + const val RUNE_OUTPUT = 0 + const val LEVEL = 1 + const val XP = 2 + const val RUNE_INPUT = 3 + const val TALISMAN = 4 + + fun runecraftComboRune() = dbTable("tables.comborune_recipe", serverOnly = true) { + + column("rune_output", RUNE_OUTPUT, VarType.OBJ) + column("level", LEVEL, VarType.INT) + column("xp", XP, VarType.INT) + column("rune_input", RUNE_INPUT, VarType.OBJ) + column("talisman", TALISMAN, VarType.OBJ) + + CombinationRuneData.entries.forEach { + row(it.row) { + columnRSCM(RUNE_OUTPUT, it.runeOutput) + column(LEVEL, it.level) + column(XP, it.xp) + columnRSCM(RUNE_INPUT, it.runeInput) + columnRSCM(TALISMAN, it.talisman) + } + } + + } + + + +} \ No newline at end of file diff --git a/cache/bin/main/org/alter/impl/skills/runecrafting/RunecraftRune.kt b/cache/bin/main/org/alter/impl/skills/runecrafting/RunecraftRune.kt new file mode 100644 index 00000000..afff6099 --- /dev/null +++ b/cache/bin/main/org/alter/impl/skills/runecrafting/RunecraftRune.kt @@ -0,0 +1,167 @@ +package org.alter.impl.skills.runecrafting + +import dev.openrune.definition.dbtables.dbTable +import dev.openrune.definition.util.VarType + +enum class Rune( + val id: String, + val essence: List, + val level: Int, + val xp: Int, + val dbId: String, + val extract: String +) { + AIR( + id = "items.mindrune", + essence = listOf("items.blankrune", "items.blankrune_high"), + level = 1, + xp = 5, + dbId = "dbrows.runecrafting_rune_air", + extract = "items.scar_extract_warped" + ), + MIND( + id = "items.mindrune", + essence = listOf("items.blankrune", "items.blankrune_high"), + level = 2, + xp = 5, + dbId = "dbrows.runecrafting_rune_mind", + extract = "items.scar_extract_warped" + ), + WATER( + id = "items.waterrune", + essence = listOf("items.blankrune", "items.blankrune_high"), + level = 5, + xp = 6, + dbId = "dbrows.runecrafting_rune_water", + extract = "items.scar_extract_warped" + ), + EARTH( + id = "items.earthrune", + essence = listOf("items.blankrune", "items.blankrune_high"), + level = 9, + xp = 6, + dbId = "dbrows.runecrafting_rune_earth", + extract = "items.scar_extract_warped" + ), + FIRE( + id = "items.firerune", + essence = listOf("items.blankrune", "items.blankrune_high"), + level = 14, + xp = 7, + dbId = "dbrows.runecrafting_rune_fire", + extract = "items.scar_extract_warped" + ), + BODY( + id = "items.bodyrune", + essence = listOf("items.blankrune", "items.blankrune_high"), + level = 20, + xp = 7, + dbId = "dbrows.runecrafting_rune_body", + extract = "items.scar_extract_warped" + ), + COSMIC( + id = "items.cosmicrune", + essence = listOf("items.blankrune_high"), + level = 27, + xp = 8, + dbId = "dbrows.runecrafting_rune_cosmic", + extract = "items.scar_extract_twisted" + ), + CHAOS( + id = "items.chaosrune", + essence = listOf("items.blankrune_high"), + level = 35, + xp = 8, + dbId = "dbrows.runecrafting_rune_chaos", + extract = "items.scar_extract_twisted" + ), + ASTRAL( + id = "items.astralrune", + essence = listOf("items.blankrune_high"), + level = 40, + xp = 9, + dbId = "dbrows.runecrafting_rune_astral", + extract = "items.scar_extract_mangled" + ), + NATURE( + id = "items.naturerune", + essence = listOf("items.blankrune_high"), + level = 44, + xp = 9, + dbId = "dbrows.runecrafting_rune_nature", + extract = "items.scar_extract_mangled" + ), + LAW( + id = "items.lawrune", + essence = listOf("items.blankrune_high"), + level = 54, + xp = 9, + dbId = "dbrows.runecrafting_rune_law", + extract = "items.scar_extract_mangled" + ), + DEATH( + id = "items.deathrune", + essence = listOf("items.blankrune_high"), + level = 65, + xp = 10, + dbId = "dbrows.runecrafting_rune_death", + extract = "items.scar_extract_mangled" + ), + BLOOD( + id = "items.bloodrune", + essence = listOf("items.blankrune_high"), + level = 77, + xp = 24, + dbId = "dbrows.runecrafting_rune_blood", + extract = "items.scar_extract_scarred" + ), + SOUL( + id = "items.soulrune", + essence = listOf("items.bigblankrune"), + level = 90, + xp = 30, + dbId = "dbrows.runecrafting_rune_soul", + extract = "items.scar_extract_scarred" + ), + WRATH( + id = "items.wrathrune", + essence = listOf("items.blankrune_high"), + level = 95, + xp = 8, + dbId = "dbrows.runecrafting_rune_wrath", + extract = "items.scar_extract_scarred" + ); + + companion object { + val values = enumValues() + } +} + +object RunecraftRune { + + val ITEM = 0 + val ESSENCE = 1 + val LEVEL = 2 + val XP = 3 + val EXTRACT = 4 + + fun runecraftRune() = dbTable("tables.runecrafting_runes", serverOnly = true) { + column("rune_output", ITEM, VarType.OBJ) + column("valid_essences", ESSENCE, VarType.OBJ) + column("xp", XP, VarType.INT) + column("level", LEVEL, VarType.INT) + column("extract", EXTRACT, VarType.OBJ) + Rune.entries.forEach { + row(it.dbId) { + columnRSCM(ITEM, it.id) + columnRSCM(ESSENCE, *it.essence.toTypedArray()) + column(LEVEL, it.level) + column(XP, it.xp) + columnRSCM(EXTRACT, it.extract) + } + } + + + } + +} \ No newline at end of file diff --git a/cache/bin/main/org/alter/impl/skills/runecrafting/Tiara.kt b/cache/bin/main/org/alter/impl/skills/runecrafting/Tiara.kt new file mode 100644 index 00000000..d6ff4645 --- /dev/null +++ b/cache/bin/main/org/alter/impl/skills/runecrafting/Tiara.kt @@ -0,0 +1,91 @@ +package org.alter.impl.skills.runecrafting + +import dev.openrune.definition.dbtables.dbTable +import dev.openrune.definition.util.VarType + +object Tiara { + + const val ITEM = 0 + const val ALTER = 1 + const val XP = 2 + + fun tiara() = dbTable("tables.runecrafting_tiara", serverOnly = true) { + column("item", ITEM, VarType.OBJ) + column("alter", ALTER, VarType.LOC) + column("xp", XP, VarType.INT) + + row("dbrows.runecrafting_tiara_air") { + columnRSCM(ITEM, "items.tiara_air") + columnRSCM(ALTER, "objects.air_altar") + column(XP, 25) + } + + row("dbrows.runecrafting_tiara_mind") { + columnRSCM(ITEM, "items.tiara_mind") + columnRSCM(ALTER, "objects.mind_altar") + column(XP, 27) + } + + row("dbrows.runecrafting_tiara_water") { + columnRSCM(ITEM, "items.tiara_water") + columnRSCM(ALTER, "objects.water_altar") + column(XP, 30) + } + + row("dbrows.runecrafting_tiara_earth") { + columnRSCM(ITEM, "items.tiara_earth") + columnRSCM(ALTER, "objects.earth_altar") + column(XP, 32) + } + + row("dbrows.runecrafting_tiara_fire") { + columnRSCM(ITEM, "items.tiara_fire") + columnRSCM(ALTER, "objects.fire_altar") + column(XP, 35) + } + + row("dbrows.runecrafting_tiara_body") { + columnRSCM(ITEM, "items.tiara_body") + columnRSCM(ALTER, "objects.body_altar") + column(XP, 37) + } + + row("dbrows.runecrafting_tiara_cosmic") { + columnRSCM(ITEM, "items.tiara_cosmic") + columnRSCM(ALTER, "objects.cosmic_altar") + column(XP, 40) + } + + row("dbrows.runecrafting_tiara_chaos") { + columnRSCM(ITEM, "items.tiara_chaos") + columnRSCM(ALTER, "objects.chaos_altar") + column(XP, 42) + } + + row("dbrows.runecrafting_tiara_nature") { + columnRSCM(ITEM, "items.tiara_nature") + columnRSCM(ALTER, "objects.nature_altar") + column(XP, 45) + } + + row("dbrows.runecrafting_tiara_law") { + columnRSCM(ITEM, "items.tiara_law") + columnRSCM(ALTER, "objects.law_altar") + column(XP, 47) + } + + row("dbrows.runecrafting_tiara_death") { + columnRSCM(ITEM, "items.tiara_death") + columnRSCM(ALTER, "objects.death_altar") + column(XP, 50) + } + + row("dbrows.runecrafting_tiara_wrath") { + columnRSCM(ITEM, "items.tiara_wrath") + columnRSCM(ALTER, "objects.wrath_altar") + column(XP, 52) + } + + } + +} \ No newline at end of file diff --git a/cache/bin/main/org/alter/rscm/RSCM.kt b/cache/bin/main/org/alter/rscm/RSCM.kt new file mode 100644 index 00000000..8a3b8123 --- /dev/null +++ b/cache/bin/main/org/alter/rscm/RSCM.kt @@ -0,0 +1,62 @@ +package org.alter.rscm + +import dev.openrune.definition.constants.ConstantProvider +import io.github.oshai.kotlinlogging.KotlinLogging +import org.alter.rscm.RSCMType.Companion.RSCM_PREFIXES +import kotlin.system.exitProcess + +enum class RSCMType(val prefix: String) { + OBJTYPES("items"), + NPCTYPES("npcs"), + INVTYPES("inv"), + VARPTYPES("varp"), + VARBITTYPES("varbits"), + LOCTYPES("objects"), + SEQTYPES("sequences"), + SPOTTYPES("spotanims"), + ROWTYPES("dbrows"), + JINGLES("jingles"), + TABLETYPES("tables"), + COMPONENTS("components"), + ENUMS("enums"), + COLUMNS("columns"), + FONTS("fonts"), + INTERFACES("interfaces"); + + companion object { + val RSCM_PREFIXES = RSCMType.entries.map { it.prefix }.toSet() + } + +} + +object RSCM { + + val logger = KotlinLogging.logger {} + + val NONE = "NONE" + + fun getRSCM(entity: Array): List = entity.map { getRSCM(it) } + + fun String.asRSCM(): Int = getRSCM(this) + + fun requireRSCM(type: RSCMType, vararg entities: String) { + for (entity in entities) { + if (!entity.startsWith(type.prefix) && entity != NONE) { + error("Invalid RSCM key. Expected prefix '${type.prefix}', got '${entity.substringBefore(".")}'") + } + } + } + + fun getReverseMapping(table: RSCMType, value: Int): String { + if (value == -1) { + return "-1" + } + return ConstantProvider.getReverseMapping(table.prefix,value) + } + + fun getRSCM(entity: String): Int { + if (entity == NONE) return -1 + require(RSCM_PREFIXES.any { entity.startsWith(it) }) { "Prefix not found for '${entity.substringBefore(".")}'" } + return ConstantProvider.getMapping(entity) + } +} \ No newline at end of file diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/BreadRecipes.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/BreadRecipes.kt index e863ed90..9b75e9b7 100644 --- a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/BreadRecipes.kt +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/BreadRecipes.kt @@ -23,7 +23,7 @@ object BreadRecipes { ), heatCook( rowKey = "cooking_pitta_bread", - raw = "items.pitta_dough", + raw = "items.uncooked_pitta_bread", cooked = "items.pitta_bread", burnt = "items.burnt_pitta_bread", level = 58, diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/FishRecipes.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/FishRecipes.kt index 807d4af1..4930362c 100644 --- a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/FishRecipes.kt +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/FishRecipes.kt @@ -224,7 +224,7 @@ object FishRecipes { rowKey = "cooking_rainbow_fish", raw = "items.hunting_raw_fish_special", cooked = "items.hunting_fish_special", - burnt = "items.burnt_rainbow_fish", + burnt = "items.burntfish2", level = 35, xp = 110, stopBurnFire = 64, diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/MiscFoodRecipes.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/MiscFoodRecipes.kt index e128221d..7e2359e7 100644 --- a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/MiscFoodRecipes.kt +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/MiscFoodRecipes.kt @@ -14,9 +14,9 @@ object MiscFoodRecipes { val sweetcorn: List = listOf( heatCook( rowKey = "cooking_sweetcorn", - raw = "items.sweetcorn_raw", + raw = "items.sweetcorn", cooked = "items.sweetcorn_cooked", - burnt = "items.burnt_sweetcorn", + burnt = "items.sweetcorn_burnt", level = 28, xp = 104, stopBurnFire = 61, @@ -35,15 +35,15 @@ object MiscFoodRecipes { "items.egg" to 1, "items.bowl_empty" to 1 ), - output = "items.bowl_egg_uncooked" + output = "items.bowl_egg_raw" ) ) ) + listOf( heatCook( rowKey = "cooking_scrambled_egg_cook", - raw = "items.bowl_egg_uncooked", + raw = "items.bowl_egg_raw", cooked = "items.bowl_egg_scrambled", - burnt = "items.burnt_egg", + burnt = "items.bowl_egg_burnt", level = 13, xp = 50, stopBurnFire = 46, @@ -55,9 +55,9 @@ object MiscFoodRecipes { val friedOnions: List = listOf( heatCook( rowKey = "cooking_fried_onions", - raw = "items.bowl_onion_chopped", + raw = "items.bowl_onion", cooked = "items.bowl_onion_fried", - burnt = "items.burnt_onion", + burnt = "items.bowl_onion_burnt", level = 42, xp = 60, stopBurnFire = 74, @@ -69,9 +69,9 @@ object MiscFoodRecipes { val friedMushrooms: List = listOf( heatCook( rowKey = "cooking_fried_mushrooms", - raw = "items.bowl_mushroom_sliced", + raw = "items.bowl_mushroom_raw", cooked = "items.bowl_mushroom_fried", - burnt = "items.burnt_mushroom", + burnt = "items.bowl_mushroom_burnt", level = 46, xp = 60, stopBurnFire = 80, @@ -81,7 +81,7 @@ object MiscFoodRecipes { /** Mushroom & onion: fried mushrooms + fried onions. */ val mushroomAndOnion: List = multiStepCook( - key = "items.bowl_mushroom_onion", + key = "items.bowl_mushroom+onion", level = 57, prepSteps = listOf( PrepStepDef( @@ -90,7 +90,7 @@ object MiscFoodRecipes { "items.bowl_mushroom_fried" to 1, "items.bowl_onion_fried" to 1 ), - output = "items.bowl_mushroom_onion", + output = "items.bowl_mushroom+onion", always = listOf("items.bowl_empty" to 1) ) ) @@ -98,7 +98,7 @@ object MiscFoodRecipes { /** Tuna and corn: cooked tuna + cooked sweetcorn + bowl. */ val tunaAndCorn: List = multiStepCook( - key = "items.bowl_tuna_corn", + key = "items.bowl_tuna+sweetcorn", level = 67, prepSteps = listOf( PrepStepDef( @@ -108,7 +108,7 @@ object MiscFoodRecipes { "items.sweetcorn_cooked" to 1, "items.bowl_empty" to 1 ), - output = "items.bowl_tuna_corn" + output = "items.bowl_tuna+sweetcorn" ) ) ) diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PieRecipes.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PieRecipes.kt index 29ccedb3..dfcf0ddf 100644 --- a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PieRecipes.kt +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PieRecipes.kt @@ -69,38 +69,38 @@ object PieRecipes { /** Mud pie (level 29). */ val mudPie: List = multiStepCook( - key = "items.raw_mud_pie", + key = "items.uncooked_mud_pie", level = 29, prepSteps = listOf( PrepStepDef( rowKey = "cooking_mud_pie_add_compost", inputs = listOf( "items.pie_shell" to 1, - "items.compost" to 1 + "items.bucket_compost" to 1 ), - output = "items.part_mud_pie_1" + output = "items.unfinished_mud_pie_1" ), PrepStepDef( rowKey = "cooking_mud_pie_add_water", inputs = listOf( - "items.part_mud_pie_1" to 1, + "items.unfinished_mud_pie_1" to 1, "items.bucket_water" to 1 ), - output = "items.part_mud_pie_2", + output = "items.unfinished_mud_pie_2", always = listOf("items.bucket_empty" to 1) ), PrepStepDef( rowKey = "cooking_mud_pie_add_clay", inputs = listOf( - "items.part_mud_pie_2" to 1, + "items.unfinished_mud_pie_2" to 1, "items.clay" to 1 ), - output = "items.raw_mud_pie" + output = "items.uncooked_mud_pie" ) ), heatStep = HeatStepDef( rowKey = "cooking_mud_pie_bake", - raw = "items.raw_mud_pie", + raw = "items.uncooked_mud_pie", cooked = "items.mud_pie", burnt = "items.burnt_pie", xp = 128, @@ -138,7 +138,7 @@ object PieRecipes { /** Fish pie (level 47). */ val fishPie: List = multiStepCook( - key = "items.raw_fish_pie", + key = "items.uncooked_fish_pie", level = 47, prepSteps = listOf( PrepStepDef( @@ -147,28 +147,28 @@ object PieRecipes { "items.pie_shell" to 1, "items.trout" to 1 ), - output = "items.part_fish_pie_1" + output = "items.unfinished_fish_pie_1" ), PrepStepDef( rowKey = "cooking_fish_pie_add_cod", inputs = listOf( - "items.part_fish_pie_1" to 1, + "items.unfinished_fish_pie_1" to 1, "items.cod" to 1 ), - output = "items.part_fish_pie_2" + output = "items.unfinished_fish_pie_2" ), PrepStepDef( rowKey = "cooking_fish_pie_add_potato", inputs = listOf( - "items.part_fish_pie_2" to 1, + "items.unfinished_fish_pie_2" to 1, "items.potato" to 1 ), - output = "items.raw_fish_pie" + output = "items.uncooked_fish_pie" ) ), heatStep = HeatStepDef( rowKey = "cooking_fish_pie_bake", - raw = "items.raw_fish_pie", + raw = "items.uncooked_fish_pie", cooked = "items.fish_pie", burnt = "items.burnt_pie", xp = 164, @@ -187,7 +187,7 @@ object PieRecipes { rowKey = "cooking_botanical_pie_add_golovanova", inputs = listOf( "items.pie_shell" to 1, - "items.golovanova_fruit_top" to 1 + "items.golovanova_top" to 1 ), output = "items.uncooked_botanical_pie" ) @@ -206,21 +206,21 @@ object PieRecipes { /** Mushroom pie (level 60). */ val mushroomPie: List = multiStepCook( - key = "items.raw_mushroom_pie", + key = "items.uncooked_mushroom_pie", level = 60, prepSteps = listOf( PrepStepDef( rowKey = "cooking_mushroom_pie_add_sulliuscep", inputs = listOf( "items.pie_shell" to 1, - "items.sulliuscep_cap" to 1 + "items.fossil_sulliuscep_cap" to 1 ), - output = "items.raw_mushroom_pie" + output = "items.uncooked_mushroom_pie" ) ), heatStep = HeatStepDef( rowKey = "cooking_mushroom_pie_bake", - raw = "items.raw_mushroom_pie", + raw = "items.uncooked_mushroom_pie", cooked = "items.mushroom_pie", burnt = "items.burnt_pie", xp = 200, @@ -232,7 +232,7 @@ object PieRecipes { /** Admiral pie (level 70). */ val admiralPie: List = multiStepCook( - key = "items.raw_admiral_pie", + key = "items.uncooked_admiral_pie", level = 70, prepSteps = listOf( PrepStepDef( @@ -241,28 +241,28 @@ object PieRecipes { "items.pie_shell" to 1, "items.salmon" to 1 ), - output = "items.part_admiral_pie_1" + output = "items.unfinished_admiral_pie_1" ), PrepStepDef( rowKey = "cooking_admiral_pie_add_tuna", inputs = listOf( - "items.part_admiral_pie_1" to 1, + "items.unfinished_admiral_pie_1" to 1, "items.tuna" to 1 ), - output = "items.part_admiral_pie_2" + output = "items.unfinished_admiral_pie_2" ), PrepStepDef( rowKey = "cooking_admiral_pie_add_potato", inputs = listOf( - "items.part_admiral_pie_2" to 1, + "items.unfinished_admiral_pie_2" to 1, "items.potato" to 1 ), - output = "items.raw_admiral_pie" + output = "items.uncooked_admiral_pie" ) ), heatStep = HeatStepDef( rowKey = "cooking_admiral_pie_bake", - raw = "items.raw_admiral_pie", + raw = "items.uncooked_admiral_pie", cooked = "items.admiral_pie", burnt = "items.burnt_pie", xp = 210, @@ -300,7 +300,7 @@ object PieRecipes { /** Wild pie (level 85). */ val wildPie: List = multiStepCook( - key = "items.raw_wild_pie", + key = "items.uncooked_wild_pie", level = 85, prepSteps = listOf( PrepStepDef( @@ -309,28 +309,28 @@ object PieRecipes { "items.pie_shell" to 1, "items.raw_bear_meat" to 1 ), - output = "items.part_wild_pie_1" + output = "items.unfinished_wild_pie_1" ), PrepStepDef( rowKey = "cooking_wild_pie_add_chompy", inputs = listOf( - "items.part_wild_pie_1" to 1, + "items.unfinished_wild_pie_1" to 1, "items.raw_chompy" to 1 ), - output = "items.part_wild_pie_2" + output = "items.unfinished_wild_pie_2" ), PrepStepDef( rowKey = "cooking_wild_pie_add_rabbit", inputs = listOf( - "items.part_wild_pie_2" to 1, + "items.unfinished_wild_pie_2" to 1, "items.raw_rabbit" to 1 ), - output = "items.raw_wild_pie" + output = "items.uncooked_wild_pie" ) ), heatStep = HeatStepDef( rowKey = "cooking_wild_pie_bake", - raw = "items.raw_wild_pie", + raw = "items.uncooked_wild_pie", cooked = "items.wild_pie", burnt = "items.burnt_pie", xp = 240, @@ -342,7 +342,7 @@ object PieRecipes { /** Summer pie (level 95). */ val summerPie: List = multiStepCook( - key = "items.raw_summer_pie", + key = "items.uncooked_summer_pie", level = 95, prepSteps = listOf( PrepStepDef( @@ -351,28 +351,28 @@ object PieRecipes { "items.pie_shell" to 1, "items.watermelon" to 1 ), - output = "items.part_summer_pie_1" + output = "items.unfinished_summer_pie_1" ), PrepStepDef( rowKey = "cooking_summer_pie_add_apple", inputs = listOf( - "items.part_summer_pie_1" to 1, + "items.unfinished_summer_pie_1" to 1, "items.cooking_apple" to 1 ), - output = "items.part_summer_pie_2" + output = "items.unfinished_summer_pie_2" ), PrepStepDef( rowKey = "cooking_summer_pie_add_strawberry", inputs = listOf( - "items.part_summer_pie_2" to 1, + "items.unfinished_summer_pie_2" to 1, "items.strawberry" to 1 ), - output = "items.raw_summer_pie" + output = "items.uncooked_summer_pie" ) ), heatStep = HeatStepDef( rowKey = "cooking_summer_pie_bake", - raw = "items.raw_summer_pie", + raw = "items.uncooked_summer_pie", cooked = "items.summer_pie", burnt = "items.burnt_pie", xp = 260, diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PizzaRecipes.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PizzaRecipes.kt index 445863d5..6977ce15 100644 --- a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PizzaRecipes.kt +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PizzaRecipes.kt @@ -66,7 +66,7 @@ object PizzaRecipes { /** Anchovy pizza topping: plain pizza + anchovies. */ val anchovyPizzaRecipes: List = multiStepCook( - key = "items.anchovy_pizza", + key = "items.anchovie_pizza", level = 55, prepSteps = listOf( PrepStepDef( @@ -75,7 +75,7 @@ object PizzaRecipes { "items.plain_pizza" to 1, "items.anchovies" to 1 ), - output = "items.anchovy_pizza", + output = "items.anchovie_pizza", xp = 39 ) ) diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PotatoRecipes.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PotatoRecipes.kt index 75fe0d8a..0898a906 100644 --- a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PotatoRecipes.kt +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PotatoRecipes.kt @@ -18,7 +18,7 @@ object PotatoRecipes { rowKey = "cooking_baked_potato", raw = "items.potato", cooked = "items.potato_baked", - burnt = "items.burnt_potato", + burnt = "items.potato_burnt", level = 7, xp = 15, stopBurnFire = 40, @@ -36,7 +36,7 @@ object PotatoRecipes { rowKey = "cooking_potato_add_butter", inputs = listOf( "items.potato_baked" to 1, - "items.pat_of_butter" to 1 + "items.pot_of_butter" to 1 ), output = "items.potato_butter" ) @@ -61,7 +61,7 @@ object PotatoRecipes { /** Egg potato: potato with butter + scrambled egg. */ val eggPotato: List = multiStepCook( - key = "items.egg_potato", + key = "items.potato_egg+tomato", level = 51, prepSteps = listOf( PrepStepDef( @@ -70,7 +70,7 @@ object PotatoRecipes { "items.potato_butter" to 1, "items.bowl_egg_scrambled" to 1 ), - output = "items.egg_potato", + output = "items.potato_egg+tomato", always = listOf("items.bowl_empty" to 1) ) ) @@ -78,16 +78,16 @@ object PotatoRecipes { /** Mushroom potato: potato with butter + mushroom & onion. */ val mushroomPotato: List = multiStepCook( - key = "items.mushroom_potato", + key = "items.potato_mushroom+onion", level = 64, prepSteps = listOf( PrepStepDef( rowKey = "cooking_potato_add_mushroom_onion", inputs = listOf( "items.potato_butter" to 1, - "items.bowl_mushroom_onion" to 1 + "items.bowl_mushroom+onion" to 1 ), - output = "items.mushroom_potato", + output = "items.potato_mushroom+onion", always = listOf("items.bowl_empty" to 1) ) ) @@ -95,16 +95,16 @@ object PotatoRecipes { /** Tuna potato: potato with butter + tuna and corn. */ val tunaPotato: List = multiStepCook( - key = "items.tuna_potato", + key = "items.potato_tuna+sweetcorn", level = 68, prepSteps = listOf( PrepStepDef( rowKey = "cooking_potato_add_tuna_corn", inputs = listOf( "items.potato_butter" to 1, - "items.bowl_tuna_corn" to 1 + "items.bowl_tuna+sweetcorn" to 1 ), - output = "items.tuna_potato", + output = "items.potato_tuna+sweetcorn", always = listOf("items.bowl_empty" to 1) ) ) diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/StewRecipes.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/StewRecipes.kt index b1b7cabc..fcc11eb7 100644 --- a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/StewRecipes.kt +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/StewRecipes.kt @@ -21,12 +21,12 @@ object StewRecipes { "items.bowl_water" to 1, "items.potato" to 1 ), - output = "items.incomplete_stew" + output = "items.stew1" ), PrepStepDef( rowKey = "cooking_stew_add_meat", inputs = listOf( - "items.incomplete_stew" to 1, + "items.stew1" to 1, "items.cooked_meat" to 1 ), output = "items.uncooked_stew" @@ -54,12 +54,12 @@ object StewRecipes { "items.bowl_water" to 1, "items.potato" to 1 ), - output = "items.incomplete_stew" + output = "items.stew1" ), PrepStepDef( rowKey = "cooking_curry_add_meat", inputs = listOf( - "items.incomplete_stew" to 1, + "items.stew1" to 1, "items.cooked_meat" to 1 ), output = "items.uncooked_stew" @@ -68,7 +68,7 @@ object StewRecipes { rowKey = "cooking_curry_add_spice", inputs = listOf( "items.uncooked_stew" to 1, - "items.spice" to 1 + "items.spicespot" to 1 ), output = "items.uncooked_curry" ) diff --git a/content/src/main/kotlin/org/alter/commands/developer/CookingTestCommandsPlugin.kt b/content/src/main/kotlin/org/alter/commands/developer/CookingTestCommandsPlugin.kt index 16947639..de2c8216 100644 --- a/content/src/main/kotlin/org/alter/commands/developer/CookingTestCommandsPlugin.kt +++ b/content/src/main/kotlin/org/alter/commands/developer/CookingTestCommandsPlugin.kt @@ -16,23 +16,27 @@ class CookingTestCommandsPlugin : PluginEvent() { val level: Int, val qty: Int, ) { - LOW("low", level = 1, qty = 5), - MID("mid", level = 25, qty = 5), - HIGH("high", level = 80, qty = 3), - FISH("fish", level = 99, qty = 5), - PREP_FISH("prepfish", level = 99, qty = 5), - MEAT("meat", level = 1, qty = 10), - PIES("pies", level = 95, qty = 5), - CAKES("cakes", level = 50, qty = 5), - PIZZA("pizza", level = 65, qty = 5), - STEW("stew", level = 60, qty = 5), - BREAD("bread", level = 58, qty = 5), - POTATO("potato", level = 68, qty = 5), - WINE("wine", level = 35, qty = 5), - MISC("misc", level = 67, qty = 5), - SNAILS("snails", level = 22, qty = 5), - HUNTER("hunter", level = 92, qty = 3), - ALL("all", level = 99, qty = 1); + LOW("low", level = 1, qty = 5), // 4 items × 5 = 20 slots + MID("mid", level = 25, qty = 5), // 3 items × 5 = 15 slots + HIGH("high", level = 80, qty = 3), // 3 items × 3 = 9 slots + FISH_LOW("fishlow", level = 15, qty = 4), // 6 items × 4 = 24 slots + FISH_MID("fishmid", level = 50, qty = 5), // 5 items × 5 = 25 slots + FISH_HIGH("fishhigh", level = 99, qty = 3), // 8 items × 3 = 24 slots + FISH_SPECIAL("fishspec", level = 70, qty = 5), // 4 items × 5 = 20 slots + PREP_FISH("prepfish", level = 99, qty = 5), // 5 items × 5 = 25 slots + MEAT("meat", level = 1, qty = 3), // 7 items × 3 = 21 slots + SPIT("spit", level = 1, qty = 3), // 6 items × 3 = 18 slots + PIES_INGR("piesingr", level = 30, qty = 3), // 7 items × 3 = 21 slots + PIES_BAKE("piesbake", level = 95, qty = 5), // 4 items × 5 = 20 slots + CAKES("cakes", level = 50, qty = 3), // 7 items × 3 = 21 slots + PIZZA("pizza", level = 65, qty = 3), // 8 items × 3 = 24 slots + STEW("stew", level = 60, qty = 5), // 5 items × 5 = 25 slots + BREAD("bread", level = 58, qty = 5), // 2 items × 5 = 10 slots + POTATO("potato", level = 68, qty = 3), // 8 items × 3 = 24 slots + WINE("wine", level = 35, qty = 5), // 2 items × 5 = 10 slots + MISC("misc", level = 67, qty = 3), // 7 items × 3 = 21 slots + SNAILS("snails", level = 22, qty = 5), // 3 items × 5 = 15 slots + HUNTER("hunter", level = 92, qty = 3); // 6 items × 3 = 18 slots companion object { fun fromKey(raw: String): CookTestSet? { @@ -117,22 +121,24 @@ class CookingTestCommandsPlugin : PluginEvent() { "items.raw_shark" ) - CookTestSet.FISH -> listOf( + CookTestSet.FISH_LOW -> listOf( "items.raw_shrimp", "items.raw_anchovies", "items.raw_sardine", "items.raw_herring", "items.raw_mackerel", - "items.raw_trout", + "items.raw_trout" + ) + + CookTestSet.FISH_MID -> listOf( "items.raw_cod", "items.raw_pike", "items.raw_salmon", "items.raw_tuna", - "items.hunting_raw_fish_special", - "items.mort_slimey_eel", - "items.raw_cave_eel", - "items.tbwt_raw_karambwan", - "items.raw_lobster", + "items.raw_lobster" + ) + + CookTestSet.FISH_HIGH -> listOf( "items.raw_bass", "items.raw_swordfish", "items.raw_monkfish", @@ -140,11 +146,14 @@ class CookingTestCommandsPlugin : PluginEvent() { "items.raw_seaturtle", "items.raw_anglerfish", "items.raw_dark_crab", - "items.raw_mantaray", - // Snails - "items.snail_corpse1", - "items.snail_corpse2", - "items.snail_corpse3" + "items.raw_mantaray" + ) + + CookTestSet.FISH_SPECIAL -> listOf( + "items.hunting_raw_fish_special", + "items.mort_slimey_eel", + "items.raw_cave_eel", + "items.tbwt_raw_karambwan" ) CookTestSet.PREP_FISH -> listOf( @@ -158,36 +167,33 @@ class CookingTestCommandsPlugin : PluginEvent() { CookTestSet.MEAT -> listOf( "items.raw_beef", "items.raw_chicken", - // Extra meats (some may not exist in all caches; missing keys are skipped safely). "items.raw_rat_meat", "items.raw_bear_meat", "items.raw_rabbit", "items.raw_ugthanki_meat", - "items.raw_chompy", - // Spit roasting requires an iron spit + skewering first. + "items.raw_chompy" + ) + + CookTestSet.SPIT -> listOf( "items.spit_iron", "items.spit_raw_bird_meat", "items.spit_raw_beast_meat", - // Optional direct roast testing (post-skewer intermediates) "items.spit_skewered_bird_meat", "items.spit_skewered_beast_meat", "items.spit_skewered_rabbit_meat" ) - CookTestSet.PIES -> listOf( - // Pie shell for assembly + CookTestSet.PIES_INGR -> listOf( "items.pie_shell", - // Garden pie ingredients "items.tomato", "items.onion", "items.cabbage", - // Redberry pie "items.redberries", - // Meat pie "items.cooked_meat", - // Apple pie - "items.cooking_apple", - // Direct bake tests + "items.cooking_apple" + ) + + CookTestSet.PIES_BAKE -> listOf( "items.uncooked_garden_pie", "items.uncooked_redberry_pie", "items.uncooked_meat_pie", @@ -195,30 +201,23 @@ class CookingTestCommandsPlugin : PluginEvent() { ) CookTestSet.CAKES -> listOf( - // Cake (mix + bake) "items.cake_tin", "items.egg", "items.bucket_milk", "items.pot_flour", - // Optional direct bake test "items.uncooked_cake", - // Chocolate cake "items.cake", "items.chocolate_bar" ) CookTestSet.PIZZA -> listOf( - // Pizza base ingredients "items.pizza_base", "items.tomato", "items.cheese", - // Toppings "items.cooked_meat", "items.anchovies", "items.pineapple_ring", - // Direct bake test "items.uncooked_pizza", - // Already baked for topping tests "items.plain_pizza" ) @@ -227,7 +226,6 @@ class CookingTestCommandsPlugin : PluginEvent() { "items.potato", "items.cooked_meat", "items.spice", - // Direct cook test "items.uncooked_stew" ) @@ -276,17 +274,24 @@ class CookingTestCommandsPlugin : PluginEvent() { "items.hunting_antelopesun_meat", "items.hunting_antelopemoon_meat" ) - - CookTestSet.ALL -> keysFor(CookTestSet.FISH) + keysFor(CookTestSet.PREP_FISH) + - keysFor(CookTestSet.MEAT) + keysFor(CookTestSet.PIES) + keysFor(CookTestSet.CAKES) + - keysFor(CookTestSet.PIZZA) + keysFor(CookTestSet.STEW) + keysFor(CookTestSet.BREAD) + - keysFor(CookTestSet.POTATO) + keysFor(CookTestSet.WINE) + keysFor(CookTestSet.MISC) + - keysFor(CookTestSet.SNAILS) + keysFor(CookTestSet.HUNTER) } private fun sendCookTestHelp(player: org.alter.game.model.entity.Player) { player.message("Usage: ::cooktest ") player.message("Presets: ${CookTestSet.entries.joinToString(", ") { it.key }}") - player.message("Examples: ${CookTestSet.entries.joinToString(" | ") { "::cooktest ${it.key}" }}") + val examples = CookTestSet.entries.map { "::cooktest ${it.key}" } + val lines = mutableListOf() + var current = "Examples: " + for ((i, ex) in examples.withIndex()) { + val separator = if (i == 0) "" else " | " + if (current.length + separator.length + ex.length > 250) { + lines.add(current) + current = ex + } else { + current += separator + ex + } + } + if (current.isNotEmpty()) lines.add(current) + lines.forEach { player.message(it) } } } diff --git a/content/src/main/kotlin/org/alter/skills/cooking/events/CookingEvents.kt b/content/src/main/kotlin/org/alter/skills/cooking/events/CookingEvents.kt index 501d788e..28e066ec 100644 --- a/content/src/main/kotlin/org/alter/skills/cooking/events/CookingEvents.kt +++ b/content/src/main/kotlin/org/alter/skills/cooking/events/CookingEvents.kt @@ -267,9 +267,7 @@ class CookingEvents : PluginEvent() { player.filterableMessage("You begin cooking...") repeatWhile(delay = 4, immediate = true, canRepeat = { - cooked < quantity && - hasInputs(player, action) && - isStillAtStation(player, objectTile, objectId) + cooked < quantity && hasInputs(player, action) && isStillAtStation(player, objectTile, objectId) }) { runCatching { player.animate("sequences.human_cooking", interruptable = true) } .onFailure { player.animate(RSCM.NONE) } diff --git a/content/src/main/kotlin/org/alter/skills/cooking/events/CookingUtils.kt b/content/src/main/kotlin/org/alter/skills/cooking/events/CookingUtils.kt index b182a3c6..217f060b 100644 --- a/content/src/main/kotlin/org/alter/skills/cooking/events/CookingUtils.kt +++ b/content/src/main/kotlin/org/alter/skills/cooking/events/CookingUtils.kt @@ -87,15 +87,17 @@ object CookingUtils { /** Checks whether the player is wearing cooking gauntlets. */ fun hasCookingGauntlets(player: Player): Boolean = - player.hasEquipped(EquipmentType.GLOVES, "items.cooking_gauntlets") + runCatching { player.hasEquipped(EquipmentType.GLOVES, "items.gauntlets_of_cooking") }.getOrDefault(false) /** Checks whether the player is wearing the cooking cape (or max cape). */ fun hasCookingCape(player: Player): Boolean = - player.equipment.containsAny( - "items.skillcape_cooking", - "items.skillcape_cooking_trimmed", - "items.skillcape_max" - ) + runCatching { + player.equipment.containsAny( + "items.skillcape_cooking", + "items.skillcape_cooking_trimmed", + "items.skillcape_max" + ) + }.getOrDefault(false) /** * Determines the cooking station type for a given game object, or null if it is not a heat source. diff --git a/content/src/main/resources/org/alter/skills/cooking/gamevals.toml b/content/src/main/resources/org/alter/skills/cooking/gamevals.toml index 8a18fecb..f8b01d64 100644 --- a/content/src/main/resources/org/alter/skills/cooking/gamevals.toml +++ b/content/src/main/resources/org/alter/skills/cooking/gamevals.toml @@ -205,365 +205,365 @@ cooking_cake_mix_outcome_always_1=982125 cooking_cake_bake_outcome_always_0=982126 # --- Skewer (spit-roast prep) entries --- -cooking_skewer_bird_meat=-1 -cooking_skewer_beast_meat=-1 -cooking_skewer_bird_meat_input_0=-1 -cooking_skewer_bird_meat_input_1=-1 -cooking_skewer_beast_meat_input_0=-1 -cooking_skewer_beast_meat_input_1=-1 -cooking_skewer_bird_meat_outcome_success=-1 -cooking_skewer_beast_meat_outcome_success=-1 +cooking_skewer_bird_meat=982193 +cooking_skewer_beast_meat=982194 +cooking_skewer_bird_meat_input_0=982195 +cooking_skewer_bird_meat_input_1=982196 +cooking_skewer_beast_meat_input_0=982197 +cooking_skewer_beast_meat_input_1=982198 +cooking_skewer_bird_meat_outcome_success=982199 +cooking_skewer_beast_meat_outcome_success=982200 # --- Bread --- -cooking_bread=-1 -cooking_pitta_bread=-1 +cooking_bread=982201 +cooking_pitta_bread=982202 -cooking_bread_input_0=-1 -cooking_pitta_bread_input_0=-1 +cooking_bread_input_0=982203 +cooking_pitta_bread_input_0=982204 -cooking_bread_outcome_success=-1 -cooking_bread_outcome_fail=-1 -cooking_pitta_bread_outcome_success=-1 -cooking_pitta_bread_outcome_fail=-1 +cooking_bread_outcome_success=982205 +cooking_bread_outcome_fail=982206 +cooking_pitta_bread_outcome_success=982207 +cooking_pitta_bread_outcome_fail=982208 # --- Pies --- -cooking_redberry_pie_add_berries=-1 -cooking_redberry_pie_bake=-1 -cooking_redberry_pie_add_berries_input_0=-1 -cooking_redberry_pie_add_berries_input_1=-1 -cooking_redberry_pie_bake_input_0=-1 -cooking_redberry_pie_add_berries_outcome_success=-1 -cooking_redberry_pie_bake_outcome_success=-1 -cooking_redberry_pie_bake_outcome_fail=-1 - -cooking_meat_pie_add_meat=-1 -cooking_meat_pie_bake=-1 -cooking_meat_pie_add_meat_input_0=-1 -cooking_meat_pie_add_meat_input_1=-1 -cooking_meat_pie_bake_input_0=-1 -cooking_meat_pie_add_meat_outcome_success=-1 -cooking_meat_pie_bake_outcome_success=-1 -cooking_meat_pie_bake_outcome_fail=-1 - -cooking_mud_pie_add_compost=-1 -cooking_mud_pie_add_water=-1 -cooking_mud_pie_add_clay=-1 -cooking_mud_pie_bake=-1 -cooking_mud_pie_add_compost_input_0=-1 -cooking_mud_pie_add_compost_input_1=-1 -cooking_mud_pie_add_water_input_0=-1 -cooking_mud_pie_add_water_input_1=-1 -cooking_mud_pie_add_clay_input_0=-1 -cooking_mud_pie_add_clay_input_1=-1 -cooking_mud_pie_bake_input_0=-1 -cooking_mud_pie_add_compost_outcome_success=-1 -cooking_mud_pie_add_water_outcome_success=-1 -cooking_mud_pie_add_water_outcome_always_0=-1 -cooking_mud_pie_add_clay_outcome_success=-1 -cooking_mud_pie_bake_outcome_success=-1 -cooking_mud_pie_bake_outcome_fail=-1 - -cooking_apple_pie_add_apple=-1 -cooking_apple_pie_bake=-1 -cooking_apple_pie_add_apple_input_0=-1 -cooking_apple_pie_add_apple_input_1=-1 -cooking_apple_pie_bake_input_0=-1 -cooking_apple_pie_add_apple_outcome_success=-1 -cooking_apple_pie_bake_outcome_success=-1 -cooking_apple_pie_bake_outcome_fail=-1 - -cooking_fish_pie_add_trout=-1 -cooking_fish_pie_add_cod=-1 -cooking_fish_pie_add_potato=-1 -cooking_fish_pie_bake=-1 -cooking_fish_pie_add_trout_input_0=-1 -cooking_fish_pie_add_trout_input_1=-1 -cooking_fish_pie_add_cod_input_0=-1 -cooking_fish_pie_add_cod_input_1=-1 -cooking_fish_pie_add_potato_input_0=-1 -cooking_fish_pie_add_potato_input_1=-1 -cooking_fish_pie_bake_input_0=-1 -cooking_fish_pie_add_trout_outcome_success=-1 -cooking_fish_pie_add_cod_outcome_success=-1 -cooking_fish_pie_add_potato_outcome_success=-1 -cooking_fish_pie_bake_outcome_success=-1 -cooking_fish_pie_bake_outcome_fail=-1 - -cooking_botanical_pie_add_golovanova=-1 -cooking_botanical_pie_bake=-1 -cooking_botanical_pie_add_golovanova_input_0=-1 -cooking_botanical_pie_add_golovanova_input_1=-1 -cooking_botanical_pie_bake_input_0=-1 -cooking_botanical_pie_add_golovanova_outcome_success=-1 -cooking_botanical_pie_bake_outcome_success=-1 -cooking_botanical_pie_bake_outcome_fail=-1 - -cooking_mushroom_pie_add_sulliuscep=-1 -cooking_mushroom_pie_bake=-1 -cooking_mushroom_pie_add_sulliuscep_input_0=-1 -cooking_mushroom_pie_add_sulliuscep_input_1=-1 -cooking_mushroom_pie_bake_input_0=-1 -cooking_mushroom_pie_add_sulliuscep_outcome_success=-1 -cooking_mushroom_pie_bake_outcome_success=-1 -cooking_mushroom_pie_bake_outcome_fail=-1 - -cooking_admiral_pie_add_salmon=-1 -cooking_admiral_pie_add_tuna=-1 -cooking_admiral_pie_add_potato=-1 -cooking_admiral_pie_bake=-1 -cooking_admiral_pie_add_salmon_input_0=-1 -cooking_admiral_pie_add_salmon_input_1=-1 -cooking_admiral_pie_add_tuna_input_0=-1 -cooking_admiral_pie_add_tuna_input_1=-1 -cooking_admiral_pie_add_potato_input_0=-1 -cooking_admiral_pie_add_potato_input_1=-1 -cooking_admiral_pie_bake_input_0=-1 -cooking_admiral_pie_add_salmon_outcome_success=-1 -cooking_admiral_pie_add_tuna_outcome_success=-1 -cooking_admiral_pie_add_potato_outcome_success=-1 -cooking_admiral_pie_bake_outcome_success=-1 -cooking_admiral_pie_bake_outcome_fail=-1 - -cooking_dragonfruit_pie_add_fruit=-1 -cooking_dragonfruit_pie_bake=-1 -cooking_dragonfruit_pie_add_fruit_input_0=-1 -cooking_dragonfruit_pie_add_fruit_input_1=-1 -cooking_dragonfruit_pie_bake_input_0=-1 -cooking_dragonfruit_pie_add_fruit_outcome_success=-1 -cooking_dragonfruit_pie_bake_outcome_success=-1 -cooking_dragonfruit_pie_bake_outcome_fail=-1 - -cooking_wild_pie_add_bear=-1 -cooking_wild_pie_add_chompy=-1 -cooking_wild_pie_add_rabbit=-1 -cooking_wild_pie_bake=-1 -cooking_wild_pie_add_bear_input_0=-1 -cooking_wild_pie_add_bear_input_1=-1 -cooking_wild_pie_add_chompy_input_0=-1 -cooking_wild_pie_add_chompy_input_1=-1 -cooking_wild_pie_add_rabbit_input_0=-1 -cooking_wild_pie_add_rabbit_input_1=-1 -cooking_wild_pie_bake_input_0=-1 -cooking_wild_pie_add_bear_outcome_success=-1 -cooking_wild_pie_add_chompy_outcome_success=-1 -cooking_wild_pie_add_rabbit_outcome_success=-1 -cooking_wild_pie_bake_outcome_success=-1 -cooking_wild_pie_bake_outcome_fail=-1 - -cooking_summer_pie_add_watermelon=-1 -cooking_summer_pie_add_apple=-1 -cooking_summer_pie_add_strawberry=-1 -cooking_summer_pie_bake=-1 -cooking_summer_pie_add_watermelon_input_0=-1 -cooking_summer_pie_add_watermelon_input_1=-1 -cooking_summer_pie_add_apple_input_0=-1 -cooking_summer_pie_add_apple_input_1=-1 -cooking_summer_pie_add_strawberry_input_0=-1 -cooking_summer_pie_add_strawberry_input_1=-1 -cooking_summer_pie_bake_input_0=-1 -cooking_summer_pie_add_watermelon_outcome_success=-1 -cooking_summer_pie_add_apple_outcome_success=-1 -cooking_summer_pie_add_strawberry_outcome_success=-1 -cooking_summer_pie_bake_outcome_success=-1 -cooking_summer_pie_bake_outcome_fail=-1 +cooking_redberry_pie_add_berries=982209 +cooking_redberry_pie_bake=982210 +cooking_redberry_pie_add_berries_input_0=982211 +cooking_redberry_pie_add_berries_input_1=982212 +cooking_redberry_pie_bake_input_0=982213 +cooking_redberry_pie_add_berries_outcome_success=982214 +cooking_redberry_pie_bake_outcome_success=982215 +cooking_redberry_pie_bake_outcome_fail=982216 + +cooking_meat_pie_add_meat=982217 +cooking_meat_pie_bake=982218 +cooking_meat_pie_add_meat_input_0=982219 +cooking_meat_pie_add_meat_input_1=982220 +cooking_meat_pie_bake_input_0=982221 +cooking_meat_pie_add_meat_outcome_success=982222 +cooking_meat_pie_bake_outcome_success=982223 +cooking_meat_pie_bake_outcome_fail=982224 + +cooking_mud_pie_add_compost=982225 +cooking_mud_pie_add_water=982226 +cooking_mud_pie_add_clay=982227 +cooking_mud_pie_bake=982228 +cooking_mud_pie_add_compost_input_0=982229 +cooking_mud_pie_add_compost_input_1=982230 +cooking_mud_pie_add_water_input_0=982231 +cooking_mud_pie_add_water_input_1=982232 +cooking_mud_pie_add_clay_input_0=982233 +cooking_mud_pie_add_clay_input_1=982234 +cooking_mud_pie_bake_input_0=982235 +cooking_mud_pie_add_compost_outcome_success=982236 +cooking_mud_pie_add_water_outcome_success=982237 +cooking_mud_pie_add_water_outcome_always_0=982238 +cooking_mud_pie_add_clay_outcome_success=982239 +cooking_mud_pie_bake_outcome_success=982240 +cooking_mud_pie_bake_outcome_fail=982241 + +cooking_apple_pie_add_apple=982242 +cooking_apple_pie_bake=982243 +cooking_apple_pie_add_apple_input_0=982244 +cooking_apple_pie_add_apple_input_1=982245 +cooking_apple_pie_bake_input_0=982246 +cooking_apple_pie_add_apple_outcome_success=982247 +cooking_apple_pie_bake_outcome_success=982248 +cooking_apple_pie_bake_outcome_fail=982249 + +cooking_fish_pie_add_trout=982250 +cooking_fish_pie_add_cod=982251 +cooking_fish_pie_add_potato=982252 +cooking_fish_pie_bake=982253 +cooking_fish_pie_add_trout_input_0=982254 +cooking_fish_pie_add_trout_input_1=982255 +cooking_fish_pie_add_cod_input_0=982256 +cooking_fish_pie_add_cod_input_1=982257 +cooking_fish_pie_add_potato_input_0=982258 +cooking_fish_pie_add_potato_input_1=982259 +cooking_fish_pie_bake_input_0=982260 +cooking_fish_pie_add_trout_outcome_success=982261 +cooking_fish_pie_add_cod_outcome_success=982262 +cooking_fish_pie_add_potato_outcome_success=982263 +cooking_fish_pie_bake_outcome_success=982264 +cooking_fish_pie_bake_outcome_fail=982265 + +cooking_botanical_pie_add_golovanova=982266 +cooking_botanical_pie_bake=982267 +cooking_botanical_pie_add_golovanova_input_0=982268 +cooking_botanical_pie_add_golovanova_input_1=982269 +cooking_botanical_pie_bake_input_0=982270 +cooking_botanical_pie_add_golovanova_outcome_success=982271 +cooking_botanical_pie_bake_outcome_success=982272 +cooking_botanical_pie_bake_outcome_fail=982273 + +cooking_mushroom_pie_add_sulliuscep=982274 +cooking_mushroom_pie_bake=982275 +cooking_mushroom_pie_add_sulliuscep_input_0=982276 +cooking_mushroom_pie_add_sulliuscep_input_1=982277 +cooking_mushroom_pie_bake_input_0=982278 +cooking_mushroom_pie_add_sulliuscep_outcome_success=982279 +cooking_mushroom_pie_bake_outcome_success=982280 +cooking_mushroom_pie_bake_outcome_fail=982281 + +cooking_admiral_pie_add_salmon=982282 +cooking_admiral_pie_add_tuna=982283 +cooking_admiral_pie_add_potato=982284 +cooking_admiral_pie_bake=982285 +cooking_admiral_pie_add_salmon_input_0=982286 +cooking_admiral_pie_add_salmon_input_1=982287 +cooking_admiral_pie_add_tuna_input_0=982288 +cooking_admiral_pie_add_tuna_input_1=982289 +cooking_admiral_pie_add_potato_input_0=982290 +cooking_admiral_pie_add_potato_input_1=982291 +cooking_admiral_pie_bake_input_0=982292 +cooking_admiral_pie_add_salmon_outcome_success=982293 +cooking_admiral_pie_add_tuna_outcome_success=982294 +cooking_admiral_pie_add_potato_outcome_success=982295 +cooking_admiral_pie_bake_outcome_success=982296 +cooking_admiral_pie_bake_outcome_fail=982297 + +cooking_dragonfruit_pie_add_fruit=982298 +cooking_dragonfruit_pie_bake=982299 +cooking_dragonfruit_pie_add_fruit_input_0=982300 +cooking_dragonfruit_pie_add_fruit_input_1=982301 +cooking_dragonfruit_pie_bake_input_0=982302 +cooking_dragonfruit_pie_add_fruit_outcome_success=982303 +cooking_dragonfruit_pie_bake_outcome_success=982304 +cooking_dragonfruit_pie_bake_outcome_fail=982305 + +cooking_wild_pie_add_bear=982306 +cooking_wild_pie_add_chompy=982307 +cooking_wild_pie_add_rabbit=982308 +cooking_wild_pie_bake=982309 +cooking_wild_pie_add_bear_input_0=982310 +cooking_wild_pie_add_bear_input_1=982311 +cooking_wild_pie_add_chompy_input_0=982312 +cooking_wild_pie_add_chompy_input_1=982313 +cooking_wild_pie_add_rabbit_input_0=982314 +cooking_wild_pie_add_rabbit_input_1=982315 +cooking_wild_pie_bake_input_0=982316 +cooking_wild_pie_add_bear_outcome_success=982317 +cooking_wild_pie_add_chompy_outcome_success=982318 +cooking_wild_pie_add_rabbit_outcome_success=982319 +cooking_wild_pie_bake_outcome_success=982320 +cooking_wild_pie_bake_outcome_fail=982321 + +cooking_summer_pie_add_watermelon=982322 +cooking_summer_pie_add_apple=982323 +cooking_summer_pie_add_strawberry=982324 +cooking_summer_pie_bake=982325 +cooking_summer_pie_add_watermelon_input_0=982326 +cooking_summer_pie_add_watermelon_input_1=982327 +cooking_summer_pie_add_apple_input_0=982328 +cooking_summer_pie_add_apple_input_1=982329 +cooking_summer_pie_add_strawberry_input_0=982330 +cooking_summer_pie_add_strawberry_input_1=982331 +cooking_summer_pie_bake_input_0=982332 +cooking_summer_pie_add_watermelon_outcome_success=982333 +cooking_summer_pie_add_apple_outcome_success=982334 +cooking_summer_pie_add_strawberry_outcome_success=982335 +cooking_summer_pie_bake_outcome_success=982336 +cooking_summer_pie_bake_outcome_fail=982337 # --- Pizzas --- -cooking_pizza_add_tomato=-1 -cooking_pizza_add_cheese=-1 -cooking_pizza_bake=-1 -cooking_pizza_add_tomato_input_0=-1 -cooking_pizza_add_tomato_input_1=-1 -cooking_pizza_add_cheese_input_0=-1 -cooking_pizza_add_cheese_input_1=-1 -cooking_pizza_bake_input_0=-1 -cooking_pizza_add_tomato_outcome_success=-1 -cooking_pizza_add_cheese_outcome_success=-1 -cooking_pizza_bake_outcome_success=-1 -cooking_pizza_bake_outcome_fail=-1 - -cooking_pizza_add_meat=-1 -cooking_pizza_add_meat_input_0=-1 -cooking_pizza_add_meat_input_1=-1 -cooking_pizza_add_meat_outcome_success=-1 - -cooking_pizza_add_anchovies=-1 -cooking_pizza_add_anchovies_input_0=-1 -cooking_pizza_add_anchovies_input_1=-1 -cooking_pizza_add_anchovies_outcome_success=-1 - -cooking_pizza_add_pineapple=-1 -cooking_pizza_add_pineapple_input_0=-1 -cooking_pizza_add_pineapple_input_1=-1 -cooking_pizza_add_pineapple_outcome_success=-1 +cooking_pizza_add_tomato=982338 +cooking_pizza_add_cheese=982339 +cooking_pizza_bake=982340 +cooking_pizza_add_tomato_input_0=982341 +cooking_pizza_add_tomato_input_1=982342 +cooking_pizza_add_cheese_input_0=982343 +cooking_pizza_add_cheese_input_1=982344 +cooking_pizza_bake_input_0=982345 +cooking_pizza_add_tomato_outcome_success=982346 +cooking_pizza_add_cheese_outcome_success=982347 +cooking_pizza_bake_outcome_success=982348 +cooking_pizza_bake_outcome_fail=982349 + +cooking_pizza_add_meat=982350 +cooking_pizza_add_meat_input_0=982351 +cooking_pizza_add_meat_input_1=982352 +cooking_pizza_add_meat_outcome_success=982353 + +cooking_pizza_add_anchovies=982354 +cooking_pizza_add_anchovies_input_0=982355 +cooking_pizza_add_anchovies_input_1=982356 +cooking_pizza_add_anchovies_outcome_success=982357 + +cooking_pizza_add_pineapple=982358 +cooking_pizza_add_pineapple_input_0=982359 +cooking_pizza_add_pineapple_input_1=982360 +cooking_pizza_add_pineapple_outcome_success=982361 # --- Stews --- -cooking_stew_add_potato=-1 -cooking_stew_add_meat=-1 -cooking_stew_cook=-1 -cooking_stew_add_potato_input_0=-1 -cooking_stew_add_potato_input_1=-1 -cooking_stew_add_meat_input_0=-1 -cooking_stew_add_meat_input_1=-1 -cooking_stew_cook_input_0=-1 -cooking_stew_add_potato_outcome_success=-1 -cooking_stew_add_meat_outcome_success=-1 -cooking_stew_cook_outcome_success=-1 -cooking_stew_cook_outcome_fail=-1 - -cooking_curry_add_potato=-1 -cooking_curry_add_meat=-1 -cooking_curry_add_spice=-1 -cooking_curry_cook=-1 -cooking_curry_add_potato_input_0=-1 -cooking_curry_add_potato_input_1=-1 -cooking_curry_add_meat_input_0=-1 -cooking_curry_add_meat_input_1=-1 -cooking_curry_add_spice_input_0=-1 -cooking_curry_add_spice_input_1=-1 -cooking_curry_cook_input_0=-1 -cooking_curry_add_potato_outcome_success=-1 -cooking_curry_add_meat_outcome_success=-1 -cooking_curry_add_spice_outcome_success=-1 -cooking_curry_cook_outcome_success=-1 -cooking_curry_cook_outcome_fail=-1 +cooking_stew_add_potato=982362 +cooking_stew_add_meat=982363 +cooking_stew_cook=982364 +cooking_stew_add_potato_input_0=982365 +cooking_stew_add_potato_input_1=982366 +cooking_stew_add_meat_input_0=982367 +cooking_stew_add_meat_input_1=982368 +cooking_stew_cook_input_0=982369 +cooking_stew_add_potato_outcome_success=982370 +cooking_stew_add_meat_outcome_success=982371 +cooking_stew_cook_outcome_success=982372 +cooking_stew_cook_outcome_fail=982373 + +cooking_curry_add_potato=982374 +cooking_curry_add_meat=982375 +cooking_curry_add_spice=982376 +cooking_curry_cook=982377 +cooking_curry_add_potato_input_0=982378 +cooking_curry_add_potato_input_1=982379 +cooking_curry_add_meat_input_0=982380 +cooking_curry_add_meat_input_1=982381 +cooking_curry_add_spice_input_0=982382 +cooking_curry_add_spice_input_1=982383 +cooking_curry_cook_input_0=982384 +cooking_curry_add_potato_outcome_success=982385 +cooking_curry_add_meat_outcome_success=982386 +cooking_curry_add_spice_outcome_success=982387 +cooking_curry_cook_outcome_success=982388 +cooking_curry_cook_outcome_fail=982389 # --- Potatoes --- -cooking_baked_potato=-1 -cooking_baked_potato_input_0=-1 -cooking_baked_potato_outcome_success=-1 -cooking_baked_potato_outcome_fail=-1 - -cooking_potato_add_butter=-1 -cooking_potato_add_butter_input_0=-1 -cooking_potato_add_butter_input_1=-1 -cooking_potato_add_butter_outcome_success=-1 - -cooking_potato_add_cheese=-1 -cooking_potato_add_cheese_input_0=-1 -cooking_potato_add_cheese_input_1=-1 -cooking_potato_add_cheese_outcome_success=-1 - -cooking_potato_add_egg=-1 -cooking_potato_add_egg_input_0=-1 -cooking_potato_add_egg_input_1=-1 -cooking_potato_add_egg_outcome_success=-1 -cooking_potato_add_egg_outcome_always_0=-1 - -cooking_potato_add_mushroom_onion=-1 -cooking_potato_add_mushroom_onion_input_0=-1 -cooking_potato_add_mushroom_onion_input_1=-1 -cooking_potato_add_mushroom_onion_outcome_success=-1 -cooking_potato_add_mushroom_onion_outcome_always_0=-1 - -cooking_potato_add_tuna_corn=-1 -cooking_potato_add_tuna_corn_input_0=-1 -cooking_potato_add_tuna_corn_input_1=-1 -cooking_potato_add_tuna_corn_outcome_success=-1 -cooking_potato_add_tuna_corn_outcome_always_0=-1 +cooking_baked_potato=982390 +cooking_baked_potato_input_0=982391 +cooking_baked_potato_outcome_success=982392 +cooking_baked_potato_outcome_fail=982393 + +cooking_potato_add_butter=982394 +cooking_potato_add_butter_input_0=982395 +cooking_potato_add_butter_input_1=982396 +cooking_potato_add_butter_outcome_success=982397 + +cooking_potato_add_cheese=982398 +cooking_potato_add_cheese_input_0=982399 +cooking_potato_add_cheese_input_1=982400 +cooking_potato_add_cheese_outcome_success=982401 + +cooking_potato_add_egg=982402 +cooking_potato_add_egg_input_0=982403 +cooking_potato_add_egg_input_1=982404 +cooking_potato_add_egg_outcome_success=982405 +cooking_potato_add_egg_outcome_always_0=982406 + +cooking_potato_add_mushroom_onion=982407 +cooking_potato_add_mushroom_onion_input_0=982408 +cooking_potato_add_mushroom_onion_input_1=982409 +cooking_potato_add_mushroom_onion_outcome_success=982410 +cooking_potato_add_mushroom_onion_outcome_always_0=982411 + +cooking_potato_add_tuna_corn=982412 +cooking_potato_add_tuna_corn_input_0=982413 +cooking_potato_add_tuna_corn_input_1=982414 +cooking_potato_add_tuna_corn_outcome_success=982415 +cooking_potato_add_tuna_corn_outcome_always_0=982416 # --- Misc foods --- -cooking_sweetcorn=-1 -cooking_sweetcorn_input_0=-1 -cooking_sweetcorn_outcome_success=-1 -cooking_sweetcorn_outcome_fail=-1 - -cooking_scrambled_egg_mix=-1 -cooking_scrambled_egg_cook=-1 -cooking_scrambled_egg_mix_input_0=-1 -cooking_scrambled_egg_mix_input_1=-1 -cooking_scrambled_egg_cook_input_0=-1 -cooking_scrambled_egg_mix_outcome_success=-1 -cooking_scrambled_egg_cook_outcome_success=-1 -cooking_scrambled_egg_cook_outcome_fail=-1 - -cooking_fried_onions=-1 -cooking_fried_onions_input_0=-1 -cooking_fried_onions_outcome_success=-1 -cooking_fried_onions_outcome_fail=-1 - -cooking_fried_mushrooms=-1 -cooking_fried_mushrooms_input_0=-1 -cooking_fried_mushrooms_outcome_success=-1 -cooking_fried_mushrooms_outcome_fail=-1 - -cooking_mushroom_onion_combine=-1 -cooking_mushroom_onion_combine_input_0=-1 -cooking_mushroom_onion_combine_input_1=-1 -cooking_mushroom_onion_combine_outcome_success=-1 -cooking_mushroom_onion_combine_outcome_always_0=-1 - -cooking_tuna_corn_combine=-1 -cooking_tuna_corn_combine_input_0=-1 -cooking_tuna_corn_combine_input_1=-1 -cooking_tuna_corn_combine_input_2=-1 -cooking_tuna_corn_combine_outcome_success=-1 - -cooking_chocolate_cake=-1 -cooking_chocolate_cake_input_0=-1 -cooking_chocolate_cake_input_1=-1 -cooking_chocolate_cake_outcome_success=-1 +cooking_sweetcorn=982417 +cooking_sweetcorn_input_0=982418 +cooking_sweetcorn_outcome_success=982419 +cooking_sweetcorn_outcome_fail=982420 + +cooking_scrambled_egg_mix=982421 +cooking_scrambled_egg_cook=982422 +cooking_scrambled_egg_mix_input_0=982423 +cooking_scrambled_egg_mix_input_1=982424 +cooking_scrambled_egg_cook_input_0=982425 +cooking_scrambled_egg_mix_outcome_success=982426 +cooking_scrambled_egg_cook_outcome_success=982427 +cooking_scrambled_egg_cook_outcome_fail=982428 + +cooking_fried_onions=982429 +cooking_fried_onions_input_0=982430 +cooking_fried_onions_outcome_success=982431 +cooking_fried_onions_outcome_fail=982432 + +cooking_fried_mushrooms=982433 +cooking_fried_mushrooms_input_0=982434 +cooking_fried_mushrooms_outcome_success=982435 +cooking_fried_mushrooms_outcome_fail=982436 + +cooking_mushroom_onion_combine=982437 +cooking_mushroom_onion_combine_input_0=982438 +cooking_mushroom_onion_combine_input_1=982439 +cooking_mushroom_onion_combine_outcome_success=982440 +cooking_mushroom_onion_combine_outcome_always_0=982441 + +cooking_tuna_corn_combine=982442 +cooking_tuna_corn_combine_input_0=982443 +cooking_tuna_corn_combine_input_1=982444 +cooking_tuna_corn_combine_input_2=982445 +cooking_tuna_corn_combine_outcome_success=982446 + +cooking_chocolate_cake=982447 +cooking_chocolate_cake_input_0=982448 +cooking_chocolate_cake_input_1=982449 +cooking_chocolate_cake_outcome_success=982450 # --- Wine --- -cooking_wine=-1 -cooking_wine_input_0=-1 -cooking_wine_input_1=-1 -cooking_wine_outcome_success=-1 -cooking_wine_outcome_fail=-1 +cooking_wine=982451 +cooking_wine_input_0=982452 +cooking_wine_input_1=982453 +cooking_wine_outcome_success=982454 +cooking_wine_outcome_fail=982455 # --- Snails --- -cooking_thin_snail=-1 -cooking_thin_snail_input_0=-1 -cooking_thin_snail_outcome_success=-1 -cooking_thin_snail_outcome_fail=-1 +cooking_thin_snail=982456 +cooking_thin_snail_input_0=982457 +cooking_thin_snail_outcome_success=982458 +cooking_thin_snail_outcome_fail=982459 -cooking_lean_snail=-1 -cooking_lean_snail_input_0=-1 -cooking_lean_snail_outcome_success=-1 -cooking_lean_snail_outcome_fail=-1 +cooking_lean_snail=982460 +cooking_lean_snail_input_0=982461 +cooking_lean_snail_outcome_success=982462 +cooking_lean_snail_outcome_fail=982463 -cooking_fat_snail=-1 -cooking_fat_snail_input_0=-1 -cooking_fat_snail_outcome_success=-1 -cooking_fat_snail_outcome_fail=-1 +cooking_fat_snail=982464 +cooking_fat_snail_input_0=982465 +cooking_fat_snail_outcome_success=982466 +cooking_fat_snail_outcome_fail=982467 # --- Spit-Roast Rabbit --- -cooking_skewer_rabbit_meat=-1 -cooking_skewer_rabbit_meat_input_0=-1 -cooking_skewer_rabbit_meat_input_1=-1 -cooking_skewer_rabbit_meat_outcome_success=-1 +cooking_skewer_rabbit_meat=982468 +cooking_skewer_rabbit_meat_input_0=982469 +cooking_skewer_rabbit_meat_input_1=982470 +cooking_skewer_rabbit_meat_outcome_success=982471 -cooking_roast_rabbit_meat=-1 -cooking_roast_rabbit_meat_input_0=-1 -cooking_roast_rabbit_meat_outcome_success=-1 -cooking_roast_rabbit_meat_outcome_fail=-1 +cooking_roast_rabbit_meat=982472 +cooking_roast_rabbit_meat_input_0=982473 +cooking_roast_rabbit_meat_outcome_success=982474 +cooking_roast_rabbit_meat_outcome_fail=982475 # --- Hunter Meats (Pitfall Trapping) --- -cooking_larupia=-1 -cooking_larupia_input_0=-1 -cooking_larupia_outcome_success=-1 -cooking_larupia_outcome_fail=-1 - -cooking_graahk=-1 -cooking_graahk_input_0=-1 -cooking_graahk_outcome_success=-1 -cooking_graahk_outcome_fail=-1 - -cooking_kyatt=-1 -cooking_kyatt_input_0=-1 -cooking_kyatt_outcome_success=-1 -cooking_kyatt_outcome_fail=-1 - -cooking_pyre_fox=-1 -cooking_pyre_fox_input_0=-1 -cooking_pyre_fox_outcome_success=-1 -cooking_pyre_fox_outcome_fail=-1 - -cooking_sunlight_antelope=-1 -cooking_sunlight_antelope_input_0=-1 -cooking_sunlight_antelope_outcome_success=-1 -cooking_sunlight_antelope_outcome_fail=-1 - -cooking_moonlight_antelope=-1 -cooking_moonlight_antelope_input_0=-1 -cooking_moonlight_antelope_outcome_success=-1 -cooking_moonlight_antelope_outcome_fail=-1 +cooking_larupia=982476 +cooking_larupia_input_0=982477 +cooking_larupia_outcome_success=982478 +cooking_larupia_outcome_fail=982479 + +cooking_graahk=982480 +cooking_graahk_input_0=982481 +cooking_graahk_outcome_success=982482 +cooking_graahk_outcome_fail=982483 + +cooking_kyatt=982484 +cooking_kyatt_input_0=982485 +cooking_kyatt_outcome_success=982486 +cooking_kyatt_outcome_fail=982487 + +cooking_pyre_fox=982488 +cooking_pyre_fox_input_0=982489 +cooking_pyre_fox_outcome_success=982490 +cooking_pyre_fox_outcome_fail=982491 + +cooking_sunlight_antelope=982492 +cooking_sunlight_antelope_input_0=982493 +cooking_sunlight_antelope_outcome_success=982494 +cooking_sunlight_antelope_outcome_fail=982495 + +cooking_moonlight_antelope=982496 +cooking_moonlight_antelope_input_0=982497 +cooking_moonlight_antelope_outcome_success=982498 +cooking_moonlight_antelope_outcome_fail=982499 diff --git a/util/bin/main/gg/rsmod/util/AabbUtil.kt b/util/bin/main/gg/rsmod/util/AabbUtil.kt new file mode 100644 index 00000000..2c698ae0 --- /dev/null +++ b/util/bin/main/gg/rsmod/util/AabbUtil.kt @@ -0,0 +1,124 @@ +package gg.rsmod.util + +/** + * Utility methods for axis-aligned bounding boxes. + * + * @author Tom + */ +object AabbUtil { + data class Box(val x: Int, val z: Int, val width: Int, val length: Int) { + val x1: Int get() = x + + val x2: Int get() = x + width + + val z1: Int get() = z + + val z2: Int get() = z + length + } + + /** + * Checks to see if two AABB are bordering, but not overlapping. + */ + fun areBordering( + x1: Int, + y1: Int, + width1: Int, + length1: Int, + x2: Int, + y2: Int, + width2: Int, + length2: Int, + ): Boolean { + val a = Box(x1, y1, width1 - 1, length1 - 1) + val b = Box(x2, y2, width2 - 1, length2 - 1) + + if (b.x1 in a.x1..a.x2 && b.z1 in a.z1..a.z2 || b.x2 in a.x1..a.x2 && b.z2 in a.z1..a.z2) { + return false + } + + if (b.x1 > a.x2 + 1) { + return false + } + + if (b.x2 < a.x1 - 1) { + return false + } + + if (b.z1 > a.z2 + 1) { + return false + } + + if (b.z2 < a.z1 - 1) { + return false + } + return true + } + + fun areDiagonal( + x1: Int, + y1: Int, + width1: Int, + length1: Int, + x2: Int, + y2: Int, + width2: Int, + length2: Int, + ): Boolean { + val a = Box(x1, y1, width1 - 1, length1 - 1) + val b = Box(x2, y2, width2 - 1, length2 - 1) + + /** + * South-west diagonal tile. + */ + if (a.x1 - 1 == b.x2 && a.z1 - 1 == b.z2) { + return true + } + + /** + * South-east diagonal tile. + */ + if (a.x2 + 1 == b.x2 && a.z1 - 1 == b.z2) { + return true + } + + /** + * North-west diagonal tile. + */ + if (a.x1 - 1 == b.x2 && a.z2 + 1 == b.z2) { + return true + } + + /** + * North-east diagonal tile. + */ + if (a.x2 + 1 == b.x2 && a.z2 + 1 == b.z2) { + return true + } + + return false + } + + fun areOverlapping( + x1: Int, + y1: Int, + width1: Int, + length1: Int, + x2: Int, + y2: Int, + width2: Int, + length2: Int, + ): Boolean { + val a = Box(x1, y1, width1 - 1, length1 - 1) + val b = Box(x2, y2, width2 - 1, length2 - 1) + + if (a.x1 > b.x2 || b.x1 > a.x2) { + return false + } + + if (a.z1 > b.z2 || b.z1 > a.z2) { + return false + } + + return true + } +} diff --git a/util/bin/main/gg/rsmod/util/BitManipulation.kt b/util/bin/main/gg/rsmod/util/BitManipulation.kt new file mode 100644 index 00000000..74a98a8b --- /dev/null +++ b/util/bin/main/gg/rsmod/util/BitManipulation.kt @@ -0,0 +1,32 @@ +package gg.rsmod.util + +/** + * @author Tom + */ +object BitManipulation { + /** + * Extracts the value from [packed] from the bits found in [startBit] to [endBit]. + */ + fun getBit( + packed: Int, + startBit: Int, + endBit: Int, + ): Int { + val position = DataConstants.BIT_SIZES[endBit - startBit] + return ((packed shr startBit) and position) + } + + /** + * Calculates the new [packed] value after editing the value in between the + * [startBit] and [endBit]. + */ + fun setBit( + packed: Int, + startBit: Int, + endBit: Int, + value: Int, + ): Int { + val maxValue = DataConstants.BIT_SIZES[endBit - startBit] shl startBit + return (packed and maxValue.inv()) or ((value shl startBit) and maxValue) + } +} diff --git a/util/bin/main/gg/rsmod/util/DataConstants.kt b/util/bin/main/gg/rsmod/util/DataConstants.kt new file mode 100644 index 00000000..905e9707 --- /dev/null +++ b/util/bin/main/gg/rsmod/util/DataConstants.kt @@ -0,0 +1,28 @@ +package gg.rsmod.util + +/** + * A class holding data-related constants. + * + * @author Graham + * @author Tom + */ +object DataConstants { + /** + * An array of bit masks. The element `n` is equal to `2n - 1`. + */ + val BIT_MASK = + IntArray(32).apply { + for (i in indices) { + set(i, (1 shl i) - 1) + } + } + + val BIT_SIZES = + IntArray(32).apply { + var size = 2 + for (i in indices) { + set(i, size - 1) + size += size + } + } +} diff --git a/util/bin/main/gg/rsmod/util/ExtensionFunctions.kt b/util/bin/main/gg/rsmod/util/ExtensionFunctions.kt new file mode 100644 index 00000000..7057065b --- /dev/null +++ b/util/bin/main/gg/rsmod/util/ExtensionFunctions.kt @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2014 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package gg.rsmod.util + +/** + * Extension function that creates an instance of [ToStringHelper]. + * + * This is helpful for implementing [Object.toString]. Specification by example: + * + * toStringHelper().toString(); // Returns "ClassName{}" + * + * toStringHelper().add("x", 1).toString(); // Returns "ClassName{x=1}" + * + * + * toStringHelper().add("x", 1).add("y", "foo").toString(); // Returns "ClassName{x=1, y=foo}" + * + */ +fun Any.toStringHelper(): ToStringHelper { + return ToStringHelper(javaClass.simpleName) +} + +/** + * Support class for [toStringHelper]. + * + * Use [toStringHelper()] to create an instance. Do not instantiate this directly. + * + * @author Jason Lee + * @since 18.0 (since 2.0 as `Objects.ToStringHelper`). + * + * Changes: 5/27/2024 converted com.google.common.base.MoreObjects.ToStringHelper to kotlin + * Streamlined functionality and removed excluding nulls. + * Original file from commit c4b883de9679dae7da831e49dd9adaca71cc1991 + */ +class ToStringHelper constructor(private val className: String) { + private val holderHead = ValueHolder() + private var holderTail: ValueHolder? = holderHead + + /** + * Adds a name/value pair to the formatted output in `name=value` format. If `value` + * is `null`, the string `"null"` is used + */ + fun add( + name: String, + value: Any?, + ): ToStringHelper { + val valueHolder = ValueHolder() + holderTail!!.next = valueHolder + holderTail = holderTail!!.next + valueHolder.value = value + valueHolder.name = name + return this + } + + /** + * Returns a string in the format specified by [toStringHelper.toStringHelper]. + * + * + * After calling this method, you can keep adding more properties to later call toString() + * again and get a more complete representation of the same object; but properties cannot be + * removed, so this only allows limited reuse of the helper instance. The helper allows + * duplication of properties (multiple name/value pairs with the same name can be added). + */ + override fun toString(): String { + // create a copy to keep it consistent in case value changes + var nextSeparator = "" + val builder = StringBuilder(32).append(className).append('{') + var valueHolder = holderHead.next + while (valueHolder != null) { + val value = valueHolder.value + builder.append(nextSeparator) + nextSeparator = ", " + if (valueHolder.name != null) { + builder.append(valueHolder.name).append('=') + } + if (value != null && value.javaClass.isArray) { + val arrayString = arrayOf(value).contentDeepToString() + builder.append(arrayString, 1, arrayString.length - 1) + } else { + builder.append(value) + } + valueHolder = valueHolder.next + } + return builder.append('}').toString() + } + + // Holder object for values that might be null and/or empty. + private class ValueHolder { + var name: String? = null + var value: Any? = null + var next: ValueHolder? = null + } +} diff --git a/util/bin/main/gg/rsmod/util/Misc.kt b/util/bin/main/gg/rsmod/util/Misc.kt new file mode 100644 index 00000000..a3da87b6 --- /dev/null +++ b/util/bin/main/gg/rsmod/util/Misc.kt @@ -0,0 +1,41 @@ +package gg.rsmod.util + +/** + * @author Tom + */ +object Misc { + fun IntRange.toArray(): Array { + return toList().toTypedArray() + } + + fun getIndefiniteArticle(word: String): String { + val first = word.lowercase().first() + val vowel = first == 'a' || first == 'e' || first == 'i' || first == 'o' || first == 'u' + val numeric = word.first().equals(Regex(".*[0-9].*")) + val special = + listOf( + "bolts", + "arrows", + "coins", + "vambraces", + "chaps", + "grapes", + "silk", + "bread", + "grey wolf fur", + "spice", + ).filter { it in word } + val some = special.isNotEmpty() + return ( + if (numeric) { + "" + } else if (vowel) { + "an" + } else if (some) { + "some" + } else { + "a" + } + ) + " " + word + } +} diff --git a/util/bin/main/gg/rsmod/util/Namer.kt b/util/bin/main/gg/rsmod/util/Namer.kt new file mode 100644 index 00000000..9b15c485 --- /dev/null +++ b/util/bin/main/gg/rsmod/util/Namer.kt @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2017, Adam + * Copyright (c) 2018, Joshua Filby + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package gg.rsmod.util + +import java.util.Locale + +class Namer { + private val used: MutableSet = HashSet() + + fun name( + name: String?, + id: Int, + ): String? { + var name = name + name = sanitize(name) + if (name == null) { + return null + } + if (used.contains(name)) { + name = name + "_" + id + assert(!used.contains(name)) + } + used.add(name) + return name + } + + companion object { + private fun sanitize(`in`: String?): String? { + val s = + removeTags(`in`) + .uppercase(Locale.getDefault()) + .replace(' ', '_') + .replace("[^a-zA-Z0-9_]".toRegex(), "") + if (s.isEmpty()) { + return null + } + return if (Character.isDigit(s[0])) { + "_$s" + } else { + s + } + } + + fun removeTags(str: String?): String { + val builder = StringBuilder(str!!.length) + var inTag = false + for (i in 0 until str.length) { + val currentChar = str[i] + if (currentChar == '<') { + inTag = true + } else if (currentChar == '>') { + inTag = false + } else if (!inTag) { + builder.append(currentChar) + } + } + return builder.toString() + } + } +} diff --git a/util/bin/main/gg/rsmod/util/RscmRemapper.kt b/util/bin/main/gg/rsmod/util/RscmRemapper.kt new file mode 100644 index 00000000..c56399de --- /dev/null +++ b/util/bin/main/gg/rsmod/util/RscmRemapper.kt @@ -0,0 +1,84 @@ +package gg.rsmod.util + +import java.io.File + +fun main() { + // Helper function to load mappings from a file + fun loadMap(path: String, sep: String = ":"): Map { + return File(path).readLines() + .map { it.split(sep) } + .associate { it[0] to it[1].toInt() } + } + + // Load old and new maps for items + val oldItemMap = loadMap("C:\\Users\\Home\\Desktop\\Alter-feature-support-231\\Alter-feature-support-231\\data\\cfg\\rscm\\item.rscm") + val newItemMap = File("C:\\Users\\Home\\Desktop\\Alter-feature-support-231\\Alter-feature-support-231\\data\\cfg\\rscm2\\items.rscm") + .readLines() + .map { it.split("=") } + .associate { it[1].toInt() to it[0] } + + val itemLookup = oldItemMap.mapNotNull { (oldName, id) -> + val newName = newItemMap[id] + if (newName != null) oldName to newName else null + }.toMap() + + // Load old and new maps for NPCs + val oldNpcMap = loadMap("C:\\Users\\Home\\Desktop\\Alter-feature-support-231\\Alter-feature-support-231\\data\\cfg\\rscm\\npc.rscm") + val newNpcMap = File("C:\\Users\\Home\\Desktop\\Alter-feature-support-231\\Alter-feature-support-231\\data\\cfg\\rscm2\\npcs.rscm") + .readLines() + .map { it.split("=") } + .associate { it[1].toInt() to it[0] } + + val npcLookup = oldNpcMap.mapNotNull { (oldName, id) -> + val newName = newNpcMap[id] + if (newName != null) oldName to newName else null + }.toMap() + + // Load old and new maps for objects + val oldObjMap = loadMap("C:\\Users\\Home\\Desktop\\Alter-feature-support-231\\Alter-feature-support-231\\data\\cfg\\rscm\\object.rscm") + val newObjMap = File("C:\\Users\\Home\\Desktop\\Alter-feature-support-231\\Alter-feature-support-231\\data\\cfg\\rscm2\\objects.rscm") + .readLines() + .map { it.split("=") } + .associate { it[1].toInt() to it[0] } + + val objLookup = oldObjMap.mapNotNull { (oldName, id) -> + val newName = newObjMap[id] + if (newName != null) oldName to newName else null + }.toMap() + + val rootDir = File("C:\\Users\\Home\\Desktop\\Alter-feature-support-231\\Alter-feature-support-231") + + rootDir.walkTopDown() + .filter { it.isFile && (it.extension == "kt" || it.extension == "kts") } + .forEach { file -> + var text = file.readText() + var replaced = false + + // Regex to match string literals like "item.*", "npc.*", "object.*" + val regex = """"(item|npc|object)\.([^"]+)"""".toRegex() + + text = regex.replace(text) { matchResult -> + val prefix = matchResult.groupValues[1] + val oldStr = matchResult.groupValues[2] + val newStr = when (prefix) { + "item" -> itemLookup[oldStr] + "npc" -> npcLookup[oldStr] + "object" -> objLookup[oldStr] + else -> null + } + + if (newStr != null) { + replaced = true + "\"$prefix.$newStr\"" + } else { + println("Unknown mapping in ${file.path}: \"${prefix}.${oldStr}\"") + matchResult.value // keep original + } + } + + if (replaced) { + println("Updated file: ${file.path}") + file.writeText(text) + } + } +} diff --git a/util/bin/main/gg/rsmod/util/ServerProperties.kt b/util/bin/main/gg/rsmod/util/ServerProperties.kt new file mode 100644 index 00000000..85182bc7 --- /dev/null +++ b/util/bin/main/gg/rsmod/util/ServerProperties.kt @@ -0,0 +1,73 @@ +package gg.rsmod.util + +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory +import java.io.File + +/** + * Holds a map of properties that can be used by the server + * at any point. + * + * @author Tom + */ +class ServerProperties { + private val properties = hashMapOf() + + /** + * Gets the property associated with the [key]. If it cannot be found, it will + * return the [default] value instead. + */ + @Suppress("UNCHECKED_CAST") + fun getOrDefault( + key: String, + default: T, + ): T = properties[key] as? T ?: default + + /** + * Gets the property associated with the [key]. If it cannot be found, it will + * return null instead. + */ + @Suppress("UNCHECKED_CAST") + fun get(key: String): T? = properties[key] as? T + + /** + * Checks if [properties] contains a value associated with [key]. + */ + fun has(key: String): Boolean = properties.containsKey(key) + + /** + * Loads a YAML (.yml) file and puts all the found keys & values + * into the [properties] map. + */ + fun loadYaml(file: File): ServerProperties { + check(properties.isEmpty()) + + val mapper = ObjectMapper(YAMLFactory()) + val values = mapper.readValue(file, HashMap().javaClass) + + values.forEach { key, value -> + if (value is String && value.isEmpty()) { + properties[key] = null + } else { + properties[key] = value + } + } + return this + } + + fun loadMap(data: Map): ServerProperties { + check(properties.isEmpty()) + + data.forEach { key, value -> + if (value is String && value.isEmpty()) { + properties[key] = null + } else { + properties[key] = value + } + } + return this + } + + @Suppress("UNCHECKED_CAST") + fun extract(key: String): ServerProperties = ServerProperties().loadMap(get>(key) as Map) +} diff --git a/util/bin/main/gg/rsmod/util/Stopwatch.kt b/util/bin/main/gg/rsmod/util/Stopwatch.kt new file mode 100644 index 00000000..03a16de1 --- /dev/null +++ b/util/bin/main/gg/rsmod/util/Stopwatch.kt @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2008 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package gg.rsmod.util + +import java.time.Duration +import java.util.* +import java.util.concurrent.TimeUnit + +/** + * An object that accurately measures *elapsed time*: the measured duration between two + * successive readings of "now" in the same process. + * + * + * In contrast, *wall time* is a reading of "now" as given by a method like + * [System.currentTimeMillis], best represented as an [java.time.Instant]. Such values + * *can* be subtracted to obtain a `Duration` (such as by `Duration.between`), but + * doing so does *not* give a reliable measurement of elapsed time, because wall time readings + * are inherently approximate, routinely affected by periodic clock corrections. Because this class + * uses [System.nanoTime], it is unaffected by these changes. + * + * + * Use this class instead of direct calls to [System.nanoTime] for the following reason: + * + * + * * The raw `long` values returned by `nanoTime` are meaningless and unsafe to use + * in any other way than how `Stopwatch` uses them. + * + * + * + * The one downside of `Stopwatch` relative to [System.nanoTime] is that `Stopwatch` requires object allocation and additional method calls, which can reduce the accuracy + * of the elapsed times reported. `Stopwatch` is still suitable for logging and metrics where + * reasonably accurate values are sufficient. If the uncommon case that you need to maximize + * accuracy, use `System.nanoTime()` directly instead. + * + * + * Basic usage: + * + *
`Stopwatch stopwatch = Stopwatch.createStarted();
+ * doSomething();
+ * stopwatch.stop(); // optional
+ *
+ * Duration duration = stopwatch.elapsed();
+ *
+ * log.info("time: " + stopwatch); // formatted string like "12.3 ms"
+`
* + * + * + * The state-changing methods are not idempotent; it is an error to start or stop a stopwatch + * that is already in the desired state. + * + * + * **Note:** This class is not thread-safe. + * + * + * @author Kevin Bourrillion + * @since 10.0 + * + * Changes: 5/27/2024 converted com.google.common.base.Stopwatch to kotlin + * Original file from commit c4b883de9679dae7da831e49dd9adaca71cc1991 + */ +class Stopwatch { + /** + * Returns `true` if [.start] has been called on this stopwatch, and [.stop] + * has not been called since the last call to `start()`. + */ + private var isRunning = false + private var elapsedNanos: Long = 0 + private var startTick: Long = 0 + + /** + * Starts the stopwatch. + * + * @return this `Stopwatch` instance + * @throws IllegalStateException if the stopwatch is already running. + */ + fun start(): Stopwatch { + check(!isRunning) { "This stopwatch is already running." } + isRunning = true + startTick = System.nanoTime() + return this + } + + /** + * Stops the stopwatch. Future reads will return the fixed duration that had elapsed up to this + * point. + * + * @return this `Stopwatch` instance + * @throws IllegalStateException if the stopwatch is already stopped. + */ + fun stop(): Stopwatch { + val tick = System.nanoTime() + check(isRunning) { "This stopwatch is already stopped." } + isRunning = false + elapsedNanos += tick - startTick + return this + } + + /** + * Sets the elapsed time for this stopwatch to zero, and places it in a stopped state. + * + * @return this `Stopwatch` instance + */ + fun reset(): Stopwatch { + elapsedNanos = 0 + isRunning = false + return this + } + + private fun elapsedNanos(): Long { + return if (isRunning) System.nanoTime() - startTick + elapsedNanos else elapsedNanos + } + + /** + * Returns the current elapsed time shown on this stopwatch, expressed in the desired time unit, + * with any fraction rounded down. + * + * + * **Note:** the overhead of measurement can be more than a microsecond, so it is generally + * not useful to specify [TimeUnit.NANOSECONDS] precision here. + * + * + * It is generally not a good idea to use an ambiguous, unitless `long` to represent + * elapsed time. Therefore, we recommend using [.elapsed] instead, which returns a + * strongly-typed `Duration` instance. + * + * @since 14.0 (since 10.0 as `elapsedTime()`) + */ + fun elapsed(desiredUnit: TimeUnit): Long { + return desiredUnit.convert(elapsedNanos(), TimeUnit.NANOSECONDS) + } + + /** + * Returns the current elapsed time shown on this stopwatch as a [Duration]. Unlike [ ][.elapsed], this method does not lose any precision due to rounding. + * + * @since 22.0 + */ + fun elapsed(): Duration { + return Duration.ofNanos(elapsedNanos()) + } + + /** Returns a string representation of the current elapsed time. */ + override fun toString(): String { + val nanos = elapsedNanos() + val unit = chooseUnit(nanos) + val value = nanos.toDouble() / TimeUnit.NANOSECONDS.convert(1, unit) + + // Too bad this functionality is not exposed as a regular method call + return formatCompact4Digits(value) + " " + abbreviate(unit) + } + + companion object { + /** + * Creates (but does not start) a new stopwatch using [System.nanoTime] as its time source. + * + * @since 15.0 + */ + fun createUnstarted(): Stopwatch { + return Stopwatch() + } + + /** + * Creates (and starts) a new stopwatch using [System.nanoTime] as its time source. + * + * @since 15.0 + */ + fun createStarted(): Stopwatch { + return Stopwatch().start() + } + + private fun chooseUnit(nanos: Long): TimeUnit { + if (TimeUnit.DAYS.convert(nanos, TimeUnit.NANOSECONDS) > 0) { + return TimeUnit.DAYS + } + if (TimeUnit.HOURS.convert(nanos, TimeUnit.NANOSECONDS) > 0) { + return TimeUnit.HOURS + } + if (TimeUnit.MINUTES.convert(nanos, TimeUnit.NANOSECONDS) > 0) { + return TimeUnit.MINUTES + } + if (TimeUnit.SECONDS.convert(nanos, TimeUnit.NANOSECONDS) > 0) { + return TimeUnit.SECONDS + } + if (TimeUnit.MILLISECONDS.convert(nanos, TimeUnit.NANOSECONDS) > 0) { + return TimeUnit.MILLISECONDS + } + return if (TimeUnit.MICROSECONDS.convert(nanos, TimeUnit.NANOSECONDS) > 0) { + TimeUnit.MICROSECONDS + } else { + TimeUnit.NANOSECONDS + } + } + + private fun abbreviate(unit: TimeUnit): String { + return when (unit) { + TimeUnit.NANOSECONDS -> "ns" + TimeUnit.MICROSECONDS -> "\u03bcs" // μs + TimeUnit.MILLISECONDS -> "ms" + TimeUnit.SECONDS -> "s" + TimeUnit.MINUTES -> "min" + TimeUnit.HOURS -> "h" + TimeUnit.DAYS -> "d" + else -> throw AssertionError() + } + } + + fun formatCompact4Digits(value: Double): String { + return String.format(Locale.ROOT, "%.4g", value) + } + } +} diff --git a/util/bin/main/gg/rsmod/util/concurrency/PhasedTask.kt b/util/bin/main/gg/rsmod/util/concurrency/PhasedTask.kt new file mode 100644 index 00000000..829db8bc --- /dev/null +++ b/util/bin/main/gg/rsmod/util/concurrency/PhasedTask.kt @@ -0,0 +1,21 @@ +package gg.rsmod.util.concurrency + +import io.github.oshai.kotlinlogging.KotlinLogging +import java.util.concurrent.Phaser + +object PhasedTask { + private val logger = KotlinLogging.logger {} + + fun run( + phaser: Phaser, + task: () -> Unit, + ) { + try { + task() + } catch (e: Exception) { + logger.error(e) { "Error with phased task." } + } finally { + phaser.arriveAndDeregister() + } + } +} diff --git a/util/bin/main/gg/rsmod/util/concurrency/ThreadFactoryBuilder.kt b/util/bin/main/gg/rsmod/util/concurrency/ThreadFactoryBuilder.kt new file mode 100644 index 00000000..05fb1ffa --- /dev/null +++ b/util/bin/main/gg/rsmod/util/concurrency/ThreadFactoryBuilder.kt @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2010 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package gg.rsmod.util.concurrency + +import java.util.* +import java.util.concurrent.Executors +import java.util.concurrent.ThreadFactory +import java.util.concurrent.atomic.AtomicLong + +/** + * A ThreadFactory builder, providing any combination of these features: + * + * + * * whether threads should be marked as [daemon][Thread.setDaemon] threads + * * a [naming format][ThreadFactoryBuilder.setNameFormat] + * * a [thread priority][Thread.setPriority] + * * an [uncaught exception handler][Thread.setUncaughtExceptionHandler] + * * a [backing thread factory][ThreadFactory.newThread] + * + * + * + * If no backing thread factory is provided, a default backing thread factory is used as if by + * calling `setThreadFactory(`[Executors.defaultThreadFactory]`)`. + * + * @author Kurt Alfred Kluever + * @since 4.0 + * + * Changes: 5/27/2024 converted com.google.common.util.concurrent.ThreadFactoryBuilder to kotlin + * Original file from commit c4b883de9679dae7da831e49dd9adaca71cc1991 + */ +class ThreadFactoryBuilder { +/** Creates a new [ThreadFactory] builder. */ + private var nameFormat: String? = null + private var daemon: Boolean? = null + private var priority: Int? = null + private var uncaughtExceptionHandler: Thread.UncaughtExceptionHandler? = null + private var backingThreadFactory: ThreadFactory? = null + + /** + * Sets the naming format to use when naming threads ([Thread.setName]) which are created + * with this ThreadFactory. + * + * @param nameFormat a [String.format]-compatible format String, to which + * a unique integer (0, 1, etc.) will be supplied as the single parameter. This integer will + * be unique to the built instance of the ThreadFactory and will be assigned sequentially. For + * example, `"rpc-pool-%d"` will generate thread names like `"rpc-pool-0"`, `"rpc-pool-1"`, `"rpc-pool-2"`, etc. + * @return this for the builder pattern + */ + fun setNameFormat(nameFormat: String): ThreadFactoryBuilder { + val unused = format(nameFormat, 0) // fail fast if the format is bad or null + this.nameFormat = nameFormat + return this + } + + /** + * Sets daemon or not for new threads created with this ThreadFactory. + * + * @param daemon whether or not new Threads created with this ThreadFactory will be daemon threads + * @return this for the builder pattern + */ + fun setDaemon(daemon: Boolean): ThreadFactoryBuilder { + this.daemon = daemon + return this + } + + /** + * Sets the priority for new threads created with this ThreadFactory. + * + * + * **Warning:** relying on the thread scheduler is [discouraged](http://errorprone.info/bugpattern/ThreadPriorityCheck). + * + * @param priority the priority for new Threads created with this ThreadFactory + * @return this for the builder pattern + */ + fun setPriority(priority: Int): ThreadFactoryBuilder { + // Thread#setPriority() already checks for validity. These error messages + // are nicer though and will fail-fast. + require(priority >= Thread.MIN_PRIORITY) { + format( + "Thread priority (%s) must be >= %s", + priority, + Thread.MIN_PRIORITY, + ) + } + require(priority <= Thread.MAX_PRIORITY) { + format( + "Thread priority (%s) must be <= %s", + priority, + Thread.MAX_PRIORITY, + ) + } + this.priority = priority + return this + } + + /** + * Sets the [UncaughtExceptionHandler] for new threads created with this ThreadFactory. + * + * @param uncaughtExceptionHandler the uncaught exception handler for new Threads created with + * this ThreadFactory + * @return this for the builder pattern + */ + fun setUncaughtExceptionHandler(uncaughtExceptionHandler: Thread.UncaughtExceptionHandler): ThreadFactoryBuilder { + this.uncaughtExceptionHandler = uncaughtExceptionHandler + return this + } + + /** + * Sets the backing [ThreadFactory] for new threads created with this ThreadFactory. Threads + * will be created by invoking #newThread(Runnable) on this backing [ThreadFactory]. + * + * @param backingThreadFactory the backing [ThreadFactory] which will be delegated to during + * thread creation. + * @return this for the builder pattern + */ + fun setThreadFactory(backingThreadFactory: ThreadFactory): ThreadFactoryBuilder { + this.backingThreadFactory = backingThreadFactory + return this + } + + /** + * Returns a new thread factory using the options supplied during the building process. After + * building, it is still possible to change the options used to build the ThreadFactory and/or + * build again. State is not shared amongst built instances. + * + * @return the fully constructed [ThreadFactory] + */ + fun build(): ThreadFactory { + return doBuild(this) + } + + companion object { + // Split out so that the anonymous ThreadFactory can't contain a reference back to the builder. + // At least, I assume that's why. TODO(cpovirk): Check, and maybe add a test for this. + private fun doBuild(builder: ThreadFactoryBuilder): ThreadFactory { + val nameFormat = builder.nameFormat + val daemon = builder.daemon + val priority = builder.priority + val uncaughtExceptionHandler = builder.uncaughtExceptionHandler + val backingThreadFactory = builder.backingThreadFactory ?: Executors.defaultThreadFactory() + val count: AtomicLong? = if (nameFormat != null) AtomicLong(0) else null + return ThreadFactory { runnable -> + val thread: Thread = backingThreadFactory.newThread(runnable) + // TODO(b/139735208): Figure out what to do when the factory returns null. + Objects.requireNonNull(thread) + if (nameFormat != null) { + // this is safe because we create `count` if (and only if) we have a nameFormat. + thread.name = format(nameFormat, count!!.getAndIncrement()) + } + if (daemon != null) { + thread.isDaemon = daemon + } + if (priority != null) { + thread.priority = priority + } + if (uncaughtExceptionHandler != null) { + thread.uncaughtExceptionHandler = uncaughtExceptionHandler + } + thread + } + } + + private fun format( + format: String, + vararg args: Any, + ): String { + return String.format(Locale.ROOT, format, *args) + } + } +} diff --git a/util/bin/main/gg/rsmod/util/io/BufferUtils.kt b/util/bin/main/gg/rsmod/util/io/BufferUtils.kt new file mode 100644 index 00000000..e2cccae8 --- /dev/null +++ b/util/bin/main/gg/rsmod/util/io/BufferUtils.kt @@ -0,0 +1,88 @@ +package gg.rsmod.util.io + +import io.netty.buffer.ByteBuf + +/** + * @author Tom + */ +object BufferUtils { + fun ByteBuf.toArray(length: Int = readableBytes()): ByteArray { + val bytes = ByteArray(length) + duplicate().readBytes(bytes) + return bytes + } + + fun ByteBuf.readString(): String { + if (isReadable) { + val start = readerIndex() + while (readByte().toInt() != 0); + val size = readerIndex() - start + + val data = ByteArray(size) + readerIndex(start) + readBytes(data) + + return String(data, 0, size - 1) + } else { + return "" + } + } + + fun ByteBuf.readJagexString(): String { + if (isReadable && readByte().toInt() != 0) { + val start = readerIndex() + while (readByte().toInt() != 0); + val size = readerIndex() - start + + val data = ByteArray(size) + readerIndex(start) + readBytes(data) + + return String(data, 0, size - 1) + } else { + return "" + } + } + + /** + * Gets a 32-bit integer at the current {@code readerIndex} + * in Litte endian format (DCBA) + * and increases the {@code readerIndex} by {@code 4} in this buffer. + * + * @throws IndexOutOfBoundsException + * if {@code this.readableBytes} is less than {@code 4} + * + * Note| this method now is natively implemented in netty and shouldn't be needed + * commented out for posterity and to keep it from showing in code completion + */ + fun ByteBuf.readIntLE(): Int { + if (readableBytes() < 4) throw IndexOutOfBoundsException("buffer does not contain enough bytes to read an int") + return (readByte().toInt() and 0xFF) + ((readByte().toInt() and 0xFF) shl 8) + ((readByte().toInt() and 0xFF) shl 16) + ((readByte().toInt() and 0xFF) shl 24) + } + + /** + * Gets a 32-bit integer at the current {@code readerIndex} + * in Inverse Middle endian format (BADC) + * and increases the {@code readerIndex} by {@code 4} in this buffer. + * + * @throws IndexOutOfBoundsException + * if {@code this.readableBytes} is less than {@code 4} + */ + fun ByteBuf.readIntIME(): Int { + if (readableBytes() < 4) throw IndexOutOfBoundsException("buffer does not contain enough bytes to read an int") + return ((readByte().toInt() and 0xFF) shl 16) + ((readByte().toInt() and 0xFF) shl 24) + (readByte().toInt() and 0xFF) + ((readByte().toInt() and 0xFF) shl 8) + } + + /** + * Gets a 32-bit integer at the current {@code readerIndex} + * in Middle endian format (CDAB) + * and increases the {@code readerIndex} by {@code 4} in this buffer. + * + * @throws IndexOutOfBoundsException + * if {@code this.readableBytes} is less than {@code 4} + */ + fun ByteBuf.readIntME(): Int { + if (readableBytes() < 4) throw IndexOutOfBoundsException("buffer does not contain enough bytes to read an int") + return ((readByte().toInt() and 0xFF) shl 8) + (readByte().toInt() and 0xFF) + ((readByte().toInt() and 0xFF) shl 24) + ((readByte().toInt() and 0xFF) shl 16) + } +} diff --git a/wikidata/burn_level.wikisrc b/wikidata/burn_level.wikisrc new file mode 100644 index 00000000..7e7a7393 --- /dev/null +++ b/wikidata/burn_level.wikisrc @@ -0,0 +1,1269 @@ +{{External|rs}} +{{Incomplete|CoX fish need looking into, [[statrandom]] was updated and everything needs to be checked over as a multitude of burn levels were slightly changed}} + +These tables show the [[Cooking]] level required for the raw [[food]] item to stop [[Burnt food|burning]]. These values do '''not''' account for wearing the [[cooking cape]], which guarantees food will never burn while wearing it. An empty value with a dash that is not N/A means that the food can '''still''' be burned on that cooking source. + +==Food types== +===Affected by cooking gauntlets=== +{| class="wikitable sortable align-left-2" style="text-align:center;" +|- +!colspan=2 rowspan=2|Food +!rowspan=2|[[Fire]] +!rowspan=2|[[Range]]? +!colspan=2|[[Hosidius Kitchen|Hosidius]]? +!colspan=3|[[Cooking gauntlets|Gauntlets]] +!rowspan=2|[[Experience]] +!rowspan=2|Members? +|- +!5% +![[Kourend & Kebos Diary#Rewards 4|10%]]The value will be N/A if the level required to not burn with the [[Elite Kourend & Kebos Diary]] completed is lower than the level required to complete the diary (level 84). +!Default +!Hosidius 5% +![[Kourend & Kebos Diary#Rewards 4|Hosidius 10%]] +|- +|{{plinkt|Lobster}} +|74 +|74 +|70 +|{{NA}} +|64 +|60 +|{{NA}} +|120 +|{{Members|no}} +|- +|{{plinkt|Swordfish}} +|86 +|80 +|76 +|{{NA}} +|80 +|76 +|{{NA}} +|140 +|{{Members|no}} +|- +|{{plinkt|Cooked kyatt}} +|86 +|80 +|76 +|{{NA}} +|80 +|76 +|{{NA}} +|143 +|{{Members|yes}} +|- +|{{plinkt|Monkfish}} +|92 +|90 +|86 +|82 +|86 +|82 +|{{NA}} +|150 +|{{Members|yes}} +|- +|{{plinkt|Shark}} +| - +| - +| - +|98 +|94 +|89 +|84 +|210 +|{{Members|yes}} +|- +|{{plinkt|Anglerfish}} +| - +| - +| - +| - +|97 +|93 +|87 +|230 +|{{Members|yes}} +|} +{{Reflist|group=h}} + +===Affected by Lumbridge Castle range=== +{| class="wikitable sortable align-left-2" style="text-align:center;" +|- +!colspan="2"|Food +![[Fire]] +![[Range|Normal
range]]{{Note|Lower chance of burning than on an open fire.|?}} +![[Cooking range (Lumbridge Castle)|Castle
range]]{{Note|Slightly lower chance to burn than both open fire and standard ranges.|?}} +![[Experience]] +!Members? +|- +|{{plinkt|Cooked meat}} +|34 +|{{NA}} +|31 +|30 +|{{Members|no}} +|- +|{{plinkt|Cooked chicken}} +|34 +|{{NA}} +|31 +|30 +|{{Members|no}} +|- +|{{plinkt|Shrimps}} +|34 +|{{NA}} +|31 +|30 +|{{Members|no}} +|- +|{{plinkt|Anchovies}} +|34 +|{{NA}} +|31 +|30 +|{{Members|no}} +|- +|{{plinkt|Bread}} +|{{NA}} +|38 +|34 +|40 +|{{Members|no}} +|- +|{{plinkt|Sardine}} +|38 +|{{NA}} +|34 +|40 +|{{Members|no}} +|- +|{{plinkt|Herring}} +|41 +|{{NA}} +|38 +|50 +|{{Members|no}} +|- +|{{plinkt|Giant carp}} +|45 +|{{NA}} +|41 +|0 +|{{Members|yes}} +|- +|{{plinkt|Mackerel}} +|45 +|{{NA}} +|41 +|60 +|{{Members|yes}} +|- +|{{plinkt|Redberry pie}} +|{{NA}} +|45 +|42 +|78 +|{{Members|no}} +|- +|{{plinkt|Thin snail meat}} +|47 +|{{NA}} +|43 +|70 +|{{Members|yes}} +|- +|{{plinkt|Lean snail meat}} +|47 +|50 +|46 +|80 +|{{Members|yes}} +|- +|{{plinkt|Trout}} +|49 +|{{NA}} +|45 +|70 +|{{Members|no}} +|- +|{{plinkt|Cod}} +|51 +|49 +|47 +|75 +|{{Members|yes}} +|- +|{{plinkt|Pike}} +|54 +|{{NA}} +|49 +|80 +|{{Members|no}} +|- +|{{plinkt|Meat pie}} +|{{NA}} +|54 +|49 +|110 +|{{Members|no}} +|- +|{{plinkt|Fat snail meat}} +|56 +|{{NA}} +|51 +|95 +|{{Members|yes}} +|- +|{{plinkt|Stew}} +|58 +|{{NA}} +|54 +|117 +|{{Members|no}} +|- +|{{plinkt|Salmon}} +|58 +|{{NA}} +|55 +|90 +|{{Members|no}} +|- +|{{plinkt|Botanical pie}} +|{{NA}} +|84 +|52 +|180 +|{{Members|yes}} +|- +|{{plinkt|Mushroom pie}} +|{{NA}} +|89 +|60 +|200 +|{{Members|yes}} +|} + +===Meats=== +{| class="wikitable sortable align-left-2" style="text-align:center;" +|- +!colspan=2 rowspan=2|Food +!rowspan=2|[[Fire]] +!rowspan=2|[[Range]]{{Note|Generally lower chance of burning than on an open fire. Value is N/A if it does not reduce burn chance.|?}} +!colspan=2|[[Hosidius Kitchen|Hosidius]]{{Note|The Hosidius Kitchen range multiplies the chance-to-not-burn roll by 1.05 or 1.10 with the elite diary completed.|?}} +!rowspan=2|[[Experience]] +!rowspan=2|Members? +|- +!5% +![[Kourend & Kebos Diary#Rewards 4|10%]]The value will be N/A if the level required to not burn with the [[Elite Kourend & Kebos Diary]] completed is lower than the level required to complete the diary (level 84). +|- +|{{plinkt|Cooked meat}} +|34 +|{{NA}} +|31 +|{{NA}} +|30 +|{{Members|no}} +|- +|{{plinkt|Cooked chicken}} +|34 +|{{NA}} +|31 +|{{NA}} +|30 +|{{Members|no}} +|- +|{{plinkt|Cooked rabbit}} +|34 +|{{NA}} +|31 +|{{NA}} +|30 +|{{Members|yes}} +|- +|{{plinkt|Shrimps}} +|34 +|{{NA}} +|31 +|{{NA}} +|30 +|{{Members|no}} +|- +|{{plinkt|Anchovies}} +|34 +|{{NA}} +|31 +|{{NA}} +|30 +|{{Members|no}} +|- +|{{plinkt|Sardine}} +|38 +|{{NA}} +|34 +|{{NA}} +|40 +|{{Members|no}} +|- +|{{plinkt|Herring}} +|41 +|{{NA}} +|38 +|{{NA}} +|50 +|{{Members|no}} +|- +|{{plinkt|Mackerel}} +|45 +|{{NA}} +|42 +|{{NA}} +|60 +|{{Members|yes}} +|- +|{{plinkt|Thin snail meat}} +|47 +|{{NA}} +|43 +|{{NA}} +|70 +|{{Members|yes}} +|- +|{{plinkt|Lean snail meat}} +|47 +|50 +|47 +|{{NA}} +|95 +|{{Members|yes}} +|- +|{{plinkt|Spider on shaft}} +|48 +|{{NA}} +|45 +|{{NA}} +|80 +|{{Members|yes}} +|- +|{{plinkt|Spider on stick}} +|48 +|{{NA}} +|45 +|{{NA}} +|80 +|{{Members|yes}} +|- +|{{plinkt|Paddlefish}} +|{{NA}} +|48 +|{{NA}} +|{{NA}} +|15 +|{{Members|yes}} +|- +|{{plinkt|Trout}} +|49 +|{{NA}} +|46 +|{{NA}} +|70 +|{{Members|no}} +|- +|{{plinkt|Cooked wild kebbit}} +|50 +|{{NA}} +|47 +|{{NA}} +|73 +|{{Members|yes}} +|- +|{{plinkt|Cod}} +|51 +|49 +|46 +|{{NA}} +|75 +|{{Members|yes}} +|- +|{{plinkt|Pike}} +|54 +|{{NA}} +|50 +|{{NA}} +|80 +|{{Members|no}} +|- +|{{plinkt|Fat snail meat}} +|56 +|{{NA}} +|52 +|{{NA}} +|95 +|{{Members|yes}} +|- +|{{plinkt|Salmon}} +|58 +|{{NA}} +|55 +|{{NA}} +|90 +|{{Members|no}} +|- +|{{plinkt|Cooked larupia}} +|59 +|{{NA}} +|55 +|{{NA}} +|92 +|{{Members|yes}} +|- +|{{plinkt|Cooked slimy eel}} +|61 +|{{NA}} +|57 +|{{NA}} +|95 +|{{Members|yes}} +|- +|{{plinkt|Cooked giant crab meat}} +|62 +|{{NA}} +|59 +|{{NA}} +|100 +|{{Members|yes}} +|- +|{{plinkt|Cooked fishcake}} +|62 +|{{NA}} +|59 +|{{NA}} +|100 +|{{Members|yes}} +|- +|{{plinkt|Tuna}} +|63 +|{{NA}} +|59 +|{{NA}} +|100 +|{{Members|no}} +|- +|{{plinkt|Cooked barb-tailed kebbit}} +|63 +|{{NA}} +|60 +|{{NA}} +|106 +|{{Members|yes}} +|- +|{{plinkt|Rainbow fish}} +|64 +|{{NA}} +|60 +|{{NA}} +|110 +|{{Members|yes}} +|- +|{{plinkt|Cave eel}} +|74 +|{{NA}} +|70 +|{{NA}} +|115 +|{{Members|yes}} +|- +|{{plinkt|Cooked graahk}} +|75 +|{{NA}} +|71 +|{{NA}} +|124 +|{{Members|yes}} +|- +|{{plinkt|Bass}} +|79 + +|{{NA}} +|75 +|{{NA}} +|130 +|{{Members|yes}} +|- +|{{plinkt|Cooked pyre fox}} +|93 +|92 +|87 +|{{NA}} +|154 +|{{Members|yes}} +|- +|{{plinkt|Cooked sunlight antelope}} +| - +|95 +|91 +|86 +|175 +|{{Members|yes}} +|- +|{{plinkt|Cooked jubbly}} +|? +|{{NA}} +|{{NA}} +|{{NA}} +|160 +|{{Members|yes}} +|- +|{{plinkt|Cooked chompy}} +|99 +|{{NA}} +|{{NA}} +|{{NA}} +|100 +|{{Members|yes}} +|- +|{{plinkt|Cooked karambwan}} +|99 +|{{NA}} +|93 +|87 +|190 +|{{Members|yes}} +|- +|{{plinkt|Poison karambwan}} +|99 +|{{NA}} +|93 +|87 +|80 +|{{Members|yes}} +|- +|{{plinkt|Roast beast meat}} +|99 +|{{NA}} +|{{NA}} +|{{NA}} +|82.5 +|{{Members|yes}} +|- +|{{plinkt|Roast bird meat}} +|99 +|{{NA}} +|{{NA}} +|{{NA}} +|60 +|{{Members|yes}} +|- +|{{plinkt|Roast rabbit}} +|99 +|{{NA}} +|{{NA}} +|{{NA}} +|72.5 +|{{Members|yes}} +|- +|{{plinkt|Ugthanki meat}} +| - +| - +|95 +|90 +|40 +|{{Members|yes}} +|- +|{{plinkt|Sea turtle}} +| - +| - +| - +| - +|211.3 +|{{Members|yes}} +|- +|{{plinkt|Cooked dashing kebbit}} +| - +| - +| - +| - +|215 +|{{Members|yes}} +|- +|{{plinkt|Dark crab}} +| - +| - +| - +| - +|215 +|{{Members|yes}} +|- +|{{plinkt|Manta ray}} +| - +| - +| - +| - +|216.3 +|{{Members|yes}} +|- +|{{plinkt|Cooked moonlight antelope}} +| - +| - +| - +| - +|220 +|{{Members|yes}} +|} +{{Reflist|group=h}} + +===Baked goods=== +{| class="wikitable sortable align-left-2" style="text-align:center;" +|- +!colspan=2 rowspan=2|Food +!rowspan=2|[[Range]] +!colspan=2|[[Hosidius Kitchen|Hosidius]]{{Note|The Hosidius Kitchen range multiplies the chance-to-not-burn roll by 1.05 or 1.10 with the elite diary completed.|?}} +!rowspan=2|[[Experience]] +!rowspan=2|Members? +|- +!5% +![[Kourend & Kebos Diary#Rewards 4|10%]]The value will be N/A if the level required to not burn with the [[Elite Kourend & Kebos Diary]] completed is lower than the level required to complete the diary (level 84). +|- +|{{plinkt|Bread}} +|38 +|34 +|{{NA}} +|40 +|{{Members|no}} +|- +|{{plinkt|Pitta bread}} +|38 +|{{NA}} +|{{NA}} +|40 +|{{Members|yes}} +|- +|{{plinkt|Redberry pie}} +|45 +|42 +|{{NA}} +|78 +|{{Members|no}} +|- +|{{plinkt|Meat pie}} +|54 +|50 +|{{NA}} +|110 +|{{Members|no}} +|- +|{{plinkt|Apple pie}} +|63 +|59 +|{{NA}} +|130 +|{{Members|no}} +|- +|{{plinkt|Mud pie}} +|63 +|59 +|{{NA}} +|128 +|{{Members|yes}} +|- +|{{plinkt|Plain pizza}} +|68 +|64 +|{{NA}} +|143 +|{{Members|no}} +|- +|{{plinkt|Garden pie}} +|68 +|64 +|{{NA}} +|138 +|{{Members|yes}} +|- +|{{plinkt|Fish pie}} +|74 +|70 +|{{NA}} +|164 +|{{Members|yes}} +|- +|{{plinkt|Cake}} +|74 +|70 +|{{NA}} +|180 +|{{Members|no}} +|- +|{{plinkt|Botanical pie}} +|84 +|80 +|{{NA}} +|180 +|{{Members|yes}} +|- +|{{plinkt|Mushroom pie}} +|89 +|84 +|{{NA}} +|200 +|{{Members|yes}} +|- +|{{plinkt|Admiral pie}} +|94 +|89 +|84 +|210 +|{{Members|yes}} +|- +|{{plinkt|Dragonfruit pie}} +| - +|97 +|92 +|220 +|{{Members|yes}} +|- +|{{plinkt|Wild pie}} +| - +| - +| - +|240 +|{{Members|yes}} +|- +|{{plinkt|Summer pie}} +| - +| - +| - +|260 +|{{Members|yes}} +|} +{{Reflist|group=h}} + +===Other foods=== +{| class="wikitable sortable align-left-2" style="text-align:center;" +|- +!colspan=2 rowspan=2|Food +!rowspan=2|[[Fire]]/[[Range]] +!colspan=2|[[Hosidius Kitchen|Hosidius]]{{Note|The Hosidius Kitchen range multiplies the chance-to-not-burn roll by 1.05 or 1.10 with the elite diary completed.|?}} +!rowspan=2|[[Experience]] +!rowspan=2|Members? +|- +!5% +![[Kourend & Kebos Diary#Rewards 4|10%]]The value will be N/A if the level required to not burn with the [[Elite Kourend & Kebos Diary]] completed is lower than the level required to complete the diary (level 84). +|- +|{{plinkt|Baked potato}} +|41 +|38 +|{{NA}} +|15 +|{{Members|yes}} +|- +|{{plinkt|Scrambled egg}} +|48 +|45 +|{{NA}} +|50 +|{{Members|yes}} +|- +|{{plinkt|Cooked sweetcorn}} +|54 +|50 +|{{NA}} +|104 +|{{Members|yes}} +|- +|{{plinkt|Nettle tea}} +|54 +|50 +|{{NA}} +|52 +|{{Members|yes}} +|- +|{{plinkt|Stew}} +|58 +|55 +|{{NA}} +|117 +|{{Members|no}} +|- +|{{plinkt|Curry}} +|74 +|70 +|{{NA}} +|280 +|{{Members|yes}} +|- +|{{plinkt|Fried onions}} +|77 +|73 +|{{NA}} +|60 +|{{Members|yes}} +|- +|{{plinkt|Fried mushrooms}} +|90 +|85 +|81 +|60 +|{{Members|yes}} +|} +{{Reflist|group=h}} + +===Ruins of Camdozaal fish=== +{| class="wikitable sortable align-left-2" style="text-align:center;" +|- +!colspan=2|Fish +![[Preparation Table]] +![[Experience]] +!Members? +|- +|{{plinkt|Guppy}} +|42 +|12 +|{{Members|no}} +|- +|{{plinkt|Cavefish}} +|53 +|23 +|{{Members|no}} +|- +|{{plinkt|Tetra}} +|61 +|31 +|{{Members|no}} +|- +|{{plinkt|Catfish}} +|78 +|43 +|{{Members|yes}} +|} + +===Gnome cooking=== +{| class="wikitable sortable align-left-2" style="text-align:center;" +|- +!colspan=2 rowspan=2|Food +!rowspan=2|[[Range]] +!colspan=2|[[Hosidius Kitchen|Hosidius]]{{Note|The Hosidius Kitchen range multiplies the chance-to-not-burn roll by 1.05 or 1.10 with the elite diary completed.|?}} +!rowspan=2|[[Experience]] +!rowspan=2|Members? +|- +!5% +![[Kourend & Kebos Diary#Rewards 4|10%]]The value will be N/A if the level required to not burn with the [[Elite Kourend & Kebos Diary]] completed is lower than the level required to complete the diary (level 84). +|- +|{{plinkt|Toad crunchies}} +|38 +|34 +|{{NA}} +|100 +|{{Members|yes}} +|- +|{{plinkt|Spicy crunchies}} +|38 +|34 +|{{NA}} +|100 +|{{Members|yes}} +|- +|{{plinkt|Worm crunchies}} +|38 +|34 +|{{NA}} +|100 +|{{Members|yes}} +|- +|{{plinkt|Chocchip crunchies}} +|38 +|34 +|{{NA}} +|100 +|{{Members|yes}} +|- +|{{plinkt|Fruit batta}} +|38 +|34 +|{{NA}} +|150 +|{{Members|yes}} +|- +|{{plinkt|Toad batta}} +|38 +|34 +|{{NA}} +|152 +|{{Members|yes}} +|- +|{{plinkt|Worm batta}} +|38 +|34 +|{{NA}} +|154 +|{{Members|yes}} +|- +|{{plinkt|Vegetable batta}} +|38 +|34 +|{{NA}} +|156 +|{{Members|yes}} +|- +|{{plinkt|Cheese+tom batta}} +|38 +|34 +|{{NA}} +|158 +|{{Members|yes}} +|- +|{{plinkt|Worm hole}} +|38 +|34 +|{{NA}} +|170 +|{{Members|yes}} +|- +|{{plinkt|Veg ball}} +|38 +|{{NA}} +|{{NA}} +|175 +|{{Members|yes}} +|- +|{{plinkt|Tangled toad's legs}} +|38 +|{{NA}} +|{{NA}} +|185 +|{{Members|yes}} +|- +|{{plinkt|Chocolate bomb}} +|38 +|{{NA}} +|{{NA}} +|190 +|{{Members|yes}} +|} +{{Reflist|group=h}} + +===Raids food=== +{| class="wikitable sortable align-left-2" style="text-align:center;" +|- +!colspan=2|Food +![[Fire]] +![[Experience]] +!Members? +|- +|{{plinkt|Kyren fish (6)|txt=Kyren fish}} +|? +|28 +|{{Members|yes}} +|- +|{{plinkt|Psykk bat (6)|txt=Psykk bat}} +|? +|28 +|{{Members|yes}} +|- +|{{plinkt|Roqed fish (5)|txt=Roqed fish}} +|? +|25 +|{{Members|yes}} +|- +|{{plinkt|Murng bat (5)|txt=Murng bat}} +|? +|25 +|{{Members|yes}} +|- +|{{plinkt|Mycil fish (4)|txt=Mycil fish}} +|? +|22 +|{{Members|yes}} +|- +|{{plinkt|Kryket bat (4)|txt=Kryket bat}} +|? +|22 +|{{Members|yes}} +|- +|{{plinkt|Brawk fish (3)|txt=Brawk fish}} +|? +|19 +|{{Members|yes}} +|- +|{{plinkt|Phluxia bat (3)|txt=Phluxia bat}} +|? +|19 +|{{Members|yes}} +|- +|{{plinkt|Leckish fish (2)|txt=Leckish fish}} +|? +|16 +|{{Members|yes}} +|- +|{{plinkt|Giral bat (2)|txt=Giral bat}} +|? +|16 +|{{Members|yes}} +|- +|{{plinkt|Suphi fish (1)|txt=Suphi fish}} +|? +|13 +|{{Members|yes}} +|- +|{{plinkt|Prael bat (1)|txt=Prael bat}} +|? +|13 +|{{Members|yes}} +|- +|{{plinkt|Pysk fish (0)|txt=Pysk fish}} +|? +|10 +|{{Members|yes}} +|- +|{{plinkt|Guanic bat (0)|txt=Guanic bat}} +|? +|10 +|{{Members|yes}} +|} + +==Obtaining burnt food items== + +If one's Cooking level is too high to obtain a particular burnt food, it is possible to temporarily lower it by making use of the [[chill]] effect or drinking [[Chilhuac red]]. [[Ghommal's hilt]] is particularly useful for this, as it can be used to teleport to the entrance of [[God Wars Dungeon]]. + +{| class="wikitable sortable align-center-1" +!colspan=2|Item +!Obtaining +!Burn level range
(lowest to highest) +!Members? +|- +|{{plinkt|Burnt shrimp}} +|Use on fire for highest rate. +|1-34 +|{{Members|no}} +|- +|{{plinkt|Burnt fish (sardine)}} +|Use on fire for highest rate. +|1-35 +|{{Members|no}} +|- +|{{plinkt|Burnt fish (herring)|txt=Burnt fish}}
([[herring]], [[mackerel]]*) +|Use on fire or collect spawn in Catherby +|5-41, 10-45 +|{{Members|no}} +|- +|{{plinkt|Burnt fish (anchovies)}} +|Use on fire for highest rate,
or collect spawn near the [[Myths' Guild]] +|1-34 +|{{Members|no}} +|- +|{{plinkt|Burnt fish (Chambers of Xeric)|txt=Burnt fish}} ([[Pysk fish (0)|pysk]], [[Suphi fish (1)|suphi]],
[[Leckish fish (2)|leckish]], [[Brawk fish (3)|brawk]], [[Mycil fish (4)|mycil]],
[[Roqed fish (5)|roqed]], [[Kyren fish (6)|kyren]]) +|[[Chambers of Xeric]] +|1, 15, 30,
45, 60, 75, 90 +|{{Members|yes}} +|- +|{{plinkt|Burnt bat}} ([[Guanic bat (0)|guanic]], [[Prael bat (1)|prael]],
[[Giral bat (2)|giral]], [[Phluxia bat (3)|phluxia]], [[Kryket bat (4)|kryket]],
[[Murng bat (5)|murng]], [[Psykk bat (6)|psykk]]) +|[[Chambers of Xeric]] +|1, 15, 30,
45, 60, 75, 90 +|{{Members|yes}} +|- +|{{plinkt|Burnt fish (trout)|txt=Burnt fish}} ([[cod]]*, [[pike]],
[[trout]], [[salmon]]) +|Use on fire for highest rate. +|18-52, 20-59,
15-50, 25-58 +|{{Members|no}} +|- +|{{plinkt|Burnt fish (tuna)|txt=Burnt fish}} ([[bass]]*, [[tuna]]) +|Use on fire for highest rate. +|43-80, 30-63 +|{{Members|no}} +|- +|{{plinkt|Burnt eel}} +|Use on fire for highest rate. +|28-58 +|{{Members|yes}} +|- +|{{plinkt|Burnt cave eel}} +|Use on fire for highest rate. +|38-73 +|{{Members|yes}} +|- +|{{plinkt|Burnt rainbow fish}} +|Use on fire for highest rate. +|35-63 +|{{Members|yes}} +|- +|{{plinkt|Burnt lobster}} +|Use on fire for highest rate. +|40-74 +|{{Members|no}} +|- +|{{plinkt|Burnt swordfish}} +|Use on fire for highest rate. +|45-81 +|{{Members|no}} +|- +|{{plinkt|Burnt karambwan}} +|[[Tai Bwo Wannai Trio]], thorough +|30-99+ +|{{Members|yes}} +|- +|{{plinkt|Burnt monkfish}} +|Use on fire for highest rate. +|62-92 +|{{Members|yes}} +|- +|{{plinkt|Burnt shark}} +|Use on fire for highest rate. +|80-99 +|{{Members|yes}} +|- +|{{plinkt|Burnt sea turtle}} +|Use on fire for highest rate. +|82-99+ +|{{Members|yes}} +|- +|{{plinkt|Burnt anglerfish}} +|Use on fire for highest rate. +|84-99 +|{{Members|yes}} +|- +|{{plinkt|Burnt dark crab}} +|Use on fire for highest rate. +|90-99+ +|{{Members|yes}} +|- +|{{plinkt|Burnt manta ray}} +|Use on fire for highest rate. +|91-99+ +|{{Members|yes}} +|- +|{{plinkt|Burnt bread}} +|[[Cooking range|Range]] only, [[Imp]] drop +|1-37 +|{{Members|no}} +|- +|{{plinkt|Burnt pie}} ([[Mud pie|mud]]*, [[Meat pie|meat]],
[[Redberry pie|redberry]], [[Apple pie|apple]], [[Garden pie|garden]]*,
[[Fish pie|fish]]*, [[Botanical pie|botanical]]*, [[Admiral pie|admiral]]*,
[[Wild pie|wild]]*, [[Summer pie|summer]]) +|[[Cooking range|Range]] only +|29, 30, 10-50,
30, 34, 47, 52,
70-94, 85-99, 95-99 +|{{Members|no}} +|- +|{{plinkt|Burnt pizza}} ([[Plain pizza|plain]], [[Meat pizza|meat]],
[[Anchovy pizza|anchovy]], [[Pineapple pizza|pineapple]]*) +|[[Cooking range|Range]] only +|35-67 +|{{Members|no}} +|- +|{{plinkt|Burnt cake}}
([[cake]], [[chocolate cake]]) +|[[Cooking range|Range]] only +|55 +|{{Members|no}} +|- +|{{plinkt|Burnt chicken}} +|[[Cooked chicken|Cooked item]] -> fire +|1-31 +|{{Members|no}} +|- +|{{plinkt|Burnt meat}} +|[[Cooked meat|Cooked item]] -> fire, [[imp]] drop, spawn in Weiss +|1-31 +|{{Members|no}} +|- +|{{plinkt|Burnt rabbit}} +|[[Iron spit]] required +|1 +|{{Members|yes}} +|- +|{{plinkt|Burnt bird meat}} +|[[Iron spit]] required +|11 +|{{Members|yes}} +|- +|{{plinkt|Burnt snail}}
([[Lean snail meat|lean]], [[Thin snail meat|thin]], [[Fat snail meat|fat]]) +|Use on fire for highest rate. +|17, 12, 22 +|{{Members|yes}} +|- +|{{plinkt|Burnt spider|txt=Burnt spider (stick)}} +|[[Skewer stick]], fire highest rate. +|16-45 +|{{Members|yes}} +|- +|{{plinkt|Burnt beast meat}} +|[[Iron spit]] required +|21 +|{{Members|yes}} +|- +|{{plinkt|Ruined chompy}} +|Use on fire for highest rate. +|30 +|{{Members|yes}} +|- +|{{plinkt|Burnt jubbly}} +|Self-obtain, [[Rantz]]/[[Jiggig]] spit,
'''partial''' [[Recipe for Disaster]] +|41 +|{{Members|yes}} +|- +|{{plinkt|Burnt oomlie}} +|[[Raw oomlie|Raw item]] -> fire. +|50 +|{{Members|yes}} +|- +|{{plinkt|Burnt oomlie wrap}} +|see on [[Burnt oomlie wrap]]. +|1-44 +|{{Members|yes}} +|- +|{{plinkt|Burnt egg}} +|[[Cooking range|Range]] only +|13 +|{{Members|yes}} +|- +|{{plinkt|Burnt onion}} +|[[Cooking range|Range]] only +|42 +|{{Members|yes}} +|- +|{{plinkt|Burnt mushroom}} +|[[Cooking range|Range]] only +|46 +|{{Members|yes}} +|- +|{{plinkt|Burnt stew}} +|[[Cooking range|Range]] only +|25-57 +|{{Members|no}} +|- +|{{plinkt|Burnt curry|pic=Burnt stew}} +| +|60-73 +|{{Members|yes}} +|- +|{{plinkt|Burnt potato}} +|[[Cooking range|Range]] only +|1-41 +|{{Members|yes}} +|- +|{{plinkt|Burnt crunchies}} +|[[Gnome Restaurant]] +|10 +|{{Members|yes}} +|- +|{{plinkt|Burnt batta}} +|[[Gnome Restaurant]] +|20 +|{{Members|yes}} +|- +|{{plinkt|Burnt sweetcorn}} +|Use on fire for highest rate. +|28-53 +|{{Members|yes}} +|- +|{{plinkt|Burnt gnomebowl}} +|[[Gnome Restaurant]] +|30 +|{{Members|yes}} +|- +|{{plinkt|Spider on shaft (burnt)}} +|[[Arrow shaft]], fire highest rate. +|16-45 +|{{Members|yes}} +|} + +[[Category:Food]] +[[Category:Cooking]] diff --git a/wikidata/burnt_food.wikisrc b/wikidata/burnt_food.wikisrc new file mode 100644 index 00000000..5efbb1b0 --- /dev/null +++ b/wikidata/burnt_food.wikisrc @@ -0,0 +1,303 @@ +{{External|rs|rsc|dw}} +{{Otheruses|all the forms of burnt food|when food stops burning|Cooking/Burn level}} +'''Burnt food''' is the result of a normal occurrence when [[Cooking]]. Burning food happens when the player's Cooking level is not high enough to not burn the food, and the chance of burning decreases as the higher Cooking level the player has. Most food will eventually stop burning at a certain cooking level; however, some foods always have a chance to burn unless wearing a [[Cooking cape]]. [[Meat]] and [[chicken]] can also be burnt by trying to cook their cooked variants. When cooking, a [[fire]] has the highest chance to burn food, using a [[range]] decreases the chance, reduced further with some foods when using the [[cooking gauntlets]], [[Cooking range (Lumbridge Castle)|Lumbridge Castle cooking range]], or the [[Hosidius Kitchen]]. + +Although selling burnt food to [[general store]]s yields {{NoCoins|0}} coins and is not tradeable on the Grand Exchange, some player collectors may pay for them, though prices vary and are dependent on the type and quantity of food. + +There are currently 48 unique varieties of burnt food which are obtainable and tradeable between player collectors, 50 including [[ruined herb tea]] and [[Ugthanki kebab (smelling)]]. + +==Types of burnt food== +{|class="wikitable sortable lighttable" +! +!Item +!Raw version +!Cooking level +!Cooked version +|- +|{{plinkt|Burnt bat}} +|Varies +|1 +|Varies +|- +|{{plinkt|Burnt bread}} +|[[Bread dough]] +|1 +|[[Bread]] +|- +|{{plinkt|Burnt chicken}} +|[[Raw chicken]] +|1 +|[[Cooked chicken]] +|- +|{{plinkt|Burnt fish (Chambers of Xeric)|txt=Burnt fish}} +|Varies +|1 +|Varies +|- +|{{plinkt|Burnt meat}} +|[[Raw meat]] +|1 +|[[Cooked meat]] +|- +|{{plinkt|Burnt shrimp}} +|[[Raw shrimp]] +|1 +|[[Shrimp]] +|- +|{{plinkt|Burnt fish (herring)|txt=Burnt fish}} +|[[Raw herring]]/[[Raw mackerel]] +|5 +|[[Herring]]/[[Mackerel]] +|- +|{{plinkt|Burnt fish (sardine)|txt=Burnt fish}} +|[[Raw sardine]] +|5 +|[[Sardine]] +|- +|{{plinkt|Burnt potato}} +|[[Potato]] +|7 +|[[Baked potato]] +|- +|{{plinkt|Burnt crunchies}} +|[[Raw crunchies]] +|10 +|[[Half baked crunchy]] +|- +|{{plinkt|Burnt fish (anchovies)|txt=Burnt fish}} +|[[Raw anchovies]] +|10 +|[[Anchovies]] +|- +|{{plinkt|Burnt pie}} +|[[Raw pies]] +|10 +|[[Pies]] +|- +|{{plinkt|Burnt bird meat}} +|[[Raw bird meat]] +|11 +|[[Roast bird meat]] +|- +|{{plinkt|Burnt snail}} +|[[Thin snail]]/[[Lean snail]]/[[Fat snail]] +|12 +|[[Thin snail meat]]/[[Lean snail meat]]/[[Fat snail meat]] +|- +|{{plinkt|Burnt egg}} +|[[Uncooked egg]] +|13 +|[[Scrambled egg]] +|- +|{{plinkt|Burnt rabbit}} +|[[Skewered rabbit]] +|16 +|[[Roast rabbit]] +|- +|{{plinkt|Burnt spider}} +|[[Spider on stick]] +|16 +|[[Spider on stick]] +|- +|{{plinkt|Spider on shaft (burnt)}} +|[[Spider on shaft]] +|16 +|[[Spider on shaft]] +|- +|{{plinkt|Burnt fish (trout)|txt=Burnt fish}} +|[[Raw cod]]/[[Raw pike]]/[[Raw trout]]/[[Raw salmon]] +|18 +|[[Cod]]/[[Pike]]/[[Trout]]/[[Salmon]] +|- +|{{plinkt|Burnt batta}} +|[[Raw batta]] +|20 +|[[Half baked batta]] +|- +|{{plinkt|Burnt beast meat}} +|[[Raw beast meat]] +|21 +|[[Roast beast meat]] +|- +|{{plinkt|Burnt giant crab meat}}These items are untradeable. +|[[Giant crab meat]] +|21 +|[[Cooked giant crab meat]] +|- +|{{plinkt|Burnt kebbit}} +|[[Raw wild kebbit]]/[[raw barb-tailed kebbit|barb-tailed kebbit]]/[[raw dashing kebbit|dashing kebbit]] +|23 +|[[Cooked wild kebbit]]/[[cooked barb-tailed kebbit|barb-tailed kebbit]]/[[cooked dashing kebbit|dashing kebbit]] +|- +|{{plinkt|Burnt stew}} +|[[Uncooked stew]] +|25 +|[[Stew]] +|- +|{{plinkt|Burnt eel}} +|[[Slimy eel]] +|28 +|[[Cooked slimy eel]] +|- +|{{plinkt|Burnt sweetcorn}} +|[[Sweetcorn]] +|28 +|[[Cooked sweetcorn]] +|- +|{{plinkt|Burnt fish (tuna)|txt=Burnt fish}} +|[[Raw bass]]/[[Raw tuna]] +|30 +|[[Bass]]/[[Tuna]] +|- +|{{plinkt|Burnt gnomebowl}} +|[[Raw gnomebowl]] +|30 +|[[Half baked bowl]] +|- +|{{plinkt|Burnt karambwan}} +|[[Raw karambwan]] +|30 +|[[Cooked karambwan]] +|- +|{{plinkt|Ruined chompy}} +|[[Raw chompy]] +|30 +|[[Cooked chompy]] +|- +|{{plinkt|Burnt fishcake}} +|[[Raw fishcake]] +|31 +|[[Cooked fishcake]] +|- +|{{plinkt|Burnt large beast}} +|[[Raw larupia]]/[[raw graahk|graahk]]/[[raw kyatt|kyatt]] +|31 +|[[Cooked larupia]]/[[cooked graahk|graahk]]/[[cooked kyatt|kyatt]] +|- +|{{plinkt|Burnt pizza}} +|[[Uncooked pizza]] +|35 +|[[Pizza]] +|- +|{{plinkt|Burnt rainbow fish}} +|[[Raw rainbow fish]] +|35 +|[[Rainbow fish]] +|- +|{{plinkt|Burnt cave eel}} +|[[Raw cave eel]] +|38 +|[[Cave eel]] +|- +|{{plinkt|Burnt cake}} +|[[Uncooked cake]] +|40 +|[[Cake]] +|- +|{{plinkt|Burnt lobster}} +|[[Raw lobster]] +|40 +|[[Lobster]] +|- +|{{plinkt|Burnt jubbly}} +|[[Raw jubbly]] +|41 +|[[Cooked jubbly]] +|- +|{{plinkt|Burnt onion}} +|[[Chopped onion]] +|42 +|[[Fried onions]] +|- +|{{plinkt|Burnt swordfish}} +|[[Raw swordfish]] +|45 +|[[Swordfish]] +|- +|{{plinkt|Burnt mushroom}} +|[[Sliced mushrooms]] +|46 +|[[Fried mushrooms]] +|- +|{{plinkt|Burnt oomlie}} +|[[Raw oomlie]] +|50 +|None +|- +|{{plinkt|Burnt oomlie wrap}} +|[[Wrapped oomlie]] +|50 +|[[Oomlie wrap]] +|- +|{{plinkt|Burnt pitta bread}}{{CiteTwitter|author=Mod Ash|url=https://twitter.com/JagexAsh/status/985833852022206464|date=16 April 2018|archiveurl=https://archive.is/2hUgv|archivedate=26 May 2020|quote=Yeah, it looks like the fail chance is already 0 by the time you have the minimum level.}} +|[[Pitta dough]] +|58 +|[[Pitta bread]] +|- +|{{plinkt|Burnt fox meat}} +|[[Raw pyre fox]] +|59 +|[[Cooked pyre fox]] +|- +|{{plinkp|Burnt stew}} +|[[Burnt curry]] +|[[Uncooked curry]] +|60 +|[[Curry]] +|- +|{{plinkt|Burnt monkfish}} +|[[Raw monkfish]] +|62 +|[[Monkfish]] +|- +|{{plinkt|Burnt antelope}} +|[[Raw sunlight antelope]]/[[Raw moonlight antelope|moonlight antelope]] +|68 +|[[Cooked sunlight antelope]]/[[Cooked moonlight antelope|moonlight antelope]] +|- +|{{plinkt|Snake over-cooked}} +|[[Raw stuffed snake]] +|70 +|[[Stuffed snake]] +|- +|{{plinkt|Burnt shark}} +|[[Raw shark]] +|80 +|[[Shark]] +|- +|{{plinkt|Burnt sea turtle}} +|[[Raw sea turtle]] +|82 +|[[Sea turtle]] +|- +|{{plinkt|Burnt anglerfish}} +|[[Raw anglerfish]] +|84 +|[[Anglerfish]] +|- +|{{plinkt|Burnt dark crab}} +|[[Raw dark crab]] +|90 +|[[Dark crab]] +|- +|{{plinkt|Burnt manta ray}} +|[[Raw manta ray]] +|91 +|[[Manta ray]] +|} + +==Burn level== +{{Main|Cooking/Burn level}} +==See also== +*[[Food]] +*[[Cooking]] + +==Trivia== +*[[Ruined chompy]], [[spider on shaft (burnt)|spider on shaft]], and [[snake over-cooked]] are the only burnt food items without 'burnt' in the name. +*Burnt foods do not leave [[placeholder]]s when withdrawn from the bank. + +==References== +{{Reflist}} +{{Burnt food}} +[[Category:Food]] +[[Category:Cooking]] diff --git a/wikidata/cooking.wikisrc b/wikidata/cooking.wikisrc new file mode 100644 index 00000000..95e923e7 --- /dev/null +++ b/wikidata/cooking.wikisrc @@ -0,0 +1,788 @@ +{{External|rs|rsc|dw}} +{{Otheruses|def=no|a list of all requirements and unlockables within the Cooking skill|Cooking/Level up table}} +{{Has calculator|Calculator:Cooking}} +{{Has skill guide|members=Pay-to-play Cooking training|free=Free-to-play Cooking training|iron=Ironman Guide/Cooking|UIM=Ultimate Ironman Guide/Cooking}} +{{Infobox Skill +|name = Cooking +|image = [[File:Cooking icon.png]] +|release = [[4 January]] [[2001]] +|update = Runescape beta is now online! +|aka = Cook +|members = No +|type = Production +}} +[[File:Cooking icon (detail).png|left]] +'''Cooking''' is a [[skill]] that allows raw [[food]] to be made edible, healing [[hitpoints]] when eaten. To do this, the player uses a raw, cookable food on a [[range]] or [[fire]]. + +Depending on the player's Cooking level, food will sometimes burn, becoming unusable. Ranges burn food less often than fires at the same level, and some foods can only be cooked on ranges. Some ranges, such as the [[Cooking range (Lumbridge Castle)|one]] in the [[Lumbridge Castle]] or in the [[Hosidius Kitchen]], burn food less often than a normal range. + +Cooking goes hand-in-hand with the [[Fishing]] skill as the player can cook the fish they obtain. If no range is nearby, having an [[axe]] and [[tinderbox]] on hand can allow the player to cut down a tree and make a fire to cook the fish on. + +By levelling Cooking, the player is able to cook better foods such as [[swordfish]], [[shark]], [[pies]], and [[pizza]]s. If a player achieves 32 cooking, they can access the [[Cooks' Guild|Cook's Guild]] near the Grand Exchange. + +{{Listen +|align = right +|title = Cooking level up - normal +|filename = Cooking Level Up!.ogg +|desc = The music that plays when levelling up.}} + +{{Listen +|align = right +|title = Cooking level up - with unlocks +|filename = Cooking Level Up! (Unlocks).ogg +|desc = The music that plays when levelling up and unlocking new content.}} + +==How to cook== +Cooking is known as one of the fastest skills to train, as players can cook in many different ways as well as being able to simply buy their raw food items from the [[Grand Exchange]]. + +Before the Grand Exchange was created, the bulk of players usually fished and then cooked their catches. Generally a player who is manually gathering their raw items will cook their food items on a local [[Fire|campfire]] created through the [[Firemaking]] skill near where they are gathering, or take the items they have obtained to a [[range]] and cook there. + +Ranges (which provide a lower burn rate) can be easily located and are almost always well labelled on the [[World map|map]] as a cooking pan ([[File:Cooking range icon.png|The cooking range icon on the map]]) [[icon]]. There are other assorted things that a player can cook on, seen in NPC camps, or on [[iron spit]]s. It is important to note that only meat, [[fish]] and [[stew]] can be cooked on an open fire. Foods like [[bread]], [[cake]], and [[pie]] must be cooked on a proper range, Most of these food items will generate an error message if the player attempts to cook it improperly while others, such as raw potatoes, will simply all burn. Raw foods loosely related to the [[Hunter]] skill, such as [[raw beast meat]], [[raw chompy]], and [[raw rabbit meat|rabbit]], must be cooked on an iron spit. + +To actually cook something, players have to "use" their raw food item on a range or a campfire. If they have more than one food item of the same kind in their inventory, a picture of the food item will appear in the dialogue box. Ranges can also be left-clicked to automatically bring up this interface. The player can right-click on the picture and select how many they want to cook, or left click to cook all of them (default option). + +If this is your first time cooking follow these steps for maximum effect: + +* Cook on the [[Cooking range (Lumbridge Castle)|Lumbridge Castle range]] after completion of [[Cook's Assistant]], as there is a bank directly upstairs and the range offers a lower burn rate than other ranges on selected foods. +* Cooking at the [[Rogues' Den]] has a permanent fire and is directly next to a banker ''([[members]] only)''. +* Consider completing [[Kourend & Kebos Diary#Easy|Easy]] Kourend and Kebos diary for 5% increased chance to succeed cooking anything when cooking in Hosidius range and completing [[Family Crest|Family Crest quest]] to gain increased chance of cooking successfully on [[Cooking gauntlets|selected few raw foods]]. + +==Burning food== +{{main|Burnt food}} +As players train Cooking, they will sometimes fail to cook something at random, resulting in no Cooking experience gained. It is normal when you first begin training this skill to burn nearly anything you cook on a fire or range, but as you gain more levels the burn ratio of food decreases until you reach a level where you can no longer burn them. + +A table of the levels where cooking food items becomes successful 100% of the time can be found [[Cooking/Burn level|here]]. + +A useful item to equip while training are [[cooking gauntlets]]. Wearing these gloves while training Cooking will cut down time and money due to less food being burnt. This is useful for food such as [[shark]]s where even at 99 you have the chance to burn them; with the cooking gauntlets equipped, you will stop burning sharks at level 94. Alternatively, cooking food while wearing a [[cooking cape]] will ensure that no food may be burned by the player. + +All [[range]]s have a lower burn rate than [[Fire|fires]], but there are also special ranges which offer decreased burn rates. These can work in conjunction with the cooking gauntlets. Unless the player is cooking something with 100% success rate, it is recommended to use these where possible to decrease the amount of burnt food. The recommended range to cook on for members is in the [[Hosidius Kitchen]], usable after completion of the [[Kourend & Kebos Diary#Easy|Easy Kourend & Kebos Diary]]. This range grants a 5% increased chance to successfully cook food (10% if [[Kourend & Kebos Diary#Elite|Elite Kourend & Kebos Diary]] is completed) and is very close to a bank chest. + +The [[Cooking range (Lumbridge Castle)|range]] in Lumbridge Castle also has a lower burn rate for some foods, usable after completing the [[Cook's Assistant]] quest. The nearest bank to this range (for members) is the [[Culinaromancer's Chest]] in the cellar, which requires the first part of the [[Recipe for Disaster]] quest to be completed, or the bank at the top of [[Lumbridge Castle]] for free players. + +==Items needed== +As Cooking is the skill of turning food from raw to edible, and there is a very wide range of available food types in ''RuneScape'', there are many items that players need in order to cook food. Depending on what you are cooking, you will need a variety of items such as water or flour. Listed below are the cardinal cooking items which are used to make the most common types of food. + +* [[Fish]] ([[raw lobster]], [[raw trout]], etc.) +* [[Flour]] (held in a [[pot]]) +* [[Water]] (Held in a [[bucket]], [[bowl]], [[vial]] or [[jug]]) +* [[Milk]] (held in a bucket) +* [[Meat]] ([[raw meat]], [[raw rat meat]], [[raw bear meat]], [[raw yak meat]], [[raw chicken]]) +* Vegetables ([[cabbage]]s, [[grain]], [[onion]]s, [[potato]]es) +* Fruits ([[cooking apple]]s, [[grapes]], [[banana]]s, [[redberries]], [[tomato]]es) +* [[Cheese]] +* [[Bowl]] +* [[Bucket]] +* [[Cake tin]] +* [[Jug]] +* [[Pie dish]] +* [[Pot]] +* [[Knife]] + +==Types of food== +===Meat / fish=== +{| class="wikitable sortable align-left-3" style="text-align:center;" +!Level +! colspan="2" |Item +! data-sort-type="number" |XP +! data-sort-type="number" |Healing +!Members +|- +|1||{{plinkt|Cooked meat}}||30||3||{{members|No}} +|- +|1||{{plinkt|Sinew}}||3||{{NA}}||{{members|Yes}} +|- +|1||{{plinkt|Shrimps}}||30||3||{{members|No}} +|- +|1||{{plinkt|Cooked chicken}}||30||3||{{members|No}} +|- +|1||{{plinkt|Cooked rabbit}}||30||5||{{members|Yes}} +|- +|1||{{plinkt|Anchovies}}||30||1||{{members|No}} +|- +|1||{{plinkt|Sardine}}||40||4||{{members|No}} +|- +|1||{{plinkt|Poison karambwan}}||80||-5||{{members|Yes}} +|- +|1||{{plinkt|Ugthanki meat}}||40||3||{{members|Yes}} +|- +|5||{{plinkt|Herring}}||50||5||{{members|No}} +|- +|7||{{plinkt|Guppy}}||12||{{NA}}||{{members|No}} +|- +|10||{{plinkt|Mackerel}}||60||6||{{members|Yes}} +|- +|11||{{plinkt|Roast bird meat}}||60||6||{{members|Yes}} +|- +|12||{{plinkt|Thin snail}}||70|| data-sort-value="6" |5-7||{{members|Yes}} +|- +|15||{{plinkt|Trout}}||70||7||{{members|No}} +|- +|16||{{plinkt|Spider on stick}}||80|| data-sort-value="8.5" |7-10||{{members|Yes}} +|- +|16||{{plinkt|Spider on shaft}}||80|| data-sort-value="8.5" |7-10||{{members|Yes}} +|- +|16||{{plinkt|Roast rabbit}}||70||7||{{members|Yes}} +|- +|17||{{plinkt|Lean snail}}||80||5-8||{{members|Yes}} +|- +|18||{{plinkt|Cod}}||75||7||{{members|Yes}} +|- +|20||{{plinkt|Pike}}||80||8||{{members|No}} +|- +|20||{{plinkt|Cavefish}}||23||{{NA}}||{{members|No}} +|- +|21||{{plinkt|Roast beast meat}}||82.5||8||{{members|Yes}} +|- +|21||{{plinkt|Red crab meat}}||85||8||{{members|Yes}} +|- +|21||{{plinkt|Cooked giant crab meat}}||100||10||{{members|Yes}} +|- +|22||{{plinkt|Fat snail}}||95|| data-sort-value="8" |7-9||{{members|Yes}} +|- +|23||{{plinkt|Cooked wild kebbit}}||73|| data-sort-value="8" |4+4 (8)||{{members|Yes}} +|- +|25||{{plinkt|Salmon}}||90||9||{{members|No}} +|- +|28||{{plinkt|Slimy eel}}||95|| data-sort-value="8" |6-10||{{members|Yes}} +|- +|30||{{plinkt|Tuna}}||100||10||{{members|No}} +|- +|30||{{plinkt|Cooked karambwan}}||190||18||{{members|Yes}} +|- +|30||{{plinkt|Cooked chompy}}||100||10||{{members|Yes}} +|- +|31||{{plinkt|Cooked fishcake}}||100||11||{{members|Yes}} +|- +|31||{{plinkt|Cooked larupia}}||92|| data-sort-value="11" |6+5 (11)||{{members|Yes}} +|- +|32||{{plinkt|Cooked barb-tailed kebbit}}||106|| data-sort-value="12" |7+5 (12)||{{members|Yes}} +|- +|33||{{plinkt|Tetra}}||31||{{NA}}||{{members|No}} +|- +|35||{{plinkt|Rainbow fish}}||110||11||{{members|Yes}} +|- +|38||{{plinkt|Cave eel}}||115|| data-sort-value="9" |7-11||{{members|Yes}} +|- +|40||{{plinkt|Lobster}}||120||12||{{members|No}} +|- +|41||{{plinkt|Cooked jubbly}}||160||15||{{members|Yes}} +|- +|41||{{plinkt|Cooked graahk}}||124|| data-sort-value="14" |8+6 (14)||{{members|Yes}} +|- +|43||{{plinkt|Bass}}||130||13||{{members|Yes}} +|- +|45||{{plinkt|Swordfish}}||140||14||{{members|No}} +|- +|46||{{plinkt|Catfish}}||43||{{NA}}||{{members|Yes}} +|- +|51||{{plinkt|Cooked kyatt}}||143|| data-sort-value="17" |9+8 (17)||{{members|Yes}} +|- +|53||{{plinkt|Lava eel}}||30||14||{{members|Yes}} +|- +|56||{{plinkt|Swordtip squid}}||150||15||{{members|Yes}} +|- +|59||{{plinkt|Cooked pyre fox}}||154|| data-sort-value="19" |11+8 (19)||{{members|Yes}} +|- +|62||{{plinkt|Monkfish}}||150||16||{{members|Yes}} +|- +|68||{{plinkt|Cooked sunlight antelope}}||175|| data-sort-value="21" |12+9 (21)||{{members|Yes}} +|- +|69||{{plinkt|Giant krill}}||177.5||17||{{members|Yes}} +|- +|71||{{plinkt|Jumbo squid}}||180||17||{{members|Yes}} +|- +|72||{{plinkt|Sacred eel}}|| data-sort-value="109" |109-124||{{NA}}||{{members|Yes}} +|- +|73||{{plinkt|Haddock}}||180||18||{{members|Yes}} +|- +|79||{{plinkt|Yellowfin}}||200||19||{{members|Yes}} +|- +|80||{{plinkt|Shark}}||210||20||{{members|Yes}} +|- +|82||{{plinkt|Sea turtle}}||211.3||21||{{members|Yes}} +|- +|82||{{plinkt|Cooked dashing kebbit}}||215|| data-sort-value="23" |13+10 (23)||{{members|Yes}} +|- +|83||{{plinkt|Halibut}}||212.5||20||{{members|Yes}} +|- +|84||{{plinkt|Anglerfish}}||230|| data-sort-value="22" |3-22||{{members|Yes}} +|- +|87||{{plinkt|Bluefin}}||215||data-sort-value="22"|22||{{members|Yes}} +|- +|90||{{plinkt|Dark crab}}||215||22||{{members|Yes}} +|- +|91||{{plinkt|Manta ray}}||216.2||22||{{members|Yes}} +|- +|91||{{plinkt|Marlin}}||225||24||{{members|Yes}} +|- +|92||{{plinkt|Cooked moonlight antelope}}||220|| data-sort-value="26" |14+12 (26)||{{members|Yes}} +|- +|} + +===Bread=== +{| class="wikitable sortable align-left-3" style="text-align:center;" +!Level +! colspan=2 |Item +! data-sort-type="number" |XP +! data-sort-type="number" |Healing +!Members +|- +|1||{{plinkt|Bread}}||40||5||{{members|No}} +|- +|58||{{plinkt|Pitta bread}}||40||{{NA}}||{{members|Yes}} +|} + +===Pies=== +{| class="wikitable sortable align-left-3 align-left-6" style="text-align:center;" +!Level +! colspan=2 |Item +! data-sort-type="number" |XP +! data-sort-type="number" |Healing +!Effect +!Members +|- +|10||{{plinkt|Redberry pie}}||78||10||None||{{members|No}} +|- +|20||{{plinkt|Meat pie}}||110||12||None||{{members|No}} +|- +|29||{{plinkt|Mud pie}}||128||0||Thrown at enemies||{{members|Yes}} +|- +|30||{{plinkt|Apple pie}}||130||14||None||{{members|No}} +|- +|34||{{plinkt|Garden pie}}||138||12||+3 [[Farming]]||{{members|Yes}} +|- +|47||{{plinkt|Fish pie}}||164||12||+3 [[Fishing]]||{{members|Yes}} +|- +|52||{{plinkt|Botanical pie}}||180||12||+4 [[Herblore]]||{{members|Yes}} +|- +|60||{{plinkt|Mushroom pie}}||200||16||+4 [[Crafting]]||{{members|Yes}} +|- +|70||{{plinkt|Admiral pie}}||210||16||+5 [[Fishing]]||{{members|Yes}} +|- +|73||{{plinkt|Dragonfruit pie}}||220||20||+4 [[Fletching]]||{{members|Yes}} +|- +|85||{{plinkt|Wild pie}}||240||22||+4 [[Ranged]], +5 [[Slayer]]||{{members|Yes}} +|- +|95||{{plinkt|Summer pie}}||260||22||+5 [[Agility]]||{{members|Yes}} +|} + +===Stews=== +{| class="wikitable sortable align-left-3" style="text-align:center;" +!Level +! colspan=2 |Item +! data-sort-type="number" |XP +! data-sort-type="number" |Healing +!Members +|- +|25||{{plinkt|Stew}}||117||11||{{members|No}} +|- +|60||{{plinkt|Curry}}||280||19||{{members|Yes}} +|} + +===Pizzas=== +{| class="wikitable sortable align-left-3" style="text-align:center;" +!Level +! colspan=2 |Item +!XP +!Healing +!Members +|- +|35||{{plinkt|Plain pizza}}||143||14||{{members|No}} +|- +|45||{{plinkt|Meat pizza}}||169||16||{{members|No}} +|- +|55||{{plinkt|Anchovy pizza}}||182||18||{{members|No}} +|- +|65||{{plinkt|Pineapple pizza}}||195||22||{{members|Yes}} +|} + +===Cakes=== +{| class="wikitable sortable align-left-3" style="text-align:center;" +!Level +! colspan=2 |Item +! data-sort-type="number" |XP +! data-sort-type="number" |Healing +!Members +|- +|40||{{plinkt|Cake}}||180||12||{{members|No}} +|- +|50||{{plinkt|Chocolate cake}}||210||15||{{members|No}} +|} + +===Wine=== +{| class="wikitable sortable align-left-3" style="text-align:center;" +!Level +! colspan=2 |Item +! data-sort-type="number" |XP +! data-sort-type="number" |Healing +!Members +|- +|35||{{plinkt|Jug of wine}}||200||11||{{members|No}} +|- +|65||{{plinkt|Wine of zamorak}}||200||{{NA}}||{{members|Yes}} +|} +Note that every wine made resets the twelve second fermentation of the previously made wines, resulting in an enormous experience drop if a series of inventories are made fast enough. It is one of the fastest methods for reaching 99 Cooking (yielding 400k+ experience per hour if done optimally) and the cost of the required ingredients are low, but is not profitable unlike almost all other cooking methods. This method is also accessible to free-to-play players. + +===Hot Drinks=== +{| class="wikitable sortable align-left-3" style="text-align:center;" +!Level +! colspan=2 |Item +! data-sort-type="number" |XP +! data-sort-type="number" |Healing +!Notes +!Members +|- +|20||{{plinkt|Cup of tea (nettle)|txt=Cup of tea}}||52||3||Restores 5% [[energy]].||{{members|Yes}} +|} + +===Vegetable=== +{| class="wikitable sortable align-left-3" style="text-align:center;" +!Level +! colspan=2 |Item +! data-sort-type="number" |XP +! data-sort-type="number" |Healing +!Members +|- +|7||{{plinkt|Baked potato}}||15||4||{{members|Yes}} +|- +|9||{{plinkt|Spicy sauce}}||25||2||{{members|Yes}} +|- +|11||{{plinkt|Chilli con carne}}||25||5||{{members|Yes}} +|- +|13||{{plinkt|Scrambled egg}}||50||5||{{members|Yes}} +|- +|23||{{plinkt|Egg and tomato}}||0||8||{{members|Yes}} +|- +|28||{{plinkt|Cooked sweetcorn}}||104|| data-sort-value="10" |1-10||{{members|Yes}} +|- +|39||{{plinkt|Potato with butter}}||40||14||{{members|Yes}} +|- +|41||{{plinkt|Chilli potato}}||15||14||{{members|Yes}} +|- +|42||{{plinkt|Fried onions}}||60||5||{{members|Yes}} +|- +|46||{{plinkt|Fried mushrooms}}||60||5||{{members|Yes}} +|- +|47||{{plinkt|Potato with cheese}}||40||16||{{members|Yes}} +|- +|51||{{plinkt|Egg potato}}||45||16||{{members|Yes}} +|- +|57||{{plinkt|Mushroom & onion}}||120||11||{{members|Yes}} +|- +|64||{{plinkt|Mushroom potato}}||55||20||{{members|Yes}} +|- +|67||{{plinkt|Tuna and corn}}||0||13||{{members|Yes}} +|- +|68||{{plinkt|Tuna potato}}||10||22||{{members|Yes}} +|} + +===Dairy=== +{| class="wikitable sortable align-left-3" style="text-align:center;" +!Level +! colspan=2 |Item +! data-sort-type="number" |XP +! data-sort-type="number" |Healing +!Members +|- +|21||{{plinkt|Pot of cream}}||18||1||{{members|Yes}} +|- +|38||{{plinkt|Pat of butter}}||40.5||{{NA}}||{{members|Yes}} +|- +|48||{{plinkt|Cheese}}||64||2||{{members|Yes}} +|} + +===Kebabs=== +{| class="wikitable sortable align-left-3" style="text-align:center;" +!Level +! colspan=2 |Item +! data-sort-type="number" |XP +! data-sort-type="number" |Healing +!Members +|- +|1||{{plinkt|Ugthanki kebab}}||40||19||{{members|Yes}} +|} + +==Brewing== +[[File:Brewing vat.png|thumb|200px|A brewing vat used to create ales.]] +{{main|Brewing}} +Brewing involves the fermenting of raw ingredients into [[ale]]s or [[cider]]. [[Brewing]] is useful because most products [[boost]] certain [[skill]]s. The process, however, is quite slow and is not a viable means of training. These [[alcohol]]ic [[drink]]s are not useful for healing, unlike most [[food]] made with Cooking. Brewing takes place at three [[fermenting vat]]s, with one located in eastern [[Keldagrim]] on the {{FloorNumber|uk=1}} of the [[Laughing Miner Pub]], one in [[Port Phasmatys]] underneath [[The Green Ghost]] pub, and one on [[Aldarin]] at the [[Moonrise Brewery and Winery]]. Only one brew can be made in a vat at a time. + +During the brewing process it is possible for an ale to mature, normally a 5% chance, or 64% when adding [[the stuff]]. The stuff '''cannot''' be added to cider. Mature ales have stronger [[boost]]s. It can also turn into bad ale which has no use and is drained from the barrel. + +To make an ale, 2 [[bucket of water]], 2 [[barley malt]], 1 [[ale yeast]], and optionally: 1 [[the stuff]] are required: +{{Instructions +|step1 = Use 2 [[bucket of water]] on the [[fermenting vat]] +|step2 = Use 2 [[barley malt]] on the fermenting vat +|step3 = ''Optional:'' Use 1 [[the stuff]] on the fermenting vat, increasing the chance to mature the ale from 5% to 64% +|step4 = Use the ingredients specific to the brew type you want to make +|step5 = Use 1 [[ale yeast]] on the fermenting vat +|step6 = Wait for 3 x 640 minute cycles (with the stuff added, between 3 x 640 and 16 x 640 minutes) +|step7 = Use the valve to drain the completed ale into the barrel +|step8 = Use 8 [[beer glass]]es or 2 [[calquat keg]]s on the barrel full of the completed ale +}} + +To make cider, 4 buckets of [[apple mush]], 1 [[ale yeast]] are required: +{{Instructions +|step1 = Use 4 buckets of [[apple mush]] on the [[fermenting vat]] +|step2 = Use 1 [[ale yeast]] on the fermenting vat +|step3 = Wait for three 640 minutes farming cycles +|step6 = Use the valve to drain the completed ale into the barrel +|step7 = Use 8 [[beer glass]]es or 2 [[calquat keg]]s on the barrel full of the completed cider +}} +Each apple mush requires 4 [[cooking apple]]s and one [[bucket]] added into the [[Apple Press]]. 16 cooking apples are required per cider. + +Most brews boost certain stats, some boost a variable amount based on the skill's level, boosting more as the level increases. +{|class="wikitable" +!rowspan=2 colspan=2|Ale!!colspan=2|{{SCP|Cooking}} +!rowspan=2|Boosts +!rowspan=2|Heals +!rowspan=2|Deboosts +!rowspan=2 colspan=2|Distinct ingredient +|- +!Level +!Experience +|- +|{{plinkt|Cider}} +|rowspan=2|14 +|rowspan=2|182 +|{{SCP|Farming|+1}} +|{{SCP|Hitpoints|1}} +|{{SCP|Attack}}{{SCP|Strength|2–3}}
2 + floor(CurrentLevel * 0.02) +|{{plinkt|Apple mush|txt=4 × Apple mush|rowspan=2}} +|- +|{{plinkt|Mature cider}} +|{{SCP|Farming|+2}} +|{{SCP|Hitpoints|2}} +|{{SCP|Attack}}{{SCP|Strength|3–4}}
3 + floor(CurrentLevel * 0.02) +|- +|{{plinkt|Dwarven stout}} +|rowspan=2|19 +|rowspan=2|215 +|{{SCP|Smithing}}{{SCP|Mining|+1}} +|{{SCP|Hitpoints|1}} +|{{SCP|Attack}}{{SCP|Defence}}{{SCP|Strength|2–5}}
2 + floor(CurrentLevel * 0.04) +|{{plinkt|Hammerstone hops|txt=4 × Hammerstone hops|rowspan=2}} +|- +|{{plinkt|Dwarven stout(m)}} +|{{SCP|Smithing}}{{SCP|Mining|+2}} +|{{SCP|Hitpoints|2}} +|{{SCP|Attack}}{{SCP|Defence}}{{SCP|Strength|3–6}}
3 + floor(CurrentLevel * 0.04) +|- +|{{plinkt|Asgarnian ale}} +|rowspan=2|24 +|rowspan=2|248 +|{{SCP|Strength|+2}} +|{{SCP|Hitpoints|1}} +|{{SCP|Attack|2–6}}
2 + floor(CurrentLevel * 0.05) +|{{plinkt|Asgarnian hops|txt=4 × Asgarnian hops|rowspan=2}} +|- +|{{plinkt|Asgarnian ale(m)}} +|{{SCP|Strength|+3}} +|{{SCP|Hitpoints|2}} +|{{SCP|Attack|3–7}}
3 + floor(CurrentLevel * 0.05) +|- +|{{plinkt|Greenman's ale}} +|rowspan=2|29 +|rowspan=2|281 +|{{SCP|Herblore|+1}} +|{{SCP|Hitpoints|1}} +|{{SCP|Attack}}{{SCP|Defence}}{{SCP|Strength|2–5}}
2 + floor(CurrentLevel * 0.04) +|{{plinkt|Harralander|txt=4 × Harralander|rowspan=2}} +|- +|{{plinkt|Greenman's ale(m)}} +|{{SCP|Herblore|+2}} +|{{SCP|Hitpoints|2}} +|{{SCP|Attack}}{{SCP|Defence}}{{SCP|Strength|3–6}}
3 + floor(CurrentLevel * 0.04) +|- +|{{plinkt|Wizard's mind bomb}} +|rowspan=2|34 +|rowspan=2|314 +|{{SCP|Magic|+2–3}}
2 + floor(CurrentLevel * 0.02) +|{{SCP|Hitpoints|1}} +|{{SCP|Attack}}{{SCP|Defence}}{{SCP|Strength|1–5}}
1 + floor(CurrentLevel * 0.05) +|{{plinkt|Yanillian hops|txt=4 × Yanillian hops|rowspan=2}} +|- +|{{plinkt|Mature wmb}} +|{{SCP|Magic|+3–4}}
3 + floor(CurrentLevel * 0.02) +|{{SCP|Hitpoints|2}} +|{{SCP|Attack}}{{SCP|Defence}}{{SCP|Strength|2–6}}
2 + floor(CurrentLevel * 0.05) +|- +|{{plinkt|Dragon bitter}} +|rowspan=2|39 +|rowspan=2|347 +|{{SCP|Strength|+2}} +|{{SCP|Hitpoints|1}} +|{{SCP|Attack|2–6}}
2 + floor(CurrentLevel * 0.05) +|{{plinkt|Krandorian hops|txt=4 × Krandorian hops|rowspan=2}} +|- +|{{plinkt|Dragon bitter(m)}} +|{{SCP|Strength|+3}} +|{{SCP|Hitpoints|2}} +|{{SCP|Attack|2–6}}
2 + floor(CurrentLevel * 0.05) +|- +|{{plinkt|Moonlight mead}} +|rowspan=2|44 +|rowspan=2|380 +|{{NA|rowspan=2}} +|{{SCP|Hitpoints|4}} +|{{NA|rowspan=2}} +|{{plinkt|Mushroom|txt=4 × Mushroom|rowspan=2}} +|- +|{{plinkt|Moonlight mead(m)}} +|{{SCP|Hitpoints|6}} +|- +|{{plinkt|Axeman's folly}} +|rowspan=2|49 +|rowspan=2|413 +|{{SCP|Woodcutting|+1}} +|{{SCP|Hitpoints|1}} +|{{SCP|Attack}}{{SCP|Strength|2–3}}
2 + floor(CurrentLevel * 0.02) +|{{plinkt|Oak roots|txt=1 × Oak roots|rowspan=2}} +|- +|{{plinkt|Axeman's folly(m)}} +|{{SCP|Woodcutting|+2}} +|{{SCP|Hitpoints|2}} +|{{SCP|Attack}}{{SCP|Strength|3–4}}
3 + floor(CurrentLevel * 0.02) +|- +|{{plinkt|Chef's delight}} +|rowspan=2|54 +|rowspan=2|413 +|{{SCP|Cooking|+1–5}}
1 + floor(CurrentLevel * 0.05) +|{{SCP|Hitpoints|1}} +|{{SCP|Attack}}{{SCP|Strength|3–6}}
2 + floor(CurrentLevel * 0.05) +|{{plinkt|Chocolate dust|txt=4 × Chocolate dust|rowspan=2}} +|- +|{{plinkt|Chef's delight(m)}} +|{{SCP|Cooking|+2–6}}
2 + floor(CurrentLevel * 0.05) +|{{SCP|Hitpoints|2}} +|{{SCP|Attack}}{{SCP|Strength|4–7}}
3 + floor(CurrentLevel * 0.05) +|- +|{{plinkt|Slayer's respite}} +|rowspan=2|59 +|rowspan=2|479 +|{{SCP|Slayer|+2}} +|{{SCP|Hitpoints|1}} +|{{SCP|Attack}}{{SCP|Strength|2–3}}
2 + floor(CurrentLevel * 0.02) +|{{plinkt|Wildblood hops|txt=4 × Wildblood hops|rowspan=2}} +|- +|{{plinkt|Slayer's respite(m)}} +|{{SCP|Slayer|+4}} +|{{SCP|Hitpoints|2}} +|{{SCP|Attack}}{{SCP|Strength|3–4}}
3 + floor(CurrentLevel * 0.02) +|} + +==Gnome cooking== +{{main|Gnome cooking}} +Gnome cooking is very complicated, and is best left with its own specially dedicated guide. The gnome foods plays a big part in the [[Gnome Restaurant]] minigame. More detailed information can be found in article linked to above, but following is a general guide for how a player can get acquainted with gnome cooking. + +Although it is complex, somewhat expensive, and requires a wide variety of unusual ingredients, gnome cooking can provide a good way to level Cooking from around 10 up to about 30 in good speed. To obtain the cookbook with all the recipes for gnome foods, a player can go to [[The Grand Tree]] in the [[Gnome Stronghold]] and find [[Aluft Gianne Sr]]. He is on the west side of the first level up of the Grand Tree and is dressed as a chef. Talk with him, and offer your assistance to him. He will assign you a succession of dishes to prepare. Once you have prepared the dish to his satisfaction, he will ask you to make another, then another moving steadily up the assortment of gnome foods. If you are using this method to train your Cooking and get an assignment you do not have the correct level to prepare, then you simply need to train until you do. Use the shops and resources in the Gnome Stronghold to make more gnome foods if you wish, or cook other foods that you may have. For each dish, the player can buy supplies from the shop run by Hudo who is found by the cooking range nearby Gianne, but ever since the shop stock update this has been severely limited. Players going through the tutorial will start by making crunchies, which can stored at a bank in the Grand Tree and later sold on the [[Grand Exchange]]. As your skill levels improve, you will be able to make battas then eventually bowls. Once you have completed the training exercises he gives you, you can start the minigame, which has several useful rewards. + +{| class="wikitable sortable align-left-3" style="text-align:center;" +!Level +! colspan=2 |Item +!XP +!Healing +|- +|6||{{plinkt|Fruit blast}}||50||9 +|- +|8||{{plinkt|Pineapple punch}}||70||9 +|- +|10||{{plinkt|Toad crunchies}}||100||8 +|- +|12||{{plinkt|Spicy crunchies}}||100||7 +|- +|14||{{plinkt|Worm crunchies}}||100||8 +|- +|16||{{plinkt|Chocchip crunchies}}||100||7 +|- +|18||{{plinkt|Wizard blizzard}}||110||5 +|- +|20||{{plinkt|Short green guy}}||120||5 +|- +|25||{{plinkt|Fruit batta}}||150||11 +|- +|26||{{plinkt|Toad batta}}||152||11 +|- +|27||{{plinkt|Worm batta}}||154||11 +|- +|28||{{plinkt|Vegetable batta}}||156||11 +|- +|29||{{plinkp|Cheese+tom batta}}||[[Cheese and tomato batta]]||158||11 +|- +|30||{{plinkt|Worm hole}}||170||12 +|- +|32||{{plinkt|Drunk dragon}}||160||5 +|- +|33||{{plinkt|Choc saturday}}||170||5 +|- +|35||{{plinkt|Veg ball}}||175||12 +|- +|37||{{plinkt|Blurberry special}}||180||7 +|- +|40||{{plinkt|Tangled toad's legs}}||185||15 +|- +|42||{{plinkt|Chocolate bomb}}||190||15 +|} + +==2-tick cooking== +[[File:Speed cooking.gif|thumb|2-tick cooking demonstrated at the range in [[Myths' Guild]].]] +It is possible to cook most foods at double speed, provided that they only have one cooking interface option. To perform this, drop the raw food items in front of a cooking range and then alternate between picking up raw food and left-clicking the range. This works because the cooking interface is skipped when only one raw food item is in the inventory, and the item is cooked with no delay. Due to the time it takes to drop items, the experience rate will not be exactly double, but this is still the fastest way to cook most foods. An inventory of food cooked on a range will take approximately 1 minute and 5 seconds. With efficient dropping, and using the 2-tick method, an inventory can be dropped and cooking in approximately 40 seconds total. This makes the 2-tick method around 30-40% faster than afk cooking, depending on shift-click drop speed. + +==Temporary boosts== +{{main|Temporary skill boost}} +{{:Temporary skill boost/Cooking}} + +==Quests== +{{Sync}} +===Quests requiring Cooking=== +{| class="wikitable sortable lighttable mw-collapsible qc-active oqg-table" style="text-align:center;" +!Quest +!Cooking
requirement +!Other requirements +|- +|[[Recipe for Disaster/Another Cook's Quest]]||{{SCP|Cooking|10}}||- +|- +|[[Ghosts Ahoy]]||{{SCP|Cooking|20}}|| {{SCP|Agility|25}} +|- +|[[Forgettable Tale...]]||{{SCP|Cooking|22}}||{{SCP|Farming|17}} +|- +|[[Recipe for Disaster/Freeing Evil Dave]]||{{SCP|Cooking|25}}||- +|- +|[[Big Chompy Bird Hunting]]||{{SCP|Cooking|30}}||{{SCP|Fletching|5}}, {{SCP|Ranged|30}} +|- +|[[Tai Bwo Wannai Trio]]||{{SCP|Cooking|30}}||{{SCP|Agility|15}}, {{SCP|Fishing|5}} +|- +|[[Recipe for Disaster/Freeing Pirate Pete]]||{{SCP|Cooking|31}}||- +|- +|[[Scrambled!]]||{{SCP|Cooking|36}}||{{SCP|Construction|38}}, {{SCP|Smithing|35}} +|- +|[[Recipe for Disaster/Freeing the Lumbridge Guide]]||{{SCP|Cooking|40}}||- +|- +|[[Recipe for Disaster/Freeing Skrach Uglogwee]]||{{SCP|Cooking|41}}||{{SCP|Firemaking|20}} +|- +|[[Heroes' Quest]]||{{SCP|Cooking|53}}||{{SCP|Quest|55}}, {{SCP|Fishing|53}}, {{SCP|Herblore|25}}, {{SCP|Mining|50}} +|- +|[[Swan Song]]||{{SCP|Cooking|62}}||{{SCP|Quest|100}}, {{SCP|Magic|66}}, {{SCP|Fishing|62}}, {{SCP|Smithing|45}}, {{SCP|Firemaking|42}}, {{SCP|Crafting|40}} +|- +|[[Recipe for Disaster/Freeing King Awowogei]]||{{SCP|Cooking|70 (Boostable)}}||{{SCP|Agility|48}} +|} + +===Quests rewarding Cooking experience=== +{{Main|Quest experience rewards}} +{| class="wikitable sortable lighttable mw-collapsible qc-active oqg-table" style="text-align:center;" +!Quest +!Experience
reward +!Cooking
requirement +!Other requirements +|- +|[[Cook's Assistant]]||300||-||- +|- +|[[Rag and Bone Man I]]||500||-||- +|- +|[[Recipe for Disaster/Freeing the Mountain Dwarf]]||1,000||-||- +|- +|[[Recipe for Disaster/Freeing the Goblin generals]]||1,000||-||- +|- +|[[Recipe for Disaster/Freeing Pirate Pete]]||1,000||{{SCP|Cooking|31|sort=y}}||- +|- +|[[Big Chompy Bird Hunting]]||1,470||{{SCP|Cooking|30|sort=y}}||{{SCP|Fletching|5}}, {{SCP|Ranged|30}} +|- +|[[Recipe for Disaster/Freeing Skrach Uglogwee]]||1,500||{{SCP|Cooking|41|sort=y}}||{{SCP|Firemaking|20}} +|- +|[[Gertrude's Cat]]||1,525||-||- +|- +|[[Recipe for Disaster/Freeing the Lumbridge Guide]]||2,500||{{SCP|Cooking|40|sort=y}}||- +|- +|[[Heroes' Quest]]||2,825||{{SCP|Cooking|53|sort=y}}||{{SCP|Quest|55}}, {{SCP|Fishing|53}}, {{SCP|Herblore|25}}, {{SCP|Mining|50}} +|- +|[[Recipe for Disaster/Freeing Sir Amik Varze]]||4,000||-||{{SCP|Quest|107}} +|- +|[[Forgettable Tale...]]||5,000||{{SCP|Cooking|22|sort=y}}||{{SCP|Farming|17}} +|- +|[[Tai Bwo Wannai Trio]]||5,000||{{SCP|Cooking|30|sort=y}}||{{SCP|Agility|15}}, {{SCP|Fishing|5}} +|- +|[[Scrambled!]]||5,000||{{SCP|Cooking|36|sort=y}}||{{SCP|Construction|38}}, {{SCP|Smithing|35}} +|- +|[[Recipe for Disaster/Freeing Evil Dave]]||7,000||-||- +|- +|[[Meat and Greet]]||8,000||-||- +|- +|[[Recipe for Disaster/Freeing King Awowogei]]||10,000||{{SCP|Cooking|70|sort=y}}||{{SCP|Agility|48}} +|- +!Total +!57,620 +! colspan="2" | +|} + +===Diaries Requiring Cooking=== +{| class="wikitable sortable lighttable mw-collapsible qc-active oqg-table" style="text-align:center;" +!Quest +! data-sort-type="number" |Cooking
requirement +!Other requirements for task +|- +|[[Morytania Easy Diary]] +|{{SCP|Cooking|12}} +| +|- +|[[Kandarin Medium Diary]] +|{{SCP|Cooking|43}} +|{{SCP|Fishing|46}} +|- +|[[Karamja Medium Diary]] +|{{SCP|Cooking|16}} +| +|- +|[[Morytania Medium Diary]] +|{{SCP|Cooking|40}} +| +|- +|[[Western Provinces Medium Diary]] +|{{SCP|Cooking|42}} +| +|- +|[[Karamja Hard Diary]] +|{{SCP|Cooking|30}} +| +|- +|[[Western Provinces Hard Diary]] +|{{SCP|Cooking|62}} +|{{SCP|Fishing|62}} +|- +|[[Kandarin Elite Diary]] +|{{SCP|Cooking|80}} +|{{SCP|Fishing|76}} +|- +|[[Kourend & Kebos Elite Diary]] +|{{SCP|Cooking|84}} +|{{SCP|Fishing|82}} +|- +|[[Desert Elite Diary]] +|{{SCP|Cooking|85}} +| +|- +|[[Wilderness Elite Diary]] +|{{SCP|Cooking|90}} +|{{SCP|Fishing|85}} +|- +|[[Ardougne Elite Diary]] +|{{SCP|Cooking|91}} +|{{SCP|Fishing|81}} +|- +|[[Varrock Elite Diary]] +|{{SCP|Cooking|95}} +| +|} + +===Skill choice=== +Upon completing any of the following quests, players may choose to allocate experience to Cooking. These rewards usually come in the form of items, such as lamps or books, and are independent of any experience rewards directly received for completing the quest. +{{SkillChoice|Cooking}} + +==Level up messages== +{{hastranscript|skill}} + +==See also== +* [[Cooking/Experience table]], a list of all Cooking experience sources +* [[Cooking/Level up table]], a list of all requirements and unlockables within the Cooking skill + +{{Skills}} +[[Category:Free-to-play skills]] diff --git a/wikidata/meat-fish.md b/wikidata/meat-fish.md new file mode 100644 index 00000000..22495cde --- /dev/null +++ b/wikidata/meat-fish.md @@ -0,0 +1,82 @@ +# Meat / fish (Cooking skill) + +- Extracted from: `cooking.wikisrc` +- Section: Meat / fish +- Extract date (UTC): 2026-01-17 +- Rows extracted: 65 + +`Done` is marked when a corresponding cooking action exists in `cache` (recipes), not just when an item exists in the cache. + +| Done | Level | Item | XP | Heal | +|---|---:|---|---:|---:| +| [x] | 1 | Cooked meat | 30 | 3 | +| [ ] | 1 | Sinew | 3 | N/A | +| [x] | 1 | Shrimps | 30 | 3 | +| [x] | 1 | Cooked chicken | 30 | 3 | +| [x] | 1 | Cooked rabbit | 30 | 5 | +| [x] | 1 | Anchovies | 30 | 1 | +| [x] | 1 | Sardine | 40 | 4 | +| [ ] | 1 | Poison karambwan | 80 | -5 | +| [x] | 1 | Ugthanki meat | 40 | 3 | +| [x] | 5 | Herring | 50 | 5 | +| [ ] | 7 | Guppy | 12 | N/A | +| [x] | 10 | Mackerel | 60 | 6 | +| [x] | 11 | Roast bird meat | 60 | 6 | +| [ ] | 12 | Thin snail | 70 | 5-7 | +| [x] | 15 | Trout | 70 | 7 | +| [ ] | 16 | Spider on stick | 80 | 7-10 | +| [ ] | 16 | Spider on shaft | 80 | 7-10 | +| [ ] | 16 | Roast rabbit | 70 | 7 | +| [ ] | 17 | Lean snail | 80 | 5-8 | +| [x] | 18 | Cod | 75 | 7 | +| [x] | 20 | Pike | 80 | 8 | +| [ ] | 20 | Cavefish | 23 | N/A | +| [x] | 21 | Roast beast meat | 82.5 | 8 | +| [ ] | 21 | Red crab meat | 85 | 8 | +| [ ] | 21 | Cooked giant crab meat | 100 | 10 | +| [ ] | 22 | Fat snail | 95 | 7-9 | +| [ ] | 23 | Cooked wild kebbit | 73 | 4+4 (8) | +| [x] | 25 | Salmon | 90 | 9 | +| [x] | 28 | Slimy eel | 95 | 6-10 | +| [x] | 30 | Tuna | 100 | 10 | +| [x] | 30 | Cooked karambwan | 190 | 18 | +| [x] | 30 | Cooked chompy | 100 | 10 | +| [ ] | 31 | Cooked fishcake | 100 | 11 | +| [ ] | 31 | Cooked larupia | 92 | 6+5 (11) | +| [ ] | 32 | Cooked barb-tailed kebbit | 106 | 7+5 (12) | +| [ ] | 33 | Tetra | 31 | N/A | +| [x] | 35 | Rainbow fish | 110 | 11 | +| [x] | 38 | Cave eel | 115 | 7-11 | +| [x] | 40 | Lobster | 120 | 12 | +| [ ] | 41 | Cooked jubbly | 160 | 15 | +| [ ] | 41 | Cooked graahk | 124 | 8+6 (14) | +| [x] | 43 | Bass | 130 | 13 | +| [x] | 45 | Swordfish | 140 | 14 | +| [ ] | 46 | Catfish | 43 | N/A | +| [ ] | 51 | Cooked kyatt | 143 | 9+8 (17) | +| [ ] | 53 | Lava eel | 30 | 14 | +| [ ] | 56 | Swordtip squid | 150 | 15 | +| [ ] | 59 | Cooked pyre fox | 154 | 11+8 (19) | +| [x] | 62 | Monkfish | 150 | 16 | +| [ ] | 68 | Cooked sunlight antelope | 175 | 12+9 (21) | +| [ ] | 69 | Giant krill | 177.5 | 17 | +| [ ] | 71 | Jumbo squid | 180 | 17 | +| [ ] | 72 | Sacred eel | 109-124 | N/A | +| [ ] | 73 | Haddock | 180 | 18 | +| [ ] | 79 | Yellowfin | 200 | 19 | +| [x] | 80 | Shark | 210 | 20 | +| [x] | 82 | Sea turtle | 211.3 | 21 | +| [ ] | 82 | Cooked dashing kebbit | 215 | 13+10 (23) | +| [ ] | 83 | Halibut | 212.5 | 20 | +| [x] | 84 | Anglerfish | 230 | 3-22 | +| [ ] | 87 | Bluefin | 215 | 22 | +| [x] | 90 | Dark crab | 215 | 22 | +| [x] | 91 | Manta ray | 216.2 | 22 | +| [ ] | 91 | Marlin | 225 | 24 | +| [ ] | 92 | Cooked moonlight antelope | 220 | 14+12 (26) | + +## Notes + +- Burn thresholds (fire/range) are not included here yet; the saved `burn_level.wikisrc` needs additional parsing/naming normalization. +- Some entries (e.g., sinew, roasted kebbits, fishcake) may require different triggers/constraints than simple heat-source cooking and may be implemented separately. +- Guppy, cavefish, tetra, and catfish are prepared on the Preparation Table with a knife (runtime item-on-object), so they are not marked done under the "cache cooking action exists" rule. diff --git a/wikidata/skill_chances.json b/wikidata/skill_chances.json new file mode 100644 index 00000000..e14ee9b7 --- /dev/null +++ b/wikidata/skill_chances.json @@ -0,0 +1,18850 @@ +[ + { + "title": "A wooden log", + "names": [ + "objects.zq_logbalance" + ], + "entries": [ + { + "label": "Crossing a wooden log", + "showbefore": "no", + "xlabel": "Agility level", + "ylabel": "Cross chance", + "label1": "Successful cross chance", + "low1": "90", + "high1": "250", + "req1": "1", + "color1": "#70450d", + "image1": "Agility icon.png" + } + ] + }, + { + "title": "Achey Tree", + "names": [ + "objects.achey_tree" + ], + "entries": [ + { + "label": "Achey tree cut chance", + "label1": "Bronze", + "low1": "64", + "high1": "200", + "req1": "1", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "96", + "high2": "300", + "req2": "1", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "128", + "high3": "400", + "req3": "6", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "144", + "high4": "450", + "req4": "11", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "160", + "high5": "500", + "req5": "21", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "192", + "high6": "600", + "req6": "31", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "224", + "high7": "700", + "req7": "41", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "240", + "high8": "750", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png" + } + ] + }, + { + "title": "Adamantite rocks", + "names": [ + "objects.adamantiterock2", + "objects.adamantiterock1", + "objects.prif_mine_adamantiterock1" + ], + "entries": [ + { + "label": "Adamantite rocks mining chance", + "showbefore": "no", + "label1": "Adamantite rocks", + "low1": "2", + "high1": "25", + "req1": "70", + "color1": "seagreen", + "image1": "Adamantite ore.png" + } + ] + }, + { + "title": "Admiral pie", + "names": [ + "items.admiral_pie", + "items.half_admiral_pie" + ], + "entries": [ + { + "label": "Admiral pie cooking chance", + "xlabel": "Cooking level", + "showbefore": "no", + "label1": "Range", + "low1": "15", + "high1": "270", + "req1": "70", + "color1": "saddlebrown", + "image1": "Admiral pie.png", + "label2": "Hosidius +5%", + "low2": "27", + "high2": "282", + "req2": "70", + "color2": "red", + "image2": "Admiral pie.png", + "label3": "Hosidius +10%", + "low3": "40", + "high3": "295", + "req3": "79", + "color3": "blue", + "image3": "Admiral pie.png" + } + ] + }, + { + "title": "Air rune (The Slug Menace)", + "names": [ + "items.slug2_rune_air" + ], + "entries": [ + { + "label": "Channeling blank rune success chance", + "xlabel": "Runecraft level", + "showbefore": "no", + "label1": "Air rune", + "low1": "110", + "high1": "253", + "req1": "30", + "color1": "#9b9090", + "image1": "Air rune (The Slug Menace).png" + } + ] + }, + { + "title": "Al Kharid warrior", + "names": [ + "npcs.al_kharid_warrior" + ], + "entries": [ + { + "label": "Al Kharid warrior pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "100", + "high1": "240", + "req1": "25", + "color1": "gray", + "image1": "Thieving icon.png", + "label2": "Gloves of silence", + "low2": "105", + "high2": "252", + "req2": "40", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "110", + "high3": "264", + "req3": "67", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "121", + "high4": "290", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Amethyst crystals", + "names": [ + "objects.amethystrock1", + "objects.amethystrock2", + "objects.amethystrock_empty" + ], + "entries": [ + { + "label": "Amethyst crystal mining chance", + "showbefore": "no", + "label1": "Amethyst crystal", + "low1": "-18", + "high1": "10", + "req1": "92", + "color1": "#b57a9b", + "image1": "Amethyst.png" + } + ] + }, + { + "title": "Anaire", + "names": [ + "npcs.prif_citizen_anaire" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Anchovies", + "names": [ + "items.anchovies" + ], + "entries": [ + { + "label": "Anchovies cooking chance", + "xlabel": "Cooking level", + "label1": "Fire or Range", + "low1": "128", + "high1": "512", + "req1": "1", + "color1": "gray", + "image1": "Anchovies.png", + "label2": "Lumbridge range", + "low2": "138", + "high2": "532", + "req2": "1", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "140", + "high3": "524", + "req3": "1", + "color3": "red", + "image3": "Anchovies.png", + "label4": "Hosidius +10%", + "low4": "153", + "high4": "537", + "req4": "84", + "color4": "blue", + "image4": "Anchovies.png" + } + ] + }, + { + "title": "Anglerfish", + "names": [ + "items.anglerfish" + ], + "entries": [ + { + "label": "Anglerfish cooking chance", + "showbefore": "no", + "label1": "Fire", + "low1": "1", + "high1": "200", + "req1": "84", + "color1": "orange", + "image1": "Firemaking icon.png", + "label2": "Range", + "low2": "1", + "high2": "220", + "req2": "84", + "color2": "saddlebrown", + "image2": "Cooking range icon.png", + "label3": "Gauntlets", + "low3": "12", + "high3": "260", + "req3": "84", + "color3": "grey", + "image3": "Cooking gauntlets.png", + "label4": "Hosidius +5%", + "low4": "13", + "high4": "232", + "req4": "84", + "color4": "red", + "image4": "Cooking range icon.png", + "label5": "Hosidius +10%", + "low5": "26", + "high5": "245", + "req5": "84", + "color5": "blue", + "image5": "Cooking range icon.png", + "label6": "Hosidius +5%, gauntlets", + "low6": "24", + "high6": "272", + "req6": "84", + "color6": "#ffcccb", + "image6": "Cooking gauntlets.png", + "label7": "Hosidius +10%, gauntlets", + "low7": "37", + "high7": "285", + "req7": "84", + "color7": "#ccccff", + "image7": "Cooking gauntlets.png" + } + ] + }, + { + "title": "Apple pie", + "names": [ + "items.apple_pie", + "items.half_an_apple_pie" + ], + "entries": [ + { + "label": "Apple pie cooking chance", + "xlabel": "Cooking level", + "label1": "Range", + "low1": "58", + "high1": "372", + "req1": "30", + "color1": "saddlebrown", + "image1": "Apple pie.png", + "label2": "Hosidius +5%", + "low2": "70", + "high2": "384", + "req2": "30", + "color2": "red", + "image2": "Apple pie.png", + "label3": "Hosidius +10%", + "low3": "83", + "high3": "397", + "req3": "79", + "color3": "blue", + "image3": "Apple pie.png" + } + ] + }, + { + "title": "Aranwe", + "names": [ + "npcs.prif_citizen_aranwe" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Arctic pine tree", + "names": [ + "objects.arctic_pine" + ], + "entries": [ + { + "label": "Arctic pine tree cut chance", + "showbefore": "no", + "label1": "Bronze", + "low1": "6", + "high1": "30", + "req1": "54", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "8", + "high2": "44", + "req2": "54", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "11", + "high3": "60", + "req3": "54", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "13", + "high4": "67", + "req4": "54", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "14", + "high5": "74", + "req5": "54", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "17", + "high6": "90", + "req6": "54", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "20", + "high7": "104", + "req7": "54", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "21", + "high8": "112", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png" + } + ] + }, + { + "title": "Aredhel", + "names": [ + "npcs.prif_citizen_aredhel" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Arvel", + "names": [ + "npcs.mourning_town_elf_3" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Baby impling", + "names": [ + "npcs.ii_impling_type_1", + "npcs.ii_impling_type_1_maze" + ], + "entries": [ + { + "label": "Baby impling catch chance", + "showbefore": "no", + "label1": "Butterfly net", + "low1": "79", + "high1": "402", + "req1": "17", + "color1": "saddlebrown", + "image1": "Butterfly net.png", + "label2": "Barehanded or magic butterfly net", + "low2": "99", + "high2": "422", + "req2": "17", + "color2": "green", + "image2": "Magic butterfly net.png" + } + ] + }, + { + "title": "Baked potato", + "names": [ + "items.potato_baked" + ], + "entries": [ + { + "label": "Potato cooking chance", + "label1": "Range", + "low1": "108", + "high1": "472", + "req1": "7", + "color1": "gray", + "image1": "Baked potato.png", + "label2": "Hosidius +5%", + "low2": "120", + "high2": "484", + "req2": "7", + "color2": "red", + "image2": "Baked potato.png", + "label3": "Hosidius +10%", + "low3": "133", + "high3": "497", + "req3": "79", + "color3": "blue", + "image3": "Baked potato.png" + } + ] + }, + { + "title": "Balancing ledge (Yanille Agility Dungeon)", + "names": [ + "objects.balancing_ledge3" + ], + "entries": [ + { + "label": "Balancing ledge", + "label1": "Walking across success rate", + "xlabel": "Agility level", + "low1": "65", + "high1": "355", + "req1": "40", + "showbefore": "no", + "color1": "#453321", + "image1": "Agility icon.png" + } + ] + }, + { + "title": "Bamboo Pipes", + "names": [ + "objects.brew_pipes_red", + "objects.brew_pipes_red_burning_1", + "objects.brew_pipes_red_burning_2", + "objects.brew_pipes_red_damaged_1", + "objects.brew_pipes_red_damaged_2", + "objects.brew_pipes_red_wet_1", + "objects.brew_pipes_red_wet_2", + "objects.brew_pipes_red_destroyed", + "objects.brew_pipes_blue", + "objects.brew_pipes_blue_burning_1", + "objects.brew_pipes_blue_burning_2", + "objects.brew_pipes_blue_damaged_1", + "objects.brew_pipes_blue_damaged_2", + "objects.brew_pipes_blue_wet_1", + "objects.brew_pipes_blue_wet_2", + "objects.brew_pipes_blue_destroyed" + ], + "entries": [ + { + "label": "Torch burn chance", + "xlabel": "Firemaking level", + "showbefore": "no", + "label1": "Successful burn", + "low1": "12", + "high1": "112", + "req1": "1", + "color1": "red", + "image1": "Lit torch.png" + } + ] + }, + { + "title": "Bandit (Bandit Camp)", + "names": [ + "npcs.fourdiamonds_sword_bandit_free", + "npcs.fourdiamonds_sword_bandit_1" + ], + "entries": [ + { + "label": "Bandit pickpocket chance", + "label1": "Normal", + "low1": "50", + "high1": "240", + "req1": "53", + "color1": "gray", + "image1": "Thief Desert bandit.png", + "label2": "Gloves of silence", + "low2": "52", + "high2": "252", + "req2": "53", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "55", + "high3": "264", + "req3": "53", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "60", + "high4": "290", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Barronite rocks", + "names": [ + "objects.camdozaalrock1", + "objects.camdozaalrock2", + "objects.camdozaalrock1_empty", + "objects.camdozaalrock2_empty" + ], + "entries": [ + { + "label": "Barronite rock mining chance", + "showbefore": "no", + "label1": "Barronite rock", + "low1": "80", + "high1": "100", + "req1": "14", + "color1": "purple", + "image1": "Barronite deposit.png", + "label2": "Charm of Mining", + "low2": "105", + "high2": "125", + "req2": "14", + "color2": "aqua", + "image2": "Charm of Mining.png" + } + ] + }, + { + "title": "Basalt rock", + "names": [ + "objects.horror_jumping_spot2", + "objects.horror_jumping_spot3", + "objects.horror_jumping_spot4", + "objects.horror_jumping_spot5", + "objects.horror_jumping_spot6", + "objects.horror_jumping_spot7", + "objects.horror_jumping_spot8", + "objects.horror_jumping_spot9" + ], + "entries": [ + { + "label": "Basalt rock success rate", + "lowlevel": "0", + "showbefore": "no", + "label1": "Basalt rock", + "low1": "5", + "high1": "255", + "req1": "1", + "color1": "Black", + "image1": "Agility icon.png" + } + ] + }, + { + "title": "Bass", + "names": [ + "items.bass" + ], + "entries": [ + { + "label": "Bass cooking chance", + "label1": "Fire or Range", + "low1": "33", + "high1": "312", + "req1": "43", + "color1": "gray", + "image1": "Bass.png", + "label2": "Hosidius +5%", + "low2": "45", + "high2": "324", + "req2": "43", + "color2": "red", + "image2": "Bass.png", + "label3": "Hosidius +10%", + "low3": "58", + "high3": "337", + "req3": "79", + "color3": "blue", + "image3": "Bass.png" + } + ] + }, + { + "title": "Bird house trapping", + "names": [], + "entries": [ + { + "label": "Seed nest chance", + "xlabel": "Hunter level", + "label1": "Seed nest", + "low1": "0", + "high1": "200", + "req1": "5", + "color1": "grey", + "image1": "Bird nest (seeds).png" + }, + { + "label": "Other nests (10 rolls per birdhouse)", + "xlabel": "Hunter level", + "birdhouse": "yes", + "label1": "Regular", + "high1": "100", + "req1": "5", + "color1": "#4b0082", + "image1": "Bird house.png", + "label2": "Oak", + "high2": "125", + "req2": "14", + "color2": "#ff0000", + "image2": "Oak bird house.png", + "label3": "Willow", + "high3": "128", + "req3": "24", + "color3": "#006400", + "image3": "Willow bird house.png", + "label4": "Teak", + "high4": "130", + "req4": "34", + "color4": "#ffa500", + "image4": "Teak bird house.png", + "label5": "Maple", + "high5": "140", + "req5": "44", + "color5": "#00ff00", + "image5": "Maple bird house.png", + "label6": "Mahogany", + "high6": "150", + "req6": "49", + "color6": "#ffff00", + "image6": "Mahogany bird house.png", + "label7": "Yew", + "high7": "160", + "req7": "59", + "color7": "#1e90ff", + "image7": "Yew bird house.png", + "label8": "Magic", + "high8": "170", + "req8": "74", + "color8": "#708090", + "image8": "Magic bird house.png", + "label9": "Redwood", + "high9": "175", + "req9": "89", + "color9": "#ff00ff", + "image9": "Redwood bird house.png" + } + ] + }, + { + "title": "Birdhouse (scenery)", + "names": [ + "objects.birdhouse_normal_built", + "objects.birdhouse_normal_full", + "objects.birdhouse_normal_bird" + ], + "entries": [ + { + "label": "Seed nest chance", + "xlabel": "Hunter level", + "label1": "Seed nest", + "low1": "0", + "high1": "200", + "req1": "5", + "color1": "grey", + "image1": "Bird nest (seeds).png" + }, + { + "label": "Other nests (10 rolls per birdhouse)", + "xlabel": "Hunter level", + "birdhouse": "yes", + "label1": "Regular", + "high1": "100", + "req1": "5", + "color1": "#4b0082", + "image1": "Bird house.png" + } + ] + }, + { + "title": "Black chinchompa (Hunter)", + "names": [ + "npcs.hunting_chinchompa_black" + ], + "entries": [ + { + "label": "Chinchompa catch chance", + "lowLevel": "53", + "label1": "Grey", + "low1": "6", + "high1": "268", + "req1": "53", + "color1": "gray", + "image1": "Chinchompa.png", + "label2": "Red", + "low2": "-78", + "high2": "228", + "req2": "63", + "color2": "red", + "image2": "Red chinchompa.png", + "label3": "Black", + "low3": "-78", + "high3": "228", + "req3": "73", + "color3": "black", + "image3": "Black chinchompa.png" + } + ] + }, + { + "title": "Black salamander (Hunter)", + "names": [ + "npcs.salamander_black" + ], + "entries": [ + { + "label": "Black salamander catch chance", + "showbefore": "no", + "label1": "Black salamander", + "low1": "0", + "high1": "212", + "req1": "67", + "color1": "#151111", + "image1": "Black salamander.png" + } + ] + }, + { + "title": "Blackjack", + "names": [], + "entries": [ + { + "label": "Blackjack Knock-Out Chance", + "xlabel": "Thieving level", + "label1": "Menaphite Thug", + "low1": "80", + "high1": "240", + "req1": "65", + "color1": "purple", + "image1": "Menaphite Thug chathead.png" + } + ] + }, + { + "title": "Blisterwood tree", + "names": [ + "objects.blisterwood_tree" + ], + "entries": [ + { + "label": "Blisterwood tree cut chance", + "showbefore": "no", + "label1": "Bronze", + "low1": "15", + "high1": "50", + "req1": "62", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Dragon", + "low2": "61", + "high2": "186", + "req2": "62", + "color2": "firebrick", + "image2": "Dragon axe.png" + } + ] + }, + { + "title": "Boil", + "names": [ + "objects.rcu_abyssal_barrier_boil1", + "objects.rcu_abyssal_barrier_boil2", + "objects.rcu_abyssal_barrier_boil3" + ], + "entries": [ + { + "label": "Boil success chance", + "xlabel": "Firemaking level", + "label1": "Success chance", + "low1": "0", + "high1": "255", + "image1": "Tinderbox.png", + "color1": "#692208" + } + ] + }, + { + "title": "Botanical pie", + "names": [ + "items.botanical_pie", + "items.half_botanical_pie" + ], + "entries": [ + { + "label": "Botanical pie cooking chance", + "label1": "Range", + "low1": "20", + "high1": "300", + "req1": "52", + "color1": "gray", + "image1": "Botanical pie.png", + "label2": "Lumbridge range", + "low2": "108", + "high2": "462", + "req2": "52", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "32", + "high3": "312", + "req3": "52", + "color3": "red", + "image3": "Botanical pie.png", + "label4": "Hosidius +10%", + "low4": "45", + "high4": "325", + "req4": "79", + "color4": "blue", + "image4": "Botanical pie.png" + } + ] + }, + { + "title": "Boulder (Volcanic Mine)", + "names": [ + "objects.fossil_mining_boulder_attached", + "objects.fossil_mining_boulder_giant", + "objects.fossil_mining_boulder_large", + "objects.fossil_mining_boulder_medium", + "objects.fossil_mining_boulder_small" + ], + "entries": [ + { + "label": "Volcanic Mine ore fragments", + "xlabel": "Mining level", + "cascade": "yes", + "showbefore": "no", + "label1": "Runite ore fragment", + "low1": "-10", + "high1": "80", + "req1": "85", + "color1": "steelblue", + "image1": "Runite ore fragment.png", + "label2": "Adamantite ore fragment", + "low2": "-90", + "high2": "90", + "req2": "70", + "color2": "seagreen", + "image2": "Adamantite ore fragment.png", + "label3": "Mithril ore fragment", + "low3": "-75", + "high3": "150", + "req3": "55", + "color3": "slateblue", + "image3": "Mithril ore fragment.png", + "label4": "Gold ore fragment", + "low4": "-40", + "high4": "160", + "req4": "50", + "color4": "goldenrod", + "image4": "Gold ore fragment.png", + "label5": "Coal fragment", + "low5": "-20", + "high5": "170", + "req5": "50", + "color5": "black", + "image5": "Coal fragment.png", + "label6": "Silver ore fragment", + "low6": "0", + "high6": "185", + "req6": "50", + "color6": "silver", + "image6": "Silver ore fragment.png", + "label7": "Iron ore fragment", + "low7": "0", + "high7": "510", + "req7": "50", + "color7": "maroon", + "image7": [] + } + ] + }, + { + "title": "Bowl", + "names": [ + "items.bowl_empty" + ], + "entries": [ + { + "label": "Firing pottery success rate", + "xlabel": "Crafting level", + "showbefore": "no", + "label1": "Unfired bowl", + "low1": "180", + "high1": "800", + "req1": "1", + "color1": "#916d11", + "image1": "Unfired bowl.png" + } + ] + }, + { + "title": "Bread", + "names": [ + "items.bread" + ], + "entries": [ + { + "label": "Bread cooking chance", + "xlabel": "Cooking level", + "label1": "Range", + "low1": "118", + "high1": "492", + "req1": "1", + "color1": "gray", + "image1": "Bread.png", + "label2": "Lumbridge range", + "low2": "128", + "high2": "512", + "req2": "1", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "130", + "high3": "504", + "req3": "1", + "color3": "red", + "image3": "Bread.png", + "label4": "Hosidius +10%", + "low4": "143", + "high4": "517", + "req4": "79", + "color4": "blue", + "image4": "Bread.png" + } + ] + }, + { + "title": "Bridge (Iban's Lair)", + "names": [ + "objects.bridgecollapsed1", + "objects.bridgecollapsed2" + ], + "entries": [ + { + "label": "Bridge crossing success rate", + "xlabel": "Agility level", + "label1": "Bridge", + "low1": "100", + "high1": "300", + "req1": "1", + "color1": "#392e0d", + "image1": "Agility icon.png" + } + ] + }, + { + "title": "Bridge (Nature Grotto)", + "names": [ + "objects.druidjump_loc" + ], + "entries": [ + { + "label": "Bridge success rate", + "lowlevel": "0", + "showbefore": "no", + "label1": "Jump", + "low1": "60", + "high1": "252", + "req1": "1", + "color1": "#5e691a", + "image1": "Agility icon.png" + } + ] + }, + { + "title": "Brimstone chest", + "names": [ + "objects.brimstone_konar_chest_closed", + "objects.brimstone_konar_chest_open" + ], + "entries": [ + { + "label": "Brimstone chest fish chance", + "xlabel": "Fishing level", + "ylabel": "Chance to receive", + "cascade": [], + "label1": "Raw manta ray", + "low1": "-10", + "high1": "20", + "image1": "Raw manta ray.png", + "color1": [], + "label2": "Raw sea turtle", + "low2": "-10", + "high2": "50", + "image2": "Raw sea turtle.png", + "color2": [], + "label3": "Raw shark", + "low3": "-60", + "high3": "140", + "image3": "Raw shark.png", + "color3": [], + "label4": "Raw monkfish", + "low4": "0", + "high4": "170", + "image4": "Raw monkfish.png", + "color4": [], + "label5": "Raw swordfish", + "low5": "30", + "high5": "200", + "image5": "Raw swordfish.png", + "color5": [], + "label6": "Raw lobster", + "low6": "70", + "high6": "270", + "image6": "Raw lobster.png", + "color6": [], + "label7": "Raw tuna", + "low7": "225", + "high7": "324", + "image7": "Raw tuna.png", + "color7": [] + } + ] + }, + { + "title": "Broken armour", + "names": [ + "items.digsitearmour2" + ], + "entries": [ + { + "label": "Broken armour repair chance", + "xlabel": "Smithing level", + "label1": "Broken armour", + "low1": "70", + "high1": "239", + "color1": "olive", + "image1": "Broken armour.png" + } + ] + }, + { + "title": "Broken arrow", + "names": [ + "items.digsitearrow" + ], + "entries": [ + { + "label": "Broken arrow repair chance", + "xlabel": "Fletching level", + "label1": "Broken arrow", + "low1": "180", + "high1": "239", + "color1": "brown", + "image1": "Broken arrow.png" + } + ] + }, + { + "title": "Broken bridge (Lighthouse)", + "names": [ + "objects.horror_broken_bridge_left_spot", + "objects.horror_broken_bridge_right_spot" + ], + "entries": [ + { + "label": "Broken bridge success rate", + "lowlevel": "0", + "showbefore": "no", + "label1": "Broken bridge", + "low1": "5", + "high1": "255", + "req1": "1", + "color1": "Black", + "image1": "Agility icon.png" + } + ] + }, + { + "title": "Broken staff", + "names": [ + "items.digsitestaff" + ], + "entries": [ + { + "label": "Broken staff repair chance", + "xlabel": "Crafting level", + "label1": "Broken staff", + "low1": "150", + "high1": "239", + "color1": "darkgoldenrod", + "image1": "Broken staff.png" + } + ] + }, + { + "title": "Burnt fish (sardine)", + "names": [ + "items.burntfish5" + ], + "entries": [ + { + "label": "Shrimps cooking chance", + "xlabel": "Cooking level", + "label1": "Fire or Range", + "low1": "128", + "high1": "512", + "req1": "1", + "color1": "gray", + "image1": "Shrimps.png", + "label2": "Lumbridge range", + "low2": "138", + "high2": "532", + "req2": "1", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "140", + "high3": "524", + "req3": "1", + "color3": "red", + "image3": "Shrimps.png", + "label4": "Hosidius +10%", + "low4": "153", + "high4": "537", + "req4": "84", + "color4": "blue", + "image4": "Shrimps.png" + } + ] + }, + { + "title": "Burnt fish (trout)", + "names": [ + "items.burntfish2" + ], + "entries": [ + { + "label": "Pike cooking chance", + "label1": "Fire or Range", + "low1": "78", + "high1": "412", + "req1": "20", + "color1": "gray", + "image1": "Pike.png", + "label2": "Lumbridge range", + "low2": "88", + "high2": "432", + "req2": "20", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "90", + "high3": "424", + "req3": "20", + "color3": "red", + "image3": "Pike.png", + "label4": "Hosidius +10%", + "low4": "103", + "high4": "437", + "req4": "79", + "color4": "blue", + "image4": "Pike.png" + } + ] + }, + { + "title": "Burnt oomlie wrap", + "names": [ + "items.burnt_oomlie" + ], + "entries": [ + { + "label": "Wrapped oomlie cooking chance", + "label1": "Fire", + "low1": "106", + "high1": "450", + "req1": "50", + "color1": "orange", + "image1": "Firemaking icon.png", + "label2": "Range", + "low2": "112", + "high2": "476", + "req2": "50", + "color2": "saddlebrown", + "image2": "Cooking range icon.png", + "label3": "Hosidius +5%", + "low3": "124", + "high3": "488", + "req3": "50", + "color3": "red", + "image3": "Cooking range icon.png", + "label4": "Hosidius +10%", + "low4": "137", + "high4": "501", + "req4": "79", + "color4": "blue", + "image4": "Cooking range icon.png" + } + ] + }, + { + "title": "Burnt shrimp", + "names": [ + "items.burnt_shrimp" + ], + "entries": [ + { + "label": "Shrimps cooking chance", + "xlabel": "Cooking level", + "label1": "Fire or Range", + "low1": "128", + "high1": "512", + "req1": "1", + "color1": "gray", + "image1": "Shrimps.png", + "label2": "Lumbridge range", + "low2": "138", + "high2": "532", + "req2": "1", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "140", + "high3": "524", + "req3": "1", + "color3": "red", + "image3": "Shrimps.png", + "label4": "Hosidius +10%", + "low4": "153", + "high4": "537", + "req4": "84", + "color4": "blue", + "image4": "Shrimps.png" + } + ] + }, + { + "title": "Burnt tree", + "names": [ + "objects.fossil_deadtree_small1", + "objects.fossil_deadtree_large1" + ], + "entries": [ + { + "label": "Dead tree cut chance", + "label1": "Bronze", + "low1": "64", + "high1": "200", + "req1": "1", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "96", + "high2": "300", + "req2": "1", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "128", + "high3": "400", + "req3": "6", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "144", + "high4": "450", + "req4": "11", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "160", + "high5": "500", + "req5": "21", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "192", + "high6": "600", + "req6": "31", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "224", + "high7": "700", + "req7": "41", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "240", + "high8": "750", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png" + } + ] + }, + { + "title": "Cake", + "names": [ + "items.cake", + "items.partial_cake", + "items.cake_slice" + ], + "entries": [ + { + "label": "Cake cooking chance", + "xlabel": "Cooking level", + "label1": "Range", + "low1": "38", + "high1": "332", + "req1": "40", + "color1": "gray", + "image1": "Cake.png", + "label2": "Hosidius +5%", + "low2": "50", + "high2": "344", + "req2": "40", + "color2": "red", + "image2": "Cake.png", + "label3": "Hosidius +10%", + "low3": "63", + "high3": "357", + "req3": "79", + "color3": "blue", + "image3": "Cake.png" + } + ] + }, + { + "title": "Cannon (Cabin Fever)", + "names": [ + "objects.fever_cannon", + "objects.fever_cannon_loaded", + "objects.fever_cannon_destroyed", + "objects.fever_cannon_no_barrel" + ], + "entries": [ + { + "label": "Hit chance", + "xlabel": "Ranged level", + "label1": "Cannon ball", + "low1": "15", + "high1": "240", + "image1": "Cannon ball.png", + "color1": "Black" + } + ] + }, + { + "title": "Canoe", + "names": [], + "entries": [ + { + "label": "Canoe shaping chance", + "xlabel": "Woodcutting level", + "showbefore": "yes", + "label1": "Bronze", + "low1": "32", + "high1": "100", + "req1": "12", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "48", + "high2": "150", + "req2": "12", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "64", + "high3": "200", + "req3": "12", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "72", + "high4": "225", + "req4": "12", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "80", + "high5": "250", + "req5": "21", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "96", + "high6": "300", + "req6": "31", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "112", + "high7": "350", + "req7": "41", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "112", + "high8": "350", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png", + "label9": "Crystal", + "low9": "112", + "high9": "350", + "req9": "71", + "color9": "cyan", + "image9": "Crystal axe.png" + } + ] + }, + { + "title": "Caranthir", + "names": [ + "npcs.prif_citizen_caranthir" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Carnivorous chinchompa", + "names": [ + "npcs.hunting_chinchompa_big" + ], + "entries": [ + { + "label": "Chinchompa catch chance", + "lowLevel": "53", + "label1": "Grey", + "low1": "6", + "high1": "268", + "req1": "53", + "color1": "gray", + "image1": "Chinchompa.png", + "label2": "Red", + "low2": "-78", + "high2": "228", + "req2": "63", + "color2": "red", + "image2": "Red chinchompa.png", + "label3": "Black", + "low3": "-78", + "high3": "228", + "req3": "73", + "color3": "black", + "image3": "Black chinchompa.png" + } + ] + }, + { + "title": "Cave eel", + "names": [ + "items.cave_eel" + ], + "entries": [ + { + "label": "Cave eel cooking chance", + "label1": "Fire or Range", + "low1": "38", + "high1": "332", + "req1": "38", + "color1": "gray", + "image1": "Cave eel.png", + "label2": "Hosidius +5%", + "low2": "50", + "high2": "344", + "req2": "38", + "color2": "red", + "image2": "Cave eel.png", + "label3": "Hosidius +10%", + "low3": "63", + "high3": "357", + "req3": "79", + "color3": "blue", + "image3": "Cave eel.png" + } + ] + }, + { + "title": "Caviar", + "names": [ + "items.brut_caviar" + ], + "entries": [ + { + "label": "Caviar creation chance", + "xlabel": "Cooking Level", + "showbefore": "no", + "label1": "Leaping sturgeon", + "caviar": "yes", + "denom1": "80", + "req1": "1", + "color1": "green", + "image1": "Leaping sturgeon.png" + } + ] + }, + { + "title": "Celebrian", + "names": [ + "npcs.prif_citizen_celebrian" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Celegorm", + "names": [ + "npcs.prif_citizen_celegorm" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Cerulean twitch", + "names": [ + "npcs.hunting_bird_polar" + ], + "entries": [ + { + "label": "Cerulean twitch catch chance", + "showbefore": "no", + "label1": "Cerulean twitch", + "low1": "82", + "high1": "380", + "req1": "11", + "color1": "#41416e", + "image1": "Cerulean twitch icon.png" + } + ] + }, + { + "title": "Cheese+tom batta", + "names": [ + "items.cheese+tom_batta" + ], + "entries": [ + { + "label": "Cheese+tom batta cooking chance", + "label1": "Range", + "low1": "118", + "high1": "492", + "req1": "29", + "color1": "gray", + "image1": "Cheese+tom batta.png", + "label2": "Hosidius +5%", + "low2": "130", + "high2": "504", + "req2": "29", + "color2": "red", + "image2": "Cheese+tom batta.png", + "label3": "Hosidius +10%", + "low3": "143", + "high3": "517", + "req3": "79", + "color3": "blue", + "image3": "Cheese+tom batta.png" + } + ] + }, + { + "title": "Chest (Aldarin Villas)", + "names": [ + "objects.aldarin_thieving_chest", + "objects.aldarin_thieving_chest_open" + ], + "entries": [ + { + "label": "Aldarin Villas chest thieving chance", + "showbefore": "no", + "label1": "Normal", + "low1": "0", + "high1": "150", + "req1": "36", + "color1": "darkred", + "image1": "Eclipse red.png", + "label2": "Lockpick", + "low2": "25", + "high2": "175", + "req2": "36", + "color2": "dimgray", + "image2": "Lockpick.png" + }, + { + "label": "Teleport chance on failure", + "ylabel": "Teleport chance", + "showbefore": "no", + "label1": "Normal", + "low1": "73", + "high1": "17", + "req1": "36", + "color1": "darkred", + "image1": "Eclipse red.png" + } + ] + }, + { + "title": "Chest (Chambers of Xeric)", + "names": [ + "objects.raids_thievingchest_closed", + "objects.raids_thievingchest_open", + "objects.raids_thievingchest_eggs_whole", + "objects.raids_thievingchest_eggs_hatched" + ], + "entries": [ + { + "label": "Cavern grub chest thieving chance", + "label1": "Normal", + "low1": "99", + "high1": "155", + "req1": "1", + "color1": "gray", + "image1": "Cavern grubs.png", + "label2": "Lockpick", + "low2": "153", + "high2": "209", + "req2": "1", + "color2": "dimgray", + "image2": "Lockpick.png" + } + ] + }, + { + "title": "Chest (Isle of Souls Dungeon)", + "names": [ + "objects.sw_dungeon_thieving_chest_closed", + "objects.sw_dungeon_thieving_chest_open" + ], + "entries": [ + { + "label": "Soul chest success chance", + "showbefore": "no", + "label1": "Normal", + "low1": "-23", + "high1": "153", + "req1": "28", + "color1": "tan", + "image1": "Dark key.png", + "label2": "Lockpick", + "low2": "3", + "high2": "179", + "req2": "28", + "color2": "dimgray", + "image2": "Lockpick.png" + } + ] + }, + { + "title": "Chinchompa (Hunter)", + "names": [ + "npcs.hunting_chinchompa" + ], + "entries": [ + { + "label": "Chinchompa catch chance", + "lowLevel": "53", + "label1": "Grey", + "low1": "6", + "high1": "268", + "req1": "53", + "color1": "gray", + "image1": "Chinchompa.png", + "label2": "Red", + "low2": "-78", + "high2": "228", + "req2": "63", + "color2": "red", + "image2": "Red chinchompa.png", + "label3": "Black", + "low3": "-78", + "high3": "228", + "req3": "73", + "color3": "black", + "image3": "Black chinchompa.png" + } + ] + }, + { + "title": "Chocchip crunchies", + "names": [ + "items.chocchip_crunchies" + ], + "entries": [ + { + "label": "Chocchip crunchies cooking chance", + "label1": "Range", + "low1": "118", + "high1": "492", + "req1": "16", + "color1": "gray", + "image1": "Chocchip crunchies.png", + "label2": "Hosidius +5%", + "low2": "130", + "high2": "504", + "req2": "16", + "color2": "red", + "image2": "Chocchip crunchies.png", + "label3": "Hosidius +10%", + "low3": "143", + "high3": "517", + "req3": "79", + "color3": "blue", + "image3": "Chocchip crunchies.png" + } + ] + }, + { + "title": "Chocolate bomb", + "names": [ + "items.chocolate_bomb" + ], + "entries": [ + { + "label": "Chocolate bomb cooking chance", + "label1": "Range", + "low1": "118", + "high1": "492", + "req1": "42", + "color1": "gray", + "image1": "Chocolate bomb.png", + "label2": "Hosidius +5%", + "low2": "130", + "high2": "504", + "req2": "42", + "color2": "red", + "image2": "Chocolate bomb.png", + "label3": "Hosidius +10%", + "low3": "143", + "high3": "517", + "req3": "79", + "color3": "blue", + "image3": "Chocolate bomb.png" + } + ] + }, + { + "title": "Cirdan", + "names": [ + "npcs.prif_citizen_cirdan" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Citizen (Civitas illa Fortis)", + "names": [ + "npcs.varlamore_citizen_poor_m_1", + "npcs.varlamore_citizen_poor_m_2", + "npcs.varlamore_citizen_poor_m_3", + "npcs.varlamore_citizen_poor_m_4", + "npcs.varlamore_citizen_poor_m_5", + "npcs.varlamore_citizen_poor_f_1", + "npcs.varlamore_citizen_poor_f_2", + "npcs.varlamore_citizen_poor_f_3", + "npcs.varlamore_citizen_poor_f_4", + "npcs.varlamore_citizen_poor_f_5", + "npcs.varlamore_citizen_normal_m_1", + "npcs.varlamore_citizen_normal_m_2", + "npcs.varlamore_citizen_normal_m_3", + "npcs.varlamore_citizen_normal_m_4", + "npcs.varlamore_citizen_normal_m_5", + "npcs.varlamore_citizen_normal_f_1", + "npcs.varlamore_citizen_normal_f_2", + "npcs.varlamore_citizen_normal_f_3", + "npcs.varlamore_citizen_normal_f_4", + "npcs.varlamore_citizen_normal_f_5", + "npcs.varlamore_citizen_rich_m_1", + "npcs.varlamore_citizen_rich_m_2", + "npcs.varlamore_citizen_rich_m_3", + "npcs.varlamore_citizen_rich_m_4", + "npcs.varlamore_citizen_rich_m_5", + "npcs.varlamore_citizen_rich_f_1", + "npcs.varlamore_citizen_rich_f_2", + "npcs.varlamore_citizen_rich_f_3", + "npcs.varlamore_citizen_rich_f_4", + "npcs.varlamore_citizen_rich_f_5", + "npcs.varlamore_citizen_with_baby_m_1", + "npcs.varlamore_citizen_with_baby_m_2", + "npcs.varlamore_citizen_with_baby_f_1", + "npcs.varlamore_citizen_with_baby_f_2" + ], + "entries": [ + { + "label": "Citizen pickpocket chance", + "label1": "Normal", + "low1": "180", + "high1": "240", + "req1": "1", + "color1": "gray", + "image1": "Thieving icon.png", + "label2": "Gloves of silence", + "low2": "189", + "high2": "252", + "req2": "1", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "198", + "high3": "264", + "req3": "1", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "217", + "high4": "290", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Clay rocks", + "names": [ + "objects.clayrock2", + "objects.clayrock1" + ], + "entries": [ + { + "label": "Clay rocks mining chance", + "showbefore": "no", + "label1": "Clay rocks", + "low1": "128", + "high1": "400", + "req1": "1", + "color1": "tan", + "image1": "Clay.png" + } + ] + }, + { + "title": "Coal rocks", + "names": [ + "objects.coalrock2", + "objects.coalrock1", + "objects.prif_mine_coalrock1" + ], + "entries": [ + { + "label": "Coal rocks mining chance", + "showbefore": "no", + "label1": "Coal rocks", + "low1": "16", + "high1": "100", + "req1": "30", + "color1": "black", + "image1": "Coal.png" + } + ] + }, + { + "title": "Cod", + "names": [ + "items.cod" + ], + "entries": [ + { + "label": "Cod cooking chance", + "label1": "Fire", + "low1": "83", + "high1": "422", + "req1": "18", + "color1": "orange", + "image1": "Firemaking icon.png", + "label2": "Range", + "low2": "88", + "high2": "432", + "req2": "18", + "color2": "saddlebrown", + "image2": "Cooking range icon.png", + "label3": "Lumbridge range", + "low3": "93", + "high3": "442", + "req3": "18", + "color3": "green", + "image3": "Lumbridge Teleport.png", + "label4": "Hosidius +5%", + "low4": "100", + "high4": "444", + "req4": "18", + "color4": "red", + "image4": "Cooking range icon.png", + "label5": "Hosidius +10%", + "low5": "113", + "high5": "457", + "req5": "79", + "color5": "blue", + "image5": "Cooking range icon.png" + } + ] + }, + { + "title": "Cooked barb-tailed kebbit", + "names": [ + "items.barbkebbit_cooked" + ], + "entries": [ + { + "label": "Cooked barb-tailed kebbit cooking chance", + "showbefore": "no", + "label1": "Fire or Range", + "low1": "56", + "high1": "370", + "req1": "32", + "color1": "gray", + "image1": "Cooked barb-tailed kebbit.png", + "label2": "Hosidius +5%", + "low2": "68", + "high2": "382", + "req2": "32", + "color2": "red", + "image2": "Cooking range icon.png", + "label3": "Hosidius +10%", + "low3": "81", + "high3": "395", + "req3": "79", + "color3": "blue", + "image3": "Cooking range icon.png" + } + ] + }, + { + "title": "Cooked chicken", + "names": [ + "items.cooked_chicken" + ], + "entries": [ + { + "label": "Cooked chicken cooking chance", + "label1": "Fire or Range", + "low1": "128", + "high1": "512", + "req1": "1", + "color1": "gray", + "image1": "Cooked chicken.png", + "label2": "Lumbridge range", + "low2": "138", + "high2": "532", + "req2": "1", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "140", + "high3": "524", + "req3": "1", + "color3": "red", + "image3": "Cooked chicken.png", + "label4": "Hosidius +10%", + "low4": "153", + "high4": "537", + "req4": "84", + "color4": "blue", + "image4": "Cooked chicken.png" + } + ] + }, + { + "title": "Cooked chicken (undead)", + "names": [ + "items.cooked_chicken_undead" + ], + "entries": [ + { + "label": "Undead chicken cooking chance", + "label1": "Fire or Range", + "low1": "128", + "high1": "512", + "req1": "1", + "color1": "gray", + "image1": "Cooked chicken (undead).png", + "label2": "Lumbridge range", + "low2": "138", + "high2": "532", + "req2": "1", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "140", + "high3": "524", + "req3": "1", + "color3": "red", + "image3": "Cooked chicken (undead).png", + "label4": "Hosidius +10%", + "low4": "153", + "high4": "537", + "req4": "84", + "color4": "blue", + "image4": "Cooked chicken (undead).png" + } + ] + }, + { + "title": "Cooked chompy", + "names": [ + "items.cooked_chompy" + ], + "entries": [ + { + "label": "Chompy cooking chance", + "label1": "Fire", + "low1": "200", + "high1": "255", + "req1": "30", + "color1": "orange", + "image1": "Firemaking icon.png" + } + ] + }, + { + "title": "Cooked crab meat", + "names": [ + "items.hundred_pirate_giant_crab_meat_5", + "items.hundred_pirate_giant_crab_meat_4", + "items.hundred_pirate_giant_crab_meat_3", + "items.hundred_pirate_giant_crab_meat_2", + "items.hundred_pirate_giant_crab_meat_1" + ], + "entries": [ + { + "label": "Cooked crab meat cooking chance", + "label1": "Fire or Range", + "low1": "57", + "high1": "377", + "req1": "21", + "color1": "gray", + "image1": "Cooked crab meat 5.png", + "label2": "Hosidius +5%", + "low2": "69", + "high2": "389", + "req2": "21", + "color2": "red", + "image2": "Cooked crab meat 5.png", + "label3": "Hosidius +10%", + "low3": "82", + "high3": "402", + "req3": "79", + "color3": "blue", + "image3": "Cooked crab meat 5.png" + } + ] + }, + { + "title": "Cooked dashing kebbit", + "names": [ + "items.dashingkebbit_cooked" + ], + "entries": [ + { + "label": "Cooked dashing kebbit cooking chance", + "showbefore": "no", + "label1": "Fire", + "low1": "1", + "high1": "194", + "req1": "82", + "color1": "orange", + "image1": "Firemaking icon.png", + "label2": "Range", + "low2": "1", + "high2": "224", + "req2": "82", + "color2": "saddlebrown", + "image2": "Cooking range icon.png", + "label3": "Hosidius +5%", + "low3": "13", + "high3": "236", + "req3": "82", + "color3": "red", + "image3": "Cooking range icon.png", + "label4": "Hosidius +10%", + "low4": "26", + "high4": "249", + "req4": "82", + "color4": "blue", + "image4": "Cooking range icon.png" + } + ] + }, + { + "title": "Cooked fishcake", + "names": [ + "items.hundred_pirate_fishcake" + ], + "entries": [ + { + "label": "Cooked fishcake cooking chance", + "label1": "Fire or Range", + "low1": "57", + "high1": "377", + "req1": "31", + "color1": "gray", + "image1": "Cooked fishcake.png", + "label2": "Hosidius +5%", + "low2": "69", + "high2": "389", + "req2": "31", + "color2": "red", + "image2": "Cooked fishcake.png", + "label3": "Hosidius +10%", + "low3": "82", + "high3": "402", + "req3": "79", + "color3": "blue", + "image3": "Cooked fishcake.png" + } + ] + }, + { + "title": "Cooked graahk", + "names": [ + "items.graahk_cooked" + ], + "entries": [ + { + "label": "Cooked graahk cooking chance", + "showbefore": "no", + "label1": "Fire or Range", + "low1": "32", + "high1": "328", + "req1": "41", + "color1": "gray", + "image1": "Cooked graahk.png", + "label2": "Hosidius +5%", + "low2": "44", + "high2": "340", + "req2": "41", + "color2": "red", + "image2": "Cooking range icon.png", + "label3": "Hosidius +10%", + "low3": "57", + "high3": "353", + "req3": "79", + "color3": "blue", + "image3": "Cooking range icon.png" + } + ] + }, + { + "title": "Cooked jubbly", + "names": [ + "items.100_jubbly_meat_cooked" + ], + "entries": [ + { + "label": "Jubbly cooking chance", + "label1": "Ogre spit-roast", + "low1": "191", + "high1": "245", + "req1": "30", + "color1": "orange", + "image1": "Firemaking icon.png" + } + ] + }, + { + "title": "Cooked karambwan", + "names": [ + "items.tbwt_cooked_karambwan" + ], + "entries": [ + { + "label": "Cooked karambwan cooking chance", + "label1": "Fire or Range", + "low1": "70", + "high1": "255", + "req1": "30", + "color1": "gray", + "image1": "Cooked_karambwan.png", + "label2": "Hosidius +5%", + "low2": "82", + "high2": "267", + "req2": "30", + "color2": "red", + "image2": "Cooked_karambwan.png", + "label3": "Hosidius +10%", + "low3": "95", + "high3": "280", + "req3": "79", + "color3": "blue", + "image3": "Cooked_karambwan.png" + } + ] + }, + { + "title": "Cooked kyatt", + "names": [ + "items.kyatt_cooked" + ], + "entries": [ + { + "label": "Cooked kyatt cooking chance", + "showbefore": "no", + "label1": "Fire", + "low1": "18", + "high1": "292", + "req1": "51", + "color1": "orange", + "image1": "Firemaking icon.png", + "label2": "Range or cooking gauntlets", + "low2": "30", + "high2": "310", + "req2": "51", + "color2": "saddlebrown", + "image2": "Cooking range icon.png", + "label3": "Hosidius +5%", + "low3": "42", + "high3": "322", + "req3": "51", + "color3": "red", + "image3": [], + "label4": "Hosidius +10%", + "low4": "55", + "high4": "335", + "req4": "79", + "color4": "blue", + "image4": "Cooking range icon.png" + } + ] + }, + { + "title": "Cooked larupia", + "names": [ + "items.larupia_cooked" + ], + "entries": [ + { + "label": "Cooked larupia cooking chance", + "showbefore": "no", + "label1": "Fire or Range", + "low1": "65", + "high1": "390", + "req1": "31", + "color1": "gray", + "image1": "Cooked larupia.png", + "label2": "Hosidius +5%", + "low2": "77", + "high2": "402", + "req2": "31", + "color2": "red", + "image2": "Cooking range icon.png", + "label3": "Hosidius +10%", + "low3": "90", + "high3": "415", + "req3": "79", + "color3": "blue", + "image3": "Cooking range icon.png" + } + ] + }, + { + "title": "Cooked meat", + "names": [ + "items.cooked_meat" + ], + "entries": [ + { + "label": "Cooked meat cooking chance", + "label1": "Fire or Range", + "low1": "128", + "high1": "512", + "req1": "1", + "color1": "gray", + "image1": "Cooked meat.png", + "label2": "Lumbridge range", + "low2": "138", + "high2": "532", + "req2": "1", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "140", + "high3": "524", + "req3": "1", + "color3": "red", + "image3": "Cooked meat.png", + "label4": "Hosidius +10%", + "low4": "153", + "high4": "537", + "req4": "84", + "color4": "blue", + "image4": "Cooked meat.png" + } + ] + }, + { + "title": "Cooked meat (undead)", + "names": [ + "items.cooked_meat_undead" + ], + "entries": [ + { + "label": "Undead meat cooking chance", + "label1": "Fire or Range", + "low1": "128", + "high1": "512", + "req1": "1", + "color1": "gray", + "image1": "Cooked meat (undead).png", + "label2": "Lumbridge range", + "low2": "138", + "high2": "532", + "req2": "1", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "140", + "high3": "524", + "req3": "1", + "color3": "red", + "image3": "Cooked meat (undead).png", + "label4": "Hosidius +10%", + "low4": "153", + "high4": "537", + "req4": "84", + "color4": "blue", + "image4": "Cooked meat (undead).png" + } + ] + }, + { + "title": "Cooked moonlight antelope", + "names": [ + "items.antelopemoon_cooked" + ], + "entries": [ + { + "label": "Cooked moonlight antelope cooking chance", + "showbefore": "no", + "label1": "Fire", + "low1": "1", + "high1": "185", + "req1": "92", + "color1": "orange", + "image1": "Firemaking icon.png", + "label2": "Range", + "low2": "1", + "high2": "200", + "req2": "92", + "color2": "saddlebrown", + "image2": "Cooking range icon.png", + "label3": "Hosidius +5%", + "low3": "13", + "high3": "212", + "req3": "92", + "color3": "red", + "image3": "Cooking range icon.png", + "label4": "Hosidius +10%", + "low4": "26", + "high4": "225", + "req4": "92", + "color4": "blue", + "image4": "Cooking range icon.png" + } + ] + }, + { + "title": "Cooked mystery meat", + "names": [ + "items.cooked_mystery_meat" + ], + "entries": [ + { + "label": "Mystery meat cooking chance", + "label1": "Fire or Range", + "low1": "128", + "high1": "512", + "req1": "1", + "color1": "gray", + "image1": "Cooked mystery meat.png", + "label2": "Lumbridge range", + "low2": "138", + "high2": "532", + "req2": "1", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "140", + "high3": "524", + "req3": "1", + "color3": "red", + "image3": "Cooked mystery meat.png", + "label4": "Hosidius +10%", + "low4": "153", + "high4": "537", + "req4": "84", + "color4": "blue", + "image4": "Cooked mystery meat.png" + } + ] + }, + { + "title": "Cooked oomlie wrap", + "names": [ + "items.cooked_oomlie" + ], + "entries": [ + { + "label": "Wrapped oomlie cooking chance", + "label1": "Fire", + "low1": "106", + "high1": "450", + "req1": "50", + "color1": "orange", + "image1": "Firemaking icon.png", + "label2": "Range", + "low2": "112", + "high2": "476", + "req2": "50", + "color2": "saddlebrown", + "image2": "Cooking range icon.png", + "label3": "Hosidius +5%", + "low3": "124", + "high3": "488", + "req3": "50", + "color3": "red", + "image3": "Cooking range icon.png", + "label4": "Hosidius +10%", + "low4": "137", + "high4": "501", + "req4": "79", + "color4": "blue", + "image4": "Cooking range icon.png" + } + ] + }, + { + "title": "Cooked pyre fox", + "names": [ + "items.fennecfox_cooked" + ], + "entries": [ + { + "label": "Cooked pyre fox cooking chance", + "showbefore": "no", + "label1": "Fire", + "low1": "10", + "high1": "273", + "req1": "59", + "color1": "orange", + "image1": "Firemaking icon.png", + "label2": "Range", + "low2": "11", + "high2": "276", + "req2": "59", + "color2": "saddlebrown", + "image2": "Cooking range icon.png", + "label3": "Hosidius +5%", + "low3": "23", + "high3": "288", + "req3": "59", + "color3": "red", + "image3": "Cooking range icon.png", + "label4": "Hosidius +10%", + "low4": "36", + "high4": "301", + "req4": "79", + "color4": "blue", + "image4": "Cooking range icon.png" + } + ] + }, + { + "title": "Cooked rabbit", + "names": [ + "items.cooked_rabbit" + ], + "entries": [ + { + "label": "Rabbit cooking chance", + "label1": "Fire or Range", + "low1": "128", + "high1": "512", + "req1": "1", + "color1": "gray", + "image1": "Cooked rabbit.png", + "label2": "Hosidius +5%", + "low2": "140", + "high2": "524", + "req2": "1", + "color2": "red", + "image2": "Cooked rabbit.png", + "label3": "Hosidius +10%", + "low3": "153", + "high3": "537", + "req3": "79", + "color3": "blue", + "image3": "Cooked rabbit.png" + } + ] + }, + { + "title": "Cooked slimy eel", + "names": [ + "items.mort_slimey_eel_cooked" + ], + "entries": [ + { + "label": "Cooked slimy eel cooking chance", + "label1": "Fire or Range", + "low1": "63", + "high1": "382", + "req1": "28", + "color1": "gray", + "image1": "Cooked slimy eel.png", + "label2": "Hosidius +5%", + "low2": "75", + "high2": "394", + "req2": "28", + "color2": "red", + "image2": "Cooked slimy eel.png", + "label3": "Hosidius +10%", + "low3": "88", + "high3": "407", + "req3": "79", + "color3": "blue", + "image3": "Cooked slimy eel.png" + } + ] + }, + { + "title": "Cooked sunlight antelope", + "names": [ + "items.antelopesun_cooked" + ], + "entries": [ + { + "label": "Cooked sunlight antelope cooking chance", + "showbefore": "no", + "label1": "Fire", + "low1": "8", + "high1": "254", + "req1": "68", + "color1": "orange", + "image1": "Firemaking icon.png", + "label2": "Range", + "low2": "8", + "high2": "265", + "req2": "68", + "color2": "saddlebrown", + "image2": "Cooking range icon.png", + "label3": "Hosidius +5%", + "low3": "20", + "high3": "277", + "req3": "68", + "color3": "red", + "image3": "Cooking range icon.png", + "label4": "Hosidius +10%", + "low4": "33", + "high4": "290", + "req4": "79", + "color4": "blue", + "image4": "Cooking range icon.png" + } + ] + }, + { + "title": "Cooked sweetcorn", + "names": [ + "items.sweetcorn_cooked" + ], + "entries": [ + { + "label": "Sweetcorn cooking chance", + "label1": "Fire or Range", + "low1": "78", + "high1": "412", + "req1": "28", + "color1": "gray", + "image1": "Cooked sweetcorn.png", + "label2": "Hosidius +5%", + "low2": "90", + "high2": "424", + "req2": "28", + "color2": "red", + "image2": "Cooked sweetcorn.png", + "label3": "Hosidius +10%", + "low3": "103", + "high3": "437", + "req3": "79", + "color3": "blue", + "image3": "Cooked sweetcorn.png" + } + ] + }, + { + "title": "Cooked wild kebbit", + "names": [ + "items.wildkebbit_cooked" + ], + "entries": [ + { + "label": "Cooked wild kebbit cooking chance", + "showbefore": "no", + "label1": "Fire or Range", + "low1": "84", + "high1": "428", + "req1": "23", + "color1": "gray", + "image1": "Cooked wild kebbit.png", + "label2": "Hosidius +5%", + "low2": "96", + "high2": "440", + "req2": "23", + "color2": "red", + "image2": "Cooking range icon.png", + "label3": "Hosidius +10%", + "low3": "109", + "high3": "453", + "req3": "79", + "color3": "blue", + "image3": "Cooking range icon.png" + } + ] + }, + { + "title": "Copper longtail", + "names": [ + "npcs.hunting_bird_woodland" + ], + "entries": [ + { + "label": "Copper longtail catch chance", + "showbefore": "no", + "label1": "Copper longtail", + "low1": "85", + "high1": "390", + "req1": "9", + "color1": "#ed9b58", + "image1": "Copper longtail icon.png" + } + ] + }, + { + "title": "Cowbells", + "names": [ + "items.peng_cowbell" + ], + "entries": [ + { + "label": "Cowbells success chance", + "showbefore": "no", + "label1": "Normal", + "low1": "128", + "high1": "200", + "req1": "15", + "color1": "gray", + "image1": "Cowbells.png" + } + ] + }, + { + "title": "Crab claw", + "names": [ + "items.hundred_pirate_crab_shell_gauntlet" + ], + "entries": [ + { + "label": "Crab claw success rate", + "xlabel": "Crafting level", + "showbefore": "no", + "label1": "Crab claw", + "low1": "40", + "high1": "240", + "req1": "15", + "color1": "red", + "image1": "Crab claw.png" + } + ] + }, + { + "title": "Crafting stall", + "names": [ + "objects.mm_stall_crafting", + "objects.dwarf_market_crafting" + ], + "entries": [ + { + "label": "Crafting Stall thieving chance", + "showbefore": "no", + "label1": "Crafting Stall", + "low1": "128", + "high1": "512", + "req1": "5", + "color1": "gold", + "image1": "Gold bar.png" + } + ] + }, + { + "title": "Crashed Star", + "names": [ + "objects.star_size_one_star", + "objects.star_size_two_star", + "objects.star_size_three_star", + "objects.star_size_four_star", + "objects.star_size_five_star", + "objects.star_size_six_star", + "objects.star_size_seven_star", + "objects.star_size_eight_star", + "objects.star_size_nine_star" + ], + "entries": [ + { + "color1": "goldenrod", + "high1": "117", + "image1": "Stardust 175.png", + "label": "Stardust mining chance", + "label1": "Stardust", + "low1": "73", + "req1": "10", + "showbefore": "no" + } + ] + }, + { + "title": "Money making guide/Cooking raw sunlight antelope", + "names": [], + "entries": [ + { + "label": "Cooked sunlight antelope cooking chance", + "showbefore": "no", + "label1": "Fire", + "low1": "8", + "high1": "254", + "req1": "62", + "color1": "orange", + "image1": "Firemaking icon.png", + "label2": "Range", + "low2": "8", + "high2": "265", + "req2": "62", + "color2": "saddlebrown", + "image2": "Cooking range icon.png", + "label3": "Hosidius +5%", + "low3": "20", + "high3": "277", + "req3": "62", + "color3": "red", + "image3": "Cooking range icon.png", + "label4": "Hosidius +10%", + "low4": "33", + "high4": "290", + "req4": "79", + "color4": "blue", + "image4": "Cooking range icon.png" + } + ] + }, + { + "title": "Crimson swift", + "names": [ + "npcs.hunting_bird_jungle" + ], + "entries": [ + { + "label": "Crimson swift catch chance", + "showbefore": "no", + "label1": "Crimson swift", + "low1": "100", + "high1": "420", + "req1": "1", + "color1": "#d44444", + "image1": "Crimson swift icon.png" + } + ] + }, + { + "title": "Crushed gem", + "names": [ + "items.crushed_gemstone" + ], + "entries": [ + { + "label": "Gem cutting rates", + "label1": "Opal", + "low1": "128", + "high1": "250", + "req1": "1", + "color1": "gray", + "image1": "Opal.png", + "label2": "Jade", + "low2": "100", + "high2": "245", + "req2": "13", + "color2": "green", + "image2": "Jade.png", + "label3": "Red topaz", + "low3": "90", + "high3": "240", + "req3": "16", + "color3": "pink", + "image3": "Red topaz.png" + } + ] + }, + { + "title": "Crystal impling", + "names": [ + "npcs.ii_impling_type_12_johnny", + "npcs.ii_impling_type_12_junior", + "npcs.ii_impling_type_12_andy", + "npcs.ii_impling_type_12_joey", + "npcs.ii_impling_type_12_trouble", + "npcs.ii_impling_type_12_hingy", + "npcs.ii_impling_type_12_zolty", + "npcs.ii_impling_type_12_neil", + "npcs.ii_impling_type_12_yanny", + "npcs.ii_impling_type_12_matty", + "npcs.ii_impling_type_12_stace", + "npcs.ii_impling_type_12_ian", + "npcs.ii_impling_type_12_jamie", + "npcs.ii_impling_type_12_damo", + "npcs.ii_impling_type_12_xander", + "npcs.ii_impling_type_12_steveo", + "npcs.ii_impling_type_12_stewie" + ], + "entries": [ + { + "label": "Crystal impling catch chance", + "showbefore": "no", + "label1": "Butterfly net", + "low1": "8", + "high1": "141", + "req1": "80", + "color1": "saddlebrown", + "image1": "Butterfly net.png", + "label2": "Barehanded or magic butterfly net", + "low2": "28", + "high2": "161", + "req2": "80", + "color2": "green", + "image2": "Magic butterfly net.png" + } + ] + }, + { + "title": "Curry", + "names": [ + "items.curry" + ], + "entries": [ + { + "label": "Curry cooking chance", + "label1": "Fire or Range", + "low1": "38", + "high1": "332", + "req1": "60", + "color1": "gray", + "image1": "Curry.png", + "label2": "Hosidius +5%", + "low2": "50", + "high2": "344", + "req2": "60", + "color2": "red", + "image2": "Curry.png", + "label3": "Hosidius +10%", + "low3": "63", + "high3": "357", + "req3": "79", + "color3": "blue", + "image3": "Curry.png" + } + ] + }, + { + "title": "Curufin", + "names": [ + "npcs.prif_citizen_curufin" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Dairy cow", + "names": [ + "objects.fat_cow", + "objects.fairy_fat_cow" + ], + "entries": [ + { + "label": "Cowbells success chance", + "showbefore": "no", + "label1": "Normal", + "low1": "128", + "high1": "200", + "req1": "15", + "color1": "gray", + "image1": "Cowbells.png" + } + ] + }, + { + "title": "Damaged armour", + "names": [ + "items.digsitearmour1" + ], + "entries": [ + { + "label": "Damaged armour repair chance", + "xlabel": "Smithing level", + "label1": "Damaged armour", + "low1": "70", + "high1": "239", + "color1": "olive", + "image1": "Damaged armour.png" + } + ] + }, + { + "title": "Dark crab", + "names": [ + "items.dark_crab" + ], + "entries": [ + { + "label": "Dark crab cooking chance", + "showbefore": "no", + "label1": "Fire or Range", + "low1": "10", + "high1": "222", + "req1": "90", + "color1": "gray", + "image1": "Dark crab.png", + "label2": "Hosidius +5%", + "low2": "22", + "high2": "234", + "req2": "90", + "color2": "red", + "image2": "Dark crab.png", + "label3": "Hosidius +10%", + "low3": "35", + "high3": "247", + "req3": "90", + "color3": "blue", + "image3": "Dark crab.png" + } + ] + }, + { + "title": "Dark kebbit", + "names": [ + "npcs.huntingbeast_silent" + ], + "entries": [ + { + "label": "Dark kebbit catch chance", + "showbefore": "no", + "label1": "Dark kebbit", + "low1": "0", + "high1": "253", + "req1": "57", + "color1": "#84630d", + "image1": "Dark kebbit icon.png" + } + ] + }, + { + "title": "Dashing kebbit", + "names": [ + "npcs.huntingbeast_speedy2" + ], + "entries": [ + { + "label": "Dashing kebbit catch chance", + "showbefore": "no", + "label1": "Dashing kebbit", + "low1": "0", + "high1": "205", + "req1": "69", + "color1": "#bd9f64", + "image1": "Dashing kebbit icon.png" + } + ] + }, + { + "title": "Dead tree", + "names": [ + "objects.deadtree2", + "objects.deadtree2_dark", + "objects.deadtree1", + "objects.deadtree1_large", + "objects.deadtree4" + ], + "entries": [ + { + "label": "Dead tree cut chance", + "label1": "Bronze", + "low1": "64", + "high1": "200", + "req1": "1", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "96", + "high2": "300", + "req2": "1", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "128", + "high3": "400", + "req3": "6", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "144", + "high4": "450", + "req4": "11", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "160", + "high5": "500", + "req5": "21", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "192", + "high6": "600", + "req6": "31", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "224", + "high7": "700", + "req7": "41", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "240", + "high8": "750", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png" + } + ] + }, + { + "title": "Dead tree (burnt)", + "names": [ + "objects.deadtree_burnt" + ], + "entries": [ + { + "label": "Dead tree cut chance", + "label1": "Bronze", + "low1": "64", + "high1": "200", + "req1": "1", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "96", + "high2": "300", + "req2": "1", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "128", + "high3": "400", + "req3": "6", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "144", + "high4": "450", + "req4": "11", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "160", + "high5": "500", + "req5": "21", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "192", + "high6": "600", + "req6": "31", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "224", + "high7": "700", + "req7": "41", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "240", + "high8": "750", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png" + } + ] + }, + { + "title": "Dead tree (old)", + "names": [ + "objects.deadtree6" + ], + "entries": [ + { + "label": "Dead tree cut chance", + "label1": "Bronze", + "low1": "64", + "high1": "200", + "req1": "1", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "96", + "high2": "300", + "req2": "1", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "128", + "high3": "400", + "req3": "6", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "144", + "high4": "450", + "req4": "11", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "160", + "high5": "500", + "req5": "21", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "192", + "high6": "600", + "req6": "31", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "224", + "high7": "700", + "req7": "41", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "240", + "high8": "750", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png" + } + ] + }, + { + "title": "Dead tree (sandy)", + "names": [ + "objects.deadtree3" + ], + "entries": [ + { + "label": "Dead tree cut chance", + "label1": "Bronze", + "low1": "64", + "high1": "200", + "req1": "1", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "96", + "high2": "300", + "req2": "1", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "128", + "high3": "400", + "req3": "6", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "144", + "high4": "450", + "req4": "11", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "160", + "high5": "500", + "req5": "21", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "192", + "high6": "600", + "req6": "31", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "224", + "high7": "700", + "req7": "41", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "240", + "high8": "750", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png" + } + ] + }, + { + "title": "Dead tree (snowy)", + "names": [ + "objects.deadtree2_snowy" + ], + "entries": [ + { + "label": "Dead tree cut chance", + "label1": "Bronze", + "low1": "64", + "high1": "200", + "req1": "1", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "96", + "high2": "300", + "req2": "1", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "128", + "high3": "400", + "req3": "6", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "144", + "high4": "450", + "req4": "11", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "160", + "high5": "500", + "req5": "21", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "192", + "high6": "600", + "req6": "31", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "224", + "high7": "700", + "req7": "41", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "240", + "high8": "750", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png" + } + ] + }, + { + "title": "Dead tree (swampy)", + "names": [ + "objects.deadtree2_swamp" + ], + "entries": [ + { + "label": "Dead tree cut chance", + "label1": "Bronze", + "low1": "64", + "high1": "200", + "req1": "1", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "96", + "high2": "300", + "req2": "1", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "128", + "high3": "400", + "req3": "6", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "144", + "high4": "450", + "req4": "11", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "160", + "high5": "500", + "req5": "21", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "192", + "high6": "600", + "req6": "31", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "224", + "high7": "700", + "req7": "41", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "240", + "high8": "750", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png" + } + ] + }, + { + "title": "Dead tree (weathered)", + "names": [ + "objects.lightdeadtree1" + ], + "entries": [ + { + "label": "Dead tree cut chance", + "label1": "Bronze", + "low1": "64", + "high1": "200", + "req1": "1", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "96", + "high2": "300", + "req2": "1", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "128", + "high3": "400", + "req3": "6", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "144", + "high4": "450", + "req4": "11", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "160", + "high5": "500", + "req5": "21", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "192", + "high6": "600", + "req6": "31", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "224", + "high7": "700", + "req7": "41", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "240", + "high8": "750", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png" + } + ] + }, + { + "title": "Dense Jungle", + "names": [ + "objects.tai_bwo_jungle_vegetation_hard_1", + "objects.tai_bwo_jungle_vegetation_hard_2", + "objects.tai_bwo_jungle_vegetation_hard_3", + "objects.tai_bwo_jungle_vegetation_hard_4", + "objects.tai_bwo_jungle_vegetation_hard_5" + ], + "entries": [ + { + "label": "Dense Jungle Cut Chance", + "showbefore": "no", + "label1": "Plain Machete", + "low1": "16", + "high1": "44", + "req1": "35", + "color1": "dimgray", + "image1": "Machete.png", + "label2": "Opal Machete", + "low2": "21", + "high2": "49", + "req2": "35", + "color2": "lightgray", + "image2": "Opal machete.png", + "label3": "Jade Machete", + "low3": "36", + "high3": "64", + "req3": "35", + "color3": "lightgreen", + "image3": "Jade machete.png", + "label4": "Red Topaz Machete", + "low4": "52", + "high4": "80", + "req4": "35", + "color4": "firebrick", + "image4": "Red topaz machete.png" + } + ] + }, + { + "title": "Dense runestone", + "names": [ + "objects.arceuus_runestone_base_mine", + "objects.arceuus_runestone_middle_mine", + "objects.arceuus_runestone_top_mine", + "objects.arceuus_runestone_base_depleted", + "objects.arceuus_runestone_middle_depleted", + "objects.arceuus_runestone_top_depleted" + ], + "entries": [ + { + "label": "Dense runestone persistence chance", + "showbefore": "no", + "label1": "Dense runestone", + "low1": "210", + "high1": "230", + "req1": "38", + "color1": "#6e6666", + "image1": "Dense essence block.png" + } + ] + }, + { + "title": "Door (Castle Wars)", + "names": [ + "objects.castlewars_saradomin_sidedoor", + "objects.castlewars_saradomin_sidedoor_open", + "objects.castlewars_zamorak_sidedoor", + "objects.castlewars_zamorak_sidedoor_open" + ], + "entries": [ + { + "label": "Door unlock chance", + "xlabel": "Thieving level", + "label1": "Unlock chance", + "low1": "15", + "high1": "255", + "image1": "Thieving icon.png", + "color1": "Black" + } + ] + }, + { + "title": "Dragon axe", + "names": [ + "items.dragon_axe" + ], + "entries": [ + { + "label": "Dragon axe success chances", + "showbefore": "yes", + "label1": "Yew tree", + "low1": "15", + "high1": "47", + "req1": "60", + "color1": "saddlebrown", + "image1": "Yew logs.png", + "label2": "Magic tree", + "low2": "7", + "high2": "22", + "req2": "75", + "color2": "slateblue", + "image2": "Magic logs.png", + "label3": "Mahogany tree", + "low3": "34", + "high3": "94", + "req3": "60", + "color3": "peru", + "image3": "Mahogany logs.png", + "label4": "Maple tree", + "low4": "30", + "high4": "93", + "req4": "60", + "color4": "chocolate", + "image4": "Maple logs.png", + "label5": "Teak tree", + "low5": "60", + "high5": "190", + "req5": "60", + "color5": "tan", + "image5": "Teak logs.png", + "label6": "Willow tree", + "low6": "60", + "high6": "187", + "req6": "60", + "color6": "darkolivegreen", + "image6": "Willow logs.png", + "label7": "Oak tree", + "low7": "120", + "high7": "375", + "req7": "60", + "color7": "wheat", + "image7": "Oak logs.png", + "label8": "Redwood tree", + "low8": "7", + "high8": "30", + "req8": "90", + "color8": "red", + "image8": "Redwood logs.png" + } + ] + }, + { + "title": "Dragon impling", + "names": [ + "npcs.ii_impling_type_10", + "npcs.ii_impling_type_10_maze" + ], + "entries": [ + { + "label": "Dragon impling catch chance", + "showbefore": "no", + "label1": "Butterfly net", + "low1": "5", + "high1": "125", + "req1": "83", + "color1": "saddlebrown", + "image1": "Butterfly net.png", + "label2": "Barehanded or magic butterfly net", + "low2": "25", + "high2": "145", + "req2": "83", + "color2": "green", + "image2": "Magic butterfly net.png" + } + ] + }, + { + "title": "Dragonfruit pie", + "names": [ + "items.dragonfruit_pie", + "items.half_dragonfruit_pie" + ], + "entries": [ + { + "label": "Dragonfruit pie cooking chance", + "showbefore": "no", + "label1": "Range", + "low1": "8", + "high1": "250", + "req1": "73", + "color1": "saddlebrown", + "image1": "Dragonfruit pie.png", + "label2": "Hosidius +5%", + "low2": "20", + "high2": "262", + "req2": "73", + "color2": "red", + "image2": "Dragonfruit pie.png", + "label3": "Hosidius +10%", + "low3": "33", + "high3": "275", + "req3": "79", + "color3": "blue", + "image3": "Dragonfruit pie.png" + } + ] + }, + { + "title": "Drunk dragon", + "names": [ + "items.drunk_dragon" + ], + "entries": [ + { + "label": "Drunk dragon experience gain chance", + "label1": "Range", + "low1": "118", + "high1": "492", + "req1": "32", + "color1": "saddlebrown", + "image1": "Drunk dragon.png", + "label2": "Hosidius +5%", + "low2": "130", + "high2": "504", + "req2": "32", + "color2": "red", + "image2": "Drunk dragon.png", + "label3": "Hosidius +10%", + "low3": "143", + "high3": "517", + "req3": "79", + "color3": "blue", + "image3": "Drunk dragon.png" + } + ] + }, + { + "title": "Dying tree", + "names": [ + "objects.fai_varrock_dead_tree" + ], + "entries": [ + { + "label": "Dying tree cut chance", + "label1": "Bronze", + "low1": "64", + "high1": "200", + "req1": "1", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "96", + "high2": "300", + "req2": "1", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "128", + "high3": "400", + "req3": "6", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "144", + "high4": "450", + "req4": "11", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "160", + "high5": "500", + "req5": "21", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "192", + "high6": "600", + "req6": "31", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "224", + "high7": "700", + "req7": "41", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "240", + "high8": "750", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png" + } + ] + }, + { + "title": "Earth impling", + "names": [ + "npcs.ii_impling_type_4", + "npcs.ii_impling_type_4_maze" + ], + "entries": [ + { + "label": "Earth impling catch chance", + "showbefore": "no", + "label1": "Butterfly net", + "low1": "51", + "high1": "302", + "req1": "36", + "color1": "saddlebrown", + "image1": "Butterfly net.png", + "label2": "Barehanded or magic butterfly net", + "low2": "71", + "high2": "322", + "req2": "36", + "color2": "green", + "image2": "Magic butterfly net.png" + } + ] + }, + { + "title": "Earth rune (The Slug Menace)", + "names": [ + "items.slug2_rune_earth" + ], + "entries": [ + { + "label": "Channeling blank rune success chance", + "xlabel": "Runecraft level", + "showbefore": "no", + "label1": "Earth rune", + "low1": "110", + "high1": "253", + "req1": "30", + "color1": "#563a09", + "image1": "Earth rune (The Slug Menace).png" + } + ] + }, + { + "title": "Earwen", + "names": [ + "npcs.prif_citizen_earwen" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Eclectic impling", + "names": [ + "npcs.ii_impling_type_6", + "npcs.ii_impling_type_6_maze" + ], + "entries": [ + { + "label": "Eclectic impling catch chance", + "showbefore": "no", + "label1": "Butterfly net", + "low1": "30", + "high1": "250", + "req1": "50", + "color1": "saddlebrown", + "image1": "Butterfly net.png", + "label2": "Barehanded or magic butterfly net", + "low2": "50", + "high2": "270", + "req2": "50", + "color2": "green", + "image2": "Magic butterfly net.png" + } + ] + }, + { + "title": "Edrahil", + "names": [ + "npcs.prif_citizen_edrahil" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Elenwe", + "names": [ + "npcs.prif_citizen_elenwe" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Elf (Thieving)", + "names": [], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Elladan", + "names": [ + "npcs.prif_citizen_elladan" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Empty plant pot", + "names": [ + "items.plantpot_empty" + ], + "entries": [ + { + "label": "Firing pottery success rate", + "xlabel": "Crafting level", + "showbefore": "no", + "label1": "Unfired plant pot", + "low1": "180", + "high1": "800", + "req1": "1", + "color1": "#bb8f6a", + "image1": "Unfired plant pot.png" + } + ] + }, + { + "title": "Enel", + "names": [ + "npcs.prif_citizen_enel" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Enelye", + "names": [ + "npcs.prif_citizen_enelye" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Enerdhil", + "names": [ + "npcs.prif_citizen_enerdhil" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Erestor", + "names": [ + "npcs.prif_citizen_erestor" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Essence impling", + "names": [ + "npcs.ii_impling_type_5", + "npcs.ii_impling_type_5_maze" + ], + "entries": [ + { + "label": "Essence impling catch chance", + "showbefore": "no", + "label1": "Butterfly net", + "low1": "40", + "high1": "275", + "req1": "42", + "color1": "saddlebrown", + "image1": "Butterfly net.png", + "label2": "Barehanded or magic butterfly net", + "low2": "60", + "high2": "295", + "req2": "42", + "color2": "green", + "image2": "Magic butterfly net.png" + } + ] + }, + { + "title": "Evergreen tree", + "names": [ + "objects.evergreen_vsnowy_large", + "objects.evergreen_snowy_large", + "objects.evergreen", + "objects.evergreen_large" + ], + "entries": [ + { + "label": "Evergreen tree cut chance", + "label1": "Bronze", + "low1": "64", + "high1": "200", + "req1": "1", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "96", + "high2": "300", + "req2": "1", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "128", + "high3": "400", + "req3": "6", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "144", + "high4": "450", + "req4": "11", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "160", + "high5": "500", + "req5": "21", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "192", + "high6": "600", + "req6": "31", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "224", + "high7": "700", + "req7": "41", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "240", + "high8": "750", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png" + } + ] + }, + { + "title": "Eyes (Abyss)", + "names": [ + "objects.rcu_abyssal_barrier_eyes1", + "objects.rcu_abyssal_barrier_eyes2", + "objects.rcu_abyssal_barrier_eyes3" + ], + "entries": [ + { + "label": "Eyes success chance", + "xlabel": "Thieving level", + "label1": "Success chance", + "low1": "0", + "high1": "255", + "image1": "Thieving icon.png", + "color1": "#692208" + } + ] + }, + { + "title": "Farmer", + "names": [ + "npcs.farmer1", + "npcs.farmer2", + "npcs.farmer3", + "npcs.farmer1_f", + "npcs.farmer2_f", + "npcs.farmer3_f", + "npcs.farmer4" + ], + "entries": [ + { + "label": "Farmer pickpocket chance", + "showbefore": "yes", + "label1": "Normal", + "low1": "150", + "high1": "240", + "req1": "7", + "color1": "gray", + "image1": "Thieving icon.png", + "label2": "Gloves of silence", + "low2": "157", + "high2": "252", + "req2": "7", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "165", + "high3": "264", + "req3": "38", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "181", + "high4": "290", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Fat snail meat", + "names": [ + "items.snail_corpse_cooked3" + ], + "entries": [ + { + "label": "Fat snail meat cooking chance", + "label1": "Fire or Range", + "low1": "73", + "high1": "402", + "req1": "22", + "color1": "gray", + "image1": "Fat snail meat.png", + "label2": "Lumbridge range", + "low2": "83", + "high2": "422", + "req2": "22", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "85", + "high3": "414", + "req3": "22", + "color3": "red", + "image3": "Fat snail meat.png", + "label4": "Hosidius +10%", + "low4": "98", + "high4": "427", + "req4": "79", + "color4": "blue", + "image4": "Fat snail meat.png" + } + ] + }, + { + "title": "Feanor", + "names": [ + "npcs.prif_citizen_feanor" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Findis", + "names": [ + "npcs.prif_citizen_findis" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Finduilas", + "names": [ + "npcs.prif_citizen_finduilas" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Fingolfin", + "names": [ + "npcs.prif_citizen_fingolfin" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Fingon", + "names": [ + "npcs.prif_citizen_fingon" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Fire rune (The Slug Menace)", + "names": [ + "items.slug2_rune_fire" + ], + "entries": [ + { + "label": "Channeling blank rune success chance", + "xlabel": "Runecraft level", + "showbefore": "no", + "label1": "Fire rune", + "low1": "110", + "high1": "253", + "req1": "30", + "color1": "#8b1d11", + "image1": "Fire rune (The Slug Menace).png" + } + ] + }, + { + "title": "Firemaking", + "names": [], + "entries": [ + { + "label": "Firemaking success chance", + "showbefore": "no", + "label1": "Normal", + "low1": "64", + "high1": "512", + "req1": "1", + "color1": "gray", + "image1": "Tinderbox.png" + } + ] + }, + { + "title": "Fish pie", + "names": [ + "items.fish_pie", + "items.half_fish_pie" + ], + "entries": [ + { + "label": "Fish pie cooking chance", + "label1": "Range", + "low1": "38", + "high1": "332", + "req1": "47", + "color1": "saddlebrown", + "image1": "Fish pie.png", + "label2": "Hosidius +5%", + "low2": "50", + "high2": "344", + "req2": "47", + "color2": "red", + "image2": "Fish pie.png", + "label3": "Hosidius +10%", + "low3": "63", + "high3": "357", + "req3": "79", + "color3": "blue", + "image3": "Fish pie.png" + } + ] + }, + { + "title": "Fishbowl (pet)", + "names": [ + "items.fishbowl_bluefish", + "items.fishbowl_greenfish", + "items.fishbowl_spinefish", + "npcs.poh_fishbowl_bluefish", + "npcs.poh_fishbowl_greenfish", + "npcs.poh_fishbowl_spinefish" + ], + "entries": [ + { + "label": "Pet fish catch rate", + "xlabel": "Fishing level", + "cascade": "yes", + "label1": "Spinefish", + "low1": "51", + "high1": "51", + "req1": "70", + "color1": "#ff9600", + "image1": "Fishbowl (orange).png", + "label2": "Greenfish", + "low2": "25", + "high2": "112", + "altlow2": "128", + "althigh2": "128", + "altreq2": "70", + "color2": "#00ff00", + "image2": "Fishbowl (green).png", + "label3": "Bluefish", + "low3": "255", + "high3": "255", + "color3": "#1ba5e3", + "image3": "Fishbowl (blue).png" + } + ] + }, + { + "title": "Fishing Trawler", + "names": [], + "entries": [ + { + "label": "Fishing Trawler fish", + "xlabel": "Fishing level", + "cascade": "yes", + "showbefore": "no", + "label1": "Manta ray", + "low1": "150", + "high1": "200", + "req1": "81", + "color1": "#515581", + "image1": "Raw manta ray.png", + "label2": "Sea turtle", + "low2": "150", + "high2": "200", + "req2": "79", + "color2": "#67a340", + "image2": "Raw sea turtle.png", + "label3": "Shark", + "low3": "150", + "high3": "200", + "req3": "76", + "color3": "#736b6b", + "image3": "Raw shark.png", + "label4": "Swordfish", + "low4": "150", + "high4": "200", + "req4": "50", + "color4": "mediumorchid", + "image4": "Raw swordfish.png", + "label5": "Lobster", + "low5": "150", + "high5": "200", + "req5": "40", + "color5": "#854c22", + "image5": "Raw lobster.png", + "label6": "Tuna", + "low6": "150", + "high6": "200", + "req6": "35", + "color6": "grey", + "image6": "Raw tuna.png", + "label7": "Oyster", + "low7": "150", + "high7": "200", + "req7": "16", + "color7": "wheat", + "image7": "Oyster.png", + "label8": "Anchovies", + "low8": "150", + "high8": "200", + "req8": "15", + "color8": "blue", + "image8": "Raw anchovies.png", + "label9": "Sardine", + "low9": "150", + "high9": "200", + "req9": "15", + "color9": "green", + "image9": "Raw sardine.png", + "label10": "Shrimps", + "low10": "150", + "high10": "200", + "req10": "15", + "color10": "#b18065", + "image10": "Raw shrimps.png" + } + ] + }, + { + "title": "Fishing spot (Tempoross Cove)", + "names": [ + "npcs.tempoross_harpoonfish_fishingspot_north", + "npcs.tempoross_harpoonfish_fishingspot_south", + "npcs.tempoross_harpoonfish_fishingspot_special" + ], + "entries": [ + { + "label": "Harpoonfish fishing chance", + "showbefore": "no", + "label1": "Harpoon", + "low1": "170", + "high1": "255", + "req1": "35", + "color1": "saddlebrown", + "image1": "Harpoon.png", + "label2": "Dragon harpoon", + "low2": "178", + "high2": "267", + "req2": "61", + "color2": "firebrick", + "image2": "Dragon harpoon.png", + "label3": "Crystal harpoon", + "low3": "187", + "high3": "280", + "req3": "71", + "color3": "cyan", + "image3": "Crystal harpoon.png" + } + ] + }, + { + "title": "Fishing spot (big net, harpoon)", + "names": [ + "npcs.0_40_53_memberfish", + "npcs.0_44_53_memberfish", + "npcs.0_33_51_memberfish", + "npcs.0_41_57_memberfish", + "npcs.0_54_49_memberfish", + "npcs.0_55_49_memberfish", + "npcs.0_43_42_memberfish", + "npcs.0_42_42_memberfish", + "npcs.0_37_59_lobster", + "npcs.0_28_56_memberfish", + "npcs.0_23_53_memberfish", + "npcs.0_26_54_memberfish", + "npcs.0_18_57_memberfish", + "npcs.0_19_58_memberfish", + "npcs.0_18_58_memberfish", + "npcs.0_33_52_memberfish", + "npcs.0_34_53_memberfish" + ], + "entries": [ + { + "label": "Big net fishing chance", + "showbefore": "no", + "label1": "Bass", + "low1": "3", + "high1": "40", + "req1": "46", + "color1": "#cb410b", + "image1": "Raw bass.png", + "label2": "Cod", + "low2": "4", + "high2": "55", + "req2": "23", + "color2": "blue", + "image2": "Raw cod.png", + "label3": "Casket", + "low3": "1", + "high3": "2", + "req3": "16", + "color3": "gold", + "image3": "Casket.png", + "label4": "Casket (skills necklace)", + "low4": "2", + "high4": "3", + "req4": "16", + "color4": "purple", + "image4": "Casket.png", + "label5": "Oyster", + "low5": "3", + "high5": "7", + "req5": "16", + "color5": "wheat", + "image5": "Oyster.png", + "label6": "Mackerel", + "low6": "5", + "high6": "65", + "bonuslow6": "10", + "bonushigh6": "10", + "req6": "16", + "color6": "#efcc00", + "image6": "Raw mackerel.png", + "label7": "Leather gloves", + "low7": "5", + "high7": "5", + "req7": "16", + "color7": "saddlebrown", + "image7": "Leather gloves.png", + "label8": "Seaweed", + "low8": "10", + "high8": "10", + "req8": "16", + "color8": "green", + "image8": "Seaweed.png", + "label9": "Leather boots", + "low9": "10", + "high9": "10", + "req9": "16", + "color9": "tan", + "image9": "Leather boots.png" + }, + { + "label": "Shark fishing chance", + "showbefore": "no", + "label1": "Harpoon", + "low1": "3", + "high1": "40", + "req1": "76", + "color1": "#736b6b", + "image1": "Harpoon.png" + } + ] + }, + { + "title": "Fishing spot (cage, harpoon)", + "names": [ + "npcs.0_40_53_rarefish", + "npcs.0_44_53_rarefish", + "npcs.0_45_49_rarefish", + "npcs.52_59_rarefish", + "npcs.0_40_60_rarefish", + "npcs.0_41_57_rarefish", + "npcs.0_37_59_tuna", + "npcs.0_28_56_rarefish", + "npcs.0_23_53_rarefish", + "npcs.0_26_54_rarefish", + "npcs.0_27_59_rarefish", + "npcs.0_38_45_rarefish", + "npcs.0_33_52_rarefish", + "npcs.0_34_53_rarefish", + "npcs.0_24_46_rarefish", + "npcs.0_21_44_rarefish" + ], + "entries": [ + { + "label": "Swordfish + tuna fishing chance", + "cascade": "yes", + "showbefore": "no", + "label1": "Swordfish", + "low1": "4", + "high1": "48", + "req1": "50", + "color1": "mediumorchid", + "image1": "Raw swordfish.png", + "label2": "Tuna", + "low2": "8", + "high2": "64", + "req2": "35", + "color2": "grey", + "image2": "Raw tuna.png" + } + ] + }, + { + "title": "Food Stall", + "names": [ + "objects.mm_stall_food" + ], + "entries": [ + { + "label": "Food Stall thieving chance", + "showbefore": "no", + "label1": "Food Stall", + "low1": "200", + "high1": "480", + "req1": "5", + "color1": "yellow", + "image1": "Banana.png" + } + ] + }, + { + "title": "Fresh monkfish", + "names": [ + "items.swan_raw_monkfish", + "items.swan_monkfish" + ], + "entries": [ + { + "label": "Fresh monkfish cooking chance", + "label1": "Fire or Range", + "low1": "100", + "high1": "240", + "req1": "62", + "color1": "gray", + "image1": "Fresh monkfish.png", + "label2": "Hosidius +5%", + "low2": "112", + "high2": "252", + "req2": "62", + "color2": "red", + "image2": "Fresh monkfish.png", + "label3": "Hosidius +10%", + "low3": "125", + "high3": "265", + "req3": "79", + "color3": "blue", + "image3": "Fresh monkfish.png" + } + ] + }, + { + "title": "Fried mushrooms", + "names": [ + "items.bowl_mushroom_fried" + ], + "entries": [ + { + "label": "Fried mushrooms cooking chance", + "label1": "Fire or Range", + "low1": "16", + "high1": "282", + "req1": "46", + "color1": "gray", + "image1": "Fried mushrooms.png", + "label2": "Hosidius +5%", + "low2": "28", + "high2": "294", + "req2": "46", + "color2": "red", + "image2": "Fried mushrooms.png", + "label3": "Hosidius +10%", + "low3": "41", + "high3": "307", + "req3": "79", + "color3": "blue", + "image3": "Fried mushrooms.png" + } + ] + }, + { + "title": "Fried onions", + "names": [ + "items.bowl_onion_fried" + ], + "entries": [ + { + "label": "Fried onions cooking chance", + "label1": "Fire or Range", + "low1": "36", + "high1": "322", + "req1": "42", + "color1": "gray", + "image1": "Fried onions.png", + "label2": "Hosidius +5%", + "low2": "48", + "high2": "334", + "req2": "42", + "color2": "red", + "image2": "Fried onions.png", + "label3": "Hosidius +10%", + "low3": "61", + "high3": "347", + "req3": "79", + "color3": "blue", + "image3": "Fried onions.png" + } + ] + }, + { + "title": "Frog spawn", + "names": [ + "items.giant_frogspawn" + ], + "entries": [ + { + "label": "Frog spawn chance", + "showbefore": "no", + "label1": "Frog spawn", + "low1": "16", + "high1": "96", + "req1": "33", + "color1": "#464f35", + "image1": "Frog spawn.png", + "label2": "Swamp weed", + "low2": "10", + "high2": "10", + "req2": "33", + "color2": "#686800", + "image2": "Swamp weed.png" + } + ] + }, + { + "title": "Fruit batta", + "names": [ + "items.fruit_batta" + ], + "entries": [ + { + "label": "Fruit batta cooking chance", + "label1": "Range", + "low1": "118", + "high1": "492", + "req1": "1", + "color1": "gray", + "image1": "Fruit batta.png", + "label2": "Hosidius +5%", + "low2": "130", + "high2": "504", + "req2": "1", + "color2": "red", + "image2": "Fruit batta.png", + "label3": "Hosidius +10%", + "low3": "143", + "high3": "517", + "req3": "79", + "color3": "blue", + "image3": "Fruit batta.png" + } + ] + }, + { + "title": "Galathil", + "names": [ + "npcs.prif_citizen_galathil" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Gap (Abyss)", + "names": [ + "objects.rcu_abyssal_barrier_agility" + ], + "entries": [ + { + "label": "Gap success chance", + "xlabel": "Agility level", + "label1": "Success chance", + "low1": "0", + "high1": "255", + "image1": "Agility icon.png", + "color1": "#692208" + } + ] + }, + { + "title": "Garden pie", + "names": [ + "items.garden_pie", + "items.half_garden_pie" + ], + "entries": [ + { + "label": "Garden pie cooking chance", + "label1": "Range", + "low1": "48", + "high1": "352", + "req1": "34", + "color1": "saddlebrown", + "image1": "Garden pie.png", + "label2": "Hosidius +5%", + "low2": "60", + "high2": "364", + "req2": "34", + "color2": "red", + "image2": "Garden pie.png", + "label3": "Hosidius +10%", + "low3": "73", + "high3": "377", + "req3": "79", + "color3": "blue", + "image3": "Garden pie.png" + } + ] + }, + { + "title": "Gelmir", + "names": [ + "npcs.prif_citizen_gelmir" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Gem rocks", + "names": [ + "objects.gemrock", + "objects.gemrock1", + "objects.village_gem_rock1", + "objects.village_gem_rock2", + "objects.village_gem_rock3" + ], + "entries": [ + { + "label": "Gem rock mining chance", + "showbefore": "no", + "label1": "Normal", + "low1": "28", + "high1": "70", + "req1": "40", + "color1": "gray", + "image1": "Rune pickaxe.png", + "label2": "Charged glory", + "low2": "84", + "high2": "210", + "req2": "40", + "color2": "purple", + "image2": "Amulet of glory(6).png" + } + ] + }, + { + "title": "General Stall", + "names": [ + "objects.mm_stall_general" + ], + "entries": [ + { + "label": "General Stall thieving chance", + "showbefore": "no", + "label1": "General Stall", + "low1": "128", + "high1": "512", + "req1": "5", + "color1": "orange", + "image1": "Pot.png" + } + ] + }, + { + "title": "Giant carp", + "names": [ + "items.giant_carp" + ], + "entries": [ + { + "label": "Giant carp cooking chance", + "label1": "Fire or Range", + "low1": "98", + "high1": "452", + "req1": "1", + "color1": "gray", + "image1": "Giant carp.png", + "label2": "Lumbridge range", + "low2": "108", + "high2": "472", + "req2": "1", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "110", + "high3": "464", + "req3": "1", + "color3": "red", + "image3": "Giant carp.png", + "label4": "Hosidius +10%", + "low4": "123", + "high4": "477", + "req4": "79", + "color4": "blue", + "image4": "Giant carp.png" + } + ] + }, + { + "title": "Glorfindel", + "names": [ + "npcs.prif_citizen_glorfindel" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Gnome", + "names": [ + "npcs.battlefield_darkskinned_gnome_archer", + "npcs.gnome", + "npcs.browclothedgnome", + "npcs.darkskinned_gnome", + "npcs.battlefield_gnome_troop", + "npcs.battlefield_gnome_archer" + ], + "entries": [ + { + "label": "Gnome pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "43", + "high1": "175", + "req1": "75", + "color1": "gray", + "image1": "Thief Gnome.png", + "label2": "Gloves of silence", + "low2": "45", + "high2": "183", + "req2": "75", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "47", + "high3": "192", + "req3": "75", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "51", + "high4": "211", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Gnome woman", + "names": [ + "npcs.gnomefemale", + "npcs.gnomefemale_dskinned" + ], + "entries": [ + { + "label": "Gnome pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "43", + "high1": "175", + "req1": "75", + "color1": "gray", + "image1": "Thief Gnome.png", + "label2": "Gloves of silence", + "low2": "45", + "high2": "183", + "req2": "75", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "47", + "high3": "192", + "req3": "75", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "51", + "high4": "211", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Gold rocks", + "names": [ + "objects.goldrock2", + "objects.goldrock1", + "objects.prif_mine_goldrock1" + ], + "entries": [ + { + "label": "Gold rocks mining chance", + "showbefore": "no", + "label1": "Gold rocks", + "low1": "7", + "high1": "75", + "req1": "40", + "color1": "goldenrod", + "image1": "Gold ore.png" + } + ] + }, + { + "title": "Golden warbler", + "names": [ + "npcs.hunting_bird_desert" + ], + "entries": [ + { + "label": "Golden warbler catch chance", + "showbefore": "no", + "label1": "Golden warbler", + "low1": "92", + "high1": "400", + "req1": "5", + "color1": "#bfbf2a", + "image1": "Golden warbler icon.png" + } + ] + }, + { + "title": "Goreu", + "names": [ + "npcs.mourning_town_elf_1" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Gourmet impling", + "names": [ + "npcs.ii_impling_type_3", + "npcs.ii_impling_type_3_maze" + ], + "entries": [ + { + "label": "Gourmet impling catch chance", + "showbefore": "no", + "label1": "Butterfly net", + "low1": "61", + "high1": "325", + "req1": "28", + "color1": "saddlebrown", + "image1": "Butterfly net.png", + "label2": "Barehanded or magic butterfly net", + "low2": "81", + "high2": "345", + "req2": "28", + "color2": "green", + "image2": "Magic butterfly net.png" + } + ] + }, + { + "title": "Grand Gold Chest", + "names": [ + "objects.ntk_golden_chest_closed", + "objects.ntk_golden_chest_open" + ], + "entries": [ + { + "label": "Chance of successfully looting grand gold chest", + "showbefore": "no", + "label1": "Chance", + "low1": "130", + "high1": "220", + "req1": "21", + "color1": "#897b31", + "image1": "Pharaoh's sceptre.png" + } + ] + }, + { + "title": "Granite rocks", + "names": [ + "objects.enakh_granite_rocks" + ], + "entries": [ + { + "label": "Granite rock mining chance", + "cascade": "yes", + "showbefore": "no", + "label1": "5kg", + "low1": "6", + "high1": "64", + "req1": "45", + "color1": "gray", + "image1": "Granite (5kg).png", + "label2": "2kg", + "low2": "8", + "high2": "75", + "req2": "45", + "color2": "red", + "image2": "Granite (2kg).png", + "label3": "500g", + "low3": "16", + "high3": "100", + "req3": "45", + "color3": "blue", + "image3": "Granite (500g).png" + } + ] + }, + { + "title": "Grape seed", + "names": [ + "items.grape_seed" + ], + "entries": [ + { + "label": "Grapes yield", + "xlabel": "Farming level", + "ylabel": "Average yield", + "showbefore": "no", + "ystep": "2", + "label1": "Regular", + "low1": "-50", + "high1": "180", + "lives1": "5", + "req1": "36", + "color1": "#79874c", + "image1": "Grapes.png", + "label2": "Attas", + "low2": "-52", + "high2": "189", + "lives2": "5", + "req2": "36", + "color2": "#be5e57", + "image2": "Attas icon.png", + "label3": "Magic secateurs", + "low3": "-44", + "high3": "186", + "lives3": "5", + "req3": "36", + "color3": "#0d8415", + "image3": "Magic secateurs.png", + "label4": "Magic secateurs, attas", + "low4": "-46", + "high4": "195", + "lives4": "5", + "req4": "36", + "color4": "#ffa210", + "image4": "Magic secateurs and attas.png" + }, + { + "label": "Zamorak's grapes yield", + "xlabel": "Farming level", + "ylabel": "Average yield", + "showbefore": "no", + "ystep": "2", + "label1": "Regular", + "low1": "-70", + "high1": "160", + "lives1": "5", + "req1": "36", + "color1": "#79874c", + "image1": "Zamorak's grapes.png", + "label2": "Attas", + "low2": "-73", + "high2": "168", + "lives2": "5", + "req2": "36", + "color2": "#be5e57", + "image2": "Attas icon.png", + "label3": "Magic secateurs", + "low3": "-64", + "high3": "166", + "lives3": "5", + "req3": "36", + "color3": "#0d8415", + "image3": "Magic secateurs.png", + "label4": "Magic secateurs, attas", + "low4": "-67", + "high4": "174", + "lives4": "5", + "req4": "36", + "color4": "#ffa210", + "image4": "Magic secateurs and attas.png" + } + ] + }, + { + "title": "Grape vine", + "names": [ + "objects.grapevine_clickzone_xp", + "objects.grapevine_grapes_5", + "objects.grapevine_clickzone_grapes_5", + "objects.grapevine_grapes_4", + "objects.grapevine_clickzone_grapes_4", + "objects.grapevine_grapes_3", + "objects.grapevine_clickzone_grapes_3", + "objects.grapevine_grapes_2", + "objects.grapevine_clickzone_grapes_2", + "objects.grapevine_grape_1", + "objects.grapevine_clickzone_grape_1", + "objects.grapevine_clickzone_seedling", + "objects.grapevine_seedling", + "objects.grapevine_clickzone_growing_1", + "objects.grapevine_growing_1", + "objects.grapevine_clickzone_growing_2", + "objects.grapevine_growing_2", + "objects.grapevine_clickzone_growing_3", + "objects.grapevine_growing_3", + "objects.grapevine_clickzone_growing_4", + "objects.grapevine_growing_4", + "objects.grapevine_clickzone_growing_5", + "objects.grapevine_growing_5", + "objects.grapevine_clickzone_growing_6", + "objects.grapevine_growing_6", + "objects.grapevine_dead", + "objects.grapevine_clickzone_dead" + ], + "entries": [ + { + "label": "Grapes yield", + "xlabel": "Farming level", + "ylabel": "Average yield", + "showbefore": "no", + "ystep": "2", + "label1": "Regular", + "low1": "-50", + "high1": "180", + "lives1": "5", + "req1": "36", + "color1": "#79874c", + "image1": "Grapes.png", + "label2": "Attas", + "low2": "-52", + "high2": "189", + "lives2": "5", + "req2": "36", + "color2": "#be5e57", + "image2": "Attas icon.png", + "label3": "Magic secateurs", + "low3": "-44", + "high3": "186", + "lives3": "5", + "req3": "36", + "color3": "#0d8415", + "image3": "Magic secateurs.png", + "label4": "Magic secateurs, attas", + "low4": "-46", + "high4": "195", + "lives4": "5", + "req4": "36", + "color4": "#ffa210", + "image4": "Magic secateurs and attas.png" + }, + { + "label": "Zamorak's grapes yield", + "xlabel": "Farming level", + "ylabel": "Average yield", + "showbefore": "no", + "ystep": "2", + "label1": "Regular", + "low1": "-70", + "high1": "160", + "lives1": "5", + "req1": "36", + "color1": "#79874c", + "image1": "Zamorak's grapes.png", + "label2": "Attas", + "low2": "-73", + "high2": "168", + "lives2": "5", + "req2": "36", + "color2": "#be5e57", + "image2": "Attas icon.png", + "label3": "Magic secateurs", + "low3": "-64", + "high3": "166", + "lives3": "5", + "req3": "36", + "color3": "#0d8415", + "image3": "Magic secateurs.png", + "label4": "Magic secateurs, attas", + "low4": "-67", + "high4": "174", + "lives4": "5", + "req4": "36", + "color4": "#ffa210", + "image4": "Magic secateurs and attas.png" + } + ] + }, + { + "title": "Guard", + "names": [ + "npcs.guard1", + "npcs.guard1_variant01", + "npcs.guard1_f", + "npcs.guard1_f_variant01", + "npcs.fai_falador_guard1", + "npcs.fai_falador_guard1_variant01", + "npcs.fai_falador_guard1_f", + "npcs.fai_falador_guard1_variant02", + "npcs.fai_falador_guard2", + "npcs.fai_falador_guard2_f", + "npcs.fai_falador_guard3", + "npcs.fai_falador_guard3_f", + "npcs.fai_falador_guard5", + "npcs.fai_falador_guard6", + "npcs.fai_falador_guard3_f", + "npcs.fai_varrock_guard02_variant01", + "npcs.fai_varrock_guard02_variant02", + "npcs.fai_varrock_guard02_f", + "npcs.fai_varrock_guard02_f_variant01", + "npcs.fai_varrock_guard02_f_variant02", + "npcs.ardougne_guard", + "npcs.ardougne_guard_variant01", + "npcs.ardougne_guard_f", + "npcs.ardougne_guard_f_variant01" + ], + "entries": [ + { + "label": "Guard pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "50", + "high1": "240", + "req1": "40", + "color1": "gray", + "image1": "Thief Guard.png", + "label2": "Gloves of silence", + "low2": "52", + "high2": "252", + "req2": "40", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "55", + "high3": "264", + "req3": "40", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "60", + "high4": "290", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Guard (Aldarin)", + "names": [ + "npcs.aldarin_guard_m_1", + "npcs.aldarin_guard_m_2", + "npcs.aldarin_guard_m_3", + "npcs.aldarin_guard_m_4", + "npcs.aldarin_guard_m_5", + "npcs.aldarin_guard_f_1", + "npcs.aldarin_guard_f_2", + "npcs.aldarin_guard_f_3", + "npcs.aldarin_guard_f_4", + "npcs.aldarin_guard_f_5" + ], + "entries": [ + { + "label": "Guard pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "50", + "high1": "240", + "req1": "40", + "color1": "gray", + "image1": "Thief Guard.png", + "label2": "Gloves of silence", + "low2": "52", + "high2": "252", + "req2": "40", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "55", + "high3": "264", + "req3": "67", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "60", + "high4": "290", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Guard (Doric's hut)", + "names": [ + "npcs.falador_doric_area_guard" + ], + "entries": [ + { + "label": "Guard pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "50", + "high1": "240", + "req1": "40", + "color1": "gray", + "image1": "Thief Guard.png", + "label2": "Gloves of silence", + "low2": "52", + "high2": "252", + "req2": "40", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "55", + "high3": "264", + "req3": "40", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "60", + "high4": "290", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Guard (Hosidius)", + "names": [ + "npcs.hos_town_guard_01", + "npcs.hos_town_guard_02", + "npcs.hos_town_guard_03", + "npcs.hos_town_guard_04" + ], + "entries": [ + { + "label": "Guard pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "50", + "high1": "240", + "req1": "40", + "color1": "gray", + "image1": "Thief Guard.png", + "label2": "Gloves of silence", + "low2": "52", + "high2": "252", + "req2": "40", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "55", + "high3": "264", + "req3": "67", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "60", + "high4": "290", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Guard (Port Sarim jail)", + "names": [ + "npcs.jail_guard_1", + "npcs.jail_guard_2", + "npcs.jail_guard_3", + "npcs.jail_guard_4", + "npcs.jail_guard_5" + ], + "entries": [ + { + "label": "Guard pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "50", + "high1": "240", + "req1": "40", + "color1": "gray", + "image1": "Thief Guard.png", + "label2": "Gloves of silence", + "low2": "52", + "high2": "252", + "req2": "40", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "55", + "high3": "264", + "req3": "40", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "60", + "high4": "290", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Guard (Varlamore)", + "names": [ + "npcs.varlamore_guard_m_1", + "npcs.varlamore_guard_m_2", + "npcs.varlamore_guard_m_3", + "npcs.varlamore_guard_m_4", + "npcs.varlamore_guard_m_5", + "npcs.varlamore_guard_f_1", + "npcs.varlamore_guard_f_2", + "npcs.varlamore_guard_f_3", + "npcs.varlamore_guard_f_4", + "npcs.varlamore_guard_f_5" + ], + "entries": [ + { + "label": "Guard pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "50", + "high1": "240", + "req1": "40", + "color1": "gray", + "image1": "Thief Guard.png", + "label2": "Gloves of silence", + "low2": "52", + "high2": "252", + "req2": "40", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "55", + "high3": "264", + "req3": "67", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "60", + "high4": "290", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Guilin", + "names": [ + "npcs.prif_citizen_guilin" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "H.A.M. Member", + "names": [ + "npcs.favour_male_ham_civilian", + "npcs.favour_female_ham_civilian" + ], + "entries": [ + { + "label": "Avoiding concussions using Agility", + "label1": "", + "low1": "0", + "high1": "254", + "req1": "15", + "showbefore": "yes", + "color1": "black", + "image1": "Agility icon.png" + }, + { + "label": "H.A.M Member pickpocket chance", + "label1": "Normal", + "low1": "135", + "high1": "239", + "req1": "15", + "color1": "gray", + "image1": "Thieving icon.png", + "label2": "Gloves of silence", + "low2": "141", + "high2": "250", + "req2": "15", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "148", + "high3": "262", + "req3": "72", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "162", + "high4": "288", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Half baked batta", + "names": [ + "items.half_baked_batta" + ], + "entries": [ + { + "label": "Half baked batta cooking chance", + "label1": "Range", + "low1": "118", + "high1": "492", + "req1": "1", + "color1": "saddlebrown", + "image1": "Half baked batta.png", + "label2": "Hosidius +5%", + "low2": "130", + "high2": "504", + "req2": "1", + "color2": "red", + "image2": "Half baked batta.png", + "label3": "Hosidius +10%", + "low3": "143", + "high3": "517", + "req3": "79", + "color3": "blue", + "image3": "Half baked batta.png" + } + ] + }, + { + "title": "Half baked bowl", + "names": [ + "items.half_baked_bowl" + ], + "entries": [ + { + "label": "Half baked bowl cooking chance", + "label1": "Range", + "low1": "118", + "high1": "492", + "req1": "1", + "color1": "saddlebrown", + "image1": "Half baked bowl.png", + "label2": "Hosidius +5%", + "low2": "130", + "high2": "504", + "req2": "1", + "color2": "red", + "image2": "Half baked bowl.png", + "label3": "Hosidius +10%", + "low3": "143", + "high3": "517", + "req3": "79", + "color3": "blue", + "image3": "Half baked bowl.png" + } + ] + }, + { + "title": "Half baked crunchy", + "names": [ + "items.half_baked_crunchy" + ], + "entries": [ + { + "label": "Half baked crunchy cooking chance", + "label1": "Range", + "low1": "118", + "high1": "492", + "req1": "1", + "color1": "saddlebrown", + "image1": "Half baked crunchy.png", + "label2": "Hosidius +5%", + "low2": "130", + "high2": "504", + "req2": "1", + "color2": "red", + "image2": "Half baked crunchy.png", + "label3": "Hosidius +10%", + "low3": "143", + "high3": "517", + "req3": "79", + "color3": "blue", + "image3": "Half baked crunchy.png" + } + ] + }, + { + "title": "Hendor (elf)", + "names": [ + "npcs.prif_citizen_hendor" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Herbiboar", + "names": [ + "npcs.fossil_herbiboar_visible", + "npcs.fossil_herbiboar_anim_visible" + ], + "entries": [ + { + "label": "Herbiboar herb chance", + "xlabel": "Herblore level", + "cascade": "yes", + "showbefore": "no", + "lowLevel": "31", + "label1": "Ranarr weed", + "low1": "-10", + "high1": "20", + "req1": "31", + "image1": "Grimy ranarr weed.png", + "color1": "#006400", + "label2": "Torstol", + "low2": "-70", + "high2": "20", + "req2": "31", + "image2": "Grimy torstol.png", + "color2": "#ff0000", + "label3": "Snapdragon", + "low3": "-60", + "high3": "20", + "req3": "31", + "image3": "Grimy snapdragon.png", + "color3": "#0000ff", + "label4": "Dwarf weed", + "low4": "-50", + "high4": "30", + "req4": "31", + "image4": "Grimy dwarf weed.png", + "color4": "#ff00ff", + "label5": "Lantadyme", + "low5": "-30", + "high5": "40", + "req5": "31", + "image5": "Grimy lantadyme.png", + "color5": "#ffdead", + "label6": "Cadantine", + "low6": "-10", + "high6": "50", + "req6": "31", + "image6": "Grimy cadantine.png", + "color6": "#a0522d", + "label7": "Kwuarm", + "low7": "10", + "high7": "60", + "req7": "31", + "image7": "Grimy kwuarm.png", + "color7": "#ffa500", + "label8": "Avantoe", + "low8": "20", + "high8": "60", + "req8": "31", + "image8": "Grimy avantoe.png", + "color8": "#00ff00", + "label9": "Irit leaf", + "low9": "30", + "high9": "70", + "req9": "31", + "image9": "Grimy irit leaf.png", + "color9": "#ffff00", + "label10": "Tarromin", + "low10": "70", + "high10": "-20", + "req10": "31", + "image10": "Grimy tarromin.png", + "color10": "#1e90ff", + "label11": "Harralander", + "low11": "100", + "high11": "-30", + "req11": "31", + "image11": "Grimy harralander.png", + "color11": "#4b0082", + "label12": "Marrentill", + "low12": "170", + "high12": "-40", + "req12": "31", + "image12": "Grimy marrentill.png", + "color12": "#708090", + "label13": "Guam", + "low13": "225", + "high13": "324", + "req13": "31", + "image13": "Grimy guam leaf.png", + "color13": "#000000" + } + ] + }, + { + "title": "Hero", + "names": [ + "npcs.hero", + "npcs.hero_variant01", + "npcs.hero_f" + ], + "entries": [ + { + "label": "Hero pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "39", + "high1": "160", + "req1": "80", + "color1": "gray", + "image1": "Thief Hero.png", + "label2": "Gloves of silence", + "low2": "40", + "high2": "168", + "req2": "80", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "42", + "high3": "176", + "req3": "80", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "46", + "high4": "193", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Herring", + "names": [ + "items.herring" + ], + "entries": [ + { + "label": "Herring cooking chance", + "label1": "Fire or Range", + "low1": "108", + "high1": "472", + "req1": "5", + "color1": "gray", + "image1": "Herring.png", + "label2": "Lumbridge range", + "low2": "118", + "high2": "492", + "req2": "5", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "120", + "high3": "484", + "req3": "5", + "color3": "red", + "image3": "Herring.png", + "label4": "Hosidius +10%", + "low4": "133", + "high4": "497", + "req4": "79", + "color4": "blue", + "image4": "Herring.png" + } + ] + }, + { + "title": "Hollow tree", + "names": [ + "objects.hollow_tree", + "objects.hollow_tree_big" + ], + "entries": [ + { + "label": "Hollow tree cut chance", + "showbefore": "no", + "label1": "Bronze", + "low1": "18", + "high1": "26", + "req1": "45", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "28", + "high2": "40", + "req2": "45", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "36", + "high3": "54", + "req3": "45", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "42", + "high4": "57", + "req4": "45", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "46", + "high5": "68", + "req5": "45", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "59", + "high6": "81", + "req6": "45", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "64", + "high7": "94", + "req7": "45", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "67", + "high8": "101", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png" + } + ] + }, + { + "title": "Hopper (Trouble Brewing)", + "names": [ + "objects.brew_hopper_red", + "objects.brew_hopper_blue", + "objects.brew_hopper_red_burning_1", + "objects.brew_hopper_red_burning_2", + "objects.brew_hopper_blue_burning_1", + "objects.brew_hopper_blue_burning_2", + "objects.brew_hopper_red_damaged_1", + "objects.brew_hopper_red_damaged_2", + "objects.brew_hopper_red_wet_1", + "objects.brew_hopper_red_wet_2", + "objects.brew_hopper_red_destroyed", + "objects.brew_hopper_blue_damaged_1", + "objects.brew_hopper_blue_damaged_2", + "objects.brew_hopper_blue_wet_1", + "objects.brew_hopper_blue_wet_2", + "objects.brew_hopper_blue_destroyed" + ], + "entries": [ + { + "label": "Torch burn chance", + "xlabel": "Firemaking level", + "showbefore": "no", + "label1": "Successful burn", + "low1": "12", + "high1": "112", + "req1": "1", + "color1": "red", + "image1": "Lit torch.png" + } + ] + }, + { + "title": "Hunters' loot sack (adept)", + "names": [ + "items.hg_lootsack_t1" + ], + "entries": [ + { + "label": "Herb chance", + "cascade": "yes", + "showbefore": "no", + "ylabel": "Probability", + "label1": "Lantadyme", + "low1": "-30", + "high1": "60", + "color1": "#1b9e77", + "image1": "Lantadyme.png", + "req1": "34", + "label2": "Cadantine", + "low2": "-10", + "high2": "70", + "color2": "#d95f02", + "image2": "Cadantine.png", + "req2": "13", + "label3": "Kwuarm", + "low3": "10", + "high3": "85", + "color3": "#7570b3", + "image3": "Kwuarm.png", + "label4": "Avantoe", + "low4": "20", + "high4": "100", + "color4": "#e7298a", + "image4": "Avantoe.png", + "label5": "Irit", + "low5": "30", + "high5": "115", + "color5": "#66a61e", + "image5": "Irit leaf.png", + "label6": "Ranarr", + "low6": "10", + "high6": "170", + "color6": "#e6ab02", + "image6": "Ranarr weed.png", + "label7": "Tarromin", + "low7": "70", + "high7": "-20", + "color7": "#a6761d", + "image7": "Tarromin.png", + "label8": "Harralander", + "low8": "999", + "high8": "999", + "color8": "SteelBlue", + "image8": "Harralander.png", + "lives": "999" + }, + { + "label": "Log chance", + "cascade": "yes", + "showbefore": "no", + "ylabel": "Probability", + "label1": "Magic", + "low1": "-60", + "high1": "60", + "color1": "DarkCyan", + "image1": "Magic logs.png", + "req1": "50", + "label2": "Yew", + "low2": "-50", + "high2": "90", + "color2": "OliveDrab", + "image2": "Yew logs.png", + "req2": "36", + "label3": "Mahogany", + "low3": "-40", + "high3": "130", + "color3": "FireBrick", + "image3": "Mahogany logs.png", + "req3": "24", + "label4": "Maple", + "low4": "0", + "high4": "160", + "color4": "DarkGoldenrod", + "image4": "Maple logs.png", + "label5": "Teak", + "low5": "999", + "high5": "999", + "color5": "DarkKhaki", + "image5": "Teak logs.png", + "lives5": [] + } + ] + }, + { + "title": "Hunters' loot sack (basic)", + "names": [ + "items.hg_lootsack_t0" + ], + "entries": [ + { + "label": "Log chance", + "cascade": "yes", + "showbefore": "no", + "ylabel": "Probability", + "label1": "Magic", + "low1": "-60", + "high1": "60", + "color1": "DarkCyan", + "image1": "Magic logs.png", + "req1": "50", + "label2": "Yew", + "low2": "-50", + "high2": "90", + "color2": "OliveDrab", + "image2": "Yew logs.png", + "req2": "36", + "label3": "Mahogany", + "low3": "-40", + "high3": "130", + "color3": "FireBrick", + "image3": "Mahogany logs.png", + "req3": "24", + "label4": "Maple", + "low4": "0", + "high4": "160", + "color4": "DarkGoldenrod", + "image4": "Maple logs.png", + "label5": "Teak", + "low5": "999", + "high5": "999", + "color5": "DarkKhaki", + "image5": "Teak logs.png", + "lives5": [] + } + ] + }, + { + "title": "Hunters' loot sack (expert)", + "names": [ + "items.hg_lootsack_t2" + ], + "entries": [ + { + "label": "Herb chance", + "cascade": "yes", + "showbefore": "no", + "ylabel": "Probability", + "label1": "Lantadyme", + "low1": "-30", + "high1": "60", + "color1": "#1b9e77", + "image1": "Lantadyme.png", + "req1": "34", + "label2": "Cadantine", + "low2": "-10", + "high2": "70", + "color2": "#d95f02", + "image2": "Cadantine.png", + "req2": "13", + "label3": "Kwuarm", + "low3": "10", + "high3": "85", + "color3": "#7570b3", + "image3": "Kwuarm.png", + "label4": "Avantoe", + "low4": "20", + "high4": "100", + "color4": "#e7298a", + "image4": "Avantoe.png", + "label5": "Irit", + "low5": "30", + "high5": "115", + "color5": "#66a61e", + "image5": "Irit leaf.png", + "label6": "Ranarr", + "low6": "10", + "high6": "170", + "color6": "#e6ab02", + "image6": "Ranarr weed.png", + "label7": "Tarromin", + "low7": "70", + "high7": "-20", + "color7": "#a6761d", + "image7": "Tarromin.png", + "label8": "Harralander", + "low8": "999", + "high8": "999", + "color8": "SteelBlue", + "image8": "Harralander.png", + "lives": "999" + }, + { + "label": "Log chance", + "cascade": "yes", + "showbefore": "no", + "ylabel": "Probability", + "label1": "Magic", + "low1": "-60", + "high1": "60", + "color1": "DarkCyan", + "image1": "Magic logs.png", + "req1": "50", + "label2": "Yew", + "low2": "-50", + "high2": "90", + "color2": "OliveDrab", + "image2": "Yew logs.png", + "req2": "36", + "label3": "Mahogany", + "low3": "-40", + "high3": "130", + "color3": "FireBrick", + "image3": "Mahogany logs.png", + "req3": "24", + "label4": "Maple", + "low4": "0", + "high4": "160", + "color4": "DarkGoldenrod", + "image4": "Maple logs.png", + "label5": "Teak", + "low5": "999", + "high5": "999", + "color5": "DarkKhaki", + "image5": "Teak logs.png", + "lives5": [] + } + ] + }, + { + "title": "Hunters' loot sack (master)", + "names": [ + "items.hg_lootsack_t3" + ], + "entries": [ + { + "label": "Herb chance", + "cascade": "yes", + "showbefore": "no", + "ylabel": "Probability", + "label1": "Lantadyme", + "low1": "-30", + "high1": "60", + "color1": "#1b9e77", + "image1": "Lantadyme.png", + "req1": "34", + "label2": "Cadantine", + "low2": "-10", + "high2": "70", + "color2": "#d95f02", + "image2": "Cadantine.png", + "req2": "13", + "label3": "Kwuarm", + "low3": "10", + "high3": "85", + "color3": "#7570b3", + "image3": "Kwuarm.png", + "label4": "Avantoe", + "low4": "20", + "high4": "100", + "color4": "#e7298a", + "image4": "Avantoe.png", + "label5": "Irit", + "low5": "30", + "high5": "115", + "color5": "#66a61e", + "image5": "Irit leaf.png", + "label6": "Ranarr", + "low6": "10", + "high6": "170", + "color6": "#e6ab02", + "image6": "Ranarr weed.png", + "label7": "Tarromin", + "low7": "70", + "high7": "-20", + "color7": "#a6761d", + "image7": "Tarromin.png", + "label8": "Harralander", + "low8": "999", + "high8": "999", + "color8": "SteelBlue", + "image8": "Harralander.png", + "lives": "999" + }, + { + "label": "Log chance", + "cascade": "yes", + "showbefore": "no", + "ylabel": "Probability", + "label1": "Magic", + "low1": "-60", + "high1": "60", + "color1": "DarkCyan", + "image1": "Magic logs.png", + "req1": "50", + "label2": "Yew", + "low2": "-50", + "high2": "90", + "color2": "OliveDrab", + "image2": "Yew logs.png", + "req2": "36", + "label3": "Mahogany", + "low3": "-40", + "high3": "130", + "color3": "FireBrick", + "image3": "Mahogany logs.png", + "req3": "24", + "label4": "Maple", + "low4": "0", + "high4": "160", + "color4": "DarkGoldenrod", + "image4": "Maple logs.png", + "label5": "Teak", + "low5": "999", + "high5": "999", + "color5": "DarkKhaki", + "image5": "Teak logs.png", + "lives5": [] + } + ] + }, + { + "title": "Hunters' loot sack (supplies)", + "names": [ + "items.hg_lootsack_trade" + ], + "entries": [ + { + "label": "Herb chance", + "cascade": "yes", + "showbefore": "no", + "ylabel": "Probability", + "label1": "Lantadyme", + "low1": "-30", + "high1": "60", + "color1": "#1b9e77", + "image1": "Lantadyme.png", + "req1": "34", + "label2": "Cadantine", + "low2": "-10", + "high2": "70", + "color2": "#d95f02", + "image2": "Cadantine.png", + "req2": "13", + "label3": "Kwuarm", + "low3": "10", + "high3": "85", + "color3": "#7570b3", + "image3": "Kwuarm.png", + "label4": "Avantoe", + "low4": "20", + "high4": "100", + "color4": "#e7298a", + "image4": "Avantoe.png", + "label5": "Irit", + "low5": "30", + "high5": "115", + "color5": "#66a61e", + "image5": "Irit leaf.png", + "label6": "Ranarr", + "low6": "10", + "high6": "170", + "color6": "#e6ab02", + "image6": "Ranarr weed.png", + "label7": "Tarromin", + "low7": "70", + "high7": "-20", + "color7": "#a6761d", + "image7": "Tarromin.png", + "label8": "Harralander", + "low8": "999", + "high8": "999", + "color8": "SteelBlue", + "image8": "Harralander.png", + "lives": "999" + }, + { + "label": "Log chance", + "cascade": "yes", + "showbefore": "no", + "ylabel": "Probability", + "label1": "Magic", + "low1": "-60", + "high1": "60", + "color1": "DarkCyan", + "image1": "Magic logs.png", + "req1": "50", + "label2": "Yew", + "low2": "-50", + "high2": "90", + "color2": "OliveDrab", + "image2": "Yew logs.png", + "req2": "36", + "label3": "Mahogany", + "low3": "-40", + "high3": "130", + "color3": "FireBrick", + "image3": "Mahogany logs.png", + "req3": "24", + "label4": "Maple", + "low4": "0", + "high4": "160", + "color4": "DarkGoldenrod", + "image4": "Maple logs.png", + "label5": "Teak", + "low5": "999", + "high5": "999", + "color5": "DarkKhaki", + "image5": "Teak logs.png", + "lives5": [] + } + ] + }, + { + "title": "Hurdle (Lunar Diplomacy)", + "names": [ + "objects.lunar_dream_hurdles" + ], + "entries": [ + { + "label": "Success chance", + "showbefore": "no", + "label1": "Hurdle", + "low1": "120", + "high1": "200", + "req1": "1", + "color1": "Gray", + "image1": "Hurdle (Lunar Diplomacy).png" + } + ] + }, + { + "title": "Icicles (Penguin Agility Course)", + "names": [ + "objects.peng_iciclepillar_clickzone" + ], + "entries": [ + { + "label": "Icicles success rate", + "lowlevel": "0", + "showbefore": "no", + "label1": "Tread-softly", + "low1": "155", + "high1": "308", + "req1": "30", + "color1": "#9eafc1", + "image1": "Agility icon.png" + } + ] + }, + { + "title": "Idril", + "names": [ + "npcs.prif_citizen_idril" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Imin", + "names": [ + "npcs.prif_citizen_imin" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Iminye", + "names": [ + "npcs.prif_citizen_iminye" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Indis", + "names": [ + "npcs.prif_citizen_indis" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Infernal eel", + "names": [ + "items.infernal_eel" + ], + "entries": [ + { + "label": "Infernal eel catch chance", + "showbefore": "no", + "label1": "Infernal eel", + "low1": "30", + "high1": "93", + "req1": "80", + "color1": "brown", + "image1": "Infernal eel.png" + } + ] + }, + { + "title": "Ingwe", + "names": [ + "npcs.prif_citizen_ingwe" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Ingwion", + "names": [ + "npcs.prif_citizen_ingwion" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Iron rocks", + "names": [ + "objects.ironrock2", + "objects.ironrock1", + "objects.gim_ironrock", + "objects.prif_mine_ironrock1" + ], + "entries": [ + { + "label": "Iron rocks mining chance", + "showbefore": "no", + "label1": "Iron rocks", + "low1": "96", + "high1": "350", + "req1": "15", + "color1": "maroon", + "image1": "Iron ore.png" + } + ] + }, + { + "title": "Jade", + "names": [ + "items.jade" + ], + "entries": [ + { + "label": "Gem cutting rates", + "label1": "Opal", + "low1": "128", + "high1": "250", + "req1": "1", + "color1": "gray", + "image1": "Opal.png", + "label2": "Jade", + "low2": "100", + "high2": "245", + "req2": "13", + "color2": "green", + "image2": "Jade.png", + "label3": "Red topaz", + "low3": "90", + "high3": "240", + "req3": "16", + "color3": "pink", + "image3": "Red topaz.png" + } + ] + }, + { + "title": "Jade bolts (e)", + "names": [ + "items.xbows_crossbow_bolts_blurite_tipped_jade_enchanted" + ], + "entries": [ + { + "label": "Enemy evasion chance", + "xlabel": "Opponent's Agility level", + "ylabel": "Evasion chance", + "showbefore": "no", + "label1": "Earth's Fury", + "low1": "-40", + "high1": "280", + "req1": "1", + "color1": "#00A36C", + "image1": "Jade bolts (e) 5.png" + } + ] + }, + { + "title": "Jade dragon bolts (e)", + "names": [ + "items.dragon_bolts_enchanted_jade" + ], + "entries": [ + { + "label": "Enemy evasion chance", + "xlabel": "Opponent's Agility level", + "ylabel": "Evasion chance", + "showbefore": "no", + "label1": "Earth's Fury", + "low1": "-40", + "high1": "280", + "req1": "1", + "color1": "#00A36C", + "image1": "Jade dragon bolts (e) 5.png" + } + ] + }, + { + "title": "Jug of wine", + "names": [ + "items.jug_wine" + ], + "entries": [ + { + "label": "Jug of wine success chance", + "showbefore": "no", + "label1": "Jug of wine", + "low1": "48", + "high1": "352", + "req1": "35", + "color1": "#a5423c", + "image1": "Jug of wine detail.png" + } + ] + }, + { + "title": "Karambwanji", + "names": [ + "items.tbwt_quest_cooked_karambwanji" + ], + "entries": [ + { + "label": "Karambwanji cooking chance", + "label1": "Fire or Range", + "low1": "200", + "high1": "400", + "req1": "1", + "color1": "gray", + "image1": "Karambwanji.png", + "label2": "Hosidius +5%", + "low2": "212", + "high2": "412", + "req2": "1", + "color2": "red", + "image2": "Karambwanji.png", + "label3": "Hosidius +10%", + "low3": "225", + "high3": "425", + "req3": "79", + "color3": "blue", + "image3": "Karambwanji.png" + } + ] + }, + { + "title": "Kelyn", + "names": [ + "npcs.sote_lady_ithell_normal", + "npcs.mourning_town_elf_5_vis", + "npcs.sote_lady_ithell_vis", + "npcs.sote_lady_ithell_upass", + "npcs.lady_ithell" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Kharidian cactus", + "names": [ + "objects.desert_cactus_full", + "objects.desert_cactus_empty" + ], + "entries": [ + { + "label": "Kharidian cactus cutting chance", + "xlabel": "Woodcutting level", + "label1": "Knife or slashing weapon", + "low1": "30", + "high1": "252", + "req1": "1", + "color1": "#628b11", + "image1": "Knife.png" + } + ] + }, + { + "title": "Knight of Ardougne", + "names": [ + "npcs.knight_of_ardougne", + "npcs.knight_of_ardougne_f", + "npcs.knight_of_ardougne_west_vis", + "npcs.knight_of_ardougne_f_west_vis" + ], + "entries": [ + { + "label": "Knight of Ardougne pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "50", + "high1": "240", + "req1": "55", + "color1": "gray", + "image1": "Thief Knight.png", + "label2": "Gloves of silence", + "low2": "52", + "high2": "252", + "req2": "55", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "55", + "high3": "264", + "req3": "55", + "color3": "black", + "image3": "Ardougne cloak 2.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "60", + "high4": "290", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Kyren fish (6)", + "names": [ + "items.raids_fish6_cooked" + ], + "entries": [ + { + "label": "Cooked Kyren fish (6) cooking chance", + "label1": "Fire", + "low1": "163", + "high1": "255", + "req1": "90", + "color1": "orange", + "image1": "Firemaking icon.png" + } + ] + }, + { + "title": "Larran's big chest", + "names": [ + "objects.slayer_larran_chest_big_closed", + "objects.slayer_larran_chest_big_open" + ], + "entries": [ + { + "label": "Larran's big chest fish chance", + "xlabel": "Fishing level", + "ylabel": "Chance to receive", + "cascade": [], + "label1": "Raw manta ray", + "low1": "-10", + "high1": "20", + "image1": "Raw manta ray.png", + "color1": [], + "label2": "Raw sea turtle", + "low2": "-10", + "high2": "50", + "image2": "Raw sea turtle.png", + "color2": [], + "label3": "Raw shark", + "low3": "-60", + "high3": "140", + "image3": "Raw shark.png", + "color3": [], + "label4": "Raw monkfish", + "low4": "0", + "high4": "170", + "image4": "Raw monkfish.png", + "color4": [], + "label5": "Raw swordfish", + "low5": "30", + "high5": "200", + "image5": "Raw swordfish.png", + "color5": [], + "label6": "Raw lobster", + "low6": "70", + "high6": "270", + "image6": "Raw lobster.png", + "color6": [], + "label7": "Raw tuna", + "low7": "225", + "high7": "324", + "image7": "Raw tuna.png", + "color7": [] + } + ] + }, + { + "title": "Larran's small chest", + "names": [ + "objects.slayer_larran_chest_small_closed", + "objects.slayer_larran_chest_small_open" + ], + "entries": [ + { + "label": "Larran's small chest fish chance", + "xlabel": "Fishing level", + "ylabel": "Chance to receive", + "cascade": [], + "label1": "Raw manta ray", + "low1": "-10", + "high1": "20", + "image1": "Raw manta ray.png", + "color1": [], + "label2": "Raw sea turtle", + "low2": "-10", + "high2": "50", + "image2": "Raw sea turtle.png", + "color2": [], + "label3": "Raw shark", + "low3": "-60", + "high3": "140", + "image3": "Raw shark.png", + "color3": [], + "label4": "Raw monkfish", + "low4": "0", + "high4": "170", + "image4": "Raw monkfish.png", + "color4": [], + "label5": "Raw swordfish", + "low5": "30", + "high5": "200", + "image5": "Raw swordfish.png", + "color5": [], + "label6": "Raw lobster", + "low6": "70", + "high6": "270", + "image6": "Raw lobster.png", + "color6": [], + "label7": "Raw tuna", + "low7": "225", + "high7": "324", + "image7": "Raw tuna.png", + "color7": [] + } + ] + }, + { + "title": "Lean snail meat", + "names": [ + "items.snail_corpse_cooked2" + ], + "entries": [ + { + "label": "Lean snail meat cooking chance", + "label1": "Fire", + "low1": "93", + "high1": "444", + "req1": "17", + "color1": "orange", + "image1": "Firemaking icon.png", + "label2": "Range", + "low2": "85", + "high2": "428", + "req2": "17", + "color2": "saddlebrown", + "image2": "Cooking range icon.png", + "label3": "Lumbridge range", + "low3": "95", + "high3": "448", + "req3": "17", + "color3": "green", + "image3": "Lumbridge Teleport.png", + "label4": "Hosidius +5%", + "low4": "97", + "high4": "440", + "req4": "17", + "color4": "red", + "image4": "Cooking range icon.png", + "label5": "Hosidius +10%", + "low5": "110", + "high5": "453", + "req5": "79", + "color5": "blue", + "image5": "Cooking range icon.png" + } + ] + }, + { + "title": "Leaping salmon", + "names": [ + "items.brut_spawning_salmon" + ], + "entries": [ + { + "label": "Barbarian rod fishing chance", + "cascade": "yes", + "showbefore": "no", + "label1": "Leaping sturgeon", + "low1": "8", + "high1": "64", + "req1": "70", + "color1": "green", + "image1": "Leaping sturgeon.png", + "label2": "Leaping salmon", + "low2": "16", + "high2": "96", + "req2": "58", + "color2": "brown", + "image2": "Leaping salmon.png", + "label3": "Leaping trout", + "low3": "32", + "high3": "192", + "req3": "48", + "color3": "gray", + "image3": "Leaping trout.png" + } + ] + }, + { + "title": "Leaping sturgeon", + "names": [ + "items.brut_sturgeon" + ], + "entries": [ + { + "label": "Barbarian rod fishing chance", + "cascade": "yes", + "showbefore": "no", + "label1": "Leaping sturgeon", + "low1": "8", + "high1": "64", + "req1": "70", + "color1": "green", + "image1": "Leaping sturgeon.png", + "label2": "Leaping salmon", + "low2": "16", + "high2": "96", + "req2": "58", + "color2": "brown", + "image2": "Leaping salmon.png", + "label3": "Leaping trout", + "low3": "32", + "high3": "192", + "req3": "48", + "color3": "gray", + "image3": "Leaping trout.png" + } + ] + }, + { + "title": "Leaping trout", + "names": [ + "items.brut_spawning_trout" + ], + "entries": [ + { + "label": "Barbarian rod fishing chance", + "cascade": "yes", + "showbefore": "no", + "label1": "Leaping sturgeon", + "low1": "8", + "high1": "64", + "req1": "70", + "color1": "green", + "image1": "Leaping sturgeon.png", + "label2": "Leaping salmon", + "low2": "16", + "high2": "96", + "req2": "58", + "color2": "brown", + "image2": "Leaping salmon.png", + "label3": "Leaping trout", + "low3": "32", + "high3": "192", + "req3": "48", + "color3": "gray", + "image3": "Leaping trout.png" + } + ] + }, + { + "title": "Lenwe", + "names": [ + "npcs.prif_citizen_lenwe" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Light Jungle", + "names": [ + "objects.tai_bwo_jungle_vegetation_easy_1", + "objects.tai_bwo_jungle_vegetation_easy_2", + "objects.tai_bwo_jungle_vegetation_easy_3", + "objects.tai_bwo_jungle_vegetation_easy_4", + "objects.tai_bwo_jungle_vegetation_easy_5" + ], + "entries": [ + { + "label": "Light Jungle Cut Chance", + "showbefore": "no", + "label1": "Plain Machete", + "low1": "49", + "high1": "169", + "req1": "10", + "color1": "dimgray", + "image1": "Machete.png", + "label2": "Opal Machete", + "low2": "54", + "high2": "174", + "req2": "10", + "color2": "lightgray", + "image2": "Opal machete.png", + "label3": "Jade Machete", + "low3": "70", + "high3": "190", + "req3": "10", + "color3": "lightgreen", + "image3": "Jade machete.png", + "label4": "Red Topaz Machete", + "low4": "85", + "high4": "205", + "req4": "10", + "color4": "firebrick", + "image4": "Red topaz machete.png" + } + ] + }, + { + "title": "Limestone rock", + "names": [ + "objects.limestone_rock1", + "objects.limestone_rock2", + "objects.limestone_rock3", + "objects.limestone_rock_noore" + ], + "entries": [ + { + "label": "Pile of rock mining chance", + "showbefore": "no", + "label1": "Limestone", + "low1": "95", + "high1": "350", + "req1": "10", + "color1": "grey", + "image1": "Limestone.png" + } + ] + }, + { + "title": "Lindir", + "names": [ + "npcs.prif_citizen_lindir" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Lobster", + "names": [ + "items.lobster" + ], + "entries": [ + { + "label": "Lobster cooking chance", + "showbefore": "no", + "label1": "Fire or Range", + "low1": "38", + "high1": "332", + "req1": "40", + "color1": "saddlebrown", + "image1": "Lobster.png", + "label2": "Gauntlets", + "low2": "55", + "high2": "368", + "req2": "40", + "color2": "grey", + "image2": "Cooking gauntlets.png", + "label3": "Hosidius +5%", + "low3": "50", + "high3": "344", + "req3": "40", + "color3": "red", + "image3": "Lobster.png", + "label4": "Hosidius +10%", + "low4": "63", + "high4": "357", + "req4": "79", + "color4": "blue", + "image4": "Lobster.png", + "label5": "Hosidius +5%, gauntlets", + "low5": "67", + "high5": "380", + "req5": "40", + "color5": "#ffcccb", + "image5": "Cooking gauntlets.png", + "label6": "Hosidius +10%, gauntlets", + "low6": "80", + "high6": "393", + "req6": "79", + "color6": "#ccccff", + "image6": "Cooking gauntlets.png" + } + ] + }, + { + "title": "Log balance (East Ardougne)", + "names": [ + "objects.ardougne_log_balance_left_sc", + "objects.ardougne_log_balance_mid_sc", + "objects.ardougne_log_balance_right_sc" + ], + "entries": [ + { + "label": "Log balance success rate", + "showbefore": "no", + "label1": "Log balance", + "low1": "90", + "high1": "250", + "req1": "33", + "color1": "#897b31", + "image1": "Agility icon.png" + } + ] + }, + { + "title": "Log balance (Wilderness Agility Course)", + "names": [ + "objects.wilderness_log_balance1" + ], + "entries": [ + { + "label": "Log balance", + "label1": "Walk-across success rate", + "xlabel": "Agility level", + "low1": "200", + "high1": "250", + "req1": "1", + "color1": "#151111", + "image1": "Agility icon.png" + } + ] + }, + { + "title": "Lucky impling", + "names": [ + "npcs.ii_impling_type_11", + "npcs.ii_impling_type_11_maze" + ], + "entries": [ + { + "label": "Lucky impling catch chance", + "showbefore": "no", + "label1": "Butterfly net", + "low1": "3", + "high1": "100", + "req1": "89", + "color1": "saddlebrown", + "image1": "Butterfly net.png", + "label2": "Barehanded or magic butterfly net", + "low2": "23", + "high2": "120", + "req2": "89", + "color2": "green", + "image2": "Magic butterfly net.png" + } + ] + }, + { + "title": "Mackerel", + "names": [ + "items.mackerel" + ], + "entries": [ + { + "label": "Mackerel cooking chance", + "label1": "Fire or Range", + "low1": "98", + "high1": "452", + "req1": "10", + "color1": "gray", + "image1": "Mackerel.png", + "label2": "Lumbridge range", + "low2": "108", + "high2": "472", + "req2": "10", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "110", + "high3": "464", + "req3": "10", + "color3": "red", + "image3": "Mackerel.png", + "label4": "Hosidius +10%", + "low4": "123", + "high4": "477", + "req4": "79", + "color4": "blue", + "image4": "Mackerel.png" + } + ] + }, + { + "title": "Maeglin", + "names": [ + "npcs.prif_citizen_maeglin" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Magic Stall", + "names": [ + "objects.mm_stall_magic" + ], + "entries": [ + { + "label": "Magic Stall thieving chance", + "showbefore": "no", + "label1": "Magic Stall", + "low1": "20", + "high1": "180", + "req1": "65", + "color1": "brown", + "image1": "Fire rune.png" + } + ] + }, + { + "title": "Magic birdhouse", + "names": [ + "objects.birdhouse_magic_built", + "objects.birdhouse_magic_full", + "objects.birdhouse_magic_bird" + ], + "entries": [ + { + "label": "Seed nest chance", + "xlabel": "Hunter level", + "label1": "Seed nest", + "low1": "0", + "high1": "200", + "req1": "74", + "color1": "grey", + "image1": "Bird nest (seeds).png" + }, + { + "label": "Other nests (10 rolls per birdhouse)", + "xlabel": "Hunter level", + "birdhouse": "yes", + "label1": "Magic", + "high1": "170", + "req1": "74", + "color1": "#708090", + "image1": "Magic bird house.png" + } + ] + }, + { + "title": "Magic tree", + "names": [ + "objects.magictree" + ], + "entries": [ + { + "label": "Magic tree cut chance", + "showbefore": "no", + "label1": "Bronze", + "low1": "2", + "high1": "6", + "req1": "75", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "3", + "high2": "9", + "req2": "75", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "4", + "high3": "12", + "req3": "75", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "5", + "high4": "13", + "req4": "75", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "5", + "high5": "15", + "req5": "75", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "6", + "high6": "18", + "req6": "75", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "7", + "high7": "21", + "req7": "75", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "7", + "high8": "22", + "req8": "75", + "color8": "firebrick", + "image8": "Dragon axe.png" + } + ] + }, + { + "title": "Magical wheat", + "names": [ + "objects.ii_maze_wheat_no_block1", + "objects.ii_maze_wheat_no_block2", + "objects.ii_maze_wheat_no_block3", + "objects.ii_maze_wheat_block1", + "objects.ii_maze_wheat_block2", + "objects.ii_maze_wheat_block_moveable1", + "objects.ii_maze_wheat_block_type8", + "objects.ii_maze_wheat_block2_type8", + "objects.ii_maze_wheat_block3_type8", + "objects.ii_maze_wheat_surround_block", + "objects.ii_maze_wheat_surround_gate", + "objects.ii_maze_wheat_invis" + ], + "entries": [ + { + "label": "Wheat Push Speed", + "cascade": "yes", + "showbefore": "no", + "label1": "Efficient", + "low1": "0", + "high1": "100", + "req1": "1", + "color1": "goldenrod", + "image1": "Strength icon.png", + "label2": "Normal", + "low2": "10", + "high2": "256", + "req2": "1", + "color2": "gray", + "image2": "Strength icon.png", + "label3": "Hard work", + "low3": "256", + "high3": "256", + "req3": "1", + "color3": "firebrick", + "image3": "Strength icon.png" + } + ] + }, + { + "title": "Magpie impling", + "names": [ + "npcs.ii_impling_type_8", + "npcs.ii_impling_type_8_maze" + ], + "entries": [ + { + "label": "Magpie impling catch chance", + "showbefore": "no", + "label1": "Butterfly net", + "low1": "15", + "high1": "177", + "req1": "65", + "color1": "saddlebrown", + "image1": "Butterfly net.png", + "label2": "Barehanded or magic butterfly net", + "low2": "35", + "high2": "197", + "req2": "65", + "color2": "green", + "image2": "Magic butterfly net.png" + } + ] + }, + { + "title": "Mahogany birdhouse", + "names": [ + "objects.birdhouse_mahogany_built", + "objects.birdhouse_mahogany_full", + "objects.birdhouse_mahogany_bird" + ], + "entries": [ + { + "label": "Seed nest chance", + "xlabel": "Hunter level", + "label1": "Seed nest", + "low1": "0", + "high1": "200", + "req1": "49", + "color1": "grey", + "image1": "Bird nest (seeds).png" + }, + { + "label": "Other nests (10 rolls per birdhouse)", + "xlabel": "Hunter level", + "birdhouse": "yes", + "label1": "Mahogany", + "high1": "150", + "req1": "49", + "color1": "#ffff00", + "image1": "Mahogany bird house.png" + } + ] + }, + { + "title": "Mahogany tree", + "names": [ + "objects.mahoganytree", + "objects.prif_mahoganytree", + "objects.mahoganytree_update" + ], + "entries": [ + { + "label": "Mahogany tree cut chance", + "showbefore": "no", + "label1": "Bronze", + "low1": "8", + "high1": "25", + "req1": "50", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "12", + "high2": "38", + "req2": "50", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "16", + "high3": "50", + "req3": "50", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "18", + "high4": "54", + "req4": "50", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "20", + "high5": "63", + "req5": "50", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "25", + "high6": "75", + "req6": "50", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "29", + "high7": "88", + "req7": "50", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "34", + "high8": "94", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png", + "label9": "Crystal", + "low9": "36", + "high9": "97", + "req9": "71", + "color9": "cyan", + "image9": "Crystal axe.png" + } + ] + }, + { + "title": "Mahtan", + "names": [ + "npcs.prif_citizen_mahtan" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Man", + "names": [ + "npcs.man", + "npcs.man_indoor", + "npcs.zeah_man", + "npcs.sote_citizen_male_2", + "npcs.man2", + "npcs.zeah_man2", + "npcs.man3", + "npcs.zeah_man3", + "npcs.man4", + "npcs.death_man_indoors1", + "npcs.man4_for_musa_point", + "npcs.al_kharid_man", + "npcs.falador_man2", + "npcs.falador_man3", + "npcs.karamja_man", + "npcs.varrock_man1", + "npcs.shayzien_man_2", + "npcs.shayzien_man_1" + ], + "entries": [ + { + "label": "Man pickpocket chance", + "label1": "Normal", + "low1": "180", + "high1": "240", + "req1": "1", + "color1": "gray", + "image1": "Thief Man.png", + "label2": "Gloves of silence", + "low2": "189", + "high2": "252", + "req2": "1", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "198", + "high3": "264", + "req3": "1", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "217", + "high4": "290", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Man (East Ardougne)", + "names": [ + "npcs.ardougnian_male1" + ], + "entries": [ + { + "label": "Man pickpocket chance", + "label1": "Normal", + "low1": "180", + "high1": "240", + "req1": "1", + "color1": "gray", + "image1": "Thief Man.png", + "label2": "Gloves of silence", + "low2": "189", + "high2": "252", + "req2": "1", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "198", + "high3": "264", + "req3": "1", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "217", + "high4": "290", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Man trap", + "names": [], + "entries": [ + { + "label": "Man trap evasion chance", + "xlabel": "Agility level", + "ylabel": "Evasion chance", + "showbefore": "no", + "label1": "Man trap", + "low1": "30", + "high1": "210", + "req1": "1", + "color1": "#170000", + "image1": "Man trap icon.png" + } + ] + }, + { + "title": "Maniacal monkey (Hunter)", + "names": [ + "npcs.hunting_monkey", + "npcs.hunting_monkey_invisible", + "npcs.hunting_monkey_sans_tail_1", + "npcs.hunting_monkey_sans_tail_2", + "npcs.hunting_monkey_sans_tail_3" + ], + "entries": [ + { + "label": "Maniacal monkey catch chance", + "showbefore": "no", + "label1": "Maniacal monkey", + "low1": "-79", + "high1": "227", + "req1": "60", + "color1": "darkolivegreen", + "image1": "Damaged monkey tail.png" + } + ] + }, + { + "title": "Manta ray", + "names": [ + "items.mantaray" + ], + "entries": [ + { + "label": "Manta ray cooking chance", + "showbefore": "no", + "label1": "Fire", + "low1": "1", + "high1": "202", + "req1": "91", + "color1": "orange", + "image1": "Firemaking icon.png", + "label2": "Range", + "low2": "1", + "high2": "222", + "req2": "91", + "color2": "saddlebrown", + "image2": "Cooking range icon.png", + "label3": "Hosidius +5%", + "low3": "13", + "high3": "234", + "req3": "91", + "color3": "red", + "image3": "Cooking range icon.png", + "label4": "Hosidius +10%", + "low4": "26", + "high4": "247", + "req4": "91", + "color4": "blue", + "image4": "Cooking range icon.png" + } + ] + }, + { + "title": "Maple birdhouse", + "names": [ + "objects.birdhouse_maple_built", + "objects.birdhouse_maple_full", + "objects.birdhouse_maple_bird" + ], + "entries": [ + { + "label": "Seed nest chance", + "xlabel": "Hunter level", + "label1": "Seed nest", + "low1": "0", + "high1": "200", + "req1": "44", + "color1": "grey", + "image1": "Bird nest (seeds).png" + }, + { + "label": "Other nests (10 rolls per birdhouse)", + "xlabel": "Hunter level", + "birdhouse": "yes", + "label1": "Maple", + "high1": "140", + "req1": "44", + "color1": "#00ff00", + "image1": "Maple bird house.png" + } + ] + }, + { + "title": "Maple tree", + "names": [ + "objects.mapletree", + "objects.prif_mapletree", + "objects.mapletree_update" + ], + "entries": [ + { + "label": "Maple tree cut chance", + "showbefore": "no", + "label1": "Bronze", + "low1": "8", + "high1": "25", + "req1": "45", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "12", + "high2": "37", + "req2": "45", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "16", + "high3": "50", + "req3": "45", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "18", + "high4": "56", + "req4": "45", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "20", + "high5": "62", + "req5": "45", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "24", + "high6": "75", + "req6": "45", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "28", + "high7": "87", + "req7": "45", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "30", + "high8": "93", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png" + } + ] + }, + { + "title": "Marble trap", + "names": [], + "entries": [ + { + "label": "Marble trap evasion chance", + "xlabel": "Agility level", + "ylabel": "Evasion chance", + "showbefore": "no", + "label1": "Marble trap", + "low1": "30", + "high1": "210", + "req1": "1", + "color1": "#a6a190", + "image1": "Marble trap icon.png" + } + ] + }, + { + "title": "Marshy jungle vine", + "names": [ + "objects.snake_vine_full", + "objects.snake_vine_empty" + ], + "entries": [ + { + "label": "Snake weed harvest chance", + "label1": "Grimy snake weed", + "low1": "9", + "high1": "219", + "req1": "1", + "color1": "grey", + "image1": "Grimy snake weed.png" + } + ] + }, + { + "title": "Martin the Master Gardener", + "names": [ + "npcs.martin_the_master_farmer" + ], + "entries": [ + { + "label": "Master Farmer pickpocket chance", + "label1": "Normal", + "low1": "90", + "high1": "240", + "req1": "38", + "color1": "gray", + "image1": "Thief Master farmer.png", + "label2": "Gloves of silence", + "low2": "94", + "high2": "252", + "req2": "38", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "99", + "high3": "264", + "req3": "67", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "108", + "high4": "290", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Master Farmer", + "names": [ + "npcs.master_farmer_1", + "npcs.master_farmer_2", + "npcs.master_farmer_1_f", + "npcs.master_farmer_2_f", + "npcs.varlamore_master_farmer_f_1", + "npcs.varlamore_master_farmer_f_2", + "npcs.varlamore_master_farmer_f_3", + "npcs.varlamore_master_farmer_f_4", + "npcs.varlamore_master_farmer_m_1", + "npcs.varlamore_master_farmer_m_2", + "npcs.varlamore_master_farmer_m_3", + "npcs.varlamore_master_farmer_m_4" + ], + "entries": [ + { + "label": "Master Farmer pickpocket chance", + "label1": "Normal", + "low1": "90", + "high1": "240", + "req1": "38", + "color1": "gray", + "image1": "Thief Master farmer.png", + "label2": "Gloves of silence", + "low2": "94", + "high2": "252", + "req2": "38", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "99", + "high3": "264", + "req3": "67", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "108", + "high4": "290", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Mawrth", + "names": [ + "npcs.mourning_town_elf_4", + "npcs.sote_mawrth", + "npcs.sote_mawrth_cutscene" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Meat pie", + "names": [ + "items.meat_pie", + "items.half_a_meat_pie" + ], + "entries": [ + { + "label": "Meat pie cooking chance", + "label1": "Range", + "low1": "78", + "high1": "412", + "req1": "20", + "color1": "gray", + "image1": "Meat pie.png", + "label2": "Lumbridge range", + "low2": "88", + "high2": "432", + "req2": "20", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "90", + "high3": "424", + "req3": "20", + "color3": "red", + "image3": "Meat pie.png", + "label4": "Hosidius +10%", + "low4": "103", + "high4": "437", + "req4": "79", + "color4": "blue", + "image4": "Meat pie.png" + } + ] + }, + { + "title": "Meat tree", + "names": [ + "npcs.raids_dogodile_meat_tree", + "objects.raids_meat_tree_full", + "objects.raids_meat_tree_empty" + ], + "entries": [ + { + "label": "Meat tree cut chance", + "label1": "Meat tree", + "low1": "50", + "high1": "200", + "req1": "1", + "color1": "red", + "image1": "Meat tree.png" + } + ] + }, + { + "title": "Medium Jungle", + "names": [ + "objects.tai_bwo_jungle_vegetation_med_1", + "objects.tai_bwo_jungle_vegetation_med_2", + "objects.tai_bwo_jungle_vegetation_med_3", + "objects.tai_bwo_jungle_vegetation_med_4", + "objects.tai_bwo_jungle_vegetation_med_5" + ], + "entries": [ + { + "label": "Medium Jungle Cut Chance", + "showbefore": "no", + "label1": "Plain Machete", + "low1": "34", + "high1": "85", + "req1": "20", + "color1": "dimgray", + "image1": "Machete.png", + "label2": "Opal Machete", + "low2": "39", + "high2": "90", + "req2": "20", + "color2": "lightgray", + "image2": "Opal machete.png", + "label3": "Jade Machete", + "low3": "54", + "high3": "105", + "req3": "20", + "color3": "lightgreen", + "image3": "Jade machete.png", + "label4": "Red Topaz Machete", + "low4": "70", + "high4": "121", + "req4": "20", + "color4": "firebrick", + "image4": "Red topaz machete.png" + } + ] + }, + { + "title": "Menaphite Thug", + "names": [ + "npcs.feud_egyptian_doorman_2", + "npcs.feud_egyptian_doorman_1" + ], + "entries": [ + { + "label": "Menaphite Thug knockout chance", + "showbefore": "no", + "label1": "Menaphite Thug", + "low1": "78", + "high1": "240", + "req1": "65", + "color1": "purple", + "image1": "Menaphite Thug chathead.png" + }, + { + "label": "Menaphite Thug pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "50", + "high1": "160", + "req1": "65", + "color1": "gray", + "image1": "Thief Menaphite thug.png", + "label2": "Gloves of silence", + "low2": "52", + "high2": "168", + "req2": "65", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "55", + "high3": "176", + "req3": "65", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "60", + "high4": "193", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Mind rune (The Slug Menace)", + "names": [ + "items.slug2_rune_mind" + ], + "entries": [ + { + "label": "Channeling blank rune success chance", + "xlabel": "Runecraft level", + "showbefore": "no", + "label1": "Mind rune", + "low1": "110", + "high1": "253", + "req1": "30", + "color1": "#b76f15", + "image1": "Mind rune (The Slug Menace).png" + } + ] + }, + { + "title": "Miriel", + "names": [ + "npcs.prif_citizen_miriel" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Mithrellas", + "names": [ + "npcs.prif_citizen_mithrellas" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Mithril rocks", + "names": [ + "objects.mithrilrock2", + "objects.mithrilrock1", + "objects.prif_mine_mithrilrock1" + ], + "entries": [ + { + "label": "Mithril rocks mining chance", + "showbefore": "no", + "label1": "Mithril rocks", + "low1": "4", + "high1": "50", + "req1": "55", + "color1": "slateblue", + "image1": "Mithril ore.png" + } + ] + }, + { + "title": "Money making guide/Cooking raw moonlight antelope", + "names": [], + "entries": [ + { + "label": "Cooked moonlight antelope cooking chance", + "showbefore": "no", + "label1": "Fire", + "low1": "1", + "high1": "185", + "req1": "92", + "color1": "orange", + "image1": "Firemaking icon.png", + "label2": "Range", + "low2": "1", + "high2": "200", + "req2": "92", + "color2": "saddlebrown", + "image2": "Cooking range icon.png", + "label3": "Hosidius +5%", + "low3": "13", + "high3": "212", + "req3": "92", + "color3": "red", + "image3": "Cooking range icon.png", + "label4": "Hosidius +10%", + "low4": "26", + "high4": "225", + "req4": "92", + "color4": "blue", + "image4": "Cooking range icon.png" + } + ] + }, + { + "title": "Money making guide/Cooking raw sunlight antelope", + "names": [], + "entries": [ + { + "label": "Cooked sunlight antelope cooking chance", + "showbefore": "no", + "label1": "Fire", + "low1": "8", + "high1": "254", + "req1": "62", + "color1": "orange", + "image1": "Firemaking icon.png", + "label2": "Range", + "low2": "8", + "high2": "265", + "req2": "62", + "color2": "saddlebrown", + "image2": "Cooking range icon.png", + "label3": "Hosidius +5%", + "low3": "20", + "high3": "277", + "req3": "62", + "color3": "red", + "image3": "Cooking range icon.png", + "label4": "Hosidius +10%", + "low4": "33", + "high4": "290", + "req4": "79", + "color4": "blue", + "image4": "Cooking range icon.png" + } + ] + }, + { + "title": "Monkeybars (Yanille Agility Dungeon)", + "names": [ + "objects.monkeybars_mid", + "objects.monkeybars_end2" + ], + "entries": [ + { + "label": "Monkeybars", + "label1": "Swinging across success rate", + "xlabel": "Agility level", + "low1": "36", + "high1": "330", + "req1": "57", + "showbefore": "no", + "color1": "#453321", + "image1": "Agility icon.png" + } + ] + }, + { + "title": "Monkfish", + "names": [ + "items.monkfish" + ], + "entries": [ + { + "label": "Monkfish cooking chance", + "showbefore": "no", + "label1": "Fire", + "low1": "11", + "high1": "275", + "req1": "62", + "color1": "orange", + "image1": "Firemaking icon.png", + "label2": "Range", + "low2": "13", + "high2": "280", + "req2": "62", + "color2": "saddlebrown", + "image2": "Cooking range icon.png", + "label3": "Gauntlets", + "low3": "24", + "high3": "290", + "req3": "62", + "color3": "grey", + "image3": "Cooking gauntlets.png", + "label4": "Hosidius +5%", + "low4": "25", + "high4": "292", + "req4": "62", + "color4": "red", + "image4": "Cooking range icon.png", + "label5": "Hosidius +10%", + "low5": "38", + "high5": "305", + "req5": "79", + "color5": "blue", + "image5": "Cooking range icon.png", + "label6": "Hosidius +5%, gauntlets", + "low6": "36", + "high6": "302", + "req6": "62", + "color6": "#ffcccb", + "image6": "Cooking gauntlets.png", + "label7": "Hosidius +10%, gauntlets", + "low7": "49", + "high7": "315", + "req7": "79", + "color7": "#ccccff", + "image7": "Cooking gauntlets.png" + } + ] + }, + { + "title": "Moonlight moth", + "names": [ + "npcs.moth_moonlight", + "npcs.moth_moonlight_low_wander", + "npcs.moth_moonlight_noclick" + ], + "entries": [ + { + "label": "Moonlight moth chance", + "showbefore": "no", + "label1": "Butterfly net", + "low1": "0", + "high1": "276", + "req1": "75", + "color1": "saddlebrown", + "image1": "Butterfly net.png", + "label2": "Barehanded or magic butterfly net", + "low2": "20", + "high2": "286", + "req2": "75", + "color2": "green", + "image2": "Magic butterfly net.png" + } + ] + }, + { + "title": "Motherlode Mine", + "names": [], + "entries": [ + { + "label": "Pay-dirt mining chance", + "showbefore": "no", + "xlabel": "Mining Level", + "label1": "Pay-dirt", + "low1": "60", + "high1": "105", + "req1": "30", + "color1": "brown", + "image1": "Pay-dirt.png" + }, + { + "label": "Motherlode Mine ore chance", + "xlabel": "Mining level", + "cascade": "yes", + "showbefore": "no", + "label1": "Golden nugget", + "low1": "7", + "high1": "7", + "req1": "30", + "color1": "gold", + "image1": "Golden nugget.png", + "label2": "Runite ore", + "low2": "-20", + "high2": "5", + "req2": "85", + "color2": "steelblue", + "image2": "Runite ore.png", + "label3": "Adamantite ore", + "low3": "-90", + "high3": "50", + "req3": "70", + "color3": "seagreen", + "image3": "Adamantite ore.png", + "label4": "Mithril ore", + "low4": "-19", + "high4": "90", + "req4": "55", + "color4": "slateblue", + "image4": "Mithril ore.png", + "label5": "Gold ore", + "low5": "-40", + "high5": "126", + "req5": "40", + "color5": "goldenrod", + "image5": "Gold ore.png", + "label6": "Coal", + "low6": "226", + "high6": "325", + "req6": "30", + "color6": "black", + "image6": "Coal.png" + } + ] + }, + { + "title": "Mud pie", + "names": [ + "items.mud_pie" + ], + "entries": [ + { + "label": "Mud pie cooking chance", + "label1": "Range", + "low1": "58", + "high1": "372", + "req1": "29", + "color1": "saddlebrown", + "image1": "Mud pie.png", + "label2": "Hosidius +5%", + "low2": "70", + "high2": "384", + "req2": "29", + "color2": "red", + "image2": "Mud pie.png", + "label3": "Hosidius +10%", + "low3": "83", + "high3": "397", + "req3": "79", + "color3": "blue", + "image3": "Mud pie.png" + } + ] + }, + { + "title": "Mushroom pie", + "names": [ + "items.mushroom_pie", + "items.half_mushroom_pie" + ], + "entries": [ + { + "label": "Mushroom pie cooking chance", + "showbefore": "yes", + "label1": "Range", + "low1": "17", + "high1": "285", + "req1": "60", + "color1": "gray", + "image1": "Mushroom pie.png", + "label2": "Lumbridge range", + "low2": "140", + "high2": "450", + "req2": "60", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "29", + "high3": "297", + "req3": "60", + "color3": "red", + "image3": "Mushroom pie.png", + "label4": "Hosidius +10%", + "low4": "42", + "high4": "310", + "req4": "79", + "color4": "blue", + "image4": "Mushroom pie.png" + } + ] + }, + { + "title": "Nature impling", + "names": [ + "npcs.ii_impling_type_7", + "npcs.ii_impling_type_7_maze" + ], + "entries": [ + { + "label": "Nature impling catch chance", + "showbefore": "no", + "label1": "Butterfly net", + "low1": "20", + "high1": "200", + "req1": "58", + "color1": "saddlebrown", + "image1": "Butterfly net.png", + "label2": "Barehanded or magic butterfly net", + "low2": "40", + "high2": "220", + "req2": "58", + "color2": "green", + "image2": "Magic butterfly net.png" + } + ] + }, + { + "title": "Nellas", + "names": [ + "npcs.prif_citizen_nellas" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Nerdanel", + "names": [ + "npcs.prif_citizen_nerdanel" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Net trap", + "names": [ + "objects.hunting_sapling_net_set_orange", + "objects.hunting_sapling_net_set_black", + "objects.hunting_sapling_net_set_swamp", + "objects.hunting_sapling_net_set_mountain", + "objects.hunting_sapling_catching_green", + "objects.hunting_sapling_full_green", + "objects.hunting_sapling_full_orange", + "objects.hunting_sapling_catching_orange", + "objects.hunting_sapling_catching_red", + "objects.hunting_sapling_full_red", + "objects.hunting_sapling_catching_black", + "objects.hunting_sapling_full_black", + "objects.hunting_sapling_catching_mountain", + "objects.hunting_sapling_full_mountain", + "objects.hunting_sapling_failing_swamp", + "objects.hunting_sapling_failed_swamp", + "objects.hunting_sapling_failed_orange", + "objects.hunting_sapling_failing_orange", + "objects.hunting_sapling_failing_red", + "objects.hunting_sapling_failed_red", + "objects.hunting_sapling_failing_black", + "objects.hunting_sapling_failed_black", + "objects.hunting_sapling_failing_mountain", + "objects.hunting_sapling_failed_mountain" + ], + "entries": [ + { + "label": "Salamander catch chance", + "showbefore": "no", + "label1": "Swamp lizard", + "low1": "52", + "high1": "360", + "req1": "29", + "color1": "#1b441a", + "image1": "Swamp lizard.png", + "label2": "Orange salamander", + "low2": "16", + "high2": "288", + "req2": "47", + "color2": "#976b1e", + "image2": "Orange salamander.png", + "label3": "Red salamander", + "low3": "0", + "high3": "240", + "req3": "59", + "color3": "#6c2413", + "image3": "Red salamander.png", + "label4": "Black salamander", + "low4": "0", + "high4": "212", + "req4": "67", + "color4": "#151111", + "image4": "Black salamander.png", + "label5": "Tecu salamander", + "low5": "1", + "high5": "212", + "req5": "79", + "color5": "#5a9e95", + "image5": "Tecu salamander.png" + } + ] + }, + { + "title": "Nettle tea", + "names": [ + "items.bowl_nettletea" + ], + "entries": [ + { + "label": "Nettle tea cooking chance", + "xlabel": "Cooking level", + "label1": "Fire or Range", + "low1": "78", + "high1": "412", + "req1": "20", + "color1": "gray", + "image1": "Nettle tea.png", + "label2": "Hosidius +5%", + "low2": "90", + "high2": "424", + "req2": "20", + "color2": "red", + "image2": "Nettle tea.png", + "label3": "Hosidius +10%", + "low3": "103", + "high3": "437", + "req3": "79", + "color3": "blue", + "image3": "Nettle tea.png" + } + ] + }, + { + "title": "Nimloth", + "names": [ + "npcs.prif_citizen_nimloth" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Ninja impling", + "names": [ + "npcs.ii_impling_type_9", + "npcs.ii_impling_type_9_maze" + ], + "entries": [ + { + "label": "Ninja impling catch chance", + "showbefore": "no", + "label1": "Butterfly net", + "low1": "10", + "high1": "151", + "req1": "74", + "color1": "saddlebrown", + "image1": "Butterfly net.png", + "label2": "Barehanded or magic butterfly net", + "low2": "30", + "high2": "171", + "req2": "74", + "color2": "green", + "image2": "Magic butterfly net.png" + } + ] + }, + { + "title": "Oak birdhouse", + "names": [ + "objects.birdhouse_oak_built", + "objects.birdhouse_oak_full", + "objects.birdhouse_oak_bird" + ], + "entries": [ + { + "label": "Seed nest chance", + "xlabel": "Hunter level", + "label1": "Seed nest", + "low1": "0", + "high1": "200", + "req1": "14", + "color1": "grey", + "image1": "Bird nest (seeds).png" + }, + { + "label": "Other nests (10 rolls per birdhouse)", + "xlabel": "Hunter level", + "birdhouse": "yes", + "label1": "Oak", + "high1": "125", + "req1": "14", + "color1": "#ff0000", + "image1": "Oak bird house.png" + } + ] + }, + { + "title": "Oak tree", + "names": [ + "objects.oaktree", + "objects.tree_oak_default01" + ], + "entries": [ + { + "label": "Oak tree cut chance", + "xlabel": "Woodcutting level", + "label1": "Bronze", + "low1": "32", + "high1": "100", + "req1": "15", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "48", + "high2": "150", + "req2": "15", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "64", + "high3": "200", + "req3": "15", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "72", + "high4": "225", + "req4": "15", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "80", + "high5": "250", + "req5": "21", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "96", + "high6": "300", + "req6": "31", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "112", + "high7": "350", + "req7": "41", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "120", + "high8": "375", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png" + } + ] + }, + { + "title": "Oak tree (The Node)", + "names": [ + "objects.gim_oaktree" + ], + "entries": [ + { + "label": "Oak tree cut chance", + "xlabel": "Woodcutting level", + "label1": "Bronze", + "low1": "32", + "high1": "100", + "req1": "15", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "48", + "high2": "150", + "req2": "15", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "64", + "high3": "200", + "req3": "15", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "72", + "high4": "225", + "req4": "15", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "80", + "high5": "250", + "req5": "21", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "96", + "high6": "300", + "req6": "31", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "112", + "high7": "350", + "req7": "41", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "120", + "high8": "375", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png" + } + ] + }, + { + "title": "Ogre Coffin (Zogre Flesh Eaters)", + "names": [ + "objects.zogre_coffin_special_entity", + "objects.zogre_coffin_special", + "objects.zogre_coffin_special_searched" + ], + "entries": [ + { + "label": "Ogre coffin opening chance", + "xlabel": "Strength level", + "label1": "Brute force", + "low1": "0", + "high1": "252", + "req1": "1", + "color1": "#766443", + "image1": "Strength icon.png" + } + ] + }, + { + "title": "Opal", + "names": [ + "items.opal" + ], + "entries": [ + { + "label": "Gem cutting rates", + "label1": "Opal", + "low1": "128", + "high1": "250", + "req1": "1", + "color1": "gray", + "image1": "Opal.png", + "label2": "Jade", + "low2": "100", + "high2": "245", + "req2": "13", + "color2": "green", + "image2": "Jade.png", + "label3": "Red topaz", + "low3": "90", + "high3": "240", + "req3": "16", + "color3": "pink", + "image3": "Red topaz.png" + } + ] + }, + { + "title": "Orange salamander (Hunter)", + "names": [ + "npcs.salamander_orange" + ], + "entries": [ + { + "label": "Orange salamander catch chance", + "showbefore": "no", + "label1": "Orange salamander", + "low1": "16", + "high1": "288", + "req1": "47", + "color1": "#976b1e", + "image1": "Orange salamander.png" + } + ] + }, + { + "title": "Oropher", + "names": [ + "npcs.prif_citizen_oropher" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Orophin", + "names": [ + "npcs.prif_citizen_orophin" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Paddlefish", + "names": [ + "items.gauntlet_food" + ], + "entries": [ + { + "label": "Paddlefish cooking chance", + "label1": "Range", + "low1": "155", + "high1": "368", + "req1": "30", + "color1": "saddlebrown", + "image1": "Paddlefish.png" + } + ] + }, + { + "title": "Paladin", + "names": [ + "npcs.paladin", + "npcs.paladin_variant01", + "npcs.paladin_variant02", + "npcs.paladin_f", + "npcs.paladin_f_variant01", + "npcs.paladin_west_vis", + "npcs.paladin_west_f_vis", + "npcs.paladin2" + ], + "entries": [ + { + "label": "Paladin pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "40", + "high1": "170", + "req1": "70", + "color1": "gray", + "image1": "Thief Paladin.png", + "label2": "Gloves of silence", + "low2": "42", + "high2": "178", + "req2": "70", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "44", + "high3": "187", + "req3": "70", + "color3": "black", + "image3": "Ardougne cloak 2.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "48", + "high4": "205", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Pay-dirt", + "names": [ + "items.paydirt" + ], + "entries": [ + { + "label": "Pay-dirt mining chance", + "xlabel": "Mining level", + "showbefore": "no", + "label1": "Pay-dirt", + "low1": "60", + "high1": "105", + "req1": "30", + "color1": "brown", + "image1": "Pay-dirt.png" + }, + { + "label": "Motherlode Mine ore chance", + "xlabel": "Mining level", + "cascade": "yes", + "showbefore": "no", + "label1": "Golden nugget", + "low1": "7", + "high1": "7", + "req1": "30", + "color1": "gold", + "image1": "Golden nugget.png", + "label2": "Runite ore", + "low2": "-20", + "high2": "5", + "req2": "85", + "color2": "#6f97ad", + "image2": "Runite ore.png", + "label3": "Adamantite ore", + "low3": "-90", + "high3": "50", + "req3": "70", + "color3": "#76a86f", + "image3": "Adamantite ore.png", + "label4": "Mithril ore", + "low4": "-19", + "high4": "90", + "req4": "55", + "color4": "#4d52a1", + "image4": "Mithril ore.png", + "label5": "Gold ore", + "low5": "-40", + "high5": "126", + "req5": "40", + "color5": "#9e7f4d", + "image5": "Gold ore.png", + "label6": "Coal", + "low6": "226", + "high6": "325", + "req6": "30", + "image6": "Coal.png", + "color6": "#000000" + } + ] + }, + { + "title": "Pie dish", + "names": [ + "items.piedish" + ], + "entries": [ + { + "label": "Firing pottery success rate", + "xlabel": "Crafting level", + "showbefore": "no", + "label1": "Unfired pie dish", + "low1": "180", + "high1": "800", + "req1": "1", + "color1": "#5b4309", + "image1": "Unfired pie dish.png" + } + ] + }, + { + "title": "Pike", + "names": [ + "items.pike" + ], + "entries": [ + { + "label": "Pike cooking chance", + "label1": "Fire or Range", + "low1": "78", + "high1": "412", + "req1": "20", + "color1": "gray", + "image1": "Pike.png", + "label2": "Lumbridge range", + "low2": "88", + "high2": "432", + "req2": "20", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "90", + "high3": "424", + "req3": "20", + "color3": "red", + "image3": "Pike.png", + "label4": "Hosidius +10%", + "low4": "103", + "high4": "437", + "req4": "79", + "color4": "blue", + "image4": "Pike.png" + } + ] + }, + { + "title": "Pit (Klenter's Pyramid)", + "names": [ + "objects.ics_little_pit_to", + "objects.ics_little_pit_from" + ], + "entries": [ + { + "label": "Pit", + "label1": "Success chance to cross", + "low1": "80", + "high1": "230", + "req1": "1", + "color1": "Grey", + "image1": "Agility icon.png" + } + ] + }, + { + "title": "Pitta bread", + "names": [ + "items.pitta_bread" + ], + "entries": [ + { + "label": "Pitta bread cooking chance", + "label1": "Range", + "low1": "118", + "high1": "492", + "req1": "58", + "color1": "saddlebrown", + "image1": "Pitta bread.png", + "label2": "Hosidius +5%", + "low2": "130", + "high2": "504", + "req2": "58", + "color2": "red", + "image2": "Pitta bread.png", + "label3": "Hosidius +10%", + "low3": "143", + "high3": "517", + "req3": "79", + "color3": "blue", + "image3": "Pitta bread.png" + } + ] + }, + { + "title": "Plain pizza", + "names": [ + "items.plain_pizza", + "items.half_plain_pizza" + ], + "entries": [ + { + "label": "Pizza cooking chance", + "label1": "Range", + "low1": "48", + "high1": "352", + "req1": "35", + "color1": "gray", + "image1": "Plain_pizza.png", + "label2": "Hosidius +5%", + "low2": "60", + "high2": "364", + "req2": "35", + "color2": "red", + "image2": "Plain_pizza.png", + "label3": "Hosidius +10%", + "low3": "73", + "high3": "377", + "req3": "79", + "color3": "blue", + "image3": "Plain_pizza.png" + } + ] + }, + { + "title": "Poison karambwan", + "names": [ + "items.tbwt_poorly_cooked_karambwan" + ], + "entries": [ + { + "label": "Poison karambwan cooking chance", + "label1": "Fire or Range", + "low1": "70", + "high1": "255", + "req1": "1", + "color1": "gray", + "image1": "Poison_karambwan.png", + "label2": "Hosidius +5%", + "low2": "82", + "high2": "267", + "req2": "1", + "color2": "red", + "image2": "Poison_karambwan.png", + "label3": "Hosidius +10%", + "low3": "95", + "high3": "280", + "req3": "79", + "color3": "blue", + "image3": "Poison_karambwan.png" + } + ] + }, + { + "title": "Polar kebbit", + "names": [], + "entries": [ + { + "label": "Polar kebbit catch chance", + "label1": "Polar kebbit", + "low1": "238", + "high1": "1080", + "req1": "1", + "color1": "#a5a8b1", + "image1": "Polar kebbit icon.png" + } + ] + }, + { + "title": "Pot", + "names": [ + "items.pot_empty" + ], + "entries": [ + { + "label": "Firing pottery success rate", + "xlabel": "Crafting level", + "showbefore": "no", + "label1": "Unfired pot", + "low1": "180", + "high1": "800", + "req1": "1", + "color1": "#84630d", + "image1": "Unfired pot.png" + } + ] + }, + { + "title": "Pot lid", + "names": [ + "items.potlid" + ], + "entries": [ + { + "label": "Firing pottery success rate", + "xlabel": "Crafting level", + "showbefore": "no", + "label1": "Unfired pot lid", + "low1": "180", + "high1": "800", + "req1": "1", + "color1": "#7b6c52", + "image1": "Unfired pot lid.png" + } + ] + }, + { + "title": "Prototype dart", + "names": [ + "items.thprotodart" + ], + "entries": [ + { + "label": "Prototype dart creation chance", + "label1": "Prototype dart", + "low1": "61", + "high1": "254", + "req1": "10", + "image1": "Prototype_dart.png" + } + ] + }, + { + "title": "Prototype dart tip", + "names": [ + "items.thprotodarttip" + ], + "entries": [ + { + "label": "Prototype dart tip creation chance", + "label1": "Prototype dart tip", + "low1": "61", + "high1": "245", + "req1": "20", + "image1": "Prototype_dart_tip.png" + } + ] + }, + { + "title": "Pyre fox", + "names": [ + "npcs.varlamore_hunterfox01" + ], + "entries": [ + { + "label": "Pyre fox catch chance", + "showbefore": "no", + "label1": "Pyre fox", + "low1": "-475", + "high1": "750", + "req1": "57", + "color1": "Orange", + "image1": "Pyre fox icon.png" + } + ] + }, + { + "title": "Railing", + "names": [ + "items.mcannonrailing1_obj" + ], + "entries": [ + { + "label": "Chance of successfully repairing a railing", + "xlabel": "Crafting level", + "label1": "Railing", + "low1": "60", + "high1": "150", + "color1": "grey", + "image1": "Railing.png" + } + ] + }, + { + "title": "Rainbow fish", + "names": [ + "items.hunting_fish_special" + ], + "entries": [ + { + "label": "Rainbow fish cooking chance", + "label1": "Fire or Range", + "low1": "56", + "high1": "370", + "req1": "35", + "color1": "gray", + "image1": "Rainbow fish.png", + "label2": "Hosidius +5%", + "low2": "68", + "high2": "382", + "req2": "35", + "color2": "red", + "image2": "Rainbow fish.png", + "label3": "Hosidius +10%", + "low3": "81", + "high3": "395", + "req3": "79", + "color3": "blue", + "image3": "Rainbow fish.png" + } + ] + }, + { + "title": "Raw anchovies", + "names": [ + "items.raw_anchovies" + ], + "entries": [ + { + "label": "Shrimp + anchovies fishing chance", + "cascade": "yes", + "label1": "Raw anchovies", + "low1": "24", + "high1": "128", + "req1": "15", + "color1": "#6e6e8b", + "image1": "Raw anchovies.png", + "label2": "Raw shrimps", + "low2": "48", + "high2": "256", + "req2": "1", + "color2": "#b18065", + "image2": "Raw shrimps.png" + } + ] + }, + { + "title": "Raw anglerfish", + "names": [ + "items.raw_anglerfish" + ], + "entries": [ + { + "label": "Anglerfish fishing chance", + "showbefore": "no", + "label1": "Sandworms", + "low1": "3", + "high1": "36", + "req1": "82", + "color1": "green", + "image1": "Sandworms.png", + "label2": "Diabolic worms", + "low2": "13", + "high2": "100", + "req2": "82", + "color2": "#c77f72", + "image2": "Diabolic worms.png" + } + ] + }, + { + "title": "Raw bass", + "names": [ + "items.raw_bass" + ], + "entries": [ + { + "label": "Big net fishing chance", + "showbefore": "no", + "label1": "Raw bass", + "low1": "3", + "high1": "40", + "req1": "46", + "color1": "#cb410b", + "image1": "Raw bass.png" + } + ] + }, + { + "title": "Raw cave eel", + "names": [ + "items.raw_cave_eel" + ], + "entries": [ + { + "label": "Slimy + cave eel fishing chance", + "cascade": "yes", + "showbefore": "no", + "label1": "Raw cave eel", + "low1": "10", + "high1": "80", + "req1": "38", + "color1": "#606b48", + "image1": "Raw cave eel.png", + "label2": "Raw slimy eel", + "low2": "10", + "high2": "80", + "req2": "28", + "color2": "#363c00", + "image2": "Raw slimy eel.png" + } + ] + }, + { + "title": "Raw cod", + "names": [ + "items.raw_cod" + ], + "entries": [ + { + "label": "Big net fishing chance", + "showbefore": "no", + "label1": "Raw cod", + "low1": "4", + "high1": "55", + "req1": "23", + "color1": "blue", + "image1": "Raw cod.png" + } + ] + }, + { + "title": "Raw dark crab", + "names": [ + "items.raw_dark_crab" + ], + "entries": [ + { + "label": "Dark crab fishing chance", + "xlabel": "Fishing level", + "showbefore": "no", + "label1": "Normal", + "low1": "3", + "high1": "40", + "req1": "85", + "color1": "gray", + "image1": "Raw dark crab.png", + "label2": "Elite Wilderness Diary", + "low2": "13", + "high2": "55", + "bonuslow2": "3", + "bonushigh2": "40", + "req2": "85", + "color2": "Purple", + "image2": "Wilderness sword 4.png" + } + ] + }, + { + "title": "Raw harpoonfish", + "names": [ + "items.tempoross_raw_harpoonfish" + ], + "entries": [ + { + "label": "Harpoonfish fishing chance", + "showbefore": "no", + "label1": "Harpoon", + "low1": "170", + "high1": "255", + "req1": "35", + "color1": "saddlebrown", + "image1": "Harpoon.png", + "label2": "Dragon harpoon", + "low2": "178", + "high2": "267", + "req2": "61", + "color2": "firebrick", + "image2": "Dragon harpoon.png", + "label3": "Crystal harpoon", + "low3": "187", + "high3": "280", + "req3": "71", + "color3": "cyan", + "image3": "Crystal harpoon.png" + } + ] + }, + { + "title": "Raw herring", + "names": [ + "items.raw_herring" + ], + "entries": [ + { + "label": "Herring + sardine fishing chance", + "cascade": "yes", + "showbefore": "no", + "label1": "Herring", + "low1": "24", + "high1": "128", + "req1": "10", + "color1": "grey", + "image1": "Raw herring.png", + "label2": "Sardine", + "low2": "32", + "high2": "192", + "req2": "5", + "color2": "green", + "image2": "Raw sardine.png" + } + ] + }, + { + "title": "Raw karambwan", + "names": [ + "items.tbwt_raw_karambwan" + ], + "entries": [ + { + "label": "Karambwan fishing chance", + "showbefore": "no", + "label1": "Raw karambwan", + "low1": "5", + "high1": "160", + "req1": "65", + "color1": "green", + "image1": "Raw karambwan.png" + } + ] + }, + { + "title": "Raw karambwanji", + "names": [ + "items.tbwt_raw_karambwanji" + ], + "entries": [ + { + "label": "Karambwanji + shrimp fishing chance", + "cascade": "yes", + "label1": "Raw karambwanji", + "low1": "100", + "high1": "250", + "req1": "5", + "color1": "#145056", + "image1": "Raw karambwanji.png", + "label2": "Raw shrimps", + "low2": "48", + "high2": "256", + "req2": "1", + "color2": "#b18065", + "image2": "Raw shrimps.png" + } + ] + }, + { + "title": "Raw lava eel", + "names": [ + "items.raw_lava_eel" + ], + "entries": [ + { + "label": "Lava eel fishing chance", + "showbefore": "no", + "label1": "Oily fishing rod", + "low1": "16", + "high1": "96", + "req1": "53", + "color1": "#bc6217", + "image1": "Oily fishing rod.png" + } + ] + }, + { + "title": "Raw lobster", + "names": [ + "items.raw_lobster" + ], + "entries": [ + { + "label": "Lobster fishing chance", + "showbefore": "no", + "label1": "Raw lobster", + "low1": "6", + "high1": "95", + "req1": "40", + "color1": "#854c22", + "image1": "Raw lobster.png" + } + ] + }, + { + "title": "Raw mackerel", + "names": [ + "items.raw_mackerel" + ], + "entries": [ + { + "label": "Big net fishing chance", + "showbefore": "no", + "label1": "Raw mackerel", + "low1": "5", + "high1": "65", + "bonuslow1": "10", + "bonushigh1": "10", + "req1": "16", + "color1": "#efcc00", + "image1": "Raw mackerel.png" + } + ] + }, + { + "title": "Raw monkfish", + "names": [ + "items.raw_monkfish" + ], + "entries": [ + { + "label": "Monkfish fishing chance", + "showbefore": "no", + "label1": "Raw monkfish", + "low1": "48", + "high1": "90", + "req1": "62", + "color1": "saddlebrown", + "image1": "Raw monkfish.png" + } + ] + }, + { + "title": "Raw pike", + "names": [ + "items.raw_pike" + ], + "entries": [ + { + "label": "Pike fishing chance", + "showbefore": "no", + "label1": "Raw pike", + "low1": "16", + "high1": "96", + "req1": "25", + "color1": "#6e8b6e", + "image1": "Raw pike.png" + } + ] + }, + { + "title": "Raw rainbow fish", + "names": [ + "items.hunting_raw_fish_special" + ], + "entries": [ + { + "label": "Rainbow fish fishing chance", + "showbefore": "no", + "label1": "Raw rainbow fish", + "low1": "8", + "high1": "64", + "req1": "38", + "color1": "#7778d1", + "image1": "Raw rainbow fish.png" + } + ] + }, + { + "title": "Raw salmon", + "names": [ + "items.raw_salmon" + ], + "entries": [ + { + "label": "Trout + salmon fishing chance", + "cascade": "yes", + "showbefore": "no", + "label1": "Raw salmon", + "low1": "16", + "high1": "96", + "req1": "30", + "color1": "#c77f72", + "image1": "Raw salmon.png", + "label2": "Raw trout", + "low2": "32", + "high2": "192", + "req2": "20", + "color2": "#9a908f", + "image2": "Raw trout.png" + } + ] + }, + { + "title": "Raw sardine", + "names": [ + "items.raw_sardine" + ], + "entries": [ + { + "label": "Herring + sardine fishing chance", + "cascade": "yes", + "showbefore": "no", + "label1": "Herring", + "low1": "24", + "high1": "128", + "req1": "10", + "color1": "grey", + "image1": "Raw herring.png", + "label2": "Sardine", + "low2": "32", + "high2": "192", + "req2": "5", + "color2": "green", + "image2": "Raw sardine.png" + } + ] + }, + { + "title": "Raw shark", + "names": [ + "items.raw_shark" + ], + "entries": [ + { + "label": "Shark fishing chance", + "showbefore": "no", + "label1": "Harpoon", + "low1": "3", + "high1": "40", + "req1": "76", + "color1": "#736b6b", + "image1": "Harpoon.png", + "label2": "Dragon", + "low2": "3", + "high2": "48", + "req2": "76", + "color2": "firebrick", + "image2": "Dragon harpoon.png", + "label3": "Crystal", + "low3": "4", + "high3": "54", + "req3": "76", + "color3": "cyan", + "image3": "Crystal harpoon.png" + } + ] + }, + { + "title": "Raw shrimps", + "names": [ + "items.raw_shrimp" + ], + "entries": [ + { + "label": "Shrimp + anchovies fishing chance", + "cascade": "yes", + "label1": "Raw anchovies", + "low1": "24", + "high1": "128", + "req1": "15", + "color1": "#6e6e8b", + "image1": "Raw anchovies.png", + "label2": "Raw shrimps", + "low2": "48", + "high2": "256", + "req2": "1", + "color2": "#b18065", + "image2": "Raw shrimps.png" + } + ] + }, + { + "title": "Raw slimy eel", + "names": [ + "items.mort_slimey_eel" + ], + "entries": [ + { + "label": "Slimy + cave eel fishing chance", + "cascade": "yes", + "showbefore": "no", + "label1": "Raw cave eel", + "low1": "10", + "high1": "80", + "req1": "38", + "color1": "#606b48", + "image1": "Raw cave eel.png", + "label2": "Raw slimy eel", + "low2": "10", + "high2": "80", + "req2": "28", + "color2": "brown", + "image2": "Raw slimy eel.png" + } + ] + }, + { + "title": "Raw swordfish", + "names": [ + "items.raw_swordfish" + ], + "entries": [ + { + "label": "Swordfish + tuna fishing chance", + "cascade": "yes", + "showbefore": "no", + "label1": "Swordfish", + "low1": "4", + "high1": "48", + "req1": "50", + "color1": "mediumorchid", + "image1": "Raw swordfish.png", + "label2": "Tuna", + "low2": "8", + "high2": "64", + "req2": "35", + "color2": "grey", + "image2": "Raw tuna.png" + }, + { + "label": "Swordfish + tuna fishing chance", + "cascade": "yes", + "showbefore": "no", + "label1": "Swordfish", + "low1": "4", + "high1": "57", + "req1": "50", + "color1": "mediumorchid", + "image1": "Raw swordfish.png", + "label2": "Tuna", + "low2": "9", + "high2": "76", + "req2": "35", + "color2": "grey", + "image2": "Raw tuna.png" + }, + { + "label": "Swordfish + tuna fishing chance", + "cascade": "yes", + "showbefore": "no", + "label1": "Swordfish", + "low1": "5", + "high1": "64", + "req1": "50", + "color1": "mediumorchid", + "image1": "Raw swordfish.png", + "label2": "Tuna", + "low2": "10", + "high2": "86", + "req2": "35", + "color2": "grey", + "image2": "Raw tuna.png" + } + ] + }, + { + "title": "Raw trout", + "names": [ + "items.raw_trout" + ], + "entries": [ + { + "label": "Trout + salmon fishing chance", + "xlabel": "Fishing level", + "cascade": "yes", + "showbefore": "no", + "label1": "Raw salmon", + "low1": "16", + "high1": "96", + "req1": "30", + "color1": "#c77f72", + "image1": "Raw salmon.png", + "label2": "Raw trout", + "low2": "32", + "high2": "192", + "req2": "20", + "color2": "#9a908f", + "image2": "Raw trout.png" + } + ] + }, + { + "title": "Raw tuna", + "names": [ + "items.raw_tuna" + ], + "entries": [ + { + "label": "Swordfish + tuna fishing chance", + "cascade": "yes", + "showbefore": "no", + "label1": "Swordfish", + "low1": "4", + "high1": "48", + "req1": "50", + "color1": "mediumorchid", + "image1": "Raw swordfish.png", + "label2": "Tuna", + "low2": "8", + "high2": "64", + "req2": "35", + "color2": "grey", + "image2": "Raw tuna.png" + }, + { + "label": "Swordfish + tuna fishing chance", + "cascade": "yes", + "showbefore": "no", + "label1": "Swordfish", + "low1": "4", + "high1": "57", + "req1": "50", + "color1": "mediumorchid", + "image1": "Raw swordfish.png", + "label2": "Tuna", + "low2": "9", + "high2": "76", + "req2": "35", + "color2": "grey", + "image2": "Raw tuna.png" + }, + { + "label": "Swordfish + tuna fishing chance", + "cascade": "yes", + "showbefore": "no", + "label1": "Swordfish", + "low1": "5", + "high1": "64", + "req1": "50", + "color1": "mediumorchid", + "image1": "Raw swordfish.png", + "label2": "Tuna", + "low2": "10", + "high2": "86", + "req2": "35", + "color2": "grey", + "image2": "Raw tuna.png" + } + ] + }, + { + "title": "Red salamander (Hunter)", + "names": [ + "npcs.salamander_red" + ], + "entries": [ + { + "label": "Salamander catch chance", + "showbefore": "no", + "label1": "Red salamander", + "low1": "0", + "high1": "240", + "req1": "59", + "color1": "#6c2413", + "image1": "Red salamander.png" + } + ] + }, + { + "title": "Red topaz", + "names": [ + "items.red_topaz" + ], + "entries": [ + { + "label": "Gem cutting rates", + "label1": "Opal", + "low1": "128", + "high1": "250", + "req1": "1", + "color1": "gray", + "image1": "Opal.png", + "label2": "Jade", + "low2": "100", + "high2": "245", + "req2": "13", + "color2": "green", + "image2": "Jade.png", + "label3": "Red topaz", + "low3": "90", + "high3": "240", + "req3": "16", + "color3": "red", + "image3": "Red topaz.png" + } + ] + }, + { + "title": "Redberry pie", + "names": [ + "items.redberry_pie", + "items.half_a_redberry_pie" + ], + "entries": [ + { + "label": "Redberry pie cooking chance", + "xlabel": "Cooking level", + "label1": "Range", + "low1": "98", + "high1": "452", + "req1": "10", + "color1": "gray", + "image1": "Redberry pie.png", + "label2": "Lumbridge range", + "low2": "108", + "high2": "462", + "req2": "10", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "110", + "high3": "464", + "req3": "10", + "color3": "red", + "image3": "Redberry pie.png", + "label4": "Hosidius +10%", + "low4": "123", + "high4": "477", + "req4": "79", + "color4": "blue", + "image4": "Redberry pie.png" + } + ] + }, + { + "title": "Redwood birdhouse", + "names": [ + "objects.birdhouse_redwood_built", + "objects.birdhouse_redwood_full", + "objects.birdhouse_redwood_bird" + ], + "entries": [ + { + "label": "Seed nest chance", + "xlabel": "Hunter level", + "label1": "Seed nest", + "low1": "0", + "high1": "200", + "req1": "89", + "color1": "grey", + "image1": "Bird nest (seeds).png" + }, + { + "label": "Other nests (10 rolls per birdhouse)", + "xlabel": "Hunter level", + "birdhouse": "yes", + "label1": "Redwood", + "high1": "175", + "req1": "89", + "color1": "#ff00ff", + "image1": "Redwood bird house.png" + } + ] + }, + { + "title": "Redwood tree", + "names": [ + "objects.redwoodtree_l", + "objects.redwoodtree_r", + "objects.redwoodtree_l_cut", + "objects.redwoodtree_r_cut", + "objects.redwoodtree_middle_side2", + "objects.redwoodtree_middle_side3" + ], + "entries": [ + { + "label": "Redwood tree cut chance", + "showbefore": "no", + "label1": "Bronze", + "low1": "2", + "high1": "6", + "req1": "90", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "3", + "high2": "9", + "req2": "90", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "4", + "high3": "12", + "req3": "90", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "4", + "high4": "14", + "req4": "90", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "5", + "high5": "15", + "req5": "90", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "6", + "high6": "18", + "req6": "90", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "7", + "high7": "21", + "req7": "90", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "7", + "high8": "30", + "req8": "90", + "color8": "firebrick", + "image8": "Dragon axe.png", + "label9": "Crystal", + "low9": "8", + "high9": "35", + "req9": "90", + "color9": "cyan", + "image9": "Crystal axe.png" + } + ] + }, + { + "title": "Money making guide/Cooking raw sunlight antelope", + "names": [], + "entries": [ + { + "label": "Cooked sunlight antelope cooking chance", + "showbefore": "no", + "label1": "Fire", + "low1": "8", + "high1": "254", + "req1": "62", + "color1": "orange", + "image1": "Firemaking icon.png", + "label2": "Range", + "low2": "8", + "high2": "265", + "req2": "62", + "color2": "saddlebrown", + "image2": "Cooking range icon.png", + "label3": "Hosidius +5%", + "low3": "20", + "high3": "277", + "req3": "62", + "color3": "red", + "image3": "Cooking range icon.png", + "label4": "Hosidius +10%", + "low4": "33", + "high4": "290", + "req4": "79", + "color4": "blue", + "image4": "Cooking range icon.png" + } + ] + }, + { + "title": "Resurrect Crops", + "names": [], + "entries": [ + { + "label": "Dead crop revival chance", + "xlabel": "Magic level", + "ylabel": "Success chance", + "showbefore": "no", + "label1": "Resurrect Crops", + "low1": "-106", + "high1": "192", + "req1": "78", + "color1": "#AFEF0B", + "image1": "Resurrect Crops.png" + } + ] + }, + { + "title": "Roast beast meat", + "names": [ + "items.spit_roasted_beast_meat" + ], + "entries": [ + { + "label": "Roast beast meat cooking chance", + "showbefore": "no", + "label1": "Fire", + "low1": "180", + "high1": "255", + "req1": "21", + "color1": "orange", + "image1": "Firemaking icon.png" + } + ] + }, + { + "title": "Roast bird meat", + "names": [ + "items.spit_roasted_bird_meat" + ], + "entries": [ + { + "label": "Roast bird meat cooking chance", + "label1": "Fire", + "low1": "155", + "high1": "255", + "req1": "11", + "color1": "orange", + "image1": "Firemaking icon.png" + } + ] + }, + { + "title": "Roast rabbit", + "names": [ + "items.spit_roasted_rabbit_meat" + ], + "entries": [ + { + "label": "Roast rabbit cooking chance", + "label1": "Fire", + "low1": "160", + "high1": "255", + "req1": "16", + "color1": "orange", + "image1": "Firemaking icon.png" + } + ] + }, + { + "title": "Rock (Abyss)", + "names": [ + "objects.rcu_abyssal_barrier_teeth1", + "objects.rcu_abyssal_barrier_teeth2", + "objects.rcu_abyssal_barrier_teeth3" + ], + "entries": [ + { + "label": "Rock mining chance", + "xlabel": "Mining level", + "label1": "Success", + "low1": "0", + "high1": "255", + "image1": "Black pickaxe.png", + "color1": "#692208" + } + ] + }, + { + "title": "Roe", + "names": [ + "items.brut_roe" + ], + "entries": [ + { + "label": "Roe creation chance", + "xlabel": "Cooking Level", + "showbefore": "no", + "caviar": "yes", + "label1": "Leaping salmon", + "denom1": "80", + "req1": "1", + "color1": "pink", + "image1": "Leaping salmon.png", + "label2": "Leaping trout", + "denom2": "150", + "req2": "1", + "color2": "gray", + "image2": "Leaping trout.png" + } + ] + }, + { + "title": "Rogue", + "names": [ + "npcs.rogue", + "npcs.wilderness_rogue" + ], + "entries": [ + { + "label": "Rogue pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "74", + "high1": "240", + "req1": "32", + "color1": "gray", + "image1": "Thieving icon.png", + "label2": "Gloves of silence", + "low2": "77", + "high2": "252", + "req2": "32", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "81", + "high3": "264", + "req3": "32", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "89", + "high4": "290", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Rope swing (Underground Pass, north)", + "names": [ + "objects.obstical_rockswing_withrope", + "objects.obstical_rockswing_middle", + "objects.obstical_rockswing_norope" + ], + "entries": [ + { + "label": "Rope swing success rate", + "lowlevel": "0", + "showbefore": "no", + "label1": "Rope swing", + "low1": "100", + "high1": "300", + "req1": "1", + "color1": "#352e00", + "image1": "Agility icon.png" + } + ] + }, + { + "title": "Ropeswing (Wilderness Agility Course)", + "names": [ + "objects.obstical_ropeswing2" + ], + "entries": [ + { + "label": "Ropeswing", + "label1": "Swing-on success rate", + "xlabel": "Agility level", + "low1": "200", + "high1": "250", + "req1": "1", + "color1": "#151111", + "image1": "Agility icon.png" + } + ] + }, + { + "title": "Rune axe", + "names": [ + "items.rune_axe" + ], + "entries": [ + { + "label": "Rune axe success chances", + "showbefore": "yes", + "label1": "Yew tree", + "low1": "14", + "high1": "44", + "req1": "60", + "color1": "saddlebrown", + "image1": "Yew logs.png", + "label2": "Magic tree", + "low2": "7", + "high2": "21", + "req2": "75", + "color2": "slateblue", + "image2": "Magic logs.png", + "label3": "Mahogany tree", + "low3": "29", + "high3": "88", + "req3": "50", + "color3": "peru", + "image3": "Mahogany logs.png", + "label4": "Maple tree", + "low4": "28", + "high4": "87", + "req4": "45", + "color4": "chocolate", + "image4": "Maple logs.png", + "label5": "Teak tree", + "low5": "55", + "high5": "164", + "req5": "35", + "color5": "tan", + "image5": "Teak logs.png", + "label6": "Willow tree", + "low6": "56", + "high6": "175", + "req6": "30", + "color6": "darkolivegreen", + "image6": "Willow logs.png", + "label7": "Oak tree", + "low7": "112", + "high7": "350", + "req7": "15", + "color7": "wheat", + "image7": "Oak logs.png", + "label8": "Redwood tree", + "low8": "7", + "high8": "16", + "req8": "90", + "color8": "red", + "image8": "Redwood logs.png" + } + ] + }, + { + "title": "Runite rocks", + "names": [ + "objects.runiterock2", + "objects.runiterock1", + "objects.prif_mine_runiterock1" + ], + "entries": [ + { + "label": "Runite rocks mining chance", + "showbefore": "no", + "label1": "Runite rocks", + "low1": "1", + "high1": "18", + "req1": "85", + "color1": "steelblue", + "image1": "Runite ore.png" + } + ] + }, + { + "title": "Rusty sword", + "names": [ + "items.digsitesword" + ], + "entries": [ + { + "label": "Rusty sword repair chance", + "xlabel": "Smithing level", + "label1": "Rusty sword", + "low1": "100", + "high1": "239", + "color1": "chocolate", + "image1": "Rusty sword.png" + } + ] + }, + { + "title": "Sack (Tombs of Amascut)", + "names": [ + "objects.toa_sack_full" + ], + "entries": [ + { + "label": "Sack success chance", + "xlabel": "Thieving level", + "label1": "Normal", + "": "", + "low1": "1", + "high1": "10", + "req1": "1", + "color1": "tan", + "image1": "Grain (Tombs of Amascut).png" + } + ] + }, + { + "title": "Sacred eel", + "names": [ + "items.snakeboss_eel" + ], + "entries": [ + { + "label": "Sacred eel catch chance", + "showbefore": "no", + "label1": "Sacred eel", + "low1": "0", + "high1": "60", + "req1": "87", + "color1": "darkseagreen", + "image1": "Sacred eel.png" + } + ] + }, + { + "title": "Saeros", + "names": [ + "npcs.prif_citizen_saeros" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Salgant", + "names": [ + "npcs.prif_citizen_salgant" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Salmon", + "names": [ + "items.salmon" + ], + "entries": [ + { + "label": "Salmon cooking chance", + "label1": "Fire or Range", + "low1": "68", + "high1": "392", + "req1": "25", + "color1": "gray", + "image1": "Salmon.png", + "label2": "Lumbridge range", + "low2": "78", + "high2": "402", + "req2": "25", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "80", + "high3": "404", + "req3": "25", + "color3": "red", + "image3": "Salmon.png", + "label4": "Hosidius +10%", + "low4": "93", + "high4": "417", + "req4": "79", + "color4": "blue", + "image4": "Salmon.png" + } + ] + }, + { + "title": "Salvager", + "names": [ + "npcs.varlamore_salvager_m_1", + "npcs.varlamore_salvager_m_2", + "npcs.varlamore_salvager_m_3", + "npcs.varlamore_salvager_m_4", + "npcs.varlamore_salvager_f_1", + "npcs.varlamore_salvager_f_2", + "npcs.varlamore_salvager_f_3" + ], + "entries": [ + { + "label": "Citizen pickpocket chance", + "label1": "Normal", + "low1": "180", + "high1": "240", + "req1": "1", + "color1": "gray", + "image1": "Thieving icon.png", + "label2": "Gloves of silence", + "low2": "189", + "high2": "252", + "req2": "1", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "198", + "high3": "264", + "req3": "1", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "217", + "high4": "290", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Sandstone", + "names": [ + "items.enakh_sandstone_tiny", + "items.enakh_sandstone_small", + "items.enakh_sandstone_medium", + "items.enakh_sandstone_large" + ], + "entries": [ + { + "label": "Sandstone mining chance", + "cascade": "yes", + "showbefore": "no", + "label1": "10kg", + "low1": "4", + "high1": "50", + "req1": "35", + "color1": "grey", + "image1": "Sandstone_(10kg).png", + "label2": "5kg", + "low2": "8", + "high2": "75", + "req2": "35", + "color2": "green", + "image2": "Sandstone_(5kg).png", + "label3": "2kg", + "low3": "16", + "high3": "100", + "req3": "35", + "color3": "blue", + "image3": "Sandstone_(2kg).png", + "label4": "1kg", + "low4": "25", + "high4": "200", + "req4": "35", + "color4": "red", + "image4": "Sandstone_(1kg).png" + } + ] + }, + { + "title": "Sandstone rocks", + "names": [ + "objects.enakh_sandstone_rocks" + ], + "entries": [ + { + "label": "Sandstone mining chance", + "cascade": "yes", + "showbefore": "no", + "label1": "10kg", + "low1": "4", + "high1": "50", + "req1": "35", + "color1": "grey", + "image1": "Sandstone_(10kg).png", + "label2": "5kg", + "low2": "8", + "high2": "75", + "req2": "35", + "color2": "green", + "image2": "Sandstone_(5kg).png", + "label3": "2kg", + "low3": "16", + "high3": "100", + "req3": "35", + "color3": "blue", + "image3": "Sandstone_(2kg).png", + "label4": "1kg", + "low4": "25", + "high4": "200", + "req4": "35", + "color4": "red", + "image4": "Sandstone_(1kg).png" + } + ] + }, + { + "title": "Sandworm castings", + "names": [ + "objects.piscarilius_grub_castings" + ], + "entries": [ + { + "label": "Digging up sandworm castings", + "showbefore": "no", + "label1": "Bucket of sandworms", + "low1": "148", + "high1": "178", + "req1": "15", + "color1": "#b66440", + "image1": "Bucket of sandworms.png", + "label2": "Bucket of sand", + "low2": "107", + "high2": "77", + "req2": "15", + "color2": "#948354", + "image2": "Bucket of sand.png" + } + ] + }, + { + "title": "Sardine", + "names": [ + "items.sardine" + ], + "entries": [ + { + "label": "Sardine cooking chance", + "label1": "Fire or Range", + "low1": "118", + "high1": "492", + "req1": "1", + "color1": "gray", + "image1": "Sardine.png", + "label2": "Lumbridge range", + "low2": "128", + "high2": "512", + "req2": "1", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "130", + "high3": "504", + "req3": "1", + "color3": "red", + "image3": "Sardine.png", + "label4": "Hosidius +10%", + "low4": "143", + "high4": "517", + "req4": "79", + "color4": "blue", + "image4": "Sardine.png" + } + ] + }, + { + "title": "Scimitar Stall", + "names": [ + "objects.mm_stall_scimitar" + ], + "entries": [ + { + "label": "Scimitar Stall thieving chance", + "showbefore": "no", + "label1": "Scimitar Stall", + "low1": "20", + "high1": "180", + "req1": "65", + "color1": "green", + "image1": "Adamant scimitar.png" + } + ] + }, + { + "title": "Scrambled egg", + "names": [ + "items.bowl_egg_scrambled" + ], + "entries": [ + { + "label": "Scrambled egg cooking chance", + "label1": "Range", + "low1": "90", + "high1": "438", + "req1": "13", + "color1": "gray", + "image1": "Scrambled egg.png", + "label2": "Hosidius +5%", + "low2": "102", + "high2": "450", + "req2": "13", + "color2": "red", + "image2": "Scrambled egg.png", + "label3": "Hosidius +10%", + "low3": "115", + "high3": "463", + "req3": "79", + "color3": "blue", + "image3": "Scrambled egg.png" + } + ] + }, + { + "title": "Sea turtle", + "names": [ + "items.seaturtle" + ], + "entries": [ + { + "label": "Sea turtle cooking chance", + "showbefore": "no", + "label1": "Fire", + "low1": "1", + "high1": "202", + "req1": "82", + "color1": "orange", + "image1": "Firemaking icon.png", + "label2": "Range", + "low2": "1", + "high2": "222", + "req2": "82", + "color2": "saddlebrown", + "image2": "Cooking range icon.png", + "label3": "Hosidius +5%", + "low3": "13", + "high3": "234", + "req3": "82", + "color3": "red", + "image3": "Cooking range icon.png", + "label4": "Hosidius +10%", + "low4": "26", + "high4": "247", + "req4": "82", + "color4": "blue", + "image4": "Cooking range icon.png" + } + ] + }, + { + "title": "Secure chest", + "names": [ + "objects.fd_bandit_shutchest" + ], + "entries": [ + { + "label": "Secure chest success chance", + "showbefore": "no", + "label1": "Each lock", + "low1": "52", + "high1": "128", + "req1": "53", + "color1": "gray", + "image1": "Lockpick.png", + "label2": "Overall success", + "low2": "52", + "high2": "128", + "req2": "53", + "color2": "goldenrod", + "image2": "Gilded cross.png", + "exponent2": "3" + } + ] + }, + { + "title": "Servery cooked meat", + "names": [ + "items.hosidius_servery_cooked_meat" + ], + "entries": [ + { + "label": "Servery cooked meat cooking chance", + "label1": "Clay oven", + "low1": "128", + "high1": "512", + "req1": "1", + "color1": "saddlebrown", + "image1": "Cooking range icon.png" + } + ] + }, + { + "title": "Servery meat pie", + "names": [ + "items.hosidius_servery_meat_pie" + ], + "entries": [ + { + "label": "Servery meat pie cooking chance", + "label1": "Clay oven", + "low1": "78", + "high1": "412", + "req1": "20", + "color1": "saddlebrown", + "image1": "Cooking range icon.png" + } + ] + }, + { + "title": "Servery plain pizza", + "names": [ + "items.hosidius_servery_plain_pizza" + ], + "entries": [ + { + "label": "Servery plain pizza cooking chance", + "label1": "Clay oven", + "low1": "48", + "high1": "352", + "req1": "0", + "color1": "saddlebrown", + "image1": "Cooking range icon.png" + } + ] + }, + { + "title": "Servery stew", + "names": [ + "items.hosidius_servery_stew" + ], + "entries": [ + { + "label": "Servery stew cooking chance", + "label1": "Clay oven", + "low1": "68", + "high1": "392", + "req1": "25", + "color1": "saddlebrown", + "image1": "Cooking range icon.png" + } + ] + }, + { + "title": "Shark", + "names": [ + "items.shark" + ], + "entries": [ + { + "label": "Shark cooking chance", + "showbefore": "no", + "label1": "Fire", + "low1": "1", + "high1": "202", + "req1": "80", + "color1": "orange", + "image1": "Firemaking icon.png", + "label2": "Range", + "low2": "1", + "high2": "232", + "req2": "80", + "color2": "saddlebrown", + "image2": "Cooking range icon.png", + "label3": "Gauntlets", + "low3": "15", + "high3": "270", + "req3": "80", + "color3": "grey", + "image3": "Cooking gauntlets.png", + "label4": "Hosidius +5%", + "low4": "13", + "high4": "244", + "req4": "80", + "color4": "red", + "image4": "Cooking range icon.png", + "label5": "Hosidius +10%", + "low5": "26", + "high5": "257", + "req5": "80", + "color5": "blue", + "image5": "Cooking range icon.png", + "label6": "Hosidius +5%, gauntlets", + "low6": "27", + "high6": "282", + "req6": "80", + "color6": "#ffcccb", + "image6": "Cooking gauntlets.png", + "label7": "Hosidius +10%, gauntlets", + "low7": "40", + "high7": "295", + "req7": "80", + "color7": "#ccccff", + "image7": "Cooking gauntlets.png" + } + ] + }, + { + "title": "Shooting Stars", + "names": [], + "entries": [ + { + "color1": "goldenrod", + "high1": "117", + "image1": "Stardust_175.png", + "label": "Stardust mining chance", + "label1": "Stardust", + "low1": "73", + "req1": "10", + "showbefore": "no" + } + ] + }, + { + "title": "Shrimps", + "names": [ + "items.shrimp" + ], + "entries": [ + { + "label": "Shrimps cooking chance", + "xlabel": "Cooking level", + "label1": "Fire or Range", + "low1": "128", + "high1": "512", + "req1": "1", + "color1": "gray", + "image1": "Shrimps.png", + "label2": "Lumbridge range", + "low2": "138", + "high2": "532", + "req2": "1", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "140", + "high3": "524", + "req3": "1", + "color3": "red", + "image3": "Shrimps.png", + "label4": "Hosidius +10%", + "low4": "153", + "high4": "537", + "req4": "84", + "color4": "blue", + "image4": "Shrimps.png" + } + ] + }, + { + "title": "Silver rocks", + "names": [ + "objects.silverrock2", + "objects.silverrock1", + "objects.prif_mine_silverrock1" + ], + "entries": [ + { + "label": "Silver rocks mining chance", + "showbefore": "no", + "label1": "Silver rocks", + "low1": "25", + "high1": "200", + "req1": "20", + "color1": "silver", + "image1": "Silver ore.png" + } + ] + }, + { + "title": "Sinew", + "names": [ + "items.xbows_sinew" + ], + "entries": [ + { + "label": "Sinew cooking chance", + "label1": "Range", + "low1": "128", + "high1": "512", + "req1": "1", + "color1": "gray", + "image1": "Sinew.png", + "label2": "Hosidius +5%", + "low2": "140", + "high2": "524", + "req2": "1", + "color2": "red", + "image2": "Sinew.png", + "label3": "Hosidius +10%", + "low3": "153", + "high3": "537", + "req3": "79", + "color3": "blue", + "image3": "Sinew.png" + } + ] + }, + { + "title": "Sithik portrait", + "names": [ + "items.zogre_sithik_portrait_good", + "items.zogre_sithik_portrait_bad" + ], + "entries": [ + { + "label": "Good Sithik portrait chance", + "xlabel": "Crafting level", + "ylabel": "Success rate", + "label1": "''Sithik Ints'', ca. 169. Charcoal on papyrus, 26 × 29 px.", + "low1": "1", + "high1": "255", + "req1": "1", + "color1": "#372920", + "image1": "Sithik portrait.png" + } + ] + }, + { + "title": "Skilling success rate", + "names": [], + "entries": [ + { + "label": "Monkfish fishing chance", + "showbefore": "no", + "label1": "Raw monkfish", + "low1": "48", + "high1": "90", + "req1": "62", + "color1": "saddlebrown", + "image1": "Raw monkfish.png" + } + ] + }, + { + "title": "Smashed table", + "names": [ + "objects.zqtableraft" + ], + "entries": [ + { + "label": "Crafting the smashed table success chance", + "xlabel": "Crafting level", + "ylabel": "Success rate", + "label1": "Making the raft or saving the wood", + "low1": "125", + "high1": "250", + "req1": "1", + "color1": "#493411", + "image1": "Wooden table (small, Mahogany Homes) icon.png" + } + ] + }, + { + "title": "Snake weed", + "names": [ + "items.snake_weed" + ], + "entries": [ + { + "label": "Snake weed", + "label1": "Collecting success rate", + "xlabel": "Herblore level", + "low1": "10", + "high1": "220", + "showbefore": "no", + "color1": "#00800", + "image1": "Herblore icon.png" + } + ] + }, + { + "title": "Snowball", + "names": [ + "items.gublinch_snowball" + ], + "entries": [ + { + "label": "Snowball hit chance", + "xlabel": "Ranged level", + "ylabel": "Success chance", + "showbefore": "no", + "label1": "Pelt", + "low1": "150", + "high1": "300", + "req1": "1", + "color1": "#5aa5cd", + "image1": "Snowball 1.png" + } + ] + }, + { + "title": "Soda ash", + "names": [ + "items.soda_ash" + ], + "entries": [ + { + "label": "Giant seaweed success rate", + "label1": "Fire or Range", + "low1": "0", + "high1": "500", + "req1": "1", + "color1": "gray", + "image1": "Soda ash.png", + "label2": "Hosidius +5%", + "low2": "12", + "high2": "512", + "req2": "1", + "color2": "red", + "image2": "Soda ash.png", + "label3": "Hosidius +10%", + "low3": "25", + "high3": "525", + "req3": "79", + "color3": "blue", + "image3": "Soda ash.png" + } + ] + }, + { + "title": "Speartrap", + "names": [ + "objects.ntk_speartrap_inmotion" + ], + "entries": [ + { + "label": "Speartrap success rate", + "showbefore": "no", + "label1": "Speartrap", + "low1": "160", + "high1": "250", + "req1": "21", + "color1": "#897b31", + "image1": "Pharaoh's sceptre.png" + } + ] + }, + { + "title": "Spicy crunchies", + "names": [ + "items.spicy_crunchies" + ], + "entries": [ + { + "label": "Spicy crunchies cooking chance", + "label1": "Range", + "low1": "118", + "high1": "492", + "req1": "12", + "color1": "gray", + "image1": "Spicy crunchies.png", + "label2": "Hosidius +5%", + "low2": "130", + "high2": "504", + "req2": "12", + "color2": "red", + "image2": "Spicy crunchies.png", + "label3": "Hosidius +10%", + "low3": "143", + "high3": "517", + "req3": "79", + "color3": "blue", + "image3": "Spicy crunchies.png" + } + ] + }, + { + "title": "Spider on shaft", + "names": [ + "items.tbw_spider_on_shaft_cooked" + ], + "entries": [ + { + "label": "Spider on shaft cooking chance", + "label1": "Fire or Range", + "low1": "91", + "high1": "438", + "req1": "16", + "color1": "gray", + "image1": "Spider on shaft.png", + "label2": "Hosidius +5%", + "low2": "103", + "high2": "450", + "req2": "16", + "color2": "red", + "image2": "Spider on shaft.png", + "label3": "Hosidius +10%", + "low3": "116", + "high3": "463", + "req3": "79", + "color3": "blue", + "image3": "Spider on shaft.png" + } + ] + }, + { + "title": "Spider on shaft (raw)", + "names": [ + "items.tbw_spider_on_shaft_raw" + ], + "entries": [ + { + "label": "Spider on shaft cooking chance", + "label1": "Fire or Range", + "low1": "91", + "high1": "438", + "req1": "16", + "color1": "gray", + "image1": "Spider on shaft.png", + "label2": "Hosidius +5%", + "low2": "103", + "high2": "450", + "req2": "16", + "color2": "red", + "image2": "Spider on shaft.png", + "label3": "Hosidius +10%", + "low3": "116", + "high3": "463", + "req3": "79", + "color3": "blue", + "image3": "Spider on shaft.png" + } + ] + }, + { + "title": "Spider on stick", + "names": [ + "items.tbw_spider_on_stick_cooked" + ], + "entries": [ + { + "label": "Spider on stick cooking chance", + "label1": "Fire or Range", + "low1": "91", + "high1": "438", + "req1": "16", + "color1": "gray", + "image1": "Spider on stick.png", + "label2": "Hosidius +5%", + "low2": "103", + "high2": "450", + "req2": "16", + "color2": "red", + "image2": "Spider on stick.png", + "label3": "Hosidius +10%", + "low3": "116", + "high3": "463", + "req3": "79", + "color3": "blue", + "image3": "Spider on stick.png" + } + ] + }, + { + "title": "Spider on stick (raw)", + "names": [ + "items.tbw_spider_on_stick_raw" + ], + "entries": [ + { + "label": "Spider on stick cooking chance", + "label1": "Fire or Range", + "low1": "91", + "high1": "438", + "req1": "16", + "color1": "gray", + "image1": "Spider on stick.png", + "label2": "Hosidius +5%", + "low2": "103", + "high2": "450", + "req2": "16", + "color2": "red", + "image2": "Spider on stick.png", + "label3": "Hosidius +10%", + "low3": "116", + "high3": "463", + "req3": "79", + "color3": "blue", + "image3": "Spider on stick.png" + } + ] + }, + { + "title": "Spike trap", + "names": [], + "entries": [ + { + "label": "Spike trap evasion chance", + "xlabel": "Agility level", + "ylabel": "Evasion chance", + "showbefore": "no", + "label1": "Spike trap", + "low1": "30", + "high1": "210", + "req1": "1", + "color1": "#800000", + "image1": "Spike trap icon.png" + } + ] + }, + { + "title": "Spinning blades (Brimhaven Agility Arena)", + "names": [ + "objects.agilityarena_sawblades" + ], + "entries": [ + { + "label": "Spinning blades success rate", + "showbefore": "no", + "label1": "", + "low1": "153", + "high1": "255", + "req1": "40", + "color1": "#f07c15", + "image1": "Agility icon.png" + } + ] + }, + { + "title": "Spotted kebbit", + "names": [ + "npcs.huntingbeast_speedy" + ], + "entries": [ + { + "label": "Spotted kebbit catch chance", + "showbefore": "no", + "label1": "Spotted kebbit", + "low1": "26", + "high1": "310", + "req1": "43", + "color1": "#5c4a2c", + "image1": "Spotted kebbit icon.png" + } + ] + }, + { + "title": "Stepping Stone (Penguin Agility Course)", + "names": [ + "objects.peng_agility_crushcourse_stepstone01", + "objects.peng_jump_stone_clickzone_02", + "objects.peng_jump_stone_clickzone_03", + "objects.peng_jump_stone_clickzone_04", + "objects.peng_jump_stone_clickzone_05", + "objects.peng_jump_stone_clickzone_06", + "objects.peng_jump_stone_clickzone_07" + ], + "entries": [ + { + "label": "Stepping stone success rate", + "lowlevel": "0", + "showbefore": "no", + "label1": "Climb", + "low1": "155", + "high1": "308", + "req1": "30", + "color1": "#9eafc1", + "image1": "Agility icon.png" + } + ] + }, + { + "title": "Stepping stone (Lumbridge Swamp Caves)", + "names": [ + "objects.swamp_cave_steppingstone_a", + "objects.swamp_cave_steppingstone_b" + ], + "entries": [ + { + "label": "Crossing a stepping stone", + "showbefore": "no", + "xlabel": "Agility level", + "ylabel": "Cross chance", + "label1": "Successful cross chance", + "low1": "51", + "high1": "252", + "req1": "1", + "color1": "seagreen", + "image1": "Agility icon.png" + } + ] + }, + { + "title": "Stepping stone (Wilderness Agility Course)", + "names": [ + "objects.steppingstone1" + ], + "entries": [ + { + "label": "Stepping stone", + "label1": "Cross success rate", + "xlabel": "Agility level", + "low1": "180", + "high1": "250", + "req1": "1", + "color1": "#151111", + "image1": "Agility icon.png" + } + ] + }, + { + "title": "Stew", + "names": [ + "items.stew" + ], + "entries": [ + { + "label": "Stew cooking chance", + "label1": "Fire or Range", + "low1": "68", + "high1": "392", + "req1": "25", + "color1": "gray", + "image1": "Stew.png", + "label2": "Lumbridge range", + "low2": "78", + "high2": "412", + "req2": "25", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "80", + "high3": "404", + "req3": "25", + "color3": "red", + "image3": "Stew.png", + "label4": "Hosidius +10%", + "low4": "93", + "high4": "417", + "req4": "79", + "color4": "blue", + "image4": "Stew.png" + } + ] + }, + { + "title": "Sticks (trap)", + "names": [ + "objects.regicide_trap_woodspring" + ], + "entries": [ + { + "label": "Passing the sticks trap", + "xlabel": "Agility level", + "label1": "Unharmed crossing chance", + "low1": "30", + "high1": "155", + "req1": "1", + "color1": "#87775b", + "image1": "Agility icon.png" + } + ] + }, + { + "title": "Stone chest", + "names": [ + "objects.molch_temple_chest_theiving" + ], + "entries": [ + { + "label": "Stone chest thieving chance", + "showbefore": "no", + "label1": "Normal", + "low1": "-56", + "high1": "154", + "req1": "64", + "color1": "brown", + "image1": "Lizardman fang.png", + "label2": "Lockpick", + "low2": "-31", + "high2": "179", + "req2": "64", + "color2": "grey", + "image2": "Lockpick.png" + } + ] + }, + { + "title": "Strut", + "names": [ + "objects.motherlode_wheel_strut_fixed", + "objects.motherlode_wheel_strut_broken" + ], + "entries": [ + { + "label": "Strut repair chance", + "label1": "Repair", + "low1": "30", + "high1": "70", + "color1": "gray", + "image1": "Hammer.png" + } + ] + }, + { + "title": "Sulliuscep", + "names": [ + "objects.fossil_cep_grown", + "objects.fossil_cep_sprout" + ], + "entries": [ + { + "label": "Sulliuscep cut chance", + "showbefore": "no", + "label1": "Bronze", + "low1": "11", + "high1": "55", + "req1": "65", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "17", + "high2": "85", + "req2": "65", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "23", + "high3": "115", + "req3": "65", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "26", + "high4": "131", + "req4": "65", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "29", + "high5": "147", + "req5": "65", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "35", + "high6": "177", + "req6": "65", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "41", + "high7": "208", + "req7": "65", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "45", + "high8": "228", + "req8": "65", + "color8": "firebrick", + "image8": "Dragon axe.png", + "label9": "Crystal", + "low9": "48", + "high9": "240", + "req9": "71", + "color9": "cyan", + "image9": "Crystal axe.png" + } + ] + }, + { + "title": "Summer pie", + "names": [ + "items.summer_pie", + "items.half_summer_pie" + ], + "entries": [ + { + "label": "Summer pie cooking chance", + "showbefore": "no", + "label1": "Range", + "low1": "1", + "high1": "212", + "req1": "95", + "color1": "saddlebrown", + "image1": "Summer pie.png", + "label2": "Hosidius +5%", + "low2": "13", + "high2": "224", + "req2": "95", + "color2": "red", + "image2": "Summer pie.png", + "label3": "Hosidius +10%", + "low3": "26", + "high3": "237", + "req3": "95", + "color3": "blue", + "image3": "Summer pie.png" + } + ] + }, + { + "title": "Sunlight Moth", + "names": [ + "npcs.moth_sunlight" + ], + "entries": [ + { + "label": "Sunlight moth chance", + "showbefore": "no", + "label1": "Barehanded or butterfly net", + "low1": "20", + "high1": "296", + "req1": "65", + "color1": "saddlebrown", + "image1": "Butterfly net.png", + "label2": "Magic butterfly net", + "low2": "40", + "high2": "316", + "req2": "65", + "color2": "green", + "image2": "Magic butterfly net.png" + } + ] + }, + { + "title": "Swamp lizard (Hunter)", + "names": [ + "npcs.salamander_green" + ], + "entries": [ + { + "label": "Swamp lizard catch chance", + "showbefore": "no", + "label1": "Swamp lizard", + "low1": "52", + "high1": "360", + "req1": "29", + "color1": "#1b441a", + "image1": "Swamp lizard.png" + } + ] + }, + { + "title": "Swordfish", + "names": [ + "items.swordfish" + ], + "entries": [ + { + "label": "Swordfish cooking chance", + "showbefore": "no", + "label1": "Fire", + "low1": "18", + "high1": "292", + "req1": "45", + "color1": "orange", + "image1": "Firemaking icon.png", + "label2": "Range or cooking gauntlets", + "low2": "30", + "high2": "310", + "req2": "45", + "color2": "saddlebrown", + "image2": "Cooking range icon.png", + "label3": "Hosidius +5%", + "low3": "42", + "high3": "322", + "req3": "45", + "color3": "red", + "image3": [], + "label4": "Hosidius +10%", + "low4": "55", + "high4": "335", + "req4": "79", + "color4": "blue", + "image4": "Cooking range icon.png" + } + ] + }, + { + "title": "Tangle vine", + "names": [], + "entries": [ + { + "label": "Tangle vine evasion chance", + "xlabel": "Agility level", + "ylabel": "Evasion chance", + "showbefore": "no", + "label1": "Tangle vine", + "low1": "30", + "high1": "210", + "req1": "1", + "color1": "#506909", + "image1": "Tangle vine icon.png" + } + ] + }, + { + "title": "Tangled toad's legs", + "names": [ + "items.tangled_toads_legs" + ], + "entries": [ + { + "label": "Tangled toad's legs cooking chance", + "label1": "Range", + "low1": "118", + "high1": "492", + "req1": "40", + "color1": "gray", + "image1": "Tangled toad's legs.png", + "label2": "Hosidius +5%", + "low2": "130", + "high2": "504", + "req2": "40", + "color2": "red", + "image2": "Tangled toad's legs.png", + "label3": "Hosidius +10%", + "low3": "143", + "high3": "517", + "req3": "79", + "color3": "blue", + "image3": "Tangled toad's legs.png" + } + ] + }, + { + "title": "Tatie", + "names": [ + "npcs.prif_citizen_tatie" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Teak birdhouse", + "names": [ + "objects.birdhouse_teak_built", + "objects.birdhouse_teak_full", + "objects.birdhouse_teak_bird" + ], + "entries": [ + { + "label": "Seed nest chance", + "xlabel": "Hunter level", + "label1": "Seed nest", + "low1": "0", + "high1": "200", + "req1": "34", + "color1": "grey", + "image1": "Bird nest (seeds).png" + }, + { + "label": "Other nests (10 rolls per birdhouse)", + "xlabel": "Hunter level", + "birdhouse": "yes", + "label1": "Teak", + "high1": "130", + "req1": "34", + "color1": "#ffa500", + "image1": "Teak bird house.png" + } + ] + }, + { + "title": "Teak tree", + "names": [ + "objects.teaktree", + "objects.prif_teaktree", + "objects.teaktree_update" + ], + "entries": [ + { + "label": "Teak tree cut chance", + "xlabel": "Woodcutting level", + "showbefore": "no", + "label1": "Bronze", + "low1": "15", + "high1": "46", + "req1": "35", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "23", + "high2": "70", + "req2": "35", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "31", + "high3": "93", + "req3": "35", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "35", + "high4": "102", + "req4": "35", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "39", + "high5": "117", + "req5": "35", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "47", + "high6": "140", + "req6": "35", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "55", + "high7": "164", + "req7": "41", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "60", + "high8": "190", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png", + "label9": "Crystal", + "low9": "60", + "high9": "200", + "req9": "71", + "color9": "cyan", + "image9": "Crystal axe.png" + } + ] + }, + { + "title": "Tecu salamander (Hunter)", + "names": [ + "npcs.salamander_mountain" + ], + "entries": [ + { + "label": "Tecu salamander chance", + "showbefore": "no", + "label1": "Tecu salamander", + "low1": "1", + "high1": "212", + "req1": "79", + "color1": "#5a9e95", + "image1": "Tecu salamander.png" + } + ] + }, + { + "title": "Teleport trap", + "names": [], + "entries": [ + { + "label": "Teleport trap evasion chance", + "xlabel": "Agility level", + "ylabel": "Evasion chance", + "showbefore": "no", + "label1": "Teleport trap", + "low1": "30", + "high1": "210", + "req1": "1", + "color1": "#c0a816", + "image1": "Teleport trap icon.png" + } + ] + }, + { + "title": "Tendrils (Abyss)", + "names": [ + "objects.rcu_abyssal_barrier_tendrils1", + "objects.rcu_abyssal_barrier_tendrils2", + "objects.rcu_abyssal_barrier_tendrils3" + ], + "entries": [ + { + "label": "Tendrils chopping chance", + "xlabel": "Woodcutting level", + "label1": "Success chance", + "low1": "0", + "high1": "255", + "image1": "Black axe.png", + "color1": "#692208" + } + ] + }, + { + "title": "Thin snail meat", + "names": [ + "items.snail_corpse_cooked1" + ], + "entries": [ + { + "label": "Thin snail meat cooking chance", + "label1": "Fire or Range", + "low1": "93", + "high1": "444", + "req1": "12", + "color1": "gray", + "image1": "Thin snail meat.png", + "label2": "Lumbridge range", + "low2": "103", + "high2": "464", + "req2": "12", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "105", + "high3": "456", + "req3": "12", + "color3": "red", + "image3": "Thin snail meat.png", + "label4": "Hosidius +10%", + "low4": "118", + "high4": "469", + "req4": "79", + "color4": "blue", + "image4": "Thin snail meat.png" + } + ] + }, + { + "title": "Thingol", + "names": [ + "npcs.prif_citizen_thingol" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Ticket Dispenser (darts)", + "names": [ + "objects.agilityarena_poisondarts" + ], + "entries": [ + { + "label": "Dart dodge success rate", + "showbefore": "no", + "label1": "", + "low1": "131", + "high1": "255", + "req1": "40", + "color1": "#f07c15", + "image1": "Agility icon.png" + } + ] + }, + { + "title": "Toad batta", + "names": [ + "items.toad_batta" + ], + "entries": [ + { + "label": "Toad batta cooking chance", + "label1": "Range", + "low1": "118", + "high1": "492", + "req1": "26", + "color1": "gray", + "image1": "Toad batta.png", + "label2": "Hosidius +5%", + "low2": "130", + "high2": "504", + "req2": "26", + "color2": "red", + "image2": "Toad batta.png", + "label3": "Hosidius +10%", + "low3": "143", + "high3": "517", + "req3": "79", + "color3": "blue", + "image3": "Toad batta.png" + } + ] + }, + { + "title": "Toad crunchies", + "names": [ + "items.toad_crunchies" + ], + "entries": [ + { + "label": "Toad crunchies cooking chance", + "label1": "Range", + "low1": "118", + "high1": "492", + "req1": "10", + "color1": "gray", + "image1": "Toad crunchies.png", + "label2": "Hosidius +5%", + "low2": "130", + "high2": "504", + "req2": "10", + "color2": "red", + "image2": "Toad crunchies.png", + "label3": "Hosidius +10%", + "low3": "143", + "high3": "517", + "req3": "79", + "color3": "blue", + "image3": "Toad crunchies.png" + } + ] + }, + { + "title": "Tomb Door", + "names": [ + "objects.ntk_tomb_door_noanim", + "objects.ntk_tomb_door_anim" + ], + "entries": [ + { + "label": "Speartrap success rate", + "showbefore": "no", + "label1": "Normal", + "low1": "130", + "high1": "220", + "req1": "21", + "color1": "gray", + "image1": "Thieving icon.png", + "label2": "Lockpick", + "low2": "160", + "high2": "250", + "req2": "21", + "color2": "dimgray", + "image2": "Lockpick.png" + } + ] + }, + { + "title": "Tourist", + "names": [ + "npcs.varlamore_tourist_m_1", + "npcs.varlamore_tourist_m_2", + "npcs.varlamore_tourist_m_3", + "npcs.varlamore_tourist_f_1", + "npcs.varlamore_tourist_f_2", + "npcs.varlamore_tourist_f_3" + ], + "entries": [ + { + "label": "Tourist pickpocket chance", + "label1": "Normal", + "low1": "180", + "high1": "240", + "req1": "1", + "color1": "gray", + "image1": "Thief Man.png", + "label2": "Gloves of silence", + "low2": "189", + "high2": "252", + "req2": "1", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "198", + "high3": "264", + "req3": "1", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "217", + "high4": "290", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Tree", + "names": [ + "objects.tree", + "objects.tree2" + ], + "entries": [ + { + "label": "Normal tree cut chance", + "xlabel": "Woodcutting level", + "label1": "Bronze", + "low1": "64", + "high1": "200", + "req1": "1", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "96", + "high2": "300", + "req2": "1", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "128", + "high3": "400", + "req3": "6", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "144", + "high4": "450", + "req4": "11", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "160", + "high5": "500", + "req5": "21", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "192", + "high6": "600", + "req6": "31", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "224", + "high7": "700", + "req7": "41", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "240", + "high8": "750", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png", + "label9": "Crystal", + "low9": "250", + "high9": "800", + "req9": "71", + "color9": "cyan", + "image9": "Crystal axe.png" + } + ] + }, + { + "title": "Tree (Great Kourend)", + "names": [ + "objects.tree3" + ], + "entries": [ + { + "label": "Normal tree cut chance", + "xlabel": "Woodcutting level", + "label1": "Bronze", + "low1": "64", + "high1": "200", + "req1": "1", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "96", + "high2": "300", + "req2": "1", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "128", + "high3": "400", + "req3": "6", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "144", + "high4": "450", + "req4": "11", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "160", + "high5": "500", + "req5": "21", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "192", + "high6": "600", + "req6": "31", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "224", + "high7": "700", + "req7": "41", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "240", + "high8": "750", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png" + } + ] + }, + { + "title": "Tree (Shayzien)", + "names": [ + "objects.tree_normal_default01" + ], + "entries": [ + { + "label": "Normal tree cut chance", + "xlabel": "Woodcutting level", + "label1": "Bronze", + "low1": "64", + "high1": "200", + "req1": "1", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "96", + "high2": "300", + "req2": "1", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "128", + "high3": "400", + "req3": "6", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "144", + "high4": "450", + "req4": "11", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "160", + "high5": "500", + "req5": "21", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "192", + "high6": "600", + "req6": "31", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "224", + "high7": "700", + "req7": "41", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "240", + "high8": "750", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png" + } + ] + }, + { + "title": "Tree (The Node)", + "names": [ + "objects.gim_tree" + ], + "entries": [ + { + "label": "Normal tree cut chance", + "xlabel": "Woodcutting level", + "label1": "Bronze", + "low1": "64", + "high1": "200", + "req1": "1", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "96", + "high2": "300", + "req2": "1", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "128", + "high3": "400", + "req3": "6", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "144", + "high4": "450", + "req4": "11", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "160", + "high5": "500", + "req5": "21", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "192", + "high6": "600", + "req6": "31", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "224", + "high7": "700", + "req7": "41", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "240", + "high8": "750", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png" + } + ] + }, + { + "title": "Tripwire", + "names": [ + "objects.regicide_trap_tripwire" + ], + "entries": [ + { + "label": "Tripwire success chance", + "label1": "Success chance", + "low1": "30", + "high1": "155", + "req1": "1", + "color1": "gray", + "image1": "Agility icon.png" + } + ] + }, + { + "title": "Tropical wagtail", + "names": [ + "npcs.multicoloured_bird" + ], + "entries": [ + { + "label": "Tropical wagtail catch chance", + "showbefore": "no", + "label1": "Tropical wagtail", + "low1": "75", + "high1": "370", + "req1": "19", + "color1": "#326432", + "image1": "Tropical wagtail icon.png" + } + ] + }, + { + "title": "Trouble Brewing", + "names": [], + "entries": [ + { + "label": "Torch burn chance", + "xlabel": "Firemaking level", + "showbefore": "no", + "label1": "Successful burn", + "low1": "12", + "high1": "112", + "req1": "1", + "color1": "red", + "image1": "Lit torch.png" + } + ] + }, + { + "title": "Trout", + "names": [ + "items.trout" + ], + "entries": [ + { + "label": "Trout cooking chance", + "label1": "Fire or Range", + "low1": "88", + "high1": "432", + "req1": "15", + "color1": "gray", + "image1": "Trout.png", + "label2": "Lumbridge range", + "low2": "98", + "high2": "452", + "req2": "15", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "100", + "high3": "444", + "req3": "15", + "color3": "red", + "image3": "Trout.png", + "label4": "Hosidius +10%", + "low4": "113", + "high4": "457", + "req4": "79", + "color4": "blue", + "image4": "Trout.png" + } + ] + }, + { + "title": "Tuna", + "names": [ + "items.tuna" + ], + "entries": [ + { + "label": "Tuna cooking chance", + "label1": "Fire or Range", + "low1": "58", + "high1": "372", + "req1": "30", + "color1": "gray", + "image1": "Tuna.png", + "label2": "Hosidius +5%", + "low2": "70", + "high2": "384", + "req2": "30", + "color2": "red", + "image2": "Tuna.png", + "label3": "Hosidius +10%", + "low3": "83", + "high3": "397", + "req3": "79", + "color3": "blue", + "image3": "Tuna.png" + } + ] + }, + { + "title": "Turgon", + "names": [ + "npcs.prif_citizen_turgon" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "TzHaar-Hur", + "names": [ + "npcs.tzhaar_hur1", + "npcs.tzhaar_hur2", + "npcs.tzhaar_hur3", + "npcs.tzhaar_hur4", + "npcs.tzhaar_hur5", + "npcs.tzhaar_hur6", + "npcs.tzhaar_hur_city1", + "npcs.tzhaar_hur_city2", + "npcs.tzhaar_hur_city3", + "npcs.tzhaar_hur_city4", + "npcs.tzhaar_hur_city5", + "npcs.tzhaar_hur_city6" + ], + "entries": [ + { + "label": "TzHaar-Hur pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "-200", + "high1": "200", + "req1": "90", + "color1": "gray", + "image1": "Thieving icon.png", + "label2": "Gloves of silence", + "low2": "-210", + "high2": "210", + "req2": "90", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "-220", + "high3": "220", + "req3": "90", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "-242", + "high4": "242", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Ugthanki meat", + "names": [ + "items.cooked_ugthanki_meat" + ], + "entries": [ + { + "label": "Ugthanki meat cooking chance", + "label1": "Fire", + "low1": "40", + "high1": "252", + "req1": "1", + "color1": "orange", + "image1": "Firemaking icon.png", + "label2": "Range", + "low2": "30", + "high2": "253", + "req2": "1", + "color2": "saddlebrown", + "image2": "Cooking range icon.png", + "label3": "Hosidius +5%", + "low3": "42", + "high3": "265", + "req3": "1", + "color3": "red", + "image3": "Cooking range icon.png", + "label4": "Hosidius +10%", + "low4": "55", + "high4": "278", + "req4": "79", + "color4": "blue", + "image4": "Cooking range icon.png" + } + ] + }, + { + "title": "Uncut jade", + "names": [ + "items.uncut_jade" + ], + "entries": [ + { + "label": "Gem cutting rates", + "label1": "Opal", + "low1": "128", + "high1": "250", + "req1": "1", + "color1": "gray", + "image1": "Opal.png", + "label2": "Jade", + "low2": "100", + "high2": "245", + "req2": "13", + "color2": "green", + "image2": "Jade.png", + "label3": "Red topaz", + "low3": "90", + "high3": "240", + "req3": "16", + "color3": "pink", + "image3": "Red topaz.png" + } + ] + }, + { + "title": "Uncut opal", + "names": [ + "items.uncut_opal" + ], + "entries": [ + { + "label": "Gem cutting rates", + "label1": "Opal", + "low1": "128", + "high1": "250", + "req1": "1", + "color1": "gray", + "image1": "Opal.png", + "label2": "Jade", + "low2": "100", + "high2": "245", + "req2": "13", + "color2": "green", + "image2": "Jade.png", + "label3": "Red topaz", + "low3": "90", + "high3": "240", + "req3": "16", + "color3": "pink", + "image3": "Red topaz.png" + } + ] + }, + { + "title": "Uncut red topaz", + "names": [ + "items.uncut_red_topaz" + ], + "entries": [ + { + "label": "Gem cutting rates", + "label1": "Opal", + "low1": "128", + "high1": "250", + "req1": "1", + "color1": "gray", + "image1": "Opal.png", + "label2": "Jade", + "low2": "100", + "high2": "245", + "req2": "13", + "color2": "green", + "image2": "Jade.png", + "label3": "Red topaz", + "low3": "90", + "high3": "240", + "req3": "16", + "color3": "pink", + "image3": "Red topaz.png" + } + ] + }, + { + "title": "Underwater Agility and Thieving", + "names": [], + "entries": [ + { + "label": "Successful search chance", + "lowLevel": "1", + "label1": "Glistening and mermaid's tears", + "low1": "30", + "high1": "40", + "req1": "1", + "color1": "blue", + "image1": "Glistening tear 5.png" + } + ] + }, + { + "title": "Urn (Pyramid Plunder)", + "names": [ + "objects.ntk_urn1_closed", + "objects.ntk_urn2_closed", + "objects.ntk_urn3_closed", + "objects.ntk_urn1_snake", + "objects.ntk_urn2_snake", + "objects.ntk_urn3_snake", + "objects.ntk_urn1_snake_charmed", + "objects.ntk_urn2_snake_charmed", + "objects.ntk_urn3_snake_charmed", + "objects.ntk_urn1_open", + "objects.ntk_urn2_open", + "objects.ntk_urn3_open" + ], + "entries": [ + { + "label": "Search urn success rate", + "showbefore": "no", + "label1": "Search", + "low1": "100", + "high1": "180", + "req1": "21", + "label2": "Searching with uncharmed snake", + "low2": "130", + "high2": "220", + "req2": "21", + "label3": "Check for snakes", + "low3": "160", + "high3": "250", + "req3": "21" + } + ] + }, + { + "title": "Vaire", + "names": [ + "npcs.prif_citizen_vaire" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Veg ball", + "names": [ + "items.veg_ball" + ], + "entries": [ + { + "label": "Veg ball cooking chance", + "label1": "Range", + "low1": "118", + "high1": "492", + "req1": "35", + "color1": "gray", + "image1": "Veg ball.png", + "label2": "Hosidius +5%", + "low2": "130", + "high2": "504", + "req2": "35", + "color2": "red", + "image2": "Veg ball.png", + "label3": "Hosidius +10%", + "low3": "143", + "high3": "517", + "req3": "79", + "color3": "blue", + "image3": "Veg ball.png" + } + ] + }, + { + "title": "Vegetable batta", + "names": [ + "items.vegetable_batta" + ], + "entries": [ + { + "label": "Vegetable batta cooking chance", + "label1": "Range", + "low1": "118", + "high1": "492", + "req1": "28", + "color1": "gray", + "image1": "Vegetable batta.png", + "label2": "Hosidius +5%", + "low2": "130", + "high2": "504", + "req2": "28", + "color2": "red", + "image2": "Vegetable batta.png", + "label3": "Hosidius +10%", + "low3": "143", + "high3": "517", + "req3": "79", + "color3": "blue", + "image3": "Vegetable batta.png" + } + ] + }, + { + "title": "Volcanic Mine", + "names": [], + "entries": [ + { + "label": "Volcanic Mine ore fragments", + "xlabel": "Mining level", + "cascade": "yes", + "showbefore": "no", + "label1": "Runite ore fragment", + "low1": "-10", + "high1": "80", + "req1": "85", + "color1": "steelblue", + "image1": "Runite ore fragment.png", + "label2": "Adamantite ore fragment", + "low2": "-90", + "high2": "90", + "req2": "70", + "color2": "seagreen", + "image2": "Adamantite ore fragment.png", + "label3": "Mithril ore fragment", + "low3": "-75", + "high3": "150", + "req3": "55", + "color3": "slateblue", + "image3": "Mithril ore fragment.png", + "label4": "Gold ore fragment", + "low4": "-40", + "high4": "160", + "req4": "50", + "color4": "goldenrod", + "image4": "Gold ore fragment.png", + "label5": "Coal fragment", + "low5": "-20", + "high5": "170", + "req5": "50", + "color5": "black", + "image5": "Coal fragment.png", + "label6": "Silver ore fragment", + "low6": "0", + "high6": "185", + "req6": "50", + "color6": "silver", + "image6": "Silver ore fragment.png", + "label7": "Iron ore fragment", + "low7": "0", + "high7": "510", + "req7": "50", + "color7": "maroon", + "image7": [] + } + ] + }, + { + "title": "Volcanic sulphur", + "names": [ + "items.lovakengj_sulphur" + ], + "entries": [ + { + "label": "Volcanic sulphur mining chance", + "showbefore": "yes", + "label1": "Volcanic sulphur", + "low1": "100", + "high1": "220", + "req1": "42", + "color1": "red", + "image1": "Volcanic sulphur.png" + } + ] + }, + { + "title": "Vyre", + "names": [], + "entries": [ + { + "label": "Vyre pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "8", + "high1": "128", + "req1": "82", + "color1": "gray", + "image1": "Vyre icon.png", + "label2": "Gloves of silence", + "low2": "8", + "high2": "134", + "req2": "82", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "8", + "high3": "140", + "req3": "82", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "8", + "high4": "154", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Vyrewatch", + "names": [ + "npcs.myq4_vyrewatch_1_crowd", + "npcs.myq4_vyrewatch_2_crowd", + "npcs.myq4_vyrewatch_3_crowd", + "npcs.myq4_vyrewatch_4_crowd", + "npcs.myq4_vyrewatch_1", + "npcs.myq4_vyrewatch_2", + "npcs.myq4_vyrewatch_3", + "npcs.myq4_vyrewatch_4", + "npcs.sang_myq3_female_walk_vyrewatch_1", + "npcs.myreque_pt3_takeoff_vyrewatch_female_1", + "npcs.sang_myq3_female_flying_vyrewatch_1", + "npcs.sang_myq3_male_walk_vyrewatch_1", + "npcs.myreque_pt3_takeoff_vyrewatch_male_1", + "npcs.sang_myq3_male_flying_vyrewatch_1", + "npcs.sang_myq3_female_flying_ns_vyrewatch_1", + "npcs.sang_myq3_male_flying_ns_vyrewatch_1", + "npcs.sang_myq3_female_walk_ns_vyrewatch_1", + "npcs.sang_myq3_male_walk_ns_vyrewatch_1", + "npcs.slepe_vyrewatch_female_1", + "npcs.slepe_vyrewatch_female_2", + "npcs.slepe_vyrewatch_female_3", + "npcs.slepe_vyrewatch_female_4", + "npcs.slepe_vyrewatch_male_1", + "npcs.slepe_vyrewatch_male_2", + "npcs.slepe_vyrewatch_male_3", + "npcs.slepe_vyrewatch_male_4", + "npcs.darkm_vyrewatch_male_2", + "npcs.darkm_vyrewatch_female_4", + "npcs.darkm_vyrewatch_female_2", + "npcs.darkm_vyrewatch_female_3", + "npcs.darkm_vyrewatch_male_4", + "npcs.darkm_vyrewatch_male_1", + "npcs.darkm_vyrewatch_male_3", + "npcs.darkm_vyrewatch_female_1", + "npcs.sang_myq3_female_walk_vyrewatch_2", + "npcs.myreque_pt3_takeoff_vyrewatch_female_2", + "npcs.sang_myq3_female_flying_vyrewatch_2", + "npcs.sang_myq3_male_walk_vyrewatch_2", + "npcs.myreque_pt3_takeoff_vyrewatch_male_2", + "npcs.sang_myq3_male_flying_vyrewatch_2", + "npcs.sang_myq3_female_flying_ns_vyrewatch_2", + "npcs.sang_myq3_male_flying_ns_vyrewatch_2", + "npcs.sang_myq3_female_walk_ns_vyrewatch_2", + "npcs.sang_myq3_male_walk_ns_vyrewatch_2", + "npcs.sang_myq3_female_walk_vyrewatch_3", + "npcs.myreque_pt3_takeoff_vyrewatch_female_3", + "npcs.sang_myq3_female_flying_vyrewatch_3", + "npcs.sang_myq3_male_walk_vyrewatch_3", + "npcs.myreque_pt3_takeoff_vyrewatch_male_3", + "npcs.sang_myq3_male_flying_vyrewatch_3", + "npcs.sang_myq3_female_flying_ns_vyrewatch_3", + "npcs.sang_myq3_male_flying_ns_vyrewatch_3", + "npcs.sang_myq3_female_walk_ns_vyrewatch_3", + "npcs.sang_myq3_male_walk_ns_vyrewatch_3", + "npcs.sang_myq3_female_walk_vyrewatch_4", + "npcs.myreque_pt3_takeoff_vyrewatch_female_4", + "npcs.sang_myq3_female_flying_vyrewatch_4", + "npcs.sang_myq3_male_walk_vyrewatch_4", + "npcs.myreque_pt3_takeoff_vyrewatch_male_4", + "npcs.sang_myq3_male_flying_vyrewatch_4", + "npcs.sang_myq3_female_flying_ns_vyrewatch_4", + "npcs.sang_myq3_male_flying_ns_vyrewatch_4", + "npcs.sang_myq3_female_walk_ns_vyrewatch_4", + "npcs.sang_myq3_male_walk_ns_vyrewatch_4" + ], + "entries": [ + { + "label": "Vyrewatch distraction chance", + "xlabel": "Thieving level", + "label1": "Distract", + "low1": "0", + "high1": "252", + "image1": "Thieving icon.png", + "color1": "#330332" + } + ] + }, + { + "title": "Wall safe", + "names": [ + "objects.roguesden_walldecor_mazesafe", + "objects.roguesden_walldecor_safe_open" + ], + "entries": [ + { + "label": "Thieving chance", + "showbefore": "no", + "": "", + "label1": "Rogue's equipment crate", + "low1": "80", + "high1": "119", + "color1": "black", + "image1": "Rogue's_equipment_crate.png" + } + ] + }, + { + "title": "Wall safe (lobby)", + "names": [ + "objects.roguesden_walldecor_safe" + ], + "entries": [ + { + "label": "Wall safe thieving chance", + "showbefore": "no", + "label1": "Normal", + "low1": "8", + "high1": "160", + "req1": "50", + "color1": "black", + "image1": "Thieving icon.png", + "label2": "Stethoscope", + "low2": "16", + "high2": "192", + "req2": "50", + "color2": "gray", + "image2": "Stethoscope.png" + } + ] + }, + { + "title": "Wall support (Temple of Light)", + "names": [ + "objects.mourning_temple_agility_hanging" + ], + "entries": [ + { + "label": "Wall support climb success rate", + "lowlevel": "0", + "showbefore": "no", + "label1": "Each jump", + "low1": "64", + "high1": "272", + "req1": "1", + "color1": "#9b8f58", + "image1": "Agility icon.png", + "label2": "Overall success", + "low2": "64", + "high2": "272", + "req2": "1", + "color2": "#aa4c58", + "image2": "Agility icon.png", + "exponent2": "8" + } + ] + }, + { + "title": "Warrior (Thieving)", + "names": [ + "npcs.warrior_woman", + "npcs.warrior_woman_variant01", + "npcs.warrior_woman_variant02", + "npcs.warrior_man", + "npcs.warrior_man_variant01", + "npcs.warrior_man_variant02" + ], + "entries": [ + { + "label": "Warrior pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "100", + "high1": "240", + "req1": "25", + "color1": "gray", + "image1": "Thieving icon.png", + "label2": "Gloves of silence", + "low2": "105", + "high2": "252", + "req2": "40", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "110", + "high3": "264", + "req3": "67", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "121", + "high4": "290", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Watchman", + "names": [ + "npcs.yanille_watchman" + ], + "entries": [ + { + "label": "Watchman pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "15", + "high1": "160", + "req1": "65", + "color1": "gray", + "image1": "Thief Watchman.png", + "label2": "Gloves of silence", + "low2": "15", + "high2": "168", + "req2": "65", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "16", + "high3": "176", + "req3": "67", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "17", + "high4": "193", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Water rune (The Slug Menace)", + "names": [ + "items.slug2_rune_water" + ], + "entries": [ + { + "label": "Channeling blank rune success chance", + "xlabel": "Runecraft level", + "showbefore": "no", + "label1": "Water rune", + "low1": "110", + "high1": "253", + "req1": "30", + "color1": "#11158b", + "image1": "Water rune (The Slug Menace).png" + } + ] + }, + { + "title": "Wealthy citizen", + "names": [ + "npcs.varlamore_wealthy_citizen_a", + "npcs.varlamore_wealthy_citizen_b", + "npcs.varlamore_wealthy_citizen_c", + "npcs.varlamore_wealthy_citizen_d" + ], + "entries": [ + { + "label": "Wealthy citizen pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "35", + "high1": "200", + "req1": "50", + "color1": "gray", + "image1": "Thief Wealthy citizen.png", + "label2": "Gloves of silence", + "low2": "36", + "high2": "210", + "req2": "50", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "38", + "high3": "220", + "req3": "50", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "41", + "high4": "242", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "White rabbit", + "names": [], + "entries": [ + { + "label": "Ferret preservation chance", + "xlabel": "Hunter level", + "showbefore": "no", + "label1": "Flushing a rabbit hole", + "low1": "190", + "high1": "255", + "req1": "27", + "color1": "#645750", + "image1": "Ferret.png" + } + ] + }, + { + "title": "Wild pie", + "names": [ + "items.wild_pie", + "items.half_wild_pie" + ], + "entries": [ + { + "label": "Wild pie cooking chance", + "showbefore": "no", + "label1": "Range", + "low1": "1", + "high1": "222", + "req1": "85", + "color1": "saddlebrown", + "image1": "Wild pie.png", + "label2": "Hosidius +5%", + "low2": "13", + "high2": "234", + "req2": "85", + "color2": "red", + "image2": "Wild pie.png", + "label3": "Hosidius +10%", + "low3": "26", + "high3": "247", + "req3": "85", + "color3": "blue", + "image3": "Wild pie.png" + } + ] + }, + { + "title": "Willow birdhouse", + "names": [ + "objects.birdhouse_willow_built", + "objects.birdhouse_willow_full", + "objects.birdhouse_willow_bird" + ], + "entries": [ + { + "label": "Seed nest chance", + "xlabel": "Hunter level", + "label1": "Seed nest", + "low1": "0", + "high1": "200", + "req1": "24", + "color1": "grey", + "image1": "Bird nest (seeds).png" + }, + { + "label": "Other nests (10 rolls per birdhouse)", + "xlabel": "Hunter level", + "birdhouse": "yes", + "label1": "Willow", + "high1": "128", + "req1": "24", + "color1": "#006400", + "image1": "Willow bird house.png" + } + ] + }, + { + "title": "Willow tree", + "names": [ + "objects.willowtree", + "objects.willow_tree2", + "objects.willow_tree3", + "objects.willow_tree4" + ], + "entries": [ + { + "label": "Willow tree cut chance", + "xlabel": "Woodcutting level", + "showbefore": "no", + "label1": "Bronze", + "low1": "16", + "high1": "50", + "req1": "30", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "24", + "high2": "75", + "req2": "30", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "32", + "high3": "100", + "req3": "30", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "36", + "high4": "112", + "req4": "30", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "40", + "high5": "125", + "req5": "30", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "48", + "high6": "150", + "req6": "31", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "56", + "high7": "175", + "req7": "41", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "60", + "high8": "187", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png" + } + ] + }, + { + "title": "Wine of zamorak", + "names": [ + "items.wine_of_zamorak" + ], + "entries": [ + { + "label": "Wine of Zamorak Success chance", + "showbefore": "no", + "label1": "Wine of Zamorak", + "low1": "-125", + "high1": "260", + "req1": "65", + "color1": "#652723", + "image1": "Wine of zamorak detail.png" + } + ] + }, + { + "title": "Wire machine", + "names": [ + "objects.dorgesh_wire_machine_chimney", + "objects.dorgesh_wire_machine", + "objects.dorgesh_wire_machine_spool", + "objects.dorgesh_wire_machine_cogs", + "objects.dorgesh_wire_machine_smoke" + ], + "entries": [ + { + "label": "Thieving chance", + "showbefore": "no", + "": "", + "label1": "Cave goblin wire", + "low1": "50", + "high1": "250", + "req1": "44", + "color1": "brown", + "image1": "Cave_goblin_wire.png" + } + ] + }, + { + "title": "Woman", + "names": [ + "npcs.woman", + "npcs.zeah_woman", + "npcs.zeah_woman_outside", + "npcs.woman2", + "npcs.zeah_woman2", + "npcs.woman3", + "npcs.zeah_woman3", + "npcs.varrock_woman1", + "npcs.shayzien_woman_1", + "npcs.shayzien_woman_2" + ], + "entries": [ + { + "label": "Woman pickpocket chance", + "label1": "Normal", + "low1": "180", + "high1": "240", + "req1": "1", + "color1": "gray", + "image1": "Thieving icon.png", + "label2": "Gloves of silence", + "low2": "189", + "high2": "252", + "req2": "1", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "198", + "high3": "264", + "req3": "1", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "217", + "high4": "290", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Woman (East Ardougne)", + "names": [ + "npcs.ardougnian_female1" + ], + "entries": [ + { + "label": "Woman pickpocket chance", + "label1": "Normal", + "low1": "180", + "high1": "240", + "req1": "1", + "color1": "gray", + "image1": "Thieving icon.png", + "label2": "Gloves of silence", + "low2": "189", + "high2": "252", + "req2": "1", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "198", + "high3": "264", + "req3": "1", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "217", + "high4": "290", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Worm batta", + "names": [ + "items.worm_batta" + ], + "entries": [ + { + "label": "Worm batta cooking chance", + "label1": "Range", + "low1": "118", + "high1": "492", + "req1": "27", + "color1": "gray", + "image1": "Worm batta.png", + "label2": "Hosidius +5%", + "low2": "130", + "high2": "504", + "req2": "27", + "color2": "red", + "image2": "Worm batta.png", + "label3": "Hosidius +10%", + "low3": "143", + "high3": "517", + "req3": "79", + "color3": "blue", + "image3": "Worm batta.png" + } + ] + }, + { + "title": "Worm crunchies", + "names": [ + "items.worm_crunchies" + ], + "entries": [ + { + "label": "Worm crunchies cooking chance", + "label1": "Range", + "low1": "118", + "high1": "492", + "req1": "14", + "color1": "gray", + "image1": "Worm crunchies.png", + "label2": "Hosidius +5%", + "low2": "130", + "high2": "504", + "req2": "14", + "color2": "red", + "image2": "Worm crunchies.png", + "label3": "Hosidius +10%", + "low3": "143", + "high3": "517", + "req3": "79", + "color3": "blue", + "image3": "Worm crunchies.png" + } + ] + }, + { + "title": "Worm hole", + "names": [ + "items.worm_hole" + ], + "entries": [ + { + "label": "Worm hole cooking chance", + "label1": "Range", + "low1": "118", + "high1": "492", + "req1": "30", + "color1": "gray", + "image1": "Worm hole.png", + "label2": "Hosidius +5%", + "low2": "130", + "high2": "504", + "req2": "30", + "color2": "red", + "image2": "Worm hole.png", + "label3": "Hosidius +10%", + "low3": "143", + "high3": "517", + "req3": "79", + "color3": "blue", + "image3": "Worm hole.png" + } + ] + }, + { + "title": "Yew birdhouse", + "names": [ + "objects.birdhouse_yew_built", + "objects.birdhouse_yew_full", + "objects.birdhouse_yew_bird" + ], + "entries": [ + { + "label": "Seed nest chance", + "xlabel": "Hunter level", + "label1": "Seed nest", + "low1": "0", + "high1": "200", + "req1": "59", + "color1": "grey", + "image1": "Bird nest (seeds).png" + }, + { + "label": "Other nests (10 rolls per birdhouse)", + "xlabel": "Hunter level", + "birdhouse": "yes", + "label1": "Yew", + "high1": "160", + "req1": "59", + "color1": "#1e90ff", + "image1": "Yew bird house.png" + } + ] + }, + { + "title": "Yew tree", + "names": [ + "objects.yewtree", + "objects.prif_yewtree", + "objects.yewtree_update", + "objects.tree_yew_default01" + ], + "entries": [ + { + "label": "Yew tree cut chance", + "showbefore": "no", + "label1": "Bronze", + "low1": "4", + "high1": "12", + "req1": "60", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "6", + "high2": "19", + "req2": "60", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "8", + "high3": "25", + "req3": "60", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "9", + "high4": "28", + "req4": "60", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "10", + "high5": "31", + "req5": "60", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "12", + "high6": "37", + "req6": "60", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "14", + "high7": "44", + "req7": "60", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "15", + "high8": "47", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png" + } + ] + }, + { + "title": "Yommi tree seeds", + "names": [ + "items.yommiseeds", + "items.yommiseeds_germ" + ], + "entries": [ + { + "label": "Yommi tree growth chance", + "showbefore": "no", + "xlabel": "Herblore level", + "label1": "Yommi tree", + "low1": "40", + "high1": "243", + "req1": "45", + "color1": "green", + "image1": "Yommi tree seeds (germinated).png" + } + ] + }, + { + "title": "Young impling", + "names": [ + "npcs.ii_impling_type_2", + "npcs.ii_impling_type_2_maze" + ], + "entries": [ + { + "label": "Young impling catch chance", + "showbefore": "no", + "label1": "Butterfly net", + "low1": "69", + "high1": "351", + "req1": "22", + "color1": "saddlebrown", + "image1": "Butterfly net.png", + "label2": "Barehanded or magic butterfly net", + "low2": "89", + "high2": "371", + "req2": "22", + "color2": "green", + "image2": "Magic butterfly net.png" + } + ] + }, + { + "title": "Dragon impling", + "names": [ + "npcs.ii_impling_type_10", + "npcs.ii_impling_type_10_maze" + ], + "entries": [ + { + "label": "Dragon impling catch chance", + "showbefore": "no", + "label1": "Butterfly net", + "low1": "5", + "high1": "125", + "req1": "83", + "color1": "saddlebrown", + "image1": "Butterfly net.png", + "label2": "Barehanded or magic butterfly net", + "low2": "25", + "high2": "145", + "req2": "83", + "color2": "green", + "image2": "Magic butterfly net.png" + } + ] + }, + { + "title": "Eclectic impling", + "names": [ + "npcs.ii_impling_type_6", + "npcs.ii_impling_type_6_maze" + ], + "entries": [ + { + "label": "Eclectic impling catch chance", + "showbefore": "no", + "label1": "Butterfly net", + "low1": "30", + "high1": "250", + "req1": "50", + "color1": "saddlebrown", + "image1": "Butterfly net.png", + "label2": "Barehanded or magic butterfly net", + "low2": "50", + "high2": "270", + "req2": "50", + "color2": "green", + "image2": "Magic butterfly net.png" + } + ] + }, + { + "title": "Black chinchompa (Hunter)", + "names": [ + "npcs.hunting_chinchompa_black" + ], + "entries": [ + { + "label": "Chinchompa catch chance", + "lowLevel": "53", + "label1": "Grey", + "low1": "6", + "high1": "268", + "req1": "53", + "color1": "gray", + "image1": "Chinchompa.png", + "label2": "Red", + "low2": "-78", + "high2": "228", + "req2": "63", + "color2": "red", + "image2": "Red chinchompa.png", + "label3": "Black", + "low3": "-78", + "high3": "228", + "req3": "73", + "color3": "black", + "image3": "Black chinchompa.png" + } + ] + }, + { + "title": "Baby impling", + "names": [ + "npcs.ii_impling_type_1", + "npcs.ii_impling_type_1_maze" + ], + "entries": [ + { + "label": "Baby impling catch chance", + "showbefore": "no", + "label1": "Butterfly net", + "low1": "79", + "high1": "402", + "req1": "17", + "color1": "saddlebrown", + "image1": "Butterfly net.png", + "label2": "Barehanded or magic butterfly net", + "low2": "99", + "high2": "422", + "req2": "17", + "color2": "green", + "image2": "Magic butterfly net.png" + } + ] + }, + { + "title": "Crystal impling", + "names": [ + "npcs.ii_impling_type_12_johnny", + "npcs.ii_impling_type_12_junior", + "npcs.ii_impling_type_12_andy", + "npcs.ii_impling_type_12_joey", + "npcs.ii_impling_type_12_trouble", + "npcs.ii_impling_type_12_hingy", + "npcs.ii_impling_type_12_zolty", + "npcs.ii_impling_type_12_neil", + "npcs.ii_impling_type_12_yanny", + "npcs.ii_impling_type_12_matty", + "npcs.ii_impling_type_12_stace", + "npcs.ii_impling_type_12_ian", + "npcs.ii_impling_type_12_jamie", + "npcs.ii_impling_type_12_damo", + "npcs.ii_impling_type_12_xander", + "npcs.ii_impling_type_12_steveo", + "npcs.ii_impling_type_12_stewie" + ], + "entries": [ + { + "label": "Crystal impling catch chance", + "showbefore": "no", + "label1": "Butterfly net", + "low1": "8", + "high1": "141", + "req1": "80", + "color1": "saddlebrown", + "image1": "Butterfly net.png", + "label2": "Barehanded or magic butterfly net", + "low2": "28", + "high2": "161", + "req2": "80", + "color2": "green", + "image2": "Magic butterfly net.png" + } + ] + }, + { + "title": "Earth impling", + "names": [ + "npcs.ii_impling_type_4", + "npcs.ii_impling_type_4_maze" + ], + "entries": [ + { + "label": "Earth impling catch chance", + "showbefore": "no", + "label1": "Butterfly net", + "low1": "51", + "high1": "302", + "req1": "36", + "color1": "saddlebrown", + "image1": "Butterfly net.png", + "label2": "Barehanded or magic butterfly net", + "low2": "71", + "high2": "322", + "req2": "36", + "color2": "green", + "image2": "Magic butterfly net.png" + } + ] + }, + { + "title": "Essence impling", + "names": [ + "npcs.ii_impling_type_5", + "npcs.ii_impling_type_5_maze" + ], + "entries": [ + { + "label": "Essence impling catch chance", + "showbefore": "no", + "label1": "Butterfly net", + "low1": "40", + "high1": "275", + "req1": "42", + "color1": "saddlebrown", + "image1": "Butterfly net.png", + "label2": "Barehanded or magic butterfly net", + "low2": "60", + "high2": "295", + "req2": "42", + "color2": "green", + "image2": "Magic butterfly net.png" + } + ] + }, + { + "title": "Al Kharid warrior", + "names": [ + "npcs.al_kharid_warrior" + ], + "entries": [ + { + "label": "Al Kharid warrior pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "100", + "high1": "240", + "req1": "25", + "color1": "gray", + "image1": "Thieving icon.png", + "label2": "Gloves of silence", + "low2": "105", + "high2": "252", + "req2": "40", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "110", + "high3": "264", + "req3": "67", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "121", + "high4": "290", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Bandit (Bandit Camp)", + "names": [ + "npcs.fourdiamonds_sword_bandit_free", + "npcs.fourdiamonds_sword_bandit_1" + ], + "entries": [ + { + "label": "Bandit pickpocket chance", + "label1": "Normal", + "low1": "50", + "high1": "240", + "req1": "53", + "color1": "gray", + "image1": "Thief Desert bandit.png", + "label2": "Gloves of silence", + "low2": "52", + "high2": "252", + "req2": "53", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "55", + "high3": "264", + "req3": "53", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "60", + "high4": "290", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Carnivorous chinchompa", + "names": [ + "npcs.hunting_chinchompa_big" + ], + "entries": [ + { + "label": "Chinchompa catch chance", + "lowLevel": "53", + "label1": "Grey", + "low1": "6", + "high1": "268", + "req1": "53", + "color1": "gray", + "image1": "Chinchompa.png", + "label2": "Red", + "low2": "-78", + "high2": "228", + "req2": "63", + "color2": "red", + "image2": "Red chinchompa.png", + "label3": "Black", + "low3": "-78", + "high3": "228", + "req3": "73", + "color3": "black", + "image3": "Black chinchompa.png" + } + ] + }, + { + "title": "Farmer", + "names": [ + "npcs.farmer1", + "npcs.farmer2", + "npcs.farmer3", + "npcs.farmer1_f", + "npcs.farmer2_f", + "npcs.farmer3_f", + "npcs.farmer4" + ], + "entries": [ + { + "label": "Farmer pickpocket chance", + "showbefore": "yes", + "label1": "Normal", + "low1": "150", + "high1": "240", + "req1": "7", + "color1": "gray", + "image1": "Thieving icon.png", + "label2": "Gloves of silence", + "low2": "157", + "high2": "252", + "req2": "7", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "165", + "high3": "264", + "req3": "38", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "181", + "high4": "290", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Chinchompa (Hunter)", + "names": [ + "npcs.hunting_chinchompa" + ], + "entries": [ + { + "label": "Chinchompa catch chance", + "lowLevel": "53", + "label1": "Grey", + "low1": "6", + "high1": "268", + "req1": "53", + "color1": "gray", + "image1": "Chinchompa.png", + "label2": "Red", + "low2": "-78", + "high2": "228", + "req2": "63", + "color2": "red", + "image2": "Red chinchompa.png", + "label3": "Black", + "low3": "-78", + "high3": "228", + "req3": "73", + "color3": "black", + "image3": "Black chinchompa.png" + } + ] + }, + { + "title": "Underwater Agility and Thieving", + "names": [], + "entries": [ + { + "label": "Successful search chance", + "lowLevel": "1", + "label1": "Glistening and mermaid's tears", + "low1": "30", + "high1": "40", + "req1": "1", + "color1": "blue", + "image1": "Glistening tear 5.png" + } + ] + }, + { + "title": "Bird house trapping", + "names": [], + "entries": [ + { + "label": "Seed nest chance", + "xlabel": "Hunter level", + "label1": "Seed nest", + "low1": "0", + "high1": "200", + "req1": "5", + "color1": "grey", + "image1": "Bird nest (seeds).png" + }, + { + "label": "Other nests (10 rolls per birdhouse)", + "xlabel": "Hunter level", + "birdhouse": "yes", + "label1": "Regular", + "high1": "100", + "req1": "5", + "color1": "#4b0082", + "image1": "Bird house.png", + "label2": "Oak", + "high2": "125", + "req2": "14", + "color2": "#ff0000", + "image2": "Oak bird house.png", + "label3": "Willow", + "high3": "128", + "req3": "24", + "color3": "#006400", + "image3": "Willow bird house.png", + "label4": "Teak", + "high4": "130", + "req4": "34", + "color4": "#ffa500", + "image4": "Teak bird house.png", + "label5": "Maple", + "high5": "140", + "req5": "44", + "color5": "#00ff00", + "image5": "Maple bird house.png", + "label6": "Mahogany", + "high6": "150", + "req6": "49", + "color6": "#ffff00", + "image6": "Mahogany bird house.png", + "label7": "Yew", + "high7": "160", + "req7": "59", + "color7": "#1e90ff", + "image7": "Yew bird house.png", + "label8": "Magic", + "high8": "170", + "req8": "74", + "color8": "#708090", + "image8": "Magic bird house.png", + "label9": "Redwood", + "high9": "175", + "req9": "89", + "color9": "#ff00ff", + "image9": "Redwood bird house.png" + } + ] + }, + { + "title": "Shooting Stars", + "names": [], + "entries": [ + { + "color1": "goldenrod", + "high1": "117", + "image1": "Stardust_175.png", + "label": "Stardust mining chance", + "label1": "Stardust", + "low1": "73", + "req1": "10", + "showbefore": "no" + } + ] + }, + { + "title": "Admiral pie", + "names": [ + "items.admiral_pie", + "items.half_admiral_pie" + ], + "entries": [ + { + "label": "Admiral pie cooking chance", + "xlabel": "Cooking level", + "showbefore": "no", + "label1": "Range", + "low1": "15", + "high1": "270", + "req1": "70", + "color1": "saddlebrown", + "image1": "Admiral pie.png", + "label2": "Hosidius +5%", + "low2": "27", + "high2": "282", + "req2": "70", + "color2": "red", + "image2": "Admiral pie.png", + "label3": "Hosidius +10%", + "low3": "40", + "high3": "295", + "req3": "79", + "color3": "blue", + "image3": "Admiral pie.png" + } + ] + }, + { + "title": "Raw salmon", + "names": [ + "items.raw_salmon" + ], + "entries": [ + { + "label": "Trout + salmon fishing chance", + "cascade": "yes", + "showbefore": "no", + "label1": "Raw salmon", + "low1": "16", + "high1": "96", + "req1": "30", + "color1": "#c77f72", + "image1": "Raw salmon.png", + "label2": "Raw trout", + "low2": "32", + "high2": "192", + "req2": "20", + "color2": "#9a908f", + "image2": "Raw trout.png" + } + ] + }, + { + "title": "Yew tree", + "names": [ + "objects.yewtree", + "objects.prif_yewtree", + "objects.yewtree_update", + "objects.tree_yew_default01" + ], + "entries": [ + { + "label": "Yew tree cut chance", + "showbefore": "no", + "label1": "Bronze", + "low1": "4", + "high1": "12", + "req1": "60", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "6", + "high2": "19", + "req2": "60", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "8", + "high3": "25", + "req3": "60", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "9", + "high4": "28", + "req4": "60", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "10", + "high5": "31", + "req5": "60", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "12", + "high6": "37", + "req6": "60", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "14", + "high7": "44", + "req7": "60", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "15", + "high8": "47", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png" + } + ] + }, + { + "title": "Willow tree", + "names": [ + "objects.willowtree", + "objects.willow_tree2", + "objects.willow_tree3", + "objects.willow_tree4" + ], + "entries": [ + { + "label": "Willow tree cut chance", + "xlabel": "Woodcutting level", + "showbefore": "no", + "label1": "Bronze", + "low1": "16", + "high1": "50", + "req1": "30", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "24", + "high2": "75", + "req2": "30", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "32", + "high3": "100", + "req3": "30", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "36", + "high4": "112", + "req4": "30", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "40", + "high5": "125", + "req5": "30", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "48", + "high6": "150", + "req6": "31", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "56", + "high7": "175", + "req7": "41", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "60", + "high8": "187", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png" + } + ] + }, + { + "title": "Raw trout", + "names": [ + "items.raw_trout" + ], + "entries": [ + { + "label": "Trout + salmon fishing chance", + "xlabel": "Fishing level", + "cascade": "yes", + "showbefore": "no", + "label1": "Raw salmon", + "low1": "16", + "high1": "96", + "req1": "30", + "color1": "#c77f72", + "image1": "Raw salmon.png", + "label2": "Raw trout", + "low2": "32", + "high2": "192", + "req2": "20", + "color2": "#9a908f", + "image2": "Raw trout.png" + } + ] + }, + { + "title": "Prototype dart tip", + "names": [ + "items.thprotodarttip" + ], + "entries": [ + { + "label": "Prototype dart tip creation chance", + "label1": "Prototype dart tip", + "low1": "61", + "high1": "245", + "req1": "20", + "image1": "Prototype_dart_tip.png" + } + ] + }, + { + "title": "Brimstone chest", + "names": [ + "objects.brimstone_konar_chest_closed", + "objects.brimstone_konar_chest_open" + ], + "entries": [ + { + "label": "Brimstone chest fish chance", + "xlabel": "Fishing level", + "ylabel": "Chance to receive", + "cascade": [], + "label1": "Raw manta ray", + "low1": "-10", + "high1": "20", + "image1": "Raw manta ray.png", + "color1": [], + "label2": "Raw sea turtle", + "low2": "-10", + "high2": "50", + "image2": "Raw sea turtle.png", + "color2": [], + "label3": "Raw shark", + "low3": "-60", + "high3": "140", + "image3": "Raw shark.png", + "color3": [], + "label4": "Raw monkfish", + "low4": "0", + "high4": "170", + "image4": "Raw monkfish.png", + "color4": [], + "label5": "Raw swordfish", + "low5": "30", + "high5": "200", + "image5": "Raw swordfish.png", + "color5": [], + "label6": "Raw lobster", + "low6": "70", + "high6": "270", + "image6": "Raw lobster.png", + "color6": [], + "label7": "Raw tuna", + "low7": "225", + "high7": "324", + "image7": "Raw tuna.png", + "color7": [] + } + ] + }, + { + "title": "Raw slimy eel", + "names": [ + "items.mort_slimey_eel" + ], + "entries": [ + { + "label": "Slimy + cave eel fishing chance", + "cascade": "yes", + "showbefore": "no", + "label1": "Raw cave eel", + "low1": "10", + "high1": "80", + "req1": "38", + "color1": "#606b48", + "image1": "Raw cave eel.png", + "label2": "Raw slimy eel", + "low2": "10", + "high2": "80", + "req2": "28", + "color2": "brown", + "image2": "Raw slimy eel.png" + } + ] + }, + { + "title": "Cooked slimy eel", + "names": [ + "items.mort_slimey_eel_cooked" + ], + "entries": [ + { + "label": "Cooked slimy eel cooking chance", + "label1": "Fire or Range", + "low1": "63", + "high1": "382", + "req1": "28", + "color1": "gray", + "image1": "Cooked slimy eel.png", + "label2": "Hosidius +5%", + "low2": "75", + "high2": "394", + "req2": "28", + "color2": "red", + "image2": "Cooked slimy eel.png", + "label3": "Hosidius +10%", + "low3": "88", + "high3": "407", + "req3": "79", + "color3": "blue", + "image3": "Cooked slimy eel.png" + } + ] + }, + { + "title": "Burnt shrimp", + "names": [ + "items.burnt_shrimp" + ], + "entries": [ + { + "label": "Shrimps cooking chance", + "xlabel": "Cooking level", + "label1": "Fire or Range", + "low1": "128", + "high1": "512", + "req1": "1", + "color1": "gray", + "image1": "Shrimps.png", + "label2": "Lumbridge range", + "low2": "138", + "high2": "532", + "req2": "1", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "140", + "high3": "524", + "req3": "1", + "color3": "red", + "image3": "Shrimps.png", + "label4": "Hosidius +10%", + "low4": "153", + "high4": "537", + "req4": "84", + "color4": "blue", + "image4": "Shrimps.png" + } + ] + }, + { + "title": "Fat snail meat", + "names": [ + "items.snail_corpse_cooked3" + ], + "entries": [ + { + "label": "Fat snail meat cooking chance", + "label1": "Fire or Range", + "low1": "73", + "high1": "402", + "req1": "22", + "color1": "gray", + "image1": "Fat snail meat.png", + "label2": "Lumbridge range", + "low2": "83", + "high2": "422", + "req2": "22", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "85", + "high3": "414", + "req3": "22", + "color3": "red", + "image3": "Fat snail meat.png", + "label4": "Hosidius +10%", + "low4": "98", + "high4": "427", + "req4": "79", + "color4": "blue", + "image4": "Fat snail meat.png" + } + ] + }, + { + "title": "Lean snail meat", + "names": [ + "items.snail_corpse_cooked2" + ], + "entries": [ + { + "label": "Lean snail meat cooking chance", + "label1": "Fire", + "low1": "93", + "high1": "444", + "req1": "17", + "color1": "orange", + "image1": "Firemaking icon.png", + "label2": "Range", + "low2": "85", + "high2": "428", + "req2": "17", + "color2": "saddlebrown", + "image2": "Cooking range icon.png", + "label3": "Lumbridge range", + "low3": "95", + "high3": "448", + "req3": "17", + "color3": "green", + "image3": "Lumbridge Teleport.png", + "label4": "Hosidius +5%", + "low4": "97", + "high4": "440", + "req4": "17", + "color4": "red", + "image4": "Cooking range icon.png", + "label5": "Hosidius +10%", + "low5": "110", + "high5": "453", + "req5": "79", + "color5": "blue", + "image5": "Cooking range icon.png" + } + ] + }, + { + "title": "Thin snail meat", + "names": [ + "items.snail_corpse_cooked1" + ], + "entries": [ + { + "label": "Thin snail meat cooking chance", + "label1": "Fire or Range", + "low1": "93", + "high1": "444", + "req1": "12", + "color1": "gray", + "image1": "Thin snail meat.png", + "label2": "Lumbridge range", + "low2": "103", + "high2": "464", + "req2": "12", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "105", + "high3": "456", + "req3": "12", + "color3": "red", + "image3": "Thin snail meat.png", + "label4": "Hosidius +10%", + "low4": "118", + "high4": "469", + "req4": "79", + "color4": "blue", + "image4": "Thin snail meat.png" + } + ] + }, + { + "title": "Wealthy citizen", + "names": [ + "npcs.varlamore_wealthy_citizen_a", + "npcs.varlamore_wealthy_citizen_b", + "npcs.varlamore_wealthy_citizen_c", + "npcs.varlamore_wealthy_citizen_d" + ], + "entries": [ + { + "label": "Wealthy citizen pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "35", + "high1": "200", + "req1": "50", + "color1": "gray", + "image1": "Thief Wealthy citizen.png", + "label2": "Gloves of silence", + "low2": "36", + "high2": "210", + "req2": "50", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "38", + "high3": "220", + "req3": "50", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "41", + "high4": "242", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Martin the Master Gardener", + "names": [ + "npcs.martin_the_master_farmer" + ], + "entries": [ + { + "label": "Master Farmer pickpocket chance", + "label1": "Normal", + "low1": "90", + "high1": "240", + "req1": "38", + "color1": "gray", + "image1": "Thief Master farmer.png", + "label2": "Gloves of silence", + "low2": "94", + "high2": "252", + "req2": "38", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "99", + "high3": "264", + "req3": "67", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "108", + "high4": "290", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Kelyn", + "names": [ + "npcs.sote_lady_ithell_normal", + "npcs.mourning_town_elf_5_vis", + "npcs.sote_lady_ithell_vis", + "npcs.sote_lady_ithell_upass", + "npcs.lady_ithell" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "H.A.M. Member", + "names": [ + "npcs.favour_male_ham_civilian", + "npcs.favour_female_ham_civilian" + ], + "entries": [ + { + "label": "Avoiding concussions using Agility", + "label1": "", + "low1": "0", + "high1": "254", + "req1": "15", + "showbefore": "yes", + "color1": "black", + "image1": "Agility icon.png" + }, + { + "label": "H.A.M Member pickpocket chance", + "label1": "Normal", + "low1": "135", + "high1": "239", + "req1": "15", + "color1": "gray", + "image1": "Thieving icon.png", + "label2": "Gloves of silence", + "low2": "141", + "high2": "250", + "req2": "15", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "148", + "high3": "262", + "req3": "72", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "162", + "high4": "288", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Golden warbler", + "names": [ + "npcs.hunting_bird_desert" + ], + "entries": [ + { + "label": "Golden warbler catch chance", + "showbefore": "no", + "label1": "Golden warbler", + "low1": "92", + "high1": "400", + "req1": "5", + "color1": "#bfbf2a", + "image1": "Golden warbler icon.png" + } + ] + }, + { + "title": "Arvel", + "names": [ + "npcs.mourning_town_elf_3" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Mawrth", + "names": [ + "npcs.mourning_town_elf_4", + "npcs.sote_mawrth", + "npcs.sote_mawrth_cutscene" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Crimson swift", + "names": [ + "npcs.hunting_bird_jungle" + ], + "entries": [ + { + "label": "Crimson swift catch chance", + "showbefore": "no", + "label1": "Crimson swift", + "low1": "100", + "high1": "420", + "req1": "1", + "color1": "#d44444", + "image1": "Crimson swift icon.png" + } + ] + }, + { + "title": "Tropical wagtail", + "names": [ + "npcs.multicoloured_bird" + ], + "entries": [ + { + "label": "Tropical wagtail catch chance", + "showbefore": "no", + "label1": "Tropical wagtail", + "low1": "75", + "high1": "370", + "req1": "19", + "color1": "#326432", + "image1": "Tropical wagtail icon.png" + } + ] + }, + { + "title": "Cerulean twitch", + "names": [ + "npcs.hunting_bird_polar" + ], + "entries": [ + { + "label": "Cerulean twitch catch chance", + "showbefore": "no", + "label1": "Cerulean twitch", + "low1": "82", + "high1": "380", + "req1": "11", + "color1": "#41416e", + "image1": "Cerulean twitch icon.png" + } + ] + }, + { + "title": "Polar kebbit", + "names": [], + "entries": [ + { + "label": "Polar kebbit catch chance", + "label1": "Polar kebbit", + "low1": "238", + "high1": "1080", + "req1": "1", + "color1": "#a5a8b1", + "image1": "Polar kebbit icon.png" + } + ] + }, + { + "title": "Black salamander (Hunter)", + "names": [ + "npcs.salamander_black" + ], + "entries": [ + { + "label": "Black salamander catch chance", + "showbefore": "no", + "label1": "Black salamander", + "low1": "0", + "high1": "212", + "req1": "67", + "color1": "#151111", + "image1": "Black salamander.png" + } + ] + }, + { + "title": "Orange salamander (Hunter)", + "names": [ + "npcs.salamander_orange" + ], + "entries": [ + { + "label": "Orange salamander catch chance", + "showbefore": "no", + "label1": "Orange salamander", + "low1": "16", + "high1": "288", + "req1": "47", + "color1": "#976b1e", + "image1": "Orange salamander.png" + } + ] + }, + { + "title": "Red salamander (Hunter)", + "names": [ + "npcs.salamander_red" + ], + "entries": [ + { + "label": "Salamander catch chance", + "showbefore": "no", + "label1": "Red salamander", + "low1": "0", + "high1": "240", + "req1": "59", + "color1": "#6c2413", + "image1": "Red salamander.png" + } + ] + }, + { + "title": "Swamp lizard (Hunter)", + "names": [ + "npcs.salamander_green" + ], + "entries": [ + { + "label": "Swamp lizard catch chance", + "showbefore": "no", + "label1": "Swamp lizard", + "low1": "52", + "high1": "360", + "req1": "29", + "color1": "#1b441a", + "image1": "Swamp lizard.png" + } + ] + }, + { + "title": "Master Farmer", + "names": [ + "npcs.master_farmer_1", + "npcs.master_farmer_2", + "npcs.master_farmer_1_f", + "npcs.master_farmer_2_f", + "npcs.varlamore_master_farmer_f_1", + "npcs.varlamore_master_farmer_f_2", + "npcs.varlamore_master_farmer_f_3", + "npcs.varlamore_master_farmer_f_4", + "npcs.varlamore_master_farmer_m_1", + "npcs.varlamore_master_farmer_m_2", + "npcs.varlamore_master_farmer_m_3", + "npcs.varlamore_master_farmer_m_4" + ], + "entries": [ + { + "label": "Master Farmer pickpocket chance", + "label1": "Normal", + "low1": "90", + "high1": "240", + "req1": "38", + "color1": "gray", + "image1": "Thief Master farmer.png", + "label2": "Gloves of silence", + "low2": "94", + "high2": "252", + "req2": "38", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "99", + "high3": "264", + "req3": "67", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "108", + "high4": "290", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Dark kebbit", + "names": [ + "npcs.huntingbeast_silent" + ], + "entries": [ + { + "label": "Dark kebbit catch chance", + "showbefore": "no", + "label1": "Dark kebbit", + "low1": "0", + "high1": "253", + "req1": "57", + "color1": "#84630d", + "image1": "Dark kebbit icon.png" + } + ] + }, + { + "title": "Dashing kebbit", + "names": [ + "npcs.huntingbeast_speedy2" + ], + "entries": [ + { + "label": "Dashing kebbit catch chance", + "showbefore": "no", + "label1": "Dashing kebbit", + "low1": "0", + "high1": "205", + "req1": "69", + "color1": "#bd9f64", + "image1": "Dashing kebbit icon.png" + } + ] + }, + { + "title": "Spotted kebbit", + "names": [ + "npcs.huntingbeast_speedy" + ], + "entries": [ + { + "label": "Spotted kebbit catch chance", + "showbefore": "no", + "label1": "Spotted kebbit", + "low1": "26", + "high1": "310", + "req1": "43", + "color1": "#5c4a2c", + "image1": "Spotted kebbit icon.png" + } + ] + }, + { + "title": "Copper longtail", + "names": [ + "npcs.hunting_bird_woodland" + ], + "entries": [ + { + "label": "Copper longtail catch chance", + "showbefore": "no", + "label1": "Copper longtail", + "low1": "85", + "high1": "390", + "req1": "9", + "color1": "#ed9b58", + "image1": "Copper longtail icon.png" + } + ] + }, + { + "title": "White rabbit", + "names": [], + "entries": [ + { + "label": "Ferret preservation chance", + "xlabel": "Hunter level", + "showbefore": "no", + "label1": "Flushing a rabbit hole", + "low1": "190", + "high1": "255", + "req1": "27", + "color1": "#645750", + "image1": "Ferret.png" + } + ] + }, + { + "title": "Achey Tree", + "names": [ + "objects.achey_tree" + ], + "entries": [ + { + "label": "Achey tree cut chance", + "label1": "Bronze", + "low1": "64", + "high1": "200", + "req1": "1", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "96", + "high2": "300", + "req2": "1", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "128", + "high3": "400", + "req3": "6", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "144", + "high4": "450", + "req4": "11", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "160", + "high5": "500", + "req5": "21", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "192", + "high6": "600", + "req6": "31", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "224", + "high7": "700", + "req7": "41", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "240", + "high8": "750", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png" + } + ] + }, + { + "title": "Anaire", + "names": [ + "npcs.prif_citizen_anaire" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Aranwe", + "names": [ + "npcs.prif_citizen_aranwe" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Aredhel", + "names": [ + "npcs.prif_citizen_aredhel" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "A wooden log", + "names": [ + "objects.zq_logbalance" + ], + "entries": [ + { + "label": "Crossing a wooden log", + "showbefore": "no", + "xlabel": "Agility level", + "ylabel": "Cross chance", + "label1": "Successful cross chance", + "low1": "90", + "high1": "250", + "req1": "1", + "color1": "#70450d", + "image1": "Agility icon.png" + } + ] + }, + { + "title": "Admiral pie", + "names": [ + "items.admiral_pie", + "items.half_admiral_pie" + ], + "entries": [ + { + "label": "Admiral pie cooking chance", + "xlabel": "Cooking level", + "showbefore": "no", + "label1": "Range", + "low1": "15", + "high1": "270", + "req1": "70", + "color1": "saddlebrown", + "image1": "Admiral pie.png", + "label2": "Hosidius +5%", + "low2": "27", + "high2": "282", + "req2": "70", + "color2": "red", + "image2": "Admiral pie.png", + "label3": "Hosidius +10%", + "low3": "40", + "high3": "295", + "req3": "79", + "color3": "blue", + "image3": "Admiral pie.png" + } + ] + }, + { + "title": "Raw salmon", + "names": [ + "items.raw_salmon" + ], + "entries": [ + { + "label": "Trout + salmon fishing chance", + "cascade": "yes", + "showbefore": "no", + "label1": "Raw salmon", + "low1": "16", + "high1": "96", + "req1": "30", + "color1": "#c77f72", + "image1": "Raw salmon.png", + "label2": "Raw trout", + "low2": "32", + "high2": "192", + "req2": "20", + "color2": "#9a908f", + "image2": "Raw trout.png" + } + ] + }, + { + "title": "Underwater Agility and Thieving", + "names": [], + "entries": [ + { + "label": "Successful search chance", + "lowLevel": "1", + "label1": "Glistening and mermaid's tears", + "low1": "30", + "high1": "40", + "req1": "1", + "color1": "blue", + "image1": "Glistening tear 5.png" + } + ] + }, + { + "title": "Yew tree", + "names": [ + "objects.yewtree", + "objects.prif_yewtree", + "objects.yewtree_update", + "objects.tree_yew_default01" + ], + "entries": [ + { + "label": "Yew tree cut chance", + "showbefore": "no", + "label1": "Bronze", + "low1": "4", + "high1": "12", + "req1": "60", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "6", + "high2": "19", + "req2": "60", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "8", + "high3": "25", + "req3": "60", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "9", + "high4": "28", + "req4": "60", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "10", + "high5": "31", + "req5": "60", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "12", + "high6": "37", + "req6": "60", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "14", + "high7": "44", + "req7": "60", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "15", + "high8": "47", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png" + } + ] + }, + { + "title": "Willow tree", + "names": [ + "objects.willowtree", + "objects.willow_tree2", + "objects.willow_tree3", + "objects.willow_tree4" + ], + "entries": [ + { + "label": "Willow tree cut chance", + "xlabel": "Woodcutting level", + "showbefore": "no", + "label1": "Bronze", + "low1": "16", + "high1": "50", + "req1": "30", + "color1": "saddlebrown", + "image1": "Bronze axe.png", + "label2": "Iron", + "low2": "24", + "high2": "75", + "req2": "30", + "color2": "dimgray", + "image2": "Iron axe.png", + "label3": "Steel", + "low3": "32", + "high3": "100", + "req3": "30", + "color3": "lightgray", + "image3": "Steel axe.png", + "label4": "Black", + "low4": "36", + "high4": "112", + "req4": "30", + "color4": "black", + "image4": "Black axe.png", + "label5": "Mithril", + "low5": "40", + "high5": "125", + "req5": "30", + "color5": "slateblue", + "image5": "Mithril axe.png", + "label6": "Adamant", + "low6": "48", + "high6": "150", + "req6": "31", + "color6": "seagreen", + "image6": "Adamant axe.png", + "label7": "Rune", + "low7": "56", + "high7": "175", + "req7": "41", + "color7": "steelblue", + "image7": "Rune axe.png", + "label8": "Dragon", + "low8": "60", + "high8": "187", + "req8": "61", + "color8": "firebrick", + "image8": "Dragon axe.png" + } + ] + }, + { + "title": "Raw trout", + "names": [ + "items.raw_trout" + ], + "entries": [ + { + "label": "Trout + salmon fishing chance", + "xlabel": "Fishing level", + "cascade": "yes", + "showbefore": "no", + "label1": "Raw salmon", + "low1": "16", + "high1": "96", + "req1": "30", + "color1": "#c77f72", + "image1": "Raw salmon.png", + "label2": "Raw trout", + "low2": "32", + "high2": "192", + "req2": "20", + "color2": "#9a908f", + "image2": "Raw trout.png" + } + ] + }, + { + "title": "Prototype dart tip", + "names": [ + "items.thprotodarttip" + ], + "entries": [ + { + "label": "Prototype dart tip creation chance", + "label1": "Prototype dart tip", + "low1": "61", + "high1": "245", + "req1": "20", + "image1": "Prototype_dart_tip.png" + } + ] + }, + { + "title": "Brimstone chest", + "names": [ + "objects.brimstone_konar_chest_closed", + "objects.brimstone_konar_chest_open" + ], + "entries": [ + { + "label": "Brimstone chest fish chance", + "xlabel": "Fishing level", + "ylabel": "Chance to receive", + "cascade": [], + "label1": "Raw manta ray", + "low1": "-10", + "high1": "20", + "image1": "Raw manta ray.png", + "color1": [], + "label2": "Raw sea turtle", + "low2": "-10", + "high2": "50", + "image2": "Raw sea turtle.png", + "color2": [], + "label3": "Raw shark", + "low3": "-60", + "high3": "140", + "image3": "Raw shark.png", + "color3": [], + "label4": "Raw monkfish", + "low4": "0", + "high4": "170", + "image4": "Raw monkfish.png", + "color4": [], + "label5": "Raw swordfish", + "low5": "30", + "high5": "200", + "image5": "Raw swordfish.png", + "color5": [], + "label6": "Raw lobster", + "low6": "70", + "high6": "270", + "image6": "Raw lobster.png", + "color6": [], + "label7": "Raw tuna", + "low7": "225", + "high7": "324", + "image7": "Raw tuna.png", + "color7": [] + } + ] + }, + { + "title": "Raw slimy eel", + "names": [ + "items.mort_slimey_eel" + ], + "entries": [ + { + "label": "Slimy + cave eel fishing chance", + "cascade": "yes", + "showbefore": "no", + "label1": "Raw cave eel", + "low1": "10", + "high1": "80", + "req1": "38", + "color1": "#606b48", + "image1": "Raw cave eel.png", + "label2": "Raw slimy eel", + "low2": "10", + "high2": "80", + "req2": "28", + "color2": "brown", + "image2": "Raw slimy eel.png" + } + ] + }, + { + "title": "Cooked slimy eel", + "names": [ + "items.mort_slimey_eel_cooked" + ], + "entries": [ + { + "label": "Cooked slimy eel cooking chance", + "label1": "Fire or Range", + "low1": "63", + "high1": "382", + "req1": "28", + "color1": "gray", + "image1": "Cooked slimy eel.png", + "label2": "Hosidius +5%", + "low2": "75", + "high2": "394", + "req2": "28", + "color2": "red", + "image2": "Cooked slimy eel.png", + "label3": "Hosidius +10%", + "low3": "88", + "high3": "407", + "req3": "79", + "color3": "blue", + "image3": "Cooked slimy eel.png" + } + ] + }, + { + "title": "Burnt shrimp", + "names": [ + "items.burnt_shrimp" + ], + "entries": [ + { + "label": "Shrimps cooking chance", + "xlabel": "Cooking level", + "label1": "Fire or Range", + "low1": "128", + "high1": "512", + "req1": "1", + "color1": "gray", + "image1": "Shrimps.png", + "label2": "Lumbridge range", + "low2": "138", + "high2": "532", + "req2": "1", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "140", + "high3": "524", + "req3": "1", + "color3": "red", + "image3": "Shrimps.png", + "label4": "Hosidius +10%", + "low4": "153", + "high4": "537", + "req4": "84", + "color4": "blue", + "image4": "Shrimps.png" + } + ] + }, + { + "title": "Fat snail meat", + "names": [ + "items.snail_corpse_cooked3" + ], + "entries": [ + { + "label": "Fat snail meat cooking chance", + "label1": "Fire or Range", + "low1": "73", + "high1": "402", + "req1": "22", + "color1": "gray", + "image1": "Fat snail meat.png", + "label2": "Lumbridge range", + "low2": "83", + "high2": "422", + "req2": "22", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "85", + "high3": "414", + "req3": "22", + "color3": "red", + "image3": "Fat snail meat.png", + "label4": "Hosidius +10%", + "low4": "98", + "high4": "427", + "req4": "79", + "color4": "blue", + "image4": "Fat snail meat.png" + } + ] + }, + { + "title": "Lean snail meat", + "names": [ + "items.snail_corpse_cooked2" + ], + "entries": [ + { + "label": "Lean snail meat cooking chance", + "label1": "Fire", + "low1": "93", + "high1": "444", + "req1": "17", + "color1": "orange", + "image1": "Firemaking icon.png", + "label2": "Range", + "low2": "85", + "high2": "428", + "req2": "17", + "color2": "saddlebrown", + "image2": "Cooking range icon.png", + "label3": "Lumbridge range", + "low3": "95", + "high3": "448", + "req3": "17", + "color3": "green", + "image3": "Lumbridge Teleport.png", + "label4": "Hosidius +5%", + "low4": "97", + "high4": "440", + "req4": "17", + "color4": "red", + "image4": "Cooking range icon.png", + "label5": "Hosidius +10%", + "low5": "110", + "high5": "453", + "req5": "79", + "color5": "blue", + "image5": "Cooking range icon.png" + } + ] + }, + { + "title": "Thin snail meat", + "names": [ + "items.snail_corpse_cooked1" + ], + "entries": [ + { + "label": "Thin snail meat cooking chance", + "label1": "Fire or Range", + "low1": "93", + "high1": "444", + "req1": "12", + "color1": "gray", + "image1": "Thin snail meat.png", + "label2": "Lumbridge range", + "low2": "103", + "high2": "464", + "req2": "12", + "color2": "green", + "image2": "Lumbridge Teleport.png", + "label3": "Hosidius +5%", + "low3": "105", + "high3": "456", + "req3": "12", + "color3": "red", + "image3": "Thin snail meat.png", + "label4": "Hosidius +10%", + "low4": "118", + "high4": "469", + "req4": "79", + "color4": "blue", + "image4": "Thin snail meat.png" + } + ] + }, + { + "title": "Wealthy citizen", + "names": [ + "npcs.varlamore_wealthy_citizen_a", + "npcs.varlamore_wealthy_citizen_b", + "npcs.varlamore_wealthy_citizen_c", + "npcs.varlamore_wealthy_citizen_d" + ], + "entries": [ + { + "label": "Wealthy citizen pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "35", + "high1": "200", + "req1": "50", + "color1": "gray", + "image1": "Thief Wealthy citizen.png", + "label2": "Gloves of silence", + "low2": "36", + "high2": "210", + "req2": "50", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "38", + "high3": "220", + "req3": "50", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "41", + "high4": "242", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Trouble Brewing", + "names": [], + "entries": [ + { + "label": "Torch burn chance", + "xlabel": "Firemaking level", + "showbefore": "no", + "label1": "Successful burn", + "low1": "12", + "high1": "112", + "req1": "1", + "color1": "red", + "image1": "Lit torch.png" + } + ] + }, + { + "title": "Motherlode Mine", + "names": [], + "entries": [ + { + "label": "Pay-dirt mining chance", + "showbefore": "no", + "xlabel": "Mining Level", + "label1": "Pay-dirt", + "low1": "60", + "high1": "105", + "req1": "30", + "color1": "brown", + "image1": "Pay-dirt.png" + }, + { + "label": "Motherlode Mine ore chance", + "xlabel": "Mining level", + "cascade": "yes", + "showbefore": "no", + "label1": "Golden nugget", + "low1": "7", + "high1": "7", + "req1": "30", + "color1": "gold", + "image1": "Golden nugget.png", + "label2": "Runite ore", + "low2": "-20", + "high2": "5", + "req2": "85", + "color2": "steelblue", + "image2": "Runite ore.png", + "label3": "Adamantite ore", + "low3": "-90", + "high3": "50", + "req3": "70", + "color3": "seagreen", + "image3": "Adamantite ore.png", + "label4": "Mithril ore", + "low4": "-19", + "high4": "90", + "req4": "55", + "color4": "slateblue", + "image4": "Mithril ore.png", + "label5": "Gold ore", + "low5": "-40", + "high5": "126", + "req5": "40", + "color5": "goldenrod", + "image5": "Gold ore.png", + "label6": "Coal", + "low6": "226", + "high6": "325", + "req6": "30", + "color6": "black", + "image6": "Coal.png" + } + ] + }, + { + "title": "Goreu", + "names": [ + "npcs.mourning_town_elf_1" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Caranthir", + "names": [ + "npcs.prif_citizen_caranthir" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Celebrian", + "names": [ + "npcs.prif_citizen_celebrian" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Celegorm", + "names": [ + "npcs.prif_citizen_celegorm" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Cirdan", + "names": [ + "npcs.prif_citizen_cirdan" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Curufin", + "names": [ + "npcs.prif_citizen_curufin" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Earwen", + "names": [ + "npcs.prif_citizen_earwen" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Edrahil", + "names": [ + "npcs.prif_citizen_edrahil" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Elenwe", + "names": [ + "npcs.prif_citizen_elenwe" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Elladan", + "names": [ + "npcs.prif_citizen_elladan" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Enel", + "names": [ + "npcs.prif_citizen_enel" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Enelye", + "names": [ + "npcs.prif_citizen_enelye" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Enerdhil", + "names": [ + "npcs.prif_citizen_enerdhil" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Erestor", + "names": [ + "npcs.prif_citizen_erestor" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Feanor", + "names": [ + "npcs.prif_citizen_feanor" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Findis", + "names": [ + "npcs.prif_citizen_findis" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Finduilas", + "names": [ + "npcs.prif_citizen_finduilas" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Fingolfin", + "names": [ + "npcs.prif_citizen_fingolfin" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Fingon", + "names": [ + "npcs.prif_citizen_fingon" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Galathil", + "names": [ + "npcs.prif_citizen_galathil" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Gelmir", + "names": [ + "npcs.prif_citizen_gelmir" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Glorfindel", + "names": [ + "npcs.prif_citizen_glorfindel" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Guilin", + "names": [ + "npcs.prif_citizen_guilin" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Hendor (elf)", + "names": [ + "npcs.prif_citizen_hendor" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Idril", + "names": [ + "npcs.prif_citizen_idril" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Imin", + "names": [ + "npcs.prif_citizen_imin" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Iminye", + "names": [ + "npcs.prif_citizen_iminye" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Indis", + "names": [ + "npcs.prif_citizen_indis" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Ingwe", + "names": [ + "npcs.prif_citizen_ingwe" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Ingwion", + "names": [ + "npcs.prif_citizen_ingwion" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Lenwe", + "names": [ + "npcs.prif_citizen_lenwe" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Lindir", + "names": [ + "npcs.prif_citizen_lindir" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Maeglin", + "names": [ + "npcs.prif_citizen_maeglin" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Mahtan", + "names": [ + "npcs.prif_citizen_mahtan" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Miriel", + "names": [ + "npcs.prif_citizen_miriel" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Mithrellas", + "names": [ + "npcs.prif_citizen_mithrellas" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Nellas", + "names": [ + "npcs.prif_citizen_nellas" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Nerdanel", + "names": [ + "npcs.prif_citizen_nerdanel" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Nimloth", + "names": [ + "npcs.prif_citizen_nimloth" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Oropher", + "names": [ + "npcs.prif_citizen_oropher" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Saeros", + "names": [ + "npcs.prif_citizen_saeros" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Salgant", + "names": [ + "npcs.prif_citizen_salgant" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Tatie", + "names": [ + "npcs.prif_citizen_tatie" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Thingol", + "names": [ + "npcs.prif_citizen_thingol" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Turgon", + "names": [ + "npcs.prif_citizen_turgon" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Vaire", + "names": [ + "npcs.prif_citizen_vaire" + ], + "entries": [ + { + "label": "Elf pickpocket chance", + "showbefore": "no", + "label1": "Normal", + "low1": "6", + "high1": "100", + "req1": "85", + "color1": "gray", + "image1": "Thief Elf.png", + "label2": "Gloves of silence", + "low2": "6", + "high2": "105", + "req2": "85", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "6", + "high3": "110", + "req3": "85", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "6", + "high4": "121", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + }, + { + "title": "Fishbowl (pet)", + "names": [ + "items.fishbowl_bluefish", + "items.fishbowl_greenfish", + "items.fishbowl_spinefish", + "npcs.poh_fishbowl_bluefish", + "npcs.poh_fishbowl_greenfish", + "npcs.poh_fishbowl_spinefish" + ], + "entries": [ + { + "label": "Pet fish catch rate", + "xlabel": "Fishing level", + "cascade": "yes", + "label1": "Spinefish", + "low1": "51", + "high1": "51", + "req1": "70", + "color1": "#ff9600", + "image1": "Fishbowl (orange).png", + "label2": "Greenfish", + "low2": "25", + "high2": "112", + "altlow2": "128", + "althigh2": "128", + "altreq2": "70", + "color2": "#00ff00", + "image2": "Fishbowl (green).png", + "label3": "Bluefish", + "low3": "255", + "high3": "255", + "color3": "#1ba5e3", + "image3": "Fishbowl (blue).png" + } + ] + }, + { + "title": "Tourist", + "names": [ + "npcs.varlamore_tourist_m_1", + "npcs.varlamore_tourist_m_2", + "npcs.varlamore_tourist_m_3", + "npcs.varlamore_tourist_f_1", + "npcs.varlamore_tourist_f_2", + "npcs.varlamore_tourist_f_3" + ], + "entries": [ + { + "label": "Tourist pickpocket chance", + "label1": "Normal", + "low1": "180", + "high1": "240", + "req1": "1", + "color1": "gray", + "image1": "Thief Man.png", + "label2": "Gloves of silence", + "low2": "189", + "high2": "252", + "req2": "1", + "color2": "darkblue", + "image2": "Gloves of silence.png", + "label3": "Ardougne Diary", + "low3": "198", + "high3": "264", + "req3": "1", + "color3": "black", + "image3": "Ardougne cloak 3.png", + "label4": "Thieving cape + Ardougne Diary", + "low4": "217", + "high4": "290", + "req4": "99", + "color4": "purple", + "image4": "Thieving cape.png" + } + ] + } +] \ No newline at end of file From 10a038700833998e9350ed0ab991d72cb4a63706 Mon Sep 17 00:00:00 2001 From: voidstarr <3334013+voidstarr@users.noreply.github.com> Date: Thu, 19 Feb 2026 14:24:05 -0800 Subject: [PATCH 08/10] feat(cooking): add wiki-accurate burn chance profiles to recipe tables - Add ChanceDef data class and ChanceModifier constants for modifier bitmasks (gauntlets, hosidius +5%/+10%, lumbridge range) - Embed burn chance profiles directly in all recipe definitions (fish, meat, bread, pies, pizza, stews, misc food, potatoes, baked goods) - Rewrite rollCookSuccess() with modifier-aware chance matching system, falling back to legacy stopBurn for recipes without profiles - Add CookingRecipeTests to verify heat-source recipes have chance data - Add chancesByAction lazy map in CookingActionRegistry for runtime lookup - Fix station masks for chompy (fire-only) and scrambled egg (range-only) - Remove old wikidata/ source files (now embedded in code) - Add cooking design docs --- .../impl/skills/cooking/CookingConstants.kt | 17 + .../impl/skills/cooking/CookingHelpers.kt | 50 +- .../impl/skills/cooking/CookingModels.kt | 35 +- .../cooking/recipes/BakedGoodsRecipes.kt | 15 +- .../skills/cooking/recipes/BreadRecipes.kt | 31 +- .../skills/cooking/recipes/FishRecipes.kt | 319 +- .../skills/cooking/recipes/MeatRecipes.kt | 173 +- .../skills/cooking/recipes/MiscFoodRecipes.kt | 46 +- .../impl/skills/cooking/recipes/PieRecipes.kt | 85 +- .../skills/cooking/recipes/PizzaRecipes.kt | 10 +- .../skills/cooking/recipes/PotatoRecipes.kt | 15 +- .../skills/cooking/recipes/StewRecipes.kt | 21 +- .../impl/skills/cooking/CookingConstants.kt | 17 + .../impl/skills/cooking/CookingHelpers.kt | 50 +- .../impl/skills/cooking/CookingModels.kt | 35 +- .../cooking/recipes/BakedGoodsRecipes.kt | 15 +- .../skills/cooking/recipes/BreadRecipes.kt | 31 +- .../skills/cooking/recipes/FishRecipes.kt | 319 +- .../skills/cooking/recipes/MeatRecipes.kt | 173 +- .../skills/cooking/recipes/MiscFoodRecipes.kt | 46 +- .../impl/skills/cooking/recipes/PieRecipes.kt | 85 +- .../skills/cooking/recipes/PizzaRecipes.kt | 10 +- .../skills/cooking/recipes/PotatoRecipes.kt | 15 +- .../skills/cooking/recipes/StewRecipes.kt | 21 +- .../skills/cooking/events/CookingUtils.kt | 113 +- .../cooking/runtime/CookingActionRegistry.kt | 19 + docs/cooking/plan.md | 61 + docs/cooking/recipe-gap.md | 102 + .../game/model/skill/CookingRecipeTests.kt | 31 + wikidata/burn_level.wikisrc | 1269 -- wikidata/burnt_food.wikisrc | 303 - wikidata/cooking.wikisrc | 788 - wikidata/meat-fish.md | 82 - wikidata/skill_chances.json | 18850 ---------------- 34 files changed, 1456 insertions(+), 21796 deletions(-) create mode 100644 docs/cooking/plan.md create mode 100644 docs/cooking/recipe-gap.md create mode 100644 game-server/src/test/kotlin/org/alter/game/model/skill/CookingRecipeTests.kt delete mode 100644 wikidata/burn_level.wikisrc delete mode 100644 wikidata/burnt_food.wikisrc delete mode 100644 wikidata/cooking.wikisrc delete mode 100644 wikidata/meat-fish.md delete mode 100644 wikidata/skill_chances.json diff --git a/cache/bin/main/org/alter/impl/skills/cooking/CookingConstants.kt b/cache/bin/main/org/alter/impl/skills/cooking/CookingConstants.kt index ce34972d..880f38eb 100644 --- a/cache/bin/main/org/alter/impl/skills/cooking/CookingConstants.kt +++ b/cache/bin/main/org/alter/impl/skills/cooking/CookingConstants.kt @@ -38,4 +38,21 @@ object CookingConstants { /** Station mask for cooking on both fire and range. */ const val STATION_ANY = STATION_FIRE or STATION_RANGE + + /** + * Modifier flags for burn chance profiles. + * Combined as bitmasks to represent equipment/location bonuses. + */ + object ChanceModifier { + /** No modifier (base chance). */ + const val NONE = 0 + /** Cooking gauntlets equipped. */ + const val GAUNTLETS = 1 + /** Hosidius Kitchen range (+5% burn reduction). */ + const val HOSIDIUS_5 = 2 + /** Hosidius Kitchen range with Kourend Hard Diary (+10% burn reduction). */ + const val HOSIDIUS_10 = 4 + /** Lumbridge Castle range (reduced burn for low-level foods). */ + const val LUMBRIDGE = 8 + } } diff --git a/cache/bin/main/org/alter/impl/skills/cooking/CookingHelpers.kt b/cache/bin/main/org/alter/impl/skills/cooking/CookingHelpers.kt index 309c37f7..2fc839fb 100644 --- a/cache/bin/main/org/alter/impl/skills/cooking/CookingHelpers.kt +++ b/cache/bin/main/org/alter/impl/skills/cooking/CookingHelpers.kt @@ -12,17 +12,24 @@ import org.alter.impl.skills.cooking.CookingConstants.Trigger object CookingHelpers { /** - * Creates a simple heat-cooking action (raw -> cooked/burnt). + * Creates a [ChanceDef] for burn chance profile definitions. * - * @param rowKey DB row key suffix (e.g., "cooking_shrimps"). - * @param raw RSCM key for the raw item. - * @param cooked RSCM key for the cooked item. - * @param burnt RSCM key for the burnt item. - * @param level Required Cooking level. - * @param xp Experience awarded on success. - * @param stopBurnFire Level at which burning stops on fires. - * @param stopBurnRange Level at which burning stops on ranges. - * @param stationMask Bitmask for allowed cooking stations. + * @param label Human-readable label (e.g., "base_any", "gauntlets", "hosidius_5"). + * @param stationMask Bitmask of stations this profile applies to. + * @param modifierMask Bitmask of required modifiers (default: none). + * @param low The low value for the statrandom calculation. + * @param high The high value for the statrandom calculation. + */ + fun chance( + label: String, + stationMask: Int, + modifierMask: Int = 0, + low: Int, + high: Int + ): ChanceDef = ChanceDef(label, stationMask, modifierMask, low, high) + + /** + * Creates a simple heat-cooking action (raw -> cooked/burnt). */ fun heatCook( rowKey: String, @@ -31,9 +38,10 @@ object CookingHelpers { burnt: String, level: Int, xp: Int, - stopBurnFire: Int, - stopBurnRange: Int, - stationMask: Int = STATION_ANY + stopBurnFire: Int = 0, + stopBurnRange: Int = 0, + stationMask: Int = STATION_ANY, + chances: List = emptyList() ): ActionDef = ActionDef( rowId = "dbrows.$rowKey", key = raw, @@ -46,7 +54,8 @@ object CookingHelpers { outcomes = listOf( OutcomeDef(rowSuffix = "success", kind = OutcomeKind.SUCCESS, item = cooked, xp = xp, weight = 1), OutcomeDef(rowSuffix = "fail", kind = OutcomeKind.FAIL, item = burnt, xp = 0, weight = 1) - ) + ), + chances = chances ) /** @@ -73,9 +82,10 @@ object CookingHelpers { burnt: String, cookingLevel: Int, xp: Int, - stopBurnFire: Int, - stopBurnRange: Int, - spitItem: String = "items.spit_iron" + stopBurnFire: Int = 0, + stopBurnRange: Int = 0, + spitItem: String = "items.spit_iron", + chances: List = emptyList() ): List = listOf( // Raw meat + iron spit -> skewered meat (inventory prep step) ActionDef( @@ -110,7 +120,8 @@ object CookingHelpers { outcomes = listOf( OutcomeDef(rowSuffix = "success", kind = OutcomeKind.SUCCESS, item = cooked, xp = xp, weight = 1), OutcomeDef(rowSuffix = "fail", kind = OutcomeKind.FAIL, item = burnt, xp = 0, weight = 1) - ) + ), + chances = chances ) ) @@ -208,7 +219,8 @@ object CookingHelpers { xp = 0, weight = 1 ) - ) + alwaysOutcomes + ) + alwaysOutcomes, + chances = step.chances ) ) } diff --git a/cache/bin/main/org/alter/impl/skills/cooking/CookingModels.kt b/cache/bin/main/org/alter/impl/skills/cooking/CookingModels.kt index 19d8e7c4..40ee6df4 100644 --- a/cache/bin/main/org/alter/impl/skills/cooking/CookingModels.kt +++ b/cache/bin/main/org/alter/impl/skills/cooking/CookingModels.kt @@ -4,6 +4,27 @@ package org.alter.impl.skills.cooking * Data models for cooking recipe definitions. */ +/** + * Defines a burn chance profile for a specific station and modifier combination. + * + * At runtime, the system selects the most specific matching profile based on the + * player's station and active modifiers, then uses [low]/[high] with the + * `computeSkillingSuccess` function to determine burn probability. + * + * @property label Human-readable label for this profile (e.g., "base_any", "gauntlets"). + * @property stationMask Bitmask of stations this profile applies to. + * @property modifierMask Bitmask of required modifiers (see [CookingConstants.ChanceModifier]). + * @property low The low value for the statrandom calculation. + * @property high The high value for the statrandom calculation. + */ +data class ChanceDef( + val label: String, + val stationMask: Int, + val modifierMask: Int = 0, + val low: Int, + val high: Int +) + /** * Defines an input ingredient for a cooking action. * @@ -55,12 +76,13 @@ data class ActionDef( val key: String, val variant: Int = CookingConstants.DEFAULT_VARIANT, val level: Int, - val stopBurnFire: Int, - val stopBurnRange: Int, + val stopBurnFire: Int = 0, + val stopBurnRange: Int = 0, val stationMask: Int = CookingConstants.STATION_ANY, val trigger: Int = CookingConstants.Trigger.HEAT_SOURCE, val inputs: List, - val outcomes: List + val outcomes: List, + val chances: List = emptyList() ) /** @@ -99,8 +121,9 @@ data class HeatStepDef( val cooked: String, val burnt: String, val xp: Int, - val stopBurnFire: Int, - val stopBurnRange: Int, + val stopBurnFire: Int = 0, + val stopBurnRange: Int = 0, val stationMask: Int = CookingConstants.STATION_ANY, - val always: List> = emptyList() + val always: List> = emptyList(), + val chances: List = emptyList() ) diff --git a/cache/bin/main/org/alter/impl/skills/cooking/recipes/BakedGoodsRecipes.kt b/cache/bin/main/org/alter/impl/skills/cooking/recipes/BakedGoodsRecipes.kt index e25ce387..a2298457 100644 --- a/cache/bin/main/org/alter/impl/skills/cooking/recipes/BakedGoodsRecipes.kt +++ b/cache/bin/main/org/alter/impl/skills/cooking/recipes/BakedGoodsRecipes.kt @@ -1,7 +1,10 @@ package org.alter.impl.skills.cooking.recipes import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_10 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_5 import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE +import org.alter.impl.skills.cooking.CookingHelpers.chance import org.alter.impl.skills.cooking.CookingHelpers.multiStepCook import org.alter.impl.skills.cooking.HeatStepDef import org.alter.impl.skills.cooking.PrepStepDef @@ -49,7 +52,12 @@ object BakedGoodsRecipes { xp = 138, stopBurnFire = 68, stopBurnRange = 64, - stationMask = STATION_RANGE + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 48, high = 352), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 60, high = 364), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 73, high = 377) + ) ) ) @@ -84,6 +92,11 @@ object BakedGoodsRecipes { stationMask = STATION_RANGE, always = listOf( "items.cake_tin" to 1 + ), + chances = listOf( + chance("range", STATION_RANGE, low = 38, high = 332), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 50, high = 344), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 63, high = 357) ) ) ) diff --git a/cache/bin/main/org/alter/impl/skills/cooking/recipes/BreadRecipes.kt b/cache/bin/main/org/alter/impl/skills/cooking/recipes/BreadRecipes.kt index 9b75e9b7..879233fe 100644 --- a/cache/bin/main/org/alter/impl/skills/cooking/recipes/BreadRecipes.kt +++ b/cache/bin/main/org/alter/impl/skills/cooking/recipes/BreadRecipes.kt @@ -1,11 +1,17 @@ package org.alter.impl.skills.cooking.recipes import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_10 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_5 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.LUMBRIDGE import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE +import org.alter.impl.skills.cooking.CookingHelpers.chance import org.alter.impl.skills.cooking.CookingHelpers.heatCook /** * Bread cooking recipes — baked on a range. + * + * Chance profiles sourced from OSRS Wiki skill_chances data. */ object BreadRecipes { @@ -15,22 +21,27 @@ object BreadRecipes { raw = "items.bread_dough", cooked = "items.bread", burnt = "items.burnt_bread", - level = 1, - xp = 40, - stopBurnFire = 35, - stopBurnRange = 35, - stationMask = STATION_RANGE + level = 1, xp = 40, stopBurnFire = 35, stopBurnRange = 35, + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 118, high = 492), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 128, high = 512), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 130, high = 504), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 143, high = 517) + ) ), heatCook( rowKey = "cooking_pitta_bread", raw = "items.uncooked_pitta_bread", cooked = "items.pitta_bread", burnt = "items.burnt_pitta_bread", - level = 58, - xp = 40, - stopBurnFire = 82, - stopBurnRange = 82, - stationMask = STATION_RANGE + level = 58, xp = 40, stopBurnFire = 82, stopBurnRange = 82, + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 118, high = 492), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 130, high = 504), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 143, high = 517) + ) ) ) } diff --git a/cache/bin/main/org/alter/impl/skills/cooking/recipes/FishRecipes.kt b/cache/bin/main/org/alter/impl/skills/cooking/recipes/FishRecipes.kt index 4930362c..1b324950 100644 --- a/cache/bin/main/org/alter/impl/skills/cooking/recipes/FishRecipes.kt +++ b/cache/bin/main/org/alter/impl/skills/cooking/recipes/FishRecipes.kt @@ -1,278 +1,381 @@ package org.alter.impl.skills.cooking.recipes import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.GAUNTLETS +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_10 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_5 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.LUMBRIDGE +import org.alter.impl.skills.cooking.CookingConstants.STATION_ANY import org.alter.impl.skills.cooking.CookingConstants.STATION_FIRE +import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE +import org.alter.impl.skills.cooking.CookingHelpers.chance import org.alter.impl.skills.cooking.CookingHelpers.heatCook /** - * Fish cooking recipes - standard heat-source cooking. + * Fish cooking recipes — standard heat-source cooking. + * + * Chance profiles sourced from OSRS Wiki skill_chances data. */ object FishRecipes { val recipes: List = listOf( + // ---- Low-level fish (shared fire/range curve + Lumbridge) ---- heatCook( rowKey = "cooking_shrimps", raw = "items.raw_shrimp", cooked = "items.shrimp", burnt = "items.burnt_shrimp", - level = 1, - xp = 30, - stopBurnFire = 34, - stopBurnRange = 34 + level = 1, xp = 30, stopBurnFire = 34, stopBurnRange = 34, + chances = listOf( + chance("base_any", STATION_ANY, low = 128, high = 512), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 138, high = 532), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 140, high = 524), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 153, high = 537) + ) ), heatCook( rowKey = "cooking_anchovies", raw = "items.raw_anchovies", cooked = "items.anchovies", burnt = "items.burntfish1", - level = 1, - xp = 30, - stopBurnFire = 34, - stopBurnRange = 34 + level = 1, xp = 30, stopBurnFire = 34, stopBurnRange = 34, + chances = listOf( + chance("base_any", STATION_ANY, low = 128, high = 512), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 138, high = 532), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 140, high = 524), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 153, high = 537) + ) ), heatCook( rowKey = "cooking_sardine", raw = "items.raw_sardine", cooked = "items.sardine", burnt = "items.burntfish5", - level = 1, - xp = 40, - stopBurnFire = 38, - stopBurnRange = 38 + level = 1, xp = 40, stopBurnFire = 38, stopBurnRange = 38, + chances = listOf( + chance("base_any", STATION_ANY, low = 118, high = 492), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 128, high = 512), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 130, high = 504), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 143, high = 517) + ) ), heatCook( rowKey = "cooking_herring", raw = "items.raw_herring", cooked = "items.herring", burnt = "items.burntfish3", - level = 5, - xp = 50, - stopBurnFire = 41, - stopBurnRange = 41 + level = 5, xp = 50, stopBurnFire = 41, stopBurnRange = 41, + chances = listOf( + chance("base_any", STATION_ANY, low = 108, high = 472), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 118, high = 492), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 120, high = 484), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 133, high = 497) + ) ), heatCook( rowKey = "cooking_mackerel", raw = "items.raw_mackerel", cooked = "items.mackerel", burnt = "items.burntfish3", - level = 10, - xp = 60, - stopBurnFire = 45, - stopBurnRange = 45 + level = 10, xp = 60, stopBurnFire = 45, stopBurnRange = 45, + chances = listOf( + chance("base_any", STATION_ANY, low = 98, high = 452), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 108, high = 472), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 110, high = 464), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 123, high = 477) + ) ), heatCook( rowKey = "cooking_trout", raw = "items.raw_trout", cooked = "items.trout", burnt = "items.burntfish2", - level = 15, - xp = 70, - stopBurnFire = 49, - stopBurnRange = 49 + level = 15, xp = 70, stopBurnFire = 49, stopBurnRange = 49, + chances = listOf( + chance("base_any", STATION_ANY, low = 88, high = 432), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 98, high = 452), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 100, high = 444), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 113, high = 457) + ) ), + + // ---- Mid-level fish ---- heatCook( rowKey = "cooking_cod", raw = "items.raw_cod", cooked = "items.cod", burnt = "items.burntfish2", - level = 18, - xp = 75, - stopBurnFire = 51, - stopBurnRange = 49 + level = 18, xp = 75, stopBurnFire = 51, stopBurnRange = 49, + chances = listOf( + chance("fire", STATION_FIRE, low = 83, high = 422), + chance("range", STATION_RANGE, low = 88, high = 432), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 93, high = 442), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 100, high = 444), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 113, high = 457) + ) ), heatCook( rowKey = "cooking_pike", raw = "items.raw_pike", cooked = "items.pike", burnt = "items.burntfish5", - level = 20, - xp = 80, - stopBurnFire = 54, - stopBurnRange = 54 + level = 20, xp = 80, stopBurnFire = 54, stopBurnRange = 54, + chances = listOf( + chance("base_any", STATION_ANY, low = 78, high = 412), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 88, high = 432), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 90, high = 424), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 103, high = 437) + ) ), heatCook( rowKey = "cooking_salmon", raw = "items.raw_salmon", cooked = "items.salmon", burnt = "items.burntfish2", - level = 25, - xp = 90, - stopBurnFire = 58, - stopBurnRange = 58 + level = 25, xp = 90, stopBurnFire = 58, stopBurnRange = 58, + chances = listOf( + chance("base_any", STATION_ANY, low = 68, high = 392), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 78, high = 402), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 80, high = 404), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 93, high = 417) + ) ), heatCook( rowKey = "cooking_slimy_eel", raw = "items.mort_slimey_eel", cooked = "items.mort_slimey_eel_cooked", burnt = "items.burnt_eel", - level = 28, - xp = 95, - stopBurnFire = 61, - stopBurnRange = 61 + level = 28, xp = 95, stopBurnFire = 61, stopBurnRange = 61, + chances = listOf( + chance("base_any", STATION_ANY, low = 63, high = 382), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 75, high = 394), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 88, high = 407) + ) ), heatCook( rowKey = "cooking_tuna", raw = "items.raw_tuna", cooked = "items.tuna", burnt = "items.burntfish4", - level = 30, - xp = 100, - stopBurnFire = 63, - stopBurnRange = 63 + level = 30, xp = 100, stopBurnFire = 63, stopBurnRange = 63, + chances = listOf( + chance("base_any", STATION_ANY, low = 58, high = 372), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 70, high = 384), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 83, high = 397) + ) ), + + // ---- Mid-high fish (gauntlet-affected) ---- heatCook( rowKey = "cooking_lobster", raw = "items.raw_lobster", cooked = "items.lobster", burnt = "items.burnt_lobster", - level = 40, - xp = 120, - stopBurnFire = 74, - stopBurnRange = 74 + level = 40, xp = 120, stopBurnFire = 74, stopBurnRange = 74, + chances = listOf( + chance("base_any", STATION_ANY, low = 38, high = 332), + chance("gauntlets", STATION_ANY, modifierMask = GAUNTLETS, low = 55, high = 368), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 50, high = 344), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 63, high = 357), + chance("hosidius_5_gauntlets", STATION_RANGE, modifierMask = HOSIDIUS_5 or GAUNTLETS, low = 67, high = 380), + chance("hosidius_10_gauntlets", STATION_RANGE, modifierMask = HOSIDIUS_10 or GAUNTLETS, low = 80, high = 393) + ) ), heatCook( rowKey = "cooking_bass", raw = "items.raw_bass", cooked = "items.bass", burnt = "items.burntfish3", - level = 43, - xp = 130, - stopBurnFire = 79, - stopBurnRange = 79 + level = 43, xp = 130, stopBurnFire = 79, stopBurnRange = 79, + chances = listOf( + chance("base_any", STATION_ANY, low = 33, high = 312), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 45, high = 324), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 58, high = 337) + ) ), heatCook( rowKey = "cooking_swordfish", raw = "items.raw_swordfish", cooked = "items.swordfish", burnt = "items.burnt_swordfish", - level = 45, - xp = 140, - stopBurnFire = 86, - stopBurnRange = 80 + level = 45, xp = 140, stopBurnFire = 86, stopBurnRange = 80, + chances = listOf( + chance("fire", STATION_FIRE, low = 18, high = 292), + chance("range", STATION_RANGE, low = 30, high = 310), + chance("gauntlets", STATION_ANY, modifierMask = GAUNTLETS, low = 30, high = 310), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 42, high = 322), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 55, high = 335) + ) ), + + // ---- High-level fish ---- heatCook( rowKey = "cooking_monkfish", raw = "items.raw_monkfish", cooked = "items.monkfish", burnt = "items.burnt_monkfish", - level = 62, - xp = 150, - stopBurnFire = 92, - stopBurnRange = 90 + level = 62, xp = 150, stopBurnFire = 92, stopBurnRange = 90, + chances = listOf( + chance("fire", STATION_FIRE, low = 11, high = 275), + chance("range", STATION_RANGE, low = 13, high = 280), + chance("gauntlets", STATION_ANY, modifierMask = GAUNTLETS, low = 24, high = 290), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 25, high = 292), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 38, high = 305), + chance("hosidius_5_gauntlets", STATION_RANGE, modifierMask = HOSIDIUS_5 or GAUNTLETS, low = 36, high = 302), + chance("hosidius_10_gauntlets", STATION_RANGE, modifierMask = HOSIDIUS_10 or GAUNTLETS, low = 49, high = 315) + ) ), heatCook( rowKey = "cooking_shark", raw = "items.raw_shark", cooked = "items.shark", burnt = "items.burnt_shark", - level = 80, - xp = 210, - stopBurnFire = 100, - stopBurnRange = 100 + level = 80, xp = 210, stopBurnFire = 100, stopBurnRange = 100, + chances = listOf( + chance("fire", STATION_FIRE, low = 1, high = 202), + chance("range", STATION_RANGE, low = 1, high = 232), + chance("gauntlets", STATION_ANY, modifierMask = GAUNTLETS, low = 15, high = 270), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 13, high = 244), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 26, high = 257), + chance("hosidius_5_gauntlets", STATION_RANGE, modifierMask = HOSIDIUS_5 or GAUNTLETS, low = 27, high = 282), + chance("hosidius_10_gauntlets", STATION_RANGE, modifierMask = HOSIDIUS_10 or GAUNTLETS, low = 40, high = 295) + ) ), heatCook( rowKey = "cooking_sea_turtle", raw = "items.raw_seaturtle", cooked = "items.seaturtle", burnt = "items.burnt_seaturtle", - level = 82, - xp = 211, - stopBurnFire = 100, - stopBurnRange = 100 + level = 82, xp = 211, stopBurnFire = 100, stopBurnRange = 100, + chances = listOf( + chance("fire", STATION_FIRE, low = 1, high = 202), + chance("range", STATION_RANGE, low = 1, high = 222), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 13, high = 234), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 26, high = 247) + ) ), heatCook( rowKey = "cooking_anglerfish", raw = "items.raw_anglerfish", cooked = "items.anglerfish", burnt = "items.burnt_anglerfish", - level = 84, - xp = 230, - stopBurnFire = 100, - stopBurnRange = 100 + level = 84, xp = 230, stopBurnFire = 100, stopBurnRange = 100, + chances = listOf( + chance("fire", STATION_FIRE, low = 1, high = 200), + chance("range", STATION_RANGE, low = 1, high = 220), + chance("gauntlets", STATION_ANY, modifierMask = GAUNTLETS, low = 12, high = 260), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 13, high = 232), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 26, high = 245), + chance("hosidius_5_gauntlets", STATION_RANGE, modifierMask = HOSIDIUS_5 or GAUNTLETS, low = 24, high = 272), + chance("hosidius_10_gauntlets", STATION_RANGE, modifierMask = HOSIDIUS_10 or GAUNTLETS, low = 37, high = 285) + ) ), heatCook( rowKey = "cooking_dark_crab", raw = "items.raw_dark_crab", cooked = "items.dark_crab", burnt = "items.burnt_dark_crab", - level = 90, - xp = 215, - stopBurnFire = 100, - stopBurnRange = 100 + level = 90, xp = 215, stopBurnFire = 100, stopBurnRange = 100, + chances = listOf( + chance("base_any", STATION_ANY, low = 10, high = 222), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 22, high = 234), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 35, high = 247) + ) ), heatCook( rowKey = "cooking_manta_ray", raw = "items.raw_mantaray", cooked = "items.mantaray", burnt = "items.burnt_mantaray", - level = 91, - xp = 216, - stopBurnFire = 100, - stopBurnRange = 100 + level = 91, xp = 216, stopBurnFire = 100, stopBurnRange = 100, + chances = listOf( + chance("fire", STATION_FIRE, low = 1, high = 202), + chance("range", STATION_RANGE, low = 1, high = 222), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 13, high = 234), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 26, high = 247) + ) ), + + // ---- Special fish ---- heatCook( rowKey = "cooking_karambwan", raw = "items.tbwt_raw_karambwan", cooked = "items.tbwt_cooked_karambwan", burnt = "items.tbwt_burnt_karambwan", - level = 30, - xp = 190, - stopBurnFire = 99, - stopBurnRange = 93 + level = 30, xp = 190, stopBurnFire = 99, stopBurnRange = 93, + chances = listOf( + chance("base_any", STATION_ANY, low = 70, high = 255), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 82, high = 267), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 95, high = 280) + ) ), heatCook( rowKey = "cooking_rainbow_fish", raw = "items.hunting_raw_fish_special", cooked = "items.hunting_fish_special", burnt = "items.burntfish2", - level = 35, - xp = 110, - stopBurnFire = 64, - stopBurnRange = 60 + level = 35, xp = 110, stopBurnFire = 64, stopBurnRange = 60, + chances = listOf( + chance("base_any", STATION_ANY, low = 56, high = 370), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 68, high = 382), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 81, high = 395) + ) ), heatCook( rowKey = "cooking_cave_eel", raw = "items.raw_cave_eel", cooked = "items.cave_eel", burnt = "items.burnt_cave_eel", - level = 38, - xp = 115, - stopBurnFire = 74, - stopBurnRange = 70 + level = 38, xp = 115, stopBurnFire = 74, stopBurnRange = 70, + chances = listOf( + chance("base_any", STATION_ANY, low = 38, high = 332), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 50, high = 344), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 63, high = 357) + ) ), - // --- Snails (fire-only, Morytania) --- + // ---- Snails ---- heatCook( rowKey = "cooking_thin_snail", raw = "items.snail_corpse1", cooked = "items.snail_corpse_cooked1", burnt = "items.burnt_snail", - level = 12, - xp = 70, - stopBurnFire = 47, - stopBurnRange = 47, - stationMask = STATION_FIRE + level = 12, xp = 70, stopBurnFire = 47, stopBurnRange = 47, + stationMask = STATION_FIRE, + chances = listOf( + chance("base_any", STATION_ANY, low = 93, high = 444), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 103, high = 464), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 105, high = 456), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 118, high = 469) + ) ), heatCook( rowKey = "cooking_lean_snail", raw = "items.snail_corpse2", cooked = "items.snail_corpse_cooked2", burnt = "items.burnt_snail", - level = 17, - xp = 80, - stopBurnFire = 47, - stopBurnRange = 50 + level = 17, xp = 80, stopBurnFire = 47, stopBurnRange = 50, + chances = listOf( + chance("fire", STATION_FIRE, low = 93, high = 444), + chance("range", STATION_RANGE, low = 85, high = 428), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 95, high = 448), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 97, high = 440), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 110, high = 453) + ) ), heatCook( rowKey = "cooking_fat_snail", raw = "items.snail_corpse3", cooked = "items.snail_corpse_cooked3", burnt = "items.burnt_snail", - level = 22, - xp = 95, - stopBurnFire = 56, - stopBurnRange = 56, - stationMask = STATION_FIRE + level = 22, xp = 95, stopBurnFire = 56, stopBurnRange = 56, + stationMask = STATION_FIRE, + chances = listOf( + chance("base_any", STATION_ANY, low = 73, high = 402), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 83, high = 422), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 85, high = 414), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 98, high = 427) + ) ) ) } diff --git a/cache/bin/main/org/alter/impl/skills/cooking/recipes/MeatRecipes.kt b/cache/bin/main/org/alter/impl/skills/cooking/recipes/MeatRecipes.kt index f33f9e63..5b9ac7ba 100644 --- a/cache/bin/main/org/alter/impl/skills/cooking/recipes/MeatRecipes.kt +++ b/cache/bin/main/org/alter/impl/skills/cooking/recipes/MeatRecipes.kt @@ -1,12 +1,21 @@ package org.alter.impl.skills.cooking.recipes import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.GAUNTLETS +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_10 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_5 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.LUMBRIDGE +import org.alter.impl.skills.cooking.CookingConstants.STATION_ANY import org.alter.impl.skills.cooking.CookingConstants.STATION_FIRE +import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE +import org.alter.impl.skills.cooking.CookingHelpers.chance import org.alter.impl.skills.cooking.CookingHelpers.heatCook import org.alter.impl.skills.cooking.CookingHelpers.spitRoast /** - * Meat cooking recipes - standard cooking and spit roasting. + * Meat cooking recipes — standard cooking and spit roasting. + * + * Chance profiles sourced from OSRS Wiki skill_chances data. */ object MeatRecipes { @@ -17,70 +26,88 @@ object MeatRecipes { raw = "items.raw_chompy", cooked = "items.cooked_chompy", burnt = "items.ruined_chompy", - level = 30, - xp = 100, - stopBurnFire = 63, - stopBurnRange = 63 + level = 30, xp = 100, stopBurnFire = 63, stopBurnRange = 63, + stationMask = STATION_FIRE, + chances = listOf( + chance("fire", STATION_FIRE, low = 200, high = 255) + ) ), heatCook( rowKey = "cooking_beef", raw = "items.raw_beef", cooked = "items.cooked_meat", burnt = "items.burnt_meat", - level = 1, - xp = 30, - stopBurnFire = 34, - stopBurnRange = 34 + level = 1, xp = 30, stopBurnFire = 34, stopBurnRange = 34, + chances = listOf( + chance("base_any", STATION_ANY, low = 128, high = 512), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 138, high = 532), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 140, high = 524), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 153, high = 537) + ) ), heatCook( rowKey = "cooking_chicken", raw = "items.raw_chicken", cooked = "items.cooked_chicken", burnt = "items.burnt_chicken", - level = 1, - xp = 30, - stopBurnFire = 34, - stopBurnRange = 34 + level = 1, xp = 30, stopBurnFire = 34, stopBurnRange = 34, + chances = listOf( + chance("base_any", STATION_ANY, low = 128, high = 512), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 138, high = 532), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 140, high = 524), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 153, high = 537) + ) ), heatCook( rowKey = "cooking_rat_meat", raw = "items.raw_rat_meat", cooked = "items.cooked_meat", burnt = "items.burnt_meat", - level = 1, - xp = 30, - stopBurnFire = 34, - stopBurnRange = 34 + level = 1, xp = 30, stopBurnFire = 34, stopBurnRange = 34, + chances = listOf( + chance("base_any", STATION_ANY, low = 128, high = 512), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 138, high = 532), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 140, high = 524), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 153, high = 537) + ) ), heatCook( rowKey = "cooking_bear_meat", raw = "items.raw_bear_meat", cooked = "items.cooked_meat", burnt = "items.burnt_meat", - level = 1, - xp = 30, - stopBurnFire = 34, - stopBurnRange = 34 + level = 1, xp = 30, stopBurnFire = 34, stopBurnRange = 34, + chances = listOf( + chance("base_any", STATION_ANY, low = 128, high = 512), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 138, high = 532), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 140, high = 524), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 153, high = 537) + ) ), heatCook( rowKey = "cooking_rabbit", raw = "items.raw_rabbit", cooked = "items.cooked_rabbit", burnt = "items.burnt_meat", - level = 1, - xp = 30, - stopBurnFire = 34, - stopBurnRange = 34 + level = 1, xp = 30, stopBurnFire = 34, stopBurnRange = 34, + chances = listOf( + chance("base_any", STATION_ANY, low = 128, high = 512), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 140, high = 524), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 153, high = 537) + ) ), heatCook( rowKey = "cooking_ugthanki_meat", raw = "items.raw_ugthanki_meat", cooked = "items.cooked_ugthanki_meat", burnt = "items.burnt_meat", - level = 1, - xp = 40, - stopBurnFire = 34, - stopBurnRange = 34 + level = 1, xp = 40, stopBurnFire = 34, stopBurnRange = 34, + chances = listOf( + chance("fire", STATION_FIRE, low = 40, high = 252), + chance("range", STATION_RANGE, low = 30, high = 253), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 42, high = 265), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 55, high = 278) + ) ) ) @@ -93,10 +120,8 @@ object MeatRecipes { skewered = "items.spit_skewered_bird_meat", cooked = "items.spit_roasted_bird_meat", burnt = "items.spit_burned_bird_meat", - cookingLevel = 11, - xp = 60, - stopBurnFire = 44, - stopBurnRange = 44 + cookingLevel = 11, xp = 60, stopBurnFire = 44, stopBurnRange = 44, + chances = listOf(chance("fire", STATION_FIRE, low = 155, high = 255)) ) + spitRoast( skewerRowKey = "cooking_skewer_beast_meat", @@ -105,10 +130,8 @@ object MeatRecipes { skewered = "items.spit_skewered_beast_meat", cooked = "items.spit_roasted_beast_meat", burnt = "items.spit_burned_beast_meat", - cookingLevel = 21, - xp = 82, - stopBurnFire = 55, - stopBurnRange = 55 + cookingLevel = 21, xp = 82, stopBurnFire = 55, stopBurnRange = 55, + chances = listOf(chance("fire", STATION_FIRE, low = 180, high = 255)) ) + spitRoast( skewerRowKey = "cooking_skewer_rabbit_meat", @@ -117,15 +140,12 @@ object MeatRecipes { skewered = "items.spit_skewered_rabbit_meat", cooked = "items.spit_roasted_rabbit_meat", burnt = "items.spit_burned_rabbit_meat", - cookingLevel = 16, - xp = 70, - stopBurnFire = 99, - stopBurnRange = 99 + cookingLevel = 16, xp = 70, stopBurnFire = 99, stopBurnRange = 99, + chances = listOf(chance("fire", STATION_FIRE, low = 160, high = 255)) ) /** * Hunter meat recipes — meats obtained from pitfall trapping. - * These are standard heatCook recipes; some are fire-only. * * Note: Small kebbits (wild, barb-tailed, dashing) are eaten raw and do NOT * require cooking. Only pitfall-trapped animals have raw→cooked transitions. @@ -136,62 +156,79 @@ object MeatRecipes { raw = "items.hunting_larupia_meat", cooked = "items.larupia_cooked", burnt = "items.burnt_largebeast", - level = 31, - xp = 92, - stopBurnFire = 59, - stopBurnRange = 59, - stationMask = STATION_FIRE + level = 31, xp = 92, stopBurnFire = 59, stopBurnRange = 59, + stationMask = STATION_FIRE, + chances = listOf( + chance("base_any", STATION_ANY, low = 65, high = 390), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 77, high = 402), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 90, high = 415) + ) ), heatCook( rowKey = "cooking_graahk", raw = "items.hunting_graahk_meat", cooked = "items.graahk_cooked", burnt = "items.burnt_largebeast", - level = 41, - xp = 124, - stopBurnFire = 75, - stopBurnRange = 75, - stationMask = STATION_FIRE + level = 41, xp = 124, stopBurnFire = 75, stopBurnRange = 75, + stationMask = STATION_FIRE, + chances = listOf( + chance("base_any", STATION_ANY, low = 32, high = 328), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 44, high = 340), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 57, high = 353) + ) ), heatCook( rowKey = "cooking_kyatt", raw = "items.hunting_kyatt_meat", cooked = "items.kyatt_cooked", burnt = "items.burnt_largebeast", - level = 51, - xp = 143, - stopBurnFire = 86, - stopBurnRange = 80 + level = 51, xp = 143, stopBurnFire = 86, stopBurnRange = 80, + chances = listOf( + chance("fire", STATION_FIRE, low = 18, high = 292), + chance("range", STATION_RANGE, low = 30, high = 310), + chance("gauntlets", STATION_ANY, modifierMask = GAUNTLETS, low = 30, high = 310), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 42, high = 322), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 55, high = 335) + ) ), heatCook( rowKey = "cooking_pyre_fox", raw = "items.hunting_fennecfox_meat", cooked = "items.fennecfox_cooked", burnt = "items.burnt_foxmeat", - level = 59, - xp = 154, - stopBurnFire = 93, - stopBurnRange = 92 + level = 59, xp = 154, stopBurnFire = 93, stopBurnRange = 92, + chances = listOf( + chance("fire", STATION_FIRE, low = 10, high = 273), + chance("range", STATION_RANGE, low = 11, high = 276), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 23, high = 288), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 36, high = 301) + ) ), heatCook( rowKey = "cooking_sunlight_antelope", raw = "items.hunting_antelopesun_meat", cooked = "items.antelopesun_cooked", burnt = "items.burnt_antelope", - level = 68, - xp = 175, - stopBurnFire = 100, - stopBurnRange = 95 + level = 68, xp = 175, stopBurnFire = 100, stopBurnRange = 95, + chances = listOf( + chance("fire", STATION_FIRE, low = 8, high = 254), + chance("range", STATION_RANGE, low = 8, high = 265), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 20, high = 277), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 33, high = 290) + ) ), heatCook( rowKey = "cooking_moonlight_antelope", raw = "items.hunting_antelopemoon_meat", cooked = "items.antelopemoon_cooked", burnt = "items.burnt_antelope", - level = 92, - xp = 220, - stopBurnFire = 100, - stopBurnRange = 100 + level = 92, xp = 220, stopBurnFire = 100, stopBurnRange = 100, + chances = listOf( + chance("fire", STATION_FIRE, low = 1, high = 185), + chance("range", STATION_RANGE, low = 1, high = 200), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 13, high = 212), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 26, high = 225) + ) ) ) diff --git a/cache/bin/main/org/alter/impl/skills/cooking/recipes/MiscFoodRecipes.kt b/cache/bin/main/org/alter/impl/skills/cooking/recipes/MiscFoodRecipes.kt index 7e2359e7..e34c1b8d 100644 --- a/cache/bin/main/org/alter/impl/skills/cooking/recipes/MiscFoodRecipes.kt +++ b/cache/bin/main/org/alter/impl/skills/cooking/recipes/MiscFoodRecipes.kt @@ -1,6 +1,11 @@ package org.alter.impl.skills.cooking.recipes import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_10 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_5 +import org.alter.impl.skills.cooking.CookingConstants.STATION_ANY +import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE +import org.alter.impl.skills.cooking.CookingHelpers.chance import org.alter.impl.skills.cooking.CookingHelpers.heatCook import org.alter.impl.skills.cooking.CookingHelpers.multiStepCook import org.alter.impl.skills.cooking.PrepStepDef @@ -17,10 +22,12 @@ object MiscFoodRecipes { raw = "items.sweetcorn", cooked = "items.sweetcorn_cooked", burnt = "items.sweetcorn_burnt", - level = 28, - xp = 104, - stopBurnFire = 61, - stopBurnRange = 61 + level = 28, xp = 104, stopBurnFire = 61, stopBurnRange = 61, + chances = listOf( + chance("base_any", STATION_ANY, low = 78, high = 412), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 90, high = 424), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 103, high = 437) + ) ) ) @@ -44,10 +51,13 @@ object MiscFoodRecipes { raw = "items.bowl_egg_raw", cooked = "items.bowl_egg_scrambled", burnt = "items.bowl_egg_burnt", - level = 13, - xp = 50, - stopBurnFire = 46, - stopBurnRange = 46 + level = 13, xp = 50, stopBurnFire = 46, stopBurnRange = 46, + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 90, high = 438), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 102, high = 450), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 115, high = 463) + ) ) ) @@ -58,10 +68,12 @@ object MiscFoodRecipes { raw = "items.bowl_onion", cooked = "items.bowl_onion_fried", burnt = "items.bowl_onion_burnt", - level = 42, - xp = 60, - stopBurnFire = 74, - stopBurnRange = 74 + level = 42, xp = 60, stopBurnFire = 74, stopBurnRange = 74, + chances = listOf( + chance("base_any", STATION_ANY, low = 36, high = 322), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 48, high = 334), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 61, high = 347) + ) ) ) @@ -72,10 +84,12 @@ object MiscFoodRecipes { raw = "items.bowl_mushroom_raw", cooked = "items.bowl_mushroom_fried", burnt = "items.bowl_mushroom_burnt", - level = 46, - xp = 60, - stopBurnFire = 80, - stopBurnRange = 80 + level = 46, xp = 60, stopBurnFire = 80, stopBurnRange = 80, + chances = listOf( + chance("base_any", STATION_ANY, low = 16, high = 282), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 28, high = 294), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 41, high = 307) + ) ) ) diff --git a/cache/bin/main/org/alter/impl/skills/cooking/recipes/PieRecipes.kt b/cache/bin/main/org/alter/impl/skills/cooking/recipes/PieRecipes.kt index dfcf0ddf..2bdf04a4 100644 --- a/cache/bin/main/org/alter/impl/skills/cooking/recipes/PieRecipes.kt +++ b/cache/bin/main/org/alter/impl/skills/cooking/recipes/PieRecipes.kt @@ -1,7 +1,11 @@ package org.alter.impl.skills.cooking.recipes import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_10 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_5 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.LUMBRIDGE import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE +import org.alter.impl.skills.cooking.CookingHelpers.chance import org.alter.impl.skills.cooking.CookingHelpers.multiStepCook import org.alter.impl.skills.cooking.HeatStepDef import org.alter.impl.skills.cooking.PrepStepDef @@ -37,7 +41,13 @@ object PieRecipes { xp = 78, stopBurnFire = 44, stopBurnRange = 44, - stationMask = STATION_RANGE + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 98, high = 452), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 108, high = 462), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 110, high = 464), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 123, high = 477) + ) ) ) @@ -63,7 +73,13 @@ object PieRecipes { xp = 110, stopBurnFire = 54, stopBurnRange = 54, - stationMask = STATION_RANGE + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 78, high = 412), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 88, high = 432), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 90, high = 424), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 103, high = 437) + ) ) ) @@ -106,7 +122,12 @@ object PieRecipes { xp = 128, stopBurnFire = 63, stopBurnRange = 63, - stationMask = STATION_RANGE + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 58, high = 372), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 70, high = 384), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 83, high = 397) + ) ) ) @@ -132,7 +153,12 @@ object PieRecipes { xp = 130, stopBurnFire = 64, stopBurnRange = 64, - stationMask = STATION_RANGE + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 58, high = 372), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 70, high = 384), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 83, high = 397) + ) ) ) @@ -174,7 +200,12 @@ object PieRecipes { xp = 164, stopBurnFire = 81, stopBurnRange = 81, - stationMask = STATION_RANGE + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 38, high = 332), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 50, high = 344), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 63, high = 357) + ) ) ) @@ -200,7 +231,13 @@ object PieRecipes { xp = 180, stopBurnFire = 86, stopBurnRange = 86, - stationMask = STATION_RANGE + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 20, high = 300), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 108, high = 462), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 32, high = 312), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 45, high = 325) + ) ) ) @@ -226,7 +263,13 @@ object PieRecipes { xp = 200, stopBurnFire = 94, stopBurnRange = 94, - stationMask = STATION_RANGE + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 17, high = 285), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 140, high = 450), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 29, high = 297), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 42, high = 310) + ) ) ) @@ -268,7 +311,12 @@ object PieRecipes { xp = 210, stopBurnFire = 100, stopBurnRange = 94, - stationMask = STATION_RANGE + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 15, high = 270), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 27, high = 282), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 40, high = 295) + ) ) ) @@ -294,7 +342,12 @@ object PieRecipes { xp = 220, stopBurnFire = 100, stopBurnRange = 97, - stationMask = STATION_RANGE + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 8, high = 250), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 20, high = 262), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 33, high = 275) + ) ) ) @@ -336,7 +389,12 @@ object PieRecipes { xp = 240, stopBurnFire = 100, stopBurnRange = 100, - stationMask = STATION_RANGE + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 1, high = 222), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 13, high = 234), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 26, high = 247) + ) ) ) @@ -378,7 +436,12 @@ object PieRecipes { xp = 260, stopBurnFire = 100, stopBurnRange = 100, - stationMask = STATION_RANGE + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 1, high = 212), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 13, high = 224), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 26, high = 237) + ) ) ) diff --git a/cache/bin/main/org/alter/impl/skills/cooking/recipes/PizzaRecipes.kt b/cache/bin/main/org/alter/impl/skills/cooking/recipes/PizzaRecipes.kt index 6977ce15..f6f4dd54 100644 --- a/cache/bin/main/org/alter/impl/skills/cooking/recipes/PizzaRecipes.kt +++ b/cache/bin/main/org/alter/impl/skills/cooking/recipes/PizzaRecipes.kt @@ -1,7 +1,10 @@ package org.alter.impl.skills.cooking.recipes import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_10 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_5 import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE +import org.alter.impl.skills.cooking.CookingHelpers.chance import org.alter.impl.skills.cooking.CookingHelpers.multiStepCook import org.alter.impl.skills.cooking.HeatStepDef import org.alter.impl.skills.cooking.PrepStepDef @@ -43,7 +46,12 @@ object PizzaRecipes { xp = 143, stopBurnFire = 68, stopBurnRange = 68, - stationMask = STATION_RANGE + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 48, high = 352), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 60, high = 364), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 73, high = 377) + ) ) ) diff --git a/cache/bin/main/org/alter/impl/skills/cooking/recipes/PotatoRecipes.kt b/cache/bin/main/org/alter/impl/skills/cooking/recipes/PotatoRecipes.kt index 0898a906..795b3b27 100644 --- a/cache/bin/main/org/alter/impl/skills/cooking/recipes/PotatoRecipes.kt +++ b/cache/bin/main/org/alter/impl/skills/cooking/recipes/PotatoRecipes.kt @@ -1,7 +1,10 @@ package org.alter.impl.skills.cooking.recipes import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_10 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_5 import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE +import org.alter.impl.skills.cooking.CookingHelpers.chance import org.alter.impl.skills.cooking.CookingHelpers.heatCook import org.alter.impl.skills.cooking.CookingHelpers.multiStepCook import org.alter.impl.skills.cooking.HeatStepDef @@ -19,11 +22,13 @@ object PotatoRecipes { raw = "items.potato", cooked = "items.potato_baked", burnt = "items.potato_burnt", - level = 7, - xp = 15, - stopBurnFire = 40, - stopBurnRange = 40, - stationMask = STATION_RANGE + level = 7, xp = 15, stopBurnFire = 40, stopBurnRange = 40, + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 108, high = 472), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 120, high = 484), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 133, high = 497) + ) ) ) diff --git a/cache/bin/main/org/alter/impl/skills/cooking/recipes/StewRecipes.kt b/cache/bin/main/org/alter/impl/skills/cooking/recipes/StewRecipes.kt index fcc11eb7..590ffca9 100644 --- a/cache/bin/main/org/alter/impl/skills/cooking/recipes/StewRecipes.kt +++ b/cache/bin/main/org/alter/impl/skills/cooking/recipes/StewRecipes.kt @@ -1,6 +1,12 @@ package org.alter.impl.skills.cooking.recipes import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_10 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_5 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.LUMBRIDGE +import org.alter.impl.skills.cooking.CookingConstants.STATION_ANY +import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE +import org.alter.impl.skills.cooking.CookingHelpers.chance import org.alter.impl.skills.cooking.CookingHelpers.multiStepCook import org.alter.impl.skills.cooking.HeatStepDef import org.alter.impl.skills.cooking.PrepStepDef @@ -39,7 +45,13 @@ object StewRecipes { burnt = "items.burnt_stew", xp = 117, stopBurnFire = 58, - stopBurnRange = 58 + stopBurnRange = 58, + chances = listOf( + chance("base_any", STATION_ANY, low = 68, high = 392), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 78, high = 412), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 80, high = 404), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 93, high = 417) + ) ) ) @@ -80,7 +92,12 @@ object StewRecipes { burnt = "items.burnt_curry", xp = 280, stopBurnFire = 74, - stopBurnRange = 74 + stopBurnRange = 74, + chances = listOf( + chance("base_any", STATION_ANY, low = 38, high = 332), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 50, high = 344), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 63, high = 357) + ) ) ) diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingConstants.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingConstants.kt index ce34972d..880f38eb 100644 --- a/cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingConstants.kt +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingConstants.kt @@ -38,4 +38,21 @@ object CookingConstants { /** Station mask for cooking on both fire and range. */ const val STATION_ANY = STATION_FIRE or STATION_RANGE + + /** + * Modifier flags for burn chance profiles. + * Combined as bitmasks to represent equipment/location bonuses. + */ + object ChanceModifier { + /** No modifier (base chance). */ + const val NONE = 0 + /** Cooking gauntlets equipped. */ + const val GAUNTLETS = 1 + /** Hosidius Kitchen range (+5% burn reduction). */ + const val HOSIDIUS_5 = 2 + /** Hosidius Kitchen range with Kourend Hard Diary (+10% burn reduction). */ + const val HOSIDIUS_10 = 4 + /** Lumbridge Castle range (reduced burn for low-level foods). */ + const val LUMBRIDGE = 8 + } } diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingHelpers.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingHelpers.kt index 309c37f7..2fc839fb 100644 --- a/cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingHelpers.kt +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingHelpers.kt @@ -12,17 +12,24 @@ import org.alter.impl.skills.cooking.CookingConstants.Trigger object CookingHelpers { /** - * Creates a simple heat-cooking action (raw -> cooked/burnt). + * Creates a [ChanceDef] for burn chance profile definitions. * - * @param rowKey DB row key suffix (e.g., "cooking_shrimps"). - * @param raw RSCM key for the raw item. - * @param cooked RSCM key for the cooked item. - * @param burnt RSCM key for the burnt item. - * @param level Required Cooking level. - * @param xp Experience awarded on success. - * @param stopBurnFire Level at which burning stops on fires. - * @param stopBurnRange Level at which burning stops on ranges. - * @param stationMask Bitmask for allowed cooking stations. + * @param label Human-readable label (e.g., "base_any", "gauntlets", "hosidius_5"). + * @param stationMask Bitmask of stations this profile applies to. + * @param modifierMask Bitmask of required modifiers (default: none). + * @param low The low value for the statrandom calculation. + * @param high The high value for the statrandom calculation. + */ + fun chance( + label: String, + stationMask: Int, + modifierMask: Int = 0, + low: Int, + high: Int + ): ChanceDef = ChanceDef(label, stationMask, modifierMask, low, high) + + /** + * Creates a simple heat-cooking action (raw -> cooked/burnt). */ fun heatCook( rowKey: String, @@ -31,9 +38,10 @@ object CookingHelpers { burnt: String, level: Int, xp: Int, - stopBurnFire: Int, - stopBurnRange: Int, - stationMask: Int = STATION_ANY + stopBurnFire: Int = 0, + stopBurnRange: Int = 0, + stationMask: Int = STATION_ANY, + chances: List = emptyList() ): ActionDef = ActionDef( rowId = "dbrows.$rowKey", key = raw, @@ -46,7 +54,8 @@ object CookingHelpers { outcomes = listOf( OutcomeDef(rowSuffix = "success", kind = OutcomeKind.SUCCESS, item = cooked, xp = xp, weight = 1), OutcomeDef(rowSuffix = "fail", kind = OutcomeKind.FAIL, item = burnt, xp = 0, weight = 1) - ) + ), + chances = chances ) /** @@ -73,9 +82,10 @@ object CookingHelpers { burnt: String, cookingLevel: Int, xp: Int, - stopBurnFire: Int, - stopBurnRange: Int, - spitItem: String = "items.spit_iron" + stopBurnFire: Int = 0, + stopBurnRange: Int = 0, + spitItem: String = "items.spit_iron", + chances: List = emptyList() ): List = listOf( // Raw meat + iron spit -> skewered meat (inventory prep step) ActionDef( @@ -110,7 +120,8 @@ object CookingHelpers { outcomes = listOf( OutcomeDef(rowSuffix = "success", kind = OutcomeKind.SUCCESS, item = cooked, xp = xp, weight = 1), OutcomeDef(rowSuffix = "fail", kind = OutcomeKind.FAIL, item = burnt, xp = 0, weight = 1) - ) + ), + chances = chances ) ) @@ -208,7 +219,8 @@ object CookingHelpers { xp = 0, weight = 1 ) - ) + alwaysOutcomes + ) + alwaysOutcomes, + chances = step.chances ) ) } diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingModels.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingModels.kt index 19d8e7c4..40ee6df4 100644 --- a/cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingModels.kt +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingModels.kt @@ -4,6 +4,27 @@ package org.alter.impl.skills.cooking * Data models for cooking recipe definitions. */ +/** + * Defines a burn chance profile for a specific station and modifier combination. + * + * At runtime, the system selects the most specific matching profile based on the + * player's station and active modifiers, then uses [low]/[high] with the + * `computeSkillingSuccess` function to determine burn probability. + * + * @property label Human-readable label for this profile (e.g., "base_any", "gauntlets"). + * @property stationMask Bitmask of stations this profile applies to. + * @property modifierMask Bitmask of required modifiers (see [CookingConstants.ChanceModifier]). + * @property low The low value for the statrandom calculation. + * @property high The high value for the statrandom calculation. + */ +data class ChanceDef( + val label: String, + val stationMask: Int, + val modifierMask: Int = 0, + val low: Int, + val high: Int +) + /** * Defines an input ingredient for a cooking action. * @@ -55,12 +76,13 @@ data class ActionDef( val key: String, val variant: Int = CookingConstants.DEFAULT_VARIANT, val level: Int, - val stopBurnFire: Int, - val stopBurnRange: Int, + val stopBurnFire: Int = 0, + val stopBurnRange: Int = 0, val stationMask: Int = CookingConstants.STATION_ANY, val trigger: Int = CookingConstants.Trigger.HEAT_SOURCE, val inputs: List, - val outcomes: List + val outcomes: List, + val chances: List = emptyList() ) /** @@ -99,8 +121,9 @@ data class HeatStepDef( val cooked: String, val burnt: String, val xp: Int, - val stopBurnFire: Int, - val stopBurnRange: Int, + val stopBurnFire: Int = 0, + val stopBurnRange: Int = 0, val stationMask: Int = CookingConstants.STATION_ANY, - val always: List> = emptyList() + val always: List> = emptyList(), + val chances: List = emptyList() ) diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/BakedGoodsRecipes.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/BakedGoodsRecipes.kt index e25ce387..a2298457 100644 --- a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/BakedGoodsRecipes.kt +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/BakedGoodsRecipes.kt @@ -1,7 +1,10 @@ package org.alter.impl.skills.cooking.recipes import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_10 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_5 import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE +import org.alter.impl.skills.cooking.CookingHelpers.chance import org.alter.impl.skills.cooking.CookingHelpers.multiStepCook import org.alter.impl.skills.cooking.HeatStepDef import org.alter.impl.skills.cooking.PrepStepDef @@ -49,7 +52,12 @@ object BakedGoodsRecipes { xp = 138, stopBurnFire = 68, stopBurnRange = 64, - stationMask = STATION_RANGE + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 48, high = 352), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 60, high = 364), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 73, high = 377) + ) ) ) @@ -84,6 +92,11 @@ object BakedGoodsRecipes { stationMask = STATION_RANGE, always = listOf( "items.cake_tin" to 1 + ), + chances = listOf( + chance("range", STATION_RANGE, low = 38, high = 332), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 50, high = 344), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 63, high = 357) ) ) ) diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/BreadRecipes.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/BreadRecipes.kt index 9b75e9b7..879233fe 100644 --- a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/BreadRecipes.kt +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/BreadRecipes.kt @@ -1,11 +1,17 @@ package org.alter.impl.skills.cooking.recipes import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_10 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_5 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.LUMBRIDGE import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE +import org.alter.impl.skills.cooking.CookingHelpers.chance import org.alter.impl.skills.cooking.CookingHelpers.heatCook /** * Bread cooking recipes — baked on a range. + * + * Chance profiles sourced from OSRS Wiki skill_chances data. */ object BreadRecipes { @@ -15,22 +21,27 @@ object BreadRecipes { raw = "items.bread_dough", cooked = "items.bread", burnt = "items.burnt_bread", - level = 1, - xp = 40, - stopBurnFire = 35, - stopBurnRange = 35, - stationMask = STATION_RANGE + level = 1, xp = 40, stopBurnFire = 35, stopBurnRange = 35, + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 118, high = 492), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 128, high = 512), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 130, high = 504), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 143, high = 517) + ) ), heatCook( rowKey = "cooking_pitta_bread", raw = "items.uncooked_pitta_bread", cooked = "items.pitta_bread", burnt = "items.burnt_pitta_bread", - level = 58, - xp = 40, - stopBurnFire = 82, - stopBurnRange = 82, - stationMask = STATION_RANGE + level = 58, xp = 40, stopBurnFire = 82, stopBurnRange = 82, + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 118, high = 492), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 130, high = 504), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 143, high = 517) + ) ) ) } diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/FishRecipes.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/FishRecipes.kt index 4930362c..1b324950 100644 --- a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/FishRecipes.kt +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/FishRecipes.kt @@ -1,278 +1,381 @@ package org.alter.impl.skills.cooking.recipes import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.GAUNTLETS +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_10 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_5 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.LUMBRIDGE +import org.alter.impl.skills.cooking.CookingConstants.STATION_ANY import org.alter.impl.skills.cooking.CookingConstants.STATION_FIRE +import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE +import org.alter.impl.skills.cooking.CookingHelpers.chance import org.alter.impl.skills.cooking.CookingHelpers.heatCook /** - * Fish cooking recipes - standard heat-source cooking. + * Fish cooking recipes — standard heat-source cooking. + * + * Chance profiles sourced from OSRS Wiki skill_chances data. */ object FishRecipes { val recipes: List = listOf( + // ---- Low-level fish (shared fire/range curve + Lumbridge) ---- heatCook( rowKey = "cooking_shrimps", raw = "items.raw_shrimp", cooked = "items.shrimp", burnt = "items.burnt_shrimp", - level = 1, - xp = 30, - stopBurnFire = 34, - stopBurnRange = 34 + level = 1, xp = 30, stopBurnFire = 34, stopBurnRange = 34, + chances = listOf( + chance("base_any", STATION_ANY, low = 128, high = 512), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 138, high = 532), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 140, high = 524), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 153, high = 537) + ) ), heatCook( rowKey = "cooking_anchovies", raw = "items.raw_anchovies", cooked = "items.anchovies", burnt = "items.burntfish1", - level = 1, - xp = 30, - stopBurnFire = 34, - stopBurnRange = 34 + level = 1, xp = 30, stopBurnFire = 34, stopBurnRange = 34, + chances = listOf( + chance("base_any", STATION_ANY, low = 128, high = 512), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 138, high = 532), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 140, high = 524), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 153, high = 537) + ) ), heatCook( rowKey = "cooking_sardine", raw = "items.raw_sardine", cooked = "items.sardine", burnt = "items.burntfish5", - level = 1, - xp = 40, - stopBurnFire = 38, - stopBurnRange = 38 + level = 1, xp = 40, stopBurnFire = 38, stopBurnRange = 38, + chances = listOf( + chance("base_any", STATION_ANY, low = 118, high = 492), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 128, high = 512), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 130, high = 504), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 143, high = 517) + ) ), heatCook( rowKey = "cooking_herring", raw = "items.raw_herring", cooked = "items.herring", burnt = "items.burntfish3", - level = 5, - xp = 50, - stopBurnFire = 41, - stopBurnRange = 41 + level = 5, xp = 50, stopBurnFire = 41, stopBurnRange = 41, + chances = listOf( + chance("base_any", STATION_ANY, low = 108, high = 472), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 118, high = 492), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 120, high = 484), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 133, high = 497) + ) ), heatCook( rowKey = "cooking_mackerel", raw = "items.raw_mackerel", cooked = "items.mackerel", burnt = "items.burntfish3", - level = 10, - xp = 60, - stopBurnFire = 45, - stopBurnRange = 45 + level = 10, xp = 60, stopBurnFire = 45, stopBurnRange = 45, + chances = listOf( + chance("base_any", STATION_ANY, low = 98, high = 452), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 108, high = 472), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 110, high = 464), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 123, high = 477) + ) ), heatCook( rowKey = "cooking_trout", raw = "items.raw_trout", cooked = "items.trout", burnt = "items.burntfish2", - level = 15, - xp = 70, - stopBurnFire = 49, - stopBurnRange = 49 + level = 15, xp = 70, stopBurnFire = 49, stopBurnRange = 49, + chances = listOf( + chance("base_any", STATION_ANY, low = 88, high = 432), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 98, high = 452), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 100, high = 444), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 113, high = 457) + ) ), + + // ---- Mid-level fish ---- heatCook( rowKey = "cooking_cod", raw = "items.raw_cod", cooked = "items.cod", burnt = "items.burntfish2", - level = 18, - xp = 75, - stopBurnFire = 51, - stopBurnRange = 49 + level = 18, xp = 75, stopBurnFire = 51, stopBurnRange = 49, + chances = listOf( + chance("fire", STATION_FIRE, low = 83, high = 422), + chance("range", STATION_RANGE, low = 88, high = 432), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 93, high = 442), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 100, high = 444), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 113, high = 457) + ) ), heatCook( rowKey = "cooking_pike", raw = "items.raw_pike", cooked = "items.pike", burnt = "items.burntfish5", - level = 20, - xp = 80, - stopBurnFire = 54, - stopBurnRange = 54 + level = 20, xp = 80, stopBurnFire = 54, stopBurnRange = 54, + chances = listOf( + chance("base_any", STATION_ANY, low = 78, high = 412), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 88, high = 432), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 90, high = 424), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 103, high = 437) + ) ), heatCook( rowKey = "cooking_salmon", raw = "items.raw_salmon", cooked = "items.salmon", burnt = "items.burntfish2", - level = 25, - xp = 90, - stopBurnFire = 58, - stopBurnRange = 58 + level = 25, xp = 90, stopBurnFire = 58, stopBurnRange = 58, + chances = listOf( + chance("base_any", STATION_ANY, low = 68, high = 392), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 78, high = 402), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 80, high = 404), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 93, high = 417) + ) ), heatCook( rowKey = "cooking_slimy_eel", raw = "items.mort_slimey_eel", cooked = "items.mort_slimey_eel_cooked", burnt = "items.burnt_eel", - level = 28, - xp = 95, - stopBurnFire = 61, - stopBurnRange = 61 + level = 28, xp = 95, stopBurnFire = 61, stopBurnRange = 61, + chances = listOf( + chance("base_any", STATION_ANY, low = 63, high = 382), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 75, high = 394), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 88, high = 407) + ) ), heatCook( rowKey = "cooking_tuna", raw = "items.raw_tuna", cooked = "items.tuna", burnt = "items.burntfish4", - level = 30, - xp = 100, - stopBurnFire = 63, - stopBurnRange = 63 + level = 30, xp = 100, stopBurnFire = 63, stopBurnRange = 63, + chances = listOf( + chance("base_any", STATION_ANY, low = 58, high = 372), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 70, high = 384), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 83, high = 397) + ) ), + + // ---- Mid-high fish (gauntlet-affected) ---- heatCook( rowKey = "cooking_lobster", raw = "items.raw_lobster", cooked = "items.lobster", burnt = "items.burnt_lobster", - level = 40, - xp = 120, - stopBurnFire = 74, - stopBurnRange = 74 + level = 40, xp = 120, stopBurnFire = 74, stopBurnRange = 74, + chances = listOf( + chance("base_any", STATION_ANY, low = 38, high = 332), + chance("gauntlets", STATION_ANY, modifierMask = GAUNTLETS, low = 55, high = 368), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 50, high = 344), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 63, high = 357), + chance("hosidius_5_gauntlets", STATION_RANGE, modifierMask = HOSIDIUS_5 or GAUNTLETS, low = 67, high = 380), + chance("hosidius_10_gauntlets", STATION_RANGE, modifierMask = HOSIDIUS_10 or GAUNTLETS, low = 80, high = 393) + ) ), heatCook( rowKey = "cooking_bass", raw = "items.raw_bass", cooked = "items.bass", burnt = "items.burntfish3", - level = 43, - xp = 130, - stopBurnFire = 79, - stopBurnRange = 79 + level = 43, xp = 130, stopBurnFire = 79, stopBurnRange = 79, + chances = listOf( + chance("base_any", STATION_ANY, low = 33, high = 312), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 45, high = 324), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 58, high = 337) + ) ), heatCook( rowKey = "cooking_swordfish", raw = "items.raw_swordfish", cooked = "items.swordfish", burnt = "items.burnt_swordfish", - level = 45, - xp = 140, - stopBurnFire = 86, - stopBurnRange = 80 + level = 45, xp = 140, stopBurnFire = 86, stopBurnRange = 80, + chances = listOf( + chance("fire", STATION_FIRE, low = 18, high = 292), + chance("range", STATION_RANGE, low = 30, high = 310), + chance("gauntlets", STATION_ANY, modifierMask = GAUNTLETS, low = 30, high = 310), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 42, high = 322), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 55, high = 335) + ) ), + + // ---- High-level fish ---- heatCook( rowKey = "cooking_monkfish", raw = "items.raw_monkfish", cooked = "items.monkfish", burnt = "items.burnt_monkfish", - level = 62, - xp = 150, - stopBurnFire = 92, - stopBurnRange = 90 + level = 62, xp = 150, stopBurnFire = 92, stopBurnRange = 90, + chances = listOf( + chance("fire", STATION_FIRE, low = 11, high = 275), + chance("range", STATION_RANGE, low = 13, high = 280), + chance("gauntlets", STATION_ANY, modifierMask = GAUNTLETS, low = 24, high = 290), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 25, high = 292), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 38, high = 305), + chance("hosidius_5_gauntlets", STATION_RANGE, modifierMask = HOSIDIUS_5 or GAUNTLETS, low = 36, high = 302), + chance("hosidius_10_gauntlets", STATION_RANGE, modifierMask = HOSIDIUS_10 or GAUNTLETS, low = 49, high = 315) + ) ), heatCook( rowKey = "cooking_shark", raw = "items.raw_shark", cooked = "items.shark", burnt = "items.burnt_shark", - level = 80, - xp = 210, - stopBurnFire = 100, - stopBurnRange = 100 + level = 80, xp = 210, stopBurnFire = 100, stopBurnRange = 100, + chances = listOf( + chance("fire", STATION_FIRE, low = 1, high = 202), + chance("range", STATION_RANGE, low = 1, high = 232), + chance("gauntlets", STATION_ANY, modifierMask = GAUNTLETS, low = 15, high = 270), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 13, high = 244), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 26, high = 257), + chance("hosidius_5_gauntlets", STATION_RANGE, modifierMask = HOSIDIUS_5 or GAUNTLETS, low = 27, high = 282), + chance("hosidius_10_gauntlets", STATION_RANGE, modifierMask = HOSIDIUS_10 or GAUNTLETS, low = 40, high = 295) + ) ), heatCook( rowKey = "cooking_sea_turtle", raw = "items.raw_seaturtle", cooked = "items.seaturtle", burnt = "items.burnt_seaturtle", - level = 82, - xp = 211, - stopBurnFire = 100, - stopBurnRange = 100 + level = 82, xp = 211, stopBurnFire = 100, stopBurnRange = 100, + chances = listOf( + chance("fire", STATION_FIRE, low = 1, high = 202), + chance("range", STATION_RANGE, low = 1, high = 222), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 13, high = 234), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 26, high = 247) + ) ), heatCook( rowKey = "cooking_anglerfish", raw = "items.raw_anglerfish", cooked = "items.anglerfish", burnt = "items.burnt_anglerfish", - level = 84, - xp = 230, - stopBurnFire = 100, - stopBurnRange = 100 + level = 84, xp = 230, stopBurnFire = 100, stopBurnRange = 100, + chances = listOf( + chance("fire", STATION_FIRE, low = 1, high = 200), + chance("range", STATION_RANGE, low = 1, high = 220), + chance("gauntlets", STATION_ANY, modifierMask = GAUNTLETS, low = 12, high = 260), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 13, high = 232), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 26, high = 245), + chance("hosidius_5_gauntlets", STATION_RANGE, modifierMask = HOSIDIUS_5 or GAUNTLETS, low = 24, high = 272), + chance("hosidius_10_gauntlets", STATION_RANGE, modifierMask = HOSIDIUS_10 or GAUNTLETS, low = 37, high = 285) + ) ), heatCook( rowKey = "cooking_dark_crab", raw = "items.raw_dark_crab", cooked = "items.dark_crab", burnt = "items.burnt_dark_crab", - level = 90, - xp = 215, - stopBurnFire = 100, - stopBurnRange = 100 + level = 90, xp = 215, stopBurnFire = 100, stopBurnRange = 100, + chances = listOf( + chance("base_any", STATION_ANY, low = 10, high = 222), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 22, high = 234), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 35, high = 247) + ) ), heatCook( rowKey = "cooking_manta_ray", raw = "items.raw_mantaray", cooked = "items.mantaray", burnt = "items.burnt_mantaray", - level = 91, - xp = 216, - stopBurnFire = 100, - stopBurnRange = 100 + level = 91, xp = 216, stopBurnFire = 100, stopBurnRange = 100, + chances = listOf( + chance("fire", STATION_FIRE, low = 1, high = 202), + chance("range", STATION_RANGE, low = 1, high = 222), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 13, high = 234), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 26, high = 247) + ) ), + + // ---- Special fish ---- heatCook( rowKey = "cooking_karambwan", raw = "items.tbwt_raw_karambwan", cooked = "items.tbwt_cooked_karambwan", burnt = "items.tbwt_burnt_karambwan", - level = 30, - xp = 190, - stopBurnFire = 99, - stopBurnRange = 93 + level = 30, xp = 190, stopBurnFire = 99, stopBurnRange = 93, + chances = listOf( + chance("base_any", STATION_ANY, low = 70, high = 255), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 82, high = 267), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 95, high = 280) + ) ), heatCook( rowKey = "cooking_rainbow_fish", raw = "items.hunting_raw_fish_special", cooked = "items.hunting_fish_special", burnt = "items.burntfish2", - level = 35, - xp = 110, - stopBurnFire = 64, - stopBurnRange = 60 + level = 35, xp = 110, stopBurnFire = 64, stopBurnRange = 60, + chances = listOf( + chance("base_any", STATION_ANY, low = 56, high = 370), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 68, high = 382), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 81, high = 395) + ) ), heatCook( rowKey = "cooking_cave_eel", raw = "items.raw_cave_eel", cooked = "items.cave_eel", burnt = "items.burnt_cave_eel", - level = 38, - xp = 115, - stopBurnFire = 74, - stopBurnRange = 70 + level = 38, xp = 115, stopBurnFire = 74, stopBurnRange = 70, + chances = listOf( + chance("base_any", STATION_ANY, low = 38, high = 332), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 50, high = 344), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 63, high = 357) + ) ), - // --- Snails (fire-only, Morytania) --- + // ---- Snails ---- heatCook( rowKey = "cooking_thin_snail", raw = "items.snail_corpse1", cooked = "items.snail_corpse_cooked1", burnt = "items.burnt_snail", - level = 12, - xp = 70, - stopBurnFire = 47, - stopBurnRange = 47, - stationMask = STATION_FIRE + level = 12, xp = 70, stopBurnFire = 47, stopBurnRange = 47, + stationMask = STATION_FIRE, + chances = listOf( + chance("base_any", STATION_ANY, low = 93, high = 444), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 103, high = 464), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 105, high = 456), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 118, high = 469) + ) ), heatCook( rowKey = "cooking_lean_snail", raw = "items.snail_corpse2", cooked = "items.snail_corpse_cooked2", burnt = "items.burnt_snail", - level = 17, - xp = 80, - stopBurnFire = 47, - stopBurnRange = 50 + level = 17, xp = 80, stopBurnFire = 47, stopBurnRange = 50, + chances = listOf( + chance("fire", STATION_FIRE, low = 93, high = 444), + chance("range", STATION_RANGE, low = 85, high = 428), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 95, high = 448), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 97, high = 440), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 110, high = 453) + ) ), heatCook( rowKey = "cooking_fat_snail", raw = "items.snail_corpse3", cooked = "items.snail_corpse_cooked3", burnt = "items.burnt_snail", - level = 22, - xp = 95, - stopBurnFire = 56, - stopBurnRange = 56, - stationMask = STATION_FIRE + level = 22, xp = 95, stopBurnFire = 56, stopBurnRange = 56, + stationMask = STATION_FIRE, + chances = listOf( + chance("base_any", STATION_ANY, low = 73, high = 402), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 83, high = 422), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 85, high = 414), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 98, high = 427) + ) ) ) } diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/MeatRecipes.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/MeatRecipes.kt index f33f9e63..5b9ac7ba 100644 --- a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/MeatRecipes.kt +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/MeatRecipes.kt @@ -1,12 +1,21 @@ package org.alter.impl.skills.cooking.recipes import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.GAUNTLETS +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_10 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_5 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.LUMBRIDGE +import org.alter.impl.skills.cooking.CookingConstants.STATION_ANY import org.alter.impl.skills.cooking.CookingConstants.STATION_FIRE +import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE +import org.alter.impl.skills.cooking.CookingHelpers.chance import org.alter.impl.skills.cooking.CookingHelpers.heatCook import org.alter.impl.skills.cooking.CookingHelpers.spitRoast /** - * Meat cooking recipes - standard cooking and spit roasting. + * Meat cooking recipes — standard cooking and spit roasting. + * + * Chance profiles sourced from OSRS Wiki skill_chances data. */ object MeatRecipes { @@ -17,70 +26,88 @@ object MeatRecipes { raw = "items.raw_chompy", cooked = "items.cooked_chompy", burnt = "items.ruined_chompy", - level = 30, - xp = 100, - stopBurnFire = 63, - stopBurnRange = 63 + level = 30, xp = 100, stopBurnFire = 63, stopBurnRange = 63, + stationMask = STATION_FIRE, + chances = listOf( + chance("fire", STATION_FIRE, low = 200, high = 255) + ) ), heatCook( rowKey = "cooking_beef", raw = "items.raw_beef", cooked = "items.cooked_meat", burnt = "items.burnt_meat", - level = 1, - xp = 30, - stopBurnFire = 34, - stopBurnRange = 34 + level = 1, xp = 30, stopBurnFire = 34, stopBurnRange = 34, + chances = listOf( + chance("base_any", STATION_ANY, low = 128, high = 512), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 138, high = 532), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 140, high = 524), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 153, high = 537) + ) ), heatCook( rowKey = "cooking_chicken", raw = "items.raw_chicken", cooked = "items.cooked_chicken", burnt = "items.burnt_chicken", - level = 1, - xp = 30, - stopBurnFire = 34, - stopBurnRange = 34 + level = 1, xp = 30, stopBurnFire = 34, stopBurnRange = 34, + chances = listOf( + chance("base_any", STATION_ANY, low = 128, high = 512), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 138, high = 532), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 140, high = 524), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 153, high = 537) + ) ), heatCook( rowKey = "cooking_rat_meat", raw = "items.raw_rat_meat", cooked = "items.cooked_meat", burnt = "items.burnt_meat", - level = 1, - xp = 30, - stopBurnFire = 34, - stopBurnRange = 34 + level = 1, xp = 30, stopBurnFire = 34, stopBurnRange = 34, + chances = listOf( + chance("base_any", STATION_ANY, low = 128, high = 512), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 138, high = 532), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 140, high = 524), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 153, high = 537) + ) ), heatCook( rowKey = "cooking_bear_meat", raw = "items.raw_bear_meat", cooked = "items.cooked_meat", burnt = "items.burnt_meat", - level = 1, - xp = 30, - stopBurnFire = 34, - stopBurnRange = 34 + level = 1, xp = 30, stopBurnFire = 34, stopBurnRange = 34, + chances = listOf( + chance("base_any", STATION_ANY, low = 128, high = 512), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 138, high = 532), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 140, high = 524), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 153, high = 537) + ) ), heatCook( rowKey = "cooking_rabbit", raw = "items.raw_rabbit", cooked = "items.cooked_rabbit", burnt = "items.burnt_meat", - level = 1, - xp = 30, - stopBurnFire = 34, - stopBurnRange = 34 + level = 1, xp = 30, stopBurnFire = 34, stopBurnRange = 34, + chances = listOf( + chance("base_any", STATION_ANY, low = 128, high = 512), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 140, high = 524), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 153, high = 537) + ) ), heatCook( rowKey = "cooking_ugthanki_meat", raw = "items.raw_ugthanki_meat", cooked = "items.cooked_ugthanki_meat", burnt = "items.burnt_meat", - level = 1, - xp = 40, - stopBurnFire = 34, - stopBurnRange = 34 + level = 1, xp = 40, stopBurnFire = 34, stopBurnRange = 34, + chances = listOf( + chance("fire", STATION_FIRE, low = 40, high = 252), + chance("range", STATION_RANGE, low = 30, high = 253), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 42, high = 265), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 55, high = 278) + ) ) ) @@ -93,10 +120,8 @@ object MeatRecipes { skewered = "items.spit_skewered_bird_meat", cooked = "items.spit_roasted_bird_meat", burnt = "items.spit_burned_bird_meat", - cookingLevel = 11, - xp = 60, - stopBurnFire = 44, - stopBurnRange = 44 + cookingLevel = 11, xp = 60, stopBurnFire = 44, stopBurnRange = 44, + chances = listOf(chance("fire", STATION_FIRE, low = 155, high = 255)) ) + spitRoast( skewerRowKey = "cooking_skewer_beast_meat", @@ -105,10 +130,8 @@ object MeatRecipes { skewered = "items.spit_skewered_beast_meat", cooked = "items.spit_roasted_beast_meat", burnt = "items.spit_burned_beast_meat", - cookingLevel = 21, - xp = 82, - stopBurnFire = 55, - stopBurnRange = 55 + cookingLevel = 21, xp = 82, stopBurnFire = 55, stopBurnRange = 55, + chances = listOf(chance("fire", STATION_FIRE, low = 180, high = 255)) ) + spitRoast( skewerRowKey = "cooking_skewer_rabbit_meat", @@ -117,15 +140,12 @@ object MeatRecipes { skewered = "items.spit_skewered_rabbit_meat", cooked = "items.spit_roasted_rabbit_meat", burnt = "items.spit_burned_rabbit_meat", - cookingLevel = 16, - xp = 70, - stopBurnFire = 99, - stopBurnRange = 99 + cookingLevel = 16, xp = 70, stopBurnFire = 99, stopBurnRange = 99, + chances = listOf(chance("fire", STATION_FIRE, low = 160, high = 255)) ) /** * Hunter meat recipes — meats obtained from pitfall trapping. - * These are standard heatCook recipes; some are fire-only. * * Note: Small kebbits (wild, barb-tailed, dashing) are eaten raw and do NOT * require cooking. Only pitfall-trapped animals have raw→cooked transitions. @@ -136,62 +156,79 @@ object MeatRecipes { raw = "items.hunting_larupia_meat", cooked = "items.larupia_cooked", burnt = "items.burnt_largebeast", - level = 31, - xp = 92, - stopBurnFire = 59, - stopBurnRange = 59, - stationMask = STATION_FIRE + level = 31, xp = 92, stopBurnFire = 59, stopBurnRange = 59, + stationMask = STATION_FIRE, + chances = listOf( + chance("base_any", STATION_ANY, low = 65, high = 390), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 77, high = 402), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 90, high = 415) + ) ), heatCook( rowKey = "cooking_graahk", raw = "items.hunting_graahk_meat", cooked = "items.graahk_cooked", burnt = "items.burnt_largebeast", - level = 41, - xp = 124, - stopBurnFire = 75, - stopBurnRange = 75, - stationMask = STATION_FIRE + level = 41, xp = 124, stopBurnFire = 75, stopBurnRange = 75, + stationMask = STATION_FIRE, + chances = listOf( + chance("base_any", STATION_ANY, low = 32, high = 328), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 44, high = 340), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 57, high = 353) + ) ), heatCook( rowKey = "cooking_kyatt", raw = "items.hunting_kyatt_meat", cooked = "items.kyatt_cooked", burnt = "items.burnt_largebeast", - level = 51, - xp = 143, - stopBurnFire = 86, - stopBurnRange = 80 + level = 51, xp = 143, stopBurnFire = 86, stopBurnRange = 80, + chances = listOf( + chance("fire", STATION_FIRE, low = 18, high = 292), + chance("range", STATION_RANGE, low = 30, high = 310), + chance("gauntlets", STATION_ANY, modifierMask = GAUNTLETS, low = 30, high = 310), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 42, high = 322), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 55, high = 335) + ) ), heatCook( rowKey = "cooking_pyre_fox", raw = "items.hunting_fennecfox_meat", cooked = "items.fennecfox_cooked", burnt = "items.burnt_foxmeat", - level = 59, - xp = 154, - stopBurnFire = 93, - stopBurnRange = 92 + level = 59, xp = 154, stopBurnFire = 93, stopBurnRange = 92, + chances = listOf( + chance("fire", STATION_FIRE, low = 10, high = 273), + chance("range", STATION_RANGE, low = 11, high = 276), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 23, high = 288), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 36, high = 301) + ) ), heatCook( rowKey = "cooking_sunlight_antelope", raw = "items.hunting_antelopesun_meat", cooked = "items.antelopesun_cooked", burnt = "items.burnt_antelope", - level = 68, - xp = 175, - stopBurnFire = 100, - stopBurnRange = 95 + level = 68, xp = 175, stopBurnFire = 100, stopBurnRange = 95, + chances = listOf( + chance("fire", STATION_FIRE, low = 8, high = 254), + chance("range", STATION_RANGE, low = 8, high = 265), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 20, high = 277), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 33, high = 290) + ) ), heatCook( rowKey = "cooking_moonlight_antelope", raw = "items.hunting_antelopemoon_meat", cooked = "items.antelopemoon_cooked", burnt = "items.burnt_antelope", - level = 92, - xp = 220, - stopBurnFire = 100, - stopBurnRange = 100 + level = 92, xp = 220, stopBurnFire = 100, stopBurnRange = 100, + chances = listOf( + chance("fire", STATION_FIRE, low = 1, high = 185), + chance("range", STATION_RANGE, low = 1, high = 200), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 13, high = 212), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 26, high = 225) + ) ) ) diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/MiscFoodRecipes.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/MiscFoodRecipes.kt index 7e2359e7..e34c1b8d 100644 --- a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/MiscFoodRecipes.kt +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/MiscFoodRecipes.kt @@ -1,6 +1,11 @@ package org.alter.impl.skills.cooking.recipes import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_10 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_5 +import org.alter.impl.skills.cooking.CookingConstants.STATION_ANY +import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE +import org.alter.impl.skills.cooking.CookingHelpers.chance import org.alter.impl.skills.cooking.CookingHelpers.heatCook import org.alter.impl.skills.cooking.CookingHelpers.multiStepCook import org.alter.impl.skills.cooking.PrepStepDef @@ -17,10 +22,12 @@ object MiscFoodRecipes { raw = "items.sweetcorn", cooked = "items.sweetcorn_cooked", burnt = "items.sweetcorn_burnt", - level = 28, - xp = 104, - stopBurnFire = 61, - stopBurnRange = 61 + level = 28, xp = 104, stopBurnFire = 61, stopBurnRange = 61, + chances = listOf( + chance("base_any", STATION_ANY, low = 78, high = 412), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 90, high = 424), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 103, high = 437) + ) ) ) @@ -44,10 +51,13 @@ object MiscFoodRecipes { raw = "items.bowl_egg_raw", cooked = "items.bowl_egg_scrambled", burnt = "items.bowl_egg_burnt", - level = 13, - xp = 50, - stopBurnFire = 46, - stopBurnRange = 46 + level = 13, xp = 50, stopBurnFire = 46, stopBurnRange = 46, + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 90, high = 438), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 102, high = 450), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 115, high = 463) + ) ) ) @@ -58,10 +68,12 @@ object MiscFoodRecipes { raw = "items.bowl_onion", cooked = "items.bowl_onion_fried", burnt = "items.bowl_onion_burnt", - level = 42, - xp = 60, - stopBurnFire = 74, - stopBurnRange = 74 + level = 42, xp = 60, stopBurnFire = 74, stopBurnRange = 74, + chances = listOf( + chance("base_any", STATION_ANY, low = 36, high = 322), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 48, high = 334), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 61, high = 347) + ) ) ) @@ -72,10 +84,12 @@ object MiscFoodRecipes { raw = "items.bowl_mushroom_raw", cooked = "items.bowl_mushroom_fried", burnt = "items.bowl_mushroom_burnt", - level = 46, - xp = 60, - stopBurnFire = 80, - stopBurnRange = 80 + level = 46, xp = 60, stopBurnFire = 80, stopBurnRange = 80, + chances = listOf( + chance("base_any", STATION_ANY, low = 16, high = 282), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 28, high = 294), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 41, high = 307) + ) ) ) diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PieRecipes.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PieRecipes.kt index dfcf0ddf..2bdf04a4 100644 --- a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PieRecipes.kt +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PieRecipes.kt @@ -1,7 +1,11 @@ package org.alter.impl.skills.cooking.recipes import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_10 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_5 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.LUMBRIDGE import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE +import org.alter.impl.skills.cooking.CookingHelpers.chance import org.alter.impl.skills.cooking.CookingHelpers.multiStepCook import org.alter.impl.skills.cooking.HeatStepDef import org.alter.impl.skills.cooking.PrepStepDef @@ -37,7 +41,13 @@ object PieRecipes { xp = 78, stopBurnFire = 44, stopBurnRange = 44, - stationMask = STATION_RANGE + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 98, high = 452), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 108, high = 462), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 110, high = 464), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 123, high = 477) + ) ) ) @@ -63,7 +73,13 @@ object PieRecipes { xp = 110, stopBurnFire = 54, stopBurnRange = 54, - stationMask = STATION_RANGE + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 78, high = 412), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 88, high = 432), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 90, high = 424), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 103, high = 437) + ) ) ) @@ -106,7 +122,12 @@ object PieRecipes { xp = 128, stopBurnFire = 63, stopBurnRange = 63, - stationMask = STATION_RANGE + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 58, high = 372), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 70, high = 384), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 83, high = 397) + ) ) ) @@ -132,7 +153,12 @@ object PieRecipes { xp = 130, stopBurnFire = 64, stopBurnRange = 64, - stationMask = STATION_RANGE + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 58, high = 372), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 70, high = 384), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 83, high = 397) + ) ) ) @@ -174,7 +200,12 @@ object PieRecipes { xp = 164, stopBurnFire = 81, stopBurnRange = 81, - stationMask = STATION_RANGE + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 38, high = 332), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 50, high = 344), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 63, high = 357) + ) ) ) @@ -200,7 +231,13 @@ object PieRecipes { xp = 180, stopBurnFire = 86, stopBurnRange = 86, - stationMask = STATION_RANGE + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 20, high = 300), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 108, high = 462), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 32, high = 312), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 45, high = 325) + ) ) ) @@ -226,7 +263,13 @@ object PieRecipes { xp = 200, stopBurnFire = 94, stopBurnRange = 94, - stationMask = STATION_RANGE + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 17, high = 285), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 140, high = 450), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 29, high = 297), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 42, high = 310) + ) ) ) @@ -268,7 +311,12 @@ object PieRecipes { xp = 210, stopBurnFire = 100, stopBurnRange = 94, - stationMask = STATION_RANGE + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 15, high = 270), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 27, high = 282), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 40, high = 295) + ) ) ) @@ -294,7 +342,12 @@ object PieRecipes { xp = 220, stopBurnFire = 100, stopBurnRange = 97, - stationMask = STATION_RANGE + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 8, high = 250), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 20, high = 262), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 33, high = 275) + ) ) ) @@ -336,7 +389,12 @@ object PieRecipes { xp = 240, stopBurnFire = 100, stopBurnRange = 100, - stationMask = STATION_RANGE + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 1, high = 222), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 13, high = 234), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 26, high = 247) + ) ) ) @@ -378,7 +436,12 @@ object PieRecipes { xp = 260, stopBurnFire = 100, stopBurnRange = 100, - stationMask = STATION_RANGE + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 1, high = 212), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 13, high = 224), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 26, high = 237) + ) ) ) diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PizzaRecipes.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PizzaRecipes.kt index 6977ce15..f6f4dd54 100644 --- a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PizzaRecipes.kt +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PizzaRecipes.kt @@ -1,7 +1,10 @@ package org.alter.impl.skills.cooking.recipes import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_10 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_5 import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE +import org.alter.impl.skills.cooking.CookingHelpers.chance import org.alter.impl.skills.cooking.CookingHelpers.multiStepCook import org.alter.impl.skills.cooking.HeatStepDef import org.alter.impl.skills.cooking.PrepStepDef @@ -43,7 +46,12 @@ object PizzaRecipes { xp = 143, stopBurnFire = 68, stopBurnRange = 68, - stationMask = STATION_RANGE + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 48, high = 352), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 60, high = 364), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 73, high = 377) + ) ) ) diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PotatoRecipes.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PotatoRecipes.kt index 0898a906..795b3b27 100644 --- a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PotatoRecipes.kt +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/PotatoRecipes.kt @@ -1,7 +1,10 @@ package org.alter.impl.skills.cooking.recipes import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_10 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_5 import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE +import org.alter.impl.skills.cooking.CookingHelpers.chance import org.alter.impl.skills.cooking.CookingHelpers.heatCook import org.alter.impl.skills.cooking.CookingHelpers.multiStepCook import org.alter.impl.skills.cooking.HeatStepDef @@ -19,11 +22,13 @@ object PotatoRecipes { raw = "items.potato", cooked = "items.potato_baked", burnt = "items.potato_burnt", - level = 7, - xp = 15, - stopBurnFire = 40, - stopBurnRange = 40, - stationMask = STATION_RANGE + level = 7, xp = 15, stopBurnFire = 40, stopBurnRange = 40, + stationMask = STATION_RANGE, + chances = listOf( + chance("range", STATION_RANGE, low = 108, high = 472), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 120, high = 484), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 133, high = 497) + ) ) ) diff --git a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/StewRecipes.kt b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/StewRecipes.kt index fcc11eb7..590ffca9 100644 --- a/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/StewRecipes.kt +++ b/cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/StewRecipes.kt @@ -1,6 +1,12 @@ package org.alter.impl.skills.cooking.recipes import org.alter.impl.skills.cooking.ActionDef +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_10 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_5 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.LUMBRIDGE +import org.alter.impl.skills.cooking.CookingConstants.STATION_ANY +import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE +import org.alter.impl.skills.cooking.CookingHelpers.chance import org.alter.impl.skills.cooking.CookingHelpers.multiStepCook import org.alter.impl.skills.cooking.HeatStepDef import org.alter.impl.skills.cooking.PrepStepDef @@ -39,7 +45,13 @@ object StewRecipes { burnt = "items.burnt_stew", xp = 117, stopBurnFire = 58, - stopBurnRange = 58 + stopBurnRange = 58, + chances = listOf( + chance("base_any", STATION_ANY, low = 68, high = 392), + chance("lumbridge", STATION_RANGE, modifierMask = LUMBRIDGE, low = 78, high = 412), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 80, high = 404), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 93, high = 417) + ) ) ) @@ -80,7 +92,12 @@ object StewRecipes { burnt = "items.burnt_curry", xp = 280, stopBurnFire = 74, - stopBurnRange = 74 + stopBurnRange = 74, + chances = listOf( + chance("base_any", STATION_ANY, low = 38, high = 332), + chance("hosidius_5", STATION_RANGE, modifierMask = HOSIDIUS_5, low = 50, high = 344), + chance("hosidius_10", STATION_RANGE, modifierMask = HOSIDIUS_10, low = 63, high = 357) + ) ) ) diff --git a/content/src/main/kotlin/org/alter/skills/cooking/events/CookingUtils.kt b/content/src/main/kotlin/org/alter/skills/cooking/events/CookingUtils.kt index 217f060b..1c520eee 100644 --- a/content/src/main/kotlin/org/alter/skills/cooking/events/CookingUtils.kt +++ b/content/src/main/kotlin/org/alter/skills/cooking/events/CookingUtils.kt @@ -7,7 +7,15 @@ import org.alter.api.computeSkillingSuccess import org.alter.api.ext.hasEquipped import org.alter.game.model.entity.GameObject import org.alter.game.model.entity.Player +import org.alter.impl.skills.cooking.ChanceDef +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.GAUNTLETS +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_10 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.HOSIDIUS_5 +import org.alter.impl.skills.cooking.CookingConstants.ChanceModifier.LUMBRIDGE +import org.alter.impl.skills.cooking.CookingConstants.STATION_FIRE +import org.alter.impl.skills.cooking.CookingConstants.STATION_RANGE import org.alter.skills.cooking.runtime.CookingAction +import org.alter.skills.cooking.runtime.CookingActionRegistry import org.alter.skills.cooking.runtime.OutcomeKind import org.alter.skills.cooking.runtime.Trigger import org.alter.skills.firemaking.ColoredLogs @@ -179,9 +187,14 @@ object CookingUtils { /** * Rolls to determine if cooking succeeds. * - * Uses the OSRS `statrandom` (computeSkillingSuccess) approach with per-food - * low/high values. The cooking cape guarantees success. Cooking gauntlets lower - * the stop-burn threshold for affected items. + * Uses wiki-sourced [ChanceDef] profiles when available (preferred), falling + * back to the legacy stopBurn approach for recipes without chance data. + * + * The chance-based system: + * 1. Cooking cape / max cape → never burn. + * 2. Build the player's station mask and modifier mask from equipment/location. + * 3. Find the most specific matching [ChanceDef] profile. + * 4. Call [computeSkillingSuccess] with that profile's low/high values. */ fun rollCookSuccess( player: Player, @@ -193,15 +206,99 @@ object CookingUtils { val cookingLevel = player.getSkills().getCurrentLevel(Skills.COOKING) + // Try chance-based success (wiki-accurate profiles) + val chances = CookingActionRegistry.chancesByAction[action.key to action.variant] + if (!chances.isNullOrEmpty()) { + val stationMask = when (station) { + CookStation.FIRE -> STATION_FIRE + else -> STATION_RANGE + } + val modifierMask = buildModifierMask(player, station) + val best = findBestChance(chances, stationMask, modifierMask) + if (best != null) { + val chance = computeSkillingSuccess( + low = best.low, + high = best.high, + level = cookingLevel.coerceIn(1, 99) + ) + return Random.nextDouble() < chance + } + } + + // Legacy fallback: stopBurn system + return rollWithStopBurn(player, station, action, cookingLevel) + } + + /** + * Builds the player's modifier bitmask from equipment and station type. + */ + private fun buildModifierMask(player: Player, station: CookStation): Int { + var mask = 0 + if (hasCookingGauntlets(player)) mask = mask or GAUNTLETS + when (station) { + CookStation.HOSIDIUS_RANGE -> { + // TODO: Check Kourend Hard Diary for +10% — default to +5% + mask = mask or if (hasKourendHardDiary(player)) HOSIDIUS_10 else HOSIDIUS_5 + } + CookStation.LUMBRIDGE_RANGE -> mask = mask or LUMBRIDGE + else -> {} + } + return mask + } + + /** + * Returns true if the player has completed the Kourend Hard Diary. + * TODO: Implement actual diary achievement check. + */ + private fun hasKourendHardDiary(@Suppress("UNUSED_PARAMETER") player: Player): Boolean = false + + /** + * Selects the most specific [ChanceDef] that matches the given station and + * modifier mask. A profile matches if: + * 1. Its station mask overlaps with the player's station. + * 2. Its modifier mask is a subset of the player's active modifiers. + * + * Among matching profiles, the one with the most modifier bits set wins + * (most specific). Ties are broken by highest chance (low + high sum). + */ + private fun findBestChance( + chances: List, + stationMask: Int, + modifierMask: Int + ): ChanceDef? { + val candidates = chances + .filter { (it.stationMask and stationMask) != 0 } + .filter { (it.modifierMask and modifierMask) == it.modifierMask } + + if (candidates.isEmpty()) { + // No modifier-compatible match — try base profile (modifierMask == 0) + return chances.firstOrNull { + (it.stationMask and stationMask) != 0 && it.modifierMask == 0 + } + } + + return candidates.maxWithOrNull( + compareBy({ Integer.bitCount(it.modifierMask) }, { it.low + it.high }) + ) + } + + /** + * Legacy stop-burn based success roll. + * Used as fallback when no [ChanceDef] profiles are defined for a recipe. + */ + private fun rollWithStopBurn( + player: Player, + station: CookStation, + action: CookingAction, + cookingLevel: Int + ): Boolean { val wearingGauntlets = hasCookingGauntlets(player) - // For stop-burn lookup, Hosidius/Lumbridge count as RANGE val baseStation = when (station) { CookStation.FIRE -> CookStation.FIRE else -> CookStation.RANGE } - // Determine effective stop-burn level val stopBurn: Int = if (wearingGauntlets) { val override = gauntletStopBurnOverrides[action.key] if (override != null) { @@ -224,16 +321,12 @@ object CookingUtils { if (cookingLevel >= stopBurn) return true - // Use computeSkillingSuccess with the level requirement as the base - // low=level requirement scaled, high=stop-burn scaled - val effectiveLevel = cookingLevel.coerceIn(1, 99) val chance = computeSkillingSuccess( low = action.row.level, high = stopBurn, - level = effectiveLevel + level = cookingLevel.coerceIn(1, 99) ) - // Hosidius Kitchen range: 5% reduced burn chance (multiply success by 1.05) val adjustedChance = when (station) { CookStation.HOSIDIUS_RANGE -> (chance * 1.05).coerceAtMost(1.0) else -> chance diff --git a/content/src/main/kotlin/org/alter/skills/cooking/runtime/CookingActionRegistry.kt b/content/src/main/kotlin/org/alter/skills/cooking/runtime/CookingActionRegistry.kt index 1ee5edd3..fbf9a752 100644 --- a/content/src/main/kotlin/org/alter/skills/cooking/runtime/CookingActionRegistry.kt +++ b/content/src/main/kotlin/org/alter/skills/cooking/runtime/CookingActionRegistry.kt @@ -1,9 +1,12 @@ package org.alter.skills.cooking.runtime +import org.alter.impl.skills.cooking.ChanceDef +import org.alter.impl.skills.cooking.CookingRecipeRegistry import org.alter.skills.cooking.runtime.OutcomeKind import org.generated.tables.cooking.CookingActionInputsRow import org.generated.tables.cooking.CookingActionOutcomesRow import org.generated.tables.cooking.CookingActionsRow +import org.alter.rscm.RSCM.asRSCM /** * Runtime models for loaded cooking recipe data. @@ -116,4 +119,20 @@ object CookingActionRegistry { .groupBy({ it.first }, { it.second }) .mapValues { (_, actions) -> actions.distinct() } } + + /** + * Chance profiles indexed by (key, variant). + * + * Built directly from [CookingRecipeRegistry.allRecipes] at startup. + * This avoids needing a separate DB table for chance data. + */ + val chancesByAction: Map, List> by lazy { + CookingRecipeRegistry.allRecipes + .filter { it.chances.isNotEmpty() } + .mapNotNull { action -> + val id = runCatching { action.key.asRSCM() }.getOrNull() ?: return@mapNotNull null + (id to action.variant) to action.chances + } + .toMap() + } } diff --git a/docs/cooking/plan.md b/docs/cooking/plan.md new file mode 100644 index 00000000..78e01152 --- /dev/null +++ b/docs/cooking/plan.md @@ -0,0 +1,61 @@ +# Cooking implementation plan + +## Goal +Implement Cooking to match wikidata (levels, XP, burn logic, station rules, prep steps, and outcome items) across cache + content. + +## Current status (as of 2026-02-01) +- Heat-source cooking for core fish/meats is implemented with per-item chance profiles (added spider on stick/shaft, snail meats, fishcake, red/giant crab meat, hunter meats, antelope, jubbly, kebbits, and late-game fish). Sacred eel remains blocked by missing item key in cache. +- Bread and pitta bread baking implemented (range-only). +- Pies (redberry/meat/mud/apple/fish/botanical/mushroom/admiral/dragonfruit/wild/summer) baked on range with chance profiles. +- Stew and curry (fire/range) implemented. +- Pizzas (plain bake + topping steps) implemented. +- Chocolate cake topping step implemented. +- Wine (jug of wine, wine of zamorak) implemented with item-on-item success chances. +- Hot drinks (nettle tea), vegetable dishes, dairy, and ugthanki kebab prep implemented. +- Spit roasting and Camdozaal prep table are implemented (bird + beast + rabbit roast; guppy/cavefish/tetra/catfish prep). +- Multi-step prep + bake exists for garden pie and cake; other pies currently bake-only from uncooked items. +- Dough/base prep added for bread dough, pastry dough, pie shell, pizza base, incomplete pizza, and uncooked pizza. +- Burn success now uses chance profiles loaded from cache tables; stop-burn flags removed. +- Station/equipment modifiers implemented for Lumbridge range, Hosidius +5/+10, and cooking gauntlets. +- Cooking cape (no-burn) implemented; Hosidius +10 diary wiring still missing in runtime. +- Large recipe gaps remain per wikidata. + +## Plan (phased) +### Phase 1 — Recipe coverage (core) +1) Add missing Meat/Fish recipes from wikidata. + - Start with remaining meat/fish from meat-fish.md. +2) Add remaining prep steps (pitta, pie fillings, other bases) and topping flows (where missing). + +### Phase 2 — Burn rules + chance data +1) Parse burn thresholds from burn_level.wikisrc. +2) Integrate skill_chances.json curves per item where available. (in progress; automated extract in tmp/) +3) Add station modifiers and equipment modifiers: + - Lumbridge Castle range + - Hosidius range (+5%, +10% with diary) + - Cooking gauntlets + - Cooking cape (no burn) + +### Phase 3 — Special/side recipes +1) Hot drinks, vegetable dishes, dairy, kebabs. +2) Hunter foods: kebbits, snails, antelope, pyre fox. +3) Fishcake, giant crab meat, karambwan poison variants. + +### Phase 4 — QA and balancing +1) Update cooking test presets to cover new recipes. +2) Add sanity checks for missing RSCM keys. +3) Verify outcomes/messages and inventory space handling. + +## Primary files to change +- [cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/FishRecipes.kt](../../cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/FishRecipes.kt) +- [cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/MeatRecipes.kt](../../cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/MeatRecipes.kt) +- [cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/BakedGoodsRecipes.kt](../../cache/src/main/kotlin/org/alter/impl/skills/cooking/recipes/BakedGoodsRecipes.kt) +- [cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingRecipeRegistry.kt](../../cache/src/main/kotlin/org/alter/impl/skills/cooking/CookingRecipeRegistry.kt) +- [content/src/main/kotlin/org/alter/skills/cooking/events/CookingUtils.kt](../../content/src/main/kotlin/org/alter/skills/cooking/events/CookingUtils.kt) +- [content/src/main/kotlin/org/alter/skills/cooking/events/CookingEvents.kt](../../content/src/main/kotlin/org/alter/skills/cooking/events/CookingEvents.kt) + +## Reference data +- [wikidata/cooking.wikisrc](../../wikidata/cooking.wikisrc) +- [wikidata/burnt_food.wikisrc](../../wikidata/burnt_food.wikisrc) +- [wikidata/burn_level.wikisrc](../../wikidata/burn_level.wikisrc) +- [wikidata/skill_chances.json](../../wikidata/skill_chances.json) +- [wikidata/meat-fish.md](../../wikidata/meat-fish.md) diff --git a/docs/cooking/recipe-gap.md b/docs/cooking/recipe-gap.md new file mode 100644 index 00000000..c76b4dac --- /dev/null +++ b/docs/cooking/recipe-gap.md @@ -0,0 +1,102 @@ +# Cooking recipe gaps (from wikidata) + +## Meat / Fish (missing) +Source: [wikidata/meat-fish.md](../../wikidata/meat-fish.md) + +- [x] Sinew +- [x] Poison karambwan +- [x] Thin snail +- [x] Spider on stick +- [x] Spider on shaft +- [x] Roast rabbit +- [x] Lean snail +- [x] Cavefish (prep table) +- [x] Red crab meat +- [x] Cooked giant crab meat +- [x] Fat snail +- [x] Cooked wild kebbit +- [x] Cooked fishcake +- [x] Cooked larupia +- [x] Cooked barb-tailed kebbit +- [x] Tetra (prep table) +- [x] Cooked jubbly +- [x] Cooked graahk +- [x] Catfish (prep table) +- [x] Cooked kyatt +- [x] Lava eel +- [x] Swordtip squid +- [x] Cooked pyre fox +- [x] Cooked sunlight antelope +- [x] Giant krill +- [x] Jumbo squid +- [ ] Sacred eel +- [x] Haddock +- [x] Yellowfin +- [x] Cooked dashing kebbit +- [x] Halibut +- [x] Bluefin +- [x] Marlin +- [x] Cooked moonlight antelope + +## Bread +- [x] Bread (bake range-only) +- [x] Pitta bread (bake range-only) + +## Pies +- [x] Redberry pie +- [x] Meat pie +- [x] Mud pie +- [x] Apple pie +- [x] Fish pie +- [x] Botanical pie +- [x] Mushroom pie +- [x] Admiral pie +- [x] Dragonfruit pie +- [x] Wild pie +- [x] Summer pie + +## Stews +- [x] Stew +- [x] Curry + +## Pizzas +- [x] Plain pizza +- [x] Meat pizza +- [x] Anchovy pizza +- [x] Pineapple pizza + +## Cakes +- [x] Chocolate cake + +## Wine +- [x] Jug of wine +- [x] Wine of zamorak + +## Hot drinks +- [x] Cup of tea + +## Vegetable dishes +- [x] Baked potato +- [x] Spicy sauce +- [x] Chilli con carne +- [x] Scrambled egg +- [x] Egg and tomato +- [x] Cooked sweetcorn +- [x] Potato with butter +- [x] Chilli potato +- [x] Fried onions +- [x] Fried mushrooms +- [x] Potato with cheese +- [x] Egg potato +- [x] Mushroom & onion +- [x] Mushroom potato +- [x] Tuna and corn +- [x] Tuna potato + +## Dairy +- [x] Pot of cream +- [x] Pat of butter +- [x] Cheese + +## Kebabs +- [x] Kebab (and variants) diff --git a/game-server/src/test/kotlin/org/alter/game/model/skill/CookingRecipeTests.kt b/game-server/src/test/kotlin/org/alter/game/model/skill/CookingRecipeTests.kt new file mode 100644 index 00000000..46fdddba --- /dev/null +++ b/game-server/src/test/kotlin/org/alter/game/model/skill/CookingRecipeTests.kt @@ -0,0 +1,31 @@ +package org.alter.game.model.skill + +import kotlin.test.Test +import kotlin.test.assertTrue +import org.alter.impl.skills.cooking.CookingConstants +import org.alter.impl.skills.cooking.CookingRecipeRegistry + +class CookingRecipeTests { + + @Test + fun `heat-source recipes have chance profiles`() { + val actions = CookingRecipeRegistry.allRecipes + .filter { it.trigger == CookingConstants.Trigger.HEAT_SOURCE } + + actions.forEach { action -> + val stationMask = action.stationMask + if ((stationMask and CookingConstants.STATION_FIRE) != 0) { + assertTrue( + action.chances.any { it.low > 0 && it.high > 0 && (it.stationMask and CookingConstants.STATION_FIRE) != 0 }, + "Missing fire chance profile for action ${action.rowId}" + ) + } + if ((stationMask and CookingConstants.STATION_RANGE) != 0) { + assertTrue( + action.chances.any { it.low > 0 && it.high > 0 && (it.stationMask and CookingConstants.STATION_RANGE) != 0 }, + "Missing range chance profile for action ${action.rowId}" + ) + } + } + } +} diff --git a/wikidata/burn_level.wikisrc b/wikidata/burn_level.wikisrc deleted file mode 100644 index 7e7a7393..00000000 --- a/wikidata/burn_level.wikisrc +++ /dev/null @@ -1,1269 +0,0 @@ -{{External|rs}} -{{Incomplete|CoX fish need looking into, [[statrandom]] was updated and everything needs to be checked over as a multitude of burn levels were slightly changed}} - -These tables show the [[Cooking]] level required for the raw [[food]] item to stop [[Burnt food|burning]]. These values do '''not''' account for wearing the [[cooking cape]], which guarantees food will never burn while wearing it. An empty value with a dash that is not N/A means that the food can '''still''' be burned on that cooking source. - -==Food types== -===Affected by cooking gauntlets=== -{| class="wikitable sortable align-left-2" style="text-align:center;" -|- -!colspan=2 rowspan=2|Food -!rowspan=2|[[Fire]] -!rowspan=2|[[Range]]? -!colspan=2|[[Hosidius Kitchen|Hosidius]]? -!colspan=3|[[Cooking gauntlets|Gauntlets]] -!rowspan=2|[[Experience]] -!rowspan=2|Members? -|- -!5% -![[Kourend & Kebos Diary#Rewards 4|10%]]The value will be N/A if the level required to not burn with the [[Elite Kourend & Kebos Diary]] completed is lower than the level required to complete the diary (level 84). -!Default -!Hosidius 5% -![[Kourend & Kebos Diary#Rewards 4|Hosidius 10%]] -|- -|{{plinkt|Lobster}} -|74 -|74 -|70 -|{{NA}} -|64 -|60 -|{{NA}} -|120 -|{{Members|no}} -|- -|{{plinkt|Swordfish}} -|86 -|80 -|76 -|{{NA}} -|80 -|76 -|{{NA}} -|140 -|{{Members|no}} -|- -|{{plinkt|Cooked kyatt}} -|86 -|80 -|76 -|{{NA}} -|80 -|76 -|{{NA}} -|143 -|{{Members|yes}} -|- -|{{plinkt|Monkfish}} -|92 -|90 -|86 -|82 -|86 -|82 -|{{NA}} -|150 -|{{Members|yes}} -|- -|{{plinkt|Shark}} -| - -| - -| - -|98 -|94 -|89 -|84 -|210 -|{{Members|yes}} -|- -|{{plinkt|Anglerfish}} -| - -| - -| - -| - -|97 -|93 -|87 -|230 -|{{Members|yes}} -|} -{{Reflist|group=h}} - -===Affected by Lumbridge Castle range=== -{| class="wikitable sortable align-left-2" style="text-align:center;" -|- -!colspan="2"|Food -![[Fire]] -![[Range|Normal
range]]{{Note|Lower chance of burning than on an open fire.|?}} -![[Cooking range (Lumbridge Castle)|Castle
range]]{{Note|Slightly lower chance to burn than both open fire and standard ranges.|?}} -![[Experience]] -!Members? -|- -|{{plinkt|Cooked meat}} -|34 -|{{NA}} -|31 -|30 -|{{Members|no}} -|- -|{{plinkt|Cooked chicken}} -|34 -|{{NA}} -|31 -|30 -|{{Members|no}} -|- -|{{plinkt|Shrimps}} -|34 -|{{NA}} -|31 -|30 -|{{Members|no}} -|- -|{{plinkt|Anchovies}} -|34 -|{{NA}} -|31 -|30 -|{{Members|no}} -|- -|{{plinkt|Bread}} -|{{NA}} -|38 -|34 -|40 -|{{Members|no}} -|- -|{{plinkt|Sardine}} -|38 -|{{NA}} -|34 -|40 -|{{Members|no}} -|- -|{{plinkt|Herring}} -|41 -|{{NA}} -|38 -|50 -|{{Members|no}} -|- -|{{plinkt|Giant carp}} -|45 -|{{NA}} -|41 -|0 -|{{Members|yes}} -|- -|{{plinkt|Mackerel}} -|45 -|{{NA}} -|41 -|60 -|{{Members|yes}} -|- -|{{plinkt|Redberry pie}} -|{{NA}} -|45 -|42 -|78 -|{{Members|no}} -|- -|{{plinkt|Thin snail meat}} -|47 -|{{NA}} -|43 -|70 -|{{Members|yes}} -|- -|{{plinkt|Lean snail meat}} -|47 -|50 -|46 -|80 -|{{Members|yes}} -|- -|{{plinkt|Trout}} -|49 -|{{NA}} -|45 -|70 -|{{Members|no}} -|- -|{{plinkt|Cod}} -|51 -|49 -|47 -|75 -|{{Members|yes}} -|- -|{{plinkt|Pike}} -|54 -|{{NA}} -|49 -|80 -|{{Members|no}} -|- -|{{plinkt|Meat pie}} -|{{NA}} -|54 -|49 -|110 -|{{Members|no}} -|- -|{{plinkt|Fat snail meat}} -|56 -|{{NA}} -|51 -|95 -|{{Members|yes}} -|- -|{{plinkt|Stew}} -|58 -|{{NA}} -|54 -|117 -|{{Members|no}} -|- -|{{plinkt|Salmon}} -|58 -|{{NA}} -|55 -|90 -|{{Members|no}} -|- -|{{plinkt|Botanical pie}} -|{{NA}} -|84 -|52 -|180 -|{{Members|yes}} -|- -|{{plinkt|Mushroom pie}} -|{{NA}} -|89 -|60 -|200 -|{{Members|yes}} -|} - -===Meats=== -{| class="wikitable sortable align-left-2" style="text-align:center;" -|- -!colspan=2 rowspan=2|Food -!rowspan=2|[[Fire]] -!rowspan=2|[[Range]]{{Note|Generally lower chance of burning than on an open fire. Value is N/A if it does not reduce burn chance.|?}} -!colspan=2|[[Hosidius Kitchen|Hosidius]]{{Note|The Hosidius Kitchen range multiplies the chance-to-not-burn roll by 1.05 or 1.10 with the elite diary completed.|?}} -!rowspan=2|[[Experience]] -!rowspan=2|Members? -|- -!5% -![[Kourend & Kebos Diary#Rewards 4|10%]]The value will be N/A if the level required to not burn with the [[Elite Kourend & Kebos Diary]] completed is lower than the level required to complete the diary (level 84). -|- -|{{plinkt|Cooked meat}} -|34 -|{{NA}} -|31 -|{{NA}} -|30 -|{{Members|no}} -|- -|{{plinkt|Cooked chicken}} -|34 -|{{NA}} -|31 -|{{NA}} -|30 -|{{Members|no}} -|- -|{{plinkt|Cooked rabbit}} -|34 -|{{NA}} -|31 -|{{NA}} -|30 -|{{Members|yes}} -|- -|{{plinkt|Shrimps}} -|34 -|{{NA}} -|31 -|{{NA}} -|30 -|{{Members|no}} -|- -|{{plinkt|Anchovies}} -|34 -|{{NA}} -|31 -|{{NA}} -|30 -|{{Members|no}} -|- -|{{plinkt|Sardine}} -|38 -|{{NA}} -|34 -|{{NA}} -|40 -|{{Members|no}} -|- -|{{plinkt|Herring}} -|41 -|{{NA}} -|38 -|{{NA}} -|50 -|{{Members|no}} -|- -|{{plinkt|Mackerel}} -|45 -|{{NA}} -|42 -|{{NA}} -|60 -|{{Members|yes}} -|- -|{{plinkt|Thin snail meat}} -|47 -|{{NA}} -|43 -|{{NA}} -|70 -|{{Members|yes}} -|- -|{{plinkt|Lean snail meat}} -|47 -|50 -|47 -|{{NA}} -|95 -|{{Members|yes}} -|- -|{{plinkt|Spider on shaft}} -|48 -|{{NA}} -|45 -|{{NA}} -|80 -|{{Members|yes}} -|- -|{{plinkt|Spider on stick}} -|48 -|{{NA}} -|45 -|{{NA}} -|80 -|{{Members|yes}} -|- -|{{plinkt|Paddlefish}} -|{{NA}} -|48 -|{{NA}} -|{{NA}} -|15 -|{{Members|yes}} -|- -|{{plinkt|Trout}} -|49 -|{{NA}} -|46 -|{{NA}} -|70 -|{{Members|no}} -|- -|{{plinkt|Cooked wild kebbit}} -|50 -|{{NA}} -|47 -|{{NA}} -|73 -|{{Members|yes}} -|- -|{{plinkt|Cod}} -|51 -|49 -|46 -|{{NA}} -|75 -|{{Members|yes}} -|- -|{{plinkt|Pike}} -|54 -|{{NA}} -|50 -|{{NA}} -|80 -|{{Members|no}} -|- -|{{plinkt|Fat snail meat}} -|56 -|{{NA}} -|52 -|{{NA}} -|95 -|{{Members|yes}} -|- -|{{plinkt|Salmon}} -|58 -|{{NA}} -|55 -|{{NA}} -|90 -|{{Members|no}} -|- -|{{plinkt|Cooked larupia}} -|59 -|{{NA}} -|55 -|{{NA}} -|92 -|{{Members|yes}} -|- -|{{plinkt|Cooked slimy eel}} -|61 -|{{NA}} -|57 -|{{NA}} -|95 -|{{Members|yes}} -|- -|{{plinkt|Cooked giant crab meat}} -|62 -|{{NA}} -|59 -|{{NA}} -|100 -|{{Members|yes}} -|- -|{{plinkt|Cooked fishcake}} -|62 -|{{NA}} -|59 -|{{NA}} -|100 -|{{Members|yes}} -|- -|{{plinkt|Tuna}} -|63 -|{{NA}} -|59 -|{{NA}} -|100 -|{{Members|no}} -|- -|{{plinkt|Cooked barb-tailed kebbit}} -|63 -|{{NA}} -|60 -|{{NA}} -|106 -|{{Members|yes}} -|- -|{{plinkt|Rainbow fish}} -|64 -|{{NA}} -|60 -|{{NA}} -|110 -|{{Members|yes}} -|- -|{{plinkt|Cave eel}} -|74 -|{{NA}} -|70 -|{{NA}} -|115 -|{{Members|yes}} -|- -|{{plinkt|Cooked graahk}} -|75 -|{{NA}} -|71 -|{{NA}} -|124 -|{{Members|yes}} -|- -|{{plinkt|Bass}} -|79 - -|{{NA}} -|75 -|{{NA}} -|130 -|{{Members|yes}} -|- -|{{plinkt|Cooked pyre fox}} -|93 -|92 -|87 -|{{NA}} -|154 -|{{Members|yes}} -|- -|{{plinkt|Cooked sunlight antelope}} -| - -|95 -|91 -|86 -|175 -|{{Members|yes}} -|- -|{{plinkt|Cooked jubbly}} -|? -|{{NA}} -|{{NA}} -|{{NA}} -|160 -|{{Members|yes}} -|- -|{{plinkt|Cooked chompy}} -|99 -|{{NA}} -|{{NA}} -|{{NA}} -|100 -|{{Members|yes}} -|- -|{{plinkt|Cooked karambwan}} -|99 -|{{NA}} -|93 -|87 -|190 -|{{Members|yes}} -|- -|{{plinkt|Poison karambwan}} -|99 -|{{NA}} -|93 -|87 -|80 -|{{Members|yes}} -|- -|{{plinkt|Roast beast meat}} -|99 -|{{NA}} -|{{NA}} -|{{NA}} -|82.5 -|{{Members|yes}} -|- -|{{plinkt|Roast bird meat}} -|99 -|{{NA}} -|{{NA}} -|{{NA}} -|60 -|{{Members|yes}} -|- -|{{plinkt|Roast rabbit}} -|99 -|{{NA}} -|{{NA}} -|{{NA}} -|72.5 -|{{Members|yes}} -|- -|{{plinkt|Ugthanki meat}} -| - -| - -|95 -|90 -|40 -|{{Members|yes}} -|- -|{{plinkt|Sea turtle}} -| - -| - -| - -| - -|211.3 -|{{Members|yes}} -|- -|{{plinkt|Cooked dashing kebbit}} -| - -| - -| - -| - -|215 -|{{Members|yes}} -|- -|{{plinkt|Dark crab}} -| - -| - -| - -| - -|215 -|{{Members|yes}} -|- -|{{plinkt|Manta ray}} -| - -| - -| - -| - -|216.3 -|{{Members|yes}} -|- -|{{plinkt|Cooked moonlight antelope}} -| - -| - -| - -| - -|220 -|{{Members|yes}} -|} -{{Reflist|group=h}} - -===Baked goods=== -{| class="wikitable sortable align-left-2" style="text-align:center;" -|- -!colspan=2 rowspan=2|Food -!rowspan=2|[[Range]] -!colspan=2|[[Hosidius Kitchen|Hosidius]]{{Note|The Hosidius Kitchen range multiplies the chance-to-not-burn roll by 1.05 or 1.10 with the elite diary completed.|?}} -!rowspan=2|[[Experience]] -!rowspan=2|Members? -|- -!5% -![[Kourend & Kebos Diary#Rewards 4|10%]]The value will be N/A if the level required to not burn with the [[Elite Kourend & Kebos Diary]] completed is lower than the level required to complete the diary (level 84). -|- -|{{plinkt|Bread}} -|38 -|34 -|{{NA}} -|40 -|{{Members|no}} -|- -|{{plinkt|Pitta bread}} -|38 -|{{NA}} -|{{NA}} -|40 -|{{Members|yes}} -|- -|{{plinkt|Redberry pie}} -|45 -|42 -|{{NA}} -|78 -|{{Members|no}} -|- -|{{plinkt|Meat pie}} -|54 -|50 -|{{NA}} -|110 -|{{Members|no}} -|- -|{{plinkt|Apple pie}} -|63 -|59 -|{{NA}} -|130 -|{{Members|no}} -|- -|{{plinkt|Mud pie}} -|63 -|59 -|{{NA}} -|128 -|{{Members|yes}} -|- -|{{plinkt|Plain pizza}} -|68 -|64 -|{{NA}} -|143 -|{{Members|no}} -|- -|{{plinkt|Garden pie}} -|68 -|64 -|{{NA}} -|138 -|{{Members|yes}} -|- -|{{plinkt|Fish pie}} -|74 -|70 -|{{NA}} -|164 -|{{Members|yes}} -|- -|{{plinkt|Cake}} -|74 -|70 -|{{NA}} -|180 -|{{Members|no}} -|- -|{{plinkt|Botanical pie}} -|84 -|80 -|{{NA}} -|180 -|{{Members|yes}} -|- -|{{plinkt|Mushroom pie}} -|89 -|84 -|{{NA}} -|200 -|{{Members|yes}} -|- -|{{plinkt|Admiral pie}} -|94 -|89 -|84 -|210 -|{{Members|yes}} -|- -|{{plinkt|Dragonfruit pie}} -| - -|97 -|92 -|220 -|{{Members|yes}} -|- -|{{plinkt|Wild pie}} -| - -| - -| - -|240 -|{{Members|yes}} -|- -|{{plinkt|Summer pie}} -| - -| - -| - -|260 -|{{Members|yes}} -|} -{{Reflist|group=h}} - -===Other foods=== -{| class="wikitable sortable align-left-2" style="text-align:center;" -|- -!colspan=2 rowspan=2|Food -!rowspan=2|[[Fire]]/[[Range]] -!colspan=2|[[Hosidius Kitchen|Hosidius]]{{Note|The Hosidius Kitchen range multiplies the chance-to-not-burn roll by 1.05 or 1.10 with the elite diary completed.|?}} -!rowspan=2|[[Experience]] -!rowspan=2|Members? -|- -!5% -![[Kourend & Kebos Diary#Rewards 4|10%]]The value will be N/A if the level required to not burn with the [[Elite Kourend & Kebos Diary]] completed is lower than the level required to complete the diary (level 84). -|- -|{{plinkt|Baked potato}} -|41 -|38 -|{{NA}} -|15 -|{{Members|yes}} -|- -|{{plinkt|Scrambled egg}} -|48 -|45 -|{{NA}} -|50 -|{{Members|yes}} -|- -|{{plinkt|Cooked sweetcorn}} -|54 -|50 -|{{NA}} -|104 -|{{Members|yes}} -|- -|{{plinkt|Nettle tea}} -|54 -|50 -|{{NA}} -|52 -|{{Members|yes}} -|- -|{{plinkt|Stew}} -|58 -|55 -|{{NA}} -|117 -|{{Members|no}} -|- -|{{plinkt|Curry}} -|74 -|70 -|{{NA}} -|280 -|{{Members|yes}} -|- -|{{plinkt|Fried onions}} -|77 -|73 -|{{NA}} -|60 -|{{Members|yes}} -|- -|{{plinkt|Fried mushrooms}} -|90 -|85 -|81 -|60 -|{{Members|yes}} -|} -{{Reflist|group=h}} - -===Ruins of Camdozaal fish=== -{| class="wikitable sortable align-left-2" style="text-align:center;" -|- -!colspan=2|Fish -![[Preparation Table]] -![[Experience]] -!Members? -|- -|{{plinkt|Guppy}} -|42 -|12 -|{{Members|no}} -|- -|{{plinkt|Cavefish}} -|53 -|23 -|{{Members|no}} -|- -|{{plinkt|Tetra}} -|61 -|31 -|{{Members|no}} -|- -|{{plinkt|Catfish}} -|78 -|43 -|{{Members|yes}} -|} - -===Gnome cooking=== -{| class="wikitable sortable align-left-2" style="text-align:center;" -|- -!colspan=2 rowspan=2|Food -!rowspan=2|[[Range]] -!colspan=2|[[Hosidius Kitchen|Hosidius]]{{Note|The Hosidius Kitchen range multiplies the chance-to-not-burn roll by 1.05 or 1.10 with the elite diary completed.|?}} -!rowspan=2|[[Experience]] -!rowspan=2|Members? -|- -!5% -![[Kourend & Kebos Diary#Rewards 4|10%]]The value will be N/A if the level required to not burn with the [[Elite Kourend & Kebos Diary]] completed is lower than the level required to complete the diary (level 84). -|- -|{{plinkt|Toad crunchies}} -|38 -|34 -|{{NA}} -|100 -|{{Members|yes}} -|- -|{{plinkt|Spicy crunchies}} -|38 -|34 -|{{NA}} -|100 -|{{Members|yes}} -|- -|{{plinkt|Worm crunchies}} -|38 -|34 -|{{NA}} -|100 -|{{Members|yes}} -|- -|{{plinkt|Chocchip crunchies}} -|38 -|34 -|{{NA}} -|100 -|{{Members|yes}} -|- -|{{plinkt|Fruit batta}} -|38 -|34 -|{{NA}} -|150 -|{{Members|yes}} -|- -|{{plinkt|Toad batta}} -|38 -|34 -|{{NA}} -|152 -|{{Members|yes}} -|- -|{{plinkt|Worm batta}} -|38 -|34 -|{{NA}} -|154 -|{{Members|yes}} -|- -|{{plinkt|Vegetable batta}} -|38 -|34 -|{{NA}} -|156 -|{{Members|yes}} -|- -|{{plinkt|Cheese+tom batta}} -|38 -|34 -|{{NA}} -|158 -|{{Members|yes}} -|- -|{{plinkt|Worm hole}} -|38 -|34 -|{{NA}} -|170 -|{{Members|yes}} -|- -|{{plinkt|Veg ball}} -|38 -|{{NA}} -|{{NA}} -|175 -|{{Members|yes}} -|- -|{{plinkt|Tangled toad's legs}} -|38 -|{{NA}} -|{{NA}} -|185 -|{{Members|yes}} -|- -|{{plinkt|Chocolate bomb}} -|38 -|{{NA}} -|{{NA}} -|190 -|{{Members|yes}} -|} -{{Reflist|group=h}} - -===Raids food=== -{| class="wikitable sortable align-left-2" style="text-align:center;" -|- -!colspan=2|Food -![[Fire]] -![[Experience]] -!Members? -|- -|{{plinkt|Kyren fish (6)|txt=Kyren fish}} -|? -|28 -|{{Members|yes}} -|- -|{{plinkt|Psykk bat (6)|txt=Psykk bat}} -|? -|28 -|{{Members|yes}} -|- -|{{plinkt|Roqed fish (5)|txt=Roqed fish}} -|? -|25 -|{{Members|yes}} -|- -|{{plinkt|Murng bat (5)|txt=Murng bat}} -|? -|25 -|{{Members|yes}} -|- -|{{plinkt|Mycil fish (4)|txt=Mycil fish}} -|? -|22 -|{{Members|yes}} -|- -|{{plinkt|Kryket bat (4)|txt=Kryket bat}} -|? -|22 -|{{Members|yes}} -|- -|{{plinkt|Brawk fish (3)|txt=Brawk fish}} -|? -|19 -|{{Members|yes}} -|- -|{{plinkt|Phluxia bat (3)|txt=Phluxia bat}} -|? -|19 -|{{Members|yes}} -|- -|{{plinkt|Leckish fish (2)|txt=Leckish fish}} -|? -|16 -|{{Members|yes}} -|- -|{{plinkt|Giral bat (2)|txt=Giral bat}} -|? -|16 -|{{Members|yes}} -|- -|{{plinkt|Suphi fish (1)|txt=Suphi fish}} -|? -|13 -|{{Members|yes}} -|- -|{{plinkt|Prael bat (1)|txt=Prael bat}} -|? -|13 -|{{Members|yes}} -|- -|{{plinkt|Pysk fish (0)|txt=Pysk fish}} -|? -|10 -|{{Members|yes}} -|- -|{{plinkt|Guanic bat (0)|txt=Guanic bat}} -|? -|10 -|{{Members|yes}} -|} - -==Obtaining burnt food items== - -If one's Cooking level is too high to obtain a particular burnt food, it is possible to temporarily lower it by making use of the [[chill]] effect or drinking [[Chilhuac red]]. [[Ghommal's hilt]] is particularly useful for this, as it can be used to teleport to the entrance of [[God Wars Dungeon]]. - -{| class="wikitable sortable align-center-1" -!colspan=2|Item -!Obtaining -!Burn level range
(lowest to highest) -!Members? -|- -|{{plinkt|Burnt shrimp}} -|Use on fire for highest rate. -|1-34 -|{{Members|no}} -|- -|{{plinkt|Burnt fish (sardine)}} -|Use on fire for highest rate. -|1-35 -|{{Members|no}} -|- -|{{plinkt|Burnt fish (herring)|txt=Burnt fish}}
([[herring]], [[mackerel]]*) -|Use on fire or collect spawn in Catherby -|5-41, 10-45 -|{{Members|no}} -|- -|{{plinkt|Burnt fish (anchovies)}} -|Use on fire for highest rate,
or collect spawn near the [[Myths' Guild]] -|1-34 -|{{Members|no}} -|- -|{{plinkt|Burnt fish (Chambers of Xeric)|txt=Burnt fish}} ([[Pysk fish (0)|pysk]], [[Suphi fish (1)|suphi]],
[[Leckish fish (2)|leckish]], [[Brawk fish (3)|brawk]], [[Mycil fish (4)|mycil]],
[[Roqed fish (5)|roqed]], [[Kyren fish (6)|kyren]]) -|[[Chambers of Xeric]] -|1, 15, 30,
45, 60, 75, 90 -|{{Members|yes}} -|- -|{{plinkt|Burnt bat}} ([[Guanic bat (0)|guanic]], [[Prael bat (1)|prael]],
[[Giral bat (2)|giral]], [[Phluxia bat (3)|phluxia]], [[Kryket bat (4)|kryket]],
[[Murng bat (5)|murng]], [[Psykk bat (6)|psykk]]) -|[[Chambers of Xeric]] -|1, 15, 30,
45, 60, 75, 90 -|{{Members|yes}} -|- -|{{plinkt|Burnt fish (trout)|txt=Burnt fish}} ([[cod]]*, [[pike]],
[[trout]], [[salmon]]) -|Use on fire for highest rate. -|18-52, 20-59,
15-50, 25-58 -|{{Members|no}} -|- -|{{plinkt|Burnt fish (tuna)|txt=Burnt fish}} ([[bass]]*, [[tuna]]) -|Use on fire for highest rate. -|43-80, 30-63 -|{{Members|no}} -|- -|{{plinkt|Burnt eel}} -|Use on fire for highest rate. -|28-58 -|{{Members|yes}} -|- -|{{plinkt|Burnt cave eel}} -|Use on fire for highest rate. -|38-73 -|{{Members|yes}} -|- -|{{plinkt|Burnt rainbow fish}} -|Use on fire for highest rate. -|35-63 -|{{Members|yes}} -|- -|{{plinkt|Burnt lobster}} -|Use on fire for highest rate. -|40-74 -|{{Members|no}} -|- -|{{plinkt|Burnt swordfish}} -|Use on fire for highest rate. -|45-81 -|{{Members|no}} -|- -|{{plinkt|Burnt karambwan}} -|[[Tai Bwo Wannai Trio]], thorough -|30-99+ -|{{Members|yes}} -|- -|{{plinkt|Burnt monkfish}} -|Use on fire for highest rate. -|62-92 -|{{Members|yes}} -|- -|{{plinkt|Burnt shark}} -|Use on fire for highest rate. -|80-99 -|{{Members|yes}} -|- -|{{plinkt|Burnt sea turtle}} -|Use on fire for highest rate. -|82-99+ -|{{Members|yes}} -|- -|{{plinkt|Burnt anglerfish}} -|Use on fire for highest rate. -|84-99 -|{{Members|yes}} -|- -|{{plinkt|Burnt dark crab}} -|Use on fire for highest rate. -|90-99+ -|{{Members|yes}} -|- -|{{plinkt|Burnt manta ray}} -|Use on fire for highest rate. -|91-99+ -|{{Members|yes}} -|- -|{{plinkt|Burnt bread}} -|[[Cooking range|Range]] only, [[Imp]] drop -|1-37 -|{{Members|no}} -|- -|{{plinkt|Burnt pie}} ([[Mud pie|mud]]*, [[Meat pie|meat]],
[[Redberry pie|redberry]], [[Apple pie|apple]], [[Garden pie|garden]]*,
[[Fish pie|fish]]*, [[Botanical pie|botanical]]*, [[Admiral pie|admiral]]*,
[[Wild pie|wild]]*, [[Summer pie|summer]]) -|[[Cooking range|Range]] only -|29, 30, 10-50,
30, 34, 47, 52,
70-94, 85-99, 95-99 -|{{Members|no}} -|- -|{{plinkt|Burnt pizza}} ([[Plain pizza|plain]], [[Meat pizza|meat]],
[[Anchovy pizza|anchovy]], [[Pineapple pizza|pineapple]]*) -|[[Cooking range|Range]] only -|35-67 -|{{Members|no}} -|- -|{{plinkt|Burnt cake}}
([[cake]], [[chocolate cake]]) -|[[Cooking range|Range]] only -|55 -|{{Members|no}} -|- -|{{plinkt|Burnt chicken}} -|[[Cooked chicken|Cooked item]] -> fire -|1-31 -|{{Members|no}} -|- -|{{plinkt|Burnt meat}} -|[[Cooked meat|Cooked item]] -> fire, [[imp]] drop, spawn in Weiss -|1-31 -|{{Members|no}} -|- -|{{plinkt|Burnt rabbit}} -|[[Iron spit]] required -|1 -|{{Members|yes}} -|- -|{{plinkt|Burnt bird meat}} -|[[Iron spit]] required -|11 -|{{Members|yes}} -|- -|{{plinkt|Burnt snail}}
([[Lean snail meat|lean]], [[Thin snail meat|thin]], [[Fat snail meat|fat]]) -|Use on fire for highest rate. -|17, 12, 22 -|{{Members|yes}} -|- -|{{plinkt|Burnt spider|txt=Burnt spider (stick)}} -|[[Skewer stick]], fire highest rate. -|16-45 -|{{Members|yes}} -|- -|{{plinkt|Burnt beast meat}} -|[[Iron spit]] required -|21 -|{{Members|yes}} -|- -|{{plinkt|Ruined chompy}} -|Use on fire for highest rate. -|30 -|{{Members|yes}} -|- -|{{plinkt|Burnt jubbly}} -|Self-obtain, [[Rantz]]/[[Jiggig]] spit,
'''partial''' [[Recipe for Disaster]] -|41 -|{{Members|yes}} -|- -|{{plinkt|Burnt oomlie}} -|[[Raw oomlie|Raw item]] -> fire. -|50 -|{{Members|yes}} -|- -|{{plinkt|Burnt oomlie wrap}} -|see on [[Burnt oomlie wrap]]. -|1-44 -|{{Members|yes}} -|- -|{{plinkt|Burnt egg}} -|[[Cooking range|Range]] only -|13 -|{{Members|yes}} -|- -|{{plinkt|Burnt onion}} -|[[Cooking range|Range]] only -|42 -|{{Members|yes}} -|- -|{{plinkt|Burnt mushroom}} -|[[Cooking range|Range]] only -|46 -|{{Members|yes}} -|- -|{{plinkt|Burnt stew}} -|[[Cooking range|Range]] only -|25-57 -|{{Members|no}} -|- -|{{plinkt|Burnt curry|pic=Burnt stew}} -| -|60-73 -|{{Members|yes}} -|- -|{{plinkt|Burnt potato}} -|[[Cooking range|Range]] only -|1-41 -|{{Members|yes}} -|- -|{{plinkt|Burnt crunchies}} -|[[Gnome Restaurant]] -|10 -|{{Members|yes}} -|- -|{{plinkt|Burnt batta}} -|[[Gnome Restaurant]] -|20 -|{{Members|yes}} -|- -|{{plinkt|Burnt sweetcorn}} -|Use on fire for highest rate. -|28-53 -|{{Members|yes}} -|- -|{{plinkt|Burnt gnomebowl}} -|[[Gnome Restaurant]] -|30 -|{{Members|yes}} -|- -|{{plinkt|Spider on shaft (burnt)}} -|[[Arrow shaft]], fire highest rate. -|16-45 -|{{Members|yes}} -|} - -[[Category:Food]] -[[Category:Cooking]] diff --git a/wikidata/burnt_food.wikisrc b/wikidata/burnt_food.wikisrc deleted file mode 100644 index 5efbb1b0..00000000 --- a/wikidata/burnt_food.wikisrc +++ /dev/null @@ -1,303 +0,0 @@ -{{External|rs|rsc|dw}} -{{Otheruses|all the forms of burnt food|when food stops burning|Cooking/Burn level}} -'''Burnt food''' is the result of a normal occurrence when [[Cooking]]. Burning food happens when the player's Cooking level is not high enough to not burn the food, and the chance of burning decreases as the higher Cooking level the player has. Most food will eventually stop burning at a certain cooking level; however, some foods always have a chance to burn unless wearing a [[Cooking cape]]. [[Meat]] and [[chicken]] can also be burnt by trying to cook their cooked variants. When cooking, a [[fire]] has the highest chance to burn food, using a [[range]] decreases the chance, reduced further with some foods when using the [[cooking gauntlets]], [[Cooking range (Lumbridge Castle)|Lumbridge Castle cooking range]], or the [[Hosidius Kitchen]]. - -Although selling burnt food to [[general store]]s yields {{NoCoins|0}} coins and is not tradeable on the Grand Exchange, some player collectors may pay for them, though prices vary and are dependent on the type and quantity of food. - -There are currently 48 unique varieties of burnt food which are obtainable and tradeable between player collectors, 50 including [[ruined herb tea]] and [[Ugthanki kebab (smelling)]]. - -==Types of burnt food== -{|class="wikitable sortable lighttable" -! -!Item -!Raw version -!Cooking level -!Cooked version -|- -|{{plinkt|Burnt bat}} -|Varies -|1 -|Varies -|- -|{{plinkt|Burnt bread}} -|[[Bread dough]] -|1 -|[[Bread]] -|- -|{{plinkt|Burnt chicken}} -|[[Raw chicken]] -|1 -|[[Cooked chicken]] -|- -|{{plinkt|Burnt fish (Chambers of Xeric)|txt=Burnt fish}} -|Varies -|1 -|Varies -|- -|{{plinkt|Burnt meat}} -|[[Raw meat]] -|1 -|[[Cooked meat]] -|- -|{{plinkt|Burnt shrimp}} -|[[Raw shrimp]] -|1 -|[[Shrimp]] -|- -|{{plinkt|Burnt fish (herring)|txt=Burnt fish}} -|[[Raw herring]]/[[Raw mackerel]] -|5 -|[[Herring]]/[[Mackerel]] -|- -|{{plinkt|Burnt fish (sardine)|txt=Burnt fish}} -|[[Raw sardine]] -|5 -|[[Sardine]] -|- -|{{plinkt|Burnt potato}} -|[[Potato]] -|7 -|[[Baked potato]] -|- -|{{plinkt|Burnt crunchies}} -|[[Raw crunchies]] -|10 -|[[Half baked crunchy]] -|- -|{{plinkt|Burnt fish (anchovies)|txt=Burnt fish}} -|[[Raw anchovies]] -|10 -|[[Anchovies]] -|- -|{{plinkt|Burnt pie}} -|[[Raw pies]] -|10 -|[[Pies]] -|- -|{{plinkt|Burnt bird meat}} -|[[Raw bird meat]] -|11 -|[[Roast bird meat]] -|- -|{{plinkt|Burnt snail}} -|[[Thin snail]]/[[Lean snail]]/[[Fat snail]] -|12 -|[[Thin snail meat]]/[[Lean snail meat]]/[[Fat snail meat]] -|- -|{{plinkt|Burnt egg}} -|[[Uncooked egg]] -|13 -|[[Scrambled egg]] -|- -|{{plinkt|Burnt rabbit}} -|[[Skewered rabbit]] -|16 -|[[Roast rabbit]] -|- -|{{plinkt|Burnt spider}} -|[[Spider on stick]] -|16 -|[[Spider on stick]] -|- -|{{plinkt|Spider on shaft (burnt)}} -|[[Spider on shaft]] -|16 -|[[Spider on shaft]] -|- -|{{plinkt|Burnt fish (trout)|txt=Burnt fish}} -|[[Raw cod]]/[[Raw pike]]/[[Raw trout]]/[[Raw salmon]] -|18 -|[[Cod]]/[[Pike]]/[[Trout]]/[[Salmon]] -|- -|{{plinkt|Burnt batta}} -|[[Raw batta]] -|20 -|[[Half baked batta]] -|- -|{{plinkt|Burnt beast meat}} -|[[Raw beast meat]] -|21 -|[[Roast beast meat]] -|- -|{{plinkt|Burnt giant crab meat}}These items are untradeable. -|[[Giant crab meat]] -|21 -|[[Cooked giant crab meat]] -|- -|{{plinkt|Burnt kebbit}} -|[[Raw wild kebbit]]/[[raw barb-tailed kebbit|barb-tailed kebbit]]/[[raw dashing kebbit|dashing kebbit]] -|23 -|[[Cooked wild kebbit]]/[[cooked barb-tailed kebbit|barb-tailed kebbit]]/[[cooked dashing kebbit|dashing kebbit]] -|- -|{{plinkt|Burnt stew}} -|[[Uncooked stew]] -|25 -|[[Stew]] -|- -|{{plinkt|Burnt eel}} -|[[Slimy eel]] -|28 -|[[Cooked slimy eel]] -|- -|{{plinkt|Burnt sweetcorn}} -|[[Sweetcorn]] -|28 -|[[Cooked sweetcorn]] -|- -|{{plinkt|Burnt fish (tuna)|txt=Burnt fish}} -|[[Raw bass]]/[[Raw tuna]] -|30 -|[[Bass]]/[[Tuna]] -|- -|{{plinkt|Burnt gnomebowl}} -|[[Raw gnomebowl]] -|30 -|[[Half baked bowl]] -|- -|{{plinkt|Burnt karambwan}} -|[[Raw karambwan]] -|30 -|[[Cooked karambwan]] -|- -|{{plinkt|Ruined chompy}} -|[[Raw chompy]] -|30 -|[[Cooked chompy]] -|- -|{{plinkt|Burnt fishcake}} -|[[Raw fishcake]] -|31 -|[[Cooked fishcake]] -|- -|{{plinkt|Burnt large beast}} -|[[Raw larupia]]/[[raw graahk|graahk]]/[[raw kyatt|kyatt]] -|31 -|[[Cooked larupia]]/[[cooked graahk|graahk]]/[[cooked kyatt|kyatt]] -|- -|{{plinkt|Burnt pizza}} -|[[Uncooked pizza]] -|35 -|[[Pizza]] -|- -|{{plinkt|Burnt rainbow fish}} -|[[Raw rainbow fish]] -|35 -|[[Rainbow fish]] -|- -|{{plinkt|Burnt cave eel}} -|[[Raw cave eel]] -|38 -|[[Cave eel]] -|- -|{{plinkt|Burnt cake}} -|[[Uncooked cake]] -|40 -|[[Cake]] -|- -|{{plinkt|Burnt lobster}} -|[[Raw lobster]] -|40 -|[[Lobster]] -|- -|{{plinkt|Burnt jubbly}} -|[[Raw jubbly]] -|41 -|[[Cooked jubbly]] -|- -|{{plinkt|Burnt onion}} -|[[Chopped onion]] -|42 -|[[Fried onions]] -|- -|{{plinkt|Burnt swordfish}} -|[[Raw swordfish]] -|45 -|[[Swordfish]] -|- -|{{plinkt|Burnt mushroom}} -|[[Sliced mushrooms]] -|46 -|[[Fried mushrooms]] -|- -|{{plinkt|Burnt oomlie}} -|[[Raw oomlie]] -|50 -|None -|- -|{{plinkt|Burnt oomlie wrap}} -|[[Wrapped oomlie]] -|50 -|[[Oomlie wrap]] -|- -|{{plinkt|Burnt pitta bread}}{{CiteTwitter|author=Mod Ash|url=https://twitter.com/JagexAsh/status/985833852022206464|date=16 April 2018|archiveurl=https://archive.is/2hUgv|archivedate=26 May 2020|quote=Yeah, it looks like the fail chance is already 0 by the time you have the minimum level.}} -|[[Pitta dough]] -|58 -|[[Pitta bread]] -|- -|{{plinkt|Burnt fox meat}} -|[[Raw pyre fox]] -|59 -|[[Cooked pyre fox]] -|- -|{{plinkp|Burnt stew}} -|[[Burnt curry]] -|[[Uncooked curry]] -|60 -|[[Curry]] -|- -|{{plinkt|Burnt monkfish}} -|[[Raw monkfish]] -|62 -|[[Monkfish]] -|- -|{{plinkt|Burnt antelope}} -|[[Raw sunlight antelope]]/[[Raw moonlight antelope|moonlight antelope]] -|68 -|[[Cooked sunlight antelope]]/[[Cooked moonlight antelope|moonlight antelope]] -|- -|{{plinkt|Snake over-cooked}} -|[[Raw stuffed snake]] -|70 -|[[Stuffed snake]] -|- -|{{plinkt|Burnt shark}} -|[[Raw shark]] -|80 -|[[Shark]] -|- -|{{plinkt|Burnt sea turtle}} -|[[Raw sea turtle]] -|82 -|[[Sea turtle]] -|- -|{{plinkt|Burnt anglerfish}} -|[[Raw anglerfish]] -|84 -|[[Anglerfish]] -|- -|{{plinkt|Burnt dark crab}} -|[[Raw dark crab]] -|90 -|[[Dark crab]] -|- -|{{plinkt|Burnt manta ray}} -|[[Raw manta ray]] -|91 -|[[Manta ray]] -|} - -==Burn level== -{{Main|Cooking/Burn level}} -==See also== -*[[Food]] -*[[Cooking]] - -==Trivia== -*[[Ruined chompy]], [[spider on shaft (burnt)|spider on shaft]], and [[snake over-cooked]] are the only burnt food items without 'burnt' in the name. -*Burnt foods do not leave [[placeholder]]s when withdrawn from the bank. - -==References== -{{Reflist}} -{{Burnt food}} -[[Category:Food]] -[[Category:Cooking]] diff --git a/wikidata/cooking.wikisrc b/wikidata/cooking.wikisrc deleted file mode 100644 index 95e923e7..00000000 --- a/wikidata/cooking.wikisrc +++ /dev/null @@ -1,788 +0,0 @@ -{{External|rs|rsc|dw}} -{{Otheruses|def=no|a list of all requirements and unlockables within the Cooking skill|Cooking/Level up table}} -{{Has calculator|Calculator:Cooking}} -{{Has skill guide|members=Pay-to-play Cooking training|free=Free-to-play Cooking training|iron=Ironman Guide/Cooking|UIM=Ultimate Ironman Guide/Cooking}} -{{Infobox Skill -|name = Cooking -|image = [[File:Cooking icon.png]] -|release = [[4 January]] [[2001]] -|update = Runescape beta is now online! -|aka = Cook -|members = No -|type = Production -}} -[[File:Cooking icon (detail).png|left]] -'''Cooking''' is a [[skill]] that allows raw [[food]] to be made edible, healing [[hitpoints]] when eaten. To do this, the player uses a raw, cookable food on a [[range]] or [[fire]]. - -Depending on the player's Cooking level, food will sometimes burn, becoming unusable. Ranges burn food less often than fires at the same level, and some foods can only be cooked on ranges. Some ranges, such as the [[Cooking range (Lumbridge Castle)|one]] in the [[Lumbridge Castle]] or in the [[Hosidius Kitchen]], burn food less often than a normal range. - -Cooking goes hand-in-hand with the [[Fishing]] skill as the player can cook the fish they obtain. If no range is nearby, having an [[axe]] and [[tinderbox]] on hand can allow the player to cut down a tree and make a fire to cook the fish on. - -By levelling Cooking, the player is able to cook better foods such as [[swordfish]], [[shark]], [[pies]], and [[pizza]]s. If a player achieves 32 cooking, they can access the [[Cooks' Guild|Cook's Guild]] near the Grand Exchange. - -{{Listen -|align = right -|title = Cooking level up - normal -|filename = Cooking Level Up!.ogg -|desc = The music that plays when levelling up.}} - -{{Listen -|align = right -|title = Cooking level up - with unlocks -|filename = Cooking Level Up! (Unlocks).ogg -|desc = The music that plays when levelling up and unlocking new content.}} - -==How to cook== -Cooking is known as one of the fastest skills to train, as players can cook in many different ways as well as being able to simply buy their raw food items from the [[Grand Exchange]]. - -Before the Grand Exchange was created, the bulk of players usually fished and then cooked their catches. Generally a player who is manually gathering their raw items will cook their food items on a local [[Fire|campfire]] created through the [[Firemaking]] skill near where they are gathering, or take the items they have obtained to a [[range]] and cook there. - -Ranges (which provide a lower burn rate) can be easily located and are almost always well labelled on the [[World map|map]] as a cooking pan ([[File:Cooking range icon.png|The cooking range icon on the map]]) [[icon]]. There are other assorted things that a player can cook on, seen in NPC camps, or on [[iron spit]]s. It is important to note that only meat, [[fish]] and [[stew]] can be cooked on an open fire. Foods like [[bread]], [[cake]], and [[pie]] must be cooked on a proper range, Most of these food items will generate an error message if the player attempts to cook it improperly while others, such as raw potatoes, will simply all burn. Raw foods loosely related to the [[Hunter]] skill, such as [[raw beast meat]], [[raw chompy]], and [[raw rabbit meat|rabbit]], must be cooked on an iron spit. - -To actually cook something, players have to "use" their raw food item on a range or a campfire. If they have more than one food item of the same kind in their inventory, a picture of the food item will appear in the dialogue box. Ranges can also be left-clicked to automatically bring up this interface. The player can right-click on the picture and select how many they want to cook, or left click to cook all of them (default option). - -If this is your first time cooking follow these steps for maximum effect: - -* Cook on the [[Cooking range (Lumbridge Castle)|Lumbridge Castle range]] after completion of [[Cook's Assistant]], as there is a bank directly upstairs and the range offers a lower burn rate than other ranges on selected foods. -* Cooking at the [[Rogues' Den]] has a permanent fire and is directly next to a banker ''([[members]] only)''. -* Consider completing [[Kourend & Kebos Diary#Easy|Easy]] Kourend and Kebos diary for 5% increased chance to succeed cooking anything when cooking in Hosidius range and completing [[Family Crest|Family Crest quest]] to gain increased chance of cooking successfully on [[Cooking gauntlets|selected few raw foods]]. - -==Burning food== -{{main|Burnt food}} -As players train Cooking, they will sometimes fail to cook something at random, resulting in no Cooking experience gained. It is normal when you first begin training this skill to burn nearly anything you cook on a fire or range, but as you gain more levels the burn ratio of food decreases until you reach a level where you can no longer burn them. - -A table of the levels where cooking food items becomes successful 100% of the time can be found [[Cooking/Burn level|here]]. - -A useful item to equip while training are [[cooking gauntlets]]. Wearing these gloves while training Cooking will cut down time and money due to less food being burnt. This is useful for food such as [[shark]]s where even at 99 you have the chance to burn them; with the cooking gauntlets equipped, you will stop burning sharks at level 94. Alternatively, cooking food while wearing a [[cooking cape]] will ensure that no food may be burned by the player. - -All [[range]]s have a lower burn rate than [[Fire|fires]], but there are also special ranges which offer decreased burn rates. These can work in conjunction with the cooking gauntlets. Unless the player is cooking something with 100% success rate, it is recommended to use these where possible to decrease the amount of burnt food. The recommended range to cook on for members is in the [[Hosidius Kitchen]], usable after completion of the [[Kourend & Kebos Diary#Easy|Easy Kourend & Kebos Diary]]. This range grants a 5% increased chance to successfully cook food (10% if [[Kourend & Kebos Diary#Elite|Elite Kourend & Kebos Diary]] is completed) and is very close to a bank chest. - -The [[Cooking range (Lumbridge Castle)|range]] in Lumbridge Castle also has a lower burn rate for some foods, usable after completing the [[Cook's Assistant]] quest. The nearest bank to this range (for members) is the [[Culinaromancer's Chest]] in the cellar, which requires the first part of the [[Recipe for Disaster]] quest to be completed, or the bank at the top of [[Lumbridge Castle]] for free players. - -==Items needed== -As Cooking is the skill of turning food from raw to edible, and there is a very wide range of available food types in ''RuneScape'', there are many items that players need in order to cook food. Depending on what you are cooking, you will need a variety of items such as water or flour. Listed below are the cardinal cooking items which are used to make the most common types of food. - -* [[Fish]] ([[raw lobster]], [[raw trout]], etc.) -* [[Flour]] (held in a [[pot]]) -* [[Water]] (Held in a [[bucket]], [[bowl]], [[vial]] or [[jug]]) -* [[Milk]] (held in a bucket) -* [[Meat]] ([[raw meat]], [[raw rat meat]], [[raw bear meat]], [[raw yak meat]], [[raw chicken]]) -* Vegetables ([[cabbage]]s, [[grain]], [[onion]]s, [[potato]]es) -* Fruits ([[cooking apple]]s, [[grapes]], [[banana]]s, [[redberries]], [[tomato]]es) -* [[Cheese]] -* [[Bowl]] -* [[Bucket]] -* [[Cake tin]] -* [[Jug]] -* [[Pie dish]] -* [[Pot]] -* [[Knife]] - -==Types of food== -===Meat / fish=== -{| class="wikitable sortable align-left-3" style="text-align:center;" -!Level -! colspan="2" |Item -! data-sort-type="number" |XP -! data-sort-type="number" |Healing -!Members -|- -|1||{{plinkt|Cooked meat}}||30||3||{{members|No}} -|- -|1||{{plinkt|Sinew}}||3||{{NA}}||{{members|Yes}} -|- -|1||{{plinkt|Shrimps}}||30||3||{{members|No}} -|- -|1||{{plinkt|Cooked chicken}}||30||3||{{members|No}} -|- -|1||{{plinkt|Cooked rabbit}}||30||5||{{members|Yes}} -|- -|1||{{plinkt|Anchovies}}||30||1||{{members|No}} -|- -|1||{{plinkt|Sardine}}||40||4||{{members|No}} -|- -|1||{{plinkt|Poison karambwan}}||80||-5||{{members|Yes}} -|- -|1||{{plinkt|Ugthanki meat}}||40||3||{{members|Yes}} -|- -|5||{{plinkt|Herring}}||50||5||{{members|No}} -|- -|7||{{plinkt|Guppy}}||12||{{NA}}||{{members|No}} -|- -|10||{{plinkt|Mackerel}}||60||6||{{members|Yes}} -|- -|11||{{plinkt|Roast bird meat}}||60||6||{{members|Yes}} -|- -|12||{{plinkt|Thin snail}}||70|| data-sort-value="6" |5-7||{{members|Yes}} -|- -|15||{{plinkt|Trout}}||70||7||{{members|No}} -|- -|16||{{plinkt|Spider on stick}}||80|| data-sort-value="8.5" |7-10||{{members|Yes}} -|- -|16||{{plinkt|Spider on shaft}}||80|| data-sort-value="8.5" |7-10||{{members|Yes}} -|- -|16||{{plinkt|Roast rabbit}}||70||7||{{members|Yes}} -|- -|17||{{plinkt|Lean snail}}||80||5-8||{{members|Yes}} -|- -|18||{{plinkt|Cod}}||75||7||{{members|Yes}} -|- -|20||{{plinkt|Pike}}||80||8||{{members|No}} -|- -|20||{{plinkt|Cavefish}}||23||{{NA}}||{{members|No}} -|- -|21||{{plinkt|Roast beast meat}}||82.5||8||{{members|Yes}} -|- -|21||{{plinkt|Red crab meat}}||85||8||{{members|Yes}} -|- -|21||{{plinkt|Cooked giant crab meat}}||100||10||{{members|Yes}} -|- -|22||{{plinkt|Fat snail}}||95|| data-sort-value="8" |7-9||{{members|Yes}} -|- -|23||{{plinkt|Cooked wild kebbit}}||73|| data-sort-value="8" |4+4 (8)||{{members|Yes}} -|- -|25||{{plinkt|Salmon}}||90||9||{{members|No}} -|- -|28||{{plinkt|Slimy eel}}||95|| data-sort-value="8" |6-10||{{members|Yes}} -|- -|30||{{plinkt|Tuna}}||100||10||{{members|No}} -|- -|30||{{plinkt|Cooked karambwan}}||190||18||{{members|Yes}} -|- -|30||{{plinkt|Cooked chompy}}||100||10||{{members|Yes}} -|- -|31||{{plinkt|Cooked fishcake}}||100||11||{{members|Yes}} -|- -|31||{{plinkt|Cooked larupia}}||92|| data-sort-value="11" |6+5 (11)||{{members|Yes}} -|- -|32||{{plinkt|Cooked barb-tailed kebbit}}||106|| data-sort-value="12" |7+5 (12)||{{members|Yes}} -|- -|33||{{plinkt|Tetra}}||31||{{NA}}||{{members|No}} -|- -|35||{{plinkt|Rainbow fish}}||110||11||{{members|Yes}} -|- -|38||{{plinkt|Cave eel}}||115|| data-sort-value="9" |7-11||{{members|Yes}} -|- -|40||{{plinkt|Lobster}}||120||12||{{members|No}} -|- -|41||{{plinkt|Cooked jubbly}}||160||15||{{members|Yes}} -|- -|41||{{plinkt|Cooked graahk}}||124|| data-sort-value="14" |8+6 (14)||{{members|Yes}} -|- -|43||{{plinkt|Bass}}||130||13||{{members|Yes}} -|- -|45||{{plinkt|Swordfish}}||140||14||{{members|No}} -|- -|46||{{plinkt|Catfish}}||43||{{NA}}||{{members|Yes}} -|- -|51||{{plinkt|Cooked kyatt}}||143|| data-sort-value="17" |9+8 (17)||{{members|Yes}} -|- -|53||{{plinkt|Lava eel}}||30||14||{{members|Yes}} -|- -|56||{{plinkt|Swordtip squid}}||150||15||{{members|Yes}} -|- -|59||{{plinkt|Cooked pyre fox}}||154|| data-sort-value="19" |11+8 (19)||{{members|Yes}} -|- -|62||{{plinkt|Monkfish}}||150||16||{{members|Yes}} -|- -|68||{{plinkt|Cooked sunlight antelope}}||175|| data-sort-value="21" |12+9 (21)||{{members|Yes}} -|- -|69||{{plinkt|Giant krill}}||177.5||17||{{members|Yes}} -|- -|71||{{plinkt|Jumbo squid}}||180||17||{{members|Yes}} -|- -|72||{{plinkt|Sacred eel}}|| data-sort-value="109" |109-124||{{NA}}||{{members|Yes}} -|- -|73||{{plinkt|Haddock}}||180||18||{{members|Yes}} -|- -|79||{{plinkt|Yellowfin}}||200||19||{{members|Yes}} -|- -|80||{{plinkt|Shark}}||210||20||{{members|Yes}} -|- -|82||{{plinkt|Sea turtle}}||211.3||21||{{members|Yes}} -|- -|82||{{plinkt|Cooked dashing kebbit}}||215|| data-sort-value="23" |13+10 (23)||{{members|Yes}} -|- -|83||{{plinkt|Halibut}}||212.5||20||{{members|Yes}} -|- -|84||{{plinkt|Anglerfish}}||230|| data-sort-value="22" |3-22||{{members|Yes}} -|- -|87||{{plinkt|Bluefin}}||215||data-sort-value="22"|22||{{members|Yes}} -|- -|90||{{plinkt|Dark crab}}||215||22||{{members|Yes}} -|- -|91||{{plinkt|Manta ray}}||216.2||22||{{members|Yes}} -|- -|91||{{plinkt|Marlin}}||225||24||{{members|Yes}} -|- -|92||{{plinkt|Cooked moonlight antelope}}||220|| data-sort-value="26" |14+12 (26)||{{members|Yes}} -|- -|} - -===Bread=== -{| class="wikitable sortable align-left-3" style="text-align:center;" -!Level -! colspan=2 |Item -! data-sort-type="number" |XP -! data-sort-type="number" |Healing -!Members -|- -|1||{{plinkt|Bread}}||40||5||{{members|No}} -|- -|58||{{plinkt|Pitta bread}}||40||{{NA}}||{{members|Yes}} -|} - -===Pies=== -{| class="wikitable sortable align-left-3 align-left-6" style="text-align:center;" -!Level -! colspan=2 |Item -! data-sort-type="number" |XP -! data-sort-type="number" |Healing -!Effect -!Members -|- -|10||{{plinkt|Redberry pie}}||78||10||None||{{members|No}} -|- -|20||{{plinkt|Meat pie}}||110||12||None||{{members|No}} -|- -|29||{{plinkt|Mud pie}}||128||0||Thrown at enemies||{{members|Yes}} -|- -|30||{{plinkt|Apple pie}}||130||14||None||{{members|No}} -|- -|34||{{plinkt|Garden pie}}||138||12||+3 [[Farming]]||{{members|Yes}} -|- -|47||{{plinkt|Fish pie}}||164||12||+3 [[Fishing]]||{{members|Yes}} -|- -|52||{{plinkt|Botanical pie}}||180||12||+4 [[Herblore]]||{{members|Yes}} -|- -|60||{{plinkt|Mushroom pie}}||200||16||+4 [[Crafting]]||{{members|Yes}} -|- -|70||{{plinkt|Admiral pie}}||210||16||+5 [[Fishing]]||{{members|Yes}} -|- -|73||{{plinkt|Dragonfruit pie}}||220||20||+4 [[Fletching]]||{{members|Yes}} -|- -|85||{{plinkt|Wild pie}}||240||22||+4 [[Ranged]], +5 [[Slayer]]||{{members|Yes}} -|- -|95||{{plinkt|Summer pie}}||260||22||+5 [[Agility]]||{{members|Yes}} -|} - -===Stews=== -{| class="wikitable sortable align-left-3" style="text-align:center;" -!Level -! colspan=2 |Item -! data-sort-type="number" |XP -! data-sort-type="number" |Healing -!Members -|- -|25||{{plinkt|Stew}}||117||11||{{members|No}} -|- -|60||{{plinkt|Curry}}||280||19||{{members|Yes}} -|} - -===Pizzas=== -{| class="wikitable sortable align-left-3" style="text-align:center;" -!Level -! colspan=2 |Item -!XP -!Healing -!Members -|- -|35||{{plinkt|Plain pizza}}||143||14||{{members|No}} -|- -|45||{{plinkt|Meat pizza}}||169||16||{{members|No}} -|- -|55||{{plinkt|Anchovy pizza}}||182||18||{{members|No}} -|- -|65||{{plinkt|Pineapple pizza}}||195||22||{{members|Yes}} -|} - -===Cakes=== -{| class="wikitable sortable align-left-3" style="text-align:center;" -!Level -! colspan=2 |Item -! data-sort-type="number" |XP -! data-sort-type="number" |Healing -!Members -|- -|40||{{plinkt|Cake}}||180||12||{{members|No}} -|- -|50||{{plinkt|Chocolate cake}}||210||15||{{members|No}} -|} - -===Wine=== -{| class="wikitable sortable align-left-3" style="text-align:center;" -!Level -! colspan=2 |Item -! data-sort-type="number" |XP -! data-sort-type="number" |Healing -!Members -|- -|35||{{plinkt|Jug of wine}}||200||11||{{members|No}} -|- -|65||{{plinkt|Wine of zamorak}}||200||{{NA}}||{{members|Yes}} -|} -Note that every wine made resets the twelve second fermentation of the previously made wines, resulting in an enormous experience drop if a series of inventories are made fast enough. It is one of the fastest methods for reaching 99 Cooking (yielding 400k+ experience per hour if done optimally) and the cost of the required ingredients are low, but is not profitable unlike almost all other cooking methods. This method is also accessible to free-to-play players. - -===Hot Drinks=== -{| class="wikitable sortable align-left-3" style="text-align:center;" -!Level -! colspan=2 |Item -! data-sort-type="number" |XP -! data-sort-type="number" |Healing -!Notes -!Members -|- -|20||{{plinkt|Cup of tea (nettle)|txt=Cup of tea}}||52||3||Restores 5% [[energy]].||{{members|Yes}} -|} - -===Vegetable=== -{| class="wikitable sortable align-left-3" style="text-align:center;" -!Level -! colspan=2 |Item -! data-sort-type="number" |XP -! data-sort-type="number" |Healing -!Members -|- -|7||{{plinkt|Baked potato}}||15||4||{{members|Yes}} -|- -|9||{{plinkt|Spicy sauce}}||25||2||{{members|Yes}} -|- -|11||{{plinkt|Chilli con carne}}||25||5||{{members|Yes}} -|- -|13||{{plinkt|Scrambled egg}}||50||5||{{members|Yes}} -|- -|23||{{plinkt|Egg and tomato}}||0||8||{{members|Yes}} -|- -|28||{{plinkt|Cooked sweetcorn}}||104|| data-sort-value="10" |1-10||{{members|Yes}} -|- -|39||{{plinkt|Potato with butter}}||40||14||{{members|Yes}} -|- -|41||{{plinkt|Chilli potato}}||15||14||{{members|Yes}} -|- -|42||{{plinkt|Fried onions}}||60||5||{{members|Yes}} -|- -|46||{{plinkt|Fried mushrooms}}||60||5||{{members|Yes}} -|- -|47||{{plinkt|Potato with cheese}}||40||16||{{members|Yes}} -|- -|51||{{plinkt|Egg potato}}||45||16||{{members|Yes}} -|- -|57||{{plinkt|Mushroom & onion}}||120||11||{{members|Yes}} -|- -|64||{{plinkt|Mushroom potato}}||55||20||{{members|Yes}} -|- -|67||{{plinkt|Tuna and corn}}||0||13||{{members|Yes}} -|- -|68||{{plinkt|Tuna potato}}||10||22||{{members|Yes}} -|} - -===Dairy=== -{| class="wikitable sortable align-left-3" style="text-align:center;" -!Level -! colspan=2 |Item -! data-sort-type="number" |XP -! data-sort-type="number" |Healing -!Members -|- -|21||{{plinkt|Pot of cream}}||18||1||{{members|Yes}} -|- -|38||{{plinkt|Pat of butter}}||40.5||{{NA}}||{{members|Yes}} -|- -|48||{{plinkt|Cheese}}||64||2||{{members|Yes}} -|} - -===Kebabs=== -{| class="wikitable sortable align-left-3" style="text-align:center;" -!Level -! colspan=2 |Item -! data-sort-type="number" |XP -! data-sort-type="number" |Healing -!Members -|- -|1||{{plinkt|Ugthanki kebab}}||40||19||{{members|Yes}} -|} - -==Brewing== -[[File:Brewing vat.png|thumb|200px|A brewing vat used to create ales.]] -{{main|Brewing}} -Brewing involves the fermenting of raw ingredients into [[ale]]s or [[cider]]. [[Brewing]] is useful because most products [[boost]] certain [[skill]]s. The process, however, is quite slow and is not a viable means of training. These [[alcohol]]ic [[drink]]s are not useful for healing, unlike most [[food]] made with Cooking. Brewing takes place at three [[fermenting vat]]s, with one located in eastern [[Keldagrim]] on the {{FloorNumber|uk=1}} of the [[Laughing Miner Pub]], one in [[Port Phasmatys]] underneath [[The Green Ghost]] pub, and one on [[Aldarin]] at the [[Moonrise Brewery and Winery]]. Only one brew can be made in a vat at a time. - -During the brewing process it is possible for an ale to mature, normally a 5% chance, or 64% when adding [[the stuff]]. The stuff '''cannot''' be added to cider. Mature ales have stronger [[boost]]s. It can also turn into bad ale which has no use and is drained from the barrel. - -To make an ale, 2 [[bucket of water]], 2 [[barley malt]], 1 [[ale yeast]], and optionally: 1 [[the stuff]] are required: -{{Instructions -|step1 = Use 2 [[bucket of water]] on the [[fermenting vat]] -|step2 = Use 2 [[barley malt]] on the fermenting vat -|step3 = ''Optional:'' Use 1 [[the stuff]] on the fermenting vat, increasing the chance to mature the ale from 5% to 64% -|step4 = Use the ingredients specific to the brew type you want to make -|step5 = Use 1 [[ale yeast]] on the fermenting vat -|step6 = Wait for 3 x 640 minute cycles (with the stuff added, between 3 x 640 and 16 x 640 minutes) -|step7 = Use the valve to drain the completed ale into the barrel -|step8 = Use 8 [[beer glass]]es or 2 [[calquat keg]]s on the barrel full of the completed ale -}} - -To make cider, 4 buckets of [[apple mush]], 1 [[ale yeast]] are required: -{{Instructions -|step1 = Use 4 buckets of [[apple mush]] on the [[fermenting vat]] -|step2 = Use 1 [[ale yeast]] on the fermenting vat -|step3 = Wait for three 640 minutes farming cycles -|step6 = Use the valve to drain the completed ale into the barrel -|step7 = Use 8 [[beer glass]]es or 2 [[calquat keg]]s on the barrel full of the completed cider -}} -Each apple mush requires 4 [[cooking apple]]s and one [[bucket]] added into the [[Apple Press]]. 16 cooking apples are required per cider. - -Most brews boost certain stats, some boost a variable amount based on the skill's level, boosting more as the level increases. -{|class="wikitable" -!rowspan=2 colspan=2|Ale!!colspan=2|{{SCP|Cooking}} -!rowspan=2|Boosts -!rowspan=2|Heals -!rowspan=2|Deboosts -!rowspan=2 colspan=2|Distinct ingredient -|- -!Level -!Experience -|- -|{{plinkt|Cider}} -|rowspan=2|14 -|rowspan=2|182 -|{{SCP|Farming|+1}} -|{{SCP|Hitpoints|1}} -|{{SCP|Attack}}{{SCP|Strength|2–3}}
2 + floor(CurrentLevel * 0.02) -|{{plinkt|Apple mush|txt=4 × Apple mush|rowspan=2}} -|- -|{{plinkt|Mature cider}} -|{{SCP|Farming|+2}} -|{{SCP|Hitpoints|2}} -|{{SCP|Attack}}{{SCP|Strength|3–4}}
3 + floor(CurrentLevel * 0.02) -|- -|{{plinkt|Dwarven stout}} -|rowspan=2|19 -|rowspan=2|215 -|{{SCP|Smithing}}{{SCP|Mining|+1}} -|{{SCP|Hitpoints|1}} -|{{SCP|Attack}}{{SCP|Defence}}{{SCP|Strength|2–5}}
2 + floor(CurrentLevel * 0.04) -|{{plinkt|Hammerstone hops|txt=4 × Hammerstone hops|rowspan=2}} -|- -|{{plinkt|Dwarven stout(m)}} -|{{SCP|Smithing}}{{SCP|Mining|+2}} -|{{SCP|Hitpoints|2}} -|{{SCP|Attack}}{{SCP|Defence}}{{SCP|Strength|3–6}}
3 + floor(CurrentLevel * 0.04) -|- -|{{plinkt|Asgarnian ale}} -|rowspan=2|24 -|rowspan=2|248 -|{{SCP|Strength|+2}} -|{{SCP|Hitpoints|1}} -|{{SCP|Attack|2–6}}
2 + floor(CurrentLevel * 0.05) -|{{plinkt|Asgarnian hops|txt=4 × Asgarnian hops|rowspan=2}} -|- -|{{plinkt|Asgarnian ale(m)}} -|{{SCP|Strength|+3}} -|{{SCP|Hitpoints|2}} -|{{SCP|Attack|3–7}}
3 + floor(CurrentLevel * 0.05) -|- -|{{plinkt|Greenman's ale}} -|rowspan=2|29 -|rowspan=2|281 -|{{SCP|Herblore|+1}} -|{{SCP|Hitpoints|1}} -|{{SCP|Attack}}{{SCP|Defence}}{{SCP|Strength|2–5}}
2 + floor(CurrentLevel * 0.04) -|{{plinkt|Harralander|txt=4 × Harralander|rowspan=2}} -|- -|{{plinkt|Greenman's ale(m)}} -|{{SCP|Herblore|+2}} -|{{SCP|Hitpoints|2}} -|{{SCP|Attack}}{{SCP|Defence}}{{SCP|Strength|3–6}}
3 + floor(CurrentLevel * 0.04) -|- -|{{plinkt|Wizard's mind bomb}} -|rowspan=2|34 -|rowspan=2|314 -|{{SCP|Magic|+2–3}}
2 + floor(CurrentLevel * 0.02) -|{{SCP|Hitpoints|1}} -|{{SCP|Attack}}{{SCP|Defence}}{{SCP|Strength|1–5}}
1 + floor(CurrentLevel * 0.05) -|{{plinkt|Yanillian hops|txt=4 × Yanillian hops|rowspan=2}} -|- -|{{plinkt|Mature wmb}} -|{{SCP|Magic|+3–4}}
3 + floor(CurrentLevel * 0.02) -|{{SCP|Hitpoints|2}} -|{{SCP|Attack}}{{SCP|Defence}}{{SCP|Strength|2–6}}
2 + floor(CurrentLevel * 0.05) -|- -|{{plinkt|Dragon bitter}} -|rowspan=2|39 -|rowspan=2|347 -|{{SCP|Strength|+2}} -|{{SCP|Hitpoints|1}} -|{{SCP|Attack|2–6}}
2 + floor(CurrentLevel * 0.05) -|{{plinkt|Krandorian hops|txt=4 × Krandorian hops|rowspan=2}} -|- -|{{plinkt|Dragon bitter(m)}} -|{{SCP|Strength|+3}} -|{{SCP|Hitpoints|2}} -|{{SCP|Attack|2–6}}
2 + floor(CurrentLevel * 0.05) -|- -|{{plinkt|Moonlight mead}} -|rowspan=2|44 -|rowspan=2|380 -|{{NA|rowspan=2}} -|{{SCP|Hitpoints|4}} -|{{NA|rowspan=2}} -|{{plinkt|Mushroom|txt=4 × Mushroom|rowspan=2}} -|- -|{{plinkt|Moonlight mead(m)}} -|{{SCP|Hitpoints|6}} -|- -|{{plinkt|Axeman's folly}} -|rowspan=2|49 -|rowspan=2|413 -|{{SCP|Woodcutting|+1}} -|{{SCP|Hitpoints|1}} -|{{SCP|Attack}}{{SCP|Strength|2–3}}
2 + floor(CurrentLevel * 0.02) -|{{plinkt|Oak roots|txt=1 × Oak roots|rowspan=2}} -|- -|{{plinkt|Axeman's folly(m)}} -|{{SCP|Woodcutting|+2}} -|{{SCP|Hitpoints|2}} -|{{SCP|Attack}}{{SCP|Strength|3–4}}
3 + floor(CurrentLevel * 0.02) -|- -|{{plinkt|Chef's delight}} -|rowspan=2|54 -|rowspan=2|413 -|{{SCP|Cooking|+1–5}}
1 + floor(CurrentLevel * 0.05) -|{{SCP|Hitpoints|1}} -|{{SCP|Attack}}{{SCP|Strength|3–6}}
2 + floor(CurrentLevel * 0.05) -|{{plinkt|Chocolate dust|txt=4 × Chocolate dust|rowspan=2}} -|- -|{{plinkt|Chef's delight(m)}} -|{{SCP|Cooking|+2–6}}
2 + floor(CurrentLevel * 0.05) -|{{SCP|Hitpoints|2}} -|{{SCP|Attack}}{{SCP|Strength|4–7}}
3 + floor(CurrentLevel * 0.05) -|- -|{{plinkt|Slayer's respite}} -|rowspan=2|59 -|rowspan=2|479 -|{{SCP|Slayer|+2}} -|{{SCP|Hitpoints|1}} -|{{SCP|Attack}}{{SCP|Strength|2–3}}
2 + floor(CurrentLevel * 0.02) -|{{plinkt|Wildblood hops|txt=4 × Wildblood hops|rowspan=2}} -|- -|{{plinkt|Slayer's respite(m)}} -|{{SCP|Slayer|+4}} -|{{SCP|Hitpoints|2}} -|{{SCP|Attack}}{{SCP|Strength|3–4}}
3 + floor(CurrentLevel * 0.02) -|} - -==Gnome cooking== -{{main|Gnome cooking}} -Gnome cooking is very complicated, and is best left with its own specially dedicated guide. The gnome foods plays a big part in the [[Gnome Restaurant]] minigame. More detailed information can be found in article linked to above, but following is a general guide for how a player can get acquainted with gnome cooking. - -Although it is complex, somewhat expensive, and requires a wide variety of unusual ingredients, gnome cooking can provide a good way to level Cooking from around 10 up to about 30 in good speed. To obtain the cookbook with all the recipes for gnome foods, a player can go to [[The Grand Tree]] in the [[Gnome Stronghold]] and find [[Aluft Gianne Sr]]. He is on the west side of the first level up of the Grand Tree and is dressed as a chef. Talk with him, and offer your assistance to him. He will assign you a succession of dishes to prepare. Once you have prepared the dish to his satisfaction, he will ask you to make another, then another moving steadily up the assortment of gnome foods. If you are using this method to train your Cooking and get an assignment you do not have the correct level to prepare, then you simply need to train until you do. Use the shops and resources in the Gnome Stronghold to make more gnome foods if you wish, or cook other foods that you may have. For each dish, the player can buy supplies from the shop run by Hudo who is found by the cooking range nearby Gianne, but ever since the shop stock update this has been severely limited. Players going through the tutorial will start by making crunchies, which can stored at a bank in the Grand Tree and later sold on the [[Grand Exchange]]. As your skill levels improve, you will be able to make battas then eventually bowls. Once you have completed the training exercises he gives you, you can start the minigame, which has several useful rewards. - -{| class="wikitable sortable align-left-3" style="text-align:center;" -!Level -! colspan=2 |Item -!XP -!Healing -|- -|6||{{plinkt|Fruit blast}}||50||9 -|- -|8||{{plinkt|Pineapple punch}}||70||9 -|- -|10||{{plinkt|Toad crunchies}}||100||8 -|- -|12||{{plinkt|Spicy crunchies}}||100||7 -|- -|14||{{plinkt|Worm crunchies}}||100||8 -|- -|16||{{plinkt|Chocchip crunchies}}||100||7 -|- -|18||{{plinkt|Wizard blizzard}}||110||5 -|- -|20||{{plinkt|Short green guy}}||120||5 -|- -|25||{{plinkt|Fruit batta}}||150||11 -|- -|26||{{plinkt|Toad batta}}||152||11 -|- -|27||{{plinkt|Worm batta}}||154||11 -|- -|28||{{plinkt|Vegetable batta}}||156||11 -|- -|29||{{plinkp|Cheese+tom batta}}||[[Cheese and tomato batta]]||158||11 -|- -|30||{{plinkt|Worm hole}}||170||12 -|- -|32||{{plinkt|Drunk dragon}}||160||5 -|- -|33||{{plinkt|Choc saturday}}||170||5 -|- -|35||{{plinkt|Veg ball}}||175||12 -|- -|37||{{plinkt|Blurberry special}}||180||7 -|- -|40||{{plinkt|Tangled toad's legs}}||185||15 -|- -|42||{{plinkt|Chocolate bomb}}||190||15 -|} - -==2-tick cooking== -[[File:Speed cooking.gif|thumb|2-tick cooking demonstrated at the range in [[Myths' Guild]].]] -It is possible to cook most foods at double speed, provided that they only have one cooking interface option. To perform this, drop the raw food items in front of a cooking range and then alternate between picking up raw food and left-clicking the range. This works because the cooking interface is skipped when only one raw food item is in the inventory, and the item is cooked with no delay. Due to the time it takes to drop items, the experience rate will not be exactly double, but this is still the fastest way to cook most foods. An inventory of food cooked on a range will take approximately 1 minute and 5 seconds. With efficient dropping, and using the 2-tick method, an inventory can be dropped and cooking in approximately 40 seconds total. This makes the 2-tick method around 30-40% faster than afk cooking, depending on shift-click drop speed. - -==Temporary boosts== -{{main|Temporary skill boost}} -{{:Temporary skill boost/Cooking}} - -==Quests== -{{Sync}} -===Quests requiring Cooking=== -{| class="wikitable sortable lighttable mw-collapsible qc-active oqg-table" style="text-align:center;" -!Quest -!Cooking
requirement -!Other requirements -|- -|[[Recipe for Disaster/Another Cook's Quest]]||{{SCP|Cooking|10}}||- -|- -|[[Ghosts Ahoy]]||{{SCP|Cooking|20}}|| {{SCP|Agility|25}} -|- -|[[Forgettable Tale...]]||{{SCP|Cooking|22}}||{{SCP|Farming|17}} -|- -|[[Recipe for Disaster/Freeing Evil Dave]]||{{SCP|Cooking|25}}||- -|- -|[[Big Chompy Bird Hunting]]||{{SCP|Cooking|30}}||{{SCP|Fletching|5}}, {{SCP|Ranged|30}} -|- -|[[Tai Bwo Wannai Trio]]||{{SCP|Cooking|30}}||{{SCP|Agility|15}}, {{SCP|Fishing|5}} -|- -|[[Recipe for Disaster/Freeing Pirate Pete]]||{{SCP|Cooking|31}}||- -|- -|[[Scrambled!]]||{{SCP|Cooking|36}}||{{SCP|Construction|38}}, {{SCP|Smithing|35}} -|- -|[[Recipe for Disaster/Freeing the Lumbridge Guide]]||{{SCP|Cooking|40}}||- -|- -|[[Recipe for Disaster/Freeing Skrach Uglogwee]]||{{SCP|Cooking|41}}||{{SCP|Firemaking|20}} -|- -|[[Heroes' Quest]]||{{SCP|Cooking|53}}||{{SCP|Quest|55}}, {{SCP|Fishing|53}}, {{SCP|Herblore|25}}, {{SCP|Mining|50}} -|- -|[[Swan Song]]||{{SCP|Cooking|62}}||{{SCP|Quest|100}}, {{SCP|Magic|66}}, {{SCP|Fishing|62}}, {{SCP|Smithing|45}}, {{SCP|Firemaking|42}}, {{SCP|Crafting|40}} -|- -|[[Recipe for Disaster/Freeing King Awowogei]]||{{SCP|Cooking|70 (Boostable)}}||{{SCP|Agility|48}} -|} - -===Quests rewarding Cooking experience=== -{{Main|Quest experience rewards}} -{| class="wikitable sortable lighttable mw-collapsible qc-active oqg-table" style="text-align:center;" -!Quest -!Experience
reward -!Cooking
requirement -!Other requirements -|- -|[[Cook's Assistant]]||300||-||- -|- -|[[Rag and Bone Man I]]||500||-||- -|- -|[[Recipe for Disaster/Freeing the Mountain Dwarf]]||1,000||-||- -|- -|[[Recipe for Disaster/Freeing the Goblin generals]]||1,000||-||- -|- -|[[Recipe for Disaster/Freeing Pirate Pete]]||1,000||{{SCP|Cooking|31|sort=y}}||- -|- -|[[Big Chompy Bird Hunting]]||1,470||{{SCP|Cooking|30|sort=y}}||{{SCP|Fletching|5}}, {{SCP|Ranged|30}} -|- -|[[Recipe for Disaster/Freeing Skrach Uglogwee]]||1,500||{{SCP|Cooking|41|sort=y}}||{{SCP|Firemaking|20}} -|- -|[[Gertrude's Cat]]||1,525||-||- -|- -|[[Recipe for Disaster/Freeing the Lumbridge Guide]]||2,500||{{SCP|Cooking|40|sort=y}}||- -|- -|[[Heroes' Quest]]||2,825||{{SCP|Cooking|53|sort=y}}||{{SCP|Quest|55}}, {{SCP|Fishing|53}}, {{SCP|Herblore|25}}, {{SCP|Mining|50}} -|- -|[[Recipe for Disaster/Freeing Sir Amik Varze]]||4,000||-||{{SCP|Quest|107}} -|- -|[[Forgettable Tale...]]||5,000||{{SCP|Cooking|22|sort=y}}||{{SCP|Farming|17}} -|- -|[[Tai Bwo Wannai Trio]]||5,000||{{SCP|Cooking|30|sort=y}}||{{SCP|Agility|15}}, {{SCP|Fishing|5}} -|- -|[[Scrambled!]]||5,000||{{SCP|Cooking|36|sort=y}}||{{SCP|Construction|38}}, {{SCP|Smithing|35}} -|- -|[[Recipe for Disaster/Freeing Evil Dave]]||7,000||-||- -|- -|[[Meat and Greet]]||8,000||-||- -|- -|[[Recipe for Disaster/Freeing King Awowogei]]||10,000||{{SCP|Cooking|70|sort=y}}||{{SCP|Agility|48}} -|- -!Total -!57,620 -! colspan="2" | -|} - -===Diaries Requiring Cooking=== -{| class="wikitable sortable lighttable mw-collapsible qc-active oqg-table" style="text-align:center;" -!Quest -! data-sort-type="number" |Cooking
requirement -!Other requirements for task -|- -|[[Morytania Easy Diary]] -|{{SCP|Cooking|12}} -| -|- -|[[Kandarin Medium Diary]] -|{{SCP|Cooking|43}} -|{{SCP|Fishing|46}} -|- -|[[Karamja Medium Diary]] -|{{SCP|Cooking|16}} -| -|- -|[[Morytania Medium Diary]] -|{{SCP|Cooking|40}} -| -|- -|[[Western Provinces Medium Diary]] -|{{SCP|Cooking|42}} -| -|- -|[[Karamja Hard Diary]] -|{{SCP|Cooking|30}} -| -|- -|[[Western Provinces Hard Diary]] -|{{SCP|Cooking|62}} -|{{SCP|Fishing|62}} -|- -|[[Kandarin Elite Diary]] -|{{SCP|Cooking|80}} -|{{SCP|Fishing|76}} -|- -|[[Kourend & Kebos Elite Diary]] -|{{SCP|Cooking|84}} -|{{SCP|Fishing|82}} -|- -|[[Desert Elite Diary]] -|{{SCP|Cooking|85}} -| -|- -|[[Wilderness Elite Diary]] -|{{SCP|Cooking|90}} -|{{SCP|Fishing|85}} -|- -|[[Ardougne Elite Diary]] -|{{SCP|Cooking|91}} -|{{SCP|Fishing|81}} -|- -|[[Varrock Elite Diary]] -|{{SCP|Cooking|95}} -| -|} - -===Skill choice=== -Upon completing any of the following quests, players may choose to allocate experience to Cooking. These rewards usually come in the form of items, such as lamps or books, and are independent of any experience rewards directly received for completing the quest. -{{SkillChoice|Cooking}} - -==Level up messages== -{{hastranscript|skill}} - -==See also== -* [[Cooking/Experience table]], a list of all Cooking experience sources -* [[Cooking/Level up table]], a list of all requirements and unlockables within the Cooking skill - -{{Skills}} -[[Category:Free-to-play skills]] diff --git a/wikidata/meat-fish.md b/wikidata/meat-fish.md deleted file mode 100644 index 22495cde..00000000 --- a/wikidata/meat-fish.md +++ /dev/null @@ -1,82 +0,0 @@ -# Meat / fish (Cooking skill) - -- Extracted from: `cooking.wikisrc` -- Section: Meat / fish -- Extract date (UTC): 2026-01-17 -- Rows extracted: 65 - -`Done` is marked when a corresponding cooking action exists in `cache` (recipes), not just when an item exists in the cache. - -| Done | Level | Item | XP | Heal | -|---|---:|---|---:|---:| -| [x] | 1 | Cooked meat | 30 | 3 | -| [ ] | 1 | Sinew | 3 | N/A | -| [x] | 1 | Shrimps | 30 | 3 | -| [x] | 1 | Cooked chicken | 30 | 3 | -| [x] | 1 | Cooked rabbit | 30 | 5 | -| [x] | 1 | Anchovies | 30 | 1 | -| [x] | 1 | Sardine | 40 | 4 | -| [ ] | 1 | Poison karambwan | 80 | -5 | -| [x] | 1 | Ugthanki meat | 40 | 3 | -| [x] | 5 | Herring | 50 | 5 | -| [ ] | 7 | Guppy | 12 | N/A | -| [x] | 10 | Mackerel | 60 | 6 | -| [x] | 11 | Roast bird meat | 60 | 6 | -| [ ] | 12 | Thin snail | 70 | 5-7 | -| [x] | 15 | Trout | 70 | 7 | -| [ ] | 16 | Spider on stick | 80 | 7-10 | -| [ ] | 16 | Spider on shaft | 80 | 7-10 | -| [ ] | 16 | Roast rabbit | 70 | 7 | -| [ ] | 17 | Lean snail | 80 | 5-8 | -| [x] | 18 | Cod | 75 | 7 | -| [x] | 20 | Pike | 80 | 8 | -| [ ] | 20 | Cavefish | 23 | N/A | -| [x] | 21 | Roast beast meat | 82.5 | 8 | -| [ ] | 21 | Red crab meat | 85 | 8 | -| [ ] | 21 | Cooked giant crab meat | 100 | 10 | -| [ ] | 22 | Fat snail | 95 | 7-9 | -| [ ] | 23 | Cooked wild kebbit | 73 | 4+4 (8) | -| [x] | 25 | Salmon | 90 | 9 | -| [x] | 28 | Slimy eel | 95 | 6-10 | -| [x] | 30 | Tuna | 100 | 10 | -| [x] | 30 | Cooked karambwan | 190 | 18 | -| [x] | 30 | Cooked chompy | 100 | 10 | -| [ ] | 31 | Cooked fishcake | 100 | 11 | -| [ ] | 31 | Cooked larupia | 92 | 6+5 (11) | -| [ ] | 32 | Cooked barb-tailed kebbit | 106 | 7+5 (12) | -| [ ] | 33 | Tetra | 31 | N/A | -| [x] | 35 | Rainbow fish | 110 | 11 | -| [x] | 38 | Cave eel | 115 | 7-11 | -| [x] | 40 | Lobster | 120 | 12 | -| [ ] | 41 | Cooked jubbly | 160 | 15 | -| [ ] | 41 | Cooked graahk | 124 | 8+6 (14) | -| [x] | 43 | Bass | 130 | 13 | -| [x] | 45 | Swordfish | 140 | 14 | -| [ ] | 46 | Catfish | 43 | N/A | -| [ ] | 51 | Cooked kyatt | 143 | 9+8 (17) | -| [ ] | 53 | Lava eel | 30 | 14 | -| [ ] | 56 | Swordtip squid | 150 | 15 | -| [ ] | 59 | Cooked pyre fox | 154 | 11+8 (19) | -| [x] | 62 | Monkfish | 150 | 16 | -| [ ] | 68 | Cooked sunlight antelope | 175 | 12+9 (21) | -| [ ] | 69 | Giant krill | 177.5 | 17 | -| [ ] | 71 | Jumbo squid | 180 | 17 | -| [ ] | 72 | Sacred eel | 109-124 | N/A | -| [ ] | 73 | Haddock | 180 | 18 | -| [ ] | 79 | Yellowfin | 200 | 19 | -| [x] | 80 | Shark | 210 | 20 | -| [x] | 82 | Sea turtle | 211.3 | 21 | -| [ ] | 82 | Cooked dashing kebbit | 215 | 13+10 (23) | -| [ ] | 83 | Halibut | 212.5 | 20 | -| [x] | 84 | Anglerfish | 230 | 3-22 | -| [ ] | 87 | Bluefin | 215 | 22 | -| [x] | 90 | Dark crab | 215 | 22 | -| [x] | 91 | Manta ray | 216.2 | 22 | -| [ ] | 91 | Marlin | 225 | 24 | -| [ ] | 92 | Cooked moonlight antelope | 220 | 14+12 (26) | - -## Notes - -- Burn thresholds (fire/range) are not included here yet; the saved `burn_level.wikisrc` needs additional parsing/naming normalization. -- Some entries (e.g., sinew, roasted kebbits, fishcake) may require different triggers/constraints than simple heat-source cooking and may be implemented separately. -- Guppy, cavefish, tetra, and catfish are prepared on the Preparation Table with a knife (runtime item-on-object), so they are not marked done under the "cache cooking action exists" rule. diff --git a/wikidata/skill_chances.json b/wikidata/skill_chances.json deleted file mode 100644 index e14ee9b7..00000000 --- a/wikidata/skill_chances.json +++ /dev/null @@ -1,18850 +0,0 @@ -[ - { - "title": "A wooden log", - "names": [ - "objects.zq_logbalance" - ], - "entries": [ - { - "label": "Crossing a wooden log", - "showbefore": "no", - "xlabel": "Agility level", - "ylabel": "Cross chance", - "label1": "Successful cross chance", - "low1": "90", - "high1": "250", - "req1": "1", - "color1": "#70450d", - "image1": "Agility icon.png" - } - ] - }, - { - "title": "Achey Tree", - "names": [ - "objects.achey_tree" - ], - "entries": [ - { - "label": "Achey tree cut chance", - "label1": "Bronze", - "low1": "64", - "high1": "200", - "req1": "1", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "96", - "high2": "300", - "req2": "1", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "128", - "high3": "400", - "req3": "6", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "144", - "high4": "450", - "req4": "11", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "160", - "high5": "500", - "req5": "21", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "192", - "high6": "600", - "req6": "31", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "224", - "high7": "700", - "req7": "41", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "240", - "high8": "750", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png" - } - ] - }, - { - "title": "Adamantite rocks", - "names": [ - "objects.adamantiterock2", - "objects.adamantiterock1", - "objects.prif_mine_adamantiterock1" - ], - "entries": [ - { - "label": "Adamantite rocks mining chance", - "showbefore": "no", - "label1": "Adamantite rocks", - "low1": "2", - "high1": "25", - "req1": "70", - "color1": "seagreen", - "image1": "Adamantite ore.png" - } - ] - }, - { - "title": "Admiral pie", - "names": [ - "items.admiral_pie", - "items.half_admiral_pie" - ], - "entries": [ - { - "label": "Admiral pie cooking chance", - "xlabel": "Cooking level", - "showbefore": "no", - "label1": "Range", - "low1": "15", - "high1": "270", - "req1": "70", - "color1": "saddlebrown", - "image1": "Admiral pie.png", - "label2": "Hosidius +5%", - "low2": "27", - "high2": "282", - "req2": "70", - "color2": "red", - "image2": "Admiral pie.png", - "label3": "Hosidius +10%", - "low3": "40", - "high3": "295", - "req3": "79", - "color3": "blue", - "image3": "Admiral pie.png" - } - ] - }, - { - "title": "Air rune (The Slug Menace)", - "names": [ - "items.slug2_rune_air" - ], - "entries": [ - { - "label": "Channeling blank rune success chance", - "xlabel": "Runecraft level", - "showbefore": "no", - "label1": "Air rune", - "low1": "110", - "high1": "253", - "req1": "30", - "color1": "#9b9090", - "image1": "Air rune (The Slug Menace).png" - } - ] - }, - { - "title": "Al Kharid warrior", - "names": [ - "npcs.al_kharid_warrior" - ], - "entries": [ - { - "label": "Al Kharid warrior pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "100", - "high1": "240", - "req1": "25", - "color1": "gray", - "image1": "Thieving icon.png", - "label2": "Gloves of silence", - "low2": "105", - "high2": "252", - "req2": "40", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "110", - "high3": "264", - "req3": "67", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "121", - "high4": "290", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Amethyst crystals", - "names": [ - "objects.amethystrock1", - "objects.amethystrock2", - "objects.amethystrock_empty" - ], - "entries": [ - { - "label": "Amethyst crystal mining chance", - "showbefore": "no", - "label1": "Amethyst crystal", - "low1": "-18", - "high1": "10", - "req1": "92", - "color1": "#b57a9b", - "image1": "Amethyst.png" - } - ] - }, - { - "title": "Anaire", - "names": [ - "npcs.prif_citizen_anaire" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Anchovies", - "names": [ - "items.anchovies" - ], - "entries": [ - { - "label": "Anchovies cooking chance", - "xlabel": "Cooking level", - "label1": "Fire or Range", - "low1": "128", - "high1": "512", - "req1": "1", - "color1": "gray", - "image1": "Anchovies.png", - "label2": "Lumbridge range", - "low2": "138", - "high2": "532", - "req2": "1", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "140", - "high3": "524", - "req3": "1", - "color3": "red", - "image3": "Anchovies.png", - "label4": "Hosidius +10%", - "low4": "153", - "high4": "537", - "req4": "84", - "color4": "blue", - "image4": "Anchovies.png" - } - ] - }, - { - "title": "Anglerfish", - "names": [ - "items.anglerfish" - ], - "entries": [ - { - "label": "Anglerfish cooking chance", - "showbefore": "no", - "label1": "Fire", - "low1": "1", - "high1": "200", - "req1": "84", - "color1": "orange", - "image1": "Firemaking icon.png", - "label2": "Range", - "low2": "1", - "high2": "220", - "req2": "84", - "color2": "saddlebrown", - "image2": "Cooking range icon.png", - "label3": "Gauntlets", - "low3": "12", - "high3": "260", - "req3": "84", - "color3": "grey", - "image3": "Cooking gauntlets.png", - "label4": "Hosidius +5%", - "low4": "13", - "high4": "232", - "req4": "84", - "color4": "red", - "image4": "Cooking range icon.png", - "label5": "Hosidius +10%", - "low5": "26", - "high5": "245", - "req5": "84", - "color5": "blue", - "image5": "Cooking range icon.png", - "label6": "Hosidius +5%, gauntlets", - "low6": "24", - "high6": "272", - "req6": "84", - "color6": "#ffcccb", - "image6": "Cooking gauntlets.png", - "label7": "Hosidius +10%, gauntlets", - "low7": "37", - "high7": "285", - "req7": "84", - "color7": "#ccccff", - "image7": "Cooking gauntlets.png" - } - ] - }, - { - "title": "Apple pie", - "names": [ - "items.apple_pie", - "items.half_an_apple_pie" - ], - "entries": [ - { - "label": "Apple pie cooking chance", - "xlabel": "Cooking level", - "label1": "Range", - "low1": "58", - "high1": "372", - "req1": "30", - "color1": "saddlebrown", - "image1": "Apple pie.png", - "label2": "Hosidius +5%", - "low2": "70", - "high2": "384", - "req2": "30", - "color2": "red", - "image2": "Apple pie.png", - "label3": "Hosidius +10%", - "low3": "83", - "high3": "397", - "req3": "79", - "color3": "blue", - "image3": "Apple pie.png" - } - ] - }, - { - "title": "Aranwe", - "names": [ - "npcs.prif_citizen_aranwe" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Arctic pine tree", - "names": [ - "objects.arctic_pine" - ], - "entries": [ - { - "label": "Arctic pine tree cut chance", - "showbefore": "no", - "label1": "Bronze", - "low1": "6", - "high1": "30", - "req1": "54", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "8", - "high2": "44", - "req2": "54", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "11", - "high3": "60", - "req3": "54", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "13", - "high4": "67", - "req4": "54", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "14", - "high5": "74", - "req5": "54", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "17", - "high6": "90", - "req6": "54", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "20", - "high7": "104", - "req7": "54", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "21", - "high8": "112", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png" - } - ] - }, - { - "title": "Aredhel", - "names": [ - "npcs.prif_citizen_aredhel" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Arvel", - "names": [ - "npcs.mourning_town_elf_3" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Baby impling", - "names": [ - "npcs.ii_impling_type_1", - "npcs.ii_impling_type_1_maze" - ], - "entries": [ - { - "label": "Baby impling catch chance", - "showbefore": "no", - "label1": "Butterfly net", - "low1": "79", - "high1": "402", - "req1": "17", - "color1": "saddlebrown", - "image1": "Butterfly net.png", - "label2": "Barehanded or magic butterfly net", - "low2": "99", - "high2": "422", - "req2": "17", - "color2": "green", - "image2": "Magic butterfly net.png" - } - ] - }, - { - "title": "Baked potato", - "names": [ - "items.potato_baked" - ], - "entries": [ - { - "label": "Potato cooking chance", - "label1": "Range", - "low1": "108", - "high1": "472", - "req1": "7", - "color1": "gray", - "image1": "Baked potato.png", - "label2": "Hosidius +5%", - "low2": "120", - "high2": "484", - "req2": "7", - "color2": "red", - "image2": "Baked potato.png", - "label3": "Hosidius +10%", - "low3": "133", - "high3": "497", - "req3": "79", - "color3": "blue", - "image3": "Baked potato.png" - } - ] - }, - { - "title": "Balancing ledge (Yanille Agility Dungeon)", - "names": [ - "objects.balancing_ledge3" - ], - "entries": [ - { - "label": "Balancing ledge", - "label1": "Walking across success rate", - "xlabel": "Agility level", - "low1": "65", - "high1": "355", - "req1": "40", - "showbefore": "no", - "color1": "#453321", - "image1": "Agility icon.png" - } - ] - }, - { - "title": "Bamboo Pipes", - "names": [ - "objects.brew_pipes_red", - "objects.brew_pipes_red_burning_1", - "objects.brew_pipes_red_burning_2", - "objects.brew_pipes_red_damaged_1", - "objects.brew_pipes_red_damaged_2", - "objects.brew_pipes_red_wet_1", - "objects.brew_pipes_red_wet_2", - "objects.brew_pipes_red_destroyed", - "objects.brew_pipes_blue", - "objects.brew_pipes_blue_burning_1", - "objects.brew_pipes_blue_burning_2", - "objects.brew_pipes_blue_damaged_1", - "objects.brew_pipes_blue_damaged_2", - "objects.brew_pipes_blue_wet_1", - "objects.brew_pipes_blue_wet_2", - "objects.brew_pipes_blue_destroyed" - ], - "entries": [ - { - "label": "Torch burn chance", - "xlabel": "Firemaking level", - "showbefore": "no", - "label1": "Successful burn", - "low1": "12", - "high1": "112", - "req1": "1", - "color1": "red", - "image1": "Lit torch.png" - } - ] - }, - { - "title": "Bandit (Bandit Camp)", - "names": [ - "npcs.fourdiamonds_sword_bandit_free", - "npcs.fourdiamonds_sword_bandit_1" - ], - "entries": [ - { - "label": "Bandit pickpocket chance", - "label1": "Normal", - "low1": "50", - "high1": "240", - "req1": "53", - "color1": "gray", - "image1": "Thief Desert bandit.png", - "label2": "Gloves of silence", - "low2": "52", - "high2": "252", - "req2": "53", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "55", - "high3": "264", - "req3": "53", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "60", - "high4": "290", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Barronite rocks", - "names": [ - "objects.camdozaalrock1", - "objects.camdozaalrock2", - "objects.camdozaalrock1_empty", - "objects.camdozaalrock2_empty" - ], - "entries": [ - { - "label": "Barronite rock mining chance", - "showbefore": "no", - "label1": "Barronite rock", - "low1": "80", - "high1": "100", - "req1": "14", - "color1": "purple", - "image1": "Barronite deposit.png", - "label2": "Charm of Mining", - "low2": "105", - "high2": "125", - "req2": "14", - "color2": "aqua", - "image2": "Charm of Mining.png" - } - ] - }, - { - "title": "Basalt rock", - "names": [ - "objects.horror_jumping_spot2", - "objects.horror_jumping_spot3", - "objects.horror_jumping_spot4", - "objects.horror_jumping_spot5", - "objects.horror_jumping_spot6", - "objects.horror_jumping_spot7", - "objects.horror_jumping_spot8", - "objects.horror_jumping_spot9" - ], - "entries": [ - { - "label": "Basalt rock success rate", - "lowlevel": "0", - "showbefore": "no", - "label1": "Basalt rock", - "low1": "5", - "high1": "255", - "req1": "1", - "color1": "Black", - "image1": "Agility icon.png" - } - ] - }, - { - "title": "Bass", - "names": [ - "items.bass" - ], - "entries": [ - { - "label": "Bass cooking chance", - "label1": "Fire or Range", - "low1": "33", - "high1": "312", - "req1": "43", - "color1": "gray", - "image1": "Bass.png", - "label2": "Hosidius +5%", - "low2": "45", - "high2": "324", - "req2": "43", - "color2": "red", - "image2": "Bass.png", - "label3": "Hosidius +10%", - "low3": "58", - "high3": "337", - "req3": "79", - "color3": "blue", - "image3": "Bass.png" - } - ] - }, - { - "title": "Bird house trapping", - "names": [], - "entries": [ - { - "label": "Seed nest chance", - "xlabel": "Hunter level", - "label1": "Seed nest", - "low1": "0", - "high1": "200", - "req1": "5", - "color1": "grey", - "image1": "Bird nest (seeds).png" - }, - { - "label": "Other nests (10 rolls per birdhouse)", - "xlabel": "Hunter level", - "birdhouse": "yes", - "label1": "Regular", - "high1": "100", - "req1": "5", - "color1": "#4b0082", - "image1": "Bird house.png", - "label2": "Oak", - "high2": "125", - "req2": "14", - "color2": "#ff0000", - "image2": "Oak bird house.png", - "label3": "Willow", - "high3": "128", - "req3": "24", - "color3": "#006400", - "image3": "Willow bird house.png", - "label4": "Teak", - "high4": "130", - "req4": "34", - "color4": "#ffa500", - "image4": "Teak bird house.png", - "label5": "Maple", - "high5": "140", - "req5": "44", - "color5": "#00ff00", - "image5": "Maple bird house.png", - "label6": "Mahogany", - "high6": "150", - "req6": "49", - "color6": "#ffff00", - "image6": "Mahogany bird house.png", - "label7": "Yew", - "high7": "160", - "req7": "59", - "color7": "#1e90ff", - "image7": "Yew bird house.png", - "label8": "Magic", - "high8": "170", - "req8": "74", - "color8": "#708090", - "image8": "Magic bird house.png", - "label9": "Redwood", - "high9": "175", - "req9": "89", - "color9": "#ff00ff", - "image9": "Redwood bird house.png" - } - ] - }, - { - "title": "Birdhouse (scenery)", - "names": [ - "objects.birdhouse_normal_built", - "objects.birdhouse_normal_full", - "objects.birdhouse_normal_bird" - ], - "entries": [ - { - "label": "Seed nest chance", - "xlabel": "Hunter level", - "label1": "Seed nest", - "low1": "0", - "high1": "200", - "req1": "5", - "color1": "grey", - "image1": "Bird nest (seeds).png" - }, - { - "label": "Other nests (10 rolls per birdhouse)", - "xlabel": "Hunter level", - "birdhouse": "yes", - "label1": "Regular", - "high1": "100", - "req1": "5", - "color1": "#4b0082", - "image1": "Bird house.png" - } - ] - }, - { - "title": "Black chinchompa (Hunter)", - "names": [ - "npcs.hunting_chinchompa_black" - ], - "entries": [ - { - "label": "Chinchompa catch chance", - "lowLevel": "53", - "label1": "Grey", - "low1": "6", - "high1": "268", - "req1": "53", - "color1": "gray", - "image1": "Chinchompa.png", - "label2": "Red", - "low2": "-78", - "high2": "228", - "req2": "63", - "color2": "red", - "image2": "Red chinchompa.png", - "label3": "Black", - "low3": "-78", - "high3": "228", - "req3": "73", - "color3": "black", - "image3": "Black chinchompa.png" - } - ] - }, - { - "title": "Black salamander (Hunter)", - "names": [ - "npcs.salamander_black" - ], - "entries": [ - { - "label": "Black salamander catch chance", - "showbefore": "no", - "label1": "Black salamander", - "low1": "0", - "high1": "212", - "req1": "67", - "color1": "#151111", - "image1": "Black salamander.png" - } - ] - }, - { - "title": "Blackjack", - "names": [], - "entries": [ - { - "label": "Blackjack Knock-Out Chance", - "xlabel": "Thieving level", - "label1": "Menaphite Thug", - "low1": "80", - "high1": "240", - "req1": "65", - "color1": "purple", - "image1": "Menaphite Thug chathead.png" - } - ] - }, - { - "title": "Blisterwood tree", - "names": [ - "objects.blisterwood_tree" - ], - "entries": [ - { - "label": "Blisterwood tree cut chance", - "showbefore": "no", - "label1": "Bronze", - "low1": "15", - "high1": "50", - "req1": "62", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Dragon", - "low2": "61", - "high2": "186", - "req2": "62", - "color2": "firebrick", - "image2": "Dragon axe.png" - } - ] - }, - { - "title": "Boil", - "names": [ - "objects.rcu_abyssal_barrier_boil1", - "objects.rcu_abyssal_barrier_boil2", - "objects.rcu_abyssal_barrier_boil3" - ], - "entries": [ - { - "label": "Boil success chance", - "xlabel": "Firemaking level", - "label1": "Success chance", - "low1": "0", - "high1": "255", - "image1": "Tinderbox.png", - "color1": "#692208" - } - ] - }, - { - "title": "Botanical pie", - "names": [ - "items.botanical_pie", - "items.half_botanical_pie" - ], - "entries": [ - { - "label": "Botanical pie cooking chance", - "label1": "Range", - "low1": "20", - "high1": "300", - "req1": "52", - "color1": "gray", - "image1": "Botanical pie.png", - "label2": "Lumbridge range", - "low2": "108", - "high2": "462", - "req2": "52", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "32", - "high3": "312", - "req3": "52", - "color3": "red", - "image3": "Botanical pie.png", - "label4": "Hosidius +10%", - "low4": "45", - "high4": "325", - "req4": "79", - "color4": "blue", - "image4": "Botanical pie.png" - } - ] - }, - { - "title": "Boulder (Volcanic Mine)", - "names": [ - "objects.fossil_mining_boulder_attached", - "objects.fossil_mining_boulder_giant", - "objects.fossil_mining_boulder_large", - "objects.fossil_mining_boulder_medium", - "objects.fossil_mining_boulder_small" - ], - "entries": [ - { - "label": "Volcanic Mine ore fragments", - "xlabel": "Mining level", - "cascade": "yes", - "showbefore": "no", - "label1": "Runite ore fragment", - "low1": "-10", - "high1": "80", - "req1": "85", - "color1": "steelblue", - "image1": "Runite ore fragment.png", - "label2": "Adamantite ore fragment", - "low2": "-90", - "high2": "90", - "req2": "70", - "color2": "seagreen", - "image2": "Adamantite ore fragment.png", - "label3": "Mithril ore fragment", - "low3": "-75", - "high3": "150", - "req3": "55", - "color3": "slateblue", - "image3": "Mithril ore fragment.png", - "label4": "Gold ore fragment", - "low4": "-40", - "high4": "160", - "req4": "50", - "color4": "goldenrod", - "image4": "Gold ore fragment.png", - "label5": "Coal fragment", - "low5": "-20", - "high5": "170", - "req5": "50", - "color5": "black", - "image5": "Coal fragment.png", - "label6": "Silver ore fragment", - "low6": "0", - "high6": "185", - "req6": "50", - "color6": "silver", - "image6": "Silver ore fragment.png", - "label7": "Iron ore fragment", - "low7": "0", - "high7": "510", - "req7": "50", - "color7": "maroon", - "image7": [] - } - ] - }, - { - "title": "Bowl", - "names": [ - "items.bowl_empty" - ], - "entries": [ - { - "label": "Firing pottery success rate", - "xlabel": "Crafting level", - "showbefore": "no", - "label1": "Unfired bowl", - "low1": "180", - "high1": "800", - "req1": "1", - "color1": "#916d11", - "image1": "Unfired bowl.png" - } - ] - }, - { - "title": "Bread", - "names": [ - "items.bread" - ], - "entries": [ - { - "label": "Bread cooking chance", - "xlabel": "Cooking level", - "label1": "Range", - "low1": "118", - "high1": "492", - "req1": "1", - "color1": "gray", - "image1": "Bread.png", - "label2": "Lumbridge range", - "low2": "128", - "high2": "512", - "req2": "1", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "130", - "high3": "504", - "req3": "1", - "color3": "red", - "image3": "Bread.png", - "label4": "Hosidius +10%", - "low4": "143", - "high4": "517", - "req4": "79", - "color4": "blue", - "image4": "Bread.png" - } - ] - }, - { - "title": "Bridge (Iban's Lair)", - "names": [ - "objects.bridgecollapsed1", - "objects.bridgecollapsed2" - ], - "entries": [ - { - "label": "Bridge crossing success rate", - "xlabel": "Agility level", - "label1": "Bridge", - "low1": "100", - "high1": "300", - "req1": "1", - "color1": "#392e0d", - "image1": "Agility icon.png" - } - ] - }, - { - "title": "Bridge (Nature Grotto)", - "names": [ - "objects.druidjump_loc" - ], - "entries": [ - { - "label": "Bridge success rate", - "lowlevel": "0", - "showbefore": "no", - "label1": "Jump", - "low1": "60", - "high1": "252", - "req1": "1", - "color1": "#5e691a", - "image1": "Agility icon.png" - } - ] - }, - { - "title": "Brimstone chest", - "names": [ - "objects.brimstone_konar_chest_closed", - "objects.brimstone_konar_chest_open" - ], - "entries": [ - { - "label": "Brimstone chest fish chance", - "xlabel": "Fishing level", - "ylabel": "Chance to receive", - "cascade": [], - "label1": "Raw manta ray", - "low1": "-10", - "high1": "20", - "image1": "Raw manta ray.png", - "color1": [], - "label2": "Raw sea turtle", - "low2": "-10", - "high2": "50", - "image2": "Raw sea turtle.png", - "color2": [], - "label3": "Raw shark", - "low3": "-60", - "high3": "140", - "image3": "Raw shark.png", - "color3": [], - "label4": "Raw monkfish", - "low4": "0", - "high4": "170", - "image4": "Raw monkfish.png", - "color4": [], - "label5": "Raw swordfish", - "low5": "30", - "high5": "200", - "image5": "Raw swordfish.png", - "color5": [], - "label6": "Raw lobster", - "low6": "70", - "high6": "270", - "image6": "Raw lobster.png", - "color6": [], - "label7": "Raw tuna", - "low7": "225", - "high7": "324", - "image7": "Raw tuna.png", - "color7": [] - } - ] - }, - { - "title": "Broken armour", - "names": [ - "items.digsitearmour2" - ], - "entries": [ - { - "label": "Broken armour repair chance", - "xlabel": "Smithing level", - "label1": "Broken armour", - "low1": "70", - "high1": "239", - "color1": "olive", - "image1": "Broken armour.png" - } - ] - }, - { - "title": "Broken arrow", - "names": [ - "items.digsitearrow" - ], - "entries": [ - { - "label": "Broken arrow repair chance", - "xlabel": "Fletching level", - "label1": "Broken arrow", - "low1": "180", - "high1": "239", - "color1": "brown", - "image1": "Broken arrow.png" - } - ] - }, - { - "title": "Broken bridge (Lighthouse)", - "names": [ - "objects.horror_broken_bridge_left_spot", - "objects.horror_broken_bridge_right_spot" - ], - "entries": [ - { - "label": "Broken bridge success rate", - "lowlevel": "0", - "showbefore": "no", - "label1": "Broken bridge", - "low1": "5", - "high1": "255", - "req1": "1", - "color1": "Black", - "image1": "Agility icon.png" - } - ] - }, - { - "title": "Broken staff", - "names": [ - "items.digsitestaff" - ], - "entries": [ - { - "label": "Broken staff repair chance", - "xlabel": "Crafting level", - "label1": "Broken staff", - "low1": "150", - "high1": "239", - "color1": "darkgoldenrod", - "image1": "Broken staff.png" - } - ] - }, - { - "title": "Burnt fish (sardine)", - "names": [ - "items.burntfish5" - ], - "entries": [ - { - "label": "Shrimps cooking chance", - "xlabel": "Cooking level", - "label1": "Fire or Range", - "low1": "128", - "high1": "512", - "req1": "1", - "color1": "gray", - "image1": "Shrimps.png", - "label2": "Lumbridge range", - "low2": "138", - "high2": "532", - "req2": "1", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "140", - "high3": "524", - "req3": "1", - "color3": "red", - "image3": "Shrimps.png", - "label4": "Hosidius +10%", - "low4": "153", - "high4": "537", - "req4": "84", - "color4": "blue", - "image4": "Shrimps.png" - } - ] - }, - { - "title": "Burnt fish (trout)", - "names": [ - "items.burntfish2" - ], - "entries": [ - { - "label": "Pike cooking chance", - "label1": "Fire or Range", - "low1": "78", - "high1": "412", - "req1": "20", - "color1": "gray", - "image1": "Pike.png", - "label2": "Lumbridge range", - "low2": "88", - "high2": "432", - "req2": "20", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "90", - "high3": "424", - "req3": "20", - "color3": "red", - "image3": "Pike.png", - "label4": "Hosidius +10%", - "low4": "103", - "high4": "437", - "req4": "79", - "color4": "blue", - "image4": "Pike.png" - } - ] - }, - { - "title": "Burnt oomlie wrap", - "names": [ - "items.burnt_oomlie" - ], - "entries": [ - { - "label": "Wrapped oomlie cooking chance", - "label1": "Fire", - "low1": "106", - "high1": "450", - "req1": "50", - "color1": "orange", - "image1": "Firemaking icon.png", - "label2": "Range", - "low2": "112", - "high2": "476", - "req2": "50", - "color2": "saddlebrown", - "image2": "Cooking range icon.png", - "label3": "Hosidius +5%", - "low3": "124", - "high3": "488", - "req3": "50", - "color3": "red", - "image3": "Cooking range icon.png", - "label4": "Hosidius +10%", - "low4": "137", - "high4": "501", - "req4": "79", - "color4": "blue", - "image4": "Cooking range icon.png" - } - ] - }, - { - "title": "Burnt shrimp", - "names": [ - "items.burnt_shrimp" - ], - "entries": [ - { - "label": "Shrimps cooking chance", - "xlabel": "Cooking level", - "label1": "Fire or Range", - "low1": "128", - "high1": "512", - "req1": "1", - "color1": "gray", - "image1": "Shrimps.png", - "label2": "Lumbridge range", - "low2": "138", - "high2": "532", - "req2": "1", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "140", - "high3": "524", - "req3": "1", - "color3": "red", - "image3": "Shrimps.png", - "label4": "Hosidius +10%", - "low4": "153", - "high4": "537", - "req4": "84", - "color4": "blue", - "image4": "Shrimps.png" - } - ] - }, - { - "title": "Burnt tree", - "names": [ - "objects.fossil_deadtree_small1", - "objects.fossil_deadtree_large1" - ], - "entries": [ - { - "label": "Dead tree cut chance", - "label1": "Bronze", - "low1": "64", - "high1": "200", - "req1": "1", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "96", - "high2": "300", - "req2": "1", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "128", - "high3": "400", - "req3": "6", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "144", - "high4": "450", - "req4": "11", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "160", - "high5": "500", - "req5": "21", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "192", - "high6": "600", - "req6": "31", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "224", - "high7": "700", - "req7": "41", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "240", - "high8": "750", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png" - } - ] - }, - { - "title": "Cake", - "names": [ - "items.cake", - "items.partial_cake", - "items.cake_slice" - ], - "entries": [ - { - "label": "Cake cooking chance", - "xlabel": "Cooking level", - "label1": "Range", - "low1": "38", - "high1": "332", - "req1": "40", - "color1": "gray", - "image1": "Cake.png", - "label2": "Hosidius +5%", - "low2": "50", - "high2": "344", - "req2": "40", - "color2": "red", - "image2": "Cake.png", - "label3": "Hosidius +10%", - "low3": "63", - "high3": "357", - "req3": "79", - "color3": "blue", - "image3": "Cake.png" - } - ] - }, - { - "title": "Cannon (Cabin Fever)", - "names": [ - "objects.fever_cannon", - "objects.fever_cannon_loaded", - "objects.fever_cannon_destroyed", - "objects.fever_cannon_no_barrel" - ], - "entries": [ - { - "label": "Hit chance", - "xlabel": "Ranged level", - "label1": "Cannon ball", - "low1": "15", - "high1": "240", - "image1": "Cannon ball.png", - "color1": "Black" - } - ] - }, - { - "title": "Canoe", - "names": [], - "entries": [ - { - "label": "Canoe shaping chance", - "xlabel": "Woodcutting level", - "showbefore": "yes", - "label1": "Bronze", - "low1": "32", - "high1": "100", - "req1": "12", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "48", - "high2": "150", - "req2": "12", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "64", - "high3": "200", - "req3": "12", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "72", - "high4": "225", - "req4": "12", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "80", - "high5": "250", - "req5": "21", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "96", - "high6": "300", - "req6": "31", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "112", - "high7": "350", - "req7": "41", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "112", - "high8": "350", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png", - "label9": "Crystal", - "low9": "112", - "high9": "350", - "req9": "71", - "color9": "cyan", - "image9": "Crystal axe.png" - } - ] - }, - { - "title": "Caranthir", - "names": [ - "npcs.prif_citizen_caranthir" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Carnivorous chinchompa", - "names": [ - "npcs.hunting_chinchompa_big" - ], - "entries": [ - { - "label": "Chinchompa catch chance", - "lowLevel": "53", - "label1": "Grey", - "low1": "6", - "high1": "268", - "req1": "53", - "color1": "gray", - "image1": "Chinchompa.png", - "label2": "Red", - "low2": "-78", - "high2": "228", - "req2": "63", - "color2": "red", - "image2": "Red chinchompa.png", - "label3": "Black", - "low3": "-78", - "high3": "228", - "req3": "73", - "color3": "black", - "image3": "Black chinchompa.png" - } - ] - }, - { - "title": "Cave eel", - "names": [ - "items.cave_eel" - ], - "entries": [ - { - "label": "Cave eel cooking chance", - "label1": "Fire or Range", - "low1": "38", - "high1": "332", - "req1": "38", - "color1": "gray", - "image1": "Cave eel.png", - "label2": "Hosidius +5%", - "low2": "50", - "high2": "344", - "req2": "38", - "color2": "red", - "image2": "Cave eel.png", - "label3": "Hosidius +10%", - "low3": "63", - "high3": "357", - "req3": "79", - "color3": "blue", - "image3": "Cave eel.png" - } - ] - }, - { - "title": "Caviar", - "names": [ - "items.brut_caviar" - ], - "entries": [ - { - "label": "Caviar creation chance", - "xlabel": "Cooking Level", - "showbefore": "no", - "label1": "Leaping sturgeon", - "caviar": "yes", - "denom1": "80", - "req1": "1", - "color1": "green", - "image1": "Leaping sturgeon.png" - } - ] - }, - { - "title": "Celebrian", - "names": [ - "npcs.prif_citizen_celebrian" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Celegorm", - "names": [ - "npcs.prif_citizen_celegorm" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Cerulean twitch", - "names": [ - "npcs.hunting_bird_polar" - ], - "entries": [ - { - "label": "Cerulean twitch catch chance", - "showbefore": "no", - "label1": "Cerulean twitch", - "low1": "82", - "high1": "380", - "req1": "11", - "color1": "#41416e", - "image1": "Cerulean twitch icon.png" - } - ] - }, - { - "title": "Cheese+tom batta", - "names": [ - "items.cheese+tom_batta" - ], - "entries": [ - { - "label": "Cheese+tom batta cooking chance", - "label1": "Range", - "low1": "118", - "high1": "492", - "req1": "29", - "color1": "gray", - "image1": "Cheese+tom batta.png", - "label2": "Hosidius +5%", - "low2": "130", - "high2": "504", - "req2": "29", - "color2": "red", - "image2": "Cheese+tom batta.png", - "label3": "Hosidius +10%", - "low3": "143", - "high3": "517", - "req3": "79", - "color3": "blue", - "image3": "Cheese+tom batta.png" - } - ] - }, - { - "title": "Chest (Aldarin Villas)", - "names": [ - "objects.aldarin_thieving_chest", - "objects.aldarin_thieving_chest_open" - ], - "entries": [ - { - "label": "Aldarin Villas chest thieving chance", - "showbefore": "no", - "label1": "Normal", - "low1": "0", - "high1": "150", - "req1": "36", - "color1": "darkred", - "image1": "Eclipse red.png", - "label2": "Lockpick", - "low2": "25", - "high2": "175", - "req2": "36", - "color2": "dimgray", - "image2": "Lockpick.png" - }, - { - "label": "Teleport chance on failure", - "ylabel": "Teleport chance", - "showbefore": "no", - "label1": "Normal", - "low1": "73", - "high1": "17", - "req1": "36", - "color1": "darkred", - "image1": "Eclipse red.png" - } - ] - }, - { - "title": "Chest (Chambers of Xeric)", - "names": [ - "objects.raids_thievingchest_closed", - "objects.raids_thievingchest_open", - "objects.raids_thievingchest_eggs_whole", - "objects.raids_thievingchest_eggs_hatched" - ], - "entries": [ - { - "label": "Cavern grub chest thieving chance", - "label1": "Normal", - "low1": "99", - "high1": "155", - "req1": "1", - "color1": "gray", - "image1": "Cavern grubs.png", - "label2": "Lockpick", - "low2": "153", - "high2": "209", - "req2": "1", - "color2": "dimgray", - "image2": "Lockpick.png" - } - ] - }, - { - "title": "Chest (Isle of Souls Dungeon)", - "names": [ - "objects.sw_dungeon_thieving_chest_closed", - "objects.sw_dungeon_thieving_chest_open" - ], - "entries": [ - { - "label": "Soul chest success chance", - "showbefore": "no", - "label1": "Normal", - "low1": "-23", - "high1": "153", - "req1": "28", - "color1": "tan", - "image1": "Dark key.png", - "label2": "Lockpick", - "low2": "3", - "high2": "179", - "req2": "28", - "color2": "dimgray", - "image2": "Lockpick.png" - } - ] - }, - { - "title": "Chinchompa (Hunter)", - "names": [ - "npcs.hunting_chinchompa" - ], - "entries": [ - { - "label": "Chinchompa catch chance", - "lowLevel": "53", - "label1": "Grey", - "low1": "6", - "high1": "268", - "req1": "53", - "color1": "gray", - "image1": "Chinchompa.png", - "label2": "Red", - "low2": "-78", - "high2": "228", - "req2": "63", - "color2": "red", - "image2": "Red chinchompa.png", - "label3": "Black", - "low3": "-78", - "high3": "228", - "req3": "73", - "color3": "black", - "image3": "Black chinchompa.png" - } - ] - }, - { - "title": "Chocchip crunchies", - "names": [ - "items.chocchip_crunchies" - ], - "entries": [ - { - "label": "Chocchip crunchies cooking chance", - "label1": "Range", - "low1": "118", - "high1": "492", - "req1": "16", - "color1": "gray", - "image1": "Chocchip crunchies.png", - "label2": "Hosidius +5%", - "low2": "130", - "high2": "504", - "req2": "16", - "color2": "red", - "image2": "Chocchip crunchies.png", - "label3": "Hosidius +10%", - "low3": "143", - "high3": "517", - "req3": "79", - "color3": "blue", - "image3": "Chocchip crunchies.png" - } - ] - }, - { - "title": "Chocolate bomb", - "names": [ - "items.chocolate_bomb" - ], - "entries": [ - { - "label": "Chocolate bomb cooking chance", - "label1": "Range", - "low1": "118", - "high1": "492", - "req1": "42", - "color1": "gray", - "image1": "Chocolate bomb.png", - "label2": "Hosidius +5%", - "low2": "130", - "high2": "504", - "req2": "42", - "color2": "red", - "image2": "Chocolate bomb.png", - "label3": "Hosidius +10%", - "low3": "143", - "high3": "517", - "req3": "79", - "color3": "blue", - "image3": "Chocolate bomb.png" - } - ] - }, - { - "title": "Cirdan", - "names": [ - "npcs.prif_citizen_cirdan" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Citizen (Civitas illa Fortis)", - "names": [ - "npcs.varlamore_citizen_poor_m_1", - "npcs.varlamore_citizen_poor_m_2", - "npcs.varlamore_citizen_poor_m_3", - "npcs.varlamore_citizen_poor_m_4", - "npcs.varlamore_citizen_poor_m_5", - "npcs.varlamore_citizen_poor_f_1", - "npcs.varlamore_citizen_poor_f_2", - "npcs.varlamore_citizen_poor_f_3", - "npcs.varlamore_citizen_poor_f_4", - "npcs.varlamore_citizen_poor_f_5", - "npcs.varlamore_citizen_normal_m_1", - "npcs.varlamore_citizen_normal_m_2", - "npcs.varlamore_citizen_normal_m_3", - "npcs.varlamore_citizen_normal_m_4", - "npcs.varlamore_citizen_normal_m_5", - "npcs.varlamore_citizen_normal_f_1", - "npcs.varlamore_citizen_normal_f_2", - "npcs.varlamore_citizen_normal_f_3", - "npcs.varlamore_citizen_normal_f_4", - "npcs.varlamore_citizen_normal_f_5", - "npcs.varlamore_citizen_rich_m_1", - "npcs.varlamore_citizen_rich_m_2", - "npcs.varlamore_citizen_rich_m_3", - "npcs.varlamore_citizen_rich_m_4", - "npcs.varlamore_citizen_rich_m_5", - "npcs.varlamore_citizen_rich_f_1", - "npcs.varlamore_citizen_rich_f_2", - "npcs.varlamore_citizen_rich_f_3", - "npcs.varlamore_citizen_rich_f_4", - "npcs.varlamore_citizen_rich_f_5", - "npcs.varlamore_citizen_with_baby_m_1", - "npcs.varlamore_citizen_with_baby_m_2", - "npcs.varlamore_citizen_with_baby_f_1", - "npcs.varlamore_citizen_with_baby_f_2" - ], - "entries": [ - { - "label": "Citizen pickpocket chance", - "label1": "Normal", - "low1": "180", - "high1": "240", - "req1": "1", - "color1": "gray", - "image1": "Thieving icon.png", - "label2": "Gloves of silence", - "low2": "189", - "high2": "252", - "req2": "1", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "198", - "high3": "264", - "req3": "1", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "217", - "high4": "290", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Clay rocks", - "names": [ - "objects.clayrock2", - "objects.clayrock1" - ], - "entries": [ - { - "label": "Clay rocks mining chance", - "showbefore": "no", - "label1": "Clay rocks", - "low1": "128", - "high1": "400", - "req1": "1", - "color1": "tan", - "image1": "Clay.png" - } - ] - }, - { - "title": "Coal rocks", - "names": [ - "objects.coalrock2", - "objects.coalrock1", - "objects.prif_mine_coalrock1" - ], - "entries": [ - { - "label": "Coal rocks mining chance", - "showbefore": "no", - "label1": "Coal rocks", - "low1": "16", - "high1": "100", - "req1": "30", - "color1": "black", - "image1": "Coal.png" - } - ] - }, - { - "title": "Cod", - "names": [ - "items.cod" - ], - "entries": [ - { - "label": "Cod cooking chance", - "label1": "Fire", - "low1": "83", - "high1": "422", - "req1": "18", - "color1": "orange", - "image1": "Firemaking icon.png", - "label2": "Range", - "low2": "88", - "high2": "432", - "req2": "18", - "color2": "saddlebrown", - "image2": "Cooking range icon.png", - "label3": "Lumbridge range", - "low3": "93", - "high3": "442", - "req3": "18", - "color3": "green", - "image3": "Lumbridge Teleport.png", - "label4": "Hosidius +5%", - "low4": "100", - "high4": "444", - "req4": "18", - "color4": "red", - "image4": "Cooking range icon.png", - "label5": "Hosidius +10%", - "low5": "113", - "high5": "457", - "req5": "79", - "color5": "blue", - "image5": "Cooking range icon.png" - } - ] - }, - { - "title": "Cooked barb-tailed kebbit", - "names": [ - "items.barbkebbit_cooked" - ], - "entries": [ - { - "label": "Cooked barb-tailed kebbit cooking chance", - "showbefore": "no", - "label1": "Fire or Range", - "low1": "56", - "high1": "370", - "req1": "32", - "color1": "gray", - "image1": "Cooked barb-tailed kebbit.png", - "label2": "Hosidius +5%", - "low2": "68", - "high2": "382", - "req2": "32", - "color2": "red", - "image2": "Cooking range icon.png", - "label3": "Hosidius +10%", - "low3": "81", - "high3": "395", - "req3": "79", - "color3": "blue", - "image3": "Cooking range icon.png" - } - ] - }, - { - "title": "Cooked chicken", - "names": [ - "items.cooked_chicken" - ], - "entries": [ - { - "label": "Cooked chicken cooking chance", - "label1": "Fire or Range", - "low1": "128", - "high1": "512", - "req1": "1", - "color1": "gray", - "image1": "Cooked chicken.png", - "label2": "Lumbridge range", - "low2": "138", - "high2": "532", - "req2": "1", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "140", - "high3": "524", - "req3": "1", - "color3": "red", - "image3": "Cooked chicken.png", - "label4": "Hosidius +10%", - "low4": "153", - "high4": "537", - "req4": "84", - "color4": "blue", - "image4": "Cooked chicken.png" - } - ] - }, - { - "title": "Cooked chicken (undead)", - "names": [ - "items.cooked_chicken_undead" - ], - "entries": [ - { - "label": "Undead chicken cooking chance", - "label1": "Fire or Range", - "low1": "128", - "high1": "512", - "req1": "1", - "color1": "gray", - "image1": "Cooked chicken (undead).png", - "label2": "Lumbridge range", - "low2": "138", - "high2": "532", - "req2": "1", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "140", - "high3": "524", - "req3": "1", - "color3": "red", - "image3": "Cooked chicken (undead).png", - "label4": "Hosidius +10%", - "low4": "153", - "high4": "537", - "req4": "84", - "color4": "blue", - "image4": "Cooked chicken (undead).png" - } - ] - }, - { - "title": "Cooked chompy", - "names": [ - "items.cooked_chompy" - ], - "entries": [ - { - "label": "Chompy cooking chance", - "label1": "Fire", - "low1": "200", - "high1": "255", - "req1": "30", - "color1": "orange", - "image1": "Firemaking icon.png" - } - ] - }, - { - "title": "Cooked crab meat", - "names": [ - "items.hundred_pirate_giant_crab_meat_5", - "items.hundred_pirate_giant_crab_meat_4", - "items.hundred_pirate_giant_crab_meat_3", - "items.hundred_pirate_giant_crab_meat_2", - "items.hundred_pirate_giant_crab_meat_1" - ], - "entries": [ - { - "label": "Cooked crab meat cooking chance", - "label1": "Fire or Range", - "low1": "57", - "high1": "377", - "req1": "21", - "color1": "gray", - "image1": "Cooked crab meat 5.png", - "label2": "Hosidius +5%", - "low2": "69", - "high2": "389", - "req2": "21", - "color2": "red", - "image2": "Cooked crab meat 5.png", - "label3": "Hosidius +10%", - "low3": "82", - "high3": "402", - "req3": "79", - "color3": "blue", - "image3": "Cooked crab meat 5.png" - } - ] - }, - { - "title": "Cooked dashing kebbit", - "names": [ - "items.dashingkebbit_cooked" - ], - "entries": [ - { - "label": "Cooked dashing kebbit cooking chance", - "showbefore": "no", - "label1": "Fire", - "low1": "1", - "high1": "194", - "req1": "82", - "color1": "orange", - "image1": "Firemaking icon.png", - "label2": "Range", - "low2": "1", - "high2": "224", - "req2": "82", - "color2": "saddlebrown", - "image2": "Cooking range icon.png", - "label3": "Hosidius +5%", - "low3": "13", - "high3": "236", - "req3": "82", - "color3": "red", - "image3": "Cooking range icon.png", - "label4": "Hosidius +10%", - "low4": "26", - "high4": "249", - "req4": "82", - "color4": "blue", - "image4": "Cooking range icon.png" - } - ] - }, - { - "title": "Cooked fishcake", - "names": [ - "items.hundred_pirate_fishcake" - ], - "entries": [ - { - "label": "Cooked fishcake cooking chance", - "label1": "Fire or Range", - "low1": "57", - "high1": "377", - "req1": "31", - "color1": "gray", - "image1": "Cooked fishcake.png", - "label2": "Hosidius +5%", - "low2": "69", - "high2": "389", - "req2": "31", - "color2": "red", - "image2": "Cooked fishcake.png", - "label3": "Hosidius +10%", - "low3": "82", - "high3": "402", - "req3": "79", - "color3": "blue", - "image3": "Cooked fishcake.png" - } - ] - }, - { - "title": "Cooked graahk", - "names": [ - "items.graahk_cooked" - ], - "entries": [ - { - "label": "Cooked graahk cooking chance", - "showbefore": "no", - "label1": "Fire or Range", - "low1": "32", - "high1": "328", - "req1": "41", - "color1": "gray", - "image1": "Cooked graahk.png", - "label2": "Hosidius +5%", - "low2": "44", - "high2": "340", - "req2": "41", - "color2": "red", - "image2": "Cooking range icon.png", - "label3": "Hosidius +10%", - "low3": "57", - "high3": "353", - "req3": "79", - "color3": "blue", - "image3": "Cooking range icon.png" - } - ] - }, - { - "title": "Cooked jubbly", - "names": [ - "items.100_jubbly_meat_cooked" - ], - "entries": [ - { - "label": "Jubbly cooking chance", - "label1": "Ogre spit-roast", - "low1": "191", - "high1": "245", - "req1": "30", - "color1": "orange", - "image1": "Firemaking icon.png" - } - ] - }, - { - "title": "Cooked karambwan", - "names": [ - "items.tbwt_cooked_karambwan" - ], - "entries": [ - { - "label": "Cooked karambwan cooking chance", - "label1": "Fire or Range", - "low1": "70", - "high1": "255", - "req1": "30", - "color1": "gray", - "image1": "Cooked_karambwan.png", - "label2": "Hosidius +5%", - "low2": "82", - "high2": "267", - "req2": "30", - "color2": "red", - "image2": "Cooked_karambwan.png", - "label3": "Hosidius +10%", - "low3": "95", - "high3": "280", - "req3": "79", - "color3": "blue", - "image3": "Cooked_karambwan.png" - } - ] - }, - { - "title": "Cooked kyatt", - "names": [ - "items.kyatt_cooked" - ], - "entries": [ - { - "label": "Cooked kyatt cooking chance", - "showbefore": "no", - "label1": "Fire", - "low1": "18", - "high1": "292", - "req1": "51", - "color1": "orange", - "image1": "Firemaking icon.png", - "label2": "Range or cooking gauntlets", - "low2": "30", - "high2": "310", - "req2": "51", - "color2": "saddlebrown", - "image2": "Cooking range icon.png", - "label3": "Hosidius +5%", - "low3": "42", - "high3": "322", - "req3": "51", - "color3": "red", - "image3": [], - "label4": "Hosidius +10%", - "low4": "55", - "high4": "335", - "req4": "79", - "color4": "blue", - "image4": "Cooking range icon.png" - } - ] - }, - { - "title": "Cooked larupia", - "names": [ - "items.larupia_cooked" - ], - "entries": [ - { - "label": "Cooked larupia cooking chance", - "showbefore": "no", - "label1": "Fire or Range", - "low1": "65", - "high1": "390", - "req1": "31", - "color1": "gray", - "image1": "Cooked larupia.png", - "label2": "Hosidius +5%", - "low2": "77", - "high2": "402", - "req2": "31", - "color2": "red", - "image2": "Cooking range icon.png", - "label3": "Hosidius +10%", - "low3": "90", - "high3": "415", - "req3": "79", - "color3": "blue", - "image3": "Cooking range icon.png" - } - ] - }, - { - "title": "Cooked meat", - "names": [ - "items.cooked_meat" - ], - "entries": [ - { - "label": "Cooked meat cooking chance", - "label1": "Fire or Range", - "low1": "128", - "high1": "512", - "req1": "1", - "color1": "gray", - "image1": "Cooked meat.png", - "label2": "Lumbridge range", - "low2": "138", - "high2": "532", - "req2": "1", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "140", - "high3": "524", - "req3": "1", - "color3": "red", - "image3": "Cooked meat.png", - "label4": "Hosidius +10%", - "low4": "153", - "high4": "537", - "req4": "84", - "color4": "blue", - "image4": "Cooked meat.png" - } - ] - }, - { - "title": "Cooked meat (undead)", - "names": [ - "items.cooked_meat_undead" - ], - "entries": [ - { - "label": "Undead meat cooking chance", - "label1": "Fire or Range", - "low1": "128", - "high1": "512", - "req1": "1", - "color1": "gray", - "image1": "Cooked meat (undead).png", - "label2": "Lumbridge range", - "low2": "138", - "high2": "532", - "req2": "1", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "140", - "high3": "524", - "req3": "1", - "color3": "red", - "image3": "Cooked meat (undead).png", - "label4": "Hosidius +10%", - "low4": "153", - "high4": "537", - "req4": "84", - "color4": "blue", - "image4": "Cooked meat (undead).png" - } - ] - }, - { - "title": "Cooked moonlight antelope", - "names": [ - "items.antelopemoon_cooked" - ], - "entries": [ - { - "label": "Cooked moonlight antelope cooking chance", - "showbefore": "no", - "label1": "Fire", - "low1": "1", - "high1": "185", - "req1": "92", - "color1": "orange", - "image1": "Firemaking icon.png", - "label2": "Range", - "low2": "1", - "high2": "200", - "req2": "92", - "color2": "saddlebrown", - "image2": "Cooking range icon.png", - "label3": "Hosidius +5%", - "low3": "13", - "high3": "212", - "req3": "92", - "color3": "red", - "image3": "Cooking range icon.png", - "label4": "Hosidius +10%", - "low4": "26", - "high4": "225", - "req4": "92", - "color4": "blue", - "image4": "Cooking range icon.png" - } - ] - }, - { - "title": "Cooked mystery meat", - "names": [ - "items.cooked_mystery_meat" - ], - "entries": [ - { - "label": "Mystery meat cooking chance", - "label1": "Fire or Range", - "low1": "128", - "high1": "512", - "req1": "1", - "color1": "gray", - "image1": "Cooked mystery meat.png", - "label2": "Lumbridge range", - "low2": "138", - "high2": "532", - "req2": "1", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "140", - "high3": "524", - "req3": "1", - "color3": "red", - "image3": "Cooked mystery meat.png", - "label4": "Hosidius +10%", - "low4": "153", - "high4": "537", - "req4": "84", - "color4": "blue", - "image4": "Cooked mystery meat.png" - } - ] - }, - { - "title": "Cooked oomlie wrap", - "names": [ - "items.cooked_oomlie" - ], - "entries": [ - { - "label": "Wrapped oomlie cooking chance", - "label1": "Fire", - "low1": "106", - "high1": "450", - "req1": "50", - "color1": "orange", - "image1": "Firemaking icon.png", - "label2": "Range", - "low2": "112", - "high2": "476", - "req2": "50", - "color2": "saddlebrown", - "image2": "Cooking range icon.png", - "label3": "Hosidius +5%", - "low3": "124", - "high3": "488", - "req3": "50", - "color3": "red", - "image3": "Cooking range icon.png", - "label4": "Hosidius +10%", - "low4": "137", - "high4": "501", - "req4": "79", - "color4": "blue", - "image4": "Cooking range icon.png" - } - ] - }, - { - "title": "Cooked pyre fox", - "names": [ - "items.fennecfox_cooked" - ], - "entries": [ - { - "label": "Cooked pyre fox cooking chance", - "showbefore": "no", - "label1": "Fire", - "low1": "10", - "high1": "273", - "req1": "59", - "color1": "orange", - "image1": "Firemaking icon.png", - "label2": "Range", - "low2": "11", - "high2": "276", - "req2": "59", - "color2": "saddlebrown", - "image2": "Cooking range icon.png", - "label3": "Hosidius +5%", - "low3": "23", - "high3": "288", - "req3": "59", - "color3": "red", - "image3": "Cooking range icon.png", - "label4": "Hosidius +10%", - "low4": "36", - "high4": "301", - "req4": "79", - "color4": "blue", - "image4": "Cooking range icon.png" - } - ] - }, - { - "title": "Cooked rabbit", - "names": [ - "items.cooked_rabbit" - ], - "entries": [ - { - "label": "Rabbit cooking chance", - "label1": "Fire or Range", - "low1": "128", - "high1": "512", - "req1": "1", - "color1": "gray", - "image1": "Cooked rabbit.png", - "label2": "Hosidius +5%", - "low2": "140", - "high2": "524", - "req2": "1", - "color2": "red", - "image2": "Cooked rabbit.png", - "label3": "Hosidius +10%", - "low3": "153", - "high3": "537", - "req3": "79", - "color3": "blue", - "image3": "Cooked rabbit.png" - } - ] - }, - { - "title": "Cooked slimy eel", - "names": [ - "items.mort_slimey_eel_cooked" - ], - "entries": [ - { - "label": "Cooked slimy eel cooking chance", - "label1": "Fire or Range", - "low1": "63", - "high1": "382", - "req1": "28", - "color1": "gray", - "image1": "Cooked slimy eel.png", - "label2": "Hosidius +5%", - "low2": "75", - "high2": "394", - "req2": "28", - "color2": "red", - "image2": "Cooked slimy eel.png", - "label3": "Hosidius +10%", - "low3": "88", - "high3": "407", - "req3": "79", - "color3": "blue", - "image3": "Cooked slimy eel.png" - } - ] - }, - { - "title": "Cooked sunlight antelope", - "names": [ - "items.antelopesun_cooked" - ], - "entries": [ - { - "label": "Cooked sunlight antelope cooking chance", - "showbefore": "no", - "label1": "Fire", - "low1": "8", - "high1": "254", - "req1": "68", - "color1": "orange", - "image1": "Firemaking icon.png", - "label2": "Range", - "low2": "8", - "high2": "265", - "req2": "68", - "color2": "saddlebrown", - "image2": "Cooking range icon.png", - "label3": "Hosidius +5%", - "low3": "20", - "high3": "277", - "req3": "68", - "color3": "red", - "image3": "Cooking range icon.png", - "label4": "Hosidius +10%", - "low4": "33", - "high4": "290", - "req4": "79", - "color4": "blue", - "image4": "Cooking range icon.png" - } - ] - }, - { - "title": "Cooked sweetcorn", - "names": [ - "items.sweetcorn_cooked" - ], - "entries": [ - { - "label": "Sweetcorn cooking chance", - "label1": "Fire or Range", - "low1": "78", - "high1": "412", - "req1": "28", - "color1": "gray", - "image1": "Cooked sweetcorn.png", - "label2": "Hosidius +5%", - "low2": "90", - "high2": "424", - "req2": "28", - "color2": "red", - "image2": "Cooked sweetcorn.png", - "label3": "Hosidius +10%", - "low3": "103", - "high3": "437", - "req3": "79", - "color3": "blue", - "image3": "Cooked sweetcorn.png" - } - ] - }, - { - "title": "Cooked wild kebbit", - "names": [ - "items.wildkebbit_cooked" - ], - "entries": [ - { - "label": "Cooked wild kebbit cooking chance", - "showbefore": "no", - "label1": "Fire or Range", - "low1": "84", - "high1": "428", - "req1": "23", - "color1": "gray", - "image1": "Cooked wild kebbit.png", - "label2": "Hosidius +5%", - "low2": "96", - "high2": "440", - "req2": "23", - "color2": "red", - "image2": "Cooking range icon.png", - "label3": "Hosidius +10%", - "low3": "109", - "high3": "453", - "req3": "79", - "color3": "blue", - "image3": "Cooking range icon.png" - } - ] - }, - { - "title": "Copper longtail", - "names": [ - "npcs.hunting_bird_woodland" - ], - "entries": [ - { - "label": "Copper longtail catch chance", - "showbefore": "no", - "label1": "Copper longtail", - "low1": "85", - "high1": "390", - "req1": "9", - "color1": "#ed9b58", - "image1": "Copper longtail icon.png" - } - ] - }, - { - "title": "Cowbells", - "names": [ - "items.peng_cowbell" - ], - "entries": [ - { - "label": "Cowbells success chance", - "showbefore": "no", - "label1": "Normal", - "low1": "128", - "high1": "200", - "req1": "15", - "color1": "gray", - "image1": "Cowbells.png" - } - ] - }, - { - "title": "Crab claw", - "names": [ - "items.hundred_pirate_crab_shell_gauntlet" - ], - "entries": [ - { - "label": "Crab claw success rate", - "xlabel": "Crafting level", - "showbefore": "no", - "label1": "Crab claw", - "low1": "40", - "high1": "240", - "req1": "15", - "color1": "red", - "image1": "Crab claw.png" - } - ] - }, - { - "title": "Crafting stall", - "names": [ - "objects.mm_stall_crafting", - "objects.dwarf_market_crafting" - ], - "entries": [ - { - "label": "Crafting Stall thieving chance", - "showbefore": "no", - "label1": "Crafting Stall", - "low1": "128", - "high1": "512", - "req1": "5", - "color1": "gold", - "image1": "Gold bar.png" - } - ] - }, - { - "title": "Crashed Star", - "names": [ - "objects.star_size_one_star", - "objects.star_size_two_star", - "objects.star_size_three_star", - "objects.star_size_four_star", - "objects.star_size_five_star", - "objects.star_size_six_star", - "objects.star_size_seven_star", - "objects.star_size_eight_star", - "objects.star_size_nine_star" - ], - "entries": [ - { - "color1": "goldenrod", - "high1": "117", - "image1": "Stardust 175.png", - "label": "Stardust mining chance", - "label1": "Stardust", - "low1": "73", - "req1": "10", - "showbefore": "no" - } - ] - }, - { - "title": "Money making guide/Cooking raw sunlight antelope", - "names": [], - "entries": [ - { - "label": "Cooked sunlight antelope cooking chance", - "showbefore": "no", - "label1": "Fire", - "low1": "8", - "high1": "254", - "req1": "62", - "color1": "orange", - "image1": "Firemaking icon.png", - "label2": "Range", - "low2": "8", - "high2": "265", - "req2": "62", - "color2": "saddlebrown", - "image2": "Cooking range icon.png", - "label3": "Hosidius +5%", - "low3": "20", - "high3": "277", - "req3": "62", - "color3": "red", - "image3": "Cooking range icon.png", - "label4": "Hosidius +10%", - "low4": "33", - "high4": "290", - "req4": "79", - "color4": "blue", - "image4": "Cooking range icon.png" - } - ] - }, - { - "title": "Crimson swift", - "names": [ - "npcs.hunting_bird_jungle" - ], - "entries": [ - { - "label": "Crimson swift catch chance", - "showbefore": "no", - "label1": "Crimson swift", - "low1": "100", - "high1": "420", - "req1": "1", - "color1": "#d44444", - "image1": "Crimson swift icon.png" - } - ] - }, - { - "title": "Crushed gem", - "names": [ - "items.crushed_gemstone" - ], - "entries": [ - { - "label": "Gem cutting rates", - "label1": "Opal", - "low1": "128", - "high1": "250", - "req1": "1", - "color1": "gray", - "image1": "Opal.png", - "label2": "Jade", - "low2": "100", - "high2": "245", - "req2": "13", - "color2": "green", - "image2": "Jade.png", - "label3": "Red topaz", - "low3": "90", - "high3": "240", - "req3": "16", - "color3": "pink", - "image3": "Red topaz.png" - } - ] - }, - { - "title": "Crystal impling", - "names": [ - "npcs.ii_impling_type_12_johnny", - "npcs.ii_impling_type_12_junior", - "npcs.ii_impling_type_12_andy", - "npcs.ii_impling_type_12_joey", - "npcs.ii_impling_type_12_trouble", - "npcs.ii_impling_type_12_hingy", - "npcs.ii_impling_type_12_zolty", - "npcs.ii_impling_type_12_neil", - "npcs.ii_impling_type_12_yanny", - "npcs.ii_impling_type_12_matty", - "npcs.ii_impling_type_12_stace", - "npcs.ii_impling_type_12_ian", - "npcs.ii_impling_type_12_jamie", - "npcs.ii_impling_type_12_damo", - "npcs.ii_impling_type_12_xander", - "npcs.ii_impling_type_12_steveo", - "npcs.ii_impling_type_12_stewie" - ], - "entries": [ - { - "label": "Crystal impling catch chance", - "showbefore": "no", - "label1": "Butterfly net", - "low1": "8", - "high1": "141", - "req1": "80", - "color1": "saddlebrown", - "image1": "Butterfly net.png", - "label2": "Barehanded or magic butterfly net", - "low2": "28", - "high2": "161", - "req2": "80", - "color2": "green", - "image2": "Magic butterfly net.png" - } - ] - }, - { - "title": "Curry", - "names": [ - "items.curry" - ], - "entries": [ - { - "label": "Curry cooking chance", - "label1": "Fire or Range", - "low1": "38", - "high1": "332", - "req1": "60", - "color1": "gray", - "image1": "Curry.png", - "label2": "Hosidius +5%", - "low2": "50", - "high2": "344", - "req2": "60", - "color2": "red", - "image2": "Curry.png", - "label3": "Hosidius +10%", - "low3": "63", - "high3": "357", - "req3": "79", - "color3": "blue", - "image3": "Curry.png" - } - ] - }, - { - "title": "Curufin", - "names": [ - "npcs.prif_citizen_curufin" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Dairy cow", - "names": [ - "objects.fat_cow", - "objects.fairy_fat_cow" - ], - "entries": [ - { - "label": "Cowbells success chance", - "showbefore": "no", - "label1": "Normal", - "low1": "128", - "high1": "200", - "req1": "15", - "color1": "gray", - "image1": "Cowbells.png" - } - ] - }, - { - "title": "Damaged armour", - "names": [ - "items.digsitearmour1" - ], - "entries": [ - { - "label": "Damaged armour repair chance", - "xlabel": "Smithing level", - "label1": "Damaged armour", - "low1": "70", - "high1": "239", - "color1": "olive", - "image1": "Damaged armour.png" - } - ] - }, - { - "title": "Dark crab", - "names": [ - "items.dark_crab" - ], - "entries": [ - { - "label": "Dark crab cooking chance", - "showbefore": "no", - "label1": "Fire or Range", - "low1": "10", - "high1": "222", - "req1": "90", - "color1": "gray", - "image1": "Dark crab.png", - "label2": "Hosidius +5%", - "low2": "22", - "high2": "234", - "req2": "90", - "color2": "red", - "image2": "Dark crab.png", - "label3": "Hosidius +10%", - "low3": "35", - "high3": "247", - "req3": "90", - "color3": "blue", - "image3": "Dark crab.png" - } - ] - }, - { - "title": "Dark kebbit", - "names": [ - "npcs.huntingbeast_silent" - ], - "entries": [ - { - "label": "Dark kebbit catch chance", - "showbefore": "no", - "label1": "Dark kebbit", - "low1": "0", - "high1": "253", - "req1": "57", - "color1": "#84630d", - "image1": "Dark kebbit icon.png" - } - ] - }, - { - "title": "Dashing kebbit", - "names": [ - "npcs.huntingbeast_speedy2" - ], - "entries": [ - { - "label": "Dashing kebbit catch chance", - "showbefore": "no", - "label1": "Dashing kebbit", - "low1": "0", - "high1": "205", - "req1": "69", - "color1": "#bd9f64", - "image1": "Dashing kebbit icon.png" - } - ] - }, - { - "title": "Dead tree", - "names": [ - "objects.deadtree2", - "objects.deadtree2_dark", - "objects.deadtree1", - "objects.deadtree1_large", - "objects.deadtree4" - ], - "entries": [ - { - "label": "Dead tree cut chance", - "label1": "Bronze", - "low1": "64", - "high1": "200", - "req1": "1", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "96", - "high2": "300", - "req2": "1", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "128", - "high3": "400", - "req3": "6", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "144", - "high4": "450", - "req4": "11", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "160", - "high5": "500", - "req5": "21", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "192", - "high6": "600", - "req6": "31", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "224", - "high7": "700", - "req7": "41", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "240", - "high8": "750", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png" - } - ] - }, - { - "title": "Dead tree (burnt)", - "names": [ - "objects.deadtree_burnt" - ], - "entries": [ - { - "label": "Dead tree cut chance", - "label1": "Bronze", - "low1": "64", - "high1": "200", - "req1": "1", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "96", - "high2": "300", - "req2": "1", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "128", - "high3": "400", - "req3": "6", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "144", - "high4": "450", - "req4": "11", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "160", - "high5": "500", - "req5": "21", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "192", - "high6": "600", - "req6": "31", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "224", - "high7": "700", - "req7": "41", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "240", - "high8": "750", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png" - } - ] - }, - { - "title": "Dead tree (old)", - "names": [ - "objects.deadtree6" - ], - "entries": [ - { - "label": "Dead tree cut chance", - "label1": "Bronze", - "low1": "64", - "high1": "200", - "req1": "1", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "96", - "high2": "300", - "req2": "1", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "128", - "high3": "400", - "req3": "6", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "144", - "high4": "450", - "req4": "11", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "160", - "high5": "500", - "req5": "21", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "192", - "high6": "600", - "req6": "31", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "224", - "high7": "700", - "req7": "41", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "240", - "high8": "750", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png" - } - ] - }, - { - "title": "Dead tree (sandy)", - "names": [ - "objects.deadtree3" - ], - "entries": [ - { - "label": "Dead tree cut chance", - "label1": "Bronze", - "low1": "64", - "high1": "200", - "req1": "1", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "96", - "high2": "300", - "req2": "1", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "128", - "high3": "400", - "req3": "6", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "144", - "high4": "450", - "req4": "11", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "160", - "high5": "500", - "req5": "21", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "192", - "high6": "600", - "req6": "31", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "224", - "high7": "700", - "req7": "41", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "240", - "high8": "750", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png" - } - ] - }, - { - "title": "Dead tree (snowy)", - "names": [ - "objects.deadtree2_snowy" - ], - "entries": [ - { - "label": "Dead tree cut chance", - "label1": "Bronze", - "low1": "64", - "high1": "200", - "req1": "1", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "96", - "high2": "300", - "req2": "1", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "128", - "high3": "400", - "req3": "6", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "144", - "high4": "450", - "req4": "11", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "160", - "high5": "500", - "req5": "21", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "192", - "high6": "600", - "req6": "31", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "224", - "high7": "700", - "req7": "41", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "240", - "high8": "750", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png" - } - ] - }, - { - "title": "Dead tree (swampy)", - "names": [ - "objects.deadtree2_swamp" - ], - "entries": [ - { - "label": "Dead tree cut chance", - "label1": "Bronze", - "low1": "64", - "high1": "200", - "req1": "1", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "96", - "high2": "300", - "req2": "1", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "128", - "high3": "400", - "req3": "6", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "144", - "high4": "450", - "req4": "11", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "160", - "high5": "500", - "req5": "21", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "192", - "high6": "600", - "req6": "31", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "224", - "high7": "700", - "req7": "41", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "240", - "high8": "750", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png" - } - ] - }, - { - "title": "Dead tree (weathered)", - "names": [ - "objects.lightdeadtree1" - ], - "entries": [ - { - "label": "Dead tree cut chance", - "label1": "Bronze", - "low1": "64", - "high1": "200", - "req1": "1", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "96", - "high2": "300", - "req2": "1", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "128", - "high3": "400", - "req3": "6", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "144", - "high4": "450", - "req4": "11", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "160", - "high5": "500", - "req5": "21", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "192", - "high6": "600", - "req6": "31", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "224", - "high7": "700", - "req7": "41", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "240", - "high8": "750", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png" - } - ] - }, - { - "title": "Dense Jungle", - "names": [ - "objects.tai_bwo_jungle_vegetation_hard_1", - "objects.tai_bwo_jungle_vegetation_hard_2", - "objects.tai_bwo_jungle_vegetation_hard_3", - "objects.tai_bwo_jungle_vegetation_hard_4", - "objects.tai_bwo_jungle_vegetation_hard_5" - ], - "entries": [ - { - "label": "Dense Jungle Cut Chance", - "showbefore": "no", - "label1": "Plain Machete", - "low1": "16", - "high1": "44", - "req1": "35", - "color1": "dimgray", - "image1": "Machete.png", - "label2": "Opal Machete", - "low2": "21", - "high2": "49", - "req2": "35", - "color2": "lightgray", - "image2": "Opal machete.png", - "label3": "Jade Machete", - "low3": "36", - "high3": "64", - "req3": "35", - "color3": "lightgreen", - "image3": "Jade machete.png", - "label4": "Red Topaz Machete", - "low4": "52", - "high4": "80", - "req4": "35", - "color4": "firebrick", - "image4": "Red topaz machete.png" - } - ] - }, - { - "title": "Dense runestone", - "names": [ - "objects.arceuus_runestone_base_mine", - "objects.arceuus_runestone_middle_mine", - "objects.arceuus_runestone_top_mine", - "objects.arceuus_runestone_base_depleted", - "objects.arceuus_runestone_middle_depleted", - "objects.arceuus_runestone_top_depleted" - ], - "entries": [ - { - "label": "Dense runestone persistence chance", - "showbefore": "no", - "label1": "Dense runestone", - "low1": "210", - "high1": "230", - "req1": "38", - "color1": "#6e6666", - "image1": "Dense essence block.png" - } - ] - }, - { - "title": "Door (Castle Wars)", - "names": [ - "objects.castlewars_saradomin_sidedoor", - "objects.castlewars_saradomin_sidedoor_open", - "objects.castlewars_zamorak_sidedoor", - "objects.castlewars_zamorak_sidedoor_open" - ], - "entries": [ - { - "label": "Door unlock chance", - "xlabel": "Thieving level", - "label1": "Unlock chance", - "low1": "15", - "high1": "255", - "image1": "Thieving icon.png", - "color1": "Black" - } - ] - }, - { - "title": "Dragon axe", - "names": [ - "items.dragon_axe" - ], - "entries": [ - { - "label": "Dragon axe success chances", - "showbefore": "yes", - "label1": "Yew tree", - "low1": "15", - "high1": "47", - "req1": "60", - "color1": "saddlebrown", - "image1": "Yew logs.png", - "label2": "Magic tree", - "low2": "7", - "high2": "22", - "req2": "75", - "color2": "slateblue", - "image2": "Magic logs.png", - "label3": "Mahogany tree", - "low3": "34", - "high3": "94", - "req3": "60", - "color3": "peru", - "image3": "Mahogany logs.png", - "label4": "Maple tree", - "low4": "30", - "high4": "93", - "req4": "60", - "color4": "chocolate", - "image4": "Maple logs.png", - "label5": "Teak tree", - "low5": "60", - "high5": "190", - "req5": "60", - "color5": "tan", - "image5": "Teak logs.png", - "label6": "Willow tree", - "low6": "60", - "high6": "187", - "req6": "60", - "color6": "darkolivegreen", - "image6": "Willow logs.png", - "label7": "Oak tree", - "low7": "120", - "high7": "375", - "req7": "60", - "color7": "wheat", - "image7": "Oak logs.png", - "label8": "Redwood tree", - "low8": "7", - "high8": "30", - "req8": "90", - "color8": "red", - "image8": "Redwood logs.png" - } - ] - }, - { - "title": "Dragon impling", - "names": [ - "npcs.ii_impling_type_10", - "npcs.ii_impling_type_10_maze" - ], - "entries": [ - { - "label": "Dragon impling catch chance", - "showbefore": "no", - "label1": "Butterfly net", - "low1": "5", - "high1": "125", - "req1": "83", - "color1": "saddlebrown", - "image1": "Butterfly net.png", - "label2": "Barehanded or magic butterfly net", - "low2": "25", - "high2": "145", - "req2": "83", - "color2": "green", - "image2": "Magic butterfly net.png" - } - ] - }, - { - "title": "Dragonfruit pie", - "names": [ - "items.dragonfruit_pie", - "items.half_dragonfruit_pie" - ], - "entries": [ - { - "label": "Dragonfruit pie cooking chance", - "showbefore": "no", - "label1": "Range", - "low1": "8", - "high1": "250", - "req1": "73", - "color1": "saddlebrown", - "image1": "Dragonfruit pie.png", - "label2": "Hosidius +5%", - "low2": "20", - "high2": "262", - "req2": "73", - "color2": "red", - "image2": "Dragonfruit pie.png", - "label3": "Hosidius +10%", - "low3": "33", - "high3": "275", - "req3": "79", - "color3": "blue", - "image3": "Dragonfruit pie.png" - } - ] - }, - { - "title": "Drunk dragon", - "names": [ - "items.drunk_dragon" - ], - "entries": [ - { - "label": "Drunk dragon experience gain chance", - "label1": "Range", - "low1": "118", - "high1": "492", - "req1": "32", - "color1": "saddlebrown", - "image1": "Drunk dragon.png", - "label2": "Hosidius +5%", - "low2": "130", - "high2": "504", - "req2": "32", - "color2": "red", - "image2": "Drunk dragon.png", - "label3": "Hosidius +10%", - "low3": "143", - "high3": "517", - "req3": "79", - "color3": "blue", - "image3": "Drunk dragon.png" - } - ] - }, - { - "title": "Dying tree", - "names": [ - "objects.fai_varrock_dead_tree" - ], - "entries": [ - { - "label": "Dying tree cut chance", - "label1": "Bronze", - "low1": "64", - "high1": "200", - "req1": "1", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "96", - "high2": "300", - "req2": "1", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "128", - "high3": "400", - "req3": "6", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "144", - "high4": "450", - "req4": "11", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "160", - "high5": "500", - "req5": "21", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "192", - "high6": "600", - "req6": "31", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "224", - "high7": "700", - "req7": "41", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "240", - "high8": "750", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png" - } - ] - }, - { - "title": "Earth impling", - "names": [ - "npcs.ii_impling_type_4", - "npcs.ii_impling_type_4_maze" - ], - "entries": [ - { - "label": "Earth impling catch chance", - "showbefore": "no", - "label1": "Butterfly net", - "low1": "51", - "high1": "302", - "req1": "36", - "color1": "saddlebrown", - "image1": "Butterfly net.png", - "label2": "Barehanded or magic butterfly net", - "low2": "71", - "high2": "322", - "req2": "36", - "color2": "green", - "image2": "Magic butterfly net.png" - } - ] - }, - { - "title": "Earth rune (The Slug Menace)", - "names": [ - "items.slug2_rune_earth" - ], - "entries": [ - { - "label": "Channeling blank rune success chance", - "xlabel": "Runecraft level", - "showbefore": "no", - "label1": "Earth rune", - "low1": "110", - "high1": "253", - "req1": "30", - "color1": "#563a09", - "image1": "Earth rune (The Slug Menace).png" - } - ] - }, - { - "title": "Earwen", - "names": [ - "npcs.prif_citizen_earwen" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Eclectic impling", - "names": [ - "npcs.ii_impling_type_6", - "npcs.ii_impling_type_6_maze" - ], - "entries": [ - { - "label": "Eclectic impling catch chance", - "showbefore": "no", - "label1": "Butterfly net", - "low1": "30", - "high1": "250", - "req1": "50", - "color1": "saddlebrown", - "image1": "Butterfly net.png", - "label2": "Barehanded or magic butterfly net", - "low2": "50", - "high2": "270", - "req2": "50", - "color2": "green", - "image2": "Magic butterfly net.png" - } - ] - }, - { - "title": "Edrahil", - "names": [ - "npcs.prif_citizen_edrahil" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Elenwe", - "names": [ - "npcs.prif_citizen_elenwe" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Elf (Thieving)", - "names": [], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Elladan", - "names": [ - "npcs.prif_citizen_elladan" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Empty plant pot", - "names": [ - "items.plantpot_empty" - ], - "entries": [ - { - "label": "Firing pottery success rate", - "xlabel": "Crafting level", - "showbefore": "no", - "label1": "Unfired plant pot", - "low1": "180", - "high1": "800", - "req1": "1", - "color1": "#bb8f6a", - "image1": "Unfired plant pot.png" - } - ] - }, - { - "title": "Enel", - "names": [ - "npcs.prif_citizen_enel" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Enelye", - "names": [ - "npcs.prif_citizen_enelye" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Enerdhil", - "names": [ - "npcs.prif_citizen_enerdhil" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Erestor", - "names": [ - "npcs.prif_citizen_erestor" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Essence impling", - "names": [ - "npcs.ii_impling_type_5", - "npcs.ii_impling_type_5_maze" - ], - "entries": [ - { - "label": "Essence impling catch chance", - "showbefore": "no", - "label1": "Butterfly net", - "low1": "40", - "high1": "275", - "req1": "42", - "color1": "saddlebrown", - "image1": "Butterfly net.png", - "label2": "Barehanded or magic butterfly net", - "low2": "60", - "high2": "295", - "req2": "42", - "color2": "green", - "image2": "Magic butterfly net.png" - } - ] - }, - { - "title": "Evergreen tree", - "names": [ - "objects.evergreen_vsnowy_large", - "objects.evergreen_snowy_large", - "objects.evergreen", - "objects.evergreen_large" - ], - "entries": [ - { - "label": "Evergreen tree cut chance", - "label1": "Bronze", - "low1": "64", - "high1": "200", - "req1": "1", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "96", - "high2": "300", - "req2": "1", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "128", - "high3": "400", - "req3": "6", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "144", - "high4": "450", - "req4": "11", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "160", - "high5": "500", - "req5": "21", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "192", - "high6": "600", - "req6": "31", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "224", - "high7": "700", - "req7": "41", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "240", - "high8": "750", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png" - } - ] - }, - { - "title": "Eyes (Abyss)", - "names": [ - "objects.rcu_abyssal_barrier_eyes1", - "objects.rcu_abyssal_barrier_eyes2", - "objects.rcu_abyssal_barrier_eyes3" - ], - "entries": [ - { - "label": "Eyes success chance", - "xlabel": "Thieving level", - "label1": "Success chance", - "low1": "0", - "high1": "255", - "image1": "Thieving icon.png", - "color1": "#692208" - } - ] - }, - { - "title": "Farmer", - "names": [ - "npcs.farmer1", - "npcs.farmer2", - "npcs.farmer3", - "npcs.farmer1_f", - "npcs.farmer2_f", - "npcs.farmer3_f", - "npcs.farmer4" - ], - "entries": [ - { - "label": "Farmer pickpocket chance", - "showbefore": "yes", - "label1": "Normal", - "low1": "150", - "high1": "240", - "req1": "7", - "color1": "gray", - "image1": "Thieving icon.png", - "label2": "Gloves of silence", - "low2": "157", - "high2": "252", - "req2": "7", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "165", - "high3": "264", - "req3": "38", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "181", - "high4": "290", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Fat snail meat", - "names": [ - "items.snail_corpse_cooked3" - ], - "entries": [ - { - "label": "Fat snail meat cooking chance", - "label1": "Fire or Range", - "low1": "73", - "high1": "402", - "req1": "22", - "color1": "gray", - "image1": "Fat snail meat.png", - "label2": "Lumbridge range", - "low2": "83", - "high2": "422", - "req2": "22", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "85", - "high3": "414", - "req3": "22", - "color3": "red", - "image3": "Fat snail meat.png", - "label4": "Hosidius +10%", - "low4": "98", - "high4": "427", - "req4": "79", - "color4": "blue", - "image4": "Fat snail meat.png" - } - ] - }, - { - "title": "Feanor", - "names": [ - "npcs.prif_citizen_feanor" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Findis", - "names": [ - "npcs.prif_citizen_findis" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Finduilas", - "names": [ - "npcs.prif_citizen_finduilas" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Fingolfin", - "names": [ - "npcs.prif_citizen_fingolfin" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Fingon", - "names": [ - "npcs.prif_citizen_fingon" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Fire rune (The Slug Menace)", - "names": [ - "items.slug2_rune_fire" - ], - "entries": [ - { - "label": "Channeling blank rune success chance", - "xlabel": "Runecraft level", - "showbefore": "no", - "label1": "Fire rune", - "low1": "110", - "high1": "253", - "req1": "30", - "color1": "#8b1d11", - "image1": "Fire rune (The Slug Menace).png" - } - ] - }, - { - "title": "Firemaking", - "names": [], - "entries": [ - { - "label": "Firemaking success chance", - "showbefore": "no", - "label1": "Normal", - "low1": "64", - "high1": "512", - "req1": "1", - "color1": "gray", - "image1": "Tinderbox.png" - } - ] - }, - { - "title": "Fish pie", - "names": [ - "items.fish_pie", - "items.half_fish_pie" - ], - "entries": [ - { - "label": "Fish pie cooking chance", - "label1": "Range", - "low1": "38", - "high1": "332", - "req1": "47", - "color1": "saddlebrown", - "image1": "Fish pie.png", - "label2": "Hosidius +5%", - "low2": "50", - "high2": "344", - "req2": "47", - "color2": "red", - "image2": "Fish pie.png", - "label3": "Hosidius +10%", - "low3": "63", - "high3": "357", - "req3": "79", - "color3": "blue", - "image3": "Fish pie.png" - } - ] - }, - { - "title": "Fishbowl (pet)", - "names": [ - "items.fishbowl_bluefish", - "items.fishbowl_greenfish", - "items.fishbowl_spinefish", - "npcs.poh_fishbowl_bluefish", - "npcs.poh_fishbowl_greenfish", - "npcs.poh_fishbowl_spinefish" - ], - "entries": [ - { - "label": "Pet fish catch rate", - "xlabel": "Fishing level", - "cascade": "yes", - "label1": "Spinefish", - "low1": "51", - "high1": "51", - "req1": "70", - "color1": "#ff9600", - "image1": "Fishbowl (orange).png", - "label2": "Greenfish", - "low2": "25", - "high2": "112", - "altlow2": "128", - "althigh2": "128", - "altreq2": "70", - "color2": "#00ff00", - "image2": "Fishbowl (green).png", - "label3": "Bluefish", - "low3": "255", - "high3": "255", - "color3": "#1ba5e3", - "image3": "Fishbowl (blue).png" - } - ] - }, - { - "title": "Fishing Trawler", - "names": [], - "entries": [ - { - "label": "Fishing Trawler fish", - "xlabel": "Fishing level", - "cascade": "yes", - "showbefore": "no", - "label1": "Manta ray", - "low1": "150", - "high1": "200", - "req1": "81", - "color1": "#515581", - "image1": "Raw manta ray.png", - "label2": "Sea turtle", - "low2": "150", - "high2": "200", - "req2": "79", - "color2": "#67a340", - "image2": "Raw sea turtle.png", - "label3": "Shark", - "low3": "150", - "high3": "200", - "req3": "76", - "color3": "#736b6b", - "image3": "Raw shark.png", - "label4": "Swordfish", - "low4": "150", - "high4": "200", - "req4": "50", - "color4": "mediumorchid", - "image4": "Raw swordfish.png", - "label5": "Lobster", - "low5": "150", - "high5": "200", - "req5": "40", - "color5": "#854c22", - "image5": "Raw lobster.png", - "label6": "Tuna", - "low6": "150", - "high6": "200", - "req6": "35", - "color6": "grey", - "image6": "Raw tuna.png", - "label7": "Oyster", - "low7": "150", - "high7": "200", - "req7": "16", - "color7": "wheat", - "image7": "Oyster.png", - "label8": "Anchovies", - "low8": "150", - "high8": "200", - "req8": "15", - "color8": "blue", - "image8": "Raw anchovies.png", - "label9": "Sardine", - "low9": "150", - "high9": "200", - "req9": "15", - "color9": "green", - "image9": "Raw sardine.png", - "label10": "Shrimps", - "low10": "150", - "high10": "200", - "req10": "15", - "color10": "#b18065", - "image10": "Raw shrimps.png" - } - ] - }, - { - "title": "Fishing spot (Tempoross Cove)", - "names": [ - "npcs.tempoross_harpoonfish_fishingspot_north", - "npcs.tempoross_harpoonfish_fishingspot_south", - "npcs.tempoross_harpoonfish_fishingspot_special" - ], - "entries": [ - { - "label": "Harpoonfish fishing chance", - "showbefore": "no", - "label1": "Harpoon", - "low1": "170", - "high1": "255", - "req1": "35", - "color1": "saddlebrown", - "image1": "Harpoon.png", - "label2": "Dragon harpoon", - "low2": "178", - "high2": "267", - "req2": "61", - "color2": "firebrick", - "image2": "Dragon harpoon.png", - "label3": "Crystal harpoon", - "low3": "187", - "high3": "280", - "req3": "71", - "color3": "cyan", - "image3": "Crystal harpoon.png" - } - ] - }, - { - "title": "Fishing spot (big net, harpoon)", - "names": [ - "npcs.0_40_53_memberfish", - "npcs.0_44_53_memberfish", - "npcs.0_33_51_memberfish", - "npcs.0_41_57_memberfish", - "npcs.0_54_49_memberfish", - "npcs.0_55_49_memberfish", - "npcs.0_43_42_memberfish", - "npcs.0_42_42_memberfish", - "npcs.0_37_59_lobster", - "npcs.0_28_56_memberfish", - "npcs.0_23_53_memberfish", - "npcs.0_26_54_memberfish", - "npcs.0_18_57_memberfish", - "npcs.0_19_58_memberfish", - "npcs.0_18_58_memberfish", - "npcs.0_33_52_memberfish", - "npcs.0_34_53_memberfish" - ], - "entries": [ - { - "label": "Big net fishing chance", - "showbefore": "no", - "label1": "Bass", - "low1": "3", - "high1": "40", - "req1": "46", - "color1": "#cb410b", - "image1": "Raw bass.png", - "label2": "Cod", - "low2": "4", - "high2": "55", - "req2": "23", - "color2": "blue", - "image2": "Raw cod.png", - "label3": "Casket", - "low3": "1", - "high3": "2", - "req3": "16", - "color3": "gold", - "image3": "Casket.png", - "label4": "Casket (skills necklace)", - "low4": "2", - "high4": "3", - "req4": "16", - "color4": "purple", - "image4": "Casket.png", - "label5": "Oyster", - "low5": "3", - "high5": "7", - "req5": "16", - "color5": "wheat", - "image5": "Oyster.png", - "label6": "Mackerel", - "low6": "5", - "high6": "65", - "bonuslow6": "10", - "bonushigh6": "10", - "req6": "16", - "color6": "#efcc00", - "image6": "Raw mackerel.png", - "label7": "Leather gloves", - "low7": "5", - "high7": "5", - "req7": "16", - "color7": "saddlebrown", - "image7": "Leather gloves.png", - "label8": "Seaweed", - "low8": "10", - "high8": "10", - "req8": "16", - "color8": "green", - "image8": "Seaweed.png", - "label9": "Leather boots", - "low9": "10", - "high9": "10", - "req9": "16", - "color9": "tan", - "image9": "Leather boots.png" - }, - { - "label": "Shark fishing chance", - "showbefore": "no", - "label1": "Harpoon", - "low1": "3", - "high1": "40", - "req1": "76", - "color1": "#736b6b", - "image1": "Harpoon.png" - } - ] - }, - { - "title": "Fishing spot (cage, harpoon)", - "names": [ - "npcs.0_40_53_rarefish", - "npcs.0_44_53_rarefish", - "npcs.0_45_49_rarefish", - "npcs.52_59_rarefish", - "npcs.0_40_60_rarefish", - "npcs.0_41_57_rarefish", - "npcs.0_37_59_tuna", - "npcs.0_28_56_rarefish", - "npcs.0_23_53_rarefish", - "npcs.0_26_54_rarefish", - "npcs.0_27_59_rarefish", - "npcs.0_38_45_rarefish", - "npcs.0_33_52_rarefish", - "npcs.0_34_53_rarefish", - "npcs.0_24_46_rarefish", - "npcs.0_21_44_rarefish" - ], - "entries": [ - { - "label": "Swordfish + tuna fishing chance", - "cascade": "yes", - "showbefore": "no", - "label1": "Swordfish", - "low1": "4", - "high1": "48", - "req1": "50", - "color1": "mediumorchid", - "image1": "Raw swordfish.png", - "label2": "Tuna", - "low2": "8", - "high2": "64", - "req2": "35", - "color2": "grey", - "image2": "Raw tuna.png" - } - ] - }, - { - "title": "Food Stall", - "names": [ - "objects.mm_stall_food" - ], - "entries": [ - { - "label": "Food Stall thieving chance", - "showbefore": "no", - "label1": "Food Stall", - "low1": "200", - "high1": "480", - "req1": "5", - "color1": "yellow", - "image1": "Banana.png" - } - ] - }, - { - "title": "Fresh monkfish", - "names": [ - "items.swan_raw_monkfish", - "items.swan_monkfish" - ], - "entries": [ - { - "label": "Fresh monkfish cooking chance", - "label1": "Fire or Range", - "low1": "100", - "high1": "240", - "req1": "62", - "color1": "gray", - "image1": "Fresh monkfish.png", - "label2": "Hosidius +5%", - "low2": "112", - "high2": "252", - "req2": "62", - "color2": "red", - "image2": "Fresh monkfish.png", - "label3": "Hosidius +10%", - "low3": "125", - "high3": "265", - "req3": "79", - "color3": "blue", - "image3": "Fresh monkfish.png" - } - ] - }, - { - "title": "Fried mushrooms", - "names": [ - "items.bowl_mushroom_fried" - ], - "entries": [ - { - "label": "Fried mushrooms cooking chance", - "label1": "Fire or Range", - "low1": "16", - "high1": "282", - "req1": "46", - "color1": "gray", - "image1": "Fried mushrooms.png", - "label2": "Hosidius +5%", - "low2": "28", - "high2": "294", - "req2": "46", - "color2": "red", - "image2": "Fried mushrooms.png", - "label3": "Hosidius +10%", - "low3": "41", - "high3": "307", - "req3": "79", - "color3": "blue", - "image3": "Fried mushrooms.png" - } - ] - }, - { - "title": "Fried onions", - "names": [ - "items.bowl_onion_fried" - ], - "entries": [ - { - "label": "Fried onions cooking chance", - "label1": "Fire or Range", - "low1": "36", - "high1": "322", - "req1": "42", - "color1": "gray", - "image1": "Fried onions.png", - "label2": "Hosidius +5%", - "low2": "48", - "high2": "334", - "req2": "42", - "color2": "red", - "image2": "Fried onions.png", - "label3": "Hosidius +10%", - "low3": "61", - "high3": "347", - "req3": "79", - "color3": "blue", - "image3": "Fried onions.png" - } - ] - }, - { - "title": "Frog spawn", - "names": [ - "items.giant_frogspawn" - ], - "entries": [ - { - "label": "Frog spawn chance", - "showbefore": "no", - "label1": "Frog spawn", - "low1": "16", - "high1": "96", - "req1": "33", - "color1": "#464f35", - "image1": "Frog spawn.png", - "label2": "Swamp weed", - "low2": "10", - "high2": "10", - "req2": "33", - "color2": "#686800", - "image2": "Swamp weed.png" - } - ] - }, - { - "title": "Fruit batta", - "names": [ - "items.fruit_batta" - ], - "entries": [ - { - "label": "Fruit batta cooking chance", - "label1": "Range", - "low1": "118", - "high1": "492", - "req1": "1", - "color1": "gray", - "image1": "Fruit batta.png", - "label2": "Hosidius +5%", - "low2": "130", - "high2": "504", - "req2": "1", - "color2": "red", - "image2": "Fruit batta.png", - "label3": "Hosidius +10%", - "low3": "143", - "high3": "517", - "req3": "79", - "color3": "blue", - "image3": "Fruit batta.png" - } - ] - }, - { - "title": "Galathil", - "names": [ - "npcs.prif_citizen_galathil" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Gap (Abyss)", - "names": [ - "objects.rcu_abyssal_barrier_agility" - ], - "entries": [ - { - "label": "Gap success chance", - "xlabel": "Agility level", - "label1": "Success chance", - "low1": "0", - "high1": "255", - "image1": "Agility icon.png", - "color1": "#692208" - } - ] - }, - { - "title": "Garden pie", - "names": [ - "items.garden_pie", - "items.half_garden_pie" - ], - "entries": [ - { - "label": "Garden pie cooking chance", - "label1": "Range", - "low1": "48", - "high1": "352", - "req1": "34", - "color1": "saddlebrown", - "image1": "Garden pie.png", - "label2": "Hosidius +5%", - "low2": "60", - "high2": "364", - "req2": "34", - "color2": "red", - "image2": "Garden pie.png", - "label3": "Hosidius +10%", - "low3": "73", - "high3": "377", - "req3": "79", - "color3": "blue", - "image3": "Garden pie.png" - } - ] - }, - { - "title": "Gelmir", - "names": [ - "npcs.prif_citizen_gelmir" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Gem rocks", - "names": [ - "objects.gemrock", - "objects.gemrock1", - "objects.village_gem_rock1", - "objects.village_gem_rock2", - "objects.village_gem_rock3" - ], - "entries": [ - { - "label": "Gem rock mining chance", - "showbefore": "no", - "label1": "Normal", - "low1": "28", - "high1": "70", - "req1": "40", - "color1": "gray", - "image1": "Rune pickaxe.png", - "label2": "Charged glory", - "low2": "84", - "high2": "210", - "req2": "40", - "color2": "purple", - "image2": "Amulet of glory(6).png" - } - ] - }, - { - "title": "General Stall", - "names": [ - "objects.mm_stall_general" - ], - "entries": [ - { - "label": "General Stall thieving chance", - "showbefore": "no", - "label1": "General Stall", - "low1": "128", - "high1": "512", - "req1": "5", - "color1": "orange", - "image1": "Pot.png" - } - ] - }, - { - "title": "Giant carp", - "names": [ - "items.giant_carp" - ], - "entries": [ - { - "label": "Giant carp cooking chance", - "label1": "Fire or Range", - "low1": "98", - "high1": "452", - "req1": "1", - "color1": "gray", - "image1": "Giant carp.png", - "label2": "Lumbridge range", - "low2": "108", - "high2": "472", - "req2": "1", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "110", - "high3": "464", - "req3": "1", - "color3": "red", - "image3": "Giant carp.png", - "label4": "Hosidius +10%", - "low4": "123", - "high4": "477", - "req4": "79", - "color4": "blue", - "image4": "Giant carp.png" - } - ] - }, - { - "title": "Glorfindel", - "names": [ - "npcs.prif_citizen_glorfindel" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Gnome", - "names": [ - "npcs.battlefield_darkskinned_gnome_archer", - "npcs.gnome", - "npcs.browclothedgnome", - "npcs.darkskinned_gnome", - "npcs.battlefield_gnome_troop", - "npcs.battlefield_gnome_archer" - ], - "entries": [ - { - "label": "Gnome pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "43", - "high1": "175", - "req1": "75", - "color1": "gray", - "image1": "Thief Gnome.png", - "label2": "Gloves of silence", - "low2": "45", - "high2": "183", - "req2": "75", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "47", - "high3": "192", - "req3": "75", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "51", - "high4": "211", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Gnome woman", - "names": [ - "npcs.gnomefemale", - "npcs.gnomefemale_dskinned" - ], - "entries": [ - { - "label": "Gnome pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "43", - "high1": "175", - "req1": "75", - "color1": "gray", - "image1": "Thief Gnome.png", - "label2": "Gloves of silence", - "low2": "45", - "high2": "183", - "req2": "75", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "47", - "high3": "192", - "req3": "75", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "51", - "high4": "211", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Gold rocks", - "names": [ - "objects.goldrock2", - "objects.goldrock1", - "objects.prif_mine_goldrock1" - ], - "entries": [ - { - "label": "Gold rocks mining chance", - "showbefore": "no", - "label1": "Gold rocks", - "low1": "7", - "high1": "75", - "req1": "40", - "color1": "goldenrod", - "image1": "Gold ore.png" - } - ] - }, - { - "title": "Golden warbler", - "names": [ - "npcs.hunting_bird_desert" - ], - "entries": [ - { - "label": "Golden warbler catch chance", - "showbefore": "no", - "label1": "Golden warbler", - "low1": "92", - "high1": "400", - "req1": "5", - "color1": "#bfbf2a", - "image1": "Golden warbler icon.png" - } - ] - }, - { - "title": "Goreu", - "names": [ - "npcs.mourning_town_elf_1" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Gourmet impling", - "names": [ - "npcs.ii_impling_type_3", - "npcs.ii_impling_type_3_maze" - ], - "entries": [ - { - "label": "Gourmet impling catch chance", - "showbefore": "no", - "label1": "Butterfly net", - "low1": "61", - "high1": "325", - "req1": "28", - "color1": "saddlebrown", - "image1": "Butterfly net.png", - "label2": "Barehanded or magic butterfly net", - "low2": "81", - "high2": "345", - "req2": "28", - "color2": "green", - "image2": "Magic butterfly net.png" - } - ] - }, - { - "title": "Grand Gold Chest", - "names": [ - "objects.ntk_golden_chest_closed", - "objects.ntk_golden_chest_open" - ], - "entries": [ - { - "label": "Chance of successfully looting grand gold chest", - "showbefore": "no", - "label1": "Chance", - "low1": "130", - "high1": "220", - "req1": "21", - "color1": "#897b31", - "image1": "Pharaoh's sceptre.png" - } - ] - }, - { - "title": "Granite rocks", - "names": [ - "objects.enakh_granite_rocks" - ], - "entries": [ - { - "label": "Granite rock mining chance", - "cascade": "yes", - "showbefore": "no", - "label1": "5kg", - "low1": "6", - "high1": "64", - "req1": "45", - "color1": "gray", - "image1": "Granite (5kg).png", - "label2": "2kg", - "low2": "8", - "high2": "75", - "req2": "45", - "color2": "red", - "image2": "Granite (2kg).png", - "label3": "500g", - "low3": "16", - "high3": "100", - "req3": "45", - "color3": "blue", - "image3": "Granite (500g).png" - } - ] - }, - { - "title": "Grape seed", - "names": [ - "items.grape_seed" - ], - "entries": [ - { - "label": "Grapes yield", - "xlabel": "Farming level", - "ylabel": "Average yield", - "showbefore": "no", - "ystep": "2", - "label1": "Regular", - "low1": "-50", - "high1": "180", - "lives1": "5", - "req1": "36", - "color1": "#79874c", - "image1": "Grapes.png", - "label2": "Attas", - "low2": "-52", - "high2": "189", - "lives2": "5", - "req2": "36", - "color2": "#be5e57", - "image2": "Attas icon.png", - "label3": "Magic secateurs", - "low3": "-44", - "high3": "186", - "lives3": "5", - "req3": "36", - "color3": "#0d8415", - "image3": "Magic secateurs.png", - "label4": "Magic secateurs, attas", - "low4": "-46", - "high4": "195", - "lives4": "5", - "req4": "36", - "color4": "#ffa210", - "image4": "Magic secateurs and attas.png" - }, - { - "label": "Zamorak's grapes yield", - "xlabel": "Farming level", - "ylabel": "Average yield", - "showbefore": "no", - "ystep": "2", - "label1": "Regular", - "low1": "-70", - "high1": "160", - "lives1": "5", - "req1": "36", - "color1": "#79874c", - "image1": "Zamorak's grapes.png", - "label2": "Attas", - "low2": "-73", - "high2": "168", - "lives2": "5", - "req2": "36", - "color2": "#be5e57", - "image2": "Attas icon.png", - "label3": "Magic secateurs", - "low3": "-64", - "high3": "166", - "lives3": "5", - "req3": "36", - "color3": "#0d8415", - "image3": "Magic secateurs.png", - "label4": "Magic secateurs, attas", - "low4": "-67", - "high4": "174", - "lives4": "5", - "req4": "36", - "color4": "#ffa210", - "image4": "Magic secateurs and attas.png" - } - ] - }, - { - "title": "Grape vine", - "names": [ - "objects.grapevine_clickzone_xp", - "objects.grapevine_grapes_5", - "objects.grapevine_clickzone_grapes_5", - "objects.grapevine_grapes_4", - "objects.grapevine_clickzone_grapes_4", - "objects.grapevine_grapes_3", - "objects.grapevine_clickzone_grapes_3", - "objects.grapevine_grapes_2", - "objects.grapevine_clickzone_grapes_2", - "objects.grapevine_grape_1", - "objects.grapevine_clickzone_grape_1", - "objects.grapevine_clickzone_seedling", - "objects.grapevine_seedling", - "objects.grapevine_clickzone_growing_1", - "objects.grapevine_growing_1", - "objects.grapevine_clickzone_growing_2", - "objects.grapevine_growing_2", - "objects.grapevine_clickzone_growing_3", - "objects.grapevine_growing_3", - "objects.grapevine_clickzone_growing_4", - "objects.grapevine_growing_4", - "objects.grapevine_clickzone_growing_5", - "objects.grapevine_growing_5", - "objects.grapevine_clickzone_growing_6", - "objects.grapevine_growing_6", - "objects.grapevine_dead", - "objects.grapevine_clickzone_dead" - ], - "entries": [ - { - "label": "Grapes yield", - "xlabel": "Farming level", - "ylabel": "Average yield", - "showbefore": "no", - "ystep": "2", - "label1": "Regular", - "low1": "-50", - "high1": "180", - "lives1": "5", - "req1": "36", - "color1": "#79874c", - "image1": "Grapes.png", - "label2": "Attas", - "low2": "-52", - "high2": "189", - "lives2": "5", - "req2": "36", - "color2": "#be5e57", - "image2": "Attas icon.png", - "label3": "Magic secateurs", - "low3": "-44", - "high3": "186", - "lives3": "5", - "req3": "36", - "color3": "#0d8415", - "image3": "Magic secateurs.png", - "label4": "Magic secateurs, attas", - "low4": "-46", - "high4": "195", - "lives4": "5", - "req4": "36", - "color4": "#ffa210", - "image4": "Magic secateurs and attas.png" - }, - { - "label": "Zamorak's grapes yield", - "xlabel": "Farming level", - "ylabel": "Average yield", - "showbefore": "no", - "ystep": "2", - "label1": "Regular", - "low1": "-70", - "high1": "160", - "lives1": "5", - "req1": "36", - "color1": "#79874c", - "image1": "Zamorak's grapes.png", - "label2": "Attas", - "low2": "-73", - "high2": "168", - "lives2": "5", - "req2": "36", - "color2": "#be5e57", - "image2": "Attas icon.png", - "label3": "Magic secateurs", - "low3": "-64", - "high3": "166", - "lives3": "5", - "req3": "36", - "color3": "#0d8415", - "image3": "Magic secateurs.png", - "label4": "Magic secateurs, attas", - "low4": "-67", - "high4": "174", - "lives4": "5", - "req4": "36", - "color4": "#ffa210", - "image4": "Magic secateurs and attas.png" - } - ] - }, - { - "title": "Guard", - "names": [ - "npcs.guard1", - "npcs.guard1_variant01", - "npcs.guard1_f", - "npcs.guard1_f_variant01", - "npcs.fai_falador_guard1", - "npcs.fai_falador_guard1_variant01", - "npcs.fai_falador_guard1_f", - "npcs.fai_falador_guard1_variant02", - "npcs.fai_falador_guard2", - "npcs.fai_falador_guard2_f", - "npcs.fai_falador_guard3", - "npcs.fai_falador_guard3_f", - "npcs.fai_falador_guard5", - "npcs.fai_falador_guard6", - "npcs.fai_falador_guard3_f", - "npcs.fai_varrock_guard02_variant01", - "npcs.fai_varrock_guard02_variant02", - "npcs.fai_varrock_guard02_f", - "npcs.fai_varrock_guard02_f_variant01", - "npcs.fai_varrock_guard02_f_variant02", - "npcs.ardougne_guard", - "npcs.ardougne_guard_variant01", - "npcs.ardougne_guard_f", - "npcs.ardougne_guard_f_variant01" - ], - "entries": [ - { - "label": "Guard pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "50", - "high1": "240", - "req1": "40", - "color1": "gray", - "image1": "Thief Guard.png", - "label2": "Gloves of silence", - "low2": "52", - "high2": "252", - "req2": "40", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "55", - "high3": "264", - "req3": "40", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "60", - "high4": "290", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Guard (Aldarin)", - "names": [ - "npcs.aldarin_guard_m_1", - "npcs.aldarin_guard_m_2", - "npcs.aldarin_guard_m_3", - "npcs.aldarin_guard_m_4", - "npcs.aldarin_guard_m_5", - "npcs.aldarin_guard_f_1", - "npcs.aldarin_guard_f_2", - "npcs.aldarin_guard_f_3", - "npcs.aldarin_guard_f_4", - "npcs.aldarin_guard_f_5" - ], - "entries": [ - { - "label": "Guard pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "50", - "high1": "240", - "req1": "40", - "color1": "gray", - "image1": "Thief Guard.png", - "label2": "Gloves of silence", - "low2": "52", - "high2": "252", - "req2": "40", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "55", - "high3": "264", - "req3": "67", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "60", - "high4": "290", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Guard (Doric's hut)", - "names": [ - "npcs.falador_doric_area_guard" - ], - "entries": [ - { - "label": "Guard pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "50", - "high1": "240", - "req1": "40", - "color1": "gray", - "image1": "Thief Guard.png", - "label2": "Gloves of silence", - "low2": "52", - "high2": "252", - "req2": "40", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "55", - "high3": "264", - "req3": "40", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "60", - "high4": "290", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Guard (Hosidius)", - "names": [ - "npcs.hos_town_guard_01", - "npcs.hos_town_guard_02", - "npcs.hos_town_guard_03", - "npcs.hos_town_guard_04" - ], - "entries": [ - { - "label": "Guard pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "50", - "high1": "240", - "req1": "40", - "color1": "gray", - "image1": "Thief Guard.png", - "label2": "Gloves of silence", - "low2": "52", - "high2": "252", - "req2": "40", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "55", - "high3": "264", - "req3": "67", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "60", - "high4": "290", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Guard (Port Sarim jail)", - "names": [ - "npcs.jail_guard_1", - "npcs.jail_guard_2", - "npcs.jail_guard_3", - "npcs.jail_guard_4", - "npcs.jail_guard_5" - ], - "entries": [ - { - "label": "Guard pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "50", - "high1": "240", - "req1": "40", - "color1": "gray", - "image1": "Thief Guard.png", - "label2": "Gloves of silence", - "low2": "52", - "high2": "252", - "req2": "40", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "55", - "high3": "264", - "req3": "40", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "60", - "high4": "290", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Guard (Varlamore)", - "names": [ - "npcs.varlamore_guard_m_1", - "npcs.varlamore_guard_m_2", - "npcs.varlamore_guard_m_3", - "npcs.varlamore_guard_m_4", - "npcs.varlamore_guard_m_5", - "npcs.varlamore_guard_f_1", - "npcs.varlamore_guard_f_2", - "npcs.varlamore_guard_f_3", - "npcs.varlamore_guard_f_4", - "npcs.varlamore_guard_f_5" - ], - "entries": [ - { - "label": "Guard pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "50", - "high1": "240", - "req1": "40", - "color1": "gray", - "image1": "Thief Guard.png", - "label2": "Gloves of silence", - "low2": "52", - "high2": "252", - "req2": "40", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "55", - "high3": "264", - "req3": "67", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "60", - "high4": "290", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Guilin", - "names": [ - "npcs.prif_citizen_guilin" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "H.A.M. Member", - "names": [ - "npcs.favour_male_ham_civilian", - "npcs.favour_female_ham_civilian" - ], - "entries": [ - { - "label": "Avoiding concussions using Agility", - "label1": "", - "low1": "0", - "high1": "254", - "req1": "15", - "showbefore": "yes", - "color1": "black", - "image1": "Agility icon.png" - }, - { - "label": "H.A.M Member pickpocket chance", - "label1": "Normal", - "low1": "135", - "high1": "239", - "req1": "15", - "color1": "gray", - "image1": "Thieving icon.png", - "label2": "Gloves of silence", - "low2": "141", - "high2": "250", - "req2": "15", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "148", - "high3": "262", - "req3": "72", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "162", - "high4": "288", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Half baked batta", - "names": [ - "items.half_baked_batta" - ], - "entries": [ - { - "label": "Half baked batta cooking chance", - "label1": "Range", - "low1": "118", - "high1": "492", - "req1": "1", - "color1": "saddlebrown", - "image1": "Half baked batta.png", - "label2": "Hosidius +5%", - "low2": "130", - "high2": "504", - "req2": "1", - "color2": "red", - "image2": "Half baked batta.png", - "label3": "Hosidius +10%", - "low3": "143", - "high3": "517", - "req3": "79", - "color3": "blue", - "image3": "Half baked batta.png" - } - ] - }, - { - "title": "Half baked bowl", - "names": [ - "items.half_baked_bowl" - ], - "entries": [ - { - "label": "Half baked bowl cooking chance", - "label1": "Range", - "low1": "118", - "high1": "492", - "req1": "1", - "color1": "saddlebrown", - "image1": "Half baked bowl.png", - "label2": "Hosidius +5%", - "low2": "130", - "high2": "504", - "req2": "1", - "color2": "red", - "image2": "Half baked bowl.png", - "label3": "Hosidius +10%", - "low3": "143", - "high3": "517", - "req3": "79", - "color3": "blue", - "image3": "Half baked bowl.png" - } - ] - }, - { - "title": "Half baked crunchy", - "names": [ - "items.half_baked_crunchy" - ], - "entries": [ - { - "label": "Half baked crunchy cooking chance", - "label1": "Range", - "low1": "118", - "high1": "492", - "req1": "1", - "color1": "saddlebrown", - "image1": "Half baked crunchy.png", - "label2": "Hosidius +5%", - "low2": "130", - "high2": "504", - "req2": "1", - "color2": "red", - "image2": "Half baked crunchy.png", - "label3": "Hosidius +10%", - "low3": "143", - "high3": "517", - "req3": "79", - "color3": "blue", - "image3": "Half baked crunchy.png" - } - ] - }, - { - "title": "Hendor (elf)", - "names": [ - "npcs.prif_citizen_hendor" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Herbiboar", - "names": [ - "npcs.fossil_herbiboar_visible", - "npcs.fossil_herbiboar_anim_visible" - ], - "entries": [ - { - "label": "Herbiboar herb chance", - "xlabel": "Herblore level", - "cascade": "yes", - "showbefore": "no", - "lowLevel": "31", - "label1": "Ranarr weed", - "low1": "-10", - "high1": "20", - "req1": "31", - "image1": "Grimy ranarr weed.png", - "color1": "#006400", - "label2": "Torstol", - "low2": "-70", - "high2": "20", - "req2": "31", - "image2": "Grimy torstol.png", - "color2": "#ff0000", - "label3": "Snapdragon", - "low3": "-60", - "high3": "20", - "req3": "31", - "image3": "Grimy snapdragon.png", - "color3": "#0000ff", - "label4": "Dwarf weed", - "low4": "-50", - "high4": "30", - "req4": "31", - "image4": "Grimy dwarf weed.png", - "color4": "#ff00ff", - "label5": "Lantadyme", - "low5": "-30", - "high5": "40", - "req5": "31", - "image5": "Grimy lantadyme.png", - "color5": "#ffdead", - "label6": "Cadantine", - "low6": "-10", - "high6": "50", - "req6": "31", - "image6": "Grimy cadantine.png", - "color6": "#a0522d", - "label7": "Kwuarm", - "low7": "10", - "high7": "60", - "req7": "31", - "image7": "Grimy kwuarm.png", - "color7": "#ffa500", - "label8": "Avantoe", - "low8": "20", - "high8": "60", - "req8": "31", - "image8": "Grimy avantoe.png", - "color8": "#00ff00", - "label9": "Irit leaf", - "low9": "30", - "high9": "70", - "req9": "31", - "image9": "Grimy irit leaf.png", - "color9": "#ffff00", - "label10": "Tarromin", - "low10": "70", - "high10": "-20", - "req10": "31", - "image10": "Grimy tarromin.png", - "color10": "#1e90ff", - "label11": "Harralander", - "low11": "100", - "high11": "-30", - "req11": "31", - "image11": "Grimy harralander.png", - "color11": "#4b0082", - "label12": "Marrentill", - "low12": "170", - "high12": "-40", - "req12": "31", - "image12": "Grimy marrentill.png", - "color12": "#708090", - "label13": "Guam", - "low13": "225", - "high13": "324", - "req13": "31", - "image13": "Grimy guam leaf.png", - "color13": "#000000" - } - ] - }, - { - "title": "Hero", - "names": [ - "npcs.hero", - "npcs.hero_variant01", - "npcs.hero_f" - ], - "entries": [ - { - "label": "Hero pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "39", - "high1": "160", - "req1": "80", - "color1": "gray", - "image1": "Thief Hero.png", - "label2": "Gloves of silence", - "low2": "40", - "high2": "168", - "req2": "80", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "42", - "high3": "176", - "req3": "80", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "46", - "high4": "193", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Herring", - "names": [ - "items.herring" - ], - "entries": [ - { - "label": "Herring cooking chance", - "label1": "Fire or Range", - "low1": "108", - "high1": "472", - "req1": "5", - "color1": "gray", - "image1": "Herring.png", - "label2": "Lumbridge range", - "low2": "118", - "high2": "492", - "req2": "5", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "120", - "high3": "484", - "req3": "5", - "color3": "red", - "image3": "Herring.png", - "label4": "Hosidius +10%", - "low4": "133", - "high4": "497", - "req4": "79", - "color4": "blue", - "image4": "Herring.png" - } - ] - }, - { - "title": "Hollow tree", - "names": [ - "objects.hollow_tree", - "objects.hollow_tree_big" - ], - "entries": [ - { - "label": "Hollow tree cut chance", - "showbefore": "no", - "label1": "Bronze", - "low1": "18", - "high1": "26", - "req1": "45", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "28", - "high2": "40", - "req2": "45", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "36", - "high3": "54", - "req3": "45", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "42", - "high4": "57", - "req4": "45", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "46", - "high5": "68", - "req5": "45", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "59", - "high6": "81", - "req6": "45", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "64", - "high7": "94", - "req7": "45", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "67", - "high8": "101", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png" - } - ] - }, - { - "title": "Hopper (Trouble Brewing)", - "names": [ - "objects.brew_hopper_red", - "objects.brew_hopper_blue", - "objects.brew_hopper_red_burning_1", - "objects.brew_hopper_red_burning_2", - "objects.brew_hopper_blue_burning_1", - "objects.brew_hopper_blue_burning_2", - "objects.brew_hopper_red_damaged_1", - "objects.brew_hopper_red_damaged_2", - "objects.brew_hopper_red_wet_1", - "objects.brew_hopper_red_wet_2", - "objects.brew_hopper_red_destroyed", - "objects.brew_hopper_blue_damaged_1", - "objects.brew_hopper_blue_damaged_2", - "objects.brew_hopper_blue_wet_1", - "objects.brew_hopper_blue_wet_2", - "objects.brew_hopper_blue_destroyed" - ], - "entries": [ - { - "label": "Torch burn chance", - "xlabel": "Firemaking level", - "showbefore": "no", - "label1": "Successful burn", - "low1": "12", - "high1": "112", - "req1": "1", - "color1": "red", - "image1": "Lit torch.png" - } - ] - }, - { - "title": "Hunters' loot sack (adept)", - "names": [ - "items.hg_lootsack_t1" - ], - "entries": [ - { - "label": "Herb chance", - "cascade": "yes", - "showbefore": "no", - "ylabel": "Probability", - "label1": "Lantadyme", - "low1": "-30", - "high1": "60", - "color1": "#1b9e77", - "image1": "Lantadyme.png", - "req1": "34", - "label2": "Cadantine", - "low2": "-10", - "high2": "70", - "color2": "#d95f02", - "image2": "Cadantine.png", - "req2": "13", - "label3": "Kwuarm", - "low3": "10", - "high3": "85", - "color3": "#7570b3", - "image3": "Kwuarm.png", - "label4": "Avantoe", - "low4": "20", - "high4": "100", - "color4": "#e7298a", - "image4": "Avantoe.png", - "label5": "Irit", - "low5": "30", - "high5": "115", - "color5": "#66a61e", - "image5": "Irit leaf.png", - "label6": "Ranarr", - "low6": "10", - "high6": "170", - "color6": "#e6ab02", - "image6": "Ranarr weed.png", - "label7": "Tarromin", - "low7": "70", - "high7": "-20", - "color7": "#a6761d", - "image7": "Tarromin.png", - "label8": "Harralander", - "low8": "999", - "high8": "999", - "color8": "SteelBlue", - "image8": "Harralander.png", - "lives": "999" - }, - { - "label": "Log chance", - "cascade": "yes", - "showbefore": "no", - "ylabel": "Probability", - "label1": "Magic", - "low1": "-60", - "high1": "60", - "color1": "DarkCyan", - "image1": "Magic logs.png", - "req1": "50", - "label2": "Yew", - "low2": "-50", - "high2": "90", - "color2": "OliveDrab", - "image2": "Yew logs.png", - "req2": "36", - "label3": "Mahogany", - "low3": "-40", - "high3": "130", - "color3": "FireBrick", - "image3": "Mahogany logs.png", - "req3": "24", - "label4": "Maple", - "low4": "0", - "high4": "160", - "color4": "DarkGoldenrod", - "image4": "Maple logs.png", - "label5": "Teak", - "low5": "999", - "high5": "999", - "color5": "DarkKhaki", - "image5": "Teak logs.png", - "lives5": [] - } - ] - }, - { - "title": "Hunters' loot sack (basic)", - "names": [ - "items.hg_lootsack_t0" - ], - "entries": [ - { - "label": "Log chance", - "cascade": "yes", - "showbefore": "no", - "ylabel": "Probability", - "label1": "Magic", - "low1": "-60", - "high1": "60", - "color1": "DarkCyan", - "image1": "Magic logs.png", - "req1": "50", - "label2": "Yew", - "low2": "-50", - "high2": "90", - "color2": "OliveDrab", - "image2": "Yew logs.png", - "req2": "36", - "label3": "Mahogany", - "low3": "-40", - "high3": "130", - "color3": "FireBrick", - "image3": "Mahogany logs.png", - "req3": "24", - "label4": "Maple", - "low4": "0", - "high4": "160", - "color4": "DarkGoldenrod", - "image4": "Maple logs.png", - "label5": "Teak", - "low5": "999", - "high5": "999", - "color5": "DarkKhaki", - "image5": "Teak logs.png", - "lives5": [] - } - ] - }, - { - "title": "Hunters' loot sack (expert)", - "names": [ - "items.hg_lootsack_t2" - ], - "entries": [ - { - "label": "Herb chance", - "cascade": "yes", - "showbefore": "no", - "ylabel": "Probability", - "label1": "Lantadyme", - "low1": "-30", - "high1": "60", - "color1": "#1b9e77", - "image1": "Lantadyme.png", - "req1": "34", - "label2": "Cadantine", - "low2": "-10", - "high2": "70", - "color2": "#d95f02", - "image2": "Cadantine.png", - "req2": "13", - "label3": "Kwuarm", - "low3": "10", - "high3": "85", - "color3": "#7570b3", - "image3": "Kwuarm.png", - "label4": "Avantoe", - "low4": "20", - "high4": "100", - "color4": "#e7298a", - "image4": "Avantoe.png", - "label5": "Irit", - "low5": "30", - "high5": "115", - "color5": "#66a61e", - "image5": "Irit leaf.png", - "label6": "Ranarr", - "low6": "10", - "high6": "170", - "color6": "#e6ab02", - "image6": "Ranarr weed.png", - "label7": "Tarromin", - "low7": "70", - "high7": "-20", - "color7": "#a6761d", - "image7": "Tarromin.png", - "label8": "Harralander", - "low8": "999", - "high8": "999", - "color8": "SteelBlue", - "image8": "Harralander.png", - "lives": "999" - }, - { - "label": "Log chance", - "cascade": "yes", - "showbefore": "no", - "ylabel": "Probability", - "label1": "Magic", - "low1": "-60", - "high1": "60", - "color1": "DarkCyan", - "image1": "Magic logs.png", - "req1": "50", - "label2": "Yew", - "low2": "-50", - "high2": "90", - "color2": "OliveDrab", - "image2": "Yew logs.png", - "req2": "36", - "label3": "Mahogany", - "low3": "-40", - "high3": "130", - "color3": "FireBrick", - "image3": "Mahogany logs.png", - "req3": "24", - "label4": "Maple", - "low4": "0", - "high4": "160", - "color4": "DarkGoldenrod", - "image4": "Maple logs.png", - "label5": "Teak", - "low5": "999", - "high5": "999", - "color5": "DarkKhaki", - "image5": "Teak logs.png", - "lives5": [] - } - ] - }, - { - "title": "Hunters' loot sack (master)", - "names": [ - "items.hg_lootsack_t3" - ], - "entries": [ - { - "label": "Herb chance", - "cascade": "yes", - "showbefore": "no", - "ylabel": "Probability", - "label1": "Lantadyme", - "low1": "-30", - "high1": "60", - "color1": "#1b9e77", - "image1": "Lantadyme.png", - "req1": "34", - "label2": "Cadantine", - "low2": "-10", - "high2": "70", - "color2": "#d95f02", - "image2": "Cadantine.png", - "req2": "13", - "label3": "Kwuarm", - "low3": "10", - "high3": "85", - "color3": "#7570b3", - "image3": "Kwuarm.png", - "label4": "Avantoe", - "low4": "20", - "high4": "100", - "color4": "#e7298a", - "image4": "Avantoe.png", - "label5": "Irit", - "low5": "30", - "high5": "115", - "color5": "#66a61e", - "image5": "Irit leaf.png", - "label6": "Ranarr", - "low6": "10", - "high6": "170", - "color6": "#e6ab02", - "image6": "Ranarr weed.png", - "label7": "Tarromin", - "low7": "70", - "high7": "-20", - "color7": "#a6761d", - "image7": "Tarromin.png", - "label8": "Harralander", - "low8": "999", - "high8": "999", - "color8": "SteelBlue", - "image8": "Harralander.png", - "lives": "999" - }, - { - "label": "Log chance", - "cascade": "yes", - "showbefore": "no", - "ylabel": "Probability", - "label1": "Magic", - "low1": "-60", - "high1": "60", - "color1": "DarkCyan", - "image1": "Magic logs.png", - "req1": "50", - "label2": "Yew", - "low2": "-50", - "high2": "90", - "color2": "OliveDrab", - "image2": "Yew logs.png", - "req2": "36", - "label3": "Mahogany", - "low3": "-40", - "high3": "130", - "color3": "FireBrick", - "image3": "Mahogany logs.png", - "req3": "24", - "label4": "Maple", - "low4": "0", - "high4": "160", - "color4": "DarkGoldenrod", - "image4": "Maple logs.png", - "label5": "Teak", - "low5": "999", - "high5": "999", - "color5": "DarkKhaki", - "image5": "Teak logs.png", - "lives5": [] - } - ] - }, - { - "title": "Hunters' loot sack (supplies)", - "names": [ - "items.hg_lootsack_trade" - ], - "entries": [ - { - "label": "Herb chance", - "cascade": "yes", - "showbefore": "no", - "ylabel": "Probability", - "label1": "Lantadyme", - "low1": "-30", - "high1": "60", - "color1": "#1b9e77", - "image1": "Lantadyme.png", - "req1": "34", - "label2": "Cadantine", - "low2": "-10", - "high2": "70", - "color2": "#d95f02", - "image2": "Cadantine.png", - "req2": "13", - "label3": "Kwuarm", - "low3": "10", - "high3": "85", - "color3": "#7570b3", - "image3": "Kwuarm.png", - "label4": "Avantoe", - "low4": "20", - "high4": "100", - "color4": "#e7298a", - "image4": "Avantoe.png", - "label5": "Irit", - "low5": "30", - "high5": "115", - "color5": "#66a61e", - "image5": "Irit leaf.png", - "label6": "Ranarr", - "low6": "10", - "high6": "170", - "color6": "#e6ab02", - "image6": "Ranarr weed.png", - "label7": "Tarromin", - "low7": "70", - "high7": "-20", - "color7": "#a6761d", - "image7": "Tarromin.png", - "label8": "Harralander", - "low8": "999", - "high8": "999", - "color8": "SteelBlue", - "image8": "Harralander.png", - "lives": "999" - }, - { - "label": "Log chance", - "cascade": "yes", - "showbefore": "no", - "ylabel": "Probability", - "label1": "Magic", - "low1": "-60", - "high1": "60", - "color1": "DarkCyan", - "image1": "Magic logs.png", - "req1": "50", - "label2": "Yew", - "low2": "-50", - "high2": "90", - "color2": "OliveDrab", - "image2": "Yew logs.png", - "req2": "36", - "label3": "Mahogany", - "low3": "-40", - "high3": "130", - "color3": "FireBrick", - "image3": "Mahogany logs.png", - "req3": "24", - "label4": "Maple", - "low4": "0", - "high4": "160", - "color4": "DarkGoldenrod", - "image4": "Maple logs.png", - "label5": "Teak", - "low5": "999", - "high5": "999", - "color5": "DarkKhaki", - "image5": "Teak logs.png", - "lives5": [] - } - ] - }, - { - "title": "Hurdle (Lunar Diplomacy)", - "names": [ - "objects.lunar_dream_hurdles" - ], - "entries": [ - { - "label": "Success chance", - "showbefore": "no", - "label1": "Hurdle", - "low1": "120", - "high1": "200", - "req1": "1", - "color1": "Gray", - "image1": "Hurdle (Lunar Diplomacy).png" - } - ] - }, - { - "title": "Icicles (Penguin Agility Course)", - "names": [ - "objects.peng_iciclepillar_clickzone" - ], - "entries": [ - { - "label": "Icicles success rate", - "lowlevel": "0", - "showbefore": "no", - "label1": "Tread-softly", - "low1": "155", - "high1": "308", - "req1": "30", - "color1": "#9eafc1", - "image1": "Agility icon.png" - } - ] - }, - { - "title": "Idril", - "names": [ - "npcs.prif_citizen_idril" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Imin", - "names": [ - "npcs.prif_citizen_imin" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Iminye", - "names": [ - "npcs.prif_citizen_iminye" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Indis", - "names": [ - "npcs.prif_citizen_indis" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Infernal eel", - "names": [ - "items.infernal_eel" - ], - "entries": [ - { - "label": "Infernal eel catch chance", - "showbefore": "no", - "label1": "Infernal eel", - "low1": "30", - "high1": "93", - "req1": "80", - "color1": "brown", - "image1": "Infernal eel.png" - } - ] - }, - { - "title": "Ingwe", - "names": [ - "npcs.prif_citizen_ingwe" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Ingwion", - "names": [ - "npcs.prif_citizen_ingwion" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Iron rocks", - "names": [ - "objects.ironrock2", - "objects.ironrock1", - "objects.gim_ironrock", - "objects.prif_mine_ironrock1" - ], - "entries": [ - { - "label": "Iron rocks mining chance", - "showbefore": "no", - "label1": "Iron rocks", - "low1": "96", - "high1": "350", - "req1": "15", - "color1": "maroon", - "image1": "Iron ore.png" - } - ] - }, - { - "title": "Jade", - "names": [ - "items.jade" - ], - "entries": [ - { - "label": "Gem cutting rates", - "label1": "Opal", - "low1": "128", - "high1": "250", - "req1": "1", - "color1": "gray", - "image1": "Opal.png", - "label2": "Jade", - "low2": "100", - "high2": "245", - "req2": "13", - "color2": "green", - "image2": "Jade.png", - "label3": "Red topaz", - "low3": "90", - "high3": "240", - "req3": "16", - "color3": "pink", - "image3": "Red topaz.png" - } - ] - }, - { - "title": "Jade bolts (e)", - "names": [ - "items.xbows_crossbow_bolts_blurite_tipped_jade_enchanted" - ], - "entries": [ - { - "label": "Enemy evasion chance", - "xlabel": "Opponent's Agility level", - "ylabel": "Evasion chance", - "showbefore": "no", - "label1": "Earth's Fury", - "low1": "-40", - "high1": "280", - "req1": "1", - "color1": "#00A36C", - "image1": "Jade bolts (e) 5.png" - } - ] - }, - { - "title": "Jade dragon bolts (e)", - "names": [ - "items.dragon_bolts_enchanted_jade" - ], - "entries": [ - { - "label": "Enemy evasion chance", - "xlabel": "Opponent's Agility level", - "ylabel": "Evasion chance", - "showbefore": "no", - "label1": "Earth's Fury", - "low1": "-40", - "high1": "280", - "req1": "1", - "color1": "#00A36C", - "image1": "Jade dragon bolts (e) 5.png" - } - ] - }, - { - "title": "Jug of wine", - "names": [ - "items.jug_wine" - ], - "entries": [ - { - "label": "Jug of wine success chance", - "showbefore": "no", - "label1": "Jug of wine", - "low1": "48", - "high1": "352", - "req1": "35", - "color1": "#a5423c", - "image1": "Jug of wine detail.png" - } - ] - }, - { - "title": "Karambwanji", - "names": [ - "items.tbwt_quest_cooked_karambwanji" - ], - "entries": [ - { - "label": "Karambwanji cooking chance", - "label1": "Fire or Range", - "low1": "200", - "high1": "400", - "req1": "1", - "color1": "gray", - "image1": "Karambwanji.png", - "label2": "Hosidius +5%", - "low2": "212", - "high2": "412", - "req2": "1", - "color2": "red", - "image2": "Karambwanji.png", - "label3": "Hosidius +10%", - "low3": "225", - "high3": "425", - "req3": "79", - "color3": "blue", - "image3": "Karambwanji.png" - } - ] - }, - { - "title": "Kelyn", - "names": [ - "npcs.sote_lady_ithell_normal", - "npcs.mourning_town_elf_5_vis", - "npcs.sote_lady_ithell_vis", - "npcs.sote_lady_ithell_upass", - "npcs.lady_ithell" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Kharidian cactus", - "names": [ - "objects.desert_cactus_full", - "objects.desert_cactus_empty" - ], - "entries": [ - { - "label": "Kharidian cactus cutting chance", - "xlabel": "Woodcutting level", - "label1": "Knife or slashing weapon", - "low1": "30", - "high1": "252", - "req1": "1", - "color1": "#628b11", - "image1": "Knife.png" - } - ] - }, - { - "title": "Knight of Ardougne", - "names": [ - "npcs.knight_of_ardougne", - "npcs.knight_of_ardougne_f", - "npcs.knight_of_ardougne_west_vis", - "npcs.knight_of_ardougne_f_west_vis" - ], - "entries": [ - { - "label": "Knight of Ardougne pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "50", - "high1": "240", - "req1": "55", - "color1": "gray", - "image1": "Thief Knight.png", - "label2": "Gloves of silence", - "low2": "52", - "high2": "252", - "req2": "55", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "55", - "high3": "264", - "req3": "55", - "color3": "black", - "image3": "Ardougne cloak 2.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "60", - "high4": "290", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Kyren fish (6)", - "names": [ - "items.raids_fish6_cooked" - ], - "entries": [ - { - "label": "Cooked Kyren fish (6) cooking chance", - "label1": "Fire", - "low1": "163", - "high1": "255", - "req1": "90", - "color1": "orange", - "image1": "Firemaking icon.png" - } - ] - }, - { - "title": "Larran's big chest", - "names": [ - "objects.slayer_larran_chest_big_closed", - "objects.slayer_larran_chest_big_open" - ], - "entries": [ - { - "label": "Larran's big chest fish chance", - "xlabel": "Fishing level", - "ylabel": "Chance to receive", - "cascade": [], - "label1": "Raw manta ray", - "low1": "-10", - "high1": "20", - "image1": "Raw manta ray.png", - "color1": [], - "label2": "Raw sea turtle", - "low2": "-10", - "high2": "50", - "image2": "Raw sea turtle.png", - "color2": [], - "label3": "Raw shark", - "low3": "-60", - "high3": "140", - "image3": "Raw shark.png", - "color3": [], - "label4": "Raw monkfish", - "low4": "0", - "high4": "170", - "image4": "Raw monkfish.png", - "color4": [], - "label5": "Raw swordfish", - "low5": "30", - "high5": "200", - "image5": "Raw swordfish.png", - "color5": [], - "label6": "Raw lobster", - "low6": "70", - "high6": "270", - "image6": "Raw lobster.png", - "color6": [], - "label7": "Raw tuna", - "low7": "225", - "high7": "324", - "image7": "Raw tuna.png", - "color7": [] - } - ] - }, - { - "title": "Larran's small chest", - "names": [ - "objects.slayer_larran_chest_small_closed", - "objects.slayer_larran_chest_small_open" - ], - "entries": [ - { - "label": "Larran's small chest fish chance", - "xlabel": "Fishing level", - "ylabel": "Chance to receive", - "cascade": [], - "label1": "Raw manta ray", - "low1": "-10", - "high1": "20", - "image1": "Raw manta ray.png", - "color1": [], - "label2": "Raw sea turtle", - "low2": "-10", - "high2": "50", - "image2": "Raw sea turtle.png", - "color2": [], - "label3": "Raw shark", - "low3": "-60", - "high3": "140", - "image3": "Raw shark.png", - "color3": [], - "label4": "Raw monkfish", - "low4": "0", - "high4": "170", - "image4": "Raw monkfish.png", - "color4": [], - "label5": "Raw swordfish", - "low5": "30", - "high5": "200", - "image5": "Raw swordfish.png", - "color5": [], - "label6": "Raw lobster", - "low6": "70", - "high6": "270", - "image6": "Raw lobster.png", - "color6": [], - "label7": "Raw tuna", - "low7": "225", - "high7": "324", - "image7": "Raw tuna.png", - "color7": [] - } - ] - }, - { - "title": "Lean snail meat", - "names": [ - "items.snail_corpse_cooked2" - ], - "entries": [ - { - "label": "Lean snail meat cooking chance", - "label1": "Fire", - "low1": "93", - "high1": "444", - "req1": "17", - "color1": "orange", - "image1": "Firemaking icon.png", - "label2": "Range", - "low2": "85", - "high2": "428", - "req2": "17", - "color2": "saddlebrown", - "image2": "Cooking range icon.png", - "label3": "Lumbridge range", - "low3": "95", - "high3": "448", - "req3": "17", - "color3": "green", - "image3": "Lumbridge Teleport.png", - "label4": "Hosidius +5%", - "low4": "97", - "high4": "440", - "req4": "17", - "color4": "red", - "image4": "Cooking range icon.png", - "label5": "Hosidius +10%", - "low5": "110", - "high5": "453", - "req5": "79", - "color5": "blue", - "image5": "Cooking range icon.png" - } - ] - }, - { - "title": "Leaping salmon", - "names": [ - "items.brut_spawning_salmon" - ], - "entries": [ - { - "label": "Barbarian rod fishing chance", - "cascade": "yes", - "showbefore": "no", - "label1": "Leaping sturgeon", - "low1": "8", - "high1": "64", - "req1": "70", - "color1": "green", - "image1": "Leaping sturgeon.png", - "label2": "Leaping salmon", - "low2": "16", - "high2": "96", - "req2": "58", - "color2": "brown", - "image2": "Leaping salmon.png", - "label3": "Leaping trout", - "low3": "32", - "high3": "192", - "req3": "48", - "color3": "gray", - "image3": "Leaping trout.png" - } - ] - }, - { - "title": "Leaping sturgeon", - "names": [ - "items.brut_sturgeon" - ], - "entries": [ - { - "label": "Barbarian rod fishing chance", - "cascade": "yes", - "showbefore": "no", - "label1": "Leaping sturgeon", - "low1": "8", - "high1": "64", - "req1": "70", - "color1": "green", - "image1": "Leaping sturgeon.png", - "label2": "Leaping salmon", - "low2": "16", - "high2": "96", - "req2": "58", - "color2": "brown", - "image2": "Leaping salmon.png", - "label3": "Leaping trout", - "low3": "32", - "high3": "192", - "req3": "48", - "color3": "gray", - "image3": "Leaping trout.png" - } - ] - }, - { - "title": "Leaping trout", - "names": [ - "items.brut_spawning_trout" - ], - "entries": [ - { - "label": "Barbarian rod fishing chance", - "cascade": "yes", - "showbefore": "no", - "label1": "Leaping sturgeon", - "low1": "8", - "high1": "64", - "req1": "70", - "color1": "green", - "image1": "Leaping sturgeon.png", - "label2": "Leaping salmon", - "low2": "16", - "high2": "96", - "req2": "58", - "color2": "brown", - "image2": "Leaping salmon.png", - "label3": "Leaping trout", - "low3": "32", - "high3": "192", - "req3": "48", - "color3": "gray", - "image3": "Leaping trout.png" - } - ] - }, - { - "title": "Lenwe", - "names": [ - "npcs.prif_citizen_lenwe" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Light Jungle", - "names": [ - "objects.tai_bwo_jungle_vegetation_easy_1", - "objects.tai_bwo_jungle_vegetation_easy_2", - "objects.tai_bwo_jungle_vegetation_easy_3", - "objects.tai_bwo_jungle_vegetation_easy_4", - "objects.tai_bwo_jungle_vegetation_easy_5" - ], - "entries": [ - { - "label": "Light Jungle Cut Chance", - "showbefore": "no", - "label1": "Plain Machete", - "low1": "49", - "high1": "169", - "req1": "10", - "color1": "dimgray", - "image1": "Machete.png", - "label2": "Opal Machete", - "low2": "54", - "high2": "174", - "req2": "10", - "color2": "lightgray", - "image2": "Opal machete.png", - "label3": "Jade Machete", - "low3": "70", - "high3": "190", - "req3": "10", - "color3": "lightgreen", - "image3": "Jade machete.png", - "label4": "Red Topaz Machete", - "low4": "85", - "high4": "205", - "req4": "10", - "color4": "firebrick", - "image4": "Red topaz machete.png" - } - ] - }, - { - "title": "Limestone rock", - "names": [ - "objects.limestone_rock1", - "objects.limestone_rock2", - "objects.limestone_rock3", - "objects.limestone_rock_noore" - ], - "entries": [ - { - "label": "Pile of rock mining chance", - "showbefore": "no", - "label1": "Limestone", - "low1": "95", - "high1": "350", - "req1": "10", - "color1": "grey", - "image1": "Limestone.png" - } - ] - }, - { - "title": "Lindir", - "names": [ - "npcs.prif_citizen_lindir" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Lobster", - "names": [ - "items.lobster" - ], - "entries": [ - { - "label": "Lobster cooking chance", - "showbefore": "no", - "label1": "Fire or Range", - "low1": "38", - "high1": "332", - "req1": "40", - "color1": "saddlebrown", - "image1": "Lobster.png", - "label2": "Gauntlets", - "low2": "55", - "high2": "368", - "req2": "40", - "color2": "grey", - "image2": "Cooking gauntlets.png", - "label3": "Hosidius +5%", - "low3": "50", - "high3": "344", - "req3": "40", - "color3": "red", - "image3": "Lobster.png", - "label4": "Hosidius +10%", - "low4": "63", - "high4": "357", - "req4": "79", - "color4": "blue", - "image4": "Lobster.png", - "label5": "Hosidius +5%, gauntlets", - "low5": "67", - "high5": "380", - "req5": "40", - "color5": "#ffcccb", - "image5": "Cooking gauntlets.png", - "label6": "Hosidius +10%, gauntlets", - "low6": "80", - "high6": "393", - "req6": "79", - "color6": "#ccccff", - "image6": "Cooking gauntlets.png" - } - ] - }, - { - "title": "Log balance (East Ardougne)", - "names": [ - "objects.ardougne_log_balance_left_sc", - "objects.ardougne_log_balance_mid_sc", - "objects.ardougne_log_balance_right_sc" - ], - "entries": [ - { - "label": "Log balance success rate", - "showbefore": "no", - "label1": "Log balance", - "low1": "90", - "high1": "250", - "req1": "33", - "color1": "#897b31", - "image1": "Agility icon.png" - } - ] - }, - { - "title": "Log balance (Wilderness Agility Course)", - "names": [ - "objects.wilderness_log_balance1" - ], - "entries": [ - { - "label": "Log balance", - "label1": "Walk-across success rate", - "xlabel": "Agility level", - "low1": "200", - "high1": "250", - "req1": "1", - "color1": "#151111", - "image1": "Agility icon.png" - } - ] - }, - { - "title": "Lucky impling", - "names": [ - "npcs.ii_impling_type_11", - "npcs.ii_impling_type_11_maze" - ], - "entries": [ - { - "label": "Lucky impling catch chance", - "showbefore": "no", - "label1": "Butterfly net", - "low1": "3", - "high1": "100", - "req1": "89", - "color1": "saddlebrown", - "image1": "Butterfly net.png", - "label2": "Barehanded or magic butterfly net", - "low2": "23", - "high2": "120", - "req2": "89", - "color2": "green", - "image2": "Magic butterfly net.png" - } - ] - }, - { - "title": "Mackerel", - "names": [ - "items.mackerel" - ], - "entries": [ - { - "label": "Mackerel cooking chance", - "label1": "Fire or Range", - "low1": "98", - "high1": "452", - "req1": "10", - "color1": "gray", - "image1": "Mackerel.png", - "label2": "Lumbridge range", - "low2": "108", - "high2": "472", - "req2": "10", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "110", - "high3": "464", - "req3": "10", - "color3": "red", - "image3": "Mackerel.png", - "label4": "Hosidius +10%", - "low4": "123", - "high4": "477", - "req4": "79", - "color4": "blue", - "image4": "Mackerel.png" - } - ] - }, - { - "title": "Maeglin", - "names": [ - "npcs.prif_citizen_maeglin" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Magic Stall", - "names": [ - "objects.mm_stall_magic" - ], - "entries": [ - { - "label": "Magic Stall thieving chance", - "showbefore": "no", - "label1": "Magic Stall", - "low1": "20", - "high1": "180", - "req1": "65", - "color1": "brown", - "image1": "Fire rune.png" - } - ] - }, - { - "title": "Magic birdhouse", - "names": [ - "objects.birdhouse_magic_built", - "objects.birdhouse_magic_full", - "objects.birdhouse_magic_bird" - ], - "entries": [ - { - "label": "Seed nest chance", - "xlabel": "Hunter level", - "label1": "Seed nest", - "low1": "0", - "high1": "200", - "req1": "74", - "color1": "grey", - "image1": "Bird nest (seeds).png" - }, - { - "label": "Other nests (10 rolls per birdhouse)", - "xlabel": "Hunter level", - "birdhouse": "yes", - "label1": "Magic", - "high1": "170", - "req1": "74", - "color1": "#708090", - "image1": "Magic bird house.png" - } - ] - }, - { - "title": "Magic tree", - "names": [ - "objects.magictree" - ], - "entries": [ - { - "label": "Magic tree cut chance", - "showbefore": "no", - "label1": "Bronze", - "low1": "2", - "high1": "6", - "req1": "75", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "3", - "high2": "9", - "req2": "75", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "4", - "high3": "12", - "req3": "75", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "5", - "high4": "13", - "req4": "75", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "5", - "high5": "15", - "req5": "75", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "6", - "high6": "18", - "req6": "75", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "7", - "high7": "21", - "req7": "75", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "7", - "high8": "22", - "req8": "75", - "color8": "firebrick", - "image8": "Dragon axe.png" - } - ] - }, - { - "title": "Magical wheat", - "names": [ - "objects.ii_maze_wheat_no_block1", - "objects.ii_maze_wheat_no_block2", - "objects.ii_maze_wheat_no_block3", - "objects.ii_maze_wheat_block1", - "objects.ii_maze_wheat_block2", - "objects.ii_maze_wheat_block_moveable1", - "objects.ii_maze_wheat_block_type8", - "objects.ii_maze_wheat_block2_type8", - "objects.ii_maze_wheat_block3_type8", - "objects.ii_maze_wheat_surround_block", - "objects.ii_maze_wheat_surround_gate", - "objects.ii_maze_wheat_invis" - ], - "entries": [ - { - "label": "Wheat Push Speed", - "cascade": "yes", - "showbefore": "no", - "label1": "Efficient", - "low1": "0", - "high1": "100", - "req1": "1", - "color1": "goldenrod", - "image1": "Strength icon.png", - "label2": "Normal", - "low2": "10", - "high2": "256", - "req2": "1", - "color2": "gray", - "image2": "Strength icon.png", - "label3": "Hard work", - "low3": "256", - "high3": "256", - "req3": "1", - "color3": "firebrick", - "image3": "Strength icon.png" - } - ] - }, - { - "title": "Magpie impling", - "names": [ - "npcs.ii_impling_type_8", - "npcs.ii_impling_type_8_maze" - ], - "entries": [ - { - "label": "Magpie impling catch chance", - "showbefore": "no", - "label1": "Butterfly net", - "low1": "15", - "high1": "177", - "req1": "65", - "color1": "saddlebrown", - "image1": "Butterfly net.png", - "label2": "Barehanded or magic butterfly net", - "low2": "35", - "high2": "197", - "req2": "65", - "color2": "green", - "image2": "Magic butterfly net.png" - } - ] - }, - { - "title": "Mahogany birdhouse", - "names": [ - "objects.birdhouse_mahogany_built", - "objects.birdhouse_mahogany_full", - "objects.birdhouse_mahogany_bird" - ], - "entries": [ - { - "label": "Seed nest chance", - "xlabel": "Hunter level", - "label1": "Seed nest", - "low1": "0", - "high1": "200", - "req1": "49", - "color1": "grey", - "image1": "Bird nest (seeds).png" - }, - { - "label": "Other nests (10 rolls per birdhouse)", - "xlabel": "Hunter level", - "birdhouse": "yes", - "label1": "Mahogany", - "high1": "150", - "req1": "49", - "color1": "#ffff00", - "image1": "Mahogany bird house.png" - } - ] - }, - { - "title": "Mahogany tree", - "names": [ - "objects.mahoganytree", - "objects.prif_mahoganytree", - "objects.mahoganytree_update" - ], - "entries": [ - { - "label": "Mahogany tree cut chance", - "showbefore": "no", - "label1": "Bronze", - "low1": "8", - "high1": "25", - "req1": "50", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "12", - "high2": "38", - "req2": "50", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "16", - "high3": "50", - "req3": "50", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "18", - "high4": "54", - "req4": "50", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "20", - "high5": "63", - "req5": "50", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "25", - "high6": "75", - "req6": "50", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "29", - "high7": "88", - "req7": "50", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "34", - "high8": "94", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png", - "label9": "Crystal", - "low9": "36", - "high9": "97", - "req9": "71", - "color9": "cyan", - "image9": "Crystal axe.png" - } - ] - }, - { - "title": "Mahtan", - "names": [ - "npcs.prif_citizen_mahtan" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Man", - "names": [ - "npcs.man", - "npcs.man_indoor", - "npcs.zeah_man", - "npcs.sote_citizen_male_2", - "npcs.man2", - "npcs.zeah_man2", - "npcs.man3", - "npcs.zeah_man3", - "npcs.man4", - "npcs.death_man_indoors1", - "npcs.man4_for_musa_point", - "npcs.al_kharid_man", - "npcs.falador_man2", - "npcs.falador_man3", - "npcs.karamja_man", - "npcs.varrock_man1", - "npcs.shayzien_man_2", - "npcs.shayzien_man_1" - ], - "entries": [ - { - "label": "Man pickpocket chance", - "label1": "Normal", - "low1": "180", - "high1": "240", - "req1": "1", - "color1": "gray", - "image1": "Thief Man.png", - "label2": "Gloves of silence", - "low2": "189", - "high2": "252", - "req2": "1", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "198", - "high3": "264", - "req3": "1", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "217", - "high4": "290", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Man (East Ardougne)", - "names": [ - "npcs.ardougnian_male1" - ], - "entries": [ - { - "label": "Man pickpocket chance", - "label1": "Normal", - "low1": "180", - "high1": "240", - "req1": "1", - "color1": "gray", - "image1": "Thief Man.png", - "label2": "Gloves of silence", - "low2": "189", - "high2": "252", - "req2": "1", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "198", - "high3": "264", - "req3": "1", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "217", - "high4": "290", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Man trap", - "names": [], - "entries": [ - { - "label": "Man trap evasion chance", - "xlabel": "Agility level", - "ylabel": "Evasion chance", - "showbefore": "no", - "label1": "Man trap", - "low1": "30", - "high1": "210", - "req1": "1", - "color1": "#170000", - "image1": "Man trap icon.png" - } - ] - }, - { - "title": "Maniacal monkey (Hunter)", - "names": [ - "npcs.hunting_monkey", - "npcs.hunting_monkey_invisible", - "npcs.hunting_monkey_sans_tail_1", - "npcs.hunting_monkey_sans_tail_2", - "npcs.hunting_monkey_sans_tail_3" - ], - "entries": [ - { - "label": "Maniacal monkey catch chance", - "showbefore": "no", - "label1": "Maniacal monkey", - "low1": "-79", - "high1": "227", - "req1": "60", - "color1": "darkolivegreen", - "image1": "Damaged monkey tail.png" - } - ] - }, - { - "title": "Manta ray", - "names": [ - "items.mantaray" - ], - "entries": [ - { - "label": "Manta ray cooking chance", - "showbefore": "no", - "label1": "Fire", - "low1": "1", - "high1": "202", - "req1": "91", - "color1": "orange", - "image1": "Firemaking icon.png", - "label2": "Range", - "low2": "1", - "high2": "222", - "req2": "91", - "color2": "saddlebrown", - "image2": "Cooking range icon.png", - "label3": "Hosidius +5%", - "low3": "13", - "high3": "234", - "req3": "91", - "color3": "red", - "image3": "Cooking range icon.png", - "label4": "Hosidius +10%", - "low4": "26", - "high4": "247", - "req4": "91", - "color4": "blue", - "image4": "Cooking range icon.png" - } - ] - }, - { - "title": "Maple birdhouse", - "names": [ - "objects.birdhouse_maple_built", - "objects.birdhouse_maple_full", - "objects.birdhouse_maple_bird" - ], - "entries": [ - { - "label": "Seed nest chance", - "xlabel": "Hunter level", - "label1": "Seed nest", - "low1": "0", - "high1": "200", - "req1": "44", - "color1": "grey", - "image1": "Bird nest (seeds).png" - }, - { - "label": "Other nests (10 rolls per birdhouse)", - "xlabel": "Hunter level", - "birdhouse": "yes", - "label1": "Maple", - "high1": "140", - "req1": "44", - "color1": "#00ff00", - "image1": "Maple bird house.png" - } - ] - }, - { - "title": "Maple tree", - "names": [ - "objects.mapletree", - "objects.prif_mapletree", - "objects.mapletree_update" - ], - "entries": [ - { - "label": "Maple tree cut chance", - "showbefore": "no", - "label1": "Bronze", - "low1": "8", - "high1": "25", - "req1": "45", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "12", - "high2": "37", - "req2": "45", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "16", - "high3": "50", - "req3": "45", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "18", - "high4": "56", - "req4": "45", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "20", - "high5": "62", - "req5": "45", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "24", - "high6": "75", - "req6": "45", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "28", - "high7": "87", - "req7": "45", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "30", - "high8": "93", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png" - } - ] - }, - { - "title": "Marble trap", - "names": [], - "entries": [ - { - "label": "Marble trap evasion chance", - "xlabel": "Agility level", - "ylabel": "Evasion chance", - "showbefore": "no", - "label1": "Marble trap", - "low1": "30", - "high1": "210", - "req1": "1", - "color1": "#a6a190", - "image1": "Marble trap icon.png" - } - ] - }, - { - "title": "Marshy jungle vine", - "names": [ - "objects.snake_vine_full", - "objects.snake_vine_empty" - ], - "entries": [ - { - "label": "Snake weed harvest chance", - "label1": "Grimy snake weed", - "low1": "9", - "high1": "219", - "req1": "1", - "color1": "grey", - "image1": "Grimy snake weed.png" - } - ] - }, - { - "title": "Martin the Master Gardener", - "names": [ - "npcs.martin_the_master_farmer" - ], - "entries": [ - { - "label": "Master Farmer pickpocket chance", - "label1": "Normal", - "low1": "90", - "high1": "240", - "req1": "38", - "color1": "gray", - "image1": "Thief Master farmer.png", - "label2": "Gloves of silence", - "low2": "94", - "high2": "252", - "req2": "38", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "99", - "high3": "264", - "req3": "67", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "108", - "high4": "290", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Master Farmer", - "names": [ - "npcs.master_farmer_1", - "npcs.master_farmer_2", - "npcs.master_farmer_1_f", - "npcs.master_farmer_2_f", - "npcs.varlamore_master_farmer_f_1", - "npcs.varlamore_master_farmer_f_2", - "npcs.varlamore_master_farmer_f_3", - "npcs.varlamore_master_farmer_f_4", - "npcs.varlamore_master_farmer_m_1", - "npcs.varlamore_master_farmer_m_2", - "npcs.varlamore_master_farmer_m_3", - "npcs.varlamore_master_farmer_m_4" - ], - "entries": [ - { - "label": "Master Farmer pickpocket chance", - "label1": "Normal", - "low1": "90", - "high1": "240", - "req1": "38", - "color1": "gray", - "image1": "Thief Master farmer.png", - "label2": "Gloves of silence", - "low2": "94", - "high2": "252", - "req2": "38", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "99", - "high3": "264", - "req3": "67", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "108", - "high4": "290", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Mawrth", - "names": [ - "npcs.mourning_town_elf_4", - "npcs.sote_mawrth", - "npcs.sote_mawrth_cutscene" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Meat pie", - "names": [ - "items.meat_pie", - "items.half_a_meat_pie" - ], - "entries": [ - { - "label": "Meat pie cooking chance", - "label1": "Range", - "low1": "78", - "high1": "412", - "req1": "20", - "color1": "gray", - "image1": "Meat pie.png", - "label2": "Lumbridge range", - "low2": "88", - "high2": "432", - "req2": "20", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "90", - "high3": "424", - "req3": "20", - "color3": "red", - "image3": "Meat pie.png", - "label4": "Hosidius +10%", - "low4": "103", - "high4": "437", - "req4": "79", - "color4": "blue", - "image4": "Meat pie.png" - } - ] - }, - { - "title": "Meat tree", - "names": [ - "npcs.raids_dogodile_meat_tree", - "objects.raids_meat_tree_full", - "objects.raids_meat_tree_empty" - ], - "entries": [ - { - "label": "Meat tree cut chance", - "label1": "Meat tree", - "low1": "50", - "high1": "200", - "req1": "1", - "color1": "red", - "image1": "Meat tree.png" - } - ] - }, - { - "title": "Medium Jungle", - "names": [ - "objects.tai_bwo_jungle_vegetation_med_1", - "objects.tai_bwo_jungle_vegetation_med_2", - "objects.tai_bwo_jungle_vegetation_med_3", - "objects.tai_bwo_jungle_vegetation_med_4", - "objects.tai_bwo_jungle_vegetation_med_5" - ], - "entries": [ - { - "label": "Medium Jungle Cut Chance", - "showbefore": "no", - "label1": "Plain Machete", - "low1": "34", - "high1": "85", - "req1": "20", - "color1": "dimgray", - "image1": "Machete.png", - "label2": "Opal Machete", - "low2": "39", - "high2": "90", - "req2": "20", - "color2": "lightgray", - "image2": "Opal machete.png", - "label3": "Jade Machete", - "low3": "54", - "high3": "105", - "req3": "20", - "color3": "lightgreen", - "image3": "Jade machete.png", - "label4": "Red Topaz Machete", - "low4": "70", - "high4": "121", - "req4": "20", - "color4": "firebrick", - "image4": "Red topaz machete.png" - } - ] - }, - { - "title": "Menaphite Thug", - "names": [ - "npcs.feud_egyptian_doorman_2", - "npcs.feud_egyptian_doorman_1" - ], - "entries": [ - { - "label": "Menaphite Thug knockout chance", - "showbefore": "no", - "label1": "Menaphite Thug", - "low1": "78", - "high1": "240", - "req1": "65", - "color1": "purple", - "image1": "Menaphite Thug chathead.png" - }, - { - "label": "Menaphite Thug pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "50", - "high1": "160", - "req1": "65", - "color1": "gray", - "image1": "Thief Menaphite thug.png", - "label2": "Gloves of silence", - "low2": "52", - "high2": "168", - "req2": "65", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "55", - "high3": "176", - "req3": "65", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "60", - "high4": "193", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Mind rune (The Slug Menace)", - "names": [ - "items.slug2_rune_mind" - ], - "entries": [ - { - "label": "Channeling blank rune success chance", - "xlabel": "Runecraft level", - "showbefore": "no", - "label1": "Mind rune", - "low1": "110", - "high1": "253", - "req1": "30", - "color1": "#b76f15", - "image1": "Mind rune (The Slug Menace).png" - } - ] - }, - { - "title": "Miriel", - "names": [ - "npcs.prif_citizen_miriel" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Mithrellas", - "names": [ - "npcs.prif_citizen_mithrellas" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Mithril rocks", - "names": [ - "objects.mithrilrock2", - "objects.mithrilrock1", - "objects.prif_mine_mithrilrock1" - ], - "entries": [ - { - "label": "Mithril rocks mining chance", - "showbefore": "no", - "label1": "Mithril rocks", - "low1": "4", - "high1": "50", - "req1": "55", - "color1": "slateblue", - "image1": "Mithril ore.png" - } - ] - }, - { - "title": "Money making guide/Cooking raw moonlight antelope", - "names": [], - "entries": [ - { - "label": "Cooked moonlight antelope cooking chance", - "showbefore": "no", - "label1": "Fire", - "low1": "1", - "high1": "185", - "req1": "92", - "color1": "orange", - "image1": "Firemaking icon.png", - "label2": "Range", - "low2": "1", - "high2": "200", - "req2": "92", - "color2": "saddlebrown", - "image2": "Cooking range icon.png", - "label3": "Hosidius +5%", - "low3": "13", - "high3": "212", - "req3": "92", - "color3": "red", - "image3": "Cooking range icon.png", - "label4": "Hosidius +10%", - "low4": "26", - "high4": "225", - "req4": "92", - "color4": "blue", - "image4": "Cooking range icon.png" - } - ] - }, - { - "title": "Money making guide/Cooking raw sunlight antelope", - "names": [], - "entries": [ - { - "label": "Cooked sunlight antelope cooking chance", - "showbefore": "no", - "label1": "Fire", - "low1": "8", - "high1": "254", - "req1": "62", - "color1": "orange", - "image1": "Firemaking icon.png", - "label2": "Range", - "low2": "8", - "high2": "265", - "req2": "62", - "color2": "saddlebrown", - "image2": "Cooking range icon.png", - "label3": "Hosidius +5%", - "low3": "20", - "high3": "277", - "req3": "62", - "color3": "red", - "image3": "Cooking range icon.png", - "label4": "Hosidius +10%", - "low4": "33", - "high4": "290", - "req4": "79", - "color4": "blue", - "image4": "Cooking range icon.png" - } - ] - }, - { - "title": "Monkeybars (Yanille Agility Dungeon)", - "names": [ - "objects.monkeybars_mid", - "objects.monkeybars_end2" - ], - "entries": [ - { - "label": "Monkeybars", - "label1": "Swinging across success rate", - "xlabel": "Agility level", - "low1": "36", - "high1": "330", - "req1": "57", - "showbefore": "no", - "color1": "#453321", - "image1": "Agility icon.png" - } - ] - }, - { - "title": "Monkfish", - "names": [ - "items.monkfish" - ], - "entries": [ - { - "label": "Monkfish cooking chance", - "showbefore": "no", - "label1": "Fire", - "low1": "11", - "high1": "275", - "req1": "62", - "color1": "orange", - "image1": "Firemaking icon.png", - "label2": "Range", - "low2": "13", - "high2": "280", - "req2": "62", - "color2": "saddlebrown", - "image2": "Cooking range icon.png", - "label3": "Gauntlets", - "low3": "24", - "high3": "290", - "req3": "62", - "color3": "grey", - "image3": "Cooking gauntlets.png", - "label4": "Hosidius +5%", - "low4": "25", - "high4": "292", - "req4": "62", - "color4": "red", - "image4": "Cooking range icon.png", - "label5": "Hosidius +10%", - "low5": "38", - "high5": "305", - "req5": "79", - "color5": "blue", - "image5": "Cooking range icon.png", - "label6": "Hosidius +5%, gauntlets", - "low6": "36", - "high6": "302", - "req6": "62", - "color6": "#ffcccb", - "image6": "Cooking gauntlets.png", - "label7": "Hosidius +10%, gauntlets", - "low7": "49", - "high7": "315", - "req7": "79", - "color7": "#ccccff", - "image7": "Cooking gauntlets.png" - } - ] - }, - { - "title": "Moonlight moth", - "names": [ - "npcs.moth_moonlight", - "npcs.moth_moonlight_low_wander", - "npcs.moth_moonlight_noclick" - ], - "entries": [ - { - "label": "Moonlight moth chance", - "showbefore": "no", - "label1": "Butterfly net", - "low1": "0", - "high1": "276", - "req1": "75", - "color1": "saddlebrown", - "image1": "Butterfly net.png", - "label2": "Barehanded or magic butterfly net", - "low2": "20", - "high2": "286", - "req2": "75", - "color2": "green", - "image2": "Magic butterfly net.png" - } - ] - }, - { - "title": "Motherlode Mine", - "names": [], - "entries": [ - { - "label": "Pay-dirt mining chance", - "showbefore": "no", - "xlabel": "Mining Level", - "label1": "Pay-dirt", - "low1": "60", - "high1": "105", - "req1": "30", - "color1": "brown", - "image1": "Pay-dirt.png" - }, - { - "label": "Motherlode Mine ore chance", - "xlabel": "Mining level", - "cascade": "yes", - "showbefore": "no", - "label1": "Golden nugget", - "low1": "7", - "high1": "7", - "req1": "30", - "color1": "gold", - "image1": "Golden nugget.png", - "label2": "Runite ore", - "low2": "-20", - "high2": "5", - "req2": "85", - "color2": "steelblue", - "image2": "Runite ore.png", - "label3": "Adamantite ore", - "low3": "-90", - "high3": "50", - "req3": "70", - "color3": "seagreen", - "image3": "Adamantite ore.png", - "label4": "Mithril ore", - "low4": "-19", - "high4": "90", - "req4": "55", - "color4": "slateblue", - "image4": "Mithril ore.png", - "label5": "Gold ore", - "low5": "-40", - "high5": "126", - "req5": "40", - "color5": "goldenrod", - "image5": "Gold ore.png", - "label6": "Coal", - "low6": "226", - "high6": "325", - "req6": "30", - "color6": "black", - "image6": "Coal.png" - } - ] - }, - { - "title": "Mud pie", - "names": [ - "items.mud_pie" - ], - "entries": [ - { - "label": "Mud pie cooking chance", - "label1": "Range", - "low1": "58", - "high1": "372", - "req1": "29", - "color1": "saddlebrown", - "image1": "Mud pie.png", - "label2": "Hosidius +5%", - "low2": "70", - "high2": "384", - "req2": "29", - "color2": "red", - "image2": "Mud pie.png", - "label3": "Hosidius +10%", - "low3": "83", - "high3": "397", - "req3": "79", - "color3": "blue", - "image3": "Mud pie.png" - } - ] - }, - { - "title": "Mushroom pie", - "names": [ - "items.mushroom_pie", - "items.half_mushroom_pie" - ], - "entries": [ - { - "label": "Mushroom pie cooking chance", - "showbefore": "yes", - "label1": "Range", - "low1": "17", - "high1": "285", - "req1": "60", - "color1": "gray", - "image1": "Mushroom pie.png", - "label2": "Lumbridge range", - "low2": "140", - "high2": "450", - "req2": "60", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "29", - "high3": "297", - "req3": "60", - "color3": "red", - "image3": "Mushroom pie.png", - "label4": "Hosidius +10%", - "low4": "42", - "high4": "310", - "req4": "79", - "color4": "blue", - "image4": "Mushroom pie.png" - } - ] - }, - { - "title": "Nature impling", - "names": [ - "npcs.ii_impling_type_7", - "npcs.ii_impling_type_7_maze" - ], - "entries": [ - { - "label": "Nature impling catch chance", - "showbefore": "no", - "label1": "Butterfly net", - "low1": "20", - "high1": "200", - "req1": "58", - "color1": "saddlebrown", - "image1": "Butterfly net.png", - "label2": "Barehanded or magic butterfly net", - "low2": "40", - "high2": "220", - "req2": "58", - "color2": "green", - "image2": "Magic butterfly net.png" - } - ] - }, - { - "title": "Nellas", - "names": [ - "npcs.prif_citizen_nellas" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Nerdanel", - "names": [ - "npcs.prif_citizen_nerdanel" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Net trap", - "names": [ - "objects.hunting_sapling_net_set_orange", - "objects.hunting_sapling_net_set_black", - "objects.hunting_sapling_net_set_swamp", - "objects.hunting_sapling_net_set_mountain", - "objects.hunting_sapling_catching_green", - "objects.hunting_sapling_full_green", - "objects.hunting_sapling_full_orange", - "objects.hunting_sapling_catching_orange", - "objects.hunting_sapling_catching_red", - "objects.hunting_sapling_full_red", - "objects.hunting_sapling_catching_black", - "objects.hunting_sapling_full_black", - "objects.hunting_sapling_catching_mountain", - "objects.hunting_sapling_full_mountain", - "objects.hunting_sapling_failing_swamp", - "objects.hunting_sapling_failed_swamp", - "objects.hunting_sapling_failed_orange", - "objects.hunting_sapling_failing_orange", - "objects.hunting_sapling_failing_red", - "objects.hunting_sapling_failed_red", - "objects.hunting_sapling_failing_black", - "objects.hunting_sapling_failed_black", - "objects.hunting_sapling_failing_mountain", - "objects.hunting_sapling_failed_mountain" - ], - "entries": [ - { - "label": "Salamander catch chance", - "showbefore": "no", - "label1": "Swamp lizard", - "low1": "52", - "high1": "360", - "req1": "29", - "color1": "#1b441a", - "image1": "Swamp lizard.png", - "label2": "Orange salamander", - "low2": "16", - "high2": "288", - "req2": "47", - "color2": "#976b1e", - "image2": "Orange salamander.png", - "label3": "Red salamander", - "low3": "0", - "high3": "240", - "req3": "59", - "color3": "#6c2413", - "image3": "Red salamander.png", - "label4": "Black salamander", - "low4": "0", - "high4": "212", - "req4": "67", - "color4": "#151111", - "image4": "Black salamander.png", - "label5": "Tecu salamander", - "low5": "1", - "high5": "212", - "req5": "79", - "color5": "#5a9e95", - "image5": "Tecu salamander.png" - } - ] - }, - { - "title": "Nettle tea", - "names": [ - "items.bowl_nettletea" - ], - "entries": [ - { - "label": "Nettle tea cooking chance", - "xlabel": "Cooking level", - "label1": "Fire or Range", - "low1": "78", - "high1": "412", - "req1": "20", - "color1": "gray", - "image1": "Nettle tea.png", - "label2": "Hosidius +5%", - "low2": "90", - "high2": "424", - "req2": "20", - "color2": "red", - "image2": "Nettle tea.png", - "label3": "Hosidius +10%", - "low3": "103", - "high3": "437", - "req3": "79", - "color3": "blue", - "image3": "Nettle tea.png" - } - ] - }, - { - "title": "Nimloth", - "names": [ - "npcs.prif_citizen_nimloth" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Ninja impling", - "names": [ - "npcs.ii_impling_type_9", - "npcs.ii_impling_type_9_maze" - ], - "entries": [ - { - "label": "Ninja impling catch chance", - "showbefore": "no", - "label1": "Butterfly net", - "low1": "10", - "high1": "151", - "req1": "74", - "color1": "saddlebrown", - "image1": "Butterfly net.png", - "label2": "Barehanded or magic butterfly net", - "low2": "30", - "high2": "171", - "req2": "74", - "color2": "green", - "image2": "Magic butterfly net.png" - } - ] - }, - { - "title": "Oak birdhouse", - "names": [ - "objects.birdhouse_oak_built", - "objects.birdhouse_oak_full", - "objects.birdhouse_oak_bird" - ], - "entries": [ - { - "label": "Seed nest chance", - "xlabel": "Hunter level", - "label1": "Seed nest", - "low1": "0", - "high1": "200", - "req1": "14", - "color1": "grey", - "image1": "Bird nest (seeds).png" - }, - { - "label": "Other nests (10 rolls per birdhouse)", - "xlabel": "Hunter level", - "birdhouse": "yes", - "label1": "Oak", - "high1": "125", - "req1": "14", - "color1": "#ff0000", - "image1": "Oak bird house.png" - } - ] - }, - { - "title": "Oak tree", - "names": [ - "objects.oaktree", - "objects.tree_oak_default01" - ], - "entries": [ - { - "label": "Oak tree cut chance", - "xlabel": "Woodcutting level", - "label1": "Bronze", - "low1": "32", - "high1": "100", - "req1": "15", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "48", - "high2": "150", - "req2": "15", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "64", - "high3": "200", - "req3": "15", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "72", - "high4": "225", - "req4": "15", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "80", - "high5": "250", - "req5": "21", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "96", - "high6": "300", - "req6": "31", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "112", - "high7": "350", - "req7": "41", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "120", - "high8": "375", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png" - } - ] - }, - { - "title": "Oak tree (The Node)", - "names": [ - "objects.gim_oaktree" - ], - "entries": [ - { - "label": "Oak tree cut chance", - "xlabel": "Woodcutting level", - "label1": "Bronze", - "low1": "32", - "high1": "100", - "req1": "15", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "48", - "high2": "150", - "req2": "15", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "64", - "high3": "200", - "req3": "15", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "72", - "high4": "225", - "req4": "15", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "80", - "high5": "250", - "req5": "21", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "96", - "high6": "300", - "req6": "31", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "112", - "high7": "350", - "req7": "41", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "120", - "high8": "375", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png" - } - ] - }, - { - "title": "Ogre Coffin (Zogre Flesh Eaters)", - "names": [ - "objects.zogre_coffin_special_entity", - "objects.zogre_coffin_special", - "objects.zogre_coffin_special_searched" - ], - "entries": [ - { - "label": "Ogre coffin opening chance", - "xlabel": "Strength level", - "label1": "Brute force", - "low1": "0", - "high1": "252", - "req1": "1", - "color1": "#766443", - "image1": "Strength icon.png" - } - ] - }, - { - "title": "Opal", - "names": [ - "items.opal" - ], - "entries": [ - { - "label": "Gem cutting rates", - "label1": "Opal", - "low1": "128", - "high1": "250", - "req1": "1", - "color1": "gray", - "image1": "Opal.png", - "label2": "Jade", - "low2": "100", - "high2": "245", - "req2": "13", - "color2": "green", - "image2": "Jade.png", - "label3": "Red topaz", - "low3": "90", - "high3": "240", - "req3": "16", - "color3": "pink", - "image3": "Red topaz.png" - } - ] - }, - { - "title": "Orange salamander (Hunter)", - "names": [ - "npcs.salamander_orange" - ], - "entries": [ - { - "label": "Orange salamander catch chance", - "showbefore": "no", - "label1": "Orange salamander", - "low1": "16", - "high1": "288", - "req1": "47", - "color1": "#976b1e", - "image1": "Orange salamander.png" - } - ] - }, - { - "title": "Oropher", - "names": [ - "npcs.prif_citizen_oropher" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Orophin", - "names": [ - "npcs.prif_citizen_orophin" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Paddlefish", - "names": [ - "items.gauntlet_food" - ], - "entries": [ - { - "label": "Paddlefish cooking chance", - "label1": "Range", - "low1": "155", - "high1": "368", - "req1": "30", - "color1": "saddlebrown", - "image1": "Paddlefish.png" - } - ] - }, - { - "title": "Paladin", - "names": [ - "npcs.paladin", - "npcs.paladin_variant01", - "npcs.paladin_variant02", - "npcs.paladin_f", - "npcs.paladin_f_variant01", - "npcs.paladin_west_vis", - "npcs.paladin_west_f_vis", - "npcs.paladin2" - ], - "entries": [ - { - "label": "Paladin pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "40", - "high1": "170", - "req1": "70", - "color1": "gray", - "image1": "Thief Paladin.png", - "label2": "Gloves of silence", - "low2": "42", - "high2": "178", - "req2": "70", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "44", - "high3": "187", - "req3": "70", - "color3": "black", - "image3": "Ardougne cloak 2.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "48", - "high4": "205", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Pay-dirt", - "names": [ - "items.paydirt" - ], - "entries": [ - { - "label": "Pay-dirt mining chance", - "xlabel": "Mining level", - "showbefore": "no", - "label1": "Pay-dirt", - "low1": "60", - "high1": "105", - "req1": "30", - "color1": "brown", - "image1": "Pay-dirt.png" - }, - { - "label": "Motherlode Mine ore chance", - "xlabel": "Mining level", - "cascade": "yes", - "showbefore": "no", - "label1": "Golden nugget", - "low1": "7", - "high1": "7", - "req1": "30", - "color1": "gold", - "image1": "Golden nugget.png", - "label2": "Runite ore", - "low2": "-20", - "high2": "5", - "req2": "85", - "color2": "#6f97ad", - "image2": "Runite ore.png", - "label3": "Adamantite ore", - "low3": "-90", - "high3": "50", - "req3": "70", - "color3": "#76a86f", - "image3": "Adamantite ore.png", - "label4": "Mithril ore", - "low4": "-19", - "high4": "90", - "req4": "55", - "color4": "#4d52a1", - "image4": "Mithril ore.png", - "label5": "Gold ore", - "low5": "-40", - "high5": "126", - "req5": "40", - "color5": "#9e7f4d", - "image5": "Gold ore.png", - "label6": "Coal", - "low6": "226", - "high6": "325", - "req6": "30", - "image6": "Coal.png", - "color6": "#000000" - } - ] - }, - { - "title": "Pie dish", - "names": [ - "items.piedish" - ], - "entries": [ - { - "label": "Firing pottery success rate", - "xlabel": "Crafting level", - "showbefore": "no", - "label1": "Unfired pie dish", - "low1": "180", - "high1": "800", - "req1": "1", - "color1": "#5b4309", - "image1": "Unfired pie dish.png" - } - ] - }, - { - "title": "Pike", - "names": [ - "items.pike" - ], - "entries": [ - { - "label": "Pike cooking chance", - "label1": "Fire or Range", - "low1": "78", - "high1": "412", - "req1": "20", - "color1": "gray", - "image1": "Pike.png", - "label2": "Lumbridge range", - "low2": "88", - "high2": "432", - "req2": "20", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "90", - "high3": "424", - "req3": "20", - "color3": "red", - "image3": "Pike.png", - "label4": "Hosidius +10%", - "low4": "103", - "high4": "437", - "req4": "79", - "color4": "blue", - "image4": "Pike.png" - } - ] - }, - { - "title": "Pit (Klenter's Pyramid)", - "names": [ - "objects.ics_little_pit_to", - "objects.ics_little_pit_from" - ], - "entries": [ - { - "label": "Pit", - "label1": "Success chance to cross", - "low1": "80", - "high1": "230", - "req1": "1", - "color1": "Grey", - "image1": "Agility icon.png" - } - ] - }, - { - "title": "Pitta bread", - "names": [ - "items.pitta_bread" - ], - "entries": [ - { - "label": "Pitta bread cooking chance", - "label1": "Range", - "low1": "118", - "high1": "492", - "req1": "58", - "color1": "saddlebrown", - "image1": "Pitta bread.png", - "label2": "Hosidius +5%", - "low2": "130", - "high2": "504", - "req2": "58", - "color2": "red", - "image2": "Pitta bread.png", - "label3": "Hosidius +10%", - "low3": "143", - "high3": "517", - "req3": "79", - "color3": "blue", - "image3": "Pitta bread.png" - } - ] - }, - { - "title": "Plain pizza", - "names": [ - "items.plain_pizza", - "items.half_plain_pizza" - ], - "entries": [ - { - "label": "Pizza cooking chance", - "label1": "Range", - "low1": "48", - "high1": "352", - "req1": "35", - "color1": "gray", - "image1": "Plain_pizza.png", - "label2": "Hosidius +5%", - "low2": "60", - "high2": "364", - "req2": "35", - "color2": "red", - "image2": "Plain_pizza.png", - "label3": "Hosidius +10%", - "low3": "73", - "high3": "377", - "req3": "79", - "color3": "blue", - "image3": "Plain_pizza.png" - } - ] - }, - { - "title": "Poison karambwan", - "names": [ - "items.tbwt_poorly_cooked_karambwan" - ], - "entries": [ - { - "label": "Poison karambwan cooking chance", - "label1": "Fire or Range", - "low1": "70", - "high1": "255", - "req1": "1", - "color1": "gray", - "image1": "Poison_karambwan.png", - "label2": "Hosidius +5%", - "low2": "82", - "high2": "267", - "req2": "1", - "color2": "red", - "image2": "Poison_karambwan.png", - "label3": "Hosidius +10%", - "low3": "95", - "high3": "280", - "req3": "79", - "color3": "blue", - "image3": "Poison_karambwan.png" - } - ] - }, - { - "title": "Polar kebbit", - "names": [], - "entries": [ - { - "label": "Polar kebbit catch chance", - "label1": "Polar kebbit", - "low1": "238", - "high1": "1080", - "req1": "1", - "color1": "#a5a8b1", - "image1": "Polar kebbit icon.png" - } - ] - }, - { - "title": "Pot", - "names": [ - "items.pot_empty" - ], - "entries": [ - { - "label": "Firing pottery success rate", - "xlabel": "Crafting level", - "showbefore": "no", - "label1": "Unfired pot", - "low1": "180", - "high1": "800", - "req1": "1", - "color1": "#84630d", - "image1": "Unfired pot.png" - } - ] - }, - { - "title": "Pot lid", - "names": [ - "items.potlid" - ], - "entries": [ - { - "label": "Firing pottery success rate", - "xlabel": "Crafting level", - "showbefore": "no", - "label1": "Unfired pot lid", - "low1": "180", - "high1": "800", - "req1": "1", - "color1": "#7b6c52", - "image1": "Unfired pot lid.png" - } - ] - }, - { - "title": "Prototype dart", - "names": [ - "items.thprotodart" - ], - "entries": [ - { - "label": "Prototype dart creation chance", - "label1": "Prototype dart", - "low1": "61", - "high1": "254", - "req1": "10", - "image1": "Prototype_dart.png" - } - ] - }, - { - "title": "Prototype dart tip", - "names": [ - "items.thprotodarttip" - ], - "entries": [ - { - "label": "Prototype dart tip creation chance", - "label1": "Prototype dart tip", - "low1": "61", - "high1": "245", - "req1": "20", - "image1": "Prototype_dart_tip.png" - } - ] - }, - { - "title": "Pyre fox", - "names": [ - "npcs.varlamore_hunterfox01" - ], - "entries": [ - { - "label": "Pyre fox catch chance", - "showbefore": "no", - "label1": "Pyre fox", - "low1": "-475", - "high1": "750", - "req1": "57", - "color1": "Orange", - "image1": "Pyre fox icon.png" - } - ] - }, - { - "title": "Railing", - "names": [ - "items.mcannonrailing1_obj" - ], - "entries": [ - { - "label": "Chance of successfully repairing a railing", - "xlabel": "Crafting level", - "label1": "Railing", - "low1": "60", - "high1": "150", - "color1": "grey", - "image1": "Railing.png" - } - ] - }, - { - "title": "Rainbow fish", - "names": [ - "items.hunting_fish_special" - ], - "entries": [ - { - "label": "Rainbow fish cooking chance", - "label1": "Fire or Range", - "low1": "56", - "high1": "370", - "req1": "35", - "color1": "gray", - "image1": "Rainbow fish.png", - "label2": "Hosidius +5%", - "low2": "68", - "high2": "382", - "req2": "35", - "color2": "red", - "image2": "Rainbow fish.png", - "label3": "Hosidius +10%", - "low3": "81", - "high3": "395", - "req3": "79", - "color3": "blue", - "image3": "Rainbow fish.png" - } - ] - }, - { - "title": "Raw anchovies", - "names": [ - "items.raw_anchovies" - ], - "entries": [ - { - "label": "Shrimp + anchovies fishing chance", - "cascade": "yes", - "label1": "Raw anchovies", - "low1": "24", - "high1": "128", - "req1": "15", - "color1": "#6e6e8b", - "image1": "Raw anchovies.png", - "label2": "Raw shrimps", - "low2": "48", - "high2": "256", - "req2": "1", - "color2": "#b18065", - "image2": "Raw shrimps.png" - } - ] - }, - { - "title": "Raw anglerfish", - "names": [ - "items.raw_anglerfish" - ], - "entries": [ - { - "label": "Anglerfish fishing chance", - "showbefore": "no", - "label1": "Sandworms", - "low1": "3", - "high1": "36", - "req1": "82", - "color1": "green", - "image1": "Sandworms.png", - "label2": "Diabolic worms", - "low2": "13", - "high2": "100", - "req2": "82", - "color2": "#c77f72", - "image2": "Diabolic worms.png" - } - ] - }, - { - "title": "Raw bass", - "names": [ - "items.raw_bass" - ], - "entries": [ - { - "label": "Big net fishing chance", - "showbefore": "no", - "label1": "Raw bass", - "low1": "3", - "high1": "40", - "req1": "46", - "color1": "#cb410b", - "image1": "Raw bass.png" - } - ] - }, - { - "title": "Raw cave eel", - "names": [ - "items.raw_cave_eel" - ], - "entries": [ - { - "label": "Slimy + cave eel fishing chance", - "cascade": "yes", - "showbefore": "no", - "label1": "Raw cave eel", - "low1": "10", - "high1": "80", - "req1": "38", - "color1": "#606b48", - "image1": "Raw cave eel.png", - "label2": "Raw slimy eel", - "low2": "10", - "high2": "80", - "req2": "28", - "color2": "#363c00", - "image2": "Raw slimy eel.png" - } - ] - }, - { - "title": "Raw cod", - "names": [ - "items.raw_cod" - ], - "entries": [ - { - "label": "Big net fishing chance", - "showbefore": "no", - "label1": "Raw cod", - "low1": "4", - "high1": "55", - "req1": "23", - "color1": "blue", - "image1": "Raw cod.png" - } - ] - }, - { - "title": "Raw dark crab", - "names": [ - "items.raw_dark_crab" - ], - "entries": [ - { - "label": "Dark crab fishing chance", - "xlabel": "Fishing level", - "showbefore": "no", - "label1": "Normal", - "low1": "3", - "high1": "40", - "req1": "85", - "color1": "gray", - "image1": "Raw dark crab.png", - "label2": "Elite Wilderness Diary", - "low2": "13", - "high2": "55", - "bonuslow2": "3", - "bonushigh2": "40", - "req2": "85", - "color2": "Purple", - "image2": "Wilderness sword 4.png" - } - ] - }, - { - "title": "Raw harpoonfish", - "names": [ - "items.tempoross_raw_harpoonfish" - ], - "entries": [ - { - "label": "Harpoonfish fishing chance", - "showbefore": "no", - "label1": "Harpoon", - "low1": "170", - "high1": "255", - "req1": "35", - "color1": "saddlebrown", - "image1": "Harpoon.png", - "label2": "Dragon harpoon", - "low2": "178", - "high2": "267", - "req2": "61", - "color2": "firebrick", - "image2": "Dragon harpoon.png", - "label3": "Crystal harpoon", - "low3": "187", - "high3": "280", - "req3": "71", - "color3": "cyan", - "image3": "Crystal harpoon.png" - } - ] - }, - { - "title": "Raw herring", - "names": [ - "items.raw_herring" - ], - "entries": [ - { - "label": "Herring + sardine fishing chance", - "cascade": "yes", - "showbefore": "no", - "label1": "Herring", - "low1": "24", - "high1": "128", - "req1": "10", - "color1": "grey", - "image1": "Raw herring.png", - "label2": "Sardine", - "low2": "32", - "high2": "192", - "req2": "5", - "color2": "green", - "image2": "Raw sardine.png" - } - ] - }, - { - "title": "Raw karambwan", - "names": [ - "items.tbwt_raw_karambwan" - ], - "entries": [ - { - "label": "Karambwan fishing chance", - "showbefore": "no", - "label1": "Raw karambwan", - "low1": "5", - "high1": "160", - "req1": "65", - "color1": "green", - "image1": "Raw karambwan.png" - } - ] - }, - { - "title": "Raw karambwanji", - "names": [ - "items.tbwt_raw_karambwanji" - ], - "entries": [ - { - "label": "Karambwanji + shrimp fishing chance", - "cascade": "yes", - "label1": "Raw karambwanji", - "low1": "100", - "high1": "250", - "req1": "5", - "color1": "#145056", - "image1": "Raw karambwanji.png", - "label2": "Raw shrimps", - "low2": "48", - "high2": "256", - "req2": "1", - "color2": "#b18065", - "image2": "Raw shrimps.png" - } - ] - }, - { - "title": "Raw lava eel", - "names": [ - "items.raw_lava_eel" - ], - "entries": [ - { - "label": "Lava eel fishing chance", - "showbefore": "no", - "label1": "Oily fishing rod", - "low1": "16", - "high1": "96", - "req1": "53", - "color1": "#bc6217", - "image1": "Oily fishing rod.png" - } - ] - }, - { - "title": "Raw lobster", - "names": [ - "items.raw_lobster" - ], - "entries": [ - { - "label": "Lobster fishing chance", - "showbefore": "no", - "label1": "Raw lobster", - "low1": "6", - "high1": "95", - "req1": "40", - "color1": "#854c22", - "image1": "Raw lobster.png" - } - ] - }, - { - "title": "Raw mackerel", - "names": [ - "items.raw_mackerel" - ], - "entries": [ - { - "label": "Big net fishing chance", - "showbefore": "no", - "label1": "Raw mackerel", - "low1": "5", - "high1": "65", - "bonuslow1": "10", - "bonushigh1": "10", - "req1": "16", - "color1": "#efcc00", - "image1": "Raw mackerel.png" - } - ] - }, - { - "title": "Raw monkfish", - "names": [ - "items.raw_monkfish" - ], - "entries": [ - { - "label": "Monkfish fishing chance", - "showbefore": "no", - "label1": "Raw monkfish", - "low1": "48", - "high1": "90", - "req1": "62", - "color1": "saddlebrown", - "image1": "Raw monkfish.png" - } - ] - }, - { - "title": "Raw pike", - "names": [ - "items.raw_pike" - ], - "entries": [ - { - "label": "Pike fishing chance", - "showbefore": "no", - "label1": "Raw pike", - "low1": "16", - "high1": "96", - "req1": "25", - "color1": "#6e8b6e", - "image1": "Raw pike.png" - } - ] - }, - { - "title": "Raw rainbow fish", - "names": [ - "items.hunting_raw_fish_special" - ], - "entries": [ - { - "label": "Rainbow fish fishing chance", - "showbefore": "no", - "label1": "Raw rainbow fish", - "low1": "8", - "high1": "64", - "req1": "38", - "color1": "#7778d1", - "image1": "Raw rainbow fish.png" - } - ] - }, - { - "title": "Raw salmon", - "names": [ - "items.raw_salmon" - ], - "entries": [ - { - "label": "Trout + salmon fishing chance", - "cascade": "yes", - "showbefore": "no", - "label1": "Raw salmon", - "low1": "16", - "high1": "96", - "req1": "30", - "color1": "#c77f72", - "image1": "Raw salmon.png", - "label2": "Raw trout", - "low2": "32", - "high2": "192", - "req2": "20", - "color2": "#9a908f", - "image2": "Raw trout.png" - } - ] - }, - { - "title": "Raw sardine", - "names": [ - "items.raw_sardine" - ], - "entries": [ - { - "label": "Herring + sardine fishing chance", - "cascade": "yes", - "showbefore": "no", - "label1": "Herring", - "low1": "24", - "high1": "128", - "req1": "10", - "color1": "grey", - "image1": "Raw herring.png", - "label2": "Sardine", - "low2": "32", - "high2": "192", - "req2": "5", - "color2": "green", - "image2": "Raw sardine.png" - } - ] - }, - { - "title": "Raw shark", - "names": [ - "items.raw_shark" - ], - "entries": [ - { - "label": "Shark fishing chance", - "showbefore": "no", - "label1": "Harpoon", - "low1": "3", - "high1": "40", - "req1": "76", - "color1": "#736b6b", - "image1": "Harpoon.png", - "label2": "Dragon", - "low2": "3", - "high2": "48", - "req2": "76", - "color2": "firebrick", - "image2": "Dragon harpoon.png", - "label3": "Crystal", - "low3": "4", - "high3": "54", - "req3": "76", - "color3": "cyan", - "image3": "Crystal harpoon.png" - } - ] - }, - { - "title": "Raw shrimps", - "names": [ - "items.raw_shrimp" - ], - "entries": [ - { - "label": "Shrimp + anchovies fishing chance", - "cascade": "yes", - "label1": "Raw anchovies", - "low1": "24", - "high1": "128", - "req1": "15", - "color1": "#6e6e8b", - "image1": "Raw anchovies.png", - "label2": "Raw shrimps", - "low2": "48", - "high2": "256", - "req2": "1", - "color2": "#b18065", - "image2": "Raw shrimps.png" - } - ] - }, - { - "title": "Raw slimy eel", - "names": [ - "items.mort_slimey_eel" - ], - "entries": [ - { - "label": "Slimy + cave eel fishing chance", - "cascade": "yes", - "showbefore": "no", - "label1": "Raw cave eel", - "low1": "10", - "high1": "80", - "req1": "38", - "color1": "#606b48", - "image1": "Raw cave eel.png", - "label2": "Raw slimy eel", - "low2": "10", - "high2": "80", - "req2": "28", - "color2": "brown", - "image2": "Raw slimy eel.png" - } - ] - }, - { - "title": "Raw swordfish", - "names": [ - "items.raw_swordfish" - ], - "entries": [ - { - "label": "Swordfish + tuna fishing chance", - "cascade": "yes", - "showbefore": "no", - "label1": "Swordfish", - "low1": "4", - "high1": "48", - "req1": "50", - "color1": "mediumorchid", - "image1": "Raw swordfish.png", - "label2": "Tuna", - "low2": "8", - "high2": "64", - "req2": "35", - "color2": "grey", - "image2": "Raw tuna.png" - }, - { - "label": "Swordfish + tuna fishing chance", - "cascade": "yes", - "showbefore": "no", - "label1": "Swordfish", - "low1": "4", - "high1": "57", - "req1": "50", - "color1": "mediumorchid", - "image1": "Raw swordfish.png", - "label2": "Tuna", - "low2": "9", - "high2": "76", - "req2": "35", - "color2": "grey", - "image2": "Raw tuna.png" - }, - { - "label": "Swordfish + tuna fishing chance", - "cascade": "yes", - "showbefore": "no", - "label1": "Swordfish", - "low1": "5", - "high1": "64", - "req1": "50", - "color1": "mediumorchid", - "image1": "Raw swordfish.png", - "label2": "Tuna", - "low2": "10", - "high2": "86", - "req2": "35", - "color2": "grey", - "image2": "Raw tuna.png" - } - ] - }, - { - "title": "Raw trout", - "names": [ - "items.raw_trout" - ], - "entries": [ - { - "label": "Trout + salmon fishing chance", - "xlabel": "Fishing level", - "cascade": "yes", - "showbefore": "no", - "label1": "Raw salmon", - "low1": "16", - "high1": "96", - "req1": "30", - "color1": "#c77f72", - "image1": "Raw salmon.png", - "label2": "Raw trout", - "low2": "32", - "high2": "192", - "req2": "20", - "color2": "#9a908f", - "image2": "Raw trout.png" - } - ] - }, - { - "title": "Raw tuna", - "names": [ - "items.raw_tuna" - ], - "entries": [ - { - "label": "Swordfish + tuna fishing chance", - "cascade": "yes", - "showbefore": "no", - "label1": "Swordfish", - "low1": "4", - "high1": "48", - "req1": "50", - "color1": "mediumorchid", - "image1": "Raw swordfish.png", - "label2": "Tuna", - "low2": "8", - "high2": "64", - "req2": "35", - "color2": "grey", - "image2": "Raw tuna.png" - }, - { - "label": "Swordfish + tuna fishing chance", - "cascade": "yes", - "showbefore": "no", - "label1": "Swordfish", - "low1": "4", - "high1": "57", - "req1": "50", - "color1": "mediumorchid", - "image1": "Raw swordfish.png", - "label2": "Tuna", - "low2": "9", - "high2": "76", - "req2": "35", - "color2": "grey", - "image2": "Raw tuna.png" - }, - { - "label": "Swordfish + tuna fishing chance", - "cascade": "yes", - "showbefore": "no", - "label1": "Swordfish", - "low1": "5", - "high1": "64", - "req1": "50", - "color1": "mediumorchid", - "image1": "Raw swordfish.png", - "label2": "Tuna", - "low2": "10", - "high2": "86", - "req2": "35", - "color2": "grey", - "image2": "Raw tuna.png" - } - ] - }, - { - "title": "Red salamander (Hunter)", - "names": [ - "npcs.salamander_red" - ], - "entries": [ - { - "label": "Salamander catch chance", - "showbefore": "no", - "label1": "Red salamander", - "low1": "0", - "high1": "240", - "req1": "59", - "color1": "#6c2413", - "image1": "Red salamander.png" - } - ] - }, - { - "title": "Red topaz", - "names": [ - "items.red_topaz" - ], - "entries": [ - { - "label": "Gem cutting rates", - "label1": "Opal", - "low1": "128", - "high1": "250", - "req1": "1", - "color1": "gray", - "image1": "Opal.png", - "label2": "Jade", - "low2": "100", - "high2": "245", - "req2": "13", - "color2": "green", - "image2": "Jade.png", - "label3": "Red topaz", - "low3": "90", - "high3": "240", - "req3": "16", - "color3": "red", - "image3": "Red topaz.png" - } - ] - }, - { - "title": "Redberry pie", - "names": [ - "items.redberry_pie", - "items.half_a_redberry_pie" - ], - "entries": [ - { - "label": "Redberry pie cooking chance", - "xlabel": "Cooking level", - "label1": "Range", - "low1": "98", - "high1": "452", - "req1": "10", - "color1": "gray", - "image1": "Redberry pie.png", - "label2": "Lumbridge range", - "low2": "108", - "high2": "462", - "req2": "10", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "110", - "high3": "464", - "req3": "10", - "color3": "red", - "image3": "Redberry pie.png", - "label4": "Hosidius +10%", - "low4": "123", - "high4": "477", - "req4": "79", - "color4": "blue", - "image4": "Redberry pie.png" - } - ] - }, - { - "title": "Redwood birdhouse", - "names": [ - "objects.birdhouse_redwood_built", - "objects.birdhouse_redwood_full", - "objects.birdhouse_redwood_bird" - ], - "entries": [ - { - "label": "Seed nest chance", - "xlabel": "Hunter level", - "label1": "Seed nest", - "low1": "0", - "high1": "200", - "req1": "89", - "color1": "grey", - "image1": "Bird nest (seeds).png" - }, - { - "label": "Other nests (10 rolls per birdhouse)", - "xlabel": "Hunter level", - "birdhouse": "yes", - "label1": "Redwood", - "high1": "175", - "req1": "89", - "color1": "#ff00ff", - "image1": "Redwood bird house.png" - } - ] - }, - { - "title": "Redwood tree", - "names": [ - "objects.redwoodtree_l", - "objects.redwoodtree_r", - "objects.redwoodtree_l_cut", - "objects.redwoodtree_r_cut", - "objects.redwoodtree_middle_side2", - "objects.redwoodtree_middle_side3" - ], - "entries": [ - { - "label": "Redwood tree cut chance", - "showbefore": "no", - "label1": "Bronze", - "low1": "2", - "high1": "6", - "req1": "90", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "3", - "high2": "9", - "req2": "90", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "4", - "high3": "12", - "req3": "90", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "4", - "high4": "14", - "req4": "90", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "5", - "high5": "15", - "req5": "90", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "6", - "high6": "18", - "req6": "90", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "7", - "high7": "21", - "req7": "90", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "7", - "high8": "30", - "req8": "90", - "color8": "firebrick", - "image8": "Dragon axe.png", - "label9": "Crystal", - "low9": "8", - "high9": "35", - "req9": "90", - "color9": "cyan", - "image9": "Crystal axe.png" - } - ] - }, - { - "title": "Money making guide/Cooking raw sunlight antelope", - "names": [], - "entries": [ - { - "label": "Cooked sunlight antelope cooking chance", - "showbefore": "no", - "label1": "Fire", - "low1": "8", - "high1": "254", - "req1": "62", - "color1": "orange", - "image1": "Firemaking icon.png", - "label2": "Range", - "low2": "8", - "high2": "265", - "req2": "62", - "color2": "saddlebrown", - "image2": "Cooking range icon.png", - "label3": "Hosidius +5%", - "low3": "20", - "high3": "277", - "req3": "62", - "color3": "red", - "image3": "Cooking range icon.png", - "label4": "Hosidius +10%", - "low4": "33", - "high4": "290", - "req4": "79", - "color4": "blue", - "image4": "Cooking range icon.png" - } - ] - }, - { - "title": "Resurrect Crops", - "names": [], - "entries": [ - { - "label": "Dead crop revival chance", - "xlabel": "Magic level", - "ylabel": "Success chance", - "showbefore": "no", - "label1": "Resurrect Crops", - "low1": "-106", - "high1": "192", - "req1": "78", - "color1": "#AFEF0B", - "image1": "Resurrect Crops.png" - } - ] - }, - { - "title": "Roast beast meat", - "names": [ - "items.spit_roasted_beast_meat" - ], - "entries": [ - { - "label": "Roast beast meat cooking chance", - "showbefore": "no", - "label1": "Fire", - "low1": "180", - "high1": "255", - "req1": "21", - "color1": "orange", - "image1": "Firemaking icon.png" - } - ] - }, - { - "title": "Roast bird meat", - "names": [ - "items.spit_roasted_bird_meat" - ], - "entries": [ - { - "label": "Roast bird meat cooking chance", - "label1": "Fire", - "low1": "155", - "high1": "255", - "req1": "11", - "color1": "orange", - "image1": "Firemaking icon.png" - } - ] - }, - { - "title": "Roast rabbit", - "names": [ - "items.spit_roasted_rabbit_meat" - ], - "entries": [ - { - "label": "Roast rabbit cooking chance", - "label1": "Fire", - "low1": "160", - "high1": "255", - "req1": "16", - "color1": "orange", - "image1": "Firemaking icon.png" - } - ] - }, - { - "title": "Rock (Abyss)", - "names": [ - "objects.rcu_abyssal_barrier_teeth1", - "objects.rcu_abyssal_barrier_teeth2", - "objects.rcu_abyssal_barrier_teeth3" - ], - "entries": [ - { - "label": "Rock mining chance", - "xlabel": "Mining level", - "label1": "Success", - "low1": "0", - "high1": "255", - "image1": "Black pickaxe.png", - "color1": "#692208" - } - ] - }, - { - "title": "Roe", - "names": [ - "items.brut_roe" - ], - "entries": [ - { - "label": "Roe creation chance", - "xlabel": "Cooking Level", - "showbefore": "no", - "caviar": "yes", - "label1": "Leaping salmon", - "denom1": "80", - "req1": "1", - "color1": "pink", - "image1": "Leaping salmon.png", - "label2": "Leaping trout", - "denom2": "150", - "req2": "1", - "color2": "gray", - "image2": "Leaping trout.png" - } - ] - }, - { - "title": "Rogue", - "names": [ - "npcs.rogue", - "npcs.wilderness_rogue" - ], - "entries": [ - { - "label": "Rogue pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "74", - "high1": "240", - "req1": "32", - "color1": "gray", - "image1": "Thieving icon.png", - "label2": "Gloves of silence", - "low2": "77", - "high2": "252", - "req2": "32", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "81", - "high3": "264", - "req3": "32", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "89", - "high4": "290", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Rope swing (Underground Pass, north)", - "names": [ - "objects.obstical_rockswing_withrope", - "objects.obstical_rockswing_middle", - "objects.obstical_rockswing_norope" - ], - "entries": [ - { - "label": "Rope swing success rate", - "lowlevel": "0", - "showbefore": "no", - "label1": "Rope swing", - "low1": "100", - "high1": "300", - "req1": "1", - "color1": "#352e00", - "image1": "Agility icon.png" - } - ] - }, - { - "title": "Ropeswing (Wilderness Agility Course)", - "names": [ - "objects.obstical_ropeswing2" - ], - "entries": [ - { - "label": "Ropeswing", - "label1": "Swing-on success rate", - "xlabel": "Agility level", - "low1": "200", - "high1": "250", - "req1": "1", - "color1": "#151111", - "image1": "Agility icon.png" - } - ] - }, - { - "title": "Rune axe", - "names": [ - "items.rune_axe" - ], - "entries": [ - { - "label": "Rune axe success chances", - "showbefore": "yes", - "label1": "Yew tree", - "low1": "14", - "high1": "44", - "req1": "60", - "color1": "saddlebrown", - "image1": "Yew logs.png", - "label2": "Magic tree", - "low2": "7", - "high2": "21", - "req2": "75", - "color2": "slateblue", - "image2": "Magic logs.png", - "label3": "Mahogany tree", - "low3": "29", - "high3": "88", - "req3": "50", - "color3": "peru", - "image3": "Mahogany logs.png", - "label4": "Maple tree", - "low4": "28", - "high4": "87", - "req4": "45", - "color4": "chocolate", - "image4": "Maple logs.png", - "label5": "Teak tree", - "low5": "55", - "high5": "164", - "req5": "35", - "color5": "tan", - "image5": "Teak logs.png", - "label6": "Willow tree", - "low6": "56", - "high6": "175", - "req6": "30", - "color6": "darkolivegreen", - "image6": "Willow logs.png", - "label7": "Oak tree", - "low7": "112", - "high7": "350", - "req7": "15", - "color7": "wheat", - "image7": "Oak logs.png", - "label8": "Redwood tree", - "low8": "7", - "high8": "16", - "req8": "90", - "color8": "red", - "image8": "Redwood logs.png" - } - ] - }, - { - "title": "Runite rocks", - "names": [ - "objects.runiterock2", - "objects.runiterock1", - "objects.prif_mine_runiterock1" - ], - "entries": [ - { - "label": "Runite rocks mining chance", - "showbefore": "no", - "label1": "Runite rocks", - "low1": "1", - "high1": "18", - "req1": "85", - "color1": "steelblue", - "image1": "Runite ore.png" - } - ] - }, - { - "title": "Rusty sword", - "names": [ - "items.digsitesword" - ], - "entries": [ - { - "label": "Rusty sword repair chance", - "xlabel": "Smithing level", - "label1": "Rusty sword", - "low1": "100", - "high1": "239", - "color1": "chocolate", - "image1": "Rusty sword.png" - } - ] - }, - { - "title": "Sack (Tombs of Amascut)", - "names": [ - "objects.toa_sack_full" - ], - "entries": [ - { - "label": "Sack success chance", - "xlabel": "Thieving level", - "label1": "Normal", - "": "", - "low1": "1", - "high1": "10", - "req1": "1", - "color1": "tan", - "image1": "Grain (Tombs of Amascut).png" - } - ] - }, - { - "title": "Sacred eel", - "names": [ - "items.snakeboss_eel" - ], - "entries": [ - { - "label": "Sacred eel catch chance", - "showbefore": "no", - "label1": "Sacred eel", - "low1": "0", - "high1": "60", - "req1": "87", - "color1": "darkseagreen", - "image1": "Sacred eel.png" - } - ] - }, - { - "title": "Saeros", - "names": [ - "npcs.prif_citizen_saeros" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Salgant", - "names": [ - "npcs.prif_citizen_salgant" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Salmon", - "names": [ - "items.salmon" - ], - "entries": [ - { - "label": "Salmon cooking chance", - "label1": "Fire or Range", - "low1": "68", - "high1": "392", - "req1": "25", - "color1": "gray", - "image1": "Salmon.png", - "label2": "Lumbridge range", - "low2": "78", - "high2": "402", - "req2": "25", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "80", - "high3": "404", - "req3": "25", - "color3": "red", - "image3": "Salmon.png", - "label4": "Hosidius +10%", - "low4": "93", - "high4": "417", - "req4": "79", - "color4": "blue", - "image4": "Salmon.png" - } - ] - }, - { - "title": "Salvager", - "names": [ - "npcs.varlamore_salvager_m_1", - "npcs.varlamore_salvager_m_2", - "npcs.varlamore_salvager_m_3", - "npcs.varlamore_salvager_m_4", - "npcs.varlamore_salvager_f_1", - "npcs.varlamore_salvager_f_2", - "npcs.varlamore_salvager_f_3" - ], - "entries": [ - { - "label": "Citizen pickpocket chance", - "label1": "Normal", - "low1": "180", - "high1": "240", - "req1": "1", - "color1": "gray", - "image1": "Thieving icon.png", - "label2": "Gloves of silence", - "low2": "189", - "high2": "252", - "req2": "1", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "198", - "high3": "264", - "req3": "1", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "217", - "high4": "290", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Sandstone", - "names": [ - "items.enakh_sandstone_tiny", - "items.enakh_sandstone_small", - "items.enakh_sandstone_medium", - "items.enakh_sandstone_large" - ], - "entries": [ - { - "label": "Sandstone mining chance", - "cascade": "yes", - "showbefore": "no", - "label1": "10kg", - "low1": "4", - "high1": "50", - "req1": "35", - "color1": "grey", - "image1": "Sandstone_(10kg).png", - "label2": "5kg", - "low2": "8", - "high2": "75", - "req2": "35", - "color2": "green", - "image2": "Sandstone_(5kg).png", - "label3": "2kg", - "low3": "16", - "high3": "100", - "req3": "35", - "color3": "blue", - "image3": "Sandstone_(2kg).png", - "label4": "1kg", - "low4": "25", - "high4": "200", - "req4": "35", - "color4": "red", - "image4": "Sandstone_(1kg).png" - } - ] - }, - { - "title": "Sandstone rocks", - "names": [ - "objects.enakh_sandstone_rocks" - ], - "entries": [ - { - "label": "Sandstone mining chance", - "cascade": "yes", - "showbefore": "no", - "label1": "10kg", - "low1": "4", - "high1": "50", - "req1": "35", - "color1": "grey", - "image1": "Sandstone_(10kg).png", - "label2": "5kg", - "low2": "8", - "high2": "75", - "req2": "35", - "color2": "green", - "image2": "Sandstone_(5kg).png", - "label3": "2kg", - "low3": "16", - "high3": "100", - "req3": "35", - "color3": "blue", - "image3": "Sandstone_(2kg).png", - "label4": "1kg", - "low4": "25", - "high4": "200", - "req4": "35", - "color4": "red", - "image4": "Sandstone_(1kg).png" - } - ] - }, - { - "title": "Sandworm castings", - "names": [ - "objects.piscarilius_grub_castings" - ], - "entries": [ - { - "label": "Digging up sandworm castings", - "showbefore": "no", - "label1": "Bucket of sandworms", - "low1": "148", - "high1": "178", - "req1": "15", - "color1": "#b66440", - "image1": "Bucket of sandworms.png", - "label2": "Bucket of sand", - "low2": "107", - "high2": "77", - "req2": "15", - "color2": "#948354", - "image2": "Bucket of sand.png" - } - ] - }, - { - "title": "Sardine", - "names": [ - "items.sardine" - ], - "entries": [ - { - "label": "Sardine cooking chance", - "label1": "Fire or Range", - "low1": "118", - "high1": "492", - "req1": "1", - "color1": "gray", - "image1": "Sardine.png", - "label2": "Lumbridge range", - "low2": "128", - "high2": "512", - "req2": "1", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "130", - "high3": "504", - "req3": "1", - "color3": "red", - "image3": "Sardine.png", - "label4": "Hosidius +10%", - "low4": "143", - "high4": "517", - "req4": "79", - "color4": "blue", - "image4": "Sardine.png" - } - ] - }, - { - "title": "Scimitar Stall", - "names": [ - "objects.mm_stall_scimitar" - ], - "entries": [ - { - "label": "Scimitar Stall thieving chance", - "showbefore": "no", - "label1": "Scimitar Stall", - "low1": "20", - "high1": "180", - "req1": "65", - "color1": "green", - "image1": "Adamant scimitar.png" - } - ] - }, - { - "title": "Scrambled egg", - "names": [ - "items.bowl_egg_scrambled" - ], - "entries": [ - { - "label": "Scrambled egg cooking chance", - "label1": "Range", - "low1": "90", - "high1": "438", - "req1": "13", - "color1": "gray", - "image1": "Scrambled egg.png", - "label2": "Hosidius +5%", - "low2": "102", - "high2": "450", - "req2": "13", - "color2": "red", - "image2": "Scrambled egg.png", - "label3": "Hosidius +10%", - "low3": "115", - "high3": "463", - "req3": "79", - "color3": "blue", - "image3": "Scrambled egg.png" - } - ] - }, - { - "title": "Sea turtle", - "names": [ - "items.seaturtle" - ], - "entries": [ - { - "label": "Sea turtle cooking chance", - "showbefore": "no", - "label1": "Fire", - "low1": "1", - "high1": "202", - "req1": "82", - "color1": "orange", - "image1": "Firemaking icon.png", - "label2": "Range", - "low2": "1", - "high2": "222", - "req2": "82", - "color2": "saddlebrown", - "image2": "Cooking range icon.png", - "label3": "Hosidius +5%", - "low3": "13", - "high3": "234", - "req3": "82", - "color3": "red", - "image3": "Cooking range icon.png", - "label4": "Hosidius +10%", - "low4": "26", - "high4": "247", - "req4": "82", - "color4": "blue", - "image4": "Cooking range icon.png" - } - ] - }, - { - "title": "Secure chest", - "names": [ - "objects.fd_bandit_shutchest" - ], - "entries": [ - { - "label": "Secure chest success chance", - "showbefore": "no", - "label1": "Each lock", - "low1": "52", - "high1": "128", - "req1": "53", - "color1": "gray", - "image1": "Lockpick.png", - "label2": "Overall success", - "low2": "52", - "high2": "128", - "req2": "53", - "color2": "goldenrod", - "image2": "Gilded cross.png", - "exponent2": "3" - } - ] - }, - { - "title": "Servery cooked meat", - "names": [ - "items.hosidius_servery_cooked_meat" - ], - "entries": [ - { - "label": "Servery cooked meat cooking chance", - "label1": "Clay oven", - "low1": "128", - "high1": "512", - "req1": "1", - "color1": "saddlebrown", - "image1": "Cooking range icon.png" - } - ] - }, - { - "title": "Servery meat pie", - "names": [ - "items.hosidius_servery_meat_pie" - ], - "entries": [ - { - "label": "Servery meat pie cooking chance", - "label1": "Clay oven", - "low1": "78", - "high1": "412", - "req1": "20", - "color1": "saddlebrown", - "image1": "Cooking range icon.png" - } - ] - }, - { - "title": "Servery plain pizza", - "names": [ - "items.hosidius_servery_plain_pizza" - ], - "entries": [ - { - "label": "Servery plain pizza cooking chance", - "label1": "Clay oven", - "low1": "48", - "high1": "352", - "req1": "0", - "color1": "saddlebrown", - "image1": "Cooking range icon.png" - } - ] - }, - { - "title": "Servery stew", - "names": [ - "items.hosidius_servery_stew" - ], - "entries": [ - { - "label": "Servery stew cooking chance", - "label1": "Clay oven", - "low1": "68", - "high1": "392", - "req1": "25", - "color1": "saddlebrown", - "image1": "Cooking range icon.png" - } - ] - }, - { - "title": "Shark", - "names": [ - "items.shark" - ], - "entries": [ - { - "label": "Shark cooking chance", - "showbefore": "no", - "label1": "Fire", - "low1": "1", - "high1": "202", - "req1": "80", - "color1": "orange", - "image1": "Firemaking icon.png", - "label2": "Range", - "low2": "1", - "high2": "232", - "req2": "80", - "color2": "saddlebrown", - "image2": "Cooking range icon.png", - "label3": "Gauntlets", - "low3": "15", - "high3": "270", - "req3": "80", - "color3": "grey", - "image3": "Cooking gauntlets.png", - "label4": "Hosidius +5%", - "low4": "13", - "high4": "244", - "req4": "80", - "color4": "red", - "image4": "Cooking range icon.png", - "label5": "Hosidius +10%", - "low5": "26", - "high5": "257", - "req5": "80", - "color5": "blue", - "image5": "Cooking range icon.png", - "label6": "Hosidius +5%, gauntlets", - "low6": "27", - "high6": "282", - "req6": "80", - "color6": "#ffcccb", - "image6": "Cooking gauntlets.png", - "label7": "Hosidius +10%, gauntlets", - "low7": "40", - "high7": "295", - "req7": "80", - "color7": "#ccccff", - "image7": "Cooking gauntlets.png" - } - ] - }, - { - "title": "Shooting Stars", - "names": [], - "entries": [ - { - "color1": "goldenrod", - "high1": "117", - "image1": "Stardust_175.png", - "label": "Stardust mining chance", - "label1": "Stardust", - "low1": "73", - "req1": "10", - "showbefore": "no" - } - ] - }, - { - "title": "Shrimps", - "names": [ - "items.shrimp" - ], - "entries": [ - { - "label": "Shrimps cooking chance", - "xlabel": "Cooking level", - "label1": "Fire or Range", - "low1": "128", - "high1": "512", - "req1": "1", - "color1": "gray", - "image1": "Shrimps.png", - "label2": "Lumbridge range", - "low2": "138", - "high2": "532", - "req2": "1", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "140", - "high3": "524", - "req3": "1", - "color3": "red", - "image3": "Shrimps.png", - "label4": "Hosidius +10%", - "low4": "153", - "high4": "537", - "req4": "84", - "color4": "blue", - "image4": "Shrimps.png" - } - ] - }, - { - "title": "Silver rocks", - "names": [ - "objects.silverrock2", - "objects.silverrock1", - "objects.prif_mine_silverrock1" - ], - "entries": [ - { - "label": "Silver rocks mining chance", - "showbefore": "no", - "label1": "Silver rocks", - "low1": "25", - "high1": "200", - "req1": "20", - "color1": "silver", - "image1": "Silver ore.png" - } - ] - }, - { - "title": "Sinew", - "names": [ - "items.xbows_sinew" - ], - "entries": [ - { - "label": "Sinew cooking chance", - "label1": "Range", - "low1": "128", - "high1": "512", - "req1": "1", - "color1": "gray", - "image1": "Sinew.png", - "label2": "Hosidius +5%", - "low2": "140", - "high2": "524", - "req2": "1", - "color2": "red", - "image2": "Sinew.png", - "label3": "Hosidius +10%", - "low3": "153", - "high3": "537", - "req3": "79", - "color3": "blue", - "image3": "Sinew.png" - } - ] - }, - { - "title": "Sithik portrait", - "names": [ - "items.zogre_sithik_portrait_good", - "items.zogre_sithik_portrait_bad" - ], - "entries": [ - { - "label": "Good Sithik portrait chance", - "xlabel": "Crafting level", - "ylabel": "Success rate", - "label1": "''Sithik Ints'', ca. 169. Charcoal on papyrus, 26 × 29 px.", - "low1": "1", - "high1": "255", - "req1": "1", - "color1": "#372920", - "image1": "Sithik portrait.png" - } - ] - }, - { - "title": "Skilling success rate", - "names": [], - "entries": [ - { - "label": "Monkfish fishing chance", - "showbefore": "no", - "label1": "Raw monkfish", - "low1": "48", - "high1": "90", - "req1": "62", - "color1": "saddlebrown", - "image1": "Raw monkfish.png" - } - ] - }, - { - "title": "Smashed table", - "names": [ - "objects.zqtableraft" - ], - "entries": [ - { - "label": "Crafting the smashed table success chance", - "xlabel": "Crafting level", - "ylabel": "Success rate", - "label1": "Making the raft or saving the wood", - "low1": "125", - "high1": "250", - "req1": "1", - "color1": "#493411", - "image1": "Wooden table (small, Mahogany Homes) icon.png" - } - ] - }, - { - "title": "Snake weed", - "names": [ - "items.snake_weed" - ], - "entries": [ - { - "label": "Snake weed", - "label1": "Collecting success rate", - "xlabel": "Herblore level", - "low1": "10", - "high1": "220", - "showbefore": "no", - "color1": "#00800", - "image1": "Herblore icon.png" - } - ] - }, - { - "title": "Snowball", - "names": [ - "items.gublinch_snowball" - ], - "entries": [ - { - "label": "Snowball hit chance", - "xlabel": "Ranged level", - "ylabel": "Success chance", - "showbefore": "no", - "label1": "Pelt", - "low1": "150", - "high1": "300", - "req1": "1", - "color1": "#5aa5cd", - "image1": "Snowball 1.png" - } - ] - }, - { - "title": "Soda ash", - "names": [ - "items.soda_ash" - ], - "entries": [ - { - "label": "Giant seaweed success rate", - "label1": "Fire or Range", - "low1": "0", - "high1": "500", - "req1": "1", - "color1": "gray", - "image1": "Soda ash.png", - "label2": "Hosidius +5%", - "low2": "12", - "high2": "512", - "req2": "1", - "color2": "red", - "image2": "Soda ash.png", - "label3": "Hosidius +10%", - "low3": "25", - "high3": "525", - "req3": "79", - "color3": "blue", - "image3": "Soda ash.png" - } - ] - }, - { - "title": "Speartrap", - "names": [ - "objects.ntk_speartrap_inmotion" - ], - "entries": [ - { - "label": "Speartrap success rate", - "showbefore": "no", - "label1": "Speartrap", - "low1": "160", - "high1": "250", - "req1": "21", - "color1": "#897b31", - "image1": "Pharaoh's sceptre.png" - } - ] - }, - { - "title": "Spicy crunchies", - "names": [ - "items.spicy_crunchies" - ], - "entries": [ - { - "label": "Spicy crunchies cooking chance", - "label1": "Range", - "low1": "118", - "high1": "492", - "req1": "12", - "color1": "gray", - "image1": "Spicy crunchies.png", - "label2": "Hosidius +5%", - "low2": "130", - "high2": "504", - "req2": "12", - "color2": "red", - "image2": "Spicy crunchies.png", - "label3": "Hosidius +10%", - "low3": "143", - "high3": "517", - "req3": "79", - "color3": "blue", - "image3": "Spicy crunchies.png" - } - ] - }, - { - "title": "Spider on shaft", - "names": [ - "items.tbw_spider_on_shaft_cooked" - ], - "entries": [ - { - "label": "Spider on shaft cooking chance", - "label1": "Fire or Range", - "low1": "91", - "high1": "438", - "req1": "16", - "color1": "gray", - "image1": "Spider on shaft.png", - "label2": "Hosidius +5%", - "low2": "103", - "high2": "450", - "req2": "16", - "color2": "red", - "image2": "Spider on shaft.png", - "label3": "Hosidius +10%", - "low3": "116", - "high3": "463", - "req3": "79", - "color3": "blue", - "image3": "Spider on shaft.png" - } - ] - }, - { - "title": "Spider on shaft (raw)", - "names": [ - "items.tbw_spider_on_shaft_raw" - ], - "entries": [ - { - "label": "Spider on shaft cooking chance", - "label1": "Fire or Range", - "low1": "91", - "high1": "438", - "req1": "16", - "color1": "gray", - "image1": "Spider on shaft.png", - "label2": "Hosidius +5%", - "low2": "103", - "high2": "450", - "req2": "16", - "color2": "red", - "image2": "Spider on shaft.png", - "label3": "Hosidius +10%", - "low3": "116", - "high3": "463", - "req3": "79", - "color3": "blue", - "image3": "Spider on shaft.png" - } - ] - }, - { - "title": "Spider on stick", - "names": [ - "items.tbw_spider_on_stick_cooked" - ], - "entries": [ - { - "label": "Spider on stick cooking chance", - "label1": "Fire or Range", - "low1": "91", - "high1": "438", - "req1": "16", - "color1": "gray", - "image1": "Spider on stick.png", - "label2": "Hosidius +5%", - "low2": "103", - "high2": "450", - "req2": "16", - "color2": "red", - "image2": "Spider on stick.png", - "label3": "Hosidius +10%", - "low3": "116", - "high3": "463", - "req3": "79", - "color3": "blue", - "image3": "Spider on stick.png" - } - ] - }, - { - "title": "Spider on stick (raw)", - "names": [ - "items.tbw_spider_on_stick_raw" - ], - "entries": [ - { - "label": "Spider on stick cooking chance", - "label1": "Fire or Range", - "low1": "91", - "high1": "438", - "req1": "16", - "color1": "gray", - "image1": "Spider on stick.png", - "label2": "Hosidius +5%", - "low2": "103", - "high2": "450", - "req2": "16", - "color2": "red", - "image2": "Spider on stick.png", - "label3": "Hosidius +10%", - "low3": "116", - "high3": "463", - "req3": "79", - "color3": "blue", - "image3": "Spider on stick.png" - } - ] - }, - { - "title": "Spike trap", - "names": [], - "entries": [ - { - "label": "Spike trap evasion chance", - "xlabel": "Agility level", - "ylabel": "Evasion chance", - "showbefore": "no", - "label1": "Spike trap", - "low1": "30", - "high1": "210", - "req1": "1", - "color1": "#800000", - "image1": "Spike trap icon.png" - } - ] - }, - { - "title": "Spinning blades (Brimhaven Agility Arena)", - "names": [ - "objects.agilityarena_sawblades" - ], - "entries": [ - { - "label": "Spinning blades success rate", - "showbefore": "no", - "label1": "", - "low1": "153", - "high1": "255", - "req1": "40", - "color1": "#f07c15", - "image1": "Agility icon.png" - } - ] - }, - { - "title": "Spotted kebbit", - "names": [ - "npcs.huntingbeast_speedy" - ], - "entries": [ - { - "label": "Spotted kebbit catch chance", - "showbefore": "no", - "label1": "Spotted kebbit", - "low1": "26", - "high1": "310", - "req1": "43", - "color1": "#5c4a2c", - "image1": "Spotted kebbit icon.png" - } - ] - }, - { - "title": "Stepping Stone (Penguin Agility Course)", - "names": [ - "objects.peng_agility_crushcourse_stepstone01", - "objects.peng_jump_stone_clickzone_02", - "objects.peng_jump_stone_clickzone_03", - "objects.peng_jump_stone_clickzone_04", - "objects.peng_jump_stone_clickzone_05", - "objects.peng_jump_stone_clickzone_06", - "objects.peng_jump_stone_clickzone_07" - ], - "entries": [ - { - "label": "Stepping stone success rate", - "lowlevel": "0", - "showbefore": "no", - "label1": "Climb", - "low1": "155", - "high1": "308", - "req1": "30", - "color1": "#9eafc1", - "image1": "Agility icon.png" - } - ] - }, - { - "title": "Stepping stone (Lumbridge Swamp Caves)", - "names": [ - "objects.swamp_cave_steppingstone_a", - "objects.swamp_cave_steppingstone_b" - ], - "entries": [ - { - "label": "Crossing a stepping stone", - "showbefore": "no", - "xlabel": "Agility level", - "ylabel": "Cross chance", - "label1": "Successful cross chance", - "low1": "51", - "high1": "252", - "req1": "1", - "color1": "seagreen", - "image1": "Agility icon.png" - } - ] - }, - { - "title": "Stepping stone (Wilderness Agility Course)", - "names": [ - "objects.steppingstone1" - ], - "entries": [ - { - "label": "Stepping stone", - "label1": "Cross success rate", - "xlabel": "Agility level", - "low1": "180", - "high1": "250", - "req1": "1", - "color1": "#151111", - "image1": "Agility icon.png" - } - ] - }, - { - "title": "Stew", - "names": [ - "items.stew" - ], - "entries": [ - { - "label": "Stew cooking chance", - "label1": "Fire or Range", - "low1": "68", - "high1": "392", - "req1": "25", - "color1": "gray", - "image1": "Stew.png", - "label2": "Lumbridge range", - "low2": "78", - "high2": "412", - "req2": "25", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "80", - "high3": "404", - "req3": "25", - "color3": "red", - "image3": "Stew.png", - "label4": "Hosidius +10%", - "low4": "93", - "high4": "417", - "req4": "79", - "color4": "blue", - "image4": "Stew.png" - } - ] - }, - { - "title": "Sticks (trap)", - "names": [ - "objects.regicide_trap_woodspring" - ], - "entries": [ - { - "label": "Passing the sticks trap", - "xlabel": "Agility level", - "label1": "Unharmed crossing chance", - "low1": "30", - "high1": "155", - "req1": "1", - "color1": "#87775b", - "image1": "Agility icon.png" - } - ] - }, - { - "title": "Stone chest", - "names": [ - "objects.molch_temple_chest_theiving" - ], - "entries": [ - { - "label": "Stone chest thieving chance", - "showbefore": "no", - "label1": "Normal", - "low1": "-56", - "high1": "154", - "req1": "64", - "color1": "brown", - "image1": "Lizardman fang.png", - "label2": "Lockpick", - "low2": "-31", - "high2": "179", - "req2": "64", - "color2": "grey", - "image2": "Lockpick.png" - } - ] - }, - { - "title": "Strut", - "names": [ - "objects.motherlode_wheel_strut_fixed", - "objects.motherlode_wheel_strut_broken" - ], - "entries": [ - { - "label": "Strut repair chance", - "label1": "Repair", - "low1": "30", - "high1": "70", - "color1": "gray", - "image1": "Hammer.png" - } - ] - }, - { - "title": "Sulliuscep", - "names": [ - "objects.fossil_cep_grown", - "objects.fossil_cep_sprout" - ], - "entries": [ - { - "label": "Sulliuscep cut chance", - "showbefore": "no", - "label1": "Bronze", - "low1": "11", - "high1": "55", - "req1": "65", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "17", - "high2": "85", - "req2": "65", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "23", - "high3": "115", - "req3": "65", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "26", - "high4": "131", - "req4": "65", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "29", - "high5": "147", - "req5": "65", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "35", - "high6": "177", - "req6": "65", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "41", - "high7": "208", - "req7": "65", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "45", - "high8": "228", - "req8": "65", - "color8": "firebrick", - "image8": "Dragon axe.png", - "label9": "Crystal", - "low9": "48", - "high9": "240", - "req9": "71", - "color9": "cyan", - "image9": "Crystal axe.png" - } - ] - }, - { - "title": "Summer pie", - "names": [ - "items.summer_pie", - "items.half_summer_pie" - ], - "entries": [ - { - "label": "Summer pie cooking chance", - "showbefore": "no", - "label1": "Range", - "low1": "1", - "high1": "212", - "req1": "95", - "color1": "saddlebrown", - "image1": "Summer pie.png", - "label2": "Hosidius +5%", - "low2": "13", - "high2": "224", - "req2": "95", - "color2": "red", - "image2": "Summer pie.png", - "label3": "Hosidius +10%", - "low3": "26", - "high3": "237", - "req3": "95", - "color3": "blue", - "image3": "Summer pie.png" - } - ] - }, - { - "title": "Sunlight Moth", - "names": [ - "npcs.moth_sunlight" - ], - "entries": [ - { - "label": "Sunlight moth chance", - "showbefore": "no", - "label1": "Barehanded or butterfly net", - "low1": "20", - "high1": "296", - "req1": "65", - "color1": "saddlebrown", - "image1": "Butterfly net.png", - "label2": "Magic butterfly net", - "low2": "40", - "high2": "316", - "req2": "65", - "color2": "green", - "image2": "Magic butterfly net.png" - } - ] - }, - { - "title": "Swamp lizard (Hunter)", - "names": [ - "npcs.salamander_green" - ], - "entries": [ - { - "label": "Swamp lizard catch chance", - "showbefore": "no", - "label1": "Swamp lizard", - "low1": "52", - "high1": "360", - "req1": "29", - "color1": "#1b441a", - "image1": "Swamp lizard.png" - } - ] - }, - { - "title": "Swordfish", - "names": [ - "items.swordfish" - ], - "entries": [ - { - "label": "Swordfish cooking chance", - "showbefore": "no", - "label1": "Fire", - "low1": "18", - "high1": "292", - "req1": "45", - "color1": "orange", - "image1": "Firemaking icon.png", - "label2": "Range or cooking gauntlets", - "low2": "30", - "high2": "310", - "req2": "45", - "color2": "saddlebrown", - "image2": "Cooking range icon.png", - "label3": "Hosidius +5%", - "low3": "42", - "high3": "322", - "req3": "45", - "color3": "red", - "image3": [], - "label4": "Hosidius +10%", - "low4": "55", - "high4": "335", - "req4": "79", - "color4": "blue", - "image4": "Cooking range icon.png" - } - ] - }, - { - "title": "Tangle vine", - "names": [], - "entries": [ - { - "label": "Tangle vine evasion chance", - "xlabel": "Agility level", - "ylabel": "Evasion chance", - "showbefore": "no", - "label1": "Tangle vine", - "low1": "30", - "high1": "210", - "req1": "1", - "color1": "#506909", - "image1": "Tangle vine icon.png" - } - ] - }, - { - "title": "Tangled toad's legs", - "names": [ - "items.tangled_toads_legs" - ], - "entries": [ - { - "label": "Tangled toad's legs cooking chance", - "label1": "Range", - "low1": "118", - "high1": "492", - "req1": "40", - "color1": "gray", - "image1": "Tangled toad's legs.png", - "label2": "Hosidius +5%", - "low2": "130", - "high2": "504", - "req2": "40", - "color2": "red", - "image2": "Tangled toad's legs.png", - "label3": "Hosidius +10%", - "low3": "143", - "high3": "517", - "req3": "79", - "color3": "blue", - "image3": "Tangled toad's legs.png" - } - ] - }, - { - "title": "Tatie", - "names": [ - "npcs.prif_citizen_tatie" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Teak birdhouse", - "names": [ - "objects.birdhouse_teak_built", - "objects.birdhouse_teak_full", - "objects.birdhouse_teak_bird" - ], - "entries": [ - { - "label": "Seed nest chance", - "xlabel": "Hunter level", - "label1": "Seed nest", - "low1": "0", - "high1": "200", - "req1": "34", - "color1": "grey", - "image1": "Bird nest (seeds).png" - }, - { - "label": "Other nests (10 rolls per birdhouse)", - "xlabel": "Hunter level", - "birdhouse": "yes", - "label1": "Teak", - "high1": "130", - "req1": "34", - "color1": "#ffa500", - "image1": "Teak bird house.png" - } - ] - }, - { - "title": "Teak tree", - "names": [ - "objects.teaktree", - "objects.prif_teaktree", - "objects.teaktree_update" - ], - "entries": [ - { - "label": "Teak tree cut chance", - "xlabel": "Woodcutting level", - "showbefore": "no", - "label1": "Bronze", - "low1": "15", - "high1": "46", - "req1": "35", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "23", - "high2": "70", - "req2": "35", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "31", - "high3": "93", - "req3": "35", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "35", - "high4": "102", - "req4": "35", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "39", - "high5": "117", - "req5": "35", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "47", - "high6": "140", - "req6": "35", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "55", - "high7": "164", - "req7": "41", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "60", - "high8": "190", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png", - "label9": "Crystal", - "low9": "60", - "high9": "200", - "req9": "71", - "color9": "cyan", - "image9": "Crystal axe.png" - } - ] - }, - { - "title": "Tecu salamander (Hunter)", - "names": [ - "npcs.salamander_mountain" - ], - "entries": [ - { - "label": "Tecu salamander chance", - "showbefore": "no", - "label1": "Tecu salamander", - "low1": "1", - "high1": "212", - "req1": "79", - "color1": "#5a9e95", - "image1": "Tecu salamander.png" - } - ] - }, - { - "title": "Teleport trap", - "names": [], - "entries": [ - { - "label": "Teleport trap evasion chance", - "xlabel": "Agility level", - "ylabel": "Evasion chance", - "showbefore": "no", - "label1": "Teleport trap", - "low1": "30", - "high1": "210", - "req1": "1", - "color1": "#c0a816", - "image1": "Teleport trap icon.png" - } - ] - }, - { - "title": "Tendrils (Abyss)", - "names": [ - "objects.rcu_abyssal_barrier_tendrils1", - "objects.rcu_abyssal_barrier_tendrils2", - "objects.rcu_abyssal_barrier_tendrils3" - ], - "entries": [ - { - "label": "Tendrils chopping chance", - "xlabel": "Woodcutting level", - "label1": "Success chance", - "low1": "0", - "high1": "255", - "image1": "Black axe.png", - "color1": "#692208" - } - ] - }, - { - "title": "Thin snail meat", - "names": [ - "items.snail_corpse_cooked1" - ], - "entries": [ - { - "label": "Thin snail meat cooking chance", - "label1": "Fire or Range", - "low1": "93", - "high1": "444", - "req1": "12", - "color1": "gray", - "image1": "Thin snail meat.png", - "label2": "Lumbridge range", - "low2": "103", - "high2": "464", - "req2": "12", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "105", - "high3": "456", - "req3": "12", - "color3": "red", - "image3": "Thin snail meat.png", - "label4": "Hosidius +10%", - "low4": "118", - "high4": "469", - "req4": "79", - "color4": "blue", - "image4": "Thin snail meat.png" - } - ] - }, - { - "title": "Thingol", - "names": [ - "npcs.prif_citizen_thingol" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Ticket Dispenser (darts)", - "names": [ - "objects.agilityarena_poisondarts" - ], - "entries": [ - { - "label": "Dart dodge success rate", - "showbefore": "no", - "label1": "", - "low1": "131", - "high1": "255", - "req1": "40", - "color1": "#f07c15", - "image1": "Agility icon.png" - } - ] - }, - { - "title": "Toad batta", - "names": [ - "items.toad_batta" - ], - "entries": [ - { - "label": "Toad batta cooking chance", - "label1": "Range", - "low1": "118", - "high1": "492", - "req1": "26", - "color1": "gray", - "image1": "Toad batta.png", - "label2": "Hosidius +5%", - "low2": "130", - "high2": "504", - "req2": "26", - "color2": "red", - "image2": "Toad batta.png", - "label3": "Hosidius +10%", - "low3": "143", - "high3": "517", - "req3": "79", - "color3": "blue", - "image3": "Toad batta.png" - } - ] - }, - { - "title": "Toad crunchies", - "names": [ - "items.toad_crunchies" - ], - "entries": [ - { - "label": "Toad crunchies cooking chance", - "label1": "Range", - "low1": "118", - "high1": "492", - "req1": "10", - "color1": "gray", - "image1": "Toad crunchies.png", - "label2": "Hosidius +5%", - "low2": "130", - "high2": "504", - "req2": "10", - "color2": "red", - "image2": "Toad crunchies.png", - "label3": "Hosidius +10%", - "low3": "143", - "high3": "517", - "req3": "79", - "color3": "blue", - "image3": "Toad crunchies.png" - } - ] - }, - { - "title": "Tomb Door", - "names": [ - "objects.ntk_tomb_door_noanim", - "objects.ntk_tomb_door_anim" - ], - "entries": [ - { - "label": "Speartrap success rate", - "showbefore": "no", - "label1": "Normal", - "low1": "130", - "high1": "220", - "req1": "21", - "color1": "gray", - "image1": "Thieving icon.png", - "label2": "Lockpick", - "low2": "160", - "high2": "250", - "req2": "21", - "color2": "dimgray", - "image2": "Lockpick.png" - } - ] - }, - { - "title": "Tourist", - "names": [ - "npcs.varlamore_tourist_m_1", - "npcs.varlamore_tourist_m_2", - "npcs.varlamore_tourist_m_3", - "npcs.varlamore_tourist_f_1", - "npcs.varlamore_tourist_f_2", - "npcs.varlamore_tourist_f_3" - ], - "entries": [ - { - "label": "Tourist pickpocket chance", - "label1": "Normal", - "low1": "180", - "high1": "240", - "req1": "1", - "color1": "gray", - "image1": "Thief Man.png", - "label2": "Gloves of silence", - "low2": "189", - "high2": "252", - "req2": "1", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "198", - "high3": "264", - "req3": "1", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "217", - "high4": "290", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Tree", - "names": [ - "objects.tree", - "objects.tree2" - ], - "entries": [ - { - "label": "Normal tree cut chance", - "xlabel": "Woodcutting level", - "label1": "Bronze", - "low1": "64", - "high1": "200", - "req1": "1", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "96", - "high2": "300", - "req2": "1", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "128", - "high3": "400", - "req3": "6", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "144", - "high4": "450", - "req4": "11", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "160", - "high5": "500", - "req5": "21", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "192", - "high6": "600", - "req6": "31", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "224", - "high7": "700", - "req7": "41", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "240", - "high8": "750", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png", - "label9": "Crystal", - "low9": "250", - "high9": "800", - "req9": "71", - "color9": "cyan", - "image9": "Crystal axe.png" - } - ] - }, - { - "title": "Tree (Great Kourend)", - "names": [ - "objects.tree3" - ], - "entries": [ - { - "label": "Normal tree cut chance", - "xlabel": "Woodcutting level", - "label1": "Bronze", - "low1": "64", - "high1": "200", - "req1": "1", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "96", - "high2": "300", - "req2": "1", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "128", - "high3": "400", - "req3": "6", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "144", - "high4": "450", - "req4": "11", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "160", - "high5": "500", - "req5": "21", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "192", - "high6": "600", - "req6": "31", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "224", - "high7": "700", - "req7": "41", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "240", - "high8": "750", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png" - } - ] - }, - { - "title": "Tree (Shayzien)", - "names": [ - "objects.tree_normal_default01" - ], - "entries": [ - { - "label": "Normal tree cut chance", - "xlabel": "Woodcutting level", - "label1": "Bronze", - "low1": "64", - "high1": "200", - "req1": "1", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "96", - "high2": "300", - "req2": "1", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "128", - "high3": "400", - "req3": "6", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "144", - "high4": "450", - "req4": "11", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "160", - "high5": "500", - "req5": "21", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "192", - "high6": "600", - "req6": "31", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "224", - "high7": "700", - "req7": "41", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "240", - "high8": "750", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png" - } - ] - }, - { - "title": "Tree (The Node)", - "names": [ - "objects.gim_tree" - ], - "entries": [ - { - "label": "Normal tree cut chance", - "xlabel": "Woodcutting level", - "label1": "Bronze", - "low1": "64", - "high1": "200", - "req1": "1", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "96", - "high2": "300", - "req2": "1", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "128", - "high3": "400", - "req3": "6", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "144", - "high4": "450", - "req4": "11", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "160", - "high5": "500", - "req5": "21", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "192", - "high6": "600", - "req6": "31", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "224", - "high7": "700", - "req7": "41", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "240", - "high8": "750", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png" - } - ] - }, - { - "title": "Tripwire", - "names": [ - "objects.regicide_trap_tripwire" - ], - "entries": [ - { - "label": "Tripwire success chance", - "label1": "Success chance", - "low1": "30", - "high1": "155", - "req1": "1", - "color1": "gray", - "image1": "Agility icon.png" - } - ] - }, - { - "title": "Tropical wagtail", - "names": [ - "npcs.multicoloured_bird" - ], - "entries": [ - { - "label": "Tropical wagtail catch chance", - "showbefore": "no", - "label1": "Tropical wagtail", - "low1": "75", - "high1": "370", - "req1": "19", - "color1": "#326432", - "image1": "Tropical wagtail icon.png" - } - ] - }, - { - "title": "Trouble Brewing", - "names": [], - "entries": [ - { - "label": "Torch burn chance", - "xlabel": "Firemaking level", - "showbefore": "no", - "label1": "Successful burn", - "low1": "12", - "high1": "112", - "req1": "1", - "color1": "red", - "image1": "Lit torch.png" - } - ] - }, - { - "title": "Trout", - "names": [ - "items.trout" - ], - "entries": [ - { - "label": "Trout cooking chance", - "label1": "Fire or Range", - "low1": "88", - "high1": "432", - "req1": "15", - "color1": "gray", - "image1": "Trout.png", - "label2": "Lumbridge range", - "low2": "98", - "high2": "452", - "req2": "15", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "100", - "high3": "444", - "req3": "15", - "color3": "red", - "image3": "Trout.png", - "label4": "Hosidius +10%", - "low4": "113", - "high4": "457", - "req4": "79", - "color4": "blue", - "image4": "Trout.png" - } - ] - }, - { - "title": "Tuna", - "names": [ - "items.tuna" - ], - "entries": [ - { - "label": "Tuna cooking chance", - "label1": "Fire or Range", - "low1": "58", - "high1": "372", - "req1": "30", - "color1": "gray", - "image1": "Tuna.png", - "label2": "Hosidius +5%", - "low2": "70", - "high2": "384", - "req2": "30", - "color2": "red", - "image2": "Tuna.png", - "label3": "Hosidius +10%", - "low3": "83", - "high3": "397", - "req3": "79", - "color3": "blue", - "image3": "Tuna.png" - } - ] - }, - { - "title": "Turgon", - "names": [ - "npcs.prif_citizen_turgon" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "TzHaar-Hur", - "names": [ - "npcs.tzhaar_hur1", - "npcs.tzhaar_hur2", - "npcs.tzhaar_hur3", - "npcs.tzhaar_hur4", - "npcs.tzhaar_hur5", - "npcs.tzhaar_hur6", - "npcs.tzhaar_hur_city1", - "npcs.tzhaar_hur_city2", - "npcs.tzhaar_hur_city3", - "npcs.tzhaar_hur_city4", - "npcs.tzhaar_hur_city5", - "npcs.tzhaar_hur_city6" - ], - "entries": [ - { - "label": "TzHaar-Hur pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "-200", - "high1": "200", - "req1": "90", - "color1": "gray", - "image1": "Thieving icon.png", - "label2": "Gloves of silence", - "low2": "-210", - "high2": "210", - "req2": "90", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "-220", - "high3": "220", - "req3": "90", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "-242", - "high4": "242", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Ugthanki meat", - "names": [ - "items.cooked_ugthanki_meat" - ], - "entries": [ - { - "label": "Ugthanki meat cooking chance", - "label1": "Fire", - "low1": "40", - "high1": "252", - "req1": "1", - "color1": "orange", - "image1": "Firemaking icon.png", - "label2": "Range", - "low2": "30", - "high2": "253", - "req2": "1", - "color2": "saddlebrown", - "image2": "Cooking range icon.png", - "label3": "Hosidius +5%", - "low3": "42", - "high3": "265", - "req3": "1", - "color3": "red", - "image3": "Cooking range icon.png", - "label4": "Hosidius +10%", - "low4": "55", - "high4": "278", - "req4": "79", - "color4": "blue", - "image4": "Cooking range icon.png" - } - ] - }, - { - "title": "Uncut jade", - "names": [ - "items.uncut_jade" - ], - "entries": [ - { - "label": "Gem cutting rates", - "label1": "Opal", - "low1": "128", - "high1": "250", - "req1": "1", - "color1": "gray", - "image1": "Opal.png", - "label2": "Jade", - "low2": "100", - "high2": "245", - "req2": "13", - "color2": "green", - "image2": "Jade.png", - "label3": "Red topaz", - "low3": "90", - "high3": "240", - "req3": "16", - "color3": "pink", - "image3": "Red topaz.png" - } - ] - }, - { - "title": "Uncut opal", - "names": [ - "items.uncut_opal" - ], - "entries": [ - { - "label": "Gem cutting rates", - "label1": "Opal", - "low1": "128", - "high1": "250", - "req1": "1", - "color1": "gray", - "image1": "Opal.png", - "label2": "Jade", - "low2": "100", - "high2": "245", - "req2": "13", - "color2": "green", - "image2": "Jade.png", - "label3": "Red topaz", - "low3": "90", - "high3": "240", - "req3": "16", - "color3": "pink", - "image3": "Red topaz.png" - } - ] - }, - { - "title": "Uncut red topaz", - "names": [ - "items.uncut_red_topaz" - ], - "entries": [ - { - "label": "Gem cutting rates", - "label1": "Opal", - "low1": "128", - "high1": "250", - "req1": "1", - "color1": "gray", - "image1": "Opal.png", - "label2": "Jade", - "low2": "100", - "high2": "245", - "req2": "13", - "color2": "green", - "image2": "Jade.png", - "label3": "Red topaz", - "low3": "90", - "high3": "240", - "req3": "16", - "color3": "pink", - "image3": "Red topaz.png" - } - ] - }, - { - "title": "Underwater Agility and Thieving", - "names": [], - "entries": [ - { - "label": "Successful search chance", - "lowLevel": "1", - "label1": "Glistening and mermaid's tears", - "low1": "30", - "high1": "40", - "req1": "1", - "color1": "blue", - "image1": "Glistening tear 5.png" - } - ] - }, - { - "title": "Urn (Pyramid Plunder)", - "names": [ - "objects.ntk_urn1_closed", - "objects.ntk_urn2_closed", - "objects.ntk_urn3_closed", - "objects.ntk_urn1_snake", - "objects.ntk_urn2_snake", - "objects.ntk_urn3_snake", - "objects.ntk_urn1_snake_charmed", - "objects.ntk_urn2_snake_charmed", - "objects.ntk_urn3_snake_charmed", - "objects.ntk_urn1_open", - "objects.ntk_urn2_open", - "objects.ntk_urn3_open" - ], - "entries": [ - { - "label": "Search urn success rate", - "showbefore": "no", - "label1": "Search", - "low1": "100", - "high1": "180", - "req1": "21", - "label2": "Searching with uncharmed snake", - "low2": "130", - "high2": "220", - "req2": "21", - "label3": "Check for snakes", - "low3": "160", - "high3": "250", - "req3": "21" - } - ] - }, - { - "title": "Vaire", - "names": [ - "npcs.prif_citizen_vaire" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Veg ball", - "names": [ - "items.veg_ball" - ], - "entries": [ - { - "label": "Veg ball cooking chance", - "label1": "Range", - "low1": "118", - "high1": "492", - "req1": "35", - "color1": "gray", - "image1": "Veg ball.png", - "label2": "Hosidius +5%", - "low2": "130", - "high2": "504", - "req2": "35", - "color2": "red", - "image2": "Veg ball.png", - "label3": "Hosidius +10%", - "low3": "143", - "high3": "517", - "req3": "79", - "color3": "blue", - "image3": "Veg ball.png" - } - ] - }, - { - "title": "Vegetable batta", - "names": [ - "items.vegetable_batta" - ], - "entries": [ - { - "label": "Vegetable batta cooking chance", - "label1": "Range", - "low1": "118", - "high1": "492", - "req1": "28", - "color1": "gray", - "image1": "Vegetable batta.png", - "label2": "Hosidius +5%", - "low2": "130", - "high2": "504", - "req2": "28", - "color2": "red", - "image2": "Vegetable batta.png", - "label3": "Hosidius +10%", - "low3": "143", - "high3": "517", - "req3": "79", - "color3": "blue", - "image3": "Vegetable batta.png" - } - ] - }, - { - "title": "Volcanic Mine", - "names": [], - "entries": [ - { - "label": "Volcanic Mine ore fragments", - "xlabel": "Mining level", - "cascade": "yes", - "showbefore": "no", - "label1": "Runite ore fragment", - "low1": "-10", - "high1": "80", - "req1": "85", - "color1": "steelblue", - "image1": "Runite ore fragment.png", - "label2": "Adamantite ore fragment", - "low2": "-90", - "high2": "90", - "req2": "70", - "color2": "seagreen", - "image2": "Adamantite ore fragment.png", - "label3": "Mithril ore fragment", - "low3": "-75", - "high3": "150", - "req3": "55", - "color3": "slateblue", - "image3": "Mithril ore fragment.png", - "label4": "Gold ore fragment", - "low4": "-40", - "high4": "160", - "req4": "50", - "color4": "goldenrod", - "image4": "Gold ore fragment.png", - "label5": "Coal fragment", - "low5": "-20", - "high5": "170", - "req5": "50", - "color5": "black", - "image5": "Coal fragment.png", - "label6": "Silver ore fragment", - "low6": "0", - "high6": "185", - "req6": "50", - "color6": "silver", - "image6": "Silver ore fragment.png", - "label7": "Iron ore fragment", - "low7": "0", - "high7": "510", - "req7": "50", - "color7": "maroon", - "image7": [] - } - ] - }, - { - "title": "Volcanic sulphur", - "names": [ - "items.lovakengj_sulphur" - ], - "entries": [ - { - "label": "Volcanic sulphur mining chance", - "showbefore": "yes", - "label1": "Volcanic sulphur", - "low1": "100", - "high1": "220", - "req1": "42", - "color1": "red", - "image1": "Volcanic sulphur.png" - } - ] - }, - { - "title": "Vyre", - "names": [], - "entries": [ - { - "label": "Vyre pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "8", - "high1": "128", - "req1": "82", - "color1": "gray", - "image1": "Vyre icon.png", - "label2": "Gloves of silence", - "low2": "8", - "high2": "134", - "req2": "82", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "8", - "high3": "140", - "req3": "82", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "8", - "high4": "154", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Vyrewatch", - "names": [ - "npcs.myq4_vyrewatch_1_crowd", - "npcs.myq4_vyrewatch_2_crowd", - "npcs.myq4_vyrewatch_3_crowd", - "npcs.myq4_vyrewatch_4_crowd", - "npcs.myq4_vyrewatch_1", - "npcs.myq4_vyrewatch_2", - "npcs.myq4_vyrewatch_3", - "npcs.myq4_vyrewatch_4", - "npcs.sang_myq3_female_walk_vyrewatch_1", - "npcs.myreque_pt3_takeoff_vyrewatch_female_1", - "npcs.sang_myq3_female_flying_vyrewatch_1", - "npcs.sang_myq3_male_walk_vyrewatch_1", - "npcs.myreque_pt3_takeoff_vyrewatch_male_1", - "npcs.sang_myq3_male_flying_vyrewatch_1", - "npcs.sang_myq3_female_flying_ns_vyrewatch_1", - "npcs.sang_myq3_male_flying_ns_vyrewatch_1", - "npcs.sang_myq3_female_walk_ns_vyrewatch_1", - "npcs.sang_myq3_male_walk_ns_vyrewatch_1", - "npcs.slepe_vyrewatch_female_1", - "npcs.slepe_vyrewatch_female_2", - "npcs.slepe_vyrewatch_female_3", - "npcs.slepe_vyrewatch_female_4", - "npcs.slepe_vyrewatch_male_1", - "npcs.slepe_vyrewatch_male_2", - "npcs.slepe_vyrewatch_male_3", - "npcs.slepe_vyrewatch_male_4", - "npcs.darkm_vyrewatch_male_2", - "npcs.darkm_vyrewatch_female_4", - "npcs.darkm_vyrewatch_female_2", - "npcs.darkm_vyrewatch_female_3", - "npcs.darkm_vyrewatch_male_4", - "npcs.darkm_vyrewatch_male_1", - "npcs.darkm_vyrewatch_male_3", - "npcs.darkm_vyrewatch_female_1", - "npcs.sang_myq3_female_walk_vyrewatch_2", - "npcs.myreque_pt3_takeoff_vyrewatch_female_2", - "npcs.sang_myq3_female_flying_vyrewatch_2", - "npcs.sang_myq3_male_walk_vyrewatch_2", - "npcs.myreque_pt3_takeoff_vyrewatch_male_2", - "npcs.sang_myq3_male_flying_vyrewatch_2", - "npcs.sang_myq3_female_flying_ns_vyrewatch_2", - "npcs.sang_myq3_male_flying_ns_vyrewatch_2", - "npcs.sang_myq3_female_walk_ns_vyrewatch_2", - "npcs.sang_myq3_male_walk_ns_vyrewatch_2", - "npcs.sang_myq3_female_walk_vyrewatch_3", - "npcs.myreque_pt3_takeoff_vyrewatch_female_3", - "npcs.sang_myq3_female_flying_vyrewatch_3", - "npcs.sang_myq3_male_walk_vyrewatch_3", - "npcs.myreque_pt3_takeoff_vyrewatch_male_3", - "npcs.sang_myq3_male_flying_vyrewatch_3", - "npcs.sang_myq3_female_flying_ns_vyrewatch_3", - "npcs.sang_myq3_male_flying_ns_vyrewatch_3", - "npcs.sang_myq3_female_walk_ns_vyrewatch_3", - "npcs.sang_myq3_male_walk_ns_vyrewatch_3", - "npcs.sang_myq3_female_walk_vyrewatch_4", - "npcs.myreque_pt3_takeoff_vyrewatch_female_4", - "npcs.sang_myq3_female_flying_vyrewatch_4", - "npcs.sang_myq3_male_walk_vyrewatch_4", - "npcs.myreque_pt3_takeoff_vyrewatch_male_4", - "npcs.sang_myq3_male_flying_vyrewatch_4", - "npcs.sang_myq3_female_flying_ns_vyrewatch_4", - "npcs.sang_myq3_male_flying_ns_vyrewatch_4", - "npcs.sang_myq3_female_walk_ns_vyrewatch_4", - "npcs.sang_myq3_male_walk_ns_vyrewatch_4" - ], - "entries": [ - { - "label": "Vyrewatch distraction chance", - "xlabel": "Thieving level", - "label1": "Distract", - "low1": "0", - "high1": "252", - "image1": "Thieving icon.png", - "color1": "#330332" - } - ] - }, - { - "title": "Wall safe", - "names": [ - "objects.roguesden_walldecor_mazesafe", - "objects.roguesden_walldecor_safe_open" - ], - "entries": [ - { - "label": "Thieving chance", - "showbefore": "no", - "": "", - "label1": "Rogue's equipment crate", - "low1": "80", - "high1": "119", - "color1": "black", - "image1": "Rogue's_equipment_crate.png" - } - ] - }, - { - "title": "Wall safe (lobby)", - "names": [ - "objects.roguesden_walldecor_safe" - ], - "entries": [ - { - "label": "Wall safe thieving chance", - "showbefore": "no", - "label1": "Normal", - "low1": "8", - "high1": "160", - "req1": "50", - "color1": "black", - "image1": "Thieving icon.png", - "label2": "Stethoscope", - "low2": "16", - "high2": "192", - "req2": "50", - "color2": "gray", - "image2": "Stethoscope.png" - } - ] - }, - { - "title": "Wall support (Temple of Light)", - "names": [ - "objects.mourning_temple_agility_hanging" - ], - "entries": [ - { - "label": "Wall support climb success rate", - "lowlevel": "0", - "showbefore": "no", - "label1": "Each jump", - "low1": "64", - "high1": "272", - "req1": "1", - "color1": "#9b8f58", - "image1": "Agility icon.png", - "label2": "Overall success", - "low2": "64", - "high2": "272", - "req2": "1", - "color2": "#aa4c58", - "image2": "Agility icon.png", - "exponent2": "8" - } - ] - }, - { - "title": "Warrior (Thieving)", - "names": [ - "npcs.warrior_woman", - "npcs.warrior_woman_variant01", - "npcs.warrior_woman_variant02", - "npcs.warrior_man", - "npcs.warrior_man_variant01", - "npcs.warrior_man_variant02" - ], - "entries": [ - { - "label": "Warrior pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "100", - "high1": "240", - "req1": "25", - "color1": "gray", - "image1": "Thieving icon.png", - "label2": "Gloves of silence", - "low2": "105", - "high2": "252", - "req2": "40", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "110", - "high3": "264", - "req3": "67", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "121", - "high4": "290", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Watchman", - "names": [ - "npcs.yanille_watchman" - ], - "entries": [ - { - "label": "Watchman pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "15", - "high1": "160", - "req1": "65", - "color1": "gray", - "image1": "Thief Watchman.png", - "label2": "Gloves of silence", - "low2": "15", - "high2": "168", - "req2": "65", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "16", - "high3": "176", - "req3": "67", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "17", - "high4": "193", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Water rune (The Slug Menace)", - "names": [ - "items.slug2_rune_water" - ], - "entries": [ - { - "label": "Channeling blank rune success chance", - "xlabel": "Runecraft level", - "showbefore": "no", - "label1": "Water rune", - "low1": "110", - "high1": "253", - "req1": "30", - "color1": "#11158b", - "image1": "Water rune (The Slug Menace).png" - } - ] - }, - { - "title": "Wealthy citizen", - "names": [ - "npcs.varlamore_wealthy_citizen_a", - "npcs.varlamore_wealthy_citizen_b", - "npcs.varlamore_wealthy_citizen_c", - "npcs.varlamore_wealthy_citizen_d" - ], - "entries": [ - { - "label": "Wealthy citizen pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "35", - "high1": "200", - "req1": "50", - "color1": "gray", - "image1": "Thief Wealthy citizen.png", - "label2": "Gloves of silence", - "low2": "36", - "high2": "210", - "req2": "50", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "38", - "high3": "220", - "req3": "50", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "41", - "high4": "242", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "White rabbit", - "names": [], - "entries": [ - { - "label": "Ferret preservation chance", - "xlabel": "Hunter level", - "showbefore": "no", - "label1": "Flushing a rabbit hole", - "low1": "190", - "high1": "255", - "req1": "27", - "color1": "#645750", - "image1": "Ferret.png" - } - ] - }, - { - "title": "Wild pie", - "names": [ - "items.wild_pie", - "items.half_wild_pie" - ], - "entries": [ - { - "label": "Wild pie cooking chance", - "showbefore": "no", - "label1": "Range", - "low1": "1", - "high1": "222", - "req1": "85", - "color1": "saddlebrown", - "image1": "Wild pie.png", - "label2": "Hosidius +5%", - "low2": "13", - "high2": "234", - "req2": "85", - "color2": "red", - "image2": "Wild pie.png", - "label3": "Hosidius +10%", - "low3": "26", - "high3": "247", - "req3": "85", - "color3": "blue", - "image3": "Wild pie.png" - } - ] - }, - { - "title": "Willow birdhouse", - "names": [ - "objects.birdhouse_willow_built", - "objects.birdhouse_willow_full", - "objects.birdhouse_willow_bird" - ], - "entries": [ - { - "label": "Seed nest chance", - "xlabel": "Hunter level", - "label1": "Seed nest", - "low1": "0", - "high1": "200", - "req1": "24", - "color1": "grey", - "image1": "Bird nest (seeds).png" - }, - { - "label": "Other nests (10 rolls per birdhouse)", - "xlabel": "Hunter level", - "birdhouse": "yes", - "label1": "Willow", - "high1": "128", - "req1": "24", - "color1": "#006400", - "image1": "Willow bird house.png" - } - ] - }, - { - "title": "Willow tree", - "names": [ - "objects.willowtree", - "objects.willow_tree2", - "objects.willow_tree3", - "objects.willow_tree4" - ], - "entries": [ - { - "label": "Willow tree cut chance", - "xlabel": "Woodcutting level", - "showbefore": "no", - "label1": "Bronze", - "low1": "16", - "high1": "50", - "req1": "30", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "24", - "high2": "75", - "req2": "30", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "32", - "high3": "100", - "req3": "30", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "36", - "high4": "112", - "req4": "30", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "40", - "high5": "125", - "req5": "30", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "48", - "high6": "150", - "req6": "31", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "56", - "high7": "175", - "req7": "41", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "60", - "high8": "187", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png" - } - ] - }, - { - "title": "Wine of zamorak", - "names": [ - "items.wine_of_zamorak" - ], - "entries": [ - { - "label": "Wine of Zamorak Success chance", - "showbefore": "no", - "label1": "Wine of Zamorak", - "low1": "-125", - "high1": "260", - "req1": "65", - "color1": "#652723", - "image1": "Wine of zamorak detail.png" - } - ] - }, - { - "title": "Wire machine", - "names": [ - "objects.dorgesh_wire_machine_chimney", - "objects.dorgesh_wire_machine", - "objects.dorgesh_wire_machine_spool", - "objects.dorgesh_wire_machine_cogs", - "objects.dorgesh_wire_machine_smoke" - ], - "entries": [ - { - "label": "Thieving chance", - "showbefore": "no", - "": "", - "label1": "Cave goblin wire", - "low1": "50", - "high1": "250", - "req1": "44", - "color1": "brown", - "image1": "Cave_goblin_wire.png" - } - ] - }, - { - "title": "Woman", - "names": [ - "npcs.woman", - "npcs.zeah_woman", - "npcs.zeah_woman_outside", - "npcs.woman2", - "npcs.zeah_woman2", - "npcs.woman3", - "npcs.zeah_woman3", - "npcs.varrock_woman1", - "npcs.shayzien_woman_1", - "npcs.shayzien_woman_2" - ], - "entries": [ - { - "label": "Woman pickpocket chance", - "label1": "Normal", - "low1": "180", - "high1": "240", - "req1": "1", - "color1": "gray", - "image1": "Thieving icon.png", - "label2": "Gloves of silence", - "low2": "189", - "high2": "252", - "req2": "1", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "198", - "high3": "264", - "req3": "1", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "217", - "high4": "290", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Woman (East Ardougne)", - "names": [ - "npcs.ardougnian_female1" - ], - "entries": [ - { - "label": "Woman pickpocket chance", - "label1": "Normal", - "low1": "180", - "high1": "240", - "req1": "1", - "color1": "gray", - "image1": "Thieving icon.png", - "label2": "Gloves of silence", - "low2": "189", - "high2": "252", - "req2": "1", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "198", - "high3": "264", - "req3": "1", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "217", - "high4": "290", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Worm batta", - "names": [ - "items.worm_batta" - ], - "entries": [ - { - "label": "Worm batta cooking chance", - "label1": "Range", - "low1": "118", - "high1": "492", - "req1": "27", - "color1": "gray", - "image1": "Worm batta.png", - "label2": "Hosidius +5%", - "low2": "130", - "high2": "504", - "req2": "27", - "color2": "red", - "image2": "Worm batta.png", - "label3": "Hosidius +10%", - "low3": "143", - "high3": "517", - "req3": "79", - "color3": "blue", - "image3": "Worm batta.png" - } - ] - }, - { - "title": "Worm crunchies", - "names": [ - "items.worm_crunchies" - ], - "entries": [ - { - "label": "Worm crunchies cooking chance", - "label1": "Range", - "low1": "118", - "high1": "492", - "req1": "14", - "color1": "gray", - "image1": "Worm crunchies.png", - "label2": "Hosidius +5%", - "low2": "130", - "high2": "504", - "req2": "14", - "color2": "red", - "image2": "Worm crunchies.png", - "label3": "Hosidius +10%", - "low3": "143", - "high3": "517", - "req3": "79", - "color3": "blue", - "image3": "Worm crunchies.png" - } - ] - }, - { - "title": "Worm hole", - "names": [ - "items.worm_hole" - ], - "entries": [ - { - "label": "Worm hole cooking chance", - "label1": "Range", - "low1": "118", - "high1": "492", - "req1": "30", - "color1": "gray", - "image1": "Worm hole.png", - "label2": "Hosidius +5%", - "low2": "130", - "high2": "504", - "req2": "30", - "color2": "red", - "image2": "Worm hole.png", - "label3": "Hosidius +10%", - "low3": "143", - "high3": "517", - "req3": "79", - "color3": "blue", - "image3": "Worm hole.png" - } - ] - }, - { - "title": "Yew birdhouse", - "names": [ - "objects.birdhouse_yew_built", - "objects.birdhouse_yew_full", - "objects.birdhouse_yew_bird" - ], - "entries": [ - { - "label": "Seed nest chance", - "xlabel": "Hunter level", - "label1": "Seed nest", - "low1": "0", - "high1": "200", - "req1": "59", - "color1": "grey", - "image1": "Bird nest (seeds).png" - }, - { - "label": "Other nests (10 rolls per birdhouse)", - "xlabel": "Hunter level", - "birdhouse": "yes", - "label1": "Yew", - "high1": "160", - "req1": "59", - "color1": "#1e90ff", - "image1": "Yew bird house.png" - } - ] - }, - { - "title": "Yew tree", - "names": [ - "objects.yewtree", - "objects.prif_yewtree", - "objects.yewtree_update", - "objects.tree_yew_default01" - ], - "entries": [ - { - "label": "Yew tree cut chance", - "showbefore": "no", - "label1": "Bronze", - "low1": "4", - "high1": "12", - "req1": "60", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "6", - "high2": "19", - "req2": "60", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "8", - "high3": "25", - "req3": "60", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "9", - "high4": "28", - "req4": "60", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "10", - "high5": "31", - "req5": "60", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "12", - "high6": "37", - "req6": "60", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "14", - "high7": "44", - "req7": "60", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "15", - "high8": "47", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png" - } - ] - }, - { - "title": "Yommi tree seeds", - "names": [ - "items.yommiseeds", - "items.yommiseeds_germ" - ], - "entries": [ - { - "label": "Yommi tree growth chance", - "showbefore": "no", - "xlabel": "Herblore level", - "label1": "Yommi tree", - "low1": "40", - "high1": "243", - "req1": "45", - "color1": "green", - "image1": "Yommi tree seeds (germinated).png" - } - ] - }, - { - "title": "Young impling", - "names": [ - "npcs.ii_impling_type_2", - "npcs.ii_impling_type_2_maze" - ], - "entries": [ - { - "label": "Young impling catch chance", - "showbefore": "no", - "label1": "Butterfly net", - "low1": "69", - "high1": "351", - "req1": "22", - "color1": "saddlebrown", - "image1": "Butterfly net.png", - "label2": "Barehanded or magic butterfly net", - "low2": "89", - "high2": "371", - "req2": "22", - "color2": "green", - "image2": "Magic butterfly net.png" - } - ] - }, - { - "title": "Dragon impling", - "names": [ - "npcs.ii_impling_type_10", - "npcs.ii_impling_type_10_maze" - ], - "entries": [ - { - "label": "Dragon impling catch chance", - "showbefore": "no", - "label1": "Butterfly net", - "low1": "5", - "high1": "125", - "req1": "83", - "color1": "saddlebrown", - "image1": "Butterfly net.png", - "label2": "Barehanded or magic butterfly net", - "low2": "25", - "high2": "145", - "req2": "83", - "color2": "green", - "image2": "Magic butterfly net.png" - } - ] - }, - { - "title": "Eclectic impling", - "names": [ - "npcs.ii_impling_type_6", - "npcs.ii_impling_type_6_maze" - ], - "entries": [ - { - "label": "Eclectic impling catch chance", - "showbefore": "no", - "label1": "Butterfly net", - "low1": "30", - "high1": "250", - "req1": "50", - "color1": "saddlebrown", - "image1": "Butterfly net.png", - "label2": "Barehanded or magic butterfly net", - "low2": "50", - "high2": "270", - "req2": "50", - "color2": "green", - "image2": "Magic butterfly net.png" - } - ] - }, - { - "title": "Black chinchompa (Hunter)", - "names": [ - "npcs.hunting_chinchompa_black" - ], - "entries": [ - { - "label": "Chinchompa catch chance", - "lowLevel": "53", - "label1": "Grey", - "low1": "6", - "high1": "268", - "req1": "53", - "color1": "gray", - "image1": "Chinchompa.png", - "label2": "Red", - "low2": "-78", - "high2": "228", - "req2": "63", - "color2": "red", - "image2": "Red chinchompa.png", - "label3": "Black", - "low3": "-78", - "high3": "228", - "req3": "73", - "color3": "black", - "image3": "Black chinchompa.png" - } - ] - }, - { - "title": "Baby impling", - "names": [ - "npcs.ii_impling_type_1", - "npcs.ii_impling_type_1_maze" - ], - "entries": [ - { - "label": "Baby impling catch chance", - "showbefore": "no", - "label1": "Butterfly net", - "low1": "79", - "high1": "402", - "req1": "17", - "color1": "saddlebrown", - "image1": "Butterfly net.png", - "label2": "Barehanded or magic butterfly net", - "low2": "99", - "high2": "422", - "req2": "17", - "color2": "green", - "image2": "Magic butterfly net.png" - } - ] - }, - { - "title": "Crystal impling", - "names": [ - "npcs.ii_impling_type_12_johnny", - "npcs.ii_impling_type_12_junior", - "npcs.ii_impling_type_12_andy", - "npcs.ii_impling_type_12_joey", - "npcs.ii_impling_type_12_trouble", - "npcs.ii_impling_type_12_hingy", - "npcs.ii_impling_type_12_zolty", - "npcs.ii_impling_type_12_neil", - "npcs.ii_impling_type_12_yanny", - "npcs.ii_impling_type_12_matty", - "npcs.ii_impling_type_12_stace", - "npcs.ii_impling_type_12_ian", - "npcs.ii_impling_type_12_jamie", - "npcs.ii_impling_type_12_damo", - "npcs.ii_impling_type_12_xander", - "npcs.ii_impling_type_12_steveo", - "npcs.ii_impling_type_12_stewie" - ], - "entries": [ - { - "label": "Crystal impling catch chance", - "showbefore": "no", - "label1": "Butterfly net", - "low1": "8", - "high1": "141", - "req1": "80", - "color1": "saddlebrown", - "image1": "Butterfly net.png", - "label2": "Barehanded or magic butterfly net", - "low2": "28", - "high2": "161", - "req2": "80", - "color2": "green", - "image2": "Magic butterfly net.png" - } - ] - }, - { - "title": "Earth impling", - "names": [ - "npcs.ii_impling_type_4", - "npcs.ii_impling_type_4_maze" - ], - "entries": [ - { - "label": "Earth impling catch chance", - "showbefore": "no", - "label1": "Butterfly net", - "low1": "51", - "high1": "302", - "req1": "36", - "color1": "saddlebrown", - "image1": "Butterfly net.png", - "label2": "Barehanded or magic butterfly net", - "low2": "71", - "high2": "322", - "req2": "36", - "color2": "green", - "image2": "Magic butterfly net.png" - } - ] - }, - { - "title": "Essence impling", - "names": [ - "npcs.ii_impling_type_5", - "npcs.ii_impling_type_5_maze" - ], - "entries": [ - { - "label": "Essence impling catch chance", - "showbefore": "no", - "label1": "Butterfly net", - "low1": "40", - "high1": "275", - "req1": "42", - "color1": "saddlebrown", - "image1": "Butterfly net.png", - "label2": "Barehanded or magic butterfly net", - "low2": "60", - "high2": "295", - "req2": "42", - "color2": "green", - "image2": "Magic butterfly net.png" - } - ] - }, - { - "title": "Al Kharid warrior", - "names": [ - "npcs.al_kharid_warrior" - ], - "entries": [ - { - "label": "Al Kharid warrior pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "100", - "high1": "240", - "req1": "25", - "color1": "gray", - "image1": "Thieving icon.png", - "label2": "Gloves of silence", - "low2": "105", - "high2": "252", - "req2": "40", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "110", - "high3": "264", - "req3": "67", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "121", - "high4": "290", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Bandit (Bandit Camp)", - "names": [ - "npcs.fourdiamonds_sword_bandit_free", - "npcs.fourdiamonds_sword_bandit_1" - ], - "entries": [ - { - "label": "Bandit pickpocket chance", - "label1": "Normal", - "low1": "50", - "high1": "240", - "req1": "53", - "color1": "gray", - "image1": "Thief Desert bandit.png", - "label2": "Gloves of silence", - "low2": "52", - "high2": "252", - "req2": "53", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "55", - "high3": "264", - "req3": "53", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "60", - "high4": "290", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Carnivorous chinchompa", - "names": [ - "npcs.hunting_chinchompa_big" - ], - "entries": [ - { - "label": "Chinchompa catch chance", - "lowLevel": "53", - "label1": "Grey", - "low1": "6", - "high1": "268", - "req1": "53", - "color1": "gray", - "image1": "Chinchompa.png", - "label2": "Red", - "low2": "-78", - "high2": "228", - "req2": "63", - "color2": "red", - "image2": "Red chinchompa.png", - "label3": "Black", - "low3": "-78", - "high3": "228", - "req3": "73", - "color3": "black", - "image3": "Black chinchompa.png" - } - ] - }, - { - "title": "Farmer", - "names": [ - "npcs.farmer1", - "npcs.farmer2", - "npcs.farmer3", - "npcs.farmer1_f", - "npcs.farmer2_f", - "npcs.farmer3_f", - "npcs.farmer4" - ], - "entries": [ - { - "label": "Farmer pickpocket chance", - "showbefore": "yes", - "label1": "Normal", - "low1": "150", - "high1": "240", - "req1": "7", - "color1": "gray", - "image1": "Thieving icon.png", - "label2": "Gloves of silence", - "low2": "157", - "high2": "252", - "req2": "7", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "165", - "high3": "264", - "req3": "38", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "181", - "high4": "290", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Chinchompa (Hunter)", - "names": [ - "npcs.hunting_chinchompa" - ], - "entries": [ - { - "label": "Chinchompa catch chance", - "lowLevel": "53", - "label1": "Grey", - "low1": "6", - "high1": "268", - "req1": "53", - "color1": "gray", - "image1": "Chinchompa.png", - "label2": "Red", - "low2": "-78", - "high2": "228", - "req2": "63", - "color2": "red", - "image2": "Red chinchompa.png", - "label3": "Black", - "low3": "-78", - "high3": "228", - "req3": "73", - "color3": "black", - "image3": "Black chinchompa.png" - } - ] - }, - { - "title": "Underwater Agility and Thieving", - "names": [], - "entries": [ - { - "label": "Successful search chance", - "lowLevel": "1", - "label1": "Glistening and mermaid's tears", - "low1": "30", - "high1": "40", - "req1": "1", - "color1": "blue", - "image1": "Glistening tear 5.png" - } - ] - }, - { - "title": "Bird house trapping", - "names": [], - "entries": [ - { - "label": "Seed nest chance", - "xlabel": "Hunter level", - "label1": "Seed nest", - "low1": "0", - "high1": "200", - "req1": "5", - "color1": "grey", - "image1": "Bird nest (seeds).png" - }, - { - "label": "Other nests (10 rolls per birdhouse)", - "xlabel": "Hunter level", - "birdhouse": "yes", - "label1": "Regular", - "high1": "100", - "req1": "5", - "color1": "#4b0082", - "image1": "Bird house.png", - "label2": "Oak", - "high2": "125", - "req2": "14", - "color2": "#ff0000", - "image2": "Oak bird house.png", - "label3": "Willow", - "high3": "128", - "req3": "24", - "color3": "#006400", - "image3": "Willow bird house.png", - "label4": "Teak", - "high4": "130", - "req4": "34", - "color4": "#ffa500", - "image4": "Teak bird house.png", - "label5": "Maple", - "high5": "140", - "req5": "44", - "color5": "#00ff00", - "image5": "Maple bird house.png", - "label6": "Mahogany", - "high6": "150", - "req6": "49", - "color6": "#ffff00", - "image6": "Mahogany bird house.png", - "label7": "Yew", - "high7": "160", - "req7": "59", - "color7": "#1e90ff", - "image7": "Yew bird house.png", - "label8": "Magic", - "high8": "170", - "req8": "74", - "color8": "#708090", - "image8": "Magic bird house.png", - "label9": "Redwood", - "high9": "175", - "req9": "89", - "color9": "#ff00ff", - "image9": "Redwood bird house.png" - } - ] - }, - { - "title": "Shooting Stars", - "names": [], - "entries": [ - { - "color1": "goldenrod", - "high1": "117", - "image1": "Stardust_175.png", - "label": "Stardust mining chance", - "label1": "Stardust", - "low1": "73", - "req1": "10", - "showbefore": "no" - } - ] - }, - { - "title": "Admiral pie", - "names": [ - "items.admiral_pie", - "items.half_admiral_pie" - ], - "entries": [ - { - "label": "Admiral pie cooking chance", - "xlabel": "Cooking level", - "showbefore": "no", - "label1": "Range", - "low1": "15", - "high1": "270", - "req1": "70", - "color1": "saddlebrown", - "image1": "Admiral pie.png", - "label2": "Hosidius +5%", - "low2": "27", - "high2": "282", - "req2": "70", - "color2": "red", - "image2": "Admiral pie.png", - "label3": "Hosidius +10%", - "low3": "40", - "high3": "295", - "req3": "79", - "color3": "blue", - "image3": "Admiral pie.png" - } - ] - }, - { - "title": "Raw salmon", - "names": [ - "items.raw_salmon" - ], - "entries": [ - { - "label": "Trout + salmon fishing chance", - "cascade": "yes", - "showbefore": "no", - "label1": "Raw salmon", - "low1": "16", - "high1": "96", - "req1": "30", - "color1": "#c77f72", - "image1": "Raw salmon.png", - "label2": "Raw trout", - "low2": "32", - "high2": "192", - "req2": "20", - "color2": "#9a908f", - "image2": "Raw trout.png" - } - ] - }, - { - "title": "Yew tree", - "names": [ - "objects.yewtree", - "objects.prif_yewtree", - "objects.yewtree_update", - "objects.tree_yew_default01" - ], - "entries": [ - { - "label": "Yew tree cut chance", - "showbefore": "no", - "label1": "Bronze", - "low1": "4", - "high1": "12", - "req1": "60", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "6", - "high2": "19", - "req2": "60", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "8", - "high3": "25", - "req3": "60", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "9", - "high4": "28", - "req4": "60", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "10", - "high5": "31", - "req5": "60", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "12", - "high6": "37", - "req6": "60", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "14", - "high7": "44", - "req7": "60", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "15", - "high8": "47", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png" - } - ] - }, - { - "title": "Willow tree", - "names": [ - "objects.willowtree", - "objects.willow_tree2", - "objects.willow_tree3", - "objects.willow_tree4" - ], - "entries": [ - { - "label": "Willow tree cut chance", - "xlabel": "Woodcutting level", - "showbefore": "no", - "label1": "Bronze", - "low1": "16", - "high1": "50", - "req1": "30", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "24", - "high2": "75", - "req2": "30", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "32", - "high3": "100", - "req3": "30", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "36", - "high4": "112", - "req4": "30", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "40", - "high5": "125", - "req5": "30", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "48", - "high6": "150", - "req6": "31", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "56", - "high7": "175", - "req7": "41", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "60", - "high8": "187", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png" - } - ] - }, - { - "title": "Raw trout", - "names": [ - "items.raw_trout" - ], - "entries": [ - { - "label": "Trout + salmon fishing chance", - "xlabel": "Fishing level", - "cascade": "yes", - "showbefore": "no", - "label1": "Raw salmon", - "low1": "16", - "high1": "96", - "req1": "30", - "color1": "#c77f72", - "image1": "Raw salmon.png", - "label2": "Raw trout", - "low2": "32", - "high2": "192", - "req2": "20", - "color2": "#9a908f", - "image2": "Raw trout.png" - } - ] - }, - { - "title": "Prototype dart tip", - "names": [ - "items.thprotodarttip" - ], - "entries": [ - { - "label": "Prototype dart tip creation chance", - "label1": "Prototype dart tip", - "low1": "61", - "high1": "245", - "req1": "20", - "image1": "Prototype_dart_tip.png" - } - ] - }, - { - "title": "Brimstone chest", - "names": [ - "objects.brimstone_konar_chest_closed", - "objects.brimstone_konar_chest_open" - ], - "entries": [ - { - "label": "Brimstone chest fish chance", - "xlabel": "Fishing level", - "ylabel": "Chance to receive", - "cascade": [], - "label1": "Raw manta ray", - "low1": "-10", - "high1": "20", - "image1": "Raw manta ray.png", - "color1": [], - "label2": "Raw sea turtle", - "low2": "-10", - "high2": "50", - "image2": "Raw sea turtle.png", - "color2": [], - "label3": "Raw shark", - "low3": "-60", - "high3": "140", - "image3": "Raw shark.png", - "color3": [], - "label4": "Raw monkfish", - "low4": "0", - "high4": "170", - "image4": "Raw monkfish.png", - "color4": [], - "label5": "Raw swordfish", - "low5": "30", - "high5": "200", - "image5": "Raw swordfish.png", - "color5": [], - "label6": "Raw lobster", - "low6": "70", - "high6": "270", - "image6": "Raw lobster.png", - "color6": [], - "label7": "Raw tuna", - "low7": "225", - "high7": "324", - "image7": "Raw tuna.png", - "color7": [] - } - ] - }, - { - "title": "Raw slimy eel", - "names": [ - "items.mort_slimey_eel" - ], - "entries": [ - { - "label": "Slimy + cave eel fishing chance", - "cascade": "yes", - "showbefore": "no", - "label1": "Raw cave eel", - "low1": "10", - "high1": "80", - "req1": "38", - "color1": "#606b48", - "image1": "Raw cave eel.png", - "label2": "Raw slimy eel", - "low2": "10", - "high2": "80", - "req2": "28", - "color2": "brown", - "image2": "Raw slimy eel.png" - } - ] - }, - { - "title": "Cooked slimy eel", - "names": [ - "items.mort_slimey_eel_cooked" - ], - "entries": [ - { - "label": "Cooked slimy eel cooking chance", - "label1": "Fire or Range", - "low1": "63", - "high1": "382", - "req1": "28", - "color1": "gray", - "image1": "Cooked slimy eel.png", - "label2": "Hosidius +5%", - "low2": "75", - "high2": "394", - "req2": "28", - "color2": "red", - "image2": "Cooked slimy eel.png", - "label3": "Hosidius +10%", - "low3": "88", - "high3": "407", - "req3": "79", - "color3": "blue", - "image3": "Cooked slimy eel.png" - } - ] - }, - { - "title": "Burnt shrimp", - "names": [ - "items.burnt_shrimp" - ], - "entries": [ - { - "label": "Shrimps cooking chance", - "xlabel": "Cooking level", - "label1": "Fire or Range", - "low1": "128", - "high1": "512", - "req1": "1", - "color1": "gray", - "image1": "Shrimps.png", - "label2": "Lumbridge range", - "low2": "138", - "high2": "532", - "req2": "1", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "140", - "high3": "524", - "req3": "1", - "color3": "red", - "image3": "Shrimps.png", - "label4": "Hosidius +10%", - "low4": "153", - "high4": "537", - "req4": "84", - "color4": "blue", - "image4": "Shrimps.png" - } - ] - }, - { - "title": "Fat snail meat", - "names": [ - "items.snail_corpse_cooked3" - ], - "entries": [ - { - "label": "Fat snail meat cooking chance", - "label1": "Fire or Range", - "low1": "73", - "high1": "402", - "req1": "22", - "color1": "gray", - "image1": "Fat snail meat.png", - "label2": "Lumbridge range", - "low2": "83", - "high2": "422", - "req2": "22", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "85", - "high3": "414", - "req3": "22", - "color3": "red", - "image3": "Fat snail meat.png", - "label4": "Hosidius +10%", - "low4": "98", - "high4": "427", - "req4": "79", - "color4": "blue", - "image4": "Fat snail meat.png" - } - ] - }, - { - "title": "Lean snail meat", - "names": [ - "items.snail_corpse_cooked2" - ], - "entries": [ - { - "label": "Lean snail meat cooking chance", - "label1": "Fire", - "low1": "93", - "high1": "444", - "req1": "17", - "color1": "orange", - "image1": "Firemaking icon.png", - "label2": "Range", - "low2": "85", - "high2": "428", - "req2": "17", - "color2": "saddlebrown", - "image2": "Cooking range icon.png", - "label3": "Lumbridge range", - "low3": "95", - "high3": "448", - "req3": "17", - "color3": "green", - "image3": "Lumbridge Teleport.png", - "label4": "Hosidius +5%", - "low4": "97", - "high4": "440", - "req4": "17", - "color4": "red", - "image4": "Cooking range icon.png", - "label5": "Hosidius +10%", - "low5": "110", - "high5": "453", - "req5": "79", - "color5": "blue", - "image5": "Cooking range icon.png" - } - ] - }, - { - "title": "Thin snail meat", - "names": [ - "items.snail_corpse_cooked1" - ], - "entries": [ - { - "label": "Thin snail meat cooking chance", - "label1": "Fire or Range", - "low1": "93", - "high1": "444", - "req1": "12", - "color1": "gray", - "image1": "Thin snail meat.png", - "label2": "Lumbridge range", - "low2": "103", - "high2": "464", - "req2": "12", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "105", - "high3": "456", - "req3": "12", - "color3": "red", - "image3": "Thin snail meat.png", - "label4": "Hosidius +10%", - "low4": "118", - "high4": "469", - "req4": "79", - "color4": "blue", - "image4": "Thin snail meat.png" - } - ] - }, - { - "title": "Wealthy citizen", - "names": [ - "npcs.varlamore_wealthy_citizen_a", - "npcs.varlamore_wealthy_citizen_b", - "npcs.varlamore_wealthy_citizen_c", - "npcs.varlamore_wealthy_citizen_d" - ], - "entries": [ - { - "label": "Wealthy citizen pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "35", - "high1": "200", - "req1": "50", - "color1": "gray", - "image1": "Thief Wealthy citizen.png", - "label2": "Gloves of silence", - "low2": "36", - "high2": "210", - "req2": "50", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "38", - "high3": "220", - "req3": "50", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "41", - "high4": "242", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Martin the Master Gardener", - "names": [ - "npcs.martin_the_master_farmer" - ], - "entries": [ - { - "label": "Master Farmer pickpocket chance", - "label1": "Normal", - "low1": "90", - "high1": "240", - "req1": "38", - "color1": "gray", - "image1": "Thief Master farmer.png", - "label2": "Gloves of silence", - "low2": "94", - "high2": "252", - "req2": "38", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "99", - "high3": "264", - "req3": "67", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "108", - "high4": "290", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Kelyn", - "names": [ - "npcs.sote_lady_ithell_normal", - "npcs.mourning_town_elf_5_vis", - "npcs.sote_lady_ithell_vis", - "npcs.sote_lady_ithell_upass", - "npcs.lady_ithell" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "H.A.M. Member", - "names": [ - "npcs.favour_male_ham_civilian", - "npcs.favour_female_ham_civilian" - ], - "entries": [ - { - "label": "Avoiding concussions using Agility", - "label1": "", - "low1": "0", - "high1": "254", - "req1": "15", - "showbefore": "yes", - "color1": "black", - "image1": "Agility icon.png" - }, - { - "label": "H.A.M Member pickpocket chance", - "label1": "Normal", - "low1": "135", - "high1": "239", - "req1": "15", - "color1": "gray", - "image1": "Thieving icon.png", - "label2": "Gloves of silence", - "low2": "141", - "high2": "250", - "req2": "15", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "148", - "high3": "262", - "req3": "72", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "162", - "high4": "288", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Golden warbler", - "names": [ - "npcs.hunting_bird_desert" - ], - "entries": [ - { - "label": "Golden warbler catch chance", - "showbefore": "no", - "label1": "Golden warbler", - "low1": "92", - "high1": "400", - "req1": "5", - "color1": "#bfbf2a", - "image1": "Golden warbler icon.png" - } - ] - }, - { - "title": "Arvel", - "names": [ - "npcs.mourning_town_elf_3" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Mawrth", - "names": [ - "npcs.mourning_town_elf_4", - "npcs.sote_mawrth", - "npcs.sote_mawrth_cutscene" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Crimson swift", - "names": [ - "npcs.hunting_bird_jungle" - ], - "entries": [ - { - "label": "Crimson swift catch chance", - "showbefore": "no", - "label1": "Crimson swift", - "low1": "100", - "high1": "420", - "req1": "1", - "color1": "#d44444", - "image1": "Crimson swift icon.png" - } - ] - }, - { - "title": "Tropical wagtail", - "names": [ - "npcs.multicoloured_bird" - ], - "entries": [ - { - "label": "Tropical wagtail catch chance", - "showbefore": "no", - "label1": "Tropical wagtail", - "low1": "75", - "high1": "370", - "req1": "19", - "color1": "#326432", - "image1": "Tropical wagtail icon.png" - } - ] - }, - { - "title": "Cerulean twitch", - "names": [ - "npcs.hunting_bird_polar" - ], - "entries": [ - { - "label": "Cerulean twitch catch chance", - "showbefore": "no", - "label1": "Cerulean twitch", - "low1": "82", - "high1": "380", - "req1": "11", - "color1": "#41416e", - "image1": "Cerulean twitch icon.png" - } - ] - }, - { - "title": "Polar kebbit", - "names": [], - "entries": [ - { - "label": "Polar kebbit catch chance", - "label1": "Polar kebbit", - "low1": "238", - "high1": "1080", - "req1": "1", - "color1": "#a5a8b1", - "image1": "Polar kebbit icon.png" - } - ] - }, - { - "title": "Black salamander (Hunter)", - "names": [ - "npcs.salamander_black" - ], - "entries": [ - { - "label": "Black salamander catch chance", - "showbefore": "no", - "label1": "Black salamander", - "low1": "0", - "high1": "212", - "req1": "67", - "color1": "#151111", - "image1": "Black salamander.png" - } - ] - }, - { - "title": "Orange salamander (Hunter)", - "names": [ - "npcs.salamander_orange" - ], - "entries": [ - { - "label": "Orange salamander catch chance", - "showbefore": "no", - "label1": "Orange salamander", - "low1": "16", - "high1": "288", - "req1": "47", - "color1": "#976b1e", - "image1": "Orange salamander.png" - } - ] - }, - { - "title": "Red salamander (Hunter)", - "names": [ - "npcs.salamander_red" - ], - "entries": [ - { - "label": "Salamander catch chance", - "showbefore": "no", - "label1": "Red salamander", - "low1": "0", - "high1": "240", - "req1": "59", - "color1": "#6c2413", - "image1": "Red salamander.png" - } - ] - }, - { - "title": "Swamp lizard (Hunter)", - "names": [ - "npcs.salamander_green" - ], - "entries": [ - { - "label": "Swamp lizard catch chance", - "showbefore": "no", - "label1": "Swamp lizard", - "low1": "52", - "high1": "360", - "req1": "29", - "color1": "#1b441a", - "image1": "Swamp lizard.png" - } - ] - }, - { - "title": "Master Farmer", - "names": [ - "npcs.master_farmer_1", - "npcs.master_farmer_2", - "npcs.master_farmer_1_f", - "npcs.master_farmer_2_f", - "npcs.varlamore_master_farmer_f_1", - "npcs.varlamore_master_farmer_f_2", - "npcs.varlamore_master_farmer_f_3", - "npcs.varlamore_master_farmer_f_4", - "npcs.varlamore_master_farmer_m_1", - "npcs.varlamore_master_farmer_m_2", - "npcs.varlamore_master_farmer_m_3", - "npcs.varlamore_master_farmer_m_4" - ], - "entries": [ - { - "label": "Master Farmer pickpocket chance", - "label1": "Normal", - "low1": "90", - "high1": "240", - "req1": "38", - "color1": "gray", - "image1": "Thief Master farmer.png", - "label2": "Gloves of silence", - "low2": "94", - "high2": "252", - "req2": "38", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "99", - "high3": "264", - "req3": "67", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "108", - "high4": "290", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Dark kebbit", - "names": [ - "npcs.huntingbeast_silent" - ], - "entries": [ - { - "label": "Dark kebbit catch chance", - "showbefore": "no", - "label1": "Dark kebbit", - "low1": "0", - "high1": "253", - "req1": "57", - "color1": "#84630d", - "image1": "Dark kebbit icon.png" - } - ] - }, - { - "title": "Dashing kebbit", - "names": [ - "npcs.huntingbeast_speedy2" - ], - "entries": [ - { - "label": "Dashing kebbit catch chance", - "showbefore": "no", - "label1": "Dashing kebbit", - "low1": "0", - "high1": "205", - "req1": "69", - "color1": "#bd9f64", - "image1": "Dashing kebbit icon.png" - } - ] - }, - { - "title": "Spotted kebbit", - "names": [ - "npcs.huntingbeast_speedy" - ], - "entries": [ - { - "label": "Spotted kebbit catch chance", - "showbefore": "no", - "label1": "Spotted kebbit", - "low1": "26", - "high1": "310", - "req1": "43", - "color1": "#5c4a2c", - "image1": "Spotted kebbit icon.png" - } - ] - }, - { - "title": "Copper longtail", - "names": [ - "npcs.hunting_bird_woodland" - ], - "entries": [ - { - "label": "Copper longtail catch chance", - "showbefore": "no", - "label1": "Copper longtail", - "low1": "85", - "high1": "390", - "req1": "9", - "color1": "#ed9b58", - "image1": "Copper longtail icon.png" - } - ] - }, - { - "title": "White rabbit", - "names": [], - "entries": [ - { - "label": "Ferret preservation chance", - "xlabel": "Hunter level", - "showbefore": "no", - "label1": "Flushing a rabbit hole", - "low1": "190", - "high1": "255", - "req1": "27", - "color1": "#645750", - "image1": "Ferret.png" - } - ] - }, - { - "title": "Achey Tree", - "names": [ - "objects.achey_tree" - ], - "entries": [ - { - "label": "Achey tree cut chance", - "label1": "Bronze", - "low1": "64", - "high1": "200", - "req1": "1", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "96", - "high2": "300", - "req2": "1", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "128", - "high3": "400", - "req3": "6", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "144", - "high4": "450", - "req4": "11", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "160", - "high5": "500", - "req5": "21", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "192", - "high6": "600", - "req6": "31", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "224", - "high7": "700", - "req7": "41", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "240", - "high8": "750", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png" - } - ] - }, - { - "title": "Anaire", - "names": [ - "npcs.prif_citizen_anaire" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Aranwe", - "names": [ - "npcs.prif_citizen_aranwe" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Aredhel", - "names": [ - "npcs.prif_citizen_aredhel" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "A wooden log", - "names": [ - "objects.zq_logbalance" - ], - "entries": [ - { - "label": "Crossing a wooden log", - "showbefore": "no", - "xlabel": "Agility level", - "ylabel": "Cross chance", - "label1": "Successful cross chance", - "low1": "90", - "high1": "250", - "req1": "1", - "color1": "#70450d", - "image1": "Agility icon.png" - } - ] - }, - { - "title": "Admiral pie", - "names": [ - "items.admiral_pie", - "items.half_admiral_pie" - ], - "entries": [ - { - "label": "Admiral pie cooking chance", - "xlabel": "Cooking level", - "showbefore": "no", - "label1": "Range", - "low1": "15", - "high1": "270", - "req1": "70", - "color1": "saddlebrown", - "image1": "Admiral pie.png", - "label2": "Hosidius +5%", - "low2": "27", - "high2": "282", - "req2": "70", - "color2": "red", - "image2": "Admiral pie.png", - "label3": "Hosidius +10%", - "low3": "40", - "high3": "295", - "req3": "79", - "color3": "blue", - "image3": "Admiral pie.png" - } - ] - }, - { - "title": "Raw salmon", - "names": [ - "items.raw_salmon" - ], - "entries": [ - { - "label": "Trout + salmon fishing chance", - "cascade": "yes", - "showbefore": "no", - "label1": "Raw salmon", - "low1": "16", - "high1": "96", - "req1": "30", - "color1": "#c77f72", - "image1": "Raw salmon.png", - "label2": "Raw trout", - "low2": "32", - "high2": "192", - "req2": "20", - "color2": "#9a908f", - "image2": "Raw trout.png" - } - ] - }, - { - "title": "Underwater Agility and Thieving", - "names": [], - "entries": [ - { - "label": "Successful search chance", - "lowLevel": "1", - "label1": "Glistening and mermaid's tears", - "low1": "30", - "high1": "40", - "req1": "1", - "color1": "blue", - "image1": "Glistening tear 5.png" - } - ] - }, - { - "title": "Yew tree", - "names": [ - "objects.yewtree", - "objects.prif_yewtree", - "objects.yewtree_update", - "objects.tree_yew_default01" - ], - "entries": [ - { - "label": "Yew tree cut chance", - "showbefore": "no", - "label1": "Bronze", - "low1": "4", - "high1": "12", - "req1": "60", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "6", - "high2": "19", - "req2": "60", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "8", - "high3": "25", - "req3": "60", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "9", - "high4": "28", - "req4": "60", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "10", - "high5": "31", - "req5": "60", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "12", - "high6": "37", - "req6": "60", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "14", - "high7": "44", - "req7": "60", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "15", - "high8": "47", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png" - } - ] - }, - { - "title": "Willow tree", - "names": [ - "objects.willowtree", - "objects.willow_tree2", - "objects.willow_tree3", - "objects.willow_tree4" - ], - "entries": [ - { - "label": "Willow tree cut chance", - "xlabel": "Woodcutting level", - "showbefore": "no", - "label1": "Bronze", - "low1": "16", - "high1": "50", - "req1": "30", - "color1": "saddlebrown", - "image1": "Bronze axe.png", - "label2": "Iron", - "low2": "24", - "high2": "75", - "req2": "30", - "color2": "dimgray", - "image2": "Iron axe.png", - "label3": "Steel", - "low3": "32", - "high3": "100", - "req3": "30", - "color3": "lightgray", - "image3": "Steel axe.png", - "label4": "Black", - "low4": "36", - "high4": "112", - "req4": "30", - "color4": "black", - "image4": "Black axe.png", - "label5": "Mithril", - "low5": "40", - "high5": "125", - "req5": "30", - "color5": "slateblue", - "image5": "Mithril axe.png", - "label6": "Adamant", - "low6": "48", - "high6": "150", - "req6": "31", - "color6": "seagreen", - "image6": "Adamant axe.png", - "label7": "Rune", - "low7": "56", - "high7": "175", - "req7": "41", - "color7": "steelblue", - "image7": "Rune axe.png", - "label8": "Dragon", - "low8": "60", - "high8": "187", - "req8": "61", - "color8": "firebrick", - "image8": "Dragon axe.png" - } - ] - }, - { - "title": "Raw trout", - "names": [ - "items.raw_trout" - ], - "entries": [ - { - "label": "Trout + salmon fishing chance", - "xlabel": "Fishing level", - "cascade": "yes", - "showbefore": "no", - "label1": "Raw salmon", - "low1": "16", - "high1": "96", - "req1": "30", - "color1": "#c77f72", - "image1": "Raw salmon.png", - "label2": "Raw trout", - "low2": "32", - "high2": "192", - "req2": "20", - "color2": "#9a908f", - "image2": "Raw trout.png" - } - ] - }, - { - "title": "Prototype dart tip", - "names": [ - "items.thprotodarttip" - ], - "entries": [ - { - "label": "Prototype dart tip creation chance", - "label1": "Prototype dart tip", - "low1": "61", - "high1": "245", - "req1": "20", - "image1": "Prototype_dart_tip.png" - } - ] - }, - { - "title": "Brimstone chest", - "names": [ - "objects.brimstone_konar_chest_closed", - "objects.brimstone_konar_chest_open" - ], - "entries": [ - { - "label": "Brimstone chest fish chance", - "xlabel": "Fishing level", - "ylabel": "Chance to receive", - "cascade": [], - "label1": "Raw manta ray", - "low1": "-10", - "high1": "20", - "image1": "Raw manta ray.png", - "color1": [], - "label2": "Raw sea turtle", - "low2": "-10", - "high2": "50", - "image2": "Raw sea turtle.png", - "color2": [], - "label3": "Raw shark", - "low3": "-60", - "high3": "140", - "image3": "Raw shark.png", - "color3": [], - "label4": "Raw monkfish", - "low4": "0", - "high4": "170", - "image4": "Raw monkfish.png", - "color4": [], - "label5": "Raw swordfish", - "low5": "30", - "high5": "200", - "image5": "Raw swordfish.png", - "color5": [], - "label6": "Raw lobster", - "low6": "70", - "high6": "270", - "image6": "Raw lobster.png", - "color6": [], - "label7": "Raw tuna", - "low7": "225", - "high7": "324", - "image7": "Raw tuna.png", - "color7": [] - } - ] - }, - { - "title": "Raw slimy eel", - "names": [ - "items.mort_slimey_eel" - ], - "entries": [ - { - "label": "Slimy + cave eel fishing chance", - "cascade": "yes", - "showbefore": "no", - "label1": "Raw cave eel", - "low1": "10", - "high1": "80", - "req1": "38", - "color1": "#606b48", - "image1": "Raw cave eel.png", - "label2": "Raw slimy eel", - "low2": "10", - "high2": "80", - "req2": "28", - "color2": "brown", - "image2": "Raw slimy eel.png" - } - ] - }, - { - "title": "Cooked slimy eel", - "names": [ - "items.mort_slimey_eel_cooked" - ], - "entries": [ - { - "label": "Cooked slimy eel cooking chance", - "label1": "Fire or Range", - "low1": "63", - "high1": "382", - "req1": "28", - "color1": "gray", - "image1": "Cooked slimy eel.png", - "label2": "Hosidius +5%", - "low2": "75", - "high2": "394", - "req2": "28", - "color2": "red", - "image2": "Cooked slimy eel.png", - "label3": "Hosidius +10%", - "low3": "88", - "high3": "407", - "req3": "79", - "color3": "blue", - "image3": "Cooked slimy eel.png" - } - ] - }, - { - "title": "Burnt shrimp", - "names": [ - "items.burnt_shrimp" - ], - "entries": [ - { - "label": "Shrimps cooking chance", - "xlabel": "Cooking level", - "label1": "Fire or Range", - "low1": "128", - "high1": "512", - "req1": "1", - "color1": "gray", - "image1": "Shrimps.png", - "label2": "Lumbridge range", - "low2": "138", - "high2": "532", - "req2": "1", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "140", - "high3": "524", - "req3": "1", - "color3": "red", - "image3": "Shrimps.png", - "label4": "Hosidius +10%", - "low4": "153", - "high4": "537", - "req4": "84", - "color4": "blue", - "image4": "Shrimps.png" - } - ] - }, - { - "title": "Fat snail meat", - "names": [ - "items.snail_corpse_cooked3" - ], - "entries": [ - { - "label": "Fat snail meat cooking chance", - "label1": "Fire or Range", - "low1": "73", - "high1": "402", - "req1": "22", - "color1": "gray", - "image1": "Fat snail meat.png", - "label2": "Lumbridge range", - "low2": "83", - "high2": "422", - "req2": "22", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "85", - "high3": "414", - "req3": "22", - "color3": "red", - "image3": "Fat snail meat.png", - "label4": "Hosidius +10%", - "low4": "98", - "high4": "427", - "req4": "79", - "color4": "blue", - "image4": "Fat snail meat.png" - } - ] - }, - { - "title": "Lean snail meat", - "names": [ - "items.snail_corpse_cooked2" - ], - "entries": [ - { - "label": "Lean snail meat cooking chance", - "label1": "Fire", - "low1": "93", - "high1": "444", - "req1": "17", - "color1": "orange", - "image1": "Firemaking icon.png", - "label2": "Range", - "low2": "85", - "high2": "428", - "req2": "17", - "color2": "saddlebrown", - "image2": "Cooking range icon.png", - "label3": "Lumbridge range", - "low3": "95", - "high3": "448", - "req3": "17", - "color3": "green", - "image3": "Lumbridge Teleport.png", - "label4": "Hosidius +5%", - "low4": "97", - "high4": "440", - "req4": "17", - "color4": "red", - "image4": "Cooking range icon.png", - "label5": "Hosidius +10%", - "low5": "110", - "high5": "453", - "req5": "79", - "color5": "blue", - "image5": "Cooking range icon.png" - } - ] - }, - { - "title": "Thin snail meat", - "names": [ - "items.snail_corpse_cooked1" - ], - "entries": [ - { - "label": "Thin snail meat cooking chance", - "label1": "Fire or Range", - "low1": "93", - "high1": "444", - "req1": "12", - "color1": "gray", - "image1": "Thin snail meat.png", - "label2": "Lumbridge range", - "low2": "103", - "high2": "464", - "req2": "12", - "color2": "green", - "image2": "Lumbridge Teleport.png", - "label3": "Hosidius +5%", - "low3": "105", - "high3": "456", - "req3": "12", - "color3": "red", - "image3": "Thin snail meat.png", - "label4": "Hosidius +10%", - "low4": "118", - "high4": "469", - "req4": "79", - "color4": "blue", - "image4": "Thin snail meat.png" - } - ] - }, - { - "title": "Wealthy citizen", - "names": [ - "npcs.varlamore_wealthy_citizen_a", - "npcs.varlamore_wealthy_citizen_b", - "npcs.varlamore_wealthy_citizen_c", - "npcs.varlamore_wealthy_citizen_d" - ], - "entries": [ - { - "label": "Wealthy citizen pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "35", - "high1": "200", - "req1": "50", - "color1": "gray", - "image1": "Thief Wealthy citizen.png", - "label2": "Gloves of silence", - "low2": "36", - "high2": "210", - "req2": "50", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "38", - "high3": "220", - "req3": "50", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "41", - "high4": "242", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Trouble Brewing", - "names": [], - "entries": [ - { - "label": "Torch burn chance", - "xlabel": "Firemaking level", - "showbefore": "no", - "label1": "Successful burn", - "low1": "12", - "high1": "112", - "req1": "1", - "color1": "red", - "image1": "Lit torch.png" - } - ] - }, - { - "title": "Motherlode Mine", - "names": [], - "entries": [ - { - "label": "Pay-dirt mining chance", - "showbefore": "no", - "xlabel": "Mining Level", - "label1": "Pay-dirt", - "low1": "60", - "high1": "105", - "req1": "30", - "color1": "brown", - "image1": "Pay-dirt.png" - }, - { - "label": "Motherlode Mine ore chance", - "xlabel": "Mining level", - "cascade": "yes", - "showbefore": "no", - "label1": "Golden nugget", - "low1": "7", - "high1": "7", - "req1": "30", - "color1": "gold", - "image1": "Golden nugget.png", - "label2": "Runite ore", - "low2": "-20", - "high2": "5", - "req2": "85", - "color2": "steelblue", - "image2": "Runite ore.png", - "label3": "Adamantite ore", - "low3": "-90", - "high3": "50", - "req3": "70", - "color3": "seagreen", - "image3": "Adamantite ore.png", - "label4": "Mithril ore", - "low4": "-19", - "high4": "90", - "req4": "55", - "color4": "slateblue", - "image4": "Mithril ore.png", - "label5": "Gold ore", - "low5": "-40", - "high5": "126", - "req5": "40", - "color5": "goldenrod", - "image5": "Gold ore.png", - "label6": "Coal", - "low6": "226", - "high6": "325", - "req6": "30", - "color6": "black", - "image6": "Coal.png" - } - ] - }, - { - "title": "Goreu", - "names": [ - "npcs.mourning_town_elf_1" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Caranthir", - "names": [ - "npcs.prif_citizen_caranthir" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Celebrian", - "names": [ - "npcs.prif_citizen_celebrian" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Celegorm", - "names": [ - "npcs.prif_citizen_celegorm" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Cirdan", - "names": [ - "npcs.prif_citizen_cirdan" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Curufin", - "names": [ - "npcs.prif_citizen_curufin" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Earwen", - "names": [ - "npcs.prif_citizen_earwen" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Edrahil", - "names": [ - "npcs.prif_citizen_edrahil" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Elenwe", - "names": [ - "npcs.prif_citizen_elenwe" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Elladan", - "names": [ - "npcs.prif_citizen_elladan" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Enel", - "names": [ - "npcs.prif_citizen_enel" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Enelye", - "names": [ - "npcs.prif_citizen_enelye" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Enerdhil", - "names": [ - "npcs.prif_citizen_enerdhil" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Erestor", - "names": [ - "npcs.prif_citizen_erestor" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Feanor", - "names": [ - "npcs.prif_citizen_feanor" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Findis", - "names": [ - "npcs.prif_citizen_findis" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Finduilas", - "names": [ - "npcs.prif_citizen_finduilas" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Fingolfin", - "names": [ - "npcs.prif_citizen_fingolfin" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Fingon", - "names": [ - "npcs.prif_citizen_fingon" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Galathil", - "names": [ - "npcs.prif_citizen_galathil" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Gelmir", - "names": [ - "npcs.prif_citizen_gelmir" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Glorfindel", - "names": [ - "npcs.prif_citizen_glorfindel" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Guilin", - "names": [ - "npcs.prif_citizen_guilin" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Hendor (elf)", - "names": [ - "npcs.prif_citizen_hendor" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Idril", - "names": [ - "npcs.prif_citizen_idril" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Imin", - "names": [ - "npcs.prif_citizen_imin" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Iminye", - "names": [ - "npcs.prif_citizen_iminye" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Indis", - "names": [ - "npcs.prif_citizen_indis" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Ingwe", - "names": [ - "npcs.prif_citizen_ingwe" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Ingwion", - "names": [ - "npcs.prif_citizen_ingwion" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Lenwe", - "names": [ - "npcs.prif_citizen_lenwe" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Lindir", - "names": [ - "npcs.prif_citizen_lindir" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Maeglin", - "names": [ - "npcs.prif_citizen_maeglin" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Mahtan", - "names": [ - "npcs.prif_citizen_mahtan" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Miriel", - "names": [ - "npcs.prif_citizen_miriel" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Mithrellas", - "names": [ - "npcs.prif_citizen_mithrellas" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Nellas", - "names": [ - "npcs.prif_citizen_nellas" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Nerdanel", - "names": [ - "npcs.prif_citizen_nerdanel" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Nimloth", - "names": [ - "npcs.prif_citizen_nimloth" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Oropher", - "names": [ - "npcs.prif_citizen_oropher" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Saeros", - "names": [ - "npcs.prif_citizen_saeros" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Salgant", - "names": [ - "npcs.prif_citizen_salgant" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Tatie", - "names": [ - "npcs.prif_citizen_tatie" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Thingol", - "names": [ - "npcs.prif_citizen_thingol" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Turgon", - "names": [ - "npcs.prif_citizen_turgon" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Vaire", - "names": [ - "npcs.prif_citizen_vaire" - ], - "entries": [ - { - "label": "Elf pickpocket chance", - "showbefore": "no", - "label1": "Normal", - "low1": "6", - "high1": "100", - "req1": "85", - "color1": "gray", - "image1": "Thief Elf.png", - "label2": "Gloves of silence", - "low2": "6", - "high2": "105", - "req2": "85", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "6", - "high3": "110", - "req3": "85", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "6", - "high4": "121", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - }, - { - "title": "Fishbowl (pet)", - "names": [ - "items.fishbowl_bluefish", - "items.fishbowl_greenfish", - "items.fishbowl_spinefish", - "npcs.poh_fishbowl_bluefish", - "npcs.poh_fishbowl_greenfish", - "npcs.poh_fishbowl_spinefish" - ], - "entries": [ - { - "label": "Pet fish catch rate", - "xlabel": "Fishing level", - "cascade": "yes", - "label1": "Spinefish", - "low1": "51", - "high1": "51", - "req1": "70", - "color1": "#ff9600", - "image1": "Fishbowl (orange).png", - "label2": "Greenfish", - "low2": "25", - "high2": "112", - "altlow2": "128", - "althigh2": "128", - "altreq2": "70", - "color2": "#00ff00", - "image2": "Fishbowl (green).png", - "label3": "Bluefish", - "low3": "255", - "high3": "255", - "color3": "#1ba5e3", - "image3": "Fishbowl (blue).png" - } - ] - }, - { - "title": "Tourist", - "names": [ - "npcs.varlamore_tourist_m_1", - "npcs.varlamore_tourist_m_2", - "npcs.varlamore_tourist_m_3", - "npcs.varlamore_tourist_f_1", - "npcs.varlamore_tourist_f_2", - "npcs.varlamore_tourist_f_3" - ], - "entries": [ - { - "label": "Tourist pickpocket chance", - "label1": "Normal", - "low1": "180", - "high1": "240", - "req1": "1", - "color1": "gray", - "image1": "Thief Man.png", - "label2": "Gloves of silence", - "low2": "189", - "high2": "252", - "req2": "1", - "color2": "darkblue", - "image2": "Gloves of silence.png", - "label3": "Ardougne Diary", - "low3": "198", - "high3": "264", - "req3": "1", - "color3": "black", - "image3": "Ardougne cloak 3.png", - "label4": "Thieving cape + Ardougne Diary", - "low4": "217", - "high4": "290", - "req4": "99", - "color4": "purple", - "image4": "Thieving cape.png" - } - ] - } -] \ No newline at end of file From a055a4f2f16450b7373ce72e98835e3e019805e0 Mon Sep 17 00:00:00 2001 From: voidstarr <3334013+voidstarr@users.noreply.github.com> Date: Thu, 19 Feb 2026 15:53:25 -0800 Subject: [PATCH 09/10] feat(cooking): add 143 new food items to FoodTable from OSRS wiki Add comprehensive food entries covering all cookable items from the Old School RuneScape wiki food table. New entries organized by category: - Basic fish (anchovies, sardine, cod, haddock, halibut, etc.) - Sailing fish (yellowfin, bluefin, marlin, swordtip squid, etc.) - Produce & fruits (banana, cabbage, potato, dragonfruit, pumpkin, etc.) - Cooked meats (rabbit, chompy, scrambled egg, wrapped oomlie) - Spit-roasted meats (bird, beast, rabbit) - Snails & spiders (3 snail variants, spider on stick/shaft) - Hunter meats (kebbit, larupia, graahk, kyatt variants) - Baked potatoes (plain, butter, cheese, chilli, egg, mushroom, tuna) - Bowl foods (stew, fried mushrooms, fried onions, egg+tomato) - Dorgesh-Kaan foods (bat shish, frog burger, green gloop soup, etc.) - Crab meats (red, blue, rainbow) - Drinks & ales (beer, wine, grog, stout, cider, etc.) - Gnome cocktails (blurberry, choc saturday, drunk dragon, etc.) - Miscellaneous (jubbly, sweetcorn, baguette, kebab, choc-ice, etc.) All RSCM item keys verified against gamevals.dat binary data. Includes reference CSV from wiki at docs/cooking/osrs_food_all.csv. Total food entries: 52 -> 195 --- .../kotlin/org/alter/impl/misc/FoodTable.kt | 143 +++++++ docs/cooking/osrs_food_all.csv | 351 ++++++++++++++++++ 2 files changed, 494 insertions(+) create mode 100644 docs/cooking/osrs_food_all.csv diff --git a/cache/src/main/kotlin/org/alter/impl/misc/FoodTable.kt b/cache/src/main/kotlin/org/alter/impl/misc/FoodTable.kt index eb39907b..21b12b6d 100644 --- a/cache/src/main/kotlin/org/alter/impl/misc/FoodTable.kt +++ b/cache/src/main/kotlin/org/alter/impl/misc/FoodTable.kt @@ -14,33 +14,176 @@ enum class Food( val combatDelay: List = listOf(), val dbRowId: String ) { + // Basic fish SHRIMPS("items.shrimp", heal = 3, dbRowId = "dbrows.shrimps_food"), + ANCHOVIES("items.anchovies", heal = 1, dbRowId = "dbrows.anchovies_food"), + SARDINE("items.sardine", heal = 4, dbRowId = "dbrows.sardine_food"), COOKED_CHICKEN("items.cooked_chicken", heal = 3, dbRowId = "dbrows.cooked_chicken_food"), COOKED_MEAT("items.cooked_meat", heal = 3, dbRowId = "dbrows.cooked_meat_food"), BREAD("items.bread", heal = 5, dbRowId = "dbrows.bread_food"), HERRING("items.herring", heal = 5, dbRowId = "dbrows.herring_food"), MACKEREL("items.mackerel", heal = 6, dbRowId = "dbrows.mackerel_food"), + COD("items.cod", heal = 7, dbRowId = "dbrows.cod_food"), TROUT("items.trout", heal = 7, dbRowId = "dbrows.trout_food"), PIKE("items.pike", heal = 8, dbRowId = "dbrows.pike_food"), PEACH("items.peach", heal = 8, dbRowId = "dbrows.peach_food"), SALMON("items.salmon", heal = 9, dbRowId = "dbrows.salmon_food"), TUNA("items.tuna", heal = 10, dbRowId = "dbrows.tuna_food"), + CAVE_EEL("items.cave_eel", heal = 10, dbRowId = "dbrows.cave_eel_food"), + LAVA_EEL("items.lava_eel", heal = 11, dbRowId = "dbrows.lava_eel_food"), JUG_OF_WINE("items.jug_wine", heal = 11, hasEffect = true, dbRowId = "dbrows.jug_of_wine_food"), LOBSTER("items.lobster", heal = 12, dbRowId = "dbrows.lobster_food"), BASS("items.bass", heal = 13, dbRowId = "dbrows.bass_food"), SWORDFISH("items.swordfish", heal = 14, dbRowId = "dbrows.swordfish_food"), + SWORDTIP_SQUID("items.swordtip_squid", heal = 15, dbRowId = "dbrows.swordtip_squid_food"), IXCOZTIC_WHITE("items.ixcoztic_white", heal = 16, hasEffect = true, dbRowId = "dbrows.ixcoztic_white_food"), POTATO_WITH_CHEESE("items.potato_cheese", heal = 16, dbRowId = "dbrows.potato_with_cheese_food"), MONKFISH("items.monkfish", heal = 16, dbRowId = "dbrows.monkfish_food"), + JUMBO_SQUID("items.jumbo_squid", heal = 17, dbRowId = "dbrows.jumbo_squid_food"), + GIANT_KRILL("items.giant_krill", heal = 17, dbRowId = "dbrows.giant_krill_food"), + HADDOCK("items.haddock", heal = 18, dbRowId = "dbrows.haddock_food"), CURRY("items.curry", "items.bowl_empty", heal = 19, dbRowId = "dbrows.curry_food"), COOKED_PYRE_FOX("items.curry", heal = 11, dbRowId = "dbrows.cooked_pyre_fox_food"), + UGTHANKI_KEBAB("items.ugthanki_kebab", heal = 19, dbRowId = "dbrows.ugthanki_kebab_food"), + YELLOWFIN("items.yellowfin", heal = 19, dbRowId = "dbrows.yellowfin_food"), SHARK("items.shark", heal = 20, dbRowId = "dbrows.shark_food"), + HALIBUT("items.halibut", heal = 20, dbRowId = "dbrows.halibut_food"), SEA_TURTLE("items.seaturtle", heal = 21, dbRowId = "dbrows.sea_turtle_food"), MANTA_RAY("items.mantaray", heal = 22, dbRowId = "dbrows.manta_ray_food"), TUNA_POTATO("items.potato_tuna+sweetcorn", heal = 22, dbRowId = "dbrows.tuna_potato_food"), DARK_CRAB("items.dark_crab", heal = 22, dbRowId = "dbrows.dark_crab_food"), + BLUEFIN("items.bluefin", heal = 22, dbRowId = "dbrows.bluefin_food"), + MARLIN("items.marlin", heal = 24, dbRowId = "dbrows.marlin_food"), + CAVEFISH("items.cavefish", heal = 20, dbRowId = "dbrows.cavefish_food"), + TETRA("items.tetra", heal = 22, dbRowId = "dbrows.tetra_food"), ANGLERFISH("items.anglerfish", heal = -1, overheal = true, dbRowId = "dbrows.anglerfish_food"), + + // Basic foods & produce ONION("items.onion", heal = 1, dbRowId = "dbrows.onion_food"), + POTATO("items.potato", heal = 1, dbRowId = "dbrows.potato_food"), + CABBAGE("items.cabbage", heal = 1, dbRowId = "dbrows.cabbage_food"), + BANANA("items.banana", heal = 2, dbRowId = "dbrows.banana_food"), + TOMATO("items.tomato", heal = 2, dbRowId = "dbrows.tomato_food"), + CHEESE("items.cheese", heal = 2, dbRowId = "dbrows.cheese_food"), + LEMON("items.lemon", heal = 2, dbRowId = "dbrows.lemon_food"), + ORANGE("items.orange", heal = 2, dbRowId = "dbrows.orange_food"), + LIME("items.lime", heal = 2, dbRowId = "dbrows.lime_food"), + PINEAPPLE("items.pineapple", heal = 2, dbRowId = "dbrows.pineapple_food"), + DWELLBERRIES("items.dwellberries", heal = 2, dbRowId = "dbrows.dwellberries_food"), + JANGERBERRIES("items.jangerberries", heal = 2, dbRowId = "dbrows.jangerberries_food"), + CAERULA_BERRIES("items.caerula_berries", heal = 2, dbRowId = "dbrows.caerula_berries_food"), + STRAWBERRY("items.strawberry", heal = 5, dbRowId = "dbrows.strawberry_food"), + WATERMELON_SLICE("items.watermelon_slice", heal = 2, dbRowId = "dbrows.watermelon_slice_food"), + PAPAYA_FRUIT("items.papaya", heal = 8, dbRowId = "dbrows.papaya_fruit_food"), + DRAGONFRUIT("items.dragonfruit", heal = 10, dbRowId = "dbrows.dragonfruit_food"), + CHOCOLATE_BAR("items.chocolate_bar", heal = 3, dbRowId = "dbrows.chocolate_bar_food"), + EDIBLE_SEAWEED("items.edible_seaweed", heal = 4, dbRowId = "dbrows.edible_seaweed_food"), + + // Cooked meats & misc + KEBAB("items.kebab", heal = 3, hasEffect = true, dbRowId = "dbrows.kebab_food"), + LOCUST_MEAT("items.locust_meat", heal = 3, dbRowId = "dbrows.locust_meat_food"), + ROE("items.brut_roe", heal = 3, dbRowId = "dbrows.roe_food"), + STEW("items.stew", "items.bowl_empty", heal = 11, dbRowId = "dbrows.stew_food"), + COOKED_RABBIT("items.cooked_rabbit", heal = 5, dbRowId = "dbrows.cooked_rabbit_food"), + COOKED_MYSTERY_MEAT("items.cooked_mystery_meat", heal = 5, dbRowId = "dbrows.cooked_mystery_meat_food"), + SCRAMBLED_EGG("items.scrambled_egg", heal = 5, dbRowId = "dbrows.scrambled_egg_food"), + CAVIAR("items.brut_caviar", heal = 5, dbRowId = "dbrows.caviar_food"), + BAGUETTE("items.baguette", heal = 6, dbRowId = "dbrows.baguette_food"), + SEASONED_SARDINE("items.seasoned_sardine", heal = 4, dbRowId = "dbrows.seasoned_sardine_food"), + GIANT_FROG_LEGS("items.giant_frog_legs", heal = 6, dbRowId = "dbrows.giant_frog_legs_food"), + COOKED_CHOMPY("items.cooked_chompy", heal = 10, dbRowId = "dbrows.cooked_chompy_food"), + CHOC_ICE("items.elid_choc_ice", heal = 7, dbRowId = "dbrows.choc_ice_food"), + PUMPKIN("items.pumpkin", heal = 14, dbRowId = "dbrows.pumpkin_food"), + EASTER_EGG("items.easter_egg", heal = 14, dbRowId = "dbrows.easter_egg_food"), + WRAPPED_OOMLIE("items.wrapped_oomlie", heal = 14, dbRowId = "dbrows.wrapped_oomlie_food"), + COOKED_SWEETCORN("items.sweetcorn_cooked", heal = 10, dbRowId = "dbrows.cooked_sweetcorn_food"), + + // Roast meats (spit-roasted) + ROAST_BIRD_MEAT("items.spit_roasted_bird_meat", heal = 6, dbRowId = "dbrows.roast_bird_meat_food"), + ROAST_RABBIT("items.spit_roasted_rabbit_meat", heal = 7, dbRowId = "dbrows.roast_rabbit_food"), + ROAST_BEAST_MEAT("items.spit_roasted_beast_meat", heal = 8, dbRowId = "dbrows.roast_beast_meat_food"), + + // Snails + THIN_SNAIL_MEAT("items.snail_corpse_cooked1", heal = 5, dbRowId = "dbrows.thin_snail_meat_food"), + LEAN_SNAIL_MEAT("items.snail_corpse_cooked2", heal = 6, dbRowId = "dbrows.lean_snail_meat_food"), + FAT_SNAIL_MEAT("items.snail_corpse_cooked3", heal = 8, dbRowId = "dbrows.fat_snail_meat_food"), + + // Spider on stick/shaft + SPIDER_ON_STICK("items.tbw_spider_on_stick_cooked", heal = 7, dbRowId = "dbrows.spider_on_stick_food"), + SPIDER_ON_SHAFT("items.tbw_spider_on_shaft_cooked", heal = 7, dbRowId = "dbrows.spider_on_shaft_food"), + + // Cooked jubbly + COOKED_JUBBLY("items.100_jubbly_meat_cooked", heal = 15, dbRowId = "dbrows.cooked_jubbly_food"), + + // Hunter meats + COOKED_WILD_KEBBIT("items.wildkebbit_cooked", heal = 4, dbRowId = "dbrows.cooked_wild_kebbit_food"), + COOKED_LARUPIA("items.larupia_cooked", heal = 6, dbRowId = "dbrows.cooked_larupia_food"), + COOKED_BARB_TAILED_KEBBIT("items.barbkebbit_cooked", heal = 7, dbRowId = "dbrows.cooked_barb_tailed_kebbit_food"), + COOKED_GRAAHK("items.graahk_cooked", heal = 8, dbRowId = "dbrows.cooked_graahk_food"), + COOKED_KYATT("items.kyatt_cooked", heal = 9, dbRowId = "dbrows.cooked_kyatt_food"), + COOKED_DASHING_KEBBIT("items.dashingkebbit_cooked", heal = 13, dbRowId = "dbrows.cooked_dashing_kebbit_food"), + + // Potatoes + BAKED_POTATO("items.potato_baked", heal = 4, dbRowId = "dbrows.baked_potato_food"), + POTATO_WITH_BUTTER("items.potato_butter", heal = 14, dbRowId = "dbrows.potato_with_butter_food"), + CHILLI_POTATO("items.potato_chilli+carne", heal = 14, dbRowId = "dbrows.chilli_potato_food"), + EGG_POTATO("items.potato_egg+tomato", heal = 16, dbRowId = "dbrows.egg_potato_food"), + MUSHROOM_POTATO("items.potato_mushroom+onion", heal = 20, dbRowId = "dbrows.mushroom_potato_food"), + + // Bowls + BOWL_OF_CHILLI_CON_CARNE("items.bowl_chilli+carne", "items.bowl_empty", heal = 5, dbRowId = "dbrows.bowl_of_chilli_con_carne_food"), + EGG_AND_TOMATO("items.bowl_egg+tomato", "items.bowl_empty", heal = 8, dbRowId = "dbrows.egg_and_tomato_food"), + MUSHROOM_AND_ONION("items.bowl_mushroom+onion", "items.bowl_empty", heal = 11, dbRowId = "dbrows.mushroom_and_onion_food"), + TUNA_AND_CORN("items.bowl_tuna+sweetcorn", "items.bowl_empty", heal = 13, dbRowId = "dbrows.tuna_and_corn_food"), + + // Dorgesh-Kaan foods + BAT_SHISH("items.dorgesh_bat_shish", heal = 2, dbRowId = "dbrows.bat_shish_food"), + GREEN_GLOOP_SOUP("items.dorgesh_green_gloop_soup", heal = 2, dbRowId = "dbrows.green_gloop_soup_food"), + FROG_SPAWN_GUMBO("items.dorgesh_frog_spawn_gumbo", heal = 3, dbRowId = "dbrows.frog_spawn_gumbo_food"), + FRIED_MUSHROOMS("items.bowl_mushroom_fried", "items.bowl_empty", heal = 5, dbRowId = "dbrows.fried_mushrooms_food"), + SAUTEED_MUSHROOMS("items.dorgesh_sauteed_mushrooms", heal = 6, dbRowId = "dbrows.sauteed_mushrooms_food"), + CAVE_EEL_SUSHI("items.dorgesh_cave_eel_sushi", heal = 7, dbRowId = "dbrows.cave_eel_sushi_food"), + FROG_BURGER("items.dorgesh_frog_burger", heal = 6, dbRowId = "dbrows.frog_burger_food"), + + // Crab meats + RED_CRAB_MEAT("items.red_crab_meat", heal = 8, dbRowId = "dbrows.red_crab_meat_food"), + BLUE_CRAB_MEAT("items.blue_crab_meat", heal = 14, dbRowId = "dbrows.blue_crab_meat_food"), + RAINBOW_CRAB_MEAT("items.rainbow_crab_meat", heal = 19, dbRowId = "dbrows.rainbow_crab_meat_food"), + + // Drinks & ales (most have stat effects) + BEER("items.beer", "items.beer_glass", heal = 1, hasEffect = true, dbRowId = "dbrows.beer_food"), + ASGARNIAN_ALE("items.asgarnian_ale", "items.beer_glass", heal = 1, hasEffect = true, dbRowId = "dbrows.asgarnian_ale_food"), + WIZARDS_MIND_BOMB("items.wizards_mind_bomb", "items.beer_glass", heal = 1, hasEffect = true, dbRowId = "dbrows.wizards_mind_bomb_food"), + GREENMANS_ALE("items.greenmans_ale", "items.beer_glass", heal = 1, hasEffect = true, dbRowId = "dbrows.greenmans_ale_food"), + DRAGON_BITTER("items.dragon_bitter", "items.beer_glass", heal = 1, hasEffect = true, dbRowId = "dbrows.dragon_bitter_food"), + DWARVEN_STOUT("items.dwarven_stout", "items.beer_glass", heal = 1, hasEffect = true, dbRowId = "dbrows.dwarven_stout_food"), + CIDER("items.cider", "items.beer_glass", heal = 1, hasEffect = true, dbRowId = "dbrows.cider_food"), + AXEMANS_FOLLY("items.axemans_folly", "items.beer_glass", heal = 1, hasEffect = true, dbRowId = "dbrows.axemans_folly_food"), + CHEFS_DELIGHT("items.chefs_delight", "items.beer_glass", heal = 1, hasEffect = true, dbRowId = "dbrows.chefs_delight_food"), + SLAYERS_RESPITE("items.slayers_respite", "items.beer_glass", heal = 1, hasEffect = true, dbRowId = "dbrows.slayers_respite_food"), + GROG("items.grog", heal = 3, hasEffect = true, dbRowId = "dbrows.grog_food"), + VODKA("items.vodka", heal = 5, hasEffect = true, dbRowId = "dbrows.vodka_food"), + WHISKY("items.whisky", heal = 5, hasEffect = true, dbRowId = "dbrows.whisky_food"), + GIN("items.gin", heal = 5, hasEffect = true, dbRowId = "dbrows.gin_food"), + BRANDY("items.brandy", heal = 5, hasEffect = true, dbRowId = "dbrows.brandy_food"), + KEG_OF_BEER("items.keg_of_beer", heal = 1, hasEffect = true, dbRowId = "dbrows.keg_of_beer_food"), + KOVACS_GROG("items.kovacs_grog", heal = 3, hasEffect = true, dbRowId = "dbrows.kovacs_grog_food"), + + // Gnome cocktails (combo foods) + FRUIT_BLAST("items.fruit_blast", heal = 9, comboFood = true, eatDelay = listOf(2), combatDelay = listOf(3), dbRowId = "dbrows.fruit_blast_food"), + PREMADE_FRUIT_BLAST("items.premade_fruit_blast", heal = 9, comboFood = true, eatDelay = listOf(2), combatDelay = listOf(3), dbRowId = "dbrows.premade_fruit_blast_food"), + PINEAPPLE_PUNCH("items.pineapple_punch", heal = 9, comboFood = true, eatDelay = listOf(2), combatDelay = listOf(3), dbRowId = "dbrows.pineapple_punch_food"), + PREMADE_PINEAPPLE_PUNCH("items.premade_pineapple_punch", heal = 9, comboFood = true, eatDelay = listOf(2), combatDelay = listOf(3), dbRowId = "dbrows.premade_pineapple_punch_food"), + SHORT_GREEN_GUY("items.sgg", heal = 5, comboFood = true, eatDelay = listOf(2), combatDelay = listOf(3), dbRowId = "dbrows.short_green_guy_food"), + PREMADE_SGG("items.premade_sgg", heal = 5, comboFood = true, eatDelay = listOf(2), combatDelay = listOf(3), dbRowId = "dbrows.premade_sgg_food"), + BLURBERRY_SPECIAL("items.blurberry_special", heal = 7, comboFood = true, eatDelay = listOf(2), combatDelay = listOf(3), dbRowId = "dbrows.blurberry_special_food"), + PREMADE_BLURBERRY_SPECIAL("items.premade_blurberry_special", heal = 7, comboFood = true, eatDelay = listOf(2), combatDelay = listOf(3), dbRowId = "dbrows.premade_blurberry_special_food"), + DRUNK_DRAGON("items.drunk_dragon", heal = 5, comboFood = true, eatDelay = listOf(2), combatDelay = listOf(3), dbRowId = "dbrows.drunk_dragon_food"), + PREMADE_DRUNK_DRAGON("items.premade_drunk_dragon", heal = 5, comboFood = true, eatDelay = listOf(2), combatDelay = listOf(3), dbRowId = "dbrows.premade_drunk_dragon_food"), + WIZARD_BLIZZARD("items.wizard_blizzard", heal = 5, comboFood = true, eatDelay = listOf(2), combatDelay = listOf(3), dbRowId = "dbrows.wizard_blizzard_food"), + PREMADE_WIZARD_BLIZZARD("items.premade_wizard_blizzard", heal = 5, comboFood = true, eatDelay = listOf(2), combatDelay = listOf(3), dbRowId = "dbrows.premade_wizard_blizzard_food"), + CHOCOLATE_SATURDAY("items.aluft_choc_saturday", heal = 5, comboFood = true, eatDelay = listOf(2), combatDelay = listOf(3), dbRowId = "dbrows.chocolate_saturday_food"), + PREMADE_CHOC_SATURDAY("items.premade_choc_saturday", heal = 5, comboFood = true, eatDelay = listOf(2), combatDelay = listOf(3), dbRowId = "dbrows.premade_choc_saturday_food"), // Cakes CAKE( diff --git a/docs/cooking/osrs_food_all.csv b/docs/cooking/osrs_food_all.csv new file mode 100644 index 00000000..2d21cda7 --- /dev/null +++ b/docs/cooking/osrs_food_all.csv @@ -0,0 +1,351 @@ +Name,Heals,Skills_Needed,Notes,GP_Per_Heal,Price,Members +Cup of tea,3,5,Boosts Attack by 2% + 2,28.33,85,1 +Bruised banana,0,,Taken from the spooky cauldron behind Zaff's Superior Staves. It was used in the 2022 and 2023 Halloween events.,N/A,N/A,0 +Tea flask,3 × 5,,Reusable item obtained via Creature CreationMust be filled with Cups of teaBoosts Attack by 3[confirmation needed],N/A,N/A,1 +Poison chalice,Random,,Has a chance to apply a variety of random effects which can be beneficial or harmfulHas a chance to either heal or severely harm the player,"75.93 – 1,063","1,063",1 +Caerula berries,2,,"Found in Caerula bushes, found north of the Twilight Temple",N/A,N/A,1 +Jangerberries,2,,,186.50,373,1 +Shrimps,3,1 1,Caught via small net fishing.,9.00,27,0 +Anchovies,1,,,58.00,58,0 +Sardine,4,1 5,Caught via bait fishing.,5.50,22,0 +Salmon,9,25 30,Caught via fly fishing.,6.89,62,0 +Trout,7,15 20,Caught via fly fishing.,5.00,35,0 +Giant carp,6,,,N/A,N/A,1 +Cod,7,18 23,Caught via big net fishing.,4.57,32,1 +Herring,5,5 10,Caught via bait fishing.,14.00,70,0 +Pike,8,20 25,Caught via bait fishing.,23.25,186,0 +Mackerel,6,10 16,Caught via big net fishing.,5.33,32,1 +Tuna,10,30 35,Caught with a harpoon.,8.90,89,0 +Bass,13,43 46,Caught via big net fishing.,7.08,92,1 +Swordfish,14,45 50,Caught with a harpoon.,14.50,203,0 +Lobster,12,40 40,Caught with a lobster pot.,12.50,150,0 +Shark,20,80 76,Caught with a harpoon or traded for with minnows.,41.30,826,1 +Manta ray,22,91 81,"Can be caught with fishing from Fishing Trawler minigame, drift net fishing, Tempoross Drops from Zulrah, Vorkath, and the Tombs of Amascut.",78.05,"1,717",1 +Sea turtle,21,82 79,"Can only be obtained from the Fishing Trawler minigame, Tempoross, and drift net fishing.",53.95,"1,133",1 +Edible seaweed,4,,,13.00,52,1 +Karamjan rum,5,,,6.00,30,0 +Cup of tea (nettle),3,20,restores 5% Run Energy,N/A,N/A,1 +Tenti pineapple,2 × 4,,Quest item that can act as a normal Pineapple,N/A,N/A,1 +Ugthanki meat,3,,Better used as an ingredient to make Ugthanki kebabs,334.00,"1,002",1 +Chopped tomato,2,,,31.50,63,1 +Chopped onion,1,,,110.00,110,1 +Onion & tomato,3,,,5.33,16,1 +Ugthanki kebab,19,58,"The player's character will say ""Yum!"" when eaten.",31.68,602,1 +Ugthanki kebab (bad),0,58,Can sometimes heal 9Can still be used to make a Super kebab,N/A,N/A,1 +Cake,4 × 3,40,"Baked by players, see Cooking skill.Heals 4 Hitpoints per bite (3 bites total).Can be stolen from East Ardougne, Keldagrim, Kourend Castle and Hosidius Farmers' Market.",22.25,267,0 +Chocolate cake,5 × 3,50,"Made by adding chocolate dust to cake.Heals 5 Hitpoints per bite (3 bites total).1/3 Slice can be thieved from bakery stalls, except the Sophanem one.",24.67,370,0 +Asgarnian ale,1,,,110.00,110,0 +Wizard's mind bomb,1,,,119.00,119,0 +Greenman's ale,1,,,235.00,235,1 +Dragon bitter,1,,,428.00,428,1 +Dwarven stout,1,,,114.00,114,0 +Grog,3,,,112.67,338,1 +Beer,1,,,85.00,85,0 +Potato,1,,,20.00,20,0 +Onion,1,,,15.00,15,0 +Pumpkin,14,,,866.07,"12,125",0 +Easter egg,14,,,551.00,"7,714",0 +Banana,2,,,23.50,47,0 +Cabbage,1,,,21.00,21,0 +Spinach roll,2,,,45.50,91,0 +Kebab,3 + 7%,,"Amount healed uses most likely resultCan heal 0 or up to 7 + 24%Rare chances to apply buffs, drains, or no effects at all",2.45 – 49,49,0 +Chocolate bar,3,,,13.00,39,0 +Chocolatey milk,4,,,N/A,N/A,1 +Tomato,2,,,9.50,19,0 +Cheese,2,,,26.00,52,0 +Half full wine jug,7,,,"2,196.14","15,373",0 +Jug of wine,11[3],35,"Upon consumption, Attack is temporarily decreased by 2 points and leaves a jug behind.",0.36,4,0 +Stew,11,25,"Once eaten, an empty bowl remains in the inventory.",5.45,60,0 +Damiana tea,4,36,Also heals for 6 run energy.,N/A,N/A,1 +Damiana tea (milky),4,N/A,Also heals for 6 run energy.,N/A,N/A,1 +Cup of tea (damiana),4,36,Also heals for 6 run energy.,N/A,N/A,1 +Cup of tea (milky damiana),4,N/A,Also heals for 6 run energy.,N/A,N/A,1 +Curry,19,60,"Commonly used for fighting the Chaos Elemental. Once eaten, an empty bowl remains in the inventory.",18.89,359,1 +Vodka,5,,,21.20,106,1 +Whisky,5,,,26.80,134,1 +Gin,5,,,34.40,172,1 +Brandy,5,,,25.60,128,1 +Premade blurb' sp.,7,,,92.86,650,1 +Premade choc s'dy,5,,,11.60,58,1 +Premade dr' dragon,5,,,6.40,32,1 +Premade fr' blast,9,,,3.89,35,1 +Premade p' punch,9,8,Purchased at Tree gnome stronghold,3.11,28,1 +Premade sgg,5,,,5.40,27,1 +Premade wiz blz'd,5,,,5.20,26,1 +Pineapple punch,9,8,See Gnome cooking for more information.,11.33,102,1 +Wizard blizzard,5,,,21.20,106,1 +Blurberry special,7,,,589.86,"4,129",1 +Choc saturday,5,,,13.80,69,1 +Short green guy,5,,,19.60,98,1 +Fruit blast,9,,,270.00,"2,430",1 +Drunk dragon,5,,,14.80,74,1 +Lemon,2,,,37.00,74,1 +Lemon chunks,2,,,58.00,116,1 +Lemon slices,2,,,67.00,134,1 +Orange,2,,,85.50,171,1 +Orange chunks,2,,,46.50,93,1 +Orange slices,2,,,160.50,321,1 +Pineapple,2 × 4,,,22.75,182,1 +Pineapple chunks,2,,,82.00,164,1 +Pineapple ring,2,,,41.00,82,1 +Lime,2,,,36.50,73,1 +Lime chunks,2,,,93.00,186,1 +Lime slices,2,,,89.50,179,1 +Dwellberries,2,,,22.00,44,1 +Equa leaves,1,,,370.00,370,1 +Pot of cream,1,,,10.00,10,1 +Cooked chicken,3,1,Raw chicken is obtained by killing chickens.,25.00,75,0 +Cooked meat,3,1,Raw meat can be obtained by killing cows or giant rats.,26.33,79,0 +Lava eel,11,,,N/A,N/A,1 +Toad's legs,3,,,147.00,441,1 +King worm,2,,,261.50,523,1 +Chocolate bomb,15,42,Made using Gnome cooking,48.60,729,1 +Tangled toad's legs,15,40,Made using Gnome cooking,55.47,832,1 +Worm hole,12,30,Made using Gnome cooking,312.17,"3,746",1 +Veg ball,12,36,Made using Gnome cooking,174.25,"2,091",1 +Worm crunchies,8,14,Made using Gnome cooking,468.88,"3,751",1 +Chocchip crunchies,7,16,Made using Gnome cooking,277.00,"1,939",1 +Spicy crunchies,7,12,Made using Gnome cooking,305.43,"2,138",1 +Toad crunchies,8,10,Made using Gnome cooking,598.13,"4,785",1 +Premade w'm batta,11,N/A,Purchased from Gnome waiter in the Grand tree for 120,4.00,44,1 +Premade t'd batta,11,N/A,Purchased from Gnome waiter in the Grand tree for 120,3.91,43,1 +Premade c+t batta,11,N/A,Purchased from Gnome waiter in the Grand tree for 120,4.36,48,1 +Premade fr't batta,11,N/A,Purchased from Gnome waiter in the Grand tree for 120,3.91,43,1 +Premade veg batta,11,N/A,Purchased from Gnome waiter in the Grand tree for 120,3.91,43,1 +Premade choc bomb,15,N/A,Purchased from Gnome waiter in the Grand tree for 160,8.20,123,1 +Premade ttl,15,N/A,Purchased from Gnome waiter in the Grand tree for 160,6.13,92,1 +Premade worm hole,12,N/A,Purchased from Gnome waiter in the Grand tree for 150,4.33,52,1 +Premade veg ball,12,N/A,Purchased from Gnome waiter in the Grand tree for 120,4.17,50,1 +Premade w'm crun',8,N/A,Purchased from Gnome waiter in the Grand tree for 85,5.88,47,1 +Premade ch' crunch,8,N/A,Purchased from Gnome waiter in the Grand tree for 85,6.88,55,1 +Premade s'y crunch,7,N/A,Purchased from Gnome waiter in the Grand tree for 85,6.71,47,1 +Premade t'd crunch,8,N/A,Purchased from Gnome waiter in the Grand tree for 85,125.88,"1,007",1 +Worm batta,11,27,"Made using Gnome cooking, Dropped by Tortoise",212.09,"2,333",1 +Toad batta,11,26,Made using Gnome cooking,130.55,"1,436",1 +Cheese+tom batta,11,29,Made using Gnome cooking,183.00,"2,013",1 +Fruit batta,11,25,Made using Gnome cooking,340.18,"3,742",1 +Vegetable batta,11,28,Made using Gnome cooking,294.18,"3,236",1 +Plain pizza,7 × 2,35,"Baked by players, see cooking skill.Heals 7 Hitpoints per bite (2 bites total).",26.93,377,0 +Meat pizza,8 × 2,45,Made by using cooked meat or chicken on a plain pizza.Heals 8 Hitpoints per bite (2 bites total).,17.50,280,0 +Anchovy pizza,9 × 2,55,Made by using anchovies on a plain pizza.Heals 9 Hitpoints per bite (2 bites total).,25.56,460,0 +Pineapple pizza,11 × 2,65,Made by using pineapple chunks or rings on a plain pizza.Heals 11 Hitpoints per bite (2 bites total).,28.32,623,1 +Bread,5,1,"Baked by players, see Cooking skill.",36.20,181,0 +Apple pie,7 × 2,30,Made by using a cooking apple on a pie shell to make an uncooked apple pie and cooking it.Heals 7 Hitpoints per bite (2 bites total).,7.86,110,0 +Chichilihui rosé,16,,"Purchased from Moonrise Wines for 100 gp. Upon consumption, Attack is temporarily decreased by 5, Farming by 1, and Herblore is temporarily boosted by 1.",18.13,290,1 +Ixcoztic white,16,,"Purchased from Moonrise Wines for 100 gp. Upon consumption, Attack is temporarily decreased by 5, Herblore by 1, and Farming is temporarily boosted by 1.",10.69,171,1 +Redberry pie,5 × 2,10,"Baked by players, see Cooking skill.Heals 5 Hitpoints per bite (2 bites total).",20.20,202,0 +Meat pie,6 × 2,20,"Baked by players, see Cooking skill.Heals 6 Hitpoints per bite (2 bites total).",3.75,45,0 +Cooked oomlie wrap,14,,,416.86,"5,836",1 +Cooked chompy,11,,,6.55,72,1 +Moonlight mead,4,,,28.25,113,1 +Cooked karambwan,18,30 65,"A karambwan vessel and completion of Tai Bwo Wannai Trio required to fish and cook it properly.Can be eaten in the same tick as another piece of food, allowing for combo eating.Shorter attack delay than most other food (2 ticks instead of 4).",28.33,510,1 +Sliced banana,2,,,20.50,41,0 +Cooked rabbit,5,,,46.20,231,1 +Thin snail meat,5 – 7,,,64.57 – 90.40,452,1 +Lean snail meat,5 – 8,,,441.13 – 705.80,"3,529",1 +Fat snail meat,7 – 9,,,281.89 – 362.43,"2,537",1 +Cooked slimy eel,6 – 10,,,2.70 – 4.50,27,1 +Keg of beer,15,,,47.07,706,1 +Beer tankard,4,,,98.75,395,1 +Monkey nuts,4,,,40.50,162,1 +Monkey bar,5,,,136.80,684,1 +Banana stew,11,N/A,"Once eaten, an empty bowl remains in the inventory.",3.36,37,1 +Nettle-water,1,,,N/A,N/A,1 +Nettle tea,3,,,N/A,N/A,1 +Guthix rest,5 × 4,18,Requires partial completion of One Small Favour to make and consume.Can boost 5 Hitpoints above max. Restores 5% run energy and reduces poison/venom damage by 1.It is not considered food as it is a potion made with the Herblore skill. Will not increase the delay until your next attack.,145.75,"2,915",1 +White pearl,2,,,N/A,N/A,1 +Giant frog legs,6,,,771.33,"4,628",1 +Purple sweets,1 – 3,N/A,The only stackable food item in the game.,"2,143.00 – 6,429.00","6,429",1 +Super kebab,3 + 7%,N/A,Amount healed is most likely resultUncommon chance to heal 0Rare chance to drain a random skill by -3,168.90 – 563.00,"1,689",1 +Bandit's brew,1,,,"2,088.00","2,088",1 +Cave eel,8 – 12,,,7.75 – 11.63,93,1 +Frog spawn,3 – 6,,,N/A,N/A,1 +Strawberry,1 – 6,,1 + 6% of maximum Hitpoints,18.50 – 111.00,111,1 +Basket of strawberries,(1 - 6) × 5,31,"Contains 5 strawberries, each of which heals 1-6 Hitpoints (1 + 6% of hp).Strawberry spawn at Shayziens' Wall in Great Kourend for no requirements.",13.83 – 83.00,415,1 +Asgarnian ale(m),2,,,"11,790.00","23,580",1 +Mature wmb,2,,,"13,832.00","27,664",1 +Greenman's ale(m),2,,,"29,816.50","59,633",1 +Dragon bitter(m),2,,,357.50,715,1 +Dwarven stout(m),2,,,"8,056.50","16,113",1 +Moonlight mead(m),6,,,915.67,"5,494",1 +Axeman's folly,1,,,248.00,248,1 +Axeman's folly(m),2,,,"25,145.50","50,291",1 +Chef's delight,1,,,284.00,284,1 +Chef's delight(m),2,,,"21,012.50","42,025",1 +Slayer's respite,1,,,40.00,40,1 +Slayer's respite(m),2,,,"19,594.00","39,188",1 +Cider,1,,,121.00,121,1 +Mature cider,2,,,"87,350.00","174,700",1 +Greenmans ale(4),1 × 4,,,"5,932.75","23,731",1 +Mind bomb(4),1 × 4,,,"8,725.00","34,900",1 +Dwarven stout(m4),2 × 4,,,"28,215.00","225,720",1 +Asgarnian ale(m4),2 × 4,,,691.50,"5,532",1 +Greenmans ale(m4),2 × 4,,,"2,247.34","193,271",1 +Mind bomb(m4),2 × 4,,,"3,825.38","30,603",1 +Dragon bitter(m4),2 × 4,,,"2,325.13","18,601",1 +Moonlight mead(m4),6 × 4,,,"5,730.00","137,520",1 +Axeman's folly(m4),2 × 4,,,"27,431.50","219,452",1 +Chef's delight(m4),2 × 4,,,"25,345.13","202,761",1 +Slayer's respite(m4),2 × 4,,,"24,659.63","197,277",1 +Cider(m4),2 × 4,,,"10,966.75","87,734",1 +Papaya fruit,8,,,206.25,"1,650",1 +Watermelon,(1 - 5) × 3,47,Must be sliced with a knife before eating.Heals for Hitpoints*120+1 per slice.,1.27 – 6.33,19,1 +Watermelon slice,1 – 5,47,Heals for Hitpoints*120+1 per slice.,15.80 – 79.00,79,1 +Cooked sweetcorn,1 – 10,,"1+10% of total hitpoints, rounded down",12.90 – 129.00,129,1 +Spider on stick,7 – 10,,,33.50 – 47.86,335,1 +Spider on shaft,7 – 10,,,27.90 – 39.86,279,1 +Gout tuber,12,,,"72,961.08","875,533",1 +White tree fruit,3,,,N/A,N/A,1 +Saradomin brew,(3 - 16) × 4,81,"Drunk in 4 sips, each healing for Hitpoints*15100+2 and can boost health above the maximum value.Due to it lowering offensive stats, it is typically used with super restore potions.It is not considered food as it is a potion made with the Herblore skill.Will not increase the delay before your next attack.",128.45 – 685.08,"8,221",1 +Armadyl brew,(3 - 11) × 4,89,"Drunk in 4 sips, each healing for Hitpoints*10100+2 and can boost health above the maximum value.Due to it lowering offensive stats, it is typically used with super restore potions.It is not considered food as it is a potion made with the Herblore skill.Will not increase the delay before your next attack.",62.70 – 229.92,"2,759",1 +Baked potato,4,,,42.50,170,1 +Potato with butter,14,39,Made by using pat of butter on a baked potato.,22.29,312,1 +Potato with cheese,16,47,Made by using cheese on a potato with butter.,15.50,248,1 +Choc-ice,7,N/A,Can be bought from Rokuh in Nardah. Negates damage from desert heat.,21.29,149,1 +Peach,8,,,N/A,N/A,1 +Baguette,6,,,N/A,N/A,0 +Triangle sandwich,6,,,92.50,555,0 +Roll,6,,,N/A,N/A,0 +Square sandwich,6,,,N/A,N/A,0 +Chilli potato,14,,,14.57,204,1 +Egg potato,16,,,15.94,255,1 +Mushroom potato,20,64,Made by using mushroom & onion on a potato with butter.,42.10,842,1 +Tuna potato,22,68,Made by using tuna and corn on a potato with butter.,80.05,"1,761",1 +Chilli con carne,5,,,8.20,41,1 +Egg and tomato,8,,,22.25,178,1 +Mushroom & onion,11,,,29.27,322,1 +Tuna and corn,13,,,76.85,999,1 +Minced meat,13,,,23.08,300,1 +Spicy sauce,2,,,380.50,761,1 +Scrambled egg,5,,,7.20,36,1 +Fried mushrooms,5,,,13.80,69,1 +Fried onions,5,,,5.80,29,1 +Chopped tuna,10,,,27.40,274,1 +Braindeath 'rum',14,,,2.14,30,1 +Garden pie,6 × 2,34,Made using CookingTemporary Farming boost of +3 Both slices are a 1-tick eat delay.,7.33,88,1 +Fish pie,6 × 2,47,Made using CookingTemporary Fishing boost of +3 Both slices are a 1-tick eat delay.,18.33,220,1 +Admiral pie,8 × 2,70,Heals 8 Hitpoints per bite (2 bites total).Boosts Fishing by 5.,5.94,95,1 +Wild pie,11 × 2,85,"Heals 11 Hitpoints per bite (2 bites total).Boosts Slayer by 5, and Ranged by 4.",28.91,636,1 +Summer pie,11 × 2,95,"Heals 11 Hitpoints per bite (2 bites total).Boosts Agility by 5, and restores 10% run energy.",36.91,812,1 +Roast rabbit,7,,,13.14,92,1 +Spicy stew,0,,,N/A,N/A,1 +Cooked giant crab meat,2 × 5,21,Made using CookingAll five bites have 2-tick eat/attack delay.,134.70,"1,347",1 +Cooked fishcake,11,,,N/A,N/A,1 +Cooked jubbly,15,,,67.53,"1,013",1 +Red banana,5,,,N/A,N/A,1 +Tchiki monkey nuts,5,,,N/A,N/A,1 +Sliced red banana,5,,,N/A,N/A,1 +Stuffed snake,20,,,N/A,N/A,1 +Bottle of wine,14,,,46.93,657,1 +Field ration,10,,,N/A,N/A,1 +Fresh monkfish,1,,,N/A,N/A,1 +Monkfish,16,62 62,Caught via small net fishing in Piscatoris Fishing Colony after the completion of the Swan Song.,17.94,287,1 +Locust meat,3,,,18.33,55,1 +Roast bird meat,6,,,2.67,16,1 +Roast beast meat,8,21,An iron spit must be used along with a fire to cook it.,2.88,23,1 +Spicy tomato,2,,,305.00,610,1 +Spicy minced meat,3,,,208.67,626,1 +Rainbow fish,11,35 38,Caught via fly fishing by using stripy feathers.,9.09,100,1 +Spring sq'irkjuice,0[confirmation needed],25,Created via Sorceress's Garden+1 Thieving and restores 10% Run Energy,N/A,N/A,1 +Summer sq'irkjuice,0[confirmation needed],65,Created via Sorceress's Garden+3 Thieving and restores 20% Run Energy,N/A,N/A,1 +Autumn sq'irkjuice,0[confirmation needed],45,Created via Sorceress's Garden+2 Thieving and restores 15% Run Energy,N/A,N/A,1 +Winter sq'irkjuice,0[confirmation needed],1,Created via Sorceress's GardenRestores 5% Run Energy,N/A,N/A,1 +Green gloop soup,2,,,N/A,N/A,1 +Frogspawn gumbo,2,,,N/A,N/A,1 +Frogburger,2,,,N/A,N/A,1 +Coated frogs' legs,2,,,N/A,N/A,1 +Bat shish,2,,,N/A,N/A,1 +Fingers,2,,,N/A,N/A,1 +Grubs à la mode,2,,,N/A,N/A,1 +Roast frog,2,,,N/A,N/A,1 +Mushrooms,2,,,N/A,N/A,1 +Fillets,2,,,N/A,N/A,1 +Loach,3,,,N/A,N/A,1 +Eel sushi,10,,,N/A,N/A,1 +Roe,3,,,32.67,98,1 +Caviar,5,,,12.40,62,1 +Attack mix(2),3 × 2,,,19.00,114,1 +Antipoison mix(2),3 × 2,,,36.00,216,1 +Relicym's mix(2),3 × 2,,,78.50,471,1 +Strength mix(2),3 × 2,,,10.00,60,1 +Combat mix(2),3 × 2,,,38.50,231,1 +Restore mix(2),3 × 2,,,15.67,94,1 +Energy mix(2),3 × 2,,,44.67,268,1 +Defence mix(2),6 × 2,,,7.17,86,1 +Agility mix(2),6 × 2,,,26.17,314,1 +Prayer mix(2),6 × 2,,,318.58,"3,823",1 +Superattack mix(2),6 × 2,,,20.92,251,1 +Anti-poison supermix(2),6 × 2,,,112.08,"1,345",1 +Fishing mix(2),6 × 2,,,9.08,109,1 +Super energy mix(2),6 × 2,,,166.50,"1,998",1 +Super str. mix(2),6 × 2,,,100.50,"1,206",1 +Magic essence mix(2),6 × 2,,,210.58,"2,527",1 +Super restore mix(2),6 × 2,,,198.92,"2,387",1 +Super def. mix(2),6 × 2,,,127.75,"1,533",1 +Antidote+ mix(2),6 × 2,,,120.92,"1,451",1 +Antifire mix(2),6 × 2,,,11.67,140,1 +Ranging mix(2),6 × 2,,,105.75,"1,269",1 +Magic mix(2),6 × 2,,,8.58,103,1 +Hunting mix(2),6 × 2,,,79.08,949,1 +Zamorak mix(2),6 × 2,,,39.25,471,1 +Dark crab,22,90 85,Caught by using a lobster pot with dark fishing bait.Can only be fished in the Wilderness and the Resource Area.,69.64,"1,532",1 +Extended antifire mix(2),6 × 2,,,17.50,210,1 +Stamina mix(2),6 × 2,,,310.83,"3,730",1 +Anglerfish,3 - 22,84 82,"Caught by using a fishing rod with sandworms.Healing dependent on the player's Hitpoints level (complex, see page)Can boost Hitpoints above maximum equal to the amount it heals.",90.27 – 662.00,"1,986",1 +Botanical pie,7 × 2,52,Made using CookingTemporary Herblore boost of +4 Both slices are a 1-tick eat delay.,52.93,741,1 +Pysk fish (0),5,,,N/A,N/A,1 +Suphi fish (1),8,,,N/A,N/A,1 +Leckish fish (2),11,,,N/A,N/A,1 +Brawk fish (3),14,,,N/A,N/A,1 +Mycil fish (4),17,,,N/A,N/A,1 +Roqed fish (5),20,,,N/A,N/A,1 +Kyren fish (6),23,,,N/A,N/A,1 +Guanic bat (0),5,,,N/A,N/A,1 +Prael bat (1),8,,,N/A,N/A,1 +Giral bat (2),11,,,N/A,N/A,1 +Phluxia bat (3),14,,,N/A,N/A,1 +Kryket bat (4),17,,,N/A,N/A,1 +Murng bat (5),20,,,N/A,N/A,1 +Psykk bat (6),23,,,N/A,N/A,1 +Xeric's aid (-),(1 - 7) × 4,,"Drunk in 4 sips, each healing for ⌊Hitpoints×7100⌋+1 and can boost health above the maximum value.Due to it lowering offensive stats, it is typically used with revitalisation potions or overloads.It can only be obtained and used within the Chambers of Xeric.Will not increase the delay before your next attack.",N/A,N/A,1 +Xeric's aid,(3 - 13) × 4,,"Drunk in 4 sips, each healing for ⌊Hitpoints×12100⌋+2 and can boost health above the maximum value.Due to it lowering offensive stats, it is typically used with revitalisation potions or overloads.It can only be obtained and used within the Chambers of Xeric.Will not increase the delay before your next attack.",N/A,N/A,1 +Xeric's aid (+),(6 - 19) × 4,,"Drunk in 4 sips, each healing for ⌊Hitpoints×15100⌋+5 and can boost health above the maximum value.Due to it lowering offensive stats, it is typically used with revitalisation potions or overloads.It can only be obtained and used within the Chambers of Xeric.Will not increase the delay before your next attack.",N/A,N/A,1 +Honey locust,20,,,N/A,N/A,1 +Ambrosia,100%,,"Completely restores Hitpoints, Prayer, and Run EnergyAlso applies the Antidote++ effect, overheals by 25% + 2 and boosts Prayer by 20% + 5",N/A,N/A,1 +Nectar,(4 - 17) × 4,,"Drunk in 4 sips, each healing for ⌊Hitpoints×15100⌋+3 and can boost health above the maximum value.Due to it lowering offensive stats, it is typically used with tears of elidinis or smelling salts.It can only be obtained and used within the Tombs of Amascut.Will not increase the delay before your next attack.",N/A,N/A,1 +Silk dressing (2),5 x 20,,"5 every 5 ticks, 20 timesAlso overheals by 5",N/A,N/A,1 +Mushroom pie,8 × 2,60,Made using CookingTemporary Crafting boost of +3 Both slices are a 1-tick eat delay.,508.13,"8,130",1 +Bloody bracer,2,,,606.50,"1,213",1 +Dragonfruit pie,10 × 2,73,Heals 10 hitpoints per bite (2 bites total).Boosts Fletching by 4.,21.25,425,1 +Dragonfruit,10,,,104.80,"1,048",1 +Paddlefish,20,,,N/A,N/A,1 +Elven dawn,1,,,319.00,319,1 +Cooked mystery meat,5,,,28.80,144,1 +Steak sandwich,6,,,N/A,N/A,0 +Corrupted paddlefish,16,,,N/A,N/A,1 +Crystal paddlefish,16,,,N/A,N/A,1 +Ancient mix(2),6 × 2,,,114.25,"1,371",1 +Kovac's grog,1,,,"51,108.00","51,108",1 +Cooked sunlight antelope,12 + 9,,"Heals 12 hitpoints immediately, then an additional 9 hitpoints after three seconds, for a total of 21 hitpoints. Raw sunlight antelopes cannot be cooked until 50 Hunters' Rumours have been completed.",33.67,707,1 +Cooked graahk,8 + 6,,"Heals 8 hitpoints immediately, then an additional 6 hitpoints after three seconds, for a total of 14 hitpoints. Raw graahks cannot be cooked until 25 Hunters' Rumours have been completed.",41.71,584,1 +Cooked dashing kebbit,13 + 10,,"Heals 13 hitpoints immediately, then an additional 10 hitpoints after three seconds, for a total of 23 hitpoints. Raw dashing kebbits cannot be cooked until 50 Hunters' Rumours have been completed.",47.00,"1,081",1 +Cooked moonlight antelope,14 + 12,,"Heals 14 hitpoints immediately, then an additional 12 hitpoints after three seconds, for a total of 26 hitpoints. Raw moonlight antelopes cannot be cooked until 50 Hunters' Rumours have been completed.",76.96,"2,001",1 +Cooked pyre fox,11 + 8,,"Heals 11 hitpoints immediately, then an additional 8 hitpoints after three seconds, for a total of 19 hitpoints. Raw pyre foxex cannot be cooked until 25 Hunters' Rumours have been completed.",19.89,378,1 +Cooked kyatt,9 + 8,,"Heals 9 hitpoints immediately, then an additional 8 hitpoints after three seconds, for a total of 17 hitpoints. Raw kyatts cannot be cooked until 25 Hunters' Rumours have been completed.",13.29,226,1 +Cooked barb-tailed kebbit,7 + 5,,"Heals 7 hitpoints immediately, then an additional 5 hitpoints after three seconds, for a total of 12 hitpoints.",47.08,565,1 +Cooked larupia,6 + 5,,"Heals 6 hitpoints immediately, then an additional 5 hitpoints after three seconds, for a total of 11 hitpoints.",32.82,361,1 +Cooked bream,Up to 33,,Cooked bream can only be used as food whilst fighting the Moons of Peril. The amount of Hitpoints restored appear to be 1/3rd of the player's Cooking or Fishing level whichever skill is the lowest.,N/A,N/A,1 +Cooked moss lizard,Up to 33,,"Cooked moss lizard can only be used as food whilst fighting the Moons of Peril. The amount of Hitpoints restored appear to be 1/3rd of the player's Cooking level or 1/2 of their Hunter level, whichever one heals less.",N/A,N/A,1 +Cooked wild kebbit,4 + 4,,"Heals 4 hitpoints immediately, then an additional 4 hitpoints after three seconds, for a total of 8 hitpoints.",79.75,638,1 +Varlamorian kebab,4 + 10%,,"Variable amount between 3-30 hitpoints. Number shown is average result. Has a chance to boost Attack, Defence, and Strength levels by 2. No chance of skill drain.",3.47 - 34.67,104,1 +Giant krill,17,69 69 ( 69 ),Caught with a fishing rod or via deep sea trawling.,33.06,562,1 +Haddock,18,73 73 ( 73 ),Caught with a fishing rod or via deep sea trawling. Can boost Hitpoints above maximum up to 109.,34.39,619,1 +Yellowfin,19,79 79 ( 79 ),Caught with a fishing rod or via deep sea trawling. Restores 20% Energy when eaten.,45.95,873,1 +Halibut,20,83 83 ( 83 ),"Caught with a fishing rod or via deep sea trawling. Can be eaten in the same tick as another piece of food, allowing for combo eating. Shorter attack delay than most other food (2 ticks instead of 4).",158.05,"3,161",1 +Bluefin,22,87 87 ( 86 ),Caught with a fishing rod or via deep sea trawling.,92.77,"2,041",1 +Marlin,24,93 93 ( 91 ),Caught with a fishing rod or via deep sea trawling.,276.17,"6,628",1 +Swordtip squid,15,56 56 47,Caught via lantern harpooning.,26.87,403,1 +Jumbo squid,17,56 56 47,Caught via lantern harpooning.,55.41,942,1 +Red crab meat,8,21 21,Caught via Crab trapping. Requires partial completion of Pandemonium to access.,20.00,160,1 +Blue crab meat,14,48 48,Caught via Crab trapping. Requires partial completion of Troubled Tortugans to access.,21.57,302,1 +Rainbow crab meat,19,77 77 64,Caught via Crab trapping.,33.95,645,1 From 6b7b4982add53141d23660c0f214aca7d4931f8c Mon Sep 17 00:00:00 2001 From: voidstarr <3334013+voidstarr@users.noreply.github.com> Date: Sun, 22 Feb 2026 14:07:56 -0800 Subject: [PATCH 10/10] Fix missing consumable food dbrows --- .../org/alter/items/consumables/gamevals.toml | 118 +++++++++++++++++- 1 file changed, 117 insertions(+), 1 deletion(-) diff --git a/content/src/main/resources/org/alter/items/consumables/gamevals.toml b/content/src/main/resources/org/alter/items/consumables/gamevals.toml index aeafc2f6..1efe750e 100644 --- a/content/src/main/resources/org/alter/items/consumables/gamevals.toml +++ b/content/src/main/resources/org/alter/items/consumables/gamevals.toml @@ -7,6 +7,7 @@ shrimps_food=98030 cooked_chicken_food=98031 cooked_meat_food=98032 bread_food=98033 +anchovies_food= 97096 herring_food=98034 mackerel_food=98035 trout_food=98036 @@ -80,4 +81,119 @@ blighted_karambwan_food=98104 blighted_manta_ray_food=98105 blighted_anglerfish_food=98106 sweets_food=98107 -moonlight_mead_food=98108 \ No newline at end of file +moonlight_mead_food=98108 +asgarnian_ale_food= 97038 +axemans_folly_food= 97039 +baguette_food= 97040 +baked_potato_food= 97041 +banana_food= 97042 +bat_shish_food= 97043 +beer_food= 97044 +blue_crab_meat_food= 97045 +bluefin_food= 97046 +blurberry_special_food= 97047 +bowl_of_chilli_con_carne_food= 97048 +brandy_food= 97049 +cabbage_food= 97050 +caerula_berries_food= 97051 +cave_eel_food= 97052 +cave_eel_sushi_food= 97053 +cavefish_food= 97054 +caviar_food= 97055 +cheese_food= 97056 +chefs_delight_food= 97057 +chilli_potato_food= 97058 +choc_ice_food= 97059 +chocolate_bar_food= 97060 +chocolate_saturday_food= 97061 +cider_food= 97062 +cod_food= 97063 +cooked_barb_tailed_kebbit_food= 97064 +cooked_chompy_food= 97065 +cooked_dashing_kebbit_food= 97066 +cooked_graahk_food= 97067 +cooked_jubbly_food= 97068 +cooked_kyatt_food= 97069 +cooked_larupia_food= 97070 +cooked_mystery_meat_food= 97071 +cooked_rabbit_food= 97072 +cooked_sweetcorn_food= 97073 +cooked_wild_kebbit_food= 97074 +dragon_bitter_food= 97075 +dragonfruit_food= 97076 +drunk_dragon_food= 97077 +dwarven_stout_food= 97078 +dwellberries_food= 97079 +easter_egg_food= 97080 +edible_seaweed_food= 97081 +egg_and_tomato_food= 97082 +egg_potato_food= 97083 +fat_snail_meat_food= 97084 +fried_mushrooms_food= 97085 +frog_burger_food= 97086 +frog_spawn_gumbo_food= 97087 +fruit_blast_food= 97088 +giant_frog_legs_food= 97089 +giant_krill_food= 97090 +gin_food= 97091 +green_gloop_soup_food= 97092 +greenmans_ale_food= 97093 +grog_food= 97094 +haddock_food= 97095 +halibut_food= 98155 +jangerberries_food= 98156 +jumbo_squid_food= 98157 +kebab_food= 98186 +keg_of_beer_food= 98210 +kovacs_grog_food= 98211 +lava_eel_food= 98212 +lean_snail_meat_food= 98213 +lemon_food= 98214 +lime_food= 98215 +locust_meat_food= 98216 +marlin_food= 98217 +mushroom_and_onion_food= 98218 +mushroom_potato_food= 98219 +orange_food= 98220 +papaya_fruit_food= 98221 +pineapple_food= 98222 +pineapple_punch_food= 98223 +potato_food= 98224 +potato_with_butter_food= 98225 +premade_blurberry_special_food= 98226 +premade_choc_saturday_food= 98227 +premade_drunk_dragon_food= 98228 +premade_fruit_blast_food= 98229 +premade_pineapple_punch_food= 98230 +premade_sgg_food= 98231 +premade_wizard_blizzard_food= 98232 +pumpkin_food= 98233 +rainbow_crab_meat_food= 98234 +red_crab_meat_food= 98235 +roast_beast_meat_food= 98236 +roast_bird_meat_food= 98237 +roast_rabbit_food= 98238 +roe_food= 98239 +sardine_food= 98240 +sauteed_mushrooms_food= 98241 +scrambled_egg_food= 98242 +seasoned_sardine_food= 98243 +short_green_guy_food= 98244 +slayers_respite_food= 98245 +spider_on_shaft_food= 98246 +spider_on_stick_food= 98247 +stew_food= 98248 +strawberry_food= 98249 +swordtip_squid_food= 98250 +tetra_food= 98251 +thin_snail_meat_food= 98252 +tomato_food= 98253 +tuna_and_corn_food= 98254 +ugthanki_kebab_food= 98255 +vodka_food= 98256 +watermelon_slice_food= 98257 +whisky_food= 98258 +wizard_blizzard_food= 98259 +wizards_mind_bomb_food= 98260 +wrapped_oomlie_food= 98261 +yellowfin_food= 98262 \ No newline at end of file