aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormsg-programs <msgdoesstuff@gmail.com>2023-08-20 13:22:34 +0200
committermsg-programs <msgdoesstuff@gmail.com>2023-08-20 13:22:34 +0200
commite228eac03fbe10ea3ffd1c2e1930f33318a98c70 (patch)
treedd62c5462f865e919160a8fbb01129cf608b9f1c
parentbb2612feb2b86e94d23d02fbc3e66d5abeb6dd41 (diff)
parent6069d3cf7d2e96ca7ef1975a3dd04e2121a6e3c9 (diff)
downloadSkyblocker-e228eac03fbe10ea3ffd1c2e1930f33318a98c70.tar.gz
Skyblocker-e228eac03fbe10ea3ffd1c2e1930f33318a98c70.tar.bz2
Skyblocker-e228eac03fbe10ea3ffd1c2e1930f33318a98c70.zip
Merge branch 'master' of https://github.com/SkyblockerMod/Skyblocker into json-tabhud
Pull newest changes from upstream
-rw-r--r--.github/workflows/buildrelease.yml32
-rw-r--r--CHANGELOG.md15
-rw-r--r--FEATURES.md6
-rw-r--r--README.md21
-rw-r--r--gradle.properties2
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java2
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java26
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/mixin/ArmorTrimMixin.java37
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/DungeonBlaze.java80
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CustomArmorDyeColors.java13
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CustomArmorTrims.java147
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CustomItemNames.java16
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/utils/RenderHelper.java69
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/utils/RenderUtils.java2
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/utils/Utils.java4
-rw-r--r--src/main/resources/assets/skyblocker/lang/en_us.json11
-rw-r--r--src/main/resources/skyblocker.mixins.json1
-rw-r--r--src/test/java/me/xmrvizzy/skyblocker/skyblock/item/ArmorTrimIdSerializationTest.java27
18 files changed, 439 insertions, 72 deletions
diff --git a/.github/workflows/buildrelease.yml b/.github/workflows/buildrelease.yml
index 2428e2b5..fde5785b 100644
--- a/.github/workflows/buildrelease.yml
+++ b/.github/workflows/buildrelease.yml
@@ -82,7 +82,7 @@ jobs:
' ORS='\n' <<< "$changelog")
# Format the modified_changelog by removing "@" characters and enclosing URLs in "<>"
- modified_changelog=$(echo "$modified_changelog" | sed -e 's/@//g' -e 's|https\?://[^[:space:]]*|<\0>|g')
+ # modified_changelog=$(echo "$modified_changelog" | sed -e 's/@//g' -e 's|https\?://[^[:space:]]*|<\0>|g')
# Store the modified_changelog in the CHANGELOG variable
CHANGELOG=$(echo -n "$modified_changelog")
@@ -124,18 +124,18 @@ jobs:
echo "::set-output name=value::${GITHUB_REF#refs/tags/}"
- name: Discord notification
- env:
- DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
- uses: Ilshidur/action-discord@master
- with:
- args: |
- "<@&1134565945482948638>"
- "## Skyblocker ${{ steps.version_tag.outputs.value }}"
- ""
- "${{ steps.read_changelog.outputs.changelog_discord }}"
- ""
- ":inbox_tray: Download latest version on Modrinth or Github:"
- "<:modrinth:900697862206287882> <${{ steps.modrinth.outputs.url }}>"
- "<:github:900697885706952725> <${{ steps.uploadrelease.outputs.url }}>"
- ""
- "<https://hysky.de/>"
+ shell: bash
+ run: |
+ OUTPUT="
+ <@&1134565945482948638>
+ ## Skyblocker ${{ steps.version_tag.outputs.value }}
+
+ ${{ steps.read_changelog.outputs.changelog_discord }}
+
+ :inbox_tray: Download latest version on Modrinth or Github:
+ <:modrinth:900697862206287882> ${{ steps.modrinth.outputs.url }}
+ <:github:900697885706952725> ${{ steps.uploadrelease.outputs.url }}
+
+ https://hysky.de/"
+
+ curl -H "Content-Type: application/json" -d '{"content":"'"${OUTPUT//$'\n'/\\n}"'", "flags": 4}' "${{ secrets.DISCORD_WEBHOOK }}" \ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 25b1d12e..876a18e0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,18 @@
+# Release 1.12.0
+
+## Highlight
+* Item and Armour customisation, see [#commands](https://github.com/SkyblockerMod/Skyblocker#commands) for more details by @AzureAaron
+
+## What's Changed
+* Add Item Renaming & Custom Armour Dye Colours by @AzureAaron in https://github.com/SkyblockerMod/Skyblocker/pull/234
+* Separate commands sent by skyblocker from the chat history by @AzureAaron in https://github.com/SkyblockerMod/Skyblocker/pull/235
+* Make IF a conflict by @Julienraptor01 in https://github.com/SkyblockerMod/Skyblocker/pull/237
+* Custom Armour Trims by @AzureAaron in https://github.com/SkyblockerMod/Skyblocker/pull/238
+* Lowercased server ip by @AzureAaron in https://github.com/SkyblockerMod/Skyblocker/pull/244
+
+
+**Full Changelog**: https://github.com/SkyblockerMod/Skyblocker/compare/v1.11.1...v1.12.0
+___
# Release 1.11.1
## Highlight
diff --git a/FEATURES.md b/FEATURES.md
index b80da7fa..44525a4f 100644
--- a/FEATURES.md
+++ b/FEATURES.md
@@ -31,4 +31,8 @@
* Custom Tab HUD
* Roughly enough items (REI) Support
* Fishing Helper + sound notification
-* Mirrorverse Waypoints \ No newline at end of file
+* Mirrorverse Waypoints
+* Item and Armour customisation:
+ * Item Renaming
+ * Custom Armour Dye Colours
+ * Custom Armour Trims \ No newline at end of file
diff --git a/README.md b/README.md
index bf792cbe..38d1e129 100644
--- a/README.md
+++ b/README.md
@@ -7,11 +7,11 @@
[![Build Beta](https://img.shields.io/github/actions/workflow/status/SkyblockerMod/Skyblocker/beta.yml?labelColor=cecece&label=beta&logo=github&logoColor=black)](https://github.com/SkyblockerMod/Skyblocker/actions/workflows/beta.yml)
[![Discord](https://img.shields.io/discord/879732108745125969?logo=discord&labelColor=cecece&color=7289DA&label=)](https://discord.com/invite/aNNJHQykck)
[![modrinth statistic](https://img.shields.io/badge/buy%20me%20coffee-skyblocker?color=434B57&logo=kofi)](https://ko-fi.com/wohlhabend)
+[![Translated](https://translate.hysky.de/widgets/Skyblocker/-/skyblocker/svg-badge.svg)](https://translate.hysky.de/projects/Skyblocker/skyblocker/)
Hypixel Skyblock Mod for Minecraft 1.17.x + 1.18.x + 1.19.x + 1.20.x
-Installation guide is [here](https://github.com/SkyblockerMod/Skyblocker/wiki/installation)
-
+Installation guide is [here](https://github.com/SkyblockerMod/Skyblocker/wiki/installation) or use our [Modpack](https://modrinth.com/modpack/skyblocker-modpack)
## Features
<details open>
@@ -51,6 +51,10 @@ Installation guide is [here](https://github.com/SkyblockerMod/Skyblocker/wiki/in
* Roughly enough items (REI) Support
* Fishing Helper + sound notification
* Mirrorverse Waypoints
+* Item and Armour customisation:
+ * Item Renaming
+ * Custom Armour Dye Colours
+ * Custom Armour Trims
</details>
@@ -58,12 +62,13 @@ ___
## Commands
-| command | option | comment |
-|:---------------------:|:-----------------------:|:-------------------------------------------|
-| /skyblocker config | | open config menu (modMenu not needed) |
-| /skyblocker options | | open config menu (modMenu not needed) |
+| command | option | comment |
+|:---------------------:|:-------------------------------------:|:-------------------------------------------|
+| /skyblocker config | | open config menu (modMenu not needed) |
+| /skyblocker options | | open config menu (modMenu not needed) |
| /skyblocker hud | dwarven / dungeonmap / titleContainer | move dwarven, dungeonmap or titleContainer |
-| /skyblocker shortcuts | | add/edit shortcuts |
+| /skyblocker shortcuts | | add/edit shortcuts |
+| /skyblocker custom | renameItem / armorTrim / dyeColor | Item and Armour customisation |
---
@@ -80,7 +85,7 @@ ___
<img padding="10px,0px" height="150" src="https://hysky.de/richpresencesmall.png" />
<img padding="10px,0px" height="150" src="https://hysky.de/recipe.png" />
<img padding="10px,0px" height="150" src="https://hysky.de/backpack-preview.png" />
-
+<img padding="10px,0px" height="150" src="https://hysky.de/armour_trim.png" />
</details>
## Contribute
diff --git a/gradle.properties b/gradle.properties
index a84834ec..8db62203 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -28,7 +28,7 @@ betterinject_version=0.1.3
occlusionculling_version = 0.0.7-SNAPSHOT
# Mod Properties
-mod_version = 1.11.1
+mod_version = 1.12.0
maven_group = me.xmrvizzy
archives_base_name = skyblocker
modrinth_id=y6DuFGwJ \ No newline at end of file
diff --git a/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java b/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java
index 8c09f5b1..fe05e793 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java
@@ -12,6 +12,7 @@ import me.xmrvizzy.skyblocker.skyblock.dungeon.DungeonMap;
import me.xmrvizzy.skyblocker.skyblock.dungeon.LividColor;
import me.xmrvizzy.skyblocker.skyblock.dwarven.DwarvenHud;
import me.xmrvizzy.skyblocker.skyblock.item.CustomArmorDyeColors;
+import me.xmrvizzy.skyblocker.skyblock.item.CustomArmorTrims;
import me.xmrvizzy.skyblocker.skyblock.item.CustomItemNames;
import me.xmrvizzy.skyblocker.skyblock.item.PriceInfoTooltip;
import me.xmrvizzy.skyblocker.skyblock.item.WikiLookup;
@@ -94,6 +95,7 @@ public class SkyblockerMod implements ClientModInitializer {
TeleportOverlay.init();
CustomItemNames.init();
CustomArmorDyeColors.init();
+ CustomArmorTrims.init();
containerSolverManager.init();
scheduler.scheduleCyclic(Utils::update, 20);
scheduler.scheduleCyclic(DiscordRPCManager::updateDataAndPresence, 100);
diff --git a/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java b/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java
index 5110b181..104c9c7a 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java
@@ -1,11 +1,10 @@
package me.xmrvizzy.skyblocker.config;
-import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
-import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
-
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
+import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
+import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import me.shedaniel.autoconfig.AutoConfig;
import me.shedaniel.autoconfig.ConfigData;
import me.shedaniel.autoconfig.annotation.Config;
@@ -14,12 +13,14 @@ import me.shedaniel.autoconfig.serializer.ConfigSerializer;
import me.shedaniel.autoconfig.serializer.GsonConfigSerializer;
import me.xmrvizzy.skyblocker.SkyblockerMod;
import me.xmrvizzy.skyblocker.chat.ChatFilterResult;
+import me.xmrvizzy.skyblocker.skyblock.item.CustomArmorTrims;
import me.xmrvizzy.skyblocker.utils.Scheduler;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.text.Style;
import net.minecraft.text.Text;
+import net.minecraft.util.Identifier;
import java.util.ArrayList;
import java.util.List;
@@ -196,10 +197,15 @@ public class SkyblockerConfig implements ConfigData {
@ConfigEntry.Gui.Excluded
public List<Integer> lockedSlots = new ArrayList<>();
-
+
+ @ConfigEntry.Gui.Excluded
public Object2ObjectOpenHashMap<String, Text> customItemNames = new Object2ObjectOpenHashMap<>();
-
+
+ @ConfigEntry.Gui.Excluded
public Object2IntOpenHashMap<String> customDyeColors = new Object2IntOpenHashMap<>();
+
+ @ConfigEntry.Gui.Excluded
+ public Object2ObjectOpenHashMap<String, CustomArmorTrims.ArmorTrimId> customArmorTrims = new Object2ObjectOpenHashMap<>();
}
public static class TabHudConf {
@@ -216,7 +222,7 @@ public class SkyblockerConfig implements ConfigData {
}
public enum NameSorting {
- DEFAULT,
+ DEFAULT,
ALPHABETICAL;
@Override
@@ -408,6 +414,7 @@ public class SkyblockerConfig implements ConfigData {
public int mapX = 2;
public int mapY = 2;
public boolean solveThreeWeirdos = true;
+ @ConfigEntry.Gui.Tooltip
public boolean blazesolver = true;
public boolean solveTrivia = true;
@ConfigEntry.Gui.CollapsibleObject
@@ -548,10 +555,11 @@ public class SkyblockerConfig implements ConfigData {
.setPrettyPrinting()
.registerTypeHierarchyAdapter(Text.class, new Text.Serializer())
.registerTypeHierarchyAdapter(Style.class, new Style.Serializer())
+ .registerTypeHierarchyAdapter(Identifier.class, new Identifier.Serializer())
.create();
-
+
ConfigSerializer.Factory<SkyblockerConfig> serializer = (cfg, cfgClass) -> new GsonConfigSerializer<>(cfg, cfgClass, gson);
-
+
AutoConfig.register(SkyblockerConfig.class, serializer);
ClientCommandRegistrationCallback.EVENT.register(((dispatcher, registryAccess) -> dispatcher.register(literal(SkyblockerMod.NAMESPACE).then(optionsLiteral("config")).then(optionsLiteral("options")))));
}
@@ -570,7 +578,7 @@ public class SkyblockerConfig implements ConfigData {
public static SkyblockerConfig get() {
return AutoConfig.getConfigHolder(SkyblockerConfig.class).getConfig();
}
-
+
public static void save() {
AutoConfig.getConfigHolder(SkyblockerConfig.class).save();
}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/ArmorTrimMixin.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/ArmorTrimMixin.java
new file mode 100644
index 00000000..a90cf4d4
--- /dev/null
+++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/ArmorTrimMixin.java
@@ -0,0 +1,37 @@
+package me.xmrvizzy.skyblocker.mixin;
+
+import com.llamalad7.mixinextras.injector.ModifyReturnValue;
+import com.llamalad7.mixinextras.sugar.Local;
+import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
+import me.xmrvizzy.skyblocker.config.SkyblockerConfig;
+import me.xmrvizzy.skyblocker.skyblock.item.CustomArmorTrims;
+import me.xmrvizzy.skyblocker.utils.Utils;
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.trim.ArmorTrim;
+import net.minecraft.nbt.NbtCompound;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+
+import java.util.Optional;
+
+@Mixin(ArmorTrim.class)
+public class ArmorTrimMixin {
+
+ @ModifyReturnValue(method = "getTrim", at = @At("RETURN"))
+ private static Optional<ArmorTrim> skyblocker$customArmorTrims(@SuppressWarnings("OptionalUsedAsFieldOrParameterType") Optional<ArmorTrim> original, @Local ItemStack stack) {
+ NbtCompound nbt = stack.getNbt();
+
+ if (Utils.isOnSkyblock() && nbt != null && nbt.contains("ExtraAttributes")) {
+ Object2ObjectOpenHashMap<String, CustomArmorTrims.ArmorTrimId> customTrims = SkyblockerConfig.get().general.customArmorTrims;
+ NbtCompound extraAttributes = nbt.getCompound("ExtraAttributes");
+ String itemUuid = extraAttributes.contains("uuid") ? extraAttributes.getString("uuid") : null;
+
+ if (customTrims.containsKey(itemUuid)) {
+ CustomArmorTrims.ArmorTrimId trimKey = customTrims.get(itemUuid);
+ return CustomArmorTrims.TRIMS_CACHE.getOrDefault(trimKey, original);
+ }
+ }
+
+ return original;
+ }
+}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/DungeonBlaze.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/DungeonBlaze.java
index 219f4258..d0dcf1e1 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/DungeonBlaze.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/DungeonBlaze.java
@@ -1,79 +1,111 @@
package me.xmrvizzy.skyblocker.skyblock.dungeon;
+import it.unimi.dsi.fastutil.objects.ObjectIntPair;
import me.xmrvizzy.skyblocker.config.SkyblockerConfig;
+import me.xmrvizzy.skyblocker.utils.RenderHelper;
+import me.xmrvizzy.skyblocker.utils.RenderUtils;
import me.xmrvizzy.skyblocker.utils.Utils;
import me.xmrvizzy.skyblocker.utils.color.QuadColor;
-import me.xmrvizzy.skyblocker.utils.RenderUtils;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.Box;
+import net.minecraft.util.math.Vec3d;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+
public class DungeonBlaze {
private static final Logger LOGGER = LoggerFactory.getLogger(DungeonBlaze.class.getName());
+ private static final float[] WHITE_COLOR_COMPONENTS = { 1.0f, 1.0f, 1.0f };
static Entity highestBlaze = null;
static Entity lowestBlaze = null;
+ static Entity nextHighestBlaze = null;
+ static Entity nextLowestBlaze = null;
static boolean renderHooked = false;
public static void update() {
ClientWorld world = MinecraftClient.getInstance().world;
if (world == null || !Utils.isInDungeons()) return;
- if(!renderHooked){
+ if (!renderHooked){
- WorldRenderEvents.END.register(DungeonBlaze::blazeRenderer);
+ WorldRenderEvents.BEFORE_DEBUG_RENDER.register(DungeonBlaze::blazeRenderer);
renderHooked = true;
}
Iterable<Entity> entities = world.getEntities();
- int highestHealth = 0;
- int lowestHealth = 99999999;
+ List<ObjectIntPair<Entity>> blazes = new ArrayList<>();
for (Entity entity : entities) {
- if (entity.getName().getString().contains("Blaze") && entity.getName().getString().contains("/")) {
-
- String blazeName = entity.getName().getString();
+ String blazeName = entity.getName().getString();
+
+ if (blazeName.contains("Blaze") && blazeName.contains("/")) {
try {
-
int health = Integer.parseInt(blazeName.substring(blazeName.indexOf("/") + 1, blazeName.length() - 1));
-
- if (health > highestHealth) {
- highestHealth = health;
-
- highestBlaze = entity;
-
- }
- if (health < lowestHealth) {
- lowestHealth = health;
- lowestBlaze = entity;
- }
+
+ blazes.add(ObjectIntPair.of(entity, health));
} catch (NumberFormatException ex) {
ex.printStackTrace();
}
}
}
+
+ // Order the blazes in the list from the lowest health to the highest health
+ blazes.sort(Comparator.comparingInt(ObjectIntPair::rightInt));
+
+ // Ensure that there are blazes in the list
+ if (!blazes.isEmpty()) {
+ lowestBlaze = blazes.get(0).left();
+
+ int highestIndex = blazes.size() - 1;
+ highestBlaze = blazes.get(highestIndex).left();
+
+ // If there's more than 1 blaze
+ if (blazes.size() > 1) {
+ nextLowestBlaze = blazes.get(1).left();
+ nextHighestBlaze = blazes.get(highestIndex - 1).left();
+ }
+ }
+
}
public static void blazeRenderer(WorldRenderContext wrc) {
QuadColor outlineColorRed = QuadColor.single( 0.0F, 1.0F, 0.0F, 1f);
QuadColor outlineColorGreen = QuadColor.single(1.0F, 0.0F, 0.0F, 1f);
+ QuadColor outlineColorWhite = QuadColor.single(1.0f, 1.0f, 1.0f, 1.0f);
+
try {
- if(highestBlaze != null && lowestBlaze != null && highestBlaze.isAlive() && lowestBlaze.isAlive() && SkyblockerConfig.get().locations.dungeons.blazesolver){
+ if (highestBlaze != null && lowestBlaze != null && highestBlaze.isAlive() && lowestBlaze.isAlive() && SkyblockerConfig.get().locations.dungeons.blazesolver){
/* Outline */
- if(highestBlaze.getY() <69) {
+ if (highestBlaze.getY() < 69) {
Box blaze = highestBlaze.getBoundingBox().expand(0.3, 0.9, 0.3).offset(0, -1.1, 0);
RenderUtils.drawBoxOutline(blaze, outlineColorRed, 5f);
+
+ if (nextHighestBlaze != null && nextHighestBlaze.isAlive() && nextHighestBlaze != highestBlaze) {
+ Box nextBlaze = nextHighestBlaze.getBoundingBox().expand(0.3, 0.9, 0.3).offset(0, -1.1, 0);
+ RenderUtils.drawBoxOutline(nextBlaze, outlineColorWhite, 5f);
+ RenderHelper.renderLinesFromPoints(wrc, new Vec3d[] { blaze.getCenter(), nextBlaze.getCenter() }, WHITE_COLOR_COMPONENTS, 1f, 5f);
+ }
}
/* Outline */
- if(lowestBlaze.getY() >69) {
+ if (lowestBlaze.getY() > 69) {
Box blaze = lowestBlaze.getBoundingBox().expand(0.3, 0.9, 0.3).offset(0, -1.1, 0);
RenderUtils.drawBoxOutline(blaze, outlineColorRed, 5f);
+
+ if (nextLowestBlaze != null && nextLowestBlaze.isAlive() && nextLowestBlaze != lowestBlaze) {
+ Box nextBlaze = nextLowestBlaze.getBoundingBox().expand(0.3, 0.9, 0.3).offset(0, -1.1, 0);
+ RenderUtils.drawBoxOutline(nextBlaze, outlineColorWhite, 5f);
+ RenderHelper.renderLinesFromPoints(wrc, new Vec3d[] { blaze.getCenter(), nextBlaze.getCenter() }, WHITE_COLOR_COMPONENTS, 1f, 5f);
+ }
}
}
- }catch(Exception e) {
+ } catch (Exception e) {
LOGGER.warn("[Skyblocker BlazeRenderer] " + e);
+ e.printStackTrace();
}
}
} \ No newline at end of file
diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CustomArmorDyeColors.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CustomArmorDyeColors.java
index 9385b4a1..7c4ed423 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CustomArmorDyeColors.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CustomArmorDyeColors.java
@@ -10,7 +10,7 @@ import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.minecraft.command.CommandRegistryAccess;
-import net.minecraft.item.DyeableArmorItem;
+import net.minecraft.item.DyeableItem;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.text.Text;
@@ -22,10 +22,11 @@ public class CustomArmorDyeColors {
private static void registerCommands(CommandDispatcher<FabricClientCommandSource> dispatcher, CommandRegistryAccess registryAccess) {
dispatcher.register(ClientCommandManager.literal("skyblocker")
- .then(ClientCommandManager.literal("dyeColor")
- .executes(context -> customizeDyeColor(context.getSource(), null))
- .then(ClientCommandManager.argument("hexCode", StringArgumentType.string())
- .executes(context -> customizeDyeColor(context.getSource(), StringArgumentType.getString(context, "hexCode"))))));
+ .then(ClientCommandManager.literal("custom")
+ .then(ClientCommandManager.literal("dyeColor")
+ .executes(context -> customizeDyeColor(context.getSource(), null))
+ .then(ClientCommandManager.argument("hexCode", StringArgumentType.string())
+ .executes(context -> customizeDyeColor(context.getSource(), StringArgumentType.getString(context, "hexCode")))))));
}
@SuppressWarnings("SameReturnValue")
@@ -39,7 +40,7 @@ public class CustomArmorDyeColors {
}
if (Utils.isOnSkyblock() && heldItem != null) {
- if (heldItem.getItem() instanceof DyeableArmorItem) {
+ if (heldItem.getItem() instanceof DyeableItem) {
if (nbt != null && nbt.contains("ExtraAttributes")) {
NbtCompound extraAttributes = nbt.getCompound("ExtraAttributes");
String itemUuid = extraAttributes.contains("uuid") ? extraAttributes.getString("uuid") : null;
diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CustomArmorTrims.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CustomArmorTrims.java
new file mode 100644
index 00000000..ffc3f67d
--- /dev/null
+++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CustomArmorTrims.java
@@ -0,0 +1,147 @@
+package me.xmrvizzy.skyblocker.skyblock.item;
+
+import com.mojang.brigadier.Command;
+import com.mojang.brigadier.CommandDispatcher;
+import com.mojang.brigadier.suggestion.SuggestionProvider;
+import it.unimi.dsi.fastutil.Pair;
+import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
+import me.xmrvizzy.skyblocker.config.SkyblockerConfig;
+import me.xmrvizzy.skyblocker.utils.SkyblockEvents;
+import me.xmrvizzy.skyblocker.utils.Utils;
+import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager;
+import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
+import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.network.ClientPlayerEntity;
+import net.minecraft.command.CommandRegistryAccess;
+import net.minecraft.command.CommandSource;
+import net.minecraft.command.argument.IdentifierArgumentType;
+import net.minecraft.item.ArmorItem;
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.trim.ArmorTrim;
+import net.minecraft.nbt.NbtCompound;
+import net.minecraft.nbt.NbtOps;
+import net.minecraft.registry.*;
+import net.minecraft.text.Text;
+import net.minecraft.util.Identifier;
+import org.jetbrains.annotations.NotNull;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Optional;
+
+public class CustomArmorTrims {
+ private static final Logger LOGGER = LoggerFactory.getLogger(CustomArmorTrims.class);
+ public static final Object2ObjectOpenHashMap<ArmorTrimId, Optional<ArmorTrim>> TRIMS_CACHE = new Object2ObjectOpenHashMap<>();
+ private static boolean trimsInitialized = false;
+
+ public static void init() {
+ SkyblockEvents.JOIN.register(CustomArmorTrims::initializeTrimCache);
+ ClientCommandRegistrationCallback.EVENT.register(CustomArmorTrims::registerCommand);
+ }
+
+ private static void initializeTrimCache() {
+ ClientPlayerEntity player = MinecraftClient.getInstance().player;
+ if (!trimsInitialized && player != null) {
+ TRIMS_CACHE.clear();
+ DynamicRegistryManager registryManager = player.networkHandler.getRegistryManager();
+ for (Identifier material : registryManager.get(RegistryKeys.TRIM_MATERIAL).getIds()) {
+ for (Identifier pattern : registryManager.get(RegistryKeys.TRIM_PATTERN).getIds()) {
+ NbtCompound compound = new NbtCompound();
+ compound.putString("material", material.toString());
+ compound.putString("pattern", pattern.toString());
+
+ ArmorTrim trim = ArmorTrim.CODEC.parse(RegistryOps.of(NbtOps.INSTANCE, registryManager), compound).resultOrPartial(LOGGER::error).orElse(null);
+
+ // Something went terribly wrong
+ if (trim == null) throw new IllegalStateException("Trim shouldn't be null! [" + "\"" + material + "\",\"" + pattern + "\"]");
+
+ TRIMS_CACHE.put(new ArmorTrimId(material, pattern), Optional.of(trim));
+ }
+ }
+
+ LOGGER.info("[Skyblocker] Successfully cached all armor trims!");
+ trimsInitialized = true;
+ }
+ }
+
+ private static void registerCommand(CommandDispatcher<FabricClientCommandSource> dispatcher, CommandRegistryAccess registryAccess) {
+ dispatcher.register(ClientCommandManager.literal("skyblocker")
+ .then(ClientCommandManager.literal("custom")
+ .then(ClientCommandManager.literal("armorTrim")
+ .executes(context -> customizeTrim(context.getSource(), null, null))
+ .then(ClientCommandManager.argument("material", IdentifierArgumentType.identifier())
+ .suggests(getIdSuggestionProvider(RegistryKeys.TRIM_MATERIAL))
+ .executes(context -> customizeTrim(context.getSource(), context.getArgument("material", Identifier.class), null))
+ .then(ClientCommandManager.argument("pattern", IdentifierArgumentType.identifier())
+ .suggests(getIdSuggestionProvider(RegistryKeys.TRIM_PATTERN))
+ .executes(context -> customizeTrim(context.getSource(), context.getArgument("material", Identifier.class), context.getArgument("pattern", Identifier.class))))))));
+ }
+
+ @NotNull
+ private static SuggestionProvider<FabricClientCommandSource> getIdSuggestionProvider(RegistryKey<? extends Registry<?>> registryKey) {
+ return (context, builder) -> context.getSource().listIdSuggestions(registryKey, CommandSource.SuggestedIdType.ELEMENTS, builder, context);
+ }
+
+ @SuppressWarnings("SameReturnValue")
+ private static int customizeTrim(FabricClientCommandSource source, Identifier material, Identifier pattern) {
+ ItemStack heldItem = source.getPlayer().getMainHandStack();
+ NbtCompound nbt = (heldItem != null) ? heldItem.getNbt() : null;
+
+ if (Utils.isOnSkyblock() && heldItem != null) {
+ if (heldItem.getItem() instanceof ArmorItem) {
+ if (nbt != null && nbt.contains("ExtraAttributes")) {
+ NbtCompound extraAttributes = nbt.getCompound("ExtraAttributes");
+ String itemUuid = extraAttributes.contains("uuid") ? extraAttributes.getString("uuid") : null;
+
+ if (itemUuid != null) {
+ Object2ObjectOpenHashMap<String, ArmorTrimId> customArmorTrims = SkyblockerConfig.get().general.customArmorTrims;
+
+ if (material == null && pattern == null) {
+ if (customArmorTrims.containsKey(itemUuid)) {
+ customArmorTrims.remove(itemUuid);
+ SkyblockerConfig.save();
+ source.sendFeedback(Text.translatable("skyblocker.customArmorTrims.removed"));
+ } else {
+ source.sendFeedback(Text.translatable("skyblocker.customArmorTrims.neverHad"));
+ }
+ } else {
+ // Ensure that the material & trim are valid
+ ArmorTrimId trimId = new ArmorTrimId(material, pattern);
+ if (TRIMS_CACHE.get(trimId) == null) {
+ source.sendError(Text.translatable("skyblocker.customArmorTrims.invalidMaterialOrPattern"));
+
+ return Command.SINGLE_SUCCESS;
+ }
+
+ customArmorTrims.put(itemUuid, trimId);
+ SkyblockerConfig.save();
+ source.sendFeedback(Text.translatable("skyblocker.customArmorTrims.added"));
+ }
+ } else {
+ source.sendError(Text.translatable("skyblocker.customArmorTrims.noItemUuid"));
+ }
+ }
+ } else {
+ source.sendError(Text.translatable("skyblocker.customArmorTrims.notAnArmorPiece"));
+ return Command.SINGLE_SUCCESS;
+ }
+ } else {
+ source.sendError(Text.translatable("skyblocker.customArmorTrims.unableToSetTrim"));
+ }
+
+ return Command.SINGLE_SUCCESS;
+ }
+
+ public record ArmorTrimId(Identifier material, Identifier pattern) implements Pair<Identifier, Identifier> {
+ @Override
+ public Identifier left() {
+ return material();
+ }
+
+ @Override
+ public Identifier right() {
+ return pattern();
+ }
+ }
+}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CustomItemNames.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CustomItemNames.java
index 5d410947..c744144a 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CustomItemNames.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CustomItemNames.java
@@ -12,6 +12,8 @@ import net.minecraft.command.CommandRegistryAccess;
import net.minecraft.command.argument.TextArgumentType;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
+import net.minecraft.text.MutableText;
+import net.minecraft.text.Style;
import net.minecraft.text.Text;
public class CustomItemNames {
@@ -21,10 +23,11 @@ public class CustomItemNames {
private static void registerCommands(CommandDispatcher<FabricClientCommandSource> dispatcher, CommandRegistryAccess registryAccess) {
dispatcher.register(ClientCommandManager.literal("skyblocker")
- .then(ClientCommandManager.literal("renameItem")
- .executes(context -> renameItem(context.getSource(), null))
- .then(ClientCommandManager.argument("textComponent", TextArgumentType.text())
- .executes(context -> renameItem(context.getSource(), context.getArgument("textComponent", Text.class))))));
+ .then(ClientCommandManager.literal("custom")
+ .then(ClientCommandManager.literal("renameItem")
+ .executes(context -> renameItem(context.getSource(), null))
+ .then(ClientCommandManager.argument("textComponent", TextArgumentType.text())
+ .executes(context -> renameItem(context.getSource(), context.getArgument("textComponent", Text.class)))))));
}
@SuppressWarnings("SameReturnValue")
@@ -50,6 +53,11 @@ public class CustomItemNames {
}
} else {
//If the text is provided then set the item's custom name to it
+
+ //Set italic to false if it hasn't been changed (or was already false)
+ Style currentStyle = text.getStyle();
+ ((MutableText) text).setStyle(currentStyle.withItalic((currentStyle.isItalic() ? true : false)));
+
customItemNames.put(itemUuid, text);
SkyblockerConfig.save();
source.sendFeedback(Text.translatable("skyblocker.customItemNames.added"));
diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/RenderHelper.java b/src/main/java/me/xmrvizzy/skyblocker/utils/RenderHelper.java
index a1221549..8f0f7860 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/utils/RenderHelper.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/utils/RenderHelper.java
@@ -9,8 +9,11 @@ import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.Camera;
+import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.render.Tessellator;
import net.minecraft.client.render.VertexConsumerProvider;
+import net.minecraft.client.render.VertexFormats;
+import net.minecraft.client.render.VertexFormat.DrawMode;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.sound.SoundEvent;
import net.minecraft.text.Text;
@@ -20,6 +23,13 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import java.awt.*;
+import org.joml.Matrix3f;
+import org.joml.Matrix4f;
+import org.joml.Vector3f;
+import org.lwjgl.opengl.GL11;
+
+import com.mojang.blaze3d.platform.GlStateManager.DstFactor;
+import com.mojang.blaze3d.platform.GlStateManager.SrcFactor;
import com.mojang.blaze3d.systems.RenderSystem;
public class RenderHelper {
@@ -67,6 +77,65 @@ public class RenderHelper {
matrices.pop();
}
}
+
+ /**
+ * Draws lines from point to point.<br><br>
+ *
+ * Tip: To draw lines from the center of a block, offset the X, Y and Z each by 0.5
+ *
+ * @param context The WorldRenderContext which supplies the matrices and tick delta
+ * @param points The points from which to draw lines between
+ * @param colorComponents An array of R, G and B color components
+ * @param alpha The alpha of the lines
+ * @param lineWidth The width of the lines
+ */
+ public static void renderLinesFromPoints(WorldRenderContext context, Vec3d[] points, float[] colorComponents, float alpha, float lineWidth) {
+ Vec3d camera = context.camera().getPos();
+ MatrixStack matrices = context.matrixStack();
+
+ matrices.push();
+ matrices.translate(-camera.x, -camera.y, -camera.z);
+
+ Tessellator tessellator = RenderSystem.renderThreadTesselator();
+ BufferBuilder buffer = tessellator.getBuffer();
+ Matrix4f projectionMatrix = matrices.peek().getPositionMatrix();
+ Matrix3f normalMatrix = matrices.peek().getNormalMatrix();
+
+ GL11.glEnable(GL11.GL_LINE_SMOOTH);
+ GL11.glHint(GL11.GL_LINE_SMOOTH_HINT, GL11.GL_NICEST);
+
+ RenderSystem.setShader(GameRenderer::getRenderTypeLinesProgram);
+ RenderSystem.setShaderColor(1f, 1f, 1f, 1f);
+ RenderSystem.lineWidth(lineWidth);
+ RenderSystem.enableBlend();
+ RenderSystem.blendFunc(SrcFactor.SRC_ALPHA, DstFactor.ONE_MINUS_SRC_ALPHA);
+ RenderSystem.disableCull();
+ RenderSystem.enableDepthTest();
+
+ buffer.begin(DrawMode.LINE_STRIP, VertexFormats.LINES);
+
+ for (int i = 0; i < points.length; i++) {
+ Vec3d point = points[i];
+ Vec3d nextPoint = (i + 1 == points.length) ? points[i - 1] : points[i + 1];
+ Vector3f normalVec = new Vector3f((float) nextPoint.getX(), (float) nextPoint.getY(), (float) nextPoint.getZ()).sub((float) point.getX(), (float) point.getY(), (float) point.getZ()).normalize();
+
+ buffer
+ .vertex(projectionMatrix, (float) point.getX(), (float) point.getY(), (float) point.getZ())
+ .color(colorComponents[0], colorComponents[1], colorComponents[2], alpha)
+ .normal(normalMatrix, normalVec.x, normalVec.y, normalVec.z)
+ .next();
+ }
+
+ tessellator.draw();
+
+ matrices.pop();
+ GL11.glDisable(GL11.GL_LINE_SMOOTH);
+ RenderSystem.lineWidth(1f);
+ RenderSystem.disableBlend();
+ RenderSystem.defaultBlendFunc();
+ RenderSystem.enableCull();
+ RenderSystem.disableDepthTest();
+ }
public static void displayTitleAndPlaySound(int stayTicks, int fadeOutTicks, String titleKey, Formatting formatting) {
MinecraftClient.getInstance().inGameHud.setTitleTicks(0, stayTicks, fadeOutTicks);
diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/RenderUtils.java b/src/main/java/me/xmrvizzy/skyblocker/utils/RenderUtils.java
index 61f79ae1..d20cfefe 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/utils/RenderUtils.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/utils/RenderUtils.java
@@ -41,6 +41,7 @@ public class RenderUtils {
BufferBuilder buffer = tessellator.getBuffer();
// Outline
+ RenderSystem.enableDepthTest();
RenderSystem.disableCull();
RenderSystem.setShader(GameRenderer::getRenderTypeLinesProgram);
RenderSystem.lineWidth(lineWidth);
@@ -50,6 +51,7 @@ public class RenderUtils {
tessellator.draw();
RenderSystem.enableCull();
+ RenderSystem.disableDepthTest();
cleanup();
}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/Utils.java b/src/main/java/me/xmrvizzy/skyblocker/utils/Utils.java
index 25e481b9..e85020aa 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/utils/Utils.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/utils/Utils.java
@@ -129,7 +129,7 @@ public class Utils {
return;
}
String string = sidebar.toString();
- String serverAddress = (client.getCurrentServerEntry() != null) ? client.getCurrentServerEntry().address : "";
+ String serverAddress = (client.getCurrentServerEntry() != null) ? client.getCurrentServerEntry().address.toLowerCase() : "";
if (sidebar.isEmpty()) return;
if (serverAddress.contains("hypixel.net") || serverAddress.contains("hypixel.io")) {
@@ -320,4 +320,4 @@ public class Utils {
locationRaw = "";
map = "";
}
-} \ No newline at end of file
+}
diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json
index c87959a4..578917e2 100644
--- a/src/main/resources/assets/skyblocker/lang/en_us.json
+++ b/src/main/resources/assets/skyblocker/lang/en_us.json
@@ -206,6 +206,7 @@
"text.autoconfig.skyblocker.option.locations.dungeons.mapY": "Map Y",
"text.autoconfig.skyblocker.option.locations.dungeons.solveThreeWeirdos": "Solve Three Weirdos Puzzle",
"text.autoconfig.skyblocker.option.locations.dungeons.blazesolver": "Solve Blaze Puzzle",
+ "text.autoconfig.skyblocker.option.locations.dungeons.blazesolver.@Tooltip": "Boxes the correct blaze in green, also draws a line to and boxes the next blaze to kill in white.",
"text.autoconfig.skyblocker.option.locations.dungeons.solveTrivia": "Solve Trivia Puzzle",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor": "Livid Color",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor": "Enable Livid Color",
@@ -306,5 +307,13 @@
"skyblocker.customDyeColors.neverHad": "§b[§6Skyblocker§b] §fThis item doesn't have a custom dye color set, but why not add one? ;)",
"skyblocker.customDyeColors.added": "§b[§6Skyblocker§b] §fSet a custom dye color for your currently held item!",
"skyblocker.customDyeColors.noItemUuid": "§b[§6Skyblocker§b] §cYou must be holding an item that has a uuid in order to set a custom dye color!",
- "skyblocker.customDyeColors.unableToSetColor": "§b[§6Skyblocker§b] §cUnable to set a custom dye color :( (Are you in skyblock?)"
+ "skyblocker.customDyeColors.unableToSetColor": "§b[§6Skyblocker§b] §cUnable to set a custom dye color :( (Are you in skyblock?, are you holding an item?)",
+
+ "skyblocker.customArmorTrims.invalidMaterialOrPattern": "§b[§6Skyblocker§b] §cYou supplied either an invalid material, or an invalid trim pattern!",
+ "skyblocker.customArmorTrims.notAnArmorPiece": "§b[§6Skyblocker§b] §cThis item isn't an armor piece!",
+ "skyblocker.customArmorTrims.removed": "§b[§6Skyblocker§b] §fRemoved this item's custom armor trim.",
+ "skyblocker.customArmorTrims.neverHad": "§b[§6Skyblocker§b] §fThis item doesn't have a armor trim set, but why not add one? ;)",
+ "skyblocker.customArmorTrims.added": "§b[§6Skyblocker§b] §fSet a custom armor trim for your currently held item!",
+ "skyblocker.customArmorTrims.noItemUuid": "§b[§6Skyblocker§b] §cYou must be holding an item that has a uuid in order to set a custom armor trim!",
+ "skyblocker.customArmorTrims.unableToSetTrim": "§b[§6Skyblocker§b] §cUnable to set a custom armor trim :( (Are you in skyblock?, are you holding an item?)"
}
diff --git a/src/main/resources/skyblocker.mixins.json b/src/main/resources/skyblocker.mixins.json
index 522c3af0..266a653b 100644
--- a/src/main/resources/skyblocker.mixins.json
+++ b/src/main/resources/skyblocker.mixins.json
@@ -3,6 +3,7 @@
"package": "me.xmrvizzy.skyblocker.mixin",
"compatibilityLevel": "JAVA_17",
"client": [
+ "ArmorTrimMixin",
"ClientPlayerEntityMixin",
"ClientPlayNetworkHandlerMixin",
"DrawContextMixin",
diff --git a/src/test/java/me/xmrvizzy/skyblocker/skyblock/item/ArmorTrimIdSerializationTest.java b/src/test/java/me/xmrvizzy/skyblocker/skyblock/item/ArmorTrimIdSerializationTest.java
new file mode 100644
index 00000000..a6ef79b0
--- /dev/null
+++ b/src/test/java/me/xmrvizzy/skyblocker/skyblock/item/ArmorTrimIdSerializationTest.java
@@ -0,0 +1,27 @@
+package me.xmrvizzy.skyblocker.skyblock.item;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import net.minecraft.util.Identifier;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class ArmorTrimIdSerializationTest {
+ private final Gson gson = new GsonBuilder().registerTypeAdapter(Identifier.class, new Identifier.Serializer()).create();
+
+ @Test
+ void serialize() {
+ CustomArmorTrims.ArmorTrimId armorTrimId = new CustomArmorTrims.ArmorTrimId(new Identifier("material_id"), new Identifier("pattern_id"));
+ String json = gson.toJson(armorTrimId);
+ String expectedJson = "{\"material\":\"minecraft:material_id\",\"pattern\":\"minecraft:pattern_id\"}";
+ Assertions.assertEquals(expectedJson, json);
+ }
+
+ @Test
+ void deserialize() {
+ String json = "{\"material\":\"minecraft:material_id\",\"pattern\":\"minecraft:pattern_id\"}";
+ CustomArmorTrims.ArmorTrimId armorTrimId = gson.fromJson(json, CustomArmorTrims.ArmorTrimId.class);
+ CustomArmorTrims.ArmorTrimId expectedArmorTrimId = new CustomArmorTrims.ArmorTrimId(new Identifier("material_id"), new Identifier("pattern_id"));
+ Assertions.assertEquals(expectedArmorTrimId, armorTrimId);
+ }
+}