mirror of
https://github.com/CitizensDev/Citizens2.git
synced 2024-11-26 20:55:44 +01:00
Move Entity creation logic into EntityController, add /npc type, reduce Location object churn
This commit is contained in:
parent
4473b2e57e
commit
e998d2a78c
@ -83,12 +83,14 @@ public class EventListen implements Listener {
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onChunkUnload(ChunkUnloadEvent event) {
|
||||
ChunkCoord coord = toCoord(event.getChunk());
|
||||
Location cachedLocation = new Location(null, 0, 0, 0);
|
||||
for (NPC npc : npcRegistry) {
|
||||
if (!npc.isSpawned())
|
||||
continue;
|
||||
Location loc = npc.getBukkitEntity().getLocation();
|
||||
boolean sameChunkCoordinates = coord.z == loc.getBlockZ() >> 4 && coord.x == loc.getBlockX() >> 4;
|
||||
if (sameChunkCoordinates && event.getWorld().equals(loc.getWorld())) {
|
||||
cachedLocation = npc.getBukkitEntity().getLocation(cachedLocation);
|
||||
boolean sameChunkCoordinates = coord.z == cachedLocation.getBlockZ() >> 4
|
||||
&& coord.x == cachedLocation.getBlockX() >> 4;
|
||||
if (sameChunkCoordinates && event.getWorld().equals(cachedLocation.getWorld())) {
|
||||
npc.despawn(DespawnReason.CHUNK_UNLOAD);
|
||||
toRespawn.put(coord, npc.getId());
|
||||
Messaging.debug("Despawned", npc.getId(), "due to chunk unload at [" + coord.x + ","
|
||||
|
@ -69,48 +69,6 @@ import org.bukkit.scheduler.BukkitTask;
|
||||
*/
|
||||
public class Metrics {
|
||||
|
||||
/**
|
||||
* The current revision number
|
||||
*/
|
||||
private final static int REVISION = 6;
|
||||
|
||||
/**
|
||||
* 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 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
|
||||
*/
|
||||
@ -121,21 +79,37 @@ public class Metrics {
|
||||
*/
|
||||
private final File configurationFile;
|
||||
|
||||
/**
|
||||
* Unique server id
|
||||
*/
|
||||
private final String guid;
|
||||
|
||||
/**
|
||||
* Debug mode
|
||||
*/
|
||||
private final boolean debug;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
private final String guid;
|
||||
|
||||
/**
|
||||
* Lock for synchronization
|
||||
*/
|
||||
private final Object optOutLock = new Object();
|
||||
|
||||
/**
|
||||
* The plugin this metrics submits for
|
||||
*/
|
||||
private final Plugin plugin;
|
||||
|
||||
/**
|
||||
* The scheduled task
|
||||
*/
|
||||
@ -168,6 +142,39 @@ public class Metrics {
|
||||
debug = configuration.getBoolean("debug", false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a custom data plotter to the default graph
|
||||
*
|
||||
* @param plotter
|
||||
* The plotter to use to plot custom data
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a Graph object to Metrics that represents data for the plugin that
|
||||
* should be sent to the backend
|
||||
*
|
||||
* @param graph
|
||||
* The name of the graph
|
||||
*/
|
||||
public void addGraph(final Graph graph) {
|
||||
if (graph == null) {
|
||||
throw new IllegalArgumentException("Graph cannot be null");
|
||||
}
|
||||
|
||||
graphs.add(graph);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct and create a Graph that can be used to separate specific
|
||||
* plotters to their own graphs on the metrics website. Plotters can be
|
||||
@ -193,154 +200,6 @@ public class Metrics {
|
||||
return graph;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a Graph object to Metrics that represents data for the plugin that
|
||||
* should be sent to the backend
|
||||
*
|
||||
* @param graph
|
||||
* The name of the graph
|
||||
*/
|
||||
public void addGraph(final Graph graph) {
|
||||
if (graph == null) {
|
||||
throw new IllegalArgumentException("Graph cannot be null");
|
||||
}
|
||||
|
||||
graphs.add(graph);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a custom data plotter to the default graph
|
||||
*
|
||||
* @param plotter
|
||||
* The plotter to use to plot custom data
|
||||
*/
|
||||
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() {
|
||||
synchronized (optOutLock) {
|
||||
// Did we opt out?
|
||||
if (isOptOut()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Is metrics already running?
|
||||
if (task != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Begin hitting the server with glorious data
|
||||
task = plugin.getServer().getScheduler().runTaskTimerAsynchronously(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() && task != null) {
|
||||
task.cancel();
|
||||
task = null;
|
||||
// Tell all plotters to stop gathering
|
||||
// information.
|
||||
for (Graph graph : graphs) {
|
||||
graph.onOptOut();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
if (debug) {
|
||||
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 0, PING_INTERVAL * 1200);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Has the server owner denied plugin metrics?
|
||||
*
|
||||
* @return true if metrics should be opted out of it
|
||||
*/
|
||||
public boolean isOptOut() {
|
||||
synchronized (optOutLock) {
|
||||
try {
|
||||
// Reload the metrics file
|
||||
configuration.load(getConfigFile());
|
||||
} catch (IOException ex) {
|
||||
if (debug) {
|
||||
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
|
||||
}
|
||||
return true;
|
||||
} catch (InvalidConfigurationException ex) {
|
||||
if (debug) {
|
||||
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return configuration.getBoolean("opt-out", false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables metrics for the server by setting "opt-out" to false in the
|
||||
* config file and starting the metrics task.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public void enable() 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", false);
|
||||
configuration.save(configurationFile);
|
||||
}
|
||||
|
||||
// Enable Task, if it is not running
|
||||
if (task == null) {
|
||||
start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables metrics for the server by setting "opt-out" to true in the
|
||||
* config file and canceling the metrics task.
|
||||
@ -366,6 +225,30 @@ public class Metrics {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables metrics for the server by setting "opt-out" to false in the
|
||||
* config file and starting the metrics task.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public void enable() 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", false);
|
||||
configuration.save(configurationFile);
|
||||
}
|
||||
|
||||
// Enable Task, if it is not running
|
||||
if (task == null) {
|
||||
start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the File object of the config file that should be used to store data
|
||||
* such as the GUID and opt-out status
|
||||
@ -385,6 +268,46 @@ public class Metrics {
|
||||
return new File(new File(pluginsFolder, "PluginMetrics"), "config.yml");
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if mineshafter is present. If it is, we need to bypass it to send
|
||||
* POST requests
|
||||
*
|
||||
* @return true if mineshafter is installed on the server
|
||||
*/
|
||||
private boolean isMineshafterPresent() {
|
||||
try {
|
||||
Class.forName("mineshafter.MineServer");
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Has the server owner denied plugin metrics?
|
||||
*
|
||||
* @return true if metrics should be opted out of it
|
||||
*/
|
||||
public boolean isOptOut() {
|
||||
synchronized (optOutLock) {
|
||||
try {
|
||||
// Reload the metrics file
|
||||
configuration.load(getConfigFile());
|
||||
} catch (IOException ex) {
|
||||
if (debug) {
|
||||
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
|
||||
}
|
||||
return true;
|
||||
} catch (InvalidConfigurationException ex) {
|
||||
if (debug) {
|
||||
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return configuration.getBoolean("opt-out", false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic method that posts a plugin to the metrics website
|
||||
*/
|
||||
@ -516,54 +439,71 @@ 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 true if mineshafter is installed on the server
|
||||
* @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 (task != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Begin hitting the server with glorious data
|
||||
task = plugin.getServer().getScheduler().runTaskTimerAsynchronously(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() && task != null) {
|
||||
task.cancel();
|
||||
task = null;
|
||||
// Tell all plotters to stop gathering
|
||||
// information.
|
||||
for (Graph graph : graphs) {
|
||||
graph.onOptOut();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
if (debug) {
|
||||
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
|
||||
* the stringbuilder to append the data pair onto
|
||||
* @param key
|
||||
* the key value
|
||||
* @param value
|
||||
* the value
|
||||
*/
|
||||
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
|
||||
* the text to encode
|
||||
* @return the encoded text, as UTF-8
|
||||
*/
|
||||
private static String encode(final String text) throws UnsupportedEncodingException {
|
||||
return URLEncoder.encode(text, "UTF-8");
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom graph on the website
|
||||
*/
|
||||
@ -584,15 +524,6 @@ public class Metrics {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the graph's name
|
||||
*
|
||||
* @return the Graph's name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a plotter to the graph, which will be used to plot entries
|
||||
*
|
||||
@ -603,14 +534,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
|
||||
* the plotter to remove from the graph
|
||||
* @return the Graph's name
|
||||
*/
|
||||
public void removePlotter(final Plotter plotter) {
|
||||
plotters.remove(plotter);
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -627,16 +567,6 @@ 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the server owner decides to opt-out of Metrics while the
|
||||
* server is running.
|
||||
@ -644,6 +574,16 @@ public class Metrics {
|
||||
protected void onOptOut() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a plotter from the graph
|
||||
*
|
||||
* @param plotter
|
||||
* the plotter to remove from the graph
|
||||
*/
|
||||
public void removePlotter(final Plotter plotter) {
|
||||
plotters.remove(plotter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -674,16 +614,15 @@ public class Metrics {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current value for the plotted point. Since this function
|
||||
* defers to an external function it may or may not return immediately
|
||||
* thus cannot be guaranteed to be thread friendly or safe. This
|
||||
* function can be called from any thread so care should be taken when
|
||||
* accessing resources that need to be synchronized.
|
||||
*
|
||||
* @return the current value for the point to be plotted.
|
||||
*/
|
||||
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
|
||||
@ -695,26 +634,87 @@ public class Metrics {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after the website graphs have been updated
|
||||
* Get the current value for the plotted point. Since this function
|
||||
* defers to an external function it may or may not return immediately
|
||||
* thus cannot be guaranteed to be thread friendly or safe. This
|
||||
* function can be called from any thread so care should be taken when
|
||||
* accessing resources that need to be synchronized.
|
||||
*
|
||||
* @return the current value for the point to be plotted.
|
||||
*/
|
||||
public void reset() {
|
||||
}
|
||||
public abstract int getValue();
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getColumnName().hashCode();
|
||||
}
|
||||
|
||||
@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 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 = 6;
|
||||
|
||||
/**
|
||||
* Encode text as UTF-8
|
||||
*
|
||||
* @param text
|
||||
* the text to encode
|
||||
* @return the encoded text, as UTF-8
|
||||
*/
|
||||
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
|
||||
* the stringbuilder to append the data pair onto
|
||||
* @param key
|
||||
* the key value
|
||||
* @param value
|
||||
* the value
|
||||
*/
|
||||
private static void encodeDataPair(final StringBuilder buffer, final String key, final String value)
|
||||
throws UnsupportedEncodingException {
|
||||
buffer.append('&').append(encode(key)).append('=').append(encode(value));
|
||||
}
|
||||
|
||||
}
|
@ -94,7 +94,6 @@ public class NPCDataStore {
|
||||
saves = new YamlStorage(new File(folder, Setting.STORAGE_FILE.asString()), "Citizens NPC Storage");
|
||||
if (!saves.load())
|
||||
return null;
|
||||
Messaging.logTr(Messages.SAVE_METHOD_SET_NOTIFICATION, saves.toString());
|
||||
return new NPCDataStore(saves);
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import net.citizensnpcs.command.exception.CommandException;
|
||||
import net.citizensnpcs.command.exception.NoPermissionsException;
|
||||
import net.citizensnpcs.command.exception.ServerCommandException;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.EntityControllers;
|
||||
import net.citizensnpcs.npc.NPCSelector;
|
||||
import net.citizensnpcs.npc.Template;
|
||||
import net.citizensnpcs.trait.Age;
|
||||
@ -814,7 +815,12 @@ public class NPCCommands {
|
||||
Messaging.sendErrorTr(sender, Messages.NPC_NAME_TOO_LONG);
|
||||
newName = newName.substring(0, 15);
|
||||
}
|
||||
Location prev = npc.isSpawned() ? npc.getBukkitEntity().getLocation() : null;
|
||||
npc.despawn();
|
||||
npc.setName(newName);
|
||||
if (prev != null)
|
||||
npc.spawn(prev);
|
||||
|
||||
Messaging.sendTr(sender, Messages.NPC_RENAMED, oldName, newName);
|
||||
}
|
||||
|
||||
@ -989,6 +995,22 @@ public class NPCCommands {
|
||||
Messaging.sendTr(sender, Messages.NPC_TELEPORTED, npc.getName());
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "npc" },
|
||||
usage = "type",
|
||||
desc = "Sets an NPC's entity type",
|
||||
modifiers = { "type" },
|
||||
min = 2,
|
||||
max = 2,
|
||||
permission = "npc.type")
|
||||
public void type(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||
EntityType type = Util.matchEntityType(args.getString(1));
|
||||
if (type == null)
|
||||
throw new CommandException(Messages.INVALID_ENTITY_TYPE, args.getString(1));
|
||||
((CitizensNPC) npc).setEntityController(EntityControllers.createForType(type));
|
||||
Messaging.sendTr(sender, Messages.ENTITY_TYPE_SET, npc.getName(), args.getString(1));
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "npc" },
|
||||
usage = "vulnerable (-t)",
|
||||
|
42
src/main/java/net/citizensnpcs/editor/EndermanEquipper.java
Normal file
42
src/main/java/net/citizensnpcs/editor/EndermanEquipper.java
Normal file
@ -0,0 +1,42 @@
|
||||
package net.citizensnpcs.editor;
|
||||
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.trait.Equipment;
|
||||
import net.citizensnpcs.util.Messages;
|
||||
import net.citizensnpcs.util.Messaging;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Enderman;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.material.MaterialData;
|
||||
|
||||
public class EndermanEquipper implements Equipper {
|
||||
@Override
|
||||
public void equip(Player equipper, NPC npc) {
|
||||
ItemStack hand = equipper.getItemInHand();
|
||||
if (!hand.getType().isBlock()) {
|
||||
Messaging.sendErrorTr(equipper, Messages.EQUIPMENT_EDITOR_INVALID_BLOCK);
|
||||
return;
|
||||
}
|
||||
|
||||
MaterialData carried = ((Enderman) npc.getBukkitEntity()).getCarriedMaterial();
|
||||
if (carried.getItemType() == Material.AIR) {
|
||||
if (hand.getType() == Material.AIR) {
|
||||
Messaging.sendErrorTr(equipper, Messages.EQUIPMENT_EDITOR_INVALID_BLOCK);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
equipper.getWorld()
|
||||
.dropItemNaturally(npc.getBukkitEntity().getLocation(), carried.toItemStack(1));
|
||||
((Enderman) npc.getBukkitEntity()).setCarriedMaterial(hand.getData());
|
||||
}
|
||||
|
||||
ItemStack set = hand.clone();
|
||||
if (set.getType() != Material.AIR) {
|
||||
set.setAmount(1);
|
||||
hand.setAmount(hand.getAmount() - 1);
|
||||
}
|
||||
npc.getTrait(Equipment.class).set(0, set);
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
package net.citizensnpcs.editor;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public interface Equipable {
|
||||
public void equip(Player equipper, ItemStack toEquip);
|
||||
}
|
@ -1,10 +1,13 @@
|
||||
package net.citizensnpcs.editor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.util.Messages;
|
||||
import net.citizensnpcs.util.Messaging;
|
||||
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event.Result;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@ -13,6 +16,8 @@ import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
public class EquipmentEditor extends Editor {
|
||||
private final NPC npc;
|
||||
private final Player player;
|
||||
@ -40,14 +45,23 @@ public class EquipmentEditor extends Editor {
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
|
||||
if (!event.getPlayer().equals(player)
|
||||
if (!npc.isSpawned() || !event.getPlayer().equals(player)
|
||||
|| !npc.equals(CitizensAPI.getNPCRegistry().getNPC(event.getRightClicked())))
|
||||
return;
|
||||
|
||||
if (npc instanceof Equipable) {
|
||||
ItemStack hand = event.getPlayer().getItemInHand();
|
||||
((Equipable) npc).equip(event.getPlayer(), hand);
|
||||
event.getPlayer().setItemInHand(hand.getAmount() > 0 ? hand : null);
|
||||
}
|
||||
Equipper equipper = EQUIPPERS.get(npc.getBukkitEntity().getType());
|
||||
if (equipper == null)
|
||||
return;
|
||||
ItemStack hand = event.getPlayer().getItemInHand();
|
||||
equipper.equip(event.getPlayer(), npc);
|
||||
event.getPlayer().setItemInHand(hand.getAmount() > 0 ? hand : null);
|
||||
}
|
||||
|
||||
private static final Map<EntityType, Equipper> EQUIPPERS = Maps.newEnumMap(EntityType.class);
|
||||
static {
|
||||
EQUIPPERS.put(EntityType.PIG, new PigEquipper());
|
||||
EQUIPPERS.put(EntityType.PLAYER, new HumanEquipper());
|
||||
EQUIPPERS.put(EntityType.SHEEP, new SheepEquipper());
|
||||
EQUIPPERS.put(EntityType.ENDERMAN, new EndermanEquipper());
|
||||
}
|
||||
}
|
9
src/main/java/net/citizensnpcs/editor/Equipper.java
Normal file
9
src/main/java/net/citizensnpcs/editor/Equipper.java
Normal file
@ -0,0 +1,9 @@
|
||||
package net.citizensnpcs.editor;
|
||||
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public interface Equipper {
|
||||
public void equip(Player equipper, NPC toEquip);
|
||||
}
|
84
src/main/java/net/citizensnpcs/editor/HumanEquipper.java
Normal file
84
src/main/java/net/citizensnpcs/editor/HumanEquipper.java
Normal file
@ -0,0 +1,84 @@
|
||||
package net.citizensnpcs.editor;
|
||||
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.trait.Equipment;
|
||||
import net.citizensnpcs.util.Messages;
|
||||
import net.citizensnpcs.util.Messaging;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class HumanEquipper implements Equipper {
|
||||
|
||||
@Override
|
||||
public void equip(Player equipper, NPC toEquip) {
|
||||
ItemStack hand = equipper.getItemInHand();
|
||||
Equipment trait = toEquip.getTrait(Equipment.class);
|
||||
int slot = 0;
|
||||
Material type = hand == null ? Material.AIR : hand.getType();
|
||||
// First, determine the slot to edit
|
||||
switch (type) {
|
||||
case SKULL_ITEM:
|
||||
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(toEquip.getBukkitEntity().getLocation(),
|
||||
trait.get(i));
|
||||
trait.set(i, null);
|
||||
}
|
||||
}
|
||||
Messaging.sendTr(equipper, Messages.EQUIPMENT_EDITOR_ALL_ITEMS_REMOVED, toEquip.getName());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Drop any previous equipment on the ground
|
||||
ItemStack equippedItem = trait.get(slot);
|
||||
if (equippedItem != null && equippedItem.getType() != Material.AIR)
|
||||
equipper.getWorld().dropItemNaturally(toEquip.getBukkitEntity().getLocation(), equippedItem);
|
||||
|
||||
// Now edit the equipment based on the slot
|
||||
if (type != Material.AIR) {
|
||||
// Set the proper slot with one of the item
|
||||
ItemStack clone = hand.clone();
|
||||
clone.setAmount(1);
|
||||
trait.set(slot, clone);
|
||||
hand.setAmount(hand.getAmount() - 1);
|
||||
}
|
||||
}
|
||||
}
|
30
src/main/java/net/citizensnpcs/editor/PigEquipper.java
Normal file
30
src/main/java/net/citizensnpcs/editor/PigEquipper.java
Normal file
@ -0,0 +1,30 @@
|
||||
package net.citizensnpcs.editor;
|
||||
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.trait.Saddle;
|
||||
import net.citizensnpcs.util.Messages;
|
||||
import net.citizensnpcs.util.Messaging;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Pig;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class PigEquipper implements Equipper {
|
||||
@Override
|
||||
public void equip(Player equipper, NPC toEquip) {
|
||||
ItemStack hand = equipper.getItemInHand();
|
||||
Pig pig = (Pig) toEquip.getBukkitEntity();
|
||||
if (hand.getType() == Material.SADDLE) {
|
||||
if (!pig.hasSaddle()) {
|
||||
toEquip.getTrait(Saddle.class).toggle();
|
||||
hand.setAmount(0);
|
||||
Messaging.sendTr(equipper, Messages.SADDLED_SET, toEquip.getName());
|
||||
}
|
||||
} else if (pig.hasSaddle()) {
|
||||
equipper.getWorld().dropItemNaturally(pig.getLocation(), new ItemStack(Material.SADDLE, 1));
|
||||
toEquip.getTrait(Saddle.class).toggle();
|
||||
Messaging.sendTr(equipper, Messages.SADDLED_STOPPED, toEquip.getName());
|
||||
}
|
||||
}
|
||||
}
|
38
src/main/java/net/citizensnpcs/editor/SheepEquipper.java
Normal file
38
src/main/java/net/citizensnpcs/editor/SheepEquipper.java
Normal file
@ -0,0 +1,38 @@
|
||||
package net.citizensnpcs.editor;
|
||||
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.trait.Sheared;
|
||||
import net.citizensnpcs.trait.WoolColor;
|
||||
import net.citizensnpcs.util.Messages;
|
||||
import net.citizensnpcs.util.Messaging;
|
||||
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Sheep;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class SheepEquipper implements Equipper {
|
||||
@Override
|
||||
public void equip(Player equipper, NPC toEquip) {
|
||||
ItemStack hand = equipper.getItemInHand();
|
||||
Sheep sheep = (Sheep) toEquip.getBukkitEntity();
|
||||
if (hand.getType() == Material.SHEARS) {
|
||||
Messaging.sendTr(equipper, toEquip.getTrait(Sheared.class).toggle() ? Messages.SHEARED_SET
|
||||
: Messages.SHEARED_STOPPED, toEquip.getName());
|
||||
} else if (hand.getType() == Material.INK_SACK) {
|
||||
if (sheep.getColor() == DyeColor.getByData((byte) (15 - hand.getData().getData())))
|
||||
return;
|
||||
|
||||
DyeColor color = DyeColor.getByData((byte) (15 - hand.getData().getData()));
|
||||
toEquip.getTrait(WoolColor.class).setColor(color);
|
||||
Messaging.sendTr(equipper, Messages.EQUIPMENT_EDITOR_SHEEP_COLOURED, toEquip.getName(), color
|
||||
.name().toLowerCase().replace("_", " "));
|
||||
|
||||
hand.setAmount(hand.getAmount() - 1);
|
||||
} else {
|
||||
toEquip.getTrait(WoolColor.class).setColor(DyeColor.WHITE);
|
||||
Messaging.sendTr(equipper, Messages.EQUIPMENT_EDITOR_SHEEP_COLOURED, toEquip.getName(), "white");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package net.citizensnpcs.npc;
|
||||
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
public abstract class AbstractEntityController implements EntityController {
|
||||
private LivingEntity bukkitEntity;
|
||||
|
||||
protected abstract LivingEntity createEntity(Location at, NPC npc);
|
||||
|
||||
@Override
|
||||
public LivingEntity getBukkitEntity() {
|
||||
return bukkitEntity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
if (bukkitEntity == null)
|
||||
return;
|
||||
bukkitEntity.remove();
|
||||
bukkitEntity = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawn(Location at, NPC npc) {
|
||||
bukkitEntity = createEntity(at, npc);
|
||||
}
|
||||
}
|
@ -25,29 +25,30 @@ import net.citizensnpcs.util.NMS;
|
||||
import net.citizensnpcs.util.Util;
|
||||
import net.minecraft.server.v1_4_5.EntityLiving;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_4_5.entity.CraftLivingEntity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
public abstract class CitizensNPC extends AbstractNPC {
|
||||
protected EntityLiving mcEntity;
|
||||
public class CitizensNPC extends AbstractNPC {
|
||||
private EntityController entityController;
|
||||
private final CitizensNavigator navigator = new CitizensNavigator(this);
|
||||
private final List<String> removedTraits = Lists.newArrayList();
|
||||
|
||||
protected CitizensNPC(int id, String name) {
|
||||
public CitizensNPC(int id, String name, EntityController entityController) {
|
||||
super(id, name);
|
||||
Preconditions.checkNotNull(entityController);
|
||||
this.entityController = entityController;
|
||||
}
|
||||
|
||||
protected abstract EntityLiving createHandle(Location loc);
|
||||
|
||||
@Override
|
||||
public boolean despawn(DespawnReason reason) {
|
||||
if (!isSpawned())
|
||||
@ -67,21 +68,19 @@ public abstract class CitizensNPC extends AbstractNPC {
|
||||
data().remove("selectors");
|
||||
for (Trait trait : traits.values())
|
||||
trait.onDespawn();
|
||||
getBukkitEntity().remove();
|
||||
mcEntity = null;
|
||||
entityController.remove();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LivingEntity getBukkitEntity() {
|
||||
if (mcEntity == null)
|
||||
return null;
|
||||
return (LivingEntity) mcEntity.getBukkitEntity();
|
||||
return entityController.getBukkitEntity();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public EntityLiving getHandle() {
|
||||
return mcEntity;
|
||||
return ((CraftLivingEntity) getBukkitEntity()).getHandle();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -91,7 +90,7 @@ public abstract class CitizensNPC extends AbstractNPC {
|
||||
|
||||
@Override
|
||||
public boolean isSpawned() {
|
||||
return mcEntity != null;
|
||||
return getBukkitEntity() != null;
|
||||
}
|
||||
|
||||
public void load(final DataKey root) {
|
||||
@ -177,35 +176,49 @@ public abstract class CitizensNPC extends AbstractNPC {
|
||||
removeTraitData(root);
|
||||
}
|
||||
|
||||
public void setEntityController(EntityController newController) {
|
||||
Preconditions.checkNotNull(newController);
|
||||
boolean wasSpawned = isSpawned();
|
||||
Location prev = null;
|
||||
if (wasSpawned) {
|
||||
prev = getBukkitEntity().getLocation();
|
||||
despawn();
|
||||
}
|
||||
entityController = newController;
|
||||
if (wasSpawned)
|
||||
spawn(prev);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean spawn(Location loc) {
|
||||
Validate.notNull(loc, "location cannot be null");
|
||||
public boolean spawn(Location at) {
|
||||
Preconditions.checkNotNull(at, "location cannot be null");
|
||||
if (isSpawned())
|
||||
return false;
|
||||
|
||||
mcEntity = createHandle(loc);
|
||||
boolean couldSpawn = !Util.isLoaded(loc) ? false : mcEntity.world.addEntity(mcEntity,
|
||||
entityController.spawn(at, this);
|
||||
EntityLiving mcEntity = getHandle();
|
||||
boolean couldSpawn = !Util.isLoaded(at) ? false : mcEntity.world.addEntity(mcEntity,
|
||||
SpawnReason.CUSTOM);
|
||||
if (!couldSpawn) {
|
||||
// we need to wait for a chunk load before trying to spawn
|
||||
mcEntity = null;
|
||||
EventListen.addForRespawn(loc, getId());
|
||||
EventListen.addForRespawn(at, getId());
|
||||
return true;
|
||||
}
|
||||
|
||||
NPCSpawnEvent spawnEvent = new NPCSpawnEvent(this, loc);
|
||||
NPCSpawnEvent spawnEvent = new NPCSpawnEvent(this, at);
|
||||
Bukkit.getPluginManager().callEvent(spawnEvent);
|
||||
if (spawnEvent.isCancelled()) {
|
||||
mcEntity = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
NMS.setHeadYaw(mcEntity, loc.getYaw());
|
||||
NMS.setHeadYaw(mcEntity, at.getYaw());
|
||||
getBukkitEntity().setMetadata(NPC_METADATA_MARKER,
|
||||
new FixedMetadataValue(CitizensAPI.getPlugin(), true));
|
||||
|
||||
// Set the spawned state
|
||||
getTrait(CurrentLocation.class).setLocation(loc);
|
||||
getTrait(CurrentLocation.class).setLocation(at);
|
||||
getTrait(Spawned.class).setSpawned(true);
|
||||
|
||||
navigator.onSpawn();
|
||||
|
@ -1,43 +1,12 @@
|
||||
package net.citizensnpcs.npc;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import net.citizensnpcs.NPCDataStore;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.npc.NPCRegistry;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.npc.entity.CitizensBatNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensBlazeNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensCaveSpiderNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensChickenNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensCowNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensCreeperNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensEnderDragonNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensEndermanNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensGhastNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensGiantNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensHumanNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensIronGolemNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensMagmaCubeNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensMushroomCowNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensOcelotNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensPigNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensPigZombieNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensSheepNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensSilverfishNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensSkeletonNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensSlimeNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensSnowmanNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensSpiderNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensSquidNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensVillagerNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensWitchNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensWitherNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensWolfNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensZombieNPC;
|
||||
import net.citizensnpcs.util.ByIdArray;
|
||||
|
||||
import org.bukkit.craftbukkit.v1_4_5.entity.CraftEntity;
|
||||
@ -47,41 +16,9 @@ import org.bukkit.entity.EntityType;
|
||||
public class CitizensNPCRegistry implements NPCRegistry {
|
||||
private final ByIdArray<NPC> npcs = new ByIdArray<NPC>();
|
||||
private final NPCDataStore saves;
|
||||
private final Map<EntityType, Class<? extends CitizensNPC>> types = new EnumMap<EntityType, Class<? extends CitizensNPC>>(
|
||||
EntityType.class);
|
||||
|
||||
public CitizensNPCRegistry(NPCDataStore store) {
|
||||
saves = store;
|
||||
|
||||
types.put(EntityType.BAT, CitizensBatNPC.class);
|
||||
types.put(EntityType.BLAZE, CitizensBlazeNPC.class);
|
||||
types.put(EntityType.CAVE_SPIDER, CitizensCaveSpiderNPC.class);
|
||||
types.put(EntityType.CHICKEN, CitizensChickenNPC.class);
|
||||
types.put(EntityType.COW, CitizensCowNPC.class);
|
||||
types.put(EntityType.CREEPER, CitizensCreeperNPC.class);
|
||||
types.put(EntityType.ENDER_DRAGON, CitizensEnderDragonNPC.class);
|
||||
types.put(EntityType.ENDERMAN, CitizensEndermanNPC.class);
|
||||
types.put(EntityType.GHAST, CitizensGhastNPC.class);
|
||||
types.put(EntityType.GIANT, CitizensGiantNPC.class);
|
||||
types.put(EntityType.IRON_GOLEM, CitizensIronGolemNPC.class);
|
||||
types.put(EntityType.MAGMA_CUBE, CitizensMagmaCubeNPC.class);
|
||||
types.put(EntityType.MUSHROOM_COW, CitizensMushroomCowNPC.class);
|
||||
types.put(EntityType.OCELOT, CitizensOcelotNPC.class);
|
||||
types.put(EntityType.PIG, CitizensPigNPC.class);
|
||||
types.put(EntityType.PIG_ZOMBIE, CitizensPigZombieNPC.class);
|
||||
types.put(EntityType.PLAYER, CitizensHumanNPC.class);
|
||||
types.put(EntityType.SHEEP, CitizensSheepNPC.class);
|
||||
types.put(EntityType.SILVERFISH, CitizensSilverfishNPC.class);
|
||||
types.put(EntityType.SKELETON, CitizensSkeletonNPC.class);
|
||||
types.put(EntityType.SLIME, CitizensSlimeNPC.class);
|
||||
types.put(EntityType.SNOWMAN, CitizensSnowmanNPC.class);
|
||||
types.put(EntityType.SPIDER, CitizensSpiderNPC.class);
|
||||
types.put(EntityType.SQUID, CitizensSquidNPC.class);
|
||||
types.put(EntityType.VILLAGER, CitizensVillagerNPC.class);
|
||||
types.put(EntityType.WOLF, CitizensWolfNPC.class);
|
||||
types.put(EntityType.WITCH, CitizensWitchNPC.class);
|
||||
types.put(EntityType.WITHER, CitizensWitherNPC.class);
|
||||
types.put(EntityType.ZOMBIE, CitizensZombieNPC.class);
|
||||
}
|
||||
|
||||
public NPC createNPC(EntityType type, int id, String name) {
|
||||
@ -134,17 +71,7 @@ public class CitizensNPCRegistry implements NPCRegistry {
|
||||
}
|
||||
|
||||
private CitizensNPC getByType(EntityType type, int id, String name) {
|
||||
Class<? extends CitizensNPC> npcClass = types.get(type);
|
||||
if (npcClass == null)
|
||||
throw new IllegalArgumentException("Invalid EntityType: " + type);
|
||||
try {
|
||||
return npcClass.getConstructor(int.class, String.class).newInstance(id, name);
|
||||
} catch (Throwable ex) {
|
||||
if (ex.getCause() != null)
|
||||
ex = ex.getCause();
|
||||
ex.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
return new CitizensNPC(id, name, EntityControllers.createForType(type));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
14
src/main/java/net/citizensnpcs/npc/EntityController.java
Normal file
14
src/main/java/net/citizensnpcs/npc/EntityController.java
Normal file
@ -0,0 +1,14 @@
|
||||
package net.citizensnpcs.npc;
|
||||
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
public interface EntityController {
|
||||
LivingEntity getBukkitEntity();
|
||||
|
||||
void remove();
|
||||
|
||||
void spawn(Location at, NPC npc);
|
||||
}
|
88
src/main/java/net/citizensnpcs/npc/EntityControllers.java
Normal file
88
src/main/java/net/citizensnpcs/npc/EntityControllers.java
Normal file
@ -0,0 +1,88 @@
|
||||
package net.citizensnpcs.npc;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import net.citizensnpcs.npc.entity.BatController;
|
||||
import net.citizensnpcs.npc.entity.BlazeController;
|
||||
import net.citizensnpcs.npc.entity.CaveSpiderController;
|
||||
import net.citizensnpcs.npc.entity.ChickenController;
|
||||
import net.citizensnpcs.npc.entity.CowController;
|
||||
import net.citizensnpcs.npc.entity.CreeperController;
|
||||
import net.citizensnpcs.npc.entity.EnderDragonController;
|
||||
import net.citizensnpcs.npc.entity.EndermanController;
|
||||
import net.citizensnpcs.npc.entity.GhastController;
|
||||
import net.citizensnpcs.npc.entity.GiantController;
|
||||
import net.citizensnpcs.npc.entity.HumanController;
|
||||
import net.citizensnpcs.npc.entity.IronGolemController;
|
||||
import net.citizensnpcs.npc.entity.MagmaCubeController;
|
||||
import net.citizensnpcs.npc.entity.MushroomCowController;
|
||||
import net.citizensnpcs.npc.entity.OcelotController;
|
||||
import net.citizensnpcs.npc.entity.PigController;
|
||||
import net.citizensnpcs.npc.entity.PigZombieController;
|
||||
import net.citizensnpcs.npc.entity.SheepController;
|
||||
import net.citizensnpcs.npc.entity.SilverfishController;
|
||||
import net.citizensnpcs.npc.entity.SkeletonController;
|
||||
import net.citizensnpcs.npc.entity.SlimeController;
|
||||
import net.citizensnpcs.npc.entity.SnowmanController;
|
||||
import net.citizensnpcs.npc.entity.SpiderController;
|
||||
import net.citizensnpcs.npc.entity.SquidController;
|
||||
import net.citizensnpcs.npc.entity.VillagerController;
|
||||
import net.citizensnpcs.npc.entity.WitchController;
|
||||
import net.citizensnpcs.npc.entity.WitherController;
|
||||
import net.citizensnpcs.npc.entity.WolfController;
|
||||
import net.citizensnpcs.npc.entity.ZombieController;
|
||||
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
public class EntityControllers {
|
||||
|
||||
private static final Map<EntityType, Class<? extends EntityController>> TYPES = Maps
|
||||
.newEnumMap(EntityType.class);
|
||||
public static EntityController createForType(EntityType type) {
|
||||
Class<? extends EntityController> controllerClass = TYPES.get(type);
|
||||
if (controllerClass == null)
|
||||
throw new IllegalArgumentException("Invalid EntityType: " + type);
|
||||
try {
|
||||
return controllerClass.newInstance();
|
||||
} catch (Throwable ex) {
|
||||
if (ex.getCause() != null)
|
||||
ex = ex.getCause();
|
||||
ex.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
TYPES.put(EntityType.BAT, BatController.class);
|
||||
TYPES.put(EntityType.BLAZE, BlazeController.class);
|
||||
TYPES.put(EntityType.CAVE_SPIDER, CaveSpiderController.class);
|
||||
TYPES.put(EntityType.CHICKEN, ChickenController.class);
|
||||
TYPES.put(EntityType.COW, CowController.class);
|
||||
TYPES.put(EntityType.CREEPER, CreeperController.class);
|
||||
TYPES.put(EntityType.ENDER_DRAGON, EnderDragonController.class);
|
||||
TYPES.put(EntityType.ENDERMAN, EndermanController.class);
|
||||
TYPES.put(EntityType.GHAST, GhastController.class);
|
||||
TYPES.put(EntityType.GIANT, GiantController.class);
|
||||
TYPES.put(EntityType.IRON_GOLEM, IronGolemController.class);
|
||||
TYPES.put(EntityType.MAGMA_CUBE, MagmaCubeController.class);
|
||||
TYPES.put(EntityType.MUSHROOM_COW, MushroomCowController.class);
|
||||
TYPES.put(EntityType.OCELOT, OcelotController.class);
|
||||
TYPES.put(EntityType.PIG, PigController.class);
|
||||
TYPES.put(EntityType.PIG_ZOMBIE, PigZombieController.class);
|
||||
TYPES.put(EntityType.PLAYER, HumanController.class);
|
||||
TYPES.put(EntityType.SHEEP, SheepController.class);
|
||||
TYPES.put(EntityType.SILVERFISH, SilverfishController.class);
|
||||
TYPES.put(EntityType.SKELETON, SkeletonController.class);
|
||||
TYPES.put(EntityType.SLIME, SlimeController.class);
|
||||
TYPES.put(EntityType.SNOWMAN, SnowmanController.class);
|
||||
TYPES.put(EntityType.SPIDER, SpiderController.class);
|
||||
TYPES.put(EntityType.SQUID, SquidController.class);
|
||||
TYPES.put(EntityType.VILLAGER, VillagerController.class);
|
||||
TYPES.put(EntityType.WOLF, WolfController.class);
|
||||
TYPES.put(EntityType.WITCH, WitchController.class);
|
||||
TYPES.put(EntityType.WITHER, WitherController.class);
|
||||
TYPES.put(EntityType.ZOMBIE, ZombieController.class);
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
package net.citizensnpcs.npc;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
@ -12,42 +11,40 @@ import net.minecraft.server.v1_4_5.World;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.craftbukkit.v1_4_5.CraftWorld;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
public abstract class CitizensMobNPC extends CitizensNPC {
|
||||
public abstract class MobEntityController extends AbstractEntityController {
|
||||
private final Constructor<?> constructor;
|
||||
|
||||
protected CitizensMobNPC(int id, String name, Class<?> clazz) {
|
||||
super(id, name);
|
||||
protected MobEntityController(Class<?> clazz) {
|
||||
this.constructor = getConstructor(clazz);
|
||||
NMS.registerEntityClass(clazz);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LivingEntity createEntity(Location at, NPC npc) {
|
||||
EntityLiving entity = createEntityFromClass(((CraftWorld) at.getWorld()).getHandle(), npc);
|
||||
entity.setPositionRotation(at.getX(), at.getY(), at.getZ(), at.getYaw(), at.getPitch());
|
||||
|
||||
// entity.onGround isn't updated right away - we approximate here so
|
||||
// that things like pathfinding still work *immediately* after spawn.
|
||||
org.bukkit.Material beneath = at.getBlock().getRelative(BlockFace.DOWN).getType();
|
||||
if (beneath.isBlock())
|
||||
entity.onGround = true;
|
||||
return (LivingEntity) entity.getBukkitEntity();
|
||||
}
|
||||
|
||||
private EntityLiving createEntityFromClass(Object... args) {
|
||||
try {
|
||||
Object[] newArgs = Arrays.copyOf(args, args.length + 1);
|
||||
newArgs[args.length] = this;
|
||||
return (EntityLiving) constructor.newInstance(newArgs);
|
||||
return (EntityLiving) constructor.newInstance(args);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EntityLiving createHandle(Location loc) {
|
||||
EntityLiving entity = createEntityFromClass(((CraftWorld) loc.getWorld()).getHandle());
|
||||
entity.setPositionRotation(loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch());
|
||||
|
||||
// entity.onGround isn't updated right away - we approximate here so
|
||||
// that things like pathfinding still work *immediately* after spawn.
|
||||
org.bukkit.Material beneath = loc.getBlock().getRelative(BlockFace.DOWN).getType();
|
||||
if (beneath.isBlock())
|
||||
entity.onGround = true;
|
||||
return entity;
|
||||
}
|
||||
|
||||
private static final Map<Class<?>, Constructor<?>> CONSTRUCTOR_CACHE = Maps.newHashMap();
|
||||
|
||||
private static Constructor<?> getConstructor(Class<?> clazz) {
|
@ -32,6 +32,8 @@ public class CitizensNavigator implements Navigator, Runnable {
|
||||
private int lastX, lastY, lastZ;
|
||||
private NavigatorParameters localParams = defaultParams;
|
||||
private final CitizensNPC npc;
|
||||
private final Location stationaryLocation = new Location(null, 0, 0, 0);
|
||||
|
||||
private int stationaryTicks;
|
||||
|
||||
public CitizensNavigator(CitizensNPC npc) {
|
||||
@ -211,19 +213,19 @@ public class CitizensNavigator implements Navigator, Runnable {
|
||||
private boolean updateStationaryStatus() {
|
||||
if (localParams.stationaryTicks() < 0)
|
||||
return false;
|
||||
Location handle = npc.getBukkitEntity().getLocation();
|
||||
if (lastX == handle.getBlockX() && lastY == handle.getBlockY() && lastZ == handle.getBlockZ()) {
|
||||
npc.getBukkitEntity().getLocation(stationaryLocation);
|
||||
if (lastX == stationaryLocation.getBlockX() && lastY == stationaryLocation.getBlockY()
|
||||
&& lastZ == stationaryLocation.getBlockZ()) {
|
||||
if (++stationaryTicks >= localParams.stationaryTicks()) {
|
||||
stopNavigating(CancelReason.STUCK);
|
||||
return true;
|
||||
}
|
||||
} else
|
||||
stationaryTicks = 0;
|
||||
lastX = handle.getBlockX();
|
||||
lastY = handle.getBlockY();
|
||||
lastZ = handle.getBlockZ();
|
||||
lastX = stationaryLocation.getBlockX();
|
||||
lastY = stationaryLocation.getBlockY();
|
||||
lastZ = stationaryLocation.getBlockZ();
|
||||
return false;
|
||||
}
|
||||
|
||||
private static int UNINITIALISED_SPEED = Integer.MIN_VALUE;
|
||||
}
|
||||
|
@ -22,8 +22,12 @@ public class MCTargetStrategy implements PathStrategy, EntityTarget {
|
||||
private CancelReason cancelReason;
|
||||
private final EntityLiving handle, target;
|
||||
private final Navigation navigation;
|
||||
private final Location npcLocation = new Location(null, 0, 0, 0);
|
||||
|
||||
private final NavigatorParameters parameters;
|
||||
|
||||
private final Location targetLocation = new Location(null, 0, 0, 0);
|
||||
|
||||
public MCTargetStrategy(NPC handle, LivingEntity target, boolean aggro, NavigatorParameters params) {
|
||||
this.handle = ((CraftLivingEntity) handle.getBukkitEntity()).getHandle();
|
||||
this.target = ((CraftLivingEntity) target).getHandle();
|
||||
@ -38,14 +42,14 @@ public class MCTargetStrategy implements PathStrategy, EntityTarget {
|
||||
&& (handle.boundingBox.e > target.boundingBox.b && handle.boundingBox.b < target.boundingBox.e)
|
||||
&& distanceSquared() <= ATTACK_DISTANCE && hasLineOfSight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearCancelReason() {
|
||||
cancelReason = null;
|
||||
}
|
||||
|
||||
private double distanceSquared() {
|
||||
return handle.getBukkitEntity().getLocation().distanceSquared(target.getBukkitEntity().getLocation());
|
||||
return handle.getBukkitEntity().getLocation(npcLocation)
|
||||
.distanceSquared(target.getBukkitEntity().getLocation(targetLocation));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2,7 +2,7 @@ package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.MobEntityController;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
@ -17,9 +17,9 @@ import org.bukkit.entity.Bat;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CitizensBatNPC extends CitizensMobNPC {
|
||||
public CitizensBatNPC(int id, String name) {
|
||||
super(id, name, EntityBatNPC.class);
|
||||
public class BatController extends MobEntityController {
|
||||
public BatController() {
|
||||
super(EntityBatNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
@ -2,7 +2,7 @@ package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.MobEntityController;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
@ -17,10 +17,9 @@ import org.bukkit.entity.Blaze;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CitizensBlazeNPC extends CitizensMobNPC {
|
||||
|
||||
public CitizensBlazeNPC(int id, String name) {
|
||||
super(id, name, EntityBlazeNPC.class);
|
||||
public class BlazeController extends MobEntityController {
|
||||
public BlazeController() {
|
||||
super(EntityBlazeNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
@ -2,7 +2,7 @@ package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.MobEntityController;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
@ -17,9 +17,9 @@ import org.bukkit.entity.CaveSpider;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CitizensCaveSpiderNPC extends CitizensMobNPC {
|
||||
public CitizensCaveSpiderNPC(int id, String name) {
|
||||
super(id, name, EntityCaveSpiderNPC.class);
|
||||
public class CaveSpiderController extends MobEntityController {
|
||||
public CaveSpiderController() {
|
||||
super(EntityCaveSpiderNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
@ -2,7 +2,7 @@ package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.MobEntityController;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
@ -17,9 +17,9 @@ import org.bukkit.entity.Chicken;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CitizensChickenNPC extends CitizensMobNPC {
|
||||
public CitizensChickenNPC(int id, String name) {
|
||||
super(id, name, EntityChickenNPC.class);
|
||||
public class ChickenController extends MobEntityController {
|
||||
public ChickenController() {
|
||||
super(EntityChickenNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
@ -1,164 +0,0 @@
|
||||
package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
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.NPCHolder;
|
||||
import net.citizensnpcs.util.Messages;
|
||||
import net.citizensnpcs.util.Messaging;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
import net.citizensnpcs.util.Util;
|
||||
import net.minecraft.server.v1_4_5.EntityEnderman;
|
||||
import net.minecraft.server.v1_4_5.World;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.craftbukkit.v1_4_5.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_4_5.entity.CraftEnderman;
|
||||
import org.bukkit.entity.Enderman;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.material.MaterialData;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CitizensEndermanNPC extends CitizensMobNPC implements Equipable {
|
||||
public CitizensEndermanNPC(int id, String name) {
|
||||
super(id, name, EntityEndermanNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void equip(Player equipper, ItemStack hand) {
|
||||
if (!hand.getType().isBlock()) {
|
||||
Messaging.sendErrorTr(equipper, Messages.EQUIPMENT_EDITOR_INVALID_BLOCK);
|
||||
return;
|
||||
}
|
||||
|
||||
MaterialData carried = getBukkitEntity().getCarriedMaterial();
|
||||
if (carried.getItemType() == Material.AIR) {
|
||||
if (hand.getType() == Material.AIR) {
|
||||
Messaging.sendErrorTr(equipper, Messages.EQUIPMENT_EDITOR_INVALID_BLOCK);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
equipper.getWorld().dropItemNaturally(getBukkitEntity().getLocation(), carried.toItemStack(1));
|
||||
getBukkitEntity().setCarriedMaterial(hand.getData());
|
||||
}
|
||||
|
||||
ItemStack set = hand.clone();
|
||||
if (set.getType() != Material.AIR) {
|
||||
set.setAmount(1);
|
||||
hand.setAmount(hand.getAmount() - 1);
|
||||
}
|
||||
getTrait(Equipment.class).set(0, set);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enderman getBukkitEntity() {
|
||||
return (Enderman) super.getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EndermanNPC extends CraftEnderman implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EndermanNPC(EntityEndermanNPC entity) {
|
||||
super((CraftServer) Bukkit.getServer(), entity);
|
||||
this.npc = entity.npc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
}
|
||||
|
||||
public static class EntityEndermanNPC extends EntityEnderman implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntityEndermanNPC(World world) {
|
||||
this(world, null);
|
||||
}
|
||||
|
||||
public EntityEndermanNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
if (npc != null) {
|
||||
NMS.clearGoals(goalSelector, targetSelector);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bl() {
|
||||
super.bl();
|
||||
if (npc != null)
|
||||
npc.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bn() {
|
||||
if (npc == null)
|
||||
super.bn();
|
||||
else {
|
||||
NMS.updateAI(this);
|
||||
npc.update();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void c() {
|
||||
if (npc == null)
|
||||
super.c();
|
||||
else {
|
||||
NMS.updateAI(this);
|
||||
npc.update();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collide(net.minecraft.server.v1_4_5.Entity entity) {
|
||||
// this method is called by both the entities involved - cancelling
|
||||
// it will not stop the NPC from moving.
|
||||
super.collide(entity);
|
||||
if (npc != null)
|
||||
Util.callCollisionEvent(npc, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void g(double x, double y, double z) {
|
||||
if (npc == null) {
|
||||
super.g(x, y, z);
|
||||
return;
|
||||
}
|
||||
if (NPCPushEvent.getHandlerList().getRegisteredListeners().length == 0) {
|
||||
if (!npc.data().get(NPC.DEFAULT_PROTECTED_METADATA, true))
|
||||
super.g(x, y, z);
|
||||
return;
|
||||
}
|
||||
Vector vector = new Vector(x, y, z);
|
||||
NPCPushEvent event = Util.callPushEvent(npc, vector);
|
||||
if (!event.isCancelled()) {
|
||||
vector = event.getCollisionVector();
|
||||
super.g(vector.getX(), vector.getY(), vector.getZ());
|
||||
}
|
||||
// when another entity collides, this method is called to push the
|
||||
// NPC so we prevent it from doing anything if the event is
|
||||
// cancelled.
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity getBukkitEntity() {
|
||||
if (bukkitEntity == null && npc != null)
|
||||
bukkitEntity = new EndermanNPC(this);
|
||||
return super.getBukkitEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,147 +0,0 @@
|
||||
package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.Settings.Setting;
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.trait.trait.Equipment;
|
||||
import net.citizensnpcs.editor.Equipable;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.util.Messages;
|
||||
import net.citizensnpcs.util.Messaging;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
import net.citizensnpcs.util.StringHelper;
|
||||
import net.citizensnpcs.util.Util;
|
||||
import net.minecraft.server.v1_4_5.EntityLiving;
|
||||
import net.minecraft.server.v1_4_5.ItemInWorldManager;
|
||||
import net.minecraft.server.v1_4_5.WorldServer;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.craftbukkit.v1_4_5.CraftWorld;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class CitizensHumanNPC extends CitizensNPC implements Equipable {
|
||||
public CitizensHumanNPC(int id, String name) {
|
||||
super(id, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EntityLiving createHandle(final Location loc) {
|
||||
WorldServer ws = ((CraftWorld) loc.getWorld()).getHandle();
|
||||
final EntityHumanNPC handle = new EntityHumanNPC(ws.getServer().getServer(), ws,
|
||||
StringHelper.parseColors(getFullName()), new ItemInWorldManager(ws), this);
|
||||
handle.getBukkitEntity().teleport(loc);
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
boolean removeFromPlayerList = Setting.REMOVE_PLAYERS_FROM_PLAYER_LIST.asBoolean();
|
||||
NMS.addOrRemoveFromPlayerList(getBukkitEntity(),
|
||||
data().get("removefromplayerlist", removeFromPlayerList));
|
||||
}
|
||||
}, 1);
|
||||
handle.getBukkitEntity().setSleepingIgnored(true);
|
||||
return handle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void equip(Player equipper, ItemStack hand) {
|
||||
Equipment trait = getTrait(Equipment.class);
|
||||
int slot = 0;
|
||||
Material type = hand == null ? Material.AIR : hand.getType();
|
||||
// First, determine the slot to edit
|
||||
switch (type) {
|
||||
case SKULL_ITEM:
|
||||
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.sendTr(equipper, Messages.EQUIPMENT_EDITOR_ALL_ITEMS_REMOVED, getName());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Drop any previous equipment on the ground
|
||||
ItemStack equippedItem = trait.get(slot);
|
||||
if (equippedItem != null && equippedItem.getType() != Material.AIR)
|
||||
equipper.getWorld().dropItemNaturally(getBukkitEntity().getLocation(), equippedItem);
|
||||
|
||||
// Now edit the equipment based on the slot
|
||||
if (type != Material.AIR) {
|
||||
// Set the proper slot with one of the item
|
||||
ItemStack clone = hand.clone();
|
||||
clone.setAmount(1);
|
||||
trait.set(slot, clone);
|
||||
|
||||
hand.setAmount(hand.getAmount() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player getBukkitEntity() {
|
||||
if (getHandle() == null)
|
||||
return null;
|
||||
return getHandle().getBukkitEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityHumanNPC getHandle() {
|
||||
return (EntityHumanNPC) mcEntity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
super.setName(name);
|
||||
Location prev = getBukkitEntity().getLocation();
|
||||
despawn();
|
||||
spawn(prev);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
super.update();
|
||||
if (isSpawned() && Util.isLoaded(getBukkitEntity().getLocation())) {
|
||||
if (!getNavigator().isNavigating() && !NMS.inWater(mcEntity))
|
||||
mcEntity.move(0, -0.2, 0);
|
||||
// gravity. also works around an entity.onGround not updating issue
|
||||
// (onGround is normally updated by the client)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,140 +0,0 @@
|
||||
package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
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.NPCHolder;
|
||||
import net.citizensnpcs.trait.Sheared;
|
||||
import net.citizensnpcs.trait.WoolColor;
|
||||
import net.citizensnpcs.util.Messages;
|
||||
import net.citizensnpcs.util.Messaging;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
import net.citizensnpcs.util.Util;
|
||||
import net.minecraft.server.v1_4_5.EntitySheep;
|
||||
import net.minecraft.server.v1_4_5.World;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.craftbukkit.v1_4_5.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_4_5.entity.CraftSheep;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Sheep;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CitizensSheepNPC extends CitizensMobNPC implements Equipable {
|
||||
public CitizensSheepNPC(int id, String name) {
|
||||
super(id, name, EntitySheepNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void equip(Player equipper, ItemStack hand) {
|
||||
if (hand.getType() == Material.SHEARS) {
|
||||
Messaging.sendTr(equipper, getTrait(Sheared.class).toggle() ? Messages.SHEARED_SET
|
||||
: Messages.SHEARED_STOPPED, getName());
|
||||
} else if (hand.getType() == Material.INK_SACK) {
|
||||
if (getBukkitEntity().getColor() == DyeColor.getByData((byte) (15 - hand.getData().getData())))
|
||||
return;
|
||||
|
||||
DyeColor color = DyeColor.getByData((byte) (15 - hand.getData().getData()));
|
||||
getTrait(WoolColor.class).setColor(color);
|
||||
Messaging.sendTr(equipper, Messages.EQUIPMENT_EDITOR_SHEEP_COLOURED, getName(), color.name()
|
||||
.toLowerCase().replace("_", " "));
|
||||
|
||||
hand.setAmount(hand.getAmount() - 1);
|
||||
} else {
|
||||
getTrait(WoolColor.class).setColor(DyeColor.WHITE);
|
||||
Messaging.sendTr(equipper, Messages.EQUIPMENT_EDITOR_SHEEP_COLOURED, getName(), "white");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Sheep getBukkitEntity() {
|
||||
return (Sheep) super.getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EntitySheepNPC extends EntitySheep implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntitySheepNPC(World world) {
|
||||
this(world, null);
|
||||
}
|
||||
|
||||
public EntitySheepNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
if (npc != null) {
|
||||
NMS.clearGoals(goalSelector, targetSelector);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bl() {
|
||||
super.bl();
|
||||
if (npc != null)
|
||||
npc.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collide(net.minecraft.server.v1_4_5.Entity entity) {
|
||||
// this method is called by both the entities involved - cancelling
|
||||
// it will not stop the NPC from moving.
|
||||
super.collide(entity);
|
||||
if (npc != null)
|
||||
Util.callCollisionEvent(npc, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void g(double x, double y, double z) {
|
||||
if (npc == null) {
|
||||
super.g(x, y, z);
|
||||
return;
|
||||
}
|
||||
if (NPCPushEvent.getHandlerList().getRegisteredListeners().length == 0) {
|
||||
if (!npc.data().get(NPC.DEFAULT_PROTECTED_METADATA, true))
|
||||
super.g(x, y, z);
|
||||
return;
|
||||
}
|
||||
Vector vector = new Vector(x, y, z);
|
||||
NPCPushEvent event = Util.callPushEvent(npc, vector);
|
||||
if (!event.isCancelled()) {
|
||||
vector = event.getCollisionVector();
|
||||
super.g(vector.getX(), vector.getY(), vector.getZ());
|
||||
}
|
||||
// when another entity collides, this method is called to push the
|
||||
// NPC so we prevent it from doing anything if the event is
|
||||
// cancelled.
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity getBukkitEntity() {
|
||||
if (bukkitEntity == null && npc != null)
|
||||
bukkitEntity = new SheepNPC(this);
|
||||
return super.getBukkitEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
}
|
||||
|
||||
public static class SheepNPC extends CraftSheep implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public SheepNPC(EntitySheepNPC entity) {
|
||||
super((CraftServer) Bukkit.getServer(), entity);
|
||||
this.npc = entity.npc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.MobEntityController;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
@ -17,10 +17,9 @@ import org.bukkit.entity.Cow;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CitizensCowNPC extends CitizensMobNPC {
|
||||
|
||||
public CitizensCowNPC(int id, String name) {
|
||||
super(id, name, EntityCowNPC.class);
|
||||
public class CowController extends MobEntityController {
|
||||
public CowController() {
|
||||
super(EntityCowNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
@ -2,7 +2,7 @@ package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.MobEntityController;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
@ -18,10 +18,9 @@ import org.bukkit.entity.Creeper;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CitizensCreeperNPC extends CitizensMobNPC {
|
||||
|
||||
public CitizensCreeperNPC(int id, String name) {
|
||||
super(id, name, EntityCreeperNPC.class);
|
||||
public class CreeperController extends MobEntityController {
|
||||
public CreeperController() {
|
||||
super(EntityCreeperNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
@ -2,7 +2,7 @@ package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.MobEntityController;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
@ -17,10 +17,9 @@ import org.bukkit.entity.EnderDragon;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CitizensEnderDragonNPC extends CitizensMobNPC {
|
||||
|
||||
public CitizensEnderDragonNPC(int id, String name) {
|
||||
super(id, name, EntityEnderDragonNPC.class);
|
||||
public class EnderDragonController extends MobEntityController {
|
||||
public EnderDragonController() {
|
||||
super(EntityEnderDragonNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
@ -0,0 +1,130 @@
|
||||
package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.MobEntityController;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
import net.citizensnpcs.util.Util;
|
||||
import net.minecraft.server.v1_4_5.EntityEnderman;
|
||||
import net.minecraft.server.v1_4_5.World;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.v1_4_5.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_4_5.entity.CraftEnderman;
|
||||
import org.bukkit.entity.Enderman;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class EndermanController extends MobEntityController {
|
||||
public EndermanController() {
|
||||
super(EntityEndermanNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enderman getBukkitEntity() {
|
||||
return (Enderman) super.getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EndermanNPC extends CraftEnderman implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EndermanNPC(EntityEndermanNPC entity) {
|
||||
super((CraftServer) Bukkit.getServer(), entity);
|
||||
this.npc = entity.npc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
}
|
||||
|
||||
public static class EntityEndermanNPC extends EntityEnderman implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntityEndermanNPC(World world) {
|
||||
this(world, null);
|
||||
}
|
||||
|
||||
public EntityEndermanNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
if (npc != null) {
|
||||
NMS.clearGoals(goalSelector, targetSelector);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bl() {
|
||||
super.bl();
|
||||
if (npc != null)
|
||||
npc.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bn() {
|
||||
if (npc == null)
|
||||
super.bn();
|
||||
else {
|
||||
NMS.updateAI(this);
|
||||
npc.update();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void c() {
|
||||
if (npc == null)
|
||||
super.c();
|
||||
else {
|
||||
NMS.updateAI(this);
|
||||
npc.update();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collide(net.minecraft.server.v1_4_5.Entity entity) {
|
||||
// this method is called by both the entities involved - cancelling
|
||||
// it will not stop the NPC from moving.
|
||||
super.collide(entity);
|
||||
if (npc != null)
|
||||
Util.callCollisionEvent(npc, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void g(double x, double y, double z) {
|
||||
if (npc == null) {
|
||||
super.g(x, y, z);
|
||||
return;
|
||||
}
|
||||
if (NPCPushEvent.getHandlerList().getRegisteredListeners().length == 0) {
|
||||
if (!npc.data().get(NPC.DEFAULT_PROTECTED_METADATA, true))
|
||||
super.g(x, y, z);
|
||||
return;
|
||||
}
|
||||
Vector vector = new Vector(x, y, z);
|
||||
NPCPushEvent event = Util.callPushEvent(npc, vector);
|
||||
if (!event.isCancelled()) {
|
||||
vector = event.getCollisionVector();
|
||||
super.g(vector.getX(), vector.getY(), vector.getZ());
|
||||
}
|
||||
// when another entity collides, this method is called to push the
|
||||
// NPC so we prevent it from doing anything if the event is
|
||||
// cancelled.
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity getBukkitEntity() {
|
||||
if (bukkitEntity == null && npc != null)
|
||||
bukkitEntity = new EndermanNPC(this);
|
||||
return super.getBukkitEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
}
|
||||
}
|
@ -24,6 +24,7 @@ import net.minecraft.server.v1_4_5.Packet5EntityEquipment;
|
||||
import net.minecraft.server.v1_4_5.World;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_4_5.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_4_5.entity.CraftPlayer;
|
||||
import org.bukkit.metadata.MetadataValue;
|
||||
@ -31,7 +32,9 @@ import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
|
||||
private final Location loadedLocation = new Location(null, 0, 0, 0);
|
||||
private final CitizensNPC npc;
|
||||
|
||||
private final net.minecraft.server.v1_4_5.ItemStack[] previousEquipment = { null, null, null, null, null };
|
||||
|
||||
public EntityHumanNPC(MinecraftServer minecraftServer, World world, String string,
|
||||
@ -125,6 +128,13 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
|
||||
if (npc == null)
|
||||
return;
|
||||
|
||||
if (getBukkitEntity() != null && Util.isLoaded(getBukkitEntity().getLocation(loadedLocation))) {
|
||||
if (!npc.getNavigator().isNavigating() && !NMS.inWater(this))
|
||||
move(0, -0.2, 0);
|
||||
// gravity. also works around an entity.onGround not updating issue
|
||||
// (onGround is normally updated by the client)
|
||||
}
|
||||
|
||||
updateEquipment();
|
||||
if (Math.abs(motX) < EPSILON && Math.abs(motY) < EPSILON && Math.abs(motZ) < EPSILON)
|
||||
motX = motY = motZ = 0;
|
||||
|
@ -2,7 +2,7 @@ package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.MobEntityController;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
@ -17,10 +17,9 @@ import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Ghast;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CitizensGhastNPC extends CitizensMobNPC {
|
||||
|
||||
public CitizensGhastNPC(int id, String name) {
|
||||
super(id, name, EntityGhastNPC.class);
|
||||
public class GhastController extends MobEntityController {
|
||||
public GhastController() {
|
||||
super(EntityGhastNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
@ -2,7 +2,7 @@ package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.MobEntityController;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
@ -17,10 +17,9 @@ import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Giant;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CitizensGiantNPC extends CitizensMobNPC {
|
||||
|
||||
public CitizensGiantNPC(int id, String name) {
|
||||
super(id, name, EntityGiantNPC.class);
|
||||
public class GiantController extends MobEntityController {
|
||||
public GiantController() {
|
||||
super(EntityGiantNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
@ -0,0 +1,41 @@
|
||||
package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.Settings.Setting;
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.AbstractEntityController;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
import net.citizensnpcs.util.StringHelper;
|
||||
import net.minecraft.server.v1_4_5.ItemInWorldManager;
|
||||
import net.minecraft.server.v1_4_5.WorldServer;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_4_5.CraftWorld;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class HumanController extends AbstractEntityController {
|
||||
@Override
|
||||
protected LivingEntity createEntity(final Location at, final NPC npc) {
|
||||
WorldServer ws = ((CraftWorld) at.getWorld()).getHandle();
|
||||
final EntityHumanNPC handle = new EntityHumanNPC(ws.getServer().getServer(), ws,
|
||||
StringHelper.parseColors(npc.getFullName()), new ItemInWorldManager(ws), npc);
|
||||
handle.getBukkitEntity().teleport(at);
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
boolean removeFromPlayerList = Setting.REMOVE_PLAYERS_FROM_PLAYER_LIST.asBoolean();
|
||||
NMS.addOrRemoveFromPlayerList(getBukkitEntity(),
|
||||
npc.data().get("removefromplayerlist", removeFromPlayerList));
|
||||
}
|
||||
}, 1);
|
||||
handle.getBukkitEntity().setSleepingIgnored(true);
|
||||
return handle.getBukkitEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player getBukkitEntity() {
|
||||
return (Player) super.getBukkitEntity();
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.MobEntityController;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
@ -17,10 +17,9 @@ import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.IronGolem;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CitizensIronGolemNPC extends CitizensMobNPC {
|
||||
|
||||
public CitizensIronGolemNPC(int id, String name) {
|
||||
super(id, name, EntityIronGolemNPC.class);
|
||||
public class IronGolemController extends MobEntityController {
|
||||
public IronGolemController() {
|
||||
super(EntityIronGolemNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
@ -2,7 +2,7 @@ package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.MobEntityController;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
@ -17,10 +17,9 @@ import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.MagmaCube;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CitizensMagmaCubeNPC extends CitizensMobNPC {
|
||||
|
||||
public CitizensMagmaCubeNPC(int id, String name) {
|
||||
super(id, name, EntityMagmaCubeNPC.class);
|
||||
public class MagmaCubeController extends MobEntityController {
|
||||
public MagmaCubeController() {
|
||||
super(EntityMagmaCubeNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
@ -2,7 +2,7 @@ package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.MobEntityController;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
@ -17,10 +17,10 @@ import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.MushroomCow;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CitizensMushroomCowNPC extends CitizensMobNPC {
|
||||
public class MushroomCowController extends MobEntityController {
|
||||
|
||||
public CitizensMushroomCowNPC(int id, String name) {
|
||||
super(id, name, EntityMushroomCowNPC.class);
|
||||
public MushroomCowController() {
|
||||
super(EntityMushroomCowNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
@ -2,7 +2,7 @@ package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.MobEntityController;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
@ -17,10 +17,9 @@ import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Ocelot;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CitizensOcelotNPC extends CitizensMobNPC {
|
||||
|
||||
public CitizensOcelotNPC(int id, String name) {
|
||||
super(id, name, EntityOcelotNPC.class);
|
||||
public class OcelotController extends MobEntityController {
|
||||
public OcelotController() {
|
||||
super(EntityOcelotNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
@ -2,13 +2,9 @@ package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.editor.Equipable;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.MobEntityController;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.trait.Saddle;
|
||||
import net.citizensnpcs.util.Messages;
|
||||
import net.citizensnpcs.util.Messaging;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
import net.citizensnpcs.util.Util;
|
||||
import net.minecraft.server.v1_4_5.EntityLightning;
|
||||
@ -16,35 +12,15 @@ import net.minecraft.server.v1_4_5.EntityPig;
|
||||
import net.minecraft.server.v1_4_5.World;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.craftbukkit.v1_4_5.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_4_5.entity.CraftPig;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Pig;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CitizensPigNPC extends CitizensMobNPC implements Equipable {
|
||||
|
||||
public CitizensPigNPC(int id, String name) {
|
||||
super(id, name, EntityPigNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void equip(Player equipper, ItemStack hand) {
|
||||
if (hand.getType() == Material.SADDLE) {
|
||||
if (!getBukkitEntity().hasSaddle()) {
|
||||
getTrait(Saddle.class).toggle();
|
||||
hand.setAmount(0);
|
||||
Messaging.sendTr(equipper, Messages.SADDLED_SET, getName());
|
||||
}
|
||||
} else if (getBukkitEntity().hasSaddle()) {
|
||||
equipper.getWorld().dropItemNaturally(getBukkitEntity().getLocation(),
|
||||
new ItemStack(Material.SADDLE, 1));
|
||||
getTrait(Saddle.class).toggle();
|
||||
Messaging.sendTr(equipper, Messages.SADDLED_STOPPED, getName());
|
||||
}
|
||||
public class PigController extends MobEntityController {
|
||||
public PigController() {
|
||||
super(EntityPigNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
@ -2,7 +2,7 @@ package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.MobEntityController;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
@ -17,10 +17,10 @@ import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.PigZombie;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CitizensPigZombieNPC extends CitizensMobNPC {
|
||||
public class PigZombieController extends MobEntityController {
|
||||
|
||||
public CitizensPigZombieNPC(int id, String name) {
|
||||
super(id, name, EntityPigZombieNPC.class);
|
||||
public PigZombieController() {
|
||||
super(EntityPigZombieNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
110
src/main/java/net/citizensnpcs/npc/entity/SheepController.java
Normal file
110
src/main/java/net/citizensnpcs/npc/entity/SheepController.java
Normal file
@ -0,0 +1,110 @@
|
||||
package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.MobEntityController;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
import net.citizensnpcs.util.Util;
|
||||
import net.minecraft.server.v1_4_5.EntitySheep;
|
||||
import net.minecraft.server.v1_4_5.World;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.v1_4_5.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_4_5.entity.CraftSheep;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Sheep;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class SheepController extends MobEntityController {
|
||||
public SheepController() {
|
||||
super(EntitySheepNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Sheep getBukkitEntity() {
|
||||
return (Sheep) super.getBukkitEntity();
|
||||
}
|
||||
|
||||
public static class EntitySheepNPC extends EntitySheep implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public EntitySheepNPC(World world) {
|
||||
this(world, null);
|
||||
}
|
||||
|
||||
public EntitySheepNPC(World world, NPC npc) {
|
||||
super(world);
|
||||
this.npc = (CitizensNPC) npc;
|
||||
if (npc != null) {
|
||||
NMS.clearGoals(goalSelector, targetSelector);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bl() {
|
||||
super.bl();
|
||||
if (npc != null)
|
||||
npc.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collide(net.minecraft.server.v1_4_5.Entity entity) {
|
||||
// this method is called by both the entities involved - cancelling
|
||||
// it will not stop the NPC from moving.
|
||||
super.collide(entity);
|
||||
if (npc != null)
|
||||
Util.callCollisionEvent(npc, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void g(double x, double y, double z) {
|
||||
if (npc == null) {
|
||||
super.g(x, y, z);
|
||||
return;
|
||||
}
|
||||
if (NPCPushEvent.getHandlerList().getRegisteredListeners().length == 0) {
|
||||
if (!npc.data().get(NPC.DEFAULT_PROTECTED_METADATA, true))
|
||||
super.g(x, y, z);
|
||||
return;
|
||||
}
|
||||
Vector vector = new Vector(x, y, z);
|
||||
NPCPushEvent event = Util.callPushEvent(npc, vector);
|
||||
if (!event.isCancelled()) {
|
||||
vector = event.getCollisionVector();
|
||||
super.g(vector.getX(), vector.getY(), vector.getZ());
|
||||
}
|
||||
// when another entity collides, this method is called to push the
|
||||
// NPC so we prevent it from doing anything if the event is
|
||||
// cancelled.
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity getBukkitEntity() {
|
||||
if (bukkitEntity == null && npc != null)
|
||||
bukkitEntity = new SheepNPC(this);
|
||||
return super.getBukkitEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
}
|
||||
|
||||
public static class SheepNPC extends CraftSheep implements NPCHolder {
|
||||
private final CitizensNPC npc;
|
||||
|
||||
public SheepNPC(EntitySheepNPC entity) {
|
||||
super((CraftServer) Bukkit.getServer(), entity);
|
||||
this.npc = entity.npc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC() {
|
||||
return npc;
|
||||
}
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.MobEntityController;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
@ -17,10 +17,9 @@ import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Silverfish;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CitizensSilverfishNPC extends CitizensMobNPC {
|
||||
|
||||
public CitizensSilverfishNPC(int id, String name) {
|
||||
super(id, name, EntitySilverfishNPC.class);
|
||||
public class SilverfishController extends MobEntityController {
|
||||
public SilverfishController() {
|
||||
super(EntitySilverfishNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
@ -2,7 +2,7 @@ package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.MobEntityController;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
@ -17,10 +17,9 @@ import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Skeleton;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CitizensSkeletonNPC extends CitizensMobNPC {
|
||||
|
||||
public CitizensSkeletonNPC(int id, String name) {
|
||||
super(id, name, EntitySkeletonNPC.class);
|
||||
public class SkeletonController extends MobEntityController {
|
||||
public SkeletonController() {
|
||||
super(EntitySkeletonNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
@ -2,7 +2,7 @@ package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.MobEntityController;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
@ -17,10 +17,10 @@ import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Slime;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CitizensSlimeNPC extends CitizensMobNPC {
|
||||
public class SlimeController extends MobEntityController {
|
||||
|
||||
public CitizensSlimeNPC(int id, String name) {
|
||||
super(id, name, EntitySlimeNPC.class);
|
||||
public SlimeController() {
|
||||
super(EntitySlimeNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
@ -2,7 +2,7 @@ package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.MobEntityController;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
@ -17,10 +17,9 @@ import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Snowman;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CitizensSnowmanNPC extends CitizensMobNPC {
|
||||
|
||||
public CitizensSnowmanNPC(int id, String name) {
|
||||
super(id, name, EntitySnowmanNPC.class);
|
||||
public class SnowmanController extends MobEntityController {
|
||||
public SnowmanController() {
|
||||
super(EntitySnowmanNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
@ -2,7 +2,7 @@ package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.MobEntityController;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
@ -17,9 +17,9 @@ import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Spider;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CitizensSpiderNPC extends CitizensMobNPC {
|
||||
public CitizensSpiderNPC(int id, String name) {
|
||||
super(id, name, EntitySpiderNPC.class);
|
||||
public class SpiderController extends MobEntityController {
|
||||
public SpiderController() {
|
||||
super(EntitySpiderNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
@ -2,7 +2,7 @@ package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.MobEntityController;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
@ -17,10 +17,9 @@ import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Squid;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CitizensSquidNPC extends CitizensMobNPC {
|
||||
|
||||
public CitizensSquidNPC(int id, String name) {
|
||||
super(id, name, EntitySquidNPC.class);
|
||||
public class SquidController extends MobEntityController {
|
||||
public SquidController() {
|
||||
super(EntitySquidNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
@ -2,7 +2,7 @@ package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.MobEntityController;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
@ -18,10 +18,9 @@ import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Villager;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CitizensVillagerNPC extends CitizensMobNPC {
|
||||
|
||||
public CitizensVillagerNPC(int id, String name) {
|
||||
super(id, name, EntityVillagerNPC.class);
|
||||
public class VillagerController extends MobEntityController {
|
||||
public VillagerController() {
|
||||
super(EntityVillagerNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
@ -2,7 +2,7 @@ package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.MobEntityController;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
@ -17,9 +17,9 @@ import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Witch;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CitizensWitchNPC extends CitizensMobNPC {
|
||||
public CitizensWitchNPC(int id, String name) {
|
||||
super(id, name, EntityWitchNPC.class);
|
||||
public class WitchController extends MobEntityController {
|
||||
public WitchController() {
|
||||
super(EntityWitchNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
@ -2,7 +2,7 @@ package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.MobEntityController;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
@ -17,9 +17,9 @@ import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Wither;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CitizensWitherNPC extends CitizensMobNPC {
|
||||
public CitizensWitherNPC(int id, String name) {
|
||||
super(id, name, EntityWitherNPC.class);
|
||||
public class WitherController extends MobEntityController {
|
||||
public WitherController() {
|
||||
super(EntityWitherNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
@ -2,7 +2,7 @@ package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.MobEntityController;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
@ -17,10 +17,9 @@ import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Wolf;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CitizensWolfNPC extends CitizensMobNPC {
|
||||
|
||||
public CitizensWolfNPC(int id, String name) {
|
||||
super(id, name, EntityWolfNPC.class);
|
||||
public class WolfController extends MobEntityController {
|
||||
public WolfController() {
|
||||
super(EntityWolfNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
@ -2,7 +2,7 @@ package net.citizensnpcs.npc.entity;
|
||||
|
||||
import net.citizensnpcs.api.event.NPCPushEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.MobEntityController;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
@ -17,10 +17,9 @@ import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Zombie;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CitizensZombieNPC extends CitizensMobNPC {
|
||||
|
||||
public CitizensZombieNPC(int id, String name) {
|
||||
super(id, name, EntityZombieNPC.class);
|
||||
public class ZombieController extends MobEntityController {
|
||||
public ZombieController() {
|
||||
super(EntityZombieNPC.class);
|
||||
}
|
||||
|
||||
@Override
|
@ -7,31 +7,29 @@ import org.bukkit.Location;
|
||||
|
||||
public class CurrentLocation extends Trait {
|
||||
@Persist(value = "", required = true)
|
||||
private Location loc;
|
||||
private Location location = new Location(null, 0, 0, 0);
|
||||
|
||||
public CurrentLocation() {
|
||||
super("location");
|
||||
}
|
||||
|
||||
public Location getLocation() {
|
||||
if (loc != null && loc.getWorld() == null)
|
||||
return null;
|
||||
return loc;
|
||||
return location.getWorld() == null ? null : location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!npc.isSpawned())
|
||||
return;
|
||||
loc = npc.getBukkitEntity().getLocation();
|
||||
location = npc.getBukkitEntity().getLocation(location);
|
||||
}
|
||||
|
||||
public void setLocation(Location loc) {
|
||||
this.loc = loc;
|
||||
this.location = loc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CurrentLocation{" + loc + "}";
|
||||
return "CurrentLocation{" + location + "}";
|
||||
}
|
||||
}
|
@ -21,7 +21,9 @@ import org.bukkit.entity.Player;
|
||||
public class LookClose extends Trait implements Toggleable, CommandConfigurable {
|
||||
private boolean enabled = Setting.DEFAULT_LOOK_CLOSE.asBoolean();
|
||||
private Player lookingAt;
|
||||
private final Location npcLocation = new Location(null, 0, 0, 0);
|
||||
private double range = Setting.DEFAULT_LOOK_CLOSE_RANGE.asDouble();
|
||||
|
||||
private boolean realisticLooking = Setting.DEFAULT_REALISTIC_LOOKING.asBoolean();
|
||||
|
||||
public LookClose() {
|
||||
@ -41,7 +43,7 @@ public class LookClose extends Trait implements Toggleable, CommandConfigurable
|
||||
|
||||
private void findNewTarget() {
|
||||
List<Entity> nearby = npc.getBukkitEntity().getNearbyEntities(range, range, range);
|
||||
final Location npcLocation = npc.getBukkitEntity().getLocation();
|
||||
npc.getBukkitEntity().getLocation(npcLocation);
|
||||
Collections.sort(nearby, new Comparator<Entity>() {
|
||||
@Override
|
||||
public int compare(Entity o1, Entity o2) {
|
||||
|
@ -50,6 +50,7 @@ public class Messages {
|
||||
public static final String CURRENT_WAYPOINT_PROVIDER = "citizens.waypoints.current-provider";
|
||||
public static final String DATABASE_CONNECTION_FAILED = "citizens.notifications.database-connection-failed";
|
||||
public static final String DELAY_TRIGGER_PROMPT = "citizens.editors.waypoints.triggers.delay.prompt";
|
||||
public static final String ENTITY_TYPE_SET = "citizens.commands.npc.type.set";
|
||||
public static final String EQUIPMENT_EDITOR_ALL_ITEMS_REMOVED = "citizens.editors.equipment.all-items-removed";
|
||||
public static final String EQUIPMENT_EDITOR_BEGIN = "citizens.editors.equipment.begin";
|
||||
public static final String EQUIPMENT_EDITOR_END = "citizens.editors.equipment.end";
|
||||
@ -78,6 +79,7 @@ public class Messages {
|
||||
public static final String INVALID_AGE = "citizens.commands.npc.age.invalid-age";
|
||||
public static final String INVALID_ANCHOR_NAME = "citizens.commands.npc.anchor.invalid-name";
|
||||
public static final String INVALID_ANIMATION = "citizens.editors.waypoints.triggers.animation.invalid-animation";
|
||||
public static final String INVALID_ENTITY_TYPE = "citizens.commands.npc.type.invalid";
|
||||
public static final String INVALID_POSE_NAME = "citizens.commands.npc.pose.invalid-name";
|
||||
public static final String INVALID_PROFESSION = "citizens.commands.npc.profession.invalid-profession";
|
||||
public static final String INVALID_SKELETON_TYPE = "citizens.commands.npc.skeletontype.invalid-type";
|
||||
@ -140,7 +142,6 @@ public class Messages {
|
||||
public static final String REMOVED_FROM_PLAYERLIST = "citizens.commands.npc.playerlist.removed";
|
||||
public static final String SADDLED_SET = "citizens.editors.equipment.saddled-set";
|
||||
public static final String SADDLED_STOPPED = "citizens.editors.equipment.saddled-stopped";
|
||||
public static final String SAVE_METHOD_SET_NOTIFICATION = "citizens.notifications.save-method-set";
|
||||
public static final String SCRIPT_COMPILED = "citizens.commands.script.compiled";
|
||||
public static final String SCRIPT_COMPILING = "citizens.commands.script.compiling";
|
||||
public static final String SCRIPT_FILE_MISSING = "citizens.commands.script.file-missing";
|
||||
|
@ -14,8 +14,8 @@ public class StringHelper {
|
||||
|
||||
public static String capitalize(Object string) {
|
||||
String capitalize = string.toString();
|
||||
return capitalize.replaceFirst(String.valueOf(capitalize.charAt(0)),
|
||||
String.valueOf(Character.toUpperCase(capitalize.charAt(0))));
|
||||
return capitalize.length() == 0 ? "" : Character.toUpperCase(capitalize.charAt(0))
|
||||
+ capitalize.substring(1, capitalize.length());
|
||||
}
|
||||
|
||||
public static int getLevenshteinDistance(String s, String t) {
|
||||
|
@ -27,6 +27,10 @@ public class Util {
|
||||
private Util() {
|
||||
}
|
||||
|
||||
private static final Location atLocation = new Location(null, 0, 0, 0);
|
||||
|
||||
private static final Location fromLocation = new Location(null, 0, 0, 0);
|
||||
|
||||
private static Class<?> RNG_CLASS = null;
|
||||
|
||||
public static void assumePose(org.bukkit.entity.Entity entity, float yaw, float pitch) {
|
||||
@ -49,11 +53,16 @@ public class Util {
|
||||
public static void faceEntity(Entity from, Entity at) {
|
||||
if (from.getWorld() != at.getWorld())
|
||||
return;
|
||||
Location loc = from.getLocation();
|
||||
|
||||
double xDiff = at.getLocation().getX() - loc.getX();
|
||||
double yDiff = at.getLocation().getY() - loc.getY();
|
||||
double zDiff = at.getLocation().getZ() - loc.getZ();
|
||||
double xDiff, yDiff, zDiff;
|
||||
synchronized (fromLocation) {
|
||||
from.getLocation(fromLocation);
|
||||
synchronized (atLocation) {
|
||||
at.getLocation(atLocation);
|
||||
xDiff = atLocation.getX() - fromLocation.getX();
|
||||
yDiff = atLocation.getY() - fromLocation.getY();
|
||||
zDiff = atLocation.getZ() - fromLocation.getZ();
|
||||
}
|
||||
}
|
||||
|
||||
double distanceXZ = Math.sqrt(xDiff * xDiff + zDiff * zDiff);
|
||||
double distanceY = Math.sqrt(distanceXZ * distanceXZ + yDiff * yDiff);
|
||||
|
@ -78,6 +78,8 @@ citizens.commands.npc.speed.modifier-above-limit=Speed is above the limit.
|
||||
citizens.commands.npc.speed.set=NPC speed modifier set to [[{0}]].
|
||||
citizens.commands.npc.tp.teleported=You teleported to [[{0}]].
|
||||
citizens.commands.npc.tphere.teleported=[[{0}]] was teleported to your location.
|
||||
citizens.commands.npc.type.set=[[{0}]]''s type set to [[{1}]].
|
||||
citizens.commands.npc.type.invalid=[[{0}]] is not a valid type.
|
||||
citizens.commands.npc.vulnerable.set=[[{0}]] is now vulnerable.
|
||||
citizens.commands.npc.vulnerable.stopped=[[{0}]] is no longer vulnerable.
|
||||
citizens.commands.page-missing=The page [[{0}]] does not exist.
|
||||
@ -190,7 +192,6 @@ citizens.notifications.npc-not-found=No NPC could be found.
|
||||
citizens.notifications.npcs-loaded=Loaded {0} NPCs.
|
||||
citizens.notifications.reloaded=Citizens reloaded.
|
||||
citizens.notifications.reloading=Reloading Citizens...
|
||||
citizens.notifications.save-method-set=Save method set to {0}.
|
||||
citizens.notifications.saved=Citizens saved.
|
||||
citizens.notifications.saving=Saving Citizens...
|
||||
citizens.notifications.skipping-broken-trait=Skipped broken or missing trait {0} while loading ID {1}. Has the name changed?
|
||||
|
Loading…
Reference in New Issue
Block a user