Rebase with upstream

This commit is contained in:
verinia 2019-05-28 22:15:17 -08:00
commit 101b8314c9
2889 changed files with 481914 additions and 0 deletions

View file

@ -0,0 +1,355 @@
package plugin.zone;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.crandor.cache.def.impl.ObjectDefinition;
import org.crandor.game.content.activity.ActivityManager;
import org.crandor.game.interaction.Option;
import org.crandor.game.interaction.OptionHandler;
import org.crandor.game.node.Node;
import org.crandor.game.node.entity.Entity;
import org.crandor.game.node.entity.npc.NPC;
import org.crandor.game.node.entity.player.Player;
import org.crandor.game.node.object.GameObject;
import org.crandor.game.world.GameWorld;
import org.crandor.game.world.map.Location;
import org.crandor.game.world.map.zone.MapZone;
import org.crandor.game.world.map.zone.ZoneBorders;
import org.crandor.game.world.map.zone.ZoneBuilder;
import org.crandor.game.world.map.zone.ZoneRestriction;
import org.crandor.game.world.update.flag.context.Graphics;
import org.crandor.plugin.Plugin;
import org.crandor.plugin.PluginManager;
import org.crandor.plugin.InitializablePlugin;
import org.crandor.tools.RandomFunction;
/**
* Handles the chaos tunnels.
* @author Vexia
*/
@InitializablePlugin
public final class ChaosTunnelZone extends MapZone implements Plugin<Object> {
/**
* The entrance data.
*/
private static final Object[][] ENTRANCE_DATA = new Object[][] { { 28891, new Location(3182, 5471, 0), 28782, new Location(3059, 3549, 0) },// 1
{ 28893, new Location(3248, 5489, 0), 28782, new Location(3120, 3571, 0) },// 2
{ 28892, new Location(3292, 5479, 0), 28782, new Location(3166, 3561, 0) },// 3
{ 28893, new Location(3234, 5558, 0), 28782, new Location(3107, 3640, 0) },// 4
{ 28892, new Location(3290, 5538, 0), 28782, new Location(3165, 3617, 0) },// 5
};
/**
* The mapping of portals.
*/
private static final Map<Location, Location> PORTALS = new HashMap<>();
/**
* Constructs a new {@Code ChaosTunnelZone} {@Code Object}
*/
public ChaosTunnelZone() {
super("Chaos tunnel", true, ZoneRestriction.CANNON);
}
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ZoneBuilder.configure(this);
PluginManager.definePlugin(new OptionHandler() {
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
for (int i = 0; i < ENTRANCE_DATA.length; i++) {
ObjectDefinition.forId((int) ENTRANCE_DATA[i][0]).getConfigurations().put("option:enter", this);
ObjectDefinition.forId((int) ENTRANCE_DATA[i][2]).getConfigurations().put("option:climb-up", this);
}
ObjectDefinition.forId(23074).getConfigurations().put("option:climb", this);
return this;
}
@Override
public boolean handle(Player player, Node node, String option) {
Object[] data = null;
switch (option) {
case "enter":
case "climb-up":
switch (node.getId()) {
case 28891:
case 28893:
case 28892:
case 28782:
if (option.equals("enter") && player.inCombat()) {
player.sendMessage("You can't enter the rift when you've recently been in combat.");
return true;
}
for (int i = 0; i < ENTRANCE_DATA.length; i++) {
if ((int) ENTRANCE_DATA[i][option.equals("enter") ? 0 : 2] == node.getId() && player.getLocation().withinDistance((Location) ENTRANCE_DATA[i][option.equals("enter") ? 3 : 1])) {
data = ENTRANCE_DATA[i];
break;
}
}
if (data == null) {
player.sendMessage("Error! Data null.");
break;
}
player.teleport((Location) data[option.equals("enter") ? 1 : 3]);
break;
}
break;
case "climb":
switch (node.getId()) {
case 23074:
player.teleport(new Location(3283, 3467, 0));
break;
}
break;
}
return true;
}
});
return this;
}
@Override
public boolean interact(Entity entity, Node target, Option option) {
if (entity instanceof Player) {
switch (target.getId()) {
case 29537:
break;
case 28779:// portal
if (target.getLocation().equals(new Location(3326, 5469, 0))) {
entity.asPlayer().sendMessage("You can't go back throught his portal.");
return true;
}
teleport(entity.asPlayer(), target.asObject());
break;
}
}
return super.interact(entity, target, option);
}
@Override
public boolean enter(Entity entity) {
if (entity instanceof NPC) {
NPC n = entity.asNpc();
if (!n.isAggressive()) {
n.setAggressive(true);
}
}
return super.enter(entity);
}
@Override
public Object fireEvent(String identifier, Object... args) {
return null;
}
@Override
public void configure() {
register(new ZoneBorders(3116, 5412, 3362, 5584));
/* top left */
addLink(3158, 5561, 3162, 5557);
addLink(3162, 5545, 3166, 5553);
addLink(3147, 5541, 3143, 5535);
addLink(3148, 5533, 3153, 5537);
addLink(3152, 5520, 3156, 5523);
addLink(3165, 5515, 3173, 5530);
addLink(3169, 5510, 3159, 5501);
addLink(3181, 5517, 3185, 5518);
addLink(3182, 5530, 3187, 5531);
addLink(3190, 5519, 3190, 5515);
addLink(3196, 5512, 3202, 5515);
addLink(3197, 5529, 3201, 5531);
addLink(3190, 5549, 3190, 5554);
addLink(3180, 5557, 3174, 5558);
addLink(3171, 5542, 3168, 5541);
/* top middle */
addLink(3206, 5553, 3204, 5546);
addLink(3226, 5553, 3230, 5547);
addLink(3214, 5533, 3211, 5533);
addLink(3208, 5527, 3211, 5523);
addLink(3238, 5507, 3232, 5501);
addLink(3241, 5529, 3243, 5526);
addLink(3261, 5536, 3268, 5534);
addLink(3252, 5543, 3249, 5546);
addLink(3262, 5552, 3266, 5552);
addLink(3256, 5561, 3253, 5561);
addLink(3297, 5536, 3299, 5533);
/* top right */
addLink(3285, 5556, 3291, 5555);
addLink(3288, 5536, 3289, 5533);
addLink(3285, 5527, 3282, 5531);
addLink(3285, 5508, 3280, 5501);
addLink(3300, 5514, 3297, 5510);
addLink(3325, 5518, 3323, 5531);
addLink(3321, 5554, 3315, 5552);
/* bottom left */
addLink(3142, 5489, 3141, 5480);
addLink(3142, 5462, 3154, 5462);
addLink(3143, 5443, 3155, 5449);
addLink(3167, 5478, 3171, 5478);
addLink(3171, 5473, 3167, 5471);
addLink(3168, 5456, 3178, 5460);
addLink(3187, 5460, 3189, 5444);
addLink(3192, 5472, 3186, 5472);
addLink(3185, 5478, 3191, 5482);
addLink(3197, 5448, 3204, 5445);
addLink(3191, 5482, 3185, 5478);
addLink(3191, 5495, 3194, 5490);
/* bottom middle */
addLink(3214, 5456, 3212, 5452);
addLink(3229, 5454, 3235, 5457);
addLink(3233, 5445, 3241, 5445);
addLink(3239, 5498, 3244, 5495);
addLink(3233, 5470, 3241, 5469);
addLink(3241, 5445, 3233, 5445);
addLink(3259, 5446, 3265, 5491);
addLink(3260, 5491, 3266, 5446);
addLink(3218, 5478, 3215, 5475);
addLink(3208, 5471, 3210, 5477);
/* bottom right */
addLink(3283, 5448, 3287, 5448);
addLink(3296, 5455, 3299, 5450);
addLink(3302, 5469, 3290, 5463);
addLink(3286, 5470, 3285, 5474);
addLink(3322, 5480, 3318, 5481);
addLink(3317, 5496, 3307, 5496);
addLink(3299, 5484, 3303, 5477);
addLink(3280, 5460, 3273, 5460);
addLink(3285, 5474, 3286, 5470);
addLink(3222, 5474, 3224, 5479);
addLink(3222, 5488, 3218, 5497);
}
/**
* Teleports a player through a portal.
* @param object the object.
* @param player the player.
*/
private void teleport(Player player, GameObject object) {
if (object.getLocation().getX() == 3142 || object.getLocation().getY() == 5545) {
commenceBorkBattle(player);
return;
}
Location loc = getLocation(object.getLocation());
if (loc == null) {
player.sendMessage("Error! Unhandled portal for - " + object + "!");
return;
}
if (!isFixed(player)) {
boolean stained = isStained(object);
if (!stained && RandomFunction.random(100) <= 3) {
stained = true;
setStainedTime(object);
}
if (stained) {
player.sendMessage("The portal is stained with dark magic.");
return;
}
if (RandomFunction.random(100) <= 3) {
loc = getRandomLocation();
player.sendMessage("The dark magic teleports you into a random location.");
}
}
player.teleport(loc);
player.graphics(Graphics.create(110));
}
/**
* Starts the instanced battle against Bork.
* @param player The player.
*/
private void commenceBorkBattle(Player player) {
if ((System.currentTimeMillis() - player.getSavedData().getActivityData().getLastBorkBattle()) < 24 * 60 * 60_000 && GameWorld.getSettings().isHosted()) {
player.getPacketDispatch().sendMessage("The portal's magic is too weak to teleport you right now.");
return;
}
player.lock(10);
player.graphics(Graphics.create(110));
player.getSavedData().getActivityData().setLastBorkBattle(System.currentTimeMillis());
ActivityManager.start(player, "Bork cutscene", false);
}
/**
* Gets a random location.
* @return the location.
*/
private Location getRandomLocation() {
return (Location) RandomFunction.getRandomElement(PORTALS.values().toArray());
}
/**
* Checks if the object is stained.
* @param object the object.
* @return {@code True} if so.
*/
private boolean isStained(GameObject object) {
return getStainedTime(object) > GameWorld.getTicks();
}
/**
* Sets stained time.
* @param object the object.
*/
private void setStainedTime(GameObject object) {
object.getAttributes().setAttribute("stained", (int) GameWorld.getTicks() + RandomFunction.random(50, 150));
}
/**
* Gets the stained tiem.
* @param object the object.
* @return the time.
*/
private int getStainedTime(GameObject object) {
return object.getAttributes().getAttribute("stained", 0);
}
/**
* Checks if the portals are fixed.
* @param player the player.
* @return {@code True} if so.
*/
private boolean isFixed(Player player) {
return false;
}
/**
* Gets a location from the portal.
* @param location the location.
* @return the location.
*/
public Location getLocation(Location location) {
Location l = PORTALS.get(location);
if (l != null) {
return l;
}
for (Entry<Location, Location> entry : PORTALS.entrySet()) {
if (entry.getValue().equals(location)) {
return entry.getKey();
}
}
return null;
}
/**
* Adds a portal link.
* @param x the x.
* @param y the x.
* @param x2 the second x.
* @param y2 the second y.
*/
private void addLink(int x, int y, int x2, int y2) {
addLink(new Location(x, y, 0), new Location(x2, y2, 0));
}
/**
* Adds a portal link.
* @param location the location.
* @param loc the second location.
*/
private void addLink(Location location, Location loc) {
PORTALS.put(location, loc);
}
}

View file

@ -0,0 +1,53 @@
package plugin.zone;
import org.crandor.game.node.entity.Entity;
import org.crandor.game.node.entity.player.Player;
import org.crandor.game.node.entity.player.link.diary.DiaryType;
import org.crandor.game.world.map.zone.MapZone;
import org.crandor.game.world.map.zone.ZoneBorders;
import org.crandor.game.world.map.zone.ZoneBuilder;
import org.crandor.plugin.InitializablePlugin;
import org.crandor.plugin.Plugin;
/**
* Represents the crandor zone.
* @author Vexia
*/
@InitializablePlugin
public class CrandorZone extends MapZone implements Plugin<Object> {
/**
* Constructs a new {@code CrandorZone} {@code Object}
*/
public CrandorZone() {
super("crandor", true);
}
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ZoneBuilder.configure(this);
return this;
}
@Override
public boolean enter(Entity entity) {
if (entity.isPlayer()) {
Player player = entity.asPlayer();
if (!player.getAchievementDiaryManager().getDiary(DiaryType.KARAMJA).isComplete(1, 2)) {
player.getAchievementDiaryManager().getDiary(DiaryType.KARAMJA).updateTask(player, 1, 2, true);
}
}
return super.enter(entity);
}
@Override
public Object fireEvent(String identifier, Object... args) {
return null;
}
@Override
public void configure() {
register(new ZoneBorders(2810, 3223, 2864, 3312));
}
}

View file

@ -0,0 +1,205 @@
package plugin.zone;
import java.util.ArrayList;
import java.util.List;
import org.crandor.cache.def.impl.ItemDefinition;
import org.crandor.game.content.global.tutorial.TutorialSession;
import org.crandor.game.node.entity.Entity;
import org.crandor.game.node.entity.combat.ImpactHandler.HitsplatType;
import org.crandor.game.node.entity.player.Player;
import org.crandor.game.node.entity.player.info.portal.Perks;
import org.crandor.game.node.item.Item;
import org.crandor.game.system.task.Pulse;
import org.crandor.game.world.GameWorld;
import org.crandor.game.world.map.zone.MapZone;
import org.crandor.game.world.map.zone.ZoneBorders;
import org.crandor.game.world.map.zone.ZoneBuilder;
import org.crandor.game.world.update.flag.context.Animation;
import org.crandor.plugin.Plugin;
import org.crandor.plugin.InitializablePlugin;
import org.crandor.tools.RandomFunction;
/**
* The desert zone map.
* @author Emperor
* @author 'Vexia
* @version 2.0
*/
@InitializablePlugin
public final class DesertZone extends MapZone implements Plugin<Object> {
/**
* Represents the hydrateable waterskin items.
*/
private static final Item[] WATER_SKINS = new Item[] { new Item(1823), new Item(1825), new Item(1827), new Item(1829) };
/**
* Represents data of water vessils to dry up.
*/
private static final int[][] VESSILS = new int[][] { { 1937, 1935 }, { 1929, 1925 }, { 1921, 1923 }, { 227, 229 } };
/**
* Represents the animation of drinking water.
*/
private static final Animation ANIMATION = new Animation(829);
/**
* The players list.
*/
private static final List<Player> PLAYERS = new ArrayList<>();
/**
* The water draining pulse.
*/
private static Pulse pulse = new Pulse(3) {
@Override
public boolean pulse() {
for (Player player : PLAYERS) {
if (player.getInterfaceManager().isOpened() || player.getInterfaceManager().hasChatbox() || player.getLocks().isMovementLocked()) {
continue;
}
if (player.getAttribute("desert-delay", -1) < GameWorld.getTicks()) {
effect(player);
}
}
return PLAYERS.isEmpty();
}
};
/**
* Method used to handle the desert effect on the <code>Player</code>.
* @param p the <code>Player</code>.
*/
private static void effect(Player p) {
p.setAttribute("desert-delay", GameWorld.getTicks() + getDelay(p));
if (p.getDetails().getShop().hasPerk(Perks.THIRST_QUENCHER)) {
return;
}
evaporate(p);
if (drink(p)) {
return;
}
p.getImpactHandler().manualHit(p, RandomFunction.random(1, p.getLocation().getY() < 2990 ? 12 : 8), HitsplatType.NORMAL);
p.getPacketDispatch().sendMessage("You start dying of thirst while you're in the desert.");
}
/**
* Method used to evaporate the water vessils in the inventory.
* @param player the <code>Player</code>
*/
public static void evaporate(Player p) {
for (int i = 0; i < VESSILS.length; i++) {
if (p.getInventory().contains(VESSILS[i][0], 1)) {
if (p.getInventory().remove(new Item(VESSILS[i][0]))) {
p.getInventory().add(new Item(VESSILS[i][1]));
p.getPacketDispatch().sendMessage("The water in your " + ItemDefinition.forId(VESSILS[i][0]).getName().toLowerCase().replace("of water", "").trim() + " evaporates in the desert heat.");
}
}
}
}
/**
* Method used to drink a waterskin in the inventory.
* @param p the player.
*/
public static boolean drink(Player p) {
for (Item i : WATER_SKINS) {
if (p.getInventory().containsItem(i) && p.getInventory().remove(i)) {
p.getInventory().add(new Item(i.getId() + 2));
p.animate(ANIMATION);
p.getPacketDispatch().sendMessage("You take a drink of water.");
return true;
}
}
if (p.getInventory().contains(1831, 1)) {
p.getPacketDispatch().sendMessage("Perhaps you should fill up one of your empty waterskins.");
} else {
p.getPacketDispatch().sendMessage("You should get a waterskin for any travelling in the desert.");
}
return false;
}
/**
* Method used to calculate the delay to the next desert effect.
* @param player the player.
* @return <code>Long</code> the amount of the delay.
*/
private static int getDelay(Player player) {
int delay = 116;
if (player.getEquipment().contains(1833, 1)) {
delay += 17;
}
if (player.getEquipment().contains(1835, 1)) {
delay += 17;
}
if (player.getEquipment().contains(1837, 1)) {
delay += 17;
}
return delay;
}
/**
* Constructs a new {@code DesertZone} {@code Object}.
*/
public DesertZone() {
super("Desert Zone", true);
}
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ZoneBuilder.configure(this);
return this;
}
@Override
public Object fireEvent(String identifier, Object... args) {
return null;
}
@Override
public void configure() {
ZoneBorders borders = new ZoneBorders(3063, 2725, 3544, 3115);
borders.addException(new ZoneBorders(3152, 2961, 3191, 2999));// Bandit
// camp
borders.addException(new ZoneBorders(3147, 3019, 3185, 3059));// Bedabin
borders.addException(new ZoneBorders(3217, 2881, 3248, 2914));// pyramid
borders.addException(new ZoneBorders(3264, 2752, 3323, 2810));// Sophanem
borders.addException(new ZoneBorders(3007, 4672, 3071, 4735));// agility-pyramid
// top(region12105)
borders.addException(new ZoneBorders(3274, 3014, 3305, 3041));// Mining
// camp
borders.addException(new ZoneBorders(3260, 9408, 3331, 9472));// Mining
// camp
register(borders);
pulse.stop();
}
@Override
public boolean enter(Entity e) {
if (e instanceof Player) {
Player p = (Player) e;
if (TutorialSession.getExtension(p).getStage() < TutorialSession.MAX_STAGE) {
return true;
}
p.setAttribute("desert-delay", GameWorld.getTicks() + getDelay(p));
PLAYERS.add(p);
if (!pulse.isRunning()) {
pulse.restart();
pulse.start();
GameWorld.submit(pulse);
}
}
return true;
}
@Override
public boolean leave(Entity e, boolean logout) {
if (e instanceof Player) {
PLAYERS.remove(e);
e.removeAttribute("desert-delay");
}
return super.leave(e, logout);
}
}

