Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions data/skill/runecrafting/runecrafting.items.toml
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ limit = 100
weight = 1.0
slot = "Hat"
type = "HairMid"
talisman_tiara = { xp = 25.0, level = 1 }
examine = "A tiara infused with the properties of air."
kept = "Wilderness"

Expand All @@ -193,6 +194,7 @@ id = 5529
price = 14
limit = 100
weight = 1.0
talisman_tiara = { xp = 27.5, level = 1 }
slot = "Hat"
type = "HairMid"
examine = "A tiara infused with the properties of the mind."
Expand All @@ -206,6 +208,7 @@ id = 5531
price = 2481
limit = 100
weight = 1.0
talisman_tiara = { xp = 30.0, level = 1 }
slot = "Hat"
type = "HairMid"
examine = "A tiara infused with the properties of water."
Expand All @@ -219,6 +222,7 @@ id = 5533
price = 3
limit = 100
weight = 1.0
talisman_tiara = { xp = 37.5, level = 1 }
slot = "Hat"
type = "HairMid"
examine = "A tiara infused with the properties of the body."
Expand All @@ -232,6 +236,7 @@ id = 5535
price = 4
limit = 100
weight = 1.0
talisman_tiara = { xp = 32.5, level = 1 }
slot = "Hat"
type = "HairMid"
examine = "A tiara infused with the properties of the earth."
Expand All @@ -245,6 +250,7 @@ id = 5537
price = 10
limit = 100
weight = 1.0
talisman_tiara = { xp = 35.0, level = 1 }
slot = "Hat"
type = "HairMid"
examine = "A tiara infused with the properties of fire."
Expand All @@ -258,6 +264,7 @@ id = 5539
price = 4
limit = 100
weight = 1.0
talisman_tiara = { xp = 40.0, level = 1 }
slot = "Hat"
type = "HairMid"
examine = "A tiara infused with the properties of the cosmos."
Expand All @@ -270,6 +277,7 @@ id = 5541
price = 8
limit = 100
weight = 1.0
talisman_tiara = { xp = 45.0, level = 1 }
slot = "Hat"
type = "HairMid"
examine = "A tiara infused with the properties of nature."
Expand All @@ -282,6 +290,7 @@ id = 5543
price = 5
limit = 100
weight = 1.0
talisman_tiara = { xp = 42.5, level = 1 }
slot = "Hat"
type = "HairMid"
examine = "A tiara infused with the properties of chaos."
Expand All @@ -294,6 +303,7 @@ id = 5545
price = 3
limit = 100
weight = 1.0
talisman_tiara = { xp = 47.5, level = 1 }
slot = "Hat"
type = "HairMid"
examine = "A tiara infused with the properties of law."
Expand All @@ -306,6 +316,7 @@ id = 5547
price = 213
limit = 100
weight = 1.0
talisman_tiara = { xp = 50.0, level = 1 }
slot = "Hat"
type = "HairMid"
examine = "A tiara infused with the properties of death."
Expand All @@ -318,6 +329,7 @@ id = 5549
price = 11900
limit = 100
weight = 1.0
talisman_tiara = { xp = 52.5, level = 1 }
slot = "Hat"
type = "HairMid"
examine = "A tiara infused with the properties of blood."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ object ItemDefinitions : DefinitionsDecoder<ItemDefinition> {
"jewellery" -> extras[key] = Jewellery(this)
"silver_jewellery" -> extras[key] = Silver(this)
"runecrafting" -> extras[key] = Rune(this)
"talisman_tiara" -> extras[key] = Tiara(this)
"cleaning" -> extras[key] = Cleaning(this)
"fletch_dart" -> extras[key] = FletchDarts(this)
"fletch_bolts" -> extras[key] = FletchBolts(this)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package world.gregs.voidps.engine.data.definition.data

import world.gregs.config.ConfigReader

data class Tiara(
val xp: Double = 0.0,
val level: Int = 1,
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false

other as Tiara

if (xp != other.xp) return false
return level == other.level
}

override fun hashCode(): Int {
var result = xp.hashCode()
result = 31 * result + level

return result
}

companion object {
operator fun invoke(reader: ConfigReader): Tiara {
var xp = 0.0
var level = 1

while (reader.nextEntry()) {
when (val key = reader.key()) {
"xp" -> xp = reader.double()
"level" -> level = reader.int()
else -> throw IllegalArgumentException("Unexpected key: '$key' ${reader.exception()}")
}
}

return Tiara(xp = xp, level = level)
}
}
}
55 changes: 55 additions & 0 deletions game/src/main/kotlin/content/skill/runecrafting/Tiaras.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package content.skill.runecrafting

