Skip to content

Commit

Permalink
Fixes for the upgrade-focus command (#114)
Browse files Browse the repository at this point in the history
* Add handling and error message for missing upgrade arguments

* Try preventing a null exception in the focus upgrades handler

* Update docs to include a vanilla focus upgrade reference

* Rename handler, make id prefix a suffix
  • Loading branch information
rndmorris authored Jan 25, 2025
1 parent c76cacd commit d8c3266
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 50 deletions.
35 changes: 31 additions & 4 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,10 +227,37 @@ Add focus upgrades to a wand focus held in your or another player's hand. Will n

**Arguments:**

| Argument | Required? | Details |
|:-------------------------------:|:---------:|:---------------------------------------------------------------------------------|
| `<upgrade [upgrade[ upgrade]]>` | Yes | A list of one or more upgrades to be applied. |
| `--player <username>` | No | If set, apply upgrades to the specified player's held focus instead of your own. |
| Argument | Required? | Details |
|:-------------------------------:|:---------:|:---------------------------------------------------------------------------------------------------------------------------------------------------|
| `<upgrade [upgrade[ upgrade]]>` | Yes | A list of one to five upgrade ids to be applied. Use tab-completion, or see the table below (vanilla Thaumcraft only), to view available upgrades. |
| `--player <username>` | No | If set, apply upgrades to the specified player's held focus instead of your own. |

The `upgrade` argument is presented in the form `defaultLocalizedName-internalId`. The upgrades available as part of base Thaumcraft are
presented below. Upgrades added by Thaumcraft addons should be automatically supported by the command.

| Upgrade | Internal Id | Expected Argument |
|:-----------------:|:-----------:|:-------------------|
| Potency | 0 | potency-0 |
| Frugal | 1 | frugal-1 |
| Treasure | 2 | treasure-2 |
| Enlarge | 3 | enlarge-3 |
| Alchemist's Fire | 4 | alchemists-fire-4 |
| Alchemist's Frost | 5 | alchemists-frost-5 |
| Architect | 6 | architect-6 |
| Extend | 7 | extend-7 |
| Silk Touch | 8 | silk-touch-8 |
| Fireball | 9 | fireball-9 |
| Fire Beam | 10 | fire-beam-10 |
| Scattershot | 11 | scattershot-11 |
| Ice Boulder | 12 | ice-boulder-12 |
| Bat Bombs | 13 | bat-bombs-13 |
| Devil Bats | 14 | devil-bats-14 |
| Nightshade | 15 | nightshade-15 |
| Seeker | 16 | seeker-16 |
| Chain Lightning | 17 | chain-lightning-17 |
| Earth Shock | 18 | earth-shock-18 |
| Vampire Bats | 19 | vampire-bats-19 |
| Dowsing | 20 | dowsing-20 |

**Default aliases:**
* `/upgrade-focus`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import dev.rndmorris.salisarcana.common.commands.arguments.ArgumentProcessor;
import dev.rndmorris.salisarcana.common.commands.arguments.annotations.NamedArg;
import dev.rndmorris.salisarcana.common.commands.arguments.annotations.PositionalArg;
import dev.rndmorris.salisarcana.common.commands.arguments.handlers.FociUpgradesHandler;
import dev.rndmorris.salisarcana.common.commands.arguments.handlers.FocusUpgradesHandler;
import dev.rndmorris.salisarcana.common.commands.arguments.handlers.IArgumentHandler;
import dev.rndmorris.salisarcana.common.commands.arguments.handlers.named.PlayerHandler;
import dev.rndmorris.salisarcana.config.ConfigModuleRoot;
Expand All @@ -32,7 +32,7 @@ protected ArgumentProcessor<Arguments> initializeProcessor() {
return new ArgumentProcessor<>(
Arguments.class,
Arguments::new,
new IArgumentHandler[] { FociUpgradesHandler.INSTANCE, PlayerHandler.INSTANCE, });
new IArgumentHandler[] { FocusUpgradesHandler.INSTANCE, PlayerHandler.INSTANCE, });
}

@Override
Expand All @@ -47,6 +47,10 @@ protected void process(ICommandSender sender, Arguments arguments, String[] args
arguments.player = executingPlayer;
}

if (arguments.upgrades == null || arguments.upgrades.size() < 1) {
throw new CommandException("salisarcana:command.upgrade-focus.noUpgrades");
}

final var heldItem = arguments.player.getCurrentEquippedItem();
final var heldFocus = WandFocusHelper.getFocusFrom(heldItem);
if (heldItem == null || heldFocus == null) {
Expand All @@ -71,7 +75,7 @@ protected void process(ICommandSender sender, Arguments arguments, String[] args

public static class Arguments {

@PositionalArg(index = 0, handler = FociUpgradesHandler.class, descLangKey = "upgrades")
@PositionalArg(index = 0, handler = FocusUpgradesHandler.class, descLangKey = "upgrades")
public ArrayList<FocusUpgradeType> upgrades;

@NamedArg(name = "--player", handler = PlayerHandler.class, descLangKey = "player")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
import static dev.rndmorris.salisarcana.lib.WandFocusHelper.getFocusFrom;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import net.minecraft.command.CommandBase;
import net.minecraft.command.CommandException;
Expand All @@ -20,51 +22,25 @@

import dev.rndmorris.salisarcana.common.commands.arguments.handlers.named.INamedArgumentHandler;
import dev.rndmorris.salisarcana.common.commands.arguments.handlers.positional.IPositionalArgumentHandler;
import dev.rndmorris.salisarcana.lib.ArrayHelper;
import dev.rndmorris.salisarcana.lib.IntegerHelper;
import dev.rndmorris.salisarcana.lib.ResearchHelper;
import thaumcraft.api.wands.FocusUpgradeType;
import thaumcraft.api.wands.ItemFocusBasic;

public class FociUpgradesHandler implements INamedArgumentHandler, IPositionalArgumentHandler {

public static final FociUpgradesHandler INSTANCE = new FociUpgradesHandler();

private static Map<FocusUpgradeType, String> upgradesToKeys;
private static Map<String, FocusUpgradeType> keysToUpgrades;

private static Map<FocusUpgradeType, String> upgradesToKeys() {
if (upgradesToKeys == null) {
upgradesToKeys = new TreeMap<>(Comparator.comparingInt(upgrade -> upgrade.id));
for (var index = 0; index < FocusUpgradeType.types.length; ++index) {
final var type = FocusUpgradeType.types[index];
final var cleanedName = type.getLocalizedName()
.toLowerCase()
.replaceAll(" +", "-")
.replaceAll("[^\\w-]", "");
// final var cleanedName = type.getLocalizedName().replaceAll();
final var key = String.format("%d-%s", index, cleanedName);
upgradesToKeys.put(type, key);
}
}
return upgradesToKeys;
}
public class FocusUpgradesHandler implements INamedArgumentHandler, IPositionalArgumentHandler {

private static Map<String, FocusUpgradeType> keysToUpgrades() {
if (keysToUpgrades == null) {
keysToUpgrades = new TreeMap<>(String::compareToIgnoreCase);
for (var entry : upgradesToKeys().entrySet()) {
keysToUpgrades.put(entry.getValue(), entry.getKey());
}
}
return keysToUpgrades;
}
public static final FocusUpgradesHandler INSTANCE = new FocusUpgradesHandler();

private final Map<Short, String> upgradeKeyCache = new TreeMap<>();

@Override
public Object parse(ICommandSender sender, PeekingIterator<String> args) {
final var resultList = new ArrayList<FocusUpgradeType>(5);
String peeked = null;
while (args.hasNext() && (peeked = args.peek()) != null && !peeked.startsWith("-")) {
final var key = args.next();
final var upgrade = keysToUpgrades().get(key);
final var upgrade = getUpgradeFromKey(key);
if (upgrade == null) {
throw new CommandException("salisarcana:error.invalid_focus_upgrade", key);
}
Expand All @@ -80,7 +56,9 @@ public List<String> getAutocompleteOptions(ICommandSender sender, PeekingIterato
ItemStack heldItem;
ItemFocusBasic heldFocus;
if ((heldItem = player.getCurrentEquippedItem()) == null || (heldFocus = getFocusFrom(heldItem)) == null) {
return new ArrayList<>(upgradesToKeys().values());
return Arrays.stream(FocusUpgradeType.types)
.map(this::formatUpgradeKey)
.collect(Collectors.toList());
}

// copied, so we can modify it as we work
Expand All @@ -96,7 +74,7 @@ public List<String> getAutocompleteOptions(ICommandSender sender, PeekingIterato
&& (peeked = args.peek()) != null
&& !peeked.startsWith("-")) {
final var key = args.next();
final var upgrade = keysToUpgrades().get(key);
final var upgrade = getUpgradeFromKey(key);
if (upgrade != null) {
appliedUpgrades.add(upgrade);
heldFocus.applyUpgrade(workingItem, upgrade, appliedUpgrades.size());
Expand All @@ -111,12 +89,12 @@ public List<String> getAutocompleteOptions(ICommandSender sender, PeekingIterato
if (possibleUpgrades == null) {
return null;
}
final var upgradeKeys = upgradesToKeys();

final var result = new ArrayList<String>(possibleUpgrades.length);
for (var upgrade : possibleUpgrades) {
if (heldFocus
.canApplyUpgrade(workingItem, ResearchHelper.knowItAll(), upgrade, appliedUpgrades.size() + 1)) {
result.add(upgradeKeys.get(upgrade));
result.add(formatUpgradeKey(upgrade));
}
}

Expand All @@ -129,4 +107,27 @@ public Class<?> getOutputType() {
return List.class;
}

private @Nonnull String formatUpgradeKey(@Nonnull FocusUpgradeType focusUpgrade) {
return upgradeKeyCache.computeIfAbsent(focusUpgrade.id, (id) -> {
final var cleanedName = focusUpgrade.getLocalizedName()
.toLowerCase()
.replaceAll(" +", "-")
.replaceAll("[^\\w-]", "");
return String.format("%s-%d", cleanedName, focusUpgrade.id);
});
}

private @Nullable FocusUpgradeType getUpgradeFromKey(@Nonnull String key) {
final var keyParts = key.split("-");
if (keyParts.length < 1) {
return null;
}
final var upgradeId = IntegerHelper.tryParse(keyParts[keyParts.length - 1]);
if (upgradeId == null) {
return null;
}
return ArrayHelper.tryGet(FocusUpgradeType.types, upgradeId)
.data();
}

}
11 changes: 6 additions & 5 deletions src/main/resources/assets/salisarcana/lang/en_US.lang
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ salisarcana:command.desc=Description:
salisarcana:command.usage=Usage:
salisarcana:command.args=Arguments:

salisarcana:command.error.tabcomplete=An error occurred while getting tab-completion suggestions. Please open a bug report, including your sever log, on the the Salis Arcana GitHub.
salisarcana:command.error.execute=An error occurred while executing this command. If this happens again, please open a bug report, including your sever log, on the the Salis Arcana GitHub.
salisarcana:command.error.tabcomplete=An error occurred while getting tab-completion suggestions. Please open a bug report, including your server log, on the the Salis Arcana GitHub.
salisarcana:command.error.execute=An error occurred while executing this command. If this happens again, please open a bug report, including your server log, on the the Salis Arcana GitHub.

salisarcana:command.create-node.desc=Create a new randomly-generated node at the specified coordinates.
salisarcana:command.create-node.usage=§7/salisarcana-create-node §7<x> §7<y> §7<z> §7[-t §7<type>] §7[-m §7<modifier>] §7[--silverwood] §7[--eerie] §7[--small] §7[-a §7<aspect1> §7<count1>[ §7-a §7<aspect2> §7<count2>[ §7...]]]§r
Expand Down Expand Up @@ -95,11 +95,12 @@ salisarcana:command.update-node.args.rem=§7§o[--rem <aspect> <count>]§r Remov
salisarcana:command.update-node.not_found=A node was not found at %d %d %d.

salisarcana:command.upgrade-focus.desc=Add focus upgrades your or another player's held wand focus. Will not apply upgrades beyond the focus's five-upgrade limit.
salisarcana:command.upgrade-focus.usage=§7/salisarcana-update-focus §7<upgrade[ §7upgrade[ §7...]]> §7[--player §7<username>]
salisarcana:command.upgrade-focus.args.upgrades=§7<upgrade-id>§r Required. A list of one or more upgrades to be applied.
salisarcana:command.upgrade-focus.usage=§7/salisarcana-upgrade-focus §7<upgrade[ §7upgrade[ §7...]]> §7[--player §7<username>]
salisarcana:command.upgrade-focus.args.upgrades=§7<upgrade>§r Required. A list of one to five upgrade ids to be applied. Upgrade ids have the form §7<internalId>-<name>§r. Use tab-completion to see available upgrade ids.
salisarcana:command.upgrade-focus.args.player=§7[--player]§r If set, apply upgrades to the specified player's held focus instead of your own.
salisarcana:command.upgrade-focus.noItem=Target player is not holding a wand focus.
salisarcana:command.upgrade-focus.tooManyUpgrades=%d upgrade(s) could not be applied due to the five-upgrade limit.
salisarcana:command.upgrade-focus.noUpgrades=No focus upgrades specified.
salisarcana:command.upgrade-focus.tooManyUpgrades=%d focus upgrade(s) could not be applied due to the five-upgrade limit.
salisarcana:command.upgrade-focus.success=All focus upgrades applied successfully.

salisarcana:error.invalid_aspect="%s" is not a known aspect.
Expand Down

0 comments on commit d8c3266

Please sign in to comment.