Add 1.15 support, add ArmorEquipEvent
- Added support for version 1.15 of minecraft. From now on, the NBT constructors are private instead of public. During initialization, they're made accessible now. - Added ArmorEquipEvent that keeps track of every possible way someone might equip armor. It is then cancelled if needed. - Updated language file. A long and a short name of each tier is now supported, which can be used as variables.
This commit is contained in:
parent
e906ddfdb3
commit
c5abedc89b
@ -0,0 +1,163 @@
|
||||
package com.codingforcookies.armorequip;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
/**
|
||||
* @author Arnah
|
||||
* @since Jul 30, 2015
|
||||
*/
|
||||
public final class ArmorEquipEvent extends PlayerEvent implements Cancellable
|
||||
{
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private boolean cancel = false;
|
||||
private final EquipMethod equipType;
|
||||
private final ArmorType type;
|
||||
private ItemStack oldArmorPiece, newArmorPiece;
|
||||
|
||||
/**
|
||||
* Constructor for the ArmorEquipEvent.
|
||||
*
|
||||
* @param player The player who put on / removed the armor.
|
||||
* @param type The ArmorType of the armor added
|
||||
* @param oldArmorPiece The ItemStack of the armor removed.
|
||||
* @param newArmorPiece The ItemStack of the armor added.
|
||||
*/
|
||||
public ArmorEquipEvent(final Player player, final EquipMethod equipType, final ArmorType type,
|
||||
final ItemStack oldArmorPiece, final ItemStack newArmorPiece)
|
||||
{
|
||||
super(player);
|
||||
this.equipType = equipType;
|
||||
this.type = type;
|
||||
this.oldArmorPiece = oldArmorPiece;
|
||||
this.newArmorPiece = newArmorPiece;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of handlers handling this event.
|
||||
*
|
||||
* @return A list of handlers handling this event.
|
||||
*/
|
||||
public final static HandlerList getHandlerList()
|
||||
{
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of handlers handling this event.
|
||||
*
|
||||
* @return A list of handlers handling this event.
|
||||
*/
|
||||
@Override
|
||||
public final HandlerList getHandlers()
|
||||
{
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if this event should be cancelled.
|
||||
*
|
||||
* @param cancel If this event should be cancelled.
|
||||
*/
|
||||
@Override
|
||||
public final void setCancelled(final boolean cancel)
|
||||
{
|
||||
this.cancel = cancel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets if this event is cancelled.
|
||||
*
|
||||
* @return If this event is cancelled
|
||||
*/
|
||||
@Override
|
||||
public final boolean isCancelled()
|
||||
{
|
||||
return cancel;
|
||||
}
|
||||
|
||||
public final ArmorType getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last equipped armor piece, could be a piece of armor,
|
||||
* {@link Material#Air}, or null.
|
||||
*/
|
||||
public final ItemStack getOldArmorPiece()
|
||||
{
|
||||
return oldArmorPiece;
|
||||
}
|
||||
|
||||
public final void setOldArmorPiece(final ItemStack oldArmorPiece)
|
||||
{
|
||||
this.oldArmorPiece = oldArmorPiece;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the newly equipped armor, could be a piece of armor,
|
||||
* {@link Material#Air}, or null.
|
||||
*/
|
||||
public final ItemStack getNewArmorPiece()
|
||||
{
|
||||
return newArmorPiece;
|
||||
}
|
||||
|
||||
public final void setNewArmorPiece(final ItemStack newArmorPiece)
|
||||
{
|
||||
this.newArmorPiece = newArmorPiece;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the method used to either equip or unequip an armor piece.
|
||||
*/
|
||||
public EquipMethod getMethod()
|
||||
{
|
||||
return equipType;
|
||||
}
|
||||
|
||||
public enum EquipMethod
|
||||
{// These have got to be the worst documentations ever.
|
||||
/**
|
||||
* When you shift click an armor piece to equip or unequip
|
||||
*/
|
||||
SHIFT_CLICK,
|
||||
/**
|
||||
* When you drag and drop the item to equip or unequip
|
||||
*/
|
||||
DRAG,
|
||||
/**
|
||||
* When you manually equip or unequip the item. Use to be DRAG
|
||||
*/
|
||||
PICK_DROP,
|
||||
/**
|
||||
* When you right click an armor piece in the hotbar without the inventory open
|
||||
* to equip.
|
||||
*/
|
||||
HOTBAR,
|
||||
/**
|
||||
* When you press the hotbar slot number while hovering over the armor slot to
|
||||
* equip or unequip
|
||||
*/
|
||||
HOTBAR_SWAP,
|
||||
/**
|
||||
* When in range of a dispenser that shoots an armor piece to equip.<br>
|
||||
* Requires the spigot version to have
|
||||
* {@link org.bukkit.event.block.BlockDispenseArmorEvent} implemented.
|
||||
*/
|
||||
DISPENSER,
|
||||
/**
|
||||
* When an armor piece is removed due to it losing all durability.
|
||||
*/
|
||||
BROKE,
|
||||
/**
|
||||
* When you die causing all armor to unequip
|
||||
*/
|
||||
DEATH,;
|
||||
}
|
||||
}
|
265
src/main/java/com/codingforcookies/armorequip/ArmorListener.java
Normal file
265
src/main/java/com/codingforcookies/armorequip/ArmorListener.java
Normal file
@ -0,0 +1,265 @@
|
||||
package com.codingforcookies.armorequip;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event.Result;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryAction;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryDragEvent;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.event.inventory.InventoryType.SlotType;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerItemBreakEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import com.codingforcookies.armorequip.ArmorEquipEvent.EquipMethod;
|
||||
|
||||
/**
|
||||
* @author Arnah
|
||||
* @since Jul 30, 2015
|
||||
*/
|
||||
public class ArmorListener implements Listener
|
||||
{
|
||||
private final List<String> blockedMaterials;
|
||||
|
||||
public ArmorListener(List<String> blockedMaterials)
|
||||
{
|
||||
this.blockedMaterials = blockedMaterials;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public final void inventoryClick(final InventoryClickEvent e)
|
||||
{
|
||||
boolean shift = false, numberkey = false;
|
||||
if (e.isCancelled())
|
||||
return;
|
||||
if (e.getAction() == InventoryAction.NOTHING)
|
||||
return;// Why does this get called if nothing happens??
|
||||
if (e.getClick().equals(ClickType.SHIFT_LEFT) || e.getClick().equals(ClickType.SHIFT_RIGHT))
|
||||
shift = true;
|
||||
if (e.getClick().equals(ClickType.NUMBER_KEY))
|
||||
numberkey = true;
|
||||
if (e.getSlotType() != SlotType.ARMOR && e.getSlotType() != SlotType.QUICKBAR &&
|
||||
e.getSlotType() != SlotType.CONTAINER)
|
||||
return;
|
||||
if (e.getClickedInventory() != null && !e.getClickedInventory().getType().equals(InventoryType.PLAYER))
|
||||
return;
|
||||
if (!e.getInventory().getType().equals(InventoryType.CRAFTING) &&
|
||||
!e.getInventory().getType().equals(InventoryType.PLAYER))
|
||||
return;
|
||||
if (!(e.getWhoClicked() instanceof Player))
|
||||
return;
|
||||
ArmorType newArmorType = ArmorType.matchType(shift ? e.getCurrentItem() : e.getCursor());
|
||||
if (!shift && newArmorType != null && e.getRawSlot() != newArmorType.getSlot())
|
||||
// Used for drag and drop checking to make sure you aren't trying to place a
|
||||
// helmet in the boots slot.
|
||||
return;
|
||||
if (shift)
|
||||
{
|
||||
newArmorType = ArmorType.matchType(e.getCurrentItem());
|
||||
if (newArmorType != null)
|
||||
{
|
||||
boolean equipping = true;
|
||||
if (e.getRawSlot() == newArmorType.getSlot())
|
||||
equipping = false;
|
||||
if (newArmorType.equals(ArmorType.HELMET) &&
|
||||
(equipping ? isAirOrNull(e.getWhoClicked().getInventory().getHelmet()) :
|
||||
!isAirOrNull(e.getWhoClicked().getInventory().getHelmet())) ||
|
||||
newArmorType.equals(ArmorType.CHESTPLATE) && (equipping ?
|
||||
isAirOrNull(e.getWhoClicked().getInventory().getChestplate()) :
|
||||
!isAirOrNull(e.getWhoClicked().getInventory().getChestplate())) ||
|
||||
newArmorType.equals(ArmorType.LEGGINGS) && (equipping ?
|
||||
isAirOrNull(e.getWhoClicked().getInventory().getLeggings()) :
|
||||
!isAirOrNull(e.getWhoClicked().getInventory().getLeggings())) ||
|
||||
newArmorType.equals(ArmorType.BOOTS) && (equipping ?
|
||||
isAirOrNull(e.getWhoClicked().getInventory().getBoots()) :
|
||||
!isAirOrNull(e.getWhoClicked().getInventory().getBoots())))
|
||||
{
|
||||
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent((Player) e.getWhoClicked(),
|
||||
EquipMethod.SHIFT_CLICK, newArmorType,
|
||||
equipping ? null : e.getCurrentItem(),
|
||||
equipping ? e.getCurrentItem() : null);
|
||||
Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent);
|
||||
if (armorEquipEvent.isCancelled())
|
||||
e.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ItemStack newArmorPiece = e.getCursor();
|
||||
ItemStack oldArmorPiece = e.getCurrentItem();
|
||||
if (numberkey)
|
||||
if (e.getClickedInventory().getType().equals(InventoryType.PLAYER))
|
||||
{ // Prevents shit in the 2by2 crafting
|
||||
// e.getClickedInventory() == The players inventory
|
||||
// e.getHotBarButton() == key people are pressing to equip or unequip the item
|
||||
// to or from.
|
||||
// e.getRawSlot() == The slot the item is going to.
|
||||
// e.getSlot() == Armor slot, can't use e.getRawSlot() as that gives a hotbar
|
||||
// slot ;-;
|
||||
ItemStack hotbarItem = e.getClickedInventory().getItem(e.getHotbarButton());
|
||||
if (!isAirOrNull(hotbarItem))
|
||||
{ // Equipping
|
||||
newArmorType = ArmorType.matchType(hotbarItem);
|
||||
newArmorPiece = hotbarItem;
|
||||
oldArmorPiece = e.getClickedInventory().getItem(e.getSlot());
|
||||
}
|
||||
else
|
||||
// Unequipping
|
||||
newArmorType = ArmorType
|
||||
.matchType(!isAirOrNull(e.getCurrentItem()) ? e.getCurrentItem() : e.getCursor());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isAirOrNull(e.getCursor()) && !isAirOrNull(e.getCurrentItem()))
|
||||
// unequip with no new item going into the slot.
|
||||
newArmorType = ArmorType.matchType(e.getCurrentItem());
|
||||
// e.getCurrentItem() == Unequip
|
||||
// e.getCursor() == Equip
|
||||
// newArmorType = ArmorType.matchType(!isAirOrNull(e.getCurrentItem()) ?
|
||||
// e.getCurrentItem() : e.getCursor());
|
||||
}
|
||||
if (newArmorType != null && e.getRawSlot() == newArmorType.getSlot())
|
||||
{
|
||||
EquipMethod method = EquipMethod.PICK_DROP;
|
||||
if (e.getAction().equals(InventoryAction.HOTBAR_SWAP) || numberkey)
|
||||
method = EquipMethod.HOTBAR_SWAP;
|
||||
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent((Player) e.getWhoClicked(), method, newArmorType,
|
||||
oldArmorPiece, newArmorPiece);
|
||||
Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent);
|
||||
if (armorEquipEvent.isCancelled())
|
||||
e.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void playerInteractEvent(PlayerInteractEvent e)
|
||||
{
|
||||
if (e.getAction() == Action.PHYSICAL)
|
||||
return;
|
||||
if (e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK)
|
||||
{
|
||||
final Player player = e.getPlayer();
|
||||
if (e.getClickedBlock() != null && e.getAction() == Action.RIGHT_CLICK_BLOCK)
|
||||
{ // Having both of these checks is useless, might as well do it though.
|
||||
// Some blocks have actions when you right click them which stops the client
|
||||
// from equipping the armor in hand.
|
||||
Material mat = e.getClickedBlock().getType();
|
||||
for (String s : blockedMaterials)
|
||||
if (mat.name().equalsIgnoreCase(s))
|
||||
return;
|
||||
}
|
||||
ArmorType newArmorType = ArmorType.matchType(e.getItem());
|
||||
if (newArmorType != null)
|
||||
{
|
||||
if (newArmorType.equals(ArmorType.HELMET) && isAirOrNull(e.getPlayer().getInventory().getHelmet()) ||
|
||||
newArmorType
|
||||
.equals(ArmorType.CHESTPLATE) && isAirOrNull(e.getPlayer().getInventory().getChestplate()) ||
|
||||
newArmorType
|
||||
.equals(ArmorType.LEGGINGS) && isAirOrNull(e.getPlayer().getInventory().getLeggings()) ||
|
||||
newArmorType.equals(ArmorType.BOOTS) && isAirOrNull(e.getPlayer().getInventory().getBoots()))
|
||||
{
|
||||
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(e.getPlayer(), EquipMethod.HOTBAR,
|
||||
ArmorType.matchType(e.getItem()), null,
|
||||
e.getItem());
|
||||
Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent);
|
||||
if (armorEquipEvent.isCancelled())
|
||||
{
|
||||
e.setCancelled(true);
|
||||
player.updateInventory();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void inventoryDrag(InventoryDragEvent event)
|
||||
{
|
||||
// getType() seems to always be even.
|
||||
// Old Cursor gives the item you are equipping
|
||||
// Raw slot is the ArmorType slot
|
||||
// Can't replace armor using this method making getCursor() useless.
|
||||
ArmorType type = ArmorType.matchType(event.getOldCursor());
|
||||
if (event.getRawSlots().isEmpty())
|
||||
return;// Idk if this will ever happen
|
||||
if (type != null && type.getSlot() == event.getRawSlots().stream().findFirst().orElse(0))
|
||||
{
|
||||
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent((Player) event.getWhoClicked(), EquipMethod.DRAG,
|
||||
type, null, event.getOldCursor());
|
||||
Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent);
|
||||
if (armorEquipEvent.isCancelled())
|
||||
{
|
||||
event.setResult(Result.DENY);
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
// Debug shit
|
||||
/*
|
||||
* System.out.println("Slots: " + event.getInventorySlots().toString());
|
||||
* System.out.println("Raw Slots: " + event.getRawSlots().toString());
|
||||
* if(event.getCursor() != null){ System.out.println("Cursor: " +
|
||||
* event.getCursor().getType().name()); } if(event.getOldCursor() != null){
|
||||
* System.out.println("OldCursor: " + event.getOldCursor().getType().name()); }
|
||||
* System.out.println("Type: " + event.getType().name());
|
||||
*/
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void itemBreakEvent(PlayerItemBreakEvent e)
|
||||
{
|
||||
ArmorType type = ArmorType.matchType(e.getBrokenItem());
|
||||
if (type != null)
|
||||
{
|
||||
Player p = e.getPlayer();
|
||||
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(p, EquipMethod.BROKE, type, e.getBrokenItem(), null);
|
||||
Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent);
|
||||
if (armorEquipEvent.isCancelled())
|
||||
{
|
||||
ItemStack i = e.getBrokenItem().clone();
|
||||
i.setAmount(1);
|
||||
i.setDurability((short) (i.getDurability() - 1));
|
||||
if (type.equals(ArmorType.HELMET))
|
||||
p.getInventory().setHelmet(i);
|
||||
else if (type.equals(ArmorType.CHESTPLATE))
|
||||
p.getInventory().setChestplate(i);
|
||||
else if (type.equals(ArmorType.LEGGINGS))
|
||||
p.getInventory().setLeggings(i);
|
||||
else if (type.equals(ArmorType.BOOTS))
|
||||
p.getInventory().setBoots(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void playerDeathEvent(PlayerDeathEvent e)
|
||||
{
|
||||
Player p = e.getEntity();
|
||||
for (ItemStack oldArmor : p.getInventory().getArmorContents())
|
||||
if (!isAirOrNull(oldArmor))
|
||||
{
|
||||
ArmorType type = ArmorType.matchType(oldArmor);
|
||||
Bukkit.getServer().getPluginManager().callEvent(new ArmorEquipEvent(p, EquipMethod.DEATH,
|
||||
type, oldArmor, null));
|
||||
// No way to cancel a death event.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A utility method to support versions that use null or air ItemStacks.
|
||||
*/
|
||||
private boolean isAirOrNull(ItemStack item)
|
||||
{
|
||||
return item == null || item.getType().equals(Material.AIR);
|
||||
}
|
||||
}
|
53
src/main/java/com/codingforcookies/armorequip/ArmorType.java
Normal file
53
src/main/java/com/codingforcookies/armorequip/ArmorType.java
Normal file
@ -0,0 +1,53 @@
|
||||
package com.codingforcookies.armorequip;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
/**
|
||||
* @author Arnah
|
||||
* @since Jul 30, 2015
|
||||
*/
|
||||
public enum ArmorType
|
||||
{
|
||||
HELMET (5),
|
||||
CHESTPLATE (6),
|
||||
LEGGINGS (7),
|
||||
BOOTS (8);
|
||||
|
||||
private final int slot;
|
||||
|
||||
ArmorType(int slot)
|
||||
{
|
||||
this.slot = slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to match the ArmorType for the specified ItemStack.
|
||||
*
|
||||
* @param itemStack The ItemStack to parse the type of.
|
||||
* @return The parsed ArmorType. (null if none were found.)
|
||||
*/
|
||||
public final static ArmorType matchType(final ItemStack itemStack)
|
||||
{
|
||||
if (itemStack == null || itemStack.getType().equals(Material.AIR))
|
||||
return null;
|
||||
if (itemStack.getType().equals(Material.ELYTRA))
|
||||
return CHESTPLATE;
|
||||
String type = itemStack.getType().name();
|
||||
if (type.endsWith("_HELMET") || type.endsWith("_SKULL"))
|
||||
return HELMET;
|
||||
else if (type.endsWith("_CHESTPLATE"))
|
||||
return CHESTPLATE;
|
||||
else if (type.endsWith("_LEGGINGS"))
|
||||
return LEGGINGS;
|
||||
else if (type.endsWith("_BOOTS"))
|
||||
return BOOTS;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getSlot()
|
||||
{
|
||||
return slot;
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.codingforcookies.armorequip;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockDispenseArmorEvent;
|
||||
|
||||
/**
|
||||
* @author Arnah
|
||||
* @since Feb 08, 2019
|
||||
*/
|
||||
public class DispenserArmorListener implements Listener
|
||||
{
|
||||
@EventHandler
|
||||
public void dispenseArmorEvent(BlockDispenseArmorEvent event)
|
||||
{
|
||||
ArmorType type = ArmorType.matchType(event.getItem());
|
||||
if (type != null)
|
||||
if (event.getTargetEntity() instanceof Player)
|
||||
{
|
||||
Player p = (Player) event.getTargetEntity();
|
||||
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(p, ArmorEquipEvent.EquipMethod.DISPENSER, type,
|
||||
null, event.getItem());
|
||||
Bukkit.getServer().getPluginManager().callEvent(armorEquipEvent);
|
||||
if (armorEquipEvent.isCancelled())
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,10 @@
|
||||
package nl.pim16aap2.armoredElytra;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.bstats.bukkit.Metrics;
|
||||
import org.bukkit.Bukkit;
|
||||
@ -18,6 +21,7 @@ import nl.pim16aap2.armoredElytra.handlers.LoginHandler;
|
||||
import nl.pim16aap2.armoredElytra.handlers.Uninstaller;
|
||||
import nl.pim16aap2.armoredElytra.nbtEditor.NBTEditor;
|
||||
import nl.pim16aap2.armoredElytra.util.ArmorTier;
|
||||
import nl.pim16aap2.armoredElytra.util.ArmorTierName;
|
||||
import nl.pim16aap2.armoredElytra.util.ConfigLoader;
|
||||
import nl.pim16aap2.armoredElytra.util.Messages;
|
||||
import nl.pim16aap2.armoredElytra.util.Update;
|
||||
@ -33,7 +37,8 @@ public class ArmoredElytra extends JavaPlugin implements Listener
|
||||
private Messages messages;
|
||||
private ConfigLoader config;
|
||||
|
||||
private String leatherName, ironName, goldName, chainName, diamondName;
|
||||
// private String leatherName, ironName, goldName, chainName, diamondName;
|
||||
private final Map<ArmorTier, ArmorTierName> armorTierNames = new EnumMap(ArmorTier.class);
|
||||
private String elytraReceivedMessage;
|
||||
private String usageDeniedMessage;
|
||||
private String elytraLore;
|
||||
@ -137,18 +142,29 @@ public class ArmoredElytra extends JavaPlugin implements Listener
|
||||
return messages;
|
||||
}
|
||||
|
||||
private final String getColorCodedStringFromConfig(final String configEntry)
|
||||
{
|
||||
return getMyMessages().getString(configEntry).replaceAll("&((?i)[0-9a-fk-or])", "\u00A7$1");
|
||||
}
|
||||
|
||||
private void readMessages()
|
||||
{
|
||||
// Replace color codes by the corresponding colors.
|
||||
usageDeniedMessage = getMyMessages().getString("MESSAGES.UsageDenied" ).replaceAll("&((?i)[0-9a-fk-or])", "\u00A7$1");
|
||||
elytraReceivedMessage = getMyMessages().getString("MESSAGES.ElytraReceived").replaceAll("&((?i)[0-9a-fk-or])", "\u00A7$1");
|
||||
elytraLore = getMyMessages().getString("MESSAGES.Lore" ).replaceAll("&((?i)[0-9a-fk-or])", "\u00A7$1");
|
||||
usageDeniedMessage = getColorCodedStringFromConfig("MESSAGES.UsageDenied");
|
||||
elytraReceivedMessage = getColorCodedStringFromConfig("MESSAGES.ElytraReceived");
|
||||
elytraLore = getColorCodedStringFromConfig("MESSAGES.Lore");
|
||||
|
||||
leatherName = getMyMessages().getString("TIER.Leather" ).replaceAll("&((?i)[0-9a-fk-or])", "\u00A7$1");
|
||||
goldName = getMyMessages().getString("TIER.Gold" ).replaceAll("&((?i)[0-9a-fk-or])", "\u00A7$1");
|
||||
chainName = getMyMessages().getString("TIER.Chain" ).replaceAll("&((?i)[0-9a-fk-or])", "\u00A7$1");
|
||||
ironName = getMyMessages().getString("TIER.Iron" ).replaceAll("&((?i)[0-9a-fk-or])", "\u00A7$1");
|
||||
diamondName = getMyMessages().getString("TIER.Diamond" ).replaceAll("&((?i)[0-9a-fk-or])", "\u00A7$1");
|
||||
armorTierNames.put(ArmorTier.NONE, new ArmorTierName("NONE", "NONE")); // Shouldn't be used.
|
||||
armorTierNames.put(ArmorTier.LEATHER, new ArmorTierName(getColorCodedStringFromConfig("TIER.Leather"),
|
||||
getColorCodedStringFromConfig("TIER.SHORT.Leather")));
|
||||
armorTierNames.put(ArmorTier.GOLD, new ArmorTierName(getColorCodedStringFromConfig("TIER.Gold"),
|
||||
getColorCodedStringFromConfig("TIER.SHORT.Gold")));
|
||||
armorTierNames.put(ArmorTier.CHAIN, new ArmorTierName(getColorCodedStringFromConfig("TIER.Chain"),
|
||||
getColorCodedStringFromConfig("TIER.SHORT.Chain")));
|
||||
armorTierNames.put(ArmorTier.IRON, new ArmorTierName(getColorCodedStringFromConfig("TIER.Iron"),
|
||||
getColorCodedStringFromConfig("TIER.SHORT.Iron")));
|
||||
armorTierNames.put(ArmorTier.DIAMOND, new ArmorTierName(getColorCodedStringFromConfig("TIER.Diamond"),
|
||||
getColorCodedStringFromConfig("TIER.SHORT.Diamond")));
|
||||
|
||||
// Change the string to null if it says "NONE".
|
||||
usageDeniedMessage = (Objects.equals(usageDeniedMessage, new String("NONE")) ? null : usageDeniedMessage );
|
||||
@ -216,10 +232,20 @@ public class ArmoredElytra extends JavaPlugin implements Listener
|
||||
}
|
||||
}
|
||||
|
||||
private static final Pattern ARMOR_TIER = Pattern.compile("%ARMOR_TIER%");
|
||||
private static final Pattern ARMOR_TIER_SHORT = Pattern.compile("%ARMOR_TIER_SHORT%");
|
||||
|
||||
// Replace %ARMOR_TIER% by the name of that armor tier in a string, but strip %ARMOR_TIER% of its color.
|
||||
public String fillInArmorTierInStringNoColor(String string, ArmorTier armorTier)
|
||||
{
|
||||
return string.replace("%ARMOR_TIER%", ChatColor.stripColor(getArmoredElytrName(armorTier)));
|
||||
if (armorTier == null)
|
||||
{
|
||||
getLogger().log(Level.INFO, "ArmorTier was null! Failed to obtain proper string!");
|
||||
return string;
|
||||
}
|
||||
final ArmorTierName tierName = armorTierNames.get(armorTier);
|
||||
return ARMOR_TIER_SHORT.matcher(ARMOR_TIER.matcher(string).replaceAll(ChatColor.stripColor(tierName.getLongName())))
|
||||
.replaceAll(ChatColor.stripColor(tierName.getShortName()));
|
||||
}
|
||||
|
||||
// Print a string to the log.
|
||||
@ -254,30 +280,14 @@ public class ArmoredElytra extends JavaPlugin implements Listener
|
||||
return elytraLore;
|
||||
}
|
||||
|
||||
public String getArmoredElytrName(ArmorTier tier)
|
||||
public String getArmoredElytraName(ArmorTier tier)
|
||||
{
|
||||
String ret;
|
||||
switch(tier)
|
||||
if (tier == null)
|
||||
{
|
||||
case LEATHER:
|
||||
ret = leatherName;
|
||||
break;
|
||||
case GOLD:
|
||||
ret = goldName;
|
||||
break;
|
||||
case CHAIN:
|
||||
ret = chainName;
|
||||
break;
|
||||
case IRON:
|
||||
ret = ironName;
|
||||
break;
|
||||
case DIAMOND:
|
||||
ret = diamondName;
|
||||
break;
|
||||
default:
|
||||
ret = "NONE";
|
||||
getLogger().log(Level.INFO, "ArmorTier was null! Failed to obtain proper string!");
|
||||
return "NULL";
|
||||
}
|
||||
return ret;
|
||||
return armorTierNames.get(tier).getLongName();
|
||||
}
|
||||
|
||||
public void setUpToDate(boolean upToDate)
|
||||
|
@ -48,6 +48,7 @@ public class CommandHandler implements CommandExecutor
|
||||
String tier = null;
|
||||
Player receiver;
|
||||
boolean allowed = false;
|
||||
|
||||
if (args.length == 1)
|
||||
{
|
||||
receiver = player;
|
||||
|
@ -277,8 +277,9 @@ public class EventHandlers implements Listener
|
||||
|
||||
// If the armored elytra is not of the leather tier, but itemTwo is leather,
|
||||
// Pick the block action, as that would repair the elytra by default (vanilla).
|
||||
// Also block Armored Elytra + Elytra.
|
||||
if (tier != ArmorTier.LEATHER && matTwo == Material.LEATHER || matTwo == Material.ELYTRA)
|
||||
// Also block Armored Elytra + Elytra and Elytra + Membrane
|
||||
if (tier != ArmorTier.LEATHER && matTwo == Material.LEATHER || matTwo == Material.ELYTRA ||
|
||||
matTwo.equals(XMaterial.PHANTOM_MEMBRANE.parseMaterial()))
|
||||
return Action.BLOCK;
|
||||
}
|
||||
return Action.NONE;
|
||||
|
@ -74,8 +74,10 @@ public class NBTEditor
|
||||
return;
|
||||
}
|
||||
|
||||
// Old versions use the old format. It is assumed here that all versions from 1.13.2 on will use the new format.
|
||||
// Spigot's 1.13.1 uses the old format, but 1.13.2 uses the new format. They share the same version number though.
|
||||
// Old versions use the old format. It is assumed here that all versions from
|
||||
// 1.13.2 on will use the new format.
|
||||
// Spigot's 1.13.1 uses the old format, but 1.13.2 uses the new format. They
|
||||
// share the same version number though.
|
||||
if (version.equals("v1_9_R1") || version.equals("v1_9_R2") || version.equals("v1_10_R1") ||
|
||||
version.equals("v1_11_R1") || version.equals("v1_12_R1") || version.equals("v1_13_R1") ||
|
||||
version.equals("v1_13_R2") && Bukkit.getVersion().split(" ")[2].equals("1.13.1)"))
|
||||
@ -104,13 +106,16 @@ public class NBTEditor
|
||||
NBTBase = getNMSClass("NBTBase");
|
||||
|
||||
NBTTagString = getNMSClass("NBTTagString");
|
||||
NBTTagStringCtor = NBTTagString.getConstructor(String.class);
|
||||
NBTTagStringCtor = NBTTagString.getDeclaredConstructor(String.class);
|
||||
NBTTagStringCtor.setAccessible(true);
|
||||
|
||||
NBTTagByte = getNMSClass("NBTTagByte");
|
||||
NBTTagByteCtor = NBTTagByte.getConstructor(byte.class);
|
||||
NBTTagByteCtor = NBTTagByte.getDeclaredConstructor(byte.class);
|
||||
NBTTagByteCtor.setAccessible(true);
|
||||
|
||||
NBTTagInt = getNMSClass("NBTTagInt");
|
||||
NBTTagIntCtor = NBTTagInt.getConstructor(int.class);
|
||||
NBTTagIntCtor = NBTTagInt.getDeclaredConstructor(int.class);
|
||||
NBTTagIntCtor.setAccessible(true);
|
||||
|
||||
NBTTagCompound = getNMSClass("NBTTagCompound");
|
||||
setTag = NBTTagCompound.getMethod("set", String.class, NBTBase);
|
||||
@ -138,7 +143,8 @@ public class NBTEditor
|
||||
}
|
||||
}
|
||||
|
||||
private void addCompound(Object instance, Object nbtbase) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
|
||||
private void addCompound(Object instance, Object nbtbase)
|
||||
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
|
||||
{
|
||||
if (addCompound.getParameterCount() == 2)
|
||||
addCompound.invoke(instance, 0, nbtbase);
|
||||
@ -155,13 +161,15 @@ public class NBTEditor
|
||||
int armorProtection = ArmorTier.getArmor(armorTier);
|
||||
int armorToughness = ArmorTier.getToughness(armorTier);
|
||||
|
||||
itemmeta.setDisplayName(plugin.getArmoredElytrName(armorTier));
|
||||
itemmeta.setDisplayName(plugin.getArmoredElytraName(armorTier));
|
||||
if (plugin.getElytraLore() != null)
|
||||
itemmeta.setLore(Arrays.asList(plugin.fillInArmorTierInStringNoColor(plugin.getElytraLore(), armorTier)));
|
||||
itemmeta
|
||||
.setLore(Arrays.asList(plugin.fillInArmorTierInStringNoColor(plugin.getElytraLore(), armorTier)));
|
||||
item.setItemMeta(itemmeta);
|
||||
|
||||
Object nmsStack = asNMSCopy.invoke(null, item);
|
||||
Object compound = ((boolean) hasTag.invoke(nmsStack) ? getTag.invoke(nmsStack) : NBTTagCompound.newInstance());
|
||||
Object compound = ((boolean) hasTag.invoke(nmsStack) ? getTag.invoke(nmsStack) :
|
||||
NBTTagCompound.newInstance());
|
||||
Object modifiers = NBTTagList.newInstance();
|
||||
Object armor = NBTTagCompound.newInstance(); // I should be able to simply add custom tags here!
|
||||
setTag.invoke(armor, "AttributeName", NBTTagStringCtor.newInstance("generic.armor"));
|
||||
@ -192,7 +200,8 @@ public class NBTEditor
|
||||
}
|
||||
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | InstantiationException e)
|
||||
{
|
||||
// TODO: Log this or something. Pretty serious issue for a plugin based entirely on this code.
|
||||
// TODO: Log this or something. Pretty serious issue for a plugin based entirely
|
||||
// on this code.
|
||||
e.printStackTrace();
|
||||
}
|
||||
return item;
|
||||
|
@ -0,0 +1,39 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package nl.pim16aap2.armoredElytra.util;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Pim
|
||||
*/
|
||||
public class ArmorTierName
|
||||
{
|
||||
private String longName, shortName;
|
||||
|
||||
public ArmorTierName(final String longName, final String shortName)
|
||||
{
|
||||
this.longName = longName;
|
||||
this.shortName = shortName;
|
||||
}
|
||||
|
||||
public String getLongName()
|
||||
{
|
||||
return longName;
|
||||
}
|
||||
|
||||
public String getShortName()
|
||||
{
|
||||
return shortName;
|
||||
}
|
||||
|
||||
public void setLongName(final String longName)
|
||||
{
|
||||
this.longName = longName;
|
||||
}
|
||||
|
||||
public void setShortName(final String shortName)
|
||||
{
|
||||
this.shortName = shortName;
|
||||
}
|
||||
}
|
@ -56,7 +56,7 @@ public class Messages
|
||||
while ((sCurrentLine = br.readLine()) != null)
|
||||
{
|
||||
// Ignore comments.
|
||||
if (sCurrentLine.startsWith("#"))
|
||||
if (sCurrentLine.startsWith("#") || sCurrentLine.isEmpty())
|
||||
continue;
|
||||
String key, value;
|
||||
String[] parts = sCurrentLine.split("=", 2);
|
||||
|
@ -62,6 +62,7 @@ public enum XMaterial
|
||||
GOLDEN_CHESTPLATE(0, "GOLD_CHESTPLATE"),
|
||||
IRON_CHESTPLATE(0, ""),
|
||||
LEATHER_CHESTPLATE(0, ""),
|
||||
PHANTOM_MEMBRANE(0, "1.13"),
|
||||
|
||||
AIR(0, ""),
|
||||
;
|
||||
|
@ -4,15 +4,25 @@
|
||||
# The format is "key=value" (without quotation marks). You can modify the values, but not the keys.
|
||||
# Order doesn't matter and you can use comments if you so desire.
|
||||
# Please do note that white space does matter! (so spaces at the end of lines, for example).
|
||||
# The long names (without 'SHORT') are the names the elytras will have.
|
||||
TIER.Leather=&2Leather Armored Elytra
|
||||
TIER.Gold=&EGolden Armored Elytra
|
||||
TIER.Chain=&8Chain Armored Elytra
|
||||
TIER.Iron=&7Iron Armored Elytra
|
||||
TIER.Diamond=&BDiamond Armored Elytra
|
||||
MESSAGES.Lore=Elytra with %ARMOR_TIER% level protection
|
||||
MESSAGES.UsageDenied=You do not have the required permissions to wear %ARMOR_TIER%!
|
||||
MESSAGES.ElytraReceived=&2A(n) %ARMOR_TIER% has been bestowed upon you!
|
||||
TIER.SHORT.Leather=&2Leather
|
||||
TIER.SHORT.Gold=&EGold
|
||||
TIER.SHORT.Chain=&8Chain
|
||||
TIER.SHORT.Iron=&7Iron
|
||||
TIER.SHORT.Diamond=&BDiamond
|
||||
MESSAGES.UninstallMode=&cPlugin in uninstall mode! New Armored Elytras are not allowed!
|
||||
MESSAGES.UnsupportedTier=&cNot a supported armor tier! Try one of these: leather, gold, chain, iron, diamond.
|
||||
MESSAGES.NoGivePermission=&cYou do not have the required permission node to give %ARMOR_TIER%s.
|
||||
MESSAGES.RepairNeeded=&cYou cannot equip this elytra! Please repair it in an anvil first.
|
||||
|
||||
# The following messages support the following variables:
|
||||
# - %ARMOR_TIER% (refers to TIER.X (e.g. TIER.Leather))
|
||||
# - %ARMOR_TIER_SHORT% (refers to TIER.SHORT.X (e.g. TIER.SHORT.Leather)).
|
||||
MESSAGES.Lore=Elytra with %ARMOR_TIER_SHORT% level protection.
|
||||
MESSAGES.NoGivePermission=&cYou do not have the required permission node to give a(n) %ARMOR_TIER%s.
|
||||
MESSAGES.UsageDenied=You do not have the required permissions to wear a(n) %ARMOR_TIER%!
|
||||
MESSAGES.ElytraReceived=&2A(n) %ARMOR_TIER% has been bestowed upon you!
|
@ -2,6 +2,7 @@ name: ArmoredElytra
|
||||
main: nl.pim16aap2.armoredElytra.ArmoredElytra
|
||||
version: ${project.version}
|
||||
author: pim16aap2
|
||||
api-version: 1.13
|
||||
commands:
|
||||
ArmoredElytra:
|
||||
description: Give an armored elytra of the specified tier.
|
||||
|
Loading…
x
Reference in New Issue
Block a user