mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2026-08-23 03:15:10 -06:00
Merge branch 2009scape:master into master
This commit is contained in:
commit
32e08837dc
23 changed files with 258 additions and 780 deletions
|
|
@ -477,7 +477,7 @@
|
|||
},
|
||||
{
|
||||
"item_id": "1939",
|
||||
"loc_data": "{1,3193,3181,0,150}-{1,3194,3168,0,150}-{1,3191,3162,0,150}-{1,3189,3163,0,150}-{1,3185,3161,0,150}-{1,3182,3165,0,150}-{1,3172,3166,0,150}-{1,3170,3167,0,150}-{1,3164,3169,0,150}-{1,3171,3177,0,150}-{1,3173,3178,0,150}-{1,3164,3180,0,150}-{1,3165,3187,0,150}-{1,3171,3191,0,150}-{1,3178,3190,0,150}-{1,3181,3193,0,150}-{1,3182,3181,0,150}-{1,3493,3408,0,30}-{1,3494,3402,0,30}-{1,3494,3396,0,30}-{1,3499,3401,0,30}-"
|
||||
"loc_data": "{1,3193,3181,0,150}-{1,3194,3168,0,150}-{1,3191,3162,0,150}-{1,3189,3163,0,150}-{1,3185,3161,0,150}-{1,3182,3165,0,150}-{1,3172,3166,0,150}-{1,3170,3167,0,150}-{1,3164,3169,0,150}-{1,3171,3177,0,150}-{1,3173,3178,0,150}-{1,3164,3180,0,150}-{1,3165,3187,0,150}-{1,3171,3191,0,150}-{1,3178,3190,0,150}-{1,3181,3193,0,150}-{1,3182,3181,0,150}-{1,3428,3322,0,45}-{1,3436,3311,0,45}-{1,3437,3298,0,45}-{1,3428,3293,0,45}-{1,3422,3286,0,45}-{1,3451,3320,0,45}-{1,3434,3277,0,45}-{1,3446,3281,0,45}-{1,3447,3269,0,45}-{1,3450,3359,0,45}-{1,3451,3359,0,45}-{1,3452,3379,0,45}-{1,3452,3380,0,45}-{1,3438,3379,0,45}-{1,3440,3377,0,45}-{1,3414,3367,0,45}-{1,3409,3363,0,45}-{1,3452,3390,0,45}-{1,3452,3391,0,45}-{1,3466,3377,0,45}-{1,3460,3374,0,45}-{1,3459,3370,0,45}-{1,3469,3363,0,45}-{1,3476,3365,0,45}-{1,3460,3353,0,45}-{1,3462,3349,0,45}-{1,3472,3344,0,45}-{1,3493,3408,0,30}-{1,3494,3402,0,30}-{1,3494,3396,0,30}-{1,3499,3401,0,30}-{1,3464,3432,0,45}-{1,3469,3434,0,45}-{1,3473,3435,0,45}-{1,3471,3430,0,45}-{1,3478,3440,0,45}-{1,3477,3444,0,45}-{1,3472,3447,0,45}-{1,3458,3418,0,45}-{1,3460,3414,0,45}-{1,3467,3417,0,45}-{1,3472,3419,0,45}-{1,3474,3415,0,45}-{1,3480,3419,0,45}-{1,3481,3427,0,45}-{1,3460,3406,0,45}-{1,3471,3403,0,45}-{1,3428,3437,0,45}-{1,3434,3433,0,45}-{1,3435,3425,0,45}-{1,3441,3438,0,45}-{1,3445,3435,0,45}-{1,3449,3434,0,45}-{1,3448,3430,0,45}-{1,3454,3441,0,45}-{1,3441,3415,0,45}-{1,3442,3414,0,45}-{1,3436,3403,0,45}-{1,3432,3402,0,45}-{1,3450,3416,0,45}-{1,3445,3405,0,45}-{1,3453,3402,0,45}-"
|
||||
},
|
||||
{
|
||||
"item_id": "1944",
|
||||
|
|
|
|||
|
|
@ -3389,7 +3389,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "1227",
|
||||
"loc_data": "{3424,3318,0,1,0}-{3423,3312,0,1,4}-{3494,3388,0,1,0}-{3507,3435,0,1,4}-{3511,3455,0,1,0}-{3508,3420,0,1,3}-{3508,3420,0,1,4}-{3506,3402,0,1,7}-{3502,3392,0,1,3}-{3484,3456,0,1,0}-{3486,3458,0,1,4}-"
|
||||
"loc_data": "{3424,3318,0,1,0}-{3423,3312,0,1,4}-{3426,3381,0,1,0}-{3418,3375,0,1,0}-{3414,3363,0,1,0}-{3411,3358,0,1,0}-{3441,3356,0,1,0}-{3424,3426,0,1,0}-{3414,3413,0,1,0}-{3421,3408,0,1,0}-{3422,3408,0,1,0}-{3440,3406,0,1,0}-{3412,3392,0,1,0}-{3494,3388,0,1,0}-{3467,3346,0,1,0}-{3465,3347,0,1,0}-{3507,3435,0,1,4}-{3511,3455,0,1,0}-{3508,3420,0,1,3}-{3508,3420,0,1,4}-{3506,3402,0,1,7}-{3502,3392,0,1,3}-{3481,3446,0,1,0}-{3480,3445,0,1,0}-{3479,3443,0,1,0}-{3471,3433,0,1,0}-{3459,3432,0,1,0}-{3459,3426,0,1,0}-{3459,3418,0,1,0}-{3456,3415,0,1,0}-{3484,3456,0,1,0}-{3486,3458,0,1,4}-{3563,3441,0,1,0}-{3544,3430,0,1,0}-{3540,3413,0,1,0}-{3529,3441,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "1228",
|
||||
|
|
@ -3397,11 +3397,11 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "1229",
|
||||
"loc_data": "{3421,3302,0,1,4}-{3417,3291,0,1,4}-{3423,3288,0,1,4}-{3418,3284,0,1,6}-{3427,3298,0,1,3}-{3431,3303,0,1,1}-{3432,3311,0,1,1}-{3502,3455,0,1,2}-{3516,3415,0,1,4}-{3511,3401,0,1,1}-{3492,3457,0,1,1}-"
|
||||
"loc_data": "{3421,3302,0,1,4}-{3417,3291,0,1,4}-{3423,3288,0,1,4}-{3418,3284,0,1,6}-{3427,3298,0,1,3}-{3431,3303,0,1,1}-{3432,3311,0,1,1}-{3427,3376,0,1,0}-{3420,3407,0,1,0}-{3425,3403,0,1,0}-{3438,3399,0,1,0}-{3446,3406,0,1,0}-{3420,3426,0,1,0}-{3477,3368,0,1,0}-{3479,3367,0,1,0}-{3502,3455,0,1,2}-{3516,3415,0,1,4}-{3511,3401,0,1,1}-{3484,3443,0,1,0}-{3483,3442,0,1,0}-{3457,3416,0,1,0}-{3469,3402,0,1,0}-{3471,3401,0,1,0}-{3492,3457,0,1,1}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "1230",
|
||||
"loc_data": "{3419,3280,0,1,4}-{3421,3277,0,1,4}-{3431,3275,0,1,3}-{3428,3314,0,1,1}-{3436,3318,0,1,5}-{3434,3322,0,1,6}-{3496,3447,0,1,7}-{3520,3437,0,1,4}-"
|
||||
"loc_data": "{3419,3280,0,1,4}-{3421,3277,0,1,4}-{3431,3275,0,1,3}-{3428,3314,0,1,1}-{3436,3318,0,1,5}-{3434,3322,0,1,6}-{3476,3350,0,1,0}-{3496,3447,0,1,7}-{3481,3442,0,1,0}-{3520,3437,0,1,4}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "1231",
|
||||
|
|
@ -3409,7 +3409,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "1232",
|
||||
"loc_data": "{3441,3265,0,1,5}-{3438,3277,0,1,7}-{3438,3283,0,1,4}-{3439,3315,0,1,3}-{3439,3310,0,1,1}-{3435,3302,0,1,3}-{3508,3420,0,1,1}-{3514,3415,0,1,7}-{3525,3417,0,1,3}-"
|
||||
"loc_data": "{3441,3265,0,1,5}-{3438,3277,0,1,7}-{3438,3283,0,1,4}-{3439,3315,0,1,3}-{3439,3310,0,1,1}-{3435,3302,0,1,3}-{3411,3362,0,1,0}-{3415,3365,0,1,0}-{3415,3371,0,1,0}-{3413,3373,0,1,0}-{3431,3383,0,1,0}-{3508,3420,0,1,1}-{3514,3415,0,1,7}-{3470,3400,0,1,0}-{3464,3405,0,1,0}-{3474,3417,0,1,0}-{3474,3419,0,1,0}-{3477,3419,0,1,0}-{3480,3441,0,1,0}-{3525,3417,0,1,3}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "1233",
|
||||
|
|
@ -3417,7 +3417,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "1234",
|
||||
"loc_data": "{3446,3282,0,1,1}-{3446,3298,0,1,3}-{3449,3304,0,1,1}-{3513,3383,0,1,0}-{3491,3388,0,1,3}-{3493,3454,0,1,2}-{3493,3454,0,1,0}-{3518,3454,0,1,2}-{3519,3441,0,1,7}-{3506,3417,0,1,5}-{3519,3401,0,1,2}-{3499,3420,0,1,3}-{3516,3410,0,1,7}-{3520,3412,0,1,0}-"
|
||||
"loc_data": "{3446,3282,0,1,1}-{3446,3298,0,1,3}-{3449,3304,0,1,1}-{3409,3387,0,1,0}-{3424,3377,0,1,0}-{3438,3351,0,1,0}-{3513,3383,0,1,0}-{3491,3388,0,1,3}-{3461,3355,0,1,0}-{3473,3348,0,1,0}-{3477,3367,0,1,0}-{3493,3454,0,1,2}-{3493,3454,0,1,0}-{3518,3454,0,1,2}-{3519,3441,0,1,7}-{3506,3417,0,1,5}-{3519,3401,0,1,2}-{3499,3420,0,1,3}-{3516,3410,0,1,7}-{3483,3444,0,1,0}-{3479,3423,0,1,0}-{3466,3408,0,1,0}-{3466,3407,0,1,0}-{3520,3412,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "1235",
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import core.game.world.update.flag.context.Graphics
|
|||
import org.rs09.consts.Sounds
|
||||
|
||||
fun kidnapPlayer(npc: NPC, player: Player, dest: Location, playerLine: String? = null, callback: (player: Player, npc: NPC) -> Unit) {
|
||||
clearScripts(player)
|
||||
val lockDuration = if (playerLine != null) 4 else 6
|
||||
lock(player, lockDuration)
|
||||
queueScript(player, 1, QueueStrength.SOFT) { stage: Int ->
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class CiderOnForesterDialogue : DialogueFile() {
|
|||
end()
|
||||
}
|
||||
else if(player!!.getAttribute("seersCiderPub",-1) !in 0..3 && !player!!.achievementDiaryManager.hasCompletedTask(DiaryType.SEERS_VILLAGE,0,6)){
|
||||
player!!.setAttribute("seersCiderPub",0)
|
||||
player!!.setAttribute("seersCiderPub", 1)
|
||||
end()
|
||||
}else if(player!!.getAttribute("seersCiderPub",-1) in 0..3){
|
||||
player!!.incrementAttribute("seersCiderPub",1)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ public class SnelmCraftPlugin extends UseWithHandler {
|
|||
* The snelm data.
|
||||
*/
|
||||
private static final int[][] DATA = new int[][] { { 3345, 3327 }, { 3355, 3337 },// blamish
|
||||
{ 3349, 3341 }, { 3341, 3359 },// ochre
|
||||
{ 3349, 3331 }, { 3359, 3341 },// ochre
|
||||
{ 3347, 3329 }, { 3357, 3339 },// blood
|
||||
{ 3351, 3333 }, { 3361, 3343 },// blue
|
||||
{ 3353, 3335 },// bark
|
||||
|
|
|
|||
|
|
@ -12,26 +12,29 @@ class LeprechaunNoter : InteractionListener {
|
|||
val LEPRECHAUNS = intArrayOf(NPCs.TOOL_LEPRECHAUN_3021,NPCs.GOTH_LEPRECHAUN_8000,NPCs.TOOL_LEPRECHAUN_4965,NPCs.TECLYN_2861)
|
||||
|
||||
override fun defineListeners() {
|
||||
onUseWith(IntType.NPC,CROPS,*LEPRECHAUNS){ player, used, with ->
|
||||
onUseAnyWith(IntType.NPC,*LEPRECHAUNS) { player, used, with ->
|
||||
val usedItem = used.asItem()
|
||||
val npc = with.asNpc()
|
||||
val expr = when(npc.id){
|
||||
3021 -> core.game.dialogue.FacialExpression.OLD_NORMAL
|
||||
NPCs.TOOL_LEPRECHAUN_3021 -> core.game.dialogue.FacialExpression.OLD_NORMAL
|
||||
else -> core.game.dialogue.FacialExpression.FRIENDLY
|
||||
}
|
||||
|
||||
if(usedItem.noteChange != usedItem.id){
|
||||
val amt = player.inventory.getAmount(usedItem.id)
|
||||
if(player.inventory.remove(Item(usedItem.id,amt))){
|
||||
player.inventory.add(Item(usedItem.noteChange,amt))
|
||||
when {
|
||||
(!usedItem.definition.isUnnoted) -> { // If the item is a banknote
|
||||
player.dialogueInterpreter.sendDialogues(npc.id,expr,"That IS a banknote!")
|
||||
}
|
||||
(usedItem.id !in CROPS || usedItem.definition.noteId < 0) -> { // If the item is not a crop or cannot be noted
|
||||
player.dialogueInterpreter.sendDialogues(npc.id,expr,"Nay, I can't turn that into a banknote.")
|
||||
}
|
||||
else -> { // Note the item
|
||||
val amt = amountInInventory(player, usedItem.id)
|
||||
if (removeItem(player, Item(usedItem.id, amt))) {
|
||||
addItem(player, usedItem.noteChange, amt)
|
||||
}
|
||||
sendItemDialogue(player, usedItem.id, "The leprechaun exchanges your items for banknotes.")
|
||||
}
|
||||
sendItemDialogue(player,usedItem.id,"The leprechaun exchanges your items for banknotes.")
|
||||
} else {
|
||||
// Unsure why the line below no longer functions, despite only changing the line above to be more correct. Using your note(NOT CROP) on the leprechaun no longer functions because of this. - Crash
|
||||
player.dialogueInterpreter.sendDialogues(npc.id,expr,"That IS a banknote!")
|
||||
}
|
||||
|
||||
return@onUseWith true
|
||||
return@onUseAnyWith true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -209,7 +209,15 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl
|
|||
PatchType.HERB_PATCH -> {
|
||||
if(isDead) setVisualState(getHerbDeathValue())
|
||||
else if(isDiseased && !isDead) setVisualState(getHerbDiseaseValue())
|
||||
else setVisualState((plantable?.value ?: 0) + currentGrowthStage)
|
||||
else {
|
||||
var state = (plantable?.value ?: 0) + currentGrowthStage
|
||||
// Spirit Weed contains states with bits 0x40 and 0x80 set, which the disease-free patch scenery interprets as watered/dead
|
||||
// Visually transmogrifies Spirit Weed (204-208) into Guam (4-8) while it's planted in the disease-free patch
|
||||
if (patch == FarmingPatch.TROLL_STRONGHOLD_HERB && plantable == Plantable.SPIRIT_WEED_SEED) {
|
||||
state = 4 + currentGrowthStage
|
||||
}
|
||||
setVisualState(state)
|
||||
}
|
||||
}
|
||||
PatchType.MUSHROOM_PATCH -> {
|
||||
if(isDead) setVisualState(getMushroomDeathValue())
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ class WoodcuttingListener : InteractionListener {
|
|||
defineInteraction(
|
||||
IntType.SCENERY,
|
||||
ids = WoodcuttingNode.values().map { it.id }.toIntArray(),
|
||||
"chop-down", "chop", "chop down", "cut down",
|
||||
"chop-down", "chop", "chop down", "cut down", "cut-branch",
|
||||
persistent = true,
|
||||
allowedDistance = 1,
|
||||
handler = ::handleWoodcutting
|
||||
|
|
@ -74,10 +74,10 @@ class WoodcuttingListener : InteractionListener {
|
|||
if (clockReady(player, Clocks.SKILLING)) {
|
||||
animateWoodcutting(player)
|
||||
|
||||
if (resource == WoodcuttingNode.DRAMEN_TREE) {
|
||||
if (resource in arrayOf(WoodcuttingNode.DRAMEN_TREE, WoodcuttingNode.SWAYING_TREE)) {
|
||||
// Reward after one chop and then abort chopping (this is authentic)
|
||||
queueScript(player, 1, QueueStrength.STRONG) {
|
||||
sendMessage(player, "You cut a branch from the Dramen tree.")
|
||||
sendMessage(player, "You cut a branch from the ${if (resource == WoodcuttingNode.DRAMEN_TREE) "Dramen" else "strangely musical"} tree.")
|
||||
addItem(player, resource.getReward())
|
||||
return@queueScript clearScripts(player)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,81 +0,0 @@
|
|||
package content.global.skill.summoning.familiar;
|
||||
|
||||
import core.game.dialogue.DialoguePlugin;
|
||||
import core.game.node.entity.npc.NPC;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.entity.player.link.TeleportManager.TeleportType;
|
||||
import core.game.world.map.Location;
|
||||
import core.plugin.Initializable;
|
||||
import core.game.world.map.zone.impl.WildernessZone;
|
||||
|
||||
/**
|
||||
* Represents the spirit graahk's dialogue
|
||||
* @author Splinter
|
||||
* @version 1.0
|
||||
*/
|
||||
@Initializable
|
||||
public final class SpiritGraahkDialogue extends DialoguePlugin {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code GertrudesCatDialogue} {@code Object}.
|
||||
*/
|
||||
public SpiritGraahkDialogue() {
|
||||
/**
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code GertrudesCatDialogue} {@code Object}.
|
||||
* @param player the player.
|
||||
*/
|
||||
public SpiritGraahkDialogue(Player player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DialoguePlugin newInstance(Player player) {
|
||||
return new SpiritGraahkDialogue(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean open(Object... args) {
|
||||
npc = (NPC) args[0];
|
||||
if (!(npc instanceof Familiar)) {
|
||||
return false;
|
||||
}
|
||||
final Familiar fam = (Familiar) npc;
|
||||
if (fam.getOwner() != player) {
|
||||
player.getPacketDispatch().sendMessage("This is not your familiar.");
|
||||
return true;
|
||||
} else {
|
||||
interpreter.sendOptions("Select an Option", "Chat", "Teleport");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(int interfaceId, int buttonId) {
|
||||
switch (buttonId) {
|
||||
case 1:
|
||||
player.sendMessage("The Graahk does not feel like talking now.");
|
||||
end();
|
||||
break;
|
||||
case 2:
|
||||
if (!WildernessZone.checkTeleport(player, 20)) {
|
||||
player.sendMessage("You cannot teleport with the Graahk above level 20 wilderness.");
|
||||
end();
|
||||
} else {
|
||||
player.getTeleporter().send(new Location(2786, 3002), TeleportType.NORMAL);
|
||||
end();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getIds() {
|
||||
return new int[] { 7353, 7364 };
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
package content.global.skill.summoning.familiar
|
||||
|
||||
import core.api.openDialogue
|
||||
import core.game.dialogue.ChatAnim
|
||||
import core.game.dialogue.DialogueLabeller
|
||||
import core.game.dialogue.DialoguePlugin
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.player.link.TeleportManager.TeleportType
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.zone.impl.WildernessZone
|
||||
import core.plugin.Initializable
|
||||
import core.tools.RandomFunction
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
/**
|
||||
* Represents the spirit graahk's dialogue
|
||||
* @author Splinter & Bishop
|
||||
* @version 2.0
|
||||
*/
|
||||
@Initializable
|
||||
class SpiritGraahkDialogue : DialoguePlugin {
|
||||
constructor()
|
||||
constructor(player: Player?) : super(player)
|
||||
|
||||
override fun newInstance(player: Player?): DialoguePlugin {
|
||||
return SpiritGraahkDialogue(player)
|
||||
}
|
||||
|
||||
override fun open(vararg args: Any?): Boolean {
|
||||
npc = args[0] as NPC?
|
||||
if (npc !is Familiar) {
|
||||
return false
|
||||
}
|
||||
val fam = npc as Familiar
|
||||
if (fam.getOwner() !== player) {
|
||||
player.packetDispatch.sendMessage("This is not your familiar.")
|
||||
return true
|
||||
} else {
|
||||
interpreter.sendOptions("Select an Option", "Chat", "Teleport")
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
|
||||
when (buttonId) {
|
||||
1 -> if (player.skills.getStaticLevel(Skills.SUMMONING) >= 67) {
|
||||
openDialogue(player, SpiritGraahkDialogueFile(), npc)
|
||||
} else {
|
||||
player.sendMessage("The Graahk does not feel like talking now.") //This message is likely inauthentic, but I cannot source the correct one so I'm keeping the default here -Bishop
|
||||
end()
|
||||
}
|
||||
|
||||
2 -> if (!WildernessZone.checkTeleport(player, 20)) {
|
||||
player.sendMessage("You cannot teleport with the Graahk above level 20 wilderness.")
|
||||
end()
|
||||
} else {
|
||||
player.teleporter.send(Location(2786, 3002), TeleportType.NORMAL)
|
||||
end()
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun getIds(): IntArray {
|
||||
return intArrayOf(NPCs.SPIRIT_GRAAHK_7363, NPCs.SPIRIT_GRAAHK_7364)
|
||||
}
|
||||
}
|
||||
|
||||
class SpiritGraahkDialogueFile : DialogueLabeller() {
|
||||
override fun addConversation() {
|
||||
exec { player, npc ->
|
||||
val spiritGraahkRandomConversation = RandomFunction.random(4)
|
||||
when (spiritGraahkRandomConversation) {
|
||||
0 -> loadLabel(player, "spiky spikes")
|
||||
1 -> loadLabel(player, "pet the spikes")
|
||||
2 -> loadLabel(player, "therapeutic spikes")
|
||||
3 -> loadLabel(player, "inspect the spikes")
|
||||
}
|
||||
}
|
||||
|
||||
label("spiky spikes")
|
||||
player(ChatAnim.NEUTRAL, "Your spikes are looking particularly spiky today.")
|
||||
npc(ChatAnim.GHRAAK_SHAKE_VIGOROUS, "Graaaaahk raaaawr?", "(Really, you think so?)")
|
||||
player(ChatAnim.HAPPY, "Yes. Most pointy, indeed.")
|
||||
npc(ChatAnim.GHRAAK_SHAKE_VIGOROUS, "Raaaawr...", "(That's really kind of you to say. I was going to spike", "you but I won't now...)")
|
||||
player(ChatAnim.HAPPY, "Thanks?")
|
||||
npc(ChatAnim.GHRAAK_SHAKE_VIGOROUS, "...Grrrrr ark.", "(...I'll do it later instead.)")
|
||||
player(ChatAnim.HAPPY, "*Sigh!*")
|
||||
|
||||
label("pet the spikes")
|
||||
npc(ChatAnim.GHRAAK_SHAKE_MILD, "Graahk grrrrowl?", "(My spikes hurt, could you pet them for me?)")
|
||||
player(ChatAnim.HAPPY, "Aww, of course I can I'll just... Oww! I think you drew", "blood that time.")
|
||||
|
||||
label("therapeutic spikes")
|
||||
npc(ChatAnim.GHRAAK_SHAKE_MILD, "Graahk!", "(Hi!)") //?
|
||||
player(ChatAnim.SUSPICIOUS, "Hello. Are you going to spike me again?")
|
||||
npc(ChatAnim.GHRAAK_SHAKE_VIGOROUS, "Grar rawr howl!", "(No, I got a present to apologise for last time.)")
|
||||
player(ChatAnim.HAPPY, "That's really sweet, thank you.")
|
||||
npc(ChatAnim.GRAAHK_NOD, "Howl graaahk rawr.", "(Here you go, it's a special cushion to make you", "comfortable.)")
|
||||
player(ChatAnim.ANGRY, "It's made of spikes!")
|
||||
npc(ChatAnim.GHRAAK_SHAKE_VIGOROUS, "Howl graaahk rawr.", "(Yes, but they're therapeutic spikes.)")
|
||||
player(ChatAnim.ANGRY, "...")
|
||||
|
||||
label("inspect the spikes")
|
||||
player(ChatAnim.HAPPY, "How's your day going?")
|
||||
npc(ChatAnim.GHRAAK_SHAKE_VIGOROUS, "Graaahk. Grak grak!", "(It's great! Actually I've got something to show you!)")
|
||||
player(ChatAnim.HALF_ASKING, "Oh? What's that?")
|
||||
npc(ChatAnim.GRAAHK_NOD, "Grrrrrk hiss graaaaa!", "(You'll need to get closer!)")
|
||||
player(ChatAnim.HALF_ASKING, "I can't see anything...")
|
||||
npc(ChatAnim.GHRAAK_SHAKE_VIGOROUS, "Grah grr aaaaahk grahk.", "(It's really small - even closer.)")
|
||||
player(ChatAnim.ANGRY, "Oww! I'm going to have your spikes trimmed!")
|
||||
}
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
package content.global.skill.summoning.familiar;
|
||||
|
||||
import core.game.node.entity.skill.SkillBonus;
|
||||
import core.game.node.entity.skill.Skills;
|
||||
import core.game.node.entity.combat.equipment.WeaponInterface;
|
||||
import core.plugin.Initializable;
|
||||
import core.game.node.entity.player.Player;
|
||||
|
||||
/**
|
||||
* Represents the Spirit Graahk familiar.
|
||||
* @author Aero
|
||||
*/
|
||||
@Initializable
|
||||
public class SpiritGraahkNPC extends Familiar {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code SpiritGraahkNPC} {@code Object}.
|
||||
*/
|
||||
public SpiritGraahkNPC() {
|
||||
this(null, 7363);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code SpiritGraahkNPC} {@code Object}.
|
||||
* @param owner The owner.
|
||||
* @param id The id.
|
||||
*/
|
||||
public SpiritGraahkNPC(Player owner, int id) {
|
||||
super(owner, id, 4900, 12810, 3, WeaponInterface.STYLE_AGGRESSIVE);
|
||||
boosts.add(new SkillBonus(Skills.HUNTER, 5));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Familiar construct(Player owner, int id) {
|
||||
return new SpiritGraahkNPC(owner, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean specialMove(FamiliarSpecial special) {
|
||||
if (!super.isOwnerAttackable()) {
|
||||
return false;
|
||||
}
|
||||
call();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getIds() {
|
||||
return new int[] { 7363, 7364 };
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package content.global.skill.summoning.familiar
|
||||
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.combat.equipment.WeaponInterface
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.skill.SkillBonus
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
import core.plugin.Initializable
|
||||
import core.tools.RandomFunction
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
/**
|
||||
* Represents the Spirit Graahk familiar.
|
||||
* @author Aero & Bishop
|
||||
*/
|
||||
@Initializable
|
||||
class SpiritGraahkNPC @JvmOverloads constructor(owner: Player? = null, id: Int = NPCs.SPIRIT_GRAAHK_7363) :
|
||||
Familiar(owner, id, 4900, Items.SPIRIT_GRAAHK_POUCH_12810, 3, WeaponInterface.STYLE_AGGRESSIVE) {
|
||||
|
||||
init {
|
||||
boosts.add(SkillBonus(Skills.HUNTER, 5.0))
|
||||
}
|
||||
|
||||
override fun construct(owner: Player?, id: Int): Familiar {
|
||||
return SpiritGraahkNPC(owner, id)
|
||||
}
|
||||
|
||||
override fun specialMove(special: FamiliarSpecial): Boolean {
|
||||
val target: Entity = special.target ?: return false
|
||||
if (!canCombatSpecial(target)) {
|
||||
return false
|
||||
}
|
||||
properties.combatPulse.attack(target)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun visualizeSpecialMove() {
|
||||
owner.visualize(Animation.create(7660), Graphics.create(1316))
|
||||
}
|
||||
|
||||
override fun getIds(): IntArray {
|
||||
return intArrayOf(NPCs.SPIRIT_GRAAHK_7363, NPCs.SPIRIT_GRAAHK_7364)
|
||||
}
|
||||
|
||||
override fun getText(): String {
|
||||
return if (RandomFunction.random(2) == 0) "Howl!" else "Rowr!"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
package content.global.skill.summoning.familiar;
|
||||
|
||||
import core.cache.def.impl.NPCDefinition;
|
||||
import core.game.interaction.OptionHandler;
|
||||
import core.game.node.Node;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* Represents the plugin used to handle the spirit graahk familiar
|
||||
* @author Splinter
|
||||
*/
|
||||
@Initializable
|
||||
public final class SpiritGraahkOptionPlugin extends OptionHandler {
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
NPCDefinition.forId(7363).getHandlers().put("option:interact", this);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(final Player player, Node node, String option) {
|
||||
player.getDialogueInterpreter().open(7353, node.asNpc());
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package content.global.skill.summoning.familiar
|
||||
|
||||
import core.cache.def.impl.NPCDefinition
|
||||
import core.game.interaction.OptionHandler
|
||||
import core.game.node.Node
|
||||
import core.game.node.entity.player.Player
|
||||
import core.plugin.Initializable
|
||||
import core.plugin.Plugin
|
||||
import org.rs09.consts.NPCs;
|
||||
|
||||
/**
|
||||
* Represents the plugin used to handle the spirit graahk familiar
|
||||
* @author Splinter
|
||||
*/
|
||||
@Initializable
|
||||
class SpiritGraahkOptionPlugin : OptionHandler() {
|
||||
@Throws(Throwable::class)
|
||||
override fun newInstance(arg: Any?): Plugin<Any?> {
|
||||
NPCDefinition.forId(NPCs.SPIRIT_GRAAHK_7363).getHandlers()["option:interact"] = this
|
||||
return this
|
||||
}
|
||||
|
||||
override fun handle(player: Player, node: Node, option: String?): Boolean {
|
||||
player.dialogueInterpreter.open(NPCs.SPIRIT_GRAAHK_7364, node.asNpc())
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
@ -84,7 +84,7 @@ class DiamondOfIceListeners : InteractionListener {
|
|||
on(Scenery.ICE_LEDGE_6455, SCENERY, "use") { player, node ->
|
||||
|
||||
if ((getQuestStage(player, DesertTreasure.questName) == 9 &&
|
||||
DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) >= 3) ||
|
||||
DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) >= 3) ||
|
||||
getQuestStage(player, DesertTreasure.questName) >= 10) {
|
||||
if (inEquipment(player, Items.SPIKED_BOOTS_3107)) {
|
||||
teleport(player, Location(2838, 3803, 1))
|
||||
|
|
|
|||
|
|
@ -67,8 +67,8 @@ class KamilCombatHandler: MultiSwingHandler(
|
|||
// I can't be bothered to fix fucking frozen. The player can hit through frozen. What the fuck is frozen for then, to glue his fucking legs???
|
||||
if (RandomFunction.roll(3) && !hasTimerActive(victim, "frozen") && !hasTimerActive(victim, "frozen:immunity")) {
|
||||
sendChat(entity as NPC, "Sallamakar Ro!") // Salad maker roll.
|
||||
impact(victim, 5)
|
||||
impact(victim, 5)
|
||||
impact(victim, if (victim.hasProtectionPrayer(CombatStyle.MAGIC)) 0 else 5)
|
||||
impact(victim, if (victim.hasProtectionPrayer(CombatStyle.RANGE)) 0 else 5)
|
||||
registerTimer(victim, spawnTimer("frozen", 7, true))
|
||||
sendMessage(victim, "You've been frozen!")
|
||||
// FIXME: before the below vfx hits, there should be another one that looks kinda like a wind wave exploding at the player's feet. Hope somebody finds the id.
|
||||
|
|
|
|||
|
|
@ -260,11 +260,6 @@ class TFTInteractionListeners : InteractionListener {
|
|||
return@on true
|
||||
}
|
||||
|
||||
on(SWAYING_TREE, IntType.SCENERY, "cut-branch"){ player, node ->
|
||||
player.pulseManager.run(WoodcuttingSkillPulse(player, node as Scenery))
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(SHOPNPCS, IntType.NPC, "Trade") { player, npc ->
|
||||
if(isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)){
|
||||
npc.asNpc().openShop(player)
|
||||
|
|
|
|||
|
|
@ -1,575 +0,0 @@
|
|||
package content.region.wilderness.handlers;
|
||||
|
||||
import core.game.dialogue.DialogueAction;
|
||||
import core.game.dialogue.DialoguePlugin;
|
||||
import core.game.dialogue.FacialExpression;
|
||||
import core.game.global.action.DoorActionHandler;
|
||||
import core.game.node.entity.skill.SkillPulse;
|
||||
import core.game.node.entity.skill.Skills;
|
||||
import content.global.skill.gather.SkillingResource;
|
||||
import content.data.skill.SkillingTool;
|
||||
import core.game.interaction.NodeUsageEvent;
|
||||
import core.game.interaction.Option;
|
||||
import core.game.interaction.UseWithHandler;
|
||||
import core.game.node.Node;
|
||||
import core.game.node.entity.Entity;
|
||||
import core.game.node.entity.combat.BattleState;
|
||||
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.item.Item;
|
||||
import core.game.world.GameWorld;
|
||||
import core.game.world.map.Location;
|
||||
import core.game.world.map.zone.MapZone;
|
||||
import core.game.world.map.zone.ZoneBorders;
|
||||
import core.game.world.map.zone.ZoneBuilder;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
import core.plugin.ClassScanner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Handles the Wilderness Area Zone.
|
||||
* @author Empathy
|
||||
* @author Vexia
|
||||
*
|
||||
*/
|
||||
@Initializable
|
||||
public class WildernessAreaZone extends MapZone implements Plugin<Object> {
|
||||
|
||||
/**
|
||||
* The list of players in the arena.
|
||||
*/
|
||||
private final List<Player> players = new ArrayList<>(20);
|
||||
|
||||
/**
|
||||
* Constructs a new {@code WildernessAreaZone} {@code Object}
|
||||
*/
|
||||
public WildernessAreaZone() {
|
||||
super("Wilderness Area Zone", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
ZoneBuilder.configure(this);
|
||||
ClassScanner.definePlugins(new MandrithDialoguePlugin(), new PilesDialoguePlugin(), new PilesItemHandler(), new RuniteGolemNPC());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean interact(Entity e, final Node node, Option option) {
|
||||
if (e instanceof Player) {
|
||||
Player player = e.asPlayer();
|
||||
switch (node.getId()) {
|
||||
case 42044:
|
||||
switch (option.getName()) {
|
||||
case "Open":
|
||||
if (player.getLocation().equals(Location.create(3184, 3945, 0))) {
|
||||
if (player.getInventory().contains(995, 7500)) {
|
||||
player.getDialogueInterpreter().sendOptions("Pay 7500 coins?", "Yes", "No");
|
||||
player.getDialogueInterpreter().addAction(new DialogueAction() {
|
||||
|
||||
@Override
|
||||
public void handle(Player player, int buttonId) {
|
||||
switch (buttonId) {
|
||||
case 2:
|
||||
if (player.getInventory().remove(new Item(995, 7500))) {
|
||||
DoorActionHandler.handleDoor(player, node.asScenery());
|
||||
player.sendMessage("You pay 7500 coins and enter the resource arena.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
return true;
|
||||
}
|
||||
player.sendMessage("You do not have enough coins to enter the Arena.");
|
||||
return true;
|
||||
}
|
||||
DoorActionHandler.handleDoor(player, node.asScenery());
|
||||
return true;
|
||||
case "Players-inside":
|
||||
if (player.getLocation().getY() < 3495) {
|
||||
player.sendMessage("All you see is the barren wasteland of the Wilderness.");
|
||||
return true;
|
||||
}
|
||||
String message = "You peek inside the gate and see no adventurers inside the arena.";
|
||||
if (players.size() > 0) {
|
||||
message = players.size() == 1 ? "You peek inside the gate and see 1 adventurer inside the arena." : "You peek inside the gate and see " + players.size() + " inside the arena.";
|
||||
}
|
||||
player.getDialogueInterpreter().sendDialogue(message);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 8666:
|
||||
switch (option.getName()) {
|
||||
case "Mine":
|
||||
player.getPulseManager().run(new RuniteGolemMinePulse(player, node.asNpc()));
|
||||
return true;
|
||||
case "Prospect":
|
||||
player.sendMessages("You examine the rock for ores...", "This rock contains runite ore.");
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.interact(e, node, option);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object fireEvent(String identifier, Object... args) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure() {
|
||||
register(new ZoneBorders(3174, 3924, 3196, 3945));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean enter(Entity e) {
|
||||
if (e instanceof Player) {
|
||||
Player p = e.asPlayer();
|
||||
players.add(p);
|
||||
}
|
||||
return super.enter(e);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public boolean leave(Entity e, boolean logout) {
|
||||
if (e instanceof Player) {
|
||||
Player p = e.asPlayer();
|
||||
players.remove(p);
|
||||
if (logout && p.getLocation().getY() <= 3944) {
|
||||
p.setLocation(Location.create(3184, 3945, 0));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return super.leave(e, logout);
|
||||
}
|
||||
|
||||
/**
|
||||
* The mining of a runite golem.
|
||||
* @author Vexia
|
||||
*
|
||||
*/
|
||||
public class RuniteGolemMinePulse extends SkillPulse<NPC> {
|
||||
|
||||
/**
|
||||
* The skilling tool used.
|
||||
*/
|
||||
private SkillingTool tool;
|
||||
|
||||
/**
|
||||
* The ticks.
|
||||
*/
|
||||
private int ticks;
|
||||
|
||||
/**
|
||||
* Constructs a new @{Code RuniteGolemMinePulse} object.
|
||||
* @param player The player.
|
||||
* @param node The node.
|
||||
*/
|
||||
public RuniteGolemMinePulse(Player player, NPC node) {
|
||||
super(player, node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
resource = SkillingResource.RUNITE_ORE_0;
|
||||
if (node.getId() != 8666) {
|
||||
player.getPacketDispatch().sendMessage("This rock contains no ore.");
|
||||
return;
|
||||
}
|
||||
if (resource == null) {
|
||||
return;
|
||||
}
|
||||
super.start();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean checkRequirements() {
|
||||
if (node.getId() != 8666) {
|
||||
return false;
|
||||
}
|
||||
if (player.getSkills().getLevel(resource.getSkillId()) < resource.getLevel()) {
|
||||
player.getPacketDispatch().sendMessage("You need a " + Skills.SKILL_NAME[resource.getSkillId()] + " level of " + resource.getLevel() + " to mine this rock.");
|
||||
return false;
|
||||
}
|
||||
if ((tool = SkillingTool.getPickaxe(player)) == null) {
|
||||
player.getPacketDispatch().sendMessage("You do not have a pickaxe to use.");
|
||||
return false;
|
||||
}
|
||||
if (player.getInventory().freeSlots() < 1) {
|
||||
player.getDialogueInterpreter().sendDialogue("Your inventory is too full to hold any more runite ore.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void animate() {
|
||||
if (tool != null) {
|
||||
player.animate(tool.getAnimation());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean reward() {
|
||||
if (++ticks % 4 != 0) {
|
||||
return false;
|
||||
}
|
||||
if (!checkReward()) {
|
||||
return false;
|
||||
}
|
||||
node.transform(8667);
|
||||
node.setAttribute("reward-tick", GameWorld.getTicks() + resource.getRespawnDuration());
|
||||
final Item item = new Item(resource.getReward());
|
||||
player.getInventory().add(item);
|
||||
player.getSkills().addExperience(resource.getSkillId(), resource.getExperience(), true);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player gets rewarded.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
private boolean checkReward() {
|
||||
int skill = Skills.MINING;
|
||||
int level = 1 + player.getSkills().getLevel(skill) + player.getFamiliarManager().getBoost(skill);
|
||||
double hostRatio = Math.random() * (100.0 * resource.getRate());
|
||||
double clientRatio = Math.random() * ((level - resource.getLevel()) * (1.0 + tool.getRatio()));
|
||||
return hostRatio < clientRatio;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the runite golem npc.
|
||||
* @author Vexia
|
||||
*
|
||||
*/
|
||||
public class RuniteGolemNPC extends AbstractNPC {
|
||||
|
||||
/**
|
||||
* The respawn time.
|
||||
*/
|
||||
private int respawn = -1;
|
||||
|
||||
/**
|
||||
* Constructs a new @{Code RuniteGolemNPC} object.
|
||||
* @param id The npc id.
|
||||
* @param location The location.
|
||||
*/
|
||||
public RuniteGolemNPC(int id, Location location) {
|
||||
super(id, location);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new @{Code RuniteGolemNPC} object.
|
||||
*/
|
||||
public RuniteGolemNPC() {
|
||||
super(-1, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractNPC construct(int id, Location location, Object... objects) {
|
||||
return new RuniteGolemNPC(id, location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
super.init();
|
||||
setAggressive(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendImpact(BattleState state) {
|
||||
super.sendImpact(state);
|
||||
if (state.getEstimatedHit() > 16) {
|
||||
state.setEstimatedHit(16);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTickActions() {
|
||||
super.handleTickActions();
|
||||
if (isAggressive()) {
|
||||
setAggressive(false);
|
||||
}
|
||||
if (respawn != -1 && respawn < GameWorld.getTicks() && getId() > 8664) {
|
||||
transform(8664);
|
||||
unlock();
|
||||
}
|
||||
if (getId() == 8667) {
|
||||
int rewardTick = getAttribute("reward-tick", -1);
|
||||
if (rewardTick != -1 && rewardTick < GameWorld.getTicks()) {
|
||||
transform(8666);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finalizeDeath(Entity killer) {
|
||||
respawn = GameWorld.getTicks() + 500;
|
||||
fullRestore();
|
||||
getProperties().setTeleportLocation(getLocation());
|
||||
setRespawnTick(0);
|
||||
setInvisible(false);
|
||||
transform(8666);
|
||||
lock();
|
||||
faceLocation(null);
|
||||
face(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getIds() {
|
||||
return new int[] {8664};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the item on piles interaction.
|
||||
* @author Vexia
|
||||
*
|
||||
*/
|
||||
public static class PilesItemHandler extends UseWithHandler {
|
||||
|
||||
/**
|
||||
* The allowed items for piles.
|
||||
*/
|
||||
private static final int[] ALLOWED = new int[] {14937, 14939, 449, 447, 440, 444, 453, 451, 1515, 1513, 2349, 9467,2351,2355,2353,2357,2359,2361,2363};
|
||||
|
||||
/**
|
||||
* Constructs a new @{Code PilesItemHandler} object.
|
||||
*/
|
||||
public PilesItemHandler() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
addHandler(8663, NPC_TYPE, this);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(final NodeUsageEvent event) {
|
||||
final Player player = event.getPlayer();
|
||||
for (int itemId : ALLOWED) {
|
||||
if (event.getUsedItem().getId() == itemId) {
|
||||
final int amount = player.getInventory().getAmount(itemId);
|
||||
final int price = 50 * amount;
|
||||
if (!player.getInventory().contains(995, price)) {
|
||||
player.getDialogueInterpreter().sendDialogues(8663, FacialExpression.OLD_NORMAL, "I'll need 50 coins per item.");
|
||||
return true;
|
||||
}
|
||||
player.getDialogueInterpreter().sendOptions("Banknote " + amount + " x " + event.getUsedItem().getName() + "?", "Yes - " + price + " gp", "Cancel");
|
||||
player.getDialogueInterpreter().addAction((player1, buttonId) -> {
|
||||
if (player1.getInventory().remove(new Item(995, price)) && player1.getInventory().remove(new Item(event.getUsedItem().getId(), amount))) {
|
||||
player1.getInventory().add(new Item(event.getUsedItem().getNoteChange(), amount));
|
||||
player1.getDialogueInterpreter().sendItemMessage(event.getUsedItem().getId(), "Piles converts your items to banknotes.");
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
player.getDialogueInterpreter().sendDialogues(8663, FacialExpression.OLD_NORMAL, "Sorry, I wasn't expecting anyone to want to convert", "that sort of item, so I haven't any banknotes for it.");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDynamic() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the Piles dialogue.
|
||||
* @author Vexia
|
||||
*
|
||||
*/
|
||||
public class PilesDialoguePlugin extends DialoguePlugin {
|
||||
|
||||
/**
|
||||
* Constructs a new @{Code PilesDialoguePlugin} object.
|
||||
*/
|
||||
public PilesDialoguePlugin() {
|
||||
/*
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new @{Code PilesDialoguePlugin} object.
|
||||
* @param player The player.
|
||||
*/
|
||||
public PilesDialoguePlugin(Player player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DialoguePlugin newInstance(Player player) {
|
||||
return new PilesDialoguePlugin(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean open(Object... args) {
|
||||
npc("Hello. I can convert items to banknotes, for 50 coins", "per item. Just hand me the items you'd like me to", "convert.");
|
||||
stage = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(int interfaceId, int buttonId) {
|
||||
switch (stage) {
|
||||
case 0:
|
||||
options("Who are you?", "Thanks.");
|
||||
stage++;
|
||||
break;
|
||||
case 1:
|
||||
switch (buttonId) {
|
||||
case 1:
|
||||
player("Who are you?");
|
||||
stage = 10;
|
||||
break;
|
||||
case 2:
|
||||
player("Thanks.");
|
||||
stage = 2;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
end();
|
||||
break;
|
||||
case 10:
|
||||
npc("I'm Piles. I lived in Draynor Village when I was", "young, where I saw three men working in the market,", "converting items to banknotes.");
|
||||
stage++;
|
||||
break;
|
||||
case 11:
|
||||
npc("Their names were Niles, Miles and Giles. I'm trying to", "be like them, so I've changed my name and started this", "business here.");
|
||||
stage++;
|
||||
break;
|
||||
case 12:
|
||||
player("Thanks.");
|
||||
stage = 2;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getIds() {
|
||||
return new int[] {8663};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the Mandrith dialogue.
|
||||
* @author Empathy
|
||||
*
|
||||
*/
|
||||
public class MandrithDialoguePlugin extends DialoguePlugin {
|
||||
|
||||
/**
|
||||
*
|
||||
* Constructs a new @{Code MandrithDialoguePlugin} object.
|
||||
*/
|
||||
public MandrithDialoguePlugin() {
|
||||
/*
|
||||
* empty
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Constructs a new @{Code MandrithDialoguePlugin} object.
|
||||
* @param player
|
||||
*/
|
||||
public MandrithDialoguePlugin(Player player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DialoguePlugin newInstance(Player player) {
|
||||
return new MandrithDialoguePlugin(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean open(Object... args) {
|
||||
player("Who are you and what is this place?" );
|
||||
stage = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(int interfaceId, int buttonId) {
|
||||
switch (stage) {
|
||||
case 1:
|
||||
npc("My name is Mandrith." );
|
||||
stage = 2;
|
||||
break;
|
||||
case 2:
|
||||
npc("I collect valuable resources and pawn off access to them", "to foolish adventurers, like yourself" );
|
||||
stage = 3;
|
||||
break;
|
||||
case 3:
|
||||
npc("You should take a look inside my arena. There's an", "abundance of valuable resources inside." );
|
||||
stage = 4;
|
||||
break;
|
||||
case 4:
|
||||
player("And I can take whatever I want?" );
|
||||
stage = 5;
|
||||
break;
|
||||
case 5:
|
||||
npc("It's all yours. All I ask is that you pay the upfront fee." );
|
||||
stage = 6;
|
||||
break;
|
||||
case 6:
|
||||
player("Will others be able to kill me inside?" );
|
||||
stage = 7;
|
||||
break;
|
||||
case 7:
|
||||
npc("Yes. These walls will only hold them back for so long." );
|
||||
stage = 8;
|
||||
break;
|
||||
case 8:
|
||||
player("You'll stop them though, right?" );
|
||||
stage = 9;
|
||||
break;
|
||||
case 9:
|
||||
npc("Haha! For the right price, I won't deny anyone access", "to my arena. Even if their intention is to kill you." );
|
||||
stage = 10;
|
||||
break;
|
||||
case 10:
|
||||
player("Right..." );
|
||||
stage = 11;
|
||||
break;
|
||||
case 11:
|
||||
npc("My arena holds many treasure that I've acquired at", "great expense, adventurer. Their bounty can come at a", "price." );
|
||||
stage = 12;
|
||||
break;
|
||||
case 12:
|
||||
npc("One day, adventurer, I will boast ownership of a much", "larger, much more dangerous arena than this. Take", "advantage of this offer while it lasts." );
|
||||
stage = 13;
|
||||
break;
|
||||
case 13:
|
||||
end();
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getIds() {
|
||||
return new int[] { 8662 };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -212,7 +212,7 @@ public final class EquipmentContainer extends Container {
|
|||
for(Item currentItem : currentItems) {
|
||||
Plugin<Object> plugin = currentItem.getDefinition().getConfiguration("equipment", null);
|
||||
if (plugin != null) {
|
||||
Object object = plugin.fireEvent("unequip", player, currentItem, newItem);
|
||||
Object object = plugin.fireEvent("unequip", player, currentItem);
|
||||
if (object != null && !((Boolean) object)) {
|
||||
canContinue = false;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -104,13 +104,19 @@ public enum FacialExpression {
|
|||
CHILD_SUSPICIOUS(7179),
|
||||
CHILD_SURPRISED(7180),
|
||||
|
||||
//Familiar Chatheads
|
||||
GRAAHK_NOD(6551),
|
||||
GHRAAK_SHAKE_MILD(6553),
|
||||
GHRAAK_SHAKE_VIGOROUS(6555),
|
||||
|
||||
|
||||
; //TODO: More?
|
||||
|
||||
/*
|
||||
* From some sources: here's a potential list of chatheads.
|
||||
* // 667
|
||||
* Chat animation group: 1540; linked animations: [7, 8, 9, 6824]
|
||||
* Chat animation group: 1489; linked animations: [225, 6550, 6551, 6552, 6553, 6555, 8372, 8373, 8374, 8375, 8581, 8582, 9178, 9179, 9180, 9181, 9183, 9187, 9189, 9190, 9192, 9202]
|
||||
* Chat animation group: 1489; potentially all familiars; linked animations: [225, 6550, 6551, 6552, 6553, 6555, 8372, 8373, 8374, 8375, 8581, 8582, 9178, 9179, 9180, 9181, 9183, 9187, 9189, 9190, 9192, 9202]
|
||||
* Chat animation group: 82; linked animations: [554, 555, 556, 557, 562, 563, 564, 565, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 610, 611, 612, 613, 614, 615, 616, 617]
|
||||
* Chat animation group: 84; linked animations: [558, 559, 560, 561]
|
||||
* Chat animation group: 80; linked animations: [584, 585, 586, 587]
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package core.game.node.entity.player;
|
|||
import content.global.handlers.item.equipment.BarrowsEquipment;
|
||||
import content.global.handlers.item.equipment.special.SalamanderSwingHandler;
|
||||
import content.global.skill.runecrafting.PouchManager;
|
||||
import content.global.skill.slayer.SlayerEquipmentFlags;
|
||||
import core.api.ContentAPIKt;
|
||||
import core.game.component.Component;
|
||||
import core.game.container.Container;
|
||||
|
|
@ -638,7 +639,7 @@ public class Player extends Entity {
|
|||
if (i == null) continue;
|
||||
InteractionListeners.run(i.getId(), this, i, false);
|
||||
Plugin equipPlugin = i.getDefinition().getConfiguration("equipment", null);
|
||||
if (equipPlugin != null) equipPlugin.fireEvent("unequip");
|
||||
if (equipPlugin != null) equipPlugin.fireEvent("unequip", this, i);
|
||||
}
|
||||
|
||||
boolean canCreateGrave = GraveController.allowGenerate(this);
|
||||
|
|
@ -669,9 +670,9 @@ public class Player extends Entity {
|
|||
}
|
||||
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());
|
||||
}
|
||||
int brokenItemId = Objects.requireNonNull(BarrowsEquipment.getDefinition(item.getId())).getBrokenId();
|
||||
item = new Item(brokenItemId, item.getAmount());
|
||||
}
|
||||
} else {
|
||||
item = GraveController.checkTransform(item);
|
||||
}
|
||||
|
|
@ -687,6 +688,7 @@ public class Player extends Entity {
|
|||
}
|
||||
|
||||
equipment.clear();
|
||||
SlayerEquipmentFlags.updateFlags(this);
|
||||
inventory.clear();
|
||||
inventory.addAll(c[0]);
|
||||
familiarManager.dismiss();
|
||||
|
|
|
|||
|
|
@ -62,17 +62,18 @@ class Shop(val title: String, val stock: Array<ShopItem>, val general: Boolean =
|
|||
|
||||
fun showTab(player: Player, main: Boolean)
|
||||
{
|
||||
val cont = if (main) getAttribute<Container?>(player, "shop-cont", null) ?: return else playerStock
|
||||
val mainCont = getAttribute<Container?>(player, "shop-cont", null) ?: return
|
||||
val cont = if (main) mainCont else playerStock
|
||||
|
||||
if(!main)
|
||||
{
|
||||
cont.listeners.remove(listenerInstances[player.details.uid])
|
||||
mainCont.listeners.remove(listenerInstances[player.details.uid])
|
||||
playerStock.listeners.add(listenerInstances[player.details.uid])
|
||||
}
|
||||
else
|
||||
{
|
||||
playerStock.listeners.remove(listenerInstances[player.details.uid])
|
||||
cont.listeners.add(listenerInstances[player.details.uid])
|
||||
mainCont.listeners.add(listenerInstances[player.details.uid])
|
||||
}
|
||||
|
||||
val settings = IfaceSettingsBuilder()
|
||||
|
|
|
|||
|
|
@ -2,13 +2,14 @@ package core.game.system.command
|
|||
|
||||
import core.game.node.entity.player.Player
|
||||
import core.ServerConstants
|
||||
import core.api.sendChat
|
||||
import core.game.node.entity.player.info.Rights
|
||||
import core.game.world.GameWorld
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
/**
|
||||
* Base class for Commands in the new system. Can pass a lambda as part of the constructor or after the constructor.
|
||||
* @author Ceikry
|
||||
* @author Ceikry, Player Name
|
||||
*/
|
||||
class Command(val name: String, val privilege: Privilege, val usage: String = "UNDOCUMENTED", val description: String = "UNDOCUMENTED", val handle: (Player, Array<String>) -> Unit) {
|
||||
fun attemptHandling(player: Player, args: Array<String>?){
|
||||
|
|
@ -18,6 +19,11 @@ class Command(val name: String, val privilege: Privilege, val usage: String = "U
|
|||
val isCheater = ServerConstants.I_AM_A_CHEATER
|
||||
if (hasRights || isDev || isCheater) {
|
||||
handle(player,args)
|
||||
} else if (ServerConstants.PLAYER_COMMANDS || args[0] == "bank") {
|
||||
// Authentically, if you attempt to use a command you shouldn't have access to, the game is supposed to say the below line.
|
||||
// We do this for all our custom commands if they are enabled (in which case this will only trigger for commands above your privilege level),
|
||||
// otherwise we only do it for the one command we have evidence existed authentically, "bank" (https://www.reddit.com/r/2007scape/comments/3n1c4d/hey_everyone_i_just_tried_to_do_something_very/)
|
||||
sendChat(player, "Hey, everyone, I just tried to do something very silly!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue