Repository reorganisation
Unified kotlin and java into just src/main Unified the rs09 and core packages Took all content out of the core package, and placed it into the new content package Reorganised all source code relating to content to be easier to find and explore
This commit is contained in:
@@ -0,0 +1,240 @@
|
||||
package content.global.skill.thieving;
|
||||
|
||||
import core.cache.def.impl.SceneryDefinition;
|
||||
import core.game.global.action.DoorActionHandler;
|
||||
import core.plugin.Initializable;
|
||||
import core.game.node.entity.skill.Skills;
|
||||
import core.game.interaction.OptionHandler;
|
||||
import core.game.node.Node;
|
||||
import core.game.node.entity.Entity;
|
||||
import core.game.node.entity.combat.ImpactHandler;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.item.Item;
|
||||
import core.game.node.scenery.Scenery;
|
||||
import core.game.world.map.Direction;
|
||||
import core.game.world.map.Location;
|
||||
import core.plugin.Plugin;
|
||||
import core.tools.RandomFunction;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a pickable door.
|
||||
* @author Vexia
|
||||
*/
|
||||
@Initializable
|
||||
public class PickableDoorHandler extends OptionHandler {
|
||||
/**
|
||||
* The lock pick item.
|
||||
*/
|
||||
private static final Item LOCK_PICK = new Item(1523);
|
||||
|
||||
private static final List<PickableDoor> pickableDoors = new ArrayList<>(20);
|
||||
|
||||
private static final int[] DOORS = new int[]{42028, 2550, 2551, 2554, 2555, 2556, 2557, 2558, 2559, 5501, 7246, 9565, 13314, 13317, 13320, 13323, 13326, 13344, 13345, 13346, 13347, 13348, 13349, 15759, 34005, 34805, 34806, 34812};
|
||||
|
||||
PickableDoor door;
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
for (int i : DOORS) {
|
||||
SceneryDefinition.forId(i).getHandlers().put("option:pick-lock", this);
|
||||
SceneryDefinition.forId(i).getHandlers().put("option:open", this);
|
||||
}
|
||||
pickableDoors.add(new PickableDoor(new Location[]{Location.create(2672, 3308, 0)}, 1, 3.8));
|
||||
pickableDoors.add(new PickableDoor(new Location[]{Location.create(2672, 3301, 0)}, 14, 15));
|
||||
pickableDoors.add(new PickableDoor(new Location[]{Location.create(2610, 3316, 0)}, 15, 15));
|
||||
pickableDoors.add(new PickableDoor(new Location[]{Location.create(3190, 3957, 0)}, 32, 25, true));
|
||||
pickableDoors.add(new PickableDoor(new Location[]{Location.create(2565, 3356, 0)}, 46, 37.5));
|
||||
pickableDoors.add(new PickableDoor(new Location[]{Location.create(2579, 3286, 1)}, 61, 50));
|
||||
pickableDoors.add(new PickableDoor(new Location[]{Location.create(2579, 3307, 1)}, 61, 50));
|
||||
pickableDoors.add(new PickableDoor(new Location[]{Location.create(3018, 3187, 0)}, 1, 0.0));
|
||||
pickableDoors.add(new PickableDoor(new Location[]{Location.create(2601, 9482, 0)}, 82, 0.0, true));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(Player player, Node node, String option) {
|
||||
door = forDoor(node.getLocation());
|
||||
if (option.equals("open")) {
|
||||
if (door == null) {
|
||||
player.getPacketDispatch().sendMessage("The door is locked.");
|
||||
return true;
|
||||
}
|
||||
door.open(player, (Scenery) node);
|
||||
return true;
|
||||
}
|
||||
if (option.equals("pick-lock")) {
|
||||
door.pickLock(player, (Scenery) node);
|
||||
return true;
|
||||
}
|
||||
System.out.println("Unhandled door: " + node.getId());
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getDestination(Node node, Node n) {
|
||||
if (n instanceof Scenery) {
|
||||
Scenery object = (Scenery) n;
|
||||
if (object.getDefinition().hasAction("pick-lock")) {
|
||||
return DoorActionHandler.getDestination((Entity) node, object);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private PickableDoor forDoor(Location location) {
|
||||
for (PickableDoor door : pickableDoors) {
|
||||
for (Location l : door.getLocations()) {
|
||||
if (l.equals(location)) {
|
||||
return door;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public class PickableDoor{
|
||||
/**
|
||||
* The locations of the door.
|
||||
*/
|
||||
private final Location[] locations;
|
||||
|
||||
/**
|
||||
* The level.
|
||||
*/
|
||||
private final int level;
|
||||
|
||||
/**
|
||||
* The experience required.
|
||||
*/
|
||||
private final double experience;
|
||||
|
||||
/**
|
||||
* If it requires a lockpick.
|
||||
*/
|
||||
private final boolean lockpick;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code PickableDoor} {@code Object}.
|
||||
* @param locations the locations.
|
||||
* @param level the level.
|
||||
* @param experience the experience.
|
||||
* @param lockpick the lock pick.
|
||||
*/
|
||||
public PickableDoor(final Location[] locations, int level, double experience, boolean lockpick) {
|
||||
this.locations = locations;
|
||||
this.level = level;
|
||||
this.experience = experience;
|
||||
this.lockpick = lockpick;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code PickableDoor} {@code Object}.
|
||||
* @param level the level.
|
||||
* @param experience the experience.
|
||||
*/
|
||||
public PickableDoor(Location[] locations, int level, double experience) {
|
||||
this(locations, level, experience, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the location.
|
||||
* @return The location.
|
||||
*/
|
||||
public Location[] getLocations() {
|
||||
return locations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a pickable door.
|
||||
* @param player the player.
|
||||
* @param object the object.
|
||||
*/
|
||||
public void open(Player player, Scenery object) {
|
||||
if (isInside(player, object)) {
|
||||
DoorActionHandler.handleAutowalkDoor(player, object);
|
||||
player.getPacketDispatch().sendMessage("You go through the door.");
|
||||
} else {
|
||||
player.getPacketDispatch().sendMessage("The door is locked.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Picks a lock on a door.
|
||||
* @param player the player.
|
||||
* @param object the object.
|
||||
*/
|
||||
public void pickLock(Player player, Scenery object) {
|
||||
boolean success = RandomFunction.random(12) >= 4;
|
||||
if (isInside(player, object)) {
|
||||
player.getPacketDispatch().sendMessage("The door is already unlocked.");
|
||||
return;
|
||||
}
|
||||
if (player.getSkills().getLevel(Skills.THIEVING) < level) {
|
||||
player.sendMessage("You attempt to pick the lock.");
|
||||
boolean hit = RandomFunction.random(10) < 5;
|
||||
player.getImpactHandler().manualHit(player, RandomFunction.random(1, 3), ImpactHandler.HitsplatType.NORMAL);
|
||||
player.sendMessage(hit ? "You have activated a trap on the lock." : "You fail to pick the lock.");
|
||||
return;
|
||||
}
|
||||
if (lockpick && !player.getInventory().containsItem(LOCK_PICK)) {
|
||||
player.sendMessage("You need a lockpick in order to pick this lock.");
|
||||
return;
|
||||
}
|
||||
if (success) {
|
||||
player.getSkills().addExperience(Skills.THIEVING, experience, true);
|
||||
DoorActionHandler.handleAutowalkDoor(player, object);
|
||||
}
|
||||
player.getPacketDispatch().sendMessage("You attempt to pick the lock.");
|
||||
player.getPacketDispatch().sendMessage("You " + (success ? "manage" : "fail") + " to pick the lock.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if we're behind the door/inside the building.
|
||||
* @param player the player.
|
||||
* @param object the object.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
private boolean isInside(Player player, Scenery object) {
|
||||
boolean inside = false;
|
||||
Direction dir = Direction.getLogicalDirection(player.getLocation(), object.getLocation());
|
||||
Direction direction = object.getDirection();
|
||||
if (direction == Direction.SOUTH && dir == Direction.WEST) {
|
||||
inside = true;
|
||||
} else if (direction == Direction.EAST && dir == Direction.SOUTH) {
|
||||
inside = true;
|
||||
} else if (direction == Direction.NORTH && dir == Direction.EAST) {
|
||||
inside = true;
|
||||
}
|
||||
return inside;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the level.
|
||||
* @return The level.
|
||||
*/
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the experience.
|
||||
* @return The experience.
|
||||
*/
|
||||
public double getExperience() {
|
||||
return experience;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the lockpick.
|
||||
* @return The lockpick.
|
||||
*/
|
||||
public boolean isLockpick() {
|
||||
return lockpick;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
package content.global.skill.thieving
|
||||
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.tools.RandomFunction
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
import core.api.utils.WeightBasedTable
|
||||
import core.api.utils.WeightedItem
|
||||
import java.util.stream.IntStream
|
||||
|
||||
enum class Pickpockets(val ids: IntArray, val requiredLevel: Int, val low: Double, val high: Double, val experience: Double, val stunDamageMin: Int, val stunDamageMax: Int, val stunTime: Int, val table: WeightBasedTable) {
|
||||
MAN(intArrayOf(1, 2, 3, 4, 5, 6, 16, 24, 25, 170, 3224, 3915, 3226, 3227, 5924, 5923), 1, 180.0, 240.0, 8.0, 1, 1,5, WeightBasedTable.create(
|
||||
WeightedItem(Items.COINS_995,3,3,1.0,true)
|
||||
)),
|
||||
FARMER(intArrayOf(7, 1757, 1758), 10, 180.0, 240.0, 14.5, 1,1,5, WeightBasedTable.create(
|
||||
WeightedItem(Items.COINS_995,9,9,1.0,true),
|
||||
WeightedItem(Items.POTATO_SEED_5318,1,1,1.0,true)
|
||||
)),
|
||||
MALE_HAM_MEMBER(intArrayOf(1714), 20, 117.0, 240.0, 22.5, 1,3,4, WeightBasedTable.create(
|
||||
WeightedItem(Items.COINS_995,1,21,5.5),
|
||||
WeightedItem(Items.TINDERBOX_590,1,1,5.0),
|
||||
WeightedItem(Items.LOGS_1511,1,1,7.0),
|
||||
WeightedItem(Items.UNCUT_JADE_1627,1,1,2.5),
|
||||
WeightedItem(Items.UNCUT_OPAL_1625,1,1,2.5),
|
||||
WeightedItem(Items.RAW_ANCHOVIES_321,1,1,7.0),
|
||||
WeightedItem(Items.RAW_CHICKEN_2138,1,1,3.5),
|
||||
WeightedItem(Items.HAM_CLOAK_4304,1,1,0.25),
|
||||
WeightedItem(Items.HAM_HOOD_4302,1,1,0.25),
|
||||
WeightedItem(Items.HAM_LOGO_4306,1,1,0.25),
|
||||
WeightedItem(Items.HAM_ROBE_4300,1,1,0.25),
|
||||
WeightedItem(Items.HAM_SHIRT_4298,1,1,0.25),
|
||||
WeightedItem(Items.BOOTS_4310,1,1,1.0),
|
||||
WeightedItem(Items.GLOVES_4308,1,1,1.0),
|
||||
WeightedItem(Items.BRONZE_PICKAXE_1265,1,1,5.0),
|
||||
WeightedItem(Items.IRON_PICKAXE_1267,1,1,5.0),
|
||||
WeightedItem(Items.STEEL_PICKAXE_1269,1,1,2.5),
|
||||
WeightedItem(Items.GRIMY_GUAM_199,1,1,2.0),
|
||||
WeightedItem(Items.GRIMY_HARRALANDER_205,1,1,2.0),
|
||||
WeightedItem(Items.GRIMY_KWUARM_213,1,1,2.0),
|
||||
WeightedItem(Items.GRIMY_MARRENTILL_201,1,1,1.5),
|
||||
WeightedItem(Items.RUSTY_SWORD_686,1,1,3.5),
|
||||
WeightedItem(Items.BROKEN_ARMOUR_698,1,1,3.5),
|
||||
WeightedItem(Items.BROKEN_STAFF_689,1,1,3.2),
|
||||
WeightedItem(Items.BROKEN_ARROW_687,1,1,3.1),
|
||||
WeightedItem(Items.BUTTONS_688,1,1,3.0)
|
||||
).insertEasyClue(1.0)),
|
||||
FEMALE_HAM_MEMBER(intArrayOf(1715), 15, 135.0, 240.0, 18.5, 1,3,4, WeightBasedTable.create(
|
||||
WeightedItem(Items.COINS_995,1,21,5.5),
|
||||
WeightedItem(Items.TINDERBOX_590,1,1,5.0),
|
||||
WeightedItem(Items.LOGS_1511,1,1,7.0),
|
||||
WeightedItem(Items.UNCUT_JADE_1627,1,1,2.5),
|
||||
WeightedItem(Items.UNCUT_OPAL_1625,1,1,2.5),
|
||||
WeightedItem(Items.RAW_ANCHOVIES_321,1,1,7.0),
|
||||
WeightedItem(Items.RAW_CHICKEN_2138,1,1,3.5),
|
||||
WeightedItem(Items.HAM_CLOAK_4304,1,1,0.25),
|
||||
WeightedItem(Items.HAM_HOOD_4302,1,1,0.25),
|
||||
WeightedItem(Items.HAM_LOGO_4306,1,1,0.25),
|
||||
WeightedItem(Items.HAM_SHIRT_4298,1,1,0.25),
|
||||
WeightedItem(Items.HAM_ROBE_4300,1,1,0.25),
|
||||
WeightedItem(Items.BOOTS_4310,1,1,1.0),
|
||||
WeightedItem(Items.GLOVES_4308,1,1,1.0),
|
||||
WeightedItem(Items.BRONZE_PICKAXE_1265,1,1,5.0),
|
||||
WeightedItem(Items.IRON_PICKAXE_1267,1,1,5.0),
|
||||
WeightedItem(Items.STEEL_PICKAXE_1269,1,1,2.5),
|
||||
WeightedItem(Items.GRIMY_GUAM_199,1,1,2.0),
|
||||
WeightedItem(Items.GRIMY_HARRALANDER_205,1,1,2.0),
|
||||
WeightedItem(Items.GRIMY_KWUARM_213,1,1,2.0),
|
||||
WeightedItem(Items.GRIMY_MARRENTILL_201,1,1,1.5),
|
||||
WeightedItem(Items.RUSTY_SWORD_686,1,1,3.5),
|
||||
WeightedItem(Items.BROKEN_ARMOUR_698,1,1,3.5),
|
||||
WeightedItem(Items.BROKEN_STAFF_689,1,1,3.2),
|
||||
WeightedItem(Items.BROKEN_ARROW_687,1,1,3.1),
|
||||
WeightedItem(Items.BUTTONS_688,1,1,3.0)
|
||||
).insertEasyClue(1.0)),
|
||||
WARRIOR(intArrayOf(15, 18), 25, 84.0, 240.0, 26.0, 2, 2, 5, WeightBasedTable.create(
|
||||
WeightedItem(Items.COINS_995,18,18,1.0,true)
|
||||
)),
|
||||
ROGUE(intArrayOf(187, 2267, 2268, 2269, 8122), 32, 74.0, 240.0,35.5, 2, 2, 5, WeightBasedTable.create(
|
||||
WeightedItem(Items.COINS_995,25,40,5.0,true),
|
||||
WeightedItem(Items.JUG_OF_WINE_1993,1,1,6.0),
|
||||
WeightedItem(Items.AIR_RUNE_556,8,8,8.0),
|
||||
WeightedItem(Items.LOCKPICK_1523,1,1,5.0),
|
||||
WeightedItem(Items.IRON_DAGGERP_1219,1,1,1.0)
|
||||
)),
|
||||
CAVE_GOBLIN(IntStream.rangeClosed(5752, 5768).toArray(), 36, 72.0, 240.0, 40.0, 1,1,5, WeightBasedTable.create(
|
||||
WeightedItem(Items.COINS_995,30,30,6.5),
|
||||
WeightedItem(Items.OIL_LAMP_4522,1,1,0.5),
|
||||
WeightedItem(Items.BULLSEYE_LANTERN_4544,1,1,0.5),
|
||||
WeightedItem(Items.UNLIT_TORCH_596,1,1,0.5),
|
||||
WeightedItem(Items.TINDERBOX_590,1,1,0.5),
|
||||
WeightedItem(Items.SWAMP_TAR_1939,1,1,0.5),
|
||||
WeightedItem(Items.IRON_ORE_441,1,4,0.25)
|
||||
)),
|
||||
MASTER_FARMER(intArrayOf(2234, 2235, NPCs.MARTIN_THE_MASTER_GARDENER_3299), 38, 90.0, 240.0, 43.0, 3, 3, 5, WeightBasedTable.create(
|
||||
WeightedItem(Items.POTATO_SEED_5318,1,3,50.0),
|
||||
WeightedItem(Items.ONION_SEED_5319,1,3,50.0),
|
||||
WeightedItem(Items.CABBAGE_SEED_5324,1,3,50.0),
|
||||
WeightedItem(Items.TOMATO_SEED_5322,1,2,50.0),
|
||||
WeightedItem(Items.SWEETCORN_SEED_5320,1,2,50.0),
|
||||
WeightedItem(Items.STRAWBERRY_SEED_5323,1,1,25.0),
|
||||
WeightedItem(Items.WATERMELON_SEED_5321,1,1,8.0),
|
||||
WeightedItem(Items.BARLEY_SEED_5305,1,4,50.0),
|
||||
WeightedItem(Items.HAMMERSTONE_SEED_5307,1,3,50.0),
|
||||
WeightedItem(Items.ASGARNIAN_SEED_5308,1,3,50.0),
|
||||
WeightedItem(Items.JUTE_SEED_5306,1,3,50.0),
|
||||
WeightedItem(Items.YANILLIAN_SEED_5309,1,2,25.0),
|
||||
WeightedItem(Items.KRANDORIAN_SEED_5310,1,2,25.0),
|
||||
WeightedItem(Items.WILDBLOOD_SEED_5311,1,1,8.0),
|
||||
WeightedItem(Items.MARIGOLD_SEED_5096,1,1,50.0),
|
||||
WeightedItem(Items.NASTURTIUM_SEED_5098,1,1,50.0),
|
||||
WeightedItem(Items.ROSEMARY_SEED_5097,1,1,50.0),
|
||||
WeightedItem(Items.WOAD_SEED_5099,1,1,50.0),
|
||||
WeightedItem(Items.LIMPWURT_SEED_5100,1,1,25.0),
|
||||
WeightedItem(Items.REDBERRY_SEED_5101,1,1,50.0),
|
||||
WeightedItem(Items.CADAVABERRY_SEED_5102,1,1,50.0),
|
||||
WeightedItem(Items.DWELLBERRY_SEED_5103,1,1,25.0),
|
||||
WeightedItem(Items.JANGERBERRY_SEED_5104,1,1,25.0),
|
||||
WeightedItem(Items.WHITEBERRY_SEED_5105,1,1,25.0),
|
||||
WeightedItem(Items.GUAM_SEED_5291,1,1,50.0),
|
||||
WeightedItem(Items.MARRENTILL_SEED_5292,1,1,50.0),
|
||||
WeightedItem(Items.TARROMIN_SEED_5293,1,1,50.0),
|
||||
WeightedItem(Items.HARRALANDER_SEED_5294,1,1,25.0),
|
||||
WeightedItem(Items.RANARR_SEED_5295,1,1,8.0),
|
||||
WeightedItem(Items.TOADFLAX_SEED_5296,1,1,8.0),
|
||||
WeightedItem(Items.IRIT_SEED_5297,1,1,8.0),
|
||||
WeightedItem(Items.AVANTOE_SEED_5298,1,1,8.0),
|
||||
WeightedItem(Items.KWUARM_SEED_5299,1,1,8.0),
|
||||
WeightedItem(Items.SNAPDRAGON_SEED_5300,1,1,5.0),
|
||||
WeightedItem(Items.CADANTINE_SEED_5301,1,1,8.0),
|
||||
WeightedItem(Items.LANTADYME_SEED_5302,1,1,5.0),
|
||||
WeightedItem(Items.DWARF_WEED_SEED_5303,1,1,5.0),
|
||||
WeightedItem(Items.TORSTOL_SEED_5304,1,1,5.0)
|
||||
)),
|
||||
GUARD(intArrayOf(9, 32, 206, 296, 297, 298, 299, 344, 345, 346, 368, 678, 812, 9, 32, 296, 297, 298, 299, 2699, 2700, 2701, 2702, 2703, 3228, 3229, 3230, 3231, 3232, 3233, 3241, 3407, 3408, 4307, 4308, 4309, 4310, 4311, 5919, 5920), 40, 50.0, 240.0, 46.5, 2,2,5, WeightBasedTable.create(
|
||||
WeightedItem(Items.COINS_995,30,30,1.0,true)
|
||||
)),
|
||||
FREMENNIK_CITIZEN(intArrayOf(2462), 45, 65.0, 240.0, 65.0, 2, 2, 5, WeightBasedTable.create(
|
||||
WeightedItem(Items.COINS_995,40,40,1.0,true)
|
||||
)),
|
||||
BEARDED_BANDIT(intArrayOf(1880, 1881, 6174), 45, 50.0, 240.0, 65.0, 5,5,5, WeightBasedTable.create(
|
||||
WeightedItem(Items.ANTIPOISON4_2446,1,1,1.0),
|
||||
WeightedItem(Items.LOCKPICK_1523,1,1,2.0),
|
||||
WeightedItem(Items.COINS_995,1,1,4.0)
|
||||
)),
|
||||
DESERT_BANDIT(intArrayOf(1926, 1921), 53, 50.0, 240.0, 79.5, 3,3,5, WeightBasedTable.create(
|
||||
WeightedItem(Items.COINS_995,50,1,3.0),
|
||||
WeightedItem(Items.ANTIPOISON4_2446,1,1,1.0),
|
||||
WeightedItem(Items.LOCKPICK_1523,1,1,1.0)
|
||||
)),
|
||||
KNIGHT_OF_ADROUGNE(intArrayOf(23, 26), 55, 50.0, 240.0, 84.3, 3,3,5, WeightBasedTable.create(
|
||||
WeightedItem(Items.COINS_995,50,50,1.0,true)
|
||||
)),
|
||||
YANILLE_WATCHMAN(intArrayOf(34), 65, 50.0, 240.0, 137.5, 3,3,5, WeightBasedTable.create(
|
||||
WeightedItem(Items.COINS_995,60,60,1.0,true),
|
||||
WeightedItem(Items.BREAD_2309,1,1,1.0,true)
|
||||
)),
|
||||
MENAPHITE_THUG(intArrayOf(1905), 65, 50.0, 240.0, 137.5, 5,5,5, WeightBasedTable.create(
|
||||
WeightedItem(Items.COINS_995,60,60,1.0,true)
|
||||
)),
|
||||
PALADIN(intArrayOf(20, 2256), 70, 50.0, 150.0,151.75, 3,3,5, WeightBasedTable.create(
|
||||
WeightedItem(Items.COINS_995,80,80,1.0,true),
|
||||
WeightedItem(Items.CHAOS_RUNE_562,2,2,1.0,true)
|
||||
)),
|
||||
GNOME(intArrayOf(66, 67, 68, 168, 169, 2249, 2250, 2251, 2371, 2649, 2650, 6002, 6004), 75, 8.0, 120.0, 198.5, 1,1,5, WeightBasedTable.create(
|
||||
WeightedItem(Items.COINS_995,300,300,2.5),
|
||||
WeightedItem(Items.EARTH_RUNE_557,1,1,3.5),
|
||||
WeightedItem(Items.GOLD_ORE_445,1,1,1.0),
|
||||
WeightedItem(Items.FIRE_ORB_569,1,1,5.0),
|
||||
WeightedItem(Items.SWAMP_TOAD_2150,1,1,8.0),
|
||||
WeightedItem(Items.KING_WORM_2162,1,1,9.0)
|
||||
)),
|
||||
HERO(intArrayOf(21), 80, 6.0, 100.0,273.3, 6,6,4, WeightBasedTable.create(
|
||||
WeightedItem(Items.COINS_995,200,300,1.5),
|
||||
WeightedItem(Items.DEATH_RUNE_560,2,2,1.0),
|
||||
WeightedItem(Items.BLOOD_RUNE_565,1,1,0.5),
|
||||
WeightedItem(Items.FIRE_ORB_569,1,1,2.5),
|
||||
WeightedItem(Items.DIAMOND_1601,1,1,2.0),
|
||||
WeightedItem(Items.GOLD_ORE_444,1,1,1.5),
|
||||
WeightedItem(Items.JUG_OF_WINE_1993,1,1,3.0)
|
||||
));
|
||||
|
||||
|
||||
companion object {
|
||||
val idMap = HashMap<Int,Pickpockets>(values().size * 5)
|
||||
|
||||
init {
|
||||
values().forEach {
|
||||
it.ids.forEach { id -> idMap[id] = it }
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun forID(id: Int): Pickpockets? {
|
||||
return idMap[id]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun getSuccessChance(player: Player): Double{
|
||||
return RandomFunction.getSkillSuccessChance(low,high,player.skills.getLevel(Skills.THIEVING))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package content.global.skill.thieving;
|
||||
|
||||
import core.game.node.item.Item;
|
||||
import core.game.node.scenery.Scenery;
|
||||
import core.tools.RandomFunction;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Represents a thieving stall.
|
||||
* @author Ceikry, Woahscam
|
||||
*/
|
||||
public enum Stall {
|
||||
VEGETABLE_STALL(new Integer[]{4706, 4708}, new Integer[] { 634 }, 2, new Item[]{new Item(1957, 1), new Item(1965, 1), new Item(1942, 1), new Item(1982, 1), new Item(1550, 1)}, 10, 4,"vegetables"),
|
||||
BAKER_STALL(new Integer[]{2561, 6163, 34384}, new Integer[] { 634, 6984, 34381 }, 5, new Item[]{new Item(1891, 1), new Item(2309, 1), new Item(1901, 1)}, 16, 4,"pastries"),
|
||||
CRAFTING_STALL(new Integer[]{4874, 6166}, new Integer[] { 4797, 6984 }, 5, new Item[]{new Item(1592, 1), new Item(1597, 1), new Item(1755, 1)}, 16, 12,"crafting supplies"),
|
||||
TEA_STALL(new Integer[]{635, 6574}, new Integer[] { 634, 6573 }, 5, new Item[]{new Item(712, 1)}, 16, 12,"tea"),
|
||||
SILK_STALL(new Integer[]{34383, 2560}, new Integer[] { 34381, 634 }, 20, new Item[]{new Item(950, 1)}, 24, 13,"silk"),
|
||||
WINE_STALL(new Integer[]{2046}, new Integer[] { 634 }, 22, new Item[]{new Item(1935, 1), new Item(1937, 1), new Item(1993, 1), new Item(7919, 1)}, 27, 27,"wine"), //OBJECT MISSING IN CACHE
|
||||
MARKET_SEED_STALL(new Integer[]{7053}, new Integer[] { 634 }, 27, new Item[]{new Item(5096, 1), new Item(5097, 1), new Item(5101, 1), new Item(5318, 1), new Item(5319, 1), new Item(5324, 1)}, 10, 19,"seeds"),
|
||||
FUR_STALL(new Integer[]{ 34387, 2563, 4278}, new Integer[] { 34381, 634, 634 }, 35, new Item[]{new Item(6814, 1), new Item(958, 1)}, 36, 25,"fur"),
|
||||
FISH_STALL(new Integer[]{ 4277, 4705, 4707 }, new Integer[] { 634, 634, 634 }, 42, new Item[]{new Item(331, 1), new Item(359, 1), new Item(377, 1)}, 42, 27,"fish"),
|
||||
CROSSBOW_STALL(new Integer[]{17031}, new Integer[] { 6984 }, 49, new Item[]{new Item(877, 3), new Item(9420, 1), new Item(9440, 1)}, 52, 19,"equipment"),
|
||||
SILVER_STALL(new Integer[]{2565, 6164, 34382}, new Integer[] { 634, 6984, 34381}, 50, new Item[]{new Item(442, 1)}, 54, 50,"jewellery"),
|
||||
SPICE_STALL(new Integer[]{34386, 6166}, new Integer[] { 34381, 6984 }, 65, new Item[]{new Item(2007, 1)}, 81, 134,"spices"),
|
||||
GEM_STALL(new Integer[]{2562, 6162, 34385}, new Integer[] { 634, 6984, 34381 }, 75, new Item[]{new Item(1623, 1), new Item(1605, 1), new Item(1603, 1), new Item(1601, 1)}, 160, 300,"gems"),
|
||||
//Ape Atoll Stalls
|
||||
SCIMITAR_STALL(new Integer[]{4878}, new Integer[] { 4797 }, 65, new Item[]{new Item(1323, 1)}, 100, 134,"equipment"),
|
||||
MAGIC_STALL(new Integer[]{4877}, new Integer[] { 4797 }, 65, new Item[]{new Item(556, 1), new Item(557, 1), new Item(554, 1), new Item(555, 1), new Item(563, 1)}, 100, 134,"equipment"),
|
||||
GENERAL_STALL(new Integer[]{4876}, new Integer[] { 4797 }, 5, new Item[]{new Item(1931, 1), new Item(2347, 1), new Item(590, 1)}, 16, 12,"goods"),
|
||||
FOOD_STALL(new Integer[]{4875}, new Integer[] { 4797 }, 5, new Item[]{new Item(1963, 1)}, 16, 12,"food");
|
||||
//CRAFTING_STALL (Ape Atoll) shares same drops/exp as regular crafting stall
|
||||
|
||||
//Quest Stalls Rocking Out
|
||||
//CUSTOMS_EVIDENCE_FILES(new Integer[]{FIND OBJ ID}, FIND OBJ EMPTY ID, 63, new Item[]{new Item(1333, 1), new Item(1617, 1), new Item(1619, 1), new Item(1623, 1), new Item(385, 1), new Item(2359, 1), new Item(2357, 1), new Item(2351, 1), new Item(7114, 1), new Item(7134, 1), new Item(1025, 1), new Item(1281, 1), new Item(1325, 1), new Item(1323, 1), new Item(1321, 1), new Item(995, 300)}, 75, 100);
|
||||
|
||||
public static HashMap<Integer,Stall> idMap = new HashMap<>();
|
||||
static{
|
||||
Arrays.stream(Stall.values()).forEach(entry -> entry.full_ids.stream().forEach(id -> idMap.putIfAbsent(id, entry)));
|
||||
}
|
||||
|
||||
List<Integer> full_ids;
|
||||
List<Integer> empty_ids;
|
||||
int level, delay;
|
||||
Item[] rewards;
|
||||
double experience;
|
||||
String msgItem;
|
||||
|
||||
Stall(Integer[] full_ids, Integer[] empty_ids, int level, Item[] rewards, double experience, int delay, String msgItem) {
|
||||
this.full_ids = new ArrayList<Integer>(Arrays.asList(full_ids));
|
||||
this.empty_ids = new ArrayList<Integer>(Arrays.asList(empty_ids));
|
||||
this.level = level;
|
||||
this.delay = delay;
|
||||
this.rewards = rewards;
|
||||
this.experience = experience;
|
||||
this.msgItem = msgItem;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public List<Integer> getFullIDs() {
|
||||
return full_ids;
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public Item[] getRewards() {
|
||||
return rewards;
|
||||
}
|
||||
|
||||
public double getExperience() {
|
||||
return experience;
|
||||
}
|
||||
|
||||
public int getEmpty(int id) {
|
||||
int fullIndex = full_ids.indexOf(id);
|
||||
return this.empty_ids.get(fullIndex);
|
||||
}
|
||||
|
||||
public int getDelay() {
|
||||
return delay;
|
||||
}
|
||||
|
||||
public Item getRandomLoot() {
|
||||
return rewards[RandomFunction.random(rewards.length)];
|
||||
}
|
||||
|
||||
public static Stall forObject(final Scenery object) {
|
||||
return idMap.get(object.getId());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
package content.global.skill.thieving;
|
||||
|
||||
import core.game.node.entity.skill.SkillPulse;
|
||||
import core.game.node.entity.skill.Skills;
|
||||
import core.game.node.entity.npc.NPC;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.item.Item;
|
||||
import core.game.node.scenery.Scenery;
|
||||
import core.game.node.scenery.SceneryBuilder;
|
||||
import core.game.world.GameWorld;
|
||||
import core.game.world.map.RegionManager;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
import core.tools.RandomFunction;
|
||||
import core.tools.StringUtils;
|
||||
|
||||
import static core.api.ContentAPIKt.*;
|
||||
|
||||
/**
|
||||
* Represents the pulse used to thieve a stall.
|
||||
* @author 'Vexia
|
||||
*/
|
||||
public final class StallThiefPulse extends SkillPulse<Scenery> {
|
||||
|
||||
/**
|
||||
* Represents the stealing animation.
|
||||
*/
|
||||
private static final Animation ANIMATION = new Animation(832);
|
||||
|
||||
/**
|
||||
* Represents the stall being thieved.
|
||||
*/
|
||||
private final Stall stall;
|
||||
|
||||
/**
|
||||
* Represents the ticks passed.
|
||||
*/
|
||||
private int ticks;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code StallThiefPulse} {@code Object}.
|
||||
* @param player the player.
|
||||
* @param node the node.
|
||||
* @param stall the stall.
|
||||
*/
|
||||
public StallThiefPulse(Player player, Scenery node, final Stall stall) {
|
||||
super(player, node);
|
||||
this.stall = stall;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
player.setAttribute("thieveDelay", GameWorld.getTicks());
|
||||
super.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkRequirements() {
|
||||
if (stall == null) {
|
||||
return false;
|
||||
}
|
||||
if (player.inCombat()) {
|
||||
player.getPacketDispatch().sendMessage("You cant steal from the market stall during combat!");
|
||||
return false;
|
||||
}
|
||||
if (player.getSkills().getLevel(Skills.THIEVING) < stall.getLevel()) {
|
||||
player.getPacketDispatch().sendMessage("You need to be level " + stall.getLevel() + " to steal from the " + node.getName().toLowerCase() + ".");
|
||||
return false;
|
||||
}
|
||||
if (player.getInventory().freeSlots() == 0) {
|
||||
player.getPacketDispatch().sendMessage("You don't have enough inventory space.");
|
||||
return false;
|
||||
}
|
||||
if (player.getLocation().isInRegion(10553) && !isQuestComplete(player, "Fremennik Trials") && stall.full_ids.contains(4278)) {
|
||||
sendDialogue(player, "The fur trader is staring at you suspiciously. You cannot steal from his stall while he distrusts you.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (player.getLocation().isInRegion(10553) && !isQuestComplete(player, "Fremennik Trials") && stall.full_ids.contains(4277)) {
|
||||
sendDialogue(player, "The fishmonger is staring at you suspiciously. You cannot steal from his stall while he distrusts you.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasInactiveNode() {
|
||||
if (player.getAttribute("thieveDelay", 0) <= GameWorld.getTicks()) {
|
||||
return false;
|
||||
}
|
||||
return super.hasInactiveNode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void animate() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean reward() {
|
||||
if (ticks == 0) {
|
||||
player.animate(ANIMATION);
|
||||
player.getLocks().lockInteractions(2);
|
||||
}
|
||||
if (++ticks % 3 != 0) {
|
||||
return false;
|
||||
}
|
||||
final boolean success = success();
|
||||
if (success) {
|
||||
if (stall == Stall.SILK_STALL) {
|
||||
player.getSavedData().getGlobalData().setSilkSteal(System.currentTimeMillis() + 1800000);
|
||||
}
|
||||
if (node.isActive()) {
|
||||
SceneryBuilder.replace(node, node.transform(stall.getEmpty(node.getId())), stall.getDelay());
|
||||
}
|
||||
final Item item = stall.getRandomLoot();
|
||||
player.getInventory().add(item);
|
||||
player.getSkills().addExperience(Skills.THIEVING, stall.getExperience(), true);
|
||||
if (item.getId() == 1987) {
|
||||
player.getPacketDispatch().sendMessage("You steal grapes from the grape stall.");
|
||||
return true;
|
||||
}
|
||||
player.getPacketDispatch().sendMessage("You steal " + (StringUtils.isPlusN(item.getName()) ? "an" : "a") + " " + item.getName().toLowerCase() + " from the " + stall.name().toLowerCase().replace('_',' ') + ".");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void message(int type) {
|
||||
switch (type) {
|
||||
case 0:
|
||||
player.getPacketDispatch().sendMessage("You attempt to steal some " + stall.msgItem + " from the " + stall.name().toLowerCase().replace('_',' '));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the thief is successful.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
private boolean success() {
|
||||
int mod = 0;
|
||||
if (RandomFunction.random(15 + mod) < 4) {
|
||||
for (NPC npc : RegionManager.getLocalNpcs(player.getLocation(), 8)) {
|
||||
if (!npc.getProperties().getCombatPulse().isAttacking() && (npc.getId() == 32 || npc.getId() == 2236)) {
|
||||
npc.sendChat("Hey! Get your hands off there!");
|
||||
npc.getProperties().getCombatPulse().attack(player);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,280 @@
|
||||
package content.global.skill.thieving;
|
||||
|
||||
import core.cache.def.impl.SceneryDefinition;
|
||||
import core.game.node.entity.skill.Skills;
|
||||
import core.game.interaction.OptionHandler;
|
||||
import core.game.node.Node;
|
||||
import core.game.node.entity.combat.ImpactHandler.HitsplatType;
|
||||
import core.game.node.entity.player.Player;
|
||||
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.update.flag.context.Animation;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* Handles the thieving of chests.
|
||||
* @author Vexia
|
||||
*/
|
||||
@Initializable
|
||||
public final class ThievableChestPlugin extends OptionHandler {
|
||||
/**
|
||||
* The lock pick item.
|
||||
*/
|
||||
private static final Item LOCK_PICK = new Item(1523);
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
|
||||
for (Chest chest : Chest.values()) {
|
||||
for (int id : chest.getObjectIds()) {
|
||||
SceneryDefinition def = SceneryDefinition.forId(id);
|
||||
def.getHandlers().put("option:open", this);
|
||||
def.getHandlers().put("option:search for traps", this);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(Player player, Node node, String option) {
|
||||
final Chest chest = Chest.forId(node.getId());
|
||||
switch (option) {
|
||||
case "open":
|
||||
if (chest != null) {
|
||||
chest.open(player, (Scenery) node);
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
case "search for traps":
|
||||
chest.searchTraps(player, (Scenery) node);
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a thievable chest.
|
||||
* @author Vexia
|
||||
*/
|
||||
public static enum Chest {
|
||||
TEN_COIN(2566, 13, 7.8, new Item[] { new Item(995, 10) }, 7), NATURE_RUNE(2567, 28, 25, new Item[] { new Item(995, 3), new Item(561, 1) }, 8), FIFTY_COIN(2568, 43, 125, new Item[] { new Item(995, 50) }, 55), STEEL_ARROWHEADS(2573, 47, 150, new Item[] { new Item(41, 5) }, 210), BLOOD_RUNES(2569, 59, 250, new Item[] { new Item(995, 500), new Item(565, 2) }, 135), PALADIN(2570, 72, 500, new Item[] { new Item(995, 1000), new Item(383, 1), new Item(449, 1), new Item(1623, 1) }, 120);
|
||||
|
||||
/**
|
||||
* The object id.
|
||||
*/
|
||||
private final int[] objectIds;
|
||||
|
||||
/**
|
||||
* The level required.
|
||||
*/
|
||||
private final int level;
|
||||
|
||||
/**
|
||||
* The experience gained.
|
||||
*/
|
||||
private final double experience;
|
||||
|
||||
/**
|
||||
* The rewards.
|
||||
*/
|
||||
private final Item[] rewards;
|
||||
|
||||
/**
|
||||
* The respawn time.
|
||||
*/
|
||||
private final int respawn;
|
||||
|
||||
/**
|
||||
* The current respawn time.
|
||||
*/
|
||||
private int currentRespawn;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Chest} {@code Object}.
|
||||
* @param level the level.
|
||||
* @param experience the experience.
|
||||
* @param rewards the rewards.
|
||||
* @param respawn the respawn time.
|
||||
*/
|
||||
private Chest(int[] objectIds, int level, double experience, Item[] rewards, int respawn) {
|
||||
this.objectIds = objectIds;
|
||||
this.level = level;
|
||||
this.experience = experience;
|
||||
this.rewards = rewards;
|
||||
this.respawn = respawn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Chest} {@code Object}.
|
||||
* @param objectId the object id.
|
||||
* @param level the level.
|
||||
* @param experience the experience.
|
||||
* @param rewards the rewards.
|
||||
* @param respawn the respawn time.
|
||||
*/
|
||||
private Chest(int objectId, int level, double experience, Item[] rewards, int respawn) {
|
||||
this(new int[] { objectId }, level, experience, rewards, respawn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the chest for a reward.
|
||||
* @param player the player.
|
||||
* @param object the object.
|
||||
*/
|
||||
private void open(final Player player, final Scenery object) {
|
||||
if (isRespawning()) {
|
||||
player.sendMessage("It looks like this chest has already been looted.");
|
||||
return;
|
||||
}
|
||||
player.lock(2);
|
||||
player.sendMessage("You have activated a trap on the chest.");
|
||||
player.getImpactHandler().manualHit(player, getHitAmount(player), HitsplatType.NORMAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for traps on a chest.
|
||||
* @param player the player.
|
||||
* @param object the object.
|
||||
*/
|
||||
private void searchTraps(final Player player, final Scenery object) {
|
||||
player.faceLocation(object.getLocation());
|
||||
if (isRespawning()) {
|
||||
player.sendMessage("It looks like this chest has already been looted.");
|
||||
return;
|
||||
}
|
||||
player.lock();
|
||||
player.animate(Animation.create(536));
|
||||
if (player.getSkills().getLevel(Skills.THIEVING) < level) {
|
||||
player.lock(2);
|
||||
player.sendMessage("You search the chest for traps.");
|
||||
player.sendMessage("You find nothing.", 1);
|
||||
player.unlock();
|
||||
return;
|
||||
}
|
||||
if (player.getInventory().freeSlots() == 0) {
|
||||
player.getPacketDispatch().sendMessage("Not enough inventory space.");
|
||||
return;
|
||||
}
|
||||
player.sendMessage("You find a trap on the chest...");
|
||||
player.getImpactHandler().setDisabledTicks(6);
|
||||
GameWorld.getPulser().submit(new Pulse(1, player) {
|
||||
int counter;
|
||||
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
switch (++counter) {
|
||||
case 2:
|
||||
player.sendMessage("You disable the trap.");
|
||||
break;
|
||||
case 4:
|
||||
player.animate(Animation.create(536));
|
||||
player.sendMessage("You open the chest.");
|
||||
break;
|
||||
case 6:
|
||||
player.unlock();
|
||||
for (Item i : rewards) {
|
||||
player.getInventory().add(i, player);
|
||||
}
|
||||
player.sendMessage("You find treasure inside!");
|
||||
player.getSkills().addExperience(Skills.THIEVING, experience, true);
|
||||
if (object.isActive()) {
|
||||
SceneryBuilder.replace(object, object.transform(2574), 3);
|
||||
}
|
||||
setRespawn();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the respawn delay.
|
||||
*/
|
||||
public void setRespawn() {
|
||||
currentRespawn = GameWorld.getTicks() + (int) (respawn / 0.6);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the chest is respawning.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean isRespawning() {
|
||||
return currentRespawn > GameWorld.getTicks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of damage to deal.
|
||||
* @param player The player.
|
||||
* @return The amount of damage.
|
||||
*/
|
||||
protected static int getHitAmount(Player player) {
|
||||
int hit = player.getSkills().getLifepoints() / 12;
|
||||
if (hit < 2) {
|
||||
hit = 2;
|
||||
}
|
||||
return hit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a chest by the id.
|
||||
* @param id the id.
|
||||
* @return the chest.
|
||||
*/
|
||||
public static Chest forId(int id) {
|
||||
for (Chest chest : values()) {
|
||||
for (int i : chest.getObjectIds()) {
|
||||
if (i == id) {
|
||||
return chest;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the objectId.
|
||||
* @return The objectId.
|
||||
*/
|
||||
public int[] getObjectIds() {
|
||||
return objectIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the level.
|
||||
* @return The level.
|
||||
*/
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the experience.
|
||||
* @return The experience.
|
||||
*/
|
||||
public double getExperience() {
|
||||
return experience;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the rewards.
|
||||
* @return The rewards.
|
||||
*/
|
||||
public Item[] getRewards() {
|
||||
return rewards;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the respawn.
|
||||
* @return The respawn.
|
||||
*/
|
||||
public int getRespawn() {
|
||||
return respawn;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package content.global.skill.thieving
|
||||
|
||||
import core.game.node.entity.combat.ImpactHandler
|
||||
import core.game.node.entity.impl.Animator
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.player.link.audio.Audio
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.node.entity.state.EntityState
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import core.tools.RandomFunction
|
||||
import org.rs09.consts.Items
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.interaction.IntType
|
||||
import core.tools.secondsToTicks
|
||||
|
||||
class ThievingListeners : InteractionListener {
|
||||
|
||||
private val PICKPOCKET_ANIM = Animation(881,Animator.Priority.HIGH)
|
||||
private val NPC_ANIM = Animation(422)
|
||||
private val SUCCESS = Audio(2581, 1, 0)
|
||||
|
||||
override fun defineListeners() {
|
||||
|
||||
on(IntType.NPC,"pickpocket","pick-pocket"){ player, node ->
|
||||
val pickpocketData = Pickpockets.forID(node.id) ?: return@on false
|
||||
var successMod = 0
|
||||
|
||||
if(player.inCombat()){
|
||||
player.sendMessage("You can't pickpocket while in combat.")
|
||||
return@on true
|
||||
}
|
||||
|
||||
if(player.skills.getLevel(Skills.THIEVING) < pickpocketData.requiredLevel){
|
||||
player.sendMessage("You need a Thieving level of ${pickpocketData.requiredLevel} to do that.")
|
||||
return@on true
|
||||
}
|
||||
|
||||
if(!pickpocketData.table.canRoll(player)){
|
||||
player.sendMessage("You don't have enough inventory space to do that.")
|
||||
return@on true
|
||||
}
|
||||
|
||||
if(pickpocketData == Pickpockets.FEMALE_HAM_MEMBER || pickpocketData == Pickpockets.MALE_HAM_MEMBER){
|
||||
successMod += getHAMItemCount(player)
|
||||
}
|
||||
|
||||
if(player.equipment.contains(Items.GLOVES_OF_SILENCE_10075,1)){
|
||||
successMod += 3
|
||||
}
|
||||
|
||||
player.animator.animate(PICKPOCKET_ANIM)
|
||||
val chance = RandomFunction.randomDouble(1.0,100.0)
|
||||
val failThreshold = pickpocketData.getSuccessChance(player) + successMod
|
||||
|
||||
if(chance > failThreshold){
|
||||
node.asNpc().face(player)
|
||||
node.asNpc().animator.animate(NPC_ANIM)
|
||||
|
||||
val hitSoundId = 518 + RandomFunction.random(4) // choose 1 of 4 possible hit noises
|
||||
player.audioManager.send(hitSoundId, 1, 20) // OSRS defines a delay of 20
|
||||
|
||||
player.stateManager.set(EntityState.STUNNED, secondsToTicks(pickpocketData.stunTime))
|
||||
player.lock(secondsToTicks(pickpocketData.stunTime))
|
||||
|
||||
player.impactHandler.manualHit(node.asNpc(),RandomFunction.random(pickpocketData.stunDamageMin,pickpocketData.stunDamageMax),ImpactHandler.HitsplatType.NORMAL)
|
||||
|
||||
node.asNpc().face(null)
|
||||
} else {
|
||||
player.audioManager.send(SUCCESS)
|
||||
player.lock(2)
|
||||
pickpocketData.table.roll().forEach { player.inventory.add(it) }
|
||||
player.skills.addExperience(Skills.THIEVING,pickpocketData.experience)
|
||||
}
|
||||
|
||||
return@on true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun getHAMItemCount(player: Player): Int{
|
||||
var counter = 0
|
||||
for(item in player.equipment.toArray()){
|
||||
item ?: continue
|
||||
counter += when(item.id){
|
||||
Items.HAM_LOGO_4306 -> 1
|
||||
Items.HAM_ROBE_4300 -> 1
|
||||
Items.HAM_HOOD_4302 -> 1
|
||||
Items.HAM_CLOAK_4304 -> 1
|
||||
Items.BOOTS_4310 -> 1
|
||||
Items.GLOVES_4308 -> 1
|
||||
else -> 0
|
||||
}
|
||||
}
|
||||
return counter
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package content.global.skill.thieving;
|
||||
|
||||
import core.cache.def.impl.SceneryDefinition;
|
||||
import core.game.interaction.OptionHandler;
|
||||
import core.game.node.Node;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.scenery.Scenery;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* Represents the plugin used to handle thieving options.
|
||||
* @author 'Vexia
|
||||
* @date 22/10/2013
|
||||
*/
|
||||
@Initializable
|
||||
public class ThievingOptionPlugin extends OptionHandler {
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
SceneryDefinition.setOptionHandler("steal-from", this);
|
||||
SceneryDefinition.setOptionHandler("steal from", this);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(Player player, Node node, String option) {
|
||||
switch (option) {
|
||||
case "steal-from":
|
||||
case "steal from":
|
||||
player.getPulseManager().run(new StallThiefPulse(player, (Scenery) node, Stall.forObject((Scenery) node)));
|
||||
player.getLocks().lockInteractions(6);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user