Created
October 23, 2025 04:37
-
-
Save johnaqu1no/a6c164568f3fc66bc61dc9ecc37f1f1f to your computer and use it in GitHub Desktop.
SpacePotato's Found Footage Camera Code - Lectern Distribution
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package gg.lode.lectern.effects.impl.horror.backrooms; | |
| import gg.lode.lectern.effects.Effect; | |
| import gg.lode.lectern.effects.EffectManager; | |
| import gg.lode.lectern.effects.impl.CameraModifier; | |
| import gg.lode.lectern.effects.impl.KeybindDisabler; | |
| import gg.lode.lectern.events.Subscribe; | |
| import gg.lode.lectern.events.impl.NetworkEvent; | |
| import gg.lode.lectern.events.impl.TickEvent; | |
| import lombok.Getter; | |
| import net.minecraft.client.MinecraftClient; | |
| import net.minecraft.util.math.MathHelper; | |
| import net.minecraft.util.math.Vec3d; | |
| public class BackroomsCutscene extends Effect { | |
| private static final int PAUSE_DURATION = 2900; | |
| private static final int FALL_DURATION = 7000; | |
| private static final int END_DURATION = 5000; | |
| // private Entity camera; | |
| private final MinecraftClient client; | |
| private boolean previousViewBob = false; | |
| private boolean started; | |
| private boolean falling; | |
| private long startTime; | |
| private boolean ending; | |
| @Getter | |
| private boolean blackScreen; | |
| private long blackScreenStartTime; | |
| private long blackScreenDuration; | |
| private boolean shouldPauseSounds; | |
| @Getter | |
| private float cameraRoll; | |
| private boolean hasInitializedLocation; | |
| private double iy, ix, iz; | |
| public BackroomsCutscene() { | |
| super("backrooms_cutscene"); | |
| this.client = MinecraftClient.getInstance(); | |
| this.started = false; | |
| this.falling = false; | |
| this.ending = false; | |
| this.blackScreen = false; | |
| this.hasInitializedLocation = false; | |
| } | |
| @Subscribe | |
| public void onNetworkEvent(NetworkEvent event) { | |
| if (getName().equals(event.getEventId())) { | |
| switch (event.getData().readString()) { | |
| case "START" -> startCutscene(); | |
| case "STOP" -> stopCutscene(); | |
| } | |
| } | |
| } | |
| @Subscribe | |
| public void onTick(TickEvent event) { | |
| if (!isActive()) return; | |
| if (!hasInitializedLocation && client.player != null) { | |
| this.ix = client.player.getX(); | |
| this.iy = client.player.getY(); | |
| this.iz = client.player.getZ(); | |
| hasInitializedLocation = true; | |
| } | |
| tickBlackScreen(); | |
| if (client.player == null || client.world == null) { | |
| stopCutscene(); | |
| return; | |
| } | |
| if (!ending && !falling) { | |
| handlePause(); | |
| } else if (falling && !ending) { | |
| handleFall(); | |
| } else { | |
| handleEnding(); | |
| } | |
| } | |
| public void startCutscene() { | |
| setActive(true); | |
| this.started = true; | |
| this.falling = false; | |
| this.ending = false; | |
| this.startTime = System.currentTimeMillis(); | |
| showBlackScreen(60, true); | |
| KeybindDisabler keybindDisabler = EffectManager.getEffect(KeybindDisabler.class); | |
| if (keybindDisabler != null) { | |
| keybindDisabler.setActive(true); | |
| keybindDisabler.addDisabledKey(mc.options.forwardKey); | |
| keybindDisabler.addDisabledKey(mc.options.leftKey); | |
| keybindDisabler.addDisabledKey(mc.options.rightKey); | |
| keybindDisabler.addDisabledKey(mc.options.backKey); | |
| keybindDisabler.addDisabledKey(mc.options.inventoryKey); | |
| keybindDisabler.addDisabledKey(mc.options.chatKey); | |
| keybindDisabler.addDisabledKey(mc.options.playerListKey); | |
| keybindDisabler.addDisabledKey(mc.options.jumpKey); | |
| } | |
| if (client.options != null) { | |
| previousViewBob = client.options.getBobView().getValue(); | |
| client.options.getBobView().setValue(false); | |
| client.options.hudHidden = true; | |
| } | |
| } | |
| private void handlePause() { | |
| if (!started) { | |
| this.startTime = System.currentTimeMillis(); | |
| this.started = true; | |
| showBlackScreen(60, true); | |
| } | |
| float timer = (float) (System.currentTimeMillis() - startTime) / PAUSE_DURATION; | |
| if (client.options != null) { | |
| client.options.hudHidden = true; | |
| } | |
| if (timer >= 1.0f) { | |
| this.falling = true; | |
| this.startTime = System.currentTimeMillis(); | |
| } | |
| } | |
| private void handleFall() { | |
| float timer = (float) (System.currentTimeMillis() - startTime) / FALL_DURATION; | |
| if (timer >= 1.0f) { | |
| showBlackScreen(50, true); | |
| this.ending = true; | |
| this.falling = false; | |
| this.startTime = System.currentTimeMillis() + 2500L; | |
| if (client.player != null) { | |
| CameraModifier cameraModifier = EffectManager.getEffect(CameraModifier.class); | |
| if (cameraModifier != null) { | |
| cameraModifier.set(ix, | |
| iy, | |
| iz, | |
| 15, 90); | |
| } | |
| } | |
| } else { | |
| if (client.options != null) { | |
| client.options.hudHidden = true; | |
| } | |
| Vec3d newPos = interpolateFallPosition(timer); | |
| Vec3d newRot = interpolateFallRotation(timer); | |
| this.cameraRoll = (float) newRot.z; | |
| CameraModifier cameraModifier = EffectManager.getEffect(CameraModifier.class); | |
| if (cameraModifier != null) { | |
| cameraModifier.set(newPos.x, newPos.y, newPos.z, | |
| (float) newRot.y, (float) newRot.x, cameraRoll); | |
| } | |
| } | |
| } | |
| private void handleEnding() { | |
| float timer = (float) (System.currentTimeMillis() - startTime) / END_DURATION; | |
| if (timer >= 1.0f) { | |
| showBlackScreen(40, true); | |
| stopCutscene(); | |
| } else { | |
| if (client.options != null) { | |
| client.options.hudHidden = true; | |
| } | |
| if (client.player != null) { | |
| cameraRoll = 100; | |
| CameraModifier cameraModifier = EffectManager.getEffect(CameraModifier.class); | |
| if (cameraModifier != null) { | |
| cameraModifier.set(ix, | |
| iy + 0.2, | |
| iz, | |
| -180, 0, cameraRoll); | |
| } | |
| } | |
| } | |
| } | |
| private Vec3d interpolateFallPosition(float timer) { | |
| float easedTimer = easeInSine(timer); | |
| double startY = iy + 193; | |
| double y = MathHelper.lerp(easedTimer, startY, iy); | |
| return new Vec3d(ix, y, iz); | |
| } | |
| private Vec3d interpolateFallRotation(float timer) { | |
| float pitch, yaw, roll; | |
| if (timer < 0.5f) { | |
| float t = timer * 2.0f; | |
| float eased = easeInOutSine(t); | |
| pitch = MathHelper.lerp(eased, 80, 60); | |
| roll = MathHelper.lerp(eased, 20, -20); | |
| } else { | |
| float t = (timer - 0.5f) * 2.0f; | |
| float eased = easeInOutSine(t); | |
| pitch = MathHelper.lerp(eased, 60, 110); | |
| roll = MathHelper.lerp(eased, -20, 0); | |
| } | |
| yaw = MathHelper.lerp(timer, 0, 120); | |
| return new Vec3d(pitch, yaw, roll); | |
| } | |
| private float easeInSine(float t) { | |
| return 1 - (float) Math.cos((t * Math.PI) / 2); | |
| } | |
| private float easeInOutSine(float t) { | |
| return -(float) (Math.cos(Math.PI * t) - 1) / 2; | |
| } | |
| private void showBlackScreen(int durationTicks, boolean pauseSounds) { | |
| this.blackScreenDuration = durationTicks * 50L; | |
| this.blackScreen = true; | |
| this.blackScreenStartTime = System.currentTimeMillis(); | |
| this.shouldPauseSounds = pauseSounds; | |
| if (client.options != null) { | |
| client.options.hudHidden = true; | |
| } | |
| } | |
| private void tickBlackScreen() { | |
| if (blackScreen) { | |
| float timer = (float) (System.currentTimeMillis() - blackScreenStartTime) / blackScreenDuration; | |
| if (timer >= 1.0f) { | |
| this.blackScreen = false; | |
| if (client.options != null) { | |
| client.options.hudHidden = false; | |
| client.options.getBobView().setValue(previousViewBob); | |
| } | |
| if (client.getSoundManager() != null) { | |
| client.getSoundManager().resumeAll(); | |
| } | |
| } else { | |
| if (shouldPauseSounds && client.getSoundManager() != null) { | |
| client.getSoundManager().pauseAll(); | |
| } | |
| if (client.options != null) { | |
| client.options.hudHidden = true; | |
| } | |
| } | |
| } | |
| } | |
| private void stopCutscene() { | |
| setActive(false); | |
| this.hasInitializedLocation = false; | |
| this.started = false; | |
| this.falling = false; | |
| this.ending = false; | |
| this.blackScreen = false; | |
| this.cameraRoll = 0; | |
| if (client.player != null) { | |
| client.cameraEntity = client.player; | |
| } | |
| if (client.options != null) { | |
| client.options.hudHidden = false; | |
| client.options.getBobView().setValue(previousViewBob); | |
| } | |
| CameraModifier cameraModifier = EffectManager.getEffect(CameraModifier.class); | |
| if (cameraModifier != null) cameraModifier.setActive(false); | |
| KeybindDisabler keybindDisabler = EffectManager.getEffect(KeybindDisabler.class); | |
| if (keybindDisabler != null) { | |
| keybindDisabler.clearDisabledKeys(); | |
| keybindDisabler.setActive(false); | |
| } | |
| if (client.getSoundManager() != null) { | |
| client.getSoundManager().resumeAll(); | |
| } | |
| this.startTime = 0L; | |
| } | |
| @Override | |
| public void reset() { | |
| stopCutscene(); | |
| } | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment