0

So I am using IntelliJ IDEA to mod Minecraft Forge 1.18.2 and I am trying to change the isEmptyBlock method of the LevelReader class using SpongePowered mixins.

But LevelReader is an interface, and the mod won't run if I try to edit an Interface. And after looking for quite a while on the InterWebs, I have found nothing.

So the question is:

So how do I change the method of an Interface?

I am using this code: in: MixinLevelReader

package net.iateminecraft.jetpacksfix.mixin;

import com.mojang.logging.LogUtils;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.LevelAccessor;
import org.slf4j.Logger;
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;

@Mixin(LevelReader.class)
public abstract class MixinLevelReader {
    @Unique
    private static final Logger LOGGER = LogUtils.getLogger();
    @Unique
    LevelAccessor world = (LevelAccessor) (Object) this;

    @Inject(at = @At("HEAD"), method = "isEmptyBlock(Lnet/minecraft/core/BlockPos;)Z", cancellable = true)
    private void isEmptyBlock(BlockPos blockposition, CallbackInfoReturnable<Boolean> callback) {
        LOGGER.info(String.valueOf(world.getBlockState(blockposition).isAir()));
        callback.setReturnValue(world.getBlockState(blockposition).isAir());
    }
}

It will compile fine when I run ./gradlew :build, but as soon as I do ./gradlew :runClient it errors with: Caused by: org.spongepowered.asm.mixin.transformer.throwables.InvalidMixinException: @Mixin target type mismatch: net.minecraft.world.level.LevelReader is an interface in org.spongepowered.asm.mixin.transformer.MixinInfo$SubType$Standard@75b6dd5b

1 Answer 1

0

On Forge, you won't be able to as the version used in 1.18.2 is too old to have the newer feature of using @Redirect or @Inject on interfaces. You'd have to use an @Overwrite of the full default method, that way you can add your code in the right place. The alternative is to use an @Override on something like ServerLevel where you can add a method "implementing" the parent method that is defaulted:


    @Override
    public boolean isEmptyBlock(BlockPos pos) {
        // Do something before
        if (net.minecraft.world.level.LevelReader.super.isEmptyBlock(isEmptyBlock)) {
            // do something after if true
        }
        // do something here as well
    }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.