From da26c0ccbf26b892013f6e365556eea6952009f2 Mon Sep 17 00:00:00 2001 From: techno-sam Date: Thu, 4 May 2023 09:32:53 -0700 Subject: [PATCH] working on upside down bogeys in nether portals --- .gitignore | 3 +- build.gradle | 4 + .../com/simibubi/create/AllBogeyStyles.java | 3 +- .../com/simibubi/create/AllTileEntities.java | 4 +- .../structureMovement/Contraption.java | 2 +- .../logistics/trains/AbstractBogeyBlock.java | 64 +++++++--- .../logistics/trains/BogeyRenderer.java | 18 +-- .../content/logistics/trains/BogeySizes.java | 7 +- .../trains/BogeyTileEntityRenderer.java | 6 +- .../trains/StandardBogeyRenderer.java | 36 +++--- .../trains/entity/BackupBogeyRenderer.java | 2 +- .../trains/entity/BogeyInstance.java | 4 +- .../logistics/trains/entity/Carriage.java | 35 ++++-- .../trains/entity/CarriageBogey.java | 47 +++++--- .../trains/entity/CarriageContraption.java | 5 +- .../CarriageContraptionEntityRenderer.java | 12 +- .../entity/CarriageCouplingRenderer.java | 2 +- .../trains/entity/CarriageSounds.java | 8 +- .../logistics/trains/entity/Train.java | 18 ++- .../logistics/trains/entity/TrainPacket.java | 4 +- .../trains/entity/TrainRelocator.java | 11 +- .../trains/entity/TravellingPoint.java | 25 ++-- .../edgePoint/station/StationTileEntity.java | 98 +++++++++------ .../trains/track/AbstractBogeyTileEntity.java | 114 ++++++++++++++++++ .../trains/track/StandardBogeyBlock.java | 10 +- .../trains/track/StandardBogeyTileEntity.java | 99 +-------------- .../foundation/command/AllCommands.java | 1 + .../foundation/command/DebugValueCommand.java | 78 ++++++++++++ .../AnimateTileEntityInstruction.java | 4 +- 29 files changed, 483 insertions(+), 241 deletions(-) create mode 100644 src/main/java/com/simibubi/create/content/logistics/trains/track/AbstractBogeyTileEntity.java create mode 100644 src/main/java/com/simibubi/create/foundation/command/DebugValueCommand.java diff --git a/.gitignore b/.gitignore index 4afb35865..b9a3321f8 100644 --- a/.gitignore +++ b/.gitignore @@ -42,4 +42,5 @@ local.properties # PDT-specific .buildpath -.DS_Store \ No newline at end of file +.DS_Store +/libs/ diff --git a/build.gradle b/build.gradle index d8e3a2d87..02e7769a0 100644 --- a/build.gradle +++ b/build.gradle @@ -135,6 +135,9 @@ repositories { includeGroup "maven.modrinth" } } + flatDir { + dirs 'libs' + } } dependencies { @@ -169,6 +172,7 @@ dependencies { // runtimeOnly fg.deobf("slimeknights.mantle:Mantle:1.16.5-1.6.115") // runtimeOnly fg.deobf("slimeknights.tconstruct:TConstruct:1.16.5-3.1.1.252") // runtimeOnly fg.deobf("maven.modrinth:rubidium:0.5.3") + implementation fg.deobf("com.railwayteam.railways:railways-1.18.2-1.1.1:all") { transitive = false } // https://discord.com/channels/313125603924639766/725850371834118214/910619168821354497 // Prevent Mixin annotation processor from getting into IntelliJ's annotation processor settings diff --git a/src/main/java/com/simibubi/create/AllBogeyStyles.java b/src/main/java/com/simibubi/create/AllBogeyStyles.java index f4eed44df..220e27eb0 100644 --- a/src/main/java/com/simibubi/create/AllBogeyStyles.java +++ b/src/main/java/com/simibubi/create/AllBogeyStyles.java @@ -7,6 +7,7 @@ import com.simibubi.create.content.logistics.trains.BogeySizes; import com.simibubi.create.content.logistics.trains.StandardBogeyRenderer.*; import com.simibubi.create.content.logistics.trains.entity.BogeyStyle; +import com.simibubi.create.foundation.utility.Components; import com.simibubi.create.foundation.utility.Lang; import com.tterrag.registrate.util.entry.BlockEntry; @@ -30,7 +31,7 @@ public class AllBogeyStyles { public static BogeyStyle STANDARD = create("standard") .commonRenderer(CommonStandardBogeyRenderer::new) - .displayName(new TranslatableComponent("create.bogeys.styles.standard")) + .displayName(Components.translatable("create.bogeys.styles.standard")) .size(BogeySizes.SMALL, SmallStandardBogeyRenderer::new, AllBlocks.SMALL_BOGEY) .size(BogeySizes.LARGE, LargeStandardBogeyRenderer::new, AllBlocks.LARGE_BOGEY) .build(); diff --git a/src/main/java/com/simibubi/create/AllTileEntities.java b/src/main/java/com/simibubi/create/AllTileEntities.java index ba342d0f8..a6f0f7456 100644 --- a/src/main/java/com/simibubi/create/AllTileEntities.java +++ b/src/main/java/com/simibubi/create/AllTileEntities.java @@ -192,6 +192,7 @@ import com.simibubi.create.content.logistics.trains.management.edgePoint.signal. import com.simibubi.create.content.logistics.trains.management.edgePoint.station.StationRenderer; import com.simibubi.create.content.logistics.trains.management.edgePoint.station.StationTileEntity; import com.simibubi.create.content.logistics.trains.track.FakeTrackTileEntity; +import com.simibubi.create.content.logistics.trains.track.AbstractBogeyTileEntity; import com.simibubi.create.content.logistics.trains.track.StandardBogeyTileEntity; import com.simibubi.create.content.logistics.trains.track.TrackBlock; import com.simibubi.create.content.logistics.trains.track.TrackInstance; @@ -203,12 +204,9 @@ import com.simibubi.create.content.schematics.block.SchematicannonRenderer; import com.simibubi.create.content.schematics.block.SchematicannonTileEntity; import com.simibubi.create.foundation.tileEntity.renderer.SmartTileEntityRenderer; import com.tterrag.registrate.util.entry.BlockEntityEntry; -import com.tterrag.registrate.util.entry.BlockEntry; import com.tterrag.registrate.util.nullness.NonNullSupplier; -import net.minecraft.world.level.block.Block; - public class AllTileEntities { // Schematics diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java index 7a74a69c4..12807830f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java @@ -342,7 +342,7 @@ public abstract class Contraption { } // Bogeys tend to have sticky sides - if (state.getBlock()instanceof AbstractBogeyBlock bogey) + if (state.getBlock()instanceof AbstractBogeyBlock bogey) for (Direction d : bogey.getStickySurfaces(world, pos, state)) if (!visited.contains(pos.relative(d))) frontier.add(pos.relative(d)); diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/AbstractBogeyBlock.java b/src/main/java/com/simibubi/create/content/logistics/trains/AbstractBogeyBlock.java index 037382721..6f1ecd1b8 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/AbstractBogeyBlock.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/AbstractBogeyBlock.java @@ -17,7 +17,7 @@ import com.simibubi.create.AllBogeyStyles; import com.simibubi.create.AllItems; import com.simibubi.create.content.contraptions.wrench.IWrenchable; import com.simibubi.create.content.logistics.trains.entity.BogeyStyle; -import com.simibubi.create.content.logistics.trains.track.StandardBogeyTileEntity; +import com.simibubi.create.content.logistics.trains.track.AbstractBogeyTileEntity; import com.simibubi.create.content.schematics.ISpecialBlockItemRequirement; import com.simibubi.create.content.schematics.ItemRequirement; import com.simibubi.create.foundation.block.ITE; @@ -55,7 +55,7 @@ import net.minecraftforge.registries.ForgeRegistries; import org.jetbrains.annotations.NotNull; -public abstract class AbstractBogeyBlock extends Block implements ITE, ProperWaterloggedBlock, ISpecialBlockItemRequirement, IWrenchable { +public abstract class AbstractBogeyBlock extends Block implements ITE, ProperWaterloggedBlock, ISpecialBlockItemRequirement, IWrenchable { public static final EnumProperty AXIS = BlockStateProperties.HORIZONTAL_AXIS; static final List BOGEYS = new ArrayList<>(); public BogeySizes.BogeySize size; @@ -100,16 +100,37 @@ public abstract class AbstractBogeyBlock extends Block implements ITE commonRenderer = style.getNewCommonRenderInstance(); final BogeyRenderer renderer = style.getInWorldRenderInstance(this.getSize()); @@ -120,9 +141,10 @@ public abstract class AbstractBogeyBlock extends Block implements ITE - common.render(sbte.getBogeyData(), wheelAngle, ms, light, vb)); + common.render(upsideDown, bogeyData, wheelAngle, ms, light, vb, state == null)); } public BogeySizes.BogeySize getSize() { @@ -160,7 +182,7 @@ public abstract class AbstractBogeyBlock extends Block implements ITE[] getTransformsFromPartial(PartialModel model, PoseStack ms, boolean inContraption, int size) { - return (inContraption) ? transformContraptionModelData(keyFromModel(model), ms) : createModelData(model, size); + public Transform[] getTransformsFromPartial(PartialModel model, PoseStack ms, boolean inInstancedContraption, int size) { + return (inInstancedContraption) ? transformContraptionModelData(keyFromModel(model), ms) : createModelData(model, size); } /** @@ -69,7 +69,7 @@ public abstract class BogeyRenderer { * @param vb (Optional) Vertex Consumer used for in-world rendering */ @OnlyIn(Dist.CLIENT) - public abstract void render(CompoundTag bogeyData, float wheelAngle, PoseStack ms, int light, VertexConsumer vb); + public abstract void render(boolean upsideDown, CompoundTag bogeyData, float wheelAngle, PoseStack ms, int light, VertexConsumer vb, boolean inContraption); /** * Used for calling in-contraption rendering ensuring that falsey data is handled correctly @@ -79,8 +79,8 @@ public abstract class BogeyRenderer { * @param ms The posestack to render to */ @OnlyIn(Dist.CLIENT) - public void render(CompoundTag bogeyData, float wheelAngle, PoseStack ms) { - this.render(bogeyData, wheelAngle, ms, 0, null); + public void render(boolean upsideDown, CompoundTag bogeyData, float wheelAngle, PoseStack ms) { + this.render(upsideDown, bogeyData, wheelAngle, ms, 0, null, true); } public abstract BogeySizes.BogeySize getSize(); @@ -147,12 +147,12 @@ public abstract class BogeyRenderer { * * @param model The key of the model to be collected or instantiated * @param ms Posestack to bind the model to if it is within a contraption - * @param inContraption Type of rendering required + * @param inInstancedContraption Type of rendering required * @return A generic transform which can be used for both in-world and in-contraption models */ - public Transform getTransformFromPartial(PartialModel model, PoseStack ms, boolean inContraption) { + public Transform getTransformFromPartial(PartialModel model, PoseStack ms, boolean inInstancedContraption) { BlockState air = Blocks.AIR.defaultBlockState(); - return inContraption ? contraptionModelData.get(keyFromModel(model))[0].setTransform(ms) + return inInstancedContraption ? contraptionModelData.get(keyFromModel(model))[0].setTransform(ms) : CachedBufferer.partial(model, air); } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/BogeySizes.java b/src/main/java/com/simibubi/create/content/logistics/trains/BogeySizes.java index 8216cf287..95bf3a5c8 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/BogeySizes.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/BogeySizes.java @@ -21,14 +21,15 @@ public class BogeySizes { BOGEY_SIZES.add(LARGE); } - public static void addSize(String modId, String name, float size) { + public static BogeySize addSize(String modId, String name, float size) { ResourceLocation location = new ResourceLocation(modId, name); - addSize(location, size); + return addSize(location, size); } - public static void addSize(ResourceLocation location, float size) { + public static BogeySize addSize(ResourceLocation location, float size) { BogeySize customSize = new BogeySize(location, size); BOGEY_SIZES.add(customSize); + return customSize; } public static List getAllSizesSmallToLarge() { diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/BogeyTileEntityRenderer.java b/src/main/java/com/simibubi/create/content/logistics/trains/BogeyTileEntityRenderer.java index 547df8b1b..ebe2efba7 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/BogeyTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/BogeyTileEntityRenderer.java @@ -1,7 +1,7 @@ package com.simibubi.create.content.logistics.trains; import com.mojang.blaze3d.vertex.PoseStack; -import com.simibubi.create.content.logistics.trains.track.StandardBogeyTileEntity; +import com.simibubi.create.content.logistics.trains.track.AbstractBogeyTileEntity; import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; import net.minecraft.client.renderer.MultiBufferSource; @@ -17,10 +17,10 @@ public class BogeyTileEntityRenderer extends SafeTileEnti protected void renderSafe(T te, float partialTicks, PoseStack ms, MultiBufferSource buffer, int light, int overlay) { BlockState blockState = te.getBlockState(); - if (te instanceof StandardBogeyTileEntity sbte) { + if (te instanceof AbstractBogeyTileEntity sbte) { float angle = sbte.getVirtualAngle(partialTicks); if (blockState.getBlock() instanceof AbstractBogeyBlock bogey) - bogey.render(blockState, angle, ms, partialTicks, buffer, light, overlay, sbte); + bogey.render(blockState, bogey.isUpsideDown(blockState), angle, ms, partialTicks, buffer, light, overlay, sbte); } } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/StandardBogeyRenderer.java b/src/main/java/com/simibubi/create/content/logistics/trains/StandardBogeyRenderer.java index 2dddffba2..0e29b961c 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/StandardBogeyRenderer.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/StandardBogeyRenderer.java @@ -36,10 +36,10 @@ public class StandardBogeyRenderer { } @Override - public void render(CompoundTag bogeyData, float wheelAngle, PoseStack ms, int light, VertexConsumer vb) { - boolean inContraption = vb == null; + public void render(boolean upsideDown, CompoundTag bogeyData, float wheelAngle, PoseStack ms, int light, VertexConsumer vb, boolean inContraption) { + boolean inInstancedContraption = vb == null; Transform[] shafts = getTransformsFromBlockState(AllBlocks.SHAFT.getDefaultState() - .setValue(ShaftBlock.AXIS, Direction.Axis.Z), ms, inContraption, 2); + .setValue(ShaftBlock.AXIS, Direction.Axis.Z), ms, inInstancedContraption, 2); for (int i : Iterate.zeroAndOne) { shafts[i].translate(-.5f, .25f, i * -1) .centre() @@ -69,20 +69,20 @@ public class StandardBogeyRenderer { } @Override - public void render(CompoundTag bogeyData, float wheelAngle, PoseStack ms, int light, VertexConsumer vb) { - boolean inContraption = vb == null; - Transform transform = getTransformFromPartial(BOGEY_FRAME, ms, inContraption); + public void render(boolean upsideDown, CompoundTag bogeyData, float wheelAngle, PoseStack ms, int light, VertexConsumer vb, boolean inContraption) { + boolean inInstancedContraption = vb == null; + Transform transform = getTransformFromPartial(BOGEY_FRAME, ms, inInstancedContraption); finalize(transform, ms, light, vb); - Transform[] wheels = getTransformsFromPartial(SMALL_BOGEY_WHEELS, ms, inContraption, 2); + Transform[] wheels = getTransformsFromPartial(SMALL_BOGEY_WHEELS, ms, inInstancedContraption, 2); for (int side : Iterate.positiveAndNegative) { - if (!inContraption) + if (!inInstancedContraption) ms.pushPose(); Transform wheel = wheels[(side + 1)/2]; wheel.translate(0, 12 / 16f, side) .rotateX(wheelAngle); finalize(wheel, ms, light, vb); - if (!inContraption) + if (!inInstancedContraption) ms.popPose(); } } @@ -107,11 +107,11 @@ public class StandardBogeyRenderer { } @Override - public void render(CompoundTag bogeyData, float wheelAngle, PoseStack ms, int light, VertexConsumer vb) { - boolean inContraption = vb == null; + public void render(boolean upsideDown, CompoundTag bogeyData, float wheelAngle, PoseStack ms, int light, VertexConsumer vb, boolean inContraption) { + boolean inInstancedContraption = vb == null; Transform[] secondaryShafts = getTransformsFromBlockState(AllBlocks.SHAFT.getDefaultState() - .setValue(ShaftBlock.AXIS, Direction.Axis.X), ms, inContraption, 2); + .setValue(ShaftBlock.AXIS, Direction.Axis.X), ms, inInstancedContraption, 2); for (int i : Iterate.zeroAndOne) { Transform secondShaft = secondaryShafts[i]; @@ -122,29 +122,29 @@ public class StandardBogeyRenderer { finalize(secondShaft, ms, light, vb); } - Transform bogeyDrive = getTransformFromPartial(BOGEY_DRIVE, ms, inContraption); + Transform bogeyDrive = getTransformFromPartial(BOGEY_DRIVE, ms, inInstancedContraption); finalize(bogeyDrive, ms, light, vb); - Transform bogeyPiston = getTransformFromPartial(BOGEY_PISTON, ms, inContraption) + Transform bogeyPiston = getTransformFromPartial(BOGEY_PISTON, ms, inInstancedContraption) .translate(0, 0, 1 / 4f * Math.sin(AngleHelper.rad(wheelAngle))); finalize(bogeyPiston, ms, light, vb); - if (!inContraption) + if (!inInstancedContraption) ms.pushPose(); - Transform bogeyWheels = getTransformFromPartial(LARGE_BOGEY_WHEELS, ms, inContraption) + Transform bogeyWheels = getTransformFromPartial(LARGE_BOGEY_WHEELS, ms, inInstancedContraption) .translate(0, 1, 0) .rotateX(wheelAngle); finalize(bogeyWheels, ms, light, vb); - Transform bogeyPin = getTransformFromPartial(BOGEY_PIN, ms, inContraption) + Transform bogeyPin = getTransformFromPartial(BOGEY_PIN, ms, inInstancedContraption) .translate(0, 1, 0) .rotateX(wheelAngle) .translate(0, 1 / 4f, 0) .rotateX(-wheelAngle); finalize(bogeyPin, ms, light, vb); - if (!inContraption) + if (!inInstancedContraption) ms.popPose(); } } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/BackupBogeyRenderer.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/BackupBogeyRenderer.java index a8783ea3a..cc80a4120 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/BackupBogeyRenderer.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/BackupBogeyRenderer.java @@ -11,7 +11,7 @@ public class BackupBogeyRenderer extends BogeyRenderer.CommonRenderer { public static BackupBogeyRenderer INSTANCE = new BackupBogeyRenderer(); @Override - public void render(CompoundTag bogeyData, float wheelAngle, PoseStack ms, int light, VertexConsumer vb) { + public void render(boolean upsideDown, CompoundTag bogeyData, float wheelAngle, PoseStack ms, int light, VertexConsumer vb, boolean inContraption) { } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/BogeyInstance.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/BogeyInstance.java index a9b0ff8af..9e66664ce 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/BogeyInstance.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/BogeyInstance.java @@ -46,8 +46,8 @@ public final class BogeyInstance { } commonRenderer.ifPresent(bogeyRenderer -> - bogeyRenderer.render(bogey.bogeyData, wheelAngle, ms)); - renderer.render(bogey.bogeyData, wheelAngle, ms); + bogeyRenderer.render(bogey.isUpsideDown(), bogey.bogeyData, wheelAngle, ms)); + renderer.render(bogey.isUpsideDown(), bogey.bogeyData, wheelAngle, ms); } public void updateLight(BlockAndTintGetter world, CarriageContraptionEntity entity) { diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/Carriage.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/Carriage.java index 12d25eea7..c9b415aae 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/Carriage.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/Carriage.java @@ -16,6 +16,8 @@ import java.util.function.Function; import javax.annotation.Nullable; +import com.simibubi.create.foundation.command.DebugValueCommand; + import org.apache.commons.lang3.mutable.MutableDouble; import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; @@ -306,6 +308,9 @@ public class Carriage { double leadingWheelSpacing = leadingBogey.type.getWheelPointSpacing(); double trailingWheelSpacing = trailingBogey.type.getWheelPointSpacing(); + boolean leadingUpsideDown = leadingBogey.isUpsideDown(); + boolean trailingUpsideDown = trailingBogey.isUpsideDown(); + for (boolean leading : Iterate.trueAndFalse) { TravellingPoint point = leading ? getLeadingPoint() : getTrailingPoint(); TravellingPoint otherPoint = !leading ? getLeadingPoint() : getTrailingPoint(); @@ -321,24 +326,31 @@ public class Carriage { dce.positionAnchor = dimension.equals(leadingBogeyDim) ? leadingBogey.getAnchorPosition() : pivoted(dce, dimension, point, - leading ? leadingWheelSpacing / 2 : bogeySpacing + trailingWheelSpacing / 2); + leading ? leadingWheelSpacing / 2 : bogeySpacing + trailingWheelSpacing / 2, + leadingUpsideDown, trailingUpsideDown, leading); + + boolean backAnchorFlip = trailingBogey.isUpsideDown() ^ leadingBogey.isUpsideDown(); if (isOnTwoBogeys()) { dce.rotationAnchors.setFirst(dimension.equals(leadingBogeyDim) ? leadingBogey.getAnchorPosition() : pivoted(dce, dimension, point, - leading ? leadingWheelSpacing / 2 : bogeySpacing + trailingWheelSpacing / 2)); - dce.rotationAnchors.setSecond(dimension.equals(trailingBogeyDim) ? trailingBogey.getAnchorPosition() + leading ? leadingWheelSpacing / 2 : bogeySpacing + trailingWheelSpacing / 2, + leadingUpsideDown, trailingUpsideDown, leading)); + dce.rotationAnchors.setSecond(dimension.equals(trailingBogeyDim) ? trailingBogey.getAnchorPosition(backAnchorFlip) : pivoted(dce, dimension, point, - leading ? leadingWheelSpacing / 2 + bogeySpacing : trailingWheelSpacing / 2)); + leading ? leadingWheelSpacing / 2 + bogeySpacing : trailingWheelSpacing / 2, + leadingUpsideDown, trailingUpsideDown, leading)); } else { if (dimension.equals(otherDimension)) { dce.rotationAnchors = leadingBogey.points.map(TravellingPoint::getPosition); } else { dce.rotationAnchors.setFirst(leadingBogey.points.getFirst() == point ? point.getPosition() - : pivoted(dce, dimension, point, leadingWheelSpacing)); + : pivoted(dce, dimension, point, leadingWheelSpacing, + leadingUpsideDown, trailingUpsideDown, leading)); dce.rotationAnchors.setSecond(leadingBogey.points.getSecond() == point ? point.getPosition() - : pivoted(dce, dimension, point, leadingWheelSpacing)); + : pivoted(dce, dimension, point, leadingWheelSpacing, + leadingUpsideDown, trailingUpsideDown, leading)); } } @@ -356,15 +368,20 @@ public class Carriage { } private Vec3 pivoted(DimensionalCarriageEntity dce, ResourceKey dimension, TravellingPoint start, - double offset) { + double offset, boolean leadingUpsideDown, boolean trailingUpsideDown, boolean isLeading) { if (train.graph == null) return dce.pivot == null ? null : dce.pivot.getLocation(); TrackNodeLocation pivot = dce.findPivot(dimension, start == getLeadingPoint()); if (pivot == null) return null; - Vec3 startVec = start.getPosition(); + Vec3 startVec = start.getPosition(start != getLeadingPoint() && (leadingBogey().isUpsideDown() != trailingBogey().isUpsideDown())); Vec3 portalVec = pivot.getLocation() - .add(0, 1, 0); + .add(0, DebugValueCommand.tmpPortalOffset(leadingUpsideDown, trailingUpsideDown, isLeading), 0); + // same side - other side + // n(ormal)-n(ormal) + // u(pside down)-u(pside down) what about un ? not tested yet un doesn't work with + 1 or -1. HALP + // 1 works for: nn n nu + //-1 works for: uu u return VecHelper.lerp((float) (offset / startVec.distanceTo(portalVec)), startVec, portalVec); } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageBogey.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageBogey.java index 3ac7d3a43..0338b2366 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageBogey.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageBogey.java @@ -8,7 +8,7 @@ import com.simibubi.create.Create; import com.simibubi.create.content.logistics.trains.DimensionPalette; import com.simibubi.create.content.logistics.trains.AbstractBogeyBlock; import com.simibubi.create.content.logistics.trains.TrackGraph; -import com.simibubi.create.content.logistics.trains.track.StandardBogeyTileEntity; +import com.simibubi.create.content.logistics.trains.track.AbstractBogeyTileEntity; import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Iterate; @@ -28,7 +28,7 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.phys.Vec3; import net.minecraftforge.registries.ForgeRegistries; -import static com.simibubi.create.content.logistics.trains.track.StandardBogeyTileEntity.BOGEY_STYLE_KEY; +import static com.simibubi.create.content.logistics.trains.track.AbstractBogeyTileEntity.BOGEY_STYLE_KEY; public class CarriageBogey { @@ -38,6 +38,7 @@ public class CarriageBogey { public CompoundTag bogeyData; AbstractBogeyBlock type; + boolean upsideDown; Couple points; LerpedFloat wheelAngle; @@ -48,11 +49,14 @@ public class CarriageBogey { int derailAngle; - public CarriageBogey(AbstractBogeyBlock type, CompoundTag bogeyData, TravellingPoint point, TravellingPoint point2) { + public CarriageBogey(AbstractBogeyBlock type, boolean upsideDown, CompoundTag bogeyData, TravellingPoint point, TravellingPoint point2) { + this.type = type; if (bogeyData == null || bogeyData.isEmpty()) bogeyData = this.createBogeyData(); // Prevent Crash When Updating this.bogeyData = bogeyData; - this.type = type; + this.upsideDown = type.canBeUpsideDown() && upsideDown; + point.upsideDown = this.upsideDown; + point2.upsideDown = this.upsideDown; points = Couple.create(point, point2); wheelAngle = LerpedFloat.angular(); yaw = LerpedFloat.angular(); @@ -109,11 +113,15 @@ public class CarriageBogey { } public TravellingPoint leading() { - return points.getFirst(); + TravellingPoint point = points.getFirst(); + point.upsideDown = isUpsideDown(); + return point; } public TravellingPoint trailing() { - return points.getSecond(); + TravellingPoint point = points.getSecond(); + point.upsideDown = isUpsideDown(); + return point; } public double getStress() { @@ -127,18 +135,23 @@ public class CarriageBogey { @Nullable public Vec3 getAnchorPosition() { + return getAnchorPosition(false); + } + + @Nullable + public Vec3 getAnchorPosition(boolean flipUpsideDown) { if (leading().edge == null) return null; return points.getFirst() - .getPosition() - .add(points.getSecond() - .getPosition()) - .scale(.5); + .getPosition(flipUpsideDown) + .add(points.getSecond() + .getPosition(flipUpsideDown)) + .scale(.5); } public void updateCouplingAnchor(Vec3 entityPos, float entityXRot, float entityYRot, int bogeySpacing, float partialTicks, boolean leading) { - Vec3 thisOffset = type.getConnectorAnchorOffset(); + Vec3 thisOffset = type.getConnectorAnchorOffset(isUpsideDown()); thisOffset = thisOffset.multiply(1, 1, leading ? -1 : 1); thisOffset = VecHelper.rotate(thisOffset, pitch.getValue(partialTicks), Axis.X); @@ -159,6 +172,7 @@ public class CarriageBogey { tag.putString("Type", RegisteredObjects.getKeyOrThrow((Block) type) .toString()); tag.put("Points", points.serializeEach(tp -> tp.write(dimensions))); + tag.putBoolean("UpsideDown", upsideDown); tag.put(BOGEY_STYLE_KEY, bogeyData); return tag; } @@ -166,10 +180,11 @@ public class CarriageBogey { public static CarriageBogey read(CompoundTag tag, TrackGraph graph, DimensionPalette dimensions) { ResourceLocation location = new ResourceLocation(tag.getString("Type")); AbstractBogeyBlock type = (AbstractBogeyBlock) ForgeRegistries.BLOCKS.getValue(location); + boolean upsideDown = tag.getBoolean("UpsideDown"); Couple points = Couple.deserializeEach(tag.getList("Points", Tag.TAG_COMPOUND), c -> TravellingPoint.read(c, graph, dimensions)); - CompoundTag data = tag.getCompound(StandardBogeyTileEntity.BOGEY_DATA_KEY); - return new CarriageBogey(type, data, points.getFirst(), points.getSecond()); + CompoundTag data = tag.getCompound(AbstractBogeyTileEntity.BOGEY_DATA_KEY); + return new CarriageBogey(type, upsideDown, data, points.getFirst(), points.getSecond()); } public BogeyInstance createInstance(MaterialManager materialManager) { @@ -183,11 +198,15 @@ public class CarriageBogey { private CompoundTag createBogeyData() { CompoundTag nbt = new CompoundTag(); - NBTHelper.writeResourceLocation(nbt, BOGEY_STYLE_KEY, AllBogeyStyles.STANDARD.name); + NBTHelper.writeResourceLocation(nbt, BOGEY_STYLE_KEY, (type != null ? type.getDefaultStyle() : AllBogeyStyles.STANDARD).name); return nbt; } void setLeading() { isLeading = true; } + + public boolean isUpsideDown() { + return type.canBeUpsideDown() && upsideDown; + } } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraption.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraption.java index 3d06b191b..f7a2be376 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraption.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraption.java @@ -162,11 +162,12 @@ public class CarriageContraption extends Contraption { .getStep(), toLocalPos(pos)); } - if (blockState.getBlock() instanceof AbstractBogeyBlock) { + if (blockState.getBlock() instanceof AbstractBogeyBlock bogey) { + boolean captureTE = bogey.captureTileEntityForTrain(); bogeys++; if (bogeys == 2) secondBogeyPos = pos; - return Pair.of(new StructureBlockInfo(pos, blockState, null), null); + return Pair.of(new StructureBlockInfo(pos, blockState, captureTE ? getTileEntityNBT(world, pos) : null), captureTE ? world.getBlockEntity(pos) : null); } if (AllBlocks.BLAZE_BURNER.has(blockState) diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraptionEntityRenderer.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraptionEntityRenderer.java index 06a9ce394..6fbddcd11 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraptionEntityRenderer.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraptionEntityRenderer.java @@ -7,7 +7,7 @@ import com.jozufozu.flywheel.util.transform.TransformStack; import com.mojang.blaze3d.vertex.PoseStack; import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionEntityRenderer; -import com.simibubi.create.content.logistics.trains.track.StandardBogeyTileEntity; +import com.simibubi.create.content.logistics.trains.track.AbstractBogeyTileEntity; import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.MultiBufferSource; @@ -70,8 +70,8 @@ public class CarriageContraptionEntityRenderer extends ContraptionEntityRenderer int light = getBogeyLightCoords(entity, bogey, partialTicks); BlockEntity be = entity.getContraption().presentTileEntities.get(bogeyPos); - bogey.type.render(null, bogey.wheelAngle.getValue(partialTicks), ms, partialTicks, buffers, light, - overlay, (StandardBogeyTileEntity) be); + bogey.type.render(null, bogey.isUpsideDown(), bogey.wheelAngle.getValue(partialTicks), ms, partialTicks, buffers, light, + overlay, (AbstractBogeyTileEntity) be); ms.popPose(); } @@ -85,6 +85,8 @@ public class CarriageContraptionEntityRenderer extends ContraptionEntityRenderer public static void translateBogey(PoseStack ms, CarriageBogey bogey, int bogeySpacing, float viewYRot, float viewXRot, float partialTicks) { + boolean selfUpsideDown = bogey.isUpsideDown(); + boolean leadingUpsideDown = bogey.carriage.leadingBogey().isUpsideDown(); TransformStack.cast(ms) .rotateY(viewYRot + 90) .rotateX(-viewXRot) @@ -95,7 +97,9 @@ public class CarriageContraptionEntityRenderer extends ContraptionEntityRenderer .rotateY(-viewYRot - 90) .rotateY(bogey.yaw.getValue(partialTicks)) .rotateX(bogey.pitch.getValue(partialTicks)) - .translate(0, .5f, 0); + .translate(0, .5f, 0) + .rotateZ(selfUpsideDown ? 180 : 0) + .translateY(selfUpsideDown != leadingUpsideDown ? 2 : 0); } public static int getBogeyLightCoords(CarriageContraptionEntity entity, CarriageBogey bogey, float partialTicks) { diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageCouplingRenderer.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageCouplingRenderer.java index f67a86798..475491414 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageCouplingRenderer.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageCouplingRenderer.java @@ -82,7 +82,7 @@ public class CarriageCouplingRenderer { float margin = 3 / 16f; double couplingDistance = train.carriageSpacing.get(i) - 2 * margin - - bogey1.type.getConnectorAnchorOffset().z - bogey2.type.getConnectorAnchorOffset().z; + - bogey1.type.getConnectorAnchorOffset(bogey1.isUpsideDown()).z - bogey2.type.getConnectorAnchorOffset(bogey1.isUpsideDown()).z; int couplingSegments = (int) Math.round(couplingDistance * 4); double stretch = ((anchor2.distanceTo(anchor) - 2 * margin) * 4) / couplingSegments; for (int j = 0; j < couplingSegments; j++) { diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageSounds.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageSounds.java index 454cc406c..b9a59d58d 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageSounds.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageSounds.java @@ -88,7 +88,13 @@ public class CarriageSounds { double distance2 = toBogey2.length(); Couple bogeys = entity.getCarriage().bogeys; - closestBogeySound = bogeys.get(distance1 > distance2).getStyle().getSoundType(); + CarriageBogey relevantBogey = bogeys.get(distance1 > distance2); + if (relevantBogey == null) { + relevantBogey = bogeys.getFirst(); + } + if (relevantBogey != null) { + closestBogeySound = relevantBogey.getStyle().getSoundType(); + } Vec3 toCarriage = distance1 > distance2 ? toBogey2 : toBogey1; double distance = Math.min(distance1, distance2); diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/Train.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/Train.java index c56137ff8..aa75b3370 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/Train.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/Train.java @@ -17,7 +17,7 @@ import java.util.function.Consumer; import javax.annotation.Nullable; -import com.simibubi.create.content.logistics.trains.track.StandardBogeyTileEntity; +import com.simibubi.create.content.logistics.trains.track.AbstractBogeyTileEntity; import net.minecraft.world.level.block.entity.BlockEntity; @@ -317,7 +317,13 @@ public class Train { if (leadingAnchor == null || trailingAnchor == null) continue; - total += leadingAnchor.distanceTo(trailingAnchor); + double distanceTo = leadingAnchor.distanceToSqr(trailingAnchor); + if (carriage.leadingBogey().isUpsideDown() != previousCarriage.trailingBogey().isUpsideDown()) { + distanceTo = Math.sqrt(distanceTo - 4); + } else { + distanceTo = Math.sqrt(distanceTo); + } + total += distanceTo; entries++; } } @@ -726,14 +732,16 @@ public class Train { if (entity.getContraption()instanceof CarriageContraption cc) cc.returnStorageForDisassembly(carriage.storage); entity.setPos(Vec3 - .atLowerCornerOf(pos.relative(assemblyDirection, backwards ? offset + carriage.bogeySpacing : offset))); + .atLowerCornerOf(pos.relative(assemblyDirection, backwards ? offset + carriage.bogeySpacing : offset).below(carriage.leadingBogey().isUpsideDown() ? 2 : 0))); entity.disassemble(); for (CarriageBogey bogey : carriage.bogeys) { + if (bogey == null) + continue; Vec3 bogeyPosition = bogey.getAnchorPosition(); if (bogeyPosition == null) continue; BlockEntity be = level.getBlockEntity(new BlockPos(bogeyPosition)); - if (!(be instanceof StandardBogeyTileEntity sbte)) + if (!(be instanceof AbstractBogeyTileEntity sbte)) continue; sbte.setBogeyData(bogey.bogeyData); } @@ -957,7 +965,7 @@ public class Train { occupiedObservers.clear(); cachedObserverFiltering.clear(); - TravellingPoint signalScout = new TravellingPoint(node1, node2, edge, position); + TravellingPoint signalScout = new TravellingPoint(node1, node2, edge, position, false); Map allGroups = Create.RAILWAYS.signalEdgeGroups; MutableObject prevGroup = new MutableObject<>(null); diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/TrainPacket.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/TrainPacket.java index 3d27c86cd..54bb6c107 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/TrainPacket.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/TrainPacket.java @@ -49,8 +49,9 @@ public class TrainPacket extends SimplePacketBase { if (!isFirst && !buffer.readBoolean()) continue; AbstractBogeyBlock type = (AbstractBogeyBlock) ForgeRegistries.BLOCKS.getValue(buffer.readResourceLocation()); + boolean upsideDown = buffer.readBoolean(); CompoundTag data = buffer.readNbt(); - bogies.set(isFirst, new CarriageBogey(type, data, new TravellingPoint(), new TravellingPoint())); + bogies.set(isFirst, new CarriageBogey(type, upsideDown, data, new TravellingPoint(), new TravellingPoint())); } int spacing = buffer.readVarInt(); carriages.add(new Carriage(bogies.getFirst(), bogies.getSecond(), spacing)); @@ -88,6 +89,7 @@ public class TrainPacket extends SimplePacketBase { } CarriageBogey bogey = carriage.bogeys.get(first); buffer.writeResourceLocation(RegisteredObjects.getKeyOrThrow((Block) bogey.type)); + buffer.writeBoolean(bogey.upsideDown); buffer.writeNbt(bogey.bogeyData); } buffer.writeVarInt(carriage.bogeySpacing); diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/TrainRelocator.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/TrainRelocator.java index 149120c53..edde7903d 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/TrainRelocator.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/TrainRelocator.java @@ -115,10 +115,13 @@ public class TrainRelocator { BlockPos blockPos = blockhit.getBlockPos(); BezierTrackPointLocation hoveredBezier = null; + boolean upsideDown = relocating.carriages.get(0).leadingBogey().isUpsideDown(); + Vec3 offset = upsideDown ? new Vec3(0, -0.5, 0) : Vec3.ZERO; + if (simulate && toVisualise != null && lastHoveredResult != null) { for (int i = 0; i < toVisualise.size() - 1; i++) { - Vec3 vec1 = toVisualise.get(i); - Vec3 vec2 = toVisualise.get(i + 1); + Vec3 vec1 = toVisualise.get(i).add(offset); + Vec3 vec2 = toVisualise.get(i + 1).add(offset); CreateClient.OUTLINER.showLine(Pair.of(relocating, i), vec1.add(0, -.925f, 0), vec2.add(0, -.925f, 0)) .colored(lastHoveredResult || i != toVisualise.size() - 2 ? 0x95CD41 : 0xEA5C2B) .disableLineNormals() @@ -150,7 +153,7 @@ public class TrainRelocator { boolean direction = bezierSelection != null && lookAngle.dot(bezierSelection.direction()) < 0; boolean result = relocate(relocating, mc.level, blockPos, hoveredBezier, direction, lookAngle, true); if (!simulate && result) { - relocating.carriages.forEach(c -> c.forEachPresentEntity(e -> e.nonDamageTicks = 10)); + relocating.carriages.forEach(c -> c.forEachPresentEntity(e -> e.nonDamageTicks = 10)); AllPackets.channel.sendToServer(new TrainRelocationPacket(relocatingTrain, blockPos, hoveredBezier, direction, lookAngle, relocatingEntityId)); } @@ -182,7 +185,7 @@ public class TrainRelocator { if (edge == null) return false; - TravellingPoint probe = new TravellingPoint(node1, node2, edge, graphLocation.position); + TravellingPoint probe = new TravellingPoint(node1, node2, edge, graphLocation.position, false); IEdgePointListener ignoreSignals = probe.ignoreEdgePoints(); ITurnListener ignoreTurns = probe.ignoreTurns(); List, Double>> recordedLocations = new ArrayList<>(); diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/TravellingPoint.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/TravellingPoint.java index 194d926a6..827380139 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/TravellingPoint.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/TravellingPoint.java @@ -38,6 +38,7 @@ public class TravellingPoint { public TrackEdge edge; public double position; public boolean blocked; + public boolean upsideDown; public static enum SteerDirection { NONE(0), LEFT(-1), RIGHT(1); @@ -64,11 +65,12 @@ public class TravellingPoint { public TravellingPoint() {} - public TravellingPoint(TrackNode node1, TrackNode node2, TrackEdge edge, double position) { + public TravellingPoint(TrackNode node1, TrackNode node2, TrackEdge edge, double position, boolean upsideDown) { this.node1 = node1; this.node2 = node2; this.edge = edge; this.position = position; + this.upsideDown = upsideDown; } public IEdgePointListener ignoreEdgePoints() { @@ -395,14 +397,22 @@ public class TravellingPoint { } public Vec3 getPosition() { - return getPositionWithOffset(0); + return getPosition(false); + } + + public Vec3 getPosition(boolean flipped) { + return getPositionWithOffset(0, flipped); } public Vec3 getPositionWithOffset(double offset) { + return getPositionWithOffset(offset, false); + } + + public Vec3 getPositionWithOffset(double offset, boolean flipUpsideDown) { double t = (position + offset) / edge.getLength(); return edge.getPosition(t) - .add(edge.getNormal(node1, node2, t) - .scale(1)); + .add(edge.getNormal(node1, node2, t) + .scale(upsideDown^flipUpsideDown ? -1 : 1)); } public void migrateTo(List locations) { @@ -423,12 +433,13 @@ public class TravellingPoint { tag.put("Nodes", nodes.map(TrackNode::getLocation) .serializeEach(loc -> loc.write(dimensions))); tag.putDouble("Position", position); + tag.putBoolean("UpsideDown", upsideDown); return tag; } public static TravellingPoint read(CompoundTag tag, TrackGraph graph, DimensionPalette dimensions) { if (graph == null) - return new TravellingPoint(null, null, null, 0); + return new TravellingPoint(null, null, null, 0, false); Couple locs = tag.contains("Nodes") ? Couple.deserializeEach(tag.getList("Nodes", Tag.TAG_COMPOUND), c -> TrackNodeLocation.read(c, dimensions)) @@ -436,11 +447,11 @@ public class TravellingPoint { : Couple.create(null, null); if (locs.either(Objects::isNull)) - return new TravellingPoint(null, null, null, 0); + return new TravellingPoint(null, null, null, 0, false); double position = tag.getDouble("Position"); return new TravellingPoint(locs.getFirst(), locs.getSecond(), graph.getConnectionsFrom(locs.getFirst()) - .get(locs.getSecond()), position); + .get(locs.getSecond()), position, tag.getBoolean("UpsideDown")); } } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationTileEntity.java index a045a4216..34c69b8c2 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationTileEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationTileEntity.java @@ -38,7 +38,7 @@ import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePoi import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBehaviour; import com.simibubi.create.content.logistics.trains.management.schedule.Schedule; import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleItem; -import com.simibubi.create.content.logistics.trains.track.StandardBogeyTileEntity; +import com.simibubi.create.content.logistics.trains.track.AbstractBogeyTileEntity; import com.simibubi.create.foundation.advancement.AllAdvancements; import com.simibubi.create.foundation.block.ProperWaterloggedBlock; import com.simibubi.create.foundation.config.AllConfigs; @@ -67,7 +67,6 @@ import net.minecraft.util.Mth; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; import net.minecraft.world.level.block.SoundType; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; @@ -194,6 +193,7 @@ public class StationTileEntity extends SmartTileEntity implements ITransformable int assemblyLength; int[] bogeyLocations; AbstractBogeyBlock[] bogeyTypes; + boolean[] upsideDownBogeys; int bogeyCount; @Override @@ -270,28 +270,31 @@ public class StationTileEntity extends SmartTileEntity implements ITransformable return false; BlockPos up = new BlockPos(track.getUpNormal(level, pos, state)); + BlockPos down = new BlockPos(track.getUpNormal(level, pos, state).multiply(-1, -1, -1)); int bogeyOffset = pos.distManhattan(edgePoint.getGlobalPosition()) - 1; if (!isValidBogeyOffset(bogeyOffset)) { - for (int i = -1; i <= 1; i++) { - BlockPos bogeyPos = pos.relative(assemblyDirection, i) - .offset(up); - BlockState blockState = level.getBlockState(bogeyPos); - if (blockState.getBlock() instanceof AbstractBogeyBlock bogey) { - BlockEntity be = level.getBlockEntity(bogeyPos); - if (!(be instanceof StandardBogeyTileEntity oldTE)) - continue; - CompoundTag oldData = oldTE.getBogeyData(); - BlockState newBlock = bogey.getNextSize(oldTE); - if (newBlock.getBlock() == bogey) - player.displayClientMessage(Lang.translateDirect("create.bogey.style.no_other_sizes") - .withStyle(ChatFormatting.RED), true); - level.setBlock(bogeyPos, newBlock, 3); - BlockEntity newEntity = level.getBlockEntity(bogeyPos); - if (!(newEntity instanceof StandardBogeyTileEntity newTE)) - continue; - newTE.setBogeyData(oldData); - bogey.playRotateSound(level, bogeyPos); - return true; + for (boolean upsideDown : Iterate.falseAndTrue) { + for (int i = -1; i <= 1; i++) { + BlockPos bogeyPos = pos.relative(assemblyDirection, i) + .offset(upsideDown ? down : up); + BlockState blockState = level.getBlockState(bogeyPos); + if (blockState.getBlock() instanceof AbstractBogeyBlock bogey) { + BlockEntity be = level.getBlockEntity(bogeyPos); + if (!(be instanceof AbstractBogeyTileEntity oldTE)) + continue; + CompoundTag oldData = oldTE.getBogeyData(); + BlockState newBlock = bogey.getNextSize(oldTE); + if (newBlock.getBlock() == bogey) + player.displayClientMessage(Lang.translateDirect("create.bogey.style.no_other_sizes") + .withStyle(ChatFormatting.RED), true); + level.setBlock(bogeyPos, newBlock, 3); + BlockEntity newEntity = level.getBlockEntity(bogeyPos); + if (!(newEntity instanceof AbstractBogeyTileEntity newTE)) + continue; + newTE.setBogeyData(oldData); + bogey.playRotateSound(level, bogeyPos); + return true; + } } } @@ -304,7 +307,9 @@ public class StationTileEntity extends SmartTileEntity implements ITransformable return false; } - BlockPos targetPos = pos.offset(up); + boolean upsideDown = (player.getViewXRot(1.0F) < 0 && (track.getBogeyAnchor(level, pos, state)).getBlock() instanceof AbstractBogeyBlock bogey && bogey.canBeUpsideDown()); + + BlockPos targetPos = upsideDown ? pos.offset(down) : pos.offset(up); if (level.getBlockState(targetPos) .getDestroySpeed(level, targetPos) == -1) { return false; @@ -312,7 +317,11 @@ public class StationTileEntity extends SmartTileEntity implements ITransformable level.destroyBlock(targetPos, true); - BlockState bogeyAnchor = ProperWaterloggedBlock.withWater(level, track.getBogeyAnchor(level, pos, state), pos); + BlockState bogeyAnchor = track.getBogeyAnchor(level, pos, state); + if (bogeyAnchor.getBlock() instanceof AbstractBogeyBlock bogey) { + bogeyAnchor = bogey.getVersion(bogeyAnchor, upsideDown); + } + bogeyAnchor = ProperWaterloggedBlock.withWater(level, bogeyAnchor, pos); level.setBlock(targetPos, bogeyAnchor, 3); player.displayClientMessage(Lang.translateDirect("train_assembly.bogey_created"), true); SoundType soundtype = bogeyAnchor.getBlock() @@ -387,8 +396,11 @@ public class StationTileEntity extends SmartTileEntity implements ITransformable bogeyLocations = new int[maxBogeyCount]; if (bogeyTypes == null) bogeyTypes = new AbstractBogeyBlock[maxBogeyCount]; + if (upsideDownBogeys == null) + upsideDownBogeys = new boolean[maxBogeyCount]; Arrays.fill(bogeyLocations, -1); Arrays.fill(bogeyTypes, null); + Arrays.fill(upsideDownBogeys, false); for (int i = 0; i < MAX_LENGTH; i++) { if (i == MAX_LENGTH - 1) { @@ -401,10 +413,19 @@ public class StationTileEntity extends SmartTileEntity implements ITransformable } BlockState potentialBogeyState = level.getBlockState(bogeyOffset.offset(currentPos)); - if (potentialBogeyState.getBlock() instanceof AbstractBogeyBlock bogey && bogeyIndex < bogeyLocations.length) { - bogeyTypes[bogeyIndex] = bogey; - bogeyLocations[bogeyIndex] = i; - bogeyIndex++; + BlockPos upsideDownBogeyOffset = new BlockPos(bogeyOffset.getX(), bogeyOffset.getY()*-1, bogeyOffset.getZ()); + if (bogeyIndex < bogeyLocations.length) { + if (potentialBogeyState.getBlock() instanceof AbstractBogeyBlock bogey && !bogey.isUpsideDown(potentialBogeyState)) { + bogeyTypes[bogeyIndex] = bogey; + bogeyLocations[bogeyIndex] = i; + upsideDownBogeys[bogeyIndex] = false; + bogeyIndex++; + } else if ((potentialBogeyState = level.getBlockState(upsideDownBogeyOffset.offset(currentPos))).getBlock() instanceof AbstractBogeyBlock bogey && bogey.isUpsideDown(potentialBogeyState)) { + bogeyTypes[bogeyIndex] = bogey; + bogeyLocations[bogeyIndex] = i; + upsideDownBogeys[bogeyIndex] = true; + bogeyIndex++; + } } currentPos.move(assemblyDirection); @@ -564,7 +585,7 @@ public class StationTileEntity extends SmartTileEntity implements ITransformable return; } - points.add(new TravellingPoint(node, secondNode, edge, positionOnEdge)); + points.add(new TravellingPoint(node, secondNode, edge, positionOnEdge, false)); } secondNode = node; @@ -591,10 +612,11 @@ public class StationTileEntity extends SmartTileEntity implements ITransformable spacing.add(bogeyLocations[bogeyIndex] - bogeyLocations[bogeyIndex - 1]); CarriageContraption contraption = new CarriageContraption(assemblyDirection); BlockPos bogeyPosOffset = trackPosition.offset(bogeyOffset); + BlockPos upsideDownBogeyPosOffset = trackPosition.offset(new BlockPos(bogeyOffset.getX(), bogeyOffset.getY() * -1, bogeyOffset.getZ())); try { int offset = bogeyLocations[bogeyIndex] + 1; - boolean success = contraption.assemble(level, bogeyPosOffset.relative(assemblyDirection, offset)); + boolean success = contraption.assemble(level, upsideDownBogeys[bogeyIndex] ? upsideDownBogeyPosOffset.relative(assemblyDirection, offset) : bogeyPosOffset.relative(assemblyDirection, offset)); atLeastOneForwardControls |= contraption.hasForwardControls(); contraption.setSoundQueueOffset(offset); if (!success) { @@ -608,25 +630,29 @@ public class StationTileEntity extends SmartTileEntity implements ITransformable } AbstractBogeyBlock typeOfFirstBogey = bogeyTypes[bogeyIndex]; + boolean firstBogeyIsUpsideDown = upsideDownBogeys[bogeyIndex]; BlockPos firstBogeyPos = contraption.anchor; - StandardBogeyTileEntity firstBogeyTileEntity = (StandardBogeyTileEntity) level.getBlockEntity(firstBogeyPos); + AbstractBogeyTileEntity firstBogeyTileEntity = (AbstractBogeyTileEntity) level.getBlockEntity(firstBogeyPos); CarriageBogey firstBogey = - new CarriageBogey(typeOfFirstBogey, firstBogeyTileEntity.getBogeyData(), points.get(pointIndex), points.get(pointIndex + 1)); + new CarriageBogey(typeOfFirstBogey, firstBogeyIsUpsideDown, firstBogeyTileEntity.getBogeyData(), points.get(pointIndex), points.get(pointIndex + 1)); CarriageBogey secondBogey = null; BlockPos secondBogeyPos = contraption.getSecondBogeyPos(); + /*if (secondBogeyPos != null && (bogeyIndex + 1 < upsideDownBogeys.length && upsideDownBogeys[bogeyIndex + 1])) { + secondBogeyPos = secondBogeyPos.above(2); + }*/ int bogeySpacing = 0; if (secondBogeyPos != null) { if (bogeyIndex == bogeyCount - 1 || !secondBogeyPos - .equals(bogeyPosOffset.relative(assemblyDirection, bogeyLocations[bogeyIndex + 1] + 1))) { + .equals((upsideDownBogeys[bogeyIndex + 1] ? upsideDownBogeyPosOffset : bogeyPosOffset).relative(assemblyDirection, bogeyLocations[bogeyIndex + 1] + 1))) { exception(new AssemblyException(Lang.translateDirect("train_assembly.not_connected_in_order")), contraptions.size() + 1); return; } - StandardBogeyTileEntity secondBogeyTileEntity = - (StandardBogeyTileEntity) level.getBlockEntity(secondBogeyPos); + AbstractBogeyTileEntity secondBogeyTileEntity = + (AbstractBogeyTileEntity) level.getBlockEntity(secondBogeyPos); bogeySpacing = bogeyLocations[bogeyIndex + 1] - bogeyLocations[bogeyIndex]; - secondBogey = new CarriageBogey(bogeyTypes[bogeyIndex + 1], secondBogeyTileEntity.getBogeyData(), + secondBogey = new CarriageBogey(bogeyTypes[bogeyIndex + 1], upsideDownBogeys[bogeyIndex + 1], secondBogeyTileEntity.getBogeyData(), points.get(pointIndex + 2), points.get(pointIndex + 3)); bogeyIndex++; diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/track/AbstractBogeyTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/trains/track/AbstractBogeyTileEntity.java new file mode 100644 index 000000000..f3b752b52 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/trains/track/AbstractBogeyTileEntity.java @@ -0,0 +1,114 @@ +package com.simibubi.create.content.logistics.trains.track; + +import com.simibubi.create.AllBogeyStyles; +import com.simibubi.create.content.logistics.trains.AbstractBogeyBlock; +import com.simibubi.create.content.logistics.trains.entity.BogeyStyle; +import com.simibubi.create.foundation.tileEntity.CachedRenderBBTileEntity; +import com.simibubi.create.foundation.utility.NBTHelper; +import com.simibubi.create.foundation.utility.animation.LerpedFloat; + +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.AABB; +; +import org.jetbrains.annotations.NotNull; + +public abstract class AbstractBogeyTileEntity extends CachedRenderBBTileEntity { + public static String BOGEY_STYLE_KEY = "BogeyStyle"; + public static String BOGEY_DATA_KEY = "BogeyData"; + + private CompoundTag bogeyData; + + public AbstractBogeyTileEntity(BlockEntityType type, BlockPos pos, BlockState state) { + super(type, pos, state); + } + + public abstract BogeyStyle getDefaultStyle(); + + public CompoundTag getBogeyData() { + if (this.bogeyData == null || !this.bogeyData.contains(BOGEY_STYLE_KEY)) + this.bogeyData = this.createBogeyData(); + return this.bogeyData; + } + + public void setBogeyData(@NotNull CompoundTag newData) { + if (!newData.contains(BOGEY_STYLE_KEY)) { + ResourceLocation style = getDefaultStyle().name; + NBTHelper.writeResourceLocation(newData, BOGEY_STYLE_KEY, style); + } + this.bogeyData = newData; + } + + public void setBogeyStyle(@NotNull BogeyStyle style) { + ResourceLocation location = style.name; + CompoundTag data = this.getBogeyData(); + NBTHelper.writeResourceLocation(data, BOGEY_STYLE_KEY, location); + markUpdated(); + } + + @NotNull + public BogeyStyle getStyle() { + CompoundTag data = this.getBogeyData(); + ResourceLocation currentStyle = NBTHelper.readResourceLocation(data, BOGEY_STYLE_KEY); + BogeyStyle style = AllBogeyStyles.BOGEY_STYLES.get(currentStyle); + if (style == null) { + setBogeyStyle(getDefaultStyle()); + return getStyle(); + } + return style; + } + + @Override + protected void saveAdditional(@NotNull CompoundTag pTag) { + CompoundTag data = this.getBogeyData(); + if (data != null) pTag.put(BOGEY_DATA_KEY, data); // Now contains style + super.saveAdditional(pTag); + } + + @Override + public void load(CompoundTag pTag) { + if (pTag.contains(BOGEY_DATA_KEY)) + this.bogeyData = pTag.getCompound(BOGEY_DATA_KEY); + else + this.bogeyData = this.createBogeyData(); + super.load(pTag); + } + + private CompoundTag createBogeyData() { + CompoundTag nbt = new CompoundTag(); + NBTHelper.writeResourceLocation(nbt, BOGEY_STYLE_KEY, getDefaultStyle().name); + return nbt; + } + + @Override + protected AABB createRenderBoundingBox() { + return super.createRenderBoundingBox().inflate(2); + } + + // Ponder + LerpedFloat virtualAnimation = LerpedFloat.angular(); + + public float getVirtualAngle(float partialTicks) { + return virtualAnimation.getValue(partialTicks); + } + + public void animate(float distanceMoved) { + BlockState blockState = getBlockState(); + if (!(blockState.getBlock() instanceof AbstractBogeyBlock type)) + return; + double angleDiff = 360 * distanceMoved / (Math.PI * 2 * type.getWheelRadius()); + double newWheelAngle = (virtualAnimation.getValue() - angleDiff) % 360; + virtualAnimation.setValue(newWheelAngle); + } + + private void markUpdated() { + setChanged(); + Level level = getLevel(); + if (level != null) + getLevel().sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3); + } +} diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/track/StandardBogeyBlock.java b/src/main/java/com/simibubi/create/content/logistics/trains/track/StandardBogeyBlock.java index f569f093d..fcfcf6188 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/track/StandardBogeyBlock.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/track/StandardBogeyBlock.java @@ -1,10 +1,11 @@ package com.simibubi.create.content.logistics.trains.track; import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllBogeyStyles; import com.simibubi.create.AllTileEntities; -import com.simibubi.create.content.logistics.trains.BogeyRenderer; import com.simibubi.create.content.logistics.trains.AbstractBogeyBlock; import com.simibubi.create.content.logistics.trains.BogeySizes; +import com.simibubi.create.content.logistics.trains.entity.BogeyStyle; import com.simibubi.create.content.schematics.ISpecialBlockItemRequirement; import com.simibubi.create.foundation.block.ITE; import com.simibubi.create.foundation.block.ProperWaterloggedBlock; @@ -18,7 +19,7 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; -public class StandardBogeyBlock extends AbstractBogeyBlock implements ITE, ProperWaterloggedBlock, ISpecialBlockItemRequirement { +public class StandardBogeyBlock extends AbstractBogeyBlock implements ITE, ProperWaterloggedBlock, ISpecialBlockItemRequirement { public StandardBogeyBlock(Properties props, BogeySizes.BogeySize size) { super(props, size); @@ -40,6 +41,11 @@ public class StandardBogeyBlock extends AbstractBogeyBlock implements ITE type, BlockPos pos, BlockState state) { super(type, pos, state); } - public CompoundTag getBogeyData() { - if (this.bogeyData == null || !this.bogeyData.contains(BOGEY_STYLE_KEY)) - this.bogeyData = this.createBogeyData(); - return this.bogeyData; - } - - public void setBogeyData(@NotNull CompoundTag newData) { - if (!newData.contains(BOGEY_STYLE_KEY)) { - ResourceLocation style = AllBogeyStyles.STANDARD.name; - NBTHelper.writeResourceLocation(newData, BOGEY_STYLE_KEY, style); - } - this.bogeyData = newData; - } - - public void setBogeyStyle(@NotNull BogeyStyle style) { - ResourceLocation location = style.name; - CompoundTag data = this.getBogeyData(); - NBTHelper.writeResourceLocation(data, BOGEY_STYLE_KEY, location); - markUpdated(); - } - - @NotNull - public BogeyStyle getStyle() { - CompoundTag data = this.getBogeyData(); - ResourceLocation currentStyle = NBTHelper.readResourceLocation(data, BOGEY_STYLE_KEY); - BogeyStyle style = AllBogeyStyles.BOGEY_STYLES.get(currentStyle); - if (style == null) { - setBogeyStyle(AllBogeyStyles.STANDARD); - return getStyle(); - } - return style; - } - @Override - protected void saveAdditional(@NotNull CompoundTag pTag) { - CompoundTag data = this.getBogeyData(); - if (data != null) pTag.put(BOGEY_DATA_KEY, data); // Now contains style - super.saveAdditional(pTag); - } - - @Override - public void load(CompoundTag pTag) { - if (pTag.contains(BOGEY_DATA_KEY)) - this.bogeyData = pTag.getCompound(BOGEY_DATA_KEY); - else - this.bogeyData = this.createBogeyData(); - super.load(pTag); - } - - private CompoundTag createBogeyData() { - CompoundTag nbt = new CompoundTag(); - NBTHelper.writeResourceLocation(nbt, BOGEY_STYLE_KEY, AllBogeyStyles.STANDARD.name); - return nbt; - } - - @Override - protected AABB createRenderBoundingBox() { - return super.createRenderBoundingBox().inflate(2); - } - - // Ponder - LerpedFloat virtualAnimation = LerpedFloat.angular(); - - public float getVirtualAngle(float partialTicks) { - return virtualAnimation.getValue(partialTicks); - } - - public void animate(float distanceMoved) { - BlockState blockState = getBlockState(); - if (!(blockState.getBlock() instanceof AbstractBogeyBlock type)) - return; - double angleDiff = 360 * distanceMoved / (Math.PI * 2 * type.getWheelRadius()); - double newWheelAngle = (virtualAnimation.getValue() - angleDiff) % 360; - virtualAnimation.setValue(newWheelAngle); - } - - private void markUpdated() { - setChanged(); - Level level = getLevel(); - if (level != null) - getLevel().sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3); + public BogeyStyle getDefaultStyle() { + return AllBogeyStyles.STANDARD; } } diff --git a/src/main/java/com/simibubi/create/foundation/command/AllCommands.java b/src/main/java/com/simibubi/create/foundation/command/AllCommands.java index 8664b0a5e..b351acb8b 100644 --- a/src/main/java/com/simibubi/create/foundation/command/AllCommands.java +++ b/src/main/java/com/simibubi/create/foundation/command/AllCommands.java @@ -60,6 +60,7 @@ public class AllCommands { .then(CameraDistanceCommand.register()) .then(CameraAngleCommand.register()) .then(FlySpeedCommand.register()) + .then(DebugValueCommand.register()) //.then(KillTPSCommand.register()) .build(); diff --git a/src/main/java/com/simibubi/create/foundation/command/DebugValueCommand.java b/src/main/java/com/simibubi/create/foundation/command/DebugValueCommand.java new file mode 100644 index 000000000..3571c132d --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/command/DebugValueCommand.java @@ -0,0 +1,78 @@ +package com.simibubi.create.foundation.command; + +import com.mojang.brigadier.arguments.FloatArgumentType; + +import com.simibubi.create.Create; + +import net.minecraft.SharedConstants; + +import org.apache.commons.lang3.mutable.MutableInt; + +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.builder.ArgumentBuilder; +import com.simibubi.create.foundation.utility.Components; + +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; +import net.minecraft.commands.arguments.coordinates.BlockPosArgument; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.BaseCommandBlock; +import net.minecraft.world.level.block.CommandBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.CommandBlockEntity; +import net.minecraft.world.level.block.state.BlockState; + +public class DebugValueCommand { + + public static float value = 0; + + public static ArgumentBuilder register() { + return Commands.literal("debugValue") + .requires(cs -> cs.hasPermission(4)) + .then(Commands.argument("value", FloatArgumentType.floatArg()) + .executes((ctx) -> { + value = FloatArgumentType.getFloat(ctx, "value"); + ctx.getSource().sendSuccess(Components.literal("Set value to: "+value), true); + return 1; + })); + + } + + // same side - other side + // n(ormal)-n(ormal) + // u(pside down)-u(pside down) what about un ? not tested yet un doesn't work with + 1 or -1. HALP + // 1 works for: nn n nu + //-1 works for: uu u + public static double tmpPortalOffset(boolean leadingUpsideDown, boolean trailingUpsideDown, boolean isLeading) { + double portalOffset = 0.0; + if (!leadingUpsideDown && !trailingUpsideDown) { // nn + return 1.0; + } else if (leadingUpsideDown && trailingUpsideDown) { // uu + return -1.0; + } else if (leadingUpsideDown && !trailingUpsideDown) { // un + if (isLeading) { + return 0.1; + } else { + return 0.2; + } + } else if (!leadingUpsideDown && trailingUpsideDown) { // nu + if (isLeading) { + return 1.0; + } else { + return 1.0; + } + } + Create.LOGGER.error("Theoretically unreachable code just got reached. HALP me please"); + return 0.0; // this is actually unreachable but yay + /*if (!leadingUpsideDown) { // leading up + portalOffset = 1.0; + } else if (trailingUpsideDown) { // leading down, trailing down + portalOffset = -1.0; + } else { // leading down, trailing up - ahh + portalOffset = DebugValueCommand.value; + } + return portalOffset;*/ + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instruction/AnimateTileEntityInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instruction/AnimateTileEntityInstruction.java index cd65b8a36..b11242d80 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/instruction/AnimateTileEntityInstruction.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/instruction/AnimateTileEntityInstruction.java @@ -7,7 +7,7 @@ import java.util.function.Function; import com.simibubi.create.content.contraptions.components.deployer.DeployerTileEntity; import com.simibubi.create.content.contraptions.components.structureMovement.bearing.IBearingTileEntity; import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyTileEntity; -import com.simibubi.create.content.logistics.trains.track.StandardBogeyTileEntity; +import com.simibubi.create.content.logistics.trains.track.AbstractBogeyTileEntity; import com.simibubi.create.foundation.ponder.PonderScene; import com.simibubi.create.foundation.ponder.PonderWorld; @@ -34,7 +34,7 @@ public class AnimateTileEntityInstruction extends TickingInstruction { public static AnimateTileEntityInstruction bogey(BlockPos location, float totalDelta, int ticks) { float movedPerTick = totalDelta / ticks; return new AnimateTileEntityInstruction(location, totalDelta, ticks, - (w, f) -> castIfPresent(w, location, StandardBogeyTileEntity.class) + (w, f) -> castIfPresent(w, location, AbstractBogeyTileEntity.class) .ifPresent(bte -> bte.animate(f.equals(totalDelta) ? 0 : movedPerTick)), (w) -> 0f); }