Add rotation mode selector
This commit is contained in:
parent
a2e2e2a313
commit
8e33eade50
|
@ -5,10 +5,10 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
|||
import com.simibubi.create.content.optics.Beam;
|
||||
import com.simibubi.create.content.optics.ILightHandler;
|
||||
import com.simibubi.create.foundation.collision.Matrix3d;
|
||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
import com.simibubi.create.foundation.utility.BeaconHelper;
|
||||
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.CenteredSideValueBoxTransform;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollOptionBehaviour;
|
||||
import com.simibubi.create.foundation.utility.*;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
|
@ -30,6 +30,7 @@ import java.util.function.Predicate;
|
|||
import java.util.stream.Stream;
|
||||
|
||||
public class MirrorTileEntity extends KineticTileEntity implements ILightHandler<MirrorTileEntity> {
|
||||
protected ScrollOptionBehaviour<RotationMode> movementMode;
|
||||
protected float angle;
|
||||
protected float clientAngleDiff;
|
||||
Map<Beam, Beam> beams;
|
||||
|
@ -46,6 +47,15 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
|
|||
setLazyTickRate(20);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
||||
super.addBehaviours(behaviours);
|
||||
movementMode = new ScrollOptionBehaviour<>(RotationMode.class, Lang.translate("optics.mirror.movement_mode"),
|
||||
this, new CenteredSideValueBoxTransform((state, d) -> getAxis() != d.getAxis()));
|
||||
movementMode.requiresWrench();
|
||||
behaviours.add(movementMode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CompoundNBT compound, boolean clientPacket) {
|
||||
compound.putFloat("Angle", angle);
|
||||
|
@ -63,6 +73,8 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
|
|||
public float getInterpolatedAngle(float partialTicks) {
|
||||
if (isVirtual())
|
||||
return MathHelper.lerp(partialTicks + .5f, prevAngle, angle);
|
||||
if (movementMode.get() == RotationMode.ROTATE_LIMITED && Math.abs(angle) == 90)
|
||||
return angle;
|
||||
return MathHelper.lerp(partialTicks, angle, angle + getAngularSpeed());
|
||||
}
|
||||
|
||||
|
@ -89,6 +101,12 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
|
|||
float newAngle = angle + angularSpeed;
|
||||
angle = newAngle % 360;
|
||||
|
||||
if (movementMode.get() == RotationMode.ROTATE_LIMITED)
|
||||
angle = MathHelper.clamp(angle, -90, 90);
|
||||
if (movementMode.get() == RotationMode.ROTATE_45 && angle == prevAngle) // don't snap while still rotating
|
||||
angle = 45F * Math.round(Math.round(angle) / 45F);
|
||||
|
||||
|
||||
if (angle != prevAngle) {
|
||||
updateBeams();
|
||||
}
|
||||
|
@ -144,7 +162,7 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
|
|||
|
||||
private Vector3d getReflectionAngle(Vector3d inputAngle) {
|
||||
inputAngle = inputAngle.normalize();
|
||||
Direction.Axis axis = getBlockState().get(BlockStateProperties.AXIS);
|
||||
Direction.Axis axis = getAxis();
|
||||
Vector3d normal;
|
||||
if (axis.isHorizontal())
|
||||
normal = new Matrix3d().asIdentity()
|
||||
|
@ -178,7 +196,7 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
|
|||
@Nonnull
|
||||
@Override
|
||||
public Direction getBeamRotationAround() {
|
||||
return Direction.getFacingFromAxisDirection(getBlockState().get(BlockStateProperties.AXIS), Direction.AxisDirection.POSITIVE);
|
||||
return Direction.getFacingFromAxisDirection(getAxis(), Direction.AxisDirection.POSITIVE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -225,11 +243,14 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
|
|||
if (inDir == null)
|
||||
return null;
|
||||
|
||||
Vector3d outDir = getReflectionAngle(inDir).normalize();
|
||||
return constructOutBeam(beam, getReflectionAngle(inDir).normalize());
|
||||
}
|
||||
|
||||
if (inDir.subtract(outDir)
|
||||
.normalize() == Vector3d.ZERO)
|
||||
return null;
|
||||
return constructOutBeam(beam, outDir);
|
||||
private Direction.Axis getAxis() {
|
||||
return getBlockState().get(BlockStateProperties.AXIS);
|
||||
}
|
||||
|
||||
public float getAngle() {
|
||||
return angle;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package com.simibubi.create.content.optics.mirror;
|
||||
|
||||
import com.simibubi.create.foundation.gui.AllIcons;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.INamedIconOptions;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
|
||||
public enum RotationMode implements INamedIconOptions {
|
||||
|
||||
// FIXME: Add proper icons
|
||||
ROTATE_FREE(AllIcons.I_ROTATE_PLACE),
|
||||
ROTATE_45(AllIcons.I_ROTATE_PLACE_RETURNED),
|
||||
ROTATE_LIMITED(AllIcons.I_ROTATE_NEVER_PLACE);
|
||||
|
||||
|
||||
private final String translationKey;
|
||||
private final AllIcons icon;
|
||||
|
||||
RotationMode(AllIcons icon) {
|
||||
this.icon = icon;
|
||||
translationKey = "optics.mirror.movement_mode." + Lang.asId(name());
|
||||
}
|
||||
|
||||
@Override
|
||||
public AllIcons getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTranslationKey() {
|
||||
return translationKey;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,26 +1,20 @@
|
|||
package com.simibubi.create.foundation.mixin;
|
||||
|
||||
import com.simibubi.create.content.optics.ILightHandler;
|
||||
import com.simibubi.create.foundation.block.ITE;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
import com.simibubi.create.foundation.utility.BeaconHelper;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.tileentity.BeaconTileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(BeaconTileEntity.class)
|
||||
public abstract class LightHandlersAreSolidToBeaconsMixin {
|
||||
@Redirect(at = @At(value = "INVOKE", target = "Lnet/minecraft/block/BlockState;getOpacity(Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;)I"), method = "tick()V")
|
||||
private int getCorrectedOpacity(BlockState state, IBlockReader world, BlockPos pos) {
|
||||
try {
|
||||
if (state.getBlock() instanceof ITE && ((ITE<?>) state.getBlock()).getTileEntity(world, pos) instanceof ILightHandler)
|
||||
return 15;
|
||||
} catch (ITE.TileEntityException ignored) {
|
||||
}
|
||||
return state.getOpacity(world, pos);
|
||||
return BeaconHelper.getCorrectedOpacity(state, world, pos);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,9 @@ import java.util.Optional;
|
|||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.simibubi.create.content.optics.ILightHandler;
|
||||
import com.simibubi.create.foundation.block.ITE;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
|
@ -27,7 +30,7 @@ public class BeaconHelper {
|
|||
while (testPos.getY() > 0) {
|
||||
testPos = testPos.down();
|
||||
BlockState state = world.getBlockState(testPos);
|
||||
if (state.getOpacity(world, testPos) >= 15 && state.getBlock() != Blocks.BEDROCK)
|
||||
if (getCorrectedOpacity(state, world, testPos) >= 15 && state.getBlock() != Blocks.BEDROCK)
|
||||
break;
|
||||
if (state.getBlock() == Blocks.BEACON) {
|
||||
TileEntity te = world.getTileEntity(testPos);
|
||||
|
@ -59,4 +62,16 @@ public class BeaconHelper {
|
|||
return ((IBeaconBeamColorProvider) block).getColor()
|
||||
.getColorComponentValues();
|
||||
}
|
||||
|
||||
public static int getCorrectedOpacity(BlockState state, IBlockReader world, BlockPos pos) {
|
||||
try {
|
||||
if (state.getBlock() instanceof ITE) {
|
||||
TileEntity te = ((ITE<?>) state.getBlock()).getTileEntity(world, pos);
|
||||
if (te instanceof ILightHandler && !((ILightHandler<?>) te).canLightPass())
|
||||
return 15;
|
||||
}
|
||||
} catch (ITE.TileEntityException ignored) {
|
||||
}
|
||||
return state.getOpacity(world, pos);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue