mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2025-12-09 16:45:44 -07:00
373 lines
14 KiB
Kotlin
373 lines
14 KiB
Kotlin
package content.data
|
|
|
|
import content.global.skill.magic.TeleportMethod
|
|
import content.global.skill.slayer.SlayerManager.Companion.getInstance
|
|
import content.global.skill.slayer.SlayerUtils
|
|
import core.ServerConstants
|
|
import core.api.*
|
|
import core.game.event.TeleportEvent
|
|
import core.game.interaction.QueueStrength
|
|
import core.game.node.entity.player.Player
|
|
import core.game.node.entity.player.link.TeleportManager
|
|
import core.game.node.item.Item
|
|
import core.game.system.task.Pulse
|
|
import core.game.world.GameWorld
|
|
import core.game.world.map.Location
|
|
import core.game.world.update.flag.context.Animation
|
|
import core.game.world.update.flag.context.Graphics
|
|
import org.rs09.consts.Items
|
|
import core.game.world.GameWorld.Pulser
|
|
import core.tools.Log
|
|
import org.rs09.consts.Sounds
|
|
import java.util.*
|
|
|
|
/**
|
|
* Represents a piece of enchanted jewellery.
|
|
* @author Vexia, downthecrop, Player Name
|
|
*/
|
|
enum class EnchantedJewellery(
|
|
|
|
val options: Array<String>,
|
|
val locations: Array<Location>, crumble: Boolean, vararg val ids: Int) {
|
|
RING_OF_SLAYING(
|
|
arrayOf(
|
|
"Sumona in Pollnivneach.",
|
|
"Morytania Slayer Tower.",
|
|
"Rellekka Slayer Caves.",
|
|
"Nowhere. Give me a slayer update."
|
|
),
|
|
arrayOf(
|
|
Location.create(3361, 2994, 0),
|
|
Location.create(3428, 3535, 0),
|
|
Location.create(2792, 3615, 0),
|
|
),
|
|
true,
|
|
Items.RING_OF_SLAYING8_13281,
|
|
Items.RING_OF_SLAYING7_13282,
|
|
Items.RING_OF_SLAYING6_13283,
|
|
Items.RING_OF_SLAYING5_13284,
|
|
Items.RING_OF_SLAYING4_13285,
|
|
Items.RING_OF_SLAYING3_13286,
|
|
Items.RING_OF_SLAYING2_13287,
|
|
Items.RING_OF_SLAYING1_13288
|
|
),
|
|
|
|
RING_OF_DUELING(
|
|
arrayOf(
|
|
"Al Kharid Duel Arena.",
|
|
"Castle Wars Arena.",
|
|
"Fist of Guthix", "Nowhere."
|
|
),
|
|
arrayOf(
|
|
Location.create(3314, 3235, 0),
|
|
Location.create(2442, 3089, 0),
|
|
Location.create(1693, 5600, 0)
|
|
),
|
|
true,
|
|
Items.RING_OF_DUELLING8_2552,
|
|
Items.RING_OF_DUELLING7_2554,
|
|
Items.RING_OF_DUELLING6_2556,
|
|
Items.RING_OF_DUELLING5_2558,
|
|
Items.RING_OF_DUELLING4_2560,
|
|
Items.RING_OF_DUELLING3_2562,
|
|
Items.RING_OF_DUELLING2_2564,
|
|
Items.RING_OF_DUELLING1_2566
|
|
),
|
|
AMULET_OF_GLORY(
|
|
arrayOf(
|
|
"Edgeville.",
|
|
"Karamja.",
|
|
"Draynor Village.",
|
|
"Al-Kharid.",
|
|
"Nowhere."
|
|
),
|
|
arrayOf(
|
|
Location.create(3087, 3495, 0),
|
|
Location.create(2919, 3175, 0),
|
|
Location.create(3104, 3249, 0),
|
|
Location.create(3304, 3124, 0)
|
|
),
|
|
Items.AMULET_OF_GLORY4_1712,
|
|
Items.AMULET_OF_GLORY3_1710,
|
|
Items.AMULET_OF_GLORY2_1708,
|
|
Items.AMULET_OF_GLORY1_1706,
|
|
Items.AMULET_OF_GLORY_1704
|
|
),
|
|
AMULET_OF_GLORY_T(
|
|
AMULET_OF_GLORY.options,
|
|
AMULET_OF_GLORY.locations,
|
|
Items.AMULET_OF_GLORYT4_10354,
|
|
Items.AMULET_OF_GLORYT3_10356,
|
|
Items.AMULET_OF_GLORYT2_10358,
|
|
Items.AMULET_OF_GLORYT1_10360,
|
|
Items.AMULET_OF_GLORYT_10362
|
|
),
|
|
GAMES_NECKLACE(
|
|
arrayOf(
|
|
"Burthorpe Games Room.",
|
|
"Barbarian Outpost.",
|
|
"Clan Wars.",
|
|
"Wilderness Volcano.",
|
|
"Corporeal Beast."
|
|
),
|
|
arrayOf(
|
|
Location.create(2899, 3563, 0),
|
|
Location.create(2520, 3571, 0),
|
|
Location.create(3266, 3686, 0),
|
|
Location.create(3179, 3685, 0),
|
|
Location.create(2885, 4372, 2)
|
|
),
|
|
true,
|
|
Items.GAMES_NECKLACE8_3853,
|
|
Items.GAMES_NECKLACE7_3855,
|
|
Items.GAMES_NECKLACE6_3857,
|
|
Items.GAMES_NECKLACE5_3859,
|
|
Items.GAMES_NECKLACE4_3861,
|
|
Items.GAMES_NECKLACE3_3863,
|
|
Items.GAMES_NECKLACE2_3865,
|
|
Items.GAMES_NECKLACE1_3867
|
|
),
|
|
DIGSITE_PENDANT(arrayOf<String>(),
|
|
arrayOf(
|
|
Location.create(3342, 3445, 0)
|
|
),
|
|
true,
|
|
Items.DIGSITE_PENDANT_5_11194,
|
|
Items.DIGSITE_PENDANT_4_11193,
|
|
Items.DIGSITE_PENDANT_3_11192,
|
|
Items.DIGSITE_PENDANT_2_11191,
|
|
Items.DIGSITE_PENDANT_1_11190
|
|
),
|
|
COMBAT_BRACELET(
|
|
arrayOf(
|
|
"Champions' Guild.",
|
|
"Monastery.",
|
|
"Ranging Guild.",
|
|
"Warriors' Guild.",
|
|
"Nowhere."
|
|
),
|
|
arrayOf(
|
|
Location.create(3191, 3365, 0),
|
|
Location.create(3052, 3472, 0),
|
|
Location.create(2657, 3439, 0),
|
|
Location.create(2878, 3546, 0)
|
|
),
|
|
Items.COMBAT_BRACELET4_11118,
|
|
Items.COMBAT_BRACELET3_11120,
|
|
Items.COMBAT_BRACELET2_11122,
|
|
Items.COMBAT_BRACELET1_11124,
|
|
Items.COMBAT_BRACELET_11126
|
|
),
|
|
SKILLS_NECKLACE(
|
|
arrayOf(
|
|
"Fishing Guild.",
|
|
"Mining Guild.",
|
|
"Crafting Guild.",
|
|
"Cooking Guild.",
|
|
"Nowhere."
|
|
),
|
|
arrayOf(
|
|
Location.create(2611, 3392, 0),
|
|
Location.create(3016, 3338, 0),
|
|
Location.create(2933, 3290, 0),
|
|
Location.create(3143, 3442, 0)
|
|
),
|
|
Items.SKILLS_NECKLACE4_11105,
|
|
Items.SKILLS_NECKLACE3_11107,
|
|
Items.SKILLS_NECKLACE2_11109,
|
|
Items.SKILLS_NECKLACE1_11111,
|
|
Items.SKILLS_NECKLACE_11113
|
|
),
|
|
RING_OF_WEALTH(
|
|
arrayOf(
|
|
"Grand Exchange.",
|
|
"Nowhere."
|
|
),
|
|
arrayOf(
|
|
Location.create(3163, 3464, 0)
|
|
),
|
|
Items.RING_OF_WEALTH4_14646,
|
|
Items.RING_OF_WEALTH3_14644,
|
|
Items.RING_OF_WEALTH2_14642,
|
|
Items.RING_OF_WEALTH1_14640,
|
|
Items.RING_OF_WEALTH_14638
|
|
),
|
|
RING_OF_LIFE(arrayOf<String>(),
|
|
arrayOf(
|
|
Location.create(ServerConstants.HOME_LOCATION)
|
|
),
|
|
true,
|
|
Items.RING_OF_LIFE_2570
|
|
);
|
|
|
|
val isCrumble: Boolean = crumble
|
|
|
|
/**
|
|
* Constructs a new `EnchantedJewelleryPlugin` `Object`.
|
|
* @param options the dialogue options.
|
|
* @param locations the teleport locations.
|
|
* @param ids the ordered item ids.
|
|
*/
|
|
constructor(options: Array<String>, locations: Array<Location>, vararg ids: Int) : this(options, locations, false, *ids)
|
|
|
|
/**
|
|
* Method used when the player "Use"s the jewellery piece.
|
|
* @param player the player.
|
|
* @param item the used jewellery item.
|
|
* @param buttonID the button id.
|
|
* @param isEquipped If the player is operating.
|
|
*/
|
|
fun use(player: Player, item: Item, buttonID: Int, isEquipped: Boolean) {
|
|
if (buttonID > locations.size - 1) {
|
|
if (isSlayerRing(item)) {
|
|
slayerProgressDialogue(player)
|
|
}
|
|
return
|
|
}
|
|
attemptTeleport(player, item, buttonID, isEquipped)
|
|
}
|
|
|
|
/**
|
|
* Method used to actually teleport the player to the desired location.
|
|
* @param player the player.
|
|
* @param item the used jewellery item.
|
|
* @param buttonID the button id.
|
|
* @param isEquipped If the player is operating.
|
|
*/
|
|
fun attemptTeleport(player: Player, item: Item, buttonID: Int, isEquipped: Boolean): Boolean {
|
|
val itemIndex = getItemIndex(item)
|
|
val nextJewellery = Item(getNext(itemIndex))
|
|
if (!canTeleport(player, nextJewellery)) {
|
|
return false
|
|
}
|
|
val location = getLocation(buttonID)
|
|
player.scripts.delay = GameWorld.ticks + 4
|
|
queueScript(player, 0, QueueStrength.SOFT) { stage ->
|
|
when (stage) {
|
|
0 -> {
|
|
lock(player, 4)
|
|
visualize(player, ANIMATION, GRAPHICS)
|
|
playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200)
|
|
player.impactHandler.disabledTicks = 4
|
|
closeInterface(player)
|
|
return@queueScript delayScript(player, 3)
|
|
}
|
|
1 -> {
|
|
teleport(player, location)
|
|
resetAnimator(player)
|
|
unlock(player)
|
|
player.dispatch(TeleportEvent(TeleportManager.TeleportType.NORMAL, TeleportMethod.JEWELRY, item, location))
|
|
if (isLastItemIndex(itemIndex)) {
|
|
if (isSlayerRing(item)) {
|
|
if (isEquipped) {
|
|
// Remove it now, but only addItemOrDrop the gem after the teleport has procced
|
|
if (removeItem(player, item, Container.EQUIPMENT)) {
|
|
return@queueScript delayScript(player, 1)
|
|
}
|
|
log(this.javaClass, Log.ERR, "Error replacing slayer ring with enchanted gem (removeItem from equipment)")
|
|
}
|
|
// Not equipped -> can replace fluently
|
|
if (replaceSlot(player, item.slot, Item(Items.ENCHANTED_GEM_4155), item) == item) {
|
|
return@queueScript stopExecuting(player)
|
|
}
|
|
log(this.javaClass, Log.ERR, "Error replacing slayer ring with enchanted gem (replaceSlot)")
|
|
}
|
|
// Not slayer ring
|
|
if (isCrumble) {
|
|
val removeFrom = if (isEquipped) Container.EQUIPMENT else Container.INVENTORY
|
|
if (removeItem(player, item, removeFrom)) {
|
|
return@queueScript stopExecuting(player)
|
|
}
|
|
log(this.javaClass, Log.ERR, "Error crumbling jewelry")
|
|
}
|
|
} else {
|
|
replaceJewellery(player, item, nextJewellery, isEquipped)
|
|
}
|
|
}
|
|
2 -> {
|
|
addItemOrDrop(player, Items.ENCHANTED_GEM_4155)
|
|
sendMessage(player, "Your Ring of Slaying reverts back into a regular enchanted gem.")
|
|
}
|
|
}
|
|
return@queueScript stopExecuting(player)
|
|
}
|
|
return true
|
|
}
|
|
|
|
private fun replaceJewellery(player: Player, item: Item, nextJewellery: Item, isEquipped: Boolean) {
|
|
if (isEquipped) {
|
|
replaceSlot(player, item.slot, nextJewellery, item, Container.EQUIPMENT)
|
|
} else {
|
|
replaceSlot(player, item.slot, nextJewellery)
|
|
}
|
|
}
|
|
|
|
private fun isSlayerRing(item: Item): Boolean {
|
|
return (item.id in RING_OF_SLAYING.ids)
|
|
}
|
|
|
|
private fun slayerProgressDialogue(player: Player) {
|
|
val slayerManager = getInstance(player)
|
|
if (!slayerManager.hasTask()) {
|
|
sendNPCDialogue(player, slayerManager.master!!.npc, "You need something new to hunt. Come and " +
|
|
"see me when you can and I'll give you a new task.", core.game.dialogue.FacialExpression.HALF_GUILTY)
|
|
return
|
|
}
|
|
sendNPCDialogue(player, slayerManager.master!!.npc, "You're currently " +
|
|
"assigned to kill ${SlayerUtils.pluralise(getSlayerTaskName(player))} " +
|
|
"only ${getSlayerTaskKillsRemaining(player)} more to go.", core.game.dialogue.FacialExpression.FRIENDLY)
|
|
// Slayer tracker UI
|
|
setVarp(player, 2502, slayerManager.flags.taskFlags shr 4)
|
|
}
|
|
|
|
private fun canTeleport(player: Player, item: Item): Boolean {
|
|
return player.zoneMonitor.teleport(1, item)
|
|
}
|
|
|
|
private fun getNext(index: Int): Int {
|
|
val i = index + 1
|
|
if (i > ids.size - 1) {
|
|
return ids[ids.size - 1]
|
|
}
|
|
return ids[i]
|
|
}
|
|
|
|
private fun getLocation(index: Int): Location {
|
|
if (index > locations.size - 1) {
|
|
return locations[locations.size - 1]
|
|
}
|
|
return locations[index]
|
|
}
|
|
|
|
fun getJewelleryName(item: Item): String {
|
|
return item.name.replace(""" ?\(t?[0-9]?\)""".toRegex(), "")
|
|
}
|
|
|
|
fun getJewelleryType(item: Item): String {
|
|
return when {
|
|
this == GAMES_NECKLACE -> "games necklace"
|
|
this == DIGSITE_PENDANT -> "necklace"
|
|
this == COMBAT_BRACELET -> "bracelet"
|
|
this == SKILLS_NECKLACE -> "necklace"
|
|
else -> item.name.split(" ")[0].lowercase(Locale.getDefault())
|
|
}
|
|
}
|
|
|
|
fun isLastItemIndex(index: Int): Boolean = index == ids.size - 1
|
|
|
|
fun getItemIndex(item: Item): Int {
|
|
return ids.indexOf(item.id)
|
|
}
|
|
|
|
companion object {
|
|
private val ANIMATION = Animation(714)
|
|
private val GRAPHICS = Graphics(308, 100, 50)
|
|
val idMap = HashMap<Int, EnchantedJewellery>()
|
|
|
|
init {
|
|
values().forEach { entry ->
|
|
entry.ids.forEach { idMap[it] = entry }
|
|
}
|
|
}
|
|
}
|
|
}
|