Track API maybe?

Not yet tested, but it is progress
This commit is contained in:
techno-sam 2023-04-06 21:13:54 -07:00
parent 5ba30d6a85
commit 2a59fd7e8a
21 changed files with 414 additions and 64 deletions

View file

@ -207,6 +207,7 @@ 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.ItemVaultCTBehaviour;
import com.simibubi.create.content.logistics.block.vault.ItemVaultItem; import com.simibubi.create.content.logistics.block.vault.ItemVaultItem;
import com.simibubi.create.content.logistics.item.LecternControllerBlock; import com.simibubi.create.content.logistics.item.LecternControllerBlock;
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.display.FlapDisplayBlock;
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType; import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType;
import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBlockItem; import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBlockItem;
@ -1500,7 +1501,7 @@ public class AllBlocks {
.transform(customItemModel()) .transform(customItemModel())
.register(); .register();
public static final BlockEntry<TrackBlock> TRACK = REGISTRATE.block("track", TrackBlock::new) public static final BlockEntry<TrackBlock> TRACK = REGISTRATE.block("track", TrackMaterial.ANDESITE::create)
.initialProperties(Material.STONE) .initialProperties(Material.STONE)
.properties(p -> p.color(MaterialColor.METAL) .properties(p -> p.color(MaterialColor.METAL)
.strength(0.8F) .strength(0.8F)
@ -1510,6 +1511,8 @@ public class AllBlocks {
.transform(pickaxeOnly()) .transform(pickaxeOnly())
.blockstate(new TrackBlockStateGenerator()::generate) .blockstate(new TrackBlockStateGenerator()::generate)
.tag(AllBlockTags.RELOCATION_NOT_SUPPORTED.tag) .tag(AllBlockTags.RELOCATION_NOT_SUPPORTED.tag)
.tag(AllBlockTags.TRACKS.tag)
.tag(AllBlockTags.GIRDABLE_TRACKS.tag)
.lang("Train Track") .lang("Train Track")
.item(TrackBlockItem::new) .item(TrackBlockItem::new)
.model((c, p) -> p.generated(c, Create.asResource("item/" + c.getName()))) .model((c, p) -> p.generated(c, Create.asResource("item/" + c.getName())))

View file

@ -107,6 +107,8 @@ public class AllTags {
SAFE_NBT, SAFE_NBT,
SEATS, SEATS,
TOOLBOXES, TOOLBOXES,
TRACKS,
GIRDABLE_TRACKS,
TREE_ATTACHMENTS, TREE_ATTACHMENTS,
VALVE_HANDLES, VALVE_HANDLES,
WINDMILL_SAILS, WINDMILL_SAILS,
@ -155,6 +157,10 @@ public class AllTags {
.is(tag); .is(tag);
} }
public boolean matches(ItemStack stack) {
return stack != null && stack.getItem() instanceof BlockItem blockItem && matches(blockItem.getBlock());
}
public boolean matches(BlockState state) { public boolean matches(BlockState state) {
return state.is(tag); return state.is(tag);
} }

View file

@ -182,6 +182,7 @@ import com.simibubi.create.content.logistics.block.vault.ItemVaultTileEntity;
import com.simibubi.create.content.logistics.item.LecternControllerRenderer; import com.simibubi.create.content.logistics.item.LecternControllerRenderer;
import com.simibubi.create.content.logistics.item.LecternControllerTileEntity; import com.simibubi.create.content.logistics.item.LecternControllerTileEntity;
import com.simibubi.create.content.logistics.trains.BogeyTileEntityRenderer; import com.simibubi.create.content.logistics.trains.BogeyTileEntityRenderer;
import com.simibubi.create.content.logistics.trains.TrackMaterial;
import com.simibubi.create.content.logistics.trains.management.display.FlapDisplayRenderer; import com.simibubi.create.content.logistics.trains.management.display.FlapDisplayRenderer;
import com.simibubi.create.content.logistics.trains.management.display.FlapDisplayTileEntity; import com.simibubi.create.content.logistics.trains.management.display.FlapDisplayTileEntity;
import com.simibubi.create.content.logistics.trains.management.edgePoint.observer.TrackObserverRenderer; import com.simibubi.create.content.logistics.trains.management.edgePoint.observer.TrackObserverRenderer;
@ -201,6 +202,7 @@ import com.simibubi.create.content.schematics.block.SchematicannonRenderer;
import com.simibubi.create.content.schematics.block.SchematicannonTileEntity; import com.simibubi.create.content.schematics.block.SchematicannonTileEntity;
import com.simibubi.create.foundation.tileEntity.renderer.SmartTileEntityRenderer; import com.simibubi.create.foundation.tileEntity.renderer.SmartTileEntityRenderer;
import com.tterrag.registrate.util.entry.BlockEntityEntry; import com.tterrag.registrate.util.entry.BlockEntityEntry;
import com.tterrag.registrate.util.entry.BlockEntry;
public class AllTileEntities { public class AllTileEntities {
@ -781,7 +783,7 @@ public class AllTileEntities {
.tileEntity("track", TrackTileEntity::new) .tileEntity("track", TrackTileEntity::new)
.instance(() -> TrackInstance::new) .instance(() -> TrackInstance::new)
.renderer(() -> TrackRenderer::new) .renderer(() -> TrackRenderer::new)
.validBlocks(AllBlocks.TRACK) .validBlocks(TrackMaterial.allBlocks().toArray(new BlockEntry<?>[0]))
.register(); .register();
public static final BlockEntityEntry<FakeTrackTileEntity> FAKE_TRACK = REGISTRATE public static final BlockEntityEntry<FakeTrackTileEntity> FAKE_TRACK = REGISTRATE

View file

@ -4,7 +4,7 @@ import javax.annotation.Nullable;
import com.jozufozu.flywheel.api.MaterialManager; import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld; import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllTags;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance; import com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionMatrices; import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionMatrices;
@ -61,7 +61,7 @@ public class DrillMovementBehaviour extends BlockBreakingMovementBehaviour {
@Override @Override
public boolean canBreak(Level world, BlockPos breakingPos, BlockState state) { public boolean canBreak(Level world, BlockPos breakingPos, BlockState state) {
return super.canBreak(world, breakingPos, state) && !state.getCollisionShape(world, breakingPos) return super.canBreak(world, breakingPos, state) && !state.getCollisionShape(world, breakingPos)
.isEmpty() && !AllBlocks.TRACK.has(state); .isEmpty() && !AllTags.AllBlockTags.TRACKS.matches(state);
} }
} }

View file

@ -3,8 +3,8 @@ package com.simibubi.create.content.contraptions.components.press;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllRecipeTypes; import com.simibubi.create.AllRecipeTypes;
import com.simibubi.create.AllTags;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.contraptions.components.crafter.MechanicalCraftingRecipe; import com.simibubi.create.content.contraptions.components.crafter.MechanicalCraftingRecipe;
import com.simibubi.create.content.contraptions.components.press.PressingBehaviour.Mode; import com.simibubi.create.content.contraptions.components.press.PressingBehaviour.Mode;
@ -69,7 +69,7 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity implemen
public void onItemPressed(ItemStack result) { public void onItemPressed(ItemStack result) {
award(AllAdvancements.PRESS); award(AllAdvancements.PRESS);
if (AllBlocks.TRACK.isIn(result)) if (AllTags.AllBlockTags.TRACKS.matches(result))
tracksCreated += result.getCount(); tracksCreated += result.getCount();
if (tracksCreated >= 1000) { if (tracksCreated >= 1000) {
award(AllAdvancements.TRACK_CRAFTING); award(AllAdvancements.TRACK_CRAFTING);

View file

@ -8,6 +8,7 @@ import java.util.Random;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllItems; import com.simibubi.create.AllItems;
import com.simibubi.create.AllShapes; import com.simibubi.create.AllShapes;
import com.simibubi.create.AllTags;
import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.fluids.pipes.BracketBlock; import com.simibubi.create.content.contraptions.fluids.pipes.BracketBlock;
import com.simibubi.create.content.contraptions.relays.elementary.BracketedTileEntityBehaviour; import com.simibubi.create.content.contraptions.relays.elementary.BracketedTileEntityBehaviour;
@ -224,7 +225,7 @@ public class GirderBlock extends Block implements SimpleWaterloggedBlock, IWrenc
for (Direction d2 : Iterate.directionsInAxis(axis == Axis.X ? Axis.Z : Axis.X)) { for (Direction d2 : Iterate.directionsInAxis(axis == Axis.X ? Axis.Z : Axis.X)) {
BlockState above = level.getBlockState(pos.above() BlockState above = level.getBlockState(pos.above()
.relative(d2)); .relative(d2));
if (AllBlocks.TRACK.has(above)) { if (AllTags.AllBlockTags.GIRDABLE_TRACKS.matches(above)) {
TrackShape shape = above.getValue(TrackBlock.SHAPE); TrackShape shape = above.getValue(TrackBlock.SHAPE);
if (shape == (axis == Axis.X ? TrackShape.XO : TrackShape.ZO)) if (shape == (axis == Axis.X ? TrackShape.XO : TrackShape.ZO))
state = state.setValue(updateProperty, true); state = state.setValue(updateProperty, true);

View file

@ -9,13 +9,13 @@ import java.util.Optional;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllItems; import com.simibubi.create.AllItems;
import com.simibubi.create.content.curiosities.tools.BlueprintEntity.BlueprintCraftingInventory; import com.simibubi.create.content.curiosities.tools.BlueprintEntity.BlueprintCraftingInventory;
import com.simibubi.create.content.curiosities.tools.BlueprintEntity.BlueprintSection; import com.simibubi.create.content.curiosities.tools.BlueprintEntity.BlueprintSection;
import com.simibubi.create.content.logistics.item.filter.AttributeFilterContainer.WhitelistMode; import com.simibubi.create.content.logistics.item.filter.AttributeFilterContainer.WhitelistMode;
import com.simibubi.create.content.logistics.item.filter.FilterItem; import com.simibubi.create.content.logistics.item.filter.FilterItem;
import com.simibubi.create.content.logistics.item.filter.ItemAttribute; import com.simibubi.create.content.logistics.item.filter.ItemAttribute;
import com.simibubi.create.content.logistics.trains.IHasTrackMaterial;
import com.simibubi.create.content.logistics.trains.track.TrackPlacement.PlacementInfo; import com.simibubi.create.content.logistics.trains.track.TrackPlacement.PlacementInfo;
import com.simibubi.create.foundation.gui.AllGuiTextures; import com.simibubi.create.foundation.gui.AllGuiTextures;
import com.simibubi.create.foundation.gui.element.GuiGameElement; import com.simibubi.create.foundation.gui.element.GuiGameElement;
@ -106,7 +106,7 @@ public class BlueprintOverlayRenderer {
int tracks = info.requiredTracks; int tracks = info.requiredTracks;
while (tracks > 0) { while (tracks > 0) {
ingredients.add(Pair.of(AllBlocks.TRACK.asStack(Math.min(64, tracks)), info.hasRequiredTracks)); ingredients.add(Pair.of(((IHasTrackMaterial) info).getMaterial().getTrackBlock().asStack(Math.min(64, tracks)), info.hasRequiredTracks));
tracks -= 64; tracks -= 64;
} }

View file

@ -31,7 +31,7 @@ import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
public class BezierConnection implements Iterable<BezierConnection.Segment> { public class BezierConnection implements Iterable<BezierConnection.Segment>, IHasTrackMaterial {
public Couple<BlockPos> tePositions; public Couple<BlockPos> tePositions;
public Couple<Vec3> starts; public Couple<Vec3> starts;
@ -39,6 +39,7 @@ public class BezierConnection implements Iterable<BezierConnection.Segment> {
public Couple<Vec3> normals; public Couple<Vec3> normals;
public boolean primary; public boolean primary;
public boolean hasGirder; public boolean hasGirder;
protected TrackMaterial trackMaterial;
// runtime // runtime
@ -55,19 +56,20 @@ public class BezierConnection implements Iterable<BezierConnection.Segment> {
private AABB bounds; private AABB bounds;
public BezierConnection(Couple<BlockPos> positions, Couple<Vec3> starts, Couple<Vec3> axes, Couple<Vec3> normals, public BezierConnection(Couple<BlockPos> positions, Couple<Vec3> starts, Couple<Vec3> axes, Couple<Vec3> normals,
boolean primary, boolean girder) { boolean primary, boolean girder, TrackMaterial material) {
tePositions = positions; tePositions = positions;
this.starts = starts; this.starts = starts;
this.axes = axes; this.axes = axes;
this.normals = normals; this.normals = normals;
this.primary = primary; this.primary = primary;
this.hasGirder = girder; this.hasGirder = girder;
this.trackMaterial = material;
resolved = false; resolved = false;
} }
public BezierConnection secondary() { public BezierConnection secondary() {
return new BezierConnection(tePositions.swap(), starts.swap(), axes.swap(), normals.swap(), !primary, return new BezierConnection(tePositions.swap(), starts.swap(), axes.swap(), normals.swap(), !primary,
hasGirder); hasGirder, trackMaterial);
} }
public BezierConnection(CompoundTag compound, BlockPos localTo) { public BezierConnection(CompoundTag compound, BlockPos localTo) {
@ -77,7 +79,7 @@ public class BezierConnection implements Iterable<BezierConnection.Segment> {
.map(v -> v.add(Vec3.atLowerCornerOf(localTo))), .map(v -> v.add(Vec3.atLowerCornerOf(localTo))),
Couple.deserializeEach(compound.getList("Axes", Tag.TAG_COMPOUND), VecHelper::readNBTCompound), Couple.deserializeEach(compound.getList("Axes", Tag.TAG_COMPOUND), VecHelper::readNBTCompound),
Couple.deserializeEach(compound.getList("Normals", Tag.TAG_COMPOUND), VecHelper::readNBTCompound), Couple.deserializeEach(compound.getList("Normals", Tag.TAG_COMPOUND), VecHelper::readNBTCompound),
compound.getBoolean("Primary"), compound.getBoolean("Girder")); compound.getBoolean("Primary"), compound.getBoolean("Girder"), TrackMaterial.deserialize(compound.getString("Material")));
} }
public CompoundTag write(BlockPos localTo) { public CompoundTag write(BlockPos localTo) {
@ -91,13 +93,14 @@ public class BezierConnection implements Iterable<BezierConnection.Segment> {
compound.put("Starts", starts.serializeEach(VecHelper::writeNBTCompound)); compound.put("Starts", starts.serializeEach(VecHelper::writeNBTCompound));
compound.put("Axes", axes.serializeEach(VecHelper::writeNBTCompound)); compound.put("Axes", axes.serializeEach(VecHelper::writeNBTCompound));
compound.put("Normals", normals.serializeEach(VecHelper::writeNBTCompound)); compound.put("Normals", normals.serializeEach(VecHelper::writeNBTCompound));
compound.putString("Material", getMaterial().id.toString());
return compound; return compound;
} }
public BezierConnection(FriendlyByteBuf buffer) { public BezierConnection(FriendlyByteBuf buffer) {
this(Couple.create(buffer::readBlockPos), Couple.create(() -> VecHelper.read(buffer)), this(Couple.create(buffer::readBlockPos), Couple.create(() -> VecHelper.read(buffer)),
Couple.create(() -> VecHelper.read(buffer)), Couple.create(() -> VecHelper.read(buffer)), Couple.create(() -> VecHelper.read(buffer)), Couple.create(() -> VecHelper.read(buffer)),
buffer.readBoolean(), buffer.readBoolean()); buffer.readBoolean(), buffer.readBoolean(), TrackMaterial.deserialize(buffer.readUtf()));
} }
public void write(FriendlyByteBuf buffer) { public void write(FriendlyByteBuf buffer) {
@ -107,6 +110,7 @@ public class BezierConnection implements Iterable<BezierConnection.Segment> {
normals.forEach(v -> VecHelper.write(v, buffer)); normals.forEach(v -> VecHelper.write(v, buffer));
buffer.writeBoolean(primary); buffer.writeBoolean(primary);
buffer.writeBoolean(hasGirder); buffer.writeBoolean(hasGirder);
buffer.writeUtf(getMaterial().id.toString());
} }
public BlockPos getKey() { public BlockPos getKey() {
@ -300,7 +304,7 @@ public class BezierConnection implements Iterable<BezierConnection.Segment> {
Inventory inv = player.getInventory(); Inventory inv = player.getInventory();
int tracks = getTrackItemCost(); int tracks = getTrackItemCost();
while (tracks > 0) { while (tracks > 0) {
inv.placeItemBackInInventory(AllBlocks.TRACK.asStack(Math.min(64, tracks))); inv.placeItemBackInInventory(getMaterial().getTrackBlock().asStack(Math.min(64, tracks)));
tracks -= 64; tracks -= 64;
} }
int girders = getGirderItemCost(); int girders = getGirderItemCost();
@ -328,7 +332,7 @@ public class BezierConnection implements Iterable<BezierConnection.Segment> {
continue; continue;
Vec3 v = VecHelper.offsetRandomly(segment.position, level.random, .125f) Vec3 v = VecHelper.offsetRandomly(segment.position, level.random, .125f)
.add(origin); .add(origin);
ItemEntity entity = new ItemEntity(level, v.x, v.y, v.z, AllBlocks.TRACK.asStack()); ItemEntity entity = new ItemEntity(level, v.x, v.y, v.z, getMaterial().getTrackBlock().asStack());
entity.setDefaultPickUpDelay(); entity.setDefaultPickUpDelay();
level.addFreshEntity(entity); level.addFreshEntity(entity);
if (!hasGirder) if (!hasGirder)
@ -342,7 +346,7 @@ public class BezierConnection implements Iterable<BezierConnection.Segment> {
} }
public void spawnDestroyParticles(Level level) { public void spawnDestroyParticles(Level level) {
BlockParticleOption data = new BlockParticleOption(ParticleTypes.BLOCK, AllBlocks.TRACK.getDefaultState()); BlockParticleOption data = new BlockParticleOption(ParticleTypes.BLOCK, getMaterial().getTrackBlock().getDefaultState());
BlockParticleOption girderData = BlockParticleOption girderData =
new BlockParticleOption(ParticleTypes.BLOCK, AllBlocks.METAL_GIRDER.getDefaultState()); new BlockParticleOption(ParticleTypes.BLOCK, AllBlocks.METAL_GIRDER.getDefaultState());
if (!(level instanceof ServerLevel slevel)) if (!(level instanceof ServerLevel slevel))
@ -360,6 +364,19 @@ public class BezierConnection implements Iterable<BezierConnection.Segment> {
} }
} }
@Override
public TrackMaterial getMaterial() {
if (trackMaterial == null) {
trackMaterial = TrackMaterial.ANDESITE;
}
return trackMaterial;
}
@Override
public void setMaterial(TrackMaterial material) {
trackMaterial = material;
}
public static class Segment { public static class Segment {
public int index; public int index;

View file

@ -0,0 +1,16 @@
package com.simibubi.create.content.logistics.trains;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.Item;
public interface IHasTrackMaterial {
TrackMaterial getMaterial();
default void setMaterial(TrackMaterial material) {}
static TrackMaterial fromItem(Item item) {
if (item instanceof BlockItem blockItem && blockItem.getBlock() instanceof IHasTrackMaterial hasTrackMaterial)
return hasTrackMaterial.getMaterial();
return TrackMaterial.ANDESITE;
}
}

View file

@ -0,0 +1,118 @@
package com.simibubi.create.content.logistics.trains;
import com.jozufozu.flywheel.core.PartialModel;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.track.TrackBlock;
import com.tterrag.registrate.util.entry.BlockEntry;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraftforge.common.util.Lazy;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
import static com.simibubi.create.content.logistics.trains.TrackMaterialFactory.make;
public class TrackMaterial {
public static final List<TrackMaterial> ALL = new ArrayList<>();
public static final TrackMaterial ANDESITE = make(Create.asResource("andesite"))
.lang("Andesite")
.block(Lazy.of(() -> AllBlocks.TRACK))
.particle(Create.asResource("block/palettes/stone_types/polished/andesite_cut_polished"))
.setBuiltin()
.build();
public final ResourceLocation id;
public final String langName;
public final Supplier<BlockEntry<? extends TrackBlock>> trackBlock;
public final Ingredient sleeperIngredient;
public final Ingredient railsIngredient;
public final ResourceLocation particle;
public final TrackType trackType;
public final TrackModelHolder modelHolder;
public TrackMaterial(ResourceLocation id, String langName, Supplier<BlockEntry<? extends TrackBlock>> trackBlock, ResourceLocation particle, Ingredient sleeperIngredient, Ingredient railsIngredient, TrackType trackType, TrackModelHolder modelHolder) {
this.id = id;
this.langName = langName;
this.trackBlock = trackBlock;
this.sleeperIngredient = sleeperIngredient;
this.railsIngredient = railsIngredient;
this.particle = particle;
this.trackType = trackType;
this.modelHolder = modelHolder;
ALL.add(this);
}
public BlockEntry<? extends TrackBlock> getTrackBlock() {
return this.trackBlock.get();
}
public TrackBlock create(BlockBehaviour.Properties properties) {
return this.trackType.factory.create(properties, this);
}
public boolean isCustom(String modId) {
return this.id.getNamespace().equals(modId);
}
public static TrackMaterial[] allCustom(String modid) {
return ALL.stream().filter(tm -> tm.isCustom(modid)).toArray(TrackMaterial[]::new);
}
public static List<BlockEntry<?>> allCustomBlocks(String modid) {
List<BlockEntry<?>> list = new ArrayList<>();
for (TrackMaterial material : allCustom(modid)) {
list.add(material.getTrackBlock());
}
return list;
}
public static List<BlockEntry<?>> allBlocks() {
List<BlockEntry<?>> list = new ArrayList<>();
for (TrackMaterial material : ALL) {
list.add(material.getTrackBlock());
}
return list;
}
public String resourceName() {
return this.id.getPath();
}
public static TrackMaterial deserialize(String serializedName) {
ResourceLocation id = new ResourceLocation(serializedName);
for (TrackMaterial material : ALL) {
if (material.id.equals(id))
return material;
}
return ANDESITE;
}
public static class TrackType {
@FunctionalInterface
protected interface TrackBlockFactory {
TrackBlock create(BlockBehaviour.Properties properties, TrackMaterial material);
}
public static final TrackType STANDARD = new TrackType(Create.asResource("standard"), TrackBlock::new);
public final ResourceLocation id;
protected final TrackBlockFactory factory;
public TrackType(ResourceLocation id, TrackBlockFactory factory) {
this.id = id;
this.factory = factory;
}
}
public record TrackModelHolder(PartialModel tie, PartialModel segment_left, PartialModel segment_right) {
static final TrackModelHolder DEFAULT = new TrackModelHolder(AllBlockPartials.TRACK_TIE, AllBlockPartials.TRACK_SEGMENT_LEFT, AllBlockPartials.TRACK_SEGMENT_RIGHT);
}
}

View file

@ -0,0 +1,118 @@
package com.simibubi.create.content.logistics.trains;
import com.jozufozu.flywheel.core.PartialModel;
import com.simibubi.create.AllTags;
import com.simibubi.create.content.logistics.trains.track.TrackBlock;
import com.tterrag.registrate.util.entry.BlockEntry;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.level.ItemLike;
import java.util.function.Supplier;
import java.util.stream.Stream;
public class TrackMaterialFactory {
private final ResourceLocation id;
private String langName;
private Supplier<BlockEntry<? extends TrackBlock>> trackBlock;
private Ingredient sleeperIngredient = Ingredient.EMPTY;
private Ingredient railsIngredient = Ingredient.fromValues(Stream.of(new Ingredient.TagValue(AllTags.forgeItemTag("nuggets/iron")), new Ingredient.TagValue(AllTags.forgeItemTag("nuggets/zinc"))));
private ResourceLocation particle;
private TrackMaterial.TrackType trackType = TrackMaterial.TrackType.STANDARD;
private TrackMaterial.TrackModelHolder modelHolder = null;
private PartialModel tieModel = null;
private PartialModel leftSegmentModel = null;
private PartialModel rightSegmentModel = null;
public TrackMaterialFactory(ResourceLocation id) {
this.id = id;
}
public static TrackMaterialFactory make(ResourceLocation id) { // Convenience function for static import
return new TrackMaterialFactory(id);
}
public TrackMaterialFactory lang(String langName) {
this.langName = langName;
return this;
}
public TrackMaterialFactory block(Supplier<BlockEntry<? extends TrackBlock>> trackBlock) {
this.trackBlock = trackBlock;
return this;
}
public TrackMaterialFactory setBuiltin() {
this.modelHolder = TrackMaterial.TrackModelHolder.DEFAULT;
return this;
}
public TrackMaterialFactory sleeper(Ingredient sleeperIngredient) {
this.sleeperIngredient = sleeperIngredient;
return this;
}
public TrackMaterialFactory sleeper(ItemLike... items) {
this.sleeperIngredient = Ingredient.of(items);
return this;
}
public TrackMaterialFactory rails(Ingredient railsIngredient) {
this.railsIngredient = railsIngredient;
return this;
}
public TrackMaterialFactory rails(ItemLike... items) {
this.railsIngredient = Ingredient.of(items);
return this;
}
public TrackMaterialFactory noRecipeGen() {
this.railsIngredient = Ingredient.EMPTY;
this.sleeperIngredient = Ingredient.EMPTY;
return this;
}
public TrackMaterialFactory particle(ResourceLocation particle) {
this.particle = particle;
return this;
}
public TrackMaterialFactory trackType(TrackMaterial.TrackType trackType) {
this.trackType = trackType;
return this;
}
public TrackMaterialFactory defaultModels() {
String namespace = id.getNamespace();
String prefix = "block/track/" + id.getPath() + "/";
tieModel = new PartialModel(new ResourceLocation(namespace, prefix + "tie"));
leftSegmentModel = new PartialModel(new ResourceLocation(namespace, prefix + "segment_left"));
rightSegmentModel = new PartialModel(new ResourceLocation(namespace, prefix + "segment_right"));
return this;
}
public TrackMaterialFactory customModels(PartialModel tieModel, PartialModel leftSegmentModel, PartialModel rightSegmentModel) {
this.tieModel = tieModel;
this.leftSegmentModel = leftSegmentModel;
this.rightSegmentModel = rightSegmentModel;
return this;
}
public TrackMaterial build() {
assert trackBlock != null;
assert langName != null;
assert particle != null;
assert trackType != null;
assert sleeperIngredient != null;
assert railsIngredient != null;
assert id != null;
assert modelHolder != null;
if (tieModel != null || leftSegmentModel != null || rightSegmentModel != null) {
assert tieModel != null && leftSegmentModel != null && rightSegmentModel != null;
modelHolder = new TrackMaterial.TrackModelHolder(tieModel, leftSegmentModel, rightSegmentModel);
}
return new TrackMaterial(id, langName, trackBlock, particle, sleeperIngredient, railsIngredient, trackType, modelHolder);
}
}

View file

@ -1,7 +1,7 @@
package com.simibubi.create.content.logistics.trains.track; package com.simibubi.create.content.logistics.trains.track;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllItems; import com.simibubi.create.AllItems;
import com.simibubi.create.AllTags;
import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBlockItem; import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBlockItem;
import com.simibubi.create.content.logistics.trains.track.TrackBlockOutline.BezierPointSelection; import com.simibubi.create.content.logistics.trains.track.TrackBlockOutline.BezierPointSelection;
import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.networking.AllPackets;
@ -117,7 +117,7 @@ public class CurvedTrackInteraction {
if (event.isUseItem()) { if (event.isUseItem()) {
ItemStack heldItem = player.getMainHandItem(); ItemStack heldItem = player.getMainHandItem();
Item item = heldItem.getItem(); Item item = heldItem.getItem();
if (AllBlocks.TRACK.isIn(heldItem)) { if (AllTags.AllBlockTags.TRACKS.matches(heldItem)) {
player.displayClientMessage(Lang.translateDirect("track.turn_start") player.displayClientMessage(Lang.translateDirect("track.turn_start")
.withStyle(ChatFormatting.RED), true); .withStyle(ChatFormatting.RED), true);
player.swing(InteractionHand.MAIN_HAND); player.swing(InteractionHand.MAIN_HAND);

View file

@ -2,7 +2,7 @@ package com.simibubi.create.content.logistics.trains.track;
import java.util.function.Supplier; import java.util.function.Supplier;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllTags;
import com.simibubi.create.foundation.networking.SimplePacketBase; import com.simibubi.create.foundation.networking.SimplePacketBase;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
@ -39,7 +39,7 @@ public class PlaceExtendedCurvePacket extends SimplePacketBase {
ctx.enqueueWork(() -> { ctx.enqueueWork(() -> {
ServerPlayer sender = ctx.getSender(); ServerPlayer sender = ctx.getSender();
ItemStack stack = sender.getItemInHand(mainHand ? InteractionHand.MAIN_HAND : InteractionHand.OFF_HAND); ItemStack stack = sender.getItemInHand(mainHand ? InteractionHand.MAIN_HAND : InteractionHand.OFF_HAND);
if (!AllBlocks.TRACK.isIn(stack) || !stack.hasTag()) if (!AllTags.AllBlockTags.TRACKS.matches(stack) || !stack.hasTag())
return; return;
CompoundTag tag = stack.getTag(); CompoundTag tag = stack.getTag();
tag.putBoolean("ExtendCurve", true); tag.putBoolean("ExtendCurve", true);

View file

@ -11,6 +11,7 @@ import static com.simibubi.create.AllShapes.TRACK_ORTHO_LONG;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -19,6 +20,11 @@ import java.util.Random;
import java.util.Set; import java.util.Set;
import java.util.function.Consumer; import java.util.function.Consumer;
import com.simibubi.create.AllTags;
import com.simibubi.create.content.logistics.trains.IHasTrackMaterial;
import com.simibubi.create.content.logistics.trains.TrackMaterial;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
@ -108,18 +114,23 @@ import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.IBlockRenderProperties; import net.minecraftforge.client.IBlockRenderProperties;
//init //init
public class TrackBlock extends Block public class TrackBlock extends Block
implements ITE<TrackTileEntity>, IWrenchable, ITrackBlock, ISpecialBlockItemRequirement, ProperWaterloggedBlock { implements ITE<TrackTileEntity>, IWrenchable, ITrackBlock, ISpecialBlockItemRequirement, ProperWaterloggedBlock, IHasTrackMaterial {
public static final EnumProperty<TrackShape> SHAPE = EnumProperty.create("shape", TrackShape.class); public static final EnumProperty<TrackShape> SHAPE = EnumProperty.create("shape", TrackShape.class);
public static final BooleanProperty HAS_TE = BooleanProperty.create("turn"); public static final BooleanProperty HAS_TE = BooleanProperty.create("turn");
public TrackBlock(Properties p_49795_) { protected final TrackMaterial material;
public TrackBlock(Properties p_49795_, TrackMaterial material) {
super(p_49795_); super(p_49795_);
registerDefaultState(defaultBlockState().setValue(SHAPE, TrackShape.ZO) registerDefaultState(defaultBlockState().setValue(SHAPE, TrackShape.ZO)
.setValue(HAS_TE, false) .setValue(HAS_TE, false)
.setValue(WATERLOGGED, false)); .setValue(WATERLOGGED, false));
this.material = material;
} }
@Override @Override
protected void createBlockStateDefinition(Builder<Block, BlockState> p_49915_) { protected void createBlockStateDefinition(Builder<Block, BlockState> p_49915_) {
super.createBlockStateDefinition(p_49915_.add(SHAPE, HAS_TE, WATERLOGGED)); super.createBlockStateDefinition(p_49915_.add(SHAPE, HAS_TE, WATERLOGGED));
@ -407,7 +418,7 @@ public class TrackBlock extends Block
return list; return list;
BlockPos boundPos = trackTE.boundLocation.getSecond(); BlockPos boundPos = trackTE.boundLocation.getSecond();
BlockState boundState = otherLevel.getBlockState(boundPos); BlockState boundState = otherLevel.getBlockState(boundPos);
if (!AllBlocks.TRACK.has(boundState)) if (!AllTags.AllBlockTags.TRACKS.matches(boundState))
return list; return list;
Vec3 center = Vec3.atBottomCenterOf(pos) Vec3 center = Vec3.atBottomCenterOf(pos)
@ -750,7 +761,8 @@ public class TrackBlock extends Block
@Override @Override
public ItemRequirement getRequiredItems(BlockState state, BlockEntity te) { public ItemRequirement getRequiredItems(BlockState state, BlockEntity te) {
int trackAmount = 1; int sameTypeTrackAmount = 1;
Map<TrackMaterial, Integer> otherTrackAmounts = new HashMap<>();
int girderAmount = 0; int girderAmount = 0;
if (te instanceof TrackTileEntity track) { if (te instanceof TrackTileEntity track) {
@ -758,15 +770,27 @@ public class TrackBlock extends Block
.values()) { .values()) {
if (!bezierConnection.isPrimary()) if (!bezierConnection.isPrimary())
continue; continue;
trackAmount += bezierConnection.getTrackItemCost(); TrackMaterial material = ((IHasTrackMaterial) bezierConnection).getMaterial();
if (material == getMaterial()) {
sameTypeTrackAmount += bezierConnection.getTrackItemCost();
} else {
otherTrackAmounts.put(material, otherTrackAmounts.getOrDefault(material, 0) + 1);
}
girderAmount += bezierConnection.getGirderItemCost(); girderAmount += bezierConnection.getGirderItemCost();
} }
} }
List<ItemStack> stacks = new ArrayList<>(); List<ItemStack> stacks = new ArrayList<>();
while (trackAmount > 0) { while (sameTypeTrackAmount > 0) {
stacks.add(AllBlocks.TRACK.asStack(Math.min(trackAmount, 64))); stacks.add(new ItemStack(state.getBlock(), Math.min(sameTypeTrackAmount, 64)));
trackAmount -= 64; sameTypeTrackAmount -= 64;
}
for (TrackMaterial material : otherTrackAmounts.keySet()) {
int amt = otherTrackAmounts.get(material);
while (amt > 0) {
stacks.add(new ItemStack(material.getTrackBlock().get(), Math.min(amt, 64)));
amt -= 64;
}
} }
while (girderAmount > 0) { while (girderAmount > 0) {
stacks.add(AllBlocks.METAL_GIRDER.asStack(Math.min(girderAmount, 64))); stacks.add(AllBlocks.METAL_GIRDER.asStack(Math.min(girderAmount, 64)));
@ -776,6 +800,11 @@ public class TrackBlock extends Block
return new ItemRequirement(ItemUseType.CONSUME, stacks); return new ItemRequirement(ItemUseType.CONSUME, stacks);
} }
@Override
public TrackMaterial getMaterial() {
return material;
}
public static class RenderProperties extends ReducedDestroyEffects implements MultiPosDestructionHandler { public static class RenderProperties extends ReducedDestroyEffects implements MultiPosDestructionHandler {
@Override @Override
@Nullable @Nullable

View file

@ -2,6 +2,7 @@ package com.simibubi.create.content.logistics.trains.track;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllSoundEvents; import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.AllTags;
import com.simibubi.create.content.logistics.trains.ITrackBlock; import com.simibubi.create.content.logistics.trains.ITrackBlock;
import com.simibubi.create.content.logistics.trains.track.TrackPlacement.PlacementInfo; import com.simibubi.create.content.logistics.trains.track.TrackPlacement.PlacementInfo;
import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.networking.AllPackets;
@ -111,7 +112,7 @@ public class TrackBlockItem extends BlockItem {
return InteractionResult.SUCCESS; return InteractionResult.SUCCESS;
stack = player.getMainHandItem(); stack = player.getMainHandItem();
if (AllBlocks.TRACK.isIn(stack)) { if (AllTags.AllBlockTags.TRACKS.matches(stack)) {
stack.setTag(null); stack.setTag(null);
player.setItemInHand(pContext.getHand(), stack); player.setItemInHand(pContext.getHand(), stack);
} }
@ -154,7 +155,7 @@ public class TrackBlockItem extends BlockItem {
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public static void sendExtenderPacket(PlayerInteractEvent.RightClickBlock event) { public static void sendExtenderPacket(PlayerInteractEvent.RightClickBlock event) {
ItemStack stack = event.getItemStack(); ItemStack stack = event.getItemStack();
if (!AllBlocks.TRACK.isIn(stack) || !stack.hasTag()) if (!AllTags.AllBlockTags.TRACKS.matches(stack) || !stack.hasTag())
return; return;
if (Minecraft.getInstance().options.keySprint.isDown()) if (Minecraft.getInstance().options.keySprint.isDown())
AllPackets.channel AllPackets.channel

View file

@ -8,8 +8,8 @@ import java.util.function.Consumer;
import com.jozufozu.flywheel.util.transform.TransformStack; import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.blaze3d.vertex.VertexConsumer;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllShapes; import com.simibubi.create.AllShapes;
import com.simibubi.create.AllTags;
import com.simibubi.create.content.logistics.trains.BezierConnection; import com.simibubi.create.content.logistics.trains.BezierConnection;
import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.AnimationTickHolder;
@ -161,7 +161,7 @@ public class TrackBlockOutline {
.rotateXRadians(angles.x) .rotateXRadians(angles.x)
.translate(-.5, -.125f, -.5); .translate(-.5, -.125f, -.5);
boolean holdingTrack = AllBlocks.TRACK.isIn(Minecraft.getInstance().player.getMainHandItem()); boolean holdingTrack = AllTags.AllBlockTags.TRACKS.matches(Minecraft.getInstance().player.getMainHandItem());
renderShape(AllShapes.TRACK_ORTHO.get(Direction.SOUTH), ms, vb, holdingTrack ? false : null); renderShape(AllShapes.TRACK_ORTHO.get(Direction.SOUTH), ms, vb, holdingTrack ? false : null);
ms.popPose(); ms.popPose();
} }
@ -189,7 +189,7 @@ public class TrackBlockOutline {
ms.pushPose(); ms.pushPose();
ms.translate(pos.getX() - camPos.x, pos.getY() - camPos.y, pos.getZ() - camPos.z); ms.translate(pos.getX() - camPos.x, pos.getY() - camPos.y, pos.getZ() - camPos.z);
boolean holdingTrack = AllBlocks.TRACK.isIn(Minecraft.getInstance().player.getMainHandItem()); boolean holdingTrack = AllTags.AllBlockTags.TRACKS.matches(Minecraft.getInstance().player.getMainHandItem());
TrackShape shape = blockstate.getValue(TrackBlock.SHAPE); TrackShape shape = blockstate.getValue(TrackBlock.SHAPE);
boolean isJunction = shape.isJunction(); boolean isJunction = shape.isJunction();
walkShapes(shape, TransformStack.cast(ms), s -> { walkShapes(shape, TransformStack.cast(ms), s -> {

View file

@ -20,6 +20,8 @@ import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.logistics.trains.BezierConnection; import com.simibubi.create.content.logistics.trains.BezierConnection;
import com.simibubi.create.content.logistics.trains.BezierConnection.GirderAngles; import com.simibubi.create.content.logistics.trains.BezierConnection.GirderAngles;
import com.simibubi.create.content.logistics.trains.BezierConnection.SegmentAngles; import com.simibubi.create.content.logistics.trains.BezierConnection.SegmentAngles;
import com.simibubi.create.content.logistics.trains.IHasTrackMaterial;
import com.simibubi.create.content.logistics.trains.TrackMaterial;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
@ -112,11 +114,13 @@ public class TrackInstance extends BlockEntityInstance<TrackTileEntity> {
leftLightPos = new BlockPos[segCount]; leftLightPos = new BlockPos[segCount];
rightLightPos = new BlockPos[segCount]; rightLightPos = new BlockPos[segCount];
mat.getModel(AllBlockPartials.TRACK_TIE) TrackMaterial.TrackModelHolder modelHolder = ((IHasTrackMaterial) bc).getMaterial().modelHolder;
mat.getModel(modelHolder.tie())
.createInstances(ties); .createInstances(ties);
mat.getModel(AllBlockPartials.TRACK_SEGMENT_LEFT) mat.getModel(modelHolder.segment_left())
.createInstances(left); .createInstances(left);
mat.getModel(AllBlockPartials.TRACK_SEGMENT_RIGHT) mat.getModel(modelHolder.segment_right())
.createInstances(right); .createInstances(right);
SegmentAngles[] segments = bc.getBakedSegments(); SegmentAngles[] segments = bc.getBakedSegments();

View file

@ -7,12 +7,14 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import com.jozufozu.flywheel.util.Color; import com.jozufozu.flywheel.util.Color;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllSpecialTextures; import com.simibubi.create.AllSpecialTextures;
import com.simibubi.create.AllTags;
import com.simibubi.create.CreateClient; import com.simibubi.create.CreateClient;
import com.simibubi.create.content.curiosities.tools.BlueprintOverlayRenderer; import com.simibubi.create.content.curiosities.tools.BlueprintOverlayRenderer;
import com.simibubi.create.content.logistics.trains.BezierConnection; import com.simibubi.create.content.logistics.trains.BezierConnection;
import com.simibubi.create.content.logistics.trains.IHasTrackMaterial;
import com.simibubi.create.content.logistics.trains.ITrackBlock; import com.simibubi.create.content.logistics.trains.ITrackBlock;
import com.simibubi.create.content.logistics.trains.TrackMaterial;
import com.simibubi.create.foundation.advancement.AllAdvancements; import com.simibubi.create.foundation.advancement.AllAdvancements;
import com.simibubi.create.foundation.block.ProperWaterloggedBlock; import com.simibubi.create.foundation.block.ProperWaterloggedBlock;
import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.config.AllConfigs;
@ -47,6 +49,7 @@ import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.EntityBlock;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.Property;
import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.HitResult.Type; import net.minecraft.world.phys.HitResult.Type;
@ -57,7 +60,7 @@ import net.minecraftforge.items.ItemHandlerHelper;
public class TrackPlacement { public class TrackPlacement {
public static class PlacementInfo { public static class PlacementInfo implements IHasTrackMaterial {
BezierConnection curve = null; BezierConnection curve = null;
boolean valid = false; boolean valid = false;
int end1Extent = 0; int end1Extent = 0;
@ -69,6 +72,7 @@ public class TrackPlacement {
public int requiredPavement = 0; public int requiredPavement = 0;
public boolean hasRequiredPavement = false; public boolean hasRequiredPavement = false;
private TrackMaterial trackMaterial;
// for visualisation // for visualisation
Vec3 end1; Vec3 end1;
@ -89,6 +93,19 @@ public class TrackPlacement {
curve = null; curve = null;
return this; return this;
} }
@Override
public TrackMaterial getMaterial() {
if (trackMaterial == null) {
throw new RuntimeException("Track material should never be null in TrackPlacement#PlacementInfo");
}
return trackMaterial;
}
@Override
public void setMaterial(TrackMaterial material) {
trackMaterial = material;
}
} }
public static PlacementInfo cached; public static PlacementInfo cached;
@ -109,6 +126,7 @@ public class TrackPlacement {
return cached; return cached;
PlacementInfo info = new PlacementInfo(); PlacementInfo info = new PlacementInfo();
info.trackMaterial = IHasTrackMaterial.fromItem(stack.getItem());
hoveringMaxed = maximiseTurn; hoveringMaxed = maximiseTurn;
hoveringAngle = lookAngle; hoveringAngle = lookAngle;
hoveringPos = pos2; hoveringPos = pos2;
@ -192,7 +210,7 @@ public class TrackPlacement {
BlockPos targetPos2 = pos2.offset(offset2.x, offset2.y, offset2.z); BlockPos targetPos2 = pos2.offset(offset2.x, offset2.y, offset2.z);
info.curve = new BezierConnection(Couple.create(targetPos1, targetPos2), info.curve = new BezierConnection(Couple.create(targetPos1, targetPos2),
Couple.create(end1.add(offset1), end2.add(offset2)), Couple.create(normedAxis1, normedAxis2), Couple.create(end1.add(offset1), end2.add(offset2)), Couple.create(normedAxis1, normedAxis2),
Couple.create(normal1, normal2), true, girder); Couple.create(normal1, normal2), true, girder, IHasTrackMaterial.fromItem(stack.getItem()));
} }
// S curve or Straight // S curve or Straight
@ -352,7 +370,7 @@ public class TrackPlacement {
info.curve = skipCurve ? null info.curve = skipCurve ? null
: new BezierConnection(Couple.create(targetPos1, targetPos2), : new BezierConnection(Couple.create(targetPos1, targetPos2),
Couple.create(end1.add(offset1), end2.add(offset2)), Couple.create(normedAxis1, normedAxis2), Couple.create(end1.add(offset1), end2.add(offset2)), Couple.create(normedAxis1, normedAxis2),
Couple.create(normal1, normal2), true, girder); Couple.create(normal1, normal2), true, girder, IHasTrackMaterial.fromItem(stack.getItem()));
info.valid = true; info.valid = true;
@ -397,7 +415,7 @@ public class TrackPlacement {
continue; continue;
ItemStack stackInSlot = (offhand ? inv.offhand : inv.items).get(i); ItemStack stackInSlot = (offhand ? inv.offhand : inv.items).get(i);
boolean isTrack = AllBlocks.TRACK.isIn(stackInSlot); boolean isTrack = AllTags.AllBlockTags.TRACKS.matches(stackInSlot) && stackInSlot.is(stack.getItem());
if (!isTrack && (!shouldPave || offhandItem.getItem() != stackInSlot.getItem())) if (!isTrack && (!shouldPave || offhandItem.getItem() != stackInSlot.getItem()))
continue; continue;
if (isTrack ? foundTracks >= tracks : foundPavement >= pavement) if (isTrack ? foundTracks >= tracks : foundPavement >= pavement)
@ -474,6 +492,18 @@ public class TrackPlacement {
info.requiredPavement += TrackPaver.paveCurve(level, info.curve, block, simulate, visited); info.requiredPavement += TrackPaver.paveCurve(level, info.curve, block, simulate, visited);
} }
private static BlockState copyProperties(BlockState from, BlockState onto) {
for (Property property : onto.getProperties()) {
if (from.hasProperty(property))
onto = onto.setValue(property, from.getValue(property));
}
return onto;
}
private static BlockState copyProperties(BlockState from, BlockState onto, boolean keepFrom) {
return keepFrom ? copyProperties(from, onto) : from;
}
private static PlacementInfo placeTracks(Level level, PlacementInfo info, BlockState state1, BlockState state2, private static PlacementInfo placeTracks(Level level, PlacementInfo info, BlockState state1, BlockState state2,
BlockPos targetPos1, BlockPos targetPos2, boolean simulate) { BlockPos targetPos1, BlockPos targetPos2, boolean simulate) {
info.requiredTracks = 0; info.requiredTracks = 0;
@ -501,7 +531,8 @@ public class TrackPlacement {
Vec3 offset = axis.scale(i); Vec3 offset = axis.scale(i);
BlockPos offsetPos = pos.offset(offset.x, offset.y, offset.z); BlockPos offsetPos = pos.offset(offset.x, offset.y, offset.z);
BlockState stateAtPos = level.getBlockState(offsetPos); BlockState stateAtPos = level.getBlockState(offsetPos);
BlockState toPlace = state; // copy over all shared properties from the shaped state to the correct track material block
BlockState toPlace = copyProperties(state, info.getMaterial().getTrackBlock().getDefaultState());
boolean canPlace = stateAtPos.getMaterial() boolean canPlace = stateAtPos.getMaterial()
.isReplaceable(); .isReplaceable();
@ -525,13 +556,14 @@ public class TrackPlacement {
if (!simulate) { if (!simulate) {
BlockState stateAtPos = level.getBlockState(targetPos1); BlockState stateAtPos = level.getBlockState(targetPos1);
BlockState onto = info.getMaterial().getTrackBlock().getDefaultState();
level.setBlock(targetPos1, ProperWaterloggedBlock.withWater(level, level.setBlock(targetPos1, ProperWaterloggedBlock.withWater(level,
(stateAtPos.getBlock() == state1.getBlock() ? stateAtPos : state1).setValue(TrackBlock.HAS_TE, true), copyProperties((stateAtPos.getBlock() == state1.getBlock() ? stateAtPos : state1), onto, AllTags.AllBlockTags.TRACKS.matches(stateAtPos)).setValue(TrackBlock.HAS_TE, true),
targetPos1), 3); targetPos1), 3);
stateAtPos = level.getBlockState(targetPos2); stateAtPos = level.getBlockState(targetPos2);
level.setBlock(targetPos2, ProperWaterloggedBlock.withWater(level, level.setBlock(targetPos2, ProperWaterloggedBlock.withWater(level,
(stateAtPos.getBlock() == state2.getBlock() ? stateAtPos : state2).setValue(TrackBlock.HAS_TE, true), copyProperties((stateAtPos.getBlock() == state2.getBlock() ? stateAtPos : state2), onto, AllTags.AllBlockTags.TRACKS.matches(stateAtPos)).setValue(TrackBlock.HAS_TE, true),
targetPos2), 3); targetPos2), 3);
} }
@ -579,10 +611,10 @@ public class TrackPlacement {
return; return;
InteractionHand hand = InteractionHand.MAIN_HAND; InteractionHand hand = InteractionHand.MAIN_HAND;
if (!AllBlocks.TRACK.isIn(stack)) { if (!AllTags.AllBlockTags.TRACKS.matches(stack)) {
stack = player.getOffhandItem(); stack = player.getOffhandItem();
hand = InteractionHand.OFF_HAND; hand = InteractionHand.OFF_HAND;
if (!AllBlocks.TRACK.isIn(stack)) if (!AllTags.AllBlockTags.TRACKS.matches(stack))
return; return;
} }

View file

@ -3,9 +3,6 @@ package com.simibubi.create.content.logistics.trains.track;
import static com.simibubi.create.AllBlockPartials.GIRDER_SEGMENT_BOTTOM; import static com.simibubi.create.AllBlockPartials.GIRDER_SEGMENT_BOTTOM;
import static com.simibubi.create.AllBlockPartials.GIRDER_SEGMENT_MIDDLE; import static com.simibubi.create.AllBlockPartials.GIRDER_SEGMENT_MIDDLE;
import static com.simibubi.create.AllBlockPartials.GIRDER_SEGMENT_TOP; import static com.simibubi.create.AllBlockPartials.GIRDER_SEGMENT_TOP;
import static com.simibubi.create.AllBlockPartials.TRACK_SEGMENT_LEFT;
import static com.simibubi.create.AllBlockPartials.TRACK_SEGMENT_RIGHT;
import static com.simibubi.create.AllBlockPartials.TRACK_TIE;
import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.util.transform.TransformStack; import com.jozufozu.flywheel.util.transform.TransformStack;
@ -15,6 +12,8 @@ import com.mojang.blaze3d.vertex.VertexConsumer;
import com.simibubi.create.content.logistics.trains.BezierConnection; import com.simibubi.create.content.logistics.trains.BezierConnection;
import com.simibubi.create.content.logistics.trains.BezierConnection.GirderAngles; import com.simibubi.create.content.logistics.trains.BezierConnection.GirderAngles;
import com.simibubi.create.content.logistics.trains.BezierConnection.SegmentAngles; import com.simibubi.create.content.logistics.trains.BezierConnection.SegmentAngles;
import com.simibubi.create.content.logistics.trains.IHasTrackMaterial;
import com.simibubi.create.content.logistics.trains.TrackMaterial;
import com.simibubi.create.foundation.render.CachedBufferer; import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AngleHelper;
@ -66,7 +65,9 @@ public class TrackRenderer extends SafeTileEntityRenderer<TrackTileEntity> {
SegmentAngles segment = segments[i]; SegmentAngles segment = segments[i];
int light = LevelRenderer.getLightColor(level, segment.lightPosition.offset(tePosition)); int light = LevelRenderer.getLightColor(level, segment.lightPosition.offset(tePosition));
CachedBufferer.partial(TRACK_TIE, air) TrackMaterial.TrackModelHolder modelHolder = ((IHasTrackMaterial) bc).getMaterial().modelHolder;
CachedBufferer.partial(modelHolder.tie(), air)
.mulPose(segment.tieTransform.pose()) .mulPose(segment.tieTransform.pose())
.mulNormal(segment.tieTransform.normal()) .mulNormal(segment.tieTransform.normal())
.light(light) .light(light)
@ -74,7 +75,7 @@ public class TrackRenderer extends SafeTileEntityRenderer<TrackTileEntity> {
for (boolean first : Iterate.trueAndFalse) { for (boolean first : Iterate.trueAndFalse) {
Pose transform = segment.railTransforms.get(first); Pose transform = segment.railTransforms.get(first);
CachedBufferer.partial(first ? TRACK_SEGMENT_LEFT : TRACK_SEGMENT_RIGHT, air) CachedBufferer.partial(first ? modelHolder.segment_left() : modelHolder.segment_right(), air)
.mulPose(transform.pose()) .mulPose(transform.pose())
.mulNormal(transform.normal()) .mulNormal(transform.normal())
.light(light) .light(light)

View file

@ -9,6 +9,7 @@ import java.util.Set;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher; import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllTags;
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableTE; import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableTE;
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform; import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
import com.simibubi.create.content.logistics.trains.BezierConnection; import com.simibubi.create.content.logistics.trains.BezierConnection;
@ -287,7 +288,7 @@ public class TrackTileEntity extends SmartTileEntity implements ITransformableTE
.getLevel(boundLocation.getFirst()); .getLevel(boundLocation.getFirst());
if (otherLevel == null) if (otherLevel == null)
return; return;
if (AllBlocks.TRACK.has(otherLevel.getBlockState(boundLocation.getSecond()))) if (AllTags.AllBlockTags.TRACKS.matches(otherLevel.getBlockState(boundLocation.getSecond())))
otherLevel.destroyBlock(boundLocation.getSecond(), false); otherLevel.destroyBlock(boundLocation.getSecond(), false);
} }
} }

View file

@ -3,6 +3,7 @@ package com.simibubi.create.foundation.ponder.content;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllItems; import com.simibubi.create.AllItems;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.TrackMaterial;
import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.ponder.PonderRegistrationHelper; import com.simibubi.create.foundation.ponder.PonderRegistrationHelper;
import com.simibubi.create.foundation.ponder.PonderRegistry; import com.simibubi.create.foundation.ponder.PonderRegistry;
@ -303,7 +304,7 @@ public class PonderIndex {
.addStoryBoard("rose_quartz_lamp", RedstoneScenes2::roseQuartzLamp); .addStoryBoard("rose_quartz_lamp", RedstoneScenes2::roseQuartzLamp);
// Trains // Trains
HELPER.forComponents(AllBlocks.TRACK) HELPER.forComponents(TrackMaterial.allBlocks())
.addStoryBoard("train_track/placement", TrackScenes::placement) .addStoryBoard("train_track/placement", TrackScenes::placement)
.addStoryBoard("train_track/portal", TrackScenes::portal) .addStoryBoard("train_track/portal", TrackScenes::portal)
.addStoryBoard("train_track/chunks", TrackScenes::chunks); .addStoryBoard("train_track/chunks", TrackScenes::chunks);