Do some reliability improvements

This commit is contained in:
grimmauld 2021-04-20 01:15:38 +02:00
parent 2b3fb358ad
commit 19129c321f
5 changed files with 100 additions and 86 deletions

View file

@ -2,7 +2,6 @@ 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;
@ -12,19 +11,19 @@ import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.item.DyeColor;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Vector3d;
public class Beam extends ArrayList<BeamSegment> {
private final Set<ILightHandler<?>> lightEventListeners;
private final Vector3d direction;
@Nullable
private final Beam parent;
private boolean removed = false;
public Beam(@Nullable Beam parent, Vector3d direction) {
public Beam(@Nullable Beam parent) {
super();
this.parent = parent;
this.direction = direction;
lightEventListeners = new HashSet<>();
}
@ -43,8 +42,22 @@ public class Beam extends ArrayList<BeamSegment> {
lightEventListeners.add(tile);
}
@Nullable
public Vector3d getDirection() {
return direction;
return isEmpty() ? null : get(0).getNormalized();
}
public void onRemoved() {
removed = true;
lightEventListeners.stream()
.filter(handler -> handler != this.getHandler())
.forEach(ILightHandler::updateBeams);
}
@Nullable
public TileEntity getHandler() {
return size() == 0 ? null : get(0).getHandler()
.getTile();
}
@Override
@ -53,15 +66,14 @@ public class Beam extends ArrayList<BeamSegment> {
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
Beam that = (Beam) o;
return lightEventListeners.equals(that.lightEventListeners) && Objects.equals(direction, that.direction);
return lightEventListeners.equals(that.lightEventListeners);
}
public boolean isRemoved() {
return isEmpty() || get(0).getHandler()
.getTile()
.isRemoved() || !get(0).getHandler()
.getOutBeams()
.contains(this) || (parent != null && parent.isRemoved());
// || !get(0).getHandler().getOutBeams().contains(this)
TileEntity handler = getHandler();
removed = removed || isEmpty() || handler == null || handler.isRemoved() || (parent != null && parent.isRemoved());
return removed;
}
public float[] getColorAt(BlockPos testBlockPos) {

View file

@ -1,7 +1,6 @@
package com.simibubi.create.content.optics;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.stream.Stream;
@ -22,20 +21,19 @@ import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.world.World;
public interface ILightHandler<T extends SmartTileEntity & ILightHandler<T>> {
@Nullable
default Beam constructOutBeam(@Nullable Beam parent, Vector3d beamDirection) {
return constructOutBeam(parent, beamDirection, getTile().getPos());
}
@Nullable
default Beam constructOutBeam(@Nullable Beam parent, Vector3d beamDirection, BlockPos testBlockPos) {
float[] segmentColor = parent == null ? DyeColor.WHITE.getColorComponentValues() : parent.getColorAt(testBlockPos);
Beam beam = new Beam(parent);
World world = getTile().getWorld();
if (world == null)
return null;
return beam;
float[] segmentColor = parent == null ? DyeColor.WHITE.getColorComponentValues() : parent.getColorAt(testBlockPos);
Vector3d direction = VecHelper.step(beamDirection);
Beam beam = new Beam(parent, direction);
Vector3d testPos = VecHelper.getCenterOf(testBlockPos);
BeamSegment segment = new BeamSegment(this, segmentColor, testPos, direction);
@ -54,9 +52,6 @@ public interface ILightHandler<T extends SmartTileEntity & ILightHandler<T>> {
if (newColor == null) {
if (testState.getOpacity(world, testBlockPos) >= 15 && testState.getBlock() != Blocks.BEDROCK || (lightHandler != null && !lightHandler.canLightPass())) {
if (lightHandler != null) {
lightHandler.setColor(segmentColor);
}
break;
}
} else if (!Arrays.equals(segmentColor, newColor)) {
@ -72,9 +67,6 @@ public interface ILightHandler<T extends SmartTileEntity & ILightHandler<T>> {
T getTile();
default void setColor(float[] segmentColor) {
}
@Nullable
default Direction getBeamRotationAround() {
return null;
@ -92,7 +84,5 @@ public interface ILightHandler<T extends SmartTileEntity & ILightHandler<T>> {
return false;
}
default Collection<Beam> getOutBeams() {
return Collections.emptySet();
}
default void updateBeams(){}
}

View file

@ -1,10 +1,11 @@
package com.simibubi.create.content.optics.mirror;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.stream.Stream;
import javax.annotation.Nonnull;
@ -112,24 +113,28 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
if (beacon != null) {
beaconBeam = constructOutBeam(null, VecHelper.UP, beacon.getPos());
if (beaconBeam != null) {
if (beaconBeam != null && !beaconBeam.isEmpty()) {
beaconBeam.addListener(this);
beaconBeam.onCreated();
}
}
}
private void updateBeams() {
@Override
public void updateBeams() {
Map<Beam, Beam> newBeams = new HashMap<>();
for (Map.Entry<Beam, Beam> entry : beams.entrySet()) {
entry.getValue()
.onRemoved();
if (entry.getKey()
.isRemoved())
continue;
Beam reflected = reflectBeam(entry.getKey());
if (reflected != null) {
if (reflected != null && !reflected.isEmpty()) {
newBeams.put(entry.getKey(), reflected);
reflected.onCreated();
entry.getKey()
.addListener(this);
}
}
beams = newBeams;
@ -138,7 +143,7 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
private Vector3d getReflectionAngle(Vector3d inputAngle) {
inputAngle = inputAngle.normalize();
Vector3d normal = new Matrix3d().asIdentity()
.asAxisRotation(getAxis(), AngleHelper.rad(angle))
.asAxisRotation(getBlockState().get(BlockStateProperties.AXIS), AngleHelper.rad(angle))
.transform(VecHelper.UP);
return inputAngle.subtract(normal.scale(2 * inputAngle.dotProduct(normal)));
}
@ -160,26 +165,10 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
return this;
}
@Override
public void setColor(float[] initialColor) {
}
@Nonnull
@Override
public Direction getBeamRotationAround() {
return Direction.getFacingFromAxisDirection(getAxis(), Direction.AxisDirection.POSITIVE);
}
public float getAngle() {
return angle;
}
public void setAngle(float forcedAngle) {
angle = forcedAngle;
}
private Direction.Axis getAxis() {
return getBlockState().get(BlockStateProperties.AXIS);
return Direction.getFacingFromAxisDirection(getBlockState().get(BlockStateProperties.AXIS), Direction.AxisDirection.POSITIVE);
}
@Override
@ -206,13 +195,13 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
public Stream<Beam> constructSubBeams(Beam beam) {
if (beams.keySet()
.stream()
.filter(((Predicate<Beam>) Beam::isRemoved).negate())
.map(Beam::getDirection)
.map(Vector3d::normalize)
.anyMatch(beam.getDirection()
.normalize()::equals))
.filter(Objects::nonNull)
.anyMatch(b -> b.equals(beam.getDirection())))
return Stream.empty();
Beam reflected = reflectBeam(beam);
if (reflected != null) {
if (reflected != null && !reflected.isEmpty()) {
beams.put(beam, reflected);
beam.addListener(this);
return Stream.of(reflected);
@ -220,23 +209,17 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
return Stream.empty();
}
@Nullable
private Beam reflectBeam(Beam beam) {
Vector3d inDir = beam.getDirection()
.normalize();
Vector3d inDir = beam.getDirection();
if (inDir == null)
return null;
Vector3d outDir = getReflectionAngle(inDir).normalize();
if (inDir.subtract(outDir)
.normalize() == Vector3d.ZERO)
return null;
// TE already has input beam at that direction
return constructOutBeam(beam, outDir);
}
@Override
public Collection<Beam> getOutBeams() {
return beams.keySet();
}
}

View file

@ -0,0 +1,26 @@
package com.simibubi.create.foundation.mixin;
import com.simibubi.create.content.optics.ILightHandler;
import com.simibubi.create.foundation.block.ITE;
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);
}
}

View file

@ -1,23 +1,26 @@
{
"required": true,
"priority": 1100,
"package": "com.simibubi.create.foundation.mixin",
"compatibilityLevel": "JAVA_8",
"refmap": "create.refmap.json",
"client": [
"TileWorldHookMixin",
"CancelTileEntityRenderMixin",
"FogColorTrackerMixin",
"LightUpdateMixin",
"NetworkLightUpdateMixin",
"RenderHooksMixin",
"ShaderCloseMixin",
"TileRemoveMixin",
"EntityContraptionInteractionMixin",
"StoreProjectionMatrixMixin"
],
"injectors": {
"defaultRequire": 1
},
"minVersion": "0.8"
"required": true,
"priority": 1100,
"package": "com.simibubi.create.foundation.mixin",
"compatibilityLevel": "JAVA_8",
"refmap": "create.refmap.json",
"client": [
"CancelTileEntityRenderMixin",
"EntityContraptionInteractionMixin",
"FogColorTrackerMixin",
"LightUpdateMixin",
"NetworkLightUpdateMixin",
"RenderHooksMixin",
"ShaderCloseMixin",
"StoreProjectionMatrixMixin",
"TileRemoveMixin",
"TileWorldHookMixin"
],
"injectors": {
"defaultRequire": 1
},
"minVersion": "0.8",
"mixins": [
"LightHandlersAreSolidToBeaconsMixin"
]
}