Add auto armor equip for kits (#3629)

Adds a config option to have player auto-equip armor from kits.

Also adds a performance improvement for all uses of EnumUtil#getAllMatching by switching it to an EnumSet.

Closes #347, closes #3452.
This commit is contained in:
Josh Roy 2021-01-08 15:39:32 -05:00 committed by GitHub
parent 70de83827d
commit 8177893e28
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 73 additions and 4 deletions

View File

@ -331,6 +331,8 @@ public interface ISettings extends IConf {
List<EssentialsSign> getUnprotectedSignNames(); List<EssentialsSign> getUnprotectedSignNames();
boolean isKitAutoEquip();
boolean isPastebinCreateKit(); boolean isPastebinCreateKit();
boolean isAllowBulkBuySell(); boolean isAllowBulkBuySell();

View File

@ -7,12 +7,14 @@ import com.earth2me.essentials.textreader.IText;
import com.earth2me.essentials.textreader.KeywordReplacer; import com.earth2me.essentials.textreader.KeywordReplacer;
import com.earth2me.essentials.textreader.SimpleTextInput; import com.earth2me.essentials.textreader.SimpleTextInput;
import com.earth2me.essentials.utils.DateUtil; import com.earth2me.essentials.utils.DateUtil;
import com.earth2me.essentials.utils.MaterialUtil;
import com.earth2me.essentials.utils.NumberUtil; import com.earth2me.essentials.utils.NumberUtil;
import net.ess3.api.IEssentials; import net.ess3.api.IEssentials;
import net.ess3.api.events.KitClaimEvent; import net.ess3.api.events.KitClaimEvent;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
@ -162,6 +164,7 @@ public class Kit {
boolean spew = false; boolean spew = false;
final boolean allowUnsafe = ess.getSettings().allowUnsafeEnchantments(); final boolean allowUnsafe = ess.getSettings().allowUnsafeEnchantments();
final boolean autoEquip = ess.getSettings().isKitAutoEquip();
final List<ItemStack> itemList = new ArrayList<>(); final List<ItemStack> itemList = new ArrayList<>();
final List<String> commandQueue = new ArrayList<>(); final List<String> commandQueue = new ArrayList<>();
final List<String> moneyQueue = new ArrayList<>(); final List<String> moneyQueue = new ArrayList<>();
@ -194,6 +197,25 @@ public class Kit {
metaStack.parseStringMeta(null, allowUnsafe, parts, 2, ess); metaStack.parseStringMeta(null, allowUnsafe, parts, 2, ess);
} }
if (autoEquip) {
final ItemStack stack = metaStack.getItemStack();
final Material material = stack.getType();
final PlayerInventory inventory = user.getBase().getInventory();
if (MaterialUtil.isHelmet(material) && isEmptyStack(inventory.getHelmet())) {
inventory.setHelmet(stack);
continue;
} else if (MaterialUtil.isChestplate(material) && isEmptyStack(inventory.getChestplate())) {
inventory.setChestplate(stack);
continue;
} else if (MaterialUtil.isLeggings(material) && isEmptyStack(inventory.getLeggings())) {
inventory.setLeggings(stack);
continue;
} else if (MaterialUtil.isBoots(material) && isEmptyStack(inventory.getBoots())) {
inventory.setBoots(stack);
continue;
}
}
itemList.add(metaStack.getItemStack()); itemList.add(metaStack.getItemStack());
} }
@ -253,4 +275,8 @@ public class Kit {
} }
return true; return true;
} }
private boolean isEmptyStack(ItemStack stack) {
return stack == null || stack.getType().isAir();
}
} }

View File

@ -1528,6 +1528,11 @@ public class Settings implements net.ess3.api.ISettings {
return newSigns; return newSigns;
} }
@Override
public boolean isKitAutoEquip() {
return config.getBoolean("kit-auto-equip", false);
}
@Override @Override
public boolean isPastebinCreateKit() { public boolean isPastebinCreateKit() {
return config.getBoolean("pastebin-createkit", false); return config.getBoolean("pastebin-createkit", false);

View File

@ -5,7 +5,7 @@ import org.bukkit.Statistic;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.HashSet; import java.util.EnumSet;
import java.util.Set; import java.util.Set;
public final class EnumUtil { public final class EnumUtil {
@ -22,7 +22,7 @@ public final class EnumUtil {
* @param <T> The enum to search through * @param <T> The enum to search through
* @return The first matching enum field * @return The first matching enum field
*/ */
public static <T extends Enum> T valueOf(final Class<T> enumClass, final String... names) { public static <T extends Enum<T>> T valueOf(final Class<T> enumClass, final String... names) {
for (final String name : names) { for (final String name : names) {
try { try {
final Field enumField = enumClass.getDeclaredField(name); final Field enumField = enumClass.getDeclaredField(name);
@ -46,8 +46,8 @@ public final class EnumUtil {
* @param <T> The enum to search through * @param <T> The enum to search through
* @return All matching enum fields * @return All matching enum fields
*/ */
public static <T extends Enum> Set<T> getAllMatching(final Class<T> enumClass, final String... names) { public static <T extends Enum<T>> Set<T> getAllMatching(final Class<T> enumClass, final String... names) {
final Set<T> set = new HashSet<>(); final Set<T> set = EnumSet.noneOf(enumClass);
for (final String name : names) { for (final String name : names) {
try { try {

View File

@ -25,7 +25,24 @@ public final class MaterialUtil {
private static final Set<Material> SIGN_POSTS; private static final Set<Material> SIGN_POSTS;
private static final Set<Material> WALL_SIGNS; private static final Set<Material> WALL_SIGNS;
private static final Set<Material> HELMETS;
private static final Set<Material> CHESTPLATES;
private static final Set<Material> LEGGINGS;
private static final Set<Material> BOOTS;
static { static {
HELMETS = EnumUtil.getAllMatching(Material.class, "LEATHER_HELMET", "CHAINMAIL_HELMET", "IRON_HELMET",
"GOLD_HELMET", "GOLDEN_HELMET", "DIAMOND_HELMET", "NETHERITE_HELMET", "TURTLE_HELMET");
CHESTPLATES = EnumUtil.getAllMatching(Material.class, "LEATHER_CHESTPLATE", "CHAINMAIL_CHESTPLATE",
"IRON_CHESTPLATE", "GOLD_CHESTPLATE", "GOLDEN_CHESTPLATE", "DIAMOND_CHESTPLATE", "NETHERITE_CHESTPLATE",
"ELYTRA");
LEGGINGS = EnumUtil.getAllMatching(Material.class, "LEATHER_LEGGINGS", "CHAINMAIL_LEGGINGS",
"IRON_LEGGINGS", "GOLD_LEGGINGS", "GOLDEN_LEGGINGS", "DIAMOND_LEGGINGS", "NETHERITE_LEGGINGS");
BOOTS = EnumUtil.getAllMatching(Material.class, "LEATHER_BOOTS", "CHAINMAIL_BOOTS", "IRON_BOOTS",
"GOLD_BOOTS", "GOLDEN_BOOTS", "DIAMOND_BOOTS", "NETHERITE_BOOTS");
BEDS = EnumUtil.getAllMatching(Material.class, "BED", "BED_BLOCK", "WHITE_BED", "ORANGE_BED", BEDS = EnumUtil.getAllMatching(Material.class, "BED", "BED_BLOCK", "WHITE_BED", "ORANGE_BED",
"MAGENTA_BED", "LIGHT_BLUE_BED", "YELLOW_BED", "LIME_BED", "PINK_BED", "GRAY_BED", "MAGENTA_BED", "LIGHT_BLUE_BED", "YELLOW_BED", "LIME_BED", "PINK_BED", "GRAY_BED",
@ -71,6 +88,22 @@ public final class MaterialUtil {
private MaterialUtil() { private MaterialUtil() {
} }
public static boolean isHelmet(final Material material) {
return HELMETS.contains(material);
}
public static boolean isChestplate(final Material material) {
return CHESTPLATES.contains(material);
}
public static boolean isLeggings(final Material material) {
return LEGGINGS.contains(material);
}
public static boolean isBoots(final Material material) {
return BOOTS.contains(material);
}
public static boolean isBed(final Material material) { public static boolean isBed(final Material material) {
return BEDS.contains(material); return BEDS.contains(material);
} }

View File

@ -321,6 +321,9 @@ use-bukkit-permissions: true
# removed from the /kit list when a player can no longer use it # removed from the /kit list when a player can no longer use it
skip-used-one-time-kits-from-kit-list: false skip-used-one-time-kits-from-kit-list: false
# When enabled, armor from kits will automatically be equipped as long as the player's armor slots are empty.
kit-auto-equip: false
# Determines the functionality of the /createkit command. # Determines the functionality of the /createkit command.
# If this is true, /createkit will give the user a link with the kit code. # If this is true, /createkit will give the user a link with the kit code.
# If this is false, /createkit will add the kit to the kits.yml config file directly. # If this is false, /createkit will add the kit to the kits.yml config file directly.