Add new pig equipper GUI

This commit is contained in:
fullwall 2021-01-31 18:29:44 +08:00
parent 47707fe628
commit f1c2fcbe37
6 changed files with 205 additions and 248 deletions

View File

@ -20,6 +20,7 @@ import com.google.common.collect.Maps;
import net.citizensnpcs.api.CitizensAPI; import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.gui.InventoryMenu; import net.citizensnpcs.api.gui.InventoryMenu;
import net.citizensnpcs.api.gui.InventoryMenuPage;
import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.trait.trait.Equipment; import net.citizensnpcs.api.trait.trait.Equipment;
import net.citizensnpcs.api.trait.trait.Equipment.EquipmentSlot; import net.citizensnpcs.api.trait.trait.Equipment.EquipmentSlot;
@ -39,10 +40,11 @@ public class EquipmentEditor extends Editor {
@Override @Override
public void begin() { public void begin() {
if (!EQUIPPERS.containsKey(npc.getEntity().getType())) { if (EQUIPPER_GUIS.containsKey(npc.getEntity().getType()) || !EQUIPPERS.containsKey(npc.getEntity().getType())) {
Map<String, Object> ctx = Maps.newHashMap(); Map<String, Object> ctx = Maps.newHashMap();
ctx.put("npc", npc); ctx.put("npc", npc);
menu = InventoryMenu.createWithContext(EquipmentGUI.class, ctx); menu = InventoryMenu.createWithContext(
EQUIPPER_GUIS.getOrDefault(npc.getEntity().getType(), GenericEquipperGUI.class), ctx);
menu.present(player); menu.present(player);
return; return;
} }
@ -124,17 +126,16 @@ public class EquipmentEditor extends Editor {
|| !npc.equals(CitizensAPI.getNPCRegistry().getNPC(event.getRightClicked()))) || !npc.equals(CitizensAPI.getNPCRegistry().getNPC(event.getRightClicked())))
return; return;
Equipper equipper = EQUIPPERS.get(npc.getEntity().getType()); Equipper equipper = EQUIPPERS.get(npc.getEntity().getType());
if (equipper == null) {
equipper = new GenericEquipper();
}
equipper.equip(event.getPlayer(), npc); equipper.equip(event.getPlayer(), npc);
event.setCancelled(true); event.setCancelled(true);
} }
private static final Map<EntityType, Class<? extends InventoryMenuPage>> EQUIPPER_GUIS = Maps
.newEnumMap(EntityType.class);
private static final Map<EntityType, Equipper> EQUIPPERS = Maps.newEnumMap(EntityType.class); private static final Map<EntityType, Equipper> EQUIPPERS = Maps.newEnumMap(EntityType.class);
static { static {
EQUIPPERS.put(EntityType.PIG, new PigEquipper()); EQUIPPER_GUIS.put(EntityType.PIG, PigEquipperGUI.class);
EQUIPPERS.put(EntityType.SHEEP, new SheepEquipper()); EQUIPPERS.put(EntityType.SHEEP, new SheepEquipper());
EQUIPPERS.put(EntityType.ENDERMAN, new EndermanEquipper()); EQUIPPERS.put(EntityType.ENDERMAN, new EndermanEquipper());
EQUIPPERS.put(EntityType.HORSE, new HorseEquipper()); EQUIPPERS.put(EntityType.HORSE, new HorseEquipper());

View File

@ -1,130 +0,0 @@
package net.citizensnpcs.editor;
import java.util.function.Function;
import org.bukkit.Material;
import org.bukkit.event.Event.Result;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.ItemStack;
import net.citizensnpcs.api.gui.ClickHandler;
import net.citizensnpcs.api.gui.InjectContext;
import net.citizensnpcs.api.gui.InventoryMenuPage;
import net.citizensnpcs.api.gui.InventoryMenuSlot;
import net.citizensnpcs.api.gui.Menu;
import net.citizensnpcs.api.gui.MenuContext;
import net.citizensnpcs.api.gui.MenuPattern;
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;
@Menu(title = "NPC Equipment", type = InventoryType.CHEST, dimensions = { 2, 5 })
@MenuSlot(slot = { 0, 2 }, material = Material.DIAMOND_HELMET, amount = 1, filter = InventoryAction.UNKNOWN)
@MenuSlot(slot = { 0, 4 }, material = Material.DIAMOND_LEGGINGS, amount = 1, filter = InventoryAction.UNKNOWN)
@MenuSlot(slot = { 0, 1 }, material = Material.ELYTRA, amount = 1, filter = InventoryAction.UNKNOWN)
@MenuSlot(slot = { 0, 0 }, material = Material.DIAMOND_SWORD, amount = 1, filter = InventoryAction.UNKNOWN)
@MenuSlot(slot = { 0, 3 }, material = Material.DIAMOND_CHESTPLATE, amount = 1, filter = InventoryAction.UNKNOWN)
@MenuSlot(slot = { 0, 5 }, material = Material.DIAMOND_BOOTS, amount = 1, filter = InventoryAction.UNKNOWN)
@MenuPattern(offset = { 0, 6 }, slots = { @MenuSlot(filter = InventoryAction.UNKNOWN, pat = 'x') }, value = "xxx\nxxx")
public class EquipmentGUI extends InventoryMenuPage {
@MenuSlot(slot = { 1, 5 })
private InventoryMenuSlot boots;
@MenuSlot(slot = { 1, 3 })
private InventoryMenuSlot chest;
@MenuSlot(slot = { 1, 0 })
private InventoryMenuSlot hand;
@MenuSlot(slot = { 1, 2 })
private InventoryMenuSlot helmet;
@MenuSlot(slot = { 1, 4 })
private InventoryMenuSlot leggings;
@InjectContext
private NPC npc;
@MenuSlot(slot = { 1, 1 })
private InventoryMenuSlot offhand;
// TODO: move into API?
private ItemStack getResult(InventoryClickEvent event) {
ItemStack stack = event.getCurrentItem() == null ? new ItemStack(event.getCursor().getType(), 0)
: event.getCurrentItem().clone();
switch (event.getAction()) {
case PICKUP_ONE:
stack.setAmount(stack.getAmount() - 1);
break;
case PICKUP_HALF:
stack.setAmount((int) Math.floor(stack.getAmount() / 2.0));
break;
case PICKUP_ALL:
stack = null;
break;
case PLACE_ALL:
stack.setAmount(
Math.min(stack.getAmount() + event.getCursor().getAmount(), stack.getType().getMaxStackSize()));
break;
case PLACE_SOME:
stack.setAmount(Math.min(stack.getAmount(), stack.getType().getMaxStackSize()));
break;
case PLACE_ONE:
stack.setAmount(stack.getAmount() + 1);
break;
default:
event.setCancelled(true);
event.setResult(Result.DENY);
return null;
}
return stack;
}
@Override
public void initialise(MenuContext ctx) {
Equipment trait = npc.getOrAddTrait(Equipment.class);
hand.setItemStack(trait.get(EquipmentSlot.HAND));
helmet.setItemStack(trait.get(EquipmentSlot.HELMET));
chest.setItemStack(trait.get(EquipmentSlot.CHESTPLATE));
leggings.setItemStack(trait.get(EquipmentSlot.LEGGINGS));
boots.setItemStack(trait.get(EquipmentSlot.BOOTS));
offhand.setItemStack(trait.get(EquipmentSlot.OFF_HAND));
}
private void set(EquipmentSlot slot, InventoryClickEvent event, Function<Material, Boolean> filter) {
ItemStack result = getResult(event);
if (event.isCancelled() || (result != null && !filter.apply(result.getType()))) {
event.setResult(Result.DENY);
return;
}
npc.getOrAddTrait(Equipment.class).set(slot, result);
}
@ClickHandler(slot = { 1, 5 })
public void setBoots(InventoryMenuSlot slot, InventoryClickEvent event) {
set(EquipmentSlot.BOOTS, event, (type) -> type.name().endsWith("BOOTS"));
}
@ClickHandler(slot = { 1, 3 })
public void setChest(InventoryMenuSlot slot, InventoryClickEvent event) {
set(EquipmentSlot.CHESTPLATE, event,
(type) -> type.name().endsWith("CHESTPLATE") || type.name().equals("ELYTRA"));
}
@ClickHandler(slot = { 1, 0 })
public void setHand(InventoryMenuSlot slot, InventoryClickEvent event) {
set(EquipmentSlot.HAND, event, (type) -> true);
}
@ClickHandler(slot = { 1, 2 })
public void setHelmet(InventoryMenuSlot slot, InventoryClickEvent event) {
set(EquipmentSlot.HELMET, event, (type) -> true);
}
@ClickHandler(slot = { 1, 4 })
public void setLeggings(InventoryMenuSlot slot, InventoryClickEvent event) {
set(EquipmentSlot.LEGGINGS, event, (type) -> type.name().endsWith("LEGGINGS"));
}
@ClickHandler(slot = { 1, 1 })
public void setOffhand(InventoryMenuSlot slot, InventoryClickEvent event) {
set(EquipmentSlot.OFF_HAND, event, (type) -> true);
}
}

View File

@ -1,81 +0,0 @@
package net.citizensnpcs.editor;
import java.util.EnumSet;
import java.util.Set;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.trait.trait.Equipment;
import net.citizensnpcs.api.trait.trait.Equipment.EquipmentSlot;
import net.citizensnpcs.api.util.Messaging;
import net.citizensnpcs.api.util.SpigotUtil;
import net.citizensnpcs.util.Messages;
public class GenericEquipper implements Equipper {
@Override
public void equip(Player equipper, NPC toEquip) {
ItemStack hand = equipper.getInventory().getItemInHand();
Equipment trait = toEquip.getOrAddTrait(Equipment.class);
EquipmentSlot slot = EquipmentSlot.HAND;
Material type = hand == null ? Material.AIR : hand.getType();
// First, determine the slot to edit
if (type.name().equals("ELYTRA") && !equipper.isSneaking()) {
slot = EquipmentSlot.CHESTPLATE;
} else {
if (type.name().endsWith("HELMET") || HELMETS.contains(type)) {
if (!equipper.isSneaking()) {
slot = EquipmentSlot.HELMET;
}
} else if (type.name().endsWith("CHESTPLATE")) {
if (!equipper.isSneaking()) {
slot = EquipmentSlot.CHESTPLATE;
}
} else if (type.name().endsWith("LEGGINGS")) {
if (!equipper.isSneaking()) {
slot = EquipmentSlot.LEGGINGS;
}
} else if (type.name().endsWith("BOOTS")) {
if (!equipper.isSneaking()) {
slot = EquipmentSlot.BOOTS;
}
} else if (type == Material.AIR) {
if (equipper.isSneaking()) {
for (int i = 0; i < 6; i++) {
if (trait.get(i) != null && trait.get(i).getType() != Material.AIR) {
equipper.getWorld().dropItemNaturally(toEquip.getEntity().getLocation(), trait.get(i));
trait.set(i, null);
}
}
Messaging.sendTr(equipper, Messages.EQUIPMENT_EDITOR_ALL_ITEMS_REMOVED, toEquip.getName());
} else {
return;
}
}
}
// Drop any previous equipment on the ground
ItemStack equippedItem = trait.get(slot);
if (equippedItem != null && equippedItem.getType() != Material.AIR) {
equipper.getWorld().dropItemNaturally(toEquip.getEntity().getLocation(), equippedItem);
}
// Now edit the equipment based on the slot
if (type != Material.AIR) {
// Set the proper slot with one of the item
ItemStack clone = hand.clone();
clone.setAmount(1);
trait.set(slot, clone);
hand.setAmount(hand.getAmount() - 1);
equipper.getInventory().setItemInHand(hand);
}
}
private static Set<Material> HELMETS = SpigotUtil.isUsing1_13API()
? EnumSet.of(Material.PUMPKIN, Material.JACK_O_LANTERN, Material.CREEPER_HEAD, Material.DRAGON_HEAD,
Material.PLAYER_HEAD, Material.SKELETON_SKULL, Material.ZOMBIE_HEAD, Material.WITHER_SKELETON_SKULL)
: EnumSet.of(Material.PUMPKIN, Material.JACK_O_LANTERN, Material.valueOf("SKULL_ITEM"));
}

View File

@ -0,0 +1,135 @@
package net.citizensnpcs.editor;
import java.util.function.Function;
import org.bukkit.Material;
import org.bukkit.event.Event.Result;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.ItemStack;
import net.citizensnpcs.api.gui.CitizensInventoryClickEvent;
import net.citizensnpcs.api.gui.ClickHandler;
import net.citizensnpcs.api.gui.InjectContext;
import net.citizensnpcs.api.gui.InventoryMenuPage;
import net.citizensnpcs.api.gui.InventoryMenuSlot;
import net.citizensnpcs.api.gui.Menu;
import net.citizensnpcs.api.gui.MenuContext;
import net.citizensnpcs.api.gui.MenuPattern;
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;
@Menu(title = "NPC Equipment", type = InventoryType.CHEST, dimensions = { 2, 5 })
@MenuSlot(
slot = { 0, 2 },
material = Material.DIAMOND_HELMET,
amount = 1,
lore = "Place a helmet below",
filter = InventoryAction.UNKNOWN)
@MenuSlot(
slot = { 0, 4 },
material = Material.DIAMOND_LEGGINGS,
lore = "Place leggings below",
amount = 1,
filter = InventoryAction.UNKNOWN)
@MenuSlot(
slot = { 0, 1 },
material = Material.ELYTRA,
lore = "Place offhand item below",
amount = 1,
filter = InventoryAction.UNKNOWN)
@MenuSlot(
slot = { 0, 0 },
material = Material.DIAMOND_SWORD,
lore = "Place in hand item below",
amount = 1,
filter = InventoryAction.UNKNOWN)
@MenuSlot(
slot = { 0, 3 },
material = Material.DIAMOND_CHESTPLATE,
lore = "Place chestplate below",
amount = 1,
filter = InventoryAction.UNKNOWN)
@MenuSlot(
slot = { 0, 5 },
material = Material.DIAMOND_BOOTS,
lore = "Place boots below",
amount = 1,
filter = InventoryAction.UNKNOWN)
@MenuPattern(
offset = { 0, 6 },
slots = { @MenuSlot(
filter = InventoryAction.UNKNOWN,
pat = 'x',
material = Material.GLASS_PANE,
title = "<4>Unused") },
value = "xxx\nxxx")
public class GenericEquipperGUI extends InventoryMenuPage {
@MenuSlot(slot = { 1, 5 })
private InventoryMenuSlot boots;
@MenuSlot(slot = { 1, 3 })
private InventoryMenuSlot chest;
@MenuSlot(slot = { 1, 0 })
private InventoryMenuSlot hand;
@MenuSlot(slot = { 1, 2 })
private InventoryMenuSlot helmet;
@MenuSlot(slot = { 1, 4 })
private InventoryMenuSlot leggings;
@InjectContext
private NPC npc;
@MenuSlot(slot = { 1, 1 })
private InventoryMenuSlot offhand;
@Override
public void initialise(MenuContext ctx) {
Equipment trait = npc.getOrAddTrait(Equipment.class);
hand.setItemStack(trait.get(EquipmentSlot.HAND));
helmet.setItemStack(trait.get(EquipmentSlot.HELMET));
chest.setItemStack(trait.get(EquipmentSlot.CHESTPLATE));
leggings.setItemStack(trait.get(EquipmentSlot.LEGGINGS));
boots.setItemStack(trait.get(EquipmentSlot.BOOTS));
offhand.setItemStack(trait.get(EquipmentSlot.OFF_HAND));
}
private void set(EquipmentSlot slot, CitizensInventoryClickEvent event, Function<Material, Boolean> filter) {
ItemStack result = event.getResultItemNonNull();
if (event.isCancelled() || !filter.apply(result.getType())) {
event.setResult(Result.DENY);
return;
}
npc.getOrAddTrait(Equipment.class).set(slot, result);
}
@ClickHandler(slot = { 1, 5 })
public void setBoots(InventoryMenuSlot slot, CitizensInventoryClickEvent event) {
set(EquipmentSlot.BOOTS, event, (type) -> type.name().endsWith("BOOTS"));
}
@ClickHandler(slot = { 1, 3 })
public void setChest(InventoryMenuSlot slot, CitizensInventoryClickEvent event) {
set(EquipmentSlot.CHESTPLATE, event,
(type) -> type.name().endsWith("CHESTPLATE") || type.name().equals("ELYTRA"));
}
@ClickHandler(slot = { 1, 0 })
public void setHand(InventoryMenuSlot slot, CitizensInventoryClickEvent event) {
set(EquipmentSlot.HAND, event, (type) -> true);
}
@ClickHandler(slot = { 1, 2 })
public void setHelmet(InventoryMenuSlot slot, CitizensInventoryClickEvent event) {
set(EquipmentSlot.HELMET, event, (type) -> true);
}
@ClickHandler(slot = { 1, 4 })
public void setLeggings(InventoryMenuSlot slot, CitizensInventoryClickEvent event) {
set(EquipmentSlot.LEGGINGS, event, (type) -> type.name().endsWith("LEGGINGS"));
}
@ClickHandler(slot = { 1, 1 })
public void setOffhand(InventoryMenuSlot slot, CitizensInventoryClickEvent event) {
set(EquipmentSlot.OFF_HAND, event, (type) -> true);
}
}

View File

@ -1,31 +0,0 @@
package net.citizensnpcs.editor;
import org.bukkit.Material;
import org.bukkit.entity.Pig;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.util.Messaging;
import net.citizensnpcs.trait.Saddle;
import net.citizensnpcs.util.Messages;
public class PigEquipper implements Equipper {
@Override
public void equip(Player equipper, NPC toEquip) {
ItemStack hand = equipper.getInventory().getItemInHand();
Pig pig = (Pig) toEquip.getEntity();
if (hand.getType() == Material.SADDLE) {
if (!pig.hasSaddle()) {
toEquip.getOrAddTrait(Saddle.class).toggle();
hand.setAmount(0);
Messaging.sendTr(equipper, Messages.SADDLED_SET, toEquip.getName());
}
} else if (pig.hasSaddle()) {
equipper.getWorld().dropItemNaturally(pig.getLocation(), new ItemStack(Material.SADDLE, 1));
toEquip.getOrAddTrait(Saddle.class).toggle();
Messaging.sendTr(equipper, Messages.SADDLED_STOPPED, toEquip.getName());
}
equipper.getInventory().setItemInHand(hand);
}
}

View File

@ -0,0 +1,63 @@
package net.citizensnpcs.editor;
import org.bukkit.Material;
import org.bukkit.event.Event.Result;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.ItemStack;
import net.citizensnpcs.api.gui.CitizensInventoryClickEvent;
import net.citizensnpcs.api.gui.ClickHandler;
import net.citizensnpcs.api.gui.InjectContext;
import net.citizensnpcs.api.gui.InventoryMenuPage;
import net.citizensnpcs.api.gui.InventoryMenuSlot;
import net.citizensnpcs.api.gui.Menu;
import net.citizensnpcs.api.gui.MenuContext;
import net.citizensnpcs.api.gui.MenuPattern;
import net.citizensnpcs.api.gui.MenuSlot;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.trait.Saddle;
@Menu(title = "NPC Equipment", type = InventoryType.HOPPER, dimensions = { 0, 5 })
@MenuSlot(
slot = { 0, 0 },
material = Material.SADDLE,
amount = 1,
lore = "Place a saddle here ->",
filter = InventoryAction.UNKNOWN)
@MenuPattern(
offset = { 0, 2 },
slots = { @MenuSlot(
filter = InventoryAction.UNKNOWN,
pat = 'x',
material = Material.GLASS_PANE,
title = "<4>Unused") },
value = "xxx")
public class PigEquipperGUI extends InventoryMenuPage {
@InjectContext
private NPC npc;
@MenuSlot(slot = { 0, 1 })
private InventoryMenuSlot saddle;
@Override
public void initialise(MenuContext ctx) {
Saddle trait = npc.getOrAddTrait(Saddle.class);
if (trait.useSaddle()) {
saddle.setItemStack(new ItemStack(Material.SADDLE, 1));
}
}
@ClickHandler(slot = { 0, 1 }, filter = { InventoryAction.PICKUP_ALL, InventoryAction.PLACE_ALL })
public void setSaddle(InventoryMenuSlot slot, CitizensInventoryClickEvent event) {
if (event.getAction() == InventoryAction.PICKUP_ALL && event.getCursor() != null) {
event.setResult(Result.DENY);
return;
}
if (event.getAction() == InventoryAction.PLACE_ALL
&& (event.getCurrentItem() != null || event.getCursor().getType() != Material.SADDLE)) {
event.setResult(Result.DENY);
return;
}
npc.getOrAddTrait(Saddle.class).toggle();
}
}