Support blank cosmetic

This commit is contained in:
fullwall 2024-10-28 01:19:30 +08:00
parent 72dabc2c2d
commit 0b978f6322
3 changed files with 39 additions and 9 deletions

View File

@ -17,14 +17,15 @@ import net.citizensnpcs.api.gui.MenuSlot;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.trait.trait.Equipment;
import net.citizensnpcs.api.trait.trait.Equipment.EquipmentSlot;
import net.citizensnpcs.util.Util;
@Menu(title = "NPC Equipment", type = InventoryType.CHEST, dimensions = { 3, 9 })
@MenuSlot(slot = { 0, 0 }, material = Material.DIAMOND_SWORD, lore = "Place in hand item below", amount = 1)
@MenuSlot(
slot = { 0, 1 },
compatMaterial = { "SHIELD", "BARRIER", "FIRE" },
lore = "Place offhand item below",
amount = 1)
@MenuSlot(slot = { 0, 0 }, material = Material.DIAMOND_SWORD, lore = "Place in hand item below", amount = 1)
@MenuSlot(slot = { 0, 2 }, material = Material.DIAMOND_HELMET, lore = "Place helmet below", amount = 1)
@MenuSlot(slot = { 0, 3 }, material = Material.DIAMOND_CHESTPLATE, lore = "Place chestplate below", amount = 1)
@MenuSlot(slot = { 0, 4 }, material = Material.DIAMOND_LEGGINGS, lore = "Place leggings below", amount = 1)
@ -48,27 +49,31 @@ public class GenericEquipperGUI extends InventoryMenuPage {
ctx.getSlot(1 * 9 + i).setItemStack(trait.get(slot));
if (trait.getCosmetic(slot) != null) {
ctx.getSlot(2 * 9 + i).setItemStack(trait.getCosmetic(slot));
} else {
ctx.getSlot(2 * 9 + i).setItemStack(Util.createItem(Util.getFallbackMaterial("BARRIER", "FIRE"),
"No cosmetic", "Click to enable cosmetic for this equipment"));
}
Function<Material, Boolean> filter = type -> true;
Function<ItemStack, Boolean> filter = type -> true;
switch (slot) {
case BOOTS:
case LEGGINGS:
filter = type -> type.name().endsWith(slot.name());
filter = stack -> Util.isEquippable(stack, slot) || stack.getType().name().endsWith(slot.name());
break;
case CHESTPLATE:
filter = type -> type == Material.ELYTRA || type.name().endsWith(slot.name());
filter = stack -> Util.isEquippable(stack, slot) || stack.getType() == Material.ELYTRA
|| stack.getType().name().endsWith(slot.name());
default:
break;
}
Function<Material, Boolean> ffilter = filter;
Function<ItemStack, Boolean> ffilter = filter;
ctx.getSlot(1 * 9 + i).addClickHandler(event -> set(slot, event, ffilter));
ctx.getSlot(2 * 9 + i).addClickHandler(event -> setCosmetic(slot, event, ffilter));
}
}
private void set(EquipmentSlot slot, CitizensInventoryClickEvent event, Function<Material, Boolean> filter) {
private void set(EquipmentSlot slot, CitizensInventoryClickEvent event, Function<ItemStack, Boolean> filter) {
ItemStack result = event.getResultItemNonNull();
if (event.isCancelled() || (result.getType() != Material.AIR && !filter.apply(result.getType()))) {
if (event.isCancelled() || (result.getType() != Material.AIR && !filter.apply(result))) {
event.setResult(Result.DENY);
return;
}
@ -76,9 +81,21 @@ public class GenericEquipperGUI extends InventoryMenuPage {
}
private void setCosmetic(EquipmentSlot slot, CitizensInventoryClickEvent event,
Function<Material, Boolean> filter) {
Function<ItemStack, Boolean> filter) {
if (event.getCursorNonNull().getType() == Material.AIR) {
if (event.getCurrentItemNonNull().getType() == Util.getFallbackMaterial("BARRIER", "FIRE")) {
event.setCurrentItem(null);
npc.getOrAddTrait(Equipment.class).setCosmetic(slot, new ItemStack(Material.AIR, 1));
} else if (event.getCurrentItem() == null) {
event.setCurrentItem(Util.createItem(Util.getFallbackMaterial("BARRIER", "FIRE"), "No cosmetic",
"Click to enable cosmetic for this equipment"));
npc.getOrAddTrait(Equipment.class).setCosmetic(slot, null);
}
event.setResult(Result.DENY);
return;
}
ItemStack result = event.getResultItemNonNull();
if (event.isCancelled() || (result.getType() != Material.AIR && !filter.apply(result.getType()))) {
if (event.isCancelled() || (result.getType() != Material.AIR && !filter.apply(result))) {
event.setResult(Result.DENY);
return;
}

View File

@ -93,6 +93,7 @@ public class Messages {
public static final String CONTROLLABLE_SET = "citizens.commands.npc.controllable.set";
public static final String COPIER_EDITOR_BEGIN = "citizens.editors.copier.begin";
public static final String COPIER_EDITOR_END = "citizens.editors.copier.end";
public static final String COSMETIC_EQUIPMENT_SET = "citizens.commands.npc.setequipment.cosmetic-set";
public static final String CURRENT_WAYPOINT_PROVIDER = "citizens.waypoints.current-provider";
public static final String DEFAULT_POSE_SET = "citizens.commands.npc.pose.default-pose-set";
public static final String DELAY_TRIGGER_PROMPT = "citizens.editors.waypoints.triggers.delay.prompt";

View File

@ -51,6 +51,7 @@ import net.citizensnpcs.api.event.NPCCollisionEvent;
import net.citizensnpcs.api.event.NPCPistonPushEvent;
import net.citizensnpcs.api.event.NPCPushEvent;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.trait.trait.Equipment.EquipmentSlot;
import net.citizensnpcs.api.util.BoundingBox;
import net.citizensnpcs.api.util.Messaging;
import net.citizensnpcs.api.util.Placeholders;
@ -300,6 +301,11 @@ public class Util {
return BEDROCK_NAME_PREFIX != null ? name.startsWith(BEDROCK_NAME_PREFIX) : false;
}
public static boolean isEquippable(ItemStack stack, EquipmentSlot slot) {
return SUPPORTS_HAS_EQUIPPABLE && stack.hasItemMeta() && stack.getItemMeta().hasEquippable()
&& stack.getItemMeta().getEquippable().getSlot() == slot.toBukkit();
}
public static boolean isHorse(EntityType type) {
String name = type.name();
return type == EntityType.HORSE || name.contains("_HORSE") || name.equals("DONKEY") || name.equals("MULE")
@ -622,6 +628,7 @@ public class Util {
private static String BEDROCK_NAME_PREFIX = ".";
private static Scoreboard DUMMY_SCOREBOARD;
private static boolean SUPPORTS_BUKKIT_GETENTITY = true;
private static boolean SUPPORTS_HAS_EQUIPPABLE = false;
private static final DecimalFormat TWO_DIGIT_DECIMAL = new DecimalFormat();
static {
@ -630,6 +637,11 @@ public class Util {
} catch (NullPointerException e) {
}
TWO_DIGIT_DECIMAL.setMaximumFractionDigits(2);
try {
ItemMeta.class.getMethod("hasEquippable");
} catch (NoSuchMethodException e) {
SUPPORTS_HAS_EQUIPPABLE = false;
}
try {
Bukkit.class.getMethod("getEntity", UUID.class);
} catch (Exception e) {