Skip to content

Redirect

Danger

Redirects should not be used as they cause hard conflicts with any other mod attempting to redirect the same target. They can awlays be replaced by either a WrapOperation or WrapWithCondition, or another type of injection.

This type of injection should never be used unless you want your mod to be incompatible with other mods. Redirect lets you redirect a method call to a different method.

Say we had the following:

public void foo(int param) {
    int a = getInt(param);
    String b = getString(param);
    boolean c = getBool(param);
    doSomething(a, b, c);
}

If we want to change the doSomething to something else, wrap the original call in a check, or simply skip the call altogether, we can do that as such:

@Redirect(method = "foo", at = @At(value = "INVOKE", target = "doSomething(ILjava/lang/String;Z)V"))
private void wrapSomething(Foo instance, int a, String b, boolean c, Operation<Void> original) {
    if (ModConfig.doSomethingElse) {
        return doSomethingElse(a, b, c); // new method
    } else if (ModConfig.doOriginal) {
        return doSomething(a, b, c); // original method, but conditionally wrapped
    } else {
        // No-op (the original method call is skipped entirely)
    }
}

Resulting in:

public void foo(int param) {
    int a = getInt(param);
    String b = getString(param);
    boolean c = getBool(param);
    if (ModConfig.doSomethingElse) {
        doSomethingElse(a, b, c);
    } else if (ModConfig.doOriginal) {
        doSomething(a, b, c);
    } else {
        // No-op
    }
}

However, we can replace this Redirect with other injections for better comptability.

  • If we want to replace the original call, we should use WrapOperation.
  • If we just want to wrap the original call with a check, we should use WrapWithCondition.