diff options
author | Anthony Hilyard <anthony.hilyard@gmail.com> | 2021-12-03 08:49:33 -0800 |
---|---|---|
committer | Anthony Hilyard <anthony.hilyard@gmail.com> | 2021-12-03 08:49:33 -0800 |
commit | 62d310bf8b3e559882d864f47de7828ea464d307 (patch) | |
tree | 8b7a5b51a1dd6883d698017a8d7c1e4b80444097 /src/main/java | |
parent | 45ba481ef75db5e0f9e09b8695da4a911da16fdb (diff) | |
download | Iceberg-62d310bf8b3e559882d864f47de7828ea464d307.tar.gz Iceberg-62d310bf8b3e559882d864f47de7828ea464d307.tar.bz2 Iceberg-62d310bf8b3e559882d864f47de7828ea464d307.zip |
Ported 1.0.27 update.
Diffstat (limited to 'src/main/java')
-rw-r--r-- | src/main/java/com/anthonyhilyard/iceberg/util/Selectors.java | 176 | ||||
-rw-r--r-- | src/main/java/com/anthonyhilyard/iceberg/util/Tooltips.java | 24 |
2 files changed, 193 insertions, 7 deletions
diff --git a/src/main/java/com/anthonyhilyard/iceberg/util/Selectors.java b/src/main/java/com/anthonyhilyard/iceberg/util/Selectors.java index 5fcaf41..af5c3af 100644 --- a/src/main/java/com/anthonyhilyard/iceberg/util/Selectors.java +++ b/src/main/java/com/anthonyhilyard/iceberg/util/Selectors.java @@ -5,9 +5,13 @@ import net.minecraft.world.item.ItemStack; import java.util.HashMap; import java.util.Map; +import java.util.function.BiPredicate; import java.util.List; import net.minecraft.client.Minecraft; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NumericTag; +import net.minecraft.nbt.Tag; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TextColor; import net.minecraft.resources.ResourceLocation; @@ -24,6 +28,100 @@ public class Selectors put("epic", Rarity.EPIC); }}; + private static Map<String, BiPredicate<Tag, String>> nbtComparators = new HashMap<String, BiPredicate<Tag, String>>() {{ + put("=", (tag, value) -> tag.getAsString().contentEquals(value)); + + put("!=", (tag, value) -> !tag.getAsString().contentEquals(value)); + + put(">", (tag, value) -> { + try + { + double parsedValue = Double.valueOf(value); + if (tag instanceof NumericTag) + { + return ((NumericTag)tag).getAsDouble() > parsedValue; + } + else + { + return false; + } + } + catch (Exception e) + { + return false; + } + }); + + put("<", (tag, value) -> { + try + { + double parsedValue = Double.valueOf(value); + if (tag instanceof NumericTag) + { + return ((NumericTag)tag).getAsDouble() < parsedValue; + } + else + { + return false; + } + } + catch (Exception e) + { + return false; + } + }); + }}; + + /** + * Returns true if this selector is syntactically valid. + * @param value The selector. + * @return True if the selector syntax is valid, false otherwise. + */ + public static boolean validateSelector(String value) + { + // This is a tag, which should be a resource location. + if (value.startsWith("$")) + { + return ResourceLocation.isValidResourceLocation(value.substring(1)); + } + // Mod IDs need to conform to this regex: ^[a-z][a-z0-9_-]{1,63}$ + else if (value.startsWith("@")) + { + return value.substring(1).matches("^[a-z][a-z0-9_-]{1,63}$"); + } + // If this is a rarity, make sure it's a valid one. + else if (value.startsWith("!")) + { + return rarities.keySet().contains(value.substring(1).toLowerCase()); + } + // If this is a hex color, ensure it's in a valid format. + else if (value.startsWith("#")) + { + return TextColor.parseColor(value) != null; + } + // Text matches are always considered valid. + else if (value.startsWith("%") || value.startsWith("^")) + { + return true; + } + // Any text is valid for NBT tag selectors. + else if (value.startsWith("&")) + { + return true; + } + // Otherwise it's an item, so just make sure it's a value resource location. + else + { + return value == null || value == "" || ResourceLocation.isValidResourceLocation(value); + } + } + + /** + * Returns true if the given item is matched by the given selector. + * @param item An ItemStack instance of an item to check. + * @param selector A selector string to check against. + * @return True if the item matches, false otherwise. + */ public static boolean itemMatches(ItemStack item, String selector) { String itemResourceLocation = Registry.ITEM.getKey(item.getItem()).toString(); @@ -36,7 +134,7 @@ public class Selectors else if (selector.startsWith("#")) { TextColor entryColor = TextColor.parseColor(selector); - if (entryColor.equals(ItemColor.getColorForItem(item, TextColor.fromRgb(0xFFFFFF)))) + if (entryColor != null && entryColor.equals(ItemColor.getColorForItem(item, TextColor.fromRgb(0xFFFFFF)))) { return true; } @@ -90,7 +188,81 @@ public class Selectors return true; } } + // NBT tag + else if (selector.startsWith("&")) + { + String tagName = selector.substring(1); + String tagValue = null; + BiPredicate<Tag, String> valueChecker = null; + + // This implementation means tag names containing and comparator strings can't be compared. + // Hopefully this isn't common. + for (String comparator : nbtComparators.keySet()) + { + if (tagName.contains(comparator)) + { + valueChecker = nbtComparators.get(comparator); + String[] components = tagName.split(comparator); + tagName = components[0]; + if (components.length > 1) + { + tagValue = components[1]; + } + break; + } + } + + // Look for a tag matching the given name. + Tag matchedTag = getSubtag(item.getTag(), tagName); + if (matchedTag != null) + { + // A tag value of null means that we are just looking for the presence of this tag. + if (tagValue == null) + { + return true; + } + // Otherwise, we will use the provided comparator. + else + { + if (valueChecker != null) + { + return valueChecker.test(matchedTag, tagValue); + } + } + } + } return false; } -} + + /** + * Retrieves the first inner tag with the given key, or null if there is no match. + */ + private static Tag getSubtag(CompoundTag tag, String key) + { + if (tag == null) + { + return null; + } + + if (tag.contains(key)) + { + return tag.get(key); + } + else + { + for (String innerKey : tag.getAllKeys()) + { + if (tag.getTagType(innerKey) == Tag.TAG_COMPOUND) + { + Tag innerTag = getSubtag(tag.getCompound(innerKey), key); + if (innerTag != null) + { + return innerTag; + } + } + } + return null; + } + } +}
\ No newline at end of file diff --git a/src/main/java/com/anthonyhilyard/iceberg/util/Tooltips.java b/src/main/java/com/anthonyhilyard/iceberg/util/Tooltips.java index 27d7c87..ec1dfc4 100644 --- a/src/main/java/com/anthonyhilyard/iceberg/util/Tooltips.java +++ b/src/main/java/com/anthonyhilyard/iceberg/util/Tooltips.java @@ -126,17 +126,24 @@ public class Tooltips initialized = true; } - public static void renderItemTooltip(final ItemStack stack, PoseStack mStack, TooltipInfo info, - Rect2i rect, int screenWidth, int screenHeight, - int backgroundColor, int borderColorStart, int borderColorEnd) + public static void renderItemTooltip(final ItemStack stack, PoseStack poseStack, TooltipInfo info, + Rect2i rect, int screenWidth, int screenHeight, + int backgroundColor, int borderColorStart, int borderColorEnd) { - renderItemTooltip(stack, mStack, info, rect, screenWidth, screenHeight, backgroundColor, borderColorStart, borderColorEnd, false); + renderItemTooltip(stack, poseStack, info, rect, screenWidth, screenHeight, backgroundColor, borderColorStart, borderColorEnd, false); } public static void renderItemTooltip(final ItemStack stack, PoseStack poseStack, TooltipInfo info, Rect2i rect, int screenWidth, int screenHeight, int backgroundColor, int borderColorStart, int borderColorEnd, boolean comparison) { + renderItemTooltip(stack, poseStack, info, rect, screenWidth, screenHeight, backgroundColor, borderColorStart, borderColorEnd, comparison, false); + } + + public static void renderItemTooltip(final ItemStack stack, PoseStack poseStack, TooltipInfo info, + Rect2i rect, int screenWidth, int screenHeight, + int backgroundColor, int borderColorStart, int borderColorEnd, boolean comparison, boolean constrain) + { // Initialize if needed. if (!initialized) { @@ -162,6 +169,13 @@ public class Tooltips int tooltipX = rectX + 12; int tooltipTextWidth = info.getMaxLineWidth(); + + // Constrain the minimum width to the rect. + if (constrain) + { + tooltipTextWidth = Math.max(info.getMaxLineWidth(), rect.getWidth() - 8); + } + if (tooltipX + tooltipTextWidth + 4 > screenWidth) { tooltipX = rectX - 16 - tooltipTextWidth; @@ -277,7 +291,7 @@ public class Tooltips RenderTooltipEvents.POST.invoker().onPost(stack, info.getLines(), poseStack, tooltipX, tooltipY, info.getFont(), tooltipTextWidth, tooltipHeight, comparison); } - public static Rect2i calculateRect(final ItemStack stack, PoseStack mStack, List<ClientTooltipComponent> textLines, int mouseX, int mouseY, + public static Rect2i calculateRect(final ItemStack stack, PoseStack poseStack, List<ClientTooltipComponent> textLines, int mouseX, int mouseY, int screenWidth, int screenHeight, int maxTextWidth, Font font) { Rect2i rect = new Rect2i(0, 0, 0, 0); |