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

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

View File

@ -150,10 +150,10 @@ All currently supported presets, and available filters for each preset:
## Permissions ## Permissions
| Permission node | Description | | Permission node | Description |
|------------------|----------------------------------------------------------| |------------------|----------------------------------------------------------------------------------------|
| blacksmith.admin | Allows overall blacksmith configuration | | blacksmith.admin | Allows overall blacksmith and scrapper configuration. |
| blacksmith.edit | Allows changing settings for the selected blacksmith NPC | | blacksmith.edit | Allows changing settings for the selected blacksmith or scrapper NPC. |
| blacksmith.use | Allows the player to repair items using blacksmiths | | blacksmith.use | Allows the player to repair items using blacksmiths and salvage items using scrappers. |
## Configuration options ## Configuration options
@ -171,7 +171,7 @@ All currently supported presets, and available filters for each preset:
| pricePerDurabilityPoint | positive decimal number | \[default: 0.005] | The price added for each durability point present/missing (depends on whether natural cost is set to true or false). Setting this without specifying a material sets the pricePerDurabilityPoint for any item the pricePerDurabilityPoint has not been set for. You can use for example "netherite*: 10" to set the value for any material beginning with "netherite". | | pricePerDurabilityPoint | positive decimal number | \[default: 0.005] | The price added for each durability point present/missing (depends on whether natural cost is set to true or false). Setting this without specifying a material sets the pricePerDurabilityPoint for any item the pricePerDurabilityPoint has not been set for. You can use for example "netherite*: 10" to set the value for any material beginning with "netherite". |
| enchantmentCost | positive decimal number | \[default: 5] | The added cost for each level of an enchantment present on the item. The cost can be set for specific enchantments. Not specifying an enchantment sets the value for all enchantments without a set value. | | enchantmentCost | positive decimal number | \[default: 5] | The added cost for each level of an enchantment present on the item. The cost can be set for specific enchantments. Not specifying an enchantment sets the value for all enchantments without a set value. |
| useNaturalCost | true/false | true | If true, each missing durability will add to the cost (price = basePrice + missingDurability * pricePerDurabilityPoint + enchantmentCost). If false, durability will be used to calculate the cost instead of missingDurability (this was the behavior before natural cost was added). | | useNaturalCost | true/false | true | If true, each missing durability will add to the cost (price = basePrice + missingDurability * pricePerDurabilityPoint + enchantmentCost). If false, durability will be used to calculate the cost instead of missingDurability (this was the behavior before natural cost was added). |
| showExactTime | true/false | false | If true, blacksmiths will display exact time remaining in minutes and seconds, instead of vague expressions | | showExactTime | true/false | false | If true, blacksmiths will display exact time remaining in minutes and seconds, instead of vague expressions. |
| chippedAnvilReforgingCost | positive decimal number | 10.0 | The price for reforging a chipped anvil (slightly damaged). No other costs apply! | | chippedAnvilReforgingCost | positive decimal number | 10.0 | The price for reforging a chipped anvil (slightly damaged). No other costs apply! |
| damagedAnvilReforgingCost | positive decimal number | 20.0 | The price for reforging a damaged anvil (very damaged). No other costs apply! | | damagedAnvilReforgingCost | positive decimal number | 20.0 | The price for reforging a damaged anvil (very damaged). No other costs apply! |
@ -197,27 +197,27 @@ All currently supported presets, and available filters for each preset:
#### Messages #### Messages
| Message Key | Default | Explanation | | Message Key | Default | Explanation |
|--------------------------|-------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------| |--------------------------|-------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------|
| busyPlayerMessage | &cI'm busy at the moment. Come back later! | The message displayed when the blacksmith is serving another player | | busyPlayerMessage | &cI'm busy at the moment. Come back later! | The message displayed when the blacksmith is serving another player. |
| busyReforgeMessage | &cI'm working on it. Be patient! I'll finish {time}! | The message displayed when the blacksmith is busy reforging an item | | busyReforgeMessage | &cI'm working on it. Be patient! I'll finish {time}! | The message displayed when the blacksmith is busy reforging an item. |
| coolDownUnexpiredMessage | &cYou've already had your chance! Give me a break! I'll be ready {time}! | The message displayed when the player has to wait for the cool-down to expire before using the blacksmith again | | coolDownUnexpiredMessage | &cYou've already had your chance! Give me a break! I'll be ready {time}! | The message displayed when the player has to wait for the cool-down to expire before using the blacksmith again. |
| costMessage | &eIt will cost &a{cost}&e to reforge that &a{item}&e! Click again to reforge! | The message displayed when telling a player about the cost of repairing an item | | costMessage | &eIt will cost &a{cost}&e to reforge that &a{item}&e! Click again to reforge! | The message displayed when telling a player about the cost of repairing an item. |
| failReforgeMessage | &cWhoops! Didn't mean to do that! Maybe next time? | The message displayed when a blacksmith fails to reforge an item | | failReforgeMessage | &cWhoops! Didn't mean to do that! Maybe next time? | The message displayed when a blacksmith fails to reforge an item. |
| insufficientFundsMessage | &cYou don't have enough money to reforge that item! | The message displayed when a player is unable to pay for reforging an item | | insufficientFundsMessage | &cYou don't have enough money to reforge that item! | The message displayed when a player is unable to pay for reforging an item. |
| invalidItemMessage | &cI'm sorry, but I'm a/an {title}, I don't know how to reforge that! | The message displayed when a blacksmith is presented an item which it cannot repair | | invalidItemMessage | &cI'm sorry, but I'm a/an {title}, I don't know how to reforge that! | The message displayed when a blacksmith is presented an item which it cannot repair. |
| itemChangedMessage | &cThat's not the item you wanted to reforge before! | The message displayed when a player changes their item after being shown the repair cost | | itemChangedMessage | &cThat's not the item you wanted to reforge before! | The message displayed when a player changes their item after being shown the repair cost. |
| startReforgeMessage | &eOk, let's see what I can do... | The message displayed when a blacksmith starts reforging an item | | startReforgeMessage | &eOk, let's see what I can do... | The message displayed when a blacksmith starts reforging an item. |
| successMessage | There you go! All better! | The message displayed when a blacksmith successfully repairs an item | | successMessage | There you go! All better! | The message displayed when a blacksmith successfully repairs an item. |
| notDamagedMessage | &cThat item is not in need of repair | The message displayed if a player tries to reforge an item with full durability | | notDamagedMessage | &cThat item is not in need of repair | The message displayed if a player tries to reforge an item with full durability. |
### Scrapper global-only options ### Scrapper global-only options
| Key | Value type | Default | Description | | Key | Value type | Default | Description |
|----------------|------------------------------------------------------------|---------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |----------------|------------------------------------------------------------|---------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| basePrice | positive decimal number | 0 | The cost of using a scrapper | | basePrice | positive decimal number | 0 | The cost of using a scrapper. |
| showExactTime | true/false | false | If true, scrappers will display exact time remaining in minutes and seconds, instead of vague expressions | | showExactTime | true/false | false | If true, scrappers will display exact time remaining in minutes and seconds, instead of vague expressions. |
| giveExperience | true/false | true | If true, each enchantment level on the salvaged item will give one EXP level as salvage | | giveExperience | true/false | true | If true, each enchantment level on the salvaged item will give one EXP level as salvage. |
| trashSalvage | TARGET_MATERIAL:IGNORED_MATERIAL\[,\*_TARGET2:\*_IGNORED2] | `"*_SHOVEL;*_PICKAXE;*_AXE;*_HOE;*_SWORD;SHIELD;*_BOW:STICK"` | The items that should be deferred when calculating partial salvage. Because receiving just the sticks when salvaging a diamond pickaxe is kind of sad, this allows specifying for example: `*_SHOVEL;*_PICKAXE;*_AXE;*_HOE;*_SWORD;SHIELD;*_BOW:STICK` (the default) for deferring sticks in salvage for shovels, pickaxes, axes, hoes and swords. A `:` character splits selected items and the trash salvage. Different item specifications are split by a `;` character. Use `,` to split separate trash salvages when using commands, like: `SHIELD:STICK,BOW_STRING` | | trashSalvage | TARGET_MATERIAL:IGNORED_MATERIAL\[,\*_TARGET2:\*_IGNORED2] | `"*_SHOVEL;*_PICKAXE;*_AXE;*_HOE;*_SWORD;SHIELD;*_BOW:STICK"` | The items that should be deferred when calculating partial salvage. Because receiving just the sticks when salvaging a diamond pickaxe is kind of sad, this allows specifying for example: `*_SHOVEL;*_PICKAXE;*_AXE;*_HOE;*_SWORD;SHIELD;*_BOW:STICK` (the default) for deferring sticks in salvage for shovels, pickaxes, axes, hoes and swords. A `:` character splits selected items and the trash salvage. Different item specifications are split by a `;` character. Use `,` to split separate trash salvages when using commands, like: `SHIELD:STICK,BOW_STRING`. |
### Scrapper per-npc (with default values set in config.yml) ### Scrapper per-npc (with default values set in config.yml)
@ -231,28 +231,31 @@ All currently supported presets, and available filters for each preset:
| maxSalvageWaitTimeSeconds | 0-3600 | 5 | The maximum number of seconds a player needs to wait for an item to be salvaged. | | maxSalvageWaitTimeSeconds | 0-3600 | 5 | The maximum number of seconds a player needs to wait for an item to be salvaged. |
| minSalvageWaitTimeSeconds | 0-3600 | 30 | The minimum number of seconds a player needs to wait for an item to be salvaged. | | minSalvageWaitTimeSeconds | 0-3600 | 30 | The minimum number of seconds a player needs to wait for an item to be salvaged. |
| salvageCoolDownSeconds | 0-3600 | 60 | The cool-down, in seconds, a player has to wait between each time they use one specific scrapper. | | salvageCoolDownSeconds | 0-3600 | 60 | The cool-down, in seconds, a player has to wait between each time they use one specific scrapper. |
| scrapperTitle | text string | scrapper | The title displayed as part of the message explaining that a scrapper doesn't recognize a player's held item | | scrapperTitle | text string | scrapper | The title displayed as part of the message explaining that a scrapper doesn't recognize a player's held item. |
| extendedSalvageEnabled | true/false | false | Whether to enable the extended salvage behavior for this scrapper. As long as it is allowed by salvageAbleItems and it can be crafted in a crafting table, it can be salvaged. This includes things like four planks salvaged into wood. | | extendedSalvageEnabled | true/false | false | Whether to enable the extended salvage behavior for this scrapper. As long as it is allowed by salvageAbleItems and it can be crafted in a crafting table, it can be salvaged. This includes things like four planks salvaged into wood. |
| salvageEnchanted | true/false | false | Whether the scrapper is able to salvage enchanted items. This is disabled by default as it's very easy to accidentally salvage heavily enchanted items if one is not careful. | | salvageEnchanted | true/false | false | Whether the scrapper is able to salvage enchanted items. This is disabled by default as it's very easy to accidentally salvage heavily enchanted items if one is not careful. |
| salvageArmorTrims | true/false | true | Whether the scrapper is able to salvage armor trims. |
#### Messages #### Messages
| Message Key | Default | Explanation | | Message Key | Default | Explanation |
|-------------------------------|-----------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------| |---------------------------------|-----------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------|
| busyPlayerMessage | &cI'm busy at the moment. Come back later! | The message displayed when the scrapper is serving another player | | busyPlayerMessage | &cI'm busy at the moment. Come back later! | The message displayed when the scrapper is serving another player. |
| busySalvageMessage | &cI'm working on it. Be patient! I'll finish {time}! | The message displayed when the scrapper is busy salvaging an item | | busySalvageMessage | &cI'm working on it. Be patient! I'll finish {time}! | The message displayed when the scrapper is busy salvaging an item. |
| coolDownUnexpiredMessage | &cYou've already had your chance! Give me a break! I'll be ready {time}! | The message displayed when the player has to wait for the cool-down to expire before using the scrapper again | | coolDownUnexpiredMessage | &cYou've already had your chance! Give me a break! I'll be ready {time}! | The message displayed when the player has to wait for the cool-down to expire before using the scrapper again. |
| invalidItemMessage | &cI'm sorry, but I'm a/an {title}, I don't know how to salvage that! | The message displayed when a scrapper is presented an item which it cannot salvage | | invalidItemMessage | &cI'm sorry, but I'm a/an {title}, I don't know how to salvage that! | The message displayed when a scrapper is presented an item which it cannot salvage. |
| tooDamagedForSalvageMessage | &cThat item is too damaged to be salvaged into anything useful | The message displayed when a scrapper is presented with an item too damaged to produce salvage | | tooDamagedForSalvageMessage | &cThat item is too damaged to be salvaged into anything useful | The message displayed when a scrapper is presented with an item too damaged to produce salvage. |
| successSalvagedMessage | There you go! | The message displayed when a scrapper successfully repairs an item | | successSalvagedMessage | There you go! | The message displayed when a scrapper successfully repairs an item. |
| failSalvageMessage | &cWhoops! The item broke! Maybe next time? | The message displayed when a scrapper fails to salvage an item | | failSalvageMessage | &cWhoops! The item broke! Maybe next time? | The message displayed when a scrapper fails to salvage an item. |
| itemChangedMessage | &cThat's not the item you wanted to salvage before! | The message displayed when a player changes their item after being shown the salvage cost | | itemChangedMessage | &cThat's not the item you wanted to salvage before! | The message displayed when a player changes their item after being shown the salvage cost. |
| startSalvageMessage | &eOk, let's see what I can do... | The message displayed when a scrapper starts salvaging an item | | startSalvageMessage | &eOk, let's see what I can do... | The message displayed when a scrapper starts salvaging an item. |
| insufficientFundsMessage | &cYou don't have enough money to salvage an item! | The message displayed when a player is unable to pay for scrapping an item | | insufficientFundsMessage | &cYou don't have enough money to salvage an item! | The message displayed when a player is unable to pay for scrapping an item. |
| costMessage | &eIt will cost &a{cost}&e to salvage that item! {yield} &eClick again to salvage! | The message displayed when telling a player about the cost of scrapping an item | | costMessage | &eIt will cost &a{cost}&e to salvage that item! {yield} &eClick again to salvage! | The message displayed when telling a player about the cost of scrapping an item. |
| fullSalvageMessage | &aI should be able to extract all components from that pristine item.&r | The message displayed as part of costMessage's yield placeholder if all components will be returned | | fullSalvageMessage | &aI should be able to extract all components from that pristine item.&r | The message displayed as part of costMessage's yield placeholder if all components will be returned. |
| partialSalvageMessage | &cI cannot extract all components from that damaged item.&r | The message displayed as part of costMessage's yield placeholder if only some components will be returned | | partialSalvageMessage | &cI cannot extract all components from that damaged item.&r | The message displayed as part of costMessage's yield placeholder if only some components will be returned. |
| cannotSalvageEnchantedMessage | &cI'm sorry, but I'm unable to salvage enchanted items! | The message displayed when telling a player that the scrapper cannot salvage enchanted items | | cannotSalvageEnchantedMessage | &cI'm sorry, but I'm unable to salvage enchanted items! | The message displayed when telling a player that the scrapper cannot salvage enchanted items. |
| cannotSalvageArmorTrimMessage | &cI'm sorry, but I'm unable to salvage armor trims! | The message displayed when telling a player that the scrapper cannot salvage items with armor trim. |
| armorTrimSalvageNotFoundMessage | "&cI'm sorry, but I don't know how to salvage that armor trim!" | The message displayed when telling a player that the scrapper cannot find the correct items to return as armor trim salvage. |
## Language customization ## Language customization

