From a67a573b9bcb33dcb20e0921212ff8140f36331d Mon Sep 17 00:00:00 2001 From: GregHib Date: Sun, 22 Mar 2026 17:16:02 +0000 Subject: [PATCH 01/40] Groundwork for a table definition system --- .../engine/data/config/RowDefinition.kt | 27 +++ .../engine/data/config/TableDefinition.kt | 104 +++++++++++ .../engine/data/definition/ColumnType.kt | 137 ++++++++++++++ .../voidps/engine/data/definition/Rows.kt | 41 ++++ .../voidps/engine/data/definition/Tables.kt | 176 ++++++++++++++++++ .../engine/data/definition/TablesTest.kt | 56 ++++++ .../engine/data/definition/test-table.toml | 11 ++ 7 files changed, 552 insertions(+) create mode 100644 engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt create mode 100644 engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt create mode 100644 engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnType.kt create mode 100644 engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Rows.kt create mode 100644 engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt create mode 100644 engine/src/test/kotlin/world/gregs/voidps/engine/data/definition/TablesTest.kt create mode 100644 engine/src/test/resources/world/gregs/voidps/engine/data/definition/test-table.toml diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt new file mode 100644 index 0000000000..5a87507d06 --- /dev/null +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt @@ -0,0 +1,27 @@ +package world.gregs.voidps.engine.data.config + +/** + * DbRow + */ +data class RowDefinition( + val data: Array, + val stringId: String +) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as RowDefinition + + if (!data.contentEquals(other.data)) return false + if (stringId != other.stringId) return false + + return true + } + + override fun hashCode(): Int { + var result = data.contentHashCode() + result = 31 * result + stringId.hashCode() + return result + } +} \ No newline at end of file diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt new file mode 100644 index 0000000000..8d4ccff8b8 --- /dev/null +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt @@ -0,0 +1,104 @@ +package world.gregs.voidps.engine.data.config + +import world.gregs.config.ConfigReader +import world.gregs.voidps.engine.data.definition.ColumnType +import world.gregs.voidps.engine.data.definition.Rows + +/** + * DbTable + */ +data class TableDefinition( + val columns: Map, + val types: Array>, + val default: Array, + val rows: IntArray, +) { + + fun get(column: String, row: Int, type: ColumnType): T = getOrNull(column, row, type) ?: type.defaultValue + + fun get(column: Int, row: Int, type: ColumnType): T = getOrNull(column, row, type) ?: type.defaultValue + + fun getOrNull(column: String, row: Int, type: ColumnType): T? { + val columnIndex = columns[column] ?: return type.defaultValue + require(types[columnIndex] == type) { "Column $column is not of type $type" } + return getOrNull(columnIndex, row, type) + } + + fun getOrNull(column: Int, row: Int, type: ColumnType): T? { + require(types[column] == type) { "Column $column is not of type $type" } + return value(row, column, type) + } + + private fun value(row: Int, column: Int, type: ColumnType): T? { + val id = rows.getOrNull(row) + if (id == null) { + val default = default.getOrNull(column) ?: return null + return type.cast(default) + } + val value = Rows.getOrNull(id)?.data[column] ?: return null + return type.cast(value) + } + + fun findOrNull(searchColumn: String, value: Any, column: String, type: ColumnType): T? { + val searchIndex = columns[searchColumn] ?: return null + return findOrNull(searchIndex, value, column, type) + } + + fun findOrNull(searchColumn: Int, value: Any, column: String, type: ColumnType): T? { + val columnIndex = columns[column] ?: return null + val row = findOrNull(searchColumn, value) ?: return null + return value(row, columnIndex, type) + } + + fun findOrNull(column: Int, value: Any): Int? { + for ((index, row) in rows.withIndex()) { + val row = Rows.getOrNull(row) + if (row != null && row.data[column] == value) { + return index + } + } + return null + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as TableDefinition + + if (columns != other.columns) return false + if (!types.contentEquals(other.types)) return false + if (!default.contentEquals(other.default)) return false + if (!rows.contentEquals(other.rows)) return false + + return true + } + + override fun hashCode(): Int { + var result = columns.hashCode() + result = 31 * result + types.contentHashCode() + result = 31 * result + default.contentHashCode() + result = 31 * result + rows.contentHashCode() + return result + } + + companion object { + + internal fun read(type: Int, reader: ConfigReader) = when (type) { + TYPE_INT -> reader.int() + else -> throw IllegalArgumentException("Unknown type $type") + } + + internal fun default(type: Int) = when (type) { + TYPE_INT -> 0 + else -> throw IllegalArgumentException("Unknown type $type") + } + + internal fun type(name: String) = when (name) { + "int" -> TYPE_INT + else -> throw IllegalArgumentException("Unknown type $name") + } + + internal const val TYPE_INT = 0 + } +} \ No newline at end of file diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnType.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnType.kt new file mode 100644 index 0000000000..16e7b3fcd3 --- /dev/null +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnType.kt @@ -0,0 +1,137 @@ +@file:Suppress("UNCHECKED_CAST") + +package world.gregs.voidps.engine.data.definition + +import world.gregs.config.ConfigReader + +sealed interface ColumnType { + val default: Encoded + fun read(reader: ConfigReader): Access + fun cast(value: Any): Access? + fun encode(value: Access): Encoded + fun decode(value: Encoded): Access + val defaultValue: Access + get() = decode(default) + + sealed class SingleRowType : ColumnType { + override fun encode(value: T) = value + override fun decode(value: T) = value + } + + object IntType : SingleRowType() { + override val default = 0 + override fun read(reader: ConfigReader) = reader.int() + override fun cast(value: Any) = value as? Int + } + + object RowType : ColumnType { + override val default = -1 + override fun read(reader: ConfigReader): String = reader.string() + override fun encode(value: String): Int = Rows.ids[value] ?: error("Unknown table row: $value") + override fun decode(value: Int): String = Rows.getOrNull(value)?.stringId ?: error("Unknown table row: $value") + override fun cast(value: Any): String? = (value as? Int)?.let { decode(it) } + } + + object StringType : SingleRowType() { + override val default = "" + override fun read(reader: ConfigReader) = reader.string() + override fun cast(value: Any) = value as? String + } + + object ItemType : ColumnType { + override val default = -1 + override fun read(reader: ConfigReader): String = reader.string() + override fun encode(value: String): Int = ItemDefinitions.getOrNull(value)?.id ?: error("Unknown item: $value") + override fun decode(value: Int): String = ItemDefinitions.getOrNull(value)?.stringId ?: error("Unknown item: $value") + override fun cast(value: Any): String? = (value as? Int)?.let { decode(it) } + } + + object IntList : SingleRowType>() { + override val default = emptyList() + override fun read(reader: ConfigReader) = reader.readList(IntType) + override fun cast(value: Any) = value as? List + } + + object StringList : SingleRowType>() { + override val default = emptyList() + override fun read(reader: ConfigReader) = reader.readList(StringType) + override fun cast(value: Any) = value as? List + } + + object ItemList : ColumnType, IntArray> { + override val default = IntArray(0) + override fun read(reader: ConfigReader) = reader.readList(StringType) + override fun cast(value: Any) = value as? List + override fun encode(value: List) = value.map(ItemType::encode).toIntArray() + override fun decode(value: IntArray) = value.map(ItemType::decode) + } + + object ItemIdType : SingleRowType() { + override val default = -1 + override fun read(reader: ConfigReader): Int = ItemType.encode(reader.string()) + override fun cast(value: Any) = IntType.cast(value) + } + + object ItemIdList : SingleRowType() { + override val default = IntArray(0) + override fun read(reader: ConfigReader) = reader.readList(IntType).toIntArray() + override fun cast(value: Any) = value as? IntArray + } + + object IntIntPair : SingleRowType>() { + override val default = Pair(IntType.default, IntType.default) + override fun read(reader: ConfigReader) = reader.readPair(IntType, IntType) + override fun cast(value: Any) = value as? Pair + } + + object StrIntPair : SingleRowType>() { + override val default = Pair(StringType.default, IntType.default) + override fun read(reader: ConfigReader) = reader.readPair(StringType, IntType) + override fun cast(value: Any) = value as? Pair + } + + object IntStrPair : SingleRowType>() { + override val default = Pair(IntType.default, StringType.default) + override fun read(reader: ConfigReader) = reader.readPair(IntType, StringType) + override fun cast(value: Any) = value as? Pair + } + + companion object { + fun type(name: String): ColumnType<*, *> = when (name.lowercase()) { + "int" -> IntType + "string" -> StringType + "item" -> ItemType + "row" -> RowType + "list" -> IntList + "list" -> StringList + "list" -> ItemList + "pair" -> IntIntPair + "pair" -> StrIntPair + "pair" -> IntStrPair + else -> throw IllegalArgumentException("Unsupported type $name") + } + + private fun ConfigReader.readPair(one: ColumnType, two: ColumnType): Pair { + var index = 0 + var a = one.defaultValue + var b = two.defaultValue + while (nextElement()) { + when (index++) { + 0 -> a = one.read(this) + 1 -> b = two.read(this) + else -> throw IllegalArgumentException("Unexpected pair index: $index") + } + } + return Pair(a, b) + } + + private fun ConfigReader.readList(type: ColumnType): List { + val list = mutableListOf() + while (nextElement()) { + list.add(type.read(this)) + } + return list + } + + } +} \ No newline at end of file diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Rows.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Rows.kt new file mode 100644 index 0000000000..a6edc69c13 --- /dev/null +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Rows.kt @@ -0,0 +1,41 @@ +package world.gregs.voidps.engine.data.definition + +import org.jetbrains.annotations.TestOnly +import world.gregs.voidps.engine.data.config.RowDefinition + +object Rows { + + var definitions: Array = emptyArray() + private set + var ids: Map = emptyMap() + private set + var loaded = false + private set + + val size: Int + get() = definitions.size + + fun get(name: String) = getOrNull(name) ?: error("Row not found: $name") + + fun get(id: Int) = definitions[id] + + fun getOrNull(name: String): RowDefinition? { + return getOrNull(ids[name] ?: return null) + } + + fun getOrNull(id: Int) = definitions.getOrNull(id) + + @TestOnly + fun set(definitions: Array, ids: Map, ) { + this.definitions = definitions + this.ids = ids + loaded = true + } + + fun clear() { + this.definitions = emptyArray() + this.ids = emptyMap() + loaded = false + } + +} \ No newline at end of file diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt new file mode 100644 index 0000000000..f65c78262a --- /dev/null +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt @@ -0,0 +1,176 @@ +package world.gregs.voidps.engine.data.definition + +import org.jetbrains.annotations.TestOnly +import world.gregs.config.Config +import world.gregs.config.ConfigReader +import world.gregs.voidps.engine.data.config.RowDefinition +import world.gregs.voidps.engine.data.config.TableDefinition +import world.gregs.voidps.engine.timedLoad + +object Tables { + + var definitions: Map = emptyMap() + private set + + var loaded = false + private set + + val size: Int + get() = definitions.size + + fun contains(table: String, column: String, rowIndex: Int): Boolean { + val definition = definitions[table] ?: return false + val index = definition.columns[column] ?: return false + val rowId = definition.rows.getOrNull(rowIndex) ?: return false + val row = Rows.getOrNull(rowId) ?: return false + return row.data[index] != null + } + + fun row(path: String): Array = Rows.get(get(path, ColumnType.RowType)).data + + fun rowOrNull(path: String): Array? { + val id = getOrNull(path, ColumnType.RowType) ?: return null + return Rows.getOrNull(id)?.data + } + + fun item(path: String): String = get(path, ColumnType.ItemType) + + fun itemOrNull(path: String): String? = getOrNull(path, ColumnType.ItemType) + + fun int(path: String): Int = get(path, ColumnType.IntType) + + fun intOrNull(path: String): Int? = getOrNull(path, ColumnType.IntType) + + fun string(path: String): String = get(path, ColumnType.StringType) + + fun stringOrNull(path: String): String? = getOrNull(path, ColumnType.StringType) + + private fun get(table: String, column: String, row: Int, type: ColumnType): T { + return definitions[table]?.get(column, row, type) ?: error("Table '$table' not found") + } + + private fun getOrNull(table: String, column: String, row: Int, type: ColumnType): T? { + val definition = definitions[table] ?: error("Table '$table' not found") + return definition.getOrNull(column, row, type) + } + + private fun get(path: String, type: ColumnType): T { + val (table, row, column) = path.split(".") + val id = Rows.ids[row] ?: error("Row '$row' not found") + return get(table, column, id, type) + } + + private fun getOrNull(path: String, type: ColumnType): T? { + val (table, row, column) = path.split(".") + val id = Rows.ids[row] ?: error("Row '$row' not found") + return getOrNull(table, column, id, type) + } + + @TestOnly + fun set(definitions: Map) { + this.definitions = definitions + loaded = true + } + + fun clear() { + this.definitions = emptyMap() + loaded = false + } + + fun load(paths: List): Tables { + require(ItemDefinitions.loaded) { "Item definitions must be loaded before tables" } + timedLoad("table config") { + val definitions = mutableMapOf() + val rows = mutableListOf() + val ids = mutableMapOf() + for (path in paths) { + Config.fileReader(path, 256) { + try { + while (nextSection()) { + val stringId = section() + if (stringId.contains(".")) { + val (key, rowName) = stringId.split(".") + readTableRow(this, definitions, rows, ids, key, rowName) + } else { + readTableHeader(this, definitions, stringId) + } + } + } catch (e: Exception) { + e.printStackTrace() + error("Error reading table definition at ${exception()}") + } + } + } + set(definitions.mapValues { it.value.build() }.toMap()) + Rows.set(rows.toTypedArray(), ids) + size + } + return this + } + + private fun readTableRow(reader: ConfigReader, definitions: MutableMap, rows: MutableList, ids: MutableMap, key: String, rowName: String) { + val builder = definitions[key] + requireNotNull(builder) { "Table header not found '$key' at ${reader.exception()}." } + val row = arrayOfNulls(builder.types.size) + while (reader.nextPair()) { + val column = reader.key() + val index = builder.columns[column] + requireNotNull(index) { "Column '$column' not found in table '$key' at ${reader.exception()}." } + val type = builder.types[index] + row[index] = type.read(reader) + } + require(!ids.containsKey(rowName)) { "Duplicate row id found '$rowName' at ${reader.exception()}." } + val id = rows.size + ids[rowName] = id + rows.add(RowDefinition(row, rowName)) + builder.addRow(id) + } + + private fun readTableHeader(reader: ConfigReader, definitions: MutableMap, stringId: String) { + require(!definitions.containsKey(stringId)) { "Duplicate table id found '$stringId' at ${reader.exception()}." } + val builder = TableBuilder() + definitions[stringId] = builder + while (reader.nextPair()) { + val key = reader.key() + if (key.endsWith("_default")) { + val default = reader.value() + builder.setDefault(key.removeSuffix("_default"), default) + } else { + val type = reader.string() + builder.addColumn(key, type) + } + } + } + + private class TableBuilder { + val columns = mutableMapOf() + val types = mutableListOf>() + val defaults = mutableListOf() + val rows = mutableListOf() + private var columnIndex = 0 + + fun setDefault(name: String, value: Any) { + val index = columns[name] + requireNotNull(index) { "Default column not found '$name'" } + require(index < columnIndex) { "Default column index out of bounds '$name' - has type been set?" } + defaults[index] = value + } + + fun addColumn(name: String, type: String) { + require(!columns.containsKey(name)) { "Duplicate column name $name in table definition" } + columns[name] = columnIndex++ + val columnType = ColumnType.type(type) + types.add(columnType) + defaults.add(columnType.default) + } + + fun addRow(id: Int) = rows.add(id) + + fun build() = TableDefinition( + columns, + types.toTypedArray(), + defaults.toTypedArray(), + rows.toIntArray(), + ) + } +} \ No newline at end of file diff --git a/engine/src/test/kotlin/world/gregs/voidps/engine/data/definition/TablesTest.kt b/engine/src/test/kotlin/world/gregs/voidps/engine/data/definition/TablesTest.kt new file mode 100644 index 0000000000..6498a867f8 --- /dev/null +++ b/engine/src/test/kotlin/world/gregs/voidps/engine/data/definition/TablesTest.kt @@ -0,0 +1,56 @@ +package world.gregs.voidps.engine.data.definition + +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertNotNull +import world.gregs.voidps.cache.definition.data.ItemDefinition +import world.gregs.voidps.engine.data.config.TableDefinition +import kotlin.test.assertContentEquals +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +class TablesTest { + + private data class Field( + val name: String, + val type: ColumnType<*, *>, + val default: Any + ) + + @Test + fun `Test loading a table`() { + ItemDefinitions.set(arrayOf(ItemDefinition()), mapOf("item_id" to 1)) + val uri = TablesTest::class.java.getResource("test-table.toml")!! + Tables.load(listOf(uri.path)) + + assertTrue(Tables.loaded) + + val definition = Tables.definitions["header"] + assertNotNull(definition) + println(definition) + assertColumns(listOf( + Field("int_field", ColumnType.IntType, 0), + Field("string_field", ColumnType.StringType, ""), + Field("item_field", ColumnType.ItemType, -1), + ), definition) + assertContentEquals(intArrayOf(0, 1), definition.rows) + + assertTrue(Rows.loaded) + val row = Rows.getOrNull("row") + assertNotNull(row) + assertContentEquals(arrayOf(1, "text", 1), row.data) + + assertEquals(1, Tables.int("header.row.int_field")) + assertEquals("text", Tables.string("header.row.string_field")) + assertEquals("item_id", Tables.item("header.row.item_field")) + + assertEquals(0, Tables.int("header.row_two.int_field")) + assertEquals("", Tables.string("header.row_two.string_field")) + assertEquals("", Tables.item("header.row.item_field")) + } + + private fun assertColumns(expected: List, definition: TableDefinition) { + assertContentEquals(expected.map { it.default }.toTypedArray(), definition.default) + assertContentEquals(expected.map { it.type }.toTypedArray(), definition.types) + assertEquals(expected.mapIndexed { index, it -> it.name to index }.toMap(), definition.columns) + } +} \ No newline at end of file diff --git a/engine/src/test/resources/world/gregs/voidps/engine/data/definition/test-table.toml b/engine/src/test/resources/world/gregs/voidps/engine/data/definition/test-table.toml new file mode 100644 index 0000000000..105e47a865 --- /dev/null +++ b/engine/src/test/resources/world/gregs/voidps/engine/data/definition/test-table.toml @@ -0,0 +1,11 @@ +[header] +int_field = "int" +string_field = "string" +item_field = "item" + +[.row] +int_field = 1 +string_field = "text" +item_field = "item_id" + +[.row_two] From faa98d79ccdd529f4d374553d54be9418c3e0b59 Mon Sep 17 00:00:00 2001 From: GregHib Date: Sun, 22 Mar 2026 22:17:43 +0000 Subject: [PATCH 02/40] More types --- .../engine/data/config/TableDefinition.kt | 4 +- .../engine/data/definition/ColumnType.kt | 42 ++++++++- .../voidps/engine/data/definition/Tables.kt | 55 ++++++++++-- .../engine/data/definition/TablesTest.kt | 89 ++++++++++++++++--- .../engine/data/definition/test-table.toml | 30 ++++++- 5 files changed, 196 insertions(+), 24 deletions(-) diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt index 8d4ccff8b8..7d0f231b77 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt @@ -20,12 +20,12 @@ data class TableDefinition( fun getOrNull(column: String, row: Int, type: ColumnType): T? { val columnIndex = columns[column] ?: return type.defaultValue - require(types[columnIndex] == type) { "Column $column is not of type $type" } + require(types[columnIndex] == type) { "Column $column is not of expected type ${types[columnIndex]::class.simpleName}, found ${type::class.simpleName}" } return getOrNull(columnIndex, row, type) } fun getOrNull(column: Int, row: Int, type: ColumnType): T? { - require(types[column] == type) { "Column $column is not of type $type" } + require(types[column] == type) { "Column $column is not of expected type ${types[column]::class.simpleName}, found ${type::class.simpleName}" } return value(row, column, type) } diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnType.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnType.kt index 16e7b3fcd3..ed91bbe38f 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnType.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnType.kt @@ -7,6 +7,7 @@ import world.gregs.config.ConfigReader sealed interface ColumnType { val default: Encoded fun read(reader: ConfigReader): Access + fun readEncoded(reader: ConfigReader): Encoded = encode(read(reader)) fun cast(value: Any): Access? fun encode(value: Access): Encoded fun decode(value: Encoded): Access @@ -46,6 +47,14 @@ sealed interface ColumnType { override fun cast(value: Any): String? = (value as? Int)?.let { decode(it) } } + object ObjectType : ColumnType { + override val default = -1 + override fun read(reader: ConfigReader): String = reader.string() + override fun encode(value: String): Int = ObjectDefinitions.getOrNull(value)?.id ?: error("Unknown object: $value") + override fun decode(value: Int): String = ObjectDefinitions.getOrNull(value)?.stringId ?: error("Unknown object: $value") + override fun cast(value: Any): String? = (value as? Int)?.let { decode(it) } + } + object IntList : SingleRowType>() { override val default = emptyList() override fun read(reader: ConfigReader) = reader.readList(IntType) @@ -61,11 +70,19 @@ sealed interface ColumnType { object ItemList : ColumnType, IntArray> { override val default = IntArray(0) override fun read(reader: ConfigReader) = reader.readList(StringType) - override fun cast(value: Any) = value as? List + override fun cast(value: Any) = (value as? IntArray)?.let { decode(it) } override fun encode(value: List) = value.map(ItemType::encode).toIntArray() override fun decode(value: IntArray) = value.map(ItemType::decode) } + object ObjectList : ColumnType, IntArray> { + override val default = IntArray(0) + override fun read(reader: ConfigReader) = reader.readList(StringType) + override fun cast(value: Any) = (value as? IntArray)?.let { decode(it) } + override fun encode(value: List) = value.map(ObjectType::encode).toIntArray() + override fun decode(value: IntArray) = value.map(ObjectType::decode) + } + object ItemIdType : SingleRowType() { override val default = -1 override fun read(reader: ConfigReader): Int = ItemType.encode(reader.string()) @@ -96,18 +113,41 @@ sealed interface ColumnType { override fun cast(value: Any) = value as? Pair } + object IntIntList : SingleRowType>>() { + override val default = emptyList>() + override fun read(reader: ConfigReader) = reader.readList(IntIntPair) + override fun cast(value: Any) = value as? List> + } + + object IntStrList : SingleRowType>>() { + override val default = emptyList>() + override fun read(reader: ConfigReader) = reader.readList(IntStrPair) + override fun cast(value: Any) = value as? List> + } + + object StrIntList : SingleRowType>>() { + override val default = emptyList>() + override fun read(reader: ConfigReader) = reader.readList(StrIntPair) + override fun cast(value: Any) = value as? List> + } + companion object { fun type(name: String): ColumnType<*, *> = when (name.lowercase()) { "int" -> IntType "string" -> StringType "item" -> ItemType + "gameobject" -> ObjectType "row" -> RowType "list" -> IntList "list" -> StringList "list" -> ItemList + "list" -> ObjectList "pair" -> IntIntPair "pair" -> StrIntPair "pair" -> IntStrPair + "list>" -> IntIntList + "list>" -> StrIntList + "list>" -> IntStrList else -> throw IllegalArgumentException("Unsupported type $name") } diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt index f65c78262a..857a5ba0d7 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt @@ -26,6 +26,14 @@ object Tables { return row.data[index] != null } + fun int(path: String): Int = get(path, ColumnType.IntType) + + fun intOrNull(path: String): Int? = getOrNull(path, ColumnType.IntType) + + fun string(path: String): String = get(path, ColumnType.StringType) + + fun stringOrNull(path: String): String? = getOrNull(path, ColumnType.StringType) + fun row(path: String): Array = Rows.get(get(path, ColumnType.RowType)).data fun rowOrNull(path: String): Array? { @@ -37,13 +45,49 @@ object Tables { fun itemOrNull(path: String): String? = getOrNull(path, ColumnType.ItemType) - fun int(path: String): Int = get(path, ColumnType.IntType) + fun obj(path: String): String = get(path, ColumnType.ObjectType) - fun intOrNull(path: String): Int? = getOrNull(path, ColumnType.IntType) + fun objOrNull(path: String): String? = getOrNull(path, ColumnType.ObjectType) - fun string(path: String): String = get(path, ColumnType.StringType) + fun intList(path: String): List = get(path, ColumnType.IntList) - fun stringOrNull(path: String): String? = getOrNull(path, ColumnType.StringType) + fun intListOrNull(path: String): List? = getOrNull(path, ColumnType.IntList) + + fun stringList(path: String): List = get(path, ColumnType.StringList) + + fun stringListOrNull(path: String): List? = getOrNull(path, ColumnType.StringList) + + fun itemList(path: String): List = get(path, ColumnType.ItemList) + + fun itemListOrNull(path: String): List? = getOrNull(path, ColumnType.ItemList) + + fun objList(path: String): List = get(path, ColumnType.ObjectList) + + fun objListOrNull(path: String): List? = getOrNull(path, ColumnType.ObjectList) + + fun intPair(path: String): Pair = get(path, ColumnType.IntIntPair) + + fun intPairOrNull(path: String): Pair? = getOrNull(path, ColumnType.IntIntPair) + + fun strIntPair(path: String): Pair = get(path, ColumnType.StrIntPair) + + fun strIntPairOrNull(path: String): Pair? = getOrNull(path, ColumnType.StrIntPair) + + fun intStrPair(path: String): Pair = get(path, ColumnType.IntStrPair) + + fun intStrPairOrNull(path: String): Pair? = getOrNull(path, ColumnType.IntStrPair) + + fun intPairList(path: String): List> = get(path, ColumnType.IntIntList) + + fun intPairListOrNull(path: String): List>? = getOrNull(path, ColumnType.IntIntList) + + fun strIntList(path: String): List> = get(path, ColumnType.StrIntList) + + fun strIntListOrNull(path: String): List>? = getOrNull(path, ColumnType.StrIntList) + + fun intStrList(path: String): List> = get(path, ColumnType.IntStrList) + + fun intStrListOrNull(path: String): List>? = getOrNull(path, ColumnType.IntStrList) private fun get(table: String, column: String, row: Int, type: ColumnType): T { return definitions[table]?.get(column, row, type) ?: error("Table '$table' not found") @@ -79,6 +123,7 @@ object Tables { fun load(paths: List): Tables { require(ItemDefinitions.loaded) { "Item definitions must be loaded before tables" } + require(ObjectDefinitions.loaded) { "Object definitions must be loaded before tables" } timedLoad("table config") { val definitions = mutableMapOf() val rows = mutableListOf() @@ -117,7 +162,7 @@ object Tables { val index = builder.columns[column] requireNotNull(index) { "Column '$column' not found in table '$key' at ${reader.exception()}." } val type = builder.types[index] - row[index] = type.read(reader) + row[index] = type.readEncoded(reader) } require(!ids.containsKey(rowName)) { "Duplicate row id found '$rowName' at ${reader.exception()}." } val id = rows.size diff --git a/engine/src/test/kotlin/world/gregs/voidps/engine/data/definition/TablesTest.kt b/engine/src/test/kotlin/world/gregs/voidps/engine/data/definition/TablesTest.kt index 6498a867f8..eacd1e4305 100644 --- a/engine/src/test/kotlin/world/gregs/voidps/engine/data/definition/TablesTest.kt +++ b/engine/src/test/kotlin/world/gregs/voidps/engine/data/definition/TablesTest.kt @@ -2,7 +2,9 @@ package world.gregs.voidps.engine.data.definition import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertNotNull +import org.junit.jupiter.api.assertThrows import world.gregs.voidps.cache.definition.data.ItemDefinition +import world.gregs.voidps.cache.definition.data.ObjectDefinition import world.gregs.voidps.engine.data.config.TableDefinition import kotlin.test.assertContentEquals import kotlin.test.assertEquals @@ -13,12 +15,13 @@ class TablesTest { private data class Field( val name: String, val type: ColumnType<*, *>, - val default: Any + val default: Any, ) @Test fun `Test loading a table`() { - ItemDefinitions.set(arrayOf(ItemDefinition()), mapOf("item_id" to 1)) + ItemDefinitions.set(arrayOf(ItemDefinition(id = 0, stringId = "item_id")), mapOf("item_id" to 0)) + ObjectDefinitions.set(arrayOf(ObjectDefinition(id = 0, stringId = "obj_id")), mapOf("obj_id" to 0)) val uri = TablesTest::class.java.getResource("test-table.toml")!! Tables.load(listOf(uri.path)) @@ -26,31 +29,93 @@ class TablesTest { val definition = Tables.definitions["header"] assertNotNull(definition) - println(definition) - assertColumns(listOf( - Field("int_field", ColumnType.IntType, 0), - Field("string_field", ColumnType.StringType, ""), - Field("item_field", ColumnType.ItemType, -1), - ), definition) + assertColumns( + listOf( + Field("int_field", ColumnType.IntType, 0), + Field("string_field", ColumnType.StringType, ""), + Field("item_field", ColumnType.ItemType, -1), + Field("obj_field", ColumnType.ObjectType, -1), + Field("int_list", ColumnType.IntList, emptyList()), + Field("str_list", ColumnType.StringList, emptyList()), + Field("item_list", ColumnType.ItemList, IntArray(0)), + Field("obj_list", ColumnType.ObjectList, IntArray(0)), + Field("int_int", ColumnType.IntIntPair, Pair(0, 0)), + Field("str_int", ColumnType.StrIntPair, Pair("", 0)), + Field("int_str", ColumnType.IntStrPair, Pair(0, "")), + Field("int_int_list", ColumnType.IntIntList, emptyList>()), + Field("str_int_list", ColumnType.StrIntList, emptyList>()), + Field("int_str_list", ColumnType.IntStrList, emptyList>()), + ), definition + ) assertContentEquals(intArrayOf(0, 1), definition.rows) assertTrue(Rows.loaded) val row = Rows.getOrNull("row") assertNotNull(row) - assertContentEquals(arrayOf(1, "text", 1), row.data) + val expected = arrayOf( + 1, + "text", + 0, + 0, + listOf(1, 2, 3), + listOf("one", "two"), + intArrayOf(0), + intArrayOf(0), + Pair(1, 2), + Pair("one", 2), + Pair(1, "two"), + listOf(Pair(1, 2), Pair(3, 4)), + listOf(Pair("one", 2), Pair("three", 4)), + listOf(Pair(1, "two"), Pair(3, "four")), + ) + for (i in row.data.indices) { + assertAnyEquals(expected[i], row.data[i]!!, i) + } assertEquals(1, Tables.int("header.row.int_field")) assertEquals("text", Tables.string("header.row.string_field")) assertEquals("item_id", Tables.item("header.row.item_field")) + assertEquals("obj_id", Tables.obj("header.row.obj_field")) + assertEquals(listOf(1, 2, 3), Tables.intList("header.row.int_list")) + assertEquals(listOf("one", "two"), Tables.stringList("header.row.str_list")) + assertEquals(listOf("item_id"), Tables.itemList("header.row.item_list")) + assertEquals(listOf("obj_id"), Tables.objList("header.row.obj_list")) + assertEquals(Pair(1, 2), Tables.intPair("header.row.int_int")) + assertEquals(Pair("one", 2), Tables.strIntPair("header.row.str_int")) + assertEquals(Pair(1, "two"), Tables.intStrPair("header.row.int_str")) + assertEquals(listOf(Pair(1, 2), Pair(3, 4)), Tables.intPairList("header.row.int_int_list")) + assertEquals(listOf(Pair("one", 2), Pair("three", 4)), Tables.strIntList("header.row.str_int_list")) + assertEquals(listOf(Pair(1, "two"), Pair(3, "four")), Tables.intStrList("header.row.int_str_list")) assertEquals(0, Tables.int("header.row_two.int_field")) assertEquals("", Tables.string("header.row_two.string_field")) - assertEquals("", Tables.item("header.row.item_field")) + assertThrows { + Tables.item("header.row_two.item_field") + } + assertEquals(emptyList(), Tables.intList("header.row_two.int_list")) + assertEquals(emptyList(), Tables.stringList("header.row_two.str_list")) + assertEquals(emptyList(), Tables.itemList("header.row_two.item_list")) + assertEquals(Pair(0, 0), Tables.intPair("header.row_two.int_int")) + assertEquals(Pair("", 0), Tables.strIntPair("header.row_two.str_int")) + assertEquals(Pair(0, ""), Tables.intStrPair("header.row_two.int_str")) + assertEquals(emptyList(), Tables.intPairList("header.row_two.int_int_list")) + assertEquals(emptyList(), Tables.strIntList("header.row_two.str_int_list")) + assertEquals(emptyList(), Tables.intStrList("header.row_two.int_str_list")) } private fun assertColumns(expected: List, definition: TableDefinition) { - assertContentEquals(expected.map { it.default }.toTypedArray(), definition.default) - assertContentEquals(expected.map { it.type }.toTypedArray(), definition.types) + for (i in expected.indices) { + assertAnyEquals(expected[i].default, definition.default[i], i) + assertAnyEquals(expected[i].type, definition.types[i], i) + } assertEquals(expected.mapIndexed { index, it -> it.name to index }.toMap(), definition.columns) } + + private fun assertAnyEquals(expect: Any, actual: Any, index: Int) { + if (expect is IntArray && actual is IntArray) { + assertContentEquals(expect, actual) + } else { + assertEquals(expect, actual, "Failed at index $index") + } + } } \ No newline at end of file diff --git a/engine/src/test/resources/world/gregs/voidps/engine/data/definition/test-table.toml b/engine/src/test/resources/world/gregs/voidps/engine/data/definition/test-table.toml index 105e47a865..50e0a12d7c 100644 --- a/engine/src/test/resources/world/gregs/voidps/engine/data/definition/test-table.toml +++ b/engine/src/test/resources/world/gregs/voidps/engine/data/definition/test-table.toml @@ -1,11 +1,33 @@ [header] -int_field = "int" -string_field = "string" -item_field = "item" +int_field = "Int" +string_field = "String" +item_field = "Item" +obj_field = "GameObject" +int_list = "List" +str_list = "List" +item_list = "List" +obj_list = "List" +int_int = "Pair" +str_int = "Pair" +int_str = "Pair" +int_int_list = "List>" +str_int_list = "List>" +int_str_list = "List>" [.row] -int_field = 1 string_field = "text" +int_field = 1 item_field = "item_id" +obj_field = "obj_id" +int_list = [1, 2, 3] +str_list = ["one", "two"] +item_list = ["item_id"] +obj_list = ["obj_id"] +int_int = [1, 2] +str_int = ["one", 2] +int_str = [1, "two"] +int_int_list = [[1, 2], [3, 4]] +str_int_list = [["one", 2], ["three", 4]] +int_str_list = [[1, "two"], [3, "four"]] [.row_two] From 126ac72be903702e7bc13eb2ca7ce732eb52bbd2 Mon Sep 17 00:00:00 2001 From: GregHib Date: Tue, 24 Mar 2026 18:53:42 +0000 Subject: [PATCH 03/40] Working-ish --- .../engine/data/config/TableDefinition.kt | 16 +- .../engine/data/definition/ColumnType.kt | 418 +++++++++++++----- .../voidps/engine/data/definition/Tables.kt | 85 +++- .../engine/data/definition/ColumnTypeTest.kt | 43 ++ .../engine/data/definition/TablesTest.kt | 82 ++-- .../engine/data/definition/test-table.toml | 18 +- 6 files changed, 479 insertions(+), 183 deletions(-) create mode 100644 engine/src/test/kotlin/world/gregs/voidps/engine/data/definition/ColumnTypeTest.kt diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt index 7d0f231b77..4ab9bdfd48 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt @@ -10,7 +10,7 @@ import world.gregs.voidps.engine.data.definition.Rows data class TableDefinition( val columns: Map, val types: Array>, - val default: Array, + val default: Array, val rows: IntArray, ) { @@ -20,23 +20,19 @@ data class TableDefinition( fun getOrNull(column: String, row: Int, type: ColumnType): T? { val columnIndex = columns[column] ?: return type.defaultValue - require(types[columnIndex] == type) { "Column $column is not of expected type ${types[columnIndex]::class.simpleName}, found ${type::class.simpleName}" } + require(types[columnIndex] == type) { "Column $column is not of expected type ${types[columnIndex]}, found $type" } return getOrNull(columnIndex, row, type) } fun getOrNull(column: Int, row: Int, type: ColumnType): T? { - require(types[column] == type) { "Column $column is not of expected type ${types[column]::class.simpleName}, found ${type::class.simpleName}" } + require(types[column] == type) { "Column $column is not of expected type ${types[column]}, found $type" } return value(row, column, type) } private fun value(row: Int, column: Int, type: ColumnType): T? { - val id = rows.getOrNull(row) - if (id == null) { - val default = default.getOrNull(column) ?: return null - return type.cast(default) - } - val value = Rows.getOrNull(id)?.data[column] ?: return null - return type.cast(value) + val id = rows.getOrNull(row) ?: return type.default(default, column) + val rows = Rows.getOrNull(id)?.data ?: return null + return type.read(rows, column) } fun findOrNull(searchColumn: String, value: Any, column: String, type: ColumnType): T? { diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnType.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnType.kt index ed91bbe38f..ffb6d9bb02 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnType.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnType.kt @@ -5,172 +5,366 @@ package world.gregs.voidps.engine.data.definition import world.gregs.config.ConfigReader sealed interface ColumnType { + val size: Int val default: Encoded - fun read(reader: ConfigReader): Access - fun readEncoded(reader: ConfigReader): Encoded = encode(read(reader)) fun cast(value: Any): Access? + fun default(defaults: Array, index: Int): Access? fun encode(value: Access): Encoded fun decode(value: Encoded): Access val defaultValue: Access get() = decode(default) + fun default(index: Int): Any = default + + fun read(row: Array, index: Int): Access? + + fun add(row: MutableList, reader: ConfigReader) + + fun set(row: Array, index: Int, reader: ConfigReader) + sealed class SingleRowType : ColumnType { + override val size = 1 override fun encode(value: T) = value override fun decode(value: T) = value + abstract fun read(reader: ConfigReader): T + + override fun add(row: MutableList, reader: ConfigReader) { + row.add(encode(read(reader))) + } + + override fun set(row: Array, index: Int, reader: ConfigReader) { + val value = read(reader) + println("Set $index $value") + row[index] = encode(value) + } + + override fun read(row: Array, index: Int): T? { + return cast(row[index] ?: return null) + } + + override fun default(defaults: Array, index: Int): T? { + val default = defaults.getOrNull(index) ?: return null + return cast(default) + } + } + + sealed class IntEncodedString : ColumnType { + override val size = 1 + override val default = -1 + + override fun cast(value: Any): String? = (value as? Int)?.let { decode(it) } + + override fun set(row: Array, index: Int, reader: ConfigReader) { + row[index] = encode(reader.string()) + } + + override fun add(row: MutableList, reader: ConfigReader) { + row.add(encode(reader.string())) + } + + override fun read(row: Array, index: Int): String? { + return cast(row[index] ?: return null) + } + + override fun default(defaults: Array, index: Int): String? { + val default = defaults.getOrNull(index) ?: return null + return cast(default) + } + } + + object BooleanType : SingleRowType() { + override val default = false + override fun read(reader: ConfigReader) = reader.boolean() + override fun cast(value: Any) = value as? Boolean + override fun toString() = "BooleanType" } object IntType : SingleRowType() { override val default = 0 override fun read(reader: ConfigReader) = reader.int() override fun cast(value: Any) = value as? Int - } - - object RowType : ColumnType { - override val default = -1 - override fun read(reader: ConfigReader): String = reader.string() - override fun encode(value: String): Int = Rows.ids[value] ?: error("Unknown table row: $value") - override fun decode(value: Int): String = Rows.getOrNull(value)?.stringId ?: error("Unknown table row: $value") - override fun cast(value: Any): String? = (value as? Int)?.let { decode(it) } + override fun toString() = "IntType" } object StringType : SingleRowType() { override val default = "" override fun read(reader: ConfigReader) = reader.string() override fun cast(value: Any) = value as? String + override fun toString() = "StringType" } - object ItemType : ColumnType { - override val default = -1 - override fun read(reader: ConfigReader): String = reader.string() + object ItemType : IntEncodedString() { override fun encode(value: String): Int = ItemDefinitions.getOrNull(value)?.id ?: error("Unknown item: $value") override fun decode(value: Int): String = ItemDefinitions.getOrNull(value)?.stringId ?: error("Unknown item: $value") - override fun cast(value: Any): String? = (value as? Int)?.let { decode(it) } + override fun toString() = "ItemType" } - object ObjectType : ColumnType { - override val default = -1 - override fun read(reader: ConfigReader): String = reader.string() + object ObjectType : IntEncodedString() { override fun encode(value: String): Int = ObjectDefinitions.getOrNull(value)?.id ?: error("Unknown object: $value") override fun decode(value: Int): String = ObjectDefinitions.getOrNull(value)?.stringId ?: error("Unknown object: $value") - override fun cast(value: Any): String? = (value as? Int)?.let { decode(it) } + override fun toString() = "ObjectType" } - object IntList : SingleRowType>() { - override val default = emptyList() - override fun read(reader: ConfigReader) = reader.readList(IntType) - override fun cast(value: Any) = value as? List + object NPCType : IntEncodedString() { + override fun encode(value: String): Int = NPCDefinitions.getOrNull(value)?.id ?: error("Unknown object: $value") + override fun decode(value: Int): String = NPCDefinitions.getOrNull(value)?.stringId ?: error("Unknown object: $value") + override fun toString() = "NPCType" } - object StringList : SingleRowType>() { - override val default = emptyList() - override fun read(reader: ConfigReader) = reader.readList(StringType) - override fun cast(value: Any) = value as? List + object RowType : IntEncodedString() { + override fun encode(value: String): Int = Rows.ids[value] ?: error("Unknown table row: $value") + override fun decode(value: Int): String = Rows.getOrNull(value)?.stringId ?: error("Unknown table row: $value") + override fun toString() = "RowType" } - object ItemList : ColumnType, IntArray> { - override val default = IntArray(0) - override fun read(reader: ConfigReader) = reader.readList(StringType) - override fun cast(value: Any) = (value as? IntArray)?.let { decode(it) } - override fun encode(value: List) = value.map(ItemType::encode).toIntArray() - override fun decode(value: IntArray) = value.map(ItemType::decode) - } + object IntList : RowList(IntType) + object StringList : RowList(StringType) + object ItemList : RowList(ItemType) + object NPCList : RowList(NPCType) + object ObjectList : RowList(ObjectType) + object IntIntPair : RowPair(IntType, IntType) + object IntStringPair : RowPair(IntType, StringType) + object StringIntPair : RowPair(StringType, IntType) + object IntIntList : RowList>(RowPair(IntType, IntType)) + object IntStringList : RowList>(RowPair(IntType, StringType)) + object StringIntList : RowList>(RowPair(StringType, IntType)) - object ObjectList : ColumnType, IntArray> { - override val default = IntArray(0) - override fun read(reader: ConfigReader) = reader.readList(StringType) - override fun cast(value: Any) = (value as? IntArray)?.let { decode(it) } - override fun encode(value: List) = value.map(ObjectType::encode).toIntArray() - override fun decode(value: IntArray) = value.map(ObjectType::decode) - } + open class RowPair(val one: ColumnType, val two: ColumnType) : SingleRowType>() { + override val default = Pair(one.defaultValue, two.defaultValue) + override val size: Int = 2 - object ItemIdType : SingleRowType() { - override val default = -1 - override fun read(reader: ConfigReader): Int = ItemType.encode(reader.string()) - override fun cast(value: Any) = IntType.cast(value) - } + override fun default(index: Int): Any { + return if (index == 0) one.default(index) else two.default(index + 1) + } - object ItemIdList : SingleRowType() { - override val default = IntArray(0) - override fun read(reader: ConfigReader) = reader.readList(IntType).toIntArray() - override fun cast(value: Any) = value as? IntArray - } + override fun read(reader: ConfigReader): Pair { + throw NotImplementedError("Shouldn't be called") + } - object IntIntPair : SingleRowType>() { - override val default = Pair(IntType.default, IntType.default) - override fun read(reader: ConfigReader) = reader.readPair(IntType, IntType) - override fun cast(value: Any) = value as? Pair - } + override fun cast(value: Any): Pair? { + return value as? Pair + } - object StrIntPair : SingleRowType>() { - override val default = Pair(StringType.default, IntType.default) - override fun read(reader: ConfigReader) = reader.readPair(StringType, IntType) - override fun cast(value: Any) = value as? Pair - } + override fun default(defaults: Array, index: Int): Pair? { + val first = one.default(defaults, index) ?: return null + val second = two.default(defaults, index + one.size) ?: return null + return Pair(first, second) + } - object IntStrPair : SingleRowType>() { - override val default = Pair(IntType.default, StringType.default) - override fun read(reader: ConfigReader) = reader.readPair(IntType, StringType) - override fun cast(value: Any) = value as? Pair - } + override fun read(row: Array, index: Int): Pair? { + val first = one.read(row, index) ?: return null + val second = two.read(row, index + one.size) ?: return null + return Pair(first, second) + } - object IntIntList : SingleRowType>>() { - override val default = emptyList>() - override fun read(reader: ConfigReader) = reader.readList(IntIntPair) - override fun cast(value: Any) = value as? List> - } + override fun add(row: MutableList, reader: ConfigReader) { + one.add(row, reader) + two.add(row, reader) + } - object IntStrList : SingleRowType>>() { - override val default = emptyList>() - override fun read(reader: ConfigReader) = reader.readList(IntStrPair) - override fun cast(value: Any) = value as? List> - } + override fun set(row: Array, index: Int, reader: ConfigReader) { + var count = 0 + while (reader.nextElement()) { + when (count) { + 0 -> one.set(row, index, reader) + 1 -> two.set(row, index + one.size, reader) + else -> throw IllegalArgumentException("Unexpected pair index: $count") + } + count++ + } + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false - object StrIntList : SingleRowType>>() { - override val default = emptyList>() - override fun read(reader: ConfigReader) = reader.readList(StrIntPair) - override fun cast(value: Any) = value as? List> + other as RowPair<*, *> + + if (one != other.one) return false + if (two != other.two) return false + + return true + } + + override fun hashCode(): Int { + var result = one.hashCode() + result = 31 * result + two.hashCode() + return result + } + + override fun toString(): String { + return "RowPair($one, $two)" + } } - companion object { - fun type(name: String): ColumnType<*, *> = when (name.lowercase()) { - "int" -> IntType - "string" -> StringType - "item" -> ItemType - "gameobject" -> ObjectType - "row" -> RowType - "list" -> IntList - "list" -> StringList - "list" -> ItemList - "list" -> ObjectList - "pair" -> IntIntPair - "pair" -> StrIntPair - "pair" -> IntStrPair - "list>" -> IntIntList - "list>" -> StrIntList - "list>" -> IntStrList - else -> throw IllegalArgumentException("Unsupported type $name") - } - - private fun ConfigReader.readPair(one: ColumnType, two: ColumnType): Pair { + open class RowTriple(val one: ColumnType, val two: ColumnType, val three: ColumnType) : SingleRowType>() { + override val default = Triple(one.defaultValue, two.defaultValue, three.defaultValue) + override val size: Int = 2 + + override fun default(index: Int): Any { + return when (index) { + 0 -> one.default(index) + 1 -> two.default(index + one.size) + 2 -> three.default(index + one.size + two.size) + else -> throw IllegalArgumentException("Unexpected pair index: $index") + } + } + + override fun read(reader: ConfigReader): Triple { + throw NotImplementedError("Shouldn't be called") + } + + override fun cast(value: Any): Triple? { + return value as? Triple + } + + override fun default(defaults: Array, index: Int): Triple? { + val first = one.default(defaults, index) ?: return null + val second = two.default(defaults, index + one.size) ?: return null + val third = three.default(defaults, index + one.size + two.size) ?: return null + return Triple(first, second, third) + } + + override fun read(row: Array, index: Int): Triple? { + val first = one.read(row, index) ?: return null + val second = two.read(row, index + one.size) ?: return null + val third = three.read(row, index + one.size + two.size) ?: return null + return Triple(first, second, third) + } + + override fun add(row: MutableList, reader: ConfigReader) { + one.add(row, reader) + two.add(row, reader) + three.add(row, reader) + } + + override fun set(row: Array, index: Int, reader: ConfigReader) { var index = 0 - var a = one.defaultValue - var b = two.defaultValue - while (nextElement()) { - when (index++) { - 0 -> a = one.read(this) - 1 -> b = two.read(this) + while (reader.nextElement()) { + when (index) { + 0 -> one.set(row, index, reader) + 1 -> two.set(row, index + one.size, reader) + 2 -> three.set(row, index + one.size + two.size, reader) else -> throw IllegalArgumentException("Unexpected pair index: $index") } + index++ } - return Pair(a, b) } - private fun ConfigReader.readList(type: ColumnType): List { - val list = mutableListOf() - while (nextElement()) { - list.add(type.read(this)) + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as RowTriple<*, *, *> + + if (one != other.one) return false + if (two != other.two) return false + if (three != other.three) return false + + return true + } + + override fun hashCode(): Int { + var result = one.hashCode() + result = 31 * result + two.hashCode() + result = 31 * result + three.hashCode() + return result + } + + override fun toString(): String { + return "RowTriple($one, $two, $three)" + } + + } + + open class RowList( + val type: ColumnType, + size: Int = 0 + ) : SingleRowType>() { + override val default = emptyList() + override val size: Int = (size * type.size) + 1 + + override fun read(reader: ConfigReader): List { + throw NotImplementedError("Shouldn't be called") + } + + override fun cast(value: Any): List? { + return value as? List + } + + override fun default(defaults: Array, index: Int): List? { + return read(defaults, index) + } + + override fun read(row: Array, index: Int): List? { + val size = IntType.read(row, index) ?: return null + return List(size) { type.read(row, it + 1)!! } + } + + override fun add(row: MutableList, reader: ConfigReader) { + val index = row.size + row.add(0) // Placeholder + var count = 0 + while (reader.nextElement()) { + type.add(row, reader) + count += type.size + } + row[index] = count + } + + override fun set(row: Array, index: Int, reader: ConfigReader) { + var acc = 0 + var count = 0 + while (reader.nextElement()) { + type.set(row, index + 1 + acc, reader) + acc += type.size + count++ + } + println("Set size $index $count") + row[index] = count + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as RowList<*> + + return type == other.type + } + + override fun hashCode(): Int { + return type.hashCode() + } + + override fun toString(): String { + return "RowList($type)" + } + + } + + companion object { + fun type(name: String): ColumnType<*, *> = when (name) { + "Boolean" -> BooleanType + "Int" -> IntType + "String" -> StringType + "NPC" -> NPCType + "Item" -> ItemType + "GameObject" -> ObjectType + "Row" -> RowType + else -> if (name.startsWith("Pair<")) { + val (first, second) = name.substringAfter("<").removeSuffix(">").split(",") + RowPair(type(first.trim()), type(second.trim())) + } else if (name.startsWith("Triple<")) { + val (first, second, third) = name.substringAfter("<").removeSuffix(">").split(",") + RowTriple(type(first.trim()), type(second.trim()), type(third.trim())) + } else if (name.startsWith("List<") && name.contains(">(")) { + val type = name.substringAfter("<").substringBefore(">(") + val size = name.substringAfter(">(").removeSuffix(")").trim().toInt() + RowList(type(type), size) + } else { + throw IllegalArgumentException("Unsupported type '$name'") } - return list } } diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt index 857a5ba0d7..cd80b3928f 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt @@ -5,6 +5,8 @@ import world.gregs.config.Config import world.gregs.config.ConfigReader import world.gregs.voidps.engine.data.config.RowDefinition import world.gregs.voidps.engine.data.config.TableDefinition +import world.gregs.voidps.engine.data.definition.ColumnType.ObjectType +import world.gregs.voidps.engine.data.definition.ColumnType.RowList import world.gregs.voidps.engine.timedLoad object Tables { @@ -26,6 +28,14 @@ object Tables { return row.data[index] != null } + /* + Primitives + */ + + fun bool(path: String): Boolean = get(path, ColumnType.BooleanType) + + fun boolOrNull(path: String): Boolean? = getOrNull(path, ColumnType.BooleanType) + fun int(path: String): Int = get(path, ColumnType.IntType) fun intOrNull(path: String): Int? = getOrNull(path, ColumnType.IntType) @@ -34,6 +44,22 @@ object Tables { fun stringOrNull(path: String): String? = getOrNull(path, ColumnType.StringType) + /* + Entities + */ + + fun item(path: String): String = get(path, ColumnType.ItemType) + + fun itemOrNull(path: String): String? = getOrNull(path, ColumnType.ItemType) + + fun obj(path: String): String = get(path, ObjectType) + + fun objOrNull(path: String): String? = getOrNull(path, ObjectType) + + fun npc(path: String): String = get(path, ColumnType.NPCType) + + fun npcOrNull(path: String): String? = getOrNull(path, ColumnType.NPCType) + fun row(path: String): Array = Rows.get(get(path, ColumnType.RowType)).data fun rowOrNull(path: String): Array? { @@ -41,13 +67,9 @@ object Tables { return Rows.getOrNull(id)?.data } - fun item(path: String): String = get(path, ColumnType.ItemType) - - fun itemOrNull(path: String): String? = getOrNull(path, ColumnType.ItemType) - - fun obj(path: String): String = get(path, ColumnType.ObjectType) - - fun objOrNull(path: String): String? = getOrNull(path, ColumnType.ObjectType) + /* + Primitive Lists + */ fun intList(path: String): List = get(path, ColumnType.IntList) @@ -57,6 +79,11 @@ object Tables { fun stringListOrNull(path: String): List? = getOrNull(path, ColumnType.StringList) + + /* + Entity Lists + */ + fun itemList(path: String): List = get(path, ColumnType.ItemList) fun itemListOrNull(path: String): List? = getOrNull(path, ColumnType.ItemList) @@ -65,29 +92,38 @@ object Tables { fun objListOrNull(path: String): List? = getOrNull(path, ColumnType.ObjectList) + fun npcList(path: String): List = get(path, ColumnType.NPCList) + + fun npcListOrNull(path: String): List? = getOrNull(path, ColumnType.NPCList) + + + /* + Primitive Pairs + */ + fun intPair(path: String): Pair = get(path, ColumnType.IntIntPair) fun intPairOrNull(path: String): Pair? = getOrNull(path, ColumnType.IntIntPair) - fun strIntPair(path: String): Pair = get(path, ColumnType.StrIntPair) + fun strIntPair(path: String): Pair = get(path, ColumnType.StringIntPair) - fun strIntPairOrNull(path: String): Pair? = getOrNull(path, ColumnType.StrIntPair) + fun strIntPairOrNull(path: String): Pair? = getOrNull(path, ColumnType.StringIntPair) - fun intStrPair(path: String): Pair = get(path, ColumnType.IntStrPair) + fun intStrPair(path: String): Pair = get(path, ColumnType.IntStringPair) - fun intStrPairOrNull(path: String): Pair? = getOrNull(path, ColumnType.IntStrPair) + fun intStrPairOrNull(path: String): Pair? = getOrNull(path, ColumnType.IntStringPair) fun intPairList(path: String): List> = get(path, ColumnType.IntIntList) fun intPairListOrNull(path: String): List>? = getOrNull(path, ColumnType.IntIntList) - fun strIntList(path: String): List> = get(path, ColumnType.StrIntList) + fun strIntList(path: String): List> = get(path, ColumnType.StringIntList) - fun strIntListOrNull(path: String): List>? = getOrNull(path, ColumnType.StrIntList) + fun strIntListOrNull(path: String): List>? = getOrNull(path, ColumnType.StringIntList) - fun intStrList(path: String): List> = get(path, ColumnType.IntStrList) + fun intStrList(path: String): List> = get(path, ColumnType.IntStringList) - fun intStrListOrNull(path: String): List>? = getOrNull(path, ColumnType.IntStrList) + fun intStrListOrNull(path: String): List>? = getOrNull(path, ColumnType.IntStringList) private fun get(table: String, column: String, row: Int, type: ColumnType): T { return definitions[table]?.get(column, row, type) ?: error("Table '$table' not found") @@ -98,7 +134,7 @@ object Tables { return definition.getOrNull(column, row, type) } - private fun get(path: String, type: ColumnType): T { + fun get(path: String, type: ColumnType): T { val (table, row, column) = path.split(".") val id = Rows.ids[row] ?: error("Row '$row' not found") return get(table, column, id, type) @@ -124,6 +160,7 @@ object Tables { fun load(paths: List): Tables { require(ItemDefinitions.loaded) { "Item definitions must be loaded before tables" } require(ObjectDefinitions.loaded) { "Object definitions must be loaded before tables" } + require(NPCDefinitions.loaded) { "NPC definitions must be loaded before tables" } timedLoad("table config") { val definitions = mutableMapOf() val rows = mutableListOf() @@ -156,13 +193,13 @@ object Tables { private fun readTableRow(reader: ConfigReader, definitions: MutableMap, rows: MutableList, ids: MutableMap, key: String, rowName: String) { val builder = definitions[key] requireNotNull(builder) { "Table header not found '$key' at ${reader.exception()}." } - val row = arrayOfNulls(builder.types.size) + val row = arrayOfNulls(builder.types.sumOf { it.size }) while (reader.nextPair()) { val column = reader.key() val index = builder.columns[column] requireNotNull(index) { "Column '$column' not found in table '$key' at ${reader.exception()}." } val type = builder.types[index] - row[index] = type.readEncoded(reader) + type.set(row, index, reader) } require(!ids.containsKey(rowName)) { "Duplicate row id found '$rowName' at ${reader.exception()}." } val id = rows.size @@ -190,7 +227,7 @@ object Tables { private class TableBuilder { val columns = mutableMapOf() val types = mutableListOf>() - val defaults = mutableListOf() + val defaults = mutableListOf() val rows = mutableListOf() private var columnIndex = 0 @@ -203,10 +240,14 @@ object Tables { fun addColumn(name: String, type: String) { require(!columns.containsKey(name)) { "Duplicate column name $name in table definition" } - columns[name] = columnIndex++ + columns[name] = columnIndex val columnType = ColumnType.type(type) - types.add(columnType) - defaults.add(columnType.default) + columnIndex += columnType.size + println("Add column $name ${columnIndex} ${columnType.size}") + for (i in 0 until columnType.size) { + types.add(columnType) + defaults.add(columnType.default(i)) + } } fun addRow(id: Int) = rows.add(id) diff --git a/engine/src/test/kotlin/world/gregs/voidps/engine/data/definition/ColumnTypeTest.kt b/engine/src/test/kotlin/world/gregs/voidps/engine/data/definition/ColumnTypeTest.kt new file mode 100644 index 0000000000..50b944f1a3 --- /dev/null +++ b/engine/src/test/kotlin/world/gregs/voidps/engine/data/definition/ColumnTypeTest.kt @@ -0,0 +1,43 @@ +package world.gregs.voidps.engine.data.definition + +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Test +import world.gregs.config.Config +import world.gregs.config.ConfigReader +import kotlin.test.assertContentEquals + +class ColumnTypeTest { + + @Test + fun `Pair type`() { + val type = ColumnType.RowPair(ColumnType.IntType, ColumnType.IntType) + + val array = arrayOfNulls(type.size) + Config.stringReader("[1, 4]") { + type.set(array, 0, this) + } + assertContentEquals(arrayOf(1, 4), array) + } + + @Test + fun `List type`() { + val type = ColumnType.RowList(ColumnType.IntType) + + val array = arrayOfNulls(4) + Config.stringReader("[1, 2, 3]") { + type.set(array, 0, this) + } + assertContentEquals(arrayOf(3, 1, 2, 3), array) + } + + @Test + fun `Triple list type`() { + val type = ColumnType.RowList(ColumnType.RowPair(ColumnType.StringType, ColumnType.IntType)) + + val array = arrayOfNulls(3) + Config.stringReader("[[\"test\", 3]]") { + type.set(array, 0, this) + } + assertContentEquals(arrayOf(1, "test", 3), array) + } +} \ No newline at end of file diff --git a/engine/src/test/kotlin/world/gregs/voidps/engine/data/definition/TablesTest.kt b/engine/src/test/kotlin/world/gregs/voidps/engine/data/definition/TablesTest.kt index eacd1e4305..b341d88226 100644 --- a/engine/src/test/kotlin/world/gregs/voidps/engine/data/definition/TablesTest.kt +++ b/engine/src/test/kotlin/world/gregs/voidps/engine/data/definition/TablesTest.kt @@ -4,8 +4,14 @@ import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertNotNull import org.junit.jupiter.api.assertThrows import world.gregs.voidps.cache.definition.data.ItemDefinition +import world.gregs.voidps.cache.definition.data.NPCDefinition import world.gregs.voidps.cache.definition.data.ObjectDefinition import world.gregs.voidps.engine.data.config.TableDefinition +import world.gregs.voidps.engine.data.definition.ColumnType.IntType +import world.gregs.voidps.engine.data.definition.ColumnType.ObjectType +import world.gregs.voidps.engine.data.definition.ColumnType.RowList +import world.gregs.voidps.engine.data.definition.ColumnType.RowPair +import world.gregs.voidps.engine.data.definition.ColumnType.StringType import kotlin.test.assertContentEquals import kotlin.test.assertEquals import kotlin.test.assertTrue @@ -22,6 +28,7 @@ class TablesTest { fun `Test loading a table`() { ItemDefinitions.set(arrayOf(ItemDefinition(id = 0, stringId = "item_id")), mapOf("item_id" to 0)) ObjectDefinitions.set(arrayOf(ObjectDefinition(id = 0, stringId = "obj_id")), mapOf("obj_id" to 0)) + NPCDefinitions.set(arrayOf(NPCDefinition(id = 0, stringId = "npc_id")), mapOf("npc_id" to 0)) val uri = TablesTest::class.java.getResource("test-table.toml")!! Tables.load(listOf(uri.path)) @@ -31,20 +38,22 @@ class TablesTest { assertNotNull(definition) assertColumns( listOf( - Field("int_field", ColumnType.IntType, 0), - Field("string_field", ColumnType.StringType, ""), - Field("item_field", ColumnType.ItemType, -1), - Field("obj_field", ColumnType.ObjectType, -1), - Field("int_list", ColumnType.IntList, emptyList()), - Field("str_list", ColumnType.StringList, emptyList()), - Field("item_list", ColumnType.ItemList, IntArray(0)), - Field("obj_list", ColumnType.ObjectList, IntArray(0)), - Field("int_int", ColumnType.IntIntPair, Pair(0, 0)), - Field("str_int", ColumnType.StrIntPair, Pair("", 0)), - Field("int_str", ColumnType.IntStrPair, Pair(0, "")), - Field("int_int_list", ColumnType.IntIntList, emptyList>()), - Field("str_int_list", ColumnType.StrIntList, emptyList>()), - Field("int_str_list", ColumnType.IntStrList, emptyList>()), + Field("int_field", ColumnType.IntType, 0), // int_field + Field("string_field", StringType, ""), // string_field + Field("item_field", ColumnType.ItemType, -1), // item_field + Field("obj_field", ColumnType.ObjectType, -1), // obj_field + Field("npc_field", ColumnType.NPCType, -1), // npc_field + Field("int_list", RowList(IntType, 3), emptyList()), // int_list + Field("str_list", RowList(StringType, 2), emptyList()), // str_list + Field("item_list", RowList(ColumnType.ItemType, 1), emptyList()), // item_list + Field("obj_list", RowList(ObjectType, 1), emptyList()), // obj_list + Field("npc_list", RowList(ColumnType.NPCType, 1), emptyList()), // npc_list + Field("int_int", RowPair(IntType, IntType), 0), // int_int + Field("str_int", RowPair(StringType, IntType), ""), // str_int + Field("int_str", RowPair(IntType, StringType), 0), // int_str + Field("int_int_list", ColumnType.RowList(RowPair(IntType, IntType), 2), emptyList>()), // int_int_list + Field("str_int_list", ColumnType.RowList(RowPair(StringType, IntType), 2), emptyList>()), // str_int_list + Field("int_str_list", ColumnType.RowList(RowPair(IntType, StringType), 2), emptyList>()), // int_str_list ), definition ) assertContentEquals(intArrayOf(0, 1), definition.rows) @@ -57,19 +66,25 @@ class TablesTest { "text", 0, 0, - listOf(1, 2, 3), - listOf("one", "two"), - intArrayOf(0), - intArrayOf(0), - Pair(1, 2), - Pair("one", 2), - Pair(1, "two"), - listOf(Pair(1, 2), Pair(3, 4)), - listOf(Pair("one", 2), Pair("three", 4)), - listOf(Pair(1, "two"), Pair(3, "four")), + 0, + 3, 1, 2, 3, // int list + 2, "one", "two", // str list + 1, 0, // item list + 1, 0, // obj list + 1, 0, // npc list + 1, 2, // int pair + "one", 2, // str/int pair + 1, "two", // int/str pair + 2, 1, 2, 3, 4, // int pair list + 2, "one", 2, "three", 4, // str/int list + 2, 1, "two", 3, "four", // int/str list ) - for (i in row.data.indices) { - assertAnyEquals(expected[i], row.data[i]!!, i) + println(row.data.toList()) + for (i in expected.indices) { + val expect = expected.getOrNull(i) ?: break + val actual = row.data[i] ?: break + println("${expect} $actual") + assertAnyEquals(expect, actual, "${expected[i]} index ${i}") } assertEquals(1, Tables.int("header.row.int_field")) @@ -104,18 +119,21 @@ class TablesTest { } private fun assertColumns(expected: List, definition: TableDefinition) { - for (i in expected.indices) { - assertAnyEquals(expected[i].default, definition.default[i], i) - assertAnyEquals(expected[i].type, definition.types[i], i) + var i = 0 + println("Check ${definition.types.toList()}") + for (field in expected) { + assertAnyEquals(field.default, definition.default[i], "${field} index $i") + assertAnyEquals(field.type, definition.types[i], "${field} index $i") + assertEquals(i, definition.columns[field.name]) + i += field.type.size } - assertEquals(expected.mapIndexed { index, it -> it.name to index }.toMap(), definition.columns) } - private fun assertAnyEquals(expect: Any, actual: Any, index: Int) { + private fun assertAnyEquals(expect: Any?, actual: Any?, index: String) { if (expect is IntArray && actual is IntArray) { assertContentEquals(expect, actual) } else { - assertEquals(expect, actual, "Failed at index $index") + assertEquals(expect, actual, "Failed at $index") } } } \ No newline at end of file diff --git a/engine/src/test/resources/world/gregs/voidps/engine/data/definition/test-table.toml b/engine/src/test/resources/world/gregs/voidps/engine/data/definition/test-table.toml index 50e0a12d7c..37d8ae9d2e 100644 --- a/engine/src/test/resources/world/gregs/voidps/engine/data/definition/test-table.toml +++ b/engine/src/test/resources/world/gregs/voidps/engine/data/definition/test-table.toml @@ -3,26 +3,30 @@ int_field = "Int" string_field = "String" item_field = "Item" obj_field = "GameObject" -int_list = "List" -str_list = "List" -item_list = "List" -obj_list = "List" +npc_field = "NPC" +int_list = "List(3)" +str_list = "List(2)" +item_list = "List(1)" +obj_list = "List(1)" +npc_list = "List(1)" int_int = "Pair" str_int = "Pair" int_str = "Pair" -int_int_list = "List>" -str_int_list = "List>" -int_str_list = "List>" +int_int_list = "List>(2)" +str_int_list = "List>(2)" +int_str_list = "List>(2)" [.row] string_field = "text" int_field = 1 item_field = "item_id" obj_field = "obj_id" +npc_field = "npc_id" int_list = [1, 2, 3] str_list = ["one", "two"] item_list = ["item_id"] obj_list = ["obj_id"] +npc_list = ["npc_id"] int_int = [1, 2] str_int = ["one", 2] int_str = [1, "two"] From 1553c4c0dfdfaf65acc5f94d5b3155bec7c04f4a Mon Sep 17 00:00:00 2001 From: GregHib Date: Tue, 24 Mar 2026 19:48:13 +0000 Subject: [PATCH 04/40] Add simplified, flexible version --- .../engine/data/config/TableDefinition.kt | 25 +- .../engine/data/definition/ColumnType.kt | 397 ++++++------------ .../voidps/engine/data/definition/Tables.kt | 91 ++-- .../engine/data/definition/ColumnTypeTest.kt | 27 +- .../engine/data/definition/TablesTest.kt | 79 ++-- .../engine/data/definition/test-table.toml | 16 +- 6 files changed, 228 insertions(+), 407 deletions(-) diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt index 4ab9bdfd48..0839ccbb72 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt @@ -9,38 +9,37 @@ import world.gregs.voidps.engine.data.definition.Rows */ data class TableDefinition( val columns: Map, - val types: Array>, + val types: Array>, val default: Array, val rows: IntArray, ) { - fun get(column: String, row: Int, type: ColumnType): T = getOrNull(column, row, type) ?: type.defaultValue + fun get(column: String, row: Int, type: ColumnType): T = getOrNull(column, row, type) ?: type.default - fun get(column: Int, row: Int, type: ColumnType): T = getOrNull(column, row, type) ?: type.defaultValue + fun get(column: Int, row: Int, type: ColumnType): T = getOrNull(column, row, type) ?: type.default - fun getOrNull(column: String, row: Int, type: ColumnType): T? { - val columnIndex = columns[column] ?: return type.defaultValue - require(types[columnIndex] == type) { "Column $column is not of expected type ${types[columnIndex]}, found $type" } + fun getOrNull(column: String, row: Int, type: ColumnType): T? { + val columnIndex = columns[column] ?: return null return getOrNull(columnIndex, row, type) } - fun getOrNull(column: Int, row: Int, type: ColumnType): T? { - require(types[column] == type) { "Column $column is not of expected type ${types[column]}, found $type" } + fun getOrNull(column: Int, row: Int, type: ColumnType): T? { return value(row, column, type) } - private fun value(row: Int, column: Int, type: ColumnType): T? { - val id = rows.getOrNull(row) ?: return type.default(default, column) + private fun value(row: Int, column: Int, type: ColumnType): T? { + val id = rows.getOrNull(row) ?: return type.default val rows = Rows.getOrNull(id)?.data ?: return null - return type.read(rows, column) + val value = rows[column] + return type.cast(value) } - fun findOrNull(searchColumn: String, value: Any, column: String, type: ColumnType): T? { + fun findOrNull(searchColumn: String, value: Any, column: String, type: ColumnType): T? { val searchIndex = columns[searchColumn] ?: return null return findOrNull(searchIndex, value, column, type) } - fun findOrNull(searchColumn: Int, value: Any, column: String, type: ColumnType): T? { + fun findOrNull(searchColumn: Int, value: Any, column: String, type: ColumnType): T? { val columnIndex = columns[column] ?: return null val row = findOrNull(searchColumn, value) ?: return null return value(row, columnIndex, type) diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnType.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnType.kt index ffb6d9bb02..56653c8fba 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnType.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnType.kt @@ -4,181 +4,41 @@ package world.gregs.voidps.engine.data.definition import world.gregs.config.ConfigReader -sealed interface ColumnType { - val size: Int - val default: Encoded - fun cast(value: Any): Access? - fun default(defaults: Array, index: Int): Access? - fun encode(value: Access): Encoded - fun decode(value: Encoded): Access - val defaultValue: Access - get() = decode(default) +sealed interface ColumnType { + val default: T + fun cast(value: Any?): T? = value as? T - fun default(index: Int): Any = default - - fun read(row: Array, index: Int): Access? - - fun add(row: MutableList, reader: ConfigReader) - - fun set(row: Array, index: Int, reader: ConfigReader) - - sealed class SingleRowType : ColumnType { - override val size = 1 - override fun encode(value: T) = value - override fun decode(value: T) = value - abstract fun read(reader: ConfigReader): T - - override fun add(row: MutableList, reader: ConfigReader) { - row.add(encode(read(reader))) - } - - override fun set(row: Array, index: Int, reader: ConfigReader) { - val value = read(reader) - println("Set $index $value") - row[index] = encode(value) - } - - override fun read(row: Array, index: Int): T? { - return cast(row[index] ?: return null) - } - - override fun default(defaults: Array, index: Int): T? { - val default = defaults.getOrNull(index) ?: return null - return cast(default) - } - } - - sealed class IntEncodedString : ColumnType { - override val size = 1 - override val default = -1 - - override fun cast(value: Any): String? = (value as? Int)?.let { decode(it) } - - override fun set(row: Array, index: Int, reader: ConfigReader) { - row[index] = encode(reader.string()) - } - - override fun add(row: MutableList, reader: ConfigReader) { - row.add(encode(reader.string())) - } - - override fun read(row: Array, index: Int): String? { - return cast(row[index] ?: return null) - } - - override fun default(defaults: Array, index: Int): String? { - val default = defaults.getOrNull(index) ?: return null - return cast(default) - } - } - - object BooleanType : SingleRowType() { + object ColumnBoolean : ColumnType { override val default = false - override fun read(reader: ConfigReader) = reader.boolean() - override fun cast(value: Any) = value as? Boolean - override fun toString() = "BooleanType" + override fun toString() = "ColumnBoolean" } - object IntType : SingleRowType() { + object ColumnInt : ColumnType { override val default = 0 - override fun read(reader: ConfigReader) = reader.int() - override fun cast(value: Any) = value as? Int - override fun toString() = "IntType" + override fun toString() = "ColumnInt" } - object StringType : SingleRowType() { + object ColumnString : ColumnType { override val default = "" - override fun read(reader: ConfigReader) = reader.string() - override fun cast(value: Any) = value as? String - override fun toString() = "StringType" + override fun toString() = "ColumnString" } - object ItemType : IntEncodedString() { - override fun encode(value: String): Int = ItemDefinitions.getOrNull(value)?.id ?: error("Unknown item: $value") - override fun decode(value: Int): String = ItemDefinitions.getOrNull(value)?.stringId ?: error("Unknown item: $value") - override fun toString() = "ItemType" - } - - object ObjectType : IntEncodedString() { - override fun encode(value: String): Int = ObjectDefinitions.getOrNull(value)?.id ?: error("Unknown object: $value") - override fun decode(value: Int): String = ObjectDefinitions.getOrNull(value)?.stringId ?: error("Unknown object: $value") - override fun toString() = "ObjectType" - } - - object NPCType : IntEncodedString() { - override fun encode(value: String): Int = NPCDefinitions.getOrNull(value)?.id ?: error("Unknown object: $value") - override fun decode(value: Int): String = NPCDefinitions.getOrNull(value)?.stringId ?: error("Unknown object: $value") - override fun toString() = "NPCType" - } - - object RowType : IntEncodedString() { - override fun encode(value: String): Int = Rows.ids[value] ?: error("Unknown table row: $value") - override fun decode(value: Int): String = Rows.getOrNull(value)?.stringId ?: error("Unknown table row: $value") - override fun toString() = "RowType" + object ColumnEntity : ColumnType { + override val default = -1 + override fun toString() = "ColumnEntity" } - object IntList : RowList(IntType) - object StringList : RowList(StringType) - object ItemList : RowList(ItemType) - object NPCList : RowList(NPCType) - object ObjectList : RowList(ObjectType) - object IntIntPair : RowPair(IntType, IntType) - object IntStringPair : RowPair(IntType, StringType) - object StringIntPair : RowPair(StringType, IntType) - object IntIntList : RowList>(RowPair(IntType, IntType)) - object IntStringList : RowList>(RowPair(IntType, StringType)) - object StringIntList : RowList>(RowPair(StringType, IntType)) - - open class RowPair(val one: ColumnType, val two: ColumnType) : SingleRowType>() { - override val default = Pair(one.defaultValue, two.defaultValue) - override val size: Int = 2 - - override fun default(index: Int): Any { - return if (index == 0) one.default(index) else two.default(index + 1) - } - - override fun read(reader: ConfigReader): Pair { - throw NotImplementedError("Shouldn't be called") - } - - override fun cast(value: Any): Pair? { - return value as? Pair - } - - override fun default(defaults: Array, index: Int): Pair? { - val first = one.default(defaults, index) ?: return null - val second = two.default(defaults, index + one.size) ?: return null - return Pair(first, second) - } - - override fun read(row: Array, index: Int): Pair? { - val first = one.read(row, index) ?: return null - val second = two.read(row, index + one.size) ?: return null - return Pair(first, second) - } - - override fun add(row: MutableList, reader: ConfigReader) { - one.add(row, reader) - two.add(row, reader) - } - - override fun set(row: Array, index: Int, reader: ConfigReader) { - var count = 0 - while (reader.nextElement()) { - when (count) { - 0 -> one.set(row, index, reader) - 1 -> two.set(row, index + one.size, reader) - else -> throw IllegalArgumentException("Unexpected pair index: $count") - } - count++ - } + open class ColumnPair(val one: ColumnType, val two: ColumnType) : ColumnType> { + override val default = Pair(one.default, two.default) + override fun toString(): String { + return "ColumnPair(one=$one, two=$two)" } override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false - other as RowPair<*, *> + other as ColumnPair<*, *> if (one != other.one) return false if (two != other.two) return false @@ -192,70 +52,19 @@ sealed interface ColumnType { return result } - override fun toString(): String { - return "RowPair($one, $two)" - } } - open class RowTriple(val one: ColumnType, val two: ColumnType, val three: ColumnType) : SingleRowType>() { - override val default = Triple(one.defaultValue, two.defaultValue, three.defaultValue) - override val size: Int = 2 - - override fun default(index: Int): Any { - return when (index) { - 0 -> one.default(index) - 1 -> two.default(index + one.size) - 2 -> three.default(index + one.size + two.size) - else -> throw IllegalArgumentException("Unexpected pair index: $index") - } - } - - override fun read(reader: ConfigReader): Triple { - throw NotImplementedError("Shouldn't be called") - } - - override fun cast(value: Any): Triple? { - return value as? Triple - } - - override fun default(defaults: Array, index: Int): Triple? { - val first = one.default(defaults, index) ?: return null - val second = two.default(defaults, index + one.size) ?: return null - val third = three.default(defaults, index + one.size + two.size) ?: return null - return Triple(first, second, third) - } - - override fun read(row: Array, index: Int): Triple? { - val first = one.read(row, index) ?: return null - val second = two.read(row, index + one.size) ?: return null - val third = three.read(row, index + one.size + two.size) ?: return null - return Triple(first, second, third) - } - - override fun add(row: MutableList, reader: ConfigReader) { - one.add(row, reader) - two.add(row, reader) - three.add(row, reader) - } - - override fun set(row: Array, index: Int, reader: ConfigReader) { - var index = 0 - while (reader.nextElement()) { - when (index) { - 0 -> one.set(row, index, reader) - 1 -> two.set(row, index + one.size, reader) - 2 -> three.set(row, index + one.size + two.size, reader) - else -> throw IllegalArgumentException("Unexpected pair index: $index") - } - index++ - } + open class ColumnTriple(val one: ColumnType, val two: ColumnType, val three: ColumnType) : ColumnType> { + override val default = Triple(one.default, two.default, three.default) + override fun toString(): String { + return "ColumnTriple(one=$one, two=$two, three=$three)" } override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false - other as RowTriple<*, *, *> + other as ColumnTriple<*, *, *> if (one != other.one) return false if (two != other.two) return false @@ -271,101 +80,133 @@ sealed interface ColumnType { return result } + } + + open class ColumnList(val type: ColumnType) : ColumnType> { + override val default = emptyList() override fun toString(): String { - return "RowTriple($one, $two, $three)" + return "ColumnList(type=$type)" } - } + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false - open class RowList( - val type: ColumnType, - size: Int = 0 - ) : SingleRowType>() { - override val default = emptyList() - override val size: Int = (size * type.size) + 1 + other as ColumnList<*> - override fun read(reader: ConfigReader): List { - throw NotImplementedError("Shouldn't be called") + return type == other.type } - override fun cast(value: Any): List? { - return value as? List + override fun hashCode(): Int { + return type.hashCode() } - override fun default(defaults: Array, index: Int): List? { - return read(defaults, index) - } + } - override fun read(row: Array, index: Int): List? { - val size = IntType.read(row, index) ?: return null - return List(size) { type.read(row, it + 1)!! } - } + object BooleanList : ColumnList(ColumnBoolean) + object IntList : ColumnList(ColumnInt) + object StringList : ColumnList(ColumnString) - override fun add(row: MutableList, reader: ConfigReader) { - val index = row.size - row.add(0) // Placeholder - var count = 0 - while (reader.nextElement()) { - type.add(row, reader) - count += type.size - } - row[index] = count - } + object IntIntPair : ColumnPair(ColumnInt, ColumnInt) + object IntStringPair : ColumnPair(ColumnInt, ColumnString) + object StringIntPair : ColumnPair(ColumnString, ColumnInt) - override fun set(row: Array, index: Int, reader: ConfigReader) { - var acc = 0 - var count = 0 - while (reader.nextElement()) { - type.set(row, index + 1 + acc, reader) - acc += type.size - count++ - } - println("Set size $index $count") - row[index] = count - } + object IntIntList : ColumnList>(ColumnPair(ColumnInt, ColumnInt)) + object IntStringList : ColumnList>(ColumnPair(ColumnInt, ColumnString)) + object StringIntList : ColumnList>(ColumnPair(ColumnString, ColumnInt)) +} - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false +sealed interface ColumnReader { + val type: ColumnType + fun list(): MutableList + fun read(reader: ConfigReader): T - other as RowList<*> + object ReaderBoolean : ColumnReader { + override val type = ColumnType.ColumnBoolean + override fun list() = mutableListOf() + override fun read(reader: ConfigReader) = reader.boolean() + } - return type == other.type - } + object ReaderInt : ColumnReader { + override val type = ColumnType.ColumnInt + override fun list() = mutableListOf() + override fun read(reader: ConfigReader) = reader.int() + } - override fun hashCode(): Int { - return type.hashCode() + class ReaderEntity(val definitions: Map) : ColumnReader { + override val type = ColumnType.ColumnEntity + override fun list() = mutableListOf() + override fun read(reader: ConfigReader) = definitions.getValue(reader.string()) + } + + object ReaderString : ColumnReader { + override val type = ColumnType.ColumnString + override fun list() = mutableListOf() + override fun read(reader: ConfigReader) = reader.string() + } + + data class ReaderPair(val one: ColumnReader, val two: ColumnReader) : ColumnReader> { + override val type = ColumnType.ColumnPair(one.type, two.type) + override fun list() = mutableListOf>() + override fun read(reader: ConfigReader): Pair { + reader.nextElement() + val one = one.read(reader) + reader.nextElement() + val two = two.read(reader) + reader.nextElement() + return Pair(one, two) } + } - override fun toString(): String { - return "RowList($type)" + data class ReaderTriple(val one: ColumnReader, val two: ColumnReader, val three: ColumnReader) : ColumnReader> { + override val type = ColumnType.ColumnTriple(one.type, two.type, three.type) + override fun list() = mutableListOf>() + override fun read(reader: ConfigReader): Triple { + reader.nextElement() + val one = one.read(reader) + reader.nextElement() + val two = two.read(reader) + reader.nextElement() + val three = three.read(reader) + reader.nextElement() + return Triple(one, two, three) } + } + data class ReaderList(val read: ColumnReader) : ColumnReader> { + override val type = ColumnType.ColumnList(read.type) + override fun list() = mutableListOf>() + override fun read(reader: ConfigReader): List { + val list = read.list() + while (reader.nextElement()) { + list.add(read.read(reader)) + } + return list + } } companion object { - fun type(name: String): ColumnType<*, *> = when (name) { - "Boolean" -> BooleanType - "Int" -> IntType - "String" -> StringType - "NPC" -> NPCType - "Item" -> ItemType - "GameObject" -> ObjectType - "Row" -> RowType + fun reader(name: String): ColumnReader<*> = when (name) { + "Boolean" -> ReaderBoolean + "Int" -> ReaderInt + "String" -> ReaderString + "NPC" -> ReaderEntity(NPCDefinitions.ids) + "Item" -> ReaderEntity(ItemDefinitions.ids) + "GameObject" -> ReaderEntity(ObjectDefinitions.ids) + "Row" -> ReaderEntity(Rows.ids) else -> if (name.startsWith("Pair<")) { val (first, second) = name.substringAfter("<").removeSuffix(">").split(",") - RowPair(type(first.trim()), type(second.trim())) + ReaderPair(reader(first.trim()), reader(second.trim())) } else if (name.startsWith("Triple<")) { val (first, second, third) = name.substringAfter("<").removeSuffix(">").split(",") - RowTriple(type(first.trim()), type(second.trim()), type(third.trim())) - } else if (name.startsWith("List<") && name.contains(">(")) { - val type = name.substringAfter("<").substringBefore(">(") - val size = name.substringAfter(">(").removeSuffix(")").trim().toInt() - RowList(type(type), size) + ReaderTriple(reader(first.trim()), reader(second.trim()), reader(third.trim())) + } else if (name.startsWith("List<") && name.endsWith(">")) { + val type = name.substringAfter("<").substringBefore(">") + ReaderList(reader(type)) } else { throw IllegalArgumentException("Unsupported type '$name'") } } } -} \ No newline at end of file +} diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt index cd80b3928f..4291aefcb8 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt @@ -5,8 +5,6 @@ import world.gregs.config.Config import world.gregs.config.ConfigReader import world.gregs.voidps.engine.data.config.RowDefinition import world.gregs.voidps.engine.data.config.TableDefinition -import world.gregs.voidps.engine.data.definition.ColumnType.ObjectType -import world.gregs.voidps.engine.data.definition.ColumnType.RowList import world.gregs.voidps.engine.timedLoad object Tables { @@ -32,38 +30,50 @@ object Tables { Primitives */ - fun bool(path: String): Boolean = get(path, ColumnType.BooleanType) + fun bool(path: String): Boolean = get(path, ColumnType.ColumnBoolean) - fun boolOrNull(path: String): Boolean? = getOrNull(path, ColumnType.BooleanType) + fun boolOrNull(path: String): Boolean? = getOrNull(path, ColumnType.ColumnBoolean) - fun int(path: String): Int = get(path, ColumnType.IntType) + fun int(path: String): Int = get(path, ColumnType.ColumnInt) - fun intOrNull(path: String): Int? = getOrNull(path, ColumnType.IntType) + fun intOrNull(path: String): Int? = getOrNull(path, ColumnType.ColumnInt) - fun string(path: String): String = get(path, ColumnType.StringType) + fun string(path: String): String = get(path, ColumnType.ColumnString) - fun stringOrNull(path: String): String? = getOrNull(path, ColumnType.StringType) + fun stringOrNull(path: String): String? = getOrNull(path, ColumnType.ColumnString) /* Entities */ - fun item(path: String): String = get(path, ColumnType.ItemType) + fun item(path: String): String = ItemDefinitions.get(get(path, ColumnType.ColumnEntity)).stringId - fun itemOrNull(path: String): String? = getOrNull(path, ColumnType.ItemType) + fun itemOrNull(path: String): String? { + val id = getOrNull(path, ColumnType.ColumnEntity) ?: return null + val item = ItemDefinitions.getOrNull(id) ?: return null + return item.stringId + } - fun obj(path: String): String = get(path, ObjectType) + fun obj(path: String): String = ObjectDefinitions.get(get(path, ColumnType.ColumnEntity)).stringId - fun objOrNull(path: String): String? = getOrNull(path, ObjectType) + fun objOrNull(path: String): String? { + val id = getOrNull(path, ColumnType.ColumnEntity) ?: return null + val obj = ObjectDefinitions.getOrNull(id) ?: return null + return obj.stringId + } - fun npc(path: String): String = get(path, ColumnType.NPCType) + fun npc(path: String): String = NPCDefinitions.get(get(path, ColumnType.ColumnEntity)).stringId - fun npcOrNull(path: String): String? = getOrNull(path, ColumnType.NPCType) + fun npcOrNull(path: String): String? { + val id = getOrNull(path, ColumnType.ColumnEntity) ?: return null + val npc = NPCDefinitions.getOrNull(id) ?: return null + return npc.stringId + } - fun row(path: String): Array = Rows.get(get(path, ColumnType.RowType)).data + fun row(path: String): Array = Rows.get(get(path, ColumnType.ColumnInt)).data fun rowOrNull(path: String): Array? { - val id = getOrNull(path, ColumnType.RowType) ?: return null + val id = getOrNull(path, ColumnType.ColumnInt) ?: return null return Rows.getOrNull(id)?.data } @@ -84,18 +94,17 @@ object Tables { Entity Lists */ - fun itemList(path: String): List = get(path, ColumnType.ItemList) + fun itemList(path: String): List = get(path, ColumnType.IntList).map { ItemDefinitions.get(it).stringId } - fun itemListOrNull(path: String): List? = getOrNull(path, ColumnType.ItemList) + fun itemListOrNull(path: String): List? = getOrNull(path, ColumnType.IntList)?.map { ItemDefinitions.get(it).stringId } - fun objList(path: String): List = get(path, ColumnType.ObjectList) + fun objList(path: String): List = get(path, ColumnType.IntList).map { ObjectDefinitions.get(it).stringId } - fun objListOrNull(path: String): List? = getOrNull(path, ColumnType.ObjectList) + fun objListOrNull(path: String): List? = getOrNull(path, ColumnType.IntList)?.map { ObjectDefinitions.get(it).stringId } - fun npcList(path: String): List = get(path, ColumnType.NPCList) - - fun npcListOrNull(path: String): List? = getOrNull(path, ColumnType.NPCList) + fun npcList(path: String): List = get(path, ColumnType.IntList).map { NPCDefinitions.get(it).stringId } + fun npcListOrNull(path: String): List? = getOrNull(path, ColumnType.IntList)?.map { NPCDefinitions.get(it).stringId } /* Primitive Pairs @@ -125,22 +134,22 @@ object Tables { fun intStrListOrNull(path: String): List>? = getOrNull(path, ColumnType.IntStringList) - private fun get(table: String, column: String, row: Int, type: ColumnType): T { + private fun get(table: String, column: String, row: Int, type: ColumnType): T { return definitions[table]?.get(column, row, type) ?: error("Table '$table' not found") } - private fun getOrNull(table: String, column: String, row: Int, type: ColumnType): T? { + private fun getOrNull(table: String, column: String, row: Int, type: ColumnType): T? { val definition = definitions[table] ?: error("Table '$table' not found") return definition.getOrNull(column, row, type) } - fun get(path: String, type: ColumnType): T { + fun get(path: String, type: ColumnType): T { val (table, row, column) = path.split(".") val id = Rows.ids[row] ?: error("Row '$row' not found") return get(table, column, id, type) } - private fun getOrNull(path: String, type: ColumnType): T? { + private fun getOrNull(path: String, type: ColumnType): T? { val (table, row, column) = path.split(".") val id = Rows.ids[row] ?: error("Row '$row' not found") return getOrNull(table, column, id, type) @@ -193,13 +202,13 @@ object Tables { private fun readTableRow(reader: ConfigReader, definitions: MutableMap, rows: MutableList, ids: MutableMap, key: String, rowName: String) { val builder = definitions[key] requireNotNull(builder) { "Table header not found '$key' at ${reader.exception()}." } - val row = arrayOfNulls(builder.types.sumOf { it.size }) + val row = arrayOfNulls(builder.readers.size) while (reader.nextPair()) { - val column = reader.key() - val index = builder.columns[column] - requireNotNull(index) { "Column '$column' not found in table '$key' at ${reader.exception()}." } - val type = builder.types[index] - type.set(row, index, reader) + val name = reader.key() + val index = builder.columns[name] + requireNotNull(index) { "Column '$name' not found in table '$key' at ${reader.exception()}." } + val column = builder.readers[index] + row[index] = column.read(reader) } require(!ids.containsKey(rowName)) { "Duplicate row id found '$rowName' at ${reader.exception()}." } val id = rows.size @@ -226,7 +235,7 @@ object Tables { private class TableBuilder { val columns = mutableMapOf() - val types = mutableListOf>() + val readers = mutableListOf>() val defaults = mutableListOf() val rows = mutableListOf() private var columnIndex = 0 @@ -240,21 +249,17 @@ object Tables { fun addColumn(name: String, type: String) { require(!columns.containsKey(name)) { "Duplicate column name $name in table definition" } - columns[name] = columnIndex - val columnType = ColumnType.type(type) - columnIndex += columnType.size - println("Add column $name ${columnIndex} ${columnType.size}") - for (i in 0 until columnType.size) { - types.add(columnType) - defaults.add(columnType.default(i)) - } + columns[name] = columnIndex++ + val reader = ColumnReader.reader(type) + readers.add(reader) + defaults.add(reader.type.default) } fun addRow(id: Int) = rows.add(id) fun build() = TableDefinition( columns, - types.toTypedArray(), + readers.map { it.type }.toTypedArray(), defaults.toTypedArray(), rows.toIntArray(), ) diff --git a/engine/src/test/kotlin/world/gregs/voidps/engine/data/definition/ColumnTypeTest.kt b/engine/src/test/kotlin/world/gregs/voidps/engine/data/definition/ColumnTypeTest.kt index 50b944f1a3..eadf358605 100644 --- a/engine/src/test/kotlin/world/gregs/voidps/engine/data/definition/ColumnTypeTest.kt +++ b/engine/src/test/kotlin/world/gregs/voidps/engine/data/definition/ColumnTypeTest.kt @@ -1,43 +1,32 @@ package world.gregs.voidps.engine.data.definition -import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.Test import world.gregs.config.Config -import world.gregs.config.ConfigReader -import kotlin.test.assertContentEquals +import kotlin.test.assertEquals class ColumnTypeTest { @Test fun `Pair type`() { - val type = ColumnType.RowPair(ColumnType.IntType, ColumnType.IntType) - - val array = arrayOfNulls(type.size) + val type = ColumnReader.ReaderPair(ColumnReader.ReaderInt, ColumnReader.ReaderInt) Config.stringReader("[1, 4]") { - type.set(array, 0, this) + assertEquals(Pair(1, 4), type.read(this)) } - assertContentEquals(arrayOf(1, 4), array) } @Test fun `List type`() { - val type = ColumnType.RowList(ColumnType.IntType) - - val array = arrayOfNulls(4) + val type = ColumnReader.ReaderList(ColumnReader.ReaderInt) Config.stringReader("[1, 2, 3]") { - type.set(array, 0, this) + assertEquals(listOf(1, 2, 3), type.read(this)) } - assertContentEquals(arrayOf(3, 1, 2, 3), array) } @Test - fun `Triple list type`() { - val type = ColumnType.RowList(ColumnType.RowPair(ColumnType.StringType, ColumnType.IntType)) - - val array = arrayOfNulls(3) + fun `Pair list type`() { + val type = ColumnReader.ReaderList(ColumnReader.ReaderPair(ColumnReader.ReaderString, ColumnReader.ReaderInt)) Config.stringReader("[[\"test\", 3]]") { - type.set(array, 0, this) + assertEquals(listOf(Pair("test", 3)), type.read(this)) } - assertContentEquals(arrayOf(1, "test", 3), array) } } \ No newline at end of file diff --git a/engine/src/test/kotlin/world/gregs/voidps/engine/data/definition/TablesTest.kt b/engine/src/test/kotlin/world/gregs/voidps/engine/data/definition/TablesTest.kt index b341d88226..d8e9fd817c 100644 --- a/engine/src/test/kotlin/world/gregs/voidps/engine/data/definition/TablesTest.kt +++ b/engine/src/test/kotlin/world/gregs/voidps/engine/data/definition/TablesTest.kt @@ -2,16 +2,10 @@ package world.gregs.voidps.engine.data.definition import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertNotNull -import org.junit.jupiter.api.assertThrows import world.gregs.voidps.cache.definition.data.ItemDefinition import world.gregs.voidps.cache.definition.data.NPCDefinition import world.gregs.voidps.cache.definition.data.ObjectDefinition import world.gregs.voidps.engine.data.config.TableDefinition -import world.gregs.voidps.engine.data.definition.ColumnType.IntType -import world.gregs.voidps.engine.data.definition.ColumnType.ObjectType -import world.gregs.voidps.engine.data.definition.ColumnType.RowList -import world.gregs.voidps.engine.data.definition.ColumnType.RowPair -import world.gregs.voidps.engine.data.definition.ColumnType.StringType import kotlin.test.assertContentEquals import kotlin.test.assertEquals import kotlin.test.assertTrue @@ -20,7 +14,7 @@ class TablesTest { private data class Field( val name: String, - val type: ColumnType<*, *>, + val type: ColumnType<*>, val default: Any, ) @@ -38,22 +32,22 @@ class TablesTest { assertNotNull(definition) assertColumns( listOf( - Field("int_field", ColumnType.IntType, 0), // int_field - Field("string_field", StringType, ""), // string_field - Field("item_field", ColumnType.ItemType, -1), // item_field - Field("obj_field", ColumnType.ObjectType, -1), // obj_field - Field("npc_field", ColumnType.NPCType, -1), // npc_field - Field("int_list", RowList(IntType, 3), emptyList()), // int_list - Field("str_list", RowList(StringType, 2), emptyList()), // str_list - Field("item_list", RowList(ColumnType.ItemType, 1), emptyList()), // item_list - Field("obj_list", RowList(ObjectType, 1), emptyList()), // obj_list - Field("npc_list", RowList(ColumnType.NPCType, 1), emptyList()), // npc_list - Field("int_int", RowPair(IntType, IntType), 0), // int_int - Field("str_int", RowPair(StringType, IntType), ""), // str_int - Field("int_str", RowPair(IntType, StringType), 0), // int_str - Field("int_int_list", ColumnType.RowList(RowPair(IntType, IntType), 2), emptyList>()), // int_int_list - Field("str_int_list", ColumnType.RowList(RowPair(StringType, IntType), 2), emptyList>()), // str_int_list - Field("int_str_list", ColumnType.RowList(RowPair(IntType, StringType), 2), emptyList>()), // int_str_list + Field("int_field", ColumnType.ColumnInt, 0), // int_field + Field("string_field", ColumnType.ColumnString, ""), // string_field + Field("item_field", ColumnType.ColumnEntity, -1), // item_field + Field("obj_field", ColumnType.ColumnEntity, -1), // obj_field + Field("npc_field", ColumnType.ColumnEntity, -1), // npc_field + Field("int_list", ColumnType.ColumnList(ColumnType.ColumnInt), emptyList()), // int_list + Field("str_list", ColumnType.ColumnList(ColumnType.ColumnString), emptyList()), // str_list + Field("item_list", ColumnType.ColumnList(ColumnType.ColumnEntity), emptyList()), // item_list + Field("obj_list", ColumnType.ColumnList(ColumnType.ColumnEntity), emptyList()), // obj_list + Field("npc_list", ColumnType.ColumnList(ColumnType.ColumnEntity), emptyList()), // npc_list + Field("int_int", ColumnType.ColumnPair(ColumnType.ColumnInt, ColumnType.ColumnInt), Pair(0, 0)), // int_int + Field("str_int", ColumnType.ColumnPair(ColumnType.ColumnString, ColumnType.ColumnInt), Pair("", 0)), // str_int + Field("int_str", ColumnType.ColumnPair(ColumnType.ColumnInt, ColumnType.ColumnString), Pair(0, "")), // int_str + Field("int_int_list", ColumnType.ColumnList(ColumnType.ColumnPair(ColumnType.ColumnInt, ColumnType.ColumnInt)), emptyList>()), // int_int_list + Field("str_int_list", ColumnType.ColumnList(ColumnType.ColumnPair(ColumnType.ColumnString, ColumnType.ColumnInt)), emptyList>()), // str_int_list + Field("int_str_list", ColumnType.ColumnList(ColumnType.ColumnPair(ColumnType.ColumnInt, ColumnType.ColumnString)), emptyList>()), // int_str_list ), definition ) assertContentEquals(intArrayOf(0, 1), definition.rows) @@ -67,24 +61,22 @@ class TablesTest { 0, 0, 0, - 3, 1, 2, 3, // int list - 2, "one", "two", // str list - 1, 0, // item list - 1, 0, // obj list - 1, 0, // npc list - 1, 2, // int pair - "one", 2, // str/int pair - 1, "two", // int/str pair - 2, 1, 2, 3, 4, // int pair list - 2, "one", 2, "three", 4, // str/int list - 2, 1, "two", 3, "four", // int/str list + listOf(1, 2, 3), // int list + listOf("one", "two"), // str list + listOf(0), // item list + listOf(0), // obj list + listOf(0), // npc list + Pair(1, 2), // int pair + Pair("one", 2), // str/int pair + Pair(1, "two"), // int/str pair + listOf(Pair(1, 2), Pair(3, 4)), // int pair list + listOf(Pair("one", 2), Pair("three", 4)), // str/int list + listOf(Pair(1, "two"), Pair(3, "four")), // int/str list ) - println(row.data.toList()) for (i in expected.indices) { val expect = expected.getOrNull(i) ?: break val actual = row.data[i] ?: break - println("${expect} $actual") - assertAnyEquals(expect, actual, "${expected[i]} index ${i}") + assertAnyEquals(expect, actual, "${expected[i]} index $i") } assertEquals(1, Tables.int("header.row.int_field")) @@ -104,9 +96,7 @@ class TablesTest { assertEquals(0, Tables.int("header.row_two.int_field")) assertEquals("", Tables.string("header.row_two.string_field")) - assertThrows { - Tables.item("header.row_two.item_field") - } + assertEquals("", Tables.item("header.row_two.item_field")) assertEquals(emptyList(), Tables.intList("header.row_two.int_list")) assertEquals(emptyList(), Tables.stringList("header.row_two.str_list")) assertEquals(emptyList(), Tables.itemList("header.row_two.item_list")) @@ -119,13 +109,10 @@ class TablesTest { } private fun assertColumns(expected: List, definition: TableDefinition) { - var i = 0 - println("Check ${definition.types.toList()}") - for (field in expected) { - assertAnyEquals(field.default, definition.default[i], "${field} index $i") - assertAnyEquals(field.type, definition.types[i], "${field} index $i") + for ((i, field) in expected.withIndex()) { + assertAnyEquals(field.default, definition.default[i], "$field index $i") + assertAnyEquals(field.type, definition.types[i], "$field index $i") assertEquals(i, definition.columns[field.name]) - i += field.type.size } } diff --git a/engine/src/test/resources/world/gregs/voidps/engine/data/definition/test-table.toml b/engine/src/test/resources/world/gregs/voidps/engine/data/definition/test-table.toml index 37d8ae9d2e..fbd80bf65b 100644 --- a/engine/src/test/resources/world/gregs/voidps/engine/data/definition/test-table.toml +++ b/engine/src/test/resources/world/gregs/voidps/engine/data/definition/test-table.toml @@ -4,17 +4,17 @@ string_field = "String" item_field = "Item" obj_field = "GameObject" npc_field = "NPC" -int_list = "List(3)" -str_list = "List(2)" -item_list = "List(1)" -obj_list = "List(1)" -npc_list = "List(1)" +int_list = "List" +str_list = "List" +item_list = "List" +obj_list = "List" +npc_list = "List" int_int = "Pair" str_int = "Pair" int_str = "Pair" -int_int_list = "List>(2)" -str_int_list = "List>(2)" -int_str_list = "List>(2)" +int_int_list = "List>" +str_int_list = "List>" +int_str_list = "List>" [.row] string_field = "text" From abc87f71287767504a2fac0a54c79bb161f4e0dc Mon Sep 17 00:00:00 2001 From: GregHib Date: Wed, 25 Mar 2026 11:16:53 +0000 Subject: [PATCH 05/40] Convert slayer master enums to tables --- data/skill/slayer/chaeldar.enums.toml | 4 +- data/skill/slayer/chaeldar.tables.toml | 169 ++++++++ data/skill/slayer/duradel.tables.toml | 134 +++++++ data/skill/slayer/kuradal.tables.toml | 153 ++++++++ data/skill/slayer/mazchna.tables.toml | 154 ++++++++ data/skill/slayer/slayer.enums.toml | 4 +- data/skill/slayer/slayer.tables.toml | 366 ++++++++++++++++++ data/skill/slayer/sumona.tables.toml | 164 ++++++++ data/skill/slayer/turael.tables.toml | 124 ++++++ data/skill/slayer/vannaka.enums.toml | 4 +- data/skill/slayer/vannaka.tables.toml | 219 +++++++++++ .../engine/data/config/TableDefinition.kt | 12 + .../engine/data/definition/ColumnReader.kt | 112 ++++++ .../engine/data/definition/ColumnType.kt | 101 +---- .../engine/data/definition/EnumDefinitions.kt | 5 + .../voidps/engine/data/definition/Rows.kt | 2 +- .../voidps/engine/data/definition/Tables.kt | 13 +- game/src/main/kotlin/Main.kt | 6 + .../kotlin/content/skill/slayer/Slayer.kt | 58 +-- .../skill/slayer/master/SlayerMaster.kt | 12 +- game/src/main/resources/game.properties | 1 + game/src/test/kotlin/WorldTest.kt | 25 ++ 22 files changed, 1702 insertions(+), 140 deletions(-) create mode 100644 data/skill/slayer/chaeldar.tables.toml create mode 100644 data/skill/slayer/duradel.tables.toml create mode 100644 data/skill/slayer/kuradal.tables.toml create mode 100644 data/skill/slayer/mazchna.tables.toml create mode 100644 data/skill/slayer/slayer.tables.toml create mode 100644 data/skill/slayer/sumona.tables.toml create mode 100644 data/skill/slayer/turael.tables.toml create mode 100644 data/skill/slayer/vannaka.tables.toml create mode 100644 engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnReader.kt diff --git a/data/skill/slayer/chaeldar.enums.toml b/data/skill/slayer/chaeldar.enums.toml index bb62797999..fcb9ee85a5 100644 --- a/data/skill/slayer/chaeldar.enums.toml +++ b/data/skill/slayer/chaeldar.enums.toml @@ -34,7 +34,7 @@ values = { ice_troll_troll_country = "70-130", turoth = "70-130", tzhaar_mej = "90-150", - vampyre_juvenile = "80-100", + vampyre_juvinate = "80-100", warped_terrorbird = "70-130", } @@ -74,6 +74,6 @@ values = { ice_troll_troll_country = 11, turoth = 10, tzhaar_mej = 8, -# vampyre_juvenile = 6, +# vampyre_juvinate = 6, # warped_terrorbird = 6, } diff --git a/data/skill/slayer/chaeldar.tables.toml b/data/skill/slayer/chaeldar.tables.toml new file mode 100644 index 0000000000..d76d1bd9d9 --- /dev/null +++ b/data/skill/slayer/chaeldar.tables.toml @@ -0,0 +1,169 @@ +[chaeldar_slayer_tasks] +amount = "range" +weight = "int" +tip = "string" + +[.aberrant_spectre] +amount = [70, 130] +weight = 8 +tip = "Aberrant Spectres are fetid, vile ghosts. The very smell of them will paralyse and harm you. A nosepeg will help ignore their stink." + +[.abyssal_demon] +amount = [70, 130] +weight = 12 +tip = "Abyssal Demons are nasty creatures to fight. They aren't really part of this realm, and are able to move very quickly to trap their prey." + +[.aviansies] +amount = [70, 130] +weight = 9 +tip = "Aviansies are bird-like creatures found in the icy dungeons of the north. Melee weapons can't reach them, so use Magic or Ranged attacks." + +[.basilisks] +amount = [70, 130] +weight = 7 +tip = "Basilisks, like Cockatrice, have a gaze which will paralyse and harm their prey. You'll need a Mirror Shield to protect you." + +[.bloodvelds] +amount = [70, 130] +weight = 8 +tip = "Bloodveld are strange demonic creatures, their long rasping tongue has magical properties so it pierces straight through physical defences." + +[.brine_rats] +amount = [70, 130] +weight = 7 +tip = "Brine Rats can be found in caves that are near the sea. They are hairless, bad-tempered and generally unfriendly." + +[.black_demons] +amount = [70, 130] +weight = 10 +tip = "Powerful weapons known as demonbane weapons can be used to quickly defeat even powerful demons like the Black Demon with greater ease." + +[.blue_dragons] +amount = [70, 130] +weight = 8 +tip = "Like all dragons, Blue Dragons have thick scales and a powerful fiery breath. Stabbing weapons and heavy bolts are best suited to piercing their defences." + +[.cave_horrors] +amount = [70, 130] +weight = 10 +tip = "Cave Horrors can be found under Mos Le'Harmless. You will need a Witchwood Icon to fight them effectively." + +[.crabs] +amount = [70, 130] +weight = 8 +tip = "Crabs can be found all across Gielinor. They don't hit very hard but they can take a while to kill." + +[.dust_devils] +amount = [70, 130] +weight = 9 +tip = "Dust Devils use clouds of dust, sand, ash, and whatever else they can inhale to blind and disorientate their victims. Make sure to wear a facemask when fighting them." + +[.dagannoth] +amount = [70, 130] +weight = 11 +tip = "Dagannoth are large sea dwelling creatures which are very aggressive. You'll often find them in caves near sea water." + +#[.elves] +#amount = [70, 130] +#weight = 8 +#tip = "Elves are quick, agile, and vicious fighters which often favour bows and polearms." + +[.fire_giant] +amount = [70, 130] +weight = 12 +tip = "Like other giants, Fire Giants have little to no magical ability, and they're particularly weak to water spells." + +#[.fever_spiders] +#amount = [70, 130] +#weight = 7 +#tip = "Fever Spiders are giant spiders that carry the deadly Spider Fever. If you don't want to catch it I suggest you wear Slayer Gloves to fight them." + +[.gargoyles] +amount = [70, 130] +weight = 11 +tip = "Gargoyles are winged creatures of stone. You'll need to fight them to near death before breaking them apart with a Rock Hammer." + +[.greater_demons] +amount = [70, 130] +weight = 9 +tip = "Demons are particularly weak to water spells. Though Greater Demons are not the strongest type of demon they are still dangerous." + +[.hellhounds] +amount = [70, 130] +weight = 9 +tip = "Hellhounds are a cross between Dogs and Demons. They are dangerous with a fierce bite, but have all of the same weaknesses as most demons." + +[.jellies] +amount = [70, 130] +weight = 10 +tip = "Jellies are nasty cube-like gelatinous creatures which absorb everything they come across into themselves. Their magical acids bypass physical defences." + +[.jungle_horrors] +amount = [70, 130] +weight = 10 +tip = "Jungle Horrors can be found all over Mos Le'Harmless. They are strong and aggressive, so watch out!" + +[.kalphites] +amount = [70, 130] +weight = 11 +tip = "Kalphite are large insects which live in great hives under the desert sands." + +[.kurask] +amount = [70, 130] +weight = 12 +tip = "Kurask are large brutal creatures with very thick hides. You'll need a Leaf-Tipped Spear or Battle-axe, Broad Arrows, or a Magic Dart to harm it." + +[.lesser_demons] +amount = [70, 130] +weight = 9 +tip = "Demons are weak to magical attacks. Though Lesser Demons are relatively weak they are still dangerous." + +[.mutated_zygomites] +amount = [8, 15] +weight = 7 +tip = "Mutated Zygomites are hard to destroy. They regenerate quickly so you will need to finish them with fungicide." + +[.nechryael] +amount = [70, 130] +weight = 12 +tip = "Nechryael are demons of decay which summon small winged beings to help them fight their victims. Their minions can bypass protective prayers so be sure to wear thick armour." + +[.skeletal_wyverns] +amount = [10, 20] +weight = 7 +tip = "Skeletal Wyverns are extremely dangerous and they are hard to hit with arrows as they slip right through. To stand a good chance of surviving you'll need some elemental shielding from its icy breath." + +[.shadow_warriors] +amount = [70, 130] +weight = 8 +tip = "Shadow Warriors are dark and mysterious. They wear spectral plate armour, so crush weapons and magic will give them trouble." + +[.spiritual_creatures] +amount = [70, 130] +weight = 12 +tip = "Spiritual Creatures can be found in the icy caverns near Trollheim, supporting the cause of their chosen god. Wearing equipment aligned with each of the gods can help you avoid undesired conflict." + +[.turoth] +amount = [70, 130] +weight = 10 +tip = "Turoth are large vicious creatures with thick hides. You'll need a Leaf-Tipped Spear or Sword, Broad Arrows, or a Magic Dart to harm them." + +[.trolls] +amount = [70, 130] +weight = 11 +tip = "Trolls regenerate damage quickly and have some level of magical defences, but this is easily bypassed by their weakness to fire." + +[.tzhaar] +amount = [90, 150] +weight = 8 +tip = "Tzhaar reside in their cave under the Karamja volcano. Beware as they can call to their fellows for aid." + +#[.vampyres] +#amount = [80, 100] +#weight = 6 +#tip = "Vampyres are extremely powerful beings. An underground group known as the Myreque have been searching for tools to defeat them, which they may be willing to share if you can find them." + +#[.warped_creatures] +#amount = [70, 130] +#weight = 6 +#tip = "Warped Creatures can supposedly be found within a mysterious dungeon on the eastern edge of the Poison Waste. Be aware that to defeat them, you'll need to purify them in some way." diff --git a/data/skill/slayer/duradel.tables.toml b/data/skill/slayer/duradel.tables.toml new file mode 100644 index 0000000000..f44a9800bf --- /dev/null +++ b/data/skill/slayer/duradel.tables.toml @@ -0,0 +1,134 @@ +[duradel_slayer_tasks] +amount = "range" +weight = "int" +tip = "string" + +[.aberrant_spectre] +amount = [130, 200] +weight = 10 +tip = "Aberrant Spectres are fetid, vile ghosts. The very smell of them will paralyse and harm you. A nosepeg will help ignore their stink." + +[.abyssal_demon] +amount = [130, 200] +weight = 15 +tip = "Abyssal Demons are nasty creatures to fight. They aren't really part of this realm, and are able to move very quickly to trap their prey." + +[.aquanites] +amount = [130, 200] +weight = 9 +tip = "Aquanites rely on their lures for both offensive and defensive purposes. Whilst their hides are resistant to slashing attacks, a well timed cut is capable of severing the lure." + +[.aviansies] +amount = [100, 125] +weight = 8 +tip = "Aviansies are bird-like creatures found in the icy dungeons of the north. Melee weapons can't reach them, so use Magic or Ranged attacks." + +[.bloodvelds] +amount = [130, 200] +weight = 10 +tip = "Bloodveld are strange demonic creatures, their long rasping tongue has magical properties so it pierces straight through physical defences." + +[.black_demons] +amount = [130, 200] +weight = 10 +tip = "Powerful weapons known as demonbane weapons can be used to quickly defeat even powerful demons like the Black Demon with greater ease." + +[.black_dragons] +amount = [40, 80] +weight = 9 +tip = "Black Dragons are the strongest dragons and very fierce, watch out for their fiery breath." + +[.dark_beasts] +amount = [130, 200] +weight = 15 +tip = "Dark Beasts are large, dog-like predators. Their massively muscled bodies protect them from crushing weapons." + +[.dust_devils] +amount = [130, 200] +weight = 10 +tip = "Dust Devils use clouds of dust, sand, ash, and whatever else they can inhale to blind and disorientate their victims. Make sure to wear a facemask when fighting them." + +[.dagannoth] +amount = [130, 200] +weight = 10 +tip = "Dagannoth are large sea dwelling creatures which are very aggressive. You'll often find them in caves near sea water." + +[.fire_giant] +amount = [130, 200] +weight = 10 +tip = "Like other giants, Fire Giants have little to no magical ability, and they're particularly weak to water spells." + +[.gargoyles] +amount = [130, 200] +weight = 10 +tip = "Gargoyles are winged creatures of stone. You'll need to fight them to near death before breaking them apart with a Rock Hammer." + +[.gorak] +amount = [40, 80] +weight = 5 +tip = "Goraks are extremely aggressive creatures. They have been imprisoned on an alternative plane, which is only accesible by using the fairyrings. Be extremely careful, their touch drains health as well as skills! " + +[.greater_demons] +amount = [130, 200] +weight = 10 +tip = "Demons are particularly weak to water spells. Though Greater Demons are not the strongest type of demon they are still dangerous." + +[.hellhounds] +amount = [130, 200] +weight = 9 +tip = "Hellhounds are a cross between Dogs and Demons. They are dangerous with a fierce bite, but have all of the same weaknesses as most demons." + +[.iron_dragons] +amount = [40, 80] +weight = 9 +tip = "Iron Dragons are some of the weaker metallic dragons, their iron scales are far thicker than normal iron armour." + +[.kalphites] +amount = [130, 200] +weight = 10 +tip = "Kalphite are large insects which live in great hives under the desert sands." + +[.mithril_dragons] +amount = [4, 8] +weight = 7 +tip = "Mithril dragons are more vulnerable to magic and to stab-based melee attacks than to anything else." + +[.nechryael] +amount = [130, 200] +weight = 10 +tip = "Nechryael are demons of decay which summon small winged beings to help them fight their victims. Their minions can bypass protective prayers so be sure to wear thick armour." + +#[.scabarites] +#amount = [40, 80] +#weight = 10 +#tip = "Scabarites are insectoid creatures, found beyond the Kharidian deserts. Make sure not to fall into one of their pitfall traps or you'll be quickly overwhelmed." + +[.skeletal_wyverns] +amount = [40, 80] +weight = 5 +tip = "Skeletal Wyverns are extremely dangerous and they are hard to hit with arrows as they slip right through. To stand a good chance of surviving you'll need some elemental shielding from its icy breath." + +[.spiritual_creatures] +amount = [120, 185] +weight = 10 +tip = "Spiritual Creatures can be found in the icy caverns near Trollheim, supporting the cause of their chosen god. Wearing equipment aligned with each of the gods can help you avoid undesired conflict." + +[.steel_dragons] +amount = [40, 80] +weight = 7 +tip = "Steel Dragons are dangerous metallic dragons, their steel scales are far thicker than normal steel armour." + +[.suqahs] +amount = [40, 80] +weight = 5 +tip = "Suqahs can only be found on the mystical Lunar Isle. They are capable of melee and magic attacks and often drop hide, teeth and herbs!" + +[.waterfiends] +amount = [130, 200] +weight = 10 +tip = "Waterfiends are creatures of water, which live under the Baxtorian Lake. Their watery form is well defended against slashing and piercing weapons, so use something blunt." + +#[.warped_creatures] +#amount = [130, 200] +#weight = 9 +#tip = "Warped Creatures can supposedly be found within a mysterious dungeon on the eastern edge of the Poison Waste. Be aware that to defeat them, you'll need to purify them in some way." diff --git a/data/skill/slayer/kuradal.tables.toml b/data/skill/slayer/kuradal.tables.toml new file mode 100644 index 0000000000..19df0be408 --- /dev/null +++ b/data/skill/slayer/kuradal.tables.toml @@ -0,0 +1,153 @@ +[kuradal_slayer_tasks] +amount = "range" +weight = "int" +tip = "string" + +[.aberrant_spectre] +amount = [150, 250] +weight = 10 +tip = "Aberrant Spectres are fetid, vile ghosts. The very smell of them will paralyse and harm you. A nosepeg will help ignore their stink." + +[.abyssal_demon] +amount = [150, 250] +weight = 10 +tip = "Abyssal Demons are nasty creatures to fight. They aren't really part of this realm, and are able to move very quickly to trap their prey." + +[.aquanites] +amount = [160, 200] +weight = 10 +tip = "Aquanites rely on their lures for both offensive and defensive purposes. Whilst their hides are resistant to slashing attacks, a well timed cut is capable of severing the lure." + +[.aviansies] +amount = [125, 150] +weight = 9 +tip = "Aviansies are bird-like creatures found in the icy dungeons of the north. Melee weapons can't reach them, so use Magic or Ranged attacks." + +[.bloodvelds] +amount = [180, 250] +weight = 10 +tip = "Bloodveld are strange demonic creatures, their long rasping tongue has magical properties so it pierces straight through physical defences." + +[.black_demons] +amount = [190, 250] +weight = 10 +tip = "Powerful weapons known as demonbane weapons can be used to quickly defeat even powerful demons like the Black Demon with greater ease." + +[.black_dragons] +amount = [40, 90] +weight = 5 +tip = "Black Dragons are the strongest dragons and very fierce, watch out for their fiery breath." + +[.blue_dragons] +amount = [120, 200] +weight = 7 +tip = "Like all dragons, Blue Dragons have thick scales and a powerful fiery breath. Stabbing weapons and heavy bolts are best suited to piercing their defences." + +[.dark_beasts] +amount = [150, 250] +weight = 12 +tip = "Dark Beasts are large, dog-like predators. Their massively muscled bodies protect them from crushing weapons." + +[.dust_devils] +amount = [150, 250] +weight = 10 +tip = "Dust Devils use clouds of dust, sand, ash, and whatever else they can inhale to blind and disorientate their victims. Make sure to wear a facemask when fighting them." + +[.dagannoth] +amount = [170, 240] +weight = 10 +tip = "Dagannoth are large sea dwelling creatures which are very aggressive. You'll often find them in caves near sea water." + +#[.elves] +#amount = [120, 150] +#weight = 12 +#tip = "Elves are quick, agile, and vicious fighters which often favour bows and polearms." + +[.fire_giant] +amount = [170, 250] +weight = 10 +tip = "Like other giants, Fire Giants have little to no magical ability, and they're particularly weak to water spells." + +[.gargoyles] +amount = [150, 250] +weight = 12 +tip = "Gargoyles are winged creatures of stone. You'll need to fight them to near death before breaking them apart with a Rock Hammer." + +[.greater_demons] +amount = [150, 250] +weight = 11 +tip = "Demons are particularly weak to water spells. Though Greater Demons are not the strongest type of demon they are still dangerous." + +[.hellhounds] +amount = [130, 220] +weight = 10 +tip = "Hellhounds are a cross between Dogs and Demons. They are dangerous with a fierce bite, but have all of the same weaknesses as most demons." + +[.iron_dragons] +amount = [60, 110] +weight = 9 +tip = "Iron Dragons are some of the weaker metallic dragons, their iron scales are far thicker than normal iron armour." + +[.kalphites] +amount = [170, 250] +weight = 5 +tip = "Kalphite are large insects which live in great hives under the desert sands." + +#[.living_rock_creatures] +#amount = [120, 170] +#weight = 10 +#tip = "Found beneath the Dwarven mines, these are tough beings of rock. They can use ranged or melee attacks against you, so plan accordingly! " + +[.mithril_dragons] +amount = [30, 35] +weight = 8 +tip = "Mithril dragons are more vulnerable to magic and to stab-based melee attacks than to anything else." + +[.nechryael] +amount = [140, 220] +weight = 10 +tip = "Nechryael are demons of decay which summon small winged beings to help them fight their victims. Their minions can bypass protective prayers so be sure to wear thick armour." + +#[.scabarites] +#amount = [80, 120] +#weight = 10 +#tip = "Scabarites are insectoid creatures, found beyond the Kharidian deserts. Make sure not to fall into one of their pitfall traps or you'll be quickly overwhelmed." + +[.skeletal_wyverns] +amount = [40, 90] +weight = 5 +tip = "Skeletal Wyverns are extremely dangerous and they are hard to hit with arrows as they slip right through. To stand a good chance of surviving you'll need some elemental shielding from its icy breath." + +[.spiritual_creatures] +amount = [120, 185] +weight = 10 +tip = "Spiritual Creatures can be found in the icy caverns near Trollheim, supporting the cause of their chosen god. Wearing equipment aligned with each of the gods can help you avoid undesired conflict." + +[.steel_dragons] +amount = [40, 100] +weight = 9 +tip = "Steel Dragons are dangerous metallic dragons, their steel scales are far thicker than normal steel armour." + +[.suqahs] +amount = [50, 100] +weight = 5 +tip = "Suqahs can only be found on the mystical Lunar Isle. They are capable of melee and magic attacks and often drop hide, teeth and herbs!" + +#[.terror_dogs] +#amount = [60, 70] +#weight = 6 +#tip = "Terror dogs are, unsurprisingly, dogs that terrorise the weak. You'll find them in the Haunted Mine, near Tarn's lair." + +[.tzhaar] +amount = [80, 110] +weight = 7 +tip = "Tzhaar reside in their cave under the Karamja volcano. Beware as they can call to their fellows for aid." + +[.waterfiends] +amount = [170, 250] +weight = 9 +tip = "Waterfiends are creatures of water, which live under the Baxtorian Lake. Their watery form is well defended against slashing and piercing weapons, so use something blunt." + +[.warped_creatures] +amount = [150, 240] +tip = "Warped Creatures can supposedly be found within a mysterious dungeon on the eastern edge of the Poison Waste. Be aware that to defeat them, you'll need to purify them in some way." diff --git a/data/skill/slayer/mazchna.tables.toml b/data/skill/slayer/mazchna.tables.toml new file mode 100644 index 0000000000..9480d256e8 --- /dev/null +++ b/data/skill/slayer/mazchna.tables.toml @@ -0,0 +1,154 @@ +[mazchna_slayer_tasks] +amount = "range" +weight = "int" +tip = "string" + +[.banshees] +amount = [30, 50] +weight = 8 +tip = "Banshees use a piercing scream to shock their enemies, you'll need some Earmuffs to protect yourself from them." + +[.bears] +amount = [30, 50] +weight = 6 +tip = "Bears are tough creatures and fierce fighters, watch out for their powerful claws." + +[.bats] +amount = [30, 50] +weight = 7 +tip = "Bats are rarely found on the ground, so you'll have to fight them while they're airborne, which won't be easy for melee." + +[.catablepons] +amount = [20, 30] +weight = 8 +tip = "Catablepon are mythical, cow like, magical creatures. Beware their weakening glare." + +[.cave_bugs] +amount = [10, 20] +weight = 8 +tip = "Cave Bugs are like Cave Crawlers, except smaller and easier to squish, though they still have a fondness for plants." + +[.cave_crawlers] +amount = [30, 50] +weight = 8 +tip = "Cave Crawlers are small and fast, often hiding in ambush. Avoid their barbed tongue or you'll get poisoned." + +[.cave_slimes] +amount = [10, 20] +weight = 8 +tip = "Cave Slimes are the lesser cousins of Jellies, though don't be fooled they can still be dangerous as they're often poisonous." + +[.cockatrice] +amount = [30, 50] +weight = 8 +tip = "Cockatrice, like Basilisks, have a gaze which will paralyse and harm their prey. You'll need a Mirror Shield to protect you." + +[.crawling_hands] +amount = [30, 50] +weight = 8 +tip = "Crawling Hands are undead severed hands, fast and dexterous they claw their victims." + +[.crabs] +amount = [30, 50] +weight = 8 +tip = "Crabs can be found all across Gielinor. They don't hit very hard but they can take a while to kill." + +[.dogs] +amount = [30, 50] +weight = 7 +tip = "Dogs are much like Wolves, they are pack creatures which will hunt in groups." + +[.flesh_crawlers] +amount = [15, 25] +weight = 7 +tip = "Fleshcrawlers are scavengers and will eat you - and anyone else, given the chance." + +[.ghosts] +amount = [30, 50] +weight = 7 +tip = "Ghosts are undead so magic is your best bet against them, there is even a spell specially for fighting the undead." + +[.ghouls] +amount = [10, 20] +weight = 7 +tip = "Ghouls aren't undead but they are stronger and tougher than they look. However they're also very cowardly and will run if they're losing a fight." + +[.hill_giants] +amount = [30, 50] +weight = 7 +tip = "Hill Giants often wield large weapons, learn to recognise what kind of weapon it is and act accordingly." + +[.hobgoblins] +amount = [30, 50] +weight = 7 +tip = "Hobgoblins carrying spears are often trained warriors. If you want less of a challenge, fight the ones that are unarmed." + +[.ice_warriors] +amount = [40, 50] +weight = 7 +tip = "Ice Warriors are a kind of ice elemental, shatter them with blunt weapons or melt them with fire." + +[.kalphites] +amount = [30, 50] +weight = 6 +tip = "Kalphite are large insects which live in great hives under the desert sands." + +#[.killerwatts] +#amount = [30, 50] +#weight = 6 +#tip = "Killerwatts store huge amounts of energy in their bodies, which is released if they are touched. You'll need to wear heavily insulated boots to counter this shocking effect." + +[.lizards] +amount = [30, 50] +weight = 8 +tip = "Lizards are large reptiles with tough skin. Those found in the desert will need you to douse them with freezing water to finish them off after a tough battle." + +#[.mogres] +#amount = [30, 50] +#weight = 8 +#tip = "Mogres are a type of aquatic Ogre that is often mistaken for a giant mudskipper. You have to force them out of the water with a fishing explosive." + +[.pyrefiends] +amount = [30, 50] +weight = 8 +tip = "Pyrefiends are beings of fire and molten rock, they're quick and agile but weak to water spells." + +[.rockslugs] +amount = [30, 50] +weight = 8 +tip = "Rockslugs are strange stoney slugs. You'll need to fight them to near death before finishing them off with Salt." + +[.scorpions] +amount = [30, 50] +weight = 7 +tip = "Scorpions are almost always poisonous, their hard carapace makes them resistant to crushing and stabbing attacks." + +#[.shades] +#amount = [30, 70] +#weight = 8 +#tip = "Shades are undead so magic is your best bet against them. You can find Shades at Mort'ton." + +[.skeletons] +amount = [30, 50] +weight = 7 +tip = "Skeletons are undead so magic is your best bet against them, there is even a spell specially for fighting the undead." + +#[.vampyres] +#amount = [10, 20] +#weight = 6 +#tip = "Vampyres are extremely powerful beings. An underground group known as the Myreque have been searching for tools to defeat them, which they may be willing to share if you can find them." + +[.wolves] +amount = [30, 50] +weight = 7 +tip = "Wolves are pack animals, so you'll always find them in groups. Watch out for their bite, it can be nasty." + +[.wall_beasts] +amount = [10, 20] +weight = 7 +tip = "Wall Beasts are really much larger creatures but you'll only see their arms. You'll want something sharp on your head to stop them grabbing you." + +[.zombies] +amount = [30, 50] +weight = 7 +tip = "Zombies are undead so magic is your best bet against them, there is even a spell specially for fighting the undead." diff --git a/data/skill/slayer/slayer.enums.toml b/data/skill/slayer/slayer.enums.toml index c35042ea1e..506d751acb 100644 --- a/data/skill/slayer/slayer.enums.toml +++ b/data/skill/slayer/slayer.enums.toml @@ -97,7 +97,7 @@ values = { turoth = "turoth", ice_troll_troll_country = "trolls", tzhaar_mej = "tzhaar", - vampyre_juvenile = "vampyres", + vampyre_juvinate = "vampyres", waterfiend = "waterfiends", werewolf = "werewolves", wolf = "wolves", @@ -205,7 +205,7 @@ values = { turoth = "Turoth are large vicious creatures with thick hides. You'll need a Leaf-Tipped Spear or Sword, Broad Arrows, or a Magic Dart to harm them.", ice_troll_troll_country = "Trolls regenerate damage quickly and have some level of magical defences, but this is easily bypassed by their weakness to fire.", tzhaar_mej = "Tzhaar reside in their cave under the Karamja volcano. Beware as they can call to their fellows for aid.", - vampyre_juvenile = "Vampyres are extremely powerful beings. An underground group known as the Myreque have been searching for tools to defeat them, which they may be willing to share if you can find them.", + vampyre_juvinate = "Vampyres are extremely powerful beings. An underground group known as the Myreque have been searching for tools to defeat them, which they may be willing to share if you can find them.", waterfiend = "Waterfiends are creatures of water, which live under the Baxtorian Lake. Their watery form is well defended against slashing and piercing weapons, so use something blunt.", werewolf = "Werewolves are feral creatures, they are strong and tough with sharp claws and teeth.", wolf = "Wolves are pack animals, so you'll always find them in groups. Watch out for their bite, it can be nasty.", diff --git a/data/skill/slayer/slayer.tables.toml b/data/skill/slayer/slayer.tables.toml new file mode 100644 index 0000000000..b84ebd380c --- /dev/null +++ b/data/skill/slayer/slayer.tables.toml @@ -0,0 +1,366 @@ +[slayer_tasks] +combat_level = "int" +defence_level = "int" +quest = "string" +variable = "string" +tip = "string" + +[.aberrant_spectre] +combat_level = 65 +quest = "priest_in_peril" +tip = "Aberrant Spectres are fetid, vile ghosts. The very smell of them will paralyse and harm you. A nosepeg will help ignore their stink." + +[.abyssal_demon] +tip = "Abyssal Demons are nasty creatures to fight. They aren't really part of this realm, and are able to move very quickly to trap their prey." + +[.aquanites] +variable = "aquanites" +tip = "Aquanites rely on their lures for both offensive and defensive purposes. Whilst their hides are resistant to slashing attacks, a well timed cut is capable of severing the lure." + +[.ankou] +tip = "Ankou are undead skeletal ghosts. Their blows can be powerful but they have limited defences, so killing them quickly is often the best way to protect yourself." + +[.aviansies] +combat_level = 70 +tip = "Aviansies are bird-like creatures found in the icy dungeons of the north. Melee weapons can't reach them, so use Magic or Ranged attacks." + +[.bandits] +tip = "Bandits band together for protection against enemies such as yourself." + +[.basilisks] +tip = "Basilisks, like Cockatrice, have a gaze which will paralyse and harm their prey. You'll need a Mirror Shield to protect you." + +[.banshees] +combat_level = 20 +quest = "priest_in_peril" +tip = "Banshees use a piercing scream to shock their enemies, you'll need some Earmuffs to protect yourself from them." + +[.bloodvelds] +tip = "Bloodveld are strange demonic creatures, their long rasping tongue has magical properties so it pierces straight through physical defences." + +[.brine_rats] +tip = "Brine Rats can be found in caves that are near the sea. They are hairless, bad-tempered and generally unfriendly." + +[.bears] +combat_level = 13 +tip = "Bears are tough creatures and fierce fighters, watch out for their powerful claws." + +[.bats] +combat_level = 5 +tip = "Bats are rarely found on the ground, so you'll have to fight them while they're airborne, which won't be easy for melee." + +[.birds] +tip = "Birds aren't the most intelligent of creatures, but watch out for their sharp stabbing beaks." + +[.black_demons] +combat_level = 100 +tip = "Powerful weapons known as demonbane weapons can be used to quickly defeat even powerful demons like the Black Demon with greater ease." + +[.black_dragons] +tip = "Black Dragons are the strongest dragons and very fierce, watch out for their fiery breath." + +[.black_knights] +tip = "Black Knights like using black armour and weapons, this makes them susceptible to magic attacks." + +[.blue_dragons] +tip = "Like all dragons, Blue Dragons have thick scales and a powerful fiery breath. Stabbing weapons and heavy bolts are best suited to piercing their defences." + +[.bronze_dragons] +tip = "Bronze Dragons are the weakest of the metallic dragons, their bronze scales are far thicker than normal bronze armour." + +[.catablepons] +combat_level = 35 +tip = "Catablepon are mythical, cow like, magical creatures. Beware their weakening glare." + +[.cave_bugs] +tip = "Cave Bugs are like Cave Crawlers, except smaller and easier to squish, though they still have a fondness for plants." + +[.cave_crawlers] +combat_level = 10 +tip = "Cave Crawlers are small and fast, often hiding in ambush. Avoid their barbed tongue or you'll get poisoned." + +[.cave_horrors] +quest = "cabin_fever" +tip = "Cave Horrors can be found under Mos Le'Harmless. You will need a Witchwood Icon to fight them effectively." + +[.cave_slimes] +combat_level = 15 +tip = "Cave Slimes are the lesser cousins of Jellies, though don't be fooled they can still be dangerous as they're often poisonous." + +[.cockatrice] +combat_level = 25 +defence_level = 20 +tip = "Cockatrice, like Basilisks, have a gaze which will paralyse and harm their prey. You'll need a Mirror Shield to protect you." + +[.cows] +combat_level = 5 +tip = "Cows are bigger than you, so they'll often hit fairly hard but are usually fairly slow to react." + +[.crawling_hands] +quest = "priest_in_peril" +tip = "Crawling Hands are undead severed hands, fast and dexterous they claw their victims." + +[.chaos_druid] +tip = "Chaos Druids are druids who've turned to evil. Some of them have spells that can harm you, or even teleport you back to them if you flee." + +[.crabs] +tip = "Crabs can be found all across Gielinor. They don't hit very hard but they can take a while to kill." + +[.crocodiles] +combat_level = 40 +tip = "Crocodiles are large reptiles which live near water. You'll want to have a stabbing weapon handy for puncturing their thick scaly hides." + +[.dark_beasts] +quest = "mournings_end_part_ii" +tip = "Dark Beasts are large, dog-like predators. Their massively muscled bodies protect them from crushing weapons." + +[.dust_devils] +quest = "what_lies_below" +tip = "Dust Devils use clouds of dust, sand, ash, and whatever else they can inhale to blind and disorientate their victims. Make sure to wear a facemask when fighting them." + +[.dagannoth] +quest = "horror_from_the_deep" +tip = "Dagannoth are large sea dwelling creatures which are very aggressive. You'll often find them in caves near sea water." + +[.dark_warriors] +tip = "Dark Warriors wear protective armour. If you want to fight them with melee, try crush-based attacks. Or try magic instead." + +[.dogs] +combat_level = 15 +tip = "Dogs are much like Wolves, they are pack creatures which will hunt in groups." + +[.dwarves] +combat_level = 6 +tip = "Dwarves are a small but tough race of miners, often using pickaxes to pierce their opponents armour." + +[.earth_warrior] +tip = "Earth Warriors are a kind of earth elemental, grind them to dust with blunt weapons." + +[.elves] +quest = "regicide" +tip = "Elves are quick, agile, and vicious fighters which often favour bows and polearms." + +[.fire_giant] +tip = "Like other giants, Fire Giants have little to no magical ability, and they're particularly weak to water spells." + +[.flesh_crawlers] +combat_level = 15 +tip = "Fleshcrawlers are scavengers and will eat you - and anyone else, given the chance." + +[.fever_spiders] +tip = "Fever Spiders are giant spiders that carry the deadly Spider Fever. If you don't want to catch it I suggest you wear Slayer Gloves to fight them." + +[.frost_dragons] +tip = "Frost dragons reside beneath the island of Grimstone. They have thick scales and powerful icy breath. Dragonfire protection is a must." + +[.ghosts] +combat_level = 13 +tip = "Ghosts are undead so magic is your best bet against them, there is even a spell specially for fighting the undead." + +[.gargoyles] +quest = "priest_in_peril" +tip = "Gargoyles are winged creatures of stone. You'll need to fight them to near death before breaking them apart with a Rock Hammer." + +[.ghouls] +combat_level = 25 +quest = "priest_in_peril" +tip = "Ghouls aren't undead but they are stronger and tougher than they look. However they're also very cowardly and will run if they're losing a fight." + +[.goblin] +tip = "Goblins are mostly just annoying, but they can be vicious. Watch out for the spears they sometimes carry." + +[.gorak] +tip = "Goraks are extremely aggressive creatures. They have been imprisoned on an alternative plane, which is only accesible by using the fairyrings. Be extremely careful, their touch drains health as well as skills! " + +[.greater_demons] +tip = "Demons are particularly weak to water spells. Though Greater Demons are not the strongest type of demon they are still dangerous." + +[.green_dragons] +tip = "Like all dragons, Green Dragons have thick scales and a powerful fiery breath. Unless you can stay out of their reach, bringing dragonfire protection is a must." + +[.hellhounds] +tip = "Hellhounds are a cross between Dogs and Demons. They are dangerous with a fierce bite, but have all of the same weaknesses as most demons." + +[.hill_giants] +combat_level = 25 +tip = "Hill Giants often wield large weapons, learn to recognise what kind of weapon it is and act accordingly." + +[.hobgoblins] +combat_level = 20 +tip = "Hobgoblins carrying spears are often trained warriors. If you want less of a challenge, fight the ones that are unarmed." + +[.harpie_bug_swarms] +tip = "Harpie Bug Swarms are pesky critters that are hard to hit. You need a lit bug lantern to distract them with its hypnotic light." + +[.infernal_mage] +tip = "Infernal Mages are dangerous spell users, beware of their magic spells and go properly prepared." + +[.ice_giant] +tip = "Like other giants, Ice Giants have little to no magical ability, and they're particularly weak to fire spells." + +[.ice_warriors] +combat_level = 45 +tip = "Ice Warriors are a kind of ice elemental, shatter them with blunt weapons or melt them with fire." + +[.icefiends] +combat_level = 20 +tip = "Icefiends are beings of ice and freezing rock, they're quick and agile so you'll want to be careful when getting close to them." + +[.iron_dragons] +tip = "Iron Dragons are some of the weaker metallic dragons, their iron scales are far thicker than normal iron armour." + +[.jellies] +tip = "Jellies are nasty cube-like gelatinous creatures which absorb everything they come across into themselves. Their magical acids bypass physical defences." + +[.jungle_horrors] +tip = "Jungle Horrors can be found all over Mos Le'Harmless. They are strong and aggressive, so watch out!" + +[.kalphites] +combat_level = 15 +tip = "Kalphite are large insects which live in great hives under the desert sands." + +[.killerwatts] +combat_level = 50 +quest = "ernest_the_chicken" +tip = "Killerwatts store huge amounts of energy in their bodies, which is released if they are touched. You'll need to wear heavily insulated boots to counter this shocking effect." + +[.kurask] +tip = "Kurask are large brutal creatures with very thick hides. You'll need a Leaf-Tipped Spear or Battle-axe, Broad Arrows, or a Magic Dart to harm it." + +[.lesser_demons] +tip = "Demons are weak to magical attacks. Though Lesser Demons are relatively weak they are still dangerous." + +[.lizards] +combat_level = 20 +tip = "Lizards are large reptiles with tough skin. Those found in the desert will need you to douse them with freezing water to finish them off after a tough battle." + +[.magic_axe] +tip = "Magic Axes have a mind of their own. You may find magic or slash-based melee attacks are slightly more effective against them." + +[.mogres] +combat_level = 30 +quest = "skippy_and_the_mogres" +tip = "Mogres are a type of aquatic Ogre that is often mistaken for a giant mudskipper. You have to force them out of the water with a fishing explosive." + +[.mutated_zygomites] +tip = "Mutated Zygomites are hard to destroy. They regenerate quickly so you will need to finish them with fungicide." + +[.minotaurs] +combat_level = 7 +tip = "Minotaurs are large manlike creatures but you'll want to be careful of their horns." + +[.mithril_dragons] +combat_level = 100 +tip = "Mithril dragons are more vulnerable to magic and to stab-based melee attacks than to anything else." + +[.monkeys] +tip = "Monkeys are tricky creatures, they are agile and fairly fast. Learn to anticipate their movements." + +[.moss_giants] +tip = "Like other giants, Moss Giants have little to no magical ability, and they're particularly weak to fire spells." + +[.nechryael] +quest = "what_lies_below" +tip = "Nechryael are demons of decay which summon small winged beings to help them fight their victims. Their minions can bypass protective prayers so be sure to wear thick armour." + +[.ogres] +tip = "Ogres are brutal creatures, favouring large blunt maces and clubs, they often attack without warning." + +[.otherworldly_beings] +tip = "Otherworldly Beings are ethereal beings making them weak to magical attack." + +[.pirates] +tip = "Pirates can be found near the sea. They like to collect coins among other things." + +[.pyrefiends] +combat_level = 25 +tip = "Pyrefiends are beings of fire and molten rock, they're quick and agile but weak to water spells." + +[.rats] +tip = "Rats are your everyday pest, but they can get fairly big. Watch out for their sharp piercing teeth." + +[.red_dragons] +tip = "Red Dragons are very powerful, stronger than most dragons, watch out for their fiery breath." + +[.rogues] +tip = "Rogues are found in lawless areas, such as the deep Wilderness. They can be very protective of their loot." + +[.rockslugs] +combat_level = 20 +tip = "Rockslugs are strange stoney slugs. You'll need to fight them to near death before finishing them off with Salt." + +[.scabarites] +quest = "dealing_with-scabaras" +tip = "Scabarites are insectoid creatures, found beyond the Kharidian deserts. Make sure not to fall into one of their pitfall traps or you'll be quickly overwhelmed." + +[.scorpions] +combat_level = 10 +tip = "Scorpions are almost always poisonous, their hard carapace makes them resistant to crushing and stabbing attacks." + +[.sea_snakes] +tip = "Sea Snakes are long and slithery with a venomous bite. The larger ones are more poisonous, so keep an eye on your health." + +[.skeletal_wyverns] +combat_level = 100 +quest = "elemental_workshop_i" +tip = "Skeletal Wyverns are extremely dangerous and they are hard to hit with arrows as they slip right through. To stand a good chance of surviving you'll need some elemental shielding from its icy breath." + +[.shades] +combat_level = 30 +tip = "Shades are undead so magic is your best bet against them. You can find Shades at Mort'ton." + +[.shadow_warriors] +tip = "Shadow Warriors are dark and mysterious. They wear spectral plate armour, so crush weapons and magic will give them trouble." + +[.skeletons] +combat_level = 15 +tip = "Skeletons are undead so magic is your best bet against them, there is even a spell specially for fighting the undead." + +[.spiritual_creatures] +tip = "Spiritual Creatures can be found in the icy caverns near Trollheim, supporting the cause of their chosen god. Wearing equipment aligned with each of the gods can help you avoid undesired conflict." + +[.spiders] +tip = "Spiders are often poisonous, and many varieties are camouflaged too." + +[.steel_dragons] +tip = "Steel Dragons are dangerous metallic dragons, their steel scales are far thicker than normal steel armour." + +[.suqahs] +quest = "lunar_diplomacy" +tip = "Suqahs can only be found on the mystical Lunar Isle. They are capable of melee and magic attacks and often drop hide, teeth and herbs!" + +[.turoth] +tip = "Turoth are large vicious creatures with thick hides. You'll need a Leaf-Tipped Spear or Sword, Broad Arrows, or a Magic Dart to harm them." + +[.trolls] +tip = "Trolls regenerate damage quickly and have some level of magical defences, but this is easily bypassed by their weakness to fire." + +[.tzhaar] +tip = "Tzhaar reside in their cave under the Karamja volcano. Beware as they can call to their fellows for aid." + +[.vampyres] +tip = "Vampyres are extremely powerful beings. An underground group known as the Myreque have been searching for tools to defeat them, which they may be willing to share if you can find them." + +[.waterfiends] +quest = "what_lies_below" +tip = "Waterfiends are creatures of water, which live under the Baxtorian Lake. Their watery form is well defended against slashing and piercing weapons, so use something blunt." + +[.werewolves] +tip = "Werewolves are feral creatures, they are strong and tough with sharp claws and teeth." + +[.wolves] +combat_level = 20 +tip = "Wolves are pack animals, so you'll always find them in groups. Watch out for their bite, it can be nasty." + +[.wall_beasts] +combat_level = 30 +defence_level = 5 +tip = "Wall Beasts are really much larger creatures but you'll only see their arms. You'll want something sharp on your head to stop them grabbing you." + +[.warped_creatures] +quest = "the_path_of_glouphrie" +tip = "Warped Creatures can supposedly be found within a mysterious dungeon on the eastern edge of the Poison Waste. Be aware that to defeat them, you'll need to purify them in some way." + +[.zombies] +combat_level = 10 +tip = "Zombies are undead so magic is your best bet against them, there is even a spell specially for fighting the undead." diff --git a/data/skill/slayer/sumona.tables.toml b/data/skill/slayer/sumona.tables.toml new file mode 100644 index 0000000000..be9c5da6a4 --- /dev/null +++ b/data/skill/slayer/sumona.tables.toml @@ -0,0 +1,164 @@ +[sumona_slayer_tasks] +amount = "range" +weight = "int" +tip = "string" + +[.aberrant_spectre] +amount = [120, 185] +weight = 15 +tip = "Aberrant Spectres are fetid, vile ghosts. The very smell of them will paralyse and harm you. A nosepeg will help ignore their stink." + +[.abyssal_demon] +amount = [120, 185] +weight = 10 +tip = "Abyssal Demons are nasty creatures to fight. They aren't really part of this realm, and are able to move very quickly to trap their prey." + +[.aquanites] +amount = [120, 185] +weight = 10 +tip = "Aquanites rely on their lures for both offensive and defensive purposes. Whilst their hides are resistant to slashing attacks, a well timed cut is capable of severing the lure." + +[.aviansies] +amount = [50, 100] +weight = 7 +tip = "Aviansies are bird-like creatures found in the icy dungeons of the north. Melee weapons can't reach them, so use Magic or Ranged attacks." + +[.basilisks] +amount = [120, 185] +weight = 15 +tip = "Basilisks, like Cockatrice, have a gaze which will paralyse and harm their prey. You'll need a Mirror Shield to protect you." + +[.banshees] +amount = [120, 185] +weight = 15 +tip = "Banshees use a piercing scream to shock their enemies, you'll need some Earmuffs to protect yourself from them." + +[.bloodvelds] +amount = [120, 185] +weight = 10 +tip = "Bloodveld are strange demonic creatures, their long rasping tongue has magical properties so it pierces straight through physical defences." + +[.black_demons] +amount = [120, 185] +weight = 10 +tip = "Powerful weapons known as demonbane weapons can be used to quickly defeat even powerful demons like the Black Demon with greater ease." + +[.blue_dragons] +amount = [120, 185] +weight = 5 +tip = "Like all dragons, Blue Dragons have thick scales and a powerful fiery breath. Stabbing weapons and heavy bolts are best suited to piercing their defences." + +[.cave_crawlers] +amount = [120, 185] +weight = 15 +tip = "Cave Crawlers are small and fast, often hiding in ambush. Avoid their barbed tongue or you'll get poisoned." + +[.cave_horrors] +amount = [120, 185] +weight = 15 +tip = "Cave Horrors can be found under Mos Le'Harmless. You will need a Witchwood Icon to fight them effectively." + +[.crocodiles] +amount = [150, 250] +weight = 4 +tip = "Crocodiles are large reptiles which live near water. You'll want to have a stabbing weapon handy for puncturing their thick scaly hides." + +[.dust_devils] +amount = [120, 185] +weight = 15 +tip = "Dust Devils use clouds of dust, sand, ash, and whatever else they can inhale to blind and disorientate their victims. Make sure to wear a facemask when fighting them." + +[.dagannoth] +amount = [120, 185] +weight = 10 +tip = "Dagannoth are large sea dwelling creatures which are very aggressive. You'll often find them in caves near sea water." + +#[.elves] +#amount = [60, 90] +#weight = 10 +#tip = "Elves are quick, agile, and vicious fighters which often favour bows and polearms." + +[.fire_giant] +amount = [120, 185] +weight = 10 +tip = "Like other giants, Fire Giants have little to no magical ability, and they're particularly weak to water spells." + +[.gargoyles] +amount = [120, 195] +weight = 10 +tip = "Gargoyles are winged creatures of stone. You'll need to fight them to near death before breaking them apart with a Rock Hammer." + +[.greater_demons] +amount = [120, 195] +weight = 10 +tip = "Demons are particularly weak to water spells. Though Greater Demons are not the strongest type of demon they are still dangerous." + +[.hellhounds] +amount = [120, 185] +weight = 10 +tip = "Hellhounds are a cross between Dogs and Demons. They are dangerous with a fierce bite, but have all of the same weaknesses as most demons." + +[.iron_dragons] +amount = [30, 60] +weight = 7 +tip = "Iron Dragons are some of the weaker metallic dragons, their iron scales are far thicker than normal iron armour." + +[.kalphites] +amount = [120, 185] +weight = 10 +tip = "Kalphite are large insects which live in great hives under the desert sands." + +[.kurask] +amount = [120, 185] +weight = 15 +tip = "Kurask are large brutal creatures with very thick hides. You'll need a Leaf-Tipped Spear or Battle-axe, Broad Arrows, or a Magic Dart to harm it." + +[.lizards] +amount = [90, 110] +weight = 4 +tip = "Lizards are large reptiles with tough skin. Those found in the desert will need you to douse them with freezing water to finish them off after a tough battle." + +[.nechryael] +amount = [120, 185] +weight = 10 +tip = "Nechryael are demons of decay which summon small winged beings to help them fight their victims. Their minions can bypass protective prayers so be sure to wear thick armour." + +[.red_dragons] +amount = [30, 60] +weight = 5 +tip = "Red Dragons are very powerful, stronger than most dragons, watch out for their fiery breath." + +#[.scabarites] +#amount = [80, 120] +#weight = 5 +#tip = "Scabarites are insectoid creatures, found beyond the Kharidian deserts. Make sure not to fall into one of their pitfall traps or you'll be quickly overwhelmed." + +[.scorpions] +amount = [150, 250] +weight = 4 +tip = "Scorpions are almost always poisonous, their hard carapace makes them resistant to crushing and stabbing attacks." + +[.spiritual_creatures] +amount = [120, 185] +weight = 10 +tip = "Spiritual Creatures can be found in the icy caverns near Trollheim, supporting the cause of their chosen god. Wearing equipment aligned with each of the gods can help you avoid undesired conflict." + +#[.terror_dogs] +#amount = [30, 60] +#weight = 10 +#tip = "Terror dogs are, unsurprisingly, dogs that terrorise the weak. You'll find them in the Haunted Mine, near Tarn's lair." + +[.turoth] +amount = [120, 185] +weight = 15 +tip = "Turoth are large vicious creatures with thick hides. You'll need a Leaf-Tipped Spear or Sword, Broad Arrows, or a Magic Dart to harm them." + +[.trolls] +amount = [120, 185] +weight = 10 +tip = "Trolls regenerate damage quickly and have some level of magical defences, but this is easily bypassed by their weakness to fire." + +#[.warped_creatures] +#amount = [120, 185] +#weight = 10 +#tip = "Warped Creatures can supposedly be found within a mysterious dungeon on the eastern edge of the Poison Waste. Be aware that to defeat them, you'll need to purify them in some way." diff --git a/data/skill/slayer/turael.tables.toml b/data/skill/slayer/turael.tables.toml new file mode 100644 index 0000000000..bc761bf1b8 --- /dev/null +++ b/data/skill/slayer/turael.tables.toml @@ -0,0 +1,124 @@ +[turael_slayer_tasks] +amount = "range" +weight = "int" +tip = "string" + +[.banshees] +amount = [15, 30] +weight = 8 +tip = "Banshees use a piercing scream to shock their enemies, you'll need some Earmuffs to protect yourself from them." + +[.bears] +amount = [10, 20] +weight = 7 +tip = "Bears are tough creatures and fierce fighters, watch out for their powerful claws." + +[.bats] +amount = [15, 30] +weight = 7 +tip = "Bats are rarely found on the ground, so you'll have to fight them while they're airborne, which won't be easy for melee." + +[.birds] +amount = [15, 30] +weight = 6 +tip = "Birds aren't the most intelligent of creatures, but watch out for their sharp stabbing beaks." + +[.cave_bugs] +amount = [10, 30] +weight = 8 +tip = "Cave Bugs are like Cave Crawlers, except smaller and easier to squish, though they still have a fondness for plants." + +[.cave_crawlers] +amount = [15, 30] +weight = 8 +tip = "Cave Crawlers are small and fast, often hiding in ambush. Avoid their barbed tongue or you'll get poisoned." + +[.cave_slimes] +amount = [10, 20] +weight = 8 +tip = "Cave Slimes are the lesser cousins of Jellies, though don't be fooled they can still be dangerous as they're often poisonous." + +[.cows] +amount = [15, 30] +weight = 8 +tip = "Cows are bigger than you, so they'll often hit fairly hard but are usually fairly slow to react." + +[.crawling_hands] +amount = [15, 30] +weight = 8 +tip = "Crawling Hands are undead severed hands, fast and dexterous they claw their victims." + +[.dogs] +amount = [15, 30] +weight = 7 +tip = "Dogs are much like Wolves, they are pack creatures which will hunt in groups." + +[.dwarves] +amount = [10, 25] +weight = 7 +tip = "Dwarves are a small but tough race of miners, often using pickaxes to pierce their opponents armour." + +[.ghosts] +amount = [15, 30] +weight = 7 +tip = "Ghosts are undead so magic is your best bet against them, there is even a spell specially for fighting the undead." + +[.goblin] +amount = [15, 30] +weight = 7 +tip = "Goblins are mostly just annoying, but they can be vicious. Watch out for the spears they sometimes carry." + +[.icefiends] +amount = [15, 20] +weight = 8 +tip = "Icefiends are beings of ice and freezing rock, they're quick and agile so you'll want to be careful when getting close to them." + +[.kalphites] +amount = [15, 30] +weight = 6 +tip = "Kalphite are large insects which live in great hives under the desert sands." + +[.lizards] +amount = [15, 30] +weight = 8 +tip = "Lizards are large reptiles with tough skin. Those found in the desert will need you to douse them with freezing water to finish them off after a tough battle." + +[.minotaurs] +amount = [10, 20] +weight = 7 +tip = "Minotaurs are large manlike creatures but you'll want to be careful of their horns." + +[.monkeys] +amount = [15, 30] +weight = 6 +tip = "Monkeys are tricky creatures, they are agile and fairly fast. Learn to anticipate their movements." + +[.rats] +amount = [15, 30] +weight = 7 +tip = "Rats are your everyday pest, but they can get fairly big. Watch out for their sharp piercing teeth." + +[.scorpions] +amount = [15, 30] +weight = 7 +tip = "Scorpions are almost always poisonous, their hard carapace makes them resistant to crushing and stabbing attacks." + +[.skeletons] +amount = [15, 30] +weight = 7 +tip = "Skeletons are undead so magic is your best bet against them, there is even a spell specially for fighting the undead." + +[.spiders] +amount = [15, 30] +weight = 6 +tip = "Spiders are often poisonous, and many varieties are camouflaged too." + +[.wolves] +amount = [15, 30] +weight = 7 +tip = "Wolves are pack animals, so you'll always find them in groups. Watch out for their bite, it can be nasty." + +[.zombies] +amount = [15, 30] +weight = 7 +tip = "Zombies are undead so magic is your best bet against them, there is even a spell specially for fighting the undead." diff --git a/data/skill/slayer/vannaka.enums.toml b/data/skill/slayer/vannaka.enums.toml index ef4d71a7fd..d5787e0dbf 100644 --- a/data/skill/slayer/vannaka.enums.toml +++ b/data/skill/slayer/vannaka.enums.toml @@ -43,7 +43,7 @@ values = { spiritual_mage_zamorak = "40-90", ice_troll_troll_country = "40-90", turoth = "30-90", - vampyre_juvenile = "10-20", + vampyre_juvinate = "10-20", werewolf = "30-60", } @@ -92,6 +92,6 @@ values = { spiritual_mage_zamorak = 8, ice_troll_troll_country = 7, turoth = 8, -# vampyre_juvenile = 7, +# vampyre_juvinate = 7, werewolf = 7, } diff --git a/data/skill/slayer/vannaka.tables.toml b/data/skill/slayer/vannaka.tables.toml new file mode 100644 index 0000000000..2abc7046ae --- /dev/null +++ b/data/skill/slayer/vannaka.tables.toml @@ -0,0 +1,219 @@ +[vannaka_slayer_tasks] +amount = "range" +weight = "int" +tip = "string" + +[.aberrant_spectre] +amount = [40, 90] +weight = 8 +tip = "Aberrant Spectres are fetid, vile ghosts. The very smell of them will paralyse and harm you. A nosepeg will help ignore their stink." + +[.abyssal_demon] +amount = [40, 90] +weight = 5 +tip = "Abyssal Demons are nasty creatures to fight. They aren't really part of this realm, and are able to move very quickly to trap their prey." + +[.ankou] +amount = [25, 35] +weight = 8 +tip = "Ankou are undead skeletal ghosts. Their blows can be powerful but they have limited defences, so killing them quickly is often the best way to protect yourself." + +[.basilisks] +amount = [40, 90] +weight = 8 +tip = "Basilisks, like Cockatrice, have a gaze which will paralyse and harm their prey. You'll need a Mirror Shield to protect you." + +[.bloodvelds] +amount = [40, 90] +weight = 8 +tip = "Bloodveld are strange demonic creatures, their long rasping tongue has magical properties so it pierces straight through physical defences." + +[.brine_rats] +amount = [40, 90] +weight = 7 +tip = "Brine Rats can be found in caves that are near the sea. They are hairless, bad-tempered and generally unfriendly." + +[.black_dragons] +amount = [40, 90] +weight = 7 +tip = "Black Dragons are the strongest dragons and very fierce, watch out for their fiery breath." + +[.cockatrice] +amount = [40, 90] +weight = 8 +tip = "Cockatrice, like Basilisks, have a gaze which will paralyse and harm their prey. You'll need a Mirror Shield to protect you." + +[.crabs] +amount = [40, 90] +weight = 7 +tip = "Crabs can be found all across Gielinor. They don't hit very hard but they can take a while to kill." + +[.crocodiles] +amount = [40, 90] +weight = 6 +tip = "Crocodiles are large reptiles which live near water. You'll want to have a stabbing weapon handy for puncturing their thick scaly hides." + +[.dust_devils] +amount = [40, 90] +weight = 8 +tip = "Dust Devils use clouds of dust, sand, ash, and whatever else they can inhale to blind and disorientate their victims. Make sure to wear a facemask when fighting them." + +[.dagannoth] +amount = [40, 90] +weight = 7 +tip = "Dagannoth are large sea dwelling creatures which are very aggressive. You'll often find them in caves near sea water." + +#[.elves] +#amount = [30, 70] +#weight = 7 +#tip = "Elves are quick, agile, and vicious fighters which often favour bows and polearms." + +[.fire_giant] +amount = [40, 90] +weight = 7 +tip = "Like other giants, Fire Giants have little to no magical ability, and they're particularly weak to water spells." + +#[.fever_spiders] +#amount = [30, 90] +#weight = 7 +#tip = "Fever Spiders are giant spiders that carry the deadly Spider Fever. If you don't want to catch it I suggest you wear Slayer Gloves to fight them." + +[.gargoyles] +amount = [40, 90] +weight = 5 +tip = "Gargoyles are winged creatures of stone. You'll need to fight them to near death before breaking them apart with a Rock Hammer." + +[.ghouls] +amount = [10, 40] +weight = 7 +tip = "Ghouls aren't undead but they are stronger and tougher than they look. However they're also very cowardly and will run if they're losing a fight." + +[.hellhounds] +amount = [30, 60] +weight = 7 +tip = "Hellhounds are a cross between Dogs and Demons. They are dangerous with a fierce bite, but have all of the same weaknesses as most demons." + +[.hill_giants] +amount = [40, 90] +weight = 7 +tip = "Hill Giants often wield large weapons, learn to recognise what kind of weapon it is and act accordingly." + +[.hobgoblins] +amount = [40, 90] +weight = 7 +tip = "Hobgoblins carrying spears are often trained warriors. If you want less of a challenge, fight the ones that are unarmed." + +#[.harpie_bug_swarms] +#amount = [40, 90] +#weight = 8 +#tip = "Harpie Bug Swarms are pesky critters that are hard to hit. You need a lit bug lantern to distract them with its hypnotic light." + +[.infernal_mage] +amount = [40, 90] +weight = 8 +tip = "Infernal Mages are dangerous spell users, beware of their magic spells and go properly prepared." + +[.ice_giant] +amount = [30, 80] +weight = 7 +tip = "Like other giants, Ice Giants have little to no magical ability, and they're particularly weak to fire spells." + +[.ice_warriors] +amount = [40, 90] +weight = 7 +tip = "Ice Warriors are a kind of ice elemental, shatter them with blunt weapons or melt them with fire." + +[.jellies] +amount = [40, 90] +weight = 8 +tip = "Jellies are nasty cube-like gelatinous creatures which absorb everything they come across into themselves. Their magical acids bypass physical defences." + +[.jungle_horrors] +amount = [40, 90] +weight = 8 +tip = "Jungle Horrors can be found all over Mos Le'Harmless. They are strong and aggressive, so watch out!" + +[.kalphites] +amount = [40, 90] +weight = 7 +tip = "Kalphite are large insects which live in great hives under the desert sands." + +[.kurask] +amount = [40, 90] +weight = 7 +tip = "Kurask are large brutal creatures with very thick hides. You'll need a Leaf-Tipped Spear or Battle-axe, Broad Arrows, or a Magic Dart to harm it." + +[.lesser_demons] +amount = [40, 90] +weight = 7 +tip = "Demons are weak to magical attacks. Though Lesser Demons are relatively weak they are still dangerous." + +#[.mogres] +#amount = [40, 90] +#weight = 7 +#tip = "Mogres are a type of aquatic Ogre that is often mistaken for a giant mudskipper. You have to force them out of the water with a fishing explosive." + +[.moss_giants] +amount = [40, 90] +weight = 7 +tip = "Like other giants, Moss Giants have little to no magical ability, and they're particularly weak to fire spells." + +[.nechryael] +amount = [40, 90] +weight = 5 +tip = "Nechryael are demons of decay which summon small winged beings to help them fight their victims. Their minions can bypass protective prayers so be sure to wear thick armour." + +[.ogres] +amount = [40, 90] +weight = 7 +tip = "Ogres are brutal creatures, favouring large blunt maces and clubs, they often attack without warning." + +[.otherworldly_beings] +amount = [40, 90] +weight = 8 +tip = "Otherworldly Beings are ethereal beings making them weak to magical attack." + +[.pyrefiends] +amount = [40, 90] +weight = 8 +tip = "Pyrefiends are beings of fire and molten rock, they're quick and agile but weak to water spells." + +#[.sea_snakes] +#amount = [40, 90] +#weight = 6 +#tip = "Sea Snakes are long and slithery with a venomous bite. The larger ones are more poisonous, so keep an eye on your health." + +#[.shades] +#amount = [40, 90] +#weight = 8 +#tip = "Shades are undead so magic is your best bet against them. You can find Shades at Mort'ton." + +[.shadow_warriors] +amount = [30, 80] +weight = 8 +tip = "Shadow Warriors are dark and mysterious. They wear spectral plate armour, so crush weapons and magic will give them trouble." + +[.spiritual_creatures] +amount = [40, 90] +weight = 8 +tip = "Spiritual Creatures can be found in the icy caverns near Trollheim, supporting the cause of their chosen god. Wearing equipment aligned with each of the gods can help you avoid undesired conflict." + +[.turoth] +amount = [30, 90] +weight = 8 +tip = "Turoth are large vicious creatures with thick hides. You'll need a Leaf-Tipped Spear or Sword, Broad Arrows, or a Magic Dart to harm them." + +[.trolls] +amount = [40, 90] +weight = 7 +tip = "Trolls regenerate damage quickly and have some level of magical defences, but this is easily bypassed by their weakness to fire." + +#[.vampyres] +#amount = [10, 20] +#weight = 7 +#tip = "Vampyres are extremely powerful beings. An underground group known as the Myreque have been searching for tools to defeat them, which they may be willing to share if you can find them." + +[.werewolves] +amount = [30, 60] +weight = 7 +tip = "Werewolves are feral creatures, they are strong and tough with sharp claws and teeth." diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt index 0839ccbb72..4b7245e448 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt @@ -14,6 +14,18 @@ data class TableDefinition( val rows: IntArray, ) { + fun bool(column: String, row: Int): Boolean = get(column, row, ColumnType.ColumnBoolean) + + fun boolOrNull(column: String, row: Int): Boolean? = getOrNull(column, row, ColumnType.ColumnBoolean) + + fun int(column: String, row: Int): Int = get(column, row, ColumnType.ColumnInt) + + fun intOrNull(column: String, row: Int): Int? = getOrNull(column, row, ColumnType.ColumnInt) + + fun string(column: String, row: Int): String = get(column, row, ColumnType.ColumnString) + + fun stringOrNull(column: String, row: Int): String? = getOrNull(column, row, ColumnType.ColumnString) + fun get(column: String, row: Int, type: ColumnType): T = getOrNull(column, row, type) ?: type.default fun get(column: Int, row: Int, type: ColumnType): T = getOrNull(column, row, type) ?: type.default diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnReader.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnReader.kt new file mode 100644 index 0000000000..f2e93dd06c --- /dev/null +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnReader.kt @@ -0,0 +1,112 @@ +package world.gregs.voidps.engine.data.definition + +import world.gregs.config.ConfigReader + +sealed interface ColumnReader { + val type: ColumnType + fun list(): MutableList + fun read(reader: ConfigReader): T + + object ReaderBoolean : ColumnReader { + override val type = ColumnType.ColumnBoolean + override fun list() = mutableListOf() + override fun read(reader: ConfigReader) = reader.boolean() + } + + object ReaderInt : ColumnReader { + override val type = ColumnType.ColumnInt + override fun list() = mutableListOf() + override fun read(reader: ConfigReader) = reader.int() + } + + object ReaderIntRange : ColumnReader { + override val type = ColumnType.ColumnIntRange + override fun list() = mutableListOf() + override fun read(reader: ConfigReader): IntRange { + reader.nextElement() + val one = reader.int() + reader.nextElement() + val two = reader.int() + reader.nextElement() + return one..two + } + } + + class ReaderEntity(val definitions: Map) : ColumnReader { + override val type = ColumnType.ColumnEntity + override fun list() = mutableListOf() + override fun read(reader: ConfigReader) = definitions.getValue(reader.string()) + } + + object ReaderString : ColumnReader { + override val type = ColumnType.ColumnString + override fun list() = mutableListOf() + override fun read(reader: ConfigReader) = reader.string() + } + + data class ReaderPair(val one: ColumnReader, val two: ColumnReader) : ColumnReader> { + override val type = ColumnType.ColumnPair(one.type, two.type) + override fun list() = mutableListOf>() + override fun read(reader: ConfigReader): Pair { + reader.nextElement() + val one = one.read(reader) + reader.nextElement() + val two = two.read(reader) + reader.nextElement() + return Pair(one, two) + } + } + + data class ReaderTriple(val one: ColumnReader, val two: ColumnReader, val three: ColumnReader) : ColumnReader> { + override val type = ColumnType.ColumnTriple(one.type, two.type, three.type) + override fun list() = mutableListOf>() + override fun read(reader: ConfigReader): Triple { + reader.nextElement() + val one = one.read(reader) + reader.nextElement() + val two = two.read(reader) + reader.nextElement() + val three = three.read(reader) + reader.nextElement() + return Triple(one, two, three) + } + } + + data class ReaderList(val read: ColumnReader) : ColumnReader> { + override val type = ColumnType.ColumnList(read.type) + override fun list() = mutableListOf>() + override fun read(reader: ConfigReader): List { + val list = read.list() + while (reader.nextElement()) { + list.add(read.read(reader)) + } + return list + } + } + + companion object { + fun reader(name: String): ColumnReader<*> = when (name) { + "boolean" -> ReaderBoolean + "int" -> ReaderInt + "range" -> ReaderIntRange + "string" -> ReaderString + "npc" -> ReaderEntity(NPCDefinitions.ids) + "item" -> ReaderEntity(ItemDefinitions.ids) + "obj" -> ReaderEntity(ObjectDefinitions.ids) + "row" -> ReaderEntity(Rows.ids) + else -> if (name.startsWith("Pair<")) { + val (first, second) = name.substringAfter("<").removeSuffix(">").split(",") + ReaderPair(reader(first.trim()), reader(second.trim())) + } else if (name.startsWith("Triple<")) { + val (first, second, third) = name.substringAfter("<").removeSuffix(">").split(",") + ReaderTriple(reader(first.trim()), reader(second.trim()), reader(third.trim())) + } else if (name.startsWith("List<") && name.endsWith(">")) { + val type = name.substringAfter("<").substringBefore(">") + ReaderList(reader(type)) + } else { + throw IllegalArgumentException("Unsupported type '$name'") + } + } + + } +} diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnType.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnType.kt index 56653c8fba..146b8d6eed 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnType.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnType.kt @@ -2,8 +2,6 @@ package world.gregs.voidps.engine.data.definition -import world.gregs.config.ConfigReader - sealed interface ColumnType { val default: T fun cast(value: Any?): T? = value as? T @@ -18,6 +16,11 @@ sealed interface ColumnType { override fun toString() = "ColumnInt" } + object ColumnIntRange : ColumnType { + override val default = 0..0 + override fun toString() = "ColumnInt" + } + object ColumnString : ColumnType { override val default = "" override fun toString() = "ColumnString" @@ -116,97 +119,3 @@ sealed interface ColumnType { object StringIntList : ColumnList>(ColumnPair(ColumnString, ColumnInt)) } -sealed interface ColumnReader { - val type: ColumnType - fun list(): MutableList - fun read(reader: ConfigReader): T - - object ReaderBoolean : ColumnReader { - override val type = ColumnType.ColumnBoolean - override fun list() = mutableListOf() - override fun read(reader: ConfigReader) = reader.boolean() - } - - object ReaderInt : ColumnReader { - override val type = ColumnType.ColumnInt - override fun list() = mutableListOf() - override fun read(reader: ConfigReader) = reader.int() - } - - class ReaderEntity(val definitions: Map) : ColumnReader { - override val type = ColumnType.ColumnEntity - override fun list() = mutableListOf() - override fun read(reader: ConfigReader) = definitions.getValue(reader.string()) - } - - object ReaderString : ColumnReader { - override val type = ColumnType.ColumnString - override fun list() = mutableListOf() - override fun read(reader: ConfigReader) = reader.string() - } - - data class ReaderPair(val one: ColumnReader, val two: ColumnReader) : ColumnReader> { - override val type = ColumnType.ColumnPair(one.type, two.type) - override fun list() = mutableListOf>() - override fun read(reader: ConfigReader): Pair { - reader.nextElement() - val one = one.read(reader) - reader.nextElement() - val two = two.read(reader) - reader.nextElement() - return Pair(one, two) - } - } - - data class ReaderTriple(val one: ColumnReader, val two: ColumnReader, val three: ColumnReader) : ColumnReader> { - override val type = ColumnType.ColumnTriple(one.type, two.type, three.type) - override fun list() = mutableListOf>() - override fun read(reader: ConfigReader): Triple { - reader.nextElement() - val one = one.read(reader) - reader.nextElement() - val two = two.read(reader) - reader.nextElement() - val three = three.read(reader) - reader.nextElement() - return Triple(one, two, three) - } - } - - data class ReaderList(val read: ColumnReader) : ColumnReader> { - override val type = ColumnType.ColumnList(read.type) - override fun list() = mutableListOf>() - override fun read(reader: ConfigReader): List { - val list = read.list() - while (reader.nextElement()) { - list.add(read.read(reader)) - } - return list - } - } - - companion object { - fun reader(name: String): ColumnReader<*> = when (name) { - "Boolean" -> ReaderBoolean - "Int" -> ReaderInt - "String" -> ReaderString - "NPC" -> ReaderEntity(NPCDefinitions.ids) - "Item" -> ReaderEntity(ItemDefinitions.ids) - "GameObject" -> ReaderEntity(ObjectDefinitions.ids) - "Row" -> ReaderEntity(Rows.ids) - else -> if (name.startsWith("Pair<")) { - val (first, second) = name.substringAfter("<").removeSuffix(">").split(",") - ReaderPair(reader(first.trim()), reader(second.trim())) - } else if (name.startsWith("Triple<")) { - val (first, second, third) = name.substringAfter("<").removeSuffix(">").split(",") - ReaderTriple(reader(first.trim()), reader(second.trim()), reader(third.trim())) - } else if (name.startsWith("List<") && name.endsWith(">")) { - val type = name.substringAfter("<").substringBefore(">") - ReaderList(reader(type)) - } else { - throw IllegalArgumentException("Unsupported type '$name'") - } - } - - } -} diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/EnumDefinitions.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/EnumDefinitions.kt index 77bd1454c5..e996ccfcb0 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/EnumDefinitions.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/EnumDefinitions.kt @@ -98,6 +98,11 @@ object EnumDefinitions : DefinitionsDecoder { return definition.intOrNull(key) } + fun intOrNull(enum: String, key: Int): Int? { + val definition = getOrNull(enum) ?: return null + return definition.intOrNull(key) + } + fun item(enum: String, key: String): String { val definition = get(enum) assert(definition.valueType == EnumTypes.ITEM || definition.valueType == EnumTypes.ITEM_2) { "Enum $enum value type not Item, found: ${EnumTypes.name(definition.valueType)}" } diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Rows.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Rows.kt index a6edc69c13..f135344b97 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Rows.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Rows.kt @@ -26,7 +26,7 @@ object Rows { fun getOrNull(id: Int) = definitions.getOrNull(id) @TestOnly - fun set(definitions: Array, ids: Map, ) { + fun set(definitions: Array, ids: Map) { this.definitions = definitions this.ids = ids loaded = true diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt index 4291aefcb8..0cb298972c 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt @@ -6,6 +6,7 @@ import world.gregs.config.ConfigReader import world.gregs.voidps.engine.data.config.RowDefinition import world.gregs.voidps.engine.data.config.TableDefinition import world.gregs.voidps.engine.timedLoad +import kotlin.collections.set object Tables { @@ -26,6 +27,10 @@ object Tables { return row.data[index] != null } + fun get(table: String) = definitions[table] ?: error("Table '$table' not found") + + fun getOrNull(table: String) = definitions[table] + /* Primitives */ @@ -42,6 +47,10 @@ object Tables { fun stringOrNull(path: String): String? = getOrNull(path, ColumnType.ColumnString) + fun intRange(path: String): IntRange = get(path, ColumnType.ColumnIntRange) + + fun intRangeOrNull(path: String): IntRange? = getOrNull(path, ColumnType.ColumnIntRange) + /* Entities */ @@ -180,8 +189,8 @@ object Tables { while (nextSection()) { val stringId = section() if (stringId.contains(".")) { - val (key, rowName) = stringId.split(".") - readTableRow(this, definitions, rows, ids, key, rowName) + val table = stringId.substringBefore(".") + readTableRow(this, definitions, rows, ids, table, stringId) } else { readTableHeader(this, definitions, stringId) } diff --git a/game/src/main/kotlin/Main.kt b/game/src/main/kotlin/Main.kt index bf6fc258bf..5e40ce2e8f 100644 --- a/game/src/main/kotlin/Main.kt +++ b/game/src/main/kotlin/Main.kt @@ -132,6 +132,12 @@ object Main { get() EnumDefinitions.init(EnumDecoder().load(cache)).load(files.list(Settings["definitions.enums"])) } + single(createdAtStart = true) { + get() + get() + get() + Tables.load(files.list(Settings["definitions.tables"])) + } single(createdAtStart = true) { GraphicDefinitions(GraphicDecoder().load(cache)).load(files.list(Settings["definitions.graphics"])) } single(createdAtStart = true) { InterfaceDefinitions.init(InterfaceDecoder().load(cache)).load(files.list(Settings["definitions.interfaces"]), files.find(Settings["definitions.interfaces.types"])) } single(createdAtStart = true) { diff --git a/game/src/main/kotlin/content/skill/slayer/Slayer.kt b/game/src/main/kotlin/content/skill/slayer/Slayer.kt index 99e0532a84..ba408c193d 100644 --- a/game/src/main/kotlin/content/skill/slayer/Slayer.kt +++ b/game/src/main/kotlin/content/skill/slayer/Slayer.kt @@ -1,15 +1,14 @@ package content.skill.slayer import content.quest.questCompleted -import world.gregs.voidps.engine.client.ui.chat.toIntRange -import world.gregs.voidps.engine.data.definition.EnumDefinitions -import world.gregs.voidps.engine.data.definition.NPCDefinitions +import world.gregs.voidps.engine.data.config.TableDefinition +import world.gregs.voidps.engine.data.definition.ColumnType +import world.gregs.voidps.engine.data.definition.Rows +import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.character.Character import world.gregs.voidps.engine.entity.character.npc.NPC import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.combatLevel -import world.gregs.voidps.engine.entity.character.player.skill.Skill -import world.gregs.voidps.engine.entity.character.player.skill.level.Level.has import world.gregs.voidps.type.random // shade, zombie, skeleton, ghost, zogre, ankou @@ -63,52 +62,55 @@ fun Player.isTask(character: Character?): Boolean { return target.categories.contains(slayerTask) } -fun assignTask(player: Player, master: String): Pair { - val npc = rollTask(player, master)!! - val amount = EnumDefinitions.string("${master}_task_amount", npc).toIntRange(inclusive = true).random(random) +fun assignTask(player: Player, master: String): Pair { + val pair = rollTask(player, master) ?: error("No task found for $master") player.slayerTasks++ player.slayerMaster = master - player.slayerTask = EnumDefinitions.string("slayer_tasks_categories", npc) - player.slayerTaskRemaining = amount - return Pair(npc, amount) + player.slayerTask = pair.first + player.slayerTaskRemaining = pair.second + return pair } -fun rollTask(player: Player, master: String): Int? { +private fun rollTask(player: Player, master: String): Pair? { var total = 0 - val weights = EnumDefinitions.getOrNull("${master}_task_weight")?.map ?: return null - for ((npc, weight) in weights) { - if (!hasRequirements(player, npc)) { + val table = Tables.getOrNull("${master}_slayer_tasks") ?: return null + for (row in table.rows) { + val weight = table.int("weight", row) + if (!hasRequirements(player, table, row)) { continue } - total += weight as Int + total += weight } val roll = random.nextInt(total) var count = 0 - for ((npc, weight) in weights) { - if (!hasRequirements(player, npc)) { + for (row in table.rows) { + if (!hasRequirements(player, table, row)) { continue } - count += weight as Int + val weight = table.int("weight", row) + count += weight if (roll < count) { - return npc + val range = table.get("amount", row, ColumnType.ColumnIntRange) + val row = Rows.get(row) + return Pair(row.stringId, range.random(random)) } } return null } -private fun hasRequirements(player: Player, index: Int): Boolean { - val slayerLevel = NPCDefinitions.get(index)["slayer_level", 1] - if (!player.has(Skill.Slayer, slayerLevel)) { - return false - } - val combatLevel = EnumDefinitions.int("slayer_task_combat_level", index) +private fun hasRequirements(player: Player, table: TableDefinition, row: Int): Boolean { +// val slayerLevel = NPCDefinitions.get(index)["slayer_level", 1] // FIXME +// if (!player.has(Skill.Slayer, slayerLevel)) { +// return false +// } + val combatLevel = table.int("combat_level", row) if (player.combatLevel < combatLevel) { return false } - val variable = EnumDefinitions.stringOrNull("slayer_task_variable", index) + val variable = table.stringOrNull("variable", row) if (variable != null && !player.contains(variable)) { return false } - val quest = EnumDefinitions.stringOrNull("slayer_task_quest", index) ?: return true + val quest = table.stringOrNull("quest", row) ?: return true return player.questCompleted(quest) } diff --git a/game/src/main/kotlin/content/skill/slayer/master/SlayerMaster.kt b/game/src/main/kotlin/content/skill/slayer/master/SlayerMaster.kt index 9fc7d3a9bc..b85b6628e7 100644 --- a/game/src/main/kotlin/content/skill/slayer/master/SlayerMaster.kt +++ b/game/src/main/kotlin/content/skill/slayer/master/SlayerMaster.kt @@ -10,7 +10,7 @@ import content.skill.slayer.* import net.pearx.kasechange.toSentenceCase import world.gregs.voidps.engine.Script import world.gregs.voidps.engine.client.ui.open -import world.gregs.voidps.engine.data.definition.EnumDefinitions +import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.combatLevel import world.gregs.voidps.engine.inv.add @@ -114,12 +114,11 @@ class SlayerMaster : Script { } suspend fun Player.roll(master: String) { - val (npc, amount) = assignTask(this, master) - val type = EnumDefinitions.string("slayer_tasks_categories", npc) + val (type, amount) = assignTask(this, master) npc("Excellent, you're doing great. Your new task is to kill $amount ${type.toSentenceCase()}.") choice { option("Got any tips for me?") { - val tip = EnumDefinitions.string("slayer_task_tips", npc) + val tip = Tables.string("${master}_slayer_tasks.${type}.tip") npc(tip) } option("Okay, great!") @@ -133,14 +132,13 @@ class SlayerMaster : Script { player("Pleeeaasssse!") npc("Oh okay then, you twisted my arm. You'll have to train against specific groups of creatures.") player("Okay, what's first?") - val (npc, amount) = assignTask(this, master) - val type = EnumDefinitions.string("slayer_tasks_categories", npc) + val (type, amount) = assignTask(this, master) npc("We'll start you off hunting ${type.toSentenceCase()}, you'll need to kill $amount of them.") npc("You'll also need this enchanted gem, it allows Slayer Masters like myself to contact you and update you on your progress. Don't worry if you lose it, you can buy another from any Slayer Master.") inventory.add("enchanted_gem") choice { option("Got any tips for me?") { - val tip = EnumDefinitions.string("slayer_task_tips", npc) + val tip = Tables.string("${master}_slayer_tasks.${type}.tip") npc(tip) } option("Okay, great!") { diff --git a/game/src/main/resources/game.properties b/game/src/main/resources/game.properties index 57207fd37f..32a740bfe7 100644 --- a/game/src/main/resources/game.properties +++ b/game/src/main/resources/game.properties @@ -454,6 +454,7 @@ definitions.clientScripts=scripts.toml # Misc definitions.produce=farming_produce.toml +definitions.tables=tables.toml #=================================== # Security & RSA Encryption Keys diff --git a/game/src/test/kotlin/WorldTest.kt b/game/src/test/kotlin/WorldTest.kt index c50cc00339..f753f60fbc 100644 --- a/game/src/test/kotlin/WorldTest.kt +++ b/game/src/test/kotlin/WorldTest.kt @@ -26,6 +26,8 @@ import world.gregs.voidps.cache.secure.Huffman import world.gregs.voidps.engine.* import world.gregs.voidps.engine.client.update.view.Viewport import world.gregs.voidps.engine.data.* +import world.gregs.voidps.engine.data.config.RowDefinition +import world.gregs.voidps.engine.data.config.TableDefinition import world.gregs.voidps.engine.data.definition.* import world.gregs.voidps.engine.entity.Spawn import world.gregs.voidps.engine.entity.World @@ -176,6 +178,11 @@ abstract class WorldTest : KoinTest { EnumDefinitions.set(enumDefinitions, enumIds) EnumDefinitions } + single(createdAtStart = true) { + Tables.set(tableDefinitions) + Rows.set(rowDefinitions, rowIds) + Tables + } single(createdAtStart = true) { fontDefinitions } single(createdAtStart = true) { objectTeleports } single(createdAtStart = true) { itemOnItemDefinitions } @@ -361,6 +368,24 @@ abstract class WorldTest : KoinTest { EnumDefinitions.definitions } + private val tableDefinitions: Map by lazy { + itemIds + npcIds + objectIds + Tables.load(configFiles.list(Settings["definitions.tables"])) + Tables.definitions + } + + private val rowDefinitions: Array by lazy { + tableDefinitions + Rows.definitions + } + + private val rowIds: Map by lazy { + tableDefinitions + Rows.ids + } + private val enumIds: Map by lazy { enumDefinitions EnumDefinitions.ids From a2454985b531d1978db64c76b2cda4f7ae5e7933 Mon Sep 17 00:00:00 2001 From: GregHib Date: Wed, 25 Mar 2026 11:33:53 +0000 Subject: [PATCH 06/40] Replace slayer enums with tables --- data/skill/slayer/chaeldar.enums.toml | 79 ----- data/skill/slayer/duradel.enums.toml | 69 ---- data/skill/slayer/kuradal.enums.toml | 79 ----- data/skill/slayer/mazchna.enums.toml | 71 ---- data/skill/slayer/slayer.enums.toml | 305 ------------------ data/skill/slayer/slayer.tables.toml | 208 ++++++------ data/skill/slayer/sumona.enums.toml | 79 ----- data/skill/slayer/turael.enums.toml | 59 ---- data/skill/slayer/vannaka.enums.toml | 97 ------ .../content/skill/slayer/EnchantedGem.kt | 10 +- .../kotlin/content/skill/slayer/Slayer.kt | 19 +- 11 files changed, 121 insertions(+), 954 deletions(-) delete mode 100644 data/skill/slayer/chaeldar.enums.toml delete mode 100644 data/skill/slayer/duradel.enums.toml delete mode 100644 data/skill/slayer/kuradal.enums.toml delete mode 100644 data/skill/slayer/mazchna.enums.toml delete mode 100644 data/skill/slayer/slayer.enums.toml delete mode 100644 data/skill/slayer/sumona.enums.toml delete mode 100644 data/skill/slayer/turael.enums.toml delete mode 100644 data/skill/slayer/vannaka.enums.toml diff --git a/data/skill/slayer/chaeldar.enums.toml b/data/skill/slayer/chaeldar.enums.toml deleted file mode 100644 index fcb9ee85a5..0000000000 --- a/data/skill/slayer/chaeldar.enums.toml +++ /dev/null @@ -1,79 +0,0 @@ -[chaeldar_task_amount] -keyType = "npc" -valueType = "string" -values = { - aberrant_spectre = "70-130", - abyssal_demon = "70-130", - aviansie_god_wars = "70-130", - basilisk = "70-130", - black_demon = "70-130", - bloodveld = "70-130", - blue_dragon = "70-130", - brine_rat = "70-130", - cave_horror = "70-130", - rock_crab = "70-130", - dagannoth_lighthouse_range_74 = "70-130", - dust_devil = "70-130", - elf_warrior = "70-130", - fever_spider = "70-130", - fire_giant = "70-130", - gargoyle = "70-130", - greater_demon = "70-130", - hellhound = "70-130", - jelly = "70-130", - jungle_horror = "70-130", - jungle_strykewyrm = "80-110", - kalphite_worker = "70-130", - kurask = "70-130", - lesser_demon = "70-130", - zygomite = "8-15", - nechryael = "70-130", - shadow_warrior = "70-130", - skeletal_wyvern = "10-20", - spiritual_mage_zamorak = "70-130", - ice_troll_troll_country = "70-130", - turoth = "70-130", - tzhaar_mej = "90-150", - vampyre_juvinate = "80-100", - warped_terrorbird = "70-130", -} - -[chaeldar_task_weight] -keyType = "npc" -valueType = "int" -values = { - aberrant_spectre = 8, - abyssal_demon = 12, - aviansie_god_wars = 9, - basilisk = 7, - black_demon = 10, - bloodveld = 8, - blue_dragon = 8, - brine_rat = 7, - cave_horror = 10, - rock_crab = 8, - dagannoth_lighthouse_range_74 = 11, - dust_devil = 9, -# elf_warrior = 8, -# fever_spider = 7, - fire_giant = 12, - gargoyle = 11, - greater_demon = 9, - hellhound = 9, - jelly = 10, - jungle_horror = 10, - jungle_strykewyrm = 12, - kalphite_worker = 11, - kurask = 12, - lesser_demon = 9, - zygomite = 7, - nechryael = 12, - shadow_warrior = 8, - skeletal_wyvern = 7, - spiritual_mage_zamorak = 12, - ice_troll_troll_country = 11, - turoth = 10, - tzhaar_mej = 8, -# vampyre_juvinate = 6, -# warped_terrorbird = 6, -} diff --git a/data/skill/slayer/duradel.enums.toml b/data/skill/slayer/duradel.enums.toml deleted file mode 100644 index 11c112eafd..0000000000 --- a/data/skill/slayer/duradel.enums.toml +++ /dev/null @@ -1,69 +0,0 @@ -[duradel_task_amount] -keyType = "npc" -valueType = "string" -values = { - aberrant_spectre = "130-200", - abyssal_demon = "130-200", - aquanite = "130-200", - aviansie_god_wars = "100-125", - black_demon = "130-200", - black_dragon = "40-80", - bloodveld = "130-200", - dagannoth_lighthouse_range_74 = "130-200", - dark_beast = "130-200", - desert_strykewyrm = "90-140", - dust_devil = "130-200", - fire_giant = "130-200", - gargoyle = "130-200", - gorak = "40-80", - greater_demon = "130-200", - hellhound = "130-200", - ice_strykewyrm = "100-200", - iron_dragon = "40-80", - jungle_strykewyrm = "90-120", - kalphite_worker = "130-200", - mithril_dragon = "4-8", - nechryael = "130-200", - giant_scarab_normal = "40-80", - skeletal_wyvern = "40-80", - spiritual_mage_zamorak = "120-185", - steel_dragon = "40-80", - suqah = "40-80", - warped_terrorbird = "130-200", - waterfiend = "130-200", -} - -[duradel_task_weight] -keyType = "npc" -valueType = "int" -values = { - aberrant_spectre = 10, - abyssal_demon = 15, - aquanite = 9, - aviansie_god_wars = 8, - black_demon = 10, - black_dragon = 9, - bloodveld = 10, - dagannoth_lighthouse_range_74 = 10, - dark_beast = 15, - desert_strykewyrm = 11, - dust_devil = 10, - fire_giant = 10, - gargoyle = 10, - gorak = 5, - greater_demon = 10, - hellhound = 9, - ice_strykewyrm = 8, - iron_dragon = 9, - jungle_strykewyrm = 10, - kalphite_worker = 10, - mithril_dragon = 7, - nechryael = 10, -# giant_scarab_normal = 10, - skeletal_wyvern = 5, - spiritual_mage_zamorak = 10, - steel_dragon = 7, - suqah = 5, -# warped_terrorbird = 9, - waterfiend = 10, -} diff --git a/data/skill/slayer/kuradal.enums.toml b/data/skill/slayer/kuradal.enums.toml deleted file mode 100644 index 14c2356408..0000000000 --- a/data/skill/slayer/kuradal.enums.toml +++ /dev/null @@ -1,79 +0,0 @@ -[kuradal_task_amount] -keyType = "npc" -valueType = "string" -values = { - aberrant_spectre = "150-250", - abyssal_demon = "150-250", - aquanite = "160-200", - aviansie_god_wars = "125-150", - black_demon = "190-250", - black_dragon = "40-90", - bloodveld = "180-250", - blue_dragon = "120-200", - dagannoth_lighthouse_range_74 = "170-240", - dark_beast = "150-250", - desert_strykewyrm = "90-160", - dust_devil = "150-250", - elf_warrior = "120-150", - fire_giant = "170-250", - gargoyle = "150-250", - greater_demon = "150-250", - hellhound = "130-220", - ice_strykewyrm = "100-200", - iron_dragon = "60-110", - jungle_strykewyrm = "90-130", - kalphite_worker = "170-250", - living_rock_protector = "120-170", - mithril_dragon = "30-35", - nechryael = "140-220", - giant_scarab_normal = "80-120", - skeletal_wyvern = "40-90", - spiritual_mage_zamorak = "120-185", - steel_dragon = "40-100", - suqah = "50-100", - terror_dog = "60-70", - tormented_demon = "40-60", - tzhaar_mej = "80-110", - warped_terrorbird = "150-240", - waterfiend = "170-250", -} - -[kuradal_task_weight] -keyType = "npc" -valueType = "int" -values = { - aberrant_spectre = 10, - abyssal_demon = 10, - aquanite = 10, - aviansie_god_wars = 9, - black_demon = 10, - black_dragon = 5, - bloodveld = 10, - blue_dragon = 7, - dagannoth_lighthouse_range_74 = 10, - dark_beast = 12, - desert_strykewyrm = 7, - dust_devil = 10, -# elf_warrior = 12, - fire_giant = 10, - gargoyle = 12, - greater_demon = 11, - hellhound = 10, - ice_strykewyrm = 9, - iron_dragon = 9, - jungle_strykewyrm = 8, - kalphite_worker = 5, -# living_rock_protector = 10, - mithril_dragon = 8, - nechryael = 10, -# giant_scarab_normal = 10, - skeletal_wyvern = 5, - spiritual_mage_zamorak = 10, - steel_dragon = 9, - suqah = 5, -# terror_dog = 6, -# tormented_demon = 8, - tzhaar_mej = 7, -# warped_terrorbird = 8, - waterfiend = 9, -} diff --git a/data/skill/slayer/mazchna.enums.toml b/data/skill/slayer/mazchna.enums.toml deleted file mode 100644 index 615daca3fe..0000000000 --- a/data/skill/slayer/mazchna.enums.toml +++ /dev/null @@ -1,71 +0,0 @@ -[mazchna_task_amount] -keyType = "npc" -valueType = "string" -values = { - banshee = "30-50", - bat = "30-50", - black_bear = "30-50", - catablepon = "20-30", - cave_bug = "10-20", - cave_crawler = "30-50", - cave_slime = "10-20", - cockatrice = "30-50", - rock_crab = "30-50", - crawling_hand = "30-50", - guard_dog = "30-50", - flesh_crawler = "15-25", - ghost = "30-50", - ghoul = "10-20", - hill_giant = "30-50", - hobgoblin_unarmed = "30-50", - ice_warrior = "40-50", - kalphite_worker = "30-50", - killerwatt = "30-50", - lizard = "30-50", - mogre = "30-50", - pyrefiend_large = "30-50", - rockslug = "30-50", - scorpion = "30-50", - asyn_shade = "30-70", - skeleton_heavy = "30-50", - vampyre_juvinate = "10-20", - wall_beast = "10-20", - wolf = "30-50", - zombie = "30-50", -} - -[mazchna_task_weight] -keyType = "npc" -valueType = "int" -values = { - banshee = 8, - bat = 7, - black_bear = 6, - catablepon = 8, - cave_bug = 8, - cave_crawler = 8, - cave_slime = 8, - cockatrice = 8, - rock_crab = 8, - crawling_hand = 8, - guard_dog = 7, - flesh_crawler = 7, - ghost = 7, - ghoul = 7, - hill_giant = 7, - hobgoblin_unarmed = 7, - ice_warrior = 7, - kalphite_worker = 6, - # killerwatt = 6, - lizard = 8, - # mogre = 8, - pyrefiend_large = 8, - rockslug = 8, - scorpion = 7, - # asyn_shade = 8, - skeleton_heavy = 7, - # vampyre_juvinate = 6, - wall_beast = 7, - wolf = 7, - zombie = 7, -} diff --git a/data/skill/slayer/slayer.enums.toml b/data/skill/slayer/slayer.enums.toml deleted file mode 100644 index 506d751acb..0000000000 --- a/data/skill/slayer/slayer.enums.toml +++ /dev/null @@ -1,305 +0,0 @@ -[slayer_tasks_categories] -keyType = "npc" -valueType = "string" -values = { - aberrant_spectre = "aberrant_spectre", - abyssal_demon = "abyssal_demon", - aquanite = "aquanites", - ankou = "ankou", - aviansie_god_wars = "aviansies", - guard_bandit = "bandits", - basilisk = "basilisks", - banshee = "banshees", - bloodveld = "bloodvelds", - brine_rat = "brine_rats", - black_bear = "bears", - bat = "bats", - bird_black = "birds", - black_demon = "black_demons", - black_dragon = "black_dragons", - black_knight = "black_knights", - blue_dragon = "blue_dragons", - bronze_dragon = "bronze_dragons", - catablepon = "catablepons", - cave_bug = "cave_bugs", - cave_crawler = "cave_crawlers", - cave_horror = "cave_horrors", - cave_slime = "cave_slimes", - cockatrice = "cockatrice", - cow_default = "cows", - crawling_hand = "crawling_hands", - chaos_druid = "chaos_druid", - rock_crab = "crabs", - crocodile_kharidian_desert = "crocodiles", - dark_beast = "dark_beasts", - dust_devil = "dust_devils", - dagannoth_lighthouse_range_74 = "dagannoth", - dark_warrior = "dark_warriors", - guard_dog = "dogs", - dwarf = "dwarves", - earth_warrior = "earth_warrior", - elf_warrior = "elves", - fire_giant = "fire_giant", - flesh_crawler = "flesh_crawlers", - fever_spider = "fever_spiders", - frost_dragon = "frost_dragons", - ghost = "ghosts", - gargoyle = "gargoyles", - ghoul = "ghouls", - goblin_mohawk_blue = "goblin", - gorak = "gorak", - greater_demon = "greater_demons", - green_dragon = "green_dragons", - hellhound = "hellhounds", - hill_giant = "hill_giants", - hobgoblin_unarmed = "hobgoblins", - harpie_bug_swarm = "harpie_bug_swarms", - infernal_mage = "infernal_mage", - ice_giant = "ice_giant", - ice_warrior = "ice_warriors", - icefiend = "icefiends", - iron_dragon = "iron_dragons", - jelly = "jellies", - jungle_horror = "jungle_horrors", - kalphite_worker = "kalphites", - killerwatt = "killerwatts", - kurask = "kurask", - lesser_demon = "lesser_demons", - lizard = "lizards", - magic_axe = "magic_axe", - mogre = "mogres", - zygomite = "mutated_zygomites", - minotaur = "minotaurs", - mithril_dragon = "mithril_dragons", - monkey_brown = "monkeys", - moss_giant = "moss_giants", - nechryael = "nechryael", - ogre_chieftain = "ogres", - otherworldly_being = "otherworldly_beings", - pirate_pirates_cove = "pirates", - pyrefiend_large = "pyrefiends", - rat = "rats", - red_dragon = "red_dragons", - # revenant = "revenants", - rogue_castle = "rogues", - rockslug = "rockslugs", - giant_scarab_normal = "scabarites", - scorpion = "scorpions", - sea_snake_young = "sea_snakes", - skeletal_wyvern = "skeletal_wyverns", - asyn_shade = "shades", - shadow_warrior = "shadow_warriors", - skeleton_heavy = "skeletons", - spiritual_mage_zamorak = "spiritual_creatures", - spider = "spiders", - steel_dragon = "steel_dragons", - suqah = "suqahs", - turoth = "turoth", - ice_troll_troll_country = "trolls", - tzhaar_mej = "tzhaar", - vampyre_juvinate = "vampyres", - waterfiend = "waterfiends", - werewolf = "werewolves", - wolf = "wolves", - wall_beast = "wall_beasts", - warped_terrorbird = "warped_creatures", - zombie = "zombies", -} - -[slayer_task_tips] -keyType = "npc" -valueType = "string" -values = { - aberrant_spectre = "Aberrant Spectres are fetid, vile ghosts. The very smell of them will paralyse and harm you. A nosepeg will help ignore their stink.", - abyssal_demon = "Abyssal Demons are nasty creatures to fight. They aren't really part of this realm, and are able to move very quickly to trap their prey.", - aquanite = "Aquanites rely on their lures for both offensive and defensive purposes. Whilst their hides are resistant to slashing attacks, a well timed cut is capable of severing the lure.", # FIXME rs2 version - ankou = "Ankou are undead skeletal ghosts. Their blows can be powerful but they have limited defences, so killing them quickly is often the best way to protect yourself.", - aviansie_god_wars = "Aviansies are bird-like creatures found in the icy dungeons of the north. Melee weapons can't reach them, so use Magic or Ranged attacks.", - guard_bandit = "Bandits band together for protection against enemies such as yourself.", - basilisk = "Basilisks, like Cockatrice, have a gaze which will paralyse and harm their prey. You'll need a Mirror Shield to protect you.", - banshee = "Banshees use a piercing scream to shock their enemies, you'll need some Earmuffs to protect yourself from them.", - bloodveld = "Bloodveld are strange demonic creatures, their long rasping tongue has magical properties so it pierces straight through physical defences.", - brine_rat = "Brine Rats can be found in caves that are near the sea. They are hairless, bad-tempered and generally unfriendly.", - black_bear = "Bears are tough creatures and fierce fighters, watch out for their powerful claws.", - bat = "Bats are rarely found on the ground, so you'll have to fight them while they're airborne, which won't be easy for melee.", - bird_black = "Birds aren't the most intelligent of creatures, but watch out for their sharp stabbing beaks.", - black_demon = "Powerful weapons known as demonbane weapons can be used to quickly defeat even powerful demons like the Black Demon with greater ease.", - black_dragon = "Black Dragons are the strongest dragons and very fierce, watch out for their fiery breath.", - black_knight = "Black Knights like using black armour and weapons, this makes them susceptible to magic attacks.", - blue_dragon = "Like all dragons, Blue Dragons have thick scales and a powerful fiery breath. Stabbing weapons and heavy bolts are best suited to piercing their defences.", - bronze_dragon = "Bronze Dragons are the weakest of the metallic dragons, their bronze scales are far thicker than normal bronze armour.", - catablepon = "Catablepon are mythical, cow like, magical creatures. Beware their weakening glare.", - cave_bug = "Cave Bugs are like Cave Crawlers, except smaller and easier to squish, though they still have a fondness for plants.", - cave_crawler = "Cave Crawlers are small and fast, often hiding in ambush. Avoid their barbed tongue or you'll get poisoned.", - cave_horror = "Cave Horrors can be found under Mos Le'Harmless. You will need a Witchwood Icon to fight them effectively.", - cave_slime = "Cave Slimes are the lesser cousins of Jellies, though don't be fooled they can still be dangerous as they're often poisonous.", - cockatrice = "Cockatrice, like Basilisks, have a gaze which will paralyse and harm their prey. You'll need a Mirror Shield to protect you.", - cow_default = "Cows are bigger than you, so they'll often hit fairly hard but are usually fairly slow to react.", - crawling_hand = "Crawling Hands are undead severed hands, fast and dexterous they claw their victims.", - chaos_druid = "Chaos Druids are druids who've turned to evil. Some of them have spells that can harm you, or even teleport you back to them if you flee.", - rock_crab = "Crabs can be found all across Gielinor. They don't hit very hard but they can take a while to kill.", - crocodile_kharidian_desert = "Crocodiles are large reptiles which live near water. You'll want to have a stabbing weapon handy for puncturing their thick scaly hides.", - dark_beast = "Dark Beasts are large, dog-like predators. Their massively muscled bodies protect them from crushing weapons.", - dust_devil = "Dust Devils use clouds of dust, sand, ash, and whatever else they can inhale to blind and disorientate their victims. Make sure to wear a facemask when fighting them.", - dagannoth_lighthouse_range_74 = "Dagannoth are large sea dwelling creatures which are very aggressive. You'll often find them in caves near sea water.", - dark_warrior = "Dark Warriors wear protective armour. If you want to fight them with melee, try crush-based attacks. Or try magic instead.", - guard_dog = "Dogs are much like Wolves, they are pack creatures which will hunt in groups.", - dwarf = "Dwarves are a small but tough race of miners, often using pickaxes to pierce their opponents armour.", - earth_warrior = "Earth Warriors are a kind of earth elemental, grind them to dust with blunt weapons.", - elf_warrior = "Elves are quick, agile, and vicious fighters which often favour bows and polearms.", - fire_giant = "Like other giants, Fire Giants have little to no magical ability, and they're particularly weak to water spells.", - flesh_crawler = "Fleshcrawlers are scavengers and will eat you - and anyone else, given the chance.", - fever_spider = "Fever Spiders are giant spiders that carry the deadly Spider Fever. If you don't want to catch it I suggest you wear Slayer Gloves to fight them.", - frost_dragon = "Frost dragons reside beneath the island of Grimstone. They have thick scales and powerful icy breath. Dragonfire protection is a must.", - ghost = "Ghosts are undead so magic is your best bet against them, there is even a spell specially for fighting the undead.", - gargoyle = "Gargoyles are winged creatures of stone. You'll need to fight them to near death before breaking them apart with a Rock Hammer.", - ghoul = "Ghouls aren't undead but they are stronger and tougher than they look. However they're also very cowardly and will run if they're losing a fight.", - goblin_mohawk_blue = "Goblins are mostly just annoying, but they can be vicious. Watch out for the spears they sometimes carry.", - gorak = "Goraks are extremely aggressive creatures. They have been imprisoned on an alternative plane, which is only accesible by using the fairyrings. Be extremely careful, their touch drains health as well as skills! ", - greater_demon = "Demons are particularly weak to water spells. Though Greater Demons are not the strongest type of demon they are still dangerous.", - green_dragon = "Like all dragons, Green Dragons have thick scales and a powerful fiery breath. Unless you can stay out of their reach, bringing dragonfire protection is a must.", - hellhound = "Hellhounds are a cross between Dogs and Demons. They are dangerous with a fierce bite, but have all of the same weaknesses as most demons.", - hill_giant = "Hill Giants often wield large weapons, learn to recognise what kind of weapon it is and act accordingly.", - hobgoblin_unarmed = "Hobgoblins carrying spears are often trained warriors. If you want less of a challenge, fight the ones that are unarmed.", - harpie_bug_swarm = "Harpie Bug Swarms are pesky critters that are hard to hit. You need a lit bug lantern to distract them with its hypnotic light.", - infernal_mage = "Infernal Mages are dangerous spell users, beware of their magic spells and go properly prepared.", - ice_giant = "Like other giants, Ice Giants have little to no magical ability, and they're particularly weak to fire spells.", - ice_warrior = "Ice Warriors are a kind of ice elemental, shatter them with blunt weapons or melt them with fire.", - icefiend = "Icefiends are beings of ice and freezing rock, they're quick and agile so you'll want to be careful when getting close to them.", - iron_dragon = "Iron Dragons are some of the weaker metallic dragons, their iron scales are far thicker than normal iron armour.", - jelly = "Jellies are nasty cube-like gelatinous creatures which absorb everything they come across into themselves. Their magical acids bypass physical defences.", - jungle_horror = "Jungle Horrors can be found all over Mos Le'Harmless. They are strong and aggressive, so watch out!", - kalphite_worker = "Kalphite are large insects which live in great hives under the desert sands.", - killerwatt = "Killerwatts store huge amounts of energy in their bodies, which is released if they are touched. You'll need to wear heavily insulated boots to counter this shocking effect.", - kurask = "Kurask are large brutal creatures with very thick hides. You'll need a Leaf-Tipped Spear or Battle-axe, Broad Arrows, or a Magic Dart to harm it.", - lesser_demon = "Demons are weak to magical attacks. Though Lesser Demons are relatively weak they are still dangerous.", - lizard = "Lizards are large reptiles with tough skin. Those found in the desert will need you to douse them with freezing water to finish them off after a tough battle.", - magic_axe = "Magic Axes have a mind of their own. You may find magic or slash-based melee attacks are slightly more effective against them.", - mogre = "Mogres are a type of aquatic Ogre that is often mistaken for a giant mudskipper. You have to force them out of the water with a fishing explosive.", - zygomite = "Mutated Zygomites are hard to destroy. They regenerate quickly so you will need to finish them with fungicide.", - minotaur = "Minotaurs are large manlike creatures but you'll want to be careful of their horns.", - mithril_dragon = "Mithril dragons are more vulnerable to magic and to stab-based melee attacks than to anything else.", - monkey_brown = "Monkeys are tricky creatures, they are agile and fairly fast. Learn to anticipate their movements.", - moss_giant = "Like other giants, Moss Giants have little to no magical ability, and they're particularly weak to fire spells.", - nechryael = "Nechryael are demons of decay which summon small winged beings to help them fight their victims. Their minions can bypass protective prayers so be sure to wear thick armour.", - ogre_chieftain = "Ogres are brutal creatures, favouring large blunt maces and clubs, they often attack without warning.", - otherworldly_being = "Otherworldly Beings are ethereal beings making them weak to magical attack.", - pirate_pirates_cove = "Pirates can be found near the sea. They like to collect coins among other things.", - pyrefiend_large = "Pyrefiends are beings of fire and molten rock, they're quick and agile but weak to water spells.", - rat = "Rats are your everyday pest, but they can get fairly big. Watch out for their sharp piercing teeth.", - red_dragon = "Red Dragons are very powerful, stronger than most dragons, watch out for their fiery breath.", - # revenants = "Revenants can be found in the Wilderness, residing in the deepest cavern of the Forinthry dungeon. They use all three styles of combat, but a charged Revenant bracelet will protect you from their attacks.", - rogue_castle = "Rogues are found in lawless areas, such as the deep Wilderness. They can be very protective of their loot.", - rockslug = "Rockslugs are strange stoney slugs. You'll need to fight them to near death before finishing them off with Salt.", - giant_scarab_normal = "Scabarites are insectoid creatures, found beyond the Kharidian deserts. Make sure not to fall into one of their pitfall traps or you'll be quickly overwhelmed.", - scorpion = "Scorpions are almost always poisonous, their hard carapace makes them resistant to crushing and stabbing attacks.", - sea_snake_young = "Sea Snakes are long and slithery with a venomous bite. The larger ones are more poisonous, so keep an eye on your health.", - skeletal_wyvern = "Skeletal Wyverns are extremely dangerous and they are hard to hit with arrows as they slip right through. To stand a good chance of surviving you'll need some elemental shielding from its icy breath.", - asyn_shade = "Shades are undead so magic is your best bet against them. You can find Shades at Mort'ton.", - shadow_warrior = "Shadow Warriors are dark and mysterious. They wear spectral plate armour, so crush weapons and magic will give them trouble.", - skeleton_heavy = "Skeletons are undead so magic is your best bet against them, there is even a spell specially for fighting the undead.", - spiritual_mage_zamorak = "Spiritual Creatures can be found in the icy caverns near Trollheim, supporting the cause of their chosen god. Wearing equipment aligned with each of the gods can help you avoid undesired conflict.", - spider = "Spiders are often poisonous, and many varieties are camouflaged too.", - steel_dragon = "Steel Dragons are dangerous metallic dragons, their steel scales are far thicker than normal steel armour.", - suqah = "Suqahs can only be found on the mystical Lunar Isle. They are capable of melee and magic attacks and often drop hide, teeth and herbs!", - turoth = "Turoth are large vicious creatures with thick hides. You'll need a Leaf-Tipped Spear or Sword, Broad Arrows, or a Magic Dart to harm them.", - ice_troll_troll_country = "Trolls regenerate damage quickly and have some level of magical defences, but this is easily bypassed by their weakness to fire.", - tzhaar_mej = "Tzhaar reside in their cave under the Karamja volcano. Beware as they can call to their fellows for aid.", - vampyre_juvinate = "Vampyres are extremely powerful beings. An underground group known as the Myreque have been searching for tools to defeat them, which they may be willing to share if you can find them.", - waterfiend = "Waterfiends are creatures of water, which live under the Baxtorian Lake. Their watery form is well defended against slashing and piercing weapons, so use something blunt.", - werewolf = "Werewolves are feral creatures, they are strong and tough with sharp claws and teeth.", - wolf = "Wolves are pack animals, so you'll always find them in groups. Watch out for their bite, it can be nasty.", - wall_beast = "Wall Beasts are really much larger creatures but you'll only see their arms. You'll want something sharp on your head to stop them grabbing you.", - warped_terrorbird = "Warped Creatures can supposedly be found within a mysterious dungeon on the eastern edge of the Poison Waste. Be aware that to defeat them, you'll need to purify them in some way.", - zombie = "Zombies are undead so magic is your best bet against them, there is even a spell specially for fighting the undead.", -} - -[slayer_task_combat_level] -keyType = "npc" -valueType = "int" -values = { - aberrant_spectre = 65, - aviansie_god_wars = 70, - banshee = 20, - bat = 5, - black_bear = 13, - black_demon = 100, - catablepon = 35, - cave_crawler = 10, - cave_slime = 15, - cow_default = 5, - cockatrice = 25, - crocodile_kharidian_desert = 40, - dwarf = 6, - desert_strykewyrm = 90, - flesh_crawler = 15, - guard_dog = 15, - ghost = 13, - ghoul = 25, - hill_giant = 25, - hobgoblin_unarmed = 20, - icefiend = 20, - ice_warrior = 45, - jungle_strykewyrm = 80, - lizard = 20, - minotaur = 7, - kalphite_worker = 15, - killerwatt = 50, - mogre = 30, - pyrefiend_large = 25, - rockslug = 20, - scorpion = 10, - asyn_shade = 30, - skeleton_heavy = 15, - vampyre_juvinate = 35, - wall_beast = 30, - wolf = 20, - zombie = 10, - skeletal_wyvern = 100, - mithril_dragon = 100, -} - -[slayer_task_defence_level] -keyType = "npc" -valueType = "int" -values = { - cockatrice = 20, - wall_beast = 5, -} - -[slayer_task_quest] -keyType = "npc" -valueType = "string" -values = { - aberrant_spectre = "priest_in_peril", - banshee = "priest_in_peril", - # TODO aviansie_god_wars & spiritual_mage_zamorak req god wars dungeon knight varbit - crawling_hand = "priest_in_peril", - ghoul = "priest_in_peril", - gargoyle = "priest_in_peril", - killerwatt = "ernest_the_chicken", - mogre = "skippy_and_the_mogres", - # TODO mithril_dragon req barbarian training - vampyre_juvinate = "priest_in_peril", - warped_terrorbird = "the_path_of_glouphrie", - giant_scarab_normal = "dealing_with-scabaras", - nechryael = "what_lies_below", - elf_warrior = "regicide", - dust_devil = "what_lies_below", - dagannoth_lighthouse_range_74 = "horror_from_the_deep", - cave_horror = "cabin_fever", - waterfiend = "what_lies_below", - suqah = "lunar_diplomacy", - dark_beast = "mournings_end_part_ii", - tormented_demon = "while_guthix_sleeps", - terror_dog = "haunted_mine", - skeletal_wyvern = "elemental_workshop_i", - ice_strykewyrm = "the_tale_of_the_muspah", -} - -[slayer_task_variable] -keyType = "npc" -valueType = "string" -values = { - aquanite = "aquanites", -} \ No newline at end of file diff --git a/data/skill/slayer/slayer.tables.toml b/data/skill/slayer/slayer.tables.toml index b84ebd380c..9680f81cc9 100644 --- a/data/skill/slayer/slayer.tables.toml +++ b/data/skill/slayer/slayer.tables.toml @@ -1,4 +1,5 @@ [slayer_tasks] +npc = "npc" combat_level = "int" defence_level = "int" quest = "string" @@ -6,361 +7,366 @@ variable = "string" tip = "string" [.aberrant_spectre] +npc = "aberrant_spectre" combat_level = 65 quest = "priest_in_peril" -tip = "Aberrant Spectres are fetid, vile ghosts. The very smell of them will paralyse and harm you. A nosepeg will help ignore their stink." [.abyssal_demon] -tip = "Abyssal Demons are nasty creatures to fight. They aren't really part of this realm, and are able to move very quickly to trap their prey." +npc = "abyssal_demon" [.aquanites] +npc = "aquanite" variable = "aquanites" -tip = "Aquanites rely on their lures for both offensive and defensive purposes. Whilst their hides are resistant to slashing attacks, a well timed cut is capable of severing the lure." [.ankou] -tip = "Ankou are undead skeletal ghosts. Their blows can be powerful but they have limited defences, so killing them quickly is often the best way to protect yourself." +npc = "ankou" [.aviansies] +npc = "aviansie_god_wars" +# TODO req god wars dungeon knight varbit combat_level = 70 -tip = "Aviansies are bird-like creatures found in the icy dungeons of the north. Melee weapons can't reach them, so use Magic or Ranged attacks." [.bandits] -tip = "Bandits band together for protection against enemies such as yourself." +npc = "guard_bandit" [.basilisks] -tip = "Basilisks, like Cockatrice, have a gaze which will paralyse and harm their prey. You'll need a Mirror Shield to protect you." +npc = "basilisk" [.banshees] +npc = "banshee" combat_level = 20 quest = "priest_in_peril" -tip = "Banshees use a piercing scream to shock their enemies, you'll need some Earmuffs to protect yourself from them." [.bloodvelds] -tip = "Bloodveld are strange demonic creatures, their long rasping tongue has magical properties so it pierces straight through physical defences." +npc = "bloodveld" [.brine_rats] -tip = "Brine Rats can be found in caves that are near the sea. They are hairless, bad-tempered and generally unfriendly." +npc = "brine_rat" [.bears] +npc = "black_bear" combat_level = 13 -tip = "Bears are tough creatures and fierce fighters, watch out for their powerful claws." [.bats] +npc = "bat" combat_level = 5 -tip = "Bats are rarely found on the ground, so you'll have to fight them while they're airborne, which won't be easy for melee." [.birds] -tip = "Birds aren't the most intelligent of creatures, but watch out for their sharp stabbing beaks." +npc = "bird_black" [.black_demons] +npc = "black_demon" combat_level = 100 -tip = "Powerful weapons known as demonbane weapons can be used to quickly defeat even powerful demons like the Black Demon with greater ease." [.black_dragons] -tip = "Black Dragons are the strongest dragons and very fierce, watch out for their fiery breath." +npc = "black_dragon" [.black_knights] -tip = "Black Knights like using black armour and weapons, this makes them susceptible to magic attacks." +npc = "black_knight" [.blue_dragons] -tip = "Like all dragons, Blue Dragons have thick scales and a powerful fiery breath. Stabbing weapons and heavy bolts are best suited to piercing their defences." +npc = "blue_dragon" [.bronze_dragons] -tip = "Bronze Dragons are the weakest of the metallic dragons, their bronze scales are far thicker than normal bronze armour." +npc = "bronze_dragon" [.catablepons] +npc = "catablepon" combat_level = 35 -tip = "Catablepon are mythical, cow like, magical creatures. Beware their weakening glare." [.cave_bugs] -tip = "Cave Bugs are like Cave Crawlers, except smaller and easier to squish, though they still have a fondness for plants." +npc = "cave_bug" [.cave_crawlers] +npc = "cave_crawler" combat_level = 10 -tip = "Cave Crawlers are small and fast, often hiding in ambush. Avoid their barbed tongue or you'll get poisoned." [.cave_horrors] +npc = "cave_horror" quest = "cabin_fever" -tip = "Cave Horrors can be found under Mos Le'Harmless. You will need a Witchwood Icon to fight them effectively." [.cave_slimes] +npc = "cave_slime" combat_level = 15 -tip = "Cave Slimes are the lesser cousins of Jellies, though don't be fooled they can still be dangerous as they're often poisonous." [.cockatrice] +npc = "cockatrice" combat_level = 25 defence_level = 20 -tip = "Cockatrice, like Basilisks, have a gaze which will paralyse and harm their prey. You'll need a Mirror Shield to protect you." [.cows] +npc = "cow_default" combat_level = 5 -tip = "Cows are bigger than you, so they'll often hit fairly hard but are usually fairly slow to react." [.crawling_hands] +npc = "crawling_hand" quest = "priest_in_peril" -tip = "Crawling Hands are undead severed hands, fast and dexterous they claw their victims." [.chaos_druid] -tip = "Chaos Druids are druids who've turned to evil. Some of them have spells that can harm you, or even teleport you back to them if you flee." +npc = "chaos_druid" [.crabs] -tip = "Crabs can be found all across Gielinor. They don't hit very hard but they can take a while to kill." +npc = "rock_crab" [.crocodiles] +npc = "crocodile_kharidian_desert" combat_level = 40 -tip = "Crocodiles are large reptiles which live near water. You'll want to have a stabbing weapon handy for puncturing their thick scaly hides." [.dark_beasts] +npc = "dark_beast" quest = "mournings_end_part_ii" -tip = "Dark Beasts are large, dog-like predators. Their massively muscled bodies protect them from crushing weapons." [.dust_devils] +npc = "dust_devil" quest = "what_lies_below" -tip = "Dust Devils use clouds of dust, sand, ash, and whatever else they can inhale to blind and disorientate their victims. Make sure to wear a facemask when fighting them." [.dagannoth] +npc = "dagannoth_lighthouse_range_74" quest = "horror_from_the_deep" -tip = "Dagannoth are large sea dwelling creatures which are very aggressive. You'll often find them in caves near sea water." [.dark_warriors] -tip = "Dark Warriors wear protective armour. If you want to fight them with melee, try crush-based attacks. Or try magic instead." +npc = "dark_warrior" [.dogs] +npc = "guard_dog" combat_level = 15 -tip = "Dogs are much like Wolves, they are pack creatures which will hunt in groups." [.dwarves] +npc = "dwarf" combat_level = 6 -tip = "Dwarves are a small but tough race of miners, often using pickaxes to pierce their opponents armour." [.earth_warrior] -tip = "Earth Warriors are a kind of earth elemental, grind them to dust with blunt weapons." +npc = "earth_warrior" [.elves] +npc = "elf_warrior" quest = "regicide" -tip = "Elves are quick, agile, and vicious fighters which often favour bows and polearms." [.fire_giant] -tip = "Like other giants, Fire Giants have little to no magical ability, and they're particularly weak to water spells." +npc = "fire_giant" [.flesh_crawlers] +npc = "flesh_crawler" combat_level = 15 -tip = "Fleshcrawlers are scavengers and will eat you - and anyone else, given the chance." [.fever_spiders] -tip = "Fever Spiders are giant spiders that carry the deadly Spider Fever. If you don't want to catch it I suggest you wear Slayer Gloves to fight them." +npc = "fever_spider" [.frost_dragons] -tip = "Frost dragons reside beneath the island of Grimstone. They have thick scales and powerful icy breath. Dragonfire protection is a must." +npc = "frost_dragon" [.ghosts] +npc = "ghost" combat_level = 13 -tip = "Ghosts are undead so magic is your best bet against them, there is even a spell specially for fighting the undead." [.gargoyles] +npc = "gargoyle" quest = "priest_in_peril" -tip = "Gargoyles are winged creatures of stone. You'll need to fight them to near death before breaking them apart with a Rock Hammer." [.ghouls] +npc = "ghoul" combat_level = 25 quest = "priest_in_peril" -tip = "Ghouls aren't undead but they are stronger and tougher than they look. However they're also very cowardly and will run if they're losing a fight." [.goblin] -tip = "Goblins are mostly just annoying, but they can be vicious. Watch out for the spears they sometimes carry." +npc = "goblin_mohawk_blue" [.gorak] -tip = "Goraks are extremely aggressive creatures. They have been imprisoned on an alternative plane, which is only accesible by using the fairyrings. Be extremely careful, their touch drains health as well as skills! " +npc = "gorak" [.greater_demons] -tip = "Demons are particularly weak to water spells. Though Greater Demons are not the strongest type of demon they are still dangerous." +npc = "greater_demon" [.green_dragons] -tip = "Like all dragons, Green Dragons have thick scales and a powerful fiery breath. Unless you can stay out of their reach, bringing dragonfire protection is a must." +npc = "green_dragon" [.hellhounds] -tip = "Hellhounds are a cross between Dogs and Demons. They are dangerous with a fierce bite, but have all of the same weaknesses as most demons." +npc = "hellhound" [.hill_giants] +npc = "hill_giant" combat_level = 25 -tip = "Hill Giants often wield large weapons, learn to recognise what kind of weapon it is and act accordingly." [.hobgoblins] +npc = "hobgoblin_unarmed" combat_level = 20 -tip = "Hobgoblins carrying spears are often trained warriors. If you want less of a challenge, fight the ones that are unarmed." [.harpie_bug_swarms] -tip = "Harpie Bug Swarms are pesky critters that are hard to hit. You need a lit bug lantern to distract them with its hypnotic light." +npc = "harpie_bug_swarm" [.infernal_mage] -tip = "Infernal Mages are dangerous spell users, beware of their magic spells and go properly prepared." +npc = "infernal_mage" [.ice_giant] -tip = "Like other giants, Ice Giants have little to no magical ability, and they're particularly weak to fire spells." +npc = "ice_giant" [.ice_warriors] +npc = "ice_warrior" combat_level = 45 -tip = "Ice Warriors are a kind of ice elemental, shatter them with blunt weapons or melt them with fire." [.icefiends] +npc = "icefiend" combat_level = 20 -tip = "Icefiends are beings of ice and freezing rock, they're quick and agile so you'll want to be careful when getting close to them." [.iron_dragons] -tip = "Iron Dragons are some of the weaker metallic dragons, their iron scales are far thicker than normal iron armour." +npc = "iron_dragon" [.jellies] -tip = "Jellies are nasty cube-like gelatinous creatures which absorb everything they come across into themselves. Their magical acids bypass physical defences." +npc = "jelly" [.jungle_horrors] -tip = "Jungle Horrors can be found all over Mos Le'Harmless. They are strong and aggressive, so watch out!" +npc = "jungle_horror" [.kalphites] +npc = "kalphite_worker" combat_level = 15 -tip = "Kalphite are large insects which live in great hives under the desert sands." [.killerwatts] +npc = "killerwatt" combat_level = 50 quest = "ernest_the_chicken" -tip = "Killerwatts store huge amounts of energy in their bodies, which is released if they are touched. You'll need to wear heavily insulated boots to counter this shocking effect." [.kurask] -tip = "Kurask are large brutal creatures with very thick hides. You'll need a Leaf-Tipped Spear or Battle-axe, Broad Arrows, or a Magic Dart to harm it." +npc = "kurask" [.lesser_demons] -tip = "Demons are weak to magical attacks. Though Lesser Demons are relatively weak they are still dangerous." +npc = "lesser_demon" [.lizards] +npc = "lizard" combat_level = 20 -tip = "Lizards are large reptiles with tough skin. Those found in the desert will need you to douse them with freezing water to finish them off after a tough battle." [.magic_axe] -tip = "Magic Axes have a mind of their own. You may find magic or slash-based melee attacks are slightly more effective against them." +npc = "magic_axe" [.mogres] +npc = "mogre" combat_level = 30 quest = "skippy_and_the_mogres" -tip = "Mogres are a type of aquatic Ogre that is often mistaken for a giant mudskipper. You have to force them out of the water with a fishing explosive." [.mutated_zygomites] -tip = "Mutated Zygomites are hard to destroy. They regenerate quickly so you will need to finish them with fungicide." +npc = "zygomite" [.minotaurs] +npc = "minotaur" combat_level = 7 -tip = "Minotaurs are large manlike creatures but you'll want to be careful of their horns." [.mithril_dragons] +npc = "mithril_dragon" +# TODO barbarian training varbit combat_level = 100 -tip = "Mithril dragons are more vulnerable to magic and to stab-based melee attacks than to anything else." [.monkeys] -tip = "Monkeys are tricky creatures, they are agile and fairly fast. Learn to anticipate their movements." +npc = "monkey_brown" [.moss_giants] -tip = "Like other giants, Moss Giants have little to no magical ability, and they're particularly weak to fire spells." +npc = "moss_giant" [.nechryael] +npc = "nechryael" quest = "what_lies_below" -tip = "Nechryael are demons of decay which summon small winged beings to help them fight their victims. Their minions can bypass protective prayers so be sure to wear thick armour." [.ogres] -tip = "Ogres are brutal creatures, favouring large blunt maces and clubs, they often attack without warning." +npc = "ogre_chieftain" [.otherworldly_beings] -tip = "Otherworldly Beings are ethereal beings making them weak to magical attack." +npc = "otherworldly_being" [.pirates] -tip = "Pirates can be found near the sea. They like to collect coins among other things." +npc = "pirate_pirates_cove" [.pyrefiends] +npc = "pyrefiend_large" combat_level = 25 -tip = "Pyrefiends are beings of fire and molten rock, they're quick and agile but weak to water spells." [.rats] -tip = "Rats are your everyday pest, but they can get fairly big. Watch out for their sharp piercing teeth." +npc = "rat" [.red_dragons] -tip = "Red Dragons are very powerful, stronger than most dragons, watch out for their fiery breath." +npc = "red_dragon" [.rogues] -tip = "Rogues are found in lawless areas, such as the deep Wilderness. They can be very protective of their loot." +npc = "rogue_castle" [.rockslugs] +npc = "rockslug" combat_level = 20 -tip = "Rockslugs are strange stoney slugs. You'll need to fight them to near death before finishing them off with Salt." [.scabarites] +npc = "giant_scarab_normal" quest = "dealing_with-scabaras" -tip = "Scabarites are insectoid creatures, found beyond the Kharidian deserts. Make sure not to fall into one of their pitfall traps or you'll be quickly overwhelmed." [.scorpions] +npc = "scorpion" combat_level = 10 -tip = "Scorpions are almost always poisonous, their hard carapace makes them resistant to crushing and stabbing attacks." [.sea_snakes] -tip = "Sea Snakes are long and slithery with a venomous bite. The larger ones are more poisonous, so keep an eye on your health." +npc = "sea_snake_young" [.skeletal_wyverns] +npc = "skeletal_wyvern" combat_level = 100 quest = "elemental_workshop_i" -tip = "Skeletal Wyverns are extremely dangerous and they are hard to hit with arrows as they slip right through. To stand a good chance of surviving you'll need some elemental shielding from its icy breath." [.shades] +npc = "asyn_shade" combat_level = 30 -tip = "Shades are undead so magic is your best bet against them. You can find Shades at Mort'ton." [.shadow_warriors] -tip = "Shadow Warriors are dark and mysterious. They wear spectral plate armour, so crush weapons and magic will give them trouble." +npc = "shadow_warrior" [.skeletons] +npc = "skeleton_heavy" combat_level = 15 -tip = "Skeletons are undead so magic is your best bet against them, there is even a spell specially for fighting the undead." [.spiritual_creatures] -tip = "Spiritual Creatures can be found in the icy caverns near Trollheim, supporting the cause of their chosen god. Wearing equipment aligned with each of the gods can help you avoid undesired conflict." +npc = "spiritual_mage_zamorak" +# TODO req god wars dungeon knight varbit [.spiders] -tip = "Spiders are often poisonous, and many varieties are camouflaged too." +npc = "spider" [.steel_dragons] -tip = "Steel Dragons are dangerous metallic dragons, their steel scales are far thicker than normal steel armour." +npc = "steel_dragon" [.suqahs] +npc = "suqah" quest = "lunar_diplomacy" -tip = "Suqahs can only be found on the mystical Lunar Isle. They are capable of melee and magic attacks and often drop hide, teeth and herbs!" [.turoth] -tip = "Turoth are large vicious creatures with thick hides. You'll need a Leaf-Tipped Spear or Sword, Broad Arrows, or a Magic Dart to harm them." +npc = "turoth" [.trolls] -tip = "Trolls regenerate damage quickly and have some level of magical defences, but this is easily bypassed by their weakness to fire." +npc = "ice_troll_troll_country" [.tzhaar] -tip = "Tzhaar reside in their cave under the Karamja volcano. Beware as they can call to their fellows for aid." +npc = "tzhaar_mej" [.vampyres] -tip = "Vampyres are extremely powerful beings. An underground group known as the Myreque have been searching for tools to defeat them, which they may be willing to share if you can find them." +npc = "vampyre_juvinate" +combat_level = 35 +quest = "priest_in_peril" [.waterfiends] +npc = "waterfiend" quest = "what_lies_below" -tip = "Waterfiends are creatures of water, which live under the Baxtorian Lake. Their watery form is well defended against slashing and piercing weapons, so use something blunt." [.werewolves] -tip = "Werewolves are feral creatures, they are strong and tough with sharp claws and teeth." +npc = "werewolf" [.wolves] +npc = "wolf" combat_level = 20 -tip = "Wolves are pack animals, so you'll always find them in groups. Watch out for their bite, it can be nasty." [.wall_beasts] +npc = "wall_beast" combat_level = 30 defence_level = 5 -tip = "Wall Beasts are really much larger creatures but you'll only see their arms. You'll want something sharp on your head to stop them grabbing you." [.warped_creatures] +npc = "warped_terrorbird" quest = "the_path_of_glouphrie" -tip = "Warped Creatures can supposedly be found within a mysterious dungeon on the eastern edge of the Poison Waste. Be aware that to defeat them, you'll need to purify them in some way." [.zombies] +npc = "zombie" combat_level = 10 -tip = "Zombies are undead so magic is your best bet against them, there is even a spell specially for fighting the undead." diff --git a/data/skill/slayer/sumona.enums.toml b/data/skill/slayer/sumona.enums.toml deleted file mode 100644 index 6228f79a30..0000000000 --- a/data/skill/slayer/sumona.enums.toml +++ /dev/null @@ -1,79 +0,0 @@ -[sumona_task_amount] -keyType = "npc" -valueType = "string" -values = { - aberrant_spectre = "120-185", - abyssal_demon = "120-185", - aquanite = "120-185", - aviansie_god_wars = "50-100", - banshee = "120-185", - basilisk = "120-185", - black_demon = "120-185", - bloodveld = "120-185", - blue_dragon = "120-185", - cave_crawler = "120-185", - cave_horror = "120-185", - crocodile_kharidian_desert = "150-250", - dagannoth_lighthouse_range_74 = "120-185", - lizard = "90-110", - desert_strykewyrm = "90-110", - dust_devil = "120-185", - elf_warrior = "60-90", - fire_giant = "120-185", - gargoyle = "120-195", - greater_demon = "120-195", - hellhound = "120-185", - iron_dragon = "30-60", - jungle_strykewyrm = "90-120", - kalphite_worker = "120-185", - kurask = "120-185", - nechryael = "120-185", - red_dragon = "30-60", - giant_scarab_normal = "80-120", - scorpion = "150-250", - spiritual_mage_zamorak = "120-185", - terror_dog = "30-60", - ice_troll_troll_country = "120-185", - turoth = "120-185", - warped_terrorbird = "120-185", -} - -[sumona_task_weight] -keyType = "npc" -valueType = "int" -values = { - aberrant_spectre = 15, - abyssal_demon = 10, - aquanite = 10, - aviansie_god_wars = 7, - banshee = 15, - basilisk = 15, - black_demon = 10, - bloodveld = 10, - blue_dragon = 5, - cave_crawler = 15, - cave_horror = 15, - crocodile_kharidian_desert = 4, - dagannoth_lighthouse_range_74 = 10, - lizard = 4, - desert_strykewyrm = 14, - dust_devil = 15, -# elf_warrior = 10, - fire_giant = 10, -# gargoyle = 10, - greater_demon = 10, - hellhound = 10, - iron_dragon = 7, - jungle_strykewyrm = 12, - kalphite_worker = 10, - kurask = 15, - nechryael = 10, - red_dragon = 5, -# giant_scarab_normal = 5, - scorpion = 4, - spiritual_mage_zamorak = 10, -# terror_dog = 10, - ice_troll_troll_country = 10, - turoth = 15, -# warped_terrorbird = 10, -} diff --git a/data/skill/slayer/turael.enums.toml b/data/skill/slayer/turael.enums.toml deleted file mode 100644 index c00be636dd..0000000000 --- a/data/skill/slayer/turael.enums.toml +++ /dev/null @@ -1,59 +0,0 @@ -[turael_task_amount] -keyType = "npc" -valueType = "string" -values = { - rat = "15-30", - cave_bug = "10-30", - ghost = "15-30", - spider = "15-30", - skeleton_heavy = "15-30", - kalphite_worker = "15-30", - lizard = "15-30", - guard_dog = "15-30", - icefiend = "15-20", - zombie = "15-30", - bird_black = "15-30", - scorpion = "15-30", - monkey_brown = "15-30", - cow_default = "15-30", - bat = "15-30", - dwarf = "10-25", - cave_crawler = "15-30", - black_bear = "10-20", - wolf = "15-30", - cave_slime = "10-20", - crawling_hand = "15-30", - goblin_mohawk_blue = "15-30", - banshee = "15-30", - minotaur = "10-20", -} - -[turael_task_weight] -keyType = "npc" -valueType = "int" -values = { - rat = 7, - cave_bug = 8, - ghost = 7, - spider = 6, - skeleton_heavy = 7, - kalphite_worker = 6, - lizard = 8, - guard_dog = 7, - icefiend = 8, - zombie = 7, - bird_black = 6, - scorpion = 7, - monkey_brown = 6, - cow_default = 8, - bat = 7, - dwarf = 7, - cave_crawler = 8, - black_bear = 7, - wolf = 7, - cave_slime = 8, - crawling_hand = 8, - goblin_mohawk_blue = 7, - banshee = 8, - minotaur = 7, -} diff --git a/data/skill/slayer/vannaka.enums.toml b/data/skill/slayer/vannaka.enums.toml deleted file mode 100644 index d5787e0dbf..0000000000 --- a/data/skill/slayer/vannaka.enums.toml +++ /dev/null @@ -1,97 +0,0 @@ -[vannaka_task_amount] -keyType = "npc" -valueType = "string" -values = { - aberrant_spectre = "40-90", - abyssal_demon = "40-90", - ankou = "25-35", - basilisk = "40-90", - bloodveld = "40-90", - black_dragon = "40-90", - brine_rat = "40-90", - cockatrice = "40-90", - rock_crab = "40-90", - crocodile_kharidian_desert = "40-90", - dagannoth_lighthouse_range_74 = "40-90", - dust_devil = "40-90", - elf_warrior = "30-70", - fever_spider = "30-90", - fire_giant = "40-90", - gargoyle = "40-90", - ghoul = "10-40", - harpie_bug_swarm = "40-90", - hellhound = "30-60", - hill_giant = "40-90", - hobgoblin_unarmed = "40-90", - ice_giant = "30-80", - ice_warrior = "40-90", - infernal_mage = "40-90", - jelly = "40-90", - jungle_horror = "40-90", - kalphite_worker = "40-90", - kurask = "40-90", - lesser_demon = "40-90", - mogre = "40-90", - moss_giant = "40-90", - nechryael = "40-90", - ogre_chieftain = "40-90", - otherworldly_being = "40-90", - pyrefiend_large = "40-90", - sea_snake_young = "40-90", - asyn_shade = "40-90", - shadow_warrior = "30-80", - spiritual_mage_zamorak = "40-90", - ice_troll_troll_country = "40-90", - turoth = "30-90", - vampyre_juvinate = "10-20", - werewolf = "30-60", -} - -[vannaka_task_weight] -keyType = "npc" -valueType = "int" -values = { - aberrant_spectre = 8, - abyssal_demon = 5, - ankou = 8, - basilisk = 8, - bloodveld = 8, - black_dragon = 7, - brine_rat = 7, - cockatrice = 8, - rock_crab = 7, - crocodile_kharidian_desert = 6, - dagannoth_lighthouse_range_74 = 7, - dust_devil = 8, -# elf_warrior = 7, -# fever_spider = 7, - fire_giant = 7, - gargoyle = 5, -# ghoul = 7, -# harpie_bug_swarm = 8, - hellhound = 7, - hill_giant = 7, - hobgoblin_unarmed = 7, - ice_giant = 7, - ice_warrior = 7, - infernal_mage = 8, - jelly = 8, - jungle_horror = 8, - kalphite_worker = 7, - kurask = 7, - lesser_demon = 7, -# mogre = 7, - moss_giant = 7, - nechryael = 5, - ogre_chieftain = 7, - otherworldly_being = 8, - pyrefiend_large = 8, -# sea_snake_young = 6, -# asyn_shade = 8, - shadow_warrior = 8, - spiritual_mage_zamorak = 8, - ice_troll_troll_country = 7, - turoth = 8, -# vampyre_juvinate = 7, - werewolf = 7, -} diff --git a/game/src/main/kotlin/content/skill/slayer/EnchantedGem.kt b/game/src/main/kotlin/content/skill/slayer/EnchantedGem.kt index 5e1e450b15..d93052283f 100644 --- a/game/src/main/kotlin/content/skill/slayer/EnchantedGem.kt +++ b/game/src/main/kotlin/content/skill/slayer/EnchantedGem.kt @@ -11,6 +11,7 @@ import net.pearx.kasechange.toSentenceCase import world.gregs.voidps.engine.Script import world.gregs.voidps.engine.client.message import world.gregs.voidps.engine.data.definition.EnumDefinitions +import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.character.player.name import world.gregs.voidps.engine.queue.queue @@ -95,14 +96,7 @@ class EnchantedGem : Script { fun ChoiceOption.anyTips() { option("Got any tips for me?") { - var npc = -1 - for ((key, value) in EnumDefinitions.get("${slayerMaster}_tasks").map ?: return@option) { - if (value == slayerTask) { - npc = key - break - } - } - val tip = EnumDefinitions.stringOrNull("slayer_task_tips", npc) ?: return@option + val tip = Tables.stringOrNull("${slayerMaster}_slayer_tasks.${slayerTask}.tip") ?: return@option npc(slayerMaster, tip) choice { howAmIDoing() diff --git a/game/src/main/kotlin/content/skill/slayer/Slayer.kt b/game/src/main/kotlin/content/skill/slayer/Slayer.kt index ba408c193d..e09eb8c961 100644 --- a/game/src/main/kotlin/content/skill/slayer/Slayer.kt +++ b/game/src/main/kotlin/content/skill/slayer/Slayer.kt @@ -3,12 +3,15 @@ package content.skill.slayer import content.quest.questCompleted import world.gregs.voidps.engine.data.config.TableDefinition import world.gregs.voidps.engine.data.definition.ColumnType +import world.gregs.voidps.engine.data.definition.NPCDefinitions import world.gregs.voidps.engine.data.definition.Rows import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.character.Character import world.gregs.voidps.engine.entity.character.npc.NPC import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.combatLevel +import world.gregs.voidps.engine.entity.character.player.skill.Skill +import world.gregs.voidps.engine.entity.character.player.skill.level.Level.has import world.gregs.voidps.type.random // shade, zombie, skeleton, ghost, zogre, ankou @@ -99,18 +102,20 @@ private fun rollTask(player: Player, master: String): Pair? { } private fun hasRequirements(player: Player, table: TableDefinition, row: Int): Boolean { -// val slayerLevel = NPCDefinitions.get(index)["slayer_level", 1] // FIXME -// if (!player.has(Skill.Slayer, slayerLevel)) { -// return false -// } - val combatLevel = table.int("combat_level", row) + val category = Rows.get(row).stringId + val npc = Tables.int("slayer_tasks.${category}.npc") + val slayerLevel = NPCDefinitions.get(npc)["slayer_level", 1] + if (!player.has(Skill.Slayer, slayerLevel)) { + return false + } + val combatLevel = Tables.int("slayer_tasks.${category}.combat_level") if (player.combatLevel < combatLevel) { return false } - val variable = table.stringOrNull("variable", row) + val variable = Tables.stringOrNull("slayer_tasks.${category}.variable") if (variable != null && !player.contains(variable)) { return false } - val quest = table.stringOrNull("quest", row) ?: return true + val quest = table.stringOrNull("slayer_tasks.${category}.quest", row) ?: return true return player.questCompleted(quest) } From 6af7934b388140abbd4cd530faf80dbada030bc8 Mon Sep 17 00:00:00 2001 From: GregHib Date: Wed, 25 Mar 2026 12:04:51 +0000 Subject: [PATCH 07/40] Add slayer master specific tips --- data/skill/slayer/chaeldar.tables.toml | 44 +++++++++--------- data/skill/slayer/duradel.tables.toml | 52 ++++++++++----------- data/skill/slayer/kuradal.tables.toml | 56 +++++++++++----------- data/skill/slayer/mazchna.tables.toml | 22 ++++----- data/skill/slayer/sumona.tables.toml | 64 +++++++++++++------------- data/skill/slayer/turael.tables.toml | 8 ++-- data/skill/slayer/vannaka.tables.toml | 14 +++--- 7 files changed, 130 insertions(+), 130 deletions(-) diff --git a/data/skill/slayer/chaeldar.tables.toml b/data/skill/slayer/chaeldar.tables.toml index d76d1bd9d9..3bdc4a5c58 100644 --- a/data/skill/slayer/chaeldar.tables.toml +++ b/data/skill/slayer/chaeldar.tables.toml @@ -6,7 +6,7 @@ tip = "string" [.aberrant_spectre] amount = [70, 130] weight = 8 -tip = "Aberrant Spectres are fetid, vile ghosts. The very smell of them will paralyse and harm you. A nosepeg will help ignore their stink." +tip = "Aberrant spectres are fetid, vile ghosts. The very smell of them will paralyse and harm you. A nosepeg will help negate their stink and their attacks are most definitely magical in nature. You'll be able to make the world more fragrant if you kill the ones lurking in the Slayer Tower near Canifis." [.abyssal_demon] amount = [70, 130] @@ -21,17 +21,17 @@ tip = "Aviansies are bird-like creatures found in the icy dungeons of the north. [.basilisks] amount = [70, 130] weight = 7 -tip = "Basilisks, like Cockatrice, have a gaze which will paralyse and harm their prey. You'll need a Mirror Shield to protect you." +tip = "Basilisks, like cockatrices, have a gaze that will paralyse and harm their prey. You'll need a mirror shield to protect you. I am sure you know that there is a Basilisk colony in the Rellekka Slayer Caves." [.bloodvelds] amount = [70, 130] weight = 8 -tip = "Bloodveld are strange demonic creatures, their long rasping tongue has magical properties so it pierces straight through physical defences." +tip = "Bloodveld are strange, demonic creatures. They use their long, rasping tongue to feed on just about anything they can find. Their tongue assaults physically, so using magic attacks might be the best choice. If you can stand being licked by a half-ton demon, you should take a trip to the Slayer Tower near Canifis." [.brine_rats] amount = [70, 130] weight = 7 -tip = "Brine Rats can be found in caves that are near the sea. They are hairless, bad-tempered and generally unfriendly." +tip = "Brine rats can be found in caves that are near the sea. They are hairless, bad-tempered and generally unfriendly. You may have spotted them while looking for pirate treasures." [.black_demons] amount = [70, 130] @@ -41,12 +41,12 @@ tip = "Powerful weapons known as demonbane weapons can be used to quickly defeat [.blue_dragons] amount = [70, 130] weight = 8 -tip = "Like all dragons, Blue Dragons have thick scales and a powerful fiery breath. Stabbing weapons and heavy bolts are best suited to piercing their defences." +tip = "Blue dragons aren't as strong as other dragons, but they're still very powerful. Watch out for their fiery breath. Taverley Dungeon has a clutch of these creatures, which it can be profitable to slay." [.cave_horrors] amount = [70, 130] weight = 10 -tip = "Cave Horrors can be found under Mos Le'Harmless. You will need a Witchwood Icon to fight them effectively." +tip = "Cave horrors can be found in the caves under Mos Le'Harmless which favour the use of missiles or Magic. You will need a witchwood icon to fight them effectively. They drop the famous black Slayer mask, so the trip may be worth it." [.crabs] amount = [70, 130] @@ -56,32 +56,32 @@ tip = "Crabs can be found all across Gielinor. They don't hit very hard but they [.dust_devils] amount = [70, 130] weight = 9 -tip = "Dust Devils use clouds of dust, sand, ash, and whatever else they can inhale to blind and disorientate their victims. Make sure to wear a facemask when fighting them." +tip = "Dust devils use clouds of dust, sand, ash and whatever else they can inhale to blind and disorientate their victims. They typically lurk in the smoky dungeon west of Pollnivneach." [.dagannoth] amount = [70, 130] weight = 11 -tip = "Dagannoth are large sea dwelling creatures which are very aggressive. You'll often find them in caves near sea water." +tip = "Dagannoth are large, sea-dwelling creatures that are very aggressive. You'll often find them in caves near sea water. I can tell that you've seen the vile creatures, so you know where to go. Remember: they attack with missiles, so protect yourself accordingly." #[.elves] #amount = [70, 130] #weight = 8 -#tip = "Elves are quick, agile, and vicious fighters which often favour bows and polearms." +#tip = "Elves are quick, agile, and vicious fighters who often favour bows and polearms. They also irritate me intensely, so slaughtering them is definitely a good thing. They live in the forests far, far to the west of human lands." [.fire_giant] amount = [70, 130] weight = 12 -tip = "Like other giants, Fire Giants have little to no magical ability, and they're particularly weak to water spells." +tip = "Like other giants, Fire giants often wield large weapons. Learn to recognise what kind of weapon it is and act accordingly. The smoke dungeon to the west of Pollnivneach has a population of these large and irritating creatures, so go smite them." #[.fever_spiders] #amount = [70, 130] #weight = 7 -#tip = "Fever Spiders are giant spiders that carry the deadly Spider Fever. If you don't want to catch it I suggest you wear Slayer Gloves to fight them." +#tip = "Fever spiders are giant spiders that carry the deadly spider fever. If you don't want to catch it, I suggest you wear Slayer gloves to fight them. I've heard they cause problems in breweries, if you want to find some." [.gargoyles] amount = [70, 130] weight = 11 -tip = "Gargoyles are winged creatures of stone. You'll need to fight them to near death before breaking them apart with a Rock Hammer." +tip = "Gargoyles are winged creatures of stone. You'll need to fight them until they are close to death before breaking them apart with a rock hammer. There is a thriving population of Gargoyles in the Slayer Tower near Canifis." [.greater_demons] amount = [70, 130] @@ -96,32 +96,32 @@ tip = "Hellhounds are a cross between Dogs and Demons. They are dangerous with a [.jellies] amount = [70, 130] weight = 10 -tip = "Jellies are nasty cube-like gelatinous creatures which absorb everything they come across into themselves. Their magical acids bypass physical defences." +tip = "Jellies are nasty, cube-like, gelatinous creatures which absorb everything they come across. Rellekka's caves are known to harbour these unnatural abominations. You can consider their attacks to be a form of Ranged and protect yourself with this in mind." [.jungle_horrors] amount = [70, 130] weight = 10 -tip = "Jungle Horrors can be found all over Mos Le'Harmless. They are strong and aggressive, so watch out!" +tip = "Jungle horrors can be found all over Mos Le'Harmless. They are strong and aggressive, but you should be heroic enough to make short work of them." [.kalphites] amount = [70, 130] weight = 11 -tip = "Kalphite are large insects which live in great hives under the desert sands." +tip = "Kalphites are large insects that live in hives under the desert sands. South-west of Shantay Pass they swarm and make themselves a nuisance. Enter deeper into the lair if you are looking for a suitable challenge." [.kurask] amount = [70, 130] weight = 12 -tip = "Kurask are large brutal creatures with very thick hides. You'll need a Leaf-Tipped Spear or Battle-axe, Broad Arrows, or a Magic Dart to harm it." +tip = "Kurasks are large, brutal creatures with very thick hides. You'll need a leaf-bladed weapon, broad arrows or a magic dart to harm them. Kurask may be found in the caverns east of Rellekka. As they are so large, you may be able to kill them when they cannot reach you." [.lesser_demons] amount = [70, 130] weight = 9 -tip = "Demons are weak to magical attacks. Though Lesser Demons are relatively weak they are still dangerous." +tip = "Lesser demons are weak to ranged attacks. Although they're relatively weak, they are still dangerous. Taverley's underworld is infested with these hellish pests." [.mutated_zygomites] amount = [8, 15] weight = 7 -tip = "Mutated Zygomites are hard to destroy. They regenerate quickly so you will need to finish them with fungicide." +tip = "Mutated zygomites are hard to destroy and attack with mainly magical damage. They regenerate quickly, so you will need to finish them off with fungicide. We have a bit of a problem with them here in Zanaris." [.nechryael] amount = [70, 130] @@ -136,7 +136,7 @@ tip = "Skeletal Wyverns are extremely dangerous and they are hard to hit with ar [.shadow_warriors] amount = [70, 130] weight = 8 -tip = "Shadow Warriors are dark and mysterious. They wear spectral plate armour, so crush weapons and magic will give them trouble." +tip = "Shadow warriors are dark and mysterious. They hide in the shadows, so be wary of ambushes. Apparently, a large number may be found lurking beneath the Legends' Guild." [.spiritual_creatures] amount = [70, 130] @@ -146,12 +146,12 @@ tip = "Spiritual Creatures can be found in the icy caverns near Trollheim, suppo [.turoth] amount = [70, 130] weight = 10 -tip = "Turoth are large vicious creatures with thick hides. You'll need a Leaf-Tipped Spear or Sword, Broad Arrows, or a Magic Dart to harm them." +tip = "Turoths are large, vicious creatures with thick hides. You'll need a leaf-bladed weapon, broad arrows, or a magic dart to harm them. Seek them out in the Rellekka Slayer Caves." [.trolls] amount = [70, 130] weight = 11 -tip = "Trolls regenerate damage quickly and have some level of magical defences, but this is easily bypassed by their weakness to fire." +tip = "Trolls regenerate quickly but are still vulnerable to poisons. They usually use crushing weapons. Perhaps you should head to the snowy islands where these creatures are both fierce and aggressive." [.tzhaar] amount = [90, 150] @@ -166,4 +166,4 @@ tip = "Tzhaar reside in their cave under the Karamja volcano. Beware as they can #[.warped_creatures] #amount = [70, 130] #weight = 6 -#tip = "Warped Creatures can supposedly be found within a mysterious dungeon on the eastern edge of the Poison Waste. Be aware that to defeat them, you'll need to purify them in some way." +#tip = "Warped tortoises are creatures tainted by magical waste. They are vulnerable to an elven chime." diff --git a/data/skill/slayer/duradel.tables.toml b/data/skill/slayer/duradel.tables.toml index f44a9800bf..594cc9d363 100644 --- a/data/skill/slayer/duradel.tables.toml +++ b/data/skill/slayer/duradel.tables.toml @@ -6,129 +6,129 @@ tip = "string" [.aberrant_spectre] amount = [130, 200] weight = 10 -tip = "Aberrant Spectres are fetid, vile ghosts. The very smell of them will paralyse and harm you. A nosepeg will help ignore their stink." +tip = "Aberrant spectres are fetid, vile ghosts. The very smell of them will paralyse and harm you. A nosepeg will help ignore their stink and weak slayers might decide to pray when fighting them. They can be found in the Slayer Tower near Canifis and I have heard rumours that they also live beneath Pollnivneach in the desert." [.abyssal_demon] amount = [130, 200] weight = 15 -tip = "Abyssal Demons are nasty creatures to fight. They aren't really part of this realm, and are able to move very quickly to trap their prey." +tip = "Abyssal demons are nasty creatures to deal with. They aren't really part of this realm and are able to move very quickly to trap their prey. The Slayer Tower is home to a number of these creatures." [.aquanites] amount = [130, 200] weight = 9 -tip = "Aquanites rely on their lures for both offensive and defensive purposes. Whilst their hides are resistant to slashing attacks, a well timed cut is capable of severing the lure." +tip = "Aquanites are amphibious creatures that attract prey using the glowing lures on their heads. They attack stronger opponents from a distance with water magic, and dislike those who pray against it. They dwell in the Fremennik Slayer Dungeon, in a chamber past the kurasks." [.aviansies] amount = [100, 125] weight = 8 -tip = "Aviansies are bird-like creatures found in the icy dungeons of the north. Melee weapons can't reach them, so use Magic or Ranged attacks." +tip = "Aviansies can be found in the Godwars Dungeon north of Trollheim. As they are flying, you'll find melee attacks are not going to cut it." [.bloodvelds] amount = [130, 200] weight = 10 -tip = "Bloodveld are strange demonic creatures, their long rasping tongue has magical properties so it pierces straight through physical defences." +tip = "Bloodveld are strange, demonic creatures. They use their long, rasping tongue to feed on just about anything they can find. Remember that their tongues are magical in nature but, moreso, they deserve to die." [.black_demons] amount = [130, 200] weight = 10 -tip = "Powerful weapons known as demonbane weapons can be used to quickly defeat even powerful demons like the Black Demon with greater ease." +tip = "Black demons are weak to ranged attacks. They're still the strongest demon and very dangerous, however. Seek them out in the Edgeville or Brimhaven dungeons." [.black_dragons] amount = [40, 80] weight = 9 -tip = "Black Dragons are the strongest dragons and very fierce, watch out for their fiery breath." +tip = "Black dragons are among the strongest dragons and are very fierce. Watch out for their fiery breath. I am sure you will have seen them in your travels and have honed your techniques on lesser dragons." [.dark_beasts] amount = [130, 200] weight = 15 -tip = "Dark Beasts are large, dog-like predators. Their massively muscled bodies protect them from crushing weapons." +tip = "Dark beasts are large, dog-like predators with massively muscled bodies that protect them from crushing weapons. You'll find them near the Temple of Light, attracted to the power of the Death Altar." [.dust_devils] amount = [130, 200] weight = 10 -tip = "Dust Devils use clouds of dust, sand, ash, and whatever else they can inhale to blind and disorientate their victims. Make sure to wear a facemask when fighting them." +tip = "Dust devils use clouds of dust, sand, ash and whatever else they can inhale to blind and disorientate their victims. Good luck on obtaining a dragon chainmail from their dusty remains." [.dagannoth] amount = [130, 200] weight = 10 -tip = "Dagannoth are large sea dwelling creatures which are very aggressive. You'll often find them in caves near sea water." +tip = "Dagannoth are large, sea-dwelling creatures that are very aggressive. You'll often find them in caves near sea water. There is no joy so great as to cleanse these from the face of Gielinor." [.fire_giant] amount = [130, 200] weight = 10 -tip = "Like other giants, Fire Giants have little to no magical ability, and they're particularly weak to water spells." +tip = "Like other giants, Fire giants often wield large weapons. Learn to recognise what kind of weapon it is and act accordingly. Remember the days when these were a challenge to you, and laugh." [.gargoyles] amount = [130, 200] weight = 10 -tip = "Gargoyles are winged creatures of stone. You'll need to fight them to near death before breaking them apart with a Rock Hammer." +tip = "Gargoyles are winged creatures of stone. You'll need to fight them until they are close to death before breaking them apart with a rock hammer. Exterminate those in the Slayer Tower." [.gorak] amount = [40, 80] weight = 5 -tip = "Goraks are extremely aggressive creatures. They have been imprisoned on an alternative plane, which is only accesible by using the fairyrings. Be extremely careful, their touch drains health as well as skills! " +tip = "Goraks are extremely aggressive creatures. They have been imprisoned on an alternate plane, which is only accessible by using the fairy rings. Be extremely careful: their touch drains life points as well as skills!" [.greater_demons] amount = [130, 200] weight = 10 -tip = "Demons are particularly weak to water spells. Though Greater Demons are not the strongest type of demon they are still dangerous." +tip = "Greater demons are weak to ranged attacks. Though not the strongest of the demons, they are still dangerous. Slaughter them easily in Brimhaven's depths, and revel in your power." [.hellhounds] amount = [130, 200] weight = 9 -tip = "Hellhounds are a cross between Dogs and Demons. They are dangerous with a fierce bite, but have all of the same weaknesses as most demons." +tip = "Hellhounds are a cross between dogs and demons; they are also dangerous with a fierce bite. Make them know fear." [.iron_dragons] amount = [40, 80] weight = 9 -tip = "Iron Dragons are some of the weaker metallic dragons, their iron scales are far thicker than normal iron armour." +tip = "Iron dragons are some of the weaker metallic dragons; their iron scales are far thicker than normal iron armour. Their fiery breath and sharp claws can be negated by a number of means. If you haven't visited Brimhaven Dungeon's depths then I advise you do - if only for the interesting creatures like these to kill there." [.kalphites] amount = [130, 200] weight = 10 -tip = "Kalphite are large insects which live in great hives under the desert sands." +tip = "Kalphites are large insects that live in hives under the desert sands. I am sure that, by now, you have seen them to the south-west of Shantay Pass." [.mithril_dragons] amount = [4, 8] weight = 7 -tip = "Mithril dragons are more vulnerable to magic and to stab-based melee attacks than to anything else." +tip = "Mithril dragons are very dangerous opponents. They live beneath the Baxtorian Falls and devour most of those who seek to slay them. You are a battlemaster; test your skills." [.nechryael] amount = [130, 200] weight = 10 -tip = "Nechryael are demons of decay which summon small winged beings to help them fight their victims. Their minions can bypass protective prayers so be sure to wear thick armour." +tip = "Nechryael are demons of decay that summon small winged beings to help them fight their victims. They can be found in the Slayer Tower near Canifis." #[.scabarites] #amount = [40, 80] #weight = 10 -#tip = "Scabarites are insectoid creatures, found beyond the Kharidian deserts. Make sure not to fall into one of their pitfall traps or you'll be quickly overwhelmed." +#tip = "Scabarites are the followers of Scabaras and consist of anything from the lowliest dung beetle to the mightiest scarab mage. They are most commonly found near Sophanem, and under it." [.skeletal_wyverns] amount = [40, 80] weight = 5 -tip = "Skeletal Wyverns are extremely dangerous and they are hard to hit with arrows as they slip right through. To stand a good chance of surviving you'll need some elemental shielding from its icy breath." +tip = "Skeletal wyverns are extremely dangerous and they are hard to hit with arrows, as they slip right through. To stand a good chance of surviving, you'll need some elemental shielding from their icy breath." [.spiritual_creatures] amount = [120, 185] weight = 10 -tip = "Spiritual Creatures can be found in the icy caverns near Trollheim, supporting the cause of their chosen god. Wearing equipment aligned with each of the gods can help you avoid undesired conflict." +tip = "Spiritual mages are the strongest of the spiritual guardians. They are devastating against warriors, but a smart ranger can sometimes defeat them. Of course, Prayer might serve you well, too. They can be found in the icy caverns near Trollheim, supporting the cause of their chosen god." [.steel_dragons] amount = [40, 80] weight = 7 -tip = "Steel Dragons are dangerous metallic dragons, their steel scales are far thicker than normal steel armour." +tip = "Steel dragons are dangerous and metallic, with steel scales that are far thicker than normal steel armour. As you are an accomplished slayer, I am sure you'll be able to deal with them easily." [.suqahs] amount = [40, 80] weight = 5 -tip = "Suqahs can only be found on the mystical Lunar Isle. They are capable of melee and magic attacks and often drop hide, teeth and herbs!" +tip = "Suqahs can only be found on the mystical Lunar Isle. They use melee and magical attacks, and they often drop hide, teeth and herbs." [.waterfiends] amount = [130, 200] weight = 10 -tip = "Waterfiends are creatures of water, which live under the Baxtorian Lake. Their watery form is well defended against slashing and piercing weapons, so use something blunt." +tip = "Waterfiends are creatures of water that live under the Baxtorian Lake. Those followed by familiars are keen to slay these elemental forces." #[.warped_creatures] #amount = [130, 200] #weight = 9 -#tip = "Warped Creatures can supposedly be found within a mysterious dungeon on the eastern edge of the Poison Waste. Be aware that to defeat them, you'll need to purify them in some way." +#tip = "Warped terrorbirds are creatures tainted by magical waste and are vulnerable to an elven chime and may only be damaged when a chime has been used; look carefully to work out which. Their sonic attack is a Ranged attack but may be affected by ear defences." diff --git a/data/skill/slayer/kuradal.tables.toml b/data/skill/slayer/kuradal.tables.toml index 19df0be408..6dd1f280cd 100644 --- a/data/skill/slayer/kuradal.tables.toml +++ b/data/skill/slayer/kuradal.tables.toml @@ -6,107 +6,107 @@ tip = "string" [.aberrant_spectre] amount = [150, 250] weight = 10 -tip = "Aberrant Spectres are fetid, vile ghosts. The very smell of them will paralyse and harm you. A nosepeg will help ignore their stink." +tip = "Aberrant spectres are fetid, vile ghosts. The very smell of them will paralyse and harm you. A nosepeg will help ignore their stink when fighting them. They can be found in the Slayer Tower near Canifis and I have heard rumours that they also live beneath Pollnivneach in the desert." [.abyssal_demon] amount = [150, 250] weight = 10 -tip = "Abyssal Demons are nasty creatures to fight. They aren't really part of this realm, and are able to move very quickly to trap their prey." +tip = "Abyssal demons are nasty creatures to deal with. They aren't really part of this realm and are able to move very quickly to trap their prey. I've managed to trap a few in the dungeon I'm guarding." [.aquanites] amount = [160, 200] weight = 10 -tip = "Aquanites rely on their lures for both offensive and defensive purposes. Whilst their hides are resistant to slashing attacks, a well timed cut is capable of severing the lure." +tip = "Aquanites are amphibious creatures that attract prey using the glowing lures on their heads. They attack stronger opponents from a distance with water magic, and dislike those who pray against it. They dwell in the Fremennik Slayer Dungeon, in a chamber past the kurasks." [.aviansies] amount = [125, 150] weight = 9 -tip = "Aviansies are bird-like creatures found in the icy dungeons of the north. Melee weapons can't reach them, so use Magic or Ranged attacks." +tip = "Aviansies can be found in the Godwars Dungeon north of Trollheim. As they are flying, you'll find melee attacks are not going to cut it." [.bloodvelds] amount = [180, 250] weight = 10 -tip = "Bloodveld are strange demonic creatures, their long rasping tongue has magical properties so it pierces straight through physical defences." +tip = "Bloodvelds are strange, demonic creatures. They use their long, rasping tongue to feed on just about anything they can find. Remember that their tongues are magical in nature, but, more so, they deserve to die." [.black_demons] amount = [190, 250] weight = 10 -tip = "Powerful weapons known as demonbane weapons can be used to quickly defeat even powerful demons like the Black Demon with greater ease." +tip = "Black demons are weak to ranged attacks. They're still the strongest demon and very dangerous, however. Seek them out in the Edgeville or Brimhaven dungeons." [.black_dragons] amount = [40, 90] weight = 5 -tip = "Black Dragons are the strongest dragons and very fierce, watch out for their fiery breath." +tip = "Black dragons are among the strongest dragons and are very fierce. Watch out for their fiery breath. I am sure you will have seen them in your travels and have honed your techniques on lesser dragons." [.blue_dragons] amount = [120, 200] weight = 7 -tip = "Like all dragons, Blue Dragons have thick scales and a powerful fiery breath. Stabbing weapons and heavy bolts are best suited to piercing their defences." +tip = "Blue dragons aren't as strong as other dragons, but they're still very powerful. I've managed to trap a few in the dungeon I'm guarding." [.dark_beasts] amount = [150, 250] weight = 12 -tip = "Dark Beasts are large, dog-like predators. Their massively muscled bodies protect them from crushing weapons." +tip = "The last Dark beast I killed I found a crossbow with bolts took them down effectively.
Dark beasts are large, dog-like predators with massively muscled bodies that protect them from crushing weapons. I've managed to trap a few in the dungeon I'm guarding." [.dust_devils] amount = [150, 250] weight = 10 -tip = "Dust Devils use clouds of dust, sand, ash, and whatever else they can inhale to blind and disorientate their victims. Make sure to wear a facemask when fighting them." +tip = "Dust devils use clouds of dust, sand, ash and whatever else they can inhale to blind and disorientate their victims. Good luck on obtaining a dragon chainmail from their dusty remains." [.dagannoth] amount = [170, 240] weight = 10 -tip = "Dagannoth are large sea dwelling creatures which are very aggressive. You'll often find them in caves near sea water." +tip = "Dagannoth are large, sea-dwelling creatures that are very aggressive. You'll often find them in caves near sea water. There is no joy so great as to cleanse these from the face of Gielinor." #[.elves] #amount = [120, 150] #weight = 12 -#tip = "Elves are quick, agile, and vicious fighters which often favour bows and polearms." +#tip = "Elves are skilled fighters across all disciplines from whom you could learn a lot. I recommend challenging only one type of elf combatant at a time." [.fire_giant] amount = [170, 250] weight = 10 -tip = "Like other giants, Fire Giants have little to no magical ability, and they're particularly weak to water spells." +tip = "Like other giants, fire giants often wield large weapons. Learn to recognise what kind of weapon it is and act accordingly. Remember the days when these were a challenge to you and laugh." [.gargoyles] amount = [150, 250] weight = 12 -tip = "Gargoyles are winged creatures of stone. You'll need to fight them to near death before breaking them apart with a Rock Hammer." +tip = "Gargoyles are winged creatures of stone. You'll need to fight them until they are close to death before breaking them apart with a rock hammer. I've managed to trap a few in the dungeon I'm guarding." [.greater_demons] amount = [150, 250] weight = 11 -tip = "Demons are particularly weak to water spells. Though Greater Demons are not the strongest type of demon they are still dangerous." +tip = "Greater demons are weak to ranged attacks. Though not the strongest of demons, they are still dangerous. I've managed to trap a few in the dungeon I'm guarding." [.hellhounds] amount = [130, 220] weight = 10 -tip = "Hellhounds are a cross between Dogs and Demons. They are dangerous with a fierce bite, but have all of the same weaknesses as most demons." +tip = "Hellhounds are a cross between dogs and demons; they are also dangerous with a fierce bite. I've managed to trap a few in the dungeon I'm guarding." [.iron_dragons] amount = [60, 110] weight = 9 -tip = "Iron Dragons are some of the weaker metallic dragons, their iron scales are far thicker than normal iron armour." +tip = "Iron dragons are some of the weaker metallic dragons, with iron scales that are far thicker than normal iron armour. Their fiery breath and sharp claws can be negated by a number of means. I've managed to trap a few in the dungeon I'm guarding." [.kalphites] amount = [170, 250] weight = 5 -tip = "Kalphite are large insects which live in great hives under the desert sands." +tip = "Kalphites are large insects that live in hives under the desert sands. I am sure that, by now, you have seen them to the south-west of Shantay Pass." #[.living_rock_creatures] #amount = [120, 170] #weight = 10 -#tip = "Found beneath the Dwarven mines, these are tough beings of rock. They can use ranged or melee attacks against you, so plan accordingly! " +#tip = "Found beneath the Dwarven mines, these are tough beings of rock. They can use ranged or melee attacks against you, so plan accordingly!" [.mithril_dragons] amount = [30, 35] weight = 8 -tip = "Mithril dragons are more vulnerable to magic and to stab-based melee attacks than to anything else." +tip = "Mithril dragons are very dangerous opponents. They live just north of where we are now. You are a battle master - test your skills." [.nechryael] amount = [140, 220] weight = 10 -tip = "Nechryael are demons of decay which summon small winged beings to help them fight their victims. Their minions can bypass protective prayers so be sure to wear thick armour." +tip = "Nechryael are demons of decay that summon small winged beings to help them fight their victims. They can be found in the Chaos Tunnels or in Canifis Slayer Tower." #[.scabarites] #amount = [80, 120] @@ -116,22 +116,22 @@ tip = "Nechryael are demons of decay which summon small winged beings to help th [.skeletal_wyverns] amount = [40, 90] weight = 5 -tip = "Skeletal Wyverns are extremely dangerous and they are hard to hit with arrows as they slip right through. To stand a good chance of surviving you'll need some elemental shielding from its icy breath." +tip = "Skeletal wyverns are extremely dangerous, and they are hard to hit with arrows as they slip right through. To stand a good chance of surviving, you'll need some elemental shielding from their icy breath." [.spiritual_creatures] amount = [120, 185] weight = 10 -tip = "Spiritual Creatures can be found in the icy caverns near Trollheim, supporting the cause of their chosen god. Wearing equipment aligned with each of the gods can help you avoid undesired conflict." +tip = "Spiritual mages are the strongest of the spiritual guardians. They are devastating against warriors, but a smart ranger can sometimes defeat them. Of course, Prayer might serve you well, too. They can be found in the icy caverns near Trollheim, supporting the cause of their chosen god." [.steel_dragons] amount = [40, 100] weight = 9 -tip = "Steel Dragons are dangerous metallic dragons, their steel scales are far thicker than normal steel armour." +tip = "Steel dragons are dangerous and metallic, with steel scales that are far thicker than normal steel armour. I've managed to trap a few in the dungeon I'm guarding." [.suqahs] amount = [50, 100] weight = 5 -tip = "Suqahs can only be found on the mystical Lunar Isle. They are capable of melee and magic attacks and often drop hide, teeth and herbs!" +tip = "Suqahs can only be found on the mystical Lunar Isle. They use melee and magical attacks, and they often drop hide, teeth and herbs." #[.terror_dogs] #amount = [60, 70] @@ -141,13 +141,13 @@ tip = "Suqahs can only be found on the mystical Lunar Isle. They are capable of [.tzhaar] amount = [80, 110] weight = 7 -tip = "Tzhaar reside in their cave under the Karamja volcano. Beware as they can call to their fellows for aid." +tip = "The TzHaar contains some mighty warriors, prove yourself against them. You'll find them deep within the Karamja volcano." [.waterfiends] amount = [170, 250] weight = 9 -tip = "Waterfiends are creatures of water, which live under the Baxtorian Lake. Their watery form is well defended against slashing and piercing weapons, so use something blunt." +tip = "Waterfiends are creatures of water that live just north of us. Those followed by familiars are keen to slay these elemental forces." [.warped_creatures] amount = [150, 240] -tip = "Warped Creatures can supposedly be found within a mysterious dungeon on the eastern edge of the Poison Waste. Be aware that to defeat them, you'll need to purify them in some way." +tip = "Warped tortoises are creatures tainted by magical waste. They are vulnerable to an elven chime. I know you have seen them in your adventures, so go crack some carapace." diff --git a/data/skill/slayer/mazchna.tables.toml b/data/skill/slayer/mazchna.tables.toml index 9480d256e8..cbd09d9e19 100644 --- a/data/skill/slayer/mazchna.tables.toml +++ b/data/skill/slayer/mazchna.tables.toml @@ -6,7 +6,7 @@ tip = "string" [.banshees] amount = [30, 50] weight = 8 -tip = "Banshees use a piercing scream to shock their enemies, you'll need some Earmuffs to protect yourself from them." +tip = "Banshees use a piercing scream to shock their enemies; you'll need some earmuffs to protect yourself from them. Their cries echo throughout the Slayer Tower in Morytania." [.bears] amount = [30, 50] @@ -31,7 +31,7 @@ tip = "Cave Bugs are like Cave Crawlers, except smaller and easier to squish, th [.cave_crawlers] amount = [30, 50] weight = 8 -tip = "Cave Crawlers are small and fast, often hiding in ambush. Avoid their barbed tongue or you'll get poisoned." +tip = "Cave crawlers are small and fast, often seen creeping around in the Rellekka Slayer Dungeon. Avoid their barbed tongue or you'll get poisoned." [.cave_slimes] amount = [10, 20] @@ -41,7 +41,7 @@ tip = "Cave Slimes are the lesser cousins of Jellies, though don't be fooled the [.cockatrice] amount = [30, 50] weight = 8 -tip = "Cockatrice, like Basilisks, have a gaze which will paralyse and harm their prey. You'll need a Mirror Shield to protect you." +tip = "Cockatrices, like basilisks, have a gaze which will paralyse and harm their prey. You'll need a mirror shield to protect you. If you are brave enough, head to Slayer Caves east of Rellekka." [.crawling_hands] amount = [30, 50] @@ -56,7 +56,7 @@ tip = "Crabs can be found all across Gielinor. They don't hit very hard but they [.dogs] amount = [30, 50] weight = 7 -tip = "Dogs are much like Wolves, they are pack creatures which will hunt in groups." +tip = "Dogs are much like wolves; they are pack creatures that will hunt in groups. I've heard there are fearsome wild dogs beneath Karamja, or near Ardougne if you are less adventurous." [.flesh_crawlers] amount = [15, 25] @@ -71,7 +71,7 @@ tip = "Ghosts are undead so magic is your best bet against them, there is even a [.ghouls] amount = [10, 20] weight = 7 -tip = "Ghouls aren't undead but they are stronger and tougher than they look. However they're also very cowardly and will run if they're losing a fight." +tip = "Ghouls aren't undead, but they are stronger and tougher than they look. They're also very cowardly and will run if they're losing a fight. They wait to ambush those entering the graveyard to the North of Canifis." [.hill_giants] amount = [30, 50] @@ -86,7 +86,7 @@ tip = "Hobgoblins carrying spears are often trained warriors. If you want less o [.ice_warriors] amount = [40, 50] weight = 7 -tip = "Ice Warriors are a kind of ice elemental, shatter them with blunt weapons or melt them with fire." +tip = "Ice warriors are a kind of ice elemental. Thurgo the dwarf recently spotted some in the caves south of Port Sarim." [.kalphites] amount = [30, 50] @@ -96,12 +96,12 @@ tip = "Kalphite are large insects which live in great hives under the desert san #[.killerwatts] #amount = [30, 50] #weight = 6 -#tip = "Killerwatts store huge amounts of energy in their bodies, which is released if they are touched. You'll need to wear heavily insulated boots to counter this shocking effect." +#tip = "Killerwatts store huge amounts of energy in their bodies, which is released if they are touched. You'll need to wear heavily insulated boots to counter this shocking effect, plus they can attack speedily with both magic and missiles. To access their cloudy plane, you'll need to explore Draynor Manor." [.lizards] amount = [30, 50] weight = 8 -tip = "Lizards are large reptiles with tough skin. Those found in the desert will need you to douse them with freezing water to finish them off after a tough battle." +tip = "Desert lizards are large reptiles with tough skin. They're cold-blooded, so dousing them with freezing water will finish them off after a tough battle. You can find them to the east of Sophanem." #[.mogres] #amount = [30, 50] @@ -111,7 +111,7 @@ tip = "Lizards are large reptiles with tough skin. Those found in the desert wil [.pyrefiends] amount = [30, 50] weight = 8 -tip = "Pyrefiends are beings of fire and molten rock, they're quick and agile but weak to water spells." +tip = "Pyrefiends are magical beings of fire and molten rock. They're quick and agile so try attacking them with a crossbow and bolts. You can find some fiends in the Rellekka Slayer Caves." [.rockslugs] amount = [30, 50] @@ -126,7 +126,7 @@ tip = "Scorpions are almost always poisonous, their hard carapace makes them res #[.shades] #amount = [30, 70] #weight = 8 -#tip = "Shades are undead so magic is your best bet against them. You can find Shades at Mort'ton." +#tip = "Shades are undead - The town of Mort'ton in Morytania is plagued by these creatures, so help if you can. There are some shades in the Stronghold of Security too, but you won't learn much from fighting those; stick to Mort'ton." [.skeletons] amount = [30, 50] @@ -136,7 +136,7 @@ tip = "Skeletons are undead so magic is your best bet against them, there is eve #[.vampyres] #amount = [10, 20] #weight = 6 -#tip = "Vampyres are extremely powerful beings. An underground group known as the Myreque have been searching for tools to defeat them, which they may be willing to share if you can find them." +#tip = "Vampyres are extremely powerful beings. They feed on the blood of the living, so watch that you don't get bitten. Look in the woods of Morytania." [.wolves] amount = [30, 50] diff --git a/data/skill/slayer/sumona.tables.toml b/data/skill/slayer/sumona.tables.toml index be9c5da6a4..b6f83683f4 100644 --- a/data/skill/slayer/sumona.tables.toml +++ b/data/skill/slayer/sumona.tables.toml @@ -6,159 +6,159 @@ tip = "string" [.aberrant_spectre] amount = [120, 185] weight = 15 -tip = "Aberrant Spectres are fetid, vile ghosts. The very smell of them will paralyse and harm you. A nosepeg will help ignore their stink." +tip = "Aberrant spectres are fetid, vile ghosts. The very smell of them will paralyse and harm you, while a nosepeg will help ignore their stink. If you sniff carefully, you may be able to detect their aroma beneath the town's well. Kill a few of them, as they offend my nose." [.abyssal_demon] amount = [120, 185] weight = 10 -tip = "Abyssal Demons are nasty creatures to fight. They aren't really part of this realm, and are able to move very quickly to trap their prey." +tip = "Abyssal demons are nasty creatures to deal with. They aren't really part of this realm and are able to move very quickly to trap their prey. I'm sure you'd love a nice abyssal whip or two, so cull these demons in the Slayer Tower near Canifis." [.aquanites] amount = [120, 185] weight = 10 -tip = "Aquanites rely on their lures for both offensive and defensive purposes. Whilst their hides are resistant to slashing attacks, a well timed cut is capable of severing the lure." +tip = "Aquanites are amphibious creatures that attract prey using the glowing lures on their heads. They attack stronger opponents from a distance with water magic, and dislike those who pray against it. You'll find these despicable, slimy creatures in the Fremennik Slayer Dungeon, in a chamber past the kurasks." [.aviansies] amount = [50, 100] weight = 7 -tip = "Aviansies are bird-like creatures found in the icy dungeons of the north. Melee weapons can't reach them, so use Magic or Ranged attacks." +tip = "Aviansies can be found in the Godwars Dungeon north of Trollheim. As they are flying, you'll find melee attacks are not going to cut it." [.basilisks] amount = [120, 185] weight = 15 -tip = "Basilisks, like Cockatrice, have a gaze which will paralyse and harm their prey. You'll need a Mirror Shield to protect you." +tip = "Basilisks, like Cockatrices, have a gaze which will paralyse and harm their prey. You'll need a mirror shield to protect you. Conveniently, you can have some combat fun with these brutes in the dungeon beneath the town well." [.banshees] amount = [120, 185] weight = 15 -tip = "Banshees use a piercing scream to shock their enemies, you'll need some Earmuffs to protect yourself from them." +tip = "Banshees use a piercing scream to shock their enemies, so you'll need some earmuffs to protect yourself. I am sometimes disturbed in my sleep by their wails, so do me a favour and thin out those beneath us." [.bloodvelds] amount = [120, 185] weight = 10 -tip = "Bloodveld are strange demonic creatures, their long rasping tongue has magical properties so it pierces straight through physical defences." +tip = "Bloodveld are strange, demonic creatures that use their long rasping tongue to feed on just about anything. They are rather robust but frankly feeble and have been seen in the Slayer Tower near Canifis, among other places. I never liked the look of them, so off you go and wipe them out." [.black_demons] amount = [120, 185] weight = 10 -tip = "Powerful weapons known as demonbane weapons can be used to quickly defeat even powerful demons like the Black Demon with greater ease." +tip = "Black demons are creatures that are weak to ranged attacks. They're the strongest type of demon and are therefore very dangerous. Prove yourself more dangerous by slaying these demons in their lairs beneath Taverley or Edgeville." [.blue_dragons] amount = [120, 185] weight = 5 -tip = "Like all dragons, Blue Dragons have thick scales and a powerful fiery breath. Stabbing weapons and heavy bolts are best suited to piercing their defences." +tip = "Blue dragons aren't as strong as other dragons, but they're still very powerful. Watch out for their fiery breath! Taverley is home to these pests - I'm sure you'll enjoy murdering a few." [.cave_crawlers] amount = [120, 185] weight = 15 -tip = "Cave Crawlers are small and fast, often hiding in ambush. Avoid their barbed tongue or you'll get poisoned." +tip = "Cave crawlers are small and fast, often hiding in ambush. Avoid their barbed tongue or you'll get poisoned. The ones in the caves below here have grown large and fat in blissful isolation - go and be a force of natural selection." [.cave_horrors] amount = [120, 185] weight = 15 -tip = "Cave Horrors can be found under Mos Le'Harmless. You will need a Witchwood Icon to fight them effectively." +tip = "Cave horrors can be found under Mos Le'Harmless. You will need a witchwood icon to fight them effectively. If you want to make a nice Slayer helmet, you'll need the black mask they drop." [.crocodiles] amount = [150, 250] weight = 4 -tip = "Crocodiles are large reptiles which live near water. You'll want to have a stabbing weapon handy for puncturing their thick scaly hides." +tip = "Crocodiles are large reptiles that live near water. You'll want to have a stabbing weapon handy for puncturing their thick, scaly hides. These are desert beasts, so seek them there." [.dust_devils] amount = [120, 185] weight = 15 -tip = "Dust Devils use clouds of dust, sand, ash, and whatever else they can inhale to blind and disorientate their victims. Make sure to wear a facemask when fighting them." +tip = "Dust devils use clouds of dust, sand, ash and whatever else they can inhale to blind and disorientate their victims. You'll be able to test your skills on them in the smoky dungeon to the west. Get going!" [.dagannoth] amount = [120, 185] weight = 10 -tip = "Dagannoth are large sea dwelling creatures which are very aggressive. You'll often find them in caves near sea water." +tip = "Dagannoth are large, sea-dwelling creatures that are very aggressive. You'll often find them in caves near sea water. You'll cackle with glee if you set up a cannon and massacre them." #[.elves] #amount = [60, 90] #weight = 10 -#tip = "Elves are quick, agile, and vicious fighters which often favour bows and polearms." +#tip = "Elves are quick, agile and vicious fighters that often favour bows, polearms and snide remarks. Their dedication to trees, bushes and music is an affront to me, so go and cause havoc in their vile villages. You'll need to travel far to the west." [.fire_giant] amount = [120, 185] weight = 10 -tip = "Like other giants, Fire Giants have little to no magical ability, and they're particularly weak to water spells." +tip = "Like other giants, Fire giants often wield large weapons. Learn to recognise what kind of weapon it is and act accordingly. Prove that bigger isn't always better by defeating some. They lurk in the smoke dungeon, west of here, telling tales of your weakness." [.gargoyles] amount = [120, 195] weight = 10 -tip = "Gargoyles are winged creatures of stone. You'll need to fight them to near death before breaking them apart with a Rock Hammer." +tip = "Gargoyles are winged creatures of stone. You'll need to fight them until they are close to death, before breaking them apart with a rock hammer. They refuse to serve me, so smite them in my name. They are hiding out in the Slayer Tower near Canifis." [.greater_demons] amount = [120, 195] weight = 10 -tip = "Demons are particularly weak to water spells. Though Greater Demons are not the strongest type of demon they are still dangerous." +tip = "Greater demons are creatures that are weak to ranged attacks. Though not the strongest of demons, they are still dangerous. Prove yourself by doing away with them. If you don't know, a large number live in the Brimhaven Dungeon." [.hellhounds] amount = [120, 185] weight = 10 -tip = "Hellhounds are a cross between Dogs and Demons. They are dangerous with a fierce bite, but have all of the same weaknesses as most demons." +tip = "Hellhounds are a cross between dogs and demons, and are dangerous with a fierce bite. Although they are not cats, they deserve to die anyway. You'll be doing Gielinor a favour if you slay Hellhounds beneath Taverley." [.iron_dragons] amount = [30, 60] weight = 7 -tip = "Iron Dragons are some of the weaker metallic dragons, their iron scales are far thicker than normal iron armour." +tip = "Iron dragons are some of the weaker metallic dragons, but their iron scales are far thicker than normal iron armour. Brimhaven Dungeon has a few of these creatures in residence; I think they should be exterminated because they bore me." [.kalphites] amount = [120, 185] weight = 10 -tip = "Kalphite are large insects which live in great hives under the desert sands." +tip = "Kalphites are large insects that live in hives under the desert sands. Their Queen is rumoured to be quite powerful. Show people that you are a force to be feared by slaying her brood in the hive to the north-west." [.kurask] amount = [120, 185] weight = 15 -tip = "Kurask are large brutal creatures with very thick hides. You'll need a Leaf-Tipped Spear or Battle-axe, Broad Arrows, or a Magic Dart to harm it." +tip = "Kurasks are large, brutal creatures with very thick hides. You'll need a leaf-bladed weapon, broad arrows, or a magic dart to harm them. Unluckily for kurasks, I am sending you to kill them. Luckily for you, kurasks thrive in the dungeons below Pollnivneach." [.lizards] amount = [90, 110] weight = 4 -tip = "Lizards are large reptiles with tough skin. Those found in the desert will need you to douse them with freezing water to finish them off after a tough battle." +tip = "Desert lizards are large reptiles with tough skin. They're cold-blooded, so dousing them with freezing water will finish them off after a tough battle." [.nechryael] amount = [120, 185] weight = 10 -tip = "Nechryael are demons of decay which summon small winged beings to help them fight their victims. Their minions can bypass protective prayers so be sure to wear thick armour." +tip = "Nechryael are demons of decay that summon small-winged beings to help them fight their victims. I don't like them much, so kill a few as a personal favour. You can find them up to no good in the Slayer Tower near Canifis." [.red_dragons] amount = [30, 60] weight = 5 -tip = "Red Dragons are very powerful, stronger than most dragons, watch out for their fiery breath." +tip = "Red dragons are fearsome firebreathers, stronger than green or blue. I'm sure that you'll have fun pitting your skills against their claws in either Brimhaven's depths or the ravaged lands far to the north." #[.scabarites] #amount = [80, 120] #weight = 5 -#tip = "Scabarites are insectoid creatures, found beyond the Kharidian deserts. Make sure not to fall into one of their pitfall traps or you'll be quickly overwhelmed." +#tip = The last Scabaras lancer I killed I found fire spells took them down effectively.
Scabarites are the followers of Scabaras and consist of anything from the lowliest dung beetle to the vilest scarab mage. They are most commonly found near and under Sophanem. They are traitorous creatures in the main, so commit genocide upon them." [.scorpions] amount = [150, 250] weight = 4 -tip = "Scorpions are almost always poisonous, their hard carapace makes them resistant to crushing and stabbing attacks." +tip = "Scorpions are almost always venomous and usually found in groups. Last I heard there was a large group near the mine north of Al Kharid." [.spiritual_creatures] amount = [120, 185] weight = 10 -tip = "Spiritual Creatures can be found in the icy caverns near Trollheim, supporting the cause of their chosen god. Wearing equipment aligned with each of the gods can help you avoid undesired conflict." +tip = "Spiritual warriors are fighters that have dedicated their souls to their deity; however, they still retain a fighter's weakness to Magic. They can be found fighting for the god whose cause they support. Kill them all and let their gods lament." #[.terror_dogs] #amount = [30, 60] #weight = 10 -#tip = "Terror dogs are, unsurprisingly, dogs that terrorise the weak. You'll find them in the Haunted Mine, near Tarn's lair." +#tip = "Terror dogs are, unsurprisingly, dogs that terrorise the weak. They are the servants of Tarn, who annoyed me when he was young. Be a force of vengeance for me by cleaning his lair of these pathetic servitors." [.turoth] amount = [120, 185] weight = 15 -tip = "Turoth are large vicious creatures with thick hides. You'll need a Leaf-Tipped Spear or Sword, Broad Arrows, or a Magic Dart to harm them." +tip = "Turoths are large vicious creatures with thick hides. You'll need a leaf-bladed weapon, broad arrows, or a magic dart to harm them. I am sure you'll make yourself useful by killing the ones beneath our feet." [.trolls] amount = [120, 185] weight = 10 -tip = "Trolls regenerate damage quickly and have some level of magical defences, but this is easily bypassed by their weakness to fire." +tip = "The last Mountain troll I killed I found water spells took them down effectively.
Trolls regenerate quickly but are still vulnerable to poisons and usually use crushing weapons. I've nothing much against them but their ridiculous names. Unluckily for them, that's enough of a reason to put a few in their graves." #[.warped_creatures] #amount = [120, 185] #weight = 10 -#tip = "Warped Creatures can supposedly be found within a mysterious dungeon on the eastern edge of the Poison Waste. Be aware that to defeat them, you'll need to purify them in some way." +#tip = "Warped tortoises are creatures tainted by magical waste. They are vulnerable to an elven chime. I know you have seen them in your adventures, so go crack some carapace." diff --git a/data/skill/slayer/turael.tables.toml b/data/skill/slayer/turael.tables.toml index bc761bf1b8..24a1a44f15 100644 --- a/data/skill/slayer/turael.tables.toml +++ b/data/skill/slayer/turael.tables.toml @@ -21,7 +21,7 @@ tip = "Bats are rarely found on the ground, so you'll have to fight them while t [.birds] amount = [15, 30] weight = 6 -tip = "Birds aren't the most intelligent of creatures, but watch out for their sharp stabbing beaks." +tip = "Birds aren't the most intelligent of creatures, but watch out for their sharp, stabbing beaks. Even the chickens in Lumbridge are after your blood, so get them before they get you." [.cave_bugs] amount = [10, 30] @@ -41,12 +41,12 @@ tip = "Cave Slimes are the lesser cousins of Jellies, though don't be fooled the [.cows] amount = [15, 30] weight = 8 -tip = "Cows are bigger than you, so they'll often hit fairly hard but are usually fairly slow to react." +tip = "Cows are bigger than you, and they'll often hit hard but react fairly slowly. You can slaughter the ones in Lumbridge - I bet they are up to no good." [.crawling_hands] amount = [15, 30] weight = 8 -tip = "Crawling Hands are undead severed hands, fast and dexterous they claw their victims." +tip = "Crawling hands are undead severed hands; fast and dexterous, they claw their victims. They can be found in the Slayer Tower, north-east of the entrance to Morytania." [.dogs] amount = [15, 30] @@ -116,7 +116,7 @@ tip = "Spiders are often poisonous, and many varieties are camouflaged too." [.wolves] amount = [15, 30] weight = 7 -tip = "Wolves are pack animals, so you'll always find them in groups. Watch out for their bite, it can be nasty." +tip = "Wolves are pack animals, so you'll always find them in groups. Watch out for their bite, it can be nasty. There are plenty to kill on White Wolf Mountain." [.zombies] amount = [15, 30] diff --git a/data/skill/slayer/vannaka.tables.toml b/data/skill/slayer/vannaka.tables.toml index 2abc7046ae..1d51b900ef 100644 --- a/data/skill/slayer/vannaka.tables.toml +++ b/data/skill/slayer/vannaka.tables.toml @@ -96,12 +96,12 @@ tip = "Hellhounds are a cross between Dogs and Demons. They are dangerous with a [.hill_giants] amount = [40, 90] weight = 7 -tip = "Hill Giants often wield large weapons, learn to recognise what kind of weapon it is and act accordingly." +tip = "Hill giants use crude weapons or tools so prepare accordingly. There is a colony of them, deep inside the Edgeville tunnels; all good folk will approve if you clean it out." [.hobgoblins] amount = [40, 90] weight = 7 -tip = "Hobgoblins carrying spears are often trained warriors. If you want less of a challenge, fight the ones that are unarmed." +tip = "Hobgoblins are larger and stronger then their brethren. There is a peninsula, south-west of Falador, where these creatures have a hideout." #[.harpie_bug_swarms] #amount = [40, 90] @@ -116,12 +116,12 @@ tip = "Infernal Mages are dangerous spell users, beware of their magic spells an [.ice_giant] amount = [30, 80] weight = 7 -tip = "Like other giants, Ice Giants have little to no magical ability, and they're particularly weak to fire spells." +tip = "Like other giants, ice giants often wield large weapons. Try using fire spells to melt them before they can hit you. Ice giants can be found underground to the south of Port Sarim." [.ice_warriors] amount = [40, 90] weight = 7 -tip = "Ice Warriors are a kind of ice elemental, shatter them with blunt weapons or melt them with fire." +tip = "Ice warriors are a kind of ice elemental. Thurgo the dwarf recently spotted some in the caves south of Port Sarim." [.jellies] amount = [40, 90] @@ -136,7 +136,7 @@ tip = "Jungle Horrors can be found all over Mos Le'Harmless. They are strong and [.kalphites] amount = [40, 90] weight = 7 -tip = "Kalphite are large insects which live in great hives under the desert sands." +tip = "Kalphite are large insects that live in hives under the desert sands. You can best enter their hive south-west of Shantay Pass, but try not to go too deep." [.kurask] amount = [40, 90] @@ -151,12 +151,12 @@ tip = "Demons are weak to magical attacks. Though Lesser Demons are relatively w #[.mogres] #amount = [40, 90] #weight = 7 -#tip = "Mogres are a type of aquatic Ogre that is often mistaken for a giant mudskipper. You have to force them out of the water with a fishing explosive." +#tip = "Mogres are a type of aquatic ogre that is often mistaken for a giant mudskipper. You have to force them out of the water with a fishing explosive. You can find them on the peninsula to the south of Port Sarim." [.moss_giants] amount = [40, 90] weight = 7 -tip = "Like other giants, Moss Giants have little to no magical ability, and they're particularly weak to fire spells." +tip = "Like other giants, moss giants often wield large weapons. Use fire spells to burn them to cinders before they can damage you. Strangely for giants, some have been seen at the end of the Varrock sewers." [.nechryael] amount = [40, 90] From 627d9dfe834aad94c2dfdd605f23319972339c05 Mon Sep 17 00:00:00 2001 From: GregHib Date: Wed, 25 Mar 2026 12:15:59 +0000 Subject: [PATCH 08/40] Add missing tasks --- data/skill/slayer/chaeldar.tables.toml | 5 +++++ data/skill/slayer/duradel.tables.toml | 16 ++++++++++++++++ data/skill/slayer/kuradal.tables.toml | 20 ++++++++++++++++++++ data/skill/slayer/sumona.tables.toml | 10 ++++++++++ 4 files changed, 51 insertions(+) diff --git a/data/skill/slayer/chaeldar.tables.toml b/data/skill/slayer/chaeldar.tables.toml index 3bdc4a5c58..9984133f69 100644 --- a/data/skill/slayer/chaeldar.tables.toml +++ b/data/skill/slayer/chaeldar.tables.toml @@ -103,6 +103,11 @@ amount = [70, 130] weight = 10 tip = "Jungle horrors can be found all over Mos Le'Harmless. They are strong and aggressive, but you should be heroic enough to make short work of them." +[.jungle_strykewyrm] +amount = [80, 110] +weight = 12 +tip = "These tricky creatures burrow beneath the jungle north west of Oo'glog. Be careful, as these poisonous jungle wyrms like to use magical attacks from a distance, while they should be weak to stab attacks." + [.kalphites] amount = [70, 130] weight = 11 diff --git a/data/skill/slayer/duradel.tables.toml b/data/skill/slayer/duradel.tables.toml index 594cc9d363..1d71fa7d6d 100644 --- a/data/skill/slayer/duradel.tables.toml +++ b/data/skill/slayer/duradel.tables.toml @@ -43,6 +43,11 @@ amount = [130, 200] weight = 15 tip = "Dark beasts are large, dog-like predators with massively muscled bodies that protect them from crushing weapons. You'll find them near the Temple of Light, attracted to the power of the Death Altar." +[.desert_strykewyrm] +amount = [90, 140] +weight = 11 +tip = "Head east of Al Kharid to find them on the hills above the Shantay Pass. Watch out for their vicious ranged attacks." + [.dust_devils] amount = [130, 200] weight = 10 @@ -78,11 +83,22 @@ amount = [130, 200] weight = 9 tip = "Hellhounds are a cross between dogs and demons; they are also dangerous with a fierce bite. Make them know fear." +[.ice_strykewyrm] +amount = [100, 200] +weight = 8 +# TODO req fire cape or unlock +tip = "The strongest and coldest of their kind, they are found beneath the Fremennik mountains. Be careful of all their attacks; but, as they are beings of ice, I've found my fire spells inflict far more damage against them." + [.iron_dragons] amount = [40, 80] weight = 9 tip = "Iron dragons are some of the weaker metallic dragons; their iron scales are far thicker than normal iron armour. Their fiery breath and sharp claws can be negated by a number of means. If you haven't visited Brimhaven Dungeon's depths then I advise you do - if only for the interesting creatures like these to kill there." +[.jungle_strykewyrm] +amount = [90, 120] +weight = 10 +tip = "These tricky creatures burrow beneath the jungle north west of Oo'glog. Be careful, as these poisonous jungle wyrms like to use magical attacks from a distance, while they should be weak to stab attacks." + [.kalphites] amount = [130, 200] weight = 10 diff --git a/data/skill/slayer/kuradal.tables.toml b/data/skill/slayer/kuradal.tables.toml index 6dd1f280cd..6e5dea5921 100644 --- a/data/skill/slayer/kuradal.tables.toml +++ b/data/skill/slayer/kuradal.tables.toml @@ -48,6 +48,11 @@ amount = [150, 250] weight = 12 tip = "The last Dark beast I killed I found a crossbow with bolts took them down effectively.
Dark beasts are large, dog-like predators with massively muscled bodies that protect them from crushing weapons. I've managed to trap a few in the dungeon I'm guarding." +[.desert_strykewyrm] +amount = [90, 160] +weight = 7 +tip = "You'll find these East of Al Kharid, atop the mountain. Watch out for their vicious ranged attacks!" + [.dust_devils] amount = [150, 250] weight = 10 @@ -83,11 +88,21 @@ amount = [130, 220] weight = 10 tip = "Hellhounds are a cross between dogs and demons; they are also dangerous with a fierce bite. I've managed to trap a few in the dungeon I'm guarding." +[.ice_strykewyrm] +amount = [100, 200] +weight = 9 +tip = "The coldest of their kind, they are found beneath the Fremennik mountains. As they are beings of ice, I've found that fire spells inflict far more damage against them." + [.iron_dragons] amount = [60, 110] weight = 9 tip = "Iron dragons are some of the weaker metallic dragons, with iron scales that are far thicker than normal iron armour. Their fiery breath and sharp claws can be negated by a number of means. I've managed to trap a few in the dungeon I'm guarding." +[.jungle_strykewyrm] +amount = [90, 130] +weight = 8 +tip = "These tricky creatures burrow beneath the jungle north west of Oo'glog. Be careful, as these poisonous jungle wyrms like to use magical attacks from a distance, while they should be weak to stab attacks." + [.kalphites] amount = [170, 250] weight = 5 @@ -143,6 +158,11 @@ amount = [80, 110] weight = 7 tip = "The TzHaar contains some mighty warriors, prove yourself against them. You'll find them deep within the Karamja volcano." +#[.tormented_demon] +#amount = [40, 60] +#weight = 8 +#tip = "Tormented demons are powerful creatures that use magic, ranged and melee attacks. They also have the ability to shield themselves. You can find them below the Tears of Guthix cave." + [.waterfiends] amount = [170, 250] weight = 9 diff --git a/data/skill/slayer/sumona.tables.toml b/data/skill/slayer/sumona.tables.toml index b6f83683f4..b3455d255d 100644 --- a/data/skill/slayer/sumona.tables.toml +++ b/data/skill/slayer/sumona.tables.toml @@ -63,6 +63,11 @@ amount = [150, 250] weight = 4 tip = "Crocodiles are large reptiles that live near water. You'll want to have a stabbing weapon handy for puncturing their thick, scaly hides. These are desert beasts, so seek them there." +[.desert_strykewyrm] +amount = [90, 110] +weight = 14 +tip = "These things are the curse of the desert! Head north to find them on the hills above the Shantay Pass. Watch out for their vicious ranged attacks." + [.dust_devils] amount = [120, 185] weight = 15 @@ -103,6 +108,11 @@ amount = [30, 60] weight = 7 tip = "Iron dragons are some of the weaker metallic dragons, but their iron scales are far thicker than normal iron armour. Brimhaven Dungeon has a few of these creatures in residence; I think they should be exterminated because they bore me." +[.jungle_strykewyrm] +amount = [90, 120] +weight = 12 +tip = "These tricky creatures burrow beneath the jungle north west of Oo'glog. Be careful, as these poisonous jungle wyrms like to use magical attacks from a distance, while they should be weak to stab attacks." + [.kalphites] amount = [120, 185] weight = 10 From f3a528ddea56f6ee48a045993675688930c5776d Mon Sep 17 00:00:00 2001 From: GregHib Date: Wed, 25 Mar 2026 12:17:21 +0000 Subject: [PATCH 09/40] Tidy slayer master table location --- data/skill/slayer/{ => master}/chaeldar.tables.toml | 0 data/skill/slayer/{ => master}/duradel.tables.toml | 0 data/skill/slayer/{ => master}/kuradal.tables.toml | 0 data/skill/slayer/{ => master}/mazchna.tables.toml | 0 data/skill/slayer/{ => master}/sumona.tables.toml | 0 data/skill/slayer/{ => master}/turael.tables.toml | 0 data/skill/slayer/{ => master}/vannaka.tables.toml | 0 .../kotlin/world/gregs/voidps/engine/data/definition/Tables.kt | 2 +- 8 files changed, 1 insertion(+), 1 deletion(-) rename data/skill/slayer/{ => master}/chaeldar.tables.toml (100%) rename data/skill/slayer/{ => master}/duradel.tables.toml (100%) rename data/skill/slayer/{ => master}/kuradal.tables.toml (100%) rename data/skill/slayer/{ => master}/mazchna.tables.toml (100%) rename data/skill/slayer/{ => master}/sumona.tables.toml (100%) rename data/skill/slayer/{ => master}/turael.tables.toml (100%) rename data/skill/slayer/{ => master}/vannaka.tables.toml (100%) diff --git a/data/skill/slayer/chaeldar.tables.toml b/data/skill/slayer/master/chaeldar.tables.toml similarity index 100% rename from data/skill/slayer/chaeldar.tables.toml rename to data/skill/slayer/master/chaeldar.tables.toml diff --git a/data/skill/slayer/duradel.tables.toml b/data/skill/slayer/master/duradel.tables.toml similarity index 100% rename from data/skill/slayer/duradel.tables.toml rename to data/skill/slayer/master/duradel.tables.toml diff --git a/data/skill/slayer/kuradal.tables.toml b/data/skill/slayer/master/kuradal.tables.toml similarity index 100% rename from data/skill/slayer/kuradal.tables.toml rename to data/skill/slayer/master/kuradal.tables.toml diff --git a/data/skill/slayer/mazchna.tables.toml b/data/skill/slayer/master/mazchna.tables.toml similarity index 100% rename from data/skill/slayer/mazchna.tables.toml rename to data/skill/slayer/master/mazchna.tables.toml diff --git a/data/skill/slayer/sumona.tables.toml b/data/skill/slayer/master/sumona.tables.toml similarity index 100% rename from data/skill/slayer/sumona.tables.toml rename to data/skill/slayer/master/sumona.tables.toml diff --git a/data/skill/slayer/turael.tables.toml b/data/skill/slayer/master/turael.tables.toml similarity index 100% rename from data/skill/slayer/turael.tables.toml rename to data/skill/slayer/master/turael.tables.toml diff --git a/data/skill/slayer/vannaka.tables.toml b/data/skill/slayer/master/vannaka.tables.toml similarity index 100% rename from data/skill/slayer/vannaka.tables.toml rename to data/skill/slayer/master/vannaka.tables.toml diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt index 0cb298972c..760597ddbf 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt @@ -184,7 +184,7 @@ object Tables { val rows = mutableListOf() val ids = mutableMapOf() for (path in paths) { - Config.fileReader(path, 256) { + Config.fileReader(path, 512) { try { while (nextSection()) { val stringId = section() From 9192552ba477652aa954ce7c37d031bf2c2a1abf Mon Sep 17 00:00:00 2001 From: GregHib Date: Wed, 25 Mar 2026 15:18:12 +0000 Subject: [PATCH 10/40] Convert object picking to tables --- .../voidps/cache/definition/data/EnumTypes.kt | 3 + data/entity/obj/picking.enums.toml | 55 +++---------------- data/entity/obj/picking.tables.toml | 33 +++++++++++ .../engine/data/config/RowDefinition.kt | 16 ++++++ .../engine/data/config/TableDefinition.kt | 21 ++++--- .../engine/data/definition/EnumDefinitions.kt | 18 ++++++ .../voidps/engine/data/definition/Tables.kt | 6 +- game/src/main/kotlin/Main.kt | 1 + .../main/kotlin/content/entity/obj/Picking.kt | 24 ++++---- game/src/test/kotlin/WorldTest.kt | 1 + 10 files changed, 109 insertions(+), 69 deletions(-) create mode 100644 data/entity/obj/picking.tables.toml diff --git a/cache/src/main/kotlin/world/gregs/voidps/cache/definition/data/EnumTypes.kt b/cache/src/main/kotlin/world/gregs/voidps/cache/definition/data/EnumTypes.kt index 4f39676366..e532664184 100644 --- a/cache/src/main/kotlin/world/gregs/voidps/cache/definition/data/EnumTypes.kt +++ b/cache/src/main/kotlin/world/gregs/voidps/cache/definition/data/EnumTypes.kt @@ -20,6 +20,7 @@ object EnumTypes { const val ENUM = 'g' const val INV = 'v' const val OBJ = 'z' // Custom + const val DBROW = 'y' // Custom fun name(char: Char) = when (char) { STRING -> "string" @@ -41,6 +42,7 @@ object EnumTypes { ENUM -> "enum" INV -> "inv" OBJ -> "object" + DBROW -> "row" else -> "null" } @@ -63,6 +65,7 @@ object EnumTypes { "enum" -> ENUM "inv" -> INV "object" -> OBJ + "row" -> DBROW else -> null } } \ No newline at end of file diff --git a/data/entity/obj/picking.enums.toml b/data/entity/obj/picking.enums.toml index fa64fada40..33e1d0745e 100644 --- a/data/entity/obj/picking.enums.toml +++ b/data/entity/obj/picking.enums.toml @@ -1,49 +1,12 @@ -[pickable_item] +[pickables] keyType = "object" -valueType = "string" -defaultString = "" +valueType = "row" values = { - cabbage_draynor_manor = "cabbage", - potato = "raw_potato", - wheat = "grain", - wheat_zanaris = "grain", - cabbage = "cabbage", - flax = "flax", - onion = "onion", + cabbage_draynor_manor = "picking.cabbages", + potato = "picking.potatoes", + wheat = "picking.wheat", + wheat_zanaris = "picking.wheat", + cabbage = "picking.cabbages", + flax = "picking.flax", + onion = "picking.onions", } - -[pickable_message] -keyType = "object" -valueType = "string" -defaultString = "" -values = { - cabbage_draynor_manor = "You pick a cabbage.", - potato = "You pick a potato.", - wheat = "You pick some wheat.", - wheat_zanaris = "You pick some wheat.", - cabbage = "You pick a cabbage.", - flax = "You pick some flax.", - onion = "You pick an onion.", -} - -[pickable_chance] -keyType = "object" -valueType = "int" -defaultInt = 1 -values = { - flax = 5, -} - -[pickable_respawn_delay] -keyType = "object" -valueType = "int" -defaultInt = -1 -values = { - cabbage_draynor_manor = 45, - potato = 30, - wheat = 30, - wheat_zanaris = 30, - cabbage = 45, - flax = 5, - onion = 30, -} \ No newline at end of file diff --git a/data/entity/obj/picking.tables.toml b/data/entity/obj/picking.tables.toml new file mode 100644 index 0000000000..73da64e054 --- /dev/null +++ b/data/entity/obj/picking.tables.toml @@ -0,0 +1,33 @@ +[picking] +item = "item" +message = "string" +chance = "int" +chance_default = 1 +respawn = "int" +respawn_default = -1 + +[.cabbages] +item = "cabbage" +respawn = 45 +message = "You pick a cabbage." + +[.potatoes] +item = "raw_potato" +respawn = 30 +message = "You pick a potato." + +[.wheat] +item = "grain" +respawn = 30 +message = "You pick some wheat." + +[.flax] +item = "flax" +chance = 5 +respawn = 5 +message = "You pick some flax." + +[.onions] +item = "onion" +respawn = 30 +message = "You pick an onion." diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt index 5a87507d06..2bdc2a8ef7 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt @@ -1,12 +1,28 @@ package world.gregs.voidps.engine.data.config +import world.gregs.voidps.engine.data.definition.Tables + /** * DbRow */ data class RowDefinition( + val id: Int, val data: Array, val stringId: String ) { + + fun int(column: String) = Tables.int("${stringId}.$column") + + fun intOrNull(column: String) = Tables.intOrNull("${stringId}.$column") + + fun string(column: String) = Tables.string("${stringId}.$column") + + fun stringOrNull(column: String) = Tables.stringOrNull("${stringId}.$column") + + fun item(column: String) = Tables.item("${stringId}.$column") + + fun itemOrNull(column: String) = Tables.itemOrNull("${stringId}.$column") + override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt index 4b7245e448..4384877828 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt @@ -26,9 +26,18 @@ data class TableDefinition( fun stringOrNull(column: String, row: Int): String? = getOrNull(column, row, ColumnType.ColumnString) - fun get(column: String, row: Int, type: ColumnType): T = getOrNull(column, row, type) ?: type.default + fun get(column: String, row: Int, type: ColumnType): T { + val columnIndex = columns[column] ?: throw IllegalArgumentException("Column $column not found") + return get(row, columnIndex, type) + } - fun get(column: Int, row: Int, type: ColumnType): T = getOrNull(column, row, type) ?: type.default + fun get(column: Int, row: Int, type: ColumnType): T { + val default = type.cast(default[column]) ?: type.default + val id = rows.getOrNull(row) ?: return default + val rows = Rows.getOrNull(id)?.data ?: return default + val value = rows[column] + return type.cast(value) ?: default + } fun getOrNull(column: String, row: Int, type: ColumnType): T? { val columnIndex = columns[column] ?: return null @@ -36,11 +45,7 @@ data class TableDefinition( } fun getOrNull(column: Int, row: Int, type: ColumnType): T? { - return value(row, column, type) - } - - private fun value(row: Int, column: Int, type: ColumnType): T? { - val id = rows.getOrNull(row) ?: return type.default + val id = rows.getOrNull(row) ?: return null val rows = Rows.getOrNull(id)?.data ?: return null val value = rows[column] return type.cast(value) @@ -54,7 +59,7 @@ data class TableDefinition( fun findOrNull(searchColumn: Int, value: Any, column: String, type: ColumnType): T? { val columnIndex = columns[column] ?: return null val row = findOrNull(searchColumn, value) ?: return null - return value(row, columnIndex, type) + return getOrNull(row, columnIndex, type) } fun findOrNull(column: Int, value: Any): Int? { diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/EnumDefinitions.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/EnumDefinitions.kt index e996ccfcb0..e2affacd8e 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/EnumDefinitions.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/EnumDefinitions.kt @@ -9,6 +9,8 @@ import world.gregs.voidps.cache.config.data.StructDefinition import world.gregs.voidps.cache.definition.Params import world.gregs.voidps.cache.definition.data.EnumDefinition import world.gregs.voidps.cache.definition.data.EnumTypes +import world.gregs.voidps.engine.data.config.RowDefinition +import world.gregs.voidps.engine.data.config.TableDefinition import world.gregs.voidps.engine.timedLoad import world.gregs.voidps.type.Tile @@ -76,6 +78,20 @@ object EnumDefinitions : DefinitionsDecoder { return definition.stringOrNull(key) } + fun tableOrNull(enum: String, key: String): TableDefinition? { + val definition = getOrNull(enum) ?: return null + val key = key(definition.keyType, key) + val id = definition.stringOrNull(key) ?: return null + return Tables.getOrNull(id) + } + + fun rowOrNull(enum: String, key: String): RowDefinition? { + val definition = getOrNull(enum) ?: return null + val key = key(definition.keyType, key) + val id = definition.stringOrNull(key) ?: return null + return Rows.getOrNull(id) + } + fun stringOrNull(enum: String, key: Int): String? { val definition = getOrNull(enum) ?: return null return definition.stringOrNull(key) @@ -150,6 +166,7 @@ object EnumDefinitions : DefinitionsDecoder { require(NPCDefinitions.loaded) { "NPC definitions must be loaded before enum definitions" } require(StructDefinitions.loaded) { "Struct definitions must be loaded before enum definitions" } require(ObjectDefinitions.loaded) { "Object definitions must be loaded before enum definitions" } + require(Tables.loaded) { "Tables must be loaded before enum definitions" } val ids = Object2IntOpenHashMap(definitions.size, Hash.VERY_FAST_LOAD_FACTOR) val custom = mutableListOf() for (path in list) { @@ -190,6 +207,7 @@ object EnumDefinitions : DefinitionsDecoder { EnumTypes.NPC -> NPCDefinitions.getOrNull(key)?.id ?: error("Unknown npc '$key' ${exception()}") EnumTypes.STRUCT -> StructDefinitions.getOrNull(key)?.id ?: error("Unknown struct '$key' ${exception()}") EnumTypes.OBJ -> ObjectDefinitions.getOrNull(key)?.id ?: error("Unknown struct '$key' ${exception()}") + EnumTypes.DBROW -> Rows.getOrNull(key)?.id ?: error("Unknown table row '$key' ${exception()}") else -> key.toInt() } map[keyInt] = value() diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt index 760597ddbf..ff5b3cc19b 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt @@ -154,13 +154,13 @@ object Tables { fun get(path: String, type: ColumnType): T { val (table, row, column) = path.split(".") - val id = Rows.ids[row] ?: error("Row '$row' not found") + val id = Rows.ids["${table}.${row}"] ?: error("Row '$row' not found for $path") return get(table, column, id, type) } private fun getOrNull(path: String, type: ColumnType): T? { val (table, row, column) = path.split(".") - val id = Rows.ids[row] ?: error("Row '$row' not found") + val id = Rows.ids["${table}.${row}"] ?: error("Row '$row' not found for $path") return getOrNull(table, column, id, type) } @@ -222,7 +222,7 @@ object Tables { require(!ids.containsKey(rowName)) { "Duplicate row id found '$rowName' at ${reader.exception()}." } val id = rows.size ids[rowName] = id - rows.add(RowDefinition(row, rowName)) + rows.add(RowDefinition(id, row, rowName)) builder.addRow(id) } diff --git a/game/src/main/kotlin/Main.kt b/game/src/main/kotlin/Main.kt index 5e40ce2e8f..5cc5012e07 100644 --- a/game/src/main/kotlin/Main.kt +++ b/game/src/main/kotlin/Main.kt @@ -130,6 +130,7 @@ object Main { get() get() get() + get() EnumDefinitions.init(EnumDecoder().load(cache)).load(files.list(Settings["definitions.enums"])) } single(createdAtStart = true) { diff --git a/game/src/main/kotlin/content/entity/obj/Picking.kt b/game/src/main/kotlin/content/entity/obj/Picking.kt index 896a4f2a44..e47f73c657 100644 --- a/game/src/main/kotlin/content/entity/obj/Picking.kt +++ b/game/src/main/kotlin/content/entity/obj/Picking.kt @@ -16,20 +16,20 @@ class Picking : Script { init { objectOperate("Pick") { (target) -> - val item = EnumDefinitions.stringOrNull("pickable_item", target.id) ?: return@objectOperate - if (inventory.add(item)) { - sound("pick") - anim("climb_down") - val chance = EnumDefinitions.int("pickable_chance", target.id) - if (random.nextInt(chance) == 0) { - val respawnDelay = EnumDefinitions.int("pickable_respawn_delay", target.id) - target.remove(TimeUnit.SECONDS.toTicks(respawnDelay)) - } - val message = EnumDefinitions.string("pickable_message", target.id) - message(message) - } else { + val pickable = EnumDefinitions.rowOrNull("pickables", target.id) ?: return@objectOperate + val item = pickable.item("item") + if (!inventory.add(item)) { inventoryFull() + return@objectOperate } + sound("pick") + anim("climb_down") + val chance = pickable.int("chance") + if (random.nextInt(chance) == 0) { + val respawnDelay = pickable.int("respawn") + target.remove(TimeUnit.SECONDS.toTicks(respawnDelay)) + } + message(pickable.string("message")) } } } diff --git a/game/src/test/kotlin/WorldTest.kt b/game/src/test/kotlin/WorldTest.kt index f753f60fbc..7e6bf5439b 100644 --- a/game/src/test/kotlin/WorldTest.kt +++ b/game/src/test/kotlin/WorldTest.kt @@ -364,6 +364,7 @@ abstract class WorldTest : KoinTest { npcIds structIds objectIds + tableDefinitions EnumDefinitions.init(EnumDecoder().load(cache)).load(configFiles.list(Settings["definitions.enums"])) EnumDefinitions.definitions } From 21fd6db6e4a91bc9b1936ffa643f3eb17eb515db Mon Sep 17 00:00:00 2001 From: GregHib Date: Thu, 26 Mar 2026 13:21:48 +0000 Subject: [PATCH 11/40] Convert enchanting jewellery --- .../skill/magic/enchant/enchanting.enums.toml | 95 ------------------- .../magic/enchant/enchanting.tables.toml | 62 ++++++++++++ .../engine/data/config/RowDefinition.kt | 2 + .../engine/data/config/TableDefinition.kt | 5 +- .../engine/data/definition/ColumnReader.kt | 6 +- .../voidps/engine/data/definition/Tables.kt | 7 ++ .../magic/book/modern/EnchantJewellery.kt | 59 ++++++++---- 7 files changed, 118 insertions(+), 118 deletions(-) delete mode 100644 data/skill/magic/enchant/enchanting.enums.toml create mode 100644 data/skill/magic/enchant/enchanting.tables.toml diff --git a/data/skill/magic/enchant/enchanting.enums.toml b/data/skill/magic/enchant/enchanting.enums.toml deleted file mode 100644 index 819aaad978..0000000000 --- a/data/skill/magic/enchant/enchanting.enums.toml +++ /dev/null @@ -1,95 +0,0 @@ -[enchant_level_1] -keyType = "item" -valueType = "item" -values = { - sapphire_ring = "ring_of_recoil", - sapphire_necklace = "games_necklace_8", - sapphire_bracelet = "bracelet_of_clay", - sapphire_amulet = "amulet_of_magic", -} - -[enchant_level_2] -keyType = "item" -valueType = "item" -values = { - emerald_ring = "ring_of_duelling_8", - emerald_necklace = "binding_necklace", - emerald_bracelet = "castle_wars_brace_3", - emerald_amulet = "amulet_of_defence", -} - -[enchant_level_3] -keyType = "item" -valueType = "item" -values = { - ruby_ring = "ring_of_forging", - ruby_necklace = "dig_site_pendant_5", - ruby_bracelet = "inoculation_brace", - ruby_amulet = "amulet_of_strength", -} - -[enchant_level_4] -keyType = "item" -valueType = "item" -values = { - diamond_ring = "ring_of_life", - diamond_necklace = "phoenix_necklace", - diamond_bracelet = "forinthry_bracelet_5", - diamond_amulet = "amulet_of_power", -} - -[enchant_level_5] -keyType = "item" -valueType = "item" -values = { - dragonstone_ring = "ring_of_wealth", - dragon_necklace = "skills_necklace", - dragonstone_bracelet = "combat_bracelet", - dragonstone_amulet = "amulet_of_glory", -} - -[enchant_level_6] -keyType = "item" -valueType = "item" -values = { - onyx_ring = "ring_of_stone", - onyx_necklace = "berserker_necklace", - onyx_bracelet = "regen_bracelet", - onyx_amulet = "amulet_of_fury", -} - -[enchant_level] -keyType = "int" -valueType = "int" -values = { - 1 = 7, - 2 = 27, - 3 = 49, - 4 = 57, - 5 = 68, - 6 = 87, -} - -[enchant_xp] -keyType = "int" -valueType = "int" -values = { - 1 = 175, - 2 = 370, - 3 = 590, - 4 = 670, - 5 = 780, - 6 = 970, -} - -[enchant_type] -keyType = "int" -valueType = "string" -values = { - 1 = "sapphire", - 2 = "emerald", - 3 = "ruby", - 4 = "diamond", - 5 = "dragonstone", - 6 = "onyx", -} \ No newline at end of file diff --git a/data/skill/magic/enchant/enchanting.tables.toml b/data/skill/magic/enchant/enchanting.tables.toml new file mode 100644 index 0000000000..e80e7b520e --- /dev/null +++ b/data/skill/magic/enchant/enchanting.tables.toml @@ -0,0 +1,62 @@ +[jewellery_enchant] +level = "int" +xp = "int" +type = "string" +ring = "pair" +necklace = "pair" +bracelet = "pair" +amulet = "pair" + +[.enchant_level_1] +level = 7 +xp = 175 +type = "sapphire" +ring = ["sapphire_ring", "ring_of_recoil"] +necklace = ["sapphire_necklace", "games_necklace_8"] +bracelet = ["sapphire_bracelet", "bracelet_of_clay"] +amulet = ["sapphire_amulet", "amulet_of_magic"] + +[.enchant_level_2] +level = 27 +xp = 370 +type = "emerald" +ring = ["emerald_ring", "ring_of_duelling_8"] +necklace = ["emerald_necklace", "binding_necklace"] +bracelet = ["emerald_bracelet", "castle_wars_brace_3"] +amulet = ["emerald_amulet", "amulet_of_defence"] + +[.enchant_level_3] +level = 49 +xp = 590 +type = "ruby" +ring = ["ruby_ring", "ring_of_forging"] +necklace = ["ruby_necklace", "dig_site_pendant_5"] +bracelet = ["ruby_bracelet", "inoculation_brace"] +amulet = ["ruby_amulet", "amulet_of_strength"] + +[.enchant_level_4] +level = 57 +xp = 670 +type = "diamond" +ring = ["diamond_ring", "ring_of_life"] +necklace = ["diamond_necklace", "phoenix_necklace"] +bracelet = ["diamond_bracelet", "forinthry_bracelet_5"] +amulet = ["diamond_amulet", "amulet_of_power"] + +[.enchant_level_5] +level = 68 +xp = 780 +type = "dragonstone" +ring = ["dragonstone_ring", "ring_of_wealth"] +necklace = ["dragon_necklace", "skills_necklace"] +bracelet = ["dragonstone_bracelet", "combat_bracelet"] +amulet = ["dragonstone_amulet", "amulet_of_glory"] + +[.enchant_level_6] +level = 87 +xp = 970 +type = "onyx" +ring = ["onyx_ring", "ring_of_stone"] +necklace = ["onyx_necklace", "berserker_necklace"] +bracelet = ["onyx_bracelet", "regen_bracelet"] +amulet = ["onyx_amulet", "amulet_of_fury"] diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt index 2bdc2a8ef7..82f1888337 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt @@ -15,6 +15,8 @@ data class RowDefinition( fun intOrNull(column: String) = Tables.intOrNull("${stringId}.$column") + fun itemPair(column: String) = Tables.itemPair("${stringId}.$column") + fun string(column: String) = Tables.string("${stringId}.$column") fun stringOrNull(column: String) = Tables.stringOrNull("${stringId}.$column") diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt index 4384877828..e3198f5d85 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt @@ -28,13 +28,12 @@ data class TableDefinition( fun get(column: String, row: Int, type: ColumnType): T { val columnIndex = columns[column] ?: throw IllegalArgumentException("Column $column not found") - return get(row, columnIndex, type) + return get(columnIndex, row, type) } fun get(column: Int, row: Int, type: ColumnType): T { val default = type.cast(default[column]) ?: type.default - val id = rows.getOrNull(row) ?: return default - val rows = Rows.getOrNull(id)?.data ?: return default + val rows = Rows.getOrNull(row)?.data ?: return default val value = rows[column] return type.cast(value) ?: default } diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnReader.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnReader.kt index f2e93dd06c..d463387483 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnReader.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnReader.kt @@ -94,13 +94,13 @@ sealed interface ColumnReader { "item" -> ReaderEntity(ItemDefinitions.ids) "obj" -> ReaderEntity(ObjectDefinitions.ids) "row" -> ReaderEntity(Rows.ids) - else -> if (name.startsWith("Pair<")) { + else -> if (name.startsWith("pair<", ignoreCase = true)) { val (first, second) = name.substringAfter("<").removeSuffix(">").split(",") ReaderPair(reader(first.trim()), reader(second.trim())) - } else if (name.startsWith("Triple<")) { + } else if (name.startsWith("triple<", ignoreCase = true)) { val (first, second, third) = name.substringAfter("<").removeSuffix(">").split(",") ReaderTriple(reader(first.trim()), reader(second.trim()), reader(third.trim())) - } else if (name.startsWith("List<") && name.endsWith(">")) { + } else if (name.startsWith("list<", ignoreCase = true) && name.endsWith(">")) { val type = name.substringAfter("<").substringBefore(">") ReaderList(reader(type)) } else { diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt index ff5b3cc19b..11ec7a35c4 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt @@ -119,6 +119,13 @@ object Tables { Primitive Pairs */ + fun itemPair(path: String): Pair { + val pair = get(path, ColumnType.IntIntPair) + val first = ItemDefinitions.get(pair.first).stringId + val second = ItemDefinitions.get(pair.second).stringId + return Pair(first, second) + } + fun intPair(path: String): Pair = get(path, ColumnType.IntIntPair) fun intPairOrNull(path: String): Pair? = getOrNull(path, ColumnType.IntIntPair) diff --git a/game/src/main/kotlin/content/skill/magic/book/modern/EnchantJewellery.kt b/game/src/main/kotlin/content/skill/magic/book/modern/EnchantJewellery.kt index 3991b988e7..4a4a1ead90 100644 --- a/game/src/main/kotlin/content/skill/magic/book/modern/EnchantJewellery.kt +++ b/game/src/main/kotlin/content/skill/magic/book/modern/EnchantJewellery.kt @@ -5,11 +5,13 @@ import world.gregs.voidps.engine.Script import world.gregs.voidps.engine.client.message import world.gregs.voidps.engine.client.variable.hasClock import world.gregs.voidps.engine.client.variable.start -import world.gregs.voidps.engine.data.definition.EnumDefinitions +import world.gregs.voidps.engine.data.definition.Rows +import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.character.player.skill.Skill import world.gregs.voidps.engine.entity.character.player.skill.exp.exp import world.gregs.voidps.engine.entity.character.player.skill.level.Level.has import world.gregs.voidps.engine.entity.character.sound +import world.gregs.voidps.engine.entity.item.Item import world.gregs.voidps.engine.inv.inventory import world.gregs.voidps.engine.inv.transact.TransactionError import world.gregs.voidps.engine.inv.transact.operation.ReplaceItem.replace @@ -21,21 +23,20 @@ class EnchantJewellery : Script { return@onItem } val spell = id.substringAfter(":") - val enchanted = EnumDefinitions.stringOrNull(spell, item.id) - val enchantLevel = spell.substringAfterLast("_").toInt() - val type = EnumDefinitions.string("enchant_type", enchantLevel) - if (enchanted == null) { + val product = find(item) + val type = Tables.string("jewellery_enchant.$spell.type") + if (product == null) { message("This spell can only be cast on $type amulets, necklaces, rings and bracelets.") return@onItem } - val level = EnumDefinitions.int("enchant_level", enchantLevel) + val level = Tables.int("jewellery_enchant.$spell.level") if (!has(Skill.Magic, level)) { return@onItem } start("action_delay", 1) inventory.transaction { removeItems(this@onItem, spell, message = false) - replace(item.id, enchanted) + replace(item.id, product) } when (inventory.transaction.error) { is TransactionError.Deficient -> { @@ -45,13 +46,13 @@ class EnchantJewellery : Script { } TransactionError.None -> { if (item.id.endsWith("necklace") || item.id.endsWith("amulet")) { - gfx("enchant_jewellery_$enchantLevel") + gfx(spell.replace("_level_", "_jewellery_")) anim( - when (enchantLevel) { - 1 -> "enchant_jewellery_1" - 2 -> "enchant_jewellery_2" + when (spell) { + "enchant_level_1" -> "enchant_jewellery_1" + "enchant_level_2" -> "enchant_jewellery_2" else -> "enchant_jewellery_3" - }, + } ) sound("enchant_${type}_amulet") } else if (item.id.endsWith("ring")) { @@ -62,18 +63,42 @@ class EnchantJewellery : Script { gfx("enchant_ring") sound("enchant_${type}_amulet") anim( - when (enchantLevel) { - 1 -> "enchant_jewellery_1" - 2 -> "enchant_jewellery_2" + when (spell) { + "enchant_level_1" -> "enchant_jewellery_1" + "enchant_level_2" -> "enchant_jewellery_2" else -> "enchant_jewellery_3" - }, + } ) } - val xp = EnumDefinitions.int("enchant_xp", enchantLevel) / 10.0 + val xp = Tables.int("jewellery_enchant.$spell.xp") / 10.0 exp(Skill.Magic, xp) } else -> return@onItem } } } + + private fun find(item: Item): String? { + val enchanted = Tables.getOrNull("jewellery_enchant") ?: return null + for (id in enchanted.rows) { + val row = Rows.get(id) + val (ring, enchantedRing) = row.itemPair("ring") + if (ring == item.id) { + return enchantedRing + } + val (necklace, enchantedNecklace) = row.itemPair("necklace") + if (necklace == item.id) { + return enchantedNecklace + } + val (bracelet, enchantedBracelet) = row.itemPair("bracelet") + if (bracelet == item.id) { + return enchantedBracelet + } + val (amulet, enchantedAmulet) = row.itemPair("amulet") + if (amulet == item.id) { + return enchantedAmulet + } + } + return null + } } From b30e7560bb6f2e57ddb85fd02bf5484fb8f66d69 Mon Sep 17 00:00:00 2001 From: GregHib Date: Thu, 26 Mar 2026 13:27:25 +0000 Subject: [PATCH 12/40] Convert bolt enchanting to tables --- .../magic/enchant/enchanted_bolts.enums.toml | 32 -------------- .../enchant/enchanting_bolts.tables.toml | 43 +++++++++++++++++++ .../magic/book/modern/EnchantCrossbowBolt.kt | 6 ++- 3 files changed, 47 insertions(+), 34 deletions(-) delete mode 100644 data/skill/magic/enchant/enchanted_bolts.enums.toml create mode 100644 data/skill/magic/enchant/enchanting_bolts.tables.toml diff --git a/data/skill/magic/enchant/enchanted_bolts.enums.toml b/data/skill/magic/enchant/enchanted_bolts.enums.toml deleted file mode 100644 index 3f50f0c8e4..0000000000 --- a/data/skill/magic/enchant/enchanted_bolts.enums.toml +++ /dev/null @@ -1,32 +0,0 @@ -[enchant_bolt_models] -keyType = "item" -valueType = "int" -values = { - opal_bolts = 3818, - sapphire_bolts = 9354, - jade_bolts = 9346, - pearl_bolts = 3822, - emerald_bolts = 9358, - topaz_bolts = 9350, - ruby_bolts = 9362, - diamond_bolts = 9366, - dragon_bolts = 9370, - onyx_bolts = 9374, -} - -[enchant_bolt_levels] -keyType = "item" -valueType = "int" -values = { - opal_bolts = 4, - sapphire_bolts = 7, - jade_bolts = 14, - pearl_bolts = 24, - emerald_bolts = 27, - topaz_bolts = 29, - ruby_bolts = 49, - diamond_bolts = 57, - dragon_bolts = 68, - onyx_bolts = 87, -} - diff --git a/data/skill/magic/enchant/enchanting_bolts.tables.toml b/data/skill/magic/enchant/enchanting_bolts.tables.toml new file mode 100644 index 0000000000..a7dff011a2 --- /dev/null +++ b/data/skill/magic/enchant/enchanting_bolts.tables.toml @@ -0,0 +1,43 @@ +[enchant_bolts] +model = "int" +level = "int" + +[.opal_bolts] +model = 3818 +level = 4 + +[.sapphire_bolts] +model = 9354 +level = 7 + +[.jade_bolts] +model = 9346 +level = 14 + +[.pearl_bolts] +model = 3822 +level = 24 + +[.emerald_bolts] +model = 9358 +level = 27 + +[.topaz_bolts] +model = 9350 +level = 29 + +[.ruby_bolts] +model = 9362 +level = 49 + +[.diamond_bolts] +model = 9366 +level = 57 + +[.dragon_bolts] +model = 9370 +level = 68 + +[.onyx_bolts] +model = 9374 +level = 87 diff --git a/game/src/main/kotlin/content/skill/magic/book/modern/EnchantCrossbowBolt.kt b/game/src/main/kotlin/content/skill/magic/book/modern/EnchantCrossbowBolt.kt index a9a1828bd3..8db7e5467e 100644 --- a/game/src/main/kotlin/content/skill/magic/book/modern/EnchantCrossbowBolt.kt +++ b/game/src/main/kotlin/content/skill/magic/book/modern/EnchantCrossbowBolt.kt @@ -9,6 +9,7 @@ import world.gregs.voidps.engine.client.variable.hasClock import world.gregs.voidps.engine.client.variable.start import world.gregs.voidps.engine.data.definition.EnumDefinitions import world.gregs.voidps.engine.data.definition.SpellDefinitions +import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.skill.Skill import world.gregs.voidps.engine.entity.character.player.skill.exp.exp @@ -43,7 +44,7 @@ class EnchantCrossbowBolt( interfaceOpened("enchant_crossbow_bolts") { for (it in set) { - interfaces.sendItem("enchant_crossbow_bolts", "${it}_bolt", EnumDefinitions.int("enchant_bolt_models", "${it}_bolts")) + interfaces.sendItem("enchant_crossbow_bolts", "${it}_bolt", Tables.int("enchant_bolts.${it}_bolts.model")) } } @@ -67,7 +68,8 @@ class EnchantCrossbowBolt( if (hasClock("action_delay")) { return } - if (!has(Skill.Magic, EnumDefinitions.int("enchant_bolt_levels", "${type}_bolts"))) { + + if (!has(Skill.Magic, Tables.int("enchant_bolts.${type}_bolts.level"))) { return } val runes = when (type) { From 4432c6f401a71dcbcd6eb013f31599b7b15bc64f Mon Sep 17 00:00:00 2001 From: GregHib Date: Thu, 26 Mar 2026 14:12:57 +0000 Subject: [PATCH 13/40] Convert cooking enums to tables --- data/skill/cooking/cooking.enums.toml | 1009 ----------------- data/skill/cooking/cooking.tables.toml | 798 +++++++++++++ .../engine/data/config/RowDefinition.kt | 8 + .../kotlin/content/skill/cooking/Cooking.kt | 41 +- 4 files changed, 827 insertions(+), 1029 deletions(-) delete mode 100644 data/skill/cooking/cooking.enums.toml create mode 100644 data/skill/cooking/cooking.tables.toml diff --git a/data/skill/cooking/cooking.enums.toml b/data/skill/cooking/cooking.enums.toml deleted file mode 100644 index a2d95dea6e..0000000000 --- a/data/skill/cooking/cooking.enums.toml +++ /dev/null @@ -1,1009 +0,0 @@ -[cooking_level] -keyType = "item" -valueType = "int" -defaultInt = 1 -values = { - raw_cavefish = 88, - raw_rocktail = 92, - raw_cave_eel = 38, - thin_snail = 12, - lean_snail = 17, - fat_snail = 22, - slimy_eel = 28, - mixed_saturday_poured = 53, - mixed_dragon_garnished = 32, - spider_on_stick_raw = 16, - spider_on_shaft_raw = 16, - skewered_chompy = 30, - nettle_water = 20, - crab_meat = 21, - raw_fishcake = 31, - raw_guide_cake = 40, - raw_jubbly = 41, - skewered_rabbit = 16, - raw_monkfish = 62, - pitta_dough = 58, - chopped_onion = 42, - uncooked_cake = 40, - raw_potato = 7, - uncooked_stew = 25, - uncooked_curry = 60, - raw_lava_eel = 53, - uncooked_pizza = 35, - uncooked_apple_pie = 30, - uncooked_meat_pie = 20, - uncooked_berry_pie = 10, - uncooked_egg = 13, - sliced_mushrooms = 46, - raw_mud_pie = 29, - raw_garden_pie = 34, - raw_fish_pie = 47, - raw_admiral_pie = 70, - raw_wild_pie = 85, - raw_summer_pie = 95, - sweetcorn = 28, - raw_salmon = 25, - raw_trout = 15, - raw_cod = 18, - raw_herring = 5, - raw_pike = 20, - raw_mackerel = 10, - raw_tuna = 30, - raw_bass = 43, - raw_swordfish = 45, - raw_lobster = 40, - raw_shark = 80, - raw_manta_ray = 91, - raw_sea_turtle = 82, - raw_karambwan = 30, - raw_rainbow_fish = 35, - raw_bird_meat = 11, - raw_beast_meat = 21, -} - -[cooking_xp] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - raw_cavefish = 2140, - raw_rocktail = 2250, - raw_cave_eel = 1150, - thin_snail = 700, - lean_snail = 800, - fat_snail = 950, - slimy_eel = 950, - mixed_dragon_garnished = 1300, - spider_on_stick_raw = 800, - spider_on_shaft_raw = 800, - skewered_chompy = 1000, - raw_yak_meat = 400, - nettle_water = 520, - crab_meat = 1000, - raw_fishcake = 1000, - raw_guide_cake = 600, - raw_jubbly = 1600, - raw_rabbit = 300, - skewered_rabbit = 720, - raw_monkfish = 1500, - raw_ugthanki_meat = 400, - pitta_dough = 400, - chopped_onion = 600, - uncooked_cake = 1800, - raw_potato = 150, - uncooked_stew = 1170, - uncooked_curry = 2800, - raw_beef = 300, - raw_rat_meat = 300, - raw_bear_meat = 300, - raw_chicken = 300, - raw_lava_eel = 300, - uncooked_pizza = 1430, - bread_dough = 400, - uncooked_apple_pie = 1300, - uncooked_meat_pie = 1100, - uncooked_berry_pie = 780, - uncooked_egg = 500, - sliced_mushrooms = 600, - raw_mud_pie = 1280, - raw_garden_pie = 1380, - raw_fish_pie = 1640, - raw_admiral_pie = 2100, - raw_wild_pie = 2400, - raw_summer_pie = 2600, - sweetcorn = 1040, - raw_shrimps = 300, - raw_anchovies = 300, - raw_sardine = 400, - raw_salmon = 900, - raw_trout = 700, - raw_cod = 750, - raw_herring = 500, - raw_pike = 800, - raw_mackerel = 600, - raw_tuna = 1000, - raw_bass = 1300, - raw_swordfish = 1400, - raw_lobster = 1200, - raw_shark = 2100, - raw_manta_ray = 2163, - raw_sea_turtle = 2113, - raw_karambwan = 1900, - raw_rainbow_fish = 1100, - raw_crayfish = 300, - raw_bird_meat = 625, - raw_beast_meat = 620, - raw_pawya_meat = 300, - sinew = 30, -} - -[cooked_id] -keyType = "item" -valueType = "string" -defaultString = "" -values = { - raw_cavefish = "cavefish", - raw_rocktail = "rocktail", - raw_cave_eel = "cave_eel", - thin_snail = "thin_snail_meat", - lean_snail = "lean_snail_meat", - fat_snail = "fat_snail_meat", - slimy_eel = "cooked_slimy_eel", - mixed_saturday_poured = "mixed_saturday_heated", - mixed_dragon_garnished = "drunk_dragon", - spider_on_stick_raw = "spider_on_stick", - spider_on_shaft_raw = "spider_on_shaft", - skewered_chompy = "cooked_chompy", - troll_thistle = "dried_thistle", - raw_yak_meat = "cooked_meat", - nettle_water = "nettle_tea", - crab_meat = "cooked_crab_meat_5", - raw_guide_cake = "cake_of_guidance", - skewered_rabbit = "roast_rabbit", - raw_monkfish = "monkfish", - raw_ugthanki_meat = "ugthanki_meat", - pitta_dough = "pitta_bread", - chopped_onion = "fried_onions", - uncooked_cake = "cake", - raw_potato = "baked_potato", - uncooked_stew = "stew", - uncooked_curry = "curry", - raw_beef = "cooked_meat", - raw_rat_meat = "cooked_meat", - raw_bear_meat = "cooked_meat", - raw_lava_eel = "lava_eel", - uncooked_pizza = "plain_pizza", - bread_dough = "bread", - uncooked_apple_pie = "apple_pie", - uncooked_meat_pie = "meat_pie", - uncooked_berry_pie = "redberry_pie", - uncooked_egg = "scrambled_egg", - sliced_mushrooms = "fried_mushrooms", - raw_mud_pie = "mud_pie", - raw_garden_pie = "garden_pie", - raw_fish_pie = "fish_pie", - raw_admiral_pie = "admiral_pie", - raw_wild_pie = "wild_pie", - raw_summer_pie = "summer_pie", - sweetcorn = "cooked_sweetcorn", - raw_shrimps = "shrimps", - raw_anchovies = "anchovies", - raw_sardine = "sardine", - raw_salmon = "salmon", - raw_trout = "trout", - raw_cod = "cod", - raw_herring = "herring", - raw_pike = "pike", - raw_mackerel = "mackerel", - raw_tuna = "tuna", - raw_bass = "bass", - raw_swordfish = "swordfish", - raw_lobster = "lobster", - raw_shark = "shark", - raw_manta_ray = "manta_ray", - raw_sea_turtle = "sea_turtle", - raw_rainbow_fish = "rainbow_fish", - raw_crayfish = "crayfish", - raw_bird_meat = "roast_bird_meat", - raw_beast_meat = "roast_beast_meat", - raw_pawya_meat = "cooked_meat", - sinew = "sinew", -} - -[cooked_message] -keyType = "item" -valueType = "string" -defaultString = "" -values = { - raw_rocktail = "You successfully cook a rocktail.", - raw_cave_eel = "You successfully cook a slimy cave eel.", - thin_snail = "You cook the thin snail.", - lean_snail = "You cook the lean snail.", - fat_snail = "You cook the fat snail.", - slimy_eel = "You cook an eel.", - troll_thistle = "You dry the troll thistle over the fire.", - nettle_water = "You boil the water and make nettle tea.", - raw_fishcake = "You manage to cook a fishcake.", - raw_guide_cake = "You successfully bake a Cake of Guidance.", - raw_rabbit = "You cook the rabbit.", - skewered_rabbit = "You roast the skewered rabbit.", - raw_monkfish = "You successfully cook a monkfish.", - pitta_dough = "You successfully bake some pitta bread.", - chopped_onion = "You successfully fry the onion.", - uncooked_cake = "You successfully bake a cake.", - raw_potato = "You successfully bake a potato.", - uncooked_stew = "You cook some stew.", - uncooked_curry = "You cook some curry.", - raw_beef = "You cook a piece of meat.", - raw_rat_meat = "You cook a piece of meat.", - raw_bear_meat = "You cook a piece of meat.", - raw_chicken = "You cook some chicken.", - uncooked_pizza = "You successfully bake a pizza.", - bread_dough = "You successfully bake some bread.", - uncooked_apple_pie = "You successfully bake a traditional apple pie.", - uncooked_meat_pie = "You successfully bake a tasty meat pie.", - uncooked_berry_pie = "You successfully bake a delicious redberry pie.", - uncooked_egg = "You successfully scramble the egg.", - sliced_mushrooms = "You successfully fry the mushroom.", - raw_mud_pie = "You successfully bake a mucky mud pie.", - raw_garden_pie = "You successfully bake a tasty garden pie.", - raw_fish_pie = "You successfully bake a tasty fish pie.", - raw_admiral_pie = "You successfully bake a tasty fish pie.", - raw_wild_pie = "You successfully bake a tasty wild pie.", - raw_summer_pie = "You successfully bake a tasty summer pie.", - sweetcorn = "You cook some sweetcorn.", - raw_shrimps = "You successfully cook some shrimps.", - raw_anchovies = "You successfully cook some anchovies.", - raw_sardine = "You successfully cook a sardine.", - raw_salmon = "You successfully cook a salmon.", - raw_trout = "You successfully cook a trout.", - raw_cod = "You successfully cook a cod.", - raw_herring = "You successfully cook a herring.", - raw_pike = "You successfully cook a pike.", - raw_mackerel = "You successfully cook a mackerel.", - raw_tuna = "You manage to cook a tuna.", - raw_bass = "You cook a bass.", - raw_swordfish = "You successfully cook a swordfish.", - raw_lobster = "You roast a lobster.", - raw_shark = "You successfully cook a shark.", - raw_manta_ray = "You successfully cook a manta ray.", - raw_sea_turtle = "You successfully cook a sea turtle.", - raw_karambwan = "You cook the karambwan. It looks delicious.", - raw_rainbow_fish = "You manage to cook a rainbow fish.", - raw_crayfish = "You successfully cook some crayfish.", - sinew = "You dry a piece of beef and extract the sinew.", -} - -[burnt_id] -keyType = "item" -valueType = "string" -defaultString = "" -values = { - thin_snail = "burnt_snail", - lean_snail = "burnt_snail", - fat_snail = "burnt_snail", - slimy_eel = "burnt_eel", - spider_on_stick_raw = "burnt_spider", - spider_on_shaft_raw = "spider_on_shaft_burnt", - skewered_chompy = "burnt_chompy", - raw_yak_meat = "burnt_meat", - crab_meat = "burnt_crab_meat", - skewered_rabbit = "You accidentally burn the skewered rabbit.", - pitta_dough = "burnt_pitta_bread", - chopped_onion = "burnt_onion", - uncooked_cake = "burnt_cake", - uncooked_stew = "burnt_stew", - uncooked_curry = "burnt_curry", - raw_beef = "burnt_meat", - raw_rat_meat = "burnt_meat", - raw_bear_meat = "burnt_meat", - uncooked_pizza = "burnt_pizza", - bread_dough = "burnt_bread", - uncooked_apple_pie = "burnt_pie", - uncooked_meat_pie = "burnt_pie", - uncooked_berry_pie = "burnt_pie", - uncooked_egg = "burnt_egg", - sliced_mushrooms = "burnt_mushroom", - raw_mud_pie = "burnt_pie", - raw_garden_pie = "burnt_pie", - raw_fish_pie = "burnt_pie", - raw_admiral_pie = "burnt_pie", - raw_wild_pie = "burnt_pie", - raw_summer_pie = "burnt_pie", - sweetcorn = "burnt_sweetcorn", - raw_shrimps = "burnt_shrimp", - raw_cod = "burnt_trout", - raw_mackerel = "burnt_herring", - raw_pawya_meat = "burnt_meat", -} - -[burnt_message] -keyType = "item" -valueType = "string" -defaultString = "" -values = { - raw_rocktail = "You accidentally burn the rocktail.", - raw_cave_eel = "You accidentally burn the cave eel.", - thin_snail = "You accidentally burn the thin snail.", - lean_snail = "You accidentally burn the lean snail.", - fat_snail = "You accidentally burn the fat snail.", - slimy_eel = "You accidentally burn the slimy eel.", - raw_fishcake = "You accidentally burn the uncooked cake.", - raw_rabbit = "You accidentally burn the rabbit.", - raw_monkfish = "You accidentally burn the monkfish.", - pitta_dough = "You accidentally burn the pitta dough.", - chopped_onion = "You accidentally burn the onion.", - uncooked_cake = "You accidentally burn the uncooked cake.", - raw_potato = "You accidentally burn the potato.", - uncooked_stew = "You accidentally burn the stew.", - uncooked_curry = "You accidentally burn the curry.", - raw_beef = "You accidentally burn the beef.", - raw_rat_meat = "You accidentally burn the rat meat.", - raw_bear_meat = "You accidentally burn the bear meat.", - raw_chicken = "You accidentally burn the chicken.", - uncooked_pizza = "You accidentally burn the uncooked pizza.", - bread_dough = "You accidentally burn the bread dough.", - uncooked_apple_pie = "You accidentally burn the uncooked apple pie.", - uncooked_meat_pie = "You accidentally burn the uncooked meat pie.", - uncooked_berry_pie = "You accidentally burn the uncooked berry pie.", - uncooked_egg = "You accidentally burn the egg.", - sliced_mushrooms = "You accidentally burn the mushroom.", - raw_mud_pie = "You accidentally burn the mud pie.", - raw_garden_pie = "You accidentally burn the garden pie.", - raw_fish_pie = "You accidentally burn the fish pie.", - raw_admiral_pie = "You accidentally burn the admiral pie.", - raw_wild_pie = "You accidentally burn the wild pie.", - raw_summer_pie = "You accidentally burn the summer pie.", - sweetcorn = "You accidentally burn the sweetcorn.", - raw_shrimps = "You accidentally burn the shrimps.", - raw_anchovies = "You accidentally burn the anchovies.", - raw_sardine = "You accidentally burn the sardine.", - raw_salmon = "You accidentally burn the salmon.", - raw_trout = "You accidentally burn the trout.", - raw_cod = "You accidentally burn the cod.", - raw_herring = "You accidentally burn the herring.", - raw_pike = "You accidentally burn the pike.", - raw_mackerel = "You accidentally burn the mackerel.", - raw_tuna = "You accidentally burn the tuna.", - raw_bass = "You accidentally burn the bass.", - raw_swordfish = "You accidentally burn the swordfish.", - raw_lobster = "You accidentally burn the lobster.", - raw_shark = "You accidentally burn the shark.", - raw_manta_ray = "You accidentally burn the manta ray.", - raw_sea_turtle = "You accidentally burn the sea turtle.", - raw_karambwan = "You accidentally burn the karambwan.", - raw_rainbow_fish = "You accidentally burn the rainbow fish.", - raw_crayfish = "You accidentally burn the crayfish.", -} - -[cooking_leftover] -keyType = "item" -valueType = "string" -defaultString = "" -values = { - raw_guide_cake = "cake_tin", - uncooked_cake = "cake_tin", -} - -[cooking_type] -keyType = "item" -valueType = "string" -defaultString = "cook" -values = { - spider_on_stick_raw = "roast", - spider_on_shaft_raw = "roast", - skewered_chompy = "roast", - troll_thistle = "heat", - nettle_water = "heat", - raw_guide_cake = "bake", - skewered_rabbit = "roast", - raw_mud_pie = "bake", - raw_garden_pie = "bake", - raw_fish_pie = "bake", - raw_admiral_pie = "bake", - raw_wild_pie = "bake", - raw_summer_pie = "bake", - raw_lobster = "roast", - raw_bird_meat = "roast", - raw_beast_meat = "roast", - sinew = "heat", -} - -[cooking_start_ticks] -keyType = "item" -valueType = "int" -defaultInt = 1 -values = { - troll_thistle = 4, - uncooked_egg = 0, -} - -[cooking_ticks] -keyType = "item" -valueType = "int" -defaultInt = 4 -values = { - raw_jubbly = 6, - skewered_rabbit = 3, -} - -[cooking_range_only] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - mixed_saturday_poured = 1, - mixed_dragon_garnished = 1, - raw_guide_cake = 1, - pitta_dough = 1, - chopped_onion = 1, - uncooked_cake = 1, - raw_potato = 1, - uncooked_pizza = 1, - bread_dough = 1, - uncooked_apple_pie = 1, - uncooked_meat_pie = 1, - uncooked_berry_pie = 1, - uncooked_egg = 1, - sliced_mushrooms = 1, - raw_mud_pie = 1, - raw_garden_pie = 1, - raw_fish_pie = 1, - raw_admiral_pie = 1, - raw_wild_pie = 1, - raw_summer_pie = 1, - sweetcorn = 1, - sinew = 1, -} - -[cooking_fire_chance_min] -keyType = "item" -valueType = "int" -defaultInt = 255 -values = { - raw_cavefish = 4, - raw_rocktail = 1, - raw_cave_eel = 38, - thin_snail = 93, - lean_snail = 93, - fat_snail = 73, - slimy_eel = 63, - spider_on_stick_raw = 91, - spider_on_shaft_raw = 91, - skewered_chompy = 200, - raw_yak_meat = 128, - crab_meat = 57, - raw_fishcake = 57, - raw_jubbly = 50, - raw_rabbit = 128, - skewered_rabbit = 160, - raw_monkfish = 11, - raw_ugthanki_meat = 40, - uncooked_stew = 68, - uncooked_curry = 38, - raw_beef = 128, - raw_rat_meat = 128, - raw_bear_meat = 128, - raw_chicken = 128, - raw_lava_eel = 0, - raw_shrimps = 128, - raw_anchovies = 128, - raw_sardine = 118, - raw_salmon = 68, - raw_trout = 88, - raw_cod = 83, - raw_herring = 108, - raw_pike = 78, - raw_mackerel = 98, - raw_tuna = 58, - raw_bass = 33, - raw_swordfish = 18, - raw_lobster = 38, - raw_shark = 1, - raw_manta_ray = 1, - raw_sea_turtle = 1, - raw_karambwan = 70, - raw_rainbow_fish = 56, - raw_crayfish = 128, - raw_bird_meat = 155, - raw_beast_meat = 180, - raw_pawya_meat = 128, -} - -[cooking_fire_chance_max] -keyType = "item" -valueType = "int" -defaultInt = 255 -values = { - raw_cavefish = 229, - raw_rocktail = 179, - raw_cave_eel = 331, - thin_snail = 443, - lean_snail = 443, - fat_snail = 401, - slimy_eel = 381, - spider_on_stick_raw = 437, - spider_on_shaft_raw = 437, - skewered_chompy = 254, - raw_yak_meat = 511, - crab_meat = 376, - raw_fishcake = 376, - raw_jubbly = 259, - raw_rabbit = 511, - skewered_rabbit = 254, - raw_monkfish = 274, - raw_ugthanki_meat = 251, - uncooked_stew = 391, - uncooked_curry = 331, - raw_beef = 511, - raw_rat_meat = 511, - raw_bear_meat = 511, - raw_chicken = 511, - raw_lava_eel = -1, - raw_shrimps = 511, - raw_anchovies = 511, - raw_sardine = 491, - raw_salmon = 391, - raw_trout = 431, - raw_cod = 421, - raw_herring = 471, - raw_pike = 411, - raw_mackerel = 451, - raw_tuna = 371, - raw_bass = 311, - raw_swordfish = 291, - raw_lobster = 331, - raw_shark = 201, - raw_manta_ray = 201, - raw_sea_turtle = 201, - raw_karambwan = 254, - raw_rainbow_fish = 369, - raw_crayfish = 511, - raw_bird_meat = 254, - raw_beast_meat = 254, - raw_pawya_meat = 511, -} - -[cooking_range_chance_min] -keyType = "item" -valueType = "int" -defaultInt = 255 -values = { - raw_cavefish = 4, - raw_rocktail = 1, - raw_cave_eel = 38, - thin_snail = 93, - lean_snail = 85, - fat_snail = 73, - slimy_eel = 63, - spider_on_stick_raw = 91, - spider_on_shaft_raw = 91, - skewered_chompy = 200, - raw_yak_meat = 128, - crab_meat = 57, - raw_fishcake = 57, - raw_jubbly = 50, - raw_rabbit = 128, - skewered_rabbit = 160, - raw_monkfish = 13, - raw_ugthanki_meat = 30, - pitta_dough = 118, - chopped_onion = 35, - uncooked_cake = 38, - raw_potato = 108, - uncooked_stew = 68, - uncooked_curry = 38, - raw_beef = 128, - raw_rat_meat = 128, - raw_bear_meat = 128, - raw_chicken = 128, - raw_lava_eel = 0, - uncooked_pizza = 48, - bread_dough = 11, - uncooked_apple_pie = 58, - uncooked_meat_pie = 78, - uncooked_berry_pie = 98, - uncooked_egg = 90, - sliced_mushrooms = 28, - raw_mud_pie = 58, - raw_garden_pie = 48, - raw_fish_pie = 38, - raw_admiral_pie = 15, - raw_wild_pie = 1, - raw_summer_pie = 1, - sweetcorn = 65, - raw_shrimps = 128, - raw_anchovies = 128, - raw_sardine = 118, - raw_salmon = 68, - raw_trout = 88, - raw_cod = 88, - raw_herring = 108, - raw_pike = 78, - raw_mackerel = 98, - raw_tuna = 58, - raw_bass = 33, - raw_swordfish = 30, - raw_lobster = 38, - raw_shark = 1, - raw_manta_ray = 1, - raw_sea_turtle = 1, - raw_karambwan = 70, - raw_rainbow_fish = 56, - raw_crayfish = 128, - raw_bird_meat = 155, - raw_beast_meat = 180, - raw_pawya_meat = 128, -} - -[cooking_range_chance_max] -keyType = "item" -valueType = "int" -defaultInt = 255 -values = { - raw_cavefish = 229, - raw_rocktail = 179, - raw_cave_eel = 331, - thin_snail = 443, - lean_snail = 427, - fat_snail = 401, - slimy_eel = 381, - mixed_saturday_poured = 254, - mixed_dragon_garnished = 254, - spider_on_stick_raw = 437, - spider_on_shaft_raw = 437, - skewered_chompy = 254, - raw_yak_meat = 511, - crab_meat = 376, - raw_fishcake = 376, - raw_guide_cake = 254, - raw_jubbly = 259, - raw_rabbit = 511, - skewered_rabbit = 254, - raw_monkfish = 279, - raw_ugthanki_meat = 252, - pitta_dough = 491, - chopped_onion = 321, - uncooked_cake = 331, - raw_potato = 471, - uncooked_stew = 391, - uncooked_curry = 331, - raw_beef = 511, - raw_rat_meat = 511, - raw_bear_meat = 511, - raw_chicken = 511, - raw_lava_eel = -1, - uncooked_pizza = 351, - bread_dough = 491, - uncooked_apple_pie = 371, - uncooked_meat_pie = 411, - uncooked_berry_pie = 451, - uncooked_egg = 437, - sliced_mushrooms = 299, - raw_mud_pie = 371, - raw_garden_pie = 351, - raw_fish_pie = 331, - raw_admiral_pie = 269, - raw_wild_pie = 221, - raw_summer_pie = 211, - sweetcorn = 381, - raw_shrimps = 511, - raw_anchovies = 511, - raw_sardine = 491, - raw_salmon = 391, - raw_trout = 431, - raw_cod = 431, - raw_herring = 471, - raw_pike = 411, - raw_mackerel = 451, - raw_tuna = 371, - raw_bass = 311, - raw_swordfish = 309, - raw_lobster = 331, - raw_shark = 231, - raw_manta_ray = 221, - raw_sea_turtle = 221, - raw_karambwan = 254, - raw_rainbow_fish = 369, - raw_crayfish = 511, - raw_bird_meat = 254, - raw_beast_meat = 254, - raw_pawya_meat = 511, - sinew = 254, -} - -[cooking_cook_o_matic_chance_min] -keyType = "item" -valueType = "int" -defaultInt = 255 -values = { - raw_cavefish = 4, - raw_rocktail = 1, - raw_cave_eel = 38, - thin_snail = 103, - lean_snail = 95, - fat_snail = 83, - slimy_eel = 63, - spider_on_stick_raw = 91, - spider_on_shaft_raw = 91, - skewered_chompy = 200, - raw_yak_meat = 138, - crab_meat = 57, - raw_fishcake = 57, - raw_jubbly = 50, - raw_rabbit = 128, - skewered_rabbit = 160, - raw_monkfish = 13, - raw_ugthanki_meat = 30, - pitta_dough = 118, - chopped_onion = 35, - uncooked_cake = 38, - raw_potato = 108, - uncooked_stew = 78, - uncooked_curry = 38, - raw_beef = 138, - raw_rat_meat = 138, - raw_bear_meat = 138, - raw_chicken = 138, - raw_lava_eel = 0, - uncooked_pizza = 48, - bread_dough = 128, - uncooked_apple_pie = 58, - uncooked_meat_pie = 88, - uncooked_berry_pie = 108, - uncooked_egg = 90, - sliced_mushrooms = 28, - raw_mud_pie = 58, - raw_garden_pie = 48, - raw_fish_pie = 38, - raw_admiral_pie = 15, - raw_wild_pie = 1, - raw_summer_pie = 1, - sweetcorn = 65, - raw_shrimps = 138, - raw_anchovies = 138, - raw_sardine = 128, - raw_salmon = 78, - raw_trout = 98, - raw_cod = 93, - raw_herring = 118, - raw_pike = 88, - raw_mackerel = 108, - raw_tuna = 58, - raw_bass = 33, - raw_swordfish = 30, - raw_lobster = 38, - raw_shark = 1, - raw_manta_ray = 1, - raw_sea_turtle = 1, - raw_karambwan = 70, - raw_rainbow_fish = 56, - raw_crayfish = 128, - raw_bird_meat = 155, - raw_beast_meat = 180, - raw_pawya_meat = 138, -} - -[cooking_cook_o_matic_chance_max] -keyType = "item" -valueType = "int" -defaultInt = 255 -values = { - raw_cavefish = 229, - raw_rocktail = 179, - raw_cave_eel = 331, - thin_snail = 463, - lean_snail = 447, - fat_snail = 421, - slimy_eel = 381, - mixed_saturday_poured = 254, - mixed_dragon_garnished = 254, - spider_on_stick_raw = 437, - spider_on_shaft_raw = 437, - skewered_chompy = 254, - raw_yak_meat = 531, - crab_meat = 376, - raw_fishcake = 376, - raw_guide_cake = 254, - raw_jubbly = 259, - raw_rabbit = 511, - skewered_rabbit = 254, - raw_monkfish = 279, - raw_ugthanki_meat = 252, - pitta_dough = 491, - chopped_onion = 321, - uncooked_cake = 331, - raw_potato = 471, - uncooked_stew = 411, - uncooked_curry = 331, - raw_beef = 531, - raw_rat_meat = 531, - raw_bear_meat = 531, - raw_chicken = 531, - raw_lava_eel = -1, - uncooked_pizza = 351, - bread_dough = 511, - uncooked_apple_pie = 371, - uncooked_meat_pie = 431, - uncooked_berry_pie = 461, - uncooked_egg = 437, - sliced_mushrooms = 299, - raw_mud_pie = 371, - raw_garden_pie = 351, - raw_fish_pie = 331, - raw_admiral_pie = 269, - raw_wild_pie = 221, - raw_summer_pie = 211, - sweetcorn = 381, - raw_shrimps = 531, - raw_anchovies = 531, - raw_sardine = 511, - raw_salmon = 401, - raw_trout = 451, - raw_cod = 441, - raw_herring = 491, - raw_pike = 431, - raw_mackerel = 471, - raw_tuna = 371, - raw_bass = 311, - raw_swordfish = 309, - raw_lobster = 331, - raw_shark = 231, - raw_manta_ray = 221, - raw_sea_turtle = 221, - raw_karambwan = 254, - raw_rainbow_fish = 369, - raw_crayfish = 511, - raw_bird_meat = 254, - raw_beast_meat = 254, - raw_pawya_meat = 531, - sinew = 254, -} - -[cooking_gauntlet_chance_min] -keyType = "item" -valueType = "int" -defaultInt = 255 -values = { - raw_cavefish = 12, - raw_rocktail = 1, - raw_cave_eel = 38, - thin_snail = 93, - lean_snail = 85, - fat_snail = 73, - slimy_eel = 63, - spider_on_stick_raw = 91, - spider_on_shaft_raw = 91, - skewered_chompy = 200, - raw_yak_meat = 128, - crab_meat = 57, - raw_fishcake = 57, - raw_jubbly = 50, - raw_rabbit = 128, - skewered_rabbit = 160, - raw_monkfish = 24, - raw_ugthanki_meat = 30, - pitta_dough = 118, - chopped_onion = 35, - uncooked_cake = 38, - raw_potato = 108, - uncooked_stew = 68, - uncooked_curry = 38, - raw_beef = 128, - raw_rat_meat = 128, - raw_bear_meat = 128, - raw_chicken = 128, - raw_lava_eel = 0, - uncooked_pizza = 48, - bread_dough = 11, - uncooked_apple_pie = 58, - uncooked_meat_pie = 78, - uncooked_berry_pie = 98, - uncooked_egg = 90, - sliced_mushrooms = 28, - raw_mud_pie = 58, - raw_garden_pie = 48, - raw_fish_pie = 38, - raw_admiral_pie = 15, - raw_wild_pie = 1, - raw_summer_pie = 1, - sweetcorn = 65, - raw_shrimps = 128, - raw_anchovies = 128, - raw_sardine = 118, - raw_salmon = 68, - raw_trout = 88, - raw_cod = 88, - raw_herring = 108, - raw_pike = 78, - raw_mackerel = 98, - raw_tuna = 58, - raw_bass = 33, - raw_swordfish = 30, - raw_lobster = 55, - raw_shark = 15, - raw_manta_ray = 1, - raw_sea_turtle = 1, - raw_karambwan = 70, - raw_rainbow_fish = 56, - raw_crayfish = 128, - raw_bird_meat = 155, - raw_beast_meat = 180, - raw_pawya_meat = 128, -} - -[cooking_gauntlet_chance_max] -keyType = "item" -valueType = "int" -defaultInt = 255 -values = { - raw_cavefish = 268, - raw_rocktail = 268, - raw_cave_eel = 331, - thin_snail = 443, - lean_snail = 427, - fat_snail = 401, - slimy_eel = 381, - mixed_saturday_poured = 254, - mixed_dragon_garnished = 254, - spider_on_stick_raw = 437, - spider_on_shaft_raw = 437, - skewered_chompy = 254, - raw_yak_meat = 511, - crab_meat = 376, - raw_fishcake = 376, - raw_guide_cake = 254, - raw_jubbly = 259, - raw_rabbit = 511, - skewered_rabbit = 254, - raw_monkfish = 289, - raw_ugthanki_meat = 252, - pitta_dough = 491, - chopped_onion = 321, - uncooked_cake = 331, - raw_potato = 471, - uncooked_stew = 391, - uncooked_curry = 331, - raw_beef = 511, - raw_rat_meat = 511, - raw_bear_meat = 511, - raw_chicken = 511, - raw_lava_eel = -1, - uncooked_pizza = 351, - bread_dough = 491, - uncooked_apple_pie = 371, - uncooked_meat_pie = 411, - uncooked_berry_pie = 451, - uncooked_egg = 437, - sliced_mushrooms = 299, - raw_mud_pie = 371, - raw_garden_pie = 351, - raw_fish_pie = 331, - raw_admiral_pie = 269, - raw_wild_pie = 221, - raw_summer_pie = 211, - sweetcorn = 381, - raw_shrimps = 511, - raw_anchovies = 511, - raw_sardine = 491, - raw_salmon = 391, - raw_trout = 431, - raw_cod = 431, - raw_herring = 471, - raw_pike = 411, - raw_mackerel = 451, - raw_tuna = 371, - raw_bass = 311, - raw_swordfish = 309, - raw_lobster = 367, - raw_shark = 269, - raw_manta_ray = 221, - raw_sea_turtle = 221, - raw_karambwan = 254, - raw_rainbow_fish = 369, - raw_crayfish = 511, - raw_bird_meat = 254, - raw_beast_meat = 254, - raw_pawya_meat = 511, - sinew = 254, -} \ No newline at end of file diff --git a/data/skill/cooking/cooking.tables.toml b/data/skill/cooking/cooking.tables.toml new file mode 100644 index 0000000000..cc5e4a1f42 --- /dev/null +++ b/data/skill/cooking/cooking.tables.toml @@ -0,0 +1,798 @@ +[cooking] +level = "int" +xp = "int" +cooked = "item" +cooked_message = "string" +leftover = "item" +burnt = "item" +burnt_message = "string" +start_ticks = "int" +ticks = "int" +type = "string" +type_default = "cook" +range_only = "boolean" +chance_fire = "range" +chance_range = "range" +chance_cook_o_matic = "range" +chance_gauntlet = "range" + +[.bread_dough] +level = 1 +xp = 400 +range_only = true +chance_range = [11, 491] +chance_cook_o_matic = [128, 511] +chance_gauntlet = [11, 491] +cooked = "bread" +cooked_message = "You successfully bake some bread." +burnt = "burnt_bread" +burnt_message = "You accidentally burn the bread dough." + +[.chopped_onion] +level = 42 +xp = 600 +range_only = true +chance_range = [35, 321] +chance_cook_o_matic = [35, 321] +chance_gauntlet = [35, 321] +cooked = "fried_onions" +cooked_message = "You successfully fry the onion." +burnt = "burnt_onion" +burnt_message = "You accidentally burn the onion." + +[.crab_meat] +level = 21 +xp = 1000 +chance_fire = [57, 376] +chance_range = [57, 376] +chance_cook_o_matic = [57, 376] +chance_gauntlet = [57, 376] +cooked = "cooked_crab_meat_5" +burnt = "burnt_crab_meat" + +[.fat_snail] +level = 22 +xp = 950 +chance_fire = [73, 401] +chance_range = [73, 401] +chance_cook_o_matic = [83, 421] +chance_gauntlet = [73, 401] +cooked = "fat_snail_meat" +cooked_message = "You cook the fat snail." +burnt = "burnt_snail" +burnt_message = "You accidentally burn the fat snail." + +[.lean_snail] +level = 17 +xp = 800 +chance_fire = [93, 443] +chance_range = [85, 427] +chance_cook_o_matic = [95, 447] +chance_gauntlet = [85, 427] +cooked = "lean_snail_meat" +cooked_message = "You cook the lean snail." +burnt = "burnt_snail" +burnt_message = "You accidentally burn the lean snail." + +[.mixed_dragon_garnished] +level = 32 +xp = 1300 +range_only = true +chance_range = [255, 254] +chance_cook_o_matic = [255, 254] +chance_gauntlet = [255, 254] +cooked = "drunk_dragon" + +[.nettle_water] +level = 20 +xp = 520 +type = "heat" +chance_range = [255, 255] +chance_cook_o_matic = [255, 255] +chance_gauntlet = [255, 255] +cooked = "nettle_tea" +cooked_message = "You boil the water and make nettle tea." + +[.pitta_dough] +level = 58 +xp = 400 +range_only = true +chance_range = [118, 491] +chance_cook_o_matic = [118, 491] +chance_gauntlet = [118, 491] +cooked = "pitta_bread" +cooked_message = "You successfully bake some pitta bread." +burnt = "burnt_pitta_bread" +burnt_message = "You accidentally burn the pitta dough." + +[.raw_admiral_pie] +level = 70 +xp = 2100 +type = "bake" +range_only = true +chance_range = [15, 269] +chance_cook_o_matic = [15, 269] +chance_gauntlet = [15, 269] +cooked = "admiral_pie" +cooked_message = "You successfully bake a tasty fish pie." +burnt = "burnt_pie" +burnt_message = "You accidentally burn the admiral pie." + +[.raw_anchovies] +level = 1 +xp = 300 +chance_fire = [128, 511] +chance_range = [128, 511] +chance_cook_o_matic = [138, 531] +chance_gauntlet = [128, 511] +cooked = "anchovies" +cooked_message = "You successfully cook some anchovies." +burnt_message = "You accidentally burn the anchovies." + +[.raw_bass] +level = 43 +xp = 1300 +chance_fire = [33, 311] +chance_range = [33, 311] +chance_cook_o_matic = [33, 311] +chance_gauntlet = [33, 311] +cooked = "bass" +cooked_message = "You cook a bass." +burnt_message = "You accidentally burn the bass." + +[.raw_bear_meat] +level = 1 +xp = 300 +chance_fire = [128, 511] +chance_range = [128, 511] +chance_cook_o_matic = [138, 531] +chance_gauntlet = [128, 511] +cooked = "cooked_meat" +cooked_message = "You cook a piece of meat." +burnt = "burnt_meat" +burnt_message = "You accidentally burn the bear meat." + +[.raw_beast_meat] +level = 21 +xp = 620 +type = "roast" +chance_fire = [180, 254] +chance_range = [180, 254] +chance_cook_o_matic = [180, 254] +chance_gauntlet = [180, 254] +cooked = "roast_beast_meat" + +[.raw_beef] +level = 1 +xp = 300 +chance_fire = [128, 511] +chance_range = [128, 511] +chance_cook_o_matic = [138, 531] +chance_gauntlet = [128, 511] +cooked = "cooked_meat" +cooked_message = "You cook a piece of meat." +burnt = "burnt_meat" +burnt_message = "You accidentally burn the beef." + +[.raw_bird_meat] +level = 11 +xp = 625 +type = "roast" +chance_fire = [155, 254] +chance_range = [155, 254] +chance_cook_o_matic = [155, 254] +chance_gauntlet = [155, 254] +cooked = "roast_bird_meat" + +[.raw_cave_eel] +level = 38 +xp = 1150 +chance_fire = [38, 331] +chance_range = [38, 331] +chance_cook_o_matic = [38, 331] +chance_gauntlet = [38, 331] +cooked = "cave_eel" +cooked_message = "You successfully cook a slimy cave eel." +burnt_message = "You accidentally burn the cave eel." + +[.raw_cavefish] +level = 88 +xp = 2140 +chance_fire = [4, 229] +chance_range = [4, 229] +chance_cook_o_matic = [4, 229] +chance_gauntlet = [12, 268] +cooked = "cavefish" + +[.raw_chicken] +level = 1 +xp = 300 +chance_fire = [128, 511] +chance_range = [128, 511] +chance_cook_o_matic = [138, 531] +chance_gauntlet = [128, 511] +cooked_message = "You cook some chicken." +burnt_message = "You accidentally burn the chicken." + +[.raw_cod] +level = 18 +xp = 750 +chance_fire = [83, 421] +chance_range = [88, 431] +chance_cook_o_matic = [93, 441] +chance_gauntlet = [88, 431] +cooked = "cod" +cooked_message = "You successfully cook a cod." +burnt = "burnt_trout" +burnt_message = "You accidentally burn the cod." + +[.raw_crayfish] +level = 1 +xp = 300 +chance_fire = [128, 511] +chance_range = [128, 511] +chance_cook_o_matic = [128, 511] +chance_gauntlet = [128, 511] +cooked = "crayfish" +cooked_message = "You successfully cook some crayfish." +burnt_message = "You accidentally burn the crayfish." + +[.raw_fish_pie] +level = 47 +xp = 1640 +type = "bake" +range_only = true +chance_range = [38, 331] +chance_cook_o_matic = [38, 331] +chance_gauntlet = [38, 331] +cooked = "fish_pie" +cooked_message = "You successfully bake a tasty fish pie." +burnt = "burnt_pie" +burnt_message = "You accidentally burn the fish pie." + +[.raw_fishcake] +level = 31 +xp = 1000 +chance_fire = [57, 376] +chance_range = [57, 376] +chance_cook_o_matic = [57, 376] +chance_gauntlet = [57, 376] +cooked_message = "You manage to cook a fishcake." +burnt_message = "You accidentally burn the uncooked cake." + +[.raw_garden_pie] +level = 34 +xp = 1380 +type = "bake" +range_only = true +chance_range = [48, 351] +chance_cook_o_matic = [48, 351] +chance_gauntlet = [48, 351] +cooked = "garden_pie" +cooked_message = "You successfully bake a tasty garden pie." +burnt = "burnt_pie" +burnt_message = "You accidentally burn the garden pie." + +[.raw_guide_cake] +level = 40 +xp = 600 +type = "bake" +range_only = true +chance_range = [255, 254] +chance_cook_o_matic = [255, 254] +chance_gauntlet = [255, 254] +cooked = "cake_of_guidance" +cooked_message = "You successfully bake a Cake of Guidance." +leftover = "cake_tin" + +[.raw_herring] +level = 5 +xp = 500 +chance_fire = [108, 471] +chance_range = [108, 471] +chance_cook_o_matic = [118, 491] +chance_gauntlet = [108, 471] +cooked = "herring" +cooked_message = "You successfully cook a herring." +burnt_message = "You accidentally burn the herring." + +[.raw_jubbly] +level = 41 +xp = 1600 +ticks = 6 +chance_fire = [50, 259] +chance_range = [50, 259] +chance_cook_o_matic = [50, 259] +chance_gauntlet = [50, 259] + +[.raw_karambwan] +level = 30 +xp = 1900 +chance_fire = [70, 254] +chance_range = [70, 254] +chance_cook_o_matic = [70, 254] +chance_gauntlet = [70, 254] +cooked_message = "You cook the karambwan. It looks delicious." +burnt_message = "You accidentally burn the karambwan." + +[.raw_lava_eel] +level = 53 +xp = 300 +chance_fire = [0, -1] +chance_range = [0, -1] +chance_cook_o_matic = [0, -1] +chance_gauntlet = [0, -1] +cooked = "lava_eel" + +[.raw_lobster] +level = 40 +xp = 1200 +type = "roast" +chance_fire = [38, 331] +chance_range = [38, 331] +chance_cook_o_matic = [38, 331] +chance_gauntlet = [55, 367] +cooked = "lobster" +cooked_message = "You roast a lobster." +burnt_message = "You accidentally burn the lobster." + +[.raw_mackerel] +level = 10 +xp = 600 +chance_fire = [98, 451] +chance_range = [98, 451] +chance_cook_o_matic = [108, 471] +chance_gauntlet = [98, 451] +cooked = "mackerel" +cooked_message = "You successfully cook a mackerel." +burnt = "burnt_herring" +burnt_message = "You accidentally burn the mackerel." + +[.raw_manta_ray] +level = 91 +xp = 2163 +chance_fire = [1, 201] +chance_range = [1, 221] +chance_cook_o_matic = [1, 221] +chance_gauntlet = [1, 221] +cooked = "manta_ray" +cooked_message = "You successfully cook a manta ray." +burnt_message = "You accidentally burn the manta ray." + +[.raw_monkfish] +level = 62 +xp = 1500 +chance_fire = [11, 274] +chance_range = [13, 279] +chance_cook_o_matic = [13, 279] +chance_gauntlet = [24, 289] +cooked = "monkfish" +cooked_message = "You successfully cook a monkfish." +burnt_message = "You accidentally burn the monkfish." + +[.raw_mud_pie] +level = 29 +xp = 1280 +type = "bake" +range_only = true +chance_range = [58, 371] +chance_cook_o_matic = [58, 371] +chance_gauntlet = [58, 371] +cooked = "mud_pie" +cooked_message = "You successfully bake a mucky mud pie." +burnt = "burnt_pie" +burnt_message = "You accidentally burn the mud pie." + +[.raw_pawya_meat] +level = 1 +xp = 300 +chance_fire = [128, 511] +chance_range = [128, 511] +chance_cook_o_matic = [138, 531] +chance_gauntlet = [128, 511] +cooked = "cooked_meat" +burnt = "burnt_meat" + +[.raw_pike] +level = 20 +xp = 800 +chance_fire = [78, 411] +chance_range = [78, 411] +chance_cook_o_matic = [88, 431] +chance_gauntlet = [78, 411] +cooked = "pike" +cooked_message = "You successfully cook a pike." +burnt_message = "You accidentally burn the pike." + +[.raw_potato] +level = 7 +xp = 150 +range_only = true +chance_range = [108, 471] +chance_cook_o_matic = [108, 471] +chance_gauntlet = [108, 471] +cooked = "baked_potato" +cooked_message = "You successfully bake a potato." +burnt_message = "You accidentally burn the potato." + +[.raw_rabbit] +level = 1 +xp = 300 +chance_fire = [128, 511] +chance_range = [128, 511] +chance_cook_o_matic = [128, 511] +chance_gauntlet = [128, 511] +cooked_message = "You cook the rabbit." +burnt_message = "You accidentally burn the rabbit." + +[.raw_rainbow_fish] +level = 35 +xp = 1100 +chance_fire = [56, 369] +chance_range = [56, 369] +chance_cook_o_matic = [56, 369] +chance_gauntlet = [56, 369] +cooked = "rainbow_fish" +cooked_message = "You manage to cook a rainbow fish." +burnt_message = "You accidentally burn the rainbow fish." + +[.raw_rat_meat] +level = 1 +xp = 300 +chance_fire = [128, 511] +chance_range = [128, 511] +chance_cook_o_matic = [138, 531] +chance_gauntlet = [128, 511] +cooked = "cooked_meat" +cooked_message = "You cook a piece of meat." +burnt = "burnt_meat" +burnt_message = "You accidentally burn the rat meat." + +[.raw_rocktail] +level = 92 +xp = 2250 +chance_fire = [1, 179] +chance_range = [1, 179] +chance_cook_o_matic = [1, 179] +chance_gauntlet = [1, 268] +cooked = "rocktail" +cooked_message = "You successfully cook a rocktail." +burnt_message = "You accidentally burn the rocktail." + +[.raw_salmon] +level = 25 +xp = 900 +chance_fire = [68, 391] +chance_range = [68, 391] +chance_cook_o_matic = [78, 401] +chance_gauntlet = [68, 391] +cooked = "salmon" +cooked_message = "You successfully cook a salmon." +burnt_message = "You accidentally burn the salmon." + +[.raw_sardine] +level = 1 +xp = 400 +chance_fire = [118, 491] +chance_range = [118, 491] +chance_cook_o_matic = [128, 511] +chance_gauntlet = [118, 491] +cooked = "sardine" +cooked_message = "You successfully cook a sardine." +burnt_message = "You accidentally burn the sardine." + +[.raw_sea_turtle] +level = 82 +xp = 2113 +chance_fire = [1, 201] +chance_range = [1, 221] +chance_cook_o_matic = [1, 221] +chance_gauntlet = [1, 221] +cooked = "sea_turtle" +cooked_message = "You successfully cook a sea turtle." +burnt_message = "You accidentally burn the sea turtle." + +[.raw_shark] +level = 80 +xp = 2100 +chance_fire = [1, 201] +chance_range = [1, 231] +chance_cook_o_matic = [1, 231] +chance_gauntlet = [15, 269] +cooked = "shark" +cooked_message = "You successfully cook a shark." +burnt_message = "You accidentally burn the shark." + +[.raw_shrimps] +level = 1 +xp = 300 +chance_fire = [128, 511] +chance_range = [128, 511] +chance_cook_o_matic = [138, 531] +chance_gauntlet = [128, 511] +cooked = "shrimps" +cooked_message = "You successfully cook some shrimps." +burnt = "burnt_shrimp" +burnt_message = "You accidentally burn the shrimps." + +[.raw_summer_pie] +level = 95 +xp = 2600 +type = "bake" +range_only = true +chance_range = [1, 211] +chance_cook_o_matic = [1, 211] +chance_gauntlet = [1, 211] +cooked = "summer_pie" +cooked_message = "You successfully bake a tasty summer pie." +burnt = "burnt_pie" +burnt_message = "You accidentally burn the summer pie." + +[.raw_swordfish] +level = 45 +xp = 1400 +chance_fire = [18, 291] +chance_range = [30, 309] +chance_cook_o_matic = [30, 309] +chance_gauntlet = [30, 309] +cooked = "swordfish" +cooked_message = "You successfully cook a swordfish." +burnt_message = "You accidentally burn the swordfish." + +[.raw_trout] +level = 15 +xp = 700 +chance_fire = [88, 431] +chance_range = [88, 431] +chance_cook_o_matic = [98, 451] +chance_gauntlet = [88, 431] +cooked = "trout" +cooked_message = "You successfully cook a trout." +burnt_message = "You accidentally burn the trout." + +[.raw_tuna] +level = 30 +xp = 1000 +chance_fire = [58, 371] +chance_range = [58, 371] +chance_cook_o_matic = [58, 371] +chance_gauntlet = [58, 371] +cooked = "tuna" +cooked_message = "You manage to cook a tuna." +burnt_message = "You accidentally burn the tuna." + +[.raw_ugthanki_meat] +level = 1 +xp = 400 +chance_fire = [40, 251] +chance_range = [30, 252] +chance_cook_o_matic = [30, 252] +chance_gauntlet = [30, 252] +cooked = "ugthanki_meat" + +[.raw_wild_pie] +level = 85 +xp = 2400 +type = "bake" +range_only = true +chance_range = [1, 221] +chance_cook_o_matic = [1, 221] +chance_gauntlet = [1, 221] +cooked = "wild_pie" +cooked_message = "You successfully bake a tasty wild pie." +burnt = "burnt_pie" +burnt_message = "You accidentally burn the wild pie." + +[.raw_yak_meat] +level = 1 +xp = 400 +chance_fire = [128, 511] +chance_range = [128, 511] +chance_cook_o_matic = [138, 531] +chance_gauntlet = [128, 511] +cooked = "cooked_meat" +burnt = "burnt_meat" + +[.sinew] +level = 1 +xp = 30 +type = "heat" +range_only = true +chance_range = [255, 254] +chance_cook_o_matic = [255, 254] +chance_gauntlet = [255, 254] +cooked = "sinew" +cooked_message = "You dry a piece of beef and extract the sinew." + +[.skewered_chompy] +level = 30 +xp = 1000 +type = "roast" +chance_fire = [200, 254] +chance_range = [200, 254] +chance_cook_o_matic = [200, 254] +chance_gauntlet = [200, 254] +cooked = "cooked_chompy" +burnt = "burnt_chompy" + +[.skewered_rabbit] +level = 16 +xp = 720 +type = "roast" +ticks = 3 +chance_fire = [160, 254] +chance_range = [160, 254] +chance_cook_o_matic = [160, 254] +chance_gauntlet = [160, 254] +cooked = "roast_rabbit" +cooked_message = "You roast the skewered rabbit." +burnt = "burnt_rabbit" +burnt_message = "You accidentally burn the skewered rabbit." + +[.sliced_mushrooms] +level = 46 +xp = 600 +range_only = true +chance_range = [28, 299] +chance_cook_o_matic = [28, 299] +chance_gauntlet = [28, 299] +cooked = "fried_mushrooms" +cooked_message = "You successfully fry the mushroom." +burnt = "burnt_mushroom" +burnt_message = "You accidentally burn the mushroom." + +[.slimy_eel] +level = 28 +xp = 950 +chance_fire = [63, 381] +chance_range = [63, 381] +chance_cook_o_matic = [63, 381] +chance_gauntlet = [63, 381] +cooked = "cooked_slimy_eel" +cooked_message = "You cook an eel." +burnt = "burnt_eel" +burnt_message = "You accidentally burn the slimy eel." + +[.spider_on_shaft_raw] +level = 16 +xp = 800 +type = "roast" +chance_fire = [91, 437] +chance_range = [91, 437] +chance_cook_o_matic = [91, 437] +chance_gauntlet = [91, 437] +cooked = "spider_on_shaft" +burnt = "spider_on_shaft_burnt" + +[.spider_on_stick_raw] +level = 16 +xp = 800 +type = "roast" +chance_fire = [91, 437] +chance_range = [91, 437] +chance_cook_o_matic = [91, 437] +chance_gauntlet = [91, 437] +cooked = "spider_on_stick" +burnt = "burnt_spider" + +[.sweetcorn] +level = 28 +xp = 1040 +range_only = true +chance_range = [65, 381] +chance_cook_o_matic = [65, 381] +chance_gauntlet = [65, 381] +cooked = "cooked_sweetcorn" +cooked_message = "You cook some sweetcorn." +burnt = "burnt_sweetcorn" +burnt_message = "You accidentally burn the sweetcorn." + +[.thin_snail] +level = 12 +xp = 700 +chance_fire = [93, 443] +chance_range = [93, 443] +chance_cook_o_matic = [103, 463] +chance_gauntlet = [93, 443] +cooked = "thin_snail_meat" +cooked_message = "You cook the thin snail." +burnt = "burnt_snail" +burnt_message = "You accidentally burn the thin snail." + +[.uncooked_apple_pie] +level = 30 +xp = 1300 +range_only = true +chance_range = [58, 371] +chance_cook_o_matic = [58, 371] +chance_gauntlet = [58, 371] +cooked = "apple_pie" +cooked_message = "You successfully bake a traditional apple pie." +burnt = "burnt_pie" +burnt_message = "You accidentally burn the uncooked apple pie." + +[.uncooked_berry_pie] +level = 10 +xp = 780 +range_only = true +chance_range = [98, 451] +chance_cook_o_matic = [108, 461] +chance_gauntlet = [98, 451] +cooked = "redberry_pie" +cooked_message = "You successfully bake a delicious redberry pie." +burnt = "burnt_pie" +burnt_message = "You accidentally burn the uncooked berry pie." + +[.uncooked_cake] +level = 40 +xp = 1800 +range_only = true +chance_range = [38, 331] +chance_cook_o_matic = [38, 331] +chance_gauntlet = [38, 331] +cooked = "cake" +cooked_message = "You successfully bake a cake." +leftover = "cake_tin" +burnt = "burnt_cake" +burnt_message = "You accidentally burn the uncooked cake." + +[.uncooked_curry] +level = 60 +xp = 2800 +chance_fire = [38, 331] +chance_range = [38, 331] +chance_cook_o_matic = [38, 331] +chance_gauntlet = [38, 331] +cooked = "curry" +cooked_message = "You cook some curry." +burnt = "burnt_curry" +burnt_message = "You accidentally burn the curry." + +[.uncooked_egg] +level = 13 +xp = 500 +start_ticks = 0 +range_only = true +chance_range = [90, 437] +chance_cook_o_matic = [90, 437] +chance_gauntlet = [90, 437] +cooked = "scrambled_egg" +cooked_message = "You successfully scramble the egg." +burnt = "burnt_egg" +burnt_message = "You accidentally burn the egg." + +[.uncooked_meat_pie] +level = 20 +xp = 1100 +range_only = true +chance_range = [78, 411] +chance_cook_o_matic = [88, 431] +chance_gauntlet = [78, 411] +cooked = "meat_pie" +cooked_message = "You successfully bake a tasty meat pie." +burnt = "burnt_pie" +burnt_message = "You accidentally burn the uncooked meat pie." + +[.uncooked_pizza] +level = 35 +xp = 1430 +range_only = true +chance_range = [48, 351] +chance_cook_o_matic = [48, 351] +chance_gauntlet = [48, 351] +cooked = "plain_pizza" +cooked_message = "You successfully bake a pizza." +burnt = "burnt_pizza" +burnt_message = "You accidentally burn the uncooked pizza." + +[.uncooked_stew] +level = 25 +xp = 1170 +chance_fire = [68, 391] +chance_range = [68, 391] +chance_cook_o_matic = [78, 411] +chance_gauntlet = [68, 391] +cooked = "stew" +cooked_message = "You cook some stew." +burnt = "burnt_stew" +burnt_message = "You accidentally burn the stew." diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt index 82f1888337..1b001dffe2 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt @@ -11,10 +11,18 @@ data class RowDefinition( val stringId: String ) { + fun bool(column: String) = Tables.bool("${stringId}.$column") + + fun boolOrNull(column: String) = Tables.boolOrNull("${stringId}.$column") + fun int(column: String) = Tables.int("${stringId}.$column") fun intOrNull(column: String) = Tables.intOrNull("${stringId}.$column") + fun intRange(column: String) = Tables.intRange("${stringId}.$column") + + fun intRangeOrNull(column: String) = Tables.intRangeOrNull("${stringId}.$column") + fun itemPair(column: String) = Tables.itemPair("${stringId}.$column") fun string(column: String) = Tables.string("${stringId}.$column") diff --git a/game/src/main/kotlin/content/skill/cooking/Cooking.kt b/game/src/main/kotlin/content/skill/cooking/Cooking.kt index cae4338e77..78837e3cb9 100644 --- a/game/src/main/kotlin/content/skill/cooking/Cooking.kt +++ b/game/src/main/kotlin/content/skill/cooking/Cooking.kt @@ -7,8 +7,9 @@ import world.gregs.voidps.engine.GameLoop import world.gregs.voidps.engine.Script import world.gregs.voidps.engine.client.message import world.gregs.voidps.engine.client.ui.closeDialogue -import world.gregs.voidps.engine.data.definition.EnumDefinitions +import world.gregs.voidps.engine.data.config.RowDefinition import world.gregs.voidps.engine.data.definition.ItemDefinitions +import world.gregs.voidps.engine.data.definition.Rows import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.chat.ChatType import world.gregs.voidps.engine.entity.character.player.chat.inventoryFull @@ -46,10 +47,10 @@ class Cooking : Script { } else { item.def } - EnumDefinitions.intOrNull("cooking_xp", definition.stringId) ?: return@itemOnObjectOperate + val row = Rows.getOrNull("cooking.${definition.stringId}") ?: return@itemOnObjectOperate var amount = inventory.count(item.id) if (amount != 1) { - val type = EnumDefinitions.string("cooking_type", definition.stringId) + val type = row.string("type") amount = makeAmount( listOf(item.id), type = type.toSentenceCase(), @@ -60,30 +61,30 @@ class Cooking : Script { val offset = (4 - (GameLoop.tick - start)).coerceAtLeast(0) closeDialogue() softTimers.start("cooking") - cook(item, amount, target, offset) + cook(row, item, amount, target, offset) } } - fun Player.cook(item: Item, count: Int, obj: GameObject, offset: Int? = null) { + fun Player.cook(row: RowDefinition, item: Item, count: Int, obj: GameObject, offset: Int? = null) { if (count <= 0 || GameObjects.findOrNull(obj.tile, obj.id) == null) { softTimers.stop("cooking") return } - val level = EnumDefinitions.int("cooking_type", item.id) + val level = row.int("level") if (!has(Skill.Cooking, level, true)) { softTimers.stop("cooking") return } - val leftover = EnumDefinitions.string("cooking_leftover", item.id) - if (leftover.isNotEmpty() && inventory.isFull()) { + val leftover = row.itemOrNull("leftover") + if (leftover != null && inventory.isFull()) { inventoryFull() softTimers.stop("cooking") return } - val rangeOnly = EnumDefinitions.contains("cooking_range_only", item.id) + val rangeOnly = row.bool("range_only") if (rangeOnly && !obj.cookingRange) { noInterest() softTimers.stop("cooking") @@ -97,30 +98,30 @@ class Cooking : Script { } val level = levels.get(Skill.Cooking) val chance = when { - obj.id == "cooking_range_lumbridge_castle" -> EnumDefinitions.int("cooking_range_chance_min", item.id)..EnumDefinitions.int("cooking_range_chance_max", item.id) - equipped(EquipSlot.Hands).id == "cooking_gauntlets" -> EnumDefinitions.int("cooking_cook_o_matic_chance_min", item.id)..EnumDefinitions.int("cooking_cook_o_matic_chance_max", item.id) - obj.cookingRange -> EnumDefinitions.int("cooking_range_chance_min", item.id)..EnumDefinitions.int("cooking_range_chance_max", item.id) - else -> EnumDefinitions.int("cooking_fire_chance_min", item.id)..EnumDefinitions.int("cooking_fire_chance_max", item.id) + obj.id == "cooking_range_lumbridge_castle" -> row.intRange("chance_range") + equipped(EquipSlot.Hands).id == "cooking_gauntlets" -> row.intRange("chance_cook_o_matic") + obj.cookingRange -> row.intRange("chance_range") + else -> row.intRange("chance_fire") } - if (failedToReplace(item, Level.success(level, chance))) { + if (failedToReplace(row, item, Level.success(level, chance))) { return@weakQueue } - if (leftover.isNotEmpty() && !inventory.add(leftover)) { + if (leftover != null && !inventory.add(leftover)) { return@weakQueue } - cook(item, count - 1, obj) + cook(row, item, count - 1, obj) } } - fun Player.failedToReplace(item: Item, cooked: Boolean): Boolean { - val id = EnumDefinitions.string(if (cooked) "cooked_id" else "burnt_id", item.id) + fun Player.failedToReplace(row: RowDefinition, item: Item, cooked: Boolean): Boolean { + val id = row.item(if (cooked) "cooked" else "burnt") val itemId = id.ifEmpty { item.id.replace("raw", if (cooked) "cooked" else "burnt") } if (!inventory.replace(item.id, itemId)) { return true } - val xp = EnumDefinitions.int("cooking_xp", item.id) / 10.0 + val xp = row.int("xp") / 10.0 exp(Skill.Cooking, if (cooked) xp else 0.0) - val message = EnumDefinitions.string(if (cooked) "cooked_message" else "burnt_message", item.id) + val message = row.string(if (cooked) "cooked_message" else "burnt_message") if (message.isNotEmpty()) { message(message, ChatType.Filter) } From 38e348d327e94bcec40aff6fe0ee77895725c871 Mon Sep 17 00:00:00 2001 From: GregHib Date: Thu, 26 Mar 2026 14:22:07 +0000 Subject: [PATCH 14/40] Convert tanning enums --- data/skill/crafting/tanning.enums.toml | 65 ------------------- data/skill/crafting/tanning.tables.toml | 46 +++++++++++++ .../area/kharidian_desert/al_kharid/Ellis.kt | 8 +-- 3 files changed, 50 insertions(+), 69 deletions(-) delete mode 100644 data/skill/crafting/tanning.enums.toml create mode 100644 data/skill/crafting/tanning.tables.toml diff --git a/data/skill/crafting/tanning.enums.toml b/data/skill/crafting/tanning.enums.toml deleted file mode 100644 index 228dc08bf4..0000000000 --- a/data/skill/crafting/tanning.enums.toml +++ /dev/null @@ -1,65 +0,0 @@ -[tanning_product] -keyType = "item" -valueType = "string" -defaultString = "" -values = { - snake_hide = "snakeskin", - snake_hide_swamp = "snakeskin", - cowhide = "leather", - black_dragonhide = "black_dragon_leather", - red_dragonhide = "red_dragon_leather", - blue_dragonhide = "blue_dragon_leather", - green_dragonhide = "green_dragon_leather", -} - -[ellis_tanning_price] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - snake_hide = 15, - snake_hide_swamp = 20, - cowhide = 1, - black_dragonhide = 20, - red_dragonhide = 20, - blue_dragonhide = 20, - green_dragonhide = 20, -} - -[sbott_tanning_price] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - snake_hide = 25, - snake_hide_swamp = 25, - cowhide = 2, - black_dragonhide = 45, - red_dragonhide = 45, - blue_dragonhide = 45, - green_dragonhide = 45, -} - -[tanning_secondary_product] -keyType = "item" -valueType = "string" -defaultString = "" -values = { - cowhide = "hard_leather", -} - -[ellis_tanning_secondary_price] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - cowhide = 3, -} - -[sbott_tanning_secondary_price] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - cowhide = 5, -} diff --git a/data/skill/crafting/tanning.tables.toml b/data/skill/crafting/tanning.tables.toml new file mode 100644 index 0000000000..9e437cd558 --- /dev/null +++ b/data/skill/crafting/tanning.tables.toml @@ -0,0 +1,46 @@ +[tanning] +row_id = "item" +leather = "item" +price_ellis = "int" +price_sbott = "int" +hard_leather = "item" +hard_price_ellis = "int" +hard_price_sbott = "int" + +[.black_dragonhide] +leather = "black_dragon_leather" +price_ellis = 20 +price_sbott = 45 + +[.blue_dragonhide] +leather = "blue_dragon_leather" +price_ellis = 20 +price_sbott = 45 + +[.cowhide] +leather = "leather" +price_ellis = 1 +price_sbott = 2 +hard_leather = "hard_leather" +hard_price_ellis = 3 +hard_price_sbott = 5 + +[.green_dragonhide] +leather = "green_dragon_leather" +price_ellis = 20 +price_sbott = 45 + +[.red_dragonhide] +leather = "red_dragon_leather" +price_ellis = 20 +price_sbott = 45 + +[.snake_hide] +leather = "snakeskin" +price_ellis = 15 +price_sbott = 25 + +[.snake_hide_swamp] +leather = "snakeskin" +price_ellis = 20 +price_sbott = 25 diff --git a/game/src/main/kotlin/content/area/kharidian_desert/al_kharid/Ellis.kt b/game/src/main/kotlin/content/area/kharidian_desert/al_kharid/Ellis.kt index 2c9a8f69d6..c937ae34ef 100644 --- a/game/src/main/kotlin/content/area/kharidian_desert/al_kharid/Ellis.kt +++ b/game/src/main/kotlin/content/area/kharidian_desert/al_kharid/Ellis.kt @@ -16,7 +16,7 @@ import world.gregs.voidps.engine.client.ui.chat.Colours import world.gregs.voidps.engine.client.ui.chat.plural import world.gregs.voidps.engine.client.ui.chat.toTag import world.gregs.voidps.engine.client.ui.open -import world.gregs.voidps.engine.data.definition.EnumDefinitions +import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.male import world.gregs.voidps.engine.inv.carriesItem @@ -90,9 +90,9 @@ class Ellis : Script { return } val tanner = player["tanner", "ellis"] - val primary = if (type.endsWith("_1")) "_secondary" else "" - val leather = EnumDefinitions.string("tanning${primary}_product", item) - val cost = EnumDefinitions.int("${tanner}_tanning${primary}_price", item) + val primary = if (type.endsWith("_1")) "hard_" else "" + val leather = Tables.item("tanning.${item}.${primary}leather") + val cost = Tables.int("tanning.${item}.${primary}price_${tanner}") var tanned = 0 var noHides = false for (i in 0 until amount) { From 20fce629f9f691f3c5cd6c3f14b3145d40a9fe14 Mon Sep 17 00:00:00 2001 From: GregHib Date: Thu, 26 Mar 2026 15:21:07 +0000 Subject: [PATCH 15/40] Add support for row_id types --- .../voidps/engine/data/config/TableDefinition.kt | 2 ++ .../gregs/voidps/engine/data/definition/Tables.kt | 13 ++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt index e3198f5d85..dd13cb4b49 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt @@ -14,6 +14,8 @@ data class TableDefinition( val rows: IntArray, ) { + fun rows(): List = rows.map { Rows.get(it) } + fun bool(column: String, row: Int): Boolean = get(column, row, ColumnType.ColumnBoolean) fun boolOrNull(column: String, row: Int): Boolean? = getOrNull(column, row, ColumnType.ColumnBoolean) diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt index 11ec7a35c4..c322595f83 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt @@ -218,6 +218,11 @@ object Tables { private fun readTableRow(reader: ConfigReader, definitions: MutableMap, rows: MutableList, ids: MutableMap, key: String, rowName: String) { val builder = definitions[key] requireNotNull(builder) { "Table header not found '$key' at ${reader.exception()}." } + val idReader = builder.idReader + if (idReader != null) { + val rowId = rowName.substringAfter(".") + requireNotNull(idReader.definitions[rowId]) { "Unable to find entity '$rowId' for row id" } + } val row = arrayOfNulls(builder.readers.size) while (reader.nextPair()) { val name = reader.key() @@ -239,7 +244,12 @@ object Tables { definitions[stringId] = builder while (reader.nextPair()) { val key = reader.key() - if (key.endsWith("_default")) { + if (key == "row_id") { + val reader = ColumnReader.reader(reader.string()) + if (reader is ColumnReader.ReaderEntity) { + builder.idReader = reader + } + } else if (key.endsWith("_default")) { val default = reader.value() builder.setDefault(key.removeSuffix("_default"), default) } else { @@ -255,6 +265,7 @@ object Tables { val defaults = mutableListOf() val rows = mutableListOf() private var columnIndex = 0 + var idReader: ColumnReader.ReaderEntity? = null fun setDefault(name: String, value: Any) { val index = columns[name] From 7a4dbf222448bb12d1525625099fd01bd71c7b1f Mon Sep 17 00:00:00 2001 From: GregHib Date: Thu, 26 Mar 2026 15:50:21 +0000 Subject: [PATCH 16/40] Convert crafting enums, add silver casting test --- data/skill/crafting/crafting.enums.toml | 246 ------------------ data/skill/crafting/jewellery.tables.toml | 120 +++++++++ .../skill/crafting/silver_casting.tables.toml | 71 +++++ data/skill/crafting/spinning.tables.toml | 63 +++++ data/skill/crafting/weaving.tables.toml | 30 +++ .../engine/data/config/RowDefinition.kt | 2 + .../content/skill/crafting/Jewellery.kt | 12 +- .../content/skill/crafting/SilverCasting.kt | 45 ++-- .../content/skill/crafting/SpinningWheel.kt | 51 ++-- .../kotlin/content/skill/crafting/Weaving.kt | 55 ++-- .../kotlin/content/skill/slayer/Slayer.kt | 4 +- .../skill/crafting/SilverCastingTest.kt | 32 +++ 12 files changed, 394 insertions(+), 337 deletions(-) delete mode 100644 data/skill/crafting/crafting.enums.toml create mode 100644 data/skill/crafting/jewellery.tables.toml create mode 100644 data/skill/crafting/silver_casting.tables.toml create mode 100644 data/skill/crafting/spinning.tables.toml create mode 100644 data/skill/crafting/weaving.tables.toml create mode 100644 game/src/test/kotlin/content/skill/crafting/SilverCastingTest.kt diff --git a/data/skill/crafting/crafting.enums.toml b/data/skill/crafting/crafting.enums.toml deleted file mode 100644 index b2d059da6d..0000000000 --- a/data/skill/crafting/crafting.enums.toml +++ /dev/null @@ -1,246 +0,0 @@ -[jewellery_level] -keyType = "item" -valueType = "int" -defaultInt = 1 -values = { - gold_ring = 5, - sapphire_ring = 20, - emerald_ring = 27, - ruby_ring = 34, - diamond_ring = 43, - dragonstone_ring = 55, - gold_necklace = 6, - sapphire_necklace = 22, - emerald_necklace = 29, - ruby_necklace = 40, - diamond_necklace = 56, - dragonstone_necklace = 72, - gold_amulet_unstrung = 8, - sapphire_amulet_unstrung = 24, - emerald_amulet_unstrung = 31, - ruby_amulet_unstrung = 50, - diamond_amulet_unstrung = 70, - dragonstone_amulet_unstrung = 80, - onyx_ring = 67, - onyx_necklace = 82, - onyx_amulet_unstrung = 90, - gold_bracelet = 7, - sapphire_bracelet = 23, - emerald_bracelet = 30, - ruby_bracelet = 42, - diamond_bracelet = 58, - dragonstone_bracelet = 74, - onyx_bracelet = 84, - ring_of_slaying_8 = 75, -} - -[jewellery_xp] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - gold_ring = 15, - sapphire_ring = 40, - emerald_ring = 55, - ruby_ring = 70, - diamond_ring = 85, - dragonstone_ring = 100, - gold_necklace = 20, - sapphire_necklace = 55, - emerald_necklace = 60, - ruby_necklace = 75, - diamond_necklace = 90, - dragonstone_necklace = 105, - gold_amulet_unstrung = 30, - sapphire_amulet_unstrung = 65, - emerald_amulet_unstrung = 70, - ruby_amulet_unstrung = 85, - diamond_amulet_unstrung = 100, - dragonstone_amulet_unstrung = 150, - onyx_ring = 115, - onyx_necklace = 120, - onyx_amulet_unstrung = 165, - gold_bracelet = 25, - sapphire_bracelet = 60, - emerald_bracelet = 65, - ruby_bracelet = 80, - diamond_bracelet = 95, - dragonstone_bracelet = 110, - onyx_bracelet = 125, - ring_of_slaying_8 = 15, -} - -[silver_jewellery_level] -keyType = "item" -valueType = "int" -defaultInt = 1 -values = { - conductor_mould = 20, - rod_clay_mould = 25, - chain_link_mould = 47, - sickle_mould = 18, - demonic_sigil_mould = 30, - unholy_mould = 17, - holy_mould = 16, - bolt_mould = 21, - tiara_mould = 16, -} - -[silver_jewellery_xp] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - conductor_mould = 500, - rod_clay_mould = 550, - chain_link_mould = 1000, - sickle_mould = 500, - demonic_sigil_mould = 500, - unholy_mould = 500, - holy_mould = 500, - bolt_mould = 500, - tiara_mould = 525, -} - -[silver_jewellery_name] -keyType = "item" -valueType = "string" -values = { - conductor_mould = "lightning rod mould", - unholy_mould = "Unholy Symbol mould", - holy_mould = "Saradomin Symbol", - bolt_mould = "crossbow bolt mould", -} - -[silver_jewellery_quest] -keyType = "item" -valueType = "string" -values = { - conductor_mould = "creature_of_fenkenstrain", - key_mould = "elemental_workshop_iii", - rod_clay_mould = "in_aid_of_the_myreque", - chain_link_mould = "legacy_of_seergaze", - sickle_mould = "nature_spirit", - demonic_sigil_mould = "shadow_of_the_storm", - unholy_mould = "observatory_quest", -} - -[silver_jewellery_item] -keyType = "item" -valueType = "string" -defaultString = "" -values = { - conductor_mould = "conductor", - key_mould = "ragged_silver_key", - rod_clay_mould = "silvthril_rod", - chain_link_mould = "silvthril_chain", - sickle_mould = "silver_sickle", - demonic_sigil_mould = "demonic_sigil", - unholy_mould = "unstrung_emblem", - holy_mould = "unstrung_symbol", - bolt_mould = "silver_bolts_unf", - tiara_mould = "tiara", -} - -[silver_jewellery_amount] -keyType = "item" -valueType = "int" -defaultInt = 1 -values = { - bolt_mould = 10, -} - -[spinning_level] -keyType = "item" -valueType = "int" -defaultInt = 1 -values = { - yak_hair = 30, - golden_wool = 40, - flax = 10, - oak_roots = 10, - willow_roots = 10, - maple_roots = 10, - yew_roots = 10, - magic_roots = 19, - sinew = 10, -} - -[spinning_xp] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - yak_hair = 250, - golden_wool = 25, - wool = 25, - black_wool = 25, - flax = 150, - oak_roots = 150, - willow_roots = 150, - maple_roots = 150, - yew_roots = 150, - magic_roots = 300, - sinew = 150, -} - -[spinning_item] -keyType = "item" -valueType = "string" -defaultString = "" -values = { - yak_hair = "rope", - golden_wool = "golden_fleece", - wool = "ball_of_wool", - black_wool = "ball_of_black_wool", - flax = "bowstring", - oak_roots = "crossbow_string", - willow_roots = "crossbow_string", - maple_roots = "crossbow_string", - yew_roots = "crossbow_string", - magic_roots = "magic_string", - sinew = "crossbow_string", -} - -[weaving_level] -keyType = "item" -valueType = "int" -defaultInt = 1 -values = { - ball_of_wool = 10, - flax = 52, - jute_fibre = 21, - willow_branch = 36, -} - -[weaving_xp] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - ball_of_wool = 120, - jute_fibre = 380, - willow_branch = 560, -} - -[weaving_amount] -keyType = "item" -valueType = "int" -defaultInt = 1 -values = { - ball_of_wool = 2, - flax = 5, - jute_fibre = 4, - willow_branch = 6, -} - -[weaving_product] -keyType = "item" -valueType = "string" -defaultString = "" -values = { - ball_of_wool = "strip_of_cloth", - flax = "unfinished_net", - jute_fibre = "empty_sack", - willow_branch = "basket", -} diff --git a/data/skill/crafting/jewellery.tables.toml b/data/skill/crafting/jewellery.tables.toml new file mode 100644 index 0000000000..5cf108381c --- /dev/null +++ b/data/skill/crafting/jewellery.tables.toml @@ -0,0 +1,120 @@ +[jewellery] +row_id = "item" +level = "int" +xp = "int" + +[.gold_ring] +level = 5 +xp = 15 + +[.sapphire_ring] +level = 20 +xp = 40 + +[.emerald_ring] +level = 27 +xp = 55 + +[.ruby_ring] +level = 34 +xp = 70 + +[.diamond_ring] +level = 43 +xp = 85 + +[.dragonstone_ring] +level = 55 +xp = 100 + +[.gold_necklace] +level = 6 +xp = 20 + +[.sapphire_necklace] +level = 22 +xp = 55 + +[.emerald_necklace] +level = 29 +xp = 60 + +[.ruby_necklace] +level = 40 +xp = 75 + +[.diamond_necklace] +level = 56 +xp = 90 + +[.dragonstone_necklace] +level = 72 +xp = 105 + +[.gold_amulet_unstrung] +level = 8 +xp = 30 + +[.sapphire_amulet_unstrung] +level = 24 +xp = 65 + +[.emerald_amulet_unstrung] +level = 31 +xp = 70 + +[.ruby_amulet_unstrung] +level = 50 +xp = 85 + +[.diamond_amulet_unstrung] +level = 70 +xp = 100 + +[.dragonstone_amulet_unstrung] +level = 80 +xp = 150 + +[.onyx_ring] +level = 67 +xp = 115 + +[.onyx_necklace] +level = 82 +xp = 120 + +[.onyx_amulet_unstrung] +level = 90 +xp = 165 + +[.gold_bracelet] +level = 7 +xp = 25 + +[.sapphire_bracelet] +level = 23 +xp = 60 + +[.emerald_bracelet] +level = 30 +xp = 65 + +[.ruby_bracelet] +level = 42 +xp = 80 + +[.diamond_bracelet] +level = 58 +xp = 95 + +[.dragonstone_bracelet] +level = 74 +xp = 110 + +[.onyx_bracelet] +level = 84 +xp = 125 + +[.ring_of_slaying_8] +level = 75 +xp = 15 diff --git a/data/skill/crafting/silver_casting.tables.toml b/data/skill/crafting/silver_casting.tables.toml new file mode 100644 index 0000000000..eff96713c2 --- /dev/null +++ b/data/skill/crafting/silver_casting.tables.toml @@ -0,0 +1,71 @@ +[silver_casting] +row_id = "item" +level = "int" +xp = "int" +amount = "int" +amount_default = 1 +name = "string" +quest = "string" +product = "item" + +[.bolt_mould] +level = 21 +xp = 500 +amount = 10 +name = "crossbow bolt mould" +product = "silver_bolts_unf" + +[.chain_link_mould] +level = 47 +xp = 1000 +quest = "legacy_of_seergaze" +product = "silvthril_chain" + +[.conductor_mould] +level = 20 +xp = 500 +name = "lightning rod mould" +quest = "creature_of_fenkenstrain" +product = "conductor" + +[.demonic_sigil_mould] +level = 30 +xp = 500 +quest = "shadow_of_the_storm" +product = "demonic_sigil" + +[.holy_mould] +level = 16 +xp = 500 +name = "Saradomin Symbol" +product = "unstrung_symbol" + +[.key_mould] +level = 1 +xp = 0 +quest = "elemental_workshop_iii" +product = "ragged_silver_key" + +[.rod_clay_mould] +level = 25 +xp = 550 +quest = "in_aid_of_the_myreque" +product = "silvthril_rod" + +[.sickle_mould] +level = 18 +xp = 500 +quest = "nature_spirit" +product = "silver_sickle" + +[.tiara_mould] +level = 16 +xp = 525 +product = "tiara" + +[.unholy_mould] +level = 17 +xp = 500 +name = "Unholy Symbol mould" +quest = "observatory_quest" +product = "unstrung_emblem" diff --git a/data/skill/crafting/spinning.tables.toml b/data/skill/crafting/spinning.tables.toml new file mode 100644 index 0000000000..b383ece359 --- /dev/null +++ b/data/skill/crafting/spinning.tables.toml @@ -0,0 +1,63 @@ +[spinning] +row_id = "item" +level = "int" +xp = "int" +quest = "string" +product = "item" + +[.black_wool] +level = 1 +xp = 25 +quest = "shear_shearer_miniquest" +product = "ball_of_black_wool" + +[.flax] +level = 10 +xp = 150 +product = "bowstring" + +[.golden_wool] +level = 40 +xp = 25 +quest = "fremennik_trials" +product = "golden_fleece" + +[.magic_roots] +level = 19 +xp = 300 +product = "magic_string" + +[.maple_roots] +level = 10 +xp = 150 +product = "crossbow_string" + +[.oak_roots] +level = 10 +xp = 150 +product = "crossbow_string" + +[.sinew] +level = 10 +xp = 150 +product = "crossbow_string" + +[.willow_roots] +level = 10 +xp = 150 +product = "crossbow_string" + +[.wool] +level = 1 +xp = 25 +product = "ball_of_wool" + +[.yak_hair] +level = 30 +xp = 250 +product = "rope" + +[.yew_roots] +level = 10 +xp = 150 +product = "crossbow_string" diff --git a/data/skill/crafting/weaving.tables.toml b/data/skill/crafting/weaving.tables.toml new file mode 100644 index 0000000000..3b296f4449 --- /dev/null +++ b/data/skill/crafting/weaving.tables.toml @@ -0,0 +1,30 @@ +[weaving] +row_id = "item" +level = "int" +xp = "int" +amount = "int" +product = "item" +plural = "string" + +[.ball_of_wool] +level = 10 +xp = 120 +product = "strip_of_cloth" +plural = "balls of wool" + +[.flax] +level = 52 +product = "unfinished_net" +plural = "flax" + +[.jute_fibre] +level = 21 +xp = 380 +product = "empty_sack" +plural = "jute fibres" + +[.willow_branch] +level = 36 +xp = 560 +product = "basket" +plural = "willow branches" diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt index 1b001dffe2..df616b7fd3 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt @@ -11,6 +11,8 @@ data class RowDefinition( val stringId: String ) { + val itemId: String get() = stringId.substringAfterLast('.') + fun bool(column: String) = Tables.bool("${stringId}.$column") fun boolOrNull(column: String) = Tables.boolOrNull("${stringId}.$column") diff --git a/game/src/main/kotlin/content/skill/crafting/Jewellery.kt b/game/src/main/kotlin/content/skill/crafting/Jewellery.kt index f326b5cbb0..bc5198259b 100644 --- a/game/src/main/kotlin/content/skill/crafting/Jewellery.kt +++ b/game/src/main/kotlin/content/skill/crafting/Jewellery.kt @@ -8,7 +8,7 @@ import world.gregs.voidps.engine.client.message import world.gregs.voidps.engine.client.sendScript import world.gregs.voidps.engine.client.ui.closeMenu import world.gregs.voidps.engine.client.ui.open -import world.gregs.voidps.engine.data.definition.EnumDefinitions +import world.gregs.voidps.engine.data.definition.Rows import world.gregs.voidps.engine.entity.World import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.name @@ -67,9 +67,8 @@ class Jewellery : Script { item = Item("ring_of_slaying_8") } - val jewellery = EnumDefinitions.intOrNull("jewellery_xp", item.id) - val level = EnumDefinitions.int("jewellery_level", item.id) - if (jewellery == null || !has(Skill.Crafting, level)) { + val row = Rows.getOrNull("jewellery.${item.id}") + if (row == null || !has(Skill.Crafting, row.int("level"))) { item = Item("blank_$type") } interfaces.sendVisibility(id, "make_${type}_option_$gem", !item.id.startsWith("blank")) @@ -92,8 +91,9 @@ class Jewellery : Script { if (amount <= 0) { return } - val xp = EnumDefinitions.intOrNull("jewellery_xp", item.id) ?: return - val level = EnumDefinitions.int("jewellery_level", item.id) + val rows = Rows.getOrNull("jewellery.${item.id}") ?: return + val xp = rows.int("xp") + val level = rows.int("level") if (!has(Skill.Crafting, level, message = true)) { return } diff --git a/game/src/main/kotlin/content/skill/crafting/SilverCasting.kt b/game/src/main/kotlin/content/skill/crafting/SilverCasting.kt index 02bcf9fad3..5deaecc045 100644 --- a/game/src/main/kotlin/content/skill/crafting/SilverCasting.kt +++ b/game/src/main/kotlin/content/skill/crafting/SilverCasting.kt @@ -8,8 +8,9 @@ import world.gregs.voidps.engine.client.message import world.gregs.voidps.engine.client.sendScript import world.gregs.voidps.engine.client.ui.closeMenu import world.gregs.voidps.engine.client.ui.open -import world.gregs.voidps.engine.data.definition.EnumDefinitions import world.gregs.voidps.engine.data.definition.ItemDefinitions +import world.gregs.voidps.engine.data.definition.Rows +import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.skill.Skill import world.gregs.voidps.engine.entity.character.player.skill.exp.exp @@ -20,39 +21,26 @@ import world.gregs.voidps.engine.queue.weakQueue class SilverCasting : Script { - val moulds = listOf( - Item("holy_mould"), - Item("sickle_mould"), - Item("tiara_mould"), - Item("demonic_sigil_mould"), - Item("chain_link_mould"), - Item("unholy_mould"), - Item("conductor_mould"), - Item("rod_clay_mould"), - Item("bolt_mould"), - Item("key_mould"), - ) - init { interfaceOpened("silver_mould") { id -> - for (mould in moulds) { - EnumDefinitions.intOrNull("silver_jewellery_xp", mould.id) ?: continue - val item = EnumDefinitions.string("silver_jewellery_item", mould.id) - val quest = EnumDefinitions.stringOrNull("silver_jewellery_quest", mould.id) - interfaces.sendVisibility(id, mould.id, quest == null || quest(quest) != "unstarted") - val has = carriesItem(mould.id) + for (row in Tables.get("silver_casting").rows()) { + val item = row.item("product") + val quest = row.stringOrNull("quest") + interfaces.sendVisibility(id, row.stringId, quest == null || quest(quest) != "unstarted") + val has = carriesItem(row.itemId) + val mould = ItemDefinitions.get(row.itemId) interfaces.sendText( id, - "${mould.id}_text", + "${row.itemId}_text", if (has) { val colour = if (carriesItem("silver_bar")) "green" else "orange" "<$colour>Make ${ItemDefinitions.get(item).name.toTitleCase()}" } else { - val name = EnumDefinitions.stringOrNull("silver_jewellery_name", mould.id) - "You need a ${name ?: mould.def.name.lowercase()} to make this item." + val name = row.stringOrNull("name") + "You need a ${name ?: mould.name.lowercase()} to make this item." }, ) - interfaces.sendItem(id, "${mould.id}_model", if (has) ItemDefinitions.get(item).id else mould.def.id) + interfaces.sendItem(id, "${row.itemId}_model", if (has) ItemDefinitions.get(item).id else mould.id) } } @@ -84,9 +72,10 @@ class SilverCasting : Script { if (amount <= 0) { return } - val exp = EnumDefinitions.intOrNull("silver_jewellery_xp", item.id) ?: return - val product = EnumDefinitions.string("silver_jewellery_item", item.id) - val produce = EnumDefinitions.int("silver_jewellery_amount", item.id) + val row = Rows.getOrNull("silver_casting.${item.id}") ?: return + val exp = row.int("xp") + val product = row.item("product") + val produce = row.int("amount") closeMenu() if (!inventory.contains(item.id)) { message("You need a ${item.def.name} in order to make a ${ItemDefinitions.get(product).name}.") @@ -96,7 +85,7 @@ class SilverCasting : Script { message("You need a silver bar in order to make a ${ItemDefinitions.get(product).name}.") return } - val level = EnumDefinitions.int("silver_jewellery_level", item.id) + val level = row.int("level") if (!has(Skill.Crafting, level)) { return } diff --git a/game/src/main/kotlin/content/skill/crafting/SpinningWheel.kt b/game/src/main/kotlin/content/skill/crafting/SpinningWheel.kt index 0668548eff..db60fa4aa8 100644 --- a/game/src/main/kotlin/content/skill/crafting/SpinningWheel.kt +++ b/game/src/main/kotlin/content/skill/crafting/SpinningWheel.kt @@ -7,7 +7,8 @@ import net.pearx.kasechange.toLowerSpaceCase import net.pearx.kasechange.toSentenceCase import world.gregs.voidps.engine.Script import world.gregs.voidps.engine.client.message -import world.gregs.voidps.engine.data.definition.EnumDefinitions +import world.gregs.voidps.engine.data.config.RowDefinition +import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.skill.Skill import world.gregs.voidps.engine.entity.character.player.skill.exp.exp @@ -44,7 +45,7 @@ class SpinningWheel : Script { (fibre.id != "black_wool" || quest("sheep_shearer_miniquest") == "started") && (fibre.id != "golden_wool" || (quest("fremennik_trials") == "started") || (quest("fremennik_trials") == "completed")) } val strings = availableFibres.map { - if (it.id == "tree_roots") "crossbow_string" else EnumDefinitions.string("spinning_item", it.id) + if (it.id == "tree_roots") "crossbow_string" else Tables.item("spinning.${it.id}.product") } val (index, amount) = makeAmountIndex( items = strings, @@ -57,55 +58,61 @@ class SpinningWheel : Script { ) delay() - var fibre = fibres[index] - if (fibre.id == "tree_roots") { + var item = fibres[index] + if (item.id == "tree_roots") { val root = treeRoots.firstOrNull { inventory.contains(it.id) } if (root == null) { message("You need some tree roots in order to make a crossbow string.") return@objectOperate } - fibre = root + item = root } - start(this, target, fibre, amount) + val row = Tables.get("spinning").rows().firstOrNull { it.itemId == item.id } ?: return@objectOperate + start(this, target, row, amount) } itemOnObjectOperate(obj = "spinning_wheel*", arrive = false) { (target, item) -> if (!item.def.contains("spinning")) { return@itemOnObjectOperate } + val rows = Tables.get("spinning").rows() + val row = rows.firstOrNull { it.itemId == item.id } ?: return@itemOnObjectOperate + val product = row.item("product") val (_, amount) = makeAmount( - items = listOf(EnumDefinitions.string("spinning_item", item.id)), + items = listOf(product), type = "Make", maximum = inventory.count(item.id), text = "How many would you like to make?", ) - start(this, target, item, amount) + start(this, target, row, amount) } } - fun start(player: Player, obj: GameObject, fibre: Item, amount: Int) { - val current = player.inventory.count(fibre.id) + fun start(player: Player, obj: GameObject, row: RowDefinition, amount: Int) { + val id = row.itemId + val current = player.inventory.count(id) if (current <= 0) { - val item = EnumDefinitions.string("spinning_item", fibre.id) - player.message("You need some ${fibre.id.toLowerSpaceCase()} in order to make a ${item.toLowerSpaceCase()}.") + val item = row.item("product") + player.message("You need some ${id.toLowerSpaceCase()} in order to make a ${item.toLowerSpaceCase()}.") return } val actualAmount = if (current < amount) current else amount - player.spin(obj, fibre, actualAmount) + player.spin(obj, row, actualAmount) } - fun Player.spin(obj: GameObject, fibre: Item, amount: Int) { + fun Player.spin(obj: GameObject, row: RowDefinition, amount: Int) { + val id = row.itemId if (amount <= 0) { return } - val item = EnumDefinitions.string("spinning_item", fibre.id) - val current = inventory.count(fibre.id) + val item = row.item("product") + val current = inventory.count(id) if (current <= 0) { - message("You need some ${fibre.id.toLowerSpaceCase()} in order to make a ${item.toLowerSpaceCase()}.") + message("You need some ${id.toLowerSpaceCase()} in order to make a ${item.toLowerSpaceCase()}.") return } face(obj) - val level = EnumDefinitions.int("spinning_level", fibre.id) + val level = row.int("level") if (!has(Skill.Crafting, level)) { return } @@ -113,13 +120,13 @@ class SpinningWheel : Script { anim("spinning") sound("spinning") weakQueue("spin", 3) { - if (!inventory.replace(fibre.id, item)) { - message("You need some ${fibre.id.toLowerSpaceCase()} in order to make a ${item.toLowerSpaceCase()}.") + if (!inventory.replace(id, item)) { + message("You need some ${id.toLowerSpaceCase()} in order to make a ${item.toLowerSpaceCase()}.") return@weakQueue } - val xp = EnumDefinitions.int("spinning_xp", fibre.id) / 10.0 + val xp = row.int("xp") / 10.0 exp(Skill.Crafting, xp) - spin(obj, fibre, amount - 1) + spin(obj, row, amount - 1) } } } diff --git a/game/src/main/kotlin/content/skill/crafting/Weaving.kt b/game/src/main/kotlin/content/skill/crafting/Weaving.kt index f30216ff7d..2d16a88ce9 100644 --- a/game/src/main/kotlin/content/skill/crafting/Weaving.kt +++ b/game/src/main/kotlin/content/skill/crafting/Weaving.kt @@ -6,13 +6,12 @@ import net.pearx.kasechange.toLowerSpaceCase import world.gregs.voidps.engine.Script import world.gregs.voidps.engine.client.message import world.gregs.voidps.engine.client.ui.chat.an -import world.gregs.voidps.engine.client.ui.chat.plural -import world.gregs.voidps.engine.data.definition.EnumDefinitions +import world.gregs.voidps.engine.data.config.RowDefinition +import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.skill.Skill import world.gregs.voidps.engine.entity.character.player.skill.exp.exp import world.gregs.voidps.engine.entity.character.player.skill.level.Level.has -import world.gregs.voidps.engine.entity.item.Item import world.gregs.voidps.engine.entity.obj.GameObject import world.gregs.voidps.engine.inv.inventory import world.gregs.voidps.engine.inv.transact.TransactionError @@ -22,81 +21,71 @@ import world.gregs.voidps.engine.queue.weakQueue class Weaving : Script { - val materials = listOf( - Item("willow_branch"), - Item("jute_fibre"), - Item("flax"), - Item("ball_of_wool"), - ) - init { objectOperate("Weave", "loom_*", arrive = false) { (target) -> - val strings = EnumDefinitions.get("weaving_product").map!!.values.filterIsInstance() + val rows = Tables.get("weaving").rows() + val strings = rows.map { it.stringId } val (index, amount) = makeAmountIndex( items = strings, type = "Make", maximum = 28, text = "How many would you like to make?", ) - val item = materials[index] - weave(target, item, amount) + val row = rows[index] + weave(target, row, amount) } itemOnObjectOperate(obj = "loom_*", arrive = false) { (target, item) -> - val product = EnumDefinitions.stringOrNull("weaving_product", item.id) ?: return@itemOnObjectOperate - val produced = EnumDefinitions.int("weaving_amount", item.id) + val rows = Tables.get("weaving").rows() + val row = rows.firstOrNull { it.itemId == item.id } ?: return@itemOnObjectOperate + val product = row.item("product") + val produced = row.int("amount") val (_, amount) = makeAmount( items = listOf(product), type = "Make", maximum = inventory.count(item.id) / produced, text = "How many would you like to make?", ) - weave(target, item, amount) + weave(target, row, amount) } } - fun Player.weave(obj: GameObject, item: Item, amount: Int) { + fun Player.weave(obj: GameObject, row: RowDefinition, amount: Int) { if (amount <= 0) { return } - val current = inventory.count(item.id) - val product = EnumDefinitions.string("weaving_product", item.id) - val produced = EnumDefinitions.int("weaving_amount", item.id) + val current = inventory.count(row.itemId) + val product = row.item("product") + val produced = row.int("amount") + val plural = row.string("plural") if (current < produced) { val name = product.toLowerSpaceCase() - message("You need $produced ${plural(item)} in order to make${name.an()} $name.") + message("You need $produced $plural in order to make${name.an()} $name.") return } face(obj) - val level = EnumDefinitions.int("weaving_level", item.id) + val level = row.int("level") if (!has(Skill.Crafting, level)) { return } anim("weaving") weakQueue("weave", 4) { inventory.transaction { - remove(item.id, produced) + remove(row.itemId, produced) add(product) } when (inventory.transaction.error) { is TransactionError.Full, is TransactionError.Deficient -> { val name = product.toLowerSpaceCase() - message("You need $produced ${plural(item)} in order to make${name.an()} $name.") + message("You need $produced $plural in order to make${name.an()} $name.") return@weakQueue } else -> {} } - val xp = EnumDefinitions.int("weaving_xp", item.id) / 10.0 + val xp = row.int("xp") / 10.0 exp(Skill.Crafting, xp) - weave(obj, item, amount - 1) + weave(obj, row, amount - 1) } } - fun plural(item: Item): String = when (item.id) { - "willow_branch" -> "willow branches" - "jute_fibre" -> "jute fibres" - "flax" -> "flax" - "ball_of_wool" -> "balls of wool" - else -> item.id.plural() - } } diff --git a/game/src/main/kotlin/content/skill/slayer/Slayer.kt b/game/src/main/kotlin/content/skill/slayer/Slayer.kt index e09eb8c961..1c51e42742 100644 --- a/game/src/main/kotlin/content/skill/slayer/Slayer.kt +++ b/game/src/main/kotlin/content/skill/slayer/Slayer.kt @@ -95,14 +95,14 @@ private fun rollTask(player: Player, master: String): Pair? { if (roll < count) { val range = table.get("amount", row, ColumnType.ColumnIntRange) val row = Rows.get(row) - return Pair(row.stringId, range.random(random)) + return Pair(row.itemId, range.random(random)) } } return null } private fun hasRequirements(player: Player, table: TableDefinition, row: Int): Boolean { - val category = Rows.get(row).stringId + val category = Rows.get(row).itemId val npc = Tables.int("slayer_tasks.${category}.npc") val slayerLevel = NPCDefinitions.get(npc)["slayer_level", 1] if (!player.has(Skill.Slayer, slayerLevel)) { diff --git a/game/src/test/kotlin/content/skill/crafting/SilverCastingTest.kt b/game/src/test/kotlin/content/skill/crafting/SilverCastingTest.kt new file mode 100644 index 0000000000..e0df8d5418 --- /dev/null +++ b/game/src/test/kotlin/content/skill/crafting/SilverCastingTest.kt @@ -0,0 +1,32 @@ +package content.skill.crafting + +import WorldTest +import itemOnObject +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Test +import world.gregs.voidps.engine.entity.character.player.skill.Skill +import world.gregs.voidps.engine.entity.obj.GameObjects +import world.gregs.voidps.engine.inv.add +import world.gregs.voidps.engine.inv.inventory +import world.gregs.voidps.type.Tile + +class SilverCastingTest : WorldTest() { + + @Test + fun `Silver casting`() { + val player = createPlayer(Tile(3227, 3255)) + player.levels.set(Skill.Crafting, 99) + player.inventory.add("bolt_mould") + player.inventory.add("silver_bar") + + val furnace = GameObjects.find(Tile(3226, 3256), "furnace_lumbridge") + + player.itemOnObject(furnace, 0) + tick(4) + + assertEquals(1, player.inventory.count("bolt_mould")) + assertEquals(0, player.inventory.count("silver_bar")) + assertEquals(10, player.inventory.count("silver_bolts_unf")) + assertNotEquals(0.0, player.experience.get(Skill.Crafting)) + } +} \ No newline at end of file From a2433753020e55c673b46780c6677b86a78b61ff Mon Sep 17 00:00:00 2001 From: GregHib Date: Thu, 26 Mar 2026 15:58:38 +0000 Subject: [PATCH 17/40] Convert firemaking enums --- data/skill/firemaking/firemaking.enums.toml | 129 ------------- data/skill/firemaking/firemaking.tables.toml | 175 ++++++++++++++++++ .../content/skill/firemaking/Firemaking.kt | 30 ++- 3 files changed, 188 insertions(+), 146 deletions(-) delete mode 100644 data/skill/firemaking/firemaking.enums.toml create mode 100644 data/skill/firemaking/firemaking.tables.toml diff --git a/data/skill/firemaking/firemaking.enums.toml b/data/skill/firemaking/firemaking.enums.toml deleted file mode 100644 index 65fc90bad2..0000000000 --- a/data/skill/firemaking/firemaking.enums.toml +++ /dev/null @@ -1,129 +0,0 @@ -[firemaking_level] -keyType = "item" -valueType = "int" -defaultInt = 1 -values = { - eucalyptus_logs = 58, - arctic_pine_logs = 42, - cursed_magic_logs = 82, - seeping_elm_branches = 10, - blood_spindle_branches = 20, - utuku_branches = 30, - spinebeam_branches = 40, - bovistrangler_branches = 50, - thigat_branches = 60, - corpsethorn_branches = 70, - entgallow_branches = 80, - grave_creeper_branches = 90, - magic_logs = 75, - yew_logs = 60, - maple_logs = 45, - willow_logs = 30, - oak_logs = 15, - mahogany_logs = 50, - teak_logs = 35, -} - -[firemaking_xp] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - red_logs = 500, - green_logs = 500, - blue_logs = 500, - white_logs = 500, - purple_logs = 500, - eucalyptus_logs = 1935, - achey_tree_logs = 400, - arctic_pine_logs = 1250, - cursed_magic_logs = 3038, - tangle_gum_branches = 250, - seeping_elm_branches = 445, - blood_spindle_branches = 656, - utuku_branches = 883, - spinebeam_branches = 1126, - bovistrangler_branches = 1385, - thigat_branches = 1660, - corpsethorn_branches = 1951, - entgallow_branches = 2258, - grave_creeper_branches = 2581, - logs = 400, - magic_logs = 3038, - yew_logs = 2025, - maple_logs = 1350, - willow_logs = 900, - oak_logs = 600, - mahogany_logs = 1575, - teak_logs = 1050, -} - -[firemaking_chance_min] -keyType = "item" -valueType = "int" -defaultInt = 65 -values = { - red_logs = 256, - green_logs = 256, - blue_logs = 256, - white_logs = 256, - purple_logs = 256, -} - -[firemaking_chance_max] -keyType = "item" -valueType = "int" -defaultInt = 513 -values = { - red_logs = 256, - green_logs = 256, - blue_logs = 256, - white_logs = 256, - purple_logs = 256, -} - -[firemaking_life] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - red_logs = 60, - green_logs = 60, - blue_logs = 60, - white_logs = 60, - purple_logs = 60, - eucalyptus_logs = 140, - achey_tree_logs = 60, - arctic_pine_logs = 100, - cursed_magic_logs = 200, - tangle_gum_branches = 60, - seeping_elm_branches = 75, - blood_spindle_branches = 82, - utuku_branches = 90, - spinebeam_branches = 100, - bovistrangler_branches = 120, - thigat_branches = 140, - corpsethorn_branches = 170, - entgallow_branches = 185, - grave_creeper_branches = 200, - logs = 60, - magic_logs = 180, - yew_logs = 160, - maple_logs = 100, - willow_logs = 90, - oak_logs = 90, - mahogany_logs = 140, - teak_logs = 90, -} - -[firemaking_colour] -keyType = "item" -valueType = "string" -defaultString = "orange" -values = { - red_logs = "red", - green_logs = "green", - blue_logs = "blue", - white_logs = "white", - purple_logs = "purple", -} \ No newline at end of file diff --git a/data/skill/firemaking/firemaking.tables.toml b/data/skill/firemaking/firemaking.tables.toml new file mode 100644 index 0000000000..3ea44b4906 --- /dev/null +++ b/data/skill/firemaking/firemaking.tables.toml @@ -0,0 +1,175 @@ +[firemaking] +row_id = "item" +level = "int" +xp = "int" +life = "int" +colour = "string" +colour_default = "orange" +chance = "range" + +[.red_logs] +level = 1 +xp = 500 +life = 60 +colour = "red" +chance = [256, 256] + +[.green_logs] +level = 1 +xp = 500 +life = 60 +colour = "green" +chance = [256, 256] + +[.blue_logs] +level = 1 +xp = 500 +life = 60 +colour = "blue" +chance = [256, 256] + +[.white_logs] +level = 1 +xp = 500 +life = 60 +colour = "white" +chance = [256, 256] + +[.purple_logs] +level = 1 +xp = 500 +life = 60 +colour = "purple" +chance = [256, 256] + +[.eucalyptus_logs] +level = 58 +xp = 1935 +life = 140 +chance = [65, 513] + +[.achey_tree_logs] +level = 1 +xp = 400 +life = 60 +chance = [65, 513] + +[.arctic_pine_logs] +level = 42 +xp = 1250 +life = 100 +chance = [65, 513] + +[.cursed_magic_logs] +level = 82 +xp = 3038 +life = 200 +chance = [65, 513] + +[.tangle_gum_branches] +level = 1 +xp = 250 +life = 60 +chance = [65, 513] + +[.seeping_elm_branches] +level = 10 +xp = 445 +life = 75 +chance = [65, 513] + +[.blood_spindle_branches] +level = 20 +xp = 656 +life = 82 +chance = [65, 513] + +[.utuku_branches] +level = 30 +xp = 883 +life = 90 +chance = [65, 513] + +[.spinebeam_branches] +level = 40 +xp = 1126 +life = 100 +chance = [65, 513] + +[.bovistrangler_branches] +level = 50 +xp = 1385 +life = 120 +chance = [65, 513] + +[.thigat_branches] +level = 60 +xp = 1660 +life = 140 +chance = [65, 513] + +[.corpsethorn_branches] +level = 70 +xp = 1951 +life = 170 +chance = [65, 513] + +[.entgallow_branches] +level = 80 +xp = 2258 +life = 185 +chance = [65, 513] + +[.grave_creeper_branches] +level = 90 +xp = 2581 +life = 200 +chance = [65, 513] + +[.logs] +level = 1 +xp = 400 +life = 60 +chance = [65, 513] + +[.magic_logs] +level = 75 +xp = 3038 +life = 180 +chance = [65, 513] + +[.yew_logs] +level = 60 +xp = 2025 +life = 160 +chance = [65, 513] + +[.maple_logs] +level = 45 +xp = 1350 +life = 100 +chance = [65, 513] + +[.willow_logs] +level = 30 +xp = 900 +life = 90 +chance = [65, 513] + +[.oak_logs] +level = 15 +xp = 600 +life = 90 +chance = [65, 513] + +[.mahogany_logs] +level = 50 +xp = 1575 +life = 140 +chance = [65, 513] + +[.teak_logs] +level = 35 +xp = 1050 +life = 90 +chance = [65, 513] diff --git a/game/src/main/kotlin/content/skill/firemaking/Firemaking.kt b/game/src/main/kotlin/content/skill/firemaking/Firemaking.kt index 0315565d00..a8a78acd2b 100644 --- a/game/src/main/kotlin/content/skill/firemaking/Firemaking.kt +++ b/game/src/main/kotlin/content/skill/firemaking/Firemaking.kt @@ -6,7 +6,9 @@ import world.gregs.voidps.engine.client.message import world.gregs.voidps.engine.client.ui.closeDialogue import world.gregs.voidps.engine.client.variable.remaining import world.gregs.voidps.engine.client.variable.start +import world.gregs.voidps.engine.data.config.RowDefinition import world.gregs.voidps.engine.data.definition.EnumDefinitions +import world.gregs.voidps.engine.data.definition.Rows import world.gregs.voidps.engine.entity.character.mode.interact.Interact import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.chat.ChatType @@ -45,14 +47,10 @@ class Firemaking : Script { } itemOnFloorItemOperate("tinderbox*", "*log*") { (target) -> - if (burnable(target.id)) { - arriveDelay() - lightFire(this, target) - } + lightFire(this, target) } floorItemOperate("Light") { (target) -> - arriveDelay() lightFire(this, target) } } @@ -61,14 +59,13 @@ class Firemaking : Script { player: Player, floorItem: FloorItem, ) { - if (!burnable(floorItem.id)) { - return - } + val row = Rows.getOrNull("firemaking.${floorItem.id}") ?: return + player.arriveDelay() player.softTimers.start("firemaking") val log = Item(floorItem.id) var first = true while (player.awaitDialogues()) { - val level = EnumDefinitions.int("firemaking_level", log.id) + val level = row.int("level") if (!player.canLight(log.id, level, floorItem)) { break } @@ -84,12 +81,11 @@ class Firemaking : Script { } else if (remaining > 0) { player.pause(remaining) } - val chanceMin = EnumDefinitions.int("firemaking_chance_min", log.id) - val chanceMax = EnumDefinitions.int("firemaking_chance_max", log.id) - if (Level.success(player.levels.get(Skill.Firemaking), chanceMin..chanceMax) && FloorItems.remove(floorItem)) { + val chance = row.intRange("chance") + if (Level.success(player.levels.get(Skill.Firemaking), chance) && FloorItems.remove(floorItem)) { player.message("The fire catches and the logs begin to burn.", ChatType.Filter) - player.exp(Skill.Firemaking, EnumDefinitions.int("firemaking_xp", log.id) / 10.0) - spawnFire(player, floorItem.tile, log.id) + player.exp(Skill.Firemaking, row.int("xp") / 10.0) + spawnFire(player, floorItem.tile, row) break } } @@ -116,9 +112,9 @@ class Firemaking : Script { return FloorItems.at(item.tile).contains(item) } - fun spawnFire(player: Player, tile: Tile, id: String) { - val colour = EnumDefinitions.string("firemaking_colour", id) - val life = EnumDefinitions.int("firemaking_life", id) + fun spawnFire(player: Player, tile: Tile, row: RowDefinition) { + val colour = row.string("colour") + val life = row.int("life") val obj = GameObjects.add("fire_$colour", tile, shape = ObjectShape.CENTRE_PIECE_STRAIGHT, rotation = 0, ticks = life) FloorItems.add(tile, "ashes", revealTicks = life, disappearTicks = 60, owner = "") val interact = player.mode as Interact From 351848ae59aa6daa77dbae7645d02037dfabb1ba Mon Sep 17 00:00:00 2001 From: GregHib Date: Thu, 26 Mar 2026 16:07:11 +0000 Subject: [PATCH 18/40] Convert mining enums --- data/skill/mining/mining.enums.toml | 178 ---------------- data/skill/mining/ores.tables.toml | 190 ++++++++++++++++++ .../kotlin/content/skill/mining/Mining.kt | 31 +-- 3 files changed, 206 insertions(+), 193 deletions(-) create mode 100644 data/skill/mining/ores.tables.toml diff --git a/data/skill/mining/mining.enums.toml b/data/skill/mining/mining.enums.toml index 8f542a540d..8a13a29dc5 100644 --- a/data/skill/mining/mining.enums.toml +++ b/data/skill/mining/mining.enums.toml @@ -1,129 +1,3 @@ -[mining_xp] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - stardust = 800, - blurite_ore = 175, - limestone = 265, - uncut_diamond = 650, - uncut_ruby = 650, - uncut_emerald = 650, - uncut_sapphire = 650, - uncut_opal = 650, - uncut_jade = 650, - uncut_red_topaz = 650, - clay = 50, - copper_ore = 175, - tin_ore = 175, - iron_ore = 350, - silver_ore = 400, - gold_ore = 650, - mithril_ore = 800, - adamantite_ore = 950, - runite_ore = 1250, - coal = 500, - sandstone_1kg = 300, - sandstone_2kg = 400, - sandstone_5kg = 500, - sandstone_10kg = 600, - granite_500g = 500, - granite_2kg = 600, - granite_5kg = 750, - rune_essence = 50, - pure_essence = 50, -} - -[mining_chance_min] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - stardust = 10, - blurite_ore = 30, - limestone = 25, - uncut_diamond = 8, - uncut_ruby = 10, - uncut_emerald = 10, - uncut_sapphire = 18, - uncut_opal = 120, - uncut_jade = 60, - uncut_red_topaz = 30, - clay = 75, - copper_ore = 40, - tin_ore = 40, - iron_ore = 110, - silver_ore = 25, - gold_ore = 7, - mithril_ore = 10, - adamantite_ore = 5, - runite_ore = 1, - coal = 20, - sandstone_1kg = 25, - sandstone_2kg = 16, - sandstone_5kg = 8, - sandstone_10kg = 4, - granite_500g = 16, - granite_2kg = 8, - granite_5kg = 6, - rune_essence = 200, - pure_essence = 150, -} - -[mining_chance_max] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - stardust = 75, - blurite_ore = 375, - limestone = 200, - uncut_diamond = 8, - uncut_ruby = 10, - uncut_emerald = 10, - uncut_sapphire = 18, - uncut_opal = 120, - uncut_jade = 60, - uncut_red_topaz = 30, - clay = 300, - copper_ore = 500, - tin_ore = 500, - iron_ore = 350, - silver_ore = 200, - gold_ore = 75, - mithril_ore = 75, - adamantite_ore = 55, - runite_ore = 18, - coal = 150, - sandstone_1kg = 200, - sandstone_2kg = 100, - sandstone_5kg = 75, - sandstone_10kg = 50, - granite_500g = 100, - granite_2kg = 75, - granite_5kg = 64, - rune_essence = 400, - pure_essence = 350, -} - -[mining_level] -keyType = "item" -valueType = "int" -defaultInt = 1 -values = { - adamantite_ore = 70, - gold_ore = 40, - coal = 30, - mithril_ore = 55, - blurite_ore = 10, - iron_ore = 15, - uncut_opal = 40, - silver_ore = 20, - sandstone_1kg = 35, - runite_ore = 85, - granite_500g = 45, -} - [mining_ores] keyType = "object" valueType = "string" @@ -494,55 +368,3 @@ values = { tin_rocks_tourist_trap_3 = "tin_ore", tin_rocks_tutorial_island_1 = "tin_ore", } - - -[mining_gems] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - copper_ore = 1, - tin_ore = 1, - adamantite_ore = 1, - gold_ore = 1, - coal = 1, - mithril_ore = 1, - blurite_ore = 1, - iron_ore = 1, - stardust = 1, - silver_ore = 1, - runite_ore = 1, - clay = 1, -} - -[mining_life] -keyType = "item" -valueType = "int" -defaultInt = -1 -values = { - copper_ore = 4, - tin_ore = 4, - adamantite_ore = 400, - gold_ore = 100, - coal = 50, - mithril_ore = 200, - blurite_ore = 42, - iron_ore = 9, - uncut_opal = 99, - uncut_jade = 99, - uncut_red_topaz = 99, - uncut_sapphire = 99, - uncut_emerald = 99, - uncut_ruby = 99, - uncut_diamond = 99, - silver_ore = 100, - sandstone_1kg = 7, - sandstone_2kg = 7, - sandstone_5kg = 7, - sandstone_10kg = 7, - runite_ore = 1200, - clay = 2, - granite_500g = 8, - granite_2kg = 8, - granite_5kg = 8, -} \ No newline at end of file diff --git a/data/skill/mining/ores.tables.toml b/data/skill/mining/ores.tables.toml new file mode 100644 index 0000000000..47228bd1d1 --- /dev/null +++ b/data/skill/mining/ores.tables.toml @@ -0,0 +1,190 @@ +[ores] +row_id = "item" +level = "int" +xp = "int" +gems = "boolean" +life = "int" +life_default = -1 +chance = "range" + +[.stardust] +level = 1 +xp = 800 +gems = true +chance = [10, 75] + +[.blurite_ore] +level = 10 +xp = 175 +gems = true +life = 42 +chance = [30, 375] + +[.limestone] +level = 1 +xp = 265 +chance = [25, 200] + +[.uncut_diamond] +level = 1 +xp = 650 +life = 99 +chance = [8, 8] + +[.uncut_ruby] +level = 1 +xp = 650 +life = 99 +chance = [10, 10] + +[.uncut_emerald] +level = 1 +xp = 650 +life = 99 +chance = [10, 10] + +[.uncut_sapphire] +level = 1 +xp = 650 +life = 99 +chance = [18, 18] + +[.uncut_opal] +level = 40 +xp = 650 +life = 99 +chance = [120, 120] + +[.uncut_jade] +level = 1 +xp = 650 +life = 99 +chance = [60, 60] + +[.uncut_red_topaz] +level = 1 +xp = 650 +life = 99 +chance = [30, 30] + +[.clay] +level = 1 +xp = 50 +gems = true +life = 2 +chance = [75, 300] + +[.copper_ore] +level = 1 +xp = 175 +gems = true +life = 4 +chance = [40, 500] + +[.tin_ore] +level = 1 +xp = 175 +gems = true +life = 4 +chance = [40, 500] + +[.iron_ore] +level = 15 +xp = 350 +gems = true +life = 9 +chance = [110, 350] + +[.silver_ore] +level = 20 +xp = 400 +gems = true +life = 100 +chance = [25, 200] + +[.gold_ore] +level = 40 +xp = 650 +gems = true +life = 100 +chance = [7, 75] + +[.mithril_ore] +level = 55 +xp = 800 +gems = true +life = 200 +chance = [10, 75] + +[.adamantite_ore] +level = 70 +xp = 950 +gems = true +life = 400 +chance = [5, 55] + +[.runite_ore] +level = 85 +xp = 1250 +gems = true +life = 1200 +chance = [1, 18] + +[.coal] +level = 30 +xp = 500 +gems = true +life = 50 +chance = [20, 150] + +[.sandstone_1kg] +level = 35 +xp = 300 +life = 7 +chance = [25, 200] + +[.sandstone_2kg] +level = 1 +xp = 400 +life = 7 +chance = [16, 100] + +[.sandstone_5kg] +level = 1 +xp = 500 +life = 7 +chance = [8, 75] + +[.sandstone_10kg] +level = 1 +xp = 600 +life = 7 +chance = [4, 50] + +[.granite_500g] +level = 45 +xp = 500 +life = 8 +chance = [16, 100] + +[.granite_2kg] +level = 1 +xp = 600 +life = 8 +chance = [8, 75] + +[.granite_5kg] +level = 1 +xp = 750 +life = 8 +chance = [6, 64] + +[.rune_essence] +level = 1 +xp = 50 +chance = [200, 400] + +[.pure_essence] +level = 1 +xp = 50 +chance = [150, 350] diff --git a/game/src/main/kotlin/content/skill/mining/Mining.kt b/game/src/main/kotlin/content/skill/mining/Mining.kt index 405174d247..5a201f3777 100644 --- a/game/src/main/kotlin/content/skill/mining/Mining.kt +++ b/game/src/main/kotlin/content/skill/mining/Mining.kt @@ -9,6 +9,8 @@ import world.gregs.voidps.engine.client.variable.remaining import world.gregs.voidps.engine.client.variable.start import world.gregs.voidps.engine.client.variable.stop import world.gregs.voidps.engine.data.definition.EnumDefinitions +import world.gregs.voidps.engine.data.definition.Rows +import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.World import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.chat.ChatType @@ -76,13 +78,13 @@ class Mining : Script { message("Your inventory is too full to hold any more ore.") break } - - val ore = EnumDefinitions.stringOrNull("mining_ores", target.id) ?: break + val type = EnumDefinitions.stringOrNull("mining_ores", target.id) ?: break + val ore = Rows.getOrNull("ores.$type") ?: break val stringId = target.def(this).stringId val level = if (stringId.startsWith("crashed_star_tier_")) { stringId.removePrefix("crashed_star_tier_").toInt() * 10 } else { - EnumDefinitions.int("mining_level", ore) + ore.int("level") } if (!has(Skill.Mining, level, true)) { break @@ -110,7 +112,7 @@ class Mining : Script { if (!GameObjects.contains(target)) { break } - if (EnumDefinitions.contains("mining_gems", target.id)) { + if (ore.bool("gems")) { val glory = equipped(EquipSlot.Amulet).id.startsWith("amulet_of_glory_") if (success(levels.get(Skill.Mining), if (glory) 3..3 else 1..1)) { addOre(this, gems.random()) @@ -126,19 +128,18 @@ class Mining : Script { ores.add("rune_essence") } } - ore == "granite_500g" -> ores.addAll(granite) - ore == "sandstone_1kg" -> ores.addAll(sandstone) - ore == "uncut_opal" -> ores.addAll(gemRocks) - else -> ores.add(ore) + ore.itemId == "granite_500g" -> ores.addAll(granite) + ore.itemId == "sandstone_1kg" -> ores.addAll(sandstone) + ore.itemId == "uncut_opal" -> ores.addAll(gemRocks) + else -> ores.add(ore.itemId) } for (item in ores) { - val chanceMin = EnumDefinitions.int("mining_chance_min", item) - val chanceMax = EnumDefinitions.int("mining_chance_max", item) - if (success(levels.get(Skill.Mining), chanceMin..chanceMax)) { - val xp = EnumDefinitions.int("mining_xp", item) / 10.0 + val chance = Tables.intRange("mining_ores.${item}.chance") + if (success(levels.get(Skill.Mining), chance)) { + val xp = Tables.int("mining_ores.${item}.xp") / 10.0 exp(Skill.Mining, xp) ShootingStarHandler.extraOreHandler(this, item, xp) - if (!addOre(this, item) || deplete(target, EnumDefinitions.int("mining_life", item))) { + if (!addOre(this, item) || deplete(target, Tables.int("mining_ores.${item}.life"))) { clearAnim() break } @@ -161,11 +162,11 @@ class Mining : Script { } message("You examine the rock for ores...") delay(4) - val ore = EnumDefinitions.stringOrNull("mining_ores", target.def(this).stringId) + val ore = Rows.getOrNull("mining_ores.${target.def(this).stringId}") if (ore == null) { message("This rock contains no ore.") } else { - message("This rock contains ${ore.toLowerSpaceCase()}.") + message("This rock contains ${ore.itemId.toLowerSpaceCase()}.") } } } From 3fb9823cdb78ffc8d82204d07916eb5ed73ee152 Mon Sep 17 00:00:00 2001 From: GregHib Date: Thu, 26 Mar 2026 17:00:05 +0000 Subject: [PATCH 19/40] Convert fishing enums --- data/skill/fishing/fishing.enums.toml | 419 ------------------ data/skill/fishing/fishing.tables.toml | 260 +++++++++++ data/skill/fishing/fishing_spots.tables.toml | 255 +++++++++++ .../engine/data/config/RowDefinition.kt | 2 + .../engine/data/config/TableDefinition.kt | 5 +- .../engine/data/definition/ColumnReader.kt | 4 +- .../voidps/engine/data/definition/Tables.kt | 15 +- .../kotlin/content/skill/fishing/Fishing.kt | 28 +- .../kotlin/content/skill/mining/Mining.kt | 6 +- 9 files changed, 548 insertions(+), 446 deletions(-) delete mode 100644 data/skill/fishing/fishing.enums.toml create mode 100644 data/skill/fishing/fishing.tables.toml create mode 100644 data/skill/fishing/fishing_spots.tables.toml diff --git a/data/skill/fishing/fishing.enums.toml b/data/skill/fishing/fishing.enums.toml deleted file mode 100644 index c3fde18356..0000000000 --- a/data/skill/fishing/fishing.enums.toml +++ /dev/null @@ -1,419 +0,0 @@ -[fishing_levels] -keyType = "item" -valueType = "int" -defaultInt = 1 -values = { - raw_cavefish = 85, - raw_rocktail = 90, - swamp_weed = 33, - cave_eel = 38, - frog_spawn = 33, - slimy_eel = 28, - raw_monkfish = 62, - raw_karambwanji = 5, - leaping_trout = 48, - leaping_salmon = 58, - leaping_sturgeon = 70, - lava_eel = 53, - raw_vile_fish = 1, - raw_heim_crab = 1, - raw_red_eye = 10, - raw_dusk_eel = 20, - raw_giant_flatfish = 30, - raw_short_finned_eel = 40, - raw_web_snipper = 50, - raw_bouldabass = 60, - raw_salve_eel = 70, - raw_blue_crab = 80, - raw_cave_moray = 90, - raw_shrimps = 0, - raw_anchovies = 15, - raw_sardine = 5, - raw_salmon = 30, - raw_trout = 20, - raw_cod = 23, - raw_herring = 10, - raw_pike = 25, - raw_mackerel = 16, - raw_tuna = 35, - raw_bass = 46, - raw_swordfish = 50, - raw_lobster = 40, - raw_shark = 76, - raw_manta_ray = 81, - raw_sea_turtle = 79, - raw_karambwan = 65, - raw_rainbow_fish = 38, - raw_crayfish = 0, - seaweed = 16, - casket = 16, - oyster = 16, - leather_gloves = 16, - leather_boots = 16, - sluglings = 50, -} - -[fishing_experience] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - raw_cavefish = 300, - raw_rocktail = 380, - swamp_weed = 1, - cave_eel = 80, - frog_spawn = 75, - slimy_eel = 65, - raw_monkfish = 120, - raw_karambwanji = 5, - leaping_trout = 50, - leaping_salmon = 70, - leaping_sturgeon = 80, - lava_eel = 60, - raw_vile_fish = 255, - raw_heim_crab = 9, - raw_red_eye = 27, - raw_dusk_eel = 45, - raw_giant_flatfish = 63, - raw_short_finned_eel = 81, - raw_web_snipper = 99, - raw_bouldabass = 117, - raw_salve_eel = 135, - raw_blue_crab = 153, - raw_cave_moray = 171, - raw_shrimps = 10, - raw_anchovies = 40, - raw_sardine = 20, - raw_salmon = 70, - raw_trout = 50, - raw_cod = 45, - raw_herring = 30, - raw_pike = 60, - raw_mackerel = 20, - raw_tuna = 80, - raw_bass = 100, - raw_swordfish = 100, - raw_lobster = 90, - raw_shark = 110, - raw_manta_ray = 46, - raw_sea_turtle = 38, - raw_karambwan = 50, - raw_rainbow_fish = 80, - raw_crayfish = 10, - seaweed = 1, - casket = 0, - oyster = 10, - leather_gloves = 1, - leather_boots = 1, -} - -[fishing_chance_min] -keyType = "item" -valueType = "int" -defaultInt = 1 -values = { - raw_cavefish = 2, - raw_rocktail = 1, - swamp_weed = 10, - cave_eel = 10, - frog_spawn = 16, - slimy_eel = 10, - raw_monkfish = 48, - raw_karambwanji = 100, - leaping_trout = 32, - leaping_salmon = 16, - leaping_sturgeon = 8, - lava_eel = 16, - raw_vile_fish = 1, - raw_heim_crab = 1, - raw_red_eye = 1, - raw_dusk_eel = 1, - raw_giant_flatfish = 1, - raw_short_finned_eel = 1, - raw_web_snipper = 1, - raw_bouldabass = 1, - raw_salve_eel = 1, - raw_blue_crab = 1, - raw_cave_moray = 1, - raw_shrimps = 48, - raw_anchovies = 24, - raw_sardine = 32, - raw_salmon = 16, - raw_trout = 32, - raw_cod = 4, - raw_herring = 24, - raw_pike = 16, - raw_mackerel = 5, - raw_tuna = 8, - raw_bass = 3, - raw_swordfish = 4, - raw_lobster = 6, - raw_shark = 3, - raw_manta_ray = 2, - raw_sea_turtle = 3, - raw_karambwan = 5, - raw_rainbow_fish = 8, - raw_crayfish = 48, - seaweed = 10, - casket = 1, - oyster = 3, - leather_gloves = 10, - leather_boots = 10, -} - -[fishing_chance_max] -keyType = "item" -valueType = "int" -defaultInt = 1 -values = { - raw_cavefish = 24, - raw_rocktail = 16, - swamp_weed = 10, - cave_eel = 80, - frog_spawn = 96, - slimy_eel = 80, - raw_monkfish = 90, - raw_karambwanji = 250, - leaping_trout = 192, - leaping_salmon = 96, - leaping_sturgeon = 64, - lava_eel = 96, - raw_vile_fish = 1, - raw_heim_crab = 1, - raw_red_eye = 1, - raw_dusk_eel = 1, - raw_giant_flatfish = 1, - raw_short_finned_eel = 1, - raw_web_snipper = 1, - raw_bouldabass = 1, - raw_salve_eel = 1, - raw_blue_crab = 1, - raw_cave_moray = 1, - raw_shrimps = 256, - raw_anchovies = 128, - raw_sardine = 192, - raw_salmon = 96, - raw_trout = 192, - raw_cod = 55, - raw_herring = 128, - raw_pike = 96, - raw_mackerel = 65, - raw_tuna = 64, - raw_bass = 40, - raw_swordfish = 48, - raw_lobster = 95, - raw_shark = 40, - raw_manta_ray = 30, - raw_sea_turtle = 30, - raw_karambwan = 160, - raw_rainbow_fish = 64, - raw_crayfish = 256, - seaweed = 10, - casket = 2, - oyster = 7, - leather_gloves = 10, - leather_boots = 10, -} - -[fishing_bait] -keyType = "item" -valueType = "string" -defaultString = "none" -values = { - raw_cave_eel = "fishing_bait", - raw_cavefish = "fishing_bait", - raw_herring = "fishing_bait", - raw_lava_eel = "fishing_bait", - raw_pike = "fishing_bait", - raw_rainbow_fish = "stripy_feather", - raw_rocktail = "living_minerals", - raw_salmon = "feather", - raw_sardine = "fishing_bait", - slimy_eel = "fishing_bait", - raw_trout = "feather", - raw_karambwan = "raw_karambwanji", -} - -[fishing_tackle_cage] -keyType = "npc" -valueType = "string" -defaultString = "lobster_pot" -values = { - fishing_spot_crayfish_lumbridge = "crayfish_cage", -} - -[fishing_fish_cage] -keyType = "npc" -valueType = "string" -defaultString = "" -values = { - fishing_spot_cage_harpoon_catherby = "raw_lobster", - fishing_spot_cage_harpoon_feldip_hills = "raw_lobster", - fishing_spot_crayfish_lumbridge = "raw_crayfish", - fishing_spot_jatizso = "raw_lobster", - fishing_spot_rellekka_cage = "raw_lobster", - fishing_spot_rellekka_4 = "raw_lobster", - fishing_spot_rellekka_5 = "raw_lobster", - fishing_spot_cage_harpoon_fishing_guild = "raw_lobster", - fishing_spot_musa_point_2 = "raw_lobster", - fishing_spot_wilderness = "raw_lobster", -} - -[fishing_tackle_net] -keyType = "npc" -valueType = "string" -defaultString = "small_fishing_net" -values = { - fishing_spot_ape_atoll = "big_fishing_net", - fishing_spot_ape_atoll_2 = "big_fishing_net", - fishing_spot_big_net_harpoon_catherby = "big_fishing_net", - fishing_spot_big_net_harpoon_feldip_hills = "big_fishing_net", - fishing_spot_burgh_de_rott = "big_fishing_net", - fishing_spot_burgh_de_rott_2 = "big_fishing_net", - fishing_spot_jatizso_big_net = "big_fishing_net", - fishing_spot_rellekka_big_net = "big_fishing_net", -} - -[fishing_fish_net] -keyType = "npc" -valueType = "string" -defaultString = "" -values = { - fishing_spot_al_kharid = "raw_shrimps,raw_anchovies", - fishing_spot_ape_atoll = "raw_mackerel,raw_cod,raw_bass,oyster,casket,seaweed,leather_gloves,leather_boots", - fishing_spot_ape_atoll_2 = "raw_mackerel,raw_cod,raw_bass,oyster,casket,seaweed,leather_gloves,leather_boots", - fishing_spot_barbarian_outpost = "raw_shrimps,raw_anchovies", - fishing_spot_big_net_harpoon_catherby = "raw_mackerel,raw_cod,raw_bass,oyster,casket,seaweed,leather_gloves,leather_boots", - fishing_spot_big_net_harpoon_feldip_hills = "raw_mackerel,raw_cod,raw_bass,oyster,casket,seaweed,leather_gloves,leather_boots", - fishing_spot_burgh_de_rott = "raw_mackerel,raw_cod,raw_bass,oyster,casket,seaweed,leather_gloves,leather_boots", - fishing_spot_burgh_de_rott_2 = "raw_mackerel,raw_cod,raw_bass,oyster,casket,seaweed,leather_gloves,leather_boots", - fishing_spot_dorgesh_kaan_agility_course = "frog_spawn", - fishing_spot_dorgesh_kaan_agility_course_2 = "frog_spawn", - fishing_spot_entrana_net = "raw_shrimps,raw_anchovies", - fishing_spot_fishing_guild = "raw_mackerel,raw_cod,raw_bass,oyster,casket,seaweed,leather_gloves,leather_boots", - fishing_spot_fishing_platform = "raw_shrimps,raw_anchovies", - fishing_spot_harpoon_small_net_piscatoris = "raw_monkfish", - fishing_spot_jatizso_big_net = "raw_mackerel,raw_cod,raw_bass,oyster,casket,seaweed,leather_gloves,leather_boots", - fishing_spot_lumbridge_swamp_caves = "frog_spawn", - fishing_spot_lumbridge_swamp_caves_2 = "frog_spawn", - fishing_spot_mudskipper_point = "raw_shrimps,raw_anchovies", - fishing_spot_musa_point = "raw_shrimps,raw_anchovies", - fishing_spot_rellekka = "raw_shrimps,raw_anchovies", - fishing_spot_rellekka_big_net = "raw_mackerel,raw_cod,raw_bass,oyster,casket,seaweed,leather_gloves,leather_boots", - fishing_spot_small_net_bait_catherby = "raw_shrimps,raw_anchovies", - fishing_spot_small_net_bait_draynor = "raw_shrimps,raw_anchovies", - fishing_spot_small_net_bait_feldip_hills = "raw_shrimps,raw_anchovies", - fishing_spot_small_net_bait_lumbridge = "raw_shrimps,raw_anchovies", - fishing_spot_tai_bwo_wannai = "raw_shrimps,raw_karambwanji", - fishing_spot_tutorial_island = "", - fishing_spot_wilderness_bandit_camp = "raw_shrimps,raw_anchovies", -} - -[fishing_tackle_harpoon] -keyType = "npc" -valueType = "string" -defaultString = "harpoon,barb_tail_harpoon" - -[fishing_fish_harpoon] -keyType = "npc" -valueType = "string" -defaultString = "" -values = { - fishing_spot_ape_atoll = "raw_shark", - fishing_spot_ape_atoll_2 = "raw_shark", - fishing_spot_big_net_harpoon_catherby = "raw_shark", - fishing_spot_big_net_harpoon_feldip_hills = "raw_shark", - fishing_spot_burgh_de_rott = "raw_shark", - fishing_spot_burgh_de_rott_2 = "raw_shark", - fishing_spot_cage_harpoon_catherby = "raw_tuna,raw_swordfish", - fishing_spot_cage_harpoon_feldip_hills = "raw_tuna,raw_swordfish", - fishing_spot_cage_harpoon_fishing_guild = "raw_tuna,raw_swordfish", - fishing_spot_fishing_guild = "raw_shark", - fishing_spot_harpoon_small_net_piscatoris = "raw_tuna,raw_swordfish", - fishing_spot_jatizso = "raw_tuna,raw_swordfish", - fishing_spot_jatizso_big_net = "raw_shark", - fishing_spot_musa_point_2 = "raw_tuna,raw_swordfish", - fishing_spot_rellekka_big_net = "raw_shark", - fishing_spot_rellekka_cage = "raw_tuna,raw_swordfish", - fishing_spot_wilderness = "raw_tuna,raw_swordfish", -} - -[fishing_tackle_bait] -keyType = "npc" -valueType = "string" -defaultString = "fishing_rod" -values = { - fishing_spot_taverley_dungeon = "oily_fishing_rod", - fishing_spot_karamja_karambwan_west = "karambwan_vessel", - fishing_spot_karamja_karambwan_east = "karambwan_vessel", - fishing_spot_braindeath_island = "fishbowl_and_net", -} - -[fishing_fish_bait] -keyType = "npc" -valueType = "string" -defaultString = "" -values = { - cavefish_shoal = "raw_cavefish", - fishing_spot_al_kharid = "raw_sardine,raw_herring", - fishing_spot_ardougne = "raw_pike", - fishing_spot_barbarian_outpost = "raw_sardine,raw_herring", - fishing_spot_barbarian_village = "raw_pike", - fishing_spot_baxtorian_falls_lure = "raw_pike", - fishing_spot_dorgesh_kaan_agility_course = "slimy_eel,raw_cave_eel", - fishing_spot_dorgesh_kaan_agility_course_2 = "slimy_eel,raw_cave_eel", - fishing_spot_entrana = "raw_pike", - fishing_spot_entrana_net = "raw_sardine,raw_herring", - fishing_spot_fisher_realm = "raw_pike", - fishing_spot_fishing_platform = "raw_sardine,raw_herring", - fishing_spot_iorwerth_camp = "raw_pike", - fishing_spot_isafdar = "raw_pike", - fishing_spot_lumbridge_swamp_caves = "slimy_eel,raw_cave_eel", - fishing_spot_lumbridge_swamp_caves_2 = "slimy_eel,raw_cave_eel", - fishing_spot_lure_bait_lumbridge = "raw_pike", - fishing_spot_meiyerditch_tunnels = "slimy_eel,raw_cave_eel", - fishing_spot_mort_myre_swamp = "slimy_eel", - fishing_spot_mort_myre_swamp_centre = "slimy_eel", - fishing_spot_mort_myre_swamp_south = "slimy_eel", - fishing_spot_mudskipper_point = "raw_sardine,raw_herring", - fishing_spot_musa_point = "raw_sardine,raw_herring", - fishing_spot_observatory = "raw_pike", - fishing_spot_rellekka = "raw_sardine,raw_herring", - fishing_spot_shilo_village = "raw_pike", - fishing_spot_sinclair_mansion = "raw_pike", - fishing_spot_small_net_bait_catherby = "raw_sardine,raw_herring", - fishing_spot_small_net_bait_draynor = "raw_sardine,raw_herring", - fishing_spot_small_net_bait_feldip_hills = "raw_sardine,raw_herring", - fishing_spot_small_net_bait_lumbridge = "raw_sardine,raw_herring", - fishing_spot_taverley_dungeon = "raw_lava_eel", - fishing_spot_tree_gnome_stronghold = "raw_pike", - fishing_spot_wilderness_bandit_camp = "raw_sardine,raw_herring", - fishing_spot_karamja_karambwan_west = "raw_karambwan", - fishing_spot_karamja_karambwan_east = "raw_karambwan", - fishing_spot_braindeath_island = "sluglings,karamthulhu", - rocktail_shoal = "raw_rocktail", -} - -[fishing_tackle_lure] -keyType = "npc" -valueType = "string" -defaultString = "fly_fishing_rod" - -[fishing_fish_lure] -keyType = "npc" -valueType = "string" -defaultString = "" -values = { - fishing_spot_entrana = "raw_trout,raw_salmon,raw_rainbow_fish", - fishing_spot_ardougne = "raw_trout,raw_salmon,raw_rainbow_fish", - fishing_spot_baxtorian_falls_lure = "raw_trout,raw_salmon,raw_rainbow_fish", - fishing_spot_sinclair_mansion = "raw_trout,raw_salmon,raw_rainbow_fish", - fishing_spot_tree_gnome_stronghold = "raw_trout,raw_salmon,raw_rainbow_fish", - fishing_spot_shilo_village = "raw_trout,raw_salmon,raw_rainbow_fish", - fishing_spot_barbarian_village = "raw_trout,raw_salmon,raw_rainbow_fish", - fishing_spot_lure_bait_lumbridge = "raw_trout,raw_salmon,raw_rainbow_fish", - fishing_spot_fisher_realm = "raw_trout,raw_salmon,raw_rainbow_fish", - fishing_spot_iorwerth_camp = "raw_trout,raw_salmon,raw_rainbow_fish", - fishing_spot_isafdar = "raw_trout,raw_salmon,raw_rainbow_fish", - fishing_spot_observatory = "raw_trout,raw_salmon,raw_rainbow_fish", -} \ No newline at end of file diff --git a/data/skill/fishing/fishing.tables.toml b/data/skill/fishing/fishing.tables.toml new file mode 100644 index 0000000000..db15748f42 --- /dev/null +++ b/data/skill/fishing/fishing.tables.toml @@ -0,0 +1,260 @@ +[fishing] +row_id = "item" +level = "int" +xp = "int" +chance = "range" +bait = "item" +bait_default = "empty_box_fish" + +[.casket] +level = 16 +chance = [1, 2] + +[.cave_eel] +level = 38 +xp = 80 +chance = [10, 80] + +[.frog_spawn] +level = 33 +xp = 75 +chance = [16, 96] + +[.lava_eel] +level = 53 +xp = 60 +chance = [16, 96] + +[.leaping_salmon] +level = 58 +xp = 70 +chance = [16, 96] + +[.leaping_sturgeon] +level = 70 +xp = 80 +chance = [8, 64] + +[.leaping_trout] +level = 48 +xp = 50 +chance = [32, 192] + +[.leather_boots] +level = 16 +xp = 1 +chance = [10, 10] + +[.leather_gloves] +level = 16 +xp = 1 +chance = [10, 10] + +[.oyster] +level = 16 +xp = 10 +chance = [3, 7] + +[.raw_anchovies] +level = 15 +xp = 40 +chance = [24, 128] + +[.raw_bass] +level = 46 +xp = 100 +chance = [3, 40] + +[.raw_blue_crab] +level = 80 +xp = 153 +chance = [1, 1] + +[.raw_bouldabass] +level = 60 +xp = 117 +chance = [1, 1] + +[.raw_cave_eel] +bait = "fishing_bait" + +[.raw_cave_moray] +level = 90 +xp = 171 +chance = [1, 1] + +[.raw_cavefish] +level = 85 +xp = 300 +chance = [2, 24] +bait = "fishing_bait" + +[.raw_cod] +level = 23 +xp = 45 +chance = [4, 55] + +[.raw_crayfish] +level = 0 +xp = 10 +chance = [48, 256] + +[.raw_dusk_eel] +level = 20 +xp = 45 +chance = [1, 1] + +[.raw_giant_flatfish] +level = 30 +xp = 63 +chance = [1, 1] + +[.raw_heim_crab] +level = 1 +xp = 9 +chance = [1, 1] + +[.raw_herring] +level = 10 +xp = 30 +chance = [24, 128] +bait = "fishing_bait" + +[.raw_karambwan] +level = 65 +xp = 50 +chance = [5, 160] +bait = "raw_karambwanji" + +[.raw_karambwanji] +level = 5 +xp = 5 +chance = [100, 250] + +[.raw_lava_eel] +bait = "fishing_bait" + +[.raw_lobster] +level = 40 +xp = 90 +chance = [6, 95] + +[.raw_mackerel] +level = 16 +xp = 20 +chance = [5, 65] + +[.raw_manta_ray] +level = 81 +xp = 46 +chance = [2, 30] + +[.raw_monkfish] +level = 62 +xp = 120 +chance = [48, 90] + +[.raw_pike] +level = 25 +xp = 60 +chance = [16, 96] +bait = "fishing_bait" + +[.raw_rainbow_fish] +level = 38 +xp = 80 +chance = [8, 64] +bait = "stripy_feather" + +[.raw_red_eye] +level = 10 +xp = 27 +chance = [1, 1] + +[.raw_rocktail] +level = 90 +xp = 380 +chance = [1, 16] +bait = "living_minerals" + +[.raw_salmon] +level = 30 +xp = 70 +chance = [16, 96] +bait = "feather" + +[.raw_salve_eel] +level = 70 +xp = 135 +chance = [1, 1] + +[.raw_sardine] +level = 5 +xp = 20 +chance = [32, 192] +bait = "fishing_bait" + +[.raw_sea_turtle] +level = 79 +xp = 38 +chance = [3, 30] + +[.raw_shark] +level = 76 +xp = 110 +chance = [3, 40] + +[.raw_short_finned_eel] +level = 40 +xp = 81 +chance = [1, 1] + +[.raw_shrimps] +level = 0 +xp = 10 +chance = [48, 256] + +[.raw_swordfish] +level = 50 +xp = 100 +chance = [4, 48] + +[.raw_trout] +level = 20 +xp = 50 +chance = [32, 192] +bait = "feather" + +[.raw_tuna] +level = 35 +xp = 80 +chance = [8, 64] + +[.raw_vile_fish] +level = 1 +xp = 255 +chance = [1, 1] + +[.raw_web_snipper] +level = 50 +xp = 99 +chance = [1, 1] + +[.seaweed] +level = 16 +xp = 1 +chance = [10, 10] + +[.slimy_eel] +level = 28 +xp = 65 +chance = [10, 80] +bait = "fishing_bait" + +[.sluglings] +level = 50 + +[.swamp_weed] +level = 33 +xp = 1 +chance = [10, 10] diff --git a/data/skill/fishing/fishing_spots.tables.toml b/data/skill/fishing/fishing_spots.tables.toml new file mode 100644 index 0000000000..3666148544 --- /dev/null +++ b/data/skill/fishing/fishing_spots.tables.toml @@ -0,0 +1,255 @@ +[fishing_spots] +row_id = "npc" +bait = "list" +cage = "list" +net = "list" +harpoon = "list" +lure = "list" +bait_tackle = "list" +bait_tackle_default = ["fishing_rod"] +cage_tackle = "list" +cage_tackle_default = ["lobster_pot"] +net_tackle = "list" +net_tackle_default = ["small_fishing_net"] +harpoon_tackle = "list" +harpoon_tackle_default = ["harpoon", "barb_tail_harpoon"] +lure_tackle = "list" +lure_tackle_default = ["fly_fishing_rod"] + +[.fishing_spot_crayfish_lumbridge] +cage_tackle = ["crayfish_cage"] +cage = ["raw_crayfish"] + +[.fishing_spot_ape_atoll] +net_tackle = ["big_fishing_net"] +net = ["raw_mackerel", "raw_cod", "raw_bass", "oyster", "casket", "seaweed", "leather_gloves", "leather_boots"] +harpoon = ["raw_shark"] + +[.fishing_spot_ape_atoll_2] +net_tackle = ["big_fishing_net"] +net = ["raw_mackerel", "raw_cod", "raw_bass", "oyster", "casket", "seaweed", "leather_gloves", "leather_boots"] +harpoon = ["raw_shark"] + +[.fishing_spot_big_net_harpoon_catherby] +net_tackle = ["big_fishing_net"] +net = ["raw_mackerel", "raw_cod", "raw_bass", "oyster", "casket", "seaweed", "leather_gloves", "leather_boots"] +harpoon = ["raw_shark"] + +[.fishing_spot_big_net_harpoon_feldip_hills] +net_tackle = ["big_fishing_net"] +net = ["raw_mackerel", "raw_cod", "raw_bass", "oyster", "casket", "seaweed", "leather_gloves", "leather_boots"] +harpoon = ["raw_shark"] + +[.fishing_spot_burgh_de_rott] +net_tackle = ["big_fishing_net"] +net = ["raw_mackerel", "raw_cod", "raw_bass", "oyster", "casket", "seaweed", "leather_gloves", "leather_boots"] +harpoon = ["raw_shark"] + +[.fishing_spot_burgh_de_rott_2] +net_tackle = ["big_fishing_net"] +net = ["raw_mackerel", "raw_cod", "raw_bass", "oyster", "casket", "seaweed", "leather_gloves", "leather_boots"] +harpoon = ["raw_shark"] + +[.fishing_spot_jatizso_big_net] +net_tackle = ["big_fishing_net"] +net = ["raw_mackerel", "raw_cod", "raw_bass", "oyster", "casket", "seaweed", "leather_gloves", "leather_boots"] +harpoon = ["raw_shark"] + +[.fishing_spot_rellekka_big_net] +net_tackle = ["big_fishing_net"] +net = ["raw_mackerel", "raw_cod", "raw_bass", "oyster", "casket", "seaweed", "leather_gloves", "leather_boots"] +harpoon = ["raw_shark"] + +[.fishing_spot_taverley_dungeon] +bait_tackle = ["oily_fishing_rod"] +bait = ["raw_lava_eel"] + +[.fishing_spot_karamja_karambwan_west] +bait_tackle = ["karambwan_vessel"] +bait = ["raw_karambwan"] + +[.fishing_spot_karamja_karambwan_east] +bait_tackle = ["karambwan_vessel"] +bait = ["raw_karambwan"] + +[.fishing_spot_braindeath_island] +bait_tackle = ["fishbowl_and_net"] +bait = ["sluglings", "karamthulhu"] + +[.fishing_spot_cage_harpoon_catherby] +cage = ["raw_lobster"] +harpoon = ["raw_tuna", "raw_swordfish"] + +[.fishing_spot_cage_harpoon_feldip_hills] +cage = ["raw_lobster"] +harpoon = ["raw_tuna", "raw_swordfish"] + +[.fishing_spot_jatizso] +cage = ["raw_lobster"] +harpoon = ["raw_tuna", "raw_swordfish"] + +[.fishing_spot_rellekka_cage] +cage = ["raw_lobster"] +harpoon = ["raw_tuna", "raw_swordfish"] + +[.fishing_spot_rellekka_4] +cage = ["raw_lobster"] + +[.fishing_spot_rellekka_5] +cage = ["raw_lobster"] + +[.fishing_spot_cage_harpoon_fishing_guild] +cage = ["raw_lobster"] +harpoon = ["raw_tuna", "raw_swordfish"] + +[.fishing_spot_musa_point_2] +cage = ["raw_lobster"] +harpoon = ["raw_tuna", "raw_swordfish"] + +[.fishing_spot_wilderness] +cage = ["raw_lobster"] +harpoon = ["raw_tuna", "raw_swordfish"] + +[.fishing_spot_al_kharid] +net = ["raw_shrimps", "raw_anchovies"] +bait = ["raw_sardine", "raw_herring"] + +[.fishing_spot_barbarian_outpost] +bait = ["raw_sardine", "raw_herring"] +net = ["raw_shrimps", "raw_anchovies"] + +[.fishing_spot_dorgesh_kaan_agility_course] +net = ["frog_spawn"] +bait = ["slimy_eel", "raw_cave_eel"] + +[.fishing_spot_dorgesh_kaan_agility_course_2] +net = ["frog_spawn"] +bait = ["slimy_eel", "raw_cave_eel"] + +[.fishing_spot_entrana_net] +net = ["raw_shrimps", "raw_anchovies"] +bait = ["raw_sardine", "raw_herring"] + +[.fishing_spot_fishing_guild] +net = ["raw_mackerel", "raw_cod", "raw_bass", "oyster", "casket", "seaweed", "leather_gloves", "leather_boots"] +harpoon = ["raw_shark"] + +[.fishing_spot_fishing_platform] +net = ["raw_shrimps", "raw_anchovies"] +bait = ["raw_sardine", "raw_herring"] + +[.fishing_spot_harpoon_small_net_piscatoris] +net = ["raw_monkfish"] +harpoon = ["raw_tuna", "raw_swordfish"] + +[.fishing_spot_lumbridge_swamp_caves] +net = ["frog_spawn"] +bait = ["slimy_eel", "raw_cave_eel"] + +[.fishing_spot_lumbridge_swamp_caves_2] +net = ["frog_spawn"] +bait = ["slimy_eel", "raw_cave_eel"] + +[.fishing_spot_mudskipper_point] +net = ["raw_shrimps", "raw_anchovies"] +bait = ["raw_sardine", "raw_herring"] + +[.fishing_spot_musa_point] +net = ["raw_shrimps", "raw_anchovies"] +bait = ["raw_sardine", "raw_herring"] + +[.fishing_spot_rellekka] +net = ["raw_shrimps", "raw_anchovies"] +bait = ["raw_sardine", "raw_herring"] + +[.fishing_spot_small_net_bait_catherby] +net = ["raw_shrimps", "raw_anchovies"] +bait = ["raw_sardine", "raw_herring"] + +[.fishing_spot_small_net_bait_draynor] +net = ["raw_shrimps", "raw_anchovies"] +bait = ["raw_sardine", "raw_herring"] + +[.fishing_spot_small_net_bait_feldip_hills] +net = ["raw_shrimps", "raw_anchovies"] +bait = ["raw_sardine", "raw_herring"] + +[.fishing_spot_small_net_bait_lumbridge] +net = ["raw_shrimps", "raw_anchovies"] +bait = ["raw_sardine", "raw_herring"] + +[.fishing_spot_tai_bwo_wannai] +net = ["raw_shrimps", "raw_karambwanji"] + +[.fishing_spot_tutorial_island] +net = [] + +[.fishing_spot_wilderness_bandit_camp] +net = ["raw_shrimps", "raw_anchovies"] +bait = ["raw_sardine", "raw_herring"] + +[.cavefish_shoal] +bait = ["raw_cavefish"] + +[.fishing_spot_ardougne] +bait = ["raw_pike"] +lure = ["raw_trout", "raw_salmon", "raw_rainbow_fish"] + +[.fishing_spot_barbarian_village] +bait = ["raw_pike"] +lure = ["raw_trout", "raw_salmon", "raw_rainbow_fish"] + +[.fishing_spot_baxtorian_falls_lure] +bait = ["raw_pike"] +lure = ["raw_trout", "raw_salmon", "raw_rainbow_fish"] + +[.fishing_spot_entrana] +bait = ["raw_pike"] +lure = ["raw_trout", "raw_salmon", "raw_rainbow_fish"] + +[.fishing_spot_fisher_realm] +bait = ["raw_pike"] +lure = ["raw_trout", "raw_salmon", "raw_rainbow_fish"] + +[.fishing_spot_iorwerth_camp] +bait = ["raw_pike"] +lure = ["raw_trout", "raw_salmon", "raw_rainbow_fish"] + +[.fishing_spot_isafdar] +bait = ["raw_pike"] +lure = ["raw_trout", "raw_salmon", "raw_rainbow_fish"] + +[.fishing_spot_lure_bait_lumbridge] +bait = ["raw_pike"] +lure = ["raw_trout", "raw_salmon", "raw_rainbow_fish"] + +[.fishing_spot_meiyerditch_tunnels] +bait = ["slimy_eel", "raw_cave_eel"] + +[.fishing_spot_mort_myre_swamp] +bait = ["slimy_eel"] + +[.fishing_spot_mort_myre_swamp_centre] +bait = ["slimy_eel"] + +[.fishing_spot_mort_myre_swamp_south] +bait = ["slimy_eel"] + +[.fishing_spot_observatory] +bait = ["raw_pike"] +lure = ["raw_trout", "raw_salmon", "raw_rainbow_fish"] + +[.fishing_spot_shilo_village] +bait = ["raw_pike"] +lure = ["raw_trout", "raw_salmon", "raw_rainbow_fish"] + +[.fishing_spot_sinclair_mansion] +bait = ["raw_pike"] +lure = ["raw_trout", "raw_salmon", "raw_rainbow_fish"] + +[.fishing_spot_tree_gnome_stronghold] +bait = ["raw_pike"] +lure = ["raw_trout", "raw_salmon", "raw_rainbow_fish"] + +[.rocktail_shoal] +bait = ["raw_rocktail"] diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt index df616b7fd3..48c0ce71c9 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt @@ -35,6 +35,8 @@ data class RowDefinition( fun itemOrNull(column: String) = Tables.itemOrNull("${stringId}.$column") + fun itemList(column: String) = Tables.itemList("${stringId}.$column") + override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt index dd13cb4b49..04c0f0aae8 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/TableDefinition.kt @@ -46,8 +46,7 @@ data class TableDefinition( } fun getOrNull(column: Int, row: Int, type: ColumnType): T? { - val id = rows.getOrNull(row) ?: return null - val rows = Rows.getOrNull(id)?.data ?: return null + val rows = Rows.getOrNull(row)?.data ?: return null val value = rows[column] return type.cast(value) } @@ -60,7 +59,7 @@ data class TableDefinition( fun findOrNull(searchColumn: Int, value: Any, column: String, type: ColumnType): T? { val columnIndex = columns[column] ?: return null val row = findOrNull(searchColumn, value) ?: return null - return getOrNull(row, columnIndex, type) + return getOrNull(columnIndex, row, type) } fun findOrNull(column: Int, value: Any): Int? { diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnReader.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnReader.kt index d463387483..e6f3e73c3b 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnReader.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnReader.kt @@ -32,10 +32,10 @@ sealed interface ColumnReader { } } - class ReaderEntity(val definitions: Map) : ColumnReader { + class ReaderEntity(val ids: Map) : ColumnReader { override val type = ColumnType.ColumnEntity override fun list() = mutableListOf() - override fun read(reader: ConfigReader) = definitions.getValue(reader.string()) + override fun read(reader: ConfigReader) = ids.getValue(reader.string()) } object ReaderString : ColumnReader { diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt index c322595f83..a7a11b086c 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt @@ -7,6 +7,7 @@ import world.gregs.voidps.engine.data.config.RowDefinition import world.gregs.voidps.engine.data.config.TableDefinition import world.gregs.voidps.engine.timedLoad import kotlin.collections.set +import kotlin.math.exp object Tables { @@ -221,7 +222,7 @@ object Tables { val idReader = builder.idReader if (idReader != null) { val rowId = rowName.substringAfter(".") - requireNotNull(idReader.definitions[rowId]) { "Unable to find entity '$rowId' for row id" } + requireNotNull(idReader.ids[rowId]) { "Unable to find entity '$rowId' for row id" } } val row = arrayOfNulls(builder.readers.size) while (reader.nextPair()) { @@ -250,8 +251,12 @@ object Tables { builder.idReader = reader } } else if (key.endsWith("_default")) { - val default = reader.value() - builder.setDefault(key.removeSuffix("_default"), default) + val name = key.removeSuffix("_default") + val index = builder.columns[name] + requireNotNull(index) { "Column '$name' not found for default at ${reader.exception()}." } + val read = builder.readers[index] + val value = read.read(reader) + builder.setDefault(index, name, value) } else { val type = reader.string() builder.addColumn(key, type) @@ -267,9 +272,7 @@ object Tables { private var columnIndex = 0 var idReader: ColumnReader.ReaderEntity? = null - fun setDefault(name: String, value: Any) { - val index = columns[name] - requireNotNull(index) { "Default column not found '$name'" } + fun setDefault(index: Int, name: String, value: Any) { require(index < columnIndex) { "Default column index out of bounds '$name' - has type been set?" } defaults[index] = value } diff --git a/game/src/main/kotlin/content/skill/fishing/Fishing.kt b/game/src/main/kotlin/content/skill/fishing/Fishing.kt index 64d73dc757..2802208ce1 100644 --- a/game/src/main/kotlin/content/skill/fishing/Fishing.kt +++ b/game/src/main/kotlin/content/skill/fishing/Fishing.kt @@ -9,8 +9,9 @@ import world.gregs.voidps.engine.client.ui.chat.plural import world.gregs.voidps.engine.client.ui.closeDialogue import world.gregs.voidps.engine.client.variable.remaining import world.gregs.voidps.engine.client.variable.stop -import world.gregs.voidps.engine.data.definition.EnumDefinitions import world.gregs.voidps.engine.data.definition.ItemDefinitions +import world.gregs.voidps.engine.data.definition.Rows +import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.World import world.gregs.voidps.engine.entity.character.npc.NPC import world.gregs.voidps.engine.entity.character.player.Player @@ -52,7 +53,8 @@ class Fishing : Script { suspend fun fish(player: Player, target: NPC, option: String) { player.arriveDelay() - val fish = EnumDefinitions.stringOrNull("fishing_fish_${option.lowercase()}", target.id)?.split(",") ?: return + val spot = Rows.getOrNull("fishing_spots.${target.id}") ?: return + val fish = spot.itemList(option.lowercase()) target.getOrPut("fishers") { mutableSetOf() }.add(player.name) player.softTimers.start("fishing") player.closeDialogue() @@ -68,12 +70,12 @@ class Fishing : Script { break } - val minimumLevel = fish.minOf { EnumDefinitions.int("fishing_levels", it) } + val minimumLevel = fish.minOf { Tables.int("fishing.$it.level") } if (!player.has(Skill.Fishing, minimumLevel, true)) { break } - val tackles = EnumDefinitions.string("fishing_tackle_${option.lowercase()}", target.id).split(",") + val tackles = spot.itemList("${option.lowercase()}_tackle") val tackle = tackles.firstOrNull { tackle -> player.carriesItem(tackle) } if (tackle == null) { player.message("You need a ${tackles.first().toTitleCase()} to catch these fish.") @@ -83,11 +85,11 @@ class Fishing : Script { var bait: String? = null var required: String? = null for (fish in fish) { - val b = EnumDefinitions.string("fishing_bait", fish) - if (required == null && b != "none") { + val b = Tables.item("fishing.${fish}.bait") + if (required == null && b != "empty_box_fish") { required = b } - if (b == "none" || player.carriesItem(b)) { + if (b == "empty_box_fish" || player.carriesItem(b)) { bait = b break } @@ -112,15 +114,15 @@ class Fishing : Script { first = false } for (item in fish) { - if (bait != EnumDefinitions.string("fishing_bait", item)) { + val row = Rows.getOrNull("fishing.$item") ?: continue + if (bait != row.itemOrNull("bait")) { continue } - val requiredLevel = EnumDefinitions.intOrNull("fishing_levels", item) ?: continue - val chanceMin = EnumDefinitions.int("fishing_chance_min", item) - val chanceMax = EnumDefinitions.int("fishing_chance_max", item) - val experience = EnumDefinitions.int("fishing_experience", item) + val requiredLevel = row.int("level") + val chance = row.intRange("chance") + val experience = row.int("xp") val level = player.levels.get(Skill.Fishing) - if (level >= requiredLevel && success(level, chanceMin..chanceMax)) { + if (level >= requiredLevel && success(level, chance)) { if (bait != "none" && !player.inventory.remove(bait)) { break@fishing } diff --git a/game/src/main/kotlin/content/skill/mining/Mining.kt b/game/src/main/kotlin/content/skill/mining/Mining.kt index 5a201f3777..36a686015a 100644 --- a/game/src/main/kotlin/content/skill/mining/Mining.kt +++ b/game/src/main/kotlin/content/skill/mining/Mining.kt @@ -134,12 +134,12 @@ class Mining : Script { else -> ores.add(ore.itemId) } for (item in ores) { - val chance = Tables.intRange("mining_ores.${item}.chance") + val chance = Tables.intRange("ores.${item}.chance") if (success(levels.get(Skill.Mining), chance)) { - val xp = Tables.int("mining_ores.${item}.xp") / 10.0 + val xp = Tables.int("ores.${item}.xp") / 10.0 exp(Skill.Mining, xp) ShootingStarHandler.extraOreHandler(this, item, xp) - if (!addOre(this, item) || deplete(target, Tables.int("mining_ores.${item}.life"))) { + if (!addOre(this, item) || deplete(target, Tables.int("ores.${item}.life"))) { clearAnim() break } From 8f317ddbf69bb0bef302d363e6cd3b25704e1ee2 Mon Sep 17 00:00:00 2001 From: GregHib Date: Thu, 26 Mar 2026 20:33:49 +0000 Subject: [PATCH 20/40] Convert woodcutting enums --- data/skill/woodcutting/log.tables.toml | 219 ++++++++++++++++++ data/skill/woodcutting/woodcutting.enums.toml | 209 ----------------- .../content/skill/woodcutting/Woodcutting.kt | 32 +-- 3 files changed, 236 insertions(+), 224 deletions(-) create mode 100644 data/skill/woodcutting/log.tables.toml diff --git a/data/skill/woodcutting/log.tables.toml b/data/skill/woodcutting/log.tables.toml new file mode 100644 index 0000000000..9884588a99 --- /dev/null +++ b/data/skill/woodcutting/log.tables.toml @@ -0,0 +1,219 @@ +[logs] +row_id = "item" +level = "int" +xp = "int" +deplete_rate = "int" +respawn_delay = "range" +chance = "range" +chance_hatchet_dif_low = "range" +chance_hatchet_dif_high = "range" + +[.achey_tree_logs] +xp = 250 +deplete_rate = 1000 +respawn_delay = [30, 60] +chance = [64, 200] +chance_hatchet_dif_low = [16, 32] +chance_hatchet_dif_high = [50, 100] + +[.arctic_pine_logs] +level = 56 +xp = 1400 +deplete_rate = 125 +respawn_delay = [80, 160] +chance = [6, 30] +chance_hatchet_dif_low = [1, 2] +chance_hatchet_dif_high = [7, 14] + +[.bark] +level = 45 +xp = 825 +deplete_rate = 125 +respawn_delay = [75, 150] +chance = [18, 26] +chance_hatchet_dif_low = [4, 10] +chance_hatchet_dif_high = [11, 14] + +[.blood_spindle_branches] +level = 20 +xp = 850 +deplete_rate = 125 +respawn_delay = [0, 1] +chance_hatchet_dif_low = [0, 1] +chance_hatchet_dif_high = [0, 1] + +[.bovistrangler_branches] +level = 50 +xp = 1750 +deplete_rate = 125 +respawn_delay = [0, 1] +chance_hatchet_dif_low = [0, 1] +chance_hatchet_dif_high = [0, 1] + +[.corpsethorn_branches] +level = 70 +xp = 2450 +deplete_rate = 125 +respawn_delay = [0, 1] +chance_hatchet_dif_low = [0, 1] +chance_hatchet_dif_high = [0, 1] + +[.cursed_magic_logs] +level = 82 +xp = 2750 +deplete_rate = 125 +respawn_delay = [150, 300] +chance_hatchet_dif_low = [0, 1] +chance_hatchet_dif_high = [0, 1] + +[.dream_log] +level = 55 +deplete_rate = 1000 +respawn_delay = [30, 60] +chance = [64, 200] +chance_hatchet_dif_low = [16, 32] +chance_hatchet_dif_high = [50, 100] + +[.entgallow_branches] +level = 80 +xp = 2850 +deplete_rate = 125 +respawn_delay = [0, 1] +chance_hatchet_dif_low = [0, 1] +chance_hatchet_dif_high = [0, 1] + +[.eucalyptus_logs] +level = 58 +xp = 1650 +deplete_rate = 125 +respawn_delay = [90, 180] +chance = [5, 16] +chance_hatchet_dif_low = [1, 3] +chance_hatchet_dif_high = [4, 9] + +[.grave_creeper_branches] +level = 90 +xp = 3300 +deplete_rate = 125 +respawn_delay = [0, 1] +chance_hatchet_dif_low = [0, 1] +chance_hatchet_dif_high = [0, 1] + +[.logs] +xp = 250 +deplete_rate = 1000 +respawn_delay = [30, 60] +chance = [64, 200] +chance_hatchet_dif_low = [16, 32] +chance_hatchet_dif_high = [50, 100] + +[.magic_logs] +level = 75 +xp = 2500 +deplete_rate = 125 +respawn_delay = [200, 387] +chance = [2, 6] +chance_hatchet_dif_low = [0, 1] +chance_hatchet_dif_high = [2, 3] + +[.mahogany_logs] +level = 50 +xp = 1250 +deplete_rate = 125 +respawn_delay = [70, 140] +chance = [8, 25] +chance_hatchet_dif_low = [2, 4] +chance_hatchet_dif_high = [9, 13] + +[.maple_logs] +level = 45 +xp = 1000 +deplete_rate = 125 +respawn_delay = [58, 125] +chance = [8, 25] +chance_hatchet_dif_low = [2, 4] +chance_hatchet_dif_high = [6, 12] + +[.oak_logs] +level = 15 +xp = 375 +deplete_rate = 125 +respawn_delay = [23, 45] +chance = [32, 100] +chance_hatchet_dif_low = [8, 16] +chance_hatchet_dif_high = [25, 50] + +[.poison_ivy_berries] +level = 68 +xp = 3325 +deplete_rate = 125 +respawn_delay = [60, 60] +chance = [7, 11] +chance_hatchet_dif_low = [2, 2] +chance_hatchet_dif_high = [2, 6] + +[.seeping_elm_branches] +level = 10 +xp = 600 +deplete_rate = 125 +respawn_delay = [0, 1] +chance_hatchet_dif_low = [0, 1] +chance_hatchet_dif_high = [0, 1] + +[.spinebeam_branches] +level = 40 +xp = 1450 +deplete_rate = 125 +respawn_delay = [0, 1] +chance_hatchet_dif_low = [0, 1] +chance_hatchet_dif_high = [0, 1] + +[.tangle_gum_branches] +xp = 350 +deplete_rate = 125 +respawn_delay = [0, 1] +chance_hatchet_dif_low = [0, 1] +chance_hatchet_dif_high = [0, 1] + +[.teak_logs] +level = 35 +xp = 850 +deplete_rate = 125 +respawn_delay = [40, 80] +chance = [15, 46] +chance_hatchet_dif_low = [4, 8] +chance_hatchet_dif_high = [15, 24] + +[.thigat_branches] +level = 60 +xp = 2100 +deplete_rate = 125 +respawn_delay = [0, 1] +chance_hatchet_dif_low = [0, 1] +chance_hatchet_dif_high = [0, 1] + +[.utuku_branches] +level = 30 +xp = 1150 +deplete_rate = 125 +respawn_delay = [0, 1] +chance_hatchet_dif_low = [0, 1] +chance_hatchet_dif_high = [0, 1] + +[.willow_logs] +level = 30 +xp = 675 +deplete_rate = 125 +respawn_delay = [0, 1] +chance = [16, 50] +chance_hatchet_dif_low = [4, 8] +chance_hatchet_dif_high = [13, 25] + +[.yew_logs] +level = 60 +xp = 1750 +deplete_rate = 125 +respawn_delay = [100, 200] +chance = [4, 12] +chance_hatchet_dif_low = [1, 2] +chance_hatchet_dif_high = [3, 7] diff --git a/data/skill/woodcutting/woodcutting.enums.toml b/data/skill/woodcutting/woodcutting.enums.toml index 4b3e3e3035..eaf95936a3 100644 --- a/data/skill/woodcutting/woodcutting.enums.toml +++ b/data/skill/woodcutting/woodcutting.enums.toml @@ -122,212 +122,3 @@ values = { yew_2 = "yew_logs", yew_tree_fullygrown_2 = "yew_logs", } - -[woodcutting_level] -keyType = "item" -valueType = "int" -defaultInt = 1 -values = { - grave_creeper_branches = 90, - willow_logs = 30, - oak_logs = 15, - entgallow_branches = 80, - yew_logs = 60, - blood_spindle_branches = 20, - eucalyptus_logs = 58, - bovistrangler_branches = 50, - mahogany_logs = 50, - corpsethorn_branches = 70, - spinebeam_branches = 40, - magic_logs = 75, - seeping_elm_branches = 10, - thigat_branches = 60, - cursed_magic_logs = 82, - maple_logs = 45, - utuku_branches = 30, - poison_ivy_berries = 68, - arctic_pine_logs = 56, - teak_logs = 35, - dream_log = 55, - bark = 45, -} - -[woodcutting_xp] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - logs = 250, - grave_creeper_branches = 3300, - willow_logs = 675, - oak_logs = 375, - entgallow_branches = 2850, - yew_logs = 1750, - blood_spindle_branches = 850, - eucalyptus_logs = 1650, - bovistrangler_branches = 1750, - mahogany_logs = 1250, - achey_tree_logs = 250, - corpsethorn_branches = 2450, - spinebeam_branches = 1450, - magic_logs = 2500, - seeping_elm_branches = 600, - thigat_branches = 2100, - cursed_magic_logs = 2750, - maple_logs = 1000, - tangle_gum_branches = 350, - utuku_branches = 1150, - poison_ivy_berries = 3325, - arctic_pine_logs = 1400, - teak_logs = 850, - bark = 825, -} - -[woodcutting_deplete_rate] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - logs = 1000, - grave_creeper_branches = 125, - willow_logs = 125, - oak_logs = 125, - entgallow_branches = 125, - yew_logs = 125, - blood_spindle_branches = 125, - eucalyptus_logs = 125, - bovistrangler_branches = 125, - mahogany_logs = 125, - achey_tree_logs = 1000, - corpsethorn_branches = 125, - spinebeam_branches = 125, - magic_logs = 125, - seeping_elm_branches = 125, - thigat_branches = 125, - cursed_magic_logs = 125, - maple_logs = 125, - tangle_gum_branches = 125, - utuku_branches = 125, - poison_ivy_berries = 125, - arctic_pine_logs = 125, - teak_logs = 125, - dream_log = 1000, - bark = 125, -} - -[woodcutting_chance] -keyType = "item" -valueType = "string" -defaultString = "0-0" -values = { - logs = "64-200", - willow_logs = "16-50", - oak_logs = "32-100", - yew_logs = "4-12", - eucalyptus_logs = "5-16", - mahogany_logs = "8-25", - achey_tree_logs = "64-200", - magic_logs = "2-6", - maple_logs = "8-25", - poison_ivy_berries = "7-11", - arctic_pine_logs = "6-30", - teak_logs = "15-46", - dream_log = "64-200", - bark = "18-26", -} - -[woodcutting_hatchet_dif_low] -keyType = "item" -valueType = "string" -defaultString = "0-0" -values = { - logs = "16-32", - grave_creeper_branches = "0-1", - willow_logs = "4-8", - oak_logs = "8-16", - entgallow_branches = "0-1", - yew_logs = "1-2", - blood_spindle_branches = "0-1", - eucalyptus_logs = "1-3", - bovistrangler_branches = "0-1", - mahogany_logs = "2-4", - achey_tree_logs = "16-32", - corpsethorn_branches = "0-1", - spinebeam_branches = "0-1", - magic_logs = "0-1", - seeping_elm_branches = "0-1", - thigat_branches = "0-1", - cursed_magic_logs = "0-1", - maple_logs = "2-4", - tangle_gum_branches = "0-1", - utuku_branches = "0-1", - poison_ivy_berries = "2-2", - arctic_pine_logs = "1-2", - teak_logs = "4-8", - dream_log = "16-32", - bark = "4-10", -} - -[woodcutting_hatchet_dif_high] -keyType = "item" -valueType = "string" -defaultString = "0-0" -values = { - logs = "50-100", - grave_creeper_branches = "0-1", - willow_logs = "13-25", - oak_logs = "25-50", - entgallow_branches = "0-1", - yew_logs = "3-7", - blood_spindle_branches = "0-1", - eucalyptus_logs = "4-9", - bovistrangler_branches = "0-1", - mahogany_logs = "9-13", - achey_tree_logs = "50-100", - corpsethorn_branches = "0-1", - spinebeam_branches = "0-1", - magic_logs = "2-3", - seeping_elm_branches = "0-1", - thigat_branches = "0-1", - cursed_magic_logs = "0-1", - maple_logs = "6-12", - tangle_gum_branches = "0-1", - utuku_branches = "0-1", - poison_ivy_berries = "2-6", - arctic_pine_logs = "7-14", - teak_logs = "15-24", - dream_log = "50-100", - bark = "11-14", -} - -[woodcutting_respawn_delay] -keyType = "item" -valueType = "string" -defaultString = "0-0" -values = { - logs = "30-60", - grave_creeper_branches = "0-1", - willow_logs = "0-1", - oak_logs = "23-45", - entgallow_branches = "0-1", - yew_logs = "100-200", - blood_spindle_branches = "0-1", - eucalyptus_logs = "90-180", - bovistrangler_branches = "0-1", - mahogany_logs = "70-140", - achey_tree_logs = "30-60", - corpsethorn_branches = "0-1", - spinebeam_branches = "0-1", - magic_logs = "200-387", - seeping_elm_branches = "0-1", - thigat_branches = "0-1", - cursed_magic_logs = "150-300", - maple_logs = "58-125", - tangle_gum_branches = "0-1", - utuku_branches = "0-1", - poison_ivy_berries = "60-60", - arctic_pine_logs = "80-160", - teak_logs = "40-80", - dream_log = "30-60", - bark = "75-150", -} diff --git a/game/src/main/kotlin/content/skill/woodcutting/Woodcutting.kt b/game/src/main/kotlin/content/skill/woodcutting/Woodcutting.kt index 13221144ff..967a7ba93f 100644 --- a/game/src/main/kotlin/content/skill/woodcutting/Woodcutting.kt +++ b/game/src/main/kotlin/content/skill/woodcutting/Woodcutting.kt @@ -3,13 +3,14 @@ package content.skill.woodcutting import net.pearx.kasechange.toLowerSpaceCase import world.gregs.voidps.engine.Script import world.gregs.voidps.engine.client.message -import world.gregs.voidps.engine.client.ui.chat.toIntRange import world.gregs.voidps.engine.client.ui.closeDialogue import world.gregs.voidps.engine.client.variable.remaining import world.gregs.voidps.engine.client.variable.start import world.gregs.voidps.engine.client.variable.stop +import world.gregs.voidps.engine.data.config.RowDefinition import world.gregs.voidps.engine.data.definition.EnumDefinitions import world.gregs.voidps.engine.data.definition.ObjectDefinitions +import world.gregs.voidps.engine.data.definition.Rows import world.gregs.voidps.engine.entity.character.areaSound import world.gregs.voidps.engine.entity.character.mode.interact.PlayerOnObjectInteract import world.gregs.voidps.engine.entity.character.player.Player @@ -45,7 +46,8 @@ class Woodcutting(val drops: DropTables) : Script { suspend fun chopDown(player: Player, interact: PlayerOnObjectInteract) { val target = interact.target - val log = EnumDefinitions.stringOrNull("woodcutting_log", target.def(player).stringId) ?: return + val id = EnumDefinitions.stringOrNull("woodcutting_log", target.def(player).stringId) ?: return + val log = Rows.getOrNull("logs.$id") ?: return val hatchet = Hatchet.best(player) if (hatchet == null) { player.message("You need a hatchet to chop down this tree.") @@ -54,10 +56,10 @@ class Woodcutting(val drops: DropTables) : Script { } player.closeDialogue() player.softTimers.start("woodcutting") - val ivy = log == "poison_ivy_berries" + val ivy = log.itemId == "poison_ivy_berries" var first = true while (player.awaitDialogues()) { - val level = EnumDefinitions.int("woodcutting_level", log) + val level = log.int("level") if (!GameObjects.contains(target) || !player.has(Skill.Woodcutting, level, true)) { break } @@ -86,10 +88,10 @@ class Woodcutting(val drops: DropTables) : Script { break } if (success(player.levels.get(Skill.Woodcutting), hatchet, log)) { - val xp = EnumDefinitions.int("woodcutting_xp", log) / 10.0 + val xp = log.int("xp") / 10.0 player.exp(Skill.Woodcutting, xp) tryDropNest(player, ivy) - if (!addLog(player, log) || deplete(player, log, target)) { + if (!addLog(player, log.itemId) || deplete(player, log, target)) { break } if (ivy) { @@ -119,10 +121,10 @@ class Woodcutting(val drops: DropTables) : Script { FloorItems.add(tile = dropTile, id = drop.id, amount = drop.amount.first, disappearTicks = 50) } - fun success(level: Int, hatchet: Item, log: String): Boolean { - val chanceRange = EnumDefinitions.string("woodcutting_chance", log).toIntRange() - val hatchetLowDifference = EnumDefinitions.string("woodcutting_hatchet_dif_low", log).toIntRange() - val hatchetHighDifference = EnumDefinitions.string("woodcutting_hatchet_dif_high", log).toIntRange() + fun success(level: Int, hatchet: Item, log: RowDefinition): Boolean { + val chanceRange = log.intRange("chance") + val hatchetLowDifference = log.intRange("chance_hatchet_dif_low") + val hatchetHighDifference = log.intRange("chance_hatchet_dif_high") val lowHatchetChance = calculateChance(hatchet, hatchetLowDifference) val highHatchetChance = calculateChance(hatchet, hatchetHighDifference) val chance = chanceRange.first + lowHatchetChance..chanceRange.last + highHatchetChance @@ -152,8 +154,8 @@ class Woodcutting(val drops: DropTables) : Script { return added } - fun deplete(player: Player, log: String, obj: GameObject): Boolean { - val depleteRate = EnumDefinitions.int("woodcutting_deplete_rate", log) / 1000.0 + fun deplete(player: Player, log: RowDefinition, obj: GameObject): Boolean { + val depleteRate = log.int("deplete_rate") / 1000.0 val depleted = random.nextDouble() <= depleteRate if (!depleted) { return false @@ -175,9 +177,9 @@ class Woodcutting(val drops: DropTables) : Script { /** * Returns regrow delay based on the type of tree and number of players online */ - fun getRegrowTickDelay(log: String): Int { - val delay = EnumDefinitions.string("woodcutting_respawn_delay", log).toIntRange() - val level = EnumDefinitions.int("woodcutting_level", log) + fun getRegrowTickDelay(log: RowDefinition): Int { + val delay = log.intRange("respawn_delay") + val level = log.int("level") return if (level == 1) { random.nextInt(delay.first, delay.last) // Regular tree's } else { From b283808e8377c3fe858f564a36ef24f92964c085 Mon Sep 17 00:00:00 2001 From: GregHib Date: Fri, 27 Mar 2026 11:02:04 +0000 Subject: [PATCH 21/40] Convert smelting --- data/skill/smithing/bars.tables.toml | 77 +++++++++++++++++++ .../engine/data/config/RowDefinition.kt | 2 + .../kotlin/content/skill/smithing/Furnace.kt | 30 ++++---- .../content/skill/smithing/SuperheatItem.kt | 9 ++- 4 files changed, 101 insertions(+), 17 deletions(-) create mode 100644 data/skill/smithing/bars.tables.toml diff --git a/data/skill/smithing/bars.tables.toml b/data/skill/smithing/bars.tables.toml new file mode 100644 index 0000000000..a751488170 --- /dev/null +++ b/data/skill/smithing/bars.tables.toml @@ -0,0 +1,77 @@ +[bars] +row_id = "item" +level = "int" +xp = "int" +ore = "list" +amount = "list" +amount_default = [1] +chance = "int" +chance_default = 255 # 100% +message = "string" + +[.bronze_bar] +level = 1 +xp = 62 +ore = ["tin_ore", "copper_ore"] +amount = [1, 1] +message = "You smelt the copper and tin together in the furnace." + +[.blurite_bar] +level = 13 +xp = 80 +ore = ["blurite_ore"] +message = "You place the blurite and four heaps of coal into the furnace." + +[.elemental_bar] +level = 20 +xp = 75 +ore = ["elemental_ore", "coal"] +amount = [1, 4] +message = "You place the elemental ore and four heaps of coal into the furnace." + +[.iron_bar] +level = 15 +xp = 125 +chance = 128 # 50% +ore = ["iron_ore"] +message = "You smelt the iron in the furnace." + +[.steel_bar] +level = 30 +xp = 175 +ore = ["iron_ore", "coal"] +amount = [1, 2] +message = "You place the iron and two heaps of coal into the furnace." + +[.silver_bar] +level = 20 +xp = 137 +ore = ["silver_ore"] +message = "You place the silver into the furnace." + +[.gold_bar] +level = 40 +xp = 225 +ore = ["gold_ore"] +message = "You place a lump of gold in the furnace." + +[.mithril_bar] +level = 50 +xp = 300 +ore = ["mithril_ore", "coal"] +amount = [1, 4] +message = "You place the mithril and four heaps of coal into the furnace." + +[.adamant_bar] +level = 70 +xp = 375 +ore = ["adamantite_ore", "coal"] +amount = [1, 6] +message = "You place the adamantite and six heaps of coal into the furnace." + +[.rune_bar] +level = 85 +xp = 500 +ore = ["runite_ore", "coal"] +amount = [1, 8] +message = "You place the runite and six heaps of coal into the furnace." diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt index 48c0ce71c9..cb769b1a65 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt @@ -19,6 +19,8 @@ data class RowDefinition( fun int(column: String) = Tables.int("${stringId}.$column") + fun intList(column: String) = Tables.intList("${stringId}.$column") + fun intOrNull(column: String) = Tables.intOrNull("${stringId}.$column") fun intRange(column: String) = Tables.intRange("${stringId}.$column") diff --git a/game/src/main/kotlin/content/skill/smithing/Furnace.kt b/game/src/main/kotlin/content/skill/smithing/Furnace.kt index a81e29f783..d9194cc0ee 100644 --- a/game/src/main/kotlin/content/skill/smithing/Furnace.kt +++ b/game/src/main/kotlin/content/skill/smithing/Furnace.kt @@ -4,7 +4,7 @@ import com.github.michaelbull.logging.InlineLogger import content.entity.player.dialogue.type.makeAmount import world.gregs.voidps.engine.Script import world.gregs.voidps.engine.client.message -import world.gregs.voidps.engine.data.definition.EnumDefinitions +import world.gregs.voidps.engine.data.definition.Rows import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.chat.ChatType import world.gregs.voidps.engine.entity.character.player.equip.equipped @@ -102,8 +102,8 @@ class Furnace : Script { return } - val xp = EnumDefinitions.intOrNull("smelting_xp", id) ?: return - val level = EnumDefinitions.int("smelting_level", id) + val row = Rows.getOrNull("bars.${id}") ?: return + val level = row.int("level") if (!player.has(Skill.Smithing, level, message = true)) { player.softTimers.stop("smelting") return @@ -111,12 +111,12 @@ class Furnace : Script { player.face(furnaceSide(player, target)) player.anim("furnace_smelt") player.sound("smelt_bar") - val message = EnumDefinitions.stringOrNull("smelting_message", id) + val message = row.stringOrNull("message") if (message != null) { player.message(message, ChatType.Filter) } player.weakQueue("smelting", 4) { - val chance = EnumDefinitions.int("smelting_chance", id) + val chance = row.int("chance") val success = random.nextInt(255) < chance val items = requiredOres(id) player.inventory.transaction { @@ -129,9 +129,10 @@ class Furnace : Script { TransactionError.None -> { var removed = 1 if (success) { - player.exp(Skill.Smithing, goldXp(player, id, xp / 10.0)) + val xp = row.int("xp") / 10.0 + player.exp(Skill.Smithing, goldXp(player, id, xp)) player.message("You retrieve a bar of ${id.removeSuffix("_bar")}.") - if (amount - 1 > 0 && varrockArmour(player, target, id, items)) { + if (amount - 1 > 0 && varrockArmour(player, target, id, items, xp)) { removed = 2 } } else { @@ -150,6 +151,7 @@ class Furnace : Script { target: GameObject, id: String, items: List, + xp: Double ): Boolean { if (target.id != "furnace_edgeville" || !player.inventory.contains(items)) { return false @@ -171,8 +173,7 @@ class Furnace : Script { remove(items) add(id) } - val xp = EnumDefinitions.int("smelting_xp", id) - player.exp(Skill.Smithing, xp / 10.0) + player.exp(Skill.Smithing, xp) player.message("The magic of the Varrock armour enables you to smelt 2 bars at the same time.") return true } @@ -188,11 +189,14 @@ class Furnace : Script { } internal fun requiredOres(id: String): MutableList { + val row = Rows.getOrNull("bars.${id}") ?: return mutableListOf() val items = mutableListOf() - items.add(Item(EnumDefinitions.string("smelting_ore_id", id))) - val secondary = EnumDefinitions.stringOrNull("smelting_ore_secondary_id", id) - if (secondary != null) { - items.add(Item(secondary, EnumDefinitions.int("smelting_ore_secondary_amount", id))) + val ores = row.itemList("ore") + val amounts = row.intList("amount") + for (i in ores.indices) { + val ore = ores[i] + val amount = amounts[i] + items.add(Item(ore, amount)) } return items } diff --git a/game/src/main/kotlin/content/skill/smithing/SuperheatItem.kt b/game/src/main/kotlin/content/skill/smithing/SuperheatItem.kt index 3e7a004a9a..07c9387de1 100644 --- a/game/src/main/kotlin/content/skill/smithing/SuperheatItem.kt +++ b/game/src/main/kotlin/content/skill/smithing/SuperheatItem.kt @@ -3,7 +3,7 @@ package content.skill.smithing import content.skill.magic.spell.SpellRunes.removeItems import world.gregs.voidps.engine.Script import world.gregs.voidps.engine.client.message -import world.gregs.voidps.engine.data.definition.EnumDefinitions +import world.gregs.voidps.engine.data.definition.Rows import world.gregs.voidps.engine.data.definition.SpellDefinitions import world.gregs.voidps.engine.entity.character.player.skill.Skill import world.gregs.voidps.engine.entity.character.player.skill.exp.exp @@ -27,8 +27,8 @@ class SuperheatItem(val spellDefinitions: SpellDefinitions) : Script { if (bar == "iron_bar" && inventory.count("coal") >= 2) { bar = "steel_bar" } - val xp = EnumDefinitions.intOrNull("smelting_xp", bar) ?: return@onItem - val level = EnumDefinitions.int("smelting_level", bar) + val row = Rows.getOrNull("bars.${bar}") ?: return@onItem + val level = row.int("level") if (!has(Skill.Smithing, level, message = true)) { sound("superheat_fail") return@onItem @@ -45,8 +45,9 @@ class SuperheatItem(val spellDefinitions: SpellDefinitions) : Script { anim(spell) gfx(spell) val definition = spellDefinitions.get(spell) + val xp = row.int("xp") / 10.0 exp(Skill.Magic, definition.experience) - exp(Skill.Smithing, Furnace.goldXp(this, bar, xp / 10.0)) + exp(Skill.Smithing, Furnace.goldXp(this, bar, xp)) } else { sound("superheat_fail") } From 4ed9382f2392171f14ddd21d922310cfeae7fa8e Mon Sep 17 00:00:00 2001 From: GregHib Date: Fri, 27 Mar 2026 11:06:06 +0000 Subject: [PATCH 22/40] Convert smithing enums --- data/skill/smithing/smithing.enums.toml | 448 ------------ data/skill/smithing/smithing.tables.toml | 680 ++++++++++++++++++ .../kotlin/content/skill/smithing/Anvil.kt | 27 +- 3 files changed, 694 insertions(+), 461 deletions(-) delete mode 100644 data/skill/smithing/smithing.enums.toml create mode 100644 data/skill/smithing/smithing.tables.toml diff --git a/data/skill/smithing/smithing.enums.toml b/data/skill/smithing/smithing.enums.toml deleted file mode 100644 index ccd3ef4762..0000000000 --- a/data/skill/smithing/smithing.enums.toml +++ /dev/null @@ -1,448 +0,0 @@ -[smelting_level] -keyType = "item" -valueType = "int" -defaultInt = 1 -values = { - blurite_bar = 13, - elemental_bar = 20, - iron_bar = 15, - steel_bar = 30, - silver_bar = 20, - gold_bar = 40, - mithril_bar = 50, - adamant_bar = 70, - rune_bar = 85, -} - -[smelting_xp] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - blurite_bar = 80, - elemental_bar = 75, - bronze_bar = 62, - iron_bar = 125, - steel_bar = 175, - silver_bar = 137, - gold_bar = 225, - mithril_bar = 300, - adamant_bar = 375, - rune_bar = 500, -} - -[smelting_chance] -keyType = "item" -valueType = "int" -defaultInt = 255 -values = { - iron_bar = 128, -} - -[smelting_message] -keyType = "item" -valueType = "string" -values = { - blurite_bar = "You place the blurite and four heaps of coal into the furnace.", - elemental_bar = "You place the elemental ore and four heaps of coal into the furnace.", - bronze_bar = "You smelt the copper and tin together in the furnace.", - iron_bar = "You smelt the iron in the furnace.", - steel_bar = "You place the iron and two heaps of coal into the furnace.", - silver_bar = "You place the silver into the furnace.", - gold_bar = "You place a lump of gold in the furnace.", - mithril_bar = "You place the mithril and four heaps of coal into the furnace.", - adamant_bar = "You place the adamantite and six heaps of coal into the furnace.", - rune_bar = "You place the runite and six heaps of coal into the furnace.", -} - -[smelting_ore_id] -keyType = "item" -valueType = "string" -values = { - blurite_bar = "blurite_ore", - elemental_bar = "elemental_ore", - bronze_bar = "tin_ore", - iron_bar = "iron_ore", - steel_bar = "iron_ore", - silver_bar = "silver_ore", - gold_bar = "gold_ore", - mithril_bar = "mithril_ore", - adamant_bar = "adamantite_ore", - rune_bar = "runite_ore", -} - -[smelting_ore_secondary_id] -keyType = "item" -valueType = "string" -values = { - elemental_bar = "coal", - bronze_bar = "copper_ore", - steel_bar = "coal", - mithril_bar = "coal", - adamant_bar = "coal", - rune_bar = "coal", -} - -[smelting_ore_secondary_amount] -keyType = "item" -valueType = "int" -defaultInt = 1 -values = { - elemental_bar = 4, - steel_bar = 2, - mithril_bar = 4, - adamant_bar = 6, - rune_bar = 8, -} - -[smithing_level] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - steel_nails = 34, - iron_spit = 17, - cannonball = 35, - bronze_nails = 4, - iron_nails = 19, - mithril_nails = 54, - adamant_nails = 74, - rune_nails = 89, - bronze_wire = 4, - oil_lantern_frame = 26, - bronze_arrowtips = 5, - iron_arrowtips = 20, - steel_arrowtips = 35, - mithril_arrowtips = 55, - adamant_arrowtips = 75, - rune_arrowtips = 90, - iron_platelegs = 31, - steel_platelegs = 46, - mithril_platelegs = 66, - adamant_platelegs = 86, - bronze_platelegs = 16, - rune_platelegs = 99, - iron_plateskirt = 31, - steel_plateskirt = 46, - mithril_plateskirt = 66, - bronze_plateskirt = 16, - adamant_plateskirt = 86, - rune_plateskirt = 99, - iron_chainbody = 26, - bronze_chainbody = 11, - steel_chainbody = 41, - mithril_chainbody = 61, - adamant_chainbody = 81, - rune_chainbody = 96, - iron_platebody = 33, - bronze_platebody = 18, - steel_platebody = 48, - mithril_platebody = 68, - adamant_platebody = 88, - rune_platebody = 99, - iron_med_helm = 18, - bronze_med_helm = 3, - steel_med_helm = 33, - mithril_med_helm = 53, - adamant_med_helm = 73, - rune_med_helm = 88, - iron_full_helm = 22, - bronze_full_helm = 7, - steel_full_helm = 37, - mithril_full_helm = 57, - adamant_full_helm = 77, - rune_full_helm = 92, - bronze_sq_shield = 8, - iron_sq_shield = 23, - steel_sq_shield = 38, - mithril_sq_shield = 58, - adamant_sq_shield = 78, - rune_sq_shield = 93, - bronze_kiteshield = 12, - iron_kiteshield = 27, - steel_kiteshield = 42, - mithril_kiteshield = 62, - adamant_kiteshield = 82, - rune_kiteshield = 97, - iron_dagger = 15, - bronze_dagger = 1, - steel_dagger = 30, - mithril_dagger = 50, - adamant_dagger = 70, - rune_dagger = 85, - bronze_spear = 5, - iron_spear = 20, - steel_spear = 35, - mithril_spear = 55, - adamant_spear = 75, - rune_spear = 90, - bronze_sword = 4, - iron_sword = 19, - steel_sword = 34, - mithril_sword = 54, - adamant_sword = 74, - rune_sword = 89, - bronze_longsword = 6, - iron_longsword = 21, - steel_longsword = 36, - mithril_longsword = 56, - adamant_longsword = 76, - rune_longsword = 91, - bronze_2h_sword = 14, - iron_2h_sword = 29, - steel_2h_sword = 44, - mithril_2h_sword = 64, - adamant_2h_sword = 84, - rune_2h_sword = 99, - bronze_scimitar = 5, - iron_scimitar = 20, - steel_scimitar = 35, - mithril_scimitar = 55, - adamant_scimitar = 75, - rune_scimitar = 90, - iron_warhammer = 24, - bronze_warhammer = 9, - steel_warhammer = 39, - mithril_warhammer = 59, - adamant_warhammer = 79, - rune_warhammer = 94, - iron_battleaxe = 25, - steel_battleaxe = 40, - mithril_battleaxe = 60, - adamant_battleaxe = 80, - rune_battleaxe = 95, - bronze_battleaxe = 10, - iron_mace = 17, - bronze_mace = 2, - steel_mace = 32, - mithril_mace = 52, - adamant_mace = 72, - rune_mace = 87, - bronze_claws = 13, - iron_claws = 28, - steel_claws = 43, - mithril_claws = 63, - adamant_claws = 83, - rune_claws = 98, - bronze_hasta = 5, - iron_hasta = 20, - steel_hasta = 35, - mithril_hasta = 55, - adamant_hasta = 75, - rune_hasta = 90, - bronze_pickaxe = 5, - iron_pickaxe = 35, - steel_pickaxe = 35, - adamant_pickaxe = 55, - mithril_pickaxe = 75, - rune_pickaxe = 91, - bronze_bolts_unf = 3, - iron_bolts_unf = 18, - steel_bolts_unf = 33, - mithril_bolts_unf = 53, - adamant_bolts_unf = 73, - rune_bolts_unf = 88, - silver_bolts_unf = 21, - mithril_grapple_tip = 59, - bronze_limbs = 6, - iron_limbs = 23, - steel_limbs = 36, - mithril_limbs = 56, - adamant_limbs = 76, - rune_limbs = 91, - bronze_dart_tip = 4, - iron_dart_tip = 19, - steel_dart_tip = 34, - mithril_dart_tip = 54, - adamant_dart_tip = 74, - rune_dart_tip = 89, - iron_knife = 22, - bronze_knife = 7, - steel_knife = 37, - mithril_knife = 57, - adamant_knife = 77, - rune_knife = 92, - steel_studs = 36, - iron_hatchet = 16, - bronze_hatchet = 1, - steel_hatchet = 31, - mithril_hatchet = 51, - adamant_hatchet = 71, - rune_hatchet = 86, -} - -[smithing_xp] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - steel_nails = 375, - iron_spit = 250, - cannonball = 256, - bronze_nails = 125, - iron_nails = 250, - mithril_nails = 500, - adamant_nails = 625, - rune_nails = 750, - bronze_wire = 125, - oil_lantern_frame = 250, - bronze_arrowtips = 125, - iron_arrowtips = 250, - steel_arrowtips = 375, - mithril_arrowtips = 500, - adamant_arrowtips = 625, - rune_arrowtips = 750, - iron_platelegs = 750, - steel_platelegs = 1125, - mithril_platelegs = 1500, - adamant_platelegs = 1875, - bronze_platelegs = 375, - rune_platelegs = 2250, - iron_plateskirt = 750, - steel_plateskirt = 1125, - mithril_plateskirt = 1500, - bronze_plateskirt = 375, - adamant_plateskirt = 1875, - rune_plateskirt = 2250, - iron_chainbody = 750, - bronze_chainbody = 375, - steel_chainbody = 1125, - mithril_chainbody = 1500, - adamant_chainbody = 1875, - rune_chainbody = 2250, - iron_platebody = 1250, - bronze_platebody = 625, - steel_platebody = 1875, - mithril_platebody = 2500, - adamant_platebody = 3125, - rune_platebody = 3750, - iron_med_helm = 250, - bronze_med_helm = 125, - steel_med_helm = 375, - mithril_med_helm = 500, - adamant_med_helm = 625, - rune_med_helm = 750, - iron_full_helm = 500, - bronze_full_helm = 250, - steel_full_helm = 750, - mithril_full_helm = 1000, - adamant_full_helm = 1250, - rune_full_helm = 1500, - bronze_sq_shield = 250, - iron_sq_shield = 500, - steel_sq_shield = 750, - mithril_sq_shield = 1000, - adamant_sq_shield = 1250, - rune_sq_shield = 1500, - bronze_kiteshield = 375, - iron_kiteshield = 750, - steel_kiteshield = 1125, - mithril_kiteshield = 1500, - adamant_kiteshield = 1875, - rune_kiteshield = 2250, - iron_dagger = 250, - bronze_dagger = 125, - steel_dagger = 375, - mithril_dagger = 500, - adamant_dagger = 625, - rune_dagger = 750, - bronze_spear = 250, - iron_spear = 500, - steel_spear = 750, - mithril_spear = 1000, - adamant_spear = 1250, - rune_spear = 1500, - bronze_sword = 125, - iron_sword = 250, - steel_sword = 375, - mithril_sword = 500, - adamant_sword = 625, - rune_sword = 750, - bronze_longsword = 250, - iron_longsword = 500, - steel_longsword = 750, - mithril_longsword = 1000, - adamant_longsword = 1250, - rune_longsword = 1500, - bronze_2h_sword = 375, - iron_2h_sword = 750, - steel_2h_sword = 1125, - mithril_2h_sword = 1500, - adamant_2h_sword = 1875, - rune_2h_sword = 2250, - bronze_scimitar = 250, - iron_scimitar = 500, - steel_scimitar = 750, - mithril_scimitar = 1000, - adamant_scimitar = 1250, - rune_scimitar = 1500, - iron_warhammer = 750, - bronze_warhammer = 375, - steel_warhammer = 1125, - mithril_warhammer = 1500, - adamant_warhammer = 1875, - rune_warhammer = 2250, - iron_battleaxe = 750, - steel_battleaxe = 1125, - mithril_battleaxe = 1500, - adamant_battleaxe = 1875, - rune_battleaxe = 2250, - bronze_battleaxe = 375, - iron_mace = 250, - bronze_mace = 125, - steel_mace = 375, - mithril_mace = 500, - adamant_mace = 625, - rune_mace = 750, - bronze_claws = 250, - iron_claws = 500, - steel_claws = 750, - mithril_claws = 1000, - adamant_claws = 1250, - rune_claws = 1500, - bronze_hasta = 250, - iron_hasta = 500, - steel_hasta = 750, - mithril_hasta = 1000, - adamant_hasta = 1250, - rune_hasta = 1500, - bronze_pickaxe = 250, - iron_pickaxe = 500, - steel_pickaxe = 750, - adamant_pickaxe = 1000, - mithril_pickaxe = 1250, - rune_pickaxe = 1500, - bronze_bolts_unf = 125, - iron_bolts_unf = 250, - steel_bolts_unf = 375, - mithril_bolts_unf = 500, - adamant_bolts_unf = 625, - rune_bolts_unf = 750, - silver_bolts_unf = 500, - mithril_grapple_tip = 500, - bronze_limbs = 125, - iron_limbs = 250, - steel_limbs = 375, - mithril_limbs = 500, - adamant_limbs = 625, - rune_limbs = 750, - bronze_dart_tip = 125, - iron_dart_tip = 250, - steel_dart_tip = 375, - mithril_dart_tip = 500, - adamant_dart_tip = 625, - rune_dart_tip = 750, - iron_knife = 250, - bronze_knife = 125, - steel_knife = 375, - mithril_knife = 500, - adamant_knife = 625, - rune_knife = 750, - steel_studs = 375, - iron_hatchet = 250, - bronze_hatchet = 125, - steel_hatchet = 375, - mithril_hatchet = 500, - adamant_hatchet = 625, - rune_hatchet = 750, -} diff --git a/data/skill/smithing/smithing.tables.toml b/data/skill/smithing/smithing.tables.toml new file mode 100644 index 0000000000..8451313c6c --- /dev/null +++ b/data/skill/smithing/smithing.tables.toml @@ -0,0 +1,680 @@ +[smithing] +row_id = "item" +level = "int" +xp = "int" + +[.adamant_2h_sword] +level = 84 +xp = 1875 + +[.adamant_arrowtips] +level = 75 +xp = 625 + +[.adamant_battleaxe] +level = 80 +xp = 1875 + +[.adamant_bolts_unf] +level = 73 +xp = 625 + +[.adamant_chainbody] +level = 81 +xp = 1875 + +[.adamant_claws] +level = 83 +xp = 1250 + +[.adamant_dagger] +level = 70 +xp = 625 + +[.adamant_dart_tip] +level = 74 +xp = 625 + +[.adamant_full_helm] +level = 77 +xp = 1250 + +[.adamant_hasta] +level = 75 +xp = 1250 + +[.adamant_hatchet] +level = 71 +xp = 625 + +[.adamant_kiteshield] +level = 82 +xp = 1875 + +[.adamant_knife] +level = 77 +xp = 625 + +[.adamant_limbs] +level = 76 +xp = 625 + +[.adamant_longsword] +level = 76 +xp = 1250 + +[.adamant_mace] +level = 72 +xp = 625 + +[.adamant_med_helm] +level = 73 +xp = 625 + +[.adamant_nails] +level = 74 +xp = 625 + +[.adamant_pickaxe] +level = 55 +xp = 1000 + +[.adamant_platebody] +level = 88 +xp = 3125 + +[.adamant_platelegs] +level = 86 +xp = 1875 + +[.adamant_plateskirt] +level = 86 +xp = 1875 + +[.adamant_scimitar] +level = 75 +xp = 1250 + +[.adamant_spear] +level = 75 +xp = 1250 + +[.adamant_sq_shield] +level = 78 +xp = 1250 + +[.adamant_sword] +level = 74 +xp = 625 + +[.adamant_warhammer] +level = 79 +xp = 1875 + +[.bronze_2h_sword] +level = 14 +xp = 375 + +[.bronze_arrowtips] +level = 5 +xp = 125 + +[.bronze_battleaxe] +level = 10 +xp = 375 + +[.bronze_bolts_unf] +level = 3 +xp = 125 + +[.bronze_chainbody] +level = 11 +xp = 375 + +[.bronze_claws] +level = 13 +xp = 250 + +[.bronze_dagger] +level = 1 +xp = 125 + +[.bronze_dart_tip] +level = 4 +xp = 125 + +[.bronze_full_helm] +level = 7 +xp = 250 + +[.bronze_hasta] +level = 5 +xp = 250 + +[.bronze_hatchet] +level = 1 +xp = 125 + +[.bronze_kiteshield] +level = 12 +xp = 375 + +[.bronze_knife] +level = 7 +xp = 125 + +[.bronze_limbs] +level = 6 +xp = 125 + +[.bronze_longsword] +level = 6 +xp = 250 + +[.bronze_mace] +level = 2 +xp = 125 + +[.bronze_med_helm] +level = 3 +xp = 125 + +[.bronze_nails] +level = 4 +xp = 125 + +[.bronze_pickaxe] +level = 5 +xp = 250 + +[.bronze_platebody] +level = 18 +xp = 625 + +[.bronze_platelegs] +level = 16 +xp = 375 + +[.bronze_plateskirt] +level = 16 +xp = 375 + +[.bronze_scimitar] +level = 5 +xp = 250 + +[.bronze_spear] +level = 5 +xp = 250 + +[.bronze_sq_shield] +level = 8 +xp = 250 + +[.bronze_sword] +level = 4 +xp = 125 + +[.bronze_warhammer] +level = 9 +xp = 375 + +[.bronze_wire] +level = 4 +xp = 125 + +[.cannonball] +level = 35 +xp = 256 + +[.iron_2h_sword] +level = 29 +xp = 750 + +[.iron_arrowtips] +level = 20 +xp = 250 + +[.iron_battleaxe] +level = 25 +xp = 750 + +[.iron_bolts_unf] +level = 18 +xp = 250 + +[.iron_chainbody] +level = 26 +xp = 750 + +[.iron_claws] +level = 28 +xp = 500 + +[.iron_dagger] +level = 15 +xp = 250 + +[.iron_dart_tip] +level = 19 +xp = 250 + +[.iron_full_helm] +level = 22 +xp = 500 + +[.iron_hasta] +level = 20 +xp = 500 + +[.iron_hatchet] +level = 16 +xp = 250 + +[.iron_kiteshield] +level = 27 +xp = 750 + +[.iron_knife] +level = 22 +xp = 250 + +[.iron_limbs] +level = 23 +xp = 250 + +[.iron_longsword] +level = 21 +xp = 500 + +[.iron_mace] +level = 17 +xp = 250 + +[.iron_med_helm] +level = 18 +xp = 250 + +[.iron_nails] +level = 19 +xp = 250 + +[.iron_pickaxe] +level = 35 +xp = 500 + +[.iron_platebody] +level = 33 +xp = 1250 + +[.iron_platelegs] +level = 31 +xp = 750 + +[.iron_plateskirt] +level = 31 +xp = 750 + +[.iron_scimitar] +level = 20 +xp = 500 + +[.iron_spear] +level = 20 +xp = 500 + +[.iron_spit] +level = 17 +xp = 250 + +[.iron_sq_shield] +level = 23 +xp = 500 + +[.iron_sword] +level = 19 +xp = 250 + +[.iron_warhammer] +level = 24 +xp = 750 + +[.mithril_2h_sword] +level = 64 +xp = 1500 + +[.mithril_arrowtips] +level = 55 +xp = 500 + +[.mithril_battleaxe] +level = 60 +xp = 1500 + +[.mithril_bolts_unf] +level = 53 +xp = 500 + +[.mithril_chainbody] +level = 61 +xp = 1500 + +[.mithril_claws] +level = 63 +xp = 1000 + +[.mithril_dagger] +level = 50 +xp = 500 + +[.mithril_dart_tip] +level = 54 +xp = 500 + +[.mithril_full_helm] +level = 57 +xp = 1000 + +[.mithril_grapple_tip] +level = 59 +xp = 500 + +[.mithril_hasta] +level = 55 +xp = 1000 + +[.mithril_hatchet] +level = 51 +xp = 500 + +[.mithril_kiteshield] +level = 62 +xp = 1500 + +[.mithril_knife] +level = 57 +xp = 500 + +[.mithril_limbs] +level = 56 +xp = 500 + +[.mithril_longsword] +level = 56 +xp = 1000 + +[.mithril_mace] +level = 52 +xp = 500 + +[.mithril_med_helm] +level = 53 +xp = 500 + +[.mithril_nails] +level = 54 +xp = 500 + +[.mithril_pickaxe] +level = 75 +xp = 1250 + +[.mithril_platebody] +level = 68 +xp = 2500 + +[.mithril_platelegs] +level = 66 +xp = 1500 + +[.mithril_plateskirt] +level = 66 +xp = 1500 + +[.mithril_scimitar] +level = 55 +xp = 1000 + +[.mithril_spear] +level = 55 +xp = 1000 + +[.mithril_sq_shield] +level = 58 +xp = 1000 + +[.mithril_sword] +level = 54 +xp = 500 + +[.mithril_warhammer] +level = 59 +xp = 1500 + +[.oil_lantern_frame] +level = 26 +xp = 250 + +[.rune_2h_sword] +level = 99 +xp = 2250 + +[.rune_arrowtips] +level = 90 +xp = 750 + +[.rune_battleaxe] +level = 95 +xp = 2250 + +[.rune_bolts_unf] +level = 88 +xp = 750 + +[.rune_chainbody] +level = 96 +xp = 2250 + +[.rune_claws] +level = 98 +xp = 1500 + +[.rune_dagger] +level = 85 +xp = 750 + +[.rune_dart_tip] +level = 89 +xp = 750 + +[.rune_full_helm] +level = 92 +xp = 1500 + +[.rune_hasta] +level = 90 +xp = 1500 + +[.rune_hatchet] +level = 86 +xp = 750 + +[.rune_kiteshield] +level = 97 +xp = 2250 + +[.rune_knife] +level = 92 +xp = 750 + +[.rune_limbs] +level = 91 +xp = 750 + +[.rune_longsword] +level = 91 +xp = 1500 + +[.rune_mace] +level = 87 +xp = 750 + +[.rune_med_helm] +level = 88 +xp = 750 + +[.rune_nails] +level = 89 +xp = 750 + +[.rune_pickaxe] +level = 91 +xp = 1500 + +[.rune_platebody] +level = 99 +xp = 3750 + +[.rune_platelegs] +level = 99 +xp = 2250 + +[.rune_plateskirt] +level = 99 +xp = 2250 + +[.rune_scimitar] +level = 90 +xp = 1500 + +[.rune_spear] +level = 90 +xp = 1500 + +[.rune_sq_shield] +level = 93 +xp = 1500 + +[.rune_sword] +level = 89 +xp = 750 + +[.rune_warhammer] +level = 94 +xp = 2250 + +[.silver_bolts_unf] +level = 21 +xp = 500 + +[.steel_2h_sword] +level = 44 +xp = 1125 + +[.steel_arrowtips] +level = 35 +xp = 375 + +[.steel_battleaxe] +level = 40 +xp = 1125 + +[.steel_bolts_unf] +level = 33 +xp = 375 + +[.steel_chainbody] +level = 41 +xp = 1125 + +[.steel_claws] +level = 43 +xp = 750 + +[.steel_dagger] +level = 30 +xp = 375 + +[.steel_dart_tip] +level = 34 +xp = 375 + +[.steel_full_helm] +level = 37 +xp = 750 + +[.steel_hasta] +level = 35 +xp = 750 + +[.steel_hatchet] +level = 31 +xp = 375 + +[.steel_kiteshield] +level = 42 +xp = 1125 + +[.steel_knife] +level = 37 +xp = 375 + +[.steel_limbs] +level = 36 +xp = 375 + +[.steel_longsword] +level = 36 +xp = 750 + +[.steel_mace] +level = 32 +xp = 375 + +[.steel_med_helm] +level = 33 +xp = 375 + +[.steel_nails] +level = 34 +xp = 375 + +[.steel_pickaxe] +level = 35 +xp = 750 + +[.steel_platebody] +level = 48 +xp = 1875 + +[.steel_platelegs] +level = 46 +xp = 1125 + +[.steel_plateskirt] +level = 46 +xp = 1125 + +[.steel_scimitar] +level = 35 +xp = 750 + +[.steel_spear] +level = 35 +xp = 750 + +[.steel_sq_shield] +level = 38 +xp = 750 + +[.steel_studs] +level = 36 +xp = 375 + +[.steel_sword] +level = 34 +xp = 375 + +[.steel_warhammer] +level = 39 +xp = 1125 diff --git a/game/src/main/kotlin/content/skill/smithing/Anvil.kt b/game/src/main/kotlin/content/skill/smithing/Anvil.kt index 6dcbc0f7f1..5ff7611ff2 100644 --- a/game/src/main/kotlin/content/skill/smithing/Anvil.kt +++ b/game/src/main/kotlin/content/skill/smithing/Anvil.kt @@ -13,9 +13,11 @@ import world.gregs.voidps.engine.client.ui.chat.Colours import world.gregs.voidps.engine.client.ui.chat.an import world.gregs.voidps.engine.client.ui.closeMenu import world.gregs.voidps.engine.client.ui.open -import world.gregs.voidps.engine.data.definition.EnumDefinitions +import world.gregs.voidps.engine.data.config.RowDefinition import world.gregs.voidps.engine.data.definition.InterfaceDefinitions import world.gregs.voidps.engine.data.definition.ItemDefinitions +import world.gregs.voidps.engine.data.definition.Rows +import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.skill.Skill import world.gregs.voidps.engine.entity.character.player.skill.exp.exp @@ -96,12 +98,12 @@ class Anvil : Script { if (id != -1) { val amount = componentDefinition?.getOrNull("amount") ?: 1 interfaces.sendItem("smithing", type, id, amount) - val xp = EnumDefinitions.intOrNull("smithing_xp", itemDefinition.stringId) + val xp = Tables.intOrNull("smithing.${itemDefinition.stringId}.xp") if (xp == null) { logger.warn { "Item $id does not have a smithing component." } continue } - val level = EnumDefinitions.int("smithing_level", itemDefinition.stringId) + val level = Tables.int("smithing.${itemDefinition.stringId}.level") interfaces.sendColour("smithing", "${type}_name", if (has(Skill.Smithing, level)) Colours.WHITE else Colours.BLACK) } val required = componentDefinition?.getOrNull("bars") ?: 1 @@ -134,7 +136,7 @@ class Anvil : Script { "mithril" if type == "grapple" -> "mithril_grapple_tip" else -> "${metal}_$type" } - EnumDefinitions.intOrNull("smithing_xp", item) ?: return + val row = Rows.getOrNull("smithing.${item}") ?: return val component = InterfaceDefinitions.getComponent("smithing", type) val quantity = component?.getOrNull("amount") ?: 1 val bars = component?.getOrNull("bars") ?: 1 @@ -147,7 +149,7 @@ class Anvil : Script { softTimers.stop("smithing") return } - smith(metal, bars, quantity, type, item, actualAmount, true) + smith(metal, bars, quantity, type, row, actualAmount, true) } suspend fun Player.smith( @@ -155,7 +157,7 @@ class Anvil : Script { bars: Int, quantity: Int, type: String, - item: String, + row: RowDefinition, count: Int, first: Boolean, ) { @@ -169,9 +171,9 @@ class Anvil : Script { return } - val level = EnumDefinitions.int("smithing_level", item) + val level = row.int("level") if (!has(Skill.Smithing, level, message = false)) { - val name = item.removeSuffix("_unf") + val name = row.itemId.removeSuffix("_unf") statement("You need a Smithing level of $level to make${name.an()} ${name.toTitleCase()}.") softTimers.stop("smithing") return @@ -182,18 +184,17 @@ class Anvil : Script { weakQueue("smithing", if (first) 0 else 5) { inventory.transaction { remove(bar, bars) - add(item, quantity) + add(row.itemId, quantity) } when (inventory.transaction.error) { is TransactionError.Deficient -> message("You do not have enough bars to smith this item.") TransactionError.None -> { - val xp = EnumDefinitions.int("smithing_xp", item) / 10.0 - exp(Skill.Smithing, xp) - smith(metal, bars, quantity, type, item, count - 1, false) + exp(Skill.Smithing, row.int("xp") / 10.0) + smith(metal, bars, quantity, type, row, count - 1, false) val name = type.removeSuffix("_unf").replace("_", " ") message("You hammer the $metal and make${name.an()} $name.") } - else -> logger.warn { "Error smithing ${this@smith} $item ${inventory.transaction.error} ${inventory.items.contentToString()}" } + else -> logger.warn { "Error smithing ${this@smith} ${row.itemId} ${inventory.transaction.error} ${inventory.items.contentToString()}" } } } } From 28d2242291b679c0008c595e16743b7cc6fe8388 Mon Sep 17 00:00:00 2001 From: GregHib Date: Fri, 27 Mar 2026 12:56:14 +0000 Subject: [PATCH 23/40] Convert runecrafting enums --- .../combination_runes.tables.toml | 42 +++ .../runecrafting/runecrafting.enums.toml | 291 ------------------ data/skill/runecrafting/runes.tables.toml | 113 +++++++ data/skill/runecrafting/tiaras.tables.toml | 39 +++ .../engine/data/config/RowDefinition.kt | 2 + .../area/kandarin/ourania/OuraniaAltar.kt | 7 +- .../skill/runecrafting/Runecrafting.kt | 30 +- .../content/skill/runecrafting/Tiaras.kt | 4 +- 8 files changed, 217 insertions(+), 311 deletions(-) create mode 100644 data/skill/runecrafting/combination_runes.tables.toml delete mode 100644 data/skill/runecrafting/runecrafting.enums.toml create mode 100644 data/skill/runecrafting/runes.tables.toml create mode 100644 data/skill/runecrafting/tiaras.tables.toml diff --git a/data/skill/runecrafting/combination_runes.tables.toml b/data/skill/runecrafting/combination_runes.tables.toml new file mode 100644 index 0000000000..12918efbd4 --- /dev/null +++ b/data/skill/runecrafting/combination_runes.tables.toml @@ -0,0 +1,42 @@ +[combination_runes] +row_id = "obj" +air_rune = "item" +air_rune_xp = "int" +earth_rune = "item" +earth_rune_xp = "int" +fire_rune = "item" +fire_rune_xp = "int" +water_rune = "item" +water_rune_xp = "int" + +[.water_altar] +fire_rune = "steam_rune" +fire_rune_xp = 93 +air_rune = "mist_rune" +air_rune_xp = 85 +earth_rune = "mud_rune" +earth_rune_xp = 93 + +[.earth_altar] +fire_rune = "lava_rune" +fire_rune_xp = 100 +water_rune = "mud_rune" +water_rune_xp = 95 +air_rune = "dust_rune" +air_rune_xp = 90 + +[.air_altar] +fire_rune = "smoke_rune" +fire_rune_xp = 85 +water_rune = "mist_rune" +water_rune_xp = 80 +earth_rune = "dust_rune" +earth_rune_xp = 83 + +[.fire_altar] +water_rune = "steam_rune" +water_rune_xp = 100 +air_rune = "smoke_rune" +water_rune_xp = 95 +earth_rune = "lava_rune" +earth_rune_xp = 105 diff --git a/data/skill/runecrafting/runecrafting.enums.toml b/data/skill/runecrafting/runecrafting.enums.toml deleted file mode 100644 index d00bf736c6..0000000000 --- a/data/skill/runecrafting/runecrafting.enums.toml +++ /dev/null @@ -1,291 +0,0 @@ -[tiara_xp] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - air_tiara = 250, - mind_tiara = 275, - water_tiara = 300, - body_tiara = 375, - earth_tiara = 325, - fire_tiara = 350, - cosmic_tiara = 400, - nature_tiara = 450, - chaos_tiara = 425, - law_tiara = 475, - death_tiara = 500, - blood_tiara = 525, -} - -[runecrafting_xp] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - astral_rune = 87, - fire_rune = 70, - water_rune = 60, - air_rune = 50, - earth_rune = 65, - mind_rune = 55, - body_rune = 75, - death_rune = 100, - nature_rune = 90, - chaos_rune = 85, - law_rune = 95, - cosmic_rune = 80, - blood_rune = 105, - soul_rune = 297, -} - -[runecrafting_pure] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - astral_rune = 1, - death_rune = 1, - nature_rune = 1, - chaos_rune = 1, - law_rune = 1, - cosmic_rune = 1, - blood_rune = 1, - soul_rune = 1, -} - -[runecrafting_level] -keyType = "item" -valueType = "int" -defaultInt = 1 -values = { - astral_rune = 40, - fire_rune = 14, - water_rune = 5, - earth_rune = 9, - mind_rune = 2, - body_rune = 20, - death_rune = 65, - nature_rune = 44, - chaos_rune = 35, - law_rune = 54, - cosmic_rune = 27, - blood_rune = 77, - soul_rune = 90, - steam_rune = 19, - mist_rune = 6, - dust_rune = 10, - smoke_rune = 15, - mud_rune = 13, - lava_rune = 23, -} - -[runecrafting_ourania_double_chance] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - fire_rune = 250, - water_rune = 250, - air_rune = 250, - earth_rune = 250, - mind_rune = 250, - body_rune = 250, - death_rune = 175, - nature_rune = 225, - chaos_rune = 250, - law_rune = 200, - cosmic_rune = 250, - blood_rune = 150, - soul_rune = 100, -} - -[runecrafting_multiplier_astral_rune] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - 0 = 40, - 1 = 82, -} - -[runecrafting_multiplier_fire_rune] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - 0 = 14, - 1 = 35, - 2 = 70, -} - -[runecrafting_multiplier_water_rune] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - 0 = 5, - 1 = 19, - 2 = 38, - 3 = 57, - 4 = 76, - 5 = 95, -} - -[runecrafting_multiplier_air_rune] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - 0 = 1, - 1 = 11, - 2 = 22, - 3 = 33, - 4 = 44, - 5 = 55, - 6 = 66, - 7 = 77, - 8 = 88, - 9 = 99, -} - -[runecrafting_multiplier_earth_rune] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - 0 = 9, - 1 = 26, - 2 = 52, - 3 = 78, -} - -[runecrafting_multiplier_mind_rune] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - 0 = 2, - 1 = 14, - 2 = 28, - 3 = 42, - 4 = 56, - 5 = 84, - 6 = 98, -} - -[runecrafting_multiplier_body_rune] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - 0 = 20, - 1 = 46, - 2 = 92, -} - -[runecrafting_multiplier_nature_rune] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - 0 = 44, - 1 = 91, -} - -[runecrafting_multiplier_chaos_rune] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - 0 = 35, - 1 = 74, -} - -[runecrafting_multiplier_cosmic_rune] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - 0 = 27, - 1 = 59, -} - -[runecrafting_combination_water_altar] -keyType = "item" -valueType = "string" -defaultString = "" -values = { - fire_rune = "steam", - air_rune = "mist", - earth_rune = "mud", -} - -[runecrafting_combination_earth_altar] -keyType = "item" -valueType = "string" -defaultString = "" -values = { - fire_rune = "lava", - water_rune = "mud", - air_rune = "dust", -} - -[runecrafting_combination_air_altar] -keyType = "item" -valueType = "string" -defaultString = "" -values = { - fire_rune = "smoke", - water_rune = "mist", - earth_rune = "dust", -} - -[runecrafting_combination_fire_altar] -keyType = "item" -valueType = "string" -defaultString = "" -values = { - water_rune = "steam", - air_rune = "smoke", - earth_rune = "lava", -} - -[runecrafting_combination_water_altar_xp] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - fire_rune = 93, - air_rune = 85, - earth_rune = 93, -} - -[runecrafting_combination_earth_altar_xp] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - fire_rune = 100, - water_rune = 95, - air_rune = 90, -} - -[runecrafting_combination_air_altar_xp] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - fire_rune = 85, - water_rune = 80, - earth_rune = 83, -} - -[runecrafting_combination_fire_altar_xp] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - water_rune = 100, - air_rune = 95, - earth_rune = 105, -} \ No newline at end of file diff --git a/data/skill/runecrafting/runes.tables.toml b/data/skill/runecrafting/runes.tables.toml new file mode 100644 index 0000000000..302f1c2124 --- /dev/null +++ b/data/skill/runecrafting/runes.tables.toml @@ -0,0 +1,113 @@ +[runes] +row_id = "item" +level = "int" +xp = "int" +ourania_double_chance = "int" +multipliers = "list" +pure_essence = "boolean" + +[.fire_rune] +level = 14 +xp = 70 +ourania_double_chance = 250 +multipliers = [14, 35, 70] + +[.water_rune] +level = 5 +xp = 60 +ourania_double_chance = 250 +multipliers = [5, 19, 38, 57, 76, 95] + +[.air_rune] +level = 1 +xp = 50 +ourania_double_chance = 250 +multipliers = [1, 11, 22, 33, 44, 55, 66, 77, 88, 99] + +[.earth_rune] +level = 9 +xp = 65 +ourania_double_chance = 250 +multipliers = [9, 26, 52, 78] + +[.mind_rune] +level = 2 +xp = 55 +ourania_double_chance = 250 +multipliers = [2, 14, 28, 42, 56, 84, 98] + +[.body_rune] +level = 20 +xp = 75 +ourania_double_chance = 250 +multipliers = [20, 46, 92] + +[.astral_rune] +level = 40 +xp = 87 +pure_essence = true +multipliers = [40, 82] + +[.death_rune] +level = 65 +xp = 100 +ourania_double_chance = 175 +pure_essence = true + +[.nature_rune] +level = 44 +xp = 90 +ourania_double_chance = 225 +pure_essence = true +multipliers = [44, 91] + +[.chaos_rune] +level = 35 +xp = 85 +ourania_double_chance = 250 +pure_essence = true +multipliers = [35, 74] + +[.law_rune] +level = 54 +xp = 95 +ourania_double_chance = 200 +pure_essence = true + +[.cosmic_rune] +level = 27 +xp = 80 +ourania_double_chance = 250 +pure_essence = true +multipliers = [27, 59] + +[.blood_rune] +level = 77 +xp = 105 +ourania_double_chance = 150 +pure_essence = true + +[.soul_rune] +level = 90 +xp = 297 +ourania_double_chance = 100 +pure_essence = true + +[.steam_rune] +level = 19 + +[.mist_rune] +level = 6 + +[.dust_rune] +level = 10 + +[.smoke_rune] +level = 15 + +[.mud_rune] +level = 13 + +[.lava_rune] +level = 23 + diff --git a/data/skill/runecrafting/tiaras.tables.toml b/data/skill/runecrafting/tiaras.tables.toml new file mode 100644 index 0000000000..6d0c7ae911 --- /dev/null +++ b/data/skill/runecrafting/tiaras.tables.toml @@ -0,0 +1,39 @@ +[tiaras] +row_id = "item" +xp = "int" + +[.air_tiara] +xp = 250 + +[.mind_tiara] +xp = 275 + +[.water_tiara] +xp = 300 + +[.body_tiara] +xp = 375 + +[.earth_tiara] +xp = 325 + +[.fire_tiara] +xp = 350 + +[.cosmic_tiara] +xp = 400 + +[.nature_tiara] +xp = 450 + +[.chaos_tiara] +xp = 425 + +[.law_tiara] +xp = 475 + +[.death_tiara] +xp = 500 + +[.blood_tiara] +xp = 525 diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt index cb769b1a65..932db0cbca 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt @@ -21,6 +21,8 @@ data class RowDefinition( fun intList(column: String) = Tables.intList("${stringId}.$column") + fun intListOrNull(column: String) = Tables.intListOrNull("${stringId}.$column") + fun intOrNull(column: String) = Tables.intOrNull("${stringId}.$column") fun intRange(column: String) = Tables.intRange("${stringId}.$column") diff --git a/game/src/main/kotlin/content/area/kandarin/ourania/OuraniaAltar.kt b/game/src/main/kotlin/content/area/kandarin/ourania/OuraniaAltar.kt index d94be0a9ff..822dfa1835 100644 --- a/game/src/main/kotlin/content/area/kandarin/ourania/OuraniaAltar.kt +++ b/game/src/main/kotlin/content/area/kandarin/ourania/OuraniaAltar.kt @@ -4,7 +4,7 @@ import com.github.michaelbull.logging.InlineLogger import world.gregs.voidps.engine.Script import world.gregs.voidps.engine.client.message import world.gregs.voidps.engine.client.variable.start -import world.gregs.voidps.engine.data.definition.EnumDefinitions +import world.gregs.voidps.engine.data.definition.Rows import world.gregs.voidps.engine.entity.character.player.chat.ChatType import world.gregs.voidps.engine.entity.character.player.skill.Skill import world.gregs.voidps.engine.entity.character.player.skill.exp.exp @@ -38,8 +38,9 @@ class OuraniaAltar(val drops: DropTables) : Script { } for (drop in runes) { val item = drop.toItem() - val doubleChance = EnumDefinitions.int("runecrafting_ourania_double_chance", item.id) - val xp = EnumDefinitions.int("runecrafting_xp", item.id) / 10.0 + val row = Rows.get("runes.${item.id}") + val doubleChance = row.int("ourania_double_chance") + val xp = row.int("xp") / 10.0 val amount = if (get("ardougne_medium_diary_complete", false) && random.nextDouble(100.0) <= doubleChance) 2 else 1 usedArdougneCloak = usedArdougneCloak || amount == 2 add(item.id, amount) diff --git a/game/src/main/kotlin/content/skill/runecrafting/Runecrafting.kt b/game/src/main/kotlin/content/skill/runecrafting/Runecrafting.kt index 24f4da9fee..32a8cda461 100644 --- a/game/src/main/kotlin/content/skill/runecrafting/Runecrafting.kt +++ b/game/src/main/kotlin/content/skill/runecrafting/Runecrafting.kt @@ -8,7 +8,8 @@ import world.gregs.voidps.engine.client.ui.chat.plural import world.gregs.voidps.engine.client.ui.chat.toInt import world.gregs.voidps.engine.client.variable.hasClock import world.gregs.voidps.engine.client.variable.start -import world.gregs.voidps.engine.data.definition.EnumDefinitions +import world.gregs.voidps.engine.data.definition.Rows +import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.World import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.chat.ChatType @@ -43,9 +44,9 @@ class Runecrafting : Script { itemOnObjectOperate("*_rune", "*_altar") { (target, item) -> val element = item.id.removeSuffix("_rune") - val xp = EnumDefinitions.intOrNull("runecrafting_combination_${target.id}_xp", item.id) - val combination = EnumDefinitions.stringOrNull("runecrafting_combination_${target.id}", item.id) - if (xp == null || combination == null || !World.members) { + val combo = Rows.getOrNull("combination_runes.${target.id}") + val combination = combo?.itemOrNull(item.id)?.removeSuffix("_rune") + if (combo == null || combination == null || !World.members) { noInterest() return@itemOnObjectOperate } @@ -57,7 +58,7 @@ class Runecrafting : Script { message("You need a $element talisman to bind $combination runes.") return@itemOnObjectOperate } - val level = EnumDefinitions.int("runecrafting_level", item.id) + val level = Tables.int("runes.${item.id}.level") if (!has(Skill.Runecrafting, level, message = false)) { message("You need a Runecrafting level of $level to bind $combination runes.") return@itemOnObjectOperate @@ -81,7 +82,7 @@ class Runecrafting : Script { message("You need pure essence to bind $combination runes.") } TransactionError.None -> { - exp(Skill.Runecrafting, (xp / 10.0) * successes) + exp(Skill.Runecrafting, (combo.int("xp") / 10.0) * successes) if (bindingNecklace && equipment.discharge(this, EquipSlot.Amulet.index)) { val charge = equipment.charges(this, EquipSlot.Amulet.index) if (charge > 0) { @@ -103,18 +104,18 @@ class Runecrafting : Script { } fun bindRunes(player: Player, id: String) { - val xp = EnumDefinitions.intOrNull("runecrafting_xp", id) ?: return - val level = EnumDefinitions.int("runecrafting_level", id) + val rune = Rows.getOrNull("runes.$id") ?: return + val level = rune.int("level") if (!player.has(Skill.Runecrafting, level, message = true)) { return } player.softTimers.start("runecrafting") - val pure = EnumDefinitions.contains("runecrafting_pure", id) || !player.inventory.contains("rune_essence") + val pure = rune.bool("pure_essence") || !player.inventory.contains("rune_essence") val essenceId = if (pure) "pure_essence" else "rune_essence" val essence = player.inventory.count(essenceId) player.inventory.transaction { remove(essenceId, essence) - val count = multiplier(player, id) + val count = multiplier(player, rune.intListOrNull("multipliers")) add(id, essence * count) } player.start("movement_delay", 3) @@ -123,7 +124,7 @@ class Runecrafting : Script { player.message("You don't have any rune essences to bind.") } TransactionError.None -> { - player.exp(Skill.Runecrafting, (xp / 10.0) * essence) + player.exp(Skill.Runecrafting, (rune.int("xp") / 10.0) * essence) player.anim("bind_runes") player.gfx("bind_runes") player.sound("bind_runes") @@ -134,13 +135,12 @@ class Runecrafting : Script { player.softTimers.stop("runecrafting") } - private fun multiplier(player: Player, id: String): Int { - val map = EnumDefinitions.getOrNull("runecrafting_multiplier_$id")?.map ?: return 1 + private fun multiplier(player: Player, list: List?): Int { + val sorted = list?.withIndex()?.sortedByDescending { it.index } ?: return 1 var multiplier = 1 - val sorted = map.toList().sortedByDescending { it.first } val rc = player.levels.get(Skill.Runecrafting) for ((index, level) in sorted) { - if (rc >= level as Int) { + if (rc >= level) { multiplier = index + 1 break } diff --git a/game/src/main/kotlin/content/skill/runecrafting/Tiaras.kt b/game/src/main/kotlin/content/skill/runecrafting/Tiaras.kt index 5d1e34b96a..4f5b8cd9ce 100644 --- a/game/src/main/kotlin/content/skill/runecrafting/Tiaras.kt +++ b/game/src/main/kotlin/content/skill/runecrafting/Tiaras.kt @@ -4,7 +4,7 @@ import com.github.michaelbull.logging.InlineLogger import world.gregs.voidps.engine.Script import world.gregs.voidps.engine.client.message import world.gregs.voidps.engine.client.variable.start -import world.gregs.voidps.engine.data.definition.EnumDefinitions +import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.skill.Skill import world.gregs.voidps.engine.entity.character.player.skill.exp.exp @@ -26,7 +26,7 @@ class Tiaras : Script { } fun Tiaras.bindTiara(player: Player, id: String) { - val xp = EnumDefinitions.intOrNull("tiara_xp", id) ?: return + val xp = Tables.intOrNull("tiaras.${id}.xp") ?: return player.softTimers.start("runecrafting") val tiaraId = "tiara" val talismanId = id.replace("_tiara", "_talisman") From bfa8394e9a26a4ba13e8a6abd8fba3a618d09ce9 Mon Sep 17 00:00:00 2001 From: GregHib Date: Fri, 27 Mar 2026 13:19:31 +0000 Subject: [PATCH 24/40] Convert thieving enums --- data/skill/thieving/pickpocket.tables.toml | 345 ++++++++++++++++++ data/skill/thieving/thieving.enums.toml | 275 -------------- data/skill/thieving/thieving.tables.toml | 160 ++++++++ .../content/skill/thieving/Pickpocketing.kt | 19 +- 4 files changed, 515 insertions(+), 284 deletions(-) create mode 100644 data/skill/thieving/pickpocket.tables.toml delete mode 100644 data/skill/thieving/thieving.enums.toml create mode 100644 data/skill/thieving/thieving.tables.toml diff --git a/data/skill/thieving/pickpocket.tables.toml b/data/skill/thieving/pickpocket.tables.toml new file mode 100644 index 0000000000..1b274355ff --- /dev/null +++ b/data/skill/thieving/pickpocket.tables.toml @@ -0,0 +1,345 @@ +[pickpocket] +row_id = "npc" +type = "string" + +[.agnar_rellekka] +type = "fremmennik" + +[.al_kharid_warrior] +type = "warrior" + +[.bandit_bandit_camp] +type = "desert_bandit" + +[.bandit_bandit_camp_2] +type = "desert_bandit" + +[.bandit_pollnivneach_2_2] +type = "bearded_bandit" + +[.bandit_pollnivneach_2_3] +type = "bearded_bandit" + +[.bandit_pollnivneach_3] +type = "bandit" + +[.bandit_pollnivneach_4] +type = "bandit" + +[.borrokar] +type = "fremmennik" + +[.cave_goblin_dorgesh_kaan] +type = "cave_goblin" + +[.cave_goblin_dorgesh_kaan_10] +type = "cave_goblin" + +[.cave_goblin_dorgesh_kaan_11] +type = "cave_goblin" + +[.cave_goblin_dorgesh_kaan_12] +type = "cave_goblin" + +[.cave_goblin_dorgesh_kaan_13] +type = "cave_goblin" + +[.cave_goblin_dorgesh_kaan_16] +type = "cave_goblin" + +[.cave_goblin_dorgesh_kaan_2] +type = "cave_goblin" + +[.cave_goblin_dorgesh_kaan_3] +type = "cave_goblin" + +[.cave_goblin_dorgesh_kaan_4] +type = "cave_goblin" + +[.cave_goblin_dorgesh_kaan_5] +type = "cave_goblin" + +[.cave_goblin_dorgesh_kaan_6] +type = "cave_goblin" + +[.cave_goblin_dorgesh_kaan_7] +type = "cave_goblin" + +[.cave_goblin_dorgesh_kaan_8] +type = "cave_goblin" + +[.cave_goblin_dorgesh_kaan_9] +type = "cave_goblin" + +[.desert_digsite_workman] +type = "workman" + +[.digsite_workman_apron] +type = "workman" + +[.digsite_workman_dirty] +type = "workman" + +[.digsite_workman_dirty_2] +type = "workman" + +[.digsite_workman_long_hair] +type = "workman" + +[.farmer] +type = "farmer" + +[.farmer_lumbridge] +type = "farmer" + +[.farmer_lumbridge_3] +type = "farmer" + +[.freidir] +type = "fremmennik" + +[.freygerd_rellekka] +type = "fremmennik" + +[.gnome] +type = "gnome" + +[.gnome_2] +type = "gnome" + +[.gnome_3] +type = "gnome" + +[.gnome_child] +type = "gnome" + +[.gnome_child_2] +type = "gnome" + +[.gnome_child_3] +type = "gnome" + +[.gnome_woman] +type = "gnome" + +[.gnome_woman_2] +type = "gnome" + +[.guard_ardougne] +type = "guard" + +[.guard_edgeville] +type = "guard" + +[.guard_edgeville_2] +type = "guard" + +[.guard_edgeville_3] +type = "guard" + +[.guard_edgeville_4] +type = "guard" + +[.guard_edgeville_6] +type = "guard" + +[.guard_edgeville_7] +type = "guard" + +[.guard_falador] +type = "guard" + +[.guard_falador_2] +type = "guard" + +[.guard_falador_3] +type = "guard" + +[.guard_falador_4] +type = "guard" + +[.guard_falador_5] +type = "guard" + +[.guard_falador_6] +type = "guard" + +[.guard_falador_7] +type = "guard" + +[.guard_falador_8] +type = "guard" + +[.guard_ham_store_rooms] +type = "guard" + +[.guard_ham_store_rooms_2] +type = "guard" + +[.guard_ham_store_rooms_3] +type = "guard" + +[.guard_ham_store_rooms_4] +type = "guard" + +[.guard_ham_store_rooms_5] +type = "guard" + +[.guard_varrock] +type = "guard" + +[.guard_varrock_2] +type = "guard" + +[.ham_member_ham_cave] +type = "ham_member" + +[.ham_member_ham_cave_2] +type = "ham_member" + +[.ham_member_ham_cave_3] +type = "ham_member" + +[.hero] +type = "hero" + +[.inga] +type = "fremmennik" + +[.knight_of_ardougne] +type = "knight" + +[.lumbridge_man] +type = "human" + +[.lumbridge_man_2] +type = "human" + +[.lumbridge_man_3] +type = "human" + +[.lumbridge_man_4] +type = "human" + +[.lumbridge_man_5] +type = "human" + +[.lumbridge_man_6] +type = "human" + +[.lumbridge_man_7] +type = "human" + +[.lumbridge_woman] +type = "human" + +[.lumbridge_woman_2] +type = "human" + +[.lumbridge_woman_3] +type = "human" + +[.lumbridge_woman_4] +type = "human" + +[.lumbridge_woman_5] +type = "human" + +[.man] +type = "human" + +[.man_2] +type = "human" + +[.man_3] +type = "human" + +[.man_al_kharid] +type = "human" + +[.martin_the_master_gardener] +type = "master_farmer" + +[.master_farmer] +type = "master_farmer" + +[.master_farmer_varrock] +type = "master_farmer" + +[.menaphite_thug_pollnivneach_after_quest] +type = "thug" + +[.paladin] +type = "paladin" + +[.paladin_2] +type = "paladin" + +[.pontak_rellekka] +type = "fremmennik" + +[.port_sarim_guard] +type = "guard" + +[.port_sarim_guard_1] +type = "guard" + +[.port_sarim_guard_2] +type = "guard" + +[.port_sarim_guard_3] +type = "guard" + +[.port_sarim_guard_4] +type = "guard" + +[.rogue_castle] +type = "rouge" + +[.sassilik_rellekka] +type = "fremmennik" + +[.villager_pollnivneach_2_2] +type = "villager" + +[.villager_pollnivneach_2_3] +type = "villager" + +[.villager_pollnivneach_2_4] +type = "villager" + +[.villager_pollnivneach_3] +type = "villager" + +[.villager_pollnivneach_3_2] +type = "villager" + +[.villager_pollnivneach_3_3] +type = "villager" + +[.villager_pollnivneach_3_4] +type = "villager" + +[.villager_pollnivneach_4] +type = "villager" + +[.villager_pollnivneach_5] +type = "villager" + +[.villager_pollnivneach_6] +type = "villager" + +[.warrior_woman] +type = "warrior" + +[.watchman] +type = "watchman" + +[.woman] +type = "human" + +[.woman_2] +type = "human" + +[.woman_3] +type = "human" diff --git a/data/skill/thieving/thieving.enums.toml b/data/skill/thieving/thieving.enums.toml deleted file mode 100644 index b1390c0976..0000000000 --- a/data/skill/thieving/thieving.enums.toml +++ /dev/null @@ -1,275 +0,0 @@ -[pickpocket_type] -keyType = "npc" -valueType = "string" -defaultString = "null" -values = { - agnar_rellekka = "agnar_rellekka", - al_kharid_warrior = "warrior_woman", - bandit_bandit_camp = "bandit_bandit_camp", - bandit_bandit_camp_2 = "bandit_bandit_camp", - bandit_pollnivneach_2_2 = "bandit_pollnivneach_2_2", - bandit_pollnivneach_2_3 = "bandit_pollnivneach_2_2", - bandit_pollnivneach_3 = "bandit_pollnivneach_3", - bandit_pollnivneach_4 = "bandit_pollnivneach_3", - borrokar = "agnar_rellekka", - cave_goblin_dorgesh_kaan = "cave_goblin_dorgesh_kaan", - cave_goblin_dorgesh_kaan_10 = "cave_goblin_dorgesh_kaan", - cave_goblin_dorgesh_kaan_11 = "cave_goblin_dorgesh_kaan", - cave_goblin_dorgesh_kaan_12 = "cave_goblin_dorgesh_kaan", - cave_goblin_dorgesh_kaan_13 = "cave_goblin_dorgesh_kaan", - cave_goblin_dorgesh_kaan_16 = "cave_goblin_dorgesh_kaan", - cave_goblin_dorgesh_kaan_2 = "cave_goblin_dorgesh_kaan", - cave_goblin_dorgesh_kaan_3 = "cave_goblin_dorgesh_kaan", - cave_goblin_dorgesh_kaan_4 = "cave_goblin_dorgesh_kaan", - cave_goblin_dorgesh_kaan_5 = "cave_goblin_dorgesh_kaan", - cave_goblin_dorgesh_kaan_6 = "cave_goblin_dorgesh_kaan", - cave_goblin_dorgesh_kaan_7 = "cave_goblin_dorgesh_kaan", - cave_goblin_dorgesh_kaan_8 = "cave_goblin_dorgesh_kaan", - cave_goblin_dorgesh_kaan_9 = "cave_goblin_dorgesh_kaan", - desert_digsite_workman = "desert_digsite_workman", - digsite_workman_apron = "desert_digsite_workman", - digsite_workman_dirty = "desert_digsite_workman", - digsite_workman_dirty_2 = "desert_digsite_workman", - digsite_workman_long_hair = "desert_digsite_workman", - farmer = "farmer", - farmer_lumbridge = "farmer", - farmer_lumbridge_3 = "farmer", - freidir = "agnar_rellekka", - freygerd_rellekka = "agnar_rellekka", - gnome = "gnome", - gnome_2 = "gnome", - gnome_3 = "gnome", - gnome_child = "gnome", - gnome_child_2 = "gnome", - gnome_child_3 = "gnome", - gnome_woman = "gnome", - gnome_woman_2 = "gnome", - guard_ardougne = "guard_falador", - guard_edgeville = "guard_falador", - guard_edgeville_2 = "guard_falador", - guard_edgeville_3 = "guard_falador", - guard_edgeville_4 = "guard_falador", - guard_edgeville_6 = "guard_falador", - guard_edgeville_7 = "guard_falador", - guard_falador = "guard_falador", - guard_falador_2 = "guard_falador", - guard_falador_3 = "guard_falador", - guard_falador_4 = "guard_falador", - guard_falador_5 = "guard_falador", - guard_falador_6 = "guard_falador", - guard_falador_7 = "guard_falador", - guard_falador_8 = "guard_falador", - guard_ham_store_rooms = "guard_falador", - guard_ham_store_rooms_2 = "guard_falador", - guard_ham_store_rooms_3 = "guard_falador", - guard_ham_store_rooms_4 = "guard_falador", - guard_ham_store_rooms_5 = "guard_falador", - guard_varrock = "guard_falador", - guard_varrock_2 = "guard_falador", - ham_member_ham_cave = "ham_member_ham_cave", - ham_member_ham_cave_2 = "ham_member_ham_cave", - ham_member_ham_cave_3 = "ham_member_ham_cave", - hero = "hero", - inga = "agnar_rellekka", - knight_of_ardougne = "knight_of_ardougne", - lumbridge_man = "man", - lumbridge_man_2 = "man", - lumbridge_man_3 = "man", - lumbridge_man_4 = "man", - lumbridge_man_5 = "man", - lumbridge_man_6 = "man", - lumbridge_man_7 = "man", - lumbridge_woman = "man", - lumbridge_woman_2 = "man", - lumbridge_woman_3 = "man", - lumbridge_woman_4 = "man", - lumbridge_woman_5 = "man", - man = "man", - man_2 = "man", - man_3 = "man", - man_al_kharid = "man", - martin_the_master_gardener = "master_farmer", - master_farmer = "master_farmer", - master_farmer_varrock = "master_farmer", - menaphite_thug_pollnivneach_after_quest = "menaphite_thug_pollnivneach_after_quest", - paladin = "paladin", - paladin_2 = "paladin", - pontak_rellekka = "agnar_rellekka", - port_sarim_guard = "guard_falador", - port_sarim_guard_1 = "guard_falador", - port_sarim_guard_2 = "guard_falador", - port_sarim_guard_3 = "guard_falador", - port_sarim_guard_4 = "guard_falador", - rogue_castle = "rogue_castle", - sassilik_rellekka = "agnar_rellekka", - villager_pollnivneach_2_2 = "villager_pollnivneach_2_2", - villager_pollnivneach_2_3 = "villager_pollnivneach_2_2", - villager_pollnivneach_2_4 = "villager_pollnivneach_2_2", - villager_pollnivneach_3 = "villager_pollnivneach_2_2", - villager_pollnivneach_3_2 = "villager_pollnivneach_2_2", - villager_pollnivneach_3_3 = "villager_pollnivneach_2_2", - villager_pollnivneach_3_4 = "villager_pollnivneach_2_2", - villager_pollnivneach_4 = "villager_pollnivneach_2_2", - villager_pollnivneach_5 = "villager_pollnivneach_2_2", - villager_pollnivneach_6 = "villager_pollnivneach_2_2", - warrior_woman = "warrior_woman", - watchman = "watchman", - woman = "man", - woman_2 = "man", - woman_3 = "man", -} - -[pickpocket_level] -keyType = "npc" -valueType = "int" -defaultInt = 1 -values = { - agnar_rellekka = 45, - bandit_bandit_camp = 53, - bandit_pollnivneach_2_2 = 45, - bandit_pollnivneach_3 = 55, - cave_goblin_dorgesh_kaan = 36, - desert_digsite_workman = 25, - farmer = 10, - gnome = 75, - guard_falador = 40, - ham_member_ham_cave = 15, - hero = 80, - knight_of_ardougne = 55, - master_farmer = 38, - menaphite_thug_pollnivneach_after_quest = 65, - paladin = 70, - rogue_castle = 32, - villager_pollnivneach_2_2 = 30, - warrior_woman = 25, - watchman = 65, -} - -[pickpocket_xp] -keyType = "npc" -valueType = "int" -defaultInt = 0 -values = { - agnar_rellekka = 650, - bandit_bandit_camp = 794, - bandit_pollnivneach_2_2 = 650, - bandit_pollnivneach_3 = 843, - cave_goblin_dorgesh_kaan = 400, - desert_digsite_workman = 104, - farmer = 145, - gnome = 1335, - guard_falador = 468, - ham_member_ham_cave = 222, - hero = 1633, - knight_of_ardougne = 843, - man = 80, - master_farmer = 430, - menaphite_thug_pollnivneach_after_quest = 1375, - paladin = 1318, - rogue_castle = 365, - villager_pollnivneach_2_2 = 80, - warrior_woman = 260, - watchman = 1375, -} - -[pickpocket_stun_ticks] -keyType = "npc" -valueType = "int" -defaultInt = 1 -values = { - agnar_rellekka = 8, - cave_goblin_dorgesh_kaan = 8, - desert_digsite_workman = 8, - farmer = 8, - gnome = 8, - guard_falador = 8, - ham_member_ham_cave = 6, - hero = 10, - knight_of_ardougne = 10, - man = 8, - master_farmer = 8, - paladin = 8, - rogue_castle = 8, - warrior_woman = 8, - watchman = 8, -} - -[pickpocket_damage] -keyType = "npc" -valueType = "string" -defaultString = "0-0" -values = { - agnar_rellekka = "20-21", - bandit_bandit_camp = "0-1", - bandit_pollnivneach_2_2 = "0-1", - bandit_pollnivneach_3 = "0-1", - cave_goblin_dorgesh_kaan = "10-11", - desert_digsite_workman = "100-101", - farmer = "10-11", - gnome = "10-11", - guard_falador = "20-21", - ham_member_ham_cave = "10-31", - hero = "30-31", - knight_of_ardougne = "30-31", - man = "10-11", - master_farmer = "30-31", - menaphite_thug_pollnivneach_after_quest = "0-1", - paladin = "30-31", - rogue_castle = "20-21", - villager_pollnivneach_2_2 = "0-1", - warrior_woman = "20-21", - watchman = "30-31", -} - -[pickpocket_chance] -keyType = "npc" -valueType = "string" -defaultString = "1-1" -values = { - agnar_rellekka = "90-240", - bandit_bandit_camp = "255-255", - bandit_pollnivneach_2_2 = "255-255", - bandit_pollnivneach_3 = "255-255", - cave_goblin_dorgesh_kaan = "80-240", - desert_digsite_workman = "100-240", - farmer = "150-240", - gnome = "43-175", - guard_falador = "50-240", - ham_member_ham_cave = "135-239", - hero = "39-160", - knight_of_ardougne = "50-240", - man = "180-240", - master_farmer = "90-240", - menaphite_thug_pollnivneach_after_quest = "255-255", - paladin = "40-170", - rogue_castle = "75-240", - villager_pollnivneach_2_2 = "255-255", - warrior_woman = "100-240", - watchman = "15-160", -} - -[pickpocket_table] -keyType = "npc" -valueType = "string" -defaultString = "null" -values = { - agnar_rellekka = "fremmennik", - bandit_bandit_camp = "desert_bandit", - bandit_pollnivneach_2_2 = "bearded_bandit", - bandit_pollnivneach_3 = "bandit", - cave_goblin_dorgesh_kaan = "cave_goblin", - desert_digsite_workman = "workman", - farmer = "farmer", - gnome = "gnome", - guard_falador = "guard", - ham_member_ham_cave = "ham_member", - hero = "hero", - knight_of_ardougne = "knight", - master_farmer = "master_farmer", - menaphite_thug_pollnivneach_after_quest = "thug", - paladin = "paladin", - rogue_castle = "rouge", - villager_pollnivneach_2_2 = "villager", - warrior_woman = "warrior", - watchman = "watchman", -} \ No newline at end of file diff --git a/data/skill/thieving/thieving.tables.toml b/data/skill/thieving/thieving.tables.toml new file mode 100644 index 0000000000..c9136dfefd --- /dev/null +++ b/data/skill/thieving/thieving.tables.toml @@ -0,0 +1,160 @@ +[thieving_types] +level = "int" +xp = "int" +stun_ticks = "int" +chance = "range" +table = "string" +damage = "range" + +[.fremmennik] +level = 45 +xp = 650 +stun_ticks = 8 +chance = [90, 240] +damage = [20, 20] +table = "fremmennik" + +[.desert_bandit] +level = 53 +xp = 794 +chance = [255, 255] +damage = [10, 10] +table = "desert_bandit" + +[.bearded_bandit] +level = 45 +xp = 650 +chance = [255, 255] +damage = [10, 10] +table = "bearded_bandit" + +[.bandit] +level = 55 +xp = 843 +chance = [255, 255] +damage = [10, 10] +table = "bandit" + +[.cave_goblin] +level = 36 +xp = 400 +stun_ticks = 8 +chance = [80, 240] +damage = [10, 10] +table = "cave_goblin" + +[.workman] +level = 25 +xp = 104 +stun_ticks = 8 +chance = [100, 240] +damage = [10, 10] +table = "workman" + +[.farmer] +level = 10 +xp = 145 +stun_ticks = 8 +chance = [150, 240] +damage = [10, 10] +table = "farmer" + +[.gnome] +level = 75 +xp = 1335 +stun_ticks = 8 +chance = [43, 175] +damage = [10, 10] +table = "gnome" + +[.guard] +level = 40 +xp = 468 +stun_ticks = 8 +chance = [50, 240] +damage = [20, 20] +table = "guard" + +[.ham_member] +level = 15 +xp = 222 +stun_ticks = 6 +chance = [135, 239] +damage = [10, 30] +table = "ham_member" + +[.hero] +level = 80 +xp = 1633 +stun_ticks = 10 +chance = [39, 160] +table = "hero" + +[.knight] +level = 55 +xp = 843 +stun_ticks = 10 +chance = [50, 240] +damage = [30, 30] +table = "knight" + +[.human] +xp = 80 +stun_ticks = 8 +chance = [180, 240] +damage = [10, 10] +table = "man" + +[.master_farmer] +level = 38 +xp = 430 +stun_ticks = 8 +chance = [90, 240] +damage = [30, 30] +table = "master_farmer" + +[.thug] +level = 65 +xp = 1375 +chance = [255, 255] +damage = [50, 50] +table = "thug" + +[.paladin] +level = 70 +xp = 1318 +stun_ticks = 8 +chance = [40, 170] +damage = [30, 30] +table = "paladin" + +[.rouge] +level = 32 +xp = 365 +stun_ticks = 8 +chance = [75, 240] +damage = [20, 20] +table = "rouge" + +[.villager] +level = 30 +xp = 80 +chance = [255, 255] +damage = [10, 10] +table = "villager" + +[.warrior] +level = 25 +xp = 260 +stun_ticks = 8 +chance = [100, 240] +damage = [20, 20] +table = "warrior" + +[.watchman] +level = 65 +xp = 1375 +stun_ticks = 8 +chance = [15, 160] +damage = [30, 30] +table = "watchman" diff --git a/game/src/main/kotlin/content/skill/thieving/Pickpocketing.kt b/game/src/main/kotlin/content/skill/thieving/Pickpocketing.kt index 18a8593a96..67c68805e8 100644 --- a/game/src/main/kotlin/content/skill/thieving/Pickpocketing.kt +++ b/game/src/main/kotlin/content/skill/thieving/Pickpocketing.kt @@ -5,10 +5,10 @@ import content.entity.effect.stun import content.skill.slayer.categories import world.gregs.voidps.engine.Script import world.gregs.voidps.engine.client.message -import world.gregs.voidps.engine.client.ui.chat.toIntRange import world.gregs.voidps.engine.client.variable.hasClock import world.gregs.voidps.engine.data.definition.CombatDefinitions -import world.gregs.voidps.engine.data.definition.EnumDefinitions +import world.gregs.voidps.engine.data.definition.Rows +import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.character.npc.NPC import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.chat.ChatType @@ -52,17 +52,18 @@ class Pickpocketing(val combatDefinitions: CombatDefinitions, val dropTables: Dr message("You can't pickpocket during combat.") return } - val type = EnumDefinitions.stringOrNull("pickpocket_type", target.id) ?: return - val level = EnumDefinitions.int("pickpocket_level", type) + val type = Tables.stringOrNull("pickpocket.${target.id}.type") ?: return + val pickpocket = Rows.getOrNull("thieving_types.${target.id}") ?: return + val level = pickpocket.int("level") if (!has(Skill.Thieving, level)) { return } - var chances = EnumDefinitions.string("pickpocket_chance", type).toIntRange() + var chances = pickpocket.intRange("chance") if (equipped(EquipSlot.Hands).id == "gloves_of_silence" && equipment.discharge(this, EquipSlot.Hands.index)) { chances = (chances.first + (chances.first / 20)).coerceAtMost(255)..(chances.last + (chances.last / 20)).coerceAtMost(255) } val success = success(levels.get(Skill.Thieving), chances) - val table = EnumDefinitions.stringOrNull("pickpocket_table", type) + val table = pickpocket.string("table") val drops = getLoot(target, table) ?: emptyList() if (success && !canLoot(this, drops)) { return @@ -76,15 +77,15 @@ class Pickpocketing(val combatDefinitions: CombatDefinitions, val dropTables: Dr addLoot(drops) } message("You pick the $name's pocket.", ChatType.Filter) - val xp = EnumDefinitions.int("pickpocket_xp", type) / 10.0 + val xp = pickpocket.int("xp") / 10.0 exp(Skill.Thieving, xp) } else { target.face(this) target.say("What do you think you're doing?") target.anim(combatDefinitions.get(target["combat_def", target.id]).defendAnim) message("You fail to pick the $name's pocket.", ChatType.Filter) - val ticks = EnumDefinitions.int("pickpocket_stun_ticks", type) - val damage = EnumDefinitions.string("pickpocket_damage", type).toIntRange() + val ticks = pickpocket.int("stun_ticks") + val damage = pickpocket.intRange("damage") target.stun(this, ticks, damage.random(random)) delay(2) } From facbcc18ef7ab1e4aad6a70354206feac48d560f Mon Sep 17 00:00:00 2001 From: GregHib Date: Fri, 27 Mar 2026 13:32:42 +0000 Subject: [PATCH 25/40] Convert bar crawl enums --- .../quest/mini/bar_crawl/bar_crawl.enums.toml | 136 ------------------ .../mini/bar_crawl/bar_crawl.tables.toml | 122 ++++++++++++++++ .../AlfredGrimhandsBarCrawl.kt | 25 ++-- .../miniquest/AlfredGrimhandsBarCrawlTest.kt | 66 +++------ 4 files changed, 153 insertions(+), 196 deletions(-) delete mode 100644 data/quest/mini/bar_crawl/bar_crawl.enums.toml create mode 100644 data/quest/mini/bar_crawl/bar_crawl.tables.toml diff --git a/data/quest/mini/bar_crawl/bar_crawl.enums.toml b/data/quest/mini/bar_crawl/bar_crawl.enums.toml deleted file mode 100644 index d686947de1..0000000000 --- a/data/quest/mini/bar_crawl/bar_crawl.enums.toml +++ /dev/null @@ -1,136 +0,0 @@ -[bar_crawl_ids] -keyType = "npc" -valueType = "string" -values = { - barmaid_emily = "hand_of_death_cocktail", - barmaid_kaylee = "hand_of_death_cocktail", - barmaid_tina = "hand_of_death_cocktail", - bartender_rusty_anchor_inn = "black_skull_ale", - bartender_dead_mans_chest = "supergrog", - bartender_zambo = "ape_bite_liqueur", - bartender_jolly_boar_inn = "olde_suspiciouse", - bartender_blue_moon_inn = "uncle_humphreys_gutrot", - bartender_foresters_arms = "liverbane_ale", - bartender_flying_horse_inn = "heart_stopper", - bartender_dragon_inn = "fire_brandy", - blurberry = "fire_toad_blast", -} - -[bar_crawl_start] -keyType = "npc" -valueType = "int" -values = { - bartender_dead_mans_chest = "Fancy a bit of Heart Stopper then do you? It'll only be 8 coins.", - bartender_zambo = "Ah, you'll be wanting some Ape Bite Liqueur, then. It's got a lovely banana taste and it'll only cost you 7 coins.", - bartender_jolly_boar_inn = "Ah, there seems to be a fair few doing that one these days. My supply of Olde Suspiciouse is starting to run low, it'll cost you 10 coins.", - bartender_foresters_arms = "Oh you're a barbarian then. Now which of these barrels contained the Liverbane Ale? That'll be 18 coins please.", - bartender_flying_horse_inn = "Fancy a bit of Heart Stopper then do you? It'll only be 8 coins.", - bartender_dragon_inn = "I suppose you'll be wanting some Fire Brandy. That'll cost you 12 coins.", -} - -[bar_crawl_prices] -keyType = "npc" -valueType = "int" -values = { - barmaid_emily = 70, - barmaid_kaylee = 70, - barmaid_tina = 70, - bartender_rusty_anchor_inn = 8, - bartender_dead_mans_chest = 15, - bartender_zambo = 7, - bartender_jolly_boar_inn = 10, - bartender_blue_moon_inn = 50, - bartender_foresters_arms = 18, - bartender_flying_horse_inn = 8, - bartender_dragon_inn = 12, - blurberry = 10, -} - -[bar_crawl_insufficient] -keyType = "npc" -valueType = "string" -values = { - barmaid_emily = "I don't have that much money on me.", - barmaid_kaylee = "I don't have that much money on me.", - barmaid_tina = "I don't have that much money on me.", - bartender_rusty_anchor_inn = "I don't have 8 coins with me.", - bartender_dead_mans_chest = "Sorry I don't have 15 coins.", - bartender_zambo = "I don't have 7 coins with me.", - bartender_jolly_boar_inn = "I don't have 10 coins right now.", - bartender_blue_moon_inn = "Oh dear. I don't seem to have enough money.", - bartender_foresters_arms = "Sorry, I don't have 18 coins.", - bartender_flying_horse_inn = "Sorry, I don't have 8 coins.", - bartender_dragon_inn = "Sorry I don't have 12 coins.", - blurberry = "I don't have 10 coins right now.", -} - -[bar_crawl_give] -keyType = "npc" -valueType = "string" -values = { - barmaid_emily = "You buy a Hand of Death cocktail.", - barmaid_kaylee = "You buy a Hand of Death cocktail.", - barmaid_tina = "You buy a Hand of Death cocktail.", - bartender_rusty_anchor_inn = "You buy a Black Skull Ale.", - bartender_dead_mans_chest = "The bartender serves you a glass of strange thick dark liquid.", - bartender_zambo = "You buy some Ape Bite Liqueur.", - bartender_jolly_boar_inn = "You buy a pint of Olde Suspiciouse.", - bartender_blue_moon_inn = "You buy some Uncle Humphrey's Gutrot.", - bartender_foresters_arms = "The bartender gives you a glass of Liverbane Ale.", - bartender_flying_horse_inn = "The bartender hands you a shot of Heart Stopper.", - bartender_dragon_inn = "The bartender hands you a small glass and sets light to the contents.", - blurberry = "You buy a Fire Toad Blast.", -} - -[bar_crawl_drink] -keyType = "npc" -valueType = "string" -values = { - barmaid_emily = "You drink the cocktail.", - barmaid_kaylee = "You drink the cocktail.", - barmaid_tina = "You drink the cocktail.", - bartender_rusty_anchor_inn = "You drink your Black Skull Ale...", - bartender_dead_mans_chest = "You wince and drink it.", - bartender_zambo = "You swirl it around and swallow it.", - bartender_jolly_boar_inn = "You gulp it down.", - bartender_blue_moon_inn = "You drink the Uncle Humphrey's Gutrot.", - bartender_foresters_arms = "You gulp it down.", - bartender_flying_horse_inn = "You grimace and drink it.", - bartender_dragon_inn = "You blow out the flame and drink it.", - blurberry = "Your mouth and throat burn as you gulp it down.", -} - -[bar_crawl_effect] -keyType = "npc" -valueType = "string" -values = { - barmaid_emily = "You stumble around the room.", - barmaid_kaylee = "You stumble around the room.", - barmaid_tina = "You stumble around the room.", - bartender_rusty_anchor_inn = "Your vision blurs.", - bartender_dead_mans_chest = "You stagger backwards.", - bartender_zambo = "Zambo signs your card.", - bartender_jolly_boar_inn = "Your head is spinning.", - bartender_blue_moon_inn = "Your insides feel terrible.", - bartender_foresters_arms = "The room seems to be swaying.", - bartender_flying_horse_inn = "You clutch your chest.", - bartender_dragon_inn = "Your vision blurs and you stagger slightly.", - blurberry = "Blurberry signs your card.", -} - -[bar_crawl_sign] -keyType = "npc" -valueType = "string" -values = { - barmaid_emily = "The barmaid giggles and signs your card.", - barmaid_kaylee = "The barmaid giggles and signs your card.", - barmaid_tina = "The barmaid giggles and signs your card.", - bartender_rusty_anchor_inn = "The bartender signs your card.", - bartender_dead_mans_chest = "You think you see 2 bartenders signing 2 barcrawl cards.", - bartender_jolly_boar_inn = "The bartender signs your card.", - bartender_blue_moon_inn = "The bartender signs your card.", - bartender_foresters_arms = "The bartender scrawls his signature on your card.", - bartender_flying_horse_inn = "Through your tears you see the bartender...", - bartender_dragon_inn = "You can just about make out the bartender signing your barcrawl card.", -} - diff --git a/data/quest/mini/bar_crawl/bar_crawl.tables.toml b/data/quest/mini/bar_crawl/bar_crawl.tables.toml new file mode 100644 index 0000000000..8158fd578e --- /dev/null +++ b/data/quest/mini/bar_crawl/bar_crawl.tables.toml @@ -0,0 +1,122 @@ +[bar_crawl] +row_id = "npc" +id = "string" +price = "int" +insufficient = "string" +start = "string" +give = "string" +drink = "string" +effect = "string" +sign = "string" + +[.barmaid_emily] +id = "hand_of_death_cocktail" +price = 70 +insufficient = "I don't have that much money on me." +give = "You buy a Hand of Death cocktail." +drink = "You drink the cocktail." +effect = "You stumble around the room." +sign = "The barmaid giggles and signs your card." + +[.barmaid_kaylee] +id = "hand_of_death_cocktail" +price = 70 +insufficient = "I don't have that much money on me." +give = "You buy a Hand of Death cocktail." +drink = "You drink the cocktail." +effect = "You stumble around the room." +sign = "The barmaid giggles and signs your card." + +[.barmaid_tina] +id = "hand_of_death_cocktail" +price = 70 +insufficient = "I don't have that much money on me." +give = "You buy a Hand of Death cocktail." +drink = "You drink the cocktail." +effect = "You stumble around the room." +sign = "The barmaid giggles and signs your card." + +[.bartender_blue_moon_inn] +id = "uncle_humphreys_gutrot" +price = 50 +insufficient = "Oh dear. I don't seem to have enough money." +give = "You buy some Uncle Humphrey's Gutrot." +drink = "You drink the Uncle Humphrey's Gutrot." +effect = "Your insides feel terrible." +sign = "The bartender signs your card." + +[.bartender_dead_mans_chest] +id = "supergrog" +price = 15 +insufficient = "Sorry I don't have 15 coins." +start = "Fancy a bit of Heart Stopper then do you? It'll only be 8 coins." +give = "The bartender serves you a glass of strange thick dark liquid." +drink = "You wince and drink it." +effect = "You stagger backwards." +sign = "You think you see 2 bartenders signing 2 barcrawl cards." + +[.bartender_dragon_inn] +id = "fire_brandy" +price = 12 +insufficient = "Sorry I don't have 12 coins." +start = "I suppose you'll be wanting some Fire Brandy. That'll cost you 12 coins." +give = "The bartender hands you a small glass and sets light to the contents." +drink = "You blow out the flame and drink it." +effect = "Your vision blurs and you stagger slightly." +sign = "You can just about make out the bartender signing your barcrawl card." + +[.bartender_flying_horse_inn] +id = "heart_stopper" +price = 8 +insufficient = "Sorry, I don't have 8 coins." +start = "Fancy a bit of Heart Stopper then do you? It'll only be 8 coins." +give = "The bartender hands you a shot of Heart Stopper." +drink = "You grimace and drink it." +effect = "You clutch your chest." +sign = "Through your tears you see the bartender..." + +[.bartender_foresters_arms] +id = "liverbane_ale" +price = 18 +insufficient = "Sorry, I don't have 18 coins." +start = "Oh you're a barbarian then. Now which of these barrels contained the Liverbane Ale? That'll be 18 coins please." +give = "The bartender gives you a glass of Liverbane Ale." +drink = "You gulp it down." +effect = "The room seems to be swaying." +sign = "The bartender scrawls his signature on your card." + +[.bartender_jolly_boar_inn] +id = "olde_suspiciouse" +price = 10 +insufficient = "I don't have 10 coins right now." +start = "Ah, there seems to be a fair few doing that one these days. My supply of Olde Suspiciouse is starting to run low, it'll cost you 10 coins." +give = "You buy a pint of Olde Suspiciouse." +drink = "You gulp it down." +effect = "Your head is spinning." +sign = "The bartender signs your card." + +[.bartender_rusty_anchor_inn] +id = "black_skull_ale" +price = 8 +insufficient = "I don't have 8 coins with me." +give = "You buy a Black Skull Ale." +drink = "You drink your Black Skull Ale..." +effect = "Your vision blurs." +sign = "The bartender signs your card." + +[.bartender_zambo] +id = "ape_bite_liqueur" +price = 7 +insufficient = "I don't have 7 coins with me." +start = "Ah, you'll be wanting some Ape Bite Liqueur, then. It's got a lovely banana taste and it'll only cost you 7 coins." +give = "You buy some Ape Bite Liqueur." +drink = "You swirl it around and swallow it." +effect = "Zambo signs your card." + +[.blurberry] +id = "fire_toad_blast" +price = 10 +insufficient = "I don't have 10 coins right now." +give = "You buy a Fire Toad Blast." +drink = "Your mouth and throat burn as you gulp it down." +effect = "Blurberry signs your card." diff --git a/game/src/main/kotlin/content/quest/miniquest/alfred_grimhands_barcrawl/AlfredGrimhandsBarCrawl.kt b/game/src/main/kotlin/content/quest/miniquest/alfred_grimhands_barcrawl/AlfredGrimhandsBarCrawl.kt index 3ffa5d8ecd..964fb5b1a8 100644 --- a/game/src/main/kotlin/content/quest/miniquest/alfred_grimhands_barcrawl/AlfredGrimhandsBarCrawl.kt +++ b/game/src/main/kotlin/content/quest/miniquest/alfred_grimhands_barcrawl/AlfredGrimhandsBarCrawl.kt @@ -10,7 +10,8 @@ import world.gregs.voidps.engine.Script import world.gregs.voidps.engine.client.message import world.gregs.voidps.engine.client.ui.chat.Colours import world.gregs.voidps.engine.client.ui.chat.toTag -import world.gregs.voidps.engine.data.definition.EnumDefinitions +import world.gregs.voidps.engine.data.definition.Rows +import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.character.npc.NPC import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.inv.inventory @@ -22,27 +23,25 @@ suspend fun Player.barCrawlDrink( effects: suspend Player.() -> Unit = {}, ) { player("I'm doing Alfred Grimhand's Barcrawl.") - val npcId = target.def.id - start?.invoke(this) ?: npc(EnumDefinitions.get("bar_crawl_start").string(npcId)) - val id = EnumDefinitions.get("bar_crawl_ids").string(npcId) - val price = EnumDefinitions.get("bar_crawl_prices").int(npcId) - if (!inventory.remove("coins", price)) { - player(EnumDefinitions.get("bar_crawl_insufficient").string(npcId)) + val bar = Rows.getOrNull("bar_crawl.${target.id}") ?: return + start?.invoke(this) ?: npc(bar.string("start")) + if (!inventory.remove("coins", bar.int("price"))) { + player(bar.string("insufficient")) return } - message(EnumDefinitions.get("bar_crawl_give").string(npcId)) + message(bar.string("give")) delay(4) - message(EnumDefinitions.get("bar_crawl_drink").string(npcId)) + message(bar.string("drink")) delay(4) - message(EnumDefinitions.get("bar_crawl_effect").string(npcId)) + message(bar.string("effect")) delay(4) - EnumDefinitions.get("bar_crawl_sign").stringOrNull(npcId)?.let { message(it) } - addVarbit("barcrawl_signatures", id) + bar.stringOrNull("sign")?.let { message(it) } + addVarbit("barcrawl_signatures", bar.string("id")) effects() } val onBarCrawl: Player.(NPC) -> Boolean = filter@{ target -> - val id = EnumDefinitions.get("bar_crawl_ids").stringOrNull(target.def.id) ?: return@filter false + val id = Tables.stringOrNull("bar_crawl.${target.id}.id") ?: return@filter false quest("alfred_grimhands_barcrawl") == "signatures" && !containsVarbit("barcrawl_signatures", id) } diff --git a/game/src/test/kotlin/content/quest/miniquest/AlfredGrimhandsBarCrawlTest.kt b/game/src/test/kotlin/content/quest/miniquest/AlfredGrimhandsBarCrawlTest.kt index 636b4b9bbf..5cfb70989a 100644 --- a/game/src/test/kotlin/content/quest/miniquest/AlfredGrimhandsBarCrawlTest.kt +++ b/game/src/test/kotlin/content/quest/miniquest/AlfredGrimhandsBarCrawlTest.kt @@ -1,6 +1,7 @@ package content.quest.miniquest import WorldTest +import dialogueContinue import dialogueOption import npcOption import objectOption @@ -36,12 +37,9 @@ internal class AlfredGrimhandsBarCrawlTest : WorldTest() { tickIf { player.dialogue == null } player.dialogueOption("continue") player.dialogueOption("line1") // I want to come through this gate - player.dialogueOption("continue") - player.dialogueOption("continue") + player.dialogueContinue(2) player.dialogueOption("line2") // Looks can be deceiving - player.dialogueOption("continue") - player.dialogueOption("continue") - player.dialogueOption("continue") + player.dialogueContinue(3) assertEquals("signatures", player["alfred_grimhands_barcrawl", "unstarted"]) assertTrue(player.inventory.contains("barcrawl_card")) assertTrue(player["barcrawl_signatures", emptyList()].isEmpty()) @@ -53,9 +51,7 @@ internal class AlfredGrimhandsBarCrawlTest : WorldTest() { tickIf { player.dialogue == null } player.dialogueOption("continue") player.dialogueOption("line3") // Doing bar crawl - player.dialogueOption("continue") - player.dialogueOption("continue") - player.dialogueOption("continue") + player.dialogueContinue(3) assertEquals(950, player.inventory.count("coins")) tick(12) assertTrue(player.containsVarbit("barcrawl_signatures", "uncle_humphreys_gutrot")) @@ -65,12 +61,9 @@ internal class AlfredGrimhandsBarCrawlTest : WorldTest() { bartender = findNpc(player, "blurberry") player.npcOption(bartender, 0) // Talk-to tick(2) - player.dialogueOption("continue") - player.dialogueOption("continue") - player.dialogueOption("continue") + player.dialogueContinue(3) player.dialogueOption("line2") // Doing bar crawl - player.dialogueOption("continue") - player.dialogueOption("continue") + player.dialogueContinue(2) assertEquals(940, player.inventory.count("coins")) tick(12) assertTrue(player.containsVarbit("barcrawl_signatures", "fire_toad_blast")) @@ -80,9 +73,7 @@ internal class AlfredGrimhandsBarCrawlTest : WorldTest() { bartender = findNpc(player, "blurberry") player.npcOption(bartender, 0) // Talk-to tickIf { player.dialogue == null } - player.dialogueOption("continue") - player.dialogueOption("continue") - player.dialogueOption("continue") + player.dialogueContinue(3) player.dialogueOption("line2") // Doing bar crawl player.dialogueOption("continue") assertEquals(940, player.inventory.count("coins")) @@ -94,9 +85,7 @@ internal class AlfredGrimhandsBarCrawlTest : WorldTest() { bartender = findNpc(player, "blurberry") player.npcOption(bartender, 0) // Talk-to tickIf { player.dialogue == null } - player.dialogueOption("continue") - player.dialogueOption("continue") - player.dialogueOption("continue") + player.dialogueContinue(3) player.dialogueOption("line2") // Doing bar crawl player.dialogueOption("continue") assertEquals(940, player.inventory.count("coins")) @@ -110,8 +99,7 @@ internal class AlfredGrimhandsBarCrawlTest : WorldTest() { tickIf { player.dialogue == null } player.dialogueOption("continue") player.dialogueOption("line4") // Doing bar crawl - player.dialogueOption("continue") - player.dialogueOption("continue") + player.dialogueContinue(2) assertEquals(925, player.inventory.count("coins")) tick(12) assertTrue(player.containsVarbit("barcrawl_signatures", "supergrog")) @@ -121,12 +109,9 @@ internal class AlfredGrimhandsBarCrawlTest : WorldTest() { bartender = findNpc(player, "bartender_dragon_inn") player.npcOption(bartender, 0) // Talk-to tickIf { player.dialogue == null } - player.dialogueOption("continue") - player.dialogueOption("continue") - player.dialogueOption("continue") + player.dialogueContinue(3) player.dialogueOption("line5") // Doing bar crawl - player.dialogueOption("continue") - player.dialogueOption("continue") + player.dialogueContinue(2) assertEquals(913, player.inventory.count("coins")) tick(12) assertTrue(player.containsVarbit("barcrawl_signatures", "fire_brandy")) @@ -136,12 +121,9 @@ internal class AlfredGrimhandsBarCrawlTest : WorldTest() { bartender = findNpc(player, "bartender_flying_horse_inn") player.npcOption(bartender, 0) // Talk-to tickIf { player.dialogue == null } - player.dialogueOption("continue") - player.dialogueOption("continue") - player.dialogueOption("continue") + player.dialogueContinue(3) player.dialogueOption("line3") // Doing bar crawl - player.dialogueOption("continue") - player.dialogueOption("continue") + player.dialogueContinue(2) assertEquals(905, player.inventory.count("coins")) tick(12) assertTrue(player.containsVarbit("barcrawl_signatures", "heart_stopper")) @@ -153,8 +135,7 @@ internal class AlfredGrimhandsBarCrawlTest : WorldTest() { tickIf { player.dialogue == null } player.dialogueOption("continue") player.dialogueOption("line3") // Doing bar crawl - player.dialogueOption("continue") - player.dialogueOption("continue") + player.dialogueContinue(2) assertEquals(887, player.inventory.count("coins")) tick(12) assertTrue(player.containsVarbit("barcrawl_signatures", "liverbane_ale")) @@ -166,8 +147,7 @@ internal class AlfredGrimhandsBarCrawlTest : WorldTest() { tickIf { player.dialogue == null } player.dialogueOption("continue") player.dialogueOption("line4") // Doing bar crawl - player.dialogueOption("continue") - player.dialogueOption("continue") + player.dialogueContinue(2) assertEquals(877, player.inventory.count("coins")) tick(12) player.dialogueOption("continue") @@ -180,8 +160,7 @@ internal class AlfredGrimhandsBarCrawlTest : WorldTest() { tickIf { player.dialogue == null } player.dialogueOption("continue") player.dialogueOption("line3") // Doing bar crawl - player.dialogueOption("continue") - player.dialogueOption("continue") + player.dialogueContinue(2) assertEquals(870, player.inventory.count("coins")) tick(12) assertTrue(player.containsVarbit("barcrawl_signatures", "ape_bite_liqueur")) @@ -193,9 +172,7 @@ internal class AlfredGrimhandsBarCrawlTest : WorldTest() { tickIf { player.dialogue == null } player.dialogueOption("continue") player.dialogueOption("line2") // Doing bar crawl - player.dialogueOption("continue") - player.dialogueOption("continue") - player.dialogueOption("continue") + player.dialogueContinue(3) assertEquals(800, player.inventory.count("coins")) tick(12) assertTrue(player.containsVarbit("barcrawl_signatures", "hand_of_death_cocktail")) @@ -206,10 +183,7 @@ internal class AlfredGrimhandsBarCrawlTest : WorldTest() { player.npcOption(bartender, 0) // Talk-to tickIf { player.dialogue == null } player.dialogueOption("line3") // Doing bar crawl - player.dialogueOption("continue") - player.dialogueOption("continue") - player.dialogueOption("continue") - player.dialogueOption("continue") + player.dialogueContinue(4) assertEquals(792, player.inventory.count("coins")) tick(12) assertTrue(player.containsVarbit("barcrawl_signatures", "black_skull_ale")) @@ -218,9 +192,7 @@ internal class AlfredGrimhandsBarCrawlTest : WorldTest() { player.tele(2542, 3569) player.npcOption(guard, 0) // Talk-to tickIf { player.dialogue == null } - player.dialogueOption("continue") - player.dialogueOption("continue") - player.dialogueOption("continue") + player.dialogueContinue(3) assertEquals("completed", player["alfred_grimhands_barcrawl", "unstarted"]) } From a885281ff99fd1da808f4ae889a78c4c28fcb147 Mon Sep 17 00:00:00 2001 From: GregHib Date: Fri, 27 Mar 2026 13:37:56 +0000 Subject: [PATCH 26/40] Convert pottery enums --- data/skill/crafting/pottery.enums.toml | 41 ------------- data/skill/crafting/pottery.tables.toml | 60 +++++++++++++++++++ .../kotlin/content/skill/crafting/Pottery.kt | 10 ++-- 3 files changed, 66 insertions(+), 45 deletions(-) delete mode 100644 data/skill/crafting/pottery.enums.toml create mode 100644 data/skill/crafting/pottery.tables.toml diff --git a/data/skill/crafting/pottery.enums.toml b/data/skill/crafting/pottery.enums.toml deleted file mode 100644 index 726531252c..0000000000 --- a/data/skill/crafting/pottery.enums.toml +++ /dev/null @@ -1,41 +0,0 @@ -[pottery_product] -keyType = "item" -valueType = "string" -defaultString = "" -values = { - unfired_pot_lid = "pot_lid", - soft_clay = "unfired_pot,unfired_pie_dish,unfired_bowl,unfired_plant_pot,unfired_pot_lid", - unfired_pot = "empty_pot", - unfired_pie_dish = "bowl", - unfired_bowl = "bowl", - unfired_plant_pot = "plant_pot_empty", -} - -[pottery_xp] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - pot_lid = 200, - unfired_pot = 63, - unfired_pie_dish = 150, - unfired_bowl = 180, - unfired_plant_pot = 200, - unfired_pot_lid = 200, - empty_pot = 63, - bowl = 150, - plant_pot_empty = 175, -} - -[pottery_level] -keyType = "item" -valueType = "int" -defaultInt = 1 -values = { - unfired_pie_dish = 7, - unfired_bowl = 8, - unfired_plant_pot = 19, - unfired_pot_lid = 25, - bowl = 8, - plant_pot_empty = 19, -} diff --git a/data/skill/crafting/pottery.tables.toml b/data/skill/crafting/pottery.tables.toml new file mode 100644 index 0000000000..4ea8f22b93 --- /dev/null +++ b/data/skill/crafting/pottery.tables.toml @@ -0,0 +1,60 @@ +[firing] +row_id = "item" +products = "list" + +[.unfired_pot_lid] +products = ["pot_lid"] + +[.soft_clay] +products = ["unfired_pot", "unfired_pie_dish", "unfired_bowl", "unfired_plant_pot", "unfired_pot_lid"] + +[.unfired_pot] +products = ["empty_pot"] + +[.unfired_pie_dish] +products = ["bowl"] + +[.unfired_bowl] +products = ["bowl"] + +[.unfired_plant_pot] +products = ["plant_pot_empty"] + +[pottery] +row_id = "item" +xp = "int" +level = "int" +level_default = 1 + +[.pot_lid] +xp = 200 + +[.unfired_pot] +xp = 63 + +[.unfired_pie_dish] +level = 7 +xp = 150 + +[.unfired_bowl] +level = 8 +xp = 180 + +[.unfired_plant_pot] +level = 19 +xp = 200 + +[.unfired_pot_lid] +level = 25 +xp = 200 + +[.empty_pot] +xp = 63 + +[.bowl] +level = 8 +xp = 150 + +[.plant_pot_empty] +level = 19 +xp = 175 diff --git a/game/src/main/kotlin/content/skill/crafting/Pottery.kt b/game/src/main/kotlin/content/skill/crafting/Pottery.kt index b66ba08fa3..9a20e8045e 100644 --- a/game/src/main/kotlin/content/skill/crafting/Pottery.kt +++ b/game/src/main/kotlin/content/skill/crafting/Pottery.kt @@ -4,7 +4,8 @@ import content.entity.player.dialogue.type.makeAmount import net.pearx.kasechange.toLowerSpaceCase import world.gregs.voidps.engine.Script import world.gregs.voidps.engine.client.message -import world.gregs.voidps.engine.data.definition.EnumDefinitions +import world.gregs.voidps.engine.data.definition.Rows +import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.skill.Skill import world.gregs.voidps.engine.entity.character.player.skill.exp.exp @@ -39,7 +40,7 @@ class Pottery : Script { } suspend fun Player.make(target: GameObject, animation: String, item: Item) { - val products = EnumDefinitions.stringOrNull("pottery_product", item.id)?.split(",") ?: return + val products = Tables.itemListOrNull("firing.${item.id}.products") ?: return val (id, amount) = makeAmount( items = products, type = "Make", @@ -67,7 +68,8 @@ class Pottery : Script { return } face(obj) - val level = EnumDefinitions.int("pottery_level", id) + val pottery = Rows.getOrNull("pottery.${id}") ?: return + val level = pottery.int("level") if (!has(Skill.Crafting, level)) { message("You need a Crafting level of $level to make a ${id.toLowerSpaceCase()}.") softTimers.stop("pottery") @@ -81,7 +83,7 @@ class Pottery : Script { return@weakQueue } player.sound("pottery") - val xp = EnumDefinitions.int("pottery_xp", id) / 10.0 + val xp = pottery.int("xp") / 10.0 exp(Skill.Crafting, xp) make(animation, obj, item, id, amount - 1) message("You make the clay into a ${id.toLowerSpaceCase()}.") From 1447b737613bdaf4349e51acb6971275c590c810 Mon Sep 17 00:00:00 2001 From: GregHib Date: Fri, 27 Mar 2026 14:30:18 +0000 Subject: [PATCH 27/40] Add row support for skill type --- .../voidps/engine/data/config/RowDefinition.kt | 4 ++++ .../engine/data/definition/ColumnReader.kt | 3 +++ .../voidps/engine/data/definition/Tables.kt | 18 ++++++++++++++++++ .../entity/character/player/skill/Skill.kt | 1 + 4 files changed, 26 insertions(+) diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt index 932db0cbca..4430c22b50 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/config/RowDefinition.kt @@ -19,6 +19,10 @@ data class RowDefinition( fun int(column: String) = Tables.int("${stringId}.$column") + fun skillPair(column: String) = Tables.skillPair("${stringId}.$column") + + fun skillPairOrNull(column: String) = Tables.skillPairOrNull("${stringId}.$column") + fun intList(column: String) = Tables.intList("${stringId}.$column") fun intListOrNull(column: String) = Tables.intListOrNull("${stringId}.$column") diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnReader.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnReader.kt index e6f3e73c3b..941e7fd980 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnReader.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnReader.kt @@ -1,6 +1,8 @@ package world.gregs.voidps.engine.data.definition +import net.pearx.kasechange.toSentenceCase import world.gregs.config.ConfigReader +import world.gregs.voidps.engine.entity.character.player.skill.Skill sealed interface ColumnReader { val type: ColumnType @@ -90,6 +92,7 @@ sealed interface ColumnReader { "int" -> ReaderInt "range" -> ReaderIntRange "string" -> ReaderString + "skill" -> ReaderEntity(Skill.map) "npc" -> ReaderEntity(NPCDefinitions.ids) "item" -> ReaderEntity(ItemDefinitions.ids) "obj" -> ReaderEntity(ObjectDefinitions.ids) diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt index a7a11b086c..c805ac25a2 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt @@ -5,6 +5,7 @@ import world.gregs.config.Config import world.gregs.config.ConfigReader import world.gregs.voidps.engine.data.config.RowDefinition import world.gregs.voidps.engine.data.config.TableDefinition +import world.gregs.voidps.engine.entity.character.player.skill.Skill import world.gregs.voidps.engine.timedLoad import kotlin.collections.set import kotlin.math.exp @@ -80,6 +81,13 @@ object Tables { return npc.stringId } + fun skill(path: String): Skill = Skill.all[get(path, ColumnType.ColumnEntity)] + + fun skillOrNull(path: String): Skill? { + val id = getOrNull(path, ColumnType.ColumnEntity) ?: return null + return Skill.all[id] + } + fun row(path: String): Array = Rows.get(get(path, ColumnType.ColumnInt)).data fun rowOrNull(path: String): Array? { @@ -127,6 +135,16 @@ object Tables { return Pair(first, second) } + fun skillPair(path: String): Pair { + val (id, level) = get(path, ColumnType.IntIntPair) + return Pair(Skill.all[id], level) + } + + fun skillPairOrNull(path: String): Pair? { + val (id, level) = getOrNull(path, ColumnType.IntIntPair) ?: return null + return Pair(Skill.all[id], level) + } + fun intPair(path: String): Pair = get(path, ColumnType.IntIntPair) fun intPairOrNull(path: String): Pair? = getOrNull(path, ColumnType.IntIntPair) diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/player/skill/Skill.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/player/skill/Skill.kt index 5afd85eb8b..5bd89ea379 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/player/skill/Skill.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/player/skill/Skill.kt @@ -38,6 +38,7 @@ enum class Skill { val all = entries.toTypedArray() val nonHealth = entries.filter { it != Constitution }.toTypedArray() val count = all.size + val map = all.mapIndexed { index, skill -> skill.name.lowercase() to index }.toMap() private val skills = mapOf( "Attack" to Attack, From 127f131365503408a92b94989eca46e58f37e58c Mon Sep 17 00:00:00 2001 From: GregHib Date: Fri, 27 Mar 2026 14:30:44 +0000 Subject: [PATCH 28/40] Convert wise old man enums --- .../wise_old_man/wise_old_man.enums.toml | 141 ---------- .../wise_old_man_items.tables.toml | 247 ++++++++++++++++++ .../wise_old_man_npcs.tables.toml | 36 +++ .../wise_old_man/WiseOldMan.kt | 138 ++-------- 4 files changed, 307 insertions(+), 255 deletions(-) delete mode 100644 data/area/misthalin/draynor/wise_old_man/wise_old_man.enums.toml create mode 100644 data/area/misthalin/draynor/wise_old_man/wise_old_man_items.tables.toml create mode 100644 data/area/misthalin/draynor/wise_old_man/wise_old_man_npcs.tables.toml diff --git a/data/area/misthalin/draynor/wise_old_man/wise_old_man.enums.toml b/data/area/misthalin/draynor/wise_old_man/wise_old_man.enums.toml deleted file mode 100644 index fc40cce3ca..0000000000 --- a/data/area/misthalin/draynor/wise_old_man/wise_old_man.enums.toml +++ /dev/null @@ -1,141 +0,0 @@ -[wise_old_man_items] -keyType = "item" -valueType = "string" -values = { - anchovies = "I could do with some freshly cooked anchovies for a salad I'm planning.", - beer_glass = "My glassware got damaged when I moved here, so I need some new beer glasses.", - bones = "My plans for today require some sets of bones, the normal-sized sort you get from goblins.", - bronze_arrow = "I'm short of ammunition, so I could do with some bronze arrows. That way I can shoot at goblins through my window.", - bronze_bar = "I need some bronze bars.", - bronze_dagger = "I need a few bronze daggers to keep the goblins at bay.", - bronze_hatchet = "The head fell off my hatchet when I was chopping wood last week, so I need some more bronze hachets.", - bronze_mace = "I'd like some maces made of bronze.", - bronze_med_helm = "I could do with some medium-sized helmets. I'd like bronze ones.", - bronze_spear = "I need some bronze spears.", - bronze_sword = "My weapons collection isn't all it used to be. Some short swords made of bronze would be much appreciated.", - beer = "Strange as it may seem, I want a lot of beer!", - cadava_berries = "I've found a use for cadava berries.", - cooked_chicken = "I'm running short of food, so I'd like some cooked chickens.", - cooked_meat = "I'm a bit hungry. I'd like some cooked meat, not chicken or any sort of bird. And definitely not camel or rabbit either!", - copper_ore = "I need a few lumps of copper ore.", - cowhide = "I'd like a few cowhides.", - egg = "I'm going to make an omelette, so I'll need some eggs.", - feather = "I need a handful of feathers to stick in my beard.", - grain = "I'd like a bit of grain.", - iron_bar = "I need some iron bars.", - iron_mace = "Some iron maces would be useful.", - iron_ore = "A few lumps of iron ore would be nice.", - soft_clay = "I'll need some clay that's been softened so I can craft it.", - leather_gloves = "It's a bit nippy in this house, and my hands are cold. I need some leather gloves.", - logs = "This house is a bit cold, so I could do with some normal logs to burn.", - molten_glass = "Some chunks of molten glass would be the ideal patch for my cracked window.", - raw_potato = "I need some potatoes, if you'd be so kind.", - raw_rat_meat = "I hear pet cats are getting popular these days. I'd like some raw rat in case I get one.", - rune_essence = "I'd like to study the rune essence that the wizards have been talking about recently, so I need a few pieces.", - shrimps = "I could do with some freshly cooked shrimps for a salad I'm planning.", - silk = "My undergarments are getting a bit worn out. I'll be needing some sheets of silk to patch them.", - leather = "I'll be needing a few pieces of soft leather.", - tin_ore = "I need a few lumps of tin ore.", - ball_of_wool = "I saw an interesting bed in Karamja called a 'hammock'. It seemed to be made out of string, and I'd like some balls of wool so I can make my own.", - bowstring = "My shortbow's string is getting a bit worn out, so could you fetch me some bow strings?", - bread = "I don't have a decent larder here, so I can't store food very well. Now I'm out of loaves of bread.", - bronze_arrowtips = "I need a few bronze arrowheads to complete some arrows I was making.", - bronze_knife = "I'd like some bronze knives to throw at goblins.", - bronze_warhammer = "Could you fetch me some big warhammers made of bronze?", - bronze_wire = "I need some lengths of bronze wire to repair something.", - headless_arrow = "I want to make some arrows, so I'll need some headless arrows that have the feathers attached.", - swamp_paste = "My roof is leaking, so I need some swamp paste to fix it.", - iron_arrowtips = "I need some iron arrowheads to put on the arrows I was making.", - iron_knife = "I could do with some iron throwing knives to keep the goblins away from my house.", - iron_warhammer = "I'd like some chunky iron warhammers.", - leather_cowl = "The hail can be very heavy here, so I'd like a few leather cowls.", - pot_of_flour = "I'm out of flour, so I could do with a few pots of that.", - unfired_pie_dish = "Strange as this may seem, I need some unfired pie dishes.", - unfired_pot = "Believe it or not, I need a few unfired clay pots.", - leather_boots = "My footwear is getting a bit worn out, so I need a few pairs of leather boots.", -} - -[wise_old_man_item_hints] -keyType = "item" -valueType = "string" -values = { - anchovies = "Use a small fishing net to get anchovies from the sea south of here. Then cook them on a fire or range.", - beer_glass = "If you get some seaweed and a bucket of sand, you'll be able to mix them at a furnace to make molten glass. Then use a glassblowing pipe to make beer glasses. Most of what you need can be found on Entrana.", - bones = "You'll find bones easily enough if you fight creatures.", - bronze_arrow = "You can make them by chopping a log into arrowshafts and adding feathers to them, then smithing a bronze bar into arrowheads to complete the arrows.", - bronze_bar = "Mine some copper ore and tin ore. The furnace in Lumbridge can smelt them into bars of bronze.", - bronze_dagger = "Try smelting some copper and tin ore to make bronze. Then hammer the bronze on an anvil to make daggers.", - bronze_hatchet = "Try smelting some copper and tin ore to make bronze. Then hammer the bronze on an anvil to make hatchets.", - bronze_mace = "Try smelting some copper and tin ore to make bronze. Then hammer the bronze on an anvil to make maces.", - bronze_med_helm = "Try smelting some copper and tin ore to make bronze. Then hammer the bronze on an anvil to make helmets.", - bronze_spear = "If you kill some of those pesky goblins, you're bound to get some bronze spears.", - bronze_sword = "Try smelting some copper and tin ore to make bronze. Then hammer the bronze on an anvil to make short swords.", - beer = "There's a pub not far from here that will sell you plenty of that. Go west to Port Sarim.", - cadava_berries = "Just look around the woods south-west of Varrock.", - cooked_chicken = "You could try killing some chickens, then cooking their meat.", - cooked_meat = "Just cook some beef, rat or bear.", - copper_ore = "It should be easy enough for you to mine some copper ore.", - cowhide = "If you slaughter some cows, you'll get cowhides easily enough.", - egg = "Eggs are usually found where chickens are farmed.", - feather = "The cheapest way to get feathers is to kill chickens.", - grain = "There's a field full of it north of here.", - iron_bar = "Mine some iron ore. The furnace in Lumbridge can smelt them into bars of iron.", - iron_mace = "Try smelting some iron. Then hammer the bronze on an anvil to make maces.", - iron_ore = "It should be easy enough for you to mine some iron ore.", - soft_clay = "If you mine some clay, you can use containers of water on it to soften it.", - leather_gloves = "If you get the tanner in Al Kharid to turn some cowhides into leather, you'll be able to sew the gloves yourself. Buy a needle & thread from the crafting shop in Al Kharid.", - logs = "I suggest you take a hatchet and chop down some standard trees.", - molten_glass = "Use a bucket of sand with some soda ash on a furnace.", - raw_potato = "There's a field of those north of Lumbridge.", - raw_rat_meat = "You should find some big rats south-east of here in the swamp.", - rune_essence = "Ask the Archmage in the tower south of here to teleport you to the Rune Essence mine. Then you can mine me some pieces.", - shrimps = "Use a small fishing net to get shrimps from the sea south of here. Then cook them on a fire or range.", - silk = "There's a man in Al Kharid who sells it very cheaply. If you ever take any to Ardougne you'll get a good profit.", - leather = "There's a tanner in Al Kharid who will turn cowhides into leather.", - tin_ore = "You shouldn't have any trouble mining tin ore.", - ball_of_wool = "You can buy shears from the general store east of here. Shear some sheep, then spin the wool into balls on the spinning wheel in Lumbridge Castle.", - bowstring = "If you pick some flax, you can use the spinning wheel in Lumbridge Castle to spin it into bowstrings.", - bread = "Mix some flour and water to make bread dough, then bake it on a cooking range.", - bronze_arrowtips = "Try smelting some copper and tin ore to make bronze. Then hammer the bronze on an anvil to make arrowtips.", - bronze_knife = "Try smelting some copper and tin ore to make bronze. Then hammer the bronze on an anvil to make knives.", - bronze_warhammer = "Try smelting some copper and tin ore to make bronze. Then hammer the bronze on an anvil to make warhammers.", - bronze_wire = "Try smelting some copper and tin ore to make bronze. Then hammer the bronze on an anvil to make wire.", - headless_arrow = "Use a knife to chop some logs into arrowshafts. Then add a feather to each arrowshaft.", - swamp_paste = "Swamp tar is found south-east of here. Add it to a pot of flour and cook it on an open fire to make the paste.", - iron_arrowtips = "Try smelting some iron. Then hammer the bronze on an anvil to make arrowtips.", - iron_knife = "Try smelting some iron. Then hammer the bronze on an anvil to make knives.", - iron_warhammer = "Try smelting some iron. Then hammer the bronze on an anvil to make warhammers.", - leather_cowl = "If you get the tanner in Al Kharid to turn some cowhides into leather, you'll be able to make the cowls yourself. Buy needles & thread from the crafting shop in Al Kharid if you need any.", - pot_of_flour = "There's a windmill north of here. You can use it to grind grain into flour. Then use an empty pot to collect the flour.", - unfired_pie_dish = "Mine some clay. Then use a container full of water to soften it. In the Barbarian Village you'll be able to form this into pie dishes. Just don't bake them.", - unfired_pot = "Mine some clay. Then use a container full of water to soften it. In the Barbarian Village you'll be able to form this into pots. Just don't bake them.", - leather_boots = "If you get the tanner in Al Kharid to turn some cowhides into leather, you'll be able to make the boots yourself. Buy needles & thread from the crafting shop in Al Kharid if you need any.", -} - -[wise_old_man_npcs] -keyType = "npc" -valueType = "string" -values = { - father_aereck = "Father Aereck in Lumbridge is sure to reward you if you take a note to him for me.", - high_priest_entrana = "Could you please take a message to the High Priest of Entrana for me?", - reldo = "Reldo, the librarian in Varrock Palace, wrote to me recently about something. I need you to take my reply to him.", - thurgo = "Thurgo the dwarf is from an ancient tribe. I've found some of its history that he was asking about, and I need you to deliver the information to him.", - father_lawrence = "I hear my old friend Fr Lawrence in Varrock is drinking a bit too much. I'd like to get a letter to him about it.", - abbot_langley = "I've written a letter to my old friend Abbot Langley that I'd like you to deliver.", - oracle = "I'd like to get a note up to the Oracle on Ice Mountain.", - thing_under_the_bed = "Well, this is rather embarrassing, but I think there's some kind of monster in my house. Could you go upstairs and get rid of it, please?" -} - -[wise_old_man_npc_hints] -keyType = "npc" -valueType = "string" -values = { - father_aereck = "Just head eastwards to Lumbridge. He'll be in the church.", - high_priest_entrana = "There are some monks in Port Sarim, west of here, who will take you there so long as you're not carrying any weapons or armour.", - reldo = "The library is on the ground floor of the Palace in Varrock.", - thurgo = "Go west to Port Sarim, then southwards to some cliffs. He lives on the beach there.", - father_lawrence = "Varrock is a fairly long way north-east of here. The church is at the eastern side of the town, near the Palace.", - abbot_langley = "Walk northwards, past Draynor Manor. When you reach the Barbarian Village, go north-west until you find his Monastery. He'll be downstairs.", - oracle = "Walk northwards, past Draynor Manor. When you reach the Barbarian Village, go north-west until you see the Ice Mountain. It'll be at the top.", - thing_under_the_bed = "I think it's somewhere upstairs. It kept me awake all last night.", -} \ No newline at end of file diff --git a/data/area/misthalin/draynor/wise_old_man/wise_old_man_items.tables.toml b/data/area/misthalin/draynor/wise_old_man/wise_old_man_items.tables.toml new file mode 100644 index 0000000000..a72e5a265f --- /dev/null +++ b/data/area/misthalin/draynor/wise_old_man/wise_old_man_items.tables.toml @@ -0,0 +1,247 @@ +[wise_old_man_items] +row_id = "item" +intro = "string" +hint = "string" +quest = "string" +hard = "boolean" +skill_req = "pair" + +[.anchovies] +skill_req = ["fishing", 15] +intro = "I could do with some freshly cooked anchovies for a salad I'm planning." +hint = "Use a small fishing net to get anchovies from the sea south of here. Then cook them on a fire or range." + +[.beer_glass] +intro = "My glassware got damaged when I moved here, so I need some new beer glasses." +hint = "If you get some seaweed and a bucket of sand, you'll be able to mix them at a furnace to make molten glass. Then use a glassblowing pipe to make beer glasses. Most of what you need can be found on Entrana." + +[.bones] +intro = "My plans for today require some sets of bones, the normal-sized sort you get from goblins." +hint = "You'll find bones easily enough if you fight creatures." + +[.bronze_arrow] +intro = "I'm short of ammunition, so I could do with some bronze arrows. That way I can shoot at goblins through my window." +hint = "You can make them by chopping a log into arrowshafts and adding feathers to them, then smithing a bronze bar into arrowheads to complete the arrows." + +[.bronze_bar] +intro = "I need some bronze bars." +hint = "Mine some copper ore and tin ore. The furnace in Lumbridge can smelt them into bars of bronze." + +[.bronze_dagger] +intro = "I need a few bronze daggers to keep the goblins at bay." +hint = "Try smelting some copper and tin ore to make bronze. Then hammer the bronze on an anvil to make daggers." + +[.bronze_hatchet] +intro = "The head fell off my hatchet when I was chopping wood last week, so I need some more bronze hachets." +hint = "Try smelting some copper and tin ore to make bronze. Then hammer the bronze on an anvil to make hatchets." + +[.bronze_mace] +skill_req = ["smithing", 2] +intro = "I'd like some maces made of bronze." +hint = "Try smelting some copper and tin ore to make bronze. Then hammer the bronze on an anvil to make maces." + +[.bronze_med_helm] +skill_req = ["smithing", 3] +intro = "I could do with some medium-sized helmets. I'd like bronze ones." +hint = "Try smelting some copper and tin ore to make bronze. Then hammer the bronze on an anvil to make helmets." + +[.bronze_spear] +skill_req = ["smithing", 5] +intro = "I need some bronze spears." +hint = "If you kill some of those pesky goblins, you're bound to get some bronze spears." + +[.bronze_sword] +skill_req = ["smithing", 5] +intro = "My weapons collection isn't all it used to be. Some short swords made of bronze would be much appreciated." +hint = "Try smelting some copper and tin ore to make bronze. Then hammer the bronze on an anvil to make short swords." + +[.beer] +intro = "Strange as it may seem, I want a lot of beer!" +hint = "There's a pub not far from here that will sell you plenty of that. Go west to Port Sarim." + +[.cadava_berries] +intro = "I've found a use for cadava berries." +hint = "Just look around the woods south-west of Varrock." + +[.cooked_chicken] +intro = "I'm running short of food, so I'd like some cooked chickens." +hint = "You could try killing some chickens, then cooking their meat." + +[.cooked_meat] +intro = "I'm a bit hungry. I'd like some cooked meat, not chicken or any sort of bird. And definitely not camel or rabbit either!" +hint = "Just cook some beef, rat or bear." + +[.copper_ore] +intro = "I need a few lumps of copper ore." +hint = "It should be easy enough for you to mine some copper ore." + +[.cowhide] +intro = "I'd like a few cowhides." +hint = "If you slaughter some cows, you'll get cowhides easily enough." + +[.egg] +intro = "I'm going to make an omelette, so I'll need some eggs." +hint = "Eggs are usually found where chickens are farmed." + +[.feather] +intro = "I need a handful of feathers to stick in my beard." +hint = "The cheapest way to get feathers is to kill chickens." + +[.grain] +intro = "I'd like a bit of grain." +hint = "There's a field full of it north of here." + +[.iron_bar] +skill_req = ["smithing", 15] +intro = "I need some iron bars." +hint = "Mine some iron ore. The furnace in Lumbridge can smelt them into bars of iron." + +[.iron_mace] +skill_req = ["smithing", 17] +intro = "Some iron maces would be useful." +hint = "Try smelting some iron. Then hammer the bronze on an anvil to make maces." + +[.iron_ore] +skill_req = ["mining", 17] +intro = "A few lumps of iron ore would be nice." +hint = "It should be easy enough for you to mine some iron ore." + +[.soft_clay] +intro = "I'll need some clay that's been softened so I can craft it." +hint = "If you mine some clay, you can use containers of water on it to soften it." + +[.leather_gloves] +intro = "It's a bit nippy in this house, and my hands are cold. I need some leather gloves." +hint = "If you get the tanner in Al Kharid to turn some cowhides into leather, you'll be able to sew the gloves yourself. Buy a needle & thread from the crafting shop in Al Kharid." + +[.logs] +intro = "This house is a bit cold, so I could do with some normal logs to burn." +hint = "I suggest you take a hatchet and chop down some standard trees." + +[.molten_glass] +intro = "Some chunks of molten glass would be the ideal patch for my cracked window." +hint = "Use a bucket of sand with some soda ash on a furnace." + +[.raw_potato] +intro = "I need some potatoes, if you'd be so kind." +hint = "There's a field of those north of Lumbridge." + +[.raw_rat_meat] +intro = "I hear pet cats are getting popular these days. I'd like some raw rat in case I get one." +hint = "You should find some big rats south-east of here in the swamp." + +[.rune_essence] +quest = "rune_mysteries" +intro = "I'd like to study the rune essence that the wizards have been talking about recently, so I need a few pieces." +hint = "Ask the Archmage in the tower south of here to teleport you to the Rune Essence mine. Then you can mine me some pieces." + +[.shrimps] +intro = "I could do with some freshly cooked shrimps for a salad I'm planning." +hint = "Use a small fishing net to get shrimps from the sea south of here. Then cook them on a fire or range." + +[.silk] +intro = "My undergarments are getting a bit worn out. I'll be needing some sheets of silk to patch them." +hint = "There's a man in Al Kharid who sells it very cheaply. If you ever take any to Ardougne you'll get a good profit." + +[.leather] +intro = "I'll be needing a few pieces of soft leather." +hint = "There's a tanner in Al Kharid who will turn cowhides into leather." + +[.tin_ore] +intro = "I need a few lumps of tin ore." +hint = "You shouldn't have any trouble mining tin ore." + +[.ball_of_wool] +hard = true +intro = "I saw an interesting bed in Karamja called a 'hammock'. It seemed to be made out of string, and I'd like some balls of wool so I can make my own." +hint = "You can buy shears from the general store east of here. Shear some sheep, then spin the wool into balls on the spinning wheel in Lumbridge Castle." + +[.bowstring] +hard = true +intro = "My shortbow's string is getting a bit worn out, so could you fetch me some bow strings?" +hint = "If you pick some flax, you can use the spinning wheel in Lumbridge Castle to spin it into bowstrings." + +[.bread] +hard = true +intro = "I don't have a decent larder here, so I can't store food very well. Now I'm out of loaves of bread." +hint = "Mix some flour and water to make bread dough, then bake it on a cooking range." + +[.bronze_arrowtips] +hard = true +skill_req = ["smithing", 5] +intro = "I need a few bronze arrowheads to complete some arrows I was making." +hint = "Try smelting some copper and tin ore to make bronze. Then hammer the bronze on an anvil to make arrowtips." + +[.bronze_knife] +hard = true +skill_req = ["smithing", 7] +intro = "I'd like some bronze knives to throw at goblins." +hint = "Try smelting some copper and tin ore to make bronze. Then hammer the bronze on an anvil to make knives." + +[.bronze_warhammer] +hard = true +skill_req = ["smithing", 9] +intro = "Could you fetch me some big warhammers made of bronze?" +hint = "Try smelting some copper and tin ore to make bronze. Then hammer the bronze on an anvil to make warhammers." + +[.bronze_wire] +hard = true +skill_req = ["smithing", 4] +intro = "I need some lengths of bronze wire to repair something." +hint = "Try smelting some copper and tin ore to make bronze. Then hammer the bronze on an anvil to make wire." + +[.headless_arrow] +hard = true +intro = "I want to make some arrows, so I'll need some headless arrows that have the feathers attached." +hint = "Use a knife to chop some logs into arrowshafts. Then add a feather to each arrowshaft." + +[.swamp_paste] +hard = true +intro = "My roof is leaking, so I need some swamp paste to fix it." +hint = "Swamp tar is found south-east of here. Add it to a pot of flour and cook it on an open fire to make the paste." + +[.iron_arrowtips] +hard = true +skill_req = ["smithing", 20] +intro = "I need some iron arrowheads to put on the arrows I was making." +hint = "Try smelting some iron. Then hammer the bronze on an anvil to make arrowtips." + +[.iron_knife] +hard = true +skill_req = ["smithing", 20] +intro = "I could do with some iron throwing knives to keep the goblins away from my house." +hint = "Try smelting some iron. Then hammer the bronze on an anvil to make knives." + +[.iron_warhammer] +hard = true +skill_req = ["smithing", 24] +intro = "I'd like some chunky iron warhammers." +hint = "Try smelting some iron. Then hammer the bronze on an anvil to make warhammers." + +[.leather_cowl] +hard = true +skill_req = ["crafting", 9] +intro = "The hail can be very heavy here, so I'd like a few leather cowls." +hint = "If you get the tanner in Al Kharid to turn some cowhides into leather, you'll be able to make the cowls yourself. Buy needles & thread from the crafting shop in Al Kharid if you need any." + +[.pot_of_flour] +hard = true +intro = "I'm out of flour, so I could do with a few pots of that." +hint = "There's a windmill north of here. You can use it to grind grain into flour. Then use an empty pot to collect the flour." + +[.unfired_pie_dish] +hard = true +skill_req = ["crafting", 7] +intro = "Strange as this may seem, I need some unfired pie dishes." +hint = "Mine some clay. Then use a container full of water to soften it. In the Barbarian Village you'll be able to form this into pie dishes. Just don't bake them." + +[.unfired_pot] +hard = true +intro = "Believe it or not, I need a few unfired clay pots." +hint = "Mine some clay. Then use a container full of water to soften it. In the Barbarian Village you'll be able to form this into pots. Just don't bake them." + +[.leather_boots] +hard = true +skill_req = ["crafting", 7] +intro = "My footwear is getting a bit worn out, so I need a few pairs of leather boots." +hint = "If you get the tanner in Al Kharid to turn some cowhides into leather, you'll be able to make the boots yourself. Buy needles & thread from the crafting shop in Al Kharid if you need any." diff --git a/data/area/misthalin/draynor/wise_old_man/wise_old_man_npcs.tables.toml b/data/area/misthalin/draynor/wise_old_man/wise_old_man_npcs.tables.toml new file mode 100644 index 0000000000..a7b79aae66 --- /dev/null +++ b/data/area/misthalin/draynor/wise_old_man/wise_old_man_npcs.tables.toml @@ -0,0 +1,36 @@ +[wise_old_man_npcs] +row_id = "npc" +intro = "string" +hint = "string" + +[.father_aereck] +intro = "Father Aereck in Lumbridge is sure to reward you if you take a note to him for me." +hint = "Just head eastwards to Lumbridge. He'll be in the church." + +[.high_priest_entrana] +intro = "Could you please take a message to the High Priest of Entrana for me?" +hint = "There are some monks in Port Sarim, west of here, who will take you there so long as you're not carrying any weapons or armour." + +[.reldo] +intro = "Reldo, the librarian in Varrock Palace, wrote to me recently about something. I need you to take my reply to him." +hint = "The library is on the ground floor of the Palace in Varrock." + +[.thurgo] +intro = "Thurgo the dwarf is from an ancient tribe. I've found some of its history that he was asking about, and I need you to deliver the information to him." +hint = "Go west to Port Sarim, then southwards to some cliffs. He lives on the beach there." + +[.father_lawrence] +intro = "I hear my old friend Fr Lawrence in Varrock is drinking a bit too much. I'd like to get a letter to him about it." +hint = "Varrock is a fairly long way north-east of here. The church is at the eastern side of the town, near the Palace." + +[.abbot_langley] +intro = "I've written a letter to my old friend Abbot Langley that I'd like you to deliver." +hint = "Walk northwards, past Draynor Manor. When you reach the Barbarian Village, go north-west until you find his Monastery. He'll be downstairs." + +[.oracle] +intro = "I'd like to get a note up to the Oracle on Ice Mountain." +hint = "Walk northwards, past Draynor Manor. When you reach the Barbarian Village, go north-west until you see the Ice Mountain. It'll be at the top." + +[.thing_under_the_bed] +intro = "Well, this is rather embarrassing, but I think there's some kind of monster in my house. Could you go upstairs and get rid of it, please?" +hint = "I think it's somewhere upstairs. It kept me awake all last night." diff --git a/game/src/main/kotlin/content/area/misthalin/draynor_village/wise_old_man/WiseOldMan.kt b/game/src/main/kotlin/content/area/misthalin/draynor_village/wise_old_man/WiseOldMan.kt index e78ba3f9cd..a2e7517a88 100644 --- a/game/src/main/kotlin/content/area/misthalin/draynor_village/wise_old_man/WiseOldMan.kt +++ b/game/src/main/kotlin/content/area/misthalin/draynor_village/wise_old_man/WiseOldMan.kt @@ -19,7 +19,7 @@ import content.entity.player.dialogue.type.player import content.quest.questCompleted import net.pearx.kasechange.toSentenceCase import world.gregs.voidps.engine.Script -import world.gregs.voidps.engine.data.definition.EnumDefinitions +import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.World import world.gregs.voidps.engine.entity.character.npc.NPC import world.gregs.voidps.engine.entity.character.player.Player @@ -92,7 +92,8 @@ class WiseOldMan : Script { clear("wise_old_man_remaining") clear("wise_old_man_task") inc("wise_old_man_tasks_completed") - when (val reward = OldMansMessage.reward(this, hard.contains(item))) { + + when (val reward = OldMansMessage.reward(this, Tables.bool("wise_old_man_items.${item}.hard"))) { "runes" -> { items("nature_rune", "water_rune", "The Wise Old Man gives you some runes.") npc("Thank you, thank you! Please take these runes as a sign of my gratitude.") @@ -402,8 +403,7 @@ class WiseOldMan : Script { suspend fun Player.checkTask() { val npc: String? = get("wise_old_man_npc") if (npc != null) { - val intro = EnumDefinitions.string("wise_old_man_npcs", npc) - npc(intro) + npc(Tables.string("wise_old_man_npcs.$npc.intro")) if (npc != "thing_under_the_bed" && !ownsItem("old_mans_message")) { npc("You seem to have mislaid my letter, so here's another copy.") if (!inventory.add("old_mans_message")) { @@ -415,8 +415,7 @@ class WiseOldMan : Script { } val item: String = get("wise_old_man_task") ?: return val remaining: Int = get("wise_old_man_remaining") ?: return - val intro = EnumDefinitions.string("wise_old_man_items", item) - npc("$intro I still need $remaining.") + npc("${Tables.string("wise_old_man_items.$item.intro")} I still need $remaining.") hintItem(item) } @@ -433,7 +432,7 @@ class WiseOldMan : Script { "oracle", "thing_under_the_bed", ).random(random) - val intro = EnumDefinitions.string("wise_old_man_npcs", npc) + val intro = Tables.string("wise_old_man_npcs.$npc.intro") npc(intro) set("wise_old_man_npc", npc) if (npc == "thing_under_the_bed") { @@ -452,7 +451,7 @@ class WiseOldMan : Script { val item = tasks().random(random) set("wise_old_man_task", item) set("wise_old_man_remaining", amount) - val intro = EnumDefinitions.string("wise_old_man_items", item) + val intro = Tables.string("wise_old_man_items.$item.intro") npc("$intro. Please bring me $amount.") hintItem(item) } @@ -460,7 +459,7 @@ class WiseOldMan : Script { private suspend fun Player.hintNpc(npc: String) { choice("What would you like to say?") { option("Where do I need to go?") { - npc(EnumDefinitions.string("wise_old_man_npc_hints", npc)) + npc(Tables.string("wise_old_man_npcs.$npc.hint")) player("Right, I'll see you later.") } option("Right, I'll see you later.") @@ -470,118 +469,29 @@ class WiseOldMan : Script { private suspend fun Player.hintItem(item: String) { choice("What would you like to say?") { option("Where can I get that?") { - npc(EnumDefinitions.string("wise_old_man_item_hints", item)) + npc(Tables.string("wise_old_man_items.$item.hint")) player("Right, I'll see you later.") } option("Right, I'll see you later.") } } - private val hard = setOf( - "ball_of_wool", - "bowstring", - "bread", - "bronze_arrowtips", - "bronze_knife", - "bronze_warhammer", - "bronze_wire", - "headless_arrow", - "swamp_paste", - "iron_arrowtips", - "iron_knife", - "iron_warhammer", - "leather_cowl", - "pot_of_flour", - "unfired_pie_dish", - "unfired_pot", - "leather_boots", - ) - private fun Player.tasks(): MutableSet { - val tasks = mutableSetOf( - "beer_glass", - "bones", - "bronze_arrow", - "bronze_bar", - "bronze_dagger", - "bronze_hatchet", - "beer", - "cadava_berries", - "cooked_chicken", - "cooked_meat", - "copper_ore", - "cowhide", - "egg", - "feather", - "grain", - "soft_clay", - "leather_gloves", - "logs", - "molten_glass", - "raw_potato", - "raw_rat_meat", - "shrimps", - "silk", - "leather", - "tin_ore", - "ball_of_wool", - "bowstring", - "bread", - "headless_arrow", - "swamp_paste", - "pot_of_flour", - "unfired_pot", - ) - if (has(Skill.Fishing, 15)) { - tasks.add("anchovies") - } - if (has(Skill.Smithing, 2)) { - tasks.add("bronze_mace") - } - if (has(Skill.Smithing, 3)) { - tasks.add("bronze_med_helm") - } - if (has(Skill.Smithing, 4)) { - tasks.add("bronze_wire") - } - if (has(Skill.Smithing, 5)) { - tasks.add("bronze_spear") - tasks.add("bronze_sword") - tasks.add("bronze_arrowtips") - } - if (has(Skill.Smithing, 7)) { - tasks.add("bronze_knife") - } - if (has(Skill.Smithing, 9)) { - tasks.add("bronze_warhammer") - } - if (has(Skill.Smithing, 15)) { - tasks.add("iron_bar") - } - if (has(Skill.Smithing, 17)) { - tasks.add("iron_mace") - } - if (has(Skill.Smithing, 20)) { - tasks.add("iron_arrowtips") - } - if (has(Skill.Smithing, 20)) { - tasks.add("iron_knife") - } - if (has(Skill.Smithing, 24)) { - tasks.add("iron_warhammer") - } - if (has(Skill.Mining, 17)) { - tasks.add("iron_ore") - } - if (has(Skill.Crafting, 7)) { - tasks.add("unfired_pie_dish") - tasks.add("leather_boots") - } - if (has(Skill.Crafting, 9)) { - tasks.add("leather_cowl") - } - if (questCompleted("rune_mysteries")) { - tasks.add("rune_essence") + val tasks = mutableSetOf() + for (row in Tables.get("wise_old_man_items").rows()) { + val quest = row.stringOrNull("quest") + if (quest != null && !questCompleted(quest)) { + continue + } + val requirement = row.skillPairOrNull("skill_req") + if (requirement == null) { + tasks.add(row.itemId) + continue + } + val (skill, level) = requirement + if (has(skill, level)) { + tasks.add(row.itemId) + } } return tasks } From ebe41bc880a1ac8648cb5f2fb975c330eb173f9f Mon Sep 17 00:00:00 2001 From: GregHib Date: Fri, 27 Mar 2026 14:41:13 +0000 Subject: [PATCH 29/40] Convert fletching enums --- data/skill/fletching/bolts.tables.toml | 37 +++++ data/skill/fletching/darts.tables.toml | 29 ++++ data/skill/fletching/fletching.enums.toml | 144 ------------------ data/skill/fletching/unf.tables.toml | 110 +++++++++++++ .../kotlin/content/skill/fletching/Bolts.kt | 9 +- .../kotlin/content/skill/fletching/Darts.kt | 9 +- .../skill/fletching/FletchUnfinished.kt | 23 ++- 7 files changed, 195 insertions(+), 166 deletions(-) create mode 100644 data/skill/fletching/bolts.tables.toml create mode 100644 data/skill/fletching/darts.tables.toml delete mode 100644 data/skill/fletching/fletching.enums.toml create mode 100644 data/skill/fletching/unf.tables.toml diff --git a/data/skill/fletching/bolts.tables.toml b/data/skill/fletching/bolts.tables.toml new file mode 100644 index 0000000000..29f268ac9c --- /dev/null +++ b/data/skill/fletching/bolts.tables.toml @@ -0,0 +1,37 @@ +[fletching_bolts] +row_id = "item" +level = "int" +level_default = 1 +xp = "int" + +[.bronze_bolts_unf] +level = 9 +xp = 5 + +[.blurite_bolts_unf] +level = 24 +xp = 10 + +[.iron_bolts_unf] +level = 39 +xp = 15 + +[.steel_bolts_unf] +level = 46 +xp = 35 + +[.mithril_bolts_unf] +level = 54 +xp = 50 + +[.adamant_bolts_unf] +level = 61 +xp = 70 + +[.rune_bolts_unf] +level = 69 +xp = 100 + +[.silver_bolts_unf] +level = 43 +xp = 25 diff --git a/data/skill/fletching/darts.tables.toml b/data/skill/fletching/darts.tables.toml new file mode 100644 index 0000000000..882266ab94 --- /dev/null +++ b/data/skill/fletching/darts.tables.toml @@ -0,0 +1,29 @@ +[fletching_darts] +row_id = "item" +level = "int" +level_default = 1 +xp = "int" + +[.iron_dart_tip] +level = 22 +xp = 18 + +[.steel_dart_tip] +level = 37 +xp = 38 + +[.mithril_dart_tip] +level = 52 +xp = 75 + +[.adamant_dart_tip] +level = 67 +xp = 112 + +[.rune_dart_tip] +level = 81 +xp = 150 + +[.dragon_dart_tip] +level = 95 +xp = 188 diff --git a/data/skill/fletching/fletching.enums.toml b/data/skill/fletching/fletching.enums.toml deleted file mode 100644 index e9878e126b..0000000000 --- a/data/skill/fletching/fletching.enums.toml +++ /dev/null @@ -1,144 +0,0 @@ -[bolt_fletching_level] -keyType = "item" -valueType = "int" -defaultInt = 1 -values = { - bronze_bolts_unf = 9, - blurite_bolts_unf = 24, - iron_bolts_unf = 39, - steel_bolts_unf = 46, - mithril_bolts_unf = 54, - adamant_bolts_unf = 61, - rune_bolts_unf = 69, - silver_bolts_unf = 43, -} - -[bolt_fletching_xp] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - bronze_bolts_unf = 5, - blurite_bolts_unf = 10, - iron_bolts_unf = 15, - steel_bolts_unf = 35, - mithril_bolts_unf = 50, - adamant_bolts_unf = 70, - rune_bolts_unf = 100, - silver_bolts_unf = 25, -} - -[dart_fletching_level] -keyType = "item" -valueType = "int" -defaultInt = 1 -values = { - iron_dart_tip = 22, - steel_dart_tip = 37, - mithril_dart_tip = 52, - adamant_dart_tip = 67, - rune_dart_tip = 81, - dragon_dart_tip = 95, -} - -[dart_fletching_xp] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - bronze_dart_tip = 18, - iron_dart_tip = 38, - steel_dart_tip = 75, - mithril_dart_tip = 112, - adamant_dart_tip = 150, - rune_dart_tip = 188, - dragon_dart_tip = 250, -} - -[unf_fletching_level] -keyType = "item" -valueType = "int" -defaultInt = 1 -values = { - longbow_u = 10, - shortbow_u = 5, - oak_shortbow_u = 20, - oak_longbow_u = 25, - willow_longbow_u = 40, - willow_shortbow_u = 35, - maple_longbow_u = 55, - maple_shortbow_u = 50, - yew_longbow_u = 70, - yew_shortbow_u = 65, - magic_longbow_u = 85, - magic_shortbow_u = 80, - wooden_stock = 9, - oak_stock = 24, - willow_stock = 39, - teak_stock = 46, - maple_stock = 54, - mahogany_stock = 61, - yew_stock = 69, -} - -[unf_fletching_xp] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - longbow_u = 100, - shortbow_u = 50, - arrow_shaft = 50, - oak_shortbow_u = 165, - oak_longbow_u = 250, - willow_longbow_u = 415, - willow_shortbow_u = 333, - maple_longbow_u = 583, - maple_shortbow_u = 500, - yew_longbow_u = 750, - yew_shortbow_u = 675, - magic_longbow_u = 915, - magic_shortbow_u = 833, - wooden_stock = 60, - oak_stock = 160, - willow_stock = 220, - teak_stock = 270, - maple_stock = 320, - mahogany_stock = 410, - yew_stock = 500, -} - -[unf_fletching_make_amount] -keyType = "item" -valueType = "int" -defaultInt = 1 -values = { - arrow_shaft = 15, -} - -[unf_fletching_tick] -keyType = "item" -valueType = "int" -defaultInt = -1 -values = { - longbow_u = 3, - shortbow_u = 3, - arrow_shaft = 2, - oak_shortbow_u = 3, - oak_longbow_u = 3, - willow_longbow_u = 3, - willow_shortbow_u = 3, - maple_longbow_u = 3, - maple_shortbow_u = 3, - yew_longbow_u = 3, - yew_shortbow_u = 3, - magic_longbow_u = 3, - magic_shortbow_u = 3, - wooden_stock = 3, - oak_stock = 3, - willow_stock = 3, - teak_stock = 3, - maple_stock = 3, - mahogany_stock = 3, - yew_stock = 3, -} \ No newline at end of file diff --git a/data/skill/fletching/unf.tables.toml b/data/skill/fletching/unf.tables.toml new file mode 100644 index 0000000000..78d55bad05 --- /dev/null +++ b/data/skill/fletching/unf.tables.toml @@ -0,0 +1,110 @@ +[fletching_unf] +row_id = "item" +level = "int" +level_default = 1 +xp = "int" +amount = "int" +amount_default = 1 +ticks = "int" +ticks_default = -1 + +[.longbow_u] +level = 10 +xp = 100 +ticks = 3 + +[.shortbow_u] +level = 5 +xp = 50 +ticks = 3 + +[.arrow_shaft] +level = 1 +xp = 50 +amount = 15 +ticks = 2 + +[.oak_shortbow_u] +level = 20 +xp = 165 +ticks = 3 + +[.oak_longbow_u] +level = 25 +xp = 250 +ticks = 3 + +[.willow_longbow_u] +level = 40 +xp = 415 +ticks = 3 + +[.willow_shortbow_u] +level = 35 +xp = 333 +ticks = 3 + +[.maple_longbow_u] +level = 55 +xp = 583 +ticks = 3 + +[.maple_shortbow_u] +level = 50 +xp = 500 +ticks = 3 + +[.yew_longbow_u] +level = 70 +xp = 750 +ticks = 3 + +[.yew_shortbow_u] +level = 65 +xp = 675 +ticks = 3 + +[.magic_longbow_u] +level = 85 +xp = 915 +ticks = 3 + +[.magic_shortbow_u] +level = 80 +xp = 833 +ticks = 3 + +[.wooden_stock] +level = 9 +xp = 60 +ticks = 3 + +[.oak_stock] +level = 24 +xp = 160 +ticks = 3 + +[.willow_stock] +level = 39 +xp = 220 +ticks = 3 + +[.teak_stock] +level = 46 +xp = 270 +ticks = 3 + +[.maple_stock] +level = 54 +xp = 320 +ticks = 3 + +[.mahogany_stock] +level = 61 +xp = 410 +ticks = 3 + +[.yew_stock] +level = 69 +xp = 500 +ticks = 3 diff --git a/game/src/main/kotlin/content/skill/fletching/Bolts.kt b/game/src/main/kotlin/content/skill/fletching/Bolts.kt index e370ed5adb..4f10df30af 100644 --- a/game/src/main/kotlin/content/skill/fletching/Bolts.kt +++ b/game/src/main/kotlin/content/skill/fletching/Bolts.kt @@ -2,7 +2,7 @@ package content.skill.fletching import world.gregs.voidps.engine.Script import world.gregs.voidps.engine.client.message -import world.gregs.voidps.engine.data.definition.EnumDefinitions +import world.gregs.voidps.engine.data.definition.Rows import world.gregs.voidps.engine.entity.character.player.chat.ChatType import world.gregs.voidps.engine.entity.character.player.skill.Skill import world.gregs.voidps.engine.entity.character.player.skill.exp.exp @@ -15,10 +15,9 @@ class Bolts : Script { init { itemOnItem("feather", "*_bolts_unf") { _, toItem -> - val xp = EnumDefinitions.intOrNull("bolt_fletching_xp", toItem.id) ?: return@itemOnItem - val level = EnumDefinitions.int("bolt_fletching_level", toItem.id) + val bolt = Rows.getOrNull("fletching_bolts.${toItem.id}") ?: return@itemOnItem - if (!has(Skill.Fletching, level, true)) { + if (!has(Skill.Fletching, bolt.int("level"), true)) { return@itemOnItem } @@ -43,7 +42,7 @@ class Bolts : Script { return@itemOnItem } - val totalExperience = (xp / 10.0) * actualAmount + val totalExperience = (bolt.int("xp") / 10.0) * actualAmount exp(Skill.Fletching, totalExperience) message("You fletch $actualAmount bolts.", ChatType.Game) } diff --git a/game/src/main/kotlin/content/skill/fletching/Darts.kt b/game/src/main/kotlin/content/skill/fletching/Darts.kt index 1ce8386e94..bf532a709d 100644 --- a/game/src/main/kotlin/content/skill/fletching/Darts.kt +++ b/game/src/main/kotlin/content/skill/fletching/Darts.kt @@ -2,7 +2,7 @@ package content.skill.fletching import world.gregs.voidps.engine.Script import world.gregs.voidps.engine.client.message -import world.gregs.voidps.engine.data.definition.EnumDefinitions +import world.gregs.voidps.engine.data.definition.Rows import world.gregs.voidps.engine.entity.character.player.chat.ChatType import world.gregs.voidps.engine.entity.character.player.skill.Skill import world.gregs.voidps.engine.entity.character.player.skill.exp.exp @@ -15,10 +15,9 @@ class Darts : Script { init { itemOnItem("feather", "*_dart_tip") { _, toItem -> - val xp = EnumDefinitions.intOrNull("dart_fletching_xp", toItem.id) ?: return@itemOnItem - val level = EnumDefinitions.int("dart_fletching_level", toItem.id) + val dart = Rows.getOrNull("fletching_darts.${toItem.id}") ?: return@itemOnItem - if (!has(Skill.Fletching, level, true)) { + if (!has(Skill.Fletching, dart.int("level"), true)) { return@itemOnItem } @@ -43,7 +42,7 @@ class Darts : Script { return@itemOnItem } - val totalExperience = (xp / 10.0) * actualAmount + val totalExperience = (dart.int("xp") / 10.0) * actualAmount exp(Skill.Fletching, totalExperience) message("You finish making $actualAmount darts.", ChatType.Game) } diff --git a/game/src/main/kotlin/content/skill/fletching/FletchUnfinished.kt b/game/src/main/kotlin/content/skill/fletching/FletchUnfinished.kt index e15fdcd766..863fa79c3a 100644 --- a/game/src/main/kotlin/content/skill/fletching/FletchUnfinished.kt +++ b/game/src/main/kotlin/content/skill/fletching/FletchUnfinished.kt @@ -4,7 +4,8 @@ import content.entity.player.dialogue.type.makeAmount import world.gregs.voidps.cache.definition.Params import world.gregs.voidps.engine.Script import world.gregs.voidps.engine.client.message -import world.gregs.voidps.engine.data.definition.EnumDefinitions +import world.gregs.voidps.engine.data.config.RowDefinition +import world.gregs.voidps.engine.data.definition.Rows import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.chat.ChatType import world.gregs.voidps.engine.entity.character.player.skill.Skill @@ -28,17 +29,16 @@ class FletchUnfinished : Script { maximum = 27, text = "What would you like to fletch?", ) - EnumDefinitions.intOrNull("unf_fletching_xp", selected) ?: return@weakQueue - val level = EnumDefinitions.int("unf_fletching_level", selected) - if (!has(Skill.Fletching, level, true)) { + val unf = Rows.getOrNull("fletching_unf.${toItem.id}") ?: return@weakQueue + if (!has(Skill.Fletching, unf.int("level"), true)) { return@weakQueue } - fletch(selected, toItem.id, amount) + fletch(selected, unf, toItem.id, amount) } } } - fun Player.fletch(addItem: String, removeItem: String, amount: Int) { + fun Player.fletch(addItem: String, unf: RowDefinition, removeItem: String, amount: Int) { if (amount <= 0) { return } @@ -47,9 +47,8 @@ class FletchUnfinished : Script { return } - val tick = EnumDefinitions.int("unf_fletching_tick", addItem) - weakQueue("fletching", tick) { - val makeAmount = EnumDefinitions.int("unf_fletching_make_amount", addItem) + weakQueue("fletching", unf.int("tick")) { + val makeAmount = unf.int("amount") val success = inventory.transaction { remove(removeItem) add(addItem, makeAmount) @@ -61,10 +60,10 @@ class FletchUnfinished : Script { val itemCreated = getFletched(addItem) message("You carefully cut the wood into $itemCreated.", ChatType.Game) - val xp = EnumDefinitions.int("unf_fletching_xp", addItem) - exp(Skill.Fletching, xp / 10.0) + val xp = unf.int("xp") / 10.0 + exp(Skill.Fletching, xp) anim("fletching_log") - fletch(addItem, removeItem, amount - 1) + fletch(addItem, unf, removeItem, amount - 1) } } From 059bb347b2cbd24747f8652a7446dc0e8fb3ae82 Mon Sep 17 00:00:00 2001 From: GregHib Date: Fri, 27 Mar 2026 14:49:03 +0000 Subject: [PATCH 30/40] Convert fletchables params --- .../gregs/voidps/cache/definition/Params.kt | 2 -- data/skill/firemaking/log.items.toml | 8 ------ data/skill/fletching/darts.tables.toml | 4 +++ data/skill/fletching/fletchables.tables.toml | 27 +++++++++++++++++++ .../skill/fletching/FletchUnfinished.kt | 8 +++--- 5 files changed, 35 insertions(+), 14 deletions(-) create mode 100644 data/skill/fletching/fletchables.tables.toml diff --git a/cache/src/main/kotlin/world/gregs/voidps/cache/definition/Params.kt b/cache/src/main/kotlin/world/gregs/voidps/cache/definition/Params.kt index 27624579b2..595ec75333 100644 --- a/cache/src/main/kotlin/world/gregs/voidps/cache/definition/Params.kt +++ b/cache/src/main/kotlin/world/gregs/voidps/cache/definition/Params.kt @@ -69,7 +69,6 @@ object Params { const val FARMING_PROTECT_AMOUNT = 5067 const val FARMING_PROTECT_ID = 5068 const val FARMING_XP = 5069 - const val FLETCHABLES = 5070 const val FLIGHT_TIME = 5071 const val FOOD = 5072 const val FOOD2 = 5073 @@ -400,7 +399,6 @@ object Params { "farming_protect_amount" -> FARMING_PROTECT_AMOUNT "farming_protect_id" -> FARMING_PROTECT_ID "farming_xp" -> FARMING_XP - "fletchables" -> FLETCHABLES "flight_time" -> FLIGHT_TIME "food" -> FOOD "food2" -> FOOD2 diff --git a/data/skill/firemaking/log.items.toml b/data/skill/firemaking/log.items.toml index b5d4724e94..b70d09b844 100644 --- a/data/skill/firemaking/log.items.toml +++ b/data/skill/firemaking/log.items.toml @@ -3,7 +3,6 @@ id = 1511 price = 30 limit = 25000 weight = 2.0 -fletchables = ["arrow_shaft", "shortbow_u", "longbow_u", "wooden_stock"] examine = "A number of wooden logs." kept = "Wilderness" @@ -15,7 +14,6 @@ id = 1513 price = 1323 limit = 25000 weight = 2.0 -fletchables = ["arrow_shaft", "magic_shortbow_u", "magic_longbow_u"] aka = ["magic_log"] farming_protect_id = "coconut" farming_protect_amount = 25 @@ -29,7 +27,6 @@ id = 1515 price = 410 limit = 25000 weight = 2.0 -fletchables = ["arrow_shaft", "yew_shortbow_u", "yew_longbow_u", "yew_stock"] aka = ["yew_log"] farming_protect_id = "cactus_spine" farming_protect_amount = 10 @@ -43,7 +40,6 @@ id = 1517 price = 51 limit = 25000 weight = 2.0 -fletchables = ["arrow_shaft", "maple_shortbow_u", "maple_longbow_u", "maple_stock"] aka = ["maple_log"] farming_protect_id = "oranges_5" examine = "Logs cut from a maple tree." @@ -56,7 +52,6 @@ id = 1519 price = 16 limit = 25000 weight = 2.0 -fletchables = ["arrow_shaft", "willow_shortbow_u", "willow_longbow_u", "willow_stock"] aka = ["willow_log"] farming_protect_id = "apples_5" examine = "Logs cut from a willow tree." @@ -69,7 +64,6 @@ id = 1521 price = 29 limit = 25000 weight = 2.0 -fletchables = ["arrow_shaft", "oak_shortbow_u", "oak_longbow_u", "oak_stock"] aka = ["oak_log"] kept = "Wilderness" farming_protect_id = "tomatoes_5" @@ -83,7 +77,6 @@ id = 6332 price = 512 limit = 25000 weight = 1.36 -fletchables = ["arrow_shaft", "mahogany_stock"] examine = "Some well-cut mahogany logs." [teak_logs] @@ -91,7 +84,6 @@ id = 6333 price = 88 limit = 25000 weight = 1.36 -fletchables = ["arrow_shaft", "teak_stock"] examine = "Some well-cut teak logs." [teak_logs_noted] diff --git a/data/skill/fletching/darts.tables.toml b/data/skill/fletching/darts.tables.toml index 882266ab94..9fa4f94d9f 100644 --- a/data/skill/fletching/darts.tables.toml +++ b/data/skill/fletching/darts.tables.toml @@ -4,6 +4,10 @@ level = "int" level_default = 1 xp = "int" +[.bronze_dart_tip] +level = 1 +xp = 18 + [.iron_dart_tip] level = 22 xp = 18 diff --git a/data/skill/fletching/fletchables.tables.toml b/data/skill/fletching/fletchables.tables.toml new file mode 100644 index 0000000000..91354dfb70 --- /dev/null +++ b/data/skill/fletching/fletchables.tables.toml @@ -0,0 +1,27 @@ +[fletchables] +row_id = "item" +products = "list" + +[.logs] +products = ["arrow_shaft", "shortbow_u", "longbow_u", "wooden_stock"] + +[.oak_logs] +products = ["arrow_shaft", "oak_shortbow_u", "oak_longbow_u", "oak_stock"] + +[.willow_logs] +products = ["arrow_shaft", "willow_shortbow_u", "willow_longbow_u", "willow_stock"] + +[.maple_logs] +products = ["arrow_shaft", "maple_shortbow_u", "maple_longbow_u", "maple_stock"] + +[.mahogany_logs] +products = ["arrow_shaft", "mahogany_stock"] + +[.teak_logs] +products = ["arrow_shaft", "teak_stock"] + +[.yew_logs] +products = ["arrow_shaft", "yew_shortbow_u", "yew_longbow_u", "yew_stock"] + +[.magic_logs] +products = ["arrow_shaft", "magic_shortbow_u", "magic_longbow_u"] diff --git a/game/src/main/kotlin/content/skill/fletching/FletchUnfinished.kt b/game/src/main/kotlin/content/skill/fletching/FletchUnfinished.kt index 863fa79c3a..6ebaa27a36 100644 --- a/game/src/main/kotlin/content/skill/fletching/FletchUnfinished.kt +++ b/game/src/main/kotlin/content/skill/fletching/FletchUnfinished.kt @@ -1,11 +1,11 @@ package content.skill.fletching import content.entity.player.dialogue.type.makeAmount -import world.gregs.voidps.cache.definition.Params import world.gregs.voidps.engine.Script import world.gregs.voidps.engine.client.message import world.gregs.voidps.engine.data.config.RowDefinition import world.gregs.voidps.engine.data.definition.Rows +import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.chat.ChatType import world.gregs.voidps.engine.entity.character.player.skill.Skill @@ -21,7 +21,7 @@ class FletchUnfinished : Script { init { @Suppress("UNCHECKED_CAST") itemOnItem("knife", "*logs*") { _, toItem -> - val displayItems = toItem.def.params?.get(Params.FLETCHABLES) as? List ?: return@itemOnItem + val displayItems = Tables.itemListOrNull("fletchables.${toItem.id}.products") ?: return@itemOnItem weakQueue("fletching_make_dialog") { val (selected, amount) = makeAmount( displayItems, @@ -29,7 +29,7 @@ class FletchUnfinished : Script { maximum = 27, text = "What would you like to fletch?", ) - val unf = Rows.getOrNull("fletching_unf.${toItem.id}") ?: return@weakQueue + val unf = Rows.getOrNull("fletching_unf.${selected}") ?: return@weakQueue if (!has(Skill.Fletching, unf.int("level"), true)) { return@weakQueue } @@ -47,7 +47,7 @@ class FletchUnfinished : Script { return } - weakQueue("fletching", unf.int("tick")) { + weakQueue("fletching", unf.int("ticks")) { val makeAmount = unf.int("amount") val success = inventory.transaction { remove(removeItem) From ff1fab3662d5c4eadd24dc80265006302afdf646 Mon Sep 17 00:00:00 2001 From: GregHib Date: Fri, 27 Mar 2026 14:51:03 +0000 Subject: [PATCH 31/40] Convert herb enums --- data/skill/herblore/herb_cleaning.enums.toml | 45 ------------- data/skill/herblore/herbs.tables.toml | 68 ++++++++++++++++++++ 2 files changed, 68 insertions(+), 45 deletions(-) delete mode 100644 data/skill/herblore/herb_cleaning.enums.toml create mode 100644 data/skill/herblore/herbs.tables.toml diff --git a/data/skill/herblore/herb_cleaning.enums.toml b/data/skill/herblore/herb_cleaning.enums.toml deleted file mode 100644 index 4958ba247b..0000000000 --- a/data/skill/herblore/herb_cleaning.enums.toml +++ /dev/null @@ -1,45 +0,0 @@ -[herb_cleaning_level] -keyType = "item" -valueType = "int" -defaultInt = 1 -values = { - grimy_guam = 1, - grimy_marrentill = 9, - grimy_tarromin = 5, - grimy_harralander = 20, - grimy_ranarr = 25, - grimy_irit = 40, - grimy_avantoe = 48, - grimy_kwuarm = 54, - grimy_cadantine = 65, - grimy_dwarf_weed = 70, - grimy_torstol = 75, - grimy_lantadyme = 67, - grimy_toadflax = 30, - grimy_snapdragon = 59, - grimy_wergali = 41, - grimy_spirit_weed = 35, -} - -[herb_cleaning_xp] -keyType = "item" -valueType = "int" -defaultInt = 0 -values = { - grimy_guam = 25, - grimy_marrentill = 50, - grimy_tarromin = 38, - grimy_harralander = 63, - grimy_ranarr = 75, - grimy_irit = 88, - grimy_avantoe = 100, - grimy_kwuarm = 113, - grimy_cadantine = 125, - grimy_dwarf_weed = 138, - grimy_torstol = 150, - grimy_lantadyme = 131, - grimy_toadflax = 80, - grimy_snapdragon = 118, - grimy_wergali = 95, - grimy_spirit_weed = 78, -} \ No newline at end of file diff --git a/data/skill/herblore/herbs.tables.toml b/data/skill/herblore/herbs.tables.toml new file mode 100644 index 0000000000..89a8b02860 --- /dev/null +++ b/data/skill/herblore/herbs.tables.toml @@ -0,0 +1,68 @@ +[herbs] +row_id = "item" +level = "int" +xp = "int" + +[.grimy_guam] +level = 1 +xp = 25 + +[.grimy_marrentill] +level = 9 +xp = 50 + +[.grimy_tarromin] +level = 5 +xp = 38 + +[.grimy_harralander] +level = 20 +xp = 63 + +[.grimy_ranarr] +level = 25 +xp = 75 + +[.grimy_irit] +level = 40 +xp = 88 + +[.grimy_avantoe] +level = 48 +xp = 100 + +[.grimy_kwuarm] +level = 54 +xp = 113 + +[.grimy_cadantine] +level = 65 +xp = 125 + +[.grimy_dwarf_weed] +level = 70 +xp = 138 + +[.grimy_torstol] +level = 75 +xp = 150 + +[.grimy_lantadyme] +level = 67 +xp = 131 + +[.grimy_toadflax] +level = 30 +xp = 80 + +[.grimy_snapdragon] +level = 59 +xp = 118 + +[.grimy_wergali] +level = 41 +xp = 95 + +[.grimy_spirit_weed] +level = 35 +xp = 78 From a8722981a91e8ccc049209982b76f222600b211c Mon Sep 17 00:00:00 2001 From: GregHib Date: Fri, 27 Mar 2026 14:51:08 +0000 Subject: [PATCH 32/40] Convert herb enums --- .../main/kotlin/content/skill/herblore/HerbCleaning.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/game/src/main/kotlin/content/skill/herblore/HerbCleaning.kt b/game/src/main/kotlin/content/skill/herblore/HerbCleaning.kt index 7c62d97e43..23cb572ea8 100644 --- a/game/src/main/kotlin/content/skill/herblore/HerbCleaning.kt +++ b/game/src/main/kotlin/content/skill/herblore/HerbCleaning.kt @@ -2,6 +2,7 @@ package content.skill.herblore import world.gregs.voidps.engine.Script import world.gregs.voidps.engine.data.definition.EnumDefinitions +import world.gregs.voidps.engine.data.definition.Rows import world.gregs.voidps.engine.entity.character.player.skill.Skill import world.gregs.voidps.engine.entity.character.player.skill.exp.exp import world.gregs.voidps.engine.entity.character.player.skill.level.Level.has @@ -12,14 +13,13 @@ class HerbCleaning : Script { init { itemOption("Clean") { (item, slot) -> - val level = EnumDefinitions.intOrNull("herb_cleaning_level", item.id) ?: return@itemOption - if (!has(Skill.Herblore, level, true)) { + val herb = Rows.getOrNull("herbs.${item.id}") ?: return@itemOption + if (!has(Skill.Herblore, herb.int("level"), true)) { return@itemOption } if (inventory.replace(slot, item.id, item.id.replace("grimy", "clean"))) { - val xp = EnumDefinitions.int("herb_cleaning_xp", item.id) / 10.0 - exp(Skill.Herblore, xp) + exp(Skill.Herblore, herb.int("xp") / 10.0) } } } From 633f0d1778e50bdd2e5fa695ec52cc2b39fc3682 Mon Sep 17 00:00:00 2001 From: GregHib Date: Fri, 27 Mar 2026 16:03:48 +0000 Subject: [PATCH 33/40] Fix row support --- .../gregs/voidps/engine/data/definition/ColumnReader.kt | 3 +-- .../world/gregs/voidps/engine/data/definition/Tables.kt | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnReader.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnReader.kt index 941e7fd980..49eca21a55 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnReader.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/ColumnReader.kt @@ -1,6 +1,5 @@ package world.gregs.voidps.engine.data.definition -import net.pearx.kasechange.toSentenceCase import world.gregs.config.ConfigReader import world.gregs.voidps.engine.entity.character.player.skill.Skill @@ -96,7 +95,7 @@ sealed interface ColumnReader { "npc" -> ReaderEntity(NPCDefinitions.ids) "item" -> ReaderEntity(ItemDefinitions.ids) "obj" -> ReaderEntity(ObjectDefinitions.ids) - "row" -> ReaderEntity(Rows.ids) + "row" -> ReaderString else -> if (name.startsWith("pair<", ignoreCase = true)) { val (first, second) = name.substringAfter("<").removeSuffix(">").split(",") ReaderPair(reader(first.trim()), reader(second.trim())) diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt index c805ac25a2..8a528bd50a 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/data/definition/Tables.kt @@ -88,11 +88,11 @@ object Tables { return Skill.all[id] } - fun row(path: String): Array = Rows.get(get(path, ColumnType.ColumnInt)).data + fun row(path: String): RowDefinition = Rows.get(get(path, ColumnType.ColumnString)) - fun rowOrNull(path: String): Array? { - val id = getOrNull(path, ColumnType.ColumnInt) ?: return null - return Rows.getOrNull(id)?.data + fun rowOrNull(path: String): RowDefinition? { + val id = getOrNull(path, ColumnType.ColumnString) ?: return null + return Rows.getOrNull(id) } /* From 7f0547c9073ea088075b893cab1a9a5e60718507 Mon Sep 17 00:00:00 2001 From: GregHib Date: Fri, 27 Mar 2026 16:04:00 +0000 Subject: [PATCH 34/40] Convert picking enums --- data/entity/obj/picking.enums.toml | 12 --------- data/entity/obj/picking.tables.toml | 25 +++++++++++++++++++ .../main/kotlin/content/entity/obj/Picking.kt | 5 ++-- 3 files changed, 27 insertions(+), 15 deletions(-) delete mode 100644 data/entity/obj/picking.enums.toml diff --git a/data/entity/obj/picking.enums.toml b/data/entity/obj/picking.enums.toml deleted file mode 100644 index 33e1d0745e..0000000000 --- a/data/entity/obj/picking.enums.toml +++ /dev/null @@ -1,12 +0,0 @@ -[pickables] -keyType = "object" -valueType = "row" -values = { - cabbage_draynor_manor = "picking.cabbages", - potato = "picking.potatoes", - wheat = "picking.wheat", - wheat_zanaris = "picking.wheat", - cabbage = "picking.cabbages", - flax = "picking.flax", - onion = "picking.onions", -} diff --git a/data/entity/obj/picking.tables.toml b/data/entity/obj/picking.tables.toml index 73da64e054..0215a6cc18 100644 --- a/data/entity/obj/picking.tables.toml +++ b/data/entity/obj/picking.tables.toml @@ -31,3 +31,28 @@ message = "You pick some flax." item = "onion" respawn = 30 message = "You pick an onion." + +[pickables] +row_id = "obj" +type = "row" + +[.cabbage_draynor_manor] +type = "picking.cabbages" + +[.potato] +type = "picking.potatoes" + +[.wheat] +type = "picking.wheat" + +[.wheat_zanaris] +type = "picking.wheat" + +[.cabbage] +type = "picking.cabbages" + +[.flax] +type = "picking.flax" + +[.onion] +type = "picking.onions" diff --git a/game/src/main/kotlin/content/entity/obj/Picking.kt b/game/src/main/kotlin/content/entity/obj/Picking.kt index e47f73c657..c2872d561e 100644 --- a/game/src/main/kotlin/content/entity/obj/Picking.kt +++ b/game/src/main/kotlin/content/entity/obj/Picking.kt @@ -2,7 +2,7 @@ package content.entity.obj import world.gregs.voidps.engine.Script import world.gregs.voidps.engine.client.message -import world.gregs.voidps.engine.data.definition.EnumDefinitions +import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.character.player.chat.inventoryFull import world.gregs.voidps.engine.entity.character.sound import world.gregs.voidps.engine.entity.obj.remove @@ -13,10 +13,9 @@ import world.gregs.voidps.type.random import java.util.concurrent.TimeUnit class Picking : Script { - init { objectOperate("Pick") { (target) -> - val pickable = EnumDefinitions.rowOrNull("pickables", target.id) ?: return@objectOperate + val pickable = Tables.rowOrNull("pickables.${target.id}.type") ?: return@objectOperate val item = pickable.item("item") if (!inventory.add(item)) { inventoryFull() From b0ce3dc663dce0c885e9516a53f40fde70ec4834 Mon Sep 17 00:00:00 2001 From: GregHib Date: Fri, 27 Mar 2026 16:12:19 +0000 Subject: [PATCH 35/40] Convert light source enums --- data/skill/firemaking/light_source.enums.toml | 50 ---------- .../skill/firemaking/light_source.tables.toml | 97 +++++++++++++++++++ .../content/skill/firemaking/LightSource.kt | 35 ++----- 3 files changed, 105 insertions(+), 77 deletions(-) delete mode 100644 data/skill/firemaking/light_source.enums.toml create mode 100644 data/skill/firemaking/light_source.tables.toml diff --git a/data/skill/firemaking/light_source.enums.toml b/data/skill/firemaking/light_source.enums.toml deleted file mode 100644 index 20753c9b3f..0000000000 --- a/data/skill/firemaking/light_source.enums.toml +++ /dev/null @@ -1,50 +0,0 @@ -[light_source_level] -keyType = "item" -valueType = "int" -defaultInt = 1 -values = { - oil_lamp_oil = 12, - candle_lantern_white = 4, - candle_lantern_black = 4, - oil_lantern_oil = 26, - bullseye_lantern_oil = 49, - mining_helmet = 65, - emerald_lantern = 49, - sapphire_lantern_oil = 49, -} - -[light_source_lit] -keyType = "item" -valueType = "string" -defaultString = "" -values = { - oil_lamp_oil = "oil_lamp", - candle_lantern_white = "candle_lantern_lit_white", - candle_lantern_black = "candle_lantern_lit_black", - oil_lantern_oil = "oil_lantern", - bullseye_lantern_oil = "bullseye_lantern_lit", - mining_helmet = "mining_helmet_lit", - emerald_lantern = "emerald_lantern_lit", - white_candle = "white_candle_lit", - black_candle = "black_candle_lit", - sapphire_lantern_oil = "sapphire_lantern_lit", - unlit_torch = "lit_torch", -} - -[light_source_extinguish] -keyType = "item" -valueType = "string" -defaultString = "" -values = { - oil_lamp = "oil_lamp_oil", - candle_lantern_lit_white = "candle_lantern_white", - candle_lantern_lit_black = "candle_lantern_black", - oil_lantern = "oil_lantern_oil", - bullseye_lantern_lit = "bullseye_lantern_oil", - mining_helmet_lit = "mining_helmet", - emerald_lantern_lit = "emerald_lantern", - black_candle_lit = "black_candle", - white_candle_lit = "white_candle", - sapphire_lantern_lit = "sapphire_lantern_oil", - lit_torch = "unlit_torch", -} \ No newline at end of file diff --git a/data/skill/firemaking/light_source.tables.toml b/data/skill/firemaking/light_source.tables.toml new file mode 100644 index 0000000000..bd411f85f4 --- /dev/null +++ b/data/skill/firemaking/light_source.tables.toml @@ -0,0 +1,97 @@ +[light_source] +row_id = "item" +lit = "item" +level = "int" +type = "string" + +[.oil_lamp_oil] +lit = "oil_lamp" +level = 12 +type = "lamp" + +[.candle_lantern_white] +lit = "candle_lantern_lit_white" +level = 4 +type = "lantern" + +[.candle_lantern_black] +lit = "candle_lantern_lit_black" +level = 4 +type = "lantern" + +[.oil_lantern_oil] +lit = "oil_lantern" +level = 26 +type = "lantern" + +[.bullseye_lantern_oil] +lit = "bullseye_lantern_lit" +level = 49 +type = "lantern" + +[.mining_helmet] +lit = "mining_helmet_lit" +level = 65 +type = "helmet" + +[.emerald_lantern] +lit = "emerald_lantern_lit" +level = 49 +type = "lantern" + +[.white_candle] +lit = "white_candle_lit" +level = 1 +type = "candle" + +[.sapphire_lantern_oil] +lit = "sapphire_lantern_lit" +level = 49 +type = "lantern" + +[.black_candle] +lit = "black_candle_lit" +level = 1 +type = "candle" + +[.unlit_torch] +lit = "lit_torch" +level = 1 +type = "torch" + +[extinguish] +row_id = "item" +unlit = "item" + +[.oil_lamp] +unlit = "oil_lamp_oil" + +[.candle_lantern_lit_white] +unlit = "candle_lantern_white" + +[.candle_lantern_lit_black] +unlit = "candle_lantern_black" + +[.oil_lantern] +unlit = "oil_lantern_oil" + +[.bullseye_lantern_lit] +unlit = "bullseye_lantern_oil" + +[.mining_helmet_lit] +unlit = "mining_helmet" + +[.emerald_lantern_lit] +unlit = "emerald_lantern" + +[.black_candle_lit] +unlit = "black_candle" + +[.white_candle_lit] +unlit = "white_candle" + +[.sapphire_lantern_lit] +unlit = "sapphire_lantern_oil" + +[.lit_torch] +unlit = "unlit_torch" diff --git a/game/src/main/kotlin/content/skill/firemaking/LightSource.kt b/game/src/main/kotlin/content/skill/firemaking/LightSource.kt index 4b4379110a..6f2639a71d 100644 --- a/game/src/main/kotlin/content/skill/firemaking/LightSource.kt +++ b/game/src/main/kotlin/content/skill/firemaking/LightSource.kt @@ -3,6 +3,8 @@ package content.skill.firemaking import world.gregs.voidps.engine.Script import world.gregs.voidps.engine.client.message import world.gregs.voidps.engine.data.definition.EnumDefinitions +import world.gregs.voidps.engine.data.definition.Rows +import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.character.player.chat.ChatType import world.gregs.voidps.engine.entity.character.player.skill.Skill import world.gregs.voidps.engine.entity.character.player.skill.level.Level.has @@ -10,46 +12,25 @@ import world.gregs.voidps.engine.inv.inventory import world.gregs.voidps.engine.inv.replace class LightSource : Script { - init { - val unlitSources = buildString { - append("oil_lamp_oil,") - append("candle_lantern_white,") - append("candle_lantern_black,") - append("oil_lantern_oil,") - append("bullseye_lantern_oil,") - append("sapphire_lantern_oil,") - append("mining_helmet,") - append("emerald_lantern,") - append("white_candle,") - append("black_candle,") - append("unlit_torch") - } + val unlitSources = Tables.get("light_source").rows().joinToString(",") { it.itemId } itemOnItem("tinderbox*", unlitSources) { _, toItem -> - val lit = EnumDefinitions.stringOrNull("light_source_lit", toItem.id) ?: return@itemOnItem - val level = EnumDefinitions.int("light_source_level", lit) - if (!has(Skill.Firemaking, level, true)) { + val source = Rows.getOrNull("light_source.${toItem.id}") ?: return@itemOnItem + if (!has(Skill.Firemaking, source.int("level"), true)) { return@itemOnItem } - if (!inventory.replace(toItem.id, lit)) { + if (!inventory.replace(toItem.id, source.item("lit"))) { return@itemOnItem } - val litItem = determineLightSource(lit) - message("You light the $litItem", ChatType.Game) + message("You light the ${source.string("type")}.", ChatType.Game) } itemOption("Extinguish") { (item) -> - val extinguished = EnumDefinitions.stringOrNull("light_source_extinguish", item.id) ?: return@itemOption + val extinguished = Tables.itemOrNull("extinguish.${item.id}") ?: return@itemOption if (!inventory.replace(item.id, extinguished)) { return@itemOption } message("You extinguish the flame.", ChatType.Game) } } - - fun determineLightSource(itemName: String): String = when { - itemName.contains("lantern", ignoreCase = true) -> "lantern." - itemName.contains("candle", ignoreCase = true) -> "candle." - else -> "null" - } } From 0563a9f246f1f4b5b8af7fe7f6d46ac06935dd9a Mon Sep 17 00:00:00 2001 From: GregHib Date: Fri, 27 Mar 2026 16:14:28 +0000 Subject: [PATCH 36/40] Convert woodcutting enums --- data/skill/woodcutting/trees.tables.toml | 357 ++++++++++++++++++ data/skill/woodcutting/woodcutting.enums.toml | 124 ------ .../content/skill/woodcutting/Woodcutting.kt | 4 +- 3 files changed, 359 insertions(+), 126 deletions(-) create mode 100644 data/skill/woodcutting/trees.tables.toml delete mode 100644 data/skill/woodcutting/woodcutting.enums.toml diff --git a/data/skill/woodcutting/trees.tables.toml b/data/skill/woodcutting/trees.tables.toml new file mode 100644 index 0000000000..22feddbe43 --- /dev/null +++ b/data/skill/woodcutting/trees.tables.toml @@ -0,0 +1,357 @@ +[trees] +row_id = "obj" +logs = "item" + +[.achey_tree] +logs = "achey_tree_logs" + +[.achey_tree_2] +logs = "achey_tree_logs" + +[.achey_tree_3] +logs = "achey_tree_logs" + +[.arctic_pine] +logs = "arctic_pine_logs" + +[.blood_spindle_tree] +logs = "blood_spindle_branches" + +[.blood_spindle_tree_2] +logs = "blood_spindle_branches" + +[.blood_spindle_tree_3] +logs = "blood_spindle_branches" + +[.bovistrangler_tree] +logs = "bovistrangler_branches" + +[.bovistrangler_tree_2] +logs = "bovistrangler_branches" + +[.bovistrangler_tree_3] +logs = "bovistrangler_branches" + +[.corpsethorn_tree] +logs = "corpsethorn_branches" + +[.corpsethorn_tree_2] +logs = "corpsethorn_branches" + +[.corpsethorn_tree_3] +logs = "corpsethorn_branches" + +[.cursed_magic_tree] +logs = "cursed_magic_logs" + +[.dead_tree] +logs = "logs" + +[.dead_tree_10] +logs = "logs" + +[.dead_tree_11] +logs = "logs" + +[.dead_tree_12] +logs = "logs" + +[.dead_tree_2] +logs = "logs" + +[.dead_tree_25] +logs = "logs" + +[.dead_tree_26] +logs = "logs" + +[.dead_tree_27] +logs = "logs" + +[.dead_tree_28] +logs = "logs" + +[.dead_tree_3] +logs = "logs" + +[.dead_tree_37] +logs = "logs" + +[.dead_tree_38] +logs = "logs" + +[.dead_tree_39] +logs = "logs" + +[.dead_tree_4] +logs = "logs" + +[.dead_tree_40] +logs = "logs" + +[.dead_tree_5] +logs = "logs" + +[.dead_tree_8] +logs = "logs" + +[.dead_tree_9] +logs = "logs" + +[.dead_tree_covered_in_snow] +logs = "logs" + +[.dream_tree] +logs = "dream_log" + +[.dying_tree] +logs = "logs" + +[.entgallow_tree] +logs = "entgallow_branches" + +[.entgallow_tree_2] +logs = "entgallow_branches" + +[.entgallow_tree_3] +logs = "entgallow_branches" + +[.eucalyptus_tree] +logs = "eucalyptus_logs" + +[.eucalyptus_tree_2] +logs = "eucalyptus_logs" + +[.eucalyptus_tree_3] +logs = "eucalyptus_logs" + +[.evergreen] +logs = "logs" + +[.evergreen_2] +logs = "logs" + +[.evergreen_3] +logs = "logs" + +[.evergreen_4] +logs = "logs" + +[.grave_creeper_tree] +logs = "grave_creeper_branches" + +[.grave_creeper_tree_2] +logs = "grave_creeper_branches" + +[.grave_creeper_tree_3] +logs = "grave_creeper_branches" + +[.hollow_tree] +logs = "bark" + +[.hollow_tree_2] +logs = "bark" + +[.ivy] +logs = "poison_ivy_berries" + +[.jungle_tree] +logs = "logs" + +[.jungle_tree_2] +logs = "logs" + +[.jungle_tree_3] +logs = "logs" + +[.jungle_tree_5] +logs = "logs" + +[.jungle_tree_6] +logs = "logs" + +[.jungle_tree_7] +logs = "logs" + +[.jungle_tree_8] +logs = "logs" + +[.jungle_tree_9] +logs = "logs" + +[.magic_tree] +logs = "magic_logs" + +[.magic_tree_fullygrown_2] +logs = "magic_logs" + +[.magic_tree_two] +logs = "magic_logs" + +[.mahogany_tree] +logs = "mahogany_logs" + +[.mahogany_tree_2] +logs = "mahogany_logs" + +[.maple_tree] +logs = "maple_logs" + +[.maple_tree_fullygrown_2] +logs = "maple_logs" + +[.maple_tree_three] +logs = "maple_logs" + +[.maple_tree_two] +logs = "maple_logs" + +[.oak] +logs = "oak_logs" + +[.oak_tree_dark] +logs = "oak_logs" + +[.oak_tree_fullygrown_2] +logs = "oak_logs" + +[.oak_tree_pale] +logs = "oak_logs" + +[.oak_tree_three] +logs = "oak_logs" + +[.seeping_elm_tree] +logs = "seeping_elm_branches" + +[.seeping_elm_tree_2] +logs = "seeping_elm_branches" + +[.seeping_elm_tree_3] +logs = "seeping_elm_branches" + +[.spinebeam_tree] +logs = "spinebeam_branches" + +[.spinebeam_tree_2] +logs = "spinebeam_branches" + +[.spinebeam_tree_3] +logs = "spinebeam_branches" + +[.tangle_gum_tree] +logs = "tangle_gum_branches" + +[.tangle_gum_tree_2] +logs = "tangle_gum_branches" + +[.tangle_gum_tree_3] +logs = "tangle_gum_branches" + +[.teak] +logs = "teak_logs" + +[.teak_2] +logs = "teak_logs" + +[.teak_3] +logs = "teak_logs" + +[.thigat_tree] +logs = "thigat_branches" + +[.thigat_tree_2] +logs = "thigat_branches" + +[.thigat_tree_3] +logs = "thigat_branches" + +[.tree] +logs = "logs" + +[.tree_10] +logs = "logs" + +[.tree_11] +logs = "logs" + +[.tree_12] +logs = "logs" + +[.tree_14] +logs = "logs" + +[.tree_15] +logs = "logs" + +[.tree_18] +logs = "logs" + +[.tree_19] +logs = "logs" + +[.tree_21] +logs = "logs" + +[.tree_22] +logs = "logs" + +[.tree_23] +logs = "logs" + +[.tree_24] +logs = "logs" + +[.tree_3] +logs = "logs" + +[.tree_4] +logs = "logs" + +[.tree_5] +logs = "logs" + +[.tree_66] +logs = "logs" + +[.tree_96] +logs = "logs" + +[.tree_97] +logs = "logs" + +[.tree_98] +logs = "logs" + +[.utuku_tree] +logs = "utuku_branches" + +[.utuku_tree_2] +logs = "utuku_branches" + +[.utuku_tree_3] +logs = "utuku_branches" + +[.willow] +logs = "willow_logs" + +[.willow_2] +logs = "willow_logs" + +[.willow_3] +logs = "willow_logs" + +[.willow_5] +logs = "willow_logs" + +[.willow_tree_fullygrown_2] +logs = "willow_logs" + +[.yew] +logs = "yew_logs" + +[.yew_2] +logs = "yew_logs" + +[.yew_tree_fullygrown_2] +logs = "yew_logs" diff --git a/data/skill/woodcutting/woodcutting.enums.toml b/data/skill/woodcutting/woodcutting.enums.toml deleted file mode 100644 index eaf95936a3..0000000000 --- a/data/skill/woodcutting/woodcutting.enums.toml +++ /dev/null @@ -1,124 +0,0 @@ -[woodcutting_log] -keyType = "object" -valueType = "string" -defaultString = "" -values = { - achey_tree = "achey_tree_logs", - achey_tree_2 = "achey_tree_logs", - achey_tree_3 = "achey_tree_logs", - arctic_pine = "arctic_pine_logs", - blood_spindle_tree = "blood_spindle_branches", - blood_spindle_tree_2 = "blood_spindle_branches", - blood_spindle_tree_3 = "blood_spindle_branches", - bovistrangler_tree = "bovistrangler_branches", - bovistrangler_tree_2 = "bovistrangler_branches", - bovistrangler_tree_3 = "bovistrangler_branches", - corpsethorn_tree = "corpsethorn_branches", - corpsethorn_tree_2 = "corpsethorn_branches", - corpsethorn_tree_3 = "corpsethorn_branches", - cursed_magic_tree = "cursed_magic_logs", - dead_tree = "logs", - dead_tree_10 = "logs", - dead_tree_11 = "logs", - dead_tree_12 = "logs", - dead_tree_2 = "logs", - dead_tree_25 = "logs", - dead_tree_26 = "logs", - dead_tree_27 = "logs", - dead_tree_28 = "logs", - dead_tree_3 = "logs", - dead_tree_37 = "logs", - dead_tree_38 = "logs", - dead_tree_39 = "logs", - dead_tree_4 = "logs", - dead_tree_40 = "logs", - dead_tree_5 = "logs", - dead_tree_8 = "logs", - dead_tree_9 = "logs", - dead_tree_covered_in_snow = "logs", - dream_tree = "dream_log", - dying_tree = "logs", - entgallow_tree = "entgallow_branches", - entgallow_tree_2 = "entgallow_branches", - entgallow_tree_3 = "entgallow_branches", - eucalyptus_tree = "eucalyptus_logs", - eucalyptus_tree_2 = "eucalyptus_logs", - eucalyptus_tree_3 = "eucalyptus_logs", - evergreen = "logs", - evergreen_2 = "logs", - evergreen_3 = "logs", - evergreen_4 = "logs", - grave_creeper_tree = "grave_creeper_branches", - grave_creeper_tree_2 = "grave_creeper_branches", - grave_creeper_tree_3 = "grave_creeper_branches", - hollow_tree = "bark", - hollow_tree_2 = "bark", - ivy = "poison_ivy_berries", - jungle_tree = "logs", - jungle_tree_2 = "logs", - jungle_tree_3 = "logs", - jungle_tree_5 = "logs", - jungle_tree_6 = "logs", - jungle_tree_7 = "logs", - jungle_tree_8 = "logs", - jungle_tree_9 = "logs", - magic_tree = "magic_logs", - magic_tree_fullygrown_2 = "magic_logs", - magic_tree_two = "magic_logs", - mahogany_tree = "mahogany_logs", - mahogany_tree_2 = "mahogany_logs", - maple_tree = "maple_logs", - maple_tree_fullygrown_2 = "maple_logs", - maple_tree_three = "maple_logs", - maple_tree_two = "maple_logs", - oak = "oak_logs", - oak_tree_dark = "oak_logs", - oak_tree_fullygrown_2 = "oak_logs", - oak_tree_pale = "oak_logs", - oak_tree_three = "oak_logs", - seeping_elm_tree = "seeping_elm_branches", - seeping_elm_tree_2 = "seeping_elm_branches", - seeping_elm_tree_3 = "seeping_elm_branches", - spinebeam_tree = "spinebeam_branches", - spinebeam_tree_2 = "spinebeam_branches", - spinebeam_tree_3 = "spinebeam_branches", - tangle_gum_tree = "tangle_gum_branches", - tangle_gum_tree_2 = "tangle_gum_branches", - tangle_gum_tree_3 = "tangle_gum_branches", - teak = "teak_logs", - teak_2 = "teak_logs", - teak_3 = "teak_logs", - thigat_tree = "thigat_branches", - thigat_tree_2 = "thigat_branches", - thigat_tree_3 = "thigat_branches", - tree = "logs", - tree_10 = "logs", - tree_11 = "logs", - tree_12 = "logs", - tree_14 = "logs", - tree_15 = "logs", - tree_18 = "logs", - tree_19 = "logs", - tree_21 = "logs", - tree_22 = "logs", - tree_23 = "logs", - tree_24 = "logs", - tree_3 = "logs", - tree_4 = "logs", - tree_5 = "logs", - tree_66 = "logs", - tree_96 = "logs", - tree_97 = "logs", - tree_98 = "logs", - utuku_tree = "utuku_branches", - utuku_tree_2 = "utuku_branches", - utuku_tree_3 = "utuku_branches", - willow = "willow_logs", - willow_2 = "willow_logs", - willow_3 = "willow_logs", - willow_5 = "willow_logs", - willow_tree_fullygrown_2 = "willow_logs", - yew = "yew_logs", - yew_2 = "yew_logs", - yew_tree_fullygrown_2 = "yew_logs", -} diff --git a/game/src/main/kotlin/content/skill/woodcutting/Woodcutting.kt b/game/src/main/kotlin/content/skill/woodcutting/Woodcutting.kt index 967a7ba93f..7b3016e663 100644 --- a/game/src/main/kotlin/content/skill/woodcutting/Woodcutting.kt +++ b/game/src/main/kotlin/content/skill/woodcutting/Woodcutting.kt @@ -8,9 +8,9 @@ import world.gregs.voidps.engine.client.variable.remaining import world.gregs.voidps.engine.client.variable.start import world.gregs.voidps.engine.client.variable.stop import world.gregs.voidps.engine.data.config.RowDefinition -import world.gregs.voidps.engine.data.definition.EnumDefinitions import world.gregs.voidps.engine.data.definition.ObjectDefinitions import world.gregs.voidps.engine.data.definition.Rows +import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.character.areaSound import world.gregs.voidps.engine.entity.character.mode.interact.PlayerOnObjectInteract import world.gregs.voidps.engine.entity.character.player.Player @@ -46,7 +46,7 @@ class Woodcutting(val drops: DropTables) : Script { suspend fun chopDown(player: Player, interact: PlayerOnObjectInteract) { val target = interact.target - val id = EnumDefinitions.stringOrNull("woodcutting_log", target.def(player).stringId) ?: return + val id = Tables.itemOrNull("trees.${target.def(player).stringId}.logs") ?: return val log = Rows.getOrNull("logs.$id") ?: return val hatchet = Hatchet.best(player) if (hatchet == null) { From c7e50f5ec969dbda0c7bd7c9161bba39ed9009e1 Mon Sep 17 00:00:00 2001 From: GregHib Date: Fri, 27 Mar 2026 16:30:46 +0000 Subject: [PATCH 37/40] Convert desert heat enums --- .../kharidian_desert/desert_heat.tables.toml | 75 ++ .../kharidian_desert.enums.toml | 29 - data/skill/mining/mining.enums.toml | 370 ------ data/skill/mining/ores.tables.toml | 26 +- data/skill/mining/rocks.tables.toml | 1095 +++++++++++++++++ .../area/kharidian_desert/DesertHeat.kt | 4 +- .../kotlin/content/skill/mining/Mining.kt | 58 +- 7 files changed, 1199 insertions(+), 458 deletions(-) create mode 100644 data/area/kharidian_desert/desert_heat.tables.toml delete mode 100644 data/area/kharidian_desert/kharidian_desert.enums.toml delete mode 100644 data/skill/mining/mining.enums.toml create mode 100644 data/skill/mining/rocks.tables.toml diff --git a/data/area/kharidian_desert/desert_heat.tables.toml b/data/area/kharidian_desert/desert_heat.tables.toml new file mode 100644 index 0000000000..fcf7b18239 --- /dev/null +++ b/data/area/kharidian_desert/desert_heat.tables.toml @@ -0,0 +1,75 @@ +[desert_clothing] +row_id = "item" +heat_delay = "int" + +[.desert_disguise] +heat_delay = 20 + +[.desert_shirt] +heat_delay = 20 + +[.desert_robe] +heat_delay = 20 + +[.desert_boots] +heat_delay = 20 + +[.black_desert_shirt] +heat_delay = 20 + +[.black_desert_robe] +heat_delay = 20 + +[.fez] +heat_delay = 20 + +[.desert_top] +heat_delay = 20 + +[.desert_legs] +heat_delay = 20 + +[.desert_top_overcoat] +heat_delay = 20 + +[.desert_robes] +heat_delay = 20 + +[.slave_shirt] +heat_delay = 10 + +[.slave_robe] +heat_delay = 10 + +[.slave_boots] +heat_delay = 10 + +[.robe_of_elidinis_top] +heat_delay = 20 + +[.robe_of_elidinis_bottom] +heat_delay = 20 + +[.menaphite_headgear_purple] +heat_delay = 20 + +[.menaphite_top_purple] +heat_delay = 20 + +[.menaphite_robe_purple] +heat_delay = 20 + +[.menaphite_action_kilt_purple] +heat_delay = 20 + +[.menaphite_headgear_red] +heat_delay = 20 + +[.menaphite_top_red] +heat_delay = 20 + +[.menaphite_robe_red] +heat_delay = 20 + +[.menaphite_action_kilt_red] +heat_delay = 20 diff --git a/data/area/kharidian_desert/kharidian_desert.enums.toml b/data/area/kharidian_desert/kharidian_desert.enums.toml deleted file mode 100644 index 6f2d429889..0000000000 --- a/data/area/kharidian_desert/kharidian_desert.enums.toml +++ /dev/null @@ -1,29 +0,0 @@ -[desert_heat_delay] -keyType = "item" -valueType = "int" -values = { - desert_disguise = 20, - desert_shirt = 20, - desert_robe = 20, - desert_boots = 20, - black_desert_shirt = 20, - black_desert_robe = 20, - fez = 20, - desert_top = 20, - desert_legs = 20, - desert_top_overcoat = 20, - desert_robes = 20, - slave_shirt = 10, - slave_robe = 10, - slave_boots = 10, - robe_of_elidinis_top = 20, - robe_of_elidinis_bottom = 20, - menaphite_headgear_purple = 20, - menaphite_top_purple = 20, - menaphite_robe_purple = 20, - menaphite_action_kilt_purple = 20, - menaphite_headgear_red = 20, - menaphite_top_red = 20, - menaphite_robe_red = 20, - menaphite_action_kilt_red = 20, -} \ No newline at end of file diff --git a/data/skill/mining/mining.enums.toml b/data/skill/mining/mining.enums.toml deleted file mode 100644 index 8a13a29dc5..0000000000 --- a/data/skill/mining/mining.enums.toml +++ /dev/null @@ -1,370 +0,0 @@ -[mining_ores] -keyType = "object" -valueType = "string" -defaultString = "" -values = { - adamantite_rocks_black_1 = "adamantite_ore", - adamantite_rocks_black_2 = "adamantite_ore", - adamantite_rocks_black_3 = "adamantite_ore", - adamantite_rocks_crandor_1 = "adamantite_ore", - adamantite_rocks_crandor_2 = "adamantite_ore", - adamantite_rocks_crandor_3 = "adamantite_ore", - adamantite_rocks_dirt_1 = "adamantite_ore", - adamantite_rocks_dirt_2 = "adamantite_ore", - adamantite_rocks_dirt_3 = "adamantite_ore", - adamantite_rocks_dungeon_1 = "adamantite_ore", - adamantite_rocks_dungeon_2 = "adamantite_ore", - adamantite_rocks_dungeon_3 = "adamantite_ore", - adamantite_rocks_falador_mine_1 = "adamantite_ore", - adamantite_rocks_falador_mine_3 = "adamantite_ore", - adamantite_rocks_grey_1 = "adamantite_ore", - adamantite_rocks_grey_2 = "adamantite_ore", - adamantite_rocks_grey_3 = "adamantite_ore", - adamantite_rocks_lava_maze_dungeon_1 = "adamantite_ore", - adamantite_rocks_lava_maze_dungeon_2 = "adamantite_ore", - adamantite_rocks_lava_maze_dungeon_3 = "adamantite_ore", - adamantite_rocks_light_1 = "adamantite_ore", - adamantite_rocks_light_2 = "adamantite_ore", - adamantite_rocks_light_3 = "adamantite_ore", - adamantite_rocks_old_1 = "adamantite_ore", - adamantite_rocks_old_2 = "adamantite_ore", - adamantite_rocks_rock_1 = "adamantite_ore", - adamantite_rocks_rock_2 = "adamantite_ore", - adamantite_rocks_rock_3 = "adamantite_ore", - adamantite_rocks_tourist_trap_1 = "adamantite_ore", - adamantite_rocks_tourist_trap_2 = "adamantite_ore", - adamantite_rocks_tourist_trap_3 = "adamantite_ore", - adamantite_rocks_tzhaar_1 = "adamantite_ore", - adamantite_rocks_tzhaar_2 = "adamantite_ore", - adamantite_rocks_tzhaar_3 = "adamantite_ore", - blurite_rocks_asgarnian_ice_1 = "blurite_ore", - blurite_rocks_asgarnian_ice_2 = "blurite_ore", - blurite_rocks_ice_1 = "blurite_ore", - blurite_rocks_ice_2 = "blurite_ore", - blurite_rocks_lumbridge_cellar_1 = "blurite_ore", - blurite_rocks_lumbridge_cellar_2 = "blurite_ore", - blurite_rocks_lumbridge_cellar_3 = "blurite_ore", - clay_rocks_dirt_1 = "clay", - clay_rocks_dirt_2 = "clay", - clay_rocks_dirt_3 = "clay", - clay_rocks_falador_mine_1 = "clay", - clay_rocks_falador_mine_2 = "clay", - clay_rocks_lava_maze_dungeon_1 = "clay", - clay_rocks_lava_maze_dungeon_2 = "clay", - clay_rocks_lava_maze_dungeon_3 = "clay", - clay_rocks_light_1 = "clay", - clay_rocks_light_2 = "clay", - clay_rocks_light_3 = "clay", - clay_rocks_mud_1 = "clay", - clay_rocks_mud_2 = "clay", - clay_rocks_mud_3 = "clay", - clay_rocks_old_1 = "clay", - clay_rocks_old_2 = "clay", - clay_rocks_piscatoris_1 = "clay", - clay_rocks_piscatoris_2 = "clay", - clay_rocks_quarry_2 = "clay", - clay_rocks_rimmington_1 = "clay", - clay_rocks_rimmington_2 = "clay", - clay_rocks_rimmington_3 = "clay", - clay_rocks_rock_1 = "clay", - clay_rocks_rock_2 = "clay", - clay_rocks_rock_3 = "clay", - coal_rocks_black_1 = "coal", - coal_rocks_black_2 = "coal", - coal_rocks_black_3 = "coal", - coal_rocks_crandor_1 = "coal", - coal_rocks_crandor_2 = "coal", - coal_rocks_crandor_3 = "coal", - coal_rocks_dirt_1 = "coal", - coal_rocks_dirt_2 = "coal", - coal_rocks_dirt_3 = "coal", - coal_rocks_dungeon_1 = "coal", - coal_rocks_dungeon_2 = "coal", - coal_rocks_dungeon_3 = "coal", - coal_rocks_falador_mine_1 = "coal", - coal_rocks_falador_mine_2 = "coal", - coal_rocks_falador_mine_3 = "coal", - coal_rocks_lava_maze_dungeon_1 = "coal", - coal_rocks_lava_maze_dungeon_2 = "coal", - coal_rocks_lava_maze_dungeon_3 = "coal", - coal_rocks_light_1 = "coal", - coal_rocks_light_2 = "coal", - coal_rocks_light_3 = "coal", - coal_rocks_misc_expansion_1 = "coal", - coal_rocks_misc_expansion_2 = "coal", - coal_rocks_misc_expansion_3 = "coal", - coal_rocks_mud_1 = "coal", - coal_rocks_mud_2 = "coal", - coal_rocks_mud_3 = "coal", - coal_rocks_old_1 = "coal", - coal_rocks_old_2 = "coal", - coal_rocks_quarry_1 = "coal", - coal_rocks_rat_pit_1 = "coal", - coal_rocks_rat_pit_2 = "coal", - coal_rocks_rock_1 = "coal", - coal_rocks_rock_2 = "coal", - coal_rocks_rock_3 = "coal", - coal_rocks_sand_1 = "coal", - coal_rocks_sand_2 = "coal", - coal_rocks_sand_3 = "coal", - coal_rocks_tzhaar_1 = "coal", - coal_rocks_tzhaar_2 = "coal", - coal_rocks_tzhaar_3 = "coal", - copper_rocks_crandor_1 = "copper_ore", - copper_rocks_crandor_2 = "copper_ore", - copper_rocks_crandor_3 = "copper_ore", - copper_rocks_dungeon_1 = "copper_ore", - copper_rocks_dungeon_2 = "copper_ore", - copper_rocks_dungeon_3 = "copper_ore", - copper_rocks_falador_mine_1 = "copper_ore", - copper_rocks_falador_mine_2 = "copper_ore", - copper_rocks_falador_mine_3 = "copper_ore", - copper_rocks_lava_maze_dungeon_1 = "copper_ore", - copper_rocks_lava_maze_dungeon_2 = "copper_ore", - copper_rocks_lava_maze_dungeon_3 = "copper_ore", - copper_rocks_light_1 = "copper_ore", - copper_rocks_light_2 = "copper_ore", - copper_rocks_light_2_1 = "copper_ore", - copper_rocks_light_2_2 = "copper_ore", - copper_rocks_light_2_3 = "copper_ore", - copper_rocks_light_3 = "copper_ore", - copper_rocks_light_3_1 = "copper_ore", - copper_rocks_mud_1 = "copper_ore", - copper_rocks_mud_2 = "copper_ore", - copper_rocks_mud_3 = "copper_ore", - copper_rocks_old_1 = "copper_ore", - copper_rocks_old_2 = "copper_ore", - copper_rocks_piscatoris_1 = "copper_ore", - copper_rocks_piscatoris_2 = "copper_ore", - copper_rocks_rimmington_1 = "copper_ore", - copper_rocks_rimmington_2 = "copper_ore", - copper_rocks_rimmington_3 = "copper_ore", - copper_rocks_rock_1 = "copper_ore", - copper_rocks_rock_2 = "copper_ore", - copper_rocks_rock_3 = "copper_ore", - copper_rocks_sand_1 = "copper_ore", - copper_rocks_sand_2 = "copper_ore", - copper_rocks_sand_3 = "copper_ore", - copper_rocks_tourist_trap_1 = "copper_ore", - copper_rocks_tourist_trap_2 = "copper_ore", - copper_rocks_tourist_trap_3 = "copper_ore", - copper_rocks_tutorial_island_1 = "copper_ore", - crashed_star_tier_1 = "stardust", - crashed_star_tier_2 = "stardust", - crashed_star_tier_3 = "stardust", - crashed_star_tier_4 = "stardust", - crashed_star_tier_5 = "stardust", - crashed_star_tier_6 = "stardust", - crashed_star_tier_7 = "stardust", - crashed_star_tier_8 = "stardust", - crashed_star_tier_9 = "stardust", - gem_rocks_ingneous_1 = "uncut_opal", - gem_rocks_ingneous_2 = "uncut_opal", - gem_rocks_ingneous_2_1 = "uncut_opal", - gem_rocks_ingneous_2_2 = "uncut_opal", - gem_rocks_ingneous_2_3 = "uncut_opal", - gem_rocks_ingneous_3 = "uncut_opal", - gem_rocks_lumbridge_cellar_1 = "uncut_opal", - gem_rocks_lumbridge_cellar_2 = "uncut_opal", - gem_rocks_lumbridge_cellar_3 = "uncut_opal", - gem_rocks_old_2 = "uncut_opal", - gold_rocks_crandor_1 = "gold_ore", - gold_rocks_crandor_2 = "gold_ore", - gold_rocks_crandor_3 = "gold_ore", - gold_rocks_dirt_1 = "gold_ore", - gold_rocks_dirt_2 = "gold_ore", - gold_rocks_dirt_3 = "gold_ore", - gold_rocks_dungeon_1 = "gold_ore", - gold_rocks_dungeon_3 = "gold_ore", - gold_rocks_falador_mine_1 = "gold_ore", - gold_rocks_falador_mine_2 = "gold_ore", - gold_rocks_grey_1 = "gold_ore", - gold_rocks_grey_2 = "gold_ore", - gold_rocks_grey_3 = "gold_ore", - gold_rocks_ingneous_1 = "gold_ore", - gold_rocks_ingneous_2 = "gold_ore", - gold_rocks_ingneous_3 = "gold_ore", - gold_rocks_lava_maze_dungeon_1 = "gold_ore", - gold_rocks_lava_maze_dungeon_2 = "gold_ore", - gold_rocks_lava_maze_dungeon_3 = "gold_ore", - gold_rocks_light_1 = "gold_ore", - gold_rocks_light_2 = "gold_ore", - gold_rocks_light_3 = "gold_ore", - gold_rocks_mud_1 = "gold_ore", - gold_rocks_mud_2 = "gold_ore", - gold_rocks_mud_3 = "gold_ore", - gold_rocks_old_1 = "gold_ore", - gold_rocks_old_2 = "gold_ore", - gold_rocks_rimmington_1 = "gold_ore", - gold_rocks_rimmington_2 = "gold_ore", - gold_rocks_rimmington_3 = "gold_ore", - gold_rocks_rock_1 = "gold_ore", - gold_rocks_rock_3 = "gold_ore", - gold_rocks_sand_1 = "gold_ore", - gold_rocks_sand_2 = "gold_ore", - gold_rocks_sand_3 = "gold_ore", - gold_rocks_tzhaar_1 = "gold_ore", - gold_rocks_tzhaar_2 = "gold_ore", - gold_rocks_tzhaar_3 = "gold_ore", - granite_rocks_quarry = "granite_500g", - iron_rocks_black_1 = "iron_ore", - iron_rocks_black_2 = "iron_ore", - iron_rocks_black_3 = "iron_ore", - iron_rocks_crandor_1 = "iron_ore", - iron_rocks_crandor_2 = "iron_ore", - iron_rocks_crandor_3 = "iron_ore", - iron_rocks_dirt_1 = "iron_ore", - iron_rocks_dirt_2 = "iron_ore", - iron_rocks_dirt_3 = "iron_ore", - iron_rocks_dungeon_1 = "iron_ore", - iron_rocks_dungeon_2 = "iron_ore", - iron_rocks_dungeon_3 = "iron_ore", - iron_rocks_falador_mine_1 = "iron_ore", - iron_rocks_falador_mine_2 = "iron_ore", - iron_rocks_falador_mine_3 = "iron_ore", - iron_rocks_light_1 = "iron_ore", - iron_rocks_light_2 = "iron_ore", - iron_rocks_light_3 = "iron_ore", - iron_rocks_lumbridge_cellar_1 = "iron_ore", - iron_rocks_lumbridge_cellar_2 = "iron_ore", - iron_rocks_mud_1 = "iron_ore", - iron_rocks_mud_2 = "iron_ore", - iron_rocks_mud_3 = "iron_ore", - iron_rocks_old_1 = "iron_ore", - iron_rocks_old_2 = "iron_ore", - iron_rocks_piscatoris_1 = "iron_ore", - iron_rocks_piscatoris_2 = "iron_ore", - iron_rocks_piscatoris_2_1 = "iron_ore", - iron_rocks_piscatoris_2_2 = "iron_ore", - iron_rocks_rat_pit_1 = "iron_ore", - iron_rocks_rat_pit_2 = "iron_ore", - iron_rocks_rimmington_1 = "iron_ore", - iron_rocks_rimmington_2 = "iron_ore", - iron_rocks_rimmington_3 = "iron_ore", - iron_rocks_rock_1 = "iron_ore", - iron_rocks_rock_2 = "iron_ore", - iron_rocks_rock_3 = "iron_ore", - iron_rocks_sand_1 = "iron_ore", - iron_rocks_sand_2 = "iron_ore", - iron_rocks_sand_3 = "iron_ore", - mithril_rocks_black_1 = "mithril_ore", - mithril_rocks_black_2 = "mithril_ore", - mithril_rocks_black_3 = "mithril_ore", - mithril_rocks_dirt_1 = "mithril_ore", - mithril_rocks_dirt_2 = "mithril_ore", - mithril_rocks_dirt_3 = "mithril_ore", - mithril_rocks_dungeon_1 = "mithril_ore", - mithril_rocks_dungeon_2 = "mithril_ore", - mithril_rocks_dungeon_3 = "mithril_ore", - mithril_rocks_falador_mine_1 = "mithril_ore", - mithril_rocks_falador_mine_2 = "mithril_ore", - mithril_rocks_falador_mine_3 = "mithril_ore", - mithril_rocks_lava_maze_dungeon_1 = "mithril_ore", - mithril_rocks_lava_maze_dungeon_2 = "mithril_ore", - mithril_rocks_lava_maze_dungeon_3 = "mithril_ore", - mithril_rocks_light_1 = "mithril_ore", - mithril_rocks_light_2 = "mithril_ore", - mithril_rocks_light_3 = "mithril_ore", - mithril_rocks_mud_1 = "mithril_ore", - mithril_rocks_mud_2 = "mithril_ore", - mithril_rocks_mud_3 = "mithril_ore", - mithril_rocks_old_1 = "mithril_ore", - mithril_rocks_old_2 = "mithril_ore", - mithril_rocks_rock_1 = "mithril_ore", - mithril_rocks_rock_2 = "mithril_ore", - mithril_rocks_rock_3 = "mithril_ore", - mithril_rocks_tourist_trap_1 = "mithril_ore", - mithril_rocks_tourist_trap_2 = "mithril_ore", - mithril_rocks_tourist_trap_3 = "mithril_ore", - mithril_rocks_tzhaar_1 = "mithril_ore", - mithril_rocks_tzhaar_2 = "mithril_ore", - mithril_rocks_tzhaar_3 = "mithril_ore", - rune_essence_rocks = "rune_essence", - runite_rocks_black_1 = "runite_ore", - runite_rocks_black_2 = "runite_ore", - runite_rocks_black_3 = "runite_ore", - runite_rocks_dirt_1 = "runite_ore", - runite_rocks_dirt_2 = "runite_ore", - runite_rocks_dungeon_1 = "runite_ore", - runite_rocks_dungeon_3 = "runite_ore", - runite_rocks_grey_1 = "runite_ore", - runite_rocks_grey_2 = "runite_ore", - runite_rocks_grey_3 = "runite_ore", - runite_rocks_lava_maze_dungeon_1 = "runite_ore", - runite_rocks_lava_maze_dungeon_2 = "runite_ore", - runite_rocks_lava_maze_dungeon_3 = "runite_ore", - runite_rocks_old_1 = "runite_ore", - runite_rocks_old_2 = "runite_ore", - sandstone_rocks_quarry = "sandstone_1kg", - silver_rocks_dirt_1 = "silver_ore", - silver_rocks_dirt_2 = "silver_ore", - silver_rocks_dirt_3 = "silver_ore", - silver_rocks_dungeon_1 = "silver_ore", - silver_rocks_dungeon_2 = "silver_ore", - silver_rocks_dungeon_3 = "silver_ore", - silver_rocks_ingneous_1 = "silver_ore", - silver_rocks_ingneous_2 = "silver_ore", - silver_rocks_ingneous_3 = "silver_ore", - silver_rocks_lava_maze_dungeon_1 = "silver_ore", - silver_rocks_lava_maze_dungeon_2 = "silver_ore", - silver_rocks_lava_maze_dungeon_3 = "silver_ore", - silver_rocks_light_1 = "silver_ore", - silver_rocks_light_2 = "silver_ore", - silver_rocks_light_3 = "silver_ore", - silver_rocks_lumbridge_cellar_1 = "silver_ore", - silver_rocks_lumbridge_cellar_2 = "silver_ore", - silver_rocks_mud_1 = "silver_ore", - silver_rocks_mud_2 = "silver_ore", - silver_rocks_mud_3 = "silver_ore", - silver_rocks_old_1 = "silver_ore", - silver_rocks_old_2 = "silver_ore", - silver_rocks_rimmington_1 = "silver_ore", - silver_rocks_rimmington_2 = "silver_ore", - silver_rocks_rimmington_2_1 = "silver_ore", - silver_rocks_rimmington_2_2 = "silver_ore", - silver_rocks_rimmington_2_3 = "silver_ore", - silver_rocks_rimmington_3 = "silver_ore", - silver_rocks_rock_1 = "silver_ore", - silver_rocks_rock_2 = "silver_ore", - silver_rocks_rock_2_1 = "silver_ore", - silver_rocks_rock_3 = "silver_ore", - silver_rocks_tzhaar_1 = "silver_ore", - silver_rocks_tzhaar_2 = "silver_ore", - silver_rocks_tzhaar_3 = "silver_ore", - tin_rocks_crandor_1 = "tin_ore", - tin_rocks_crandor_2 = "tin_ore", - tin_rocks_crandor_3 = "tin_ore", - tin_rocks_dungeon_1 = "tin_ore", - tin_rocks_dungeon_2 = "tin_ore", - tin_rocks_dungeon_3 = "tin_ore", - tin_rocks_falador_mine_1 = "tin_ore", - tin_rocks_falador_mine_2 = "tin_ore", - tin_rocks_falador_mine_3 = "tin_ore", - tin_rocks_lava_maze_dungeon_1 = "tin_ore", - tin_rocks_lava_maze_dungeon_2 = "tin_ore", - tin_rocks_lava_maze_dungeon_3 = "tin_ore", - tin_rocks_light_1 = "tin_ore", - tin_rocks_light_2 = "tin_ore", - tin_rocks_light_2_1 = "tin_ore", - tin_rocks_light_2_2 = "tin_ore", - tin_rocks_light_2_3 = "tin_ore", - tin_rocks_light_3 = "tin_ore", - tin_rocks_light_3_1 = "tin_ore", - tin_rocks_mud_1 = "tin_ore", - tin_rocks_mud_2 = "tin_ore", - tin_rocks_mud_3 = "tin_ore", - tin_rocks_old_1 = "tin_ore", - tin_rocks_old_2 = "tin_ore", - tin_rocks_piscatoris_1 = "tin_ore", - tin_rocks_piscatoris_2 = "tin_ore", - tin_rocks_rock_1 = "tin_ore", - tin_rocks_rock_2 = "tin_ore", - tin_rocks_rock_3 = "tin_ore", - tin_rocks_sand_1 = "tin_ore", - tin_rocks_sand_2 = "tin_ore", - tin_rocks_sand_3 = "tin_ore", - tin_rocks_tourist_trap_1 = "tin_ore", - tin_rocks_tourist_trap_2 = "tin_ore", - tin_rocks_tourist_trap_3 = "tin_ore", - tin_rocks_tutorial_island_1 = "tin_ore", -} diff --git a/data/skill/mining/ores.tables.toml b/data/skill/mining/ores.tables.toml index 47228bd1d1..57ab30cc1a 100644 --- a/data/skill/mining/ores.tables.toml +++ b/data/skill/mining/ores.tables.toml @@ -21,30 +21,30 @@ life = 42 chance = [30, 375] [.limestone] -level = 1 +level = 10 xp = 265 chance = [25, 200] [.uncut_diamond] -level = 1 +level = 40 xp = 650 life = 99 chance = [8, 8] [.uncut_ruby] -level = 1 +level = 40 xp = 650 life = 99 chance = [10, 10] [.uncut_emerald] -level = 1 +level = 40 xp = 650 life = 99 chance = [10, 10] [.uncut_sapphire] -level = 1 +level = 40 xp = 650 life = 99 chance = [18, 18] @@ -56,13 +56,13 @@ life = 99 chance = [120, 120] [.uncut_jade] -level = 1 +level = 40 xp = 650 life = 99 chance = [60, 60] [.uncut_red_topaz] -level = 1 +level = 40 xp = 650 life = 99 chance = [30, 30] @@ -144,19 +144,19 @@ life = 7 chance = [25, 200] [.sandstone_2kg] -level = 1 +level = 35 xp = 400 life = 7 chance = [16, 100] [.sandstone_5kg] -level = 1 +level = 35 xp = 500 life = 7 chance = [8, 75] [.sandstone_10kg] -level = 1 +level = 35 xp = 600 life = 7 chance = [4, 50] @@ -168,13 +168,13 @@ life = 8 chance = [16, 100] [.granite_2kg] -level = 1 +level = 45 xp = 600 life = 8 chance = [8, 75] [.granite_5kg] -level = 1 +level = 45 xp = 750 life = 8 chance = [6, 64] @@ -185,6 +185,6 @@ xp = 50 chance = [200, 400] [.pure_essence] -level = 1 +level = 30 xp = 50 chance = [150, 350] diff --git a/data/skill/mining/rocks.tables.toml b/data/skill/mining/rocks.tables.toml new file mode 100644 index 0000000000..e46908ddaa --- /dev/null +++ b/data/skill/mining/rocks.tables.toml @@ -0,0 +1,1095 @@ +[rocks] +row_id = "obj" +ores = "list" + +[.adamantite_rocks_black_1] +ores = ["adamantite_ore"] + +[.adamantite_rocks_black_2] +ores = ["adamantite_ore"] + +[.adamantite_rocks_black_3] +ores = ["adamantite_ore"] + +[.adamantite_rocks_crandor_1] +ores = ["adamantite_ore"] + +[.adamantite_rocks_crandor_2] +ores = ["adamantite_ore"] + +[.adamantite_rocks_crandor_3] +ores = ["adamantite_ore"] + +[.adamantite_rocks_dirt_1] +ores = ["adamantite_ore"] + +[.adamantite_rocks_dirt_2] +ores = ["adamantite_ore"] + +[.adamantite_rocks_dirt_3] +ores = ["adamantite_ore"] + +[.adamantite_rocks_dungeon_1] +ores = ["adamantite_ore"] + +[.adamantite_rocks_dungeon_2] +ores = ["adamantite_ore"] + +[.adamantite_rocks_dungeon_3] +ores = ["adamantite_ore"] + +[.adamantite_rocks_falador_mine_1] +ores = ["adamantite_ore"] + +[.adamantite_rocks_falador_mine_3] +ores = ["adamantite_ore"] + +[.adamantite_rocks_grey_1] +ores = ["adamantite_ore"] + +[.adamantite_rocks_grey_2] +ores = ["adamantite_ore"] + +[.adamantite_rocks_grey_3] +ores = ["adamantite_ore"] + +[.adamantite_rocks_lava_maze_dungeon_1] +ores = ["adamantite_ore"] + +[.adamantite_rocks_lava_maze_dungeon_2] +ores = ["adamantite_ore"] + +[.adamantite_rocks_lava_maze_dungeon_3] +ores = ["adamantite_ore"] + +[.adamantite_rocks_light_1] +ores = ["adamantite_ore"] + +[.adamantite_rocks_light_2] +ores = ["adamantite_ore"] + +[.adamantite_rocks_light_3] +ores = ["adamantite_ore"] + +[.adamantite_rocks_old_1] +ores = ["adamantite_ore"] + +[.adamantite_rocks_old_2] +ores = ["adamantite_ore"] + +[.adamantite_rocks_rock_1] +ores = ["adamantite_ore"] + +[.adamantite_rocks_rock_2] +ores = ["adamantite_ore"] + +[.adamantite_rocks_rock_3] +ores = ["adamantite_ore"] + +[.adamantite_rocks_tourist_trap_1] +ores = ["adamantite_ore"] + +[.adamantite_rocks_tourist_trap_2] +ores = ["adamantite_ore"] + +[.adamantite_rocks_tourist_trap_3] +ores = ["adamantite_ore"] + +[.adamantite_rocks_tzhaar_1] +ores = ["adamantite_ore"] + +[.adamantite_rocks_tzhaar_2] +ores = ["adamantite_ore"] + +[.adamantite_rocks_tzhaar_3] +ores = ["adamantite_ore"] + +[.blurite_rocks_asgarnian_ice_1] +ores = ["blurite_ore"] + +[.blurite_rocks_asgarnian_ice_2] +ores = ["blurite_ore"] + +[.blurite_rocks_ice_1] +ores = ["blurite_ore"] + +[.blurite_rocks_ice_2] +ores = ["blurite_ore"] + +[.blurite_rocks_lumbridge_cellar_1] +ores = ["blurite_ore"] + +[.blurite_rocks_lumbridge_cellar_2] +ores = ["blurite_ore"] + +[.blurite_rocks_lumbridge_cellar_3] +ores = ["blurite_ore"] + +[.clay_rocks_dirt_1] +ores = ["clay"] + +[.clay_rocks_dirt_2] +ores = ["clay"] + +[.clay_rocks_dirt_3] +ores = ["clay"] + +[.clay_rocks_falador_mine_1] +ores = ["clay"] + +[.clay_rocks_falador_mine_2] +ores = ["clay"] + +[.clay_rocks_lava_maze_dungeon_1] +ores = ["clay"] + +[.clay_rocks_lava_maze_dungeon_2] +ores = ["clay"] + +[.clay_rocks_lava_maze_dungeon_3] +ores = ["clay"] + +[.clay_rocks_light_1] +ores = ["clay"] + +[.clay_rocks_light_2] +ores = ["clay"] + +[.clay_rocks_light_3] +ores = ["clay"] + +[.clay_rocks_mud_1] +ores = ["clay"] + +[.clay_rocks_mud_2] +ores = ["clay"] + +[.clay_rocks_mud_3] +ores = ["clay"] + +[.clay_rocks_old_1] +ores = ["clay"] + +[.clay_rocks_old_2] +ores = ["clay"] + +[.clay_rocks_piscatoris_1] +ores = ["clay"] + +[.clay_rocks_piscatoris_2] +ores = ["clay"] + +[.clay_rocks_quarry_2] +ores = ["clay"] + +[.clay_rocks_rimmington_1] +ores = ["clay"] + +[.clay_rocks_rimmington_2] +ores = ["clay"] + +[.clay_rocks_rimmington_3] +ores = ["clay"] + +[.clay_rocks_rock_1] +ores = ["clay"] + +[.clay_rocks_rock_2] +ores = ["clay"] + +[.clay_rocks_rock_3] +ores = ["clay"] + +[.coal_rocks_black_1] +ores = ["coal"] + +[.coal_rocks_black_2] +ores = ["coal"] + +[.coal_rocks_black_3] +ores = ["coal"] + +[.coal_rocks_crandor_1] +ores = ["coal"] + +[.coal_rocks_crandor_2] +ores = ["coal"] + +[.coal_rocks_crandor_3] +ores = ["coal"] + +[.coal_rocks_dirt_1] +ores = ["coal"] + +[.coal_rocks_dirt_2] +ores = ["coal"] + +[.coal_rocks_dirt_3] +ores = ["coal"] + +[.coal_rocks_dungeon_1] +ores = ["coal"] + +[.coal_rocks_dungeon_2] +ores = ["coal"] + +[.coal_rocks_dungeon_3] +ores = ["coal"] + +[.coal_rocks_falador_mine_1] +ores = ["coal"] + +[.coal_rocks_falador_mine_2] +ores = ["coal"] + +[.coal_rocks_falador_mine_3] +ores = ["coal"] + +[.coal_rocks_lava_maze_dungeon_1] +ores = ["coal"] + +[.coal_rocks_lava_maze_dungeon_2] +ores = ["coal"] + +[.coal_rocks_lava_maze_dungeon_3] +ores = ["coal"] + +[.coal_rocks_light_1] +ores = ["coal"] + +[.coal_rocks_light_2] +ores = ["coal"] + +[.coal_rocks_light_3] +ores = ["coal"] + +[.coal_rocks_misc_expansion_1] +ores = ["coal"] + +[.coal_rocks_misc_expansion_2] +ores = ["coal"] + +[.coal_rocks_misc_expansion_3] +ores = ["coal"] + +[.coal_rocks_mud_1] +ores = ["coal"] + +[.coal_rocks_mud_2] +ores = ["coal"] + +[.coal_rocks_mud_3] +ores = ["coal"] + +[.coal_rocks_old_1] +ores = ["coal"] + +[.coal_rocks_old_2] +ores = ["coal"] + +[.coal_rocks_quarry_1] +ores = ["coal"] + +[.coal_rocks_rat_pit_1] +ores = ["coal"] + +[.coal_rocks_rat_pit_2] +ores = ["coal"] + +[.coal_rocks_rock_1] +ores = ["coal"] + +[.coal_rocks_rock_2] +ores = ["coal"] + +[.coal_rocks_rock_3] +ores = ["coal"] + +[.coal_rocks_sand_1] +ores = ["coal"] + +[.coal_rocks_sand_2] +ores = ["coal"] + +[.coal_rocks_sand_3] +ores = ["coal"] + +[.coal_rocks_tzhaar_1] +ores = ["coal"] + +[.coal_rocks_tzhaar_2] +ores = ["coal"] + +[.coal_rocks_tzhaar_3] +ores = ["coal"] + +[.copper_rocks_crandor_1] +ores = ["copper_ore"] + +[.copper_rocks_crandor_2] +ores = ["copper_ore"] + +[.copper_rocks_crandor_3] +ores = ["copper_ore"] + +[.copper_rocks_dungeon_1] +ores = ["copper_ore"] + +[.copper_rocks_dungeon_2] +ores = ["copper_ore"] + +[.copper_rocks_dungeon_3] +ores = ["copper_ore"] + +[.copper_rocks_falador_mine_1] +ores = ["copper_ore"] + +[.copper_rocks_falador_mine_2] +ores = ["copper_ore"] + +[.copper_rocks_falador_mine_3] +ores = ["copper_ore"] + +[.copper_rocks_lava_maze_dungeon_1] +ores = ["copper_ore"] + +[.copper_rocks_lava_maze_dungeon_2] +ores = ["copper_ore"] + +[.copper_rocks_lava_maze_dungeon_3] +ores = ["copper_ore"] + +[.copper_rocks_light_1] +ores = ["copper_ore"] + +[.copper_rocks_light_2] +ores = ["copper_ore"] + +[.copper_rocks_light_2_1] +ores = ["copper_ore"] + +[.copper_rocks_light_2_2] +ores = ["copper_ore"] + +[.copper_rocks_light_2_3] +ores = ["copper_ore"] + +[.copper_rocks_light_3] +ores = ["copper_ore"] + +[.copper_rocks_light_3_1] +ores = ["copper_ore"] + +[.copper_rocks_mud_1] +ores = ["copper_ore"] + +[.copper_rocks_mud_2] +ores = ["copper_ore"] + +[.copper_rocks_mud_3] +ores = ["copper_ore"] + +[.copper_rocks_old_1] +ores = ["copper_ore"] + +[.copper_rocks_old_2] +ores = ["copper_ore"] + +[.copper_rocks_piscatoris_1] +ores = ["copper_ore"] + +[.copper_rocks_piscatoris_2] +ores = ["copper_ore"] + +[.copper_rocks_rimmington_1] +ores = ["copper_ore"] + +[.copper_rocks_rimmington_2] +ores = ["copper_ore"] + +[.copper_rocks_rimmington_3] +ores = ["copper_ore"] + +[.copper_rocks_rock_1] +ores = ["copper_ore"] + +[.copper_rocks_rock_2] +ores = ["copper_ore"] + +[.copper_rocks_rock_3] +ores = ["copper_ore"] + +[.copper_rocks_sand_1] +ores = ["copper_ore"] + +[.copper_rocks_sand_2] +ores = ["copper_ore"] + +[.copper_rocks_sand_3] +ores = ["copper_ore"] + +[.copper_rocks_tourist_trap_1] +ores = ["copper_ore"] + +[.copper_rocks_tourist_trap_2] +ores = ["copper_ore"] + +[.copper_rocks_tourist_trap_3] +ores = ["copper_ore"] + +[.copper_rocks_tutorial_island_1] +ores = ["copper_ore"] + +[.crashed_star_tier_1] +ores = ["stardust"] + +[.crashed_star_tier_2] +ores = ["stardust"] + +[.crashed_star_tier_3] +ores = ["stardust"] + +[.crashed_star_tier_4] +ores = ["stardust"] + +[.crashed_star_tier_5] +ores = ["stardust"] + +[.crashed_star_tier_6] +ores = ["stardust"] + +[.crashed_star_tier_7] +ores = ["stardust"] + +[.crashed_star_tier_8] +ores = ["stardust"] + +[.crashed_star_tier_9] +ores = ["stardust"] + +[.gem_rocks_ingneous_1] +ores = ["uncut_opal", "uncut_jade", "uncut_red_topaz", "uncut_sapphire", "uncut_emerald", "uncut_ruby", "uncut_diamond"] + +[.gem_rocks_ingneous_2] +ores = ["uncut_opal", "uncut_jade", "uncut_red_topaz", "uncut_sapphire", "uncut_emerald", "uncut_ruby", "uncut_diamond"] + +[.gem_rocks_ingneous_2_1] +ores = ["uncut_opal", "uncut_jade", "uncut_red_topaz", "uncut_sapphire", "uncut_emerald", "uncut_ruby", "uncut_diamond"] + +[.gem_rocks_ingneous_2_2] +ores = ["uncut_opal", "uncut_jade", "uncut_red_topaz", "uncut_sapphire", "uncut_emerald", "uncut_ruby", "uncut_diamond"] + +[.gem_rocks_ingneous_2_3] +ores = ["uncut_opal", "uncut_jade", "uncut_red_topaz", "uncut_sapphire", "uncut_emerald", "uncut_ruby", "uncut_diamond"] + +[.gem_rocks_ingneous_3] +ores = ["uncut_opal", "uncut_jade", "uncut_red_topaz", "uncut_sapphire", "uncut_emerald", "uncut_ruby", "uncut_diamond"] + +[.gem_rocks_lumbridge_cellar_1] +ores = ["uncut_opal", "uncut_jade", "uncut_red_topaz", "uncut_sapphire", "uncut_emerald", "uncut_ruby", "uncut_diamond"] + +[.gem_rocks_lumbridge_cellar_2] +ores = ["uncut_opal", "uncut_jade", "uncut_red_topaz", "uncut_sapphire", "uncut_emerald", "uncut_ruby", "uncut_diamond"] + +[.gem_rocks_lumbridge_cellar_3] +ores = ["uncut_opal", "uncut_jade", "uncut_red_topaz", "uncut_sapphire", "uncut_emerald", "uncut_ruby", "uncut_diamond"] + +[.gem_rocks_old_2] +ores = ["uncut_opal", "uncut_jade", "uncut_red_topaz", "uncut_sapphire", "uncut_emerald", "uncut_ruby", "uncut_diamond"] + +[.gold_rocks_crandor_1] +ores = ["gold_ore"] + +[.gold_rocks_crandor_2] +ores = ["gold_ore"] + +[.gold_rocks_crandor_3] +ores = ["gold_ore"] + +[.gold_rocks_dirt_1] +ores = ["gold_ore"] + +[.gold_rocks_dirt_2] +ores = ["gold_ore"] + +[.gold_rocks_dirt_3] +ores = ["gold_ore"] + +[.gold_rocks_dungeon_1] +ores = ["gold_ore"] + +[.gold_rocks_dungeon_3] +ores = ["gold_ore"] + +[.gold_rocks_falador_mine_1] +ores = ["gold_ore"] + +[.gold_rocks_falador_mine_2] +ores = ["gold_ore"] + +[.gold_rocks_grey_1] +ores = ["gold_ore"] + +[.gold_rocks_grey_2] +ores = ["gold_ore"] + +[.gold_rocks_grey_3] +ores = ["gold_ore"] + +[.gold_rocks_ingneous_1] +ores = ["gold_ore"] + +[.gold_rocks_ingneous_2] +ores = ["gold_ore"] + +[.gold_rocks_ingneous_3] +ores = ["gold_ore"] + +[.gold_rocks_lava_maze_dungeon_1] +ores = ["gold_ore"] + +[.gold_rocks_lava_maze_dungeon_2] +ores = ["gold_ore"] + +[.gold_rocks_lava_maze_dungeon_3] +ores = ["gold_ore"] + +[.gold_rocks_light_1] +ores = ["gold_ore"] + +[.gold_rocks_light_2] +ores = ["gold_ore"] + +[.gold_rocks_light_3] +ores = ["gold_ore"] + +[.gold_rocks_mud_1] +ores = ["gold_ore"] + +[.gold_rocks_mud_2] +ores = ["gold_ore"] + +[.gold_rocks_mud_3] +ores = ["gold_ore"] + +[.gold_rocks_old_1] +ores = ["gold_ore"] + +[.gold_rocks_old_2] +ores = ["gold_ore"] + +[.gold_rocks_rimmington_1] +ores = ["gold_ore"] + +[.gold_rocks_rimmington_2] +ores = ["gold_ore"] + +[.gold_rocks_rimmington_3] +ores = ["gold_ore"] + +[.gold_rocks_rock_1] +ores = ["gold_ore"] + +[.gold_rocks_rock_3] +ores = ["gold_ore"] + +[.gold_rocks_sand_1] +ores = ["gold_ore"] + +[.gold_rocks_sand_2] +ores = ["gold_ore"] + +[.gold_rocks_sand_3] +ores = ["gold_ore"] + +[.gold_rocks_tzhaar_1] +ores = ["gold_ore"] + +[.gold_rocks_tzhaar_2] +ores = ["gold_ore"] + +[.gold_rocks_tzhaar_3] +ores = ["gold_ore"] + +[.granite_rocks_quarry] +ores = ["granite_5kg", "granite_2kg", "granite_500g"] + +[.iron_rocks_black_1] +ores = ["iron_ore"] + +[.iron_rocks_black_2] +ores = ["iron_ore"] + +[.iron_rocks_black_3] +ores = ["iron_ore"] + +[.iron_rocks_crandor_1] +ores = ["iron_ore"] + +[.iron_rocks_crandor_2] +ores = ["iron_ore"] + +[.iron_rocks_crandor_3] +ores = ["iron_ore"] + +[.iron_rocks_dirt_1] +ores = ["iron_ore"] + +[.iron_rocks_dirt_2] +ores = ["iron_ore"] + +[.iron_rocks_dirt_3] +ores = ["iron_ore"] + +[.iron_rocks_dungeon_1] +ores = ["iron_ore"] + +[.iron_rocks_dungeon_2] +ores = ["iron_ore"] + +[.iron_rocks_dungeon_3] +ores = ["iron_ore"] + +[.iron_rocks_falador_mine_1] +ores = ["iron_ore"] + +[.iron_rocks_falador_mine_2] +ores = ["iron_ore"] + +[.iron_rocks_falador_mine_3] +ores = ["iron_ore"] + +[.iron_rocks_light_1] +ores = ["iron_ore"] + +[.iron_rocks_light_2] +ores = ["iron_ore"] + +[.iron_rocks_light_3] +ores = ["iron_ore"] + +[.iron_rocks_lumbridge_cellar_1] +ores = ["iron_ore"] + +[.iron_rocks_lumbridge_cellar_2] +ores = ["iron_ore"] + +[.iron_rocks_mud_1] +ores = ["iron_ore"] + +[.iron_rocks_mud_2] +ores = ["iron_ore"] + +[.iron_rocks_mud_3] +ores = ["iron_ore"] + +[.iron_rocks_old_1] +ores = ["iron_ore"] + +[.iron_rocks_old_2] +ores = ["iron_ore"] + +[.iron_rocks_piscatoris_1] +ores = ["iron_ore"] + +[.iron_rocks_piscatoris_2] +ores = ["iron_ore"] + +[.iron_rocks_piscatoris_2_1] +ores = ["iron_ore"] + +[.iron_rocks_piscatoris_2_2] +ores = ["iron_ore"] + +[.iron_rocks_rat_pit_1] +ores = ["iron_ore"] + +[.iron_rocks_rat_pit_2] +ores = ["iron_ore"] + +[.iron_rocks_rimmington_1] +ores = ["iron_ore"] + +[.iron_rocks_rimmington_2] +ores = ["iron_ore"] + +[.iron_rocks_rimmington_3] +ores = ["iron_ore"] + +[.iron_rocks_rock_1] +ores = ["iron_ore"] + +[.iron_rocks_rock_2] +ores = ["iron_ore"] + +[.iron_rocks_rock_3] +ores = ["iron_ore"] + +[.iron_rocks_sand_1] +ores = ["iron_ore"] + +[.iron_rocks_sand_2] +ores = ["iron_ore"] + +[.iron_rocks_sand_3] +ores = ["iron_ore"] + +[.mithril_rocks_black_1] +ores = ["mithril_ore"] + +[.mithril_rocks_black_2] +ores = ["mithril_ore"] + +[.mithril_rocks_black_3] +ores = ["mithril_ore"] + +[.mithril_rocks_dirt_1] +ores = ["mithril_ore"] + +[.mithril_rocks_dirt_2] +ores = ["mithril_ore"] + +[.mithril_rocks_dirt_3] +ores = ["mithril_ore"] + +[.mithril_rocks_dungeon_1] +ores = ["mithril_ore"] + +[.mithril_rocks_dungeon_2] +ores = ["mithril_ore"] + +[.mithril_rocks_dungeon_3] +ores = ["mithril_ore"] + +[.mithril_rocks_falador_mine_1] +ores = ["mithril_ore"] + +[.mithril_rocks_falador_mine_2] +ores = ["mithril_ore"] + +[.mithril_rocks_falador_mine_3] +ores = ["mithril_ore"] + +[.mithril_rocks_lava_maze_dungeon_1] +ores = ["mithril_ore"] + +[.mithril_rocks_lava_maze_dungeon_2] +ores = ["mithril_ore"] + +[.mithril_rocks_lava_maze_dungeon_3] +ores = ["mithril_ore"] + +[.mithril_rocks_light_1] +ores = ["mithril_ore"] + +[.mithril_rocks_light_2] +ores = ["mithril_ore"] + +[.mithril_rocks_light_3] +ores = ["mithril_ore"] + +[.mithril_rocks_mud_1] +ores = ["mithril_ore"] + +[.mithril_rocks_mud_2] +ores = ["mithril_ore"] + +[.mithril_rocks_mud_3] +ores = ["mithril_ore"] + +[.mithril_rocks_old_1] +ores = ["mithril_ore"] + +[.mithril_rocks_old_2] +ores = ["mithril_ore"] + +[.mithril_rocks_rock_1] +ores = ["mithril_ore"] + +[.mithril_rocks_rock_2] +ores = ["mithril_ore"] + +[.mithril_rocks_rock_3] +ores = ["mithril_ore"] + +[.mithril_rocks_tourist_trap_1] +ores = ["mithril_ore"] + +[.mithril_rocks_tourist_trap_2] +ores = ["mithril_ore"] + +[.mithril_rocks_tourist_trap_3] +ores = ["mithril_ore"] + +[.mithril_rocks_tzhaar_1] +ores = ["mithril_ore"] + +[.mithril_rocks_tzhaar_2] +ores = ["mithril_ore"] + +[.mithril_rocks_tzhaar_3] +ores = ["mithril_ore"] + +[.rune_essence_rocks] +ores = ["pure_essence", "rune_essence"] + +[.runite_rocks_black_1] +ores = ["runite_ore"] + +[.runite_rocks_black_2] +ores = ["runite_ore"] + +[.runite_rocks_black_3] +ores = ["runite_ore"] + +[.runite_rocks_dirt_1] +ores = ["runite_ore"] + +[.runite_rocks_dirt_2] +ores = ["runite_ore"] + +[.runite_rocks_dungeon_1] +ores = ["runite_ore"] + +[.runite_rocks_dungeon_3] +ores = ["runite_ore"] + +[.runite_rocks_grey_1] +ores = ["runite_ore"] + +[.runite_rocks_grey_2] +ores = ["runite_ore"] + +[.runite_rocks_grey_3] +ores = ["runite_ore"] + +[.runite_rocks_lava_maze_dungeon_1] +ores = ["runite_ore"] + +[.runite_rocks_lava_maze_dungeon_2] +ores = ["runite_ore"] + +[.runite_rocks_lava_maze_dungeon_3] +ores = ["runite_ore"] + +[.runite_rocks_old_1] +ores = ["runite_ore"] + +[.runite_rocks_old_2] +ores = ["runite_ore"] + +[.sandstone_rocks_quarry] +ores = ["sandstone_10kg", "sandstone_5kg", "sandstone_2kg", "sandstone_1kg"] + +[.silver_rocks_dirt_1] +ores = ["silver_ore"] + +[.silver_rocks_dirt_2] +ores = ["silver_ore"] + +[.silver_rocks_dirt_3] +ores = ["silver_ore"] + +[.silver_rocks_dungeon_1] +ores = ["silver_ore"] + +[.silver_rocks_dungeon_2] +ores = ["silver_ore"] + +[.silver_rocks_dungeon_3] +ores = ["silver_ore"] + +[.silver_rocks_ingneous_1] +ores = ["silver_ore"] + +[.silver_rocks_ingneous_2] +ores = ["silver_ore"] + +[.silver_rocks_ingneous_3] +ores = ["silver_ore"] + +[.silver_rocks_lava_maze_dungeon_1] +ores = ["silver_ore"] + +[.silver_rocks_lava_maze_dungeon_2] +ores = ["silver_ore"] + +[.silver_rocks_lava_maze_dungeon_3] +ores = ["silver_ore"] + +[.silver_rocks_light_1] +ores = ["silver_ore"] + +[.silver_rocks_light_2] +ores = ["silver_ore"] + +[.silver_rocks_light_3] +ores = ["silver_ore"] + +[.silver_rocks_lumbridge_cellar_1] +ores = ["silver_ore"] + +[.silver_rocks_lumbridge_cellar_2] +ores = ["silver_ore"] + +[.silver_rocks_mud_1] +ores = ["silver_ore"] + +[.silver_rocks_mud_2] +ores = ["silver_ore"] + +[.silver_rocks_mud_3] +ores = ["silver_ore"] + +[.silver_rocks_old_1] +ores = ["silver_ore"] + +[.silver_rocks_old_2] +ores = ["silver_ore"] + +[.silver_rocks_rimmington_1] +ores = ["silver_ore"] + +[.silver_rocks_rimmington_2] +ores = ["silver_ore"] + +[.silver_rocks_rimmington_2_1] +ores = ["silver_ore"] + +[.silver_rocks_rimmington_2_2] +ores = ["silver_ore"] + +[.silver_rocks_rimmington_2_3] +ores = ["silver_ore"] + +[.silver_rocks_rimmington_3] +ores = ["silver_ore"] + +[.silver_rocks_rock_1] +ores = ["silver_ore"] + +[.silver_rocks_rock_2] +ores = ["silver_ore"] + +[.silver_rocks_rock_2_1] +ores = ["silver_ore"] + +[.silver_rocks_rock_3] +ores = ["silver_ore"] + +[.silver_rocks_tzhaar_1] +ores = ["silver_ore"] + +[.silver_rocks_tzhaar_2] +ores = ["silver_ore"] + +[.silver_rocks_tzhaar_3] +ores = ["silver_ore"] + +[.tin_rocks_crandor_1] +ores = ["tin_ore"] + +[.tin_rocks_crandor_2] +ores = ["tin_ore"] + +[.tin_rocks_crandor_3] +ores = ["tin_ore"] + +[.tin_rocks_dungeon_1] +ores = ["tin_ore"] + +[.tin_rocks_dungeon_2] +ores = ["tin_ore"] + +[.tin_rocks_dungeon_3] +ores = ["tin_ore"] + +[.tin_rocks_falador_mine_1] +ores = ["tin_ore"] + +[.tin_rocks_falador_mine_2] +ores = ["tin_ore"] + +[.tin_rocks_falador_mine_3] +ores = ["tin_ore"] + +[.tin_rocks_lava_maze_dungeon_1] +ores = ["tin_ore"] + +[.tin_rocks_lava_maze_dungeon_2] +ores = ["tin_ore"] + +[.tin_rocks_lava_maze_dungeon_3] +ores = ["tin_ore"] + +[.tin_rocks_light_1] +ores = ["tin_ore"] + +[.tin_rocks_light_2] +ores = ["tin_ore"] + +[.tin_rocks_light_2_1] +ores = ["tin_ore"] + +[.tin_rocks_light_2_2] +ores = ["tin_ore"] + +[.tin_rocks_light_2_3] +ores = ["tin_ore"] + +[.tin_rocks_light_3] +ores = ["tin_ore"] + +[.tin_rocks_light_3_1] +ores = ["tin_ore"] + +[.tin_rocks_mud_1] +ores = ["tin_ore"] + +[.tin_rocks_mud_2] +ores = ["tin_ore"] + +[.tin_rocks_mud_3] +ores = ["tin_ore"] + +[.tin_rocks_old_1] +ores = ["tin_ore"] + +[.tin_rocks_old_2] +ores = ["tin_ore"] + +[.tin_rocks_piscatoris_1] +ores = ["tin_ore"] + +[.tin_rocks_piscatoris_2] +ores = ["tin_ore"] + +[.tin_rocks_rock_1] +ores = ["tin_ore"] + +[.tin_rocks_rock_2] +ores = ["tin_ore"] + +[.tin_rocks_rock_3] +ores = ["tin_ore"] + +[.tin_rocks_sand_1] +ores = ["tin_ore"] + +[.tin_rocks_sand_2] +ores = ["tin_ore"] + +[.tin_rocks_sand_3] +ores = ["tin_ore"] + +[.tin_rocks_tourist_trap_1] +ores = ["tin_ore"] + +[.tin_rocks_tourist_trap_2] +ores = ["tin_ore"] + +[.tin_rocks_tourist_trap_3] +ores = ["tin_ore"] + +[.tin_rocks_tutorial_island_1] +ores = ["tin_ore"] diff --git a/game/src/main/kotlin/content/area/kharidian_desert/DesertHeat.kt b/game/src/main/kotlin/content/area/kharidian_desert/DesertHeat.kt index 07b4384476..2c056f7a40 100644 --- a/game/src/main/kotlin/content/area/kharidian_desert/DesertHeat.kt +++ b/game/src/main/kotlin/content/area/kharidian_desert/DesertHeat.kt @@ -4,7 +4,7 @@ import content.entity.combat.hit.directHit import world.gregs.voidps.engine.Script import world.gregs.voidps.engine.client.message import world.gregs.voidps.engine.data.Settings -import world.gregs.voidps.engine.data.definition.EnumDefinitions +import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.chat.ChatType import world.gregs.voidps.engine.entity.character.player.equip.equipped @@ -98,6 +98,6 @@ class DesertHeat : Script { if (item == "") { return 0 } - return EnumDefinitions.intOrNull("desert_heat_delay", item) ?: default + return Tables.intOrNull("desert_clothing.${item}.heat_delay") ?: default } } diff --git a/game/src/main/kotlin/content/skill/mining/Mining.kt b/game/src/main/kotlin/content/skill/mining/Mining.kt index 36a686015a..5619fb71af 100644 --- a/game/src/main/kotlin/content/skill/mining/Mining.kt +++ b/game/src/main/kotlin/content/skill/mining/Mining.kt @@ -8,7 +8,6 @@ import world.gregs.voidps.engine.client.message import world.gregs.voidps.engine.client.variable.remaining import world.gregs.voidps.engine.client.variable.start import world.gregs.voidps.engine.client.variable.stop -import world.gregs.voidps.engine.data.definition.EnumDefinitions import world.gregs.voidps.engine.data.definition.Rows import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.World @@ -38,29 +37,6 @@ class Mining : Script { "uncut_diamond", ) - val gemRocks = setOf( - "uncut_opal", - "uncut_jade", - "uncut_red_topaz", - "uncut_sapphire", - "uncut_emerald", - "uncut_ruby", - "uncut_diamond", - ) - - val sandstone = setOf( - "sandstone_10kg", - "sandstone_5kg", - "sandstone_2kg", - "sandstone_1kg", - ) - - val granite = setOf( - "granite_5kg", - "granite_2kg", - "granite_500g", - ) - init { objectOperate("Mine") { (target) -> if (target.id.startsWith("depleted")) { @@ -78,8 +54,9 @@ class Mining : Script { message("Your inventory is too full to hold any more ore.") break } - val type = EnumDefinitions.stringOrNull("mining_ores", target.id) ?: break - val ore = Rows.getOrNull("ores.$type") ?: break + + val ores = Tables.itemListOrNull("rocks.${target.id}.ores") ?: break + val ore = Rows.getOrNull("ores.${ores.last()}") ?: break val stringId = target.def(this).stringId val level = if (stringId.startsWith("crashed_star_tier_")) { stringId.removePrefix("crashed_star_tier_").toInt() * 10 @@ -119,27 +96,20 @@ class Mining : Script { continue } } - var ores = mutableListOf() - when { - target.id == "rune_essence_rocks" -> { - if (World.members && has(Skill.Mining, 30)) { - ores.add("pure_essence") - } else { - ores.add("rune_essence") - } - } - ore.itemId == "granite_500g" -> ores.addAll(granite) - ore.itemId == "sandstone_1kg" -> ores.addAll(sandstone) - ore.itemId == "uncut_opal" -> ores.addAll(gemRocks) - else -> ores.add(ore.itemId) - } for (item in ores) { - val chance = Tables.intRange("ores.${item}.chance") + if (item == "pure_essence" && !World.members) { + continue + } + val ore = Rows.getOrNull("ores.$item") ?: continue + if (!has(Skill.Mining, ore.int("level"))) { + continue + } + val chance = ore.intRange("chance") if (success(levels.get(Skill.Mining), chance)) { - val xp = Tables.int("ores.${item}.xp") / 10.0 + val xp = ore.int("xp") / 10.0 exp(Skill.Mining, xp) ShootingStarHandler.extraOreHandler(this, item, xp) - if (!addOre(this, item) || deplete(target, Tables.int("ores.${item}.life"))) { + if (!addOre(this, item) || deplete(target, ore.int("life"))) { clearAnim() break } @@ -162,7 +132,7 @@ class Mining : Script { } message("You examine the rock for ores...") delay(4) - val ore = Rows.getOrNull("mining_ores.${target.def(this).stringId}") + val ore = Rows.getOrNull("ores.${target.def(this).stringId}") if (ore == null) { message("This rock contains no ore.") } else { From 4469ac32b66bf00affb03f3dc05a9ef3fbac6275 Mon Sep 17 00:00:00 2001 From: GregHib Date: Fri, 27 Mar 2026 16:48:42 +0000 Subject: [PATCH 38/40] Fix tests --- .../combination_runes.tables.toml | 2 +- .../runecrafting/runecrafting.enums.toml | 291 ++++++++++++++++++ .../engine/data/definition/TablesTest.kt | 2 +- .../engine/data/definition/test-table.toml | 32 +- .../content/skill/firemaking/Firemaking.kt | 4 +- .../skill/runecrafting/Runecrafting.kt | 2 +- .../content/skill/thieving/Pickpocketing.kt | 2 +- .../CombinationRunecraftingTest.kt | 11 +- 8 files changed, 319 insertions(+), 27 deletions(-) create mode 100644 data/skill/runecrafting/runecrafting.enums.toml diff --git a/data/skill/runecrafting/combination_runes.tables.toml b/data/skill/runecrafting/combination_runes.tables.toml index 12918efbd4..dec1bae58a 100644 --- a/data/skill/runecrafting/combination_runes.tables.toml +++ b/data/skill/runecrafting/combination_runes.tables.toml @@ -37,6 +37,6 @@ earth_rune_xp = 83 water_rune = "steam_rune" water_rune_xp = 100 air_rune = "smoke_rune" -water_rune_xp = 95 +air_rune_xp = 95 earth_rune = "lava_rune" earth_rune_xp = 105 diff --git a/data/skill/runecrafting/runecrafting.enums.toml b/data/skill/runecrafting/runecrafting.enums.toml new file mode 100644 index 0000000000..d00bf736c6 --- /dev/null +++ b/data/skill/runecrafting/runecrafting.enums.toml @@ -0,0 +1,291 @@ +[tiara_xp] +keyType = "item" +valueType = "int" +defaultInt = 0 +values = { + air_tiara = 250, + mind_tiara = 275, + water_tiara = 300, + body_tiara = 375, + earth_tiara = 325, + fire_tiara = 350, + cosmic_tiara = 400, + nature_tiara = 450, + chaos_tiara = 425, + law_tiara = 475, + death_tiara = 500, + blood_tiara = 525, +} + +[runecrafting_xp] +keyType = "item" +valueType = "int" +defaultInt = 0 +values = { + astral_rune = 87, + fire_rune = 70, + water_rune = 60, + air_rune = 50, + earth_rune = 65, + mind_rune = 55, + body_rune = 75, + death_rune = 100, + nature_rune = 90, + chaos_rune = 85, + law_rune = 95, + cosmic_rune = 80, + blood_rune = 105, + soul_rune = 297, +} + +[runecrafting_pure] +keyType = "item" +valueType = "int" +defaultInt = 0 +values = { + astral_rune = 1, + death_rune = 1, + nature_rune = 1, + chaos_rune = 1, + law_rune = 1, + cosmic_rune = 1, + blood_rune = 1, + soul_rune = 1, +} + +[runecrafting_level] +keyType = "item" +valueType = "int" +defaultInt = 1 +values = { + astral_rune = 40, + fire_rune = 14, + water_rune = 5, + earth_rune = 9, + mind_rune = 2, + body_rune = 20, + death_rune = 65, + nature_rune = 44, + chaos_rune = 35, + law_rune = 54, + cosmic_rune = 27, + blood_rune = 77, + soul_rune = 90, + steam_rune = 19, + mist_rune = 6, + dust_rune = 10, + smoke_rune = 15, + mud_rune = 13, + lava_rune = 23, +} + +[runecrafting_ourania_double_chance] +keyType = "item" +valueType = "int" +defaultInt = 0 +values = { + fire_rune = 250, + water_rune = 250, + air_rune = 250, + earth_rune = 250, + mind_rune = 250, + body_rune = 250, + death_rune = 175, + nature_rune = 225, + chaos_rune = 250, + law_rune = 200, + cosmic_rune = 250, + blood_rune = 150, + soul_rune = 100, +} + +[runecrafting_multiplier_astral_rune] +keyType = "item" +valueType = "int" +defaultInt = 0 +values = { + 0 = 40, + 1 = 82, +} + +[runecrafting_multiplier_fire_rune] +keyType = "item" +valueType = "int" +defaultInt = 0 +values = { + 0 = 14, + 1 = 35, + 2 = 70, +} + +[runecrafting_multiplier_water_rune] +keyType = "item" +valueType = "int" +defaultInt = 0 +values = { + 0 = 5, + 1 = 19, + 2 = 38, + 3 = 57, + 4 = 76, + 5 = 95, +} + +[runecrafting_multiplier_air_rune] +keyType = "item" +valueType = "int" +defaultInt = 0 +values = { + 0 = 1, + 1 = 11, + 2 = 22, + 3 = 33, + 4 = 44, + 5 = 55, + 6 = 66, + 7 = 77, + 8 = 88, + 9 = 99, +} + +[runecrafting_multiplier_earth_rune] +keyType = "item" +valueType = "int" +defaultInt = 0 +values = { + 0 = 9, + 1 = 26, + 2 = 52, + 3 = 78, +} + +[runecrafting_multiplier_mind_rune] +keyType = "item" +valueType = "int" +defaultInt = 0 +values = { + 0 = 2, + 1 = 14, + 2 = 28, + 3 = 42, + 4 = 56, + 5 = 84, + 6 = 98, +} + +[runecrafting_multiplier_body_rune] +keyType = "item" +valueType = "int" +defaultInt = 0 +values = { + 0 = 20, + 1 = 46, + 2 = 92, +} + +[runecrafting_multiplier_nature_rune] +keyType = "item" +valueType = "int" +defaultInt = 0 +values = { + 0 = 44, + 1 = 91, +} + +[runecrafting_multiplier_chaos_rune] +keyType = "item" +valueType = "int" +defaultInt = 0 +values = { + 0 = 35, + 1 = 74, +} + +[runecrafting_multiplier_cosmic_rune] +keyType = "item" +valueType = "int" +defaultInt = 0 +values = { + 0 = 27, + 1 = 59, +} + +[runecrafting_combination_water_altar] +keyType = "item" +valueType = "string" +defaultString = "" +values = { + fire_rune = "steam", + air_rune = "mist", + earth_rune = "mud", +} + +[runecrafting_combination_earth_altar] +keyType = "item" +valueType = "string" +defaultString = "" +values = { + fire_rune = "lava", + water_rune = "mud", + air_rune = "dust", +} + +[runecrafting_combination_air_altar] +keyType = "item" +valueType = "string" +defaultString = "" +values = { + fire_rune = "smoke", + water_rune = "mist", + earth_rune = "dust", +} + +[runecrafting_combination_fire_altar] +keyType = "item" +valueType = "string" +defaultString = "" +values = { + water_rune = "steam", + air_rune = "smoke", + earth_rune = "lava", +} + +[runecrafting_combination_water_altar_xp] +keyType = "item" +valueType = "int" +defaultInt = 0 +values = { + fire_rune = 93, + air_rune = 85, + earth_rune = 93, +} + +[runecrafting_combination_earth_altar_xp] +keyType = "item" +valueType = "int" +defaultInt = 0 +values = { + fire_rune = 100, + water_rune = 95, + air_rune = 90, +} + +[runecrafting_combination_air_altar_xp] +keyType = "item" +valueType = "int" +defaultInt = 0 +values = { + fire_rune = 85, + water_rune = 80, + earth_rune = 83, +} + +[runecrafting_combination_fire_altar_xp] +keyType = "item" +valueType = "int" +defaultInt = 0 +values = { + water_rune = 100, + air_rune = 95, + earth_rune = 105, +} \ No newline at end of file diff --git a/engine/src/test/kotlin/world/gregs/voidps/engine/data/definition/TablesTest.kt b/engine/src/test/kotlin/world/gregs/voidps/engine/data/definition/TablesTest.kt index d8e9fd817c..8b1144f437 100644 --- a/engine/src/test/kotlin/world/gregs/voidps/engine/data/definition/TablesTest.kt +++ b/engine/src/test/kotlin/world/gregs/voidps/engine/data/definition/TablesTest.kt @@ -53,7 +53,7 @@ class TablesTest { assertContentEquals(intArrayOf(0, 1), definition.rows) assertTrue(Rows.loaded) - val row = Rows.getOrNull("row") + val row = Rows.getOrNull("header.row") assertNotNull(row) val expected = arrayOf( 1, diff --git a/engine/src/test/resources/world/gregs/voidps/engine/data/definition/test-table.toml b/engine/src/test/resources/world/gregs/voidps/engine/data/definition/test-table.toml index fbd80bf65b..7a65fa97c3 100644 --- a/engine/src/test/resources/world/gregs/voidps/engine/data/definition/test-table.toml +++ b/engine/src/test/resources/world/gregs/voidps/engine/data/definition/test-table.toml @@ -1,20 +1,20 @@ [header] -int_field = "Int" -string_field = "String" -item_field = "Item" -obj_field = "GameObject" -npc_field = "NPC" -int_list = "List" -str_list = "List" -item_list = "List" -obj_list = "List" -npc_list = "List" -int_int = "Pair" -str_int = "Pair" -int_str = "Pair" -int_int_list = "List>" -str_int_list = "List>" -int_str_list = "List>" +int_field = "int" +string_field = "string" +item_field = "item" +obj_field = "obj" +npc_field = "npc" +int_list = "list" +str_list = "list" +item_list = "list" +obj_list = "list" +npc_list = "list" +int_int = "pair" +str_int = "pair" +int_str = "pair" +int_int_list = "list>" +str_int_list = "list>" +int_str_list = "list>" [.row] string_field = "text" diff --git a/game/src/main/kotlin/content/skill/firemaking/Firemaking.kt b/game/src/main/kotlin/content/skill/firemaking/Firemaking.kt index a8a78acd2b..bc2279c566 100644 --- a/game/src/main/kotlin/content/skill/firemaking/Firemaking.kt +++ b/game/src/main/kotlin/content/skill/firemaking/Firemaking.kt @@ -7,8 +7,8 @@ import world.gregs.voidps.engine.client.ui.closeDialogue import world.gregs.voidps.engine.client.variable.remaining import world.gregs.voidps.engine.client.variable.start import world.gregs.voidps.engine.data.config.RowDefinition -import world.gregs.voidps.engine.data.definition.EnumDefinitions import world.gregs.voidps.engine.data.definition.Rows +import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.character.mode.interact.Interact import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.chat.ChatType @@ -32,7 +32,7 @@ class Firemaking : Script { val directions = listOf(Direction.WEST, Direction.EAST, Direction.SOUTH, Direction.NORTH) - fun burnable(id: String) = EnumDefinitions.intOrNull("firemaking_xp", id) != null + fun burnable(id: String) = Tables.intOrNull("firemaking.${id}.xp") != null init { itemOnItem("tinderbox*", "*logs*") { fromItem, toItem, fromSlot, toSlot -> diff --git a/game/src/main/kotlin/content/skill/runecrafting/Runecrafting.kt b/game/src/main/kotlin/content/skill/runecrafting/Runecrafting.kt index 32a8cda461..5e7d680f70 100644 --- a/game/src/main/kotlin/content/skill/runecrafting/Runecrafting.kt +++ b/game/src/main/kotlin/content/skill/runecrafting/Runecrafting.kt @@ -82,7 +82,7 @@ class Runecrafting : Script { message("You need pure essence to bind $combination runes.") } TransactionError.None -> { - exp(Skill.Runecrafting, (combo.int("xp") / 10.0) * successes) + exp(Skill.Runecrafting, (combo.int("${item.id}_xp") / 10.0) * successes) if (bindingNecklace && equipment.discharge(this, EquipSlot.Amulet.index)) { val charge = equipment.charges(this, EquipSlot.Amulet.index) if (charge > 0) { diff --git a/game/src/main/kotlin/content/skill/thieving/Pickpocketing.kt b/game/src/main/kotlin/content/skill/thieving/Pickpocketing.kt index 67c68805e8..5a1f790b52 100644 --- a/game/src/main/kotlin/content/skill/thieving/Pickpocketing.kt +++ b/game/src/main/kotlin/content/skill/thieving/Pickpocketing.kt @@ -53,7 +53,7 @@ class Pickpocketing(val combatDefinitions: CombatDefinitions, val dropTables: Dr return } val type = Tables.stringOrNull("pickpocket.${target.id}.type") ?: return - val pickpocket = Rows.getOrNull("thieving_types.${target.id}") ?: return + val pickpocket = Rows.getOrNull("thieving_types.${type}") ?: return val level = pickpocket.int("level") if (!has(Skill.Thieving, level)) { return diff --git a/game/src/test/kotlin/content/skill/runecrafting/CombinationRunecraftingTest.kt b/game/src/test/kotlin/content/skill/runecrafting/CombinationRunecraftingTest.kt index 098f0b81a9..f7a304072c 100644 --- a/game/src/test/kotlin/content/skill/runecrafting/CombinationRunecraftingTest.kt +++ b/game/src/test/kotlin/content/skill/runecrafting/CombinationRunecraftingTest.kt @@ -12,6 +12,7 @@ import org.koin.test.get import world.gregs.voidps.engine.client.variable.start import world.gregs.voidps.engine.data.definition.EnumDefinitions import world.gregs.voidps.engine.data.definition.ItemDefinitions +import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.character.player.skill.Skill import world.gregs.voidps.engine.entity.obj.GameObjects import world.gregs.voidps.engine.inv.add @@ -33,11 +34,11 @@ internal class CombinationRunecraftingTest : WorldTest() { }) teleports = get() combinationsList.clear() - for (objectElement in elements) { - for ((rune, out) in EnumDefinitions.get("runecrafting_combination_${objectElement}_altar").map!!) { - val xp = EnumDefinitions.int("runecrafting_combination_${objectElement}_altar_xp", rune) / 10.0 - val element = ItemDefinitions.get(rune).stringId.removeSuffix("_rune") - combinationsList.add(listOf(element, objectElement, out as String, xp)) + for (row in Tables.get("combination_runes").rows()) { + for (element in elements) { + val combined = row.itemOrNull("${element}_rune") ?: continue + val xp = row.int("${element}_rune_xp") / 10.0 + combinationsList.add(listOf(element, row.itemId.removeSuffix("_altar"), combined.removeSuffix("_rune"), xp)) } } } From 45c4ebe4c459dca75398ec239fdbad228ca6f1db Mon Sep 17 00:00:00 2001 From: GregHib Date: Fri, 27 Mar 2026 16:51:05 +0000 Subject: [PATCH 39/40] Formatting --- .../kotlin/content/area/kharidian_desert/DesertHeat.kt | 2 +- .../content/area/kharidian_desert/al_kharid/Ellis.kt | 4 ++-- .../misthalin/draynor_village/wise_old_man/WiseOldMan.kt | 2 +- game/src/main/kotlin/content/skill/crafting/Pottery.kt | 2 +- game/src/main/kotlin/content/skill/crafting/Weaving.kt | 1 - .../main/kotlin/content/skill/firemaking/Firemaking.kt | 2 +- .../main/kotlin/content/skill/firemaking/LightSource.kt | 1 - game/src/main/kotlin/content/skill/fishing/Fishing.kt | 2 +- .../kotlin/content/skill/fletching/FletchUnfinished.kt | 2 +- .../main/kotlin/content/skill/herblore/HerbCleaning.kt | 1 - .../skill/magic/book/modern/EnchantCrossbowBolt.kt | 1 - .../content/skill/magic/book/modern/EnchantJewellery.kt | 4 ++-- game/src/main/kotlin/content/skill/runecrafting/Tiaras.kt | 2 +- game/src/main/kotlin/content/skill/slayer/EnchantedGem.kt | 3 +-- game/src/main/kotlin/content/skill/slayer/Slayer.kt | 8 ++++---- .../kotlin/content/skill/slayer/master/SlayerMaster.kt | 4 ++-- game/src/main/kotlin/content/skill/smithing/Anvil.kt | 2 +- game/src/main/kotlin/content/skill/smithing/Furnace.kt | 6 +++--- .../main/kotlin/content/skill/smithing/SuperheatItem.kt | 2 +- .../main/kotlin/content/skill/thieving/Pickpocketing.kt | 2 +- .../kotlin/content/skill/crafting/SilverCastingTest.kt | 2 +- .../skill/runecrafting/CombinationRunecraftingTest.kt | 2 -- .../kotlin/world/gregs/voidps/tools/EnumDefinitions.kt | 2 ++ 23 files changed, 27 insertions(+), 32 deletions(-) diff --git a/game/src/main/kotlin/content/area/kharidian_desert/DesertHeat.kt b/game/src/main/kotlin/content/area/kharidian_desert/DesertHeat.kt index 2c056f7a40..6bd5f0730d 100644 --- a/game/src/main/kotlin/content/area/kharidian_desert/DesertHeat.kt +++ b/game/src/main/kotlin/content/area/kharidian_desert/DesertHeat.kt @@ -98,6 +98,6 @@ class DesertHeat : Script { if (item == "") { return 0 } - return Tables.intOrNull("desert_clothing.${item}.heat_delay") ?: default + return Tables.intOrNull("desert_clothing.$item.heat_delay") ?: default } } diff --git a/game/src/main/kotlin/content/area/kharidian_desert/al_kharid/Ellis.kt b/game/src/main/kotlin/content/area/kharidian_desert/al_kharid/Ellis.kt index c937ae34ef..7653c5d0b8 100644 --- a/game/src/main/kotlin/content/area/kharidian_desert/al_kharid/Ellis.kt +++ b/game/src/main/kotlin/content/area/kharidian_desert/al_kharid/Ellis.kt @@ -91,8 +91,8 @@ class Ellis : Script { } val tanner = player["tanner", "ellis"] val primary = if (type.endsWith("_1")) "hard_" else "" - val leather = Tables.item("tanning.${item}.${primary}leather") - val cost = Tables.int("tanning.${item}.${primary}price_${tanner}") + val leather = Tables.item("tanning.$item.${primary}leather") + val cost = Tables.int("tanning.$item.${primary}price_$tanner") var tanned = 0 var noHides = false for (i in 0 until amount) { diff --git a/game/src/main/kotlin/content/area/misthalin/draynor_village/wise_old_man/WiseOldMan.kt b/game/src/main/kotlin/content/area/misthalin/draynor_village/wise_old_man/WiseOldMan.kt index a2e7517a88..b83200c03b 100644 --- a/game/src/main/kotlin/content/area/misthalin/draynor_village/wise_old_man/WiseOldMan.kt +++ b/game/src/main/kotlin/content/area/misthalin/draynor_village/wise_old_man/WiseOldMan.kt @@ -93,7 +93,7 @@ class WiseOldMan : Script { clear("wise_old_man_task") inc("wise_old_man_tasks_completed") - when (val reward = OldMansMessage.reward(this, Tables.bool("wise_old_man_items.${item}.hard"))) { + when (val reward = OldMansMessage.reward(this, Tables.bool("wise_old_man_items.$item.hard"))) { "runes" -> { items("nature_rune", "water_rune", "The Wise Old Man gives you some runes.") npc("Thank you, thank you! Please take these runes as a sign of my gratitude.") diff --git a/game/src/main/kotlin/content/skill/crafting/Pottery.kt b/game/src/main/kotlin/content/skill/crafting/Pottery.kt index 9a20e8045e..903feed389 100644 --- a/game/src/main/kotlin/content/skill/crafting/Pottery.kt +++ b/game/src/main/kotlin/content/skill/crafting/Pottery.kt @@ -68,7 +68,7 @@ class Pottery : Script { return } face(obj) - val pottery = Rows.getOrNull("pottery.${id}") ?: return + val pottery = Rows.getOrNull("pottery.$id") ?: return val level = pottery.int("level") if (!has(Skill.Crafting, level)) { message("You need a Crafting level of $level to make a ${id.toLowerSpaceCase()}.") diff --git a/game/src/main/kotlin/content/skill/crafting/Weaving.kt b/game/src/main/kotlin/content/skill/crafting/Weaving.kt index 2d16a88ce9..0579b34e69 100644 --- a/game/src/main/kotlin/content/skill/crafting/Weaving.kt +++ b/game/src/main/kotlin/content/skill/crafting/Weaving.kt @@ -87,5 +87,4 @@ class Weaving : Script { weave(obj, row, amount - 1) } } - } diff --git a/game/src/main/kotlin/content/skill/firemaking/Firemaking.kt b/game/src/main/kotlin/content/skill/firemaking/Firemaking.kt index bc2279c566..5c81e5ea34 100644 --- a/game/src/main/kotlin/content/skill/firemaking/Firemaking.kt +++ b/game/src/main/kotlin/content/skill/firemaking/Firemaking.kt @@ -32,7 +32,7 @@ class Firemaking : Script { val directions = listOf(Direction.WEST, Direction.EAST, Direction.SOUTH, Direction.NORTH) - fun burnable(id: String) = Tables.intOrNull("firemaking.${id}.xp") != null + fun burnable(id: String) = Tables.intOrNull("firemaking.$id.xp") != null init { itemOnItem("tinderbox*", "*logs*") { fromItem, toItem, fromSlot, toSlot -> diff --git a/game/src/main/kotlin/content/skill/firemaking/LightSource.kt b/game/src/main/kotlin/content/skill/firemaking/LightSource.kt index 6f2639a71d..7a405d7b57 100644 --- a/game/src/main/kotlin/content/skill/firemaking/LightSource.kt +++ b/game/src/main/kotlin/content/skill/firemaking/LightSource.kt @@ -2,7 +2,6 @@ package content.skill.firemaking import world.gregs.voidps.engine.Script import world.gregs.voidps.engine.client.message -import world.gregs.voidps.engine.data.definition.EnumDefinitions import world.gregs.voidps.engine.data.definition.Rows import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.character.player.chat.ChatType diff --git a/game/src/main/kotlin/content/skill/fishing/Fishing.kt b/game/src/main/kotlin/content/skill/fishing/Fishing.kt index 2802208ce1..4e6cd78217 100644 --- a/game/src/main/kotlin/content/skill/fishing/Fishing.kt +++ b/game/src/main/kotlin/content/skill/fishing/Fishing.kt @@ -85,7 +85,7 @@ class Fishing : Script { var bait: String? = null var required: String? = null for (fish in fish) { - val b = Tables.item("fishing.${fish}.bait") + val b = Tables.item("fishing.$fish.bait") if (required == null && b != "empty_box_fish") { required = b } diff --git a/game/src/main/kotlin/content/skill/fletching/FletchUnfinished.kt b/game/src/main/kotlin/content/skill/fletching/FletchUnfinished.kt index 6ebaa27a36..a59edb5efa 100644 --- a/game/src/main/kotlin/content/skill/fletching/FletchUnfinished.kt +++ b/game/src/main/kotlin/content/skill/fletching/FletchUnfinished.kt @@ -29,7 +29,7 @@ class FletchUnfinished : Script { maximum = 27, text = "What would you like to fletch?", ) - val unf = Rows.getOrNull("fletching_unf.${selected}") ?: return@weakQueue + val unf = Rows.getOrNull("fletching_unf.$selected") ?: return@weakQueue if (!has(Skill.Fletching, unf.int("level"), true)) { return@weakQueue } diff --git a/game/src/main/kotlin/content/skill/herblore/HerbCleaning.kt b/game/src/main/kotlin/content/skill/herblore/HerbCleaning.kt index 23cb572ea8..6a8563cd43 100644 --- a/game/src/main/kotlin/content/skill/herblore/HerbCleaning.kt +++ b/game/src/main/kotlin/content/skill/herblore/HerbCleaning.kt @@ -1,7 +1,6 @@ package content.skill.herblore import world.gregs.voidps.engine.Script -import world.gregs.voidps.engine.data.definition.EnumDefinitions import world.gregs.voidps.engine.data.definition.Rows import world.gregs.voidps.engine.entity.character.player.skill.Skill import world.gregs.voidps.engine.entity.character.player.skill.exp.exp diff --git a/game/src/main/kotlin/content/skill/magic/book/modern/EnchantCrossbowBolt.kt b/game/src/main/kotlin/content/skill/magic/book/modern/EnchantCrossbowBolt.kt index 8db7e5467e..b4eb112f01 100644 --- a/game/src/main/kotlin/content/skill/magic/book/modern/EnchantCrossbowBolt.kt +++ b/game/src/main/kotlin/content/skill/magic/book/modern/EnchantCrossbowBolt.kt @@ -7,7 +7,6 @@ import world.gregs.voidps.engine.client.ui.closeInterfaces import world.gregs.voidps.engine.client.ui.open import world.gregs.voidps.engine.client.variable.hasClock import world.gregs.voidps.engine.client.variable.start -import world.gregs.voidps.engine.data.definition.EnumDefinitions import world.gregs.voidps.engine.data.definition.SpellDefinitions import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.character.player.Player diff --git a/game/src/main/kotlin/content/skill/magic/book/modern/EnchantJewellery.kt b/game/src/main/kotlin/content/skill/magic/book/modern/EnchantJewellery.kt index 4a4a1ead90..638470545c 100644 --- a/game/src/main/kotlin/content/skill/magic/book/modern/EnchantJewellery.kt +++ b/game/src/main/kotlin/content/skill/magic/book/modern/EnchantJewellery.kt @@ -52,7 +52,7 @@ class EnchantJewellery : Script { "enchant_level_1" -> "enchant_jewellery_1" "enchant_level_2" -> "enchant_jewellery_2" else -> "enchant_jewellery_3" - } + }, ) sound("enchant_${type}_amulet") } else if (item.id.endsWith("ring")) { @@ -67,7 +67,7 @@ class EnchantJewellery : Script { "enchant_level_1" -> "enchant_jewellery_1" "enchant_level_2" -> "enchant_jewellery_2" else -> "enchant_jewellery_3" - } + }, ) } val xp = Tables.int("jewellery_enchant.$spell.xp") / 10.0 diff --git a/game/src/main/kotlin/content/skill/runecrafting/Tiaras.kt b/game/src/main/kotlin/content/skill/runecrafting/Tiaras.kt index 4f5b8cd9ce..e0eb6519f1 100644 --- a/game/src/main/kotlin/content/skill/runecrafting/Tiaras.kt +++ b/game/src/main/kotlin/content/skill/runecrafting/Tiaras.kt @@ -26,7 +26,7 @@ class Tiaras : Script { } fun Tiaras.bindTiara(player: Player, id: String) { - val xp = Tables.intOrNull("tiaras.${id}.xp") ?: return + val xp = Tables.intOrNull("tiaras.$id.xp") ?: return player.softTimers.start("runecrafting") val tiaraId = "tiara" val talismanId = id.replace("_tiara", "_talisman") diff --git a/game/src/main/kotlin/content/skill/slayer/EnchantedGem.kt b/game/src/main/kotlin/content/skill/slayer/EnchantedGem.kt index d93052283f..f2aea6f7d2 100644 --- a/game/src/main/kotlin/content/skill/slayer/EnchantedGem.kt +++ b/game/src/main/kotlin/content/skill/slayer/EnchantedGem.kt @@ -10,7 +10,6 @@ import net.pearx.kasechange.toLowerSpaceCase import net.pearx.kasechange.toSentenceCase import world.gregs.voidps.engine.Script import world.gregs.voidps.engine.client.message -import world.gregs.voidps.engine.data.definition.EnumDefinitions import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.character.player.name import world.gregs.voidps.engine.queue.queue @@ -96,7 +95,7 @@ class EnchantedGem : Script { fun ChoiceOption.anyTips() { option("Got any tips for me?") { - val tip = Tables.stringOrNull("${slayerMaster}_slayer_tasks.${slayerTask}.tip") ?: return@option + val tip = Tables.stringOrNull("${slayerMaster}_slayer_tasks.$slayerTask.tip") ?: return@option npc(slayerMaster, tip) choice { howAmIDoing() diff --git a/game/src/main/kotlin/content/skill/slayer/Slayer.kt b/game/src/main/kotlin/content/skill/slayer/Slayer.kt index 1c51e42742..b8e37a6c56 100644 --- a/game/src/main/kotlin/content/skill/slayer/Slayer.kt +++ b/game/src/main/kotlin/content/skill/slayer/Slayer.kt @@ -103,19 +103,19 @@ private fun rollTask(player: Player, master: String): Pair? { private fun hasRequirements(player: Player, table: TableDefinition, row: Int): Boolean { val category = Rows.get(row).itemId - val npc = Tables.int("slayer_tasks.${category}.npc") + val npc = Tables.int("slayer_tasks.$category.npc") val slayerLevel = NPCDefinitions.get(npc)["slayer_level", 1] if (!player.has(Skill.Slayer, slayerLevel)) { return false } - val combatLevel = Tables.int("slayer_tasks.${category}.combat_level") + val combatLevel = Tables.int("slayer_tasks.$category.combat_level") if (player.combatLevel < combatLevel) { return false } - val variable = Tables.stringOrNull("slayer_tasks.${category}.variable") + val variable = Tables.stringOrNull("slayer_tasks.$category.variable") if (variable != null && !player.contains(variable)) { return false } - val quest = table.stringOrNull("slayer_tasks.${category}.quest", row) ?: return true + val quest = table.stringOrNull("slayer_tasks.$category.quest", row) ?: return true return player.questCompleted(quest) } diff --git a/game/src/main/kotlin/content/skill/slayer/master/SlayerMaster.kt b/game/src/main/kotlin/content/skill/slayer/master/SlayerMaster.kt index b85b6628e7..8279af635d 100644 --- a/game/src/main/kotlin/content/skill/slayer/master/SlayerMaster.kt +++ b/game/src/main/kotlin/content/skill/slayer/master/SlayerMaster.kt @@ -118,7 +118,7 @@ class SlayerMaster : Script { npc("Excellent, you're doing great. Your new task is to kill $amount ${type.toSentenceCase()}.") choice { option("Got any tips for me?") { - val tip = Tables.string("${master}_slayer_tasks.${type}.tip") + val tip = Tables.string("${master}_slayer_tasks.$type.tip") npc(tip) } option("Okay, great!") @@ -138,7 +138,7 @@ class SlayerMaster : Script { inventory.add("enchanted_gem") choice { option("Got any tips for me?") { - val tip = Tables.string("${master}_slayer_tasks.${type}.tip") + val tip = Tables.string("${master}_slayer_tasks.$type.tip") npc(tip) } option("Okay, great!") { diff --git a/game/src/main/kotlin/content/skill/smithing/Anvil.kt b/game/src/main/kotlin/content/skill/smithing/Anvil.kt index 5ff7611ff2..05374c0073 100644 --- a/game/src/main/kotlin/content/skill/smithing/Anvil.kt +++ b/game/src/main/kotlin/content/skill/smithing/Anvil.kt @@ -136,7 +136,7 @@ class Anvil : Script { "mithril" if type == "grapple" -> "mithril_grapple_tip" else -> "${metal}_$type" } - val row = Rows.getOrNull("smithing.${item}") ?: return + val row = Rows.getOrNull("smithing.$item") ?: return val component = InterfaceDefinitions.getComponent("smithing", type) val quantity = component?.getOrNull("amount") ?: 1 val bars = component?.getOrNull("bars") ?: 1 diff --git a/game/src/main/kotlin/content/skill/smithing/Furnace.kt b/game/src/main/kotlin/content/skill/smithing/Furnace.kt index d9194cc0ee..e0cf65f28e 100644 --- a/game/src/main/kotlin/content/skill/smithing/Furnace.kt +++ b/game/src/main/kotlin/content/skill/smithing/Furnace.kt @@ -102,7 +102,7 @@ class Furnace : Script { return } - val row = Rows.getOrNull("bars.${id}") ?: return + val row = Rows.getOrNull("bars.$id") ?: return val level = row.int("level") if (!player.has(Skill.Smithing, level, message = true)) { player.softTimers.stop("smelting") @@ -151,7 +151,7 @@ class Furnace : Script { target: GameObject, id: String, items: List, - xp: Double + xp: Double, ): Boolean { if (target.id != "furnace_edgeville" || !player.inventory.contains(items)) { return false @@ -189,7 +189,7 @@ class Furnace : Script { } internal fun requiredOres(id: String): MutableList { - val row = Rows.getOrNull("bars.${id}") ?: return mutableListOf() + val row = Rows.getOrNull("bars.$id") ?: return mutableListOf() val items = mutableListOf() val ores = row.itemList("ore") val amounts = row.intList("amount") diff --git a/game/src/main/kotlin/content/skill/smithing/SuperheatItem.kt b/game/src/main/kotlin/content/skill/smithing/SuperheatItem.kt index 07c9387de1..ba51691093 100644 --- a/game/src/main/kotlin/content/skill/smithing/SuperheatItem.kt +++ b/game/src/main/kotlin/content/skill/smithing/SuperheatItem.kt @@ -27,7 +27,7 @@ class SuperheatItem(val spellDefinitions: SpellDefinitions) : Script { if (bar == "iron_bar" && inventory.count("coal") >= 2) { bar = "steel_bar" } - val row = Rows.getOrNull("bars.${bar}") ?: return@onItem + val row = Rows.getOrNull("bars.$bar") ?: return@onItem val level = row.int("level") if (!has(Skill.Smithing, level, message = true)) { sound("superheat_fail") diff --git a/game/src/main/kotlin/content/skill/thieving/Pickpocketing.kt b/game/src/main/kotlin/content/skill/thieving/Pickpocketing.kt index 5a1f790b52..c37d2adffb 100644 --- a/game/src/main/kotlin/content/skill/thieving/Pickpocketing.kt +++ b/game/src/main/kotlin/content/skill/thieving/Pickpocketing.kt @@ -53,7 +53,7 @@ class Pickpocketing(val combatDefinitions: CombatDefinitions, val dropTables: Dr return } val type = Tables.stringOrNull("pickpocket.${target.id}.type") ?: return - val pickpocket = Rows.getOrNull("thieving_types.${type}") ?: return + val pickpocket = Rows.getOrNull("thieving_types.$type") ?: return val level = pickpocket.int("level") if (!has(Skill.Thieving, level)) { return diff --git a/game/src/test/kotlin/content/skill/crafting/SilverCastingTest.kt b/game/src/test/kotlin/content/skill/crafting/SilverCastingTest.kt index e0df8d5418..50a4b202c7 100644 --- a/game/src/test/kotlin/content/skill/crafting/SilverCastingTest.kt +++ b/game/src/test/kotlin/content/skill/crafting/SilverCastingTest.kt @@ -29,4 +29,4 @@ class SilverCastingTest : WorldTest() { assertEquals(10, player.inventory.count("silver_bolts_unf")) assertNotEquals(0.0, player.experience.get(Skill.Crafting)) } -} \ No newline at end of file +} diff --git a/game/src/test/kotlin/content/skill/runecrafting/CombinationRunecraftingTest.kt b/game/src/test/kotlin/content/skill/runecrafting/CombinationRunecraftingTest.kt index f7a304072c..8bfa8f10e2 100644 --- a/game/src/test/kotlin/content/skill/runecrafting/CombinationRunecraftingTest.kt +++ b/game/src/test/kotlin/content/skill/runecrafting/CombinationRunecraftingTest.kt @@ -10,8 +10,6 @@ import org.junit.jupiter.api.DynamicTest.dynamicTest import org.junit.jupiter.api.TestFactory import org.koin.test.get import world.gregs.voidps.engine.client.variable.start -import world.gregs.voidps.engine.data.definition.EnumDefinitions -import world.gregs.voidps.engine.data.definition.ItemDefinitions import world.gregs.voidps.engine.data.definition.Tables import world.gregs.voidps.engine.entity.character.player.skill.Skill import world.gregs.voidps.engine.entity.obj.GameObjects diff --git a/tools/src/main/kotlin/world/gregs/voidps/tools/EnumDefinitions.kt b/tools/src/main/kotlin/world/gregs/voidps/tools/EnumDefinitions.kt index 5cae782b61..3d022bd0bd 100644 --- a/tools/src/main/kotlin/world/gregs/voidps/tools/EnumDefinitions.kt +++ b/tools/src/main/kotlin/world/gregs/voidps/tools/EnumDefinitions.kt @@ -18,6 +18,7 @@ import world.gregs.voidps.engine.data.definition.ItemDefinitions import world.gregs.voidps.engine.data.definition.NPCDefinitions import world.gregs.voidps.engine.data.definition.ObjectDefinitions import world.gregs.voidps.engine.data.definition.StructDefinitions +import world.gregs.voidps.engine.data.definition.Tables object EnumDefinitions { @@ -32,6 +33,7 @@ object EnumDefinitions { NPCDefinitions.init(NPCDecoder().load(cache)).load(files.list(Settings["definitions.npcs"])) StructDefinitions.init(StructDecoder().load(cache)).load(files.find(Settings["definitions.structs"])) ObjectDefinitions.init(ObjectDecoder().load(cache)).load(files.list(Settings["definitions.objects"])) + Tables.load(files.list(Settings["definitions.tables"])) val definitions = EnumDefinitions.init(EnumDecoder().load(cache)).load(files.list(Settings["definitions.enums"])) for (i in definitions.definitions.indices) { val def = definitions.getOrNull(i) ?: continue From 7bdc3bfd2c3f26bdd2686048ba35b696efa3953a Mon Sep 17 00:00:00 2001 From: GregHib Date: Fri, 27 Mar 2026 17:15:24 +0000 Subject: [PATCH 40/40] Fix fishing --- data/skill/fishing/fishing.tables.toml | 4 ++-- game/src/main/kotlin/content/skill/fishing/Fishing.kt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/data/skill/fishing/fishing.tables.toml b/data/skill/fishing/fishing.tables.toml index db15748f42..ab7647fbde 100644 --- a/data/skill/fishing/fishing.tables.toml +++ b/data/skill/fishing/fishing.tables.toml @@ -95,7 +95,7 @@ xp = 45 chance = [4, 55] [.raw_crayfish] -level = 0 +level = 1 xp = 10 chance = [48, 256] @@ -210,7 +210,7 @@ xp = 81 chance = [1, 1] [.raw_shrimps] -level = 0 +level = 1 xp = 10 chance = [48, 256] diff --git a/game/src/main/kotlin/content/skill/fishing/Fishing.kt b/game/src/main/kotlin/content/skill/fishing/Fishing.kt index 4e6cd78217..a6b486e84b 100644 --- a/game/src/main/kotlin/content/skill/fishing/Fishing.kt +++ b/game/src/main/kotlin/content/skill/fishing/Fishing.kt @@ -115,7 +115,7 @@ class Fishing : Script { } for (item in fish) { val row = Rows.getOrNull("fishing.$item") ?: continue - if (bait != row.itemOrNull("bait")) { + if (bait != row.item("bait")) { continue } val requiredLevel = row.int("level") @@ -123,7 +123,7 @@ class Fishing : Script { val experience = row.int("xp") val level = player.levels.get(Skill.Fishing) if (level >= requiredLevel && success(level, chance)) { - if (bait != "none" && !player.inventory.remove(bait)) { + if (bait != "empty_box_fish" && !player.inventory.remove(bait)) { break@fishing } player.exp(Skill.Fishing, experience.toDouble())