Fixed numerous interfaces, including Puro puro, Destroy item, Equipment, kept on death, Cooking (single prompts i.e. raw fish -> range), Fletching (make set i.e. fletching arrows, bow)

Rewrote herb cleaning to listener
Fixed studded leather crafting level requirement and xp
Fixed bow stringing stealing strings
::quest <player> can now be used to look up a player's completed quests
This commit is contained in:
Woahscam
2023-11-11 03:16:35 +00:00
committed by Ryan
parent 098d947d87
commit 8ef5d8bce4
23 changed files with 792 additions and 575 deletions
@@ -1,5 +1,7 @@
package content.global.handlers.iface;
import content.global.skill.summoning.familiar.BurdenBeast;
import core.api.ContentAPIKt;
import core.cache.def.impl.ItemDefinition;
import core.game.component.Component;
import core.game.component.ComponentDefinition;
@@ -24,6 +26,7 @@ import core.game.global.action.EquipHandler;
import core.game.interaction.IntType;
import core.game.interaction.InteractionListeners;
import core.game.world.GameWorld;
import core.tools.Log;
/**
* Represents the equipment interface.
@@ -35,6 +38,7 @@ public final class EquipmentInterface extends ComponentPlugin {
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ComponentDefinition.put(102, this);
ComponentDefinition.put(387, this);
ComponentDefinition.put(667, this);
ComponentDefinition.put(670, this);
@@ -111,20 +115,46 @@ public final class EquipmentInterface extends ComponentPlugin {
if (p.getInterfaceManager().isOpened() && p.getInterfaceManager().getOpened().getId() == 102) {
return true;
}
boolean skulled = p.getSkullManager().isSkulled();
boolean usingProtect = p.getPrayer().get(PrayerType.PROTECT_ITEMS);
p.getInterfaceManager().openComponent(102);
p.getPacketDispatch().sendIfaceSettings(211, 0, 2, 6684690, 4);
p.getPacketDispatch().sendIfaceSettings(212, 0, 2, 6684693, 42);
// (Highlight white items are auto destroyed on death Enum#616 (Items kept on death interface) TODO: Parse server sided
// SCRIPT 118 - Items kept on death interface CS
// ARG 0: Safe location check Takes: 0 Safe Area/2 in POH/3 in Castle Wars/4 in Trouble Brewing/5 in Barbass
int zoneType = p.getZoneMonitor().getType();
// ARG 1: Amount of items kept on death Takes: 0/1/3/4
Container[] itemArray = DeathTask.getContainers(p);
Container kept = itemArray[0];
int state = 0; // 1=familiar carrying items
int keptItems = skulled ? (usingProtect ? 1 : 0) : (usingProtect ? 4 : 3);
int zoneType = p.getZoneMonitor().getType();
int pvpType = p.getSkullManager().isWilderness() ? 0 : 1;
Object[] params = new Object[] { 11510, 12749, "", state, pvpType, kept.getId(3), kept.getId(2), kept.getId(1), kept.getId(0), keptItems, zoneType };
PacketRepository.send(ContainerPacket.class, new ContainerContext(p, 149, 0, 91, itemArray[1], false));
p.getPacketDispatch().sendRunScript(118, "iiooooiisii", params);
int amtKeptOnDeath = kept.itemCount();
if (amtKeptOnDeath > 4 && zoneType == 0) {
ContentAPIKt.log(this.getClass(), Log.ERR, "Items kept on death interface should not contain more than 4 items when not in a safe zone!");
}
// ARG 2: Item kept on death slot 0
int slot0 = kept.getId(0);
// ARG 3: Item kept on death slot 1
int slot1 = kept.getId(1);
// ARG 4: Item kept on death slot 2
int slot2 = kept.getId(2);
// ARG 5: Item kept on death slot 3
int slot3 = kept.getId(3);
// ARG 6: Player skulled Takes: 0 not skulled/1 skulled
int skulled = p.getSkullManager().isSkulled() ? 1 : 0;
// ARG 7: Player has summoning creature out Takes: 0 not out/1 Creature summoned
int hasBoB;
if (p.getFamiliarManager().hasFamiliar()) {
if (p.getFamiliarManager().getFamiliar().isBurdenBeast()) {
hasBoB = ((BurdenBeast) p.getFamiliarManager().getFamiliar()).getContainer().isEmpty() ? 0 : 1;
} else {
hasBoB = 0;
}
} else {
hasBoB = 0;
}
// ARG 8: String for effect:
// if (arg1 == 0) arg8 + " This reduces the items you keep from three to zero!"
// if (arg1 == 1) arg8 + " This reduces the items you keep from three to zero!" + "<br>" + "<br>" + "However, you also have the " + "<col=ff3333>" + "Protect Items" + "<col=ff981f>" + " prayer active, which saves you one extra item!");
Object[] params = new Object[] { hasBoB, skulled, slot3, slot2, slot1, slot0, amtKeptOnDeath, zoneType, "You are skulled." };
p.getPacketDispatch().sendRunScript(118, "siiooooii", params);
p.getInterfaceManager().openComponent(102);
break;
case 28:
if (opcode == 81) {
@@ -4,6 +4,7 @@ import core.api.*
import core.cache.def.impl.ItemDefinition
import core.game.interaction.IntType
import core.game.interaction.InteractionListener
import core.game.node.item.Item
import org.rs09.consts.Items
import org.rs09.consts.Sounds
import java.util.*
@@ -17,18 +18,14 @@ class EmptyOptionListener : InteractionListener {
on(EmptyItem.emptyItemList.toIntArray(), IntType.ITEM, "empty", "empty bowl", "empty dish") { player, node ->
if (node.name.contains("brew") || node.name.contains("potion") || node.name.lowercase(Locale.getDefault()).contains("poison") || node.name.lowercase(Locale.getDefault()).contains("serum") || node.name.contains("cure") || node.name.contains("mix") || node.name.contains("balm")) {
if (removeItem(player, node.id)) {
addItem(player, EmptyItem.getEmpty(Items.POTION_195)!!)
playAudio(player, EmptyItem.getEmptyAudio(Items.POTION_195)!!)
}
replaceSlot(player, node.asItem().slot, Item(EmptyItem.getEmpty(Items.POTION_195)!!), node.asItem())
playAudio(player, EmptyItem.getEmptyAudio(Items.POTION_195)!!)
return@on true
}
if (EmptyItem.emptyItemMap[node.id] != null) {
if (removeItem(player, node.id)) {
addItem(player, EmptyItem.getEmpty(node.id)!!)
if (EmptyItem.getEmptyAudio(node.id) != -1) playAudio(player, EmptyItem.getEmptyAudio(node.id)!!)
EmptyItem.getEmptyMessage(node.id)?.let { sendMessage(player, it) }
}
replaceSlot(player, node.asItem().slot, Item(EmptyItem.getEmpty(node.id)!!), node.asItem())
if (EmptyItem.getEmptyAudio(node.id) != -1) playAudio(player, EmptyItem.getEmptyAudio(node.id)!!)
EmptyItem.getEmptyMessage(node.id)?.let { sendMessage(player, it) }
}
return@on true
}
@@ -3,7 +3,6 @@ package content.global.skill.cooking
import core.api.*
import core.cache.def.impl.ItemDefinition
import core.game.node.scenery.Scenery
import content.global.skill.cooking.CookableItems
import content.global.skill.cooking.CookingRewrite.Companion.cook
import core.net.packet.PacketRepository
import core.net.packet.context.ChildPositionContext
@@ -15,6 +14,7 @@ import core.tools.START_DIALOGUE
/**
* @author Ceikry
* @author bushtail - fixing it up
* @auther Woah - for more fixing up
*/
class CookingDialogue(vararg val args: Any) : DialogueFile(){
@@ -47,7 +47,7 @@ class CookingDialogue(vararg val args: Any) : DialogueFile(){
"Dry the meat into sinew",
"Cook the meat"
)
stage = 100
stage = if (amountInInventory(player!!, initial) > 1) 100 else 101
return
}
}
@@ -78,7 +78,7 @@ class CookingDialogue(vararg val args: Any) : DialogueFile(){
when (buttonID) {
1 -> {
product = Items.SINEW_9436
display(Items.COOKED_MEAT_2142)
display()
}
2 -> {
product = CookableItems.forId(initial).cooked
@@ -86,6 +86,19 @@ class CookingDialogue(vararg val args: Any) : DialogueFile(){
}
}
}
101 -> {
when (buttonID) {
1 -> {
end()
cook(player!!, `object`, initial, Items.SINEW_9436, 1)
}
2 -> {
end()
cook(player!!, `object`, initial, CookableItems.forId(initial).cooked, 1)
}
}
}
}
}
@@ -99,12 +112,23 @@ class CookingDialogue(vararg val args: Any) : DialogueFile(){
return -1
}
fun display(vararg args : Int) {
fun display() {
player!!.packetDispatch.sendItemZoomOnInterface(initial, 160, 307, 2)
player!!.packetDispatch.sendString("<br><br><br><br>${ItemDefinition.forId(initial).name}", 307, 6)
// Re-format this interface because it is not formatted properly for the chat-box
// Swords
PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 307, 0, 12, 15))
PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 307, 1, 431, 15))
// "How many would you like to cook?"
PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 307, 7, 0, 12))
// Right click context menu boxes
PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 307, 3, 58, 27))
PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 307, 4, 58, 27))
PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 307, 5, 58, 27))
PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 307, 6, 58, 27))
player!!.interfaceManager.openChatbox(307)
PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 307, 3, 60, 90))
PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 307, 2, 208, 20))
player!!.packetDispatch.sendItemZoomOnInterface(if(args.size == 1) args[0] else product, 160, 307, 2)
player!!.packetDispatch.sendString(ItemDefinition.forId(product).name, 307, 3)
stage = 1
}
}
@@ -1,5 +1,6 @@
package content.global.skill.cooking
import core.api.amountInInventory
import core.game.interaction.IntType
import core.game.interaction.InteractionListener
import core.game.node.entity.player.Player
@@ -15,6 +16,7 @@ import org.rs09.consts.Items.UNCOOKED_CAKE_1889
/**
* @author Ceikry
* @author bushtail - added bear meat for sinew making
* @author Woah - added single food cooking
*/
class CookingRewrite : InteractionListener {
@@ -47,7 +49,17 @@ class CookingRewrite : InteractionListener {
}
//cook a standard item
player.dialogueInterpreter.open(CookingDialogue(item.id,obj))
if (amountInInventory(player, item.id) > 1) {
player.dialogueInterpreter.open(CookingDialogue(item.id,obj))
} else {
// Don't display dialogue if player only has *1* of the item
val product = if (CookableItems.intentionalBurn(item.id)) { // checks intentional burning
CookableItems.getIntentionalBurn(item.id).id
} else {
CookableItems.forId(item.id).cooked
}
cook(player, obj, item.id, product, 1)
}
return@onUseWith true
}
@@ -71,7 +71,7 @@ public final class StuddedArmourPlugin extends UseWithHandler {
* @version 1.0
*/
public enum StuddedArmour {
CHAPS(new Item(1095), new Item(1097), 18, 27), BODY(new Item(1129), new Item(1133), 41, 40);
CHAPS(new Item(1095), new Item(1097), 44, 42), BODY(new Item(1129), new Item(1133), 41, 40);
/**
* Represents the unstudded item.
@@ -63,7 +63,7 @@ class FletchingListeners : InteractionListener {
onUseWith(IntType.ITEM,ARROW_SHAFT,*FEATHERS){ player, shaft, feather ->
val handler: SkillDialogueHandler =
object : SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, Item(FLETCHED_SHAFT)) {
object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, Item(FLETCHED_SHAFT)) {
override fun create(amount: Int, index: Int) {
player.pulseManager.run(HeadlessArrowPulse(player, shaft.asItem(), Item(feather.id), amount))
}
@@ -73,14 +73,13 @@ class FletchingListeners : InteractionListener {
}
}
handler.open()
PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, Components.SKILL_MULTI1_309, 2, 210, 10))
return@onUseWith true
}
onUseWith(IntType.ITEM,FLETCHED_SHAFT,*UNFINISHED_ARROWS){ player, shaft, unfinished ->
val head = Fletching.arrowHeadMap[unfinished.id] ?: return@onUseWith false
val handler: SkillDialogueHandler =
object : SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, head.getFinished()) {
object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, head.getFinished()) {
override fun create(amount: Int, index: Int) {
player.pulseManager.run(ArrowHeadPulse(player, shaft.asItem(), head, amount))
}
@@ -90,7 +89,6 @@ class FletchingListeners : InteractionListener {
}
}
handler.open()
PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, Components.SKILL_MULTI1_309, 2, 210, 10))
return@onUseWith true
}
@@ -49,7 +49,7 @@ public class FletchingPlugin extends UseWithHandler {
//handle darts
if(Fletching.isDart(event.getUsedItem().getId())){
final Fletching.Darts dart = Fletching.dartMap.get(event.getUsedItem().getId());
SkillDialogueHandler handler = new SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, dart.getFinished()) {
SkillDialogueHandler handler = new SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, dart.getFinished()) {
@Override
public void create(final int amount, int index) {
player.getPulseManager().run(new DartPulse(player, event.getUsedItem(), dart, amount));
@@ -60,7 +60,6 @@ public class FletchingPlugin extends UseWithHandler {
}
};
handler.open();
PacketRepository.send(RepositionChild.class, new ChildPositionContext(player, 309, 2, 230, 10));
return true;
}
@@ -78,7 +77,7 @@ public class FletchingPlugin extends UseWithHandler {
final boolean hasFeather = (featherId == 314 || (featherId >= 10087 && featherId <= 10091));
if (hasFeather) {
SkillDialogueHandler handler = new SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, bolt.getFinished()) {
SkillDialogueHandler handler = new SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, bolt.getFinished()) {
@Override
public void create(final int amount, int index) {
player.getPulseManager().run(new BoltPulse(player, event.getUsedItem(), bolt, new Item(featherId), amount));
@@ -89,7 +88,6 @@ public class FletchingPlugin extends UseWithHandler {
}
};
handler.open();
PacketRepository.send(RepositionChild.class, new ChildPositionContext(player, 309, 2, 210, 10));
return true;
}
return false;
@@ -53,7 +53,7 @@ class GemBoltListener : InteractionListener {
val handler: SkillDialogueHandler =
object : SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, Item(bolt.product)) {
object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, Item(bolt.product)) {
override fun create(amount: Int, index: Int) {
player.pulseManager.run(GemBoltPulse(player, used as? Item, bolt, amount))
}
@@ -63,7 +63,6 @@ class GemBoltListener : InteractionListener {
}
}
handler.open()
PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 309, 2, 210, 10))
return@onUseWith true
}
}
@@ -1,5 +1,7 @@
package content.global.skill.fletching.items.bow;
import core.api.Container;
import core.api.ContentAPIKt;
import core.game.node.entity.player.link.diary.DiaryType;
import core.game.world.map.zone.ZoneBorders;
import core.game.node.entity.skill.SkillPulse;
@@ -46,6 +48,9 @@ public class StringPulse extends SkillPulse<Item> {
player.getDialogueInterpreter().sendDialogue("You need a fletching level of " + bow.level + " to string this bow.");
return false;
}
if (!player.getInventory().containsItem(new Item(bow.unfinished))) {
return false;
}
if (!player.getInventory().containsItem(new Item(bow.string))) {
player.getDialogueInterpreter().sendDialogue("You seem to have run out of bow strings.");
return false;
@@ -0,0 +1,34 @@
package content.global.skill.herblore
import core.api.*
import core.game.interaction.IntType
import core.game.interaction.InteractionListener
import core.game.node.entity.skill.Skills
import core.game.node.item.Item
import java.util.*
/**
* Dirty herb cleaning listener
* @author Woah
*/
class HerbCleanListener : InteractionListener {
override fun defineListeners() {
on(IntType.ITEM, "clean") { player, node ->
lock(player, 1)
if (!requireQuest(player, "Druidic Ritual", "before you can use Herblore.")) return@on true
val herb: Herbs = Herbs.forItem(node as Item) ?: return@on true
if (getDynLevel(player, Skills.HERBLORE) < herb.level) {
sendMessage(player, "You need level " + herb.level + " Herblore to clean the " + herb.product.name.replace("Clean", "Grimy") + ".")
return@on true
}
val exp = herb.experience
replaceSlot(player, node.asItem().slot, herb.product, node.asItem())
rewardXP(player, Skills.HERBLORE, exp)
playAudio(player, 5153)
sendMessage(player, "You clean the dirt from the " + herb.product.name.lowercase(Locale.getDefault()).replace("clean", "").trim { it <= ' ' } + " leaf.")
return@on true
}
}
}
@@ -1,56 +0,0 @@
package content.global.skill.herblore;
import core.api.Container;
import static core.api.ContentAPIKt.*;
import core.cache.def.impl.ItemDefinition;
import core.game.interaction.OptionHandler;
import core.game.node.Node;
import core.game.node.entity.player.Player;
import core.game.node.entity.skill.Skills;
import core.game.node.item.Item;
import core.plugin.Initializable;
import core.plugin.Plugin;
import core.tools.RandomFunction;
/**
* Represents the cleaning of a dirty herb.
* @author Vexia
* @version 1.0
*/
@Initializable
public final class HerbCleanPlugin extends OptionHandler {
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ItemDefinition.setOptionHandler("clean", this);
return this;
}
@Override
public boolean handle(Player player, Node node, String option) {
if (!player.getQuestRepository().isComplete("Druidic Ritual")) {
player.getPacketDispatch().sendMessage("You must complete the Druidic Ritual quest before you can use Herblore.");
return true;
}
final Herbs herb = Herbs.forItem((Item) node);
if (player.getSkills().getLevel(Skills.HERBLORE) < herb.getLevel()) {
player.getPacketDispatch().sendMessage("You need level " + herb.getLevel() + " Herblore to clean the " + herb.getProduct().getName().replace("Clean", "Grimy") + ".");
return true;
}
double exp = herb.getExperience();
if (removeItem(player, node.asItem(), Container.INVENTORY)){
player.getSkills().addExperience(Skills.HERBLORE, exp, true);
addItem(player, herb.getProduct().getId(), 1, Container.INVENTORY);
playAudio(player, 5153);
player.getPacketDispatch().sendMessage("You clean the dirt from the " + herb.getProduct().getName().toLowerCase().replace("clean", "").trim() + " leaf.");
}
player.lock(1);
return true;
}
@Override
public boolean isWalk() {
return false;
}
}