mirror of
https://github.com/CitizensDev/Citizens2.git
synced 2024-11-27 13:15:33 +01:00
Work on new waypoint provider
This commit is contained in:
parent
d75f380084
commit
42172100ab
@ -176,8 +176,9 @@ public class EventListen implements Listener {
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onEntityDeath(EntityDeathEvent event) {
|
||||
final NPC npc = npcRegistry.getNPC(event.getEntity());
|
||||
if (npc == null)
|
||||
if (npc == null) {
|
||||
return;
|
||||
}
|
||||
Bukkit.getPluginManager().callEvent(new NPCDeathEvent(npc, event));
|
||||
final Location location = npc.getBukkitEntity().getLocation();
|
||||
npc.despawn(DespawnReason.DEATH);
|
||||
|
@ -45,8 +45,9 @@ public class WaypointCommands {
|
||||
if (args.argsLength() == 1) {
|
||||
if (args.hasFlag('d')) {
|
||||
waypoints.describeProviders(sender);
|
||||
} else
|
||||
} else {
|
||||
Messaging.sendTr(sender, Messages.CURRENT_WAYPOINT_PROVIDER, waypoints.getCurrentProviderName());
|
||||
}
|
||||
return;
|
||||
}
|
||||
boolean success = waypoints.setWaypointProvider(args.getString(1));
|
||||
|
@ -0,0 +1,271 @@
|
||||
package net.citizensnpcs.trait.waypoint;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.ai.Goal;
|
||||
import net.citizensnpcs.api.ai.GoalSelector;
|
||||
import net.citizensnpcs.api.ai.event.CancelReason;
|
||||
import net.citizensnpcs.api.ai.event.NavigatorCallback;
|
||||
import net.citizensnpcs.api.astar.AStarGoal;
|
||||
import net.citizensnpcs.api.astar.AStarMachine;
|
||||
import net.citizensnpcs.api.astar.AStarNode;
|
||||
import net.citizensnpcs.api.astar.Agent;
|
||||
import net.citizensnpcs.api.astar.Plan;
|
||||
import net.citizensnpcs.api.command.CommandContext;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.persistence.Persist;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
import net.citizensnpcs.api.util.Messaging;
|
||||
import net.citizensnpcs.util.Messages;
|
||||
import net.citizensnpcs.util.Util;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
public class JeebissFindingWaypointProvider implements WaypointProvider {
|
||||
@Persist("availablewaypoints")
|
||||
private final List<Waypoint> available = Lists.newArrayList();
|
||||
private JeebissFindingWaypointProviderGoal currentGoal;
|
||||
@Persist("helperwaypoints")
|
||||
private final List<Waypoint> helpers = Lists.newArrayList();
|
||||
private NPC npc;
|
||||
private boolean paused;
|
||||
|
||||
@Override
|
||||
public WaypointEditor createEditor(final Player player, CommandContext args) {
|
||||
return new WaypointEditor() {
|
||||
WaypointMarkers markers = new WaypointMarkers(player.getWorld());
|
||||
|
||||
@Override
|
||||
public void begin() {
|
||||
showPath();
|
||||
Messaging.sendTr(player, Messages.LINEAR_WAYPOINT_EDITOR_BEGIN);
|
||||
}
|
||||
|
||||
private void createWaypointMarkerWithData(Waypoint element) {
|
||||
Entity entity = markers.createWaypointMarker(element);
|
||||
if (entity == null)
|
||||
return;
|
||||
entity.setMetadata("citizens.waypointhashcode",
|
||||
new FixedMetadataValue(CitizensAPI.getPlugin(), element.hashCode()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end() {
|
||||
Messaging.sendTr(player, Messages.LINEAR_WAYPOINT_EDITOR_END);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
if (!event.getPlayer().equals(player) || event.getAction() == Action.PHYSICAL
|
||||
|| event.getClickedBlock() == null)
|
||||
return;
|
||||
if (event.getPlayer().getWorld() != npc.getBukkitEntity().getWorld())
|
||||
return;
|
||||
event.setCancelled(true);
|
||||
Location at = event.getClickedBlock().getLocation();
|
||||
Waypoint element = new Waypoint(at);
|
||||
if (player.isSneaking()) {
|
||||
available.add(element);
|
||||
} else {
|
||||
helpers.add(element);
|
||||
}
|
||||
createWaypointMarkerWithData(element);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
|
||||
if (!event.getRightClicked().hasMetadata("citizens.waypointhashcode"))
|
||||
return;
|
||||
int hashcode = event.getRightClicked().getMetadata("citizens.waypointhashcode").get(0).asInt();
|
||||
Iterator<Waypoint> itr = Iterables.concat(available, helpers).iterator();
|
||||
while (itr.hasNext()) {
|
||||
if (itr.next().hashCode() == hashcode) {
|
||||
itr.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void showPath() {
|
||||
for (Waypoint element : Iterables.concat(available, helpers)) {
|
||||
createWaypointMarkerWithData(element);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPaused() {
|
||||
return paused;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(DataKey key) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpawn(NPC npc) {
|
||||
this.npc = npc;
|
||||
if (currentGoal == null) {
|
||||
currentGoal = new JeebissFindingWaypointProviderGoal();
|
||||
CitizensAPI.registerEvents(currentGoal);
|
||||
npc.getDefaultGoalController().addGoal(currentGoal, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(DataKey key) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPaused(boolean paused) {
|
||||
this.paused = paused;
|
||||
}
|
||||
|
||||
private class JeebissFindingWaypointProviderGoal implements Goal {
|
||||
JeebissPlan plan;
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
plan = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(GoalSelector selector) {
|
||||
if (plan.isComplete()) {
|
||||
selector.finish();
|
||||
return;
|
||||
}
|
||||
Waypoint current = plan.getCurrentWaypoint();
|
||||
npc.getNavigator().setTarget(current.getLocation());
|
||||
npc.getNavigator().getLocalParameters().addSingleUseCallback(new NavigatorCallback() {
|
||||
@Override
|
||||
public void onCompletion(CancelReason cancelReason) {
|
||||
plan.update(npc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldExecute(GoalSelector selector) {
|
||||
if (paused || available.size() == 0 || !npc.isSpawned() || npc.getNavigator().isNavigating())
|
||||
return false;
|
||||
Waypoint target = available.get(Util.getFastRandom().nextInt(available.size()));
|
||||
ASTAR.runFully(new JeebissGoal(target), null);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static class JeebissGoal implements AStarGoal<JeebissNode> {
|
||||
private final Waypoint dest;
|
||||
|
||||
public JeebissGoal(Waypoint dest) {
|
||||
this.dest = dest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float g(JeebissNode from, JeebissNode to) {
|
||||
return (float) from.distance(to.waypoint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getInitialCost(JeebissNode node) {
|
||||
return h(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float h(JeebissNode from) {
|
||||
return (float) from.distance(dest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinished(JeebissNode node) {
|
||||
return node.waypoint.equals(dest);
|
||||
}
|
||||
}
|
||||
|
||||
private static class JeebissNode extends AStarNode {
|
||||
private Waypoint waypoint;
|
||||
|
||||
@Override
|
||||
public Plan buildPlan() {
|
||||
return new JeebissPlan(this.<JeebissNode> getParents());
|
||||
}
|
||||
|
||||
public double distance(Waypoint dest) {
|
||||
return waypoint.distance(dest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
JeebissNode other = (JeebissNode) obj;
|
||||
if (waypoint == null) {
|
||||
if (other.waypoint != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!waypoint.equals(other.waypoint)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<AStarNode> getNeighbours() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31 + ((waypoint == null) ? 0 : waypoint.hashCode());
|
||||
}
|
||||
}
|
||||
|
||||
private static class JeebissPlan implements Plan {
|
||||
private int index = 0;
|
||||
private final Waypoint[] path;
|
||||
|
||||
public JeebissPlan(Iterable<JeebissNode> path) {
|
||||
this.path = Iterables.toArray(Iterables.transform(path, new Function<JeebissNode, Waypoint>() {
|
||||
@Override
|
||||
public Waypoint apply(JeebissNode to) {
|
||||
return to.waypoint;
|
||||
}
|
||||
}), Waypoint.class);
|
||||
}
|
||||
|
||||
public Waypoint getCurrentWaypoint() {
|
||||
return path[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComplete() {
|
||||
return index >= path.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Agent agent) {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
private static final AStarMachine<JeebissNode, JeebissPlan> ASTAR = AStarMachine.createWithDefaultStorage();
|
||||
}
|
@ -2,7 +2,6 @@ package net.citizensnpcs.trait.waypoint;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@ -23,16 +22,12 @@ import net.citizensnpcs.api.util.Messaging;
|
||||
import net.citizensnpcs.editor.Editor;
|
||||
import net.citizensnpcs.trait.waypoint.triggers.TriggerEditPrompt;
|
||||
import net.citizensnpcs.util.Messages;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
import net.citizensnpcs.util.Util;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.conversations.Conversation;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.block.Action;
|
||||
@ -40,10 +35,8 @@ import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerItemHeldEvent;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
public class LinearWaypointProvider implements WaypointProvider {
|
||||
private LinearWaypointGoal currentGoal;
|
||||
@ -121,12 +114,13 @@ public class LinearWaypointProvider implements WaypointProvider {
|
||||
Conversation conversation;
|
||||
boolean editing = true;
|
||||
int editingSlot = waypoints.size() - 1;
|
||||
WaypointMarkers markers;
|
||||
private final Player player;
|
||||
private boolean showPath;
|
||||
private final Map<Waypoint, Entity> waypointMarkers = Maps.newHashMap();
|
||||
|
||||
private LinearWaypointEditor(Player player) {
|
||||
this.player = player;
|
||||
this.markers = new WaypointMarkers(player.getWorld());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -138,31 +132,16 @@ public class LinearWaypointProvider implements WaypointProvider {
|
||||
editingSlot = 0;
|
||||
waypoints.clear();
|
||||
onWaypointsModified();
|
||||
destroyWaypointMarkers();
|
||||
markers.destroyWaypointMarkers();
|
||||
Messaging.sendTr(player, Messages.LINEAR_WAYPOINT_EDITOR_WAYPOINTS_CLEARED);
|
||||
}
|
||||
|
||||
private void createWaypointMarker(int index, Waypoint waypoint) {
|
||||
Entity entity = spawnMarker(player.getWorld(), waypoint.getLocation().clone().add(0, 1, 0));
|
||||
if (entity == null)
|
||||
return;
|
||||
entity.setMetadata("waypointindex", new FixedMetadataValue(CitizensAPI.getPlugin(), index));
|
||||
waypointMarkers.put(waypoint, entity);
|
||||
}
|
||||
|
||||
private void createWaypointMarkers() {
|
||||
for (int i = 0; i < waypoints.size(); i++) {
|
||||
createWaypointMarker(i, waypoints.get(i));
|
||||
markers.createWaypointMarker(waypoints.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
private void destroyWaypointMarkers() {
|
||||
for (Entity entity : waypointMarkers.values()) {
|
||||
entity.remove();
|
||||
}
|
||||
waypointMarkers.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end() {
|
||||
if (!editing)
|
||||
@ -173,7 +152,7 @@ public class LinearWaypointProvider implements WaypointProvider {
|
||||
editing = false;
|
||||
if (!showPath)
|
||||
return;
|
||||
destroyWaypointMarkers();
|
||||
markers.destroyWaypointMarkers();
|
||||
}
|
||||
|
||||
private String formatLoc(Location location) {
|
||||
@ -275,8 +254,9 @@ public class LinearWaypointProvider implements WaypointProvider {
|
||||
Waypoint element = new Waypoint(at);
|
||||
normaliseEditingSlot();
|
||||
waypoints.add(editingSlot, element);
|
||||
if (showPath)
|
||||
createWaypointMarker(editingSlot, element);
|
||||
if (showPath) {
|
||||
markers.createWaypointMarker(element);
|
||||
}
|
||||
editingSlot = Math.min(editingSlot + 1, waypoints.size());
|
||||
Messaging.sendTr(player, Messages.LINEAR_WAYPOINT_EDITOR_ADDED_WAYPOINT, formatLoc(at),
|
||||
editingSlot + 1, waypoints.size());
|
||||
@ -284,8 +264,9 @@ public class LinearWaypointProvider implements WaypointProvider {
|
||||
event.setCancelled(true);
|
||||
normaliseEditingSlot();
|
||||
Waypoint waypoint = waypoints.remove(editingSlot);
|
||||
if (showPath)
|
||||
removeWaypointMarker(waypoint);
|
||||
if (showPath) {
|
||||
markers.removeWaypointMarker(waypoint);
|
||||
}
|
||||
editingSlot = Math.max(0, editingSlot - 1);
|
||||
Messaging.sendTr(player, Messages.LINEAR_WAYPOINT_EDITOR_REMOVED_WAYPOINT, waypoints.size(),
|
||||
editingSlot + 1);
|
||||
@ -331,23 +312,13 @@ public class LinearWaypointProvider implements WaypointProvider {
|
||||
}
|
||||
}
|
||||
|
||||
private void removeWaypointMarker(Waypoint waypoint) {
|
||||
Entity entity = waypointMarkers.remove(waypoint);
|
||||
if (entity != null)
|
||||
entity.remove();
|
||||
}
|
||||
|
||||
private Entity spawnMarker(World world, Location at) {
|
||||
return NMS.spawnCustomEntity(world, at, EntityEnderCrystalMarker.class, EntityType.ENDER_CRYSTAL);
|
||||
}
|
||||
|
||||
private void togglePath() {
|
||||
showPath = !showPath;
|
||||
if (showPath) {
|
||||
createWaypointMarkers();
|
||||
Messaging.sendTr(player, Messages.LINEAR_WAYPOINT_EDITOR_SHOWING_MARKERS);
|
||||
} else {
|
||||
destroyWaypointMarkers();
|
||||
markers.destroyWaypointMarkers();
|
||||
Messaging.sendTr(player, Messages.LINEAR_WAYPOINT_EDITOR_NOT_SHOWING_MARKERS);
|
||||
}
|
||||
}
|
||||
|
@ -24,13 +24,11 @@ public class WanderWaypointProvider implements WaypointProvider {
|
||||
@Override
|
||||
public void begin() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -35,6 +35,10 @@ public class Waypoint {
|
||||
triggers.add(trigger);
|
||||
}
|
||||
|
||||
public double distance(Waypoint dest) {
|
||||
return location.distance(dest.location);
|
||||
}
|
||||
|
||||
public Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
@ -0,0 +1,46 @@
|
||||
package net.citizensnpcs.trait.waypoint;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import net.citizensnpcs.util.NMS;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
public class WaypointMarkers {
|
||||
private final Map<Waypoint, Entity> waypointMarkers = Maps.newHashMap();
|
||||
private final World world;
|
||||
|
||||
public WaypointMarkers(World world) {
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
public Entity createWaypointMarker(Waypoint waypoint) {
|
||||
Entity entity = spawnMarker(world, waypoint.getLocation().clone().add(0, 1, 0));
|
||||
if (entity == null)
|
||||
return null;
|
||||
waypointMarkers.put(waypoint, entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
public void destroyWaypointMarkers() {
|
||||
for (Entity entity : waypointMarkers.values()) {
|
||||
entity.remove();
|
||||
}
|
||||
waypointMarkers.clear();
|
||||
}
|
||||
|
||||
public void removeWaypointMarker(Waypoint waypoint) {
|
||||
Entity entity = waypointMarkers.remove(waypoint);
|
||||
if (entity != null)
|
||||
entity.remove();
|
||||
}
|
||||
|
||||
public Entity spawnMarker(World world, Location at) {
|
||||
return NMS.spawnCustomEntity(world, at, EntityEnderCrystalMarker.class, EntityType.ENDER_CRYSTAL);
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ import java.util.Map.Entry;
|
||||
|
||||
import net.citizensnpcs.api.command.CommandContext;
|
||||
import net.citizensnpcs.api.exception.NPCLoadException;
|
||||
import net.citizensnpcs.api.persistence.PersistenceLoader;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
import net.citizensnpcs.api.util.Messaging;
|
||||
@ -74,6 +75,7 @@ public class Waypoints extends Trait {
|
||||
}
|
||||
if (provider == null)
|
||||
return;
|
||||
PersistenceLoader.load(provider, key.getRelative(providerName));
|
||||
provider.load(key.getRelative(providerName));
|
||||
}
|
||||
|
||||
@ -87,6 +89,7 @@ public class Waypoints extends Trait {
|
||||
public void save(DataKey key) {
|
||||
if (provider == null)
|
||||
return;
|
||||
PersistenceLoader.save(provider, key.getRelative(providerName));
|
||||
provider.save(key.getRelative(providerName));
|
||||
key.setString("provider", providerName);
|
||||
}
|
||||
@ -113,8 +116,6 @@ public class Waypoints extends Trait {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static final Map<String, Class<? extends WaypointProvider>> providers = Maps.newHashMap();
|
||||
|
||||
/**
|
||||
* Registers a {@link WaypointProvider}, which can be subsequently used by
|
||||
* NPCs.
|
||||
@ -128,8 +129,11 @@ public class Waypoints extends Trait {
|
||||
providers.put(name, clazz);
|
||||
}
|
||||
|
||||
private static final Map<String, Class<? extends WaypointProvider>> providers = Maps.newHashMap();
|
||||
|
||||
static {
|
||||
providers.put("linear", LinearWaypointProvider.class);
|
||||
providers.put("wander", WanderWaypointProvider.class);
|
||||
providers.put("jeebissfinding", JeebissFindingWaypointProvider.class);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user