Rewrote stiles

Added a new ContentAPI function, animationCycles, that returns the exact number of cycles an animation lasts for (useful for forced movement)
Added a new function to Vector objects that allows convertion into Direction objects (useful for transforming locations)
This commit is contained in:
Ceikry
2023-09-04 06:46:10 +00:00
committed by Ryan
parent d4e62c0e96
commit 895c41756a
7 changed files with 177 additions and 109 deletions
@@ -1,108 +0,0 @@
package content.global.skill.agility.shortcuts;
import core.game.activity.ActivityManager;
import core.game.node.entity.impl.PulseType;
import core.plugin.Initializable;
import content.global.skill.agility.AgilityShortcut;
import core.game.interaction.MovementPulse;
import core.game.node.entity.impl.ForceMovement;
import core.game.node.entity.player.Player;
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;
/**
* Handles a stile shortcut.
* @author Vexia
*/
@Initializable
public class StileShortcut extends AgilityShortcut {
/**
* Constructs a new {@Code StileShortcut} {@Code Object}
*/
public StileShortcut() {
super(new int[] { 993, 3730, 7527, 12982, 19222, 22302, 29460, 33842, 34776, 39508, 39509, 39510 }, 1, 0.0, false, 0.0, new String[] { "climb-over" });
}
@Override
public void run(final Player player, final Scenery object, String option, boolean failed) {
player.getWalkingQueue().reset();
Location loc = getLocation(player, object, true);
player.getWalkingQueue().addPath(loc.getX(), loc.getY());
player.getPulseManager().run(new MovementPulse(player, loc) {
@Override
public boolean pulse() {
climb(player, object);
return true;
}
}, PulseType.STANDARD);
}
/**
* Method used to climb the stile.
* @param player the player.
* @param object the object.
*/
public static void climb(final Player player, final Scenery object) {
player.lock(1);
int delay = 0;
GameWorld.getPulser().submit(new Pulse(delay, player) {
@Override
public boolean pulse() {
ForceMovement movement = new ForceMovement(player, getLocation(player, object, true), getLocation(player, object, false), Animation.create(839)) {
@Override
public void stop() {
super.stop();
if (object.getId() == 19222) {// falconry.
handleFalconry(player, object);
}
}
};
movement.run(player, 5);
return true;
}
});
}
/**
* Method used to get the end location.
* @param player the player.
* @param object the object.
* @param start if getting the start loc.
* @return the location.
*/
public static Location getLocation(final Player player, final Scenery object, boolean start) {
if ((object.getDirection() == Direction.NORTH || object.getDirection() == Direction.SOUTH)) {
if (player.getLocation().getY() <= object.getLocation().getY()) {
return start ? object.getLocation() : object.getLocation().transform(0, 1, 0);
} else {
return start ? object.getLocation().transform(0, 1, 0) : object.getLocation();
}
} else {
if (player.getLocation().getX() <= object.getLocation().getX()) {
return start ? object.getLocation() : object.getLocation().transform(1, 0, 0);
} else {
return start ? object.getLocation().transform(1, 0, 0) : object.getLocation();
}
}
}
/**
* Method used to handle the falconry stile.
* @param player the player.
* @param object the object.
*/
private static void handleFalconry(final Player player, Scenery object) {
if (player.getLocation().equals(Location.create(2371, 3621, 0))) {
ActivityManager.start(player, "falconry", false);
} else {
ActivityManager.getActivity("falconry").leave(player, false);
}
}
}
@@ -0,0 +1,78 @@
package content.global.skill.agility.shortcuts
import core.api.*
import core.api.utils.Vector
import core.game.activity.ActivityManager
import core.game.interaction.IntType
import core.game.interaction.InteractionListener
import core.game.interaction.QueueStrength
import core.game.node.entity.player.Player
import core.game.world.map.Direction
import core.game.world.map.Location
class StileShortcut : InteractionListener {
val ids = intArrayOf(993, 3730, 7527, 12982, 19222, 22302, 29460, 33842, 34776, 39508, 39509, 39510)
val FALCONRY_STILE = 19222
override fun defineListeners() {
on (ids, IntType.SCENERY, "climb-over") {p, n ->
val direction = Vector.betweenLocs(p.location, n.location).toDirection()
val startLoc = p.location.transform(direction, 1)
val endLoc = p.location.transform(direction, 2)
p.walkingQueue.reset()
p.walkingQueue.addPath(startLoc.x, startLoc.y)
forceMove(p, startLoc, endLoc, 0, animationCycles(839), direction, 839)
queueScript(p, 5, QueueStrength.SOFT) {_ ->
val end = endLoc.transform(direction, 1)
p.walkingQueue.reset()
p.walkingQueue.addPath(end.x, end.y)
if (n.id == FALCONRY_STILE)
handleFalconry(p, endLoc)
return@queueScript stopExecuting(p)
}
return@on true
}
setDest(IntType.SCENERY, ids, "climb-over") {e, n ->
return@setDest getInteractLocation(e.location, n.location, getOrientation(n.direction))
}
}
companion object {
fun getInteractLocation (pLoc: Location, sLoc: Location, orientation: Orientation) : Location {
when (orientation) {
Orientation.Horizontal -> {
if (pLoc.x <= sLoc.x) return sLoc.transform(-1, 0, 0)
else return sLoc.transform(2, 0, 0)
}
Orientation.Vertical -> {
if (pLoc.y <= sLoc.y) return sLoc.transform(0, -1, 0)
else return sLoc.transform(0, 2, 0)
}
}
}
fun getOrientation (rotation: Direction) : Orientation {
when (rotation) {
Direction.EAST, Direction.WEST -> return Orientation.Horizontal
else -> return Orientation.Vertical
}
}
fun handleFalconry (p: Player, endLoc: Location) {
if (endLoc.y == 3619)
ActivityManager.start(p, "falconry", false)
else
ActivityManager.getActivity("falconry").leave(p, false)
}
}
enum class Orientation {
Horizontal,
Vertical
}
}
+7 -1
View File
@@ -64,6 +64,7 @@ import core.game.world.repository.Repository
import core.game.consumable.*
import core.ServerConstants
import core.api.utils.Vector
import core.cache.def.impl.AnimationDefinition
import core.game.node.entity.player.link.quest.Quest
import core.tools.*
import core.game.world.update.flag.*
@@ -431,7 +432,12 @@ fun resetAnimator(player: Player) {
* @return the number of ticks the given animation lasts for
*/
fun animationDuration(animation: Animation): Int {
return animation.definition.durationTicks
return cyclesToTicks(animation.definition.cycles)
}
fun animationCycles (animation: Int) : Int {
val def = AnimationDefinition.forId(animation)
return def.cycles
}
/**
+16
View File
@@ -1,5 +1,6 @@
package core.api.utils
import core.game.world.map.Direction
import core.game.world.map.Location
import kotlin.math.*
@@ -45,6 +46,21 @@ class Vector (val x: Double, val y: Double) {
return Location.create(floor(x).toInt(), floor(y).toInt(), plane)
}
fun toDirection() : Direction {
val norm = normalized()
if (norm.x >= 0.85) return Direction.EAST
else if (norm.x <= -0.85) return Direction.WEST
if (norm.y > 0) {
if (norm.y >= 0.85) return Direction.NORTH
return if (norm.x > 0) Direction.NORTH_EAST else Direction.NORTH_WEST
} else {
if (norm.y <= -0.85) return Direction.SOUTH
return if (norm.x > 0) Direction.SOUTH_EAST else Direction.SOUTH_WEST
}
}
companion object {
@JvmStatic fun betweenLocs (from: Location, to: Location) : Vector {
val xDiff = to.x - from.x
@@ -88,6 +88,14 @@ public final class AnimationDefinition {
return duration;
}
public int getCycles() {
if (durations == null) return 0;
int duration = 0;
for (int i : durations)
duration += i;
return duration;
}
/**
* Gets the duration of this animation in (600ms) ticks.
* @return The duration in ticks.
+22
View File
@@ -5,6 +5,8 @@ import content.global.skill.slayer.Master
import content.global.skill.slayer.SlayerManager
import content.global.skill.slayer.Tasks
import core.game.node.item.Item
import core.api.utils.Vector
import core.game.world.map.Direction
import org.json.simple.JSONObject
import org.json.simple.parser.JSONParser
import org.junit.jupiter.api.Assertions
@@ -348,4 +350,24 @@ class APITests {
}
}
}
@Test fun vectorToDirectionShouldReturnExpectedDirections() {
val testData = arrayOf(
Pair(Vector(1.0, 0.0), Direction.EAST),
Pair(Vector(-1.0, 0.0), Direction.WEST),
Pair(Vector(0.0, 1.0), Direction.NORTH),
Pair(Vector(0.0, -1.0), Direction.SOUTH),
Pair(Vector(1.0, 1.0), Direction.NORTH_EAST),
Pair(Vector(1.0, -1.0), Direction.SOUTH_EAST),
Pair(Vector(-1.0, 1.0), Direction.NORTH_WEST),
Pair(Vector(-1.0, -1.0), Direction.SOUTH_WEST),
Pair(Vector(15.0, 0.0), Direction.EAST),
Pair(Vector(15.0, 1.0), Direction.EAST),
Pair(Vector(-15.0, -9.7), Direction.SOUTH_WEST)
)
for ((vec, expDir) in testData) {
Assertions.assertEquals(expDir, vec.toDirection(), "Vector: $vec")
}
}
}
@@ -0,0 +1,46 @@
package content.skill.agility
import content.global.skill.agility.shortcuts.StileShortcut
import core.game.world.map.Direction
import core.game.world.map.Location
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
class ShortcutTests {
@Test fun stileGetInteractionLocShouldReturnCorrectLoc() {
data class StileTestData (val playerLoc: Location, val expectedLoc: Location, val stileLoc: Location, val stileOrientation: StileShortcut.Orientation)
val testData = arrayOf(
//Horizontal
StileTestData(Location.create(3044, 3308, 0), Location.create(3045, 3305, 0), Location.create(3043, 3305, 0), StileShortcut.Orientation.Horizontal),
StileTestData(Location.create(3048, 3303, 0), Location.create(3045, 3305, 0), Location.create(3043, 3305, 0), StileShortcut.Orientation.Horizontal),
StileTestData(Location.create(3043, 3307, 0), Location.create(3042, 3305, 0), Location.create(3043, 3305, 0), StileShortcut.Orientation.Horizontal),
StileTestData(Location.create(3039, 3301, 0), Location.create(3042, 3305, 0), Location.create(3043, 3305, 0), StileShortcut.Orientation.Horizontal),
//Vertical
StileTestData(Location.create(3203, 3276, 0), Location.create(3197, 3275, 0), Location.create(3197, 3276, 0), StileShortcut.Orientation.Vertical),
StileTestData(Location.create(3195, 3274, 0), Location.create(3197, 3275, 0), Location.create(3197, 3276, 0), StileShortcut.Orientation.Vertical),
StileTestData(Location.create(3191, 3280, 0), Location.create(3197, 3278, 0), Location.create(3197, 3276, 0), StileShortcut.Orientation.Vertical),
StileTestData(Location.create(3206, 3281, 0), Location.create(3197, 3278, 0), Location.create(3197, 3276, 0), StileShortcut.Orientation.Vertical)
)
for ((pLoc, expLoc, sLoc, ori) in testData) {
Assertions.assertEquals(expLoc, StileShortcut.getInteractLocation(pLoc, sLoc, ori))
}
}
@Test fun stileGetOrientationShouldReturnCorrectOrientation() {
val testData = arrayOf(
Pair (Direction.NORTH, StileShortcut.Orientation.Vertical),
Pair (Direction.SOUTH, StileShortcut.Orientation.Vertical),
Pair (Direction.NORTH_WEST, StileShortcut.Orientation.Vertical),
Pair (Direction.NORTH_EAST, StileShortcut.Orientation.Vertical),
Pair (Direction.SOUTH_EAST, StileShortcut.Orientation.Vertical),
Pair (Direction.SOUTH_WEST, StileShortcut.Orientation.Vertical),
Pair (Direction.EAST, StileShortcut.Orientation.Horizontal),
Pair (Direction.WEST, StileShortcut.Orientation.Horizontal)
)
for ((dir, expOri) in testData) {
Assertions.assertEquals(expOri, StileShortcut.getOrientation(dir))
}
}
}