Barrows equipment now degrades by 20% on grave death (fully repaired equipment is excluded from this)

Barrows equipment now breaks and drops on non-grave deaths (instead of converting to coins)
Rewrote Bob handlers
This commit is contained in:
dam 2025-11-25 10:12:24 +02:00 committed by Ryan
parent 8d182f2505
commit 9a7a885818
11 changed files with 681 additions and 812 deletions

View file

@ -1,87 +0,0 @@
package content.data;
import core.game.node.item.Item;
/**
* Represents the repair item type.
* @author Vexia
*/
public enum RepairItem {
BRONZE_HATCHET(new Item(494, 1), new Item(1351, 1), 0),
BRONZE_PICKAXE(new Item(468, 1), new Item(1265, 1), 0),
IRON_HATCHET(new Item(496, 1), new Item(1349, 1), 0),
IRON_PICKAXE(new Item(470, 1), new Item(1267, 1), 0),
STEEL_HATCHET(new Item(498, 1), new Item(1353, 1), 0),
STEEL_PICKAXE(new Item(472, 1), new Item(1269, 1), 14),
BLACK_HATCHET(new Item(500, 1), new Item(1361, 1), 10),
MITHRIL_HATCHET(new Item(502, 1), new Item(1355, 1), 18),
MITHRIL_PICKAXE(new Item(474, 1), new Item(1273, 1), 43),
ADAMANT_HATCHET(new Item(504, 1), new Item(1357, 1), 43),
ADAMANT_PICKAXE(new Item(476, 1), new Item(1271, 1), 107),
RUNE_HATCHET(new Item(506, 1), new Item(1359, 1), 427),
RUNE_PICKAXE(new Item(478, 1), new Item(1275, 1), 1100),
DRAGON_HATCHET(new Item(6741, 1), new Item(6739, 1), 1800);
/**
* The item id.
*/
private final Item item;
/**
* The product item.
*/
private final Item product;
/**
* The cost of the money to repair.
*/
private final int cost;
/**
* Constructs a new {@code BobRepairItem} {@code Object}.
* @param item the item.
* @param product the product.
* @param cost the cost.
*/
RepairItem(Item item, Item product, int cost) {
this.item = item;
this.product = product;
this.cost = cost;
}
/**
* Gets the item.
* @return The item.
*/
public Item getItem() {
return item;
}
/**
* Gets the product.
* @return The product.
*/
public Item getProduct() {
return product;
}
/**
* Gets the cost.
* @return The cost.
*/
public int getCost() {
return cost;
}
/**
* Gets the reapir item by the id.
* @param id the id.
* @return the repair item.
*/
public static RepairItem forId(int id) {
for (RepairItem item : RepairItem.values())
if (item.item.getId() == id)
return item;
return null;
}
}

View file

@ -0,0 +1,43 @@
package content.data
import core.game.node.item.Item
/**
* Represents the repair item type.
* @author Vexia
* @author Damighty - Kotlin conversion
*/
enum class RepairItem(
val item: Item,
val product: Item,
val cost: Int
) {
BRONZE_HATCHET(Item(494, 1), Item(1351, 1), 0),
BRONZE_PICKAXE(Item(468, 1), Item(1265, 1), 0),
IRON_HATCHET(Item(496, 1), Item(1349, 1), 0),
IRON_PICKAXE(Item(470, 1), Item(1267, 1), 0),
STEEL_HATCHET(Item(498, 1), Item(1353, 1), 0),
STEEL_PICKAXE(Item(472, 1), Item(1269, 1), 14),
BLACK_HATCHET(Item(500, 1), Item(1361, 1), 10),
MITHRIL_HATCHET(Item(502, 1), Item(1355, 1), 18),
MITHRIL_PICKAXE(Item(474, 1), Item(1273, 1), 43),
ADAMANT_HATCHET(Item(504, 1), Item(1357, 1), 43),
ADAMANT_PICKAXE(Item(476, 1), Item(1271, 1), 107),
RUNE_HATCHET(Item(506, 1), Item(1359, 1), 427),
RUNE_PICKAXE(Item(478, 1), Item(1275, 1), 1100),
DRAGON_HATCHET(Item(6741, 1), Item(6739, 1), 1800);
companion object {
/**
* List of all repairable item IDs.
*/
@JvmStatic
val repairableItemIds: List<Int> = values().map { it.item.id }
/**
* Gets the repair item by the broken items ID.
*/
@JvmStatic
fun forId(id: Int): RepairItem? = values().firstOrNull { it.item.id == id }
}
}

View file

