Skip to content

Commit

Permalink
patch YACL, fix following issues:
Browse files Browse the repository at this point in the history
  • Loading branch information
LucunJi committed Jun 24, 2024
1 parent 0d4e215 commit e7cbc29
Show file tree
Hide file tree
Showing 11 changed files with 237 additions and 107 deletions.
2 changes: 1 addition & 1 deletion src/main/java/github/io/lucunji/explayerenderer/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public void onInitializeClient() {
"key." + MOD_ID + ".category"));
ClientTickEvents.END_CLIENT_TICK.register(client -> {
while (configKey.wasPressed()) {
client.setScreen(Configs.HANDLER.generateGui().generateScreen(client.currentScreen));
client.setScreen(Configs.genGui(client.currentScreen));
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import com.mojang.blaze3d.systems.RenderSystem;
import github.io.lucunji.explayerenderer.client.render.DataBackup.DataBackupEntry;
import github.io.lucunji.explayerenderer.config.Configs;
import github.io.lucunji.explayerenderer.config.PoseOffsetMethod;
import github.io.lucunji.explayerenderer.mixin.ClientPlayerEntityAccessor;
import github.io.lucunji.explayerenderer.mixin.EntityMixin;
import github.io.lucunji.explayerenderer.mixin.LivingEntityAccessor;
Expand Down Expand Up @@ -63,7 +62,7 @@ public class PlayerHUDRenderer {
* Mimics the code in {@link InventoryScreen#drawEntity}
*/
public void render(float partialTicks) {
Configs configs = Configs.HANDLER.instance();
Configs configs = Configs.getInstance();
if (client.world == null || client.player == null || !configs.enabled) return;
LivingEntity targetEntity = client.world.getPlayers().stream().filter(p -> p.getName().getString().equals(configs.playerName)).findFirst().orElse(client.player);
if (configs.spectatorAutoSwitch && client.player.isSpectator()) {
Expand All @@ -77,15 +76,15 @@ public void render(float partialTicks) {

int scaledWidth = client.getWindow().getScaledWidth();
int scaledHeight = client.getWindow().getScaledHeight();
PoseOffsetMethod poseOffsetMethod = configs.poseOffsetMethod;
Configs.PoseOffsetMethod poseOffsetMethod = configs.poseOffsetMethod;

var backup = new DataBackup<>(targetEntity, LIVINGENTITY_BACKUP_ENTRIES);
backup.save();

transformEntity(targetEntity, partialTicks, poseOffsetMethod == PoseOffsetMethod.FORCE_STANDING);
transformEntity(targetEntity, partialTicks, poseOffsetMethod == Configs.PoseOffsetMethod.FORCE_STANDING);

DataBackup<LivingEntity> vehicleBackup = null;
if (configs.renderVehicle && poseOffsetMethod != PoseOffsetMethod.FORCE_STANDING && targetEntity.hasVehicle()) {
if (configs.renderVehicle && poseOffsetMethod != Configs.PoseOffsetMethod.FORCE_STANDING && targetEntity.hasVehicle()) {
var vehicle = targetEntity.getVehicle();
assert vehicle != null;

Expand Down Expand Up @@ -125,9 +124,9 @@ public void render(float partialTicks) {
backup.restore();
}

private double getPoseOffsetY(LivingEntity targetEntity, float partialTicks, PoseOffsetMethod poseOffsetMethod) {
Configs configs = Configs.HANDLER.instance();
if (poseOffsetMethod == PoseOffsetMethod.AUTO) {
private double getPoseOffsetY(LivingEntity targetEntity, float partialTicks, Configs.PoseOffsetMethod poseOffsetMethod) {
Configs configs = Configs.getInstance();
if (poseOffsetMethod == Configs.PoseOffsetMethod.AUTO) {
final float defaultPlayerEyeHeight = PlayerEntity.DEFAULT_EYE_HEIGHT;
final float defaultPlayerSwimmingBBHeight = PlayerEntity.field_30650;
final float eyeHeightRatio = 0.85f;
Expand All @@ -142,7 +141,7 @@ private double getPoseOffsetY(LivingEntity targetEntity, float partialTicks, Pos
} else {
return PlayerEntity.DEFAULT_EYE_HEIGHT - targetEntity.getStandingEyeHeight();
}
} else if (poseOffsetMethod == PoseOffsetMethod.MANUAL) {
} else if (poseOffsetMethod == Configs.PoseOffsetMethod.MANUAL) {
if (targetEntity.isFallFlying()) {
return configs.elytraOffsetY * getFallFlyingLeaning(targetEntity, partialTicks);
} else if ((targetEntity.isInSwimmingPose()) && targetEntity.getLeaningPitch(partialTicks) > 0 || targetEntity.isUsingRiptide()) { // require nonzero leaning to filter out glitch
Expand All @@ -157,7 +156,7 @@ private double getPoseOffsetY(LivingEntity targetEntity, float partialTicks, Pos
}

private void transformEntity(LivingEntity targetEntity, float partialTicks, boolean forceStanding) {
Configs configs = Configs.HANDLER.instance();
Configs configs = Configs.getInstance();
// synchronize values to remove glitch
if (!targetEntity.isSwimming() && !targetEntity.isFallFlying() && !targetEntity.isCrawling()) {
targetEntity.setPose(targetEntity.isInSneakingPose() ? EntityPose.CROUCHING : EntityPose.STANDING);
Expand Down Expand Up @@ -207,7 +206,7 @@ private void transformEntity(LivingEntity targetEntity, float partialTicks, bool
@SuppressWarnings("deprecation")
private void performRendering(Entity targetEntity, double posX, double posY, double size, boolean mirror,
Vector3f offset, double lightDegree, float partialTicks) {
Configs configs = Configs.HANDLER.instance();
Configs configs = Configs.getInstance();
EntityRenderDispatcher entityRenderDispatcher = client.getEntityRenderDispatcher();

Matrix4fStack matrixStack1 = RenderSystem.getModelViewStack();
Expand Down Expand Up @@ -263,7 +262,7 @@ private void performRendering(Entity targetEntity, double posX, double posY, dou
}

private static int getLight(Entity entity, float tickDelta) {
Configs configs = Configs.HANDLER.instance();
Configs configs = Configs.getInstance();
if (configs.useWorldLight) {
World world = entity.getWorld();
int blockLight = world.getLightLevel(LightType.BLOCK, BlockPos.ofFloored(entity.getCameraPosVec(tickDelta)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
public class ModMenuApiImpl implements ModMenuApi {
@Override
public ConfigScreenFactory<?> getModConfigScreenFactory() {
return screen -> Configs.HANDLER.generateGui().generateScreen(screen);
return Configs::genGui;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package github.io.lucunji.explayerenderer.config;

import dev.isxander.yacl3.api.NameableEnum;
import dev.isxander.yacl3.api.YetAnotherConfigLib;
import dev.isxander.yacl3.api.utils.OptionUtils;
import dev.isxander.yacl3.config.v2.api.ConfigClassHandler;
import dev.isxander.yacl3.config.v2.api.SerialEntry;
import dev.isxander.yacl3.config.v2.api.autogen.*;
Expand All @@ -12,13 +15,23 @@
import net.minecraft.util.Identifier;

public class Configs {
public static ConfigClassHandler<Configs> HANDLER = ConfigClassHandler.createBuilder(Configs.class)
private static final ConfigClassHandler<Configs> HANDLER = ConfigClassHandler.createBuilder(Configs.class)
.id(Identifier.of(Main.MOD_ID, "config"))
.serializer(config -> GsonConfigSerializerBuilder.create(config)
.setPath(FabricLoader.getInstance().getConfigDir().resolve(Main.MOD_ID + "_yacl.json"))
.build())
.build();

public static Configs getInstance() {
return HANDLER.instance();
}

public static Screen genGui(Screen parent) {
YetAnotherConfigLib yacl = HANDLER.generateGui();
OptionUtils.forEachOptions(yacl, option -> option.addListener((o, p) -> o.applyValue()));
return yacl.generateScreen(parent);
}

public static boolean isConfigScreen(Screen screen) {
return screen != null && screen.getTitle() != null && screen.getTitle().equals(Text.translatable("yacl3.config." + Main.MOD_ID + ":config.title"));
}
Expand Down Expand Up @@ -135,4 +148,19 @@ public static boolean isConfigScreen(Screen screen) {
@AutoGen(category = "details")
@Boolean
public boolean renderVehicle = true;

public enum PoseOffsetMethod implements NameableEnum {
AUTO, MANUAL, FORCE_STANDING, DISABLED;

public final String nameKey;

PoseOffsetMethod() {
this.nameKey = "yacl3.config." + Main.MOD_ID + ":config.poseOffsetMethod." + this.name();
}

@Override
public Text getDisplayName() {
return Text.translatable(this.nameKey);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package github.io.lucunji.explayerenderer.config;

public interface OptionPatch<T> {
T extraPlayerRenderer$getSavedValue();
boolean extraPlayerRenderer$savePendingValue();
void extraPlayerRenderer$restoreSavedValue();
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package github.io.lucunji.explayerenderer.mixin.yacl.patch;

import com.google.common.collect.ImmutableSet;
import dev.isxander.yacl3.api.*;
import dev.isxander.yacl3.impl.OptionImpl;
import github.io.lucunji.explayerenderer.config.Configs;
import github.io.lucunji.explayerenderer.config.OptionPatch;
import net.minecraft.client.MinecraftClient;
import net.minecraft.text.Text;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Final;
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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

import java.util.Collection;
import java.util.Objects;
import java.util.function.BiConsumer;
import java.util.function.Function;

@SuppressWarnings("UnstableApiUsage")
@Mixin(value = OptionImpl.class, priority = Integer.MIN_VALUE)
public abstract class OptionImplMixin<T> implements Option<T>, OptionPatch<T> {
@Shadow
@Final
private Binding<T> binding;
@Shadow private T pendingValue;
@Shadow public abstract boolean applyValue();

@Shadow public abstract void requestSet(@NotNull T value);

/**
* We should rename it to isDirty
*/
@Shadow public abstract boolean changed();

@Shadow public abstract boolean isPendingValueDefault();

@Unique private T savedValue;

@Inject(method = "<init>", at = @At("RETURN"), remap = false)
public void onInit(
@NotNull Text name,
@NotNull Function<T, OptionDescription> descriptionFunction,
@NotNull Function<Option<T>, Controller<T>> controlGetter,
@NotNull Binding<T> binding,
boolean available,
ImmutableSet<OptionFlag> flags,
@NotNull Collection<BiConsumer<Option<T>, T>> listeners,
CallbackInfo ci) {
this.savedValue = binding.getValue();
}

@Inject(method = "changed", at = @At("HEAD"), cancellable = true, remap = false)
public void onChanged(CallbackInfoReturnable<Boolean> cir) {
if (!Configs.isConfigScreen(MinecraftClient.getInstance().currentScreen)) return;
// the second case is needed to allow applyValue to work when running Undo/Cancel
cir.setReturnValue(!Objects.equals(pendingValue, savedValue) || !Objects.equals(pendingValue, binding.getValue()));
}


@Unique
@Override
public T extraPlayerRenderer$getSavedValue() {
return savedValue;
}

@Unique
@Override
public boolean extraPlayerRenderer$savePendingValue() {
if (changed()) {
binding().setValue(savedValue = pendingValue);
return true;
}
return false;
}

@Unique
@Override
public void extraPlayerRenderer$restoreSavedValue() {
requestSet(savedValue);
}
}
Loading

0 comments on commit e7cbc29

Please sign in to comment.