mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2026-08-19 17:35:10 -06:00
Merge branch 'imp' into 'master'
Fixed Imp in a Box (hunter item) Closes #709 See merge request 2009scape/2009scape!2479
This commit is contained in:
commit
87fb2cd74b
2 changed files with 218 additions and 174 deletions
218
Server/src/main/content/global/skill/hunter/ImpBoxListener.kt
Normal file
218
Server/src/main/content/global/skill/hunter/ImpBoxListener.kt
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
package content.global.skill.hunter
|
||||
|
||||
import core.api.*
|
||||
import core.game.dialogue.DialogueLabeller
|
||||
import core.game.dialogue.DialogueOption
|
||||
import core.game.dialogue.FacialExpression
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.interaction.InterfaceListener
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.player.link.IronmanMode
|
||||
import core.game.node.item.Item
|
||||
import core.game.system.config.ItemConfigParser
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
/**
|
||||
* The Imp-in-a-box that can bank items.
|
||||
*/
|
||||
|
||||
class ImpBoxListener : InteractionListener, InterfaceListener {
|
||||
|
||||
// Great source: https://www.youtube.com/watch?v=k0LhRhcQ0g8
|
||||
// wiki: https://runescape.wiki/w/Imp-in-a-box, https://runescape.wiki/w/Magic_box?oldid=1743149
|
||||
// uses 701.cs2
|
||||
|
||||
companion object {
|
||||
val RELEASE_IFACE = 478
|
||||
private val BOXES = intArrayOf(Items.IMP_IN_A_BOX2_10027, Items.IMP_IN_A_BOX1_10028)
|
||||
}
|
||||
|
||||
override fun defineListeners() {
|
||||
|
||||
// use an item with the imp box
|
||||
onUseAnyWith(IntType.ITEM,*BOXES) { player, used, _ ->
|
||||
bankItem(player, used.asItem())
|
||||
return@onUseAnyWith true
|
||||
}
|
||||
|
||||
// open the banking interface
|
||||
on(BOXES, IntType.ITEM, "bank") {player, _ ->
|
||||
openInterface(player, RELEASE_IFACE)
|
||||
return@on true
|
||||
}
|
||||
|
||||
// talk to the imp
|
||||
on(BOXES, IntType.ITEM, "talk-to") {player, node ->
|
||||
openDialogue(player, ImpBoxDialogueFile(node.id), NPC(NPCs.IMP_1531))
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
|
||||
override fun defineInterfaceListeners() {
|
||||
|
||||
// send the interface settings that display the deposit and examine options that get set by the cs2 file
|
||||
onOpen(RELEASE_IFACE) { player, _ ->
|
||||
val settings = IfaceSettingsBuilder()
|
||||
.enableOptions(0, 1) // option 0 = "Deposit" (CS2 slot 1), option 1 = "Examine" (CS2 slot 2)
|
||||
.build()
|
||||
player.packetDispatch.sendIfaceSettings(settings, 14, RELEASE_IFACE, 0, 28)
|
||||
return@onOpen true
|
||||
}
|
||||
|
||||
on(RELEASE_IFACE) { player, _, opcode, buttonID, slot, _ ->
|
||||
val clickItemButton = 14
|
||||
val depositOpcode = 155
|
||||
val examineOpcode = 196
|
||||
val item = player.inventory[slot]
|
||||
|
||||
when(buttonID) {
|
||||
clickItemButton -> {
|
||||
when(opcode) {
|
||||
depositOpcode -> bankItem(player, item)
|
||||
examineOpcode -> sendMessage(player, "${item.definition.examine}")
|
||||
}
|
||||
}
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
|
||||
// banks the item
|
||||
private fun bankItem(player: Player, item: Item) {
|
||||
|
||||
if (item != null) {
|
||||
// check for non-bankable conditions (non-bankable items, banking the imp, ult. ironman, or in wildy)
|
||||
if (!item.definition.getConfiguration(ItemConfigParser.BANKABLE, true)
|
||||
|| item.id in BOXES
|
||||
|| player.ironmanManager.mode == IronmanMode.ULTIMATE
|
||||
|| player.skullManager.level > 20
|
||||
) {
|
||||
sendMessage(player, "A magical force prevents you from banking this item.")
|
||||
return
|
||||
}
|
||||
|
||||
// can't do in combat
|
||||
if (player.inCombat()) {
|
||||
sendMessage(player, "You can't use this while in combat.")
|
||||
return
|
||||
}
|
||||
|
||||
// attempt to add to bank
|
||||
if (addItem(player, item.id, item.amount, Container.BANK)
|
||||
&& removeItem(player, item)
|
||||
&& decrementBox(player)
|
||||
) {
|
||||
closeInterface(player)
|
||||
sendMessage(player, "The imp teleports away, taking the item to your bank account.")
|
||||
} else {
|
||||
sendMessage(player, "You cannot add this item to your bank.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// decrements the box
|
||||
private fun decrementBox(player: Player) : Boolean {
|
||||
if (amountInInventory(player, Items.IMP_IN_A_BOX1_10028) > 0) {
|
||||
// replace a 1-charge box with a 0-charge
|
||||
if (removeItem(player, Items.IMP_IN_A_BOX1_10028)) {
|
||||
addItem(player, Items.MAGIC_BOX_10025)
|
||||
return true
|
||||
}
|
||||
} else if (amountInInventory(player, Items.IMP_IN_A_BOX2_10027) > 0) {
|
||||
// replace a 2-charge box with a 1-charge
|
||||
if (removeItem(player, Items.IMP_IN_A_BOX2_10027)) {
|
||||
addItem(player, Items.IMP_IN_A_BOX1_10028)
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
sendMessage(player, "ERROR: No valid imp boxes found. Please report this.")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// dialogue for the imp in a box
|
||||
class ImpBoxDialogueFile(val box: Int) : DialogueLabeller() {
|
||||
override fun addConversation() {
|
||||
exec { player, _ ->
|
||||
if (box == Items.IMP_IN_A_BOX2_10027) {
|
||||
loadLabel(player, "two start")
|
||||
} else {
|
||||
loadLabel(player, "one start")
|
||||
}
|
||||
}
|
||||
|
||||
label("one start")
|
||||
player("Hey imp, are you still there?")
|
||||
npc(FacialExpression.OLD_DEFAULT, "An who's fault is that, eh? EH? I got betta fings to do dan sit ere waitin' for ya. 'Ave ya made up ya mind what else I'm luggin about?")
|
||||
options(
|
||||
DialogueOption("ok", "Yes I have."),
|
||||
DialogueOption("no escape", "No, I'm afraid you're going to have to wait a bit longer.")
|
||||
)
|
||||
|
||||
label("no escape")
|
||||
npc(FacialExpression.OLD_DEFAULT, "Dat's alright guv'nor. I'll get back to me luvverly dream about beads. Big shiny beads. Love it!")
|
||||
goto("end")
|
||||
|
||||
label("two start")
|
||||
player("Hey imp, can you hear me?")
|
||||
npc(FacialExpression.OLD_DEFAULT, "Of course I can hear ya, ya great big ape. You know,", "'veres not even enuf space to swing Bob about in 'ere.", "How about a breather? You know, stretch me pins for a", "bit?")
|
||||
options(
|
||||
DialogueOption("no", "No, I'm going to keep you in there.", "No, I'm going to keep you in there. I might keep you as a pet."),
|
||||
DialogueOption("not bad", "It's not that bad.", "It's not that bad. You've got four big windows, charming company...er..."),
|
||||
DialogueOption("wish", "Don't I get three wishes?")
|
||||
)
|
||||
|
||||
label("no")
|
||||
npc(FacialExpression.OLD_DEFAULT, "Pet!! Nah mate. I fink you'd find dat you'd be my pet!! We is not makin good pets.")
|
||||
player("Really? Why not?")
|
||||
npc(FacialExpression.OLD_DEFAULT, "Coz...errr...")
|
||||
npc(FacialExpression.OLD_DEFAULT, "We bite! Yeah we is biting and...and...er...")
|
||||
npc(FacialExpression.OLD_DEFAULT, "We is fire risk! Yeah dat's it! We be burning down your housey and stealin' all ya shiny gems. Oh, and da beads!! Mmmm, beads.")
|
||||
player("Fire risk? How does that work?")
|
||||
npc(FacialExpression.OLD_DEFAULT, "Is those wizzies. Dey don't like de imps so dey make us go BOOOM!!")
|
||||
goto("end")
|
||||
|
||||
label("not bad")
|
||||
npc(FacialExpression.OLD_DEFAULT, "Yeah, we's love tiny, crampt space. It be magical. But I is a busy imp, innit? Dragons needin' ticklin', shiny relics needin' stealin', you know how it goes.")
|
||||
npc(FacialExpression.OLD_DEFAULT, "So, if you's know whas good for ya, you'd be lettin' me go, right?")
|
||||
options(
|
||||
DialogueOption("no", "No, I'm going to keep you in there.", "No, I'm going to keep you in there. I might keep you as a pet."),
|
||||
DialogueOption("wish", "Don't I get three wishes?")
|
||||
)
|
||||
|
||||
label("wish")
|
||||
npc(FacialExpression.OLD_DEFAULT, "Nah, mate. Dunno what you're chirpin' about.")
|
||||
player("Well, you're a magical creature aren't you? Surely I", "get some wishes for capturing you, or releasing you, or", "something?")
|
||||
npc(FacialExpression.OLD_DEFAULT, "I'm finking dat you be a bit confoosed. I is an imp, not", "some namby-pamby genie or some kinda fairy. Ye can", "tell by the horns.")
|
||||
npc(FacialExpression.OLD_DEFAULT, "Sayin' dat, I don't fancy being cooped up like one of", "my uncle's pigeons. Tell you what, is there anything", "you need deliverin' to the bank? I may not be no", "cunjerer or sommink like dat, but I can get about nice")
|
||||
npc(FacialExpression.OLD_DEFAULT, "an quick like. If you let me scarper, I'll take a couple of", "fings to the bank for ya. You game?")
|
||||
options(
|
||||
DialogueOption("ok", "Okay, that sounds fair."),
|
||||
DialogueOption("three", "Surely it should be three items?", "Surely it should be three items? Then it's one item per wish."),
|
||||
DialogueOption("nothing", "I've got nothing I need banking right now.")
|
||||
)
|
||||
|
||||
label("ok")
|
||||
exec { player, _ ->
|
||||
openInterface(player, ImpBoxListener.RELEASE_IFACE)
|
||||
end()
|
||||
}
|
||||
|
||||
label("three")
|
||||
npc(FacialExpression.OLD_DEFAULT, "I've already told ya, I ain't no bloomin' fairy. Besides, you know wot dey say, three's a crowd innit? I don't fink I can hop about carryin' more dan 2 fings.")
|
||||
options(
|
||||
DialogueOption("ok", "Okay, that sounds fair."),
|
||||
DialogueOption("nothing", "I've got nothing I need banking right now.")
|
||||
)
|
||||
|
||||
label("nothing")
|
||||
npc(FacialExpression.OLD_DEFAULT, "Great, just blinkin great, dat is. I'll just sit about", "countin' zombie sheep then. One...two...two and a", "bit...three and a bit more... I don't fink sheep 'ave dat", "many legs...")
|
||||
goto("end")
|
||||
}
|
||||
}
|
||||
|
|
@ -1,174 +0,0 @@
|
|||
package content.global.skill.hunter;
|
||||
|
||||
import core.cache.def.impl.ItemDefinition;
|
||||
import core.game.component.Component;
|
||||
import core.game.component.ComponentDefinition;
|
||||
import core.game.component.ComponentPlugin;
|
||||
import core.plugin.Initializable;
|
||||
import core.game.dialogue.DialogueInterpreter;
|
||||
import core.game.dialogue.DialoguePlugin;
|
||||
import core.game.dialogue.FacialExpression;
|
||||
import core.game.interaction.OptionHandler;
|
||||
import core.game.node.Node;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.item.Item;
|
||||
import core.net.packet.PacketRepository;
|
||||
import core.net.packet.context.ContainerContext;
|
||||
import core.net.packet.out.ContainerPacket;
|
||||
import core.plugin.Plugin;
|
||||
import core.plugin.ClassScanner;
|
||||
import core.tools.RandomFunction;
|
||||
|
||||
/**
|
||||
* Handles the imp box.
|
||||
* @author Taylor
|
||||
*/
|
||||
@Initializable
|
||||
public class ImpBoxPlugin extends OptionHandler {
|
||||
|
||||
/**
|
||||
* The item ids.
|
||||
*/
|
||||
private static final int[] IDS = new int[] { 10028, 10027 };
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
ClassScanner.definePlugin(new ImpInterfaceHandler(null));
|
||||
for (int id : IDS) {
|
||||
ItemDefinition.forId(id).getHandlers().put("option:bank", this);
|
||||
ItemDefinition.forId(id).getHandlers().put("option:talk-to", this);
|
||||
}
|
||||
ClassScanner.definePlugin(new ImpBoxDialogue());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(Player player, Node node, String option) {
|
||||
switch (option) {
|
||||
case "bank":
|
||||
Component component = new Component(478);
|
||||
component.setPlugin(new ImpInterfaceHandler((Item) node));
|
||||
player.getInterfaceManager().open(component);
|
||||
PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 478, 61, 91, player.getInventory(), true));
|
||||
break;
|
||||
case "talk-to":
|
||||
player.getDialogueInterpreter().open("imp-box");
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWalk() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles talk-to dialogue on the imp box.
|
||||
* @author Taylor
|
||||
*/
|
||||
public static class ImpBoxDialogue extends DialoguePlugin {
|
||||
|
||||
/**
|
||||
* The messages to send.
|
||||
*/
|
||||
private static final String[] MESSAGES = { "Let me outa here!", "Errgghh..", "Well look who it is.", "What are you looking at?" };
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ImpBoxDialogue} {@code Object}.
|
||||
*/
|
||||
public ImpBoxDialogue() {
|
||||
/**
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ImpBoxDialogue} {@code Object}.
|
||||
* @param player The player.
|
||||
*/
|
||||
public ImpBoxDialogue(Player player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DialoguePlugin newInstance(Player player) {
|
||||
return new ImpBoxDialogue(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean open(Object... args) {
|
||||
interpreter.sendDialogues(708, FacialExpression.FURIOUS, MESSAGES[RandomFunction.getRandom(MESSAGES.length - 1)]);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(int interfaceId, int buttonId) {
|
||||
end();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getIds() {
|
||||
return new int[] { DialogueInterpreter.getDialogueKey("imp-box") };
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the imp interface.
|
||||
* @author Taylor
|
||||
*/
|
||||
public class ImpInterfaceHandler extends ComponentPlugin {
|
||||
|
||||
/**
|
||||
* The message to show when the imp is gone.
|
||||
*/
|
||||
private static final String FINISHING_MESSAGE = "The imp teleports away, taking the item to your bank account.";
|
||||
|
||||
/**
|
||||
* The box the player is using.
|
||||
*/
|
||||
private Item box;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ImpInterfaceHandler} {@code Object}.
|
||||
* @param box The box the player is using.
|
||||
*/
|
||||
public ImpInterfaceHandler(Item box) {
|
||||
this.box = box;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
ComponentDefinition.forId(478).setPlugin(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) {
|
||||
Item item = player.getInventory().get(slot);
|
||||
if (item != null) {
|
||||
if (player.getBank().canAdd(item) && item.getId() != box.getId()) {
|
||||
player.getDialogueInterpreter().close();
|
||||
player.getInventory().remove(item);
|
||||
player.getBank().add(item);
|
||||
PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 478, 61, 91, player.getInventory(), true));
|
||||
if (box.getId() == IDS[1]) {
|
||||
int boxSlot = player.getInventory().getSlot(box);
|
||||
player.getInventory().replace((box = new Item(IDS[0])), boxSlot);
|
||||
} else if (box.getId() == IDS[0]) {
|
||||
int boxSlot = player.getInventory().getSlot(box);
|
||||
player.getInventory().replace(new Item(10025), boxSlot);
|
||||
player.getInterfaceManager().close(component);
|
||||
player.sendMessage(FINISHING_MESSAGE);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
player.sendMessage("You cannot add this item to your bank.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue