package net.knarcraft.blacksmith.util; import net.knarcraft.blacksmith.container.ActionCost; import net.knarcraft.blacksmith.formatting.Translatable; import net.knarcraft.blacksmith.property.CostModifyAction; import net.knarcraft.blacksmith.property.CostType; import net.knarcraft.knarlib.formatting.FormatBuilder; import net.knarcraft.knarlib.util.TabCompletionHelper; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; /** * A helper class for setting action costs */ public final class CostHelper { private CostHelper() { } /** * Parses a simple double cost * * @param commandSender
The command sender to notify of any problems
* @param costStringThe string to parse into a cost
* @returnThe parsed cost, or null if not a valid number
*/ @Nullable public static Double parseSimpleCost(@NotNull CommandSender commandSender, @NotNull String costString) throws IllegalArgumentException { try { double cost = Double.parseDouble(costString); if (cost < 0) { throw new NumberFormatException(); } return cost; } catch (NumberFormatException exception) { new FormatBuilder(Translatable.DOUBLE_COST_REQUIRED).error(commandSender); return null; } } /** * Shows tab-completion actions for altering a cost * * @param argumentsThe arguments given by the user
* @returnThe available tab-complete options
*/ public static @Nullable ListThe action to perform on the cost
* @param costTypeNameThe name of the cost to modify, or null if clearing costs
* @param costValueThe value of the new cost, or null if clearing costs
* @param oldCostThe previous cost of the action
* @param playerThe player attempting to alter the action cost
* @returnThe modified action cost, or null if something went wrong
*/ @Nullable public static ActionCost modifyActionCost(@NotNull String costAction, @Nullable String costTypeName, @Nullable String costValue, @NotNull ActionCost oldCost, @NotNull Player player) { CostType costType; if (costTypeName != null) { costType = CostType.parse(costTypeName); } else { costType = null; } CostModifyAction action = CostModifyAction.fromString(costAction); if (action == null) { return null; } if (action != CostModifyAction.CLEAR && (costType == null || costValue == null)) { player.sendMessage("Invalid cost type or value specified!"); return null; } return switch (action) { case CLEAR -> clearActionCost(costType, oldCost); case ADD -> addActionCost(costType, costValue, oldCost, player); case SET -> setActionCost(costType, costValue, player); }; } /** * Sets the cost to the specified value * * @param costTypeThe type of cost to set
* @param costValueThe value of the new cost
* @param playerThe player to alert if the cost cannot be properly set
* @returnThe new action cost
*/ public static ActionCost setActionCost(@NotNull CostType costType, @NotNull String costValue, @NotNull Player player) { return parseCost(costType, costValue, new ActionCost(), player); } /** * Modifies a value for the specified action cost * * @param costTypeThe type of cost to modify
* @param costValueThe new value of the cost
* @param oldCostThe cost to modify
* @param playerThe player to alert if the cost cannot be properly set
* @returnThe new action cost
*/ public static ActionCost addActionCost(@NotNull CostType costType, @NotNull String costValue, @NotNull ActionCost oldCost, @NotNull Player player) { return parseCost(costType, costValue, oldCost, player); } /** * Clears an action cost * * @param costTypeThe type of action cost to clear, or null if clearing all action costs
* @param oldCostThe old cost to modify, or null if clearing all action costs
* @returnThe modified cost
*/ public static ActionCost clearActionCost(@Nullable CostType costType, @Nullable ActionCost oldCost) { // Clears one or all fields of a cost if (costType == null || oldCost == null) { return new ActionCost(); } else { return switch (costType) { case EXP -> oldCost.changeExpCost(0); case ITEM -> oldCost.changeItemCost(null); case ECONOMY -> oldCost.changeMonetaryCost(0); case PERMISSION -> oldCost.changePermissionCost(Set.of()); }; } } /** * Parses an advanced action cost * * @param costTypeThe type of cost to parse
* @param valueThe value to parse
* @param oldCostThe old cost to modify
* @param playerThe player changing the value
* @returnThe new action cost, or null if the process failed.
*/ @Nullable private static ActionCost parseCost(@NotNull CostType costType, @NotNull String value, @NotNull ActionCost oldCost, @NotNull Player player) { switch (costType) { case ECONOMY: double economyCost = Double.parseDouble(value); if (economyCost < 0) { new FormatBuilder("Cost cannot be negative!").error(player); return null; } return oldCost.changeMonetaryCost(economyCost); case ITEM: ItemStack itemCost = player.getInventory().getItemInMainHand(); if (itemCost.getType().isAir()) { new FormatBuilder("You have no item in your main hand").error(player); return null; } return oldCost.changeItemCost(itemCost); case PERMISSION: Set