diff --git a/src/main/java/com/replaymod/replay/ReplayModReplay.java b/src/main/java/com/replaymod/replay/ReplayModReplay.java index 468d4892..c3bdd328 100644 --- a/src/main/java/com/replaymod/replay/ReplayModReplay.java +++ b/src/main/java/com/replaymod/replay/ReplayModReplay.java @@ -1,9 +1,11 @@ package com.replaymod.replay; +import com.google.common.base.Function; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.replaymod.core.ReplayMod; +import com.replaymod.replay.camera.*; import com.replaymod.replay.handler.GuiHandler; import de.johni0702.replaystudio.replay.ReplayFile; import de.johni0702.replaystudio.replay.ZipReplayFile; @@ -11,12 +13,15 @@ import de.johni0702.replaystudio.studio.ReplayStudio; import net.minecraft.client.Minecraft; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.event.FMLInitializationEvent; +import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import org.apache.logging.log4j.Logger; import org.lwjgl.input.Keyboard; +import javax.annotation.Nullable; import java.io.File; import java.io.IOException; +import java.util.ArrayList; @Mod(modid = ReplayModReplay.MOD_ID, useMetadata = true) public class ReplayModReplay { @@ -28,6 +33,8 @@ public class ReplayModReplay { @Mod.Instance(ReplayMod.MOD_ID) private static ReplayMod core; + private final CameraControllerRegistry cameraControllerRegistry = new CameraControllerRegistry(); + private Logger logger; private ReplayHandler replayHandler; @@ -83,6 +90,21 @@ public class ReplayModReplay { } } }); + + cameraControllerRegistry.register("replaymod.camera.classic", new Function() { + @Nullable + @Override + public CameraController apply(CameraEntity cameraEntity) { + return new ClassicCameraController(cameraEntity); + } + }); + cameraControllerRegistry.register("replaymod.camera.vanilla", new Function() { + @Nullable + @Override + public CameraController apply(@Nullable CameraEntity cameraEntity) { + return new VanillaCameraController(core.getMinecraft(), cameraEntity); + } + }); } @Mod.EventHandler @@ -93,6 +115,11 @@ public class ReplayModReplay { new GuiHandler(this).register(); } + @Mod.EventHandler + public void postInit(FMLPostInitializationEvent event) { + Setting.CAMERA.setChoices(new ArrayList<>(cameraControllerRegistry.getControllers())); + } + public void startReplay(File file) throws IOException { ReplayFile replayFile = new ZipReplayFile(new ReplayStudio(), file); replayHandler = new ReplayHandler(replayFile, true); @@ -105,4 +132,13 @@ public class ReplayModReplay { public Logger getLogger() { return logger; } + + public CameraControllerRegistry getCameraControllerRegistry() { + return cameraControllerRegistry; + } + + public CameraController createCameraController(CameraEntity cameraEntity) { + String controllerName = core.getSettingsRegistry().get(Setting.CAMERA); + return cameraControllerRegistry.create(controllerName, cameraEntity); + } } diff --git a/src/main/java/com/replaymod/replay/Setting.java b/src/main/java/com/replaymod/replay/Setting.java index 3808670e..619a8d0d 100644 --- a/src/main/java/com/replaymod/replay/Setting.java +++ b/src/main/java/com/replaymod/replay/Setting.java @@ -6,6 +6,9 @@ public final class Setting extends SettingsRegistry.SettingKeys { public static final Setting RECORD_SINGLEPLAYER = make("recordSingleplayer", "recordsingleplayer", true); public static final Setting RECORD_SERVER = make("recordServer", "recordserver", true); public static final Setting INDICATOR = make("indicator", "indicator", true); + public static final SettingsRegistry.MultipleChoiceSettingKeys CAMERA = + new SettingsRegistry.MultipleChoiceSettingKeys<>( + "replay", "camera", "replaymod.gui.settings.camera", "replaymod.camera.classic"); private static Setting make(String key, String displayName, T defaultValue) { return new Setting<>(key, displayName, defaultValue); diff --git a/src/main/java/com/replaymod/replay/camera/CameraControllerRegistry.java b/src/main/java/com/replaymod/replay/camera/CameraControllerRegistry.java new file mode 100644 index 00000000..1a3a31df --- /dev/null +++ b/src/main/java/com/replaymod/replay/camera/CameraControllerRegistry.java @@ -0,0 +1,26 @@ +package com.replaymod.replay.camera; + +import com.google.common.base.Function; +import com.google.common.base.Preconditions; + +import java.util.Collections; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +public class CameraControllerRegistry { + private final Map> constructors = new ConcurrentHashMap<>(); + + public void register(String name, Function constructor) { + Preconditions.checkState(!constructors.containsKey(name), "Controller " + name + " is already registered."); + constructors.put(name, constructor); + } + + public Set getControllers() { + return Collections.unmodifiableSet(constructors.keySet()); + } + + public CameraController create(String name, CameraEntity cameraEntity) { + return constructors.get(name).apply(cameraEntity); + } +} diff --git a/src/main/java/com/replaymod/replay/camera/CameraEntity.java b/src/main/java/com/replaymod/replay/camera/CameraEntity.java index 5f102e97..087076f7 100755 --- a/src/main/java/com/replaymod/replay/camera/CameraEntity.java +++ b/src/main/java/com/replaymod/replay/camera/CameraEntity.java @@ -1,6 +1,8 @@ package com.replaymod.replay.camera; +import com.replaymod.core.events.SettingsChangedEvent; import com.replaymod.replay.ReplayModReplay; +import com.replaymod.replay.Setting; import eu.crushedpixel.replaymod.holders.AdvancedPosition; import lombok.Getter; import lombok.Setter; @@ -39,7 +41,7 @@ public class CameraEntity extends EntityPlayerSP { public CameraEntity(Minecraft mcIn, World worldIn, NetHandlerPlayClient netHandlerPlayClient, StatFileWriter statFileWriter) { super(mcIn, worldIn, netHandlerPlayClient, statFileWriter); FMLCommonHandler.instance().bus().register(this); - cameraController = new VanillaCameraController(mc, this); + cameraController = ReplayModReplay.instance.createCameraController(this); } /** @@ -214,4 +216,11 @@ public class CameraEntity extends EntityPlayerSP { lastControllerUpdate = now; } } + + @SubscribeEvent + public void onSettingsChanged(SettingsChangedEvent event) { + if (event.getKey() == Setting.CAMERA) { + cameraController = ReplayModReplay.instance.createCameraController(this); + } + } } diff --git a/src/main/resources/assets/replaymod/lang/en_US.lang b/src/main/resources/assets/replaymod/lang/en_US.lang index d6fb0196..8722cab8 100644 --- a/src/main/resources/assets/replaymod/lang/en_US.lang +++ b/src/main/resources/assets/replaymod/lang/en_US.lang @@ -260,6 +260,7 @@ replaymod.gui.settings.interpolation=Path Interpolation replaymod.gui.settings.pathpreview=Show Path Preview replaymod.gui.settings.keyframecleancallback=Clear Confirmation replaymod.gui.settings.renderinvisible=Render invisible Entities +replaymod.gui.settings.camera=Camera replaymod.gui.settings.warning.linea=WARNING: Recording settings will be replaymod.gui.settings.warning.lineb=applied the next time you join a world. @@ -281,6 +282,10 @@ replaymod.input.assetmanager=Asset Manager replaymod.input.objectmanager=Object Manager replaymod.input.interpolation=Toggle Interpolation +# CameraControllers +replaymod.camera.classic=Classic +replaymod.camera.vanilla=Vanilla-ish + #Keyframe Presets GUI replaymod.gui.keyframerepository.title=Keyframe Repository replaymod.gui.keyframerepository.presets=Keyframe Presets