package content.global.skill.summoning; import core.cache.def.impl.SceneryDefinition; import core.game.component.Component; import core.game.activity.ActivityManager; import core.game.activity.ActivityPlugin; import core.game.activity.CutscenePlugin; import core.plugin.Initializable; import core.game.dialogue.DialoguePlugin; import core.game.global.action.ClimbActionHandler; import core.game.node.entity.skill.Skills; import core.game.interaction.OptionHandler; import core.game.node.Node; import core.game.node.entity.impl.Projectile; import core.game.node.entity.npc.NPC; import core.game.node.entity.player.Player; import core.game.node.entity.player.link.quest.Quest; 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.Location; import core.game.world.map.build.DynamicRegion; import core.game.world.map.path.Pathfinder; import core.game.world.update.flag.context.Animation; import core.game.world.update.flag.context.Graphics; import core.net.packet.PacketRepository; import core.net.packet.context.CameraContext; import core.net.packet.context.CameraContext.CameraType; import core.net.packet.context.MinimapStateContext; import core.net.packet.out.CameraViewPacket; import core.net.packet.out.MinimapState; import core.plugin.Plugin; import core.plugin.ClassScanner; /** * Handles the summoning training room. * @author Emperor * @author 'Vexia * @version 1.0 */ @Initializable public final class SummoningTrainingRoom extends OptionHandler { /** * Represents the wolf bones item. */ private static final Item BONES = new Item(2859, 2); /** * Represents the trapdoor key. */ private static final Item TRAPDOOR_KEY = new Item(12528); /** * Represents the howl scroll item. */ private static final Item HOWL_SCROLL = new Item(12425); /** * Represents the wolf pouch. */ private static final Item WOLF_POUCH = new Item(12047); @Override public Plugin newInstance(Object arg) throws Throwable { SceneryDefinition.forId(28675).getHandlers().put("option:open", this); SceneryDefinition.forId(28676).getHandlers().put("option:climb-down", this); SceneryDefinition.forId(28653).getHandlers().put("option:climb-down", this); SceneryDefinition.forId(28572).getHandlers().put("option:climb-up", this); SceneryDefinition.forId(28676).getHandlers().put("option:close", this); SceneryDefinition.forId(28714).getHandlers().put("option:climb", this); SceneryDefinition.forId(28586).getHandlers().put("option:search", this); ActivityManager.register(new FluffyCutscene()); return this; } @Override public boolean handle(final Player player, Node node, String option) { Scenery object = (Scenery) node; Location loc = null; Quest quest = player.getQuestRepository().getQuest("Wolf Whistle"); int questVal = quest.getStage(player) == 0 ? 0 : quest.getStage(player) > 0 && quest.getStage(player) < 100 ? 5 : 28893; switch (option) { case "close": player.getConfigManager().set(1178, questVal == 28893 ? 32989 : (1 << 11) + questVal); return true; case "open": if (quest.getStage(player) < 40) { player.getPacketDispatch().sendMessage("The trapdoor is locked."); return true; } else if (quest.getStage(player) == 40) { if (player.getAttribute("has-key", false) || player.getInventory().remove(TRAPDOOR_KEY)) { player.setAttribute("has-key", true); player.getConfigManager().set(1178, (2 << 11) + questVal, true); } else { player.getPacketDispatch().sendMessage("The trapdoor is locked."); return true; } } player.getConfigManager().set(1178, questVal == 28893 ? 28893 : (2 << 11) + questVal); return true; case "climb-down": if (object.getId() == 28653) { if (quest.getStage(player) == 50) { final CutscenePlugin plugin = player.getAttribute("in-cutscene", null); if (plugin != null) { plugin.stop(true); } else { ClimbActionHandler.climbLadder(player, object, option); } } else { ClimbActionHandler.climbLadder(player, object, option); } return true; } if (!object.getLocation().equals(Location.create(2927, 3444, 0))) { return false; } loc = Location.create(2209, 5348, 0); break; case "climb": if (!object.getLocation().equals(Location.create(2209, 5349, 0))) { return false; } loc = Location.create(2926, 3444, 0); break; case "climb-up": switch (quest.getStage(player)) { case 10: case 50: if (player.getFamiliarManager().hasFamiliar()) { player.getPacketDispatch().sendMessage("You can't bring a familiar up there."); return true; } if (quest.getStage(player) == 50 && (!player.getInventory().containsItem(WOLF_POUCH) || !player.getInventory().containsItem(HOWL_SCROLL))) { player.getDialogueInterpreter().sendDialogues(player, null, "I should bring my spirit wolf pouch and howl scroll", "with me up there."); return true; } ActivityManager.start(player, "fluffy cutscene", false); break; case 100: case 60: ClimbActionHandler.climbLadder(player, (Scenery) node, option); break; default: player.getDialogueInterpreter().sendDialogue("There is a loud crash from upstairs, followed by the tinkling of", "broken glass."); break; } return true; case "search": if (quest.getStage(player) == 30 && !player.getAttribute("searched-body", false)) { if (!player.getInventory().hasSpaceFor(BONES)) { player.getPacketDispatch().sendMessage("You search the dead body but find nothing."); return true; } if (!player.getInventory().containsItem(BONES) && player.getInventory().add(BONES)) { player.setAttribute("/save:searched-body", true); player.getPacketDispatch().sendMessage("You search the dead body and find two wolf bones."); return true; } else { player.getPacketDispatch().sendMessage("You search the dead body but find nothing."); return true; } } else { player.getPacketDispatch().sendMessage("You search the dead body but find nothing."); } return true; default: return false; } ClimbActionHandler.climb(player, new Animation(828), loc); return true; } /** * Represents the cutscene used during wolf whistle. * @author 'Vexia * @version 1.0 */ public static final class FluffyCutscene extends CutscenePlugin { /** * Constructs a new {@code FluffyCutscene} {@code Object}. */ public FluffyCutscene() { super("fluffy cutscene"); } /** * Constructs a new {@code FluffyCutscene} {@code Object}. * @param player the player. */ public FluffyCutscene(final Player player) { this(); this.player = player; } @Override public ActivityPlugin newInstance(Player p) throws Throwable { return new FluffyCutscene(p); } @Override public void open() { player.getDialogueInterpreter().open(392932, this); player.setAttribute("wolf-dial", player.getDialogueInterpreter().getDialogue()); player.setAttribute("in-cutscene", this); player.lock(); } @Override public void end() { super.end(); player.removeAttribute("in-cutscene"); player.getFamiliarManager().dismiss(); } @Override public Location getSpawnLocation() { return null; } @Override public Location getStartLocation() { return base.transform(46, 50, 1); } @Override public void configure() { region = DynamicRegion.create(11573); setRegionBase(); registerRegion(region.getId()); } @Override public void register() { ClassScanner.definePlugin(new FluffyDialogue()); } /** * Represents the dialogue used during the fluffy cutscene. * @author 'Vexia * @version 1.0 */ public static final class FluffyDialogue extends DialoguePlugin { /** * Represents the scared animation. */ private static final Animation SCARED_ANIMATION = new Animation(2836); /** * Represents the wolpertiner graphic. */ private static final Graphics GRAPHIC = new Graphics(1522); /** * Represents the shudder animation. */ private static final Animation SHUDDER_ANIMATION = new Animation(8506); /** * Represents the death animation. */ private static final Animation DEATH_ANIMATION = new Animation(8507); /** * Represents the cutscene instance. */ private CutscenePlugin cutscene; /** * Represents the quest instance. */ private Quest quest; /** * Represents the fluffy npc. */ private NPC fluffy; /** * Represents the wolf npc. */ private NPC wolf; /** * Constructs a new {@code FluffyDialogue} {@code Object}. */ public FluffyDialogue() { /** * empty. */ } /** * Constructs a new {@code FluffyDialogue} {@code Object}. * @param player the player. */ public FluffyDialogue(final Player player) { super(player); } @Override public DialoguePlugin newInstance(Player player) { return new FluffyDialogue(player); } @Override public boolean open(Object... args) { cutscene = (CutscenePlugin) args[0]; quest = player.getQuestRepository().getQuest("Wolf Whistle"); fluffy = NPC.create(6990, cutscene.getBase().transform(41, 52, 1)); fluffy.init(); fluffy.faceTemporary(player, 1); Location b = cutscene.getBase().transform(42, 50, 0); PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, b.getX(), b.getY(), 244, 1, 100)); PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, b.getX() + 1, b.getY(), 244, 1, 100)); switch (quest.getStage(player)) { case 10: player("Come on then little, fluffy..."); break; case 50: player("Mustn't look round, bunny will eat me.", "Mustn't look round, bunny will eat me.", "Mustn't look round, bunny will eat me."); break; } return true; } @Override public boolean handle(int interfaceId, int buttonId) { switch (quest.getStage(player)) { case 10: switch (stage) { case 0: close(); GameWorld.getPulser().submit(new Pulse(1, player, fluffy) { int counter = 0; @Override public boolean pulse() { switch (++counter) { case 2: player.face(fluffy); break; case 5: player("Gigantic..."); stage = 1; return true; } return false; } }); break; case 1: player("scary-looking..."); stage = 2; break; case 2: player("razor-fanged..."); stage = 3; break; case 3: player("bunny..."); stage = 4; break; case 4: close(); int x = player.getLocation().getX() + 1; int y = player.getLocation().getY() - 1; int height = 300; PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, x, y, height, 1, 100)); PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, x + 1000, y + 13, height, 1, 100)); player.faceLocation(cutscene.getBase().transform(44, 50, 1)); GameWorld.getPulser().submit(new Pulse(1, player, fluffy) { int counter = 0; @Override public boolean pulse() { switch (++counter) { case 3: fluffy.sendChat("Mrooowr?"); break; case 6: player("What is that thing?"); stage = 5; return true; } return false; } }); break; case 5: player("Maybe, if I leave quitely, it won't notice me."); stage = 6; break; case 6: close(); GameWorld.getPulser().submit(new Pulse(1, player, fluffy) { int counter = 0; @Override public boolean pulse() { switch (++counter) { case 2: Pathfinder.find(fluffy, cutscene.getBase().transform(41, 51, 1)).walk(fluffy); break; case 4: fluffy.face(player); fluffy.graphics(GRAPHIC); break; case 5: fluffy.sendChat("Raaaarw!"); break; case 8: int x = player.getLocation().getX() - 4; int y = player.getLocation().getY(); int height = 270; PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, x, y, height, 1, 100)); PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, x + 1, y, height, 1, 100)); interpreter.sendDialogue("A chilling, unnatural fear envelops you!"); stage = 7; return true; } return false; } }); break; case 7: player("It's coming to get me!"); player.animate(SCARED_ANIMATION); player.sendChat("It's coming to get me!"); stage = 8; break; case 8: end(); GameWorld.getPulser().submit(new Pulse(2) { @Override public boolean pulse() { player.animate(Animation.create(827)); return true; } }); cutscene.stop(true); quest.setStage(player, 20); break; } break; case 50:// second cutscene. switch (stage) { case 0: fluffy.faceLocation(cutscene.getBase().transform(40, 53, 1)); player("Okay, I have the spirit wolf pouch, so it can't hurt me..."); stage = 1; break; case 1: player("...I hope."); stage = 2; break; case 2: int x = player.getLocation().getX() + 1; int y = player.getLocation().getY() - 1; int height = 300; PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, x, y, height, 1, 100)); PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, x + 1000, y + 13, height, 1, 100)); player.faceLocation(cutscene.getBase().transform(44, 50, 1)); close(); player("Oh, good. It's too busy gnawing to notice me."); stage = 3; break; case 3: fluffy.faceTemporary(player, 1); fluffy.sendChat("Raaaarw!"); player("I spoke too soon!"); stage = 4; break; case 4: player("I'll use the spirit wolf pouch. I hope this works."); stage = 5; break; case 5: PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.RESET, 0 + 1000, 0 + 13, 0, 1, 100)); PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 0)); player.unlock(); player.getLocks().lockMovement(10000000); player.getInterfaceManager().openTab(new Component(149)); stage = -5; break; case -5: player.setAttribute("in-cutscene", cutscene); close(); stage = 6; break; case 6: Location l = cutscene.getBase().transform(46, 50, 0); x = l.getX() + 1; y = l.getY() - 2; height = 440; player.lock(); player.getLocks().lockMovement(100000); PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, x, y, height, 1, 95)); PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, x + 1000, y + 17, height, 1, 95)); wolf = player.getFamiliarManager().getFamiliar(); GameWorld.getPulser().submit(new Pulse(1, player, fluffy) { int counter; @Override public boolean pulse() { switch (++counter) { case 1: wolf.sendChat("Grrrrrrrrrrrrrrrr..."); break; case 2: fluffy.sendChat("Whiiiiiine!"); break; case 4: player("Get that thing!"); stage = 7; return true; } return false; } }); break; case 7: player.getLocks().lockMovement(1000000); player.lock(); close(); fluffy.animate(SHUDDER_ANIMATION); if (player.getInventory().remove(HOWL_SCROLL)) { player.getDialogueInterpreter().setDialogue(this); player.getDialogueInterpreter().getDialogue().setStage(8); GameWorld.getPulser().submit(new Pulse(1, player, fluffy, wolf) { int counter; @Override public boolean pulse() { switch (++counter) { case 2: wolf.animate(Animation.create(8293)); Projectile.magic(wolf, fluffy, 1333, 40, 36, 50, 5).send(); player.getSkills().updateLevel(Skills.SUMMONING, -2, 0); break; case 5: fluffy.animate(DEATH_ANIMATION); break; case 12: fluffy.clear(); wolf.face(player); player.face(player); player("Well, that certainly seems to have got rid of the giant", "wolpertinger."); stage = 8; player.getDialogueInterpreter().setDialogue(FluffyDialogue.this); player.getDialogueInterpreter().getDialogue().setStage(8); return true; } return false; } }); } break; case 8: player("Come on, let's go tell Pikkupstix."); stage = 9; break; case 9: wolf.clear(); player("They both vanished! I'm sure Pikkupstix will be able to", "explain this to me."); stage = 10; break; case 10: end(); quest.setStage(player, 60); cutscene.stop(true); break; } break; } return true; } @Override public boolean close() { return super.close(); } @Override public void end() { super.end(); if (player.getFamiliarManager().hasFamiliar()) { player.getFamiliarManager().getFamiliar().dismiss(); } } @Override public int[] getIds() { return new int[] { 392932 }; } } } }