mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-02-05 09:54:59 +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.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
@ -12,19 +11,19 @@ import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
import net.minecraft.item.DyeColor;
|
import net.minecraft.item.DyeColor;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.vector.Vector3d;
|
import net.minecraft.util.math.vector.Vector3d;
|
||||||
|
|
||||||
public class Beam extends ArrayList<BeamSegment> {
|
public class Beam extends ArrayList<BeamSegment> {
|
||||||
private final Set<ILightHandler<?>> lightEventListeners;
|
private final Set<ILightHandler<?>> lightEventListeners;
|
||||||
private final Vector3d direction;
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private final Beam parent;
|
private final Beam parent;
|
||||||
|
private boolean removed = false;
|
||||||
|
|
||||||
public Beam(@Nullable Beam parent, Vector3d direction) {
|
public Beam(@Nullable Beam parent) {
|
||||||
super();
|
super();
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.direction = direction;
|
|
||||||
lightEventListeners = new HashSet<>();
|
lightEventListeners = new HashSet<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,8 +42,22 @@ public class Beam extends ArrayList<BeamSegment> {
|
||||||
lightEventListeners.add(tile);
|
lightEventListeners.add(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public Vector3d getDirection() {
|
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
|
@Override
|
||||||
|
@ -53,15 +66,14 @@ public class Beam extends ArrayList<BeamSegment> {
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
if (!super.equals(o)) return false;
|
if (!super.equals(o)) return false;
|
||||||
Beam that = (Beam) o;
|
Beam that = (Beam) o;
|
||||||
return lightEventListeners.equals(that.lightEventListeners) && Objects.equals(direction, that.direction);
|
return lightEventListeners.equals(that.lightEventListeners);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isRemoved() {
|
public boolean isRemoved() {
|
||||||
return isEmpty() || get(0).getHandler()
|
// || !get(0).getHandler().getOutBeams().contains(this)
|
||||||
.getTile()
|
TileEntity handler = getHandler();
|
||||||
.isRemoved() || !get(0).getHandler()
|
removed = removed || isEmpty() || handler == null || handler.isRemoved() || (parent != null && parent.isRemoved());
|
||||||
.getOutBeams()
|
return removed;
|
||||||
.contains(this) || (parent != null && parent.isRemoved());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public float[] getColorAt(BlockPos testBlockPos) {
|
public float[] getColorAt(BlockPos testBlockPos) {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package com.simibubi.create.content.optics;
|
package com.simibubi.create.content.optics;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
@ -22,20 +21,19 @@ import net.minecraft.util.math.vector.Vector3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public interface ILightHandler<T extends SmartTileEntity & ILightHandler<T>> {
|
public interface ILightHandler<T extends SmartTileEntity & ILightHandler<T>> {
|
||||||
@Nullable
|
|
||||||
default Beam constructOutBeam(@Nullable Beam parent, Vector3d beamDirection) {
|
default Beam constructOutBeam(@Nullable Beam parent, Vector3d beamDirection) {
|
||||||
return constructOutBeam(parent, beamDirection, getTile().getPos());
|
return constructOutBeam(parent, beamDirection, getTile().getPos());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
default Beam constructOutBeam(@Nullable Beam parent, Vector3d beamDirection, BlockPos testBlockPos) {
|
default Beam constructOutBeam(@Nullable Beam parent, Vector3d beamDirection, BlockPos testBlockPos) {
|
||||||
|
Beam beam = new Beam(parent);
|
||||||
float[] segmentColor = parent == null ? DyeColor.WHITE.getColorComponentValues() : parent.getColorAt(testBlockPos);
|
|
||||||
World world = getTile().getWorld();
|
World world = getTile().getWorld();
|
||||||
if (world == null)
|
if (world == null)
|
||||||
return null;
|
return beam;
|
||||||
|
|
||||||
|
float[] segmentColor = parent == null ? DyeColor.WHITE.getColorComponentValues() : parent.getColorAt(testBlockPos);
|
||||||
Vector3d direction = VecHelper.step(beamDirection);
|
Vector3d direction = VecHelper.step(beamDirection);
|
||||||
Beam beam = new Beam(parent, direction);
|
|
||||||
Vector3d testPos = VecHelper.getCenterOf(testBlockPos);
|
Vector3d testPos = VecHelper.getCenterOf(testBlockPos);
|
||||||
|
|
||||||
BeamSegment segment = new BeamSegment(this, segmentColor, testPos, direction);
|
BeamSegment segment = new BeamSegment(this, segmentColor, testPos, direction);
|
||||||
|
@ -54,9 +52,6 @@ public interface ILightHandler<T extends SmartTileEntity & ILightHandler<T>> {
|
||||||
|
|
||||||
if (newColor == null) {
|
if (newColor == 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 || (lightHandler != null && !lightHandler.canLightPass())) {
|
||||||
if (lightHandler != null) {
|
|
||||||
lightHandler.setColor(segmentColor);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (!Arrays.equals(segmentColor, newColor)) {
|
} else if (!Arrays.equals(segmentColor, newColor)) {
|
||||||
|
@ -72,9 +67,6 @@ public interface ILightHandler<T extends SmartTileEntity & ILightHandler<T>> {
|
||||||
|
|
||||||
T getTile();
|
T getTile();
|
||||||
|
|
||||||
default void setColor(float[] segmentColor) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
default Direction getBeamRotationAround() {
|
default Direction getBeamRotationAround() {
|
||||||
return null;
|
return null;
|
||||||
|
@ -92,7 +84,5 @@ public interface ILightHandler<T extends SmartTileEntity & ILightHandler<T>> {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
default Collection<Beam> getOutBeams() {
|
default void updateBeams(){}
|
||||||
return Collections.emptySet();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
package com.simibubi.create.content.optics.mirror;
|
package com.simibubi.create.content.optics.mirror;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
@ -112,24 +113,28 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
|
||||||
|
|
||||||
if (beacon != null) {
|
if (beacon != null) {
|
||||||
beaconBeam = constructOutBeam(null, VecHelper.UP, beacon.getPos());
|
beaconBeam = constructOutBeam(null, VecHelper.UP, beacon.getPos());
|
||||||
if (beaconBeam != null) {
|
if (beaconBeam != null && !beaconBeam.isEmpty()) {
|
||||||
beaconBeam.addListener(this);
|
beaconBeam.addListener(this);
|
||||||
beaconBeam.onCreated();
|
beaconBeam.onCreated();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateBeams() {
|
@Override
|
||||||
|
public void updateBeams() {
|
||||||
Map<Beam, Beam> newBeams = new HashMap<>();
|
Map<Beam, Beam> newBeams = new HashMap<>();
|
||||||
for (Map.Entry<Beam, Beam> entry : beams.entrySet()) {
|
for (Map.Entry<Beam, Beam> entry : beams.entrySet()) {
|
||||||
|
entry.getValue()
|
||||||
|
.onRemoved();
|
||||||
if (entry.getKey()
|
if (entry.getKey()
|
||||||
.isRemoved())
|
.isRemoved())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Beam reflected = reflectBeam(entry.getKey());
|
Beam reflected = reflectBeam(entry.getKey());
|
||||||
if (reflected != null) {
|
if (reflected != null && !reflected.isEmpty()) {
|
||||||
newBeams.put(entry.getKey(), reflected);
|
newBeams.put(entry.getKey(), reflected);
|
||||||
reflected.onCreated();
|
reflected.onCreated();
|
||||||
|
entry.getKey()
|
||||||
|
.addListener(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
beams = newBeams;
|
beams = newBeams;
|
||||||
|
@ -138,7 +143,7 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
|
||||||
private Vector3d getReflectionAngle(Vector3d inputAngle) {
|
private Vector3d getReflectionAngle(Vector3d inputAngle) {
|
||||||
inputAngle = inputAngle.normalize();
|
inputAngle = inputAngle.normalize();
|
||||||
Vector3d normal = new Matrix3d().asIdentity()
|
Vector3d normal = new Matrix3d().asIdentity()
|
||||||
.asAxisRotation(getAxis(), AngleHelper.rad(angle))
|
.asAxisRotation(getBlockState().get(BlockStateProperties.AXIS), AngleHelper.rad(angle))
|
||||||
.transform(VecHelper.UP);
|
.transform(VecHelper.UP);
|
||||||
return inputAngle.subtract(normal.scale(2 * inputAngle.dotProduct(normal)));
|
return inputAngle.subtract(normal.scale(2 * inputAngle.dotProduct(normal)));
|
||||||
}
|
}
|
||||||
|
@ -160,26 +165,10 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setColor(float[] initialColor) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Direction getBeamRotationAround() {
|
public Direction getBeamRotationAround() {
|
||||||
return Direction.getFacingFromAxisDirection(getAxis(), Direction.AxisDirection.POSITIVE);
|
return Direction.getFacingFromAxisDirection(getBlockState().get(BlockStateProperties.AXIS), Direction.AxisDirection.POSITIVE);
|
||||||
}
|
|
||||||
|
|
||||||
public float getAngle() {
|
|
||||||
return angle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAngle(float forcedAngle) {
|
|
||||||
angle = forcedAngle;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Direction.Axis getAxis() {
|
|
||||||
return getBlockState().get(BlockStateProperties.AXIS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -206,13 +195,13 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
|
||||||
public Stream<Beam> constructSubBeams(Beam beam) {
|
public Stream<Beam> constructSubBeams(Beam beam) {
|
||||||
if (beams.keySet()
|
if (beams.keySet()
|
||||||
.stream()
|
.stream()
|
||||||
|
.filter(((Predicate<Beam>) Beam::isRemoved).negate())
|
||||||
.map(Beam::getDirection)
|
.map(Beam::getDirection)
|
||||||
.map(Vector3d::normalize)
|
.filter(Objects::nonNull)
|
||||||
.anyMatch(beam.getDirection()
|
.anyMatch(b -> b.equals(beam.getDirection())))
|
||||||
.normalize()::equals))
|
|
||||||
return Stream.empty();
|
return Stream.empty();
|
||||||
Beam reflected = reflectBeam(beam);
|
Beam reflected = reflectBeam(beam);
|
||||||
if (reflected != null) {
|
if (reflected != null && !reflected.isEmpty()) {
|
||||||
beams.put(beam, reflected);
|
beams.put(beam, reflected);
|
||||||
beam.addListener(this);
|
beam.addListener(this);
|
||||||
return Stream.of(reflected);
|
return Stream.of(reflected);
|
||||||
|
@ -220,23 +209,17 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
|
||||||
return Stream.empty();
|
return Stream.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private Beam reflectBeam(Beam beam) {
|
private Beam reflectBeam(Beam beam) {
|
||||||
Vector3d inDir = beam.getDirection()
|
Vector3d inDir = beam.getDirection();
|
||||||
.normalize();
|
if (inDir == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
Vector3d outDir = getReflectionAngle(inDir).normalize();
|
Vector3d outDir = getReflectionAngle(inDir).normalize();
|
||||||
|
|
||||||
if (inDir.subtract(outDir)
|
if (inDir.subtract(outDir)
|
||||||
.normalize() == Vector3d.ZERO)
|
.normalize() == Vector3d.ZERO)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
// TE already has input beam at that direction
|
|
||||||
|
|
||||||
return constructOutBeam(beam, outDir);
|
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,
|
"required": true,
|
||||||
"priority": 1100,
|
"priority": 1100,
|
||||||
"package": "com.simibubi.create.foundation.mixin",
|
"package": "com.simibubi.create.foundation.mixin",
|
||||||
"compatibilityLevel": "JAVA_8",
|
"compatibilityLevel": "JAVA_8",
|
||||||
"refmap": "create.refmap.json",
|
"refmap": "create.refmap.json",
|
||||||
"client": [
|
"client": [
|
||||||
"TileWorldHookMixin",
|
"CancelTileEntityRenderMixin",
|
||||||
"CancelTileEntityRenderMixin",
|
"EntityContraptionInteractionMixin",
|
||||||
"FogColorTrackerMixin",
|
"FogColorTrackerMixin",
|
||||||
"LightUpdateMixin",
|
"LightUpdateMixin",
|
||||||
"NetworkLightUpdateMixin",
|
"NetworkLightUpdateMixin",
|
||||||
"RenderHooksMixin",
|
"RenderHooksMixin",
|
||||||
"ShaderCloseMixin",
|
"ShaderCloseMixin",
|
||||||
"TileRemoveMixin",
|
"StoreProjectionMatrixMixin",
|
||||||
"EntityContraptionInteractionMixin",
|
"TileRemoveMixin",
|
||||||
"StoreProjectionMatrixMixin"
|
"TileWorldHookMixin"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
},
|
},
|
||||||
"minVersion": "0.8"
|
"minVersion": "0.8",
|
||||||
|
"mixins": [
|
||||||
|
"LightHandlersAreSolidToBeaconsMixin"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue