Add camera movement
This commit is contained in:
@@ -1,276 +0,0 @@
|
||||
package com.replaymod.replay;
|
||||
|
||||
import eu.crushedpixel.replaymod.holders.AdvancedPosition;
|
||||
import eu.crushedpixel.replaymod.replay.LesserDataWatcher;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.network.NetHandlerPlayClient;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.stats.StatFileWriter;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.World;
|
||||
import org.lwjgl.Sys;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class CameraEntity extends EntityPlayerSP {
|
||||
|
||||
public static final double SPEED_CHANGE = 0.5;
|
||||
public static final double LOWER_SPEED = 2;
|
||||
public static final double UPPER_SPEED = 20;
|
||||
|
||||
private static double MAX_SPEED = 10;
|
||||
private static double THRESHOLD = MAX_SPEED / 20;
|
||||
private static double DECAY = MAX_SPEED/3;
|
||||
|
||||
public static void modifyCameraSpeed(boolean increase) {
|
||||
setCameraMaximumSpeed(getCameraMaximumSpeed() + (increase ? 1 : -1) * SPEED_CHANGE);
|
||||
}
|
||||
|
||||
public static void setCameraMaximumSpeed(double maxSpeed) {
|
||||
if(maxSpeed < LOWER_SPEED || maxSpeed > UPPER_SPEED) return;
|
||||
MAX_SPEED = maxSpeed;
|
||||
THRESHOLD = MAX_SPEED / 20;
|
||||
DECAY = 5;
|
||||
}
|
||||
|
||||
public static double getCameraMaximumSpeed() {
|
||||
return MAX_SPEED;
|
||||
}
|
||||
|
||||
private Vec3 direction;
|
||||
private Vec3 dirBefore;
|
||||
private double motion;
|
||||
|
||||
public float roll;
|
||||
|
||||
private long lastCall = 0;
|
||||
|
||||
private boolean speedup = false;
|
||||
|
||||
public CameraEntity(Minecraft mcIn, World worldIn, NetHandlerPlayClient netHandlerPlayClient, StatFileWriter statFileWriter) {
|
||||
super(mcIn, worldIn, netHandlerPlayClient, statFileWriter);
|
||||
}
|
||||
|
||||
//frac = time since last tick
|
||||
public void updateMovement() {
|
||||
|
||||
long frac = Sys.getTime() - lastCall;
|
||||
|
||||
if(frac == 0) return;
|
||||
|
||||
double decFac = Math.max(0, 1 - (DECAY * (frac / 1000D)));
|
||||
|
||||
if(speedup) {
|
||||
if(motion < THRESHOLD) motion = THRESHOLD;
|
||||
motion /= decFac;
|
||||
} else {
|
||||
motion *= decFac;
|
||||
}
|
||||
|
||||
motion = Math.min(motion, MAX_SPEED);
|
||||
|
||||
lastCall = Sys.getTime();
|
||||
|
||||
if(direction == null || motion < THRESHOLD) {
|
||||
return;
|
||||
}
|
||||
|
||||
Vec3 movement = direction.normalize();
|
||||
double factor = motion * (frac / 1000D);
|
||||
|
||||
moveRelative(movement.xCoord * factor, movement.yCoord * factor, movement.zCoord * factor);
|
||||
}
|
||||
|
||||
public void speedUp() {
|
||||
speedup = true;
|
||||
}
|
||||
|
||||
public void stopSpeedUp() {
|
||||
speedup = false;
|
||||
}
|
||||
|
||||
public void setMovement(MoveDirection dir) {
|
||||
switch(dir) {
|
||||
case BACKWARD:
|
||||
direction = this.getVectorForRotation(-rotationPitch, rotationYaw - 180);
|
||||
break;
|
||||
case DOWN:
|
||||
direction = this.getVectorForRotation(90, 0);
|
||||
break;
|
||||
case FORWARD:
|
||||
direction = this.getVectorForRotation(rotationPitch, rotationYaw);
|
||||
break;
|
||||
case LEFT:
|
||||
direction = this.getVectorForRotation(0, rotationYaw - 90);
|
||||
break;
|
||||
case RIGHT:
|
||||
direction = this.getVectorForRotation(0, rotationYaw + 90);
|
||||
break;
|
||||
case UP:
|
||||
direction = this.getVectorForRotation(-90, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
Vec3 dbf = direction;
|
||||
|
||||
if(dirBefore != null) {
|
||||
direction = dirBefore.normalize().add(direction);
|
||||
}
|
||||
|
||||
dirBefore = dbf;
|
||||
|
||||
updateMovement();
|
||||
}
|
||||
|
||||
public void moveAbsolute(AdvancedPosition pos) {
|
||||
this.moveAbsolute(pos.getX(), pos.getY(), pos.getZ());
|
||||
rotationPitch = prevRotationPitch = (float)pos.getPitch();
|
||||
rotationYaw = prevRotationYaw = (float)pos.getYaw();
|
||||
roll = (float) pos.getRoll();
|
||||
updateBoundingBox();
|
||||
}
|
||||
|
||||
public void moveAbsolute(double x, double y, double z) {
|
||||
this.lastTickPosX = this.prevPosX = this.posX = x;
|
||||
this.lastTickPosY = this.prevPosY = this.posY = y;
|
||||
this.lastTickPosZ = this.prevPosZ = this.posZ = z;
|
||||
updateBoundingBox();
|
||||
}
|
||||
|
||||
public void moveRelative(double x, double y, double z) {
|
||||
this.lastTickPosX = this.prevPosX = this.posX = this.posX + x;
|
||||
this.lastTickPosY = this.prevPosY = this.posY = this.posY + y;
|
||||
this.lastTickPosZ = this.prevPosZ = this.posZ = this.posZ + z;
|
||||
updateBoundingBox();
|
||||
}
|
||||
|
||||
public void movePath(AdvancedPosition pos) {
|
||||
this.prevRotationPitch = this.rotationPitch = (float)pos.getPitch();
|
||||
this.prevRotationYaw = this.rotationYaw = (float)pos.getYaw();
|
||||
this.roll = (float) pos.getRoll();
|
||||
this.lastTickPosX = this.prevPosX = this.posX = pos.getX();
|
||||
this.lastTickPosY = this.prevPosY = this.posY = pos.getY();
|
||||
this.lastTickPosZ = this.prevPosZ = this.posZ = pos.getZ();
|
||||
updateBoundingBox();
|
||||
}
|
||||
|
||||
private void updateBoundingBox() {
|
||||
this.setEntityBoundingBox(new AxisAlignedBB(posX - width / 2, posY, posZ - width / 2,
|
||||
posX + width / 2, posY + height, posZ + width / 2));
|
||||
}
|
||||
|
||||
protected void updatePos(Entity to) {
|
||||
prevPosX = to.prevPosX;
|
||||
prevPosY = to.prevPosY;
|
||||
prevPosZ = to.prevPosZ;
|
||||
prevRotationYaw = to.prevRotationYaw;
|
||||
prevRotationPitch = to.prevRotationPitch;
|
||||
posX = to.posX;
|
||||
posY = to.posY;
|
||||
posZ = to.posZ;
|
||||
rotationYaw = to.rotationYaw;
|
||||
rotationPitch = to.rotationPitch;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void entityInit() {
|
||||
this.dataWatcher = new LesserDataWatcher(this);
|
||||
this.setSize(0.6f, 1.8f);
|
||||
updateBoundingBox();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAngles(float yaw, float pitch) {
|
||||
this.rotationYaw = (float) ((double) this.rotationYaw + (double) yaw * 0.15D);
|
||||
this.rotationPitch = (float) ((double) this.rotationPitch - (double) pitch * 0.15D);
|
||||
this.rotationPitch = MathHelper.clamp_float(this.rotationPitch, -90.0F, 90.0F);
|
||||
this.prevRotationPitch = this.rotationPitch;
|
||||
this.prevRotationYawHead = this.rotationYawHead = this.prevRotationYaw = this.rotationYaw;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate() {
|
||||
Entity view = mc.getRenderViewEntity();
|
||||
if (view != null) {
|
||||
UUID spectating = ReplayModReplay.instance.getReplayHandler().spectating;
|
||||
if (spectating != null && (view.getUniqueID() != spectating || view.worldObj != worldObj)) {
|
||||
view = worldObj.getPlayerEntityByUUID(spectating);
|
||||
if (view != null) {
|
||||
mc.setRenderViewEntity(view);
|
||||
} else {
|
||||
mc.setRenderViewEntity(this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (view != this) {
|
||||
updatePos(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preparePlayerToSpawn() {
|
||||
if (mc.theWorld != null) {
|
||||
worldObj = mc.theWorld;
|
||||
}
|
||||
super.preparePlayerToSpawn();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEntityInsideOpaqueBlock() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInsideOfMaterial(Material materialIn) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInLava() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInWater() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBePushed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createRunningParticles() {}
|
||||
|
||||
@Override
|
||||
public boolean canBeCollidedWith() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSpectator() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public enum MoveDirection {
|
||||
UP, DOWN, LEFT, RIGHT, FORWARD, BACKWARD
|
||||
}
|
||||
|
||||
@Override
|
||||
public MovingObjectPosition rayTrace(double p_174822_1_, float p_174822_3_) {
|
||||
MovingObjectPosition pos = super.rayTrace(p_174822_1_, 1f);
|
||||
|
||||
if(pos != null && pos.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) {
|
||||
pos.typeOfHit = MovingObjectPosition.MovingObjectType.MISS;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.replaymod.replay;
|
||||
|
||||
import com.replaymod.core.utils.WrappedTimer;
|
||||
import com.replaymod.replay.camera.CameraController;
|
||||
import com.replaymod.replay.camera.CameraEntity;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.settings.GameSettings;
|
||||
@@ -64,7 +66,21 @@ public class InputReplayTimer extends WrappedTimer {
|
||||
|
||||
int wheel = Mouse.getEventDWheel();
|
||||
if (wheel != 0) {
|
||||
// TODO: Update camera movement speed
|
||||
ReplayHandler replayHandler = mod.getReplayHandler();
|
||||
if (replayHandler != null) {
|
||||
CameraEntity cameraEntity = replayHandler.getCameraEntity();
|
||||
if (cameraEntity != null) {
|
||||
CameraController controller = cameraEntity.getCameraController();
|
||||
while (wheel > 0) {
|
||||
controller.increaseSpeed();
|
||||
wheel--;
|
||||
}
|
||||
while (wheel < 0) {
|
||||
controller.decreaseSpeed();
|
||||
wheel++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mc.currentScreen == null) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.replaymod.replay;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.replaymod.replay.camera.CameraEntity;
|
||||
import com.replaymod.replay.events.ReplayCloseEvent;
|
||||
import com.replaymod.replay.events.ReplayOpenEvent;
|
||||
import com.replaymod.replay.gui.overlay.GuiReplayOverlay;
|
||||
@@ -72,7 +73,7 @@ public class ReplayHandler {
|
||||
*/
|
||||
private AdvancedPosition targetCameraPosition;
|
||||
|
||||
protected UUID spectating;
|
||||
private UUID spectating;
|
||||
|
||||
public ReplayHandler(ReplayFile replayFile, boolean asyncMode) throws IOException {
|
||||
Preconditions.checkState(mc.isCallingFromMinecraftThread(), "Must be called from Minecraft thread.");
|
||||
@@ -212,7 +213,7 @@ public class ReplayHandler {
|
||||
|
||||
if (mc.getRenderViewEntity() != e) {
|
||||
mc.setRenderViewEntity(e);
|
||||
cameraEntity.updatePos(e);
|
||||
cameraEntity.setCameraPosRot(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,6 +241,10 @@ public class ReplayHandler {
|
||||
return mc.thePlayer instanceof CameraEntity ? (CameraEntity) mc.thePlayer : null;
|
||||
}
|
||||
|
||||
public UUID getSpectatedUUID() {
|
||||
return spectating;
|
||||
}
|
||||
|
||||
public void setTargetPosition(AdvancedPosition pos) {
|
||||
targetCameraPosition = pos;
|
||||
}
|
||||
@@ -247,7 +252,7 @@ public class ReplayHandler {
|
||||
public void moveCameraToTargetPosition() {
|
||||
CameraEntity cam = getCameraEntity();
|
||||
if (cam != null && targetCameraPosition != null) {
|
||||
cam.moveAbsolute(targetCameraPosition);
|
||||
cam.setCameraPosRot(targetCameraPosition);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.replaymod.replay;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.io.Files;
|
||||
import com.google.common.util.concurrent.ListenableFutureTask;
|
||||
import com.replaymod.replay.camera.CameraEntity;
|
||||
import de.johni0702.replaystudio.replay.ReplayFile;
|
||||
import eu.crushedpixel.replaymod.holders.PacketData;
|
||||
import com.replaymod.core.utils.Restrictions;
|
||||
@@ -425,7 +426,7 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
|
||||
}
|
||||
|
||||
CameraEntity cent = replayHandler.getCameraEntity();
|
||||
cent.moveAbsolute(ppl.func_148932_c(), ppl.func_148928_d(), ppl.func_148933_e());
|
||||
cent.setCameraPosition(ppl.func_148932_c(), ppl.func_148928_d(), ppl.func_148933_e());
|
||||
return null;
|
||||
}
|
||||
}.call();
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.replaymod.replay.camera;
|
||||
|
||||
public interface CameraController {
|
||||
void update(float partialTicksPassed);
|
||||
|
||||
void increaseSpeed();
|
||||
void decreaseSpeed();
|
||||
}
|
||||
217
src/main/java/com/replaymod/replay/camera/CameraEntity.java
Executable file
217
src/main/java/com/replaymod/replay/camera/CameraEntity.java
Executable file
@@ -0,0 +1,217 @@
|
||||
package com.replaymod.replay.camera;
|
||||
|
||||
import com.replaymod.replay.ReplayModReplay;
|
||||
import eu.crushedpixel.replaymod.holders.AdvancedPosition;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.network.NetHandlerPlayClient;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.stats.StatFileWriter;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* The camera entity used as the main player entity during replay viewing.
|
||||
* During a replay {@link Minecraft#thePlayer} should be an instance of this class.
|
||||
* Camera movement is controlled by a separate {@link CameraController}.
|
||||
*/
|
||||
public class CameraEntity extends EntityPlayerSP {
|
||||
/**
|
||||
* Roll of this camera in degrees.
|
||||
*/
|
||||
public float roll;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private CameraController cameraController;
|
||||
|
||||
private long lastControllerUpdate = System.currentTimeMillis();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the camera by the specified delta.
|
||||
* @param x Delta in X direction
|
||||
* @param y Delta in Y direction
|
||||
* @param z Delta in Z direction
|
||||
*/
|
||||
public void moveCamera(double x, double y, double z) {
|
||||
setCameraPosition(posX + x, posY + y, posZ + z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the camera position.
|
||||
* @param x X coordinate
|
||||
* @param y Y coordinate
|
||||
* @param z Z coordinate
|
||||
*/
|
||||
public void setCameraPosition(double x, double y, double z) {
|
||||
this.lastTickPosX = this.prevPosX = this.posX = x;
|
||||
this.lastTickPosY = this.prevPosY = this.posY = y;
|
||||
this.lastTickPosZ = this.prevPosZ = this.posZ = z;
|
||||
updateBoundingBox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the camera rotation.
|
||||
* @param yaw Yaw in degrees
|
||||
* @param pitch Pitch in degrees
|
||||
* @param roll Roll in degrees
|
||||
*/
|
||||
public void setCameraRotation(float yaw, float pitch, float roll) {
|
||||
this.prevRotationYaw = this.rotationYaw = yaw;
|
||||
this.prevRotationPitch = this.rotationPitch = pitch;
|
||||
this.roll = roll;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the camera position and rotation to that of the specified AdvancedPosition
|
||||
* @param pos The position and rotation to set
|
||||
*/
|
||||
public void setCameraPosRot(AdvancedPosition pos) {
|
||||
setCameraRotation((float) pos.getYaw(), (float) pos.getPitch(), (float) pos.getRoll());
|
||||
setCameraPosition(pos.getX(), pos.getY(), pos.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the camera position and rotation to that of the specified entity.
|
||||
* @param to The entity whose position to copy
|
||||
*/
|
||||
public void setCameraPosRot(Entity to) {
|
||||
prevPosX = to.prevPosX;
|
||||
prevPosY = to.prevPosY;
|
||||
prevPosZ = to.prevPosZ;
|
||||
prevRotationYaw = to.prevRotationYaw;
|
||||
prevRotationPitch = to.prevRotationPitch;
|
||||
posX = to.posX;
|
||||
posY = to.posY;
|
||||
posZ = to.posZ;
|
||||
rotationYaw = to.rotationYaw;
|
||||
rotationPitch = to.rotationPitch;
|
||||
lastTickPosX = to.lastTickPosX;
|
||||
lastTickPosY = to.lastTickPosY;
|
||||
lastTickPosZ = to.lastTickPosZ;
|
||||
updateBoundingBox();
|
||||
}
|
||||
|
||||
private void updateBoundingBox() {
|
||||
setEntityBoundingBox(new AxisAlignedBB(
|
||||
posX - width / 2, posY, posZ - width / 2,
|
||||
posX + width / 2, posY + height, posZ + width / 2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate() {
|
||||
Entity view = mc.getRenderViewEntity();
|
||||
if (view != null) {
|
||||
// Make sure we're always spectating the right entity
|
||||
// This is important if the spectated player respawns as their
|
||||
// entity is recreated and we have to spectate a new entity
|
||||
UUID spectating = ReplayModReplay.instance.getReplayHandler().getSpectatedUUID();
|
||||
if (spectating != null && (view.getUniqueID() != spectating || view.worldObj != worldObj)) {
|
||||
view = worldObj.getPlayerEntityByUUID(spectating);
|
||||
if (view != null) {
|
||||
mc.setRenderViewEntity(view);
|
||||
} else {
|
||||
mc.setRenderViewEntity(this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Move cmera to their position so when we exit the first person view
|
||||
// we don't jump back to where we entered it
|
||||
if (view != this) {
|
||||
setCameraPosRot(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preparePlayerToSpawn() {
|
||||
// Make sure our world is up-to-date in case of world changes
|
||||
if (mc.theWorld != null) {
|
||||
worldObj = mc.theWorld;
|
||||
}
|
||||
super.preparePlayerToSpawn();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEntityInsideOpaqueBlock() {
|
||||
return false; // Make sure no suffocation overlay is rendered
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInsideOfMaterial(Material materialIn) {
|
||||
return false; // Make sure no overlays are rendered
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInLava() {
|
||||
return false; // Make sure no lava overlay is rendered
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInWater() {
|
||||
return false; // Make sure no water overlay is rendered
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBePushed() {
|
||||
return false; // We are in full control of ourselves
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createRunningParticles() {
|
||||
// We do not produce any particles, we are a camera
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeCollidedWith() {
|
||||
return false; // We are a camera, we cannot collide
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSpectator() {
|
||||
return true; // Make sure we're treated as spectator
|
||||
}
|
||||
|
||||
@Override
|
||||
public MovingObjectPosition rayTrace(double p_174822_1_, float p_174822_3_) {
|
||||
MovingObjectPosition pos = super.rayTrace(p_174822_1_, 1f);
|
||||
|
||||
// Make sure we can never look at blocks (-> no outline)
|
||||
if(pos != null && pos.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) {
|
||||
pos.typeOfHit = MovingObjectPosition.MovingObjectType.MISS;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDead() {
|
||||
super.setDead();
|
||||
FMLCommonHandler.instance().bus().unregister(this);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onRenderUpdate(TickEvent.RenderTickEvent event) {
|
||||
if (event.phase == TickEvent.Phase.START) {
|
||||
long now = System.currentTimeMillis();
|
||||
long timePassed = now - lastControllerUpdate;
|
||||
cameraController.update(timePassed / 50f);
|
||||
lastControllerUpdate = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package com.replaymod.replay.camera;
|
||||
|
||||
public class ClassicCameraController implements CameraController {
|
||||
@Override
|
||||
public void update(float partialTicksPassed) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public void increaseSpeed() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decreaseSpeed() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
// public static final double SPEED_CHANGE = 0.5;
|
||||
// public static final double LOWER_SPEED = 2;
|
||||
// public static final double UPPER_SPEED = 20;
|
||||
//
|
||||
// private static double MAX_SPEED = 10;
|
||||
// private static double THRESHOLD = MAX_SPEED / 20;
|
||||
// private static double DECAY = MAX_SPEED/3;
|
||||
//
|
||||
// public static void modifyCameraSpeed(boolean increase) {
|
||||
// setCameraMaximumSpeed(getCameraMaximumSpeed() + (increase ? 1 : -1) * SPEED_CHANGE);
|
||||
// }
|
||||
//
|
||||
// public static void setCameraMaximumSpeed(double maxSpeed) {
|
||||
// if(maxSpeed < LOWER_SPEED || maxSpeed > UPPER_SPEED) return;
|
||||
// MAX_SPEED = maxSpeed;
|
||||
// THRESHOLD = MAX_SPEED / 20;
|
||||
// DECAY = 5;
|
||||
// }
|
||||
//
|
||||
// public static double getCameraMaximumSpeed() {
|
||||
// return MAX_SPEED;
|
||||
// }
|
||||
//
|
||||
// private Vec3 direction;
|
||||
// private Vec3 dirBefore;
|
||||
// private double motion;
|
||||
// private long lastCall = 0;
|
||||
//
|
||||
// private boolean speedup = false;
|
||||
//
|
||||
// //frac = time since last tick
|
||||
// public void updateMovement() {
|
||||
//
|
||||
// long frac = Sys.getTime() - lastCall;
|
||||
//
|
||||
// if(frac == 0) return;
|
||||
//
|
||||
// double decFac = Math.max(0, 1 - (DECAY * (frac / 1000D)));
|
||||
//
|
||||
// if(speedup) {
|
||||
// if(motion < THRESHOLD) motion = THRESHOLD;
|
||||
// motion /= decFac;
|
||||
// } else {
|
||||
// motion *= decFac;
|
||||
// }
|
||||
//
|
||||
// motion = Math.min(motion, MAX_SPEED);
|
||||
//
|
||||
// lastCall = Sys.getTime();
|
||||
//
|
||||
// if(direction == null || motion < THRESHOLD) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// Vec3 movement = direction.normalize();
|
||||
// double factor = motion * (frac / 1000D);
|
||||
//
|
||||
// moveCamera(movement.xCoord * factor, movement.yCoord * factor, movement.zCoord * factor);
|
||||
// }
|
||||
//
|
||||
// public void setMovement(MoveDirection dir) {
|
||||
// switch(dir) {
|
||||
// case BACKWARD:
|
||||
// direction = this.getVectorForRotation(-rotationPitch, rotationYaw - 180);
|
||||
// break;
|
||||
// case DOWN:
|
||||
// direction = this.getVectorForRotation(90, 0);
|
||||
// break;
|
||||
// case FORWARD:
|
||||
// direction = this.getVectorForRotation(rotationPitch, rotationYaw);
|
||||
// break;
|
||||
// case LEFT:
|
||||
// direction = this.getVectorForRotation(0, rotationYaw - 90);
|
||||
// break;
|
||||
// case RIGHT:
|
||||
// direction = this.getVectorForRotation(0, rotationYaw + 90);
|
||||
// break;
|
||||
// case UP:
|
||||
// direction = this.getVectorForRotation(-90, 0);
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// Vec3 dbf = direction;
|
||||
//
|
||||
// if(dirBefore != null) {
|
||||
// direction = dirBefore.normalize().add(direction);
|
||||
// }
|
||||
//
|
||||
// dirBefore = dbf;
|
||||
//
|
||||
// updateMovement();
|
||||
// }
|
||||
//
|
||||
// public enum MoveDirection {
|
||||
// UP, DOWN, LEFT, RIGHT, FORWARD, BACKWARD
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.replaymod.replay.camera;
|
||||
|
||||
import com.sun.javafx.geom.Vec3d;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.settings.GameSettings;
|
||||
import net.minecraft.client.settings.KeyBinding;
|
||||
|
||||
/**
|
||||
* Camera controller performing vanilla creative-like camera movements.
|
||||
*/
|
||||
public class VanillaCameraController implements CameraController {
|
||||
private static final int MAX_SPEED = 1000;
|
||||
private static final int MIN_SPEED = -1000;
|
||||
|
||||
private static final Vec3d[] DIRECTIONS = new Vec3d[]{
|
||||
new Vec3d(0, 0, 1), new Vec3d(0, 0, -1), new Vec3d(1, 0, 0), new Vec3d(-1, 0, 0),
|
||||
new Vec3d(0, 1, 0), new Vec3d(0, -1, 0),
|
||||
};
|
||||
|
||||
private final KeyBinding[] bindings = new KeyBinding[6];
|
||||
|
||||
private final CameraEntity camera;
|
||||
|
||||
private int speed;
|
||||
|
||||
public VanillaCameraController(Minecraft mc, CameraEntity camera) {
|
||||
this.camera = camera;
|
||||
GameSettings gameSettings = mc.gameSettings;
|
||||
this.bindings[0] = gameSettings.keyBindForward;
|
||||
this.bindings[1] = gameSettings.keyBindBack;
|
||||
this.bindings[2] = gameSettings.keyBindLeft;
|
||||
this.bindings[3] = gameSettings.keyBindRight;
|
||||
this.bindings[4] = gameSettings.keyBindJump;
|
||||
this.bindings[5] = gameSettings.keyBindSneak;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(float partialTicksPassed) {
|
||||
if (partialTicksPassed == 0) return;
|
||||
Vec3d direction = new Vec3d(0, 0, 0);
|
||||
for (int i = 0; i < 6; i++) { // First, get movement direction depending on keys pressed
|
||||
if (bindings[i].isKeyDown()) {
|
||||
direction.add(DIRECTIONS[i]);
|
||||
}
|
||||
}
|
||||
if (direction.length() == 0) return;
|
||||
direction.normalize(); // Normalize, so we don't move quicker if we hold down multiple keys
|
||||
double yawRadians = Math.toRadians(camera.rotationYaw);
|
||||
double yawSin = Math.sin(yawRadians), yawCos = Math.cos(yawRadians);
|
||||
// Rotate by yaw
|
||||
direction.set(
|
||||
direction.x * yawCos - direction.z * yawSin,
|
||||
direction.y,
|
||||
direction.x * yawSin + direction.z * yawCos
|
||||
);
|
||||
// Adjust for current speed
|
||||
// We transform speed to blocks per second: x->2^(x/300)
|
||||
direction.mul(Math.pow(2, speed / 300d));
|
||||
// Adjust for time passed
|
||||
direction.mul(partialTicksPassed / 20);
|
||||
// Actually move
|
||||
camera.moveCamera(direction.x, direction.y, direction.z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void increaseSpeed() {
|
||||
speed = Math.min(MAX_SPEED, speed + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decreaseSpeed() {
|
||||
speed = Math.max(MIN_SPEED, speed - 1);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user