Authenticity improvements to runecrafting pouches. Due to changes in degrade counters, they will degrade within the next 1 or 2 fills after this update; this is a one-time event. Resolve (or prevent) this by repairing via the dark mage

This commit is contained in:
Player Name 2024-11-14 11:56:16 +00:00 committed by Ryan
parent 1da53c448d
commit 7a6adda997
3 changed files with 107 additions and 96 deletions

View file

@ -1,5 +1,6 @@
package content.global.skill.runecrafting
import core.api.*
import core.game.container.Container
import core.game.node.entity.player.Player
import core.game.node.entity.skill.Skills
@ -7,109 +8,131 @@ import core.game.node.item.Item
import org.json.simple.JSONArray
import org.json.simple.JSONObject
import org.rs09.consts.Items
import core.tools.colorize
/**
* A class for managing rune pouches.
* @param player the player this manager instance belongs to.
* @author Ceikry
* @author Ceikry, Player Name
*/
class PouchManager(val player: Player) {
val pouches = mapOf(
Items.SMALL_POUCH_5509 to RCPouch(3,1),
Items.MEDIUM_POUCH_5510 to RCPouch(6,25),
Items.LARGE_POUCH_5512 to RCPouch(9,50),
Items.GIANT_POUCH_5514 to RCPouch(12,75)
Items.SMALL_POUCH_5509 to RCPouch(3, 3, 1),
Items.MEDIUM_POUCH_5510 to RCPouch(6, 264, 25),
Items.LARGE_POUCH_5512 to RCPouch(9, 186, 50),
Items.GIANT_POUCH_5514 to RCPouch(12,140, 75)
)
/**
* Method to add essence to a pouch
* @param pouchId the id of the pouch we are adding to
* @param itemId the item ID of the pouch we are adding to
* @param amount the amount of essence to add
* @param essence the ID of the essence item we are trying to add
* @author Ceikry
* @author Ceikry, Player Name
*/
fun addToPouch(pouchId: Int, amount: Int, essence: Int){
if(!checkRequirement(pouchId)){
player.sendMessage(colorize("%RYou lack the required level to use this pouch."))
fun addToPouch(itemId: Int, amount: Int, essence: Int) {
val pouchId = if (isDecayedPouch(itemId)) itemId - 1 else itemId
if (!checkRequirement(pouchId)) {
sendMessage(player, "You lack the required level to use this pouch.")
return
}
var amt = amount
val pouch = pouches[pouchId]
val otherEssence = when(essence){
val otherEssence = when(essence) {
Items.RUNE_ESSENCE_1436 -> Items.PURE_ESSENCE_7936
Items.PURE_ESSENCE_7936 -> Items.RUNE_ESSENCE_1436
else -> 0
}
pouch ?: return
if(amount > pouch.container.freeSlots()){
if (amount > pouch.container.freeSlots()) {
amt = pouch.container.freeSlots()
}
if(amt == 0){
player.sendMessage("This pouch is already full.")
if (amt == pouch.container.freeSlots()) {
sendMessage(player, "Your pouch is full.") //https://www.youtube.com/watch?v=wbYtRwODKTo
}
if(pouch.container.contains(otherEssence,1)){
player.sendMessage("You can only store one type of essence in each pouch.")
if (pouch.container.contains(otherEssence,1)) {
sendMessage(player, "You can only store one type of essence in each pouch.")
return
}
player.inventory.remove(Item(essence,amt))
pouch.container.add(Item(essence,amt))
}
var disappeared = false
if (itemId != Items.SMALL_POUCH_5509) {
pouch.charges -= amt
}
if (pouch.charges <= 0) {
pouch.currentCap -= when (pouchId) {
Items.MEDIUM_POUCH_5510 -> 1
Items.LARGE_POUCH_5512 -> 2
Items.GIANT_POUCH_5514 -> 3
else /*small pouch*/ -> 0
}
if (pouch.currentCap <= 0) {
// The pouch will disappear: https://runescape.wiki/w/Runecrafting_pouches?oldid=708494, https://oldschool.runescape.wiki/w/Essence_pouch
// "Degraded pouches will continue to degrade and lose essence capacity until they disappear or are repaired." implies that this is the end result of a gradual decay process
if (removeItem(player, itemId)) {
disappeared = true
sendMessage(player, "Your pouch has degraded completely.")
// Reset the pouch for when the player obtains a new one
pouch.currentCap = pouch.capacity
pouch.charges = pouch.maxCharges
pouch.remakeContainer()
}
} else {
if (!isDecayedPouch(itemId)) {
val slot = player.inventory.getSlot(Item(itemId))
replaceSlot(player, slot, Item(itemId + 1))
}
sendMessage(player, "Your pouch has decayed through use.") //https://www.youtube.com/watch?v=FUcPYrgPUlQ
pouch.charges = 9 * pouch.currentCap //implied by multiple contemporaneous sources, quantified only by https://oldschool.runescape.wiki/w/Large_pouch
pouch.remakeContainer()
if (amt > pouch.currentCap) {
amt = pouch.currentCap
}
}
}
val essItem = Item(essence, amt)
if (!disappeared && removeItem(player, essItem)) {
pouch.container.add(essItem)
}
}
/**
* Method to withdraw rune essence from a pouch.
* @param pouchId the item ID of the pouch to withdraw from
* @author Ceikry
* @param itemId the item ID of the pouch to withdraw from
* @author Ceikry, Player Name
*/
fun withdrawFromPouch(pouchId: Int){
fun withdrawFromPouch(itemId: Int) {
val pouchId = if (isDecayedPouch(itemId)) itemId - 1 else itemId
val pouch = pouches[pouchId]
pouch ?: return
val playerFree = player.inventory.freeSlots()
val playerFree = freeSlots(player)
var amount = pouch.currentCap - pouch.container.freeSlots()
if (amount > playerFree) amount = playerFree
player.debug("$amount")
if(amount == 0) return
val essence = Item(pouch.container.get(0).id,amount)
pouch.container.remove(essence)
pouch.container.shift()
player.inventory.add(essence)
if(pouch.charges-- <= 0){
pouch.currentCap -= when(pouchId){
5510 -> 1
5512 -> 2
5514 -> 3
else -> 0
}
if(pouch.currentCap <= 0){
player.inventory.remove(Item(pouchId))
player.inventory.add(Item(pouchId + 1))
player.sendMessage(colorize("%RYour ${Item(pouchId).name} has degraded completely."))
}
pouch.remakeContainer()
pouch.charges = 10
if(pouchId != 5509) {
player.sendMessage(colorize("%RYour ${Item(pouchId).name.toLowerCase()} has degraded slightly from use."))
if (amount > playerFree) {
amount = playerFree
} else {
sendMessage(player, "Your pouch has no essence left in it.") //https://www.youtube.com/watch?v=wbYtRwODKTo
if (amount == 0) {
return
}
}
val essence = Item(pouch.container.get(0).id, amount)
pouch.container.remove(essence)
pouch.container.shift()
addItem(player, essence.id, essence.amount)
}
/**
* Method to save pouches to a root JSONObject
* @param root the JSONObject we are adding the "pouches" JSONArray to
* @author Ceikry
*/
fun save(root: JSONObject){
fun save(root: JSONObject) {
val pouches = JSONArray()
for(i in this.pouches){
for(i in this.pouches) {
val pouch = JSONObject()
pouch.put("id",i.key.toString())
val items = JSONArray()
for(item in i.value.container.toArray()){
for(item in i.value.container.toArray()) {
item ?: continue
val it = JSONObject()
it.put("itemId",item.id.toString())
@ -124,14 +147,13 @@ class PouchManager(val player: Player) {
root.put("pouches",pouches)
}
/**
* Method to parse save data from a JSONArray
* @param data the JSONArray that contains the data to parse
* @author Ceikry
*/
fun parse(data: JSONArray){
for(e in data){
fun parse(data: JSONArray) {
for (e in data){
val pouch = e as JSONObject
val id = pouch["id"].toString().toInt()
val p = pouches[id]
@ -141,7 +163,7 @@ class PouchManager(val player: Player) {
p.charges = charges
p.currentCap = currentCap
p.remakeContainer()
for(i in pouch["container"] as JSONArray){
for (i in pouch["container"] as JSONArray) {
val it = i as JSONObject
it["itemId"] ?: continue
val item = it["itemId"].toString().toInt()
@ -151,33 +173,31 @@ class PouchManager(val player: Player) {
}
}
/**
* Method for checking the level requirement for a given pouch.
* @param pouchId the item ID of the pouch to check
* @author Ceikry
*/
fun checkRequirement(pouchId: Int): Boolean{
fun checkRequirement(pouchId: Int): Boolean {
val p = pouches[pouchId]
p ?: return false
return player.skills.getLevel(Skills.RUNECRAFTING) >= p.levelRequirement
}
/**
* Method for sending the player a message about how much space is left in a pouch
* @param pouchId the item ID of the pouch to check
* @author Ceikry
* @param itemId the item ID of the pouch to check
* @author Ceikry, Player Name
*/
fun checkAmount(pouchId: Int){
fun checkAmount(itemId: Int) {
val pouchId = if (isDecayedPouch(itemId)) itemId - 1 else itemId
val p = pouches[pouchId]
p ?: return
player.sendMessage("This pouch has space for ${p.container.freeSlots()} more essence.")
}
fun isDecayedPouch(pouchId: Int): Boolean{
if(pouchId == 5510) return false
fun isDecayedPouch(pouchId: Int): Boolean {
if (pouchId == Items.MEDIUM_POUCH_5510) return false
return pouches[pouchId - 1] != null
}
@ -185,12 +205,12 @@ class PouchManager(val player: Player) {
* A class that represents a runecrafting pouch.
* @author Ceikry
*/
class RCPouch(val capacity: Int, val levelRequirement: Int){
class RCPouch(val capacity: Int, val maxCharges: Int, val levelRequirement: Int) {
var container = Container(capacity)
var currentCap = capacity
var charges = 10
fun remakeContainer(){
var charges = maxCharges
fun remakeContainer() {
this.container = Container(currentCap)
}
}
}
}

View file

@ -11,7 +11,7 @@ import core.tools.colorize
/**
* Handles the rune pouches.
* @author Ceikry
* @author Ceikry, Player Name
*/
class RunePouchPlugin : OptionHandler() {
@Throws(Throwable::class)
@ -37,21 +37,11 @@ class RunePouchPlugin : OptionHandler() {
if(preferenceFlag == 0) rEssAmt else pEssAmt
)
if(player.pouchManager.isDecayedPouch(node.id)){
player.debug("E2")
when(option) { //Handling for IF the pouch has already completely decayed
"drop" -> player.dialogueInterpreter.open(9878,Item(node.id))
else -> player.sendMessage(colorize("%RThis pouch has completely decayed and needs to be repaired."))
}
} else {
player.debug("E")
when (option) { //Normal handling
"fill" -> player.pouchManager.addToPouch(node.id, essence.amount, essence.id)
"empty" -> player.pouchManager.withdrawFromPouch(node.id)
"check" -> player.pouchManager.checkAmount(node.id)
"drop" -> player.dialogueInterpreter.open(9878,Item(node.id))
}
when (option) {
"fill" -> player.pouchManager.addToPouch(node.id, essence.amount, essence.id)
"empty" -> player.pouchManager.withdrawFromPouch(node.id)
"check" -> player.pouchManager.checkAmount(node.id)
"drop" -> player.dialogueInterpreter.open(9878,Item(node.id))
}
return true
}
@ -59,4 +49,4 @@ class RunePouchPlugin : OptionHandler() {
override fun isWalk(): Boolean {
return false
}
}
}

View file

@ -4,6 +4,7 @@ import core.game.dialogue.DialoguePlugin;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
import core.game.node.item.Item;
import org.rs09.consts.Items;
/**
* Handles the dark mages dialogue.
@ -140,18 +141,18 @@ public final class DarkMageDialogue extends DialoguePlugin {
private boolean repair() {
player.pouchManager.getPouches().forEach((id, pouch) -> {
pouch.setCurrentCap(pouch.getCapacity());
pouch.setCharges(10);
Item essence = null;
if(!pouch.getContainer().isEmpty()){
int ess = pouch.getContainer().get(0).getId();
int amount = pouch.getContainer().getAmount(ess);
essence = new Item(ess,amount);
pouch.setCharges(pouch.getMaxCharges());
Item essItem = null;
if (!pouch.getContainer().isEmpty()) {
int essence = pouch.getContainer().get(0).getId();
int amount = pouch.getContainer().getAmount(essence);
essItem = new Item(essence, amount);
}
pouch.remakeContainer();
if(essence != null){
pouch.getContainer().add(essence);
if (essItem != null) {
pouch.getContainer().add(essItem);
}
if(id != 5509) {
if (id != Items.SMALL_POUCH_5509) {
if (player.getInventory().contains(id + 1, 1)) {
player.getInventory().remove(new Item(id + 1, 1));
player.getInventory().add(new Item(id, 1));