Files
Blacksmith/src/main/java/net/knarcraft/blacksmith/util/CostHelper.java
EpicKnarvik97 0919b4c4db
All checks were successful
EpicKnarvik97/Blacksmith/pipeline/head This commit looks good
Attempts to start proper implementation of the new action cost
2025-12-17 14:25:14 +01:00

216 lines
8.4 KiB
Java

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 <p>The command sender to notify of any problems</p>
* @param costString <p>The string to parse into a cost</p>
* @return <p>The parsed cost, or null if not a valid number</p>
*/
@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 arguments <p>The arguments given by the user</p>
* @return <p>The available tab-complete options</p>
*/
public static @Nullable List<String> tabCompleteCost(@NotNull String[] arguments) {
if (arguments.length == 1) {
return List.of("simple", "advanced");
} else if (arguments.length == 2) {
if (arguments[0].equalsIgnoreCase("simple")) {
return List.of();
} else {
return TabCompletionHelper.filterMatchingStartsWith(TabCompletionHelper.getEnumList(CostModifyAction.class), arguments[1]);
}
} else if (arguments.length == 3) {
if (arguments[0].equalsIgnoreCase("simple")) {
return List.of();
} else {
return TabCompletionHelper.filterMatchingStartsWith(TabCompletionHelper.getEnumList(CostType.class), arguments[2]);
}
} else if (arguments.length == 4) {
CostType costType = CostType.parse(arguments[2]);
if (costType == null) {
return null;
}
return switch (costType) {
case PERMISSION -> TabCompletionHelper.tabCompletePermission(arguments[3]);
case ECONOMY -> List.of("0.5", "1", "10");
case EXP -> List.of("1, 5, 10");
case ITEM -> List.of();
};
}
return List.of();
}
/**
* Modifies the cost of an action
*
* @param costAction <p>The action to perform on the cost</p>
* @param costTypeName <p>The name of the cost to modify, or null if clearing costs</p>
* @param costValue <p>The value of the new cost, or null if clearing costs</p>
* @param oldCost <p>The previous cost of the action</p>
* @param player <p>The player attempting to alter the action cost</p>
* @return <p>The modified action cost, or null if something went wrong</p>
*/
@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 costType <p>The type of cost to set</p>
* @param costValue <p>The value of the new cost</p>
* @param player <p>The player to alert if the cost cannot be properly set</p>
* @return <p>The new action cost</p>
*/
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 costType <p>The type of cost to modify</p>
* @param costValue <p>The new value of the cost</p>
* @param oldCost <p>The cost to modify</p>
* @param player <p>The player to alert if the cost cannot be properly set</p>
* @return <p>The new action cost</p>
*/
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 costType <p>The type of action cost to clear, or null if clearing all action costs</p>
* @param oldCost <p>The old cost to modify, or null if clearing all action costs</p>
* @return <p>The modified cost</p>
*/
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 costType <p>The type of cost to parse</p>
* @param value <p>The value to parse</p>
* @param oldCost <p>The old cost to modify</p>
* @param player <p>The player changing the value</p>
* @return <p>The new action cost, or null if the process failed.</p>
*/
@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<String> permissionSet = new HashSet<>(Arrays.asList(value.split(",")));
return oldCost.changePermissionCost(permissionSet);
case EXP:
int expCost = Integer.parseInt(value);
if (expCost < 0) {
new FormatBuilder("Exp cost cannot be negative!").error(player);
return null;
}
return oldCost.changeExpCost(expCost);
default:
return null;
}
}
}