Split mod into core, recording, replay, render[todo], paths[todo] and extras[wip] modules
Move everything to com.replaymod package Add KeyBindingRegistry and SettingsRegistry Recreate settings GUI with new GUI API and dynamically from SettingsRegistry Use ReplayFile from ReplayStudio ReplayHandler is now object oriented Add GuiOverlay, GuiSlider and GuiTexturedButton to GUI API Rewrite both overlays to use new GUI API Fix size capping in vertical and horizontal layout Allow CustomLayouts to have parents Fix tooltip rendering when close to screen border Allow changing of columns in GridLayout
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
package eu.crushedpixel.replaymod.mixin;
|
||||
|
||||
import com.replaymod.replay.CameraEntity;
|
||||
import eu.crushedpixel.replaymod.renderer.SpectatorRenderer;
|
||||
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
||||
import eu.crushedpixel.replaymod.settings.RenderOptions;
|
||||
import eu.crushedpixel.replaymod.video.EntityRendererHandler;
|
||||
import eu.crushedpixel.replaymod.video.capturer.CubicOpenGlFrameCapturer;
|
||||
@@ -18,6 +18,7 @@ import net.minecraft.util.MovingObjectPosition;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.util.glu.Project;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
@@ -25,6 +26,9 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(EntityRenderer.class)
|
||||
public abstract class MixinEntityRenderer implements EntityRendererHandler.IEntityRenderer, EntityRendererHandler.GluPerspective {
|
||||
@Shadow
|
||||
public Minecraft mc;
|
||||
|
||||
private EntityRendererHandler handler;
|
||||
private SpectatorRenderer spectatorRenderer = new SpectatorRenderer();
|
||||
|
||||
@@ -65,8 +69,8 @@ public abstract class MixinEntityRenderer implements EntityRendererHandler.IEnti
|
||||
if (options.getIgnoreCameraRotation()[1]) {
|
||||
entity.prevRotationPitch = entity.rotationPitch = 0;
|
||||
}
|
||||
if (options.getIgnoreCameraRotation()[2]) {
|
||||
ReplayHandler.setCameraTilt(0);
|
||||
if (options.getIgnoreCameraRotation()[2] && entity instanceof CameraEntity) {
|
||||
((CameraEntity) entity).roll = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -85,7 +89,7 @@ public abstract class MixinEntityRenderer implements EntityRendererHandler.IEnti
|
||||
orgPitch = entity.rotationPitch;
|
||||
orgPrevYaw = entity.prevRotationYaw;
|
||||
orgPrevPitch = entity.prevRotationPitch;
|
||||
orgRoll = ReplayHandler.getCameraTilt();
|
||||
orgRoll = entity instanceof CameraEntity ? ((CameraEntity) entity).roll : 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,28 +101,31 @@ public abstract class MixinEntityRenderer implements EntityRendererHandler.IEnti
|
||||
entity.rotationPitch = orgPitch;
|
||||
entity.prevRotationYaw = orgPrevYaw;
|
||||
entity.prevRotationPitch = orgPrevPitch;
|
||||
ReplayHandler.setCameraTilt(orgRoll);
|
||||
if (entity instanceof CameraEntity) {
|
||||
((CameraEntity) entity).roll = orgRoll;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "renderHand", at = @At("HEAD"), cancellable = true)
|
||||
private void renderSpectatorHand(float partialTicks, int renderPass, CallbackInfo ci) {
|
||||
if (handler != null) {
|
||||
if (handler.data instanceof CubicOpenGlFrameCapturer.Data) {
|
||||
ci.cancel();
|
||||
return; // No spectator hands during 360° view, we wouldn't even know where to put it
|
||||
}
|
||||
Entity currentEntity = Minecraft.getMinecraft().getRenderViewEntity();
|
||||
if (!ReplayHandler.isCamera() && currentEntity instanceof EntityPlayer) {
|
||||
renderPass = handler.data == StereoscopicOpenGlFrameCapturer.Data.LEFT_EYE ? 1 : 0;
|
||||
spectatorRenderer.renderSpectatorHand((EntityPlayer) currentEntity, partialTicks, renderPass);
|
||||
}
|
||||
} else if (ReplayHandler.isInReplay() && !ReplayHandler.isCamera()) {
|
||||
Entity currentEntity = Minecraft.getMinecraft().getRenderViewEntity();
|
||||
if (!ReplayHandler.isCamera() && currentEntity instanceof EntityPlayer) {
|
||||
spectatorRenderer.renderSpectatorHand((EntityPlayer) currentEntity, partialTicks, renderPass);
|
||||
}
|
||||
}
|
||||
// TODO
|
||||
// if (handler != null) {
|
||||
// if (handler.data instanceof CubicOpenGlFrameCapturer.Data) {
|
||||
// ci.cancel();
|
||||
// return; // No spectator hands during 360° view, we wouldn't even know where to put it
|
||||
// }
|
||||
// Entity currentEntity = Minecraft.getMinecraft().getRenderViewEntity();
|
||||
// if (!ReplayHandler.isCameraView() && currentEntity instanceof EntityPlayer) {
|
||||
// renderPass = handler.data == StereoscopicOpenGlFrameCapturer.Data.LEFT_EYE ? 1 : 0;
|
||||
// spectatorRenderer.renderSpectatorHand((EntityPlayer) currentEntity, partialTicks, renderPass);
|
||||
// }
|
||||
// } else if (ReplayHandler.isInReplay() && !ReplayHandler.isCameraView()) {
|
||||
// Entity currentEntity = Minecraft.getMinecraft().getRenderViewEntity();
|
||||
// if (!ReplayHandler.isCameraView() && currentEntity instanceof EntityPlayer) {
|
||||
// spectatorRenderer.renderSpectatorHand((EntityPlayer) currentEntity, partialTicks, renderPass);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
@Redirect(method = "renderWorldPass", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/RenderGlobal;drawSelectionBox(Lnet/minecraft/entity/player/EntityPlayer;Lnet/minecraft/util/MovingObjectPosition;IF)V"))
|
||||
@@ -242,8 +249,8 @@ public abstract class MixinEntityRenderer implements EntityRendererHandler.IEnti
|
||||
|
||||
@Inject(method = "orientCamera", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/GlStateManager;translate(FFF)V", shift = At.Shift.AFTER, ordinal = 3))
|
||||
private void setupCameraRoll(float partialTicks, CallbackInfo ci) {
|
||||
if (ReplayHandler.isInReplay()) {
|
||||
GL11.glRotated(ReplayHandler.getCameraTilt(), 0D, 0D, 1D);
|
||||
if (mc.getRenderViewEntity() instanceof CameraEntity) {
|
||||
GL11.glRotated(((CameraEntity) mc.getRenderViewEntity()).roll, 0D, 0D, 1D);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
package eu.crushedpixel.replaymod.mixin;
|
||||
|
||||
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
||||
import com.replaymod.replay.CameraEntity;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiSpectator;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(GuiSpectator.class)
|
||||
public abstract class MixinGuiSpectator {
|
||||
@Shadow
|
||||
private Minecraft field_175268_g;
|
||||
|
||||
@Inject(method = "func_175260_a", at = @At("HEAD"), cancellable = true)
|
||||
public void isInReplay(int i, CallbackInfo ci) {
|
||||
if (ReplayHandler.isInReplay()) {
|
||||
if (field_175268_g.thePlayer instanceof CameraEntity) {
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package eu.crushedpixel.replaymod.mixin;
|
||||
|
||||
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.audio.SoundHandler;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
@@ -12,6 +11,7 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
public class MixinMinecraft {
|
||||
@Redirect(method = "runGameLoop", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/audio/SoundHandler;setListener(Lnet/minecraft/entity/player/EntityPlayer;F)V"))
|
||||
public void setSoundSystemListener(SoundHandler soundHandler, EntityPlayer listener, float renderPartialTicks) {
|
||||
soundHandler.setListener(ReplayHandler.isInReplay() ? ReplayHandler.getCameraEntity() : listener, renderPartialTicks);
|
||||
//TODO might no longer be necessary?
|
||||
// soundHandler.setListener(ReplayHandler.isInReplay() ? ReplayHandler.getCameraEntity() : listener, renderPartialTicks);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
package eu.crushedpixel.replaymod.mixin;
|
||||
|
||||
import eu.crushedpixel.replaymod.ReplayMod;
|
||||
import eu.crushedpixel.replaymod.recording.ConnectionEventHandler;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.network.NetHandlerPlayClient;
|
||||
import net.minecraft.network.play.server.S07PacketRespawn;
|
||||
import net.minecraft.network.play.server.S38PacketPlayerListItem;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(NetHandlerPlayClient.class)
|
||||
public abstract class MixinNetHandlerPlayClient {
|
||||
|
||||
/**
|
||||
* Record the own player entity joining the world.
|
||||
* We cannot use the {@link net.minecraftforge.event.entity.EntityJoinWorldEvent} because the entity id
|
||||
* of the player is set afterwards and the tablist entry might not yet be sent.
|
||||
* @param packet The packet
|
||||
* @param ci Callback info
|
||||
*/
|
||||
@Inject(method = "handlePlayerListItem", at=@At("RETURN"))
|
||||
public void recordOwnJoin(S38PacketPlayerListItem packet, CallbackInfo ci) {
|
||||
if (ConnectionEventHandler.isRecording() && packet.func_179768_b() == S38PacketPlayerListItem.Action.ADD_PLAYER) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<S38PacketPlayerListItem.AddPlayerData> dataList = packet.func_179767_a();
|
||||
for (S38PacketPlayerListItem.AddPlayerData data : dataList) {
|
||||
if (data.func_179962_a().getId().equals(Minecraft.getMinecraft().thePlayer.getGameProfile().getId())) {
|
||||
ReplayMod.recordingHandler.onPlayerJoin();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Record the own player entity respawning.
|
||||
* We cannot use the {@link net.minecraftforge.event.entity.EntityJoinWorldEvent} because that would also include
|
||||
* the first spawn which is already handled by {@link #recordOwnJoin(S38PacketPlayerListItem, CallbackInfo)}.
|
||||
* @param packet The packet
|
||||
* @param ci Callback info
|
||||
*/
|
||||
@Inject(method = "handleRespawn", at=@At("RETURN"))
|
||||
public void recordOwnRespawn(S07PacketRespawn packet, CallbackInfo ci) {
|
||||
if (ConnectionEventHandler.isRecording()) {
|
||||
ReplayMod.recordingHandler.onPlayerRespawn();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package eu.crushedpixel.replaymod.mixin;
|
||||
|
||||
import eu.crushedpixel.replaymod.entities.CameraEntity;
|
||||
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
||||
import com.replaymod.replay.CameraEntity;
|
||||
import com.replaymod.replay.ReplayModReplay;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.multiplayer.PlayerControllerMP;
|
||||
@@ -25,7 +25,7 @@ public abstract class MixinPlayerControllerMP {
|
||||
|
||||
@Inject(method = "func_178892_a", at=@At("HEAD"), cancellable = true)
|
||||
public void createReplayCamera(World worldIn, StatFileWriter statFileWriter, CallbackInfoReturnable<EntityPlayerSP> ci) {
|
||||
if (ReplayHandler.isInReplay()) {
|
||||
if (ReplayModReplay.instance.getReplayHandler() != null) {
|
||||
ci.setReturnValue(new CameraEntity(mc, worldIn, netClientHandler, statFileWriter));
|
||||
ci.cancel();
|
||||
}
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
package eu.crushedpixel.replaymod.mixin;
|
||||
|
||||
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
||||
import net.minecraft.client.renderer.culling.ICamera;
|
||||
import net.minecraft.client.renderer.entity.Render;
|
||||
import net.minecraft.client.renderer.entity.RenderArrow;
|
||||
import net.minecraft.client.renderer.entity.RenderManager;
|
||||
import net.minecraft.entity.Entity;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
@Mixin(RenderArrow.class)
|
||||
@@ -14,8 +11,9 @@ public abstract class MixinRenderArrow extends Render {
|
||||
super(renderManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRender(Entity entity, ICamera camera, double camX, double camY, double camZ) {
|
||||
return ReplayHandler.isInReplay() || super.shouldRender(entity, camera, camX, camY, camZ);
|
||||
}
|
||||
// TODO
|
||||
// @Override
|
||||
// public boolean shouldRender(Entity entity, ICamera camera, double camX, double camY, double camZ) {
|
||||
// return ReplayHandler.isInReplay() || super.shouldRender(entity, camera, camX, camY, camZ);
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
package eu.crushedpixel.replaymod.mixin;
|
||||
|
||||
import eu.crushedpixel.replaymod.recording.ConnectionEventHandler;
|
||||
import eu.crushedpixel.replaymod.timer.EnchantmentTimer;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.RenderGlobal;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.network.play.server.S25PacketBlockBreakAnim;
|
||||
import net.minecraft.util.BlockPos;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
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;
|
||||
|
||||
@Mixin(RenderGlobal.class)
|
||||
public abstract class MixinRenderGlobal {
|
||||
@Inject(method = "sendBlockBreakProgress", at = @At("HEAD"))
|
||||
public void saveBlockBreakProgressPacket(int breakerId, BlockPos pos, int progress, CallbackInfo info) {
|
||||
if(ConnectionEventHandler.isRecording()) {
|
||||
EntityPlayer thePlayer = Minecraft.getMinecraft().thePlayer;
|
||||
if(thePlayer != null && breakerId == thePlayer.getEntityId()) {
|
||||
ConnectionEventHandler.insertPacket(new S25PacketBlockBreakAnim(breakerId, pos, progress));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Redirect(method = "renderWorldBorder", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;getSystemTime()J"))
|
||||
private long getEnchantmentTime() {
|
||||
return EnchantmentTimer.getEnchantmentTime();
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
package eu.crushedpixel.replaymod.mixin;
|
||||
|
||||
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
||||
import eu.crushedpixel.replaymod.settings.ReplaySettings;
|
||||
import eu.crushedpixel.replaymod.video.EntityRendererHandler;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.entity.RendererLivingEntity;
|
||||
@@ -22,17 +20,19 @@ public abstract class MixinRendererLivingEntity {
|
||||
ci.setReturnValue(false); //this calls the cancel method
|
||||
}
|
||||
|
||||
if(ReplayHandler.isInReplay() && entity.isInvisible()
|
||||
&& ReplaySettings.ReplayOptions.renderInvisible.getValue() == Boolean.FALSE) {
|
||||
ci.setReturnValue(false);
|
||||
}
|
||||
// TODO
|
||||
// if(ReplayHandler.isInReplay() && entity.isInvisible()
|
||||
// && ReplaySettings.ReplayOptions.renderInvisible.getValue() == Boolean.FALSE) {
|
||||
// ci.setReturnValue(false);
|
||||
// }
|
||||
}
|
||||
|
||||
@Redirect(method = "renderModel", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/EntityLivingBase;isInvisibleToPlayer(Lnet/minecraft/entity/player/EntityPlayer;)Z"))
|
||||
private boolean shouldInvisibleNotBeRendered(EntityLivingBase entity, EntityPlayer thePlayer) {
|
||||
if(ReplaySettings.ReplayOptions.renderInvisible.getValue() == Boolean.TRUE|| !ReplayHandler.isInReplay()) {
|
||||
return entity.isInvisibleToPlayer(thePlayer);
|
||||
}
|
||||
// TODO
|
||||
// if(ReplaySettings.ReplayOptions.renderInvisible.getValue() == Boolean.TRUE|| !ReplayHandler.isInReplay()) {
|
||||
// return entity.isInvisibleToPlayer(thePlayer);
|
||||
// }
|
||||
return true; //the original method inverts the return value
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package eu.crushedpixel.replaymod.mixin;
|
||||
|
||||
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
||||
import net.minecraft.client.renderer.RenderGlobal;
|
||||
import net.minecraft.client.renderer.ViewFrustum;
|
||||
import net.minecraft.client.renderer.chunk.IRenderChunkFactory;
|
||||
@@ -39,9 +38,10 @@ public abstract class MixinViewFrustum {
|
||||
*/
|
||||
@Inject(method = "updateChunkPositions", at = @At("HEAD"), cancellable = true)
|
||||
public void fixedUpdateChunkPositions(double viewEntityX, double viewEntityZ, CallbackInfo ci) {
|
||||
if (!ReplayHandler.isInReplay()) {
|
||||
return;
|
||||
}
|
||||
// TODO
|
||||
// if (!ReplayHandler.isInReplay()) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
int i = MathHelper.floor_double(viewEntityX) - 8;
|
||||
int j = MathHelper.floor_double(viewEntityZ) - 8;
|
||||
|
||||
Reference in New Issue
Block a user