lore;
private final double radiusSquared;
/**
@@ -26,36 +30,21 @@ public class Waypoint implements Unlockable {
*
* If it's empty it can access any waypoint.
*/
- private final Map destinations = new HashMap<>();
+ private final Map destinations = new HashMap<>();
/**
* Waypoint options saved here.
*/
private final Map options = new HashMap<>();
-
- /**
- * 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;
- }
+ private final List dynamicUseConditions = new ArrayList<>();
public Waypoint(ConfigurationSection config) {
+ super(config);
+
id = Objects.requireNonNull(config, "Could not load config section").getName();
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"));
radiusSquared = Math.pow(config.getDouble("radius"), 2);
@@ -63,36 +52,29 @@ public class Waypoint implements Unlockable {
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()));
- //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)));
-
- }
-
+ if (config.contains("dynamic-conditions")) {
+ List 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());
+ }
}
}
- public boolean canHaveDynamicUse(Player player) {
- if (!options.get(WaypointOption.DYNAMIC))
- return false;
+ @Override
+ protected void whenPostLoaded(@NotNull ConfigurationSection config) {
- for (Condition condition : dynamicUseConditions) {
- if (!condition.isMet(new ConditionInstance(player)))
- return false;
+ // Load waypoint network
+ if (config.contains("linked")) {
+ ConfigurationSection section = config.getConfigurationSection("linked");
+ for (String key : section.getKeys(false))
+ destinations.put(MMOCore.plugin.waypointManager.get(key), section.getInt(key));
}
- return true;
}
public String getId() {
@@ -103,71 +85,85 @@ public class Waypoint implements Unlockable {
return name;
}
+ public List getLore() {
+ return lore;
+ }
+
public Location getLocation() {
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.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
+ * If it is, cost of the instant travel between the two waypoints.
*/
- private int getSimpleCostDestination(Waypoint waypoint) {
- if (!destinations.keySet().contains(waypoint.getId()))
- return Integer.MAX_VALUE;
- return destinations.get(waypoint.getId());
+ public int getDirectCost(Waypoint waypoint) {
+ return destinations.getOrDefault(waypoint, Integer.MAX_VALUE);
}
-
- public ArrayList getAllPath() {
+ public List getAllPath() {
//All the WayPoints that have been registered
- ArrayList checkedPoints = new ArrayList<>();
+ List checkedPoints = new ArrayList<>();
//All the path
- ArrayList paths = new ArrayList();
- ArrayList pointsToCheck = new ArrayList<>();
- pointsToCheck.add(new PathInfo(this));
+ List paths = new ArrayList();
+ List pointsToCheck = new ArrayList<>();
+ pointsToCheck.add(new WaypointPath(this));
while (pointsToCheck.size() != 0) {
- PathInfo checked = pointsToCheck.get(0);
+ WaypointPath 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);
+ for (Waypoint toCheck : checked.getFinalWaypoint().destinations.keySet())
if (!checkedPoints.contains(toCheck)) {
- PathInfo toCheckInfo = checked.addWayPoint(toCheck);
- //We keep pointsToCheck ordered
+ WaypointPath toCheckInfo = checked.addWayPoint(toCheck);
+ // We keep pointsToCheck ordered
pointsToCheck = toCheckInfo.addInOrder(pointsToCheck);
}
- }
}
return paths;
-
}
-
@Nullable
- public PathInfo getPath(Waypoint targetWaypoint) {
+ public WaypointPath getPath(Waypoint targetWaypoint) {
//All the WayPoints that have been registered
- ArrayList checkedPoints = new ArrayList<>();
+ List checkedPoints = new ArrayList<>();
//All the path
- ArrayList paths = new ArrayList();
- ArrayList pointsToCheck = new ArrayList<>();
- pointsToCheck.add(new PathInfo(this));
+ List paths = new ArrayList();
+ List pointsToCheck = new ArrayList<>();
+ pointsToCheck.add(new WaypointPath(this));
while (pointsToCheck.size() != 0) {
- PathInfo checked = pointsToCheck.get(0);
+ WaypointPath checked = pointsToCheck.get(0);
pointsToCheck.remove(0);
paths.add(checked);
checkedPoints.add(checked.getFinalWaypoint());
@@ -175,19 +171,16 @@ public class Waypoint implements Unlockable {
if (checked.getFinalWaypoint().equals(targetWaypoint))
return checked;
- for (String wayPointId : checked.getFinalWaypoint().destinations.keySet()) {
- Waypoint toCheck = MMOCore.plugin.waypointManager.get(wayPointId);
+ for (Waypoint toCheck : checked.getFinalWaypoint().destinations.keySet())
if (!checkedPoints.contains(toCheck)) {
- PathInfo toCheckInfo = checked.addWayPoint(toCheck);
- //We keep pointsToCheck ordered
+ WaypointPath 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) {
@@ -235,96 +228,4 @@ 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/java/net/Indyuce/mmocore/waypoint/WaypointPath.java b/src/main/java/net/Indyuce/mmocore/waypoint/WaypointPath.java
new file mode 100644
index 00000000..e987eff5
--- /dev/null
+++ b/src/main/java/net/Indyuce/mmocore/waypoint/WaypointPath.java
@@ -0,0 +1,85 @@
+package net.Indyuce.mmocore.waypoint;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class WaypointPath {
+ private final List 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 waypoints, double cost) {
+ this.waypoints = new ArrayList<>(waypoints);
+ this.cost = cost;
+ }
+
+ public List getWaypoints() {
+ return waypoints;
+ }
+
+ public double getCost() {
+ return cost;
+ }
+
+ public WaypointPath addCost(double cost) {
+ this.cost += cost;
+ return this;
+ }
+
+ public List addInOrder(List 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 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);
+ }
+}
diff --git a/src/main/resources/default/gui/waypoints.yml b/src/main/resources/default/gui/waypoints.yml
index cd90f0c8..56ade9b9 100644
--- a/src/main/resources/default/gui/waypoints.yml
+++ b/src/main/resources/default/gui/waypoints.yml
@@ -59,7 +59,7 @@ items:
lore:
- '&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
display:
diff --git a/src/main/resources/default/waypoints.yml b/src/main/resources/default/waypoints.yml
index 1de64a36..cb57e8fc 100644
--- a/src/main/resources/default/waypoints.yml
+++ b/src/main/resources/default/waypoints.yml
@@ -12,11 +12,11 @@ spawn:
# Radius of waypoint around the specified location.
radius: 2.0
+ lore: {}
+
+ # Cost for several specific actions
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.
dynamic-use: 5
@@ -46,13 +46,11 @@ spawn:
spawn1: 4
spawn2: 5
-
spawn1:
name: Spawn1
location: 'world 69 71 136 136 0'
radius: 2.0
- cost:
- normal-use: 3
+ lore: {}
option:
default: false
@@ -60,21 +58,19 @@ 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:
+ # Not necessary if the waypoint doesn't allow dynamic use
+ # The conditions for the dynamic-use of the waypoint
+ dynamic-conditions:
- 'distance{world=world;x=69;y=71;z=163;distance=500}'
-
linked:
spawn: 4
spawn2:
name: Spawn2
+ lore: {}
location: 'world 69 71 136 136 0'
radius: 3.0
- cost:
- normal-use: 3
option:
enable-menu: false
linked: