Implements armor trim salvage #24
All checks were successful
EpicKnarvik97/Blacksmith/pipeline/head This commit looks good

This commit is contained in:
2024-05-06 14:48:48 +02:00
parent 3ed3c99c15
commit e6047f3866
7 changed files with 226 additions and 56 deletions

View File

@ -141,6 +141,16 @@ public class ScrapperNPCSettings implements TraitSettings<ScrapperSetting> {
return asString(ScrapperSetting.COST_MESSAGE);
}
/**
* Gets the message to use for displaying armor trim salvage cost
*
* @return <p>The message to use for displaying armor trim salvage cost</p>
*/
@NotNull
public String getArmorTrimCostMessage() {
return asString(ScrapperSetting.COST_MESSAGE_ARMOR_TRIM);
}
@Override
@NotNull
public String getCoolDownUnexpiredMessage() {
@ -297,6 +307,15 @@ public class ScrapperNPCSettings implements TraitSettings<ScrapperSetting> {
return asBoolean(ScrapperSetting.SALVAGE_ENCHANTED);
}
/**
* Whether salvage of armor trims is enabled
*
* @return <p>True if this scrapper can salvage armor trims</p>
*/
public boolean salvageArmorTrims() {
return asBoolean(ScrapperSetting.SALVAGE_ARMOR_TRIMS);
}
/**
* Gets the title of this scrapper NPC
*
@ -371,4 +390,29 @@ public class ScrapperNPCSettings implements TraitSettings<ScrapperSetting> {
return asString(ScrapperSetting.CANNOT_SALVAGE_ENCHANTED_MESSAGE);
}
/**
* Gets the message to display when explaining that this scrapper is unable to salvage armor trims
*
* @return <p>The cannot salvage armor trim message</p>
*/
@NotNull
public String getCannotSalvageArmorTrimMessage() {
return asString(ScrapperSetting.CANNOT_SALVAGE_ARMOR_TRIM_MESSAGE);
}
/**
* Gets the message to display when explaining that this scrapper is unable to find salvage for the armor trim
*
* <p>Because there is no direct way (that I have found) to convert TrimMaterial and TrimPattern to Material, armor
* trim salvaging relies on material string and a hard-coded map. As those are prone to breaking because of API
* changes, there is a high likelihood that cases will arise when the scrapper is unable to find the correct
* materials.</p>
*
* @return <p>The cannot find armor trim salvage message</p>
*/
@NotNull
public String getArmorTrimSalvageNotFoundMessage() {
return asString(ScrapperSetting.ARMOR_TRIM_SALVAGE_NOT_FOUND_MESSAGE);
}
}

View File

@ -79,6 +79,12 @@ public enum ScrapperSetting implements Setting {
SALVAGE_ENCHANTED("salvageEnchanted", SettingValueType.BOOLEAN, false,
"Whether to enable salvaging of enchanted items. This is disabled by default because it's " +
"possible to accidentally salvage items with very good enchantments.", true, false),
/**
* The setting for whether the NPC should allow salvaging of armor trims
*/
SALVAGE_ARMOR_TRIMS("salvageArmorTrims", SettingValueType.BOOLEAN, true,
"Whether to enable salvaging of armor trims.", true, false),
/*-----------
| Messages |
@ -155,12 +161,19 @@ public enum ScrapperSetting implements Setting {
"The message to display when a player cannot pay for the salvaging", true, true),
/**
* The message displayed when displaying the cost of reforging the held item to the player
* The message displayed when displaying the cost of salvaging the held item to the player
*/
COST_MESSAGE("costMessage", SettingValueType.STRING,
"&eIt will cost &a{cost}&e to salvage that item! {yield} Click again to salvage!",
"The message to display when informing a player about the salvaging cost", true, true),
/**
* The message displayed when displaying the cost of salvaging the armor trim of the held item to the player
*/
COST_MESSAGE_ARMOR_TRIM("costMessageArmorTrim", SettingValueType.STRING,
"&eIt will cost &a{cost}&e to salvage that armor trim!",
"The message to display when explaining the shown item's armor trim's salvage cost", true, true),
/**
* The message displayed when explaining that all items will be returned as salvage
*/
@ -175,10 +188,27 @@ public enum ScrapperSetting implements Setting {
"&cI cannot extract all components from that damaged item.&r",
"The message to display when explaining expected partial yield as part of the cost message", true, true),
/**
* The message displayed when explaining that enchanted item salvage is disabled
*/
CANNOT_SALVAGE_ENCHANTED_MESSAGE("cannotSalvageEnchantedMessage", SettingValueType.STRING,
"&cI'm sorry, but I'm unable to salvage enchanted items!",
"The message to display when asked to salvage an enchanted item, and that option is disabled", true, true),
/**
* The message displayed when explaining that armor trim salvage is disabled
*/
CANNOT_SALVAGE_ARMOR_TRIM_MESSAGE("cannotSalvageArmorTrimMessage", SettingValueType.STRING,
"&cI'm sorry, but I'm unable to salvage armor trims!",
"The message to display when asked to salvage an armor trim, and that option is disabled", true, true),
/**
* The message displayed when explaining that the items to return as armor trim salvage are unknown
*/
ARMOR_TRIM_SALVAGE_NOT_FOUND_MESSAGE("armorTrimSalvageNotFoundMessage", SettingValueType.STRING,
"&cI'm sorry, but I don't know how to salvage that armor trim!",
"The message to display if the correct materials to return for the armor trim are unknown", true, true),
/*------------------
| Global settings |
------------------*/

View File

@ -13,6 +13,7 @@ import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ArmorMeta;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -87,6 +88,23 @@ public class ScrapperTrait extends CustomTrait<ScrapperSetting> {
return;
}
List<ItemStack> salvage = null;
// Deal with armor trim salvage
boolean salvagingArmorTrim = false;
if (itemInHand.getItemMeta() instanceof ArmorMeta armorMeta && armorMeta.hasTrim()) {
if (!getSettings().salvageArmorTrims()) {
sendNPCMessage(this.npc, player, getSettings().getCannotSalvageArmorTrimMessage());
return;
}
salvage = SalvageHelper.getTrimSalvage(itemInHand, armorMeta);
if (salvage == null) {
sendNPCMessage(this.npc, player, getSettings().getArmorTrimSalvageNotFoundMessage());
return;
}
salvagingArmorTrim = true;
}
// Check if the item is enchanted, and whether this blacksmith can salvage it
if (!itemInHand.getEnchantments().isEmpty() && !getSettings().salvageEnchanted()) {
sendNPCMessage(this.npc, player, getSettings().getCannotSalvageEnchantedMessage());
@ -94,7 +112,9 @@ public class ScrapperTrait extends CustomTrait<ScrapperSetting> {
}
// Check if any salvage will be produced
List<ItemStack> salvage = getSalvage(itemInHand, extended);
if (salvage == null) {
salvage = getSalvage(itemInHand, extended);
}
boolean noUsefulSalvage = salvage == null || salvage.isEmpty();
if (noUsefulSalvage) {
sendNPCMessage(this.npc, player, getSettings().getTooDamagedMessage());
@ -114,8 +134,13 @@ public class ScrapperTrait extends CustomTrait<ScrapperSetting> {
expectedYield = getSettings().getPartialSalvageMessage();
}
sendNPCMessage(this.npc, player, StringFormatter.replacePlaceholders(getSettings().getCostMessage(),
List.of("{cost}", "{yield}"), List.of(cost, expectedYield)));
if (salvagingArmorTrim) {
sendNPCMessage(this.npc, player, StringFormatter.replacePlaceholder(getSettings().getArmorTrimCostMessage(),
"{cost}", cost));
} else {
sendNPCMessage(this.npc, player, StringFormatter.replacePlaceholders(getSettings().getCostMessage(),
List.of("{cost}", "{yield}"), List.of(cost, expectedYield)));
}
}
@Override

View File

@ -8,6 +8,9 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Recipe;
import org.bukkit.inventory.ShapedRecipe;
import org.bukkit.inventory.ShapelessRecipe;
import org.bukkit.inventory.meta.ArmorMeta;
import org.bukkit.inventory.meta.trim.ArmorTrim;
import org.bukkit.inventory.meta.trim.TrimMaterial;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -24,6 +27,59 @@ import java.util.Random;
public final class SalvageHelper {
private static final Random random = new Random();
private static final Map<TrimMaterial, Material> trimMaterialToMaterial;
static {
trimMaterialToMaterial = new HashMap<>();
trimMaterialToMaterial.put(TrimMaterial.AMETHYST, Material.AMETHYST_SHARD);
trimMaterialToMaterial.put(TrimMaterial.COPPER, Material.COPPER_INGOT);
trimMaterialToMaterial.put(TrimMaterial.DIAMOND, Material.DIAMOND);
trimMaterialToMaterial.put(TrimMaterial.EMERALD, Material.EMERALD);
trimMaterialToMaterial.put(TrimMaterial.GOLD, Material.GOLD_INGOT);
trimMaterialToMaterial.put(TrimMaterial.IRON, Material.IRON_INGOT);
trimMaterialToMaterial.put(TrimMaterial.LAPIS, Material.LAPIS_LAZULI);
trimMaterialToMaterial.put(TrimMaterial.NETHERITE, Material.NETHERITE_INGOT);
trimMaterialToMaterial.put(TrimMaterial.QUARTZ, Material.QUARTZ);
trimMaterialToMaterial.put(TrimMaterial.REDSTONE, Material.REDSTONE);
}
/**
* Gets salvage for the given armor trim
*
* @param item <p>The item to have its armor trim salvaged</p>
* @param armorMeta <p>The armor meta of the item to salvage</p>
* @return <p>The salvage, or null if salvage could not be calculated</p>
*/
@Nullable
public static List<ItemStack> getTrimSalvage(@NotNull ItemStack item, @NotNull ArmorMeta armorMeta) {
ArmorTrim armorTrim = armorMeta.getTrim();
if (armorTrim == null) {
return null;
}
List<ItemStack> result = new ArrayList<>();
Material trimMaterial = trimMaterialToMaterial.get(armorTrim.getMaterial());
if (trimMaterial != null) {
result.add(new ItemStack(trimMaterial, 1));
} else {
return null;
}
Material patternMaterial = Material.matchMaterial(armorTrim.getPattern().getKey().getKey() +
"_ARMOR_TRIM_SMITHING_TEMPLATE");
if (patternMaterial != null) {
result.add(new ItemStack(patternMaterial, 1));
} else {
return null;
}
// Return a clone of the input item, with the armor trim removed
ItemStack strippedItem = item.clone();
armorMeta.setTrim(null);
strippedItem.setItemMeta(armorMeta);
result.add(strippedItem);
return result;
}
/**
* Gets whether the given item has a valid crafting recipe