Refactored Spirit Graahk

Added the effect of Spirit Graahk's scroll, Goad
Added Spirit Graahk's dialogue
Added Spirit Graahk's Baroo!-isms
This commit is contained in:
Bishop
2026-02-08 12:55:20 +00:00
committed by Ryan
parent 8283ae6ba8
commit 18dadc54c8
7 changed files with 200 additions and 163 deletions
@@ -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
}
}
@@ -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]