View file

@ -0,0 +1,714 @@
package plugin.zone;
import org.crandor.cache.def.impl.ItemDefinition;
import org.crandor.game.content.dialogue.DialogueInterpreter;
import org.crandor.game.content.dialogue.DialoguePlugin;
import org.crandor.game.content.dialogue.FacialExpression;
import org.crandor.game.content.global.shop.Shop;
import org.crandor.game.content.global.shop.ShopViewer;
import org.crandor.game.interaction.NodeUsageEvent;
import org.crandor.game.interaction.Option;
import org.crandor.game.interaction.UseWithHandler;
import org.crandor.game.node.Node;
import org.crandor.game.node.entity.Entity;
import org.crandor.game.node.entity.player.Player;
import org.crandor.game.node.entity.player.info.portal.DonatorType;
import org.crandor.game.node.entity.player.link.TeleportManager.TeleportType;
import org.crandor.game.node.item.Item;
import org.crandor.game.node.object.GameObject;
import org.crandor.game.node.object.ObjectBuilder;
import org.crandor.game.system.mysql.impl.ShopSQLHandler;
import org.crandor.game.system.task.Pulse;
import org.crandor.game.system.task.TaskExecutor;
import org.crandor.game.world.GameWorld;
import org.crandor.game.world.map.Location;
import org.crandor.game.world.map.zone.MapZone;
import org.crandor.game.world.map.zone.ZoneBorders;
import org.crandor.game.world.map.zone.ZoneBuilder;
import org.crandor.plugin.InitializablePlugin;
import org.crandor.plugin.Plugin;
import org.crandor.plugin.PluginManager;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* The grand exchange map zone.
* @author Emperor
*
*/
@InitializablePlugin
public final class GrandExchangeZone extends MapZone implements Plugin<Object> {
/**
* The store that sells items in exchange for credits.
*/
private static final CreditStore CREDIT_STORE = new CreditStore();
/**
* Constructs a new {@code GrandExchangeZone} {@code Object}.
*/
public GrandExchangeZone() {
super("grand exchange", true);
}
@Override
public void configure() {
addObjects();
PluginManager.definePlugin(new TeleporterDialogue(), new GnomeTravellerPlugin(), new RewardTraderDialogue());
ShopSQLHandler.getUidShops().put(1485756, CREDIT_STORE);
super.register(new ZoneBorders(3146, 3472, 3183, 3508));
}
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ZoneBuilder.configure(this);
return this;
}
@Override
public Object fireEvent(String identifier, Object... args) {
return null;
}
@Override
public boolean interact(Entity entity, Node node, Option option) {
if(entity instanceof Player){
Player player = entity.asPlayer();
switch(option.getName()){
case "Talk-to":
switch(node.getId()){
case 8631:
entity.asPlayer().getDialogueInterpreter().open(123656);
return true;
case 3322:
case 8029:
case 8174:
case 8139:
ShopSQLHandler.getShops().get(node.getId()).open(player);
break;
}
break;
case "Trade":
switch(node.getId()){
case 8631:
CREDIT_STORE.open(entity.asPlayer());
return true;
}
break;
}
}
return super.interact(entity, node, option);
}
/**
* The store that sells items in exchange for credits. Point prices are read from the item config table.
* @author Splinter
*/
public static class CreditStore extends Shop {
/**
* The default credit price if no item configuration was found.
*/
private final int DEFAULT_PRICE = 50;
/**
* Constructs a new {@Code CreditStore} {@Code Object}
*/
public CreditStore() {
super(GameWorld.getName()+"RSPS.org <col=FF0000>Voting</col> Credit Shop", new Item[] {new Item(6199, 100), new Item(14810, 100), new Item(14807, 100), new Item(14674, 100), new Item(13661, 10)}, false);
setPointShop(true);
}
@Override
public void open(final Player player) {
TaskExecutor.executeSQL(new Runnable() {
@Override
public void run() {
if (player.getDetails().getShop().syncCredits()) {
CreditStore.super.open(player);
int credits = player.getDetails().getShop().getCredits();
player.sendMessage("<col=CC0000>You currently have " + credits + (credits == 1 ? " credit" : " credits") + " to spend.");
}
}
});
}
@Override
public void buy(final Player player, final int slot, final int amount, final int tabIndex) {
TaskExecutor.executeSQL(new Runnable() {
@Override
public void run() {
if (player.getDetails().getShop().syncCredits()) {
if(checkConditions(player, slot, amount, tabIndex)){
CreditStore.super.buy(player, slot, amount, tabIndex);
player.sendMessage("You now have <col=CC0000>"+player.getDetails().getShop().getCredits()+"</col> credit(s) remaining.");
}
} else {
player.sendMessages("Sorry, you cannot buy from the shop right now. Our database needs to sync", "some remaining data.");
}
}
});
}
@Override
public boolean canSell(Player player, Item item, ItemDefinition def) {
player.sendMessage("You cannot sell items to this store.");
return false;
}
@Override
public String getPointsName() {
return "credit";
}
@Override
public void value(Player player, ShopViewer viewer, Item item, boolean sell) {
if(sell){
player.sendMessage("You cannot sell items to this store.");
} else {
player.sendMessage(item.getName().contains("ring") ? "This item costs "+getBuyPrice(item, player)+" "+getPointsName()+"s plus a regular unimbued version of the ring." : "This item costs "+getBuyPrice(item, player)+" "+getPointsName()+"s.");
}
}
@Override
public int getBuyPrice(Item item, Player player) {
return item.getDefinition().getConfiguration("point_price", DEFAULT_PRICE);
}
@Override
public void decrementPoints(Player player, int decrement) {
player.getDetails().getShop().setCredits(player.getDetails().getShop().getCredits() - decrement, true);
}
@Override
public int getPoints(Player player) {
return player.getDetails().getShop().getCredits();
}
/**
* Checks to see if the player is eligible to buy the item.
* @return true if so.
*/
private boolean checkConditions(Player player, int slot, int amount, int tabIndex){
String itemName = CreditStore.super.getItems()[slot].getName();
int buyId = CreditStore.super.getItems()[slot].getId();
if(itemName.contains("ring")){
if(!player.getInventory().containsItem(getUnimbued(buyId, amount))){
player.sendMessage("You need 35 credits plus a regular version of the ring in order to upgrade to imbued.");
return false;
} else {
if(player.getDetails().getShop().getCredits() > getBuyPrice(CreditStore.super.getItems()[slot], player) * amount){
if(player.getInventory().remove(getUnimbued(buyId, amount))){
return true;
} else {
player.sendMessage("You don't have that many unimbued rings.");
}
} else{
player.sendMessage("You don't have that many credits.");
return false;
}
}
} else {
return true;
}
return false;
}
/**
* Gets the un-imbued ring ID.
* @return
*/
private Item getUnimbued(int imbuedRing, int amount){
switch(imbuedRing){
case 14810:
return new Item(6737, amount);
case 14808:
return new Item(6733, amount);
case 14809:
return new Item(6735, amount);
case 14807:
return new Item(6731, amount);
}
return new Item(-1);
}
}
/**
* Represents the dialogue plugin for the GE rewards trader
* @author Splinter
*/
@InitializablePlugin
public final class RewardTraderDialogue extends DialoguePlugin {
/**
* Constructs a new {@code RewardTraderDialogue} {@code Object}.
*/
public RewardTraderDialogue() {
/**
* empty.
*/
}
/**
* Constructs a new {@code RewardTraderDialogue} {@code Object}.
* @param player the player.
*/
public RewardTraderDialogue(Player player) {
super(player);
}
@Override
public DialoguePlugin newInstance(Player player) {
return new RewardTraderDialogue(player);
}
@Override
public boolean open(Object... args) {
interpreter.sendDialogues(8631, FacialExpression.OSRS_NORMAL, "Greetings, "+player.getUsername()+". I offer a wide assortment", "of valuable goods that you may be interested in.");
stage = 0;
return true;
}
@Override
public boolean handle(int interfaceId, int buttonId) {
switch (stage) {
case 0:
interpreter.sendDialogues(8631, FacialExpression.OSRS_NORMAL, "The items I have for sale are in exchange for your", "continued dedication in assisting "+GameWorld.getName()+". Please","continue to show support by voting daily on our", "website.");
stage = 1;
break;
case 1:
interpreter.sendOptions("Select an Option", "How do I obtain credits?", "Let me see your store.", "Nevermind.");
stage = 2;
break;
case 2:
switch(buttonId){
case 1:
interpreter.sendDialogues(player, null, "How do I obtain "+GameWorld.getName()+" credits?");
stage = 3;
break;
case 2:
interpreter.sendDialogues(player, null, "Let me see your store.");
stage = 10;
break;
case 3:
interpreter.sendDialogues(player, null, "Nevermind.");
stage = 15;
break;
}
break;
case 3:
interpreter.sendDialogues(8631, FacialExpression.OSRS_NORMAL, "Visit our website by heading to www.keldagrim.org.", "Log-in to the website with your in-game details", "and then simply vote via the account panel in order", "to obtain your credits.");
stage = 4;
break;
case 4:
interpreter.sendDialogues(8631, FacialExpression.OSRS_NORMAL, "You may have to log out of your account and back in", "for your credits to visually appear in your account.", "To view how many credits you have, you may type", "::shop or ::credits while in-game.");
stage = 1;
break;
case 10:
interpreter.sendDialogues(8631, FacialExpression.OSRS_NORMAL, "Certainly.");
stage = 11;
break;
case 11:
end();
CREDIT_STORE.open(player);
break;
case 15:
end();
break;
}
return true;
}
@Override
public int[] getIds() {
return new int[] { 8631, 123656 };
}
}
/**
* Represents the dialogue plugin for the GE Teleporter
* @author Splinter
*
*/
@InitializablePlugin
public static final class TeleporterDialogue extends DialoguePlugin {
/**
* The teleport destinations.
*/
private static final Object[][][] TELEPORTS = new Object[][][] {
{{"Training"}, {"Cows", Location.create(3256, 3266, 0)}, {"Stronghold of Security", Location.create(3080, 3421, 0)}, {"Rock crabs", Location.create(2672, 3712, 0)}, {"Al-Kharid Warriors", Location.create(3293, 3180, 0)}, {"Neitiznot Yaks", Location.create(2326, 3803, 0)}, {"Desert Bandits", Location.create(3176, 2987, 0)}, {"TzHaar", Location.create(2450, 5165, 0)}, {"Fremmenik Slayer Dungeon", Location.create(2796, 3615, 0)}, {"H.A.M. Hideout", Location.create(3149, 9652, 0)}, {"Armoured Zombies", Location.create(3239, 3606, 0)}, {"Asgarnian Ice Caves", Location.create(3014, 9579, 0)}, {"Slayer Tower", Location.create(3429, 3535, 0)}, {"Brimhaven Dungeon (bring 875 gp)", Location.create(2744, 3152, 0)}, {"Brine Rat Cave", Location.create(2690, 10124, 0)}, {"Ape Atoll Dungeon", Location.create(2764, 9103, 0)}},
{{"Cities"}, {"Lumbridge", Location.create(3222, 3217, 0)}, {"Falador", Location.create(2965, 3380, 0)}, {"Edgeville", Location.create(3088, 3491, 0)}, {"Varrock", Location.create(3213, 3428, 0)}, {"Ardougne", Location.create(2663, 3305, 0)}, {"Seer's Village", Location.create(2713, 3484, 0)}, {"Burthorpe", Location.create(2898, 3544, 0)}, {"Rellekka", Location.create(2659, 3657, 0)}, {"Neitiznot", Location.create(2335, 3803, 0)}, {"Al-Kharid", Location.create(3293, 3184, 0)}, {"Karamja/Brimhaven", Location.create(2910, 3152, 0)}, {"Yanille", Location.create(2605, 3093, 0)}, {"Mos'le Harmless", Location.create(3676, 2975, 0)}, {"Tree Gnome Stronghold", Location.create(2450, 3422, 0)}, {"Shilo Village", Location.create(2849, 2961, 0)}, {"Piscatoris Fishing Colony", Location.create(2344, 3655, 0)}},
{{"Minigames"}, {"Pest Control", Location.create(2659, 2649, 0)}, {"Duel Arena", Location.create(3352, 3265, 0)}, {"Sorceress' Garden", Location.create(3315, 3163, 0)}, {"Warrior's Guild", Location.create(2881, 3546, 0)}, {"Puro Puro(requires Lost City)", Location.create(2592, 4317, 0)}, {"Fight Pits", Location.create(2399, 5178, 0)}, {"Clan Wars", Location.create(3272, 3687, 0)}, {"Magic Training Arena", Location.create(3363, 3298, 0)}},
};
/**
* The lastIndex displayed.
*/
private int firstIndex;
/**
* The option index.
*/
private int optionIndex;
/**
* Constructs a new {@code TeleporterDialogue} {@code Object}.
*/
public TeleporterDialogue() {
/**
* empty.
*/
}
/**
* Constructs a new {@code TeleporterDialogue} {@code Object}.
* @param player the player.
*/
public TeleporterDialogue(Player player) {
super(player);
}
@Override
public DialoguePlugin newInstance(Player player) {
return new TeleporterDialogue(player);
}
@Override
public boolean open(Object... args) {
int minutes = (int) TimeUnit.MILLISECONDS.toMinutes(player.getSavedData().getGlobalData().getGlobalTeleporterDelay() - System.currentTimeMillis());
if (minutes < 1) {
minutes = 1;
}
interpreter.sendItemMessage(563, "This is the Keldagrim teleporter. You may use it every","five minutes to freely teleport to many places.", (player.getSavedData().getGlobalData().getGlobalTeleporterDelay() > System.currentTimeMillis() ? "<col=CC4000>You are on cooldown for the next "+ (minutes)+" minute(s)." : ""));
stage = -5;
return true;
}
@Override
public boolean handle(int interfaceId, int buttonId) {
int index;
switch (stage) {
case -10:
end();
break;
case -5:
interpreter.sendOptions("Select an Option", "Buy teletabs", "Use teleporter");
stage = 0;
break;
case 0:
switch(buttonId){
case 1:
end();
ShopSQLHandler.openUid(player, 200);
break;
case 2:
if (player.getSavedData().getGlobalData().getGlobalTeleporterDelay() > System.currentTimeMillis()) {
long millis = player.getSavedData().getGlobalData().getGlobalTeleporterDelay() - System.currentTimeMillis();
int minutes = (int) TimeUnit.MILLISECONDS.toMinutes(millis);
if (minutes < 1) {
minutes = 1;
}
interpreter.sendDialogue("You need to wait " + minutes + " more minute" + (minutes > 1 ? "s" : "") + " in order to use the free", "teleportation system again.");
stage = -10;
return true;
}
player.removeAttribute("global_teleporter");
String[] options = new String[TELEPORTS.length];
for (int i = 0; i < TELEPORTS.length; i++) {
options[i] = (String) TELEPORTS[i][0][0];
}
interpreter.sendOptions("Select an Option", options);
stage = 1;
break;
}
break;
case 1:
index = buttonId - 1;
optionIndex = index;
sendOptions();
stage = 2;
break;
case 2:
index = buttonId - 1;
int teleIndex = (firstIndex + index) + 1;
int optionSize = 3;
for (int i = 0; i < 3; i++) {
if (firstIndex + 1 + i > TELEPORTS[optionIndex].length-1) {
optionSize = i;
break;
}
}
if (teleIndex > firstIndex + optionSize) {
firstIndex = firstIndex + optionSize;
sendOptions();
break;
}
Object teleports[] = TELEPORTS[optionIndex][teleIndex];
if (optionIndex == 2 && teleports[teleIndex] == "Puro Puro(requires Lost City)" && !player.getQuestRepository().isComplete("Lost City")) {
interpreter.sendDialogue("You need to have completed Lost City to teleport here.");
break;
}
send(player, (Location) teleports[1]);
break;
}
return true;
}
/**
* Sends the options.
*/
private void sendOptions() {
if (firstIndex >= TELEPORTS[optionIndex].length -1) {
firstIndex = 0;
}
int optionSize = 3;
Object[][] data = TELEPORTS[optionIndex];
for (int i = 0; i < 3; i++) {
if (firstIndex + 1 + i > data.length-1) {
optionSize = i;
break;
}
}
String [] options = new String[optionSize + 1];
for (int i = 0; i < optionSize; i++) {
options[i] = (String) data[firstIndex + (i + 1)][0];
}
options[options.length - 1] = "More Options";
interpreter.sendOptions("Select an Option", options);
}
/**
* Sends the player to the specified location.
*/
private void send(final Player player, final Location loc){
player.getDialogueInterpreter().close();
player.getPulseManager().run(new Pulse(1, player) {
int counter = 5;
@Override
public boolean pulse() {
switch(--counter){
case -1:
player.getInterfaceManager().closeChatbox();
player.getSavedData().getGlobalData().setGlobalTeleporterDelay(System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(player.getDonatorType() == DonatorType.EXTREME ? 1 : player.getDonatorType() == DonatorType.REGULAR ? 3 : 5));
player.getTeleporter().send(loc, TeleportType.TELE_OTHER);
return true;
default:
player.getDialogueInterpreter().sendPlainMessage(true, "You will be teleported in... "+counter+".", "Move away to cancel.");
return false;
}
}
});
}
@Override
public int[] getIds() {
return new int[] { 543543 };
}
}
/**
* Handles the gnome traveller whom buys low level skilling items.
* @author Vexia
*
*/
public static class GnomeTravellerPlugin extends UseWithHandler {
/**
* The items the gnome accepts.
*/
private static final Object[][] ITEMS = new Object[][] {{1511, 70}, {1521, 120}, {1519, 90}, {434, 50}, {436, 70}, {438, 70}, {440, 120}, {317, 50}, {315, 70}, {327, 50}, {325, 70}, {321, 50}, {319, 70}, {335, 50}, {333, 70}, {249, 145}, {199, 130}, {253, 200}, {203, 190}, {255, 220}, {205, 160}, {2351, 410}, {52, 10}, {2349, 135}};
/**
* Constructs the gnome traveller plugin.
*/
public GnomeTravellerPlugin() {
super(getItemIds());
}
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
addHandler(2138, NPC_TYPE, this);
PluginManager.definePlugin(new GnomeDialogue());
return this;
}
@Override
public boolean handle(NodeUsageEvent event) {
int price = getPrice(event.getUsedItem().getId());
if (price < 1 && event.getUsedItem().getDefinition().getNoteId() > -1) {
price = getPrice(event.getUsedItem().getDefinition().getNoteId());
}
if (price < 1) {
return false;
}
Player player = event.getPlayer();
player.getDialogueInterpreter().open(DialogueInterpreter.getDialogueKey("gnome-traveller"), new Item(event.getUsedItem().getId(), player.getInventory().getAmount(event.getUsedItem())), price);
return true;
}
/**
* Gets the price of an item.
* @param itemId The item id.
* @return The price.
*/
public int getPrice(int itemId) {
for (int i = 0; i < ITEMS.length; i++) {
if (itemId == (int) ITEMS[i][0]) {
return (int) ITEMS[i][1];
}
}
return 0;
}
/**
* Gets the item ids.
* @return The item ids.
*/
public static int[] getItemIds() {
List<Integer> items = new ArrayList<>();
for (int i = 0; i < ITEMS.length; i++) {
items.add((int) ITEMS[i][0]);
if (ItemDefinition.forId((int) ITEMS[i][0]).getNoteId() > -1 ) {
items.add(ItemDefinition.forId((int) ITEMS[i][0]).getNoteId());
}
}
int[] array = new int[items.size()];
for (int i = 0; i < array.length; i++) {
array[i] = items.get(i);
}
return array;
}
/**
* The gnome dialogue.
* @author Vexia
*
*/
@InitializablePlugin
public class GnomeDialogue extends DialoguePlugin {
/**
* The item used.
*/
private Item item;
/**
* The price offered.
*/
private int price;
/**
* Constructs the {@code GnomeDialogue}
* @param player The player.
*/
public GnomeDialogue(Player player) {
super(player);
}
/**
* Constructs the {@code GnomeDialogue}
*/
public GnomeDialogue() {
/*
* empty.
*/
}
@Override
public DialoguePlugin newInstance(Player player) {
return new GnomeDialogue(player);
}
@Override
public boolean open(Object... args) {
item = (Item) args[0];
price = (int) args[1];
player.getDialogueInterpreter().sendDialogues(2138, FacialExpression.OSRS_NORMAL, "A total of " + item.getAmount() + " to sell, not too shabby.", "I'll offer you " + price + " for each for a total of", price * item.getAmount() + " gold.");;
stage = 1;
return true;
}
@Override
public boolean handle(int interfaceId, int buttonId) {
switch (stage) {
case 1:
options("Sell " + item.getAmount() + " for " + price + " each.", "No.");
stage++;
break;
case 2:
switch (buttonId) {
case 1:
if (player.getInventory().remove(item)) {
player.getInventory().add(new Item(995, price * item.getAmount()));
interpreter.sendItemMessage(new Item(995, price), "You hand over your items in exchange for gold.");
stage = 5;
break;
}
end();
break;
case 2:
player("I think I will hold on to these for now.");
stage = 3;
break;
}
break;
case 3:
player.getDialogueInterpreter().sendDialogues(2138, FacialExpression.OSRS_NORMAL, "Very well. I will be here if you decide to sell me", "raw materials.", "Just keep in mind I offer a better bargain than", "most other vendors!");
stage++;
break;
case 4:
end();
break;
case 5:
player.getDialogueInterpreter().sendDialogues(2138, FacialExpression.OSRS_NORMAL, "Pleasure doing business with you, " + player.getUsername() + ".");
stage = 4;
break;
}
return true;
}
@Override
public int[] getIds() {
return new int[] { DialogueInterpreter.getDialogueKey("gnome-traveller")};
}
}
}
/**
* The objects to spawn in the Grand Exchange Zone.
*/
private final void addObjects(){
ObjectBuilder.add(new GameObject(11402, new Location(3160, 3468)));
ObjectBuilder.add(new GameObject(11402, new Location(3159, 3468)));
ObjectBuilder.add(new GameObject(1161, new Location(3149, 3471)));
ObjectBuilder.add(new GameObject(1161, new Location(3149, 3470)));
ObjectBuilder.add(new GameObject(1161, new Location(3151, 3470)));
ObjectBuilder.add(new GameObject(1161, new Location(3150, 3470)));
ObjectBuilder.add(new GameObject(1161, new Location(3151, 3471)));
ObjectBuilder.add(new GameObject(1161, new Location(3150, 3471)));
ObjectBuilder.add(new GameObject(1161, new Location(3152, 3471)));
ObjectBuilder.add(new GameObject(1161, new Location(3152, 3470)));
ObjectBuilder.add(new GameObject(29954, new Location(3155, 3469)));
ObjectBuilder.add(new GameObject(2732, new Location(3182, 3474)));
ObjectBuilder.add(new GameObject(24343, new Location(3168, 3468), 10, 4));
ObjectBuilder.add(new GameObject(36781, new Location(3176, 3509)));
ObjectBuilder.add(new GameObject(17985, new Location(3179, 3471), 22, 1));
ObjectBuilder.add(new GameObject(2092, new Location(3153, 3510)));
ObjectBuilder.add(new GameObject(2092, new Location(3154, 3511)));
ObjectBuilder.add(new GameObject(2092, new Location(3152, 3513), 2));
ObjectBuilder.add(new GameObject(17010, new Location(3151, 3484), 1));
ObjectBuilder.add(new GameObject(6552, new Location(3149, 3487), 1));
ObjectBuilder.add(new GameObject(2096, new Location(3159, 3512)));
ObjectBuilder.add(new GameObject(2097, new Location(3157, 3513)));
ObjectBuilder.add(new GameObject(11666, Location.create(3142, 3487, 0)));
ObjectBuilder.add(new GameObject(2783, Location.create(3143, 3490, 0)));
ObjectBuilder.add(new GameObject(13656, Location.create(3173, 3485, 0)));
}
}

View file

@ -0,0 +1,48 @@
package plugin.zone;
import org.crandor.game.node.object.GameObject;
import org.crandor.game.node.object.ObjectBuilder;
import org.crandor.game.world.map.Location;
import org.crandor.game.world.map.zone.MapZone;
import org.crandor.game.world.map.zone.ZoneBorders;
import org.crandor.game.world.map.zone.ZoneBuilder;
import org.crandor.plugin.Plugin;
import org.crandor.plugin.PluginManager;
import plugin.zone.GrandExchangeZone.TeleporterDialogue;
public class HomeZone extends MapZone implements Plugin<Object> {
/**
* Constructs a new {@code HomeZone} {@code Object}.
*/
public HomeZone() {
super("home", true);
}
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ZoneBuilder.configure(this);
return this;
}
@Override
public Object fireEvent(String identifier, Object... args) {
return null;
}
@Override
public void configure() {
addObjects();
PluginManager.definePlugin(new TeleporterDialogue());
super.register(new ZoneBorders(3075, 3460, 3115, 3519));
}
/**
* The objects to spawn in the Grand Exchange Zone.
*/
private final void addObjects(){
ObjectBuilder.add(new GameObject(29534, new Location(3084, 3490), 1));
}
}

View file

@ -0,0 +1,91 @@
package plugin.zone;
import org.crandor.game.component.Component;
import org.crandor.game.node.entity.Entity;
import org.crandor.game.node.entity.combat.ImpactHandler.HitsplatType;
import org.crandor.game.node.entity.player.Player;
import org.crandor.game.system.task.Pulse;
import org.crandor.game.world.GameWorld;
import org.crandor.game.world.map.zone.MapZone;
import org.crandor.game.world.map.zone.ZoneBorders;
import org.crandor.game.world.map.zone.ZoneBuilder;
import org.crandor.plugin.Plugin;
import org.crandor.plugin.InitializablePlugin;
import org.crandor.tools.RandomFunction;
/**
* The God Wars entrance zone monitor.
* @author Emperor
*/
@InitializablePlugin
public final class IcePathZone extends MapZone implements Plugin<Object> {
/**
* Constructs a new {@code IcePathZone} {@code Object}.
*/
public IcePathZone() {
super("Ice path zone", true);
}
@Override
public void configure() {
ZoneBorders border = new ZoneBorders(2821, 3712, 2940, 3839);
border.addException(new ZoneBorders(2821, 3712, 2838, 3745));
register(border);
}
@Override
public boolean enter(Entity e) {
if (e instanceof Player) {
final Player player = (Player) e;
player.getInterfaceManager().openOverlay(new Component(482)); // TODO:
// find
// the
// real
// one
Pulse pulse = new Pulse(10, player) {
@Override
public boolean pulse() {
if (player.getLocks().isMovementLocked()) {
return false;
}
player.getSettings().updateRunEnergy(100);
player.getImpactHandler().manualHit(player, 1, HitsplatType.NORMAL);
int skill = RandomFunction.randomize(7);
if (skill == 3 || skill == 5) {
skill++;
}
player.getSkills().updateLevel(skill, -1, 0);
return false;
}
};
player.setAttribute("ice_path_pulse", pulse);
GameWorld.submit(pulse);
}
return true;
}
@Override
public boolean leave(Entity e, boolean logout) {
if (e instanceof Player) {
((Player) e).getInterfaceManager().closeOverlay();
Pulse pulse = e.getAttribute("ice_path_pulse");
if (pulse != null) {
pulse.stop();
e.removeAttribute("ice_path_pulse");
}
}
return true;
}
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ZoneBuilder.configure(this);
return this;
}
@Override
public Object fireEvent(String identifier, Object... args) {
return null;
}
}

View file

@ -0,0 +1,40 @@
package plugin.zone;
import org.crandor.game.world.map.zone.MapZone;
import org.crandor.game.world.map.zone.ZoneBorders;
import org.crandor.game.world.map.zone.ZoneBuilder;
import org.crandor.game.world.map.zone.ZoneRestriction;
import org.crandor.plugin.InitializablePlugin;
import org.crandor.plugin.Plugin;
/**
* Handles the tzhaar zone.
* @author Vexia
*/
@InitializablePlugin
public class TzhaarZone extends MapZone implements Plugin<Object> {
/**
* Constructs a new {@code TzhaarZone} {@code Object}
*/
public TzhaarZone() {
super("Tzhaar zone", true, ZoneRestriction.CANNON);
}
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ZoneBuilder.configure(this);
return this;
}
@Override
public Object fireEvent(String identifier, Object... args) {
return null;
}
@Override
public void configure() {
register(new ZoneBorders(2369, 5054, 2549, 5188));
}
}

View file

@ -0,0 +1,580 @@
package plugin.zone;
import org.crandor.game.content.dialogue.DialogueAction;
import org.crandor.game.content.dialogue.DialoguePlugin;
import org.crandor.game.content.dialogue.FacialExpression;
import org.crandor.game.content.global.action.DoorActionHandler;
import org.crandor.game.content.global.tutorial.TutorialSession;
import org.crandor.game.content.global.tutorial.TutorialStage;
import org.crandor.game.content.skill.SkillPulse;
import org.crandor.game.content.skill.Skills;
import org.crandor.game.content.skill.free.gather.SkillingResource;
import org.crandor.game.content.skill.free.gather.SkillingTool;
import org.crandor.game.interaction.NodeUsageEvent;
import org.crandor.game.interaction.Option;
import org.crandor.game.interaction.UseWithHandler;
import org.crandor.game.node.Node;
import org.crandor.game.node.entity.Entity;
import org.crandor.game.node.entity.combat.BattleState;
import org.crandor.game.node.entity.npc.AbstractNPC;
import org.crandor.game.node.entity.npc.NPC;
import org.crandor.game.node.entity.player.Player;
import org.crandor.game.node.entity.player.info.portal.Perks;
import org.crandor.game.node.item.Item;
import org.crandor.game.world.GameWorld;
import org.crandor.game.world.map.Location;
import org.crandor.game.world.map.zone.MapZone;
import org.crandor.game.world.map.zone.ZoneBorders;
import org.crandor.game.world.map.zone.ZoneBuilder;
import org.crandor.plugin.InitializablePlugin;
import org.crandor.plugin.Plugin;
import org.crandor.plugin.PluginManager;
import java.util.ArrayList;
import java.util.List;
/**
* Handles the Wilderness Area Zone.
* @author Empathy
* @author Vexia
*
*/
@InitializablePlugin
public class WildernessAreaZone extends MapZone implements Plugin<Object> {
/**
* The list of players in the arena.
*/
private final List<Player> players = new ArrayList<>();
/**
* Constructs a new {@code WildernessAreaZone} {@code Object}
*/
public WildernessAreaZone() {
super("Wilderness Area Zone", true);
}
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ZoneBuilder.configure(this);
PluginManager.definePlugin(new MandrithDialoguePlugin(), new PilesDialoguePlugin(), new PilesItemHandler(), new RuniteGolemNPC());
return this;
}
@Override
public boolean interact(Entity e, final Node node, Option option) {
if (e instanceof Player) {
Player player = e.asPlayer();
switch (node.getId()) {
case 42044:
switch (option.getName()) {
case "Open":
if (player.getLocation().equals(Location.create(3184, 3945, 0))) {
if (player.getInventory().contains(995, 7500)) {
player.getDialogueInterpreter().sendOptions("Pay 7500 coins?", "Yes", "No");
player.getDialogueInterpreter().addAction(new DialogueAction() {
@Override
public void handle(Player player, int buttonId) {
switch (buttonId) {
case 2:
if (player.getInventory().remove(new Item(995, 7500))) {
DoorActionHandler.handleDoor(player, node.asObject());
player.sendMessage("You pay 7500 coins and enter the resource arena.");
}
break;
}
}
});
return true;
}
player.sendMessage("You do not have enough coins to enter the Arena.");
return true;
}
DoorActionHandler.handleDoor(player, node.asObject());
return true;
case "Players-inside":
if (player.getLocation().getY() < 3495) {
player.sendMessage("All you see is the barren wasteland of the Wilderness.");
return true;
}
String message = "You peek inside the gate and see no adventurers inside the arena.";
if (players.size() > 0) {
message = players.size() == 1 ? "You peek inside the gate and see 1 adventurer inside the arena." : "You peek inside the gate and see " + players.size() + " inside the arena.";
}
player.getDialogueInterpreter().sendDialogue(message);
break;
}
break;
case 8666:
switch (option.getName()) {
case "Mine":
player.getPulseManager().run(new RuniteGolemMinePulse(player, node.asNpc()));
return true;
case "Prospect":
player.sendMessages("You examine the rock for ores...", "This rock contains runite ore.");
return true;
}
break;
}
}
return super.interact(e, node, option);
}
@Override
public Object fireEvent(String identifier, Object... args) {
return null;
}
@Override
public void configure() {
register(new ZoneBorders(3174, 3924, 3196, 3945));
}
@Override
public boolean enter(Entity e) {
if (e instanceof Player) {
Player p = e.asPlayer();
players.add(p);
}
return super.enter(e);
}
@SuppressWarnings("deprecation")
@Override
public boolean leave(Entity e, boolean logout) {
if (e instanceof Player) {
Player p = e.asPlayer();
players.remove(p);
if (logout && p.getLocation().getY() <= 3944) {
p.setLocation(Location.create(3184, 3945, 0));
return true;
}
}
return super.leave(e, logout);
}
/**
* The mining of a runite golem.
* @author Vexia
*
*/
public class RuniteGolemMinePulse extends SkillPulse<NPC> {
/**
* The skilling tool used.
*/
private SkillingTool tool;
/**
* The ticks.
*/
private int ticks;
/**
* Constructs a new @{Code RuniteGolemMinePulse} object.
* @param player The player.
* @param node The node.
*/
public RuniteGolemMinePulse(Player player, NPC node) {
super(player, node);
}
@Override
public void start() {
resource = SkillingResource.RUNITE_ORE_0;
if (node.getId() != 8666) {
player.getPacketDispatch().sendMessage("This rock contains no ore.");
return;
}
if (resource == null) {
return;
}
if (TutorialSession.getExtension(player).getStage() == 35) {
TutorialStage.load(player, 36, false);
}
super.start();
}
@Override
public boolean checkRequirements() {
if (node.getId() != 8666) {
return false;
}
if (player.getSkills().getLevel(resource.getSkillId()) < resource.getLevel()) {
player.getPacketDispatch().sendMessage("You need a " + Skills.SKILL_NAME[resource.getSkillId()] + " level of " + resource.getLevel() + " to mine this rock.");
return false;
}
if ((tool = SkillingTool.getPickaxe(player)) == null) {
player.getPacketDispatch().sendMessage("You do not have a pickaxe to use.");
return false;
}
if (player.getInventory().freeSlots() < 1) {
player.getDialogueInterpreter().sendDialogue("Your inventory is too full to hold any more runite ore.");
return false;
}
return true;
}
@Override
public void animate() {
if (tool != null) {
player.animate(tool.getAnimation());
}
}
@Override
public boolean reward() {
if (++ticks % 4 != 0) {
return false;
}
if (!checkReward()) {
return false;
}
node.transform(8667);
node.setAttribute("reward-tick", GameWorld.getTicks() + resource.getRespawnDuration());
Perks.addDouble(player, new Item(resource.getReward()));
player.getSkills().addExperience(resource.getSkillId(), resource.getExperience(), true);
return true;
}
/**
* Checks if the player gets rewarded.
* @return {@code True} if so.
*/
private boolean checkReward() {
int skill = Skills.MINING;
int level = 1 + player.getSkills().getLevel(skill) + player.getFamiliarManager().getBoost(skill);
double hostRatio = Math.random() * (100.0 * resource.getRate());
double clientRatio = Math.random() * ((level - resource.getLevel()) * (1.0 + tool.getRatio()));
return hostRatio < clientRatio;
}
}
/**
* Handles the runite golem npc.
* @author Vexia
*
*/
public class RuniteGolemNPC extends AbstractNPC {
/**
* The respawn time.
*/
private int respawn = -1;
/**
* Constructs a new @{Code RuniteGolemNPC} object.
* @param id The npc id.
* @param location The location.
*/
public RuniteGolemNPC(int id, Location location) {
super(id, location);
}
/**
* Constructs a new @{Code RuniteGolemNPC} object.
*/
public RuniteGolemNPC() {
super(-1, null);
}
@Override
public AbstractNPC construct(int id, Location location, Object... objects) {
return new RuniteGolemNPC(id, location);
}
@Override
public void init() {
super.init();
setAggressive(false);
}
@Override
public void sendImpact(BattleState state) {
super.sendImpact(state);
if (state.getEstimatedHit() > 16) {
state.setEstimatedHit(16);
}
}
@Override
public void handleTickActions() {
super.handleTickActions();
if (isAggressive()) {
setAggressive(false);
}
if (respawn != -1 && respawn < GameWorld.getTicks() && getId() > 8664) {
transform(8664);
unlock();
}
if (getId() == 8667) {
int rewardTick = getAttribute("reward-tick", -1);
if (rewardTick != -1 && rewardTick < GameWorld.getTicks()) {
transform(8666);
}
}
}
@Override
public void finalizeDeath(Entity killer) {
respawn = GameWorld.getTicks() + 500;
fullRestore();
getProperties().setTeleportLocation(getLocation());
setRespawnTick(0);
setInvisible(false);
transform(8666);
lock();
faceLocation(null);
face(null);
}
@Override
public int[] getIds() {
return new int[] {8664};
}
}
/**
* Handles the item on piles interaction.
* @author Vexia
*
*/
public static class PilesItemHandler extends UseWithHandler {
/**
* The allowed items for piles.
*/
private static final int[] ALLOWED = new int[] {14937, 14939, 449, 447, 440, 444, 453, 451, 1515, 1513, 2349, 9467,2351,2355,2353,2357,2359,2361,2363};
/**
* Constructs a new @{Code PilesItemHandler} object.
*/
public PilesItemHandler() {
super();
}
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
addHandler(8663, NPC_TYPE, this);
return this;
}
@Override
public boolean handle(final NodeUsageEvent event) {
final Player player = event.getPlayer();
for (int itemId : ALLOWED) {
if (event.getUsedItem().getId() == itemId) {
final int amount = player.getInventory().getAmount(itemId);
final int price = 50 * amount;
if (!player.getInventory().contains(995, price)) {
player.getDialogueInterpreter().sendDialogues(8663, FacialExpression.OSRS_NORMAL, "I'll need 50 coins per item.");
return true;
}
player.getDialogueInterpreter().sendOptions("Banknote " + amount + " x " + event.getUsedItem().getName() + "?", "Yes - " + price + " gp", "Cancel");
player.getDialogueInterpreter().addAction((player1, buttonId) -> {
if (player1.getInventory().remove(new Item(995, price)) && player1.getInventory().remove(new Item(event.getUsedItem().getId(), amount))) {
player1.getInventory().add(new Item(event.getUsedItem().getNoteChange(), amount));
player1.getDialogueInterpreter().sendItemMessage(event.getUsedItem().getId(), "Piles converts your items to banknotes.");
}
});
return true;
}
}
player.getDialogueInterpreter().sendDialogues(8663, FacialExpression.OSRS_NORMAL, "Sorry, I wasn't expecting anyone to want to convert", "that sort of item, so I haven't any banknotes for it.");
return true;
}
@Override
public boolean isDynamic() {
return true;
}
}
/**
* Handles the Piles dialogue.
* @author Vexia
*
*/
public class PilesDialoguePlugin extends DialoguePlugin {
/**
* Constructs a new @{Code PilesDialoguePlugin} object.
*/
public PilesDialoguePlugin() {
/*
* empty.
*/
}
/**
* Constructs a new @{Code PilesDialoguePlugin} object.
* @param player The player.
*/
public PilesDialoguePlugin(Player player) {
super(player);
}
@Override
public DialoguePlugin newInstance(Player player) {
return new PilesDialoguePlugin(player);
}
@Override
public boolean open(Object... args) {
npc("Hello. I can convert items to banknotes, for 50 coins", "per item. Just hand me the items you'd like me to", "convert.");
stage = 0;
return true;
}
@Override
public boolean handle(int interfaceId, int buttonId) {
switch (stage) {
case 0:
options("Who are you?", "Thanks.");
stage++;
break;
case 1:
switch (buttonId) {
case 1:
player("Who are you?");
stage = 10;
break;
case 2:
player("Thanks.");
stage = 2;
break;
}
break;
case 2:
end();
break;
case 10:
npc("I'm Piles. I lived in Draynor Village when I was", "young, where I saw three men working in the market,", "converting items to banknotes.");
stage++;
break;
case 11:
npc("Their names were Niles, Miles and Giles. I'm trying to", "be like them, so I've changed my name and started this", "business here.");
stage++;
break;
case 12:
player("Thanks.");
stage = 2;
break;
}
return true;
}
@Override
public int[] getIds() {
return new int[] {8663};
}
}
/**
* Handles the Mandrith dialogue.
* @author Empathy
*
*/
public class MandrithDialoguePlugin extends DialoguePlugin {
/**
*
* Constructs a new @{Code MandrithDialoguePlugin} object.
*/
public MandrithDialoguePlugin() {
/*
* empty
*/
}
/**
*
* Constructs a new @{Code MandrithDialoguePlugin} object.
* @param player
*/
public MandrithDialoguePlugin(Player player) {
super(player);
}
@Override
public DialoguePlugin newInstance(Player player) {
return new MandrithDialoguePlugin(player);
}
@Override
public boolean open(Object... args) {
player("Who are you and what is this place?" );
stage = 1;
return true;
}
@Override
public boolean handle(int interfaceId, int buttonId) {
switch (stage) {
case 1:
npc("My name is Mandrith." );
stage = 2;
break;
case 2:
npc("I collect valuable resources and pawn off access to them", "to foolish adventurers, like yourself" );
stage = 3;
break;
case 3:
npc("You should take a look inside my arena. There's an", "abundance of valuable resources inside." );
stage = 4;
break;
case 4:
player("And I can take whatever I want?" );
stage = 5;
break;
case 5:
npc("It's all yours. All I ask is that you pay the upfront fee." );
stage = 6;
break;
case 6:
player("Will others be able to kill me inside?" );
stage = 7;
break;
case 7:
npc("Yes. These walls will only hold them back for so long." );
stage = 8;
break;
case 8:
player("You'll stop them though, right?" );
stage = 9;
break;
case 9:
npc("Haha! For the right price, I won't deny anyone access", "to my arena. Even if their intention is to kill you." );
stage = 10;
break;
case 10:
player("Right..." );
stage = 11;
break;
case 11:
npc("My arena holds many treasure that I've acquired at", "great expense, adventurer. Their bounty can come at a", "price." );
stage = 12;
break;
case 12:
npc("One day, adventurer, I will boast ownership of a much", "larger, much more dangerous arena than this. Take", "advantage of this offer while it lasts." );
stage = 13;
break;
case 13:
end();
break;
}
return false;
}
@Override
public int[] getIds() {
return new int[] { 8662 };
}
}
}

View file

@ -0,0 +1,220 @@
package plugin.zone;
import org.crandor.game.content.global.action.ClimbActionHandler;
import org.crandor.game.content.skill.Skills;
import org.crandor.game.content.skill.member.agility.AgilityHandler;
import org.crandor.game.interaction.Option;
import org.crandor.game.node.Node;
import org.crandor.game.node.entity.Entity;
import org.crandor.game.node.entity.combat.BattleState;
import org.crandor.game.node.entity.combat.CombatSpell;
import org.crandor.game.node.entity.combat.CombatStyle;
import org.crandor.game.node.entity.npc.AbstractNPC;
import org.crandor.game.node.entity.player.Player;
import org.crandor.game.node.entity.state.EntityState;
import org.crandor.game.node.item.Item;
import org.crandor.game.node.object.GameObject;
import org.crandor.game.node.object.ObjectBuilder;
import org.crandor.game.system.task.Pulse;
import org.crandor.game.world.GameWorld;
import org.crandor.game.world.map.Direction;
import org.crandor.game.world.map.Location;
import org.crandor.game.world.map.zone.MapZone;
import org.crandor.game.world.map.zone.ZoneBorders;
import org.crandor.game.world.map.zone.ZoneBuilder;
import org.crandor.game.world.update.flag.context.Animation;
import org.crandor.plugin.Plugin;
import org.crandor.plugin.PluginManager;
import org.crandor.plugin.InitializablePlugin;
import org.crandor.tools.RandomFunction;
/**
* Handles the yanille agility dungeon.
* @author Vexia
*/
@InitializablePlugin
public class YanilleAgilityDungeon extends MapZone implements Plugin<Object> {
/**
* The herb items.
*/
private static final Item[] HERBS = new Item[] { new Item(205, 2), new Item(207, 3), new Item(209), new Item(211), new Item(213), new Item(219) };
/**
* Constructs a new {@Code YanilleAgilityDungeon} {@Code
* Object}
*/
public YanilleAgilityDungeon() {
super("Yanilee agility", true);
}
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ZoneBuilder.configure(this);
PluginManager.definePlugin(new SalarinTwistedNPC());
return this;
}
@Override
public boolean interact(Entity entity, Node target, Option option) {
if (entity instanceof Player) {
Player player = entity.asPlayer();
switch (target.getId()) {
case 1728:
player.teleport(new Location(2620, 9565, 0));
return true;
case 1729:
player.teleport(new Location(2620, 9496, 0));
return true;
case 2316:
player.teleport(Location.create(2569, 9525, 0));
return true;
case 2318:
case 2317:
if (player.getSkills().getLevel(Skills.AGILITY) < 67) {
player.getDialogueInterpreter().sendDialogue("You need an Agility level of at least 67 in order to do this.");
return true;
}
Location loc = target.getId() == 2317 ? new Location(2615, 9503, 0) : new Location(2617, 9572, 0);
ClimbActionHandler.climb(player, target.getId() == 2317 ? ClimbActionHandler.CLIMB_UP : ClimbActionHandler.CLIMB_DOWN, loc);
player.sendMessage("You climb " + (target.getId() == 2317 ? "up" : "down") + " the pile of rubble...");
player.getSkills().addExperience(Skills.AGILITY, 5.5, true);
return true;
case 35969:
case 2303:
handleBalancingLedge(player, target.asObject());
return true;
case 377:
if (!player.getInventory().contains(993, 1)) {
player.sendMessage("The chest is locked.");
} else {
if (player.getInventory().freeSlots() == 0) {
player.sendMessage("You don't have enough inventory space.");
return true;
}
player.lock(1);
player.getInventory().remove(new Item(993));
player.sendMessages("You unlock the chest with your key...", "A foul gas seeps from the chest");
player.getStateManager().register(EntityState.POISONED, true, 28, player);
for (Item item : HERBS) {
player.getInventory().add(item, player);
}
ObjectBuilder.replace(target.asObject(), target.asObject().transform(target.getId() + 1), 5);
}
return true;
case 378:
switch (option.getName().toLowerCase()) {
case "search":
player.sendMessage("The chest is empty.");
break;
case "shut":
break;
}
return true;
}
}
return super.interact(entity, target, option);
}
/**
* Handles the balancing ledge.
* @param player the player.
* @param object the object.
*/
private void handleBalancingLedge(final Player player, GameObject object) {
if (player.getSkills().getLevel(Skills.AGILITY) < 40) {
player.getDialogueInterpreter().sendDialogue("You need an Agility level of at least 40 in order to do this.");
return;
}
final Direction dir = Direction.getLogicalDirection(player.getLocation(), object.getLocation());
final int diff = player.getLocation().getY() == 9512 ? 0 : 1;
Location end = object.getLocation();
double xp = 0.0;
if (AgilityHandler.hasFailed(player, 40, 0.01)) {
player.lock(3);
GameWorld.submit(new Pulse(2, player) {
@Override
public boolean pulse() {
AgilityHandler.fail(player, 1, new Location(2572, 9570, 0), Animation.create(761 - diff), RandomFunction.random(1, 3), "You lost your balance!");
return true;
}
});
} else {
xp = 22.5;
end = object.getLocation().transform(dir.getStepX() * 7, dir.getStepY() * 7, 0);
}
AgilityHandler.walk(player, -1, player.getLocation(), end, Animation.create(157 - diff), xp, null);
}
@Override
public Object fireEvent(String identifier, Object... args) {
return null;
}
@Override
public void configure() {
register(new ZoneBorders(2544, 9481, 2631, 9587));
}
/**
* Handles the salarin twisted npc.
* @author Vexia
*/
public static class SalarinTwistedNPC extends AbstractNPC {
/**
* The spell ids.
*/
private static final int[] SPELL_IDS = new int[] { 1, 4, 6, 8 };
/**
* Constructs a new {@Code SalarinTwistedNPC} {@Code
* Object}
*/
public SalarinTwistedNPC() {
super(-1, null);
}
/**
* Constructs a new {@Code SalarinTwistedNPC} {@Code
* Object}
* @param id the id.
* @param location the location.
*/
public SalarinTwistedNPC(int id, Location location) {
super(id, location);
super.setAggressive(true);
}
@Override
public AbstractNPC construct(int id, Location location, Object... objects) {
return new SalarinTwistedNPC(id, location);
}
@Override
public void checkImpact(BattleState state) {
if (state.getStyle() != CombatStyle.MAGIC) {
state.neutralizeHits();
return;
}
if (state.getSpell() == null) {
state.neutralizeHits();
return;
}
CombatSpell spell = state.getSpell();
for (int id : SPELL_IDS) {
if (id == spell.getSpellId()) {
return;
}
}
state.neutralizeHits();
}
@Override
public int[] getIds() {
return new int[] { 205 };
}
}
}

View file

@ -0,0 +1,30 @@
package plugin.zone.fremmenik;
import org.crandor.cache.def.impl.NPCDefinition;
import org.crandor.game.interaction.OptionHandler;
import org.crandor.game.node.Node;
import org.crandor.game.node.entity.player.Player;
import org.crandor.plugin.Plugin;
/**
* Handles the fremmenik plugin.
* @author Vexia
*/
public class FremmenikPlugin extends OptionHandler {
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
NPCDefinition.forId(5508).getConfigurations().put("option:ferry-neitiznot", this);
return this;
}
@Override
public boolean handle(Player player, Node node, String option) {
switch (option) {
case "ferry-neitiznot":
return true;
}
return true;
}
}

View file

@ -0,0 +1,105 @@
package plugin.zone.neitiznot;
import org.crandor.game.content.dialogue.DialoguePlugin;
import org.crandor.game.node.entity.player.Player;
import org.crandor.game.node.item.Item;
/**
* Handles the mawnis burowgar dialogue.
* @author Vexia
*/
public class MawnisBurowgarDialogue extends DialoguePlugin {
/**
* The helmet of neitiznot.
*/
private static final Item HELM = new Item(10828);
/**
* Constructs a new {@code MawnisBurowgarDialogue} {@code Object}
*/
public MawnisBurowgarDialogue() {
/**
* empty.
*/
}
/**
* Constructs a new {@code MawnisBurowgarDialogue} {@code Object}
* @param player the player.
*/
public MawnisBurowgarDialogue(Player player) {
super(player);
}
@Override
public DialoguePlugin newInstance(Player player) {
return new MawnisBurowgarDialogue(player);
}
@Override
public boolean open(Object... args) {
npc("It makes me proud to know that the helm of my", "ancestors will be worn in battle.");
return true;
}
@Override
public boolean handle(int interfaceId, int buttonId) {
switch (stage) {
case 0:
npc("I thank you on behalf of all my kinsmen Talvald.");
stage++;
break;
case 1:
if (player.hasItem(HELM) || player.hasItem(new Item(10843))) {
end();
break;
}
player("Ah yes, about that beautiful helmet.");
stage++;
break;
case 2:
npc("You mean the priceless heirloom that I have to you as", "a sign of my trust and gratitude?");
stage++;
break;
case 3:
player("Err yes, that one. I may have mislaid it.");
stage++;
break;
case 4:
npc("It's a good job I have alert and loyal men who notice", "when something like this is left lying around and picks it", "up.");
stage++;
break;
case 5:
npc("I'm afraid I'm going to have to charge you a", "50,000GP handling cost.");
stage++;
break;
case 6:
if (!player.getInventory().contains(995, 50000)) {
player("I don't have that much money on me.");
stage++;
break;
}
if (player.getInventory().remove(new Item(995, 50000))) {
player.getInventory().add(HELM, player);
interpreter.sendItemMessage(HELM, "The Burgher hands you his crown.");
stage = 8;
}
break;
case 7:
npc("Well, come back when you do.");
stage++;
break;
case 8:
end();
break;
}
return true;
}
@Override
public int[] getIds() {
return new int[] { 5504 };
}
}

View file

@ -0,0 +1,63 @@
package plugin.zone.neitiznot;
import org.crandor.game.interaction.Option;
import org.crandor.game.node.Node;
import org.crandor.game.node.entity.Entity;
import org.crandor.game.node.entity.player.Player;
import org.crandor.game.world.map.zone.MapZone;
import org.crandor.game.world.map.zone.ZoneBuilder;
import org.crandor.plugin.Plugin;
import org.crandor.plugin.InitializablePlugin;
import org.crandor.plugin.PluginManager;
/**
* Handles the neitiznot zone.
* @author Vexia
*/
@InitializablePlugin
public class NeitiznotZone extends MapZone implements Plugin<Object> {
/**
* Constructs a new {@code NeitiznotZone} {@code Object}
*/
public NeitiznotZone() {
super("Neitiznot zone", true);
}
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ZoneBuilder.configure(this);
PluginManager.definePlugin(new MawnisBurowgarDialogue(), new ThakkradYakDialogue(), new YakArmourPlugin(), new YakArmourPlugin());
return this;
}
@Override
public boolean interact(Entity e, Node target, Option option) {
if (e instanceof Player) {
Player player = e.asPlayer();
switch (target.getId()) {
case 21301:
player.getBank().open();
return true;
case 5506:
if (option.getName().equals("Craft-goods")) {
player.getDialogueInterpreter().open("thakkrad-yak");
return true;
}
break;
}
}
return super.interact(e, target, option);
}
@Override
public Object fireEvent(String identifier, Object... args) {
return null;
}
@Override
public void configure() {
registerRegion(9275);
}
}

View file

@ -0,0 +1,144 @@
package plugin.zone.neitiznot;
import org.crandor.game.content.dialogue.DialogueInterpreter;
import org.crandor.game.content.dialogue.DialoguePlugin;
import org.crandor.game.node.entity.player.Player;
import org.crandor.game.node.item.Item;
/**
* Handles the thakkrad yak dialogue.
* @author Vexia
*/
public class ThakkradYakDialogue extends DialoguePlugin {
/**
* Constructs a new {@code ThakkradYakDialogue} {@code Object}
*/
public ThakkradYakDialogue() {
/**
* empty.
*/
}
/**
* Constructs a new {@code ThakkradYakDialogue} {@code Object}
* @param player the player.
*/
public ThakkradYakDialogue(Player player) {
super(player);
}
@Override
public DialoguePlugin newInstance(Player player) {
return new ThakkradYakDialogue(player);
}
@Override
public boolean open(Object... args) {
options("Cure my yak-hide, please.", "Nothing, thanks.");
return true;
}
@Override
public boolean handle(int interfaceId, int buttonId) {
switch (stage) {
case 0:
switch (buttonId) {
case 1:
player("Cure my yak-hide, please.");
stage = 4;
break;
case 2:
player("Nothing, thanks.");
stage++;
break;
}
break;
case 1:
interpreter.sendDialogues(5506, null, "See you later.");
stage++;
break;
case 2:
interpreter.sendDialogues(5506, null, "You won't find anyone else who can cure yak-hide.");
stage++;
break;
case 3:
end();
break;
case 4:
interpreter.sendDialogues(5506, null, "I will cure yak-hide for a fee of 5 gp per hide.");
stage++;
break;
case 5:
if (!player.getInventory().contains(10818, 1)) {
interpreter.sendDialogues(5506, null, "You have no yak-hide to cure.");
stage = 7;
break;
}
if (!player.getInventory().contains(995, 5)) {
interpreter.sendDialogues(5506, null, "You don't have enough gold to pay me!");
stage = 7;
break;
}
options("Cure all my hides.", "Cure one hide.", "Cure no nide.", "Can you cure any other type of leather?");
stage++;
break;
case 6:
switch (buttonId) {
case 1:
case 2:
cure(player, buttonId == 2 ? 1 : player.getInventory().getAmount(10818));
stage = 8;
break;
case 3:
interpreter.sendDialogues(5506, null, "Bye!");
stage = 7;
break;
case 4:
interpreter.sendDialogues(5506, null, "Other types of leather? Why would you need any other", "type of leather?");
stage = 40;
break;
}
break;
case 7:
end();
break;
case 40:
player("I'll take that as a no then.");
stage = 7;
break;
case 8:
end();
break;
}
return true;
}
/**
* Cures the yak hide.
* @param player the player.
* @param amount the amount.
* @return {@code True} if cured.
*/
private boolean cure(Player player, int amount) {
if (!player.getInventory().contains(995, 5 * amount)) {
interpreter.sendDialogues(5506, null, "You don't have enough gold to pay me!");
return false;
}
if (player.getInventory().remove(new Item(995, 5 * amount))) {
for (int i = 0; i < amount; i++) {
if (player.getInventory().remove(new Item(10818))) {
player.getInventory().add(new Item(10820));
}
}
}
player("There you go!");
return true;
}
@Override
public int[] getIds() {
return new int[] { DialogueInterpreter.getDialogueKey("thakkrad-yak") };
}
}

View file

@ -0,0 +1,160 @@
package plugin.zone.neitiznot;
import org.crandor.game.content.dialogue.SkillDialogueHandler;
import org.crandor.game.content.dialogue.SkillDialogueHandler.SkillDialogue;
import org.crandor.game.content.skill.SkillPulse;
import org.crandor.game.content.skill.Skills;
import org.crandor.game.content.skill.free.crafting.armour.LeatherCrafting;
import org.crandor.game.interaction.NodeUsageEvent;
import org.crandor.game.interaction.UseWithHandler;
import org.crandor.game.node.entity.player.Player;
import org.crandor.game.node.entity.player.info.portal.Perks;
import org.crandor.game.node.item.Item;
import org.crandor.game.world.update.flag.context.Animation;
import org.crandor.plugin.Plugin;
import org.crandor.tools.RandomFunction;
/**
* Handles the crafting of yak armour.
* @author Vexia
*/
public class YakArmourPlugin extends UseWithHandler {
/**
* The body item.
*/
private static final Item BODY = new Item(10822);
/**
* The legs item.
*/
private static final Item LEGS = new Item(10824);
/**
* Constructs a new {@code YakArmourPlugin} {@code Object}
*/
public YakArmourPlugin() {
super(1733);
}
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
addHandler(10820, ITEM_TYPE, this);
return this;
}
@Override
public boolean handle(final NodeUsageEvent event) {
final Player player = event.getPlayer();
SkillDialogueHandler dialogue = new SkillDialogueHandler(player, SkillDialogue.TWO_OPTION, LEGS, BODY) {
@Override
public void create(final int amount, int index) {
player.getPulseManager().run(new YakArmourPulse(player, index == 1 ? LEGS : BODY, index, amount));
}
@Override
public int getAll(int index) {
return player.getInventory().getAmount(event.getUsedItem());
}
};
dialogue.open();
return true;
}
/**
* Handles the crafting of yak armour.
* @author Vexia
*/
public class YakArmourPulse extends SkillPulse<Item> {
/**
* The index.
*/
private final int index;
/**
* The ticks.
*/
private int ticks;
/**
* The amount.
*/
private int amount;
/**
* Constructs a new {@code YakArmourPulse} {@code Object}
* @param player the player.
* @param node the node.
* @param index the index.
*/
public YakArmourPulse(Player player, Item node, int index, int amount) {
super(player, node);
this.index = index;
this.amount = amount;
}
@Override
public boolean checkRequirements() {
int level = (index == 1 ? 43 : 46);
if (player.getSkills().getLevel(Skills.CRAFTING) < level) {
player.getDialogueInterpreter().sendDialogue("You need a Crafting level of at least " + level + " in order to do this.");
return false;
}
if (!player.getInventory().contains(LeatherCrafting.NEEDLE, 1)) {
return false;
}
if (!player.getInventory().containsItem(LeatherCrafting.THREAD)) {
player.getDialogueInterpreter().sendDialogue("You need some thread to make anything out of leather.");
return false;
}
int reqAmount = index == 1 ? 1 : 2;
if (!player.getInventory().contains(10820, reqAmount)) {
player.getDialogueInterpreter().sendDialogue("You don't have the required amount of yak-hide in order to do this.");
return false;
}
player.getInterfaceManager().close();
return true;
}
@Override
public void animate() {
if (ticks % 5 == 0) {
player.animate(Animation.create(1249));
}
}
@Override
public boolean reward() {
if (++ticks % 5 != 0) {
return false;
}
if (!player.getDetails().getShop().hasPerk(Perks.GOLDEN_NEEDLE) && RandomFunction.random(30) == 5) {
if (player.getInventory().remove(new Item(LeatherCrafting.NEEDLE))) {
player.getPacketDispatch().sendMessage("Your needle broke.");
return true;
}
}
int reqAmount = index == 1 ? 1 : 2;
if (player.getInventory().remove(new Item(10820, reqAmount))) {
Perks.addDouble(player, node);
if (player.getDetails().getShop().hasPerk(Perks.GOLDEN_NEEDLE) && RandomFunction.random(100) <= 10) {
player.getSkills().addExperience(Skills.CRAFTING, (32 * 0.35), true);
player.sendMessage("Your golden needle rewards you with some extra XP!");
}
player.getSkills().addExperience(Skills.CRAFTING, 32, true);
LeatherCrafting.decayThread(player);
if (LeatherCrafting.isLastThread(player)) {
LeatherCrafting.removeThread(player);
}
player.sendMessage("You make " + node.getName().toLowerCase() + ".");
}
amount--;
return amount < 1;
}
}
}

View file

@ -0,0 +1,58 @@
package plugin.zone.phasmatys;
import org.crandor.game.interaction.NodeUsageEvent;
import org.crandor.game.interaction.UseWithHandler;
import org.crandor.game.node.entity.player.Player;
import org.crandor.game.node.item.Item;
import org.crandor.game.system.task.Pulse;
import org.crandor.game.world.update.flag.context.Animation;
import org.crandor.plugin.Plugin;
/**
* Handles the ectoplasm filling.
* @author Vexia
*/
public class EctoplasmFillPlugin extends UseWithHandler {
/**
* The object ids of the slime.
*/
private static final int[] OBJECTS = new int[] { 5461, 17116, 17117, 17118, 17119 };
/**
* Constructs a new {@code EctoplasmFillPlugin} {@code Object}.
*/
public EctoplasmFillPlugin() {
super(1925);
}
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
for (int id : OBJECTS) {
addHandler(id, OBJECT_TYPE, this);
}
return this;
}
@Override
public boolean handle(NodeUsageEvent event) {
final Player player = event.getPlayer();
player.animate(Animation.create(4471));
player.getPacketDispatch().sendMessage("You fill the bucket with ectoplasm.");
player.getPulseManager().run(new Pulse(3, player) {
@Override
public boolean pulse() {
if (player.getInventory().remove(new Item(1925, 1))) {
player.getInventory().add(new Item(4286));
if (player.getInventory().contains(1925, 1)) {
player.animate(Animation.create(4471), 1);
return false;
}
}
return !player.getInventory().contains(1925, 1);
}
});
return true;
}
}

View file

@ -0,0 +1,171 @@
package plugin.zone.phasmatys;
import org.crandor.game.content.dialogue.DialoguePlugin;
import org.crandor.game.node.entity.npc.NPC;
import org.crandor.game.node.entity.player.Player;
import org.crandor.game.node.item.Item;
/**
* Handles the dialogue used for a ghost disciple.
* @author Vexia
*/
public final class GhostDiscipleDialogue extends DialoguePlugin {
/**
* Constructs a new {@code GhostDiscipleDialogue} {@code Object}.
*/
public GhostDiscipleDialogue() {
/**
* empty.
*/
}
/**
* Constructs a new {@code GhostDiscipleDialogue} {@code Object}.
* @param player the player.
*/
public GhostDiscipleDialogue(Player player) {
super(player);
}
@Override
public DialoguePlugin newInstance(Player player) {
return new GhostDiscipleDialogue(player);
}
@Override
public boolean open(Object... args) {
npc = (NPC) args[0];
if (player.getSavedData().getGlobalData().getEctoCharges() > 0) {
player("Can I have the tokens I have earned?");
stage = 80;
return true;
}
if (player.getLocation().getZ() > 0) {
if (args.length > 1) {
npc("What are you doing going in there?");
stage = 70;
return true;
}
player("How do I use the bone grinder?");
stage = 60;
return true;
}
player("What is this strange fountain?");
return true;
}
@Override
public boolean handle(int interfaceId, int buttonId) {
switch (stage) {
case 0:
npc("This is the Ectofuntus, the most marvellous creation of", "Necrovarus, our glorious leader.");
stage++;
break;
case 1:
options("What is the Ectofunuts?", "Where do I get ectoplasm from?", "How do I grind bones?", "How do I receive Ectotokens?", "Thanks for your time.");
stage++;
break;
case 2:
switch (buttonId) {
case 1:
player("What is the Ectofunuts?");
stage = 10;
break;
case 2:
player("Where do I get ectoplasm from?");
stage = 20;
break;
case 3:
player("How do I grind bones?");
stage = 30;
break;
case 4:
player("How do I receive Ectotokens?");
stage = 40;
break;
case 5:
player("Thanks for your time.");
stage = 50;
break;
}
break;
case 10:
npc("It provides the power to keep us ghosts from passing", "over into the next plane of existence.");
stage++;
break;
case 11:
player("And how does it work?");
stage++;
break;
case 12:
npc("You have to pour a bucket of ectoplasm into the", "fountain, a pot of ground bones, and then worship at", "the Ectofuntus. A unit of unholy power will then be", "created.");
stage = 1;
break;
case 20:
npc("Necrovarus sensed the power bubbling beneath our feet,", "and we delved long and deep beneath Port Phasmatys,", "until we found a pool of natural ectoplasm. You may", "find it by using the trapdoor over there.");
stage = 1;
break;
case 30:
npc("There is a bone grinding machine upstairs. Put bones", "of any type into the machine's hopper, and then turn", "the handle to grind them. You will need a pot to empty", "the machine of ground up bones.");
stage = 1;
break;
case 40:
npc("We disciples keep track of how many units of power", "have been produced. Just talk to us once you have", "generated some and we will reimburse you with the", "correct amount of Ectotokens.");
stage++;
break;
case 41:
player("How do I generate units of power?");
stage++;
break;
case 42:
npc("You have to pour a bucket of ectoplasm into the", "fountain and then worship at the Ectofuntus with a pot", "of ground bones. This will create a unit of unholy", "power.");
stage = 1;
break;
case 50:
end();
break;
case 60:
npc("Put bones of any type into the machine's hopper, and", "then turn the handle to grind them. You will need a pot", "to empty the machine of ground up bones.");
stage++;
break;
case 61:
end();
break;
case 70:
player("Err, I was just curious...");
stage++;
break;
case 71:
npc("Inside that room is a coffin, inside which lie the mortal", "remains of our most glorious master. Necrovarus.", "None may enter.");
stage++;
break;
case 72:
end();
break;
case 80:
final int amount = player.getSavedData().getGlobalData().getEctoCharges() * 5;
final Item tokens = new Item(4278, amount);
if (!player.getInventory().hasSpaceFor(tokens)) {
player("Sorry, I don't have enough inventory space.");
stage++;
break;
}
stage++;
player.getInventory().add(tokens);
player.getSavedData().getGlobalData().setEctoCharges(0);
npc("Certainly, mortal. Here's " + (amount) + " ectotokens.");
break;
case 81:
end();
break;
}
return true;
}
@Override
public int[] getIds() {
return new int[] { 1686 };
}
}

View file

@ -0,0 +1,145 @@
package plugin.zone.phasmatys;
import org.crandor.game.content.dialogue.DialoguePlugin;
import org.crandor.game.node.entity.player.Player;
/**
* Handles the ghost inkeeper dialogue.
* @author Vexia
*/
public class GhostInkeeperDialogue extends DialoguePlugin {
/**
* Constructs a new {@code GhostInkeeperDialogue} {@code Object}.
* @param player the player.
*/
public GhostInkeeperDialogue(final Player player) {
super(player);
}
/**
* Constructs a new {@code GhostInkeeperDialogue} {@code Object}.
*/
public GhostInkeeperDialogue() {
/**
* empty.
*/
}
@Override
public DialoguePlugin newInstance(Player player) {
return new GhostInkeeperDialogue(player);
}
@Override
public boolean open(Object... args) {
if (PhasmatysZone.hasAmulet(player)) {
player("Hello there!");
} else {
npc("Woooo wooo wooooo woooo");
stage = 10;
}
return true;
}
@Override
public boolean handle(int interfaceId, int buttonId) {
switch (stage) {
case 0:
npc("Greetings, traveller. Welcome to 'The Green Ghost'", "Tavern. What can I do you for?");
stage++;
break;
case 1:
options("Can I buy a beer?", "Can I hear some gossip?", "What happened to the folk of this town?", "Do you have any jobs I can do?", "Nothing, thanks.");
stage++;
break;
case 2:
switch (buttonId) {
case 1:
player("Can I buy a beer?");
stage = 3;
break;
case 2:
player("Can I hear some gossip?");
stage = 20;
break;
case 3:
player("What happened to the folk of this town?");
stage = 30;
break;
case 4:
player("Do you have any jobs I can do?");
stage = 40;
break;
case 5:
player("Nothing, thanks.");
stage = 50;
break;
}
break;
case 3:
npc("Sorry, but our pumps dried up over half a century", "ago. We of this village do not have much of a thirst", "these days.");
stage++;
break;
case 4:
end();
break;
case 20:
npc("I suppose, as long as you keep it to yourself...");
stage++;
break;
case 21:
npc("You see Gravingas out there in the marketplace? He", "speaks for the silent majoirty of Port Phasmatys, for", "those of us who would prefer to pass over into the next", "world.");
stage++;
break;
case 22:
npc("But old Gravingas is far too obvious in his methods.", "Now Velorina, she's a ghost of a different colour", "altogether. If you feel like helping our cause at all, go", "speak to Velorina.");
stage++;
break;
case 23:
end();
break;
case 30:
npc("That's a long story, my friend, but you look like you", "have the time...");
stage++;
break;
case 31:
player("Nope, you are right. I am very busy!");// .. I dont want
// to do this
// dialogue.
stage++;
break;
case 32:
end();
break;
case 40:
npc("Yes, actually, I do. We have a very famous Master", "Bowman named Robin staying with us at the moment.", "Could you take him some clean bed linen for me?");
stage++;
break;
case 41:
npc("No, I didn't mean a job like that.");
stage++;
break;
case 42:
end();
break;
case 50:
end();
break;
case 10:
interpreter.sendDialogue("You cannot understand the ghost.");
stage++;
break;
case 11:
end();
break;
}
return true;
}
@Override
public int[] getIds() {
return new int[] { 1700 };
}
}

View file

@ -0,0 +1,83 @@
package plugin.zone.phasmatys;
import org.crandor.game.content.dialogue.DialoguePlugin;
import org.crandor.game.content.dialogue.FacialExpression;
import org.crandor.game.node.entity.npc.NPC;
import org.crandor.game.node.entity.player.Player;
/**
* Represents the ghost sailor dialogue plugin.
* @author 'Vexia
* @version 1.0
*/
public final class GhostSailorDialogue extends DialoguePlugin {
/**
* Constructs a new {@code GhostSailorDialogue} {@code Object}.
*/
public GhostSailorDialogue() {
/**
* empty.
*/
}
/**
* Constructs a new {@code GhostSailorDialogue} {@code Object}.
* @param player the player.
*/
public GhostSailorDialogue(Player player) {
super(player);
}
@Override
public DialoguePlugin newInstance(Player player) {
return new GhostSailorDialogue(player);
}
@Override
public boolean open(Object... args) {
npc = (NPC) args[0];
if (PhasmatysZone.hasAmulet(player)) {
player("Hi there. Why do you still bother having ships here? I", "mean - you're dead, what use are they to you?");
stage = 10;
} else {
interpreter.sendDialogues(npc, FacialExpression.NORMAL, "Woooo wooo wooooo woooo");
stage = 0;
}
return true;
}
@Override
public boolean handle(int interfaceId, int buttonId) {
switch (stage) {
case 0:
interpreter.sendDialogue("You cannot understand the ghost.");
stage = 1;
break;
case 1:
end();
break;
case 10:
npc("We keep ships because we still need trade in", "Phasmatys. Every trader that comes to Phastmatys is", "made to worship the Ectofuntus, so that the Ectopower", "doesn't run out.");
stage++;
break;
case 11:
player("So, without traders to worship in the Temple you're", "history right?");
stage++;
break;
case 12:
npc("Aye, matey.");
stage++;
break;
case 13:
end();
break;
}
return true;
}
@Override
public int[] getIds() {
return new int[] { 1703, 1704 };
}
}

View file

@ -0,0 +1,73 @@
package plugin.zone.phasmatys;
import org.crandor.game.content.dialogue.DialoguePlugin;
import org.crandor.game.node.entity.player.Player;
import org.crandor.tools.RandomFunction;
/**
* Handles the ghost villager dialogue.
* @author Vexia
*/
public final class GhostVillagerDialogue extends DialoguePlugin {
/**
* Constructs a new {@code GhostVillagerDialogue} {@code Object}.
*/
public GhostVillagerDialogue() {
/**
* empty.
*/
}
/**
* Constructs a new {@code GhostVillagerDialogue} {@code Object}.
* @param player the player.
*/
public GhostVillagerDialogue(Player player) {
super(player);
}
@Override
public DialoguePlugin newInstance(Player player) {
return new GhostVillagerDialogue(player);
}
@Override
public boolean open(Object... args) {
if (PhasmatysZone.hasAmulet(player)) {
final int random = RandomFunction.random(10);
switch (random) {
default:
npc("What do you want, mortal?");
break;
}
} else {
npc("Woooo wooo wooooo woooo");
stage = 10;
}
return true;
}
@Override
public boolean handle(int interfaceId, int buttonId) {
switch (stage) {
case 0:
end();
break;
case 10:
interpreter.sendDialogue("You cannot understand the ghost.");
stage++;
break;
case 11:
end();
break;
}
return true;
}
@Override
public int[] getIds() {
return new int[] { 1697 };
}
}

View file

@ -0,0 +1,134 @@
package plugin.zone.phasmatys;
import org.crandor.game.content.dialogue.DialoguePlugin;
import org.crandor.game.node.entity.npc.AbstractNPC;
import org.crandor.game.node.entity.player.Player;
import org.crandor.game.world.map.Location;
import org.crandor.plugin.Plugin;
import org.crandor.plugin.PluginManager;
import org.crandor.tools.RandomFunction;
/**
* Handles the gravingas npc.
* @author Vexia
*/
public final class GravingasNPC extends AbstractNPC {
/**
* The force chats.
*/
private static final String[] CHATS = new String[] { "Down with Necrovaus!!", "Rise up my fellow ghosts, and we shall be victorious!", "Power to the Ghosts!!", "Rise together, Ghosts without a cause!!", "United we conquer - divided we fall!!", "We shall overcome!!", "Let Necrovarus know we want out!!", "Don't stay silent - victory in numbers!!" };
/**
* Constructs a new {@code GravingasNPC} {@code Object}.
* @param id the id.
* @param location the location.
*/
public GravingasNPC(int id, Location location) {
super(id, location);
}
/**
* Constructs a new {@code GravingasNPC} {@code Object}.
*/
public GravingasNPC() {
super(0, null);
}
@Override
public void handleTickActions() {
super.handleTickActions();
if (RandomFunction.random(45) == 5) {
sendChat(CHATS[RandomFunction.random(CHATS.length)]);
}
}
@Override
public AbstractNPC construct(int id, Location location, Object... objects) {
return new GravingasNPC(id, location);
}
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
PluginManager.definePlugin(new GravingasDialogue());
return super.newInstance(arg);
}
@Override
public int[] getIds() {
return new int[] { 1685 };
}
/**
* Handles the gravingas dialogue.
* @author Vexia
*/
public final class GravingasDialogue extends DialoguePlugin {
/**
* Constructs a new {@code GravingasDialogue} {@code Object}.
* @param player the player.
*/
public GravingasDialogue(final Player player) {
super(player);
}
/**
* Constructs a new {@code GravingasDialogue} {@code Object}.
*/
public GravingasDialogue() {
/**
* empty.
*/
}
@Override
public DialoguePlugin newInstance(Player player) {
return new GravingasDialogue(player);
}
@Override
public boolean open(Object... args) {
if (PhasmatysZone.hasAmulet(player)) {
npc("Will you join with me and protect against the evil ban", "of Nercrovarus and his disciples?");
stage = 0;
} else {
npc("Woooo wooo wooooo woooo");
stage = 10;
}
return true;
}
@Override
public boolean handle(int interfaceId, int buttonId) {
switch (stage) {
case 0:
player("I'm sorry, I don't really think I should get involved.");
stage++;
break;
case 1:
npc("Ah, the youth of today - so apathetic to politics.");
stage++;
break;
case 2:
end();
break;
case 10:
interpreter.sendDialogue("You cannot understand the ghost.");
stage = 11;
break;
case 11:
end();
break;
}
return true;
}
@Override
public int[] getIds() {
return GravingasNPC.this.getIds();
}
}
}

View file

@ -0,0 +1,89 @@
package plugin.zone.phasmatys;
import org.crandor.game.content.dialogue.DialoguePlugin;
import org.crandor.game.node.entity.player.Player;
/**
* Handles the dialogue used for necrovarus.
* @author Vexia
*/
public final class NecrovarusDialogue extends DialoguePlugin {
/**
* Constructs a new {@code NecrovarusDialogue} {@code Object}.
*/
public NecrovarusDialogue() {
/**
* empty.
*/
}
/**
* Constructs a new {@code NecrovarusDialogue} {@code Object}.
* @param player the player.
*/
public NecrovarusDialogue(Player player) {
super(player);
}
@Override
public DialoguePlugin newInstance(Player player) {
return new NecrovarusDialogue(player);
}
@Override
public boolean open(Object... args) {
options("What is this place?", "What happened to everyone here?", "How do I get into the town?");
return true;
}
@Override
public boolean handle(int interfaceId, int buttonId) {
switch (stage) {
case 0:
switch (buttonId) {
case 1:
player("What is this place?");
stage = 10;
break;
case 2:
player("What happened to everyone here?");
stage = 20;
break;
case 3:
player("How do I get into the town?");
stage = 30;
break;
}
break;
case 10:
npc("Speak to me again and I will rend the soul from your", "flesh.");
stage++;
break;
case 11:
end();
break;
case 20:
npc("You dare to speak to me??? Have you lost your", "wits????");
stage++;
break;
case 21:
end();
break;
case 30:
npc("I do not answer questions, mortal fool!");
stage++;
break;
case 31:
end();
break;
}
return true;
}
@Override
public int[] getIds() {
return new int[] { 1684 };
}
}

View file

@ -0,0 +1,327 @@
package plugin.zone.phasmatys;
import org.crandor.game.content.global.Bones;
import org.crandor.game.content.global.action.ClimbActionHandler;
import org.crandor.game.content.skill.Skills;
import org.crandor.game.content.skill.member.agility.AgilityHandler;
import org.crandor.game.interaction.NodeUsageEvent;
import org.crandor.game.interaction.Option;
import org.crandor.game.interaction.UseWithHandler;
import org.crandor.game.node.Node;
import org.crandor.game.node.entity.Entity;
import org.crandor.game.node.entity.npc.NPC;
import org.crandor.game.node.entity.player.Player;
import org.crandor.game.node.item.Item;
import org.crandor.game.node.object.GameObject;
import org.crandor.game.node.object.ObjectBuilder;
import org.crandor.game.world.map.Direction;
import org.crandor.game.world.map.Location;
import org.crandor.game.world.map.zone.MapZone;
import org.crandor.game.world.map.zone.ZoneBorders;
import org.crandor.game.world.map.zone.ZoneBuilder;
import org.crandor.game.world.update.flag.context.Animation;
import org.crandor.plugin.Plugin;
import org.crandor.plugin.InitializablePlugin;
import org.crandor.plugin.PluginManager;
/**
* Handles the phasmatyz zone area.
* @author Vexia
*/
@InitializablePlugin
public final class PhasmatysZone extends MapZone implements Plugin<Object> {
/**
* Constructs a new {@code PhasmatysZone} {@code Object}.
*/
public PhasmatysZone() {
super("Port phasmatys", true);
}
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ZoneBuilder.configure(this);
PluginManager.definePlugin(new GravingasNPC());
PluginManager.definePlugin(new BoneLoaderHandler());
PluginManager.definePlugin(new NecrovarusDialogue());
PluginManager.definePlugin(new GhostSailorDialogue());
PluginManager.definePlugin(new EctoplasmFillPlugin());
PluginManager.definePlugin(new GhostDiscipleDialogue());
PluginManager.definePlugin(new GhostVillagerDialogue());
PluginManager.definePlugin(new GhostInkeeperDialogue());
return this;
}
@Override
public boolean interact(Entity e, Node target, Option option) {
if (e.isPlayer()) {
Player player = e.asPlayer();
if (target instanceof NPC) {
NPC npc = (NPC) target;
if ((npc.getName().toLowerCase().contains("ghost") || npc.getName().equalsIgnoreCase("velorina") || npc.getName().contains("husband")) && !hasAmulet(player)) {
player.getDialogueInterpreter().open("ghosty dialogue", target);
return true;
}
}
switch (target.getId()) {
case 5259:
handleEnergyBarrier(player, (GameObject) target);
return true;
case 5267:
player.animate(Animation.create(536));
player.getPacketDispatch().sendMessage("The trapdoor opens...");
ObjectBuilder.replace((GameObject) target, ((GameObject) target).transform(5268));
return true;
case 5268:
if (option.getName().equals("Close")) {
player.animate(Animation.create(535));
player.getPacketDispatch().sendMessage("You close the trapdoor.");
ObjectBuilder.replace((GameObject) target, ((GameObject) target).transform(5267));
} else {
player.getPacketDispatch().sendMessage("You climb down through the trapdoor...");
player.getProperties().setTeleportLocation(Location.create(3669, 9888, 3));
}
return true;
case 9308:
if (player.getSkills().getStaticLevel(Skills.AGILITY) < 58) {
player.sendMessage("You need an agility level of at least 58 to climb down this wall.");
return true;
}
player.getProperties().setTeleportLocation(Location.create(3671, 9888, 2));
return true;
case 9307:
if (player.getSkills().getStaticLevel(Skills.AGILITY) < 58) {
player.sendMessage("You need an agility level of at least 58 to climb up this wall.");
return true;
}
player.getProperties().setTeleportLocation(Location.create(3670, 9888, 3));
return true;
case 5264:
ClimbActionHandler.climb(player, Animation.create(828), Location.create(3654, 3519, 0));
return true;
case 5244:
player.getDialogueInterpreter().open(1686, null, true);
return true;
case 11163:
case 11164:
GameObject obj = (GameObject) target;
switch (option.getName().toLowerCase()) {
case "wind":
wind(player, obj);
return true;
case "empty":
empty(player, obj);
return true;
case "status":
checkStatus(player, obj);
return true;
}
break;
case 5282:
worship(player);
return true;
}
}
return super.interact(e, target, option);
}
/**
* Checks if the player has the amulet equipped.
* @param player the player.
* @return {@code True} if so.
*/
public static boolean hasAmulet(Player player) {
return player.getEquipment().contains(552, 1);
}
/**
* Checks the status of a grinder.
* @param player the player.
* @param object the object.
*/
private void checkStatus(Player player, GameObject object) {
String status = "The grinder is empty.";
if (hasBones(player, object, true)) {
status = "There are some bones in the hopper.";
} else if (hasBones(player, object, false)) {
status = "There are some crushed bones in the bin.";
}
player.sendMessage(status);
}
/**
* Emptys the grinder.
* @param player the player.
* @param object the object.
*/
private void empty(Player player, GameObject object) {
if (hasBones(player, object, true)) {
player.sendMessage("You need to wind the handle to grind the bones.");
return;
}
if (!hasBones(player, object, false)) {
player.sendMessage("The grinder is already empty.");
return;
}
if (!player.getInventory().contains(1931, 1)) {
player.sendMessage("You need an empty pot to put the crushed bones into.");
return;
}
final Bones bone = Bones.forConfigValue(player.getConfigManager().get(408), false);
player.lock(2);
player.animate(Animation.create(1650));
player.getConfigManager().set(408, 0, true);
player.sendMessage("You fill a pot with crushed bones.");
player.getInventory().replace(bone.getBoneMeal(), player.getInventory().getSlot(new Item(1931)));
}
/**
* Windws the grinder.
* @param player the player.
* @param object the object.
*/
private void wind(Player player, GameObject object) {
final Bones bone = Bones.forConfigValue(player.getConfigManager().get(408), true);
player.lock(3);
player.animate(Animation.create(1648));
player.sendMessage("You wind the grinder handle.");
if (hasBones(player, object, true)) {
player.getConfigManager().set(408, bone.getConfigValue(false), true);
player.sendMessage("Some crushed bones pour into the bin.", 3);
}
}
/**
* Checks if bones are in the hopper.
* @param player the player.
* @param if in the hopper or in the bin.
* @param object the object.
* @return {@code True} if so.
*/
public static boolean hasBones(Player player, GameObject object, boolean inHopper) {
int value = player.getConfigManager().get(408);
for (Bones bone : Bones.values()) {
if (bone.getConfigValue(inHopper) == value) {
return true;
}
}
return false;
}
/**
* Worships the ectofuntus.
* @param player the player.
*/
private void worship(Player player) {
Bones bone = null;
for (Item i : player.getInventory().toArray()) {
if (i == null) {
continue;
}
Bones b = Bones.forBoneMeal(i.getId());
if (b != null) {
bone = b;
break;
}
}
if (!player.getInventory().contains(4286, 1) && bone == null) {
player.getDialogueInterpreter().sendDialogue("You don't have any ectoplasm or crushed bones to put into the", "Ectofuntus.");
return;
}
if (bone == null) {
player.getDialogueInterpreter().sendDialogue("You need a pot of crushed bones to put into the Ectofuntus.");
return;
}
if (!player.getInventory().contains(4286, 1)) {
player.getDialogueInterpreter().sendDialogue("You need ectoplasm to put into the Ectofuntus.");
return;
}
if (player.getInventory().remove(bone.getBoneMeal(), new Item(4286, 1))) {
player.lock(5);
player.animate(Animation.create(1651));
player.getInventory().add(new Item(1925), new Item(1931));
player.getSkills().addExperience(Skills.PRAYER, bone.getExperience() * 4, true);
player.sendMessage("You put some ectoplasm and bonemeal into the Ectofuntus, and worship it.");
player.getSavedData().getGlobalData().setEctoCharges(player.getSavedData().getGlobalData().getEctoCharges() + 1);
}
}
/**
* Handles the passing of the energy barrier.
* @param player the player.
* @param object the object.
*/
private void handleEnergyBarrier(Player player, GameObject object) {
boolean force = object.getLocation().equals(3659, 3508, 0) && player.getLocation().getY() < 3508 || object.getLocation().equals(3652, 3485, 0) && player.getLocation().getX() > 3652;
if (!force && !player.getInventory().contains(4278, 2)) {
player.getDialogueInterpreter().open(1706);
return;
}
if (force || player.getInventory().remove(new Item(4278, 2))) {
final Direction direction = Direction.getLogicalDirection(player.getLocation(), object.getLocation());
Location end = player.getLocation().transform(direction, 2);
if (player.getLocation().getY() >= 3508) {
end = object.getLocation().transform(0, -2, 0);
}
if (object.getLocation().equals(new Location(3652, 3485, 0))) {
end = object.getLocation().transform(player.getLocation().getX() >= 3653 ? -1 : 2, 0, 0);
}
AgilityHandler.walk(player, -1, player.getLocation(), end, null, 0.0, null);
}
}
/**
* Handles the bone loader.
* @author Vexia
*/
public static final class BoneLoaderHandler extends UseWithHandler {
/**
* Constructs a new {@code BoneLoaderHandler} {@code Object}.
*/
public BoneLoaderHandler() {
super(Bones.getArray());
}
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
addHandler(11162, OBJECT_TYPE, this);
return this;
}
@Override
public boolean handle(NodeUsageEvent event) {
final Player player = event.getPlayer();
final GameObject object = (GameObject) event.getUsedWith();
final Bones bone = Bones.forId(event.getUsedItem().getId());
if (hasBones(player, object, true)) {
player.sendMessage("There are already some bones in the grinder's hopper.");
return true;
} else if (hasBones(player, object, false)) {
player.sendMessage("You need to empty the grinder's bin before you put more bones in it.");
return true;
}
if (player.getInventory().remove(event.getUsedItem())) {
player.lock(2);
player.animate(Animation.create(1649));
player.getConfigManager().set(408, bone.getConfigValue(true), true);
player.sendMessage("You put some bones in the grinder's hopper.", 1);
}
return true;
}
}
@Override
public Object fireEvent(String identifier, Object... args) {
return null;
}
@Override
public void configure() {
register(new ZoneBorders(3583, 3456, 3701, 3552));
register(new ZoneBorders(3667, 9873, 3699, 9914));
}
}

View file

@ -0,0 +1,246 @@
package plugin.zone.rellekka;
import org.crandor.game.component.Component;
import org.crandor.game.content.dialogue.DialoguePlugin;
import org.crandor.game.node.entity.npc.NPC;
import org.crandor.game.node.entity.player.Player;
import org.crandor.game.node.item.Item;
import org.crandor.game.system.task.LocationLogoutTask;
import org.crandor.game.system.task.LogoutTask;
import org.crandor.game.system.task.Pulse;
import org.crandor.game.world.GameWorld;
import org.crandor.game.world.map.Location;
/**
* Handles the jarvald dialogue.
* @author Vexia
*/
public final class JarvaldDialogue extends DialoguePlugin {
/**
* Constructs a new {@code JarvaldDialogue} {@code Object}.
*/
public JarvaldDialogue() {
/**
* empty.
*/
}
/**
* Constructs a new {@code JarvaldDialogue} {@code Object}.
* @param player the player.
*/
public JarvaldDialogue(Player player) {
super(player);
}
@Override
public DialoguePlugin newInstance(Player player) {
return new JarvaldDialogue(player);
}
@Override
public boolean open(Object... args) {
npc = (NPC) args[0];
if (args.length > 1) {
handleTravelStage();
return true;
}
if (npc.getId() == 2438) {
npc("Ah, you live yet, outerlander!");
stage = 37;
return true;
}
npc("What do you want from me outerlander?", "It is our policy not to associate with those not of our", "tribe.");
return true;
}
@Override
public boolean handle(int interfaceId, int buttonId) {
switch (stage) {
case 0:
options("Where is your chieftain?", "What Jarvald is doing.", "Nothing");
stage++;
break;
case 1:
switch (buttonId) {
case 1:
player("Where is your chieftain?", "I find it highly discriminatory to refuse to talk to", "someone on the grounds that they are not part of your", "tribe.");
stage = 10;
break;
case 2:
player("So what are you doing here?");
stage = 20;
break;
case 3:
end();
break;
}
break;
case 10:
npc("I don't rightly understand your speech outerlander, but", "my loyality is with Chieftain Brundt.");
stage++;
break;
case 11:
npc("He resides in our longhall; it is the large building over", "there, you should speak to him for he speaks for us all.");
stage++;
break;
case 12:
end();
break;
case 20:
handleTravelStage();
break;
case 21:
player("Hey, scary barbarian type guy, think I can join you on", "this expedition?");
stage++;
break;
case 22:
npc("An outerlander join us on a honoured hunt???");
stage++;
break;
case 23:
npc("Well.....", "I gues...", "I might be able to allow you to join us, although it is a", "breach of many of our customs...");
stage++;
break;
case 24:
player("Oh, pleeeeeeease?", "I really LOVE killing stuff!");
stage++;
break;
case 25:
npc("Well...", "I remain unconvinced that it would be wise to allow an", "outerlander to join us in such dangerous battle, but", "your ethusiasm seems genuine enough...");
stage++;
break;
case 26:
npc("I will allow you to escort us, but you must pay me a", "sum of money first.");
stage++;
break;
case 27:
player("What?", "That's outrageous, why charge me money?", "And, uh, how much does it cost me?");
stage++;
break;
case 28:
npc("Ah, the outerlander have stolen from my people for", "many years, in this way you can help my community", "with a small amount of money...");
stage++;
break;
case 29:
npc("Let us say...", "1000 coins.", "Payable in advance, of course.");
stage++;
break;
case 30:
npc("For this I will take you to Waterbirth Island on my", "boat, and will bring you back here when you have had", "your fill of the hunt.", "Assuming you are still alive to wish to leave, of course.");
stage++;
break;
case 31:
player.getConfigManager().set(520, 1 << 13, true);
end();
break;
case 32:
options("YES", "NO");
stage++;
break;
case 33:
switch (buttonId) {
case 1:
if (!player.getInventory().contains(995, 1000)) {
player("Sorry, I don't have enough coins.");
stage = 35;
break;
}
if (player.getInventory().remove(new Item(995, 1000))) {
sail(player, true);
}
end();
break;
case 2:
player("No, actually I have some stuff to do here first.");
stage = 34;
break;
}
break;
case 34:
npc("As you wish.", "Come and see me when your bloodlust needs sating.");
stage++;
break;
case 35:
end();
break;
case 36:
switch (buttonId) {
case 1:
npc("Then let us away;", "There will be death to bring here another day!");
stage = 39;
break;
case 2:
end();
break;
}
break;
case 37:
npc("Have you had your fill of the hunt and wish to return,", "or are you still feeling the joy of the cull?");
stage++;
break;
case 38:
interpreter.sendOptions("Leave island?", "YES", "NO");
stage = 36;
break;
case 39:
end();
sail(player, false);
break;
}
return true;
}
/**
* Sails the player to and from waterbirth.
* @param player the player.
*/
public void sail(final Player player, final boolean to) {
player.lock();
player.getInterfaceManager().open(new Component(224));
player.addExtension(LogoutTask.class, new LocationLogoutTask(5, to ? Location.create(2544, 3759, 0) : Location.create(2620, 3685, 0)));
GameWorld.submit(new Pulse(1, player) {
int count;
@Override
public boolean pulse() {
switch (++count) {
case 5:
player.unlock();
player.getInterfaceManager().close();
player.getProperties().setTeleportLocation(to ? Location.create(2544, 3759, 0) : Location.create(2620, 3685, 0));
player.getDialogueInterpreter().close();
player.getDialogueInterpreter().sendDialogue("The ship arrives at " + (to ? "Waterbirth Island" : "Rellekka") + ".");
return true;
}
return false;
}
});
}
/**
* Handles the travel stage.
*/
private void handleTravelStage() {
if (npc.getId() == 2438) {
interpreter.sendOptions("Leave island?", "YES", "NO");
stage = 36;
return;
}
if (player.getConfigManager().get(520) == 0) {
npc("This should not concern you, outerlander.", "I am awaiting other Fremenniks to join me on an", "expedition to Waterbirth Island.");
stage = 21;
} else {
npc("So do you have the 1000 coins for my service, and are", "you ready to leave?");
stage = 32;
}
}
@Override
public int[] getIds() {
return new int[] { 2435, 2436, 2437, 2438 };
}
}

View file

@ -0,0 +1,46 @@
package plugin.zone.rellekka;
import org.crandor.cache.def.impl.ObjectDefinition;
import org.crandor.game.content.global.action.DoorActionHandler;
import org.crandor.game.interaction.OptionHandler;
import org.crandor.game.node.Node;
import org.crandor.game.node.entity.Entity;
import org.crandor.game.node.entity.player.Player;
import org.crandor.game.world.map.Location;
import org.crandor.plugin.InitializablePlugin;
import org.crandor.plugin.Plugin;
/**
* Handles the light house plugin.
* @author Vexia
*/
@InitializablePlugin
public class LightHousePlugin extends OptionHandler {
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ObjectDefinition.forId(4577).getConfigurations().put("option:walk-through", this);
ObjectDefinition.forId(4383).getConfigurations().put("option:climb", this);
return this;
}
@Override
public boolean handle(Player player, Node node, String option) {
switch (node.getId()) {
case 4577:
DoorActionHandler.handleDoor(player, node.asObject());
return true;
case 4383:
return false;
}
return true;
}
@Override
public Location getDestination(Node node, Node n) {
if (n.getName().equals("Door")) {
return DoorActionHandler.getDestination((Entity) node, n.asObject());
}
return null;
}
}

View file

@ -0,0 +1,92 @@
package plugin.zone.rellekka;
import org.crandor.game.content.dialogue.DialoguePlugin;
import org.crandor.game.node.entity.npc.NPC;
import org.crandor.game.node.entity.player.Player;
import org.crandor.game.world.map.Location;
/**
* Handles the maria gunnars dialogue.
* @author Vexia
*/
public class MariaGunnarsDialogue extends DialoguePlugin {
/**
* Constructs a new {@code MariaGunnarsDialogue} {@code Object}
*/
public MariaGunnarsDialogue() {
/**
* empty.
*/
}
/**
* Constructs a new {@code MariaGunnarsDialogue} {@code Object}
* @param player the player.
*/
public MariaGunnarsDialogue(Player player) {
super(player);
}
@Override
public DialoguePlugin newInstance(Player player) {
return new MariaGunnarsDialogue(player);
}
@Override
public boolean open(Object... args) {
npc = (NPC) args[0];
npc("Welcome, Talvald. Do you have any questions?");
return true;
}
@Override
public boolean handle(int interfaceId, int buttonId) {
switch (stage) {
case 0:
options("Can you ferry me to " + (npc.getId() == 5508 ? "Neitiznot?" : "Relleka") + "?", "I just stopped to say 'hello'.");
stage++;
break;
case 1:
if (buttonId == 1) {
player("Can you ferry me to " + (npc.getId() == 5508 ? "Neitiznot?" : "Relleka") + "?");
stage++;
} else {
player("I just stopped to say 'hello'.");
stage = 4;
}
break;
case 2:
npc("Let's set sail then.");
stage++;
break;
case 3:
if (npc.getId() == 5508) {
RellekkaZone.sail(player, "Relleka", new Location(2310, 3782, 0));
} else {
RellekkaZone.sail(player, "Neitiznot", new Location(2644, 3710, 0));
}
end();
break;
case 4:
npc("Thanks!");
stage++;
break;
case 5:
player("I may be back later.");
stage++;
break;
case 6:
end();
npc.sendChat("Bye");
break;
}
return true;
}
@Override
public int[] getIds() {
return new int[] { 5508, 5507 };
}
}

View file

@ -0,0 +1,215 @@
package plugin.zone.rellekka;
import org.crandor.cache.def.impl.NPCDefinition;
import org.crandor.cache.def.impl.ObjectDefinition;
import org.crandor.game.component.Component;
import org.crandor.game.content.skill.member.agility.AgilityHandler;
import org.crandor.game.interaction.Option;
import org.crandor.game.interaction.OptionHandler;
import org.crandor.game.node.Node;
import org.crandor.game.node.entity.Entity;
import org.crandor.game.node.entity.impl.ForceMovement;
import org.crandor.game.node.entity.npc.NPC;
import org.crandor.game.node.entity.player.Player;
import org.crandor.game.node.object.GameObject;
import org.crandor.game.system.task.LocationLogoutTask;
import org.crandor.game.system.task.LogoutTask;
import org.crandor.game.system.task.Pulse;
import org.crandor.game.world.GameWorld;
import org.crandor.game.world.map.Location;
import org.crandor.game.world.map.zone.MapZone;
import org.crandor.game.world.map.zone.ZoneBorders;
import org.crandor.game.world.map.zone.ZoneBuilder;
import org.crandor.game.world.update.flag.context.Animation;
import org.crandor.plugin.Plugin;
import org.crandor.plugin.InitializablePlugin;
import org.crandor.plugin.PluginManager;
/**
* Handles the rellekka zone.
* @author Vexia
*/
@InitializablePlugin
public final class RellekkaZone extends MapZone implements Plugin<Object> {
/**
* Constructs a new {@code RellekkaZone} {@code Object}.
*/
public RellekkaZone() {
super("rellekka", true);
}
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ZoneBuilder.configure(this);
PluginManager.definePlugin(new SailorDialogue());
PluginManager.definePlugin(new JarvaldDialogue());
PluginManager.definePlugin(new RellekaOptionHandler(), new MariaGunnarsDialogue());
PluginManager.definePlugin(new OptionHandler() {
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
NPCDefinition.forId(5507).getConfigurations().put("option:ferry-rellekka", this);
return this;
}
@Override
public boolean handle(Player player, Node node, String option) {
sail(player, "Relleka", new Location(2644, 3710, 0));
return true;
}
});
return this;
}
@Override
public boolean interact(Entity e, Node target, Option option) {
if (e instanceof Player) {
final Player player = (Player) e;
switch (target.getId()) {
case 4306:
case 4310:
case 4309:
case 4304:
case 4308:
player.sendMessage("Only Fremenniks may use this " + target.getName().toLowerCase() + ".");
return true;
/*
* case 1301: player.sendMessage("Only Fremenniks may " +
* (option.equals("Trade") ? "buy clothes here" :
* "change their shoes here") + "."); return true;
*/
case 4165:
player.getDialogueInterpreter().open(1288);
return true;
case 4166:
player.sendMessage("This door is locked tightly shut.");
return true;
case 1288:
player.getDialogueInterpreter().sendDialogues((NPC) target, null, "I have no interest in talking to you just now", "outerlander.");
return true;
case 34286:
player.getDialogueInterpreter().sendDialogues(1289, null, "Outerlander... do not test my patience. I do not take", "kindly to people wandering in here and acting as though", "they own the place.");
return true;
case 4148:
player.getDialogueInterpreter().sendDialogues(1278, null, "Hey, outerlander. You can't go through there. Talent", "only, backstage.");
return true;
case 100:
player.getDialogueInterpreter().sendDialogue("You try to open the trapdoor but it won't budge! It looks like the", "trapdoor can only be opened from the other side.");
return true;
case 4158:
player.getDialogueInterpreter().sendDialogues(1283, null, "Hey! Outerlander! Do you normally just barge into", "someones home and wander around as you please?");
return true;
case 2435:
case 2436:
case 2437:
case 2438:
if (option.getName().equals("Travel")) {
player.getDialogueInterpreter().open(target.getId(), target, true);
return true;
}
break;
case 5508:
if (option.getName().equals("Ferry-Neitiznot")) {
sail(player, "Neitiznot", new Location(2310, 3782, 0));
}
return true;
}
}
return super.interact(e, target, option);
}
@Override
public Object fireEvent(String identifier, Object... args) {
return null;
}
@Override
public void configure() {
register(new ZoneBorders(2602, 3639, 2739, 3741));
}
/**
* Sails a player using the relleka ships.
* @param player the player.
* @param name the name.
* @param destination the destination.
*/
public static void sail(final Player player, final String name, final Location destination) {
player.lock();
player.getInterfaceManager().open(new Component(224));
player.addExtension(LogoutTask.class, new LocationLogoutTask(5, destination));
GameWorld.submit(new Pulse(1, player) {
int count;
@Override
public boolean pulse() {
switch (++count) {
case 5:
player.unlock();
player.getInterfaceManager().close();
player.getProperties().setTeleportLocation(destination);
player.getDialogueInterpreter().sendDialogue("The ship arrives at " + name + ".");
return true;
}
return false;
}
});
}
/**
* Handles options related to relleka.
* @author Vexia
*/
public static final class RellekaOptionHandler extends OptionHandler {
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ObjectDefinition.forId(4616).getConfigurations().put("option:cross", this);
ObjectDefinition.forId(4615).getConfigurations().put("option:cross", this);
ObjectDefinition.forId(5847).getConfigurations().put("option:climb-over", this);
return this;
}
@Override
public boolean handle(Player player, Node node, String option) {
switch (option) {
case "cross":
switch (node.getId()) {
case 4616:
case 4615:
crossRellekaBridge(player, (GameObject) node);
break;
}
break;
case "climb-over":
switch (node.getId()) {
case 5847:
AgilityHandler.forceWalk(player, -1, player.getLocation(), player.getLocation().transform(0, player.getLocation().getY() <= 3657 ? 3 : -3, 0), Animation.create(840), 20, 1, null, 0);
break;
}
break;
}
return true;
}
/**
* Crosses the relleka bridge.
* @param player the player.
* @param node the node.
*/
private void crossRellekaBridge(Player player, GameObject node) {
boolean east = node.getId() == 4616;
player.lock(2);
if (player.getLocation().equals(node.getLocation())) {
AgilityHandler.forceWalk(player, -1, player.getLocation(), player.getLocation().transform(east ? -2 : 2, 0, 0), Animation.create(1115), 20, 1.0, null, 1);
return;
}
AgilityHandler.forceWalk(player, -1, player.getLocation(), player.getLocation().transform(east ? -1 : 1, 0, 0), ForceMovement.WALK_ANIMATION, 10, 0.0, null);
AgilityHandler.forceWalk(player, -1, player.getLocation().transform(east ? -1 : 1, 0, 0), player.getLocation().transform(east ? -3 : 3, 0, 0), Animation.create(1115), 20, 1.0, null, 1);
}
}
}

View file

@ -0,0 +1,73 @@
package plugin.zone.rellekka;
import org.crandor.game.content.dialogue.DialoguePlugin;
import org.crandor.game.node.entity.npc.NPC;
import org.crandor.game.node.entity.player.Player;
import org.crandor.game.world.map.Location;
/**
* Handles the sailor dialogue.
* @author Vexia
*/
public final class SailorDialogue extends DialoguePlugin {
/**
* If its the relleka npc.
*/
private boolean rellekaNpc;
/**
* Constructs a new {@Code SailorDialogue} {@Code Object}
*/
public SailorDialogue() {
}
/**
* Constructs a new {@Code SailorDialogue} {@Code Object}
* @param player the player.
*/
public SailorDialogue(Player player) {
super(player);
}
@Override
public DialoguePlugin newInstance(Player player) {
return new SailorDialogue(player);
}
@Override
public boolean open(Object... args) {
npc = (NPC) args[0];
rellekaNpc = npc.getId() == 1385;
player("Hello. Can I get a ride on your ship?");
return true;
}
@Override
public boolean handle(int interfaceId, int buttonId) {
switch (stage) {
case 0:
npc("Hello again, brother " + player.getUsername() + ". If you're ready to jump", "aboard, we're all ready to set sail with the tide!");
stage++;
break;
case 1:
player("Let's go!");
stage++;
break;
case 2:
end();
player.lock();
player.sendMessage("You board the longship...");
RellekkaZone.sail(player, rellekaNpc ? "Miscellania" : "Rellekka", rellekaNpc ? Location.create(2581, 3845, 0) : Location.create(2629, 3693, 0));
break;
}
return true;
}
@Override
public int[] getIds() {
return new int[] { 1385, 1304 };
}
}

View file

@ -0,0 +1,217 @@
package plugin.zone.wbisland;
import java.util.List;
import org.crandor.game.content.global.BossKillCounter;
import org.crandor.game.node.entity.Entity;
import org.crandor.game.node.entity.combat.BattleState;
import org.crandor.game.node.entity.combat.CombatStyle;
import org.crandor.game.node.entity.npc.AbstractNPC;
import org.crandor.game.node.entity.player.Player;
import org.crandor.game.world.map.Location;
import org.crandor.game.world.map.RegionManager;
import org.crandor.tools.RandomFunction;
/**
* Represents a dagannoth king npc.
* @author Vexia
*/
public final class DagannothKingNPC extends AbstractNPC {
/**
* The type of dag.
*/
private DagType type;
/**
* Constructs a new {@Code DagannothKingNPC} {@Code Object}
*/
public DagannothKingNPC() {
super(-1, null);
}
/**
* Constructs a new {@Code DagannothKingNPC} {@Code Object}
* @param id the id.
* @param location the location.
*/
public DagannothKingNPC(int id, Location location) {
super(id, location);
}
@Override
public void init() {
type = DagType.forId(getId());
super.init();
}
@Override
public void checkImpact(BattleState state) {
CombatStyle style = state.getStyle();
if (style == null) {
style = state.getAttacker().getProperties().getCombatPulse().getStyle();
}
if (type.isImmune(style)) {
state.neutralizeHits();
}
}
@Override
public double getLevelMod(Entity entity, Entity victim) {
if (type == DagType.PRIME) {
return 3.5;
}
return 0.0;
}
@Override
public void sendImpact(BattleState state) {
if (state.getEstimatedHit() > type.getMaxHit()) {
state.setEstimatedHit(RandomFunction.random(type.getMaxHit() - 5, type.getMaxHit()));
}
if (type != DagType.REX && RandomFunction.random(5) <= 2) {
List<Player> players = RegionManager.getLocalPlayers(this, 9);
if (players.size() <= 1) {
return;
}
Player newP = players.get(RandomFunction.random(players.size()));
if (newP != null) {
getProperties().getCombatPulse().stop();
getAggressiveHandler().setPauseTicks(2);
attack(newP);
}
}
}
@Override
public AbstractNPC construct(int id, Location location, Object... objects) {
return new DagannothKingNPC(id, location);
}
@Override
public int[] getIds() {
return new int[] { 2881, 2882, 2883 };
}
@Override
public void finalizeDeath(Entity killer) {
super.finalizeDeath(killer);
if (getId() == 2881 || getId() == 2882 || getId() == 2883) {
BossKillCounter.addtoKillcount((Player) killer, this.getId());
}
}
/**
* ß A king type.
* @author Vexia
*/
public enum DagType {
SUPREME(2881, CombatStyle.RANGE, CombatStyle.MELEE, CombatStyle.MAGIC, 30), PRIME(2882, CombatStyle.MAGIC, CombatStyle.RANGE, CombatStyle.MELEE, 61), REX(2883, CombatStyle.MELEE, CombatStyle.MAGIC, CombatStyle.RANGE, 28);
/**
* The npc id.
*/
private final int id;
/**
* The combat style.
*/
private final CombatStyle style;
/**
* The style he is weak to.
*/
private final CombatStyle weakStyle;
/**
* The style he is immunned to.
*/
private final CombatStyle immuneStyle;
/**
* The max hit.
*/
private final int maxHit;
/**
* Constructs a new {@Code DagType} {@Code Object}
* @param id the id.
* @param style the style.
* @param weakStyle the weak style.
* @parmam immuneStyle the style.
* @param maxHit the max hit.
*/
private DagType(int id, CombatStyle style, CombatStyle weakStyle, CombatStyle immuneStyle, int maxHit) {
this.id = id;
this.style = style;
this.weakStyle = weakStyle;
this.immuneStyle = immuneStyle;
this.maxHit = maxHit;
}
/**
* Gets the maxHit.
* @return the maxHit
*/
public int getMaxHit() {
return maxHit;
}
/**
* Gets a dag type.
* @param id the id.
* @return the type.
*/
public static DagType forId(int id) {
for (DagType type : values()) {
if (type.getId() == id) {
return type;
}
}
return null;
}
/**
* Checks if the dag is immune to a style.
* @param style the style.
* @return {@code True} if so.
*/
public boolean isImmune(CombatStyle style) {
return style == immuneStyle || style == this.style;
}
/**
* Gets the id.
* @return the id
*/
public int getId() {
return id;
}
/**
* Gets the style.
* @return the style
*/
public CombatStyle getStyle() {
return style;
}
/**
* Gets the immuneStyle.
* @return the immuneStyle
*/
public CombatStyle getImmuneStyle() {
return immuneStyle;
}
/**
* Gets the weakStyle.
* @return the weakStyle
*/
public CombatStyle getWeakStyle() {
return weakStyle;
}
}
}

View file

@ -0,0 +1,158 @@
package plugin.zone.wbisland;
import org.crandor.game.node.entity.Entity;
import org.crandor.game.node.entity.combat.BattleState;
import org.crandor.game.node.entity.combat.CombatSpell;
import org.crandor.game.node.entity.combat.CombatStyle;
import org.crandor.game.node.entity.combat.CombatSwingHandler;
import org.crandor.game.node.entity.combat.InteractionType;
import org.crandor.game.node.entity.combat.equipment.SwitchAttack;
import org.crandor.game.node.entity.combat.handlers.MultiSwingHandler;
import org.crandor.game.node.entity.npc.AbstractNPC;
import org.crandor.game.node.entity.player.link.SpellBookManager.SpellBook;
import org.crandor.game.node.entity.state.EntityState;
import org.crandor.game.world.map.Location;
import org.crandor.tools.RandomFunction;
/**
* Represents a spinolyp npc.
* @author Vexia
*/
public final class SpinolypNPC extends AbstractNPC {
/**
* The swing handler.
*/
private static final CombatSwingHandler SWING_HANDLER = new SpinolpySwingHandler();
/**
* Constructs a new {@Code SpinolypNPC} {@Code Object}
*/
public SpinolypNPC() {
this(-1, null);
}
/**
* Constructs a new {@Code SpinolypNPC} {@Code Object}
* @param id the id.
* @param location the location.
*/
public SpinolypNPC(int id, Location location) {
super(id, location);
super.setAggressive(true);
super.setNeverWalks(true);
}
@Override
public AbstractNPC construct(int id, Location location, Object... objects) {
return new SpinolypNPC(id, location);
}
@Override
public CombatSwingHandler getSwingHandler(boolean swing) {
return SWING_HANDLER;
}
@Override
public void init() {
super.init();
super.getLocks().lockMovement(Integer.MAX_VALUE);
setSpell();
}
/**
* Sets the spell.
*/
public void setSpell() {
CombatSpell spell = (CombatSpell) SpellBook.MODERN.getSpell(14);
getProperties().setSpell(spell);
getProperties().setAutocastSpell(spell);
}
@Override
public void sendImpact(BattleState state) {
if (state.getEstimatedHit() == 0 && RandomFunction.random(15) < 2) {
state.setEstimatedHit(RandomFunction.random(1, 11));
}
if (state.getEstimatedHit() > 11) {
state.setEstimatedHit(RandomFunction.random(3, 9));
}
}
@Override
public int[] getIds() {
return new int[] { 2894, 2896 };
}
/**
* Handles the spinolpys swings.
* @author Vexia
*/
public static final class SpinolpySwingHandler extends MultiSwingHandler {
/**
* Constructs a new {@Code SpinolpySwingHandler} {@Code
* Object}
*/
public SpinolpySwingHandler() {
super(new SwitchAttack(CombatStyle.MAGIC.getSwingHandler(), null), new SwitchAttack(CombatStyle.RANGE.getSwingHandler(), null));
}
@Override
public InteractionType canSwing(Entity entity, Entity victim) {
InteractionType type = super.canSwing(entity, victim);
if (type == InteractionType.MOVE_INTERACT) {
type = InteractionType.NO_INTERACT;
}
return type;
}
@Override
public int swing(Entity entity, Entity victim, BattleState state) {
int swing = super.swing(entity, victim, state);
if (getType() == CombatStyle.MAGIC) {
setSpell(entity);
}
return swing;
}
@Override
public int getCombatDistance(Entity e, Entity v, int distance) {
return 12;
}
@Override
public void visualize(Entity entity, Entity victim, BattleState state) {
super.visualize(entity, victim, state);
if (state.getStyle() == CombatStyle.MAGIC) {
setSpell(entity);
CombatSpell spell = (CombatSpell) SpellBook.MODERN.getSpell(14);
state.setSpell(spell);
}
state.getStyle().getSwingHandler().visualize(entity, victim, state);
entity.getAnimator().forceAnimation(entity.getProperties().getAttackAnimation());
}
@Override
public void impact(Entity entity, Entity victim, BattleState state) {
super.impact(entity, victim, state);
if (super.getType() == CombatStyle.MAGIC) {
victim.getSkills().decrementPrayerPoints(1);
} else {
if (RandomFunction.random(20) == 5) {
victim.getStateManager().register(EntityState.POISONED, false, 68, entity);
}
}
}
/**
* Sets the spell.
*/
public void setSpell(Entity e) {
CombatSpell spell = (CombatSpell) SpellBook.MODERN.getSpell(14);
e.getProperties().setSpell(spell);
e.getProperties().setAutocastSpell(spell);
}
}
}

View file

@ -0,0 +1,408 @@
package plugin.zone.wbisland;
import java.util.ArrayList;
import java.util.List;
import org.crandor.cache.def.impl.NPCDefinition;
import org.crandor.cache.def.impl.ObjectDefinition;
import org.crandor.game.content.dialogue.DialogueAction;
import org.crandor.game.content.global.action.ClimbActionHandler;
import org.crandor.game.content.skill.Skills;
import org.crandor.game.interaction.Option;
import org.crandor.game.interaction.OptionHandler;
import org.crandor.game.node.Node;
import org.crandor.game.node.entity.Entity;
import org.crandor.game.node.entity.combat.BattleState;
import org.crandor.game.node.entity.combat.CombatStyle;
import org.crandor.game.node.entity.npc.AbstractNPC;
import org.crandor.game.node.entity.npc.NPC;
import org.crandor.game.node.entity.player.Player;
import org.crandor.game.node.object.ObjectBuilder;
import org.crandor.game.system.task.Pulse;
import org.crandor.game.world.GameWorld;
import org.crandor.game.world.map.Location;
import org.crandor.game.world.map.RegionManager;
import org.crandor.game.world.map.zone.MapZone;
import org.crandor.game.world.map.zone.ZoneBorders;
import org.crandor.game.world.map.zone.ZoneRestriction;
import org.crandor.game.world.repository.Repository;
import org.crandor.game.world.update.flag.context.Animation;
import org.crandor.plugin.Plugin;
import org.crandor.plugin.PluginManager;
/**
* Handles the waterbirth dungeon zone.
* @author Vexia
*/
public final class WaterBirthDungeonZone extends MapZone implements Plugin<Object> {
/**
* The door support locations.
*/
private static final Location[] DOOR_SUPPORTS = new Location[] { Location.create(2545, 10145, 0), Location.create(2543, 10143, 0), Location.create(2545, 10141, 0) };
/**
* Constructs a new {@code WaterBirthDungeonZone} {@code Object}.
*/
public WaterBirthDungeonZone() {
super("Water birth dungeon", true, ZoneRestriction.CANNON, ZoneRestriction.RANDOM_EVENTS);
PluginManager.definePlugin(new DagannothKingNPC());
PluginManager.definePlugin(new DoorSupportNPC());
PluginManager.definePlugin(new DungeonOptionHandler());
PluginManager.definePlugin(new SpinolypNPC());
}
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
return this;
}
@Override
public Object fireEvent(String identifier, Object... args) {
return null;
}
@Override
public boolean move(Entity e, Location from, Location to) {
for (Location location : DOOR_SUPPORTS) {
if (location.equals(to)) {
List<NPC> npcs = RegionManager.getLocalNpcs(location, 0);
NPC npc = null;
if (npcs.size() != 0) {
npc = npcs.get(0);
}
if (npc != null && npc instanceof DoorSupportNPC) {
DoorSupportNPC door = (DoorSupportNPC) npc;
if (door.getId() != door.getOriginalId()) {
return true;
}
}
return false;
}
}
if (e instanceof Player) {
final Player p = (e.asPlayer());
if (p.getLocation().equals(new Location(2545, 10144, 0)) || p.getLocation().equals(new Location(2545, 10142, 0))) {
final List<NPC> eggs = new ArrayList<>();
NPC n = Repository.findNPC(new Location(2546, 10142, 0));
if (n != null && n.getId() == 2449) {
eggs.add(n);
}
n = Repository.findNPC(new Location(2546, 10144, 0));
if (n != null && n.getId() == 2449) {
eggs.add(n);
}
if (eggs.size() == 0) {
return true;
}
for (NPC npc : eggs) {
if (npc.getAttribute("transforming", 0) > GameWorld.getTicks()) {
return true;
}
npc.setAttribute("transforming", GameWorld.getTicks() + 3);
}
GameWorld.submit(new Pulse(1) {
int counter;
@Override
public boolean pulse() {
switch (++counter) {
case 1:
for (NPC n : eggs) {
n.transform(n.getId() + 1);
}
break;
case 3:
final List<NPC> spawns = new ArrayList<>();
for (NPC n : eggs) {
n.transform(n.getId() + 1);
NPC spawn = NPC.create(2454, n.getLocation().transform(-1, 0, 0));
spawn.init();
spawn.setWalks(true);
spawn.setAggressive(true);
spawn.setRespawn(false);
spawn.attack(p);
spawns.add(spawn);
}
GameWorld.submit(new Pulse(GameWorld.getSettings().isDevMode() ? 10 : 45) {
@Override
public boolean pulse() {
for (NPC n : eggs) {
n.reTransform();
}
for (NPC spawn : spawns) {
if (spawn.isActive() && !spawn.inCombat()) {
spawn.clear();
}
}
return true;
}
});
break;
}
return counter == 3;
}
});
}
}
return super.move(e, from, to);
}
@Override
public boolean interact(Entity e, Node target, Option option) {
if (e instanceof Player) {
final Player player = (Player) e;
switch (target.getId()) {
case 8966:
player.getProperties().setTeleportLocation(Location.create(2523, 3740, 0));
return true;
case 10193:
player.getProperties().setTeleportLocation(new Location(2545, 10143, 0));
return true;
case 10177:
switch (option.getName()) {
case "Climb":
player.getDialogueInterpreter().sendOptions("Select an Option", "Climb Up.", "Climb Down.");
player.getDialogueInterpreter().addAction(new DialogueAction() {
@Override
public void handle(Player player, int buttonId) {
switch (buttonId) {
case 1:
ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_UP, new Location(2544, 3741, 0));
break;
case 2:
ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_DOWN, new Location(1799, 4406, 3));
break;
}
}
});
break;
case "Climb-down":
ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_DOWN, new Location(1799, 4406, 3));
break;
case "Climb-up":
ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_UP, new Location(2544, 3741, 0));
break;
}
return true;
case 10217:
player.sendMessage("You need to have completed Horror from the Deep in order to do this.");
return true;
case 10230:
player.teleport(Location.create(2899, 4450, 0));
return true;
case 10229:
player.teleport(Location.create(1912, 4367, 0));
return true;
}
}
return super.interact(e, target, option);
}
@Override
public void configure() {
register(new ZoneBorders(2423, 10090, 2585, 10195));
registerRegion(7236);
registerRegion(7492);
registerRegion(7748);
registerRegion(11589);
}
/**
* Handles the dungeon options.
* @author Vexia
*/
public static final class DungeonOptionHandler extends OptionHandler {
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ObjectDefinition.forId(8958).getConfigurations().put("option:open", this);
ObjectDefinition.forId(8959).getConfigurations().put("option:open", this);
ObjectDefinition.forId(8960).getConfigurations().put("option:open", this);
NPCDefinition.forId(2440).getConfigurations().put("option:destroy", this);
NPCDefinition.forId(2443).getConfigurations().put("option:destroy", this);
NPCDefinition.forId(2446).getConfigurations().put("option:destroy", this);
for (Location l : DOOR_SUPPORTS) {
ObjectBuilder.remove(RegionManager.getObject(l));
}
return this;
}
@Override
public boolean handle(Player player, Node node, String option) {
switch (node.getId()) {
case 8958:
case 8959:
case 8960:
boolean behind = player.getLocation().getX() >= 2492;
if (!behind) {
if (RegionManager.getLocalPlayers(node.getLocation().transform(-1, 0, 0), 0).size() == 0 || RegionManager.getLocalPlayers(node.getLocation().getLocation().transform(-1, 2, 0), 0).size() == 0) {
player.sendMessage("You cannot see a way to open this door...");
break;
}
}
if (!node.isActive()) {
return true;
}
ObjectBuilder.replace(node.asObject(), node.asObject().transform(8962), 30);
break;
case 2440:
case 2443:
case 2446:
int x = node.getLocation().getX();
int y = node.getLocation().getY();
boolean canAttack = true;
if (x == 2545 && y == 10145 && player.getLocation().getY() > y) {// top
// north
canAttack = false;
} else if (x == 2543 && y == 10143 && player.getLocation().getX() < x) {// middle
canAttack = false;
} else if (x == 2545 && y == 10141 && player.getLocation().getY() < y) {// south
canAttack = false;
}
if (!canAttack) {
player.sendMessage("The door is propped securely shut from this side...");
break;
}
player.attack(node);
break;
}
return true;
}
@Override
public Location getDestination(Node node, Node n) {
if (n.getName().equals("Door-support")) {
Player player = node.asPlayer();
if (player.getProperties().getCombatPulse().getStyle() != CombatStyle.MELEE) {
return node.getLocation();
}
}
return null;
}
}
/**
* Represents a door support npc.
* @author Vexia
*/
public static final class DoorSupportNPC extends AbstractNPC {
/**
* The death spawn.
*/
private long deathSpawn = -1;
/**
* Constructs a new {@Code DoorSupportNPC} {@Code Object}
*/
public DoorSupportNPC() {
super(-1, null);
}
/**
* Constructs a new {@Code DoorSupportNPC} {@Code Object}
* @param id the id.
* @param location the location.
*/
public DoorSupportNPC(int id, Location location) {
super(id, location);
}
@Override
public AbstractNPC construct(int id, Location location, Object... objects) {
return new DoorSupportNPC(id, location);
}
@Override
public void init() {
lock();
super.init();
getSkills().setStaticLevel(Skills.HITPOINTS, 1);
getSkills().setLevel(Skills.HITPOINTS, 1);
getSkills().setLifepoints(1);
getProperties().setDeathAnimation(new Animation(-1));
}
@Override
public void handleTickActions() {
if (deathSpawn != -1 && deathSpawn < GameWorld.getTicks()) {
deathSpawn = -1;
transform(getOriginalId());
getSkills().setStaticLevel(Skills.HITPOINTS, 1);
getSkills().setLevel(Skills.HITPOINTS, 1);
getSkills().setLifepoints(1);
fullRestore();
getSkills().heal(100);
}
}
@Override
public boolean face(Entity entity) {
return false;
}
@Override
public boolean faceLocation(Location locatin) {
return false;
}
@Override
public void checkImpact(BattleState state) {
getSkills().setStaticLevel(Skills.HITPOINTS, 1);
getSkills().setLevel(Skills.HITPOINTS, 1);
getSkills().setLifepoints(1);
getSkills().setLifepoints(1);
state.setEstimatedHit(1);
lock();
getWalkingQueue().reset();
}
@Override
public boolean canStartCombat(Entity victim) {
return false;
}
@Override
public void commenceDeath(Entity killer) {
getAnimator().reset();
transform(getOriginalId() + 1);
lock();
}
@Override
public void finalizeDeath(Entity killer) {
getAnimator().reset();
transform(getOriginalId() + 2);
deathSpawn = GameWorld.getTicks() + 55;
lock();
}
@Override
public boolean isAttackable(Entity entity, CombatStyle style) {
if (getId() != getOriginalId()) {
return false;
}
if (entity.getLocation().getDistance(getLocation()) <= 3) {
if (entity instanceof Player) {
Player player = entity.asPlayer();
player.sendMessage("The door is propped securely shut from this side...");
}
return false;
}
return style != CombatStyle.MELEE;
}
@Override
public int[] getIds() {
return new int[] { 2440, 2443, 2446 };
}
}
}

View file

@ -0,0 +1,103 @@
package plugin.zone.wbisland;
import org.crandor.game.component.Component;
import org.crandor.game.interaction.Option;
import org.crandor.game.node.Node;
import org.crandor.game.node.entity.Entity;
import org.crandor.game.node.entity.player.Player;
import org.crandor.game.world.map.Location;
import org.crandor.game.world.map.zone.MapZone;
import org.crandor.game.world.map.zone.ZoneBorders;
import org.crandor.game.world.map.zone.ZoneBuilder;
import org.crandor.plugin.InitializablePlugin;
import org.crandor.plugin.Plugin;
/**
* Handles the waterbirth island zone.
* @author Vexia
*/
@InitializablePlugin
public final class WaterBirthIslandZone extends MapZone implements Plugin<Object> {
/**
* Constructs a new {@code WaterBirthIslandZone} {@code Object}.
*/
public WaterBirthIslandZone() {
super("Water birth island", true);
}
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ZoneBuilder.configure(this);
ZoneBuilder.configure(new WaterBirthDungeonZone());
return this;
}
@Override
public Object fireEvent(String identifier, Object... args) {
return null;
}
@Override
public boolean interact(Entity e, Node target, Option option) {
if (e instanceof Player) {
final Player player = (Player) e;
switch (target.getId()) {
case 2438:
if (option.getName().equals("Travel")) {
player.getDialogueInterpreter().open(target.getId(), target, true);
return true;
}
break;
case 8929:
player.getInterfaceManager().open(new Component(574));
return true;
case 8930:
player.getProperties().setTeleportLocation(new Location(2545, 10143, 0));
return true;
}
}
return super.interact(e, target, option);
}
@Override
public boolean enter(Entity e) {
if (e instanceof Player) {
final Player player = (Player) e;
player.getInterfaceManager().openOverlay(new Component(482));
}
return true;
}
@Override
public boolean leave(Entity e, boolean logout) {
if (e instanceof Player) {
((Player) e).getInterfaceManager().closeOverlay();
}
return true;
}
@Override
public boolean actionButton(Player player, int interfaceId, int buttonId, int slot, int itemId, int opcode) {
switch (interfaceId) {
case 574:
switch (buttonId) {
case 17:
player.getInterfaceManager().close();
player.getProperties().setTeleportLocation(Location.create(2443, 10146, 0));
break;
case 18:
player.getInterfaceManager().close();
break;
}
break;
}
return super.actionButton(player, interfaceId, buttonId, slot, itemId, opcode);
}
@Override
public void configure() {
register(new ZoneBorders(2487, 3711, 2565, 3776));
}
}