diff --git a/src/main/java/com/simibubi/create/content/optics/ILightHandler.java b/src/main/java/com/simibubi/create/content/optics/ILightHandler.java index 68e31735e..6e7889bff 100644 --- a/src/main/java/com/simibubi/create/content/optics/ILightHandler.java +++ b/src/main/java/com/simibubi/create/content/optics/ILightHandler.java @@ -91,10 +91,10 @@ public interface ILightHandler { return true; } - default void updateBeams() { - } + void updateBeams(); - default float getInterpolatedAngle(float v) { - return 0; + @FunctionalInterface + interface ILightHandlerProvider { + ILightHandler getHandler(); } } diff --git a/src/main/java/com/simibubi/create/content/optics/ILightHandlerProvider.java b/src/main/java/com/simibubi/create/content/optics/ILightHandlerProvider.java deleted file mode 100644 index 1a6400e0b..000000000 --- a/src/main/java/com/simibubi/create/content/optics/ILightHandlerProvider.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.simibubi.create.content.optics; - -@FunctionalInterface -public interface ILightHandlerProvider { - ILightHandler getHandler(); -} diff --git a/src/main/java/com/simibubi/create/content/optics/behaviour/AbstractLightHandlingBehaviour.java b/src/main/java/com/simibubi/create/content/optics/behaviour/AbstractLightHandlingBehaviour.java new file mode 100644 index 000000000..83b887f84 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/optics/behaviour/AbstractLightHandlingBehaviour.java @@ -0,0 +1,83 @@ +package com.simibubi.create.content.optics.behaviour; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import javax.annotation.Nullable; + +import com.simibubi.create.content.optics.Beam; +import com.simibubi.create.content.optics.ILightHandler; +import com.simibubi.create.foundation.tileEntity.SmartTileEntity; +import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; +import com.simibubi.create.foundation.utility.BeaconHelper; +import com.simibubi.create.foundation.utility.VecHelper; + +import net.minecraft.tileentity.BeaconTileEntity; +import net.minecraft.tileentity.TileEntity; + +public abstract class AbstractLightHandlingBehaviour extends TileEntityBehaviour implements ILightHandler { + protected final T handler; + protected Set beams; + protected Beam beaconBeam = null; + @Nullable + protected BeaconTileEntity beacon; + + protected AbstractLightHandlingBehaviour(T te) { + super(te); + this.handler = te; + beams = new HashSet<>(); + } + + @Override + public void tick() { + super.tick(); + if (beacon != null && beacon.isRemoved()) + updateBeaconState(); + } + + + protected void updateBeaconState() { + BeaconTileEntity beaconBefore = beacon; + beacon = BeaconHelper.getBeaconTE(getBlockPos(), getHandlerWorld()) + .orElse(null); + + if (beaconBefore != null) { + beaconBeam.clear(); + beaconBeam = null; + updateBeams(); + } + + if (beacon != null) { + beaconBeam = constructOutBeam(null, VecHelper.UP, beacon.getPos()); + if (beaconBeam != null && !beaconBeam.isEmpty()) { + beaconBeam.addListener(this); + beaconBeam.onCreated(); + } + } + } + + @Override + public TileEntity getTile() { + return tileEntity; + } + + @Override + public void lazyTick() { + super.lazyTick(); + updateBeaconState(); + updateBeams(); + } + + + @Override + public Iterator getRenderBeams() { + return beaconBeam == null ? Collections.emptyIterator() : Collections.singleton(beaconBeam) + .iterator(); + } + + public Set getBeams() { + return beams; + } +} diff --git a/src/main/java/com/simibubi/create/content/optics/behaviour/AbstractLightRelayBehaviour.java b/src/main/java/com/simibubi/create/content/optics/behaviour/AbstractLightRelayBehaviour.java new file mode 100644 index 000000000..e406838f7 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/optics/behaviour/AbstractLightRelayBehaviour.java @@ -0,0 +1,68 @@ +package com.simibubi.create.content.optics.behaviour; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Objects; +import java.util.Set; +import java.util.function.Predicate; +import java.util.stream.Stream; + +import com.google.common.collect.Iterators; +import com.simibubi.create.content.optics.Beam; +import com.simibubi.create.content.optics.ILightHandler; +import com.simibubi.create.foundation.tileEntity.SmartTileEntity; + +public abstract class AbstractLightRelayBehaviour extends AbstractLightHandlingBehaviour { + private boolean isUpdating; + + protected AbstractLightRelayBehaviour(T te) { + super(te); + isUpdating = false; + } + + @Override + public void updateBeams() { + if (isUpdating) + return; + isUpdating = true; + + Set oldBeams = new HashSet<>(beams); + beams.clear(); + for (Beam child : oldBeams) { + Beam parent = child.getParent(); + + child.onRemoved(); + if (parent == null || parent.isRemoved()) + continue; + constructSubBeams(parent).forEach(Beam::onCreated); + } + isUpdating = false; + } + + @Override + public Stream constructSubBeams(Beam beam) { + if (beams.stream() + .map(Beam::getParent) + .filter(Objects::nonNull) + .filter(((Predicate) Beam::isRemoved).negate()) + .map(Beam::getDirection) + .filter(Objects::nonNull) + .anyMatch(b -> b.equals(beam.getDirection()))) + return Stream.empty(); + return constructSubBeams(beam, beams); + } + + public Stream constructSubBeams(Beam beam, Set beamListing) { + return safeConstructSubBeamsFor(beam) + .filter(Objects::nonNull) + .filter(((Predicate) Beam::isEmpty).negate()) + .peek(beamListing::add); + } + + @Override + public Iterator getRenderBeams() { + return Iterators.concat(beams.iterator(), super.getRenderBeams()); + } + + protected abstract Stream safeConstructSubBeamsFor(Beam beam); +} diff --git a/src/main/java/com/simibubi/create/content/optics/behaviour/RotatedLightHandlingBehaviour.java b/src/main/java/com/simibubi/create/content/optics/behaviour/AbstractRotatedLightRelayBehaviour.java similarity index 85% rename from src/main/java/com/simibubi/create/content/optics/behaviour/RotatedLightHandlingBehaviour.java rename to src/main/java/com/simibubi/create/content/optics/behaviour/AbstractRotatedLightRelayBehaviour.java index 8af8966d9..4be66c431 100644 --- a/src/main/java/com/simibubi/create/content/optics/behaviour/RotatedLightHandlingBehaviour.java +++ b/src/main/java/com/simibubi/create/content/optics/behaviour/AbstractRotatedLightRelayBehaviour.java @@ -1,18 +1,18 @@ package com.simibubi.create.content.optics.behaviour; import com.simibubi.create.content.contraptions.base.KineticTileEntity; -import com.simibubi.create.content.optics.ILightHandlerProvider; +import com.simibubi.create.content.optics.ILightHandler; import com.simibubi.create.foundation.utility.ServerSpeedProvider; import net.minecraft.nbt.CompoundNBT; import net.minecraft.util.math.MathHelper; -public abstract class RotatedLightHandlingBehaviour extends LightHandlingBehaviour { +public abstract class AbstractRotatedLightRelayBehaviour extends AbstractLightRelayBehaviour { protected float angle; protected float clientAngleDiff; private float prevAngle; - public RotatedLightHandlingBehaviour(T te) { + protected AbstractRotatedLightRelayBehaviour(T te) { super(te); } diff --git a/src/main/java/com/simibubi/create/content/optics/behaviour/LightAcceptingBehaviour.java b/src/main/java/com/simibubi/create/content/optics/behaviour/LightAcceptingBehaviour.java new file mode 100644 index 000000000..335195701 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/optics/behaviour/LightAcceptingBehaviour.java @@ -0,0 +1,52 @@ +package com.simibubi.create.content.optics.behaviour; + +import com.simibubi.create.content.optics.Beam; +import com.simibubi.create.content.optics.ILightHandler; +import com.simibubi.create.content.optics.mirror.MirrorBehaviour; +import com.simibubi.create.foundation.tileEntity.SmartTileEntity; +import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType; + +import java.util.Objects; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class LightAcceptingBehaviour extends AbstractLightHandlingBehaviour { + public static final BehaviourType TYPE = new BehaviourType<>(); + boolean isUpdating = false; + + protected LightAcceptingBehaviour(T te) { + super(te); + } + + @Override + public void updateBeams() { + if (isUpdating) + return; + isUpdating = true; + + beams = beams.stream() + .filter(Objects::nonNull) + .filter(((Predicate) Beam::isRemoved).negate()) + .collect(Collectors.toSet()); + isUpdating = false; + } + + @Override + public BehaviourType getType() { + return TYPE; + } + + @Override + public Stream constructSubBeams(Beam beam) { + if (beams.stream() + .map(Beam::getParent) + .filter(Objects::nonNull) + .filter(((Predicate) Beam::isRemoved).negate()) + .map(Beam::getDirection) + .filter(Objects::nonNull) + .noneMatch(b -> b.equals(beam.getDirection()))) + beams.add(beam); + return Stream.empty(); + } +} diff --git a/src/main/java/com/simibubi/create/content/optics/behaviour/LightHandlingBehaviour.java b/src/main/java/com/simibubi/create/content/optics/behaviour/LightHandlingBehaviour.java deleted file mode 100644 index 2e0005699..000000000 --- a/src/main/java/com/simibubi/create/content/optics/behaviour/LightHandlingBehaviour.java +++ /dev/null @@ -1,126 +0,0 @@ -package com.simibubi.create.content.optics.behaviour; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Objects; -import java.util.Set; -import java.util.function.Predicate; -import java.util.stream.Stream; - -import javax.annotation.Nullable; - -import com.google.common.collect.Iterators; -import com.simibubi.create.content.optics.Beam; -import com.simibubi.create.content.optics.ILightHandler; -import com.simibubi.create.content.optics.ILightHandlerProvider; -import com.simibubi.create.foundation.tileEntity.SmartTileEntity; -import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; -import com.simibubi.create.foundation.utility.BeaconHelper; -import com.simibubi.create.foundation.utility.VecHelper; - -import net.minecraft.tileentity.BeaconTileEntity; -import net.minecraft.tileentity.TileEntity; - -public abstract class LightHandlingBehaviour extends TileEntityBehaviour implements ILightHandler { - protected final T handler; - public Set beams; - private boolean isUpdating; - @Nullable - private BeaconTileEntity beacon; - private Beam beaconBeam = null; - - public LightHandlingBehaviour(T te) { - super(te); - handler = te; - isUpdating = false; - beams = new HashSet<>(); - } - - @Override - public void tick() { - super.tick(); - if (beacon != null && beacon.isRemoved()) - updateBeaconState(); - } - - protected void updateBeaconState() { - BeaconTileEntity beaconBefore = beacon; - beacon = BeaconHelper.getBeaconTE(getBlockPos(), getHandlerWorld()) - .orElse(null); - - if (beaconBefore != null) { - beaconBeam.clear(); - beaconBeam = null; - updateBeams(); - } - - if (beacon != null) { - beaconBeam = constructOutBeam(null, VecHelper.UP, beacon.getPos()); - if (beaconBeam != null && !beaconBeam.isEmpty()) { - beaconBeam.addListener(this); - beaconBeam.onCreated(); - } - } - } - - @Override - public TileEntity getTile() { - return tileEntity; - } - - @Override - public void lazyTick() { - super.lazyTick(); - updateBeaconState(); - updateBeams(); - } - - @Override - public void updateBeams() { - if (isUpdating) - return; - isUpdating = true; - - Set newBeams = new HashSet<>(); - for (Beam child : new HashSet<>(beams)) { - Beam parent = child.getParent(); - - child.onRemoved(); - if (parent == null || parent.isRemoved()) - continue; - constructSubBeams(parent, newBeams).forEach(Beam::onCreated); - } - beams = newBeams; - isUpdating = false; - } - - @Override - public Stream constructSubBeams(Beam beam) { - if (beams.stream() - .map(Beam::getParent) - .filter(Objects::nonNull) - .filter(((Predicate) Beam::isRemoved).negate()) - .map(Beam::getDirection) - .filter(Objects::nonNull) - .anyMatch(b -> b.equals(beam.getDirection()))) - return Stream.empty(); - return constructSubBeams(beam, beams); - } - - public Stream constructSubBeams(Beam beam, Set beamListing) { - return safeConstructSubBeamsFor(beam) - .filter(Objects::nonNull) - .filter(((Predicate) Beam::isEmpty).negate()) - .peek(beamListing::add); - } - - protected abstract Stream safeConstructSubBeamsFor(Beam beam); - - @Override - public Iterator getRenderBeams() { - Iterator beaconIter = beaconBeam == null ? Collections.emptyIterator() : Collections.singleton(beaconBeam) - .iterator(); - return Iterators.concat(beams.iterator(), beaconIter); - } -} diff --git a/src/main/java/com/simibubi/create/content/optics/mirror/MirrorBehaviour.java b/src/main/java/com/simibubi/create/content/optics/mirror/MirrorBehaviour.java index e134722e9..be46a3e40 100644 --- a/src/main/java/com/simibubi/create/content/optics/mirror/MirrorBehaviour.java +++ b/src/main/java/com/simibubi/create/content/optics/mirror/MirrorBehaviour.java @@ -5,7 +5,7 @@ import java.util.stream.Stream; import javax.annotation.Nonnull; import com.simibubi.create.content.optics.Beam; -import com.simibubi.create.content.optics.behaviour.RotatedLightHandlingBehaviour; +import com.simibubi.create.content.optics.behaviour.AbstractRotatedLightRelayBehaviour; import com.simibubi.create.foundation.collision.Matrix3d; import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType; import com.simibubi.create.foundation.utility.AngleHelper; @@ -14,7 +14,7 @@ import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.util.Direction; import net.minecraft.util.math.vector.Vector3d; -public class MirrorBehaviour extends RotatedLightHandlingBehaviour { +public class MirrorBehaviour extends AbstractRotatedLightRelayBehaviour { public static final BehaviourType TYPE = new BehaviourType<>(); public MirrorBehaviour(MirrorTileEntity te) { diff --git a/src/main/java/com/simibubi/create/content/optics/mirror/MirrorTileEntity.java b/src/main/java/com/simibubi/create/content/optics/mirror/MirrorTileEntity.java index 00ae8fa32..f76205e0f 100644 --- a/src/main/java/com/simibubi/create/content/optics/mirror/MirrorTileEntity.java +++ b/src/main/java/com/simibubi/create/content/optics/mirror/MirrorTileEntity.java @@ -4,7 +4,7 @@ import java.util.List; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.optics.ILightHandler; -import com.simibubi.create.content.optics.ILightHandlerProvider; +import com.simibubi.create.content.optics.behaviour.AbstractRotatedLightRelayBehaviour; import com.simibubi.create.content.optics.behaviour.RotationMode; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.CenteredSideValueBoxTransform; @@ -18,7 +18,7 @@ import net.minecraft.util.math.AxisAlignedBB; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; -public class MirrorTileEntity extends KineticTileEntity implements ILightHandlerProvider, RotationMode.RotationModeProvider { +public class MirrorTileEntity extends KineticTileEntity implements ILightHandler.ILightHandlerProvider, RotationMode.RotationModeProvider { protected ScrollOptionBehaviour movementMode; protected MirrorBehaviour mirror; @@ -61,7 +61,7 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler } @Override - public ILightHandler getHandler() { + public AbstractRotatedLightRelayBehaviour getHandler() { return mirror; } diff --git a/src/main/java/com/simibubi/create/foundation/utility/BeaconHelper.java b/src/main/java/com/simibubi/create/foundation/utility/BeaconHelper.java index 2659a18fb..85a48c52e 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/BeaconHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/BeaconHelper.java @@ -4,7 +4,7 @@ import java.util.Optional; import javax.annotation.Nullable; -import com.simibubi.create.content.optics.ILightHandlerProvider; +import com.simibubi.create.content.optics.ILightHandler; import com.simibubi.create.foundation.block.ITE; import net.minecraft.block.Block; @@ -67,7 +67,7 @@ public class BeaconHelper { try { if (state.getBlock() instanceof ITE) { TileEntity te = ((ITE) state.getBlock()).getTileEntity(world, pos); - if (te instanceof ILightHandlerProvider && ((ILightHandlerProvider) te).getHandler() + if (te instanceof ILightHandler.ILightHandlerProvider && ((ILightHandler.ILightHandlerProvider) te).getHandler() .absorbsLight()) return 15; }