Cache old waypoint providers in memory to enable switching

This commit is contained in:
fullwall 2023-07-04 00:16:22 +08:00
parent 58655fc45e
commit d39c198956
6 changed files with 56 additions and 46 deletions

View File

@ -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

View File

@ -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) {

View File

@ -1,7 +0,0 @@
package net.citizensnpcs.trait.waypoint;
import org.bukkit.Location;
public interface Locatable {
public Location getLocation();
}

View File

@ -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<PhTreeSolid<Boolean>>, Function<NPC, Location> {
public class WanderWaypointProvider implements WaypointProvider {
private WanderGoal currentGoal;
@Persist
public int delay = -1;
@ -53,7 +50,7 @@ public class WanderWaypointProvider
private final List<Location> regionCentres = Lists.newArrayList();
private PhTreeSolid<Boolean> 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<Boolean> get() {
return regionCentres.isEmpty() ? null : tree;
}
public List<Location> 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 };

View File

@ -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();
}

View File

@ -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<String, WaypointProvider> providerCache = Maps.newHashMap();
private String providerName = "linear";
public Waypoints() {
super("waypoints");
}
private WaypointProvider create(Class<? extends WaypointProvider> clazz) {
try {
return clazz.newInstance();
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
private WaypointProvider create(String name, Class<? extends WaypointProvider> 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<String, Class<? extends WaypointProvider>> entry : PROVIDERS.entrySet()) {
if (entry.getKey().equals(providerName)) {
provider = create(entry.getValue());
break;
}
}
Class<? extends WaypointProvider> 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()) {