Down the Checklist, Part II

- Fake Tracks no longer replace lava or flowing water
- Fixed passengers dismounting from contraptions teleporting into the ceiling for a tick
-  Fixed serverside collision mask not updating when doors open on a contraption
- Signals can now be seen from further away
- Fixed some model loading logspam
- Fixed curved tracks dropping items when destroyed in creative mode
- Fixed curved tracks sometimes reappearing after being broken once
- Fixed Fluid pipes not rendering a rim when facing a pump from its side
- Fixed Super glue not always taking effect when intersecting with another box
- Fixed Super glue blocking entities travelling on a belt
- Fixed Super glue disintegrating when pushed by a vanilla piston
- Fixed Tracks placed up against a solid wall placing as ascending slopes
- Fixed movement actors switching dimensions stalling indefinitely
- Fixed kinetic components showing speed requirement popups when moving very slowly
- Fixed display boards not always connecting properly when placed with placement assist
- Fixed display boards getting caught in kinetic ghost power loops
- Fixed display boards loading in with jumbled text
- Fixed players unable to hand schedules to conductors while seated
This commit is contained in:
simibubi 2022-06-21 19:43:53 +02:00
parent 08c67cc4bc
commit cdadd12b41
29 changed files with 218 additions and 117 deletions

View file

@ -208,6 +208,7 @@ d13940ed213d7acbc6ebe3bdd21175ef89e4d613 assets/create/blockstates/encased_fluid
8bc601601858042859cd834e7fa391a8235d3d75 assets/create/blockstates/exposed_copper_tile_slab.json 8bc601601858042859cd834e7fa391a8235d3d75 assets/create/blockstates/exposed_copper_tile_slab.json
8a87e42262f3f161b0e6fe10b795ff00eccf768f assets/create/blockstates/exposed_copper_tile_stairs.json 8a87e42262f3f161b0e6fe10b795ff00eccf768f assets/create/blockstates/exposed_copper_tile_stairs.json
fb41aa1a0828c9256b3f886fdcb55bb54252ba09 assets/create/blockstates/exposed_copper_tiles.json fb41aa1a0828c9256b3f886fdcb55bb54252ba09 assets/create/blockstates/exposed_copper_tiles.json
7a2259a71fbbbb9491fc1e6a9c935bc9fef14042 assets/create/blockstates/fake_track.json
bb74442749b6bd688d45d919b541dbd66bbeb18a assets/create/blockstates/fluid_pipe.json bb74442749b6bd688d45d919b541dbd66bbeb18a assets/create/blockstates/fluid_pipe.json
f0eaab18e16c4f3f65ebf3b55b08f0dc445720fe assets/create/blockstates/fluid_tank.json f0eaab18e16c4f3f65ebf3b55b08f0dc445720fe assets/create/blockstates/fluid_tank.json
5408d92ab02af86539ac42971d4033545970bb3a assets/create/blockstates/fluid_valve.json 5408d92ab02af86539ac42971d4033545970bb3a assets/create/blockstates/fluid_valve.json
@ -5022,7 +5023,7 @@ e98ea64ba1a6780456e135628239251add737f2e data/create/recipes/deploying/waxed_wea
72110302ade0a3b7d82c5e778c63e0b457a2470b data/create/recipes/dripstone_pillar_from_dripstone_block_stonecutting.json 72110302ade0a3b7d82c5e778c63e0b457a2470b data/create/recipes/dripstone_pillar_from_dripstone_block_stonecutting.json
27d9bf05a610447e90314e658dbbcd191f378fc9 data/create/recipes/dripstone_pillar_from_stone_types_dripstone_stonecutting.json 27d9bf05a610447e90314e658dbbcd191f378fc9 data/create/recipes/dripstone_pillar_from_stone_types_dripstone_stonecutting.json
d81ceba2946286d374801e698a4ca2116395cbad data/create/recipes/emptying/builders_tea.json d81ceba2946286d374801e698a4ca2116395cbad data/create/recipes/emptying/builders_tea.json
d12905d723363a6a053f7925af576c416a7b0aee data/create/recipes/emptying/compat/farmersdelight/milk_bottle.json c26d003e921720308c05ad7b9f3cb57de94a10a8 data/create/recipes/emptying/compat/farmersdelight/milk_bottle.json
20b7c7c62fa2e33199e08188dd8836844a6d9cfd data/create/recipes/emptying/honey_bottle.json 20b7c7c62fa2e33199e08188dd8836844a6d9cfd data/create/recipes/emptying/honey_bottle.json
dfc1bbb05a4eca31f47d1b25c5975866cb4b61f9 data/create/recipes/exposed_copper_shingle_slab.json dfc1bbb05a4eca31f47d1b25c5975866cb4b61f9 data/create/recipes/exposed_copper_shingle_slab.json
4e1cfc70d9089d90adbed4bef37b36e66751f5db data/create/recipes/exposed_copper_shingle_slab_from_exposed_copper_shingles_stonecutting.json 4e1cfc70d9089d90adbed4bef37b36e66751f5db data/create/recipes/exposed_copper_shingle_slab_from_exposed_copper_shingles_stonecutting.json
@ -5035,7 +5036,7 @@ c2f40d447fbac4b4975e578fe32635658b73ebf7 data/create/recipes/exposed_copper_tile
133e79f78a7f2c2f63ac7695d2be57d56e8955f4 data/create/recipes/filling/blaze_cake.json 133e79f78a7f2c2f63ac7695d2be57d56e8955f4 data/create/recipes/filling/blaze_cake.json
642e96ce5dd2f31e7a33c6ef4060eecb0bf2aa86 data/create/recipes/filling/builders_tea.json 642e96ce5dd2f31e7a33c6ef4060eecb0bf2aa86 data/create/recipes/filling/builders_tea.json
1367357fc36adc4b67467d90589ef91e657380a4 data/create/recipes/filling/chocolate_glazed_berries.json 1367357fc36adc4b67467d90589ef91e657380a4 data/create/recipes/filling/chocolate_glazed_berries.json
efeb30ea6e9a7dca0d8fc388fd9c96ee70078537 data/create/recipes/filling/compat/farmersdelight/milk_bottle.json 0e79248178f8c1690b4e5a5ad2ffaf63711ad3c7 data/create/recipes/filling/compat/farmersdelight/milk_bottle.json
5bec6c2068a3c1005810d18bd45ce916389b5423 data/create/recipes/filling/glowstone.json 5bec6c2068a3c1005810d18bd45ce916389b5423 data/create/recipes/filling/glowstone.json
5eb6227ccb6fa940b662d3ec029c3bd61fe61c8d data/create/recipes/filling/grass_block.json 5eb6227ccb6fa940b662d3ec029c3bd61fe61c8d data/create/recipes/filling/grass_block.json
244f27eadefefbc966ac384ac087c57d19484321 data/create/recipes/filling/gunpowder.json 244f27eadefefbc966ac384ac087c57d19484321 data/create/recipes/filling/gunpowder.json

View file

@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "create:block/fake_track"
}
}
}

View file

@ -13,5 +13,11 @@
"fluid": "minecraft:milk", "fluid": "minecraft:milk",
"amount": 250 "amount": 250
} }
],
"conditions": [
{
"modid": "farmersdelight",
"type": "forge:mod_loaded"
}
] ]
} }

View file

@ -13,5 +13,11 @@
{ {
"item": "farmersdelight:milk_bottle" "item": "farmersdelight:milk_bottle"
} }
],
"conditions": [
{
"modid": "farmersdelight",
"type": "forge:mod_loaded"
}
] ]
} }

View file

@ -1509,8 +1509,8 @@ public class AllBlocks {
.nonSolid() .nonSolid()
.replaceable() .replaceable()
.build()) .build())
.blockstate((c, p) -> p.models() .blockstate((c, p) -> p.simpleBlock(c.get(), p.models()
.withExistingParent(c.getName(), p.mcLoc("block/air"))) .withExistingParent(c.getName(), p.mcLoc("block/air"))))
.lang("Track Marker for Maps") .lang("Track Marker for Maps")
.register(); .register();

View file

@ -141,7 +141,7 @@ public interface IRotate extends IWrenchable {
public Axis getRotationAxis(BlockState state); public Axis getRotationAxis(BlockState state);
public default SpeedLevel getMinimumRequiredSpeedLevel() { public default SpeedLevel getMinimumRequiredSpeedLevel() {
return SpeedLevel.SLOW; return SpeedLevel.NONE;
} }
public default boolean hideStressImpact() { public default boolean hideStressImpact() {

View file

@ -57,7 +57,8 @@ public abstract class KineticBlock extends Block implements IRotate {
} }
@Override @Override
public void updateIndirectNeighbourShapes(BlockState stateIn, LevelAccessor worldIn, BlockPos pos, int flags, int count) { public void updateIndirectNeighbourShapes(BlockState stateIn, LevelAccessor worldIn, BlockPos pos, int flags,
int count) {
if (worldIn.isClientSide()) if (worldIn.isClientSide())
return; return;
@ -66,10 +67,8 @@ public abstract class KineticBlock extends Block implements IRotate {
return; return;
KineticTileEntity kte = (KineticTileEntity) tileEntity; KineticTileEntity kte = (KineticTileEntity) tileEntity;
if (kte.preventSpeedUpdate > 0) { if (kte.preventSpeedUpdate > 0)
kte.preventSpeedUpdate--;
return; return;
}
// Remove previous information when block is added // Remove previous information when block is added
kte.warnOfMovement(); kte.warnOfMovement();

View file

@ -94,6 +94,8 @@ public class KineticTileEntity extends SmartTileEntity
super.tick(); super.tick();
effects.tick(); effects.tick();
preventSpeedUpdate = 0;
if (level.isClientSide) { if (level.isClientSide) {
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> this.tickAudio()); DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> this.tickAudio());
return; return;

View file

@ -144,8 +144,10 @@ public class BlockBreakingMovementBehaviour implements MovementBehaviour {
CompoundTag data = context.data; CompoundTag data = context.data;
if (context.world.isClientSide) if (context.world.isClientSide)
return; return;
if (!data.contains("BreakingPos")) if (!data.contains("BreakingPos")) {
context.stall = false;
return; return;
}
if (context.relativeMotion.equals(Vec3.ZERO)) { if (context.relativeMotion.equals(Vec3.ZERO)) {
context.stall = false; context.stall = false;
return; return;

View file

@ -44,6 +44,7 @@ import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtIo; import net.minecraft.nbt.NbtIo;
import net.minecraft.nbt.Tag;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.Packet;
@ -167,6 +168,15 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
new ContraptionSeatMappingPacket(getId(), contraption.getSeatMapping())); new ContraptionSeatMappingPacket(getId(), contraption.getSeatMapping()));
} }
@Override
public Vec3 getDismountLocationForPassenger(LivingEntity pLivingEntity) {
Vec3 loc = super.getDismountLocationForPassenger(pLivingEntity);
CompoundTag data = pLivingEntity.getPersistentData();
if (!data.contains("ContraptionDismountLocation"))
return loc;
return VecHelper.readNBT(data.getList("ContraptionDismountLocation", Tag.TAG_DOUBLE));
}
@Override @Override
public void positionRider(Entity passenger, MoveFunction callback) { public void positionRider(Entity passenger, MoveFunction callback) {
if (!hasPassenger(passenger)) if (!hasPassenger(passenger))

View file

@ -47,6 +47,7 @@ import net.minecraft.world.level.block.Mirror;
import net.minecraft.world.level.block.Rotation; import net.minecraft.world.level.block.Rotation;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BooleanProperty; import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.level.material.PushReaction;
import net.minecraft.world.level.portal.PortalInfo; import net.minecraft.world.level.portal.PortalInfo;
import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
@ -66,7 +67,8 @@ public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnDat
for (SuperGlueEntity glueEntity : cached) for (SuperGlueEntity glueEntity : cached)
if (glueEntity.contains(blockPos) && glueEntity.contains(targetPos)) if (glueEntity.contains(blockPos) && glueEntity.contains(targetPos))
return true; return true;
for (SuperGlueEntity glueEntity : level.getEntitiesOfClass(SuperGlueEntity.class, span(blockPos, targetPos))) { for (SuperGlueEntity glueEntity : level.getEntitiesOfClass(SuperGlueEntity.class,
span(blockPos, targetPos).inflate(16))) {
if (!glueEntity.contains(blockPos) || !glueEntity.contains(targetPos)) if (!glueEntity.contains(blockPos) || !glueEntity.contains(targetPos))
continue; continue;
if (cached != null) if (cached != null)
@ -288,6 +290,11 @@ public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnDat
return getBoundingBox().contains(Vec3.atCenterOf(pos)); return getBoundingBox().contains(Vec3.atCenterOf(pos));
} }
@Override
public PushReaction getPistonPushReaction() {
return PushReaction.IGNORE;
}
@Override @Override
public PortalInfo findDimensionEntryPoint(ServerLevel pDestination) { public PortalInfo findDimensionEntryPoint(ServerLevel pDestination) {
portalEntrancePos = blockPosition(); portalEntrancePos = blockPosition();

View file

@ -241,7 +241,8 @@ public abstract class FluidTransportBehaviour extends TileEntityBehaviour {
BlockPos offsetPos = pos.relative(direction); BlockPos offsetPos = pos.relative(direction);
BlockState facingState = world.getBlockState(offsetPos); BlockState facingState = world.getBlockState(offsetPos);
if (facingState.getBlock() instanceof PumpBlock && facingState.getValue(PumpBlock.FACING) != direction) if (facingState.getBlock() instanceof PumpBlock
&& facingState.getValue(PumpBlock.FACING) == direction.getOpposite())
return AttachmentTypes.NONE; return AttachmentTypes.NONE;
if (AllBlocks.ENCASED_FLUID_PIPE.has(facingState) if (AllBlocks.ENCASED_FLUID_PIPE.has(facingState)

View file

@ -7,7 +7,6 @@ import static net.minecraft.world.entity.MoverType.SELF;
import java.util.List; import java.util.List;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity;
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock; import com.simibubi.create.content.contraptions.relays.belt.BeltBlock;
import com.simibubi.create.content.contraptions.relays.belt.BeltPart; import com.simibubi.create.content.contraptions.relays.belt.BeltPart;
import com.simibubi.create.content.contraptions.relays.belt.BeltSlope; import com.simibubi.create.content.contraptions.relays.belt.BeltSlope;
@ -27,6 +26,7 @@ import net.minecraft.world.level.Level;
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.BlockStateProperties; import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.material.PushReaction;
import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
@ -196,10 +196,10 @@ public class BeltMovementHandler {
} }
public static boolean shouldIgnoreBlocking(Entity me, Entity other) { public static boolean shouldIgnoreBlocking(Entity me, Entity other) {
if (other instanceof AbstractContraptionEntity)
return true;
if (other instanceof HangingEntity) if (other instanceof HangingEntity)
return true; return true;
if (other.getPistonPushReaction() == PushReaction.IGNORE)
return true;
return isRidingOrBeingRiddenBy(me, other); return isRidingOrBeingRiddenBy(me, other);
} }

View file

@ -80,6 +80,7 @@ public class SlidingDoorMovementBehaviour implements MovementBehaviour {
if (info != null && info.state.hasProperty(DoorBlock.OPEN)) { if (info != null && info.state.hasProperty(DoorBlock.OPEN)) {
newState = info.state.cycle(DoorBlock.OPEN); newState = info.state.cycle(DoorBlock.OPEN);
contraption.entity.setBlock(otherPos, new StructureBlockInfo(info.pos, newState, info.nbt)); contraption.entity.setBlock(otherPos, new StructureBlockInfo(info.pos, newState, info.nbt));
contraption.invalidateColliders();
} }
} }

View file

@ -197,4 +197,9 @@ public class NixieTubeRenderer extends SafeTileEntityRenderer<NixieTubeTileEntit
} }
@Override
public int getViewDistance() {
return 128;
}
} }

View file

@ -263,7 +263,6 @@ public class TrackGraph {
if (train.graph != this) if (train.graph != this)
continue; continue;
train.graph = toOther; train.graph = toOther;
train.syncTrackGraphChanges();
} }
} }
@ -341,7 +340,6 @@ public class TrackGraph {
if (!train.isTravellingOn(node)) if (!train.isTravellingOn(node))
continue; continue;
train.graph = target; train.graph = target;
train.syncTrackGraphChanges();
} }
nodes.remove(nodeLoc); nodes.remove(nodeLoc);
@ -376,12 +374,7 @@ public class TrackGraph {
TrackEdge edge = new TrackEdge(node1, node2, turn); TrackEdge edge = new TrackEdge(node1, node2, turn);
TrackEdge edge2 = new TrackEdge(node2, node1, bezier ? turn.secondary() : null); TrackEdge edge2 = new TrackEdge(node2, node1, bezier ? turn.secondary() : null);
if (reader instanceof Level level) {
for (TrackGraph graph : Create.RAILWAYS.trackNetworks.values()) { for (TrackGraph graph : Create.RAILWAYS.trackNetworks.values()) {
if (graph != this
&& !graph.getBounds(level).box.intersects(location.getLocation(), location2.getLocation()))
continue;
for (TrackNode otherNode1 : graph.nodes.values()) { for (TrackNode otherNode1 : graph.nodes.values()) {
Map<TrackNode, TrackEdge> connections = graph.connectionsByNode.get(otherNode1); Map<TrackNode, TrackEdge> connections = graph.connectionsByNode.get(otherNode1);
if (connections == null) if (connections == null)
@ -391,8 +384,7 @@ public class TrackGraph {
TrackEdge otherEdge = entry.getValue(); TrackEdge otherEdge = entry.getValue();
if (graph == this) if (graph == this)
if (otherNode1 == node1 || otherNode2 == node1 || otherNode1 == node2 if (otherNode1 == node1 || otherNode2 == node1 || otherNode1 == node2 || otherNode2 == node2)
|| otherNode2 == node2)
continue; continue;
if (edge == otherEdge) if (edge == otherEdge)
@ -414,9 +406,7 @@ public class TrackGraph {
otherEdge.edgeData.addIntersection(graph, id, t, node1, node2, s); otherEdge.edgeData.addIntersection(graph, id, t, node1, node2, s);
TrackEdge otherEdge2 = graph.getConnection(Couple.create(otherNode2, otherNode1)); TrackEdge otherEdge2 = graph.getConnection(Couple.create(otherNode2, otherNode1));
if (otherEdge2 != null) if (otherEdge2 != null)
otherEdge2.edgeData.addIntersection(graph, id, otherEdge.getLength() - t, node1, node2, otherEdge2.edgeData.addIntersection(graph, id, otherEdge.getLength() - t, node1, node2, s);
s);
}
} }
} }
} }

View file

@ -19,7 +19,6 @@ import javax.annotation.Nullable;
import org.apache.commons.lang3.mutable.MutableDouble; import org.apache.commons.lang3.mutable.MutableDouble;
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
import com.simibubi.create.content.contraptions.components.structureMovement.train.TrainCargoManager; import com.simibubi.create.content.contraptions.components.structureMovement.train.TrainCargoManager;
import com.simibubi.create.content.logistics.trains.DimensionPalette; import com.simibubi.create.content.logistics.trains.DimensionPalette;
import com.simibubi.create.content.logistics.trains.TrackGraph; import com.simibubi.create.content.logistics.trains.TrackGraph;
@ -778,7 +777,6 @@ public class Carriage {
entity.moveTo(positionAnchor); entity.moveTo(positionAnchor);
this.entity = new WeakReference<>(cce); this.entity = new WeakReference<>(cce);
cce.setGraph(train.graph == null ? null : train.graph.id);
cce.setCarriage(Carriage.this); cce.setCarriage(Carriage.this);
cce.syncCarriage(); cce.syncCarriage();

View file

@ -8,8 +8,6 @@ import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import javax.annotation.Nullable;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.simibubi.create.AllEntityDataSerializers; import com.simibubi.create.AllEntityDataSerializers;
import com.simibubi.create.AllEntityTypes; import com.simibubi.create.AllEntityTypes;
@ -124,6 +122,8 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
if (!level.isClientSide) if (!level.isClientSide)
return; return;
bindCarriage();
if (TRACK_GRAPH.equals(key)) if (TRACK_GRAPH.equals(key))
updateTrackGraph(); updateTrackGraph();
@ -212,21 +212,11 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
nonDamageTicks--; nonDamageTicks--;
if (!(contraption instanceof CarriageContraption cc)) if (!(contraption instanceof CarriageContraption cc))
return; return;
if (carriage == null) { if (carriage == null) {
if (level.isClientSide) { if (level.isClientSide)
Train train = Create.RAILWAYS.sided(level).trains.get(trainId); bindCarriage();
if (train == null || train.carriages.size() <= carriageIndex) else
return;
carriage = train.carriages.get(carriageIndex);
if (carriage != null) {
DimensionalCarriageEntity dimensional = carriage.getDimensional(level);
dimensional.entity = new WeakReference<>(this);
dimensional.pivot = null;
carriage.updateContraptionAnchors();
dimensional.updateRenderedCutoff();
}
updateTrackGraph();
} else
discard(); discard();
return; return;
} }
@ -240,6 +230,7 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
if (!level.isClientSide) { if (!level.isClientSide) {
entityData.set(SCHEDULED, carriage.train.runtime.getSchedule() != null); entityData.set(SCHEDULED, carriage.train.runtime.getSchedule() != null);
boolean shouldCarriageSyncThisTick = boolean shouldCarriageSyncThisTick =
carriage.train.shouldCarriageSyncThisTick(level.getGameTime(), getType().updateInterval()); carriage.train.shouldCarriageSyncThisTick(level.getGameTime(), getType().updateInterval());
if (shouldCarriageSyncThisTick && carriageData.isDirty()) { if (shouldCarriageSyncThisTick && carriageData.isDirty()) {
@ -259,6 +250,10 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
if (arrivalSoundPlaying) if (arrivalSoundPlaying)
tickArrivalSound(cc); tickArrivalSound(cc);
entityData.set(TRACK_GRAPH, Optional.ofNullable(carriage.train.graph)
.map(g -> g.id));
return; return;
} }
@ -310,6 +305,23 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
validForRender = true; validForRender = true;
} }
private void bindCarriage() {
if (carriage != null)
return;
Train train = Create.RAILWAYS.sided(level).trains.get(trainId);
if (train == null || train.carriages.size() <= carriageIndex)
return;
carriage = train.carriages.get(carriageIndex);
if (carriage != null) {
DimensionalCarriageEntity dimensional = carriage.getDimensional(level);
dimensional.entity = new WeakReference<>(this);
dimensional.pivot = null;
carriage.updateContraptionAnchors();
dimensional.updateRenderedCutoff();
}
updateTrackGraph();
}
private void tickArrivalSound(CarriageContraption cc) { private void tickArrivalSound(CarriageContraption cc) {
List<Carriage> carriages = carriage.train.carriages; List<Carriage> carriages = carriage.train.carriages;
@ -454,6 +466,11 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
super.readAdditional(compound, spawnPacket); super.readAdditional(compound, spawnPacket);
trainId = compound.getUUID("TrainId"); trainId = compound.getUUID("TrainId");
carriageIndex = compound.getInt("CarriageIndex"); carriageIndex = compound.getInt("CarriageIndex");
if (spawnPacket) {
xOld = getX();
yOld = getY();
zOld = getZ();
}
} }
@Override @Override
@ -708,11 +725,6 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
dimensional.updateRenderedCutoff(); dimensional.updateRenderedCutoff();
} }
public void setGraph(@Nullable UUID graphId) {
entityData.set(TRACK_GRAPH, Optional.ofNullable(graphId));
prevPosInvalid = true;
}
@Override @Override
public boolean isReadyForRender() { public boolean isReadyForRender() {
return super.isReadyForRender() && validForRender && !firstPositionUpdate; return super.isReadyForRender() && validForRender && !firstPositionUpdate;

View file

@ -6,6 +6,7 @@ import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance;
import com.jozufozu.flywheel.util.AnimationTickHolder; import com.jozufozu.flywheel.util.AnimationTickHolder;
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.math.Vector3f;
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;
@ -54,8 +55,9 @@ public class CarriageContraptionInstance extends EntityInstance<CarriageContrapt
ms.pushPose(); ms.pushPose();
Vector3f instancePosition = getInstancePosition(partialTicks);
TransformStack.cast(ms) TransformStack.cast(ms)
.translate(getInstancePosition(partialTicks)); .translate(instancePosition);
for (boolean current : Iterate.trueAndFalse) { for (boolean current : Iterate.trueAndFalse) {
BogeyInstance instance = bogeys.get(current); BogeyInstance instance = bogeys.get(current);

View file

@ -402,7 +402,6 @@ public class Train {
navigation.cancelNavigation(); navigation.cancelNavigation();
runtime.tick(level); runtime.tick(level);
derailed = true; derailed = true;
syncTrackGraphChanges();
status.highStress(); status.highStress();
} else if (speed != 0) } else if (speed != 0)
@ -683,7 +682,6 @@ public class Train {
speed = -Mth.clamp(speed, -.5, .5); speed = -Mth.clamp(speed, -.5, .5);
derailed = true; derailed = true;
graph = null; graph = null;
syncTrackGraphChanges();
status.crash(); status.crash();
for (Carriage carriage : carriages) for (Carriage carriage : carriages)
@ -840,7 +838,6 @@ public class Train {
migrationCooldown = 40; migrationCooldown = 40;
status.failedMigration(); status.failedMigration();
derailed = true; derailed = true;
syncTrackGraphChanges();
return; return;
} }
@ -859,16 +856,10 @@ public class Train {
currentStation.reserveFor(this); currentStation.reserveFor(this);
updateSignalBlocks = true; updateSignalBlocks = true;
migrationCooldown = 0; migrationCooldown = 0;
syncTrackGraphChanges();
return; return;
} }
} }
public void syncTrackGraphChanges() {
for (Carriage carriage : carriages)
carriage.forEachPresentEntity(e -> e.setGraph(graph == null ? null : graph.id));
}
public int getTotalLength() { public int getTotalLength() {
int length = 0; int length = 0;
for (int i = 0; i < carriages.size(); i++) { for (int i = 0; i < carriages.size(); i++) {

View file

@ -95,7 +95,6 @@ public class TrainRelocationPacket extends SimplePacketBase {
if (TrainRelocator.relocate(train, sender.level, pos, hoveredBezier, direction, lookAngle, false)) { if (TrainRelocator.relocate(train, sender.level, pos, hoveredBezier, direction, lookAngle, false)) {
sender.displayClientMessage(Lang.translate("train.relocate.success") sender.displayClientMessage(Lang.translate("train.relocate.success")
.withStyle(ChatFormatting.GREEN), true); .withStyle(ChatFormatting.GREEN), true);
train.syncTrackGraphChanges();
train.carriages.forEach(c -> c.forEachPresentEntity(e -> e.nonDamageTicks = 10)); train.carriages.forEach(c -> c.forEachPresentEntity(e -> e.nonDamageTicks = 10));
return; return;
} }

View file

@ -197,11 +197,9 @@ public class FlapDisplayBlock extends HorizontalKineticBlock
MutableBlockPos currentPos = new MutableBlockPos(); MutableBlockPos currentPos = new MutableBlockPos();
Axis axis = getConnectionAxis(state); Axis axis = getConnectionAxis(state);
for (Direction connection : Iterate.directions) { for (Direction connection : Iterate.directionsInAxis(Axis.Y)) {
if (connection.getAxis() == axis)
continue;
boolean connect = true; boolean connect = true;
Move: for (Direction movement : Iterate.directionsInAxis(axis)) { Move: for (Direction movement : Iterate.directionsInAxis(axis)) {
currentPos.set(pos); currentPos.set(pos);
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
@ -334,8 +332,9 @@ public class FlapDisplayBlock extends HorizontalKineticBlock
.isReplaceable()); .isReplaceable());
return directions.isEmpty() ? PlacementOffset.fail() return directions.isEmpty() ? PlacementOffset.fail()
: PlacementOffset.success(pos.relative(directions.get(0)), : PlacementOffset.success(pos.relative(directions.get(0)), s -> AllBlocks.DISPLAY_BOARD.get()
s -> s.setValue(HORIZONTAL_FACING, state.getValue(FlapDisplayBlock.HORIZONTAL_FACING))); .updateColumn(world, pos.relative(directions.get(0)),
s.setValue(HORIZONTAL_FACING, state.getValue(FlapDisplayBlock.HORIZONTAL_FACING)), true));
} }
} }

View file

@ -25,6 +25,7 @@ public class FlapDisplaySection {
boolean hasGap; boolean hasGap;
boolean rightAligned; boolean rightAligned;
boolean wideFlaps; boolean wideFlaps;
boolean sendTransition;
String cycle; String cycle;
Component component; Component component;
@ -56,6 +57,7 @@ public class FlapDisplaySection {
public void setText(Component component) { public void setText(Component component) {
this.component = component; this.component = component;
sendTransition = true;
} }
private void refresh(boolean transition) { private void refresh(boolean transition) {
@ -73,9 +75,9 @@ public class FlapDisplaySection {
newText = rightAligned ? whitespace + newText : newText + whitespace; newText = rightAligned ? whitespace + newText : newText + whitespace;
if (!text.isEmpty()) if (!text.isEmpty())
for (int i = 0; i < spinning.length; i++) for (int i = 0; i < spinning.length; i++)
spinning[i] |= text.charAt(i) != newText.charAt(i); spinning[i] |= transition && text.charAt(i) != newText.charAt(i);
} else if (!text.isEmpty()) } else if (!text.isEmpty())
spinning[0] |= !newText.equals(text); spinning[0] |= transition && !newText.equals(text);
text = newText; text = newText;
spinningTicks = 0; spinningTicks = 0;
@ -131,6 +133,9 @@ public class FlapDisplaySection {
NBTHelper.putMarker(tag, "Wide"); NBTHelper.putMarker(tag, "Wide");
if (component != null) if (component != null)
tag.putString("Text", Component.Serializer.toJson(component)); tag.putString("Text", Component.Serializer.toJson(component));
if (sendTransition)
NBTHelper.putMarker(tag, "Transition");
sendTransition = false;
return tag; return tag;
} }
@ -149,7 +154,7 @@ public class FlapDisplaySection {
return section; return section;
section.component = Component.Serializer.fromJson(tag.getString("Text")); section.component = Component.Serializer.fromJson(tag.getString("Text"));
section.refresh(false); section.refresh(tag.getBoolean("Transition"));
return section; return section;
} }
@ -157,7 +162,7 @@ public class FlapDisplaySection {
component = Component.Serializer.fromJson(tag.getString("Text")); component = Component.Serializer.fromJson(tag.getString("Text"));
if (cyclingOptions == null) if (cyclingOptions == null)
cyclingOptions = getFlapCycle(cycle); cyclingOptions = getFlapCycle(cycle);
refresh(true); refresh(tag.getBoolean("Transition"));
} }
public boolean renderCharsIndividually() { public boolean renderCharsIndividually() {

View file

@ -65,6 +65,7 @@ import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.item.context.BlockPlaceContext;
@ -170,7 +171,9 @@ public class TrackBlock extends Block
.offset(new BlockPos(bestAxis.scale(neg ? -1 : 1))); .offset(new BlockPos(bestAxis.scale(neg ? -1 : 1)));
if (level.getBlockState(offset) if (level.getBlockState(offset)
.isFaceSturdy(level, offset, Direction.UP)) { .isFaceSturdy(level, offset, Direction.UP)
&& !level.getBlockState(offset.above())
.isFaceSturdy(level, offset, Direction.DOWN)) {
if (best == TrackShape.XO) if (best == TrackShape.XO)
best = neg ? TrackShape.AW : TrackShape.AE; best = neg ? TrackShape.AW : TrackShape.AE;
if (best == TrackShape.ZO) if (best == TrackShape.ZO)
@ -186,6 +189,19 @@ public class TrackBlock extends Block
return PushReaction.BLOCK; return PushReaction.BLOCK;
} }
@Override
public void playerWillDestroy(Level pLevel, BlockPos pPos, BlockState pState, Player pPlayer) {
super.playerWillDestroy(pLevel, pPos, pState, pPlayer);
if (pLevel.isClientSide())
return;
if (!pPlayer.isCreative())
return;
withTileEntityDo(pLevel, pPos, te -> {
te.cancelDrops = true;
te.removeInboundConnections();
});
}
@Override @Override
public void onPlace(BlockState pState, Level pLevel, BlockPos pPos, BlockState pOldState, boolean pIsMoving) { public void onPlace(BlockState pState, Level pLevel, BlockPos pPos, BlockState pOldState, boolean pIsMoving) {
if (pOldState.getBlock() == this && pState.setValue(HAS_TE, true) == pOldState.setValue(HAS_TE, true)) if (pOldState.getBlock() == this && pState.setValue(HAS_TE, true) == pOldState.setValue(HAS_TE, true))
@ -198,6 +214,12 @@ public class TrackBlock extends Block
updateGirders(pState, pLevel, pPos, blockTicks); updateGirders(pState, pLevel, pPos, blockTicks);
} }
@Override
public void setPlacedBy(Level pLevel, BlockPos pPos, BlockState pState, LivingEntity pPlacer, ItemStack pStack) {
super.setPlacedBy(pLevel, pPos, pState, pPlacer, pStack);
withTileEntityDo(pLevel, pPos, TrackTileEntity::validateConnections);
}
@Override @Override
public void tick(BlockState state, ServerLevel level, BlockPos pos, Random p_60465_) { public void tick(BlockState state, ServerLevel level, BlockPos pos, Random p_60465_) {
TrackPropagator.onRailAdded(level, pos, state); TrackPropagator.onRailAdded(level, pos, state);

View file

@ -38,6 +38,8 @@ import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
@ -47,7 +49,6 @@ import net.minecraftforge.fml.DistExecutor;
public class TrackTileEntity extends SmartTileEntity implements ITransformableTE, IMergeableTE { public class TrackTileEntity extends SmartTileEntity implements ITransformableTE, IMergeableTE {
Map<BlockPos, BezierConnection> connections; Map<BlockPos, BezierConnection> connections;
boolean connectionsValidated;
boolean cancelDrops; boolean cancelDrops;
public Pair<ResourceKey<Level>, BlockPos> boundLocation; public Pair<ResourceKey<Level>, BlockPos> boundLocation;
@ -55,13 +56,10 @@ public class TrackTileEntity extends SmartTileEntity implements ITransformableTE
public TrackTileEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) { public TrackTileEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state); super(type, pos, state);
connections = new HashMap<>(); connections = new HashMap<>();
connectionsValidated = false;
setLazyTickRate(100); setLazyTickRate(100);
} }
public Map<BlockPos, BezierConnection> getConnections() { public Map<BlockPos, BezierConnection> getConnections() {
if (!level.isClientSide && !connectionsValidated)
validateConnections();
return connections; return connections;
} }
@ -79,7 +77,7 @@ public class TrackTileEntity extends SmartTileEntity implements ITransformableTE
manageFakeTracksAlong(connection, false); manageFakeTracksAlong(connection, false);
} }
private void validateConnections() { public void validateConnections() {
Set<BlockPos> invalid = new HashSet<>(); Set<BlockPos> invalid = new HashSet<>();
for (Entry<BlockPos, BezierConnection> entry : connections.entrySet()) { for (Entry<BlockPos, BezierConnection> entry : connections.entrySet()) {
@ -109,7 +107,6 @@ public class TrackTileEntity extends SmartTileEntity implements ITransformableTE
trackTE.addConnection(bc.secondary()); trackTE.addConnection(bc.secondary());
} }
connectionsValidated = true;
for (BlockPos blockPos : invalid) for (BlockPos blockPos : invalid)
removeConnection(blockPos); removeConnection(blockPos);
} }
@ -223,7 +220,7 @@ public class TrackTileEntity extends SmartTileEntity implements ITransformableTE
public void accept(BlockEntity other) { public void accept(BlockEntity other) {
if (other instanceof TrackTileEntity track) if (other instanceof TrackTileEntity track)
connections.putAll(track.connections); connections.putAll(track.connections);
connectionsValidated = false; validateConnections();
level.scheduleTick(worldPosition, getBlockState().getBlock(), 1); level.scheduleTick(worldPosition, getBlockState().getBlock(), 1);
} }
@ -384,6 +381,10 @@ public class TrackTileEntity extends SmartTileEntity implements ITransformableTE
continue; continue;
} }
FluidState fluidState = stateAtPos.getFluidState();
if (!fluidState.isSourceOfType(Fluids.WATER))
continue;
if (!present && stateAtPos.getMaterial() if (!present && stateAtPos.getMaterial()
.isReplaceable()) .isReplaceable())
level.setBlock(targetPos, level.setBlock(targetPos,

View file

@ -48,6 +48,7 @@ public class ConnectedPillarBlock extends LayeredBlock {
private BlockState updateColumn(Level level, BlockPos pos, BlockState state, boolean present) { private BlockState updateColumn(Level level, BlockPos pos, BlockState state, boolean present) {
MutableBlockPos currentPos = new MutableBlockPos(); MutableBlockPos currentPos = new MutableBlockPos();
Axis axis = state.getValue(AXIS); Axis axis = state.getValue(AXIS);
for (Direction connection : Iterate.directions) { for (Direction connection : Iterate.directions) {
if (connection.getAxis() == axis) if (connection.getAxis() == axis)
continue; continue;
@ -56,7 +57,7 @@ public class ConnectedPillarBlock extends LayeredBlock {
Move: for (Direction movement : Iterate.directionsInAxis(axis)) { Move: for (Direction movement : Iterate.directionsInAxis(axis)) {
currentPos.set(pos); currentPos.set(pos);
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
if (!level.isAreaLoaded(currentPos, 1)) if (!level.isLoaded(currentPos))
break; break;
BlockState other1 = currentPos.equals(pos) ? state : level.getBlockState(currentPos); BlockState other1 = currentPos.equals(pos) ? state : level.getBlockState(currentPos);

View file

@ -0,0 +1,34 @@
package com.simibubi.create.foundation.mixin;
import javax.annotation.Nullable;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Intrinsic;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity;
import net.minecraft.world.entity.Entity;
import net.minecraftforge.common.capabilities.CapabilityProvider;
import net.minecraftforge.common.extensions.IForgeEntity;
@Mixin(Entity.class)
@Implements(@Interface(iface = IForgeEntity.class, prefix = "iForgeEntity$"))
public abstract class ContraptionDriverInteractMixin extends CapabilityProvider<Entity> {
private ContraptionDriverInteractMixin(Class<Entity> baseClass) {
super(baseClass);
}
@Shadow
public abstract Entity getRootVehicle();
@Nullable
@Intrinsic
public boolean iForgeEntity$canRiderInteract() {
return getRootVehicle() instanceof AbstractContraptionEntity;
}
}

View file

@ -1,6 +1,5 @@
{ {
"credit": "Made with Blockbench", "credit": "Made with Blockbench",
"parent": "create:item/potato_cannon/item",
"texture_size": [32, 32], "texture_size": [32, 32],
"textures": { "textures": {
"1": "create:item/potato_cannon", "1": "create:item/potato_cannon",

View file

@ -7,6 +7,7 @@
"mixins": [ "mixins": [
"CustomItemUseEffectsMixin", "CustomItemUseEffectsMixin",
"MapItemSavedDataMixin", "MapItemSavedDataMixin",
"ContraptionDriverInteractMixin",
"accessor.AbstractProjectileDispenseBehaviorAccessor", "accessor.AbstractProjectileDispenseBehaviorAccessor",
"accessor.DispenserBlockAccessor", "accessor.DispenserBlockAccessor",
"accessor.FallingBlockEntityAccessor", "accessor.FallingBlockEntityAccessor",