Implemented Mogre miniquest

This commit is contained in:
GregF 2025-02-16 10:42:27 +00:00 committed by Ryan
parent 2d1a626df0
commit b6560c0e3f
10 changed files with 629 additions and 413 deletions

View file

@ -5858,205 +5858,165 @@
"charm": [
{
"minAmount": "1",
"weight": "100.0",
"id": "12158",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "100.0",
"id": "12159",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "100.0",
"id": "12160",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "100.0",
"id": "12163",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "5600.0",
"weight": "1000.0",
"id": "0",
"maxAmount": "1"
}
],
"tertiary": [
{
"minAmount": "1",
"weight": "4986.5",
"id": "0",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "12.5",
"id": "10976",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "1.0",
"id": "10977",
"maxAmount": "1"
}
],
"ids": "114",
"description": "",
"main": [
{
"minAmount": "1",
"weight": "50.0",
"id": "7844",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "5.0",
"id": "10977",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "5.0",
"id": "10976",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5323",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5298",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5281",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5301",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5280",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5294",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5297",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5104",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5100",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5106",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "12176",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5293",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5296",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5311",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5105",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5292",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "5.0",
"id": "5295",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "5.0",
"id": "5303",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "5.0",
"id": "5302",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "5.0",
"id": "5321",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "5.0",
"id": "5299",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "5.0",
"id": "31",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "100.0",
"id": "0",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "3.0",
"weight": "39.0625",
"id": "6666",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "3.0",
"weight": "78.125",
"id": "6665",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "13.0",
"id": "14422",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "13.0",
"id": "14430",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "156.25",
"id": "345",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "156.25",
"id": "327",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "156.25",
"id": "371",
"maxAmount": "1"
},
{
"minAmount": "2",
"weight": "156.25",
"id": "372",
"maxAmount": "5"
},
{
"minAmount": "1",
"weight": "156.25",
"id": "359",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "156.25",
"id": "360",
"maxAmount": "3"
},
{
"minAmount": "1",
"weight": "39.0625",
"id": "383",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "39.0625",
"id": "349",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "39.0625",
"id": "331",
"maxAmount": "1"
},
{
"minAmount": "5",
"weight": "156.25",
"id": "313",
"maxAmount": "15"
},
{
"minAmount": "1",
"weight": "156.25",
"id": "1511",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "39.0625",
"id": "1383",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "78.125",
"id": "407",
"maxAmount": "1"
},
{
"minAmount": "4",
"weight": "78.125",
"id": "402",
"maxAmount": "8"
},
{
"minAmount": "5",
"weight": "4.0",
"id": "555",
"maxAmount": "18"
},
{
"minAmount": "3",
"weight": "78.125",
"id": "6664",
"maxAmount": "6"
},
{
"minAmount": "1",
"weight": "39.0625",
"id": "401",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "39.0625",
"id": "6667",
"maxAmount": "1"
}
]
},

View file

@ -72145,6 +72145,7 @@
{
"examine": "A sea bird.",
"name": "Gull",
"water_npc": "true",
"id": "2726"
},
{
@ -87866,5 +87867,30 @@
"name": "Elena",
"id": "335",
"examine": "She doesn't look too happy."
},
{
"examine": "Use 1344 to change me",
"name": "Skippy Varbit",
"id": "2795"
},
{
"examine": "He looks angry and smells drunk.",
"name": "Skippy",
"id": "2796"
},
{
"name": "Skippy",
"id": "2797",
"examine": "Skippy, just looking a little 'tender'."
},
{
"name": "Skippy",
"id": "2798",
"examine": "He seems a lot less angry and smells a great deal fresher."
},
{
"name": "Skippy",
"id": "2799",
"examine": "He seems a bit confused."
}
]

View file

