Changes ignored salvage into trash salvage according to #22
This commit is contained in:
parent
c71d664a79
commit
21d55563b7
12
README.md
12
README.md
@ -59,10 +59,10 @@ annoying:
|
|||||||
|
|
||||||
A scrapper will produce salvage for a damage-able item by calculating the amount of items returned based on items in the
|
A scrapper will produce salvage for a damage-able item by calculating the amount of items returned based on items in the
|
||||||
recipe, and the percentage of durability left on the item. To avoid returning relatively worthless items instead of
|
recipe, and the percentage of durability left on the item. To avoid returning relatively worthless items instead of
|
||||||
valuable items, `ignoredSalvage` can be configured. If the item is fully repaired, the worthless items will be returned
|
valuable items, `trashSalvage` can be configured. Trash salvage will only be returned if all non-trash items are
|
||||||
as well, but otherwise, only the valuable items are considered as possible salvage. A scrapper will by default only
|
returned as well. A scrapper will by default only salvage damage-able items (same as blacksmiths), but enabling
|
||||||
salvage damage-able items (same as blacksmiths), but enabling `extendedSalvageEnabled` for a scrapper will allow it to
|
`extendedSalvageEnabled` for a scrapper will allow it to salvage any crafting table recipe. Note that to salvage for
|
||||||
salvage any crafting table recipe. Note that to salvage for example planks into wood, four wood will be taken.
|
example planks into wood, four wood will be taken.
|
||||||
|
|
||||||
When an item is salvaged, EXP will be returned based on enchantments on the item.
|
When an item is salvaged, EXP will be returned based on enchantments on the item.
|
||||||
|
|
||||||
@ -214,11 +214,11 @@ All currently supported presets, and available filters for each preset:
|
|||||||
### Scrapper global-only options
|
### Scrapper global-only options
|
||||||
|
|
||||||
| Key | Value type | Description |
|
| Key | Value type | Description |
|
||||||
|----------------|----------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|----------------|------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| basePrice | positive decimal number | The cost of using a scrapper |
|
| basePrice | positive decimal number | The cost of using a scrapper |
|
||||||
| showExactTime | true/false | If true, scrappers will display exact time remaining in minutes and seconds, instead of vague expressions |
|
| showExactTime | true/false | If true, scrappers will display exact time remaining in minutes and seconds, instead of vague expressions |
|
||||||
| giveExperience | true/false | If true, each enchantment level on the salvaged item will give one EXP level as salvage |
|
| giveExperience | true/false | If true, each enchantment level on the salvaged item will give one EXP level as salvage |
|
||||||
| ignoredSalvage | TARGET_MATERIAL:IGNORED_MATERIAL | The items that should be ignored 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:STICK` (the default) for ignoring sticks in salvage for shovels, pickaxes, axes, hoes and swords. A `:` character splits selected items and the ignored salvage. Different item specifications are split by a `;` character. Use `,` to split separate ignored salvages, like: `SHIELD:STICK,BOW_STRING` |
|
| trashSalvage | TARGET_MATERIAL:IGNORED_MATERIAL\[,\*_TARGET2:\*_IGNORED2] | 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)
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ public class GlobalScrapperSettings implements Settings<ScrapperSetting> {
|
|||||||
|
|
||||||
private final Map<ScrapperSetting, Object> settings = new HashMap<>();
|
private final Map<ScrapperSetting, Object> settings = new HashMap<>();
|
||||||
private final List<Material> defaultSalvageableMaterials = new ArrayList<>();
|
private final List<Material> defaultSalvageableMaterials = new ArrayList<>();
|
||||||
private final Map<Material, Set<Material>> ignoredSalvage = new HashMap<>();
|
private final Map<Material, Set<Material>> trashSalvage = new HashMap<>();
|
||||||
|
|
||||||
private final BlacksmithPlugin instance;
|
private final BlacksmithPlugin instance;
|
||||||
|
|
||||||
@ -144,7 +144,7 @@ public class GlobalScrapperSettings implements Settings<ScrapperSetting> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
loadSalvageAbleItems();
|
loadSalvageAbleItems();
|
||||||
loadIgnoredSalvage();
|
loadTrashSalvage();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -182,17 +182,17 @@ public class GlobalScrapperSettings implements Settings<ScrapperSetting> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets ignored salvage for the given material
|
* Gets trash salvage for the given material
|
||||||
*
|
*
|
||||||
* <p>The ignored salvage should be ignored when calculating item salvage, in order to increase the probability of
|
* <p>The trash salvage should be deferred when calculating item salvage, in order to increase the probability of
|
||||||
* getting the more expensive materials back.</p>
|
* getting the more expensive materials back.</p>
|
||||||
*
|
*
|
||||||
* @param material <p>The material to get ignored salvage for</p>
|
* @param material <p>The material to get trash salvage for</p>
|
||||||
* @return <p>The ignored salvage</p>
|
* @return <p>The trash salvage</p>
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public Set<Material> getIgnoredSalvage(@NotNull Material material) {
|
public Set<Material> getTrashSalvage(@NotNull Material material) {
|
||||||
return this.ignoredSalvage.get(material);
|
return this.trashSalvage.get(material);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -207,40 +207,40 @@ public class GlobalScrapperSettings implements Settings<ScrapperSetting> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads all ignored salvage from the configuration file
|
* Loads all trash salvage from the configuration file
|
||||||
*/
|
*/
|
||||||
private void loadIgnoredSalvage() {
|
private void loadTrashSalvage() {
|
||||||
this.ignoredSalvage.clear();
|
this.trashSalvage.clear();
|
||||||
List<String> allIgnoredSalvage = ConfigHelper.asStringList(this.settings.get(ScrapperSetting.IGNORED_SALVAGE));
|
List<String> allTrashSalvage = ConfigHelper.asStringList(this.settings.get(ScrapperSetting.IGNORED_SALVAGE));
|
||||||
if (allIgnoredSalvage == null) {
|
if (allTrashSalvage == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String ignoredSalvageInfo : allIgnoredSalvage) {
|
for (String trashSalvageInfo : allTrashSalvage) {
|
||||||
// Ignore invalid lines
|
// Ignore invalid lines
|
||||||
if (!ignoredSalvageInfo.contains(":")) {
|
if (!trashSalvageInfo.contains(":")) {
|
||||||
BlacksmithPlugin.getInstance().getLogger().log(Level.WARNING, String.format("The ignored salvage " +
|
BlacksmithPlugin.getInstance().getLogger().log(Level.WARNING, String.format("The trash salvage " +
|
||||||
"configuration line %s is invalid", ignoredSalvageInfo));
|
"configuration line %s is invalid", trashSalvageInfo));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse all material names
|
// Parse all material names
|
||||||
String[] data = ignoredSalvageInfo.split(":");
|
String[] data = trashSalvageInfo.split(":");
|
||||||
String[] materialStrings = data[0].split(";");
|
String[] materialStrings = data[0].split(";");
|
||||||
List<Material> materials = new ArrayList<>();
|
List<Material> materials = new ArrayList<>();
|
||||||
for (String materialString : materialStrings) {
|
for (String materialString : materialStrings) {
|
||||||
materials.addAll(ItemHelper.getWildcardMatch(materialString, true));
|
materials.addAll(ItemHelper.getWildcardMatch(materialString, true));
|
||||||
}
|
}
|
||||||
String[] ignoredSalvageStrings = data[1].split(";");
|
String[] trashSalvageStrings = data[1].split(";");
|
||||||
List<Material> ignored = new ArrayList<>();
|
List<Material> ignored = new ArrayList<>();
|
||||||
for (String ignoredSalvageString : ignoredSalvageStrings) {
|
for (String trashSalvageString : trashSalvageStrings) {
|
||||||
ignored.addAll(ItemHelper.getWildcardMatch(ignoredSalvageString, true));
|
ignored.addAll(ItemHelper.getWildcardMatch(trashSalvageString, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the ignored salvage to all the matched materials
|
// Add the trash salvage to all the matched materials
|
||||||
for (Material material : materials) {
|
for (Material material : materials) {
|
||||||
ignoredSalvage.computeIfAbsent(material, k -> new HashSet<>());
|
trashSalvage.computeIfAbsent(material, k -> new HashSet<>());
|
||||||
ignoredSalvage.get(material).addAll(ignored);
|
trashSalvage.get(material).addAll(ignored);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,13 +194,13 @@ public enum ScrapperSetting implements Setting {
|
|||||||
/**
|
/**
|
||||||
* Which items are ignored when calculating salvage for a given material
|
* Which items are ignored when calculating salvage for a given material
|
||||||
*/
|
*/
|
||||||
IGNORED_SALVAGE("ignoredSalvage", SettingValueType.STRING_LIST,
|
IGNORED_SALVAGE("trashSalvage", SettingValueType.STRING_LIST,
|
||||||
new ArrayList<>(List.of("*_SHOVEL;*_PICKAXE;*_AXE;*_HOE;*_SWORD:STICK")),
|
new ArrayList<>(List.of("*_SHOVEL;*_PICKAXE;*_AXE;*_HOE;*_SWORD;SHIELD;*_BOW:STICK")),
|
||||||
"Items ignored during salvage calculation. This follows the format: " +
|
"Items treated as trash during salvage calculation. This follows the format: " +
|
||||||
"\"MATERIAL[,MATERIAL2][,MATERIAL3]:IGNORED\", so the material or materials listed will ignore " +
|
"\"MATERIAL[;MATERIAL2][;MATERIAL3]:TRASH_MATERIAL[;TRASH_MATERIAL2]\", so the material or " +
|
||||||
"the material specified after the \":\" when calculating salvage (* matches any character). This " +
|
"materials listed will treat the material specified after the \":\" as trash when calculating " +
|
||||||
"causes the player to lose some items during salvaging, but can prevent cases where a diamond " +
|
"salvage unless all non-trash items can be given as well(* matches any character).",
|
||||||
"pickaxe is salvaged and only sticks are returned.", false, false),
|
false, false),
|
||||||
;
|
;
|
||||||
|
|
||||||
private final String path;
|
private final String path;
|
||||||
|
@ -144,14 +144,14 @@ public class ScrapperTrait extends CustomTrait<ScrapperSetting> {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private List<ItemStack> getSalvage(@NotNull ItemStack item, boolean extended) {
|
private List<ItemStack> getSalvage(@NotNull ItemStack item, boolean extended) {
|
||||||
// Get the salvage, for the item, but ignore some materials if set, and the item isn't at full durability
|
// Get the salvage, for the item, but ignore some materials if set, and the item isn't at full durability
|
||||||
Set<Material> ignoredSalvage = BlacksmithPlugin.getInstance().getGlobalScrapperSettings().getIgnoredSalvage(
|
Set<Material> trashSalvage = BlacksmithPlugin.getInstance().getGlobalScrapperSettings().getTrashSalvage(
|
||||||
item.getType());
|
item.getType());
|
||||||
// Don't ignore salvage for fully repaired items
|
// Don't ignore salvage for fully repaired items
|
||||||
if (ignoredSalvage == null || ItemHelper.getDamage(item) == 0) {
|
if (trashSalvage == null || ItemHelper.getDamage(item) == 0) {
|
||||||
ignoredSalvage = new HashSet<>();
|
trashSalvage = new HashSet<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
return SalvageHelper.getSalvage(BlacksmithPlugin.getInstance().getServer(), item, ignoredSalvage, extended);
|
return SalvageHelper.getSalvage(BlacksmithPlugin.getInstance().getServer(), item, trashSalvage, extended);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -63,12 +63,12 @@ public final class SalvageHelper {
|
|||||||
*
|
*
|
||||||
* @param server <p>The server to get recipes from</p>
|
* @param server <p>The server to get recipes from</p>
|
||||||
* @param salvagedItem <p>The item stack to salvage</p>
|
* @param salvagedItem <p>The item stack to salvage</p>
|
||||||
* @param ignoredSalvage <p>Any material which should not be returned as part of the salvage.</p>
|
* @param trashSalvage <p>Any material treated as trash salvage</p>
|
||||||
* @param extended <p>Whether to enable extended salvage, ignoring the repairable restriction</p>
|
* @param extended <p>Whether to enable extended salvage, ignoring the repairable restriction</p>
|
||||||
* @return <p>The items to return to the user, or null if not salvageable</p>
|
* @return <p>The items to return to the user, or null if not salvageable</p>
|
||||||
*/
|
*/
|
||||||
public static @Nullable List<ItemStack> getSalvage(@NotNull Server server, @Nullable ItemStack salvagedItem,
|
public static @Nullable List<ItemStack> getSalvage(@NotNull Server server, @Nullable ItemStack salvagedItem,
|
||||||
@NotNull Collection<Material> ignoredSalvage, boolean extended) {
|
@NotNull Collection<Material> trashSalvage, boolean extended) {
|
||||||
if (salvagedItem == null || salvagedItem.getAmount() < 1 ||
|
if (salvagedItem == null || salvagedItem.getAmount() < 1 ||
|
||||||
(!extended && !ItemHelper.isRepairable(salvagedItem))) {
|
(!extended && !ItemHelper.isRepairable(salvagedItem))) {
|
||||||
return null;
|
return null;
|
||||||
@ -76,7 +76,7 @@ public final class SalvageHelper {
|
|||||||
|
|
||||||
for (Recipe recipe : server.getRecipesFor(new ItemStack(salvagedItem.getType(), salvagedItem.getAmount()))) {
|
for (Recipe recipe : server.getRecipesFor(new ItemStack(salvagedItem.getType(), salvagedItem.getAmount()))) {
|
||||||
if (recipe instanceof ShapedRecipe || recipe instanceof ShapelessRecipe) {
|
if (recipe instanceof ShapedRecipe || recipe instanceof ShapelessRecipe) {
|
||||||
List<ItemStack> salvage = getRecipeSalvage(recipe, salvagedItem, ignoredSalvage);
|
List<ItemStack> salvage = getRecipeSalvage(recipe, salvagedItem, trashSalvage);
|
||||||
if (salvage != null && !salvage.isEmpty()) {
|
if (salvage != null && !salvage.isEmpty()) {
|
||||||
return salvage;
|
return salvage;
|
||||||
}
|
}
|
||||||
@ -91,11 +91,11 @@ public final class SalvageHelper {
|
|||||||
*
|
*
|
||||||
* @param recipe <p>The recipe to get salvage for</p>
|
* @param recipe <p>The recipe to get salvage for</p>
|
||||||
* @param salvagedItem <p>The item to be salvaged</p>
|
* @param salvagedItem <p>The item to be salvaged</p>
|
||||||
* @param ignoredSalvage <p>Any material which should not be returned as part of the salvage.</p>
|
* @param trashSalvage <p>Any material treated as trash salvage</p>
|
||||||
* @return <p>A list of items, or null if not a valid type of recipe</p>
|
* @return <p>A list of items, or null if not a valid type of recipe</p>
|
||||||
*/
|
*/
|
||||||
private static @Nullable List<ItemStack> getRecipeSalvage(@NotNull Recipe recipe, @NotNull ItemStack salvagedItem,
|
private static @Nullable List<ItemStack> getRecipeSalvage(@NotNull Recipe recipe, @NotNull ItemStack salvagedItem,
|
||||||
@NotNull Collection<Material> ignoredSalvage) {
|
@NotNull Collection<Material> trashSalvage) {
|
||||||
List<ItemStack> ingredients;
|
List<ItemStack> ingredients;
|
||||||
if (recipe instanceof ShapedRecipe shapedRecipe) {
|
if (recipe instanceof ShapedRecipe shapedRecipe) {
|
||||||
ingredients = getIngredients(shapedRecipe);
|
ingredients = getIngredients(shapedRecipe);
|
||||||
@ -108,10 +108,7 @@ public final class SalvageHelper {
|
|||||||
//Make things easier by eliminating identical stacks
|
//Make things easier by eliminating identical stacks
|
||||||
ingredients = combineStacks(ingredients);
|
ingredients = combineStacks(ingredients);
|
||||||
|
|
||||||
//Purge any ignored salvage to only calculate salvage using the remaining items
|
return combineStacks(getSalvage(copyItems(ingredients), salvagedItem, trashSalvage));
|
||||||
ingredients.removeIf((item) -> ignoredSalvage.contains(item.getType()));
|
|
||||||
|
|
||||||
return combineStacks(getSalvage(copyItems(ingredients), salvagedItem));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -135,11 +132,13 @@ public final class SalvageHelper {
|
|||||||
*
|
*
|
||||||
* @param recipeItems <p>All items required for crafting the item to salvage</p>
|
* @param recipeItems <p>All items required for crafting the item to salvage</p>
|
||||||
* @param salvagedItem <p>The item to be salvaged</p>
|
* @param salvagedItem <p>The item to be salvaged</p>
|
||||||
|
* @param trashSalvage <p>The types of materials considered trash for this recipe</p>
|
||||||
* @return <p>The items to be returned to the user as salvage</p>
|
* @return <p>The items to be returned to the user as salvage</p>
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
private static List<ItemStack> getSalvage(@NotNull List<ItemStack> recipeItems,
|
private static List<ItemStack> getSalvage(@NotNull List<ItemStack> recipeItems,
|
||||||
@NotNull ItemStack salvagedItem) {
|
@NotNull ItemStack salvagedItem,
|
||||||
|
@NotNull Collection<Material> trashSalvage) {
|
||||||
int durability = ItemHelper.getDurability(salvagedItem);
|
int durability = ItemHelper.getDurability(salvagedItem);
|
||||||
int maxDurability = ItemHelper.getMaxDurability(salvagedItem);
|
int maxDurability = ItemHelper.getMaxDurability(salvagedItem);
|
||||||
|
|
||||||
@ -156,16 +155,28 @@ public final class SalvageHelper {
|
|||||||
int itemsToReturn = (int) Math.floor(percentageRemaining * totalItems);
|
int itemsToReturn = (int) Math.floor(percentageRemaining * totalItems);
|
||||||
int bound = recipeItems.size();
|
int bound = recipeItems.size();
|
||||||
|
|
||||||
|
List<ItemStack> goodItems = copyItems(recipeItems);
|
||||||
|
goodItems.removeIf((item) -> trashSalvage.contains(item.getType()));
|
||||||
|
int goodSalvage = totalItemAmount(goodItems);
|
||||||
|
|
||||||
List<ItemStack> salvage = new ArrayList<>();
|
List<ItemStack> salvage = new ArrayList<>();
|
||||||
for (int i = 0; i < itemsToReturn; i++) {
|
for (int i = 0; i < itemsToReturn; i++) {
|
||||||
|
// Pick random item
|
||||||
int itemIndex = SalvageHelper.random.nextInt(bound);
|
int itemIndex = SalvageHelper.random.nextInt(bound);
|
||||||
ItemStack itemStack = recipeItems.get(itemIndex);
|
ItemStack itemStack = recipeItems.get(itemIndex);
|
||||||
|
|
||||||
|
// The selected item is trash, so skip it
|
||||||
|
if (trashSalvage.contains(itemStack.getType()) && i < goodSalvage) {
|
||||||
|
i--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
//Make sure to never give more of one item than the amount which exists in the recipe
|
//Make sure to never give more of one item than the amount which exists in the recipe
|
||||||
if (itemStack.getAmount() <= 0) {
|
if (itemStack.getAmount() <= 0) {
|
||||||
i--;
|
i--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
itemStack.setAmount(itemStack.getAmount() - 1);
|
itemStack.setAmount(itemStack.getAmount() - 1);
|
||||||
|
|
||||||
salvage.add(new ItemStack(itemStack.getType(), 1));
|
salvage.add(new ItemStack(itemStack.getType(), 1));
|
||||||
|
@ -123,13 +123,12 @@ scrapper:
|
|||||||
# Whether enchanted salvaged items should return some amount of exp upon salvage
|
# Whether enchanted salvaged items should return some amount of exp upon salvage
|
||||||
giveExperience: true
|
giveExperience: true
|
||||||
|
|
||||||
# Items ignored during salvage calculation. This follows the format:
|
# Items treated as trash during salvage calculation. This follows the format:
|
||||||
# "MATERIAL[;MATERIAL2][;MATERIAL3]:IGNORED_MATERIAL[;IGNORED_MATERIAL2]",
|
# "MATERIAL[;MATERIAL2][;MATERIAL3]:TRASH_MATERIAL[;TRASH_MATERIAL2]", so the material or materials listed will
|
||||||
# so the material or materials listed will ignore the material specified after the ":" when calculating salvage
|
# treat the material specified after the ":" as trash when calculating salvage unless all non-trash items can be
|
||||||
# (* matches any character). This causes the player to lose some items during salvaging, but can prevent cases
|
# given as well(* matches any character).
|
||||||
# where a diamond pickaxe is salvaged and only sticks are returned.
|
trashSalvage:
|
||||||
ignoredSalvage:
|
- "*_SHOVEL;*_PICKAXE;*_AXE;*_HOE;*_SWORD;SHIELD;*_BOW:STICK"
|
||||||
- "*_SHOVEL;*_PICKAXE;*_AXE;*_HOE;*_SWORD:STICK"
|
|
||||||
|
|
||||||
# The cost of using the scrapper
|
# The cost of using the scrapper
|
||||||
basePrice: 0
|
basePrice: 0
|
||||||
|
Loading…
Reference in New Issue
Block a user