2021-11-27 23:49:43 +01:00
|
|
|
package com.simibubi.create.foundation.ponder.instruction;
|
2021-03-05 20:54:41 +01:00
|
|
|
|
|
|
|
import java.util.Optional;
|
|
|
|
import java.util.function.BiConsumer;
|
|
|
|
import java.util.function.Function;
|
|
|
|
|
2021-03-16 21:04:42 +01:00
|
|
|
import com.simibubi.create.content.contraptions.components.deployer.DeployerTileEntity;
|
2021-03-11 03:32:18 +01:00
|
|
|
import com.simibubi.create.content.contraptions.components.structureMovement.bearing.IBearingTileEntity;
|
2021-03-05 20:54:41 +01:00
|
|
|
import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyTileEntity;
|
2023-05-09 18:23:47 +02:00
|
|
|
import com.simibubi.create.content.logistics.trains.track.AbstractBogeyTileEntity;
|
2021-03-05 20:54:41 +01:00
|
|
|
import com.simibubi.create.foundation.ponder.PonderScene;
|
|
|
|
import com.simibubi.create.foundation.ponder.PonderWorld;
|
|
|
|
|
2021-11-02 00:08:20 +01:00
|
|
|
import net.minecraft.core.BlockPos;
|
2021-11-02 06:18:30 +01:00
|
|
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
2021-03-05 20:54:41 +01:00
|
|
|
|
|
|
|
public class AnimateTileEntityInstruction extends TickingInstruction {
|
|
|
|
|
|
|
|
protected double deltaPerTick;
|
|
|
|
protected double totalDelta;
|
|
|
|
protected double target;
|
|
|
|
protected final BlockPos location;
|
|
|
|
|
|
|
|
private BiConsumer<PonderWorld, Float> setter;
|
|
|
|
private Function<PonderWorld, Float> getter;
|
|
|
|
|
|
|
|
public static AnimateTileEntityInstruction bearing(BlockPos location, float totalDelta, int ticks) {
|
|
|
|
return new AnimateTileEntityInstruction(location, totalDelta, ticks,
|
2021-03-11 03:32:18 +01:00
|
|
|
(w, f) -> castIfPresent(w, location, IBearingTileEntity.class).ifPresent(bte -> bte.setAngle(f)),
|
|
|
|
(w) -> castIfPresent(w, location, IBearingTileEntity.class).map(bte -> bte.getInterpolatedAngle(0))
|
2021-03-05 20:54:41 +01:00
|
|
|
.orElse(0f));
|
|
|
|
}
|
|
|
|
|
2022-06-28 00:07:10 +02:00
|
|
|
public static AnimateTileEntityInstruction bogey(BlockPos location, float totalDelta, int ticks) {
|
|
|
|
float movedPerTick = totalDelta / ticks;
|
|
|
|
return new AnimateTileEntityInstruction(location, totalDelta, ticks,
|
2023-05-09 18:23:47 +02:00
|
|
|
(w, f) -> castIfPresent(w, location, AbstractBogeyTileEntity.class)
|
2022-06-28 00:07:10 +02:00
|
|
|
.ifPresent(bte -> bte.animate(f.equals(totalDelta) ? 0 : movedPerTick)),
|
|
|
|
(w) -> 0f);
|
|
|
|
}
|
|
|
|
|
2021-03-05 20:54:41 +01:00
|
|
|
public static AnimateTileEntityInstruction pulley(BlockPos location, float totalDelta, int ticks) {
|
|
|
|
return new AnimateTileEntityInstruction(location, totalDelta, ticks,
|
2021-03-11 03:32:18 +01:00
|
|
|
(w, f) -> castIfPresent(w, location, PulleyTileEntity.class).ifPresent(pulley -> pulley.animateOffset(f)),
|
2021-03-05 20:54:41 +01:00
|
|
|
(w) -> castIfPresent(w, location, PulleyTileEntity.class).map(pulley -> pulley.offset)
|
|
|
|
.orElse(0f));
|
|
|
|
}
|
|
|
|
|
2021-03-16 21:04:42 +01:00
|
|
|
public static AnimateTileEntityInstruction deployer(BlockPos location, float totalDelta, int ticks) {
|
|
|
|
return new AnimateTileEntityInstruction(location, totalDelta, ticks,
|
|
|
|
(w, f) -> castIfPresent(w, location, DeployerTileEntity.class)
|
|
|
|
.ifPresent(deployer -> deployer.setAnimatedOffset(f)),
|
|
|
|
(w) -> castIfPresent(w, location, DeployerTileEntity.class).map(deployer -> deployer.getHandOffset(1))
|
|
|
|
.orElse(0f));
|
|
|
|
}
|
|
|
|
|
2021-03-05 20:54:41 +01:00
|
|
|
protected AnimateTileEntityInstruction(BlockPos location, float totalDelta, int ticks,
|
|
|
|
BiConsumer<PonderWorld, Float> setter, Function<PonderWorld, Float> getter) {
|
|
|
|
super(false, ticks);
|
|
|
|
this.location = location;
|
|
|
|
this.setter = setter;
|
|
|
|
this.getter = getter;
|
|
|
|
this.deltaPerTick = totalDelta * (1d / ticks);
|
|
|
|
this.totalDelta = totalDelta;
|
|
|
|
this.target = totalDelta;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected final void firstTick(PonderScene scene) {
|
|
|
|
super.firstTick(scene);
|
|
|
|
target = getter.apply(scene.getWorld()) + totalDelta;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void tick(PonderScene scene) {
|
|
|
|
super.tick(scene);
|
|
|
|
PonderWorld world = scene.getWorld();
|
2021-03-16 21:04:42 +01:00
|
|
|
float current = getter.apply(world);
|
|
|
|
float next = (float) (remainingTicks == 0 ? target : current + deltaPerTick);
|
|
|
|
setter.accept(world, next);
|
|
|
|
if (remainingTicks == 0) // lock interpolation
|
|
|
|
setter.accept(world, next);
|
2021-03-05 20:54:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private static <T> Optional<T> castIfPresent(PonderWorld world, BlockPos pos, Class<T> teType) {
|
2021-11-02 00:08:20 +01:00
|
|
|
BlockEntity tileEntity = world.getBlockEntity(pos);
|
2021-03-05 20:54:41 +01:00
|
|
|
if (teType.isInstance(tileEntity))
|
|
|
|
return Optional.of(teType.cast(tileEntity));
|
|
|
|
return Optional.empty();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|