@ -6255,6 +6255,10 @@
"npc_id": "2794",
"loc_data": "{2606,3100,0,0,0}-"
},
{
"npc_id": "2795",
"loc_data": "{2979,3197,0,1,0}-"
},
{
"npc_id": "2796",
"loc_data": "{3096,3108,0,0,6}-"

View file

@ -72,7 +72,7 @@ public final class FieldPickingPlugin extends OptionHandler {
player.dispatch(new ResourceProducedEvent(reward.getId(), reward.getAmount(), node, -1));
if (plant.name().startsWith("NETTLES") && (player.getEquipment().get(EquipmentContainer.SLOT_HANDS) == null || player.getEquipment().get(EquipmentContainer.SLOT_HANDS) != null && !player.getEquipment().get(EquipmentContainer.SLOT_HANDS).getName().contains("glove"))) {
player.getPacketDispatch().sendMessage("You have been stung by the nettles!");
player.getImpactHandler().manualHit(player, 2, HitsplatType.POISON);
player.getImpactHandler().manualHit(player, 6, HitsplatType.POISON);
return true;
}
if (plant.respawn != -1 && plant != PickingPlant.FLAX) {

View file

@ -1,228 +0,0 @@
package content.global.skill.slayer;
import core.cache.def.impl.SceneryDefinition;
import core.game.interaction.NodeUsageEvent;
import core.game.interaction.OptionHandler;
import core.game.interaction.UseWithHandler;
import core.game.node.Node;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.CombatStyle;
import core.game.node.entity.combat.ImpactHandler.HitsplatType;
import core.game.node.entity.impl.Projectile;
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.HintIconManager;
import core.game.node.entity.player.link.diary.DiaryType;
import core.game.node.item.Item;
import core.game.node.scenery.Scenery;
import core.game.system.task.Pulse;
import core.game.world.GameWorld;
import core.game.world.map.Direction;
import core.game.world.map.Location;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.plugin.Initializable;
import core.plugin.Plugin;
import core.tools.RandomFunction;
/**
* Represents the plugin used to handle the fishing expolosive on a omnious
* fishing spot.
* @author 'Vexia
*/
@Initializable
public final class FishingExplosivePlugin extends OptionHandler {
/**
* Represents the ominous fishing spot ids.
*/
private final static int[] IDS = new int[] { 10087, 10088, 10089 };
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
for (int id : IDS) {
SceneryDefinition.forId(id).getHandlers().put("option:lure", this);
SceneryDefinition.forId(id).getHandlers().put("option:bait", this);
}
new FishingExplosiveHandler().newInstance(arg);
new MogreNPC().newInstance(arg);
return this;
}
@Override
public boolean handle(Player player, Node node, String option) {
player.getPacketDispatch().sendMessage("Something seems to have scared all the fishes away...");
return true;
}
@Override
public Location getDestination(Node node, Node n) {
return node.getLocation();
}
/**
* Represents the handler for the fishing expolsive on a fishing spot.
* @author 'Vexia
* @version 1.0
*/
public static final class FishingExplosiveHandler extends UseWithHandler {
/**
* Represents the throwing animation.
*/
private static final Animation ANIMATION = new Animation(385);
/**
* Represents the splashing graphics.
*/
private static final Graphics SPLASH_GRAPHIC = new Graphics(68);
/**
* Represents the npc mogre id.
*/
private static final int MOGRE_ID = 114;
/**
* Represents the messages used to send for the mogres.
*/
private static final String[] MESSAGES = new String[] { "Da boom-boom kill all da fishies!", "I smack you good!", "Smash stupid human!", "Tasty human!", "Human hit me on the head!", "I get you!", "Human scare all da fishies!" };
/**
* Constructs a new {@code FishingExplosiveHandler} {@code Object}.
*/
public FishingExplosiveHandler() {
super(6664, 12633);
}
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
for (int i : IDS) {
addHandler(i, OBJECT_TYPE, this);
}
return this;
}
@Override
public boolean handle(final NodeUsageEvent event) {
final Player player = event.getPlayer();
if (player.getAttributes().containsKey("hasMogre")) {
player.getDialogueInterpreter().sendDialogues(player, null, "Sinister as that fishing spot is, why would I want to", "explode it?");
return true;
}
if (!player.getInventory().remove(new Item(event.getUsedItem().getId(), 1))) {
return true;
}
final int delay = (int) (2 + (player.getLocation().getDistance(event.getUsedWith().getLocation())) * 0.5);
player.animate(ANIMATION);
player.getPacketDispatch().sendMessage("You hurl the shuddering vial into the water...");
sendProjectile(player, (Scenery) event.getUsedWith());
GameWorld.getPulser().submit(new Pulse(delay, player) {
@Override
public boolean pulse() {
Direction dir = event.getUsedWith().getDirection();
NPC mogre = NPC.create(MOGRE_ID, event.getUsedWith().getLocation().transform(dir.getStepX() << 1, dir.getStepY() << 1, 0));
mogre.init();
mogre.moveStep();
mogre.setRespawn(false);
mogre.getProperties().getCombatPulse().attack(player);
mogre.setAttribute("player", player);
mogre.sendChat(MESSAGES[RandomFunction.random(MESSAGES.length)]);
HintIconManager.registerHintIcon(player, mogre);
if (event.getUsedItem().getId() == 12633) {
mogre.getImpactHandler().manualHit(player, 15, HitsplatType.NORMAL);
}
player.setAttribute("hasMogre", true);
mogre.graphics(SPLASH_GRAPHIC);
player.getPacketDispatch().sendMessage("...and a Mogre appears!");
return true;
}
});
return true;
}
/**
* Method used to send the fishign explosive projectile.
* @param player the player.
* @param object the object.
*/
private void sendProjectile(final Player player, final Scenery object) {
Projectile p = Projectile.create(player, null, 49, 30, 20, 30, Projectile.getSpeed(player, object.getLocation()));
p.setEndLocation(object.getLocation());
p.send();
}
@Override
public Location getDestination(Player player, Node with) {
return player.getLocation();
}
}
/**
* Represents a mogre npc.
* @author 'Vexia
* @version 1.0
*/
public final class MogreNPC extends AbstractNPC {
/**
* Constructs a new {@code MogreNPC} {@code Object}.
* @param id the id.
* @param location the location.
*/
public MogreNPC(int id, Location location) {
super(id, location, true);
}
/**
* Constructs a new {@code MogreNPC} {@code Object}.
*/
public MogreNPC() {
super(0, null);
}
@Override
public void tick() {
super.tick();
final Player pl = getAttribute("player", null);
if (pl == null || pl.getLocation().getDistance(getLocation()) > 15) {
clear();
}
}
@Override
public void clear() {
super.clear();
final Player pl = getAttribute("player", null);
if (pl != null) {
pl.removeAttribute("hasMogre");
}
}
@Override
public boolean isAttackable(Entity entity, CombatStyle style, boolean message) {
final Player pl = getAttribute("player", null);
return pl != null && pl == entity && super.isAttackable(entity, style, message);
}
@Override
public void finalizeDeath(final Entity killer) {
super.finalizeDeath(killer);
if (killer instanceof Player) {
final Player player = killer.asPlayer();
player.getAchievementDiaryManager().finishTask(player,DiaryType.FALADOR, 2, 7);
}
}
@Override
public AbstractNPC construct(int id, Location location, Object... objects) {
return new MogreNPC(id, location);
}
@Override
public int[] getIds() {
return new int[] { 114 };
}
}
}

View file

@ -106,7 +106,7 @@ public enum Master {
// new Task(Tasks.KILLERWATTS,6),
new Task(Tasks.KURASKS,7),
new Task(Tasks.LESSER_DEMONS,7),
//new Task(Tasks.MOGRES,7),
new Task(Tasks.MOGRES,7),
// new Task(Tasks.MOLANISKS,7),
new Task(Tasks.MOSS_GIANTS,7),
new Task(Tasks.OGRES,7),

View file

@ -0,0 +1,33 @@
package content.global.skill.slayer
import core.game.node.entity.Entity
import core.game.node.entity.npc.AbstractNPC
import core.game.world.map.Location
import org.rs09.consts.NPCs
/**
* Represents a mogre npc.
* @author 'Vexia
* @author gregf36665
* @version 2.0
*/
class MogreNPC : AbstractNPC(NPCs.MOGRE_114, null) {
override fun tick() {
super.tick()
val victim = properties.combatPulse.getVictim()
if (victim != null) {
if (victim.location.getDistance(getLocation()) > 15) {
clear()
}
}
}
override fun construct(id: Int, location: Location?, vararg objects: Any?): AbstractNPC {
return MogreNPC()
}
override fun getIds(): IntArray {
return intArrayOf(NPCs.MOGRE_114)
}
}

View file

@ -212,6 +212,9 @@ class FaladorAchievementDiary : DiaryEventHookBase(DiaryType.FALADOR) {
)
}
}
if (event.npc.id == NPCs.MOGRE_114){
finishTask(player, DiaryLevel.HARD, HardTasks.MUDSKIPPER_POINT_KILL_MOGRE)
}
}
override fun onItemPurchasedFromShop(player: Player, event: ItemShopPurchaseEvent) {

View file

@ -0,0 +1,151 @@
package content.region.asgarnia.mudskipperpoint
import content.global.skill.slayer.MogreNPC
import content.region.asgarnia.mudskipperpoint.dialogue.SkippyBootDialogue
import content.region.asgarnia.mudskipperpoint.dialogue.SkippyBucketDialogue
import core.api.*
import core.game.interaction.IntType
import core.game.interaction.InteractionListener
import core.game.node.entity.impl.Projectile
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.game.world.map.Location
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
import org.rs09.consts.Scenery
import org.rs09.consts.Vars
@Initializable
class MudSkipperPointListeners : InteractionListener {
companion object {
private val MESSAGES = arrayOf(
"Da boom-boom kill all da fishies!",
"I smack you good!",
"Smash stupid human!",
"Tasty human!",
"Human hit me on the head!",
"I get you!",
"Human scare all da fishies!"
)
private val FISHING_SPOTS = intArrayOf(
Scenery.OMINOUS_FISHING_SPOT_10087,
Scenery.OMINOUS_FISHING_SPOT_10088,
Scenery.OMINOUS_FISHING_SPOT_10089
)
}
private fun handleExplosives(player: Player, explosives: Item, target: Location): Boolean{
// Check if the player has unlocked the ability to summon Mogres
if (getVarbit(player, Vars.VARBIT_MINI_QUEST_MOGRE) != SkippyBucketDialogue.DONE_QUEST){
sendDialogueLines(player, "Sinister as that fishing spot is, why would I want to", "explode it?")
return false
}
val distance = player.location.getDistance(target)
if (distance < 5){
//too close
sendPlayerDialogue(player, "If this thing explodes, I think I should stand a liiiiitle further away.")
return false
}
if (distance > 14){
// too far
sendPlayerDialogue(player, "I can't throw that far.")
return false
}
removeItem(player, explosives.id)
animate(player, Animation(385)) // Throw the vial
sendMessage(player, "You hurl the shuddering vial into the water...")
val projectile = Projectile.create(player, null, 49, 30, 20, 30, Projectile.getSpeed(player, target.location))
projectile.endLocation = target.location
projectile.send()
val delay = (2+ distance * 0.5).toInt()
queueScript(player, delay){
val mogre = MogreNPC()
val xOffset = (player.location.x - target.location.x) % 2
val yOffset = (player.location.y - target.location.y) % 2
mogre.location = Location.create(target.location.x + xOffset, target.location.y + yOffset)
mogre.init()
mogre.moveStep()
mogre.isRespawn = false
mogre.attack(player)
registerHintIcon(player, mogre)
mogre.sendChat(MESSAGES[RandomFunction.random(MESSAGES.size)])
if (explosives.id == Items.SUPER_FISHING_EXPLOSIVE_12633){
impact(mogre, 15)
}
mogre.graphics(Graphics(68))
sendMessage(player, "...and a Mogre appears!")
return@queueScript stopExecuting(player)
}
return true
}
private fun soberSkippy(player: Player): Boolean {
if (getVarbit(player, Vars.VARBIT_MINI_QUEST_MOGRE) > SkippyBucketDialogue.DRUNK){
sendDialogue(player, "I think he's sober enough. And I don't want to use another bucket of water.")
return false
}
else{
if (hasAnItem(player, Items.BUCKET_OF_WATER_1929).exists()) {
openDialogue(player, SkippyBucketDialogue())
return true
}
else{
sendDialogue(player, "You know, I could shock him out of it if I could find some cold water...")
return false
}
}
}
override fun defineListeners() {
onUseWith(IntType.SCENERY, Items.FISHING_EXPLOSIVE_6664, *FISHING_SPOTS) { player, used, with ->
handleExplosives(player, used.asItem(), with.location)
}
onUseWith(IntType.SCENERY, Items.SUPER_FISHING_EXPLOSIVE_12633, *FISHING_SPOTS) { player, used, with ->
handleExplosives(player, used.asItem(), with.location)
}
on(FISHING_SPOTS, IntType.SCENERY, "Lure", "Bait") { player, _ ->
sendMessage(player, "Something seems to have scared all the fishes away...")
return@on true
}
on(Scenery.SIGNPOST_10090, IntType.SCENERY, "read") { player, _ ->
setInterfaceText(player, "Mudskipper Point.", 220, 2)
setInterfaceText(player, "WARNING! BEWARE OF THE MUDSKIPPERS!", 220, 4)
openInterface(player, 220)
return@on true
}
// For some reason the 2795 wrapper does not work for sober-up
on(intArrayOf(NPCs.SKIPPY_2796, NPCs.SKIPPY_2797, NPCs.SKIPPY_2798, NPCs.SKIPPY_2799),
IntType.NPC, "sober-up") { player, _ ->
return@on soberSkippy(player)
}
onUseWith(IntType.NPC, Items.BUCKET_OF_WATER_1929, NPCs.SKIPPY_2795) { player, _, _ ->
return@onUseWith soberSkippy(player)
}
onUseWith(IntType.NPC, Items.FORLORN_BOOT_6663, NPCs.SKIPPY_2795){ player, _, _ ->
openDialogue(player, SkippyBootDialogue())
return@onUseWith true
}
}
override fun defineDestinationOverrides() {
// Don't run towards the fishing spots when trying to lure or bait or throw explosives
setDest(IntType.SCENERY, FISHING_SPOTS, "Lure", "Bait", "use"){ entity, _ ->
return@setDest entity.location
}
}
}

View file

@ -0,0 +1,267 @@
package content.region.asgarnia.mudskipperpoint.dialogue
import content.data.Quests
import core.api.*
import core.game.dialogue.DialogueFile
import core.game.dialogue.DialoguePlugin
import core.game.dialogue.FacialExpression
import core.game.dialogue.Topic
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.plugin.Initializable
import core.tools.END_DIALOGUE
import core.tools.RandomFunction
import org.rs09.consts.Items
import org.rs09.consts.NPCs
import org.rs09.consts.Vars
@Initializable
class SkippyDialogue(player: Player? = null) : DialoguePlugin(player) {
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
openDialogue(player, SkippyBucketDialogue(0, getVarbit(player, Vars.VARBIT_MINI_QUEST_MOGRE)))
return true
}
override fun getIds(): IntArray {
return intArrayOf(NPCs.SKIPPY_2795)
}
}
class SkippyBucketDialogue(override var stage: Int = 0, val questStage: Int = 0) : DialogueFile() {
companion object{
// Skippy will progress through these stages as you help him
const val DRUNK = 0
const val TENDER = 1
const val HUNGOVER = 2
const val DONE_QUEST = 3
// Dialogue branches
const val THROW_WATER = 10
const val DRUNK_RAMBLING = 30
const val CRAZY_PEOPLE = 40
const val WHO_ARE_THEY = 50
// Tea state
const val LEARN_RECIPE = 170
const val PLAGUE_CITY_RECIPE = 180
const val NO_TEA = 190
// Hangover cure state
const val CURE = 220
const val NO_CURE = 250
const val RECIPE = 260
const val NAME_ORIGIN = 270
const val ALL_DONE = 300
}
override fun handle(componentID: Int, buttonID: Int) {
npc = NPC(NPCs.SKIPPY_2796)
when (questStage){
DRUNK -> when (stage) {
0 -> if(hasAnItem(player!!, Items.BUCKET_OF_WATER_1929).exists()){
playerl(FacialExpression.THINKING, "Well, I could dump this bucket of water over him. That would sober him up a little.").also { stage = THROW_WATER }
}
else {
playerl(FacialExpression.ASKING, "Are you all right? You seem a little...incoherent.").also { stage = DRUNK_RAMBLING }
}
THROW_WATER -> showTopics(
Topic("Throw the water!", THROW_WATER+ 1, true),
Topic("I think I'll leave it for now.", END_DIALOGUE)
)
THROW_WATER + 1 -> playerl(FacialExpression.NEUTRAL, "Hey, Skippy!").also { stage++ }
THROW_WATER + 2 -> npcl(FacialExpression.DRUNK, "What?").also {
stage = END_DIALOGUE
queueScript(player!!, 1){ animationStage : Int ->
when(animationStage){
1 -> {
// todo get the right animation
animate(player!!, 2283)
removeItem(player!!, Items.BUCKET_OF_WATER_1929)
addItem(player!!, Items.BUCKET_1925)
setVarbit(player!!, Vars.VARBIT_MINI_QUEST_MOGRE, TENDER, true)
return@queueScript delayScript(player!!, 1)
}
2 -> {
openDialogue(player!!, SkippyBucketDialogue(THROW_WATER + 4))
return@queueScript delayScript(player!!, 1)
}
3 -> return@queueScript stopExecuting(player!!)
else -> return@queueScript delayScript(player!!, 1)
}
} }
THROW_WATER + 4 -> npcl(FacialExpression.ANGRY, "Ahhhhhhhhhhgh! That's cold! Are you trying to kill me?").also { stage++ }
THROW_WATER + 5 -> playerl(FacialExpression.NEUTRAL, "Nope. Just sober you up. Memory coming back yet?").also { stage++ }
THROW_WATER + 6 -> npcl(FacialExpression.ANGRY, "No. But I could do with a bowl of tea to warm myself up a bit. Go grab me one and we'll talk.").also { stage++ }
THROW_WATER + 7 -> playerl(FacialExpression.ASKING, "Any particular type of tea?").also { stage++ }
THROW_WATER + 8 -> npcl(FacialExpression.ANGRY, "Nettle for preference. Just make sure it's hot.").also { stage++ }
THROW_WATER + 9 -> npcl(FacialExpression.ANGRY, "And don't throw it at me!").also { stage++ }
THROW_WATER + 10 -> playerl(FacialExpression.HALF_GUILTY, "What's your problem? You're all clean now.").also { stage = END_DIALOGUE }
DRUNK_RAMBLING -> npcl(FacialExpression.DRUNK, "Inc'hearnt? Inc'herant! You...you...with yer fancy book- lernin' words. You'd be more than inc'herant if youd seen...").also { stage++ }
DRUNK_RAMBLING + 1 -> npcl(FacialExpression.DRUNK, "(Dramatic pause)").also { stage++ }
DRUNK_RAMBLING + 2 -> npcl(FacialExpression.DRUNK, "THEM!").also { stage++ }
DRUNK_RAMBLING + 3 -> showTopics(
Topic("I'm sure I would as well.", CRAZY_PEOPLE),
Topic("Who are (Dramatic pause) THEY?", WHO_ARE_THEY, true)
)
CRAZY_PEOPLE -> playerl(FacialExpression.NEUTRAL, "I'm going over here to talk to non-crazy people now.").also { stage++ }
CRAZY_PEOPLE + 1 -> npcl(FacialExpression.DRUNK, "Yeah? Yeah? Well when THEY come floppin' into your house and eat your furniture you'll be sorry!").also { stage = END_DIALOGUE }
WHO_ARE_THEY -> playerl(FacialExpression.NEUTRAL, "Who are").also { stage++ }
WHO_ARE_THEY + 1 -> playerl(FacialExpression.NEUTRAL, "(Dramatic pause)").also { stage++ }
WHO_ARE_THEY + 2 -> playerl(FacialExpression.NEUTRAL, "THEY?").also { stage++ }
WHO_ARE_THEY + 3 -> npcl(FacialExpression.DRUNK, "They! Those bloodthirsty, flesh-tearing devils! They are the reason I'm out here every day hurlin' bottles into the sea!").also { stage++ }
WHO_ARE_THEY + 4 -> npcl(FacialExpression.DRUNK, "They are the reason I've lost everything, except the horrifying memory of what THEY look like...").also { stage++ }
WHO_ARE_THEY + 5 -> playerl(FacialExpression.ASKING, "And what do THEY look like?").also { stage++ }
WHO_ARE_THEY + 6 -> npcl(FacialExpression.DRUNK, "Mudskippers!").also { stage++ }
WHO_ARE_THEY + 7 -> playerl(FacialExpression.ASKING, "Mudskippers?").also { stage++ }
WHO_ARE_THEY + 8 -> npcl(FacialExpression.DRUNK, "Aye, Mudskippers! Those ferocious, ravening, evil, beady-eyed terrors of the deep!").also { stage++ }
WHO_ARE_THEY + 9 -> playerl(FacialExpression.SUSPICIOUS, "I...see...").also{ stage++ }
WHO_ARE_THEY + 10 -> npcl(FacialExpression.DRUNK, " I was ambushed by them way back, see. They got the drop on me...I can't remember where, somewhere around here though.").also { stage++ }
WHO_ARE_THEY + 11 -> playerl(FacialExpression.ASKING, "These would be the mudskippers, right?").also{ stage++ }
WHO_ARE_THEY + 12 -> npcl(FacialExpression.DRUNK, "Aye! The mudskippers! Huge they were! Ten feet of glistening, muddy flesh floppin' towards me with white foam flying from their gnashing fangs!").also { stage++ }
WHO_ARE_THEY + 13 -> npcl(FacialExpression.DRUNK, "I fought them up and down the beach, with the tide rising and more of them leaping towards me with cutlasses drawn!").also { stage++ }
WHO_ARE_THEY + 14 -> playerl(FacialExpression.HALF_GUILTY, "This is fascinating, but I have to be...").also{ stage++ }
WHO_ARE_THEY + 15 -> npcl(FacialExpression.DRUNK, "Shut yer' word-hole and listen! I can't remember all the details, as I'm sure they must have hit me quite hard, but the last thing I remember before it all went black...").also { stage++ }
WHO_ARE_THEY + 16 -> npcl(FacialExpression.DRUNK, "...was one of those devils rearing over me, its eyes glowin' red with the fires of hell!").also { stage++ }
WHO_ARE_THEY + 17 -> playerl(FacialExpression.ROLLING_EYES, "Fires of hell...right. I believe you.").also { stage++ }
WHO_ARE_THEY + 18 -> npcl(FacialExpression.DRUNK, "No you don't! You think I'm crazy, like all the rest! Well, if I'm crazy, how did I get these?").also { stage++ }
WHO_ARE_THEY + 19 -> playerl(FacialExpression.ASKING, "Get what?").also { stage++ }
WHO_ARE_THEY + 20 -> sendDialogue(player!!, "Skippy shows you what appears to be massive bite scars on his legs. You're no expert, but they look like... giant mudskipper bites!").also { stage++ }
WHO_ARE_THEY + 21 -> playerl(FacialExpression.ASKING, "Giant mudskipper bites! Where did you get those?").also { stage++ }
WHO_ARE_THEY + 22 -> npcl(FacialExpression.DRUNK, "I can't remember... I've been drinking to forget the horror, and all I seem to have forgotten is where it all happened...").also { stage++ }
WHO_ARE_THEY + 23 -> playerl(FacialExpression.THINKING, "Hmmm...I suppose if I sober you up you may well start to recall.").also{ stage++ }
WHO_ARE_THEY + 24 -> npcl(FacialExpression.DRUNK, "You'll have a job. I've been drinking this for a week.").also { stage++ }
WHO_ARE_THEY + 25 -> playerl(FacialExpression.ASKING, "'Captain Braindeath's Extra Strength Rum/Drain Cleaner. Now 50% more debilitating'?").also { stage++ }
WHO_ARE_THEY + 26 -> npcl(FacialExpression.DRUNK, "It's the extra sheep tranquilizers that gives it that added kick!").also { stage++ }
WHO_ARE_THEY + 27 -> playerl(FacialExpression.NEUTRAL, "Stay here and I'll be right back. Try not to move. Or go near any open flames.").also { stage = END_DIALOGUE }
}
TENDER -> when(stage){
0 -> playerl(FacialExpression.HAPPY, "Hey, Skippy!").also { stage++ }
1 -> npcl(FacialExpression.PANICKED, "Gaah! Don't drench me again!").also { stage++ }
2 -> playerl(FacialExpression.HALF_GUILTY, "Hey! I only did that once! Try not to be such a big baby!").also { stage++ }
3 -> npcl(FacialExpression.HALF_THINKING, "So what are you here for then?").also { stage = if (hasAnItem(player!!, Items.NETTLE_TEA_4239).exists()) 4 else NO_TEA }
4 -> playerl(FacialExpression.HAPPY, "I've come to give you your tea.").also { stage++ }
5 -> npcl(FacialExpression.HAPPY, "Excellent! I was thinking I was going to freeze out here!").also { stage++ }
6 -> sendItemDialogue(player!!, Items.NETTLE_TEA_4239, "Skippy drinks the tea and clutches his forehead in pain.").also {
stage++
removeItem(player!!, Items.NETTLE_TEA_4239)
setVarbit(player!!, Vars.VARBIT_MINI_QUEST_MOGRE, HUNGOVER, true)
}
7 -> npcl(FacialExpression.ANNOYED, "Ohhhhh...").also { stage++ }
8 -> playerl(FacialExpression.ASKING, "What? What's wrong?").also { stage++ }
9 -> npcl(FacialExpression.ANNOYED, "Not so loud...I think I have a hangover...").also { stage++ }
10 -> playerl(FacialExpression.HALF_WORRIED, "Great...Well, I doubt you can remember anything through a hangover. What a waste of nettle tea...").also { stage++ }
11 -> npcl(FacialExpression.FURIOUS, "Hey! A little sympathy here?").also { stage++ }
12 -> npcl(FacialExpression.ANNOYED, "Owwowwoww... must remember not to shout...").also { stage++ }
13 -> npcl(FacialExpression.ASKING, "Look, I do know a hangover cure. If you can get me a bucket of the stuff I think I'll be okay.").also { stage = if(getQuestStage(player!!, Quests.PLAGUE_CITY) >= 14 ) PLAGUE_CITY_RECIPE else LEARN_RECIPE }
PLAGUE_CITY_RECIPE -> playerl(FacialExpression.HALF_THINKING, "Wait... is this cure a bucket of chocolate milk and snape grass?").also { stage++ }
PLAGUE_CITY_RECIPE + 1 -> npcl(FacialExpression.HAPPY, "Yes! That's the stuff!").also { stage++ }
PLAGUE_CITY_RECIPE + 2 -> playerl(FacialExpression.HALF_THINKING, "Ahhh. Yes, I've made some of that stuff before. I should be able to get you some, no problem.").also { stage = END_DIALOGUE }
LEARN_RECIPE -> playerl(FacialExpression.ASKING, "So what is it you need?").also { stage++ }
LEARN_RECIPE + 1 -> npcl(FacialExpression.NEUTRAL, "A bucket of milk with chocolate ground into it, with a handful of snape grass thrown in on top.").also { stage++ }
LEARN_RECIPE + 2 -> playerl(FacialExpression.ASKING, "What? Run that past me again?").also { stage ++ }
LEARN_RECIPE + 3 -> npcl(FacialExpression.NEUTRAL, "Take a bucket of milk, a bar of chocolate and some snape grass.").also { stage++ }
LEARN_RECIPE + 4 -> npcl(FacialExpression.NEUTRAL, "Grind the chocolate with a mortar and pestle.").also { stage++ }
LEARN_RECIPE + 5 -> npcl(FacialExpression.NEUTRAL, "Add the chocolate powder to the milk, then add the snape grass.").also { stage++ }
LEARN_RECIPE + 6 -> npcl(FacialExpression.NEUTRAL, "Then bring it here and I will drink it.").also { stage++ }
LEARN_RECIPE + 7 -> npcl(FacialExpression.NEUTRAL, "The end, and we all live happily ever after. Got it?").also { stage = END_DIALOGUE }
NO_TEA -> playerl(FacialExpression.HALF_GUILTY, "No real reason. I just thought I would check up on you is all.").also { stage++ }
NO_TEA + 1 -> npcl(FacialExpression.ANGRY, "Well, I'm still wet, still cold and still waiting on that nettle tea.").also { stage = END_DIALOGUE }
}
HUNGOVER -> when(stage){
0 -> playerl(FacialExpression.HAPPY, "Hey, Skippy!").also{ stage++ }
1 -> npcl(FacialExpression.ANNOYED, "Egad! Don't you know not to shout around a guy with a hangover?").also { stage++ }
2 -> npcl(FacialExpression.HALF_GUILTY, "Ahhhhhg...No more shouting for me...").also { stage++ }
3 -> npcl(FacialExpression.ASKING, "What is it anyway?").also { stage = if (hasAnItem(player!!, Items.HANGOVER_CURE_1504).exists()) CURE else NO_CURE }
CURE -> playerl(FacialExpression.HAPPY, "Well Skippy, you will no doubt be glad to hear that I got you your hangover cure!").also { stage++ }
CURE + 1 ->npcl(FacialExpression.HAPPY, "Gimme!").also { stage++ }
CURE + 2 -> sendDialogue(player!!, "Skippy chugs the hangover cure... very impressive.").also {
removeItem(player!!, Items.HANGOVER_CURE_1504)
stage++
setVarbit(player!!, 1344, DONE_QUEST, true)
}
CURE + 3 -> npcl(FacialExpression.HAPPY, "Ahhhhhhhhhhhhhhh...").also { stage ++ }
CURE + 4 -> npcl(FacialExpression.HAPPY, "Much better...").also { stage ++ }
CURE + 5 -> playerl(FacialExpression.ASKING, "Feeling better?").also { stage ++ }
CURE + 6 -> npcl(FacialExpression.HAPPY, "Considerably.").also { stage ++ }
CURE + 7 -> playerl(FacialExpression.ASKING, "Then tell me where the mudskippers are!").also { stage++ }
CURE + 8 -> npcl(FacialExpression.NEUTRAL, "I wish you wouldn't go looking for them. Those vicious killers will tear you apart.").also { stage ++ }
CURE + 9 -> npcl(FacialExpression.HALF_THINKING, "It's all becoming clear to me now...").also { stage ++ }
CURE + 10 -> npcl(FacialExpression.HAPPY, "I was fishing using a Fishing Explosive...").also { stage ++ }
CURE + 11 -> playerl(FacialExpression.ASKING, "A Fishing Explosive?").also { stage++ }
CURE + 12 -> npcl(FacialExpression.NEUTRAL, "Well, Slayer Masters sell these highly volatile potions for killing underwater creatures.").also { stage ++ }
CURE + 13 -> npcl(FacialExpression.NEUTRAL, "If you don't feel like lobbing a net about all day you can use them to fish with...").also { stage ++ }
CURE + 14 -> npcl(FacialExpression.NEUTRAL, "But this time I was startled by what I thought was a giant mudskipper.").also { stage ++ }
CURE + 15 -> npcl(FacialExpression.NEUTRAL, "What it was, in fact, was a...").also { stage ++ }
CURE + 16 -> npcl(FacialExpression.NEUTRAL, "Dramatic Pause...").also { stage ++ }
CURE + 17 -> npcl(FacialExpression.PANICKED, "A Mogre!").also { stage ++ }
CURE + 18 -> playerl(FacialExpression.ASKING, "What exactly is a Mogre?").also { stage++ }
CURE + 19 -> npcl(FacialExpression.NEUTRAL, "A Mogre is a type of Ogre that spends most of its time underwater.").also { stage ++ }
CURE + 20 -> npcl(FacialExpression.NEUTRAL, "They hunt giant mudskippers by wearing their skins and swimming close until they can attack them.").also { stage ++ }
CURE + 21 -> npcl(FacialExpression.NEUTRAL, "When I used the Fishing Explosive I scared off all the fish, and so the Mogre got out of the water to express its extreme displeasure.").also { stage ++ }
CURE + 22 -> npcl(FacialExpression.NEUTRAL, "With an iron mace.").also { stage ++ }
CURE + 23 -> playerl(FacialExpression.ASKING, "I take it the head injury is responsible for the staggering and yelling?").also { stage++ }
CURE + 24 -> npcl(FacialExpression.NEUTRAL, "No, no.").also { stage ++ }
CURE + 25 -> npcl(FacialExpression.NEUTRAL, "My addiction to almost-lethal alcohol did that.").also { stage ++ }
CURE + 26 -> npcl(FacialExpression.NEUTRAL, "But if you are set on finding these Mogres just head south from here until you find Mudskipper Point.").also { stage ++ }
CURE + 27 -> playerl(FacialExpression.ASKING, "The mudskipper-eating monsters are to be found at Mudskipper point?").also { stage++ }
CURE + 28 -> playerl(FacialExpression.ROLLING_EYES, "Shock!").also { stage++ }
CURE + 29 -> playerl(FacialExpression.NEUTRAL, "Thanks. I'll be careful.").also { stage = END_DIALOGUE }
NO_CURE -> playerl(FacialExpression.HALF_GUILTY, "I just came back to ask you something.").also { stage++ }
NO_CURE + 1 -> npcl(FacialExpression.ANNOYED, "What?").also { stage++ }
NO_CURE + 2 -> showTopics(
Topic("How do I make that hangover cure again?", RECIPE),
Topic("Why do they call you 'Skippy'?", NAME_ORIGIN)
)
RECIPE -> npcl(FacialExpression.ANGRY, "Give me strength...Here's what you do. Pay attention!").also { stage++ }
RECIPE + 1 -> npcl(FacialExpression.ANGRY, "You take a bucket of milk, a bar of chocolate and some snape grass.").also { stage++ }
RECIPE + 2 -> npcl(FacialExpression.ANGRY, "Grind the chocolate with a pestle and mortar.").also { stage++ }
RECIPE + 3 -> npcl(FacialExpression.ANGRY, "Add the chocolate powder to the milk, then add the snape grass.").also { stage++ }
RECIPE + 4 -> npcl(FacialExpression.ANGRY, "Then bring it here and I will drink it.").also { stage++ }
RECIPE + 5 -> npcl(FacialExpression.ANGRY, "Are you likely to remember that or should I go get some crayons and draw you a picture?").also { stage++ }
RECIPE + 6 -> playerl(FacialExpression.ANGRY, "Hey! I remember it now, ok! See you in a bit.").also { stage = END_DIALOGUE }
NAME_ORIGIN -> npcl(FacialExpression.THINKING, "I think it may have something to do with my near- constant raving about mudskippers.").also { stage++ }
NAME_ORIGIN + 1 -> npcl(FacialExpression.THINKING, "That or it's something to do with that time with the dress and the field full of daisies...").also { stage = END_DIALOGUE }
}
DONE_QUEST -> when(stage){
0 -> playerl(FacialExpression.NEUTRAL, "Hey, Skippy.").also { stage++ }
1 -> npcl(FacialExpression.HAPPY, "Hey you!").also { stage++ }
2 -> playerl(FacialExpression.ASKING, "How do I annoy the Mogres again?").also { stage++ }
3 -> npcl(FacialExpression.HAPPY, "Go south to Mudskipper Point and lob a Fishing Explosive into the sea. You can grab them from the Slayer masters.").also { stage++ }
4 -> playerl(FacialExpression.ASKING, "Thanks! So, what are you going to do now?").also { stage++ }
5 -> npcl(FacialExpression.HAPPY, "Well, I was planning on continuing my hobby of wandering up and down this bit of coastline, bellowing random threats and throwing bottles.").also { stage++ }
6 -> npcl(FacialExpression.ASKING, "And you?").also { stage++ }
7 -> playerl(FacialExpression.NEUTRAL, "I was planning on wandering up and down the landscape, bugging people to see if they had mindblowingly dangerous quests for me to undertake.").also { stage++ }
8 -> npcl(FacialExpression.HAPPY, "Well, good luck with that!").also { stage++ }
9 -> playerl(FacialExpression.HAPPY, "You too!").also { stage++ }
10 -> npcl(FacialExpression.ROLLING_EYES, "Weirdo...").also { stage++ }
11 -> playerl(FacialExpression.ROLLING_EYES, "Loony..").also { stage = END_DIALOGUE }
}
}
}
}
class SkippyBootDialogue: DialogueFile(){
override fun handle(componentID: Int, buttonID: Int) {
npc = NPC(NPCs.SKIPPY_2796)
val expression = if (getVarbit(player!!, Vars.VARBIT_MINI_QUEST_MOGRE) > SkippyBucketDialogue.DRUNK) FacialExpression.ROLLING_EYES else FacialExpression.DRUNK
npcl(expression, "Thanks! Now I have two right boots!").also { stage = END_DIALOGUE }
}
}