View File

@ -141,6 +141,16 @@ public class ScrapperNPCSettings implements TraitSettings<ScrapperSetting> {
return asString(ScrapperSetting.COST_MESSAGE); 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 @Override
@NotNull @NotNull
public String getCoolDownUnexpiredMessage() { public String getCoolDownUnexpiredMessage() {
@ -297,6 +307,15 @@ public class ScrapperNPCSettings implements TraitSettings<ScrapperSetting> {
return asBoolean(ScrapperSetting.SALVAGE_ENCHANTED); 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 * Gets the title of this scrapper NPC
* *
@ -371,4 +390,29 @@ public class ScrapperNPCSettings implements TraitSettings<ScrapperSetting> {
return asString(ScrapperSetting.CANNOT_SALVAGE_ENCHANTED_MESSAGE); 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

@ -80,6 +80,12 @@ public enum ScrapperSetting implements Setting {
"Whether to enable salvaging of enchanted items. This is disabled by default because it's " + "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), "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 | | 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 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, COST_MESSAGE("costMessage", SettingValueType.STRING,
"&eIt will cost &a{cost}&e to salvage that item! {yield} Click again to salvage!", "&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 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 * 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", "&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 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, CANNOT_SALVAGE_ENCHANTED_MESSAGE("cannotSalvageEnchantedMessage", SettingValueType.STRING,
"&cI'm sorry, but I'm unable to salvage enchanted items!", "&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 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 | | Global settings |
------------------*/ ------------------*/

View File

@ -13,6 +13,7 @@ import org.bukkit.Material;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ArmorMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -87,6 +88,23 @@ public class ScrapperTrait extends CustomTrait<ScrapperSetting> {
return; 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 // Check if the item is enchanted, and whether this blacksmith can salvage it
if (!itemInHand.getEnchantments().isEmpty() && !getSettings().salvageEnchanted()) { if (!itemInHand.getEnchantments().isEmpty() && !getSettings().salvageEnchanted()) {
sendNPCMessage(this.npc, player, getSettings().getCannotSalvageEnchantedMessage()); sendNPCMessage(this.npc, player, getSettings().getCannotSalvageEnchantedMessage());
@ -94,7 +112,9 @@ public class ScrapperTrait extends CustomTrait<ScrapperSetting> {
} }
// Check if any salvage will be produced // 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(); boolean noUsefulSalvage = salvage == null || salvage.isEmpty();
if (noUsefulSalvage) { if (noUsefulSalvage) {
sendNPCMessage(this.npc, player, getSettings().getTooDamagedMessage()); sendNPCMessage(this.npc, player, getSettings().getTooDamagedMessage());
@ -114,9 +134,14 @@ public class ScrapperTrait extends CustomTrait<ScrapperSetting> {
expectedYield = getSettings().getPartialSalvageMessage(); expectedYield = getSettings().getPartialSalvageMessage();
} }
if (salvagingArmorTrim) {
sendNPCMessage(this.npc, player, StringFormatter.replacePlaceholder(getSettings().getArmorTrimCostMessage(),
"{cost}", cost));
} else {
sendNPCMessage(this.npc, player, StringFormatter.replacePlaceholders(getSettings().getCostMessage(), sendNPCMessage(this.npc, player, StringFormatter.replacePlaceholders(getSettings().getCostMessage(),
List.of("{cost}", "{yield}"), List.of(cost, expectedYield))); List.of("{cost}", "{yield}"), List.of(cost, expectedYield)));
} }
}
@Override @Override
protected boolean showExactTime() { protected boolean showExactTime() {

View File

@ -8,6 +8,9 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Recipe; import org.bukkit.inventory.Recipe;
import org.bukkit.inventory.ShapedRecipe; import org.bukkit.inventory.ShapedRecipe;
import org.bukkit.inventory.ShapelessRecipe; 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.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -24,6 +27,59 @@ import java.util.Random;
public final class SalvageHelper { public final class SalvageHelper {
private static final Random random = new Random(); 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 * Gets whether the given item has a valid crafting recipe

View File

@ -167,6 +167,9 @@ scrapper:
# salvage items with very good enchantments. # salvage items with very good enchantments.
salvageEnchanted: false salvageEnchanted: false
# Whether to enable salvaging of armor trims
salvageArmorTrims: true
# Default values for messages used by NPCs # Default values for messages used by NPCs
messages: messages:
# The message to display when another player is using the scrapper # The message to display when another player is using the scrapper
@ -202,6 +205,9 @@ scrapper:
# The message to display when explaining the shown item's salvage cost # The message to display when explaining the shown item's salvage cost
costMessage: "&eIt will cost &a{cost}&e to salvage that item! {yield} &eClick again to salvage!" costMessage: "&eIt will cost &a{cost}&e to salvage that item! {yield} &eClick again to salvage!"
# The message to display when explaining the shown item's armor trim's salvage cost
costMessageArmorTrim: "&eIt will cost &a{cost}&e to salvage that armor trim!"
# The yield message to display if trying to salvage a non-damaged item # The yield message to display if trying to salvage a non-damaged item
fullSalvageMessage: "&aI should be able to extract all components from that pristine item.&r" fullSalvageMessage: "&aI should be able to extract all components from that pristine item.&r"
@ -210,3 +216,9 @@ scrapper:
# The message to display when asked to salvage an enchanted item, and that option is disabled # The message to display when asked to salvage an enchanted item, and that option is disabled
cannotSalvageEnchantedMessage: "&cI'm sorry, but I'm unable to salvage enchanted items!" cannotSalvageEnchantedMessage: "&cI'm sorry, but I'm unable to salvage enchanted items!"
# The message to display when asked to salvage an armor trim, and that option is disabled
cannotSalvageArmorTrimMessage: "&cI'm sorry, but I'm unable to salvage armor trims!"
# The message to display if the correct materials to return for the armor trim are unknown
armorTrimSalvageNotFoundMessage: "&cI'm sorry, but I don't know how to salvage that armor trim!"

View File

@ -6,43 +6,43 @@ main: net.knarcraft.blacksmith.BlacksmithPlugin
depend: [ Citizens, Vault ] depend: [ Citizens, Vault ]
prefix: "Blacksmith" prefix: "Blacksmith"
api-version: 1.19 api-version: 1.20
commands: commands:
blacksmith: blacksmith:
permission: blacksmith.edit permission: blacksmith.edit
usage: /<command> <option> [new value] usage: /<command> <option> [new value]
description: Used for configuring the selected blacksmith NPC description: Used for configuring the selected blacksmith NPC.
blacksmithConfig: blacksmithConfig:
permission: blacksmith.admin permission: blacksmith.admin
usage: /<command> <option/reload> [new value] usage: /<command> <option/reload> [new value]
description: Used for configuring default blacksmith settings, or global blacksmith settings description: Used for configuring default blacksmith settings, or global blacksmith settings.
scrapper: scrapper:
permission: blacksmith.edit permission: blacksmith.edit
usage: /<command> <option> [new value] usage: /<command> <option> [new value]
description: Used for configuring the selected scrapper NPC description: Used for configuring the selected scrapper NPC.
scrapperConfig: scrapperConfig:
permission: blacksmith.admin permission: blacksmith.admin
usage: /<command> <option/reload> [new value] usage: /<command> <option/reload> [new value]
description: Used for configuring default scrapper settings, or global scrapper settings description: Used for configuring default scrapper settings, or global scrapper settings.
preset: preset:
permission: blacksmith.preset permission: blacksmith.preset
usage: /<command> <preset>[:filter] usage: /<command> <preset>[:filter]
description: Used to display which materials are part of a given preset. If a filter, such as diamond is used, the result of applying the filter is shown. description: Used to display which materials are part of a given preset. If a filter, such as diamond is used, the result of applying the filter is shown.
permissions: permissions:
blacksmith.admin: blacksmith.admin:
description: Allows overall blacksmith configuration description: Allows overall blacksmith and scrapper configuration.
default: op default: op
children: children:
blacksmith.edit: true blacksmith.edit: true
blacksmith.use: true blacksmith.use: true
blacksmith.preset: true blacksmith.preset: true
blacksmith.edit: blacksmith.edit:
description: Allows changing settings for the selected blacksmith NPC description: Allows changing settings for the selected blacksmith or scrapper NPC.
default: op default: op
blacksmith.use: blacksmith.use:
description: Allows the player to repair items using blacksmiths description: Allows the player to repair items using blacksmiths and salvage items using scrappers.
default: true default: true
blacksmith.preset: blacksmith.preset:
description: Allows the player to use the /preset command description: Allows the player to use the /preset command.
default: op default: op