mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-05 03:32:36 +01:00
commit
206de01311
30 changed files with 1323 additions and 546 deletions
|
@ -207,6 +207,8 @@ import com.simibubi.create.content.logistics.block.vault.ItemVaultBlock;
|
|||
import com.simibubi.create.content.logistics.block.vault.ItemVaultCTBehaviour;
|
||||
import com.simibubi.create.content.logistics.block.vault.ItemVaultItem;
|
||||
import com.simibubi.create.content.logistics.item.LecternControllerBlock;
|
||||
import com.simibubi.create.content.logistics.trains.BogeyRenderer;
|
||||
import com.simibubi.create.content.logistics.trains.BogeySizes;
|
||||
import com.simibubi.create.content.logistics.trains.TrackMaterial;
|
||||
import com.simibubi.create.content.logistics.trains.management.display.FlapDisplayBlock;
|
||||
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType;
|
||||
|
@ -668,7 +670,7 @@ public class AllBlocks {
|
|||
.onRegister(movementBehaviour(new BlazeBurnerMovementBehaviour()))
|
||||
.onRegister(interactionBehaviour(new BlazeBurnerInteractionBehaviour()))
|
||||
.item(BlazeBurnerBlockItem::withBlaze)
|
||||
.model(AssetLookup.<BlazeBurnerBlockItem>customBlockItemModel("blaze_burner", "block_with_blaze"))
|
||||
.model(AssetLookup.customBlockItemModel("blaze_burner", "block_with_blaze"))
|
||||
.build()
|
||||
.register();
|
||||
|
||||
|
@ -927,7 +929,7 @@ public class AllBlocks {
|
|||
.onRegister(assignDataBehaviour(new BoilerDisplaySource(), "boiler_status"))
|
||||
.addLayer(() -> RenderType::cutoutMipped)
|
||||
.item(FluidTankItem::new)
|
||||
.model(AssetLookup.<FluidTankItem>customBlockItemModel("_", "block_single_window"))
|
||||
.model(AssetLookup.customBlockItemModel("_", "block_single_window"))
|
||||
.build()
|
||||
.register();
|
||||
|
||||
|
@ -1581,13 +1583,13 @@ public class AllBlocks {
|
|||
.register();
|
||||
|
||||
public static final BlockEntry<StandardBogeyBlock> SMALL_BOGEY =
|
||||
REGISTRATE.block("small_bogey", p -> new StandardBogeyBlock(p, false))
|
||||
REGISTRATE.block("small_bogey", p -> new StandardBogeyBlock(p, BogeySizes.SMALL))
|
||||
.properties(p -> p.color(MaterialColor.PODZOL))
|
||||
.transform(BuilderTransformers.bogey())
|
||||
.register();
|
||||
|
||||
public static final BlockEntry<StandardBogeyBlock> LARGE_BOGEY =
|
||||
REGISTRATE.block("large_bogey", p -> new StandardBogeyBlock(p, true))
|
||||
REGISTRATE.block("large_bogey", p -> new StandardBogeyBlock(p, BogeySizes.LARGE))
|
||||
.properties(p -> p.color(MaterialColor.PODZOL))
|
||||
.transform(BuilderTransformers.bogey())
|
||||
.register();
|
||||
|
|
114
src/main/java/com/simibubi/create/AllBogeyStyles.java
Normal file
114
src/main/java/com/simibubi/create/AllBogeyStyles.java
Normal file
|
@ -0,0 +1,114 @@
|
|||
package com.simibubi.create;
|
||||
|
||||
import com.simibubi.create.content.logistics.trains.AbstractBogeyBlock;
|
||||
import com.simibubi.create.content.logistics.trains.BogeyRenderer;
|
||||
import com.simibubi.create.content.logistics.trains.BogeyRenderer.CommonRenderer;
|
||||
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.Lang;
|
||||
|
||||
import com.tterrag.registrate.util.entry.BlockEntry;
|
||||
|
||||
import net.minecraft.core.particles.ParticleOptions;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.TranslatableComponent;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static com.simibubi.create.Create.LOGGER;
|
||||
|
||||
public class AllBogeyStyles {
|
||||
public static final Map<ResourceLocation, BogeyStyle> BOGEY_STYLES = new HashMap<>();
|
||||
|
||||
public static BogeyStyle STANDARD = create("standard")
|
||||
.commonRenderer(CommonStandardBogeyRenderer::new)
|
||||
.displayName(new TranslatableComponent("create.bogeys.styles.standard"))
|
||||
.size(BogeySizes.SMALL, SmallStandardBogeyRenderer::new, AllBlocks.SMALL_BOGEY)
|
||||
.size(BogeySizes.LARGE, LargeStandardBogeyRenderer::new, AllBlocks.LARGE_BOGEY)
|
||||
.build();
|
||||
|
||||
public static BogeyStyleBuilder create(String name) {
|
||||
return create(Create.asResource(name));
|
||||
}
|
||||
|
||||
public static BogeyStyleBuilder create(ResourceLocation name) {
|
||||
return new BogeyStyleBuilder(name);
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
LOGGER.info("Registered bogey styles from " + Create.ID);
|
||||
}
|
||||
|
||||
public static class BogeyStyleBuilder {
|
||||
protected final Map<BogeySizes.BogeySize, BogeyStyle.SizeData> sizes = new HashMap<>();
|
||||
protected final ResourceLocation name;
|
||||
|
||||
protected Component displayName = Lang.translateDirect("create.bogeys.invalid");
|
||||
protected ResourceLocation soundType = AllSoundEvents.TRAIN2.getId();
|
||||
protected CompoundTag defaultData = new CompoundTag();
|
||||
protected ParticleOptions contactParticle = ParticleTypes.CRIT;
|
||||
protected ParticleOptions smokeParticle = ParticleTypes.POOF;
|
||||
protected Optional<CommonRenderer> commonRenderer = Optional.empty();
|
||||
|
||||
public BogeyStyleBuilder(ResourceLocation name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public BogeyStyleBuilder displayName(Component displayName) {
|
||||
this.displayName = displayName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BogeyStyleBuilder soundType(ResourceLocation soundType) {
|
||||
this.soundType = soundType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BogeyStyleBuilder defaultData(CompoundTag defaultData) {
|
||||
this.defaultData = defaultData;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BogeyStyleBuilder size(BogeySizes.BogeySize size, Supplier<? extends BogeyRenderer> renderer,
|
||||
BlockEntry<? extends AbstractBogeyBlock> blockEntry) {
|
||||
this.size(size, renderer, blockEntry.getId());
|
||||
return this;
|
||||
}
|
||||
|
||||
public BogeyStyleBuilder size(BogeySizes.BogeySize size, Supplier<? extends BogeyRenderer> renderer,
|
||||
ResourceLocation location) {
|
||||
this.sizes.put(size, new BogeyStyle.SizeData(location, renderer.get()));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BogeyStyleBuilder contactParticle(ParticleOptions contactParticle) {
|
||||
this.contactParticle = contactParticle;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BogeyStyleBuilder smokeParticle(ParticleOptions smokeParticle) {
|
||||
this.smokeParticle = smokeParticle;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BogeyStyleBuilder commonRenderer(Supplier<? extends CommonRenderer> commonRenderer) {
|
||||
this.commonRenderer = Optional.of(commonRenderer.get());
|
||||
return this;
|
||||
}
|
||||
|
||||
public BogeyStyle build() {
|
||||
BogeyStyle entry =
|
||||
new BogeyStyle(name, displayName, soundType, contactParticle, smokeParticle, defaultData, sizes, commonRenderer);
|
||||
BOGEY_STYLES.put(name, entry);
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,8 @@ package com.simibubi.create;
|
|||
|
||||
import java.util.Random;
|
||||
|
||||
import com.simibubi.create.content.logistics.trains.BogeySizes;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
@ -121,6 +123,8 @@ public class Create {
|
|||
AllFeatures.register(modEventBus);
|
||||
AllPlacementModifiers.register(modEventBus);
|
||||
BuiltinRegistration.register(modEventBus);
|
||||
BogeySizes.init();
|
||||
AllBogeyStyles.register();
|
||||
|
||||
AllConfigs.register(modLoadingContext);
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ import com.simibubi.create.content.contraptions.fluids.tank.FluidTankBlock;
|
|||
import com.simibubi.create.content.curiosities.deco.SlidingDoorBlock;
|
||||
import com.simibubi.create.content.logistics.block.redstone.RedstoneLinkBlock;
|
||||
import com.simibubi.create.content.logistics.block.vault.ItemVaultBlock;
|
||||
import com.simibubi.create.content.logistics.trains.IBogeyBlock;
|
||||
import com.simibubi.create.content.logistics.trains.AbstractBogeyBlock;
|
||||
import com.simibubi.create.content.logistics.trains.ITrackBlock;
|
||||
import com.simibubi.create.content.logistics.trains.management.edgePoint.station.StationBlock;
|
||||
import com.simibubi.create.foundation.config.ContraptionMovementSetting;
|
||||
|
@ -337,7 +337,7 @@ public class BlockMovementChecks {
|
|||
return direction == state.getValue(StickerBlock.FACING)
|
||||
&& !isNotSupportive(world.getBlockState(pos.relative(direction)), direction.getOpposite());
|
||||
}
|
||||
if (block instanceof IBogeyBlock bogey)
|
||||
if (block instanceof AbstractBogeyBlock bogey)
|
||||
return bogey.getStickySurfaces(world, pos, state)
|
||||
.contains(direction);
|
||||
if (block instanceof WhistleBlock)
|
||||
|
|
|
@ -63,7 +63,7 @@ import com.simibubi.create.content.curiosities.deco.SlidingDoorBlock;
|
|||
import com.simibubi.create.content.logistics.block.inventories.CreativeCrateTileEntity;
|
||||
import com.simibubi.create.content.logistics.block.redstone.RedstoneContactBlock;
|
||||
import com.simibubi.create.content.logistics.block.vault.ItemVaultTileEntity;
|
||||
import com.simibubi.create.content.logistics.trains.IBogeyBlock;
|
||||
import com.simibubi.create.content.logistics.trains.AbstractBogeyBlock;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.tileEntity.IMultiTileContainer;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
|
||||
|
@ -342,7 +342,7 @@ public abstract class Contraption {
|
|||
}
|
||||
|
||||
// Bogeys tend to have sticky sides
|
||||
if (state.getBlock()instanceof IBogeyBlock 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));
|
||||
|
@ -1006,7 +1006,7 @@ public abstract class Contraption {
|
|||
if (disassembled)
|
||||
return;
|
||||
disassembled = true;
|
||||
|
||||
|
||||
for (boolean nonBrittles : Iterate.trueAndFalse) {
|
||||
for (StructureBlockInfo block : blocks.values()) {
|
||||
if (nonBrittles == BlockMovementChecks.isBrittle(block.state))
|
||||
|
|
|
@ -0,0 +1,282 @@
|
|||
package com.simibubi.create.content.logistics.trains;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import com.mojang.math.Vector3f;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
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.schematics.ISpecialBlockItemRequirement;
|
||||
import com.simibubi.create.content.schematics.ItemRequirement;
|
||||
import com.simibubi.create.foundation.block.ITE;
|
||||
import com.simibubi.create.foundation.block.ProperWaterloggedBlock;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.foundation.utility.RegisteredObjects;
|
||||
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Rotation;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.block.state.properties.EnumProperty;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class AbstractBogeyBlock extends Block implements ITE<StandardBogeyTileEntity>, ProperWaterloggedBlock, ISpecialBlockItemRequirement, IWrenchable {
|
||||
public static final EnumProperty<Direction.Axis> AXIS = BlockStateProperties.HORIZONTAL_AXIS;
|
||||
static final List<ResourceLocation> BOGEYS = new ArrayList<>();
|
||||
public BogeySizes.BogeySize size;
|
||||
|
||||
|
||||
public AbstractBogeyBlock(Properties pProperties, BogeySizes.BogeySize size) {
|
||||
super(pProperties);
|
||||
registerDefaultState(defaultBlockState().setValue(WATERLOGGED, false));
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public static void register(ResourceLocation block) {
|
||||
BOGEYS.add(block);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
||||
builder.add(AXIS, WATERLOGGED);
|
||||
super.createBlockStateDefinition(builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState updateShape(BlockState pState, Direction pDirection, BlockState pNeighborState,
|
||||
LevelAccessor pLevel, BlockPos pCurrentPos, BlockPos pNeighborPos) {
|
||||
updateWater(pLevel, pState, pCurrentPos);
|
||||
return pState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FluidState getFluidState(BlockState pState) {
|
||||
return fluidState(pState);
|
||||
}
|
||||
|
||||
static final EnumSet<Direction> STICKY_X = EnumSet.of(Direction.EAST, Direction.WEST);
|
||||
static final EnumSet<Direction> STICKY_Z = EnumSet.of(Direction.SOUTH, Direction.NORTH);
|
||||
|
||||
public EnumSet<Direction> getStickySurfaces(BlockGetter world, BlockPos pos, BlockState state) {
|
||||
return state.getValue(BlockStateProperties.HORIZONTAL_AXIS) == Direction.Axis.X ? STICKY_X : STICKY_Z;
|
||||
}
|
||||
|
||||
public abstract double getWheelPointSpacing();
|
||||
|
||||
public abstract double getWheelRadius();
|
||||
|
||||
public abstract Vec3 getConnectorAnchorOffset();
|
||||
|
||||
public boolean allowsSingleBogeyCarriage() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@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();
|
||||
final Optional<BogeyRenderer.CommonRenderer> commonRenderer
|
||||
= style.getNewCommonRenderInstance();
|
||||
final BogeyRenderer renderer = style.getInWorldRenderInstance(this.getSize());
|
||||
if (state != null) {
|
||||
ms.translate(.5f, .5f, .5f);
|
||||
if (state.getValue(AXIS) == Direction.Axis.X)
|
||||
ms.mulPose(Vector3f.YP.rotationDegrees(90));
|
||||
}
|
||||
ms.translate(0, -1.5 - 1 / 128f, 0);
|
||||
VertexConsumer vb = buffers.getBuffer(RenderType.cutoutMipped());
|
||||
renderer.render(sbte.getBogeyData(), wheelAngle, ms, light, vb);
|
||||
commonRenderer.ifPresent(common ->
|
||||
common.render(sbte.getBogeyData(), wheelAngle, ms, light, vb));
|
||||
}
|
||||
|
||||
public BogeySizes.BogeySize getSize() {
|
||||
return this.size;
|
||||
};
|
||||
|
||||
public Direction getBogeyUpDirection() {
|
||||
return Direction.UP;
|
||||
}
|
||||
|
||||
public boolean isTrackAxisAlongFirstCoordinate(BlockState state) {
|
||||
return state.getValue(AXIS) == Direction.Axis.X;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public BlockState getMatchingBogey(Direction upDirection, boolean axisAlongFirst) {
|
||||
if (upDirection != Direction.UP)
|
||||
return null;
|
||||
return defaultBlockState().setValue(AXIS, axisAlongFirst ? Direction.Axis.X : Direction.Axis.Z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand,
|
||||
BlockHitResult hit) {
|
||||
if (level.isClientSide)
|
||||
return InteractionResult.PASS;
|
||||
ItemStack stack = player.getItemInHand(hand);
|
||||
|
||||
if (!player.isShiftKeyDown() && stack.is(AllItems.WRENCH.get()) && !player.getCooldowns().isOnCooldown(stack.getItem())
|
||||
&& AllBogeyStyles.BOGEY_STYLES.size() > 1) {
|
||||
Collection<BogeyStyle> styles = AllBogeyStyles.BOGEY_STYLES.values();
|
||||
|
||||
if (styles.size() <= 1)
|
||||
return InteractionResult.PASS;
|
||||
|
||||
BlockEntity be = level.getBlockEntity(pos);
|
||||
|
||||
if (!(be instanceof StandardBogeyTileEntity sbte))
|
||||
return InteractionResult.FAIL;
|
||||
|
||||
player.getCooldowns().addCooldown(stack.getItem(), 20);
|
||||
BogeyStyle currentStyle = sbte.getStyle();
|
||||
BogeySizes.BogeySize size = getSize();
|
||||
|
||||
BogeyStyle style = this.getNextStyle(currentStyle);
|
||||
Set<BogeySizes.BogeySize> validSizes = style.validSizes();
|
||||
|
||||
for (int i = 0; i < BogeySizes.count(); i++) {
|
||||
if (validSizes.contains(size)) break;
|
||||
size = size.increment();
|
||||
}
|
||||
|
||||
sbte.setBogeyStyle(style);
|
||||
|
||||
CompoundTag defaultData = style.defaultData;
|
||||
sbte.setBogeyData(sbte.getBogeyData().merge(defaultData));
|
||||
|
||||
if (size == getSize()) {
|
||||
player.displayClientMessage(Lang.translateDirect("create.bogey.style.updated_style")
|
||||
.append(": " + style.displayName), true);
|
||||
} else {
|
||||
CompoundTag oldData = sbte.getBogeyData();
|
||||
level.setBlock(pos, this.getStateOfSize(sbte, size), 3);
|
||||
BlockEntity newBlockEntity = level.getBlockEntity(pos);
|
||||
if (!(newBlockEntity instanceof StandardBogeyTileEntity newTileEntity))
|
||||
return InteractionResult.FAIL;
|
||||
newTileEntity.setBogeyData(oldData);
|
||||
player.displayClientMessage(Lang.translateDirect("create.bogey.style.updated_style_and_size")
|
||||
.append(": " + style.displayName), true);
|
||||
}
|
||||
|
||||
return InteractionResult.CONSUME;
|
||||
}
|
||||
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BlockState getRotatedBlockState(BlockState state, Direction targetedFace) {
|
||||
Block block = state.getBlock();
|
||||
int indexOf = BOGEYS.indexOf(RegisteredObjects.getKeyOrThrow(block));
|
||||
if (indexOf == -1)
|
||||
return state;
|
||||
int index = (indexOf + 1) % BOGEYS.size();
|
||||
Direction bogeyUpDirection = getBogeyUpDirection();
|
||||
boolean trackAxisAlongFirstCoordinate = isTrackAxisAlongFirstCoordinate(state);
|
||||
|
||||
while (index != indexOf) {
|
||||
ResourceLocation id = BOGEYS.get(index);
|
||||
Block newBlock = ForgeRegistries.BLOCKS.getValue(id);
|
||||
if (newBlock instanceof AbstractBogeyBlock bogey) {
|
||||
BlockState matchingBogey = bogey.getMatchingBogey(bogeyUpDirection, trackAxisAlongFirstCoordinate);
|
||||
if (matchingBogey != null)
|
||||
return matchingBogey.hasProperty(WATERLOGGED)
|
||||
? matchingBogey.setValue(WATERLOGGED, state.getValue(WATERLOGGED))
|
||||
: matchingBogey;
|
||||
}
|
||||
index = (index + 1) % BOGEYS.size();
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
public BlockState getNextSize(Level level, BlockPos pos) {
|
||||
BlockEntity te = level.getBlockEntity(pos);
|
||||
if (te instanceof StandardBogeyTileEntity sbte)
|
||||
return this.getNextSize(sbte);
|
||||
return level.getBlockState(pos);
|
||||
}
|
||||
|
||||
public BlockState getNextSize(StandardBogeyTileEntity sbte) {
|
||||
BogeySizes.BogeySize size = this.getSize();
|
||||
BogeyStyle style = sbte.getStyle();
|
||||
BlockState nextBlock = style.getNextBlock(size).defaultBlockState();
|
||||
return nextBlock.hasProperty(WATERLOGGED)
|
||||
? nextBlock.setValue(WATERLOGGED, sbte.getBlockState().getValue(WATERLOGGED))
|
||||
: nextBlock;
|
||||
}
|
||||
|
||||
public BlockState getStateOfSize(StandardBogeyTileEntity sbte, BogeySizes.BogeySize size) {
|
||||
BogeyStyle style = sbte.getStyle();
|
||||
BlockState state = style.getBlockOfSize(size).defaultBlockState();
|
||||
return state.hasProperty(WATERLOGGED)
|
||||
? state.setValue(WATERLOGGED, sbte.getBlockState().getValue(WATERLOGGED))
|
||||
: state;
|
||||
}
|
||||
|
||||
public BogeyStyle getNextStyle(Level level, BlockPos pos) {
|
||||
BlockEntity te = level.getBlockEntity(pos);
|
||||
if (te instanceof StandardBogeyTileEntity sbte)
|
||||
return this.getNextStyle(sbte.getStyle());
|
||||
return AllBogeyStyles.STANDARD;
|
||||
}
|
||||
|
||||
public BogeyStyle getNextStyle(BogeyStyle style) {
|
||||
Collection<BogeyStyle> allStyles = AllBogeyStyles.BOGEY_STYLES.values();
|
||||
if (allStyles.size() <= 1)
|
||||
return style;
|
||||
List<BogeyStyle> list = new ArrayList<>(allStyles);
|
||||
return Iterate.cycleValue(list, style);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull BlockState rotate(@NotNull BlockState pState, Rotation pRotation) {
|
||||
return switch (pRotation) {
|
||||
case COUNTERCLOCKWISE_90, CLOCKWISE_90 -> pState.cycle(AXIS);
|
||||
default -> pState;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemRequirement getRequiredItems(BlockState state, BlockEntity te) {
|
||||
return new ItemRequirement(ItemRequirement.ItemUseType.CONSUME, AllBlocks.RAILWAY_CASING.asStack());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,298 @@
|
|||
package com.simibubi.create.content.logistics.trains;
|
||||
|
||||
import com.jozufozu.flywheel.api.MaterialManager;
|
||||
import com.jozufozu.flywheel.core.Materials;
|
||||
import com.jozufozu.flywheel.core.PartialModel;
|
||||
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
||||
import com.jozufozu.flywheel.util.transform.Transform;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
|
||||
import com.simibubi.create.foundation.render.CachedBufferer;
|
||||
import com.simibubi.create.foundation.render.SuperByteBuffer;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class BogeyRenderer {
|
||||
Map<String, ModelData[]> contraptionModelData = new HashMap<>();
|
||||
|
||||
/**
|
||||
* A common interface for getting transform data for both in-world and in-contraption model data safely from a
|
||||
* partial model
|
||||
*
|
||||
* @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 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* A common interface for getting transform data for both in-world and in-contraption model data safely from a
|
||||
* blockstate
|
||||
*
|
||||
* @param state 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 size The amount of models needed
|
||||
* @return A generic transform which can be used for both in-world and in-contraption models
|
||||
*/
|
||||
public Transform<?>[] getTransformsFromBlockState(BlockState state, PoseStack ms, boolean inContraption, int size) {
|
||||
return (inContraption) ? transformContraptionModelData(keyFromModel(state), ms) : createModelData(state, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for calling both in-world and in-contraption rendering
|
||||
*
|
||||
* @param bogeyData Custom data stored on the bogey able to be used for rendering
|
||||
* @param wheelAngle The angle of the wheel
|
||||
* @param ms The posestack to render to
|
||||
* @param light (Optional) Light used for in-world rendering
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* Used for calling in-contraption rendering ensuring that falsey data is handled correctly
|
||||
*
|
||||
* @param bogeyData Custom data stored on the bogey able to be used for rendering
|
||||
* @param wheelAngle The angle of the wheel
|
||||
* @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 abstract BogeySizes.BogeySize getSize();
|
||||
|
||||
/**
|
||||
* Used to collect Contraption Model Data for in-contraption rendering, should not be utilised directly when
|
||||
* rendering to prevent render type mismatch
|
||||
*
|
||||
* @param key The key used to access the model
|
||||
* @param ms Posestack of the contraption to bind the model data to
|
||||
* @return A generic transform which can be used for both in-world and in-contraption models
|
||||
*/
|
||||
private Transform<?>[] transformContraptionModelData(String key, PoseStack ms) {
|
||||
ModelData[] modelData = contraptionModelData.get(key);
|
||||
Arrays.stream(modelData).forEach(modelDataElement -> modelDataElement.setTransform(ms));
|
||||
return modelData;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used for in world rendering, creates a set count of model data to be rendered, allowing for a generic response
|
||||
* when rendering multiple models both in-world and in-contraption for example, with wheels
|
||||
*
|
||||
* @param model The partial model of the model data ot be made
|
||||
* @param size The Amount of models needed
|
||||
* @return A generic transform which can be used for both in-world and in-contraption models
|
||||
*/
|
||||
private Transform<?>[] createModelData(PartialModel model, int size) {
|
||||
BlockState air = Blocks.AIR.defaultBlockState();
|
||||
SuperByteBuffer[] data = { CachedBufferer.partial(model, air) };
|
||||
return expandArrayToLength(data, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for in world rendering, creates a set count of model data to be rendered, allowing for a generic response
|
||||
* when rendering multiple models both in-world and in-contraption for example, with wheels
|
||||
*
|
||||
* @param state The state of the model data to be made
|
||||
* @param size Amount of models needed
|
||||
* @return A generic transform which can be used for both in-world and in-contraption models
|
||||
*/
|
||||
private Transform<?>[] createModelData(BlockState state, int size) {
|
||||
SuperByteBuffer[] data = { CachedBufferer.block(state) };
|
||||
return expandArrayToLength(data, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function to clone in-world models to a set size to allow for common handling of rendering with multiple
|
||||
* instances of the same model for example with wheels
|
||||
*
|
||||
* @param data An in-world model to be replicated
|
||||
* @param size Amount of models needed
|
||||
* @return A generic transform which can be used for both in-world and in-contraption models
|
||||
*/
|
||||
private Transform<?>[] expandArrayToLength(SuperByteBuffer[] data, int size) {
|
||||
return Arrays.stream(Collections.nCopies(size, data).toArray())
|
||||
.flatMap(inner -> Arrays.stream((SuperByteBuffer[]) inner))
|
||||
.toArray(SuperByteBuffer[]::new);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to collect or create a single model from a partial model used for both in-world and
|
||||
* in-contraption rendering
|
||||
*
|
||||
* @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
|
||||
* @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) {
|
||||
BlockState air = Blocks.AIR.defaultBlockState();
|
||||
return inContraption ? contraptionModelData.get(keyFromModel(model))[0].setTransform(ms)
|
||||
: CachedBufferer.partial(model, air);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Provides render implementations a point in setup to instantiate all model data to be needed
|
||||
*
|
||||
* @param materialManager The material manager
|
||||
*/
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public abstract void initialiseContraptionModelData(MaterialManager materialManager);
|
||||
|
||||
/**
|
||||
* Creates instances of models for in-world rendering to a set length from a provided partial model
|
||||
*
|
||||
* @param materialManager The material manager
|
||||
* @param model Partial model to be instanced
|
||||
* @param count Amount of models neeeded
|
||||
*/
|
||||
public void createModelInstances(MaterialManager materialManager, PartialModel model, int count) {
|
||||
ModelData[] modelData = new ModelData[count];
|
||||
materialManager.defaultSolid().material(Materials.TRANSFORMED)
|
||||
.getModel(model).createInstances(modelData);
|
||||
contraptionModelData.put(keyFromModel(model), modelData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates instances of models for in-world rendering to a set length from a provided blockstate
|
||||
*
|
||||
* @param materialManager The material manager
|
||||
* @param state Blockstate of the model to be created
|
||||
* @param count Amount of models needed
|
||||
*/
|
||||
public void createModelInstances(MaterialManager materialManager, BlockState state, int count) {
|
||||
ModelData[] modelData = new ModelData[count];
|
||||
materialManager.defaultSolid().material(Materials.TRANSFORMED)
|
||||
.getModel(state).createInstances(modelData);
|
||||
contraptionModelData.put(keyFromModel(state), modelData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to create a single model instance for in-contraption rendering
|
||||
*
|
||||
* @param materialManager The material manager
|
||||
* @param models The type of model to create instances of
|
||||
*/
|
||||
public void createModelInstances(MaterialManager materialManager, PartialModel... models) {
|
||||
for (PartialModel model : models)
|
||||
createModelInstances(materialManager, model, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles scale for all model data and renders non contraption model data
|
||||
*
|
||||
* @param b The model data itself
|
||||
* @param ms Pose stack to render to
|
||||
* @param light light level of the scene
|
||||
* @param vb Vertex Consumber to render to
|
||||
* @param <B> Generic alias for both contraption and in-world model data
|
||||
*/
|
||||
|
||||
public static <B extends Transform<?>> void finalize(B b, PoseStack ms, int light, @Nullable VertexConsumer vb) {
|
||||
b.scale(1 - 1/512f);
|
||||
if (b instanceof SuperByteBuffer byteBuf && vb != null)
|
||||
byteBuf.light(light).renderInto(ms, vb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatic handling for setting empty transforms for all model data
|
||||
*
|
||||
*/
|
||||
|
||||
public void emptyTransforms() {
|
||||
for (ModelData[] data : contraptionModelData.values())
|
||||
for (ModelData model : data)
|
||||
model.setEmptyTransform();
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatic handling for updating all model data's light
|
||||
*
|
||||
* @param blockLight the blocklight to be applied
|
||||
* @param skyLight the skylight to be applied
|
||||
*/
|
||||
|
||||
public void updateLight(int blockLight, int skyLight) {
|
||||
for (ModelData[] data : contraptionModelData.values())
|
||||
for (ModelData model : data)
|
||||
model.setBlockLight(blockLight).setSkyLight(skyLight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatic handling for clearing all model data of a contraption
|
||||
*
|
||||
*/
|
||||
|
||||
public void remove() {
|
||||
for (ModelData[] data : contraptionModelData.values())
|
||||
for (ModelData model : data)
|
||||
model.delete();
|
||||
contraptionModelData.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a model key from a partial model, so it can be easily accessed
|
||||
*
|
||||
* @param partialModel the model we want a unique key for
|
||||
* @return Key of the model
|
||||
*/
|
||||
|
||||
private String keyFromModel(PartialModel partialModel) {
|
||||
return partialModel.getLocation().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a model key from a blockstate, so it can be easily accessed
|
||||
*
|
||||
* @param state Blockstate of the model
|
||||
* @return Key of the model
|
||||
*/
|
||||
|
||||
private String keyFromModel(BlockState state) {
|
||||
return state.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for rendering in contraptions allowing for individual instances of models for each component
|
||||
*
|
||||
* @return new Instance of renderer
|
||||
*/
|
||||
public abstract BogeyRenderer createNewInstance();
|
||||
|
||||
|
||||
public static abstract class CommonRenderer extends BogeyRenderer {
|
||||
@Override
|
||||
public BogeySizes.BogeySize getSize() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract CommonRenderer createNewInstance();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
package com.simibubi.create.content.logistics.trains;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class BogeySizes {
|
||||
private static final Collection<BogeySize> BOGEY_SIZES = new HashSet<>();
|
||||
public static final BogeySize SMALL = new BogeySize(Create.ID, "small", 6.5f / 16f);
|
||||
public static final BogeySize LARGE = new BogeySize(Create.ID, "large", 12.5f / 16f);
|
||||
|
||||
static {
|
||||
BOGEY_SIZES.add(SMALL);
|
||||
BOGEY_SIZES.add(LARGE);
|
||||
}
|
||||
|
||||
public static void addSize(String modId, String name, float size) {
|
||||
ResourceLocation location = new ResourceLocation(modId, name);
|
||||
addSize(location, size);
|
||||
}
|
||||
|
||||
public static void addSize(ResourceLocation location, float size) {
|
||||
BogeySize customSize = new BogeySize(location, size);
|
||||
BOGEY_SIZES.add(customSize);
|
||||
}
|
||||
|
||||
public static List<BogeySize> getAllSizesSmallToLarge() {
|
||||
return BOGEY_SIZES.stream()
|
||||
.sorted(Comparator.comparing(BogeySize::wheelRadius))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static List<BogeySize> getAllSizesLargeToSmall() {
|
||||
List<BogeySize> sizes = getAllSizesSmallToLarge();
|
||||
Collections.reverse(sizes);
|
||||
return sizes;
|
||||
}
|
||||
|
||||
public static int count() {
|
||||
return BOGEY_SIZES.size();
|
||||
}
|
||||
|
||||
public record BogeySize(ResourceLocation location, Float wheelRadius) {
|
||||
public BogeySize(String modId, String name, float wheelRadius) {
|
||||
this(new ResourceLocation(modId, name), wheelRadius);
|
||||
}
|
||||
|
||||
public BogeySize increment() {
|
||||
List<BogeySize> values = getAllSizesSmallToLarge();
|
||||
int ordinal = values.indexOf(this);
|
||||
return values.get((ordinal + 1) % values.size());
|
||||
}
|
||||
|
||||
public boolean is(BogeySize size) {
|
||||
return size.location == this.location;
|
||||
}
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
|
||||
}
|
||||
}
|
|
@ -17,11 +17,11 @@ 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();
|
||||
float angle = 0;
|
||||
if (te instanceof StandardBogeyTileEntity sbte)
|
||||
angle = sbte.getVirtualAngle(partialTicks);
|
||||
if (blockState.getBlock()instanceof IBogeyBlock bogey)
|
||||
bogey.render(blockState, angle, ms, partialTicks, buffer, light, overlay);
|
||||
if (te instanceof StandardBogeyTileEntity sbte) {
|
||||
float angle = sbte.getVirtualAngle(partialTicks);
|
||||
if (blockState.getBlock() instanceof AbstractBogeyBlock bogey)
|
||||
bogey.render(blockState, angle, ms, partialTicks, buffer, light, overlay, sbte);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,91 +0,0 @@
|
|||
package com.simibubi.create.content.logistics.trains;
|
||||
|
||||
import static net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.jozufozu.flywheel.api.MaterialManager;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.simibubi.create.content.contraptions.wrench.IWrenchable;
|
||||
import com.simibubi.create.content.logistics.trains.entity.BogeyInstance;
|
||||
import com.simibubi.create.content.logistics.trains.entity.CarriageBogey;
|
||||
import com.simibubi.create.foundation.utility.RegisteredObjects;
|
||||
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
public interface IBogeyBlock extends IWrenchable {
|
||||
|
||||
static final List<ResourceLocation> BOGEYS = new ArrayList<>();
|
||||
|
||||
public static void register(ResourceLocation block) {
|
||||
BOGEYS.add(block);
|
||||
}
|
||||
|
||||
public EnumSet<Direction> getStickySurfaces(BlockGetter world, BlockPos pos, BlockState state);
|
||||
|
||||
public double getWheelPointSpacing();
|
||||
|
||||
public double getWheelRadius();
|
||||
|
||||
public boolean allowsSingleBogeyCarriage();
|
||||
|
||||
public Vec3 getConnectorAnchorOffset();
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void render(@Nullable BlockState state, float wheelAngle, PoseStack ms, float partialTicks,
|
||||
MultiBufferSource buffers, int light, int overlay);
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public BogeyInstance createInstance(MaterialManager materialManager, CarriageBogey bogey);
|
||||
|
||||
public default Direction getBogeyUpDirection() {
|
||||
return Direction.UP;
|
||||
}
|
||||
|
||||
public boolean isTrackAxisAlongFirstCoordinate(BlockState state);
|
||||
|
||||
@Nullable
|
||||
public BlockState getMatchingBogey(Direction upDirection, boolean axisAlongFirst);
|
||||
|
||||
@Override
|
||||
default BlockState getRotatedBlockState(BlockState state, Direction targetedFace) {
|
||||
Block block = state.getBlock();
|
||||
int indexOf = BOGEYS.indexOf(RegisteredObjects.getKeyOrThrow(block));
|
||||
if (indexOf == -1)
|
||||
return state;
|
||||
|
||||
int index = (indexOf + 1) % BOGEYS.size();
|
||||
Direction bogeyUpDirection = getBogeyUpDirection();
|
||||
boolean trackAxisAlongFirstCoordinate = isTrackAxisAlongFirstCoordinate(state);
|
||||
|
||||
while (index != indexOf) {
|
||||
ResourceLocation id = BOGEYS.get(index);
|
||||
Block newBlock = ForgeRegistries.BLOCKS.getValue(id);
|
||||
if (newBlock instanceof IBogeyBlock bogey) {
|
||||
BlockState matchingBogey = bogey.getMatchingBogey(bogeyUpDirection, trackAxisAlongFirstCoordinate);
|
||||
if (matchingBogey != null)
|
||||
return matchingBogey.hasProperty(WATERLOGGED)
|
||||
? matchingBogey.setValue(WATERLOGGED, state.getValue(WATERLOGGED))
|
||||
: matchingBogey;
|
||||
}
|
||||
index = (index + 1) % BOGEYS.size();
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
package com.simibubi.create.content.logistics.trains;
|
||||
|
||||
import com.jozufozu.flywheel.api.MaterialManager;
|
||||
import com.jozufozu.flywheel.util.transform.Transform;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.content.contraptions.relays.elementary.ShaftBlock;
|
||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static com.simibubi.create.AllBlockPartials.LARGE_BOGEY_WHEELS;
|
||||
import static com.simibubi.create.AllBlockPartials.BOGEY_PIN;
|
||||
import static com.simibubi.create.AllBlockPartials.BOGEY_DRIVE;
|
||||
import static com.simibubi.create.AllBlockPartials.BOGEY_PISTON;
|
||||
import static com.simibubi.create.AllBlockPartials.SMALL_BOGEY_WHEELS;
|
||||
import static com.simibubi.create.AllBlockPartials.BOGEY_FRAME;
|
||||
|
||||
public class StandardBogeyRenderer {
|
||||
public static class CommonStandardBogeyRenderer extends BogeyRenderer.CommonRenderer {
|
||||
@Override
|
||||
public void initialiseContraptionModelData(MaterialManager materialManager) {
|
||||
createModelInstances(materialManager, AllBlocks.SHAFT.getDefaultState()
|
||||
.setValue(ShaftBlock.AXIS, Direction.Axis.Z), 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonStandardBogeyRenderer createNewInstance() {
|
||||
return new CommonStandardBogeyRenderer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(CompoundTag bogeyData, float wheelAngle, PoseStack ms, int light, VertexConsumer vb) {
|
||||
boolean inContraption = vb == null;
|
||||
Transform<?>[] shafts = getTransformsFromBlockState(AllBlocks.SHAFT.getDefaultState()
|
||||
.setValue(ShaftBlock.AXIS, Direction.Axis.Z), ms, inContraption, 2);
|
||||
for (int i : Iterate.zeroAndOne) {
|
||||
shafts[i].translate(-.5f, .25f, i * -1)
|
||||
.centre()
|
||||
.rotateZ(wheelAngle)
|
||||
.unCentre();
|
||||
finalize(shafts[i], ms, light, vb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class SmallStandardBogeyRenderer extends BogeyRenderer {
|
||||
@Override
|
||||
public void initialiseContraptionModelData(MaterialManager materialManager) {
|
||||
createModelInstances(materialManager, SMALL_BOGEY_WHEELS, 2);
|
||||
createModelInstances(materialManager, BOGEY_FRAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BogeyRenderer createNewInstance() {
|
||||
return new SmallStandardBogeyRenderer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BogeySizes.BogeySize getSize() {
|
||||
return BogeySizes.SMALL;
|
||||
}
|
||||
|
||||
@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);
|
||||
finalize(transform, ms, light, vb);
|
||||
|
||||
Transform<?>[] wheels = getTransformsFromPartial(SMALL_BOGEY_WHEELS, ms, inContraption, 2);
|
||||
for (int side : Iterate.positiveAndNegative) {
|
||||
if (!inContraption)
|
||||
ms.pushPose();
|
||||
Transform<?> wheel = wheels[(side + 1)/2];
|
||||
wheel.translate(0, 12 / 16f, side)
|
||||
.rotateX(wheelAngle);
|
||||
finalize(wheel, ms, light, vb);
|
||||
if (!inContraption)
|
||||
ms.popPose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class LargeStandardBogeyRenderer extends BogeyRenderer {
|
||||
@Override
|
||||
public void initialiseContraptionModelData(MaterialManager materialManager) {
|
||||
createModelInstances(materialManager, LARGE_BOGEY_WHEELS, BOGEY_DRIVE, BOGEY_PISTON, BOGEY_PIN);
|
||||
createModelInstances(materialManager, AllBlocks.SHAFT.getDefaultState()
|
||||
.setValue(ShaftBlock.AXIS, Direction.Axis.X), 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BogeyRenderer createNewInstance() {
|
||||
return new LargeStandardBogeyRenderer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BogeySizes.BogeySize getSize() {
|
||||
return BogeySizes.LARGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(CompoundTag bogeyData, float wheelAngle, PoseStack ms, int light, VertexConsumer vb) {
|
||||
boolean inContraption = vb == null;
|
||||
|
||||
Transform<?>[] secondaryShafts = getTransformsFromBlockState(AllBlocks.SHAFT.getDefaultState()
|
||||
.setValue(ShaftBlock.AXIS, Direction.Axis.X), ms, inContraption, 2);
|
||||
|
||||
for (int i : Iterate.zeroAndOne) {
|
||||
Transform<?> secondShaft = secondaryShafts[i];
|
||||
secondShaft.translate(-.5f, .25f, .5f + i * -2)
|
||||
.centre()
|
||||
.rotateX(wheelAngle)
|
||||
.unCentre();
|
||||
finalize(secondShaft, ms, light, vb);
|
||||
}
|
||||
|
||||
Transform<?> bogeyDrive = getTransformFromPartial(BOGEY_DRIVE, ms, inContraption);
|
||||
finalize(bogeyDrive, ms, light, vb);
|
||||
|
||||
Transform<?> bogeyPiston = getTransformFromPartial(BOGEY_PISTON, ms, inContraption)
|
||||
.translate(0, 0, 1 / 4f * Math.sin(AngleHelper.rad(wheelAngle)));
|
||||
finalize(bogeyPiston, ms, light, vb);
|
||||
|
||||
if (!inContraption)
|
||||
ms.pushPose();
|
||||
|
||||
Transform<?> bogeyWheels = getTransformFromPartial(LARGE_BOGEY_WHEELS, ms, inContraption)
|
||||
.translate(0, 1, 0)
|
||||
.rotateX(wheelAngle);
|
||||
finalize(bogeyWheels, ms, light, vb);
|
||||
|
||||
Transform<?> bogeyPin = getTransformFromPartial(BOGEY_PIN, ms, inContraption)
|
||||
.translate(0, 1, 0)
|
||||
.rotateX(wheelAngle)
|
||||
.translate(0, 1 / 4f, 0)
|
||||
.rotateX(-wheelAngle);
|
||||
finalize(bogeyPin, ms, light, vb);
|
||||
|
||||
if (!inContraption)
|
||||
ms.popPose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.simibubi.create.content.logistics.trains.entity;
|
||||
|
||||
import com.jozufozu.flywheel.api.MaterialManager;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import com.simibubi.create.content.logistics.trains.BogeyRenderer;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
||||
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) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialiseContraptionModelData(MaterialManager materialManager) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonRenderer createNewInstance() {
|
||||
return new BackupBogeyRenderer();
|
||||
}
|
||||
}
|
|
@ -1,235 +1,72 @@
|
|||
package com.simibubi.create.content.logistics.trains.entity;
|
||||
|
||||
import com.jozufozu.flywheel.api.Material;
|
||||
import com.jozufozu.flywheel.api.MaterialManager;
|
||||
import com.jozufozu.flywheel.core.Materials;
|
||||
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
||||
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.simibubi.create.AllBlockPartials;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.content.contraptions.relays.elementary.ShaftBlock;
|
||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
import com.simibubi.create.content.logistics.trains.BogeyRenderer;
|
||||
|
||||
import com.simibubi.create.content.logistics.trains.BogeySizes;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.LightLayer;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public sealed class BogeyInstance {
|
||||
import java.util.Optional;
|
||||
|
||||
public final class BogeyInstance {
|
||||
private final BogeySizes.BogeySize size;
|
||||
private final BogeyStyle style;
|
||||
|
||||
public final CarriageBogey bogey;
|
||||
private final ModelData[] shafts;
|
||||
public final BogeyRenderer renderer;
|
||||
public final Optional<BogeyRenderer.CommonRenderer> commonRenderer;
|
||||
|
||||
protected BogeyInstance(CarriageBogey bogey, MaterialManager materialManager) {
|
||||
public BogeyInstance(CarriageBogey bogey, BogeyStyle style, BogeySizes.BogeySize size, MaterialManager materialManager) {
|
||||
this.bogey = bogey;
|
||||
this.size = size;
|
||||
this.style = style;
|
||||
|
||||
shafts = new ModelData[2];
|
||||
|
||||
materialManager.defaultSolid()
|
||||
.material(Materials.TRANSFORMED)
|
||||
.getModel(AllBlocks.SHAFT.getDefaultState()
|
||||
.setValue(ShaftBlock.AXIS, Direction.Axis.Z))
|
||||
.createInstances(shafts);
|
||||
this.renderer = this.style.createRendererInstance(this.size);
|
||||
this.commonRenderer = this.style.getNewCommonRenderInstance();
|
||||
|
||||
commonRenderer.ifPresent(bogeyRenderer ->
|
||||
bogeyRenderer.initialiseContraptionModelData(materialManager));
|
||||
renderer.initialiseContraptionModelData(materialManager);
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
for (ModelData shaft : shafts)
|
||||
shaft.delete();
|
||||
}
|
||||
|
||||
public void hiddenFrame() {
|
||||
void hiddenFrame() {
|
||||
beginFrame(0, null);
|
||||
}
|
||||
|
||||
|
||||
public void beginFrame(float wheelAngle, PoseStack ms) {
|
||||
if (ms == null) {
|
||||
for (int i : Iterate.zeroAndOne)
|
||||
shafts[i].setEmptyTransform();
|
||||
renderer.emptyTransforms();
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i : Iterate.zeroAndOne)
|
||||
shafts[i].setTransform(ms)
|
||||
.translate(-.5f, .25f, i * -1)
|
||||
.centre()
|
||||
.rotateZ(wheelAngle)
|
||||
.unCentre();
|
||||
commonRenderer.ifPresent(bogeyRenderer ->
|
||||
bogeyRenderer.render(bogey.bogeyData, wheelAngle, ms));
|
||||
renderer.render(bogey.bogeyData, wheelAngle, ms);
|
||||
}
|
||||
|
||||
public void updateLight(BlockAndTintGetter world, CarriageContraptionEntity entity) {
|
||||
var lightPos = new BlockPos(getLightPos(entity));
|
||||
|
||||
updateLight(world.getBrightness(LightLayer.BLOCK, lightPos), world.getBrightness(LightLayer.SKY, lightPos));
|
||||
commonRenderer.ifPresent(bogeyRenderer
|
||||
-> bogeyRenderer.updateLight(world.getBrightness(LightLayer.BLOCK, lightPos),
|
||||
world.getBrightness(LightLayer.SKY, lightPos)));
|
||||
renderer.updateLight(world.getBrightness(LightLayer.BLOCK, lightPos),
|
||||
world.getBrightness(LightLayer.SKY, lightPos));
|
||||
}
|
||||
|
||||
private Vec3 getLightPos(CarriageContraptionEntity entity) {
|
||||
if (bogey.getAnchorPosition() != null) {
|
||||
return bogey.getAnchorPosition();
|
||||
} else {
|
||||
return entity.getLightProbePosition(AnimationTickHolder.getPartialTicks());
|
||||
}
|
||||
return bogey.getAnchorPosition() != null ? bogey.getAnchorPosition()
|
||||
: entity.getLightProbePosition(AnimationTickHolder.getPartialTicks());
|
||||
}
|
||||
|
||||
public void updateLight(int blockLight, int skyLight) {
|
||||
for (ModelData shaft : shafts) {
|
||||
shaft.setBlockLight(blockLight)
|
||||
.setSkyLight(skyLight);
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Frame extends BogeyInstance {
|
||||
|
||||
private final ModelData frame;
|
||||
private final ModelData[] wheels;
|
||||
|
||||
public Frame(CarriageBogey bogey, MaterialManager materialManager) {
|
||||
super(bogey, materialManager);
|
||||
|
||||
frame = materialManager.defaultSolid()
|
||||
.material(Materials.TRANSFORMED)
|
||||
.getModel(AllBlockPartials.BOGEY_FRAME)
|
||||
.createInstance();
|
||||
|
||||
wheels = new ModelData[2];
|
||||
|
||||
materialManager.defaultSolid()
|
||||
.material(Materials.TRANSFORMED)
|
||||
.getModel(AllBlockPartials.SMALL_BOGEY_WHEELS)
|
||||
.createInstances(wheels);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginFrame(float wheelAngle, PoseStack ms) {
|
||||
super.beginFrame(wheelAngle, ms);
|
||||
|
||||
if (ms == null) {
|
||||
frame.setEmptyTransform();
|
||||
for (int side : Iterate.positiveAndNegative)
|
||||
wheels[(side + 1) / 2].setEmptyTransform();
|
||||
return;
|
||||
}
|
||||
|
||||
frame.setTransform(ms);
|
||||
|
||||
for (int side : Iterate.positiveAndNegative) {
|
||||
wheels[(side + 1) / 2].setTransform(ms)
|
||||
.translate(0, 12 / 16f, side)
|
||||
.rotateX(wheelAngle);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLight(int blockLight, int skyLight) {
|
||||
super.updateLight(blockLight, skyLight);
|
||||
frame.setBlockLight(blockLight)
|
||||
.setSkyLight(skyLight);
|
||||
for (ModelData wheel : wheels)
|
||||
wheel.setBlockLight(blockLight)
|
||||
.setSkyLight(skyLight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
super.remove();
|
||||
frame.delete();
|
||||
for (ModelData wheel : wheels)
|
||||
wheel.delete();
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Drive extends BogeyInstance {
|
||||
|
||||
private final ModelData[] secondShaft;
|
||||
private final ModelData drive;
|
||||
private final ModelData piston;
|
||||
private final ModelData wheels;
|
||||
private final ModelData pin;
|
||||
|
||||
public Drive(CarriageBogey bogey, MaterialManager materialManager) {
|
||||
super(bogey, materialManager);
|
||||
Material<ModelData> mat = materialManager.defaultSolid()
|
||||
.material(Materials.TRANSFORMED);
|
||||
|
||||
secondShaft = new ModelData[2];
|
||||
|
||||
mat.getModel(AllBlocks.SHAFT.getDefaultState()
|
||||
.setValue(ShaftBlock.AXIS, Direction.Axis.X))
|
||||
.createInstances(secondShaft);
|
||||
|
||||
drive = mat.getModel(AllBlockPartials.BOGEY_DRIVE)
|
||||
.createInstance();
|
||||
piston = mat.getModel(AllBlockPartials.BOGEY_PISTON)
|
||||
.createInstance();
|
||||
wheels = mat.getModel(AllBlockPartials.LARGE_BOGEY_WHEELS)
|
||||
.createInstance();
|
||||
pin = mat.getModel(AllBlockPartials.BOGEY_PIN)
|
||||
.createInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginFrame(float wheelAngle, PoseStack ms) {
|
||||
super.beginFrame(wheelAngle, ms);
|
||||
|
||||
if (ms == null) {
|
||||
for (int i : Iterate.zeroAndOne)
|
||||
secondShaft[i].setEmptyTransform();
|
||||
drive.setEmptyTransform();
|
||||
piston.setEmptyTransform();
|
||||
wheels.setEmptyTransform();
|
||||
pin.setEmptyTransform();
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i : Iterate.zeroAndOne)
|
||||
secondShaft[i].setTransform(ms)
|
||||
.translate(-.5f, .25f, .5f + i * -2)
|
||||
.centre()
|
||||
.rotateX(wheelAngle)
|
||||
.unCentre();
|
||||
|
||||
drive.setTransform(ms);
|
||||
piston.setTransform(ms)
|
||||
.translate(0, 0, 1 / 4f * Math.sin(AngleHelper.rad(wheelAngle)));
|
||||
|
||||
wheels.setTransform(ms)
|
||||
.translate(0, 1, 0)
|
||||
.rotateX(wheelAngle);
|
||||
pin.setTransform(ms)
|
||||
.translate(0, 1, 0)
|
||||
.rotateX(wheelAngle)
|
||||
.translate(0, 1 / 4f, 0)
|
||||
.rotateX(-wheelAngle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLight(int blockLight, int skyLight) {
|
||||
super.updateLight(blockLight, skyLight);
|
||||
for (ModelData shaft : secondShaft)
|
||||
shaft.setBlockLight(blockLight)
|
||||
.setSkyLight(skyLight);
|
||||
drive.setBlockLight(blockLight)
|
||||
.setSkyLight(skyLight);
|
||||
piston.setBlockLight(blockLight)
|
||||
.setSkyLight(skyLight);
|
||||
wheels.setBlockLight(blockLight)
|
||||
.setSkyLight(skyLight);
|
||||
pin.setBlockLight(blockLight)
|
||||
.setSkyLight(skyLight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
super.remove();
|
||||
for (ModelData shaft : secondShaft)
|
||||
shaft.delete();
|
||||
drive.delete();
|
||||
piston.delete();
|
||||
wheels.delete();
|
||||
pin.delete();
|
||||
}
|
||||
@FunctionalInterface
|
||||
interface BogeyInstanceFactory {
|
||||
BogeyInstance create(CarriageBogey bogey, BogeySizes.BogeySize size,
|
||||
MaterialManager materialManager);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
package com.simibubi.create.content.logistics.trains.entity;
|
||||
|
||||
import com.jozufozu.flywheel.api.MaterialManager;
|
||||
import com.simibubi.create.AllSoundEvents;
|
||||
import com.simibubi.create.content.logistics.trains.BogeyRenderer;
|
||||
|
||||
import com.simibubi.create.content.logistics.trains.BogeyRenderer.CommonRenderer;
|
||||
import com.simibubi.create.content.logistics.trains.BogeySizes;
|
||||
|
||||
import net.minecraft.core.particles.ParticleOptions;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
|
||||
public class BogeyStyle {
|
||||
public final ResourceLocation name;
|
||||
private final Optional<CommonRenderer> commonRenderer;
|
||||
private final Map<BogeySizes.BogeySize, SizeData> sizes;
|
||||
public final Component displayName;
|
||||
public final ResourceLocation soundType;
|
||||
public final ParticleOptions contactParticle;
|
||||
public final ParticleOptions smokeParticle;
|
||||
public final CompoundTag defaultData;
|
||||
|
||||
public BogeyStyle(ResourceLocation name, Component displayName, ResourceLocation soundType, ParticleOptions contactParticle, ParticleOptions smokeParticle,
|
||||
CompoundTag defaultData, Map<BogeySizes.BogeySize, SizeData> sizes, Optional<CommonRenderer> commonRenderer) {
|
||||
this.name = name;
|
||||
this.displayName = displayName;
|
||||
this.soundType = soundType;
|
||||
this.contactParticle = contactParticle;
|
||||
this.smokeParticle = smokeParticle;
|
||||
this.defaultData = defaultData;
|
||||
|
||||
this.sizes = sizes;
|
||||
this.commonRenderer = commonRenderer;
|
||||
}
|
||||
|
||||
public Block getNextBlock(BogeySizes.BogeySize currentSize) {
|
||||
return Stream.iterate(currentSize.increment(), BogeySizes.BogeySize::increment)
|
||||
.filter(sizes::containsKey)
|
||||
.findFirst()
|
||||
.map(size -> ForgeRegistries.BLOCKS.getValue(sizes.get(size).block()))
|
||||
.orElse(ForgeRegistries.BLOCKS.getValue(sizes.get(currentSize).block()));
|
||||
}
|
||||
|
||||
public Block getBlockOfSize(BogeySizes.BogeySize size) {
|
||||
return ForgeRegistries.BLOCKS.getValue(sizes.get(size).block());
|
||||
}
|
||||
|
||||
public Set<BogeySizes.BogeySize> validSizes() {
|
||||
return sizes.keySet();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public SoundEvent getSoundType() {
|
||||
AllSoundEvents.SoundEntry entry = AllSoundEvents.ALL.get(this.soundType);
|
||||
if (entry == null || entry.getMainEvent() == null) entry = AllSoundEvents.TRAIN2;
|
||||
return entry.getMainEvent();
|
||||
}
|
||||
|
||||
public BogeyRenderer createRendererInstance(BogeySizes.BogeySize size) {
|
||||
return this.getInWorldRenderInstance(size).createNewInstance();
|
||||
}
|
||||
|
||||
public BogeyRenderer getInWorldRenderInstance(BogeySizes.BogeySize size) {
|
||||
SizeData sizeData = this.sizes.get(size);
|
||||
return sizeData != null ? sizeData.renderer() : BackupBogeyRenderer.INSTANCE;
|
||||
}
|
||||
|
||||
public Optional<CommonRenderer> getInWorldCommonRenderInstance() {
|
||||
return this.commonRenderer;
|
||||
}
|
||||
|
||||
public Optional<CommonRenderer> getNewCommonRenderInstance() {
|
||||
return this.getInWorldCommonRenderInstance().map(CommonRenderer::createNewInstance);
|
||||
}
|
||||
|
||||
public BogeyInstance createInstance(CarriageBogey bogey, BogeySizes.BogeySize size, MaterialManager materialManager) {
|
||||
return new BogeyInstance(bogey, this, size, materialManager);
|
||||
}
|
||||
|
||||
public record SizeData(ResourceLocation block, BogeyRenderer renderer) {
|
||||
}
|
||||
}
|
|
@ -3,13 +3,16 @@ package com.simibubi.create.content.logistics.trains.entity;
|
|||
import javax.annotation.Nullable;
|
||||
|
||||
import com.jozufozu.flywheel.api.MaterialManager;
|
||||
import com.simibubi.create.AllBogeyStyles;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.logistics.trains.DimensionPalette;
|
||||
import com.simibubi.create.content.logistics.trains.IBogeyBlock;
|
||||
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.foundation.utility.AngleHelper;
|
||||
import com.simibubi.create.foundation.utility.Couple;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
import com.simibubi.create.foundation.utility.NBTHelper;
|
||||
import com.simibubi.create.foundation.utility.RegisteredObjects;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
|
||||
|
@ -25,13 +28,16 @@ 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;
|
||||
|
||||
public class CarriageBogey {
|
||||
|
||||
public Carriage carriage;
|
||||
|
||||
boolean isLeading;
|
||||
|
||||
IBogeyBlock type;
|
||||
public CompoundTag bogeyData;
|
||||
|
||||
AbstractBogeyBlock type;
|
||||
Couple<TravellingPoint> points;
|
||||
|
||||
LerpedFloat wheelAngle;
|
||||
|
@ -42,7 +48,10 @@ public class CarriageBogey {
|
|||
|
||||
int derailAngle;
|
||||
|
||||
public CarriageBogey(IBogeyBlock type, TravellingPoint point, TravellingPoint point2) {
|
||||
public CarriageBogey(AbstractBogeyBlock type, CompoundTag bogeyData, TravellingPoint point, TravellingPoint point2) {
|
||||
if (bogeyData == null || bogeyData.isEmpty())
|
||||
bogeyData = this.createBogeyData(); // Prevent Crash When Updating
|
||||
this.bogeyData = bogeyData;
|
||||
this.type = type;
|
||||
points = Couple.create(point, point2);
|
||||
wheelAngle = LerpedFloat.angular();
|
||||
|
@ -150,20 +159,32 @@ public class CarriageBogey {
|
|||
tag.putString("Type", RegisteredObjects.getKeyOrThrow((Block) type)
|
||||
.toString());
|
||||
tag.put("Points", points.serializeEach(tp -> tp.write(dimensions)));
|
||||
tag.put(BOGEY_STYLE_KEY, bogeyData);
|
||||
return tag;
|
||||
}
|
||||
|
||||
public static CarriageBogey read(CompoundTag tag, TrackGraph graph, DimensionPalette dimensions) {
|
||||
ResourceLocation location = new ResourceLocation(tag.getString("Type"));
|
||||
IBogeyBlock type = (IBogeyBlock) ForgeRegistries.BLOCKS.getValue(location);
|
||||
AbstractBogeyBlock type = (AbstractBogeyBlock) ForgeRegistries.BLOCKS.getValue(location);
|
||||
Couple<TravellingPoint> points = Couple.deserializeEach(tag.getList("Points", Tag.TAG_COMPOUND),
|
||||
c -> TravellingPoint.read(c, graph, dimensions));
|
||||
CarriageBogey carriageBogey = new CarriageBogey(type, points.getFirst(), points.getSecond());
|
||||
return carriageBogey;
|
||||
CompoundTag data = tag.getCompound(StandardBogeyTileEntity.BOGEY_DATA_KEY);
|
||||
return new CarriageBogey(type, data, points.getFirst(), points.getSecond());
|
||||
}
|
||||
|
||||
public BogeyInstance createInstance(MaterialManager materialManager) {
|
||||
return type.createInstance(materialManager, this);
|
||||
return this.getStyle().createInstance(this, type.getSize(), materialManager);
|
||||
}
|
||||
|
||||
public BogeyStyle getStyle() {
|
||||
ResourceLocation location = NBTHelper.readResourceLocation(this.bogeyData, BOGEY_STYLE_KEY);
|
||||
return AllBogeyStyles.BOGEY_STYLES.get(location);
|
||||
}
|
||||
|
||||
private CompoundTag createBogeyData() {
|
||||
CompoundTag nbt = new CompoundTag();
|
||||
NBTHelper.writeResourceLocation(nbt, BOGEY_STYLE_KEY, AllBogeyStyles.STANDARD.name);
|
||||
return nbt;
|
||||
}
|
||||
|
||||
void setLeading() {
|
||||
|
|
|
@ -22,7 +22,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.ren
|
|||
import com.simibubi.create.content.contraptions.components.structureMovement.train.TrainCargoManager;
|
||||
import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock;
|
||||
import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.HeatLevel;
|
||||
import com.simibubi.create.content.logistics.trains.IBogeyBlock;
|
||||
import com.simibubi.create.content.logistics.trains.AbstractBogeyBlock;
|
||||
import com.simibubi.create.foundation.utility.Couple;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
|
@ -71,7 +71,7 @@ public class CarriageContraption extends Contraption {
|
|||
// render
|
||||
public int portalCutoffMin;
|
||||
public int portalCutoffMax;
|
||||
|
||||
|
||||
static final IItemHandlerModifiable fallbackItems = new ItemStackHandler();
|
||||
static final IFluidHandler fallbackFluids = new FluidTank(0);
|
||||
|
||||
|
@ -162,7 +162,7 @@ public class CarriageContraption extends Contraption {
|
|||
.getStep(), toLocalPos(pos));
|
||||
}
|
||||
|
||||
if (blockState.getBlock() instanceof IBogeyBlock) {
|
||||
if (blockState.getBlock() instanceof AbstractBogeyBlock) {
|
||||
bogeys++;
|
||||
if (bogeys == 2)
|
||||
secondBogeyPos = pos;
|
||||
|
@ -235,7 +235,7 @@ public class CarriageContraption extends Contraption {
|
|||
protected MountedStorageManager getStorageForSpawnPacket() {
|
||||
return storageProxy;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected ContraptionType getType() {
|
||||
return ContraptionType.CARRIAGE;
|
||||
|
|
|
@ -7,12 +7,15 @@ 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 net.minecraft.client.renderer.LightTexture;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.culling.Frustum;
|
||||
import net.minecraft.client.renderer.entity.EntityRendererProvider;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.LightLayer;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class CarriageContraptionEntityRenderer extends ContraptionEntityRenderer<CarriageContraptionEntity> {
|
||||
|
@ -37,7 +40,7 @@ public class CarriageContraptionEntityRenderer extends ContraptionEntityRenderer
|
|||
MultiBufferSource buffers, int overlay) {
|
||||
if (!entity.validForRender || entity.firstPositionUpdate)
|
||||
return;
|
||||
|
||||
|
||||
super.render(entity, yaw, partialTicks, ms, buffers, overlay);
|
||||
|
||||
Carriage carriage = entity.getCarriage();
|
||||
|
@ -65,8 +68,10 @@ public class CarriageContraptionEntityRenderer extends ContraptionEntityRenderer
|
|||
translateBogey(ms, bogey, bogeySpacing, viewYRot, viewXRot, partialTicks);
|
||||
|
||||
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);
|
||||
overlay, (StandardBogeyTileEntity) be);
|
||||
|
||||
ms.popPose();
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import com.jozufozu.flywheel.util.AnimationTickHolder;
|
|||
import com.jozufozu.flywheel.util.transform.TransformStack;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.math.Vector3f;
|
||||
import com.simibubi.create.content.logistics.trains.BogeyRenderer;
|
||||
import com.simibubi.create.foundation.utility.Couple;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
|
||||
|
@ -31,7 +32,8 @@ public class CarriageContraptionInstance extends EntityInstance<CarriageContrapt
|
|||
if (carriage == null)
|
||||
return;
|
||||
|
||||
bogeys = carriage.bogeys.mapNotNullWithParam(CarriageBogey::createInstance, materialManager);
|
||||
bogeys = carriage.bogeys.mapNotNullWithParam((bogey, manager) ->
|
||||
bogey.getStyle().createInstance(bogey, bogey.type.getSize(), manager), materialManager);
|
||||
updateLight();
|
||||
}
|
||||
|
||||
|
@ -98,8 +100,10 @@ public class CarriageContraptionInstance extends EntityInstance<CarriageContrapt
|
|||
return;
|
||||
|
||||
bogeys.forEach(instance -> {
|
||||
if (instance != null)
|
||||
instance.remove();
|
||||
if (instance != null) {
|
||||
instance.commonRenderer.ifPresent(BogeyRenderer::remove);
|
||||
instance.renderer.remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser;
|
|||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.Direction.Axis;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
@ -110,7 +109,7 @@ public class CarriageParticles {
|
|||
|
||||
m = m.add(contraptionMotion.scale(.75f));
|
||||
|
||||
level.addParticle(spark ? ParticleTypes.CRIT : ParticleTypes.POOF, v.x, v.y, v.z, m.x, m.y, m.z);
|
||||
level.addParticle(spark ? bogey.getStyle().contactParticle : bogey.getStyle().smokeParticle, v.x, v.y, v.z, m.x, m.y, m.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.simibubi.create.content.logistics.trains.entity;
|
|||
import com.simibubi.create.AllSoundEvents;
|
||||
import com.simibubi.create.AllSoundEvents.SoundEntry;
|
||||
import com.simibubi.create.content.logistics.trains.entity.Carriage.DimensionalCarriageEntity;
|
||||
import com.simibubi.create.foundation.utility.Couple;
|
||||
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
|
||||
import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser;
|
||||
|
||||
|
@ -29,6 +30,9 @@ public class CarriageSounds {
|
|||
LoopingSound sharedWheelSoundSeated;
|
||||
LoopingSound sharedHonkSound;
|
||||
|
||||
Couple<SoundEvent> bogeySounds;
|
||||
SoundEvent closestBogeySound;
|
||||
|
||||
boolean arrived;
|
||||
|
||||
int tick;
|
||||
|
@ -36,6 +40,10 @@ public class CarriageSounds {
|
|||
|
||||
public CarriageSounds(CarriageContraptionEntity entity) {
|
||||
this.entity = entity;
|
||||
bogeySounds = entity.getCarriage().bogeys.map(bogey ->
|
||||
bogey != null ? bogey.getStyle().getSoundType()
|
||||
: AllSoundEvents.TRAIN2.getMainEvent());
|
||||
closestBogeySound = bogeySounds.getFirst();
|
||||
distanceFactor = LerpedFloat.linear();
|
||||
speedFactor = LerpedFloat.linear();
|
||||
approachFactor = LerpedFloat.linear();
|
||||
|
@ -79,6 +87,9 @@ public class CarriageSounds {
|
|||
double distance1 = toBogey1.length();
|
||||
double distance2 = toBogey2.length();
|
||||
|
||||
Couple<CarriageBogey> bogeys = entity.getCarriage().bogeys;
|
||||
closestBogeySound = bogeys.get(distance1 > distance2).getStyle().getSoundType();
|
||||
|
||||
Vec3 toCarriage = distance1 > distance2 ? toBogey2 : toBogey1;
|
||||
double distance = Math.min(distance1, distance2);
|
||||
Vec3 soundLocation = cam.add(toCarriage);
|
||||
|
@ -97,7 +108,7 @@ public class CarriageSounds {
|
|||
seatCrossfade.tickChaser();
|
||||
|
||||
minecartEsqueSound = playIfMissing(mc, minecartEsqueSound, AllSoundEvents.TRAIN.getMainEvent());
|
||||
sharedWheelSound = playIfMissing(mc, sharedWheelSound, AllSoundEvents.TRAIN2.getMainEvent());
|
||||
sharedWheelSound = playIfMissing(mc, sharedWheelSound, closestBogeySound);
|
||||
sharedWheelSoundSeated = playIfMissing(mc, sharedWheelSoundSeated, AllSoundEvents.TRAIN3.getMainEvent());
|
||||
|
||||
float volume = Math.min(Math.min(speedFactor.getValue(), distanceFactor.getValue() / 100),
|
||||
|
@ -205,7 +216,7 @@ public class CarriageSounds {
|
|||
public void submitSharedSoundVolume(Vec3 location, float volume) {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
minecartEsqueSound = playIfMissing(mc, minecartEsqueSound, AllSoundEvents.TRAIN.getMainEvent());
|
||||
sharedWheelSound = playIfMissing(mc, sharedWheelSound, AllSoundEvents.TRAIN2.getMainEvent());
|
||||
sharedWheelSound = playIfMissing(mc, sharedWheelSound, closestBogeySound);
|
||||
sharedWheelSoundSeated = playIfMissing(mc, sharedWheelSoundSeated, AllSoundEvents.TRAIN3.getMainEvent());
|
||||
|
||||
boolean approach = true;
|
||||
|
|
|
@ -17,6 +17,10 @@ import java.util.function.Consumer;
|
|||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.simibubi.create.content.logistics.trains.track.StandardBogeyTileEntity;
|
||||
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||
import org.apache.commons.lang3.mutable.MutableObject;
|
||||
|
||||
|
@ -124,7 +128,7 @@ public class Train {
|
|||
public int honkPitch;
|
||||
|
||||
public float accumulatedSteamRelease;
|
||||
|
||||
|
||||
int tickOffset;
|
||||
double[] stress;
|
||||
|
||||
|
@ -277,7 +281,7 @@ public class Train {
|
|||
int carriageCount = carriages.size();
|
||||
boolean stalled = false;
|
||||
double maxStress = 0;
|
||||
|
||||
|
||||
if (carriageWaitingForChunks != -1)
|
||||
distance = 0;
|
||||
|
||||
|
@ -317,7 +321,7 @@ public class Train {
|
|||
entries++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (entries > 0)
|
||||
actual = total / entries;
|
||||
|
@ -369,7 +373,7 @@ public class Train {
|
|||
.getLeadingPoint();
|
||||
|
||||
double totalStress = derailed ? 0 : leadingStress + trailingStress;
|
||||
|
||||
|
||||
boolean first = i == 0;
|
||||
boolean last = i == carriageCount - 1;
|
||||
int carriageType = first ? last ? Carriage.BOTH : Carriage.FIRST : last ? Carriage.LAST : Carriage.MIDDLE;
|
||||
|
@ -725,6 +729,15 @@ public class Train {
|
|||
.atLowerCornerOf(pos.relative(assemblyDirection, backwards ? offset + carriage.bogeySpacing : offset)));
|
||||
entity.disassemble();
|
||||
|
||||
for (CarriageBogey bogey : carriage.bogeys) {
|
||||
Vec3 bogeyPosition = bogey.getAnchorPosition();
|
||||
if (bogeyPosition == null) continue;
|
||||
BlockEntity be = level.getBlockEntity(new BlockPos(bogeyPosition));
|
||||
if (!(be instanceof StandardBogeyTileEntity sbte))
|
||||
continue;
|
||||
sbte.setBogeyData(bogey.bogeyData);
|
||||
}
|
||||
|
||||
offset += carriage.bogeySpacing;
|
||||
|
||||
if (i < carriageSpacing.size())
|
||||
|
|
|
@ -7,12 +7,13 @@ import java.util.UUID;
|
|||
import java.util.function.Supplier;
|
||||
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.content.logistics.trains.IBogeyBlock;
|
||||
import com.simibubi.create.content.logistics.trains.AbstractBogeyBlock;
|
||||
import com.simibubi.create.foundation.networking.SimplePacketBase;
|
||||
import com.simibubi.create.foundation.utility.Couple;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
import com.simibubi.create.foundation.utility.RegisteredObjects;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
@ -44,11 +45,12 @@ public class TrainPacket extends SimplePacketBase {
|
|||
int size = buffer.readVarInt();
|
||||
for (int i = 0; i < size; i++) {
|
||||
Couple<CarriageBogey> bogies = Couple.create(null, null);
|
||||
for (boolean first : Iterate.trueAndFalse) {
|
||||
if (!first && !buffer.readBoolean())
|
||||
for (boolean isFirst : Iterate.trueAndFalse) {
|
||||
if (!isFirst && !buffer.readBoolean())
|
||||
continue;
|
||||
IBogeyBlock type = (IBogeyBlock) ForgeRegistries.BLOCKS.getValue(buffer.readResourceLocation());
|
||||
bogies.set(first, new CarriageBogey(type, new TravellingPoint(), new TravellingPoint()));
|
||||
AbstractBogeyBlock type = (AbstractBogeyBlock) ForgeRegistries.BLOCKS.getValue(buffer.readResourceLocation());
|
||||
CompoundTag data = buffer.readNbt();
|
||||
bogies.set(isFirst, new CarriageBogey(type, data, new TravellingPoint(), new TravellingPoint()));
|
||||
}
|
||||
int spacing = buffer.readVarInt();
|
||||
carriages.add(new Carriage(bogies.getFirst(), bogies.getSecond(), spacing));
|
||||
|
@ -86,6 +88,7 @@ public class TrainPacket extends SimplePacketBase {
|
|||
}
|
||||
CarriageBogey bogey = carriage.bogeys.get(first);
|
||||
buffer.writeResourceLocation(RegisteredObjects.getKeyOrThrow((Block) bogey.type));
|
||||
buffer.writeNbt(bogey.bogeyData);
|
||||
}
|
||||
buffer.writeVarInt(carriage.bogeySpacing);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.ITr
|
|||
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
||||
import com.simibubi.create.content.logistics.block.depot.DepotBehaviour;
|
||||
import com.simibubi.create.content.logistics.block.display.DisplayLinkBlock;
|
||||
import com.simibubi.create.content.logistics.trains.IBogeyBlock;
|
||||
import com.simibubi.create.content.logistics.trains.AbstractBogeyBlock;
|
||||
import com.simibubi.create.content.logistics.trains.ITrackBlock;
|
||||
import com.simibubi.create.content.logistics.trains.TrackEdge;
|
||||
import com.simibubi.create.content.logistics.trains.TrackGraph;
|
||||
|
@ -38,6 +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.foundation.advancement.AllAdvancements;
|
||||
import com.simibubi.create.foundation.block.ProperWaterloggedBlock;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
|
@ -51,6 +52,7 @@ import com.simibubi.create.foundation.utility.WorldAttached;
|
|||
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
|
||||
import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser;
|
||||
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.BlockPos.MutableBlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
|
@ -65,7 +67,9 @@ 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;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.levelgen.structure.BoundingBox;
|
||||
|
@ -189,7 +193,7 @@ public class StationTileEntity extends SmartTileEntity implements ITransformable
|
|||
Direction assemblyDirection;
|
||||
int assemblyLength;
|
||||
int[] bogeyLocations;
|
||||
IBogeyBlock[] bogeyTypes;
|
||||
AbstractBogeyBlock[] bogeyTypes;
|
||||
int bogeyCount;
|
||||
|
||||
@Override
|
||||
|
@ -272,8 +276,20 @@ public class StationTileEntity extends SmartTileEntity implements ITransformable
|
|||
BlockPos bogeyPos = pos.relative(assemblyDirection, i)
|
||||
.offset(up);
|
||||
BlockState blockState = level.getBlockState(bogeyPos);
|
||||
if (blockState.getBlock() instanceof IBogeyBlock bogey) {
|
||||
level.setBlock(bogeyPos, bogey.getRotatedBlockState(blockState, Direction.DOWN), 3);
|
||||
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;
|
||||
}
|
||||
|
@ -370,7 +386,7 @@ public class StationTileEntity extends SmartTileEntity implements ITransformable
|
|||
if (bogeyLocations == null)
|
||||
bogeyLocations = new int[maxBogeyCount];
|
||||
if (bogeyTypes == null)
|
||||
bogeyTypes = new IBogeyBlock[maxBogeyCount];
|
||||
bogeyTypes = new AbstractBogeyBlock[maxBogeyCount];
|
||||
Arrays.fill(bogeyLocations, -1);
|
||||
Arrays.fill(bogeyTypes, null);
|
||||
|
||||
|
@ -385,7 +401,7 @@ public class StationTileEntity extends SmartTileEntity implements ITransformable
|
|||
}
|
||||
|
||||
BlockState potentialBogeyState = level.getBlockState(bogeyOffset.offset(currentPos));
|
||||
if (potentialBogeyState.getBlock() instanceof IBogeyBlock bogey && bogeyIndex < bogeyLocations.length) {
|
||||
if (potentialBogeyState.getBlock() instanceof AbstractBogeyBlock bogey && bogeyIndex < bogeyLocations.length) {
|
||||
bogeyTypes[bogeyIndex] = bogey;
|
||||
bogeyLocations[bogeyIndex] = i;
|
||||
bogeyIndex++;
|
||||
|
@ -591,9 +607,11 @@ public class StationTileEntity extends SmartTileEntity implements ITransformable
|
|||
return;
|
||||
}
|
||||
|
||||
IBogeyBlock typeOfFirstBogey = bogeyTypes[bogeyIndex];
|
||||
AbstractBogeyBlock typeOfFirstBogey = bogeyTypes[bogeyIndex];
|
||||
BlockPos firstBogeyPos = contraption.anchor;
|
||||
StandardBogeyTileEntity firstBogeyTileEntity = (StandardBogeyTileEntity) level.getBlockEntity(firstBogeyPos);
|
||||
CarriageBogey firstBogey =
|
||||
new CarriageBogey(typeOfFirstBogey, points.get(pointIndex), points.get(pointIndex + 1));
|
||||
new CarriageBogey(typeOfFirstBogey, firstBogeyTileEntity.getBogeyData(), points.get(pointIndex), points.get(pointIndex + 1));
|
||||
CarriageBogey secondBogey = null;
|
||||
BlockPos secondBogeyPos = contraption.getSecondBogeyPos();
|
||||
int bogeySpacing = 0;
|
||||
|
@ -605,10 +623,11 @@ public class StationTileEntity extends SmartTileEntity implements ITransformable
|
|||
contraptions.size() + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
StandardBogeyTileEntity secondBogeyTileEntity =
|
||||
(StandardBogeyTileEntity) level.getBlockEntity(secondBogeyPos);
|
||||
bogeySpacing = bogeyLocations[bogeyIndex + 1] - bogeyLocations[bogeyIndex];
|
||||
secondBogey = new CarriageBogey(bogeyTypes[bogeyIndex + 1], points.get(pointIndex + 2),
|
||||
points.get(pointIndex + 3));
|
||||
secondBogey = new CarriageBogey(bogeyTypes[bogeyIndex + 1], secondBogeyTileEntity.getBogeyData(),
|
||||
points.get(pointIndex + 2), points.get(pointIndex + 3));
|
||||
bogeyIndex++;
|
||||
|
||||
} else if (!typeOfFirstBogey.allowsSingleBogeyCarriage()) {
|
||||
|
|
|
@ -1,89 +1,30 @@
|
|||
package com.simibubi.create.content.logistics.trains.track;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
import com.jozufozu.flywheel.api.MaterialManager;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import com.mojang.math.Vector3f;
|
||||
import com.simibubi.create.AllBlockPartials;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.content.contraptions.relays.elementary.ShaftBlock;
|
||||
import com.simibubi.create.content.logistics.trains.IBogeyBlock;
|
||||
import com.simibubi.create.content.logistics.trains.entity.BogeyInstance;
|
||||
import com.simibubi.create.content.logistics.trains.entity.CarriageBogey;
|
||||
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.schematics.ISpecialBlockItemRequirement;
|
||||
import com.simibubi.create.content.schematics.ItemRequirement;
|
||||
import com.simibubi.create.content.schematics.ItemRequirement.ItemUseType;
|
||||
import com.simibubi.create.foundation.block.ITE;
|
||||
import com.simibubi.create.foundation.block.ProperWaterloggedBlock;
|
||||
import com.simibubi.create.foundation.render.CachedBufferer;
|
||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Direction.Axis;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.Rotation;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition.Builder;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.block.state.properties.EnumProperty;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
public class StandardBogeyBlock extends Block
|
||||
implements IBogeyBlock, ITE<StandardBogeyTileEntity>, ProperWaterloggedBlock, ISpecialBlockItemRequirement {
|
||||
public class StandardBogeyBlock extends AbstractBogeyBlock implements ITE<StandardBogeyTileEntity>, ProperWaterloggedBlock, ISpecialBlockItemRequirement {
|
||||
|
||||
public static final EnumProperty<Axis> AXIS = BlockStateProperties.HORIZONTAL_AXIS;
|
||||
private final boolean large;
|
||||
|
||||
public StandardBogeyBlock(Properties p_i48440_1_, boolean large) {
|
||||
super(p_i48440_1_);
|
||||
this.large = large;
|
||||
public StandardBogeyBlock(Properties props, BogeySizes.BogeySize size) {
|
||||
super(props, size);
|
||||
registerDefaultState(defaultBlockState().setValue(WATERLOGGED, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(Builder<Block, BlockState> builder) {
|
||||
builder.add(AXIS, WATERLOGGED);
|
||||
super.createBlockStateDefinition(builder);
|
||||
}
|
||||
|
||||
static final EnumSet<Direction> STICKY_X = EnumSet.of(Direction.EAST, Direction.WEST);
|
||||
static final EnumSet<Direction> STICKY_Z = EnumSet.of(Direction.SOUTH, Direction.NORTH);
|
||||
|
||||
@Override
|
||||
public EnumSet<Direction> getStickySurfaces(BlockGetter world, BlockPos pos, BlockState state) {
|
||||
return state.getValue(BlockStateProperties.HORIZONTAL_AXIS) == Axis.X ? STICKY_X : STICKY_Z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState updateShape(BlockState pState, Direction pDirection, BlockState pNeighborState,
|
||||
LevelAccessor pLevel, BlockPos pCurrentPos, BlockPos pNeighborPos) {
|
||||
updateWater(pLevel, pState, pCurrentPos);
|
||||
return pState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FluidState getFluidState(BlockState pState) {
|
||||
return fluidState(pState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getWheelPointSpacing() {
|
||||
return 2;
|
||||
|
@ -91,7 +32,7 @@ public class StandardBogeyBlock extends Block
|
|||
|
||||
@Override
|
||||
public double getWheelRadius() {
|
||||
return (large ? 12.5 : 6.5) / 16d;
|
||||
return (size == BogeySizes.LARGE ? 12.5 : 6.5) / 16d;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -99,125 +40,6 @@ public class StandardBogeyBlock extends Block
|
|||
return new Vec3(0, 7 / 32f, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowsSingleBogeyCarriage() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getMatchingBogey(Direction upDirection, boolean axisAlongFirst) {
|
||||
if (upDirection != Direction.UP)
|
||||
return null;
|
||||
return defaultBlockState().setValue(AXIS, axisAlongFirst ? Axis.X : Axis.Z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTrackAxisAlongFirstCoordinate(BlockState state) {
|
||||
return state.getValue(AXIS) == Axis.X;
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void render(BlockState state, float wheelAngle, PoseStack ms, float partialTicks, MultiBufferSource buffers,
|
||||
int light, int overlay) {
|
||||
if (state != null) {
|
||||
ms.translate(.5f, .5f, .5f);
|
||||
if (state.getValue(AXIS) == Axis.X)
|
||||
ms.mulPose(Vector3f.YP.rotationDegrees(90));
|
||||
}
|
||||
|
||||
ms.translate(0, -1.5 - 1 / 128f, 0);
|
||||
|
||||
VertexConsumer vb = buffers.getBuffer(RenderType.cutoutMipped());
|
||||
BlockState air = Blocks.AIR.defaultBlockState();
|
||||
|
||||
for (int i : Iterate.zeroAndOne)
|
||||
CachedBufferer.block(AllBlocks.SHAFT.getDefaultState()
|
||||
.setValue(ShaftBlock.AXIS, Axis.Z))
|
||||
.translate(-.5f, .25f, i * -1)
|
||||
.centre()
|
||||
.rotateZ(wheelAngle)
|
||||
.unCentre()
|
||||
.light(light)
|
||||
.renderInto(ms, vb);
|
||||
|
||||
if (large) {
|
||||
renderLargeBogey(wheelAngle, ms, light, vb, air);
|
||||
} else {
|
||||
renderBogey(wheelAngle, ms, light, vb, air);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderBogey(float wheelAngle, PoseStack ms, int light, VertexConsumer vb, BlockState air) {
|
||||
CachedBufferer.partial(AllBlockPartials.BOGEY_FRAME, air)
|
||||
.scale(1 - 1 / 512f)
|
||||
.light(light)
|
||||
.renderInto(ms, vb);
|
||||
|
||||
for (int side : Iterate.positiveAndNegative) {
|
||||
ms.pushPose();
|
||||
CachedBufferer.partial(AllBlockPartials.SMALL_BOGEY_WHEELS, air)
|
||||
.translate(0, 12 / 16f, side)
|
||||
.rotateX(wheelAngle)
|
||||
.light(light)
|
||||
.renderInto(ms, vb);
|
||||
ms.popPose();
|
||||
}
|
||||
}
|
||||
|
||||
private void renderLargeBogey(float wheelAngle, PoseStack ms, int light, VertexConsumer vb, BlockState air) {
|
||||
for (int i : Iterate.zeroAndOne)
|
||||
CachedBufferer.block(AllBlocks.SHAFT.getDefaultState()
|
||||
.setValue(ShaftBlock.AXIS, Axis.X))
|
||||
.translate(-.5f, .25f, .5f + i * -2)
|
||||
.centre()
|
||||
.rotateX(wheelAngle)
|
||||
.unCentre()
|
||||
.light(light)
|
||||
.renderInto(ms, vb);
|
||||
|
||||
CachedBufferer.partial(AllBlockPartials.BOGEY_DRIVE, air)
|
||||
.scale(1 - 1 / 512f)
|
||||
.light(light)
|
||||
.renderInto(ms, vb);
|
||||
CachedBufferer.partial(AllBlockPartials.BOGEY_PISTON, air)
|
||||
.translate(0, 0, 1 / 4f * Math.sin(AngleHelper.rad(wheelAngle)))
|
||||
.light(light)
|
||||
.renderInto(ms, vb);
|
||||
|
||||
ms.pushPose();
|
||||
CachedBufferer.partial(AllBlockPartials.LARGE_BOGEY_WHEELS, air)
|
||||
.translate(0, 1, 0)
|
||||
.rotateX(wheelAngle)
|
||||
.light(light)
|
||||
.renderInto(ms, vb);
|
||||
CachedBufferer.partial(AllBlockPartials.BOGEY_PIN, air)
|
||||
.translate(0, 1, 0)
|
||||
.rotateX(wheelAngle)
|
||||
.translate(0, 1 / 4f, 0)
|
||||
.rotateX(-wheelAngle)
|
||||
.light(light)
|
||||
.renderInto(ms, vb);
|
||||
ms.popPose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BogeyInstance createInstance(MaterialManager materialManager, CarriageBogey bogey) {
|
||||
if (large) {
|
||||
return new BogeyInstance.Drive(bogey, materialManager);
|
||||
} else {
|
||||
return new BogeyInstance.Frame(bogey, materialManager);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState rotate(BlockState pState, Rotation pRotation) {
|
||||
return switch (pRotation) {
|
||||
case COUNTERCLOCKWISE_90, CLOCKWISE_90 -> pState.cycle(AXIS);
|
||||
default -> pState;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getCloneItemStack(BlockState state, HitResult target, BlockGetter level, BlockPos pos,
|
||||
Player player) {
|
||||
|
@ -233,10 +55,4 @@ public class StandardBogeyBlock extends Block
|
|||
public BlockEntityType<? extends StandardBogeyTileEntity> getTileEntityType() {
|
||||
return AllTileEntities.BOGEY.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemRequirement getRequiredItems(BlockState state, BlockEntity te) {
|
||||
return new ItemRequirement(ItemUseType.CONSUME, AllBlocks.RAILWAY_CASING.asStack());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,40 +1,112 @@
|
|||
package com.simibubi.create.content.logistics.trains.track;
|
||||
|
||||
import com.simibubi.create.content.logistics.trains.IBogeyBlock;
|
||||
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 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 IBogeyBlock type))
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,9 +62,11 @@ import net.minecraftforge.eventbus.api.EventPriority;
|
|||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.LogicalSide;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
import net.minecraftforge.forgespi.language.IModFileInfo;
|
||||
import net.minecraftforge.forgespi.locating.IModFile;
|
||||
import net.minecraftforge.registries.NewRegistryEvent;
|
||||
|
||||
@EventBusSubscriber
|
||||
public class CommonEvents {
|
||||
|
@ -90,7 +92,7 @@ public class CommonEvents {
|
|||
ToolboxHandler.playerLogin(player);
|
||||
Create.RAILWAYS.playerLogin(player);
|
||||
}
|
||||
|
||||
|
||||
@SubscribeEvent
|
||||
public static void playerLoggedOut(PlayerLoggedOutEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
|
@ -166,7 +168,7 @@ public class CommonEvents {
|
|||
public static void onEntityEnterSection(EntityEvent.EnteringSection event) {
|
||||
CarriageEntityHandler.onEntityEnterSection(event);
|
||||
}
|
||||
|
||||
|
||||
@SubscribeEvent
|
||||
public static void addReloadListeners(AddReloadListenerEvent event) {
|
||||
event.addListener(RecipeFinder.LISTENER);
|
||||
|
@ -248,7 +250,5 @@ public class CommonEvents {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ import com.simibubi.create.content.curiosities.deco.SlidingDoorMovementBehaviour
|
|||
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelBlock;
|
||||
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelBlock.Shape;
|
||||
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelItem;
|
||||
import com.simibubi.create.content.logistics.trains.IBogeyBlock;
|
||||
import com.simibubi.create.content.logistics.trains.AbstractBogeyBlock;
|
||||
import com.simibubi.create.content.logistics.trains.track.StandardBogeyBlock;
|
||||
import com.simibubi.create.foundation.block.BlockStressDefaults;
|
||||
import com.simibubi.create.foundation.block.ItemUseOverrides;
|
||||
|
@ -88,7 +88,7 @@ public class BuilderTransformers {
|
|||
.blockstate((c, p) -> BlockStateGen.horizontalAxisBlock(c, p, s -> p.models()
|
||||
.getExistingFile(p.modLoc("block/track/bogey/top"))))
|
||||
.loot((p, l) -> p.dropOther(l, AllBlocks.RAILWAY_CASING.get()))
|
||||
.onRegister(block -> IBogeyBlock.register(RegisteredObjects.getKeyOrThrow(block)));
|
||||
.onRegister(block -> AbstractBogeyBlock.register(RegisteredObjects.getKeyOrThrow(block)));
|
||||
}
|
||||
|
||||
public static <B extends TrapDoorBlock, P> NonNullUnaryOperator<BlockBuilder<B, P>> trapdoor(boolean orientable) {
|
||||
|
|
|
@ -16,8 +16,10 @@ import com.simibubi.create.CreateClient;
|
|||
import com.simibubi.create.content.AllSections;
|
||||
import com.simibubi.create.content.contraptions.fluids.VirtualFluid;
|
||||
import com.simibubi.create.content.contraptions.relays.encased.CasingConnectivity;
|
||||
import com.simibubi.create.content.logistics.trains.entity.BogeyStyle;
|
||||
import com.simibubi.create.foundation.block.connected.CTModel;
|
||||
import com.simibubi.create.foundation.block.connected.ConnectedTextureBehaviour;
|
||||
import com.simibubi.create.foundation.utility.CreateRegistry;
|
||||
import com.simibubi.create.foundation.utility.RegisteredObjects;
|
||||
import com.tterrag.registrate.AbstractRegistrate;
|
||||
import com.tterrag.registrate.builders.BlockBuilder;
|
||||
|
|
|
@ -45,4 +45,13 @@ public class Iterate {
|
|||
public static List<BlockPos> hereBelowAndAbove(BlockPos pos) {
|
||||
return Arrays.asList(pos, pos.below(), pos.above());
|
||||
}
|
||||
|
||||
public static <T> T cycleValue(List<T> list, T current) {
|
||||
int currentIndex = list.indexOf(current);
|
||||
if (currentIndex == -1) {
|
||||
throw new IllegalArgumentException("Current value not found in list");
|
||||
}
|
||||
int nextIndex = (currentIndex + 1) % list.size();
|
||||
return list.get(nextIndex);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import net.minecraft.nbt.FloatTag;
|
|||
import net.minecraft.nbt.IntTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
|
||||
|
@ -108,4 +109,18 @@ public class NBTHelper {
|
|||
return new CompoundTag();
|
||||
}
|
||||
|
||||
public static void writeResourceLocation(CompoundTag nbt, String key, ResourceLocation location) {
|
||||
// Ensure correct format
|
||||
nbt.putString(key, location.toString());
|
||||
}
|
||||
|
||||
public static ResourceLocation readResourceLocation(CompoundTag nbt, String key) {
|
||||
if (!nbt.contains(key))
|
||||
return null;
|
||||
String[] data = nbt.getString(key).split(":");
|
||||
if (data.length != 2)
|
||||
return null;
|
||||
return new ResourceLocation(data[0], data[1]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue