mirror of
https://github.com/CitizensDev/Citizens2.git
synced 2024-12-23 01:27:33 +01:00
Implement new /template generate command, bugfixes
This commit is contained in:
parent
e8eadbfa36
commit
224b43d75b
@ -405,8 +405,10 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
|
||||
traitFactory = new CitizensTraitFactory(this);
|
||||
traitFactory.registerTrait(TraitInfo.create(ShopTrait.class).withSupplier(() -> new ShopTrait(shops)));
|
||||
selector = new NPCSelector(this);
|
||||
templateRegistry = new TemplateRegistry(new File(this.getDataFolder(), "templates").toPath());
|
||||
|
||||
templateRegistry = new TemplateRegistry(new File(getDataFolder(), "templates").toPath());
|
||||
if (!new File(getDataFolder(), "skins").exists()) {
|
||||
new File(getDataFolder(), "skins").mkdir();
|
||||
}
|
||||
Bukkit.getPluginManager().registerEvents(new EventListen(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new Placeholders(), this);
|
||||
|
||||
|
@ -456,6 +456,7 @@ public class EventListen implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onNPCKnockback(NPCKnockbackEvent event) {
|
||||
event.setCancelled(event.getNPC().isProtected());
|
||||
if (event.getNPC().data().has(NPC.Metadata.KNOCKBACK)) {
|
||||
event.setCancelled(!event.getNPC().data().get(NPC.Metadata.KNOCKBACK, true));
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ public class Settings {
|
||||
"npc.pathfinding.default-distance-margin", 1),
|
||||
DEFAULT_HOLOGRAM_RENDERER(
|
||||
"The default renderer for holograms, must be one of the following:<br>interaction - matches inbuilt nametags most closely<br>display - allows for different colored backgrounds<br>armorstand - creates an armorstand and teleports it to the player",
|
||||
"npc.hologram.default-renderer", "interaction"),
|
||||
"npc.hologram.default-renderer", "display"),
|
||||
DEFAULT_LOOK_CLOSE("Enable look close by default", "npc.default.look-close.enabled", false),
|
||||
DEFAULT_LOOK_CLOSE_RANGE("Default look close range in blocks", "npc.default.look-close.range", 10),
|
||||
DEFAULT_NPC_HOLOGRAM_LINE_HEIGHT("Default distance between hologram lines", "npc.hologram.default-line-height",
|
||||
|
@ -23,6 +23,7 @@ import org.bukkit.DyeColor;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.Rotation;
|
||||
import org.bukkit.Sound;
|
||||
@ -893,7 +894,9 @@ public class NPCCommands {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (String part : parts) {
|
||||
if (part.contains(":")) {
|
||||
Template template = templateRegistry.getTemplateByNamespacedKey(part);
|
||||
int idx = part.indexOf(':');
|
||||
Template template = templateRegistry
|
||||
.getTemplateByKey(new NamespacedKey(part.substring(0, idx), part.substring(idx + 1)));
|
||||
if (template == null)
|
||||
continue;
|
||||
template.apply(npc);
|
||||
@ -3347,7 +3350,8 @@ public class NPCCommands {
|
||||
modifiers = { "tpto" },
|
||||
min = 2,
|
||||
max = 3,
|
||||
permission = "citizens.npc.tpto")
|
||||
permission = "citizens.npc.tpto",
|
||||
parsePlaceholders = true)
|
||||
@Requirements
|
||||
public void tpto(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||
Entity from = null, to = null;
|
||||
|
@ -3,6 +3,7 @@ package net.citizensnpcs.commands;
|
||||
import java.util.Collection;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
@ -36,25 +37,47 @@ public class TemplateCommands {
|
||||
min = 2,
|
||||
permission = "citizens.templates.apply")
|
||||
public void apply(CommandContext args, CommandSender sender, NPC npc,
|
||||
@Arg(value = 1, completionsProvider = TemplateCompletions.class) String templateName)
|
||||
@Arg(value = 1, completionsProvider = TemplateCompletions.class) String templateKey)
|
||||
throws CommandException {
|
||||
Template template = null;
|
||||
if (templateName.contains(":")) {
|
||||
template = registry.getTemplateByNamespacedKey(templateName);
|
||||
if (templateKey.contains(":")) {
|
||||
int idx = templateKey.indexOf(':');
|
||||
template = registry
|
||||
.getTemplateByKey(new NamespacedKey(templateKey.substring(0, idx), templateKey.substring(idx + 1)));
|
||||
} else {
|
||||
Collection<Template> templates = registry.getTemplates(templateName);
|
||||
Collection<Template> templates = registry.getTemplates(templateKey);
|
||||
if (templates.isEmpty())
|
||||
throw new CommandException(Messages.TEMPLATE_MISSING);
|
||||
if (templates.size() > 1)
|
||||
throw new CommandException(Messages.TEMPLATE_PICKER, templateName, Joiner.on(", ").join(templates
|
||||
.stream().map(t -> t.getNamespace() + ":" + t.getName()).collect(Collectors.toList())));
|
||||
throw new CommandException(Messages.TEMPLATE_PICKER, templateKey,
|
||||
Joiner.on(", ").join(templates.stream().map(t -> t.getKey()).collect(Collectors.toList())));
|
||||
template = templates.iterator().next();
|
||||
}
|
||||
if (template == null)
|
||||
throw new CommandException(Messages.TEMPLATE_MISSING);
|
||||
|
||||
template.apply(npc);
|
||||
Messaging.sendTr(sender, Messages.TEMPLATE_APPLIED, template.getName(), npc.getName());
|
||||
Messaging.sendTr(sender, Messages.TEMPLATE_APPLIED, template.getKey().getKey(), npc.getName());
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "template", "tpl" },
|
||||
usage = "generate (template namespace:)[name]",
|
||||
desc = "",
|
||||
modifiers = { "generate" },
|
||||
min = 2,
|
||||
max = 2,
|
||||
permission = "citizens.templates.generate")
|
||||
public void generate(CommandContext args, CommandSender sender, NPC npc,
|
||||
@Arg(value = 1, completionsProvider = TemplateCompletions.class) String templateName)
|
||||
throws CommandException {
|
||||
int idx = templateName.indexOf(':');
|
||||
NamespacedKey key = idx == -1 ? new NamespacedKey("generated", templateName)
|
||||
: new NamespacedKey(templateName.substring(0, idx), templateName.substring(idx + 1));
|
||||
if (registry.getTemplateByKey(key) != null)
|
||||
throw new CommandException(Messages.TEMPLATE_CONFLICT);
|
||||
registry.generateTemplateFromNPC(key, npc);
|
||||
Messaging.sendTr(sender, Messages.TEMPLATE_GENERATED, npc.getName());
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -68,7 +91,7 @@ public class TemplateCommands {
|
||||
public void list(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||
Messaging.sendTr(sender, Messages.TEMPLATE_LIST_HEADER);
|
||||
for (Template template : registry.getAllTemplates()) {
|
||||
Messaging.send(sender, "[[-]] " + template.getNamespace() + ":" + template.getName());
|
||||
Messaging.send(sender, "[[-]] " + template.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,7 +104,7 @@ public class TemplateCommands {
|
||||
|
||||
@Override
|
||||
public Collection<String> getCompletions(CommandContext args, CommandSender sender, NPC npc) {
|
||||
return templateRegistry.getAllTemplates().stream().map(t -> t.getNamespace() + ":" + t.getName())
|
||||
return templateRegistry.getAllTemplates().stream().map(t -> t.getKey().toString())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,8 @@ import net.citizensnpcs.api.util.DataKey;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
|
||||
/**
|
||||
* Persists the current {@link Location} of the {@link NPC}. Will cache last known location if despawned.
|
||||
* Persists the current {@link Location} of the {@link net.citizensnpcs.api.npc.NPC}. Will cache last known location if
|
||||
* despawned.
|
||||
*/
|
||||
@TraitName("location")
|
||||
public class CurrentLocation extends Trait {
|
||||
|
@ -28,6 +28,8 @@ import net.citizensnpcs.api.util.SpigotUtil;
|
||||
import net.citizensnpcs.util.InventoryMultiplexer;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
import net.citizensnpcs.util.Util;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitComponentSerializer;
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
||||
public class ItemAction extends NPCShopAction {
|
||||
@Persist
|
||||
@ -53,11 +55,11 @@ public class ItemAction extends NPCShopAction {
|
||||
@Override
|
||||
public String describe() {
|
||||
if (items.size() == 1)
|
||||
return items.get(0).getAmount() + " " + Util.prettyEnum(items.get(0).getType());
|
||||
return stringify(items.get(0));
|
||||
String description = items.size() + " items";
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
ItemStack item = items.get(i);
|
||||
description += "\n" + item.getAmount() + " " + Util.prettyEnum(item.getType());
|
||||
description += "\n" + stringify(item);
|
||||
if (i == 3) {
|
||||
description += "...";
|
||||
break;
|
||||
@ -155,6 +157,7 @@ public class ItemAction extends NPCShopAction {
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private boolean metaMatches(ItemStack needle, ItemStack haystack, List<String> meta) {
|
||||
Map<String, Object> source = NMS.getComponentMap(needle);
|
||||
Map<String, Object> compare = NMS.getComponentMap(haystack);
|
||||
@ -178,6 +181,14 @@ public class ItemAction extends NPCShopAction {
|
||||
return true;
|
||||
}
|
||||
|
||||
private String stringify(ItemStack item) {
|
||||
if (SUPPORT_TRANSLATABLE) {
|
||||
return BukkitComponentSerializer.legacy().serialize(Component.text(item.getAmount() + " ")
|
||||
.append(Component.translatable().key(item.getTranslationKey())));
|
||||
}
|
||||
return item.getAmount() + " " + Util.prettyEnum(item.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transaction take(Entity entity, InventoryMultiplexer im, int repeats) {
|
||||
if (!(entity instanceof InventoryHolder))
|
||||
@ -314,4 +325,14 @@ public class ItemAction extends NPCShopAction {
|
||||
return action instanceof ItemAction;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean SUPPORT_TRANSLATABLE = true;
|
||||
|
||||
static {
|
||||
try {
|
||||
Class.forName("org.bukkit.Translatable");
|
||||
} catch (ClassNotFoundException e) {
|
||||
SUPPORT_TRANSLATABLE = false;
|
||||
}
|
||||
}
|
||||
}
|
@ -414,6 +414,7 @@ public class Messages {
|
||||
public static final String TEMPLATE_APPLIED = "citizens.commands.template.applied";
|
||||
public static final String TEMPLATE_CONFLICT = "citizens.commands.template.conflict";
|
||||
public static final String TEMPLATE_DELETED = "citizens.commands.template.delete.deleted";
|
||||
public static final String TEMPLATE_GENERATED = "citizens.commands.template.generate.generated";
|
||||
public static final String TEMPLATE_LIST_HEADER = "citizens.commands.template.list.header";
|
||||
public static final String TEMPLATE_MISSING = "citizens.commands.template.missing";
|
||||
public static final String TEMPLATE_NAMESPACE_EXISTS = "citizens.commands.template.namespace-already-exists";
|
||||
|
@ -30,7 +30,7 @@ public class MojangSkinGenerator {
|
||||
con.setRequestProperty("User-Agent", "Citizens/2.0");
|
||||
con.setRequestProperty("Cache-Control", "no-cache");
|
||||
con.setRequestProperty("Content-Type", "multipart/form-data;boundary=*****");
|
||||
con.setConnectTimeout(1000);
|
||||
con.setConnectTimeout(2000);
|
||||
con.setReadTimeout(30000);
|
||||
out = new DataOutputStream(con.getOutputStream());
|
||||
out.writeBytes("--*****\r\n");
|
||||
@ -91,7 +91,7 @@ public class MojangSkinGenerator {
|
||||
con.setRequestProperty("Cache-Control", "no-cache");
|
||||
con.setRequestProperty("Accept", "application/json");
|
||||
con.setRequestProperty("Content-Type", "application/json");
|
||||
con.setConnectTimeout(1000);
|
||||
con.setConnectTimeout(2000);
|
||||
con.setReadTimeout(30000);
|
||||
out = new DataOutputStream(con.getOutputStream());
|
||||
JSONObject req = new JSONObject();
|
||||
|
@ -618,6 +618,8 @@
|
||||
"citizens.commands.requirements.must-have-selected" : "You must have an NPC selected to execute that command.",
|
||||
"citizens.commands.requirements.too-few-arguments" : "Too few arguments.",
|
||||
"citizens.commands.requirements.too-many-arguments" : "Too many arguments. ",
|
||||
"citizens.commands.template.generate.generated" : "Generated template from [[{0}]]",
|
||||
"citizens.commands.template.generate.description" : "Generate a template from the selected NPC",
|
||||
"citizens.commands.template.applied" : "Applied [[{0}]] to [[{1}]].",
|
||||
"citizens.commands.template.apply.description" : "Applies a template to the selected NPC",
|
||||
"citizens.commands.template.apply.help" : "",
|
||||
|
@ -700,7 +700,8 @@ public class NMSImpl implements NMSBridge {
|
||||
|
||||
@Override
|
||||
public float getRidingHeightOffset(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity mount) {
|
||||
return (float) getHandle(entity).getPassengerRidingPosition(getHandle(mount)).y;
|
||||
Entity handle = getHandle(entity);
|
||||
return (float) (handle.getPassengerRidingPosition(getHandle(mount)).y - handle.position().y);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -911,8 +912,7 @@ public class NMSImpl implements NMSBridge {
|
||||
@Override
|
||||
public void linkTextInteraction(org.bukkit.entity.Player player, org.bukkit.entity.Entity entity,
|
||||
org.bukkit.entity.Entity mount, double offset) {
|
||||
Interaction handle = (Interaction) getHandle(entity);
|
||||
offset += handle.getPassengerRidingPosition(getHandle(mount)).y;
|
||||
offset += getRidingHeightOffset(entity, mount);
|
||||
sendPacket(player,
|
||||
new ClientboundBundlePacket(List.of(
|
||||
new ClientboundSetEntityDataPacket(entity.getEntityId(),
|
||||
|
Loading…
Reference in New Issue
Block a user