mirror of
https://github.com/CitizensDev/Citizens2.git
synced 2025-01-01 14:08:08 +01:00
Format and potential fix for incorrect chunk unload logic
This commit is contained in:
parent
c053fa9871
commit
dc4fb0a33e
@ -62,8 +62,8 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
|
|||||||
private CitizensNPCRegistry npcRegistry;
|
private CitizensNPCRegistry npcRegistry;
|
||||||
private NPCDataStore saves;
|
private NPCDataStore saves;
|
||||||
private NPCSelector selector;
|
private NPCSelector selector;
|
||||||
private CitizensTraitFactory traitFactory;
|
|
||||||
private CitizensSpeechFactory speechFactory;
|
private CitizensSpeechFactory speechFactory;
|
||||||
|
private CitizensTraitFactory traitFactory;
|
||||||
|
|
||||||
private void despawnNPCs() {
|
private void despawnNPCs() {
|
||||||
Iterator<NPC> itr = npcRegistry.iterator();
|
Iterator<NPC> itr = npcRegistry.iterator();
|
||||||
@ -131,13 +131,13 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TraitFactory getTraitFactory() {
|
public SpeechFactory getSpeechFactory() {
|
||||||
return traitFactory;
|
return speechFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SpeechFactory getSpeechFactory() {
|
public TraitFactory getTraitFactory() {
|
||||||
return speechFactory;
|
return traitFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -69,21 +69,13 @@ public class EventListen implements Listener {
|
|||||||
/*
|
/*
|
||||||
* Chunk events
|
* Chunk events
|
||||||
*/
|
*/
|
||||||
@EventHandler(ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
public void onChunkLoad(ChunkLoadEvent event) {
|
public void onChunkLoad(ChunkLoadEvent event) {
|
||||||
ChunkCoord coord = toCoord(event.getChunk());
|
ChunkCoord coord = toCoord(event.getChunk());
|
||||||
List<Integer> ids = toRespawn.get(coord);
|
respawnAllFromCoord(coord);
|
||||||
for (int i = 0; i < ids.size(); i++) {
|
|
||||||
int id = ids.get(i);
|
|
||||||
boolean success = spawn(id);
|
|
||||||
if (!success)
|
|
||||||
continue;
|
|
||||||
ids.remove(i);
|
|
||||||
Messaging.debug("Spawned", id, "due to chunk load at [" + coord.x + "," + coord.z + "]");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
public void onChunkUnload(ChunkUnloadEvent event) {
|
public void onChunkUnload(ChunkUnloadEvent event) {
|
||||||
ChunkCoord coord = toCoord(event.getChunk());
|
ChunkCoord coord = toCoord(event.getChunk());
|
||||||
Location location = new Location(null, 0, 0, 0);
|
Location location = new Location(null, 0, 0, 0);
|
||||||
@ -93,13 +85,15 @@ public class EventListen implements Listener {
|
|||||||
location = npc.getBukkitEntity().getLocation(location);
|
location = npc.getBukkitEntity().getLocation(location);
|
||||||
boolean sameChunkCoordinates = coord.z == location.getBlockZ() >> 4 && coord.x == location.getBlockX() >> 4;
|
boolean sameChunkCoordinates = coord.z == location.getBlockZ() >> 4 && coord.x == location.getBlockX() >> 4;
|
||||||
if (sameChunkCoordinates && event.getWorld().equals(location.getWorld())) {
|
if (sameChunkCoordinates && event.getWorld().equals(location.getWorld())) {
|
||||||
npc.despawn(DespawnReason.CHUNK_UNLOAD);
|
if (!npc.despawn(DespawnReason.CHUNK_UNLOAD)) {
|
||||||
if (event.getChunk().isLoaded()) {
|
event.setCancelled(true);
|
||||||
toRespawn.removeAll(coord);
|
Messaging.debug("Cancelled chunk unload at [" + coord.x + "," + coord.z + "]");
|
||||||
|
respawnAllFromCoord(coord);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
toRespawn.put(coord, npc.getId());
|
toRespawn.put(coord, npc.getId());
|
||||||
Messaging.debug("Despawned", npc.getId(), "due to chunk unload at [" + coord.x + "," + coord.z + "]");
|
Messaging.debug("Despawned id ", npc.getId(), "due to chunk unload at [" + coord.x + "," + coord.z
|
||||||
|
+ "]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -189,10 +183,6 @@ public class EventListen implements Listener {
|
|||||||
// undesirable as player NPCs are not real players and confuse plugins.
|
// undesirable as player NPCs are not real players and confuse plugins.
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Player events
|
|
||||||
*/
|
|
||||||
|
|
||||||
@EventHandler(ignoreCancelled = true)
|
@EventHandler(ignoreCancelled = true)
|
||||||
public void onPlayerCreateNPC(PlayerCreateNPCEvent event) {
|
public void onPlayerCreateNPC(PlayerCreateNPCEvent event) {
|
||||||
if (event.getCreator().hasPermission("citizens.admin.avoid-limits"))
|
if (event.getCreator().hasPermission("citizens.admin.avoid-limits"))
|
||||||
@ -219,6 +209,10 @@ public class EventListen implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Player events
|
||||||
|
*/
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
|
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
|
||||||
NPC npc = npcRegistry.getNPC(event.getRightClicked());
|
NPC npc = npcRegistry.getNPC(event.getRightClicked());
|
||||||
@ -232,7 +226,7 @@ public class EventListen implements Listener {
|
|||||||
Bukkit.getPluginManager().callEvent(rightClickEvent);
|
Bukkit.getPluginManager().callEvent(rightClickEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||||
Editor.leave(event.getPlayer());
|
Editor.leave(event.getPlayer());
|
||||||
}
|
}
|
||||||
@ -255,17 +249,34 @@ public class EventListen implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
public void onWorldUnload(WorldUnloadEvent event) {
|
public void onWorldUnload(WorldUnloadEvent event) {
|
||||||
for (NPC npc : npcRegistry) {
|
for (NPC npc : npcRegistry) {
|
||||||
if (!npc.isSpawned() || !npc.getBukkitEntity().getWorld().equals(event.getWorld()))
|
if (!npc.isSpawned() || !npc.getBukkitEntity().getWorld().equals(event.getWorld()))
|
||||||
continue;
|
continue;
|
||||||
storeForRespawn(npc);
|
storeForRespawn(npc);
|
||||||
npc.despawn();
|
npc.despawn(DespawnReason.WORLD_UNLOAD);
|
||||||
|
if (event.isCancelled())
|
||||||
|
return;
|
||||||
Messaging.debug("Despawned", npc.getId() + "due to world unload at", event.getWorld().getName());
|
Messaging.debug("Despawned", npc.getId() + "due to world unload at", event.getWorld().getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void respawnAllFromCoord(ChunkCoord coord) {
|
||||||
|
List<Integer> ids = toRespawn.get(coord);
|
||||||
|
for (int i = 0; i < ids.size(); i++) {
|
||||||
|
int id = ids.get(i);
|
||||||
|
boolean success = spawn(id);
|
||||||
|
if (!success) {
|
||||||
|
Messaging.debug("Couldn't respawn id " + id + " during chunk event at [" + coord.x + "," + coord.z
|
||||||
|
+ "]");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ids.remove(i);
|
||||||
|
Messaging.debug("Spawned id ", id, "due to chunk event at [" + coord.x + "," + coord.z + "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private boolean spawn(int id) {
|
private boolean spawn(int id) {
|
||||||
NPC npc = npcRegistry.getById(id);
|
NPC npc = npcRegistry.getById(id);
|
||||||
if (npc == null)
|
if (npc == null)
|
||||||
|
@ -28,6 +28,27 @@ public class NPCDataStore {
|
|||||||
root = saves;
|
root = saves;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addPlotters(Graph graph) {
|
||||||
|
graph.addPlotter(new Plotter("Database") {
|
||||||
|
@Override
|
||||||
|
public int getValue() {
|
||||||
|
return root instanceof DatabaseStorage ? 1 : 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
graph.addPlotter(new Plotter("YAML") {
|
||||||
|
@Override
|
||||||
|
public int getValue() {
|
||||||
|
return root instanceof YamlStorage ? 1 : 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
graph.addPlotter(new Plotter("NBT") {
|
||||||
|
@Override
|
||||||
|
public int getValue() {
|
||||||
|
return root instanceof NBTStorage ? 1 : 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public void loadInto(CitizensNPCRegistry registry) {
|
public void loadInto(CitizensNPCRegistry registry) {
|
||||||
int created = 0;
|
int created = 0;
|
||||||
for (DataKey key : root.getKey("npc").getIntegerSubKeys()) {
|
for (DataKey key : root.getKey("npc").getIntegerSubKeys()) {
|
||||||
@ -81,16 +102,14 @@ public class NPCDataStore {
|
|||||||
String type = Setting.STORAGE_TYPE.asString();
|
String type = Setting.STORAGE_TYPE.asString();
|
||||||
if (type.equalsIgnoreCase("db") || type.equalsIgnoreCase("database")) {
|
if (type.equalsIgnoreCase("db") || type.equalsIgnoreCase("database")) {
|
||||||
try {
|
try {
|
||||||
saves = new DatabaseStorage(Setting.DATABASE_DRIVER.asString(),
|
saves = new DatabaseStorage(Setting.DATABASE_DRIVER.asString(), Setting.DATABASE_URL.asString(),
|
||||||
Setting.DATABASE_URL.asString(), Setting.DATABASE_USERNAME.asString(),
|
Setting.DATABASE_USERNAME.asString(), Setting.DATABASE_PASSWORD.asString());
|
||||||
Setting.DATABASE_PASSWORD.asString());
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Messaging.logTr(Messages.DATABASE_CONNECTION_FAILED);
|
Messaging.logTr(Messages.DATABASE_CONNECTION_FAILED);
|
||||||
}
|
}
|
||||||
} else if (type.equalsIgnoreCase("nbt")) {
|
} else if (type.equalsIgnoreCase("nbt")) {
|
||||||
saves = new NBTStorage(folder + File.separator + Setting.STORAGE_FILE.asString(),
|
saves = new NBTStorage(folder + File.separator + Setting.STORAGE_FILE.asString(), "Citizens NPC Storage");
|
||||||
"Citizens NPC Storage");
|
|
||||||
}
|
}
|
||||||
if (saves == null)
|
if (saves == null)
|
||||||
saves = new YamlStorage(new File(folder, Setting.STORAGE_FILE.asString()), "Citizens NPC Storage");
|
saves = new YamlStorage(new File(folder, Setting.STORAGE_FILE.asString()), "Citizens NPC Storage");
|
||||||
@ -98,25 +117,4 @@ public class NPCDataStore {
|
|||||||
return null;
|
return null;
|
||||||
return new NPCDataStore(saves);
|
return new NPCDataStore(saves);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addPlotters(Graph graph) {
|
|
||||||
graph.addPlotter(new Plotter("Database") {
|
|
||||||
@Override
|
|
||||||
public int getValue() {
|
|
||||||
return root instanceof DatabaseStorage ? 1 : 0;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
graph.addPlotter(new Plotter("YAML") {
|
|
||||||
@Override
|
|
||||||
public int getValue() {
|
|
||||||
return root instanceof YamlStorage ? 1 : 0;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
graph.addPlotter(new Plotter("NBT") {
|
|
||||||
@Override
|
|
||||||
public int getValue() {
|
|
||||||
return root instanceof NBTStorage ? 1 : 0;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -43,14 +43,16 @@ public class Settings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public enum Setting {
|
public enum Setting {
|
||||||
CHAT_FORMAT("npc.chat.format.no-targets", "[<npc>]: <text>"),
|
|
||||||
CHAT_FORMAT_TO_TARGET("npc.chat.format.to-target", "[<npc>] -> You: <text>"),
|
|
||||||
CHAT_FORMAT_TO_BYSTANDERS("npc.chat.format.with-target-to-bystanders", "[<npc>] -> [<target>]: <text>"),
|
|
||||||
CHAT_FORMAT_WITH_TARGETS_TO_BYSTANDERS("npc.chat.format.with-targets-to-bystanders", "[<npc>] -> [<targets>]: <text>"),
|
|
||||||
CHAT_RANGE("npc.chat.options.range", 5),
|
|
||||||
CHAT_BYSTANDERS_HEAR_TARGETED_CHAT("npc.chat.options.bystanders-hear-targeted-chat", true),
|
CHAT_BYSTANDERS_HEAR_TARGETED_CHAT("npc.chat.options.bystanders-hear-targeted-chat", true),
|
||||||
|
CHAT_FORMAT("npc.chat.format.no-targets", "[<npc>]: <text>"),
|
||||||
|
CHAT_FORMAT_TO_BYSTANDERS("npc.chat.format.with-target-to-bystanders", "[<npc>] -> [<target>]: <text>"),
|
||||||
|
CHAT_FORMAT_TO_TARGET("npc.chat.format.to-target", "[<npc>] -> You: <text>"),
|
||||||
|
CHAT_FORMAT_WITH_TARGETS_TO_BYSTANDERS("npc.chat.format.with-targets-to-bystanders",
|
||||||
|
"[<npc>] -> [<targets>]: <text>"),
|
||||||
CHAT_MAX_NUMBER_OF_TARGETS("npc.chat.options.max-number-of-targets-to-show", 2),
|
CHAT_MAX_NUMBER_OF_TARGETS("npc.chat.options.max-number-of-targets-to-show", 2),
|
||||||
CHAT_MULTIPLE_TARGETS_FORMAT("npc.chat.options.multiple-targets-format", "<target>|, <target>| & <target>| & others"),
|
CHAT_MULTIPLE_TARGETS_FORMAT("npc.chat.options.multiple-targets-format",
|
||||||
|
"<target>|, <target>| & <target>| & others"),
|
||||||
|
CHAT_RANGE("npc.chat.options.range", 5),
|
||||||
DATABASE_DRIVER("storage.database.driver", ""),
|
DATABASE_DRIVER("storage.database.driver", ""),
|
||||||
DATABASE_PASSWORD("storage.database.password", ""),
|
DATABASE_PASSWORD("storage.database.password", ""),
|
||||||
DATABASE_URL("storage.database.url", ""),
|
DATABASE_URL("storage.database.url", ""),
|
||||||
|
@ -215,7 +215,7 @@ public class CommandContext {
|
|||||||
location = ((BlockCommandSender) sender).getBlock().getLocation();
|
location = ((BlockCommandSender) sender).getBlock().getLocation();
|
||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] getSlice(int index) {
|
public String[] getSlice(int index) {
|
||||||
String[] slice = new String[args.length - index];
|
String[] slice = new String[args.length - index];
|
||||||
System.arraycopy(args, index, slice, 0, args.length - index);
|
System.arraycopy(args, index, slice, 0, args.length - index);
|
||||||
|
@ -35,8 +35,7 @@ import com.google.common.collect.Lists;
|
|||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
public class CommandManager {
|
public class CommandManager {
|
||||||
private final Map<Class<? extends Annotation>, CommandAnnotationProcessor> annotationProcessors = Maps
|
private final Map<Class<? extends Annotation>, CommandAnnotationProcessor> annotationProcessors = Maps.newHashMap();
|
||||||
.newHashMap();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mapping of commands (including aliases) with a description. Root commands
|
* Mapping of commands (including aliases) with a description. Root commands
|
||||||
@ -77,8 +76,8 @@ public class CommandManager {
|
|||||||
* @throws CommandException
|
* @throws CommandException
|
||||||
* Any exceptions caused from execution of the command
|
* Any exceptions caused from execution of the command
|
||||||
*/
|
*/
|
||||||
public void execute(org.bukkit.command.Command command, String[] args, CommandSender sender,
|
public void execute(org.bukkit.command.Command command, String[] args, CommandSender sender, Object... methodArgs)
|
||||||
Object... methodArgs) throws CommandException {
|
throws CommandException {
|
||||||
// must put command into split.
|
// must put command into split.
|
||||||
String[] newArgs = new String[args.length + 1];
|
String[] newArgs = new String[args.length + 1];
|
||||||
System.arraycopy(args, 0, newArgs, 1, args.length);
|
System.arraycopy(args, 0, newArgs, 1, args.length);
|
||||||
@ -90,8 +89,7 @@ public class CommandManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to execute a command.
|
// Attempt to execute a command.
|
||||||
private void executeMethod(String[] args, CommandSender sender, Object[] methodArgs)
|
private void executeMethod(String[] args, CommandSender sender, Object[] methodArgs) throws CommandException {
|
||||||
throws CommandException {
|
|
||||||
String cmdName = args[0];
|
String cmdName = args[0];
|
||||||
String modifier = args.length > 1 ? args[1] : "";
|
String modifier = args.length > 1 ? args[1] : "";
|
||||||
|
|
||||||
@ -288,8 +286,7 @@ public class CommandManager {
|
|||||||
// Returns whether a player has access to a command.
|
// Returns whether a player has access to a command.
|
||||||
private boolean hasPermission(Method method, CommandSender sender) {
|
private boolean hasPermission(Method method, CommandSender sender) {
|
||||||
Command cmd = method.getAnnotation(Command.class);
|
Command cmd = method.getAnnotation(Command.class);
|
||||||
if (cmd.permission().isEmpty() || hasPermission(sender, cmd.permission())
|
if (cmd.permission().isEmpty() || hasPermission(sender, cmd.permission()) || hasPermission(sender, "admin"))
|
||||||
|| hasPermission(sender, "admin"))
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -64,8 +64,8 @@ public class RequirementsProcessor implements CommandAnnotationProcessor {
|
|||||||
|
|
||||||
EntityType type = npc.getTrait(MobType.class).getType();
|
EntityType type = npc.getTrait(MobType.class).getType();
|
||||||
if (!types.contains(type)) {
|
if (!types.contains(type)) {
|
||||||
throw new RequirementMissingException(Messaging.tr(
|
throw new RequirementMissingException(Messaging.tr(Messages.COMMAND_REQUIREMENTS_INVALID_MOB_TYPE,
|
||||||
Messages.COMMAND_REQUIREMENTS_INVALID_MOB_TYPE, type.getName()));
|
type.getName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,10 +23,8 @@ public class AdminCommands {
|
|||||||
|
|
||||||
@Command(aliases = { "citizens" }, desc = "Show basic plugin information", max = 0, permission = "admin")
|
@Command(aliases = { "citizens" }, desc = "Show basic plugin information", max = 0, permission = "admin")
|
||||||
public void citizens(CommandContext args, CommandSender sender, NPC npc) {
|
public void citizens(CommandContext args, CommandSender sender, NPC npc) {
|
||||||
Messaging.send(
|
Messaging.send(sender,
|
||||||
sender,
|
" " + StringHelper.wrapHeader("<e>Citizens v" + plugin.getDescription().getVersion()));
|
||||||
" "
|
|
||||||
+ StringHelper.wrapHeader("<e>Citizens v" + plugin.getDescription().getVersion()));
|
|
||||||
Messaging.send(sender, " <7>-- <c>Written by fullwall and aPunch");
|
Messaging.send(sender, " <7>-- <c>Written by fullwall and aPunch");
|
||||||
Messaging.send(sender, " <7>-- <c>Source Code: http://github.com/CitizensDev");
|
Messaging.send(sender, " <7>-- <c>Source Code: http://github.com/CitizensDev");
|
||||||
Messaging.send(sender, " <7>-- <c>Website: " + plugin.getDescription().getWebsite());
|
Messaging.send(sender, " <7>-- <c>Website: " + plugin.getDescription().getWebsite());
|
||||||
|
@ -23,8 +23,8 @@ public class EditorCommands {
|
|||||||
min = 1,
|
min = 1,
|
||||||
max = 1,
|
max = 1,
|
||||||
permission = "npc.edit.equip")
|
permission = "npc.edit.equip")
|
||||||
@Requirements(selected = true, ownership = true, types = { EntityType.ENDERMAN, EntityType.PLAYER,
|
@Requirements(selected = true, ownership = true, types = { EntityType.ENDERMAN, EntityType.PLAYER, EntityType.PIG,
|
||||||
EntityType.PIG, EntityType.SHEEP })
|
EntityType.SHEEP })
|
||||||
public void equip(CommandContext args, Player player, NPC npc) {
|
public void equip(CommandContext args, Player player, NPC npc) {
|
||||||
Editor.enterOrLeave(player, new EquipmentEditor(player, npc));
|
Editor.enterOrLeave(player, new EquipmentEditor(player, npc));
|
||||||
}
|
}
|
||||||
@ -37,8 +37,8 @@ public class EditorCommands {
|
|||||||
min = 1,
|
min = 1,
|
||||||
max = 1,
|
max = 1,
|
||||||
permission = "npc.edit.path")
|
permission = "npc.edit.path")
|
||||||
@Requirements(selected = true, ownership = true, excludedTypes = { EntityType.BLAZE,
|
@Requirements(selected = true, ownership = true, excludedTypes = { EntityType.BLAZE, EntityType.ENDER_DRAGON,
|
||||||
EntityType.ENDER_DRAGON, EntityType.GHAST, EntityType.BAT, EntityType.WITHER, EntityType.SQUID })
|
EntityType.GHAST, EntityType.BAT, EntityType.WITHER, EntityType.SQUID })
|
||||||
public void path(CommandContext args, Player player, NPC npc) {
|
public void path(CommandContext args, Player player, NPC npc) {
|
||||||
Editor.enterOrLeave(player, npc.getTrait(Waypoints.class).getEditor(player));
|
Editor.enterOrLeave(player, npc.getTrait(Waypoints.class).getEditor(player));
|
||||||
}
|
}
|
||||||
|
@ -112,8 +112,7 @@ public class HelpCommands {
|
|||||||
throw new CommandException(Messages.COMMAND_PAGE_MISSING, page);
|
throw new CommandException(Messages.COMMAND_PAGE_MISSING, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendSpecificHelp(CommandSender sender, String rootCommand, String modifier)
|
private void sendSpecificHelp(CommandSender sender, String rootCommand, String modifier) throws CommandException {
|
||||||
throws CommandException {
|
|
||||||
CommandInfo info = plugin.getCommandInfo(rootCommand, modifier);
|
CommandInfo info = plugin.getCommandInfo(rootCommand, modifier);
|
||||||
if (info == null)
|
if (info == null)
|
||||||
throw new CommandException(Messages.COMMAND_MISSING, rootCommand + " " + modifier);
|
throw new CommandException(Messages.COMMAND_MISSING, rootCommand + " " + modifier);
|
||||||
@ -165,7 +164,7 @@ public class HelpCommands {
|
|||||||
private static final String COMMAND_FORMAT = "<7>/<c>%s%s <7>- <e>%s";
|
private static final String COMMAND_FORMAT = "<7>/<c>%s%s <7>- <e>%s";
|
||||||
|
|
||||||
private static final String format(Command command) {
|
private static final String format(Command command) {
|
||||||
return String.format(COMMAND_FORMAT, command.aliases()[0], (command.usage().isEmpty() ? "" : " "
|
return String.format(COMMAND_FORMAT, command.aliases()[0],
|
||||||
+ command.usage()), Messaging.tryTranslate(command.desc()));
|
(command.usage().isEmpty() ? "" : " " + command.usage()), Messaging.tryTranslate(command.desc()));
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -30,8 +30,7 @@ public class ScriptCommands {
|
|||||||
min = 2,
|
min = 2,
|
||||||
max = 2,
|
max = 2,
|
||||||
permission = "script.compile")
|
permission = "script.compile")
|
||||||
public void runScript(final CommandContext args, final CommandSender sender, NPC npc)
|
public void runScript(final CommandContext args, final CommandSender sender, NPC npc) throws CommandException {
|
||||||
throws CommandException {
|
|
||||||
File file = new File(CitizensAPI.getScriptFolder(), args.getString(1));
|
File file = new File(CitizensAPI.getScriptFolder(), args.getString(1));
|
||||||
if (!file.exists())
|
if (!file.exists())
|
||||||
throw new CommandException(Messages.SCRIPT_FILE_MISSING, args.getString(1));
|
throw new CommandException(Messages.SCRIPT_FILE_MISSING, args.getString(1));
|
||||||
|
@ -55,8 +55,8 @@ public class SelectionPrompt extends NumericPrompt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void start(NPCSelector selector, Player player, List<NPC> possible) {
|
public static void start(NPCSelector selector, Player player, List<NPC> possible) {
|
||||||
final Conversation conversation = new ConversationFactory(CitizensAPI.getPlugin())
|
final Conversation conversation = new ConversationFactory(CitizensAPI.getPlugin()).withLocalEcho(false)
|
||||||
.withLocalEcho(false).withEscapeSequence("exit").withModality(false)
|
.withEscapeSequence("exit").withModality(false)
|
||||||
.withFirstPrompt(new SelectionPrompt(selector, possible)).buildConversation(player);
|
.withFirstPrompt(new SelectionPrompt(selector, possible)).buildConversation(player);
|
||||||
conversation.begin();
|
conversation.begin();
|
||||||
}
|
}
|
||||||
|
@ -24,13 +24,8 @@ import com.google.common.collect.Lists;
|
|||||||
@Requirements(selected = true, ownership = true)
|
@Requirements(selected = true, ownership = true)
|
||||||
public class TraitCommands {
|
public class TraitCommands {
|
||||||
|
|
||||||
@Command(
|
@Command(aliases = { "trait", "tr" }, usage = "add [trait name]...", desc = "Adds traits to the NPC", modifiers = {
|
||||||
aliases = { "trait", "tr" },
|
"add", "a" }, min = 1, permission = "npc.trait")
|
||||||
usage = "add [trait name]...",
|
|
||||||
desc = "Adds traits to the NPC",
|
|
||||||
modifiers = { "add", "a" },
|
|
||||||
min = 1,
|
|
||||||
permission = "npc.trait")
|
|
||||||
public void add(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
public void add(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||||
List<String> added = Lists.newArrayList();
|
List<String> added = Lists.newArrayList();
|
||||||
List<String> failed = Lists.newArrayList();
|
List<String> failed = Lists.newArrayList();
|
||||||
|
@ -26,8 +26,7 @@ public class WaypointCommands {
|
|||||||
min = 1,
|
min = 1,
|
||||||
max = 1,
|
max = 1,
|
||||||
permission = "waypoints.disableteleport")
|
permission = "waypoints.disableteleport")
|
||||||
public void disableTeleporting(CommandContext args, CommandSender sender, NPC npc)
|
public void disableTeleporting(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||||
throws CommandException {
|
|
||||||
npc.getNavigator().getDefaultParameters().stuckAction(null);
|
npc.getNavigator().getDefaultParameters().stuckAction(null);
|
||||||
Messaging.sendTr(sender, Messages.WAYPOINT_TELEPORTING_DISABLED);
|
Messaging.sendTr(sender, Messages.WAYPOINT_TELEPORTING_DISABLED);
|
||||||
}
|
}
|
||||||
@ -47,8 +46,7 @@ public class WaypointCommands {
|
|||||||
if (args.hasFlag('a')) {
|
if (args.hasFlag('a')) {
|
||||||
waypoints.describeProviders(sender);
|
waypoints.describeProviders(sender);
|
||||||
} else
|
} else
|
||||||
Messaging.sendTr(sender, Messages.CURRENT_WAYPOINT_PROVIDER,
|
Messaging.sendTr(sender, Messages.CURRENT_WAYPOINT_PROVIDER, waypoints.getCurrentProviderName());
|
||||||
waypoints.getCurrentProviderName());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
boolean success = waypoints.setWaypointProvider(args.getString(1));
|
boolean success = waypoints.setWaypointProvider(args.getString(1));
|
||||||
|
@ -27,8 +27,7 @@ public class EndermanEquipper implements Equipper {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
equipper.getWorld()
|
equipper.getWorld().dropItemNaturally(npc.getBukkitEntity().getLocation(), carried.toItemStack(1));
|
||||||
.dropItemNaturally(npc.getBukkitEntity().getLocation(), carried.toItemStack(1));
|
|
||||||
((Enderman) npc.getBukkitEntity()).setCarriedMaterial(hand.getData());
|
((Enderman) npc.getBukkitEntity()).setCarriedMaterial(hand.getData());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,8 +56,7 @@ public class GenericEquipper implements Equipper {
|
|||||||
case AIR:
|
case AIR:
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
if (trait.get(i) != null && trait.get(i).getType() != Material.AIR) {
|
if (trait.get(i) != null && trait.get(i).getType() != Material.AIR) {
|
||||||
equipper.getWorld().dropItemNaturally(toEquip.getBukkitEntity().getLocation(),
|
equipper.getWorld().dropItemNaturally(toEquip.getBukkitEntity().getLocation(), trait.get(i));
|
||||||
trait.get(i));
|
|
||||||
trait.set(i, null);
|
trait.set(i, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,8 +26,8 @@ public class SheepEquipper implements Equipper {
|
|||||||
|
|
||||||
DyeColor color = DyeColor.getByData((byte) (15 - hand.getData().getData()));
|
DyeColor color = DyeColor.getByData((byte) (15 - hand.getData().getData()));
|
||||||
toEquip.getTrait(WoolColor.class).setColor(color);
|
toEquip.getTrait(WoolColor.class).setColor(color);
|
||||||
Messaging.sendTr(equipper, Messages.EQUIPMENT_EDITOR_SHEEP_COLOURED, toEquip.getName(), color
|
Messaging.sendTr(equipper, Messages.EQUIPMENT_EDITOR_SHEEP_COLOURED, toEquip.getName(), color.name()
|
||||||
.name().toLowerCase().replace("_", " "));
|
.toLowerCase().replace("_", " "));
|
||||||
|
|
||||||
hand.setAmount(hand.getAmount() - 1);
|
hand.setAmount(hand.getAmount() - 1);
|
||||||
} else {
|
} else {
|
||||||
|
@ -58,8 +58,7 @@ public class CitizensNPC extends AbstractNPC {
|
|||||||
event.setCancelled(Setting.KEEP_CHUNKS_LOADED.asBoolean());
|
event.setCancelled(Setting.KEEP_CHUNKS_LOADED.asBoolean());
|
||||||
Bukkit.getPluginManager().callEvent(event);
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
if (event.isCancelled()) {
|
if (event.isCancelled()) {
|
||||||
getBukkitEntity().getLocation().getChunk();
|
getBukkitEntity().getLocation().getChunk().load();
|
||||||
// ensure that we are in a loaded chunk.
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
boolean keepSelected = getTrait(Spawned.class).shouldSpawn();
|
boolean keepSelected = getTrait(Spawned.class).shouldSpawn();
|
||||||
@ -97,8 +96,8 @@ public class CitizensNPC extends AbstractNPC {
|
|||||||
// Load traits
|
// Load traits
|
||||||
|
|
||||||
String traitNames = root.getString("traitnames");
|
String traitNames = root.getString("traitnames");
|
||||||
Iterable<DataKey> keys = traitNames.isEmpty() ? root.getRelative("traits").getSubKeys() : Iterables
|
Iterable<DataKey> keys = traitNames.isEmpty() ? root.getRelative("traits").getSubKeys() : Iterables.transform(
|
||||||
.transform(Splitter.on(',').split(traitNames), new Function<String, DataKey>() {
|
Splitter.on(',').split(traitNames), new Function<String, DataKey>() {
|
||||||
@Override
|
@Override
|
||||||
public DataKey apply(@Nullable String input) {
|
public DataKey apply(@Nullable String input) {
|
||||||
return root.getRelative("traits." + input);
|
return root.getRelative("traits." + input);
|
||||||
@ -196,8 +195,7 @@ public class CitizensNPC extends AbstractNPC {
|
|||||||
|
|
||||||
entityController.spawn(at, this);
|
entityController.spawn(at, this);
|
||||||
EntityLiving mcEntity = getHandle();
|
EntityLiving mcEntity = getHandle();
|
||||||
boolean couldSpawn = !Util.isLoaded(at) ? false : mcEntity.world.addEntity(mcEntity,
|
boolean couldSpawn = !Util.isLoaded(at) ? false : mcEntity.world.addEntity(mcEntity, SpawnReason.CUSTOM);
|
||||||
SpawnReason.CUSTOM);
|
|
||||||
if (!couldSpawn) {
|
if (!couldSpawn) {
|
||||||
// we need to wait for a chunk load before trying to spawn
|
// we need to wait for a chunk load before trying to spawn
|
||||||
mcEntity = null;
|
mcEntity = null;
|
||||||
@ -213,8 +211,7 @@ public class CitizensNPC extends AbstractNPC {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NMS.setHeadYaw(mcEntity, at.getYaw());
|
NMS.setHeadYaw(mcEntity, at.getYaw());
|
||||||
getBukkitEntity().setMetadata(NPC_METADATA_MARKER,
|
getBukkitEntity().setMetadata(NPC_METADATA_MARKER, new FixedMetadataValue(CitizensAPI.getPlugin(), true));
|
||||||
new FixedMetadataValue(CitizensAPI.getPlugin(), true));
|
|
||||||
|
|
||||||
// Set the spawned state
|
// Set the spawned state
|
||||||
getTrait(CurrentLocation.class).setLocation(at);
|
getTrait(CurrentLocation.class).setLocation(at);
|
||||||
|
@ -38,8 +38,8 @@ import com.google.common.collect.Maps;
|
|||||||
|
|
||||||
public class EntityControllers {
|
public class EntityControllers {
|
||||||
|
|
||||||
private static final Map<EntityType, Class<? extends EntityController>> TYPES = Maps
|
private static final Map<EntityType, Class<? extends EntityController>> TYPES = Maps.newEnumMap(EntityType.class);
|
||||||
.newEnumMap(EntityType.class);
|
|
||||||
public static EntityController createForType(EntityType type) {
|
public static EntityController createForType(EntityType type) {
|
||||||
Class<? extends EntityController> controllerClass = TYPES.get(type);
|
Class<? extends EntityController> controllerClass = TYPES.get(type);
|
||||||
if (controllerClass == null)
|
if (controllerClass == null)
|
||||||
|
@ -102,8 +102,7 @@ public class Template {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static YamlStorage templates = new YamlStorage(new File(CitizensAPI.getDataFolder(),
|
private static YamlStorage templates = new YamlStorage(new File(CitizensAPI.getDataFolder(), "templates.yml"));
|
||||||
"templates.yml"));
|
|
||||||
|
|
||||||
public static Template byName(String name) {
|
public static Template byName(String name) {
|
||||||
if (!templates.getKey("").keyExists(name))
|
if (!templates.getKey("").keyExists(name))
|
||||||
|
@ -31,8 +31,9 @@ public class AStarNavigationStrategy extends AbstractPathStrategy {
|
|||||||
this.destination = dest;
|
this.destination = dest;
|
||||||
this.npc = npc;
|
this.npc = npc;
|
||||||
Location location = npc.getBukkitEntity().getEyeLocation();
|
Location location = npc.getBukkitEntity().getEyeLocation();
|
||||||
plan = ASTAR.runFully(new VectorGoal(dest), new VectorNode(location, new ChunkBlockSource(location,
|
plan = ASTAR.runFully(new VectorGoal(dest),
|
||||||
params.range()), params.examiners()), (int) (params.range() * 10));
|
new VectorNode(location, new ChunkBlockSource(location, params.range()), params.examiners()),
|
||||||
|
(int) (params.range() * 10));
|
||||||
if (plan == null || plan.isComplete()) {
|
if (plan == null || plan.isComplete()) {
|
||||||
setCancelReason(CancelReason.STUCK);
|
setCancelReason(CancelReason.STUCK);
|
||||||
} else {
|
} else {
|
||||||
|
@ -23,10 +23,10 @@ import org.bukkit.entity.LivingEntity;
|
|||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
public class CitizensNavigator implements Navigator, Runnable {
|
public class CitizensNavigator implements Navigator, Runnable {
|
||||||
private final NavigatorParameters defaultParams = new NavigatorParameters()
|
private final NavigatorParameters defaultParams = new NavigatorParameters().baseSpeed(UNINITIALISED_SPEED)
|
||||||
.baseSpeed(UNINITIALISED_SPEED).range(Setting.DEFAULT_PATHFINDING_RANGE.asFloat())
|
.range(Setting.DEFAULT_PATHFINDING_RANGE.asFloat())
|
||||||
.stationaryTicks(Setting.DEFAULT_STATIONARY_TICKS.asInt())
|
.stationaryTicks(Setting.DEFAULT_STATIONARY_TICKS.asInt()).stuckAction(TeleportStuckAction.INSTANCE)
|
||||||
.stuckAction(TeleportStuckAction.INSTANCE).examiner(new MinecraftBlockExaminer());
|
.examiner(new MinecraftBlockExaminer());
|
||||||
private PathStrategy executing;
|
private PathStrategy executing;
|
||||||
private int lastX, lastY, lastZ;
|
private int lastX, lastY, lastZ;
|
||||||
private NavigatorParameters localParams = defaultParams;
|
private NavigatorParameters localParams = defaultParams;
|
||||||
@ -82,15 +82,12 @@ public class CitizensNavigator implements Navigator, Runnable {
|
|||||||
|
|
||||||
public void load(DataKey root) {
|
public void load(DataKey root) {
|
||||||
defaultParams.baseSpeed((float) root.getDouble("speed", UNINITIALISED_SPEED));
|
defaultParams.baseSpeed((float) root.getDouble("speed", UNINITIALISED_SPEED));
|
||||||
defaultParams.range((float) root.getDouble("pathfindingrange",
|
defaultParams.range((float) root.getDouble("pathfindingrange", Setting.DEFAULT_PATHFINDING_RANGE.asFloat()));
|
||||||
Setting.DEFAULT_PATHFINDING_RANGE.asFloat()));
|
defaultParams.stationaryTicks(root.getInt("stationaryticks", Setting.DEFAULT_STATIONARY_TICKS.asInt()));
|
||||||
defaultParams
|
|
||||||
.stationaryTicks(root.getInt("stationaryticks", Setting.DEFAULT_STATIONARY_TICKS.asInt()));
|
|
||||||
defaultParams.speedModifier((float) root.getDouble("speedmodifier", 1F));
|
defaultParams.speedModifier((float) root.getDouble("speedmodifier", 1F));
|
||||||
if (root.keyExists("avoidwater"))
|
if (root.keyExists("avoidwater"))
|
||||||
defaultParams.avoidWater(root.getBoolean("avoidwater"));
|
defaultParams.avoidWater(root.getBoolean("avoidwater"));
|
||||||
if (!root.getBoolean("usedefaultstuckaction")
|
if (!root.getBoolean("usedefaultstuckaction") && defaultParams.stuckAction() == TeleportStuckAction.INSTANCE)
|
||||||
&& defaultParams.stuckAction() == TeleportStuckAction.INSTANCE)
|
|
||||||
defaultParams.stuckAction(null);
|
defaultParams.stuckAction(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@ public class MCTargetStrategy implements PathStrategy, EntityTarget {
|
|||||||
return handle.getBukkitEntity().getLocation(HANDLE_LOCATION)
|
return handle.getBukkitEntity().getLocation(HANDLE_LOCATION)
|
||||||
.distanceSquared(target.getBukkitEntity().getLocation(TARGET_LOCATION));
|
.distanceSquared(target.getBukkitEntity().getLocation(TARGET_LOCATION));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CancelReason getCancelReason() {
|
public CancelReason getCancelReason() {
|
||||||
return cancelReason;
|
return cancelReason;
|
||||||
|
@ -17,101 +17,120 @@ import net.citizensnpcs.util.Messaging;
|
|||||||
|
|
||||||
public class Chat implements VocalChord {
|
public class Chat implements VocalChord {
|
||||||
|
|
||||||
public final String VOCAL_CHORD_NAME = "chat";
|
public final String VOCAL_CHORD_NAME = "chat";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return VOCAL_CHORD_NAME;
|
return VOCAL_CHORD_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void talk(SpeechContext context) {
|
public void talk(SpeechContext context) {
|
||||||
|
|
||||||
// Check valid talker
|
|
||||||
if (context.getTalker() == null) return;
|
|
||||||
NPC npc = CitizensAPI.getNPCRegistry().getNPC(context.getTalker().getEntity());
|
|
||||||
if (npc == null) return;
|
|
||||||
|
|
||||||
// If no recipients, chat to the world with CHAT_FORMAT and CHAT_RANGE settings
|
|
||||||
if (!context.hasRecipients()) {
|
|
||||||
String text = Setting.CHAT_FORMAT.asString().replace("<npc>", npc.getName()).replace("<text>", context.getMessage());
|
|
||||||
talkToBystanders(npc, text, context);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assumed recipients at this point
|
// Check valid talker
|
||||||
else if (context.size() <= 1) { // One recipient
|
if (context.getTalker() == null)
|
||||||
String text = Setting.CHAT_FORMAT_TO_TARGET.asString().replace("<npc>", npc.getName()).replace("<text>", context.getMessage());
|
return;
|
||||||
String targetName = "";
|
NPC npc = CitizensAPI.getNPCRegistry().getNPC(context.getTalker().getEntity());
|
||||||
// For each recipient
|
if (npc == null)
|
||||||
for (Talkable entity : context) {
|
return;
|
||||||
entity.talkTo(context, text, this);
|
|
||||||
targetName = entity.getName();
|
|
||||||
}
|
|
||||||
// Check if bystanders hear targeted chat
|
|
||||||
if (!Setting.CHAT_BYSTANDERS_HEAR_TARGETED_CHAT.asBoolean()) return;
|
|
||||||
// Format message with config setting and send to bystanders
|
|
||||||
String bystanderText = Setting.CHAT_FORMAT_TO_BYSTANDERS.asString().replace("<npc>", npc.getName()).replace("<target>", targetName).replace("<text>", context.getMessage());
|
|
||||||
talkToBystanders(npc, bystanderText, context);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
else { // Multiple recipients
|
// If no recipients, chat to the world with CHAT_FORMAT and CHAT_RANGE
|
||||||
String text = Setting.CHAT_FORMAT_TO_TARGET.asString().replace("<npc>", npc.getName()).replace("<text>", context.getMessage());
|
// settings
|
||||||
List<String> targetNames = Collections.emptyList();
|
if (!context.hasRecipients()) {
|
||||||
// Talk to each recipient
|
String text = Setting.CHAT_FORMAT.asString().replace("<npc>", npc.getName())
|
||||||
for (Talkable entity : context) {
|
.replace("<text>", context.getMessage());
|
||||||
entity.talkTo(context, text, this);
|
talkToBystanders(npc, text, context);
|
||||||
targetNames.add(entity.getName());
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Setting.CHAT_BYSTANDERS_HEAR_TARGETED_CHAT.asBoolean()) return;
|
// Assumed recipients at this point
|
||||||
String targets = "";
|
else if (context.size() <= 1) { // One recipient
|
||||||
int max = Setting.CHAT_MAX_NUMBER_OF_TARGETS.asInt();
|
String text = Setting.CHAT_FORMAT_TO_TARGET.asString().replace("<npc>", npc.getName())
|
||||||
String[] format = Setting.CHAT_FORMAT_WITH_TARGETS_TO_BYSTANDERS.asString().split("\\|");
|
.replace("<text>", context.getMessage());
|
||||||
if (format.length != 4) Messaging.log(Level.WARNING, "npc.chat.format.with-target-to-bystanders invalid!");
|
String targetName = "";
|
||||||
if (max == 1) {
|
// For each recipient
|
||||||
targets = format[0].replace("<npc>", targetNames.get(0)) + format[3];
|
for (Talkable entity : context) {
|
||||||
}
|
entity.talkTo(context, text, this);
|
||||||
else if (max == 2 || targetNames.size() == 2) {
|
targetName = entity.getName();
|
||||||
if (targetNames.size() == 2)
|
}
|
||||||
targets = format[0].replace("<npc>", targetNames.get(0)) + format[2].replace("<npc>", targetNames.get(1));
|
// Check if bystanders hear targeted chat
|
||||||
else
|
if (!Setting.CHAT_BYSTANDERS_HEAR_TARGETED_CHAT.asBoolean())
|
||||||
targets = format[0].replace("<npc>", targetNames.get(0)) + format[1].replace("<npc>", targetNames.get(1)) + format[3];
|
return;
|
||||||
}
|
// Format message with config setting and send to bystanders
|
||||||
else if (max >= 3) {
|
String bystanderText = Setting.CHAT_FORMAT_TO_BYSTANDERS.asString().replace("<npc>", npc.getName())
|
||||||
targets = format[0].replace("<npc>", targetNames.get(0));
|
.replace("<target>", targetName).replace("<text>", context.getMessage());
|
||||||
|
talkToBystanders(npc, bystanderText, context);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int x = 1;
|
else { // Multiple recipients
|
||||||
for (x = 1; x < max - 1; x++) {
|
String text = Setting.CHAT_FORMAT_TO_TARGET.asString().replace("<npc>", npc.getName())
|
||||||
if (targetNames.size() - 1 == x) break;
|
.replace("<text>", context.getMessage());
|
||||||
targets = targets + format[1].replace("<npc>", targetNames.get(x));
|
List<String> targetNames = Collections.emptyList();
|
||||||
}
|
// Talk to each recipient
|
||||||
if (targetNames.size() == max)
|
for (Talkable entity : context) {
|
||||||
targets = targets + format[2].replace("<npc>", targetNames.get(x));
|
entity.talkTo(context, text, this);
|
||||||
else targets = targets + format[3];
|
targetNames.add(entity.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
String bystanderText = Setting.CHAT_FORMAT_WITH_TARGETS_TO_BYSTANDERS.asString().replace("<npc>", npc.getName()).replace("<targets>", targets).replace("<text>", context.getMessage());
|
|
||||||
talkToBystanders(npc, bystanderText, context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void talkToBystanders(NPC npc, String text, SpeechContext context) {
|
if (!Setting.CHAT_BYSTANDERS_HEAR_TARGETED_CHAT.asBoolean())
|
||||||
// Get list of nearby entities
|
return;
|
||||||
List<Entity> bystanderEntities = npc.getBukkitEntity().getNearbyEntities(Setting.CHAT_RANGE.asDouble(), Setting.CHAT_RANGE.asDouble(), Setting.CHAT_RANGE.asDouble());
|
String targets = "";
|
||||||
for (Entity bystander : bystanderEntities)
|
int max = Setting.CHAT_MAX_NUMBER_OF_TARGETS.asInt();
|
||||||
// Continue if a LivingEntity, which is compatible with TalkableEntity
|
String[] format = Setting.CHAT_FORMAT_WITH_TARGETS_TO_BYSTANDERS.asString().split("\\|");
|
||||||
if (bystander instanceof LivingEntity) {
|
if (format.length != 4)
|
||||||
// Exclude targeted recipients
|
Messaging.log(Level.WARNING, "npc.chat.format.with-target-to-bystanders invalid!");
|
||||||
if (context.hasRecipients()) {
|
if (max == 1) {
|
||||||
for (Talkable target : context)
|
targets = format[0].replace("<npc>", targetNames.get(0)) + format[3];
|
||||||
if (target.getEntity() == bystander) continue;
|
} else if (max == 2 || targetNames.size() == 2) {
|
||||||
else new TalkableEntity((LivingEntity) bystander).talkNear(context, text, this);
|
if (targetNames.size() == 2)
|
||||||
} else
|
targets = format[0].replace("<npc>", targetNames.get(0))
|
||||||
// Found a nearby LivingEntity, make it Talkable and talkNear it
|
+ format[2].replace("<npc>", targetNames.get(1));
|
||||||
new TalkableEntity((LivingEntity) bystander).talkNear(context, text, this);
|
else
|
||||||
}
|
targets = format[0].replace("<npc>", targetNames.get(0))
|
||||||
}
|
+ format[1].replace("<npc>", targetNames.get(1)) + format[3];
|
||||||
|
} else if (max >= 3) {
|
||||||
|
targets = format[0].replace("<npc>", targetNames.get(0));
|
||||||
|
|
||||||
|
int x = 1;
|
||||||
|
for (x = 1; x < max - 1; x++) {
|
||||||
|
if (targetNames.size() - 1 == x)
|
||||||
|
break;
|
||||||
|
targets = targets + format[1].replace("<npc>", targetNames.get(x));
|
||||||
|
}
|
||||||
|
if (targetNames.size() == max)
|
||||||
|
targets = targets + format[2].replace("<npc>", targetNames.get(x));
|
||||||
|
else
|
||||||
|
targets = targets + format[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
String bystanderText = Setting.CHAT_FORMAT_WITH_TARGETS_TO_BYSTANDERS.asString()
|
||||||
|
.replace("<npc>", npc.getName()).replace("<targets>", targets)
|
||||||
|
.replace("<text>", context.getMessage());
|
||||||
|
talkToBystanders(npc, bystanderText, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void talkToBystanders(NPC npc, String text, SpeechContext context) {
|
||||||
|
// Get list of nearby entities
|
||||||
|
List<Entity> bystanderEntities = npc.getBukkitEntity().getNearbyEntities(Setting.CHAT_RANGE.asDouble(),
|
||||||
|
Setting.CHAT_RANGE.asDouble(), Setting.CHAT_RANGE.asDouble());
|
||||||
|
for (Entity bystander : bystanderEntities)
|
||||||
|
// Continue if a LivingEntity, which is compatible with
|
||||||
|
// TalkableEntity
|
||||||
|
if (bystander instanceof LivingEntity) {
|
||||||
|
// Exclude targeted recipients
|
||||||
|
if (context.hasRecipients()) {
|
||||||
|
for (Talkable target : context)
|
||||||
|
if (target.getEntity() == bystander)
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
new TalkableEntity((LivingEntity) bystander).talkNear(context, text, this);
|
||||||
|
} else
|
||||||
|
// Found a nearby LivingEntity, make it Talkable and
|
||||||
|
// talkNear it
|
||||||
|
new TalkableEntity((LivingEntity) bystander).talkNear(context, text, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,66 +14,68 @@ import net.citizensnpcs.api.ai.speech.VocalChord;
|
|||||||
|
|
||||||
public class CitizensSpeechFactory implements SpeechFactory {
|
public class CitizensSpeechFactory implements SpeechFactory {
|
||||||
|
|
||||||
Map<String, Class<? extends VocalChord>> registered = new HashMap<String, Class <? extends VocalChord>>();
|
Map<String, Class<? extends VocalChord>> registered = new HashMap<String, Class<? extends VocalChord>>();
|
||||||
|
|
||||||
@Override
|
|
||||||
public VocalChord getVocalChord(Class<? extends VocalChord> clazz) {
|
|
||||||
// Return a new instance of the VocalChord specified
|
|
||||||
try {
|
|
||||||
return clazz.newInstance();
|
|
||||||
} catch (InstantiationException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VocalChord getVocalChord(String name) {
|
public VocalChord getVocalChord(Class<? extends VocalChord> clazz) {
|
||||||
// Check if VocalChord name is a registered type
|
// Return a new instance of the VocalChord specified
|
||||||
if (isRegistered(name))
|
try {
|
||||||
// Return a new instance of the VocalChord specified
|
return clazz.newInstance();
|
||||||
try {
|
} catch (InstantiationException e) {
|
||||||
return registered.get(name.toLowerCase()).newInstance();
|
e.printStackTrace();
|
||||||
} catch (InstantiationException e) {
|
} catch (IllegalAccessException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch (IllegalAccessException e) {
|
}
|
||||||
e.printStackTrace();
|
return null;
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getVocalChordName(Class<? extends VocalChord> clazz) {
|
public VocalChord getVocalChord(String name) {
|
||||||
// Get the name of a VocalChord class that has been registered
|
// Check if VocalChord name is a registered type
|
||||||
for (Entry<String, Class<? extends VocalChord>> vocalChord : registered.entrySet())
|
if (isRegistered(name))
|
||||||
if (vocalChord.getValue() == clazz) return vocalChord.getKey();
|
// Return a new instance of the VocalChord specified
|
||||||
|
try {
|
||||||
return null;
|
return registered.get(name.toLowerCase()).newInstance();
|
||||||
}
|
} catch (InstantiationException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isRegistered(String name) {
|
public String getVocalChordName(Class<? extends VocalChord> clazz) {
|
||||||
if (registered.containsKey(name.toLowerCase())) return true;
|
// Get the name of a VocalChord class that has been registered
|
||||||
else return false;
|
for (Entry<String, Class<? extends VocalChord>> vocalChord : registered.entrySet())
|
||||||
}
|
if (vocalChord.getValue() == clazz)
|
||||||
|
return vocalChord.getKey();
|
||||||
|
|
||||||
@Override
|
return null;
|
||||||
public void register(Class<? extends VocalChord> clazz, String name) {
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRegistered(String name) {
|
||||||
|
if (registered.containsKey(name.toLowerCase()))
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Talkable newTalkableEntity(LivingEntity entity) {
|
||||||
|
if (entity == null)
|
||||||
|
return null;
|
||||||
|
return new TalkableEntity(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void register(Class<? extends VocalChord> clazz, String name) {
|
||||||
Preconditions.checkNotNull(name, "info cannot be null");
|
Preconditions.checkNotNull(name, "info cannot be null");
|
||||||
Preconditions.checkNotNull(clazz, "vocalchord cannot be null");
|
Preconditions.checkNotNull(clazz, "vocalchord cannot be null");
|
||||||
if (registered.containsKey(name.toLowerCase()))
|
if (registered.containsKey(name.toLowerCase()))
|
||||||
throw new IllegalArgumentException("vocalchord name already registered");
|
throw new IllegalArgumentException("vocalchord name already registered");
|
||||||
registered.put(name.toLowerCase(), clazz);
|
registered.put(name.toLowerCase(), clazz);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Talkable newTalkableEntity(LivingEntity entity) {
|
|
||||||
if (entity == null) return null;
|
|
||||||
return new TalkableEntity(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,77 +15,82 @@ import org.bukkit.entity.Player;
|
|||||||
|
|
||||||
public class TalkableEntity implements Talkable {
|
public class TalkableEntity implements Talkable {
|
||||||
|
|
||||||
LivingEntity entity;
|
LivingEntity entity;
|
||||||
|
|
||||||
public TalkableEntity(LivingEntity entity) {
|
|
||||||
this.entity = entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TalkableEntity(NPC npc) {
|
|
||||||
entity = npc.getBukkitEntity();
|
|
||||||
}
|
|
||||||
|
|
||||||
public TalkableEntity(Player player) {
|
|
||||||
entity = (LivingEntity) player;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to compare a LivingEntity to this TalkableEntity
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* 0 if the Entities are the same, 1 if they are not, -1 if
|
|
||||||
* the object compared is not a valid LivingEntity
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int compareTo(Object o) {
|
|
||||||
// If not living entity, return -1
|
|
||||||
if (!(o instanceof LivingEntity)) return -1;
|
|
||||||
// If NPC and matches, return 0
|
|
||||||
else if (CitizensAPI.getNPCRegistry().isNPC((LivingEntity) o)
|
|
||||||
&& CitizensAPI.getNPCRegistry().isNPC((LivingEntity) entity)
|
|
||||||
&& CitizensAPI.getNPCRegistry().getNPC((LivingEntity) o).getId() ==
|
|
||||||
CitizensAPI.getNPCRegistry().getNPC((LivingEntity) entity).getId())
|
|
||||||
return 0;
|
|
||||||
else if ((LivingEntity) o == entity) return 0;
|
|
||||||
// Not a match, return 1
|
|
||||||
else return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
public TalkableEntity(LivingEntity entity) {
|
||||||
public LivingEntity getEntity() {
|
this.entity = entity;
|
||||||
return entity;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
if (CitizensAPI.getNPCRegistry().isNPC(entity))
|
|
||||||
return CitizensAPI.getNPCRegistry().getNPC(entity).getName();
|
|
||||||
else if (entity instanceof Player)
|
|
||||||
return ((Player) entity).getName();
|
|
||||||
else
|
|
||||||
return entity.getType().name().replace("_", " ");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void talk(String message) {
|
|
||||||
if (entity instanceof Player
|
|
||||||
&& !CitizensAPI.getNPCRegistry().isNPC(entity))
|
|
||||||
Messaging.send((Player) entity, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void talkNear(SpeechContext context, String text, VocalChord vocalChord) {
|
|
||||||
SpeechBystanderEvent event = new SpeechBystanderEvent(this, context, text, vocalChord);
|
|
||||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
|
||||||
if (event.isCancelled()) return;
|
|
||||||
else talk(event.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
public TalkableEntity(NPC npc) {
|
||||||
public void talkTo(SpeechContext context, String text, VocalChord vocalChord) {
|
entity = npc.getBukkitEntity();
|
||||||
SpeechTargetedEvent event = new SpeechTargetedEvent(this, context, text, vocalChord);
|
}
|
||||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
|
||||||
if (event.isCancelled()) return;
|
public TalkableEntity(Player player) {
|
||||||
else talk(event.getMessage());
|
entity = (LivingEntity) player;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to compare a LivingEntity to this TalkableEntity
|
||||||
|
*
|
||||||
|
* @return 0 if the Entities are the same, 1 if they are not, -1 if the
|
||||||
|
* object compared is not a valid LivingEntity
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int compareTo(Object o) {
|
||||||
|
// If not living entity, return -1
|
||||||
|
if (!(o instanceof LivingEntity))
|
||||||
|
return -1;
|
||||||
|
// If NPC and matches, return 0
|
||||||
|
else if (CitizensAPI.getNPCRegistry().isNPC((LivingEntity) o)
|
||||||
|
&& CitizensAPI.getNPCRegistry().isNPC((LivingEntity) entity)
|
||||||
|
&& CitizensAPI.getNPCRegistry().getNPC((LivingEntity) o).getId() == CitizensAPI.getNPCRegistry()
|
||||||
|
.getNPC((LivingEntity) entity).getId())
|
||||||
|
return 0;
|
||||||
|
else if ((LivingEntity) o == entity)
|
||||||
|
return 0;
|
||||||
|
// Not a match, return 1
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LivingEntity getEntity() {
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
if (CitizensAPI.getNPCRegistry().isNPC(entity))
|
||||||
|
return CitizensAPI.getNPCRegistry().getNPC(entity).getName();
|
||||||
|
else if (entity instanceof Player)
|
||||||
|
return ((Player) entity).getName();
|
||||||
|
else
|
||||||
|
return entity.getType().name().replace("_", " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void talk(String message) {
|
||||||
|
if (entity instanceof Player && !CitizensAPI.getNPCRegistry().isNPC(entity))
|
||||||
|
Messaging.send((Player) entity, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void talkNear(SpeechContext context, String text, VocalChord vocalChord) {
|
||||||
|
SpeechBystanderEvent event = new SpeechBystanderEvent(this, context, text, vocalChord);
|
||||||
|
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||||
|
if (event.isCancelled())
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
talk(event.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void talkTo(SpeechContext context, String text, VocalChord vocalChord) {
|
||||||
|
SpeechTargetedEvent event = new SpeechTargetedEvent(this, context, text, vocalChord);
|
||||||
|
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||||
|
if (event.isCancelled())
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
talk(event.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -189,8 +189,7 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
|
|||||||
net.minecraft.server.v1_4_6.ItemStack previous = previousEquipment[i];
|
net.minecraft.server.v1_4_6.ItemStack previous = previousEquipment[i];
|
||||||
net.minecraft.server.v1_4_6.ItemStack current = getEquipment(i);
|
net.minecraft.server.v1_4_6.ItemStack current = getEquipment(i);
|
||||||
if (previous != current) {
|
if (previous != current) {
|
||||||
NMS.sendPacketNearby(getBukkitEntity().getLocation(), new Packet5EntityEquipment(id, i,
|
NMS.sendPacketNearby(getBukkitEntity().getLocation(), new Packet5EntityEquipment(id, i, current));
|
||||||
current));
|
|
||||||
previousEquipment[i] = current;
|
previousEquipment[i] = current;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,8 @@ public class HumanController extends AbstractEntityController {
|
|||||||
@Override
|
@Override
|
||||||
protected LivingEntity createEntity(final Location at, final NPC npc) {
|
protected LivingEntity createEntity(final Location at, final NPC npc) {
|
||||||
WorldServer ws = ((CraftWorld) at.getWorld()).getHandle();
|
WorldServer ws = ((CraftWorld) at.getWorld()).getHandle();
|
||||||
final EntityHumanNPC handle = new EntityHumanNPC(ws.getServer().getServer(), ws,
|
final EntityHumanNPC handle = new EntityHumanNPC(ws.getServer().getServer(), ws, StringHelper.parseColors(npc
|
||||||
StringHelper.parseColors(npc.getFullName()), new PlayerInteractManager(ws), npc);
|
.getFullName()), new PlayerInteractManager(ws), npc);
|
||||||
handle.getBukkitEntity().teleport(at);
|
handle.getBukkitEntity().teleport(at);
|
||||||
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() {
|
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -18,8 +18,7 @@ import net.minecraft.server.v1_4_6.Packet3Chat;
|
|||||||
import net.minecraft.server.v1_4_6.Packet51MapChunk;
|
import net.minecraft.server.v1_4_6.Packet51MapChunk;
|
||||||
|
|
||||||
public class EmptyNetHandler extends PlayerConnection {
|
public class EmptyNetHandler extends PlayerConnection {
|
||||||
public EmptyNetHandler(MinecraftServer minecraftServer, NetworkManager networkManager,
|
public EmptyNetHandler(MinecraftServer minecraftServer, NetworkManager networkManager, EntityPlayer entityPlayer) {
|
||||||
EntityPlayer entityPlayer) {
|
|
||||||
super(minecraftServer, networkManager, entityPlayer);
|
super(minecraftServer, networkManager, entityPlayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,8 +11,7 @@ import net.minecraft.server.v1_4_6.Packet;
|
|||||||
|
|
||||||
public class EmptyNetworkManager extends NetworkManager {
|
public class EmptyNetworkManager extends NetworkManager {
|
||||||
|
|
||||||
public EmptyNetworkManager(Socket socket, String string, Connection conn, PrivateKey key)
|
public EmptyNetworkManager(Socket socket, String string, Connection conn, PrivateKey key) throws IOException {
|
||||||
throws IOException {
|
|
||||||
super(socket, string, conn, key);
|
super(socket, string, conn, key);
|
||||||
|
|
||||||
NMS.stopNetworkThreads(this);
|
NMS.stopNetworkThreads(this);
|
||||||
|
@ -202,16 +202,6 @@ public class Controllable extends Trait implements Toggleable, CommandConfigurab
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static interface MovementController {
|
|
||||||
void leftClick(PlayerInteractEvent event);
|
|
||||||
|
|
||||||
void rightClick(PlayerInteractEvent event);
|
|
||||||
|
|
||||||
void rightClickEntity(NPCRightClickEvent event);
|
|
||||||
|
|
||||||
void run(Player rider);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class GroundController implements MovementController {
|
public class GroundController implements MovementController {
|
||||||
private void jump() {
|
private void jump() {
|
||||||
boolean allowed = getHandle().onGround;
|
boolean allowed = getHandle().onGround;
|
||||||
@ -249,6 +239,16 @@ public class Controllable extends Trait implements Toggleable, CommandConfigurab
|
|||||||
private static final float JUMP_VELOCITY = 0.6F;
|
private static final float JUMP_VELOCITY = 0.6F;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static interface MovementController {
|
||||||
|
void leftClick(PlayerInteractEvent event);
|
||||||
|
|
||||||
|
void rightClick(PlayerInteractEvent event);
|
||||||
|
|
||||||
|
void rightClickEntity(NPCRightClickEvent event);
|
||||||
|
|
||||||
|
void run(Player rider);
|
||||||
|
}
|
||||||
|
|
||||||
private static final Map<EntityType, Class<? extends MovementController>> controllerTypes = Maps
|
private static final Map<EntityType, Class<? extends MovementController>> controllerTypes = Maps
|
||||||
.newEnumMap(EntityType.class);
|
.newEnumMap(EntityType.class);
|
||||||
|
|
||||||
|
@ -53,8 +53,7 @@ public class Poses extends Trait {
|
|||||||
paginator.addLine("<e>Key: <a>ID <b>Name <c>Pitch/Yaw");
|
paginator.addLine("<e>Key: <a>ID <b>Name <c>Pitch/Yaw");
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (Pose pose : poses.values()) {
|
for (Pose pose : poses.values()) {
|
||||||
String line = "<a>" + i + "<b> " + pose.getName() + "<c> " + pose.getPitch() + "/"
|
String line = "<a>" + i + "<b> " + pose.getName() + "<c> " + pose.getPitch() + "/" + pose.getYaw();
|
||||||
+ pose.getYaw();
|
|
||||||
paginator.addLine(line);
|
paginator.addLine(line);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
@ -11,13 +11,11 @@ import java.util.concurrent.TimeUnit;
|
|||||||
import net.citizensnpcs.Settings.Setting;
|
import net.citizensnpcs.Settings.Setting;
|
||||||
import net.citizensnpcs.api.CitizensAPI;
|
import net.citizensnpcs.api.CitizensAPI;
|
||||||
import net.citizensnpcs.api.ai.speech.SpeechContext;
|
import net.citizensnpcs.api.ai.speech.SpeechContext;
|
||||||
import net.citizensnpcs.api.ai.speech.Talkable;
|
|
||||||
import net.citizensnpcs.api.event.NPCRightClickEvent;
|
import net.citizensnpcs.api.event.NPCRightClickEvent;
|
||||||
import net.citizensnpcs.api.exception.NPCLoadException;
|
import net.citizensnpcs.api.exception.NPCLoadException;
|
||||||
import net.citizensnpcs.api.trait.Trait;
|
import net.citizensnpcs.api.trait.Trait;
|
||||||
import net.citizensnpcs.api.util.DataKey;
|
import net.citizensnpcs.api.util.DataKey;
|
||||||
import net.citizensnpcs.editor.Editor;
|
import net.citizensnpcs.editor.Editor;
|
||||||
import net.citizensnpcs.npc.ai.speech.TalkableEntity;
|
|
||||||
import net.citizensnpcs.trait.Toggleable;
|
import net.citizensnpcs.trait.Toggleable;
|
||||||
import net.citizensnpcs.util.Messages;
|
import net.citizensnpcs.util.Messages;
|
||||||
import net.citizensnpcs.util.Messaging;
|
import net.citizensnpcs.util.Messaging;
|
||||||
@ -65,10 +63,9 @@ public class Text extends Trait implements Runnable, Toggleable, Listener, Conve
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Editor getEditor(final Player player) {
|
public Editor getEditor(final Player player) {
|
||||||
final Conversation conversation = new ConversationFactory(plugin)
|
final Conversation conversation = new ConversationFactory(plugin).addConversationAbandonedListener(this)
|
||||||
.addConversationAbandonedListener(this).withLocalEcho(false).withEscapeSequence("/npc text")
|
.withLocalEcho(false).withEscapeSequence("/npc text").withEscapeSequence("exit").withModality(false)
|
||||||
.withEscapeSequence("exit").withModality(false).withFirstPrompt(new TextStartPrompt(this))
|
.withFirstPrompt(new TextStartPrompt(this)).buildConversation(player);
|
||||||
.buildConversation(player);
|
|
||||||
return new Editor() {
|
return new Editor() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -111,8 +108,7 @@ public class Text extends Trait implements Runnable, Toggleable, Listener, Conve
|
|||||||
public void onRightClick(NPCRightClickEvent event) {
|
public void onRightClick(NPCRightClickEvent event) {
|
||||||
if (!event.getNPC().equals(npc))
|
if (!event.getNPC().equals(npc))
|
||||||
return;
|
return;
|
||||||
String localPattern = itemInHandPattern.equals("default") ? Setting.TALK_ITEM.asString()
|
String localPattern = itemInHandPattern.equals("default") ? Setting.TALK_ITEM.asString() : itemInHandPattern;
|
||||||
: itemInHandPattern;
|
|
||||||
if (Util.matchesItemInHand(event.getClicker(), localPattern) && !shouldTalkClose())
|
if (Util.matchesItemInHand(event.getClicker(), localPattern) && !shouldTalkClose())
|
||||||
sendText(event.getClicker());
|
sendText(event.getClicker());
|
||||||
}
|
}
|
||||||
@ -192,9 +188,10 @@ public class Text extends Trait implements Runnable, Toggleable, Listener, Conve
|
|||||||
currentIndex = 0;
|
currentIndex = 0;
|
||||||
index = currentIndex++;
|
index = currentIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
npc.getDefaultSpeechController().speak(new SpeechContext(text.get(index), player));
|
npc.getDefaultSpeechController().speak(new SpeechContext(text.get(index), player));
|
||||||
// Messaging.sendWithNPC(player, Setting.CHAT_PREFIX.asString() + text.get(index), npc);
|
// Messaging.sendWithNPC(player, Setting.CHAT_PREFIX.asString() +
|
||||||
|
// text.get(index), npc);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,8 +20,7 @@ public class TextEditPrompt extends StringPrompt {
|
|||||||
public Prompt acceptInput(ConversationContext context, String input) {
|
public Prompt acceptInput(ConversationContext context, String input) {
|
||||||
int index = (Integer) context.getSessionData("index");
|
int index = (Integer) context.getSessionData("index");
|
||||||
text.edit(index, input);
|
text.edit(index, input);
|
||||||
Messaging
|
Messaging.sendTr((CommandSender) context.getForWhom(), Messages.TEXT_EDITOR_EDITED_TEXT, index, input);
|
||||||
.sendTr((CommandSender) context.getForWhom(), Messages.TEXT_EDITOR_EDITED_TEXT, index, input);
|
|
||||||
return new TextStartPrompt(text);
|
return new TextStartPrompt(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,8 +30,7 @@ public class TextStartPrompt extends StringPrompt {
|
|||||||
else if (input.equalsIgnoreCase("random"))
|
else if (input.equalsIgnoreCase("random"))
|
||||||
Messaging.sendTr(sender, Messages.TEXT_EDITOR_RANDOM_TALKER_SET, text.toggleRandomTalker());
|
Messaging.sendTr(sender, Messages.TEXT_EDITOR_RANDOM_TALKER_SET, text.toggleRandomTalker());
|
||||||
else if (input.equalsIgnoreCase("realistic looking"))
|
else if (input.equalsIgnoreCase("realistic looking"))
|
||||||
Messaging.sendTr(sender, Messages.TEXT_EDITOR_REALISTIC_LOOKING_SET,
|
Messaging.sendTr(sender, Messages.TEXT_EDITOR_REALISTIC_LOOKING_SET, text.toggleRealisticLooking());
|
||||||
text.toggleRealisticLooking());
|
|
||||||
else if (input.equalsIgnoreCase("close") || input.equalsIgnoreCase("talk-close"))
|
else if (input.equalsIgnoreCase("close") || input.equalsIgnoreCase("talk-close"))
|
||||||
Messaging.sendTr(sender, Messages.TEXT_EDITOR_CLOSE_TALKER_SET, text.toggle());
|
Messaging.sendTr(sender, Messages.TEXT_EDITOR_CLOSE_TALKER_SET, text.toggle());
|
||||||
else if (input.equalsIgnoreCase("range")) {
|
else if (input.equalsIgnoreCase("range")) {
|
||||||
|
@ -267,8 +267,8 @@ public class LinearWaypointProvider implements WaypointProvider {
|
|||||||
if (!event.getRightClicked().hasMetadata("waypointindex"))
|
if (!event.getRightClicked().hasMetadata("waypointindex"))
|
||||||
return;
|
return;
|
||||||
editingSlot = event.getRightClicked().getMetadata("waypointindex").get(0).asInt();
|
editingSlot = event.getRightClicked().getMetadata("waypointindex").get(0).asInt();
|
||||||
Messaging.sendTr(player, Messages.LINEAR_WAYPOINT_EDITOR_EDIT_SLOT_SET, editingSlot,
|
Messaging.sendTr(player, Messages.LINEAR_WAYPOINT_EDITOR_EDIT_SLOT_SET, editingSlot, formatLoc(waypoints
|
||||||
formatLoc(waypoints.get(editingSlot).getLocation()));
|
.get(editingSlot).getLocation()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
@ -288,8 +288,8 @@ public class LinearWaypointProvider implements WaypointProvider {
|
|||||||
editingSlot += diff > 0 ? 1 : -1;
|
editingSlot += diff > 0 ? 1 : -1;
|
||||||
}
|
}
|
||||||
normaliseEditingSlot();
|
normaliseEditingSlot();
|
||||||
Messaging.sendTr(player, Messages.LINEAR_WAYPOINT_EDITOR_EDIT_SLOT_SET, editingSlot,
|
Messaging.sendTr(player, Messages.LINEAR_WAYPOINT_EDITOR_EDIT_SLOT_SET, editingSlot, formatLoc(waypoints
|
||||||
formatLoc(waypoints.get(editingSlot).getLocation()));
|
.get(editingSlot).getLocation()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onWaypointsModified() {
|
private void onWaypointsModified() {
|
||||||
@ -339,8 +339,8 @@ public class LinearWaypointProvider implements WaypointProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Iterator<Waypoint> getNewIterator() {
|
private Iterator<Waypoint> getNewIterator() {
|
||||||
LinearWaypointsCompleteEvent event = new LinearWaypointsCompleteEvent(
|
LinearWaypointsCompleteEvent event = new LinearWaypointsCompleteEvent(LinearWaypointProvider.this,
|
||||||
LinearWaypointProvider.this, waypoints.iterator());
|
waypoints.iterator());
|
||||||
Bukkit.getPluginManager().callEvent(event);
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
Iterator<Waypoint> next = event.getNextWaypoints();
|
Iterator<Waypoint> next = event.getNextWaypoints();
|
||||||
return next;
|
return next;
|
||||||
|
@ -23,8 +23,7 @@ public class AnimationTriggerPrompt extends StringPrompt implements WaypointTrig
|
|||||||
if (input.equalsIgnoreCase("back"))
|
if (input.equalsIgnoreCase("back"))
|
||||||
return (Prompt) context.getSessionData("previous");
|
return (Prompt) context.getSessionData("previous");
|
||||||
if (input.equalsIgnoreCase("finish")) {
|
if (input.equalsIgnoreCase("finish")) {
|
||||||
context.setSessionData(WaypointTriggerPrompt.CREATED_TRIGGER_KEY,
|
context.setSessionData(WaypointTriggerPrompt.CREATED_TRIGGER_KEY, new AnimationTrigger(animations));
|
||||||
new AnimationTrigger(animations));
|
|
||||||
return (Prompt) context.getSessionData(WaypointTriggerPrompt.RETURN_PROMPT_KEY);
|
return (Prompt) context.getSessionData(WaypointTriggerPrompt.RETURN_PROMPT_KEY);
|
||||||
}
|
}
|
||||||
PlayerAnimation animation = Util.matchEnum(PlayerAnimation.values(), input);
|
PlayerAnimation animation = Util.matchEnum(PlayerAnimation.values(), input);
|
||||||
@ -36,8 +35,7 @@ public class AnimationTriggerPrompt extends StringPrompt implements WaypointTrig
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPromptText(ConversationContext context) {
|
public String getPromptText(ConversationContext context) {
|
||||||
Messaging.sendTr((CommandSender) context.getForWhom(), Messages.ANIMATION_TRIGGER_PROMPT,
|
Messaging.sendTr((CommandSender) context.getForWhom(), Messages.ANIMATION_TRIGGER_PROMPT, getValidAnimations());
|
||||||
getValidAnimations());
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,8 +27,7 @@ public class ChatTriggerPrompt extends StringPrompt implements WaypointTriggerPr
|
|||||||
Messaging.sendErrorTr((CommandSender) context.getForWhom(),
|
Messaging.sendErrorTr((CommandSender) context.getForWhom(),
|
||||||
Messages.WAYPOINT_TRIGGER_CHAT_INVALID_RADIUS);
|
Messages.WAYPOINT_TRIGGER_CHAT_INVALID_RADIUS);
|
||||||
} catch (IndexOutOfBoundsException e) {
|
} catch (IndexOutOfBoundsException e) {
|
||||||
Messaging.sendErrorTr((CommandSender) context.getForWhom(),
|
Messaging.sendErrorTr((CommandSender) context.getForWhom(), Messages.WAYPOINT_TRIGGER_CHAT_NO_RADIUS);
|
||||||
Messages.WAYPOINT_TRIGGER_CHAT_NO_RADIUS);
|
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,8 @@ public class TeleportTrigger implements WaypointTrigger {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String description() {
|
public String description() {
|
||||||
return String.format("Teleport to [%s, %d, %d, %d]", location.getWorld().getName(),
|
return String.format("Teleport to [%s, %d, %d, %d]", location.getWorld().getName(), location.getBlockX(),
|
||||||
location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
location.getBlockY(), location.getBlockZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -29,8 +29,7 @@ public class TeleportTriggerPrompt extends RegexPrompt implements WaypointTrigge
|
|||||||
return (Prompt) context.getSessionData("previous");
|
return (Prompt) context.getSessionData("previous");
|
||||||
if (input.equalsIgnoreCase("here")) {
|
if (input.equalsIgnoreCase("here")) {
|
||||||
Player player = (Player) context.getForWhom();
|
Player player = (Player) context.getForWhom();
|
||||||
context.setSessionData(WaypointTriggerPrompt.CREATED_TRIGGER_KEY,
|
context.setSessionData(WaypointTriggerPrompt.CREATED_TRIGGER_KEY, new TeleportTrigger(player.getLocation()));
|
||||||
new TeleportTrigger(player.getLocation()));
|
|
||||||
return (Prompt) context.getSessionData(WaypointTriggerPrompt.RETURN_PROMPT_KEY);
|
return (Prompt) context.getSessionData(WaypointTriggerPrompt.RETURN_PROMPT_KEY);
|
||||||
}
|
}
|
||||||
String[] parts = Iterables.toArray(Splitter.on(':').split(input), String.class);
|
String[] parts = Iterables.toArray(Splitter.on(':').split(input), String.class);
|
||||||
|
@ -35,23 +35,20 @@ public class TriggerAddPrompt extends StringPrompt {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPromptText(ConversationContext context) {
|
public String getPromptText(ConversationContext context) {
|
||||||
WaypointTrigger returned = (WaypointTrigger) context
|
WaypointTrigger returned = (WaypointTrigger) context.getSessionData(WaypointTriggerPrompt.CREATED_TRIGGER_KEY);
|
||||||
.getSessionData(WaypointTriggerPrompt.CREATED_TRIGGER_KEY);
|
|
||||||
if (returned != null) {
|
if (returned != null) {
|
||||||
if (editor.getCurrentWaypoint() != null) {
|
if (editor.getCurrentWaypoint() != null) {
|
||||||
editor.getCurrentWaypoint().addTrigger(returned);
|
editor.getCurrentWaypoint().addTrigger(returned);
|
||||||
context.setSessionData(WaypointTriggerPrompt.CREATED_TRIGGER_KEY, null);
|
context.setSessionData(WaypointTriggerPrompt.CREATED_TRIGGER_KEY, null);
|
||||||
Messaging.sendTr((CommandSender) context.getForWhom(),
|
Messaging.sendTr((CommandSender) context.getForWhom(), Messages.WAYPOINT_TRIGGER_ADDED_SUCCESSFULLY,
|
||||||
Messages.WAYPOINT_TRIGGER_ADDED_SUCCESSFULLY, returned.description());
|
returned.description());
|
||||||
} else
|
} else
|
||||||
Messaging.sendErrorTr((CommandSender) context.getForWhom(),
|
Messaging.sendErrorTr((CommandSender) context.getForWhom(), Messages.WAYPOINT_TRIGGER_EDITOR_INACTIVE);
|
||||||
Messages.WAYPOINT_TRIGGER_EDITOR_INACTIVE);
|
|
||||||
}
|
}
|
||||||
if (context.getSessionData("said") == Boolean.TRUE)
|
if (context.getSessionData("said") == Boolean.TRUE)
|
||||||
return "";
|
return "";
|
||||||
context.setSessionData("said", true);
|
context.setSessionData("said", true);
|
||||||
context.setSessionData(WaypointTriggerPrompt.RETURN_PROMPT_KEY, this);
|
context.setSessionData(WaypointTriggerPrompt.RETURN_PROMPT_KEY, this);
|
||||||
return Messaging.tr(Messages.WAYPOINT_TRIGGER_ADD_PROMPT,
|
return Messaging.tr(Messages.WAYPOINT_TRIGGER_ADD_PROMPT, WaypointTriggerRegistry.describeValidTriggerNames());
|
||||||
WaypointTriggerRegistry.describeValidTriggerNames());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,9 +53,9 @@ public class TriggerEditPrompt extends StringPrompt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Conversation start(Player player, WaypointEditor editor) {
|
public static Conversation start(Player player, WaypointEditor editor) {
|
||||||
final Conversation conversation = new ConversationFactory(CitizensAPI.getPlugin())
|
final Conversation conversation = new ConversationFactory(CitizensAPI.getPlugin()).withLocalEcho(false)
|
||||||
.withLocalEcho(false).withEscapeSequence("exit").withEscapeSequence("/npc path")
|
.withEscapeSequence("exit").withEscapeSequence("/npc path").withModality(false)
|
||||||
.withModality(false).withFirstPrompt(new TriggerEditPrompt(editor)).buildConversation(player);
|
.withFirstPrompt(new TriggerEditPrompt(editor)).buildConversation(player);
|
||||||
conversation.begin();
|
conversation.begin();
|
||||||
return conversation;
|
return conversation;
|
||||||
}
|
}
|
||||||
|
@ -25,16 +25,15 @@ public class TriggerRemovePrompt extends StringPrompt {
|
|||||||
return (Prompt) context.getSessionData("previous");
|
return (Prompt) context.getSessionData("previous");
|
||||||
}
|
}
|
||||||
if (editor.getCurrentWaypoint() == null) {
|
if (editor.getCurrentWaypoint() == null) {
|
||||||
Messaging.sendErrorTr((CommandSender) context.getForWhom(),
|
Messaging.sendErrorTr((CommandSender) context.getForWhom(), Messages.WAYPOINT_TRIGGER_EDITOR_INACTIVE);
|
||||||
Messages.WAYPOINT_TRIGGER_EDITOR_INACTIVE);
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
int index = 0;
|
int index = 0;
|
||||||
try {
|
try {
|
||||||
index = Math.max(0, Integer.parseInt(input) - 1);
|
index = Math.max(0, Integer.parseInt(input) - 1);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
Messaging.sendErrorTr((CommandSender) context.getForWhom(),
|
Messaging
|
||||||
Messages.WAYPOINT_TRIGGER_REMOVE_INVALID_NUMBER);
|
.sendErrorTr((CommandSender) context.getForWhom(), Messages.WAYPOINT_TRIGGER_REMOVE_INVALID_NUMBER);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
List<WaypointTrigger> triggers = editor.getCurrentWaypoint().getTriggers();
|
List<WaypointTrigger> triggers = editor.getCurrentWaypoint().getTriggers();
|
||||||
@ -43,8 +42,7 @@ public class TriggerRemovePrompt extends StringPrompt {
|
|||||||
Messages.WAYPOINT_TRIGGER_REMOVE_INDEX_OUT_OF_RANGE, triggers.size());
|
Messages.WAYPOINT_TRIGGER_REMOVE_INDEX_OUT_OF_RANGE, triggers.size());
|
||||||
} else {
|
} else {
|
||||||
triggers.remove(index);
|
triggers.remove(index);
|
||||||
Messaging.sendTr((CommandSender) context.getForWhom(), Messages.WAYPOINT_TRIGGER_REMOVE_REMOVED,
|
Messaging.sendTr((CommandSender) context.getForWhom(), Messages.WAYPOINT_TRIGGER_REMOVE_REMOVED, index + 1);
|
||||||
index + 1);
|
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -52,8 +50,7 @@ public class TriggerRemovePrompt extends StringPrompt {
|
|||||||
@Override
|
@Override
|
||||||
public String getPromptText(ConversationContext context) {
|
public String getPromptText(ConversationContext context) {
|
||||||
if (editor.getCurrentWaypoint() == null) {
|
if (editor.getCurrentWaypoint() == null) {
|
||||||
Messaging.sendErrorTr((CommandSender) context.getForWhom(),
|
Messaging.sendErrorTr((CommandSender) context.getForWhom(), Messages.WAYPOINT_TRIGGER_EDITOR_INACTIVE);
|
||||||
Messages.WAYPOINT_TRIGGER_EDITOR_INACTIVE);
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
if (context.getSessionData("said") == Boolean.TRUE)
|
if (context.getSessionData("said") == Boolean.TRUE)
|
||||||
@ -64,8 +61,7 @@ public class TriggerRemovePrompt extends StringPrompt {
|
|||||||
for (WaypointTrigger trigger : editor.getCurrentWaypoint().getTriggers()) {
|
for (WaypointTrigger trigger : editor.getCurrentWaypoint().getTriggers()) {
|
||||||
root += String.format("<br> %d. " + trigger.description(), i++);
|
root += String.format("<br> %d. " + trigger.description(), i++);
|
||||||
}
|
}
|
||||||
Messaging
|
Messaging.sendTr((CommandSender) context.getForWhom(), Messages.WAYPOINT_TRIGGER_REMOVE_PROMPT + root);
|
||||||
.sendTr((CommandSender) context.getForWhom(), Messages.WAYPOINT_TRIGGER_REMOVE_PROMPT + root);
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,14 +44,14 @@ public class Anchor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String stringValue() {
|
public String stringValue() {
|
||||||
return name + ";" + location.getWorld().getName() + ";" + location.getX() + ";" + location.getY()
|
return name + ";" + location.getWorld().getName() + ";" + location.getX() + ";" + location.getY() + ";"
|
||||||
+ ";" + location.getZ();
|
+ location.getZ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Name: " + name + " World: " + location.getWorld().getName() + " Location: "
|
return "Name: " + name + " World: " + location.getWorld().getName() + " Location: " + location.getBlockX()
|
||||||
+ location.getBlockX() + "," + location.getBlockY() + "," + location.getBlockZ();
|
+ "," + location.getBlockY() + "," + location.getBlockZ();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -50,38 +50,12 @@ public class NMS {
|
|||||||
// util class
|
// util class
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendToOnline(Packet... packets) {
|
|
||||||
Validate.notNull(packets, "packets cannot be null");
|
|
||||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
|
||||||
if (player == null || !player.isOnline())
|
|
||||||
continue;
|
|
||||||
for (Packet packet : packets) {
|
|
||||||
sendPacket(player, packet);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void sendPacketNearby(Location location, Packet packet, double radius) {
|
|
||||||
radius *= radius;
|
|
||||||
final org.bukkit.World world = location.getWorld();
|
|
||||||
for (Player ply : Bukkit.getServer().getOnlinePlayers()) {
|
|
||||||
if (ply == null || world != ply.getWorld()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (location.distanceSquared(ply.getLocation()) > radius) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
sendPacket(ply, packet);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void sendPacketNearby(Location location, Packet packet) {
|
|
||||||
NMS.sendPacketNearby(location, packet, 64);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final float DEFAULT_SPEED = 0.4F;
|
private static final float DEFAULT_SPEED = 0.4F;
|
||||||
|
|
||||||
private static Map<Class<?>, Integer> ENTITY_CLASS_TO_INT;
|
private static Map<Class<?>, Integer> ENTITY_CLASS_TO_INT;
|
||||||
|
|
||||||
private static final Map<Class<?>, Constructor<?>> ENTITY_CONSTRUCTOR_CACHE = new WeakHashMap<Class<?>, Constructor<?>>();
|
private static final Map<Class<?>, Constructor<?>> ENTITY_CONSTRUCTOR_CACHE = new WeakHashMap<Class<?>, Constructor<?>>();
|
||||||
|
|
||||||
private static Map<Integer, Class<?>> ENTITY_INT_TO_CLASS;
|
private static Map<Integer, Class<?>> ENTITY_INT_TO_CLASS;
|
||||||
private static Field GOAL_FIELD;
|
private static Field GOAL_FIELD;
|
||||||
private static Field LAND_SPEED_MODIFIER_FIELD;
|
private static Field LAND_SPEED_MODIFIER_FIELD;
|
||||||
@ -92,9 +66,7 @@ public class NMS {
|
|||||||
private static Set<Integer> SLAB_MATERIALS = Sets.newHashSet();
|
private static Set<Integer> SLAB_MATERIALS = Sets.newHashSet();
|
||||||
private static Field SPEED_FIELD;
|
private static Field SPEED_FIELD;
|
||||||
private static Set<Integer> STAIR_MATERIALS = Sets.newHashSet();
|
private static Set<Integer> STAIR_MATERIALS = Sets.newHashSet();
|
||||||
|
|
||||||
private static Field THREAD_STOPPER;
|
private static Field THREAD_STOPPER;
|
||||||
|
|
||||||
public static void addOrRemoveFromPlayerList(LivingEntity bukkitEntity, boolean remove) {
|
public static void addOrRemoveFromPlayerList(LivingEntity bukkitEntity, boolean remove) {
|
||||||
if (bukkitEntity == null)
|
if (bukkitEntity == null)
|
||||||
return;
|
return;
|
||||||
@ -107,7 +79,6 @@ public class NMS {
|
|||||||
handle.world.players.add(handle);
|
handle.world.players.add(handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void attack(EntityLiving handle, EntityLiving target) {
|
public static void attack(EntityLiving handle, EntityLiving target) {
|
||||||
int damage = handle instanceof EntityMonster ? ((EntityMonster) handle).c((Entity) target) : 2;
|
int damage = handle instanceof EntityMonster ? ((EntityMonster) handle).c((Entity) target) : 2;
|
||||||
|
|
||||||
@ -157,8 +128,8 @@ public class NMS {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Constructor<?> getCustomEntityConstructor(Class<?> clazz, EntityType type)
|
private static Constructor<?> getCustomEntityConstructor(Class<?> clazz, EntityType type) throws SecurityException,
|
||||||
throws SecurityException, NoSuchMethodException {
|
NoSuchMethodException {
|
||||||
Constructor<?> constructor = ENTITY_CONSTRUCTOR_CACHE.get(clazz);
|
Constructor<?> constructor = ENTITY_CONSTRUCTOR_CACHE.get(clazz);
|
||||||
if (constructor == null) {
|
if (constructor == null) {
|
||||||
constructor = clazz.getConstructor(World.class);
|
constructor = clazz.getConstructor(World.class);
|
||||||
@ -241,6 +212,35 @@ public class NMS {
|
|||||||
((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
|
((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void sendPacketNearby(Location location, Packet packet) {
|
||||||
|
NMS.sendPacketNearby(location, packet, 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendPacketNearby(Location location, Packet packet, double radius) {
|
||||||
|
radius *= radius;
|
||||||
|
final org.bukkit.World world = location.getWorld();
|
||||||
|
for (Player ply : Bukkit.getServer().getOnlinePlayers()) {
|
||||||
|
if (ply == null || world != ply.getWorld()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (location.distanceSquared(ply.getLocation()) > radius) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sendPacket(ply, packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendToOnline(Packet... packets) {
|
||||||
|
Validate.notNull(packets, "packets cannot be null");
|
||||||
|
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||||
|
if (player == null || !player.isOnline())
|
||||||
|
continue;
|
||||||
|
for (Packet packet : packets) {
|
||||||
|
sendPacket(player, packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void setDestination(LivingEntity bukkitEntity, double x, double y, double z, float speed) {
|
public static void setDestination(LivingEntity bukkitEntity, double x, double y, double z, float speed) {
|
||||||
((CraftLivingEntity) bukkitEntity).getHandle().getControllerMove().a(x, y, z, speed);
|
((CraftLivingEntity) bukkitEntity).getHandle().getControllerMove().a(x, y, z, speed);
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,7 @@ public class Paginator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean sendPage(CommandSender sender, int page) {
|
public boolean sendPage(CommandSender sender, int page) {
|
||||||
int pages = (int) ((lines.size() / LINES_PER_PAGE == 0) ? 1 : Math.ceil((double) lines.size()
|
int pages = (int) ((lines.size() / LINES_PER_PAGE == 0) ? 1 : Math.ceil((double) lines.size() / LINES_PER_PAGE));
|
||||||
/ LINES_PER_PAGE));
|
|
||||||
if (page < 0 || page > pages)
|
if (page < 0 || page > pages)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -33,8 +33,8 @@ public enum PlayerAnimation {
|
|||||||
SLEEP {
|
SLEEP {
|
||||||
@Override
|
@Override
|
||||||
protected void playAnimation(EntityPlayer player, int radius) {
|
protected void playAnimation(EntityPlayer player, int radius) {
|
||||||
Packet17EntityLocationAction packet = new Packet17EntityLocationAction(player, 0,
|
Packet17EntityLocationAction packet = new Packet17EntityLocationAction(player, 0, (int) player.locX,
|
||||||
(int) player.locX, (int) player.locY, (int) player.locZ);
|
(int) player.locY, (int) player.locZ);
|
||||||
sendPacketNearby(packet, player, radius);
|
sendPacketNearby(packet, player, radius);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -42,8 +42,7 @@ public enum PlayerAnimation {
|
|||||||
@Override
|
@Override
|
||||||
protected void playAnimation(EntityPlayer player, int radius) {
|
protected void playAnimation(EntityPlayer player, int radius) {
|
||||||
player.getBukkitEntity().setSneaking(true);
|
player.getBukkitEntity().setSneaking(true);
|
||||||
sendPacketNearby(new Packet40EntityMetadata(player.id, player.getDataWatcher(), true), player,
|
sendPacketNearby(new Packet40EntityMetadata(player.id, player.getDataWatcher(), true), player, radius);
|
||||||
radius);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
STOP_SITTING {
|
STOP_SITTING {
|
||||||
@ -63,8 +62,7 @@ public enum PlayerAnimation {
|
|||||||
@Override
|
@Override
|
||||||
protected void playAnimation(EntityPlayer player, int radius) {
|
protected void playAnimation(EntityPlayer player, int radius) {
|
||||||
player.getBukkitEntity().setSneaking(false);
|
player.getBukkitEntity().setSneaking(false);
|
||||||
sendPacketNearby(new Packet40EntityMetadata(player.id, player.getDataWatcher(), true), player,
|
sendPacketNearby(new Packet40EntityMetadata(player.id, player.getDataWatcher(), true), player, radius);
|
||||||
radius);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -93,7 +93,6 @@ public class StringHelper {
|
|||||||
String colors = "";
|
String colors = "";
|
||||||
for (ChatColor color : ChatColor.values())
|
for (ChatColor color : ChatColor.values())
|
||||||
colors += color.getChar();
|
colors += color.getChar();
|
||||||
COLOR_MATCHER = Pattern.compile("\\<([COLORS])\\>".replace("COLORS", colors),
|
COLOR_MATCHER = Pattern.compile("\\<([COLORS])\\>".replace("COLORS", colors), Pattern.CASE_INSENSITIVE);
|
||||||
Pattern.CASE_INSENSITIVE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -37,8 +37,8 @@ public class Translator {
|
|||||||
this.resourceFile = resourceFile;
|
this.resourceFile = resourceFile;
|
||||||
this.defaultLocale = locale;
|
this.defaultLocale = locale;
|
||||||
try {
|
try {
|
||||||
preferredBundle = ResourceBundle.getBundle(PREFIX, defaultLocale, new FileClassLoader(
|
preferredBundle = ResourceBundle.getBundle(PREFIX, defaultLocale,
|
||||||
Translator.class.getClassLoader(), resourceFile));
|
new FileClassLoader(Translator.class.getClassLoader(), resourceFile));
|
||||||
} catch (MissingResourceException e) {
|
} catch (MissingResourceException e) {
|
||||||
preferredBundle = getDefaultBundle();
|
preferredBundle = getDefaultBundle();
|
||||||
Messaging.log(translate(Messages.MISSING_TRANSLATIONS, locale));
|
Messaging.log(translate(Messages.MISSING_TRANSLATIONS, locale));
|
||||||
@ -53,8 +53,8 @@ public class Translator {
|
|||||||
|
|
||||||
private ResourceBundle getBundle(Locale locale) {
|
private ResourceBundle getBundle(Locale locale) {
|
||||||
try {
|
try {
|
||||||
ResourceBundle bundle = ResourceBundle.getBundle(PREFIX, locale, new FileClassLoader(
|
ResourceBundle bundle = ResourceBundle.getBundle(PREFIX, locale,
|
||||||
Translator.class.getClassLoader(), resourceFile));
|
new FileClassLoader(Translator.class.getClassLoader(), resourceFile));
|
||||||
return bundle == null ? preferredBundle : bundle;
|
return bundle == null ? preferredBundle : bundle;
|
||||||
} catch (MissingResourceException e) {
|
} catch (MissingResourceException e) {
|
||||||
return preferredBundle;
|
return preferredBundle;
|
||||||
@ -275,8 +275,8 @@ public class Translator {
|
|||||||
public static String translate(String key, Locale preferredLocale, Object... msg) {
|
public static String translate(String key, Locale preferredLocale, Object... msg) {
|
||||||
if (instance == null)
|
if (instance == null)
|
||||||
createInstance();
|
createInstance();
|
||||||
return StringHelper.parseColors(msg.length == 0 ? instance.translate(key, preferredLocale) : instance
|
return StringHelper.parseColors(msg.length == 0 ? instance.translate(key, preferredLocale) : instance.format(
|
||||||
.format(key, preferredLocale, msg));
|
key, preferredLocale, msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String translate(String key, Object... msg) {
|
public static String translate(String key, Object... msg) {
|
||||||
|
Loading…
Reference in New Issue
Block a user