Skip to content

Commit

Permalink
[VirtualInput] More documentation and tests
Browse files Browse the repository at this point in the history
- [Util] Added documentation
- [Util] Refactored PointerNormalizer
- [Gui] Disabled trajectories from InfoHud
- [VirtualInput] Refactored MixinEntityRenderer
  • Loading branch information
ScribbleTAS committed Feb 15, 2024
1 parent 1fb45a5 commit bba6ac7
Show file tree
Hide file tree
Showing 12 changed files with 282 additions and 115 deletions.
24 changes: 12 additions & 12 deletions src/main/java/com/minecrafttas/tasmod/gui/InfoHud.java
Original file line number Diff line number Diff line change
Expand Up @@ -350,18 +350,18 @@ public boolean checkInit() {
// return String.format("Mouse Cursor: " + TASmodClient.virtual.getNextMouse().getPath().get(0).cursorX + " " + TASmodClient.virtual.getNextMouse().getPath().get(0).cursorY);
// })); TODO Remove?

title = "trajectories";
y += 14;
if (configuration.getProperty(title + "_x", "err").equals("err")) setDefaults(title, y);
lists.add(new InfoLabel(title, Integer.parseInt(configuration.getProperty(title + "_x")), Integer.parseInt(configuration.getProperty(title + "_y")), Boolean.parseBoolean(configuration.getProperty(title + "_visible")), Boolean.parseBoolean(configuration.getProperty(title + "_rect")), () -> {
if (Minecraft.getMinecraft().currentScreen == this) return "Trajectories";
String message = "Invalid Item";
Vec3d vec = TrajectoriesCalculator.calculate();
if (vec != null) {
message = String.format("%.3f %.3f %.3f", vec.x, vec.y, vec.z);
}
return String.format("Trajectories: " + message);
}));
// title = "trajectories";
// y += 14;
// if (configuration.getProperty(title + "_x", "err").equals("err")) setDefaults(title, y);
// lists.add(new InfoLabel(title, Integer.parseInt(configuration.getProperty(title + "_x")), Integer.parseInt(configuration.getProperty(title + "_y")), Boolean.parseBoolean(configuration.getProperty(title + "_visible")), Boolean.parseBoolean(configuration.getProperty(title + "_rect")), () -> {
// if (Minecraft.getMinecraft().currentScreen == this) return "Trajectories";
// String message = "Invalid Item";
// Vec3d vec = TrajectoriesCalculator.calculate();
// if (vec != null) {
// message = String.format("%.3f %.3f %.3f", vec.x, vec.y, vec.z);
// }
// return String.format("Trajectories: " + message);
// }));

title = "velocity";
y += 14;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.minecrafttas.tasmod.util.Ducks.SubtickDuck;
import com.minecrafttas.tasmod.virtual.VirtualInput;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.renderer.EntityRenderer;
import net.minecraft.util.math.MathHelper;
import org.lwjgl.input.Mouse;
Expand All @@ -16,11 +17,17 @@
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.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

/**
* Redirects the camera to use {@link VirtualInput.VirtualCameraAngleInput}.<br>
* Also conforms the camera to 20tps as
* To support handling the camera in TASes and to avoid desyncs via lag,<br>
* it was decided to only update the camera every tick.<br>
* <br>
* To achieve this, some parts of the vanilla code were disabled, but get called every tick in {@link #runUpdate(float)}
*
* @author Scribble, Pancake
*/
@Mixin(EntityRenderer.class)
public class MixinEntityRenderer implements SubtickDuck {
Expand Down Expand Up @@ -63,8 +70,8 @@ public void playback_injectAtStartSection(float partialTicks, long nanoTime, Cal
dX = 0;
dY = 0;
} else {
// Comment this out to disable interpolation, also comment out @SubscribeEvent
// in InterpolationEvents
// Comment this out to disable interpolation
// - Pancake
if (this.mc.currentScreen == null) {
InterpolationHandler.rotationYaw = ((float) ((double) InterpolationHandler.rotationYaw + (double) mc.mouseHelper.deltaX * f1 * 0.15D));
InterpolationHandler.rotationPitch = (float) ((double) InterpolationHandler.rotationPitch - (double) mc.mouseHelper.deltaY * f1 * 0.15D);
Expand All @@ -73,47 +80,43 @@ public void playback_injectAtStartSection(float partialTicks, long nanoTime, Cal
}
}

@ModifyExpressionValue(method = "updateCameraAndRender", at = @At(value = "FIELD", target = "Lnet/minecraft/client/Minecraft;inGameHasFocus:Z", opcode = Opcodes.GETFIELD))
public boolean playback_stopVanilla(boolean original){
return original && TASmodClient.tickratechanger.ticksPerSecond == 0;
@Redirect(method = "updateCameraAndRender", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/EntityPlayerSP;turn(FF)V"))
public void playback_stopVanilla(EntityPlayerSP player, float deltaYaw, float deltaPitch){
if(TASmodClient.tickratechanger.ticksPerSecond == 0){
player.turn(deltaYaw, deltaPitch);
}
}

@Override
public void runUpdate(float partialTicks) {
boolean flag = Display.isActive();
if (flag && Minecraft.IS_RUNNING_ON_MAC && mc.inGameHasFocus && !Mouse.isInsideWindow()) {
Mouse.setGrabbed(false);
Mouse.setCursorPosition(Display.getWidth() / 2, Display.getHeight() / 2 - 20);
Mouse.setGrabbed(true);
}
boolean isDisplayActive = Display.isActive();

if (mc.inGameHasFocus && flag) {
mc.getTutorial().handleMouse(mc.mouseHelper);
float f = mc.gameSettings.mouseSensitivity * 0.6F + 0.2F;
float f1 = f * f * f * 8.0F;
float f2 = (float) dX * f1;
float f3 = (float) dY * f1;
int i = 1;
if (mc.inGameHasFocus && isDisplayActive) {
float mouseSensitivity = mc.gameSettings.mouseSensitivity * 0.6F + 0.2F;
float cubedSensitivity = mouseSensitivity * mouseSensitivity * mouseSensitivity * 8.0F;
float yawDelta = (float) dX * cubedSensitivity;
float pitchDelta = (float) dY * cubedSensitivity;
int isInverted = 1;

dX = 0;
dY = 0;

if (mc.gameSettings.invertMouse) {
i = -1;
isInverted = -1;
}

if (mc.gameSettings.smoothCamera) {
smoothCamYaw += f2;
smoothCamPitch += f3;
float f4 = partialTicks - smoothCamPartialTicks;
smoothCamYaw += yawDelta;
smoothCamPitch += pitchDelta;
float smoothCamTimerframe = partialTicks - smoothCamPartialTicks;
smoothCamPartialTicks = partialTicks;
f2 = smoothCamFilterX * f4;
f3 = smoothCamFilterY * f4;
mc.player.turn(f2, f3 * (float) i);
yawDelta = smoothCamFilterX * smoothCamTimerframe;
pitchDelta = smoothCamFilterY * smoothCamTimerframe;
mc.player.turn(yawDelta, pitchDelta * (float) isInverted);
} else {
smoothCamYaw = 0.0F;
smoothCamPitch = 0.0F;
mc.player.turn(f2, f3 * (float) i);
mc.player.turn(yawDelta, pitchDelta * (float) isInverted);
}
TASmodClient.virtual.CAMERA_ANGLE.updateCameraAngle(mc.player.rotationPitch, mc.player.rotationYaw);
mc.player.rotationPitch = TASmodClient.virtual.CAMERA_ANGLE.getPitch();
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/com/minecrafttas/tasmod/util/Ducks.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ public static interface GuiScreenDuck {
* Quacks the subtick
*/
public static interface SubtickDuck {
/**
* Custom updating method for EntityRenderer, updating the player rotation
* @param partialTicks The partial ticks from the vanilla Minecraft timer
*/
void runUpdate(float partialTicks);
}

Expand Down
9 changes: 7 additions & 2 deletions src/main/java/com/minecrafttas/tasmod/util/FileThread.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,17 @@
import java.util.ArrayList;
import java.util.List;

/**
* Thread for writing files to disc
*
* @author Pancake
*/
public class FileThread extends Thread {

private PrintWriter stream;
private final PrintWriter stream;
private boolean end = false;

private List<String> output = new ArrayList<String>();
private final List<String> output = new ArrayList<>();

public FileThread(File fileLocation, boolean append) throws FileNotFoundException {
stream = new PrintWriter(new OutputStreamWriter(new FileOutputStream(fileLocation, append), StandardCharsets.UTF_8));
Expand Down
84 changes: 44 additions & 40 deletions src/main/java/com/minecrafttas/tasmod/util/PointerNormalizer.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,100 +5,104 @@
import net.minecraft.client.gui.GuiWorldSelection;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.gui.inventory.GuiContainerCreative;

/**
* Adjusts the pointer/cursor of the playback to different gui scalings.
*
* This was the work of many hours of trial and error.
*
* Out of despair I reached out to Darkmoon to help me with this problem...
*
* @author ScribbleLP, Darkmoon
* Normalizes the cursor to be independent of gui scalings.<br>
* That way, a TAS recorded in e.g. Gui Scale "Large" can also be played back on Gui Scale "Small"
*
* @author Scribble, Darkmoon
*/
public class PointerNormalizer {

/**
* Mathematically removes scaling from the x coordinate
* @param pointerX The current pointer coordinate
* @return The normalized x coordinate
*/
public static int getNormalizedX(int pointerX) {
Minecraft mc = Minecraft.getMinecraft();
ScaledResolution scaled = new ScaledResolution(mc);
int out = (int) (pointerX - (scaled.getScaledWidth() / 2D));
return out;
return (int) (pointerX - (scaled.getScaledWidth() / 2D));
}

/**
* Mathematically removes scaling from the y coordinate
* @param pointerY The current pointer coordinate
* @return The normalized y coordinate
*/
public static int getNormalizedY(int pointerY) {
Minecraft mc = Minecraft.getMinecraft();
ScaledResolution scaled = new ScaledResolution(mc);

int out = pointerY;

if (mc.currentScreen instanceof GuiContainer || mc.currentScreen instanceof GuiContainerCreative) {
if (mc.currentScreen instanceof GuiContainer) {
out = (int) (pointerY - (scaled.getScaledHeight() / 2D));
} else if (mc.currentScreen instanceof GuiWorldSelection|| mc.currentScreen instanceof GuiMultiplayer) {

// TODO Figure out what to do here
} else {
out = (int) (pointerY - (scaled.getScaledHeight() / 4 + 72 + -16));
}

return out;
}

public static int getCoordsX(int normalizedX) {
/**
* Reapplies gui scaling to the normalized pointer x coordinate
* @param normalizedX The normalized pointer coordinate
* @return The scaled coordinate
*/
public static int reapplyScalingX(int normalizedX) {
Minecraft mc = Minecraft.getMinecraft();
ScaledResolution scaled = new ScaledResolution(mc);
int out = (int) Math.round(normalizedX + (scaled.getScaledWidth() / 2D));
return limiterX(out, scaled);
return clamp(out, 0, scaled.getScaledWidth());
}

public static int getCoordsY(int normalizedY) {
/**
* Reapplies gui scaling to the normalized pointer y coordinate
* @param normalizedY The normalized pointer coordinate
* @return The scaled coordinate
*/
public static int reapplyScalingY(int normalizedY) {
Minecraft mc = Minecraft.getMinecraft();
ScaledResolution scaled = new ScaledResolution(mc);

int out = normalizedY;
if (mc.currentScreen instanceof GuiContainer || mc.currentScreen instanceof GuiContainerCreative) {
if (mc.currentScreen instanceof GuiContainer) {
out = (int) Math.round(normalizedY + (scaled.getScaledHeight() / 2D));
} else if (mc.currentScreen instanceof GuiWorldSelection || mc.currentScreen instanceof GuiMultiplayer) {

// TODO Figure out what to do here
} else {
out = (int) (normalizedY + (scaled.getScaledHeight() / 4 + 72 + -16));
}

return limiterY(out, scaled);
}

private static int limiterX(int out, ScaledResolution scaled) {
int width = scaled.getScaledWidth();
if (out > width) {
out = width;
} else if (out < 0)
out = 0;
return out;
}

private static int limiterY(int out, ScaledResolution scaled) {
int height = scaled.getScaledHeight();
if (out > height) {
out = height;
} else if (out < 0)
out = 0;
return out;
return clamp(out, 0, scaled.getScaledHeight());
}

private static int gcd(int a, int b) {
return (b == 0) ? a : gcd(b, a % b);
private static int clamp(int value, int lower, int upper) {
if (value < lower) {
return lower;
} else {
return Math.min(value, upper);
}
}

public static void printAspectRatio() {
int height = Minecraft.getMinecraft().displayHeight;
int width = Minecraft.getMinecraft().displayWidth;
int gcd = gcd(width, height);
int gcd = greatestCommonDivisor(width, height);
if (gcd == 0) {
System.out.println(gcd);
} else {
System.out.println(width / gcd + ":" + height / gcd);
}
}


private static int greatestCommonDivisor(int a, int b) {
return (b == 0) ? a : greatestCommonDivisor(b, a % b);
}

/*
* Here lies 10 hours of work for something I didn't even use. This code
* normalizes the pointers coordinates and scales it depending on the screen
Expand Down
1 change: 0 additions & 1 deletion src/main/java/com/minecrafttas/tasmod/util/Scheduler.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
* A simple scheduling interface
*
* @author Scribble
*
*/
public class Scheduler {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.ResourceLocation;

/**
* Downloads shield textures from <a href="https://minecrafttas.com/>https://minecrafttas.com</a>
*
* @author Scribble
*/
public class ShieldDownloader implements EventPlayerJoinedClientSide, EventOtherPlayerJoinedClientSide{
private final ResourceLocation bottleshield = new ResourceLocation("tasmod:textures/shields/bottleshield.png");
private final String defaultshield = "bottleshield";
Expand Down
Loading

0 comments on commit bba6ac7

Please sign in to comment.