mirror of
https://github.com/CitizensDev/Citizens2.git
synced 2024-11-23 02:55:45 +01:00
Git fail. WARNING: API BREAKAGES
This commit is contained in:
parent
bc5fe1bb18
commit
bcd727e554
2
pom.xml
2
pom.xml
@ -11,7 +11,7 @@
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<craftbukkit.version>1.2.5-R1.2-SNAPSHOT</craftbukkit.version>
|
||||
<craftbukkit.version>1.2.5-R4.1-SNAPSHOT</craftbukkit.version>
|
||||
<citizensapi.version>2.0-SNAPSHOT</citizensapi.version>
|
||||
<build.number>Unknown</build.number>
|
||||
</properties>
|
||||
|
@ -12,11 +12,10 @@ import net.citizensnpcs.api.event.CitizensReloadEvent;
|
||||
import net.citizensnpcs.api.exception.NPCLoadException;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.npc.NPCRegistry;
|
||||
import net.citizensnpcs.api.npc.character.CharacterManager;
|
||||
import net.citizensnpcs.api.scripting.EventRegistrar;
|
||||
import net.citizensnpcs.api.scripting.ObjectProvider;
|
||||
import net.citizensnpcs.api.scripting.ScriptCompiler;
|
||||
import net.citizensnpcs.api.trait.TraitManager;
|
||||
import net.citizensnpcs.api.trait.TraitFactory;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
import net.citizensnpcs.api.util.DatabaseStorage;
|
||||
import net.citizensnpcs.api.util.NBTStorage;
|
||||
@ -35,10 +34,9 @@ import net.citizensnpcs.command.exception.ServerCommandException;
|
||||
import net.citizensnpcs.command.exception.UnhandledCommandException;
|
||||
import net.citizensnpcs.command.exception.WrappedCommandException;
|
||||
import net.citizensnpcs.editor.Editor;
|
||||
import net.citizensnpcs.npc.CitizensCharacterManager;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.CitizensNPCRegistry;
|
||||
import net.citizensnpcs.npc.CitizensTraitManager;
|
||||
import net.citizensnpcs.npc.CitizensTraitFactory;
|
||||
import net.citizensnpcs.npc.NPCSelector;
|
||||
import net.citizensnpcs.util.Messaging;
|
||||
import net.citizensnpcs.util.StringHelper;
|
||||
@ -50,12 +48,12 @@ import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
public class Citizens extends JavaPlugin implements CitizensPlugin {
|
||||
private final CitizensCharacterManager characterManager = new CitizensCharacterManager();
|
||||
private final CommandManager commands = new CommandManager();
|
||||
private boolean compatible;
|
||||
private Settings config;
|
||||
@ -63,11 +61,32 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
|
||||
private CitizensNPCRegistry npcRegistry;
|
||||
private Storage saves; // TODO: refactor this, it's used in too many places
|
||||
private NPCSelector selector;
|
||||
private TraitManager traitManager;
|
||||
private CitizensTraitFactory traitFactory;
|
||||
|
||||
@Override
|
||||
public CharacterManager getCharacterManager() {
|
||||
return characterManager;
|
||||
private void despawnNPCs() {
|
||||
Iterator<NPC> itr = npcRegistry.iterator();
|
||||
while (itr.hasNext()) {
|
||||
NPC npc = itr.next();
|
||||
itr.remove();
|
||||
npc.despawn();
|
||||
}
|
||||
}
|
||||
|
||||
private void enableSubPlugins() {
|
||||
File root = new File(getDataFolder(), Setting.SUBPLUGIN_FOLDER.asString());
|
||||
if (!root.exists() || !root.isDirectory())
|
||||
return;
|
||||
Plugin[] plugins = Bukkit.getPluginManager().loadPlugins(root);
|
||||
// code beneath modified from CraftServer
|
||||
for (Plugin plugin : plugins) {
|
||||
try {
|
||||
Messaging.logF("Loading %s", plugin.getDescription().getFullName());
|
||||
plugin.onLoad();
|
||||
} catch (Throwable ex) {
|
||||
Messaging.severe(ex.getMessage() + " initializing " + plugin.getDescription().getFullName());
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Iterable<net.citizensnpcs.command.Command> getCommands(String base) {
|
||||
@ -89,8 +108,8 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
|
||||
}
|
||||
|
||||
@Override
|
||||
public TraitManager getTraitManager() {
|
||||
return traitManager;
|
||||
public TraitFactory getTraitFactory() {
|
||||
return traitFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -170,7 +189,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
|
||||
setupStorage();
|
||||
|
||||
npcRegistry = new CitizensNPCRegistry(saves);
|
||||
traitManager = new CitizensTraitManager(this);
|
||||
traitFactory = new CitizensTraitFactory();
|
||||
selector = new NPCSelector(this);
|
||||
CitizensAPI.setImplementation(this);
|
||||
|
||||
@ -187,30 +206,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
|
||||
public void run() {
|
||||
setupNPCs();
|
||||
startMetrics();
|
||||
}
|
||||
|
||||
private void startMetrics() {
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Metrics metrics = new Metrics(Citizens.this);
|
||||
if (metrics.isOptOut())
|
||||
return;
|
||||
metrics.addCustomData(new Metrics.Plotter("Total NPCs") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return Iterables.size(npcRegistry);
|
||||
}
|
||||
});
|
||||
characterManager.addPlotters(metrics);
|
||||
metrics.start();
|
||||
Messaging.log("Metrics started.");
|
||||
} catch (IOException e) {
|
||||
Messaging.logF("Unable to start metrics: %s.", e.getMessage());
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
enableSubPlugins();
|
||||
}
|
||||
}) == -1) {
|
||||
Messaging.severe("Issue enabling plugin. Disabling.");
|
||||
@ -251,15 +247,6 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
|
||||
getServer().getPluginManager().callEvent(new CitizensReloadEvent());
|
||||
}
|
||||
|
||||
private void despawnNPCs() {
|
||||
Iterator<NPC> itr = npcRegistry.iterator();
|
||||
while (itr.hasNext()) {
|
||||
NPC npc = itr.next();
|
||||
itr.remove();
|
||||
npc.despawn();
|
||||
}
|
||||
}
|
||||
|
||||
public void save() {
|
||||
for (NPC npc : npcRegistry)
|
||||
((CitizensNPC) npc).save(saves.getKey("npc." + npc.getId()));
|
||||
@ -287,7 +274,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
NPC npc = npcRegistry.createNPC(type, id, key.getString("name"), null);
|
||||
NPC npc = npcRegistry.createNPC(type, id, key.getString("name"));
|
||||
((CitizensNPC) npc).load(key);
|
||||
|
||||
++created;
|
||||
@ -300,7 +287,11 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
|
||||
private void setupScripting() {
|
||||
contextClassLoader = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader(getClassLoader());
|
||||
// workaround to fix scripts not loading plugin classes properly
|
||||
// Workaround to fix scripts not loading plugin classes properly.
|
||||
// The built in Sun Rhino Javascript engine uses the context classloader
|
||||
// to search for class imports. Since the context classloader only has
|
||||
// CraftBukkit classes, we replace it with a PluginClassLoader, which
|
||||
// allows all plugin classes to be imported.
|
||||
}
|
||||
|
||||
private void setupStorage() {
|
||||
@ -324,6 +315,31 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
|
||||
Messaging.logF("Save method set to %s.", saves.toString());
|
||||
}
|
||||
|
||||
private void startMetrics() {
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Metrics metrics = new Metrics(Citizens.this);
|
||||
if (metrics.isOptOut())
|
||||
return;
|
||||
metrics.addCustomData(new Metrics.Plotter("Total NPCs") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return Iterables.size(npcRegistry);
|
||||
}
|
||||
});
|
||||
|
||||
traitFactory.addPlotters(metrics.createGraph("traits"));
|
||||
metrics.start();
|
||||
Messaging.log("Metrics started.");
|
||||
} catch (IOException e) {
|
||||
Messaging.logF("Unable to start metrics: %s.", e.getMessage());
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
private boolean suggestClosestModifier(CommandSender sender, String command, String modifier) {
|
||||
int minDist = Integer.MAX_VALUE;
|
||||
String closest = "";
|
||||
|
@ -1,6 +1,5 @@
|
||||
package net.citizensnpcs;
|
||||
|
||||
import net.citizensnpcs.Settings.Setting;
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.event.NPCDamageByEntityEvent;
|
||||
import net.citizensnpcs.api.event.NPCDamageEvent;
|
||||
@ -11,8 +10,6 @@ import net.citizensnpcs.api.npc.NPCRegistry;
|
||||
import net.citizensnpcs.editor.Editor;
|
||||
import net.citizensnpcs.npc.entity.EntityHumanNPC;
|
||||
import net.citizensnpcs.trait.CurrentLocation;
|
||||
import net.citizensnpcs.trait.text.Text;
|
||||
import net.citizensnpcs.util.Util;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
@ -52,7 +49,7 @@ public class EventListen implements Listener {
|
||||
if (!toRespawn.containsKey(coord))
|
||||
return;
|
||||
for (int id : toRespawn.get(coord)) {
|
||||
NPC npc = npcRegistry.getNPC(id);
|
||||
NPC npc = npcRegistry.getById(id);
|
||||
npc.spawn(npc.getTrait(CurrentLocation.class).getLocation());
|
||||
}
|
||||
toRespawn.removeAll(coord);
|
||||
@ -96,11 +93,6 @@ public class EventListen implements Listener {
|
||||
// Call left-click event
|
||||
NPCLeftClickEvent leftClickEvent = new NPCLeftClickEvent(npc, damager);
|
||||
Bukkit.getPluginManager().callEvent(leftClickEvent);
|
||||
if (leftClickEvent.isCancelled())
|
||||
return;
|
||||
|
||||
if (npc.getCharacter() != null)
|
||||
npc.getCharacter().onLeftClick(npc, damager);
|
||||
} else {
|
||||
Bukkit.getPluginManager().callEvent(new NPCDamageEvent(npc, event));
|
||||
}
|
||||
@ -125,15 +117,6 @@ public class EventListen implements Listener {
|
||||
// Call right-click event
|
||||
NPCRightClickEvent rightClickEvent = new NPCRightClickEvent(npc, player);
|
||||
Bukkit.getPluginManager().callEvent(rightClickEvent);
|
||||
if (rightClickEvent.isCancelled())
|
||||
return;
|
||||
// If the NPC isn't a close talker
|
||||
// TODO: move this into text.class
|
||||
if (Util.isSettingFulfilled(player, Setting.TALK_ITEM) && !npc.getTrait(Text.class).shouldTalkClose())
|
||||
npc.getTrait(Text.class).sendText(player);
|
||||
|
||||
if (npc.getCharacter() != null)
|
||||
npc.getCharacter().onRightClick(npc, player);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -171,7 +154,7 @@ public class EventListen implements Listener {
|
||||
if (!event.getWorld().isChunkLoaded(chunk.first, chunk.second))
|
||||
continue;
|
||||
for (int id : toRespawn.get(chunk)) {
|
||||
NPC npc = npcRegistry.getNPC(id);
|
||||
NPC npc = npcRegistry.getById(id);
|
||||
npc.spawn(npc.getTrait(CurrentLocation.class).getLocation());
|
||||
}
|
||||
toRespawn.removeAll(chunk);
|
||||
|
@ -67,53 +67,6 @@ import org.bukkit.plugin.PluginDescriptionFile;
|
||||
*/
|
||||
public class Metrics {
|
||||
|
||||
/**
|
||||
* The current revision number
|
||||
*/
|
||||
private final static int REVISION = 5;
|
||||
|
||||
/**
|
||||
* The base url of the metrics domain
|
||||
*/
|
||||
private static final String BASE_URL = "http://mcstats.org";
|
||||
|
||||
/**
|
||||
* The url used to report a server's status
|
||||
*/
|
||||
private static final String REPORT_URL = "/report/%s";
|
||||
|
||||
/**
|
||||
* The file where guid and opt out is stored in
|
||||
*/
|
||||
private static final String CONFIG_FILE = "plugins/PluginMetrics/config.yml";
|
||||
|
||||
/**
|
||||
* The separator to use for custom data. This MUST NOT change unless you are
|
||||
* hosting your own version of metrics and want to change it.
|
||||
*/
|
||||
private static final String CUSTOM_DATA_SEPARATOR = "~~";
|
||||
|
||||
/**
|
||||
* Interval of time to ping (in minutes)
|
||||
*/
|
||||
private static final int PING_INTERVAL = 10;
|
||||
|
||||
/**
|
||||
* The plugin this metrics submits for
|
||||
*/
|
||||
private final Plugin plugin;
|
||||
|
||||
/**
|
||||
* All of the custom graphs to submit to metrics
|
||||
*/
|
||||
private final Set<Graph> graphs = Collections.synchronizedSet(new HashSet<Graph>());
|
||||
|
||||
/**
|
||||
* The default graph, used for addCustomData when you don't want a specific
|
||||
* graph
|
||||
*/
|
||||
private final Graph defaultGraph = new Graph("Default");
|
||||
|
||||
/**
|
||||
* The plugin configuration file
|
||||
*/
|
||||
@ -124,6 +77,17 @@ public class Metrics {
|
||||
*/
|
||||
private final File configurationFile;
|
||||
|
||||
/**
|
||||
* The default graph, used for addCustomData when you don't want a specific
|
||||
* graph
|
||||
*/
|
||||
private final Graph defaultGraph = new Graph("Default");
|
||||
|
||||
/**
|
||||
* All of the custom graphs to submit to metrics
|
||||
*/
|
||||
private final Set<Graph> graphs = Collections.synchronizedSet(new HashSet<Graph>());
|
||||
|
||||
/**
|
||||
* Unique server id
|
||||
*/
|
||||
@ -134,6 +98,11 @@ public class Metrics {
|
||||
*/
|
||||
private final Object optOutLock = new Object();
|
||||
|
||||
/**
|
||||
* The plugin this metrics submits for
|
||||
*/
|
||||
private final Plugin plugin;
|
||||
|
||||
/**
|
||||
* Id of the scheduled task
|
||||
*/
|
||||
@ -164,6 +133,23 @@ public class Metrics {
|
||||
guid = configuration.getString("guid");
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a custom data plotter to the default graph
|
||||
*
|
||||
* @param plotter
|
||||
*/
|
||||
public void addCustomData(final Plotter plotter) {
|
||||
if (plotter == null) {
|
||||
throw new IllegalArgumentException("Plotter cannot be null");
|
||||
}
|
||||
|
||||
// Add the plotter to the graph o/
|
||||
defaultGraph.addPlotter(plotter);
|
||||
|
||||
// Ensure the default graph is included in the submitted graphs
|
||||
graphs.add(defaultGraph);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct and create a Graph that can be used to separate specific
|
||||
* plotters to their own graphs on the metrics website. Plotters can be
|
||||
@ -189,99 +175,27 @@ public class Metrics {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a custom data plotter to the default graph
|
||||
* Disables metrics for the server by setting "opt-out" to true in the
|
||||
* config file and canceling the metrics task.
|
||||
*
|
||||
* @param plotter
|
||||
* @throws IOException
|
||||
*/
|
||||
public void addCustomData(final Plotter plotter) {
|
||||
if (plotter == null) {
|
||||
throw new IllegalArgumentException("Plotter cannot be null");
|
||||
}
|
||||
|
||||
// Add the plotter to the graph o/
|
||||
defaultGraph.addPlotter(plotter);
|
||||
|
||||
// Ensure the default graph is included in the submitted graphs
|
||||
graphs.add(defaultGraph);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start measuring statistics. This will immediately create an async
|
||||
* repeating task as the plugin and send the initial data to the metrics
|
||||
* backend, and then after that it will post in increments of PING_INTERVAL
|
||||
* * 1200 ticks.
|
||||
*
|
||||
* @return True if statistics measuring is running, otherwise false.
|
||||
*/
|
||||
public boolean start() {
|
||||
public void disable() throws IOException {
|
||||
// This has to be synchronized or it can collide with the check in the
|
||||
// task.
|
||||
synchronized (optOutLock) {
|
||||
// Did we opt out?
|
||||
if (isOptOut()) {
|
||||
return false;
|
||||
// Check if the server owner has already set opt-out, if not, set
|
||||
// it.
|
||||
if (!isOptOut()) {
|
||||
configuration.set("opt-out", true);
|
||||
configuration.save(configurationFile);
|
||||
}
|
||||
|
||||
// Is metrics already running?
|
||||
if (taskId >= 0) {
|
||||
return true;
|
||||
// Disable Task, if it is running
|
||||
if (taskId > 0) {
|
||||
this.plugin.getServer().getScheduler().cancelTask(taskId);
|
||||
taskId = -1;
|
||||
}
|
||||
|
||||
// Begin hitting the server with glorious data
|
||||
taskId = plugin.getServer().getScheduler().scheduleAsyncRepeatingTask(plugin, new Runnable() {
|
||||
|
||||
private boolean firstPost = true;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
// This has to be synchronized or it can collide with
|
||||
// the disable method.
|
||||
synchronized (optOutLock) {
|
||||
// Disable Task, if it is running and the server
|
||||
// owner decided to opt-out
|
||||
if (isOptOut() && taskId > 0) {
|
||||
plugin.getServer().getScheduler().cancelTask(taskId);
|
||||
taskId = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// We use the inverse of firstPost because if it is the
|
||||
// first time we are posting,
|
||||
// it is not a interval ping, so it evaluates to FALSE
|
||||
// Each time thereafter it will evaluate to TRUE, i.e
|
||||
// PING!
|
||||
postPlugin(!firstPost);
|
||||
|
||||
// After the first post we set firstPost to false
|
||||
// Each post thereafter will be a ping
|
||||
firstPost = false;
|
||||
} catch (IOException e) {
|
||||
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}, 0, PING_INTERVAL * 1200);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Has the server owner denied plugin metrics?
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isOptOut() {
|
||||
synchronized (optOutLock) {
|
||||
try {
|
||||
// Reload the metrics file
|
||||
configuration.load(CONFIG_FILE);
|
||||
} catch (IOException ex) {
|
||||
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
|
||||
return true;
|
||||
} catch (InvalidConfigurationException ex) {
|
||||
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
|
||||
return true;
|
||||
}
|
||||
return configuration.getBoolean("opt-out", false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -310,27 +224,38 @@ public class Metrics {
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables metrics for the server by setting "opt-out" to true in the
|
||||
* config file and canceling the metrics task.
|
||||
* Check if mineshafter is present. If it is, we need to bypass it to send
|
||||
* POST requests
|
||||
*
|
||||
* @throws IOException
|
||||
* @return
|
||||
*/
|
||||
public void disable() throws IOException {
|
||||
// This has to be synchronized or it can collide with the check in the
|
||||
// task.
|
||||
synchronized (optOutLock) {
|
||||
// Check if the server owner has already set opt-out, if not, set
|
||||
// it.
|
||||
if (!isOptOut()) {
|
||||
configuration.set("opt-out", true);
|
||||
configuration.save(configurationFile);
|
||||
}
|
||||
private boolean isMineshafterPresent() {
|
||||
try {
|
||||
Class.forName("mineshafter.MineServer");
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Disable Task, if it is running
|
||||
if (taskId > 0) {
|
||||
this.plugin.getServer().getScheduler().cancelTask(taskId);
|
||||
taskId = -1;
|
||||
/**
|
||||
* Has the server owner denied plugin metrics?
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isOptOut() {
|
||||
synchronized (optOutLock) {
|
||||
try {
|
||||
// Reload the metrics file
|
||||
configuration.load(CONFIG_FILE);
|
||||
} catch (IOException ex) {
|
||||
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
|
||||
return true;
|
||||
} catch (InvalidConfigurationException ex) {
|
||||
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
|
||||
return true;
|
||||
}
|
||||
return configuration.getBoolean("opt-out", false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -444,51 +369,64 @@ public class Metrics {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if mineshafter is present. If it is, we need to bypass it to send
|
||||
* POST requests
|
||||
* Start measuring statistics. This will immediately create an async
|
||||
* repeating task as the plugin and send the initial data to the metrics
|
||||
* backend, and then after that it will post in increments of PING_INTERVAL
|
||||
* * 1200 ticks.
|
||||
*
|
||||
* @return
|
||||
* @return True if statistics measuring is running, otherwise false.
|
||||
*/
|
||||
private boolean isMineshafterPresent() {
|
||||
try {
|
||||
Class.forName("mineshafter.MineServer");
|
||||
public boolean start() {
|
||||
synchronized (optOutLock) {
|
||||
// Did we opt out?
|
||||
if (isOptOut()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Is metrics already running?
|
||||
if (taskId >= 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Begin hitting the server with glorious data
|
||||
taskId = plugin.getServer().getScheduler().scheduleAsyncRepeatingTask(plugin, new Runnable() {
|
||||
|
||||
private boolean firstPost = true;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
// This has to be synchronized or it can collide with
|
||||
// the disable method.
|
||||
synchronized (optOutLock) {
|
||||
// Disable Task, if it is running and the server
|
||||
// owner decided to opt-out
|
||||
if (isOptOut() && taskId > 0) {
|
||||
plugin.getServer().getScheduler().cancelTask(taskId);
|
||||
taskId = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// We use the inverse of firstPost because if it is the
|
||||
// first time we are posting,
|
||||
// it is not a interval ping, so it evaluates to FALSE
|
||||
// Each time thereafter it will evaluate to TRUE, i.e
|
||||
// PING!
|
||||
postPlugin(!firstPost);
|
||||
|
||||
// After the first post we set firstPost to false
|
||||
// Each post thereafter will be a ping
|
||||
firstPost = false;
|
||||
} catch (IOException e) {
|
||||
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}, 0, PING_INTERVAL * 1200);
|
||||
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Encode a key/value data pair to be used in a HTTP post request. This
|
||||
* INCLUDES a & so the first key/value pair MUST be included manually, e.g:
|
||||
* </p>
|
||||
* <code>
|
||||
* StringBuffer data = new StringBuffer();
|
||||
* data.append(encode("guid")).append('=').append(encode(guid));
|
||||
* encodeDataPair(data, "version", description.getVersion());
|
||||
* </code>
|
||||
*
|
||||
* @param buffer
|
||||
* @param key
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
private static void encodeDataPair(final StringBuilder buffer, final String key, final String value)
|
||||
throws UnsupportedEncodingException {
|
||||
buffer.append('&').append(encode(key)).append('=').append(encode(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode text as UTF-8
|
||||
*
|
||||
* @param text
|
||||
* @return
|
||||
*/
|
||||
private static String encode(final String text) throws UnsupportedEncodingException {
|
||||
return URLEncoder.encode(text, "UTF-8");
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom graph on the website
|
||||
*/
|
||||
@ -509,15 +447,6 @@ public class Metrics {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the graph's name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a plotter to the graph, which will be used to plot entries
|
||||
*
|
||||
@ -527,13 +456,23 @@ public class Metrics {
|
||||
plotters.add(plotter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object object) {
|
||||
if (!(object instanceof Graph)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Graph graph = (Graph) object;
|
||||
return graph.name.equals(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a plotter from the graph
|
||||
* Gets the graph's name
|
||||
*
|
||||
* @param plotter
|
||||
* @return
|
||||
*/
|
||||
public void removePlotter(final Plotter plotter) {
|
||||
plotters.remove(plotter);
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -550,14 +489,13 @@ public class Metrics {
|
||||
return name.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object object) {
|
||||
if (!(object instanceof Graph)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Graph graph = (Graph) object;
|
||||
return graph.name.equals(name);
|
||||
/**
|
||||
* Remove a plotter from the graph
|
||||
*
|
||||
* @param plotter
|
||||
*/
|
||||
public void removePlotter(final Plotter plotter) {
|
||||
plotters.remove(plotter);
|
||||
}
|
||||
|
||||
}
|
||||
@ -588,12 +526,15 @@ public class Metrics {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current value for the plotted point
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public abstract int getValue();
|
||||
@Override
|
||||
public boolean equals(final Object object) {
|
||||
if (!(object instanceof Plotter)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Plotter plotter = (Plotter) object;
|
||||
return plotter.name.equals(name) && plotter.getValue() == getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the column name for the plotted point
|
||||
@ -605,26 +546,85 @@ public class Metrics {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after the website graphs have been updated
|
||||
* Get the current value for the plotted point
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public void reset() {
|
||||
}
|
||||
public abstract int getValue();
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getColumnName().hashCode() + getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object object) {
|
||||
if (!(object instanceof Plotter)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Plotter plotter = (Plotter) object;
|
||||
return plotter.name.equals(name) && plotter.getValue() == getValue();
|
||||
/**
|
||||
* Called after the website graphs have been updated
|
||||
*/
|
||||
public void reset() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The base url of the metrics domain
|
||||
*/
|
||||
private static final String BASE_URL = "http://mcstats.org";
|
||||
|
||||
/**
|
||||
* The file where guid and opt out is stored in
|
||||
*/
|
||||
private static final String CONFIG_FILE = "plugins/PluginMetrics/config.yml";
|
||||
|
||||
/**
|
||||
* The separator to use for custom data. This MUST NOT change unless you are
|
||||
* hosting your own version of metrics and want to change it.
|
||||
*/
|
||||
private static final String CUSTOM_DATA_SEPARATOR = "~~";
|
||||
|
||||
/**
|
||||
* Interval of time to ping (in minutes)
|
||||
*/
|
||||
private static final int PING_INTERVAL = 10;
|
||||
|
||||
/**
|
||||
* The url used to report a server's status
|
||||
*/
|
||||
private static final String REPORT_URL = "/report/%s";
|
||||
|
||||
/**
|
||||
* The current revision number
|
||||
*/
|
||||
private final static int REVISION = 5;
|
||||
|
||||
/**
|
||||
* Encode text as UTF-8
|
||||
*
|
||||
* @param text
|
||||
* @return
|
||||
*/
|
||||
private static String encode(final String text) throws UnsupportedEncodingException {
|
||||
return URLEncoder.encode(text, "UTF-8");
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Encode a key/value data pair to be used in a HTTP post request. This
|
||||
* INCLUDES a & so the first key/value pair MUST be included manually, e.g:
|
||||
* </p>
|
||||
* <code>
|
||||
* StringBuffer data = new StringBuffer();
|
||||
* data.append(encode("guid")).append('=').append(encode(guid));
|
||||
* encodeDataPair(data, "version", description.getVersion());
|
||||
* </code>
|
||||
*
|
||||
* @param buffer
|
||||
* @param key
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
private static void encodeDataPair(final StringBuilder buffer, final String key, final String value)
|
||||
throws UnsupportedEncodingException {
|
||||
buffer.append('&').append(encode(key)).append('=').append(encode(value));
|
||||
}
|
||||
|
||||
}
|
@ -23,9 +23,9 @@ public class Settings {
|
||||
for (Setting setting : Setting.values()) {
|
||||
if (!root.keyExists(setting.path)) {
|
||||
Messaging.logF("Writing default setting: '%s'", setting.path);
|
||||
setting.set(root);
|
||||
setting.setAtKey(root);
|
||||
} else
|
||||
setting.load(root);
|
||||
setting.loadFromKey(root);
|
||||
}
|
||||
|
||||
save();
|
||||
@ -35,7 +35,7 @@ public class Settings {
|
||||
config.load();
|
||||
for (Setting setting : Setting.values())
|
||||
if (root.keyExists(setting.path))
|
||||
setting.load(root);
|
||||
setting.loadFromKey(root);
|
||||
|
||||
save();
|
||||
}
|
||||
@ -56,7 +56,7 @@ public class Settings {
|
||||
DEFAULT_TALK_CLOSE("npc.default.talk-close", false),
|
||||
DEFAULT_TEXT("npc.default.text.0", "Hi, I'm <npc>!") {
|
||||
@Override
|
||||
public void load(DataKey root) {
|
||||
public void loadFromKey(DataKey root) {
|
||||
List<String> list = new ArrayList<String>();
|
||||
for (DataKey key : root.getRelative("npc.default.text").getSubKeys())
|
||||
list.add(key.getString(""));
|
||||
@ -69,6 +69,7 @@ public class Settings {
|
||||
SERVER_OWNS_NPCS("npc.server-ownership", false),
|
||||
STORAGE_FILE("storage.file", "saves.yml"),
|
||||
STORAGE_TYPE("storage.type", "yaml"),
|
||||
SUBPLUGIN_FOLDER("subplugins.folder", "plugins"),
|
||||
TALK_CLOSE_MAXIMUM_COOLDOWN("npc.text.max-talk-cooldown", 60),
|
||||
TALK_CLOSE_MINIMUM_COOLDOWN("npc.text.min-talk-cooldown", 30),
|
||||
TALK_ITEM("npc.text.talk-item", "340");
|
||||
@ -109,12 +110,12 @@ public class Settings {
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
protected void set(DataKey root) {
|
||||
root.setRaw(path, value);
|
||||
protected void loadFromKey(DataKey root) {
|
||||
value = root.getRaw(path);
|
||||
}
|
||||
|
||||
protected void load(DataKey root) {
|
||||
value = root.getRaw(path);
|
||||
protected void setAtKey(DataKey root) {
|
||||
root.setRaw(path, value);
|
||||
}
|
||||
}
|
||||
}
|
@ -198,6 +198,11 @@ public class CommandManager {
|
||||
|| commands.containsKey(command.toLowerCase() + " *");
|
||||
}
|
||||
|
||||
// Returns whether a player has permission.
|
||||
private boolean hasPermission(CommandSender sender, String perm) {
|
||||
return sender.hasPermission("citizens." + perm);
|
||||
}
|
||||
|
||||
// Returns whether a player has access to a command.
|
||||
private boolean hasPermission(Method method, CommandSender sender) {
|
||||
Command cmd = method.getAnnotation(Command.class);
|
||||
@ -207,11 +212,6 @@ public class CommandManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns whether a player has permission.
|
||||
private boolean hasPermission(CommandSender sender, String perm) {
|
||||
return sender.hasPermission("citizens." + perm);
|
||||
}
|
||||
|
||||
/*
|
||||
* Register an class that contains commands (denoted by Command. If no
|
||||
* dependency injector is specified, then the methods of the class will be
|
||||
|
@ -8,11 +8,11 @@ import org.bukkit.entity.EntityType;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Requirements {
|
||||
|
||||
EntityType[] excludedTypes() default { EntityType.UNKNOWN };
|
||||
|
||||
boolean ownership() default false;
|
||||
|
||||
boolean selected() default false;
|
||||
|
||||
EntityType[] types() default { EntityType.UNKNOWN };
|
||||
|
||||
EntityType[] excludedTypes() default { EntityType.UNKNOWN };
|
||||
}
|
@ -59,24 +59,6 @@ public class HelpCommands {
|
||||
return lines;
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "script" },
|
||||
usage = "help (page)",
|
||||
desc = "Script help menu",
|
||||
modifiers = { "help" },
|
||||
min = 1,
|
||||
max = 2,
|
||||
permission = "script.help")
|
||||
@Requirements
|
||||
public void scriptHelp(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||
int page = args.argsLength() == 2 ? args.getInteger(1) : 1;
|
||||
Paginator paginator = new Paginator().header("Script Help");
|
||||
for (String line : getLines(sender, "script"))
|
||||
paginator.addLine(line);
|
||||
if (!paginator.sendPage(sender, page))
|
||||
throw new CommandException("The page '" + page + "' does not exist.");
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "npc" },
|
||||
usage = "help (page)",
|
||||
@ -94,4 +76,22 @@ public class HelpCommands {
|
||||
if (!paginator.sendPage(sender, page))
|
||||
throw new CommandException("The page '" + page + "' does not exist.");
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "script" },
|
||||
usage = "help (page)",
|
||||
desc = "Script help menu",
|
||||
modifiers = { "help" },
|
||||
min = 1,
|
||||
max = 2,
|
||||
permission = "script.help")
|
||||
@Requirements
|
||||
public void scriptHelp(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||
int page = args.argsLength() == 2 ? args.getInteger(1) : 1;
|
||||
Paginator paginator = new Paginator().header("Script Help");
|
||||
for (String line : getLines(sender, "script"))
|
||||
paginator.addLine(line);
|
||||
if (!paginator.sendPage(sender, page))
|
||||
throw new CommandException("The page '" + page + "' does not exist.");
|
||||
}
|
||||
}
|
@ -8,8 +8,7 @@ import net.citizensnpcs.Settings.Setting;
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.npc.NPCRegistry;
|
||||
import net.citizensnpcs.api.npc.character.Character;
|
||||
import net.citizensnpcs.api.npc.character.CharacterManager;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.trait.trait.MobType;
|
||||
import net.citizensnpcs.api.trait.trait.Owner;
|
||||
import net.citizensnpcs.api.trait.trait.Spawned;
|
||||
@ -26,15 +25,14 @@ import net.citizensnpcs.trait.CurrentLocation;
|
||||
import net.citizensnpcs.trait.LookClose;
|
||||
import net.citizensnpcs.trait.Powered;
|
||||
import net.citizensnpcs.trait.VillagerProfession;
|
||||
import net.citizensnpcs.trait.text.Text;
|
||||
import net.citizensnpcs.util.Messaging;
|
||||
import net.citizensnpcs.util.Paginator;
|
||||
import net.citizensnpcs.util.StringHelper;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Ageable;
|
||||
import org.bukkit.entity.EntityType;
|
||||
@ -46,7 +44,6 @@ import com.google.common.base.Splitter;
|
||||
|
||||
@Requirements(selected = true, ownership = true)
|
||||
public class NPCCommands {
|
||||
private final CharacterManager characterManager = CitizensAPI.getCharacterManager();
|
||||
private final NPCRegistry npcRegistry;
|
||||
private final NPCSelector selector;
|
||||
|
||||
@ -64,8 +61,8 @@ public class NPCCommands {
|
||||
min = 1,
|
||||
max = 2,
|
||||
permission = "npc.age")
|
||||
@Requirements(selected = true, ownership = true, types = { EntityType.CHICKEN, EntityType.COW, EntityType.OCELOT,
|
||||
EntityType.PIG, EntityType.SHEEP, EntityType.VILLAGER, EntityType.WOLF })
|
||||
@Requirements(selected = true, ownership = true, types = { EntityType.CHICKEN, EntityType.COW,
|
||||
EntityType.OCELOT, EntityType.PIG, EntityType.SHEEP, EntityType.VILLAGER, EntityType.WOLF })
|
||||
public void age(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||
Age trait = npc.getTrait(Age.class);
|
||||
|
||||
@ -93,8 +90,13 @@ public class NPCCommands {
|
||||
Messaging.send(sender, "<a>Age " + (trait.toggle() ? "locked" : "unlocked") + ".");
|
||||
}
|
||||
|
||||
@Command(aliases = { "npc" }, usage = "behaviour [scripts]", desc = "Sets the behaviour of a NPC", modifiers = {
|
||||
"behaviour", "ai" }, min = 2, max = -1)
|
||||
@Command(
|
||||
aliases = { "npc" },
|
||||
usage = "behaviour [scripts]",
|
||||
desc = "Sets the behaviour of a NPC",
|
||||
modifiers = { "behaviour", "ai" },
|
||||
min = 2,
|
||||
max = -1)
|
||||
public void behaviour(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||
Iterable<String> files = Splitter.on(',').split(args.getJoinedStrings(1, ','));
|
||||
npc.getTrait(Behaviour.class).addScripts(files);
|
||||
@ -103,31 +105,19 @@ public class NPCCommands {
|
||||
|
||||
@Command(
|
||||
aliases = { "npc" },
|
||||
usage = "character [character]",
|
||||
desc = "Set the character of a NPC",
|
||||
modifiers = { "character" },
|
||||
min = 2,
|
||||
max = 2)
|
||||
public void character(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||
String name = args.getString(1).toLowerCase();
|
||||
Character character = characterManager.getCharacter(name);
|
||||
|
||||
if (character == null)
|
||||
throw new CommandException("The character '" + args.getString(1) + "' does not exist.");
|
||||
if (npc.getCharacter() != null && npc.getCharacter().getName().equalsIgnoreCase(character.getName()))
|
||||
throw new CommandException("The NPC already has the character '" + name + "'.");
|
||||
if (!sender.hasPermission("citizens.npc.character." + character.getName())
|
||||
&& !sender.hasPermission("citizens.npc.character.*") && !sender.hasPermission("citizens.admin"))
|
||||
throw new NoPermissionsException();
|
||||
|
||||
EntityType type = EntityType.valueOf(npc.getTrait(MobType.class).getType());
|
||||
if (!character.getValidTypes().isEmpty() && !character.getValidTypes().contains(type)) {
|
||||
Messaging.sendError(sender, "This NPC cannot be given the character '" + character.getName() + "'.");
|
||||
return;
|
||||
usage = "controllable",
|
||||
desc = "Toggles whether the NPC can be ridden and controlled",
|
||||
modifiers = { "controllable" },
|
||||
min = 1,
|
||||
max = 1,
|
||||
permission = "npc.controllable")
|
||||
public void controllable(CommandContext args, CommandSender sender, NPC npc) {
|
||||
boolean enabled = npc.getTrait(Controllable.class).toggle();
|
||||
if (enabled) {
|
||||
Messaging.send(sender, StringHelper.wrap(npc.getName()) + " can now be controlled.");
|
||||
} else {
|
||||
Messaging.send(sender, StringHelper.wrap(npc.getName()) + " can no longer be controlled.");
|
||||
}
|
||||
Messaging.send(sender, StringHelper.wrap(npc.getName() + "'s") + " character is now " + StringHelper.wrap(name)
|
||||
+ ".");
|
||||
npc.setCharacter(character);
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -143,7 +133,8 @@ public class NPCCommands {
|
||||
public void create(CommandContext args, final Player player, NPC npc) {
|
||||
String name = args.getString(1);
|
||||
if (name.length() > 16) {
|
||||
Messaging.sendError(player, "NPC names cannot be longer than 16 characters. The name has been shortened.");
|
||||
Messaging.sendError(player,
|
||||
"NPC names cannot be longer than 16 characters. The name has been shortened.");
|
||||
name = name.substring(0, 15);
|
||||
}
|
||||
EntityType type = EntityType.PLAYER;
|
||||
@ -156,25 +147,8 @@ public class NPCCommands {
|
||||
}
|
||||
}
|
||||
npc = npcRegistry.createNPC(type, name);
|
||||
String msg = ChatColor.GREEN + "You created " + StringHelper.wrap(npc.getName());
|
||||
if (args.hasValueFlag("char")) {
|
||||
String character = args.getFlag("char").toLowerCase();
|
||||
if (characterManager.getCharacter(character) == null) {
|
||||
Messaging.sendError(player, "'" + args.getFlag("char") + "' is not a valid character.");
|
||||
return;
|
||||
} else {
|
||||
Character set = characterManager.getCharacter(character);
|
||||
if (!set.getValidTypes().isEmpty() && !set.getValidTypes().contains(type)) {
|
||||
Messaging.sendError(player, "The character '" + set.getName() + "' cannot be given the mob type '"
|
||||
+ type.name().toLowerCase() + "'.");
|
||||
npc.remove();
|
||||
return;
|
||||
}
|
||||
npc.setCharacter(characterManager.getCharacter(character));
|
||||
msg += " with the character " + StringHelper.wrap(character);
|
||||
}
|
||||
}
|
||||
msg += " at your location";
|
||||
String msg = ChatColor.GREEN + "You created " + StringHelper.wrap(npc.getName())
|
||||
+ " at your location";
|
||||
|
||||
int age = 0;
|
||||
if (args.hasFlag('b')) {
|
||||
@ -195,32 +169,36 @@ public class NPCCommands {
|
||||
msg += ".";
|
||||
|
||||
// Initialize necessary traits
|
||||
npc.addTrait(Owner.class);
|
||||
if (!Setting.SERVER_OWNS_NPCS.asBoolean())
|
||||
npc.getTrait(Owner.class).setOwner(player.getName());
|
||||
npc.getTrait(MobType.class).setType(type.toString());
|
||||
npc.addTrait(LookClose.class);
|
||||
npc.addTrait(Text.class);
|
||||
|
||||
npc.spawn(player.getLocation());
|
||||
|
||||
// Set age after entity spawns
|
||||
if (npc.getBukkitEntity() instanceof Ageable)
|
||||
npc.getTrait(Age.class).setAge(age);
|
||||
|
||||
selector.select(player, npc);
|
||||
Messaging.send(player, msg);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "npc" },
|
||||
usage = "despawn",
|
||||
usage = "despawn (id)",
|
||||
desc = "Despawn a NPC",
|
||||
modifiers = { "despawn" },
|
||||
min = 1,
|
||||
max = 1,
|
||||
max = 2,
|
||||
permission = "npc.despawn")
|
||||
public void despawn(CommandContext args, CommandSender sender, NPC npc) {
|
||||
@Requirements
|
||||
public void despawn(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||
if (npc == null || args.argsLength() == 2) {
|
||||
if (args.argsLength() < 2)
|
||||
throw new CommandException("No NPC selected.");
|
||||
npc = CitizensAPI.getNPCRegistry().getById(args.getInteger(2));
|
||||
if (npc == null)
|
||||
throw new CommandException("No NPC found with that ID.");
|
||||
}
|
||||
npc.getTrait(Spawned.class).setSpawned(false);
|
||||
npc.despawn();
|
||||
Messaging.send(sender, ChatColor.GREEN + "You despawned " + StringHelper.wrap(npc.getName()) + ".");
|
||||
@ -267,17 +245,6 @@ public class NPCCommands {
|
||||
npcs.add(add);
|
||||
}
|
||||
}
|
||||
|
||||
if (args.hasValueFlag("char")) {
|
||||
String character = args.getFlag("char");
|
||||
if (characterManager.getCharacter(character) == null)
|
||||
throw new CommandException("'" + character + "' is not a valid character.");
|
||||
|
||||
for (NPC add : npcRegistry.getNPCs(characterManager.getCharacter(character).getClass())) {
|
||||
if (!npcs.contains(add))
|
||||
npcs.add(add);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Paginator paginator = new Paginator().header("NPCs");
|
||||
@ -308,26 +275,23 @@ public class NPCCommands {
|
||||
Messaging.send(sender, msg + " when a player is nearby.");
|
||||
}
|
||||
|
||||
@Command(aliases = { "npc" }, desc = "Show basic NPC information", max = 0)
|
||||
public void npc(CommandContext args, CommandSender sender, NPC npc) {
|
||||
Messaging.send(sender, StringHelper.wrapHeader(npc.getName()));
|
||||
Messaging.send(sender, " <a>ID: <e>" + npc.getId());
|
||||
Messaging.send(sender, " <a>Character: <e>"
|
||||
+ (npc.getCharacter() != null ? npc.getCharacter().getName() : "None"));
|
||||
Messaging.send(sender, " <a>Type: <e>" + npc.getTrait(MobType.class).getType());
|
||||
}
|
||||
|
||||
@Command(aliases = { "npc" }, usage = "moveto", desc = "Teleports a NPC to a given location", modifiers = "moveto",
|
||||
min = 1, max = 1, permission = "npc.moveto")
|
||||
@Command(
|
||||
aliases = { "npc" },
|
||||
usage = "moveto",
|
||||
desc = "Teleports a NPC to a given location",
|
||||
modifiers = "moveto",
|
||||
min = 1,
|
||||
max = 1,
|
||||
permission = "npc.moveto")
|
||||
public void moveto(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||
// Spawn the NPC if it isn't spawned to prevent NPEs
|
||||
if (!npc.isSpawned())
|
||||
npc.spawn(npc.getTrait(CurrentLocation.class).getLocation());
|
||||
Location current = npc.getBukkitEntity().getLocation();
|
||||
Location to = current.clone();
|
||||
if (args.hasValueFlag("x"))
|
||||
if (args.hasValueFlag("x"))
|
||||
to.setX(args.getFlagInteger("x"));
|
||||
if (args.hasValueFlag("y"))
|
||||
if (args.hasValueFlag("y"))
|
||||
to.setY(args.getFlagInteger("y"));
|
||||
if (args.hasValueFlag("z"))
|
||||
to.setZ(args.getFlagInteger("z"));
|
||||
@ -335,16 +299,24 @@ public class NPCCommands {
|
||||
to.setYaw((float) args.getFlagDouble("yaw"));
|
||||
if (args.hasValueFlag("pitch"))
|
||||
to.setPitch((float) args.getFlagDouble("pitch"));
|
||||
if (args.hasValueFlag("world")){
|
||||
if (args.hasValueFlag("world")) {
|
||||
World world = Bukkit.getWorld(args.getFlag("world"));
|
||||
if (world == null)
|
||||
throw new CommandException("Given world not found.");
|
||||
to.setWorld(world);
|
||||
}
|
||||
|
||||
npc.getBukkitEntity().teleport(to, TeleportCause.COMMAND);
|
||||
Messaging.send(sender, StringHelper.wrap(npc.getName()) + " was teleported to " + to + ".");
|
||||
}
|
||||
|
||||
|
||||
@Command(aliases = { "npc" }, desc = "Show basic NPC information", max = 0)
|
||||
public void npc(CommandContext args, CommandSender sender, NPC npc) {
|
||||
Messaging.send(sender, StringHelper.wrapHeader(npc.getName()));
|
||||
Messaging.send(sender, " <a>ID: <e>" + npc.getId());
|
||||
Messaging.send(sender, " <a>Type: <e>" + npc.getTrait(MobType.class).getType());
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "npc" },
|
||||
usage = "owner [name]",
|
||||
@ -394,11 +366,10 @@ public class NPCCommands {
|
||||
public void profession(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||
String profession = args.getString(1);
|
||||
try {
|
||||
npc.getTrait(VillagerProfession.class).setProfession(Profession.valueOf(profession.toUpperCase()));
|
||||
Messaging.send(
|
||||
sender,
|
||||
StringHelper.wrap(npc.getName()) + " is now the profession "
|
||||
+ StringHelper.wrap(profession.toUpperCase()) + ".");
|
||||
npc.getTrait(VillagerProfession.class)
|
||||
.setProfession(Profession.valueOf(profession.toUpperCase()));
|
||||
Messaging.send(sender, StringHelper.wrap(npc.getName()) + " is now the profession "
|
||||
+ StringHelper.wrap(profession.toUpperCase()) + ".");
|
||||
} catch (IllegalArgumentException ex) {
|
||||
throw new CommandException("'" + profession + "' is not a valid profession.");
|
||||
}
|
||||
@ -431,7 +402,7 @@ public class NPCCommands {
|
||||
throw new CommandException("You must be the owner of this NPC to execute that command.");
|
||||
if (!player.hasPermission("citizens.npc.remove") && !player.hasPermission("citizens.admin"))
|
||||
throw new NoPermissionsException();
|
||||
npc.remove();
|
||||
npc.destroy();
|
||||
Messaging.send(player, "<a>You permanently removed " + StringHelper.wrap(npc.getName()) + ".");
|
||||
}
|
||||
|
||||
@ -447,11 +418,13 @@ public class NPCCommands {
|
||||
String oldName = npc.getName();
|
||||
String newName = args.getString(1);
|
||||
if (newName.length() > 16) {
|
||||
Messaging.sendError(sender, "NPC names cannot be longer than 16 characters. The name has been shortened.");
|
||||
Messaging.sendError(sender,
|
||||
"NPC names cannot be longer than 16 characters. The name has been shortened.");
|
||||
newName = newName.substring(0, 15);
|
||||
}
|
||||
npc.setName(newName);
|
||||
String msg = String.format("You renamed %s to %s.", StringHelper.wrap(oldName), StringHelper.wrap(newName));
|
||||
String msg = String.format("You renamed %s to %s.", StringHelper.wrap(oldName),
|
||||
StringHelper.wrap(newName));
|
||||
Messaging.send(sender, ChatColor.GREEN + msg);
|
||||
}
|
||||
|
||||
@ -465,7 +438,7 @@ public class NPCCommands {
|
||||
permission = "npc.select")
|
||||
@Requirements(ownership = true)
|
||||
public void select(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||
NPC toSelect = npcRegistry.getNPC(args.getInteger(1));
|
||||
NPC toSelect = npcRegistry.getById(args.getInteger(1));
|
||||
if (toSelect == null || !toSelect.getTrait(Spawned.class).shouldSpawn())
|
||||
throw new CommandException("No NPC with the ID '" + args.getInteger(1) + "' is spawned.");
|
||||
if (npc != null && toSelect.getId() == npc.getId())
|
||||
@ -482,38 +455,24 @@ public class NPCCommands {
|
||||
min = 2,
|
||||
max = 2,
|
||||
permission = "npc.spawn")
|
||||
@Requirements
|
||||
public void spawn(CommandContext args, Player player, NPC npc) throws CommandException {
|
||||
NPC respawn = npcRegistry.getNPC(args.getInteger(1));
|
||||
@Requirements(ownership = true)
|
||||
public void spawn(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||
NPC respawn = npcRegistry.getById(args.getInteger(1));
|
||||
if (respawn == null)
|
||||
throw new CommandException("No NPC with the ID '" + args.getInteger(1) + "' exists.");
|
||||
|
||||
if (!respawn.getTrait(Owner.class).isOwnedBy(player))
|
||||
throw new CommandException("You must be the owner of this NPC to execute that command.");
|
||||
|
||||
if (respawn.spawn(player.getLocation())) {
|
||||
selector.select(player, respawn);
|
||||
Messaging.send(player, ChatColor.GREEN + "You respawned " + StringHelper.wrap(respawn.getName())
|
||||
+ " at your location.");
|
||||
} else
|
||||
if (respawn.isSpawned())
|
||||
throw new CommandException(respawn.getName() + " is already spawned at another location."
|
||||
+ " Use '/npc tphere' to teleport the NPC to your location.");
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "npc" },
|
||||
usage = "controllable",
|
||||
desc = "Toggles whether the NPC can be ridden and controlled",
|
||||
modifiers = { "controllable" },
|
||||
min = 1,
|
||||
max = 1,
|
||||
permission = "npc.controllable")
|
||||
public void controllable(CommandContext args, CommandSender sender, NPC npc) {
|
||||
boolean enabled = npc.getTrait(Controllable.class).toggle();
|
||||
if (enabled) {
|
||||
Messaging.send(sender, StringHelper.wrap(npc.getName()) + " can now be controlled.");
|
||||
} else {
|
||||
Messaging.send(sender, StringHelper.wrap(npc.getName()) + " can no longer be controlled.");
|
||||
Location location = respawn.getTrait(CurrentLocation.class).getLocation();
|
||||
if (location == null && sender instanceof Player)
|
||||
location = ((Player) sender).getLocation();
|
||||
else
|
||||
throw new CommandException("No stored location available - command must be used ingame.");
|
||||
if (respawn.spawn(location)) {
|
||||
selector.select(sender, respawn);
|
||||
Messaging.send(sender, ChatColor.GREEN + "You respawned " + StringHelper.wrap(respawn.getName())
|
||||
+ " at your location.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -530,11 +489,12 @@ public class NPCCommands {
|
||||
if (!npc.isSpawned())
|
||||
npc.spawn(npc.getTrait(CurrentLocation.class).getLocation());
|
||||
player.teleport(npc.getBukkitEntity(), TeleportCause.COMMAND);
|
||||
Messaging.send(player, ChatColor.GREEN + "You teleported to " + StringHelper.wrap(npc.getName()) + ".");
|
||||
Messaging.send(player, ChatColor.GREEN + "You teleported to " + StringHelper.wrap(npc.getName())
|
||||
+ ".");
|
||||
}
|
||||
|
||||
@Command(aliases = { "npc" }, usage = "tphere", desc = "Teleport a NPC to your location", modifiers = { "tphere",
|
||||
"move" }, min = 1, max = 1, permission = "npc.tphere")
|
||||
@Command(aliases = { "npc" }, usage = "tphere", desc = "Teleport a NPC to your location", modifiers = {
|
||||
"tphere", "move" }, min = 1, max = 1, permission = "npc.tphere")
|
||||
public void tphere(CommandContext args, Player player, NPC npc) {
|
||||
// Spawn the NPC if it isn't spawned to prevent NPEs
|
||||
if (!npc.isSpawned())
|
||||
@ -542,4 +502,21 @@ public class NPCCommands {
|
||||
npc.getBukkitEntity().teleport(player, TeleportCause.COMMAND);
|
||||
Messaging.send(player, StringHelper.wrap(npc.getName()) + " was teleported to your location.");
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "npc" },
|
||||
usage = "trait [trait name]",
|
||||
desc = "Adds a trait to the NPC",
|
||||
modifiers = { "trait" },
|
||||
min = 2,
|
||||
max = 2,
|
||||
permission = "npc.trait")
|
||||
public void trait(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||
Trait trait = CitizensAPI.getTraitFactory().getTrait(args.getString(1));
|
||||
if (trait == null)
|
||||
throw new CommandException("Trait not found.");
|
||||
npc.addTrait(trait);
|
||||
Messaging.sendF(sender, ChatColor.GREEN + "Trait %s added successfully.",
|
||||
StringHelper.wrap(trait.getName()));
|
||||
}
|
||||
}
|
@ -37,6 +37,10 @@ public class ScriptCommands {
|
||||
if (!file.exists())
|
||||
throw new CommandException("The file '" + args.getString(1) + "' doesn't exist!");
|
||||
CitizensAPI.getScriptCompiler().compile(file).withCallback(new CompileCallback() {
|
||||
@Override
|
||||
public void onCompileTaskFinished() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScriptCompiled(ScriptFactory script) {
|
||||
Script s = script.newInstance();
|
||||
@ -47,10 +51,6 @@ public class ScriptCommands {
|
||||
}
|
||||
Messaging.send(sender, "<a>Done.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCompileTaskFinished() {
|
||||
}
|
||||
}).begin();
|
||||
sender.sendMessage("Compiling...");
|
||||
}
|
||||
|
@ -1,47 +0,0 @@
|
||||
package net.citizensnpcs.npc;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import net.citizensnpcs.Metrics;
|
||||
import net.citizensnpcs.Metrics.Graph;
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.exception.CharacterException;
|
||||
import net.citizensnpcs.api.npc.character.Character;
|
||||
import net.citizensnpcs.api.npc.character.CharacterFactory;
|
||||
import net.citizensnpcs.api.npc.character.CharacterManager;
|
||||
import net.citizensnpcs.util.StringHelper;
|
||||
|
||||
public class CitizensCharacterManager implements CharacterManager {
|
||||
private final Map<String, Character> registered = new HashMap<String, Character>();
|
||||
|
||||
@Override
|
||||
public Character getCharacter(String name) {
|
||||
return registered.get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerCharacter(CharacterFactory factory) {
|
||||
try {
|
||||
Character character = factory.create();
|
||||
registered.put(character.getName(), character); // TODO: this only
|
||||
// allows singletons
|
||||
// for characters.
|
||||
} catch (CharacterException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void addPlotters(Metrics metrics) {
|
||||
Graph graph = metrics.createGraph("Character Type Usage");
|
||||
for (final Character character : registered.values()) {
|
||||
graph.addPlotter(new Metrics.Plotter(StringHelper.capitalize(character.getName())) {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return CitizensAPI.getNPCRegistry().getNPCs(character.getClass()).size();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,48 +1,31 @@
|
||||
package net.citizensnpcs.npc;
|
||||
|
||||
import net.citizensnpcs.Settings.Setting;
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.ai.Navigator;
|
||||
import net.citizensnpcs.api.event.NPCDespawnEvent;
|
||||
import net.citizensnpcs.api.event.NPCSpawnEvent;
|
||||
import net.citizensnpcs.api.exception.NPCLoadException;
|
||||
import net.citizensnpcs.api.npc.AbstractNPC;
|
||||
import net.citizensnpcs.api.npc.character.Character;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.trait.trait.Spawned;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
import net.citizensnpcs.npc.ai.CitizensAI;
|
||||
import net.citizensnpcs.npc.ai.CitizensNavigator;
|
||||
import net.citizensnpcs.trait.CurrentLocation;
|
||||
import net.citizensnpcs.util.Messaging;
|
||||
import net.citizensnpcs.util.StringHelper;
|
||||
import net.minecraft.server.EntityLiving;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
|
||||
public abstract class CitizensNPC extends AbstractNPC {
|
||||
private final CitizensAI ai = new CitizensAI(this);
|
||||
protected EntityLiving mcEntity;
|
||||
private final CitizensTraitManager traitManager;
|
||||
private final CitizensNavigator navigator = new CitizensNavigator(this);
|
||||
|
||||
protected CitizensNPC(int id, String name) {
|
||||
super(id, name);
|
||||
traitManager = (CitizensTraitManager) CitizensAPI.getTraitManager();
|
||||
// TODO: remove this dependency
|
||||
}
|
||||
|
||||
@Override
|
||||
public void chat(Player player, String message) {
|
||||
Messaging.sendWithNPC(player, Setting.CHAT_PREFIX.asString() + message, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void chat(String message) {
|
||||
for (Player player : Bukkit.getOnlinePlayers())
|
||||
chat(player, message);
|
||||
}
|
||||
|
||||
protected abstract EntityLiving createHandle(Location loc);
|
||||
@ -57,18 +40,13 @@ public abstract class CitizensNPC extends AbstractNPC {
|
||||
Bukkit.getPluginManager().callEvent(new NPCDespawnEvent(this));
|
||||
boolean keepSelected = getTrait(Spawned.class).shouldSpawn();
|
||||
if (!keepSelected)
|
||||
removeMetadata("selectors", CitizensAPI.getPlugin());
|
||||
data().remove("selectors");
|
||||
getBukkitEntity().remove();
|
||||
mcEntity = null;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CitizensAI getAI() {
|
||||
return ai;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LivingEntity getBukkitEntity() {
|
||||
return (LivingEntity) getHandle().getBukkitEntity();
|
||||
@ -79,15 +57,13 @@ public abstract class CitizensNPC extends AbstractNPC {
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.inventory.Inventory getInventory() {
|
||||
Inventory inventory = Bukkit.getServer().createInventory(this, 36, StringHelper.parseColors(getFullName()));
|
||||
inventory.setContents(getTrait(net.citizensnpcs.api.trait.trait.Inventory.class).getContents());
|
||||
return inventory;
|
||||
public Navigator getNavigator() {
|
||||
return navigator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trait getTraitFor(Class<? extends Trait> clazz) {
|
||||
return traitManager.getTrait(clazz, this);
|
||||
return CitizensAPI.getTraitFactory().getTrait(clazz);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -96,30 +72,18 @@ public abstract class CitizensNPC extends AbstractNPC {
|
||||
}
|
||||
|
||||
public void load(DataKey root) {
|
||||
Character character = CitizensAPI.getCharacterManager().getCharacter(root.getString("character"));
|
||||
|
||||
// Load the character if it exists
|
||||
if (character != null) {
|
||||
try {
|
||||
character.load(root.getRelative("characters." + character.getName()));
|
||||
} catch (NPCLoadException e) {
|
||||
Messaging.severe(String.format("Unable to load character '%s': %s.", character.getName(),
|
||||
e.getMessage()));
|
||||
}
|
||||
setCharacter(character);
|
||||
}
|
||||
|
||||
// Load traits
|
||||
for (DataKey traitKey : root.getRelative("traits").getSubKeys()) {
|
||||
Trait trait = traitManager.getTrait(traitKey.name(), this);
|
||||
Trait trait = CitizensAPI.getTraitFactory().getTrait(traitKey.name());
|
||||
if (trait == null) {
|
||||
Messaging.severeF("Skipped missing trait '%s' while loading NPC ID: '%d'. Has the name changed?",
|
||||
Messaging.severeF(
|
||||
"Skipped missing trait '%s' while loading NPC ID: '%d'. Has the name changed?",
|
||||
traitKey.name(), getId());
|
||||
continue;
|
||||
}
|
||||
addTrait(trait);
|
||||
try {
|
||||
getTrait(trait.getClass()).load(traitKey);
|
||||
trait.load(traitKey);
|
||||
} catch (NPCLoadException ex) {
|
||||
Messaging.logF("The trait '%s' failed to load for NPC ID: '%d'.", traitKey.name(), getId(),
|
||||
ex.getMessage());
|
||||
@ -134,32 +98,15 @@ public abstract class CitizensNPC extends AbstractNPC {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
super.remove();
|
||||
CitizensAPI.getNPCRegistry().deregister(this);
|
||||
}
|
||||
|
||||
public void save(DataKey root) {
|
||||
root.setString("name", getFullName());
|
||||
|
||||
// Save the character if it exists
|
||||
if (getCharacter() != null) {
|
||||
root.setString("character", getCharacter().getName());
|
||||
getCharacter().save(root.getRelative("characters." + getCharacter().getName()));
|
||||
}
|
||||
|
||||
// Save all existing traits
|
||||
for (Trait trait : traits.values()) {
|
||||
trait.save(root.getRelative("traits." + trait.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
super.setName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean spawn(Location loc) {
|
||||
Validate.notNull(loc, "location cannot be null");
|
||||
@ -176,6 +123,8 @@ public abstract class CitizensNPC extends AbstractNPC {
|
||||
|
||||
mcEntity.world.addEntity(mcEntity);
|
||||
mcEntity.world.players.remove(mcEntity);
|
||||
getBukkitEntity().setMetadata(NPC_METADATA_MARKER,
|
||||
new FixedMetadataValue(CitizensAPI.getPlugin(), true));
|
||||
|
||||
// Set the spawned state
|
||||
getTrait(CurrentLocation.class).setLocation(loc);
|
||||
@ -183,7 +132,7 @@ public abstract class CitizensNPC extends AbstractNPC {
|
||||
|
||||
// Modify NPC using traits after the entity has been created
|
||||
for (Trait trait : traits.values())
|
||||
trait.onNPCSpawn();
|
||||
trait.onSpawn();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -191,10 +140,13 @@ public abstract class CitizensNPC extends AbstractNPC {
|
||||
public void update() {
|
||||
try {
|
||||
super.update();
|
||||
ai.update();
|
||||
if (isSpawned())
|
||||
navigator.update();
|
||||
} catch (Exception ex) {
|
||||
Messaging.logF("Exception while updating %d: %s.", getId(), ex.getMessage());
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static final String NPC_METADATA_MARKER = "NPC";
|
||||
}
|
@ -1,17 +1,13 @@
|
||||
package net.citizensnpcs.npc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.npc.NPCRegistry;
|
||||
import net.citizensnpcs.api.npc.character.Character;
|
||||
import net.citizensnpcs.api.util.Storage;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.npc.entity.CitizensBlazeNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensCaveSpiderNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensChickenNPC;
|
||||
@ -82,67 +78,17 @@ public class CitizensNPCRegistry implements NPCRegistry {
|
||||
types.put(EntityType.ZOMBIE, CitizensZombieNPC.class);
|
||||
}
|
||||
|
||||
public NPC createNPC(EntityType type, int id, String name, Character character) {
|
||||
public NPC createNPC(EntityType type, int id, String name) {
|
||||
CitizensNPC npc = getByType(type, id, name);
|
||||
if (npc == null)
|
||||
throw new IllegalStateException("Could not create NPC.");
|
||||
if (character != null)
|
||||
npc.setCharacter(character);
|
||||
npcs.put(npc.getId(), npc);
|
||||
return npc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC createNPC(EntityType type, String name) {
|
||||
return createNPC(type, name, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC createNPC(EntityType type, String name, Character character) {
|
||||
return createNPC(type, generateUniqueId(), name, character);
|
||||
}
|
||||
|
||||
private int generateUniqueId() {
|
||||
int count = 0;
|
||||
while (getNPC(count++) != null)
|
||||
; // TODO: doesn't respect existing save data that might not have
|
||||
// been loaded. This causes DBs with NPCs that weren't loaded to
|
||||
// have conflicting primary keys.
|
||||
return count - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC(Entity entity) {
|
||||
Validate.notNull(entity);
|
||||
net.minecraft.server.Entity handle = ((CraftEntity) entity).getHandle();
|
||||
return handle instanceof NPCHandle ? ((NPCHandle) handle).getNPC() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC(int id) {
|
||||
if (id < 0)
|
||||
throw new IllegalArgumentException("invalid id");
|
||||
return npcs.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<NPC> getNPCs(Class<? extends Character> character) {
|
||||
List<NPC> npcs = new ArrayList<NPC>();
|
||||
for (NPC npc : this) {
|
||||
if (npc.getCharacter() != null && npc.getCharacter().getClass().equals(character))
|
||||
npcs.add(npc);
|
||||
}
|
||||
return npcs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNPC(Entity entity) {
|
||||
return getNPC(entity) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<NPC> iterator() {
|
||||
return npcs.iterator();
|
||||
return createNPC(type, generateUniqueId(), name);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -163,6 +109,22 @@ public class CitizensNPCRegistry implements NPCRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
private int generateUniqueId() {
|
||||
int count = 0;
|
||||
while (getById(count++) != null)
|
||||
; // TODO: doesn't respect existing save data that might not have
|
||||
// been loaded. This causes DBs with NPCs that weren't loaded to
|
||||
// have conflicting primary keys.
|
||||
return count - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getById(int id) {
|
||||
if (id < 0)
|
||||
throw new IllegalArgumentException("invalid id");
|
||||
return npcs.get(id);
|
||||
}
|
||||
|
||||
private CitizensNPC getByType(EntityType type, int id, String name) {
|
||||
Class<? extends CitizensNPC> npcClass = types.get(type);
|
||||
if (npcClass == null)
|
||||
@ -173,4 +135,21 @@ public class CitizensNPCRegistry implements NPCRegistry {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC(Entity entity) {
|
||||
Validate.notNull(entity);
|
||||
net.minecraft.server.Entity handle = ((CraftEntity) entity).getHandle();
|
||||
return handle instanceof NPCHolder ? ((NPCHolder) handle).getNPC() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNPC(Entity entity) {
|
||||
return getNPC(entity) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<NPC> iterator() {
|
||||
return npcs.iterator();
|
||||
}
|
||||
}
|
104
src/main/java/net/citizensnpcs/npc/CitizensTraitFactory.java
Normal file
104
src/main/java/net/citizensnpcs/npc/CitizensTraitFactory.java
Normal file
@ -0,0 +1,104 @@
|
||||
package net.citizensnpcs.npc;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import net.citizensnpcs.Metrics;
|
||||
import net.citizensnpcs.Metrics.Graph;
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.trait.TraitInfo;
|
||||
import net.citizensnpcs.api.trait.TraitFactory;
|
||||
import net.citizensnpcs.api.trait.trait.Equipment;
|
||||
import net.citizensnpcs.api.trait.trait.Inventory;
|
||||
import net.citizensnpcs.api.trait.trait.MobType;
|
||||
import net.citizensnpcs.api.trait.trait.Owner;
|
||||
import net.citizensnpcs.api.trait.trait.Spawned;
|
||||
import net.citizensnpcs.trait.Age;
|
||||
import net.citizensnpcs.trait.Behaviour;
|
||||
import net.citizensnpcs.trait.Controllable;
|
||||
import net.citizensnpcs.trait.CurrentLocation;
|
||||
import net.citizensnpcs.trait.LookClose;
|
||||
import net.citizensnpcs.trait.Powered;
|
||||
import net.citizensnpcs.trait.Saddle;
|
||||
import net.citizensnpcs.trait.Sheared;
|
||||
import net.citizensnpcs.trait.VillagerProfession;
|
||||
import net.citizensnpcs.trait.WoolColor;
|
||||
import net.citizensnpcs.trait.text.Text;
|
||||
import net.citizensnpcs.trait.waypoint.Waypoints;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
public class CitizensTraitFactory implements TraitFactory {
|
||||
private final Map<String, Class<? extends Trait>> registered = Maps.newHashMap();
|
||||
|
||||
// TODO: find a way to avoid naming conflicts
|
||||
public CitizensTraitFactory() {
|
||||
registerTrait(TraitInfo.create(Age.class).withName("age"));
|
||||
registerTrait(TraitInfo.create(CurrentLocation.class).withName("location"));
|
||||
registerTrait(TraitInfo.create(Equipment.class).withName("equipment"));
|
||||
registerTrait(TraitInfo.create(Inventory.class).withName("inventory"));
|
||||
registerTrait(TraitInfo.create(LookClose.class).withName("lookclose"));
|
||||
registerTrait(TraitInfo.create(MobType.class).withName("type"));
|
||||
registerTrait(TraitInfo.create(Owner.class).withName("owner"));
|
||||
registerTrait(TraitInfo.create(Powered.class).withName("powered"));
|
||||
registerTrait(TraitInfo.create(Saddle.class).withName("saddle"));
|
||||
registerTrait(TraitInfo.create(Sheared.class).withName("sheared"));
|
||||
registerTrait(TraitInfo.create(Spawned.class).withName("spawned"));
|
||||
registerTrait(TraitInfo.create(Text.class).withName("text"));
|
||||
registerTrait(TraitInfo.create(VillagerProfession.class).withName("profession"));
|
||||
registerTrait(TraitInfo.create(Waypoints.class).withName("waypoints"));
|
||||
registerTrait(TraitInfo.create(WoolColor.class).withName("woolcolor"));
|
||||
registerTrait(TraitInfo.create(Controllable.class).withName("controllable"));
|
||||
registerTrait(TraitInfo.create(Behaviour.class).withName("behaviour"));
|
||||
}
|
||||
|
||||
public void addPlotters(Graph graph) {
|
||||
for (Map.Entry<String, Class<? extends Trait>> entry : registered.entrySet()) {
|
||||
final Class<? extends Trait> traitClass = entry.getValue();
|
||||
graph.addPlotter(new Metrics.Plotter(entry.getKey()) {
|
||||
@Override
|
||||
public int getValue() {
|
||||
int numberUsingTrait = 0;
|
||||
for (NPC npc : CitizensAPI.getNPCRegistry()) {
|
||||
if (npc.hasTrait(traitClass))
|
||||
++numberUsingTrait;
|
||||
}
|
||||
return numberUsingTrait;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private <T extends Trait> T create(Class<T> trait) {
|
||||
try {
|
||||
return trait.newInstance();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Trait> T getTrait(Class<T> clazz) {
|
||||
if (!registered.containsValue(clazz))
|
||||
return null;
|
||||
return create(clazz);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Trait> T getTrait(String name) {
|
||||
Class<? extends Trait> clazz = registered.get(name);
|
||||
if (clazz == null)
|
||||
return null;
|
||||
return (T) create(clazz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerTrait(TraitInfo info) {
|
||||
Preconditions.checkNotNull(info, "info cannot be null");
|
||||
registered.put(info.getTraitName(), info.getTraitClass());
|
||||
}
|
||||
}
|
@ -1,139 +0,0 @@
|
||||
package net.citizensnpcs.npc;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.trait.TraitFactory;
|
||||
import net.citizensnpcs.api.trait.TraitManager;
|
||||
import net.citizensnpcs.api.trait.trait.Equipment;
|
||||
import net.citizensnpcs.api.trait.trait.Inventory;
|
||||
import net.citizensnpcs.api.trait.trait.MobType;
|
||||
import net.citizensnpcs.api.trait.trait.Owner;
|
||||
import net.citizensnpcs.api.trait.trait.Spawned;
|
||||
import net.citizensnpcs.trait.Age;
|
||||
import net.citizensnpcs.trait.Behaviour;
|
||||
import net.citizensnpcs.trait.Controllable;
|
||||
import net.citizensnpcs.trait.CurrentLocation;
|
||||
import net.citizensnpcs.trait.LookClose;
|
||||
import net.citizensnpcs.trait.Powered;
|
||||
import net.citizensnpcs.trait.Saddle;
|
||||
import net.citizensnpcs.trait.Sheared;
|
||||
import net.citizensnpcs.trait.VillagerProfession;
|
||||
import net.citizensnpcs.trait.WoolColor;
|
||||
import net.citizensnpcs.trait.text.Text;
|
||||
import net.citizensnpcs.trait.waypoint.Waypoints;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class CitizensTraitManager implements TraitManager {
|
||||
private final Map<Class<? extends Trait>, Constructor<? extends Trait>> CACHED_CTORS = new HashMap<Class<? extends Trait>, Constructor<? extends Trait>>();
|
||||
private final Map<Plugin, Map<String, Class<? extends Trait>>> registered = new HashMap<Plugin, Map<String, Class<? extends Trait>>>();
|
||||
|
||||
// TODO: handle Plugin-setting/names better and avoid cruft. also find a
|
||||
// way to avoid naming conflicts
|
||||
public CitizensTraitManager(Plugin plugin) {
|
||||
registerTrait(new TraitFactory(Age.class).withName("age").withPlugin(plugin));
|
||||
registerTrait(new TraitFactory(CurrentLocation.class).withName("location").withPlugin(plugin));
|
||||
registerTrait(new TraitFactory(Equipment.class).withName("equipment").withPlugin(plugin));
|
||||
registerTrait(new TraitFactory(Inventory.class).withName("inventory").withPlugin(plugin));
|
||||
registerTrait(new TraitFactory(LookClose.class).withName("lookclose").withPlugin(plugin));
|
||||
registerTrait(new TraitFactory(MobType.class).withName("type").withPlugin(plugin));
|
||||
registerTrait(new TraitFactory(Owner.class).withName("owner").withPlugin(plugin));
|
||||
registerTrait(new TraitFactory(Powered.class).withName("powered").withPlugin(plugin));
|
||||
registerTrait(new TraitFactory(Saddle.class).withName("saddle").withPlugin(plugin));
|
||||
registerTrait(new TraitFactory(Sheared.class).withName("sheared").withPlugin(plugin));
|
||||
registerTrait(new TraitFactory(Spawned.class).withName("spawned").withPlugin(plugin));
|
||||
registerTrait(new TraitFactory(Text.class).withName("text").withPlugin(plugin));
|
||||
registerTrait(new TraitFactory(VillagerProfession.class).withName("profession").withPlugin(plugin));
|
||||
registerTrait(new TraitFactory(Waypoints.class).withName("waypoints").withPlugin(plugin));
|
||||
registerTrait(new TraitFactory(WoolColor.class).withName("woolcolor").withPlugin(plugin));
|
||||
registerTrait(new TraitFactory(Controllable.class).withName("controllable").withPlugin(plugin));
|
||||
registerTrait(new TraitFactory(Behaviour.class).withName("behaviour").withPlugin(plugin));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T extends Trait> T create(Class<T> trait, NPC npc) {
|
||||
Constructor<? extends Trait> constructor;
|
||||
|
||||
if (!CACHED_CTORS.containsKey(trait)) {
|
||||
try {
|
||||
// TODO: replace this fixed constructor with a context class
|
||||
// which can have extra environment variables.
|
||||
constructor = trait.getConstructor(NPC.class);
|
||||
if (constructor == null)
|
||||
constructor = trait.getConstructor(CitizensNPC.class);
|
||||
constructor.setAccessible(true);
|
||||
} catch (Exception ex) {
|
||||
constructor = null;
|
||||
}
|
||||
CACHED_CTORS.put(trait, constructor);
|
||||
} else
|
||||
constructor = CACHED_CTORS.get(trait);
|
||||
|
||||
try {
|
||||
if (constructor == null || npc == null)
|
||||
return trait.newInstance();
|
||||
return (T) constructor.newInstance(npc);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Trait> T getTrait(Class<T> clazz) {
|
||||
return getTrait(clazz, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Trait> T getTrait(Class<T> clazz, NPC npc) {
|
||||
for (Entry<Plugin, Map<String, Class<? extends Trait>>> entry : registered.entrySet()) {
|
||||
for (Entry<String, Class<? extends Trait>> subEntry : entry.getValue().entrySet()) {
|
||||
if (!subEntry.getValue().equals(clazz))
|
||||
continue;
|
||||
Trait trait = create(subEntry.getValue(), npc);
|
||||
if (trait == null)
|
||||
return null;
|
||||
trait.setPlugin(entry.getKey());
|
||||
trait.setName(subEntry.getKey());
|
||||
return (T) trait;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T extends Trait> T getTrait(String name) {
|
||||
for (Map<String, Class<? extends Trait>> entry : registered.values()) {
|
||||
if (!entry.containsKey(name))
|
||||
continue;
|
||||
return (T) create(entry.get(name), null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Trait> T getTrait(String name, NPC npc) {
|
||||
for (Map<String, Class<? extends Trait>> entry : registered.values()) {
|
||||
Class<? extends Trait> clazz = entry.get(name);
|
||||
if (clazz == null)
|
||||
continue;
|
||||
return (T) getTrait(clazz, npc);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerTrait(TraitFactory factory) {
|
||||
Map<String, Class<? extends Trait>> map = registered.get(factory.getTraitPlugin());
|
||||
if (map == null)
|
||||
map = new HashMap<String, Class<? extends Trait>>();
|
||||
map.put(factory.getTraitName(), factory.getTraitClass());
|
||||
registered.put(factory.getTraitPlugin(), map);
|
||||
}
|
||||
}
|
@ -22,15 +22,48 @@ import org.bukkit.metadata.FixedMetadataValue;
|
||||
import org.bukkit.metadata.MetadataValue;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
public class NPCSelector implements Listener {
|
||||
private final Plugin plugin;
|
||||
private int consoleSelectedNPC = -1;
|
||||
private final Plugin plugin;
|
||||
|
||||
public NPCSelector(Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
public NPC getSelected(CommandSender sender) {
|
||||
if (sender instanceof Player) {
|
||||
List<MetadataValue> metadata = ((Player) sender).getMetadata("selected");
|
||||
if (metadata.size() == 0)
|
||||
return null;
|
||||
return CitizensAPI.getNPCRegistry().getById(metadata.get(0).asInt());
|
||||
} else {
|
||||
if (consoleSelectedNPC == -1)
|
||||
return null;
|
||||
return CitizensAPI.getNPCRegistry().getById(consoleSelectedNPC);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onNPCRemove(NPCRemoveEvent event) {
|
||||
NPC npc = event.getNPC();
|
||||
List<String> selectors = npc.data().get("selectors");
|
||||
if (selectors == null)
|
||||
return;
|
||||
for (String value : selectors) {
|
||||
if (value.equals("console")) {
|
||||
consoleSelectedNPC = -1;
|
||||
} else {
|
||||
Player search = Bukkit.getPlayerExact(value);
|
||||
if (search != null)
|
||||
search.removeMetadata("selected", plugin);
|
||||
}
|
||||
}
|
||||
npc.data().remove("selectors");
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onNPCRightClick(NPCRightClickEvent event) {
|
||||
Player player = event.getClicker();
|
||||
@ -48,51 +81,24 @@ public class NPCSelector implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onNPCRemove(NPCRemoveEvent event) {
|
||||
NPC npc = event.getNPC();
|
||||
for (MetadataValue value : npc.getMetadata("selectors")) {
|
||||
if (value.asString().equals("console")) {
|
||||
consoleSelectedNPC = -1;
|
||||
} else {
|
||||
Player search = Bukkit.getPlayerExact(value.asString());
|
||||
if (search != null)
|
||||
search.removeMetadata("selected", plugin);
|
||||
}
|
||||
}
|
||||
npc.removeMetadata("selectors", plugin);
|
||||
}
|
||||
|
||||
public void select(CommandSender sender, NPC npc) {
|
||||
// Remove existing selection if any
|
||||
List<Object> selectors = npc.data().get("selectors", Lists.newArrayList());
|
||||
if (sender instanceof Player) {
|
||||
Player player = (Player) sender;
|
||||
if (player.hasMetadata("selected"))
|
||||
player.removeMetadata("selected", plugin);
|
||||
|
||||
player.setMetadata("selected", new FixedMetadataValue(plugin, npc.getId()));
|
||||
npc.setMetadata("selectors", new FixedMetadataValue(plugin, player.getName()));
|
||||
selectors.add(player.getName());
|
||||
|
||||
// Remove editor if the player has one
|
||||
Editor.leave(player);
|
||||
} else {
|
||||
consoleSelectedNPC = npc.getId();
|
||||
npc.setMetadata("selectors", new FixedMetadataValue(plugin, "console"));
|
||||
selectors.add("console");
|
||||
}
|
||||
|
||||
Bukkit.getPluginManager().callEvent(new NPCSelectEvent(npc, sender));
|
||||
}
|
||||
|
||||
public NPC getSelected(CommandSender sender) {
|
||||
if (sender instanceof Player) {
|
||||
List<MetadataValue> metadata = ((Player) sender).getMetadata("selected");
|
||||
if (metadata.size() == 0)
|
||||
return null;
|
||||
return CitizensAPI.getNPCRegistry().getNPC(metadata.get(0).asInt());
|
||||
} else {
|
||||
if (consoleSelectedNPC == -1)
|
||||
return null;
|
||||
return CitizensAPI.getNPCRegistry().getNPC(consoleSelectedNPC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,236 +0,0 @@
|
||||
package net.citizensnpcs.npc.ai;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import net.citizensnpcs.api.ai.AI;
|
||||
import net.citizensnpcs.api.ai.Goal;
|
||||
import net.citizensnpcs.api.ai.NavigationCallback;
|
||||
import net.citizensnpcs.api.ai.NavigationCallback.CancelReason;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
public class CitizensAI implements AI {
|
||||
private final List<WeakReference<NavigationCallback>> callbacks = Lists.newArrayList();
|
||||
private PathStrategy executing;
|
||||
private final List<GoalEntry> executingGoals = Lists.newArrayList();
|
||||
private final List<GoalEntry> goals = Lists.newArrayList();
|
||||
private List<Goal> toRemove = null;
|
||||
private final CitizensNPC npc;
|
||||
private boolean paused;
|
||||
|
||||
public CitizensAI(CitizensNPC npc) {
|
||||
this.npc = npc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGoal(int priority, Goal goal) {
|
||||
if (goals.contains(goal))
|
||||
return;
|
||||
goals.add(new GoalEntry(priority, goal));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelDestination() {
|
||||
if (executing == null)
|
||||
return;
|
||||
executing = null;
|
||||
for (int i = 0; i < callbacks.size(); ++i) {
|
||||
NavigationCallback next = callbacks.get(i).get();
|
||||
if (next == null || next.onCancel(this, CancelReason.CANCEL)) {
|
||||
callbacks.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDestination() {
|
||||
return executing != null;
|
||||
}
|
||||
|
||||
private boolean isGoalAllowable(GoalEntry test) {
|
||||
for (int i = 0; i < goals.size(); ++i) {
|
||||
GoalEntry item = goals.get(i);
|
||||
if (item == test)
|
||||
continue;
|
||||
if (test.getPriority() >= item.getPriority()) {
|
||||
if (!test.getGoal().isCompatibleWith(item.getGoal()) && executingGoals.contains(item)) {
|
||||
return false;
|
||||
}
|
||||
} /*else if (executingGoals.contains(item) && !item.goal.requiresUpdates()) {
|
||||
return false;
|
||||
}*/
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
paused = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerNavigationCallback(NavigationCallback callback) {
|
||||
if (!callbacks.contains(callback)) {
|
||||
callbacks.add(new WeakReference<NavigationCallback>(callback));
|
||||
callback.onAttach(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeGoal(Goal goal) {
|
||||
if (toRemove == null)
|
||||
toRemove = Lists.newArrayList();
|
||||
toRemove.add(goal);
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
paused = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDestination(Location destination) {
|
||||
if (destination == null)
|
||||
throw new IllegalArgumentException("destination cannot be null");
|
||||
if (!npc.isSpawned())
|
||||
throw new IllegalStateException("npc is not spawned");
|
||||
if (destination.getWorld() != npc.getBukkitEntity().getWorld())
|
||||
throw new IllegalArgumentException("location is not in the same world");
|
||||
|
||||
boolean replaced = executing != null;
|
||||
executing = new MCNavigationStrategy(npc, destination);
|
||||
|
||||
for (int i = 0; i < callbacks.size(); ++i) {
|
||||
NavigationCallback next = callbacks.get(i).get();
|
||||
if (next == null || (replaced && next.onCancel(this, CancelReason.REPLACE)) || next.onBegin(this)) {
|
||||
callbacks.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTarget(LivingEntity target, boolean aggressive) {
|
||||
if (target == null)
|
||||
throw new IllegalArgumentException("target cannot be null");
|
||||
|
||||
boolean replaced = executing != null;
|
||||
executing = new MCTargetStrategy(npc, target, aggressive);
|
||||
|
||||
for (int i = 0; i < callbacks.size(); ++i) {
|
||||
NavigationCallback next = callbacks.get(i).get();
|
||||
if (next == null || (replaced && next.onCancel(this, CancelReason.REPLACE)) || next.onBegin(this)) {
|
||||
callbacks.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void update() {
|
||||
if (paused || !npc.isSpawned()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (executing != null && executing.update()) {
|
||||
executing = null;
|
||||
for (int i = 0; i < callbacks.size(); ++i) {
|
||||
NavigationCallback next = callbacks.get(i).get();
|
||||
if (next == null || next.onCompletion(this)) {
|
||||
callbacks.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
removeGoals();
|
||||
for (int i = 0; i < goals.size(); ++i) {
|
||||
GoalEntry entry = goals.get(i);
|
||||
boolean executing = executingGoals.contains(entry);
|
||||
|
||||
if (executing) {
|
||||
if (!entry.getGoal().continueExecuting() || !isGoalAllowable(entry)) {
|
||||
entry.getGoal().reset();
|
||||
executingGoals.remove(entry);
|
||||
}
|
||||
} else if (entry.getGoal().shouldExecute() && isGoalAllowable(entry)) {
|
||||
entry.getGoal().start();
|
||||
executingGoals.add(entry);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < executingGoals.size(); ++i) {
|
||||
executingGoals.get(i).getGoal().update();
|
||||
}
|
||||
}
|
||||
|
||||
private void removeGoals() {
|
||||
if (toRemove == null)
|
||||
return;
|
||||
for (Goal goal : toRemove) {
|
||||
Iterator<GoalEntry> itr = executingGoals.iterator();
|
||||
while (itr.hasNext()) {
|
||||
GoalEntry entry = itr.next();
|
||||
if (entry.getGoal().equals(goal)) {
|
||||
entry.getGoal().reset();
|
||||
itr.remove();
|
||||
}
|
||||
}
|
||||
itr = goals.iterator();
|
||||
while (itr.hasNext()) {
|
||||
GoalEntry entry = itr.next();
|
||||
if (entry.getGoal().equals(goal))
|
||||
itr.remove();
|
||||
}
|
||||
}
|
||||
|
||||
toRemove = null;
|
||||
}
|
||||
|
||||
public static class GoalEntry implements Comparable<GoalEntry> {
|
||||
private final Goal goal;
|
||||
private final int priority;
|
||||
|
||||
public GoalEntry(int priority, Goal goal) {
|
||||
this.priority = priority;
|
||||
this.goal = goal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(GoalEntry o) {
|
||||
return o.priority > priority ? 1 : o.priority < priority ? -1 : 0;
|
||||
}
|
||||
|
||||
public Goal getGoal() {
|
||||
return goal;
|
||||
}
|
||||
|
||||
public int getPriority() {
|
||||
return priority;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31 + ((goal == null) ? 0 : goal.hashCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
GoalEntry other = (GoalEntry) obj;
|
||||
if (goal == null) {
|
||||
if (other.goal != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!goal.equals(other.goal)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
137
src/main/java/net/citizensnpcs/npc/ai/CitizensNavigator.java
Normal file
137
src/main/java/net/citizensnpcs/npc/ai/CitizensNavigator.java
Normal file
@ -0,0 +1,137 @@
|
||||
package net.citizensnpcs.npc.ai;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
|
||||
import net.citizensnpcs.api.ai.EntityTarget;
|
||||
import net.citizensnpcs.api.ai.Navigator;
|
||||
import net.citizensnpcs.api.ai.TargetType;
|
||||
import net.citizensnpcs.api.ai.event.NavigationBeginEvent;
|
||||
import net.citizensnpcs.api.ai.event.NavigationCancelEvent;
|
||||
import net.citizensnpcs.api.ai.event.NavigationReplaceEvent;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.minecraft.server.EntityLiving;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
public class CitizensNavigator implements Navigator {
|
||||
private PathStrategy executing;
|
||||
private final CitizensNPC npc;
|
||||
private float speed;
|
||||
|
||||
public CitizensNavigator(CitizensNPC npc) {
|
||||
this.npc = npc;
|
||||
this.speed = getSpeedFor(npc.getHandle());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelNavigation() {
|
||||
if (executing != null) {
|
||||
Bukkit.getPluginManager().callEvent(new NavigationCancelEvent(this));
|
||||
}
|
||||
executing = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityTarget getEntityTarget() {
|
||||
return executing instanceof EntityTarget ? (EntityTarget) executing : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getSpeed() {
|
||||
return speed;
|
||||
}
|
||||
|
||||
private float getSpeedFor(EntityLiving from) {
|
||||
EntityType entityType = from.getBukkitEntity().getType();
|
||||
Float cached = MOVEMENT_SPEEDS.get(entityType);
|
||||
if (cached != null)
|
||||
return cached;
|
||||
if (SPEED_FIELD == null) {
|
||||
MOVEMENT_SPEEDS.put(entityType, DEFAULT_SPEED);
|
||||
return DEFAULT_SPEED;
|
||||
}
|
||||
try {
|
||||
float speed = SPEED_FIELD.getFloat(from);
|
||||
MOVEMENT_SPEEDS.put(entityType, speed);
|
||||
return speed;
|
||||
} catch (IllegalAccessException ex) {
|
||||
ex.printStackTrace();
|
||||
return DEFAULT_SPEED;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getTargetAsLocation() {
|
||||
return executing.getTargetAsLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TargetType getTargetType() {
|
||||
return executing.getTargetType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNavigating() {
|
||||
return executing != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpeed(float speed) {
|
||||
this.speed = speed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTarget(LivingEntity target, boolean aggressive) {
|
||||
PathStrategy newStrategy = new MCTargetStrategy(npc, target, aggressive, speed);
|
||||
switchStrategyTo(newStrategy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTarget(Location target) {
|
||||
PathStrategy newStrategy = new MCNavigationStrategy(npc, target, speed);
|
||||
switchStrategyTo(newStrategy);
|
||||
}
|
||||
|
||||
private void switchStrategyTo(PathStrategy newStrategy) {
|
||||
if (executing != null)
|
||||
Bukkit.getPluginManager().callEvent(new NavigationReplaceEvent(this));
|
||||
|
||||
executing = newStrategy;
|
||||
|
||||
Bukkit.getPluginManager().callEvent(new NavigationBeginEvent(this));
|
||||
}
|
||||
|
||||
public void update() {
|
||||
if (executing == null)
|
||||
return;
|
||||
boolean finished = executing.update();
|
||||
if (finished) {
|
||||
Bukkit.getPluginManager().callEvent(new NavigationCompleteEvent(this));
|
||||
executing = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static final float DEFAULT_SPEED = 0.3F;
|
||||
private static final Map<EntityType, Float> MOVEMENT_SPEEDS = Maps.newEnumMap(EntityType.class);
|
||||
private static Field SPEED_FIELD;
|
||||
static {
|
||||
MOVEMENT_SPEEDS.put(EntityType.IRON_GOLEM, 0.15F);
|
||||
MOVEMENT_SPEEDS.put(EntityType.CHICKEN, 0.25F);
|
||||
MOVEMENT_SPEEDS.put(EntityType.COW, 0.2F);
|
||||
MOVEMENT_SPEEDS.put(EntityType.SHEEP, 0.25F);
|
||||
MOVEMENT_SPEEDS.put(EntityType.VILLAGER, 0.3F);
|
||||
MOVEMENT_SPEEDS.put(EntityType.SNOWMAN, 0.25F);
|
||||
try {
|
||||
SPEED_FIELD = EntityLiving.class.getDeclaredField("bb");
|
||||
SPEED_FIELD.setAccessible(true);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,82 +1,51 @@
|
||||
package net.citizensnpcs.npc.ai;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
|
||||
import net.citizensnpcs.api.ai.TargetType;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.minecraft.server.EntityLiving;
|
||||
import net.minecraft.server.Navigation;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
public class MCNavigationStrategy implements PathStrategy {
|
||||
private final EntityLiving entity;
|
||||
private final Navigation navigation;
|
||||
private final Location target;
|
||||
|
||||
MCNavigationStrategy(final CitizensNPC npc, final Location dest) {
|
||||
entity = npc.getHandle();
|
||||
if (npc.getBukkitEntity() instanceof Player) {
|
||||
MCNavigationStrategy(final CitizensNPC npc, Location dest, float speed) {
|
||||
this(npc.getHandle(), dest);
|
||||
navigation.a(dest.getX(), dest.getY(), dest.getZ(), speed);
|
||||
|
||||
}
|
||||
|
||||
MCNavigationStrategy(EntityLiving entity, EntityLiving target, float speed) {
|
||||
this(entity, target.getBukkitEntity().getLocation());
|
||||
navigation.a(target, speed);
|
||||
}
|
||||
|
||||
private MCNavigationStrategy(EntityLiving entity, Location target) {
|
||||
this.target = target;
|
||||
if (entity.getBukkitEntity() instanceof Player) {
|
||||
entity.onGround = true;
|
||||
// not sure of a better way around this - if onGround is false, then
|
||||
// navigation won't execute, and calling entity.move doesn't
|
||||
// entirely fix the problem.
|
||||
}
|
||||
navigation = entity.al();
|
||||
navigation.a(dest.getX(), dest.getY(), dest.getZ(), getSpeed(npc.getHandle()));
|
||||
|
||||
}
|
||||
|
||||
MCNavigationStrategy(EntityLiving entity, EntityLiving target) {
|
||||
this.entity = entity;
|
||||
if (entity.getBukkitEntity() instanceof Player) {
|
||||
entity.onGround = true; // see above
|
||||
}
|
||||
navigation = entity.al();
|
||||
navigation.a(target, getSpeed(entity));
|
||||
@Override
|
||||
public Location getTargetAsLocation() {
|
||||
return target;
|
||||
}
|
||||
|
||||
private float getSpeed(EntityLiving from) {
|
||||
Float cached = MOVEMENT_SPEEDS.get(from.getBukkitEntity().getType());
|
||||
if (cached != null)
|
||||
return cached;
|
||||
if (SPEED_FIELD == null) {
|
||||
MOVEMENT_SPEEDS.put(from.getBukkitEntity().getType(), DEFAULT_SPEED);
|
||||
return DEFAULT_SPEED;
|
||||
}
|
||||
try {
|
||||
float speed = SPEED_FIELD.getFloat(from);
|
||||
MOVEMENT_SPEEDS.put(from.getBukkitEntity().getType(), speed);
|
||||
return speed;
|
||||
} catch (IllegalAccessException ex) {
|
||||
ex.printStackTrace();
|
||||
return DEFAULT_SPEED;
|
||||
}
|
||||
@Override
|
||||
public TargetType getTargetType() {
|
||||
return TargetType.LOCATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update() {
|
||||
return navigation.e();
|
||||
}
|
||||
|
||||
private static final float DEFAULT_SPEED = 0.3F;
|
||||
private static final Map<EntityType, Float> MOVEMENT_SPEEDS = Maps.newEnumMap(EntityType.class);
|
||||
private static Field SPEED_FIELD;
|
||||
static {
|
||||
MOVEMENT_SPEEDS.put(EntityType.IRON_GOLEM, 0.15F);
|
||||
MOVEMENT_SPEEDS.put(EntityType.CHICKEN, 0.25F);
|
||||
MOVEMENT_SPEEDS.put(EntityType.COW, 0.2F);
|
||||
MOVEMENT_SPEEDS.put(EntityType.SHEEP, 0.25F);
|
||||
MOVEMENT_SPEEDS.put(EntityType.VILLAGER, 0.3F);
|
||||
MOVEMENT_SPEEDS.put(EntityType.SNOWMAN, 0.25F);
|
||||
try {
|
||||
SPEED_FIELD = EntityLiving.class.getDeclaredField("bb");
|
||||
SPEED_FIELD.setAccessible(true);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package net.citizensnpcs.npc.ai;
|
||||
|
||||
import net.citizensnpcs.api.ai.EntityTarget;
|
||||
import net.citizensnpcs.api.ai.TargetType;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.util.Util;
|
||||
import net.minecraft.server.EntityLiving;
|
||||
@ -7,17 +9,20 @@ import net.minecraft.server.EntityMonster;
|
||||
import net.minecraft.server.EntityPlayer;
|
||||
import net.minecraft.server.Packet18ArmAnimation;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.entity.CraftLivingEntity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
public class MCTargetStrategy implements PathStrategy {
|
||||
public class MCTargetStrategy implements PathStrategy, EntityTarget {
|
||||
private final boolean aggro;
|
||||
private final EntityLiving handle, target;
|
||||
private final float speed;
|
||||
|
||||
public MCTargetStrategy(CitizensNPC handle, LivingEntity target, boolean aggro) {
|
||||
public MCTargetStrategy(CitizensNPC handle, LivingEntity target, boolean aggro, float speed) {
|
||||
this.handle = handle.getHandle();
|
||||
this.target = ((CraftLivingEntity) target).getHandle();
|
||||
this.aggro = aggro;
|
||||
this.speed = speed;
|
||||
}
|
||||
|
||||
private boolean canAttack() {
|
||||
@ -30,11 +35,31 @@ public class MCTargetStrategy implements PathStrategy {
|
||||
return handle.getBukkitEntity().getLocation().distanceSquared(target.getBukkitEntity().getLocation());
|
||||
}
|
||||
|
||||
@Override
|
||||
public LivingEntity getTarget() {
|
||||
return (LivingEntity) target.getBukkitEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getTargetAsLocation() {
|
||||
return getTarget().getLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TargetType getTargetType() {
|
||||
return TargetType.ENTITY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAggressive() {
|
||||
return aggro;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update() {
|
||||
if (target == null || target.dead)
|
||||
return true;
|
||||
new MCNavigationStrategy(handle, target).update();
|
||||
new MCNavigationStrategy(handle, target, speed).update();
|
||||
handle.getControllerLook().a(target, 10.0F, handle.D());
|
||||
if (aggro && canAttack()) {
|
||||
if (handle instanceof EntityMonster) {
|
||||
@ -43,8 +68,8 @@ public class MCTargetStrategy implements PathStrategy {
|
||||
} else if (handle instanceof EntityPlayer) {
|
||||
EntityPlayer humanHandle = (EntityPlayer) handle;
|
||||
humanHandle.attack(target);
|
||||
Util.sendPacketNearby(handle.getBukkitEntity().getLocation(), new Packet18ArmAnimation(humanHandle, 1),
|
||||
64);
|
||||
Util.sendPacketNearby(handle.getBukkitEntity().getLocation(), new Packet18ArmAnimation(
|
||||
humanHandle, 1), 64);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,6 @@ package net.citizensnpcs.npc.ai;
|
||||
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
|
||||
public interface NPCHandle {
|
||||
public interface NPCHolder {
|
||||
public NPC getNPC();
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package net.citizensnpcs.npc.ai;
|
||||
|
||||
import net.citizensnpcs.api.ai.Navigator;
|
||||
import net.citizensnpcs.api.ai.event.NavigationEvent;
|
||||
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
public class NavigationCompleteEvent extends NavigationEvent {
|
||||
public NavigationCompleteEvent(Navigator navigator) {
|
||||
super(navigator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
@ -1,6 +1,13 @@
|
||||
package net.citizensnpcs.npc.ai;
|
||||
|
||||
import net.citizensnpcs.api.ai.TargetType;
|
||||
|
||||
import org.bukkit.Location;
|
||||
|
||||
public interface PathStrategy {
|
||||
Location getTargetAsLocation();
|
||||
|
||||
TargetType getTargetType();
|
||||
|
||||
boolean update();
|
||||
}
|
@ -3,7 +3,7 @@ package net.citizensnpcs.npc.entity;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.minecraft.server.EntityBlaze;
|
||||
import net.minecraft.server.PathfinderGoalSelector;
|
||||
import net.minecraft.server.World;
|
||||
@ -21,7 +21,7 @@ public class CitizensBlazeNPC extends CitizensMobNPC {
|
||||
return (Blaze) getHandle().getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EntityBlazeNPC extends EntityBlaze implements NPCHandle {
|
||||
public static class EntityBlazeNPC extends EntityBlaze implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntityBlazeNPC(World world) {
|
||||
@ -31,8 +31,16 @@ public class CitizensBlazeNPC extends CitizensMobNPC {
|
||||
public EntityBlazeNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
if (npc != null) {
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void b_(double x, double y, double z) {
|
||||
// when another entity collides, b_ is called to push the NPC
|
||||
// so we prevent b_ from doing anything.
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -3,7 +3,7 @@ package net.citizensnpcs.npc.entity;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.minecraft.server.EntityCaveSpider;
|
||||
import net.minecraft.server.PathfinderGoalSelector;
|
||||
import net.minecraft.server.World;
|
||||
@ -21,14 +21,27 @@ public class CitizensCaveSpiderNPC extends CitizensMobNPC {
|
||||
return (CaveSpider) getHandle().getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EntityCaveSpiderNPC extends EntityCaveSpider implements NPCHandle {
|
||||
public static class EntityCaveSpiderNPC extends EntityCaveSpider implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntityCaveSpiderNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
if (npc != null) {
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void b_(double x, double y, double z) {
|
||||
// when another entity collides, b_ is called to push the NPC
|
||||
// so we prevent b_ from doing anything.
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -36,10 +49,5 @@ public class CitizensCaveSpiderNPC extends CitizensMobNPC {
|
||||
super.z_();
|
||||
npc.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ package net.citizensnpcs.npc.entity;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.minecraft.server.EntityChicken;
|
||||
import net.minecraft.server.PathfinderGoalSelector;
|
||||
import net.minecraft.server.World;
|
||||
@ -21,7 +21,7 @@ public class CitizensChickenNPC extends CitizensMobNPC {
|
||||
return (Chicken) getHandle().getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EntityChickenNPC extends EntityChicken implements NPCHandle {
|
||||
public static class EntityChickenNPC extends EntityChicken implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntityChickenNPC(World world) {
|
||||
@ -31,8 +31,21 @@ public class CitizensChickenNPC extends CitizensMobNPC {
|
||||
public EntityChickenNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
if (npc != null) {
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void b_(double x, double y, double z) {
|
||||
// when another entity collides, b_ is called to push the NPC
|
||||
// so we prevent b_ from doing anything.
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -41,10 +54,5 @@ public class CitizensChickenNPC extends CitizensMobNPC {
|
||||
if (npc != null)
|
||||
npc.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ package net.citizensnpcs.npc.entity;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.minecraft.server.EntityCow;
|
||||
import net.minecraft.server.PathfinderGoalSelector;
|
||||
import net.minecraft.server.World;
|
||||
@ -21,7 +21,7 @@ public class CitizensCowNPC extends CitizensMobNPC {
|
||||
return (Cow) getHandle().getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EntityCowNPC extends EntityCow implements NPCHandle {
|
||||
public static class EntityCowNPC extends EntityCow implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntityCowNPC(World world) {
|
||||
@ -31,8 +31,21 @@ public class CitizensCowNPC extends CitizensMobNPC {
|
||||
public EntityCowNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
if (npc != null) {
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void b_(double x, double y, double z) {
|
||||
// when another entity collides, b_ is called to push the NPC
|
||||
// so we prevent b_ from doing anything.
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -41,10 +54,5 @@ public class CitizensCowNPC extends CitizensMobNPC {
|
||||
if (npc != null)
|
||||
npc.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ package net.citizensnpcs.npc.entity;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.minecraft.server.EntityCreeper;
|
||||
import net.minecraft.server.EntityWeatherLighting;
|
||||
import net.minecraft.server.PathfinderGoalSelector;
|
||||
@ -22,7 +22,7 @@ public class CitizensCreeperNPC extends CitizensMobNPC {
|
||||
return (Creeper) getHandle().getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EntityCreeperNPC extends EntityCreeper implements NPCHandle {
|
||||
public static class EntityCreeperNPC extends EntityCreeper implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntityCreeperNPC(World world) {
|
||||
@ -32,12 +32,27 @@ public class CitizensCreeperNPC extends CitizensMobNPC {
|
||||
public EntityCreeperNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
if (npc != null) {
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void a(EntityWeatherLighting entityweatherlighting) {
|
||||
if (npc == null)
|
||||
super.a(entityweatherlighting);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void b_(double x, double y, double z) {
|
||||
// when another entity collides, b_ is called to push the NPC
|
||||
// so we prevent b_ from doing anything.
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -46,10 +61,5 @@ public class CitizensCreeperNPC extends CitizensMobNPC {
|
||||
if (npc != null)
|
||||
npc.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ package net.citizensnpcs.npc.entity;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.minecraft.server.EntityEnderDragon;
|
||||
import net.minecraft.server.PathfinderGoalSelector;
|
||||
import net.minecraft.server.World;
|
||||
@ -21,23 +21,36 @@ public class CitizensEnderDragonNPC extends CitizensMobNPC {
|
||||
return (EnderDragon) getHandle().getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EntityEnderDragonNPC extends EntityEnderDragon implements NPCHandle {
|
||||
public static class EntityEnderDragonNPC extends EntityEnderDragon implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntityEnderDragonNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
if (npc != null) {
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void b_(double x, double y, double z) {
|
||||
// when another entity collides, b_ is called to push the NPC
|
||||
// so we prevent b_ from doing anything.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void d_() {
|
||||
if (npc == null)
|
||||
super.d_();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void e() {
|
||||
npc.update();
|
||||
if (npc != null)
|
||||
npc.update();
|
||||
else
|
||||
super.e();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -5,7 +5,7 @@ import net.citizensnpcs.api.trait.trait.Equipment;
|
||||
import net.citizensnpcs.editor.Equipable;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.Messaging;
|
||||
import net.minecraft.server.EntityEnderman;
|
||||
import net.minecraft.server.PathfinderGoalSelector;
|
||||
@ -59,7 +59,7 @@ public class CitizensEndermanNPC extends CitizensMobNPC implements Equipable {
|
||||
return (Enderman) getHandle().getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EntityEndermanNPC extends EntityEnderman implements NPCHandle {
|
||||
public static class EntityEndermanNPC extends EntityEnderman implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntityEndermanNPC(World world) {
|
||||
@ -69,12 +69,22 @@ public class CitizensEndermanNPC extends CitizensMobNPC implements Equipable {
|
||||
public EntityEndermanNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
if (npc != null) {
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void b_(double x, double y, double z) {
|
||||
// when another entity collides, b_ is called to push the NPC
|
||||
// so we prevent b_ from doing anything.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void d_() {
|
||||
if (npc == null)
|
||||
super.d_();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -3,7 +3,7 @@ package net.citizensnpcs.npc.entity;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.minecraft.server.EntityGhast;
|
||||
import net.minecraft.server.PathfinderGoalSelector;
|
||||
import net.minecraft.server.World;
|
||||
@ -21,7 +21,7 @@ public class CitizensGhastNPC extends CitizensMobNPC {
|
||||
return (Ghast) getHandle().getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EntityGhastNPC extends EntityGhast implements NPCHandle {
|
||||
public static class EntityGhastNPC extends EntityGhast implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntityGhastNPC(World world) {
|
||||
@ -31,8 +31,16 @@ public class CitizensGhastNPC extends CitizensMobNPC {
|
||||
public EntityGhastNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
if (npc != null) {
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void b_(double x, double y, double z) {
|
||||
// when another entity collides, b_ is called to push the NPC
|
||||
// so we prevent b_ from doing anything.
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -3,7 +3,7 @@ package net.citizensnpcs.npc.entity;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.minecraft.server.EntityGiantZombie;
|
||||
import net.minecraft.server.PathfinderGoalSelector;
|
||||
import net.minecraft.server.World;
|
||||
@ -21,14 +21,22 @@ public class CitizensGiantNPC extends CitizensMobNPC {
|
||||
return (Giant) getHandle().getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EntityGiantNPC extends EntityGiantZombie implements NPCHandle {
|
||||
public static class EntityGiantNPC extends EntityGiantZombie implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntityGiantNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
if (npc != null) {
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void b_(double x, double y, double z) {
|
||||
// when another entity collides, b_ is called to push the NPC
|
||||
// so we prevent b_ from doing anything.
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -48,48 +48,50 @@ public class CitizensHumanNPC extends CitizensNPC implements Equipable {
|
||||
Material type = hand == null ? Material.AIR : hand.getType();
|
||||
// First, determine the slot to edit
|
||||
switch (type) {
|
||||
case PUMPKIN:
|
||||
case JACK_O_LANTERN:
|
||||
case LEATHER_HELMET:
|
||||
case CHAINMAIL_HELMET:
|
||||
case GOLD_HELMET:
|
||||
case IRON_HELMET:
|
||||
case DIAMOND_HELMET:
|
||||
if (!equipper.isSneaking())
|
||||
slot = 1;
|
||||
break;
|
||||
case LEATHER_CHESTPLATE:
|
||||
case CHAINMAIL_CHESTPLATE:
|
||||
case GOLD_CHESTPLATE:
|
||||
case IRON_CHESTPLATE:
|
||||
case DIAMOND_CHESTPLATE:
|
||||
if (!equipper.isSneaking())
|
||||
slot = 2;
|
||||
break;
|
||||
case LEATHER_LEGGINGS:
|
||||
case CHAINMAIL_LEGGINGS:
|
||||
case GOLD_LEGGINGS:
|
||||
case IRON_LEGGINGS:
|
||||
case DIAMOND_LEGGINGS:
|
||||
if (!equipper.isSneaking())
|
||||
slot = 3;
|
||||
break;
|
||||
case LEATHER_BOOTS:
|
||||
case CHAINMAIL_BOOTS:
|
||||
case GOLD_BOOTS:
|
||||
case IRON_BOOTS:
|
||||
case DIAMOND_BOOTS:
|
||||
if (!equipper.isSneaking())
|
||||
slot = 4;
|
||||
break;
|
||||
case AIR:
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (trait.get(i) != null && trait.get(i).getType() != Material.AIR) {
|
||||
equipper.getWorld().dropItemNaturally(getBukkitEntity().getLocation(), trait.get(i));
|
||||
trait.set(i, null);
|
||||
case PUMPKIN:
|
||||
case JACK_O_LANTERN:
|
||||
case LEATHER_HELMET:
|
||||
case CHAINMAIL_HELMET:
|
||||
case GOLD_HELMET:
|
||||
case IRON_HELMET:
|
||||
case DIAMOND_HELMET:
|
||||
if (!equipper.isSneaking())
|
||||
slot = 1;
|
||||
break;
|
||||
case LEATHER_CHESTPLATE:
|
||||
case CHAINMAIL_CHESTPLATE:
|
||||
case GOLD_CHESTPLATE:
|
||||
case IRON_CHESTPLATE:
|
||||
case DIAMOND_CHESTPLATE:
|
||||
if (!equipper.isSneaking())
|
||||
slot = 2;
|
||||
break;
|
||||
case LEATHER_LEGGINGS:
|
||||
case CHAINMAIL_LEGGINGS:
|
||||
case GOLD_LEGGINGS:
|
||||
case IRON_LEGGINGS:
|
||||
case DIAMOND_LEGGINGS:
|
||||
if (!equipper.isSneaking())
|
||||
slot = 3;
|
||||
break;
|
||||
case LEATHER_BOOTS:
|
||||
case CHAINMAIL_BOOTS:
|
||||
case GOLD_BOOTS:
|
||||
case IRON_BOOTS:
|
||||
case DIAMOND_BOOTS:
|
||||
if (!equipper.isSneaking())
|
||||
slot = 4;
|
||||
break;
|
||||
case AIR:
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (trait.get(i) != null && trait.get(i).getType() != Material.AIR) {
|
||||
equipper.getWorld().dropItemNaturally(getBukkitEntity().getLocation(), trait.get(i));
|
||||
trait.set(i, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
Messaging.sendF(equipper, "<e>%s<a>had all of its items removed.", getName());
|
||||
Messaging.sendF(equipper, "<e>%s<a>had all of its items removed.", getName());
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Drop any previous equipment on the ground
|
||||
if (trait.get(slot) != null && trait.get(slot).getType() != Material.AIR)
|
||||
|
@ -3,7 +3,7 @@ package net.citizensnpcs.npc.entity;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.minecraft.server.EntityIronGolem;
|
||||
import net.minecraft.server.PathfinderGoalSelector;
|
||||
import net.minecraft.server.World;
|
||||
@ -21,25 +21,34 @@ public class CitizensIronGolemNPC extends CitizensMobNPC {
|
||||
return (IronGolem) getHandle().getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EntityIronGolemNPC extends EntityIronGolem implements NPCHandle {
|
||||
public static class EntityIronGolemNPC extends EntityIronGolem implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntityIronGolemNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
if (npc != null) {
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void z_() {
|
||||
super.z_();
|
||||
npc.update();
|
||||
public void b_(double x, double y, double z) {
|
||||
// when another entity collides, b_ is called to push the NPC
|
||||
// so we prevent b_ from doing anything.
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void z_() {
|
||||
super.z_();
|
||||
if (npc != null)
|
||||
npc.update();
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ package net.citizensnpcs.npc.entity;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.minecraft.server.EntityMagmaCube;
|
||||
import net.minecraft.server.PathfinderGoalSelector;
|
||||
import net.minecraft.server.World;
|
||||
@ -21,7 +21,7 @@ public class CitizensMagmaCubeNPC extends CitizensMobNPC {
|
||||
return (MagmaCube) getHandle().getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EntityMagmaCubeNPC extends EntityMagmaCube implements NPCHandle {
|
||||
public static class EntityMagmaCubeNPC extends EntityMagmaCube implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntityMagmaCubeNPC(World world) {
|
||||
@ -31,9 +31,17 @@ public class CitizensMagmaCubeNPC extends CitizensMobNPC {
|
||||
public EntityMagmaCubeNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
setSize(3);
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
if (npc != null) {
|
||||
setSize(3);
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void b_(double x, double y, double z) {
|
||||
// when another entity collides, b_ is called to push the NPC
|
||||
// so we prevent b_ from doing anything.
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -3,7 +3,7 @@ package net.citizensnpcs.npc.entity;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.minecraft.server.EntityMushroomCow;
|
||||
import net.minecraft.server.PathfinderGoalSelector;
|
||||
import net.minecraft.server.World;
|
||||
@ -21,7 +21,7 @@ public class CitizensMushroomCowNPC extends CitizensMobNPC {
|
||||
return (MushroomCow) getHandle().getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EntityMushroomCowNPC extends EntityMushroomCow implements NPCHandle {
|
||||
public static class EntityMushroomCowNPC extends EntityMushroomCow implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntityMushroomCowNPC(World world) {
|
||||
@ -31,8 +31,21 @@ public class CitizensMushroomCowNPC extends CitizensMobNPC {
|
||||
public EntityMushroomCowNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
if (npc != null) {
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void b_(double x, double y, double z) {
|
||||
// when another entity collides, b_ is called to push the NPC
|
||||
// so we prevent b_ from doing anything.
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -41,10 +54,5 @@ public class CitizensMushroomCowNPC extends CitizensMobNPC {
|
||||
if (npc != null)
|
||||
npc.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ package net.citizensnpcs.npc.entity;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.minecraft.server.EntityOcelot;
|
||||
import net.minecraft.server.PathfinderGoalSelector;
|
||||
import net.minecraft.server.World;
|
||||
@ -21,7 +21,7 @@ public class CitizensOcelotNPC extends CitizensMobNPC {
|
||||
return (Ocelot) getHandle().getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EntityOcelotNPC extends EntityOcelot implements NPCHandle {
|
||||
public static class EntityOcelotNPC extends EntityOcelot implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntityOcelotNPC(World world) {
|
||||
@ -31,8 +31,21 @@ public class CitizensOcelotNPC extends CitizensMobNPC {
|
||||
public EntityOcelotNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
if (npc != null) {
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void b_(double x, double y, double z) {
|
||||
// when another entity collides, b_ is called to push the NPC
|
||||
// so we prevent b_ from doing anything.
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -41,10 +54,5 @@ public class CitizensOcelotNPC extends CitizensMobNPC {
|
||||
if (npc != null)
|
||||
npc.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.editor.Equipable;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.trait.Saddle;
|
||||
import net.citizensnpcs.util.Messaging;
|
||||
import net.citizensnpcs.util.StringHelper;
|
||||
@ -48,7 +48,7 @@ public class CitizensPigNPC extends CitizensMobNPC implements Equipable {
|
||||
return (Pig) getHandle().getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EntityPigNPC extends EntityPig implements NPCHandle {
|
||||
public static class EntityPigNPC extends EntityPig implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntityPigNPC(World world) {
|
||||
@ -58,12 +58,27 @@ public class CitizensPigNPC extends CitizensMobNPC implements Equipable {
|
||||
public EntityPigNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
if (npc != null) {
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void a(EntityWeatherLighting entityweatherlighting) {
|
||||
if (npc == null)
|
||||
super.a(entityweatherlighting);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void b_(double x, double y, double z) {
|
||||
// when another entity collides, b_ is called to push the NPC
|
||||
// so we prevent b_ from doing anything.
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -72,10 +87,5 @@ public class CitizensPigNPC extends CitizensMobNPC implements Equipable {
|
||||
if (npc != null)
|
||||
npc.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ package net.citizensnpcs.npc.entity;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.minecraft.server.EntityPigZombie;
|
||||
import net.minecraft.server.PathfinderGoalSelector;
|
||||
import net.minecraft.server.World;
|
||||
@ -21,7 +21,7 @@ public class CitizensPigZombieNPC extends CitizensMobNPC {
|
||||
return (PigZombie) getHandle().getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EntityPigZombieNPC extends EntityPigZombie implements NPCHandle {
|
||||
public static class EntityPigZombieNPC extends EntityPigZombie implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntityPigZombieNPC(World world) {
|
||||
@ -31,8 +31,16 @@ public class CitizensPigZombieNPC extends CitizensMobNPC {
|
||||
public EntityPigZombieNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
if (npc != null) {
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void b_(double x, double y, double z) {
|
||||
// when another entity collides, b_ is called to push the NPC
|
||||
// so we prevent b_ from doing anything.
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -4,7 +4,7 @@ import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.editor.Equipable;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.trait.Sheared;
|
||||
import net.citizensnpcs.trait.WoolColor;
|
||||
import net.citizensnpcs.util.Messaging;
|
||||
@ -49,7 +49,8 @@ public class CitizensSheepNPC extends CitizensMobNPC implements Equipable {
|
||||
equipper.setItemInHand(hand);
|
||||
} else {
|
||||
getTrait(WoolColor.class).setColor(DyeColor.WHITE);
|
||||
Messaging.send(equipper, StringHelper.wrap(getName()) + " is now " + StringHelper.wrap("white") + ".");
|
||||
Messaging.send(equipper, StringHelper.wrap(getName()) + " is now " + StringHelper.wrap("white")
|
||||
+ ".");
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,7 +59,7 @@ public class CitizensSheepNPC extends CitizensMobNPC implements Equipable {
|
||||
return (Sheep) getHandle().getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EntitySheepNPC extends EntitySheep implements NPCHandle {
|
||||
public static class EntitySheepNPC extends EntitySheep implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntitySheepNPC(World world) {
|
||||
@ -68,8 +69,21 @@ public class CitizensSheepNPC extends CitizensMobNPC implements Equipable {
|
||||
public EntitySheepNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
if (npc != null) {
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void b_(double x, double y, double z) {
|
||||
// when another entity collides, b_ is called to push the NPC
|
||||
// so we prevent b_ from doing anything.
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -78,10 +92,5 @@ public class CitizensSheepNPC extends CitizensMobNPC implements Equipable {
|
||||
if (npc != null)
|
||||
npc.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ package net.citizensnpcs.npc.entity;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.minecraft.server.EntitySilverfish;
|
||||
import net.minecraft.server.PathfinderGoalSelector;
|
||||
import net.minecraft.server.World;
|
||||
@ -21,7 +21,7 @@ public class CitizensSilverfishNPC extends CitizensMobNPC {
|
||||
return (Silverfish) getHandle().getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EntitySilverfishNPC extends EntitySilverfish implements NPCHandle {
|
||||
public static class EntitySilverfishNPC extends EntitySilverfish implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntitySilverfishNPC(World world) {
|
||||
@ -31,8 +31,21 @@ public class CitizensSilverfishNPC extends CitizensMobNPC {
|
||||
public EntitySilverfishNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
if (npc != null) {
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void b_(double x, double y, double z) {
|
||||
// when another entity collides, b_ is called to push the NPC
|
||||
// so we prevent b_ from doing anything.
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -41,10 +54,5 @@ public class CitizensSilverfishNPC extends CitizensMobNPC {
|
||||
if (npc != null)
|
||||
npc.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ package net.citizensnpcs.npc.entity;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.minecraft.server.EntitySkeleton;
|
||||
import net.minecraft.server.PathfinderGoalSelector;
|
||||
import net.minecraft.server.World;
|
||||
@ -21,7 +21,7 @@ public class CitizensSkeletonNPC extends CitizensMobNPC {
|
||||
return (Skeleton) getHandle().getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EntitySkeletonNPC extends EntitySkeleton implements NPCHandle {
|
||||
public static class EntitySkeletonNPC extends EntitySkeleton implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntitySkeletonNPC(World world) {
|
||||
@ -31,8 +31,21 @@ public class CitizensSkeletonNPC extends CitizensMobNPC {
|
||||
public EntitySkeletonNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
if (npc != null) {
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void b_(double x, double y, double z) {
|
||||
// when another entity collides, b_ is called to push the NPC
|
||||
// so we prevent b_ from doing anything.
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -41,10 +54,5 @@ public class CitizensSkeletonNPC extends CitizensMobNPC {
|
||||
if (npc != null)
|
||||
npc.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ package net.citizensnpcs.npc.entity;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.minecraft.server.EntitySlime;
|
||||
import net.minecraft.server.PathfinderGoalSelector;
|
||||
import net.minecraft.server.World;
|
||||
@ -21,7 +21,7 @@ public class CitizensSlimeNPC extends CitizensMobNPC {
|
||||
return (Slime) getHandle().getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EntitySlimeNPC extends EntitySlime implements NPCHandle {
|
||||
public static class EntitySlimeNPC extends EntitySlime implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntitySlimeNPC(World world) {
|
||||
@ -31,9 +31,22 @@ public class CitizensSlimeNPC extends CitizensMobNPC {
|
||||
public EntitySlimeNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
setSize(3);
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
if (npc != null) {
|
||||
setSize(3);
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void b_(double x, double y, double z) {
|
||||
// when another entity collides, b_ is called to push the NPC
|
||||
// so we prevent b_ from doing anything.
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -42,10 +55,5 @@ public class CitizensSlimeNPC extends CitizensMobNPC {
|
||||
if (npc != null)
|
||||
npc.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ package net.citizensnpcs.npc.entity;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.minecraft.server.EntitySnowman;
|
||||
import net.minecraft.server.PathfinderGoalSelector;
|
||||
import net.minecraft.server.World;
|
||||
@ -21,14 +21,27 @@ public class CitizensSnowmanNPC extends CitizensMobNPC {
|
||||
return (Snowman) getHandle().getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EntitySnowmanNPC extends EntitySnowman implements NPCHandle {
|
||||
public static class EntitySnowmanNPC extends EntitySnowman implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntitySnowmanNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
if (npc != null) {
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void b_(double x, double y, double z) {
|
||||
// when another entity collides, b_ is called to push the NPC
|
||||
// so we prevent b_ from doing anything.
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -36,10 +49,5 @@ public class CitizensSnowmanNPC extends CitizensMobNPC {
|
||||
super.z_();
|
||||
npc.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ package net.citizensnpcs.npc.entity;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.minecraft.server.EntitySpider;
|
||||
import net.minecraft.server.PathfinderGoalSelector;
|
||||
import net.minecraft.server.World;
|
||||
@ -21,7 +21,7 @@ public class CitizensSpiderNPC extends CitizensMobNPC {
|
||||
return (Spider) getHandle().getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EntitySpiderNPC extends EntitySpider implements NPCHandle {
|
||||
public static class EntitySpiderNPC extends EntitySpider implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntitySpiderNPC(World world) {
|
||||
@ -31,8 +31,21 @@ public class CitizensSpiderNPC extends CitizensMobNPC {
|
||||
public EntitySpiderNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
if (npc != null) {
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void b_(double x, double y, double z) {
|
||||
// when another entity collides, b_ is called to push the NPC
|
||||
// so we prevent b_ from doing anything.
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -41,10 +54,5 @@ public class CitizensSpiderNPC extends CitizensMobNPC {
|
||||
if (npc != null)
|
||||
npc.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ package net.citizensnpcs.npc.entity;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.minecraft.server.EntitySquid;
|
||||
import net.minecraft.server.PathfinderGoalSelector;
|
||||
import net.minecraft.server.World;
|
||||
@ -21,7 +21,7 @@ public class CitizensSquidNPC extends CitizensMobNPC {
|
||||
return (Squid) getHandle().getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EntitySquidNPC extends EntitySquid implements NPCHandle {
|
||||
public static class EntitySquidNPC extends EntitySquid implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntitySquidNPC(World world) {
|
||||
@ -31,8 +31,16 @@ public class CitizensSquidNPC extends CitizensMobNPC {
|
||||
public EntitySquidNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
if (npc != null) {
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void b_(double x, double y, double z) {
|
||||
// when another entity collides, b_ is called to push the NPC
|
||||
// so we prevent b_ from doing anything.
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -3,7 +3,7 @@ package net.citizensnpcs.npc.entity;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.minecraft.server.EntityVillager;
|
||||
import net.minecraft.server.PathfinderGoalSelector;
|
||||
import net.minecraft.server.World;
|
||||
@ -21,7 +21,7 @@ public class CitizensVillagerNPC extends CitizensMobNPC {
|
||||
return (Villager) getHandle().getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EntityVillagerNPC extends EntityVillager implements NPCHandle {
|
||||
public static class EntityVillagerNPC extends EntityVillager implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntityVillagerNPC(World world) {
|
||||
@ -31,8 +31,21 @@ public class CitizensVillagerNPC extends CitizensMobNPC {
|
||||
public EntityVillagerNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
if (npc != null) {
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void b_(double x, double y, double z) {
|
||||
// when another entity collides, b_ is called to push the NPC
|
||||
// so we prevent b_ from doing anything.
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -41,10 +54,5 @@ public class CitizensVillagerNPC extends CitizensMobNPC {
|
||||
if (npc != null)
|
||||
npc.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ package net.citizensnpcs.npc.entity;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.minecraft.server.EntityWolf;
|
||||
import net.minecraft.server.PathfinderGoalSelector;
|
||||
import net.minecraft.server.World;
|
||||
@ -21,7 +21,7 @@ public class CitizensWolfNPC extends CitizensMobNPC {
|
||||
return (Wolf) getHandle().getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EntityWolfNPC extends EntityWolf implements NPCHandle {
|
||||
public static class EntityWolfNPC extends EntityWolf implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntityWolfNPC(World world) {
|
||||
@ -31,8 +31,21 @@ public class CitizensWolfNPC extends CitizensMobNPC {
|
||||
public EntityWolfNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
if (npc != null) {
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void b_(double x, double y, double z) {
|
||||
// when another entity collides, b_ is called to push the NPC
|
||||
// so we prevent b_ from doing anything.
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -41,10 +54,5 @@ public class CitizensWolfNPC extends CitizensMobNPC {
|
||||
if (npc != null)
|
||||
npc.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ package net.citizensnpcs.npc.entity;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.minecraft.server.EntityZombie;
|
||||
import net.minecraft.server.PathfinderGoalSelector;
|
||||
import net.minecraft.server.World;
|
||||
@ -21,7 +21,7 @@ public class CitizensZombieNPC extends CitizensMobNPC {
|
||||
return (Zombie) getHandle().getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EntityZombieNPC extends EntityZombie implements NPCHandle {
|
||||
public static class EntityZombieNPC extends EntityZombie implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntityZombieNPC(World world) {
|
||||
@ -31,8 +31,21 @@ public class CitizensZombieNPC extends CitizensMobNPC {
|
||||
public EntityZombieNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
if (npc != null) {
|
||||
goalSelector = new PathfinderGoalSelector();
|
||||
targetSelector = new PathfinderGoalSelector();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void b_(double x, double y, double z) {
|
||||
// when another entity collides, b_ is called to push the NPC
|
||||
// so we prevent b_ from doing anything.
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -41,10 +54,5 @@ public class CitizensZombieNPC extends CitizensMobNPC {
|
||||
if (npc != null)
|
||||
npc.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ import java.io.IOException;
|
||||
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.npc.network.NPCNetHandler;
|
||||
import net.citizensnpcs.npc.network.NPCNetworkManager;
|
||||
import net.citizensnpcs.npc.network.NPCSocket;
|
||||
@ -16,7 +16,7 @@ import net.minecraft.server.NetHandler;
|
||||
import net.minecraft.server.NetworkManager;
|
||||
import net.minecraft.server.World;
|
||||
|
||||
public class EntityHumanNPC extends EntityPlayer implements NPCHandle {
|
||||
public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
|
||||
private CitizensNPC npc;
|
||||
|
||||
public EntityHumanNPC(MinecraftServer minecraftServer, World world, String string,
|
||||
@ -42,6 +42,12 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHandle {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void b_(double x, double y, double z) {
|
||||
// when another entity collides, b_ is called to push the NPC
|
||||
// so we prevent b_ from doing anything.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void F_() {
|
||||
super.F_();
|
||||
@ -57,6 +63,11 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHandle {
|
||||
npc.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
|
||||
private void moveOnCurrentHeading() {
|
||||
getControllerMove().c();
|
||||
getControllerLook().a();
|
||||
@ -76,9 +87,4 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHandle {
|
||||
a(aW, aX);
|
||||
X = yaw; // TODO: this looks jerky
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
package net.citizensnpcs.npc.network;
|
||||
|
||||
import net.minecraft.server.EntityPlayer;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.NetServerHandler;
|
||||
import net.minecraft.server.NetworkManager;
|
||||
import net.minecraft.server.Packet;
|
||||
import net.minecraft.server.Packet102WindowClick;
|
||||
import net.minecraft.server.Packet106Transaction;
|
||||
import net.minecraft.server.Packet10Flying;
|
||||
import net.minecraft.server.Packet130UpdateSign;
|
||||
import net.minecraft.server.Packet14BlockDig;
|
||||
import net.minecraft.server.Packet15Place;
|
||||
import net.minecraft.server.Packet16BlockItemSwitch;
|
||||
import net.minecraft.server.Packet255KickDisconnect;
|
||||
import net.minecraft.server.Packet28EntityVelocity;
|
||||
import net.minecraft.server.Packet3Chat;
|
||||
import net.minecraft.server.Packet51MapChunk;
|
||||
|
||||
public class EmptyNetHandler extends NetServerHandler {
|
||||
public EmptyNetHandler(MinecraftServer minecraftServer, NetworkManager networkManager, EntityPlayer entityPlayer) {
|
||||
super(minecraftServer, networkManager, entityPlayer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void a() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void a(Packet102WindowClick packet) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void a(Packet106Transaction packet) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void a(Packet10Flying packet) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void a(Packet130UpdateSign packet) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void a(Packet14BlockDig packet) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void a(Packet15Place packet) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void a(Packet16BlockItemSwitch packet) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void a(Packet255KickDisconnect packet) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void a(Packet28EntityVelocity packet) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void a(Packet3Chat packet) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void a(Packet51MapChunk packet) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void a(String string, Object[] objects) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(String string) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacket(Packet packet) {
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package net.citizensnpcs.npc.network;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.Socket;
|
||||
|
||||
import net.minecraft.server.NetHandler;
|
||||
import net.minecraft.server.NetworkManager;
|
||||
import net.minecraft.server.Packet;
|
||||
|
||||
public class EmptyNetworkManager extends NetworkManager {
|
||||
|
||||
public EmptyNetworkManager(Socket socket, String string, NetHandler netHandler) {
|
||||
super(socket, string, netHandler);
|
||||
|
||||
try {
|
||||
// the field above the 3 synchronized lists
|
||||
Field f = NetworkManager.class.getDeclaredField("l");
|
||||
f.setAccessible(true);
|
||||
f.set(this, false);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void a() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void a(NetHandler netHandler) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void a(String s, Object... objects) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void b() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void d() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int e() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queue(Packet packet) {
|
||||
}
|
||||
}
|
20
src/main/java/net/citizensnpcs/npc/network/EmptySocket.java
Normal file
20
src/main/java/net/citizensnpcs/npc/network/EmptySocket.java
Normal file
@ -0,0 +1,20 @@
|
||||
package net.citizensnpcs.npc.network;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
|
||||
public class EmptySocket extends Socket {
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() {
|
||||
return new ByteArrayInputStream(new byte[10]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream getOutputStream() {
|
||||
return new ByteArrayOutputStream();
|
||||
}
|
||||
}
|
@ -1,20 +1,18 @@
|
||||
package net.citizensnpcs.trait;
|
||||
|
||||
import net.citizensnpcs.api.exception.NPCLoadException;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
|
||||
import org.bukkit.entity.Ageable;
|
||||
|
||||
public class Age extends Trait implements Runnable, Toggleable {
|
||||
public class Age extends Trait implements Toggleable {
|
||||
private int age = 0;
|
||||
private boolean locked = true;
|
||||
private boolean ageable = false;
|
||||
private final NPC npc;
|
||||
private boolean locked = true;
|
||||
|
||||
public Age(NPC npc) {
|
||||
this.npc = npc;
|
||||
public Age() {
|
||||
super("age");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -26,7 +24,7 @@ public class Age extends Trait implements Runnable, Toggleable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNPCSpawn() {
|
||||
public void onSpawn() {
|
||||
if (npc instanceof Ageable) {
|
||||
Ageable entity = (Ageable) npc.getBukkitEntity();
|
||||
entity.setAge(age);
|
||||
|
@ -8,7 +8,6 @@ import java.util.Map.Entry;
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.ai.Goal;
|
||||
import net.citizensnpcs.api.exception.NPCLoadException;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.scripting.CompileCallback;
|
||||
import net.citizensnpcs.api.scripting.ScriptFactory;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
@ -31,7 +30,6 @@ public class Behaviour extends Trait {
|
||||
return new File(rootFolder, arg0);
|
||||
}
|
||||
};
|
||||
private final NPC npc;
|
||||
private final File rootFolder = new File(CitizensAPI.getScriptFolder(), "behaviours");
|
||||
private final List<File> scripts = Lists.newArrayList();
|
||||
{
|
||||
@ -39,8 +37,8 @@ public class Behaviour extends Trait {
|
||||
rootFolder.mkdirs();
|
||||
}
|
||||
|
||||
public Behaviour(NPC npc) {
|
||||
this.npc = npc;
|
||||
public Behaviour() {
|
||||
super("behaviour");
|
||||
}
|
||||
|
||||
public void addScripts(Iterable<String> scripts) {
|
||||
@ -58,21 +56,21 @@ public class Behaviour extends Trait {
|
||||
addScripts(Splitter.on(",").split(scripts));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNPCSpawn() {
|
||||
for (Entry<Goal, Integer> entry : addedGoals.entrySet()) {
|
||||
npc.getAI().addGoal(entry.getValue(), entry.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemove() {
|
||||
removeGoals();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpawn() {
|
||||
for (Entry<Goal, Integer> entry : addedGoals.entrySet()) {
|
||||
npc.getDefaultGoalController().addGoal(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
private void removeGoals() {
|
||||
for (Goal entry : addedGoals.keySet()) {
|
||||
npc.getAI().removeGoal(entry);
|
||||
npc.getDefaultGoalController().removeGoal(entry);
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,7 +98,7 @@ public class Behaviour extends Trait {
|
||||
if (!npc.isSpawned())
|
||||
return;
|
||||
for (Entry<Goal, Integer> entry : goals.goals.entrySet()) {
|
||||
npc.getAI().addGoal(entry.getValue(), entry.getKey());
|
||||
npc.getDefaultGoalController().addGoal(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,7 +111,7 @@ public class Behaviour extends Trait {
|
||||
public static class Goals {
|
||||
private final Map<Goal, Integer> goals = Maps.newHashMap();
|
||||
|
||||
public void addGoal(int priority, Goal goal) {
|
||||
public void addGoal(Goal goal, int priority) {
|
||||
Validate.notNull(goal);
|
||||
goals.put(goal, priority);
|
||||
}
|
||||
|
@ -5,30 +5,32 @@ import net.citizensnpcs.api.exception.NPCLoadException;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.minecraft.server.EntityLiving;
|
||||
import net.minecraft.server.EntityPlayer;
|
||||
|
||||
import org.bukkit.craftbukkit.entity.CraftLivingEntity;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
|
||||
//TODO: reduce reliance on CitizensNPC
|
||||
public class Controllable extends Trait implements Runnable, Listener, Toggleable {
|
||||
private final CitizensNPC npc;
|
||||
public class Controllable extends Trait implements Toggleable {
|
||||
private boolean enabled;
|
||||
|
||||
public Controllable(NPC npc) {
|
||||
this.npc = (CitizensNPC) npc;
|
||||
super("controllable");
|
||||
}
|
||||
|
||||
private EntityLiving getHandle() {
|
||||
return ((CraftLivingEntity) npc.getBukkitEntity()).getHandle();
|
||||
}
|
||||
|
||||
private void jump() {
|
||||
boolean allowed = npc.getHandle().onGround;
|
||||
boolean allowed = getHandle().onGround;
|
||||
if (!allowed)
|
||||
return;
|
||||
npc.getHandle().motY = JUMP_VELOCITY;
|
||||
getHandle().motY = JUMP_VELOCITY;
|
||||
// TODO: make jumping work in liquid or make liquids float the npc
|
||||
}
|
||||
|
||||
@ -43,7 +45,7 @@ public class Controllable extends Trait implements Runnable, Listener, Toggleabl
|
||||
return;
|
||||
EntityPlayer handle = ((CraftPlayer) event.getPlayer()).getHandle();
|
||||
Action performed = event.getAction();
|
||||
if (performed == Action.PHYSICAL || !handle.equals(npc.getHandle().passenger))
|
||||
if (performed == Action.PHYSICAL || !handle.equals(getHandle().passenger))
|
||||
return;
|
||||
if (performed == Action.LEFT_CLICK_AIR || performed == Action.LEFT_CLICK_BLOCK) {
|
||||
jump();
|
||||
@ -55,20 +57,20 @@ public class Controllable extends Trait implements Runnable, Listener, Toggleabl
|
||||
if (!npc.isSpawned() || !event.getNPC().equals(npc))
|
||||
return;
|
||||
EntityPlayer handle = ((CraftPlayer) event.getClicker()).getHandle();
|
||||
if (npc.getHandle().passenger != null) {
|
||||
if (npc.getHandle().passenger == handle) {
|
||||
if (getHandle().passenger != null) {
|
||||
if (getHandle().passenger == handle) {
|
||||
event.getClicker().leaveVehicle();
|
||||
}
|
||||
return;
|
||||
}
|
||||
handle.setPassengerOf(npc.getHandle());
|
||||
handle.setPassengerOf(getHandle());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!npc.isSpawned() || npc.getHandle().passenger == null)
|
||||
if (!npc.isSpawned() || getHandle().passenger == null)
|
||||
return;
|
||||
EntityLiving handle = npc.getHandle();
|
||||
EntityLiving handle = getHandle();
|
||||
boolean onGround = handle.onGround;
|
||||
handle.motX += handle.passenger.motX * (onGround ? GROUND_SPEED : AIR_SPEED);
|
||||
handle.motZ += handle.passenger.motZ * (onGround ? GROUND_SPEED : AIR_SPEED);
|
||||
@ -79,12 +81,13 @@ public class Controllable extends Trait implements Runnable, Listener, Toggleabl
|
||||
key.setBoolean("enabled", enabled);
|
||||
}
|
||||
|
||||
private static final double GROUND_SPEED = 4;
|
||||
private static final double AIR_SPEED = 1.5;
|
||||
private static final double JUMP_VELOCITY = 0.6;
|
||||
|
||||
@Override
|
||||
public boolean toggle() {
|
||||
return (enabled = !enabled);
|
||||
}
|
||||
|
||||
private static final double AIR_SPEED = 1.5;
|
||||
private static final double GROUND_SPEED = 4;
|
||||
|
||||
private static final double JUMP_VELOCITY = 0.6;
|
||||
}
|
||||
|
@ -1,29 +1,23 @@
|
||||
package net.citizensnpcs.trait;
|
||||
|
||||
import net.citizensnpcs.api.exception.NPCLoadException;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
|
||||
public class CurrentLocation extends Trait implements Runnable {
|
||||
public class CurrentLocation extends Trait {
|
||||
private Location loc;
|
||||
private final NPC npc;
|
||||
|
||||
public CurrentLocation(NPC npc) {
|
||||
this.npc = npc;
|
||||
public CurrentLocation() {
|
||||
super("location");
|
||||
}
|
||||
|
||||
public Location getLocation() {
|
||||
return loc;
|
||||
}
|
||||
|
||||
public void setLocation(Location loc) {
|
||||
this.loc = loc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(DataKey key) throws NPCLoadException {
|
||||
if (Bukkit.getWorld(key.getString("world")) == null)
|
||||
@ -56,6 +50,10 @@ public class CurrentLocation extends Trait implements Runnable {
|
||||
key.setDouble("pitch", loc.getPitch());
|
||||
}
|
||||
|
||||
public void setLocation(Location loc) {
|
||||
this.loc = loc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CurrentLocation{" + loc + "}";
|
||||
|
@ -6,7 +6,6 @@ import java.util.List;
|
||||
|
||||
import net.citizensnpcs.Settings.Setting;
|
||||
import net.citizensnpcs.api.exception.NPCLoadException;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
import net.minecraft.server.EntityLiving;
|
||||
@ -16,13 +15,12 @@ import org.bukkit.craftbukkit.entity.CraftLivingEntity;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class LookClose extends Trait implements Runnable, Toggleable {
|
||||
public class LookClose extends Trait implements Toggleable {
|
||||
private boolean enabled = Setting.DEFAULT_LOOK_CLOSE.asBoolean();
|
||||
private Player lookingAt;
|
||||
private final NPC npc;
|
||||
|
||||
public LookClose(NPC npc) {
|
||||
this.npc = npc;
|
||||
public LookClose() {
|
||||
super("lookclose");
|
||||
}
|
||||
|
||||
private void faceEntity(Entity from, Entity at) {
|
||||
@ -49,23 +47,6 @@ public class LookClose extends Trait implements Runnable, Toggleable {
|
||||
handle.X = handle.yaw;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(DataKey key) throws NPCLoadException {
|
||||
enabled = key.getBoolean("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!enabled || npc.getAI().hasDestination())
|
||||
return;
|
||||
if (hasInvalidTarget()) {
|
||||
findNewTarget();
|
||||
}
|
||||
if (lookingAt != null) {
|
||||
faceEntity(npc.getBukkitEntity(), lookingAt);
|
||||
}
|
||||
}
|
||||
|
||||
private void findNewTarget() {
|
||||
List<Entity> nearby = npc.getBukkitEntity().getNearbyEntities(2.5, 5, 2.5);
|
||||
Collections.sort(nearby, new Comparator<Entity>() {
|
||||
@ -96,6 +77,23 @@ public class LookClose extends Trait implements Runnable, Toggleable {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(DataKey key) throws NPCLoadException {
|
||||
enabled = key.getBoolean("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!enabled || npc.getNavigator().isNavigating())
|
||||
return;
|
||||
if (hasInvalidTarget()) {
|
||||
findNewTarget();
|
||||
}
|
||||
if (lookingAt != null) {
|
||||
faceEntity(npc.getBukkitEntity(), lookingAt);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(DataKey key) {
|
||||
key.setBoolean("", enabled);
|
||||
|
@ -1,18 +1,16 @@
|
||||
package net.citizensnpcs.trait;
|
||||
|
||||
import net.citizensnpcs.api.exception.NPCLoadException;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
|
||||
import org.bukkit.entity.Creeper;
|
||||
|
||||
public class Powered extends Trait implements Toggleable {
|
||||
private final NPC npc;
|
||||
private boolean powered;
|
||||
|
||||
public Powered(NPC npc) {
|
||||
this.npc = npc;
|
||||
public Powered() {
|
||||
super("powered");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -21,7 +19,7 @@ public class Powered extends Trait implements Toggleable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNPCSpawn() {
|
||||
public void onSpawn() {
|
||||
if (npc.getBukkitEntity() instanceof Creeper)
|
||||
((Creeper) npc.getBukkitEntity()).setPowered(powered);
|
||||
}
|
||||
|
@ -2,22 +2,19 @@ package net.citizensnpcs.trait;
|
||||
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.exception.NPCLoadException;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
|
||||
import org.bukkit.entity.Pig;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||
|
||||
public class Saddle extends Trait implements Toggleable, Listener {
|
||||
private final NPC npc;
|
||||
private boolean saddle;
|
||||
public class Saddle extends Trait implements Toggleable {
|
||||
private boolean pig;
|
||||
private boolean saddle;
|
||||
|
||||
public Saddle(NPC npc) {
|
||||
this.npc = npc;
|
||||
public Saddle() {
|
||||
super("saddle");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -25,8 +22,14 @@ public class Saddle extends Trait implements Toggleable, Listener {
|
||||
saddle = key.getBoolean("");
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
|
||||
if (pig && npc.equals(CitizensAPI.getNPCRegistry().getNPC(event.getRightClicked())))
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNPCSpawn() {
|
||||
public void onSpawn() {
|
||||
if (npc.getBukkitEntity() instanceof Pig) {
|
||||
((Pig) npc.getBukkitEntity()).setSaddle(saddle);
|
||||
pig = true;
|
||||
@ -34,12 +37,6 @@ public class Saddle extends Trait implements Toggleable, Listener {
|
||||
pig = false;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
|
||||
if (pig && npc.equals(CitizensAPI.getNPCRegistry().getNPC(event.getRightClicked())))
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(DataKey key) {
|
||||
key.setBoolean("", saddle);
|
||||
|
@ -2,21 +2,18 @@ package net.citizensnpcs.trait;
|
||||
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.exception.NPCLoadException;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
|
||||
import org.bukkit.entity.Sheep;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerShearEntityEvent;
|
||||
|
||||
public class Sheared extends Trait implements Toggleable, Listener {
|
||||
private final NPC npc;
|
||||
public class Sheared extends Trait implements Toggleable {
|
||||
private boolean sheared;
|
||||
|
||||
public Sheared(NPC npc) {
|
||||
this.npc = npc;
|
||||
public Sheared() {
|
||||
super("sheared");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -24,17 +21,17 @@ public class Sheared extends Trait implements Toggleable, Listener {
|
||||
sheared = key.getBoolean("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNPCSpawn() {
|
||||
((Sheep) npc.getBukkitEntity()).setSheared(sheared);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerShearEntityEvent(PlayerShearEntityEvent event) {
|
||||
if (npc.equals(CitizensAPI.getNPCRegistry().getNPC(event.getEntity())))
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpawn() {
|
||||
((Sheep) npc.getBukkitEntity()).setSheared(sheared);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(DataKey key) {
|
||||
key.setBoolean("", sheared);
|
||||
|
@ -1,7 +1,6 @@
|
||||
package net.citizensnpcs.trait;
|
||||
|
||||
import net.citizensnpcs.api.exception.NPCLoadException;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
|
||||
@ -9,11 +8,10 @@ import org.bukkit.entity.Villager;
|
||||
import org.bukkit.entity.Villager.Profession;
|
||||
|
||||
public class VillagerProfession extends Trait {
|
||||
private final NPC npc;
|
||||
private Profession profession = Profession.FARMER;
|
||||
|
||||
public VillagerProfession(NPC npc) {
|
||||
this.npc = npc;
|
||||
public VillagerProfession() {
|
||||
super("profession");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -26,7 +24,7 @@ public class VillagerProfession extends Trait {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNPCSpawn() {
|
||||
public void onSpawn() {
|
||||
if (npc.getBukkitEntity() instanceof Villager)
|
||||
((Villager) npc.getBukkitEntity()).setProfession(profession);
|
||||
}
|
||||
|
@ -2,23 +2,20 @@ package net.citizensnpcs.trait;
|
||||
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.exception.NPCLoadException;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.entity.Sheep;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.SheepDyeWoolEvent;
|
||||
|
||||
public class WoolColor extends Trait implements Listener {
|
||||
public class WoolColor extends Trait {
|
||||
private DyeColor color = DyeColor.WHITE;
|
||||
private final NPC npc;
|
||||
boolean sheep = false;
|
||||
|
||||
public WoolColor(NPC npc) {
|
||||
this.npc = npc;
|
||||
public WoolColor() {
|
||||
super("woolcolor");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -30,8 +27,14 @@ public class WoolColor extends Trait implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onSheepDyeWool(SheepDyeWoolEvent event) {
|
||||
if (npc.equals(CitizensAPI.getNPCRegistry().getNPC(event.getEntity())))
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNPCSpawn() {
|
||||
public void onSpawn() {
|
||||
if (npc.getBukkitEntity() instanceof Sheep) {
|
||||
((Sheep) npc.getBukkitEntity()).setColor(color);
|
||||
sheep = true;
|
||||
@ -39,12 +42,6 @@ public class WoolColor extends Trait implements Listener {
|
||||
sheep = false;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onSheepDyeWool(SheepDyeWoolEvent event) {
|
||||
if (npc.equals(CitizensAPI.getNPCRegistry().getNPC(event.getEntity())))
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(DataKey key) {
|
||||
key.setString("", color.name());
|
||||
|
@ -1,15 +1,16 @@
|
||||
package net.citizensnpcs.trait.text;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import net.citizensnpcs.Settings.Setting;
|
||||
import net.citizensnpcs.api.event.NPCRightClickEvent;
|
||||
import net.citizensnpcs.api.exception.NPCLoadException;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
import net.citizensnpcs.editor.Editor;
|
||||
@ -17,6 +18,7 @@ import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.trait.Toggleable;
|
||||
import net.citizensnpcs.util.Messaging;
|
||||
import net.citizensnpcs.util.Paginator;
|
||||
import net.citizensnpcs.util.Util;
|
||||
import net.minecraft.server.EntityHuman;
|
||||
import net.minecraft.server.EntityLiving;
|
||||
|
||||
@ -26,19 +28,20 @@ import org.bukkit.conversations.ConversationAbandonedEvent;
|
||||
import org.bukkit.conversations.ConversationAbandonedListener;
|
||||
import org.bukkit.conversations.ConversationFactory;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class Text extends Trait implements Runnable, Toggleable, ConversationAbandonedListener {
|
||||
private final Map<String, Calendar> cooldowns = new HashMap<String, Calendar>();
|
||||
public class Text extends Trait implements Runnable, Toggleable, Listener, ConversationAbandonedListener {
|
||||
private final Map<String, Date> cooldowns = new HashMap<String, Date>();
|
||||
private int currentIndex;
|
||||
private final NPC npc;
|
||||
private final Plugin plugin;
|
||||
private boolean randomTalker = Setting.DEFAULT_RANDOM_TALKER.asBoolean();
|
||||
private boolean talkClose = Setting.DEFAULT_TALK_CLOSE.asBoolean();
|
||||
private final List<String> text = new ArrayList<String>();
|
||||
|
||||
public Text(NPC npc) {
|
||||
this.npc = npc;
|
||||
public Text() {
|
||||
super("text");
|
||||
this.plugin = Bukkit.getPluginManager().getPlugin("Citizens");
|
||||
}
|
||||
|
||||
@ -92,8 +95,16 @@ public class Text extends Trait implements Runnable, Toggleable, ConversationAba
|
||||
randomTalker = key.getBoolean("random-talker");
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onRightClick(NPCRightClickEvent event) {
|
||||
if (!event.getNPC().equals(npc))
|
||||
return;
|
||||
if (Util.isSettingFulfilled(event.getClicker(), Setting.TALK_ITEM) && !shouldTalkClose())
|
||||
sendText(event.getClicker());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNPCSpawn() {
|
||||
public void onSpawn() {
|
||||
if (text.isEmpty())
|
||||
populateDefaultText();
|
||||
}
|
||||
@ -116,17 +127,17 @@ public class Text extends Trait implements Runnable, Toggleable, ConversationAba
|
||||
Player player = (Player) search.getBukkitEntity();
|
||||
// If the cooldown is not expired, do not send text
|
||||
if (cooldowns.get(player.getName()) != null) {
|
||||
if (!Calendar.getInstance().after(cooldowns.get(player.getName())))
|
||||
if (!new Date().after(cooldowns.get(player.getName())))
|
||||
return;
|
||||
cooldowns.remove(player.getName());
|
||||
}
|
||||
if (sendText(player)) {
|
||||
// Add a cooldown if the text was successfully sent
|
||||
Calendar wait = Calendar.getInstance();
|
||||
wait.add(
|
||||
Calendar.SECOND,
|
||||
(new Random().nextInt(Setting.TALK_CLOSE_MAXIMUM_COOLDOWN.asInt()) + Setting.TALK_CLOSE_MINIMUM_COOLDOWN
|
||||
.asInt()));
|
||||
Date wait = new Date();
|
||||
int secondsDelta = new Random().nextInt(Setting.TALK_CLOSE_MAXIMUM_COOLDOWN.asInt())
|
||||
+ Setting.TALK_CLOSE_MINIMUM_COOLDOWN.asInt();
|
||||
long millisecondsDelta = TimeUnit.MILLISECONDS.convert(secondsDelta, TimeUnit.SECONDS);
|
||||
wait.setTime(wait.getTime() + millisecondsDelta);
|
||||
cooldowns.put(player.getName(), wait);
|
||||
}
|
||||
}
|
||||
@ -162,7 +173,7 @@ public class Text extends Trait implements Runnable, Toggleable, ConversationAba
|
||||
currentIndex = 0;
|
||||
index = currentIndex++;
|
||||
}
|
||||
npc.chat(player, text.get(index));
|
||||
Messaging.sendWithNPC(player, Setting.CHAT_PREFIX.asString() + text.get(index), npc);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,94 +0,0 @@
|
||||
package net.citizensnpcs.trait.waypoint;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import net.citizensnpcs.api.ai.AI;
|
||||
import net.citizensnpcs.api.ai.NavigationCallback;
|
||||
|
||||
import org.bukkit.Location;
|
||||
|
||||
public class GenericWaypointCallback extends NavigationCallback {
|
||||
private AI ai;
|
||||
private Location dest;
|
||||
private boolean executing;
|
||||
private Iterator<Waypoint> itr;
|
||||
private final Iterable<Waypoint> provider;
|
||||
|
||||
public GenericWaypointCallback(Iterable<Waypoint> provider) {
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
private void ensureItr() {
|
||||
if (itr == null || !itr.hasNext()) {
|
||||
itr = provider.iterator();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(AI ai) {
|
||||
this.ai = ai;
|
||||
executing |= !ai.hasDestination();
|
||||
if (!executing)
|
||||
return;
|
||||
if (dest == null) {
|
||||
ensureItr();
|
||||
if (itr.hasNext()) {
|
||||
dest = itr.next().getLocation();
|
||||
}
|
||||
}
|
||||
if (dest != null) {
|
||||
ai.setDestination(dest);
|
||||
}
|
||||
}
|
||||
|
||||
boolean hackfix = false;
|
||||
|
||||
@Override
|
||||
public boolean onCancel(AI ai, CancelReason reason) {
|
||||
if (hackfix) {
|
||||
hackfix = false;
|
||||
return false;
|
||||
}
|
||||
hackfix = false;
|
||||
if (executing && reason == CancelReason.REPLACE) {
|
||||
executing = false;
|
||||
return false;
|
||||
}
|
||||
executing = true;
|
||||
ensureItr();
|
||||
if (dest == null && itr.hasNext())
|
||||
dest = itr.next().getLocation();
|
||||
if (dest != null) {
|
||||
hackfix = true;
|
||||
ai.setDestination(dest);
|
||||
hackfix = false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCompletion(AI ai) {
|
||||
if (executing) { // if we're executing, we need to get the next waypoint
|
||||
ensureItr();
|
||||
dest = itr.hasNext() ? itr.next().getLocation() : null;
|
||||
} else {
|
||||
executing = true;
|
||||
// we're free to return to our waypoints!
|
||||
// if we had a destination, we will return to it.
|
||||
}
|
||||
if (dest != null) {
|
||||
ai.setDestination(dest);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void onProviderChanged() {
|
||||
itr = provider.iterator();
|
||||
if (ai == null)
|
||||
return;
|
||||
dest = itr.hasNext() ? itr.next().getLocation() : null;
|
||||
if (dest != null) {
|
||||
ai.setDestination(dest);
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,8 @@ package net.citizensnpcs.trait.waypoint;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import net.citizensnpcs.api.ai.NavigationCallback;
|
||||
import net.citizensnpcs.api.ai.Goal;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
import net.citizensnpcs.editor.Editor;
|
||||
import net.citizensnpcs.util.Messaging;
|
||||
@ -21,7 +22,7 @@ import org.bukkit.event.player.PlayerItemHeldEvent;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
public class LinearWaypointProvider implements WaypointProvider, Iterable<Waypoint> {
|
||||
private final GenericWaypointCallback callback = new GenericWaypointCallback(this);
|
||||
private WaypointGoal currentGoal;
|
||||
private final List<Waypoint> waypoints = Lists.newArrayList();
|
||||
|
||||
@Override
|
||||
@ -41,35 +42,37 @@ public class LinearWaypointProvider implements WaypointProvider, Iterable<Waypoi
|
||||
}
|
||||
|
||||
private String formatLoc(Location location) {
|
||||
return String.format("<e>%d<a>, <e>%d<a>, <e>%d<a>", location.getBlockX(), location.getBlockY(),
|
||||
location.getBlockZ());
|
||||
return String.format("<e>%d<a>, <e>%d<a>, <e>%d<a>", location.getBlockX(),
|
||||
location.getBlockY(), location.getBlockZ());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@SuppressWarnings("unused")
|
||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
if (!event.getPlayer().equals(player) || event.getAction() == Action.PHYSICAL)
|
||||
return;
|
||||
if (event.getAction() == Action.LEFT_CLICK_BLOCK || event.getAction() == Action.LEFT_CLICK_AIR) {
|
||||
if (event.getAction() == Action.LEFT_CLICK_BLOCK
|
||||
|| event.getAction() == Action.LEFT_CLICK_AIR) {
|
||||
if (event.getClickedBlock() == null)
|
||||
return;
|
||||
Location at = event.getClickedBlock().getLocation();
|
||||
waypoints.add(Math.max(0, editingSlot), new Waypoint(at));
|
||||
editingSlot = Math.min(editingSlot + 1, waypoints.size());
|
||||
Messaging.send(player, String.format("<e>Added<a> a waypoint at (" + formatLoc(at)
|
||||
+ ") (<e>%d<a>, <e>%d<a>)", editingSlot + 1, waypoints.size()));
|
||||
Messaging.send(
|
||||
player,
|
||||
String.format("<e>Added<a> a waypoint at (" + formatLoc(at)
|
||||
+ ") (<e>%d<a>, <e>%d<a>)", editingSlot + 1, waypoints.size()));
|
||||
} else if (waypoints.size() > 0) {
|
||||
editingSlot = Math.min(0, Math.max(waypoints.size() - 1, editingSlot));
|
||||
waypoints.remove(editingSlot);
|
||||
editingSlot = Math.max(0, editingSlot - 1);
|
||||
Messaging.send(player, String.format("<e>Removed<a> a waypoint (<e>%d<a> remaining) (<e>%d<a>)",
|
||||
waypoints.size(), editingSlot + 1));
|
||||
Messaging.send(player, String.format(
|
||||
"<e>Removed<a> a waypoint (<e>%d<a> remaining) (<e>%d<a>)", waypoints.size(),
|
||||
editingSlot + 1));
|
||||
}
|
||||
callback.onProviderChanged();
|
||||
currentGoal.onProviderChanged();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@SuppressWarnings("unused")
|
||||
public void onPlayerItemHeldChange(PlayerItemHeldEvent event) {
|
||||
if (!event.getPlayer().equals(player) || waypoints.size() == 0)
|
||||
return;
|
||||
@ -98,8 +101,10 @@ public class LinearWaypointProvider implements WaypointProvider, Iterable<Waypoi
|
||||
}
|
||||
|
||||
@Override
|
||||
public NavigationCallback getCallback() {
|
||||
return callback;
|
||||
public Goal getGoal(NPC npc) {
|
||||
if (currentGoal == null)
|
||||
currentGoal = new WaypointGoal(this, npc.getNavigator());
|
||||
return currentGoal;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -111,17 +116,12 @@ public class LinearWaypointProvider implements WaypointProvider, Iterable<Waypoi
|
||||
public void load(DataKey key) {
|
||||
for (DataKey root : key.getRelative("points").getIntegerSubKeys()) {
|
||||
root = root.getRelative("location");
|
||||
waypoints.add(new Waypoint(new Location(Bukkit.getWorld(root.getString("world")), root.getDouble("x"), root
|
||||
.getDouble("y"), root.getDouble("z"), (float) root.getDouble("yaw", 0), (float) root.getDouble(
|
||||
"pitch", 0))));
|
||||
waypoints.add(new Waypoint(new Location(Bukkit.getWorld(root.getString("world")), root
|
||||
.getDouble("x"), root.getDouble("y"), root.getDouble("z"), (float) root.getDouble("yaw",
|
||||
0), (float) root.getDouble("pitch", 0))));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach() {
|
||||
callback.onProviderChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(DataKey key) {
|
||||
key.removeKey("points");
|
||||
|
@ -0,0 +1,66 @@
|
||||
package net.citizensnpcs.trait.waypoint;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import net.citizensnpcs.api.ai.Goal;
|
||||
import net.citizensnpcs.api.ai.GoalSelector;
|
||||
import net.citizensnpcs.api.ai.Navigator;
|
||||
import net.citizensnpcs.api.ai.event.NavigationCancelEvent;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.event.EventHandler;
|
||||
|
||||
public class WaypointGoal implements Goal {
|
||||
private Location currentDestination;
|
||||
private Iterator<Waypoint> itr;
|
||||
private final Navigator navigator;
|
||||
private final Iterable<Waypoint> provider;
|
||||
private GoalSelector selector;
|
||||
|
||||
public WaypointGoal(Iterable<Waypoint> provider, Navigator navigator) {
|
||||
this.provider = provider;
|
||||
this.navigator = navigator;
|
||||
}
|
||||
|
||||
private void ensureItr() {
|
||||
if (itr == null || !itr.hasNext()) {
|
||||
itr = provider.iterator();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onNavigationCancel(NavigationCancelEvent event) {
|
||||
if (!event.getNavigator().equals(navigator) || currentDestination == null)
|
||||
return;
|
||||
if (currentDestination.equals(event.getNavigator().getTargetAsLocation()))
|
||||
selector.finish();
|
||||
}
|
||||
|
||||
public void onProviderChanged() {
|
||||
itr = provider.iterator();
|
||||
if (currentDestination != null)
|
||||
selector.finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
currentDestination = null;
|
||||
selector = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldExecute(GoalSelector selector) {
|
||||
ensureItr();
|
||||
boolean shouldExecute = itr.hasNext();
|
||||
if (shouldExecute) {
|
||||
this.selector = selector;
|
||||
currentDestination = itr.next().getLocation();
|
||||
navigator.setTarget(currentDestination);
|
||||
}
|
||||
return shouldExecute;
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package net.citizensnpcs.trait.waypoint;
|
||||
|
||||
import net.citizensnpcs.api.ai.AI;
|
||||
import net.citizensnpcs.api.ai.NavigationCallback;
|
||||
import net.citizensnpcs.api.ai.Goal;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
import net.citizensnpcs.editor.Editor;
|
||||
|
||||
@ -19,12 +19,12 @@ public interface WaypointProvider {
|
||||
public Editor createEditor(Player player);
|
||||
|
||||
/**
|
||||
* Returns the {@link NavigationCallback} linked to this provider. This will
|
||||
* be linked to the NPC's {@link AI}.
|
||||
*
|
||||
* @return The callback in use
|
||||
* @param npc
|
||||
* The attached {@link NPC} the goal is for.
|
||||
* @return The {@link Goal} to attach to the NPC.
|
||||
*/
|
||||
public NavigationCallback getCallback();
|
||||
public Goal getGoal(NPC npc);
|
||||
|
||||
/**
|
||||
* Loads from the specified {@link DataKey}.
|
||||
@ -41,6 +41,4 @@ public interface WaypointProvider {
|
||||
* The key to save to
|
||||
*/
|
||||
public void save(DataKey key);
|
||||
|
||||
public void onAttach();
|
||||
}
|
@ -4,8 +4,8 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import net.citizensnpcs.api.ai.Goal;
|
||||
import net.citizensnpcs.api.exception.NPCLoadException;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
import net.citizensnpcs.editor.Editor;
|
||||
@ -13,13 +13,11 @@ import net.citizensnpcs.editor.Editor;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class Waypoints extends Trait {
|
||||
private final NPC npc;
|
||||
private WaypointProvider provider = new LinearWaypointProvider();
|
||||
private String providerName = "linear";
|
||||
|
||||
public Waypoints(NPC npc) {
|
||||
this.npc = npc;
|
||||
npc.getAI().registerNavigationCallback(provider.getCallback());
|
||||
public Waypoints() {
|
||||
super("waypoints");
|
||||
}
|
||||
|
||||
private WaypointProvider create(Class<? extends WaypointProvider> clazz) {
|
||||
@ -32,11 +30,6 @@ public class Waypoints extends Trait {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNPCSpawn() {
|
||||
npc.getAI().registerNavigationCallback(provider.getCallback());
|
||||
}
|
||||
|
||||
public Editor getEditor(Player player) {
|
||||
return provider.createEditor(player);
|
||||
}
|
||||
@ -56,6 +49,14 @@ public class Waypoints extends Trait {
|
||||
provider.load(key.getRelative(providerName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpawn() {
|
||||
if (provider != null) {
|
||||
Goal goal = provider.getGoal(getNPC());
|
||||
getNPC().getDefaultGoalController().addGoal(goal, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(DataKey key) {
|
||||
if (provider == null)
|
||||
|
@ -22,6 +22,12 @@ public class Messaging {
|
||||
log(msg);
|
||||
}
|
||||
|
||||
private static String getFormatted(Object[] msg) {
|
||||
String toFormat = msg[0].toString();
|
||||
Object[] args = msg.length > 1 ? Arrays.copyOfRange(msg, 1, msg.length) : new Object[] {};
|
||||
return String.format(toFormat, args);
|
||||
}
|
||||
|
||||
public static void log(Level level, Object... msg) {
|
||||
Bukkit.getLogger().log(level, "[Citizens] " + SPACE.join(msg));
|
||||
}
|
||||
@ -30,12 +36,6 @@ public class Messaging {
|
||||
log(Level.INFO, msg);
|
||||
}
|
||||
|
||||
private static String getFormatted(Object[] msg) {
|
||||
String toFormat = msg[0].toString();
|
||||
Object[] args = msg.length > 1 ? Arrays.copyOfRange(msg, 1, msg.length) : new Object[] {};
|
||||
return String.format(toFormat, args);
|
||||
}
|
||||
|
||||
public static void logF(Object... msg) {
|
||||
log(getFormatted(msg));
|
||||
}
|
||||
@ -46,12 +46,6 @@ public class Messaging {
|
||||
sender.sendMessage(joined);
|
||||
}
|
||||
|
||||
public static void sendF(CommandSender sender, Object... msg) {
|
||||
String joined = getFormatted(msg);
|
||||
joined = StringHelper.parseColors(joined);
|
||||
sender.sendMessage(joined);
|
||||
}
|
||||
|
||||
public static void sendError(CommandSender sender, Object... msg) {
|
||||
send(sender, ChatColor.RED.toString() + SPACE.join(msg));
|
||||
}
|
||||
@ -60,6 +54,12 @@ public class Messaging {
|
||||
sendF(sender, ChatColor.RED.toString() + SPACE.join(msg));
|
||||
}
|
||||
|
||||
public static void sendF(CommandSender sender, Object... msg) {
|
||||
String joined = getFormatted(msg);
|
||||
joined = StringHelper.parseColors(joined);
|
||||
sender.sendMessage(joined);
|
||||
}
|
||||
|
||||
public static void sendWithNPC(CommandSender sender, Object msg, NPC npc) {
|
||||
String send = msg.toString();
|
||||
|
||||
|
@ -26,6 +26,8 @@ public class Util {
|
||||
private Util() {
|
||||
}
|
||||
|
||||
private static final Map<Class<?>, Class<?>> primitiveClassMap = Maps.newHashMap();
|
||||
|
||||
/**
|
||||
* Given a set of instantiation parameters, attempts to find a matching
|
||||
* constructor with the greatest number of matching class parameters and
|
||||
@ -85,6 +87,17 @@ public class Util {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isSettingFulfilled(Player player, Setting setting) {
|
||||
String parts = setting.asString();
|
||||
if (parts.contains("*"))
|
||||
return true;
|
||||
for (String part : Splitter.on(',').split(parts)) {
|
||||
if (Material.matchMaterial(part) == player.getItemInHand().getType()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private static boolean searchInterfaces(Class<?> class1, Class<?> class2) {
|
||||
for (Class<?> test : class1.getInterfaces())
|
||||
if (test == class2)
|
||||
@ -92,7 +105,31 @@ public class Util {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static final Map<Class<?>, Class<?>> primitiveClassMap = Maps.newHashMap();
|
||||
public static void sendPacketNearby(Location location, Packet packet, double radius) {
|
||||
radius *= radius;
|
||||
final World world = location.getWorld();
|
||||
for (Player ply : Bukkit.getServer().getOnlinePlayers()) {
|
||||
if (ply == null || world != ply.getWorld()) {
|
||||
continue;
|
||||
}
|
||||
if (location.distanceSquared(ply.getLocation()) > radius) {
|
||||
continue;
|
||||
}
|
||||
((CraftPlayer) ply).getHandle().netServerHandler.sendPacket(packet);
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendToOnline(Packet... packets) {
|
||||
Validate.notNull(packets, "packets cannot be null");
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
if (player == null || !player.isOnline())
|
||||
continue;
|
||||
for (Packet packet : packets) {
|
||||
((CraftPlayer) player).getHandle().netServerHandler.sendPacket(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
primitiveClassMap.put(Boolean.class, boolean.class);
|
||||
primitiveClassMap.put(Byte.class, byte.class);
|
||||
@ -111,41 +148,4 @@ public class Util {
|
||||
primitiveClassMap.put(float.class, Float.class);
|
||||
primitiveClassMap.put(double.class, Double.class);
|
||||
}
|
||||
|
||||
public static boolean isSettingFulfilled(Player player, Setting setting) {
|
||||
String parts = setting.asString();
|
||||
if (parts.contains("*"))
|
||||
return true;
|
||||
for (String part : Splitter.on(',').split(parts)) {
|
||||
if (Material.matchMaterial(part) == player.getItemInHand().getType()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void sendToOnline(Packet... packets) {
|
||||
Validate.notNull(packets, "packets cannot be null");
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
if (player == null || !player.isOnline())
|
||||
continue;
|
||||
for (Packet packet : packets) {
|
||||
((CraftPlayer) player).getHandle().netServerHandler.sendPacket(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendPacketNearby(Location location, Packet packet, double radius) {
|
||||
radius *= radius;
|
||||
final World world = location.getWorld();
|
||||
for (Player ply : Bukkit.getServer().getOnlinePlayers()) {
|
||||
if (ply == null || world != ply.getWorld()) {
|
||||
continue;
|
||||
}
|
||||
if (location.distanceSquared(ply.getLocation()) > radius) {
|
||||
continue;
|
||||
}
|
||||
((CraftPlayer) ply).getHandle().netServerHandler.sendPacket(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user