From f29d7e37de1ff02b6aa1848f4982786a0690be29 Mon Sep 17 00:00:00 2001 From: Ceikry Date: Wed, 29 Jun 2022 12:09:06 +0000 Subject: [PATCH] Rewrote animal magnetism cutscene in the new cutscene system Fixes bug where the player could not progress --- .../animalmagnetism/AliceHusbandDialogue.java | 306 +----------------- Server/src/main/kotlin/Cutscene.kt | 8 +- .../quest/members/anma/AnmaCutscene.kt | 203 ++++++++++++ .../system/command/sets/MiscCommandSet.kt | 44 +++ 4 files changed, 257 insertions(+), 304 deletions(-) create mode 100644 Server/src/main/kotlin/rs09/game/content/quest/members/anma/AnmaCutscene.kt diff --git a/Server/src/main/java/core/game/content/quest/members/animalmagnetism/AliceHusbandDialogue.java b/Server/src/main/java/core/game/content/quest/members/animalmagnetism/AliceHusbandDialogue.java index 5ad67b9bd..1e76b57e0 100644 --- a/Server/src/main/java/core/game/content/quest/members/animalmagnetism/AliceHusbandDialogue.java +++ b/Server/src/main/java/core/game/content/quest/members/animalmagnetism/AliceHusbandDialogue.java @@ -12,6 +12,7 @@ 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.system.task.Pulse; +import rs09.game.content.quest.members.anma.AnmaCutscene; import rs09.game.world.GameWorld; import core.game.world.map.Location; import core.game.world.map.build.DynamicRegion; @@ -34,11 +35,6 @@ public final class AliceHusbandDialogue extends DialoguePlugin { */ private Quest quest; - /** - * The chicken catch scene. - */ - private ChickenCatchScene scene; - /** * Constructs a new {@code AliceHusbandDialogue} {@code Object}. */ @@ -64,7 +60,6 @@ public final class AliceHusbandDialogue extends DialoguePlugin { @Override public void init() { super.init(); - ClassScanner.definePlugin(new ChickenCatchScene()); } @Override @@ -402,186 +397,8 @@ public final class AliceHusbandDialogue extends DialoguePlugin { stage++; break; case 4: - stage++; - close(); - ActivityManager.start(player, ChickenCatchScene.NAME, false, this); - break; - case 5: - close(); - player.face(scene.chicken); - scene.walk(scene.husband, 46, 9); - scene.walk(scene.chicken, 46, 9); - GameWorld.getPulser().submit(new Pulse(1, player) { - int counter; - - @Override - public boolean pulse() { - switch (++counter) { - case 3: - scene.walk(scene.husband, 53, 8); - scene.walk(scene.chicken, 52, 8); - break; - case 11: - scene.walk(scene.chicken, 40, 10); - scene.walk(scene.husband, 40, 10); - break; - case 22: - npc("Git 'ere, yer pesky bird!"); - stage++; - return true; - } - return false; - } - }); - break; - case 6: - stage++; - close(); - scene.husband.getAnimator().forceAnimation(new Animation(5377, Priority.HIGH)); - scene.walk(scene.husband, 51, 8); - scene.walk(scene.chicken, 45, 10); - GameWorld.getPulser().submit(new Pulse(1, player) { - int counter; - - @Override - public boolean pulse() { - switch (++counter) { - case 2: - scene.husband.getAnimator().forceAnimation(new Animation(5377, Priority.HIGH)); - break; - case 5: - scene.husband.getAnimator().forceAnimation(new Animation(5377, Priority.HIGH)); - break; - case 7: - scene.walk(scene.chicken, 47, 7); - break; - case 8: - scene.husband.animate(new Animation(5377, Priority.HIGH)); - break; - case 12: - scene.walk(scene.chicken, 47, 11); - break; - case 17: - npc("Where'd she go?"); - return true; - } - return false; - } - }); - break; - case 7: - close(); - stage++; - scene.allice.init(); - scene.cow.init(); - scene.cowKiller.init(); - scene.walk(scene.allice, 48, 8); - scene.walk(scene.cowKiller, 46, 9); - scene.walk(scene.cow, 46, 10); - scene.walk(scene.husband, 44, 10); - GameWorld.getPulser().submit(new Pulse(1, player) { - int counter; - - @Override - public boolean pulse() { - switch (++counter) { - case 2: - scene.walk(scene.chicken, 45, 9); - break; - case 8: - scene.allice.face(player); - scene.husband.face(player); - npc("Git orf my laaand!"); - return true; - } - return false; - } - }); - break; - case 8: - interpreter.sendDialogues(scene.allice, null, "You heard my husband: leave now!"); - stage++; - break; - case 9: - scene.allice.face(scene.cowKiller); - scene.cowKiller.face(scene.allice); - interpreter.sendDialogues(scene.cowKiller, null, "Always the same; I can never get these animals to", "myself."); - stage = 20; - break; - case 20: - scene.cowKiller.animate(Animation.create(2067)); - scene.cowKiller.faceTemporary(scene.cow, 1); - scene.cow.getImpactHandler().manualHit(scene.cowKiller, scene.cow.getSkills().getLifepoints(), HitsplatType.NORMAL); - interpreter.sendDialogues(scene.allice, null, "You killed Bessie!"); - stage++; - break; - case 21: - interpreter.sendDialogues(scene.cowKiller, null, "Buying cowhides and feathers - ahh, that chicken is", "next, feathers for me!"); - stage++; - break; - case 22: - close(); - stage++; - scene.allice.face(scene.husband); - scene.walk(scene.cowKiller, 46, 10); - GameWorld.getPulser().submit(new Pulse(1, player) { - int count; - - @Override - public boolean pulse() { - switch (++count) { - case 4: - scene.cowKiller.animate(Animation.create(832)); - break; - case 6: - scene.cowKiller.face(scene.chicken); - scene.chicken.sendChat("Woo woo!"); - break; - case 8: - scene.husband.face(scene.cowKiller); - scene.walk(scene.chicken, 45, 10); - break; - case 10: - scene.cowKiller.animate(Animation.create(2067)); - scene.chicken.getImpactHandler().manualHit(player, 0, HitsplatType.MISS); - scene.chicken.face(scene.husband); - break; - case 12: - interpreter.sendDialogues(5209, null, "Woo woo woo!"); - break; - } - return false; - } - - }); - break; - case 23: - close(); - stage++; - GameWorld.getPulser().submit(new Pulse(1, player) { - int counter; - - @Override - public boolean pulse() { - switch (++counter) { - case 1: - scene.husband.animate(Animation.create(5377)); - break; - case 3: - scene.chicken.clear(); - break; - case 6: - player("Well, that's one way to catch a chicken, I suppose."); - return true; - } - return false; - } - }); - break; - case 24: - quest.setStage(player, 20); - close(); - scene.stop(true); + end(); + new AnmaCutscene(player).start(); break; } break; @@ -609,123 +426,6 @@ public final class AliceHusbandDialogue extends DialoguePlugin { } } - /** - * Handles the cutscene used to catch a chicken. - * @author Vexia - */ - public static final class ChickenCatchScene extends CutscenePlugin { - - /** - * The name of the cutscene. - */ - public static final String NAME = "am:chicken"; - - /** - * The npcs used. - */ - public NPC chicken, husband, cowKiller, cow, allice; - - /** - * Constructs a new {@code ChickenCatchScene} {@code Object}. - */ - public ChickenCatchScene() { - super(NAME); - } - - /** - * Constructs a new {@code ChickenCatchScene} {@code Object}. - * @param player the player. - */ - public ChickenCatchScene(Player player) { - super(NAME); - this.player = player; - } - - @Override - public ActivityPlugin newInstance(Player p) throws Throwable { - return new ChickenCatchScene(p); - } - - @Override - public boolean start(final Player player, boolean login, Object... args) { - setNpcs(); - AliceHusbandDialogue dial = (AliceHusbandDialogue) args[0]; - dial.scene = this; - return super.start(player, login, args); - } - - @Override - public void open() { - super.open(); - player.getLocks().lock(); - Location loc = player.getLocation(); - int height = 480, xRot = -6, yRot = -28; - PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, loc.getX() + 2, loc.getY() + 3, height, 1, 100)); - PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, loc.getX() + xRot, loc.getY() + yRot, height, 1, 100)); - player.faceTemporary(chicken, 1); - player.getLocks().lockMovement(GameWorld.getTicks() + 1000000); - player.getDialogueInterpreter().sendDialogues(5202, null, "Here, chicky chicky!"); - } - - @Override - public boolean leave(final Entity e, boolean logout) { - chicken.clear(); - husband.clear(); - cowKiller.clear(); - allice.clear(); - cow.clear(); - return super.leave(e, logout); - } - - /** - * Sets the npc instances. - */ - private void setNpcs() { - chicken = NPC.create(1692, base.transform(44, 10, 0)); - husband = NPC.create(5205, base.transform(42, 10, 0)); - cow = NPC.create(5211, base.transform(42, 10, 0)); - cowKiller = NPC.create(5210, base.transform(51, 8, 0)); - allice = NPC.create(5212, base.transform(47, 5, 0)); - allice.setWalks(false); - cow.setWalks(false); - cowKiller.setWalks(false); - chicken.setWalks(false); - husband.setWalks(false); - husband.init(); - chicken.init(); - chicken.faceLocation(husband.getLocation()); - walk(husband, chicken.getLocation().getX() - 1, chicken.getLocation().getY()); - } - - /** - * Walks an npc. - * @param npc the npc. - */ - public void walk(NPC npc, int x, int y) { - Location loc = base.transform(x, y, 0); - npc.getWalkingQueue().reset(); - Pathfinder.find(npc, loc).walk(npc); - } - - @Override - public Location getStartLocation() { - return base.transform(46, 13, 0); - } - - @Override - public Location getSpawnLocation() { - return null; - } - - @Override - public void configure() { - region = DynamicRegion.create(14391); - setRegionBase(); - registerRegion(region.getId()); - } - - } - @Override public int[] getIds() { return new int[] { 5202 }; diff --git a/Server/src/main/kotlin/Cutscene.kt b/Server/src/main/kotlin/Cutscene.kt index c3364f2cc..55d38a9d6 100644 --- a/Server/src/main/kotlin/Cutscene.kt +++ b/Server/src/main/kotlin/Cutscene.kt @@ -14,6 +14,10 @@ import core.game.world.map.Location import core.game.world.map.Region import core.game.world.map.RegionManager import core.game.world.map.build.DynamicRegion +import core.game.world.map.path.Pathfinder +import core.net.packet.PacketRepository +import core.net.packet.context.MinimapStateContext +import core.net.packet.out.MinimapState import org.rs09.consts.Components import rs09.ServerConstants import rs09.game.Event @@ -94,7 +98,7 @@ abstract class Cutscene(val player: Player) { fun move(entity: Entity, regionX: Int, regionY: Int) { logCutscene("Moving ${entity.username} to LOCAL[$regionX,$regionY].") - entity.pulseManager.run(object : MovementPulse(entity, base.transform(regionX,regionY,0)) { + entity.pulseManager.run(object : MovementPulse(entity, base.transform(regionX,regionY,0), Pathfinder.SMART) { override fun pulse(): Boolean { return true } @@ -223,6 +227,7 @@ abstract class Cutscene(val player: Player) { region = RegionManager.forId(player.location.regionId) base = RegionManager.forId(player.location.regionId).baseLocation setup() + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 2)) runStage(player.getCutsceneStage()) setAttribute(player, ATTRIBUTE_CUTSCENE, this) setAttribute(player, ATTRIBUTE_CUTSCENE_STAGE, 0) @@ -262,6 +267,7 @@ abstract class Cutscene(val player: Player) { player.unhook(CUTSCENE_DEATH_HOOK) player.logoutListeners.remove("cutscene") RandomEventManager.getInstance(player)!!.enabled = true + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 0)) return true } } diff --git a/Server/src/main/kotlin/rs09/game/content/quest/members/anma/AnmaCutscene.kt b/Server/src/main/kotlin/rs09/game/content/quest/members/anma/AnmaCutscene.kt new file mode 100644 index 000000000..9983a9014 --- /dev/null +++ b/Server/src/main/kotlin/rs09/game/content/quest/members/anma/AnmaCutscene.kt @@ -0,0 +1,203 @@ +package rs09.game.content.quest.members.anma + +import Cutscene +import api.* +import core.game.content.dialogue.FacialExpression +import core.game.node.entity.combat.ImpactHandler +import core.game.node.entity.player.Player +import core.game.world.map.Direction +import org.rs09.consts.Animations +import org.rs09.consts.NPCs + +class AnmaCutscene(player: Player) : Cutscene(player) { + override fun setup() { + setExit(player.location.transform(0,0,0)) //create copy of player's location + loadRegion(14391) + addNPC(FARMER, 36, 9, Direction.EAST, 0) + addNPC(CHICKEN, 44, 10, Direction.WEST, 0) + addNPC(ALICE, 43, 5, Direction.WEST) + addNPC(COWKILLER, 52, 8, Direction.WEST) + addNPC(COW, 37, 8, Direction.WEST) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + fadeToBlack() + timedUpdate(5) + } + 1 -> { + teleport(player, 46, 13) + face(player, getNPC(CHICKEN)!!.location) + face(getNPC(FARMER)!!, getNPC(CHICKEN)!!) + move(getNPC(FARMER)!!, 43, 10) + timedUpdate(5) + } + 2 -> { + fadeFromBlack() + moveCamera(48,16, 500) + rotateCamera(44, 0) + dialogueUpdate(FARMER, FacialExpression.NEUTRAL, "Here, chicky chicky!") + } + 3 -> { + move(getNPC(FARMER)!!, 44, 10) + animate(getNPC(FARMER)!!, ATTEMPT_CATCH) + move(getNPC(CHICKEN)!!, 45, 9) + timedUpdate(2) + } + 4 -> { + move(getNPC(FARMER)!!, 53, 8) + move(getNPC(CHICKEN)!!, 53, 8) + timedUpdate(10) + } + 5 -> { + move(getNPC(CHICKEN)!!, 47, 8) + timedUpdate(1) + } + 6 -> { + move(getNPC(FARMER)!!, 48, 8) + timedUpdate(8) + } + 7 -> { + move(getNPC(CHICKEN)!!, 45, 10) + animate(getNPC(FARMER)!!, ATTEMPT_CATCH) + timedUpdate(1) + } + 8 -> { + move(getNPC(FARMER)!!, 45, 10) + move(getNPC(CHICKEN)!!, 38, 10) + animate(getNPC(CHICKEN)!!, CHICKEN_JUMP) + timedUpdate(1) + } + 9 -> { + move(getNPC(FARMER)!!, 38, 10) + timedUpdate(9) + } + 10 -> { + face(player, getNPC(FARMER)!!.location) + dialogueUpdate(FARMER, FacialExpression.NEUTRAL, "Git 'ere yer pesky bird!") + } + 11 -> { + move(getNPC(FARMER)!!, 44, 10) + move(getNPC(CHICKEN)!!, 45, 10) + timedUpdate(8) + } + 12 -> { + animate(getNPC(FARMER)!!, ATTEMPT_CATCH) + animate(getNPC(CHICKEN)!!, CHICKEN_JUMP) + face(player, getNPC(CHICKEN)!!.location) + move(getNPC(CHICKEN)!!, 47, 7) + timedUpdate(3) + } + 13 -> { + move(getNPC(FARMER)!!, 52, 8) + timedUpdate(6) + } + 14 -> { + face(getNPC(CHICKEN)!!, getNPC(CHICKEN)!!.location.transform(0, 1, 0)) + timedUpdate(6) + } + 15 -> { + move(getNPC(CHICKEN)!!, 47, 11) + face(getNPC(COW)!!, getNPC(COW)!!.location.transform(Direction.EAST)) + timedUpdate(8) + } + 16 -> { + face(getNPC(CHICKEN)!!, getNPC(FARMER)!!.location) + teleport(getNPC(COW)!!, 41, 10) + dialogueUpdate(FARMER, FacialExpression.NEUTRAL, "Where'd she go?") + } + 17 -> { + setAttribute(getNPC(COWKILLER)!!, "1hko", true) + move(getNPC(COWKILLER)!!, 46, 9) + move(getNPC(COW)!!, 46, 10) + move(getNPC(FARMER)!!, 44, 10) + move(getNPC(ALICE)!!, 48, 8) + timedUpdate(11) + } + 18 -> { + face(getNPC(FARMER)!!, player.location) + face(player, getNPC(FARMER)!!.location) + move(getNPC(CHICKEN)!!, 45, 9) + dialogueUpdate(FARMER, FacialExpression.ANNOYED, "Git oof my laaaaaand!") + } + 19 -> { + face(getNPC(FARMER)!!, getNPC(ALICE)!!.location) + face(getNPC(ALICE)!!, getNPC(COWKILLER)!!.location) + dialogueUpdate(ALICE, FacialExpression.ANNOYED, "You heard my husband: leave now!") + } + 20 -> { + face(getNPC(ALICE)!!, getNPC(COWKILLER)!!.location) + face(getNPC(COWKILLER)!!, getNPC(ALICE)!!.location) + dialogueUpdate(COWKILLER, FacialExpression.HALF_THINKING, "Always the same, I can never get these animals to myself.") + } + 21 -> { + face(getNPC(COWKILLER)!!, getNPC(COW)!!.location) + animate(getNPC(COWKILLER)!!, ATTACK_ANIM) + impact(getNPC(COW)!!, 8, ImpactHandler.HitsplatType.NORMAL) + timedUpdate(3) + } + 22 -> { + dialogueUpdate(ALICE, FacialExpression.SAD, "You killed Bessie!") + } + 23 -> { + dialogueUpdate(COWKILLER, FacialExpression.FRIENDLY, "Buying cowhides and feathers - ahh, that chicken is next, feathers for me!") + } + 24 -> { + move(getNPC(COWKILLER)!!, 46, 10) + timedUpdate(3) + } + 25 -> { + animate(getNPC(COWKILLER)!!, Animations.HUMAN_BURYING_BONES_827) + timedUpdate(1) + } + 26 -> { + face(getNPC(COWKILLER)!!, getNPC(COWKILLER)!!.location.transform(-1,0,0)) + timedUpdate(2) + } + 27 -> { + face(getNPC(CHICKEN)!!, getNPC(CHICKEN)!!.location.transform(0,1,0)) + sendChat(getNPC(CHICKEN)!!, "Woo woo!") + timedUpdate(2) + } + 28 -> { + move(getNPC(CHICKEN)!!, 45, 10) + timedUpdate(2) + } + 29 -> { + animate(getNPC(COWKILLER)!!, ATTACK_ANIM) + animate(getNPC(CHICKEN)!!, CHICKEN_JUMP) + impact(getNPC(CHICKEN)!!, 0, ImpactHandler.HitsplatType.MISS) + timedUpdate(2) + } + 30 -> { + face(getNPC(CHICKEN)!!, getNPC(FARMER)!!) + face(getNPC(FARMER)!!, getNPC(CHICKEN)!!) + visualize(getNPC(FARMER)!!, GRAB_CHICKEN_ANIM, GRAB_CHICKEN_GFX) + timedUpdate(6) + } + 31 -> { + getNPC(CHICKEN)!!.clear() + playerDialogueUpdate(FacialExpression.FRIENDLY, "Well, that's one way to catch a chicken, I suppose.") + } + 32 -> { + end { + setQuestStage(player, "Animal Magnetism", 20) + } + } + } + } + + companion object { + val FARMER = NPCs.ALICES_HUSBAND_5205 + val ALICE = NPCs.ALICE_5212 + val CHICKEN = NPCs.UNDEAD_CHICKEN_1692 + val COWKILLER = NPCs.COW1337KILLR_5210 + val COW = NPCs.UNDEAD_COW_5211 + val ATTEMPT_CATCH = 5377 + val ATTACK_ANIM = 2066 + val GRAB_CHICKEN_ANIM = 5376 + val GRAB_CHICKEN_GFX = 973 + val CHICKEN_JUMP = 5380 + } +} \ No newline at end of file diff --git a/Server/src/main/kotlin/rs09/game/system/command/sets/MiscCommandSet.kt b/Server/src/main/kotlin/rs09/game/system/command/sets/MiscCommandSet.kt index f298c4bed..22ed85969 100644 --- a/Server/src/main/kotlin/rs09/game/system/command/sets/MiscCommandSet.kt +++ b/Server/src/main/kotlin/rs09/game/system/command/sets/MiscCommandSet.kt @@ -21,9 +21,11 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import org.rs09.consts.Components import rs09.ServerConstants +import rs09.game.camerautils.PlayerCamera import rs09.game.content.activity.fishingtrawler.TrawlerLoot import rs09.game.content.ame.RandomEventManager import rs09.game.content.ame.RandomEvents +import rs09.game.content.quest.members.anma.AnmaCutscene import rs09.game.ge.GrandExchange import rs09.game.node.entity.state.newsys.states.FarmingState import rs09.game.system.SystemLogger @@ -62,6 +64,48 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){ } } + define("movcam", Privilege.ADMIN) {player, args -> + val regionX = args[1].toIntOrNull() ?: return@define + val regionY = args[2].toIntOrNull() ?: return@define + var height = 300 + var speed = 100 + + if (args.size > 3) + height = args[3].toIntOrNull() ?: return@define + + if (args.size > 4) + speed = args[4].toIntOrNull() ?: return@define + + val region = RegionManager.forId(player.location.regionId) + val base = region.baseLocation + + val globalLoc = base.transform(regionX, regionY, 0) + PlayerCamera(player).panTo(globalLoc.x, globalLoc.y, height, speed) + } + + define("rotcam", Privilege.ADMIN) {player, args -> + val regionX = args[1].toIntOrNull() ?: return@define + val regionY = args[2].toIntOrNull() ?: return@define + var height = 300 + var speed = 100 + + if (args.size > 3) + height = args[3].toIntOrNull() ?: return@define + + if (args.size > 4) + speed = args[4].toIntOrNull() ?: return@define + + val region = RegionManager.forId(player.location.regionId) + val base = region.baseLocation + + val globalLoc = base.transform(regionX, regionY, 0) + PlayerCamera(player).rotateTo(globalLoc.x, globalLoc.y, height, speed) + } + + define("anmacs", Privilege.ADMIN) { player, _ -> + AnmaCutscene(player).start() + } + /** * Prints player's current location */