@ -0,0 +1,244 @@
package content.global.handlers.item.equipment
import core.game.node.item.Item
import org.rs09.consts.Items
/**
* Barrows equipment information and utilities.
* @author 'Vexia - original code
* @author Damighty - Kotlin conversion and refactor
*/
object BarrowsEquipment {
// Barrows equipment lasts for 15 hours of combat. Each piece has 4 degradation tiers (100, 75, 50, 25).
const val DEGRADATION_TICKS_PER_TIER = (15 * 6000) / 4 // 22500 ticks per tier
private const val MAX_DURABILITY = DEGRADATION_TICKS_PER_TIER * 4
/**
* A data class for each Barrows piece. Holds all information related to a specific piece of Barrows gear.
*
* @param brother The Barrows brother this item belongs to.
* @param equipmentType The slot type ("weapon", "body", "legs", "helm").
* @param itemName The formatted name of the item.
* @param baseRepairCost The full repair cost in GP.
* @param degradationStates A list of item IDs, from fully repaired (index 0) to broken (index 5).
*/
data class BarrowsItemDefinition(
val brother: String,
val equipmentType: String,
val itemName: String,
val baseRepairCost: Int,
val degradationStates: List<Int>
) {
val repairedId: Int = degradationStates.first()
val brokenId: Int = degradationStates.last()
/** Checks if a given item ID belongs to this specific equipment set. */
fun contains(itemId: Int): Boolean = itemId in degradationStates
/** Gets the degradation index for a given item ID (0=repaired, 1=100, ..., 5=broken). */
fun getDegradationIndex(itemId: Int): Int = degradationStates.indexOf(itemId)
}
/** All Barrows equipment data. */
private val barrowsItemDefinitions = listOf(
// Dharok
BarrowsItemDefinition("dharok", "helm", "Dharok's helm", 60_000,
listOf(Items.DHAROKS_HELM_4716, Items.DHAROKS_HELM_100_4880,
Items.DHAROKS_HELM_75_4881, Items.DHAROKS_HELM_50_4882,
Items.DHAROKS_HELM_25_4883, Items.DHAROKS_HELM_0_4884)),
BarrowsItemDefinition("dharok", "weapon", "Dharok's greataxe", 100_000,
listOf(Items.DHAROKS_GREATAXE_4718, Items.DHAROKS_AXE_100_4886,
Items.DHAROKS_AXE_75_4887, Items.DHAROKS_AXE_50_4888,
Items.DHAROKS_AXE_25_4889, Items.DHAROKS_AXE_0_4890)),
BarrowsItemDefinition("dharok", "body", "Dharok's platebody", 90_000,
listOf(Items.DHAROKS_PLATEBODY_4720, Items.DHAROKS_BODY_100_4892,
Items.DHAROKS_BODY_75_4893, Items.DHAROKS_BODY_50_4894,
Items.DHAROKS_BODY_25_4895, Items.DHAROKS_BODY_0_4896)),
BarrowsItemDefinition("dharok", "legs", "Dharok's platelegs", 80_000,
listOf(Items.DHAROKS_PLATELEGS_4722, Items.DHAROKS_LEGS_100_4898,
Items.DHAROKS_LEGS_75_4899, Items.DHAROKS_LEGS_50_4900,
Items.DHAROKS_LEGS_25_4901, Items.DHAROKS_LEGS_0_4902)),
// Guthan
BarrowsItemDefinition("guthan", "helm", "Guthan's helm", 60_000,
listOf(Items.GUTHANS_HELM_4724, Items.GUTHANS_HELM_100_4904,
Items.GUTHANS_HELM_75_4905, Items.GUTHANS_HELM_50_4906,
Items.GUTHANS_HELM_25_4907, Items.GUTHANS_HELM_0_4908)),
BarrowsItemDefinition("guthan", "weapon", "Guthan's warspear", 100_000,
listOf(Items.GUTHANS_WARSPEAR_4726, Items.GUTHANS_SPEAR_100_4910,
Items.GUTHANS_SPEAR_75_4911, Items.GUTHANS_SPEAR_50_4912,
Items.GUTHANS_SPEAR_25_4913, Items.GUTHANS_SPEAR_0_4914)),
BarrowsItemDefinition("guthan", "body", "Guthan's platebody", 90_000,
listOf(Items.GUTHANS_PLATEBODY_4728, Items.GUTHANS_BODY_100_4916,
Items.GUTHANS_BODY_75_4917, Items.GUTHANS_BODY_50_4918,
Items.GUTHANS_BODY_25_4919, Items.GUTHANS_BODY_0_4920)),
BarrowsItemDefinition("guthan", "legs", "Guthan's chainskirt", 80_000,
listOf(Items.GUTHANS_CHAINSKIRT_4730, Items.GUTHANS_SKIRT_100_4922,
Items.GUTHANS_SKIRT_75_4923, Items.GUTHANS_SKIRT_50_4924,
Items.GUTHANS_SKIRT_25_4925, Items.GUTHANS_SKIRT_0_4926)),
// Torag
BarrowsItemDefinition("torag", "helm", "Torag's helm", 60_000,
listOf(Items.TORAGS_HELM_4745, Items.TORAGS_HELM_100_4952,
Items.TORAGS_HELM_75_4953, Items.TORAGS_HELM_50_4954,
Items.TORAGS_HELM_25_4955, Items.TORAGS_HELM_0_4956)),
BarrowsItemDefinition("torag", "weapon", "Torag's hammers", 100_000,
listOf(Items.TORAGS_HAMMERS_4747, Items.TORAGS_HAMMER_100_4958,
Items.TORAGS_HAMMER_75_4959, Items.TORAGS_HAMMER_50_4960,
Items.TORAGS_HAMMER_25_4961, Items.TORAGS_HAMMER_0_4962)),
BarrowsItemDefinition("torag", "body", "Torag's platebody", 90_000,
listOf(Items.TORAGS_PLATEBODY_4749, Items.TORAGS_BODY_100_4964,
Items.TORAGS_BODY_75_4965, Items.TORAGS_BODY_50_4966,
Items.TORAGS_BODY_25_4967, Items.TORAGS_BODY_0_4968)),
BarrowsItemDefinition("torag", "legs", "Torag's platelegs", 80_000,
listOf(Items.TORAGS_PLATELEGS_4751, Items.TORAGS_LEGS_100_4970,
Items.TORAGS_LEGS_75_4971, Items.TORAGS_LEGS_50_4972,
Items.TORAGS_LEGS_25_4973, Items.TORAGS_LEGS_0_4974)),
// Verac
BarrowsItemDefinition("verac", "helm", "Verac's helm", 60_000,
listOf(Items.VERACS_HELM_4753, Items.VERACS_HELM_100_4976,
Items.VERACS_HELM_75_4977, Items.VERACS_HELM_50_4978,
Items.VERACS_HELM_25_4979, Items.VERACS_HELM_0_4980)),
BarrowsItemDefinition("verac", "weapon", "Verac's flail", 100_000,
listOf(Items.VERACS_FLAIL_4755, Items.VERACS_FLAIL_100_4982,
Items.VERACS_FLAIL_75_4983, Items.VERACS_FLAIL_50_4984,
Items.VERACS_FLAIL_25_4985, Items.VERACS_FLAIL_0_4986)),
BarrowsItemDefinition("verac", "body", "Verac's brassard", 90_000,
listOf(Items.VERACS_BRASSARD_4757, Items.VERACS_TOP_100_4988,
Items.VERACS_TOP_75_4989, Items.VERACS_TOP_50_4990,
Items.VERACS_TOP_25_4991, Items.VERACS_TOP_0_4992)),
BarrowsItemDefinition("verac", "legs", "Verac's plateskirt", 80_000,
listOf(Items.VERACS_PLATESKIRT_4759, Items.VERACS_SKIRT_100_4994,
Items.VERACS_SKIRT_75_4995, Items.VERACS_SKIRT_50_4996,
Items.VERACS_SKIRT_25_4997, Items.VERACS_SKIRT_0_4998)),
// Ahrim
BarrowsItemDefinition("ahrim", "helm", "Ahrim's hood", 60_000,
listOf(Items.AHRIMS_HOOD_4708, Items.AHRIMS_HOOD_100_4856,
Items.AHRIMS_HOOD_75_4857, Items.AHRIMS_HOOD_50_4858,
Items.AHRIMS_HOOD_25_4859, Items.AHRIMS_HOOD_0_4860)),
BarrowsItemDefinition("ahrim", "weapon", "Ahrim's staff", 100_000,
listOf(Items.AHRIMS_STAFF_4710, Items.AHRIMS_STAFF_100_4862,
Items.AHRIMS_STAFF_75_4863, Items.AHRIMS_STAFF_50_4864,
Items.AHRIMS_STAFF_25_4865, Items.AHRIMS_STAFF_0_4866)),
BarrowsItemDefinition("ahrim", "body", "Ahrim's robetop", 90_000,
listOf(Items.AHRIMS_ROBETOP_4712, Items.AHRIMS_TOP_100_4868,
Items.AHRIMS_TOP_75_4869, Items.AHRIMS_TOP_50_4870,
Items.AHRIMS_TOP_25_4871, Items.AHRIMS_TOP_0_4872)),
BarrowsItemDefinition("ahrim", "legs", "Ahrim's robeskirt", 80_000,
listOf(Items.AHRIMS_ROBESKIRT_4714, Items.AHRIMS_SKIRT_100_4874,
Items.AHRIMS_SKIRT_75_4875, Items.AHRIMS_SKIRT_50_4876,
Items.AHRIMS_SKIRT_25_4877, Items.AHRIMS_SKIRT_0_4878)),
// Karil
BarrowsItemDefinition("karil", "helm", "Karil's coif", 60_000,
listOf(Items.KARILS_COIF_4732, Items.KARILS_COIF_100_4928,
Items.KARILS_COIF_75_4929, Items.KARILS_COIF_50_4930,
Items.KARILS_COIF_25_4931, Items.KARILS_COIF_0_4932)),
BarrowsItemDefinition("karil", "weapon", "Karil's crossbow", 100_000,
listOf(Items.KARILS_CROSSBOW_4734, Items.KARILS_X_BOW_100_4934,
Items.KARILS_X_BOW_75_4935, Items.KARILS_X_BOW_50_4936,
Items.KARILS_X_BOW_25_4937, Items.KARILS_X_BOW_0_4938)),
BarrowsItemDefinition("karil", "body", "Karil's leathertop", 90_000,
listOf(Items.KARILS_LEATHERTOP_4736, Items.KARILS_TOP_100_4940,
Items.KARILS_TOP_75_4941, Items.KARILS_TOP_50_4942,
Items.KARILS_TOP_25_4943, Items.KARILS_TOP_0_4944)),
BarrowsItemDefinition("karil", "legs", "Karil's leatherskirt", 80_000,
listOf(Items.KARILS_LEATHERSKIRT_4738, Items.KARILS_SKIRT_100_4946,
Items.KARILS_SKIRT_75_4947, Items.KARILS_SKIRT_50_4948,
Items.KARILS_SKIRT_25_4949, Items.KARILS_SKIRT_0_4950))
)
/** Cached access to an item's full definition from its ID */
private val itemIdToDefinitionMap: Map<Int, BarrowsItemDefinition> by lazy {
barrowsItemDefinitions.flatMap { def ->
def.degradationStates.map { id -> id to def }
}.toMap()
}
/** Gets all degradation state arrays for degradation registration */
fun getAllEquipmentSets(): Collection<IntArray> = barrowsItemDefinitions.map { it.degradationStates.toIntArray() }
/** Gets all repairable Barrows item IDs (anything not fully repaired) */
fun getAllRepairableBarrowsIds(): List<Int> = itemIdToDefinitionMap.filter { !isFullyRepaired(it.key) }.keys.toList()
/** Gets the full definition for a Barrows item */
@JvmStatic
fun getDefinition(itemId: Int): BarrowsItemDefinition? = itemIdToDefinitionMap[itemId]
/** Checks if an item ID is any Barrows item */
@JvmStatic
fun isBarrowsItem(itemId: Int): Boolean = itemId in itemIdToDefinitionMap
/** Checks if a Barrows item is fully repaired */
@JvmStatic
fun isFullyRepaired(itemId: Int): Boolean = getDefinition(itemId)?.repairedId == itemId
/** Checks if a Barrows item is broken */
@JvmStatic
fun isBroken(itemId: Int): Boolean = getDefinition(itemId)?.brokenId == itemId
/**
* Calculates the repair cost for a degraded Barrows item
* @param item The degraded Barrows item
* @return The repair cost in GP, or -1 if the item cannot be repaired
*/
fun getRepairCost(item: Item): Int {
val def = getDefinition(item.id) ?: return -1
if (isFullyRepaired(item.id)) return -1
val totalRemainingDurability = calculateTotalRemainingDurability(item, def)
val durabilityLost = MAX_DURABILITY - totalRemainingDurability
val cost = ((durabilityLost.toDouble() / MAX_DURABILITY) * def.baseRepairCost).toInt()
return cost
}
/**
* Reduces the durability of a Barrows item by 20% of its total remaining durability
* @param item The Barrows item
* @return The item with reduced durability, or null if the item is not a valid Barrows piece
*/
@JvmStatic
fun graveDeathDurabilityReduction(item: Item): Item? {
val def = getDefinition(item.id) ?: return null
if (isBroken(item.id)) return item
val totalRemainingDurability = calculateTotalRemainingDurability(item, def)
val durabilityReduction = (totalRemainingDurability * 0.2).toInt()
val newRemainingDurability = totalRemainingDurability - durabilityReduction
return createItemFromDurability(def, newRemainingDurability, item.amount)
}
/**
* Calculates the total remaining durability ticks (charge) for a Barrows item
*/
private fun calculateTotalRemainingDurability(item: Item, def: BarrowsItemDefinition): Int {
return when (val index = def.getDegradationIndex(item.id)) {
-1 -> 0 // Invalid
0 -> MAX_DURABILITY // Fully repaired
5 -> 0 // Broken
else -> {
// For degraded items (100, 75, 50, 25), durability is the number of fully remaining tiers below it, plus the charge of the current tier.
// Index 1 (100) has 3 tiers below it. Index 4 (25) has 0 tiers below it.
val remainingTiers = 4 - index
(remainingTiers * DEGRADATION_TICKS_PER_TIER) + item.charge
}
}
}
/**
* Creates a new Item instance based on a total durability value
*/
private fun createItemFromDurability(def: BarrowsItemDefinition, durability: Int, amount: Int): Item {
if (durability <= 0) {
return Item(def.brokenId, amount)
}
// Tier is 1-indexed (1=25, 2=50, 3=75, 4=100)
val tier = ((durability - 1) / DEGRADATION_TICKS_PER_TIER) + 1
// Degradation index is 4-indexed (4=25, 3=50, 2=75, 1=100)
val degradationIndex = 5 - tier
val newId = def.degradationStates[degradationIndex]
val newCharge = (durability - 1) % DEGRADATION_TICKS_PER_TIER + 1
return Item(newId, amount, newCharge)
}
}

