Implement the Ref interfaces explicitly in their mixins
Several mixins implemented a Ref method only through a vanilla method of the same name. Released jars rename vanilla methods to intermediary names, so those Ref methods had no implementation there and threw AbstractMethodError: the armour display's durability, the status effects' icon and infinite checks, the SVG texture size and the pre-1.21.6 matrix stack's push and pop. With Mojang's names the same happens in development (1.21.4 crashed on the title screen). Each mixin now shadows the vanilla method and implements the Ref method by calling it. Points common at the Ref renames this needs. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -18,6 +18,8 @@ Every version is built with Mojang's official names (`loom.officialMojangMapping
|
|||||||
|
|
||||||
Mojang renamed a few classes within 1.21.x. `src/` uses the newest names, and `stonecutter.gradle.kts` lists replacements that swap in the older name when Stonecutter processes an older version (for example `Identifier`, which was `ResourceLocation` before 1.21.11, and `AvatarRenderState`, which was `PlayerRenderState` before 1.21.9). Add a replacement there when a rename touches many lines. A class that only moved package needs just a version comment on its import, and a renamed method a version comment where it's called.
|
Mojang renamed a few classes within 1.21.x. `src/` uses the newest names, and `stonecutter.gradle.kts` lists replacements that swap in the older name when Stonecutter processes an older version (for example `Identifier`, which was `ResourceLocation` before 1.21.11, and `AvatarRenderState`, which was `PlayerRenderState` before 1.21.9). Add a replacement there when a rename touches many lines. A class that only moved package needs just a version comment on its import, and a renamed method a version comment where it's called.
|
||||||
|
|
||||||
|
Released jars run on intermediary names (`method_1234`), not Mojang's, and Loom renames everything that refers to Minecraft when it builds them. So a mixin can't implement one of `common`'s Ref interfaces by relying on a vanilla method that happens to have the same name: the vanilla method is renamed in the jar, and the interface method is left without an implementation (`AbstractMethodError`). Shadow the vanilla method and implement the Ref method explicitly, as `WindowMixin` does. For the same reason, Ref methods mustn't share a name and parameters with a method of the class they're mixed into, or the mixin replaces the vanilla method in development.
|
||||||
|
|
||||||
## Version-specific code with Stonecutter
|
## Version-specific code with Stonecutter
|
||||||
|
|
||||||
The code in `src/` is always plain Java for the **active** version (1.21.11, set in `stonecutter.gradle.kts`). Code for other versions sits in comments that Stonecutter swaps before building each version:
|
The code in `src/` is always plain Java for the **active** version (1.21.11, set in `stonecutter.gradle.kts`). Code for other versions sits in comments that Stonecutter swaps before building each version:
|
||||||
|
|||||||
+1
-1
Submodule common updated: b0d75af8c4...a6a324a61a
@@ -16,4 +16,20 @@ public abstract class ItemStackMixin implements ItemStackRef {
|
|||||||
|
|
||||||
@Shadow
|
@Shadow
|
||||||
public abstract int getDamageValue();
|
public abstract int getDamageValue();
|
||||||
|
|
||||||
|
// ItemStackRef's methods delegate to ItemStack's, whose names production renames.
|
||||||
|
@Override
|
||||||
|
public boolean isEmptyStack() {
|
||||||
|
return isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxItemDamage() {
|
||||||
|
return getMaxDamage();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemDamage() {
|
||||||
|
return getDamageValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,17 @@ import com.mojang.math.Axis;
|
|||||||
//? if <1.21.5
|
//? if <1.21.5
|
||||||
//public abstract void rotateAround(Quaternionf quaternion, float originX, float originY, float originZ);
|
//public abstract void rotateAround(Quaternionf quaternion, float originX, float originY, float originZ);
|
||||||
|
|
||||||
|
// MatrixStackRef's methods delegate to PoseStack's, whose names production renames.
|
||||||
|
@Override
|
||||||
|
public void push() {
|
||||||
|
pushPose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pop() {
|
||||||
|
popPose();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translate(float x, float y) {
|
public void translate(float x, float y) {
|
||||||
translate(x, y, 0);
|
translate(x, y, 0);
|
||||||
|
|||||||
@@ -29,6 +29,17 @@ public abstract class StatusEffectMixin implements EffectRef {
|
|||||||
@Shadow
|
@Shadow
|
||||||
public abstract Holder<MobEffect> getEffect();
|
public abstract Holder<MobEffect> getEffect();
|
||||||
|
|
||||||
|
// EffectRef's methods delegate to MobEffectInstance's, whose names production renames.
|
||||||
|
@Override
|
||||||
|
public boolean shouldShowIcon() {
|
||||||
|
return showIcon();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInfinite() {
|
||||||
|
return isInfiniteDuration();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SpriteRef getIcon() {
|
public SpriteRef getIcon() {
|
||||||
// 1.21.9 changed the GUI atlas, so newer versions draw the effect's texture (getIconId) instead.
|
// 1.21.9 changed the GUI atlas, so newer versions draw the effect's texture (getIconId) instead.
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
package org.saturnclient.impl.mixins;
|
package org.saturnclient.impl.mixins;
|
||||||
|
|
||||||
import com.mojang.blaze3d.platform.Window;
|
|
||||||
import org.saturnclient.common.ref.render.WindowRef;
|
import org.saturnclient.common.ref.render.WindowRef;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.platform.Window;
|
||||||
|
|
||||||
@Mixin(Window.class)
|
@Mixin(Window.class)
|
||||||
public abstract class WindowMixin implements WindowRef {
|
public abstract class WindowMixin implements WindowRef {
|
||||||
@Shadow
|
@Shadow
|
||||||
@@ -13,9 +14,31 @@ public abstract class WindowMixin implements WindowRef {
|
|||||||
@Shadow
|
@Shadow
|
||||||
public abstract int getScreenHeight();
|
public abstract int getScreenHeight();
|
||||||
|
|
||||||
|
// The framebuffer's size
|
||||||
@Shadow
|
@Shadow
|
||||||
public abstract int getWidth();
|
public abstract int getWidth();
|
||||||
|
|
||||||
@Shadow
|
@Shadow
|
||||||
public abstract int getHeight();
|
public abstract int getHeight();
|
||||||
|
|
||||||
|
// WindowRef's methods delegate to Window's, whose names production renames.
|
||||||
|
@Override
|
||||||
|
public int getWindowWidth() {
|
||||||
|
return getScreenWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getWindowHeight() {
|
||||||
|
return getScreenHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFramebufferWidth() {
|
||||||
|
return getWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFramebufferHeight() {
|
||||||
|
return getHeight();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user