diff --git a/src/main/java/net/citizensnpcs/trait/Anchors.java b/src/main/java/net/citizensnpcs/trait/Anchors.java index 9dd8ab50d..b3918a2dc 100644 --- a/src/main/java/net/citizensnpcs/trait/Anchors.java +++ b/src/main/java/net/citizensnpcs/trait/Anchors.java @@ -12,9 +12,13 @@ import net.citizensnpcs.util.Messages; import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.world.WorldLoadEvent; +import org.bukkit.event.world.WorldUnloadEvent; public class Anchors extends Trait { - private final List anchors = new ArrayList(); + private List anchors = new ArrayList(); public Anchors() { super("anchors"); @@ -41,14 +45,20 @@ public class Anchors extends Trait { @Override public void load(DataKey key) throws NPCLoadException { - for (DataKey sub : key.getRelative("list").getIntegerSubKeys()) + for (DataKey sub : key.getRelative("list").getIntegerSubKeys()) { + String[] parts = sub.getString("").split(";"); + Location location; try { - String[] parts = sub.getString("").split(";"); - anchors.add(new Anchor(parts[0], new Location(Bukkit.getServer().getWorld(parts[1]), Double - .valueOf(parts[2]), Double.valueOf(parts[3]), Double.valueOf(parts[4])))); + location = new Location(Bukkit.getServer().getWorld(parts[1]), Double + .valueOf(parts[2]), Double.valueOf(parts[3]), Double.valueOf(parts[4])); + anchors.add(new Anchor(parts[0], location)); } catch (NumberFormatException e) { Messaging.logTr(Messages.SKIPPING_INVALID_ANCHOR, sub.name(), e.getMessage()); + } catch (NullPointerException e) { + // Invalid world/location/etc. Still enough data to build an unloaded anchor + anchors.add(new Anchor(parts[0], sub.getString("").split(";", 2)[1])); } + } } public boolean removeAnchor(Anchor anchor) { @@ -65,4 +75,12 @@ public class Anchors extends Trait { for (int i = 0; i < anchors.size(); i++) key.setString("list." + String.valueOf(i), anchors.get(i).stringValue()); } + + @EventHandler + public void checkWorld(WorldLoadEvent event) { + for (Anchor anchor : anchors) + if (!anchor.isLoaded()) + anchor.load(); + } + } diff --git a/src/main/java/net/citizensnpcs/util/Anchor.java b/src/main/java/net/citizensnpcs/util/Anchor.java index 3cd716318..21f1d7d0a 100644 --- a/src/main/java/net/citizensnpcs/util/Anchor.java +++ b/src/main/java/net/citizensnpcs/util/Anchor.java @@ -2,6 +2,7 @@ package net.citizensnpcs.util; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; +import org.bukkit.Bukkit; import org.bukkit.Location; /* @@ -9,12 +10,39 @@ import org.bukkit.Location; */ public class Anchor { - private final Location location; + private Location location; private final String name; + // Needed for Anchors defined that can't currently have a valid 'Location' + private final String unloaded_value; + + // Allow construction of anchor for unloaded worlds + public Anchor(String name, String unloaded_value) { + this.location = null; + this.unloaded_value = unloaded_value; + this.name = name; + } + public Anchor(String name, Location location) { this.location = location; this.name = name; + this.unloaded_value = location.getWorld().getName() + ';' + + location.getX() + ';' + location.getY() + ';' + location.getZ(); + } + + public boolean isLoaded() { + return location != null; + } + + public boolean load() { + try { + String[] parts = getUnloadedValue(); + this.location = new Location(Bukkit.getWorld(parts[0]), + Double.valueOf(parts[1]), Double.valueOf(parts[2]), Double.valueOf(parts[3])); + } catch (Exception e) { + // Still not able to be loaded + } + return location != null; } @Override @@ -27,7 +55,7 @@ public class Anchor { return false; Anchor op = (Anchor) object; - return new EqualsBuilder().append(name, op.getName()).isEquals(); + return new EqualsBuilder().append(name, op.name).isEquals(); } public Location getLocation() { @@ -38,20 +66,30 @@ public class Anchor { return name; } + /** + * Returns a String[] of the 'world_name, x, y, z' information needed to create the Location + * that is associated with the Anchor, in that order. + * + * @return a String array of the anchor's location data + */ + public String[] getUnloadedValue() { + return unloaded_value.split(";"); + } + @Override public int hashCode() { return new HashCodeBuilder(13, 21).append(name).toHashCode(); } + // A friendly representation for use in saves.yml public String stringValue() { - return name + ";" + location.getWorld().getName() + ";" + location.getX() + ";" + location.getY() + ";" - + location.getZ(); + return name + ';' + unloaded_value; } @Override public String toString() { - return "Name: " + name + " World: " + location.getWorld().getName() + " Location: " + location.getBlockX() - + "," + location.getBlockY() + "," + location.getBlockZ(); + String[] parts = getUnloadedValue(); + return "Anchor{Name='" + name + "';World='" + parts[0] + "';Location='" + parts[1] + ',' + parts[2] + ',' + parts[3] + "';}"; } } \ No newline at end of file