Waypoints cleanup

This commit is contained in:
Indyuce 2022-05-23 11:10:02 +02:00
parent e9aa71b616
commit 758caf747d
10 changed files with 210 additions and 247 deletions

View File

@ -43,12 +43,8 @@
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId> <artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version> <version>2.3.1</version>
<configuration>
<outputDirectory>C:\Users\guill\Minecraft Server\Server\plugins</outputDirectory>
</configuration>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>

View File

@ -8,11 +8,10 @@ import net.Indyuce.mmocore.gui.api.GeneratedInventory;
import net.Indyuce.mmocore.gui.api.item.InventoryItem; import net.Indyuce.mmocore.gui.api.item.InventoryItem;
import net.Indyuce.mmocore.gui.api.item.Placeholders; import net.Indyuce.mmocore.gui.api.item.Placeholders;
import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem; import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
import net.Indyuce.mmocore.waypoint.CostType;
import net.Indyuce.mmocore.waypoint.Waypoint; import net.Indyuce.mmocore.waypoint.Waypoint;
import net.Indyuce.mmocore.waypoint.WaypointOption; import net.Indyuce.mmocore.waypoint.WaypointPath;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit; import org.bukkit.ChatColor;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
@ -21,8 +20,12 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType; import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.Nullable;
import java.util.*; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class WaypointViewer extends EditableInventory { public class WaypointViewer extends EditableInventory {
public WaypointViewer() { public WaypointViewer() {
@ -68,7 +71,6 @@ public class WaypointViewer extends EditableInventory {
private final SimplePlaceholderItem noWaypoint, locked; private final SimplePlaceholderItem noWaypoint, locked;
private final WaypointItemHandler availWaypoint, noStellium, notLinked, notDynamic, currentWayPoint; private final WaypointItemHandler availWaypoint, noStellium, notLinked, notDynamic, currentWayPoint;
public WaypointItem(ConfigurationSection config) { public WaypointItem(ConfigurationSection config) {
super(Material.BARRIER, config); super(Material.BARRIER, config);
@ -80,7 +82,6 @@ public class WaypointViewer extends EditableInventory {
Validate.notNull(config.getConfigurationSection("not-enough-stellium"), "Could not load 'not-enough-stellium' 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"); Validate.notNull(config.getConfigurationSection("display"), "Could not load 'display' config");
noWaypoint = new SimplePlaceholderItem(config.getConfigurationSection("no-waypoint")); noWaypoint = new SimplePlaceholderItem(config.getConfigurationSection("no-waypoint"));
locked = new SimplePlaceholderItem(config.getConfigurationSection("locked")); locked = new SimplePlaceholderItem(config.getConfigurationSection("locked"));
notLinked = new WaypointItemHandler(config.getConfigurationSection("not-a-destination"), true); notLinked = new WaypointItemHandler(config.getConfigurationSection("not-a-destination"), true);
@ -107,7 +108,6 @@ public class WaypointViewer extends EditableInventory {
if (inv.current != null && inv.current.equals(waypoint)) if (inv.current != null && inv.current.equals(waypoint))
return currentWayPoint.display(inv, n); return currentWayPoint.display(inv, n);
if (!inv.getPlayerData().hasWaypoint(waypoint)) if (!inv.getPlayerData().hasWaypoint(waypoint))
return locked.display(inv, n); return locked.display(inv, n);
@ -115,7 +115,6 @@ public class WaypointViewer extends EditableInventory {
if (inv.current != null && !inv.paths.containsKey(waypoint)) if (inv.current != null && !inv.paths.containsKey(waypoint))
return notLinked.display(inv, n); return notLinked.display(inv, n);
// Not dynamic waypoint // Not dynamic waypoint
if (inv.current == null && !inv.paths.containsKey(waypoint)) if (inv.current == null && !inv.paths.containsKey(waypoint))
return notDynamic.display(inv, n); return notDynamic.display(inv, n);
@ -124,7 +123,6 @@ public class WaypointViewer extends EditableInventory {
if (inv.paths.get(waypoint).getCost() > inv.getPlayerData().getStellium()) if (inv.paths.get(waypoint).getCost() > inv.getPlayerData().getStellium())
return noStellium.display(inv, n); return noStellium.display(inv, n);
return availWaypoint.display(inv, n); return availWaypoint.display(inv, n);
} }
} }
@ -144,6 +142,16 @@ public class WaypointViewer extends EditableInventory {
// If a player can teleport to another waypoint given his location // 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); Waypoint waypoint = inv.waypoints.get(inv.page * inv.getEditable().getByFunction("waypoint").getSlots().size() + n);
ItemMeta meta = disp.getItemMeta(); ItemMeta meta = disp.getItemMeta();
// Add waypoint lore if not empty
if (!waypoint.getLore().isEmpty()) {
List<String> lore = meta.getLore();
Placeholders placeholders = new Placeholders();
for (String str : waypoint.getLore())
lore.add(0, ChatColor.GRAY + placeholders.apply(inv.getPlayer(), str));
meta.setLore(lore);
}
PersistentDataContainer container = meta.getPersistentDataContainer(); PersistentDataContainer container = meta.getPersistentDataContainer();
container.set(new NamespacedKey(MMOCore.plugin, "waypointId"), PersistentDataType.STRING, waypoint.getId()); container.set(new NamespacedKey(MMOCore.plugin, "waypointId"), PersistentDataType.STRING, waypoint.getId());
disp.setItemMeta(meta); disp.setItemMeta(meta);
@ -160,7 +168,7 @@ public class WaypointViewer extends EditableInventory {
holders.register("current_cost", inv.paths.get(waypoint).getCost()); 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("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("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"); holders.register("intermediary_waypoints", inv.paths.containsKey(waypoint) ? inv.paths.get(waypoint).displayIntermediaryWayPoints(inv.isDynamicUse()) : "None");
} }
return holders; return holders;
@ -169,9 +177,9 @@ public class WaypointViewer extends EditableInventory {
public class WaypointViewerInventory extends GeneratedInventory { public class WaypointViewerInventory extends GeneratedInventory {
private final List<Waypoint> waypoints = new ArrayList<>(MMOCore.plugin.waypointManager.getAll()); private final List<Waypoint> waypoints = new ArrayList<>(MMOCore.plugin.waypointManager.getAll());
@Nullable
private final Waypoint current; private final Waypoint current;
private final Map<Waypoint, Waypoint.PathInfo> paths = new HashMap<>(); private final Map<Waypoint, WaypointPath> paths = new HashMap<>();
private final CostType waypointCostType;
private int page; private int page;
@ -179,32 +187,29 @@ public class WaypointViewer extends EditableInventory {
super(playerData, editable); super(playerData, editable);
this.current = current; this.current = current;
if (current != null) { if (current != null)
for (Waypoint.PathInfo pathInfo : current.getAllPath()) for (WaypointPath pathInfo : current.getAllPath())
paths.put(pathInfo.getFinalWaypoint(), pathInfo); paths.put(pathInfo.getFinalWaypoint(), pathInfo);
}
if (current == null) { if (current == null) {
//Iterate through all the dynamic points and find all the points it is linked to and the path //Iterate through all the dynamic points and find all the points it is linked to and the path
HashMap<Waypoint, Double> dynamicPoints = new HashMap<>(); HashMap<Waypoint, Double> dynamicPoints = new HashMap<>();
//We first check all the dynamic waypoints //We first check all the dynamic waypoints
for (Waypoint waypoint : waypoints) { for (Waypoint waypoint : waypoints) {
if (waypoint.canHaveDynamicUse(playerData.getPlayer())) { if (waypoint.mayBeUsedDynamically(playerData.getPlayer())) {
paths.put(waypoint, new Waypoint.PathInfo(waypoint, waypoint.getDynamicCost())); paths.put(waypoint, new WaypointPath(waypoint, waypoint.getDynamicCost()));
dynamicPoints.put(waypoint, waypoint.getDynamicCost()); dynamicPoints.put(waypoint, waypoint.getDynamicCost());
} }
} }
for (Waypoint source : dynamicPoints.keySet()) { for (Waypoint source : dynamicPoints.keySet()) {
for (Waypoint.PathInfo target : source.getAllPath()) { for (WaypointPath target : source.getAllPath()) {
if (!paths.containsKey(target.getFinalWaypoint()) || paths.get(target.getFinalWaypoint()).getCost() > target.getCost() + dynamicPoints.get(source)) { if (!paths.containsKey(target.getFinalWaypoint()) || paths.get(target.getFinalWaypoint()).getCost() > target.getCost() + dynamicPoints.get(source)) {
paths.put(target.getFinalWaypoint(), target.addCost(dynamicPoints.get(source))); paths.put(target.getFinalWaypoint(), target.addCost(dynamicPoints.get(source)));
} }
} }
} }
} }
this.waypointCostType = current == null ? CostType.DYNAMIC_USE : CostType.NORMAL_USE;
} }
@Override @Override
@ -212,6 +217,10 @@ public class WaypointViewer extends EditableInventory {
return getName(); return getName();
} }
public boolean isDynamicUse() {
return current == null;
}
@Override @Override
public void whenClicked(InventoryClickEvent event, InventoryItem item) { public void whenClicked(InventoryClickEvent event, InventoryItem item) {
if (item.getFunction().equals("next")) { if (item.getFunction().equals("next")) {
@ -260,7 +269,6 @@ public class WaypointViewer extends EditableInventory {
} }
// Stellium cost // Stellium cost
CostType costType = current == null ? CostType.DYNAMIC_USE : CostType.NORMAL_USE;
double withdraw = paths.get(waypoint).getCost(); double withdraw = paths.get(waypoint).getCost();
double left = withdraw - playerData.getStellium(); double left = withdraw - playerData.getStellium();
if (left > 0) { if (left > 0) {

View File

@ -35,7 +35,7 @@ public class LootChestRegion {
} }
}; };
private static final Random random = new Random(); private static final Random RANDOM = new Random();
public LootChestRegion(ConfigurationSection config) { public LootChestRegion(ConfigurationSection config) {
Validate.notNull(config, "Could not load config"); Validate.notNull(config, "Could not load config");
@ -110,7 +110,7 @@ public class LootChestRegion {
location.getBlock().setType(Material.CHEST); location.getBlock().setType(Material.CHEST);
Chest chest = (Chest) location.getBlock().getState(); Chest chest = (Chest) location.getBlock().getState();
tier.getDropTable().collect(builder).forEach(item -> { tier.getDropTable().collect(builder).forEach(item -> {
Integer slot = slots.get(random.nextInt(slots.size())); Integer slot = slots.get(RANDOM.nextInt(slots.size()));
chest.getInventory().setItem(slot, item); chest.getInventory().setItem(slot, item);
slots.remove(slot); slots.remove(slot);
}); });
@ -135,7 +135,7 @@ public class LootChestRegion {
double cummulated = 0; double cummulated = 0;
for (ChestTier tier : tiers) { for (ChestTier tier : tiers) {
cummulated += getTierCoefficient(tier.getChance(), chance); cummulated += getTierCoefficient(tier.getChance(), chance);
if (random.nextDouble() < cummulated / sum) if (RANDOM.nextDouble() < cummulated / sum)
return tier; return tier;
} }
@ -175,9 +175,9 @@ public class LootChestRegion {
* Chooses a random direction and get the block in * Chooses a random direction and get the block in
* that direction which has the same height as the player * that direction which has the same height as the player
*/ */
double a = random.nextDouble() * 2 * Math.PI; double a = RANDOM.nextDouble() * 2 * Math.PI;
Vector dir = new Vector(Math.cos(a), 0, Math.sin(a)) Vector dir = new Vector(Math.cos(a), 0, Math.sin(a))
.multiply(algOptions.minRange + random.nextDouble() * (algOptions.maxRange - algOptions.minRange)); .multiply(algOptions.minRange + RANDOM.nextDouble() * (algOptions.maxRange - algOptions.minRange));
Location random = center.add(dir); Location random = center.add(dir);
/* /*

View File

@ -55,5 +55,12 @@ public class WaypointManager implements MMOCoreManager {
} catch (RuntimeException exception) { } catch (RuntimeException exception) {
MMOCore.log(Level.WARNING, "Could not load waypoint '" + key + "': " + exception.getMessage()); MMOCore.log(Level.WARNING, "Could not load waypoint '" + key + "': " + exception.getMessage());
} }
for (Waypoint waypoint : waypoints.values())
try {
waypoint.postLoad();
} catch (RuntimeException exception) {
MMOCore.log(Level.WARNING, "Could not post-load waypoint '" + waypoint.getId() + "': " + exception.getMessage());
}
} }
} }

View File

@ -1,30 +0,0 @@
package net.Indyuce.mmocore.waypoint;
public enum CostType {
/**
* When teleporting to this waypoint
*/
NORMAL_USE,
/**
* When dynamically teleporting to this waypoint
*/
DYNAMIC_USE,
/**
* When setting your spawn point to this waypoint.
*/
// SET_SPAWNPOINT
;
private final String path;
CostType() {
this.path = name().toLowerCase().replace("_", "-");
}
public String getPath() {
return path;
}
}

View File

@ -1,6 +1,7 @@
package net.Indyuce.mmocore.waypoint; package net.Indyuce.mmocore.waypoint;
import io.lumine.mythic.lib.api.MMOLineConfig; import io.lumine.mythic.lib.api.MMOLineConfig;
import io.lumine.mythic.lib.api.util.PostLoadObject;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.loot.chest.condition.Condition; import net.Indyuce.mmocore.loot.chest.condition.Condition;
import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance; import net.Indyuce.mmocore.loot.chest.condition.ConditionInstance;
@ -12,12 +13,15 @@ import org.bukkit.World;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.craftbukkit.libs.jline.internal.Nullable; import org.bukkit.craftbukkit.libs.jline.internal.Nullable;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.*; import java.util.*;
import java.util.logging.Level;
public class Waypoint implements Unlockable { public class Waypoint extends PostLoadObject implements Unlockable {
private final String id, name; private final String id, name;
private final Location loc; private final Location loc;
private final List<String> lore;
private final double radiusSquared; private final double radiusSquared;
/** /**
@ -26,36 +30,21 @@ public class Waypoint implements Unlockable {
* <p> * <p>
* If it's empty it can access any waypoint. * If it's empty it can access any waypoint.
*/ */
private final Map<String, Integer> destinations = new HashMap<>(); private final Map<Waypoint, Integer> destinations = new HashMap<>();
/** /**
* Waypoint options saved here. * Waypoint options saved here.
*/ */
private final Map<WaypointOption, Boolean> options = new HashMap<>(); private final Map<WaypointOption, Boolean> options = new HashMap<>();
/**
* Stellium cost for each action (0 being the default cost)
*/
private final double dynamicCost, setSpawnCost; private final double dynamicCost, setSpawnCost;
private final ArrayList<Condition> dynamicUseConditions = new ArrayList<>(); private final List<Condition> dynamicUseConditions = new ArrayList<>();
private final Map<CostType, Double> 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) { public Waypoint(ConfigurationSection config) {
super(config);
id = Objects.requireNonNull(config, "Could not load config section").getName(); id = Objects.requireNonNull(config, "Could not load config section").getName();
name = Objects.requireNonNull(config.getString("name"), "Could not load waypoint name"); name = Objects.requireNonNull(config.getString("name"), "Could not load waypoint name");
lore = Objects.requireNonNullElse(config.getStringList("lore"), new ArrayList<>());
loc = readLocation(Objects.requireNonNull(config.getString("location"), "Could not read location")); loc = readLocation(Objects.requireNonNull(config.getString("location"), "Could not read location"));
radiusSquared = Math.pow(config.getDouble("radius"), 2); radiusSquared = Math.pow(config.getDouble("radius"), 2);
@ -63,37 +52,30 @@ public class Waypoint implements Unlockable {
dynamicCost = config.getDouble("cost.dynamic-use"); dynamicCost = config.getDouble("cost.dynamic-use");
setSpawnCost = config.getDouble("cost.set-spawnpoint"); setSpawnCost = config.getDouble("cost.set-spawnpoint");
for (WaypointOption option : WaypointOption.values()) for (WaypointOption option : WaypointOption.values())
options.put(option, config.getBoolean("option." + option.getPath(), option.getDefaultValue())); options.put(option, config.getBoolean("option." + option.getPath(), option.getDefaultValue()));
//We load all the linked WayPoints if (config.contains("dynamic-conditions")) {
List<String> conditions = config.getStringList("dynamic-conditions");
for (String condition : conditions)
try {
dynamicUseConditions.add(MMOCore.plugin.loadManager.loadCondition(new MMOLineConfig(condition)));
} catch (RuntimeException exception) {
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not load condition '" + condition + "' from waypoint '" + id + "': " + exception.getMessage());
}
}
}
@Override
protected void whenPostLoaded(@NotNull ConfigurationSection config) {
// Load waypoint network
if (config.contains("linked")) { if (config.contains("linked")) {
ConfigurationSection section = config.getConfigurationSection("linked"); ConfigurationSection section = config.getConfigurationSection("linked");
for (String key : section.getKeys(false)) { for (String key : section.getKeys(false))
destinations.put(key, section.getInt(key)); destinations.put(MMOCore.plugin.waypointManager.get(key), section.getInt(key));
} }
} }
if (config.contains("conditions")) {
List<String> 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() { public String getId() {
return id; return id;
@ -103,71 +85,85 @@ public class Waypoint implements Unlockable {
return name; return name;
} }
public List<String> getLore() {
return lore;
}
public Location getLocation() { public Location getLocation() {
return loc; return loc;
} }
/** /**
* @param other Another waypoint * @param other Another waypoint
* @return If any player standing on that waypoint can teleport to given waypoint * @return If any player standing on that waypoint can teleport to given waypoint
*/ */
@Deprecated @Deprecated
public boolean hasDestination(Waypoint other) { public boolean hasDestination(Waypoint other) {
return destinations.isEmpty() || destinations.keySet().contains(other.getId()); return destinations.isEmpty() || destinations.containsKey(other);
}
public double getDynamicCost() {
return dynamicCost;
}
public double getSetSpawnCost() {
return setSpawnCost;
}
public boolean mayBeUsedDynamically(Player player) {
if (!options.get(WaypointOption.DYNAMIC))
return false;
for (Condition condition : dynamicUseConditions)
if (!condition.isMet(new ConditionInstance(player)))
return false;
return true;
} }
/** /**
* Checks directly if the waypoint is directly linked to the current one
*
* @return Integer.POSITIVE_INFINITY if the way point is not linked * @return Integer.POSITIVE_INFINITY if the way point is not linked
* If it is, cost of the instant travel between the two waypoints.
*/ */
private int getSimpleCostDestination(Waypoint waypoint) { public int getDirectCost(Waypoint waypoint) {
if (!destinations.keySet().contains(waypoint.getId())) return destinations.getOrDefault(waypoint, Integer.MAX_VALUE);
return Integer.MAX_VALUE;
return destinations.get(waypoint.getId());
} }
public List<WaypointPath> getAllPath() {
public ArrayList<PathInfo> getAllPath() {
//All the WayPoints that have been registered //All the WayPoints that have been registered
ArrayList<Waypoint> checkedPoints = new ArrayList<>(); List<Waypoint> checkedPoints = new ArrayList<>();
//All the path //All the path
ArrayList<PathInfo> paths = new ArrayList(); List<WaypointPath> paths = new ArrayList();
ArrayList<PathInfo> pointsToCheck = new ArrayList<>(); List<WaypointPath> pointsToCheck = new ArrayList<>();
pointsToCheck.add(new PathInfo(this)); pointsToCheck.add(new WaypointPath(this));
while (pointsToCheck.size() != 0) { while (pointsToCheck.size() != 0) {
PathInfo checked = pointsToCheck.get(0); WaypointPath checked = pointsToCheck.get(0);
pointsToCheck.remove(0); pointsToCheck.remove(0);
paths.add(checked); paths.add(checked);
checkedPoints.add(checked.getFinalWaypoint()); checkedPoints.add(checked.getFinalWaypoint());
for (String wayPointId : checked.getFinalWaypoint().destinations.keySet()) { for (Waypoint toCheck : checked.getFinalWaypoint().destinations.keySet())
Waypoint toCheck = MMOCore.plugin.waypointManager.get(wayPointId);
if (!checkedPoints.contains(toCheck)) { if (!checkedPoints.contains(toCheck)) {
PathInfo toCheckInfo = checked.addWayPoint(toCheck); WaypointPath toCheckInfo = checked.addWayPoint(toCheck);
// We keep pointsToCheck ordered // We keep pointsToCheck ordered
pointsToCheck = toCheckInfo.addInOrder(pointsToCheck); pointsToCheck = toCheckInfo.addInOrder(pointsToCheck);
} }
} }
}
return paths; return paths;
} }
@Nullable @Nullable
public PathInfo getPath(Waypoint targetWaypoint) { public WaypointPath getPath(Waypoint targetWaypoint) {
//All the WayPoints that have been registered //All the WayPoints that have been registered
ArrayList<Waypoint> checkedPoints = new ArrayList<>(); List<Waypoint> checkedPoints = new ArrayList<>();
//All the path //All the path
ArrayList<PathInfo> paths = new ArrayList(); List<WaypointPath> paths = new ArrayList();
ArrayList<PathInfo> pointsToCheck = new ArrayList<>(); List<WaypointPath> pointsToCheck = new ArrayList<>();
pointsToCheck.add(new PathInfo(this)); pointsToCheck.add(new WaypointPath(this));
while (pointsToCheck.size() != 0) { while (pointsToCheck.size() != 0) {
PathInfo checked = pointsToCheck.get(0); WaypointPath checked = pointsToCheck.get(0);
pointsToCheck.remove(0); pointsToCheck.remove(0);
paths.add(checked); paths.add(checked);
checkedPoints.add(checked.getFinalWaypoint()); checkedPoints.add(checked.getFinalWaypoint());
@ -175,19 +171,16 @@ public class Waypoint implements Unlockable {
if (checked.getFinalWaypoint().equals(targetWaypoint)) if (checked.getFinalWaypoint().equals(targetWaypoint))
return checked; return checked;
for (String wayPointId : checked.getFinalWaypoint().destinations.keySet()) { for (Waypoint toCheck : checked.getFinalWaypoint().destinations.keySet())
Waypoint toCheck = MMOCore.plugin.waypointManager.get(wayPointId);
if (!checkedPoints.contains(toCheck)) { if (!checkedPoints.contains(toCheck)) {
PathInfo toCheckInfo = checked.addWayPoint(toCheck); WaypointPath toCheckInfo = checked.addWayPoint(toCheck);
// We keep pointsToCheck ordered // We keep pointsToCheck ordered
pointsToCheck = toCheckInfo.addInOrder(pointsToCheck); pointsToCheck = toCheckInfo.addInOrder(pointsToCheck);
} }
} }
}
//If no path has been found we return null //If no path has been found we return null
return null; return null;
} }
public boolean hasOption(WaypointOption option) { public boolean hasOption(WaypointOption option) {
@ -235,96 +228,4 @@ public class Waypoint implements Unlockable {
return new Location(world, x, y, z, yaw, pitch); return new Location(world, x, y, z, yaw, pitch);
} }
public static class PathInfo {
private final ArrayList<Waypoint> waypoints;
private double cost;
public ArrayList<Waypoint> 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<PathInfo> addInOrder(ArrayList<PathInfo> 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<Waypoint> 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<Waypoint> 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);
}
}
} }

View File

@ -0,0 +1,85 @@
package net.Indyuce.mmocore.waypoint;
import java.util.ArrayList;
import java.util.List;
public class WaypointPath {
private final List<Waypoint> waypoints;
private double cost;
public WaypointPath(Waypoint waypoint) {
this.waypoints = new ArrayList<>();
this.waypoints.add(waypoint);
cost = 0;
}
public WaypointPath(Waypoint waypoint, double cost) {
this.waypoints = new ArrayList<>();
this.waypoints.add(waypoint);
this.cost = cost;
}
public WaypointPath(List<Waypoint> waypoints, double cost) {
this.waypoints = new ArrayList<>(waypoints);
this.cost = cost;
}
public List<Waypoint> getWaypoints() {
return waypoints;
}
public double getCost() {
return cost;
}
public WaypointPath addCost(double cost) {
this.cost += cost;
return this;
}
public List<WaypointPath> addInOrder(List<WaypointPath> 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() add the waypoint at the end
pathInfos.add(this);
return pathInfos;
}
/**
* @param dynamic Display the first waypoint if it is dynamic as it is an intermediary point
* @return List with all
*/
public String displayIntermediaryWayPoints(boolean dynamic) {
int beginIndex = dynamic ? 0 : 1;
if (waypoints.size() <= beginIndex + 1)
return "None";
String result = "";
for (int i = beginIndex; i < waypoints.size() - 1; i++)
result += waypoints.get(i).getName() + (i != waypoints.size() - 2 ? ", " : "");
return result;
}
public WaypointPath addWayPoint(Waypoint waypoint) {
List<Waypoint> newWaypoints = new ArrayList<>();
newWaypoints.addAll(waypoints);
newWaypoints.add(waypoint);
double cost = this.cost + getFinalWaypoint().getDirectCost(waypoint);
return new WaypointPath(newWaypoints, cost);
}
public Waypoint getInitialWaypoint() {
return waypoints.get(0);
}
public Waypoint getFinalWaypoint() {
return waypoints.get(waypoints.size() - 1);
}
}

View File

@ -59,7 +59,7 @@ items:
lore: lore:
- '&7You cannot teleport as you do not have enough Stellium.' - '&7You cannot teleport as you do not have enough Stellium.'
- '&7Teleporting costs &b&l{normal_cost}&7/&b&l{dynamic_cost} &7Stellium.' - '&7Teleporting costs &b{normal_cost}&7/&b{dynamic_cost} &7Stellium.'
# Displayed when the waypoint is unlocked and usable # Displayed when the waypoint is unlocked and usable
display: display:

View File

@ -12,11 +12,11 @@ spawn:
# Radius of waypoint around the specified location. # Radius of waypoint around the specified location.
radius: 2.0 radius: 2.0
lore: {}
# Cost for several specific actions
cost: cost:
# 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.
# Cost when not standing on any waypoint. # Cost when not standing on any waypoint.
dynamic-use: 5 dynamic-use: 5
@ -46,13 +46,11 @@ spawn:
spawn1: 4 spawn1: 4
spawn2: 5 spawn2: 5
spawn1: spawn1:
name: Spawn1 name: Spawn1
location: 'world 69 71 136 136 0' location: 'world 69 71 136 136 0'
radius: 2.0 radius: 2.0
cost: lore: {}
normal-use: 3
option: option:
default: false default: false
@ -60,21 +58,19 @@ spawn1:
# on any waypoint (waypoint must be unlocked). # on any waypoint (waypoint must be unlocked).
dynamic: true dynamic: true
##Not necessary if the waypoint doesn't allow dynamic use # Not necessary if the waypoint doesn't allow dynamic use
##The conditions for the dynamic-use of the waypoint # The conditions for the dynamic-use of the waypoint
conditions: dynamic-conditions:
- 'distance{world=world;x=69;y=71;z=163;distance=500}' - 'distance{world=world;x=69;y=71;z=163;distance=500}'
linked: linked:
spawn: 4 spawn: 4
spawn2: spawn2:
name: Spawn2 name: Spawn2
lore: {}
location: 'world 69 71 136 136 0' location: 'world 69 71 136 136 0'
radius: 3.0 radius: 3.0
cost:
normal-use: 3
option: option:
enable-menu: false enable-menu: false
linked: linked: