Rewrote animal magnetism cutscene in the new cutscene system

Fixes bug where the player could not progress
This commit is contained in:
Ceikry
2022-06-29 12:09:06 +00:00
committed by Ryan
parent bdf4b48388
commit f29d7e37de
4 changed files with 257 additions and 304 deletions
@@ -12,6 +12,7 @@ import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.quest.Quest; import core.game.node.entity.player.link.quest.Quest;
import core.game.node.item.Item; import core.game.node.item.Item;
import core.game.system.task.Pulse; import core.game.system.task.Pulse;
import rs09.game.content.quest.members.anma.AnmaCutscene;
import rs09.game.world.GameWorld; import rs09.game.world.GameWorld;
import core.game.world.map.Location; import core.game.world.map.Location;
import core.game.world.map.build.DynamicRegion; import core.game.world.map.build.DynamicRegion;
@@ -34,11 +35,6 @@ public final class AliceHusbandDialogue extends DialoguePlugin {
*/ */
private Quest quest; private Quest quest;
/**
* The chicken catch scene.
*/
private ChickenCatchScene scene;
/** /**
* Constructs a new {@code AliceHusbandDialogue} {@code Object}. * Constructs a new {@code AliceHusbandDialogue} {@code Object}.
*/ */
@@ -64,7 +60,6 @@ public final class AliceHusbandDialogue extends DialoguePlugin {
@Override @Override
public void init() { public void init() {
super.init(); super.init();
ClassScanner.definePlugin(new ChickenCatchScene());
} }
@Override @Override
@@ -402,186 +397,8 @@ public final class AliceHusbandDialogue extends DialoguePlugin {
stage++; stage++;
break; break;
case 4: case 4:
stage++; end();
close(); new AnmaCutscene(player).start();
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);
break; break;
} }
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 @Override
public int[] getIds() { public int[] getIds() {
return new int[] { 5202 }; return new int[] { 5202 };
+7 -1
View File
@@ -14,6 +14,10 @@ import core.game.world.map.Location
import core.game.world.map.Region import core.game.world.map.Region
import core.game.world.map.RegionManager import core.game.world.map.RegionManager
import core.game.world.map.build.DynamicRegion 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 org.rs09.consts.Components
import rs09.ServerConstants import rs09.ServerConstants
import rs09.game.Event import rs09.game.Event
@@ -94,7 +98,7 @@ abstract class Cutscene(val player: Player) {
fun move(entity: Entity, regionX: Int, regionY: Int) fun move(entity: Entity, regionX: Int, regionY: Int)
{ {
logCutscene("Moving ${entity.username} to LOCAL[$regionX,$regionY].") 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 { override fun pulse(): Boolean {
return true return true
} }
@@ -223,6 +227,7 @@ abstract class Cutscene(val player: Player) {
region = RegionManager.forId(player.location.regionId) region = RegionManager.forId(player.location.regionId)
base = RegionManager.forId(player.location.regionId).baseLocation base = RegionManager.forId(player.location.regionId).baseLocation
setup() setup()
PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 2))
runStage(player.getCutsceneStage()) runStage(player.getCutsceneStage())
setAttribute(player, ATTRIBUTE_CUTSCENE, this) setAttribute(player, ATTRIBUTE_CUTSCENE, this)
setAttribute(player, ATTRIBUTE_CUTSCENE_STAGE, 0) setAttribute(player, ATTRIBUTE_CUTSCENE_STAGE, 0)
@@ -262,6 +267,7 @@ abstract class Cutscene(val player: Player) {
player.unhook(CUTSCENE_DEATH_HOOK) player.unhook(CUTSCENE_DEATH_HOOK)
player.logoutListeners.remove("cutscene") player.logoutListeners.remove("cutscene")
RandomEventManager.getInstance(player)!!.enabled = true RandomEventManager.getInstance(player)!!.enabled = true
PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 0))
return true return true
} }
} }
@@ -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
}
}
@@ -21,9 +21,11 @@ import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.rs09.consts.Components import org.rs09.consts.Components
import rs09.ServerConstants import rs09.ServerConstants
import rs09.game.camerautils.PlayerCamera
import rs09.game.content.activity.fishingtrawler.TrawlerLoot import rs09.game.content.activity.fishingtrawler.TrawlerLoot
import rs09.game.content.ame.RandomEventManager import rs09.game.content.ame.RandomEventManager
import rs09.game.content.ame.RandomEvents import rs09.game.content.ame.RandomEvents
import rs09.game.content.quest.members.anma.AnmaCutscene
import rs09.game.ge.GrandExchange import rs09.game.ge.GrandExchange
import rs09.game.node.entity.state.newsys.states.FarmingState import rs09.game.node.entity.state.newsys.states.FarmingState
import rs09.game.system.SystemLogger 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 * Prints player's current location
*/ */