mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2025-12-09 16:45:44 -07:00
Rewrote grappling, fixes Yanille south shortcut, Catherby skill check and requirements text getting cut off
This commit is contained in:
parent
24b314426e
commit
50eb295fda
15 changed files with 788 additions and 651 deletions
|
|
@ -1,114 +0,0 @@
|
|||
package content.global.skill.agility.shortcuts
|
||||
|
||||
import core.api.*
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.system.task.Pulse
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.Scenery
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
|
||||
/**
|
||||
* Handles the Catherby to Taverley grapple shortcut
|
||||
* @author Byte
|
||||
*/
|
||||
class CatherbyGrappleShortcut : InteractionListener {
|
||||
|
||||
companion object {
|
||||
private val START_LOCATION: Location = Location.create(2866, 3429, 0)
|
||||
private val END_LOCATION: Location = Location.create(2869,3430,0)
|
||||
|
||||
private val REQUIREMENTS = hashMapOf(
|
||||
Skills.AGILITY to 32,
|
||||
Skills.RANGE to 35,
|
||||
Skills.STRENGTH to 35
|
||||
)
|
||||
|
||||
private val VALID_CROSSBOWS = intArrayOf(
|
||||
Items.MITH_CROSSBOW_9181,
|
||||
Items.ADAMANT_CROSSBOW_9183,
|
||||
Items.RUNE_CROSSBOW_9185,
|
||||
Items.DORGESHUUN_CBOW_8880
|
||||
)
|
||||
}
|
||||
|
||||
private var rocks = getScenery(Location.create(2869,3429, 0))
|
||||
|
||||
override fun defineListeners() {
|
||||
flagInstant() // execute listeners instantly without determining path
|
||||
|
||||
on(Scenery.ROCKS_17042, IntType.SCENERY, "grapple") { player, _ ->
|
||||
if (isPlayerInRangeToGrapple(player)) {
|
||||
forceWalk(player, START_LOCATION, "smart")
|
||||
} else {
|
||||
sendMessage(player, "Nothing interesting happens.")
|
||||
return@on true
|
||||
}
|
||||
|
||||
if (!doesPlayerHaveRequiredItemsEquipped(player)) {
|
||||
sendDialogue(player, "You need a Mithril crossbow and a Mithril grapple in order to do this.")
|
||||
return@on true
|
||||
}
|
||||
|
||||
if (!doesPlayerHaveRequiredLevels(player)) {
|
||||
sendDialogueLines(player,
|
||||
"You need at least " +
|
||||
REQUIREMENTS[Skills.AGILITY] + " " + Skills.SKILL_NAME[Skills.AGILITY] + ", " +
|
||||
REQUIREMENTS[Skills.RANGE] + " " + Skills.SKILL_NAME[Skills.RANGE] + ", ",
|
||||
"and " +
|
||||
REQUIREMENTS[Skills.STRENGTH] + " " + Skills.SKILL_NAME[Skills.STRENGTH] + " to use this shortcut."
|
||||
)
|
||||
return@on true
|
||||
}
|
||||
|
||||
lock(player, 15)
|
||||
submitWorldPulse(object : Pulse(2) {
|
||||
var counter = 0
|
||||
override fun pulse() : Boolean {
|
||||
when (counter++) {
|
||||
1 -> {
|
||||
face(player, END_LOCATION)
|
||||
// Audit: shows player climbing (probably a wall), need a cliff climb animation
|
||||
animate(player, Animation(4455))
|
||||
}
|
||||
3 -> {
|
||||
// Audit: shows grapple on rocks, but there is no rope
|
||||
replaceScenery(rocks!!, rocks!!.id + 1, 10)
|
||||
}
|
||||
8 -> {
|
||||
teleport(player, END_LOCATION)
|
||||
}
|
||||
9 -> {
|
||||
sendMessage(player, "You successfully grapple the rock and climb the cliffside.")
|
||||
unlock(player)
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
|
||||
private fun doesPlayerHaveRequiredItemsEquipped(player: Player): Boolean {
|
||||
return inEquipment(player, Items.MITH_GRAPPLE_9419) && anyInEquipment(player, *VALID_CROSSBOWS)
|
||||
}
|
||||
|
||||
private fun doesPlayerHaveRequiredLevels(player: Player): Boolean {
|
||||
for ((skill, requiredLevel) in REQUIREMENTS) {
|
||||
if (!hasLevelDyn(player, skill, requiredLevel)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun isPlayerInRangeToGrapple(player: Player): Boolean {
|
||||
return inBorders(player, START_LOCATION.x - 2, START_LOCATION.y - 2, START_LOCATION.x, START_LOCATION.y)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,145 +0,0 @@
|
|||
package content.global.skill.agility.shortcuts;
|
||||
|
||||
import core.cache.def.impl.SceneryDefinition;
|
||||
import core.game.component.Component;
|
||||
import org.rs09.consts.Items;
|
||||
import core.game.interaction.OptionHandler;
|
||||
import core.game.node.Node;
|
||||
import core.game.node.entity.impl.ForceMovement;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.entity.player.link.diary.DiaryType;
|
||||
import core.game.node.item.Item;
|
||||
import core.game.system.task.Pulse;
|
||||
import core.game.world.GameWorld;
|
||||
import core.game.world.map.Location;
|
||||
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.MinimapStateContext;
|
||||
import core.net.packet.out.MinimapState;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
import core.game.node.entity.skill.Skills;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Represents the plugin used to handle the grappling of the falador wall.
|
||||
*
|
||||
* @author 'Vexia
|
||||
* @version 1.0
|
||||
*/
|
||||
@Initializable
|
||||
public final class FaladorGrapplePlugin extends OptionHandler {
|
||||
private static final HashMap<Integer, Integer> REQUIREMENTS = new HashMap<>();
|
||||
private static String requirementsString;
|
||||
|
||||
static {
|
||||
REQUIREMENTS.putIfAbsent(Skills.AGILITY, 11);
|
||||
REQUIREMENTS.putIfAbsent(Skills.RANGE, 19);
|
||||
REQUIREMENTS.putIfAbsent(Skills.STRENGTH, 37);
|
||||
|
||||
requirementsString = "You need at least "
|
||||
+ REQUIREMENTS.get(Skills.AGILITY) + " " + Skills.SKILL_NAME[Skills.AGILITY] + ", "
|
||||
+ REQUIREMENTS.get(Skills.RANGE) + " " + Skills.SKILL_NAME[Skills.RANGE] + ", and "
|
||||
+ REQUIREMENTS.get(Skills.STRENGTH) + " " + Skills.SKILL_NAME[Skills.STRENGTH]
|
||||
+ " to use this shortcut.";
|
||||
}
|
||||
|
||||
private static final int[] CBOWS = new int[]{
|
||||
Items.MITH_CROSSBOW_9181,
|
||||
Items.ADAMANT_CROSSBOW_9183,
|
||||
Items.RUNE_CROSSBOW_9185,
|
||||
Items.DORGESHUUN_CBOW_8880
|
||||
};
|
||||
private static final Item MITH_GRAPPLE = new Item(9419);
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
SceneryDefinition.forId(17049).getHandlers().put("option:grapple", this);
|
||||
SceneryDefinition.forId(17050).getHandlers().put("option:grapple", this);
|
||||
SceneryDefinition.forId(17051).getHandlers().put("option:jump", this);
|
||||
SceneryDefinition.forId(17052).getHandlers().put("option:jump", this);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(final Player player, final Node node, String option) {
|
||||
Location destination;
|
||||
Location current = player.getLocation();
|
||||
|
||||
switch (option) {
|
||||
case "jump":
|
||||
ForceMovement.run(player,
|
||||
current,
|
||||
node.asScenery().getId() == 17051
|
||||
? Location.create(3033, 3390, 0)
|
||||
: Location.create(3032, 3388, 0),
|
||||
new Animation(7268),
|
||||
10);
|
||||
break;
|
||||
case "grapple":
|
||||
destination = node.asScenery().getId() == 17049
|
||||
? Location.create(3033, 3389, 1)
|
||||
: Location.create(3032, 3391, 1);
|
||||
|
||||
for (Map.Entry<Integer, Integer> e : REQUIREMENTS.entrySet()) {
|
||||
if (player.getSkills().getLevel(e.getKey()) < e.getValue()) {
|
||||
player.getDialogueInterpreter().sendDialogue(requirementsString);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!player.getEquipment().containsAtLeastOneItem(CBOWS) || !player.getEquipment().containsItem(MITH_GRAPPLE)) {
|
||||
player.getDialogueInterpreter().sendDialogue("You need a Mithril crossbow and a Mithril grapple in order to do this.");
|
||||
return true;
|
||||
}
|
||||
|
||||
player.lock();
|
||||
GameWorld.getPulser().submit(new Pulse(1, player) {
|
||||
int counter = 1;
|
||||
Component tab;
|
||||
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
switch (counter++) {
|
||||
case 1:
|
||||
player.faceLocation(destination);
|
||||
player.visualize(new Animation(4455), new Graphics(760, 100));
|
||||
break;
|
||||
case 8:
|
||||
tab = player.getInterfaceManager().getSingleTab();
|
||||
player.getInterfaceManager().openOverlay(new Component(115));
|
||||
PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 2));
|
||||
player.getInterfaceManager().removeTabs(0, 1, 2, 3, 4, 5, 6, 11, 12);
|
||||
break;
|
||||
case 13:
|
||||
player.getProperties().setTeleportLocation(destination);
|
||||
break;
|
||||
case 14:
|
||||
player.getInterfaceManager().restoreTabs();
|
||||
if (tab != null) {
|
||||
player.getInterfaceManager().openTab(tab);
|
||||
}
|
||||
PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 0));
|
||||
player.getInterfaceManager().closeOverlay();
|
||||
player.getInterfaceManager().close();
|
||||
player.unlock();
|
||||
player.getAchievementDiaryManager().finishTask(player, DiaryType.FALADOR, 1, 2);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getDestination(final Node moving, final Node destination) {
|
||||
return destination.asScenery().getId() == 17050 ? Location.create(3032, 3388, 0) : null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,145 +0,0 @@
|
|||
package content.global.skill.agility.shortcuts;
|
||||
|
||||
import core.cache.def.impl.SceneryDefinition;
|
||||
import core.game.component.Component;
|
||||
import org.rs09.consts.Items;
|
||||
import core.game.interaction.OptionHandler;
|
||||
import core.game.node.Node;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.entity.player.link.diary.DiaryType;
|
||||
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.Direction;
|
||||
import core.game.world.map.Location;
|
||||
import core.game.world.map.RegionManager;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
import core.game.node.entity.skill.Skills;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Initializable
|
||||
public class KaramjaGrapple extends OptionHandler {
|
||||
private static final HashMap<Integer, Integer> REQUIREMENTS = new HashMap<>();
|
||||
private static final String requirementsString;
|
||||
|
||||
static {
|
||||
REQUIREMENTS.putIfAbsent(Skills.AGILITY, 53);
|
||||
REQUIREMENTS.putIfAbsent(Skills.RANGE, 42);
|
||||
REQUIREMENTS.putIfAbsent(Skills.STRENGTH, 21);
|
||||
|
||||
requirementsString = "You need at least "
|
||||
+ REQUIREMENTS.get(Skills.AGILITY) + " " + Skills.SKILL_NAME[Skills.AGILITY] + ", "
|
||||
+ REQUIREMENTS.get(Skills.RANGE) + " " + Skills.SKILL_NAME[Skills.RANGE] + ", and "
|
||||
+ REQUIREMENTS.get(Skills.STRENGTH) + " " + Skills.SKILL_NAME[Skills.STRENGTH]
|
||||
+ " to use this shortcut.";
|
||||
}
|
||||
|
||||
private static final int[] CBOWS = new int[]{
|
||||
Items.MITH_CROSSBOW_9181,
|
||||
Items.ADAMANT_CROSSBOW_9183,
|
||||
Items.RUNE_CROSSBOW_9185,
|
||||
Items.DORGESHUUN_CBOW_8880
|
||||
};
|
||||
private static final Item MITH_GRAPPLE = new Item(9419);
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
SceneryDefinition.forId(17074).getHandlers().put("option:grapple", this);
|
||||
// island tree 17074 +1 rope loop, +2 grappled one way, +3 grappled other way
|
||||
// north tree 17056 +1 rope loop, +2 grappled
|
||||
// south tree 17059 +1 rope loop, +2 grappled
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(Player player, Node node, String option) {
|
||||
Location destination;
|
||||
Location current = player.getLocation();
|
||||
Scenery startTree, endTree;
|
||||
Direction direction;
|
||||
if (current.getY() > 3134) { // starting at north side
|
||||
startTree = RegionManager.getObject(Location.create(2874, 3144, 0));
|
||||
endTree = RegionManager.getObject(Location.create(2873, 3125, 0));
|
||||
destination = Location.create(2874, 3127, 0);
|
||||
direction = Direction.SOUTH;
|
||||
} else {
|
||||
startTree = RegionManager.getObject(Location.create(2873, 3125, 0));
|
||||
endTree = RegionManager.getObject(Location.create(2874, 3144, 0));
|
||||
destination = Location.create(2874, 3142, 0);
|
||||
direction = Direction.NORTH;
|
||||
}
|
||||
Scenery islandTree = RegionManager.getObject(Location.create(2873, 3134, 0));
|
||||
|
||||
|
||||
switch (option) {
|
||||
case "grapple":
|
||||
|
||||
for (Map.Entry<Integer, Integer> e : REQUIREMENTS.entrySet()) {
|
||||
if (player.getSkills().getLevel(e.getKey()) < e.getValue()) {
|
||||
player.getDialogueInterpreter().sendDialogue(requirementsString);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!player.getEquipment().containsAtLeastOneItem(CBOWS) || !player.getEquipment().containsItem(MITH_GRAPPLE)) {
|
||||
player.getDialogueInterpreter().sendDialogue("You need a Mithril crossbow and a Mithril grapple in order to do this.");
|
||||
return true;
|
||||
}
|
||||
|
||||
player.lock();
|
||||
GameWorld.getPulser().submit(new Pulse(1, player) {
|
||||
int counter = 1;
|
||||
Component tab;
|
||||
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
switch (counter++) {
|
||||
// TODO animations not implemented.
|
||||
// See ~11min in https://www.youtube.com/watch?v=qpB53rzYqrA
|
||||
// don't know how to get ropes to show up. The tree objects have grapples and stuff but don't look like the video and aren't the right directions
|
||||
// splash gfx are 68 and 69, not sure why there are two
|
||||
// not sure what swimming animation is, could be 4464 thru 4468
|
||||
case 1:
|
||||
player.faceLocation(player.getLocation().transform(direction));
|
||||
player.animate(new Animation(4230));
|
||||
break;
|
||||
case 3:
|
||||
//player.getPacketDispatch().sendPositionedGraphic(67, 10, 0, player.getLocation().transform(direction, 5)); //
|
||||
break;
|
||||
case 4:
|
||||
//ObjectBuilder.replace(startTree, startTree.transform(startTree.getId() + 1), 10);
|
||||
//ObjectBuilder.replace(islandTree, islandTree.transform(islandTree.getId() + 1), 10);
|
||||
break;
|
||||
case 5:
|
||||
break;
|
||||
case 13:
|
||||
player.getProperties().setTeleportLocation(destination);
|
||||
break;
|
||||
case 14:
|
||||
player.unlock();
|
||||
player.getAchievementDiaryManager().finishTask(player, DiaryType.KARAMJA, 2, 6);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getDestination(final Node moving, final Node destination) {
|
||||
// Run between tree and water before firing grapple
|
||||
if (moving.getLocation().getY() > 3134) { // starting at north side
|
||||
return Location.create(2874, 3142, 0);
|
||||
} else {
|
||||
return Location.create(2874, 3127, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,126 +0,0 @@
|
|||
package content.global.skill.agility.shortcuts;
|
||||
|
||||
import core.cache.def.impl.SceneryDefinition;
|
||||
import core.game.component.Component;
|
||||
import org.rs09.consts.Items;
|
||||
import core.game.interaction.OptionHandler;
|
||||
import core.game.node.Node;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.entity.player.link.diary.DiaryType;
|
||||
import core.game.node.item.Item;
|
||||
import core.game.node.scenery.Scenery;
|
||||
import core.game.node.scenery.SceneryBuilder;
|
||||
import core.game.system.task.Pulse;
|
||||
import core.game.world.GameWorld;
|
||||
import core.game.world.map.Location;
|
||||
import core.game.world.map.RegionManager;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
import core.game.node.entity.skill.Skills;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Initializable
|
||||
public class WaterOrbGrapple extends OptionHandler {
|
||||
private static final HashMap<Integer, Integer> REQUIREMENTS = new HashMap<>();
|
||||
private static final String requirementsString;
|
||||
|
||||
static {
|
||||
REQUIREMENTS.putIfAbsent(Skills.AGILITY, 36);
|
||||
REQUIREMENTS.putIfAbsent(Skills.RANGE, 39);
|
||||
REQUIREMENTS.putIfAbsent(Skills.STRENGTH, 22);
|
||||
|
||||
requirementsString = "You need at least "
|
||||
+ REQUIREMENTS.get(Skills.AGILITY) + " " + Skills.SKILL_NAME[Skills.AGILITY] + ", "
|
||||
+ REQUIREMENTS.get(Skills.RANGE) + " " + Skills.SKILL_NAME[Skills.RANGE] + ", and "
|
||||
+ REQUIREMENTS.get(Skills.STRENGTH) + " " + Skills.SKILL_NAME[Skills.STRENGTH]
|
||||
+ " to use this shortcut.";
|
||||
}
|
||||
|
||||
private static final int[] CBOWS = new int[]{
|
||||
Items.MITH_CROSSBOW_9181,
|
||||
Items.ADAMANT_CROSSBOW_9183,
|
||||
Items.RUNE_CROSSBOW_9185,
|
||||
Items.DORGESHUUN_CBOW_8880
|
||||
};
|
||||
private static final Item MITH_GRAPPLE = new Item(9419);
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
SceneryDefinition.forId(17062).getHandlers().put("option:grapple", this);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(Player player, Node node, String option) {
|
||||
Location destination;
|
||||
Location current = player.getLocation();
|
||||
Scenery rock = RegionManager.getObject(Location.create(2841, 3426, 0));
|
||||
Scenery tree = RegionManager.getObject(Location.create(2841, 3434, 0));
|
||||
|
||||
switch (option) {
|
||||
case "grapple":
|
||||
destination = Location.create(2841, 3433, 0);
|
||||
|
||||
for (Map.Entry<Integer, Integer> e : REQUIREMENTS.entrySet()) {
|
||||
if (player.getSkills().getLevel(e.getKey()) < e.getValue()) {
|
||||
player.getDialogueInterpreter().sendDialogue(requirementsString);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!player.getEquipment().containsAtLeastOneItem(CBOWS) || !player.getEquipment().containsItem(MITH_GRAPPLE)) {
|
||||
player.getDialogueInterpreter().sendDialogue("You need a Mithril crossbow and a Mithril grapple in order to do this.");
|
||||
return true;
|
||||
}
|
||||
|
||||
player.lock();
|
||||
GameWorld.getPulser().submit(new Pulse(1, player) {
|
||||
int counter = 1;
|
||||
Component tab;
|
||||
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
switch (counter++) {
|
||||
// TODO this animation sequence is wrong. sendPositionedGraphic doesn't work correctly, and rest of water crossing not well implemented
|
||||
// See 4:24 in https://www.youtube.com/watch?v=O90y-N_vwTc
|
||||
// rope gfx is 67
|
||||
// splash gfx are 68 and 69, not sure why there are two
|
||||
// not sure what swimming animation is, could be 4464 thru 4468
|
||||
case 1:
|
||||
player.faceLocation(destination);
|
||||
player.animate(new Animation(4230));
|
||||
break;
|
||||
case 3:
|
||||
player.getPacketDispatch().sendPositionedGraphic(67, 10, 0, Location.create(2840,3427,0)); //
|
||||
break;
|
||||
case 4:
|
||||
SceneryBuilder.replace(rock, rock.transform(rock.getId() + 1), 10);
|
||||
SceneryBuilder.replace(tree, tree.transform(tree.getId() + 1), 10);
|
||||
break;
|
||||
case 5:
|
||||
break;
|
||||
case 13:
|
||||
player.getProperties().setTeleportLocation(destination);
|
||||
break;
|
||||
case 14:
|
||||
player.unlock();
|
||||
player.getAchievementDiaryManager().finishTask(player, DiaryType.SEERS_VILLAGE, 2, 10);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getDestination(final Node moving, final Node destination) {
|
||||
// Run between rock and stream before firing grapple
|
||||
return Location.create(2841, 3427, 0);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,121 +0,0 @@
|
|||
package content.global.skill.agility.shortcuts;
|
||||
|
||||
import core.cache.def.impl.SceneryDefinition;
|
||||
import core.game.component.Component;
|
||||
import core.game.interaction.OptionHandler;
|
||||
import core.game.node.Node;
|
||||
import core.game.node.entity.impl.ForceMovement;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.item.Item;
|
||||
import core.game.system.task.Pulse;
|
||||
import core.game.world.GameWorld;
|
||||
import core.game.world.map.Location;
|
||||
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.MinimapStateContext;
|
||||
import core.net.packet.out.MinimapState;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
import core.game.node.entity.skill.Skills;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Initializable
|
||||
public class YanilleGrapple extends OptionHandler {
|
||||
private static final HashMap<Integer, Integer> REQUIREMENTS = new HashMap<>();
|
||||
private static String requirementsString;
|
||||
|
||||
static {
|
||||
REQUIREMENTS.putIfAbsent(Skills.AGILITY, 39);
|
||||
REQUIREMENTS.putIfAbsent(Skills.RANGE, 21);
|
||||
REQUIREMENTS.putIfAbsent(Skills.STRENGTH, 38);
|
||||
|
||||
requirementsString = "You need at least "
|
||||
+ REQUIREMENTS.get(Skills.AGILITY) + " " + Skills.SKILL_NAME[Skills.AGILITY] + ", "
|
||||
+ REQUIREMENTS.get(Skills.RANGE) + " " + Skills.SKILL_NAME[Skills.RANGE] + ", and "
|
||||
+ REQUIREMENTS.get(Skills.STRENGTH) + " " + Skills.SKILL_NAME[Skills.STRENGTH]
|
||||
+ " to use this shortcut.";
|
||||
}
|
||||
|
||||
private static final Item MITH_CBOW = new Item(9181);
|
||||
private static final Item MITH_GRAPPLE = new Item(9419);
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
SceneryDefinition.forId(17047).getHandlers().put("option:grapple", this);
|
||||
SceneryDefinition.forId(17048).getHandlers().put("option:jump", this);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(Player player, Node node, String option) {
|
||||
Location destination;
|
||||
Location current = player.getLocation();
|
||||
|
||||
switch (option) {
|
||||
case "jump":
|
||||
ForceMovement.run(player,
|
||||
current,
|
||||
current.getY() < 3074 ? Location.create(2556,3072,0) : Location.create(2556,3075,0),
|
||||
new Animation(7268),
|
||||
10);
|
||||
break;
|
||||
case "grapple":
|
||||
destination = current.getY() < 3073
|
||||
? Location.create(2556, 3073, 1)
|
||||
: Location.create(2556, 3074, 1);
|
||||
|
||||
for (Map.Entry<Integer, Integer> e : REQUIREMENTS.entrySet()) {
|
||||
if (player.getSkills().getLevel(e.getKey()) < e.getValue()) {
|
||||
player.getDialogueInterpreter().sendDialogue(requirementsString);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!player.getEquipment().containsItem(MITH_CBOW) || !player.getEquipment().containsItem(MITH_GRAPPLE)) {
|
||||
player.getDialogueInterpreter().sendDialogue("You need a Mithril crossbow and a Mithril grapple in order to do this.");
|
||||
return true;
|
||||
}
|
||||
|
||||
player.lock();
|
||||
GameWorld.getPulser().submit(new Pulse(1, player) {
|
||||
int counter = 1;
|
||||
Component tab;
|
||||
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
switch (counter++) {
|
||||
case 1:
|
||||
player.faceLocation(destination);
|
||||
player.visualize(new Animation(4455), new Graphics(760, 100));
|
||||
break;
|
||||
case 8:
|
||||
tab = player.getInterfaceManager().getSingleTab();
|
||||
player.getInterfaceManager().openOverlay(new Component(115));
|
||||
PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 2));
|
||||
player.getInterfaceManager().removeTabs(0, 1, 2, 3, 4, 5, 6, 11, 12);
|
||||
break;
|
||||
case 13:
|
||||
player.getProperties().setTeleportLocation(destination);
|
||||
break;
|
||||
case 14:
|
||||
player.getInterfaceManager().restoreTabs();
|
||||
if (tab != null) {
|
||||
player.getInterfaceManager().openTab(tab);
|
||||
}
|
||||
PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 0));
|
||||
player.getInterfaceManager().closeOverlay();
|
||||
player.getInterfaceManager().close();
|
||||
player.unlock();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
package content.global.skill.agility.shortcuts.grapple
|
||||
|
||||
import core.api.*
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.interaction.QueueStrength
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.node.scenery.Scenery
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import org.rs09.consts.Items
|
||||
|
||||
abstract class AbstractGrappleShortcut : InteractionListener {
|
||||
/**
|
||||
* Make sure that you have flagInstant in your listeners.
|
||||
* If you do not the player will run and try to touch the grapple point
|
||||
*/
|
||||
private val VALID_CROSSBOWS = intArrayOf(
|
||||
Items.MITH_CROSSBOW_9181,
|
||||
Items.ADAMANT_CROSSBOW_9183,
|
||||
Items.RUNE_CROSSBOW_9185,
|
||||
Items.DORGESHUUN_CBOW_8880
|
||||
)
|
||||
|
||||
protected abstract val REQUIREMENTS: HashMap<Int, Int>
|
||||
|
||||
protected abstract val grappleStartLocation: Location
|
||||
protected abstract val grappleEndLocation: Location
|
||||
|
||||
// use lazy so that the skill requirements can be populated after the child builds them
|
||||
private val requirementString1: String by lazy {
|
||||
"You need at least " +
|
||||
REQUIREMENTS[Skills.AGILITY] + " " + Skills.SKILL_NAME[Skills.AGILITY] + ", " +
|
||||
REQUIREMENTS[Skills.RANGE] + " " + Skills.SKILL_NAME[Skills.RANGE] + ","
|
||||
}
|
||||
private val requirementString2: String by lazy {
|
||||
"and " +
|
||||
REQUIREMENTS[Skills.STRENGTH] + " " + Skills.SKILL_NAME[Skills.STRENGTH] + " to use this shortcut."
|
||||
}
|
||||
|
||||
|
||||
// What needs to have its model changed during a grapple
|
||||
protected abstract val grappleScenery: List<Scenery?>
|
||||
|
||||
// What animation to use when getting the player across
|
||||
protected abstract val animation: Animation
|
||||
// How long should the animation last (in ticks)
|
||||
protected abstract val animationDuration: Int
|
||||
|
||||
protected abstract fun animation(animationStage: Int, player: Player): Boolean
|
||||
|
||||
|
||||
// The message that can appear if there should be one after grappling
|
||||
protected val message: String? = null
|
||||
|
||||
private fun getRequirementString(): Array<String> {
|
||||
val requirementString = arrayOf(requirementString1, requirementString2)
|
||||
return requirementString
|
||||
}
|
||||
|
||||
private fun doesPlayerHaveRequiredItemsEquipped(player: Player): Boolean {
|
||||
return inEquipment(player, Items.MITH_GRAPPLE_9419) && anyInEquipment(player, *VALID_CROSSBOWS)
|
||||
}
|
||||
|
||||
private fun doesPlayerHaveRequiredLevels(player: Player): Boolean {
|
||||
for ((skill, requiredLevel) in REQUIREMENTS) {
|
||||
if (!hasLevelDyn(player, skill, requiredLevel)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
protected open fun isPlayerInRangeToGrapple(player: Player, startLoc: Location, range: Int): Boolean {
|
||||
return inBorders(player, startLoc.x - range, startLoc.y - range,
|
||||
startLoc.x + range, startLoc.y + range)
|
||||
}
|
||||
|
||||
/**
|
||||
* See if the [player] is close enough to the [startLoc] (based on [range] to
|
||||
* try and grapple. This will return false if the [player] is too far away,
|
||||
* if the player does not have the right levels or if the player does not have
|
||||
* the correct gear equipped.
|
||||
*/
|
||||
protected fun canGrapple(player: Player, startLoc: Location, range: Int): Boolean {
|
||||
if (isPlayerInRangeToGrapple(player, startLoc, range)) {
|
||||
forceWalk(player, startLoc, "smart")
|
||||
} else {
|
||||
// todo should this be "you are too far away" or something like that?
|
||||
sendMessage(player, "Nothing interesting happens.")
|
||||
return false
|
||||
}
|
||||
|
||||
if (!doesPlayerHaveRequiredItemsEquipped(player)) {
|
||||
sendDialogue(player, "You need a Mithril crossbow and a Mithril grapple in order to do this.")
|
||||
return false
|
||||
}
|
||||
|
||||
if (!doesPlayerHaveRequiredLevels(player)) {
|
||||
sendDialogueLines(player,
|
||||
*getRequirementString()
|
||||
)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
protected fun grapple(player: Player, message: String?): Boolean {
|
||||
|
||||
lock(player, animationDuration)
|
||||
// TODO is this right? should we force the player to cross?
|
||||
queueScript(player, strength = QueueStrength.SOFT) { stage: Int ->
|
||||
if (animation(stage, player)){
|
||||
// We're done with the animation
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
else{
|
||||
return@queueScript delayScript(player, 1)
|
||||
}
|
||||
}
|
||||
|
||||
message?.let{
|
||||
player.sendMessage(message)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If an achievement diary can be updated it should be done here
|
||||
*/
|
||||
protected open fun updateDiary(player: Player): Boolean{
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package content.global.skill.agility.shortcuts.grapple
|
||||
|
||||
import core.api.*
|
||||
import core.game.node.entity.player.Player
|
||||
|
||||
abstract class AbstractOneWayGrapple : AbstractGrappleShortcut() {
|
||||
|
||||
|
||||
override fun animation(animationStage: Int, player: Player): Boolean {
|
||||
when (animationStage) {
|
||||
1 -> {
|
||||
// Point towards the grapple landing zone
|
||||
face(player, grappleEndLocation)
|
||||
// Start the grapple animation
|
||||
animate(player, animation)
|
||||
}
|
||||
|
||||
5 -> {
|
||||
for (tgt in grappleScenery) {
|
||||
// Add grapple effects to all scenery (for 10 ticks)
|
||||
replaceScenery(tgt!!, tgt.id + 1, 10)
|
||||
}
|
||||
}
|
||||
|
||||
5 + animationDuration -> {
|
||||
// After the animation is done teleport to the landing zone
|
||||
teleport(player, grappleEndLocation)
|
||||
}
|
||||
|
||||
5 + animationDuration + 1 -> {
|
||||
// free the player
|
||||
unlock(player)
|
||||
updateDiary(player)
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package content.global.skill.agility.shortcuts.grapple
|
||||
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.world.map.Direction
|
||||
import core.game.world.map.Location
|
||||
|
||||
abstract class AbstractTwoWayGrapple : AbstractGrappleShortcut(){
|
||||
|
||||
abstract var direction: Direction?
|
||||
|
||||
abstract var startLoc: Location?
|
||||
abstract var endLoc: Location?
|
||||
|
||||
protected abstract fun setStartEndSide(player: Player, margin: Int = 5)
|
||||
protected abstract fun getGrappleScenery(direction: Direction): List<core.game.node.scenery.Scenery?>
|
||||
}
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
package content.global.skill.agility.shortcuts.grapple
|
||||
|
||||
import core.api.*
|
||||
import core.game.interaction.IntType
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.world.map.Direction
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import org.rs09.consts.Scenery
|
||||
|
||||
class AlKharidGrapple : AbstractTwoWayGrapple(){
|
||||
|
||||
override val REQUIREMENTS: HashMap<Int, Int> = hashMapOf(Skills.AGILITY to 8, Skills.RANGE to 37, Skills.STRENGTH to 19)
|
||||
|
||||
// Lumbridge
|
||||
override val grappleStartLocation: Location = Location(3246, 3179, 0)
|
||||
|
||||
// Al Kharid
|
||||
override val grappleEndLocation: Location = Location(3259, 3179, 0)
|
||||
|
||||
override var direction: Direction? = null
|
||||
override var startLoc: Location? = null
|
||||
override var endLoc: Location? = null
|
||||
|
||||
override var grappleScenery: List<core.game.node.scenery.Scenery?> = listOf()
|
||||
|
||||
override val animation: Animation = Animation(4230)
|
||||
override val animationDuration: Int = 9
|
||||
override fun animation(animationStage: Int, player: Player): Boolean {
|
||||
when (animationStage) {
|
||||
1 -> {
|
||||
face(player, endLoc!!)
|
||||
animate(player, animation)
|
||||
}
|
||||
|
||||
5 -> {
|
||||
for (tgt in grappleScenery) {
|
||||
if ((tgt!!.id == 17068)) {
|
||||
// This is the raft
|
||||
continue
|
||||
}
|
||||
replaceScenery(tgt, tgt.id + 1, 10)
|
||||
}
|
||||
}
|
||||
|
||||
5 + animationDuration -> {
|
||||
teleport(player, endLoc!!)
|
||||
}
|
||||
5 + animationDuration + 1 -> {
|
||||
unlock(player)
|
||||
updateDiary(player)
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun defineListeners() {
|
||||
flagInstant() // execute listeners instantly without determining path
|
||||
|
||||
on(Scenery.BROKEN_RAFT_17068, IntType.SCENERY, "grapple") { player, target ->
|
||||
// Check if we are on the east or the west of the broken raft
|
||||
// East = Lum
|
||||
setStartEndSide(player)
|
||||
if (!canGrapple(player, startLoc!!, 2)){
|
||||
return@on true
|
||||
}
|
||||
grapple(player,message)
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun setStartEndSide(player: Player, margin: Int) {
|
||||
if (player.location.x < grappleStartLocation.x + margin){
|
||||
// We're on the west side
|
||||
direction = Direction.EAST // got to jump east
|
||||
startLoc = grappleStartLocation
|
||||
endLoc = grappleEndLocation
|
||||
}
|
||||
else {
|
||||
// we're on the east side
|
||||
direction = Direction.WEST // got to jump west
|
||||
startLoc = grappleEndLocation
|
||||
endLoc = grappleStartLocation
|
||||
}
|
||||
|
||||
grappleScenery = getGrappleScenery(direction!!)
|
||||
}
|
||||
|
||||
override fun getGrappleScenery(direction: Direction): List<core.game.node.scenery.Scenery?> {
|
||||
val lumbridgeTree = getScenery(Location(3244, 3179, 0))
|
||||
val alKharidTree = getScenery(Location(3260, 3178, 0))
|
||||
val startTree : core.game.node.scenery.Scenery?
|
||||
val endTree : core.game.node.scenery.Scenery?
|
||||
val raft = getScenery(Location(3252, 3179, 0))
|
||||
if (direction == Direction.EAST){
|
||||
startTree = lumbridgeTree
|
||||
endTree = alKharidTree
|
||||
}
|
||||
else{
|
||||
startTree = alKharidTree
|
||||
endTree = lumbridgeTree
|
||||
}
|
||||
return listOf(startTree,endTree, raft)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package content.global.skill.agility.shortcuts.grapple
|
||||
|
||||
import core.api.*
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import org.rs09.consts.Scenery
|
||||
import core.game.interaction.IntType
|
||||
import core.plugin.Initializable
|
||||
import kotlin.collections.HashMap
|
||||
|
||||
|
||||
@Initializable
|
||||
class CatherbyGrappleShortcut : AbstractOneWayGrapple(){
|
||||
|
||||
override val REQUIREMENTS: HashMap<Int, Int> = hashMapOf(Skills.AGILITY to 32, Skills.RANGE to 35, Skills.STRENGTH to 35)
|
||||
|
||||
override val grappleStartLocation: Location = Location.create(2866, 3429, 0)
|
||||
|
||||
override val grappleEndLocation: Location = Location.create(2869,3430,0)
|
||||
|
||||
// todo this is the wrong animation
|
||||
override val animation: Animation = Animation(4455)
|
||||
|
||||
override val animationDuration: Int = 9
|
||||
|
||||
override val grappleScenery: List<core.game.node.scenery.Scenery?> = listOf(
|
||||
getScenery(Location.create(2869,3429, 0)) // rocks
|
||||
)
|
||||
|
||||
override fun defineListeners() {
|
||||
flagInstant()
|
||||
|
||||
on(Scenery.ROCKS_17042, IntType.SCENERY, "grapple"){ player, _ ->
|
||||
if (!canGrapple(player, grappleStartLocation, 1)) {
|
||||
return@on true
|
||||
}
|
||||
grapple(player, message)
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
package content.global.skill.agility.shortcuts.grapple
|
||||
|
||||
import core.api.*
|
||||
import core.game.interaction.IntType
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.player.link.diary.DiaryType
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
import core.plugin.Initializable
|
||||
import org.rs09.consts.Scenery
|
||||
|
||||
abstract class AbstractFaladorGrapple(private var wallGrappleInterface: WallGrappleInterface = WallGrappleInterfaceImpl()): AbstractOneWayGrapple() {
|
||||
|
||||
override val animation: Animation = Animation(4455)
|
||||
|
||||
override val animationDuration: Int = 14
|
||||
|
||||
// There are no scenery items to hook so don't let children override this
|
||||
final override val grappleScenery: List<core.game.node.scenery.Scenery?> = listOf()
|
||||
|
||||
protected fun jump(player: Player, destination: Location): Boolean {
|
||||
return wallGrappleInterface.jump(player, destination)
|
||||
}
|
||||
|
||||
override fun animation(animationStage: Int, player: Player): Boolean {
|
||||
when (animationStage) {
|
||||
1 -> {
|
||||
player.faceLocation(grappleEndLocation)
|
||||
visualize(player, animation, Graphics(760, 100))
|
||||
}
|
||||
|
||||
8 -> {
|
||||
wallGrappleInterface.fadeToBlack(player)
|
||||
}
|
||||
|
||||
13 -> teleport(player, grappleEndLocation)
|
||||
14 -> {
|
||||
wallGrappleInterface.showGame(player)
|
||||
unlock(player)
|
||||
updateDiary(player)
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
@Initializable
|
||||
class FaladorGrappleNorth : AbstractFaladorGrapple() {
|
||||
|
||||
override val REQUIREMENTS: HashMap<Int, Int> = hashMapOf(Skills.AGILITY to 11, Skills.RANGE to 19, Skills.STRENGTH to 37)
|
||||
|
||||
override val grappleStartLocation: Location = Location.create(3033, 3390, 0)
|
||||
|
||||
|
||||
override val grappleEndLocation: Location = Location.create(3033, 3389, 1)
|
||||
|
||||
override fun defineListeners() {
|
||||
flagInstant()
|
||||
on(Scenery.WALL_17049, IntType.SCENERY, "grapple") { player, _ ->
|
||||
if(!canGrapple(player, grappleStartLocation, 4)) {
|
||||
return@on true
|
||||
}
|
||||
grapple(player, message)
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(Scenery.WALL_17051, IntType.SCENERY, "jump"){ player, _ ->
|
||||
jump(player, grappleStartLocation)
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
|
||||
override fun isPlayerInRangeToGrapple(player: Player, startLoc: Location, range: Int): Boolean {
|
||||
// Do not let the player grapple from the other side of the wall
|
||||
return inBorders(player, startLoc.x - range, startLoc.y,
|
||||
startLoc.x + range, startLoc.y + 2)
|
||||
}
|
||||
|
||||
override fun updateDiary(player: Player): Boolean {
|
||||
player.achievementDiaryManager.finishTask(player, DiaryType.FALADOR, 1, 2)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@Initializable
|
||||
class FaladorGrappleSouth : AbstractFaladorGrapple() {
|
||||
|
||||
override val REQUIREMENTS: HashMap<Int, Int> = hashMapOf(Skills.AGILITY to 11, Skills.RANGE to 19, Skills.STRENGTH to 37)
|
||||
|
||||
override val grappleStartLocation: Location = Location.create(3032, 3388, 0)
|
||||
|
||||
override val grappleEndLocation: Location = Location.create(3032, 3389, 1)
|
||||
|
||||
override fun defineListeners() {
|
||||
flagInstant()
|
||||
on(Scenery.WALL_17050, IntType.SCENERY, "grapple") { player, _ ->
|
||||
if(!canGrapple(player, grappleStartLocation, 4)) {
|
||||
return@on true
|
||||
}
|
||||
grapple(player, message)
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(Scenery.WALL_17052, IntType.SCENERY, "jump"){ player, _ ->
|
||||
jump(player, grappleStartLocation)
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
|
||||
override fun isPlayerInRangeToGrapple(player: Player, startLoc: Location, range: Int): Boolean {
|
||||
// Do not let the player grapple from the other side of the wall
|
||||
return inBorders(player, startLoc.x - range, startLoc.y,
|
||||
startLoc.x + range, startLoc.y - 2)
|
||||
}
|
||||
|
||||
override fun updateDiary(player: Player): Boolean {
|
||||
player.achievementDiaryManager.finishTask(player, DiaryType.FALADOR, 1, 2)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
package content.global.skill.agility.shortcuts.grapple
|
||||
|
||||
import core.api.*
|
||||
import core.game.interaction.IntType
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.player.link.diary.DiaryType
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.world.map.Direction
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import core.plugin.Initializable
|
||||
import org.rs09.consts.Scenery
|
||||
|
||||
@Initializable
|
||||
class KaramjaGrapple : AbstractTwoWayGrapple(){
|
||||
|
||||
override val REQUIREMENTS: HashMap<Int, Int> = hashMapOf(Skills.AGILITY to 53, Skills.RANGE to 42, Skills.STRENGTH to 21)
|
||||
|
||||
// South
|
||||
override val grappleStartLocation: Location = Location.create(2874, 3127, 0)
|
||||
|
||||
|
||||
// North
|
||||
override val grappleEndLocation: Location = Location.create(2874,3142,0)
|
||||
|
||||
override var direction: Direction? = null
|
||||
override var startLoc: Location? = null
|
||||
override var endLoc: Location? = null
|
||||
|
||||
override var grappleScenery: List<core.game.node.scenery.Scenery?> = listOf()
|
||||
|
||||
override val animation: Animation = Animation(4230)
|
||||
override val animationDuration: Int = 9
|
||||
|
||||
override fun animation(animationStage: Int, player: Player): Boolean {
|
||||
when (animationStage) {
|
||||
1 -> {
|
||||
face(player, endLoc!!)
|
||||
animate(player, animation)
|
||||
}
|
||||
|
||||
5 -> {
|
||||
for (tgt in grappleScenery) {
|
||||
replaceScenery(tgt!!, tgt.id + 1, 10)
|
||||
}
|
||||
}
|
||||
|
||||
5 + animationDuration -> {
|
||||
teleport(player, endLoc!!)
|
||||
}
|
||||
5 + animationDuration + 1 -> {
|
||||
unlock(player)
|
||||
updateDiary(player)
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun defineListeners() {
|
||||
flagInstant()
|
||||
|
||||
on(Scenery.STRONG_TREE_17074, IntType.SCENERY, "grapple"){ player, _ ->
|
||||
setStartEndSide(player)
|
||||
if(!canGrapple(player, startLoc!!, 1)){
|
||||
return@on true
|
||||
}
|
||||
grapple(player, message)
|
||||
return@on true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun setStartEndSide(player: Player, margin: Int) {
|
||||
if (player.location.y > grappleEndLocation.y - margin){ // we're on the north side
|
||||
direction = Direction.SOUTH // got to jump south
|
||||
startLoc = grappleEndLocation
|
||||
endLoc = grappleStartLocation
|
||||
}
|
||||
else {
|
||||
direction = Direction.NORTH // got to jump north
|
||||
startLoc = grappleStartLocation
|
||||
endLoc = grappleEndLocation
|
||||
}
|
||||
|
||||
grappleScenery = getGrappleScenery(direction!!)
|
||||
}
|
||||
|
||||
override fun getGrappleScenery(direction: Direction): List<core.game.node.scenery.Scenery?> {
|
||||
val startTree : core.game.node.scenery.Scenery?
|
||||
val endTree : core.game.node.scenery.Scenery?
|
||||
val islandTree = getScenery(Location(2873, 3134, 0))
|
||||
if (direction == Direction.NORTH){
|
||||
startTree = getScenery(Location(2874, 3144, 0))
|
||||
endTree = getScenery(Location(2873, 3125, 0))
|
||||
}
|
||||
else{
|
||||
startTree = getScenery(Location(2874, 3144, 0))
|
||||
endTree = getScenery(Location(2873, 3125, 0))
|
||||
}
|
||||
return listOf(startTree,endTree, islandTree)
|
||||
}
|
||||
|
||||
override fun updateDiary(player: Player): Boolean {
|
||||
player.achievementDiaryManager.finishTask(player, DiaryType.KARAMJA, 2, 6)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
package content.global.skill.agility.shortcuts.grapple
|
||||
|
||||
import core.api.*
|
||||
import core.game.component.Component
|
||||
import core.game.interaction.QueueStrength
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import core.net.packet.PacketRepository
|
||||
import core.net.packet.context.MinimapStateContext
|
||||
import core.net.packet.out.MinimapState
|
||||
|
||||
interface WallGrappleInterface {
|
||||
var tab: Component?
|
||||
fun jump(player: Player, destination: Location): Boolean
|
||||
fun fadeToBlack(player: Player): Component
|
||||
fun showGame(player: Player): Boolean
|
||||
}
|
||||
|
||||
|
||||
class WallGrappleInterfaceImpl: WallGrappleInterface{
|
||||
override var tab: Component? = null
|
||||
|
||||
override fun jump(player: Player, destination: Location): Boolean {
|
||||
// todo this doesn't look great compared to what it used to look like
|
||||
forceWalk(player, destination,"smart" )
|
||||
face(player, destination)
|
||||
// We're teleporting if we are animating so make the strength SOFT
|
||||
queueScript(player, strength = QueueStrength.SOFT){ stage: Int ->
|
||||
when (stage){
|
||||
1 -> animate(player, Animation(7268))
|
||||
2 ->{
|
||||
teleport(player, destination)
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
}
|
||||
return@queueScript delayScript(player, 1)
|
||||
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
override fun fadeToBlack(player: Player): Component {
|
||||
// todo make this work. Right now the tab is always null
|
||||
tab = player.interfaceManager.singleTab
|
||||
player.interfaceManager.openOverlay(Component(115))
|
||||
PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 2))
|
||||
player.interfaceManager.removeTabs(0, 1, 2, 3, 4, 5, 6, 11, 12)
|
||||
if (tab == null){
|
||||
println("Panic")
|
||||
return Component(1)
|
||||
}
|
||||
return tab!!
|
||||
}
|
||||
|
||||
override fun showGame(player: Player): Boolean {
|
||||
player.interfaceManager.restoreTabs()
|
||||
if (tab != null) {
|
||||
player.interfaceManager.openTab(tab)
|
||||
}
|
||||
PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 0))
|
||||
closeOverlay(player)
|
||||
closeInterface(player)
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
package content.global.skill.agility.shortcuts.grapple
|
||||
|
||||
import core.api.getScenery
|
||||
import core.game.interaction.IntType
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.player.link.diary.DiaryType
|
||||
import core.game.node.entity.skill.Skills
|
||||
import org.rs09.consts.Scenery
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import core.plugin.Initializable
|
||||
|
||||
@Initializable
|
||||
class WaterOrbGrapple : AbstractOneWayGrapple(){
|
||||
|
||||
override val REQUIREMENTS: HashMap<Int, Int> = hashMapOf(Skills.AGILITY to 36, Skills.RANGE to 39, Skills.STRENGTH to 22)
|
||||
|
||||
override val grappleStartLocation: Location = Location.create(2841, 3427, 0)
|
||||
|
||||
override val grappleEndLocation: Location = Location.create(2841, 3433, 0)
|
||||
|
||||
override val animation: Animation = Animation(4230)
|
||||
|
||||
override val animationDuration: Int = 9
|
||||
|
||||
override val grappleScenery: List<core.game.node.scenery.Scenery?> = listOf(
|
||||
getScenery(Location.create(2841, 3426, 0)), // rock
|
||||
getScenery(Location.create(2841, 3434, 0)) // tree
|
||||
)
|
||||
|
||||
override fun defineListeners() {
|
||||
flagInstant()
|
||||
|
||||
on(Scenery.CROSSBOW_TREE_17062, IntType.SCENERY, "grapple"){ player, _ ->
|
||||
if (!canGrapple(player, grappleStartLocation, 1)) {
|
||||
return@on true
|
||||
}
|
||||
grapple(player, message)
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateDiary(player: Player): Boolean {
|
||||
player.achievementDiaryManager.finishTask(player, DiaryType.SEERS_VILLAGE, 2, 10)
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
package content.global.skill.agility.shortcuts.grapple
|
||||
|
||||
import core.api.inBorders
|
||||
import core.api.teleport
|
||||
import core.api.unlock
|
||||
import core.api.visualize
|
||||
import core.game.interaction.IntType
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.world.map.Direction
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
import core.plugin.Initializable
|
||||
import org.rs09.consts.Scenery
|
||||
|
||||
@Initializable
|
||||
class YanilleGrapple(private var wallGrappleInterface: WallGrappleInterface = WallGrappleInterfaceImpl()): AbstractTwoWayGrapple() {
|
||||
|
||||
override val REQUIREMENTS: HashMap<Int, Int> = hashMapOf(Skills.AGILITY to 11, Skills.RANGE to 19, Skills.STRENGTH to 37)
|
||||
|
||||
override val grappleStartLocation: Location = Location.create(2556, 3072, 0)
|
||||
|
||||
override val grappleEndLocation: Location = Location.create(2556, 3073, 1)
|
||||
|
||||
override var direction: Direction? = null
|
||||
override var startLoc: Location? = null
|
||||
override var endLoc: Location? = null
|
||||
override fun setStartEndSide(player: Player, margin: Int) {
|
||||
// Start location is where you end after jumping in the opposite way
|
||||
if (player.location.y > 3073 ){
|
||||
// We are north of the middle of the wall
|
||||
startLoc = Location.create(2556, 3075, 0) // This is where you grapple from/land after jumping
|
||||
endLoc = Location.create(2556, 3074, 1) //
|
||||
}
|
||||
else {
|
||||
// We are south of the middle of the wall
|
||||
startLoc = Location.create(2556, 3072, 0)
|
||||
endLoc = Location.create(2556, 3073, 1)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getGrappleScenery(direction: Direction): List<core.game.node.scenery.Scenery?> {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
override var grappleScenery: List<core.game.node.scenery.Scenery?> = listOf()
|
||||
|
||||
override val animation: Animation = Animation(4455)
|
||||
override val animationDuration: Int = 9
|
||||
override fun animation(animationStage: Int, player: Player): Boolean {
|
||||
when (animationStage) {
|
||||
1 -> {
|
||||
player.faceLocation(endLoc)
|
||||
visualize(player, animation, Graphics(760, 100))
|
||||
}
|
||||
|
||||
8 -> {
|
||||
wallGrappleInterface.fadeToBlack(player)
|
||||
}
|
||||
|
||||
13 -> teleport(player, endLoc!!)
|
||||
14 -> {
|
||||
wallGrappleInterface.showGame(player)
|
||||
unlock(player)
|
||||
updateDiary(player)
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
override fun defineListeners() {
|
||||
// Do not use flagListeners here
|
||||
// The player needs to be able to touch the target
|
||||
on(Scenery.WALL_17047, IntType.SCENERY, "grapple") { player, _ ->
|
||||
setStartEndSide(player, 0)
|
||||
if(!canGrapple(player, startLoc!!, 4)){
|
||||
return@on true
|
||||
}
|
||||
grapple(player, message)
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(Scenery.WALL_17048, IntType.SCENERY, "jump") { player, _ ->
|
||||
setStartEndSide(player, 0)
|
||||
wallGrappleInterface.jump(player, startLoc!!)
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
|
||||
override fun isPlayerInRangeToGrapple(player: Player, startLoc: Location, range: Int): Boolean {
|
||||
// Do not let the player grapple from the other side of the wall
|
||||
return inBorders(
|
||||
player, startLoc.x - range, startLoc.y,
|
||||
startLoc.x + range, startLoc.y - 2)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue