Do some more shuffling and splitting, add LightAcceptingBehaviour

This commit is contained in:
grimmauld 2021-04-21 09:39:51 +02:00
parent 19fa27c54b
commit 869d68ac27
10 changed files with 217 additions and 146 deletions

View file

@ -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();
}
}

View file

@ -1,6 +0,0 @@
package com.simibubi.create.content.optics;
@FunctionalInterface
public interface ILightHandlerProvider {
ILightHandler getHandler();
}

View file

@ -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<T extends SmartTileEntity & ILightHandler.ILightHandlerProvider> extends TileEntityBehaviour implements ILightHandler {
protected final T handler;
protected Set<Beam> 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<Beam> getRenderBeams() {
return beaconBeam == null ? Collections.emptyIterator() : Collections.singleton(beaconBeam)
.iterator();
}
public Set<Beam> getBeams() {
return beams;
}
}

View file

@ -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<T extends SmartTileEntity & ILightHandler.ILightHandlerProvider> extends AbstractLightHandlingBehaviour<T> {
private boolean isUpdating;
protected AbstractLightRelayBehaviour(T te) {
super(te);
isUpdating = false;
}
@Override
public void updateBeams() {
if (isUpdating)
return;
isUpdating = true;
Set<Beam> 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<Beam> constructSubBeams(Beam beam) {
if (beams.stream()
.map(Beam::getParent)
.filter(Objects::nonNull)
.filter(((Predicate<Beam>) Beam::isRemoved).negate())
.map(Beam::getDirection)
.filter(Objects::nonNull)
.anyMatch(b -> b.equals(beam.getDirection())))
return Stream.empty();
return constructSubBeams(beam, beams);
}
public Stream<Beam> constructSubBeams(Beam beam, Set<Beam> beamListing) {
return safeConstructSubBeamsFor(beam)
.filter(Objects::nonNull)
.filter(((Predicate<Beam>) Beam::isEmpty).negate())
.peek(beamListing::add);
}
@Override
public Iterator<Beam> getRenderBeams() {
return Iterators.concat(beams.iterator(), super.getRenderBeams());
}
protected abstract Stream<Beam> safeConstructSubBeamsFor(Beam beam);
}

View file

@ -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<T extends KineticTileEntity & ILightHandlerProvider & RotationMode.RotationModeProvider> extends LightHandlingBehaviour<T> {
public abstract class AbstractRotatedLightRelayBehaviour<T extends KineticTileEntity & ILightHandler.ILightHandlerProvider & RotationMode.RotationModeProvider> extends AbstractLightRelayBehaviour<T> {
protected float angle;
protected float clientAngleDiff;
private float prevAngle;
public RotatedLightHandlingBehaviour(T te) {
protected AbstractRotatedLightRelayBehaviour(T te) {
super(te);
}

View file

@ -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<T extends SmartTileEntity & ILightHandler.ILightHandlerProvider> extends AbstractLightHandlingBehaviour<T> {
public static final BehaviourType<MirrorBehaviour> 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>) Beam::isRemoved).negate())
.collect(Collectors.toSet());
isUpdating = false;
}
@Override
public BehaviourType<?> getType() {
return TYPE;
}
@Override
public Stream<Beam> constructSubBeams(Beam beam) {
if (beams.stream()
.map(Beam::getParent)
.filter(Objects::nonNull)
.filter(((Predicate<Beam>) Beam::isRemoved).negate())
.map(Beam::getDirection)
.filter(Objects::nonNull)
.noneMatch(b -> b.equals(beam.getDirection())))
beams.add(beam);
return Stream.empty();
}
}

View file

@ -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<T extends SmartTileEntity & ILightHandlerProvider> extends TileEntityBehaviour implements ILightHandler {
protected final T handler;
public Set<Beam> 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<Beam> 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<Beam> constructSubBeams(Beam beam) {
if (beams.stream()
.map(Beam::getParent)
.filter(Objects::nonNull)
.filter(((Predicate<Beam>) Beam::isRemoved).negate())
.map(Beam::getDirection)
.filter(Objects::nonNull)
.anyMatch(b -> b.equals(beam.getDirection())))
return Stream.empty();
return constructSubBeams(beam, beams);
}
public Stream<Beam> constructSubBeams(Beam beam, Set<Beam> beamListing) {
return safeConstructSubBeamsFor(beam)
.filter(Objects::nonNull)
.filter(((Predicate<Beam>) Beam::isEmpty).negate())
.peek(beamListing::add);
}
protected abstract Stream<Beam> safeConstructSubBeamsFor(Beam beam);
@Override
public Iterator<Beam> getRenderBeams() {
Iterator<Beam> beaconIter = beaconBeam == null ? Collections.emptyIterator() : Collections.singleton(beaconBeam)
.iterator();
return Iterators.concat(beams.iterator(), beaconIter);
}
}

View file

@ -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<MirrorTileEntity> {
public class MirrorBehaviour extends AbstractRotatedLightRelayBehaviour<MirrorTileEntity> {
public static final BehaviourType<MirrorBehaviour> TYPE = new BehaviourType<>();
public MirrorBehaviour(MirrorTileEntity te) {

View file

@ -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<RotationMode> movementMode;
protected MirrorBehaviour mirror;
@ -61,7 +61,7 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
}
@Override
public ILightHandler getHandler() {
public AbstractRotatedLightRelayBehaviour<MirrorTileEntity> getHandler() {
return mirror;
}

View file

@ -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;
}