aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/moe/nea/firmament/init/AutoDiscoveryPlugin.java322
-rw-r--r--src/main/java/moe/nea/firmament/init/EarlyRiser.java2
-rw-r--r--src/main/java/moe/nea/firmament/init/HandledScreenRiser.java1
-rw-r--r--src/main/java/moe/nea/firmament/init/ItemColorsSodiumRiser.java64
-rw-r--r--src/main/java/moe/nea/firmament/init/MixinPlugin.java103
-rw-r--r--src/main/java/moe/nea/firmament/init/SectionBuilderRiser.java183
-rw-r--r--src/main/java/moe/nea/firmament/mixins/AlwaysDisplayFirmamentClientCommandErrors.java18
-rw-r--r--src/main/java/moe/nea/firmament/mixins/AppendRepoAsResourcePack.java24
-rw-r--r--src/main/java/moe/nea/firmament/mixins/CopyChatPatch.java44
-rw-r--r--src/main/java/moe/nea/firmament/mixins/CustomModelEventPatch.java36
-rw-r--r--src/main/java/moe/nea/firmament/mixins/CustomSkullTexturePatch.java21
-rw-r--r--src/main/java/moe/nea/firmament/mixins/DisableHurtCam.java18
-rw-r--r--src/main/java/moe/nea/firmament/mixins/DispatchMouseInputEventsPatch.java17
-rw-r--r--src/main/java/moe/nea/firmament/mixins/EntityUpdateEventListener.java34
-rw-r--r--src/main/java/moe/nea/firmament/mixins/FirmKeybindsInVanillaControlsPatch.java2
-rw-r--r--src/main/java/moe/nea/firmament/mixins/HideStatusEffectsPatch.java29
-rw-r--r--src/main/java/moe/nea/firmament/mixins/HudRenderEventsPatch.java7
-rw-r--r--src/main/java/moe/nea/firmament/mixins/IncomingPacketListenerPatches.java3
-rw-r--r--src/main/java/moe/nea/firmament/mixins/KeyPressInWorldEventPatch.java13
-rw-r--r--src/main/java/moe/nea/firmament/mixins/LenientProfileComponentPatch.java25
-rw-r--r--src/main/java/moe/nea/firmament/mixins/MinecraftInitLevelListener.java26
-rw-r--r--src/main/java/moe/nea/firmament/mixins/MixinHandledScreen.java16
-rw-r--r--src/main/java/moe/nea/firmament/mixins/MixinRecipeBookScreen.java16
-rw-r--r--src/main/java/moe/nea/firmament/mixins/PlayerDropEventPatch.java20
-rw-r--r--src/main/java/moe/nea/firmament/mixins/PropertySignatureIgnorePatch.java36
-rw-r--r--src/main/java/moe/nea/firmament/mixins/ReplaceTextColorInHandledScreen.java48
-rw-r--r--src/main/java/moe/nea/firmament/mixins/SaveOriginalCommandTreePacket.java17
-rw-r--r--src/main/java/moe/nea/firmament/mixins/SlotUpdateListener.java8
-rw-r--r--src/main/java/moe/nea/firmament/mixins/SoundReceiveEventPatch.java30
-rw-r--r--src/main/java/moe/nea/firmament/mixins/TolerateFirmamentTolerateRegistryOwners.java18
-rw-r--r--src/main/java/moe/nea/firmament/mixins/WorldRenderLastEventPatch.java6
-rw-r--r--src/main/java/moe/nea/firmament/mixins/accessor/AccessorChatHud.java10
-rw-r--r--src/main/java/moe/nea/firmament/mixins/accessor/AccessorHandledScreen.java2
-rw-r--r--src/main/java/moe/nea/firmament/mixins/accessor/AccessorPlayerListHud.java31
-rw-r--r--src/main/java/moe/nea/firmament/mixins/accessor/AccessorWorldRenderer.java17
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/ApplyHeadModelInItemRenderer.java35
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/BakedModelDataHolderBasic.java42
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/BakedModelDataHolderBuiltin.java43
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/BakedOverrideDataHolder.java28
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/HeadModelReplacerPatch.java57
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/ItemColorRemovalPatch.java39
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/ItemModelGeneratorJsonUnbakedModelCopy.java22
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/ItemRendererTintContextPatch.java35
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/JsonUnbakedModelDataHolder.java130
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/ModelOverrideDataHolder.java28
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/PatchArmorTexture.java29
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/PatchJsonUnbakedModelDeserializer.java31
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/PatchLegacyArmorLayerSupport.java22
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/PatchOverrideDeserializer.java50
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/ProvideBakerToJsonUnbakedModelPatch.java27
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/ReferenceCustomModelsPatch.java36
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockBreakSoundPatch.java27
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockHitSoundPatch.java30
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockRenderManagerBlockModel.java38
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/ReplaceFallbackBlockModel.java21
-rw-r--r--src/main/java/moe/nea/firmament/mixins/custommodels/TestForFirmamentOverridePredicatesPatch.java68
-rw-r--r--src/main/java/moe/nea/firmament/mixins/feature/DisableSlotHighlights.java25
-rw-r--r--src/main/java/moe/nea/firmament/mixins/feature/devcosmetics/CustomCapeFeatureRenderer.java43
-rw-r--r--src/main/java/moe/nea/firmament/mixins/feature/devcosmetics/CustomCapeStorage.java23
-rw-r--r--src/main/java/moe/nea/firmament/mixins/feature/devcosmetics/SaveCapeToPlayerEntityRenderState.java19
-rw-r--r--src/main/java/moe/nea/firmament/mixins/render/entitytints/ChangeColorOfLivingEntities.java62
-rw-r--r--src/main/java/moe/nea/firmament/mixins/render/entitytints/EntityRenderStateTint.java55
-rw-r--r--src/main/java/moe/nea/firmament/mixins/render/entitytints/InjectIntoRenderState.java30
-rw-r--r--src/main/java/moe/nea/firmament/mixins/render/entitytints/ReplaceOverlayTexture.java24
-rw-r--r--src/main/java/moe/nea/firmament/mixins/render/entitytints/UseOverlayableEquipmentRenderer.java34
-rw-r--r--src/main/java/moe/nea/firmament/mixins/render/entitytints/UseOverlayableHeadFeatureRenderer.java25
-rw-r--r--src/main/java/moe/nea/firmament/mixins/render/entitytints/UseOverlayableItemRenderer.java25
-rw-r--r--src/main/java/moe/nea/firmament/mixins/render/entitytints/UseOverlayableSkullBlockEntityRenderer.java25
68 files changed, 1061 insertions, 1434 deletions
diff --git a/src/main/java/moe/nea/firmament/init/AutoDiscoveryPlugin.java b/src/main/java/moe/nea/firmament/init/AutoDiscoveryPlugin.java
index 9b891a4..a9db7f9 100644
--- a/src/main/java/moe/nea/firmament/init/AutoDiscoveryPlugin.java
+++ b/src/main/java/moe/nea/firmament/init/AutoDiscoveryPlugin.java
@@ -1,6 +1,9 @@
package moe.nea.firmament.init;
+import moe.nea.firmament.util.ErrorUtil;
+import moe.nea.firmament.util.compatloader.ICompatMeta;
+
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
@@ -16,160 +19,169 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class AutoDiscoveryPlugin {
- private static final List<AutoDiscoveryPlugin> mixinPlugins = new ArrayList<>();
-
- public static List<AutoDiscoveryPlugin> getMixinPlugins() {
- return mixinPlugins;
- }
-
- private String mixinPackage;
-
- public void setMixinPackage(String mixinPackage) {
- this.mixinPackage = mixinPackage;
- mixinPlugins.add(this);
- }
-
- /**
- * Resolves the base class root for a given class URL. This resolves either the JAR root, or the class file root.
- * In either case the return value of this + the class name will resolve back to the original class url, or to other
- * class urls for other classes.
- */
- public URL getBaseUrlForClassUrl(URL classUrl) {
- String string = classUrl.toString();
- if (classUrl.getProtocol().equals("jar")) {
- try {
- return new URL(string.substring(4).split("!")[0]);
- } catch (MalformedURLException e) {
- throw new RuntimeException(e);
- }
- }
- if (string.endsWith(".class")) {
- try {
- return new URL(string.replace("\\", "/")
- .replace(getClass().getCanonicalName()
- .replace(".", "/") + ".class", ""));
- } catch (MalformedURLException e) {
- throw new RuntimeException(e);
- }
- }
- return classUrl;
- }
-
- /**
- * Get the package that contains all the mixins. This value is set using {@link #setMixinPackage}.
- */
- public String getMixinPackage() {
- return mixinPackage;
- }
-
- /**
- * Get the path inside the class root to the mixin package
- */
- public String getMixinBaseDir() {
- return mixinPackage.replace(".", "/");
- }
-
- /**
- * A list of all discovered mixins.
- */
- private List<String> mixins = null;
-
- /**
- * Try to add mixin class ot the mixins based on the filepath inside of the class root.
- * Removes the {@code .class} file suffix, as well as the base mixin package.
- * <p><b>This method cannot be called after mixin initialization.</p>
- *
- * @param className the name or path of a class to be registered as a mixin.
- */
- public void tryAddMixinClass(String className) {
- if (!className.endsWith(".class")) return;
- String norm = (className.substring(0, className.length() - ".class".length()))
- .replace("\\", "/")
- .replace("/", ".");
- if (norm.startsWith(getMixinPackage() + ".") && !norm.endsWith(".")) {
- mixins.add(norm.substring(getMixinPackage().length() + 1));
- }
- }
-
- private void tryDiscoverFromContentFile(URL url) {
- Path file;
- try {
- file = Paths.get(getBaseUrlForClassUrl(url).toURI());
- } catch (URISyntaxException e) {
- throw new RuntimeException(e);
- }
- System.out.println("Base directory found at " + file);
- if (!Files.exists(file)) {
- System.out.println("Skipping non-existing mixin root: " + file);
- return;
- }
- if (Files.isDirectory(file)) {
- walkDir(file);
- } else {
- walkJar(file);
- }
- System.out.println("Found mixins: " + mixins);
-
- }
-
- /**
- * Search through the JAR or class directory to find mixins contained in {@link #getMixinPackage()}
- */
- public List<String> getMixins() {
- if (mixins != null) return mixins;
- System.out.println("Trying to discover mixins");
- mixins = new ArrayList<>();
- URL classUrl = getClass().getProtectionDomain().getCodeSource().getLocation();
- System.out.println("Found classes at " + classUrl);
- tryDiscoverFromContentFile(classUrl);
- var classRoots = System.getProperty("firmament.classroots");
- if (classRoots != null && !classRoots.isBlank()) {
- System.out.println("Found firmament class roots: " + classRoots);
- for (String s : classRoots.split(File.pathSeparator)) {
- if (s.isBlank()) {
- continue;
- }
- try {
- tryDiscoverFromContentFile(new File(s).toURI().toURL());
- } catch (MalformedURLException e) {
- throw new RuntimeException(e);
- }
- }
- }
- return mixins;
- }
-
- /**
- * Search through directory for mixin classes based on {@link #getMixinBaseDir}.
- *
- * @param classRoot The root directory in which classes are stored for the default package.
- */
- private void walkDir(Path classRoot) {
- System.out.println("Trying to find mixins from directory");
- var path = classRoot.resolve(getMixinBaseDir());
- if (!Files.exists(path)) return;
- try (Stream<Path> classes = Files.walk(path)) {
- classes.map(it -> classRoot.relativize(it).toString())
- .forEach(this::tryAddMixinClass);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Read through a JAR file, trying to find all mixins inside.
- */
- private void walkJar(Path file) {
- System.out.println("Trying to find mixins from jar file");
- try (ZipInputStream zis = new ZipInputStream(Files.newInputStream(file))) {
- ZipEntry next;
- while ((next = zis.getNextEntry()) != null) {
- tryAddMixinClass(next.getName());
- zis.closeEntry();
- }
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
+ public static List<String> getDefaultAllMixinClassesFQNs() {
+ var defaultName = "moe.nea.firmament.mixins";
+ var plugin = new AutoDiscoveryPlugin();
+ plugin.setMixinPackage(defaultName);
+ var mixins = plugin.getMixins();
+ return mixins.stream().map(it -> defaultName + "." + it).toList();
+ }
+
+ private static final List<AutoDiscoveryPlugin> mixinPlugins = new ArrayList<>();
+
+ public static List<AutoDiscoveryPlugin> getMixinPlugins() {
+ return mixinPlugins;
+ }
+
+ private String mixinPackage;
+
+ public void setMixinPackage(String mixinPackage) {
+ this.mixinPackage = mixinPackage;
+ mixinPlugins.add(this);
+ }
+
+ /**
+ * Resolves the base class root for a given class URL. This resolves either the JAR root, or the class file root.
+ * In either case the return value of this + the class name will resolve back to the original class url, or to other
+ * class urls for other classes.
+ */
+ public URL getBaseUrlForClassUrl(URL classUrl) {
+ String string = classUrl.toString();
+ if (classUrl.getProtocol().equals("jar")) {
+ try {
+ return new URL(string.substring(4).split("!")[0]);
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ if (string.endsWith(".class")) {
+ try {
+ return new URL(string.replace("\\", "/")
+ .replace(getClass().getCanonicalName()
+ .replace(".", "/") + ".class", ""));
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return classUrl;
+ }
+
+ /**
+ * Get the package that contains all the mixins. This value is set using {@link #setMixinPackage}.
+ */
+ public String getMixinPackage() {
+ return mixinPackage;
+ }
+
+ /**
+ * Get the path inside the class root to the mixin package
+ */
+ public String getMixinBaseDir() {
+ return mixinPackage.replace(".", "/");
+ }
+
+ /**
+ * A list of all discovered mixins.
+ */
+ private List<String> mixins = null;
+
+ /**
+ * Try to add mixin class ot the mixins based on the filepath inside of the class root.
+ * Removes the {@code .class} file suffix, as well as the base mixin package.
+ * <p><b>This method cannot be called after mixin initialization.</p>
+ *
+ * @param className the name or path of a class to be registered as a mixin.
+ */
+ public void tryAddMixinClass(String className) {
+ if (!className.endsWith(".class")) return;
+ String norm = (className.substring(0, className.length() - ".class".length()))
+ .replace("\\", "/")
+ .replace("/", ".");
+ if (norm.startsWith(getMixinPackage() + ".") && !norm.endsWith(".") && ICompatMeta.Companion.shouldLoad(norm)) {
+ mixins.add(norm.substring(getMixinPackage().length() + 1));
+ }
+ }
+
+ private void tryDiscoverFromContentFile(URL url) {
+ Path file;
+ try {
+ file = Paths.get(getBaseUrlForClassUrl(url).toURI());
+ } catch (URISyntaxException e) {
+ throw new RuntimeException(e);
+ }
+ System.out.println("Base directory found at " + file);
+ if (!Files.exists(file)) {
+ System.out.println("Skipping non-existing mixin root: " + file);
+ return;
+ }
+ if (Files.isDirectory(file)) {
+ walkDir(file);
+ } else {
+ walkJar(file);
+ }
+ System.out.println("Found mixins: " + mixins);
+
+ }
+
+ /**
+ * Search through the JAR or class directory to find mixins contained in {@link #getMixinPackage()}
+ */
+ public List<String> getMixins() {
+ if (mixins != null) return mixins;
+ try {
+ System.out.println("Trying to discover mixins");
+ mixins = new ArrayList<>();
+ URL classUrl = getClass().getProtectionDomain().getCodeSource().getLocation();
+ System.out.println("Found classes at " + classUrl);
+ tryDiscoverFromContentFile(classUrl);
+ var classRoots = System.getProperty("firmament.classroots");
+ if (classRoots != null && !classRoots.isBlank()) {
+ System.out.println("Found firmament class roots: " + classRoots);
+ for (String s : classRoots.split(File.pathSeparator)) {
+ if (s.isBlank()) {
+ continue;
+ }
+ tryDiscoverFromContentFile(new File(s).toURI().toURL());
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ return mixins;
+ }
+
+ /**
+ * Search through directory for mixin classes based on {@link #getMixinBaseDir}.
+ *
+ * @param classRoot The root directory in which classes are stored for the default package.
+ */
+ private void walkDir(Path classRoot) {
+ System.out.println("Trying to find mixins from directory");
+ var path = classRoot.resolve(getMixinBaseDir());
+ if (!Files.exists(path)) return;
+ try (Stream<Path> classes = Files.walk(path)) {
+ classes.map(it -> classRoot.relativize(it).toString())
+ .forEach(this::tryAddMixinClass);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Read through a JAR file, trying to find all mixins inside.
+ */
+ private void walkJar(Path file) {
+ System.out.println("Trying to find mixins from jar file");
+ try (ZipInputStream zis = new ZipInputStream(Files.newInputStream(file))) {
+ ZipEntry next;
+ while ((next = zis.getNextEntry()) != null) {
+ tryAddMixinClass(next.getName());
+ zis.closeEntry();
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
}
diff --git a/src/main/java/moe/nea/firmament/init/EarlyRiser.java b/src/main/java/moe/nea/firmament/init/EarlyRiser.java
index 9734e94..5441255 100644
--- a/src/main/java/moe/nea/firmament/init/EarlyRiser.java
+++ b/src/main/java/moe/nea/firmament/init/EarlyRiser.java
@@ -7,6 +7,6 @@ public class EarlyRiser implements Runnable {
new ClientPlayerRiser().addTinkerers();
new HandledScreenRiser().addTinkerers();
new SectionBuilderRiser().addTinkerers();
- new ItemColorsSodiumRiser().addTinkerers();
+// TODO: new ItemColorsSodiumRiser().addTinkerers();
}
}
diff --git a/src/main/java/moe/nea/firmament/init/HandledScreenRiser.java b/src/main/java/moe/nea/firmament/init/HandledScreenRiser.java
index 355a666..f7db18c 100644
--- a/src/main/java/moe/nea/firmament/init/HandledScreenRiser.java
+++ b/src/main/java/moe/nea/firmament/init/HandledScreenRiser.java
@@ -3,7 +3,6 @@ package moe.nea.firmament.init;
import me.shedaniel.mm.api.ClassTinkerers;
import net.minecraft.client.gui.Element;
-import net.minecraft.client.gui.ParentElement;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.ClassNode;
diff --git a/src/main/java/moe/nea/firmament/init/ItemColorsSodiumRiser.java b/src/main/java/moe/nea/firmament/init/ItemColorsSodiumRiser.java
deleted file mode 100644
index 80ee9aa..0000000
--- a/src/main/java/moe/nea/firmament/init/ItemColorsSodiumRiser.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package moe.nea.firmament.init;
-
-import me.shedaniel.mm.api.ClassTinkerers;
-import moe.nea.firmament.util.ErrorUtil;
-import net.fabricmc.loader.api.FabricLoader;
-import net.minecraft.client.color.item.ItemColorProvider;
-import net.minecraft.client.color.item.ItemColors;
-import net.minecraft.item.ItemStack;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.tree.ClassNode;
-import org.objectweb.asm.tree.InsnList;
-import org.objectweb.asm.tree.InsnNode;
-import org.objectweb.asm.tree.MethodInsnNode;
-import org.objectweb.asm.tree.VarInsnNode;
-
-public class ItemColorsSodiumRiser extends RiserUtils {
- @IntermediaryName(ItemColors.class)
- String ItemColors;
- @IntermediaryName(ItemColorProvider.class)
- String ItemColorProvider;
- @IntermediaryName(ItemStack.class)
- String ItemStack;
- String getColorProvider = "sodium$getColorProvider";
- Type getColorProviderDesc = Type.getMethodType(getTypeForClassName(ItemColorProvider),
- getTypeForClassName(ItemStack));
-
- @Override
- public void addTinkerers() {
- ClassTinkerers.addTransformation(ItemColors, this::addSodiumOverride, true);
- }
-
- private void addSodiumOverride(ClassNode classNode) {
- var node = findMethod(classNode, getColorProvider, getColorProviderDesc);
- if (node == null) {
- if (!FabricLoader.getInstance().isModLoaded("sodium"))
- ErrorUtil.INSTANCE.softError("Sodium is present, but sodium color override could not be injected.");
- return;
- }
- var p = node.instructions.getFirst();
- while (p != null) {
- if (p.getOpcode() == Opcodes.ARETURN) {
- node.instructions.insertBefore(
- p,
- mkOverrideSodiumCall()
- );
- }
- p = p.getNext();
- }
- }
-
- private InsnList mkOverrideSodiumCall() {
- var insnList = new InsnList();
- insnList.add(new VarInsnNode(Opcodes.ALOAD, 0));
- insnList.add(new InsnNode(Opcodes.SWAP));
- insnList.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
- getTypeForClassName(ItemColors).getInternalName(),
- "overrideSodium_firmament",
- Type.getMethodType(getTypeForClassName(ItemColorProvider),
- getTypeForClassName(ItemColorProvider)).getDescriptor(),
- false));
- return insnList;
- }
-}
diff --git a/src/main/java/moe/nea/firmament/init/MixinPlugin.java b/src/main/java/moe/nea/firmament/init/MixinPlugin.java
index 61e8f14..d48139b 100644
--- a/src/main/java/moe/nea/firmament/init/MixinPlugin.java
+++ b/src/main/java/moe/nea/firmament/init/MixinPlugin.java
@@ -8,54 +8,69 @@ import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class MixinPlugin implements IMixinConfigPlugin {
- AutoDiscoveryPlugin autoDiscoveryPlugin = new AutoDiscoveryPlugin();
- public static String mixinPackage;
- @Override
- public void onLoad(String mixinPackage) {
- MixinExtrasBootstrap.init();
- MixinPlugin.mixinPackage = mixinPackage;
- autoDiscoveryPlugin.setMixinPackage(mixinPackage);
- }
-
- @Override
- public String getRefMapperConfig() {
- return null;
- }
-
- @Override
- public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
- if (!Boolean.getBoolean("firmament.debug") && mixinClassName.contains("devenv.")) {
- return false;
- }
- return true;
- }
-
- @Override
- public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {
-
- }
-
- @Override
- public List<String> getMixins() {
- return autoDiscoveryPlugin.getMixins().stream().filter(it -> this.shouldApplyMixin(null, it))
- .toList();
- }
-
- @Override
- public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
-
- }
-
- public static List<String> appliedMixins = new ArrayList<>();
-
- @Override
- public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
- appliedMixins.add(mixinClassName);
- }
+ AutoDiscoveryPlugin autoDiscoveryPlugin = new AutoDiscoveryPlugin();
+ public static List<MixinPlugin> instances = new ArrayList<>();
+ public String mixinPackage;
+
+ @Override
+ public void onLoad(String mixinPackage) {
+ MixinExtrasBootstrap.init();
+ instances.add(this);
+ this.mixinPackage = mixinPackage;
+ autoDiscoveryPlugin.setMixinPackage(mixinPackage);
+ }
+
+ @Override
+ public String getRefMapperConfig() {
+ return null;
+ }
+
+ @Override
+ public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
+ if (!Boolean.getBoolean("firmament.debug") && mixinClassName.contains("devenv.")) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {
+
+ }
+
+ @Override
+ public List<String> getMixins() {
+ return autoDiscoveryPlugin.getMixins().stream().filter(it -> this.shouldApplyMixin(null, it))
+ .toList();
+ }
+
+ @Override
+ public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
+
+ }
+
+ public Set<String> getAppliedFullPathMixins() {
+ return new HashSet<>(appliedMixins);
+ }
+
+ public Set<String> getExpectedFullPathMixins() {
+ return getMixins()
+ .stream()
+ .map(it -> mixinPackage + "." + it)
+ .collect(Collectors.toSet());
+ }
+
+ public List<String> appliedMixins = new ArrayList<>();
+
+ @Override
+ public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
+ appliedMixins.add(mixinClassName);
+ }
}
diff --git a/src/main/java/moe/nea/firmament/init/SectionBuilderRiser.java b/src/main/java/moe/nea/firmament/init/SectionBuilderRiser.java
index f2c6c53..8b65946 100644
--- a/src/main/java/moe/nea/firmament/init/SectionBuilderRiser.java
+++ b/src/main/java/moe/nea/firmament/init/SectionBuilderRiser.java
@@ -3,10 +3,9 @@ package moe.nea.firmament.init;
import me.shedaniel.mm.api.ClassTinkerers;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.block.BlockState;
-import net.minecraft.client.render.block.BlockModels;
import net.minecraft.client.render.block.BlockRenderManager;
import net.minecraft.client.render.chunk.SectionBuilder;
-import net.minecraft.client.render.model.BakedModel;
+import net.minecraft.client.render.model.BlockStateModel;
import net.minecraft.util.math.BlockPos;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
@@ -20,98 +19,100 @@ import org.objectweb.asm.tree.VarInsnNode;
public class SectionBuilderRiser extends RiserUtils {
- @IntermediaryName(SectionBuilder.class)
- String SectionBuilder;
- @IntermediaryName(BlockPos.class)
- String BlockPos;
- @IntermediaryName(BlockRenderManager.class)
- String BlockRenderManager;
- @IntermediaryName(BlockState.class)
- String BlockState;
- @IntermediaryName(BakedModel.class)
- String BakedModel;
- String CustomBlockTextures = "moe.nea.firmament.features.texturepack.CustomBlockTextures";
+ @IntermediaryName(SectionBuilder.class)
+ String SectionBuilder;
+ @IntermediaryName(BlockPos.class)
+ String BlockPos;
+ @IntermediaryName(BlockRenderManager.class)
+ String BlockRenderManager;
+ @IntermediaryName(BlockState.class)
+ String BlockState;
+ @IntermediaryName(BlockStateModel.class)
+ String BlockStateModel;
+ String CustomBlockTextures = "moe.nea.firmament.features.texturepack.CustomBlockTextures";
- Type getModelDesc = Type.getMethodType(
- getTypeForClassName(BlockRenderManager),
- getTypeForClassName(BlockState)
- );
- String getModel = remapper.mapMethodName(
- "intermediary",
- Intermediary.<BlockRenderManager>className(),
- Intermediary.methodName(net.minecraft.client.render.block.BlockRenderManager::getModel),
- Type.getMethodDescriptor(
- getTypeForClassName(Intermediary.<BakedModel>className()),
- getTypeForClassName(Intermediary.<BlockState>className())
- )
- );
+ Type getModelDesc = Type.getMethodType(
+ getTypeForClassName(BlockRenderManager),
+ getTypeForClassName(BlockState)
+ );
+ String getModel = remapper.mapMethodName(
+ "intermediary",
+ Intermediary.<BlockRenderManager>className(),
+ Intermediary.methodName(net.minecraft.client.render.block.BlockRenderManager::getModel),
+ Type.getMethodDescriptor(
+ getTypeForClassName(Intermediary.<BlockStateModel>className()),
+ getTypeForClassName(Intermediary.<BlockState>className())
+ )
+ );
- @Override
- public void addTinkerers() {
- if (FabricLoader.getInstance().isModLoaded("fabric-renderer-indigo"))
- ClassTinkerers.addTransformation(SectionBuilder, this::handle, true);
- }
+ @Override
+ public void addTinkerers() {
+ if (FabricLoader.getInstance().isModLoaded("fabric-renderer-indigo"))
+ ClassTinkerers.addTransformation(SectionBuilder, this::handle, true);
+ }
- private void handle(ClassNode classNode) {
- for (MethodNode method : classNode.methods) {
- if ((method.name.endsWith("$fabric-renderer-indigo$hookBuildRenderBlock")
- || method.name.endsWith("$fabric-renderer-indigo$hookChunkBuildTessellate")) &&
- method.name.startsWith("redirect$")) {
- handleIndigo(method);
- return;
- }
- }
- System.err.println("Could not inject indigo rendering hook. Is a custom renderer installed (e.g. sodium)?");
- }
+ private void handle(ClassNode classNode) {
+ System.out.println("AVAST! "+ getModel);
+ for (MethodNode method : classNode.methods) {
+ if ((method.name.endsWith("$fabric-renderer-indigo$hookBuildRenderBlock")
+ || method.name.endsWith("$fabric-renderer-indigo$hookChunkBuildTessellate")) &&
+ method.name.startsWith("redirect$")) {
+ handleIndigo(method);
+ return;
+ }
+ }
+ System.err.println("Could not inject indigo rendering hook. Is a custom renderer installed (e.g. sodium)?");
+ }
- private void handleIndigo(MethodNode method) {
- LocalVariableNode blockPosVar = null, blockStateVar = null;
- for (LocalVariableNode localVariable : method.localVariables) {
- if (Type.getType(localVariable.desc).equals(getTypeForClassName(BlockPos))) {
- blockPosVar = localVariable;
- }
- if (Type.getType(localVariable.desc).equals(getTypeForClassName(BlockState))) {
- blockStateVar = localVariable;
- }
- }
- if (blockPosVar == null || blockStateVar == null) {
- System.err.println("Firmament could inject into indigo: missing either block pos or blockstate");
- return;
- }
- for (AbstractInsnNode instruction : method.instructions) {
- if (instruction.getOpcode() != Opcodes.INVOKEVIRTUAL) continue;
- var methodInsn = (MethodInsnNode) instruction;
- if (!(methodInsn.name.equals(getModel) && Type.getObjectType(methodInsn.owner).equals(getTypeForClassName(BlockRenderManager))))
- continue;
- method.instructions.insertBefore(
- methodInsn,
- new MethodInsnNode(
- Opcodes.INVOKESTATIC,
- getTypeForClassName(CustomBlockTextures).getInternalName(),
- "enterFallbackCall",
- Type.getMethodDescriptor(Type.VOID_TYPE)
- ));
+ private void handleIndigo(MethodNode method) {
+ LocalVariableNode blockPosVar = null, blockStateVar = null;
+ for (LocalVariableNode localVariable : method.localVariables) {
+ if (Type.getType(localVariable.desc).equals(getTypeForClassName(BlockPos))) {
+ blockPosVar = localVariable;
+ }
+ if (Type.getType(localVariable.desc).equals(getTypeForClassName(BlockState))) {
+ blockStateVar = localVariable;
+ }
+ }
+ if (blockPosVar == null || blockStateVar == null) {
+ System.err.println("Firmament could inject into indigo: missing either block pos or blockstate");
+ return;
+ }
+ for (AbstractInsnNode instruction : method.instructions) {
+ if (instruction.getOpcode() != Opcodes.INVOKEVIRTUAL) continue;
+ var methodInsn = (MethodInsnNode) instruction;
+ if (!(methodInsn.name.equals(getModel) && Type.getObjectType(methodInsn.owner).equals(getTypeForClassName(BlockRenderManager))))
+ continue;
+ method.instructions.insertBefore(
+ methodInsn,
+ new MethodInsnNode(
+ Opcodes.INVOKESTATIC,
+ getTypeForClassName(CustomBlockTextures).getInternalName(),
+ "enterFallbackCall",
+ Type.getMethodDescriptor(Type.VOID_TYPE)
+ ));
- var insnList = new InsnList();
- insnList.add(new MethodInsnNode(
- Opcodes.INVOKESTATIC,
- getTypeForClassName(CustomBlockTextures).getInternalName(),
- "exitFallbackCall",
- Type.getMethodDescriptor(Type.VOID_TYPE)
- ));
- insnList.add(new VarInsnNode(Opcodes.ALOAD, blockPosVar.index));
- insnList.add(new VarInsnNode(Opcodes.ALOAD, blockStateVar.index));
- insnList.add(new MethodInsnNode(
- Opcodes.INVOKESTATIC,
- getTypeForClassName(CustomBlockTextures).getInternalName(),
- "patchIndigo",
- Type.getMethodDescriptor(getTypeForClassName(BakedModel),
- getTypeForClassName(BakedModel),
- getTypeForClassName(BlockPos),
- getTypeForClassName(BlockState)),
- false
- ));
- method.instructions.insert(methodInsn, insnList);
- }
- }
+ var insnList = new InsnList();
+ insnList.add(new MethodInsnNode(
+ Opcodes.INVOKESTATIC,
+ getTypeForClassName(CustomBlockTextures).getInternalName(),
+ "exitFallbackCall",
+ Type.getMethodDescriptor(Type.VOID_TYPE)
+ ));
+ insnList.add(new VarInsnNode(Opcodes.ALOAD, blockPosVar.index));
+ insnList.add(new VarInsnNode(Opcodes.ALOAD, blockStateVar.index));
+ insnList.add(new MethodInsnNode(
+ Opcodes.INVOKESTATIC,
+ getTypeForClassName(CustomBlockTextures).getInternalName(),
+ "patchIndigo",
+ Type.getMethodDescriptor(
+ getTypeForClassName(BlockStateModel),
+ getTypeForClassName(BlockStateModel),
+ getTypeForClassName(BlockPos),
+ getTypeForClassName(BlockState)),
+ false
+ ));
+ method.instructions.insert(methodInsn, insnList);
+ }
+ }
}
diff --git a/src/main/java/moe/nea/firmament/mixins/AlwaysDisplayFirmamentClientCommandErrors.java b/src/main/java/moe/nea/firmament/mixins/AlwaysDisplayFirmamentClientCommandErrors.java
new file mode 100644
index 0000000..59769c6
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/AlwaysDisplayFirmamentClientCommandErrors.java
@@ -0,0 +1,18 @@
+package moe.nea.firmament.mixins;
+
+import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
+import com.llamalad7.mixinextras.sugar.Local;
+import net.fabricmc.fabric.impl.command.client.ClientCommandInternals;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+
+@Mixin(ClientCommandInternals.class)
+public class AlwaysDisplayFirmamentClientCommandErrors {
+ @ModifyExpressionValue(method = "executeCommand", at = @At(value = "INVOKE", target = "Lnet/fabricmc/fabric/impl/command/client/ClientCommandInternals;isIgnoredException(Lcom/mojang/brigadier/exceptions/CommandExceptionType;)Z"))
+ private static boolean markFirmamentExceptionsAsNotIgnores(boolean original, @Local(argsOnly = true) String command) {
+ if (command.startsWith("firm ") || command.equals("firm") || command.startsWith("firmament ") || command.equals("firmament")) {
+ return false;
+ }
+ return original;
+ }
+}
diff --git a/src/main/java/moe/nea/firmament/mixins/AppendRepoAsResourcePack.java b/src/main/java/moe/nea/firmament/mixins/AppendRepoAsResourcePack.java
index 22ce991..d8e35d7 100644
--- a/src/main/java/moe/nea/firmament/mixins/AppendRepoAsResourcePack.java
+++ b/src/main/java/moe/nea/firmament/mixins/AppendRepoAsResourcePack.java
@@ -1,28 +1,34 @@
package moe.nea.firmament.mixins;
+import com.llamalad7.mixinextras.sugar.Local;
import moe.nea.firmament.repo.RepoModResourcePack;
import net.fabricmc.fabric.api.resource.ModResourcePack;
+import net.fabricmc.fabric.impl.resource.loader.ModResourcePackSorter;
import net.fabricmc.fabric.impl.resource.loader.ModResourcePackUtil;
+import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.resource.ResourceType;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.List;
@Mixin(ModResourcePackUtil.class)
public class AppendRepoAsResourcePack {
- @Inject(method = "appendModResourcePacks", at = @At("TAIL"))
- private static void onAppendModResourcePack(
- List<ModResourcePack> packs,
- ResourceType type,
- @Nullable String subPath,
- CallbackInfo ci
- ) {
- RepoModResourcePack.Companion.append(packs);
- }
+ @Inject(
+ method = "getModResourcePacks",
+ at = @At(value = "INVOKE", target = "Lnet/fabricmc/fabric/impl/resource/loader/ModResourcePackSorter;getPacks()Ljava/util/List;"),
+ require = 0
+ )
+ private static void onAppendModResourcePack(
+ FabricLoader fabricLoader, ResourceType type, @Nullable String subPath, CallbackInfoReturnable<List<ModResourcePack>> cir,
+ @Local ModResourcePackSorter sorter
+ ) {
+ RepoModResourcePack.Companion.append(sorter);
+ }
}
diff --git a/src/main/java/moe/nea/firmament/mixins/CopyChatPatch.java b/src/main/java/moe/nea/firmament/mixins/CopyChatPatch.java
new file mode 100644
index 0000000..6996818
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/CopyChatPatch.java
@@ -0,0 +1,44 @@
+package moe.nea.firmament.mixins;
+
+import moe.nea.firmament.features.chat.CopyChat;
+import moe.nea.firmament.mixins.accessor.AccessorChatHud;
+import moe.nea.firmament.util.ClipboardUtils;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.gui.hud.ChatHud;
+import net.minecraft.client.gui.hud.ChatHudLine;
+import net.minecraft.client.gui.screen.ChatScreen;
+import net.minecraft.text.Text;
+import net.minecraft.util.Formatting;
+import net.minecraft.util.math.MathHelper;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Unique;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
+import java.util.List;
+
+@Mixin(ChatScreen.class)
+public class CopyChatPatch {
+ @Inject(method = "mouseClicked", at = @At("HEAD"), cancellable = true)
+ private void onRightClick(double mouseX, double mouseY, int button, CallbackInfoReturnable<Boolean> cir) throws NoSuchFieldException, IllegalAccessException {
+ if (button != 1 || !CopyChat.TConfig.INSTANCE.getCopyChat()) return;
+ MinecraftClient client = MinecraftClient.getInstance();
+ ChatHud chatHud = client.inGameHud.getChatHud();
+ int lineIndex = getChatLineIndex(chatHud, mouseY);
+ if (lineIndex < 0) return;
+ List<ChatHudLine.Visible> visible = ((AccessorChatHud) chatHud).getVisibleMessages_firmament();
+ if (lineIndex >= visible.size()) return;
+ ChatHudLine.Visible line = visible.get(lineIndex);
+ String text = CopyChat.INSTANCE.orderedTextToString(line.content());
+ ClipboardUtils.INSTANCE.setTextContent(text);
+ chatHud.addMessage(Text.literal("Copied: ").append(text).formatted(Formatting.GRAY));
+ cir.setReturnValue(true);
+ cir.cancel();
+ }
+
+ @Unique
+ private int getChatLineIndex(ChatHud chatHud, double mouseY) {
+ double chatLineY = ((AccessorChatHud) chatHud).toChatLineY_firmament(mouseY);
+ return MathHelper.floor(chatLineY + ((AccessorChatHud) chatHud).getScrolledLines_firmament());
+ }
+}
diff --git a/src/main/java/moe/nea/firmament/mixins/CustomModelEventPatch.java b/src/main/java/moe/nea/firmament/mixins/CustomModelEventPatch.java
deleted file mode 100644
index e0a7544..0000000
--- a/src/main/java/moe/nea/firmament/mixins/CustomModelEventPatch.java
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-package moe.nea.firmament.mixins;
-
-import moe.nea.firmament.events.CustomItemModelEvent;
-import moe.nea.firmament.features.texturepack.CustomGlobalTextures;
-import net.minecraft.client.render.item.ItemModels;
-import net.minecraft.client.render.model.BakedModel;
-import net.minecraft.client.render.model.BakedModelManager;
-import net.minecraft.item.Item;
-import net.minecraft.item.ItemStack;
-import net.minecraft.util.Identifier;
-import org.spongepowered.asm.mixin.Final;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
-
-import java.util.Map;
-
-@Mixin(ItemModels.class)
-public class CustomModelEventPatch {
-
- @Inject(method = "getModel(Lnet/minecraft/item/ItemStack;)Lnet/minecraft/client/render/model/BakedModel;", at = @At("HEAD"), cancellable = true)
- public void onGetModel(ItemStack stack, CallbackInfoReturnable<BakedModel> cir) {
- var $this = (ItemModels) (Object) this;
- var model = CustomItemModelEvent.getModel(stack, $this);
- if (model == null) {
- model = CustomGlobalTextures.replaceGlobalModel($this, stack);
- }
- if (model != null) {
- cir.setReturnValue(model);
- }
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/CustomSkullTexturePatch.java b/src/main/java/moe/nea/firmament/mixins/CustomSkullTexturePatch.java
deleted file mode 100644
index f3b616a..0000000
--- a/src/main/java/moe/nea/firmament/mixins/CustomSkullTexturePatch.java
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-package moe.nea.firmament.mixins;
-
-import moe.nea.firmament.features.texturepack.CustomSkyBlockTextures;
-import net.minecraft.block.SkullBlock;
-import net.minecraft.client.render.RenderLayer;
-import net.minecraft.client.render.block.entity.SkullBlockEntityRenderer;
-import net.minecraft.component.type.ProfileComponent;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
-
-@Mixin(SkullBlockEntityRenderer.class)
-public class CustomSkullTexturePatch {
- @Inject(method = "getRenderLayer", at = @At("HEAD"), cancellable = true)
- private static void onGetRenderLayer(SkullBlock.SkullType type, ProfileComponent profile, CallbackInfoReturnable<RenderLayer> cir) {
- CustomSkyBlockTextures.INSTANCE.modifySkullTexture(type, profile, cir);
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/DisableHurtCam.java b/src/main/java/moe/nea/firmament/mixins/DisableHurtCam.java
new file mode 100644
index 0000000..ed7a2d4
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/DisableHurtCam.java
@@ -0,0 +1,18 @@
+package moe.nea.firmament.mixins;
+
+import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
+import moe.nea.firmament.features.fixes.Fixes;
+import net.minecraft.client.render.GameRenderer;
+import org.objectweb.asm.Opcodes;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+
+@Mixin(GameRenderer.class)
+public class DisableHurtCam {
+ @ModifyExpressionValue(method = "tiltViewWhenHurt", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/LivingEntity;hurtTime:I", opcode = Opcodes.GETFIELD))
+ private int replaceHurtTime(int original) {
+ if (Fixes.TConfig.INSTANCE.getNoHurtCam())
+ return 0;
+ return original;
+ }
+}
diff --git a/src/main/java/moe/nea/firmament/mixins/DispatchMouseInputEventsPatch.java b/src/main/java/moe/nea/firmament/mixins/DispatchMouseInputEventsPatch.java
new file mode 100644
index 0000000..f1b07bb
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/DispatchMouseInputEventsPatch.java
@@ -0,0 +1,17 @@
+package moe.nea.firmament.mixins;
+
+import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
+import moe.nea.firmament.events.WorldMouseMoveEvent;
+import net.minecraft.client.Mouse;
+import net.minecraft.client.network.ClientPlayerEntity;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+
+@Mixin(Mouse.class)
+public class DispatchMouseInputEventsPatch {
+ @WrapWithCondition(method = "updateMouse", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;changeLookDirection(DD)V"))
+ public boolean onRotatePlayer(ClientPlayerEntity instance, double deltaX, double deltaY) {
+ var event = WorldMouseMoveEvent.Companion.publish(new WorldMouseMoveEvent(deltaX, deltaY));
+ return !event.getCancelled();
+ }
+}
diff --git a/src/main/java/moe/nea/firmament/mixins/EntityUpdateEventListener.java b/src/main/java/moe/nea/firmament/mixins/EntityUpdateEventListener.java
index c2d6e46..d956da9 100644
--- a/src/main/java/moe/nea/firmament/mixins/EntityUpdateEventListener.java
+++ b/src/main/java/moe/nea/firmament/mixins/EntityUpdateEventListener.java
@@ -12,6 +12,7 @@ import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.packet.s2c.play.EntityAttributesS2CPacket;
+import net.minecraft.network.packet.s2c.play.EntityEquipmentUpdateS2CPacket;
import net.minecraft.network.packet.s2c.play.EntityTrackerUpdateS2CPacket;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@@ -22,21 +23,26 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ClientPlayNetworkHandler.class)
public abstract class EntityUpdateEventListener extends ClientCommonNetworkHandler {
- @Shadow
- private ClientWorld world;
+ @Shadow
+ private ClientWorld world;
- protected EntityUpdateEventListener(MinecraftClient client, ClientConnection connection, ClientConnectionState connectionState) {
- super(client, connection, connectionState);
- }
+ protected EntityUpdateEventListener(MinecraftClient client, ClientConnection connection, ClientConnectionState connectionState) {
+ super(client, connection, connectionState);
+ }
- @Inject(method = "onEntityAttributes", at = @At("TAIL"))
- private void onAttributeUpdate(EntityAttributesS2CPacket packet, CallbackInfo ci) {
- EntityUpdateEvent.Companion.publish(new EntityUpdateEvent.AttributeUpdate(
- (LivingEntity) world.getEntityById(packet.getEntityId()), packet.getEntries()));
- }
+ @Inject(method = "onEntityEquipmentUpdate", at = @At(value = "INVOKE", target = "Ljava/util/List;forEach(Ljava/util/function/Consumer;)V", shift = At.Shift.AFTER))
+ private void onEquipmentUpdate(EntityEquipmentUpdateS2CPacket packet, CallbackInfo ci, @Local LivingEntity entity) {
+ EntityUpdateEvent.Companion.publish(new EntityUpdateEvent.EquipmentUpdate(entity, packet.getEquipmentList()));
+ }
- @Inject(method = "onEntityTrackerUpdate", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/data/DataTracker;writeUpdatedEntries(Ljava/util/List;)V", shift = At.Shift.AFTER))
- private void onEntityTracker(EntityTrackerUpdateS2CPacket packet, CallbackInfo ci, @Local Entity entity) {
- EntityUpdateEvent.Companion.publish(new EntityUpdateEvent.TrackedDataUpdate(entity, packet.trackedValues()));
- }
+ @Inject(method = "onEntityAttributes", at = @At("TAIL"))
+ private void onAttributeUpdate(EntityAttributesS2CPacket packet, CallbackInfo ci) {
+ EntityUpdateEvent.Companion.publish(new EntityUpdateEvent.AttributeUpdate(
+ (LivingEntity) world.getEntityById(packet.getEntityId()), packet.getEntries()));
+ }
+
+ @Inject(method = "onEntityTrackerUpdate", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/data/DataTracker;writeUpdatedEntries(Ljava/util/List;)V", shift = At.Shift.AFTER))
+ private void onEntityTracker(EntityTrackerUpdateS2CPacket packet, CallbackInfo ci, @Local Entity entity) {
+ EntityUpdateEvent.Companion.publish(new EntityUpdateEvent.TrackedDataUpdate(entity, packet.trackedValues()));
+ }
}
diff --git a/src/main/java/moe/nea/firmament/mixins/FirmKeybindsInVanillaControlsPatch.java b/src/main/java/moe/nea/firmament/mixins/FirmKeybindsInVanillaControlsPatch.java
index b386604..699d5b7 100644
--- a/src/main/java/moe/nea/firmament/mixins/FirmKeybindsInVanillaControlsPatch.java
+++ b/src/main/java/moe/nea/firmament/mixins/FirmKeybindsInVanillaControlsPatch.java
@@ -51,7 +51,7 @@ public class FirmKeybindsInVanillaControlsPatch {
var config = FirmamentKeyBindings.INSTANCE.getKeyBindings().get(binding);
if (config == null) return;
resetButton.active = false;
- editButton.setMessage(Text.translatable("firmament.keybinding.external", config.value.format()));
+ editButton.setMessage(Text.translatable("firmament.keybinding.external", config.getValue().format()));
ci.cancel();
}
diff --git a/src/main/java/moe/nea/firmament/mixins/HideStatusEffectsPatch.java b/src/main/java/moe/nea/firmament/mixins/HideStatusEffectsPatch.java
new file mode 100644
index 0000000..c5af8b6
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/HideStatusEffectsPatch.java
@@ -0,0 +1,29 @@
+package moe.nea.firmament.mixins;
+
+import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
+import moe.nea.firmament.features.fixes.Fixes;
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.gui.screen.ingame.InventoryScreen;
+import net.minecraft.client.gui.screen.ingame.StatusEffectsDisplay;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
+
+@Mixin(InventoryScreen.class)
+public abstract class HideStatusEffectsPatch {
+ @Shadow
+ public abstract boolean shouldHideStatusEffectHud();
+
+ @Inject(method = "shouldHideStatusEffectHud", at = @At("HEAD"), cancellable = true)
+ private void hideStatusEffects(CallbackInfoReturnable<Boolean> cir) {
+ cir.setReturnValue(!Fixes.TConfig.INSTANCE.getHidePotionEffects());
+ }
+
+ @WrapWithCondition(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/ingame/StatusEffectsDisplay;drawStatusEffects(Lnet/minecraft/client/gui/DrawContext;IIF)V"))
+ private boolean conditionalRenderStatuses(StatusEffectsDisplay instance, DrawContext context, int mouseX, int mouseY, float tickDelta) {
+ return shouldHideStatusEffectHud() || !Fixes.TConfig.INSTANCE.getHidePotionEffects();
+ }
+
+}
diff --git a/src/main/java/moe/nea/firmament/mixins/HudRenderEventsPatch.java b/src/main/java/moe/nea/firmament/mixins/HudRenderEventsPatch.java
index 85c0462..49e86fb 100644
--- a/src/main/java/moe/nea/firmament/mixins/HudRenderEventsPatch.java
+++ b/src/main/java/moe/nea/firmament/mixins/HudRenderEventsPatch.java
@@ -4,6 +4,7 @@ package moe.nea.firmament.mixins;
import moe.nea.firmament.events.HotbarItemRenderEvent;
import moe.nea.firmament.events.HudRenderEvent;
+import moe.nea.firmament.features.fixes.Fixes;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.hud.InGameHud;
import net.minecraft.client.render.RenderTickCounter;
@@ -26,4 +27,10 @@ public class HudRenderEventsPatch {
if (stack != null && !stack.isEmpty())
HotbarItemRenderEvent.Companion.publish(new HotbarItemRenderEvent(stack, context, x, y, tickCounter));
}
+
+ @Inject(method = "renderStatusEffectOverlay", at = @At("HEAD"), cancellable = true)
+ public void hideStatusEffects(CallbackInfo ci) {
+ if (Fixes.TConfig.INSTANCE.getHidePotionEffectsHud()) ci.cancel();
+ }
+
}
diff --git a/src/main/java/moe/nea/firmament/mixins/IncomingPacketListenerPatches.java b/src/main/java/moe/nea/firmament/mixins/IncomingPacketListenerPatches.java
index 80a9fd5..a7c3875 100644
--- a/src/main/java/moe/nea/firmament/mixins/IncomingPacketListenerPatches.java
+++ b/src/main/java/moe/nea/firmament/mixins/IncomingPacketListenerPatches.java
@@ -18,7 +18,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ClientPlayNetworkHandler.class)
public abstract class IncomingPacketListenerPatches {
-
@ModifyExpressionValue(method = "onCommandTree", at = @At(value = "NEW", target = "(Lcom/mojang/brigadier/tree/RootCommandNode;)Lcom/mojang/brigadier/CommandDispatcher;", remap = false))
public CommandDispatcher onOnCommandTree(CommandDispatcher dispatcher) {
MaskCommands.Companion.publish(new MaskCommands(dispatcher));
@@ -31,7 +30,7 @@ public abstract class IncomingPacketListenerPatches {
packet.getParameters(),
new Vec3d(packet.getX(), packet.getY(), packet.getZ()),
new Vector3f(packet.getOffsetX(), packet.getOffsetY(), packet.getOffsetZ()),
- packet.isLongDistance(),
+ packet.isImportant(),
packet.getCount(),
packet.getSpeed()
);
diff --git a/src/main/java/moe/nea/firmament/mixins/KeyPressInWorldEventPatch.java b/src/main/java/moe/nea/firmament/mixins/KeyPressInWorldEventPatch.java
index 48f3c23..d2b3f91 100644
--- a/src/main/java/moe/nea/firmament/mixins/KeyPressInWorldEventPatch.java
+++ b/src/main/java/moe/nea/firmament/mixins/KeyPressInWorldEventPatch.java
@@ -2,18 +2,19 @@
package moe.nea.firmament.mixins;
+import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
import moe.nea.firmament.events.WorldKeyboardEvent;
import net.minecraft.client.Keyboard;
+import net.minecraft.client.util.InputUtil;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(Keyboard.class)
public class KeyPressInWorldEventPatch {
- @Inject(method = "onKey", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/option/KeyBinding;onKeyPressed(Lnet/minecraft/client/util/InputUtil$Key;)V"))
- public void onKeyBoardInWorld(long window, int key, int scancode, int action, int modifiers, CallbackInfo ci) {
- WorldKeyboardEvent.Companion.publish(new WorldKeyboardEvent(key, scancode, modifiers));
- }
+ @WrapWithCondition(method = "onKey", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/option/KeyBinding;onKeyPressed(Lnet/minecraft/client/util/InputUtil$Key;)V"))
+ public boolean onKeyBoardInWorld(InputUtil.Key key, long window, int _key, int scancode, int action, int modifiers) {
+ var event = WorldKeyboardEvent.Companion.publish(new WorldKeyboardEvent(_key, scancode, modifiers));
+ return !event.getCancelled();
+ }
}
diff --git a/src/main/java/moe/nea/firmament/mixins/LenientProfileComponentPatch.java b/src/main/java/moe/nea/firmament/mixins/LenientProfileComponentPatch.java
deleted file mode 100644
index 76b34ba..0000000
--- a/src/main/java/moe/nea/firmament/mixins/LenientProfileComponentPatch.java
+++ /dev/null
@@ -1,25 +0,0 @@
-
-package moe.nea.firmament.mixins;
-
-import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
-import com.mojang.serialization.Codec;
-import com.mojang.serialization.DataResult;
-import com.mojang.serialization.Lifecycle;
-import com.mojang.util.UndashedUuid;
-import moe.nea.firmament.util.json.FirmCodecs;
-import net.minecraft.component.type.ProfileComponent;
-import net.minecraft.util.Uuids;
-import org.objectweb.asm.Opcodes;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-
-import java.util.UUID;
-
-@Mixin(ProfileComponent.class)
-public class LenientProfileComponentPatch {
- // lambda in RecordCodecBuilder.create for BASE_CODEC
- @ModifyExpressionValue(method = "method_57508", at = @At(value = "FIELD", opcode = Opcodes.GETSTATIC, target = "Lnet/minecraft/util/Uuids;INT_STREAM_CODEC:Lcom/mojang/serialization/Codec;"))
- private static Codec<UUID> onStaticInit(Codec<UUID> original) {
- return FirmCodecs.UUID_LENIENT_PREFER_INT_STREAM;
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/MinecraftInitLevelListener.java b/src/main/java/moe/nea/firmament/mixins/MinecraftInitLevelListener.java
new file mode 100644
index 0000000..1673987
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/MinecraftInitLevelListener.java
@@ -0,0 +1,26 @@
+package moe.nea.firmament.mixins;
+
+import moe.nea.firmament.util.mc.InitLevel;
+import net.minecraft.client.MinecraftClient;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+@Mixin(MinecraftClient.class)
+public class MinecraftInitLevelListener {
+ @Inject(method = "<init>", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;initBackendSystem()Lnet/minecraft/util/TimeSupplier$Nanoseconds;"))
+ private void onInitRenderBackend(CallbackInfo ci) {
+ InitLevel.bump(InitLevel.RENDER_INIT);
+ }
+
+ @Inject(method = "<init>", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;initRenderer(JIZLjava/util/function/BiFunction;Z)V"))
+ private void onInitRender(CallbackInfo ci) {
+ InitLevel.bump(InitLevel.RENDER);
+ }
+
+ @Inject(method = "<init>", at = @At(value = "TAIL"))
+ private void onFinishedLoading(CallbackInfo ci) {
+ InitLevel.bump(InitLevel.MAIN_MENU);
+ }
+}
diff --git a/src/main/java/moe/nea/firmament/mixins/MixinHandledScreen.java b/src/main/java/moe/nea/firmament/mixins/MixinHandledScreen.java
index e607ba3..43aec40 100644
--- a/src/main/java/moe/nea/firmament/mixins/MixinHandledScreen.java
+++ b/src/main/java/moe/nea/firmament/mixins/MixinHandledScreen.java
@@ -4,8 +4,11 @@ package moe.nea.firmament.mixins;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
-import com.llamalad7.mixinextras.sugar.Local;
-import moe.nea.firmament.events.*;
+import moe.nea.firmament.events.HandledScreenClickEvent;
+import moe.nea.firmament.events.HandledScreenForegroundEvent;
+import moe.nea.firmament.events.HandledScreenKeyPressedEvent;
+import moe.nea.firmament.events.IsSlotProtectedEvent;
+import moe.nea.firmament.events.SlotRenderEvents;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.entity.player.PlayerInventory;
@@ -22,9 +25,6 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
-import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
-
-import java.util.Iterator;
@Mixin(value = HandledScreen.class, priority = 990)
public abstract class MixinHandledScreen<T extends ScreenHandler> {
@@ -74,17 +74,17 @@ public abstract class MixinHandledScreen<T extends ScreenHandler> {
public void onMouseClickedSlot(Slot slot, int slotId, int button, SlotActionType actionType, CallbackInfo ci) {
if (slotId == -999 && getScreenHandler() != null && actionType == SlotActionType.PICKUP) { // -999 is code for "clicked outside the main window"
ItemStack cursorStack = getScreenHandler().getCursorStack();
- if (cursorStack != null && IsSlotProtectedEvent.shouldBlockInteraction(slot, SlotActionType.THROW, cursorStack)) {
+ if (cursorStack != null && IsSlotProtectedEvent.shouldBlockInteraction(slot, SlotActionType.THROW, IsSlotProtectedEvent.MoveOrigin.INVENTORY_MOVE, cursorStack)) {
ci.cancel();
return;
}
}
- if (IsSlotProtectedEvent.shouldBlockInteraction(slot, actionType)) {
+ if (IsSlotProtectedEvent.shouldBlockInteraction(slot, actionType, IsSlotProtectedEvent.MoveOrigin.INVENTORY_MOVE)) {
ci.cancel();
return;
}
if (actionType == SlotActionType.SWAP && 0 <= button && button < 9) {
- if (IsSlotProtectedEvent.shouldBlockInteraction(new Slot(playerInventory, button, 0, 0), actionType)) {
+ if (IsSlotProtectedEvent.shouldBlockInteraction(new Slot(playerInventory, button, 0, 0), actionType, IsSlotProtectedEvent.MoveOrigin.INVENTORY_MOVE)) {
ci.cancel();
}
}
diff --git a/src/main/java/moe/nea/firmament/mixins/MixinRecipeBookScreen.java b/src/main/java/moe/nea/firmament/mixins/MixinRecipeBookScreen.java
new file mode 100644
index 0000000..2dbe738
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/MixinRecipeBookScreen.java
@@ -0,0 +1,16 @@
+package moe.nea.firmament.mixins;
+
+import moe.nea.firmament.features.fixes.Fixes;
+import net.minecraft.client.gui.screen.ingame.RecipeBookScreen;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+@Mixin(value = RecipeBookScreen.class, priority = 999)
+public class MixinRecipeBookScreen {
+ @Inject(method = "addRecipeBook", at = @At("HEAD"), cancellable = true)
+ public void addRecipeBook(CallbackInfo ci) {
+ if (Fixes.TConfig.INSTANCE.getHideRecipeBook()) ci.cancel();
+ }
+}
diff --git a/src/main/java/moe/nea/firmament/mixins/PlayerDropEventPatch.java b/src/main/java/moe/nea/firmament/mixins/PlayerDropEventPatch.java
index 9a4626f..f07604e 100644
--- a/src/main/java/moe/nea/firmament/mixins/PlayerDropEventPatch.java
+++ b/src/main/java/moe/nea/firmament/mixins/PlayerDropEventPatch.java
@@ -14,15 +14,15 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(ClientPlayerEntity.class)
public abstract class PlayerDropEventPatch extends PlayerEntity {
- public PlayerDropEventPatch() {
- super(null, null, 0, null);
- }
+ public PlayerDropEventPatch() {
+ super(null, null, 0, null);
+ }
- @Inject(method = "dropSelectedItem", at = @At("HEAD"), cancellable = true)
- public void onDropSelectedItem(boolean entireStack, CallbackInfoReturnable<Boolean> cir) {
- Slot fakeSlot = new Slot(getInventory(), getInventory().selectedSlot, 0, 0);
- if (IsSlotProtectedEvent.shouldBlockInteraction(fakeSlot, SlotActionType.THROW)) {
- cir.setReturnValue(false);
- }
- }
+ @Inject(method = "dropSelectedItem", at = @At("HEAD"), cancellable = true)
+ public void onDropSelectedItem(boolean entireStack, CallbackInfoReturnable<Boolean> cir) {
+ Slot fakeSlot = new Slot(getInventory(), getInventory().getSelectedSlot(), 0, 0);
+ if (IsSlotProtectedEvent.shouldBlockInteraction(fakeSlot, SlotActionType.THROW, IsSlotProtectedEvent.MoveOrigin.DROP_FROM_HOTBAR)) {
+ cir.setReturnValue(false);
+ }
+ }
}
diff --git a/src/main/java/moe/nea/firmament/mixins/PropertySignatureIgnorePatch.java b/src/main/java/moe/nea/firmament/mixins/PropertySignatureIgnorePatch.java
deleted file mode 100644
index e7331c5..0000000
--- a/src/main/java/moe/nea/firmament/mixins/PropertySignatureIgnorePatch.java
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-package moe.nea.firmament.mixins;
-
-import com.mojang.authlib.properties.Property;
-import moe.nea.firmament.features.fixes.Fixes;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
-
-import java.security.PublicKey;
-
-@Mixin(value = Property.class, remap = false)
-public class PropertySignatureIgnorePatch {
- @Inject(method = "isSignatureValid", cancellable = true, at = @At("HEAD"), remap = false)
- public void onValidateSignature(PublicKey publicKey, CallbackInfoReturnable<Boolean> cir) {
- if (Fixes.TConfig.INSTANCE.getFixUnsignedPlayerSkins()) {
- cir.setReturnValue(true);
- }
- }
-
- @Inject(method = "signature", cancellable = true, at = @At("HEAD"), remap = false)
- public void returnEmptySignatureInsteadOfNull(CallbackInfoReturnable<String> cir) {
- if (Fixes.TConfig.INSTANCE.getFixUnsignedPlayerSkins()) {
- cir.setReturnValue("");
- }
- }
-
- @Inject(method = "hasSignature", cancellable = true, at = @At("HEAD"), remap = false)
- public void onHasSignature(CallbackInfoReturnable<Boolean> cir) {
- if (Fixes.TConfig.INSTANCE.getFixUnsignedPlayerSkins()) {
- cir.setReturnValue(true);
- }
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/ReplaceTextColorInHandledScreen.java b/src/main/java/moe/nea/firmament/mixins/ReplaceTextColorInHandledScreen.java
deleted file mode 100644
index c9fb073..0000000
--- a/src/main/java/moe/nea/firmament/mixins/ReplaceTextColorInHandledScreen.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package moe.nea.firmament.mixins;
-
-
-import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
-import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
-import moe.nea.firmament.features.texturepack.CustomTextColors;
-import net.minecraft.client.font.TextRenderer;
-import net.minecraft.client.gui.DrawContext;
-import net.minecraft.client.gui.screen.ingame.AnvilScreen;
-import net.minecraft.client.gui.screen.ingame.BeaconScreen;
-import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
-import net.minecraft.client.gui.screen.ingame.HandledScreen;
-import net.minecraft.client.gui.screen.ingame.InventoryScreen;
-import net.minecraft.client.gui.screen.ingame.MerchantScreen;
-import net.minecraft.text.Text;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-
-@Mixin({HandledScreen.class, InventoryScreen.class, CreativeInventoryScreen.class, MerchantScreen.class,
- AnvilScreen.class, BeaconScreen.class})
-public class ReplaceTextColorInHandledScreen {
-
- // To my future self: double check those mixins, but don't be too concerned about errors. Some of the wrapopertions
- // only apply in some of the specified subclasses.
-
- @WrapOperation(
- method = "drawForeground",
- at = @At(
- value = "INVOKE",
- target = "Lnet/minecraft/client/gui/DrawContext;drawText(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/text/Text;IIIZ)I"),
- expect = 0,
- require = 0)
- private int replaceTextColorWithVariableShadow(DrawContext instance, TextRenderer textRenderer, Text text, int x, int y, int color, boolean shadow, Operation<Integer> original) {
- return original.call(instance, textRenderer, text, x, y, CustomTextColors.INSTANCE.mapTextColor(text, color), shadow);
- }
-
- @WrapOperation(
- method = "drawForeground",
- at = @At(
- value = "INVOKE",
- target = "Lnet/minecraft/client/gui/DrawContext;drawTextWithShadow(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/text/Text;III)I"),
- expect = 0,
- require = 0)
- private int replaceTextColorWithShadow(DrawContext instance, TextRenderer textRenderer, Text text, int x, int y, int color, Operation<Integer> original) {
- return original.call(instance, textRenderer, text, x, y, CustomTextColors.INSTANCE.mapTextColor(text, color));
- }
-
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/SaveOriginalCommandTreePacket.java b/src/main/java/moe/nea/firmament/mixins/SaveOriginalCommandTreePacket.java
new file mode 100644
index 0000000..2f2f188
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/SaveOriginalCommandTreePacket.java
@@ -0,0 +1,17 @@
+package moe.nea.firmament.mixins;
+
+import moe.nea.firmament.features.chat.QuickCommands;
+import net.minecraft.client.network.ClientPlayNetworkHandler;
+import net.minecraft.network.packet.s2c.play.CommandTreeS2CPacket;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+@Mixin(ClientPlayNetworkHandler.class)
+public class SaveOriginalCommandTreePacket {
+ @Inject(method = "onCommandTree", at = @At(value = "RETURN"))
+ private void saveUnmodifiedCommandTree(CommandTreeS2CPacket packet, CallbackInfo ci) {
+ QuickCommands.INSTANCE.setLastReceivedTreePacket(packet);
+ }
+}
diff --git a/src/main/java/moe/nea/firmament/mixins/SlotUpdateListener.java b/src/main/java/moe/nea/firmament/mixins/SlotUpdateListener.java
index 06ecbd4..a4ae931 100644
--- a/src/main/java/moe/nea/firmament/mixins/SlotUpdateListener.java
+++ b/src/main/java/moe/nea/firmament/mixins/SlotUpdateListener.java
@@ -43,11 +43,11 @@ public abstract class SlotUpdateListener extends ClientCommonNetworkHandler {
private void onMultiSlotUpdate(InventoryS2CPacket packet, CallbackInfo ci) {
var player = this.client.player;
assert player != null;
- if (packet.getSyncId() == 0) {
- PlayerInventoryUpdate.Companion.publish(new PlayerInventoryUpdate.Multi(packet.getContents()));
- } else if (packet.getSyncId() == player.currentScreenHandler.syncId) {
+ if (packet.syncId() == 0) {
+ PlayerInventoryUpdate.Companion.publish(new PlayerInventoryUpdate.Multi(packet.contents()));
+ } else if (packet.syncId() == player.currentScreenHandler.syncId) {
ChestInventoryUpdateEvent.Companion.publish(
- new ChestInventoryUpdateEvent.Multi(packet.getContents())
+ new ChestInventoryUpdateEvent.Multi(packet.contents())
);
}
}
diff --git a/src/main/java/moe/nea/firmament/mixins/SoundReceiveEventPatch.java b/src/main/java/moe/nea/firmament/mixins/SoundReceiveEventPatch.java
index 5c52d70..b8cba80 100644
--- a/src/main/java/moe/nea/firmament/mixins/SoundReceiveEventPatch.java
+++ b/src/main/java/moe/nea/firmament/mixins/SoundReceiveEventPatch.java
@@ -1,30 +1,32 @@
package moe.nea.firmament.mixins;
+import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
import moe.nea.firmament.events.SoundReceiveEvent;
import net.minecraft.client.network.ClientPlayNetworkHandler;
-import net.minecraft.network.packet.s2c.play.PlaySoundS2CPacket;
+import net.minecraft.client.world.ClientWorld;
+import net.minecraft.entity.Entity;
+import net.minecraft.registry.entry.RegistryEntry;
+import net.minecraft.sound.SoundCategory;
+import net.minecraft.sound.SoundEvent;
import net.minecraft.util.math.Vec3d;
+import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ClientPlayNetworkHandler.class)
public class SoundReceiveEventPatch {
- @Inject(method = "onPlaySound", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;playSound(Lnet/minecraft/entity/player/PlayerEntity;DDDLnet/minecraft/registry/entry/RegistryEntry;Lnet/minecraft/sound/SoundCategory;FFJ)V"), cancellable = true)
- private void postEventWhenSoundIsPlayed(PlaySoundS2CPacket packet, CallbackInfo ci) {
+ @WrapWithCondition(method = "onPlaySound", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;playSound(Lnet/minecraft/entity/Entity;DDDLnet/minecraft/registry/entry/RegistryEntry;Lnet/minecraft/sound/SoundCategory;FFJ)V"))
+ private boolean postEventWhenSoundIsPlayed(ClientWorld instance, @Nullable Entity source, double x, double y, double z, RegistryEntry<SoundEvent> sound, SoundCategory category, float volume, float pitch, long seed) {
var event = new SoundReceiveEvent(
- packet.getSound(),
- packet.getCategory(),
- new Vec3d(packet.getX(), packet.getY(), packet.getZ()),
- packet.getPitch(),
- packet.getVolume(),
- packet.getSeed()
+ sound,
+ category,
+ new Vec3d(x,y,z),
+ pitch,
+ volume,
+ seed
);
SoundReceiveEvent.Companion.publish(event);
- if (event.getCancelled()) {
- ci.cancel();
- }
+ return !event.getCancelled();
}
}
diff --git a/src/main/java/moe/nea/firmament/mixins/TolerateFirmamentTolerateRegistryOwners.java b/src/main/java/moe/nea/firmament/mixins/TolerateFirmamentTolerateRegistryOwners.java
new file mode 100644
index 0000000..ac6f614
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/TolerateFirmamentTolerateRegistryOwners.java
@@ -0,0 +1,18 @@
+package moe.nea.firmament.mixins;
+
+import moe.nea.firmament.util.mc.TolerantRegistriesOps;
+import net.minecraft.registry.entry.RegistryEntryOwner;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
+
+@Mixin(RegistryEntryOwner.class)
+public interface TolerateFirmamentTolerateRegistryOwners<T> {
+ @Inject(method = "ownerEquals", at = @At("HEAD"), cancellable = true)
+ private void equalTolerantRegistryOwners(RegistryEntryOwner<T> other, CallbackInfoReturnable<Boolean> cir) {
+ if (other instanceof TolerantRegistriesOps.TolerantOwner<?>) {
+ cir.setReturnValue(true);
+ }
+ }
+}
diff --git a/src/main/java/moe/nea/firmament/mixins/WorldRenderLastEventPatch.java b/src/main/java/moe/nea/firmament/mixins/WorldRenderLastEventPatch.java
index 847fb4d..3ed8c1b 100644
--- a/src/main/java/moe/nea/firmament/mixins/WorldRenderLastEventPatch.java
+++ b/src/main/java/moe/nea/firmament/mixins/WorldRenderLastEventPatch.java
@@ -2,11 +2,9 @@
package moe.nea.firmament.mixins;
-import com.llamalad7.mixinextras.sugar.Local;
import moe.nea.firmament.events.WorldRenderLastEvent;
import net.minecraft.client.render.*;
import net.minecraft.client.util.Handle;
-import net.minecraft.client.util.ObjectAllocator;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.profiler.Profiler;
import org.joml.Matrix4f;
@@ -31,12 +29,12 @@ public abstract class WorldRenderLastEventPatch {
protected abstract void checkEmpty(MatrixStack matrices);
@Inject(method = "method_62214", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/profiler/Profiler;pop()V", shift = At.Shift.AFTER))
- public void onWorldRenderLast(Fog fog, RenderTickCounter tickCounter, Camera camera, Profiler profiler, Matrix4f matrix4f, Matrix4f matrix4f2, Handle handle, Handle handle2, Handle handle3, Handle handle4, boolean bl, Frustum frustum, Handle handle5, CallbackInfo ci) {
+ public void onWorldRenderLast(Fog fog, RenderTickCounter renderTickCounter, Camera camera, Profiler profiler, Matrix4f matrix4f, Matrix4f matrix4f2, Handle handle, Handle handle2, boolean bl, Frustum frustum, Handle handle3, Handle handle4, CallbackInfo ci) {
var imm = this.bufferBuilders.getEntityVertexConsumers();
var stack = new MatrixStack();
// TODO: pre-cancel this event if F1 is active
var event = new WorldRenderLastEvent(
- stack, tickCounter,
+ stack, renderTickCounter,
camera,
imm
);
diff --git a/src/main/java/moe/nea/firmament/mixins/accessor/AccessorChatHud.java b/src/main/java/moe/nea/firmament/mixins/accessor/AccessorChatHud.java
index 72a72f0..d164aac 100644
--- a/src/main/java/moe/nea/firmament/mixins/accessor/AccessorChatHud.java
+++ b/src/main/java/moe/nea/firmament/mixins/accessor/AccessorChatHud.java
@@ -4,6 +4,7 @@ import net.minecraft.client.gui.hud.ChatHud;
import net.minecraft.client.gui.hud.ChatHudLine;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
+import org.spongepowered.asm.mixin.gen.Invoker;
import java.util.List;
@@ -11,4 +12,13 @@ import java.util.List;
public interface AccessorChatHud {
@Accessor("messages")
List<ChatHudLine> getMessages_firmament();
+
+ @Accessor("visibleMessages")
+ List<ChatHudLine.Visible> getVisibleMessages_firmament();
+
+ @Accessor("scrolledLines")
+ int getScrolledLines_firmament();
+
+ @Invoker("toChatLineY")
+ double toChatLineY_firmament(double y);
}
diff --git a/src/main/java/moe/nea/firmament/mixins/accessor/AccessorHandledScreen.java b/src/main/java/moe/nea/firmament/mixins/accessor/AccessorHandledScreen.java
index 7ed04b1..f55ef4f 100644
--- a/src/main/java/moe/nea/firmament/mixins/accessor/AccessorHandledScreen.java
+++ b/src/main/java/moe/nea/firmament/mixins/accessor/AccessorHandledScreen.java
@@ -1,5 +1,3 @@
-
-
package moe.nea.firmament.mixins.accessor;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
diff --git a/src/main/java/moe/nea/firmament/mixins/accessor/AccessorPlayerListHud.java b/src/main/java/moe/nea/firmament/mixins/accessor/AccessorPlayerListHud.java
new file mode 100644
index 0000000..81ea0fd
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/accessor/AccessorPlayerListHud.java
@@ -0,0 +1,31 @@
+package moe.nea.firmament.mixins.accessor;
+
+import net.minecraft.client.gui.hud.PlayerListHud;
+import net.minecraft.client.network.PlayerListEntry;
+import net.minecraft.text.Text;
+import org.jetbrains.annotations.Nullable;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Accessor;
+import org.spongepowered.asm.mixin.gen.Invoker;
+
+import java.util.Comparator;
+import java.util.List;
+
+@Mixin(PlayerListHud.class)
+public interface AccessorPlayerListHud {
+
+ @Accessor("ENTRY_ORDERING")
+ static Comparator<PlayerListEntry> getEntryOrdering() {
+ throw new AssertionError();
+ }
+
+ @Invoker("collectPlayerEntries")
+ List<PlayerListEntry> collectPlayerEntries_firmament();
+
+ @Accessor("footer")
+ @Nullable Text getFooter_firmament();
+
+ @Accessor("header")
+ @Nullable Text getHeader_firmament();
+
+}
diff --git a/src/main/java/moe/nea/firmament/mixins/accessor/AccessorWorldRenderer.java b/src/main/java/moe/nea/firmament/mixins/accessor/AccessorWorldRenderer.java
new file mode 100644
index 0000000..8b25562
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/accessor/AccessorWorldRenderer.java
@@ -0,0 +1,17 @@
+package moe.nea.firmament.mixins.accessor;
+
+import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
+import net.minecraft.client.render.WorldRenderer;
+import net.minecraft.entity.player.BlockBreakingInfo;
+import org.jetbrains.annotations.NotNull;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Accessor;
+
+import java.util.SortedSet;
+
+@Mixin(WorldRenderer.class)
+public interface AccessorWorldRenderer {
+ @Accessor("blockBreakingProgressions")
+ @NotNull
+ Long2ObjectMap<SortedSet<BlockBreakingInfo>> getBlockBreakingProgressions_firmament();
+}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/ApplyHeadModelInItemRenderer.java b/src/main/java/moe/nea/firmament/mixins/custommodels/ApplyHeadModelInItemRenderer.java
deleted file mode 100644
index dac65fe..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/ApplyHeadModelInItemRenderer.java
+++ /dev/null
@@ -1,35 +0,0 @@
-
-package moe.nea.firmament.mixins.custommodels;
-
-import com.llamalad7.mixinextras.sugar.Local;
-import com.llamalad7.mixinextras.sugar.ref.LocalRef;
-import moe.nea.firmament.features.texturepack.BakedModelExtra;
-import net.minecraft.client.render.VertexConsumerProvider;
-import net.minecraft.client.render.item.ItemRenderer;
-import net.minecraft.client.render.model.BakedModel;
-import net.minecraft.client.util.math.MatrixStack;
-import net.minecraft.item.ItemStack;
-import net.minecraft.item.ModelTransformationMode;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-
-@Mixin(ItemRenderer.class)
-public class ApplyHeadModelInItemRenderer {
- @Inject(method = "renderItem(Lnet/minecraft/item/ItemStack;Lnet/minecraft/item/ModelTransformationMode;ZLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;IILnet/minecraft/client/render/model/BakedModel;ZF)V",
- at = @At("HEAD"))
- private void applyHeadModel(ItemStack stack, ModelTransformationMode transformationMode, boolean leftHanded,
- MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay,
- BakedModel model, boolean useInventoryModel, float z, CallbackInfo ci,
- @Local(argsOnly = true) LocalRef<BakedModel> modelMut
- ) {
- var extra = BakedModelExtra.cast(model);
- if (transformationMode == ModelTransformationMode.HEAD && extra != null) {
- var headModel = extra.getHeadModel_firmament();
- if (headModel != null) {
- modelMut.set(headModel);
- }
- }
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/BakedModelDataHolderBasic.java b/src/main/java/moe/nea/firmament/mixins/custommodels/BakedModelDataHolderBasic.java
deleted file mode 100644
index 3ed2177..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/BakedModelDataHolderBasic.java
+++ /dev/null
@@ -1,42 +0,0 @@
-
-package moe.nea.firmament.mixins.custommodels;
-
-import moe.nea.firmament.features.texturepack.BakedModelExtra;
-import moe.nea.firmament.features.texturepack.TintOverrides;
-import net.minecraft.client.render.model.BakedModel;
-import net.minecraft.client.render.model.BasicBakedModel;
-import org.jetbrains.annotations.Nullable;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Unique;
-
-@Mixin(BasicBakedModel.class)
-public class BakedModelDataHolderBasic implements BakedModelExtra {
-
- @Unique
- private BakedModel headModel;
-
- @Unique
- @Nullable
- private TintOverrides tintOverrides;
-
- @Nullable
- @Override
- public BakedModel getHeadModel_firmament() {
- return headModel;
- }
-
- @Override
- public void setHeadModel_firmament(@Nullable BakedModel headModel) {
- this.headModel = headModel;
- }
-
- @Override
- public @Nullable TintOverrides getTintOverrides_firmament() {
- return tintOverrides;
- }
-
- @Override
- public void setTintOverrides_firmament(@Nullable TintOverrides tintOverrides) {
- this.tintOverrides = tintOverrides;
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/BakedModelDataHolderBuiltin.java b/src/main/java/moe/nea/firmament/mixins/custommodels/BakedModelDataHolderBuiltin.java
deleted file mode 100644
index 87aecb1..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/BakedModelDataHolderBuiltin.java
+++ /dev/null
@@ -1,43 +0,0 @@
-
-package moe.nea.firmament.mixins.custommodels;
-
-import moe.nea.firmament.features.texturepack.BakedModelExtra;
-import moe.nea.firmament.features.texturepack.TintOverrides;
-import net.minecraft.client.render.model.BakedModel;
-import net.minecraft.client.render.model.BuiltinBakedModel;
-import org.jetbrains.annotations.Nullable;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Unique;
-
-@Mixin(BuiltinBakedModel.class)
-public class BakedModelDataHolderBuiltin implements BakedModelExtra {
-
- @Unique
- @Nullable
- private BakedModel headModel;
-
- @Unique
- @Nullable
- private TintOverrides tintOverrides;
-
- @Override
- public @Nullable TintOverrides getTintOverrides_firmament() {
- return tintOverrides;
- }
-
- @Override
- public void setTintOverrides_firmament(@Nullable TintOverrides tintOverrides) {
- this.tintOverrides = tintOverrides;
- }
-
- @Nullable
- @Override
- public BakedModel getHeadModel_firmament() {
- return headModel;
- }
-
- @Override
- public void setHeadModel_firmament(@Nullable BakedModel headModel) {
- this.headModel = headModel;
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/BakedOverrideDataHolder.java b/src/main/java/moe/nea/firmament/mixins/custommodels/BakedOverrideDataHolder.java
deleted file mode 100644
index 26972b1..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/BakedOverrideDataHolder.java
+++ /dev/null
@@ -1,28 +0,0 @@
-
-package moe.nea.firmament.mixins.custommodels;
-
-import moe.nea.firmament.features.texturepack.BakedOverrideData;
-import moe.nea.firmament.features.texturepack.FirmamentModelPredicate;
-import net.minecraft.client.render.model.json.ModelOverrideList;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Unique;
-
-@Mixin(ModelOverrideList.BakedOverride.class)
-public class BakedOverrideDataHolder implements BakedOverrideData {
-
- @Unique
- private FirmamentModelPredicate[] firmamentOverrides;
-
- @Nullable
- @Override
- public FirmamentModelPredicate[] getFirmamentOverrides() {
- return firmamentOverrides;
- }
-
- @Override
- public void setFirmamentOverrides(@NotNull FirmamentModelPredicate[] overrides) {
- this.firmamentOverrides = overrides;
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/HeadModelReplacerPatch.java b/src/main/java/moe/nea/firmament/mixins/custommodels/HeadModelReplacerPatch.java
deleted file mode 100644
index 26c331e..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/HeadModelReplacerPatch.java
+++ /dev/null
@@ -1,57 +0,0 @@
-
-package moe.nea.firmament.mixins.custommodels;
-
-import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
-import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
-import com.llamalad7.mixinextras.sugar.Local;
-import moe.nea.firmament.features.texturepack.BakedModelExtra;
-import net.minecraft.block.AbstractSkullBlock;
-import net.minecraft.block.Block;
-import net.minecraft.block.Blocks;
-import net.minecraft.client.render.VertexConsumerProvider;
-import net.minecraft.client.render.entity.LivingEntityRenderer;
-import net.minecraft.client.render.entity.feature.HeadFeatureRenderer;
-import net.minecraft.client.render.entity.model.EntityModel;
-import net.minecraft.client.render.entity.model.ModelWithHead;
-import net.minecraft.client.render.entity.state.LivingEntityRenderState;
-import net.minecraft.client.render.model.BakedModel;
-import net.minecraft.client.util.math.MatrixStack;
-import net.minecraft.entity.EquipmentSlot;
-import net.minecraft.item.BlockItem;
-import net.minecraft.item.ItemStack;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-
-@Mixin(HeadFeatureRenderer.class)
-public class HeadModelReplacerPatch<S extends LivingEntityRenderState, M extends EntityModel<S> & ModelWithHead> {
- /**
- * This class serves to disable the replacing of head models with the vanilla block model. Vanilla first selects loads
- * the model containing the head model regularly in {@link LivingEntityRenderer#updateRenderState}, but then discards
- * the model in {@link HeadFeatureRenderer#render(MatrixStack, VertexConsumerProvider, int, LivingEntityRenderState, float, float)}
- * if it detects a skull block. This serves to disable that functionality if a head model override is present.
- */
- @WrapOperation(method = "render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/client/render/entity/state/LivingEntityRenderState;FF)V",
- at = @At(value = "INVOKE", target = "Lnet/minecraft/item/BlockItem;getBlock()Lnet/minecraft/block/Block;"))
- private Block replaceSkull(BlockItem instance, Operation<Block> original, @Local BakedModel bakedModel) {
- var oldBlock = original.call(instance);
- if (oldBlock instanceof AbstractSkullBlock) {
- var extra = BakedModelExtra.cast(bakedModel);
- if (extra != null && extra.getHeadModel_firmament() != null)
- return Blocks.ENCHANTING_TABLE; // Any non skull block. Let's choose the enchanting table because it is very distinct.
- }
- return oldBlock;
- }
-
- /**
- * We disable the has model override, since texture packs get precedent to server data.
- */
- @WrapOperation(method = "render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/client/render/entity/state/LivingEntityRenderState;FF)V",
- at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/entity/feature/ArmorFeatureRenderer;hasModel(Lnet/minecraft/item/ItemStack;Lnet/minecraft/entity/EquipmentSlot;)Z"))
- private boolean replaceHasModel(ItemStack stack, EquipmentSlot slot, Operation<Boolean> original,
- @Local BakedModel bakedModel) {
- var extra = BakedModelExtra.cast(bakedModel);
- if (extra != null && extra.getHeadModel_firmament() != null)
- return false;
- return original.call(stack, slot);
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/ItemColorRemovalPatch.java b/src/main/java/moe/nea/firmament/mixins/custommodels/ItemColorRemovalPatch.java
deleted file mode 100644
index 8c76c60..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/ItemColorRemovalPatch.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package moe.nea.firmament.mixins.custommodels;
-
-import moe.nea.firmament.features.texturepack.TintOverrides;
-import moe.nea.firmament.init.ItemColorsSodiumRiser;
-import net.minecraft.client.color.item.ItemColorProvider;
-import net.minecraft.client.color.item.ItemColors;
-import net.minecraft.item.ItemStack;
-import org.jetbrains.annotations.Nullable;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
-
-@Mixin(ItemColors.class)
-public class ItemColorRemovalPatch {
-
- /**
- * @see ItemColorsSodiumRiser
- */
- private @Nullable ItemColorProvider overrideSodium_firmament(@Nullable ItemColorProvider original) {
- var tintOverrides = TintOverrides.Companion.getCurrentOverrides();
- if (!tintOverrides.hasOverrides()) return original;
- return (stack, tintIndex) -> {
- var override = tintOverrides.getOverride(tintIndex);
- if (override != null) return override;
- if (original != null) return original.getColor(stack, tintIndex);
- return -1;
- };
- }
-
-
- @Inject(method = "getColor", at = @At("HEAD"), cancellable = true)
- private void overrideGetColorCall(ItemStack item, int tintIndex, CallbackInfoReturnable<Integer> cir) {
- var tintOverrides = TintOverrides.Companion.getCurrentOverrides();
- var override = tintOverrides.getOverride(tintIndex);
- if (override != null)
- cir.setReturnValue(override);
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/ItemModelGeneratorJsonUnbakedModelCopy.java b/src/main/java/moe/nea/firmament/mixins/custommodels/ItemModelGeneratorJsonUnbakedModelCopy.java
deleted file mode 100644
index 89d0411..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/ItemModelGeneratorJsonUnbakedModelCopy.java
+++ /dev/null
@@ -1,22 +0,0 @@
-
-package moe.nea.firmament.mixins.custommodels;
-
-import com.llamalad7.mixinextras.injector.ModifyReturnValue;
-import com.llamalad7.mixinextras.sugar.Local;
-import moe.nea.firmament.features.texturepack.JsonUnbakedModelFirmExtra;
-import net.minecraft.client.render.model.json.ItemModelGenerator;
-import net.minecraft.client.render.model.json.JsonUnbakedModel;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-
-@Mixin(ItemModelGenerator.class)
-public class ItemModelGeneratorJsonUnbakedModelCopy {
- @ModifyReturnValue(method = "create", at = @At("RETURN"))
- private JsonUnbakedModel copyExtraModelData(JsonUnbakedModel original, @Local(argsOnly = true) JsonUnbakedModel oldModel) {
- var extra = ((JsonUnbakedModelFirmExtra) original);
- var oldExtra = ((JsonUnbakedModelFirmExtra) oldModel);
- extra.setHeadModel_firmament(oldExtra.getHeadModel_firmament());
- extra.setTintOverrides_firmament(oldExtra.getTintOverrides_firmament());
- return original;
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/ItemRendererTintContextPatch.java b/src/main/java/moe/nea/firmament/mixins/custommodels/ItemRendererTintContextPatch.java
deleted file mode 100644
index 8c5411b..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/ItemRendererTintContextPatch.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package moe.nea.firmament.mixins.custommodels;
-
-import moe.nea.firmament.features.texturepack.BakedModelExtra;
-import moe.nea.firmament.features.texturepack.TintOverrides;
-import net.minecraft.client.render.VertexConsumerProvider;
-import net.minecraft.client.render.item.ItemRenderer;
-import net.minecraft.client.render.model.BakedModel;
-import net.minecraft.client.util.math.MatrixStack;
-import net.minecraft.item.ItemStack;
-import net.minecraft.item.ModelTransformationMode;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-
-@Mixin(value = ItemRenderer.class, priority = 1010)
-public class ItemRendererTintContextPatch {
- @Inject(method = "renderItem(Lnet/minecraft/item/ItemStack;Lnet/minecraft/item/ModelTransformationMode;ZLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;IILnet/minecraft/client/render/model/BakedModel;ZF)V",
- at = @At(value = "HEAD"), allow = 1)
- private void onStartRendering(ItemStack stack, ModelTransformationMode transformationMode, boolean leftHanded, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, BakedModel model, boolean useInventoryModel, float z, CallbackInfo ci) {
- var extra = BakedModelExtra.cast(model);
- if (extra != null) {
- TintOverrides.Companion.enter(extra.getTintOverrides_firmament());
- }
- }
-
- @Inject(method = "renderItem(Lnet/minecraft/item/ItemStack;Lnet/minecraft/item/ModelTransformationMode;ZLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;IILnet/minecraft/client/render/model/BakedModel;ZF)V",
- at = @At("TAIL"), allow = 1)
- private void onEndRendering(ItemStack stack, ModelTransformationMode transformationMode, boolean leftHanded, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, BakedModel model, boolean useInventoryModel, float z, CallbackInfo ci) {
- var extra = BakedModelExtra.cast(model);
- if (extra != null) {
- TintOverrides.Companion.exit(extra.getTintOverrides_firmament());
- }
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/JsonUnbakedModelDataHolder.java b/src/main/java/moe/nea/firmament/mixins/custommodels/JsonUnbakedModelDataHolder.java
deleted file mode 100644
index a5bb34f..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/JsonUnbakedModelDataHolder.java
+++ /dev/null
@@ -1,130 +0,0 @@
-package moe.nea.firmament.mixins.custommodels;
-
-import com.llamalad7.mixinextras.injector.ModifyReturnValue;
-import com.llamalad7.mixinextras.sugar.Local;
-import moe.nea.firmament.features.texturepack.BakedModelExtra;
-import moe.nea.firmament.features.texturepack.JsonUnbakedModelFirmExtra;
-import moe.nea.firmament.features.texturepack.TintOverrides;
-import moe.nea.firmament.util.ErrorUtil;
-import net.minecraft.client.render.model.BakedModel;
-import net.minecraft.client.render.model.Baker;
-import net.minecraft.client.render.model.ModelRotation;
-import net.minecraft.client.render.model.UnbakedModel;
-import net.minecraft.client.render.model.json.JsonUnbakedModel;
-import net.minecraft.util.Identifier;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
-import org.spongepowered.asm.mixin.Unique;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-
-import java.util.Objects;
-
-@Mixin(JsonUnbakedModel.class)
-public abstract class JsonUnbakedModelDataHolder implements JsonUnbakedModelFirmExtra {
- @Shadow
- @Nullable
- protected JsonUnbakedModel parent;
-
- @Shadow
- public abstract String toString();
-
- @Unique
- @Nullable
- public Identifier headModel;
- @Unique
- @Nullable
- public TintOverrides tintOverrides;
- @Unique
- @Nullable
- public TintOverrides mergedTintOverrides;
-
- @Override
- public void setTintOverrides_firmament(@Nullable TintOverrides tintOverrides) {
- this.tintOverrides = tintOverrides;
- this.mergedTintOverrides = null;
- }
-
- @Override
- public @NotNull TintOverrides getTintOverrides_firmament() {
- if (mergedTintOverrides != null)
- return mergedTintOverrides;
- var mergedTintOverrides = parent == null ? new TintOverrides()
- : ((JsonUnbakedModelFirmExtra) parent).getTintOverrides_firmament();
- if (tintOverrides != null)
- mergedTintOverrides = tintOverrides.mergeWithParent(mergedTintOverrides);
- this.mergedTintOverrides = mergedTintOverrides;
- return mergedTintOverrides;
- }
-
- @Override
- public void setHeadModel_firmament(@Nullable Identifier identifier) {
- this.headModel = identifier;
- }
-
- @Override
- public @Nullable Identifier getHeadModel_firmament() {
- if (this.headModel != null) return this.headModel;
- if (this.parent == null) return null;
- return ((JsonUnbakedModelFirmExtra) this.parent).getHeadModel_firmament();
- }
-
- @Inject(method = "resolve", at = @At("HEAD"))
- private void addDependencies(UnbakedModel.Resolver resolver, CallbackInfo ci) {
- var headModel = getHeadModel_firmament();
- if (headModel != null) {
- resolver.resolve(headModel);
- }
- }
-
- private void addExtraBakeInfo(BakedModel bakedModel, Baker baker) {
- if (!this.toString().contains("minecraft") && this.toString().contains("crimson")) {
- System.out.println("Found non minecraft model " + this);
- }
- var extra = BakedModelExtra.cast(bakedModel);
- if (extra != null) {
- var headModel = getHeadModel_firmament();
- if (headModel != null) {
- extra.setHeadModel_firmament(baker.bake(headModel, ModelRotation.X0_Y0));
- }
- if (getTintOverrides_firmament().hasOverrides()) {
- extra.setTintOverrides_firmament(getTintOverrides_firmament());
- }
- }
- }
-
- /**
- * @see ProvideBakerToJsonUnbakedModelPatch
- */
- @Override
- public void storeExtraBaker_firmament(@NotNull Baker baker) {
- this.storedBaker = baker;
- }
-
- @Unique
- private Baker storedBaker;
-
- @ModifyReturnValue(
- method = "bake(Ljava/util/function/Function;Lnet/minecraft/client/render/model/ModelBakeSettings;Z)Lnet/minecraft/client/render/model/BakedModel;",
- at = @At("RETURN"))
- private BakedModel bakeExtraInfoWithoutBaker(BakedModel original) {
- if (storedBaker != null) {
- addExtraBakeInfo(original, storedBaker);
- storedBaker = null;
- }
- return original;
- }
-
- @ModifyReturnValue(
- method = {
- "bake(Lnet/minecraft/client/render/model/Baker;Ljava/util/function/Function;Lnet/minecraft/client/render/model/ModelBakeSettings;)Lnet/minecraft/client/render/model/BakedModel;"
- },
- at = @At(value = "RETURN"))
- private BakedModel bakeExtraInfo(BakedModel original, @Local(argsOnly = true) Baker baker) {
- addExtraBakeInfo(original, baker);
- return original;
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/ModelOverrideDataHolder.java b/src/main/java/moe/nea/firmament/mixins/custommodels/ModelOverrideDataHolder.java
deleted file mode 100644
index 5f9689a..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/ModelOverrideDataHolder.java
+++ /dev/null
@@ -1,28 +0,0 @@
-
-package moe.nea.firmament.mixins.custommodels;
-
-import moe.nea.firmament.features.texturepack.FirmamentModelPredicate;
-import moe.nea.firmament.features.texturepack.ModelOverrideData;
-import net.minecraft.client.render.model.json.ModelOverride;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Unique;
-
-@Mixin(ModelOverride.class)
-public class ModelOverrideDataHolder implements ModelOverrideData {
-
- @Unique
- private FirmamentModelPredicate[] overrides;
-
- @Nullable
- @Override
- public FirmamentModelPredicate[] getFirmamentOverrides() {
- return overrides;
- }
-
- @Override
- public void setFirmamentOverrides(@NotNull FirmamentModelPredicate[] overrides) {
- this.overrides = overrides;
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/PatchArmorTexture.java b/src/main/java/moe/nea/firmament/mixins/custommodels/PatchArmorTexture.java
deleted file mode 100644
index 4468150..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/PatchArmorTexture.java
+++ /dev/null
@@ -1,29 +0,0 @@
-
-package moe.nea.firmament.mixins.custommodels;
-
-import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
-import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
-import com.llamalad7.mixinextras.sugar.Local;
-import moe.nea.firmament.features.texturepack.CustomGlobalArmorOverrides;
-import net.minecraft.client.render.entity.feature.ArmorFeatureRenderer;
-import net.minecraft.component.type.EquippableComponent;
-import net.minecraft.item.ItemStack;
-import net.minecraft.util.Identifier;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-
-import java.util.Optional;
-
-@Mixin(ArmorFeatureRenderer.class)
-public class PatchArmorTexture {
- @WrapOperation(
- method = "renderArmor",
- at = @At(value = "INVOKE", target = "Lnet/minecraft/component/type/EquippableComponent;model()Ljava/util/Optional;"))
- private Optional<Identifier> overrideLayers(
- EquippableComponent instance, Operation<Optional<Identifier>> original, @Local(argsOnly = true) ItemStack itemStack
- ) {
- // TODO: check that all armour items are naturally equippable and have the equppable component. otherwise our call here will not be reached.
- var overrides = CustomGlobalArmorOverrides.overrideArmor(itemStack);
- return overrides.or(() -> original.call(instance));
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/PatchJsonUnbakedModelDeserializer.java b/src/main/java/moe/nea/firmament/mixins/custommodels/PatchJsonUnbakedModelDeserializer.java
deleted file mode 100644
index d6c25b5..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/PatchJsonUnbakedModelDeserializer.java
+++ /dev/null
@@ -1,31 +0,0 @@
-
-package moe.nea.firmament.mixins.custommodels;
-
-import com.google.gson.JsonObject;
-import com.google.gson.JsonPrimitive;
-import com.llamalad7.mixinextras.injector.ModifyReturnValue;
-import com.llamalad7.mixinextras.sugar.Local;
-import moe.nea.firmament.features.texturepack.JsonUnbakedModelFirmExtra;
-import moe.nea.firmament.features.texturepack.TintOverrides;
-import net.minecraft.client.render.model.json.JsonUnbakedModel;
-import net.minecraft.util.Identifier;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-
-@Mixin(JsonUnbakedModel.Deserializer.class)
-public class PatchJsonUnbakedModelDeserializer {
- @ModifyReturnValue(method = "deserialize(Lcom/google/gson/JsonElement;Ljava/lang/reflect/Type;Lcom/google/gson/JsonDeserializationContext;)Lnet/minecraft/client/render/model/json/JsonUnbakedModel;",
- at = @At("RETURN"))
- private JsonUnbakedModel addHeadModel(JsonUnbakedModel original, @Local JsonObject jsonObject) {
- var headModel = jsonObject.get("firmament:head_model");
- var extra = ((JsonUnbakedModelFirmExtra) original);
- if (headModel instanceof JsonPrimitive prim && prim.isString()) {
- extra.setHeadModel_firmament(Identifier.of(prim.getAsString()));
- }
- var tintOverrides = jsonObject.get("firmament:tint_overrides");
- if (tintOverrides instanceof JsonObject object) {
- extra.setTintOverrides_firmament(TintOverrides.Companion.parse(object));
- }
- return original;
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/PatchLegacyArmorLayerSupport.java b/src/main/java/moe/nea/firmament/mixins/custommodels/PatchLegacyArmorLayerSupport.java
deleted file mode 100644
index 8c0b3f8..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/PatchLegacyArmorLayerSupport.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package moe.nea.firmament.mixins.custommodels;
-
-import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
-import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
-import moe.nea.firmament.features.texturepack.CustomGlobalArmorOverrides;
-import net.minecraft.client.render.entity.equipment.EquipmentModelLoader;
-import net.minecraft.client.render.entity.equipment.EquipmentRenderer;
-import net.minecraft.item.equipment.EquipmentModel;
-import net.minecraft.util.Identifier;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-
-@Mixin(EquipmentRenderer.class)
-public class PatchLegacyArmorLayerSupport {
- @WrapOperation(method = "render(Lnet/minecraft/item/equipment/EquipmentModel$LayerType;Lnet/minecraft/util/Identifier;Lnet/minecraft/client/model/Model;Lnet/minecraft/item/ItemStack;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/util/Identifier;)V",
- at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/entity/equipment/EquipmentModelLoader;get(Lnet/minecraft/util/Identifier;)Lnet/minecraft/item/equipment/EquipmentModel;"))
- private EquipmentModel patchModelLayers(EquipmentModelLoader instance, Identifier id, Operation<EquipmentModel> original) {
- var modelOverride = CustomGlobalArmorOverrides.overrideArmorLayer(id);
- if (modelOverride != null) return modelOverride;
- return original.call(instance, id);
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/PatchOverrideDeserializer.java b/src/main/java/moe/nea/firmament/mixins/custommodels/PatchOverrideDeserializer.java
deleted file mode 100644
index abb1792..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/PatchOverrideDeserializer.java
+++ /dev/null
@@ -1,50 +0,0 @@
-
-package moe.nea.firmament.mixins.custommodels;
-
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonPrimitive;
-import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
-import com.llamalad7.mixinextras.injector.ModifyReturnValue;
-import com.llamalad7.mixinextras.sugar.Local;
-import moe.nea.firmament.features.texturepack.CustomModelOverrideParser;
-import moe.nea.firmament.features.texturepack.ModelOverrideData;
-import net.minecraft.client.render.model.json.ModelOverride;
-import net.minecraft.util.Identifier;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
-
-import java.util.List;
-import java.util.Map;
-
-@Mixin(ModelOverride.Deserializer.class)
-public class PatchOverrideDeserializer {
-
- @ModifyReturnValue(
- method = "deserialize(Lcom/google/gson/JsonElement;Ljava/lang/reflect/Type;Lcom/google/gson/JsonDeserializationContext;)Lnet/minecraft/client/render/model/json/ModelOverride;",
- at = @At(value = "RETURN"))
- private ModelOverride addCustomOverrides(ModelOverride original, @Local JsonObject jsonObject) {
- var originalData = (ModelOverrideData) (Object) original;
- originalData.setFirmamentOverrides(CustomModelOverrideParser.parseCustomModelOverrides(jsonObject));
- return original;
- }
-
- @ModifyExpressionValue(
- method = "deserializeMinPropertyValues(Lcom/google/gson/JsonObject;)Ljava/util/List;",
- at = @At(value = "INVOKE", target = "Ljava/util/Map$Entry;getValue()Ljava/lang/Object;"))
- private Object removeFirmamentPredicatesFromJsonIteration(Object original, @Local Map.Entry<String, JsonElement> entry) {
- if (entry.getKey().startsWith("firmament:")) return new JsonPrimitive(0F);
- return original;
- }
-
- @Inject(
- method = "deserializeMinPropertyValues",
- at = @At(value = "INVOKE", target = "Ljava/util/Map;entrySet()Ljava/util/Set;")
- )
- private void whatever(JsonObject object, CallbackInfoReturnable<List<ModelOverride.Condition>> cir,
- @Local Map<Identifier, Float> maps) {
- maps.entrySet().removeIf(it -> it.getKey().getNamespace().equals("firmament"));
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/ProvideBakerToJsonUnbakedModelPatch.java b/src/main/java/moe/nea/firmament/mixins/custommodels/ProvideBakerToJsonUnbakedModelPatch.java
deleted file mode 100644
index c1ac119..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/ProvideBakerToJsonUnbakedModelPatch.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package moe.nea.firmament.mixins.custommodels;
-
-import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
-import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
-import moe.nea.firmament.features.texturepack.JsonUnbakedModelFirmExtra;
-import net.minecraft.client.render.model.BakedModel;
-import net.minecraft.client.render.model.Baker;
-import net.minecraft.client.render.model.ModelBakeSettings;
-import net.minecraft.client.render.model.json.JsonUnbakedModel;
-import net.minecraft.client.texture.Sprite;
-import net.minecraft.client.util.SpriteIdentifier;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-
-import java.util.function.Function;
-
-/**
- * @see JsonUnbakedModelDataHolder#storeExtraBaker_firmament
- */
-@Mixin(targets = "net.minecraft.client.render.model.ModelBaker$BakerImpl")
-public abstract class ProvideBakerToJsonUnbakedModelPatch implements Baker {
- @WrapOperation(method = "bake(Lnet/minecraft/client/render/model/UnbakedModel;Lnet/minecraft/client/render/model/ModelBakeSettings;)Lnet/minecraft/client/render/model/BakedModel;", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/model/json/JsonUnbakedModel;bake(Ljava/util/function/Function;Lnet/minecraft/client/render/model/ModelBakeSettings;Z)Lnet/minecraft/client/render/model/BakedModel;"))
- private BakedModel provideExtraBakerToModel(JsonUnbakedModel instance, Function<SpriteIdentifier, Sprite> function, ModelBakeSettings modelBakeSettings, boolean bl, Operation<BakedModel> original) {
- ((JsonUnbakedModelFirmExtra) instance).storeExtraBaker_firmament(this);
- return original.call(instance, function, modelBakeSettings, bl);
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/ReferenceCustomModelsPatch.java b/src/main/java/moe/nea/firmament/mixins/custommodels/ReferenceCustomModelsPatch.java
deleted file mode 100644
index bb9cd10..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/ReferenceCustomModelsPatch.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package moe.nea.firmament.mixins.custommodels;
-
-import moe.nea.firmament.events.BakeExtraModelsEvent;
-import net.minecraft.client.render.model.BlockStatesLoader;
-import net.minecraft.client.render.model.ItemModel;
-import net.minecraft.client.render.model.ReferencedModelsCollector;
-import net.minecraft.client.render.model.UnbakedModel;
-import net.minecraft.client.util.ModelIdentifier;
-import net.minecraft.util.Identifier;
-import org.spongepowered.asm.mixin.Final;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-
-import java.util.Map;
-
-@Mixin(ReferencedModelsCollector.class)
-public abstract class ReferenceCustomModelsPatch {
- @Shadow
- protected abstract void addTopLevelModel(ModelIdentifier modelId, UnbakedModel model);
-
- @Shadow
- @Final
- private Map<Identifier, UnbakedModel> inputs;
-
- @Inject(method = "addBlockStates", at = @At("RETURN"))
- private void addFirmamentReferencedModels(
- BlockStatesLoader.BlockStateDefinition definition, CallbackInfo ci
- ) {
- BakeExtraModelsEvent.Companion.publish(new BakeExtraModelsEvent(
- (modelIdentifier, identifier) -> addTopLevelModel(modelIdentifier, new ItemModel(identifier))));
-
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockBreakSoundPatch.java b/src/main/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockBreakSoundPatch.java
deleted file mode 100644
index 9401889..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockBreakSoundPatch.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package moe.nea.firmament.mixins.custommodels;
-
-import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
-import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
-import com.llamalad7.mixinextras.sugar.Local;
-import moe.nea.firmament.features.texturepack.CustomBlockTextures;
-import net.minecraft.block.BlockState;
-import net.minecraft.client.render.WorldRenderer;
-import net.minecraft.sound.BlockSoundGroup;
-import net.minecraft.sound.SoundEvent;
-import net.minecraft.util.math.BlockPos;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-
-@Mixin(WorldRenderer.class)
-public class ReplaceBlockBreakSoundPatch {
-// Sadly hypixel does not send a world event here and instead plays the sound on the server directly
-// @WrapOperation(method = "processWorldEvent", at = @At(value = "INVOKE", target = "Lnet/minecraft/sound/BlockSoundGroup;getBreakSound()Lnet/minecraft/sound/SoundEvent;"))
-// private SoundEvent replaceBreakSoundEvent(BlockSoundGroup instance, Operation<SoundEvent> original,
-// @Local(argsOnly = true) BlockPos pos, @Local BlockState blockState) {
-// var replacement = CustomBlockTextures.getReplacement(blockState, pos);
-// if (replacement != null && replacement.getSound() != null) {
-// return SoundEvent.of(replacement.getSound());
-// }
-// return original.call(instance);
-// }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockHitSoundPatch.java b/src/main/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockHitSoundPatch.java
deleted file mode 100644
index f9a1d0d..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockHitSoundPatch.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package moe.nea.firmament.mixins.custommodels;
-
-import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
-import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
-import com.llamalad7.mixinextras.sugar.Local;
-import moe.nea.firmament.features.texturepack.CustomBlockTextures;
-import net.minecraft.block.BlockState;
-import net.minecraft.client.network.ClientPlayerInteractionManager;
-import net.minecraft.client.sound.PositionedSoundInstance;
-import net.minecraft.sound.SoundCategory;
-import net.minecraft.sound.SoundEvent;
-import net.minecraft.util.math.BlockPos;
-import net.minecraft.util.math.random.Random;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-
-@Mixin(ClientPlayerInteractionManager.class)
-public class ReplaceBlockHitSoundPatch {
- @WrapOperation(method = "updateBlockBreakingProgress", at = @At(value = "NEW", target = "(Lnet/minecraft/sound/SoundEvent;Lnet/minecraft/sound/SoundCategory;FFLnet/minecraft/util/math/random/Random;Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/client/sound/PositionedSoundInstance;"))
- private PositionedSoundInstance replaceSound(
- SoundEvent sound, SoundCategory category, float volume, float pitch,
- Random random, BlockPos pos, Operation<PositionedSoundInstance> original,
- @Local BlockState blockState) {
- var replacement = CustomBlockTextures.getReplacement(blockState, pos);
- if (replacement != null && replacement.getSound() != null) {
- sound = SoundEvent.of(replacement.getSound());
- }
- return original.call(sound, category, volume, pitch, random, pos);
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockRenderManagerBlockModel.java b/src/main/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockRenderManagerBlockModel.java
deleted file mode 100644
index 711b2af..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/ReplaceBlockRenderManagerBlockModel.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package moe.nea.firmament.mixins.custommodels;
-
-import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
-import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
-import com.llamalad7.mixinextras.sugar.Local;
-import moe.nea.firmament.features.texturepack.CustomBlockTextures;
-import net.minecraft.block.BlockState;
-import net.minecraft.client.render.block.BlockModels;
-import net.minecraft.client.render.block.BlockRenderManager;
-import net.minecraft.client.render.model.BakedModel;
-import net.minecraft.util.math.BlockPos;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-
-@Mixin(BlockRenderManager.class)
-public class ReplaceBlockRenderManagerBlockModel {
- @WrapOperation(method = "renderBlock", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/block/BlockRenderManager;getModel(Lnet/minecraft/block/BlockState;)Lnet/minecraft/client/render/model/BakedModel;"))
- private BakedModel replaceModelInRenderBlock(
- BlockRenderManager instance, BlockState state, Operation<BakedModel> original, @Local(argsOnly = true) BlockPos pos) {
- var replacement = CustomBlockTextures.getReplacementModel(state, pos);
- if (replacement != null) return replacement;
- CustomBlockTextures.enterFallbackCall();
- var fallback = original.call(instance, state);
- CustomBlockTextures.exitFallbackCall();
- return fallback;
- }
-
- @WrapOperation(method = "renderDamage", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/block/BlockModels;getModel(Lnet/minecraft/block/BlockState;)Lnet/minecraft/client/render/model/BakedModel;"))
- private BakedModel replaceModelInRenderDamage(
- BlockModels instance, BlockState state, Operation<BakedModel> original, @Local(argsOnly = true) BlockPos pos) {
- var replacement = CustomBlockTextures.getReplacementModel(state, pos);
- if (replacement != null) return replacement;
- CustomBlockTextures.enterFallbackCall();
- var fallback = original.call(instance, state);
- CustomBlockTextures.exitFallbackCall();
- return fallback;
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/ReplaceFallbackBlockModel.java b/src/main/java/moe/nea/firmament/mixins/custommodels/ReplaceFallbackBlockModel.java
deleted file mode 100644
index 53ab74a..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/ReplaceFallbackBlockModel.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package moe.nea.firmament.mixins.custommodels;
-
-import moe.nea.firmament.features.texturepack.CustomBlockTextures;
-import net.minecraft.block.BlockState;
-import net.minecraft.client.render.block.BlockModels;
-import net.minecraft.client.render.model.BakedModel;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
-
-@Mixin(BlockModels.class)
-public class ReplaceFallbackBlockModel {
- // TODO: add check to BlockDustParticle
- @Inject(method = "getModel", at = @At("HEAD"), cancellable = true)
- private void getModel(BlockState state, CallbackInfoReturnable<BakedModel> cir) {
- var replacement = CustomBlockTextures.getReplacementModel(state, null);
- if (replacement != null)
- cir.setReturnValue(replacement);
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/custommodels/TestForFirmamentOverridePredicatesPatch.java b/src/main/java/moe/nea/firmament/mixins/custommodels/TestForFirmamentOverridePredicatesPatch.java
deleted file mode 100644
index 63f3cf0..0000000
--- a/src/main/java/moe/nea/firmament/mixins/custommodels/TestForFirmamentOverridePredicatesPatch.java
+++ /dev/null
@@ -1,68 +0,0 @@
-
-package moe.nea.firmament.mixins.custommodels;
-
-import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
-import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
-import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
-import com.llamalad7.mixinextras.sugar.Local;
-import moe.nea.firmament.Firmament;
-import moe.nea.firmament.features.texturepack.BakedOverrideData;
-import moe.nea.firmament.features.texturepack.CustomSkyBlockTextures;
-import moe.nea.firmament.features.texturepack.FirmamentModelPredicate;
-import moe.nea.firmament.features.texturepack.ModelOverrideData;
-import net.minecraft.client.render.model.json.ModelOverride;
-import net.minecraft.client.render.model.json.ModelOverrideList;
-import net.minecraft.item.ItemStack;
-import net.minecraft.util.Identifier;
-import org.objectweb.asm.Opcodes;
-import org.spongepowered.asm.mixin.Final;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.ModifyArg;
-
-import java.util.List;
-import java.util.Objects;
-
-@Mixin(ModelOverrideList.class)
-public class TestForFirmamentOverridePredicatesPatch {
-
- @Shadow
- private Identifier[] conditionTypes;
-
- @ModifyArg(method = "<init>(Lnet/minecraft/client/render/model/Baker;Ljava/util/List;)V",
- at = @At(
- value = "INVOKE", target = "Ljava/util/List;add(Ljava/lang/Object;)Z"
- ))
- public Object onInit(
- Object element,
- @Local ModelOverride modelOverride
- ) {
- var bakedOverride = (ModelOverrideList.BakedOverride) element;
- var modelOverrideData = ModelOverrideData.cast(modelOverride);
- BakedOverrideData.cast(bakedOverride)
- .setFirmamentOverrides(modelOverrideData.getFirmamentOverrides());
- if (conditionTypes.length == 0 &&
- modelOverrideData.getFirmamentOverrides() != null &&
- modelOverrideData.getFirmamentOverrides().length > 0) {
- conditionTypes = new Identifier[]{Firmament.INSTANCE.identifier("sentinel/enforce_model_override_evaluation")};
- }
- return element;
- }
-
- @ModifyExpressionValue(method = "getModel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/model/json/ModelOverrideList$BakedOverride;test([F)Z"))
- public boolean testFirmamentOverrides(boolean originalValue,
- @Local ModelOverrideList.BakedOverride bakedOverride,
- @Local(argsOnly = true) ItemStack stack) {
- if (!originalValue) return false;
- var overrideData = (BakedOverrideData) (Object) bakedOverride;
- var overrides = overrideData.getFirmamentOverrides();
- if (overrides == null) return true;
- if (!CustomSkyBlockTextures.TConfig.INSTANCE.getEnableModelOverrides()) return false;
- for (FirmamentModelPredicate firmamentOverride : overrides) {
- if (!firmamentOverride.test(stack))
- return false;
- }
- return true;
- }
-}
diff --git a/src/main/java/moe/nea/firmament/mixins/feature/DisableSlotHighlights.java b/src/main/java/moe/nea/firmament/mixins/feature/DisableSlotHighlights.java
new file mode 100644
index 0000000..0abed22
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/feature/DisableSlotHighlights.java
@@ -0,0 +1,25 @@
+package moe.nea.firmament.mixins.feature;
+
+import moe.nea.firmament.features.fixes.Fixes;
+import net.minecraft.component.DataComponentTypes;
+import net.minecraft.item.ItemStack;
+import net.minecraft.screen.slot.Slot;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
+
+@Mixin(Slot.class)
+public abstract class DisableSlotHighlights {
+ @Shadow
+ public abstract ItemStack getStack();
+
+ @Inject(method = "canBeHighlighted", at = @At("HEAD"), cancellable = true)
+ private void dontHighlight(CallbackInfoReturnable<Boolean> cir) {
+ if (!Fixes.TConfig.INSTANCE.getHideSlotHighlights()) return;
+ var display = getStack().get(DataComponentTypes.TOOLTIP_DISPLAY);
+ if (display != null && display.hideTooltip())
+ cir.setReturnValue(false);
+ }
+}
diff --git a/src/main/java/moe/nea/firmament/mixins/feature/devcosmetics/CustomCapeFeatureRenderer.java b/src/main/java/moe/nea/firmament/mixins/feature/devcosmetics/CustomCapeFeatureRenderer.java
new file mode 100644
index 0000000..5a92f89
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/feature/devcosmetics/CustomCapeFeatureRenderer.java
@@ -0,0 +1,43 @@
+package moe.nea.firmament.mixins.feature.devcosmetics;
+
+import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
+import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
+import com.llamalad7.mixinextras.sugar.Local;
+import kotlin.Unit;
+import moe.nea.firmament.features.misc.CustomCapes;
+import net.minecraft.client.render.RenderLayer;
+import net.minecraft.client.render.VertexConsumer;
+import net.minecraft.client.render.VertexConsumerProvider;
+import net.minecraft.client.render.entity.feature.CapeFeatureRenderer;
+import net.minecraft.client.render.entity.feature.FeatureRenderer;
+import net.minecraft.client.render.entity.feature.FeatureRendererContext;
+import net.minecraft.client.render.entity.model.BipedEntityModel;
+import net.minecraft.client.render.entity.model.PlayerEntityModel;
+import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
+import net.minecraft.client.util.SkinTextures;
+import net.minecraft.client.util.math.MatrixStack;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+
+@Mixin(CapeFeatureRenderer.class)
+public abstract class CustomCapeFeatureRenderer extends FeatureRenderer<PlayerEntityRenderState, PlayerEntityModel> {
+ public CustomCapeFeatureRenderer(FeatureRendererContext<PlayerEntityRenderState, PlayerEntityModel> context) {
+ super(context);
+ }
+
+ @WrapOperation(
+ method = "render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/client/render/entity/state/PlayerEntityRenderState;FF)V",
+ at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/entity/model/BipedEntityModel;render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumer;II)V")
+ )
+ private void onRender(BipedEntityModel instance, MatrixStack matrixStack, VertexConsumer vertexConsumer, int light, int overlay, Operation<Void> original, @Local PlayerEntityRenderState playerEntityRenderState, @Local SkinTextures skinTextures, @Local VertexConsumerProvider vertexConsumerProvider) {
+ CustomCapes.render(
+ playerEntityRenderState,
+ vertexConsumer,
+ RenderLayer.getEntitySolid(skinTextures.capeTexture()),
+ vertexConsumerProvider,
+ updatedConsumer -> {
+ original.call(instance, matrixStack, updatedConsumer, light, overlay);
+ return Unit.INSTANCE;
+ });
+ }
+}
diff --git a/src/main/java/moe/nea/firmament/mixins/feature/devcosmetics/CustomCapeStorage.java b/src/main/java/moe/nea/firmament/mixins/feature/devcosmetics/CustomCapeStorage.java
new file mode 100644
index 0000000..428d7ec
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/feature/devcosmetics/CustomCapeStorage.java
@@ -0,0 +1,23 @@
+package moe.nea.firmament.mixins.feature.devcosmetics;
+
+import moe.nea.firmament.features.misc.CustomCapes;
+import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
+import org.jetbrains.annotations.Nullable;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Unique;
+
+@Mixin(PlayerEntityRenderState.class)
+public class CustomCapeStorage implements CustomCapes.CapeStorage {
+ @Unique
+ CustomCapes.CustomCape customCape;
+
+ @Override
+ public CustomCapes.@Nullable CustomCape getCape_firmament() {
+ return customCape;
+ }
+
+ @Override
+ public void setCape_firmament(CustomCapes.@Nullable CustomCape customCape) {
+ this.customCape = customCape;
+ }
+}
diff --git a/src/main/java/moe/nea/firmament/mixins/feature/devcosmetics/SaveCapeToPlayerEntityRenderState.java b/src/main/java/moe/nea/firmament/mixins/feature/devcosmetics/SaveCapeToPlayerEntityRenderState.java
new file mode 100644
index 0000000..ae9c743
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/feature/devcosmetics/SaveCapeToPlayerEntityRenderState.java
@@ -0,0 +1,19 @@
+package moe.nea.firmament.mixins.feature.devcosmetics;
+
+import moe.nea.firmament.features.misc.CustomCapes;
+import net.minecraft.client.network.AbstractClientPlayerEntity;
+import net.minecraft.client.render.entity.PlayerEntityRenderer;
+import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+@Mixin(PlayerEntityRenderer.class)
+public class SaveCapeToPlayerEntityRenderState {
+ @Inject(method = "updateRenderState(Lnet/minecraft/client/network/AbstractClientPlayerEntity;Lnet/minecraft/client/render/entity/state/PlayerEntityRenderState;F)V",
+ at = @At("TAIL"))
+ private void addCustomCape(AbstractClientPlayerEntity abstractClientPlayerEntity, PlayerEntityRenderState playerEntityRenderState, float f, CallbackInfo ci) {
+ CustomCapes.addCapeData(abstractClientPlayerEntity, playerEntityRenderState);
+ }
+}
diff --git a/src/main/java/moe/nea/firmament/mixins/render/entitytints/ChangeColorOfLivingEntities.java b/src/main/java/moe/nea/firmament/mixins/render/entitytints/ChangeColorOfLivingEntities.java
new file mode 100644
index 0000000..2b96e5c
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/render/entitytints/ChangeColorOfLivingEntities.java
@@ -0,0 +1,62 @@
+package moe.nea.firmament.mixins.render.entitytints;
+
+import com.llamalad7.mixinextras.injector.ModifyReturnValue;
+import com.llamalad7.mixinextras.sugar.Local;
+import moe.nea.firmament.events.EntityRenderTintEvent;
+import net.minecraft.client.render.VertexConsumerProvider;
+import net.minecraft.client.render.entity.LivingEntityRenderer;
+import net.minecraft.client.render.entity.model.EntityModel;
+import net.minecraft.client.render.entity.state.LivingEntityRenderState;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.entity.LivingEntity;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.ModifyArg;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+/**
+ * Applies various rendering modifications from {@link EntityRenderTintEvent}
+ */
+@Mixin(LivingEntityRenderer.class)
+public class ChangeColorOfLivingEntities<T extends LivingEntity, S extends LivingEntityRenderState, M extends EntityModel<? super S>> {
+ @ModifyReturnValue(method = "getMixColor", at = @At("RETURN"))
+ private int changeColor(int original, @Local(argsOnly = true) S state) {
+ var tintState = EntityRenderTintEvent.HasTintRenderState.cast(state);
+ if (tintState.getHasTintOverride_firmament())
+ return tintState.getTint_firmament();
+ return original;
+ }
+
+ @ModifyArg(
+ method = "getOverlay",
+ at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/OverlayTexture;getU(F)I"),
+ allow = 1
+ )
+ private static float modifyLightOverlay(float originalWhiteOffset, @Local(argsOnly = true) LivingEntityRenderState state) {
+ var tintState = EntityRenderTintEvent.HasTintRenderState.cast(state);
+ if (tintState.getHasTintOverride_firmament() || tintState.getOverlayTexture_firmament() != null) {
+ return 1F; // TODO: add interpolation percentage to render state extension
+ }
+ return originalWhiteOffset;
+ }
+
+ @Inject(method = "render(Lnet/minecraft/client/render/entity/state/LivingEntityRenderState;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/math/MatrixStack;pop()V"))
+ private void afterRender(S livingEntityRenderState, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int i, CallbackInfo ci) {
+ var tintState = EntityRenderTintEvent.HasTintRenderState.cast(livingEntityRenderState);
+ var overlayTexture = tintState.getOverlayTexture_firmament();
+ if (overlayTexture != null && vertexConsumerProvider instanceof VertexConsumerProvider.Immediate imm) {
+ imm.drawCurrentLayer();
+ }
+ EntityRenderTintEvent.overlayOverride = null;
+ }
+
+ @Inject(method = "render(Lnet/minecraft/client/render/entity/state/LivingEntityRenderState;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/math/MatrixStack;push()V"))
+ private void beforeRender(S livingEntityRenderState, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int i, CallbackInfo ci) {
+ var tintState = EntityRenderTintEvent.HasTintRenderState.cast(livingEntityRenderState);
+ var overlayTexture = tintState.getOverlayTexture_firmament();
+ if (overlayTexture != null) {
+ EntityRenderTintEvent.overlayOverride = overlayTexture;
+ }
+ }
+}
diff --git a/src/main/java/moe/nea/firmament/mixins/render/entitytints/EntityRenderStateTint.java b/src/main/java/moe/nea/firmament/mixins/render/entitytints/EntityRenderStateTint.java
new file mode 100644
index 0000000..1019027
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/render/entitytints/EntityRenderStateTint.java
@@ -0,0 +1,55 @@
+package moe.nea.firmament.mixins.render.entitytints;
+
+import moe.nea.firmament.events.EntityRenderTintEvent;
+import moe.nea.firmament.util.render.TintedOverlayTexture;
+import net.minecraft.client.render.entity.state.EntityRenderState;
+import org.jetbrains.annotations.Nullable;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Unique;
+
+@Mixin(EntityRenderState.class)
+public class EntityRenderStateTint implements EntityRenderTintEvent.HasTintRenderState {
+ @Unique
+ int tint = -1;
+ @Unique
+ TintedOverlayTexture overlayTexture;
+ @Unique
+ boolean hasTintOverride = false;
+
+ @Override
+ public int getTint_firmament() {
+ return tint;
+ }
+
+ @Override
+ public void setTint_firmament(int i) {
+ tint = i;
+ hasTintOverride = true;
+ }
+
+ @Override
+ public boolean getHasTintOverride_firmament() {
+ return hasTintOverride;
+ }
+
+ @Override
+ public void setHasTintOverride_firmament(boolean b) {
+ hasTintOverride = b;
+ }
+
+ @Override
+ public void reset_firmament() {
+ hasTintOverride = false;
+ overlayTexture = null;
+ }
+
+ @Override
+ public @Nullable TintedOverlayTexture getOverlayTexture_firmament() {
+ return overlayTexture;
+ }
+
+ @Override
+ public void setOverlayTexture_firmament(@Nullable TintedOverlayTexture tintedOverlayTexture) {
+ this.overlayTexture = tintedOverlayTexture;
+ }
+}
diff --git a/src/main/java/moe/nea/firmament/mixins/render/entitytints/InjectIntoRenderState.java b/src/main/java/moe/nea/firmament/mixins/render/entitytints/InjectIntoRenderState.java
new file mode 100644
index 0000000..7938340
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/render/entitytints/InjectIntoRenderState.java
@@ -0,0 +1,30 @@
+package moe.nea.firmament.mixins.render.entitytints;
+
+import moe.nea.firmament.events.EntityRenderTintEvent;
+import net.minecraft.client.render.entity.EntityRenderer;
+import net.minecraft.client.render.entity.state.EntityRenderState;
+import net.minecraft.entity.Entity;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+/**
+ * Dispatches {@link EntityRenderTintEvent} to collect additional render state used by {@link ChangeColorOfLivingEntities}
+ */
+@Mixin(EntityRenderer.class)
+public class InjectIntoRenderState<T extends Entity, S extends EntityRenderState> {
+
+ @Inject(
+ method = "updateRenderState",
+ at = @At("RETURN"))
+ private void onUpdateRenderState(T entity, S state, float tickDelta, CallbackInfo ci) {
+ var renderState = EntityRenderTintEvent.HasTintRenderState.cast(state);
+ renderState.reset_firmament();
+ var tintEvent = new EntityRenderTintEvent(
+ entity,
+ renderState
+ );
+ EntityRenderTintEvent.Companion.publish(tintEvent);
+ }
+}
diff --git a/src/main/java/moe/nea/firmament/mixins/render/entitytints/ReplaceOverlayTexture.java b/src/main/java/moe/nea/firmament/mixins/render/entitytints/ReplaceOverlayTexture.java
new file mode 100644
index 0000000..61e5c65
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/render/entitytints/ReplaceOverlayTexture.java
@@ -0,0 +1,24 @@
+package moe.nea.firmament.mixins.render.entitytints;
+
+import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
+import moe.nea.firmament.events.EntityRenderTintEvent;
+import net.minecraft.client.render.OverlayTexture;
+import net.minecraft.client.render.RenderLayer;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+
+/**
+ * Replaces the overlay texture used by rendering with the override specified in {@link EntityRenderTintEvent#overlayOverride}
+ */
+@Mixin(RenderLayer.Overlay.class)
+public class ReplaceOverlayTexture {
+ @ModifyExpressionValue(
+ method = {"method_23555", "method_23556"},
+ expect = 2,
+ at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/GameRenderer;getOverlayTexture()Lnet/minecraft/client/render/OverlayTexture;"))
+ private static OverlayTexture replaceOverlayTexture(OverlayTexture original) {
+ if (EntityRenderTintEvent.overlayOverride != null)
+ return EntityRenderTintEvent.overlayOverride;
+ return original;
+ }
+}
diff --git a/src/main/java/moe/nea/firmament/mixins/render/entitytints/UseOverlayableEquipmentRenderer.java b/src/main/java/moe/nea/firmament/mixins/render/entitytints/UseOverlayableEquipmentRenderer.java
new file mode 100644
index 0000000..d9c174c
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/render/entitytints/UseOverlayableEquipmentRenderer.java
@@ -0,0 +1,34 @@
+package moe.nea.firmament.mixins.render.entitytints;
+
+import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
+import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
+import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
+import moe.nea.firmament.events.EntityRenderTintEvent;
+import net.minecraft.client.render.OverlayTexture;
+import net.minecraft.client.render.RenderLayer;
+import net.minecraft.client.render.entity.equipment.EquipmentRenderer;
+import net.minecraft.util.Identifier;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+
+/**
+ * Patch to make {@link EquipmentRenderer} use a {@link RenderLayer} that allows uses Minecraft's overlay texture, if a {@link EntityRenderTintEvent#overlayOverride} is specified.
+ */
+@Mixin(EquipmentRenderer.class)
+public class UseOverlayableEquipmentRenderer {
+ @WrapOperation(method = "render(Lnet/minecraft/client/render/entity/equipment/EquipmentModel$LayerType;Lnet/minecraft/registry/RegistryKey;Lnet/minecraft/client/model/Model;Lnet/minecraft/item/ItemStack;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/util/Identifier;)V",
+ at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/RenderLayer;getArmorCutoutNoCull(Lnet/minecraft/util/Identifier;)Lnet/minecraft/client/render/RenderLayer;"))
+ private RenderLayer replace(Identifier texture, Operation<RenderLayer> original) {
+ if (EntityRenderTintEvent.overlayOverride != null)
+ return RenderLayer.getEntityTranslucent(texture);
+ return original.call(texture);
+ }
+
+ @ModifyExpressionValue(method = "render(Lnet/minecraft/client/render/entity/equipment/EquipmentModel$LayerType;Lnet/minecraft/registry/RegistryKey;Lnet/minecraft/client/model/Model;Lnet/minecraft/item/ItemStack;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/util/Identifier;)V",
+ at = @At(value = "FIELD", target = "Lnet/minecraft/client/render/OverlayTexture;DEFAULT_UV:I"))
+ private int replaceUvIndex(int original) {
+ if (EntityRenderTintEvent.overlayOverride != null)
+ return OverlayTexture.packUv(15, 10); // TODO: store this info in a global alongside overlayOverride
+ return original;
+ }
+}
diff --git a/src/main/java/moe/nea/firmament/mixins/render/entitytints/UseOverlayableHeadFeatureRenderer.java b/src/main/java/moe/nea/firmament/mixins/render/entitytints/UseOverlayableHeadFeatureRenderer.java
new file mode 100644
index 0000000..07bc5cf
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/render/entitytints/UseOverlayableHeadFeatureRenderer.java
@@ -0,0 +1,25 @@
+package moe.nea.firmament.mixins.render.entitytints;
+
+import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
+import moe.nea.firmament.events.EntityRenderTintEvent;
+import net.minecraft.client.render.OverlayTexture;
+import net.minecraft.client.render.RenderLayer;
+import net.minecraft.client.render.entity.feature.HeadFeatureRenderer;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+
+/**
+ * Patch to make {@link HeadFeatureRenderer} use a {@link RenderLayer} that allows uses Minecraft's overlay texture, if a {@link EntityRenderTintEvent#overlayOverride} is specified.
+ * @see UseOverlayableItemRenderer
+ */
+@Mixin(HeadFeatureRenderer.class)
+public class UseOverlayableHeadFeatureRenderer {
+
+ @ModifyExpressionValue(method = "render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/client/render/entity/state/LivingEntityRenderState;FF)V",
+ at = @At(value = "FIELD", target = "Lnet/minecraft/client/render/OverlayTexture;DEFAULT_UV:I"))
+ private int replaceUvIndex(int original) {
+ if (EntityRenderTintEvent.overlayOverride != null)
+ return OverlayTexture.packUv(15, 10); // TODO: store this info in a global alongside overlayOverride
+ return original;
+ }
+}
diff --git a/src/main/java/moe/nea/firmament/mixins/render/entitytints/UseOverlayableItemRenderer.java b/src/main/java/moe/nea/firmament/mixins/render/entitytints/UseOverlayableItemRenderer.java
new file mode 100644
index 0000000..620ab2c
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/render/entitytints/UseOverlayableItemRenderer.java
@@ -0,0 +1,25 @@
+package moe.nea.firmament.mixins.render.entitytints;
+
+import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
+import moe.nea.firmament.events.EntityRenderTintEvent;
+import net.minecraft.client.render.OverlayTexture;
+import net.minecraft.client.render.RenderLayer;
+import net.minecraft.client.render.RenderPhase;
+import net.minecraft.client.render.item.ItemRenderState;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+
+/**
+ * Patch to make {@link ItemRenderState} use a {@link RenderLayer} that allows uses Minecraft's overlay texture.
+ *
+ * @see UseOverlayableHeadFeatureRenderer
+ */
+@Mixin(ItemRenderState.LayerRenderState.class)
+public class UseOverlayableItemRenderer {
+ @ModifyExpressionValue(method = "render", at = @At(value = "FIELD", target = "Lnet/minecraft/client/render/item/ItemRenderState$LayerRenderState;renderLayer:Lnet/minecraft/client/render/RenderLayer;"))
+ private RenderLayer replace(RenderLayer original) {
+ if (EntityRenderTintEvent.overlayOverride != null && original instanceof RenderLayer.MultiPhase multiPhase && multiPhase.phases.texture instanceof RenderPhase.Texture texture && texture.getId().isPresent())
+ return RenderLayer.getEntityTranslucent(texture.getId().get());
+ return original;
+ }
+}
diff --git a/src/main/java/moe/nea/firmament/mixins/render/entitytints/UseOverlayableSkullBlockEntityRenderer.java b/src/main/java/moe/nea/firmament/mixins/render/entitytints/UseOverlayableSkullBlockEntityRenderer.java
new file mode 100644
index 0000000..9905af1
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/render/entitytints/UseOverlayableSkullBlockEntityRenderer.java
@@ -0,0 +1,25 @@
+package moe.nea.firmament.mixins.render.entitytints;
+
+import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
+import moe.nea.firmament.events.EntityRenderTintEvent;
+import net.minecraft.client.render.OverlayTexture;
+import net.minecraft.client.render.RenderLayer;
+import net.minecraft.client.render.block.entity.SkullBlockEntityRenderer;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+
+/**
+ * Patch to make {@link SkullBlockEntityRenderer} use a {@link RenderLayer} that allows uses Minecraft's overlay texture, if a {@link EntityRenderTintEvent#overlayOverride} is specified.
+ */
+
+@Mixin(SkullBlockEntityRenderer.class)
+public class UseOverlayableSkullBlockEntityRenderer {
+ @ModifyExpressionValue(method = "renderSkull",
+ at = @At(value = "FIELD", target = "Lnet/minecraft/client/render/OverlayTexture;DEFAULT_UV:I"))
+ private static int replaceUvIndex(int original) {
+ if (EntityRenderTintEvent.overlayOverride != null)
+ return OverlayTexture.packUv(15, 10); // TODO: store this info in a global alongside overlayOverride
+ return original;
+ }
+
+}