mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-02-05 01:45:00 +01:00
Do some reliability improvements
This commit is contained in:
parent
2b3fb358ad
commit
19129c321f
5 changed files with 100 additions and 86 deletions
|
@ -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) {
|
||||
|
|
|
@ -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(){}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue