working on upside down bogeys in nether portals

This commit is contained in:
techno-sam 2023-05-04 09:32:53 -07:00
parent 2f285b6eb7
commit da26c0ccbf
29 changed files with 483 additions and 241 deletions

3
.gitignore vendored
View file

@ -42,4 +42,5 @@ local.properties
# PDT-specific
.buildpath
.DS_Store
.DS_Store
/libs/

View file

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

View file

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

View file

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

View file

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

View file

@ -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<StandardBogeyTileEntity>, ProperWaterloggedBlock, ISpecialBlockItemRequirement, IWrenchable {
public abstract class AbstractBogeyBlock<T extends AbstractBogeyTileEntity> extends Block implements ITE<T>, ProperWaterloggedBlock, ISpecialBlockItemRequirement, IWrenchable {
public static final EnumProperty<Direction.Axis> AXIS = BlockStateProperties.HORIZONTAL_AXIS;
static final List<ResourceLocation> BOGEYS = new ArrayList<>();
public BogeySizes.BogeySize size;
@ -100,16 +100,37 @@ public abstract class AbstractBogeyBlock extends Block implements ITE<StandardBo
public abstract double getWheelRadius();
public abstract Vec3 getConnectorAnchorOffset();
public Vec3 getConnectorAnchorOffset(boolean upsideDown) {
return getConnectorAnchorOffset();
}
/**
* This should be implemented, but not called directly
*/
protected abstract Vec3 getConnectorAnchorOffset();
public boolean allowsSingleBogeyCarriage() {
return true;
}
public abstract BogeyStyle getDefaultStyle();
/**
* Legacy system doesn't capture bogey tile entities when constructing a train
*/
public boolean captureTileEntityForTrain() {
return false;
}
@OnlyIn(Dist.CLIENT)
public void render(@Nullable BlockState state, float wheelAngle, PoseStack ms, float partialTicks,
MultiBufferSource buffers, int light, int overlay, StandardBogeyTileEntity sbte) {
BogeyStyle style = sbte.getStyle();
public void render(@Nullable BlockState state, boolean upsideDown, float wheelAngle, PoseStack ms, float partialTicks,
MultiBufferSource buffers, int light, int overlay, AbstractBogeyTileEntity sbte) {
BogeyStyle style;
if (sbte != null) { // on trains, sbte can be null.
style = sbte.getStyle();
} else {
style = getDefaultStyle();
}
final Optional<BogeyRenderer.CommonRenderer> commonRenderer
= style.getNewCommonRenderInstance();
final BogeyRenderer renderer = style.getInWorldRenderInstance(this.getSize());
@ -120,9 +141,10 @@ public abstract class AbstractBogeyBlock extends Block implements ITE<StandardBo
}
ms.translate(0, -1.5 - 1 / 128f, 0);
VertexConsumer vb = buffers.getBuffer(RenderType.cutoutMipped());
renderer.render(sbte.getBogeyData(), wheelAngle, ms, light, vb);
CompoundTag bogeyData = sbte != null ? sbte.getBogeyData() : new CompoundTag();
renderer.render(upsideDown, bogeyData, wheelAngle, ms, light, vb, state == null);
commonRenderer.ifPresent(common ->
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<StandardBo
BlockEntity be = level.getBlockEntity(pos);
if (!(be instanceof StandardBogeyTileEntity sbte))
if (!(be instanceof AbstractBogeyTileEntity sbte))
return InteractionResult.FAIL;
player.getCooldowns().addCooldown(stack.getItem(), 20);
@ -187,7 +209,7 @@ public abstract class AbstractBogeyBlock extends Block implements ITE<StandardBo
CompoundTag oldData = sbte.getBogeyData();
level.setBlock(pos, this.getStateOfSize(sbte, size), 3);
BlockEntity newBlockEntity = level.getBlockEntity(pos);
if (!(newBlockEntity instanceof StandardBogeyTileEntity newTileEntity))
if (!(newBlockEntity instanceof AbstractBogeyTileEntity newTileEntity))
return InteractionResult.FAIL;
newTileEntity.setBogeyData(oldData);
player.displayClientMessage(Lang.translateDirect("create.bogey.style.updated_style_and_size")
@ -229,12 +251,12 @@ public abstract class AbstractBogeyBlock extends Block implements ITE<StandardBo
public BlockState getNextSize(Level level, BlockPos pos) {
BlockEntity te = level.getBlockEntity(pos);
if (te instanceof StandardBogeyTileEntity sbte)
if (te instanceof AbstractBogeyTileEntity sbte)
return this.getNextSize(sbte);
return level.getBlockState(pos);
}
public BlockState getNextSize(StandardBogeyTileEntity sbte) {
public BlockState getNextSize(AbstractBogeyTileEntity sbte) {
BogeySizes.BogeySize size = this.getSize();
BogeyStyle style = sbte.getStyle();
BlockState nextBlock = style.getNextBlock(size).defaultBlockState();
@ -243,7 +265,7 @@ public abstract class AbstractBogeyBlock extends Block implements ITE<StandardBo
: nextBlock;
}
public BlockState getStateOfSize(StandardBogeyTileEntity sbte, BogeySizes.BogeySize size) {
public BlockState getStateOfSize(AbstractBogeyTileEntity sbte, BogeySizes.BogeySize size) {
BogeyStyle style = sbte.getStyle();
BlockState state = style.getBlockOfSize(size).defaultBlockState();
return state.hasProperty(WATERLOGGED)
@ -253,9 +275,9 @@ public abstract class AbstractBogeyBlock extends Block implements ITE<StandardBo
public BogeyStyle getNextStyle(Level level, BlockPos pos) {
BlockEntity te = level.getBlockEntity(pos);
if (te instanceof StandardBogeyTileEntity sbte)
if (te instanceof AbstractBogeyTileEntity sbte)
return this.getNextStyle(sbte.getStyle());
return AllBogeyStyles.STANDARD;
return getDefaultStyle();
}
public BogeyStyle getNextStyle(BogeyStyle style) {
@ -279,4 +301,16 @@ public abstract class AbstractBogeyBlock extends Block implements ITE<StandardBo
public ItemRequirement getRequiredItems(BlockState state, BlockEntity te) {
return new ItemRequirement(ItemRequirement.ItemUseType.CONSUME, AllBlocks.RAILWAY_CASING.asStack());
}
public boolean canBeUpsideDown() {
return false;
}
public boolean isUpsideDown(BlockState state) {
return false;
}
public BlockState getVersion(BlockState base, boolean upsideDown) {
return base;
}
}

View file

@ -37,12 +37,12 @@ public abstract class BogeyRenderer {
*
* @param model The key for the model data to instantiate or retrieve
* @param ms The posestack used for contraption model data
* @param inContraption The type of model needed
* @param inInstancedContraption The type of model needed
* @param size The amount of models needed
* @return A generic transform which can be used for both in-world and in-contraption models
*/
public Transform<?>[] 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);
}

View file

@ -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<BogeySize> getAllSizesSmallToLarge() {

View file

@ -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<T extends BlockEntity> 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);
}
}

View file

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

View file

@ -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) {
}

View file

@ -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) {

View file

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

View file

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

View file

@ -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)

View file

@ -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) {

View file

@ -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++) {

View file

@ -88,7 +88,13 @@ public class CarriageSounds {
double distance2 = toBogey2.length();
Couple<CarriageBogey> 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);

View file

@ -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<UUID, SignalEdgeGroup> allGroups = Create.RAILWAYS.signalEdgeGroups;
MutableObject<UUID> prevGroup = new MutableObject<>(null);

View file

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

View file

@ -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<Pair<Couple<TrackNode>, Double>> recordedLocations = new ArrayList<>();

View file

@ -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<GraphLocation> 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<TrackNode> 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"));
}
}

View file

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

View file

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

View file

@ -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<StandardBogeyTileEntity>, ProperWaterloggedBlock, ISpecialBlockItemRequirement {
public class StandardBogeyBlock extends AbstractBogeyBlock<StandardBogeyTileEntity> implements ITE<StandardBogeyTileEntity>, ProperWaterloggedBlock, ISpecialBlockItemRequirement {
public StandardBogeyBlock(Properties props, BogeySizes.BogeySize size) {
super(props, size);
@ -40,6 +41,11 @@ public class StandardBogeyBlock extends AbstractBogeyBlock implements ITE<Standa
return new Vec3(0, 7 / 32f, 1);
}
@Override
public BogeyStyle getDefaultStyle() {
return AllBogeyStyles.STANDARD;
}
@Override
public ItemStack getCloneItemStack(BlockState state, HitResult target, BlockGetter level, BlockPos pos,
Player player) {

View file

@ -1,112 +1,19 @@
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 class StandardBogeyTileEntity extends CachedRenderBBTileEntity {
public static String BOGEY_STYLE_KEY = "BogeyStyle";
public static String BOGEY_DATA_KEY = "BogeyData";
private CompoundTag bogeyData;
public class StandardBogeyTileEntity extends AbstractBogeyTileEntity {
public StandardBogeyTileEntity(BlockEntityType<?> 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;
}
}

View file

@ -60,6 +60,7 @@ public class AllCommands {
.then(CameraDistanceCommand.register())
.then(CameraAngleCommand.register())
.then(FlySpeedCommand.register())
.then(DebugValueCommand.register())
//.then(KillTPSCommand.register())
.build();

View file

@ -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<CommandSourceStack, ?> 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;*/
}
}

View file

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