-
Notifications
You must be signed in to change notification settings - Fork 18
Local
Allows you to capture local variables wherever you need them. Targeting the variables works in exactly the same way as explained here, so I encourage you to read that.
Possible parameters could look like:
-
@Local double fov
(captures the only local of typedouble
and throws an error if there is more than one) -
@Local(ordinal = 1) BlockPos pos
(captures the second local of typeBlockPos
) -
@Local(index = 3) int x
(captures the local with LVT index 3)
When targeting code such as the following:
boolean bl1 = complexThing1() && complexThing2() || complexThing3();
boolean bl2 = !complexThing4() || complexThing5();
you may wish to change bl2
in such a way that requires the value of bl1
.
This could be done like so:
@ModifyVariable(method = "targetMethod", at = @At("STORE"), ordinal = 1)
private boolean modifybl2ForReasons(boolean original, @Local(ordinal = 0) boolean bl1) {
return original && YourMod.anotherComplexThing(bl1);
}
Your ModifyVariable
would work as normal, modifying bl2
, but you also receive the value of bl1
.
boolean bl2 = !complexThing4() || complexThing5();
+ bl2 = modifybl2ForReasons(bl2, bl1);
@Local
also allows you to capture mutable references to local variables. Targeting the locals works in exactly the same way as above, but instead of the local's type, you use the corresponding reference type.
Possible parameters could look like:
-
@Local LocalDoubleRef fov
(captures a reference to the only local of typedouble
and throws an error if there is more than one) -
@Local(ordinal = 1) LocalRef<BlockPos> pos
(captures a reference to the second local of typeBlockPos
) -
@Local(index = 3) LocalIntRef x
(captures a reference to the local with LVT index 3).
These reference types have get
and set
methods providing both read and write access to the variable in question.
When targeting code such as the following:
String playerName = player.getName();
int color = 0xFFFFFFFF;
if (player.isSneaking()) {
// ...
}
// ...
you may wish to modify both variables at the same time.
This could be done like so:
@Inject(method = "targetMethod", at = @At(value = "INVOKE", target = "Lsome/package/Player;isSneaking()Z"))
private void changeNameAndColor(CallbackInfo ci, @Local LocalRef<String> name, @Local LocalIntRef color) {
if (name.get().equals("LlamaLad7")) {
name.set("Herobrine");
color.set(0xFFFF0000);
}
}
Your Inject
would be passed references to both variables, and your new values would be assigned to the actual variables when your handler method finishes.
String playerName = player.getName();
int color = 0xFFFFFFFF;
+ LocalRef ref1 = new LocalRefImpl(playerName);
+ LocalIntRef ref2 = new LocalIntRefImpl(color);
+ changeNameAndColor(null, ref1, ref2);
+ color = ref2.get();
+ playerName = ref1.get();
if (player.isSneaking()) {
// ...
}
// ...