View file

@ -5,72 +5,15 @@ import core.plugin.Plugin
@Initializable @Initializable
class BarrowsEquipmentRegister : Plugin<Any> { class BarrowsEquipmentRegister : Plugin<Any> {
public companion object {
// Barrows equipment lasts for 15 hours of combat, and each piece has 4 stages of degredation
@JvmField
public val TICKS = (15 * 6000) / 4
}
val DHAROK_HELM = arrayOf(4716,4880,4881,4882,4883,4884)
val DHAROK_AXE = arrayOf(4718,4886,4887,4888,4889,4890)
val DHAROK_BODY = arrayOf(4720,4892,4893,4894,4895,4896)
val DHAROK_LEGS = arrayOf(4722,4898,4899,4900,4901,4902)
val GUTHAN_HELM = arrayOf(4724,4904,4905,4906,4907,4908)
val GUTHAN_SPEAR = arrayOf(4726,4910,4911,4912,4913,4914)
val GUTHAN_BODY = arrayOf(4728,4916,4917,4918,4919,4920)
val GUTHAN_SKIRT = arrayOf(4730,4922,4923,4924,4925,4926)
val TORAG_HELM = arrayOf(4745,4952,4953,4954,4955,4956)
val TORAG_HAMMER = arrayOf(4747,4958,4959,4960,4961,4962)
val TORAG_BODY = arrayOf(4749,4964,4965,4966,4967,4968)
val TORAG_LEGS = arrayOf(4751,4970,4971,4972,4973,4974)
val VERAC_HELM = arrayOf(4753,4976,4977,4978,4979,4980)
val VERAC_FLAIL = arrayOf(4755,4982,4983,4984,4985,4986)
val VERAC_BRASS = arrayOf(4757,4988,4989,4990,4991,4992)
val VERAC_SKIRT = arrayOf(4759,4994,4995,4996,4997,4998)
val AHRIM_HOOD = arrayOf(4708,4856,4857,4858,4859,4860)
val AHRIM_STAFF = arrayOf(4710,4862,4863,4864,4865,4866)
val AHRIM_TOP = arrayOf(4712,4868,4869,4870,4871,4872)
val AHRIM_SKIRT = arrayOf(4714,4874,4875,4876,4877,4878)
val KARIL_COIF = arrayOf(4732,4928,4929,4930,4931,4932)
val KARIL_CBOW = arrayOf(4734,4934,4935,4936,4937,4938)
val KARIL_TOP = arrayOf(4736,4940,4941,4942,4943,4944)
val KARIL_SKIRT = arrayOf(4738,4946,4947,4948,4949,4950)
override fun newInstance(arg: Any?): Plugin<Any> { override fun newInstance(arg: Any?): Plugin<Any> {
EquipmentDegrader.registerSet(TICKS, AHRIM_HOOD) BarrowsEquipment.getAllEquipmentSets().forEach {
EquipmentDegrader.registerSet(TICKS, AHRIM_STAFF) degradationSet ->
EquipmentDegrader.registerSet(TICKS, AHRIM_TOP) EquipmentDegrader.registerSet(BarrowsEquipment.DEGRADATION_TICKS_PER_TIER, degradationSet.toTypedArray())
EquipmentDegrader.registerSet(TICKS, AHRIM_SKIRT) }
EquipmentDegrader.registerSet(TICKS, KARIL_COIF)
EquipmentDegrader.registerSet(TICKS, KARIL_CBOW)
EquipmentDegrader.registerSet(TICKS, KARIL_TOP)
EquipmentDegrader.registerSet(TICKS, KARIL_SKIRT)
EquipmentDegrader.registerSet(TICKS, DHAROK_HELM)
EquipmentDegrader.registerSet(TICKS, DHAROK_AXE)
EquipmentDegrader.registerSet(TICKS, DHAROK_BODY)
EquipmentDegrader.registerSet(TICKS, DHAROK_LEGS)
EquipmentDegrader.registerSet(TICKS, GUTHAN_HELM)
EquipmentDegrader.registerSet(TICKS, GUTHAN_SPEAR)
EquipmentDegrader.registerSet(TICKS, GUTHAN_BODY)
EquipmentDegrader.registerSet(TICKS, GUTHAN_SKIRT)
EquipmentDegrader.registerSet(TICKS, TORAG_HELM)
EquipmentDegrader.registerSet(TICKS, TORAG_HAMMER)
EquipmentDegrader.registerSet(TICKS, TORAG_BODY)
EquipmentDegrader.registerSet(TICKS, TORAG_LEGS)
EquipmentDegrader.registerSet(TICKS, VERAC_HELM)
EquipmentDegrader.registerSet(TICKS, VERAC_FLAIL)
EquipmentDegrader.registerSet(TICKS, VERAC_BRASS)
EquipmentDegrader.registerSet(TICKS, VERAC_SKIRT)
return this return this
} }
override fun fireEvent(identifier: String?, vararg args: Any?): Any { override fun fireEvent(identifier: String?, vararg args: Any?): Any {
return Unit return Unit
} }
} }

View file

