Fixed incorrect banker NPC look-up behavior for bank booths

Banker interactions are now properly restricted for Ultimate Ironmen
Added theme-appropriate banker NPCs to booths at Void Knights' Outpost Island
Added missing Canifis banker NPCs
Fixed incorrect handling of Arnold Lydspor banking-related logic
Added Arnold Lydspor dialogue
Consolidated banker NPC listener logic into BankerNPC class itself
Added ContentAPI call to check if a node offers an interaction option
This commit is contained in:
vddcore
2022-07-02 09:46:24 +00:00
committed by Ryan
parent fdf8e3ea1b
commit 534f568ef0
36 changed files with 374 additions and 262 deletions
+20 -4
View File
@@ -1261,7 +1261,7 @@
}, },
{ {
"npc_id": "494", "npc_id": "494",
"loc_data": "{2807,3443,0,0,6}-{2810,3443,0,0,6}-{2657,3283,0,0,3}-{2657,3286,0,0,3}-{2615,3094,0,0,3}-{2615,3092,0,0,3}-{2615,3092,0,0,3}-{2615,3094,0,0,3}-{3122,3125,0,0,6}-{3120,3125,0,0,6}-{3090,3242,0,0,4}-{3090,3245,0,0,4}-{3090,3243,0,0,4}-{2584,3422,0,0,4}-{2584,3419,0,0,4}-{3682,2981,0,0,3}-{2618,3330,0,0,0}-{2619,3330,0,0,0}-{2584,3418,0,0,4}" "loc_data": "{2807,3443,0,0,6}-{2810,3443,0,0,6}-{2657,3283,0,0,3}-{2657,3286,0,0,3}-{2615,3094,0,0,3}-{2615,3092,0,0,3}-{2615,3092,0,0,3}-{2615,3094,0,0,3}-{3122,3125,0,0,6}-{3120,3125,0,0,6}-{3090,3242,0,0,4}-{3090,3245,0,0,4}-{3090,3243,0,0,4}-{2584,3422,0,0,4}-{2584,3419,0,0,4}-{2618,3330,0,0,0}-{2619,3330,0,0,0}-{2584,3418,0,0,4}"
}, },
{ {
"npc_id": "495", "npc_id": "495",
@@ -1269,11 +1269,11 @@
}, },
{ {
"npc_id": "496", "npc_id": "496",
"loc_data": "{3267,3164,0,0,4}-{3267,3167,0,0,4}-{3267,3169,0,0,4}-{3682,2983,0,0,3}" "loc_data": "{3267,3164,0,0,4}-{3267,3167,0,0,4}-{3267,3169,0,0,4}"
}, },
{ {
"npc_id": "497", "npc_id": "497",
"loc_data": "{3267,3166,0,0,4}-{3267,3168,0,0,4}-{3682,2982,0,0,3}" "loc_data": "{3267,3166,0,0,4}-{3267,3168,0,0,4}"
}, },
{ {
"npc_id": "498", "npc_id": "498",
@@ -2481,7 +2481,7 @@
}, },
{ {
"npc_id": "1036", "npc_id": "1036",
"loc_data": "{3514,3479,1,0,0}-{3514,3481,1,0,0}-{3514,3481,0,0,3}-{3514,3479,0,0,3}" "loc_data": "{3514,3478,0,0,0}-{3514,3479,0,0,0}-{3514,3480,0,0,0}-{3514,3481,0,0,0}-{3514,3482,0,0,0}-{3514,3483,0,0,0}"
}, },
{ {
"npc_id": "1037", "npc_id": "1037",
@@ -5511,6 +5511,14 @@
"npc_id": "3196", "npc_id": "3196",
"loc_data": "{3649,3004,0,1,6}" "loc_data": "{3649,3004,0,1,6}"
}, },
{
"npc_id": "3198",
"loc_data": "{3682,2982,0,0,3}"
},
{
"npc_id": "3199",
"loc_data": "{3682,2981,0,0,3}-{3682,2983,0,0,3}"
},
{ {
"npc_id": "3200", "npc_id": "3200",
"loc_data": "{3263,3932,0,1,3}" "loc_data": "{3263,3932,0,1,3}"
@@ -7395,6 +7403,14 @@
"npc_id": "5202", "npc_id": "5202",
"loc_data": "{3621,3528,0,1,4}" "loc_data": "{3621,3528,0,1,4}"
}, },
{
"npc_id": "5258",
"loc_data": "{2666,2651,0,0,1}-{2668,2651,0,0,1}"
},
{
"npc_id": "5260",
"loc_data": "{2665,2651,0,0,1}-{2667,2651,0,0,1}"
},
{ {
"npc_id": "5291", "npc_id": "5291",
"loc_data": "{3300,2792,0,0,6}-{3282,2807,0,0,6}-{3285,2811,0,0,1}-{3283,2772,0,1,5}-{3281,2771,0,1,7}-{3283,2776,0,1,6}-{3278,2770,0,1,6}" "loc_data": "{3300,2792,0,0,6}-{3282,2807,0,0,6}-{3285,2811,0,0,1}-{3283,2772,0,1,5}-{3281,2771,0,1,7}-{3283,2776,0,1,6}-{3278,2770,0,1,6}"
@@ -48,7 +48,7 @@ public final class BankingPlugin extends OptionHandler {
/** /**
* Represents the banker npc ids. * Represents the banker npc ids.
*/ */
private static final int[] NPC_IDS = {44, 45, 166, 494, 495, 496, 497, 498, 499, 902, 1036, 1360, 1702, 2163, 2164, 2354, 2355, 2568, 2569, 2570, 2619, 3046, 3198, 3199, 3824, 4296, 5257, 5258, 5259, 5260, 5383, 5488, 5776, 5777, 5898, 5912, 5913, 6200, 6362, 6532, 6533, 6534, 6535, 6538, 7049, 7050, 7445, 7446, 7605}; private static final int[] NPC_IDS = {44, 45, 166, 494, 495, 496, 497, 498, 499, 902, 1036, 1360, 1702, 2163, 2164, 2354, 2355, 2568, 2569, 2570, 2619, 3046, 3198, 3199, 4296, 5257, 5258, 5259, 5260, 5383, 5488, 5776, 5777, 5898, 5912, 5913, 6200, 6362, 6532, 6533, 6534, 6535, 6538, 7049, 7050, 7445, 7446, 7605};
/** /**
* Represents the id to use. * Represents the id to use.
@@ -14,7 +14,7 @@ public class ShopNPC extends AbstractNPC {
/** /**
* The NPC ids of NPCs using this plugin. * The NPC ids of NPCs using this plugin.
*/ */
private static final int[] ID = { 410, 528, 529, 525, 524, 1436, 590, 591, 971, 1917, 597, 1083, 3541, 7396, 1040, 563, 5798, 582, 526, 527, 873, 532, 533, 568, 2154, 1334, 2352, 4516, 520, 521, 4716, 3922, 1254, 2086, 3824, 1866, 530, 531, 836, 516, 560, 471, 522, 523, 4651, 4652, 4653, 4654, 4655, 4656, 4650, 534, 588, 2356, 1860, 550, 575, 683, 682, 4563, 4558, 4559, 519, 559, 562, 581, 554, 601, 1301, 1039, 2353, 3166, 2161, 2162, 600, 593, 545, 585, 5268, 2305, 2307, 2304, 1783, 557, 1038, 1433, 7053, 571, 5487, 536, 4294, 4293, 584, 570, 540, 2157, 69669, 569, 572, 573, 1303, 595, 297, 704, 587, 5110, 5109, 556, 1865, 543, 2198, 580, 1862, 583, 553, 461, 4513, 3097, 903, 1435, 606, 2623, 594, 579, 2160, 6750, 6898, 6893, 589, 5485, 542, 549, 3038, 544, 1434, 209, 1980, 546, 6988, 3671, 558, 576, 5266, 586, 602, 552, 551, 541, 692, 797, 564, 2152, 1208, 2233, 3205, 70, 1598, 1596, 1597, 1599, 2259, 3162, 1167, 2620, 2151, 5486, 4250, 1079, 970, 793, 2572 }; private static final int[] ID = { 410, 528, 529, 525, 524, 1436, 590, 591, 971, 1917, 597, 1083, 3541, 7396, 1040, 563, 5798, 582, 526, 527, 873, 532, 533, 568, 2154, 1334, 2352, 4516, 520, 521, 4716, 3922, 1254, 2086, 1866, 530, 531, 836, 516, 560, 471, 522, 523, 4651, 4652, 4653, 4654, 4655, 4656, 4650, 534, 588, 2356, 1860, 550, 575, 683, 682, 4563, 4558, 4559, 519, 559, 562, 581, 554, 601, 1301, 1039, 2353, 3166, 2161, 2162, 600, 593, 545, 585, 5268, 2305, 2307, 2304, 1783, 557, 1038, 1433, 7053, 571, 5487, 536, 4294, 4293, 584, 570, 540, 2157, 69669, 569, 572, 573, 1303, 595, 297, 704, 587, 5110, 5109, 556, 1865, 543, 2198, 580, 1862, 583, 553, 461, 4513, 3097, 903, 1435, 606, 2623, 594, 579, 2160, 6750, 6898, 6893, 589, 5485, 542, 549, 3038, 544, 1434, 209, 1980, 546, 6988, 3671, 558, 576, 5266, 586, 602, 552, 551, 541, 692, 797, 564, 2152, 1208, 2233, 3205, 70, 1598, 1596, 1597, 1599, 2259, 3162, 1167, 2620, 2151, 5486, 4250, 1079, 970, 793, 2572 };
/** /**
* Constructs a new {@code ShopNPC} {@code Object}. * Constructs a new {@code ShopNPC} {@code Object}.
+19
View File
@@ -445,6 +445,25 @@ fun itemDefinition(id: Int): ItemDefinition {
return ItemDefinition.forId(id) return ItemDefinition.forId(id)
} }
/**
* Check whether a node contains an interaction option.
*
* @param node: An NPC, a scenery object or an item to inspect.
* @param option: The name of the interaction option to check for existence of.
*
* @return A Boolean value indicating the presence of the specified option in the given node.
*
* @author vddCore
*/
fun hasOption(node: Node, option: String): Boolean {
return when(node) {
is NPC -> node.definition.hasAction(option)
is Scenery -> node.definition.hasAction(option)
is Item -> node.definition.hasAction(option)
else -> throw IllegalArgumentException("Expected an NPC, Scenery or an Item, got ${node.javaClass.simpleName}.")
}
}
/** /**
* Send an object animation * Send an object animation
*/ */
@@ -9,8 +9,8 @@ import core.game.system.task.Pulse
import rs09.game.interaction.InteractionListener import rs09.game.interaction.InteractionListener
import core.game.world.map.Location import core.game.world.map.Location
import org.rs09.consts.Items import org.rs09.consts.Items
import rs09.game.node.entity.npc.other.BFOreVariant import rs09.game.node.entity.npc.BFOreVariant
import rs09.game.node.entity.npc.other.BlastFurnaceOre import rs09.game.node.entity.npc.BlastFurnaceOre
/**"Most" of the listeners for blast furnace live in this funny little file, handles /**"Most" of the listeners for blast furnace live in this funny little file, handles
* listeners for most things from interacting with the temp gauge to putting ore on the * listeners for most things from interacting with the temp gauge to putting ore on the
@@ -1,4 +1,4 @@
package rs09.game.node.entity.npc.city.alkharid package rs09.game.content.dialogue.region.alkharid
import core.game.content.dialogue.DialoguePlugin import core.game.content.dialogue.DialoguePlugin
import core.game.content.dialogue.FacialExpression import core.game.content.dialogue.FacialExpression
@@ -1,4 +1,4 @@
package rs09.game.node.entity.npc.city.alkharid package rs09.game.content.dialogue.region.alkharid
import api.* import api.*
import core.game.content.dialogue.FacialExpression import core.game.content.dialogue.FacialExpression
@@ -1,4 +1,4 @@
package rs09.game.node.entity.npc.city.alkharid package rs09.game.content.dialogue.region.alkharid
import core.game.content.dialogue.DialoguePlugin import core.game.content.dialogue.DialoguePlugin
import core.game.content.dialogue.FacialExpression import core.game.content.dialogue.FacialExpression
@@ -1,4 +1,4 @@
package rs09.game.node.entity.npc.city.alkharid package rs09.game.content.dialogue.region.alkharid
import core.game.content.dialogue.DialoguePlugin import core.game.content.dialogue.DialoguePlugin
import core.game.content.dialogue.FacialExpression import core.game.content.dialogue.FacialExpression
@@ -1,4 +1,4 @@
package rs09.game.node.entity.npc.city.alkharid package rs09.game.content.dialogue.region.alkharid
import core.game.content.dialogue.DialoguePlugin import core.game.content.dialogue.DialoguePlugin
import core.game.content.dialogue.FacialExpression import core.game.content.dialogue.FacialExpression
@@ -1,4 +1,4 @@
package rs09.game.node.entity.npc.city.alkharid package rs09.game.content.dialogue.region.alkharid
import api.addItem import api.addItem
import core.game.content.dialogue.DialoguePlugin import core.game.content.dialogue.DialoguePlugin
@@ -1,4 +1,4 @@
package rs09.game.node.entity.npc.city.alkharid package rs09.game.content.dialogue.region.alkharid
import api.addItem import api.addItem
import api.openDialogue import api.openDialogue
@@ -1,4 +1,4 @@
package rs09.game.node.entity.npc.city.alkharid package rs09.game.content.dialogue.region.alkharid
import core.game.content.dialogue.DialoguePlugin import core.game.content.dialogue.DialoguePlugin
import core.game.content.dialogue.FacialExpression import core.game.content.dialogue.FacialExpression
@@ -1,4 +1,4 @@
package rs09.game.node.entity.npc.city.alkharid package rs09.game.content.dialogue.region.alkharid
import core.game.content.dialogue.DialoguePlugin import core.game.content.dialogue.DialoguePlugin
import core.game.content.dialogue.FacialExpression import core.game.content.dialogue.FacialExpression
@@ -1,4 +1,4 @@
package rs09.game.node.entity.npc.city.alkharid package rs09.game.content.dialogue.region.alkharid
import api.animate import api.animate
import api.getDynLevel import api.getDynLevel
@@ -1,4 +1,4 @@
package rs09.game.node.entity.npc.city.alkharid package rs09.game.content.dialogue.region.alkharid
import core.game.content.dialogue.DialoguePlugin import core.game.content.dialogue.DialoguePlugin
import core.game.content.dialogue.FacialExpression import core.game.content.dialogue.FacialExpression
@@ -1,4 +1,4 @@
package rs09.game.node.entity.npc.city.alkharid package rs09.game.content.dialogue.region.alkharid
import core.game.content.dialogue.DialoguePlugin import core.game.content.dialogue.DialoguePlugin
import api.* import api.*
@@ -0,0 +1,87 @@
package rs09.game.content.dialogue.region.piscatoris
import api.addItemOrDrop
import api.sendItemDialogue
import core.game.content.dialogue.DialoguePlugin
import core.game.content.dialogue.FacialExpression
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.plugin.Initializable
import org.rs09.consts.Items
import org.rs09.consts.NPCs
import rs09.game.content.dialogue.Topic
import rs09.game.content.global.shops.Shops
import rs09.game.node.entity.npc.BankerNPC
import rs09.tools.END_DIALOGUE
import rs09.tools.START_DIALOGUE
/**
* Provides the regular dialogue for Arnold Lydspor.
* TODO: Swan Song quest will need a special case handling.
*
* @author vddCore
*/
@Initializable
class ArnoldLydsporDialogue(player: Player? = null) : DialoguePlugin(player) {
override fun open(vararg args: Any?): Boolean {
npc = args[0] as NPC
npc(FacialExpression.FRIENDLY, "Ah, you come back! What you want from Arnold, heh?")
return true
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when (stage) {
START_DIALOGUE -> showTopics(
Topic("Can you open my bank account, please?", 2),
Topic(FacialExpression.NEUTRAL, "I'd like to check my bank PIN settings.", 3),
Topic(FacialExpression.NEUTRAL, "I'd like to collect items.", 4),
Topic("Would you like to trade?", 5),
Topic(FacialExpression.FRIENDLY, "Nothing, I just came to chat.", 7)
)
2 -> BankerNPC.attemptBank(player, npc)
.also { end() }
/* TODO change when PIN management is re-worked
* TODO and the relevant ContentAPI call is created
*/
3 -> player.bankPinManager.openSettings()
.also { end() }
4 -> BankerNPC.attemptCollect(player, npc)
.also { end() }
5 -> npc(FacialExpression.FRIENDLY, "Ja, I have wide range of stock...")
.also { stage++ }
6 -> Shops.shopsByNpc[NPCs.ARNOLD_LYDSPOR_3824]?.openFor(player)
.also { end() }
7 -> npcl(FacialExpression.FRIENDLY,
"Ah, that is nice - always I like to chat, but"
+ " Herr Caranos tell me to get back to work!"
+ " Here, you been nice, so have a present."
).also { stage++ }
8 -> sendItemDialogue(player, Items.CABBAGE_1965, "Arnold gives you a cabbage.")
.also {
addItemOrDrop(player, Items.CABBAGE_1965)
stage++
}
9 -> player(FacialExpression.HALF_THINKING, "A cabbage?")
.also { stage++ }
10 -> npc("Ja, cabbage is good for you!")
.also { stage++ }
11 -> player(FacialExpression.NEUTRAL, "Um... Thanks!")
.also { stage = END_DIALOGUE }
}
return true
}
override fun newInstance(player: Player?): DialoguePlugin = ArnoldLydsporDialogue(player)
override fun getIds(): IntArray = ArnoldLydsporListener.NPC_IDS
}
@@ -0,0 +1,24 @@
package rs09.game.content.dialogue.region.piscatoris
import core.plugin.Initializable
import org.rs09.consts.NPCs
import rs09.game.interaction.InteractionListener
import rs09.game.node.entity.npc.BankerNPC
/**
* Provides banker interactions for Arnold Lydspor
*
* @author vddCore
*/
@Initializable
class ArnoldLydsporListener : InteractionListener {
companion object {
val NPC_IDS = intArrayOf(NPCs.ARNOLD_LYDSPOR_3824)
}
override fun defineListeners() {
on(NPC_IDS, NPC, "bank", handler = BankerNPC::attemptBank)
on(NPC_IDS, NPC, "collect", handler = BankerNPC::attemptCollect)
/* Talk-to handled by NPCTalkListener */
}
}
@@ -1,4 +1,4 @@
package rs09.game.node.entity.npc.city.pollnivneach package rs09.game.content.dialogue.region.pollnivneach
import core.game.content.dialogue.DialoguePlugin import core.game.content.dialogue.DialoguePlugin
import core.game.content.dialogue.FacialExpression import core.game.content.dialogue.FacialExpression
@@ -1,4 +1,4 @@
package rs09.game.node.entity.npc.city.pollnivneach package rs09.game.content.dialogue.region.pollnivneach
import core.game.content.dialogue.DialoguePlugin import core.game.content.dialogue.DialoguePlugin
import core.game.content.dialogue.FacialExpression import core.game.content.dialogue.FacialExpression
@@ -1,4 +1,4 @@
package rs09.game.node.entity.npc.city.pollnivneach package rs09.game.content.dialogue.region.pollnivneach
import core.game.content.dialogue.DialoguePlugin import core.game.content.dialogue.DialoguePlugin
import core.game.content.dialogue.FacialExpression import core.game.content.dialogue.FacialExpression
@@ -16,9 +16,8 @@ import rs09.game.content.dialogue.DialogueFile
import rs09.game.content.global.action.PickupHandler import rs09.game.content.global.action.PickupHandler
import rs09.game.content.global.shops.Shops import rs09.game.content.global.shops.Shops
import rs09.game.interaction.InteractionListener import rs09.game.interaction.InteractionListener
import rs09.game.node.entity.npc.other.MortMyreGhastNPC import rs09.game.node.entity.npc.MortMyreGhastNPC
import rs09.game.system.SystemLogger import rs09.game.system.SystemLogger
import rs09.game.system.config.ShopParser
import rs09.tools.END_DIALOGUE import rs09.tools.END_DIALOGUE
class NSListeners : InteractionListener { class NSListeners : InteractionListener {
@@ -2,20 +2,15 @@ package rs09.game.content.quest.members.naturespirit
import api.Container import api.Container
import api.* import api.*
import core.game.node.Node
import core.game.node.scenery.Scenery
import core.game.node.scenery.SceneryBuilder import core.game.node.scenery.SceneryBuilder
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.game.system.task.Pulse import core.game.system.task.Pulse
import core.game.world.map.Location
import core.game.world.map.RegionManager import core.game.world.map.RegionManager
import core.game.world.map.RegionManager.forId import core.game.world.map.RegionManager.forId
import core.game.world.map.RegionManager.lock
import core.game.world.update.flag.context.Graphics import core.game.world.update.flag.context.Graphics
import core.tools.RandomFunction import core.tools.RandomFunction
import org.rs09.consts.Items import org.rs09.consts.Items
import rs09.game.node.entity.npc.other.MortMyreGhastNPC import rs09.game.node.entity.npc.MortMyreGhastNPC
object NSUtils { object NSUtils {
fun flagFungusPlaced(player: Player) { fun flagFungusPlaced(player: Player) {
@@ -1,109 +0,0 @@
package rs09.game.interaction.npc
import api.getScenery
import api.location
import api.openDialogue
import core.game.node.Node
import core.game.node.entity.Entity
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.world.map.Direction
import core.game.world.map.Location
import core.game.world.map.path.Pathfinder
import org.rs09.consts.NPCs
import rs09.game.content.dialogue.region.lunarisle.SirsalBankerDialogue
import rs09.game.ge.GrandExchangeRecords
import rs09.game.interaction.InteractionListener
import rs09.game.interaction.`object`.BankBoothHandler
import rs09.game.node.entity.npc.other.BankerNPC
import rs09.game.system.SystemLogger
/**
* Allows the user to interact with banker NPC options.
*
* @author vddCore
*/
class BankerNPCListener : InteractionListener {
companion object {
val BANKER_NPCS = intArrayOf(
NPCs.BANKER_44, NPCs.BANKER_45, NPCs.BANKER_494, NPCs.BANKER_495, NPCs.BANKER_496, NPCs.BANKER_497,
NPCs.BANKER_498, NPCs.BANKER_499, NPCs.BANKER_1036, NPCs.BANKER_1360, NPCs.BANKER_2163, NPCs.BANKER_2164,
NPCs.BANKER_2354, NPCs.BANKER_2355, NPCs.BANKER_2568, NPCs.BANKER_2569, NPCs.BANKER_2570, NPCs.BANKER_3198,
NPCs.BANKER_3199, NPCs.BANKER_5258, NPCs.BANKER_5259, NPCs.BANKER_5260, NPCs.BANKER_5261, NPCs.BANKER_5776,
NPCs.BANKER_5777, NPCs.BANKER_5912, NPCs.BANKER_5913, NPCs.BANKER_6200, NPCs.BANKER_6532, NPCs.BANKER_6533,
NPCs.BANKER_6534, NPCs.BANKER_6535, NPCs.BANKER_6538, NPCs.BANKER_7445, NPCs.BANKER_7446, NPCs.BANKER_7605,
NPCs.BANK_TUTOR_4907,
NPCs.GHOST_BANKER_1702, NPCs.GNOME_BANKER_166, NPCs.NARDAH_BANKER_3046,
NPCs.OGRESS_BANKER_7049, NPCs.OGRESS_BANKER_7050, NPCs.SIRSAL_BANKER_4519,
NPCs.FADLI_958, NPCs.ARNOLD_LYDSPOR_3824, NPCs.MAGNUS_GRAM_5488
)
fun provideDestinationOverride(entity: Entity, node: Node): Location {
val npc = node as NPC
return when(npc.id) {
/* Ogress bankers are 2x2 with their spawn being offset to south-western tile. */
NPCs.OGRESS_BANKER_7049,
NPCs.OGRESS_BANKER_7050 -> npc.location.transform(3, 1, 0)
/* Magnus has no bank booth nearby so we need to handle that edge case here. */
NPCs.MAGNUS_GRAM_5488 -> npc.location.transform(Direction.NORTH, 2)
else -> {
if (npc is BankerNPC) {
npc.findAdjacentBankBoothLocation()?.let {
return it.second
}
}
val path = Pathfinder.find(entity, node)
if (path.isSuccessful) {
val pt = path.points.last
return Location(pt.x, pt.y)
}
return npc.location
}
}
}
}
override fun defineListeners() {
on(BANKER_NPCS, NPC, "bank") { player, node ->
val npc = node as NPC
if (BankerNPC.checkLunarIsleRestriction(player, node)) {
openDialogue(player, npc.id, npc)
return@on true
}
npc.faceLocation(null)
player.bank.open(); true
}
on(BANKER_NPCS, NPC, "collect") { player, node ->
val npc = node as NPC
if (BankerNPC.checkLunarIsleRestriction(player, node)) {
openDialogue(player, npc.id, npc)
return@on true
}
npc.faceLocation(null)
GrandExchangeRecords.getInstance(player).openCollectionBox(); true
}
on(BANKER_NPCS, NPC, "talk-to") { player, node ->
val npc = node as NPC
openDialogue(player, npc.id, npc); true
}
}
override fun defineDestinationOverrides() {
setDest(NPC, BANKER_NPCS, "bank", "collect", "talk-to", handler = ::provideDestinationOverride)
}
}
@@ -17,7 +17,6 @@ class NPCTalkListener : InteractionListener {
val barCrawlNPCs = intArrayOf(733,848,735,739,737,738,731,568,3217,736,734) val barCrawlNPCs = intArrayOf(733,848,735,739,737,738,731,568,3217,736,734)
override fun defineListeners() { override fun defineListeners() {
on(barCrawlNPCs, NPC, "talk-to", "talk"){player, node -> on(barCrawlNPCs, NPC, "talk-to", "talk"){player, node ->
val type = BarcrawlType.forId(node.id) val type = BarcrawlType.forId(node.id)
val instance = BarcrawlManager.getInstance(player) val instance = BarcrawlManager.getInstance(player)
@@ -52,20 +51,5 @@ class NPCTalkListener : InteractionListener {
} }
return@on player.dialogueInterpreter.open(npc.id, npc) return@on player.dialogueInterpreter.open(npc.id, npc)
} }
}
override fun defineDestinationOverrides() {
setDest(NPC,"talk","talk-to"){_,node ->
val npc = node as NPC
if (npc.getAttribute("facing_booth", false)) {
val offsetX = npc.direction.stepX shl 1
val offsetY = npc.direction.stepY shl 1
return@setDest npc.location.transform(offsetX, offsetY, 0)
}
return@setDest node.location
}
setDest(NPC, BankerNPCListener.BANKER_NPCS, "talk-to", handler = BankerNPCListener::provideDestinationOverride)
} }
} }
@@ -14,7 +14,7 @@ import org.rs09.consts.Scenery
import rs09.ServerConstants import rs09.ServerConstants
import rs09.game.ge.GrandExchangeRecords import rs09.game.ge.GrandExchangeRecords
import rs09.game.interaction.InteractionListener import rs09.game.interaction.InteractionListener
import rs09.game.node.entity.npc.other.BankerNPC import rs09.game.node.entity.npc.BankerNPC
import rs09.game.world.repository.Repository import rs09.game.world.repository.Repository
/** /**
@@ -25,16 +25,19 @@ import rs09.game.world.repository.Repository
class BankBoothHandler : InteractionListener { class BankBoothHandler : InteractionListener {
companion object { companion object {
val INOPERABLE_BANK_BOOTHS = intArrayOf(
Scenery.BANK_BOOTH_12800, Scenery.BANK_BOOTH_12801, Scenery.BANK_BOOTH_36262, Scenery.BANK_BOOTH_35648
)
val BANK_BOOTHS = intArrayOf( val BANK_BOOTHS = intArrayOf(
Scenery.BANK_BOOTH_2213, Scenery.BANK_BOOTH_2214, Scenery.BANK_BOOTH_3045, Scenery.BANK_BOOTH_5276, Scenery.BANK_BOOTH_2213, Scenery.BANK_BOOTH_2214, Scenery.BANK_BOOTH_3045, Scenery.BANK_BOOTH_5276,
Scenery.BANK_BOOTH_6084, Scenery.BANK_BOOTH_10517, Scenery.BANK_BOOTH_11338, Scenery.BANK_BOOTH_11402, Scenery.BANK_BOOTH_6084, Scenery.BANK_BOOTH_10517, Scenery.BANK_BOOTH_11338, Scenery.BANK_BOOTH_11402,
Scenery.BANK_BOOTH_11758, Scenery.BANK_BOOTH_12798, Scenery.BANK_BOOTH_12799, Scenery.BANK_BOOTH_12800, Scenery.BANK_BOOTH_11758, Scenery.BANK_BOOTH_12798, Scenery.BANK_BOOTH_12799, Scenery.BANK_BOOTH_14367,
Scenery.BANK_BOOTH_12801, Scenery.BANK_BOOTH_14367, Scenery.BANK_BOOTH_14368, Scenery.BANK_BOOTH_16700, Scenery.BANK_BOOTH_14368, Scenery.BANK_BOOTH_16700, Scenery.BANK_BOOTH_18491, Scenery.BANK_BOOTH_19230,
Scenery.BANK_BOOTH_18491, Scenery.BANK_BOOTH_19230, Scenery.BANK_BOOTH_20325, Scenery.BANK_BOOTH_20326, Scenery.BANK_BOOTH_20325, Scenery.BANK_BOOTH_20326, Scenery.BANK_BOOTH_20327, Scenery.BANK_BOOTH_20328,
Scenery.BANK_BOOTH_20327, Scenery.BANK_BOOTH_20328, Scenery.BANK_BOOTH_22819, Scenery.BANK_BOOTH_24914, Scenery.BANK_BOOTH_22819, Scenery.BANK_BOOTH_24914, Scenery.BANK_BOOTH_25808, Scenery.BANK_BOOTH_26972,
Scenery.BANK_BOOTH_25808, Scenery.BANK_BOOTH_26972, Scenery.BANK_BOOTH_29085, Scenery.BANK_BOOTH_30015, Scenery.BANK_BOOTH_29085, Scenery.BANK_BOOTH_30015, Scenery.BANK_BOOTH_30016, Scenery.BANK_BOOTH_34205,
Scenery.BANK_BOOTH_30016, Scenery.BANK_BOOTH_34205, Scenery.BANK_BOOTH_34752, Scenery.BANK_BOOTH_35647, Scenery.BANK_BOOTH_34752, Scenery.BANK_BOOTH_35647, Scenery.BANK_BOOTH_36786, Scenery.BANK_BOOTH_37474
Scenery.BANK_BOOTH_35648, Scenery.BANK_BOOTH_36262, Scenery.BANK_BOOTH_36786, Scenery.BANK_BOOTH_37474
) )
} }
@@ -49,7 +52,7 @@ class BankBoothHandler : InteractionListener {
*/ */
private fun locateAdjacentBankerLinear(node: Node): NPC? { private fun locateAdjacentBankerLinear(node: Node): NPC? {
for (dir in arrayOf(Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST)) { for (dir in arrayOf(Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST)) {
Repository.findNPC(node.location.transform(dir))?.let { return it } Repository.findNPC(node.location.transform(dir))?.let { return it as? BankerNPC }
} }
return null return null
@@ -69,7 +72,7 @@ class BankBoothHandler : InteractionListener {
private fun locateAdjacentBankerSquare(node: Node, size: Int = 1): NPC? { private fun locateAdjacentBankerSquare(node: Node, size: Int = 1): NPC? {
for (y in (node.location.y - size)..(node.location.y + size)) { for (y in (node.location.y - size)..(node.location.y + size)) {
for (x in (node.location.x - size)..(node.location.x + size)) { for (x in (node.location.x - size)..(node.location.x + size)) {
Repository.findNPC(Location(x, y))?.let { return it } Repository.findNPC(Location(x, y))?.let { return it as? BankerNPC }
} }
} }
@@ -129,6 +132,13 @@ class BankBoothHandler : InteractionListener {
} }
private fun attemptToConvertItems(player: Player, used: Node, with: Node): Boolean { private fun attemptToConvertItems(player: Player, used: Node, with: Node): Boolean {
if (!hasOption(with, "use")) {
sendMessage(player, "You shouldn't be able to do that with object ${with.id}.")
sendMessage(player, "Please screenshot this and report to the developers.")
return true
}
if (!ServerConstants.BANK_BOOTH_NOTE_UIM && player.ironmanManager.checkRestriction(IronmanMode.ULTIMATE)) { if (!ServerConstants.BANK_BOOTH_NOTE_UIM && player.ironmanManager.checkRestriction(IronmanMode.ULTIMATE)) {
return true return true
} }
@@ -1,4 +1,4 @@
package rs09.game.node.entity.npc.other package rs09.game.node.entity.npc
import core.cache.def.impl.NPCDefinition import core.cache.def.impl.NPCDefinition
import core.game.interaction.OptionHandler import core.game.interaction.OptionHandler
@@ -0,0 +1,167 @@
package rs09.game.node.entity.npc
import api.getScenery
import api.hasSealOfPassage
import api.openDialogue
import core.game.node.Node
import core.game.node.entity.Entity
import core.game.node.entity.npc.AbstractNPC
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.world.map.Direction
import core.game.world.map.Location
import core.plugin.Initializable
import org.rs09.consts.NPCs
import rs09.game.ge.GrandExchangeRecords
import rs09.game.interaction.InteractionListener
import rs09.game.interaction.`object`.BankBoothHandler
@Initializable
class BankerNPC : AbstractNPC, InteractionListener {
companion object {
private const val LUNAR_ISLE_BANK_REGION = 8253
val NPC_IDS = intArrayOf(
NPCs.BANKER_44, NPCs.BANKER_45, NPCs.BANKER_494, NPCs.BANKER_495, NPCs.BANKER_496, NPCs.BANKER_497,
NPCs.BANKER_498, NPCs.BANKER_499, NPCs.BANKER_1036, NPCs.BANKER_1360, NPCs.BANKER_2163, NPCs.BANKER_2164,
NPCs.BANKER_2354, NPCs.BANKER_2355, NPCs.BANKER_2568, NPCs.BANKER_2569, NPCs.BANKER_2570, NPCs.BANKER_3198,
NPCs.BANKER_3199, NPCs.BANKER_5258, NPCs.BANKER_5259, NPCs.BANKER_5260, NPCs.BANKER_5261, NPCs.BANKER_5776,
NPCs.BANKER_5777, NPCs.BANKER_5912, NPCs.BANKER_5913, NPCs.BANKER_6200, NPCs.BANKER_6532, NPCs.BANKER_6533,
NPCs.BANKER_6534, NPCs.BANKER_6535, NPCs.BANKER_6538, NPCs.BANKER_7445, NPCs.BANKER_7446, NPCs.BANKER_7605,
NPCs.BANK_TUTOR_4907, NPCs.JADE_4296,
NPCs.GHOST_BANKER_1702, NPCs.GNOME_BANKER_166, NPCs.NARDAH_BANKER_3046,
NPCs.OGRESS_BANKER_7049, NPCs.OGRESS_BANKER_7050, NPCs.SIRSAL_BANKER_4519,
NPCs.FADLI_958, NPCs.MAGNUS_GRAM_5488
)
/**
* This is poorly named, but performs a few checks to see if the player
* is trying to access the bank on the Lunar Isle and returns a boolean
* controlling whether or not to pass the quick bank or collection use.
*
* TODO
* The location of this method is shit too. Find a better place for it?
*/
fun checkLunarIsleRestriction(player: Player, node: Node): Boolean {
if (node.location.regionId != LUNAR_ISLE_BANK_REGION)
return false
if (!hasSealOfPassage(player)) {
return true
}
return false
}
fun attemptBank(player: Player, node: Node): Boolean {
val npc = node as NPC
if (player.ironmanManager.checkRestriction(IronmanMode.ULTIMATE)) {
return true
}
if (checkLunarIsleRestriction(player, node)) {
openDialogue(player, npc.id, npc)
return true
}
npc.faceLocation(null)
player.bank.open()
return true
}
fun attemptCollect(player: Player, node: Node): Boolean {
val npc = node as NPC
if (player.ironmanManager.checkRestriction(IronmanMode.ULTIMATE)) {
return true
}
if (checkLunarIsleRestriction(player, node)) {
openDialogue(player, npc.id, npc)
return true
}
npc.faceLocation(null)
GrandExchangeRecords.getInstance(player).openCollectionBox()
return true
}
}
//Constructor spaghetti because Arios I guess
constructor() : super(0, null)
private constructor(id: Int, location: Location) : super(id, location)
override fun construct(id: Int, location: Location, vararg objects: Any?): AbstractNPC {
return BankerNPC(id, location)
}
private fun findAdjacentBankBoothLocation(): Pair<Direction, Location>? {
for (side in arrayOf(Direction.SOUTH, Direction.WEST, Direction.NORTH, Direction.EAST)) {
val boothLocation = location.transform(side)
val sceneryObject = getScenery(boothLocation)
if (sceneryObject != null && sceneryObject.id in BankBoothHandler.BANK_BOOTHS) {
return Pair(side, boothLocation.transform(side, 1))
}
}
return null
}
private fun provideDestinationOverride(entity: Entity, node: Node): Location {
val npc = node as NPC
return when(npc.id) {
/* Ogress bankers are 2x2 with their spawn being offset to south-western tile. */
NPCs.OGRESS_BANKER_7049,
NPCs.OGRESS_BANKER_7050 -> npc.location.transform(3, 1, 0)
NPCs.BANKER_6532, NPCs.BANKER_6533,
NPCs.BANKER_6534, NPCs.BANKER_6535 -> npc.location.transform(npc.direction, 1)
/* Magnus has no bank booth nearby so we need to handle that edge case here. */
NPCs.MAGNUS_GRAM_5488 -> npc.location.transform(Direction.NORTH, 2)
else -> {
if (npc is BankerNPC) {
npc.findAdjacentBankBoothLocation()?.let {
return it.second
}
}
return npc.location
}
}
}
override fun defineListeners() {
on(NPC_IDS, NPC, "bank", handler = Companion::attemptBank)
on(NPC_IDS, NPC, "collect", handler = Companion::attemptCollect)
}
override fun defineDestinationOverrides() {
setDest(NPC, NPC_IDS, "bank", "collect", "talk-to", handler = ::provideDestinationOverride)
}
override fun init() {
super.init()
findAdjacentBankBoothLocation()?.let {
val (boothDirection, _) = it
direction = boothDirection
isWalks = false
setAttribute("facing_booth", true)
}
}
override fun getIds(): IntArray = NPC_IDS
}
@@ -1,4 +1,4 @@
package rs09.game.node.entity.npc.other package rs09.game.node.entity.npc
import api.* import api.*
import core.game.node.entity.npc.AbstractNPC import core.game.node.entity.npc.AbstractNPC
@@ -21,15 +21,15 @@ class BlastFurnaceOre : AbstractNPC {
constructor(owner: Player, variant: BFOreVariant, amount: Int) : super( constructor(owner: Player, variant: BFOreVariant, amount: Int) : super(
when(variant){ when(variant){
BFOreVariant.IRON -> NPCs.IRON_ORE_2556 BFOreVariant.IRON -> NPCs.IRON_ORE_2556
BFOreVariant.COPPER -> NPCs.COPPER_ORE_2555 BFOreVariant.COPPER -> NPCs.COPPER_ORE_2555
BFOreVariant.TIN -> NPCs.TIN_ORE_2554 BFOreVariant.TIN -> NPCs.TIN_ORE_2554
BFOreVariant.COAL -> NPCs.COAL_2562 BFOreVariant.COAL -> NPCs.COAL_2562
BFOreVariant.MITHRIL -> NPCs.MITHRIL_ORE_2557 BFOreVariant.MITHRIL -> NPCs.MITHRIL_ORE_2557
BFOreVariant.ADAMANT -> NPCs.ADAMANTITE_ORE_2558 BFOreVariant.ADAMANT -> NPCs.ADAMANTITE_ORE_2558
BFOreVariant.SILVER -> NPCs.SILVER_ORE_2560 BFOreVariant.SILVER -> NPCs.SILVER_ORE_2560
BFOreVariant.GOLD -> NPCs.GOLD_ORE_2561 BFOreVariant.GOLD -> NPCs.GOLD_ORE_2561
BFOreVariant.RUNITE -> NPCs.RUNITE_ORE_2559 BFOreVariant.RUNITE -> NPCs.RUNITE_ORE_2559
}, Location.create(1942, 4966, 0)) {this.owner = owner; isRespawn = false; } }, Location.create(1942, 4966, 0)) {this.owner = owner; isRespawn = false; }
var owner: Player? = null var owner: Player? = null
@@ -1,4 +1,4 @@
package rs09.game.node.entity.npc.other package rs09.game.node.entity.npc
import api.* import api.*
import core.game.node.entity.npc.AbstractNPC import core.game.node.entity.npc.AbstractNPC
@@ -1,4 +1,4 @@
package rs09.game.node.entity.npc.other package rs09.game.node.entity.npc
import api.* import api.*
import core.game.node.entity.npc.AbstractNPC import core.game.node.entity.npc.AbstractNPC
@@ -1,12 +1,10 @@
package rs09.game.node.entity.npc.other package rs09.game.node.entity.npc
import api.* import api.*
import core.game.node.entity.npc.AbstractNPC import core.game.node.entity.npc.AbstractNPC
import core.game.world.map.Location import core.game.world.map.Location
import core.plugin.Initializable import core.plugin.Initializable
import core.tools.RandomFunction
import org.rs09.consts.NPCs import org.rs09.consts.NPCs
import rs09.game.system.SystemLogger
@Initializable @Initializable
class IceTrollJatizsoCaves : AbstractNPC { class IceTrollJatizsoCaves : AbstractNPC {
@@ -1,4 +1,4 @@
package rs09.game.node.entity.npc.other package rs09.game.node.entity.npc
import api.Container import api.Container
import api.* import api.*
@@ -8,7 +8,6 @@ import core.game.interaction.MovementPulse
import core.game.node.entity.Entity import core.game.node.entity.Entity
import core.game.node.entity.combat.ImpactHandler import core.game.node.entity.combat.ImpactHandler
import core.game.node.entity.npc.AbstractNPC import core.game.node.entity.npc.AbstractNPC
import core.game.node.entity.npc.NPC
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.world.map.Location import core.game.world.map.Location
@@ -1,4 +1,4 @@
package rs09.game.node.entity.npc.other package rs09.game.node.entity.npc
import core.game.node.entity.npc.AbstractNPC import core.game.node.entity.npc.AbstractNPC
import core.game.world.map.Location import core.game.world.map.Location
@@ -1,77 +0,0 @@
package rs09.game.node.entity.npc.other
import api.getScenery
import api.hasSealOfPassage
import core.game.content.dialogue.DialogueInterpreter
import core.game.node.Node
import core.game.node.entity.npc.AbstractNPC
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.world.map.Direction
import core.game.world.map.Location
import core.plugin.Initializable
import rs09.game.interaction.npc.BankerNPCListener
import rs09.game.interaction.`object`.BankBoothHandler
private const val LUNAR_ISLE_BANK_REGION = 8253
@Initializable
class BankerNPC : AbstractNPC {
companion object {
/**
* This is poorly named, but performs a few checks to see if the player
* is trying to access the bank on the Lunar Isle and returns a boolean
* controlling whether or not to pass the quick bank or collection use.
*
* TODO
* The location of this method is shit too. Find a better place for it?
*/
fun checkLunarIsleRestriction(player: Player, node: Node): Boolean {
if (node.location.regionId != LUNAR_ISLE_BANK_REGION)
return false
if (!hasSealOfPassage(player)) {
return true
}
return false
}
}
//Constructor spaghetti because Arios I guess
constructor() : super(0, null)
private constructor(id: Int, location: Location) : super(id, location)
override fun construct(id: Int, location: Location, vararg objects: Any?): AbstractNPC {
return BankerNPC(id, location)
}
fun findAdjacentBankBoothLocation(): Pair<Direction, Location>? {
for (side in arrayOf(Direction.SOUTH, Direction.WEST, Direction.NORTH, Direction.EAST)) {
val boothLocation = location.transform(side)
val sceneryObject = getScenery(boothLocation)
if (sceneryObject != null && sceneryObject.id in BankBoothHandler.BANK_BOOTHS) {
return Pair(side, boothLocation.transform(side, 1))
}
}
return null
}
override fun init() {
super.init()
findAdjacentBankBoothLocation()?.let {
val (boothDirection, _) = it
direction = boothDirection
isWalks = false
setAttribute("facing_booth", true)
}
}
override fun getIds(): IntArray = BankerNPCListener.BANKER_NPCS
}