mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-02-05 01:45:00 +01:00
Finally, a properly working state (reflection maths is still of by a bit)
This commit is contained in:
parent
8fd59b17b9
commit
dbede41eba
6 changed files with 216 additions and 61 deletions
74
src/main/java/com/simibubi/create/content/optics/Beam.java
Normal file
74
src/main/java/com/simibubi/create/content/optics/Beam.java
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
package com.simibubi.create.content.optics;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
|
|
||||||
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
|
import net.minecraft.util.math.vector.Vector3d;
|
||||||
|
|
||||||
|
public class Beam extends ArrayList<BeamSegment> {
|
||||||
|
public final Set<Beam> subBeams;
|
||||||
|
private final Set<ILightHandler<?>> lightEventListeners;
|
||||||
|
private final Vector3d direction;
|
||||||
|
private boolean removed = false;
|
||||||
|
|
||||||
|
public Beam(Vector3d direction) {
|
||||||
|
super();
|
||||||
|
this.direction = direction;
|
||||||
|
lightEventListeners = new HashSet<>();
|
||||||
|
subBeams = new HashSet<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onRemoved() {
|
||||||
|
lightEventListeners.forEach(handler -> handler.onBeamRemoved(this));
|
||||||
|
subBeams.forEach(Beam::onRemoved);
|
||||||
|
subBeams.clear();
|
||||||
|
removed = true;
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onCreated() {
|
||||||
|
lightEventListeners.stream()
|
||||||
|
.flatMap(handler -> handler.constructSubBeams(this))
|
||||||
|
.forEach(subBeams::add);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerSubBeam(Beam beam) {
|
||||||
|
subBeams.add(beam);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void render(MatrixStack ms, IRenderTypeBuffer buffer, float partialTicks) {
|
||||||
|
if (removed)
|
||||||
|
throw new IllegalStateException("tried to render removed beam");
|
||||||
|
forEach(beamSegment -> beamSegment.renderSegment(ms, buffer, partialTicks));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addListener(@Nullable ILightHandler<?> tile) {
|
||||||
|
if (tile != null)
|
||||||
|
lightEventListeners.add(tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3d getDirection() {
|
||||||
|
return direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
if (!super.equals(o)) return false;
|
||||||
|
Beam that = (Beam) o;
|
||||||
|
return removed == that.removed && subBeams.equals(that.subBeams) && lightEventListeners.equals(that.lightEventListeners) && Objects.equals(direction, that.direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeSubBeam(Beam out) {
|
||||||
|
if (subBeams.remove(out))
|
||||||
|
out.onRemoved();
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,7 +32,7 @@ public class BeamSegment {
|
||||||
private final Vector3d direction;
|
private final Vector3d direction;
|
||||||
private final Vector3d start;
|
private final Vector3d start;
|
||||||
private final LazyValue<Vector3d> normalized;
|
private final LazyValue<Vector3d> normalized;
|
||||||
private final LazyValue<Double> totalSectionLength;
|
private final LazyValue<Float> totalSectionLength;
|
||||||
private final ILightHandler<? extends TileEntity> handler;
|
private final ILightHandler<? extends TileEntity> handler;
|
||||||
@Nullable
|
@Nullable
|
||||||
private Quaternion beaconBeamModifier;
|
private Quaternion beaconBeamModifier;
|
||||||
|
@ -46,27 +46,27 @@ public class BeamSegment {
|
||||||
this.length = 1;
|
this.length = 1;
|
||||||
this.normalized = new LazyValue<>(direction::normalize);
|
this.normalized = new LazyValue<>(direction::normalize);
|
||||||
beaconBeamModifier = null;
|
beaconBeamModifier = null;
|
||||||
totalSectionLength = new LazyValue<>(() -> getDirection().scale(getLength())
|
totalSectionLength = new LazyValue<>(() -> (float) getDirection().scale(getLength())
|
||||||
.length());
|
.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
private static void renderBeam(MatrixStack ms, IVertexBuilder builder, float[] colors, float alpha, double segemntLength, double length, float p_228840_9_, float p_228840_10_, float p_228840_11_, float p_228840_12_, float p_228840_13_, float p_228840_14_, float p_228840_15_, float p_228840_18_, float p_228840_19_) {
|
private static void renderBeam(MatrixStack ms, IVertexBuilder builder, float[] colors, float alpha, float segmentLength, float p_228840_9_, float p_228840_10_, float p_228840_11_, float p_228840_12_, float p_228840_13_, float p_228840_14_, float p_228840_15_, float p_228840_18_, float p_228840_19_) {
|
||||||
MatrixStack.Entry matrixstack$entry = ms.peek();
|
MatrixStack.Entry matrixstack$entry = ms.peek();
|
||||||
Matrix4f model = matrixstack$entry.getModel();
|
Matrix4f model = matrixstack$entry.getModel();
|
||||||
Matrix3f normal = matrixstack$entry.getNormal();
|
Matrix3f normal = matrixstack$entry.getNormal();
|
||||||
putVertices(model, normal, builder, colors, alpha, segemntLength, length, (float) 0.0, p_228840_9_, p_228840_10_, p_228840_11_, p_228840_18_, p_228840_19_);
|
putVertices(model, normal, builder, colors, alpha, segmentLength, 0F, p_228840_9_, p_228840_10_, p_228840_11_, p_228840_18_, p_228840_19_);
|
||||||
putVertices(model, normal, builder, colors, alpha, segemntLength, length, p_228840_14_, p_228840_15_, p_228840_12_, p_228840_13_, p_228840_18_, p_228840_19_);
|
putVertices(model, normal, builder, colors, alpha, segmentLength, p_228840_14_, p_228840_15_, p_228840_12_, p_228840_13_, p_228840_18_, p_228840_19_);
|
||||||
putVertices(model, normal, builder, colors, alpha, segemntLength, length, p_228840_10_, p_228840_11_, p_228840_14_, p_228840_15_, p_228840_18_, p_228840_19_);
|
putVertices(model, normal, builder, colors, alpha, segmentLength, p_228840_10_, p_228840_11_, p_228840_14_, p_228840_15_, p_228840_18_, p_228840_19_);
|
||||||
putVertices(model, normal, builder, colors, alpha, segemntLength, length, p_228840_12_, p_228840_13_, (float) 0.0, p_228840_9_, p_228840_18_, p_228840_19_);
|
putVertices(model, normal, builder, colors, alpha, segmentLength, p_228840_12_, p_228840_13_, 0F, p_228840_9_, p_228840_18_, p_228840_19_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
private static void putVertices(Matrix4f model, Matrix3f normal, IVertexBuilder builder, float[] colors, float alpha, double segemntLength, double length, float p_228839_9_, float p_228839_10_, float p_228839_11_, float p_228839_12_, float p_228839_15_, float p_228839_16_) {
|
private static void putVertices(Matrix4f model, Matrix3f normal, IVertexBuilder builder, float[] colors, float alpha, float segmentLength, float p_228839_9_, float p_228839_10_, float p_228839_11_, float p_228839_12_, float p_228839_15_, float p_228839_16_) {
|
||||||
putVertex(model, normal, builder, colors, alpha, (float) length, p_228839_9_, p_228839_10_, (float) 1.0, p_228839_15_);
|
putVertex(model, normal, builder, colors, alpha, segmentLength, p_228839_9_, p_228839_10_, 1F, p_228839_15_);
|
||||||
putVertex(model, normal, builder, colors, alpha, (float) segemntLength, p_228839_9_, p_228839_10_, (float) 1.0, p_228839_16_);
|
putVertex(model, normal, builder, colors, alpha, 0F, p_228839_9_, p_228839_10_, 1F, p_228839_16_);
|
||||||
putVertex(model, normal, builder, colors, alpha, (float) segemntLength, p_228839_11_, p_228839_12_, (float) 0.0, p_228839_16_);
|
putVertex(model, normal, builder, colors, alpha, 0F, p_228839_11_, p_228839_12_, 0F, p_228839_16_);
|
||||||
putVertex(model, normal, builder, colors, alpha, (float) length, p_228839_11_, p_228839_12_, (float) 0.0, p_228839_15_);
|
putVertex(model, normal, builder, colors, alpha, segmentLength, p_228839_11_, p_228839_12_, 0F, p_228839_15_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
@ -140,9 +140,8 @@ public class BeamSegment {
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
public void renderSegment(MatrixStack ms, IRenderTypeBuffer buffer, float partialTicks, double segmentOffset) {
|
public void renderSegment(MatrixStack ms, IRenderTypeBuffer buffer, float partialTicks) {
|
||||||
float adjustedGameTime = (float) Math.floorMod(getWorldTick(), 40L) + partialTicks;
|
float adjustedGameTime = (float) Math.floorMod(getWorldTick(), 40L) + partialTicks;
|
||||||
double totalLength = totalSectionLength.getValue() + segmentOffset;
|
|
||||||
float textureOffset1 = MathHelper.fractionalPart(-adjustedGameTime * 0.2F - (float) MathHelper.floor(-adjustedGameTime * 0.1F)) - 1;
|
float textureOffset1 = MathHelper.fractionalPart(-adjustedGameTime * 0.2F - (float) MathHelper.floor(-adjustedGameTime * 0.1F)) - 1;
|
||||||
float textureOffset2 = (float) this.getLength() * 2.5f + textureOffset1;
|
float textureOffset2 = (float) this.getLength() * 2.5f + textureOffset1;
|
||||||
|
|
||||||
|
@ -157,11 +156,11 @@ public class BeamSegment {
|
||||||
.multiply(Vector3f.POSITIVE_Y, adjustedGameTime * 2.25F - 45.0F);
|
.multiply(Vector3f.POSITIVE_Y, adjustedGameTime * 2.25F - 45.0F);
|
||||||
|
|
||||||
renderBeam(stacker.unwrap(), buffer.getBuffer(RenderType.getBeaconBeam(TEXTURE_BEACON_BEAM, false)), this.colors, 1F,
|
renderBeam(stacker.unwrap(), buffer.getBuffer(RenderType.getBeaconBeam(TEXTURE_BEACON_BEAM, false)), this.colors, 1F,
|
||||||
segmentOffset, totalLength, 0.2F, .2F, 0F, -.2f,
|
totalSectionLength.getValue(), 0.2F, .2F, 0F, -.2f,
|
||||||
0f, 0f, -.2f, textureOffset2, textureOffset1);
|
0f, 0f, -.2f, textureOffset2, textureOffset1);
|
||||||
stacker.pop();
|
stacker.pop();
|
||||||
renderBeam(stacker.unwrap(), buffer.getBuffer(RenderType.getBeaconBeam(TEXTURE_BEACON_BEAM, true)), this.colors, 0.125F,
|
renderBeam(stacker.unwrap(), buffer.getBuffer(RenderType.getBeaconBeam(TEXTURE_BEACON_BEAM, true)), this.colors, 0.125F,
|
||||||
segmentOffset, totalLength, -.25f, .25f, -.25f, -.25f,
|
totalSectionLength.getValue(), -.25f, .25f, -.25f, -.25f,
|
||||||
.25f, .25f, .25f, textureOffset2, textureOffset1);
|
.25f, .25f, .25f, textureOffset2, textureOffset1);
|
||||||
stacker.pop()
|
stacker.pop()
|
||||||
.pop();
|
.pop();
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
package com.simibubi.create.content.optics;
|
package com.simibubi.create.content.optics;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||||
import com.simibubi.create.foundation.utility.BeaconHelper;
|
import com.simibubi.create.foundation.utility.BeaconHelper;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
|
@ -18,29 +20,41 @@ import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.vector.Vector3d;
|
import net.minecraft.util.math.vector.Vector3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public interface ILightHandler<T extends TileEntity & ILightHandler<T>> {
|
public interface ILightHandler<T extends SmartTileEntity & ILightHandler<T>> {
|
||||||
default List<BeamSegment> constructOutBeam(Vector3d beamDirection) {
|
@Nullable
|
||||||
ArrayList<BeamSegment> beam = new ArrayList<>();
|
default Beam constructOutBeam(Vector3d beamDirection) {
|
||||||
|
return constructOutBeam(beamDirection, getTile().getPos());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
default Beam constructOutBeam(Vector3d beamDirection, BlockPos testBlockPos) {
|
||||||
|
|
||||||
float[] segmentColor = getSegmentStartColor();
|
float[] segmentColor = getSegmentStartColor();
|
||||||
World world = getTile().getWorld();
|
World world = getTile().getWorld();
|
||||||
if (world == null)
|
if (world == null)
|
||||||
return beam;
|
return null;
|
||||||
Vector3d direction = VecHelper.step(beamDirection);
|
Vector3d direction = VecHelper.step(beamDirection);
|
||||||
Vector3d testPos = VecHelper.getCenterOf(getTile().getPos());
|
Beam beam = new Beam(direction);
|
||||||
|
Vector3d testPos = VecHelper.getCenterOf(testBlockPos);
|
||||||
|
|
||||||
BeamSegment segment = new BeamSegment(this, segmentColor, testPos, direction);
|
BeamSegment segment = new BeamSegment(this, segmentColor, testPos, direction);
|
||||||
beam.add(segment);
|
beam.add(segment);
|
||||||
|
|
||||||
for (int i = 0; i < 128; i++) {
|
for (int i = 0; i < 128; i++) {
|
||||||
testPos = testPos.add(direction); // check next block
|
testPos = testPos.add(direction); // check next block
|
||||||
BlockPos testBlockPos = new BlockPos(testPos.x, testPos.y, testPos.z);
|
testBlockPos = new BlockPos(testPos.x, testPos.y, testPos.z);
|
||||||
BlockState testState = world.getBlockState(testBlockPos);
|
BlockState testState = world.getBlockState(testBlockPos);
|
||||||
float[] newColor = BeaconHelper.getBeaconColorAt(testState.getBlock());
|
float[] newColor = BeaconHelper.getBeaconColorAt(testState.getBlock());
|
||||||
|
|
||||||
|
TileEntity te = testState.hasTileEntity() ? world.getTileEntity(testBlockPos) : null;
|
||||||
|
ILightHandler<?> lightHandler = te instanceof ILightHandler ? (ILightHandler<?>) te : null;
|
||||||
|
if (lightHandler != this)
|
||||||
|
beam.addListener(lightHandler);
|
||||||
|
|
||||||
if (newColor == null) {
|
if (newColor == null) {
|
||||||
TileEntity te = testState.hasTileEntity() ? world.getTileEntity(testBlockPos) : null;
|
if (testState.getOpacity(world, testBlockPos) >= 15 && testState.getBlock() != Blocks.BEDROCK || (lightHandler != null && !lightHandler.canLightPass())) {
|
||||||
if (testState.getOpacity(world, testBlockPos) >= 15 && testState.getBlock() != Blocks.BEDROCK || te instanceof ILightHandler) {
|
if (lightHandler != null) {
|
||||||
if (te instanceof ILightHandler) {
|
lightHandler.setColor(segmentColor);
|
||||||
((ILightHandler<?>) te).setColor(segmentColor);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -69,4 +83,18 @@ public interface ILightHandler<T extends TileEntity & ILightHandler<T>> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default void onBeamRemoved(Beam beam) {
|
||||||
|
}
|
||||||
|
|
||||||
|
default Stream<Beam> constructSubBeams(Beam beam) {
|
||||||
|
return Stream.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
default Iterator<Beam> getRenderBeams() {
|
||||||
|
return Collections.emptyIterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean canLightPass() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
package com.simibubi.create.content.optics.mirror;
|
|
||||||
|
|
||||||
public class BeaconSegmentListWrapper {
|
|
||||||
|
|
||||||
}
|
|
|
@ -6,7 +6,6 @@ import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import com.simibubi.create.AllBlockPartials;
|
import com.simibubi.create.AllBlockPartials;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
||||||
import com.simibubi.create.content.optics.BeamSegment;
|
|
||||||
import com.simibubi.create.foundation.render.SuperByteBuffer;
|
import com.simibubi.create.foundation.render.SuperByteBuffer;
|
||||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||||
|
|
||||||
|
@ -30,15 +29,8 @@ public class MirrorRenderer extends KineticTileEntityRenderer {
|
||||||
MirrorTileEntity mirrorTe = (MirrorTileEntity) te;
|
MirrorTileEntity mirrorTe = (MirrorTileEntity) te;
|
||||||
|
|
||||||
renderMirror(mirrorTe, partialTicks, ms, buffer, light);
|
renderMirror(mirrorTe, partialTicks, ms, buffer, light);
|
||||||
renderOutBeam(mirrorTe.beam, partialTicks, ms, buffer);
|
((MirrorTileEntity) te).getRenderBeams()
|
||||||
}
|
.forEachRemaining(beam -> beam.render(ms, buffer, partialTicks));
|
||||||
|
|
||||||
private void renderOutBeam(Iterable<BeamSegment> beam, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer) {
|
|
||||||
double totalLength = 0;
|
|
||||||
for (BeamSegment beamSegment : beam) {
|
|
||||||
beamSegment.renderSegment(ms, buffer, partialTicks, totalLength);
|
|
||||||
totalLength += beamSegment.getTotalSectionLength();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderMirror(MirrorTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light) {
|
private void renderMirror(MirrorTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light) {
|
||||||
|
|
|
@ -1,7 +1,17 @@
|
||||||
package com.simibubi.create.content.optics.mirror;
|
package com.simibubi.create.content.optics.mirror;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.google.common.collect.Iterators;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||||
import com.simibubi.create.content.optics.BeamSegment;
|
import com.simibubi.create.content.optics.Beam;
|
||||||
import com.simibubi.create.content.optics.ILightHandler;
|
import com.simibubi.create.content.optics.ILightHandler;
|
||||||
import com.simibubi.create.foundation.collision.Matrix3d;
|
import com.simibubi.create.foundation.collision.Matrix3d;
|
||||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||||
|
@ -22,24 +32,20 @@ import net.minecraft.util.math.vector.Vector3d;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public class MirrorTileEntity extends KineticTileEntity implements ILightHandler<MirrorTileEntity> {
|
public class MirrorTileEntity extends KineticTileEntity implements ILightHandler<MirrorTileEntity> {
|
||||||
public final List<BeamSegment> beam;
|
|
||||||
protected float angle;
|
protected float angle;
|
||||||
protected float clientAngleDiff;
|
protected float clientAngleDiff;
|
||||||
|
Map<Beam, Beam> beams;
|
||||||
private float prevAngle;
|
private float prevAngle;
|
||||||
private Optional<BeaconTileEntity> beacon;
|
@Nullable
|
||||||
|
private BeaconTileEntity beacon;
|
||||||
|
private Beam beaconBeam = null;
|
||||||
private float[] initialColor = DyeColor.WHITE.getColorComponentValues();
|
private float[] initialColor = DyeColor.WHITE.getColorComponentValues();
|
||||||
|
|
||||||
public MirrorTileEntity(TileEntityType<?> typeIn) {
|
public MirrorTileEntity(TileEntityType<?> typeIn) {
|
||||||
super(typeIn);
|
super(typeIn);
|
||||||
beacon = Optional.empty();
|
beacon = null;
|
||||||
beam = new ArrayList<>();
|
beams = new HashMap<>();
|
||||||
setLazyTickRate(20);
|
setLazyTickRate(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,14 +92,40 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
|
||||||
float newAngle = angle + angularSpeed;
|
float newAngle = angle + angularSpeed;
|
||||||
angle = newAngle % 360;
|
angle = newAngle % 360;
|
||||||
|
|
||||||
if (angle != prevAngle)
|
if (angle != prevAngle) {
|
||||||
updateBeams();
|
updateReflections();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (beacon != null && beacon.isRemoved())
|
||||||
|
updateBeaconState();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateBeams() {
|
private void updateBeaconState() {
|
||||||
beacon = BeaconHelper.getBeaconTE(pos, world);
|
BeaconTileEntity beaconBefore = beacon;
|
||||||
beam.clear();
|
beacon = BeaconHelper.getBeaconTE(pos, world)
|
||||||
beam.addAll(constructOutBeam(getReflectionAngle(VecHelper.UP)));
|
.orElse(null);
|
||||||
|
|
||||||
|
if (beaconBefore == beacon)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (beaconBefore != null) {
|
||||||
|
beaconBeam.onRemoved();
|
||||||
|
beaconBeam = null;
|
||||||
|
updateReflections();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (beacon != null) {
|
||||||
|
beaconBeam = constructOutBeam(VecHelper.UP, beacon.getPos());
|
||||||
|
if (beaconBeam != null) {
|
||||||
|
beaconBeam.addListener(this);
|
||||||
|
beaconBeam.onCreated();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateReflections() {
|
||||||
|
new HashMap<>(beams).forEach(Beam::removeSubBeam);
|
||||||
|
beams.replaceAll((b, v) -> reflectBeam(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Vector3d getReflectionAngle(Vector3d inputAngle) {
|
private Vector3d getReflectionAngle(Vector3d inputAngle) {
|
||||||
|
@ -107,7 +139,8 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
|
||||||
@Override
|
@Override
|
||||||
public void lazyTick() {
|
public void lazyTick() {
|
||||||
super.lazyTick();
|
super.lazyTick();
|
||||||
updateBeams();
|
updateBeaconState();
|
||||||
|
updateReflections();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -158,4 +191,38 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
|
||||||
public double getMaxRenderDistanceSquared() {
|
public double getMaxRenderDistanceSquared() {
|
||||||
return 256.0D;
|
return 256.0D;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Beam> getRenderBeams() {
|
||||||
|
Iterator<Beam> beaconIter = beaconBeam == null ? Collections.emptyIterator() : Collections.singleton(beaconBeam)
|
||||||
|
.iterator();
|
||||||
|
return Iterators.concat(beams.values()
|
||||||
|
.iterator(), beaconIter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBeamRemoved(Beam beam) {
|
||||||
|
beams.remove(beam);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stream<Beam> constructSubBeams(Beam beam) {
|
||||||
|
Beam reflected = reflectBeam(beam);
|
||||||
|
if (reflected != null) {
|
||||||
|
beams.put(beam, reflected);
|
||||||
|
return Stream.of(reflected);
|
||||||
|
}
|
||||||
|
return Stream.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Beam reflectBeam(Beam beam) {
|
||||||
|
Beam reflected = constructOutBeam(getReflectionAngle(beam.getDirection()));
|
||||||
|
if (reflected != null) {
|
||||||
|
beam.registerSubBeam(reflected);
|
||||||
|
reflected.onCreated();
|
||||||
|
}
|
||||||
|
return reflected;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue