diff --git a/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java b/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java index 7b8857b7..074b123d 100644 --- a/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java +++ b/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java @@ -1,16 +1,12 @@ package net.Indyuce.mmocore.api.load; import net.Indyuce.mmocore.experience.dispenser.ExperienceDispenser; +import net.Indyuce.mmocore.loot.droptable.condition.*; import org.bukkit.configuration.ConfigurationSection; import net.Indyuce.mmocore.api.block.BlockType; import net.Indyuce.mmocore.api.block.SkullBlockType; import net.Indyuce.mmocore.api.block.VanillaBlockType; -import net.Indyuce.mmocore.loot.droptable.condition.BiomeCondition; -import net.Indyuce.mmocore.loot.droptable.condition.Condition; -import net.Indyuce.mmocore.loot.droptable.condition.LevelCondition; -import net.Indyuce.mmocore.loot.droptable.condition.PermissionCondition; -import net.Indyuce.mmocore.loot.droptable.condition.WorldCondition; import net.Indyuce.mmocore.loot.droptable.dropitem.DropItem; import net.Indyuce.mmocore.loot.droptable.dropitem.DropTableDropItem; import net.Indyuce.mmocore.loot.droptable.dropitem.GoldDropItem; @@ -109,6 +105,9 @@ public class DefaultMMOLoader extends MMOLoader { @Override public Condition loadCondition(MMOLineConfig config) { + if(config.getKey().equals("distance")) + return new DistanceCondition(config); + if (config.getKey().equals("world")) return new WorldCondition(config); diff --git a/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java b/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java index 0fae0302..75c9d6bc 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java @@ -457,9 +457,9 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc * Teleports the player to a specific waypoint. This applies * the stellium waypoint cost and plays the teleport animation. * - * @param waypoint Target waypoint + * @param target Target waypoint */ - public void warp(Waypoint waypoint, CostType costType) { + public void warp(Waypoint target, double cost) { /* * This cooldown is only used internally to make sure the player is not @@ -467,8 +467,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc * player waypoints data */ setLastActivity(PlayerActivity.USE_WAYPOINT); - - final double cost = waypoint.getCost(costType); giveStellium(-cost, PlayerResourceUpdateEvent.UpdateReason.USE_WAYPOINT); new BukkitRunnable() { @@ -491,7 +489,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc MMOCore.plugin.configManager.getSimpleMessage("warping-comencing", "left", "" + ((120 - t) / 20)).send(getPlayer()); if (t++ >= 100) { - getPlayer().teleport(waypoint.getLocation()); + getPlayer().teleport(target.getLocation()); getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 20, 1, false, false)); MMOCore.plugin.soundManager.getSound(SoundEvent.WARP_TELEPORT).playTo(getPlayer()); cancel(); @@ -869,7 +867,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc * checks if they could potentially upgrade to one of these * * @return If the player can change its current class to - * a subclass + * a subclass */ public boolean canChooseSubclass() { for (Subclass subclass : getProfess().getSubclasses()) diff --git a/src/main/java/net/Indyuce/mmocore/api/player/stats/StatType.java b/src/main/java/net/Indyuce/mmocore/api/player/stats/StatType.java index cfc69000..9f66f9bf 100644 --- a/src/main/java/net/Indyuce/mmocore/api/player/stats/StatType.java +++ b/src/main/java/net/Indyuce/mmocore/api/player/stats/StatType.java @@ -61,6 +61,7 @@ public enum StatType { // Utility ADDITIONAL_EXPERIENCE, COOLDOWN_REDUCTION, + CHANCE, // Damage-type based stats MAGIC_DAMAGE, diff --git a/src/main/java/net/Indyuce/mmocore/gui/WaypointViewer.java b/src/main/java/net/Indyuce/mmocore/gui/WaypointViewer.java index 385db1ce..1f68d5ac 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/WaypointViewer.java +++ b/src/main/java/net/Indyuce/mmocore/gui/WaypointViewer.java @@ -1,7 +1,5 @@ package net.Indyuce.mmocore.gui; -import io.lumine.mythic.lib.api.item.ItemTag; -import io.lumine.mythic.lib.api.item.NBTItem; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerActivity; import net.Indyuce.mmocore.api.player.PlayerData; @@ -14,14 +12,17 @@ import net.Indyuce.mmocore.waypoint.CostType; import net.Indyuce.mmocore.waypoint.Waypoint; import net.Indyuce.mmocore.waypoint.WaypointOption; import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; import org.bukkit.Material; +import org.bukkit.NamespacedKey; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; +import java.util.*; public class WaypointViewer extends EditableInventory { public WaypointViewer() { @@ -65,7 +66,8 @@ public class WaypointViewer extends EditableInventory { public class WaypointItem extends SimplePlaceholderItem { private final SimplePlaceholderItem noWaypoint, locked; - private final WaypointItemHandler availWaypoint, notLinked, notDynamic, noStellium; + private final WaypointItemHandler availWaypoint, noStellium, notLinked, notDynamic, currentWayPoint; + public WaypointItem(ConfigurationSection config) { super(Material.BARRIER, config); @@ -74,15 +76,18 @@ public class WaypointViewer extends EditableInventory { Validate.notNull(config.getConfigurationSection("locked"), "Could not load 'locked' config"); Validate.notNull(config.getConfigurationSection("not-a-destination"), "Could not load 'not-a-destination' config"); Validate.notNull(config.getConfigurationSection("not-dynamic"), "Could not load 'not-dynamic' config"); + Validate.notNull(config.getConfigurationSection("current-waypoint"), "Could not load 'current-waypoint' config"); Validate.notNull(config.getConfigurationSection("not-enough-stellium"), "Could not load 'not-enough-stellium' config"); Validate.notNull(config.getConfigurationSection("display"), "Could not load 'display' config"); + noWaypoint = new SimplePlaceholderItem(config.getConfigurationSection("no-waypoint")); locked = new SimplePlaceholderItem(config.getConfigurationSection("locked")); - notLinked = new WaypointItemHandler(config.getConfigurationSection("not-a-destination")); - notDynamic = new WaypointItemHandler(config.getConfigurationSection("not-dynamic")); - noStellium = new WaypointItemHandler(config.getConfigurationSection("not-enough-stellium")); - availWaypoint = new WaypointItemHandler(config.getConfigurationSection("display")); + notLinked = new WaypointItemHandler(config.getConfigurationSection("not-a-destination"), true); + notDynamic = new WaypointItemHandler(config.getConfigurationSection("not-dynamic"), true); + currentWayPoint = new WaypointItemHandler(config.getConfigurationSection("current-waypoint"), true); + noStellium = new WaypointItemHandler(config.getConfigurationSection("not-enough-stellium"), false); + availWaypoint = new WaypointItemHandler(config.getConfigurationSection("display"), false); } @Override @@ -99,28 +104,37 @@ public class WaypointViewer extends EditableInventory { // Locked waypoint? Waypoint waypoint = inv.waypoints.get(index); + if (inv.current != null && inv.current.equals(waypoint)) + return currentWayPoint.display(inv, n); + + if (!inv.getPlayerData().hasWaypoint(waypoint)) return locked.display(inv, n); // Waypoints are not linked - if (inv.current != null && !inv.current.hasDestination(waypoint)) + if (inv.current != null && !inv.paths.containsKey(waypoint)) return notLinked.display(inv, n); + // Not dynamic waypoint - if (inv.current == null && !waypoint.hasOption(WaypointOption.DYNAMIC)) + if (inv.current == null && !inv.paths.containsKey(waypoint)) return notDynamic.display(inv, n); - // Stellium cost - if (waypoint.getCost(inv.current == null ? CostType.DYNAMIC_USE : CostType.NORMAL_USE) > inv.getPlayerData().getStellium()) + //Normal cost + if (inv.paths.get(waypoint).getCost() > inv.getPlayerData().getStellium()) return noStellium.display(inv, n); + return availWaypoint.display(inv, n); } } public class WaypointItemHandler extends InventoryItem { - public WaypointItemHandler(ConfigurationSection config) { + private final boolean onlyName; + + public WaypointItemHandler(ConfigurationSection config, boolean onlyName) { super(config); + this.onlyName = onlyName; } @Override @@ -129,7 +143,11 @@ public class WaypointViewer extends EditableInventory { // If a player can teleport to another waypoint given his location Waypoint waypoint = inv.waypoints.get(inv.page * inv.getEditable().getByFunction("waypoint").getSlots().size() + n); - return NBTItem.get(disp).addTag(new ItemTag("waypointId", waypoint.getId())).toItem(); + ItemMeta meta = disp.getItemMeta(); + PersistentDataContainer container = meta.getPersistentDataContainer(); + container.set(new NamespacedKey(MMOCore.plugin, "waypointId"), PersistentDataType.STRING, waypoint.getId()); + disp.setItemMeta(meta); + return disp; } @Override @@ -138,9 +156,12 @@ public class WaypointViewer extends EditableInventory { Waypoint waypoint = inv.waypoints.get(inv.page * inv.getByFunction("waypoint").getSlots().size() + n); holders.register("name", waypoint.getName()); - holders.register("current_cost", decimal.format(waypoint.getCost(inv.waypointCostType))); - holders.register("normal_cost", decimal.format(waypoint.getCost(CostType.NORMAL_USE))); - holders.register("dynamic_cost", decimal.format(waypoint.getCost(CostType.DYNAMIC_USE))); + if (!onlyName) { + holders.register("current_cost", inv.paths.get(waypoint).getCost()); + holders.register("normal_cost", decimal.format(inv.paths.containsKey(waypoint) ? inv.paths.get(waypoint).getCost() : Double.POSITIVE_INFINITY)); + holders.register("dynamic_cost", decimal.format(waypoint.getDynamicCost())); + holders.register("intermediary_waypoints", inv.paths.containsKey(waypoint) ? inv.paths.get(waypoint).displayIntermediaryWayPoints(inv.waypointCostType.equals(CostType.DYNAMIC_USE)) : "none"); + } return holders; } @@ -149,6 +170,7 @@ public class WaypointViewer extends EditableInventory { public class WaypointViewerInventory extends GeneratedInventory { private final List waypoints = new ArrayList<>(MMOCore.plugin.waypointManager.getAll()); private final Waypoint current; + private final Map paths = new HashMap<>(); private final CostType waypointCostType; private int page; @@ -157,6 +179,31 @@ public class WaypointViewer extends EditableInventory { super(playerData, editable); this.current = current; + if (current != null) { + for (Waypoint.PathInfo pathInfo : current.getAllPath()) + paths.put(pathInfo.getFinalWaypoint(), pathInfo); + } + if (current == null) { + + //Iterate through all the dynamic points and find all the points it is linked to and the path + HashMap dynamicPoints = new HashMap<>(); + //We first check all the dynamic waypoints + for (Waypoint waypoint : waypoints) { + if (waypoint.canHaveDynamicUse(playerData.getPlayer())) { + paths.put(waypoint, new Waypoint.PathInfo(waypoint, waypoint.getDynamicCost())); + dynamicPoints.put(waypoint, waypoint.getDynamicCost()); + } + } + for(Waypoint source: dynamicPoints.keySet()){ + for (Waypoint.PathInfo target : source.getAllPath()) { + if (!paths.containsKey(target.getFinalWaypoint()) || paths.get(target.getFinalWaypoint()).getCost() > target.getCost()+dynamicPoints.get(source)) { + paths.put(target.getFinalWaypoint(), target.addCost(dynamicPoints.get(source))); + } + } + } + + } + this.waypointCostType = current == null ? CostType.DYNAMIC_USE : CostType.NORMAL_USE; } @@ -180,7 +227,10 @@ public class WaypointViewer extends EditableInventory { } if (item.getFunction().equals("waypoint")) { - String tag = NBTItem.get(event.getCurrentItem()).getString("waypointId"); + PersistentDataContainer container = event.getCurrentItem().getItemMeta().getPersistentDataContainer(); + String tag = container.has(new NamespacedKey(MMOCore.plugin, "waypointId"), PersistentDataType.STRING) ? + container.get(new NamespacedKey(MMOCore.plugin, "waypointId"), PersistentDataType.STRING) : ""; + if (tag.equals("")) return; @@ -198,20 +248,21 @@ public class WaypointViewer extends EditableInventory { } // Waypoint does not have target as destination - if (current != null && !current.hasDestination(waypoint)) { + if (current != null && current.getPath(waypoint) == null) { MMOCore.plugin.configManager.getSimpleMessage("cannot-teleport-to").send(player); return; } // Not dynamic waypoint - if (current == null && !waypoint.hasOption(WaypointOption.DYNAMIC)) { + if (current == null && !paths.containsKey(waypoint)) { MMOCore.plugin.configManager.getSimpleMessage("not-dynamic-waypoint").send(player); return; } // Stellium cost CostType costType = current == null ? CostType.DYNAMIC_USE : CostType.NORMAL_USE; - double left = waypoint.getCost(costType) - playerData.getStellium(); + double withdraw = paths.get(waypoint).getCost(); + double left = withdraw - playerData.getStellium(); if (left > 0) { MMOCore.plugin.configManager.getSimpleMessage("not-enough-stellium", "more", decimal.format(left)).send(player); return; @@ -221,7 +272,8 @@ public class WaypointViewer extends EditableInventory { return; player.closeInventory(); - playerData.warp(waypoint, costType); + playerData.warp(waypoint, withdraw); + } } } diff --git a/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java b/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java index ef7e8217..6e265a3b 100644 --- a/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java +++ b/src/main/java/net/Indyuce/mmocore/loot/chest/LootChestRegion.java @@ -4,6 +4,7 @@ import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.event.LootChestSpawnEvent; import net.Indyuce.mmocore.api.player.PlayerActivity; import net.Indyuce.mmocore.api.player.PlayerData; +import net.Indyuce.mmocore.api.player.stats.StatType; import net.Indyuce.mmocore.loot.LootBuilder; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; @@ -85,7 +86,7 @@ public class LootChestRegion { player.setLastActivity(PlayerActivity.LOOT_CHEST_SPAWN); // First randomly determine the chest tier - ChestTier tier = rollTier(); + ChestTier tier = rollTier(player); // Find a random location, 20 trials max Location location = getRandomLocation(player.getPlayer().getLocation()); @@ -116,14 +117,22 @@ public class LootChestRegion { MMOCore.plugin.lootChests.register(lootChest); } - // TODO stat to increase chance to get higher tiers? - public ChestTier rollTier() { + public ChestTier rollTier(PlayerData player) { + double chance = player.getStats().getStat(StatType.CHANCE); - double s = 0; + //chance=0 ->the tier.chance remains the same + //chance ->+inf -> the tier.chance becomes the same for everyone, uniform law + //chance=8-> tierChance=sqrt(tierChance) + double sum = 0; for (ChestTier tier : tiers) { - if (random.nextDouble() < tier.chance / (1 - s)) + sum += Math.pow(tier.chance, 1 / Math.pow((1 + chance),1/3)); + } + + double s=0; + for (ChestTier tier : tiers) { + s+=Math.pow(tier.chance, 1 / Math.pow((1 + chance),1/3))/sum; + if (random.nextDouble() < s) return tier; - s += tier.chance; } return tiers.stream().findAny().orElse(null); diff --git a/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/DistanceCondition.java b/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/DistanceCondition.java new file mode 100644 index 00000000..486ce977 --- /dev/null +++ b/src/main/java/net/Indyuce/mmocore/loot/droptable/condition/DistanceCondition.java @@ -0,0 +1,39 @@ +package net.Indyuce.mmocore.loot.droptable.condition; + +import io.lumine.mythic.lib.api.MMOLineConfig; +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.generator.WorldInfo; + + +import java.util.stream.Collectors; + +public class DistanceCondition extends Condition{ + private final Location location; + private final double distance; + + public DistanceCondition(MMOLineConfig config) { + super(config); + Validate.isTrue(config.contains("world")); + Validate.isTrue(config.contains("x")); + Validate.isTrue(config.contains("y")); + Validate.isTrue(config.contains("z")); + Validate.isTrue(config.contains("distance")); + Validate.isTrue(Bukkit.getWorld(config.getString("world"))!=null,"This world doesn't exist"); + location=new Location(Bukkit.getWorld(config.getString("world")),config.getDouble("x"), + config.getDouble("y"),config.getDouble("z")); + distance=config.getDouble("distance"); + } + + @Override + public boolean isMet(ConditionInstance entity) { + Entity entity1=entity.getEntity(); + return entity1.getWorld().equals(location.getWorld())&&location.distance(entity1.getLocation()) * If it's empty it can access any waypoint. */ - private final Set destinations = new HashSet<>(); + private final Map destinations = new HashMap<>(); /** * Waypoint options saved here. @@ -31,8 +38,23 @@ public class Waypoint implements Unlockable { /** * Stellium cost for each action (0 being the default cost) */ + private final double dynamicCost, setSpawnCost; + private final ArrayList dynamicUseConditions = new ArrayList<>(); + private final Map costs = new HashMap<>(); + public double getDynamicCost() { + return dynamicCost; + } + + public double getSetSpawnCost() { + return setSpawnCost; + } + + public double getCost(Waypoint waypoint) { + return getPath(waypoint).cost; + } + public Waypoint(ConfigurationSection config) { id = Objects.requireNonNull(config, "Could not load config section").getName(); name = Objects.requireNonNull(config.getString("name"), "Could not load waypoint name"); @@ -40,13 +62,39 @@ public class Waypoint implements Unlockable { loc = readLocation(Objects.requireNonNull(config.getString("location"), "Could not read location")); radiusSquared = Math.pow(config.getDouble("radius"), 2); - for (CostType costType : CostType.values()) - costs.put(costType, config.getDouble("cost." + costType.getPath())); + dynamicCost = config.getDouble("cost.dynamic-use"); + setSpawnCost = config.getDouble("cost.set-spawnpoint"); + for (WaypointOption option : WaypointOption.values()) options.put(option, config.getBoolean("option." + option.getPath(), option.getDefaultValue())); - destinations.addAll(config.getStringList("linked")); + //We load all the linked WayPoints + if (config.contains("linked")) { + ConfigurationSection section = config.getConfigurationSection("linked"); + for (String key : section.getKeys(false)) { + destinations.put(key, section.getInt(key)); + } + } + if (config.contains("conditions")) { + List conditions = config.getStringList("conditions"); + for (String condition : conditions) { + dynamicUseConditions.add(MMOCore.plugin.loadManager.loadCondition(new MMOLineConfig(condition))); + + } + + } + } + + public boolean canHaveDynamicUse(Player player) { + if (!options.get(WaypointOption.DYNAMIC)) + return false; + + for (Condition condition : dynamicUseConditions) { + if (!condition.isMet(new ConditionInstance(player))) + return false; + } + return true; } public String getId() { @@ -61,16 +109,87 @@ public class Waypoint implements Unlockable { return loc; } + /** * @param other Another waypoint * @return If any player standing on that waypoint can teleport to given waypoint */ + @Deprecated public boolean hasDestination(Waypoint other) { - return destinations.isEmpty() || destinations.contains(other.getId()); + return destinations.isEmpty() || destinations.keySet().contains(other.getId()); } - public double getCost(CostType type) { - return costs.getOrDefault(type, 0d); + /** + * Checks directly if the waypoint is directly linked to the current one + * + * @return Integer.POSITIVE_INFINITY if the way point is not linked + */ + private int getSimpleCostDestination(Waypoint waypoint) { + if (!destinations.keySet().contains(waypoint.getId())) + return Integer.MAX_VALUE; + return destinations.get(waypoint.getId()); + } + + + public ArrayList getAllPath() { + //All the WayPoints that have been registered + ArrayList checkedPoints = new ArrayList<>(); + //All the path + ArrayList paths = new ArrayList(); + ArrayList pointsToCheck = new ArrayList<>(); + pointsToCheck.add(new PathInfo(this)); + + while (pointsToCheck.size() != 0) { + PathInfo checked = pointsToCheck.get(0); + pointsToCheck.remove(0); + paths.add(checked); + checkedPoints.add(checked.getFinalWaypoint()); + + for (String wayPointId : checked.getFinalWaypoint().destinations.keySet()) { + Waypoint toCheck = MMOCore.plugin.waypointManager.get(wayPointId); + if (!checkedPoints.contains(toCheck)) { + PathInfo toCheckInfo = checked.addWayPoint(toCheck); + //We keep pointsToCheck ordered + pointsToCheck = toCheckInfo.addInOrder(pointsToCheck); + } + } + } + return paths; + + } + + + @Nullable + public PathInfo getPath(Waypoint targetWaypoint) { + //All the WayPoints that have been registered + ArrayList checkedPoints = new ArrayList<>(); + //All the path + ArrayList paths = new ArrayList(); + ArrayList pointsToCheck = new ArrayList<>(); + pointsToCheck.add(new PathInfo(this)); + + while (pointsToCheck.size() != 0) { + PathInfo checked = pointsToCheck.get(0); + pointsToCheck.remove(0); + paths.add(checked); + checkedPoints.add(checked.getFinalWaypoint()); + + if (checked.getFinalWaypoint().equals(targetWaypoint)) + return checked; + + for (String wayPointId : checked.getFinalWaypoint().destinations.keySet()) { + Waypoint toCheck = MMOCore.plugin.waypointManager.get(wayPointId); + if (!checkedPoints.contains(toCheck)) { + PathInfo toCheckInfo = checked.addWayPoint(toCheck); + //We keep pointsToCheck ordered + pointsToCheck = toCheckInfo.addInOrder(pointsToCheck); + } + } + } + + //If no path has been found we return null + return null; + } public boolean hasOption(WaypointOption option) { @@ -118,4 +237,96 @@ public class Waypoint implements Unlockable { return new Location(world, x, y, z, yaw, pitch); } + + public static class PathInfo { + private final ArrayList waypoints; + private double cost; + + public ArrayList getWaypoints() { + return waypoints; + } + + public double getCost() { + return cost; + } + + public PathInfo(Waypoint waypoint) { + this.waypoints = new ArrayList<>(); + this.waypoints.add(waypoint); + cost = 0; + } + public PathInfo(Waypoint waypoint,double cost) { + this.waypoints = new ArrayList<>(); + this.waypoints.add(waypoint); + this.cost = cost; + } + + public PathInfo addCost(double cost) { + this.cost+=cost; + return this; + } + + public ArrayList addInOrder(ArrayList pathInfos) { + int index = 0; + while (index < pathInfos.size()) { + if (cost < pathInfos.get(index).cost) { + pathInfos.set(index, this); + return pathInfos; + } + index++; + } + //If index==pathInfos.size() we add the waypoint at the end + pathInfos.add(this); + return pathInfos; + } + + + public PathInfo(List waypoints, double cost) { + this.waypoints = new ArrayList<>(waypoints); + this.cost = cost; + } + + /** + * + * @param dynamic We display the first waypoint if it is dynamic as it is an intermediary point + * @return + */ + public String displayIntermediaryWayPoints(boolean dynamic) { + String result = ""; + if(!dynamic) { + if (waypoints.size() <= 2) + return "none"; + for (int i = 1; i < waypoints.size() - 1; i++) { + result += waypoints.get(i).name + (i != waypoints.size() - 2 ? "," : ""); + } + + } + if(dynamic) { + if (waypoints.size() <= 1) + return "none"; + for (int i = 0; i < waypoints.size() - 1; i++) { + result += waypoints.get(i).name + (i != waypoints.size() - 2 ? "," : ""); + } + } + return result; + } + + public PathInfo addWayPoint(Waypoint waypoint) { + Validate.isTrue(!waypoints.contains(waypoint), "You can't create cyclic path"); + ArrayList newWaypoints = new ArrayList<>(); + newWaypoints.addAll(waypoints); + newWaypoints.add(waypoint); + double cost = this.cost + getFinalWaypoint().getSimpleCostDestination(waypoint); + return new PathInfo(newWaypoints, cost); + } + + + public Waypoint getInitialWaypoint() { + return waypoints.get(0); + } + + public Waypoint getFinalWaypoint() { + return waypoints.get(waypoints.size() - 1); + } + } } \ No newline at end of file diff --git a/src/main/resources/default/gui/waypoints.yml b/src/main/resources/default/gui/waypoints.yml index 074e6aca..ff58f2c2 100644 --- a/src/main/resources/default/gui/waypoints.yml +++ b/src/main/resources/default/gui/waypoints.yml @@ -34,7 +34,7 @@ items: lore: - '&7You cannot teleport as the two waypoints are not linked.' - - '&7Teleporting costs &b&l{normal_cost}&7/&b&l{dynamic_cost} &7Stellium.' + # When you cannot teleport to a non dynamic waypoint not-dynamic: @@ -43,9 +43,16 @@ items: lore: - '&7You cannot teleport as you are not standing on a waypoint.' - - '&7Teleporting costs &b&l{normal_cost}&7/&b&l{dynamic_cost} &7Stellium.' - # When you cannot teleport to a non dynamic waypoint + + current-waypoint: + name: '&a{name}' + item: ENDER_PEARL + + lore: + - '&7The waypoint you are standing at.' + + # When you don't have enough stellium not-enough-stellium: name: '&a{name}' item: ENDER_PEARL @@ -61,6 +68,7 @@ items: lore: - '&7You can teleport to this waypoint.' + - '&7Intermediary waypoints : {intermediary_waypoints}' - '&7Click to teleport for &b{current_cost} &7Stellium.' next: diff --git a/src/main/resources/default/professions/fishing.yml b/src/main/resources/default/professions/fishing.yml index c26e6a6a..ed2b9985 100644 --- a/src/main/resources/default/professions/fishing.yml +++ b/src/main/resources/default/professions/fishing.yml @@ -22,7 +22,7 @@ exp-sources: {} on-fish: overriding-drop-table: conditions: - - 'region{name=swamp}' + - 'biome{name=swamp}' # When drop table is read, one of these # items will be selected randomly. diff --git a/src/main/resources/default/stats.yml b/src/main/resources/default/stats.yml index 1c9ef218..21fdee82 100644 --- a/src/main/resources/default/stats.yml +++ b/src/main/resources/default/stats.yml @@ -58,6 +58,11 @@ default: COOLDOWN_REDUCTION: base: 0 per-level: 0 + + #Increases chance to have rare loot chests + CHANCE: + base: 0 + per-level: 0 # Dealt by skills SKILL_DAMAGE: diff --git a/src/main/resources/default/waypoints.yml b/src/main/resources/default/waypoints.yml index 59999359..1de64a36 100644 --- a/src/main/resources/default/waypoints.yml +++ b/src/main/resources/default/waypoints.yml @@ -17,8 +17,6 @@ spawn: # Stellium cost in order to use the waypoint. # Stellium is like stamina however it's not used # by skills and regens much slower than mana. - normal-use: 3 - # Cost when not standing on any waypoint. dynamic-use: 5 @@ -42,12 +40,12 @@ spawn: default: true # All the waypoints you can teleport to when standing - # on that waypoint. If that list is empty you are able + # on that waypoint. And the cost needed to travel to his pointIf that list is empty you are able # to teleport to any waypoint linked: - - spawn1 - - spawn2 - - forest + spawn1: 4 + spawn2: 5 + spawn1: name: Spawn1 @@ -62,6 +60,15 @@ spawn1: # on any waypoint (waypoint must be unlocked). dynamic: true + ##Not necessary if the waypoint doesn't allow dynamic use + ##The conditions for the dynamic-use of the waypoint + conditions: + - 'distance{world=world;x=69;y=71;z=163;distance=500}' + + + linked: + spawn: 4 + spawn2: name: Spawn2 location: 'world 69 71 136 136 0' @@ -70,3 +77,5 @@ spawn2: normal-use: 3 option: enable-menu: false + linked: + spawn: 3