@ -4,8 +4,7 @@ import core.game.dialogue.DialoguePlugin
import content.data.RepairItem import content.data.RepairItem
import core.game.interaction.NodeUsageEvent import core.game.interaction.NodeUsageEvent
import core.game.interaction.UseWithHandler import core.game.interaction.UseWithHandler
import content.region.misthalin.lumbridge.dialogue.BobDialogue.BarrowsEquipment import content.global.handlers.item.equipment.BarrowsEquipment
import content.region.misthalin.lumbridge.dialogue.BobDialogue.BarrowsEquipment.BarrowsFullEquipment
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.game.node.entity.skill.Skills import core.game.node.entity.skill.Skills
import core.game.node.item.Item import core.game.node.item.Item
@ -14,8 +13,10 @@ import core.plugin.Plugin
import kotlin.math.ceil import kotlin.math.ceil
import org.rs09.consts.Items import org.rs09.consts.Items
private val ALL_REPAIRABLE_ITEM_IDS = (RepairItem.repairableItemIds + BarrowsEquipment.getAllRepairableBarrowsIds()).toIntArray()
@Initializable @Initializable
class ArmourStand : UseWithHandler(494, 468, 496, 470, 498, 472, 500, 502, 474, 504, 476, 506, 478, 6741, 4856, 4857, 4858, 4859, 4860, 4862, 4863, 4864, 4865, 4866, 4868, 4869, 4870, 4871, 4872, 4874, 4875, 4876, 4877, 4878, 4880, 4881, 4882, 4883, 4884, 4886, 4887, 4888, 4889, 4890, 4892, 4893, 4894, 4895, 4896, 4898, 4899, 4900, 4901, 4902, 4904, 4905, 4906, 4907, 4908, 4910, 4911, 4912, 4913, 4914, 4916, 4917, 4918, 4919, 4920, 4922, 4923, 4924, 4925, 4926, 4928, 4929, 4930, 4931, 4932, 4934, 4935, 4936, 4937, 4938, 4940, 4941, 4942, 4943, 4944, 4946, 4947, 4948, 4949, 4950, 4952, 4953, 4954, 4955, 4956, 4958, 4959, 4960, 4961, 4962, 4964, 4965, 4966, 4967, 4968, 4970, 4971, 4972, 4973, 4974, 4976, 4977, 4978, 4979, 4980, 4982, 4983, 4984, 4985, 4986, 4988, 4989, 4990, 4991, 4992, 4994, 4995, 4996, 4997, 4998){ class ArmourStand : UseWithHandler(*ALL_REPAIRABLE_ITEM_IDS) {
override fun newInstance(arg: Any?): Plugin<Any> { override fun newInstance(arg: Any?): Plugin<Any> {
addHandler(13715, OBJECT_TYPE, this) addHandler(13715, OBJECT_TYPE, this)
return this return this
@ -24,76 +25,90 @@ class ArmourStand : UseWithHandler(494, 468, 496, 470, 498, 472, 500, 502, 474,
override fun handle(event: NodeUsageEvent?): Boolean { override fun handle(event: NodeUsageEvent?): Boolean {
event ?: return false event ?: return false
val player = event.player val player = event.player
val repairItem = RepairItem.forId(event.used.id) val usedItem = event.used.asItem()
var baseCost = 0.0 var baseCost = 0
var product: Item? = null var product: Item? = null
if(repairItem != null){ val repairItem = RepairItem.forId(usedItem.id)
baseCost = repairItem.cost * 1.0 val barrowsDef = BarrowsEquipment.getDefinition(usedItem.id)
product = repairItem.product
} else if(BarrowsEquipment.isBarrowsItem(event.used.id)){
//Begin terrible code thanks to Vexia
val type = BarrowsEquipment.formatedName(event.used.id)
val single = BarrowsEquipment.getSingleName(type)
val equipment = BarrowsEquipment.getEquipmentType(type)
val newString = type.toLowerCase().replace(single, "").trim { it <= ' ' }.replace("'s", "")
val newewString = StringBuilder()
newewString.append(newString).append(" $equipment")
val fullequip = BarrowsFullEquipment.forName(newewString.toString())
baseCost = BarrowsEquipment.getFormatedCost(equipment,event.used.asItem()) * 1.0
product = fullequip.full
//End terrible code thanks to Vexia
}
if((repairItem == null && baseCost == 0.0)){ if (repairItem != null) {
baseCost = repairItem.cost
product = repairItem.product
} else if (barrowsDef != null) {
if (BarrowsEquipment.isFullyRepaired(event.used.id)) {
player.sendMessage("That item can't be repaired.")
return true
}
baseCost = BarrowsEquipment.getRepairCost(usedItem)
product = Item(barrowsDef.repairedId)
} else {
player.sendMessage("That item can't be repaired.") player.sendMessage("That item can't be repaired.")
return true return true
} }
val cost: Int = ceil(((100.0 - (player.skills.getLevel(Skills.SMITHING) / 2.0) ) / 100.0) * baseCost).toInt() val discountMultiplier = (100.0 - (player.skills.getLevel(Skills.SMITHING) / 2.0)) / 100.0
val cost = ceil(discountMultiplier * baseCost).toInt()
player.dialogueInterpreter.open(58824213,event.used,cost,product)
player.dialogueInterpreter.open(58824213,usedItem, cost, product)
return true return true
} }
@Initializable @Initializable
class RepairDialogue(player: Player? = null) : DialoguePlugin(player) { class RepairDialogue(player: Player? = null) : DialoguePlugin(player) {
override fun newInstance(player: Player?): DialoguePlugin {
return RepairDialogue(player) private var item: Item? = null
} private var cost: Int = 0
var item: Item? = null private var product: Item? = null
var cost: Int = 0
var product: Item? = null override fun newInstance(player: Player?): DialoguePlugin = RepairDialogue(player)
override fun open(vararg args: Any?): Boolean { override fun open(vararg args: Any?): Boolean {
item = args[0] as Item item = args[0] as Item
cost = args[1] as Int cost = args[1] as Int
product = args[2] as Item product = args[2] as Item
player.dialogueInterpreter.sendDialogue("Would you like to repair your ${(item as Item).name.toLowerCase()}","for $cost gp?")
val itemName = item?.name?.lowercase() ?: "item"
player.dialogueInterpreter.sendDialogue(
"Would you like to repair your $itemName",
"for $cost gp?"
)
stage = 0 stage = 0
return true return true
} }
override fun handle(interfaceId: Int, buttonId: Int): Boolean { override fun handle(interfaceId: Int, buttonId: Int): Boolean {
item ?: return false val currentItem = item ?: return false
product ?: return false val currentProduct = product ?: return false
when (stage) { when (stage) {
0 -> options("Yes, please","No, thanks").also{stage++} 0 -> {
options("Yes, please", "No, thanks")
stage++
}
1 -> when (buttonId) { 1 -> when (buttonId) {
1 -> exchangeItems(item as Item,cost,product as Item).also { end() } 1 -> {
exchangeItems(currentItem, cost, currentProduct)
end()
}
2 -> end() 2 -> end()
} }
} }
return true return true
} }
fun exchangeItems(item: Item, cost: Int, product: Item) { private fun exchangeItems(item: Item, cost: Int, product: Item) {
val coins = Item(Items.COINS_995, cost) val coins = Item(Items.COINS_995, cost)
if (player.inventory.containsItem(coins) && player.inventory.containsItem(item)) { if (player.inventory.containsItem(coins) && player.inventory.containsItem(item)) {
player.inventory.remove(item, coins) if (player.inventory.remove(item, coins)) {
player.inventory.add(product) if (player.inventory.add(product)) {
player.sendMessage("You repair your ${product.name.toLowerCase()} for $cost.") val costText = if (cost > 0) "${cost}gp" else "free"
player.sendMessage("You repair your ${product.name.lowercase()} for $costText.")
return
}
}
player.sendMessage("Report this to an administrator!")
} else { } else {
player.sendMessage("You can't afford that.") player.sendMessage("You can't afford that.")
} }

View file

@ -1,569 +0,0 @@
package content.region.misthalin.lumbridge.dialogue;
import core.cache.def.impl.ItemDefinition;
import core.game.dialogue.DialoguePlugin;
import core.game.dialogue.FacialExpression;
import content.data.RepairItem;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.diary.AchievementDiary;
import core.game.node.entity.player.link.diary.DiaryType;
import core.game.node.item.Item;
import content.global.handlers.item.equipment.BarrowsEquipmentRegister;
/**
* Represents the dialogue plugin used for the bob npc who repairs items.
* @author 'Vexia
* @version 1.0
*/
public final class BobDialogue extends DialoguePlugin {
/**
* Represents the item id being repaired.
*/
private int itemId = 0;
/**
* Represents the item being repaired.
*/
private Item item;
/**
* Represents the item repairing.
*/
private static RepairItem repairitem = null;
/**
* The achievement diary.
*/
private final int level = 1;
/**
* Constructs a new {@code BobDialogue} {@code Object}.
*/
public BobDialogue() {
/**
* empty.
*/
}
/**
* Constructs a new {@code BobDialogue} {@code Object}.
* @param player the player.
*/
public BobDialogue(Player player) {
super(player);
}
@Override
public boolean handle(int interfaceId, int buttonId) {
switch (stage) {
case 754:
options("Yes, please.", "No, thank you.");
stage = 755;
break;
case 755:
switch (buttonId) {
case 1:
player("Yes, please.");
stage = 757;
break;
case 2:
player("No, thank you.");
stage = 756;
break;
}
break;
case 756:
end();
break;
case 757:
end();
if (repairitem != null) {
if (!player.getInventory().contains(995, repairitem.getCost())) {
end();
player.getPacketDispatch().sendMessage("You don't have enough to pay him.");
break;
}
if (!player.getInventory().contains(itemId, 1)) {
end();
return true;
}
player.getInventory().remove(new Item(995, repairitem.getCost()));
if (player.getInventory().remove(new Item(itemId, 1))) {
player.getInventory().add(repairitem.getProduct());
}
String cost = "free";
if (repairitem.getCost() != 0) {
cost = repairitem.getCost() + "gp";
}
player.getPacketDispatch().sendMessage("Bob fixes your " + ItemDefinition.forId(itemId).getName().toLowerCase().replace("broken", "").trim() + " for " + cost + ".");
}
if (repairitem == null) {
String cost = "free";
String type = BarrowsEquipment.formatedName(itemId);
String single = BarrowsEquipment.getSingleName(type);
String equipment = BarrowsEquipment.getEquipmentType(type);
String newString = type.toLowerCase().replace(single, "").trim().replace("'s", "");
StringBuilder newewString = new StringBuilder();
newewString.append(newString).append(" " + equipment);
final BarrowsEquipment.BarrowsFullEquipment fullequip = BarrowsEquipment.BarrowsFullEquipment.forName(newewString.toString());
if (BarrowsEquipment.getFormatedCost(equipment, item) != 0) {
cost = String.valueOf(BarrowsEquipment.getFormatedCost(equipment, item) + "gp");
}
if (!player.getInventory().contains(995, BarrowsEquipment.getFormatedCost(equipment, item))) {
end();
player.getPacketDispatch().sendMessage("You don't have enough to pay him.");
break;
}
if (fullequip == null || fullequip.getFull() == null) {
player.getPacketDispatch().sendMessage("Report this to an administrator!");
return true;
}
if (!player.getInventory().contains(itemId, 1)) {
end();
return true;
}
player.getInventory().remove(new Item(995, BarrowsEquipment.getFormatedCost(equipment, item)));
if (player.getInventory().remove(new Item(itemId, 1))) {
player.getInventory().add(fullequip.getFull());
}
player.getPacketDispatch().sendMessage("Bob fixes your " + equipment + " for " + cost + ".");
}
break;
case 678:
end();
break;
case 0:
switch (buttonId) {
case 1:
player("Give me a quest!");
stage = -5;
break;
case 2:
player("Have you anything to sell?");
stage = 10;
break;
case 3:
player("Can you repair my items for me?");
stage = 20;
break;
case 4:
player("I'd like to talk about Achievement Diaries.");
stage = 30;
break;
}
break;
case -5:
interpreter.sendDialogues(npc, FacialExpression.FURIOUS, "Get yer own!");
stage = -4;
break;
case -4:
end();
break;
case 10:
npc("Yes! I buy and sell axes! Take your pick (or axe)!");
stage = 11;
break;
case 11:
end();
npc.openShop(player);
break;
case 20:
npc("Of course I'll repair it, though the materials may cost", "you. Just hand me the item and I'll have a look.");
stage = 21;
break;
case 21:
end();
break;
case 30:
if (AchievementDiary.canClaimLevelRewards(player, DiaryType.LUMBRIDGE, level)) {
player("I've done all the medium tasks in my Lumbridge", "Achievement Diary.");
stage = 150;
break;
}
if (AchievementDiary.canReplaceReward(player, DiaryType.LUMBRIDGE, level)) {
player("I've seemed to have lost my explorer's ring...");
stage = 160;
break;
}
options("What is the Achievement Diary?", "What are the rewards?", "How do I claim the rewards?", "See you later.");
stage = 31;
break;
case 31:
switch (buttonId) {
case 1:
player("What is the Achievement Diary?");
stage = 110;
break;
case 2:
player("What are the rewards?");
stage = 120;
break;
case 3:
player("How do I claim the rewards?");
stage = 130;
break;
case 4:
player("See you later!");
stage = 140;
break;
}
break;
case 110:
npc("Ah, well, it's a diary that helps you keep track of", "particular achievements you've made in the world of", "Gielinor. In Lumbridge and Draynor I can help you", "discover some very useful things indeed.");
stage++;
break;
case 111:
npc("Eventually with enough exploration you will be", "rewarded for your explorative efforts.");
stage++;
break;
case 112:
npc("You can access your Achievement Diary by going to", "the Quest Journal. When you've opened the Quest", "Journal click on the green star icon on the top right", "hand corner. This will open the diary.");
stage = 30;
break;
case 120:
npc("Ah, well there are different rewards for each", "Achievement Diary. For completing the Lumbridge and", "Draynor diary you are presented with an explorer's", "ring.");
stage++;
break;
case 121:
npc("This ring will become increasingly useful with each", "section of the diary that you complete.");
stage = 30;
break;
case 130:
npc("You need to complete the tasks so that they're all ticked", "off, then you can claim your reward. Most of them are", "straightforward although you might find some required", "quests to be started, if not finished.");
stage++;
break;
case 131:
npc("To claim the explorer's ring speak to Explorer Jack", " in Lumbridge, Ned in Draynor Village or myself.");
stage = 30;
break;
case 140:
end();
break;
case 150:
npc("Yes I see that, you'll be wanting your", "reward then I assume?");
stage++;
break;
case 151:
player("Yes please.");
stage++;
break;
case 152:
AchievementDiary.flagRewarded(player, DiaryType.LUMBRIDGE, level);
npc("This ring is a representation of the adventures you", "went on to complete your tasks.");
stage ++;
break;
case 153:
player("Wow, thanks!");
stage = 30;
break;
case 160:
AchievementDiary.grantReplacement(player, DiaryType.LUMBRIDGE, level);
npc("You better be more careful this time.");
stage = -1;
break;
}
return true;
}
@Override
public DialoguePlugin newInstance(Player player) {
return new BobDialogue(player);
}
@Override
public boolean open(Object... args) {
npc = (NPC) args[0];
boolean repair = false;
boolean wrong = false;
if (npc.getId() == 3797 && args.length == 1) {
player("Can you repair my items for me?");
stage = 20;
return true;
}
if (args.length == 1) {
options("Give me a quest!", "Have you anything to sell?", "Can you repair my items for me?", "Talk about Achievement Diaries");
stage = 0;
return true;
}
if (args[1] != null) {
repair = (boolean) args[1];
}
if (args[2] != null) {
wrong = (boolean) args[2];
}
if (args[3] != null) {
repairitem = RepairItem.forId((int) args[3]);
itemId = (int) args[3];
}
if (args[4] != null) {
item = (Item) args[4];
}
if (repair && !wrong) {
String cost = "free";
if (repairitem != null) {
if (repairitem.getCost() != 0) {
cost = String.valueOf(repairitem.getCost() + "gp");
}
} else {
String type = BarrowsEquipment.formatedName(itemId);
String single = BarrowsEquipment.getSingleName(type);
String equipment = BarrowsEquipment.getEquipmentType(type);
String newString = type.toLowerCase().replace(single, "").trim().replace("'s", "");
StringBuilder newewString = new StringBuilder();
newewString.append(newString).append(" " + equipment);
if (BarrowsEquipment.getFormatedCost(equipment, item) != 0) {
cost = String.valueOf(BarrowsEquipment.getFormatedCost(equipment, item) + "gp");
}
}
npc("Quite badly damaged, but easy to repair. Would you", "like me to repair it for " + cost + "?");
stage = 754;
return true;
}
if (repair == true && wrong == true) {
npc("Sorry friend, but I can't do anything with that.");
stage = 678;
return true;
}
return true;
}
@Override
public int[] getIds() {
return new int[] { 519, 3797 };
}
/**
* Barrows equipment information.
* @author 'Vexia
*/
public static class BarrowsEquipment {
/**
* Represents the base names.
*/
private String[] base = new String[] { "dharok", "verac", "ahrim", "torag", "guthan" };
/**
* The weapon names.
*/
private static final String[] weapon_names = new String[] { "flail", "greataxe", "spear", "x-bow", "hammer", "hammers", "staff" };
/**
* The weapon body names.
*/
private static final String[] body_names = new String[] { "top", "platebody", "body" };
/**
* The helm names.
*/
private static final String[] helm_names = new String[] { "hood", "helm", "coif" };
/**
* The leg names.
*/
private static final String[] leg_names = new String[] { "skirt", "legs", "plateskirt", "platelegs" };
/**
* The prices.
*/
private static final Object[][] prices = new Object[][] { { "weapon", 100 }, { "body", 90 }, { "legs", 80 }, { "helm", 60 } };
/**
* Represents the items.
*/
private static final Object[][] ITEMS = { { 4856, "Ahrim's hood" }, { 4857, "Ahrim's hood" }, { 4858, "Ahrim's hood" }, { 4859, "Ahrim's hood" }, { 4860, "Ahrim's hood" }, { 4862, "Ahrim's staff" }, { 4863, "Ahrim's staff" }, { 4864, "Ahrim's staff" }, { 4865, "Ahrim's staff" }, { 4866, "Ahrim's staff" }, { 4868, "Ahrim's top" }, { 4869, "Ahrim's top" }, { 4870, "Ahrim's top" }, { 4871, "Ahrim's top" }, { 4872, "Ahrim's top" }, { 4874, "Ahrim's skirt" }, { 4875, "Ahrim's skirt" }, { 4876, "Ahrim's skirt" }, { 4877, "Ahrim's skirt" }, { 4878, "Ahrim's skirt" }, { 4880, "Dharok's helm" }, { 4881, "Dharok's helm" }, { 4882, "Dharok's helm" }, { 4883, "Dharok's helm" }, { 4884, "Dharok's helm" }, { 4886, "Dharok's greataxe" }, { 4887, "Dharok's greataxe" }, { 4888, "Dharok's greataxe" }, { 4889, "Dharok's greataxe" }, { 4890, "Dharok's greataxe" }, { 4892, "Dharok's platebody" }, { 4893, "Dharok's platebody" }, { 4894, "Dharok's platebody" }, { 4895, "Dharok's platebody" }, { 4896, "Dharok's platebody" }, { 4898, "Dharok's platelegs" }, { 4899, "Dharok's platelegs" }, { 4900, "Dharok's platelegs" }, { 4901, "Dharok's platelegs" }, { 4902, "Dharok's platelegs" }, { 4904, "Guthan's helm" }, { 4905, "Guthan's helm" }, { 4906, "Guthan's helm" }, { 4907, "Guthan's helm" }, { 4908, "Guthan's helm" }, { 4910, "Guthan's spear" }, { 4911, "Guthan's spear" }, { 4912, "Guthan's spear" }, { 4913, "Guthan's spear" }, { 4914, "Guthan's spear" }, { 4916, "Guthan's body" }, { 4917, "Guthan's body" }, { 4918, "Guthan's body" }, { 4919, "Guthan's body" }, { 4920, "Guthan's body" }, { 4922, "Guthan's skirt" }, { 4923, "Guthan's skirt" }, { 4924, "Guthan's skirt" }, { 4925, "Guthan's skirt" }, { 4926, "Guthan's skirt" }, { 4928, "Karil's coif" }, { 4929, "Karil's coif" }, { 4930, "Karil's coif" }, { 4931, "Karil's coif" }, { 4932, "Karil's coif" }, { 4934, "Karil's x-bow" }, { 4935, "Karil's x-bow" }, { 4936, "Karil's x-bow" }, { 4937, "Karil's x-bow" }, { 4938, "Karil's x-bow" }, { 4940, "Karil's top" }, { 4941, "Karil's top" }, { 4942, "Karil's top" }, { 4943, "Karil's top" }, { 4944, "Karil's top" }, { 4946, "Karil's skirt" }, { 4947, "Karil's skirt" }, { 4948, "Karil's skirt" }, { 4949, "Karil's skirt" }, { 4950, "Karil's skirt" }, { 4952, "Torag's helm" }, { 4953, "Torag's helm" }, { 4954, "Torag's helm" }, { 4955, "Torag's helm" }, { 4956, "Torag's helm" }, { 4958, "Torag's hammers" }, { 4959, "Torag's hammers" }, { 4960, "Torag's hammers" }, { 4961, "Torag's hammers" }, { 4962, "Torag's hammers" }, { 4964, "Torag's body" }, { 4965, "Torag's body" }, { 4966, "Torag's body" }, { 4967, "Torag's body" }, { 4968, "Torag's body" }, { 4970, "Torag's legs" }, { 4971, "Torag's legs" }, { 4972, "Torag's legs" }, { 4973, "Torag's legs" }, { 4974, "Torag's legs" }, { 4976, "Verac's helm" }, { 4977, "Verac's helm" }, { 4978, "Verac's helm" }, { 4979, "Verac's helm" }, { 4980, "Verac's helm" }, { 4982, "Verac's flail" }, { 4983, "Verac's flail" }, { 4984, "Verac's flail" }, { 4985, "Verac's flail" }, { 4986, "Verac's flail" }, { 4988, "Verac's top" }, { 4989, "Verac's top" }, { 4990, "Verac's top" }, { 4991, "Verac's top" }, { 4992, "Verac's top" }, { 4994, "Verac's skirt" }, { 4995, "Verac's skirt" }, { 4996, "Verac's skirt" }, { 4997, "Verac's skirt" }, { 4998, "Verac's skirt" } };
/**
* Gets the cost.
* @param name the name.
* @return the price.
*/
public static int getFormatedCost(String name, Item item) {
int ticks = BarrowsEquipmentRegister.TICKS;
int[] degrades = new int[] { 100, 75, 50, 25, 0 };
for (int i = 0; i < prices.length; i++) {
String check = (String) prices[i][0];
if (check.equals(name)) {
int degrade = 0;
for (int d : degrades) {
if (item.getName().contains(String.valueOf(d))) {
degrade = d;
break;
}
}
degrade -= 25 - (25 * ((double)item.getCharge() / (double)ticks));
int max = (int) prices[i][1] * 1000;
return (int) (max - (max * (degrade * 0.01)));
}
}
return 0;
}
/**
* Gets the cost of the item type.
* @param name the name.
* @return the return type.
*/
public static int getCost(String name) {
for (int i = 0; i < prices.length; i++) {
String check = (String) prices[i][0];
if (check.equals(name)) {
return (int) prices[i][1];
}
}
return 0;
}
/**
* Represents if an item is a barrows item.
* @param id the id.
* @return {@code True} if so.
*/
public static boolean isBarrowsItem(int id) {
for (int i = 0; i < ITEMS.length; i++) {
if ((int) ITEMS[i][0] == id) {
return true;
}
}
return false;
}
/**
* Gets the formatted name.
* @param id the id.
* @return the name.
*/
public static String formatedName(int id) {
for (int i = 0; i < ITEMS.length; i++) {
if ((int) ITEMS[i][0] == id) {
return (String) ITEMS[i][1];
}
}
return null;
}
/**
* Gets the equipment type.
* @param name the name.
* @return the type.
*/
public static String getEquipmentType(String name) {
name = name.toLowerCase().replace("verac's", "").replace("karil's", "").replace("dharok's", "").replace("torag's", "").replace("guthan's", "").replace("ahrim's", "").trim();
for (int i = 0; i < weapon_names.length; i++) {
if (weapon_names[i].contains(name)) {
return "weapon";
}
}
for (int k = 0; k < body_names.length; k++) {
if (body_names[k].contains(name)) {
return "body";
}
}
for (int z = 0; z < leg_names.length; z++) {
if (leg_names[z].contains(name)) {
return "legs";
}
}
for (int q = 0; q < helm_names.length; q++) {
if (helm_names[q].contains(name)) {
return "helm";
}
}
return null;
}
/**
* Method used t get its single name.
* @param name the name.
* @return the name.
*/
public static String getSingleName(String name) {
name = name.toLowerCase().replace("verac's", "").replace("karil's", "").replace("dharok's", "").replace("torag's", "").replace("guthan's", "").replace("ahrim's", "").trim();
for (int i = 0; i < weapon_names.length; i++) {
if (weapon_names[i].contains(name)) {
return weapon_names[i];
}
}
for (int k = 0; k < body_names.length; k++) {
if (body_names[k].contains(name)) {
return body_names[k];
}
}
for (int z = 0; z < leg_names.length; z++) {
if (leg_names[z].contains(name)) {
return leg_names[z];
}
}
for (int q = 0; q < helm_names.length; q++) {
if (helm_names[q].contains(name)) {
return helm_names[q];
}
}
return null;
}
/**
* Gets the bases.
* @return the base.
*/
public String[] getBase() {
return base;
}
/**
* Represents the multiple full barrows equipment items.
* @author 'Vexia
* @version 1.0
*/
public enum BarrowsFullEquipment {
VERAC_LEGS(new Item(4759, 1)), VERAC_TOP(new Item(4757, 1)), VERAC_WEAPON(new Item(4755, 1)), VERAC_HELM(new Item(4753, 1)), TORAG_LEGS(new Item(4751, 1)), TORAG_BODY(new Item(4749, 1)), TORAG_HELM(new Item(4745, 1)), TORAG_WEAPON(new Item(4747, 1)), KARIL_HELM(new Item(4732, 1)), KARIL_WEAPON(new Item(4734, 1)), KARIL_BODY(new Item(4736, 1)), KARIL_LEGS(new Item(4738, 1)), GUTHAN_HELM(new Item(4724, 1)), GUTHAN_BODY(new Item(4728, 1)), GUTHAN_LEGS(new Item(4730, 1)), GUTHAN_WEAPON(new Item(4726, 1)), DHAROK_HELM(new Item(4716, 1)), DHAROK_BODY(new Item(4720, 1)), DHAROK_LEGS(new Item(4722, 1)), DHAROK_WEAPON(new Item(4718, 1)), AHRIM_HELM(new Item(4708, 1)), AHRIM_BODY(new Item(4712, 1)), AHRIM_LEGS(new Item(4714, 1)), AHRIM_WEAPON(new Item(4710, 1));
/**
* Constructs a new {@code BarrowsEquipment} {@code Object}.
* @param full the full item.
*/
BarrowsFullEquipment(Item full) {
this.full = full;
}
/**
* Represents the full item.
*/
private final Item full;
/**
* for name
* @param name thename.
* @return the equipment.
*/
public static BarrowsFullEquipment forName(String name) {
if (name.equals("guthan body body")) {
name = "guthan body";
} else if (name.equals("torag body body")) {
name = "torag body";
} else if (name.equals("verac body")) {
name = "verac top";
}
for (BarrowsFullEquipment barrow : BarrowsFullEquipment.values()) {
if (barrow.name().toLowerCase().replace("_", " ").trim().equalsIgnoreCase(name)) {
return barrow;
}
}
return null;
}
/**
* Gets the full.
* @return The full.
*/
public Item getFull() {
return full;
}
}
}
}

View file

@ -0,0 +1,266 @@
package content.region.misthalin.lumbridge.dialogue
import content.data.RepairItem
import content.global.handlers.item.equipment.BarrowsEquipment
import core.cache.def.impl.ItemDefinition
import core.game.dialogue.DialoguePlugin
import core.game.dialogue.FacialExpression
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.diary.AchievementDiary
import core.game.node.entity.player.link.diary.DiaryType
import core.game.node.item.Item
import core.plugin.Initializable
/**
* Represents the dialogue plugin used for the bob npc who repairs items.
* @author 'Vexia
* @author Damighty - Kotlin conversion
* @version 1.0
*/
@Initializable
class BobDialogue(player: Player? = null) : DialoguePlugin(player) {
/**
* Represents the item id being repaired.
*/
private var itemId = 0
/**
* Represents the item being repaired.
*/
private lateinit var item: Item
/**
* Represents the item repairing.
*/
private var repairItem: RepairItem? = null
/**
* The achievement diary.
*/
private val level = 1
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when (stage) {
754 -> {
options("Yes, please.", "No, thank you.")
stage = 755
}
755 -> when (buttonId) {
1 -> {
player("Yes, please.")
stage = 757
}
2 -> {
player("No, thank you.")
stage = 756
}
}
756 -> end()
757 -> {
end()
val repairItemDef = RepairItem.forId(itemId)
if (repairItemDef != null) {
// Standard repairable items
if (!player.inventory.contains(995, repairItemDef.cost)) {
player.packetDispatch.sendMessage("You don't have enough to pay him.")
return true
}
if (player.inventory.remove(Item(itemId, 1))) {
player.inventory.remove(Item(995, repairItemDef.cost))
player.inventory.add(repairItemDef.product)
val costText = if (repairItemDef.cost > 0) "${repairItemDef.cost}gp" else "free"
player.packetDispatch.sendMessage("Bob fixes your ${item.name.lowercase().replace("broken", "").trim()} for $costText.")
}
} else {
// Barrows items
val barrowsDef = BarrowsEquipment.getDefinition(itemId) ?: return true
val repairCost = BarrowsEquipment.getRepairCost(item)
if (!player.inventory.contains(995, repairCost)) {
player.packetDispatch.sendMessage("You don't have enough to pay him.")
return true
}
if (player.inventory.remove(Item(itemId, 1))) {
player.inventory.remove(Item(995, repairCost))
player.inventory.add(Item(barrowsDef.repairedId))
val costText = if (repairCost > 0) "${repairCost}gp" else "free"
player.packetDispatch.sendMessage("Bob fixes your ${barrowsDef.itemName.lowercase()} for $costText.")
}
}
return true
}
678 -> end()
0 -> when (buttonId) {
1 -> {
player("Give me a quest!")
stage = -5
}
2 -> {
player("Have you anything to sell?")
stage = 10
}
3 -> {
player("Can you repair my items for me?")
stage = 20
}
4 -> {
player("I'd like to talk about Achievement Diaries.")
stage = 30
}
}
-5 -> {
interpreter.sendDialogues(npc, FacialExpression.FURIOUS, "Get yer own!")
stage = -4
}
-4 -> end()
10 -> {
npc("Yes! I buy and sell axes! Take your pick (or axe)!")
stage = 11
}
11 -> {
end()
npc.openShop(player)
}
20 -> {
npc("Of course I'll repair it, though the materials may cost", "you. Just hand me the item and I'll have a look.")
stage = 21
}
21 -> end()
30 -> {
if (AchievementDiary.canClaimLevelRewards(player, DiaryType.LUMBRIDGE, level)) {
player("I've done all the medium tasks in my Lumbridge", "Achievement Diary.")
stage = 150
} else if (AchievementDiary.canReplaceReward(player, DiaryType.LUMBRIDGE, level)) {
player("I've seemed to have lost my explorer's ring...")
stage = 160
} else {
options("What is the Achievement Diary?", "What are the rewards?", "How do I claim the rewards?", "See you later.")
stage = 31
}
}
31 -> when (buttonId) {
1 -> {
player("What is the Achievement Diary?")
stage = 110
}
2 -> {
player("What are the rewards?")
stage = 120
}
3 -> {
player("How do I claim the rewards?")
stage = 130
}
4 -> {
player("See you later!")
stage = 140
}
}
110 -> {
npc("Ah, well, it's a diary that helps you keep track of", "particular achievements you've made in the world of", "Gielinor. In Lumbridge and Draynor I can help you", "discover some very useful things indeed.")
stage++
}
111 -> {
npc("Eventually with enough exploration you will be", "rewarded for your explorative efforts.")
stage++
}
112 -> {
npc("You can access your Achievement Diary by going to", "the Quest Journal. When you've opened the Quest", "Journal click on the green star icon on the top right", "hand corner. This will open the diary.")
stage = 30
}
120 -> {
npc("Ah, well there are different rewards for each", "Achievement Diary. For completing the Lumbridge and", "Draynor diary you are presented with an explorer's", "ring.")
stage++
}
121 -> {
npc("This ring will become increasingly useful with each", "section of the diary that you complete.")
stage = 30
}
130 -> {
npc("You need to complete the tasks so that they're all ticked", "off, then you can claim your reward. Most of them are", "straightforward although you might find some required", "quests to be started, if not finished.")
stage++
}
131 -> {
npc("To claim the explorer's ring speak to Explorer Jack", " in Lumbridge, Ned in Draynor Village or myself.")
stage = 30
}
140 -> end()
150 -> {
npc("Yes I see that, you'll be wanting your", "reward then I assume?")
stage++
}
151 -> {
player("Yes please.")
stage++
}
152 -> {
AchievementDiary.flagRewarded(player, DiaryType.LUMBRIDGE, level)
npc("This ring is a representation of the adventures you", "went on to complete your tasks.")
stage++
}
153 -> {
player("Wow, thanks!")
stage = 30
}
160 -> {
AchievementDiary.grantReplacement(player, DiaryType.LUMBRIDGE, level)
npc("You better be more careful this time.")
stage = -1
}
}
return true
}
override fun newInstance(player: Player): DialoguePlugin {
return BobDialogue(player)
}
override fun open(vararg args: Any): Boolean {
npc = args[0] as NPC
var repair = false
var wrong = false
if (npc.id == 3797 && args.size == 1) {
player("Can you repair my items for me?")
stage = 20
return true
}
if (args.size == 1) {
options("Give me a quest!", "Have you anything to sell?", "Can you repair my items for me?", "Talk about Achievement Diaries")
stage = 0
return true
}
if (args.size > 1) repair = args[1] as Boolean
if (args.size > 2) wrong = args[2] as Boolean
if (args.size > 3) {
repairItem = RepairItem.forId(args[3] as Int)
itemId = args[3] as Int
}
if (args.size > 4) item = args[4] as Item
if (repair && !wrong) {
val cost = RepairItem.forId(itemId)?.cost ?: BarrowsEquipment.getRepairCost(item)
val costText = if (cost > 0) "${cost}gp" else "free"
npc("Quite badly damaged, but easy to repair. Would you", "like me to repair it for $costText?")
stage = 754
return true
}
if (repair && wrong) {
npc("Sorry friend, but I can't do anything with that.")
stage = 678
return true
}
return true
}
override fun getIds(): IntArray {
return intArrayOf(519, 3797)
}
}

View file

@ -1,48 +0,0 @@
package content.region.misthalin.lumbridge.handlers;
import content.region.misthalin.lumbridge.dialogue.BobDialogue;
import content.data.RepairItem;
import core.game.interaction.NodeUsageEvent;
import core.game.interaction.UseWithHandler;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
import core.plugin.Plugin;
import core.plugin.Initializable;
import core.plugin.ClassScanner;
/**
* Represents the plugin used to handle an item being used on bob.
* @author 'Vexia
* @version 1.0
*/
@Initializable
public final class BobRepairItem extends UseWithHandler {
/**
* Constructs a new {@code BobRepairItem} {@code Object}.
*/
public BobRepairItem() {
super(494, 468, 496, 470, 498, 472, 500, 502, 474, 504, 476, 506, 478, 6741, 4856, 4857, 4858, 4859, 4860, 4862, 4863, 4864, 4865, 4866, 4868, 4869, 4870, 4871, 4872, 4874, 4875, 4876, 4877, 4878, 4880, 4881, 4882, 4883, 4884, 4886, 4887, 4888, 4889, 4890, 4892, 4893, 4894, 4895, 4896, 4898, 4899, 4900, 4901, 4902, 4904, 4905, 4906, 4907, 4908, 4910, 4911, 4912, 4913, 4914, 4916, 4917, 4918, 4919, 4920, 4922, 4923, 4924, 4925, 4926, 4928, 4929, 4930, 4931, 4932, 4934, 4935, 4936, 4937, 4938, 4940, 4941, 4942, 4943, 4944, 4946, 4947, 4948, 4949, 4950, 4952, 4953, 4954, 4955, 4956, 4958, 4959, 4960, 4961, 4962, 4964, 4965, 4966, 4967, 4968, 4970, 4971, 4972, 4973, 4974, 4976, 4977, 4978, 4979, 4980, 4982, 4983, 4984, 4985, 4986, 4988, 4989, 4990, 4991, 4992, 4994, 4995, 4996, 4997, 4998);
}
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
addHandler(519, NPC_TYPE, this);
addHandler(3797, NPC_TYPE, this);
ClassScanner.definePlugin(new BobDialogue());
return this;
}
@Override
public boolean handle(NodeUsageEvent event) {
final Player player = event.getPlayer();
final RepairItem repair = RepairItem.forId(event.getUsedItem().getId());
if (repair == null && !BobDialogue.BarrowsEquipment.isBarrowsItem(event.getUsedItem().getId())) {
player.getDialogueInterpreter().open(519, ((NPC) event.getUsedWith()), true, true, null);
return true;
}
player.getDialogueInterpreter().open(519, ((NPC) event.getUsedWith()), true, false, event.getUsedItem().getId(), event.getUsedItem());
return true;
}
}

View file

@ -0,0 +1,47 @@
package content.region.misthalin.lumbridge.handlers
import content.global.handlers.item.equipment.BarrowsEquipment
import content.data.RepairItem
import core.game.interaction.NodeUsageEvent
import core.game.interaction.UseWithHandler
import core.game.node.entity.npc.NPC
import core.plugin.Plugin
import core.plugin.Initializable
private val ALL_REPAIRABLE_ITEM_IDS = (RepairItem.repairableItemIds + BarrowsEquipment.getAllRepairableBarrowsIds()).toIntArray()
/**
* Handles items being used on Bob for repair services.
* @author 'Vexia
* @author Damighty - Kotlin conversion
*/
@Initializable
class BobRepairItem : UseWithHandler(*ALL_REPAIRABLE_ITEM_IDS) {
override fun newInstance(arg: Any?): Plugin<Any> {
addHandler(519, NPC_TYPE, this)
addHandler(3797, NPC_TYPE, this)
return this
}
override fun handle(event: NodeUsageEvent): Boolean {
val player = event.player
val item = event.usedItem
val npc = event.usedWith as NPC
val isBarrowsItem = BarrowsEquipment.isBarrowsItem(item.id)
if (isBarrowsItem) {
if (BarrowsEquipment.isFullyRepaired(item.id)) {
player.dialogueInterpreter.open(519, npc, true, true, item.id)
return true
}
} else if (RepairItem.forId(item.id) == null) {
player.dialogueInterpreter.open(519, npc, true, true)
return true
}
player.dialogueInterpreter.open(519, npc, true, false, item.id, item)
return true
}
}

View file

@ -1,5 +1,6 @@
package core.game.node.entity.combat.graves package core.game.node.entity.combat.graves
import content.global.handlers.item.equipment.BarrowsEquipment
import core.api.clearHintIcon import core.api.clearHintIcon
import core.api.registerHintIcon import core.api.registerHintIcon
import core.api.sendMessage import core.api.sendMessage
@ -65,7 +66,11 @@ class Grave : AbstractNPC {
continue continue
} }
val finalItem = GraveController.checkTransform(item) val finalItem = if (BarrowsEquipment.isBarrowsItem(item.id) && !BarrowsEquipment.isFullyRepaired(item.id)) {
BarrowsEquipment.graveDeathDurabilityReduction(item) ?: item
} else {
GraveController.checkTransform(item)
}
val gi = GroundItemManager.create(finalItem, this.location, player) val gi = GroundItemManager.create(finalItem, this.location, player)
gi.isRemainPrivate = true gi.isRemainPrivate = true

View file

@ -1,5 +1,6 @@
package core.game.node.entity.player; package core.game.node.entity.player;
import content.global.handlers.item.equipment.BarrowsEquipment;
import content.global.handlers.item.equipment.special.SalamanderSwingHandler; import content.global.handlers.item.equipment.special.SalamanderSwingHandler;
import content.global.skill.runecrafting.PouchManager; import content.global.skill.runecrafting.PouchManager;
import core.api.ContentAPIKt; import core.api.ContentAPIKt;
@ -661,11 +662,13 @@ public class Player extends Entity {
if (item == null) continue; if (item == null) continue;
if (killer instanceof Player) if (killer instanceof Player)
itemsLost.append(getItemName(item.getId())).append("(").append(item.getAmount()).append("), "); itemsLost.append(getItemName(item.getId())).append("(").append(item.getAmount()).append("), ");
if (GraveController.shouldCrumble(item.getId())) if (GraveController.shouldCrumble(item.getId()))
continue; continue;
if (GraveController.shouldRelease(item.getId())) if (GraveController.shouldRelease(item.getId()))
continue; continue;
if (!item.getDefinition().isTradeable()) {
if (!BarrowsEquipment.isBarrowsItem(item.getId()) && !item.getDefinition().isTradeable()) {
if (killer instanceof Player) { if (killer instanceof Player) {
int value = item.getDefinition().getAlchemyValue(true); int value = item.getDefinition().getAlchemyValue(true);
if (getStatLevel(killer, Skills.MAGIC) < 55) value /= 2; if (getStatLevel(killer, Skills.MAGIC) < 55) value /= 2;
@ -673,7 +676,14 @@ public class Player extends Entity {
continue; continue;
} else stayPrivate = true; } else stayPrivate = true;
} }
if (BarrowsEquipment.isBarrowsItem(item.getId())) {
if (!BarrowsEquipment.isBroken(item.getId())) {
int brokenItemId = Objects.requireNonNull(BarrowsEquipment.getDefinition(item.getId())).getBrokenId();
item = new Item(brokenItemId, item.getAmount());
}
} else {
item = GraveController.checkTransform(item); item = GraveController.checkTransform(item);
}
GroundItem gi = GroundItemManager.create(item, location, killer instanceof Player ? (Player) killer : this); GroundItem gi = GroundItemManager.create(item, location, killer instanceof Player ? (Player) killer : this);
gi.setRemainPrivate(stayPrivate); gi.setRemainPrivate(stayPrivate);
} }