Play sounds during replay relative to camera
This commit is contained in:
@@ -11,6 +11,7 @@ public class LoadingPlugin implements IFMLLoadingPlugin {
|
|||||||
return new String[]{
|
return new String[]{
|
||||||
CameraRollCT.class.getName(),
|
CameraRollCT.class.getName(),
|
||||||
ForceChunkLoadingCT.class.getName(),
|
ForceChunkLoadingCT.class.getName(),
|
||||||
|
SoundManagerCT.class.getName(),
|
||||||
EnchantmentTimerCT.class.getName()
|
EnchantmentTimerCT.class.getName()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package eu.crushedpixel.replaymod.coremod;
|
||||||
|
|
||||||
|
import net.minecraft.launchwrapper.IClassTransformer;
|
||||||
|
import org.objectweb.asm.ClassReader;
|
||||||
|
import org.objectweb.asm.ClassWriter;
|
||||||
|
import org.objectweb.asm.tree.*;
|
||||||
|
|
||||||
|
import java.util.ListIterator;
|
||||||
|
|
||||||
|
import static org.objectweb.asm.Opcodes.*;
|
||||||
|
import static org.objectweb.asm.Opcodes.INVOKESTATIC;
|
||||||
|
|
||||||
|
public class SoundManagerCT implements IClassTransformer {
|
||||||
|
|
||||||
|
private static final String REPLAY_HANDLER = "eu/crushedpixel/replaymod/replay/ReplayHandler";
|
||||||
|
private static final String CAMERA_ENTITY = "eu/crushedpixel/replaymod/entities/CameraEntity";
|
||||||
|
private static final String CLASS_NAME = "net.minecraft.client.audio.SoundManager";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] transform(String name, String transformedName, byte[] bytes) {
|
||||||
|
if (CLASS_NAME.equals(transformedName)) {
|
||||||
|
if (name.equals(transformedName)) {
|
||||||
|
return transform(bytes, "setListener", "(Lnet/minecraft/entity/player/EntityPlayer;F)V");
|
||||||
|
} else {
|
||||||
|
return transform(bytes, "a", "(Lahd;F)V");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] transform(byte[] bytes, String name_setListener, String desc_setListener) {
|
||||||
|
ClassReader classReader = new ClassReader(bytes);
|
||||||
|
ClassNode classNode = new ClassNode();
|
||||||
|
classReader.accept(classNode, 0);
|
||||||
|
|
||||||
|
boolean success = false;
|
||||||
|
for (MethodNode m : classNode.methods) {
|
||||||
|
if (desc_setListener.equals(m.desc) && name_setListener.equals(m.name)) {
|
||||||
|
ListIterator<AbstractInsnNode> iter = m.instructions.iterator();
|
||||||
|
inject(iter);
|
||||||
|
success = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!success) {
|
||||||
|
throw new NoSuchMethodError();
|
||||||
|
}
|
||||||
|
|
||||||
|
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
|
||||||
|
classNode.accept(classWriter);
|
||||||
|
return classWriter.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* public void setListener(EntityPlayer player, float partialTicks) {
|
||||||
|
* ...
|
||||||
|
* if (ReplayHandler.isInReplay()) {
|
||||||
|
* player = ReplayHandler.getCameraEntity();
|
||||||
|
* }
|
||||||
|
* ...
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
private void inject(ListIterator<AbstractInsnNode> iter) {
|
||||||
|
LabelNode l = new LabelNode();
|
||||||
|
iter.add(new MethodInsnNode(INVOKESTATIC, REPLAY_HANDLER, "isInReplay", "()Z", false));
|
||||||
|
iter.add(new JumpInsnNode(IFEQ, l));
|
||||||
|
iter.add(new MethodInsnNode(INVOKESTATIC, REPLAY_HANDLER, "getCameraEntity", "()L" + CAMERA_ENTITY + ";", false));
|
||||||
|
iter.add(new VarInsnNode(ASTORE, 1));
|
||||||
|
iter.add(l);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,12 +4,15 @@ import eu.crushedpixel.replaymod.holders.Position;
|
|||||||
import eu.crushedpixel.replaymod.replay.LesserDataWatcher;
|
import eu.crushedpixel.replaymod.replay.LesserDataWatcher;
|
||||||
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.MathHelper;
|
import net.minecraft.util.MathHelper;
|
||||||
import net.minecraft.util.MovingObjectPosition;
|
import net.minecraft.util.MovingObjectPosition;
|
||||||
import net.minecraft.util.Vec3;
|
import net.minecraft.util.Vec3;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
||||||
import org.lwjgl.Sys;
|
import org.lwjgl.Sys;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
@@ -31,6 +34,25 @@ public class CameraEntity extends EntityPlayer {
|
|||||||
super(worldIn, Minecraft.getMinecraft().getSession().getProfile());
|
super(worldIn, Minecraft.getMinecraft().getSession().getProfile());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public void tick(TickEvent.ClientTickEvent event) {
|
||||||
|
if (event.phase == TickEvent.Phase.END) {
|
||||||
|
Entity view = Minecraft.getMinecraft().getRenderViewEntity();
|
||||||
|
if (view != this) {
|
||||||
|
prevPosX = view.prevPosX;
|
||||||
|
prevPosY = view.prevPosY;
|
||||||
|
prevPosZ = view.prevPosZ;
|
||||||
|
prevRotationYaw = view.prevRotationYaw;
|
||||||
|
prevRotationPitch = view.prevRotationPitch;
|
||||||
|
posX = view.posX;
|
||||||
|
posY = view.posY;
|
||||||
|
posZ = view.posZ;
|
||||||
|
rotationYaw = view.rotationYaw;
|
||||||
|
rotationPitch = view.rotationPitch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//frac = time since last tick
|
//frac = time since last tick
|
||||||
public void updateMovement() {
|
public void updateMovement() {
|
||||||
Minecraft mc = Minecraft.getMinecraft();
|
Minecraft mc = Minecraft.getMinecraft();
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import net.minecraft.entity.Entity;
|
|||||||
import net.minecraft.network.EnumPacketDirection;
|
import net.minecraft.network.EnumPacketDirection;
|
||||||
import net.minecraft.network.NetworkManager;
|
import net.minecraft.network.NetworkManager;
|
||||||
import net.minecraft.network.play.INetHandlerPlayClient;
|
import net.minecraft.network.play.INetHandlerPlayClient;
|
||||||
|
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||||
import net.minecraftforge.fml.common.network.handshake.NetworkDispatcher;
|
import net.minecraftforge.fml.common.network.handshake.NetworkDispatcher;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -119,7 +120,11 @@ public class ReplayHandler {
|
|||||||
|
|
||||||
public static void setCameraEntity(CameraEntity entity) {
|
public static void setCameraEntity(CameraEntity entity) {
|
||||||
if(entity == null) return;
|
if(entity == null) return;
|
||||||
|
if (cameraEntity != null) {
|
||||||
|
FMLCommonHandler.instance().bus().unregister(cameraEntity);
|
||||||
|
}
|
||||||
cameraEntity = entity;
|
cameraEntity = entity;
|
||||||
|
FMLCommonHandler.instance().bus().register(cameraEntity);
|
||||||
spectateCamera();
|
spectateCamera();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
|
|||||||
* These packets are ignored completely during replay.
|
* These packets are ignored completely during replay.
|
||||||
*/
|
*/
|
||||||
private static final List<Class> BAD_PACKETS = Arrays.<Class>asList(
|
private static final List<Class> BAD_PACKETS = Arrays.<Class>asList(
|
||||||
S28PacketEffect.class,
|
|
||||||
S2BPacketChangeGameState.class,
|
S2BPacketChangeGameState.class,
|
||||||
S06PacketUpdateHealth.class,
|
S06PacketUpdateHealth.class,
|
||||||
S2DPacketOpenWindow.class,
|
S2DPacketOpenWindow.class,
|
||||||
@@ -255,9 +254,11 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
|
|||||||
protected Packet processPacket(Packet p) throws Exception {
|
protected Packet processPacket(Packet p) throws Exception {
|
||||||
if(BAD_PACKETS.contains(p.getClass())) return null;
|
if(BAD_PACKETS.contains(p.getClass())) return null;
|
||||||
|
|
||||||
if(p instanceof S29PacketSoundEffect && ReplayProcess.isVideoRecording()) {
|
if (p instanceof S29PacketSoundEffect || p instanceof S28PacketEffect) {
|
||||||
|
if (!asyncMode || isHurrying()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(p instanceof S03PacketTimeUpdate) {
|
if(p instanceof S03PacketTimeUpdate) {
|
||||||
p = TimeHandler.getTimePacket((S03PacketTimeUpdate) p);
|
p = TimeHandler.getTimePacket((S03PacketTimeUpdate) p);
|
||||||
|
|||||||
Reference in New Issue
Block a user