Dynamically generate repair options for config

This commit is contained in:
Pim van der Loos 2021-11-01 15:56:52 +01:00
parent 53b5dfbc5f
commit 97b84ad211
No known key found for this signature in database
GPG Key ID: C16F020ADAE6D5A8
6 changed files with 172 additions and 60 deletions

39
pom.xml
View File

@ -14,10 +14,13 @@
<version.maven.checkstyle>3.1.2</version.maven.checkstyle> <version.maven.checkstyle>3.1.2</version.maven.checkstyle>
<version.maven.compiler>3.8.1</version.maven.compiler> <version.maven.compiler>3.8.1</version.maven.compiler>
<version.maven.shade>3.2.1</version.maven.shade> <version.maven.shade>3.2.1</version.maven.shade>
<version.maven.surefire>3.0.0-M5</version.maven.surefire>
<version.spigot>1.16.5-R0.1-SNAPSHOT</version.spigot> <version.spigot>1.16.5-R0.1-SNAPSHOT</version.spigot>
<version.bstats>2.2.1</version.bstats> <version.bstats>2.2.1</version.bstats>
<version.checkstyle>9.1</version.checkstyle> <version.checkstyle>9.1</version.checkstyle>
<version.mockito>4.0.0</version.mockito>
<version.junit>5.8.1</version.junit>
</properties> </properties>
<repositories> <repositories>
@ -48,6 +51,32 @@
<version>${version.checkstyle}</version> <version>${version.checkstyle}</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${version.junit}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${version.junit}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${version.mockito}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>${version.mockito}</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>
@ -96,6 +125,16 @@
<configLocation>checkstyle.xml</configLocation> <configLocation>checkstyle.xml</configLocation>
</configuration> </configuration>
</plugin> </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${version.maven.surefire}</version>
<configuration>
<trimStackTrace>false</trimStackTrace>
<useFile>false</useFile>
</configuration>
</plugin>
</plugins> </plugins>
</build> </build>
</project> </project>

View File

@ -1,6 +1,8 @@
package nl.pim16aap2.armoredElytra.handlers; package nl.pim16aap2.armoredElytra.handlers;
import nl.pim16aap2.armoredElytra.ArmoredElytra; import nl.pim16aap2.armoredElytra.ArmoredElytra;
import nl.pim16aap2.armoredElytra.util.ArmorTier;
import nl.pim16aap2.armoredElytra.util.ConfigLoader;
import nl.pim16aap2.armoredElytra.util.XMaterial; import nl.pim16aap2.armoredElytra.util.XMaterial;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Color; import org.bukkit.Color;
@ -18,40 +20,41 @@ import javax.annotation.CheckReturnValue;
*/ */
abstract class ArmoredElytraHandler abstract class ArmoredElytraHandler
{ {
protected final ArmoredElytra plugin;
protected final boolean creationEnabled;
private static final Color DEFAULT_LEATHER_COLOR = Bukkit.getServer().getItemFactory().getDefaultLeatherColor(); private static final Color DEFAULT_LEATHER_COLOR = Bukkit.getServer().getItemFactory().getDefaultLeatherColor();
protected final ArmoredElytra plugin;
protected final boolean creationEnabled;
private final ConfigLoader config;
public ArmoredElytraHandler(final ArmoredElytra plugin, final boolean creationEnabled) public ArmoredElytraHandler(final ArmoredElytra plugin, final boolean creationEnabled)
{ {
this.plugin = plugin; this.plugin = plugin;
this.creationEnabled = creationEnabled; this.creationEnabled = creationEnabled;
config = plugin.getConfigLoader();
} }
// Repair an Armored Elytra // Repair an Armored Elytra
protected short repairItem(short curDur, ItemStack repairItem) protected short repairItem(short curDur, ItemStack repairItem)
{ {
// Get the multiplier for the repair items. final ArmorTier repairTier;
double mult = 0.01;
if (repairItem.getType().equals(Material.LEATHER)) if (repairItem.getType().equals(Material.LEATHER))
mult *= (100.0f / plugin.getConfigLoader().LEATHER_TO_FULL()); repairTier = ArmorTier.LEATHER;
else if (repairItem.getType().equals(Material.GOLD_INGOT)) else if (repairItem.getType().equals(Material.GOLD_INGOT))
mult *= (100.0f / plugin.getConfigLoader().GOLD_TO_FULL()); repairTier = ArmorTier.GOLD;
else if (repairItem.getType().equals(Material.IRON_INGOT)) else if (repairItem.getType().equals(Material.IRON_INGOT))
mult *= (100.0f / plugin.getConfigLoader().IRON_TO_FULL()); repairTier = ArmorTier.IRON;
else if (repairItem.getType().equals(Material.DIAMOND)) else if (repairItem.getType().equals(Material.DIAMOND))
mult *= (100.0f / plugin.getConfigLoader().DIAMONDS_TO_FULL()); repairTier = ArmorTier.DIAMOND;
else if (repairItem.getType().equals(XMaterial.NETHERITE_INGOT.parseMaterial())) else if (repairItem.getType().equals(XMaterial.NETHERITE_INGOT.parseMaterial()))
mult *= (100.0f / plugin.getConfigLoader().NETHERITE_TO_FULL()); repairTier = ArmorTier.NETHERITE;
else
repairTier = ArmorTier.NONE;
final int repairCount = Math.max(1, config.getFullRepairItemCount(repairTier));
final double repairPercentage = 1f / repairCount;
int maxDurability = Material.ELYTRA.getMaxDurability(); int maxDurability = Material.ELYTRA.getMaxDurability();
int newDurability = (int) (curDur - repairItem.getAmount() * (maxDurability * mult)); int newDurability = (int) (curDur - repairItem.getAmount() * (maxDurability * repairPercentage));
return (short) (Math.max(newDurability, 0)); return (short) (Math.max(newDurability, 0));
} }

View File

@ -7,14 +7,14 @@ import java.util.Map;
public enum ArmorTier public enum ArmorTier
{ {
// Tier: TierID, armor-value, armor-toughness, knockbackResistance, repair // Tier: TierID, armor-value, armor-toughness, knockbackResistance, repair, defaultRepairCount, name, durability
NONE(0, 0, 0, 0, null, ""), NONE(0, 0, 0, 0, null, 0, "", 0),
LEATHER(1, 3, 0, 0, Material.LEATHER, "leather"), LEATHER(1, 3, 0, 0, Material.LEATHER, 6, "leather", 80),
GOLD(2, 5, 0, 0, Material.GOLD_INGOT, "gold"), GOLD(2, 5, 0, 0, Material.GOLD_INGOT, 6, "gold", 112),
CHAIN(3, 5, 0, 0, Material.IRON_INGOT, "chain"), CHAIN(3, 5, 0, 0, Material.IRON_INGOT, 4, "chain", 240),
IRON(4, 6, 0, 0, Material.IRON_INGOT, "iron"), IRON(4, 6, 0, 0, Material.IRON_INGOT, 4, "iron", 240),
DIAMOND(5, 8, 2, 0, Material.DIAMOND, "diamond"), DIAMOND(5, 8, 2, 0, Material.DIAMOND, 3, "diamond", 528),
NETHERITE(6, 8, 3, 0.1, XMaterial.NETHERITE_INGOT.parseMaterial(), "netherite"), NETHERITE(6, 8, 3, 0.1, XMaterial.NETHERITE_INGOT.parseMaterial(), 3, "netherite", 592),
; ;
private final int tierID; private final int tierID;
@ -22,34 +22,41 @@ public enum ArmorTier
private final int toughness; private final int toughness;
private final double knockbackResistance; private final double knockbackResistance;
private final Material repair; private final Material repair;
private final int defaultRepairCount;
private final String name; private final String name;
private final int durability;
private static final Map<String, ArmorTier> map = new HashMap<>(); private static final Map<String, ArmorTier> map = new HashMap<>();
private static final Map<Integer, ArmorTier> armorValueMap = new HashMap<>(); private static final Map<Integer, ArmorTier> armorValueMap = new HashMap<>();
private static final Map<Integer, ArmorTier> armorIDMap = new HashMap<>(); private static final Map<Integer, ArmorTier> armorIDMap = new HashMap<>();
ArmorTier(int tierID, int armor, int toughness, double knockbackResistance, Material repair, String name) ArmorTier(int tierID, int armor, int toughness, double knockbackResistance, Material repair, int defaultRepairCount,
String name, int durability)
{ {
this.tierID = tierID; this.tierID = tierID;
this.armor = armor; this.armor = armor;
this.toughness = toughness; this.toughness = toughness;
this.knockbackResistance = knockbackResistance; this.knockbackResistance = knockbackResistance;
this.repair = repair; this.repair = repair;
this.defaultRepairCount = defaultRepairCount;
this.name = name; this.name = name;
this.durability = durability;
} }
// return the armor value of a tier.
public static int getArmor(ArmorTier tier) public static int getArmor(ArmorTier tier)
{ {
return tier.armor; return tier.armor;
} }
// return the armor value of a tier. public static int getMaxDurability(ArmorTier tier)
{
return tier.durability;
}
public static int getTierID(ArmorTier tier) public static int getTierID(ArmorTier tier)
{ {
return tier.tierID; return tier.tierID;
} }
// return the armor toughness of a tier.
public static int getToughness(ArmorTier tier) public static int getToughness(ArmorTier tier)
{ {
return tier.toughness; return tier.toughness;
@ -105,4 +112,9 @@ public enum ArmorTier
// be around from when it was still used. // be around from when it was still used.
armorValueMap.put(ArmorTier.DIAMOND.armor, ArmorTier.DIAMOND); armorValueMap.put(ArmorTier.DIAMOND.armor, ArmorTier.DIAMOND);
} }
public static int getDefaultRepairCount(ArmorTier armorTier)
{
return armorTier.defaultRepairCount;
}
} }

View File

@ -6,6 +6,7 @@ import org.bukkit.NamespacedKey;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import javax.annotation.Nullable;
import java.io.File; import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
@ -23,13 +24,16 @@ public class ConfigLoader
private boolean unbreakable; private boolean unbreakable;
private boolean enableDebug; private boolean enableDebug;
private String languageFile; private String languageFile;
private int GOLD_TO_FULL;
private int IRON_TO_FULL; private final int[] repairCounts = new int[ArmorTier.values().length];
private int goldToFull;
private int ironToFull;
private int leatherToFull;
private int diamondsToFull;
private int netheriteToFull;
private boolean uninstallMode; private boolean uninstallMode;
private boolean checkForUpdates; private boolean checkForUpdates;
private int LEATHER_TO_FULL;
private int DIAMONDS_TO_FULL;
private int NETHERITE_TO_FULL;
private boolean noFlightDurability; private boolean noFlightDurability;
private boolean dropNetheriteAsChestplate; private boolean dropNetheriteAsChestplate;
private LinkedHashSet<Enchantment> allowedEnchantments; private LinkedHashSet<Enchantment> allowedEnchantments;
@ -163,11 +167,25 @@ public class ConfigLoader
unbreakable = addNewConfigOption(config, "unbreakable", false, unbreakableComment); unbreakable = addNewConfigOption(config, "unbreakable", false, unbreakableComment);
noFlightDurability = addNewConfigOption(config, "noFlightDurability", false, flyDurabilityComment); noFlightDurability = addNewConfigOption(config, "noFlightDurability", false, flyDurabilityComment);
LEATHER_TO_FULL = addNewConfigOption(config, "leatherRepair", 6, repairComment);
GOLD_TO_FULL = addNewConfigOption(config, "goldRepair", 5, null); final ArmorTier[] armorTiers = ArmorTier.values();
IRON_TO_FULL = addNewConfigOption(config, "ironRepair", 4, null); for (int idx = 1; idx < armorTiers.length; ++idx)
DIAMONDS_TO_FULL = addNewConfigOption(config, "diamondsRepair", 3, null); {
NETHERITE_TO_FULL = addNewConfigOption(config, "netheriteIngotsRepair", 3, null); final ArmorTier armorTier = armorTiers[idx];
// Only the first one should have the comment.
final @Nullable String[] comment = idx == 1 ? repairComment : null;
final String name = Util.snakeToCamelCase(ArmorTier.getRepairItem(armorTier).name());
final int defaultRepairCount = ArmorTier.getDefaultRepairCount(armorTier);
repairCounts[idx] = addNewConfigOption(config, name, defaultRepairCount, comment);
}
final int armorTierCount = ArmorTier.values().length;
if (repairCounts.length != armorTierCount)
throw new IllegalStateException("Incorrect repair counts array size! Expected size " +
armorTierCount + " but got size " + repairCounts.length);
final boolean smithingTableAllowed = plugin.getMinecraftVersion().isNewerThan(MinecraftVersion.v1_15); final boolean smithingTableAllowed = plugin.getMinecraftVersion().isNewerThan(MinecraftVersion.v1_15);
craftingInSmithingTable = addNewConfigOption(config, "craftingInSmithingTable", smithingTableAllowed, craftingInSmithingTable = addNewConfigOption(config, "craftingInSmithingTable", smithingTableAllowed,
@ -308,29 +326,9 @@ public class ConfigLoader
return languageFile; return languageFile;
} }
public int LEATHER_TO_FULL() public int getFullRepairItemCount(ArmorTier armorTier)
{ {
return LEATHER_TO_FULL; return repairCounts[ArmorTier.getArmor(armorTier)];
}
public int GOLD_TO_FULL()
{
return GOLD_TO_FULL;
}
public int IRON_TO_FULL()
{
return IRON_TO_FULL;
}
public int DIAMONDS_TO_FULL()
{
return DIAMONDS_TO_FULL;
}
public int NETHERITE_TO_FULL()
{
return NETHERITE_TO_FULL;
} }
public boolean allowMultipleProtectionEnchantments() public boolean allowMultipleProtectionEnchantments()
@ -382,4 +380,10 @@ public class ConfigLoader
{ {
return bypassCraftPerm; return bypassCraftPerm;
} }
public boolean useTierDurability()
{
// TODO: Implement this option.
return true;
}
} }

View File

@ -6,6 +6,7 @@ import org.bukkit.inventory.ItemStack;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.util.Locale;
import java.util.Map; import java.util.Map;
public class Util public class Util
@ -85,6 +86,41 @@ public class Util
} }
} }
public static String snakeToCamelCase(String input)
{
final char[] arr = input.toLowerCase(Locale.US).toCharArray();
int skipped = 0;
boolean capitalize = false;
for (int idx = 0; idx < arr.length; ++idx)
{
char current = arr[idx];
if (current == '_')
{
++skipped;
capitalize = true;
continue;
}
final int targetIdx = idx - skipped;
if (capitalize)
{
if (targetIdx > 0)
current = Character.toUpperCase(current);
capitalize = false;
}
// targetIdx is always <= idx, so we can reuse the current array
// without overwriting any values we will need in the future.
arr[targetIdx] = current;
}
return new String(arr, 0, arr.length - skipped);
}
// Function that returns which/how many protection enchantments there are. // Function that returns which/how many protection enchantments there are.
public static int getProtectionEnchantmentsVal(Map<Enchantment, Integer> enchantments) public static int getProtectionEnchantmentsVal(Map<Enchantment, Integer> enchantments)
{ {

View File

@ -0,0 +1,18 @@
package nl.pim16aap2.armoredElytra.util;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
class UtilTest
{
@Test
void testSnakeToCamelCase()
{
Assertions.assertEquals("testCase", Util.snakeToCamelCase("TeSt_Case"));
Assertions.assertEquals("testCase", Util.snakeToCamelCase("____test_case"));
Assertions.assertEquals("", Util.snakeToCamelCase("________"));
Assertions.assertEquals("testCase", Util.snakeToCamelCase("TeSt__Case____"));
Assertions.assertEquals("t", Util.snakeToCamelCase("_T_"));
Assertions.assertEquals("testcase", Util.snakeToCamelCase("TeStCase"));
}
}