Implements netherite salvaging #24
All checks were successful
EpicKnarvik97/Blacksmith/pipeline/head This commit looks good
All checks were successful
EpicKnarvik97/Blacksmith/pipeline/head This commit looks good
This commit is contained in:
parent
e6047f3866
commit
1d7e8a0732
60
README.md
60
README.md
@ -119,6 +119,10 @@ repair all items, except diamond armor.
|
||||
All currently supported presets, and available filters for each preset:
|
||||
|
||||
- BLACKSMITH (WEAPON_SMITH + ARMOR_SMITH + TOOL_SMITH)
|
||||
- GOLD
|
||||
- IRON
|
||||
- DIAMOND
|
||||
- NETHERITE
|
||||
- WEAPON_SMITH: (RANGED + SWORD + SHIELD)
|
||||
- BOW (bows and crossbows)
|
||||
- SWORD (swords)
|
||||
@ -212,12 +216,14 @@ All currently supported presets, and available filters for each preset:
|
||||
|
||||
### Scrapper global-only options
|
||||
|
||||
| Key | Value type | Default | Description |
|
||||
|----------------|------------------------------------------------------------|---------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| 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. |
|
||||
| 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`. |
|
||||
| Key | Value type | Default | Description |
|
||||
|-----------------------|------------------------------------------------------------|---------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| salvagePrice | positive decimal number | 0 | The cost of using a scrapper to salvage an item. |
|
||||
| armorTrimSalvagePrice | positive decimal number | 5 | The cost of using a scrapper to remove armor trim from an item. |
|
||||
| netheriteSalvagePrice | positive decimal number | 15 | The cost of using a scrapper to remove netherite from an item. |
|
||||
| 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. |
|
||||
| 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)
|
||||
|
||||
@ -234,28 +240,32 @@ All currently supported presets, and available filters for each preset:
|
||||
| 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. |
|
||||
| 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. |
|
||||
| salvageArmorTrims | true/false | true | Whether the scrapper is able to salvage armor trims from items. |
|
||||
| salvageNetherite | true/false | true | Whether the scrapper is able to salvage netherite items into diamond items. |
|
||||
|
||||
#### Messages
|
||||
|
||||
| Message Key | Default | Explanation |
|
||||
|---------------------------------|-----------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------|
|
||||
| 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. |
|
||||
| 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. |
|
||||
| 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. |
|
||||
| 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. |
|
||||
| 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. |
|
||||
| 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. |
|
||||
| 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. |
|
||||
| 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. |
|
||||
| Message Key | Default | Explanation |
|
||||
|---------------------------------|-----------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------|
|
||||
| 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. |
|
||||
| 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. |
|
||||
| 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. |
|
||||
| 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. |
|
||||
| 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 salvaging an item. |
|
||||
| costMessage | &eIt will cost &a{cost}&e to salvage that &a{item}&e! {yield} &eClick again to salvage! | The message displayed when telling a player about the cost of salvaging an item. |
|
||||
| costMessageArmorTrim | &eIt will cost &a{cost}&e to salvage that &a{item}&e's armor trim! | The message displayed when telling a player about the cost of salvaging an item's armor trim. |
|
||||
| costMessageNetherite | &eIt will cost &a{cost}&e to salvage that &a{item}&e into diamond! | The message displayed when telling a player about the cost of salvaging a netherite item into a diamond 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. |
|
||||
| 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. |
|
||||
| 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. |
|
||||
| cannotSalvageNetheriteMessage | &cI'm sorry, but I'm unable to salvage netherite items! | The message displayed when telling a player that the scrapper cannot salvage netherite items. |
|
||||
|
||||
## Language customization
|
||||
|
||||
|
@ -0,0 +1,23 @@
|
||||
package net.knarcraft.blacksmith.config;
|
||||
|
||||
/**
|
||||
* A representation of the different ways an item can be salvaged
|
||||
*/
|
||||
public enum SalvageMethod {
|
||||
|
||||
/**
|
||||
* Salvaging the item normally by returning the item's crafting recipe
|
||||
*/
|
||||
SALVAGE,
|
||||
|
||||
/**
|
||||
* Removing the armor trim from an item
|
||||
*/
|
||||
ARMOR_TRIM,
|
||||
|
||||
/**
|
||||
* Un-doing netherite application for an item
|
||||
*/
|
||||
NETHERITE,
|
||||
|
||||
}
|
@ -22,7 +22,8 @@ public enum SmithPreset {
|
||||
/**
|
||||
* A blacksmith capable of re-forging everything
|
||||
*/
|
||||
BLACKSMITH(new SmithPresetFilter[]{}),
|
||||
BLACKSMITH(new SmithPresetFilter[]{SmithPresetFilter.GOLD, SmithPresetFilter.IRON, SmithPresetFilter.DIAMOND,
|
||||
SmithPresetFilter.NETHERITE}),
|
||||
|
||||
/**
|
||||
* A blacksmith capable of re-forging all weapons (including shields)
|
||||
|
@ -34,7 +34,7 @@ public class GlobalScrapperSettings implements Settings<ScrapperSetting> {
|
||||
*
|
||||
* @param instance <p>A reference to the blacksmith plugin</p>
|
||||
*/
|
||||
public GlobalScrapperSettings(BlacksmithPlugin instance) {
|
||||
public GlobalScrapperSettings(@NotNull BlacksmithPlugin instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
@ -78,7 +78,8 @@ public class GlobalScrapperSettings implements Settings<ScrapperSetting> {
|
||||
* @param scrapperSetting <p>The setting to get</p>
|
||||
* @return <p>The current raw setting value</p>
|
||||
*/
|
||||
public @NotNull Object getRawValue(@NotNull ScrapperSetting scrapperSetting) {
|
||||
@NotNull
|
||||
public Object getRawValue(@NotNull ScrapperSetting scrapperSetting) {
|
||||
return this.settings.get(scrapperSetting);
|
||||
}
|
||||
|
||||
@ -87,6 +88,7 @@ public class GlobalScrapperSettings implements Settings<ScrapperSetting> {
|
||||
*
|
||||
* @return <p>The current value of the default NPC settings</p>
|
||||
*/
|
||||
@NotNull
|
||||
public Map<ScrapperSetting, Object> getDefaultNPCSettings() {
|
||||
return new HashMap<>(this.settings);
|
||||
}
|
||||
@ -108,10 +110,22 @@ public class GlobalScrapperSettings implements Settings<ScrapperSetting> {
|
||||
* @param setting <p>The setting to get the value of</p>
|
||||
* @return <p>The value of the given setting as a boolean</p>
|
||||
*/
|
||||
public boolean asBoolean(ScrapperSetting setting) {
|
||||
public boolean asBoolean(@NotNull ScrapperSetting setting) {
|
||||
return ConfigHelper.asBoolean(getValue(setting));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the given value as a double
|
||||
*
|
||||
* <p>This will throw an exception if used for a non-double setting</p>
|
||||
*
|
||||
* @param setting <p>The setting to get the value of</p>
|
||||
* @return <p>The value of the given setting as a double</p>
|
||||
*/
|
||||
public double asDouble(@NotNull ScrapperSetting setting) {
|
||||
return ConfigHelper.asDouble(getValue(setting));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of a setting, using the default if not set
|
||||
*
|
||||
@ -173,12 +187,30 @@ public class GlobalScrapperSettings implements Settings<ScrapperSetting> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cost of using a scrapper
|
||||
* Gets the cost of using a scrapper to salvage an item
|
||||
*
|
||||
* @return <p>The cost of using a scrapper</p>
|
||||
* @return <p>The cost of using a scrapper to salvage an item</p>
|
||||
*/
|
||||
public double getCost() {
|
||||
return ConfigHelper.asDouble(getValue(ScrapperSetting.USE_COST));
|
||||
public double getSalvageCost() {
|
||||
return asDouble(ScrapperSetting.SALVAGE_COST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cost of using a scrapper to remove armor trim
|
||||
*
|
||||
* @return <p>The cost of using a scrapper to remove armor trim</p>
|
||||
*/
|
||||
public double getArmorTrimSalvageCost() {
|
||||
return asDouble(ScrapperSetting.ARMOR_TRIM_SALVAGE_COST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cost of using a scrapper to remove netherite from an item
|
||||
*
|
||||
* @return <p>The cost of using a scrapper to remove netherite from an item</p>
|
||||
*/
|
||||
public double getNetheriteSalvageCost() {
|
||||
return asDouble(ScrapperSetting.NETHERITE_SALVAGE_COST);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -151,6 +151,16 @@ public class ScrapperNPCSettings implements TraitSettings<ScrapperSetting> {
|
||||
return asString(ScrapperSetting.COST_MESSAGE_ARMOR_TRIM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message to use for displaying netherite salvage cost
|
||||
*
|
||||
* @return <p>The message to use for displaying netherite salvage cost</p>
|
||||
*/
|
||||
@NotNull
|
||||
public String getNetheriteCostMessage() {
|
||||
return asString(ScrapperSetting.COST_MESSAGE_NETHERITE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getCoolDownUnexpiredMessage() {
|
||||
@ -316,6 +326,15 @@ public class ScrapperNPCSettings implements TraitSettings<ScrapperSetting> {
|
||||
return asBoolean(ScrapperSetting.SALVAGE_ARMOR_TRIMS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether salvage of netherite items is enabled
|
||||
*
|
||||
* @return <p>True if this scrapper can salvage netherite items</p>
|
||||
*/
|
||||
public boolean salvageNetherite() {
|
||||
return asBoolean(ScrapperSetting.SALVAGE_NETHERITE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the title of this scrapper NPC
|
||||
*
|
||||
@ -415,4 +434,14 @@ public class ScrapperNPCSettings implements TraitSettings<ScrapperSetting> {
|
||||
return asString(ScrapperSetting.ARMOR_TRIM_SALVAGE_NOT_FOUND_MESSAGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message to display when explaining that this scrapper is unable to salvage netherite items
|
||||
*
|
||||
* @return <p>The message to display when explaining that this scrapper is unable to salvage netherite items</p>
|
||||
*/
|
||||
@NotNull
|
||||
public String getCannotSalvageNetheriteMessage() {
|
||||
return asString(ScrapperSetting.CANNOT_SALVAGE_NETHERITE_MESSAGE);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ public enum ScrapperSetting implements Setting {
|
||||
* <p>If set to false, the item will be directly put in the player's inventory instead</p>
|
||||
*/
|
||||
DROP_ITEM("dropItem", SettingValueType.BOOLEAN, true, "Whether the " +
|
||||
"item will drop materials resulting from scrapping on the ground, instead of putting them into the user's" +
|
||||
"item will drop materials resulting from salvaging on the ground, instead of putting them into the user's" +
|
||||
" inventory", true, false),
|
||||
|
||||
/**
|
||||
@ -86,6 +86,12 @@ public enum ScrapperSetting implements Setting {
|
||||
SALVAGE_ARMOR_TRIMS("salvageArmorTrims", SettingValueType.BOOLEAN, true,
|
||||
"Whether to enable salvaging of armor trims.", true, false),
|
||||
|
||||
/**
|
||||
* The setting for whether the NPC should allow salvaging netherite items to diamond items
|
||||
*/
|
||||
SALVAGE_NETHERITE("salvageNetherite", SettingValueType.BOOLEAN, true,
|
||||
"Whether to enable salvaging of netherite items", true, false),
|
||||
|
||||
/*-----------
|
||||
| Messages |
|
||||
-----------*/
|
||||
@ -164,16 +170,23 @@ public enum ScrapperSetting implements Setting {
|
||||
* 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!",
|
||||
"&eIt will cost &a{cost}&e to salvage that &a{item}&e! {yield} &eClick 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!",
|
||||
"&eIt will cost &a{cost}&e to salvage that &a{item}&e's armor trim!",
|
||||
"The message to display when explaining the shown item's armor trim's salvage cost", true, true),
|
||||
|
||||
/**
|
||||
* The message displayed when displaying the cost of salvaging the netherite of the held item to the player
|
||||
*/
|
||||
COST_MESSAGE_NETHERITE("costMessageNetherite", SettingValueType.STRING,
|
||||
"&eIt will cost &a{cost}&e to salvage that &a{item}&e into diamond!",
|
||||
"The message to display when explaining the shown item's netherite salvage cost", true, true),
|
||||
|
||||
/**
|
||||
* The message displayed when explaining that all items will be returned as salvage
|
||||
*/
|
||||
@ -209,21 +222,40 @@ public enum ScrapperSetting implements Setting {
|
||||
"&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),
|
||||
|
||||
/**
|
||||
* The message displayed when explaining that netherite salvage is disabled
|
||||
*/
|
||||
CANNOT_SALVAGE_NETHERITE_MESSAGE("cannotSalvageNetheriteMessage", SettingValueType.STRING,
|
||||
"&cI'm sorry, but I'm unable to salvage netherite items!",
|
||||
"The message to display when asked to salvage netherite items, and that option is disabled", true, true),
|
||||
|
||||
/*------------------
|
||||
| Global settings |
|
||||
------------------*/
|
||||
|
||||
/**
|
||||
* The setting for the use cost of using the scrapper
|
||||
* The setting for the salvage cost
|
||||
*/
|
||||
USE_COST("basePrice", SettingValueType.POSITIVE_DOUBLE, 0, "The cost of using a scrapper",
|
||||
false, false),
|
||||
SALVAGE_COST("salvagePrice", SettingValueType.POSITIVE_DOUBLE, 0,
|
||||
"The cost of using a scrapper to salvage an item", false, false),
|
||||
|
||||
/**
|
||||
* The setting for the armor trim salvage cost
|
||||
*/
|
||||
ARMOR_TRIM_SALVAGE_COST("armorTrimSalvagePrice", SettingValueType.POSITIVE_DOUBLE, 5,
|
||||
"The cost of using the scrapper to remove armor trim", false, false),
|
||||
|
||||
/**
|
||||
* The setting for the netherite salvage cost
|
||||
*/
|
||||
NETHERITE_SALVAGE_COST("netheriteSalvagePrice", SettingValueType.POSITIVE_DOUBLE, 15,
|
||||
"The cost of using the scrapper to remove netherite from an item", false, false),
|
||||
|
||||
/**
|
||||
* Whether to display exact time in minutes and seconds when displaying a remaining cool-down
|
||||
*/
|
||||
SHOW_EXACT_TIME("showExactTime", SettingValueType.BOOLEAN, "false", "Exact time displays the " +
|
||||
"exact number of seconds and minutes remaining as part of the scrapping cool-down and scrapping delay " +
|
||||
"exact number of seconds and minutes remaining as part of the salvaging cool-down and salvaging delay " +
|
||||
"messages, instead of just vaguely hinting at the remaining time.", false, false),
|
||||
|
||||
/**
|
||||
@ -263,7 +295,7 @@ public enum ScrapperSetting implements Setting {
|
||||
* @param isPerNPC <p>Whether this setting is per-NPC or global</p>
|
||||
* @param isMessage <p>Whether this option is for an NPC message</p>
|
||||
*/
|
||||
ScrapperSetting(String key, SettingValueType valueType, Object value,
|
||||
ScrapperSetting(@NotNull String key, @NotNull SettingValueType valueType, @NotNull Object value,
|
||||
@NotNull String description, boolean isPerNPC, boolean isMessage) {
|
||||
if (isPerNPC) {
|
||||
if (isMessage) {
|
||||
@ -289,32 +321,38 @@ public enum ScrapperSetting implements Setting {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getPath() {
|
||||
@NotNull
|
||||
public String getPath() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getChildPath() {
|
||||
@NotNull
|
||||
public String getChildPath() {
|
||||
return this.childPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Object getDefaultValue() {
|
||||
@NotNull
|
||||
public Object getDefaultValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getCommandName() {
|
||||
@NotNull
|
||||
public String getCommandName() {
|
||||
return this.commandName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull SettingValueType getValueType() {
|
||||
@NotNull
|
||||
public SettingValueType getValueType() {
|
||||
return this.valueType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getDescription() {
|
||||
@NotNull
|
||||
public String getDescription() {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
package net.knarcraft.blacksmith.manager;
|
||||
|
||||
import net.knarcraft.blacksmith.BlacksmithPlugin;
|
||||
import net.knarcraft.blacksmith.config.SalvageMethod;
|
||||
import net.knarcraft.blacksmith.config.blacksmith.GlobalBlacksmithSettings;
|
||||
import net.knarcraft.blacksmith.config.scrapper.GlobalScrapperSettings;
|
||||
import net.knarcraft.blacksmith.util.ItemHelper;
|
||||
import net.milkbowl.vault.economy.Economy;
|
||||
import org.bukkit.Material;
|
||||
@ -54,11 +56,12 @@ public class EconomyManager {
|
||||
/**
|
||||
* Gets whether the given player cannot pay for salvaging an item
|
||||
*
|
||||
* @param player <p>The player holding an item</p>
|
||||
* @param player <p>The player holding an item</p>
|
||||
* @param salvageMethod <p>The salvage method to check</p>
|
||||
* @return <p>Whether the player cannot pay for the salvage</p>
|
||||
*/
|
||||
public static boolean cannotPayForSalvage(@NotNull Player player) {
|
||||
return economy.getBalance(player) - BlacksmithPlugin.getInstance().getGlobalScrapperSettings().getCost() < 0;
|
||||
public static boolean cannotPayForSalvage(@NotNull Player player, @NotNull SalvageMethod salvageMethod) {
|
||||
return economy.getBalance(player) - getSalvageCost(salvageMethod) < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -76,12 +79,27 @@ public class EconomyManager {
|
||||
/**
|
||||
* Gets the human-readable cost of salvaging an item
|
||||
*
|
||||
* @param salvageMethod <p>The salvage method to get the cost for</p>
|
||||
* @return <p>The formatted cost</p>
|
||||
*/
|
||||
@NotNull
|
||||
public static String formatScrapperCost() {
|
||||
double cost = BlacksmithPlugin.getInstance().getGlobalScrapperSettings().getCost();
|
||||
return economy.format(cost);
|
||||
public static String formatSalvageCost(@NotNull SalvageMethod salvageMethod) {
|
||||
return economy.format(getSalvageCost(salvageMethod));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cost of salvaging using the specified method
|
||||
*
|
||||
* @param salvageMethod <p>The salvage method to get cost for</p>
|
||||
* @return <p>The salvage cost</p>
|
||||
*/
|
||||
private static double getSalvageCost(@NotNull SalvageMethod salvageMethod) {
|
||||
GlobalScrapperSettings settings = BlacksmithPlugin.getInstance().getGlobalScrapperSettings();
|
||||
return switch (salvageMethod) {
|
||||
case SALVAGE -> settings.getSalvageCost();
|
||||
case NETHERITE -> settings.getNetheriteSalvageCost();
|
||||
case ARMOR_TRIM -> settings.getArmorTrimSalvageCost();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@ -101,10 +119,11 @@ public class EconomyManager {
|
||||
/**
|
||||
* Withdraws the salvaging cost from the given player
|
||||
*
|
||||
* @param player <p>The player to withdraw from</p>
|
||||
* @param player <p>The player to withdraw from</p>
|
||||
* @param salvageMethod <p>The salvage method to withdraw for</p>
|
||||
*/
|
||||
public static void withdrawScrapper(Player player) {
|
||||
double cost = BlacksmithPlugin.getInstance().getGlobalScrapperSettings().getCost();
|
||||
public static void withdrawScrapper(@NotNull Player player, @NotNull SalvageMethod salvageMethod) {
|
||||
double cost = getSalvageCost(salvageMethod);
|
||||
if (cost > 0) {
|
||||
economy.withdrawPlayer(player, cost);
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import net.knarcraft.blacksmith.config.Settings;
|
||||
import net.knarcraft.blacksmith.config.TraitSettings;
|
||||
import net.knarcraft.blacksmith.formatting.TimeFormatter;
|
||||
import net.knarcraft.blacksmith.manager.EconomyManager;
|
||||
import net.knarcraft.blacksmith.util.ItemHelper;
|
||||
import net.knarcraft.blacksmith.util.SalvageHelper;
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -181,8 +181,8 @@ public abstract class CustomTrait<K extends Setting> extends Trait {
|
||||
|
||||
if (isBlacksmith) {
|
||||
EconomyManager.withdrawBlacksmith(player);
|
||||
} else {
|
||||
EconomyManager.withdrawScrapper(player);
|
||||
} else if (this.session instanceof SalvageSession salvageSession) {
|
||||
EconomyManager.withdrawScrapper(player, salvageSession.salvageMethod);
|
||||
}
|
||||
|
||||
session.scheduleAction();
|
||||
@ -198,7 +198,7 @@ public abstract class CustomTrait<K extends Setting> extends Trait {
|
||||
//Remove the item from the player's inventory
|
||||
if (!isBlacksmith) {
|
||||
// For scrappers, just reduce the amounts of items, unless the remaining stack is salvaged
|
||||
int amount = ItemHelper.getRequiredAmountForSalvage(player.getServer(), heldItem);
|
||||
int amount = SalvageHelper.getRequiredAmountForSalvage(player.getServer(), heldItem);
|
||||
if (amount != heldItem.getAmount()) {
|
||||
heldItem.setAmount(heldItem.getAmount() - amount);
|
||||
playerInventory.setItemInMainHand(heldItem);
|
||||
|
@ -69,14 +69,14 @@ public class ReforgeSession extends Session implements Runnable {
|
||||
@Override
|
||||
public boolean isSessionInvalid() {
|
||||
// Prevent player from switching items during session
|
||||
ItemStack itemInHand = player.getInventory().getItemInMainHand();
|
||||
ItemStack itemInHand = this.player.getInventory().getItemInMainHand();
|
||||
if (!itemToReforge.equals(itemInHand)) {
|
||||
sendNPCMessage(this.npc, player, config.getItemChangedMessage());
|
||||
sendNPCMessage(this.npc, this.player, this.config.getItemChangedMessage());
|
||||
return true;
|
||||
}
|
||||
// The player is unable to pay
|
||||
if (EconomyManager.cannotPayForHeldItemReforge(player)) {
|
||||
sendNPCMessage(this.npc, player, config.getInsufficientFundsMessage());
|
||||
if (EconomyManager.cannotPayForHeldItemReforge(this.player)) {
|
||||
sendNPCMessage(this.npc, this.player, this.config.getInsufficientFundsMessage());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -84,9 +84,9 @@ public class ReforgeSession extends Session implements Runnable {
|
||||
|
||||
@Override
|
||||
protected int getActionDelay() {
|
||||
if (config.getMaxReforgeDelay() > 0) {
|
||||
if (this.config.getMaxReforgeDelay() > 0) {
|
||||
//Finish the reforging after a random delay between the max and min
|
||||
return new Random().nextInt(config.getMaxReforgeDelay()) + config.getMinReforgeDelay();
|
||||
return new Random().nextInt(this.config.getMaxReforgeDelay()) + this.config.getMinReforgeDelay();
|
||||
} else {
|
||||
//Finish the salvaging as soon as possible
|
||||
return 0;
|
||||
@ -98,41 +98,41 @@ public class ReforgeSession extends Session implements Runnable {
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
sendNPCMessage(this.npc, player, reforgeItem() ? config.getSuccessMessage() : config.getFailMessage());
|
||||
sendNPCMessage(this.npc, this.player, reforgeItem() ? this.config.getSuccessMessage() : this.config.getFailMessage());
|
||||
|
||||
//Stop the reforged item from displaying in the blacksmith's hand
|
||||
if (npc.getEntity() instanceof Player) {
|
||||
((Player) npc.getEntity()).getInventory().setItemInMainHand(null);
|
||||
if (this.npc.getEntity() instanceof Player) {
|
||||
((Player) this.npc.getEntity()).getInventory().setItemInMainHand(null);
|
||||
} else {
|
||||
Objects.requireNonNull(((LivingEntity) npc.getEntity()).getEquipment()).setItemInMainHand(null);
|
||||
Objects.requireNonNull(((LivingEntity) this.npc.getEntity()).getEquipment()).setItemInMainHand(null);
|
||||
}
|
||||
|
||||
//Give the item back to the player
|
||||
giveReforgedItem();
|
||||
|
||||
//Mark this blacksmith as available
|
||||
blacksmithTrait.unsetSession();
|
||||
this.blacksmithTrait.unsetSession();
|
||||
|
||||
// Start cool-down
|
||||
Calendar wait = Calendar.getInstance();
|
||||
wait.add(Calendar.SECOND, config.getReforgeCoolDown());
|
||||
blacksmithTrait.addCoolDown(player.getUniqueId(), wait);
|
||||
wait.add(Calendar.SECOND, this.config.getReforgeCoolDown());
|
||||
this.blacksmithTrait.addCoolDown(this.player.getUniqueId(), wait);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the reforged item back to the player
|
||||
*/
|
||||
private void giveReforgedItem() {
|
||||
if (config.getMaxReforgeDelay() > 0) {
|
||||
if (this.config.getMaxReforgeDelay() > 0) {
|
||||
//If the player isn't online, or the player cannot fit the item, drop the item to prevent it from disappearing
|
||||
if (config.getDropItem() || !player.isOnline() || player.getInventory().firstEmpty() == -1) {
|
||||
player.getWorld().dropItemNaturally(npc.getEntity().getLocation(), itemToReforge);
|
||||
if (this.config.getDropItem() || !this.player.isOnline() || this.player.getInventory().firstEmpty() == -1) {
|
||||
this.player.getWorld().dropItemNaturally(this.npc.getEntity().getLocation(), this.itemToReforge);
|
||||
} else {
|
||||
player.getInventory().addItem(itemToReforge);
|
||||
this.player.getInventory().addItem(this.itemToReforge);
|
||||
}
|
||||
} else {
|
||||
//It can be assumed as this happens instantly, that the player still has the item's previous slot selected
|
||||
player.getInventory().setItemInMainHand(itemToReforge);
|
||||
this.player.getInventory().setItemInMainHand(this.itemToReforge);
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,7 +142,7 @@ public class ReforgeSession extends Session implements Runnable {
|
||||
* @return <p>Whether the reforge was successful. False if the blacksmith failed to fully repair the item.</p>
|
||||
*/
|
||||
private boolean reforgeItem() {
|
||||
if (random.nextInt(100) < config.getFailChance()) {
|
||||
if (random.nextInt(100) < this.config.getFailChance()) {
|
||||
failReforge();
|
||||
return false;
|
||||
} else {
|
||||
@ -156,18 +156,18 @@ public class ReforgeSession extends Session implements Runnable {
|
||||
*/
|
||||
private void succeedReforge() {
|
||||
// Remove any damage done to the item
|
||||
updateDamage(itemToReforge, 0);
|
||||
updateDamage(this.itemToReforge, 0);
|
||||
|
||||
//Replace damaged anvils with a normal anvil
|
||||
if (ItemHelper.isAnvil(itemToReforge.getType(), true)) {
|
||||
itemToReforge.setType(Material.ANVIL);
|
||||
if (ItemHelper.isAnvil(this.itemToReforge.getType(), true)) {
|
||||
this.itemToReforge.setType(Material.ANVIL);
|
||||
}
|
||||
|
||||
//See if a random roll (0-99) is less than extraEnchantmentChance, and add a random enchantment
|
||||
int roll = random.nextInt(100);
|
||||
if (roll < config.getExtraEnchantmentChance() &&
|
||||
itemToReforge.getEnchantments().keySet().size() < config.getMaxEnchantments() &&
|
||||
!ItemHelper.isAnvil(itemToReforge.getType(), false)) {
|
||||
if (roll < this.config.getExtraEnchantmentChance() &&
|
||||
this.itemToReforge.getEnchantments().keySet().size() < this.config.getMaxEnchantments() &&
|
||||
!ItemHelper.isAnvil(this.itemToReforge.getType(), false)) {
|
||||
addRandomEnchantment();
|
||||
}
|
||||
}
|
||||
@ -180,12 +180,12 @@ public class ReforgeSession extends Session implements Runnable {
|
||||
List<Enchantment> usableEnchantments = new ArrayList<>();
|
||||
for (String enchantmentName : enchantments) {
|
||||
Enchantment enchantment = InputParsingHelper.matchEnchantment(enchantmentName);
|
||||
if (enchantment != null && enchantment.canEnchantItem(itemToReforge)) {
|
||||
if (enchantment != null && enchantment.canEnchantItem(this.itemToReforge)) {
|
||||
usableEnchantments.add(enchantment);
|
||||
}
|
||||
}
|
||||
//Remove any enchantments in the block list
|
||||
usableEnchantments.removeAll(blacksmithTrait.getSettings().getEnchantmentBlockList());
|
||||
usableEnchantments.removeAll(this.blacksmithTrait.getSettings().getEnchantmentBlockList());
|
||||
|
||||
//In case all usable enchantments have been blocked, abort
|
||||
if (usableEnchantments.isEmpty()) {
|
||||
@ -198,10 +198,10 @@ public class ReforgeSession extends Session implements Runnable {
|
||||
int randomBound = randomEnchantment.getMaxLevel() + 1;
|
||||
//A workaround for the random method's bound sometimes being negative
|
||||
if (randomBound >= 0) {
|
||||
int existingLevel = itemToReforge.getEnchantmentLevel(randomEnchantment);
|
||||
int existingLevel = this.itemToReforge.getEnchantmentLevel(randomEnchantment);
|
||||
/* Add a random enchantment whose level is no lower than the start level, and no lower than the
|
||||
existing level (to prevent making the item worse) */
|
||||
itemToReforge.addEnchantment(randomEnchantment, Math.max(Math.max(random.nextInt(randomBound),
|
||||
this.itemToReforge.addEnchantment(randomEnchantment, Math.max(Math.max(random.nextInt(randomBound),
|
||||
randomEnchantment.getStartLevel()), existingLevel));
|
||||
}
|
||||
}
|
||||
@ -211,20 +211,20 @@ public class ReforgeSession extends Session implements Runnable {
|
||||
* The method to run when a blacksmith fails re-forging an item
|
||||
*/
|
||||
private void failReforge() {
|
||||
if (config.getFailRemovesEnchantments()) {
|
||||
if (this.config.getFailRemovesEnchantments()) {
|
||||
removeOrDowngradeEnchantments();
|
||||
}
|
||||
|
||||
//Damage the item
|
||||
short currentItemDurability = ItemHelper.getDurability(itemToReforge);
|
||||
short currentItemDurability = ItemHelper.getDurability(this.itemToReforge);
|
||||
short newDurability = (short) (currentItemDurability + (currentItemDurability * random.nextInt(8)));
|
||||
short maxDurability = itemToReforge.getType().getMaxDurability();
|
||||
short maxDurability = this.itemToReforge.getType().getMaxDurability();
|
||||
if (newDurability <= 0) {
|
||||
newDurability = (short) (maxDurability / 3);
|
||||
} else if (currentItemDurability + newDurability > maxDurability) {
|
||||
newDurability = (short) (maxDurability - random.nextInt(maxDurability - 25));
|
||||
}
|
||||
updateDamage(itemToReforge, maxDurability - newDurability);
|
||||
updateDamage(this.itemToReforge, maxDurability - newDurability);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -232,13 +232,13 @@ public class ReforgeSession extends Session implements Runnable {
|
||||
*/
|
||||
private void removeOrDowngradeEnchantments() {
|
||||
//Remove or downgrade existing enchantments
|
||||
for (Enchantment enchantment : itemToReforge.getEnchantments().keySet()) {
|
||||
for (Enchantment enchantment : this.itemToReforge.getEnchantments().keySet()) {
|
||||
//Completely remove the enchantment, downgrade it, or keep it if lucky and already level 1
|
||||
if (random.nextBoolean()) {
|
||||
itemToReforge.removeEnchantment(enchantment);
|
||||
} else if (itemToReforge.getEnchantmentLevel(enchantment) > 1) {
|
||||
itemToReforge.removeEnchantment(enchantment);
|
||||
itemToReforge.addEnchantment(enchantment, 1);
|
||||
this.itemToReforge.removeEnchantment(enchantment);
|
||||
} else if (this.itemToReforge.getEnchantmentLevel(enchantment) > 1) {
|
||||
this.itemToReforge.removeEnchantment(enchantment);
|
||||
this.itemToReforge.addEnchantment(enchantment, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.knarcraft.blacksmith.trait;
|
||||
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.knarcraft.blacksmith.config.SalvageMethod;
|
||||
import net.knarcraft.blacksmith.config.scrapper.ScrapperNPCSettings;
|
||||
import net.knarcraft.blacksmith.manager.EconomyManager;
|
||||
import net.knarcraft.blacksmith.util.ItemHelper;
|
||||
@ -30,6 +31,7 @@ public class SalvageSession extends Session implements Runnable {
|
||||
private final ScrapperNPCSettings config;
|
||||
private final List<ItemStack> salvage;
|
||||
private final int enchantmentLevels;
|
||||
protected final SalvageMethod salvageMethod;
|
||||
private static final Random random = new Random();
|
||||
|
||||
/**
|
||||
@ -39,9 +41,11 @@ public class SalvageSession extends Session implements Runnable {
|
||||
* @param player <p>The player initiating the session</p>
|
||||
* @param npc <p>The scrapper NPC involved in the session</p>
|
||||
* @param config <p>The config to use for the session</p>
|
||||
* @param salvageMethod <p>The salvage method performed in this session</p>
|
||||
*/
|
||||
SalvageSession(@NotNull ScrapperTrait scrapperTrait, @NotNull Player player, @NotNull NPC npc,
|
||||
@NotNull ScrapperNPCSettings config, @NotNull List<ItemStack> salvage) {
|
||||
@NotNull ScrapperNPCSettings config, @NotNull List<ItemStack> salvage,
|
||||
@NotNull SalvageMethod salvageMethod) {
|
||||
super(player);
|
||||
this.scrapperTrait = scrapperTrait;
|
||||
this.npc = npc;
|
||||
@ -49,19 +53,20 @@ public class SalvageSession extends Session implements Runnable {
|
||||
this.config = config;
|
||||
this.salvage = salvage;
|
||||
this.enchantmentLevels = SalvageHelper.getTotalEnchantmentLevels(this.itemToSalvage);
|
||||
this.salvageMethod = salvageMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSessionInvalid() {
|
||||
// Prevent player from switching items during session
|
||||
ItemStack itemInHand = player.getInventory().getItemInMainHand();
|
||||
ItemStack itemInHand = this.player.getInventory().getItemInMainHand();
|
||||
if (!itemToSalvage.equals(itemInHand)) {
|
||||
sendNPCMessage(this.npc, player, config.getItemChangedMessage());
|
||||
sendNPCMessage(this.npc, this.player, this.config.getItemChangedMessage());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (EconomyManager.cannotPayForSalvage(player)) {
|
||||
sendNPCMessage(this.npc, player, config.getInsufficientFundsMessage());
|
||||
if (EconomyManager.cannotPayForSalvage(this.player, this.salvageMethod)) {
|
||||
sendNPCMessage(this.npc, this.player, this.config.getInsufficientFundsMessage());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -69,9 +74,9 @@ public class SalvageSession extends Session implements Runnable {
|
||||
|
||||
@Override
|
||||
protected int getActionDelay() {
|
||||
if (config.getMaxSalvageDelay() > 0) {
|
||||
if (this.config.getMaxSalvageDelay() > 0) {
|
||||
//Finish the salvaging after a random delay between the max and min
|
||||
return new Random().nextInt(config.getMaxSalvageDelay()) + config.getMinSalvageDelay();
|
||||
return new Random().nextInt(this.config.getMaxSalvageDelay()) + this.config.getMinSalvageDelay();
|
||||
} else {
|
||||
//Finish the salvaging as soon as possible
|
||||
return 0;
|
||||
@ -83,22 +88,22 @@ public class SalvageSession extends Session implements Runnable {
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
sendNPCMessage(this.npc, player, salvageItem() ? config.getSuccessMessage() : config.getFailMessage());
|
||||
sendNPCMessage(this.npc, this.player, salvageItem() ? this.config.getSuccessMessage() : this.config.getFailMessage());
|
||||
|
||||
//Stop the reforged item from displaying in the scrapper's hand
|
||||
if (npc.getEntity() instanceof Player) {
|
||||
((Player) npc.getEntity()).getInventory().setItemInMainHand(null);
|
||||
if (this.npc.getEntity() instanceof Player) {
|
||||
((Player) this.npc.getEntity()).getInventory().setItemInMainHand(null);
|
||||
} else {
|
||||
Objects.requireNonNull(((LivingEntity) npc.getEntity()).getEquipment()).setItemInMainHand(null);
|
||||
Objects.requireNonNull(((LivingEntity) this.npc.getEntity()).getEquipment()).setItemInMainHand(null);
|
||||
}
|
||||
|
||||
//Mark this scrapper as available
|
||||
scrapperTrait.unsetSession();
|
||||
this.scrapperTrait.unsetSession();
|
||||
|
||||
// Start cool-down
|
||||
Calendar wait = Calendar.getInstance();
|
||||
wait.add(Calendar.SECOND, config.getSalvageCoolDown());
|
||||
scrapperTrait.addCoolDown(player.getUniqueId(), wait);
|
||||
wait.add(Calendar.SECOND, this.config.getSalvageCoolDown());
|
||||
this.scrapperTrait.addCoolDown(this.player.getUniqueId(), wait);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -107,7 +112,7 @@ public class SalvageSession extends Session implements Runnable {
|
||||
* @return <p>True if the salvage was successful. False otherwise.</p>
|
||||
*/
|
||||
private boolean salvageItem() {
|
||||
if (random.nextInt(100) < config.getFailChance()) {
|
||||
if (random.nextInt(100) < this.config.getFailChance()) {
|
||||
failSalvage();
|
||||
return false;
|
||||
} else {
|
||||
@ -121,19 +126,19 @@ public class SalvageSession extends Session implements Runnable {
|
||||
* The method to run when a crapper fails salvaging an item
|
||||
*/
|
||||
private void failSalvage() {
|
||||
if (itemToSalvage.getItemMeta() instanceof Damageable) {
|
||||
if (this.itemToSalvage.getItemMeta() instanceof Damageable) {
|
||||
//Damage the item
|
||||
short currentItemDurability = ItemHelper.getDurability(itemToSalvage);
|
||||
short currentItemDurability = ItemHelper.getDurability(this.itemToSalvage);
|
||||
short newDurability = (short) (currentItemDurability + (currentItemDurability * random.nextInt(8)));
|
||||
short maxDurability = itemToSalvage.getType().getMaxDurability();
|
||||
short maxDurability = this.itemToSalvage.getType().getMaxDurability();
|
||||
if (newDurability <= 0) {
|
||||
newDurability = (short) (maxDurability / 3);
|
||||
} else if (currentItemDurability + newDurability > maxDurability) {
|
||||
newDurability = (short) (maxDurability - random.nextInt(maxDurability - 25));
|
||||
}
|
||||
updateDamage(itemToSalvage, maxDurability - newDurability);
|
||||
updateDamage(this.itemToSalvage, maxDurability - newDurability);
|
||||
} else {
|
||||
itemToSalvage.setAmount(Math.max(itemToSalvage.getAmount() - 1, 1));
|
||||
this.itemToSalvage.setAmount(Math.max(this.itemToSalvage.getAmount() - 1, 1));
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,20 +148,20 @@ public class SalvageSession extends Session implements Runnable {
|
||||
private void giveSalvage() {
|
||||
// TODO: Find a better calculation than 1 enchantment level = 1 exp level
|
||||
// Gives the player back some of the EXP used on an item
|
||||
player.giveExpLevels(enchantmentLevels);
|
||||
if (config.getDropItem() || !player.isOnline() || player.getInventory().firstEmpty() == -1) {
|
||||
this.player.giveExpLevels(this.enchantmentLevels);
|
||||
if (this.config.getDropItem() || !this.player.isOnline() || this.player.getInventory().firstEmpty() == -1) {
|
||||
// If the player isn't online, or the player cannot fit the item, drop the item to prevent it from
|
||||
// disappearing, even if drop item is disabled.
|
||||
for (ItemStack item : salvage) {
|
||||
player.getWorld().dropItemNaturally(npc.getEntity().getLocation(), item);
|
||||
for (ItemStack item : this.salvage) {
|
||||
this.player.getWorld().dropItemNaturally(this.npc.getEntity().getLocation(), item);
|
||||
}
|
||||
} else {
|
||||
for (ItemStack item : salvage) {
|
||||
if (ItemHelper.canFitItem(player.getInventory(), item)) {
|
||||
player.getInventory().addItem(item);
|
||||
for (ItemStack item : this.salvage) {
|
||||
if (ItemHelper.canFitItem(this.player.getInventory(), item)) {
|
||||
this.player.getInventory().addItem(item);
|
||||
} else {
|
||||
// If the player cannot fit all the salvage, drop it on the ground
|
||||
player.getWorld().dropItemNaturally(player.getLocation(), item);
|
||||
this.player.getWorld().dropItemNaturally(this.player.getLocation(), item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,15 +2,18 @@ package net.knarcraft.blacksmith.trait;
|
||||
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
import net.knarcraft.blacksmith.BlacksmithPlugin;
|
||||
import net.knarcraft.blacksmith.config.SalvageMethod;
|
||||
import net.knarcraft.blacksmith.config.SmithPreset;
|
||||
import net.knarcraft.blacksmith.config.SmithPresetFilter;
|
||||
import net.knarcraft.blacksmith.config.scrapper.ScrapperNPCSettings;
|
||||
import net.knarcraft.blacksmith.config.scrapper.ScrapperSetting;
|
||||
import net.knarcraft.blacksmith.manager.EconomyManager;
|
||||
import net.knarcraft.blacksmith.util.ItemHelper;
|
||||
import net.knarcraft.blacksmith.util.SalvageHelper;
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.knarlib.formatting.StringReplacer;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ArmorMeta;
|
||||
@ -82,7 +85,7 @@ public class ScrapperTrait extends CustomTrait<ScrapperSetting> {
|
||||
boolean extended = getSettings().extendedSalvageEnabled();
|
||||
|
||||
// Check if the item can be salvaged
|
||||
if (!canBeSalvaged(player.getServer(), itemInHand, salvageAbleItems, extended)) {
|
||||
if (!canBeSalvaged(itemInHand, salvageAbleItems, extended)) {
|
||||
sendNPCMessage(this.npc, player, StringFormatter.replacePlaceholder(getSettings().getInvalidItemMessage(),
|
||||
"{title}", getSettings().getScrapperTitle()));
|
||||
return;
|
||||
@ -91,18 +94,35 @@ public class ScrapperTrait extends CustomTrait<ScrapperSetting> {
|
||||
List<ItemStack> salvage = null;
|
||||
|
||||
// Deal with armor trim salvage
|
||||
boolean salvagingArmorTrim = false;
|
||||
SalvageMethod salvageMethod = SalvageMethod.SALVAGE;
|
||||
if (itemInHand.getItemMeta() instanceof ArmorMeta armorMeta && armorMeta.hasTrim()) {
|
||||
if (!getSettings().salvageArmorTrims()) {
|
||||
sendNPCMessage(this.npc, player, getSettings().getCannotSalvageArmorTrimMessage());
|
||||
return;
|
||||
}
|
||||
salvage = SalvageHelper.getTrimSalvage(itemInHand, armorMeta);
|
||||
salvage = SalvageHelper.getArmorTrimSalvage(itemInHand, armorMeta);
|
||||
if (salvage == null) {
|
||||
sendNPCMessage(this.npc, player, getSettings().getArmorTrimSalvageNotFoundMessage());
|
||||
return;
|
||||
}
|
||||
salvagingArmorTrim = true;
|
||||
salvageMethod = SalvageMethod.ARMOR_TRIM;
|
||||
}
|
||||
|
||||
// Remove the netherite ingot from the item
|
||||
if (salvage == null && SmithPreset.BLACKSMITH.getFilteredMaterials(SmithPresetFilter.NETHERITE).contains(itemInHand.getType())) {
|
||||
if (!getSettings().salvageNetherite()) {
|
||||
sendNPCMessage(this.npc, player, getSettings().getCannotSalvageNetheriteMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
salvage = SalvageHelper.getNetheriteSalvage(itemInHand);
|
||||
salvageMethod = SalvageMethod.NETHERITE;
|
||||
}
|
||||
|
||||
// As there is no recipe for netherite items, the check needs to be after the netherite salvage check
|
||||
if (salvageMethod == SalvageMethod.SALVAGE && !SalvageHelper.isSalvageable(player.getServer(), itemInHand)) {
|
||||
sendNPCMessage(this.npc, player, StringFormatter.replacePlaceholder(getSettings().getInvalidItemMessage(),
|
||||
"{title}", getSettings().getScrapperTitle()));
|
||||
}
|
||||
|
||||
// Check if the item is enchanted, and whether this blacksmith can salvage it
|
||||
@ -121,26 +141,53 @@ public class ScrapperTrait extends CustomTrait<ScrapperSetting> {
|
||||
return;
|
||||
}
|
||||
|
||||
//Start a new scrapper session for the player
|
||||
startSession(player, salvage, salvageMethod);
|
||||
// Print the cost to the player
|
||||
printCostMessage(player, itemInHand, EconomyManager.formatSalvageCost(salvageMethod), salvageMethod);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a message to the given player, explaining the cost of salvaging the held item
|
||||
*
|
||||
* @param player <p>The player that interacted with the scrapper</p>
|
||||
* @param itemInHand <p>The item the player wants to salvage</p>
|
||||
* @param cost <p>The cost of salvaging the item</p>
|
||||
* @param salvageMethod <p>The type of salvage performed</p>
|
||||
*/
|
||||
private void printCostMessage(@NotNull Player player, @NotNull ItemStack itemInHand, @NotNull String cost,
|
||||
@NotNull SalvageMethod salvageMethod) {
|
||||
StringReplacer replacer = new StringReplacer();
|
||||
replacer.add("{cost}", cost);
|
||||
replacer.add("{item}", itemInHand.getType().name().toLowerCase().replace('_', ' '));
|
||||
if (salvageMethod == SalvageMethod.ARMOR_TRIM) {
|
||||
sendNPCMessage(this.npc, player, replacer.replace(getSettings().getArmorTrimCostMessage()));
|
||||
} else if (salvageMethod == SalvageMethod.SALVAGE) {
|
||||
String expectedYield;
|
||||
if (ItemHelper.getDamage(itemInHand) <= 0) {
|
||||
expectedYield = getSettings().getFullSalvageMessage();
|
||||
} else {
|
||||
expectedYield = getSettings().getPartialSalvageMessage();
|
||||
}
|
||||
replacer.add("{yield}", expectedYield);
|
||||
sendNPCMessage(this.npc, player, replacer.replace(getSettings().getCostMessage()));
|
||||
} else if (salvageMethod == SalvageMethod.NETHERITE) {
|
||||
sendNPCMessage(this.npc, player, replacer.replace(getSettings().getNetheriteCostMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a new scrapper session
|
||||
*
|
||||
* @param player <p>The player to start the session for</p>
|
||||
* @param salvage <p>The salvage to return to the player</p>
|
||||
* @param salvageMethod <p>The type of salvage performed</p>
|
||||
*/
|
||||
private void startSession(@NotNull Player player, @NotNull List<ItemStack> salvage,
|
||||
@NotNull SalvageMethod salvageMethod) {
|
||||
//Start a new scrapper session for the player
|
||||
currentSessionStartTime = System.currentTimeMillis();
|
||||
session = new SalvageSession(this, player, npc, getSettings(), salvage);
|
||||
//Tell the player the cost of repairing the item
|
||||
String cost = EconomyManager.formatScrapperCost();
|
||||
|
||||
String expectedYield;
|
||||
if (ItemHelper.getDamage(itemInHand) <= 0) {
|
||||
expectedYield = getSettings().getFullSalvageMessage();
|
||||
} else {
|
||||
expectedYield = getSettings().getPartialSalvageMessage();
|
||||
}
|
||||
|
||||
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)));
|
||||
}
|
||||
session = new SalvageSession(this, player, npc, getSettings(), salvage, salvageMethod);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -151,17 +198,14 @@ public class ScrapperTrait extends CustomTrait<ScrapperSetting> {
|
||||
/**
|
||||
* Gets whether this scrapper can salvage the given item
|
||||
*
|
||||
* @param server <p>The server to get recipes from</p>
|
||||
* @param item <p>The item to check</p>
|
||||
* @param salvageAbleItems <p>The items this scrapper can salvage</p>
|
||||
* @param extended <p>Whether extended salvage is enabled</p>
|
||||
* @return <p>True if the item can be theoretically salvaged</p>
|
||||
*/
|
||||
private boolean canBeSalvaged(@NotNull Server server, @NotNull ItemStack item,
|
||||
@NotNull List<Material> salvageAbleItems, boolean extended) {
|
||||
return (extended || ItemHelper.isRepairable(item)) && ItemHelper.isSalvageable(server, item) &&
|
||||
(salvageAbleItems.isEmpty() || salvageAbleItems.contains(item.getType())) &&
|
||||
SalvageHelper.hasRecipe(item);
|
||||
private boolean canBeSalvaged(@NotNull ItemStack item, @NotNull List<Material> salvageAbleItems, boolean extended) {
|
||||
return (extended || ItemHelper.isRepairable(item)) &&
|
||||
(salvageAbleItems.isEmpty() || salvageAbleItems.contains(item.getType()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -110,6 +110,7 @@ public final class ConfigHelper {
|
||||
/**
|
||||
* Changes all configuration values from the old name to the new name
|
||||
*
|
||||
* @param dataFolderPath <p>The path to this plugin's data</p>
|
||||
* @param currentConfiguration <p>The current config to back up</p>
|
||||
*/
|
||||
public static void migrateConfig(@NotNull String dataFolderPath, @NotNull FileConfiguration currentConfiguration) {
|
||||
|
@ -3,11 +3,8 @@ package net.knarcraft.blacksmith.util;
|
||||
import net.knarcraft.blacksmith.BlacksmithPlugin;
|
||||
import net.knarcraft.blacksmith.config.SmithPreset;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.inventory.CraftingRecipe;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.Recipe;
|
||||
import org.bukkit.inventory.meta.Damageable;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -168,40 +165,6 @@ public final class ItemHelper {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given item can be salvaged, assuming no restrictions apply
|
||||
*
|
||||
* @param server <p>The server to get recipes from</p>
|
||||
* @param item <p>The item to check</p>
|
||||
* @return <p>True if the item can be salvaged</p>
|
||||
*/
|
||||
public static boolean isSalvageable(@NotNull Server server, @NotNull ItemStack item) {
|
||||
for (Recipe recipe : server.getRecipesFor(new ItemStack(item.getType(), item.getAmount()))) {
|
||||
// Only crafting recipes are allowed.
|
||||
if ((recipe instanceof CraftingRecipe) && item.getAmount() >= recipe.getResult().getAmount()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of an item that's required to salvage that item
|
||||
*
|
||||
* @param server <p>The server to get recipes from</p>
|
||||
* @param item <p>The item to check</p>
|
||||
* @return <p>The number of items required for salvage, or -1 if the recipe was not found</p>
|
||||
*/
|
||||
public static int getRequiredAmountForSalvage(@NotNull Server server, @NotNull ItemStack item) {
|
||||
for (Recipe recipe : server.getRecipesFor(new ItemStack(item.getType(), item.getAmount()))) {
|
||||
// Only crafting recipes are allowed.
|
||||
if (recipe instanceof CraftingRecipe) {
|
||||
return recipe.getResult().getAmount();
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all materials matching the given material wildcard
|
||||
*
|
||||
|
@ -1,6 +1,5 @@
|
||||
package net.knarcraft.blacksmith.util;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
@ -43,6 +42,29 @@ public final class SalvageHelper {
|
||||
trimMaterialToMaterial.put(TrimMaterial.REDSTONE, Material.REDSTONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets salvage for a given netherite item
|
||||
*
|
||||
* @param item <p>The netherite armor/tool to salvage</p>
|
||||
* @return <p></p>
|
||||
*/
|
||||
@Nullable
|
||||
public static List<ItemStack> getNetheriteSalvage(@NotNull ItemStack item) {
|
||||
Material newMaterial = Material.matchMaterial(item.getType().name().replace("NETHERITE", "DIAMOND"));
|
||||
if (newMaterial == null) {
|
||||
return null;
|
||||
}
|
||||
ItemStack clone = item.clone();
|
||||
clone.setType(newMaterial);
|
||||
|
||||
List<ItemStack> salvage = new ArrayList<>();
|
||||
salvage.add(clone);
|
||||
salvage.add(new ItemStack(Material.NETHERITE_INGOT, 1));
|
||||
salvage.add(new ItemStack(Material.NETHERITE_UPGRADE_SMITHING_TEMPLATE, 1));
|
||||
|
||||
return salvage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets salvage for the given armor trim
|
||||
*
|
||||
@ -51,7 +73,7 @@ public final class SalvageHelper {
|
||||
* @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) {
|
||||
public static List<ItemStack> getArmorTrimSalvage(@NotNull ItemStack item, @NotNull ArmorMeta armorMeta) {
|
||||
ArmorTrim armorTrim = armorMeta.getTrim();
|
||||
if (armorTrim == null) {
|
||||
return null;
|
||||
@ -82,22 +104,41 @@ public final class SalvageHelper {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether the given item has a valid crafting recipe
|
||||
* Checks whether the given item can be salvaged, assuming no restrictions apply
|
||||
*
|
||||
* @param item <p>The item to check</p>
|
||||
* @return <p>True if the item has a valid crafting recipe</p>
|
||||
* @param server <p>The server to get recipes from</p>
|
||||
* @param item <p>The item to check</p>
|
||||
* @return <p>True if the item can be salvaged</p>
|
||||
*/
|
||||
public static boolean hasRecipe(@NotNull ItemStack item) {
|
||||
List<Recipe> recipes = Bukkit.getRecipesFor(new ItemStack(item.getType(), item.getAmount()));
|
||||
public static boolean isSalvageable(@NotNull Server server, @NotNull ItemStack item) {
|
||||
List<Recipe> recipes = server.getRecipesFor(new ItemStack(item.getType(), item.getAmount()));
|
||||
for (Recipe recipe : recipes) {
|
||||
if (recipe instanceof ShapedRecipe || recipe instanceof ShapelessRecipe) {
|
||||
// Only crafting recipes are allowed.
|
||||
if ((recipe instanceof ShapedRecipe || recipe instanceof ShapelessRecipe) &&
|
||||
item.getAmount() >= recipe.getResult().getAmount()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of an item that's required to salvage that item
|
||||
*
|
||||
* @param server <p>The server to get recipes from</p>
|
||||
* @param item <p>The item to check</p>
|
||||
* @return <p>The number of items required for salvage, or -1 if the recipe was not found</p>
|
||||
*/
|
||||
public static int getRequiredAmountForSalvage(@NotNull Server server, @NotNull ItemStack item) {
|
||||
for (Recipe recipe : server.getRecipesFor(new ItemStack(item.getType(), item.getAmount()))) {
|
||||
// Only crafting recipes are allowed.
|
||||
if (recipe instanceof ShapedRecipe || recipe instanceof ShapelessRecipe) {
|
||||
return recipe.getResult().getAmount();
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the sum of all enchantment levels for the given item
|
||||
*
|
||||
|
@ -116,8 +116,8 @@ blacksmith:
|
||||
scrapper:
|
||||
# The settings which apply to all Scrapper NPCs. These can also be changed using the /scrapperConfig command
|
||||
global:
|
||||
# Exact time displays the exact number of seconds and minutes remaining as part of the scrapping cool-down and
|
||||
# scrapping delay messages, instead of just vaguely hinting at the remaining time.
|
||||
# Exact time displays the exact number of seconds and minutes remaining as part of the salvaging cool-down and
|
||||
# salvaging delay messages, instead of just vaguely hinting at the remaining time.
|
||||
showExactTime: false
|
||||
|
||||
# Whether enchanted salvaged items should return some amount of exp upon salvage
|
||||
@ -130,14 +130,20 @@ scrapper:
|
||||
trashSalvage:
|
||||
- "*_SHOVEL;*_PICKAXE;*_AXE;*_HOE;*_SWORD;SHIELD;*_BOW:STICK"
|
||||
|
||||
# The cost of using the scrapper
|
||||
basePrice: 0
|
||||
# The cost of using a scrapper to salvage an item
|
||||
salvagePrice: 0
|
||||
|
||||
# The cost of using the scrapper to remove armor trim
|
||||
armorTrimSalvagePrice: 5
|
||||
|
||||
# The cost of using the scrapper to remove netherite from an item
|
||||
netheriteSalvagePrice: 15
|
||||
|
||||
# The settings which are set to any new scrapper NPC. To change any of these settings for an existing NPC, you must
|
||||
# change the Citizens NPC file, or use the /scrapper command
|
||||
defaults:
|
||||
|
||||
# Whether the item will drop materials resulting from scrapping on the ground, instead of putting them into the user's inventory
|
||||
# Whether the item will drop materials resulting from salvaging on the ground, instead of putting them into the user's inventory
|
||||
dropItem: true
|
||||
|
||||
# The chance to fail a salvage, thus destroying the item (0-100)
|
||||
@ -170,6 +176,9 @@ scrapper:
|
||||
# Whether to enable salvaging of armor trims
|
||||
salvageArmorTrims: true
|
||||
|
||||
# Whether to enable salvaging of netherite items
|
||||
salvageNetherite: true
|
||||
|
||||
# Default values for messages used by NPCs
|
||||
messages:
|
||||
# The message to display when another player is using the scrapper
|
||||
@ -203,10 +212,13 @@ scrapper:
|
||||
insufficientFundsMessage: "&cYou don't have enough money to salvage an item!"
|
||||
|
||||
# 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 &a{item}&e! {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!"
|
||||
costMessageArmorTrim: "&eIt will cost &a{cost}&e to salvage that &a{item}&e's armor trim!"
|
||||
|
||||
# The message to display when explaining the shown item's netherite salvage cost
|
||||
costMessageNetherite: "&eIt will cost &a{cost}&e to salvage that &a{item}&e into diamond!"
|
||||
|
||||
# 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"
|
||||
@ -222,3 +234,6 @@ scrapper:
|
||||
|
||||
# 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!"
|
||||
|
||||
# The message to display when asked to salvage netherite items, and that option is disabled
|
||||
cannotSalvageNetheriteMessage: "&cI'm sorry, but I'm unable to salvage netherite items!"
|
Loading…
Reference in New Issue
Block a user