From d39c19895635837ae14ca897667d2576b7fabb9f Mon Sep 17 00:00:00 2001 From: fullwall Date: Tue, 4 Jul 2023 00:16:22 +0800 Subject: [PATCH] Cache old waypoint providers in memory to enable switching --- .../waypoint/GuidedWaypointProvider.java | 4 +++ .../waypoint/LinearWaypointProvider.java | 31 ++++++++++++++++--- .../trait/waypoint/Locatable.java | 7 ----- .../waypoint/WanderWaypointProvider.java | 29 +++++++---------- .../citizensnpcs/trait/waypoint/Waypoint.java | 3 +- .../trait/waypoint/Waypoints.java | 28 ++++++++--------- 6 files changed, 56 insertions(+), 46 deletions(-) delete mode 100644 main/src/main/java/net/citizensnpcs/trait/waypoint/Locatable.java diff --git a/main/src/main/java/net/citizensnpcs/trait/waypoint/GuidedWaypointProvider.java b/main/src/main/java/net/citizensnpcs/trait/waypoint/GuidedWaypointProvider.java index 1531e2dde..672fba8ae 100644 --- a/main/src/main/java/net/citizensnpcs/trait/waypoint/GuidedWaypointProvider.java +++ b/main/src/main/java/net/citizensnpcs/trait/waypoint/GuidedWaypointProvider.java @@ -235,7 +235,11 @@ public class GuidedWaypointProvider implements EnumerableWaypointProvider { @Override public void onRemove() { + if (currentGoal == null) + return; + currentGoal.onProviderChanged(); npc.getDefaultGoalController().removeGoal(currentGoal); + currentGoal = null; } @Override diff --git a/main/src/main/java/net/citizensnpcs/trait/waypoint/LinearWaypointProvider.java b/main/src/main/java/net/citizensnpcs/trait/waypoint/LinearWaypointProvider.java index 3dc83c19b..c1a8cbfbf 100644 --- a/main/src/main/java/net/citizensnpcs/trait/waypoint/LinearWaypointProvider.java +++ b/main/src/main/java/net/citizensnpcs/trait/waypoint/LinearWaypointProvider.java @@ -76,6 +76,10 @@ public class LinearWaypointProvider implements EnumerableWaypointProvider { } } + public boolean cachePaths() { + return cachePaths; + } + @Override public WaypointEditor createEditor(CommandSender sender, CommandContext args) { if (args.hasFlag('h')) { @@ -119,6 +123,10 @@ public class LinearWaypointProvider implements EnumerableWaypointProvider { return new LinearWaypointEditor((Player) sender); } + public boolean cycleWaypoints() { + return cycle; + } + public Waypoint getCurrentWaypoint() { if (currentGoal != null && currentGoal.currentDestination != null) { return currentGoal.currentDestination; @@ -143,10 +151,11 @@ public class LinearWaypointProvider implements EnumerableWaypointProvider { @Override public void onRemove() { - if (currentGoal != null) { - npc.getDefaultGoalController().removeGoal(currentGoal); - currentGoal = null; - } + if (currentGoal == null) + return; + currentGoal.onProviderChanged(); + npc.getDefaultGoalController().removeGoal(currentGoal); + currentGoal = null; } @Override @@ -167,6 +176,20 @@ public class LinearWaypointProvider implements EnumerableWaypointProvider { } } + public void setCachePaths(boolean cachePaths) { + this.cachePaths = cachePaths; + if (currentGoal != null) { + currentGoal.onProviderChanged(); + } + } + + public void setCycle(boolean cycle) { + this.cycle = cycle; + if (currentGoal != null) { + currentGoal.onProviderChanged(); + } + } + @Override public void setPaused(boolean paused) { if (currentGoal != null) { diff --git a/main/src/main/java/net/citizensnpcs/trait/waypoint/Locatable.java b/main/src/main/java/net/citizensnpcs/trait/waypoint/Locatable.java deleted file mode 100644 index 445dcda4d..000000000 --- a/main/src/main/java/net/citizensnpcs/trait/waypoint/Locatable.java +++ /dev/null @@ -1,7 +0,0 @@ -package net.citizensnpcs.trait.waypoint; - -import org.bukkit.Location; - -public interface Locatable { - public Location getLocation(); -} \ No newline at end of file diff --git a/main/src/main/java/net/citizensnpcs/trait/waypoint/WanderWaypointProvider.java b/main/src/main/java/net/citizensnpcs/trait/waypoint/WanderWaypointProvider.java index c46b90d53..c6ae19a7c 100644 --- a/main/src/main/java/net/citizensnpcs/trait/waypoint/WanderWaypointProvider.java +++ b/main/src/main/java/net/citizensnpcs/trait/waypoint/WanderWaypointProvider.java @@ -3,7 +3,6 @@ package net.citizensnpcs.trait.waypoint; import java.util.Collection; import java.util.Iterator; import java.util.List; -import java.util.function.Function; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -16,7 +15,6 @@ import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.metadata.FixedMetadataValue; -import com.google.common.base.Supplier; import com.google.common.collect.ForwardingList; import com.google.common.collect.Lists; import com.sk89q.worldedit.bukkit.BukkitAdapter; @@ -40,8 +38,7 @@ import net.citizensnpcs.util.Util; * A wandering waypoint provider that wanders between either a box centered at the current location or inside a region * defined by a list of boxes. */ -public class WanderWaypointProvider - implements WaypointProvider, Supplier>, Function { +public class WanderWaypointProvider implements WaypointProvider { private WanderGoal currentGoal; @Persist public int delay = -1; @@ -53,7 +50,7 @@ public class WanderWaypointProvider private final List regionCentres = Lists.newArrayList(); private PhTreeSolid tree = PhTreeSolid.create(3); @Persist - private String worldguardRegion; + public String worldguardRegion; private Object worldguardRegionCache; @Persist public int xrange = DEFAULT_XRANGE; @@ -70,12 +67,6 @@ public class WanderWaypointProvider recalculateTree(); } - @Override - public Location apply(NPC npc) { - return MinecraftBlockExaminer.findValidLocation(npc.getStoredLocation(), xrange, yrange, - currentGoal.blockFilter()); - } - @Override public WaypointEditor createEditor(final CommandSender sender, CommandContext args) { return new WaypointEditor() { @@ -221,11 +212,6 @@ public class WanderWaypointProvider }; } - @Override - public PhTreeSolid get() { - return regionCentres.isEmpty() ? null : tree; - } - public List getRegionCentres() { return new RecalculateList(); } @@ -259,14 +245,22 @@ public class WanderWaypointProvider @Override public void onRemove() { + worldguardRegionCache = null; + if (currentGoal == null) + return; + currentGoal.pause(); npc.getDefaultGoalController().removeGoal(currentGoal); + currentGoal = null; } @Override public void onSpawn(NPC npc) { this.npc = npc; if (currentGoal == null) { - currentGoal = WanderGoal.builder(npc).xrange(xrange).yrange(yrange).fallback(this).tree(this).delay(delay) + currentGoal = WanderGoal.builder(npc).xrange(xrange).yrange(yrange) + .fallback(n -> MinecraftBlockExaminer.findValidLocation(n.getStoredLocation(), xrange, yrange, + currentGoal.blockFilter())) + .tree(() -> regionCentres.isEmpty() ? null : tree).delay(delay) .worldguardRegion(() -> getWorldGuardRegion()).build(); if (paused) { currentGoal.pause(); @@ -282,7 +276,6 @@ public class WanderWaypointProvider } private void recalculateTree() { - tree.clear(); tree = PhTreeSolid.create(3); for (Location loc : regionCentres) { long[] lower = { loc.getBlockX() - xrange, loc.getBlockY() - yrange, loc.getBlockZ() - xrange }; diff --git a/main/src/main/java/net/citizensnpcs/trait/waypoint/Waypoint.java b/main/src/main/java/net/citizensnpcs/trait/waypoint/Waypoint.java index 8847ac534..d8ac67e5e 100644 --- a/main/src/main/java/net/citizensnpcs/trait/waypoint/Waypoint.java +++ b/main/src/main/java/net/citizensnpcs/trait/waypoint/Waypoint.java @@ -22,7 +22,7 @@ import net.citizensnpcs.util.Messages; /** * Represents a {@link Location} with a number of {@link WaypointTrigger}s that activate on reaching the location. */ -public class Waypoint implements Locatable { +public class Waypoint { @Persist(required = true) private Location location; @Persist @@ -90,7 +90,6 @@ public class Waypoint implements Locatable { return true; } - @Override public Location getLocation() { return location.clone(); } diff --git a/main/src/main/java/net/citizensnpcs/trait/waypoint/Waypoints.java b/main/src/main/java/net/citizensnpcs/trait/waypoint/Waypoints.java index 1a294350a..13289c429 100644 --- a/main/src/main/java/net/citizensnpcs/trait/waypoint/Waypoints.java +++ b/main/src/main/java/net/citizensnpcs/trait/waypoint/Waypoints.java @@ -1,7 +1,6 @@ package net.citizensnpcs.trait.waypoint; import java.util.Map; -import java.util.Map.Entry; import org.bukkit.command.CommandSender; @@ -21,19 +20,22 @@ import net.citizensnpcs.util.StringHelper; @TraitName("waypoints") public class Waypoints extends Trait { private WaypointProvider provider; + private final Map providerCache = Maps.newHashMap(); private String providerName = "linear"; public Waypoints() { super("waypoints"); } - private WaypointProvider create(Class clazz) { - try { - return clazz.newInstance(); - } catch (Exception ex) { - ex.printStackTrace(); - return null; - } + private WaypointProvider create(String name, Class clazz) { + return providerCache.computeIfAbsent(name, s -> { + try { + return clazz.newInstance(); + } catch (Exception ex) { + ex.printStackTrace(); + return null; + } + }); } public void describeProviders(CommandSender sender) { @@ -67,12 +69,8 @@ public class Waypoints extends Trait { public void load(DataKey key) throws NPCLoadException { provider = null; providerName = key.getString("provider", "linear"); - for (Entry> entry : PROVIDERS.entrySet()) { - if (entry.getKey().equals(providerName)) { - provider = create(entry.getValue()); - break; - } - } + Class clazz = PROVIDERS.get(providerName); + provider = create(providerName, clazz); if (provider == null) return; PersistenceLoader.load(provider, key.getRelative(providerName)); @@ -114,7 +112,7 @@ public class Waypoints extends Trait { if (provider != null) { provider.onRemove(); } - if (clazz == null || (provider = create(clazz)) == null) + if (clazz == null || (provider = create(name, clazz)) == null) return false; providerName = name; if (npc != null && npc.isSpawned()) {