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,37 @@
|
||||
package content.global.skill.hunter;
|
||||
|
||||
import core.game.node.entity.skill.Skills;
|
||||
import core.game.node.entity.npc.NPC;
|
||||
import core.game.node.item.Item;
|
||||
|
||||
/**
|
||||
* Handles the box trap node.
|
||||
* @author Vexia
|
||||
*/
|
||||
public final class BoxTrapNode extends TrapNode {
|
||||
|
||||
/**
|
||||
* The summoning level required.
|
||||
*/
|
||||
private final int summoningLevel;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code BoxTrapNode} {@code Object}.
|
||||
* @param npcIds the npc ids.
|
||||
* @param level the level.
|
||||
* @param experience the experience.
|
||||
* @param rewards the rewards.
|
||||
*/
|
||||
public BoxTrapNode(int[] npcIds, int level, double experience, Item[] rewards, final int summoningLevel) {
|
||||
super(npcIds, level, experience, new int[] { 19188, 19189 }, rewards);
|
||||
this.summoningLevel = summoningLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCatch(TrapWrapper wrapper, final NPC npc) {
|
||||
if (wrapper.getPlayer().getSkills().getStaticLevel(Skills.SUMMONING) < summoningLevel) {
|
||||
return false;
|
||||
}
|
||||
return super.canCatch(wrapper, npc);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
package content.global.skill.hunter;
|
||||
|
||||
import content.global.skill.firemaking.Log;
|
||||
import core.game.node.Node;
|
||||
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.map.Direction;
|
||||
import core.game.world.map.Location;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Handles a deadfall trap.
|
||||
* @author Vexia
|
||||
*/
|
||||
public final class DeadfallSetting extends TrapSetting {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code DeadfallSetting} {@code Object}.
|
||||
*/
|
||||
public DeadfallSetting() {
|
||||
super(new int[] { 28935, 19205 },
|
||||
new Item[] { new Item(946) },
|
||||
new int[] { 28937, 19206 },
|
||||
new int[] { 10138, 6006, 12574, 341, 2132 },
|
||||
"set-trap", 23, -1, new Animation(5208), new Animation(9726), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasItems(Player player) {
|
||||
if (!super.hasItems(player)) {
|
||||
player.getPacketDispatch().sendMessage("You need a knife in order to set a deadfall trap.");
|
||||
return false;
|
||||
}
|
||||
for (Log log : Log.values()) {
|
||||
if (player.getInventory().contains(log.getLogId(), 1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
player.getPacketDispatch().sendMessage("You need logs in order to set a deadfall trap.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrapHook createHook(TrapWrapper wrapper) {
|
||||
return new TrapHook(wrapper, getLocations(wrapper.getObject()).toArray(new Location[] {}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reward(Player player, Node node, TrapWrapper wrapper) {
|
||||
player.getInventory().remove(new Item(getLog(player).getLogId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clear(TrapWrapper wrapper, int type) {
|
||||
if (super.clear(wrapper, type)) {
|
||||
SceneryBuilder.add(wrapper.getObject().transform(getNodeForObjectId(wrapper.isCaught() ? wrapper.getOriginalId() : wrapper.getObject().getId())));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCatch(TrapWrapper wrapper, NPC npc) {
|
||||
int x = wrapper.getObject().getLocation().getX(), y = wrapper.getObject().getLocation().getY();
|
||||
Direction direction = wrapper.getObject().getDirection();
|
||||
int dir = 0;
|
||||
if (direction == Direction.NORTH) {
|
||||
if (npc.getLocation().getY() < y) {
|
||||
dir = 1;
|
||||
} else {
|
||||
dir = 0;
|
||||
}
|
||||
} else if (direction == Direction.SOUTH) {
|
||||
if (npc.getLocation().getY() < y) {
|
||||
dir = 0;
|
||||
} else {
|
||||
dir = 1;
|
||||
}
|
||||
} else if (direction == Direction.WEST) {
|
||||
if (npc.getLocation().getX() > x) {
|
||||
dir = 1;
|
||||
} else {
|
||||
dir = 0;
|
||||
}
|
||||
} else {
|
||||
if (npc.getLocation().getX() > x) {
|
||||
dir = 0;
|
||||
} else {
|
||||
dir = 1;
|
||||
}
|
||||
}
|
||||
npc.faceLocation(wrapper.getObject().getLocation());
|
||||
wrapper.getObject().getAttributes().setAttribute("kebbit-dir", dir);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuccess(Player player, final TrapNode node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTransformId(TrapWrapper wrapper, TrapNode node) {
|
||||
int dir = wrapper.getObject().getAttributes().getAttribute("kebbit-dir", 0);
|
||||
int id = dir == 0 ? node.getObjectIds()[0] : node.getObjectIds()[1];
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFinalId(TrapWrapper wrapper, TrapNode node) {
|
||||
return node.getObjectIds()[2];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Scenery buildObject(Player player, Node node) {
|
||||
return node.asScenery().transform(getObjectForNode(node));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLimitMessage(Player player) {
|
||||
return "You can only have one deadfall trap at a time.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exceedsLimit(Player player) {
|
||||
return HunterManager.getInstance(player).getTrapAmount() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of locations.
|
||||
* @return the locations.
|
||||
*/
|
||||
private List<Location> getLocations(Scenery object) {
|
||||
List<Location> locs = new ArrayList<>(20);
|
||||
if (object.getDirection() == Direction.NORTH) {
|
||||
locs.add(object.getLocation().transform(1, -1, 0));
|
||||
locs.add(object.getLocation().transform(1, 1, 0));
|
||||
} else if (object.getDirection() == Direction.SOUTH) {
|
||||
locs.add(object.getLocation().transform(0, 1, 0));
|
||||
locs.add(object.getLocation().transform(0, -1, 0));
|
||||
} else if (object.getDirection() == Direction.WEST) {
|
||||
locs.add(object.getLocation().transform(1, 1, 0));
|
||||
locs.add(object.getLocation().transform(-1, 1, 0));
|
||||
} else {
|
||||
locs.add(object.getLocation().transform(-1, 0, 0));
|
||||
locs.add(object.getLocation().transform(1, 0, 0));
|
||||
}
|
||||
return locs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the log the player has.
|
||||
* @param player the player.
|
||||
* @return the log.
|
||||
*/
|
||||
private Log getLog(Player player) {
|
||||
for (Log log : Log.values()) {
|
||||
if (player.getInventory().contains(log.getLogId(), 1)) {
|
||||
return log;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
package content.global.skill.hunter;
|
||||
|
||||
import content.global.skill.hunter.falconry.FalconryCatchPulse;
|
||||
import core.cache.def.impl.ItemDefinition;
|
||||
import core.cache.def.impl.NPCDefinition;
|
||||
import core.game.activity.ActivityPlugin;
|
||||
import core.game.node.entity.skill.Skills;
|
||||
import content.global.skill.hunter.falconry.FalconCatch;
|
||||
import core.game.interaction.Option;
|
||||
import core.game.interaction.OptionHandler;
|
||||
import core.game.node.Node;
|
||||
import core.game.node.entity.Entity;
|
||||
import core.game.node.entity.npc.NPC;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.entity.player.link.HintIconManager;
|
||||
import core.game.node.item.Item;
|
||||
import core.game.world.map.Location;
|
||||
import core.game.world.map.zone.ZoneBorders;
|
||||
import core.plugin.Plugin;
|
||||
import core.plugin.ClassScanner;
|
||||
|
||||
/**
|
||||
* Represents the activity used during falconry practice.
|
||||
* @author Vexia
|
||||
*/
|
||||
public final class FalconryActivityPlugin extends ActivityPlugin {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code FalconryActivityPlugin} {@code Object}.
|
||||
*/
|
||||
public FalconryActivityPlugin() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code FalconryActivityPlugin} {@code Object}.
|
||||
* @param player the player.
|
||||
*/
|
||||
public FalconryActivityPlugin(final Player player) {
|
||||
super("falconry", true, false, false);
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActivityPlugin newInstance(Player p) throws Throwable {
|
||||
return new FalconryActivityPlugin(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start(final Player player, boolean login, Object... args) {
|
||||
player.setAttribute("/save:falconry", true);
|
||||
return super.start(player, login, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean leave(final Entity entity, boolean logout) {
|
||||
if (!(entity instanceof Player)) {
|
||||
return super.leave(entity, logout);
|
||||
}
|
||||
if (entity instanceof Player) {
|
||||
if (!logout) {
|
||||
((Player) entity).removeAttribute("falconry");
|
||||
removeItems((Player) entity);
|
||||
}
|
||||
}
|
||||
return super.leave(entity, logout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to remove the items.
|
||||
*/
|
||||
public static void removeItems(final Player player) {
|
||||
player.getInventory().remove(new Item(10023, player.getInventory().getAmount(new Item(10023))));
|
||||
player.getInventory().remove(new Item(10024, player.getInventory().getAmount(new Item(10024))));
|
||||
player.getEquipment().remove(new Item(10023));
|
||||
player.getEquipment().remove(new Item(10024));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean teleport(final Entity entity, int type, Node node) {
|
||||
removeItems((Player) entity);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean interact(final Entity e, Node target, Option option) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getSpawnLocation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure() {
|
||||
register(new ZoneBorders(2360, 3571, 2396, 3637));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register() {
|
||||
ClassScanner.definePlugin(new FalconryPlugin());
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the falconry plugin.
|
||||
* @author Vexia
|
||||
*/
|
||||
public static final class FalconryPlugin extends OptionHandler {
|
||||
|
||||
/**
|
||||
* Represents the bones.
|
||||
*/
|
||||
private static final Item BONES = new Item(526);
|
||||
|
||||
/**
|
||||
* Represents the falcon item.
|
||||
*/
|
||||
private static final Item FALCON = new Item(10024);
|
||||
|
||||
/**
|
||||
* Represents the falcon glove.
|
||||
*/
|
||||
private static final Item GLOVE = new Item(10023);
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
NPCDefinition.forId(5093).getHandlers().put("option:quick-falconry", this);
|
||||
NPCDefinition.forId(5094).getHandlers().put("option:retrieve", this);
|
||||
for (FalconCatch falconCatch : FalconCatch.values()) {
|
||||
NPCDefinition.forId(falconCatch.getNpc()).getHandlers().put("option:catch", this);
|
||||
}
|
||||
ClassScanner.definePlugin(new Plugin<Object>() {
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
ItemDefinition.forId(10024).getHandlers().put("equipment", this);
|
||||
ItemDefinition.forId(10023).getHandlers().put("equipment", this);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object fireEvent(String identifier, Object... args) {
|
||||
final Player player = (Player) args[0];
|
||||
switch (identifier) {
|
||||
case "unequip":
|
||||
if (player.getZoneMonitor().isInZone("falconry")) {
|
||||
player.getDialogueInterpreter().sendDialogue("Leave the area in order to remove your falcon.");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(Player player, Node node, String option) {
|
||||
switch (option) {
|
||||
case "quick-falconry":
|
||||
player.getDialogueInterpreter().open(5093, null, true);
|
||||
break;
|
||||
case "catch":
|
||||
player.face(((NPC) node));
|
||||
player.getPulseManager().run(new FalconryCatchPulse(player, ((NPC) node), FalconCatch.forNPC(((NPC) node))));
|
||||
break;
|
||||
case "retrieve":
|
||||
final NPC npc = ((NPC) node);
|
||||
if (!npc.getAttribute("falcon:owner", "").equals(player.getUsername())) {
|
||||
player.getPacketDispatch().sendMessage("This isn't your falcon.");
|
||||
return true;
|
||||
}
|
||||
if (player.getInventory().freeSlots() == 0) {
|
||||
player.getPacketDispatch().sendMessage("You don't have enough inventory space.");
|
||||
return true;
|
||||
}
|
||||
npc.clear();
|
||||
HintIconManager.removeHintIcon(player, 1);
|
||||
final FalconCatch falconCatch = npc.getAttribute("falcon:catch");
|
||||
player.getSkills().addExperience(Skills.HUNTER, falconCatch.getExperience(), true);
|
||||
player.getPacketDispatch().sendMessage("You retrieve the falcon as well as the fur of the dead kebbit.");
|
||||
player.getInventory().add(falconCatch.getItem());
|
||||
player.getInventory().add(BONES);
|
||||
if (player.getEquipment().remove(GLOVE)) {
|
||||
player.getEquipment().add(FALCON, true, false);
|
||||
} else {
|
||||
player.getInventory().remove(GLOVE);
|
||||
player.getInventory().add(FALCON);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWalk() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWalk(final Player player, Node node) {
|
||||
if (node instanceof NPC) {
|
||||
final NPC n = ((NPC) node);
|
||||
if (n.getId() == 5093 || n.getId() == 5094) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package content.global.skill.hunter;
|
||||
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.item.Item;
|
||||
|
||||
/**
|
||||
* Represents a set of hunter gear.
|
||||
* @author Vexia
|
||||
*/
|
||||
public enum HunterGear {
|
||||
GLOVE_OF_SILENCE(3.0, new Item(10075)), SPOTIER_CAPE(5.0, new Item(10071)), SPOTTED_CAPE(5.0, new Item(10069)), LARUPIA(10.00, new Item(10045), new Item(10043), new Item(10041)), DESERT_GEAR(10.00, new Item(12568), new Item(10063), new Item(10061)), GRAAHK_GEAR(10.00, new Item(10051), new Item(10047), new Item(10049)), KYATT_GEAR(10.00, new Item(10039), new Item(10035), new Item(10037)), JUNGLE_GEAR(8.00, new Item(10059), new Item(10057)), POLAR_GEAR(8.00, new Item(10065), new Item(10067));
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Trap} {@code Object}.
|
||||
* @param equipment the equipment.
|
||||
* @param chanceRate the rate.
|
||||
*/
|
||||
HunterGear(double chanceRate, Item... equipment) {
|
||||
this.equipment = equipment;
|
||||
this.chanceRate = chanceRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the equipment.
|
||||
*/
|
||||
private final Item[] equipment;
|
||||
|
||||
/**
|
||||
* Represents the chance it increased.
|
||||
*/
|
||||
private final double chanceRate;
|
||||
|
||||
/**
|
||||
* Method used to check if the player in the gear.
|
||||
* @param player the player.
|
||||
* @return the gear.
|
||||
*/
|
||||
public static HunterGear inGear(final Player player) {
|
||||
int contained = 0;
|
||||
for (HunterGear type : values()) {
|
||||
for (Item i : type.getEquipment()) {
|
||||
if (player.getEquipment().containsItem(i)) {
|
||||
contained += 1;
|
||||
}
|
||||
if (contained == type.getEquipment().length) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the chance rate the player has.
|
||||
* @param player the player.
|
||||
* @return the rate.
|
||||
*/
|
||||
public static double getChanceRate(Player player) {
|
||||
final HunterGear gear = inGear(player);
|
||||
if (gear == null) {
|
||||
return 0.0;
|
||||
}
|
||||
return gear.getChanceRate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the equipment.
|
||||
* @return The equipment.
|
||||
*/
|
||||
public Item[] getEquipment() {
|
||||
return equipment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the increase.
|
||||
* @return The increase.
|
||||
*/
|
||||
public double getChanceRate() {
|
||||
return chanceRate;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
package content.global.skill.hunter;
|
||||
|
||||
import core.api.LoginListener;
|
||||
import core.api.LogoutListener;
|
||||
import core.game.event.EventHook;
|
||||
import core.game.event.TickEvent;
|
||||
import core.game.node.entity.Entity;
|
||||
import core.game.node.entity.skill.Skills;
|
||||
import core.game.node.Node;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.scenery.Scenery;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import core.api.Event;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Manages the players hunter state.
|
||||
* @author Vexia
|
||||
*/
|
||||
public final class HunterManager implements LoginListener, LogoutListener, EventHook<TickEvent> {
|
||||
|
||||
/**
|
||||
* The list of active traps.
|
||||
*/
|
||||
private final List<TrapWrapper> traps = new ArrayList<>(20);
|
||||
|
||||
/**
|
||||
* The player instance.
|
||||
*/
|
||||
private final Player player;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code HunterManager} {@code Object}.
|
||||
* @param player the player.
|
||||
*/
|
||||
public HunterManager(final Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public HunterManager() {
|
||||
this.player = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void login(@NotNull Player player) {
|
||||
HunterManager instance = new HunterManager(player);
|
||||
player.hook(Event.getTick(), instance);
|
||||
player.setAttribute("hunter-manager", instance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout(@NotNull Player player) {
|
||||
HunterManager instance = getInstance(player);
|
||||
if (instance == null) return;
|
||||
Iterator<TrapWrapper> iterator = instance.traps.iterator();
|
||||
TrapWrapper wrapper = null;
|
||||
while (iterator.hasNext()) {
|
||||
wrapper = iterator.next();
|
||||
if (wrapper.getType().getSettings().clear(wrapper, 0)) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(@NotNull Entity entity, @NotNull TickEvent event) {
|
||||
if (traps.size() == 0) {
|
||||
return;
|
||||
}
|
||||
Iterator<TrapWrapper> iterator = traps.iterator();
|
||||
TrapWrapper wrapper = null;
|
||||
while (iterator.hasNext()) {
|
||||
wrapper = iterator.next();
|
||||
if (wrapper.cycle()) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a hunting trap.
|
||||
* @param trap the trap.
|
||||
* @param node the node.
|
||||
* @param object the object.
|
||||
* @return {@code True} if registered.
|
||||
*/
|
||||
public boolean register(Traps trap, Node node, final Scenery object) {
|
||||
final TrapWrapper wrapper = new TrapWrapper(player, trap, object);
|
||||
trap.getSettings().reward(player, node, wrapper);
|
||||
wrapper.setHook(trap.addHook(wrapper));
|
||||
return traps.add(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the wrapper from the registar.
|
||||
* @param wrapper the wrapper.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean deregister(final TrapWrapper wrapper) {
|
||||
return traps.remove(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if they're the owner of the trap.
|
||||
* @param object the object.
|
||||
* @return {@code True} if they're the owner.
|
||||
*/
|
||||
public boolean isOwner(Scenery object) {
|
||||
return getUid(object) == getUid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the wrapper.
|
||||
* @param object the object.
|
||||
* @return the wrapper.
|
||||
*/
|
||||
public TrapWrapper getWrapper(Scenery object) {
|
||||
for (TrapWrapper wrapper : traps) {
|
||||
if (wrapper.getObject() == object || (wrapper.getSecondary() != null && wrapper.getSecondary() == object)) {
|
||||
return wrapper;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player exceeds the trap limit.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean exceedsTrapLimit(Traps trap) {
|
||||
if (trap.getSettings().exceedsLimit(player)) {
|
||||
return true;
|
||||
}
|
||||
return traps.size() + 1 > getMaximumTraps();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the trap amount.
|
||||
* @return the trap amount.
|
||||
*/
|
||||
public int getTrapAmount() {
|
||||
return traps.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum amount of traps.
|
||||
* @return the traps.
|
||||
*/
|
||||
public int getMaximumTraps() {
|
||||
final int level = getStaticLevel();
|
||||
return level >= 80 ? 5 : level >= 60 ? 4 : level >= 40 ? 3 : level >= 20 ? 2 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the uid of a trap.
|
||||
* @param object the object.
|
||||
* @return the uid.
|
||||
*/
|
||||
public int getUid(Scenery object) {
|
||||
return object.getAttributes().getAttribute("trap-uid", 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the uid of this manager.
|
||||
* @return the manager.
|
||||
*/
|
||||
public int getUid() {
|
||||
return player.getName().hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the static level.
|
||||
* @return the level.
|
||||
*/
|
||||
public int getStaticLevel() {
|
||||
return player.getSkills().getStaticLevel(Skills.HUNTER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player.
|
||||
* @return The player.
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the traps.
|
||||
* @return The traps.
|
||||
*/
|
||||
public List<TrapWrapper> getTraps() {
|
||||
return traps;
|
||||
}
|
||||
|
||||
public static HunterManager getInstance(Player player)
|
||||
{
|
||||
return player.getAttribute("hunter-manager");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
package content.global.skill.hunter;
|
||||
|
||||
import core.api.ContentAPIKt;
|
||||
import core.game.node.entity.Entity;
|
||||
import core.game.node.entity.combat.BattleState;
|
||||
import core.game.node.entity.npc.AbstractNPC;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.entity.player.link.TeleportManager;
|
||||
import org.rs09.consts.NPCs;
|
||||
import core.game.world.GameWorld;
|
||||
import core.game.world.map.Location;
|
||||
import core.tools.RandomFunction;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static core.api.ContentAPIKt.getPathableRandomLocalCoordinate;
|
||||
import static core.api.ContentAPIKt.sendGraphics;
|
||||
|
||||
/**
|
||||
* Handles a hunter npc.
|
||||
* @author Vexia
|
||||
*/
|
||||
public final class HunterNPC extends AbstractNPC {
|
||||
|
||||
private static final int IMP_TELEPORT_CHANCE_ON_HIT = 10; // 1/10
|
||||
private static final int IMP_TELEPORT_CHANCE_ON_TICK = 1000; // 1/75
|
||||
|
||||
/**
|
||||
* The trap type.
|
||||
*/
|
||||
private final Traps trap;
|
||||
|
||||
/**
|
||||
* The trap type node.
|
||||
*/
|
||||
private final TrapNode type;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code HunterNPC} {@code Object}.
|
||||
*/
|
||||
public HunterNPC() {
|
||||
this(0, null, null, null);
|
||||
this.setWalks(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code HunterNPC} {@code Object}.
|
||||
* @param id the id.
|
||||
* @param location the location.
|
||||
* @param trap the trap.
|
||||
* @param type the type.
|
||||
*/
|
||||
public HunterNPC(int id, Location location, Traps trap, TrapNode type) {
|
||||
super(id, location);
|
||||
this.trap = trap;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractNPC construct(int id, Location location, Object... objects) {
|
||||
Object[] data = Traps.getNode(id);
|
||||
return new HunterNPC(id, location, (Traps) data[0], (TrapNode) data[1]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLocation(Location last) {
|
||||
final TrapWrapper wrapper = trap.getByHook(getLocation());
|
||||
if (wrapper != null) {
|
||||
wrapper.getType().catchNpc(wrapper, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Location getMovementDestination() {
|
||||
if (trap.getHooks().size() == 0 || RandomFunction.random(170) > 5) {
|
||||
return super.getMovementDestination();
|
||||
}
|
||||
TrapHook hook = trap.getHooks().get(RandomFunction.random(trap.getHooks().size()));
|
||||
if (hook == null || !type.canCatch(hook.getWrapper(), this)) {
|
||||
return super.getMovementDestination();
|
||||
}
|
||||
Location destination = hook.getChanceLocation();
|
||||
return destination != null && destination.getDistance(getLocation()) <= 24 ? destination : super.getMovementDestination();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleDrops(Player p, Entity killer) {
|
||||
int ticks = getAttribute("hunter", 0);
|
||||
if (ticks < GameWorld.getTicks()) {
|
||||
super.handleDrops(p, killer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getIds() {
|
||||
List<Integer> ids = new ArrayList<>(10);
|
||||
for (Traps t : Traps.values()) {
|
||||
for (TrapNode node : t.getNodes()) {
|
||||
for (int id : node.getNpcIds()) {
|
||||
ids.add(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
int[] array = new int[ids.size()];
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
array[i] = ids.get(i);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkImpact(BattleState state) {
|
||||
super.checkImpact(state);
|
||||
|
||||
if (this.getId() == NPCs.IMP_708 || this.getId() == NPCs.IMP_709 || this.getId() == NPCs.IMP_1531) {
|
||||
if (RandomFunction.roll(IMP_TELEPORT_CHANCE_ON_HIT)) {
|
||||
getRandomLocAndTeleport();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
if (this.getId() == NPCs.IMP_708 || this.getId() == NPCs.IMP_709 || this.getId() == NPCs.IMP_1531) {
|
||||
if (RandomFunction.roll(IMP_TELEPORT_CHANCE_ON_TICK)) {
|
||||
getRandomLocAndTeleport();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type.
|
||||
* @return The type.
|
||||
*/
|
||||
public TrapNode getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the trap.
|
||||
* @return The trap.
|
||||
*/
|
||||
public Traps getTrap() {
|
||||
return trap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to teleport imps
|
||||
*/
|
||||
private void getRandomLocAndTeleport() {
|
||||
Location teleportLocation = getPathableRandomLocalCoordinate(this, walkRadius, getProperties().getSpawnLocation(), 3);
|
||||
|
||||
if (getLocation() != teleportLocation) {
|
||||
sendGraphics(1119, getLocation());
|
||||
ContentAPIKt.teleport(this, teleportLocation, TeleportManager.TeleportType.INSTANT);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
package content.global.skill.hunter;
|
||||
|
||||
import content.global.skill.hunter.bnet.BNetNode;
|
||||
import content.global.skill.hunter.bnet.BNetTypes;
|
||||
import content.global.skill.hunter.bnet.ImplingNode;
|
||||
import core.cache.def.Definition;
|
||||
import core.cache.def.impl.ItemDefinition;
|
||||
import core.cache.def.impl.NPCDefinition;
|
||||
import core.cache.def.impl.SceneryDefinition;
|
||||
import core.plugin.Initializable;
|
||||
import content.global.skill.hunter.NetTrapSetting.NetTrap;
|
||||
import core.game.interaction.NodeUsageEvent;
|
||||
import core.game.interaction.OptionHandler;
|
||||
import core.game.interaction.UseWithHandler;
|
||||
import core.game.node.Node;
|
||||
import core.game.node.entity.npc.NPC;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.item.GroundItem;
|
||||
import core.game.node.item.Item;
|
||||
import core.game.node.scenery.Scenery;
|
||||
import core.game.world.map.Location;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
import core.plugin.Plugin;
|
||||
import core.plugin.ClassScanner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Handles the hunter skill.
|
||||
* @author Vexia
|
||||
*/
|
||||
@Initializable
|
||||
public final class HunterPlugin extends OptionHandler {
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
Definition<?> definition = null;
|
||||
for (Traps trap : Traps.values()) {
|
||||
for (int nodeId : trap.getSettings().getNodeIds()) {
|
||||
definition = trap.getSettings().isObjectTrap() ? SceneryDefinition.forId(nodeId) : ItemDefinition.forId(nodeId);
|
||||
definition.getHandlers().put("option:" + trap.getSettings().getOption(), this);
|
||||
}
|
||||
if (trap.getSettings().getFailId() != -1) {
|
||||
definition = SceneryDefinition.forId(trap.getSettings().getFailId());
|
||||
definition.getHandlers().put("option:dismantle", this);
|
||||
definition.getHandlers().put("option:deactivate", this);
|
||||
}
|
||||
for (int objectId : trap.getSettings().getObjectIds()) {
|
||||
definition = SceneryDefinition.forId(objectId);
|
||||
definition.getHandlers().put("option:deactivate", this);
|
||||
definition.getHandlers().put("option:dismantle", this);
|
||||
definition.getHandlers().put("option:investigate", this);
|
||||
}
|
||||
for (TrapNode node : trap.getNodes()) {
|
||||
for (int objectId : node.getObjectIds()) {
|
||||
definition = SceneryDefinition.forId(objectId);
|
||||
definition.getHandlers().put("option:check", this);
|
||||
definition.getHandlers().put("option:retrieve", this);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (NetTrap trap : NetTrap.values()) {
|
||||
SceneryDefinition.forId(trap.getBent()).getHandlers().put("option:dismantle", this);
|
||||
SceneryDefinition.forId(trap.getFailed()).getHandlers().put("option:dismantle", this);
|
||||
SceneryDefinition.forId(trap.getNet()).getHandlers().put("option:dismantle", this);
|
||||
SceneryDefinition.forId(trap.getCaught()).getHandlers().put("option:check", this);
|
||||
SceneryDefinition.forId(trap.getBent()).getHandlers().put("option:investigate", this);
|
||||
SceneryDefinition.forId(trap.getFailed()).getHandlers().put("option:investigate", this);
|
||||
SceneryDefinition.forId(trap.getNet()).getHandlers().put("option:investigate", this);
|
||||
}
|
||||
ClassScanner.definePlugin(new HunterNPC());
|
||||
ClassScanner.definePlugin(new HunterNetPlugin());
|
||||
ClassScanner.definePlugin(new HunterItemPlugin());
|
||||
ClassScanner.definePlugin(new FalconryActivityPlugin());
|
||||
ClassScanner.definePlugin(new HuntingItemUseWithHandler());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(Player player, Node node, String option) {
|
||||
final Traps trap = Traps.forNode(node);
|
||||
switch (option) {
|
||||
case "lay":
|
||||
case "activate":
|
||||
case "set-trap":
|
||||
case "trap":
|
||||
trap.create(player, node);
|
||||
return true;
|
||||
case "dismantle":
|
||||
case "deactivate":
|
||||
case "retrieve":
|
||||
case "check":
|
||||
trap.dismantle(player, (Scenery) node);
|
||||
return true;
|
||||
case "investigate":
|
||||
trap.investigate(player, (Scenery) node);
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getDestination(Node node, Node n) {
|
||||
if (n.getName().startsWith("Bird")) {
|
||||
if (node.getLocation().equals(n.getLocation())) {
|
||||
return n.getLocation().transform(node.getDirection(), 1);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWalk(Player player, Node node) {
|
||||
return node instanceof GroundItem || !(node instanceof Item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWalk() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the usage of an item on a trap.
|
||||
* @author Vexia
|
||||
*/
|
||||
public final static class HuntingItemUseWithHandler extends UseWithHandler {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code HuntingItemUseWithHandler} {@code Object}.
|
||||
*/
|
||||
public HuntingItemUseWithHandler() {
|
||||
super(getIds());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
for (Traps trap : Traps.values()) {
|
||||
for (int objectId : trap.getSettings().getObjectIds()) {
|
||||
addHandler(objectId, OBJECT_TYPE, this);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(NodeUsageEvent event) {
|
||||
final Player player = event.getPlayer();
|
||||
final Scenery object = event.getUsedWith() instanceof Scenery ? (Scenery) event.getUsedWith() : (Scenery) event.getUsed();
|
||||
final Item item = event.getUsedItem();
|
||||
if (HunterManager.getInstance(player).isOwner(object)) {
|
||||
player.sendMessage("This isn't your trap!");
|
||||
return true;
|
||||
}
|
||||
final TrapWrapper wrapper = HunterManager.getInstance(player).getWrapper(object);
|
||||
if (item.getId() == 594) {
|
||||
wrapper.smoke();
|
||||
} else {
|
||||
wrapper.bait(item);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ids to be used.
|
||||
* @return the ids.
|
||||
*/
|
||||
public static int[] getIds() {
|
||||
List<Integer> list = new ArrayList<>(10);
|
||||
for (Traps trap : Traps.values()) {
|
||||
for (int id : trap.getSettings().getBaitIds()) {
|
||||
list.add(id);
|
||||
}
|
||||
}
|
||||
list.add(594);
|
||||
int[] array = new int[list.size()];
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
array[i] = list.get(i);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a hunter item plugin.
|
||||
* @author Vexia
|
||||
*/
|
||||
public static final class HunterItemPlugin extends OptionHandler {
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
ItemDefinition.setOptionHandler("release", this);
|
||||
for (int i = BNetTypes.BABY_IMPLING.ordinal() - 1; i < BNetTypes.values().length; i++) {
|
||||
BNetTypes.values()[i].getNode().getReward().getDefinition().getHandlers().put("option:loot", this);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(Player player, Node node, String option) {
|
||||
switch (option) {
|
||||
case "release":
|
||||
ReleaseType type = ReleaseType.forId(node.getId());
|
||||
if (type != null) {
|
||||
type.release(player, (Item) node);
|
||||
}
|
||||
break;
|
||||
case "loot":
|
||||
((ImplingNode) BNetTypes.forItem((Item) node)).loot(player, (Item) node);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWalk() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* A release type.
|
||||
* @author Vexia
|
||||
*/
|
||||
public enum ReleaseType {
|
||||
TRAPS(10033, 10034, 10092, 10146, 10147, 10148, 10149), BUTTERFLY(10020, 10018, 10016, 10014) {
|
||||
@Override
|
||||
public void release(final Player player, final Item item) {
|
||||
BNetNode node = BNetTypes.forItem(item);
|
||||
if (player.getInventory().remove(item)) {
|
||||
player.animate(Animation.create(5213));
|
||||
player.getInventory().add(new Item(10012));
|
||||
player.graphics(node.getGraphics()[1]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The ids of the item.
|
||||
*/
|
||||
private final int[] ids;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ReleaseType} {@code Object}.
|
||||
* @param ids the ids.
|
||||
*/
|
||||
private ReleaseType(int... ids) {
|
||||
this.ids = ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases an item.
|
||||
* @param player the player.
|
||||
* @param item the item.
|
||||
*/
|
||||
public void release(final Player player, final Item item) {
|
||||
boolean multiple = item.getAmount() > 1;
|
||||
player.getInventory().remove(item);
|
||||
player.sendMessage("You release the " + item.getName().toLowerCase() + (multiple ? "s" : "") + " and " + (multiple ? "they" : "it") + " bound" + (!multiple ? "s" : "") + " away.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a release type.
|
||||
* @param id the id.
|
||||
* @return the type.
|
||||
*/
|
||||
public static ReleaseType forId(int id) {
|
||||
for (ReleaseType type : values()) {
|
||||
for (int i : type.getIds()) {
|
||||
if (i == id) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ids.
|
||||
* @return The ids.
|
||||
*/
|
||||
public int[] getIds() {
|
||||
return ids;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the catching of a hunter npc with a net.
|
||||
* @author Vexia
|
||||
*/
|
||||
public static final class HunterNetPlugin extends OptionHandler {
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
for (BNetTypes type : BNetTypes.values()) {
|
||||
for (int id : type.getNode().getNpcs()) {
|
||||
NPCDefinition.forId(id).getHandlers().put("option:catch", this);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(Player player, Node node, String option) {
|
||||
BNetTypes.forNpc((NPC) node).handle(player, (NPC) node);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
package content.global.skill.hunter;
|
||||
|
||||
import core.cache.def.impl.ItemDefinition;
|
||||
import core.game.component.Component;
|
||||
import core.game.component.ComponentDefinition;
|
||||
import core.game.component.ComponentPlugin;
|
||||
import core.plugin.Initializable;
|
||||
import core.game.dialogue.DialogueInterpreter;
|
||||
import core.game.dialogue.DialoguePlugin;
|
||||
import core.game.dialogue.FacialExpression;
|
||||
import core.game.interaction.OptionHandler;
|
||||
import core.game.node.Node;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.item.Item;
|
||||
import core.net.packet.PacketRepository;
|
||||
import core.net.packet.context.ContainerContext;
|
||||
import core.net.packet.out.ContainerPacket;
|
||||
import core.plugin.Plugin;
|
||||
import core.plugin.ClassScanner;
|
||||
import core.tools.RandomFunction;
|
||||
|
||||
/**
|
||||
* Handles the imp box.
|
||||
* @author Taylor
|
||||
*/
|
||||
@Initializable
|
||||
public class ImpBoxPlugin extends OptionHandler {
|
||||
|
||||
/**
|
||||
* The item ids.
|
||||
*/
|
||||
private static final int[] IDS = new int[] { 10028, 10027 };
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
ClassScanner.definePlugin(new ImpInterfaceHandler(null));
|
||||
for (int id : IDS) {
|
||||
ItemDefinition.forId(id).getHandlers().put("option:bank", this);
|
||||
ItemDefinition.forId(id).getHandlers().put("option:talk-to", this);
|
||||
}
|
||||
ClassScanner.definePlugin(new ImpBoxDialogue());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(Player player, Node node, String option) {
|
||||
switch (option) {
|
||||
case "bank":
|
||||
Component component = new Component(478);
|
||||
component.setPlugin(new ImpInterfaceHandler((Item) node));
|
||||
player.getInterfaceManager().open(component);
|
||||
PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 478, 61, 91, player.getInventory(), true));
|
||||
break;
|
||||
case "talk-to":
|
||||
player.getDialogueInterpreter().open("imp-box");
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWalk() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles talk-to dialogue on the imp box.
|
||||
* @author Taylor
|
||||
*/
|
||||
public static class ImpBoxDialogue extends DialoguePlugin {
|
||||
|
||||
/**
|
||||
* The messages to send.
|
||||
*/
|
||||
private static final String[] MESSAGES = { "Let me outa here!", "Errgghh..", "Well look who it is.", "What are you looking at?" };
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ImpBoxDialogue} {@code Object}.
|
||||
*/
|
||||
public ImpBoxDialogue() {
|
||||
/**
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ImpBoxDialogue} {@code Object}.
|
||||
* @param player The player.
|
||||
*/
|
||||
public ImpBoxDialogue(Player player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DialoguePlugin newInstance(Player player) {
|
||||
return new ImpBoxDialogue(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean open(Object... args) {
|
||||
interpreter.sendDialogues(708, FacialExpression.FURIOUS, MESSAGES[RandomFunction.getRandom(MESSAGES.length - 1)]);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(int interfaceId, int buttonId) {
|
||||
end();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getIds() {
|
||||
return new int[] { DialogueInterpreter.getDialogueKey("imp-box") };
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the imp interface.
|
||||
* @author Taylor
|
||||
*/
|
||||
public class ImpInterfaceHandler extends ComponentPlugin {
|
||||
|
||||
/**
|
||||
* The message to show when the imp is gone.
|
||||
*/
|
||||
private static final String FINISHING_MESSAGE = "The imp teleports away, taking the item to your bank account.";
|
||||
|
||||
/**
|
||||
* The box the player is using.
|
||||
*/
|
||||
private Item box;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ImpInterfaceHandler} {@code Object}.
|
||||
* @param box The box the player is using.
|
||||
*/
|
||||
public ImpInterfaceHandler(Item box) {
|
||||
this.box = box;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
ComponentDefinition.forId(478).setPlugin(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) {
|
||||
Item item = player.getInventory().get(slot);
|
||||
if (item != null) {
|
||||
if (player.getBank().canAdd(item) && item.getId() != box.getId()) {
|
||||
player.getDialogueInterpreter().close();
|
||||
player.getInventory().remove(item);
|
||||
player.getBank().add(item);
|
||||
PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 478, 61, 91, player.getInventory(), true));
|
||||
if (box.getId() == IDS[1]) {
|
||||
int boxSlot = player.getInventory().getSlot(box);
|
||||
player.getInventory().replace((box = new Item(IDS[0])), boxSlot);
|
||||
} else if (box.getId() == IDS[0]) {
|
||||
int boxSlot = player.getInventory().getSlot(box);
|
||||
player.getInventory().replace(new Item(10025), boxSlot);
|
||||
player.getInterfaceManager().close(component);
|
||||
player.sendMessage(FINISHING_MESSAGE);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
player.sendMessage("You cannot add this item to your bank.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
package content.global.skill.hunter;
|
||||
|
||||
import content.global.skill.hunter.bnet.BNetTypes;
|
||||
import content.global.skill.hunter.bnet.ImplingNode;
|
||||
import core.api.StartupListener;
|
||||
import core.game.world.GameWorld;
|
||||
import core.game.world.map.Location;
|
||||
import core.tools.RandomFunction;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Handles the impetuous impulse minigame.
|
||||
* @author Vexia
|
||||
* @author Emperor
|
||||
*/
|
||||
public final class ImpetuousImpulses implements StartupListener {
|
||||
|
||||
/**
|
||||
* The random instance used.
|
||||
*/
|
||||
private static final Random RANDOM = new Random();
|
||||
|
||||
/**
|
||||
* The puro puro locations.
|
||||
*/
|
||||
private static final Location[] PURO_LOCATIONS = new Location[] { new Location(2575, 4314, 0), new Location(2572, 4302, 0), new Location(2575, 4297, 0), new Location(2589, 4297, 0), new Location(2603, 4297, 0), new Location(2612, 4301, 0), new Location(2619, 4296, 0), new Location(2616, 4297, 0), new Location(2620, 4308, 0), new Location(2617, 4313, 0), new Location(2620, 4317, 0), new Location(2611, 4312, 0), new Location(2607, 4305, 0), new Location(2593, 4303, 0), new Location(2578, 4318, 0), new Location(2578, 4330, 0), new Location(2581, 4338, 0), new Location(2586, 4342, 0), Location.create(2585, 4344, 0), Location.create(2573, 4335, 0), Location.create(2570, 4325, 0), Location.create(2567, 4313, 0), Location.create(2566, 4299, 0), Location.create(2573, 4292, 0), Location.create(2603, 4342, 0), Location.create(2616, 4318, 0), Location.create(2616, 4337, 0), Location.create(2584, 4297, 0), Location.create(2596, 4310, 0), Location.create(2596, 4310, 0), Location.create(2588, 4303, 0) };
|
||||
|
||||
/**
|
||||
* The possible locations.
|
||||
*/
|
||||
public static final Location[] LOCATIONS = new Location[] {
|
||||
/*
|
||||
* Camelot
|
||||
*/
|
||||
Location.create(2718 + RANDOM.nextInt(50), 3441 + RANDOM.nextInt(20), 0),
|
||||
/*
|
||||
* Duel arena entrance
|
||||
*/
|
||||
Location.create(3300 + RANDOM.nextInt(10), 3250 + RANDOM.nextInt(10), 0),
|
||||
/*
|
||||
* Castle wars entrance
|
||||
*/
|
||||
Location.create(2478 + RANDOM.nextInt(20), 3068 + RANDOM.nextInt(20), 0),
|
||||
/*
|
||||
* Lumbridge
|
||||
*/
|
||||
Location.create(3175 + RANDOM.nextInt(10), 3261 + RANDOM.nextInt(10), 0),
|
||||
/*
|
||||
* Draynor
|
||||
*/
|
||||
Location.create(3092 + RANDOM.nextInt(5), 3227 + RANDOM.nextInt(5), 0),
|
||||
/*
|
||||
* Falador (east)
|
||||
*/
|
||||
Location.create(3071 + RANDOM.nextInt(10), 3355 + RANDOM.nextInt(10), 0),
|
||||
/*
|
||||
* Varrock (west)
|
||||
*/
|
||||
Location.create(3131 + RANDOM.nextInt(5), 3401 + RANDOM.nextInt(5), 0),
|
||||
/*
|
||||
* Ardougne (south)
|
||||
*/
|
||||
Location.create(2630 + RANDOM.nextInt(10), 3217 + RANDOM.nextInt(10), 0),
|
||||
/*
|
||||
* Yanille (north)
|
||||
*/
|
||||
Location.create(2594 + RANDOM.nextInt(20), 3121 + RANDOM.nextInt(20), 0),
|
||||
/*
|
||||
* Red salamander hunting place (ZMI altar)
|
||||
*/
|
||||
Location.create(2436 + RANDOM.nextInt(15), 3206 + RANDOM.nextInt(15), 0),
|
||||
/*
|
||||
* Shilo hunting area (graahk/larupia/..)
|
||||
*/
|
||||
Location.create(2763 + RANDOM.nextInt(20), 3003 + RANDOM.nextInt(20), 0),
|
||||
/*
|
||||
* Rimmington
|
||||
*/
|
||||
Location.create(2947 + RANDOM.nextInt(20), 3219 + RANDOM.nextInt(20), 0),
|
||||
/*
|
||||
* Karamja volcano
|
||||
*/
|
||||
Location.create(2856 + RANDOM.nextInt(15), 3150 + RANDOM.nextInt(15), 0),
|
||||
/*
|
||||
* Brimhaven dungeon entrance
|
||||
*/
|
||||
Location.create(2733 + RANDOM.nextInt(10), 3146 + RANDOM.nextInt(10), 0),
|
||||
/*
|
||||
* Sophanem
|
||||
*/
|
||||
Location.create(3299 + RANDOM.nextInt(5), 2784 + RANDOM.nextInt(5), 0),
|
||||
/*
|
||||
* Tree gnome stronghold
|
||||
*/
|
||||
Location.create(2438 + RANDOM.nextInt(20), 3420 + RANDOM.nextInt(20), 0),
|
||||
/*
|
||||
* Zanaris (center, just north of grain field)
|
||||
*/
|
||||
Location.create(2416 + RANDOM.nextInt(3), 4456 + RANDOM.nextInt(3), 0), };
|
||||
|
||||
/**
|
||||
* Spawns the imps.
|
||||
*/
|
||||
private void spawnImps() {
|
||||
int amount = BNetTypes.getImplings().size() + 2;
|
||||
for (ImplingNode impling : BNetTypes.getImplings()) {
|
||||
if (impling.getLevel() == 83) {
|
||||
int rand = RandomFunction.random(1, 2);
|
||||
for (int i = 0; i < rand; i++) {
|
||||
createImp(impling, true);
|
||||
}
|
||||
int randAmt = RandomFunction.random(2, 5);
|
||||
for (int i = 0; i < randAmt; i++) {
|
||||
createImp(impling, false);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
for (int i = 0; i < amount; i++) {
|
||||
if (RANDOM.nextInt(10) < 4) {
|
||||
createImp(impling, false);
|
||||
continue;
|
||||
}
|
||||
createImp(impling, true);
|
||||
}
|
||||
amount--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the impling.
|
||||
* @param impling the impling.
|
||||
* @param puro the puro.
|
||||
*/
|
||||
private void createImp(ImplingNode impling, boolean puro) {
|
||||
ImplingNPC npc = null;
|
||||
if (puro) {
|
||||
npc = new ImplingNPC(impling.getNpcs()[1], PURO_LOCATIONS[RANDOM.nextInt(PURO_LOCATIONS.length)], impling);
|
||||
npc.setAttribute("puroPuro", true);
|
||||
} else {
|
||||
npc = new ImplingNPC(impling.getNpcs()[0], LOCATIONS[RANDOM.nextInt(LOCATIONS.length)], impling);
|
||||
npc.setAttribute("nextTeleport", GameWorld.getTicks() + 600);
|
||||
}
|
||||
npc.init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startup() {
|
||||
spawnImps();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
package content.global.skill.hunter;
|
||||
|
||||
import content.global.skill.hunter.bnet.ImplingNode;
|
||||
import core.game.node.entity.Entity;
|
||||
import core.game.node.entity.combat.BattleState;
|
||||
import core.game.node.entity.combat.CombatStyle;
|
||||
import core.game.node.entity.npc.AbstractNPC;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.system.task.Pulse;
|
||||
import core.game.world.map.Location;
|
||||
import core.game.world.map.path.Pathfinder;
|
||||
import core.game.world.update.flag.context.Graphics;
|
||||
import core.tools.RandomFunction;
|
||||
import core.game.system.config.NPCConfigParser;
|
||||
import core.game.world.GameWorld;
|
||||
|
||||
/**
|
||||
* Handles an impling npc.
|
||||
* @author Vexia
|
||||
*/
|
||||
public final class ImplingNPC extends AbstractNPC {
|
||||
|
||||
/**
|
||||
* The impling node.
|
||||
*/
|
||||
private final ImplingNode impling;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ImplingNPC} {@code Object}.
|
||||
*/
|
||||
public ImplingNPC() {
|
||||
super(0, null);
|
||||
this.impling = null;
|
||||
this.setWalks(true);
|
||||
this.setWalkRadius(20);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ImplingNPC} {@code Object}.
|
||||
* @param id the id.
|
||||
* @param location the location.
|
||||
*/
|
||||
public ImplingNPC(int id, Location location, ImplingNode impling) {
|
||||
super(id, location);
|
||||
this.impling = impling;
|
||||
if (impling != null) {
|
||||
this.getDefinition().getHandlers().put(NPCConfigParser.RESPAWN_DELAY, impling.getRespawnTime());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractNPC construct(int id, Location location, Object... objects) {
|
||||
return new ImplingNPC(id, location, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTickActions() {
|
||||
if (!getLocks().isMovementLocked()) {
|
||||
if (isWalks() && !getPulseManager().hasPulseRunning() && nextWalk < GameWorld.getTicks()) {
|
||||
setNextWalk();
|
||||
Location l = getLocation().transform(-5 + RandomFunction.random(getWalkRadius()), -5 + RandomFunction.random(getWalkRadius()), 0);
|
||||
if (canMove(l)) {
|
||||
Pathfinder.find(this, l, true, Pathfinder.PROJECTILE).walk(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (RandomFunction.random(100) < 4) {
|
||||
sendChat("Tee hee!");
|
||||
}
|
||||
int nextTeleport = getAttribute("nextTeleport", -1);
|
||||
if (nextTeleport > -1 && GameWorld.getTicks() > nextTeleport) {
|
||||
setAttribute("nextTeleport", GameWorld.getTicks() + 600);
|
||||
graphics(new Graphics(590));
|
||||
GameWorld.getPulser().submit(new Pulse(1) {
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
teleport(ImpetuousImpulses.LOCATIONS[RandomFunction.random(ImpetuousImpulses.LOCATIONS.length)]);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAttackable(Entity entity, CombatStyle style, boolean message) {
|
||||
if (style != CombatStyle.MAGIC) {
|
||||
return false;
|
||||
}
|
||||
if (entity.getProperties().getSpell().getSpellId() == 12 || entity.getProperties().getSpell().getSpellId() == 30 || entity.getProperties().getSpell().getSpellId() == 56) {
|
||||
return true;
|
||||
}
|
||||
return super.isAttackable(entity, style, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleDrops(Player p, Entity killer) {
|
||||
getProperties().setTeleportLocation(getProperties().getSpawnLocation());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkImpact(BattleState state) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getIds() {
|
||||
return new int[] {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the impling.
|
||||
* @return The impling.
|
||||
*/
|
||||
public ImplingNode getImpling() {
|
||||
return impling;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package content.global.skill.hunter;
|
||||
|
||||
import core.game.node.entity.npc.NPC;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
|
||||
/**
|
||||
* Handles the magic box.
|
||||
* @author Vexia
|
||||
*/
|
||||
public final class MagicBoxSetting extends TrapSetting {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code MagicBoxSetting} {@code Object}.
|
||||
*/
|
||||
public MagicBoxSetting() {
|
||||
super(10025, new int[] { 19223 }, new int[] { 1470, 1472, 1476, 1474 }, "activate", 19224, Animation.create(5208), Animation.create(9726), 27);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCatch(int counter, TrapWrapper wrapper, TrapNode node, NPC npc, boolean success) {
|
||||
switch (counter) {
|
||||
case 2:
|
||||
if (success) {
|
||||
wrapper.getPlayer().getPacketDispatch().sendPositionedGraphic(932, 0, 0, npc.getLocation());
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
npc.moveStep();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTool(Player player, TrapWrapper wrapper, int type) {
|
||||
if (!wrapper.isCaught()) {
|
||||
super.addTool(player, wrapper, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
package content.global.skill.hunter;
|
||||
|
||||
import core.game.node.Node;
|
||||
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.map.Location;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Handles the net trap.
|
||||
* @author Vexia
|
||||
*/
|
||||
public final class NetTrapSetting extends TrapSetting {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code NetTrapSetting} {@code Object}.
|
||||
*/
|
||||
public NetTrapSetting() {
|
||||
super(new int[] { 19652, 19663, 19671, 19679, 28564 }, new Item[] { new Item(303), new Item(954) }, NetTrap.getIds(), new int[] { 10142, 10143, 10144, 10145 }, "set-trap", 29, -1, new Animation(5215), Animation.create(5207), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasItems(Player player) {
|
||||
if (!super.hasItems(player)) {
|
||||
player.sendMessage("You need a net and a rope to set a net trap.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clear(TrapWrapper wrapper, int type) {
|
||||
if (super.clear(wrapper, type)) {
|
||||
if (wrapper.getSecondary() != null && wrapper.getSecondary().isActive()) {
|
||||
SceneryBuilder.remove(wrapper.getSecondary());
|
||||
}
|
||||
SceneryBuilder.add(wrapper.getObject().transform(wrapper.getNetType().getOriginal()));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void returnItems(Scenery object, TrapWrapper wrapper, int type) {
|
||||
super.returnItems(object, wrapper, type);
|
||||
if (type == 0) {
|
||||
for (Item i : super.getItems()) {
|
||||
createGroundItem(i, object.getLocation(), wrapper.getPlayer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reward(Player player, Node node, TrapWrapper wrapper) {
|
||||
Scenery object = wrapper.getObject();
|
||||
wrapper.setNetType(NetTrap.forId(node.getId()));
|
||||
int rotation = 0;
|
||||
int increment = 0;
|
||||
boolean x = false;
|
||||
Object[] netInfo = getNetInfo(player, node);
|
||||
rotation = (int) netInfo[0];
|
||||
increment = (int) netInfo[1];
|
||||
x = (boolean) netInfo[2];
|
||||
Scenery secondary = new Scenery(wrapper.getNetType().getNet(), object.getLocation().transform(x ? increment : 0, !x ? increment : 0, 0), rotation);
|
||||
secondary = SceneryBuilder.add(secondary);
|
||||
wrapper.setSecondary(secondary);
|
||||
player.moveStep();
|
||||
wrapper.addItem(getItems());
|
||||
player.getInventory().remove(wrapper.getType().getSettings().getItems());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCatch(int counter, TrapWrapper wrapper, TrapNode node, NPC npc, boolean success) {
|
||||
switch (counter) {
|
||||
case 2:
|
||||
SceneryBuilder.remove(wrapper.getSecondary());
|
||||
break;
|
||||
case 3:
|
||||
npc.moveStep();
|
||||
wrapper.setObject(wrapper.getNetType().getFailed());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Scenery buildObject(Player player, Node node) {
|
||||
return ((Scenery) node).transform(NetTrap.forId(node.getId()).getBent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrapHook createHook(TrapWrapper wrapper) {
|
||||
return new TrapHook(wrapper, new Location[] { wrapper.getSecondary().getLocation() });
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTransformId(TrapWrapper wrapper, TrapNode node) {
|
||||
return wrapper.getNetType().getCatching();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFinalId(TrapWrapper wrapper, TrapNode node) {
|
||||
return wrapper.getNetType().getCaught();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFailId(TrapWrapper wrapper, TrapNode node) {
|
||||
return wrapper.getNetType().getFailing();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTimeUpMessage() {
|
||||
return "The net trap that you constructed has collapsed.";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the net info.
|
||||
* @param player the player.
|
||||
* @param node the node.
|
||||
* @return the data.
|
||||
*/
|
||||
private Object[] getNetInfo(Player player, Node node) {
|
||||
int rotation;
|
||||
int increment;
|
||||
boolean x = false;
|
||||
if (player.getLocation().getX() < node.getLocation().getX()) {
|
||||
rotation = 3;
|
||||
increment = -1;
|
||||
x = true;
|
||||
} else if (player.getLocation().getX() > node.getLocation().getX()) {
|
||||
rotation = 1;
|
||||
increment = 1;
|
||||
x = true;
|
||||
} else if (player.getLocation().getY() < node.getLocation().getY()) {
|
||||
rotation = 2;
|
||||
increment = -1;
|
||||
} else {
|
||||
rotation = 0;
|
||||
increment = 1;
|
||||
}
|
||||
return new Object[] { rotation, increment, x };
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a net trap.
|
||||
* @author Vexia
|
||||
*/
|
||||
public enum NetTrap {
|
||||
GREEN(19679, 19678, 19676, 19677, 19674, 19675, 19651), SQUIREL(28564, 28563, 28752, 28753, 28750, 28751, 28566), ORANGE(19652, 19650, 19657, 19656, 19655, 19654, 19665), RED(19663, 19662, 19660, 19661, 19658, 19659, 19673), BLACK(19671, 19670, 19668, 19669, 19666, 19667, 19681);
|
||||
|
||||
/**
|
||||
* Represents the original object id.
|
||||
*/
|
||||
private final int original;
|
||||
|
||||
/**
|
||||
* Represents the bend object id.
|
||||
*/
|
||||
private final int bent;
|
||||
|
||||
/**
|
||||
* Represents the failing object id.
|
||||
*/
|
||||
private final int failing;
|
||||
|
||||
/**
|
||||
* Represents the failed object id.
|
||||
*/
|
||||
private final int failed;
|
||||
|
||||
/**
|
||||
* Represents the catching object id.
|
||||
*/
|
||||
private final int catching;
|
||||
|
||||
/**
|
||||
* Represents the caught object id.
|
||||
*/
|
||||
private final int caught;
|
||||
|
||||
/**
|
||||
* Represents the net.
|
||||
*/
|
||||
private final int net;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code StationaryCatch.java} {@code Object}.
|
||||
* @param original the original.
|
||||
* @param bent the bent.
|
||||
* @param failing the failing.
|
||||
* @param failed the failed.
|
||||
* @param catching the catching.
|
||||
* @param caught the caught.
|
||||
* @param net the net.
|
||||
*/
|
||||
NetTrap(int original, int bent, int failing, int failed, int catching, int caught, int net) {
|
||||
this.original = original;
|
||||
this.bent = bent;
|
||||
this.failing = failing;
|
||||
this.failed = failed;
|
||||
this.catching = catching;
|
||||
this.caught = caught;
|
||||
this.net = net;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the net trap for the id.
|
||||
* @param id the id.
|
||||
* @return the trap.
|
||||
*/
|
||||
public static NetTrap forId(int id) {
|
||||
for (NetTrap trap : values()) {
|
||||
if (trap.getOriginal() == id) {
|
||||
return trap;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id.
|
||||
* @return the array.
|
||||
*/
|
||||
public static int[] getIds() {
|
||||
List<Integer> ids = new ArrayList<>(10);
|
||||
for (NetTrap trap : NetTrap.values()) {
|
||||
ids.add(trap.getBent());
|
||||
ids.add(trap.getCaught());
|
||||
ids.add(trap.getNet());
|
||||
ids.add(trap.getOriginal());
|
||||
}
|
||||
int[] array = new int[ids.size()];
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
array[i] = ids.get(i);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the original.
|
||||
* @return The original.
|
||||
*/
|
||||
public int getOriginal() {
|
||||
return original;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bent.
|
||||
* @return The bent.
|
||||
*/
|
||||
public int getBent() {
|
||||
return bent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the failed.
|
||||
* @return The failed.
|
||||
*/
|
||||
public int getFailed() {
|
||||
return failed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the catching.
|
||||
* @return The catching.
|
||||
*/
|
||||
public int getCatching() {
|
||||
return catching;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the caught.
|
||||
* @return The caught.
|
||||
*/
|
||||
public int getCaught() {
|
||||
return caught;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the failing.
|
||||
* @return The failing.
|
||||
*/
|
||||
public int getFailing() {
|
||||
return failing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the net.
|
||||
* @return The net.
|
||||
*/
|
||||
public int getNet() {
|
||||
return net;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
package content.global.skill.hunter;
|
||||
|
||||
import core.game.node.entity.skill.SkillPulse;
|
||||
import core.game.node.Node;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.entity.skill.Skills;
|
||||
import core.game.node.item.GroundItem;
|
||||
import core.game.node.item.GroundItemManager;
|
||||
import core.game.node.item.Item;
|
||||
import core.game.node.scenery.Scenery;
|
||||
import core.game.node.scenery.SceneryBuilder;
|
||||
import core.game.world.map.Location;
|
||||
import core.game.world.map.RegionManager;
|
||||
|
||||
/**
|
||||
* Handles the trap creating pulse.
|
||||
* @author Vexia
|
||||
*/
|
||||
public final class TrapCreatePulse extends SkillPulse<Node> {
|
||||
|
||||
/**
|
||||
* The starting location of the trap.
|
||||
*/
|
||||
private final Location startLocation;
|
||||
|
||||
/**
|
||||
* The ground item of the trap.
|
||||
*/
|
||||
private GroundItem groundItem;
|
||||
|
||||
/**
|
||||
* The trap type.
|
||||
*/
|
||||
private final Traps trap;
|
||||
|
||||
/**
|
||||
* The amounts of ticks passed.
|
||||
*/
|
||||
private int ticks;
|
||||
|
||||
private final HunterManager instance;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code TrapCreatePulse} {@code Object}.
|
||||
* @param player the player.
|
||||
* @param node the node.
|
||||
* @param trap the trap.
|
||||
*/
|
||||
public TrapCreatePulse(Player player, Node node, Traps trap) {
|
||||
super(player, node);
|
||||
this.trap = trap;
|
||||
this.startLocation = node instanceof GroundItem ? node.getLocation() : player.getLocation();
|
||||
this.instance = HunterManager.getInstance(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkRequirements() {
|
||||
if (player.skills.getStaticLevel(Skills.HUNTER) < trap.getSettings().getLevel()) {
|
||||
player.sendMessage("You need a Hunter level of at least " + trap.getSettings().getLevel() + " in order to setup a " + node.getName().toLowerCase() + ".");
|
||||
return false;
|
||||
}
|
||||
if (instance.exceedsTrapLimit(trap)) {
|
||||
player.sendMessage(trap.getSettings().getLimitMessage(player));
|
||||
return false;
|
||||
}
|
||||
if (RegionManager.getObject(player.getLocation()) != null) {
|
||||
player.sendMessage("You can't lay a trap here.");
|
||||
return false;
|
||||
}
|
||||
if (!player.getLocation().equals(startLocation)) {
|
||||
return false;
|
||||
}
|
||||
if (trap.getSettings().isObjectTrap() && !trap.getSettings().hasItems(player)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void animate() {
|
||||
if (ticks < 1) {
|
||||
player.getAnimator().forceAnimation(trap.getSettings().getSetupAnimation());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean reward() {
|
||||
if (++ticks % (trap.getSettings().getSetupAnimation().getDefinition().getDurationTicks()) != 0) {
|
||||
return false;
|
||||
}
|
||||
Scenery object = trap.getSettings().buildObject(player, node);
|
||||
if (isGroundSetup() || groundItem != null) {
|
||||
GroundItemManager.destroy(groundItem);
|
||||
}
|
||||
if (!trap.getSettings().isObjectTrap()) {
|
||||
player.moveStep();
|
||||
} else {
|
||||
SceneryBuilder.remove(node.asScenery());
|
||||
}
|
||||
object = SceneryBuilder.add(object);
|
||||
instance.register(trap, node, object);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void message(int type) {
|
||||
switch (type) {
|
||||
case 0:
|
||||
setUp();
|
||||
player.getPacketDispatch().sendMessage("You begin setting up the trap.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the trap.
|
||||
*/
|
||||
private void setUp() {
|
||||
player.lock(1);
|
||||
player.getWalkingQueue().reset();
|
||||
if (trap.getSettings().isObjectTrap()) {
|
||||
|
||||
} else {
|
||||
if (!isGroundSetup()) {
|
||||
if (player.getInventory().remove((Item) node)) {
|
||||
groundItem = new GroundItem((Item) node, player.getLocation(), player);
|
||||
GroundItemManager.create(groundItem);
|
||||
}
|
||||
return;
|
||||
}
|
||||
groundItem = (GroundItem) node;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If we're setting it up from the ground.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean isGroundSetup() {
|
||||
return node instanceof GroundItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the trap.
|
||||
* @return The trap.
|
||||
*/
|
||||
public Traps getTrap() {
|
||||
return trap;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
package content.global.skill.hunter;
|
||||
|
||||
import content.data.skill.SkillingPets;
|
||||
import core.game.node.entity.skill.SkillPulse;
|
||||
import core.game.node.entity.skill.Skills;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.scenery.Scenery;
|
||||
|
||||
/**
|
||||
* Handles the dismantling of a trap.
|
||||
* @author Vexia
|
||||
*/
|
||||
public final class TrapDismantlePulse extends SkillPulse<Scenery> {
|
||||
|
||||
/**
|
||||
* The trap wrapper.
|
||||
*/
|
||||
private final TrapWrapper wrapper;
|
||||
|
||||
/**
|
||||
* The trap type.
|
||||
*/
|
||||
private final Traps trap;
|
||||
|
||||
/**
|
||||
* The ticks passed.
|
||||
*/
|
||||
private int ticks;
|
||||
|
||||
private final HunterManager instance;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code TrapDismantlePulse} {@code Object}.
|
||||
* @param player the player.
|
||||
* @param node the node.
|
||||
*/
|
||||
public TrapDismantlePulse(Player player, Scenery node, final TrapWrapper wrapper) {
|
||||
super(player, node);
|
||||
this.trap = wrapper.getType();
|
||||
this.wrapper = wrapper;
|
||||
this.instance = HunterManager.getInstance(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkRequirements() {
|
||||
if (wrapper == null || !instance.isOwner(node)) {
|
||||
player.sendMessage("This isn't your trap!");
|
||||
return false;
|
||||
}
|
||||
final int itemCount = wrapper.getItems().size() + (wrapper.getType().getSettings().isObjectTrap() ? 0 : 1);
|
||||
final int difference = itemCount - player.getInventory().freeSlots();
|
||||
if (player.getInventory().freeSlots() < itemCount) {
|
||||
player.getPacketDispatch().sendMessage("You don't have enough inventory space. You need " + difference + " more free slot" + (difference > 1 ? "s" : "") + ".");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void animate() {
|
||||
if (ticks < 1) {
|
||||
player.getAnimator().forceAnimation(trap.getSettings().getDismantleAnimation());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean reward() {
|
||||
if (++ticks % (trap.getSettings().getDismantleAnimation().getDefinition().getDurationTicks() + 1) != 0) {
|
||||
return false;
|
||||
}
|
||||
if (wrapper.getType().getSettings().clear(wrapper, 1)) {
|
||||
instance.deregister(wrapper);
|
||||
if (wrapper.isCaught()) {
|
||||
if (wrapper.getType().equals(Traps.BOX_TRAP)) {
|
||||
for (int i : wrapper.getReward().getNpcIds()) {
|
||||
if (i == 5080 || i == 5079) {
|
||||
SkillingPets.checkPetDrop(player, i == 5080 ? SkillingPets.BABY_RED_CHINCHOMPA : SkillingPets.BABY_GREY_CHINCHOMPA);
|
||||
}
|
||||
}
|
||||
}
|
||||
player.getSkills().addExperience(Skills.HUNTER, wrapper.getReward().getExperience(), true);
|
||||
}
|
||||
player.getPacketDispatch().sendMessage("You dismantle the trap.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void message(int type) {
|
||||
switch (type) {
|
||||
case 0:
|
||||
int ticks = wrapper.getTicks() + (wrapper.getType().getSettings().getDismantleAnimation().getDefinition().getDurationTicks()) + 1;
|
||||
wrapper.setTicks(ticks);
|
||||
wrapper.setBusyTicks(ticks);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the trap.
|
||||
* @return The trap.
|
||||
*/
|
||||
public Traps getTrap() {
|
||||
return trap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the wrapper.
|
||||
* @return The wrapper.
|
||||
*/
|
||||
public TrapWrapper getWrapper() {
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package content.global.skill.hunter;
|
||||
|
||||
import core.game.world.GameWorld;
|
||||
import core.game.world.map.Location;
|
||||
import core.tools.RandomFunction;
|
||||
|
||||
/**
|
||||
* A trap location hook.
|
||||
* @author Vexia
|
||||
*/
|
||||
public class TrapHook {
|
||||
|
||||
/**
|
||||
* The wrapper of the hook.
|
||||
*/
|
||||
private final TrapWrapper wrapper;
|
||||
|
||||
/**
|
||||
* The locations for the trap to trigger.
|
||||
*/
|
||||
private final Location[] locations;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code TrapHook} {@code Object}.
|
||||
* @param wrapper the wrapper.
|
||||
* @param locations the locations.
|
||||
*/
|
||||
public TrapHook(TrapWrapper wrapper, Location[] locations) {
|
||||
this.wrapper = wrapper;
|
||||
this.locations = locations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a location by chance for the npc to go to.
|
||||
* @return the location.
|
||||
*/
|
||||
public Location getChanceLocation() {
|
||||
final double chance = wrapper.getChanceRate();
|
||||
final int roll = RandomFunction.random(99);
|
||||
final double successChance = (GameWorld.getSettings().isDevMode() ? 100 : 55.0) + chance;
|
||||
if (successChance > roll) {
|
||||
return RandomFunction.getRandomElement(locations);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the trap is hooked.
|
||||
* @param location the location.
|
||||
* @return {@code True} if hooked.
|
||||
*/
|
||||
public boolean isHooked(Location location) {
|
||||
for (Location l : locations) {
|
||||
if (l.equals(location)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the wrapper.
|
||||
* @return The wrapper.
|
||||
*/
|
||||
public TrapWrapper getWrapper() {
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the locations.
|
||||
* @return The locations.
|
||||
*/
|
||||
public Location[] getLocations() {
|
||||
return locations;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package content.global.skill.hunter;
|
||||
|
||||
import content.data.skill.SkillingPets;
|
||||
import core.game.node.entity.npc.NPC;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.entity.skill.Skills;
|
||||
import core.game.node.item.Item;
|
||||
|
||||
/**
|
||||
* Represents a node for a trap.
|
||||
* @author Vexia
|
||||
*/
|
||||
public class TrapNode {
|
||||
|
||||
/**
|
||||
* The npc ids related to the node.
|
||||
*/
|
||||
private final int[] npcIds;
|
||||
|
||||
/**
|
||||
* The level required.
|
||||
*/
|
||||
private final int level;
|
||||
|
||||
/**
|
||||
* The experience received.
|
||||
*/
|
||||
private final double experience;
|
||||
|
||||
/**
|
||||
* The object ids for this node.
|
||||
*/
|
||||
private final int[] objectIds;
|
||||
|
||||
/**
|
||||
* The rewards received.
|
||||
*/
|
||||
private final Item[] rewards;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code TrapNode} {@code Object}.
|
||||
* @param npcIds the npc ids.
|
||||
* @param level the level.
|
||||
* @param experience the experience.
|
||||
* @param rewards the rewards.
|
||||
*/
|
||||
public TrapNode(int[] npcIds, int level, double experience, int[] objectIds, Item[] rewards) {
|
||||
this.npcIds = npcIds;
|
||||
this.level = level;
|
||||
this.experience = experience;
|
||||
this.objectIds = objectIds;
|
||||
this.rewards = rewards;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has the requirements to catch the node.
|
||||
* @param wrapper the wrapper.
|
||||
* @param npc the npc.
|
||||
* @return {@code True} if so.
|
||||
* @note Override for quests.
|
||||
*/
|
||||
public boolean canCatch(TrapWrapper wrapper, final NPC npc) {
|
||||
final Player player = wrapper.getPlayer();
|
||||
if (wrapper.isCaught() || wrapper.isBusy() || wrapper.isFailed()) {
|
||||
return false;
|
||||
}
|
||||
return player.skills.getStaticLevel(Skills.HUNTER) >= level && !npc.isInvisible();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the transform id.
|
||||
* @return the id.
|
||||
*/
|
||||
public int getTransformId() {
|
||||
return objectIds[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the final id.
|
||||
* @return the id.
|
||||
*/
|
||||
public int getFinalId() {
|
||||
return objectIds[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the npcIds.
|
||||
* @return The npcIds.
|
||||
*/
|
||||
public int[] getNpcIds() {
|
||||
return npcIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 objectIds.
|
||||
* @return The objectIds.
|
||||
*/
|
||||
public int[] getObjectIds() {
|
||||
return objectIds;
|
||||
}
|
||||
|
||||
public SkillingPets getPet() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,591 @@
|
||||
package content.global.skill.hunter;
|
||||
|
||||
import core.cache.def.impl.ItemDefinition;
|
||||
import core.cache.def.impl.SceneryDefinition;
|
||||
import core.game.node.Node;
|
||||
import core.game.node.entity.npc.NPC;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.entity.skill.Skills;
|
||||
import core.game.node.item.GroundItem;
|
||||
import core.game.node.item.GroundItemManager;
|
||||
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.update.flag.context.Animation;
|
||||
import core.tools.RandomFunction;
|
||||
|
||||
/**
|
||||
* A setting for a trap type.
|
||||
* @author Vexia
|
||||
*/
|
||||
public class TrapSetting {
|
||||
|
||||
/**
|
||||
* The node ids to create the trap.
|
||||
*/
|
||||
private final int[] nodeIds;
|
||||
|
||||
/**
|
||||
* The items required.
|
||||
*/
|
||||
private final Item[] items;
|
||||
|
||||
/**
|
||||
* The create option.
|
||||
*/
|
||||
private final String option;
|
||||
|
||||
/**
|
||||
* The level required to set the trap.
|
||||
*/
|
||||
private final int level;
|
||||
|
||||
/**
|
||||
* The setup animation of the trap.
|
||||
*/
|
||||
private final Animation setupAnimation;
|
||||
|
||||
/**
|
||||
* The animation
|
||||
*/
|
||||
private final Animation dismantleAnimation;
|
||||
|
||||
/**
|
||||
* The fail object id.
|
||||
*/
|
||||
private final int failId;
|
||||
|
||||
/**
|
||||
* The corresponding object ids.
|
||||
*/
|
||||
private final int[] objectIds;
|
||||
|
||||
/**
|
||||
* The bait ids.
|
||||
*/
|
||||
private final int[] baitIds;
|
||||
|
||||
/**
|
||||
* If it's an object trap.
|
||||
*/
|
||||
private final boolean objectTrap;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code TrapSetting} {@code Object}.
|
||||
* @param nodeIds the node ids.
|
||||
* @param items the items.
|
||||
* @param level the level.
|
||||
* @param option the option.
|
||||
* @param setupAnimation the animation.
|
||||
* @param objectTrap if an object trap.
|
||||
*/
|
||||
public TrapSetting(int[] nodeIds, Item[] items, int[] objectIds, final int[] baitIds, final String option, int level, final int failId, final Animation setupAnimation, final Animation dismantleAnimation, boolean objectTrap) {
|
||||
this.nodeIds = nodeIds;
|
||||
this.items = items;
|
||||
this.objectIds = objectIds;
|
||||
this.baitIds = baitIds;
|
||||
this.level = level;
|
||||
this.option = option;
|
||||
this.objectTrap = objectTrap;
|
||||
this.failId = failId;
|
||||
this.setupAnimation = setupAnimation;
|
||||
this.dismantleAnimation = dismantleAnimation;
|
||||
}
|
||||
|
||||
/***
|
||||
* Constructs a new {@code TrapSetting} {@code Object}.
|
||||
* @param nodeId the node id.
|
||||
* @param items the items.
|
||||
* @param option the option.
|
||||
* @param level the level.
|
||||
* @param objectTrap if an object trap.
|
||||
*/
|
||||
public TrapSetting(int nodeId, Item[] items, int[] objectIds, final int[] baitIds, final String option, int level, final int failId, final Animation setupAnimation, final Animation dismantleAnimation, boolean objectTrap) {
|
||||
this(new int[] { nodeId }, items, objectIds, baitIds, option, level, failId, setupAnimation, dismantleAnimation, objectTrap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code TrapSetting} {@code Object}.
|
||||
* @param nodeId the node id.
|
||||
* @param option the option.
|
||||
* @param objectIds the ids.
|
||||
* @param level the level.
|
||||
*/
|
||||
public TrapSetting(int nodeId, int[] objectIds, final int[] baitIds, String option, final int failId, final Animation setupAnimation, final Animation dismantleAnimation, int level) {
|
||||
this(new int[] { nodeId }, objectIds, baitIds, option, level, failId, setupAnimation, dismantleAnimation, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code TrapSetting} {@code Object}.
|
||||
* @param nodeIds the node ids.
|
||||
* @param option the option.
|
||||
* @param level the level.
|
||||
* @param objectTrap the object trap.
|
||||
*/
|
||||
public TrapSetting(int[] nodeIds, int[] objectIds, final int[] baitIds, String option, int level, final int failId, final Animation setupAnimation, final Animation dismantleAnimation, boolean objectTrap) {
|
||||
this(nodeIds, new Item[] { new Item(nodeIds[0]) }, objectIds, baitIds, option, level, failId, setupAnimation, dismantleAnimation, objectTrap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the trap.
|
||||
* @param wrapper the wrapper.
|
||||
* @param type the clear type (0=groundItems, 1=inventory)
|
||||
* @return {@code True} if cleared.
|
||||
*/
|
||||
public boolean clear(TrapWrapper wrapper, int type) {
|
||||
Scenery object = wrapper.getObject();
|
||||
returnItems(object, wrapper, type);
|
||||
wrapper.getType().getHooks().remove(wrapper.getHook());
|
||||
removeObject(wrapper);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the items to the ground or player.
|
||||
* @param object the object.
|
||||
* @param wrapper the wrapper.
|
||||
* @param type the type.
|
||||
*/
|
||||
public void returnItems(Scenery object, TrapWrapper wrapper, int type) {
|
||||
boolean ground = type == 0;
|
||||
Player player = wrapper.getPlayer();
|
||||
if (!isObjectTrap()) {
|
||||
if (ground) {
|
||||
createGroundItem(items[0], object.getLocation(), wrapper.getPlayer());
|
||||
return;
|
||||
}
|
||||
addTool(player, wrapper, type);
|
||||
player.getInventory().add(wrapper.getItems().toArray(new Item[] {}));
|
||||
} else {
|
||||
if (isObjectTrap() && !ground) {
|
||||
player.getInventory().add(wrapper.getItems().toArray(new Item[] {}));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the tool back to the inventory.
|
||||
* @param player the player.
|
||||
* @param wrapper the wrapper.
|
||||
* @param type the type.
|
||||
*/
|
||||
public void addTool(Player player, TrapWrapper wrapper, int type) {
|
||||
player.getInventory().add(items[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player has the required items.
|
||||
* @param player the player.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean hasItems(Player player) {
|
||||
for (Item item : items) {
|
||||
if (!player.getInventory().containsItem(item)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ground item.
|
||||
* @param item the item.
|
||||
* @param location the location.
|
||||
* @param player the player.
|
||||
*/
|
||||
public void createGroundItem(Item item, Location location, Player player) {
|
||||
GroundItemManager.create(new GroundItem(item, location, player));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the object from a wrapper.
|
||||
* @param wrapper the object.
|
||||
*/
|
||||
public boolean removeObject(TrapWrapper wrapper) {
|
||||
return removeObject(wrapper.getObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the object from the region.
|
||||
* @param object the object.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean removeObject(Scenery object) {
|
||||
return SceneryBuilder.remove(object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a scenery.
|
||||
* @param node the node.
|
||||
* @return the object.
|
||||
*/
|
||||
public Scenery buildObject(Player player, Node node) {
|
||||
return new Scenery(objectIds[0], player.getLocation());
|
||||
}
|
||||
|
||||
/**
|
||||
* Investigates a trap.
|
||||
* @param player the player.
|
||||
* @param object the object.
|
||||
*/
|
||||
public void investigate(Player player, Scenery object) {
|
||||
HunterManager instance = HunterManager.getInstance(player);
|
||||
if (!instance.isOwner(object)) {
|
||||
player.sendMessage("This isn't your trap.");
|
||||
return;
|
||||
}
|
||||
TrapWrapper wrapper = instance.getWrapper(object);
|
||||
player.sendMessage("This trap " + (wrapper.isSmoked() ? "has" : "hasn't") + " been smoked.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Catches an npc.
|
||||
* @param wrapper the wrapper.
|
||||
* @param npc the npc.
|
||||
*/
|
||||
public void catchNpc(final TrapWrapper wrapper, final TrapNode node, final NPC npc) {
|
||||
final boolean success = isSuccess(wrapper.getPlayer(), node);
|
||||
int ticks = success ? 3 : 2;
|
||||
npc.lock(ticks);
|
||||
wrapper.setBusyTicks(ticks);
|
||||
npc.getWalkingQueue().reset();
|
||||
npc.getPulseManager().clear();
|
||||
wrapper.setTicks(wrapper.getTicks() + 4);
|
||||
GameWorld.getPulser().submit(getCatchPulse(wrapper, node, npc, success));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the catch on a pulse.
|
||||
* @param counter the counter.
|
||||
* @param wrapper the wrapper.
|
||||
* @param node the node.
|
||||
* @param npc the npc.
|
||||
* @param success the success.
|
||||
*/
|
||||
public void handleCatch(int counter, TrapWrapper wrapper, TrapNode node, NPC npc, boolean success) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the catch pulse.
|
||||
* @param wrapper the wrapper.
|
||||
* @param node the node.
|
||||
* @param npc the npc.
|
||||
* @return the pulse.
|
||||
*/
|
||||
public Pulse getCatchPulse(final TrapWrapper wrapper, final TrapNode node, final NPC npc, final boolean success) {
|
||||
final Player player = wrapper.getPlayer();
|
||||
wrapper.setFailed(!success);
|
||||
return new Pulse(1) {
|
||||
int counter;
|
||||
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
switch (++counter) {
|
||||
case 2:
|
||||
handleCatch(counter, wrapper, node, npc, success);
|
||||
if (success) {
|
||||
int transformId = getTransformId(wrapper, node);
|
||||
npc.setAttribute("hunter", GameWorld.getTicks() + 6);
|
||||
npc.finalizeDeath(player);
|
||||
if (transformId != -1) {
|
||||
wrapper.setObject(getTransformId(wrapper, node));
|
||||
}
|
||||
npc.getProperties().setTeleportLocation(npc.getProperties().getSpawnLocation());
|
||||
break;
|
||||
}
|
||||
npc.moveStep();
|
||||
wrapper.setObject(getFailId(wrapper, node));
|
||||
break;
|
||||
case 3:
|
||||
handleCatch(counter, wrapper, node, npc, success);
|
||||
if (success) {
|
||||
wrapper.setTicks(GameWorld.getTicks() + 100);
|
||||
wrapper.setReward(node);
|
||||
wrapper.setObject(getFinalId(wrapper, node));
|
||||
return true;
|
||||
}
|
||||
npc.moveStep();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the catch was successfull.
|
||||
* @param player the player.
|
||||
* @param node the node.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean isSuccess(Player player, final TrapNode node) {
|
||||
double level = player.skills.getStaticLevel(Skills.HUNTER);
|
||||
double req = node.getLevel();
|
||||
double successChance = Math.ceil((level * 50 - req * 17) / req / 3 * 4);
|
||||
int roll = RandomFunction.random(99);
|
||||
if (successChance >= roll) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a trap hook.
|
||||
* @param wrapper the wrapper.
|
||||
* @return the hook.
|
||||
*/
|
||||
public TrapHook createHook(TrapWrapper wrapper) {
|
||||
return new TrapHook(wrapper, new Location[] { wrapper.getObject().getLocation() });
|
||||
}
|
||||
|
||||
/**
|
||||
* Calles when an object is setup.
|
||||
* @param player the player.
|
||||
* @param node the node.
|
||||
* @param wrapper the wrapper.
|
||||
*/
|
||||
public void reward(Player player, Node node, TrapWrapper wrapper) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A global method to check if a catch can be made.
|
||||
* @param wrapper the wrapper.
|
||||
* @param npc the npc.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean canCatch(TrapWrapper wrapper, NPC npc) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the bait corresponds.
|
||||
* @param bait the bait.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean hasBait(Item bait) {
|
||||
for (int id : getBaitIds()) {
|
||||
if (id == bait.getId()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the node for the object.
|
||||
* @param objectId the object.
|
||||
* @return the node id.
|
||||
*/
|
||||
public int getNodeForObjectId(int objectId) {
|
||||
return getNodeForObject(getObjectIndex(objectId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the node for the object.
|
||||
* @param index the index.
|
||||
* @return the id.
|
||||
*/
|
||||
public int getNodeForObject(int index) {
|
||||
return nodeIds[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the object id for the node.
|
||||
* @param node the node. the id.
|
||||
*/
|
||||
public int getObjectForNode(Node node) {
|
||||
return getObjectForNode(getNodeIndex(node));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the object id for the node.
|
||||
* @param index the index.
|
||||
* @return the id.
|
||||
*/
|
||||
public int getObjectForNode(int index) {
|
||||
return objectIds[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the node index.
|
||||
* @param node the node.
|
||||
* @return the index.
|
||||
*/
|
||||
public int getNodeIndex(Node node) {
|
||||
for (int i = 0; i < nodeIds.length; i++) {
|
||||
if (node.getId() == nodeIds[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the object index.
|
||||
* @param objectId the object.
|
||||
* @return the index.
|
||||
*/
|
||||
public int getObjectIndex(int objectId) {
|
||||
for (int i = 0; i < objectIds.length; i++) {
|
||||
if (objectId == objectIds[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the transform id.
|
||||
* @param node the node.
|
||||
* @param wrapper the object.
|
||||
* @return the id.
|
||||
*/
|
||||
public int getTransformId(TrapWrapper wrapper, TrapNode node) {
|
||||
return node.getTransformId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the final id.
|
||||
* @param wrapper the wrapper.
|
||||
* @param node the node.
|
||||
* @return the id.
|
||||
*/
|
||||
public int getFinalId(TrapWrapper wrapper, TrapNode node) {
|
||||
return node.getFinalId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the failId.
|
||||
* @param wrapper the wrapper.
|
||||
* @param node the node.
|
||||
* @return The failId.
|
||||
*/
|
||||
public int getFailId(TrapWrapper wrapper, TrapNode node) {
|
||||
return failId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the limit message.
|
||||
* @param player the player.
|
||||
* @return the message.
|
||||
*/
|
||||
public String getLimitMessage(Player player) {
|
||||
HunterManager instance = HunterManager.getInstance(player);
|
||||
return "You don't have a high enough Hunter level to set up more than " + instance.getMaximumTraps() + " trap" + (instance.getMaximumTraps() == 1 ? "." : "s.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the trap.
|
||||
* @return the name.
|
||||
*/
|
||||
public String getName() {
|
||||
if (isObjectTrap()) {
|
||||
return SceneryDefinition.forId(nodeIds[0]).getName().toLowerCase();
|
||||
}
|
||||
return ItemDefinition.forId(nodeIds[0]).getName().toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the time up message.
|
||||
* @return the message.
|
||||
*/
|
||||
public String getTimeUpMessage() {
|
||||
return "The " + getName() + " " + (isObjectTrap() ? "trap that you constructed has collapsed." : "that you laid has fallen over.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if adding this trap will exceed the limit.
|
||||
* @param player the player.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean exceedsLimit(Player player) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the objectTrap.
|
||||
* @return The objectTrap.
|
||||
*/
|
||||
public boolean isObjectTrap() {
|
||||
return objectTrap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the nodeIds.
|
||||
* @return The nodeIds.
|
||||
*/
|
||||
public int[] getNodeIds() {
|
||||
return nodeIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the items.
|
||||
* @return The items.
|
||||
*/
|
||||
public Item[] getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the option.
|
||||
* @return The option.
|
||||
*/
|
||||
public String getOption() {
|
||||
return option;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the level.
|
||||
* @return The level.
|
||||
*/
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the setupAnimation.
|
||||
* @return The setupAnimation.
|
||||
*/
|
||||
public Animation getSetupAnimation() {
|
||||
return setupAnimation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the objectIds.
|
||||
* @return The objectIds.
|
||||
*/
|
||||
public int[] getObjectIds() {
|
||||
return objectIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the dismantleAnimation.
|
||||
* @return The dismantleAnimation.
|
||||
*/
|
||||
public Animation getDismantleAnimation() {
|
||||
return dismantleAnimation;
|
||||
}
|
||||
|
||||
/**
|
||||
* The fail id.
|
||||
* @return the id.
|
||||
*/
|
||||
public int getFailId() {
|
||||
return failId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the baitIds.
|
||||
* @return The baitIds.
|
||||
*/
|
||||
public int[] getBaitIds() {
|
||||
return baitIds;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,422 @@
|
||||
package content.global.skill.hunter;
|
||||
|
||||
import core.game.node.entity.skill.Skills;
|
||||
import content.global.skill.hunter.NetTrapSetting.NetTrap;
|
||||
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.update.flag.context.Animation;
|
||||
import core.game.world.update.flag.context.Graphics;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A wrapper class for a trap object.
|
||||
* @author Vexia
|
||||
*/
|
||||
public final class TrapWrapper {
|
||||
|
||||
/**
|
||||
* The items to be recieved on trap clearing.
|
||||
*/
|
||||
private final List<Item> items = new ArrayList<>(10);
|
||||
|
||||
/**
|
||||
* The player instance.
|
||||
*/
|
||||
private final Player player;
|
||||
|
||||
/**
|
||||
* The type of trap.
|
||||
*/
|
||||
private final Traps type;
|
||||
|
||||
/**
|
||||
* The net type if net trapping.
|
||||
*/
|
||||
private NetTrap netType;
|
||||
|
||||
/**
|
||||
* The original object id.
|
||||
*/
|
||||
private final int originalId;
|
||||
|
||||
/**
|
||||
* The object of the trap.
|
||||
*/
|
||||
private Scenery object;
|
||||
|
||||
/**
|
||||
* The secondary scenery.
|
||||
*/
|
||||
private Scenery secondary;
|
||||
|
||||
/**
|
||||
* The trap hook.
|
||||
*/
|
||||
private TrapHook hook;
|
||||
|
||||
/**
|
||||
* The reward of the trap.
|
||||
*/
|
||||
private TrapNode reward;
|
||||
|
||||
/**
|
||||
* If the trap has been smoked.
|
||||
*/
|
||||
private boolean smoked;
|
||||
|
||||
/**
|
||||
* If the trap has been baited.
|
||||
*/
|
||||
private boolean baited;
|
||||
|
||||
/**
|
||||
* If the trap has failed.
|
||||
*/
|
||||
private boolean failed;
|
||||
|
||||
/**
|
||||
* If the trap is currently in an reward.
|
||||
*/
|
||||
private int busyTicks;
|
||||
|
||||
/**
|
||||
* The tick when the life is up.
|
||||
*/
|
||||
private int ticks;
|
||||
|
||||
private HunterManager instance;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code TrapWrapper} {@code Object}.
|
||||
* @param player the player.
|
||||
* @param type the type.
|
||||
* @param object the object.
|
||||
*/
|
||||
public TrapWrapper(final Player player, Traps type, Scenery object) {
|
||||
this.player = player;
|
||||
this.type = type;
|
||||
this.object = object;
|
||||
this.originalId = object.getId();
|
||||
this.ticks = GameWorld.getTicks() + (100);
|
||||
this.instance = HunterManager.getInstance(player);
|
||||
this.object.getAttributes().setAttribute("trap-uid", instance.getUid());
|
||||
}
|
||||
|
||||
/**
|
||||
* Cycles this trap wrapper.
|
||||
* @return {@code True} to deregister the trap.
|
||||
*/
|
||||
public boolean cycle() {
|
||||
if (isTimeUp() && type.getSettings().clear(this, 0)) {
|
||||
if (!isCaught()) {
|
||||
player.sendMessage(type.getSettings().getTimeUpMessage());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the new object of the wrapper.
|
||||
* @param id the id.
|
||||
*/
|
||||
public void setObject(final int id) {
|
||||
Scenery newObject = object.transform(id);
|
||||
SceneryBuilder.remove(object);
|
||||
this.object = SceneryBuilder.add(newObject);
|
||||
this.object.getAttributes().setAttribute("trap-uid", instance.getUid());
|
||||
}
|
||||
|
||||
/**
|
||||
* Smokes the trap.
|
||||
*/
|
||||
public void smoke() {
|
||||
if (smoked) {
|
||||
player.sendMessage("This trap has already been smoked.");
|
||||
return;
|
||||
}
|
||||
if (player.skills.getStaticLevel(Skills.HUNTER) < 39) {
|
||||
player.sendMessage("You need a Hunter level of at least 39 to be able to smoke traps.");
|
||||
return;
|
||||
}
|
||||
smoked = true;
|
||||
player.lock(4);
|
||||
player.visualize(new Animation(5208), new Graphics(931));
|
||||
player.sendMessage("You use the smoke from the torch to remove your scent from the trap.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Baits the trap.
|
||||
*/
|
||||
public void bait(Item bait) {
|
||||
if (baited) {
|
||||
player.sendMessage("This trap has already been baited.");
|
||||
return;
|
||||
}
|
||||
if (!type.getSettings().hasBait(bait)) {
|
||||
player.sendMessage("You can't use that on this trap.");
|
||||
return;
|
||||
}
|
||||
baited = true;
|
||||
bait = new Item(bait.getId(), 1);
|
||||
player.getInventory().remove(new Item(bait.getId(), 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the chance ratio of luring.
|
||||
* @return the chance rate.
|
||||
*/
|
||||
public double getChanceRate() {
|
||||
double chance = 0.0;
|
||||
if (baited) {
|
||||
chance += 1.0;
|
||||
}
|
||||
if (smoked) {
|
||||
chance += 1.0;
|
||||
}
|
||||
chance += HunterGear.getChanceRate(player);
|
||||
return chance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds items to the recieved list.
|
||||
* @param items the items.
|
||||
*/
|
||||
public void addItem(Item... items) {
|
||||
for (Item item : items) {
|
||||
addItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an item to the recieved list.
|
||||
* @param item the item.
|
||||
*/
|
||||
public void addItem(Item item) {
|
||||
items.add(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the time is up.
|
||||
* @return {@code True} if o.
|
||||
*/
|
||||
private boolean isTimeUp() {
|
||||
return ticks < GameWorld.getTicks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type.
|
||||
* @return The type.
|
||||
*/
|
||||
public Traps getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the object.
|
||||
* @return The object.
|
||||
*/
|
||||
public Scenery getObject() {
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* The original id.
|
||||
* @return the id.
|
||||
*/
|
||||
public int getOriginalId() {
|
||||
return originalId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player.
|
||||
* @return The player.
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ticks.
|
||||
* @return The ticks.
|
||||
*/
|
||||
public int getTicks() {
|
||||
return ticks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ticks.
|
||||
* @param ticks The ticks to set.
|
||||
*/
|
||||
public void setTicks(int ticks) {
|
||||
this.ticks = ticks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the smoked.
|
||||
* @return The smoked.
|
||||
*/
|
||||
public boolean isSmoked() {
|
||||
return smoked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the smoked.
|
||||
* @param smoked The smoked to set.
|
||||
*/
|
||||
public void setSmoked(boolean smoked) {
|
||||
this.smoked = smoked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hook.
|
||||
* @return The hook.
|
||||
*/
|
||||
public TrapHook getHook() {
|
||||
return hook;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the hook.
|
||||
* @param hook The hook to set.
|
||||
*/
|
||||
public void setHook(TrapHook hook) {
|
||||
this.hook = hook;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the baited.
|
||||
* @return The baited.
|
||||
*/
|
||||
public boolean isBaited() {
|
||||
return baited;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the baited.
|
||||
* @param baited The baited to set.
|
||||
*/
|
||||
public void setBaited(boolean baited) {
|
||||
this.baited = baited;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the trap has been caught.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean isCaught() {
|
||||
return getReward() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the reward.
|
||||
* @return The reward.
|
||||
*/
|
||||
public TrapNode getReward() {
|
||||
return reward;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the reward.
|
||||
* @param reward The reward to set.
|
||||
*/
|
||||
public void setReward(TrapNode reward) {
|
||||
this.reward = reward;
|
||||
this.addItem(reward.getRewards());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the trap is busy.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean isBusy() {
|
||||
return getBusyTicks() > GameWorld.getTicks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the busyTicks.
|
||||
* @return The busyTicks.
|
||||
*/
|
||||
public int getBusyTicks() {
|
||||
return busyTicks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the busyTicks.
|
||||
* @param busyTicks The busyTicks to set.
|
||||
*/
|
||||
public void setBusyTicks(int busyTicks) {
|
||||
this.busyTicks = GameWorld.getTicks() + busyTicks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the items.
|
||||
* @return The items.
|
||||
*/
|
||||
public List<Item> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the secondary.
|
||||
* @return The secondary.
|
||||
*/
|
||||
public Scenery getSecondary() {
|
||||
return secondary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the secondary.
|
||||
* @param secondary The secondary to set.
|
||||
*/
|
||||
public void setSecondary(Scenery secondary) {
|
||||
this.secondary = secondary;
|
||||
this.secondary.getAttributes().setAttribute("trap-uid", player.getName().hashCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the netType.
|
||||
* @return The netType.
|
||||
*/
|
||||
public NetTrap getNetType() {
|
||||
return netType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the netType.
|
||||
* @param netType The netType to set.
|
||||
*/
|
||||
public void setNetType(NetTrap netType) {
|
||||
this.netType = netType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the object.
|
||||
* @param object The object to set.
|
||||
*/
|
||||
public void setObject(Scenery object) {
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the failed.
|
||||
* @return The failed.
|
||||
*/
|
||||
public boolean isFailed() {
|
||||
return failed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the failed.
|
||||
* @param failed The failed to set.
|
||||
*/
|
||||
public void setFailed(boolean failed) {
|
||||
this.failed = failed;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,253 @@
|
||||
package content.global.skill.hunter;
|
||||
|
||||
import core.game.node.Node;
|
||||
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.tools.SystemLogger;
|
||||
import core.game.world.map.Location;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a trap type.
|
||||
* @author Vexia
|
||||
*/
|
||||
public enum Traps {
|
||||
BIRD_SNARE(new TrapSetting(10006, new int[] { 19175 }, new int[] {}, "lay", 19174, Animation.create(5208), Animation.create(5207), 1),
|
||||
new TrapNode(new int[] { 5073 }, 1, 34, new int[] { 19179, 19180 }, new Item[] { new Item(10088, 8), new Item(9978), new Item(526) }),
|
||||
new TrapNode(new int[] { 5075 }, 5, 48, new int[] { 19183, 19184 }, new Item[] { new Item(10090, 8), new Item(9978), new Item(526) }),
|
||||
new TrapNode(new int[] { 5076 }, 9, 61, new int[] { 19185, 19186 }, new Item[] { new Item(10091, 8), new Item(9978), new Item(526) }),
|
||||
new TrapNode(new int[] { 5074 }, 11, 64.7, new int[] { 19181, 19182 }, new Item[] { new Item(10089, 8), new Item(9978), new Item(526) }),
|
||||
new TrapNode(new int[] { 5072 }, 19, 95.2, new int[] { 19177, 19178 }, new Item[] { new Item(10087, 8), new Item(9978), new Item(526) }),
|
||||
new TrapNode(new int[] { 7031 }, 39, 167, new int[] { 28931, 28930 }, new Item[] { new Item(11525, 8), new Item(9978), new Item(526) }) {
|
||||
@Override
|
||||
public boolean canCatch(TrapWrapper wrapper, final NPC npc) {
|
||||
return false;
|
||||
}
|
||||
}),
|
||||
BOX_TRAP(new TrapSetting(10008, new int[] { 19187 }, new int[] { 1963, 12579, 1869, 9996, 5972, 12535 }, "lay", 19192, Animation.create(5208), new Animation(9726), 27),
|
||||
new BoxTrapNode(new int[] { 5081 }, 27, 100, new Item[] { new Item(10092) }, 1),
|
||||
new BoxTrapNode(new int[] { 6918, 7289, 7290, 7291, 7292 }, 27, 100, new Item[] { new Item(12184) }, 10),
|
||||
new BoxTrapNode(new int[] { 1487 }, 27, 100, new Item[] { new Item(4033, 1) }, 95),
|
||||
new BoxTrapNode(new int[] { 7021, 7022, 7023 }, 48, 150, new Item[] { new Item(12551, 1) }, 1),
|
||||
new BoxTrapNode(new int[] { 5079 }, 53, 198, new Item[] { new Item(10033, 1) }, 1),
|
||||
new BoxTrapNode(new int[] { 5428, 5430, 5449, 5450, 5451 }, 56, 150, new Item[] { new Item(12188) }, 1),
|
||||
new BoxTrapNode(new int[] { 5080 }, 63, 265, new Item[] { new Item(10034, 1) }, 1),
|
||||
new BoxTrapNode(new int[] { 7012, 7014 }, 66, 400, new Item[] { new Item(12535) }, 1),
|
||||
new BoxTrapNode(new int[] { 8654 }, 73, 315, new Item[] { new Item(14861) }, 1),
|
||||
new BoxTrapNode(new int[] { 7010, 7011 }, 77, 726, new Item[] { new Item(12539, 1) }, 1)),
|
||||
RABBIT_SNARE(new TrapSetting(10031, new int[] { 19333 }, new int[] {}, "lay", -1, Animation.create(5208), Animation.create(9726), 27)),
|
||||
IMP_BOX(new MagicBoxSetting(),
|
||||
new TrapNode(new int[] { 708, 709, 1531 }, 71, 450, new int[] { -1, 19226 }, new Item[] { new Item(10027) })),
|
||||
DEAD_FALL(new DeadfallSetting(),
|
||||
new TrapNode(new int[] { 5089 }, 23, 128, new int[] { 19213, 19214, 19218 }, new Item[] { new Item(10113), new Item(526) }),
|
||||
new TrapNode(new int[] { 5088 }, 33, 168, new int[] { 19211, 19212, 19217 }, new Item[] { new Item(10129), new Item(526) }),
|
||||
new TrapNode(new int[] { 5086 }, 37, 204, new int[] { 19208, 19208, 19217 }, new Item[] { new Item(10105), new Item(526) }),
|
||||
new TrapNode(new int[] { 7039 }, 44, 200, new int[] { 28939, 28940, 28941 }, new Item[] { new Item(12567), new Item(526) }),
|
||||
new TrapNode(new int[] { 5087 }, 51, 200, new int[] { 19209, 19210, 19216 }, new Item[] { new Item(10109), new Item(526) })),
|
||||
NET_TRAP(new NetTrapSetting(), new TrapNode(new int[] { 5117 }, 29, 152, new int[] {}, new Item[] { new Item(10149) }),
|
||||
new TrapNode(new int[] { 5114 }, 47, 224, new int[] {}, new Item[] { new Item(10146) }),
|
||||
new TrapNode(new int[] { 6921 }, 29, 152, new int[] {}, new Item[] { new Item(12130) }),
|
||||
new TrapNode(new int[] { 5115 }, 59, 272, new int[] {}, new Item[] { new Item(10147) }),
|
||||
new TrapNode(new int[] { 5116 }, 67, 304, new int[] {}, new Item[] { new Item(10148) }));
|
||||
|
||||
/**
|
||||
* The location hooks for this node.
|
||||
*/
|
||||
private final List<TrapHook> hooks = new ArrayList<>(5);
|
||||
|
||||
/**
|
||||
* The trap settings.
|
||||
*/
|
||||
private final TrapSetting settings;
|
||||
|
||||
/**
|
||||
* The nodes related to the trap.
|
||||
*/
|
||||
private final TrapNode[] nodes;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code TrapType} {@code Object}.
|
||||
* @param settings the settings.
|
||||
* @param nodes the nodes.
|
||||
*/
|
||||
Traps(TrapSetting settings, TrapNode... nodes) {
|
||||
this.settings = settings;
|
||||
this.nodes = nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a trap instance.
|
||||
* @param player the player.
|
||||
*/
|
||||
public void create(Player player, Node node) {
|
||||
player.getPulseManager().run(new TrapCreatePulse(player, node, this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismantles a trap.
|
||||
* @param player the player.
|
||||
* @param object the object.
|
||||
*/
|
||||
public void dismantle(Player player, Scenery object) {
|
||||
HunterManager instance = HunterManager.getInstance(player);
|
||||
|
||||
if (!instance.isOwner(object)) {
|
||||
player.sendMessage("This isn't your trap!");
|
||||
return;
|
||||
}
|
||||
if (instance.getWrapper(object) == null) {
|
||||
SystemLogger.logErr(this.getClass(), "NO WRAPPER (HUNTER DISMANTLE)");
|
||||
return;
|
||||
}
|
||||
player.faceLocation(object.getLocation());
|
||||
player.getPulseManager().run(new TrapDismantlePulse(player, object, instance.getWrapper(object)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Investigates the trap.
|
||||
* @param player the player.
|
||||
* @param object the object.
|
||||
*/
|
||||
public void investigate(Player player, Scenery object) {
|
||||
getSettings().investigate(player, object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an npc is hooked.
|
||||
* @param wrapper the wrapper.
|
||||
* @param npc the npc.
|
||||
*/
|
||||
public void catchNpc(TrapWrapper wrapper, NPC npc) {
|
||||
final TrapNode trapNode = forNpc(npc);
|
||||
if (trapNode == null || !trapNode.canCatch(wrapper, npc) || !settings.canCatch(wrapper, npc)) {
|
||||
return;
|
||||
}
|
||||
settings.catchNpc(wrapper, trapNode, npc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a hook.
|
||||
* @param wrapper the wrapper.
|
||||
*/
|
||||
public TrapHook addHook(TrapWrapper wrapper) {
|
||||
TrapHook hook = settings.createHook(wrapper);
|
||||
hooks.add(hook);
|
||||
return hook;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a node by the npc.
|
||||
* @param npc the npc.
|
||||
* @return the node.
|
||||
*/
|
||||
public TrapNode forNpc(NPC npc) {
|
||||
for (TrapNode node : nodes) {
|
||||
for (int npcId : node.getNpcIds()) {
|
||||
if (npcId == npc.getId()) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a trap by the node id.
|
||||
* @param node the node.
|
||||
* @return the {@code Traps}.
|
||||
*/
|
||||
public static Traps forNode(Node node) {
|
||||
for (Traps trap : Traps.values()) {
|
||||
for (int nodeId : trap.getSettings().getNodeIds()) {
|
||||
if (node.getId() == nodeId) {
|
||||
return trap;
|
||||
}
|
||||
}
|
||||
for (int objectId : trap.getSettings().getObjectIds()) {
|
||||
if (objectId == node.getId()) {
|
||||
return trap;
|
||||
}
|
||||
}
|
||||
for (TrapNode n : trap.getNodes()) {
|
||||
for (int id : n.getObjectIds()) {
|
||||
if (id == node.getId()) {
|
||||
return trap;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (trap.getSettings().getFailId() == node.getId()) {
|
||||
return trap;
|
||||
}
|
||||
if (trap == NET_TRAP) {
|
||||
for (NetTrapSetting.NetTrap net : NetTrapSetting.NetTrap.values()) {
|
||||
if (net.getOriginal() == node.getId() || net.getFailed() == node.getId() || net.getNet() == node.getId() || net.getBent() == node.getId() || net.getCaught() == node.getId()) {
|
||||
return trap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a trap node by the id.
|
||||
* @param id the id.
|
||||
* @return the node.
|
||||
*/
|
||||
public static Object[] getNode(int id) {
|
||||
for (Traps trap : values()) {
|
||||
for (TrapNode t : trap.getNodes()) {
|
||||
for (int i : t.getNpcIds()) {
|
||||
if (i == id) {
|
||||
return new Object[] { trap, t };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the wrapper by the hook.
|
||||
* @param location the location.
|
||||
* @return the wrapper.
|
||||
*/
|
||||
public TrapWrapper getByHook(Location location) {
|
||||
for (TrapHook hook : hooks) {
|
||||
if (hook.isHooked(location)) {
|
||||
return hook.getWrapper();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the settings.
|
||||
* @return The settings.
|
||||
*/
|
||||
public TrapSetting getSettings() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the nodes.
|
||||
* @return The nodes.
|
||||
*/
|
||||
public TrapNode[] getNodes() {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hooks.
|
||||
* @return The hooks.
|
||||
*/
|
||||
public List<TrapHook> getHooks() {
|
||||
return hooks;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
package content.global.skill.hunter.bnet;
|
||||
|
||||
import core.cache.def.impl.NPCDefinition;
|
||||
import core.game.container.impl.EquipmentContainer;
|
||||
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.world.update.flag.context.Graphics;
|
||||
|
||||
/**
|
||||
* A butterfly net node.
|
||||
* @author Vexia
|
||||
*/
|
||||
public class BNetNode {
|
||||
|
||||
/**
|
||||
* The butterfly jar item.
|
||||
*/
|
||||
private static final Item BUTTERFLY_JAR = new Item(10012);
|
||||
|
||||
/**
|
||||
* The impling jar item.
|
||||
*/
|
||||
protected static final Item IMPLING_JAR = new Item(11260);
|
||||
|
||||
/**
|
||||
* The npcs related to this node.
|
||||
*/
|
||||
private final int[] npcs;
|
||||
|
||||
/**
|
||||
* The levels needed.
|
||||
*/
|
||||
private final int[] levels;
|
||||
|
||||
/**
|
||||
* The experience gained.
|
||||
*/
|
||||
private final double[] experience;
|
||||
|
||||
/**
|
||||
* The graphics related to the node.
|
||||
*/
|
||||
private final Graphics[] graphics;
|
||||
|
||||
/**
|
||||
* The reward item.
|
||||
*/
|
||||
private final Item reward;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ButterflyNetNode} {@code Object}.
|
||||
* @param npcs the npcs.
|
||||
* @param levels the levels.
|
||||
* @param experience the experience.
|
||||
* @param graphics the graphics.
|
||||
*/
|
||||
public BNetNode(int[] npcs, int[] levels, double[] experience, Graphics[] graphics, Item reward) {
|
||||
this.npcs = npcs;
|
||||
this.levels = levels;
|
||||
this.experience = experience;
|
||||
this.graphics = graphics;
|
||||
this.reward = reward;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewards the player.
|
||||
* @param player the player.
|
||||
* @param npc the npc.
|
||||
*/
|
||||
public void reward(Player player, NPC npc) {
|
||||
if (!isBareHand(player)) {
|
||||
if (player.getInventory().remove(getJar())) {
|
||||
final Item item = getReward();
|
||||
player.getInventory().add(item);
|
||||
player.getSkills().addExperience(Skills.HUNTER, getExperience(player), true);
|
||||
}
|
||||
} else {
|
||||
player.graphics(graphics[0]);
|
||||
player.getSkills().addExperience(Skills.HUNTER, getExperiences()[1], true);
|
||||
player.getSkills().addExperience(Skills.AGILITY, getExperiences()[2], true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a message event.
|
||||
* @param type the type.
|
||||
* @param success the success.
|
||||
*/
|
||||
public void message(Player player, int type, boolean success) {
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
switch (type) {
|
||||
case 1:
|
||||
player.getPacketDispatch().sendMessage("You manage to catch the butterfly.");
|
||||
if (isBareHand(player)) {
|
||||
player.getPacketDispatch().sendMessage("You release the " + NPCDefinition.forId(npcs[0]).getName().toLowerCase() + " butterfly.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player has a jar.
|
||||
* @param player the player.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean hasJar(Player player) {
|
||||
return player.getInventory().containsItem(getJar());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player has a weapon.
|
||||
* @param player the player.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean hasWeapon(Player player) {
|
||||
Item item = player.getEquipment().get(EquipmentContainer.SLOT_WEAPON);
|
||||
return item != null && (item.getId() != 10010 && item.getId() != 11259);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player has a net.
|
||||
* @param player the player.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean hasNet(Player player) {
|
||||
return player.getEquipment().contains(10010, 1) || player.getEquipment().contains(11259, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player is bare handed.
|
||||
* @param player the player.
|
||||
* @return {@code} True if so.
|
||||
*/
|
||||
public boolean isBareHand(Player player) {
|
||||
return !hasNet(player) && player.getSkills().getLevel(Skills.HUNTER) >= getBareHandLevel() && player.getSkills().getLevel(Skills.AGILITY) >= getAgilityLevel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the experience in hunter.
|
||||
* @return the exp.
|
||||
*/
|
||||
public double getExperience(Player player) {
|
||||
return experience[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hunter level.
|
||||
* @return the level.
|
||||
*/
|
||||
public int getLevel() {
|
||||
return levels[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the agility level.
|
||||
* @return the level.
|
||||
*/
|
||||
public int getAgilityLevel() {
|
||||
return levels[2];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bare hand level.
|
||||
* @return the level.
|
||||
*/
|
||||
public int getBareHandLevel() {
|
||||
return levels[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the npcs.
|
||||
* @return The npcs.
|
||||
*/
|
||||
public int[] getNpcs() {
|
||||
return npcs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the levels.
|
||||
* @return The levels.
|
||||
*/
|
||||
public int[] getLevels() {
|
||||
return levels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the experience.
|
||||
* @return The experience.
|
||||
*/
|
||||
public double[] getExperiences() {
|
||||
return experience;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the graphics.
|
||||
* @return The graphics.
|
||||
*/
|
||||
public Graphics[] getGraphics() {
|
||||
return graphics;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the reward.
|
||||
* @return The reward.
|
||||
*/
|
||||
public Item getReward() {
|
||||
return reward;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the jar.
|
||||
* @return the jar.
|
||||
*/
|
||||
public Item getJar() {
|
||||
return BUTTERFLY_JAR;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
package content.global.skill.hunter.bnet;
|
||||
|
||||
import core.game.container.impl.EquipmentContainer;
|
||||
import core.game.node.entity.skill.SkillPulse;
|
||||
import core.game.node.entity.skill.Skills;
|
||||
import core.game.node.entity.combat.DeathTask;
|
||||
import core.game.node.entity.npc.NPC;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.item.Item;
|
||||
import core.game.world.GameWorld;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
import core.tools.RandomFunction;
|
||||
import core.tools.StringUtils;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Handles the butterfly net catch pulse.
|
||||
* @author Vexia
|
||||
*/
|
||||
public final class BNetPulse extends SkillPulse<NPC> {
|
||||
|
||||
/**
|
||||
* The swinging animation.
|
||||
*/
|
||||
private static final Animation ANIMATION = new Animation(6999);
|
||||
|
||||
/**
|
||||
* The net node.
|
||||
*/
|
||||
private final BNetNode type;
|
||||
|
||||
/**
|
||||
* If we are successfull.
|
||||
*/
|
||||
private boolean success;
|
||||
|
||||
/**
|
||||
* The ticks passed.
|
||||
*/
|
||||
private int ticks;
|
||||
|
||||
/**
|
||||
* Update lumbridge impling task, makes sure we're in puro puro and checks diary entry completion
|
||||
* @returns false if not in puro puro, true and updates diary if in puro puro
|
||||
*/
|
||||
public boolean updateLumbridgeImplingTask(Player player) {
|
||||
if(!player.getZoneMonitor().isInZone("puro puro")){
|
||||
return false;
|
||||
} else {
|
||||
/* if(!player.getAchievementDiaryManager().hasCompletedTask(DiaryType.LUMBRIDGE,1,8)){
|
||||
player.getAchievementDiaryManager().updateTask(player,DiaryType.LUMBRIDGE,1,8,true);
|
||||
}*/
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code BNetPulse} {@code Object}.
|
||||
* @param player the player.
|
||||
* @param node the node.
|
||||
* @param type the type.
|
||||
*/
|
||||
public BNetPulse(Player player, NPC node, BNetNode type) {
|
||||
super(player, node);
|
||||
this.type = type;
|
||||
this.resetAnimation = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkRequirements() {
|
||||
if (player.getSkills().getLevel(Skills.HUNTER) < type.getLevel()) {
|
||||
player.sendMessage("You need a Hunter level of at least " + type.getLevel() + " in order to do that.");
|
||||
return false;
|
||||
}
|
||||
if (!type.isBareHand(player)) {
|
||||
if (type.hasWeapon(player)) {
|
||||
player.getPacketDispatch().sendMessage("Your hands need to be free.");
|
||||
return false;
|
||||
} else if (!type.hasNet(player)) {
|
||||
player.sendMessage("You need to be wielding a butterfly net to catch " + (type instanceof ImplingNode ? "implings" : "butterflies") + ".");
|
||||
return false;
|
||||
} else if (!type.hasJar(player)) {
|
||||
player.getPacketDispatch().sendMessage("You need to have a" + (StringUtils.isPlusN(type.getJar().getName()) ? "n" : "") + " " + type.getJar().getName().toLowerCase() + ".");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (node.isInvisible() || DeathTask.isDead(node)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void animate() {
|
||||
if (ticks < 1) {
|
||||
player.animate(ANIMATION);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean reward() {
|
||||
if (node.isInvisible() || DeathTask.isDead(node)) {
|
||||
return true;
|
||||
}
|
||||
if (++ticks % 2 != 0) {
|
||||
return false;
|
||||
}
|
||||
if (node.getAttribute("dead", 0) > GameWorld.getTicks()) {
|
||||
player.sendMessage("Ooops! It's gone.");
|
||||
return true;
|
||||
}
|
||||
if ((success = isSuccessful())) {
|
||||
node.finalizeDeath(player);
|
||||
type.reward(player, node);
|
||||
node.setAttribute("dead", GameWorld.getTicks() + 10);
|
||||
if (type == BNetTypes.ECLECTIC_IMPLING.getNode() || type == BNetTypes.ESSENCE_IMPLING.getNode() ) {
|
||||
updateLumbridgeImplingTask(player);
|
||||
}
|
||||
} else {
|
||||
node.moveStep();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void message(int type) {
|
||||
if (type == 0) {
|
||||
node.setAttribute("looting", GameWorld.getTicks() + (ANIMATION.getDuration() + 1));
|
||||
player.lock(ANIMATION.getDuration());
|
||||
}
|
||||
this.type.message(player, type, success);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player has succesfully caught the impling.
|
||||
* @return {@code True} if succesful, {@code false} if not.
|
||||
*/
|
||||
private boolean isSuccessful() {
|
||||
int huntingLevel = player.getSkills().getLevel(Skills.HUNTER);
|
||||
int level = type.getLevel();
|
||||
if (type.hasNet(player)) {
|
||||
Item net = player.getEquipment().get(EquipmentContainer.SLOT_WEAPON);
|
||||
if (net != null && net.getId() == 11259) {
|
||||
huntingLevel += 5;
|
||||
}
|
||||
} else {
|
||||
huntingLevel *= 0.5;
|
||||
}
|
||||
int currentLevel = RandomFunction.random(huntingLevel) + 1;
|
||||
double ratio = (double) currentLevel / (new Random().nextInt(level + 5) + 1);
|
||||
return Math.round(ratio * huntingLevel) >= level;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
package content.global.skill.hunter.bnet;
|
||||
|
||||
import core.game.node.entity.npc.NPC;
|
||||
import core.game.node.entity.npc.drop.DropFrequency;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.item.ChanceItem;
|
||||
import core.game.node.item.Item;
|
||||
import core.game.world.update.flag.context.Graphics;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A butterfly net type catch.
|
||||
* @author Vexia
|
||||
*/
|
||||
public enum BNetTypes {
|
||||
// Butterflies
|
||||
RUBY_HARVEST(new BNetNode(new int[] { 5085 }, new int[] { 15, 80, 75 }, new double[] { 24, 300, 50 }, new Graphics[] { new Graphics(913), new Graphics(917) }, new ChanceItem(10020))),
|
||||
SAPPHIRE_GLACIALIS(new BNetNode(new int[] { 5084, 7499 }, new int[] { 25, 85, 80 }, new double[] { 34, 400, 70 }, new Graphics[] { new Graphics(912), new Graphics(916) }, new ChanceItem(10018))),
|
||||
SNOWRY_KNIGHT(new BNetNode(new int[] { 5083, 7498 }, new int[] { 35, 90, 85 }, new double[] { 44, 500, 100 }, new Graphics[] { new Graphics(911), new Graphics(915) }, new ChanceItem(10016))),
|
||||
BLACK_WARLOCK(new BNetNode(new int[] { 5082 }, new int[] { 45, 95, 90 }, new double[] { 54, 650, 125 }, new Graphics[] { new Graphics(910), new Graphics(914) }, new ChanceItem(10014))),
|
||||
// Implings ( Clearly these morons typed way too fast - wasn't sure if these names were anywhere else in the code)
|
||||
BABY_IMPLING(new ImplingNode(new int[] { 1028, 6055 }, 17, 20, 18, new Item(11238), new ChanceItem(1755, 1, 1, DropFrequency.COMMON), new ChanceItem(1734, 1, 1, DropFrequency.COMMON), new ChanceItem(1733, 1, 1, DropFrequency.COMMON), new ChanceItem(946, 1, 1, DropFrequency.COMMON), new ChanceItem(1985, 1, 1, DropFrequency.COMMON), new ChanceItem(2347, 1, 1, DropFrequency.COMMON), new ChanceItem(1759, 1, 1, DropFrequency.COMMON), new ChanceItem(1927, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(319, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(2007, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(2007, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(1779, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(7170, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(401, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(1438, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(2355, 1, 1, DropFrequency.RARE), new ChanceItem(1607, 1, 1, DropFrequency.RARE), new ChanceItem(1743, 1, 1, DropFrequency.RARE), new ChanceItem(379, 1, 1, DropFrequency.RARE), new ChanceItem(1761, 1, 1, DropFrequency.RARE))),
|
||||
YOUNG_IMPLING(new ImplingNode(new int[] { 1029, 6056 }, 22, 22, 25, new Item(11240), new ChanceItem(1539, 5, 5, DropFrequency.COMMON), new ChanceItem(1901, 1, 1, DropFrequency.COMMON), new ChanceItem(7936, 1, 1, DropFrequency.COMMON), new ChanceItem(361, 1, 1, DropFrequency.COMMON), new ChanceItem(1523, 1, 1, DropFrequency.COMMON), new ChanceItem(453, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(1777, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(2293, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(1353, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(2359, 1, 1, DropFrequency.RARE))),
|
||||
GOURMET_IMPLING(new ImplingNode(new int[] { 1030, 6057 }, 28, 24, 22, new Item(11242), new ChanceItem(365, 1, 1, DropFrequency.COMMON), new ChanceItem(361, 1, 1, DropFrequency.COMMON), new ChanceItem(2011, 1, 1, DropFrequency.COMMON), new ChanceItem(1897, 1, 1, DropFrequency.COMMON), new ChanceItem(2327, 1, 1, DropFrequency.COMMON), new ChanceItem(5004, 1, 1, DropFrequency.COMMON), new ChanceItem(2007, 1, 1, DropFrequency.COMMON), new ChanceItem(5970, 1, 1, DropFrequency.COMMON), new ChanceItem(365, 4, 4, DropFrequency.UNCOMMON), new ChanceItem(3145, 2, 2, DropFrequency.RARE), new ChanceItem(7178, 1, 5, DropFrequency.UNCOMMON), new ChanceItem(5755, 1, 1, DropFrequency.RARE), new ChanceItem(386, 3, 3, DropFrequency.UNCOMMON), new ChanceItem(5406, 1, 1, DropFrequency.RARE), new ChanceItem(10136, 1, 1, DropFrequency.RARE), new ChanceItem(1883, 1, 1, DropFrequency.UNCOMMON))),
|
||||
EARTH_IMPLING(new ImplingNode(new int[] { 1031, 6058 }, 36, 27, 25, new Item(11244), new ChanceItem(6033, 6, 6, DropFrequency.COMMON), new ChanceItem(1440, 1, 1, DropFrequency.COMMON), new ChanceItem(5535, 1, 1, DropFrequency.COMMON), new ChanceItem(557, 32, 32, DropFrequency.COMMON), new ChanceItem(1442, 1, 1, DropFrequency.COMMON), new ChanceItem(1784, 4, 4, DropFrequency.UNCOMMON), new ChanceItem(447, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(447, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(1606, 2, 2, DropFrequency.RARE))),
|
||||
ESSENCE_IMPLING(new ImplingNode(new int[] { 1032, 6059 }, 42, 29, 27, new Item(11246), new ChanceItem(7937, 20, 20, DropFrequency.COMMON), new ChanceItem(555, 30, 30, DropFrequency.COMMON), new ChanceItem(556, 30, 30, DropFrequency.COMMON), new ChanceItem(558, 25, 25, DropFrequency.COMMON), new ChanceItem(559, 28, 28, DropFrequency.COMMON), new ChanceItem(562, 4, 4, DropFrequency.COMMON), new ChanceItem(1448, 1, 1, DropFrequency.COMMON), new ChanceItem(564, 4, 4, DropFrequency.UNCOMMON), new ChanceItem(565, 7, 7, DropFrequency.RARE), new ChanceItem(563, 13, 13, DropFrequency.RARE), new ChanceItem(566, 11, 11, DropFrequency.RARE))),
|
||||
ECLECTIC_IMPLING(new ImplingNode(new int[] { 1033, 6060 }, 50, 32, 30, new Item(11248), new ChanceItem(1273, 1, 1, DropFrequency.COMMON), new ChanceItem(1199, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(2493, 1, 1, DropFrequency.RARE), new ChanceItem(10083, 1, 1, DropFrequency.RARE), new ChanceItem(1213, 1, 1, DropFrequency.RARE), new ChanceItem(1391, 1, 1, DropFrequency.VERY_RARE), new ChanceItem(5970, 1, 1, DropFrequency.COMMON), new ChanceItem(231, 1, 1, DropFrequency.COMMON), new ChanceItem(556, 30, 57, DropFrequency.COMMON), new ChanceItem(8779, 4, 4, DropFrequency.COMMON), new ChanceItem(4527, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(444, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(2358, 5, 5, DropFrequency.UNCOMMON), new ChanceItem(7937, 20, 35, DropFrequency.UNCOMMON), new ChanceItem(237, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(450, 10, 10, DropFrequency.RARE), new ChanceItem(5760, 2, 2, DropFrequency.RARE), new ChanceItem(7208, 1, 1, DropFrequency.RARE), new ChanceItem(5321, 3, 3, DropFrequency.RARE), new ChanceItem(1601, 1, 1, DropFrequency.VERY_RARE))),
|
||||
NATURE_IMPLING(new ImplingNode(new int[] { 1034, 6061 }, 58, 36, 34, new Item(11250), new ChanceItem(5303, 1, 1, DropFrequency.VERY_RARE), new ChanceItem(270, 2, 2, DropFrequency.VERY_RARE), new ChanceItem(5295, 1, 1, DropFrequency.RARE), new ChanceItem(5304, 1, 1, DropFrequency.RARE), new ChanceItem(5298, 5, 5, DropFrequency.UNCOMMON), new ChanceItem(5299, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(5297, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(5974, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(3000, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(5285, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(5286, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(5100, 1, 1, DropFrequency.COMMON), new ChanceItem(5104, 1, 1, DropFrequency.COMMON), new ChanceItem(5281, 1, 1, DropFrequency.COMMON), new ChanceItem(5294, 1, 1, DropFrequency.COMMON), new ChanceItem(6016, 1, 1, DropFrequency.COMMON), new ChanceItem(1513, 1, 1, DropFrequency.COMMON), new ChanceItem(254, 4, 4, DropFrequency.COMMON), new ChanceItem(5313, 1, 1, DropFrequency.UNCOMMON))),
|
||||
MAGPIE_IMPLING(new ImplingNode(new int[] { 1035, 6062 }, 65, 46, 44, new Item(11252), 500, new ChanceItem(1682, 3, 3, DropFrequency.COMMON), new ChanceItem(1732, 3, 3, DropFrequency.COMMON), new ChanceItem(2569, 3, 3, DropFrequency.COMMON), new ChanceItem(3391, 1, 1, DropFrequency.COMMON), new ChanceItem(1347, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(2571, 4, 4, DropFrequency.UNCOMMON), new ChanceItem(4097, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(4095, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(1215, 1, 1, DropFrequency.RARE), new ChanceItem(1185, 1, 1, DropFrequency.RARE), new ChanceItem(5541, 1, 1, DropFrequency.COMMON), new ChanceItem(1748, 6, 6, DropFrequency.COMMON), new ChanceItem(2364, 2, 2, DropFrequency.UNCOMMON), new ChanceItem(1602, 4, 4, DropFrequency.RARE), new ChanceItem(5287, 1, 1, DropFrequency.RARE), new ChanceItem(985, 1, 1, DropFrequency.RARE), new ChanceItem(987, 1, 1, DropFrequency.RARE), new ChanceItem(993, 1, 1, DropFrequency.VERY_RARE), new ChanceItem(5300, 1, 1, DropFrequency.VERY_RARE))),
|
||||
NINJA_IMPLING(new ImplingNode(new int[] { 6053, 6063 }, 74, 52, 50, new Item(11254), 2000, new ChanceItem(4097, 1, 1, DropFrequency.COMMON), new ChanceItem(1113, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(3385, 1, 1, DropFrequency.COMMON), new ChanceItem(1215, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(811, 70, 70, DropFrequency.UNCOMMON), new ChanceItem(1333, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(1347, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(9342, 2, 2, DropFrequency.UNCOMMON), new ChanceItem(9194, 4, 4, DropFrequency.RARE), new ChanceItem(140, 4, 4, DropFrequency.COMMON), new ChanceItem(6155, 3, 3, DropFrequency.UNCOMMON), new ChanceItem(1748, 10, 16, DropFrequency.COMMON))),
|
||||
// Pirate should be here
|
||||
DRAGON_IMPLING(new ImplingNode(new int[] { 6054, 6064 }, 83, 300, 65, new Item(11256), 3000, new ChanceItem(1705, 2, 3, DropFrequency.RARE), new ChanceItem(4093, 1, 1, DropFrequency.VERY_RARE), new ChanceItem(1684, 2, 3, DropFrequency.VERY_RARE), new ChanceItem(11212, 100, 500, DropFrequency.COMMON), new ChanceItem(9341, 3, 40, DropFrequency.COMMON), new ChanceItem(1305, 1, 1, DropFrequency.COMMON), new ChanceItem(5699, 3, 3, DropFrequency.UNCOMMON), new ChanceItem(11230, 105, 350, DropFrequency.UNCOMMON), new ChanceItem(11232, 105, 350, DropFrequency.COMMON), new ChanceItem(11237, 100, 500, DropFrequency.COMMON), new ChanceItem(9193, 10, 49, DropFrequency.COMMON), new ChanceItem(535, 111, 297, DropFrequency.COMMON), new ChanceItem(5316, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(537, 52, 99, DropFrequency.UNCOMMON), new ChanceItem(1616, 3, 6, DropFrequency.UNCOMMON), new ChanceItem(5300, 6, 6, DropFrequency.RARE), new ChanceItem(7219, 5, 15, DropFrequency.RARE)));
|
||||
|
||||
|
||||
/**
|
||||
* The implings.
|
||||
*/
|
||||
private static final List<ImplingNode> IMPLINGS = new ArrayList<>(20);
|
||||
|
||||
/**
|
||||
* The node.
|
||||
*/
|
||||
private final BNetNode node;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code BNetTypes} {@code Object}.
|
||||
* @param node the node.
|
||||
*/
|
||||
private BNetTypes(BNetNode node) {
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Catches a net npc.
|
||||
* @param player the player.
|
||||
* @param npc the npc.
|
||||
*/
|
||||
public void handle(Player player, NPC npc) {
|
||||
player.getPulseManager().run(new BNetPulse(player, npc, node));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an impling.
|
||||
* @param player the player.
|
||||
* @return the imp.
|
||||
*/
|
||||
public static ImplingNode getImpling(Player player) {
|
||||
for (ImplingNode imp : IMPLINGS) {
|
||||
if (player.getInventory().containsItem(imp.getReward())) {
|
||||
return imp;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a net type for the npc.
|
||||
* @param npc the npc.
|
||||
* @return {@code BNetTypes} type.
|
||||
*/
|
||||
public static BNetTypes forNpc(NPC npc) {
|
||||
for (BNetTypes type : BNetTypes.values()) {
|
||||
for (int id : type.getNode().getNpcs()) {
|
||||
if (id == npc.getId()) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the BNetNode by the item.
|
||||
* @param item the item.
|
||||
* @return the instance.
|
||||
*/
|
||||
public static BNetNode forItem(Item item) {
|
||||
for (BNetTypes type : values()) {
|
||||
if (type.getNode().getReward().getId() == item.getId()) {
|
||||
return type.getNode();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the node.
|
||||
* @return The node.
|
||||
*/
|
||||
public BNetNode getNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the implings.
|
||||
* @return The implings.
|
||||
*/
|
||||
public static List<ImplingNode> getImplings() {
|
||||
return IMPLINGS;
|
||||
}
|
||||
|
||||
/**
|
||||
* static-modifier.
|
||||
*/
|
||||
static {
|
||||
for (BNetTypes type : values()) {
|
||||
BNetNode node = type.getNode();
|
||||
if (node instanceof ImplingNode) {
|
||||
IMPLINGS.add((ImplingNode) node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
package content.global.skill.hunter.bnet;
|
||||
|
||||
import core.game.node.entity.skill.Skills;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.item.ChanceItem;
|
||||
import core.game.node.item.Item;
|
||||
import core.tools.RandomFunction;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Handles the impling node.
|
||||
* @author Vexia
|
||||
*/
|
||||
public final class ImplingNode extends BNetNode {
|
||||
|
||||
/**
|
||||
* The loot from an imp.
|
||||
*/
|
||||
private final ChanceItem[] loot;
|
||||
|
||||
/**
|
||||
* The respawn time.
|
||||
*/
|
||||
private final int respawnTime;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ImplingNode} {@code Object}.
|
||||
* @param npcs the npcs.
|
||||
* @param level the level.
|
||||
* @param exp the exp.
|
||||
* @param puroExp the puro exp.
|
||||
* @param reward the reward.
|
||||
* @param loot the loot.
|
||||
*/
|
||||
public ImplingNode(int[] npcs, int level, double exp, double puroExp, Item reward, final int respawnTime, final ChanceItem... loot) {
|
||||
super(npcs, new int[] { level }, new double[] { exp, puroExp }, null, reward);
|
||||
this.loot = loot;
|
||||
this.respawnTime = respawnTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ImplingNode} {@code Object}.
|
||||
* @param npcs the npcs.
|
||||
* @param level the level.
|
||||
* @param exp the exp.
|
||||
* @param puroExp the puro exp.
|
||||
* @param reward the reward.
|
||||
* @param loot the loot.
|
||||
*/
|
||||
public ImplingNode(int[] npcs, int level, double exp, double puroExp, Item reward, final ChanceItem... loot) {
|
||||
this(npcs, level, exp, puroExp, reward, 16, loot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loots an imp jar.
|
||||
* @param player the player.
|
||||
* @param item the item.
|
||||
*/
|
||||
public void loot(final Player player, final Item item) {
|
||||
player.lock(1);
|
||||
if (player.getInventory().freeSlots() < 1) {
|
||||
player.getPacketDispatch().sendMessage("You don't have enough inventory space.");
|
||||
return;
|
||||
}
|
||||
final Item reward = RandomFunction.getChanceItem(getLoot()).getRandomItem();
|
||||
if (player.getInventory().remove(item)) {
|
||||
if (isBroken(player)) {
|
||||
player.sendMessage("You break the jar as you try and open it. You throw the shattered remains away.");
|
||||
} else {
|
||||
player.getInventory().add(IMPLING_JAR);
|
||||
}
|
||||
player.getInventory().add(reward, player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the item will break.
|
||||
* @param player the player.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
private boolean isBroken(Player player) {
|
||||
int strengthLevel = player.getSkills().getLevel(Skills.STRENGTH);
|
||||
strengthLevel /= 0.5;
|
||||
int level = getLevel();
|
||||
int currentLevel = RandomFunction.random(strengthLevel) + 1;
|
||||
double ratio = (double) currentLevel / (new Random().nextInt(level + 5) + 1);
|
||||
return Math.round(ratio * strengthLevel) < level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void message(Player player, int type, boolean success) {
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
if(type == 1){
|
||||
player.sendMessage("You manage to catch the impling and squeeze it into a jar.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getExperience(Player player) {
|
||||
return player.getZoneMonitor().isInZone("puro puro") ? getExperiences()[1] : super.getExperience(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBareHand(Player player) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item getJar() {
|
||||
return IMPLING_JAR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the loot.
|
||||
* @return The loot.
|
||||
*/
|
||||
public ChanceItem[] getLoot() {
|
||||
return loot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the respawnTime.
|
||||
* @return The respawnTime.
|
||||
*/
|
||||
public int getRespawnTime() {
|
||||
return respawnTime;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package content.global.skill.hunter.falconry;
|
||||
|
||||
import core.game.node.entity.npc.NPC;
|
||||
import core.game.node.item.Item;
|
||||
|
||||
/**
|
||||
* Represents a falcon catch.
|
||||
* @author Vexia
|
||||
*/
|
||||
public enum FalconCatch {
|
||||
SPOTTED_KEBBIT(5098, 43, 104, new Item(10125)), DARK_KEBBIT(5099, 57, 132, new Item(10115)), DASHING_KEBBIT(5100, 69, 156, new Item(10127));
|
||||
|
||||
/**
|
||||
* Represents the npc.
|
||||
*/
|
||||
private final int npc;
|
||||
|
||||
/**
|
||||
* Represents the level.
|
||||
*/
|
||||
private final int level;
|
||||
|
||||
/**
|
||||
* Represents the experience gained.
|
||||
*/
|
||||
private final double experience;
|
||||
|
||||
/**
|
||||
* Represents the item reward.
|
||||
*/
|
||||
private final Item item;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code FalconCatch} {@code Object}.
|
||||
* @param npc the npc.
|
||||
* @param level the level.
|
||||
* @param experience the experience.
|
||||
* @param item the item.
|
||||
*/
|
||||
FalconCatch(int npc, int level, double experience, Item item) {
|
||||
this.npc = npc;
|
||||
this.level = level;
|
||||
this.experience = experience;
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the falcon catch.
|
||||
* @param item the item.
|
||||
* @return the falcon catch.
|
||||
*/
|
||||
public static FalconCatch forItem(final Item item) {
|
||||
for (FalconCatch falconCatch : FalconCatch.values()) {
|
||||
if (item.getId() == falconCatch.getItem().getId()) {
|
||||
return falconCatch;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the falcon catch.
|
||||
* @param npc the npc.
|
||||
* @return the falcon catch.
|
||||
*/
|
||||
public static FalconCatch forNPC(final NPC npc) {
|
||||
for (FalconCatch falconCatch : FalconCatch.values()) {
|
||||
if (npc.getId() == falconCatch.getNpc()) {
|
||||
return falconCatch;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the npc.
|
||||
* @return The npc.
|
||||
*/
|
||||
public int getNpc() {
|
||||
return npc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the level.
|
||||
* @return The level.
|
||||
*/
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the experience.
|
||||
* @return The experience.
|
||||
*/
|
||||
public double getExperience() {
|
||||
return experience;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the item.
|
||||
* @return The item.
|
||||
*/
|
||||
public Item getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
package content.global.skill.hunter.falconry;
|
||||
|
||||
import core.game.container.impl.EquipmentContainer;
|
||||
import core.game.node.entity.skill.SkillPulse;
|
||||
import core.game.node.entity.skill.Skills;
|
||||
import core.game.node.entity.impl.Projectile;
|
||||
import core.game.node.entity.npc.NPC;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.entity.player.link.HintIconManager;
|
||||
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.repository.Repository;
|
||||
import core.tools.RandomFunction;
|
||||
|
||||
/**
|
||||
* Represents the skill pulse used to catch a kebbit.
|
||||
* @author Vexia
|
||||
*/
|
||||
public final class FalconryCatchPulse extends SkillPulse<NPC> {
|
||||
|
||||
/**
|
||||
* Represents the falcon catch.
|
||||
*/
|
||||
private final FalconCatch falconCatch;
|
||||
|
||||
/**
|
||||
* Represents the falcon item.
|
||||
*/
|
||||
private static final Item FALCON = new Item(10024);
|
||||
|
||||
/**
|
||||
* Represents the falcon glove.
|
||||
*/
|
||||
private static final Item GLOVE = new Item(10023);
|
||||
|
||||
/**
|
||||
* Represents the original location.
|
||||
*/
|
||||
private final Location originalLocation;
|
||||
|
||||
/**
|
||||
* If the falcon has been checked.
|
||||
*/
|
||||
private boolean checked;
|
||||
|
||||
/**
|
||||
* The ticks passed.
|
||||
*/
|
||||
private int ticks;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code FalconryCatchPulse.java} {@code Object}.
|
||||
* @param player
|
||||
* @param node
|
||||
*/
|
||||
public FalconryCatchPulse(final Player player, final NPC node, final FalconCatch falconCatch) {
|
||||
super(player, node);
|
||||
this.falconCatch = falconCatch;
|
||||
this.originalLocation = node.getLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
player.faceTemporary(node, 1);
|
||||
node.getWalkingQueue().reset();
|
||||
player.getWalkingQueue().reset();
|
||||
super.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkRequirements() {
|
||||
if (!checked) {
|
||||
checked = true;
|
||||
if (node.getLocation().getDistance(player.getLocation()) > 15) {
|
||||
player.getPacketDispatch().sendMessage("You can't catch a kebbit that far away.");
|
||||
return false;
|
||||
}
|
||||
if (player.getSkills().getLevel(Skills.HUNTER) < falconCatch.getLevel()) {
|
||||
player.getPacketDispatch().sendMessage("You need a Hunter level of at least " + falconCatch.getLevel() + " to catch this kebbit.");
|
||||
return false;
|
||||
}
|
||||
if (player.getEquipment().get(EquipmentContainer.SLOT_HANDS) != null || player.getEquipment().get(EquipmentContainer.SLOT_SHIELD) != null) {
|
||||
player.getDialogueInterpreter().sendDialogue("Sorry, free your hands, weapon, and shield slot first.");
|
||||
return false;
|
||||
}
|
||||
if (player.getEquipment().get(EquipmentContainer.SLOT_WEAPON) == null || !player.getEquipment().containsItem(FALCON)) {
|
||||
player.getPacketDispatch().sendMessage("You need a falcon to catch a kebbit.");
|
||||
return false;
|
||||
}
|
||||
if (player.getEquipment().remove(FALCON)) {
|
||||
player.getEquipment().add(GLOVE, true, false);
|
||||
sendProjectile();
|
||||
}
|
||||
node.lock(getDistance()+1);
|
||||
player.lock(getDistance()+1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
super.stop();
|
||||
player.unlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void animate() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean reward() {
|
||||
if (++ticks % getDistance() != 0) {
|
||||
return false;
|
||||
}
|
||||
final boolean success = success();
|
||||
player.getPacketDispatch().sendMessage(success ? "The falcon successfully swoops down and captures the kebbit." : "The falcon swoops down on the kebbit, but just misses catching it.");
|
||||
if (success) {
|
||||
node.finalizeDeath(player);
|
||||
final NPC falcon = NPC.create(5094, node.getLocation());
|
||||
falcon.setAttribute("falcon:owner", player.getUsername());
|
||||
falcon.setAttribute("falcon:catch", falconCatch);
|
||||
falcon.init();
|
||||
HintIconManager.registerHintIcon(player, falcon);
|
||||
GameWorld.getPulser().submit(new Pulse(100, falcon) {
|
||||
@Override
|
||||
public boolean pulse() {
|
||||
if (!falcon.isActive()) {
|
||||
return true;
|
||||
}
|
||||
Projectile projectile = Projectile.create(node, Repository.findNPC(5093), 918);
|
||||
projectile.setSpeed(80);
|
||||
projectile.send();
|
||||
player.getPacketDispatch().sendMessage("Your falcon has left its prey. You see it heading back toward the falconer.");
|
||||
falcon.clear();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (player.getEquipment().remove(GLOVE)) {
|
||||
player.getEquipment().add(FALCON, true, false);
|
||||
}
|
||||
}
|
||||
player.face(null);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the projectile.
|
||||
*/
|
||||
private void sendProjectile() {
|
||||
Projectile projectile = Projectile.create(player, node, 918);
|
||||
projectile.setSpeed(80);
|
||||
projectile.setStartHeight(26);
|
||||
projectile.setEndHeight(1);
|
||||
projectile.send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the distance of the npc.
|
||||
* @return the distance.
|
||||
*/
|
||||
public int getDistance() {
|
||||
return (int) (2 + (player.getLocation().getDistance(node.getLocation())) * 0.5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the catch was successful.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean success() {
|
||||
if (originalLocation != node.getLocation()) {
|
||||
return RandomFunction.random(1, 3) == 2;
|
||||
}
|
||||
return ((RandomFunction.getRandom(3) * player.getSkills().getLevel(Skills.HUNTER)) / 3) > (falconCatch.getLevel() / 2);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,325 @@
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import core.api.*
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.combat.CombatStyle
|
||||
import core.game.node.entity.impl.Animator.Priority;
|
||||
import core.game.node.entity.impl.ForceMovement
|
||||
import core.game.node.entity.npc.AbstractNPC
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.skill.Skills
|
||||
import content.global.skill.hunter.HunterManager
|
||||
import core.game.node.item.Item
|
||||
import core.game.node.scenery.Scenery
|
||||
import core.game.system.task.Pulse
|
||||
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 core.tools.RandomFunction
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.interaction.IntType
|
||||
import core.game.world.GameWorld
|
||||
|
||||
/*@Initializable
|
||||
class HunterPitfall : OptionHandler() {
|
||||
//19227,
|
||||
val graahkPitIds = intArrayOf(19227)//, 19268,19267,19266,19264,19265)
|
||||
val GRAAHK_ID = 5105
|
||||
val hunterReq = 41
|
||||
override fun handle(player: Player?, node: Node?, option: String?): Boolean {
|
||||
node ?: return true
|
||||
player ?: return true
|
||||
player.sendMessage("Hello from HunterPitfall: ${option}")
|
||||
when(option) {
|
||||
"tease" -> {
|
||||
(node as Entity).attack(player)
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun newInstance(arg: Any?): Plugin<Any> {
|
||||
for(graahkPit in graahkPitIds) {
|
||||
SceneryDefinition.forId(graahkPit).handlers["option:trap"] = this
|
||||
}
|
||||
//NPCDefinition.forId(GRAAHK_ID).handlers["option:tease"] = this
|
||||
return this
|
||||
}
|
||||
}*/
|
||||
|
||||
val LARUPIA_IDS: IntArray = intArrayOf(NPCs.SPINED_LARUPIA_5104)
|
||||
val GRAAHK_IDS: IntArray = intArrayOf(NPCs.HORNED_GRAAHK_5105, NPCs.HORNED_GRAAHK_5106, NPCs.HORNED_GRAAHK_5107, NPCs.HORNED_GRAAHK_5108)
|
||||
val KYATT_IDS: IntArray = intArrayOf(NPCs.SABRE_TOOTHED_KYATT_5103, NPCs.SABRE_TOOTHED_KYATT_7497)
|
||||
val BEAST_IDS: IntArray = intArrayOf(*LARUPIA_IDS, *GRAAHK_IDS, *KYATT_IDS)
|
||||
val HUNTER_REQS = hashMapOf(
|
||||
"Spined larupia" to 31,
|
||||
"Horned graahk" to 41,
|
||||
"Sabre-toothed kyatt" to 55,
|
||||
)
|
||||
//val pitVarpOffsets = hashMapOf( 19264 to 3, 19265 to 6, 19266 to 9, 19267 to 12, 19268 to 15,)
|
||||
data class Pit(val varpId: Int, val varpOffset: Int, val horizontal: Boolean)
|
||||
val pitVarps = hashMapOf(
|
||||
// Larupia pits (the duplicate 24 is likely authentic)
|
||||
Location.create(2565,2888) to Pit(917, 27, true),
|
||||
Location.create(2573,2885) to Pit(918, 0, false),
|
||||
Location.create(2556,2893) to Pit(917, 18, false),
|
||||
Location.create(2552,2904) to Pit(917, 24, true),
|
||||
Location.create(2543,2908) to Pit(917, 21, false),
|
||||
Location.create(2538,2899) to Pit(917, 24, true),
|
||||
// Kyatt pits
|
||||
Location.create(2700,3795) to Pit(917, 0, true),
|
||||
Location.create(2700,3785) to Pit(917, 3, false),
|
||||
Location.create(2706,3789) to Pit(917, 6, false),
|
||||
Location.create(2730,3791) to Pit(917, 9, true),
|
||||
Location.create(2737,3784) to Pit(917, 12, true),
|
||||
Location.create(2730,3780) to Pit(917, 15, false),
|
||||
// Graahk pits
|
||||
Location.create(2766,3010) to Pit(918, 3, false),
|
||||
Location.create(2762,3005) to Pit(918, 6, false),
|
||||
Location.create(2771,3004) to Pit(918, 9, true),
|
||||
Location.create(2777,3001) to Pit(918, 12, false),
|
||||
Location.create(2784,3001) to Pit(918, 15, true),
|
||||
)
|
||||
/*val pitJumpSpots = hashMapOf(
|
||||
Location.create(2766,3010) to hashMapOf(
|
||||
Location.create(2766,3009) to Direction.NORTH,
|
||||
Location.create(2767,3009) to Direction.NORTH,
|
||||
Location.create(2766,3012) to Direction.SOUTH,
|
||||
Location.create(2767,3012) to Direction.SOUTH,
|
||||
),
|
||||
Location.create(2762,3005) to hashMapOf(
|
||||
Location.create(2762,3004) to Direction.NORTH,
|
||||
Location.create(2763,3004) to Direction.NORTH,
|
||||
Location.create(2762,3007) to Direction.SOUTH,
|
||||
Location.create(2763,3007) to Direction.SOUTH,
|
||||
),
|
||||
Location.create(2771,3004) to hashMapOf(
|
||||
Location.create(2770,3004) to Direction.EAST,
|
||||
Location.create(2770,3005) to Direction.EAST,
|
||||
Location.create(2773,3004) to Direction.WEST,
|
||||
Location.create(2773,3005) to Direction.WEST,
|
||||
),
|
||||
Location.create(2777,3001) to hashMapOf(
|
||||
Location.create(2777,3000) to Direction.NORTH,
|
||||
Location.create(2778,3000) to Direction.NORTH,
|
||||
Location.create(2777,3003) to Direction.SOUTH,
|
||||
Location.create(2778,3003) to Direction.SOUTH,
|
||||
),
|
||||
Location.create(2784,3001) to hashMapOf(
|
||||
Location.create(2783,3002) to Direction.EAST,
|
||||
Location.create(2783,3001) to Direction.EAST,
|
||||
Location.create(2786,3002) to Direction.WEST,
|
||||
Location.create(2786,3001) to Direction.WEST,
|
||||
),
|
||||
)*/
|
||||
fun pitJumpSpots(loc: Location): HashMap<Location, Direction>? {
|
||||
val pit = pitVarps[loc] ?: return null
|
||||
if(pit.horizontal) {
|
||||
return hashMapOf(
|
||||
loc.transform(-1, 0, 0) to Direction.EAST,
|
||||
loc.transform(-1, 1, 0) to Direction.EAST,
|
||||
loc.transform(2, 0, 0) to Direction.WEST,
|
||||
loc.transform(2, 1, 0) to Direction.WEST,
|
||||
)
|
||||
} else {
|
||||
return hashMapOf(
|
||||
loc.transform(0, -1, 0) to Direction.NORTH,
|
||||
loc.transform(1, -1, 0) to Direction.NORTH,
|
||||
loc.transform(0, 2, 0) to Direction.SOUTH,
|
||||
loc.transform(1, 2, 0) to Direction.SOUTH,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val KNIFE = Item(Items.KNIFE_946)
|
||||
val TEASING_STICK = Item(Items.TEASING_STICK_10029)
|
||||
val LOGS = Item(Items.LOGS_1511)
|
||||
|
||||
val PIT = 19227
|
||||
val SPIKED_PIT = 19228
|
||||
val GRAAHK_PIT = 19231
|
||||
val LARUPIA_PIT = 19232
|
||||
val KYATT_PIT = 19233
|
||||
|
||||
class PitfallListeners : InteractionListener {
|
||||
|
||||
override fun defineListeners() {
|
||||
setDest(IntType.SCENERY, intArrayOf(PIT, SPIKED_PIT, LARUPIA_PIT, GRAAHK_PIT, KYATT_PIT), "trap", "jump", "dismantle") { player, node ->
|
||||
val pit = node as Scenery
|
||||
val src = player.getLocation()
|
||||
var dst = pit.getLocation()
|
||||
val locs = pitJumpSpots(dst)
|
||||
if(locs != null) {
|
||||
for(loc in locs.keys) {
|
||||
if(src.getDistance(loc) <= src.getDistance(dst)) {
|
||||
dst = loc
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(player is Player) {
|
||||
player.sendMessage("Error: Unimplemented pit at ${pit.location}")
|
||||
}
|
||||
}
|
||||
return@setDest dst
|
||||
}
|
||||
on(PIT, IntType.SCENERY, "trap") { player, node ->
|
||||
val pit = node as Scenery;
|
||||
// TODO: check hunter level, remove logs
|
||||
if(player.skills.getLevel(Skills.HUNTER) < 31) {
|
||||
player.sendMessage("You need a hunter level of 31 to set a pitfall trap.")
|
||||
return@on true
|
||||
}
|
||||
|
||||
val maxTraps = HunterManager.getInstance(player).maximumTraps
|
||||
if(player.getAttribute("pitfall:count", 0) >= maxTraps) {
|
||||
player.sendMessage("You can't set up more than $maxTraps pitfall traps at your hunter level.")
|
||||
return@on true
|
||||
}
|
||||
player.incrementAttribute("pitfall:count", 1)
|
||||
|
||||
if(!player.inventory.containsItem(KNIFE) || !player.inventory.remove(LOGS)) {
|
||||
player.sendMessage("You need some logs and a knife to set a pitfall trap.")
|
||||
return@on true
|
||||
}
|
||||
|
||||
player.setAttribute("pitfall:timestamp:${pit.location.x}:${pit.location.y}", System.currentTimeMillis())
|
||||
setPitState(player, pit.location, 1)
|
||||
val collapsePulse = object : Pulse(201, player) {
|
||||
override fun pulse(): Boolean {
|
||||
val oldTime = player.getAttribute("pitfall:timestamp:${pit.location.x}:${pit.location.y}", System.currentTimeMillis())
|
||||
if(System.currentTimeMillis() - oldTime >= TimeUnit.MINUTES.toMillis(2)) {
|
||||
player.sendMessage("Your pitfall trap has collapsed.")
|
||||
setPitState(player, pit.location, 0)
|
||||
player.incrementAttribute("pitfall:count", -1)
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
GameWorld.Pulser.submit(collapsePulse)
|
||||
return@on true
|
||||
}
|
||||
on(SPIKED_PIT, IntType.SCENERY, "jump") { player, node ->
|
||||
val pit = node as Scenery;
|
||||
val src = player.getLocation()
|
||||
val dir = pitJumpSpots(pit.getLocation())!![src]
|
||||
if(dir != null) {
|
||||
val dst = src.transform(dir, 3)
|
||||
ForceMovement.run(player, src, dst, ForceMovement.WALK_ANIMATION, Animation(1603), dir, 16);
|
||||
val pitfall_npc: Entity? = player.getAttribute("pitfall_npc", null)
|
||||
if(pitfall_npc != null && pitfall_npc.getLocation().getDistance(src) < 3.0) {
|
||||
val last_pit_loc: Location? = pitfall_npc.getAttribute("last_pit_loc", null)
|
||||
if(last_pit_loc == pit.location) {
|
||||
player.sendMessage("The ${pitfall_npc.name.toLowerCase()} won't jump the same pit twice in a row.")
|
||||
return@on true
|
||||
}
|
||||
// TODO: what are the actual probabilities of a graahk jumping over a pit?
|
||||
val chance = RandomFunction.getSkillSuccessChance(50.0, 100.0, player.skills.getLevel(Skills.HUNTER))
|
||||
if(RandomFunction.random(0.0, 100.0) < chance) {
|
||||
//ForceMovement.run(pitfall_npc, pitfall_npc.getLocation(), pit.getLocation(), ForceMovement.WALK_ANIMATION, Animation(ANIM), dir, 8);
|
||||
//pitfall_npc.setLocation(pit.getLocation());
|
||||
//pitfall_npc.walkingQueue.addPath(pit.location.x, pit.location.y);
|
||||
teleport(pitfall_npc, pit.location)
|
||||
pitfall_npc.startDeath(null)
|
||||
player.removeAttribute("pitfall:timestamp:${pit.location.x}:${pit.location.y}")
|
||||
player.incrementAttribute("pitfall:count", -1)
|
||||
setPitState(player, pit.location, 3)
|
||||
//pitfall_npc.animate(Animation(5234))
|
||||
} else {
|
||||
//ForceMovement.run(pitfall_npc, pitfall_npc.getLocation(), dst, ForceMovement.WALK_ANIMATION, Animation(ANIM), dir, 8);
|
||||
//pitfall_npc.walkingQueue.addPath(npcdst.x, npcdst.y)
|
||||
val npcdst = dst.transform(dir, if(dir == Direction.SOUTH || dir == Direction.WEST) 1 else 0)
|
||||
teleport(pitfall_npc, npcdst)
|
||||
pitfall_npc.animate(Animation(5232, Priority.HIGH))
|
||||
pitfall_npc.attack(player)
|
||||
pitfall_npc.setAttribute("last_pit_loc", pit.location)
|
||||
}
|
||||
}
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
on(SPIKED_PIT, IntType.SCENERY, "dismantle") { player, node ->
|
||||
val pit = node as Scenery;
|
||||
player.removeAttribute("pitfall:timestamp:${pit.location.x}:${pit.location.y}")
|
||||
player.incrementAttribute("pitfall:count", -1)
|
||||
setPitState(player, pit.location, 0)
|
||||
return@on true
|
||||
}
|
||||
on(LARUPIA_PIT, IntType.SCENERY, "dismantle") { player, node ->
|
||||
lootCorpse(player, node as Scenery, 180.0, Items.LARUPIA_FUR_10095, Items.TATTY_LARUPIA_FUR_10093)
|
||||
return@on true
|
||||
}
|
||||
on(GRAAHK_PIT, IntType.SCENERY, "dismantle") { player, node ->
|
||||
lootCorpse(player, node as Scenery, 240.0, Items.GRAAHK_FUR_10099, Items.TATTY_GRAAHK_FUR_10097)
|
||||
return@on true
|
||||
}
|
||||
on(KYATT_PIT, IntType.SCENERY, "dismantle") { player, node ->
|
||||
lootCorpse(player, node as Scenery, 300.0, Items.KYATT_FUR_10103, Items.TATTY_KYATT_FUR_10101)
|
||||
return@on true
|
||||
}
|
||||
on(BEAST_IDS, IntType.NPC, "tease") { player, node ->
|
||||
val entity = node as Entity
|
||||
val hunterReq = HUNTER_REQS[entity.name]!!
|
||||
if(player.skills.getLevel(Skills.HUNTER) < hunterReq) {
|
||||
player.sendMessage("You need a hunter level of ${hunterReq} to hunt ${entity.name.toLowerCase()}s.")
|
||||
return@on true
|
||||
}
|
||||
if(!player.inventory.containsItem(TEASING_STICK)) {
|
||||
player.sendMessage("You need a teasing stick to hunt ${entity.name.toLowerCase()}s.")
|
||||
return@on true
|
||||
}
|
||||
entity.attack(player)
|
||||
player.setAttribute("pitfall_npc", entity)
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
|
||||
fun lootCorpse(player: Player, pit: Scenery, xp: Double, goodFur: Int, badFur: Int) {
|
||||
if(player.inventory.freeSlots() < 2) {
|
||||
player.sendMessage("You don't have enough inventory space. You need 2 more free slots.");
|
||||
return
|
||||
}
|
||||
setPitState(player, pit.location, 0)
|
||||
player.getSkills().addExperience(Skills.HUNTER, xp, true);
|
||||
player.inventory.add(Item(Items.BIG_BONES_532))
|
||||
// TODO: what's the actual probability of tatty vs perfect fur?
|
||||
val chance = RandomFunction.getSkillSuccessChance(50.0, 100.0, player.skills.getLevel(Skills.HUNTER))
|
||||
if(RandomFunction.random(0.0, 100.0) < chance) {
|
||||
player.inventory.add(Item(goodFur))
|
||||
} else {
|
||||
player.inventory.add(Item(badFur))
|
||||
}
|
||||
}
|
||||
|
||||
fun setPitState(player: Player, loc: Location, state: Int) {
|
||||
val pit = pitVarps[loc]!!
|
||||
player.varpManager.get(pit.varpId).setVarbit(pit.varpOffset, state).send(player)
|
||||
}
|
||||
}
|
||||
|
||||
@Initializable
|
||||
class PitfallNPC : AbstractNPC {
|
||||
constructor() : super(NPCs.HORNED_GRAAHK_5105, null, true) {}
|
||||
private constructor(id: Int, location: Location) : super(id, location) {}
|
||||
override fun construct(id: Int, location: Location, vararg objects: Any?): AbstractNPC {
|
||||
return PitfallNPC(id, location)
|
||||
}
|
||||
|
||||
init {
|
||||
walkRadius = 22
|
||||
}
|
||||
|
||||
override fun getIds(): IntArray {
|
||||
return BEAST_IDS
|
||||
}
|
||||
|
||||
override fun isAttackable(entity: Entity, style: CombatStyle, message: Boolean): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun isIgnoreAttackRestrictions(victim: Entity): Boolean {
|
||||
return victim is Player
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package content.global.skill.hunter.tracking
|
||||
|
||||
import core.cache.def.impl.SceneryDefinition
|
||||
import core.game.node.item.Item
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import core.plugin.Initializable
|
||||
import core.plugin.Plugin
|
||||
import org.rs09.consts.Items
|
||||
|
||||
@Initializable
|
||||
class CommonKebbitEast : HunterTracking() {
|
||||
|
||||
init {
|
||||
initialMap = hashMapOf(
|
||||
19439 to arrayListOf(
|
||||
TrailDefinition(0,TrailType.LINKING, false,Location.create(2354, 3595, 0),Location.create(2360, 3602, 0)),
|
||||
TrailDefinition(3,TrailType.LINKING,false,Location.create(2354, 3595, 0),Location.create(2355, 3601, 0)),
|
||||
TrailDefinition(6,TrailType.LINKING,false,Location.create(2354, 3594, 0),Location.create(2349, 3604, 0))
|
||||
),
|
||||
19440 to arrayListOf(
|
||||
TrailDefinition(18,TrailType.LINKING,true,Location.create(2361, 3611, 0),Location.create(2360, 3602, 0)),
|
||||
TrailDefinition(21,TrailType.LINKING,true,Location.create(2360, 3612, 0),Location.create(2357, 3607, 0))
|
||||
)
|
||||
)
|
||||
|
||||
linkingTrails = arrayListOf(
|
||||
TrailDefinition(24,TrailType.LINKING,false,Location.create(2357, 3607, 0),Location.create(2354, 3609, 0),Location.create(2355, 3608, 0)),
|
||||
TrailDefinition(27,TrailType.LINKING,false,Location.create(2354, 3609, 0),Location.create(2349, 3604, 0),Location.create(2351, 3608, 0)),
|
||||
TrailDefinition(9,TrailType.LINKING,false ,Location.create(2360, 3602, 0),Location.create(2355, 3601, 0),Location.create(2358, 3599, 0)),
|
||||
TrailDefinition(12,TrailType.LINKING,false,Location.create(2355, 3601, 0),Location.create(2349, 3604, 0),Location.create(2352, 3603, 0)),
|
||||
TrailDefinition(15,TrailType.LINKING,false,Location.create(2360, 3602, 0),Location.create(2357, 3607, 0),Location.create(2358, 3603, 0))
|
||||
)
|
||||
experience = 36.0
|
||||
varp = 919
|
||||
trailLimit = 3
|
||||
attribute = "hunter:tracking:commontrail"
|
||||
indexAttribute = "hunter:tracking:commonIndex"
|
||||
rewards = arrayOf(Item(Items.COMMON_KEBBIT_FUR_10121), Item(Items.BONES_526),Item(Items.RAW_BEAST_MEAT_9986))
|
||||
KEBBIT_ANIM = Animation(5259)
|
||||
}
|
||||
|
||||
|
||||
override fun newInstance(arg: Any?): Plugin<Any> {
|
||||
if(!linkingTrails.contains(initialMap.values.random()[0])){
|
||||
addExtraTrails()
|
||||
}
|
||||
SceneryDefinition.forId(19439).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19440).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19360).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19361).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19362).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19363).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19364).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19365).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19356).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19357).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19358).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19359).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19375).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19376).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19377).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19378).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19379).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19372).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19380).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19374).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19373).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19428).handlers["option:search"] = this
|
||||
SceneryDefinition.forId(19428).handlers["option:attack"] = this
|
||||
|
||||
return this
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package content.global.skill.hunter.tracking
|
||||
|
||||
class CommonKebbitWest {
|
||||
}
|
||||
@@ -0,0 +1,265 @@
|
||||
package content.global.skill.hunter.tracking
|
||||
|
||||
import core.game.interaction.OptionHandler
|
||||
import core.game.node.Node
|
||||
import core.game.node.scenery.Scenery
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.node.item.GroundItemManager
|
||||
import core.game.node.item.Item
|
||||
import core.game.system.task.Pulse
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import core.tools.RandomFunction
|
||||
import org.rs09.consts.Items
|
||||
import core.tools.SystemLogger
|
||||
import core.game.world.GameWorld
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Main class for hunter tracking. All the other subclasses just define values that the methods in this class use.
|
||||
* @author Ceikry
|
||||
*/
|
||||
abstract class HunterTracking : OptionHandler(){
|
||||
var KEBBIT_ANIM = Animation(0)
|
||||
val MISS_ANIM = Animation(5255)
|
||||
var trailLimit = 0
|
||||
var attribute = ""
|
||||
var indexAttribute = ""
|
||||
var rewards = Array<Item>(0){Item(0)}
|
||||
var tunnelEntrances = Array<Location>(0){ Location(0,0,0) }
|
||||
var initialMap = HashMap<Int,ArrayList<TrailDefinition>>()
|
||||
var linkingTrails = ArrayList<TrailDefinition>()
|
||||
var experience = 0.0
|
||||
var varp = 0
|
||||
var requiredLevel = 1
|
||||
|
||||
/**
|
||||
* Gets the initial trail based on the ID of the hole object the player clicked on
|
||||
* @author Ceikry
|
||||
*/
|
||||
fun getInitialTrail(obj: Scenery): TrailDefinition? {
|
||||
return initialMap[obj.id]?.random()
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the entire trail all at once.
|
||||
* @author Ceikry
|
||||
*/
|
||||
fun generateTrail(startobj: Scenery, player: Player) {
|
||||
val trail = player.getAttribute(attribute, ArrayList<TrailDefinition>())
|
||||
val initialTrail = getInitialTrail(startobj)
|
||||
if(initialTrail == null) {
|
||||
SystemLogger.logWarn(this::class.java, "UNHANDLED STARTING OBJECT FOR HUNTER TRACKING $startobj")
|
||||
return
|
||||
}
|
||||
trail.add(initialTrail)
|
||||
player.setAttribute(attribute,trail)
|
||||
|
||||
var numSpots = RandomFunction.random(2,trailLimit)
|
||||
var triesRemaining = numSpots * 3
|
||||
|
||||
while(numSpots > 0){
|
||||
if(triesRemaining-- <= 0) {
|
||||
clearTrail(player)
|
||||
return
|
||||
}
|
||||
val nextTrail = getLinkingTrail(player)
|
||||
nextTrail ?: continue
|
||||
var offsetUsed = false
|
||||
for(i in trail){
|
||||
if(i.offset == nextTrail.offset){ offsetUsed = true; break }
|
||||
}
|
||||
if(offsetUsed) continue
|
||||
if(nextTrail.type == TrailType.TUNNEL){
|
||||
trail.add(nextTrail)
|
||||
continue
|
||||
}
|
||||
trail.add(nextTrail)
|
||||
player.setAttribute(attribute,trail)
|
||||
numSpots--
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a linking trail point, used to build entire trails
|
||||
* @author Ceikry
|
||||
*/
|
||||
fun getLinkingTrail(player: Player): TrailDefinition? {
|
||||
val trail = player.getAttribute(attribute,ArrayList<TrailDefinition>())
|
||||
val previousTrail = trail.get(trail.lastIndex)
|
||||
if(previousTrail.type == TrailType.TUNNEL){
|
||||
val possibleTrails = ArrayList<TrailDefinition>()
|
||||
for(trail in linkingTrails){
|
||||
val invTrail = getTrailInverse(trail,false)
|
||||
if(invTrail.type == TrailType.TUNNEL && previousTrail.endLocation.withinDistance(invTrail.startLocation,5) && !previousTrail.endLocation.equals(invTrail.startLocation) && previousTrail.offset != trail.offset){
|
||||
possibleTrails.add(trail)
|
||||
}
|
||||
}
|
||||
return possibleTrails.random()
|
||||
}
|
||||
val possibleTrails = ArrayList<TrailDefinition>()
|
||||
for(trail in linkingTrails){
|
||||
if(trail.startLocation.equals(previousTrail.endLocation) && previousTrail.offset != trail.offset){
|
||||
possibleTrails.add(trail)
|
||||
}
|
||||
}
|
||||
return possibleTrails.random()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inverts a trail so trails only have to be defined manually in one direction
|
||||
* @author Ceikry
|
||||
*/
|
||||
fun getTrailInverse(trail: TrailDefinition, swapLocations: Boolean): TrailDefinition{
|
||||
if(swapLocations)
|
||||
return TrailDefinition(trail.offset,if(tunnelEntrances.contains(trail.startLocation)) TrailType.TUNNEL else TrailType.LINKING,!trail.inverted,trail.endLocation,trail.startLocation, trail.triggerObjectLocation)
|
||||
return TrailDefinition(trail.offset, if(tunnelEntrances.contains(trail.startLocation)) TrailType.TUNNEL else TrailType.LINKING, !trail.inverted, trail.startLocation, trail.endLocation)
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the linked trail list with inverses of the manually defined trails
|
||||
* @author Ceikry
|
||||
*/
|
||||
fun addExtraTrails(){
|
||||
linkingTrails.toTypedArray().forEach { trail ->
|
||||
linkingTrails.add(getTrailInverse(trail,true))
|
||||
}
|
||||
if(this is PolarKebbitHunting){
|
||||
initialMap.values.forEach {
|
||||
linkingTrails.addAll(it)
|
||||
it.forEach { trail ->
|
||||
linkingTrails.add(getTrailInverse(trail, true))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets a player's trail
|
||||
* @author Ceikry
|
||||
*/
|
||||
fun clearTrail(player: Player){
|
||||
player.removeAttribute(attribute)
|
||||
player.removeAttribute(indexAttribute)
|
||||
player.varpManager.get(varp).clear()
|
||||
player.varpManager.get(varp).send(player)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a player has an active trail
|
||||
* @author Ceikry
|
||||
*/
|
||||
fun hasTrail(player: Player): Boolean{
|
||||
return player.getAttribute(attribute,null) != null
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewards the player with items from the rewards array and awards experience.
|
||||
* Pass false to success to just play the kebbit animation without rewarding anything.
|
||||
* @author Ceikry
|
||||
*/
|
||||
fun reward(player: Player, success: Boolean) {
|
||||
player.lock()
|
||||
player.animator.animate(if(success) KEBBIT_ANIM else MISS_ANIM)
|
||||
GameWorld.Pulser.submit(object : Pulse(KEBBIT_ANIM.duration){
|
||||
override fun pulse(): Boolean {
|
||||
if(hasTrail(player) && success){
|
||||
for(item in rewards){
|
||||
if(!player.inventory.add(item))
|
||||
GroundItemManager.create(item,player)
|
||||
}
|
||||
player.skills.addExperience(Skills.HUNTER,experience)
|
||||
clearTrail(player)
|
||||
}
|
||||
player.unlock()
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the trail varp based on the current trail index
|
||||
* @author Ceikry
|
||||
*/
|
||||
fun updateTrail(player: Player){
|
||||
player ?: return
|
||||
val trail = player.getAttribute(attribute,ArrayList<TrailDefinition>())
|
||||
val trailIndex = player.getAttribute(indexAttribute,0)
|
||||
for(index in 0..trailIndex){
|
||||
val trl = trail[index]
|
||||
player.varpManager.get(varp).setVarbit(trl.offset + 2,1)
|
||||
player.varpManager.get(varp).setVarbit(trl.offset,if(trl.inverted) 1 else 0)
|
||||
}
|
||||
player.varpManager.get(varp).send(player)
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles all trail interactions
|
||||
* @author Ceikry
|
||||
*/
|
||||
override fun handle(player: Player?, node: Node?, option: String?): Boolean {
|
||||
node ?: return true
|
||||
player ?: return true
|
||||
val trail = player.getAttribute(attribute,ArrayList<TrailDefinition>())
|
||||
val currentIndex = player.getAttribute(indexAttribute,0)
|
||||
if(!hasTrail(player) && !initialMap.containsKey(node.id)){
|
||||
player.dialogueInterpreter.sendDialogue("You search but find nothing.")
|
||||
return true
|
||||
}
|
||||
val currentTrail = if(hasTrail(player)) {
|
||||
if (currentIndex < trail.lastIndex) {
|
||||
trail.get(currentIndex + 1)
|
||||
} else {
|
||||
trail.get(currentIndex)
|
||||
}
|
||||
} else {
|
||||
TrailDefinition(0,TrailType.LINKING,false,Location(0,0,0),Location(0,0,0),Location(0,0,0))
|
||||
}
|
||||
when(option){
|
||||
|
||||
"attack" -> {
|
||||
if(!hasNooseWand(player)){
|
||||
player.dialogueInterpreter.sendDialogue("You need a noose wand to catch the kebbit.")
|
||||
return true
|
||||
}
|
||||
if(currentIndex == trail.lastIndex && currentTrail.endLocation.equals(node.location)){
|
||||
reward(player,true)
|
||||
} else {
|
||||
reward(player,false)
|
||||
}
|
||||
}
|
||||
|
||||
"inspect","search" -> {
|
||||
if(!hasTrail(player)){
|
||||
if(player.skills.getLevel(Skills.HUNTER) < requiredLevel){
|
||||
player.dialogueInterpreter.sendDialogue("You need a hunter level of $requiredLevel to track these.")
|
||||
return true
|
||||
}
|
||||
generateTrail(node.asScenery(),player)
|
||||
updateTrail(player)
|
||||
} else {
|
||||
if(currentTrail.triggerObjectLocation.equals(node.location) || (currentIndex == trail.lastIndex && currentTrail.endLocation.equals(node.location))){
|
||||
if(currentIndex == trail.lastIndex){
|
||||
player.dialogueInterpreter.sendDialogue("It looks like something is moving around in there.")
|
||||
} else {
|
||||
player.dialogueInterpreter.sendDialogue("You discover some tracks nearby.")
|
||||
player.incrementAttribute(indexAttribute)
|
||||
updateTrail(player)
|
||||
}
|
||||
} else {
|
||||
player.dialogueInterpreter.sendDialogue("You search but find nothing of interest.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
fun hasNooseWand(player: Player) : Boolean{
|
||||
return player.equipment.contains(Items.NOOSE_WAND_10150,1) || player.inventory.contains(Items.NOOSE_WAND_10150,1)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package content.global.skill.hunter.tracking
|
||||
|
||||
import core.cache.def.impl.SceneryDefinition
|
||||
import core.game.node.item.Item
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import core.plugin.Initializable
|
||||
import core.plugin.Plugin
|
||||
import org.rs09.consts.Items
|
||||
|
||||
@Initializable
|
||||
class PolarKebbitHunting : HunterTracking() {
|
||||
|
||||
init {
|
||||
KEBBIT_ANIM = Animation(5256)
|
||||
trailLimit = 3
|
||||
attribute = "hunter:tracking:polartrail"
|
||||
indexAttribute = "hunter:tracking:polarindex"
|
||||
rewards = arrayOf(Item(Items.RAW_BEAST_MEAT_9986),Item(Items.POLAR_KEBBIT_FUR_10117),Item(Items.BONES_526))
|
||||
tunnelEntrances = arrayOf(
|
||||
Location.create(2711, 3819, 1),
|
||||
Location.create(2714, 3821, 1),
|
||||
Location.create(2718, 3829, 1),
|
||||
Location.create(2721, 3827, 1),
|
||||
Location.create(2718, 3832, 1),
|
||||
Location.create(2715, 3820, 1)
|
||||
)
|
||||
initialMap = hashMapOf(
|
||||
19640 to arrayListOf(
|
||||
TrailDefinition(24,TrailType.TUNNEL,false,Location.create(2712, 3831, 1),Location.create(2718, 3832, 1)),
|
||||
TrailDefinition(21,TrailType.LINKING,true,Location.create(2712, 3831, 1),Location.create(2716, 3827, 1),Location.create(2713,3827,1)),
|
||||
TrailDefinition(12,TrailType.LINKING,false,Location.create(2712, 3831, 1),Location.create(2708, 3819, 1),Location.create(2708,3825,1))
|
||||
),
|
||||
19641 to arrayListOf(
|
||||
TrailDefinition(0,TrailType.LINKING,true,Location.create(2718, 3820, 1),Location.create(2708, 3819, 1),Location.create(2712,3815,1)),
|
||||
TrailDefinition(6,TrailType.TUNNEL,false, Location.create(2718, 3820, 1),Location.create(2715, 3820, 1)),
|
||||
TrailDefinition(9,TrailType.TUNNEL,false,Location.create(2718, 3820, 1),Location.create(2721, 3827, 1))
|
||||
)
|
||||
)
|
||||
linkingTrails = arrayListOf(
|
||||
TrailDefinition(15,TrailType.LINKING,true,Location.create(2714,3821,1),Location.create(2716, 3827, 1)),
|
||||
TrailDefinition(18,TrailType.TUNNEL,true,Location.create(2716, 3827, 1),Location.create(2718,3829,1)),
|
||||
TrailDefinition(3,TrailType.TUNNEL,false,Location.create(2708, 3819, 1),Location.create(2711, 3819, 1))
|
||||
)
|
||||
experience = 30.0
|
||||
varp = 926
|
||||
requiredLevel = 1
|
||||
}
|
||||
|
||||
override fun newInstance(arg: Any?): Plugin<Any> {
|
||||
addExtraTrails()
|
||||
SceneryDefinition.forId(19640).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19641).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19435).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(36689).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(36690).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19421).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19424).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19426).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19419).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19420).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19423).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(36688).handlers["option:inspect"] = this
|
||||
SceneryDefinition.forId(19435).handlers["option:search"] = this
|
||||
SceneryDefinition.forId(19435).handlers["option:attack"] = this
|
||||
return this
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package content.global.skill.hunter.tracking
|
||||
|
||||
import core.game.world.map.Location
|
||||
|
||||
class TrailDefinition(val offset: Int, val type: TrailType, var inverted: Boolean, val startLocation: Location, val endLocation: Location, val triggerObjectLocation: Location = endLocation){
|
||||
override fun toString(): String {
|
||||
return "$startLocation $endLocation [offset: $offset] [${type.name}] [inverted: $inverted]"
|
||||
}
|
||||
}
|
||||
enum class TrailType{
|
||||
LINKING,
|
||||
INITIAL,
|
||||
TUNNEL
|
||||
}
|
||||
Reference in New Issue
Block a user