diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionHandler.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionHandler.java index 21664ce2e..30f6a6a9d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionHandler.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionHandler.java @@ -7,6 +7,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher; import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.WorldAttached; @@ -17,7 +18,9 @@ import net.minecraft.entity.LivingEntity; import net.minecraft.nbt.CompoundNBT; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; +import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.common.util.Constants.NBT; +import net.minecraftforge.fml.DistExecutor; public class ContraptionHandler { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionRenderDispatcher.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionRenderDispatcher.java index 2fbf9eb5a..ff7b72608 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionRenderDispatcher.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionRenderDispatcher.java @@ -10,6 +10,10 @@ import com.simibubi.create.foundation.render.TileEntityRenderHelper; import com.simibubi.create.foundation.render.backend.FastRenderDispatcher; import com.simibubi.create.foundation.render.backend.Backend; import com.simibubi.create.foundation.utility.AnimationTickHolder; +import com.simibubi.create.foundation.utility.Pair; +import com.simibubi.create.foundation.utility.worldWrappers.PlacementSimulationWorld; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.Matrix4f; @@ -30,9 +34,12 @@ import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ForkJoinPool; public class ContraptionRenderDispatcher { - public static final HashMap renderers = new HashMap<>(); + public static final Int2ObjectMap renderers = new Int2ObjectOpenHashMap<>(); public static void notifyLightUpdate(ILightReader world, LightType type, SectionPos pos) { for (RenderedContraption renderer : renderers.values()) { @@ -82,16 +89,15 @@ public class ContraptionRenderDispatcher { } private static RenderedContraption getRenderer(World world, Contraption c) { - RenderedContraption renderer; int entityId = c.entity.getEntityId(); - if (renderers.containsKey(entityId)) { - renderer = renderers.get(entityId); - } else { - renderer = new RenderedContraption(world, c); - renderers.put(entityId, renderer); + RenderedContraption contraption = renderers.get(entityId); + + if (contraption == null) { + contraption = new RenderedContraption(world, c); + renderers.put(entityId, contraption); } - return renderer; + return contraption; } public static void renderLayer(RenderType layer, Matrix4f viewProjection, float camX, float camY, float camZ) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/RenderedContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/RenderedContraption.java index 1d8108e4e..ddcf78be9 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/RenderedContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/RenderedContraption.java @@ -34,7 +34,7 @@ import java.util.List; import java.util.Random; public class RenderedContraption { - private HashMap renderLayers = new HashMap<>(); + private final HashMap renderLayers = new HashMap<>(); public final PlacementSimulationWorld renderWorld; diff --git a/src/main/java/com/simibubi/create/foundation/utility/worldWrappers/PlacementSimulationWorld.java b/src/main/java/com/simibubi/create/foundation/utility/worldWrappers/PlacementSimulationWorld.java index e7f740ebe..8e8d71b3c 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/worldWrappers/PlacementSimulationWorld.java +++ b/src/main/java/com/simibubi/create/foundation/utility/worldWrappers/PlacementSimulationWorld.java @@ -89,6 +89,10 @@ public class PlacementSimulationWorld extends WrappedWorld { return true; } + public BlockState getBlockState(int x, int y, int z) { + return getBlockState(scratch.setPos(x, y, z)); + } + @Override public BlockState getBlockState(BlockPos pos) { BlockState state = blocksAdded.get(pos); diff --git a/src/main/java/com/simibubi/create/foundation/utility/worldWrappers/chunk/WrappedChunk.java b/src/main/java/com/simibubi/create/foundation/utility/worldWrappers/chunk/WrappedChunk.java index 521d5319d..e21d3d044 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/worldWrappers/chunk/WrappedChunk.java +++ b/src/main/java/com/simibubi/create/foundation/utility/worldWrappers/chunk/WrappedChunk.java @@ -30,11 +30,13 @@ import java.util.stream.Stream; public class WrappedChunk implements IChunk { - private final PlacementSimulationWorld world; - private boolean needsLight; - private final int x; - private final int z; - private final ChunkPos pos; + final PlacementSimulationWorld world; + boolean needsLight; + final int x; + final int z; + final ChunkPos pos; + + private final ChunkSection[] sections; public WrappedChunk(PlacementSimulationWorld world, int x, int z) { this.world = world; @@ -42,6 +44,12 @@ public class WrappedChunk implements IChunk { this.x = x; this.z = z; this.pos = new ChunkPos(x, z); + + this.sections = new ChunkSection[16]; + + for (int i = 0; i < 16; i++) { + sections[i] = new WrappedChunkSection(this, i << 4); + } } @Override @@ -57,6 +65,11 @@ public class WrappedChunk implements IChunk { .map(Map.Entry::getKey); } + @Override + public ChunkSection[] getSections() { + return sections; + } + @Nullable @Override public BlockState setBlockState(BlockPos p_177436_1_, BlockState p_177436_2_, boolean p_177436_3_) { @@ -78,11 +91,6 @@ public class WrappedChunk implements IChunk { return null; } - @Override - public ChunkSection[] getSections() { - return new ChunkSection[0]; - } - @Override public Collection> func_217311_f() { return null; diff --git a/src/main/java/com/simibubi/create/foundation/utility/worldWrappers/chunk/WrappedChunkSection.java b/src/main/java/com/simibubi/create/foundation/utility/worldWrappers/chunk/WrappedChunkSection.java new file mode 100644 index 000000000..e5e90594d --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/utility/worldWrappers/chunk/WrappedChunkSection.java @@ -0,0 +1,32 @@ +package com.simibubi.create.foundation.utility.worldWrappers.chunk; + +import net.minecraft.block.BlockState; +import net.minecraft.world.chunk.ChunkSection; + +public class WrappedChunkSection extends ChunkSection { + + public WrappedChunk owner; + + public final int xStart; + public final int yStart; + public final int zStart; + + public WrappedChunkSection(WrappedChunk owner, int yBase) { + super(yBase); + this.owner = owner; + this.xStart = owner.pos.getXStart(); + this.yStart = yBase; + this.zStart = owner.pos.getZStart(); + } + + @Override + public BlockState getBlockState(int x, int y, int z) { + // ChunkSection#getBlockState expects local chunk coordinates, so we add to get back into world coords. + return owner.world.getBlockState(x + xStart, y + yStart, z + zStart); + } + + @Override + public BlockState setBlockState(int p_177484_1_, int p_177484_2_, int p_177484_3_, BlockState p_177484_4_, boolean p_177484_5_) { + throw new IllegalStateException("Chunk sections should not be mutated in a fake world."); + } +}