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:
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -64,6 +64,7 @@ import core.game.world.repository.Repository
|
|||||||
import core.game.consumable.*
|
import core.game.consumable.*
|
||||||
import core.ServerConstants
|
import core.ServerConstants
|
||||||
import core.api.utils.Vector
|
import core.api.utils.Vector
|
||||||
|
import core.cache.def.impl.AnimationDefinition
|
||||||
import core.game.node.entity.player.link.quest.Quest
|
import core.game.node.entity.player.link.quest.Quest
|
||||||
import core.tools.*
|
import core.tools.*
|
||||||
import core.game.world.update.flag.*
|
import core.game.world.update.flag.*
|
||||||
@@ -431,7 +432,12 @@ fun resetAnimator(player: Player) {
|
|||||||
* @return the number of ticks the given animation lasts for
|
* @return the number of ticks the given animation lasts for
|
||||||
*/
|
*/
|
||||||
fun animationDuration(animation: Animation): Int {
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package core.api.utils
|
package core.api.utils
|
||||||
|
|
||||||
|
import core.game.world.map.Direction
|
||||||
import core.game.world.map.Location
|
import core.game.world.map.Location
|
||||||
import kotlin.math.*
|
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)
|
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 {
|
companion object {
|
||||||
@JvmStatic fun betweenLocs (from: Location, to: Location) : Vector {
|
@JvmStatic fun betweenLocs (from: Location, to: Location) : Vector {
|
||||||
val xDiff = to.x - from.x
|
val xDiff = to.x - from.x
|
||||||
|
|||||||
@@ -88,6 +88,14 @@ public final class AnimationDefinition {
|
|||||||
return duration;
|
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.
|
* Gets the duration of this animation in (600ms) ticks.
|
||||||
* @return The duration in ticks.
|
* @return The duration in ticks.
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import content.global.skill.slayer.Master
|
|||||||
import content.global.skill.slayer.SlayerManager
|
import content.global.skill.slayer.SlayerManager
|
||||||
import content.global.skill.slayer.Tasks
|
import content.global.skill.slayer.Tasks
|
||||||
import core.game.node.item.Item
|
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.JSONObject
|
||||||
import org.json.simple.parser.JSONParser
|
import org.json.simple.parser.JSONParser
|
||||||
import org.junit.jupiter.api.Assertions
|
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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user