import com.github.michaelbull.logging.InlineLogger
import world.gregs.voidps.cache.definition.data.ItemDefinition
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.ItemDefinitions
import world.gregs.voidps.engine.data.definition.data.Tiara
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.sound
import world.gregs.voidps.engine.inv.inventory
import world.gregs.voidps.engine.inv.transact.TransactionError
import world.gregs.voidps.engine.inv.transact.operation.AddItem.add
import world.gregs.voidps.engine.inv.transact.operation.RemoveItem.remove

class Tiaras : Script {

Check warning on line 19 in game/src/main/kotlin/content/skill/runecrafting/Tiaras.kt

View workflow job for this annotation

GitHub Actions / qodana

Unused symbol

Class "Tiaras" is never used

val logger = InlineLogger()

init {
itemOnObjectOperate("tiara", "*_altar") { (target) ->
val id = target.id.replace("_altar", "_tiara")
bindTiara(this, id, ItemDefinitions.get(id))
}
}

fun Tiaras.bindTiara(player: Player, id: String, itemDefinition: ItemDefinition) {
val tiara: Tiara = itemDefinition.getOrNull("talisman_tiara") ?: return
player.softTimers.start("runecrafting")
val tiaraId = "tiara"
val talismanId = id.replace("_tiara", "_talisman")
player.inventory.transaction {
remove(tiaraId, 1)
remove(talismanId, 1)
add(id, 1)
}
player.start("movement_delay", 3)
when (player.inventory.transaction.error) {
is TransactionError.Deficient, is TransactionError.Invalid -> {
player.message("You don't have a talisman to bind.")
}
TransactionError.None -> {
player.exp(Skill.Runecrafting, tiara.xp)
player.anim("bind_runes")
player.gfx("bind_runes")
player.sound("bind_runes")
}
else -> logger.warn { "Error binding talisman with tiara $player $tiara ${player.levels.get(Skill.Runecrafting)} $talismanId" }
}
player.softTimers.stop("runecrafting")
}
}
64 changes: 64 additions & 0 deletions game/src/test/kotlin/content/skill/runecrafting/TiaraTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package content.skill.runecrafting

import WorldTest
import content.entity.obj.ObjectTeleports
import itemOnObject
import org.junit.jupiter.api.Assertions.assertFalse
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.DynamicTest.dynamicTest
import org.junit.jupiter.api.TestFactory
import org.koin.test.get
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 TiaraTest : WorldTest() {

private lateinit var teleports: ObjectTeleports

@BeforeEach
fun setup() {
teleports = get()
}

@TestFactory
fun `Bind tiara with a talisman at an altar`() = altars.map { (type, _, altarTile) ->
dynamicTest("Craft $type tiara") {
val tile = teleports.get("${type}_altar_ruins_enter", "Enter").first().to
val player = createPlayer(tile)
player.inventory.add("tiara", "${type}_talisman")

val altar = GameObjects.find(altarTile, "${type}_altar")
player.itemOnObject(altar, 0)
tick(1)
tickIf { player.visuals.moved }

assertFalse(player.inventory.contains("tiara"))
assertFalse(player.inventory.contains("${type}_talisman"))
assertTrue(player.inventory.contains("${type}_tiara"))
assertTrue(player.experience.get(Skill.Runecrafting) > 0)
}
}

companion object {
internal data class Altar(val type: String, val ruinsTile: Tile, val altarTile: Tile)

internal val altars = listOf(
Altar("air", Tile(3126, 3404), Tile(2843, 4833)),
Altar("water", Tile(3184, 3164), Tile(3483, 4835)),
Altar("earth", Tile(3305, 3473), Tile(2657, 4840)),
Altar("fire", Tile(3312, 3254), Tile(2584, 4837)),
Altar("mind", Tile(2981, 3513), Tile(2785, 4840)),
Altar("body", Tile(3052, 3444), Tile(2522, 4839)),
Altar("cosmic", Tile(2407, 4376), Tile(2141, 4832)),
Altar("law", Tile(2857, 3380), Tile(2463, 4831)),
Altar("nature", Tile(2868, 3018), Tile(2399, 4840)),
Altar("chaos", Tile(3059, 3590), Tile(2270, 4841)),
Altar("death", Tile(1860, 4638), Tile(2204, 4835)),
Altar("blood", Tile(3560, 9780), Tile(2461, 4894, 1)),
)
}
}