From b18993ed268fbe6e1e5d7cbccea52a234064829c Mon Sep 17 00:00:00 2001 From: JozsefA Date: Wed, 24 Mar 2021 15:48:15 -0700 Subject: [PATCH 1/9] Little things. - Quark magnets don't crash (already fixed). - Fix quark magnet leaving behind ghost instances. - Fix crash with belt lighting after being placed by contraptions. - Simplify tile add/remove mixins and avoid conflict with Performant. - Avoid FloatBuffer detour when uploading matrix uniforms. - InstancedTileRenderer no longer has to clean up. - Properly let go of tickable instances. --- .../relays/belt/BeltTileEntity.java | 20 +- .../foundation/mixin/AddRemoveTileMixin.java | 72 ----- .../create/foundation/mixin/TileAddMixin.java | 29 ++ .../foundation/mixin/TileRemoveMixin.java | 25 ++ .../foundation/render/backend/Backend.java | 124 ++++----- .../foundation/render/backend/RenderUtil.java | 31 ++- .../render/backend/ShaderLoader.java | 247 +++++++++--------- .../render/backend/gl/BasicProgram.java | 6 +- .../backend/instancing/IDynamicInstance.java | 3 +- .../backend/instancing/ITickableInstance.java | 4 + .../instancing/InstancedTileRenderer.java | 13 +- .../backend/instancing/impl/ModelData.java | 2 +- src/main/resources/create.mixins.json | 14 +- 13 files changed, 300 insertions(+), 290 deletions(-) delete mode 100644 src/main/java/com/simibubi/create/foundation/mixin/AddRemoveTileMixin.java create mode 100644 src/main/java/com/simibubi/create/foundation/mixin/TileAddMixin.java create mode 100644 src/main/java/com/simibubi/create/foundation/mixin/TileRemoveMixin.java diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java index 95b756234..4fe5b0f48 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java @@ -548,18 +548,20 @@ public class BeltTileEntity extends KineticTileEntity implements LightUpdateList } private void initializeLight() { - light = new byte[beltLength * 2]; + if (beltLength > 0) { + light = new byte[beltLength * 2]; - Vec3i vec = getBeltFacing().getDirectionVec(); - BeltSlope slope = getBlockState().get(BeltBlock.SLOPE); - int verticality = slope == BeltSlope.DOWNWARD ? -1 : slope == BeltSlope.UPWARD ? 1 : 0; + Vec3i vec = getBeltFacing().getDirectionVec(); + BeltSlope slope = getBlockState().get(BeltBlock.SLOPE); + int verticality = slope == BeltSlope.DOWNWARD ? -1 : slope == BeltSlope.UPWARD ? 1 : 0; - BlockPos.Mutable pos = new BlockPos.Mutable(controller); - for (int i = 0; i < beltLength * 2; i += 2) { - light[i] = (byte) world.getLightLevel(LightType.BLOCK, pos); - light[i + 1] = (byte) world.getLightLevel(LightType.SKY, pos); + BlockPos.Mutable pos = new BlockPos.Mutable(controller); + for (int i = 0; i < beltLength * 2; i += 2) { + light[i] = (byte) world.getLightLevel(LightType.BLOCK, pos); + light[i + 1] = (byte) world.getLightLevel(LightType.SKY, pos); - pos.move(vec.getX(), verticality, vec.getZ()); + pos.move(vec.getX(), verticality, vec.getZ()); + } } } diff --git a/src/main/java/com/simibubi/create/foundation/mixin/AddRemoveTileMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/AddRemoveTileMixin.java deleted file mode 100644 index 8496fdee8..000000000 --- a/src/main/java/com/simibubi/create/foundation/mixin/AddRemoveTileMixin.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.simibubi.create.foundation.mixin; - -import com.simibubi.create.foundation.render.KineticRenderer; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; - -import com.simibubi.create.CreateClient; - -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; - -import java.util.Set; - -@OnlyIn(Dist.CLIENT) -@Mixin(value = World.class, priority = 1042) -public class AddRemoveTileMixin { - - @Shadow @Final public boolean isRemote; - - @Shadow @Final protected Set tileEntitiesToBeRemoved; - - /** - * JUSTIFICATION: This method is called whenever a tile entity is removed due - * to a change in block state, even on the client. By hooking into this method, - * we gain easy access to the information while having no impact on performance. - */ - @Inject(at = @At( - value = "INVOKE_ASSIGN", - target = "Lnet/minecraft/world/World;getTileEntity(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/tileentity/TileEntity;" - ), - method = "removeTileEntity", - locals = LocalCapture.CAPTURE_FAILHARD - ) - private void onRemoveTile(BlockPos pos, CallbackInfo ci, TileEntity te) { - if (isRemote) { - World thi = (World)(Object) this; - CreateClient.kineticRenderer.get(thi).remove(te); - } - } - - @Inject(at = @At("TAIL"), method = "addTileEntity") - private void onAddTile(TileEntity te, CallbackInfoReturnable cir) { - if (isRemote) { - World thi = (World)(Object) this; - CreateClient.kineticRenderer.get(thi).queueAdd(te); - } - } - - @Inject(at = @At( - value = "INVOKE", - target = "Ljava/util/Set;clear()V", ordinal = 0 - ), - method = "tickBlockEntities") - private void onChunkUnload(CallbackInfo ci) { - if (isRemote) { - World thi = (World)(Object) this; - KineticRenderer kineticRenderer = CreateClient.kineticRenderer.get(thi); - for (TileEntity tile : tileEntitiesToBeRemoved) { - kineticRenderer.remove(tile); - } - } - } -} diff --git a/src/main/java/com/simibubi/create/foundation/mixin/TileAddMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/TileAddMixin.java new file mode 100644 index 000000000..650968b45 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/mixin/TileAddMixin.java @@ -0,0 +1,29 @@ +package com.simibubi.create.foundation.mixin; + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import com.simibubi.create.CreateClient; + +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + +@OnlyIn(Dist.CLIENT) +@Mixin(World.class) +public class TileAddMixin { + + @Shadow @Final public boolean isRemote; + + @Inject(at = @At("TAIL"), method = "addTileEntity") + private void onAddTile(TileEntity te, CallbackInfoReturnable cir) { + if (isRemote) { + CreateClient.kineticRenderer.get((World)(Object) this).queueAdd(te); + } + } +} diff --git a/src/main/java/com/simibubi/create/foundation/mixin/TileRemoveMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/TileRemoveMixin.java new file mode 100644 index 000000000..c34c25c79 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/mixin/TileRemoveMixin.java @@ -0,0 +1,25 @@ +package com.simibubi.create.foundation.mixin; + +import net.minecraft.client.world.ClientWorld; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; + +import javax.annotation.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import com.simibubi.create.CreateClient; + +@Mixin(TileEntity.class) +public class TileRemoveMixin { + + @Shadow @Nullable protected World world; + + @Inject(at = @At("TAIL"), method = "remove") + private void onRemove(CallbackInfo ci) { + if (world instanceof ClientWorld) + CreateClient.kineticRenderer.get(this.world).remove((TileEntity) (Object) this); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/Backend.java b/src/main/java/com/simibubi/create/foundation/render/backend/Backend.java index 3c3891c17..20292f6d7 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/Backend.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/Backend.java @@ -11,6 +11,7 @@ import com.simibubi.create.foundation.render.backend.instancing.IFlywheelWorld; import net.minecraft.world.World; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.lwjgl.opengl.GL; import org.lwjgl.opengl.GLCapabilities; import org.lwjgl.system.MemoryUtil; @@ -23,82 +24,85 @@ import net.minecraft.util.ResourceLocation; import net.minecraftforge.resource.ISelectiveResourceReloadListener; public class Backend { - public static final Boolean SHADER_DEBUG_OUTPUT = true; + public static final Boolean SHADER_DEBUG_OUTPUT = true; - public static final Logger log = LogManager.getLogger(Backend.class); - public static final FloatBuffer MATRIX_BUFFER = MemoryUtil.memAllocFloat(16); + public static final Logger log = LogManager.getLogger(Backend.class); + public static GLCapabilities capabilities; + public static GlFeatureCompat compat; - static final Map> registry = new HashMap<>(); - static final Map, ProgramGroup> programs = new HashMap<>(); + private static boolean instancingAvailable; + private static boolean enabled; - private static boolean enabled; + static final Map> registry = new HashMap<>(); + static final Map, ProgramGroup> programs = new HashMap<>(); - public static GLCapabilities capabilities; - public static GlFeatureCompat compat; + public Backend() { + throw new IllegalStateException(); + } - public Backend() { - throw new IllegalStateException(); - } + /** + * Register a shader program. TODO: replace with forge registry? + */ + public static

> S register(S spec) { + ResourceLocation name = spec.name; + if (registry.containsKey(name)) { + throw new IllegalStateException("Program spec '" + name + "' already registered."); + } + registry.put(name, spec); + return spec; + } - /** - * Register a shader program. TODO: replace with forge registry? - */ - public static

> S register(S spec) { - ResourceLocation name = spec.name; - if (registry.containsKey(name)) { - throw new IllegalStateException("Program spec '" + name + "' already registered."); - } - registry.put(name, spec); - return spec; - } + @SuppressWarnings("unchecked") + public static

> P getProgram(S spec) { + return (P) programs.get(spec).get(GlFog.getFogMode()); + } - @SuppressWarnings("unchecked") - public static

> P getProgram(S spec) { - return (P) programs.get(spec).get(GlFog.getFogMode()); - } + public static boolean isFlywheelWorld(World world) { + return world == Minecraft.getInstance().world || (world instanceof IFlywheelWorld && ((IFlywheelWorld) world).supportsFlywheel()); + } - public static boolean isFlywheelWorld(World world) { - return world == Minecraft.getInstance().world || (world instanceof IFlywheelWorld && ((IFlywheelWorld) world).supportsFlywheel()); - } + public static boolean available() { + return canUseVBOs(); + } - public static boolean available() { - return canUseVBOs(); - } + public static boolean canUseInstancing() { + return enabled && instancingAvailable; + } - public static boolean canUseInstancing() { - return enabled && - compat.vertexArrayObjectsSupported() && - compat.drawInstancedSupported() && - compat.instancedArraysSupported(); - } + public static boolean canUseVBOs() { + return enabled && gl20(); + } - public static boolean canUseVBOs() { - return enabled && gl20(); - } + public static boolean gl33() { + return capabilities.OpenGL33; + } - public static boolean gl33() { - return capabilities.OpenGL33; - } + public static boolean gl20() { + return capabilities.OpenGL20; + } - public static boolean gl20() { - return capabilities.OpenGL20; - } + public static void init() { + // Can be null when running datagenerators due to the unfortunate time we call this + Minecraft mc = Minecraft.getInstance(); + if (mc == null) return; - public static void init() { - // Can be null when running datagenerators due to the unfortunate time we call this - Minecraft mc = Minecraft.getInstance(); - if (mc == null) return; + IResourceManager manager = mc.getResourceManager(); - IResourceManager manager = mc.getResourceManager(); + if (manager instanceof IReloadableResourceManager) { + ISelectiveResourceReloadListener listener = ShaderLoader::onResourceManagerReload; + ((IReloadableResourceManager) manager).addReloadListener(listener); + } + } - if (manager instanceof IReloadableResourceManager) { - ISelectiveResourceReloadListener listener = ShaderLoader::onResourceManagerReload; - ((IReloadableResourceManager) manager).addReloadListener(listener); - } - } + public static void refresh() { + capabilities = GL.createCapabilities(); - public static void refresh() { - enabled = AllConfigs.CLIENT.experimentalRendering.get() && !OptifineHandler.usingShaders(); - } + compat = new GlFeatureCompat(capabilities); + instancingAvailable = compat.vertexArrayObjectsSupported() && + compat.drawInstancedSupported() && + compat.instancedArraysSupported(); + + enabled = AllConfigs.CLIENT.experimentalRendering.get() && !OptifineHandler.usingShaders(); + } } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/RenderUtil.java b/src/main/java/com/simibubi/create/foundation/render/backend/RenderUtil.java index e5ee528c2..dde1e9a15 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/RenderUtil.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/RenderUtil.java @@ -3,8 +3,7 @@ package com.simibubi.create.foundation.render.backend; import net.minecraft.client.renderer.Matrix3f; import net.minecraft.client.renderer.Matrix4f; -import java.nio.ByteBuffer; -import java.nio.FloatBuffer; +import com.mojang.blaze3d.matrix.MatrixStack; public class RenderUtil { public static int nextPowerOf2(int a) { @@ -17,9 +16,12 @@ public class RenderUtil { return b == 0 && n != 0; } - // GPUs want matrices in column major order. + public static float[] writeMatrixStack(MatrixStack stack) { + return writeMatrixStack(stack.peek().getModel(), stack.peek().getNormal()); + } - public static float[] bufferMatrices(Matrix4f model, Matrix3f normal) { + // GPUs want matrices in column major order. + public static float[] writeMatrixStack(Matrix4f model, Matrix3f normal) { return new float[] { model.a00, model.a10, @@ -48,4 +50,25 @@ public class RenderUtil { normal.a22, }; } + + public static float[] writeMatrix(Matrix4f model) { + return new float[]{ + model.a00, + model.a10, + model.a20, + model.a30, + model.a01, + model.a11, + model.a21, + model.a31, + model.a02, + model.a12, + model.a22, + model.a32, + model.a03, + model.a13, + model.a23, + model.a33, + }; + } } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/ShaderLoader.java b/src/main/java/com/simibubi/create/foundation/render/backend/ShaderLoader.java index a9a4119e5..c512fd8a7 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/ShaderLoader.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/ShaderLoader.java @@ -28,175 +28,172 @@ import java.util.stream.Collectors; import java.util.stream.Stream; public class ShaderLoader { - public static final String SHADER_DIR = "flywheel/shaders/"; - public static final ArrayList EXTENSIONS = Lists.newArrayList(".vert", ".vsh", ".frag", ".fsh", ".glsl"); + public static final String SHADER_DIR = "flywheel/shaders/"; + public static final ArrayList EXTENSIONS = Lists.newArrayList(".vert", ".vsh", ".frag", ".fsh", ".glsl"); - static final Map shaderSource = new HashMap<>(); + static final Map shaderSource = new HashMap<>(); - static void onResourceManagerReload(IResourceManager manager, Predicate predicate) { - if (predicate.test(VanillaResourceType.SHADERS)) { - Backend.capabilities = GL.createCapabilities(); - Backend.compat = new GlFeatureCompat(Backend.capabilities); + static void onResourceManagerReload(IResourceManager manager, Predicate predicate) { + if (predicate.test(VanillaResourceType.SHADERS)) { + OptifineHandler.refresh(); + Backend.refresh(); - OptifineHandler.refresh(); - Backend.refresh(); + if (Backend.gl20()) { + shaderSource.clear(); + loadShaderSources(manager); - if (Backend.gl20()) { - shaderSource.clear(); - loadShaderSources(manager); + Backend.programs.values().forEach(ProgramGroup::delete); + Backend.programs.clear(); + Backend.registry.values().forEach(ShaderLoader::loadProgram); - Backend.programs.values().forEach(ProgramGroup::delete); - Backend.programs.clear(); - Backend.registry.values().forEach(ShaderLoader::loadProgram); + Backend.log.info("Loaded all shader programs."); + } + } + } - Backend.log.info("Loaded all shader programs."); - } - } - } + private static void loadShaderSources(IResourceManager manager){ + Collection allShaders = manager.getAllResourceLocations(SHADER_DIR, s -> { + for (String ext : EXTENSIONS) { + if (s.endsWith(ext)) return true; + } + return false; + }); - private static void loadShaderSources(IResourceManager manager){ - Collection allShaders = manager.getAllResourceLocations(SHADER_DIR, s -> { - for (String ext : EXTENSIONS) { - if (s.endsWith(ext)) return true; - } - return false; - }); + for (ResourceLocation location : allShaders) { + try { + IResource resource = manager.getResource(location); - for (ResourceLocation location : allShaders) { - try { - IResource resource = manager.getResource(location); + String file = readToString(resource.getInputStream()); - String file = readToString(resource.getInputStream()); + ResourceLocation name = new ResourceLocation(location.getNamespace(), + location.getPath().substring(SHADER_DIR.length())); - ResourceLocation name = new ResourceLocation(location.getNamespace(), - location.getPath().substring(SHADER_DIR.length())); + shaderSource.put(name, file); + } catch (IOException e) { - shaderSource.put(name, file); - } catch (IOException e) { + } + } + } - } - } - } + static

> void loadProgram(S programSpec) { + Map programGroup = new EnumMap<>(GlFogMode.class); - static

> void loadProgram(S programSpec) { - Map programGroup = new EnumMap<>(GlFogMode.class); + for (GlFogMode fogMode : GlFogMode.values()) { + programGroup.put(fogMode, loadProgram(programSpec, fogMode)); + } - for (GlFogMode fogMode : GlFogMode.values()) { - programGroup.put(fogMode, loadProgram(programSpec, fogMode)); - } + Backend.programs.put(programSpec, new ProgramGroup<>(programGroup)); - Backend.programs.put(programSpec, new ProgramGroup<>(programGroup)); + Backend.log.debug("Loaded program {}", programSpec.name); + } - Backend.log.debug("Loaded program {}", programSpec.name); - } + private static

> P loadProgram(S programSpec, GlFogMode fogMode) { + GlShader vert = null; + GlShader frag = null; + try { + ShaderConstants defines = new ShaderConstants(programSpec.defines); - private static

> P loadProgram(S programSpec, GlFogMode fogMode) { - GlShader vert = null; - GlShader frag = null; - try { - ShaderConstants defines = new ShaderConstants(programSpec.defines); + defines.defineAll(fogMode.getDefines()); - defines.defineAll(fogMode.getDefines()); + vert = loadShader(programSpec.getVert(), ShaderType.VERTEX, defines); + frag = loadShader(programSpec.getFrag(), ShaderType.FRAGMENT, defines); - vert = loadShader(programSpec.getVert(), ShaderType.VERTEX, defines); - frag = loadShader(programSpec.getFrag(), ShaderType.FRAGMENT, defines); + GlProgram.Builder builder = GlProgram.builder(programSpec.name, fogMode).attachShader(vert).attachShader(frag); - GlProgram.Builder builder = GlProgram.builder(programSpec.name, fogMode).attachShader(vert).attachShader(frag); + programSpec.attributes.forEach(builder::addAttribute); - programSpec.attributes.forEach(builder::addAttribute); + return builder.build(programSpec.factory); - return builder.build(programSpec.factory); + } finally { + if (vert != null) vert.delete(); + if (frag != null) frag.delete(); + } + } - } finally { - if (vert != null) vert.delete(); - if (frag != null) frag.delete(); - } - } + private static final Pattern includePattern = Pattern.compile("#flwinclude <\"([\\w\\d_]+:[\\w\\d_./]+)\">"); - private static final Pattern includePattern = Pattern.compile("#flwinclude <\"([\\w\\d_]+:[\\w\\d_./]+)\">"); + private static String processIncludes(ResourceLocation baseName, String source) { + HashSet seen = new HashSet<>(); + seen.add(baseName); - private static String processIncludes(ResourceLocation baseName, String source) { - HashSet seen = new HashSet<>(); - seen.add(baseName); + return includeRecursive(source, seen).collect(Collectors.joining("\n")); + } - return includeRecursive(source, seen).collect(Collectors.joining("\n")); - } + private static Stream includeRecursive(String source, Set seen) { + return new BufferedReader(new StringReader(source)).lines().flatMap(line -> { - private static Stream includeRecursive(String source, Set seen) { - return new BufferedReader(new StringReader(source)).lines().flatMap(line -> { + Matcher matcher = includePattern.matcher(line); - Matcher matcher = includePattern.matcher(line); + if (matcher.find()) { + String includeName = matcher.group(1); - if (matcher.find()) { - String includeName = matcher.group(1); + ResourceLocation include = new ResourceLocation(includeName); - ResourceLocation include = new ResourceLocation(includeName); + if (seen.add(include)) { + String includeSource = shaderSource.get(include); - if (seen.add(include)) { - String includeSource = shaderSource.get(include); + if (includeSource != null) { + return includeRecursive(includeSource, seen); + } + } + } - if (includeSource != null) { - return includeRecursive(includeSource, seen); - } - } - } + return Stream.of(line); + }); + } - return Stream.of(line); - }); - } + private static GlShader loadShader(ResourceLocation name, ShaderType type, ShaderConstants defines) { + String source = shaderSource.get(name); - private static GlShader loadShader(ResourceLocation name, ShaderType type, ShaderConstants defines) { - String source = shaderSource.get(name); + source = processIncludes(name, source); - source = processIncludes(name, source); - - if (defines != null) - source = defines.process(source); + if (defines != null) + source = defines.process(source); - return new GlShader(type, name, source); - } + return new GlShader(type, name, source); + } - public static String readToString(InputStream is) { - RenderSystem.assertThread(RenderSystem::isOnRenderThread); - ByteBuffer bytebuffer = null; + public static String readToString(InputStream is) { + RenderSystem.assertThread(RenderSystem::isOnRenderThread); + ByteBuffer bytebuffer = null; - try { - bytebuffer = readToBuffer(is); - int i = bytebuffer.position(); - ((Buffer)bytebuffer).rewind(); - return MemoryUtil.memASCII(bytebuffer, i); - } catch (IOException e) { + try { + bytebuffer = readToBuffer(is); + int i = bytebuffer.position(); + ((Buffer)bytebuffer).rewind(); + return MemoryUtil.memASCII(bytebuffer, i); + } catch (IOException e) { - } finally { - if (bytebuffer != null) { - MemoryUtil.memFree(bytebuffer); - } + } finally { + if (bytebuffer != null) { + MemoryUtil.memFree(bytebuffer); + } - } + } - return null; - } + return null; + } - public static ByteBuffer readToBuffer(InputStream is) throws IOException { - ByteBuffer bytebuffer; - if (is instanceof FileInputStream) { - FileInputStream fileinputstream = (FileInputStream)is; - FileChannel filechannel = fileinputstream.getChannel(); - bytebuffer = MemoryUtil.memAlloc((int)filechannel.size() + 1); + public static ByteBuffer readToBuffer(InputStream is) throws IOException { + ByteBuffer bytebuffer; + if (is instanceof FileInputStream) { + FileInputStream fileinputstream = (FileInputStream)is; + FileChannel filechannel = fileinputstream.getChannel(); + bytebuffer = MemoryUtil.memAlloc((int)filechannel.size() + 1); - while (filechannel.read(bytebuffer) != -1) { } - } else { - bytebuffer = MemoryUtil.memAlloc(8192); - ReadableByteChannel readablebytechannel = Channels.newChannel(is); + while (filechannel.read(bytebuffer) != -1) { } + } else { + bytebuffer = MemoryUtil.memAlloc(8192); + ReadableByteChannel readablebytechannel = Channels.newChannel(is); - while (readablebytechannel.read(bytebuffer) != -1) { - if (bytebuffer.remaining() == 0) { - bytebuffer = MemoryUtil.memRealloc(bytebuffer, bytebuffer.capacity() * 2); - } - } - } + while (readablebytechannel.read(bytebuffer) != -1) { + if (bytebuffer.remaining() == 0) { + bytebuffer = MemoryUtil.memRealloc(bytebuffer, bytebuffer.capacity() * 2); + } + } + } - return bytebuffer; - } + return bytebuffer; + } } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/gl/BasicProgram.java b/src/main/java/com/simibubi/create/foundation/render/backend/gl/BasicProgram.java index bef778f9a..29467719e 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/gl/BasicProgram.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/gl/BasicProgram.java @@ -1,5 +1,6 @@ package com.simibubi.create.foundation.render.backend.gl; +import com.simibubi.create.foundation.render.backend.RenderUtil; import com.simibubi.create.foundation.render.backend.gl.shader.ProgramFogMode; import org.lwjgl.opengl.GL20; @@ -53,9 +54,6 @@ public class BasicProgram extends GlProgram { } protected static void uploadMatrixUniform(int uniform, Matrix4f mat) { - Backend.MATRIX_BUFFER.position(0); - mat.write(Backend.MATRIX_BUFFER); - Backend.MATRIX_BUFFER.rewind(); - GL20.glUniformMatrix4fv(uniform, false, Backend.MATRIX_BUFFER); + GL20.glUniformMatrix4fv(uniform, false, RenderUtil.writeMatrix(mat)); } } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/IDynamicInstance.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/IDynamicInstance.java index 0af4bc1eb..2e0914698 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/IDynamicInstance.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/IDynamicInstance.java @@ -2,7 +2,8 @@ package com.simibubi.create.foundation.render.backend.instancing; public interface IDynamicInstance { /** - * Called every frame, this can be used to make more dynamic animations. + * Called every frame. This can be used to smoothly change instance data + * to allow for fancy animations that could not be achieved on the GPU alone. */ void beginFrame(); } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/ITickableInstance.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/ITickableInstance.java index 04a6f7ec0..a93f7b8d3 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/ITickableInstance.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/ITickableInstance.java @@ -2,5 +2,9 @@ package com.simibubi.create.foundation.render.backend.instancing; public interface ITickableInstance { + /** + * Called every tick. This is useful for things that don't have to be smooth, + * or to recalculate something that would only change after a game tick. + */ void tick(); } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java index 74bda0057..a0a488329 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java @@ -39,14 +39,6 @@ public abstract class InstancedTileRenderer

{ public abstract void registerMaterials(); public void tick() { - int ticks = AnimationTickHolder.getTicks(); - - // Clean up twice a second. This doesn't have to happen every tick, - // but this does need to be run to ensure we don't miss anything. - if (ticks % 10 == 0) { - clean(); - } - if (tickableInstances.size() > 0) tickableInstances.values().forEach(ITickableInstance::tick); } @@ -187,16 +179,13 @@ public abstract class InstancedTileRenderer

{ return renderer; } - private void clean() { - instances.keySet().removeIf(TileEntity::isRemoved); - } - public void invalidate() { for (RenderMaterial material : materials.values()) { material.delete(); } instances.clear(); dynamicInstances.clear(); + tickableInstances.clear(); } public boolean canCreateInstance(TileEntity tile) { diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/ModelData.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/ModelData.java index 170d555a7..2ad27e1b2 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/ModelData.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/ModelData.java @@ -16,7 +16,7 @@ public class ModelData extends BasicData { } public ModelData setTransform(MatrixStack stack) { - matrices = RenderUtil.bufferMatrices(stack.peek().getModel(), stack.peek().getNormal()); + matrices = RenderUtil.writeMatrixStack(stack); return this; } diff --git a/src/main/resources/create.mixins.json b/src/main/resources/create.mixins.json index 285af7c77..1789b3b03 100644 --- a/src/main/resources/create.mixins.json +++ b/src/main/resources/create.mixins.json @@ -3,9 +3,19 @@ "package": "com.simibubi.create.foundation.mixin", "compatibilityLevel": "JAVA_8", "refmap": "create.refmap.json", - "client": ["AddRemoveTileMixin", "CancelTileEntityRenderMixin", "FogColorTrackerMixin", "LightUpdateMixin", "NetworkLightUpdateMixin", "RenderHooksMixin", "ShaderCloseMixin"], + "mixins": ["StepSoundMixin"], + "client": [ + "TileAddMixin", + "CancelTileEntityRenderMixin", + "FogColorTrackerMixin", + "LightUpdateMixin", + "NetworkLightUpdateMixin", + "RenderHooksMixin", + "ShaderCloseMixin", + "TileRemoveMixin" + ], "injectors": { "defaultRequire": 1 }, - "minVersion": "0.8", "mixins": ["StepSoundMixin"] + "minVersion": "0.8" } \ No newline at end of file From 8c79174904eff78adba4e654a1ad05fe6cfa919f Mon Sep 17 00:00:00 2001 From: zelophed Date: Thu, 25 Mar 2021 03:58:24 +0100 Subject: [PATCH 2/9] fix pressing recipe inconsistency (closes #1296) --- .../press/BeltPressingCallbacks.java | 26 ++++++++---- .../content/logistics/InWorldProcessing.java | 40 +++++++++---------- 2 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/press/BeltPressingCallbacks.java b/src/main/java/com/simibubi/create/content/contraptions/components/press/BeltPressingCallbacks.java index 4c9e92062..1a0ac5a85 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/press/BeltPressingCallbacks.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/press/BeltPressingCallbacks.java @@ -1,18 +1,16 @@ package com.simibubi.create.content.contraptions.components.press; -import static com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour.ProcessingResult.HOLD; -import static com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour.ProcessingResult.PASS; - import java.util.List; import java.util.Optional; - +import java.util.stream.Collectors; import com.simibubi.create.content.contraptions.components.press.MechanicalPressTileEntity.Mode; import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack; -import com.simibubi.create.foundation.item.ItemHelper; +import com.simibubi.create.content.logistics.InWorldProcessing; import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour.ProcessingResult; import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour; -import net.minecraft.item.ItemStack; +import static com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour.ProcessingResult.HOLD; +import static com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour.ProcessingResult.PASS; public class BeltPressingCallbacks { @@ -45,13 +43,25 @@ public class BeltPressingCallbacks { if (!recipe.isPresent()) return PASS; - ItemStack out = recipe.get() + List collect = InWorldProcessing.applyRecipeOn(transported.stack, recipe.get()) + .stream() + .map(stack -> { + TransportedItemStack copy = transported.copy(); + copy.stack = stack; + return copy; + }).collect(Collectors.toList()); + + if (collect.isEmpty()) + handler.handleProcessingOnItem(transported, TransportedItemStackHandlerBehaviour.TransportedResult.removeItem()); + else + handler.handleProcessingOnItem(transported, TransportedItemStackHandlerBehaviour.TransportedResult.convertTo(collect)); + /*ItemStack out = recipe.get() .getRecipeOutput() .copy(); List multipliedOutput = ItemHelper.multipliedOutput(transported.stack, out); if (multipliedOutput.isEmpty()) transported.stack = ItemStack.EMPTY; - transported.stack = multipliedOutput.get(0); + transported.stack = multipliedOutput.get(0);*/ pressTe.sendData(); return HOLD; } diff --git a/src/main/java/com/simibubi/create/content/logistics/InWorldProcessing.java b/src/main/java/com/simibubi/create/content/logistics/InWorldProcessing.java index 8ce46bffa..d10612ad3 100644 --- a/src/main/java/com/simibubi/create/content/logistics/InWorldProcessing.java +++ b/src/main/java/com/simibubi/create/content/logistics/InWorldProcessing.java @@ -1,25 +1,5 @@ package com.simibubi.create.content.logistics; -import static com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.getHeatLevelOf; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -import javax.annotation.Nullable; - -import com.simibubi.create.AllBlocks; -import com.simibubi.create.AllRecipeTypes; -import com.simibubi.create.content.contraptions.components.fan.SplashingRecipe; -import com.simibubi.create.content.contraptions.processing.ProcessingRecipe; -import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock; -import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack; -import com.simibubi.create.foundation.config.AllConfigs; -import com.simibubi.create.foundation.item.ItemHelper; -import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour.TransportedResult; -import com.simibubi.create.foundation.utility.ColorHelper; - import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; @@ -47,6 +27,24 @@ import net.minecraftforge.items.ItemHandlerHelper; import net.minecraftforge.items.ItemStackHandler; import net.minecraftforge.items.wrapper.RecipeWrapper; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import javax.annotation.Nullable; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllRecipeTypes; +import com.simibubi.create.content.contraptions.components.fan.SplashingRecipe; +import com.simibubi.create.content.contraptions.processing.ProcessingRecipe; +import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock; +import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack; +import com.simibubi.create.foundation.config.AllConfigs; +import com.simibubi.create.foundation.item.ItemHelper; +import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour.TransportedResult; +import com.simibubi.create.foundation.utility.ColorHelper; + +import static com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.getHeatLevelOf; + public class InWorldProcessing { public static class SplashingInv extends RecipeWrapper { @@ -265,7 +263,7 @@ public class InWorldProcessing { } } - private static List applyRecipeOn(ItemStack stackIn, IRecipe recipe) { + public static List applyRecipeOn(ItemStack stackIn, IRecipe recipe) { List stacks; if (recipe instanceof ProcessingRecipe) { From a56514c308a425a959a7b6d38a87938413cb854e Mon Sep 17 00:00:00 2001 From: JozsefA Date: Thu, 25 Mar 2021 14:29:52 -0700 Subject: [PATCH 3/9] Some housekeeping and documentation. --- .../contraptions/base/HalfShaftInstance.java | 2 +- .../contraptions/base/KineticData.java | 27 ++++---- .../base/KineticTileInstance.java | 68 ++++++++++++------- .../base/ShaftlessCogInstance.java | 2 +- .../base/SingleRotatingInstance.java | 17 ++--- .../components/actors/DrillInstance.java | 2 +- .../actors/HarvesterActorInstance.java | 2 +- .../crafter/MechanicalCrafterInstance.java | 2 +- .../components/crank/HandCrankInstance.java | 4 +- .../deployer/DeployerActorInstance.java | 4 +- .../components/deployer/DeployerInstance.java | 7 +- .../components/fan/FanInstance.java | 17 ++--- .../components/flywheel/FlyWheelInstance.java | 16 ++--- .../flywheel/engine/EngineInstance.java | 7 +- .../millstone/MillStoneCogInstance.java | 2 +- .../components/mixer/MixerInstance.java | 10 ++- .../components/press/PressInstance.java | 3 +- .../components/saw/SawInstance.java | 5 +- .../chassis/StickerInstance.java | 7 +- .../gantry/GantryCarriageInstance.java | 9 +-- .../contraptions/fluids/PumpCogInstance.java | 2 +- .../fluids/pipes/FluidValveInstance.java | 5 +- .../relays/belt/BeltInstance.java | 23 ++++--- .../relays/encased/ShaftInstance.java | 2 +- .../relays/encased/SplitShaftInstance.java | 22 ++---- .../relays/gauge/GaugeInstance.java | 11 ++- .../relays/gearbox/GearboxInstance.java | 11 +-- .../diodes/AdjustableRepeaterInstance.java | 6 +- .../block/mechanicalArm/ArmInstance.java | 9 +-- .../block/redstone/AnalogLeverInstance.java | 6 +- .../block/SchematicannonInstance.java | 7 +- .../backend/instancing/IDynamicInstance.java | 12 +++- .../backend/instancing/ITickableInstance.java | 25 +++++-- .../instancing/InstancedTileRenderer.java | 5 +- .../backend/instancing/MaterialType.java | 5 -- .../backend/instancing/RenderMaterial.java | 6 +- .../instancing/TileEntityInstance.java | 64 ++++++++++++++--- 37 files changed, 228 insertions(+), 206 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/HalfShaftInstance.java b/src/main/java/com/simibubi/create/content/contraptions/base/HalfShaftInstance.java index 7b5249963..8e974deab 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/HalfShaftInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/HalfShaftInstance.java @@ -15,7 +15,7 @@ public class HalfShaftInstance extends SingleRotatingInstance { @Override protected InstancedModel getModel() { Direction dir = getShaftDirection(); - return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, blockState, dir); + return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(renderer, blockState, dir); } protected Direction getShaftDirection() { diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticData.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticData.java index 56b0714d3..18e48cb8f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/KineticData.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/KineticData.java @@ -20,16 +20,6 @@ public class KineticData extends BasicData { super(owner); } - public KineticData setTileEntity(KineticTileEntity te) { - setPosition(te.getPos()); - if (te.hasSource()) { - setColor(te.network); - }else { - setColor(0xFF, 0xFF, 0x00); - } - return this; - } - public KineticData setPosition(BlockPos pos) { return setPosition(pos.getX(), pos.getY(), pos.getZ()); } @@ -39,11 +29,9 @@ public class KineticData extends BasicData { } public KineticData setPosition(int x, int y, int z) { - BlockPos origin = owner.renderer.getOriginCoordinate(); - - return setPosition((float) (x - origin.getX()), - (float) (y - origin.getY()), - (float) (z - origin.getZ())); + return setPosition((float) (x), + (float) (y), + (float) (z)); } public KineticData setPosition(float x, float y, float z) { @@ -60,6 +48,15 @@ public class KineticData extends BasicData { return this; } + public KineticData setColor(KineticTileEntity te) { + if (te.hasSource()) { + setColor(te.network); + }else { + setColor(0xFF, 0xFF, 0x00); + } + return this; + } + public KineticData setColor(Long l) { if (l != null) return setColor(l.longValue()); diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileInstance.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileInstance.java index a31e26f09..72eb1f9d3 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileInstance.java @@ -8,41 +8,55 @@ import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; import net.minecraft.block.BlockState; import net.minecraft.util.Direction; -import net.minecraft.world.LightType; public abstract class KineticTileInstance extends TileEntityInstance { + protected final Direction.Axis axis; + public KineticTileInstance(InstancedTileRenderer modelManager, T tile) { super(modelManager, tile); + + axis = ((IRotate) blockState.getBlock()).getRotationAxis(blockState); } - protected final void updateRotation(InstanceKey key, Direction.Axis axis) { - updateRotation(key, axis, tile.getSpeed()); + protected final void updateRotation(RotatingData instance) { + updateRotation(instance, getRotationAxis(), getTileSpeed()); } - protected final void updateRotation(InstanceKey key, Direction.Axis axis, float speed) { - updateRotation(key.getInstance(), axis, speed); + protected final void updateRotation(RotatingData instance, Direction.Axis axis) { + updateRotation(instance, axis, getTileSpeed()); } - protected final void updateRotation(RotatingData key, Direction.Axis axis, float speed) { - key.setRotationAxis(axis) + protected final void updateRotation(RotatingData instance, float speed) { + updateRotation(instance, getRotationAxis(), speed); + } + + protected final void updateRotation(RotatingData instance, Direction.Axis axis, float speed) { + instance.setRotationAxis(axis) .setRotationOffset(getRotationOffset(axis)) .setRotationalSpeed(speed) - .setColor(tile.network); + .setColor(tile); } - protected final void updateRotation(RotatingData key, Direction.Axis axis) { - updateRotation(key, axis, tile.getSpeed()); + protected final InstanceKey setup(InstanceKey key) { + return setup(key, getRotationAxis(), getTileSpeed()); } - protected final InstanceKey setup(InstanceKey key, float speed, Direction.Axis axis) { + protected final InstanceKey setup(InstanceKey key, Direction.Axis axis) { + return setup(key, axis, getTileSpeed()); + } + + protected final InstanceKey setup(InstanceKey key, float speed) { + return setup(key, getRotationAxis(), speed); + } + + protected final InstanceKey setup(InstanceKey key, Direction.Axis axis, float speed) { key.getInstance() .setRotationAxis(axis) .setRotationalSpeed(speed) .setRotationOffset(getRotationOffset(axis)) - .setTileEntity(tile) - .setSkyLight(world.getLightLevel(LightType.SKY, pos)) - .setBlockLight(world.getLightLevel(LightType.BLOCK, pos)); + .setColor(tile) + .setPosition(getInstancePosition()); return key; } @@ -57,16 +71,24 @@ public abstract class KineticTileInstance extends T return offset; } + protected Direction.Axis getRotationAxis() { + return axis; + } + + protected float getTileSpeed() { + return tile.getSpeed(); + } + + protected BlockState shaft() { + return shaft(getRotationAxis()); + } + + protected final RenderMaterial> getRotatingMaterial() { + return renderer.getMaterial(KineticRenderMaterials.ROTATING); + } + public static BlockState shaft(Direction.Axis axis) { return AllBlocks.SHAFT.getDefaultState() - .with(ShaftBlock.AXIS, axis); - } - - public Direction.Axis getRotationAxis() { - return ((IRotate) blockState.getBlock()).getRotationAxis(blockState); - } - - protected final RenderMaterial> rotatingMaterial() { - return modelManager.getMaterial(KineticRenderMaterials.ROTATING); + .with(ShaftBlock.AXIS, axis); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/ShaftlessCogInstance.java b/src/main/java/com/simibubi/create/content/contraptions/base/ShaftlessCogInstance.java index 952846454..7c9fd17c2 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/ShaftlessCogInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/ShaftlessCogInstance.java @@ -12,6 +12,6 @@ public class ShaftlessCogInstance extends SingleRotatingInstance { @Override protected InstancedModel getModel() { - return AllBlockPartials.SHAFTLESS_COGWHEEL.renderOnRotating(modelManager, tile.getBlockState()); + return AllBlockPartials.SHAFTLESS_COGWHEEL.renderOnRotating(renderer, tile.getBlockState()); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/SingleRotatingInstance.java b/src/main/java/com/simibubi/create/content/contraptions/base/SingleRotatingInstance.java index ab81c0462..c0d7d9e93 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/SingleRotatingInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/SingleRotatingInstance.java @@ -1,39 +1,34 @@ package com.simibubi.create.content.contraptions.base; -import static com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer.KINETIC_TILE; - import com.simibubi.create.foundation.render.backend.instancing.InstanceKey; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; import net.minecraft.block.BlockState; -import net.minecraft.util.Direction; public class SingleRotatingInstance extends KineticTileInstance { - protected final InstanceKey rotatingModelKey; + protected final InstanceKey rotatingModel; public SingleRotatingInstance(InstancedTileRenderer modelManager, KineticTileEntity tile) { super(modelManager, tile); - Direction.Axis axis = ((IRotate) blockState.getBlock()).getRotationAxis(blockState); - rotatingModelKey = setup(getModel().createInstance(), tile.getSpeed(), axis); + rotatingModel = setup(getModel().createInstance()); } @Override public void update() { - Direction.Axis axis = ((IRotate) blockState.getBlock()).getRotationAxis(blockState); - updateRotation(rotatingModelKey, axis); + updateRotation(rotatingModel.getInstance()); } @Override public void updateLight() { - relight(pos, rotatingModelKey.getInstance()); + relight(pos, rotatingModel.getInstance()); } @Override public void remove() { - rotatingModelKey.delete(); + rotatingModel.delete(); } protected BlockState getRenderedBlockState() { @@ -41,6 +36,6 @@ public class SingleRotatingInstance extends KineticTileInstance getModel() { - return rotatingMaterial().getModel(KINETIC_TILE, getRenderedBlockState()); + return getRotatingMaterial().getModel(getRenderedBlockState()); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillInstance.java index dbd7b9b92..da5a33476 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillInstance.java @@ -14,6 +14,6 @@ public class DrillInstance extends SingleRotatingInstance { @Override protected InstancedModel getModel() { - return AllBlockPartials.DRILL_HEAD.renderOnDirectionalSouthRotating(modelManager, tile.getBlockState()); + return AllBlockPartials.DRILL_HEAD.renderOnDirectionalSouthRotating(renderer, tile.getBlockState()); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterActorInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterActorInstance.java index 1ce83ff38..43d31684c 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterActorInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterActorInstance.java @@ -36,7 +36,7 @@ public class HarvesterActorInstance extends ActorInstance { public HarvesterActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) { super(modelManager, context); - RenderMaterial> renderMaterial = modelManager.transformMaterial(); + RenderMaterial> renderMaterial = modelManager.getTransformMaterial(); BlockState state = context.state; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/crafter/MechanicalCrafterInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/crafter/MechanicalCrafterInstance.java index adb9fd3e2..2d88b431c 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/crafter/MechanicalCrafterInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/crafter/MechanicalCrafterInstance.java @@ -35,6 +35,6 @@ public class MechanicalCrafterInstance extends SingleRotatingInstance { stacker.unCentre(); return stack; }; - return rotatingMaterial().getModel(AllBlockPartials.SHAFTLESS_COGWHEEL, blockState, facing, ms); + return getRotatingMaterial().getModel(AllBlockPartials.SHAFTLESS_COGWHEEL, blockState, facing, ms); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/crank/HandCrankInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/crank/HandCrankInstance.java index 382471548..f825d1927 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/crank/HandCrankInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/crank/HandCrankInstance.java @@ -30,8 +30,6 @@ public class HandCrankInstance extends SingleRotatingInstance implements IDynami facing = blockState.get(BlockStateProperties.FACING); InstancedModel model = renderedHandle.renderOnDirectionalSouthModel(modelManager, blockState, facing.getOpposite()); crank = model.createInstance(); - - updateLight(); } @Override @@ -45,7 +43,7 @@ public class HandCrankInstance extends SingleRotatingInstance implements IDynami MatrixStack ms = new MatrixStack(); MatrixStacker.of(ms) - .translate(getFloatingPos()) + .translate(getInstancePosition()) .centre() .rotate(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis), angle) .unCentre(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerActorInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerActorInstance.java index 4d73c88ef..8cf440adf 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerActorInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerActorInstance.java @@ -37,7 +37,7 @@ public class DeployerActorInstance extends ActorInstance { public DeployerActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) { super(modelManager, context); - RenderMaterial> mat = modelManager.transformMaterial(); + RenderMaterial> mat = modelManager.getTransformMaterial(); BlockState state = context.state; DeployerTileEntity.Mode mode = NBTHelper.readEnum(context.tileData, "Mode", DeployerTileEntity.Mode.class); @@ -56,7 +56,7 @@ public class DeployerActorInstance extends ActorInstance { Direction.Axis axis = ((IRotate) state.getBlock()).getRotationAxis(state); shaft = modelManager.getMaterial(KineticRenderMaterials.ROTATING) - .getModel(KineticTileEntityRenderer.KINETIC_TILE, KineticTileInstance.shaft(axis)) + .getModel(KineticTileInstance.shaft(axis)) .createInstance(); int blockLight = localBlockLight(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerInstance.java index 2b334a52e..f05361148 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerInstance.java @@ -3,7 +3,6 @@ package com.simibubi.create.content.contraptions.components.deployer; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.relays.encased.ShaftInstance; -import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.instancing.*; import com.simibubi.create.foundation.render.backend.instancing.impl.OrientedData; import com.simibubi.create.foundation.utility.AngleHelper; @@ -46,7 +45,7 @@ public class DeployerInstance extends ShaftInstance implements IDynamicInstance, zRot = facing == Direction.UP ? 270 : facing == Direction.DOWN ? 90 : 0; zRotPole = rotatePole ? 90 : 0; - pole = RenderMaterials.ORIENTED.get(modelManager).getModel(AllBlockPartials.DEPLOYER_POLE, blockState).createInstance(); + pole = getOrientedMaterial().getModel(AllBlockPartials.DEPLOYER_POLE, blockState).createInstance(); updateHandPose(); relight(pos, pole.getInstance()); @@ -73,7 +72,7 @@ public class DeployerInstance extends ShaftInstance implements IDynamicInstance, : currentHand == AllBlockPartials.DEPLOYER_HAND_HOLDING ? 4 / 16f : 3 / 16f; float distance = Math.min(MathHelper.clamp(progress, 0, 1) * (tile.reach + handLength), 21 / 16f); Vec3i facingVec = facing.getDirectionVec(); - BlockPos blockPos = getFloatingPos(); + BlockPos blockPos = getInstancePosition(); float x = blockPos.getX() + ((float) facingVec.getX()) * distance; float y = blockPos.getY() + ((float) facingVec.getY()) * distance; @@ -107,7 +106,7 @@ public class DeployerInstance extends ShaftInstance implements IDynamicInstance, if (hand != null) hand.delete(); - hand = RenderMaterials.ORIENTED.get(modelManager).getModel(currentHand, blockState).createInstance(); + hand = getOrientedMaterial().getModel(currentHand, blockState).createInstance(); relight(pos, hand.getInstance()); updateRotation(pole, hand, yRot, zRot, zRotPole); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/fan/FanInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/fan/FanInstance.java index 8660b5628..b2beb5a75 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/fan/FanInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/fan/FanInstance.java @@ -17,27 +17,18 @@ public class FanInstance extends KineticTileInstance { protected final InstanceKey shaft; protected final InstanceKey fan; - final Direction.Axis axis; final Direction direction; public FanInstance(InstancedTileRenderer modelManager, EncasedFanTileEntity tile) { super(modelManager, tile); direction = blockState.get(FACING); - axis = ((IRotate) blockState.getBlock()).getRotationAxis(blockState); shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, blockState, direction.getOpposite()).createInstance(); fan = AllBlockPartials.ENCASED_FAN_INNER.renderOnDirectionalSouthRotating(modelManager, blockState, direction.getOpposite()).createInstance(); - RotatingData shaftInstance = shaft.getInstance(); - shaftInstance.setTileEntity(tile); - updateRotation(shaftInstance, axis); - - RotatingData fanInstance = fan.getInstance(); - fanInstance.setTileEntity(tile); - updateRotation(fanInstance, axis, getFanSpeed()); - - updateLight(); + setup(shaft); + setup(fan, getFanSpeed()); } private float getFanSpeed() { @@ -51,8 +42,8 @@ public class FanInstance extends KineticTileInstance { @Override protected void update() { - updateRotation(shaft, axis); - updateRotation(fan, axis, getFanSpeed()); + updateRotation(shaft.getInstance()); + updateRotation(fan.getInstance(), getFanSpeed()); } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java index 6b323f0f2..8b1fc41bf 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java @@ -6,10 +6,8 @@ import java.util.List; import com.google.common.collect.Lists; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; -import com.simibubi.create.content.contraptions.base.IRotate; import com.simibubi.create.content.contraptions.base.KineticTileInstance; import com.simibubi.create.content.contraptions.base.RotatingData; -import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.instancing.*; import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData; @@ -49,8 +47,7 @@ public class FlyWheelInstance extends KineticTileInstance im facing = blockState.get(BlockStateProperties.HORIZONTAL_FACING); - Direction.Axis axis = ((IRotate) blockState.getBlock()).getRotationAxis(blockState); - shaft = setup(shaftModel().createInstance(), tile.getSpeed(), axis); + shaft = setup(shaftModel().createInstance()); wheel = AllBlockPartials.FLYWHEEL.renderOnHorizontalModel(modelManager, blockState.rotate(Rotation.CLOCKWISE_90)).createInstance(); @@ -62,7 +59,7 @@ public class FlyWheelInstance extends KineticTileInstance im connectorAngleMult = flipAngle ? -1 : 1; - RenderMaterial> mat = modelManager.getMaterial(RenderMaterials.TRANSFORMED); + RenderMaterial> mat = getTransformMaterial(); upperRotating = mat.getModel(AllBlockPartials.FLYWHEEL_UPPER_ROTATING, blockState).createInstance(); lowerRotating = mat.getModel(AllBlockPartials.FLYWHEEL_LOWER_ROTATING, blockState).createInstance(); @@ -73,8 +70,6 @@ public class FlyWheelInstance extends KineticTileInstance im } else { connectors = Collections.emptyList(); } - - updateLight(); } @Override @@ -90,7 +85,7 @@ public class FlyWheelInstance extends KineticTileInstance im MatrixStack ms = new MatrixStack(); MatrixStacker msr = MatrixStacker.of(ms); - msr.translate(getFloatingPos()); + msr.translate(getInstancePosition()); if (connection != null) { float rotation = angle * connectorAngleMult; @@ -133,8 +128,7 @@ public class FlyWheelInstance extends KineticTileInstance im @Override protected void update() { - Direction.Axis axis = ((IRotate) blockState.getBlock()).getRotationAxis(blockState); - updateRotation(shaft, axis); + updateRotation(shaft.getInstance()); } @Override @@ -156,7 +150,7 @@ public class FlyWheelInstance extends KineticTileInstance im } protected InstancedModel shaftModel() { - return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, blockState, facing.getOpposite()); + return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(renderer, blockState, facing.getOpposite()); } protected void transformConnector(MatrixStacker ms, boolean upper, boolean rotating, float angle, boolean flip) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/engine/EngineInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/engine/EngineInstance.java index b2830d978..370cd50e0 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/engine/EngineInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/engine/EngineInstance.java @@ -2,7 +2,6 @@ package com.simibubi.create.content.contraptions.components.flywheel.engine; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; -import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.instancing.InstanceKey; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; import com.simibubi.create.foundation.render.backend.instancing.TileEntityInstance; @@ -30,14 +29,14 @@ public class EngineInstance extends TileEntityInstance { Direction facing = blockState.get(BlockStateProperties.HORIZONTAL_FACING); - this.frame = modelManager.getMaterial(RenderMaterials.TRANSFORMED).getModel(frame, blockState).createInstance(); + this.frame = getTransformMaterial().getModel(frame, blockState).createInstance(); float angle = AngleHelper.rad(AngleHelper.horizontalAngle(facing)); MatrixStack ms = new MatrixStack(); MatrixStacker msr = MatrixStacker.of(ms); - msr.translate(getFloatingPos()) + msr.translate(getInstancePosition()) .nudge(tile.hashCode()) .centre() .rotate(Direction.UP, angle) @@ -46,8 +45,6 @@ public class EngineInstance extends TileEntityInstance { this.frame.getInstance() .setTransform(ms); - - updateLight(); } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/millstone/MillStoneCogInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/millstone/MillStoneCogInstance.java index cc06621a6..dded6ee67 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/millstone/MillStoneCogInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/millstone/MillStoneCogInstance.java @@ -15,6 +15,6 @@ public class MillStoneCogInstance extends SingleRotatingInstance { @Override protected InstancedModel getModel() { - return AllBlockPartials.MILLSTONE_COG.renderOnRotating(modelManager, tile.getBlockState()); + return AllBlockPartials.MILLSTONE_COG.renderOnRotating(renderer, tile.getBlockState()); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MixerInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MixerInstance.java index 0290fdfb7..50098f65f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MixerInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MixerInstance.java @@ -5,7 +5,6 @@ import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.RotatingData; import com.simibubi.create.content.contraptions.base.ShaftlessCogInstance; -import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.instancing.*; import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData; import com.simibubi.create.foundation.utility.AnimationTickHolder; @@ -20,13 +19,13 @@ public class MixerInstance extends ShaftlessCogInstance implements IDynamicInsta public MixerInstance(InstancedTileRenderer dispatcher, KineticTileEntity tile) { super(dispatcher, tile); - mixerHead = rotatingMaterial().getModel(AllBlockPartials.MECHANICAL_MIXER_HEAD, blockState) + mixerHead = getRotatingMaterial().getModel(AllBlockPartials.MECHANICAL_MIXER_HEAD, blockState) .createInstance(); mixerHead.getInstance() .setRotationAxis(Direction.Axis.Y); - mixerPole = modelManager.getMaterial(RenderMaterials.TRANSFORMED) + mixerPole = getTransformMaterial() .getModel(AllBlockPartials.MECHANICAL_MIXER_POLE, blockState) .createInstance(); @@ -36,7 +35,6 @@ public class MixerInstance extends ShaftlessCogInstance implements IDynamicInsta transformPole(renderedHeadOffset); transformHead(mixer, renderedHeadOffset); - updateLight(); } @Override @@ -56,7 +54,7 @@ public class MixerInstance extends ShaftlessCogInstance implements IDynamicInsta float speed = mixer.getRenderedHeadRotationSpeed(AnimationTickHolder.getPartialTicks()); mixerHead.getInstance() - .setPosition(pos) + .setPosition(getInstancePosition()) .nudge(0, -renderedHeadOffset, 0) .setRotationalSpeed(speed * 2); } @@ -65,7 +63,7 @@ public class MixerInstance extends ShaftlessCogInstance implements IDynamicInsta MatrixStack ms = new MatrixStack(); MatrixStacker msr = MatrixStacker.of(ms); - msr.translate(getFloatingPos()); + msr.translate(getInstancePosition()); msr.translate(0, -renderedHeadOffset, 0); mixerPole.getInstance().setTransform(ms); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/press/PressInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/press/PressInstance.java index cacf1d99d..b4a3eff51 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/press/PressInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/press/PressInstance.java @@ -20,7 +20,6 @@ public class PressInstance extends ShaftInstance implements IDynamicInstance { pressHead = AllBlockPartials.MECHANICAL_PRESS_HEAD.renderOnHorizontalModel(dispatcher, blockState).createInstance(); - updateLight(); transformModels((MechanicalPressTileEntity) tile); } @@ -39,7 +38,7 @@ public class PressInstance extends ShaftInstance implements IDynamicInstance { MatrixStack ms = new MatrixStack(); MatrixStacker msr = MatrixStacker.of(ms); - msr.translate(getFloatingPos()); + msr.translate(getInstancePosition()); msr.translate(0, -renderedHeadOffset, 0); pressHead.getInstance() diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawInstance.java index 7b06a384a..606ffe62b 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawInstance.java @@ -4,7 +4,6 @@ import static net.minecraft.state.properties.BlockStateProperties.FACING; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; -import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.content.contraptions.base.RotatingData; import com.simibubi.create.content.contraptions.base.SingleRotatingInstance; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; @@ -21,8 +20,8 @@ public class SawInstance extends SingleRotatingInstance { @Override protected InstancedModel getModel() { if (blockState.get(FACING).getAxis().isHorizontal()) - return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, blockState.rotate(tile.getWorld(), tile.getPos(), Rotation.CLOCKWISE_180)); + return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(renderer, blockState.rotate(tile.getWorld(), tile.getPos(), Rotation.CLOCKWISE_180)); else - return rotatingMaterial().getModel(KineticTileEntityRenderer.KINETIC_TILE, shaft(getRotationAxis())); + return getRotatingMaterial().getModel(shaft()); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerInstance.java index dffa94083..3fd32da92 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerInstance.java @@ -2,7 +2,6 @@ package com.simibubi.create.content.contraptions.components.structureMovement.ch import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; -import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.instancing.*; import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData; import com.simibubi.create.foundation.utility.AngleHelper; @@ -24,13 +23,11 @@ public class StickerInstance extends TileEntityInstance imple public StickerInstance(InstancedTileRenderer modelManager, StickerTileEntity tile) { super(modelManager, tile); - head = modelManager.getMaterial(RenderMaterials.TRANSFORMED).getModel(AllBlockPartials.STICKER_HEAD, blockState).createInstance(); + head = getTransformMaterial().getModel(AllBlockPartials.STICKER_HEAD, blockState).createInstance(); fakeWorld = tile.getWorld() != Minecraft.getInstance().world; facing = blockState.get(StickerBlock.FACING); offset = blockState.get(StickerBlock.EXTENDED) ? 1 : 0; - - updateLight(); } @Override @@ -45,7 +42,7 @@ public class StickerInstance extends TileEntityInstance imple MatrixStack stack = new MatrixStack(); MatrixStacker.of(stack) - .translate(getFloatingPos()) + .translate(getInstancePosition()) .nudge(tile.hashCode()) .centre() .rotateY(AngleHelper.horizontalAngle(facing)) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageInstance.java index 096548d84..1ea699d6c 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageInstance.java @@ -5,7 +5,6 @@ import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.content.contraptions.relays.encased.ShaftInstance; -import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.instancing.IDynamicInstance; import com.simibubi.create.foundation.render.backend.instancing.InstanceKey; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; @@ -29,7 +28,7 @@ public class GantryCarriageInstance extends ShaftInstance implements IDynamicIns public GantryCarriageInstance(InstancedTileRenderer dispatcher, KineticTileEntity tile) { super(dispatcher, tile); - gantryCogs = modelManager.getMaterial(RenderMaterials.TRANSFORMED) + gantryCogs = getTransformMaterial() .getModel(AllBlockPartials.GANTRY_COGS, blockState) .createInstance(); @@ -40,8 +39,6 @@ public class GantryCarriageInstance extends ShaftInstance implements IDynamicIns visualPos = facing.getAxisDirection() == Direction.AxisDirection.POSITIVE ? tile.getPos() : tile.getPos() .offset(facing.getOpposite()); - - updateLight(); } @Override @@ -62,7 +59,7 @@ public class GantryCarriageInstance extends ShaftInstance implements IDynamicIns MatrixStack ms = new MatrixStack(); MatrixStacker.of(ms) - .translate(getFloatingPos()) + .translate(getInstancePosition()) .centre() .rotateY(AngleHelper.horizontalAngle(facing)) .rotateX(facing == Direction.UP ? 0 : facing == Direction.DOWN ? 180 : 90) @@ -77,7 +74,7 @@ public class GantryCarriageInstance extends ShaftInstance implements IDynamicIns @Override public void updateLight() { - relight(pos, gantryCogs.getInstance()); + relight(pos, gantryCogs.getInstance(), rotatingModel.getInstance()); } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpCogInstance.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpCogInstance.java index efca3411e..786c5dca8 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpCogInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpCogInstance.java @@ -15,6 +15,6 @@ public class PumpCogInstance extends SingleRotatingInstance { @Override protected InstancedModel getModel() { - return AllBlockPartials.MECHANICAL_PUMP_COG.renderOnDirectionalSouthRotating(modelManager, tile.getBlockState()); + return AllBlockPartials.MECHANICAL_PUMP_COG.renderOnDirectionalSouthRotating(renderer, tile.getBlockState()); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/pipes/FluidValveInstance.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/pipes/FluidValveInstance.java index c21a668ae..2fa1f8a28 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/pipes/FluidValveInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/pipes/FluidValveInstance.java @@ -37,9 +37,8 @@ public class FluidValveInstance extends ShaftInstance implements IDynamicInstanc boolean twist = pipeAxis.isHorizontal() && shaftAxis == Direction.Axis.Z || pipeAxis.isVertical(); pointerRotationOffset = twist ? 90 : 0; - pointer = modelManager.transformMaterial().getModel(AllBlockPartials.FLUID_VALVE_POINTER, blockState).createInstance(); + pointer = renderer.getTransformMaterial().getModel(AllBlockPartials.FLUID_VALVE_POINTER, blockState).createInstance(); - updateLight(); transformPointer((FluidValveTileEntity) tile); } @@ -58,7 +57,7 @@ public class FluidValveInstance extends ShaftInstance implements IDynamicInstanc MatrixStack ms = new MatrixStack(); MatrixStacker.of(ms) - .translate(getFloatingPos()) + .translate(getInstancePosition()) .centre() .rotateY(yRot) .rotateX(xRot) diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstance.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstance.java index 7b06006f3..5781336c3 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstance.java @@ -69,7 +69,7 @@ public class BeltInstance extends KineticTileInstance { if (tile.hasPulley()) { InstancedModel pulleyModel = getPulleyModel(); - pulleyKey = setup(pulleyModel.createInstance(), tile.getSpeed(), getRotationAxis()); + pulleyKey = setup(pulleyModel.createInstance()); } } @@ -83,13 +83,13 @@ public class BeltInstance extends KineticTileInstance { SpriteShiftEntry spriteShiftEntry = BeltRenderer.getSpriteShiftEntry(color, diagonal, bottom); key.getInstance() .setScrollTexture(spriteShiftEntry) - .setColor(tile.network) + .setColor(tile) .setRotationalSpeed(getScrollSpeed()); bottom = false; } if (pulleyKey != null) { - updateRotation(pulleyKey, getRotationAxis()); + updateRotation(pulleyKey.getInstance()); } } @@ -139,7 +139,7 @@ public class BeltInstance extends KineticTileInstance { return modelTransform; }; - return rotatingMaterial().getModel(AllBlockPartials.BELT_PULLEY, blockState, dir, ms); + return getRotatingMaterial().getModel(AllBlockPartials.BELT_PULLEY, blockState, dir, ms); } private Direction getOrientation() { @@ -159,13 +159,14 @@ public class BeltInstance extends KineticTileInstance { Quaternion q = new Quaternion(rotX, rotY, rotZ, true); - key.getInstance() - .setScrollTexture(spriteShift) - .setScrollMult(diagonal ? 3f / 8f : 0.5f) - .setRotation(q) - .setRotationalSpeed(getScrollSpeed()) - .setRotationOffset(bottom ? 0.5f : 0f) - .setTileEntity(tile) + key.getInstance() + .setScrollTexture(spriteShift) + .setScrollMult(diagonal ? 3f / 8f : 0.5f) + .setRotation(q) + .setRotationalSpeed(getScrollSpeed()) + .setRotationOffset(bottom ? 0.5f : 0f) + .setColor(tile) + .setPosition(getInstancePosition()) .setBlockLight(world.getLightLevel(LightType.BLOCK, pos)) .setSkyLight(world.getLightLevel(LightType.SKY, pos)); diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/ShaftInstance.java b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/ShaftInstance.java index 9805e7f05..a17c27479 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/ShaftInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/ShaftInstance.java @@ -18,7 +18,7 @@ public class ShaftInstance extends SingleRotatingInstance { @Override protected BlockState getRenderedBlockState() { - return shaft(getRotationAxis()); + return shaft(); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java index 3c4272e1f..d55d5f4ce 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java @@ -24,19 +24,18 @@ public class SplitShaftInstance extends KineticTileInstance(2); - Block block = blockState.getBlock(); - final Direction.Axis boxAxis = ((IRotate) block).getRotationAxis(blockState); - float speed = tile.getSpeed(); - for (Direction dir : Iterate.directionsInAxis(boxAxis)) { + for (Direction dir : Iterate.directionsInAxis(getRotationAxis())) { InstancedModel half = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, blockState, dir); float splitSpeed = speed * tile.getRotationSpeedModifier(dir); - keys.add(setup(half.createInstance(), splitSpeed, boxAxis)); + keys.add(setup(half.createInstance(), splitSpeed)); } + + updateLight(); } @Override @@ -47,13 +46,13 @@ public class SplitShaftInstance extends KineticTileInstance relight(pos, ((InstanceKey) key).getInstance())); + relight(pos, keys.stream().map(InstanceKey::getInstance)); } @Override @@ -62,13 +61,4 @@ public class SplitShaftInstance extends KineticTileInstance key, Direction dir) { - Direction.Axis axis = dir.getAxis(); - - key.getInstance() - .setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector()) - .setRotationalSpeed(tile.getSpeed() * tile.getRotationSpeedModifier(dir)) - .setRotationOffset(getRotationOffset(axis)) - .setColor(tile.network); - } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/gauge/GaugeInstance.java b/src/main/java/com/simibubi/create/content/contraptions/relays/gauge/GaugeInstance.java index 11e672ad0..4af5eaa0a 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/gauge/GaugeInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/gauge/GaugeInstance.java @@ -4,7 +4,6 @@ import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.relays.encased.ShaftInstance; -import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.instancing.IDynamicInstance; import com.simibubi.create.foundation.render.backend.instancing.InstanceKey; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; @@ -30,12 +29,12 @@ public abstract class GaugeInstance extends ShaftInstance implements IDynamicIns GaugeTileEntity gaugeTile = (GaugeTileEntity) tile; GaugeBlock gaugeBlock = (GaugeBlock) blockState.getBlock(); - InstancedModel dialModel = modelManager.getMaterial(RenderMaterials.TRANSFORMED).getModel(AllBlockPartials.GAUGE_DIAL, blockState); + InstancedModel dialModel = getTransformMaterial().getModel(AllBlockPartials.GAUGE_DIAL, blockState); InstancedModel headModel = getHeadModel(); ms = new MatrixStack(); MatrixStacker msr = MatrixStacker.of(ms); - msr.translate(getFloatingPos()); + msr.translate(getInstancePosition()); float progress = MathHelper.lerp(AnimationTickHolder.getPartialTicks(), gaugeTile.prevDialState, gaugeTile.dialState); @@ -49,8 +48,6 @@ public abstract class GaugeInstance extends ShaftInstance implements IDynamicIns face.setupTransform(msr, progress); } - - updateLight(); } private DialFace makeFace(Direction face, InstancedModel dialModel, InstancedModel headModel) { @@ -151,7 +148,7 @@ public abstract class GaugeInstance extends ShaftInstance implements IDynamicIns @Override protected InstancedModel getHeadModel() { - return modelManager.getMaterial(RenderMaterials.TRANSFORMED).getModel(AllBlockPartials.GAUGE_HEAD_SPEED, blockState); + return getTransformMaterial().getModel(AllBlockPartials.GAUGE_HEAD_SPEED, blockState); } } @@ -162,7 +159,7 @@ public abstract class GaugeInstance extends ShaftInstance implements IDynamicIns @Override protected InstancedModel getHeadModel() { - return modelManager.getMaterial(RenderMaterials.TRANSFORMED).getModel(AllBlockPartials.GAUGE_HEAD_STRESS, blockState); + return getTransformMaterial().getModel(AllBlockPartials.GAUGE_HEAD_STRESS, blockState); } } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java b/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java index 836422301..b34e56917 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java @@ -44,8 +44,8 @@ public class GearboxInstance extends KineticTileInstance { key.getInstance() .setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector()) .setRotationalSpeed(getSpeed(direction)) - .setRotationOffset(getRotationOffset(axis)) - .setTileEntity(tile) + .setRotationOffset(getRotationOffset(axis)).setColor(tile) + .setPosition(getInstancePosition()) .setBlockLight(blockLight) .setSkyLight(skyLight); @@ -81,12 +81,7 @@ public class GearboxInstance extends KineticTileInstance { Direction direction = key.getKey(); Direction.Axis axis = direction.getAxis(); - key.getValue() - .getInstance() - .setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector()) - .setRotationalSpeed(getSpeed(direction)) - .setRotationOffset(getRotationOffset(axis)) - .setColor(tile.network); + updateRotation(key.getValue().getInstance(), axis, getSpeed(direction)); } } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/diodes/AdjustableRepeaterInstance.java b/src/main/java/com/simibubi/create/content/logistics/block/diodes/AdjustableRepeaterInstance.java index a0a6c33ea..4666c2b39 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/diodes/AdjustableRepeaterInstance.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/diodes/AdjustableRepeaterInstance.java @@ -16,18 +16,16 @@ public class AdjustableRepeaterInstance extends TileEntityInstance modelManager, AdjustableRepeaterTileEntity tile) { super(modelManager, tile); - indicator = modelManager.transformMaterial().getModel(AllBlockPartials.FLEXPEATER_INDICATOR, blockState).createInstance(); + indicator = modelManager.getTransformMaterial().getModel(AllBlockPartials.FLEXPEATER_INDICATOR, blockState).createInstance(); MatrixStack ms = new MatrixStack(); - MatrixStacker.of(ms).translate(getFloatingPos()); + MatrixStacker.of(ms).translate(getInstancePosition()); indicator.getInstance() .setTransform(ms) .setColor(getColor()); previousState = tile.state; - - updateLight(); } @Override diff --git a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInstance.java b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInstance.java index 046e446a8..9e680a157 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInstance.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInstance.java @@ -6,7 +6,6 @@ import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.RotatingData; import com.simibubi.create.content.contraptions.base.SingleRotatingInstance; -import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.instancing.*; import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData; @@ -38,7 +37,7 @@ public class ArmInstance extends SingleRotatingInstance implements IDynamicInsta public ArmInstance(InstancedTileRenderer modelManager, KineticTileEntity tile) { super(modelManager, tile); - RenderMaterial> mat = modelManager.getMaterial(RenderMaterials.TRANSFORMED); + RenderMaterial> mat = getTransformMaterial(); base = mat.getModel(AllBlockPartials.ARM_BASE, blockState).createInstance(); lowerBody = mat.getModel(AllBlockPartials.ARM_LOWER_BODY, blockState).createInstance(); @@ -52,8 +51,6 @@ public class ArmInstance extends SingleRotatingInstance implements IDynamicInsta clawGrips = Lists.newArrayList(clawGrip1, clawGrip2); models = Lists.newArrayList(base, lowerBody, upperBody, head, claw, clawGrip1, clawGrip2); - - updateLight(); } @Override @@ -91,7 +88,7 @@ public class ArmInstance extends SingleRotatingInstance implements IDynamicInsta MatrixStack msLocal = new MatrixStack(); MatrixStacker msr = MatrixStacker.of(msLocal); - msr.translate(getFloatingPos()); + msr.translate(getInstancePosition()); msr.centre(); if (blockState.get(ArmBlock.CEILING)) @@ -147,7 +144,7 @@ public class ArmInstance extends SingleRotatingInstance implements IDynamicInsta @Override protected InstancedModel getModel() { - return AllBlockPartials.ARM_COG.renderOnRotating(modelManager, tile.getBlockState()); + return AllBlockPartials.ARM_COG.renderOnRotating(renderer, tile.getBlockState()); } @Override diff --git a/src/main/java/com/simibubi/create/content/logistics/block/redstone/AnalogLeverInstance.java b/src/main/java/com/simibubi/create/content/logistics/block/redstone/AnalogLeverInstance.java index 78fffc5c5..8245a1e9f 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/redstone/AnalogLeverInstance.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/redstone/AnalogLeverInstance.java @@ -2,7 +2,6 @@ package com.simibubi.create.content.logistics.block.redstone; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; -import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.instancing.*; import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData; import com.simibubi.create.foundation.utility.AngleHelper; @@ -23,7 +22,7 @@ public class AnalogLeverInstance extends TileEntityInstance modelManager, AnalogLeverTileEntity tile) { super(modelManager, tile); - RenderMaterial> mat = modelManager.getMaterial(RenderMaterials.TRANSFORMED); + RenderMaterial> mat = getTransformMaterial(); handle = mat.getModel(AllBlockPartials.ANALOG_LEVER_HANDLE, blockState).createInstance(); indicator = mat.getModel(AllBlockPartials.ANALOG_LEVER_INDICATOR, blockState).createInstance(); @@ -33,7 +32,6 @@ public class AnalogLeverInstance extends TileEntityInstance modelManager, SchematicannonTileEntity tile) { super(modelManager, tile); - RenderMaterial> mat = modelManager.getMaterial(RenderMaterials.TRANSFORMED); + RenderMaterial> mat = getTransformMaterial(); connector = mat.getModel(AllBlockPartials.SCHEMATICANNON_CONNECTOR, blockState).createInstance(); pipe = mat.getModel(AllBlockPartials.SCHEMATICANNON_PIPE, blockState).createInstance(); - - updateLight(); } @Override @@ -39,7 +36,7 @@ public class SchematicannonInstance extends TileEntityInstance
If your goal is offloading work to shaders, but you're unsure exactly how you need + * to parameterize the instances, you're encouraged to implement this for prototyping. + */ public interface IDynamicInstance { /** - * Called every frame. This can be used to smoothly change instance data - * to allow for fancy animations that could not be achieved on the GPU alone. + * Called every frame. */ void beginFrame(); } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/ITickableInstance.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/ITickableInstance.java index a93f7b8d3..196ef9360 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/ITickableInstance.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/ITickableInstance.java @@ -1,10 +1,25 @@ package com.simibubi.create.foundation.render.backend.instancing; +/** + * An interface giving {@link TileEntityInstance}s a hook to have a function called at + * the end of every tick. By implementing {@link ITickableInstance}, a {@link TileEntityInstance} + * can update frequently, but not every frame. + *
There are a few cases in which this should be considered over {@link IDynamicInstance}: + *

    + *
  • + * You'd like to change something about the instance every now and then. + * eg. adding or removing parts, snapping to a different rotation. + *
  • + *
  • + * Your TileEntity does animate, but the animation doesn't have + * to be smooth, in which case this could be an optimization. + *
  • + *
+ */ public interface ITickableInstance { - /** - * Called every tick. This is useful for things that don't have to be smooth, - * or to recalculate something that would only change after a game tick. - */ - void tick(); + /** + * Called every tick. + */ + void tick(); } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java index a0a488329..193d4e5be 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java @@ -68,11 +68,11 @@ public abstract class InstancedTileRenderer

{ return (RenderMaterial) materials.get(materialType); } - public RenderMaterial> transformMaterial() { + public RenderMaterial> getTransformMaterial() { return getMaterial(RenderMaterials.TRANSFORMED); } - public RenderMaterial> orientedMaterial() { + public RenderMaterial> getOrientedMaterial() { return getMaterial(RenderMaterials.ORIENTED); } @@ -167,6 +167,7 @@ public abstract class InstancedTileRenderer

{ TileEntityInstance renderer = InstancedTileRenderRegistry.instance.create(this, tile); if (renderer != null) { + renderer.updateLight(); instances.put(tile, renderer); if (renderer instanceof IDynamicInstance) diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/MaterialType.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/MaterialType.java index bda912737..4865eecd6 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/MaterialType.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/MaterialType.java @@ -1,10 +1,5 @@ package com.simibubi.create.foundation.render.backend.instancing; -import com.simibubi.create.foundation.render.backend.gl.BasicProgram; - public class MaterialType> { - public

RenderMaterial get(InstancedTileRenderer

renderer) { - return renderer.getMaterial(this); - } } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/RenderMaterial.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/RenderMaterial.java index bfdd3fd4e..d9557abec 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/RenderMaterial.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/RenderMaterial.java @@ -56,7 +56,7 @@ public class RenderMaterial

buildModel(partial.get(), referenceState, modelTransform.get())); } - public MODEL getModel(Compartment compartment, BlockState toRender) { - return get(compartment, toRender, () -> buildModel(toRender)); + public MODEL getModel(BlockState toRender) { + return get(Compartment.GENERIC_TILE, toRender, () -> buildModel(toRender)); } public MODEL get(Compartment compartment, T key, Supplier supplier) { diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/TileEntityInstance.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/TileEntityInstance.java index 4c66529da..97da4b18b 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/TileEntityInstance.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/TileEntityInstance.java @@ -1,6 +1,9 @@ package com.simibubi.create.foundation.render.backend.instancing; import com.simibubi.create.foundation.render.backend.instancing.impl.IFlatLight; +import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData; +import com.simibubi.create.foundation.render.backend.instancing.impl.OrientedData; + import net.minecraft.block.BlockState; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; @@ -10,16 +13,33 @@ import net.minecraft.world.World; import java.util.Arrays; import java.util.stream.Stream; +/** + * The layer between a {@link TileEntity} and the Flywheel backend. + * + *

{@link #updateLight()} is called after construction. + * + *

There are a few additional features that overriding classes can opt in to: + *

    + *
  • {@link IDynamicInstance}
  • + *
  • {@link ITickableInstance}
  • + *
+ * See the interfaces' documentation for more information about each one. + * + *
Implementing one or more of these will give a {@link TileEntityInstance} access + * to more interesting and regular points within a tick or a frame. + * + * @param The type of {@link TileEntity} your class is an instance of. + */ public abstract class TileEntityInstance { - protected final InstancedTileRenderer modelManager; + protected final InstancedTileRenderer renderer; protected final T tile; protected final World world; protected final BlockPos pos; protected final BlockState blockState; - public TileEntityInstance(InstancedTileRenderer modelManager, T tile) { - this.modelManager = modelManager; + public TileEntityInstance(InstancedTileRenderer renderer, T tile) { + this.renderer = renderer; this.tile = tile; this.world = tile.getWorld(); this.pos = tile.getPos(); @@ -30,26 +50,46 @@ public abstract class TileEntityInstance { * Update instance data here. Good for when data doesn't change very often and when animations are GPU based. * Don't query lighting data here, that's handled separately in {@link #updateLight()}. * - * If your animations are complex and more CPU driven, use {@link IDynamicInstance} or {@link ITickableInstance}. + *

If your animations are complex or more CPU driven, see {@link IDynamicInstance} or {@link ITickableInstance}. */ protected void update() { } /** - * Called when a light update occurs in the world. If your model needs it, update light here. + * Called after construction and when a light update occurs in the world. + * + *
If your model needs it, update light here. */ public void updateLight() { } /** - * Call {@link InstanceKey#delete()} on all acquired keys. + * Free any acquired resources. + * + *
eg. call {@link InstanceKey#delete()}. */ public abstract void remove(); + /** + * Just before {@link #update()} would be called, shouldReset() is checked. + * If this function returns true, then this instance will be {@link #remove}d, + * and another instance will be constructed to replace it. This allows for more sane resource + * acquisition compared to trying to update everything within the lifetime of an instance. + * + * @return true if this instance should be discarded and refreshed. + */ public boolean shouldReset() { return tile.getBlockState() != blockState; } - public BlockPos getFloatingPos() { - return pos.subtract(modelManager.getOriginCoordinate()); + /** + * In order to accommodate for floating point precision errors at high coordinates, + * {@link InstancedTileRenderer}s are allowed to arbitrarily adjust the origin, and + * shift the world matrix provided as a shader uniform accordingly. + * + * @return The {@link BlockPos} at which the {@link TileEntity} this instance + * represents should be rendered at to appear in the correct location. + */ + public BlockPos getInstancePosition() { + return pos.subtract(renderer.getOriginCoordinate()); } protected void relight(BlockPos pos, IFlatLight... models) { @@ -67,4 +107,12 @@ public abstract class TileEntityInstance { protected void relight(int block, int sky, Stream> models) { models.forEach(model -> model.setBlockLight(block).setSkyLight(sky)); } + + protected RenderMaterial> getTransformMaterial() { + return renderer.getTransformMaterial(); + } + + protected RenderMaterial> getOrientedMaterial() { + return renderer.getOrientedMaterial(); + } } From affb8abfbddb06e3330d92ae95b8b0ad92f7f301 Mon Sep 17 00:00:00 2001 From: JozsefA Date: Thu, 25 Mar 2021 14:48:42 -0700 Subject: [PATCH 4/9] Potentially fix weird crash. --- .../render/backend/instancing/InstancedTileRenderer.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java index 193d4e5be..ebb6f8a57 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java @@ -196,6 +196,8 @@ public abstract class InstancedTileRenderer

{ if (world == null) return false; + if (world.isAirBlock(tile.getPos())) return false; + if (world == Minecraft.getInstance().world) { BlockPos pos = tile.getPos(); From 2e5d7a734f4324fb01a6de2263eac8c010226289 Mon Sep 17 00:00:00 2001 From: JozsefA Date: Thu, 25 Mar 2021 15:10:40 -0700 Subject: [PATCH 5/9] Fix ConcurrentModificationException preparing frame for rendering. --- .../render/ContraptionKineticRenderer.java | 10 ++++---- .../instancing/InstancedTileRenderer.java | 24 +++++++++++-------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionKineticRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionKineticRenderer.java index c6b3df6e6..20d0bc6a5 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionKineticRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionKineticRenderer.java @@ -25,7 +25,7 @@ import java.util.ArrayList; public class ContraptionKineticRenderer extends InstancedTileRenderer { - protected ArrayList actors = new ArrayList<>(); + protected ArrayList actors = new ArrayList<>(); private final WeakReference contraption; @@ -46,25 +46,25 @@ public class ContraptionKineticRenderer extends InstancedTileRenderer actor) { + public ActorInstance createActor(Pair actor) { Template.BlockInfo blockInfo = actor.getLeft(); MovementContext context = actor.getRight(); MovementBehaviour movementBehaviour = AllMovementBehaviours.of(blockInfo.state); if (movementBehaviour != null && movementBehaviour.hasSpecialInstancedRendering()) { - com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance instance = movementBehaviour.createInstance(this, context); + ActorInstance instance = movementBehaviour.createInstance(this, context); actors.add(instance); diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java index ebb6f8a57..ba4592852 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java @@ -44,10 +44,7 @@ public abstract class InstancedTileRenderer

{ } public void beginFrame(double cameraX, double cameraY, double cameraZ) { - if (queuedAdditions.size() > 0) { - queuedAdditions.forEach(this::addInternal); - queuedAdditions.clear(); - } + processQueuedAdditions(); if (dynamicInstances.size() > 0) dynamicInstances.values().forEach(IDynamicInstance::beginFrame); } @@ -111,12 +108,6 @@ public abstract class InstancedTileRenderer

{ } } - public void queueAdd(T tile) { - if (!Backend.canUseInstancing()) return; - - queuedAdditions.add(tile); - } - public void update(T tile) { if (!Backend.canUseInstancing()) return; @@ -144,6 +135,19 @@ public abstract class InstancedTileRenderer

{ } } + public synchronized void queueAdd(T tile) { + if (!Backend.canUseInstancing()) return; + + queuedAdditions.add(tile); + } + + protected synchronized void processQueuedAdditions() { + if (queuedAdditions.size() > 0) { + queuedAdditions.forEach(this::addInternal); + queuedAdditions.clear(); + } + } + private void addInternal(TileEntity tile) { getInstance(tile, true); } From 718142e26f06736ad807c1af4ab5468c9c1bba59 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Fri, 26 Mar 2021 00:15:38 +0100 Subject: [PATCH 6/9] Faith in your Depot - Added Weighted Ejectors - Fixed? some tunnel distribution inconsistencies --- src/generated/resources/.cache/cache | 39 +- .../assets/create/blockstates/fluid_pipe.json | 110 ++-- .../create/blockstates/radial_chassis.json | 96 ++-- .../create/blockstates/weighted_ejector.json | 19 + .../resources/assets/create/lang/en_ud.json | 1 + .../resources/assets/create/lang/en_us.json | 85 ++- .../assets/create/lang/unfinished/de_de.json | 87 ++- .../assets/create/lang/unfinished/es_es.json | 87 ++- .../assets/create/lang/unfinished/es_mx.json | 87 ++- .../assets/create/lang/unfinished/fr_fr.json | 87 ++- .../assets/create/lang/unfinished/it_it.json | 87 ++- .../assets/create/lang/unfinished/ja_jp.json | 87 ++- .../assets/create/lang/unfinished/ko_kr.json | 87 ++- .../assets/create/lang/unfinished/nl_nl.json | 87 ++- .../assets/create/lang/unfinished/pt_br.json | 87 ++- .../assets/create/lang/unfinished/ru_ru.json | 87 ++- .../assets/create/lang/unfinished/zh_cn.json | 87 ++- .../assets/create/lang/unfinished/zh_tw.json | 87 ++- .../create/models/item/weighted_ejector.json | 3 + .../data/create/advancements/aesthetics.json | 4 +- .../crafting/kinetics/weighted_ejector.json | 32 ++ .../loot_tables/blocks/weighted_ejector.json | 19 + .../crafting/kinetics/weighted_ejector.json | 22 + .../com/simibubi/create/AllBlockPartials.java | 2 + .../java/com/simibubi/create/AllBlocks.java | 101 +++- .../com/simibubi/create/AllTileEntities.java | 56 +- .../contraptions/base/KineticTileEntity.java | 2 - .../mixer/BasinOperatorBlockItem.java | 2 +- .../components/saw/SawTileEntity.java | 2 +- .../fluids/actors/ItemDrainTileEntity.java | 2 +- .../block/belts/tunnel/BeltTunnelBlock.java | 2 +- .../belts/tunnel/BeltTunnelInstance.java | 28 +- .../belts/tunnel/BeltTunnelTileEntity.java | 4 +- .../belts/tunnel/BrassTunnelTileEntity.java | 106 ++-- .../logistics/block/depot/DepotBehaviour.java | 379 +++++++++++++ .../logistics/block/depot/DepotBlock.java | 79 +-- .../block/depot/DepotItemHandler.java | 24 +- .../logistics/block/depot/DepotRenderer.java | 36 +- .../block/depot/DepotTileEntity.java | 226 +------- .../logistics/block/depot/EjectorBlock.java | 152 ++++++ .../block/depot/EjectorElytraPacket.java | 51 ++ .../logistics/block/depot/EjectorItem.java | 52 ++ .../block/depot/EjectorPlacementPacket.java | 68 +++ .../block/depot/EjectorRenderer.java | 97 ++++ .../block/depot/EjectorTargetHandler.java | 269 ++++++++++ .../block/depot/EjectorTileEntity.java | 496 ++++++++++++++++++ .../block/depot/EjectorTriggerPacket.java | 29 + .../logistics/block/depot/EntityLauncher.java | 140 +++++ .../block/depot/SharedDepotBlockMethods.java | 111 ++++ .../mechanicalArm/ArmInteractionPoint.java | 2 +- .../simibubi/create/events/ClientEvents.java | 2 + .../create/foundation/config/CKinetics.java | 2 + .../data/recipe/StandardRecipeGen.java | 10 +- .../foundation/networking/AllPackets.java | 33 +- .../ponder/content/PonderIndex.java | 2 + .../belt/DirectBeltInputBehaviour.java | 8 +- .../scrollvalue/ScrollValueBehaviour.java | 12 + .../scrollvalue/ScrollValueHandler.java | 2 + .../scrollvalue/ScrollValueRenderer.java | 4 +- .../foundation/utility/IntAttached.java | 33 +- .../assets/create/lang/default/messages.json | 6 + .../models/block/weighted_ejector/block.json | 112 ++++ .../models/block/weighted_ejector/item.json | 247 +++++++++ .../models/block/weighted_ejector/top.json | 126 +++++ .../weighted_ejector/weighted depot.bbmodel | 1 + .../block/weighted_ejector_casing.png | Bin 0 -> 1308 bytes .../textures/block/weighted_ejector_inner.png | Bin 0 -> 487 bytes .../textures/block/weighted_ejector_top.png | Bin 0 -> 613 bytes 68 files changed, 3951 insertions(+), 641 deletions(-) create mode 100644 src/generated/resources/assets/create/blockstates/weighted_ejector.json create mode 100644 src/generated/resources/assets/create/models/item/weighted_ejector.json create mode 100644 src/generated/resources/data/create/advancements/recipes/create.base/crafting/kinetics/weighted_ejector.json create mode 100644 src/generated/resources/data/create/loot_tables/blocks/weighted_ejector.json create mode 100644 src/generated/resources/data/create/recipes/crafting/kinetics/weighted_ejector.json create mode 100644 src/main/java/com/simibubi/create/content/logistics/block/depot/DepotBehaviour.java create mode 100644 src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorBlock.java create mode 100644 src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorElytraPacket.java create mode 100644 src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorItem.java create mode 100644 src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorPlacementPacket.java create mode 100644 src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorRenderer.java create mode 100644 src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorTargetHandler.java create mode 100644 src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorTileEntity.java create mode 100644 src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorTriggerPacket.java create mode 100644 src/main/java/com/simibubi/create/content/logistics/block/depot/EntityLauncher.java create mode 100644 src/main/java/com/simibubi/create/content/logistics/block/depot/SharedDepotBlockMethods.java create mode 100644 src/main/resources/assets/create/models/block/weighted_ejector/block.json create mode 100644 src/main/resources/assets/create/models/block/weighted_ejector/item.json create mode 100644 src/main/resources/assets/create/models/block/weighted_ejector/top.json create mode 100644 src/main/resources/assets/create/models/block/weighted_ejector/weighted depot.bbmodel create mode 100644 src/main/resources/assets/create/textures/block/weighted_ejector_casing.png create mode 100644 src/main/resources/assets/create/textures/block/weighted_ejector_inner.png create mode 100644 src/main/resources/assets/create/textures/block/weighted_ejector_top.png diff --git a/src/generated/resources/.cache/cache b/src/generated/resources/.cache/cache index 2ed629144..c067095a9 100644 --- a/src/generated/resources/.cache/cache +++ b/src/generated/resources/.cache/cache @@ -140,7 +140,7 @@ de8a40b7daf1497d5aecee47a43b3e0b1d030b00 assets/create/blockstates/fancy_scoria_ fc9ac0a7e7191b93516719455a17177fa6524ecc assets/create/blockstates/fancy_weathered_limestone_bricks_slab.json b2a7c321b1795f20e7433f81a55ce4683de081b8 assets/create/blockstates/fancy_weathered_limestone_bricks_stairs.json 6372fe02ba0065acb0758121c45a15a1a8fdc5de assets/create/blockstates/fancy_weathered_limestone_bricks_wall.json -37bc041b7449dc4d7962225e606125ba1b188974 assets/create/blockstates/fluid_pipe.json +48086bf71a824faf14841b698050cc8544b09a9b assets/create/blockstates/fluid_pipe.json f0eaab18e16c4f3f65ebf3b55b08f0dc445720fe assets/create/blockstates/fluid_tank.json 5408d92ab02af86539ac42971d4033545970bb3a assets/create/blockstates/fluid_valve.json e9da1794b6ece7f9aa8bcb43d42c23a55446133b assets/create/blockstates/flywheel.json @@ -337,7 +337,7 @@ e8b0a401c10d1ba67ed71ba31bd5f9bc28571b65 assets/create/blockstates/powered_toggl d06cd9a1101b18d306a786320aab12018b1325d6 assets/create/blockstates/purple_sail.json 92957119abd5fbcca36a113b2a80255fd70fc303 assets/create/blockstates/purple_seat.json 61035f8afe75ff7bbd291da5d8690bcbebe679eb assets/create/blockstates/purple_valve_handle.json -8d7e653bfd9846e684a0d3725595714a19201017 assets/create/blockstates/radial_chassis.json +4439fc83a8c7370ab44b211a3fd48abde20a4728 assets/create/blockstates/radial_chassis.json 45877c4d90a7185c2f304edbd67379d800920439 assets/create/blockstates/red_sail.json da1b08387af7afa0855ee8d040f620c01f20660a assets/create/blockstates/red_seat.json 722fc77bbf387af8a4016e42cbf9501d2b968881 assets/create/blockstates/red_valve_handle.json @@ -391,6 +391,7 @@ fd7a9c7095372485081436c91489cadb2b0c514e assets/create/blockstates/weathered_lim 47f8c91ff4c3f5cad782ab469a1fe5f4909dc7f1 assets/create/blockstates/weathered_limestone_cobblestone_stairs.json c60c3115fd6eeaa3a696428a87a74d184ab7d62d assets/create/blockstates/weathered_limestone_cobblestone_wall.json c77b46d8b459e5c7cc495393546f3fcca8a1fa1d assets/create/blockstates/weathered_limestone_pillar.json +c838c0792511ca2e14493b40032bb1370fac588a assets/create/blockstates/weighted_ejector.json 512bf17c9ea309b1f7da54440f923530d25e467c assets/create/blockstates/white_sail.json 4647010162eb4c350fad236d860317eaa1884c77 assets/create/blockstates/white_seat.json 89000903d0ab8139e919abea7aa0361b34c24e55 assets/create/blockstates/white_valve_handle.json @@ -401,20 +402,20 @@ a3a11524cd3515fc01d905767b4b7ea782adaf03 assets/create/blockstates/yellow_seat.j 6801fa1f466f172700e573e5b8ee8ee5f9ca4583 assets/create/blockstates/yellow_valve_handle.json 7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json -2b12f3cf99e498899207a8c4855210e7b5dc55cd assets/create/lang/en_ud.json -3522bc1dd15fd219aaf506766fb96be5f65b1939 assets/create/lang/en_us.json -d389c171d3d6a7382fb5b2e80b14e9bee53d8179 assets/create/lang/unfinished/de_de.json -b3caab7bb37be53ea93895cbaae2081452cd095e assets/create/lang/unfinished/es_es.json -0039068794faea032b0a39c954f142e2c8e4dfc1 assets/create/lang/unfinished/es_mx.json -1e34083359caea11cf9fdbb3f04a5881ea62a55e assets/create/lang/unfinished/fr_fr.json -c9abd10d296055f56877317a5c7dee14d0e33bf5 assets/create/lang/unfinished/it_it.json -83298d57034c2bb54924dff2d9b5257502ac3b9a assets/create/lang/unfinished/ja_jp.json -2c0e5fbfc813949d973e9f95af9501ed65b80b82 assets/create/lang/unfinished/ko_kr.json -4b3b113e5f9351b741974bc18d13d9d648d38f91 assets/create/lang/unfinished/nl_nl.json -9bddfffdf5349353d37d7003546c94799c6e812d assets/create/lang/unfinished/pt_br.json -5119b6690e8faa7e25450674caebf3c9c53fd54b assets/create/lang/unfinished/ru_ru.json -f11eb922b49753b60894f0dfe8baabe004d13e05 assets/create/lang/unfinished/zh_cn.json -017a9c9cc6f4538c8c497097cbd59f590b4af160 assets/create/lang/unfinished/zh_tw.json +ce0e5405da381a86625b908c569c5dbe347abdba assets/create/lang/en_ud.json +5383435fbb7d8be0c6cdc8a4ebfae072645e461f assets/create/lang/en_us.json +f67a8ceef1ec2091b53198e5509e80ac9e5b82c1 assets/create/lang/unfinished/de_de.json +174bd2c5b0fe4560030c4b5f92dd795ce7785245 assets/create/lang/unfinished/es_es.json +20783faf769c31e3d8200ebdc78256e6845e4fc6 assets/create/lang/unfinished/es_mx.json +c33171dd6390d80e39beef5c1511e72e7515c390 assets/create/lang/unfinished/fr_fr.json +38bff62b21ff5c241cab0e06cc161cd12162749e assets/create/lang/unfinished/it_it.json +c5a21a9238d491434fac9552c2372b0e2c5a8612 assets/create/lang/unfinished/ja_jp.json +fab3e5b787268d39fa3b1c31d923e9d4f4b66419 assets/create/lang/unfinished/ko_kr.json +62f4a359bf78057eaf9a3ef73766ee5e25833ce6 assets/create/lang/unfinished/nl_nl.json +4fd663de3f40c2e2c569de95cfce4167e8a42cb1 assets/create/lang/unfinished/pt_br.json +d431bca588528894340f8619cfcd82013eb04635 assets/create/lang/unfinished/ru_ru.json +752dee8e473eb96deaa7a6b1f8405a1313c99cec assets/create/lang/unfinished/zh_cn.json +efe100b3543f98a16f4230b7278a66f9bd00166c assets/create/lang/unfinished/zh_tw.json 846200eb548d3bfa2e77b41039de159b4b6cfb45 assets/create/models/block/acacia_window.json 1930fa3a3c98d53dd19e4ee7f55bc27fd47aa281 assets/create/models/block/acacia_window_pane_noside.json 1763ea2c9b981d187f5031ba608f3d5d3be3986a assets/create/models/block/acacia_window_pane_noside_alt.json @@ -1570,6 +1571,7 @@ def7382f3216c59d835ab64f534678f3d31ecc51 assets/create/models/item/weathered_lim 3d26cb5616182ba6926d0bf703119ebfbeacbe31 assets/create/models/item/weathered_limestone_cobblestone_stairs.json 62cba55cef305e8fcbc545363919f75d702a617b assets/create/models/item/weathered_limestone_cobblestone_wall.json 40bed7f5e9e97da45c5d9cebc3fcf87b2b13a808 assets/create/models/item/weathered_limestone_pillar.json +c36834070e12d25cd9e818d0d0181e267584b483 assets/create/models/item/weighted_ejector.json 8914910270736f8f15364c623cd08d4638383cc5 assets/create/models/item/wheat_flour.json 0cc80844db689404d4722c93f1002b0bed05edcd assets/create/models/item/whisk.json c6253e0f8db3c3992d3f78fe5045e276d39d5b22 assets/create/models/item/white_sail.json @@ -1585,7 +1587,7 @@ d080b1b25e5bc8baf5aee68691b08c7f12ece3b0 assets/create/models/item/windmill_bear 9f9455ccb5fc9e3cbfce73862b46078346a522a5 assets/create/models/item/zinc_nugget.json b1689617190c05ef34bd18456b0c7ae09bb3210f assets/create/models/item/zinc_ore.json e76041b7ae829fdd7dc0524f6ca4d2f89fca51bb assets/create/sounds.json -5d0cc4c0255dc241e61c173b31ddca70c88d08e4 data/create/advancements/aesthetics.json +0f1b4b980afba9bf2caf583b88e261bba8b10313 data/create/advancements/aesthetics.json 187921fa131b06721bfaf63f2623a28c141aae9a data/create/advancements/andesite_alloy.json 0ea2db7173b5be28b289ea7c9a6a0cf5805c60c7 data/create/advancements/andesite_casing.json 356f4855a2a6c65be3fb51d7d1aabf2ca6034d42 data/create/advancements/arm_blaze_burner.json @@ -1825,6 +1827,7 @@ f3fc3d4fee0712906f833aa17185f0bacb21922f data/create/advancements/recipes/create 07ec7b627bdb049f52dddcce021cec0ad44b0049 data/create/advancements/recipes/create.base/crafting/kinetics/turntable.json 89401c0a6dffa62dbffdbb63986f580a4878402e data/create/advancements/recipes/create.base/crafting/kinetics/vertical_gearboxfrom_conversion.json 4ab6ae87b6c3a29c0c2966dad2fa335a39fafe78 data/create/advancements/recipes/create.base/crafting/kinetics/water_wheel.json +e42093eecd00375bf95d562a6e845ab1a30d7991 data/create/advancements/recipes/create.base/crafting/kinetics/weighted_ejector.json 7c146cc51139c2a8e287a60c8d645fa6f6f48cb1 data/create/advancements/recipes/create.base/crafting/kinetics/whisk.json f876dcbd2877c921613a4af481c89d66664c1ea8 data/create/advancements/recipes/create.base/crafting/kinetics/white_sail.json 37e545b016a7c5cd283168ac71ace6467a5ad3ef data/create/advancements/recipes/create.base/crafting/kinetics/white_seat.json @@ -2688,6 +2691,7 @@ c2a62f12680d04ed4f586c501bb026e367243dd2 data/create/loot_tables/blocks/weathere a89f425c47c3831071b556697169a3124370aed7 data/create/loot_tables/blocks/weathered_limestone_cobblestone_stairs.json e8f3af61d9a2fd1ff5b32c9bb474ed005e6d70c4 data/create/loot_tables/blocks/weathered_limestone_cobblestone_wall.json 54358a64639957cc66ffa5296ff45723f7adf00e data/create/loot_tables/blocks/weathered_limestone_pillar.json +e3969f1c5966c4992b3280a06e1d6c5000c37df5 data/create/loot_tables/blocks/weighted_ejector.json 28ae0ee8a0b1fb6becae6264de687fe17940708e data/create/loot_tables/blocks/white_sail.json 969eda31556feb5a68e350762848d17453275fee data/create/loot_tables/blocks/white_seat.json 79fe374f8e677088f928a3a49ff5eeed6128d165 data/create/loot_tables/blocks/white_valve_handle.json @@ -2887,6 +2891,7 @@ af5854ee2fa3be195ad9abcdeebe6ed7306b651c data/create/recipes/crafting/kinetics/s 8494f5fcd85a740fa0f0384e3522d8cdd905ce49 data/create/recipes/crafting/kinetics/turntable.json 057c889b0a306f44b8835c896663154ccd9ff12f data/create/recipes/crafting/kinetics/vertical_gearboxfrom_conversion.json 4fb009b86a51b2e259bd1f73848803f6276dd820 data/create/recipes/crafting/kinetics/water_wheel.json +254265966b3c7c7a307e908c313a15ce92d20c83 data/create/recipes/crafting/kinetics/weighted_ejector.json f508d510576c93712e7f5265345a32e8818bbf0d data/create/recipes/crafting/kinetics/whisk.json d80a741d2f0d4f742217b43d7e4d37f003ec9f9d data/create/recipes/crafting/kinetics/white_sail.json f4d88aa2edea548d29cf2678a111d8bb5db7720a data/create/recipes/crafting/kinetics/white_seat.json diff --git a/src/generated/resources/assets/create/blockstates/fluid_pipe.json b/src/generated/resources/assets/create/blockstates/fluid_pipe.json index 37315d0be..80a25280c 100644 --- a/src/generated/resources/assets/create/blockstates/fluid_pipe.json +++ b/src/generated/resources/assets/create/blockstates/fluid_pipe.json @@ -181,10 +181,10 @@ }, { "when": { - "east": "false", - "west": "true", "south": "true", - "north": "false" + "west": "true", + "north": "false", + "east": "false" }, "apply": { "model": "create:block/fluid_pipe/lu_y" @@ -192,10 +192,10 @@ }, { "when": { - "east": "true", - "west": "false", "south": "true", - "north": "false" + "west": "false", + "north": "false", + "east": "true" }, "apply": { "model": "create:block/fluid_pipe/ru_y" @@ -203,10 +203,10 @@ }, { "when": { - "east": "false", - "west": "true", "south": "false", - "north": "true" + "west": "true", + "north": "true", + "east": "false" }, "apply": { "model": "create:block/fluid_pipe/ld_y" @@ -214,10 +214,10 @@ }, { "when": { - "east": "true", - "west": "false", "south": "false", - "north": "true" + "west": "false", + "north": "true", + "east": "true" }, "apply": { "model": "create:block/fluid_pipe/rd_y" @@ -225,10 +225,10 @@ }, { "when": { - "east": "false", - "west": "false", "south": "true", - "north": "true" + "west": "false", + "north": "true", + "east": "false" }, "apply": { "model": "create:block/fluid_pipe/ud_y" @@ -236,10 +236,10 @@ }, { "when": { - "east": "false", - "west": "false", "south": "true", - "north": "false" + "west": "false", + "north": "false", + "east": "false" }, "apply": { "model": "create:block/fluid_pipe/ud_y" @@ -247,10 +247,10 @@ }, { "when": { - "east": "false", - "west": "false", "south": "false", - "north": "true" + "west": "false", + "north": "true", + "east": "false" }, "apply": { "model": "create:block/fluid_pipe/ud_y" @@ -258,10 +258,10 @@ }, { "when": { - "east": "true", + "south": "false", "west": "true", - "south": "false", - "north": "false" + "north": "false", + "east": "true" }, "apply": { "model": "create:block/fluid_pipe/lr_y" @@ -269,10 +269,10 @@ }, { "when": { - "east": "false", + "south": "false", "west": "true", - "south": "false", - "north": "false" + "north": "false", + "east": "false" }, "apply": { "model": "create:block/fluid_pipe/lr_y" @@ -280,10 +280,10 @@ }, { "when": { - "east": "true", - "west": "false", "south": "false", - "north": "false" + "west": "false", + "north": "false", + "east": "true" }, "apply": { "model": "create:block/fluid_pipe/lr_y" @@ -291,10 +291,10 @@ }, { "when": { - "east": "false", - "west": "false", "south": "false", - "north": "false" + "west": "false", + "north": "false", + "east": "false" }, "apply": { "model": "create:block/fluid_pipe/none_y" @@ -303,9 +303,9 @@ { "when": { "down": "false", - "east": "true", + "up": "true", "west": "false", - "up": "true" + "east": "true" }, "apply": { "model": "create:block/fluid_pipe/lu_z" @@ -314,9 +314,9 @@ { "when": { "down": "false", - "east": "false", + "up": "true", "west": "true", - "up": "true" + "east": "false" }, "apply": { "model": "create:block/fluid_pipe/ru_z" @@ -325,9 +325,9 @@ { "when": { "down": "true", - "east": "true", + "up": "false", "west": "false", - "up": "false" + "east": "true" }, "apply": { "model": "create:block/fluid_pipe/ld_z" @@ -336,9 +336,9 @@ { "when": { "down": "true", - "east": "false", + "up": "false", "west": "true", - "up": "false" + "east": "false" }, "apply": { "model": "create:block/fluid_pipe/rd_z" @@ -347,9 +347,9 @@ { "when": { "down": "true", - "east": "false", + "up": "true", "west": "false", - "up": "true" + "east": "false" }, "apply": { "model": "create:block/fluid_pipe/ud_z" @@ -358,9 +358,9 @@ { "when": { "down": "false", - "east": "false", + "up": "true", "west": "false", - "up": "true" + "east": "false" }, "apply": { "model": "create:block/fluid_pipe/ud_z" @@ -369,9 +369,9 @@ { "when": { "down": "true", - "east": "false", + "up": "false", "west": "false", - "up": "false" + "east": "false" }, "apply": { "model": "create:block/fluid_pipe/ud_z" @@ -380,9 +380,9 @@ { "when": { "down": "false", - "east": "true", + "up": "false", "west": "true", - "up": "false" + "east": "true" }, "apply": { "model": "create:block/fluid_pipe/lr_z" @@ -391,9 +391,9 @@ { "when": { "down": "false", - "east": "true", + "up": "false", "west": "false", - "up": "false" + "east": "true" }, "apply": { "model": "create:block/fluid_pipe/lr_z" @@ -402,9 +402,9 @@ { "when": { "down": "false", - "east": "false", + "up": "false", "west": "true", - "up": "false" + "east": "false" }, "apply": { "model": "create:block/fluid_pipe/lr_z" @@ -413,9 +413,9 @@ { "when": { "down": "false", - "east": "false", + "up": "false", "west": "false", - "up": "false" + "east": "false" }, "apply": { "model": "create:block/fluid_pipe/none_z" diff --git a/src/generated/resources/assets/create/blockstates/radial_chassis.json b/src/generated/resources/assets/create/blockstates/radial_chassis.json index 9d00ea8b1..8bd829ffc 100644 --- a/src/generated/resources/assets/create/blockstates/radial_chassis.json +++ b/src/generated/resources/assets/create/blockstates/radial_chassis.json @@ -29,8 +29,8 @@ }, { "when": { - "sticky_south": "true", - "axis": "x" + "axis": "x", + "sticky_south": "true" }, "apply": { "model": "create:block/radial_chassis_side_x_sticky", @@ -39,8 +39,8 @@ }, { "when": { - "sticky_south": "true", - "axis": "y" + "axis": "y", + "sticky_south": "true" }, "apply": { "model": "create:block/radial_chassis_side_y_sticky" @@ -48,8 +48,8 @@ }, { "when": { - "sticky_south": "true", - "axis": "z" + "axis": "z", + "sticky_south": "true" }, "apply": { "model": "create:block/radial_chassis_side_x_sticky", @@ -59,8 +59,8 @@ }, { "when": { - "sticky_south": "false", - "axis": "x" + "axis": "x", + "sticky_south": "false" }, "apply": { "model": "create:block/radial_chassis_side_x", @@ -69,8 +69,8 @@ }, { "when": { - "sticky_south": "false", - "axis": "y" + "axis": "y", + "sticky_south": "false" }, "apply": { "model": "create:block/radial_chassis_side_y" @@ -78,8 +78,8 @@ }, { "when": { - "sticky_south": "false", - "axis": "z" + "axis": "z", + "sticky_south": "false" }, "apply": { "model": "create:block/radial_chassis_side_x", @@ -89,8 +89,8 @@ }, { "when": { - "sticky_west": "true", - "axis": "x" + "axis": "x", + "sticky_west": "true" }, "apply": { "model": "create:block/radial_chassis_side_x_sticky", @@ -99,8 +99,8 @@ }, { "when": { - "sticky_west": "true", - "axis": "y" + "axis": "y", + "sticky_west": "true" }, "apply": { "model": "create:block/radial_chassis_side_y_sticky", @@ -109,8 +109,8 @@ }, { "when": { - "sticky_west": "true", - "axis": "z" + "axis": "z", + "sticky_west": "true" }, "apply": { "model": "create:block/radial_chassis_side_z_sticky", @@ -119,8 +119,8 @@ }, { "when": { - "sticky_west": "false", - "axis": "x" + "axis": "x", + "sticky_west": "false" }, "apply": { "model": "create:block/radial_chassis_side_x", @@ -129,8 +129,8 @@ }, { "when": { - "sticky_west": "false", - "axis": "y" + "axis": "y", + "sticky_west": "false" }, "apply": { "model": "create:block/radial_chassis_side_y", @@ -139,8 +139,8 @@ }, { "when": { - "sticky_west": "false", - "axis": "z" + "axis": "z", + "sticky_west": "false" }, "apply": { "model": "create:block/radial_chassis_side_z", @@ -149,8 +149,8 @@ }, { "when": { - "sticky_north": "true", - "axis": "x" + "axis": "x", + "sticky_north": "true" }, "apply": { "model": "create:block/radial_chassis_side_x_sticky" @@ -158,8 +158,8 @@ }, { "when": { - "sticky_north": "true", - "axis": "y" + "axis": "y", + "sticky_north": "true" }, "apply": { "model": "create:block/radial_chassis_side_y_sticky", @@ -168,8 +168,8 @@ }, { "when": { - "sticky_north": "true", - "axis": "z" + "axis": "z", + "sticky_north": "true" }, "apply": { "model": "create:block/radial_chassis_side_x_sticky", @@ -178,8 +178,8 @@ }, { "when": { - "sticky_north": "false", - "axis": "x" + "axis": "x", + "sticky_north": "false" }, "apply": { "model": "create:block/radial_chassis_side_x" @@ -187,8 +187,8 @@ }, { "when": { - "sticky_north": "false", - "axis": "y" + "axis": "y", + "sticky_north": "false" }, "apply": { "model": "create:block/radial_chassis_side_y", @@ -197,8 +197,8 @@ }, { "when": { - "sticky_north": "false", - "axis": "z" + "axis": "z", + "sticky_north": "false" }, "apply": { "model": "create:block/radial_chassis_side_x", @@ -207,8 +207,8 @@ }, { "when": { - "sticky_east": "true", - "axis": "x" + "axis": "x", + "sticky_east": "true" }, "apply": { "model": "create:block/radial_chassis_side_x_sticky", @@ -217,8 +217,8 @@ }, { "when": { - "sticky_east": "true", - "axis": "y" + "axis": "y", + "sticky_east": "true" }, "apply": { "model": "create:block/radial_chassis_side_y_sticky", @@ -227,8 +227,8 @@ }, { "when": { - "sticky_east": "true", - "axis": "z" + "axis": "z", + "sticky_east": "true" }, "apply": { "model": "create:block/radial_chassis_side_z_sticky" @@ -236,8 +236,8 @@ }, { "when": { - "sticky_east": "false", - "axis": "x" + "axis": "x", + "sticky_east": "false" }, "apply": { "model": "create:block/radial_chassis_side_x", @@ -246,8 +246,8 @@ }, { "when": { - "sticky_east": "false", - "axis": "y" + "axis": "y", + "sticky_east": "false" }, "apply": { "model": "create:block/radial_chassis_side_y", @@ -256,8 +256,8 @@ }, { "when": { - "sticky_east": "false", - "axis": "z" + "axis": "z", + "sticky_east": "false" }, "apply": { "model": "create:block/radial_chassis_side_z" diff --git a/src/generated/resources/assets/create/blockstates/weighted_ejector.json b/src/generated/resources/assets/create/blockstates/weighted_ejector.json new file mode 100644 index 000000000..12044c3db --- /dev/null +++ b/src/generated/resources/assets/create/blockstates/weighted_ejector.json @@ -0,0 +1,19 @@ +{ + "variants": { + "facing=north": { + "model": "create:block/weighted_ejector/block" + }, + "facing=south": { + "model": "create:block/weighted_ejector/block", + "y": 180 + }, + "facing=west": { + "model": "create:block/weighted_ejector/block", + "y": 270 + }, + "facing=east": { + "model": "create:block/weighted_ejector/block", + "y": 90 + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/lang/en_ud.json b/src/generated/resources/assets/create/lang/en_ud.json index d700f301e..9d5ae463e 100644 --- a/src/generated/resources/assets/create/lang/en_ud.json +++ b/src/generated/resources/assets/create/lang/en_ud.json @@ -392,6 +392,7 @@ "block.create.weathered_limestone_cobblestone_stairs": "s\u0279\u0131\u0250\u0287S \u01DDuo\u0287s\u01DD\u05DFqqo\u0186 \u01DDuo\u0287s\u01DD\u026F\u0131\uA780 p\u01DD\u0279\u01DD\u0265\u0287\u0250\u01DDM", "block.create.weathered_limestone_cobblestone_wall": "\u05DF\u05DF\u0250M \u01DDuo\u0287s\u01DD\u05DFqqo\u0186 \u01DDuo\u0287s\u01DD\u026F\u0131\uA780 p\u01DD\u0279\u01DD\u0265\u0287\u0250\u01DDM", "block.create.weathered_limestone_pillar": "\u0279\u0250\u05DF\u05DF\u0131\u0500 \u01DDuo\u0287s\u01DD\u026F\u0131\uA780 p\u01DD\u0279\u01DD\u0265\u0287\u0250\u01DDM", + "block.create.weighted_ejector": "\u0279o\u0287\u0254\u01DD\u0638\u018E p\u01DD\u0287\u0265b\u0131\u01DDM", "block.create.white_sail": "\u05DF\u0131\u0250S \u01DD\u0287\u0131\u0265M", "block.create.white_seat": "\u0287\u0250\u01DDS \u01DD\u0287\u0131\u0265M", "block.create.white_valve_handle": "\u01DD\u05DFpu\u0250H \u01DD\u028C\u05DF\u0250\u039B \u01DD\u0287\u0131\u0265M", diff --git a/src/generated/resources/assets/create/lang/en_us.json b/src/generated/resources/assets/create/lang/en_us.json index 43b6dae4a..57cfdb221 100644 --- a/src/generated/resources/assets/create/lang/en_us.json +++ b/src/generated/resources/assets/create/lang/en_us.json @@ -395,6 +395,7 @@ "block.create.weathered_limestone_cobblestone_stairs": "Weathered Limestone Cobblestone Stairs", "block.create.weathered_limestone_cobblestone_wall": "Weathered Limestone Cobblestone Wall", "block.create.weathered_limestone_pillar": "Weathered Limestone Pillar", + "block.create.weighted_ejector": "Weighted Ejector", "block.create.white_sail": "White Sail", "block.create.white_seat": "White Seat", "block.create.white_valve_handle": "White Valve Handle", @@ -1083,6 +1084,12 @@ "create.mechanical_arm.summary": "Mechanical Arm has %1$s input(s) and %2$s output(s).", "create.mechanical_arm.points_outside_range": "%1$s selected interaction point(s) removed due to range limitations.", + "create.weighted_ejector.target_set": "Target Selected", + "create.weighted_ejector.target_not_valid": "Ejecting to Adjacent block (Target was not Valid)", + "create.weighted_ejector.no_target": "Ejecting to Adjacent block (No Target was Selected)", + "create.weighted_ejector.targeting": "Ejecting to [%1$s,%2$s,%3$s]", + "create.weighted_ejector.stack_size": "Ejected Stack Size", + "create.logistics.when_multiple_outputs_available": "When Multiple Outputs Available", "create.mechanical_arm.selection_mode.round_robin": "Round Robin", @@ -1837,22 +1844,24 @@ "create.ponder.tag.contraption_actor.description": "Components which expose special behaviour when attached to a moving contraption", "create.ponder.tag.arm_targets": "Targets for Mechanical Arms", "create.ponder.tag.arm_targets.description": "Components which can be selected as inputs or outputs to the Mechanical Arm", - "create.ponder.tag.contraption_assembly": "Block Attachment Utility", - "create.ponder.tag.contraption_assembly.description": "Tools and Components used to assemble structures moved as an animated Contraption", "create.ponder.tag.logistics": "Item Transportation", "create.ponder.tag.logistics.description": "Components which help moving items around", "create.ponder.tag.movement_anchor": "Movement Anchors", "create.ponder.tag.movement_anchor.description": "Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways", + "create.ponder.tag.creative": "Creative Mode", + "create.ponder.tag.creative.description": "Components not usually available for Survival Mode", + "create.ponder.tag.kinetic_relays": "Kinetic Blocks", + "create.ponder.tag.kinetic_relays.description": "Components which help relaying Rotational Force elsewhere", + "create.ponder.tag.windmill_sails": "Sails for Windmill Bearings", + "create.ponder.tag.windmill_sails.description": "Blocks that count towards the strength of a Windmill Contraption when assembled. Each of these have equal efficiency in doing so.", + "create.ponder.tag.contraption_assembly": "Block Attachment Utility", + "create.ponder.tag.contraption_assembly.description": "Tools and Components used to assemble structures moved as an animated Contraption", "create.ponder.tag.decoration": "Aesthetics", "create.ponder.tag.decoration.description": "Components used mostly for decorative purposes", "create.ponder.tag.kinetic_appliances": "Kinetic Appliances", "create.ponder.tag.kinetic_appliances.description": "Components which make use of Rotational Force", "create.ponder.tag.redstone": "Logic Components", "create.ponder.tag.redstone.description": "Components which help with redstone engineering", - "create.ponder.tag.creative": "Creative Mode", - "create.ponder.tag.creative.description": "Components not usually available for Survival Mode", - "create.ponder.tag.kinetic_relays": "Kinetic Blocks", - "create.ponder.tag.kinetic_relays.description": "Components which help relaying Rotational Force elsewhere", "create.ponder.tag.fluids": "Fluid Manipulators", "create.ponder.tag.fluids.description": "Components which help relaying and making use of Fluids", @@ -2154,10 +2163,64 @@ "create.ponder.linear_chassis_group.text_2": "When one is moved by a Contraption, the others are dragged with it", "create.ponder.linear_chassis_group.text_3": "Chassis of a different type or facing another direction will not attach", + "create.ponder.mechanical_arm.header": "Setting up Mechanical Arms", + "create.ponder.mechanical_arm.text_1": "Mechanical Arms have to be assigned their in- and outputs before they are placed", + "create.ponder.mechanical_arm.text_2": "Right-Click inventories while holding the Arm to assign them as Targets", + "create.ponder.mechanical_arm.text_3": "Right-Click again to toggle between Input (Blue) and Output (Orange)", + "create.ponder.mechanical_arm.text_4": "Left-Click components to remove their Selection", + "create.ponder.mechanical_arm.text_5": "Once placed, the Mechanical Arm will target the blocks selected previously", + "create.ponder.mechanical_arm.text_6": "They can have any amount of in- and outputs within their range", + "create.ponder.mechanical_arm.text_7": "However, not every type of Inventory can be interacted with directly", + "create.ponder.mechanical_arm.text_8": "Funnels and Depots can help to Bridge that gap", + + "create.ponder.mechanical_arm_filtering.header": "Filtering Outputs of the Mechanical Arm", + "create.ponder.mechanical_arm_filtering.text_1": "Inputs", + "create.ponder.mechanical_arm_filtering.text_2": "Outputs", + "create.ponder.mechanical_arm_filtering.text_3": "Sometimes it is desirable to restrict targets of the Arm by matching a filter", + "create.ponder.mechanical_arm_filtering.text_4": "Mechanical Arms by themselves do not provide any options for filtering", + "create.ponder.mechanical_arm_filtering.text_5": "Brass Funnels as Targets do however communicate their own filter to the Arm", + "create.ponder.mechanical_arm_filtering.text_6": "The Arm is smart enough not to pick up items it couldn't distribute", + + "create.ponder.mechanical_arm_modes.header": "Distribution modes of the Mechanical Arm", + "create.ponder.mechanical_arm_modes.text_1": "Input", + "create.ponder.mechanical_arm_modes.text_2": "Outputs", + "create.ponder.mechanical_arm_modes.text_3": "Whenever an Arm has to choose between multiple valid outputs...", + "create.ponder.mechanical_arm_modes.text_4": "...it will act according to its setting", + "create.ponder.mechanical_arm_modes.text_5": "Scrolling with a Wrench will allow you to configure it", + "create.ponder.mechanical_arm_modes.text_6": "Round Robin mode simply cycles through all outputs that are available", + "create.ponder.mechanical_arm_modes.text_7": "If an output is unable to take more items, it will be skipped", + "create.ponder.mechanical_arm_modes.text_8": "Forced Round Robin mode will never skip outputs, and instead wait until they are free", + "create.ponder.mechanical_arm_modes.text_9": "Prefer First prioritizes the outputs selected earliest when configuring this Arm", + + "create.ponder.mechanical_arm_redstone.header": "Controlling Mechanical Arms with Redstone", + "create.ponder.mechanical_arm_redstone.text_1": "When powered by Redstone, Mechanical Arms will not activate", + "create.ponder.mechanical_arm_redstone.text_2": "Before stopping, it will finish any started cycles", + "create.ponder.mechanical_arm_redstone.text_3": "Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.mechanical_bearing.header": "Movings Structures using the Mechanical Bearing", "create.ponder.mechanical_bearing.text_1": "Mechanical Bearings attach to the block in front of them", "create.ponder.mechanical_bearing.text_2": "Upon receiving Rotational Force, it will assemble it into a Rotating Contraption", + "create.ponder.mechanical_crafter.header": "Setting up Mechanical Crafters", + "create.ponder.mechanical_crafter.text_1": "An array of Mechanical Crafters can be used to automate any Crafting Recipe", + "create.ponder.mechanical_crafter.text_2": "Using a Wrench, the Crafters' paths can be arranged", + "create.ponder.mechanical_crafter.text_3": "For a valid setup, all paths have to converge into one exit at any side", + "create.ponder.mechanical_crafter.text_4": "The outputs will be placed into the inventory at the exit", + "create.ponder.mechanical_crafter.text_5": "Mechanical Crafters require Rotational Force to operate", + "create.ponder.mechanical_crafter.text_6": "Right-Click the front to insert Items manually", + "create.ponder.mechanical_crafter.text_7": "Once every slot of a path contains an Item, the crafting process will begin", + "create.ponder.mechanical_crafter.text_8": "For recipes not fully occupying the crafter setup, the start can be forced using a Redstone Pulse", + + "create.ponder.mechanical_crafter_connect.header": "Connecting Inventories of Crafters", + "create.ponder.mechanical_crafter_connect.text_1": "Items can be inserted to Crafters automatically", + "create.ponder.mechanical_crafter_connect.text_2": "Using the Wrench at their backs, Mechanical Crafter inputs can be combined", + "create.ponder.mechanical_crafter_connect.text_3": "All connected Crafters can now be accessed by the same input location", + + "create.ponder.mechanical_crafter_covers.header": "Covering slots of Mechanical Crafters", + "create.ponder.mechanical_crafter_covers.text_1": "Some recipes will require additional Crafters to bridge gaps in the path", + "create.ponder.mechanical_crafter_covers.text_2": "Using Slot Covers, Crafters can be set to act as an Empty Slot in the arrangement", + "create.ponder.mechanical_crafter_covers.text_3": "Shared Inputs created with the Wrench at the back can also reach across covered Crafters", + "create.ponder.mechanical_drill.header": "Breaking Blocks with the Mechanical Drill", "create.ponder.mechanical_drill.text_1": "When given Rotational Force, a Mechanical Drill will break blocks directly in front of it", "create.ponder.mechanical_drill.text_2": "Its mining speed depends on the Rotational Input", @@ -2297,6 +2360,16 @@ "create.ponder.rotation_speed_controller.text_1": "Rot. Speed Controllers relay rotation from their axis to a Large Cogwheel above them", "create.ponder.rotation_speed_controller.text_2": "Using the scroll input on its side, the conveyed speed can be configured", + "create.ponder.sail.header": "Assembling Windmills using Sails", + "create.ponder.sail.text_1": "Sails are handy blocks to create Windmills with", + "create.ponder.sail.text_2": "They will attach to blocks and each other without the need of Super Glue or Chassis Blocks", + "create.ponder.sail.text_3": "Right-Click with Dye to paint them", + "create.ponder.sail.text_4": "Right-Click with Shears to turn them back into frames", + + "create.ponder.sail_frame.header": "Assembling Windmills using Sail Frames", + "create.ponder.sail_frame.text_1": "Sail Frames are handy blocks to create Windmills with", + "create.ponder.sail_frame.text_2": "They will attach to blocks and each other without the need of Super Glue or Chassis Blocks", + "create.ponder.sequenced_gearshift.header": "Controlling Rotational Speed using Sequenced Gearshifts", "create.ponder.sequenced_gearshift.text_1": "Seq. Gearshifts relay rotation by following a timed list of instructions", "create.ponder.sequenced_gearshift.text_2": "Right-click it to open the Configuration UI", diff --git a/src/generated/resources/assets/create/lang/unfinished/de_de.json b/src/generated/resources/assets/create/lang/unfinished/de_de.json index 9db22f031..aec1cbcc7 100644 --- a/src/generated/resources/assets/create/lang/unfinished/de_de.json +++ b/src/generated/resources/assets/create/lang/unfinished/de_de.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1443", + "_": "Missing Localizations: 1506", "_": "->------------------------] Game Elements [------------------------<-", @@ -396,6 +396,7 @@ "block.create.weathered_limestone_cobblestone_stairs": "UNLOCALIZED: Weathered Limestone Cobblestone Stairs", "block.create.weathered_limestone_cobblestone_wall": "UNLOCALIZED: Weathered Limestone Cobblestone Wall", "block.create.weathered_limestone_pillar": "Verwitterte Kalksteinsäule", + "block.create.weighted_ejector": "UNLOCALIZED: Weighted Ejector", "block.create.white_sail": "UNLOCALIZED: White Sail", "block.create.white_seat": "UNLOCALIZED: White Seat", "block.create.white_valve_handle": "UNLOCALIZED: White Valve Handle", @@ -1084,6 +1085,12 @@ "create.mechanical_arm.summary": "UNLOCALIZED: Mechanical Arm has %1$s input(s) and %2$s output(s).", "create.mechanical_arm.points_outside_range": "UNLOCALIZED: %1$s selected interaction point(s) removed due to range limitations.", + "create.weighted_ejector.target_set": "UNLOCALIZED: Target Selected", + "create.weighted_ejector.target_not_valid": "UNLOCALIZED: Ejecting to Adjacent block (Target was not Valid)", + "create.weighted_ejector.no_target": "UNLOCALIZED: Ejecting to Adjacent block (No Target was Selected)", + "create.weighted_ejector.targeting": "UNLOCALIZED: Ejecting to [%1$s,%2$s,%3$s]", + "create.weighted_ejector.stack_size": "UNLOCALIZED: Ejected Stack Size", + "create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available", "create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: Round Robin", @@ -1838,22 +1845,24 @@ "create.ponder.tag.contraption_actor.description": "UNLOCALIZED: Components which expose special behaviour when attached to a moving contraption", "create.ponder.tag.arm_targets": "UNLOCALIZED: Targets for Mechanical Arms", "create.ponder.tag.arm_targets.description": "UNLOCALIZED: Components which can be selected as inputs or outputs to the Mechanical Arm", - "create.ponder.tag.contraption_assembly": "UNLOCALIZED: Block Attachment Utility", - "create.ponder.tag.contraption_assembly.description": "UNLOCALIZED: Tools and Components used to assemble structures moved as an animated Contraption", "create.ponder.tag.logistics": "UNLOCALIZED: Item Transportation", "create.ponder.tag.logistics.description": "UNLOCALIZED: Components which help moving items around", "create.ponder.tag.movement_anchor": "UNLOCALIZED: Movement Anchors", "create.ponder.tag.movement_anchor.description": "UNLOCALIZED: Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways", + "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", + "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", + "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", + "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", + "create.ponder.tag.windmill_sails": "UNLOCALIZED: Sails for Windmill Bearings", + "create.ponder.tag.windmill_sails.description": "UNLOCALIZED: Blocks that count towards the strength of a Windmill Contraption when assembled. Each of these have equal efficiency in doing so.", + "create.ponder.tag.contraption_assembly": "UNLOCALIZED: Block Attachment Utility", + "create.ponder.tag.contraption_assembly.description": "UNLOCALIZED: Tools and Components used to assemble structures moved as an animated Contraption", "create.ponder.tag.decoration": "UNLOCALIZED: Aesthetics", "create.ponder.tag.decoration.description": "UNLOCALIZED: Components used mostly for decorative purposes", "create.ponder.tag.kinetic_appliances": "UNLOCALIZED: Kinetic Appliances", "create.ponder.tag.kinetic_appliances.description": "UNLOCALIZED: Components which make use of Rotational Force", "create.ponder.tag.redstone": "UNLOCALIZED: Logic Components", "create.ponder.tag.redstone.description": "UNLOCALIZED: Components which help with redstone engineering", - "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", - "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", - "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", - "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", "create.ponder.tag.fluids": "UNLOCALIZED: Fluid Manipulators", "create.ponder.tag.fluids.description": "UNLOCALIZED: Components which help relaying and making use of Fluids", @@ -2155,10 +2164,64 @@ "create.ponder.linear_chassis_group.text_2": "UNLOCALIZED: When one is moved by a Contraption, the others are dragged with it", "create.ponder.linear_chassis_group.text_3": "UNLOCALIZED: Chassis of a different type or facing another direction will not attach", + "create.ponder.mechanical_arm.header": "UNLOCALIZED: Setting up Mechanical Arms", + "create.ponder.mechanical_arm.text_1": "UNLOCALIZED: Mechanical Arms have to be assigned their in- and outputs before they are placed", + "create.ponder.mechanical_arm.text_2": "UNLOCALIZED: Right-Click inventories while holding the Arm to assign them as Targets", + "create.ponder.mechanical_arm.text_3": "UNLOCALIZED: Right-Click again to toggle between Input (Blue) and Output (Orange)", + "create.ponder.mechanical_arm.text_4": "UNLOCALIZED: Left-Click components to remove their Selection", + "create.ponder.mechanical_arm.text_5": "UNLOCALIZED: Once placed, the Mechanical Arm will target the blocks selected previously", + "create.ponder.mechanical_arm.text_6": "UNLOCALIZED: They can have any amount of in- and outputs within their range", + "create.ponder.mechanical_arm.text_7": "UNLOCALIZED: However, not every type of Inventory can be interacted with directly", + "create.ponder.mechanical_arm.text_8": "UNLOCALIZED: Funnels and Depots can help to Bridge that gap", + + "create.ponder.mechanical_arm_filtering.header": "UNLOCALIZED: Filtering Outputs of the Mechanical Arm", + "create.ponder.mechanical_arm_filtering.text_1": "UNLOCALIZED: Inputs", + "create.ponder.mechanical_arm_filtering.text_2": "UNLOCALIZED: Outputs", + "create.ponder.mechanical_arm_filtering.text_3": "UNLOCALIZED: Sometimes it is desirable to restrict targets of the Arm by matching a filter", + "create.ponder.mechanical_arm_filtering.text_4": "UNLOCALIZED: Mechanical Arms by themselves do not provide any options for filtering", + "create.ponder.mechanical_arm_filtering.text_5": "UNLOCALIZED: Brass Funnels as Targets do however communicate their own filter to the Arm", + "create.ponder.mechanical_arm_filtering.text_6": "UNLOCALIZED: The Arm is smart enough not to pick up items it couldn't distribute", + + "create.ponder.mechanical_arm_modes.header": "UNLOCALIZED: Distribution modes of the Mechanical Arm", + "create.ponder.mechanical_arm_modes.text_1": "UNLOCALIZED: Input", + "create.ponder.mechanical_arm_modes.text_2": "UNLOCALIZED: Outputs", + "create.ponder.mechanical_arm_modes.text_3": "UNLOCALIZED: Whenever an Arm has to choose between multiple valid outputs...", + "create.ponder.mechanical_arm_modes.text_4": "UNLOCALIZED: ...it will act according to its setting", + "create.ponder.mechanical_arm_modes.text_5": "UNLOCALIZED: Scrolling with a Wrench will allow you to configure it", + "create.ponder.mechanical_arm_modes.text_6": "UNLOCALIZED: Round Robin mode simply cycles through all outputs that are available", + "create.ponder.mechanical_arm_modes.text_7": "UNLOCALIZED: If an output is unable to take more items, it will be skipped", + "create.ponder.mechanical_arm_modes.text_8": "UNLOCALIZED: Forced Round Robin mode will never skip outputs, and instead wait until they are free", + "create.ponder.mechanical_arm_modes.text_9": "UNLOCALIZED: Prefer First prioritizes the outputs selected earliest when configuring this Arm", + + "create.ponder.mechanical_arm_redstone.header": "UNLOCALIZED: Controlling Mechanical Arms with Redstone", + "create.ponder.mechanical_arm_redstone.text_1": "UNLOCALIZED: When powered by Redstone, Mechanical Arms will not activate", + "create.ponder.mechanical_arm_redstone.text_2": "UNLOCALIZED: Before stopping, it will finish any started cycles", + "create.ponder.mechanical_arm_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.mechanical_bearing.header": "UNLOCALIZED: Movings Structures using the Mechanical Bearing", "create.ponder.mechanical_bearing.text_1": "UNLOCALIZED: Mechanical Bearings attach to the block in front of them", "create.ponder.mechanical_bearing.text_2": "UNLOCALIZED: Upon receiving Rotational Force, it will assemble it into a Rotating Contraption", + "create.ponder.mechanical_crafter.header": "UNLOCALIZED: Setting up Mechanical Crafters", + "create.ponder.mechanical_crafter.text_1": "UNLOCALIZED: An array of Mechanical Crafters can be used to automate any Crafting Recipe", + "create.ponder.mechanical_crafter.text_2": "UNLOCALIZED: Using a Wrench, the Crafters' paths can be arranged", + "create.ponder.mechanical_crafter.text_3": "UNLOCALIZED: For a valid setup, all paths have to converge into one exit at any side", + "create.ponder.mechanical_crafter.text_4": "UNLOCALIZED: The outputs will be placed into the inventory at the exit", + "create.ponder.mechanical_crafter.text_5": "UNLOCALIZED: Mechanical Crafters require Rotational Force to operate", + "create.ponder.mechanical_crafter.text_6": "UNLOCALIZED: Right-Click the front to insert Items manually", + "create.ponder.mechanical_crafter.text_7": "UNLOCALIZED: Once every slot of a path contains an Item, the crafting process will begin", + "create.ponder.mechanical_crafter.text_8": "UNLOCALIZED: For recipes not fully occupying the crafter setup, the start can be forced using a Redstone Pulse", + + "create.ponder.mechanical_crafter_connect.header": "UNLOCALIZED: Connecting Inventories of Crafters", + "create.ponder.mechanical_crafter_connect.text_1": "UNLOCALIZED: Items can be inserted to Crafters automatically", + "create.ponder.mechanical_crafter_connect.text_2": "UNLOCALIZED: Using the Wrench at their backs, Mechanical Crafter inputs can be combined", + "create.ponder.mechanical_crafter_connect.text_3": "UNLOCALIZED: All connected Crafters can now be accessed by the same input location", + + "create.ponder.mechanical_crafter_covers.header": "UNLOCALIZED: Covering slots of Mechanical Crafters", + "create.ponder.mechanical_crafter_covers.text_1": "UNLOCALIZED: Some recipes will require additional Crafters to bridge gaps in the path", + "create.ponder.mechanical_crafter_covers.text_2": "UNLOCALIZED: Using Slot Covers, Crafters can be set to act as an Empty Slot in the arrangement", + "create.ponder.mechanical_crafter_covers.text_3": "UNLOCALIZED: Shared Inputs created with the Wrench at the back can also reach across covered Crafters", + "create.ponder.mechanical_drill.header": "UNLOCALIZED: Breaking Blocks with the Mechanical Drill", "create.ponder.mechanical_drill.text_1": "UNLOCALIZED: When given Rotational Force, a Mechanical Drill will break blocks directly in front of it", "create.ponder.mechanical_drill.text_2": "UNLOCALIZED: Its mining speed depends on the Rotational Input", @@ -2298,6 +2361,16 @@ "create.ponder.rotation_speed_controller.text_1": "UNLOCALIZED: Rot. Speed Controllers relay rotation from their axis to a Large Cogwheel above them", "create.ponder.rotation_speed_controller.text_2": "UNLOCALIZED: Using the scroll input on its side, the conveyed speed can be configured", + "create.ponder.sail.header": "UNLOCALIZED: Assembling Windmills using Sails", + "create.ponder.sail.text_1": "UNLOCALIZED: Sails are handy blocks to create Windmills with", + "create.ponder.sail.text_2": "UNLOCALIZED: They will attach to blocks and each other without the need of Super Glue or Chassis Blocks", + "create.ponder.sail.text_3": "UNLOCALIZED: Right-Click with Dye to paint them", + "create.ponder.sail.text_4": "UNLOCALIZED: Right-Click with Shears to turn them back into frames", + + "create.ponder.sail_frame.header": "UNLOCALIZED: Assembling Windmills using Sail Frames", + "create.ponder.sail_frame.text_1": "UNLOCALIZED: Sail Frames are handy blocks to create Windmills with", + "create.ponder.sail_frame.text_2": "UNLOCALIZED: They will attach to blocks and each other without the need of Super Glue or Chassis Blocks", + "create.ponder.sequenced_gearshift.header": "UNLOCALIZED: Controlling Rotational Speed using Sequenced Gearshifts", "create.ponder.sequenced_gearshift.text_1": "UNLOCALIZED: Seq. Gearshifts relay rotation by following a timed list of instructions", "create.ponder.sequenced_gearshift.text_2": "UNLOCALIZED: Right-click it to open the Configuration UI", diff --git a/src/generated/resources/assets/create/lang/unfinished/es_es.json b/src/generated/resources/assets/create/lang/unfinished/es_es.json index 4b1671b37..683a53505 100644 --- a/src/generated/resources/assets/create/lang/unfinished/es_es.json +++ b/src/generated/resources/assets/create/lang/unfinished/es_es.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 474", + "_": "Missing Localizations: 537", "_": "->------------------------] Game Elements [------------------------<-", @@ -396,6 +396,7 @@ "block.create.weathered_limestone_cobblestone_stairs": "Escaleras de adoquín de piedra caliza erosionada", "block.create.weathered_limestone_cobblestone_wall": "Pared de adoquínes de piedra caliza erosionada", "block.create.weathered_limestone_pillar": "Pilar de piedra caliza erosionada", + "block.create.weighted_ejector": "UNLOCALIZED: Weighted Ejector", "block.create.white_sail": "Vela blanca", "block.create.white_seat": "Asiento blanco", "block.create.white_valve_handle": "Asa de válvula blanco", @@ -1084,6 +1085,12 @@ "create.mechanical_arm.summary": "El brazo mecánico tiene %1$s entrada(s) y %2$s salida(s)", "create.mechanical_arm.points_outside_range": "%1$s punto(s) de interacción seleccionado(s) eliminado(s) debido a las limitaciones de rango", + "create.weighted_ejector.target_set": "UNLOCALIZED: Target Selected", + "create.weighted_ejector.target_not_valid": "UNLOCALIZED: Ejecting to Adjacent block (Target was not Valid)", + "create.weighted_ejector.no_target": "UNLOCALIZED: Ejecting to Adjacent block (No Target was Selected)", + "create.weighted_ejector.targeting": "UNLOCALIZED: Ejecting to [%1$s,%2$s,%3$s]", + "create.weighted_ejector.stack_size": "UNLOCALIZED: Ejected Stack Size", + "create.logistics.when_multiple_outputs_available": "Cuando hay múltiples salidas disponibles", "create.mechanical_arm.selection_mode.round_robin": "Round Robin", @@ -1838,22 +1845,24 @@ "create.ponder.tag.contraption_actor.description": "UNLOCALIZED: Components which expose special behaviour when attached to a moving contraption", "create.ponder.tag.arm_targets": "UNLOCALIZED: Targets for Mechanical Arms", "create.ponder.tag.arm_targets.description": "UNLOCALIZED: Components which can be selected as inputs or outputs to the Mechanical Arm", - "create.ponder.tag.contraption_assembly": "UNLOCALIZED: Block Attachment Utility", - "create.ponder.tag.contraption_assembly.description": "UNLOCALIZED: Tools and Components used to assemble structures moved as an animated Contraption", "create.ponder.tag.logistics": "UNLOCALIZED: Item Transportation", "create.ponder.tag.logistics.description": "UNLOCALIZED: Components which help moving items around", "create.ponder.tag.movement_anchor": "UNLOCALIZED: Movement Anchors", "create.ponder.tag.movement_anchor.description": "UNLOCALIZED: Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways", + "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", + "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", + "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", + "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", + "create.ponder.tag.windmill_sails": "UNLOCALIZED: Sails for Windmill Bearings", + "create.ponder.tag.windmill_sails.description": "UNLOCALIZED: Blocks that count towards the strength of a Windmill Contraption when assembled. Each of these have equal efficiency in doing so.", + "create.ponder.tag.contraption_assembly": "UNLOCALIZED: Block Attachment Utility", + "create.ponder.tag.contraption_assembly.description": "UNLOCALIZED: Tools and Components used to assemble structures moved as an animated Contraption", "create.ponder.tag.decoration": "UNLOCALIZED: Aesthetics", "create.ponder.tag.decoration.description": "UNLOCALIZED: Components used mostly for decorative purposes", "create.ponder.tag.kinetic_appliances": "UNLOCALIZED: Kinetic Appliances", "create.ponder.tag.kinetic_appliances.description": "UNLOCALIZED: Components which make use of Rotational Force", "create.ponder.tag.redstone": "UNLOCALIZED: Logic Components", "create.ponder.tag.redstone.description": "UNLOCALIZED: Components which help with redstone engineering", - "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", - "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", - "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", - "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", "create.ponder.tag.fluids": "UNLOCALIZED: Fluid Manipulators", "create.ponder.tag.fluids.description": "UNLOCALIZED: Components which help relaying and making use of Fluids", @@ -2155,10 +2164,64 @@ "create.ponder.linear_chassis_group.text_2": "UNLOCALIZED: When one is moved by a Contraption, the others are dragged with it", "create.ponder.linear_chassis_group.text_3": "UNLOCALIZED: Chassis of a different type or facing another direction will not attach", + "create.ponder.mechanical_arm.header": "UNLOCALIZED: Setting up Mechanical Arms", + "create.ponder.mechanical_arm.text_1": "UNLOCALIZED: Mechanical Arms have to be assigned their in- and outputs before they are placed", + "create.ponder.mechanical_arm.text_2": "UNLOCALIZED: Right-Click inventories while holding the Arm to assign them as Targets", + "create.ponder.mechanical_arm.text_3": "UNLOCALIZED: Right-Click again to toggle between Input (Blue) and Output (Orange)", + "create.ponder.mechanical_arm.text_4": "UNLOCALIZED: Left-Click components to remove their Selection", + "create.ponder.mechanical_arm.text_5": "UNLOCALIZED: Once placed, the Mechanical Arm will target the blocks selected previously", + "create.ponder.mechanical_arm.text_6": "UNLOCALIZED: They can have any amount of in- and outputs within their range", + "create.ponder.mechanical_arm.text_7": "UNLOCALIZED: However, not every type of Inventory can be interacted with directly", + "create.ponder.mechanical_arm.text_8": "UNLOCALIZED: Funnels and Depots can help to Bridge that gap", + + "create.ponder.mechanical_arm_filtering.header": "UNLOCALIZED: Filtering Outputs of the Mechanical Arm", + "create.ponder.mechanical_arm_filtering.text_1": "UNLOCALIZED: Inputs", + "create.ponder.mechanical_arm_filtering.text_2": "UNLOCALIZED: Outputs", + "create.ponder.mechanical_arm_filtering.text_3": "UNLOCALIZED: Sometimes it is desirable to restrict targets of the Arm by matching a filter", + "create.ponder.mechanical_arm_filtering.text_4": "UNLOCALIZED: Mechanical Arms by themselves do not provide any options for filtering", + "create.ponder.mechanical_arm_filtering.text_5": "UNLOCALIZED: Brass Funnels as Targets do however communicate their own filter to the Arm", + "create.ponder.mechanical_arm_filtering.text_6": "UNLOCALIZED: The Arm is smart enough not to pick up items it couldn't distribute", + + "create.ponder.mechanical_arm_modes.header": "UNLOCALIZED: Distribution modes of the Mechanical Arm", + "create.ponder.mechanical_arm_modes.text_1": "UNLOCALIZED: Input", + "create.ponder.mechanical_arm_modes.text_2": "UNLOCALIZED: Outputs", + "create.ponder.mechanical_arm_modes.text_3": "UNLOCALIZED: Whenever an Arm has to choose between multiple valid outputs...", + "create.ponder.mechanical_arm_modes.text_4": "UNLOCALIZED: ...it will act according to its setting", + "create.ponder.mechanical_arm_modes.text_5": "UNLOCALIZED: Scrolling with a Wrench will allow you to configure it", + "create.ponder.mechanical_arm_modes.text_6": "UNLOCALIZED: Round Robin mode simply cycles through all outputs that are available", + "create.ponder.mechanical_arm_modes.text_7": "UNLOCALIZED: If an output is unable to take more items, it will be skipped", + "create.ponder.mechanical_arm_modes.text_8": "UNLOCALIZED: Forced Round Robin mode will never skip outputs, and instead wait until they are free", + "create.ponder.mechanical_arm_modes.text_9": "UNLOCALIZED: Prefer First prioritizes the outputs selected earliest when configuring this Arm", + + "create.ponder.mechanical_arm_redstone.header": "UNLOCALIZED: Controlling Mechanical Arms with Redstone", + "create.ponder.mechanical_arm_redstone.text_1": "UNLOCALIZED: When powered by Redstone, Mechanical Arms will not activate", + "create.ponder.mechanical_arm_redstone.text_2": "UNLOCALIZED: Before stopping, it will finish any started cycles", + "create.ponder.mechanical_arm_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.mechanical_bearing.header": "UNLOCALIZED: Movings Structures using the Mechanical Bearing", "create.ponder.mechanical_bearing.text_1": "UNLOCALIZED: Mechanical Bearings attach to the block in front of them", "create.ponder.mechanical_bearing.text_2": "UNLOCALIZED: Upon receiving Rotational Force, it will assemble it into a Rotating Contraption", + "create.ponder.mechanical_crafter.header": "UNLOCALIZED: Setting up Mechanical Crafters", + "create.ponder.mechanical_crafter.text_1": "UNLOCALIZED: An array of Mechanical Crafters can be used to automate any Crafting Recipe", + "create.ponder.mechanical_crafter.text_2": "UNLOCALIZED: Using a Wrench, the Crafters' paths can be arranged", + "create.ponder.mechanical_crafter.text_3": "UNLOCALIZED: For a valid setup, all paths have to converge into one exit at any side", + "create.ponder.mechanical_crafter.text_4": "UNLOCALIZED: The outputs will be placed into the inventory at the exit", + "create.ponder.mechanical_crafter.text_5": "UNLOCALIZED: Mechanical Crafters require Rotational Force to operate", + "create.ponder.mechanical_crafter.text_6": "UNLOCALIZED: Right-Click the front to insert Items manually", + "create.ponder.mechanical_crafter.text_7": "UNLOCALIZED: Once every slot of a path contains an Item, the crafting process will begin", + "create.ponder.mechanical_crafter.text_8": "UNLOCALIZED: For recipes not fully occupying the crafter setup, the start can be forced using a Redstone Pulse", + + "create.ponder.mechanical_crafter_connect.header": "UNLOCALIZED: Connecting Inventories of Crafters", + "create.ponder.mechanical_crafter_connect.text_1": "UNLOCALIZED: Items can be inserted to Crafters automatically", + "create.ponder.mechanical_crafter_connect.text_2": "UNLOCALIZED: Using the Wrench at their backs, Mechanical Crafter inputs can be combined", + "create.ponder.mechanical_crafter_connect.text_3": "UNLOCALIZED: All connected Crafters can now be accessed by the same input location", + + "create.ponder.mechanical_crafter_covers.header": "UNLOCALIZED: Covering slots of Mechanical Crafters", + "create.ponder.mechanical_crafter_covers.text_1": "UNLOCALIZED: Some recipes will require additional Crafters to bridge gaps in the path", + "create.ponder.mechanical_crafter_covers.text_2": "UNLOCALIZED: Using Slot Covers, Crafters can be set to act as an Empty Slot in the arrangement", + "create.ponder.mechanical_crafter_covers.text_3": "UNLOCALIZED: Shared Inputs created with the Wrench at the back can also reach across covered Crafters", + "create.ponder.mechanical_drill.header": "UNLOCALIZED: Breaking Blocks with the Mechanical Drill", "create.ponder.mechanical_drill.text_1": "UNLOCALIZED: When given Rotational Force, a Mechanical Drill will break blocks directly in front of it", "create.ponder.mechanical_drill.text_2": "UNLOCALIZED: Its mining speed depends on the Rotational Input", @@ -2298,6 +2361,16 @@ "create.ponder.rotation_speed_controller.text_1": "UNLOCALIZED: Rot. Speed Controllers relay rotation from their axis to a Large Cogwheel above them", "create.ponder.rotation_speed_controller.text_2": "UNLOCALIZED: Using the scroll input on its side, the conveyed speed can be configured", + "create.ponder.sail.header": "UNLOCALIZED: Assembling Windmills using Sails", + "create.ponder.sail.text_1": "UNLOCALIZED: Sails are handy blocks to create Windmills with", + "create.ponder.sail.text_2": "UNLOCALIZED: They will attach to blocks and each other without the need of Super Glue or Chassis Blocks", + "create.ponder.sail.text_3": "UNLOCALIZED: Right-Click with Dye to paint them", + "create.ponder.sail.text_4": "UNLOCALIZED: Right-Click with Shears to turn them back into frames", + + "create.ponder.sail_frame.header": "UNLOCALIZED: Assembling Windmills using Sail Frames", + "create.ponder.sail_frame.text_1": "UNLOCALIZED: Sail Frames are handy blocks to create Windmills with", + "create.ponder.sail_frame.text_2": "UNLOCALIZED: They will attach to blocks and each other without the need of Super Glue or Chassis Blocks", + "create.ponder.sequenced_gearshift.header": "UNLOCALIZED: Controlling Rotational Speed using Sequenced Gearshifts", "create.ponder.sequenced_gearshift.text_1": "UNLOCALIZED: Seq. Gearshifts relay rotation by following a timed list of instructions", "create.ponder.sequenced_gearshift.text_2": "UNLOCALIZED: Right-click it to open the Configuration UI", diff --git a/src/generated/resources/assets/create/lang/unfinished/es_mx.json b/src/generated/resources/assets/create/lang/unfinished/es_mx.json index 087f4834d..970066780 100644 --- a/src/generated/resources/assets/create/lang/unfinished/es_mx.json +++ b/src/generated/resources/assets/create/lang/unfinished/es_mx.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1373", + "_": "Missing Localizations: 1436", "_": "->------------------------] Game Elements [------------------------<-", @@ -396,6 +396,7 @@ "block.create.weathered_limestone_cobblestone_stairs": "Escaleras de Piedra Labrada de Caliza Meteorizada", "block.create.weathered_limestone_cobblestone_wall": "Pared de Piedra Labrada de Caliza Meteorizada", "block.create.weathered_limestone_pillar": "Pilar de Caliza Meteorizada", + "block.create.weighted_ejector": "UNLOCALIZED: Weighted Ejector", "block.create.white_sail": "Vela Blanca", "block.create.white_seat": "Asiento Blanco", "block.create.white_valve_handle": "Manija de Válvula Blanca", @@ -1084,6 +1085,12 @@ "create.mechanical_arm.summary": "UNLOCALIZED: Mechanical Arm has %1$s input(s) and %2$s output(s).", "create.mechanical_arm.points_outside_range": "UNLOCALIZED: %1$s selected interaction point(s) removed due to range limitations.", + "create.weighted_ejector.target_set": "UNLOCALIZED: Target Selected", + "create.weighted_ejector.target_not_valid": "UNLOCALIZED: Ejecting to Adjacent block (Target was not Valid)", + "create.weighted_ejector.no_target": "UNLOCALIZED: Ejecting to Adjacent block (No Target was Selected)", + "create.weighted_ejector.targeting": "UNLOCALIZED: Ejecting to [%1$s,%2$s,%3$s]", + "create.weighted_ejector.stack_size": "UNLOCALIZED: Ejected Stack Size", + "create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available", "create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: Round Robin", @@ -1838,22 +1845,24 @@ "create.ponder.tag.contraption_actor.description": "UNLOCALIZED: Components which expose special behaviour when attached to a moving contraption", "create.ponder.tag.arm_targets": "UNLOCALIZED: Targets for Mechanical Arms", "create.ponder.tag.arm_targets.description": "UNLOCALIZED: Components which can be selected as inputs or outputs to the Mechanical Arm", - "create.ponder.tag.contraption_assembly": "UNLOCALIZED: Block Attachment Utility", - "create.ponder.tag.contraption_assembly.description": "UNLOCALIZED: Tools and Components used to assemble structures moved as an animated Contraption", "create.ponder.tag.logistics": "UNLOCALIZED: Item Transportation", "create.ponder.tag.logistics.description": "UNLOCALIZED: Components which help moving items around", "create.ponder.tag.movement_anchor": "UNLOCALIZED: Movement Anchors", "create.ponder.tag.movement_anchor.description": "UNLOCALIZED: Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways", + "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", + "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", + "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", + "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", + "create.ponder.tag.windmill_sails": "UNLOCALIZED: Sails for Windmill Bearings", + "create.ponder.tag.windmill_sails.description": "UNLOCALIZED: Blocks that count towards the strength of a Windmill Contraption when assembled. Each of these have equal efficiency in doing so.", + "create.ponder.tag.contraption_assembly": "UNLOCALIZED: Block Attachment Utility", + "create.ponder.tag.contraption_assembly.description": "UNLOCALIZED: Tools and Components used to assemble structures moved as an animated Contraption", "create.ponder.tag.decoration": "UNLOCALIZED: Aesthetics", "create.ponder.tag.decoration.description": "UNLOCALIZED: Components used mostly for decorative purposes", "create.ponder.tag.kinetic_appliances": "UNLOCALIZED: Kinetic Appliances", "create.ponder.tag.kinetic_appliances.description": "UNLOCALIZED: Components which make use of Rotational Force", "create.ponder.tag.redstone": "UNLOCALIZED: Logic Components", "create.ponder.tag.redstone.description": "UNLOCALIZED: Components which help with redstone engineering", - "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", - "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", - "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", - "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", "create.ponder.tag.fluids": "UNLOCALIZED: Fluid Manipulators", "create.ponder.tag.fluids.description": "UNLOCALIZED: Components which help relaying and making use of Fluids", @@ -2155,10 +2164,64 @@ "create.ponder.linear_chassis_group.text_2": "UNLOCALIZED: When one is moved by a Contraption, the others are dragged with it", "create.ponder.linear_chassis_group.text_3": "UNLOCALIZED: Chassis of a different type or facing another direction will not attach", + "create.ponder.mechanical_arm.header": "UNLOCALIZED: Setting up Mechanical Arms", + "create.ponder.mechanical_arm.text_1": "UNLOCALIZED: Mechanical Arms have to be assigned their in- and outputs before they are placed", + "create.ponder.mechanical_arm.text_2": "UNLOCALIZED: Right-Click inventories while holding the Arm to assign them as Targets", + "create.ponder.mechanical_arm.text_3": "UNLOCALIZED: Right-Click again to toggle between Input (Blue) and Output (Orange)", + "create.ponder.mechanical_arm.text_4": "UNLOCALIZED: Left-Click components to remove their Selection", + "create.ponder.mechanical_arm.text_5": "UNLOCALIZED: Once placed, the Mechanical Arm will target the blocks selected previously", + "create.ponder.mechanical_arm.text_6": "UNLOCALIZED: They can have any amount of in- and outputs within their range", + "create.ponder.mechanical_arm.text_7": "UNLOCALIZED: However, not every type of Inventory can be interacted with directly", + "create.ponder.mechanical_arm.text_8": "UNLOCALIZED: Funnels and Depots can help to Bridge that gap", + + "create.ponder.mechanical_arm_filtering.header": "UNLOCALIZED: Filtering Outputs of the Mechanical Arm", + "create.ponder.mechanical_arm_filtering.text_1": "UNLOCALIZED: Inputs", + "create.ponder.mechanical_arm_filtering.text_2": "UNLOCALIZED: Outputs", + "create.ponder.mechanical_arm_filtering.text_3": "UNLOCALIZED: Sometimes it is desirable to restrict targets of the Arm by matching a filter", + "create.ponder.mechanical_arm_filtering.text_4": "UNLOCALIZED: Mechanical Arms by themselves do not provide any options for filtering", + "create.ponder.mechanical_arm_filtering.text_5": "UNLOCALIZED: Brass Funnels as Targets do however communicate their own filter to the Arm", + "create.ponder.mechanical_arm_filtering.text_6": "UNLOCALIZED: The Arm is smart enough not to pick up items it couldn't distribute", + + "create.ponder.mechanical_arm_modes.header": "UNLOCALIZED: Distribution modes of the Mechanical Arm", + "create.ponder.mechanical_arm_modes.text_1": "UNLOCALIZED: Input", + "create.ponder.mechanical_arm_modes.text_2": "UNLOCALIZED: Outputs", + "create.ponder.mechanical_arm_modes.text_3": "UNLOCALIZED: Whenever an Arm has to choose between multiple valid outputs...", + "create.ponder.mechanical_arm_modes.text_4": "UNLOCALIZED: ...it will act according to its setting", + "create.ponder.mechanical_arm_modes.text_5": "UNLOCALIZED: Scrolling with a Wrench will allow you to configure it", + "create.ponder.mechanical_arm_modes.text_6": "UNLOCALIZED: Round Robin mode simply cycles through all outputs that are available", + "create.ponder.mechanical_arm_modes.text_7": "UNLOCALIZED: If an output is unable to take more items, it will be skipped", + "create.ponder.mechanical_arm_modes.text_8": "UNLOCALIZED: Forced Round Robin mode will never skip outputs, and instead wait until they are free", + "create.ponder.mechanical_arm_modes.text_9": "UNLOCALIZED: Prefer First prioritizes the outputs selected earliest when configuring this Arm", + + "create.ponder.mechanical_arm_redstone.header": "UNLOCALIZED: Controlling Mechanical Arms with Redstone", + "create.ponder.mechanical_arm_redstone.text_1": "UNLOCALIZED: When powered by Redstone, Mechanical Arms will not activate", + "create.ponder.mechanical_arm_redstone.text_2": "UNLOCALIZED: Before stopping, it will finish any started cycles", + "create.ponder.mechanical_arm_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.mechanical_bearing.header": "UNLOCALIZED: Movings Structures using the Mechanical Bearing", "create.ponder.mechanical_bearing.text_1": "UNLOCALIZED: Mechanical Bearings attach to the block in front of them", "create.ponder.mechanical_bearing.text_2": "UNLOCALIZED: Upon receiving Rotational Force, it will assemble it into a Rotating Contraption", + "create.ponder.mechanical_crafter.header": "UNLOCALIZED: Setting up Mechanical Crafters", + "create.ponder.mechanical_crafter.text_1": "UNLOCALIZED: An array of Mechanical Crafters can be used to automate any Crafting Recipe", + "create.ponder.mechanical_crafter.text_2": "UNLOCALIZED: Using a Wrench, the Crafters' paths can be arranged", + "create.ponder.mechanical_crafter.text_3": "UNLOCALIZED: For a valid setup, all paths have to converge into one exit at any side", + "create.ponder.mechanical_crafter.text_4": "UNLOCALIZED: The outputs will be placed into the inventory at the exit", + "create.ponder.mechanical_crafter.text_5": "UNLOCALIZED: Mechanical Crafters require Rotational Force to operate", + "create.ponder.mechanical_crafter.text_6": "UNLOCALIZED: Right-Click the front to insert Items manually", + "create.ponder.mechanical_crafter.text_7": "UNLOCALIZED: Once every slot of a path contains an Item, the crafting process will begin", + "create.ponder.mechanical_crafter.text_8": "UNLOCALIZED: For recipes not fully occupying the crafter setup, the start can be forced using a Redstone Pulse", + + "create.ponder.mechanical_crafter_connect.header": "UNLOCALIZED: Connecting Inventories of Crafters", + "create.ponder.mechanical_crafter_connect.text_1": "UNLOCALIZED: Items can be inserted to Crafters automatically", + "create.ponder.mechanical_crafter_connect.text_2": "UNLOCALIZED: Using the Wrench at their backs, Mechanical Crafter inputs can be combined", + "create.ponder.mechanical_crafter_connect.text_3": "UNLOCALIZED: All connected Crafters can now be accessed by the same input location", + + "create.ponder.mechanical_crafter_covers.header": "UNLOCALIZED: Covering slots of Mechanical Crafters", + "create.ponder.mechanical_crafter_covers.text_1": "UNLOCALIZED: Some recipes will require additional Crafters to bridge gaps in the path", + "create.ponder.mechanical_crafter_covers.text_2": "UNLOCALIZED: Using Slot Covers, Crafters can be set to act as an Empty Slot in the arrangement", + "create.ponder.mechanical_crafter_covers.text_3": "UNLOCALIZED: Shared Inputs created with the Wrench at the back can also reach across covered Crafters", + "create.ponder.mechanical_drill.header": "UNLOCALIZED: Breaking Blocks with the Mechanical Drill", "create.ponder.mechanical_drill.text_1": "UNLOCALIZED: When given Rotational Force, a Mechanical Drill will break blocks directly in front of it", "create.ponder.mechanical_drill.text_2": "UNLOCALIZED: Its mining speed depends on the Rotational Input", @@ -2298,6 +2361,16 @@ "create.ponder.rotation_speed_controller.text_1": "UNLOCALIZED: Rot. Speed Controllers relay rotation from their axis to a Large Cogwheel above them", "create.ponder.rotation_speed_controller.text_2": "UNLOCALIZED: Using the scroll input on its side, the conveyed speed can be configured", + "create.ponder.sail.header": "UNLOCALIZED: Assembling Windmills using Sails", + "create.ponder.sail.text_1": "UNLOCALIZED: Sails are handy blocks to create Windmills with", + "create.ponder.sail.text_2": "UNLOCALIZED: They will attach to blocks and each other without the need of Super Glue or Chassis Blocks", + "create.ponder.sail.text_3": "UNLOCALIZED: Right-Click with Dye to paint them", + "create.ponder.sail.text_4": "UNLOCALIZED: Right-Click with Shears to turn them back into frames", + + "create.ponder.sail_frame.header": "UNLOCALIZED: Assembling Windmills using Sail Frames", + "create.ponder.sail_frame.text_1": "UNLOCALIZED: Sail Frames are handy blocks to create Windmills with", + "create.ponder.sail_frame.text_2": "UNLOCALIZED: They will attach to blocks and each other without the need of Super Glue or Chassis Blocks", + "create.ponder.sequenced_gearshift.header": "UNLOCALIZED: Controlling Rotational Speed using Sequenced Gearshifts", "create.ponder.sequenced_gearshift.text_1": "UNLOCALIZED: Seq. Gearshifts relay rotation by following a timed list of instructions", "create.ponder.sequenced_gearshift.text_2": "UNLOCALIZED: Right-click it to open the Configuration UI", diff --git a/src/generated/resources/assets/create/lang/unfinished/fr_fr.json b/src/generated/resources/assets/create/lang/unfinished/fr_fr.json index 55a1d458a..0add5245a 100644 --- a/src/generated/resources/assets/create/lang/unfinished/fr_fr.json +++ b/src/generated/resources/assets/create/lang/unfinished/fr_fr.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1155", + "_": "Missing Localizations: 1218", "_": "->------------------------] Game Elements [------------------------<-", @@ -396,6 +396,7 @@ "block.create.weathered_limestone_cobblestone_stairs": "UNLOCALIZED: Weathered Limestone Cobblestone Stairs", "block.create.weathered_limestone_cobblestone_wall": "UNLOCALIZED: Weathered Limestone Cobblestone Wall", "block.create.weathered_limestone_pillar": "Pillier de Calcaire altéré", + "block.create.weighted_ejector": "UNLOCALIZED: Weighted Ejector", "block.create.white_sail": "UNLOCALIZED: White Sail", "block.create.white_seat": "UNLOCALIZED: White Seat", "block.create.white_valve_handle": "UNLOCALIZED: White Valve Handle", @@ -1084,6 +1085,12 @@ "create.mechanical_arm.summary": "UNLOCALIZED: Mechanical Arm has %1$s input(s) and %2$s output(s).", "create.mechanical_arm.points_outside_range": "UNLOCALIZED: %1$s selected interaction point(s) removed due to range limitations.", + "create.weighted_ejector.target_set": "UNLOCALIZED: Target Selected", + "create.weighted_ejector.target_not_valid": "UNLOCALIZED: Ejecting to Adjacent block (Target was not Valid)", + "create.weighted_ejector.no_target": "UNLOCALIZED: Ejecting to Adjacent block (No Target was Selected)", + "create.weighted_ejector.targeting": "UNLOCALIZED: Ejecting to [%1$s,%2$s,%3$s]", + "create.weighted_ejector.stack_size": "UNLOCALIZED: Ejected Stack Size", + "create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available", "create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: Round Robin", @@ -1838,22 +1845,24 @@ "create.ponder.tag.contraption_actor.description": "UNLOCALIZED: Components which expose special behaviour when attached to a moving contraption", "create.ponder.tag.arm_targets": "UNLOCALIZED: Targets for Mechanical Arms", "create.ponder.tag.arm_targets.description": "UNLOCALIZED: Components which can be selected as inputs or outputs to the Mechanical Arm", - "create.ponder.tag.contraption_assembly": "UNLOCALIZED: Block Attachment Utility", - "create.ponder.tag.contraption_assembly.description": "UNLOCALIZED: Tools and Components used to assemble structures moved as an animated Contraption", "create.ponder.tag.logistics": "UNLOCALIZED: Item Transportation", "create.ponder.tag.logistics.description": "UNLOCALIZED: Components which help moving items around", "create.ponder.tag.movement_anchor": "UNLOCALIZED: Movement Anchors", "create.ponder.tag.movement_anchor.description": "UNLOCALIZED: Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways", + "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", + "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", + "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", + "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", + "create.ponder.tag.windmill_sails": "UNLOCALIZED: Sails for Windmill Bearings", + "create.ponder.tag.windmill_sails.description": "UNLOCALIZED: Blocks that count towards the strength of a Windmill Contraption when assembled. Each of these have equal efficiency in doing so.", + "create.ponder.tag.contraption_assembly": "UNLOCALIZED: Block Attachment Utility", + "create.ponder.tag.contraption_assembly.description": "UNLOCALIZED: Tools and Components used to assemble structures moved as an animated Contraption", "create.ponder.tag.decoration": "UNLOCALIZED: Aesthetics", "create.ponder.tag.decoration.description": "UNLOCALIZED: Components used mostly for decorative purposes", "create.ponder.tag.kinetic_appliances": "UNLOCALIZED: Kinetic Appliances", "create.ponder.tag.kinetic_appliances.description": "UNLOCALIZED: Components which make use of Rotational Force", "create.ponder.tag.redstone": "UNLOCALIZED: Logic Components", "create.ponder.tag.redstone.description": "UNLOCALIZED: Components which help with redstone engineering", - "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", - "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", - "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", - "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", "create.ponder.tag.fluids": "UNLOCALIZED: Fluid Manipulators", "create.ponder.tag.fluids.description": "UNLOCALIZED: Components which help relaying and making use of Fluids", @@ -2155,10 +2164,64 @@ "create.ponder.linear_chassis_group.text_2": "UNLOCALIZED: When one is moved by a Contraption, the others are dragged with it", "create.ponder.linear_chassis_group.text_3": "UNLOCALIZED: Chassis of a different type or facing another direction will not attach", + "create.ponder.mechanical_arm.header": "UNLOCALIZED: Setting up Mechanical Arms", + "create.ponder.mechanical_arm.text_1": "UNLOCALIZED: Mechanical Arms have to be assigned their in- and outputs before they are placed", + "create.ponder.mechanical_arm.text_2": "UNLOCALIZED: Right-Click inventories while holding the Arm to assign them as Targets", + "create.ponder.mechanical_arm.text_3": "UNLOCALIZED: Right-Click again to toggle between Input (Blue) and Output (Orange)", + "create.ponder.mechanical_arm.text_4": "UNLOCALIZED: Left-Click components to remove their Selection", + "create.ponder.mechanical_arm.text_5": "UNLOCALIZED: Once placed, the Mechanical Arm will target the blocks selected previously", + "create.ponder.mechanical_arm.text_6": "UNLOCALIZED: They can have any amount of in- and outputs within their range", + "create.ponder.mechanical_arm.text_7": "UNLOCALIZED: However, not every type of Inventory can be interacted with directly", + "create.ponder.mechanical_arm.text_8": "UNLOCALIZED: Funnels and Depots can help to Bridge that gap", + + "create.ponder.mechanical_arm_filtering.header": "UNLOCALIZED: Filtering Outputs of the Mechanical Arm", + "create.ponder.mechanical_arm_filtering.text_1": "UNLOCALIZED: Inputs", + "create.ponder.mechanical_arm_filtering.text_2": "UNLOCALIZED: Outputs", + "create.ponder.mechanical_arm_filtering.text_3": "UNLOCALIZED: Sometimes it is desirable to restrict targets of the Arm by matching a filter", + "create.ponder.mechanical_arm_filtering.text_4": "UNLOCALIZED: Mechanical Arms by themselves do not provide any options for filtering", + "create.ponder.mechanical_arm_filtering.text_5": "UNLOCALIZED: Brass Funnels as Targets do however communicate their own filter to the Arm", + "create.ponder.mechanical_arm_filtering.text_6": "UNLOCALIZED: The Arm is smart enough not to pick up items it couldn't distribute", + + "create.ponder.mechanical_arm_modes.header": "UNLOCALIZED: Distribution modes of the Mechanical Arm", + "create.ponder.mechanical_arm_modes.text_1": "UNLOCALIZED: Input", + "create.ponder.mechanical_arm_modes.text_2": "UNLOCALIZED: Outputs", + "create.ponder.mechanical_arm_modes.text_3": "UNLOCALIZED: Whenever an Arm has to choose between multiple valid outputs...", + "create.ponder.mechanical_arm_modes.text_4": "UNLOCALIZED: ...it will act according to its setting", + "create.ponder.mechanical_arm_modes.text_5": "UNLOCALIZED: Scrolling with a Wrench will allow you to configure it", + "create.ponder.mechanical_arm_modes.text_6": "UNLOCALIZED: Round Robin mode simply cycles through all outputs that are available", + "create.ponder.mechanical_arm_modes.text_7": "UNLOCALIZED: If an output is unable to take more items, it will be skipped", + "create.ponder.mechanical_arm_modes.text_8": "UNLOCALIZED: Forced Round Robin mode will never skip outputs, and instead wait until they are free", + "create.ponder.mechanical_arm_modes.text_9": "UNLOCALIZED: Prefer First prioritizes the outputs selected earliest when configuring this Arm", + + "create.ponder.mechanical_arm_redstone.header": "UNLOCALIZED: Controlling Mechanical Arms with Redstone", + "create.ponder.mechanical_arm_redstone.text_1": "UNLOCALIZED: When powered by Redstone, Mechanical Arms will not activate", + "create.ponder.mechanical_arm_redstone.text_2": "UNLOCALIZED: Before stopping, it will finish any started cycles", + "create.ponder.mechanical_arm_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.mechanical_bearing.header": "UNLOCALIZED: Movings Structures using the Mechanical Bearing", "create.ponder.mechanical_bearing.text_1": "UNLOCALIZED: Mechanical Bearings attach to the block in front of them", "create.ponder.mechanical_bearing.text_2": "UNLOCALIZED: Upon receiving Rotational Force, it will assemble it into a Rotating Contraption", + "create.ponder.mechanical_crafter.header": "UNLOCALIZED: Setting up Mechanical Crafters", + "create.ponder.mechanical_crafter.text_1": "UNLOCALIZED: An array of Mechanical Crafters can be used to automate any Crafting Recipe", + "create.ponder.mechanical_crafter.text_2": "UNLOCALIZED: Using a Wrench, the Crafters' paths can be arranged", + "create.ponder.mechanical_crafter.text_3": "UNLOCALIZED: For a valid setup, all paths have to converge into one exit at any side", + "create.ponder.mechanical_crafter.text_4": "UNLOCALIZED: The outputs will be placed into the inventory at the exit", + "create.ponder.mechanical_crafter.text_5": "UNLOCALIZED: Mechanical Crafters require Rotational Force to operate", + "create.ponder.mechanical_crafter.text_6": "UNLOCALIZED: Right-Click the front to insert Items manually", + "create.ponder.mechanical_crafter.text_7": "UNLOCALIZED: Once every slot of a path contains an Item, the crafting process will begin", + "create.ponder.mechanical_crafter.text_8": "UNLOCALIZED: For recipes not fully occupying the crafter setup, the start can be forced using a Redstone Pulse", + + "create.ponder.mechanical_crafter_connect.header": "UNLOCALIZED: Connecting Inventories of Crafters", + "create.ponder.mechanical_crafter_connect.text_1": "UNLOCALIZED: Items can be inserted to Crafters automatically", + "create.ponder.mechanical_crafter_connect.text_2": "UNLOCALIZED: Using the Wrench at their backs, Mechanical Crafter inputs can be combined", + "create.ponder.mechanical_crafter_connect.text_3": "UNLOCALIZED: All connected Crafters can now be accessed by the same input location", + + "create.ponder.mechanical_crafter_covers.header": "UNLOCALIZED: Covering slots of Mechanical Crafters", + "create.ponder.mechanical_crafter_covers.text_1": "UNLOCALIZED: Some recipes will require additional Crafters to bridge gaps in the path", + "create.ponder.mechanical_crafter_covers.text_2": "UNLOCALIZED: Using Slot Covers, Crafters can be set to act as an Empty Slot in the arrangement", + "create.ponder.mechanical_crafter_covers.text_3": "UNLOCALIZED: Shared Inputs created with the Wrench at the back can also reach across covered Crafters", + "create.ponder.mechanical_drill.header": "UNLOCALIZED: Breaking Blocks with the Mechanical Drill", "create.ponder.mechanical_drill.text_1": "UNLOCALIZED: When given Rotational Force, a Mechanical Drill will break blocks directly in front of it", "create.ponder.mechanical_drill.text_2": "UNLOCALIZED: Its mining speed depends on the Rotational Input", @@ -2298,6 +2361,16 @@ "create.ponder.rotation_speed_controller.text_1": "UNLOCALIZED: Rot. Speed Controllers relay rotation from their axis to a Large Cogwheel above them", "create.ponder.rotation_speed_controller.text_2": "UNLOCALIZED: Using the scroll input on its side, the conveyed speed can be configured", + "create.ponder.sail.header": "UNLOCALIZED: Assembling Windmills using Sails", + "create.ponder.sail.text_1": "UNLOCALIZED: Sails are handy blocks to create Windmills with", + "create.ponder.sail.text_2": "UNLOCALIZED: They will attach to blocks and each other without the need of Super Glue or Chassis Blocks", + "create.ponder.sail.text_3": "UNLOCALIZED: Right-Click with Dye to paint them", + "create.ponder.sail.text_4": "UNLOCALIZED: Right-Click with Shears to turn them back into frames", + + "create.ponder.sail_frame.header": "UNLOCALIZED: Assembling Windmills using Sail Frames", + "create.ponder.sail_frame.text_1": "UNLOCALIZED: Sail Frames are handy blocks to create Windmills with", + "create.ponder.sail_frame.text_2": "UNLOCALIZED: They will attach to blocks and each other without the need of Super Glue or Chassis Blocks", + "create.ponder.sequenced_gearshift.header": "UNLOCALIZED: Controlling Rotational Speed using Sequenced Gearshifts", "create.ponder.sequenced_gearshift.text_1": "UNLOCALIZED: Seq. Gearshifts relay rotation by following a timed list of instructions", "create.ponder.sequenced_gearshift.text_2": "UNLOCALIZED: Right-click it to open the Configuration UI", diff --git a/src/generated/resources/assets/create/lang/unfinished/it_it.json b/src/generated/resources/assets/create/lang/unfinished/it_it.json index aad6e8ef3..321d024fc 100644 --- a/src/generated/resources/assets/create/lang/unfinished/it_it.json +++ b/src/generated/resources/assets/create/lang/unfinished/it_it.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 491", + "_": "Missing Localizations: 554", "_": "->------------------------] Game Elements [------------------------<-", @@ -396,6 +396,7 @@ "block.create.weathered_limestone_cobblestone_stairs": "Scalini di pietrisco di calcare consumato", "block.create.weathered_limestone_cobblestone_wall": "Muretto di pietrisco di calcare consumato", "block.create.weathered_limestone_pillar": "Pilastro di calcare consumato", + "block.create.weighted_ejector": "UNLOCALIZED: Weighted Ejector", "block.create.white_sail": "Vela bianca", "block.create.white_seat": "Sedile bianco", "block.create.white_valve_handle": "Maniglia per valvola bianca", @@ -1084,6 +1085,12 @@ "create.mechanical_arm.summary": "Il braccio meccanico ha %1$s input e %2$s output.", "create.mechanical_arm.points_outside_range": "%1$s punti di interazione selezionati rimossi per limiti di gamma.", + "create.weighted_ejector.target_set": "UNLOCALIZED: Target Selected", + "create.weighted_ejector.target_not_valid": "UNLOCALIZED: Ejecting to Adjacent block (Target was not Valid)", + "create.weighted_ejector.no_target": "UNLOCALIZED: Ejecting to Adjacent block (No Target was Selected)", + "create.weighted_ejector.targeting": "UNLOCALIZED: Ejecting to [%1$s,%2$s,%3$s]", + "create.weighted_ejector.stack_size": "UNLOCALIZED: Ejected Stack Size", + "create.logistics.when_multiple_outputs_available": "Quando disponibili diversi output", "create.mechanical_arm.selection_mode.round_robin": "Round Robin", @@ -1838,22 +1845,24 @@ "create.ponder.tag.contraption_actor.description": "UNLOCALIZED: Components which expose special behaviour when attached to a moving contraption", "create.ponder.tag.arm_targets": "UNLOCALIZED: Targets for Mechanical Arms", "create.ponder.tag.arm_targets.description": "UNLOCALIZED: Components which can be selected as inputs or outputs to the Mechanical Arm", - "create.ponder.tag.contraption_assembly": "UNLOCALIZED: Block Attachment Utility", - "create.ponder.tag.contraption_assembly.description": "UNLOCALIZED: Tools and Components used to assemble structures moved as an animated Contraption", "create.ponder.tag.logistics": "UNLOCALIZED: Item Transportation", "create.ponder.tag.logistics.description": "UNLOCALIZED: Components which help moving items around", "create.ponder.tag.movement_anchor": "UNLOCALIZED: Movement Anchors", "create.ponder.tag.movement_anchor.description": "UNLOCALIZED: Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways", + "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", + "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", + "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", + "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", + "create.ponder.tag.windmill_sails": "UNLOCALIZED: Sails for Windmill Bearings", + "create.ponder.tag.windmill_sails.description": "UNLOCALIZED: Blocks that count towards the strength of a Windmill Contraption when assembled. Each of these have equal efficiency in doing so.", + "create.ponder.tag.contraption_assembly": "UNLOCALIZED: Block Attachment Utility", + "create.ponder.tag.contraption_assembly.description": "UNLOCALIZED: Tools and Components used to assemble structures moved as an animated Contraption", "create.ponder.tag.decoration": "UNLOCALIZED: Aesthetics", "create.ponder.tag.decoration.description": "UNLOCALIZED: Components used mostly for decorative purposes", "create.ponder.tag.kinetic_appliances": "UNLOCALIZED: Kinetic Appliances", "create.ponder.tag.kinetic_appliances.description": "UNLOCALIZED: Components which make use of Rotational Force", "create.ponder.tag.redstone": "UNLOCALIZED: Logic Components", "create.ponder.tag.redstone.description": "UNLOCALIZED: Components which help with redstone engineering", - "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", - "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", - "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", - "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", "create.ponder.tag.fluids": "UNLOCALIZED: Fluid Manipulators", "create.ponder.tag.fluids.description": "UNLOCALIZED: Components which help relaying and making use of Fluids", @@ -2155,10 +2164,64 @@ "create.ponder.linear_chassis_group.text_2": "UNLOCALIZED: When one is moved by a Contraption, the others are dragged with it", "create.ponder.linear_chassis_group.text_3": "UNLOCALIZED: Chassis of a different type or facing another direction will not attach", + "create.ponder.mechanical_arm.header": "UNLOCALIZED: Setting up Mechanical Arms", + "create.ponder.mechanical_arm.text_1": "UNLOCALIZED: Mechanical Arms have to be assigned their in- and outputs before they are placed", + "create.ponder.mechanical_arm.text_2": "UNLOCALIZED: Right-Click inventories while holding the Arm to assign them as Targets", + "create.ponder.mechanical_arm.text_3": "UNLOCALIZED: Right-Click again to toggle between Input (Blue) and Output (Orange)", + "create.ponder.mechanical_arm.text_4": "UNLOCALIZED: Left-Click components to remove their Selection", + "create.ponder.mechanical_arm.text_5": "UNLOCALIZED: Once placed, the Mechanical Arm will target the blocks selected previously", + "create.ponder.mechanical_arm.text_6": "UNLOCALIZED: They can have any amount of in- and outputs within their range", + "create.ponder.mechanical_arm.text_7": "UNLOCALIZED: However, not every type of Inventory can be interacted with directly", + "create.ponder.mechanical_arm.text_8": "UNLOCALIZED: Funnels and Depots can help to Bridge that gap", + + "create.ponder.mechanical_arm_filtering.header": "UNLOCALIZED: Filtering Outputs of the Mechanical Arm", + "create.ponder.mechanical_arm_filtering.text_1": "UNLOCALIZED: Inputs", + "create.ponder.mechanical_arm_filtering.text_2": "UNLOCALIZED: Outputs", + "create.ponder.mechanical_arm_filtering.text_3": "UNLOCALIZED: Sometimes it is desirable to restrict targets of the Arm by matching a filter", + "create.ponder.mechanical_arm_filtering.text_4": "UNLOCALIZED: Mechanical Arms by themselves do not provide any options for filtering", + "create.ponder.mechanical_arm_filtering.text_5": "UNLOCALIZED: Brass Funnels as Targets do however communicate their own filter to the Arm", + "create.ponder.mechanical_arm_filtering.text_6": "UNLOCALIZED: The Arm is smart enough not to pick up items it couldn't distribute", + + "create.ponder.mechanical_arm_modes.header": "UNLOCALIZED: Distribution modes of the Mechanical Arm", + "create.ponder.mechanical_arm_modes.text_1": "UNLOCALIZED: Input", + "create.ponder.mechanical_arm_modes.text_2": "UNLOCALIZED: Outputs", + "create.ponder.mechanical_arm_modes.text_3": "UNLOCALIZED: Whenever an Arm has to choose between multiple valid outputs...", + "create.ponder.mechanical_arm_modes.text_4": "UNLOCALIZED: ...it will act according to its setting", + "create.ponder.mechanical_arm_modes.text_5": "UNLOCALIZED: Scrolling with a Wrench will allow you to configure it", + "create.ponder.mechanical_arm_modes.text_6": "UNLOCALIZED: Round Robin mode simply cycles through all outputs that are available", + "create.ponder.mechanical_arm_modes.text_7": "UNLOCALIZED: If an output is unable to take more items, it will be skipped", + "create.ponder.mechanical_arm_modes.text_8": "UNLOCALIZED: Forced Round Robin mode will never skip outputs, and instead wait until they are free", + "create.ponder.mechanical_arm_modes.text_9": "UNLOCALIZED: Prefer First prioritizes the outputs selected earliest when configuring this Arm", + + "create.ponder.mechanical_arm_redstone.header": "UNLOCALIZED: Controlling Mechanical Arms with Redstone", + "create.ponder.mechanical_arm_redstone.text_1": "UNLOCALIZED: When powered by Redstone, Mechanical Arms will not activate", + "create.ponder.mechanical_arm_redstone.text_2": "UNLOCALIZED: Before stopping, it will finish any started cycles", + "create.ponder.mechanical_arm_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.mechanical_bearing.header": "UNLOCALIZED: Movings Structures using the Mechanical Bearing", "create.ponder.mechanical_bearing.text_1": "UNLOCALIZED: Mechanical Bearings attach to the block in front of them", "create.ponder.mechanical_bearing.text_2": "UNLOCALIZED: Upon receiving Rotational Force, it will assemble it into a Rotating Contraption", + "create.ponder.mechanical_crafter.header": "UNLOCALIZED: Setting up Mechanical Crafters", + "create.ponder.mechanical_crafter.text_1": "UNLOCALIZED: An array of Mechanical Crafters can be used to automate any Crafting Recipe", + "create.ponder.mechanical_crafter.text_2": "UNLOCALIZED: Using a Wrench, the Crafters' paths can be arranged", + "create.ponder.mechanical_crafter.text_3": "UNLOCALIZED: For a valid setup, all paths have to converge into one exit at any side", + "create.ponder.mechanical_crafter.text_4": "UNLOCALIZED: The outputs will be placed into the inventory at the exit", + "create.ponder.mechanical_crafter.text_5": "UNLOCALIZED: Mechanical Crafters require Rotational Force to operate", + "create.ponder.mechanical_crafter.text_6": "UNLOCALIZED: Right-Click the front to insert Items manually", + "create.ponder.mechanical_crafter.text_7": "UNLOCALIZED: Once every slot of a path contains an Item, the crafting process will begin", + "create.ponder.mechanical_crafter.text_8": "UNLOCALIZED: For recipes not fully occupying the crafter setup, the start can be forced using a Redstone Pulse", + + "create.ponder.mechanical_crafter_connect.header": "UNLOCALIZED: Connecting Inventories of Crafters", + "create.ponder.mechanical_crafter_connect.text_1": "UNLOCALIZED: Items can be inserted to Crafters automatically", + "create.ponder.mechanical_crafter_connect.text_2": "UNLOCALIZED: Using the Wrench at their backs, Mechanical Crafter inputs can be combined", + "create.ponder.mechanical_crafter_connect.text_3": "UNLOCALIZED: All connected Crafters can now be accessed by the same input location", + + "create.ponder.mechanical_crafter_covers.header": "UNLOCALIZED: Covering slots of Mechanical Crafters", + "create.ponder.mechanical_crafter_covers.text_1": "UNLOCALIZED: Some recipes will require additional Crafters to bridge gaps in the path", + "create.ponder.mechanical_crafter_covers.text_2": "UNLOCALIZED: Using Slot Covers, Crafters can be set to act as an Empty Slot in the arrangement", + "create.ponder.mechanical_crafter_covers.text_3": "UNLOCALIZED: Shared Inputs created with the Wrench at the back can also reach across covered Crafters", + "create.ponder.mechanical_drill.header": "UNLOCALIZED: Breaking Blocks with the Mechanical Drill", "create.ponder.mechanical_drill.text_1": "UNLOCALIZED: When given Rotational Force, a Mechanical Drill will break blocks directly in front of it", "create.ponder.mechanical_drill.text_2": "UNLOCALIZED: Its mining speed depends on the Rotational Input", @@ -2298,6 +2361,16 @@ "create.ponder.rotation_speed_controller.text_1": "UNLOCALIZED: Rot. Speed Controllers relay rotation from their axis to a Large Cogwheel above them", "create.ponder.rotation_speed_controller.text_2": "UNLOCALIZED: Using the scroll input on its side, the conveyed speed can be configured", + "create.ponder.sail.header": "UNLOCALIZED: Assembling Windmills using Sails", + "create.ponder.sail.text_1": "UNLOCALIZED: Sails are handy blocks to create Windmills with", + "create.ponder.sail.text_2": "UNLOCALIZED: They will attach to blocks and each other without the need of Super Glue or Chassis Blocks", + "create.ponder.sail.text_3": "UNLOCALIZED: Right-Click with Dye to paint them", + "create.ponder.sail.text_4": "UNLOCALIZED: Right-Click with Shears to turn them back into frames", + + "create.ponder.sail_frame.header": "UNLOCALIZED: Assembling Windmills using Sail Frames", + "create.ponder.sail_frame.text_1": "UNLOCALIZED: Sail Frames are handy blocks to create Windmills with", + "create.ponder.sail_frame.text_2": "UNLOCALIZED: They will attach to blocks and each other without the need of Super Glue or Chassis Blocks", + "create.ponder.sequenced_gearshift.header": "UNLOCALIZED: Controlling Rotational Speed using Sequenced Gearshifts", "create.ponder.sequenced_gearshift.text_1": "UNLOCALIZED: Seq. Gearshifts relay rotation by following a timed list of instructions", "create.ponder.sequenced_gearshift.text_2": "UNLOCALIZED: Right-click it to open the Configuration UI", diff --git a/src/generated/resources/assets/create/lang/unfinished/ja_jp.json b/src/generated/resources/assets/create/lang/unfinished/ja_jp.json index 47b38141f..5b64d94c6 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ja_jp.json +++ b/src/generated/resources/assets/create/lang/unfinished/ja_jp.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 498", + "_": "Missing Localizations: 561", "_": "->------------------------] Game Elements [------------------------<-", @@ -396,6 +396,7 @@ "block.create.weathered_limestone_cobblestone_stairs": "風化した石灰岩の丸石の階段", "block.create.weathered_limestone_cobblestone_wall": "風化した石灰岩の丸石の壁", "block.create.weathered_limestone_pillar": "風化した石灰岩の柱", + "block.create.weighted_ejector": "UNLOCALIZED: Weighted Ejector", "block.create.white_sail": "白色の帆", "block.create.white_seat": "白色のシート", "block.create.white_valve_handle": "白色のバルブハンドル", @@ -1084,6 +1085,12 @@ "create.mechanical_arm.summary": "メカニカルアームは%1$s個の搬入ブロックと%2$s個の搬出ブロックを持っています。", "create.mechanical_arm.points_outside_range": "%1$s個の選択ブロックが射程限界のため、除外されました。", + "create.weighted_ejector.target_set": "UNLOCALIZED: Target Selected", + "create.weighted_ejector.target_not_valid": "UNLOCALIZED: Ejecting to Adjacent block (Target was not Valid)", + "create.weighted_ejector.no_target": "UNLOCALIZED: Ejecting to Adjacent block (No Target was Selected)", + "create.weighted_ejector.targeting": "UNLOCALIZED: Ejecting to [%1$s,%2$s,%3$s]", + "create.weighted_ejector.stack_size": "UNLOCALIZED: Ejected Stack Size", + "create.logistics.when_multiple_outputs_available": "複数の出力が利用可能なとき:", "create.mechanical_arm.selection_mode.round_robin": "順繰り分配", @@ -1838,22 +1845,24 @@ "create.ponder.tag.contraption_actor.description": "UNLOCALIZED: Components which expose special behaviour when attached to a moving contraption", "create.ponder.tag.arm_targets": "UNLOCALIZED: Targets for Mechanical Arms", "create.ponder.tag.arm_targets.description": "UNLOCALIZED: Components which can be selected as inputs or outputs to the Mechanical Arm", - "create.ponder.tag.contraption_assembly": "UNLOCALIZED: Block Attachment Utility", - "create.ponder.tag.contraption_assembly.description": "UNLOCALIZED: Tools and Components used to assemble structures moved as an animated Contraption", "create.ponder.tag.logistics": "UNLOCALIZED: Item Transportation", "create.ponder.tag.logistics.description": "UNLOCALIZED: Components which help moving items around", "create.ponder.tag.movement_anchor": "UNLOCALIZED: Movement Anchors", "create.ponder.tag.movement_anchor.description": "UNLOCALIZED: Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways", + "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", + "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", + "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", + "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", + "create.ponder.tag.windmill_sails": "UNLOCALIZED: Sails for Windmill Bearings", + "create.ponder.tag.windmill_sails.description": "UNLOCALIZED: Blocks that count towards the strength of a Windmill Contraption when assembled. Each of these have equal efficiency in doing so.", + "create.ponder.tag.contraption_assembly": "UNLOCALIZED: Block Attachment Utility", + "create.ponder.tag.contraption_assembly.description": "UNLOCALIZED: Tools and Components used to assemble structures moved as an animated Contraption", "create.ponder.tag.decoration": "UNLOCALIZED: Aesthetics", "create.ponder.tag.decoration.description": "UNLOCALIZED: Components used mostly for decorative purposes", "create.ponder.tag.kinetic_appliances": "UNLOCALIZED: Kinetic Appliances", "create.ponder.tag.kinetic_appliances.description": "UNLOCALIZED: Components which make use of Rotational Force", "create.ponder.tag.redstone": "UNLOCALIZED: Logic Components", "create.ponder.tag.redstone.description": "UNLOCALIZED: Components which help with redstone engineering", - "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", - "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", - "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", - "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", "create.ponder.tag.fluids": "UNLOCALIZED: Fluid Manipulators", "create.ponder.tag.fluids.description": "UNLOCALIZED: Components which help relaying and making use of Fluids", @@ -2155,10 +2164,64 @@ "create.ponder.linear_chassis_group.text_2": "UNLOCALIZED: When one is moved by a Contraption, the others are dragged with it", "create.ponder.linear_chassis_group.text_3": "UNLOCALIZED: Chassis of a different type or facing another direction will not attach", + "create.ponder.mechanical_arm.header": "UNLOCALIZED: Setting up Mechanical Arms", + "create.ponder.mechanical_arm.text_1": "UNLOCALIZED: Mechanical Arms have to be assigned their in- and outputs before they are placed", + "create.ponder.mechanical_arm.text_2": "UNLOCALIZED: Right-Click inventories while holding the Arm to assign them as Targets", + "create.ponder.mechanical_arm.text_3": "UNLOCALIZED: Right-Click again to toggle between Input (Blue) and Output (Orange)", + "create.ponder.mechanical_arm.text_4": "UNLOCALIZED: Left-Click components to remove their Selection", + "create.ponder.mechanical_arm.text_5": "UNLOCALIZED: Once placed, the Mechanical Arm will target the blocks selected previously", + "create.ponder.mechanical_arm.text_6": "UNLOCALIZED: They can have any amount of in- and outputs within their range", + "create.ponder.mechanical_arm.text_7": "UNLOCALIZED: However, not every type of Inventory can be interacted with directly", + "create.ponder.mechanical_arm.text_8": "UNLOCALIZED: Funnels and Depots can help to Bridge that gap", + + "create.ponder.mechanical_arm_filtering.header": "UNLOCALIZED: Filtering Outputs of the Mechanical Arm", + "create.ponder.mechanical_arm_filtering.text_1": "UNLOCALIZED: Inputs", + "create.ponder.mechanical_arm_filtering.text_2": "UNLOCALIZED: Outputs", + "create.ponder.mechanical_arm_filtering.text_3": "UNLOCALIZED: Sometimes it is desirable to restrict targets of the Arm by matching a filter", + "create.ponder.mechanical_arm_filtering.text_4": "UNLOCALIZED: Mechanical Arms by themselves do not provide any options for filtering", + "create.ponder.mechanical_arm_filtering.text_5": "UNLOCALIZED: Brass Funnels as Targets do however communicate their own filter to the Arm", + "create.ponder.mechanical_arm_filtering.text_6": "UNLOCALIZED: The Arm is smart enough not to pick up items it couldn't distribute", + + "create.ponder.mechanical_arm_modes.header": "UNLOCALIZED: Distribution modes of the Mechanical Arm", + "create.ponder.mechanical_arm_modes.text_1": "UNLOCALIZED: Input", + "create.ponder.mechanical_arm_modes.text_2": "UNLOCALIZED: Outputs", + "create.ponder.mechanical_arm_modes.text_3": "UNLOCALIZED: Whenever an Arm has to choose between multiple valid outputs...", + "create.ponder.mechanical_arm_modes.text_4": "UNLOCALIZED: ...it will act according to its setting", + "create.ponder.mechanical_arm_modes.text_5": "UNLOCALIZED: Scrolling with a Wrench will allow you to configure it", + "create.ponder.mechanical_arm_modes.text_6": "UNLOCALIZED: Round Robin mode simply cycles through all outputs that are available", + "create.ponder.mechanical_arm_modes.text_7": "UNLOCALIZED: If an output is unable to take more items, it will be skipped", + "create.ponder.mechanical_arm_modes.text_8": "UNLOCALIZED: Forced Round Robin mode will never skip outputs, and instead wait until they are free", + "create.ponder.mechanical_arm_modes.text_9": "UNLOCALIZED: Prefer First prioritizes the outputs selected earliest when configuring this Arm", + + "create.ponder.mechanical_arm_redstone.header": "UNLOCALIZED: Controlling Mechanical Arms with Redstone", + "create.ponder.mechanical_arm_redstone.text_1": "UNLOCALIZED: When powered by Redstone, Mechanical Arms will not activate", + "create.ponder.mechanical_arm_redstone.text_2": "UNLOCALIZED: Before stopping, it will finish any started cycles", + "create.ponder.mechanical_arm_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.mechanical_bearing.header": "UNLOCALIZED: Movings Structures using the Mechanical Bearing", "create.ponder.mechanical_bearing.text_1": "UNLOCALIZED: Mechanical Bearings attach to the block in front of them", "create.ponder.mechanical_bearing.text_2": "UNLOCALIZED: Upon receiving Rotational Force, it will assemble it into a Rotating Contraption", + "create.ponder.mechanical_crafter.header": "UNLOCALIZED: Setting up Mechanical Crafters", + "create.ponder.mechanical_crafter.text_1": "UNLOCALIZED: An array of Mechanical Crafters can be used to automate any Crafting Recipe", + "create.ponder.mechanical_crafter.text_2": "UNLOCALIZED: Using a Wrench, the Crafters' paths can be arranged", + "create.ponder.mechanical_crafter.text_3": "UNLOCALIZED: For a valid setup, all paths have to converge into one exit at any side", + "create.ponder.mechanical_crafter.text_4": "UNLOCALIZED: The outputs will be placed into the inventory at the exit", + "create.ponder.mechanical_crafter.text_5": "UNLOCALIZED: Mechanical Crafters require Rotational Force to operate", + "create.ponder.mechanical_crafter.text_6": "UNLOCALIZED: Right-Click the front to insert Items manually", + "create.ponder.mechanical_crafter.text_7": "UNLOCALIZED: Once every slot of a path contains an Item, the crafting process will begin", + "create.ponder.mechanical_crafter.text_8": "UNLOCALIZED: For recipes not fully occupying the crafter setup, the start can be forced using a Redstone Pulse", + + "create.ponder.mechanical_crafter_connect.header": "UNLOCALIZED: Connecting Inventories of Crafters", + "create.ponder.mechanical_crafter_connect.text_1": "UNLOCALIZED: Items can be inserted to Crafters automatically", + "create.ponder.mechanical_crafter_connect.text_2": "UNLOCALIZED: Using the Wrench at their backs, Mechanical Crafter inputs can be combined", + "create.ponder.mechanical_crafter_connect.text_3": "UNLOCALIZED: All connected Crafters can now be accessed by the same input location", + + "create.ponder.mechanical_crafter_covers.header": "UNLOCALIZED: Covering slots of Mechanical Crafters", + "create.ponder.mechanical_crafter_covers.text_1": "UNLOCALIZED: Some recipes will require additional Crafters to bridge gaps in the path", + "create.ponder.mechanical_crafter_covers.text_2": "UNLOCALIZED: Using Slot Covers, Crafters can be set to act as an Empty Slot in the arrangement", + "create.ponder.mechanical_crafter_covers.text_3": "UNLOCALIZED: Shared Inputs created with the Wrench at the back can also reach across covered Crafters", + "create.ponder.mechanical_drill.header": "UNLOCALIZED: Breaking Blocks with the Mechanical Drill", "create.ponder.mechanical_drill.text_1": "UNLOCALIZED: When given Rotational Force, a Mechanical Drill will break blocks directly in front of it", "create.ponder.mechanical_drill.text_2": "UNLOCALIZED: Its mining speed depends on the Rotational Input", @@ -2298,6 +2361,16 @@ "create.ponder.rotation_speed_controller.text_1": "UNLOCALIZED: Rot. Speed Controllers relay rotation from their axis to a Large Cogwheel above them", "create.ponder.rotation_speed_controller.text_2": "UNLOCALIZED: Using the scroll input on its side, the conveyed speed can be configured", + "create.ponder.sail.header": "UNLOCALIZED: Assembling Windmills using Sails", + "create.ponder.sail.text_1": "UNLOCALIZED: Sails are handy blocks to create Windmills with", + "create.ponder.sail.text_2": "UNLOCALIZED: They will attach to blocks and each other without the need of Super Glue or Chassis Blocks", + "create.ponder.sail.text_3": "UNLOCALIZED: Right-Click with Dye to paint them", + "create.ponder.sail.text_4": "UNLOCALIZED: Right-Click with Shears to turn them back into frames", + + "create.ponder.sail_frame.header": "UNLOCALIZED: Assembling Windmills using Sail Frames", + "create.ponder.sail_frame.text_1": "UNLOCALIZED: Sail Frames are handy blocks to create Windmills with", + "create.ponder.sail_frame.text_2": "UNLOCALIZED: They will attach to blocks and each other without the need of Super Glue or Chassis Blocks", + "create.ponder.sequenced_gearshift.header": "UNLOCALIZED: Controlling Rotational Speed using Sequenced Gearshifts", "create.ponder.sequenced_gearshift.text_1": "UNLOCALIZED: Seq. Gearshifts relay rotation by following a timed list of instructions", "create.ponder.sequenced_gearshift.text_2": "UNLOCALIZED: Right-click it to open the Configuration UI", diff --git a/src/generated/resources/assets/create/lang/unfinished/ko_kr.json b/src/generated/resources/assets/create/lang/unfinished/ko_kr.json index 92968da8a..b0845cb27 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ko_kr.json +++ b/src/generated/resources/assets/create/lang/unfinished/ko_kr.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 544", + "_": "Missing Localizations: 607", "_": "->------------------------] Game Elements [------------------------<-", @@ -396,6 +396,7 @@ "block.create.weathered_limestone_cobblestone_stairs": "풍화된 석회암 조약돌 계단", "block.create.weathered_limestone_cobblestone_wall": "풍화된 석회암 조약돌 담장", "block.create.weathered_limestone_pillar": "풍화된 석회암 기둥", + "block.create.weighted_ejector": "UNLOCALIZED: Weighted Ejector", "block.create.white_sail": "하얀색 날개", "block.create.white_seat": "하얀색 좌석", "block.create.white_valve_handle": "하얀색 밸브 손잡이", @@ -1084,6 +1085,12 @@ "create.mechanical_arm.summary": "이 기계 팔은 %1$s개의 입력부와 %2$s개의 출력부를 가졌습니다.", "create.mechanical_arm.points_outside_range": "%1$s개의 상호작용 포인트가 거리제한으로 인해 삭제되었습니다.", + "create.weighted_ejector.target_set": "UNLOCALIZED: Target Selected", + "create.weighted_ejector.target_not_valid": "UNLOCALIZED: Ejecting to Adjacent block (Target was not Valid)", + "create.weighted_ejector.no_target": "UNLOCALIZED: Ejecting to Adjacent block (No Target was Selected)", + "create.weighted_ejector.targeting": "UNLOCALIZED: Ejecting to [%1$s,%2$s,%3$s]", + "create.weighted_ejector.stack_size": "UNLOCALIZED: Ejected Stack Size", + "create.logistics.when_multiple_outputs_available": "다수의 입력부가 존재할 때", "create.mechanical_arm.selection_mode.round_robin": "순서대로 옮김", @@ -1838,22 +1845,24 @@ "create.ponder.tag.contraption_actor.description": "UNLOCALIZED: Components which expose special behaviour when attached to a moving contraption", "create.ponder.tag.arm_targets": "UNLOCALIZED: Targets for Mechanical Arms", "create.ponder.tag.arm_targets.description": "UNLOCALIZED: Components which can be selected as inputs or outputs to the Mechanical Arm", - "create.ponder.tag.contraption_assembly": "UNLOCALIZED: Block Attachment Utility", - "create.ponder.tag.contraption_assembly.description": "UNLOCALIZED: Tools and Components used to assemble structures moved as an animated Contraption", "create.ponder.tag.logistics": "UNLOCALIZED: Item Transportation", "create.ponder.tag.logistics.description": "UNLOCALIZED: Components which help moving items around", "create.ponder.tag.movement_anchor": "UNLOCALIZED: Movement Anchors", "create.ponder.tag.movement_anchor.description": "UNLOCALIZED: Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways", + "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", + "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", + "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", + "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", + "create.ponder.tag.windmill_sails": "UNLOCALIZED: Sails for Windmill Bearings", + "create.ponder.tag.windmill_sails.description": "UNLOCALIZED: Blocks that count towards the strength of a Windmill Contraption when assembled. Each of these have equal efficiency in doing so.", + "create.ponder.tag.contraption_assembly": "UNLOCALIZED: Block Attachment Utility", + "create.ponder.tag.contraption_assembly.description": "UNLOCALIZED: Tools and Components used to assemble structures moved as an animated Contraption", "create.ponder.tag.decoration": "UNLOCALIZED: Aesthetics", "create.ponder.tag.decoration.description": "UNLOCALIZED: Components used mostly for decorative purposes", "create.ponder.tag.kinetic_appliances": "UNLOCALIZED: Kinetic Appliances", "create.ponder.tag.kinetic_appliances.description": "UNLOCALIZED: Components which make use of Rotational Force", "create.ponder.tag.redstone": "UNLOCALIZED: Logic Components", "create.ponder.tag.redstone.description": "UNLOCALIZED: Components which help with redstone engineering", - "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", - "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", - "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", - "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", "create.ponder.tag.fluids": "UNLOCALIZED: Fluid Manipulators", "create.ponder.tag.fluids.description": "UNLOCALIZED: Components which help relaying and making use of Fluids", @@ -2155,10 +2164,64 @@ "create.ponder.linear_chassis_group.text_2": "UNLOCALIZED: When one is moved by a Contraption, the others are dragged with it", "create.ponder.linear_chassis_group.text_3": "UNLOCALIZED: Chassis of a different type or facing another direction will not attach", + "create.ponder.mechanical_arm.header": "UNLOCALIZED: Setting up Mechanical Arms", + "create.ponder.mechanical_arm.text_1": "UNLOCALIZED: Mechanical Arms have to be assigned their in- and outputs before they are placed", + "create.ponder.mechanical_arm.text_2": "UNLOCALIZED: Right-Click inventories while holding the Arm to assign them as Targets", + "create.ponder.mechanical_arm.text_3": "UNLOCALIZED: Right-Click again to toggle between Input (Blue) and Output (Orange)", + "create.ponder.mechanical_arm.text_4": "UNLOCALIZED: Left-Click components to remove their Selection", + "create.ponder.mechanical_arm.text_5": "UNLOCALIZED: Once placed, the Mechanical Arm will target the blocks selected previously", + "create.ponder.mechanical_arm.text_6": "UNLOCALIZED: They can have any amount of in- and outputs within their range", + "create.ponder.mechanical_arm.text_7": "UNLOCALIZED: However, not every type of Inventory can be interacted with directly", + "create.ponder.mechanical_arm.text_8": "UNLOCALIZED: Funnels and Depots can help to Bridge that gap", + + "create.ponder.mechanical_arm_filtering.header": "UNLOCALIZED: Filtering Outputs of the Mechanical Arm", + "create.ponder.mechanical_arm_filtering.text_1": "UNLOCALIZED: Inputs", + "create.ponder.mechanical_arm_filtering.text_2": "UNLOCALIZED: Outputs", + "create.ponder.mechanical_arm_filtering.text_3": "UNLOCALIZED: Sometimes it is desirable to restrict targets of the Arm by matching a filter", + "create.ponder.mechanical_arm_filtering.text_4": "UNLOCALIZED: Mechanical Arms by themselves do not provide any options for filtering", + "create.ponder.mechanical_arm_filtering.text_5": "UNLOCALIZED: Brass Funnels as Targets do however communicate their own filter to the Arm", + "create.ponder.mechanical_arm_filtering.text_6": "UNLOCALIZED: The Arm is smart enough not to pick up items it couldn't distribute", + + "create.ponder.mechanical_arm_modes.header": "UNLOCALIZED: Distribution modes of the Mechanical Arm", + "create.ponder.mechanical_arm_modes.text_1": "UNLOCALIZED: Input", + "create.ponder.mechanical_arm_modes.text_2": "UNLOCALIZED: Outputs", + "create.ponder.mechanical_arm_modes.text_3": "UNLOCALIZED: Whenever an Arm has to choose between multiple valid outputs...", + "create.ponder.mechanical_arm_modes.text_4": "UNLOCALIZED: ...it will act according to its setting", + "create.ponder.mechanical_arm_modes.text_5": "UNLOCALIZED: Scrolling with a Wrench will allow you to configure it", + "create.ponder.mechanical_arm_modes.text_6": "UNLOCALIZED: Round Robin mode simply cycles through all outputs that are available", + "create.ponder.mechanical_arm_modes.text_7": "UNLOCALIZED: If an output is unable to take more items, it will be skipped", + "create.ponder.mechanical_arm_modes.text_8": "UNLOCALIZED: Forced Round Robin mode will never skip outputs, and instead wait until they are free", + "create.ponder.mechanical_arm_modes.text_9": "UNLOCALIZED: Prefer First prioritizes the outputs selected earliest when configuring this Arm", + + "create.ponder.mechanical_arm_redstone.header": "UNLOCALIZED: Controlling Mechanical Arms with Redstone", + "create.ponder.mechanical_arm_redstone.text_1": "UNLOCALIZED: When powered by Redstone, Mechanical Arms will not activate", + "create.ponder.mechanical_arm_redstone.text_2": "UNLOCALIZED: Before stopping, it will finish any started cycles", + "create.ponder.mechanical_arm_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.mechanical_bearing.header": "UNLOCALIZED: Movings Structures using the Mechanical Bearing", "create.ponder.mechanical_bearing.text_1": "UNLOCALIZED: Mechanical Bearings attach to the block in front of them", "create.ponder.mechanical_bearing.text_2": "UNLOCALIZED: Upon receiving Rotational Force, it will assemble it into a Rotating Contraption", + "create.ponder.mechanical_crafter.header": "UNLOCALIZED: Setting up Mechanical Crafters", + "create.ponder.mechanical_crafter.text_1": "UNLOCALIZED: An array of Mechanical Crafters can be used to automate any Crafting Recipe", + "create.ponder.mechanical_crafter.text_2": "UNLOCALIZED: Using a Wrench, the Crafters' paths can be arranged", + "create.ponder.mechanical_crafter.text_3": "UNLOCALIZED: For a valid setup, all paths have to converge into one exit at any side", + "create.ponder.mechanical_crafter.text_4": "UNLOCALIZED: The outputs will be placed into the inventory at the exit", + "create.ponder.mechanical_crafter.text_5": "UNLOCALIZED: Mechanical Crafters require Rotational Force to operate", + "create.ponder.mechanical_crafter.text_6": "UNLOCALIZED: Right-Click the front to insert Items manually", + "create.ponder.mechanical_crafter.text_7": "UNLOCALIZED: Once every slot of a path contains an Item, the crafting process will begin", + "create.ponder.mechanical_crafter.text_8": "UNLOCALIZED: For recipes not fully occupying the crafter setup, the start can be forced using a Redstone Pulse", + + "create.ponder.mechanical_crafter_connect.header": "UNLOCALIZED: Connecting Inventories of Crafters", + "create.ponder.mechanical_crafter_connect.text_1": "UNLOCALIZED: Items can be inserted to Crafters automatically", + "create.ponder.mechanical_crafter_connect.text_2": "UNLOCALIZED: Using the Wrench at their backs, Mechanical Crafter inputs can be combined", + "create.ponder.mechanical_crafter_connect.text_3": "UNLOCALIZED: All connected Crafters can now be accessed by the same input location", + + "create.ponder.mechanical_crafter_covers.header": "UNLOCALIZED: Covering slots of Mechanical Crafters", + "create.ponder.mechanical_crafter_covers.text_1": "UNLOCALIZED: Some recipes will require additional Crafters to bridge gaps in the path", + "create.ponder.mechanical_crafter_covers.text_2": "UNLOCALIZED: Using Slot Covers, Crafters can be set to act as an Empty Slot in the arrangement", + "create.ponder.mechanical_crafter_covers.text_3": "UNLOCALIZED: Shared Inputs created with the Wrench at the back can also reach across covered Crafters", + "create.ponder.mechanical_drill.header": "UNLOCALIZED: Breaking Blocks with the Mechanical Drill", "create.ponder.mechanical_drill.text_1": "UNLOCALIZED: When given Rotational Force, a Mechanical Drill will break blocks directly in front of it", "create.ponder.mechanical_drill.text_2": "UNLOCALIZED: Its mining speed depends on the Rotational Input", @@ -2298,6 +2361,16 @@ "create.ponder.rotation_speed_controller.text_1": "UNLOCALIZED: Rot. Speed Controllers relay rotation from their axis to a Large Cogwheel above them", "create.ponder.rotation_speed_controller.text_2": "UNLOCALIZED: Using the scroll input on its side, the conveyed speed can be configured", + "create.ponder.sail.header": "UNLOCALIZED: Assembling Windmills using Sails", + "create.ponder.sail.text_1": "UNLOCALIZED: Sails are handy blocks to create Windmills with", + "create.ponder.sail.text_2": "UNLOCALIZED: They will attach to blocks and each other without the need of Super Glue or Chassis Blocks", + "create.ponder.sail.text_3": "UNLOCALIZED: Right-Click with Dye to paint them", + "create.ponder.sail.text_4": "UNLOCALIZED: Right-Click with Shears to turn them back into frames", + + "create.ponder.sail_frame.header": "UNLOCALIZED: Assembling Windmills using Sail Frames", + "create.ponder.sail_frame.text_1": "UNLOCALIZED: Sail Frames are handy blocks to create Windmills with", + "create.ponder.sail_frame.text_2": "UNLOCALIZED: They will attach to blocks and each other without the need of Super Glue or Chassis Blocks", + "create.ponder.sequenced_gearshift.header": "UNLOCALIZED: Controlling Rotational Speed using Sequenced Gearshifts", "create.ponder.sequenced_gearshift.text_1": "UNLOCALIZED: Seq. Gearshifts relay rotation by following a timed list of instructions", "create.ponder.sequenced_gearshift.text_2": "UNLOCALIZED: Right-click it to open the Configuration UI", diff --git a/src/generated/resources/assets/create/lang/unfinished/nl_nl.json b/src/generated/resources/assets/create/lang/unfinished/nl_nl.json index c8f125878..c10eef86d 100644 --- a/src/generated/resources/assets/create/lang/unfinished/nl_nl.json +++ b/src/generated/resources/assets/create/lang/unfinished/nl_nl.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1642", + "_": "Missing Localizations: 1705", "_": "->------------------------] Game Elements [------------------------<-", @@ -396,6 +396,7 @@ "block.create.weathered_limestone_cobblestone_stairs": "UNLOCALIZED: Weathered Limestone Cobblestone Stairs", "block.create.weathered_limestone_cobblestone_wall": "UNLOCALIZED: Weathered Limestone Cobblestone Wall", "block.create.weathered_limestone_pillar": "Verweerde Kalksteen Pilaar", + "block.create.weighted_ejector": "UNLOCALIZED: Weighted Ejector", "block.create.white_sail": "UNLOCALIZED: White Sail", "block.create.white_seat": "UNLOCALIZED: White Seat", "block.create.white_valve_handle": "UNLOCALIZED: White Valve Handle", @@ -1084,6 +1085,12 @@ "create.mechanical_arm.summary": "UNLOCALIZED: Mechanical Arm has %1$s input(s) and %2$s output(s).", "create.mechanical_arm.points_outside_range": "UNLOCALIZED: %1$s selected interaction point(s) removed due to range limitations.", + "create.weighted_ejector.target_set": "UNLOCALIZED: Target Selected", + "create.weighted_ejector.target_not_valid": "UNLOCALIZED: Ejecting to Adjacent block (Target was not Valid)", + "create.weighted_ejector.no_target": "UNLOCALIZED: Ejecting to Adjacent block (No Target was Selected)", + "create.weighted_ejector.targeting": "UNLOCALIZED: Ejecting to [%1$s,%2$s,%3$s]", + "create.weighted_ejector.stack_size": "UNLOCALIZED: Ejected Stack Size", + "create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available", "create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: Round Robin", @@ -1838,22 +1845,24 @@ "create.ponder.tag.contraption_actor.description": "UNLOCALIZED: Components which expose special behaviour when attached to a moving contraption", "create.ponder.tag.arm_targets": "UNLOCALIZED: Targets for Mechanical Arms", "create.ponder.tag.arm_targets.description": "UNLOCALIZED: Components which can be selected as inputs or outputs to the Mechanical Arm", - "create.ponder.tag.contraption_assembly": "UNLOCALIZED: Block Attachment Utility", - "create.ponder.tag.contraption_assembly.description": "UNLOCALIZED: Tools and Components used to assemble structures moved as an animated Contraption", "create.ponder.tag.logistics": "UNLOCALIZED: Item Transportation", "create.ponder.tag.logistics.description": "UNLOCALIZED: Components which help moving items around", "create.ponder.tag.movement_anchor": "UNLOCALIZED: Movement Anchors", "create.ponder.tag.movement_anchor.description": "UNLOCALIZED: Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways", + "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", + "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", + "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", + "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", + "create.ponder.tag.windmill_sails": "UNLOCALIZED: Sails for Windmill Bearings", + "create.ponder.tag.windmill_sails.description": "UNLOCALIZED: Blocks that count towards the strength of a Windmill Contraption when assembled. Each of these have equal efficiency in doing so.", + "create.ponder.tag.contraption_assembly": "UNLOCALIZED: Block Attachment Utility", + "create.ponder.tag.contraption_assembly.description": "UNLOCALIZED: Tools and Components used to assemble structures moved as an animated Contraption", "create.ponder.tag.decoration": "UNLOCALIZED: Aesthetics", "create.ponder.tag.decoration.description": "UNLOCALIZED: Components used mostly for decorative purposes", "create.ponder.tag.kinetic_appliances": "UNLOCALIZED: Kinetic Appliances", "create.ponder.tag.kinetic_appliances.description": "UNLOCALIZED: Components which make use of Rotational Force", "create.ponder.tag.redstone": "UNLOCALIZED: Logic Components", "create.ponder.tag.redstone.description": "UNLOCALIZED: Components which help with redstone engineering", - "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", - "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", - "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", - "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", "create.ponder.tag.fluids": "UNLOCALIZED: Fluid Manipulators", "create.ponder.tag.fluids.description": "UNLOCALIZED: Components which help relaying and making use of Fluids", @@ -2155,10 +2164,64 @@ "create.ponder.linear_chassis_group.text_2": "UNLOCALIZED: When one is moved by a Contraption, the others are dragged with it", "create.ponder.linear_chassis_group.text_3": "UNLOCALIZED: Chassis of a different type or facing another direction will not attach", + "create.ponder.mechanical_arm.header": "UNLOCALIZED: Setting up Mechanical Arms", + "create.ponder.mechanical_arm.text_1": "UNLOCALIZED: Mechanical Arms have to be assigned their in- and outputs before they are placed", + "create.ponder.mechanical_arm.text_2": "UNLOCALIZED: Right-Click inventories while holding the Arm to assign them as Targets", + "create.ponder.mechanical_arm.text_3": "UNLOCALIZED: Right-Click again to toggle between Input (Blue) and Output (Orange)", + "create.ponder.mechanical_arm.text_4": "UNLOCALIZED: Left-Click components to remove their Selection", + "create.ponder.mechanical_arm.text_5": "UNLOCALIZED: Once placed, the Mechanical Arm will target the blocks selected previously", + "create.ponder.mechanical_arm.text_6": "UNLOCALIZED: They can have any amount of in- and outputs within their range", + "create.ponder.mechanical_arm.text_7": "UNLOCALIZED: However, not every type of Inventory can be interacted with directly", + "create.ponder.mechanical_arm.text_8": "UNLOCALIZED: Funnels and Depots can help to Bridge that gap", + + "create.ponder.mechanical_arm_filtering.header": "UNLOCALIZED: Filtering Outputs of the Mechanical Arm", + "create.ponder.mechanical_arm_filtering.text_1": "UNLOCALIZED: Inputs", + "create.ponder.mechanical_arm_filtering.text_2": "UNLOCALIZED: Outputs", + "create.ponder.mechanical_arm_filtering.text_3": "UNLOCALIZED: Sometimes it is desirable to restrict targets of the Arm by matching a filter", + "create.ponder.mechanical_arm_filtering.text_4": "UNLOCALIZED: Mechanical Arms by themselves do not provide any options for filtering", + "create.ponder.mechanical_arm_filtering.text_5": "UNLOCALIZED: Brass Funnels as Targets do however communicate their own filter to the Arm", + "create.ponder.mechanical_arm_filtering.text_6": "UNLOCALIZED: The Arm is smart enough not to pick up items it couldn't distribute", + + "create.ponder.mechanical_arm_modes.header": "UNLOCALIZED: Distribution modes of the Mechanical Arm", + "create.ponder.mechanical_arm_modes.text_1": "UNLOCALIZED: Input", + "create.ponder.mechanical_arm_modes.text_2": "UNLOCALIZED: Outputs", + "create.ponder.mechanical_arm_modes.text_3": "UNLOCALIZED: Whenever an Arm has to choose between multiple valid outputs...", + "create.ponder.mechanical_arm_modes.text_4": "UNLOCALIZED: ...it will act according to its setting", + "create.ponder.mechanical_arm_modes.text_5": "UNLOCALIZED: Scrolling with a Wrench will allow you to configure it", + "create.ponder.mechanical_arm_modes.text_6": "UNLOCALIZED: Round Robin mode simply cycles through all outputs that are available", + "create.ponder.mechanical_arm_modes.text_7": "UNLOCALIZED: If an output is unable to take more items, it will be skipped", + "create.ponder.mechanical_arm_modes.text_8": "UNLOCALIZED: Forced Round Robin mode will never skip outputs, and instead wait until they are free", + "create.ponder.mechanical_arm_modes.text_9": "UNLOCALIZED: Prefer First prioritizes the outputs selected earliest when configuring this Arm", + + "create.ponder.mechanical_arm_redstone.header": "UNLOCALIZED: Controlling Mechanical Arms with Redstone", + "create.ponder.mechanical_arm_redstone.text_1": "UNLOCALIZED: When powered by Redstone, Mechanical Arms will not activate", + "create.ponder.mechanical_arm_redstone.text_2": "UNLOCALIZED: Before stopping, it will finish any started cycles", + "create.ponder.mechanical_arm_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.mechanical_bearing.header": "UNLOCALIZED: Movings Structures using the Mechanical Bearing", "create.ponder.mechanical_bearing.text_1": "UNLOCALIZED: Mechanical Bearings attach to the block in front of them", "create.ponder.mechanical_bearing.text_2": "UNLOCALIZED: Upon receiving Rotational Force, it will assemble it into a Rotating Contraption", + "create.ponder.mechanical_crafter.header": "UNLOCALIZED: Setting up Mechanical Crafters", + "create.ponder.mechanical_crafter.text_1": "UNLOCALIZED: An array of Mechanical Crafters can be used to automate any Crafting Recipe", + "create.ponder.mechanical_crafter.text_2": "UNLOCALIZED: Using a Wrench, the Crafters' paths can be arranged", + "create.ponder.mechanical_crafter.text_3": "UNLOCALIZED: For a valid setup, all paths have to converge into one exit at any side", + "create.ponder.mechanical_crafter.text_4": "UNLOCALIZED: The outputs will be placed into the inventory at the exit", + "create.ponder.mechanical_crafter.text_5": "UNLOCALIZED: Mechanical Crafters require Rotational Force to operate", + "create.ponder.mechanical_crafter.text_6": "UNLOCALIZED: Right-Click the front to insert Items manually", + "create.ponder.mechanical_crafter.text_7": "UNLOCALIZED: Once every slot of a path contains an Item, the crafting process will begin", + "create.ponder.mechanical_crafter.text_8": "UNLOCALIZED: For recipes not fully occupying the crafter setup, the start can be forced using a Redstone Pulse", + + "create.ponder.mechanical_crafter_connect.header": "UNLOCALIZED: Connecting Inventories of Crafters", + "create.ponder.mechanical_crafter_connect.text_1": "UNLOCALIZED: Items can be inserted to Crafters automatically", + "create.ponder.mechanical_crafter_connect.text_2": "UNLOCALIZED: Using the Wrench at their backs, Mechanical Crafter inputs can be combined", + "create.ponder.mechanical_crafter_connect.text_3": "UNLOCALIZED: All connected Crafters can now be accessed by the same input location", + + "create.ponder.mechanical_crafter_covers.header": "UNLOCALIZED: Covering slots of Mechanical Crafters", + "create.ponder.mechanical_crafter_covers.text_1": "UNLOCALIZED: Some recipes will require additional Crafters to bridge gaps in the path", + "create.ponder.mechanical_crafter_covers.text_2": "UNLOCALIZED: Using Slot Covers, Crafters can be set to act as an Empty Slot in the arrangement", + "create.ponder.mechanical_crafter_covers.text_3": "UNLOCALIZED: Shared Inputs created with the Wrench at the back can also reach across covered Crafters", + "create.ponder.mechanical_drill.header": "UNLOCALIZED: Breaking Blocks with the Mechanical Drill", "create.ponder.mechanical_drill.text_1": "UNLOCALIZED: When given Rotational Force, a Mechanical Drill will break blocks directly in front of it", "create.ponder.mechanical_drill.text_2": "UNLOCALIZED: Its mining speed depends on the Rotational Input", @@ -2298,6 +2361,16 @@ "create.ponder.rotation_speed_controller.text_1": "UNLOCALIZED: Rot. Speed Controllers relay rotation from their axis to a Large Cogwheel above them", "create.ponder.rotation_speed_controller.text_2": "UNLOCALIZED: Using the scroll input on its side, the conveyed speed can be configured", + "create.ponder.sail.header": "UNLOCALIZED: Assembling Windmills using Sails", + "create.ponder.sail.text_1": "UNLOCALIZED: Sails are handy blocks to create Windmills with", + "create.ponder.sail.text_2": "UNLOCALIZED: They will attach to blocks and each other without the need of Super Glue or Chassis Blocks", + "create.ponder.sail.text_3": "UNLOCALIZED: Right-Click with Dye to paint them", + "create.ponder.sail.text_4": "UNLOCALIZED: Right-Click with Shears to turn them back into frames", + + "create.ponder.sail_frame.header": "UNLOCALIZED: Assembling Windmills using Sail Frames", + "create.ponder.sail_frame.text_1": "UNLOCALIZED: Sail Frames are handy blocks to create Windmills with", + "create.ponder.sail_frame.text_2": "UNLOCALIZED: They will attach to blocks and each other without the need of Super Glue or Chassis Blocks", + "create.ponder.sequenced_gearshift.header": "UNLOCALIZED: Controlling Rotational Speed using Sequenced Gearshifts", "create.ponder.sequenced_gearshift.text_1": "UNLOCALIZED: Seq. Gearshifts relay rotation by following a timed list of instructions", "create.ponder.sequenced_gearshift.text_2": "UNLOCALIZED: Right-click it to open the Configuration UI", diff --git a/src/generated/resources/assets/create/lang/unfinished/pt_br.json b/src/generated/resources/assets/create/lang/unfinished/pt_br.json index 969babaa9..e45ff7651 100644 --- a/src/generated/resources/assets/create/lang/unfinished/pt_br.json +++ b/src/generated/resources/assets/create/lang/unfinished/pt_br.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1708", + "_": "Missing Localizations: 1771", "_": "->------------------------] Game Elements [------------------------<-", @@ -396,6 +396,7 @@ "block.create.weathered_limestone_cobblestone_stairs": "UNLOCALIZED: Weathered Limestone Cobblestone Stairs", "block.create.weathered_limestone_cobblestone_wall": "UNLOCALIZED: Weathered Limestone Cobblestone Wall", "block.create.weathered_limestone_pillar": "Pilar de Calcário Resistido", + "block.create.weighted_ejector": "UNLOCALIZED: Weighted Ejector", "block.create.white_sail": "UNLOCALIZED: White Sail", "block.create.white_seat": "UNLOCALIZED: White Seat", "block.create.white_valve_handle": "UNLOCALIZED: White Valve Handle", @@ -1084,6 +1085,12 @@ "create.mechanical_arm.summary": "UNLOCALIZED: Mechanical Arm has %1$s input(s) and %2$s output(s).", "create.mechanical_arm.points_outside_range": "UNLOCALIZED: %1$s selected interaction point(s) removed due to range limitations.", + "create.weighted_ejector.target_set": "UNLOCALIZED: Target Selected", + "create.weighted_ejector.target_not_valid": "UNLOCALIZED: Ejecting to Adjacent block (Target was not Valid)", + "create.weighted_ejector.no_target": "UNLOCALIZED: Ejecting to Adjacent block (No Target was Selected)", + "create.weighted_ejector.targeting": "UNLOCALIZED: Ejecting to [%1$s,%2$s,%3$s]", + "create.weighted_ejector.stack_size": "UNLOCALIZED: Ejected Stack Size", + "create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available", "create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: Round Robin", @@ -1838,22 +1845,24 @@ "create.ponder.tag.contraption_actor.description": "UNLOCALIZED: Components which expose special behaviour when attached to a moving contraption", "create.ponder.tag.arm_targets": "UNLOCALIZED: Targets for Mechanical Arms", "create.ponder.tag.arm_targets.description": "UNLOCALIZED: Components which can be selected as inputs or outputs to the Mechanical Arm", - "create.ponder.tag.contraption_assembly": "UNLOCALIZED: Block Attachment Utility", - "create.ponder.tag.contraption_assembly.description": "UNLOCALIZED: Tools and Components used to assemble structures moved as an animated Contraption", "create.ponder.tag.logistics": "UNLOCALIZED: Item Transportation", "create.ponder.tag.logistics.description": "UNLOCALIZED: Components which help moving items around", "create.ponder.tag.movement_anchor": "UNLOCALIZED: Movement Anchors", "create.ponder.tag.movement_anchor.description": "UNLOCALIZED: Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways", + "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", + "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", + "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", + "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", + "create.ponder.tag.windmill_sails": "UNLOCALIZED: Sails for Windmill Bearings", + "create.ponder.tag.windmill_sails.description": "UNLOCALIZED: Blocks that count towards the strength of a Windmill Contraption when assembled. Each of these have equal efficiency in doing so.", + "create.ponder.tag.contraption_assembly": "UNLOCALIZED: Block Attachment Utility", + "create.ponder.tag.contraption_assembly.description": "UNLOCALIZED: Tools and Components used to assemble structures moved as an animated Contraption", "create.ponder.tag.decoration": "UNLOCALIZED: Aesthetics", "create.ponder.tag.decoration.description": "UNLOCALIZED: Components used mostly for decorative purposes", "create.ponder.tag.kinetic_appliances": "UNLOCALIZED: Kinetic Appliances", "create.ponder.tag.kinetic_appliances.description": "UNLOCALIZED: Components which make use of Rotational Force", "create.ponder.tag.redstone": "UNLOCALIZED: Logic Components", "create.ponder.tag.redstone.description": "UNLOCALIZED: Components which help with redstone engineering", - "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", - "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", - "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", - "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", "create.ponder.tag.fluids": "UNLOCALIZED: Fluid Manipulators", "create.ponder.tag.fluids.description": "UNLOCALIZED: Components which help relaying and making use of Fluids", @@ -2155,10 +2164,64 @@ "create.ponder.linear_chassis_group.text_2": "UNLOCALIZED: When one is moved by a Contraption, the others are dragged with it", "create.ponder.linear_chassis_group.text_3": "UNLOCALIZED: Chassis of a different type or facing another direction will not attach", + "create.ponder.mechanical_arm.header": "UNLOCALIZED: Setting up Mechanical Arms", + "create.ponder.mechanical_arm.text_1": "UNLOCALIZED: Mechanical Arms have to be assigned their in- and outputs before they are placed", + "create.ponder.mechanical_arm.text_2": "UNLOCALIZED: Right-Click inventories while holding the Arm to assign them as Targets", + "create.ponder.mechanical_arm.text_3": "UNLOCALIZED: Right-Click again to toggle between Input (Blue) and Output (Orange)", + "create.ponder.mechanical_arm.text_4": "UNLOCALIZED: Left-Click components to remove their Selection", + "create.ponder.mechanical_arm.text_5": "UNLOCALIZED: Once placed, the Mechanical Arm will target the blocks selected previously", + "create.ponder.mechanical_arm.text_6": "UNLOCALIZED: They can have any amount of in- and outputs within their range", + "create.ponder.mechanical_arm.text_7": "UNLOCALIZED: However, not every type of Inventory can be interacted with directly", + "create.ponder.mechanical_arm.text_8": "UNLOCALIZED: Funnels and Depots can help to Bridge that gap", + + "create.ponder.mechanical_arm_filtering.header": "UNLOCALIZED: Filtering Outputs of the Mechanical Arm", + "create.ponder.mechanical_arm_filtering.text_1": "UNLOCALIZED: Inputs", + "create.ponder.mechanical_arm_filtering.text_2": "UNLOCALIZED: Outputs", + "create.ponder.mechanical_arm_filtering.text_3": "UNLOCALIZED: Sometimes it is desirable to restrict targets of the Arm by matching a filter", + "create.ponder.mechanical_arm_filtering.text_4": "UNLOCALIZED: Mechanical Arms by themselves do not provide any options for filtering", + "create.ponder.mechanical_arm_filtering.text_5": "UNLOCALIZED: Brass Funnels as Targets do however communicate their own filter to the Arm", + "create.ponder.mechanical_arm_filtering.text_6": "UNLOCALIZED: The Arm is smart enough not to pick up items it couldn't distribute", + + "create.ponder.mechanical_arm_modes.header": "UNLOCALIZED: Distribution modes of the Mechanical Arm", + "create.ponder.mechanical_arm_modes.text_1": "UNLOCALIZED: Input", + "create.ponder.mechanical_arm_modes.text_2": "UNLOCALIZED: Outputs", + "create.ponder.mechanical_arm_modes.text_3": "UNLOCALIZED: Whenever an Arm has to choose between multiple valid outputs...", + "create.ponder.mechanical_arm_modes.text_4": "UNLOCALIZED: ...it will act according to its setting", + "create.ponder.mechanical_arm_modes.text_5": "UNLOCALIZED: Scrolling with a Wrench will allow you to configure it", + "create.ponder.mechanical_arm_modes.text_6": "UNLOCALIZED: Round Robin mode simply cycles through all outputs that are available", + "create.ponder.mechanical_arm_modes.text_7": "UNLOCALIZED: If an output is unable to take more items, it will be skipped", + "create.ponder.mechanical_arm_modes.text_8": "UNLOCALIZED: Forced Round Robin mode will never skip outputs, and instead wait until they are free", + "create.ponder.mechanical_arm_modes.text_9": "UNLOCALIZED: Prefer First prioritizes the outputs selected earliest when configuring this Arm", + + "create.ponder.mechanical_arm_redstone.header": "UNLOCALIZED: Controlling Mechanical Arms with Redstone", + "create.ponder.mechanical_arm_redstone.text_1": "UNLOCALIZED: When powered by Redstone, Mechanical Arms will not activate", + "create.ponder.mechanical_arm_redstone.text_2": "UNLOCALIZED: Before stopping, it will finish any started cycles", + "create.ponder.mechanical_arm_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.mechanical_bearing.header": "UNLOCALIZED: Movings Structures using the Mechanical Bearing", "create.ponder.mechanical_bearing.text_1": "UNLOCALIZED: Mechanical Bearings attach to the block in front of them", "create.ponder.mechanical_bearing.text_2": "UNLOCALIZED: Upon receiving Rotational Force, it will assemble it into a Rotating Contraption", + "create.ponder.mechanical_crafter.header": "UNLOCALIZED: Setting up Mechanical Crafters", + "create.ponder.mechanical_crafter.text_1": "UNLOCALIZED: An array of Mechanical Crafters can be used to automate any Crafting Recipe", + "create.ponder.mechanical_crafter.text_2": "UNLOCALIZED: Using a Wrench, the Crafters' paths can be arranged", + "create.ponder.mechanical_crafter.text_3": "UNLOCALIZED: For a valid setup, all paths have to converge into one exit at any side", + "create.ponder.mechanical_crafter.text_4": "UNLOCALIZED: The outputs will be placed into the inventory at the exit", + "create.ponder.mechanical_crafter.text_5": "UNLOCALIZED: Mechanical Crafters require Rotational Force to operate", + "create.ponder.mechanical_crafter.text_6": "UNLOCALIZED: Right-Click the front to insert Items manually", + "create.ponder.mechanical_crafter.text_7": "UNLOCALIZED: Once every slot of a path contains an Item, the crafting process will begin", + "create.ponder.mechanical_crafter.text_8": "UNLOCALIZED: For recipes not fully occupying the crafter setup, the start can be forced using a Redstone Pulse", + + "create.ponder.mechanical_crafter_connect.header": "UNLOCALIZED: Connecting Inventories of Crafters", + "create.ponder.mechanical_crafter_connect.text_1": "UNLOCALIZED: Items can be inserted to Crafters automatically", + "create.ponder.mechanical_crafter_connect.text_2": "UNLOCALIZED: Using the Wrench at their backs, Mechanical Crafter inputs can be combined", + "create.ponder.mechanical_crafter_connect.text_3": "UNLOCALIZED: All connected Crafters can now be accessed by the same input location", + + "create.ponder.mechanical_crafter_covers.header": "UNLOCALIZED: Covering slots of Mechanical Crafters", + "create.ponder.mechanical_crafter_covers.text_1": "UNLOCALIZED: Some recipes will require additional Crafters to bridge gaps in the path", + "create.ponder.mechanical_crafter_covers.text_2": "UNLOCALIZED: Using Slot Covers, Crafters can be set to act as an Empty Slot in the arrangement", + "create.ponder.mechanical_crafter_covers.text_3": "UNLOCALIZED: Shared Inputs created with the Wrench at the back can also reach across covered Crafters", + "create.ponder.mechanical_drill.header": "UNLOCALIZED: Breaking Blocks with the Mechanical Drill", "create.ponder.mechanical_drill.text_1": "UNLOCALIZED: When given Rotational Force, a Mechanical Drill will break blocks directly in front of it", "create.ponder.mechanical_drill.text_2": "UNLOCALIZED: Its mining speed depends on the Rotational Input", @@ -2298,6 +2361,16 @@ "create.ponder.rotation_speed_controller.text_1": "UNLOCALIZED: Rot. Speed Controllers relay rotation from their axis to a Large Cogwheel above them", "create.ponder.rotation_speed_controller.text_2": "UNLOCALIZED: Using the scroll input on its side, the conveyed speed can be configured", + "create.ponder.sail.header": "UNLOCALIZED: Assembling Windmills using Sails", + "create.ponder.sail.text_1": "UNLOCALIZED: Sails are handy blocks to create Windmills with", + "create.ponder.sail.text_2": "UNLOCALIZED: They will attach to blocks and each other without the need of Super Glue or Chassis Blocks", + "create.ponder.sail.text_3": "UNLOCALIZED: Right-Click with Dye to paint them", + "create.ponder.sail.text_4": "UNLOCALIZED: Right-Click with Shears to turn them back into frames", + + "create.ponder.sail_frame.header": "UNLOCALIZED: Assembling Windmills using Sail Frames", + "create.ponder.sail_frame.text_1": "UNLOCALIZED: Sail Frames are handy blocks to create Windmills with", + "create.ponder.sail_frame.text_2": "UNLOCALIZED: They will attach to blocks and each other without the need of Super Glue or Chassis Blocks", + "create.ponder.sequenced_gearshift.header": "UNLOCALIZED: Controlling Rotational Speed using Sequenced Gearshifts", "create.ponder.sequenced_gearshift.text_1": "UNLOCALIZED: Seq. Gearshifts relay rotation by following a timed list of instructions", "create.ponder.sequenced_gearshift.text_2": "UNLOCALIZED: Right-click it to open the Configuration UI", diff --git a/src/generated/resources/assets/create/lang/unfinished/ru_ru.json b/src/generated/resources/assets/create/lang/unfinished/ru_ru.json index 7d277317b..4869223bd 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ru_ru.json +++ b/src/generated/resources/assets/create/lang/unfinished/ru_ru.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 494", + "_": "Missing Localizations: 557", "_": "->------------------------] Game Elements [------------------------<-", @@ -396,6 +396,7 @@ "block.create.weathered_limestone_cobblestone_stairs": "Ступени из известняк-булыжника", "block.create.weathered_limestone_cobblestone_wall": "Стена из известняк-булыжника", "block.create.weathered_limestone_pillar": "Колонна из выветренного известняка", + "block.create.weighted_ejector": "UNLOCALIZED: Weighted Ejector", "block.create.white_sail": "Белый парус", "block.create.white_seat": "Белое сиденье", "block.create.white_valve_handle": "Белый ручной вентиль", @@ -1084,6 +1085,12 @@ "create.mechanical_arm.summary": "Механическая рука имеет %1$s вход(ов) и %2$s выход(ов).", "create.mechanical_arm.points_outside_range": "%1$s выбранные точки взаимодействия удалены из-за ограничений диапазона.", + "create.weighted_ejector.target_set": "UNLOCALIZED: Target Selected", + "create.weighted_ejector.target_not_valid": "UNLOCALIZED: Ejecting to Adjacent block (Target was not Valid)", + "create.weighted_ejector.no_target": "UNLOCALIZED: Ejecting to Adjacent block (No Target was Selected)", + "create.weighted_ejector.targeting": "UNLOCALIZED: Ejecting to [%1$s,%2$s,%3$s]", + "create.weighted_ejector.stack_size": "UNLOCALIZED: Ejected Stack Size", + "create.logistics.when_multiple_outputs_available": "Когда доступно несколько выходов", "create.mechanical_arm.selection_mode.round_robin": "По кругу", @@ -1838,22 +1845,24 @@ "create.ponder.tag.contraption_actor.description": "UNLOCALIZED: Components which expose special behaviour when attached to a moving contraption", "create.ponder.tag.arm_targets": "UNLOCALIZED: Targets for Mechanical Arms", "create.ponder.tag.arm_targets.description": "UNLOCALIZED: Components which can be selected as inputs or outputs to the Mechanical Arm", - "create.ponder.tag.contraption_assembly": "UNLOCALIZED: Block Attachment Utility", - "create.ponder.tag.contraption_assembly.description": "UNLOCALIZED: Tools and Components used to assemble structures moved as an animated Contraption", "create.ponder.tag.logistics": "UNLOCALIZED: Item Transportation", "create.ponder.tag.logistics.description": "UNLOCALIZED: Components which help moving items around", "create.ponder.tag.movement_anchor": "UNLOCALIZED: Movement Anchors", "create.ponder.tag.movement_anchor.description": "UNLOCALIZED: Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways", + "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", + "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", + "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", + "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", + "create.ponder.tag.windmill_sails": "UNLOCALIZED: Sails for Windmill Bearings", + "create.ponder.tag.windmill_sails.description": "UNLOCALIZED: Blocks that count towards the strength of a Windmill Contraption when assembled. Each of these have equal efficiency in doing so.", + "create.ponder.tag.contraption_assembly": "UNLOCALIZED: Block Attachment Utility", + "create.ponder.tag.contraption_assembly.description": "UNLOCALIZED: Tools and Components used to assemble structures moved as an animated Contraption", "create.ponder.tag.decoration": "UNLOCALIZED: Aesthetics", "create.ponder.tag.decoration.description": "UNLOCALIZED: Components used mostly for decorative purposes", "create.ponder.tag.kinetic_appliances": "UNLOCALIZED: Kinetic Appliances", "create.ponder.tag.kinetic_appliances.description": "UNLOCALIZED: Components which make use of Rotational Force", "create.ponder.tag.redstone": "UNLOCALIZED: Logic Components", "create.ponder.tag.redstone.description": "UNLOCALIZED: Components which help with redstone engineering", - "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", - "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", - "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", - "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", "create.ponder.tag.fluids": "UNLOCALIZED: Fluid Manipulators", "create.ponder.tag.fluids.description": "UNLOCALIZED: Components which help relaying and making use of Fluids", @@ -2155,10 +2164,64 @@ "create.ponder.linear_chassis_group.text_2": "UNLOCALIZED: When one is moved by a Contraption, the others are dragged with it", "create.ponder.linear_chassis_group.text_3": "UNLOCALIZED: Chassis of a different type or facing another direction will not attach", + "create.ponder.mechanical_arm.header": "UNLOCALIZED: Setting up Mechanical Arms", + "create.ponder.mechanical_arm.text_1": "UNLOCALIZED: Mechanical Arms have to be assigned their in- and outputs before they are placed", + "create.ponder.mechanical_arm.text_2": "UNLOCALIZED: Right-Click inventories while holding the Arm to assign them as Targets", + "create.ponder.mechanical_arm.text_3": "UNLOCALIZED: Right-Click again to toggle between Input (Blue) and Output (Orange)", + "create.ponder.mechanical_arm.text_4": "UNLOCALIZED: Left-Click components to remove their Selection", + "create.ponder.mechanical_arm.text_5": "UNLOCALIZED: Once placed, the Mechanical Arm will target the blocks selected previously", + "create.ponder.mechanical_arm.text_6": "UNLOCALIZED: They can have any amount of in- and outputs within their range", + "create.ponder.mechanical_arm.text_7": "UNLOCALIZED: However, not every type of Inventory can be interacted with directly", + "create.ponder.mechanical_arm.text_8": "UNLOCALIZED: Funnels and Depots can help to Bridge that gap", + + "create.ponder.mechanical_arm_filtering.header": "UNLOCALIZED: Filtering Outputs of the Mechanical Arm", + "create.ponder.mechanical_arm_filtering.text_1": "UNLOCALIZED: Inputs", + "create.ponder.mechanical_arm_filtering.text_2": "UNLOCALIZED: Outputs", + "create.ponder.mechanical_arm_filtering.text_3": "UNLOCALIZED: Sometimes it is desirable to restrict targets of the Arm by matching a filter", + "create.ponder.mechanical_arm_filtering.text_4": "UNLOCALIZED: Mechanical Arms by themselves do not provide any options for filtering", + "create.ponder.mechanical_arm_filtering.text_5": "UNLOCALIZED: Brass Funnels as Targets do however communicate their own filter to the Arm", + "create.ponder.mechanical_arm_filtering.text_6": "UNLOCALIZED: The Arm is smart enough not to pick up items it couldn't distribute", + + "create.ponder.mechanical_arm_modes.header": "UNLOCALIZED: Distribution modes of the Mechanical Arm", + "create.ponder.mechanical_arm_modes.text_1": "UNLOCALIZED: Input", + "create.ponder.mechanical_arm_modes.text_2": "UNLOCALIZED: Outputs", + "create.ponder.mechanical_arm_modes.text_3": "UNLOCALIZED: Whenever an Arm has to choose between multiple valid outputs...", + "create.ponder.mechanical_arm_modes.text_4": "UNLOCALIZED: ...it will act according to its setting", + "create.ponder.mechanical_arm_modes.text_5": "UNLOCALIZED: Scrolling with a Wrench will allow you to configure it", + "create.ponder.mechanical_arm_modes.text_6": "UNLOCALIZED: Round Robin mode simply cycles through all outputs that are available", + "create.ponder.mechanical_arm_modes.text_7": "UNLOCALIZED: If an output is unable to take more items, it will be skipped", + "create.ponder.mechanical_arm_modes.text_8": "UNLOCALIZED: Forced Round Robin mode will never skip outputs, and instead wait until they are free", + "create.ponder.mechanical_arm_modes.text_9": "UNLOCALIZED: Prefer First prioritizes the outputs selected earliest when configuring this Arm", + + "create.ponder.mechanical_arm_redstone.header": "UNLOCALIZED: Controlling Mechanical Arms with Redstone", + "create.ponder.mechanical_arm_redstone.text_1": "UNLOCALIZED: When powered by Redstone, Mechanical Arms will not activate", + "create.ponder.mechanical_arm_redstone.text_2": "UNLOCALIZED: Before stopping, it will finish any started cycles", + "create.ponder.mechanical_arm_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.mechanical_bearing.header": "UNLOCALIZED: Movings Structures using the Mechanical Bearing", "create.ponder.mechanical_bearing.text_1": "UNLOCALIZED: Mechanical Bearings attach to the block in front of them", "create.ponder.mechanical_bearing.text_2": "UNLOCALIZED: Upon receiving Rotational Force, it will assemble it into a Rotating Contraption", + "create.ponder.mechanical_crafter.header": "UNLOCALIZED: Setting up Mechanical Crafters", + "create.ponder.mechanical_crafter.text_1": "UNLOCALIZED: An array of Mechanical Crafters can be used to automate any Crafting Recipe", + "create.ponder.mechanical_crafter.text_2": "UNLOCALIZED: Using a Wrench, the Crafters' paths can be arranged", + "create.ponder.mechanical_crafter.text_3": "UNLOCALIZED: For a valid setup, all paths have to converge into one exit at any side", + "create.ponder.mechanical_crafter.text_4": "UNLOCALIZED: The outputs will be placed into the inventory at the exit", + "create.ponder.mechanical_crafter.text_5": "UNLOCALIZED: Mechanical Crafters require Rotational Force to operate", + "create.ponder.mechanical_crafter.text_6": "UNLOCALIZED: Right-Click the front to insert Items manually", + "create.ponder.mechanical_crafter.text_7": "UNLOCALIZED: Once every slot of a path contains an Item, the crafting process will begin", + "create.ponder.mechanical_crafter.text_8": "UNLOCALIZED: For recipes not fully occupying the crafter setup, the start can be forced using a Redstone Pulse", + + "create.ponder.mechanical_crafter_connect.header": "UNLOCALIZED: Connecting Inventories of Crafters", + "create.ponder.mechanical_crafter_connect.text_1": "UNLOCALIZED: Items can be inserted to Crafters automatically", + "create.ponder.mechanical_crafter_connect.text_2": "UNLOCALIZED: Using the Wrench at their backs, Mechanical Crafter inputs can be combined", + "create.ponder.mechanical_crafter_connect.text_3": "UNLOCALIZED: All connected Crafters can now be accessed by the same input location", + + "create.ponder.mechanical_crafter_covers.header": "UNLOCALIZED: Covering slots of Mechanical Crafters", + "create.ponder.mechanical_crafter_covers.text_1": "UNLOCALIZED: Some recipes will require additional Crafters to bridge gaps in the path", + "create.ponder.mechanical_crafter_covers.text_2": "UNLOCALIZED: Using Slot Covers, Crafters can be set to act as an Empty Slot in the arrangement", + "create.ponder.mechanical_crafter_covers.text_3": "UNLOCALIZED: Shared Inputs created with the Wrench at the back can also reach across covered Crafters", + "create.ponder.mechanical_drill.header": "UNLOCALIZED: Breaking Blocks with the Mechanical Drill", "create.ponder.mechanical_drill.text_1": "UNLOCALIZED: When given Rotational Force, a Mechanical Drill will break blocks directly in front of it", "create.ponder.mechanical_drill.text_2": "UNLOCALIZED: Its mining speed depends on the Rotational Input", @@ -2298,6 +2361,16 @@ "create.ponder.rotation_speed_controller.text_1": "UNLOCALIZED: Rot. Speed Controllers relay rotation from their axis to a Large Cogwheel above them", "create.ponder.rotation_speed_controller.text_2": "UNLOCALIZED: Using the scroll input on its side, the conveyed speed can be configured", + "create.ponder.sail.header": "UNLOCALIZED: Assembling Windmills using Sails", + "create.ponder.sail.text_1": "UNLOCALIZED: Sails are handy blocks to create Windmills with", + "create.ponder.sail.text_2": "UNLOCALIZED: They will attach to blocks and each other without the need of Super Glue or Chassis Blocks", + "create.ponder.sail.text_3": "UNLOCALIZED: Right-Click with Dye to paint them", + "create.ponder.sail.text_4": "UNLOCALIZED: Right-Click with Shears to turn them back into frames", + + "create.ponder.sail_frame.header": "UNLOCALIZED: Assembling Windmills using Sail Frames", + "create.ponder.sail_frame.text_1": "UNLOCALIZED: Sail Frames are handy blocks to create Windmills with", + "create.ponder.sail_frame.text_2": "UNLOCALIZED: They will attach to blocks and each other without the need of Super Glue or Chassis Blocks", + "create.ponder.sequenced_gearshift.header": "UNLOCALIZED: Controlling Rotational Speed using Sequenced Gearshifts", "create.ponder.sequenced_gearshift.text_1": "UNLOCALIZED: Seq. Gearshifts relay rotation by following a timed list of instructions", "create.ponder.sequenced_gearshift.text_2": "UNLOCALIZED: Right-click it to open the Configuration UI", diff --git a/src/generated/resources/assets/create/lang/unfinished/zh_cn.json b/src/generated/resources/assets/create/lang/unfinished/zh_cn.json index 7befc4728..e1f1eeb33 100644 --- a/src/generated/resources/assets/create/lang/unfinished/zh_cn.json +++ b/src/generated/resources/assets/create/lang/unfinished/zh_cn.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 492", + "_": "Missing Localizations: 555", "_": "->------------------------] Game Elements [------------------------<-", @@ -396,6 +396,7 @@ "block.create.weathered_limestone_cobblestone_stairs": "风化石灰岩圆石楼梯", "block.create.weathered_limestone_cobblestone_wall": "风化石灰岩圆石墙", "block.create.weathered_limestone_pillar": "竖纹风化石灰岩", + "block.create.weighted_ejector": "UNLOCALIZED: Weighted Ejector", "block.create.white_sail": "白色风帆", "block.create.white_seat": "白色坐垫", "block.create.white_valve_handle": "白色阀门手轮", @@ -1084,6 +1085,12 @@ "create.mechanical_arm.summary": "动力臂的输入为%1$s,输出为%2$s。", "create.mechanical_arm.points_outside_range": "由于距离限制,选定的交互点%1$s已被移除。", + "create.weighted_ejector.target_set": "UNLOCALIZED: Target Selected", + "create.weighted_ejector.target_not_valid": "UNLOCALIZED: Ejecting to Adjacent block (Target was not Valid)", + "create.weighted_ejector.no_target": "UNLOCALIZED: Ejecting to Adjacent block (No Target was Selected)", + "create.weighted_ejector.targeting": "UNLOCALIZED: Ejecting to [%1$s,%2$s,%3$s]", + "create.weighted_ejector.stack_size": "UNLOCALIZED: Ejected Stack Size", + "create.logistics.when_multiple_outputs_available": "当多个输出可用时", "create.mechanical_arm.selection_mode.round_robin": "轮询调度", @@ -1838,22 +1845,24 @@ "create.ponder.tag.contraption_actor.description": "UNLOCALIZED: Components which expose special behaviour when attached to a moving contraption", "create.ponder.tag.arm_targets": "UNLOCALIZED: Targets for Mechanical Arms", "create.ponder.tag.arm_targets.description": "UNLOCALIZED: Components which can be selected as inputs or outputs to the Mechanical Arm", - "create.ponder.tag.contraption_assembly": "UNLOCALIZED: Block Attachment Utility", - "create.ponder.tag.contraption_assembly.description": "UNLOCALIZED: Tools and Components used to assemble structures moved as an animated Contraption", "create.ponder.tag.logistics": "UNLOCALIZED: Item Transportation", "create.ponder.tag.logistics.description": "UNLOCALIZED: Components which help moving items around", "create.ponder.tag.movement_anchor": "UNLOCALIZED: Movement Anchors", "create.ponder.tag.movement_anchor.description": "UNLOCALIZED: Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways", + "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", + "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", + "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", + "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", + "create.ponder.tag.windmill_sails": "UNLOCALIZED: Sails for Windmill Bearings", + "create.ponder.tag.windmill_sails.description": "UNLOCALIZED: Blocks that count towards the strength of a Windmill Contraption when assembled. Each of these have equal efficiency in doing so.", + "create.ponder.tag.contraption_assembly": "UNLOCALIZED: Block Attachment Utility", + "create.ponder.tag.contraption_assembly.description": "UNLOCALIZED: Tools and Components used to assemble structures moved as an animated Contraption", "create.ponder.tag.decoration": "UNLOCALIZED: Aesthetics", "create.ponder.tag.decoration.description": "UNLOCALIZED: Components used mostly for decorative purposes", "create.ponder.tag.kinetic_appliances": "UNLOCALIZED: Kinetic Appliances", "create.ponder.tag.kinetic_appliances.description": "UNLOCALIZED: Components which make use of Rotational Force", "create.ponder.tag.redstone": "UNLOCALIZED: Logic Components", "create.ponder.tag.redstone.description": "UNLOCALIZED: Components which help with redstone engineering", - "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", - "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", - "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", - "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", "create.ponder.tag.fluids": "UNLOCALIZED: Fluid Manipulators", "create.ponder.tag.fluids.description": "UNLOCALIZED: Components which help relaying and making use of Fluids", @@ -2155,10 +2164,64 @@ "create.ponder.linear_chassis_group.text_2": "UNLOCALIZED: When one is moved by a Contraption, the others are dragged with it", "create.ponder.linear_chassis_group.text_3": "UNLOCALIZED: Chassis of a different type or facing another direction will not attach", + "create.ponder.mechanical_arm.header": "UNLOCALIZED: Setting up Mechanical Arms", + "create.ponder.mechanical_arm.text_1": "UNLOCALIZED: Mechanical Arms have to be assigned their in- and outputs before they are placed", + "create.ponder.mechanical_arm.text_2": "UNLOCALIZED: Right-Click inventories while holding the Arm to assign them as Targets", + "create.ponder.mechanical_arm.text_3": "UNLOCALIZED: Right-Click again to toggle between Input (Blue) and Output (Orange)", + "create.ponder.mechanical_arm.text_4": "UNLOCALIZED: Left-Click components to remove their Selection", + "create.ponder.mechanical_arm.text_5": "UNLOCALIZED: Once placed, the Mechanical Arm will target the blocks selected previously", + "create.ponder.mechanical_arm.text_6": "UNLOCALIZED: They can have any amount of in- and outputs within their range", + "create.ponder.mechanical_arm.text_7": "UNLOCALIZED: However, not every type of Inventory can be interacted with directly", + "create.ponder.mechanical_arm.text_8": "UNLOCALIZED: Funnels and Depots can help to Bridge that gap", + + "create.ponder.mechanical_arm_filtering.header": "UNLOCALIZED: Filtering Outputs of the Mechanical Arm", + "create.ponder.mechanical_arm_filtering.text_1": "UNLOCALIZED: Inputs", + "create.ponder.mechanical_arm_filtering.text_2": "UNLOCALIZED: Outputs", + "create.ponder.mechanical_arm_filtering.text_3": "UNLOCALIZED: Sometimes it is desirable to restrict targets of the Arm by matching a filter", + "create.ponder.mechanical_arm_filtering.text_4": "UNLOCALIZED: Mechanical Arms by themselves do not provide any options for filtering", + "create.ponder.mechanical_arm_filtering.text_5": "UNLOCALIZED: Brass Funnels as Targets do however communicate their own filter to the Arm", + "create.ponder.mechanical_arm_filtering.text_6": "UNLOCALIZED: The Arm is smart enough not to pick up items it couldn't distribute", + + "create.ponder.mechanical_arm_modes.header": "UNLOCALIZED: Distribution modes of the Mechanical Arm", + "create.ponder.mechanical_arm_modes.text_1": "UNLOCALIZED: Input", + "create.ponder.mechanical_arm_modes.text_2": "UNLOCALIZED: Outputs", + "create.ponder.mechanical_arm_modes.text_3": "UNLOCALIZED: Whenever an Arm has to choose between multiple valid outputs...", + "create.ponder.mechanical_arm_modes.text_4": "UNLOCALIZED: ...it will act according to its setting", + "create.ponder.mechanical_arm_modes.text_5": "UNLOCALIZED: Scrolling with a Wrench will allow you to configure it", + "create.ponder.mechanical_arm_modes.text_6": "UNLOCALIZED: Round Robin mode simply cycles through all outputs that are available", + "create.ponder.mechanical_arm_modes.text_7": "UNLOCALIZED: If an output is unable to take more items, it will be skipped", + "create.ponder.mechanical_arm_modes.text_8": "UNLOCALIZED: Forced Round Robin mode will never skip outputs, and instead wait until they are free", + "create.ponder.mechanical_arm_modes.text_9": "UNLOCALIZED: Prefer First prioritizes the outputs selected earliest when configuring this Arm", + + "create.ponder.mechanical_arm_redstone.header": "UNLOCALIZED: Controlling Mechanical Arms with Redstone", + "create.ponder.mechanical_arm_redstone.text_1": "UNLOCALIZED: When powered by Redstone, Mechanical Arms will not activate", + "create.ponder.mechanical_arm_redstone.text_2": "UNLOCALIZED: Before stopping, it will finish any started cycles", + "create.ponder.mechanical_arm_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.mechanical_bearing.header": "UNLOCALIZED: Movings Structures using the Mechanical Bearing", "create.ponder.mechanical_bearing.text_1": "UNLOCALIZED: Mechanical Bearings attach to the block in front of them", "create.ponder.mechanical_bearing.text_2": "UNLOCALIZED: Upon receiving Rotational Force, it will assemble it into a Rotating Contraption", + "create.ponder.mechanical_crafter.header": "UNLOCALIZED: Setting up Mechanical Crafters", + "create.ponder.mechanical_crafter.text_1": "UNLOCALIZED: An array of Mechanical Crafters can be used to automate any Crafting Recipe", + "create.ponder.mechanical_crafter.text_2": "UNLOCALIZED: Using a Wrench, the Crafters' paths can be arranged", + "create.ponder.mechanical_crafter.text_3": "UNLOCALIZED: For a valid setup, all paths have to converge into one exit at any side", + "create.ponder.mechanical_crafter.text_4": "UNLOCALIZED: The outputs will be placed into the inventory at the exit", + "create.ponder.mechanical_crafter.text_5": "UNLOCALIZED: Mechanical Crafters require Rotational Force to operate", + "create.ponder.mechanical_crafter.text_6": "UNLOCALIZED: Right-Click the front to insert Items manually", + "create.ponder.mechanical_crafter.text_7": "UNLOCALIZED: Once every slot of a path contains an Item, the crafting process will begin", + "create.ponder.mechanical_crafter.text_8": "UNLOCALIZED: For recipes not fully occupying the crafter setup, the start can be forced using a Redstone Pulse", + + "create.ponder.mechanical_crafter_connect.header": "UNLOCALIZED: Connecting Inventories of Crafters", + "create.ponder.mechanical_crafter_connect.text_1": "UNLOCALIZED: Items can be inserted to Crafters automatically", + "create.ponder.mechanical_crafter_connect.text_2": "UNLOCALIZED: Using the Wrench at their backs, Mechanical Crafter inputs can be combined", + "create.ponder.mechanical_crafter_connect.text_3": "UNLOCALIZED: All connected Crafters can now be accessed by the same input location", + + "create.ponder.mechanical_crafter_covers.header": "UNLOCALIZED: Covering slots of Mechanical Crafters", + "create.ponder.mechanical_crafter_covers.text_1": "UNLOCALIZED: Some recipes will require additional Crafters to bridge gaps in the path", + "create.ponder.mechanical_crafter_covers.text_2": "UNLOCALIZED: Using Slot Covers, Crafters can be set to act as an Empty Slot in the arrangement", + "create.ponder.mechanical_crafter_covers.text_3": "UNLOCALIZED: Shared Inputs created with the Wrench at the back can also reach across covered Crafters", + "create.ponder.mechanical_drill.header": "UNLOCALIZED: Breaking Blocks with the Mechanical Drill", "create.ponder.mechanical_drill.text_1": "UNLOCALIZED: When given Rotational Force, a Mechanical Drill will break blocks directly in front of it", "create.ponder.mechanical_drill.text_2": "UNLOCALIZED: Its mining speed depends on the Rotational Input", @@ -2298,6 +2361,16 @@ "create.ponder.rotation_speed_controller.text_1": "UNLOCALIZED: Rot. Speed Controllers relay rotation from their axis to a Large Cogwheel above them", "create.ponder.rotation_speed_controller.text_2": "UNLOCALIZED: Using the scroll input on its side, the conveyed speed can be configured", + "create.ponder.sail.header": "UNLOCALIZED: Assembling Windmills using Sails", + "create.ponder.sail.text_1": "UNLOCALIZED: Sails are handy blocks to create Windmills with", + "create.ponder.sail.text_2": "UNLOCALIZED: They will attach to blocks and each other without the need of Super Glue or Chassis Blocks", + "create.ponder.sail.text_3": "UNLOCALIZED: Right-Click with Dye to paint them", + "create.ponder.sail.text_4": "UNLOCALIZED: Right-Click with Shears to turn them back into frames", + + "create.ponder.sail_frame.header": "UNLOCALIZED: Assembling Windmills using Sail Frames", + "create.ponder.sail_frame.text_1": "UNLOCALIZED: Sail Frames are handy blocks to create Windmills with", + "create.ponder.sail_frame.text_2": "UNLOCALIZED: They will attach to blocks and each other without the need of Super Glue or Chassis Blocks", + "create.ponder.sequenced_gearshift.header": "UNLOCALIZED: Controlling Rotational Speed using Sequenced Gearshifts", "create.ponder.sequenced_gearshift.text_1": "UNLOCALIZED: Seq. Gearshifts relay rotation by following a timed list of instructions", "create.ponder.sequenced_gearshift.text_2": "UNLOCALIZED: Right-click it to open the Configuration UI", diff --git a/src/generated/resources/assets/create/lang/unfinished/zh_tw.json b/src/generated/resources/assets/create/lang/unfinished/zh_tw.json index e8d27316c..a0122693f 100644 --- a/src/generated/resources/assets/create/lang/unfinished/zh_tw.json +++ b/src/generated/resources/assets/create/lang/unfinished/zh_tw.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 497", + "_": "Missing Localizations: 560", "_": "->------------------------] Game Elements [------------------------<-", @@ -396,6 +396,7 @@ "block.create.weathered_limestone_cobblestone_stairs": "碎風化石灰岩樓梯", "block.create.weathered_limestone_cobblestone_wall": "碎風化石灰岩牆", "block.create.weathered_limestone_pillar": "豎紋風化石灰岩", + "block.create.weighted_ejector": "UNLOCALIZED: Weighted Ejector", "block.create.white_sail": "白色風帆", "block.create.white_seat": "白色坐墊", "block.create.white_valve_handle": "白色閥門開關", @@ -1084,6 +1085,12 @@ "create.mechanical_arm.summary": "機械手臂有%1$s 輸入以及 %2$s 輸出。", "create.mechanical_arm.points_outside_range": "%1$s 由於距離限制,選定的交互點被移除。", + "create.weighted_ejector.target_set": "UNLOCALIZED: Target Selected", + "create.weighted_ejector.target_not_valid": "UNLOCALIZED: Ejecting to Adjacent block (Target was not Valid)", + "create.weighted_ejector.no_target": "UNLOCALIZED: Ejecting to Adjacent block (No Target was Selected)", + "create.weighted_ejector.targeting": "UNLOCALIZED: Ejecting to [%1$s,%2$s,%3$s]", + "create.weighted_ejector.stack_size": "UNLOCALIZED: Ejected Stack Size", + "create.logistics.when_multiple_outputs_available": "當多個輸出可用時", "create.mechanical_arm.selection_mode.round_robin": "輪詢調度", @@ -1838,22 +1845,24 @@ "create.ponder.tag.contraption_actor.description": "UNLOCALIZED: Components which expose special behaviour when attached to a moving contraption", "create.ponder.tag.arm_targets": "UNLOCALIZED: Targets for Mechanical Arms", "create.ponder.tag.arm_targets.description": "UNLOCALIZED: Components which can be selected as inputs or outputs to the Mechanical Arm", - "create.ponder.tag.contraption_assembly": "UNLOCALIZED: Block Attachment Utility", - "create.ponder.tag.contraption_assembly.description": "UNLOCALIZED: Tools and Components used to assemble structures moved as an animated Contraption", "create.ponder.tag.logistics": "UNLOCALIZED: Item Transportation", "create.ponder.tag.logistics.description": "UNLOCALIZED: Components which help moving items around", "create.ponder.tag.movement_anchor": "UNLOCALIZED: Movement Anchors", "create.ponder.tag.movement_anchor.description": "UNLOCALIZED: Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways", + "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", + "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", + "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", + "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", + "create.ponder.tag.windmill_sails": "UNLOCALIZED: Sails for Windmill Bearings", + "create.ponder.tag.windmill_sails.description": "UNLOCALIZED: Blocks that count towards the strength of a Windmill Contraption when assembled. Each of these have equal efficiency in doing so.", + "create.ponder.tag.contraption_assembly": "UNLOCALIZED: Block Attachment Utility", + "create.ponder.tag.contraption_assembly.description": "UNLOCALIZED: Tools and Components used to assemble structures moved as an animated Contraption", "create.ponder.tag.decoration": "UNLOCALIZED: Aesthetics", "create.ponder.tag.decoration.description": "UNLOCALIZED: Components used mostly for decorative purposes", "create.ponder.tag.kinetic_appliances": "UNLOCALIZED: Kinetic Appliances", "create.ponder.tag.kinetic_appliances.description": "UNLOCALIZED: Components which make use of Rotational Force", "create.ponder.tag.redstone": "UNLOCALIZED: Logic Components", "create.ponder.tag.redstone.description": "UNLOCALIZED: Components which help with redstone engineering", - "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", - "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", - "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", - "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", "create.ponder.tag.fluids": "UNLOCALIZED: Fluid Manipulators", "create.ponder.tag.fluids.description": "UNLOCALIZED: Components which help relaying and making use of Fluids", @@ -2155,10 +2164,64 @@ "create.ponder.linear_chassis_group.text_2": "UNLOCALIZED: When one is moved by a Contraption, the others are dragged with it", "create.ponder.linear_chassis_group.text_3": "UNLOCALIZED: Chassis of a different type or facing another direction will not attach", + "create.ponder.mechanical_arm.header": "UNLOCALIZED: Setting up Mechanical Arms", + "create.ponder.mechanical_arm.text_1": "UNLOCALIZED: Mechanical Arms have to be assigned their in- and outputs before they are placed", + "create.ponder.mechanical_arm.text_2": "UNLOCALIZED: Right-Click inventories while holding the Arm to assign them as Targets", + "create.ponder.mechanical_arm.text_3": "UNLOCALIZED: Right-Click again to toggle between Input (Blue) and Output (Orange)", + "create.ponder.mechanical_arm.text_4": "UNLOCALIZED: Left-Click components to remove their Selection", + "create.ponder.mechanical_arm.text_5": "UNLOCALIZED: Once placed, the Mechanical Arm will target the blocks selected previously", + "create.ponder.mechanical_arm.text_6": "UNLOCALIZED: They can have any amount of in- and outputs within their range", + "create.ponder.mechanical_arm.text_7": "UNLOCALIZED: However, not every type of Inventory can be interacted with directly", + "create.ponder.mechanical_arm.text_8": "UNLOCALIZED: Funnels and Depots can help to Bridge that gap", + + "create.ponder.mechanical_arm_filtering.header": "UNLOCALIZED: Filtering Outputs of the Mechanical Arm", + "create.ponder.mechanical_arm_filtering.text_1": "UNLOCALIZED: Inputs", + "create.ponder.mechanical_arm_filtering.text_2": "UNLOCALIZED: Outputs", + "create.ponder.mechanical_arm_filtering.text_3": "UNLOCALIZED: Sometimes it is desirable to restrict targets of the Arm by matching a filter", + "create.ponder.mechanical_arm_filtering.text_4": "UNLOCALIZED: Mechanical Arms by themselves do not provide any options for filtering", + "create.ponder.mechanical_arm_filtering.text_5": "UNLOCALIZED: Brass Funnels as Targets do however communicate their own filter to the Arm", + "create.ponder.mechanical_arm_filtering.text_6": "UNLOCALIZED: The Arm is smart enough not to pick up items it couldn't distribute", + + "create.ponder.mechanical_arm_modes.header": "UNLOCALIZED: Distribution modes of the Mechanical Arm", + "create.ponder.mechanical_arm_modes.text_1": "UNLOCALIZED: Input", + "create.ponder.mechanical_arm_modes.text_2": "UNLOCALIZED: Outputs", + "create.ponder.mechanical_arm_modes.text_3": "UNLOCALIZED: Whenever an Arm has to choose between multiple valid outputs...", + "create.ponder.mechanical_arm_modes.text_4": "UNLOCALIZED: ...it will act according to its setting", + "create.ponder.mechanical_arm_modes.text_5": "UNLOCALIZED: Scrolling with a Wrench will allow you to configure it", + "create.ponder.mechanical_arm_modes.text_6": "UNLOCALIZED: Round Robin mode simply cycles through all outputs that are available", + "create.ponder.mechanical_arm_modes.text_7": "UNLOCALIZED: If an output is unable to take more items, it will be skipped", + "create.ponder.mechanical_arm_modes.text_8": "UNLOCALIZED: Forced Round Robin mode will never skip outputs, and instead wait until they are free", + "create.ponder.mechanical_arm_modes.text_9": "UNLOCALIZED: Prefer First prioritizes the outputs selected earliest when configuring this Arm", + + "create.ponder.mechanical_arm_redstone.header": "UNLOCALIZED: Controlling Mechanical Arms with Redstone", + "create.ponder.mechanical_arm_redstone.text_1": "UNLOCALIZED: When powered by Redstone, Mechanical Arms will not activate", + "create.ponder.mechanical_arm_redstone.text_2": "UNLOCALIZED: Before stopping, it will finish any started cycles", + "create.ponder.mechanical_arm_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.mechanical_bearing.header": "UNLOCALIZED: Movings Structures using the Mechanical Bearing", "create.ponder.mechanical_bearing.text_1": "UNLOCALIZED: Mechanical Bearings attach to the block in front of them", "create.ponder.mechanical_bearing.text_2": "UNLOCALIZED: Upon receiving Rotational Force, it will assemble it into a Rotating Contraption", + "create.ponder.mechanical_crafter.header": "UNLOCALIZED: Setting up Mechanical Crafters", + "create.ponder.mechanical_crafter.text_1": "UNLOCALIZED: An array of Mechanical Crafters can be used to automate any Crafting Recipe", + "create.ponder.mechanical_crafter.text_2": "UNLOCALIZED: Using a Wrench, the Crafters' paths can be arranged", + "create.ponder.mechanical_crafter.text_3": "UNLOCALIZED: For a valid setup, all paths have to converge into one exit at any side", + "create.ponder.mechanical_crafter.text_4": "UNLOCALIZED: The outputs will be placed into the inventory at the exit", + "create.ponder.mechanical_crafter.text_5": "UNLOCALIZED: Mechanical Crafters require Rotational Force to operate", + "create.ponder.mechanical_crafter.text_6": "UNLOCALIZED: Right-Click the front to insert Items manually", + "create.ponder.mechanical_crafter.text_7": "UNLOCALIZED: Once every slot of a path contains an Item, the crafting process will begin", + "create.ponder.mechanical_crafter.text_8": "UNLOCALIZED: For recipes not fully occupying the crafter setup, the start can be forced using a Redstone Pulse", + + "create.ponder.mechanical_crafter_connect.header": "UNLOCALIZED: Connecting Inventories of Crafters", + "create.ponder.mechanical_crafter_connect.text_1": "UNLOCALIZED: Items can be inserted to Crafters automatically", + "create.ponder.mechanical_crafter_connect.text_2": "UNLOCALIZED: Using the Wrench at their backs, Mechanical Crafter inputs can be combined", + "create.ponder.mechanical_crafter_connect.text_3": "UNLOCALIZED: All connected Crafters can now be accessed by the same input location", + + "create.ponder.mechanical_crafter_covers.header": "UNLOCALIZED: Covering slots of Mechanical Crafters", + "create.ponder.mechanical_crafter_covers.text_1": "UNLOCALIZED: Some recipes will require additional Crafters to bridge gaps in the path", + "create.ponder.mechanical_crafter_covers.text_2": "UNLOCALIZED: Using Slot Covers, Crafters can be set to act as an Empty Slot in the arrangement", + "create.ponder.mechanical_crafter_covers.text_3": "UNLOCALIZED: Shared Inputs created with the Wrench at the back can also reach across covered Crafters", + "create.ponder.mechanical_drill.header": "UNLOCALIZED: Breaking Blocks with the Mechanical Drill", "create.ponder.mechanical_drill.text_1": "UNLOCALIZED: When given Rotational Force, a Mechanical Drill will break blocks directly in front of it", "create.ponder.mechanical_drill.text_2": "UNLOCALIZED: Its mining speed depends on the Rotational Input", @@ -2298,6 +2361,16 @@ "create.ponder.rotation_speed_controller.text_1": "UNLOCALIZED: Rot. Speed Controllers relay rotation from their axis to a Large Cogwheel above them", "create.ponder.rotation_speed_controller.text_2": "UNLOCALIZED: Using the scroll input on its side, the conveyed speed can be configured", + "create.ponder.sail.header": "UNLOCALIZED: Assembling Windmills using Sails", + "create.ponder.sail.text_1": "UNLOCALIZED: Sails are handy blocks to create Windmills with", + "create.ponder.sail.text_2": "UNLOCALIZED: They will attach to blocks and each other without the need of Super Glue or Chassis Blocks", + "create.ponder.sail.text_3": "UNLOCALIZED: Right-Click with Dye to paint them", + "create.ponder.sail.text_4": "UNLOCALIZED: Right-Click with Shears to turn them back into frames", + + "create.ponder.sail_frame.header": "UNLOCALIZED: Assembling Windmills using Sail Frames", + "create.ponder.sail_frame.text_1": "UNLOCALIZED: Sail Frames are handy blocks to create Windmills with", + "create.ponder.sail_frame.text_2": "UNLOCALIZED: They will attach to blocks and each other without the need of Super Glue or Chassis Blocks", + "create.ponder.sequenced_gearshift.header": "UNLOCALIZED: Controlling Rotational Speed using Sequenced Gearshifts", "create.ponder.sequenced_gearshift.text_1": "UNLOCALIZED: Seq. Gearshifts relay rotation by following a timed list of instructions", "create.ponder.sequenced_gearshift.text_2": "UNLOCALIZED: Right-click it to open the Configuration UI", diff --git a/src/generated/resources/assets/create/models/item/weighted_ejector.json b/src/generated/resources/assets/create/models/item/weighted_ejector.json new file mode 100644 index 000000000..9d675525a --- /dev/null +++ b/src/generated/resources/assets/create/models/item/weighted_ejector.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/weighted_ejector/item" +} \ No newline at end of file diff --git a/src/generated/resources/data/create/advancements/aesthetics.json b/src/generated/resources/data/create/advancements/aesthetics.json index 59a86f429..d723cbe38 100644 --- a/src/generated/resources/data/create/advancements/aesthetics.json +++ b/src/generated/resources/data/create/advancements/aesthetics.json @@ -28,8 +28,8 @@ "trigger": "create:bracket_apply", "conditions": { "accepted_entries": [ - "create:large_cogwheel", - "create:cogwheel" + "create:cogwheel", + "create:large_cogwheel" ] } }, diff --git a/src/generated/resources/data/create/advancements/recipes/create.base/crafting/kinetics/weighted_ejector.json b/src/generated/resources/data/create/advancements/recipes/create.base/crafting/kinetics/weighted_ejector.json new file mode 100644 index 000000000..d88cdf3c4 --- /dev/null +++ b/src/generated/resources/data/create/advancements/recipes/create.base/crafting/kinetics/weighted_ejector.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "rewards": { + "recipes": [ + "create:crafting/kinetics/weighted_ejector" + ] + }, + "criteria": { + "has_item": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "create:andesite_casing" + } + ] + } + }, + "has_the_recipe": { + "trigger": "minecraft:recipe_unlocked", + "conditions": { + "recipe": "create:crafting/kinetics/weighted_ejector" + } + } + }, + "requirements": [ + [ + "has_item", + "has_the_recipe" + ] + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/loot_tables/blocks/weighted_ejector.json b/src/generated/resources/data/create/loot_tables/blocks/weighted_ejector.json new file mode 100644 index 000000000..4642af181 --- /dev/null +++ b/src/generated/resources/data/create/loot_tables/blocks/weighted_ejector.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "create:weighted_ejector" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/recipes/crafting/kinetics/weighted_ejector.json b/src/generated/resources/data/create/recipes/crafting/kinetics/weighted_ejector.json new file mode 100644 index 000000000..f1b065cd8 --- /dev/null +++ b/src/generated/resources/data/create/recipes/crafting/kinetics/weighted_ejector.json @@ -0,0 +1,22 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "A", + "D", + "I" + ], + "key": { + "A": { + "item": "create:golden_sheet" + }, + "D": { + "item": "create:depot" + }, + "I": { + "item": "create:cogwheel" + } + }, + "result": { + "item": "create:weighted_ejector" + } +} \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/AllBlockPartials.java b/src/main/java/com/simibubi/create/AllBlockPartials.java index 47cfd2963..f855246c5 100644 --- a/src/main/java/com/simibubi/create/AllBlockPartials.java +++ b/src/main/java/com/simibubi/create/AllBlockPartials.java @@ -123,6 +123,8 @@ public class AllBlockPartials { GOGGLES = get("goggles"), + EJECTOR_TOP = get("weighted_ejector/top"), + COUPLING_ATTACHMENT = getEntity("minecart_coupling/attachment"), COUPLING_RING = getEntity("minecart_coupling/ring"), COUPLING_CONNECTOR = getEntity("minecart_coupling/connector") diff --git a/src/main/java/com/simibubi/create/AllBlocks.java b/src/main/java/com/simibubi/create/AllBlocks.java index 8d936a3a9..35295937e 100644 --- a/src/main/java/com/simibubi/create/AllBlocks.java +++ b/src/main/java/com/simibubi/create/AllBlocks.java @@ -1,10 +1,29 @@ package com.simibubi.create; +import static com.simibubi.create.AllMovementBehaviours.addMovementBehaviour; +import static com.simibubi.create.AllTags.tagBlockAndItem; +import static com.simibubi.create.content.AllSections.SCHEMATICS; +import static com.simibubi.create.foundation.data.BlockStateGen.axisBlock; +import static com.simibubi.create.foundation.data.BlockStateGen.oxidizedBlockstate; +import static com.simibubi.create.foundation.data.CreateRegistrate.connectedTextures; +import static com.simibubi.create.foundation.data.ModelGen.customItemModel; +import static com.simibubi.create.foundation.data.ModelGen.oxidizedItemModel; + import com.simibubi.create.AllTags.AllBlockTags; import com.simibubi.create.AllTags.AllItemTags; import com.simibubi.create.content.AllSections; import com.simibubi.create.content.contraptions.base.CasingBlock; -import com.simibubi.create.content.contraptions.components.actors.*; +import com.simibubi.create.content.contraptions.components.actors.DrillBlock; +import com.simibubi.create.content.contraptions.components.actors.DrillMovementBehaviour; +import com.simibubi.create.content.contraptions.components.actors.HarvesterBlock; +import com.simibubi.create.content.contraptions.components.actors.HarvesterMovementBehaviour; +import com.simibubi.create.content.contraptions.components.actors.PloughBlock; +import com.simibubi.create.content.contraptions.components.actors.PloughMovementBehaviour; +import com.simibubi.create.content.contraptions.components.actors.PortableStorageInterfaceBlock; +import com.simibubi.create.content.contraptions.components.actors.PortableStorageInterfaceMovement; +import com.simibubi.create.content.contraptions.components.actors.SawMovementBehaviour; +import com.simibubi.create.content.contraptions.components.actors.SeatBlock; +import com.simibubi.create.content.contraptions.components.actors.SeatMovementBehaviour; import com.simibubi.create.content.contraptions.components.clock.CuckooClockBlock; import com.simibubi.create.content.contraptions.components.crafter.CrafterCTBehaviour; import com.simibubi.create.content.contraptions.components.crafter.MechanicalCrafterBlock; @@ -27,7 +46,11 @@ import com.simibubi.create.content.contraptions.components.motor.CreativeMotorGe import com.simibubi.create.content.contraptions.components.press.MechanicalPressBlock; import com.simibubi.create.content.contraptions.components.saw.SawBlock; import com.simibubi.create.content.contraptions.components.saw.SawGenerator; -import com.simibubi.create.content.contraptions.components.structureMovement.bearing.*; +import com.simibubi.create.content.contraptions.components.structureMovement.bearing.ClockworkBearingBlock; +import com.simibubi.create.content.contraptions.components.structureMovement.bearing.MechanicalBearingBlock; +import com.simibubi.create.content.contraptions.components.structureMovement.bearing.SailBlock; +import com.simibubi.create.content.contraptions.components.structureMovement.bearing.StabilizedBearingMovementBehaviour; +import com.simibubi.create.content.contraptions.components.structureMovement.bearing.WindmillBearingBlock; import com.simibubi.create.content.contraptions.components.structureMovement.chassis.LinearChassisBlock; import com.simibubi.create.content.contraptions.components.structureMovement.chassis.LinearChassisBlock.ChassisCTBehaviour; import com.simibubi.create.content.contraptions.components.structureMovement.chassis.RadialChassisBlock; @@ -50,7 +73,15 @@ import com.simibubi.create.content.contraptions.fluids.PumpBlock; import com.simibubi.create.content.contraptions.fluids.actors.HosePulleyBlock; import com.simibubi.create.content.contraptions.fluids.actors.ItemDrainBlock; import com.simibubi.create.content.contraptions.fluids.actors.SpoutBlock; -import com.simibubi.create.content.contraptions.fluids.pipes.*; +import com.simibubi.create.content.contraptions.fluids.pipes.BracketBlock; +import com.simibubi.create.content.contraptions.fluids.pipes.BracketBlockItem; +import com.simibubi.create.content.contraptions.fluids.pipes.BracketGenerator; +import com.simibubi.create.content.contraptions.fluids.pipes.EncasedPipeBlock; +import com.simibubi.create.content.contraptions.fluids.pipes.FluidPipeBlock; +import com.simibubi.create.content.contraptions.fluids.pipes.FluidValveBlock; +import com.simibubi.create.content.contraptions.fluids.pipes.GlassFluidPipeBlock; +import com.simibubi.create.content.contraptions.fluids.pipes.SmartFluidPipeBlock; +import com.simibubi.create.content.contraptions.fluids.pipes.SmartFluidPipeGenerator; import com.simibubi.create.content.contraptions.fluids.tank.FluidTankBlock; import com.simibubi.create.content.contraptions.fluids.tank.FluidTankGenerator; import com.simibubi.create.content.contraptions.fluids.tank.FluidTankItem; @@ -72,7 +103,13 @@ import com.simibubi.create.content.contraptions.relays.elementary.BracketedKinet import com.simibubi.create.content.contraptions.relays.elementary.CogWheelBlock; import com.simibubi.create.content.contraptions.relays.elementary.CogwheelBlockItem; import com.simibubi.create.content.contraptions.relays.elementary.ShaftBlock; -import com.simibubi.create.content.contraptions.relays.encased.*; +import com.simibubi.create.content.contraptions.relays.encased.AdjustablePulleyBlock; +import com.simibubi.create.content.contraptions.relays.encased.ClutchBlock; +import com.simibubi.create.content.contraptions.relays.encased.EncasedBeltBlock; +import com.simibubi.create.content.contraptions.relays.encased.EncasedBeltGenerator; +import com.simibubi.create.content.contraptions.relays.encased.EncasedCTBehaviour; +import com.simibubi.create.content.contraptions.relays.encased.EncasedShaftBlock; +import com.simibubi.create.content.contraptions.relays.encased.GearshiftBlock; import com.simibubi.create.content.contraptions.relays.gauge.GaugeBlock; import com.simibubi.create.content.contraptions.relays.gauge.GaugeGenerator; import com.simibubi.create.content.contraptions.relays.gearbox.GearboxBlock; @@ -84,23 +121,53 @@ import com.simibubi.create.content.logistics.block.chute.ChuteGenerator; import com.simibubi.create.content.logistics.block.chute.ChuteItem; import com.simibubi.create.content.logistics.block.chute.SmartChuteBlock; import com.simibubi.create.content.logistics.block.depot.DepotBlock; -import com.simibubi.create.content.logistics.block.diodes.*; -import com.simibubi.create.content.logistics.block.funnel.*; +import com.simibubi.create.content.logistics.block.depot.EjectorBlock; +import com.simibubi.create.content.logistics.block.depot.EjectorItem; +import com.simibubi.create.content.logistics.block.diodes.AbstractDiodeGenerator; +import com.simibubi.create.content.logistics.block.diodes.AdjustableRepeaterBlock; +import com.simibubi.create.content.logistics.block.diodes.AdjustableRepeaterGenerator; +import com.simibubi.create.content.logistics.block.diodes.PoweredLatchBlock; +import com.simibubi.create.content.logistics.block.diodes.PoweredLatchGenerator; +import com.simibubi.create.content.logistics.block.diodes.PulseRepeaterBlock; +import com.simibubi.create.content.logistics.block.diodes.PulseRepeaterGenerator; +import com.simibubi.create.content.logistics.block.diodes.ToggleLatchBlock; +import com.simibubi.create.content.logistics.block.diodes.ToggleLatchGenerator; +import com.simibubi.create.content.logistics.block.funnel.AndesiteFunnelBlock; +import com.simibubi.create.content.logistics.block.funnel.BeltFunnelBlock; +import com.simibubi.create.content.logistics.block.funnel.BeltFunnelGenerator; +import com.simibubi.create.content.logistics.block.funnel.BrassFunnelBlock; +import com.simibubi.create.content.logistics.block.funnel.FunnelGenerator; +import com.simibubi.create.content.logistics.block.funnel.FunnelItem; +import com.simibubi.create.content.logistics.block.funnel.FunnelMovementBehaviour; import com.simibubi.create.content.logistics.block.inventories.AdjustableCrateBlock; import com.simibubi.create.content.logistics.block.inventories.CreativeCrateBlock; import com.simibubi.create.content.logistics.block.mechanicalArm.ArmBlock; import com.simibubi.create.content.logistics.block.mechanicalArm.ArmItem; -import com.simibubi.create.content.logistics.block.redstone.*; +import com.simibubi.create.content.logistics.block.redstone.AnalogLeverBlock; +import com.simibubi.create.content.logistics.block.redstone.ContactMovementBehaviour; +import com.simibubi.create.content.logistics.block.redstone.ContentObserverBlock; +import com.simibubi.create.content.logistics.block.redstone.NixieTubeBlock; +import com.simibubi.create.content.logistics.block.redstone.NixieTubeGenerator; +import com.simibubi.create.content.logistics.block.redstone.RedstoneContactBlock; +import com.simibubi.create.content.logistics.block.redstone.RedstoneLinkBlock; +import com.simibubi.create.content.logistics.block.redstone.RedstoneLinkGenerator; +import com.simibubi.create.content.logistics.block.redstone.StockpileSwitchBlock; import com.simibubi.create.content.palettes.MetalBlock; import com.simibubi.create.content.schematics.block.SchematicTableBlock; import com.simibubi.create.content.schematics.block.SchematicannonBlock; import com.simibubi.create.foundation.block.ItemUseOverrides; import com.simibubi.create.foundation.config.StressConfigDefaults; -import com.simibubi.create.foundation.data.*; +import com.simibubi.create.foundation.data.AssetLookup; +import com.simibubi.create.foundation.data.BlockStateGen; +import com.simibubi.create.foundation.data.BuilderTransformers; +import com.simibubi.create.foundation.data.CreateRegistrate; +import com.simibubi.create.foundation.data.ModelGen; +import com.simibubi.create.foundation.data.SharedProperties; import com.simibubi.create.foundation.item.TooltipHelper; import com.simibubi.create.foundation.utility.DyeHelper; import com.simibubi.create.foundation.worldgen.OxidizingBlock; import com.tterrag.registrate.util.entry.BlockEntry; + import net.minecraft.block.Block; import net.minecraft.block.Blocks; import net.minecraft.block.SoundType; @@ -119,15 +186,6 @@ import net.minecraftforge.client.model.generators.ModelFile; import net.minecraftforge.common.Tags; import net.minecraftforge.common.ToolType; -import static com.simibubi.create.AllMovementBehaviours.addMovementBehaviour; -import static com.simibubi.create.AllTags.tagBlockAndItem; -import static com.simibubi.create.content.AllSections.SCHEMATICS; -import static com.simibubi.create.foundation.data.BlockStateGen.axisBlock; -import static com.simibubi.create.foundation.data.BlockStateGen.oxidizedBlockstate; -import static com.simibubi.create.foundation.data.CreateRegistrate.connectedTextures; -import static com.simibubi.create.foundation.data.ModelGen.customItemModel; -import static com.simibubi.create.foundation.data.ModelGen.oxidizedItemModel; - public class AllBlocks { private static final CreateRegistrate REGISTRATE = Create.registrate() @@ -422,6 +480,15 @@ public class AllBlocks { .item() .transform(customItemModel("_", "block")) .register(); + + public static final BlockEntry WEIGHTED_EJECTOR = REGISTRATE.block("weighted_ejector", EjectorBlock::new) + .initialProperties(SharedProperties::stone) + .properties(Block.Properties::nonOpaque) + .blockstate((c, p) -> p.horizontalBlock(c.getEntry(), AssetLookup.partialBaseModel(c, p), 180)) + .transform(StressConfigDefaults.setImpact(2.0)) + .item(EjectorItem::new) + .transform(customItemModel()) + .register(); public static final BlockEntry CHUTE = REGISTRATE.block("chute", ChuteBlock::new) .initialProperties(SharedProperties::softMetal) diff --git a/src/main/java/com/simibubi/create/AllTileEntities.java b/src/main/java/com/simibubi/create/AllTileEntities.java index 914ab8678..cbeb1f51b 100644 --- a/src/main/java/com/simibubi/create/AllTileEntities.java +++ b/src/main/java/com/simibubi/create/AllTileEntities.java @@ -1,7 +1,18 @@ package com.simibubi.create; -import com.simibubi.create.content.contraptions.base.*; -import com.simibubi.create.content.contraptions.components.actors.*; +import com.simibubi.create.content.contraptions.base.BackHalfShaftInstance; +import com.simibubi.create.content.contraptions.base.HalfShaftInstance; +import com.simibubi.create.content.contraptions.base.HorizontalHalfShaftInstance; +import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; +import com.simibubi.create.content.contraptions.base.SingleRotatingInstance; +import com.simibubi.create.content.contraptions.components.actors.DrillInstance; +import com.simibubi.create.content.contraptions.components.actors.DrillRenderer; +import com.simibubi.create.content.contraptions.components.actors.DrillTileEntity; +import com.simibubi.create.content.contraptions.components.actors.HarvesterRenderer; +import com.simibubi.create.content.contraptions.components.actors.HarvesterTileEntity; +import com.simibubi.create.content.contraptions.components.actors.PortableFluidInterfaceTileEntity; +import com.simibubi.create.content.contraptions.components.actors.PortableItemInterfaceTileEntity; +import com.simibubi.create.content.contraptions.components.actors.PortableStorageInterfaceRenderer; import com.simibubi.create.content.contraptions.components.clock.CuckooClockRenderer; import com.simibubi.create.content.contraptions.components.clock.CuckooClockTileEntity; import com.simibubi.create.content.contraptions.components.crafter.MechanicalCrafterInstance; @@ -60,8 +71,19 @@ import com.simibubi.create.content.contraptions.components.waterwheel.WaterWheel import com.simibubi.create.content.contraptions.fluids.PumpCogInstance; import com.simibubi.create.content.contraptions.fluids.PumpRenderer; import com.simibubi.create.content.contraptions.fluids.PumpTileEntity; -import com.simibubi.create.content.contraptions.fluids.actors.*; -import com.simibubi.create.content.contraptions.fluids.pipes.*; +import com.simibubi.create.content.contraptions.fluids.actors.HosePulleyRenderer; +import com.simibubi.create.content.contraptions.fluids.actors.HosePulleyTileEntity; +import com.simibubi.create.content.contraptions.fluids.actors.ItemDrainRenderer; +import com.simibubi.create.content.contraptions.fluids.actors.ItemDrainTileEntity; +import com.simibubi.create.content.contraptions.fluids.actors.SpoutRenderer; +import com.simibubi.create.content.contraptions.fluids.actors.SpoutTileEntity; +import com.simibubi.create.content.contraptions.fluids.pipes.FluidPipeTileEntity; +import com.simibubi.create.content.contraptions.fluids.pipes.FluidValveInstance; +import com.simibubi.create.content.contraptions.fluids.pipes.FluidValveRenderer; +import com.simibubi.create.content.contraptions.fluids.pipes.FluidValveTileEntity; +import com.simibubi.create.content.contraptions.fluids.pipes.SmartFluidPipeTileEntity; +import com.simibubi.create.content.contraptions.fluids.pipes.StraightPipeTileEntity; +import com.simibubi.create.content.contraptions.fluids.pipes.TransparentStraightPipeRenderer; import com.simibubi.create.content.contraptions.fluids.tank.CreativeFluidTankTileEntity; import com.simibubi.create.content.contraptions.fluids.tank.FluidTankRenderer; import com.simibubi.create.content.contraptions.fluids.tank.FluidTankTileEntity; @@ -77,7 +99,13 @@ import com.simibubi.create.content.contraptions.relays.belt.BeltInstance; import com.simibubi.create.content.contraptions.relays.belt.BeltRenderer; import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity; import com.simibubi.create.content.contraptions.relays.elementary.SimpleKineticTileEntity; -import com.simibubi.create.content.contraptions.relays.encased.*; +import com.simibubi.create.content.contraptions.relays.encased.AdjustablePulleyTileEntity; +import com.simibubi.create.content.contraptions.relays.encased.ClutchTileEntity; +import com.simibubi.create.content.contraptions.relays.encased.EncasedShaftRenderer; +import com.simibubi.create.content.contraptions.relays.encased.EncasedShaftTileEntity; +import com.simibubi.create.content.contraptions.relays.encased.ShaftInstance; +import com.simibubi.create.content.contraptions.relays.encased.SplitShaftInstance; +import com.simibubi.create.content.contraptions.relays.encased.SplitShaftRenderer; import com.simibubi.create.content.contraptions.relays.gauge.GaugeInstance; import com.simibubi.create.content.contraptions.relays.gauge.GaugeRenderer; import com.simibubi.create.content.contraptions.relays.gauge.SpeedGaugeTileEntity; @@ -96,6 +124,8 @@ import com.simibubi.create.content.logistics.block.chute.SmartChuteRenderer; import com.simibubi.create.content.logistics.block.chute.SmartChuteTileEntity; import com.simibubi.create.content.logistics.block.depot.DepotRenderer; import com.simibubi.create.content.logistics.block.depot.DepotTileEntity; +import com.simibubi.create.content.logistics.block.depot.EjectorRenderer; +import com.simibubi.create.content.logistics.block.depot.EjectorTileEntity; import com.simibubi.create.content.logistics.block.diodes.AdjustablePulseRepeaterTileEntity; import com.simibubi.create.content.logistics.block.diodes.AdjustableRepeaterInstance; import com.simibubi.create.content.logistics.block.diodes.AdjustableRepeaterRenderer; @@ -108,7 +138,14 @@ import com.simibubi.create.content.logistics.block.inventories.CreativeCrateTile import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInstance; import com.simibubi.create.content.logistics.block.mechanicalArm.ArmRenderer; import com.simibubi.create.content.logistics.block.mechanicalArm.ArmTileEntity; -import com.simibubi.create.content.logistics.block.redstone.*; +import com.simibubi.create.content.logistics.block.redstone.AnalogLeverInstance; +import com.simibubi.create.content.logistics.block.redstone.AnalogLeverRenderer; +import com.simibubi.create.content.logistics.block.redstone.AnalogLeverTileEntity; +import com.simibubi.create.content.logistics.block.redstone.ContentObserverTileEntity; +import com.simibubi.create.content.logistics.block.redstone.NixieTubeRenderer; +import com.simibubi.create.content.logistics.block.redstone.NixieTubeTileEntity; +import com.simibubi.create.content.logistics.block.redstone.RedstoneLinkTileEntity; +import com.simibubi.create.content.logistics.block.redstone.StockpileSwitchTileEntity; import com.simibubi.create.content.schematics.block.SchematicTableTileEntity; import com.simibubi.create.content.schematics.block.SchematicannonInstance; import com.simibubi.create.content.schematics.block.SchematicannonRenderer; @@ -578,6 +615,13 @@ public class AllTileEntities { .renderer(() -> DepotRenderer::new) .register(); + public static final TileEntityEntry WEIGHTED_EJECTOR = Create.registrate() + .tileEntity("weighted_ejector", EjectorTileEntity::new) + .instance(() -> ShaftInstance::new) + .validBlocks(AllBlocks.WEIGHTED_EJECTOR) + .renderer(() -> EjectorRenderer::new) + .register(); + public static final TileEntityEntry FUNNEL = Create.registrate() .tileEntity("funnel", FunnelTileEntity::new) .instance(() -> FunnelInstance::new) diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java index c0984e491..f38efb6fa 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java @@ -8,7 +8,6 @@ import java.util.List; import javax.annotation.Nullable; import com.simibubi.create.Create; -import com.simibubi.create.CreateClient; import com.simibubi.create.content.contraptions.KineticNetwork; import com.simibubi.create.content.contraptions.RotationPropagator; import com.simibubi.create.content.contraptions.base.IRotate.SpeedLevel; @@ -40,7 +39,6 @@ import net.minecraft.util.text.TextFormatting; import net.minecraft.world.World; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.fml.DistExecutor; public abstract class KineticTileEntity extends SmartTileEntity implements ITickableTileEntity, IHaveGoggleInformation, IHaveHoveringInformation, IInstanceRendered { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/mixer/BasinOperatorBlockItem.java b/src/main/java/com/simibubi/create/content/contraptions/components/mixer/BasinOperatorBlockItem.java index ae91c16c8..e6831212e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/mixer/BasinOperatorBlockItem.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/mixer/BasinOperatorBlockItem.java @@ -24,7 +24,7 @@ public class BasinOperatorBlockItem extends BlockItem { BlockState placedOnState = context.getWorld() .getBlockState(placedOnPos); if (AllBlocks.BASIN.has(placedOnState) || AllBlocks.BELT.has(placedOnState) - || AllBlocks.DEPOT.has(placedOnState)) { + || AllBlocks.DEPOT.has(placedOnState) || AllBlocks.WEIGHTED_EJECTOR.has(placedOnState)) { if (context.getWorld() .getBlockState(placedOnPos.up(2)) .getMaterial() diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawTileEntity.java index 3ad112e59..d6608fced 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawTileEntity.java @@ -150,7 +150,7 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity { if (stack.isEmpty()) continue; ItemStack tryExportingToBeltFunnel = getBehaviour(DirectBeltInputBehaviour.TYPE) - .tryExportingToBeltFunnel(stack, itemMovementFacing.getOpposite()); + .tryExportingToBeltFunnel(stack, itemMovementFacing.getOpposite(), false); if (tryExportingToBeltFunnel != null) { if (tryExportingToBeltFunnel.getCount() != stack.getCount()) { inventory.setStackInSlot(slot, tryExportingToBeltFunnel); diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/ItemDrainTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/ItemDrainTileEntity.java index 671202efb..b3dba75c2 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/ItemDrainTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/ItemDrainTileEntity.java @@ -128,7 +128,7 @@ public class ItemDrainTileEntity extends SmartTileEntity implements IHaveGoggleI Direction side = heldItem.insertedFrom; ItemStack tryExportingToBeltFunnel = getBehaviour(DirectBeltInputBehaviour.TYPE) - .tryExportingToBeltFunnel(heldItem.stack, side.getOpposite()); + .tryExportingToBeltFunnel(heldItem.stack, side.getOpposite(), false); if (tryExportingToBeltFunnel != null) { if (tryExportingToBeltFunnel.getCount() != heldItem.stack.getCount()) { if (tryExportingToBeltFunnel.isEmpty()) diff --git a/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelBlock.java b/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelBlock.java index bd24f2271..603bc3b20 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelBlock.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelBlock.java @@ -132,7 +132,7 @@ public class BeltTunnelBlock extends Block implements ITE, public void updateTunnel(IWorld world, BlockPos pos) { BlockState tunnel = world.getBlockState(pos); BlockState newTunnel = getTunnelState(world, pos); - if (tunnel != newTunnel) { + if (tunnel != newTunnel && !world.isRemote()) { world.setBlockState(pos, newTunnel, 3); TileEntity te = world.getTileEntity(pos); if (te != null && (te instanceof BeltTunnelTileEntity)) diff --git a/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelInstance.java b/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelInstance.java index 48f643efa..11f493dbb 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelInstance.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelInstance.java @@ -1,19 +1,24 @@ package com.simibubi.create.content.logistics.block.belts.tunnel; -import com.simibubi.create.AllBlockPartials; -import com.simibubi.create.content.contraptions.base.KineticRenderMaterials; -import com.simibubi.create.content.logistics.block.FlapData; -import com.simibubi.create.foundation.gui.widgets.InterpolatedValue; -import com.simibubi.create.foundation.render.backend.instancing.*; -import com.simibubi.create.foundation.utility.AnimationTickHolder; -import net.minecraft.util.Direction; -import net.minecraft.world.LightType; - import java.util.ArrayList; import java.util.Collection; import java.util.EnumMap; import java.util.Map; +import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.content.contraptions.base.KineticRenderMaterials; +import com.simibubi.create.content.logistics.block.FlapData; +import com.simibubi.create.foundation.gui.widgets.InterpolatedValue; +import com.simibubi.create.foundation.render.backend.instancing.IDynamicInstance; +import com.simibubi.create.foundation.render.backend.instancing.InstanceKey; +import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; +import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; +import com.simibubi.create.foundation.render.backend.instancing.TileEntityInstance; +import com.simibubi.create.foundation.utility.AnimationTickHolder; + +import net.minecraft.util.Direction; +import net.minecraft.world.LightType; + public class BeltTunnelInstance extends TileEntityInstance implements IDynamicInstance { private final Map>> tunnelFlaps; @@ -62,6 +67,11 @@ public class BeltTunnelInstance extends TileEntityInstance tunnelFlaps.put(direction, flaps); }); } + + @Override + public boolean shouldReset() { + return super.shouldReset() || tunnelFlaps.size() != tile.flaps.size(); + } @Override public void beginFrame() { diff --git a/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelTileEntity.java index 650edfba7..4bc4cf3b6 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelTileEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelTileEntity.java @@ -101,9 +101,9 @@ public class BeltTunnelTileEntity extends SmartTileEntity implements IInstanceRe // Backwards compat if (!compound.contains("Sides") && compound.contains("Flaps")) sides.addAll(flaps.keySet()); - + super.read(compound, clientPacket); - + if (clientPacket) DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> FastRenderDispatcher.enqueueUpdate(this)); } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BrassTunnelTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BrassTunnelTileEntity.java index cae6d2088..36c76bbe9 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BrassTunnelTileEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BrassTunnelTileEntity.java @@ -22,6 +22,7 @@ import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBe import com.simibubi.create.foundation.tileEntity.behaviour.filtering.SidedFilteringBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.INamedIconOptions; import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollOptionBehaviour; +import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.NBTHelper; @@ -55,11 +56,13 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity { ItemStack stackToDistribute; float distributionProgress; - List> distributionTargets; int distributionDistanceLeft; int distributionDistanceRight; int previousOutputIndex; + // + Couple>> distributionTargets; + private boolean syncedOutputActive; private Set syncSet; @@ -69,7 +72,7 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity { public BrassTunnelTileEntity(TileEntityType type) { super(type); - distributionTargets = new ArrayList<>(); + distributionTargets = Couple.create(ArrayList::new); syncSet = new HashSet<>(); stackToDistribute = ItemStack.EMPTY; beltCapability = LazyOptional.empty(); @@ -113,7 +116,7 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity { return; if (distributionProgress == -1) { - distributionTargets.clear(); + distributionTargets.forEach(List::clear); distributionDistanceLeft = 0; distributionDistanceRight = 0; @@ -137,27 +140,24 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity { if (stackToDistribute.isEmpty()) return; - for (boolean filterPass : Iterate.trueAndFalse) { - for (Pair pair : validOutputs) { - BrassTunnelTileEntity tunnel = pair.getKey(); - Direction output = pair.getValue(); - if (filterPass && tunnel.flapFilterEmpty(output)) - continue; - if (insertIntoTunnel(tunnel, output, stackToDistribute, true) == null) - continue; - distributionTargets.add(Pair.of(tunnel.pos, output)); - int distance = tunnel.pos.getX() + tunnel.pos.getZ() - pos.getX() - pos.getZ(); - if (distance < 0) - distributionDistanceLeft = Math.max(distributionDistanceLeft, -distance); - else - distributionDistanceRight = Math.max(distributionDistanceRight, distance); - } - - if (!distributionTargets.isEmpty() && filterPass) - break; + for (Pair pair : validOutputs) { + BrassTunnelTileEntity tunnel = pair.getKey(); + Direction output = pair.getValue(); + if (insertIntoTunnel(tunnel, output, stackToDistribute, true) == null) + continue; + distributionTargets.get(!tunnel.flapFilterEmpty(output)) + .add(Pair.of(tunnel.pos, output)); + int distance = tunnel.pos.getX() + tunnel.pos.getZ() - pos.getX() - pos.getZ(); + if (distance < 0) + distributionDistanceLeft = Math.max(distributionDistanceLeft, -distance); + else + distributionDistanceRight = Math.max(distributionDistanceRight, distance); } - if (distributionTargets.isEmpty()) + if (distributionTargets.getFirst() + .isEmpty() + && distributionTargets.getSecond() + .isEmpty()) return; if (selectionMode.get() != SelectionMode.SYNCHRONIZE || syncedOutputActive) { @@ -167,9 +167,14 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity { return; } - if (distributionProgress == 0) { + if (distributionProgress != 0) + return; + + distributionTargets.forEach(list -> { + if (stackToDistribute.isEmpty()) + return; List> validTargets = new ArrayList<>(); - for (Pair pair : distributionTargets) { + for (Pair pair : list) { BlockPos tunnelPos = pair.getKey(); Direction output = pair.getValue(); TileEntity te = world.getTileEntity(tunnelPos); @@ -177,18 +182,15 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity { continue; validTargets.add(Pair.of((BrassTunnelTileEntity) te, output)); } - distribute(validTargets); distributionProgress = -1; - return; - } - + }); } private static Random rand = new Random(); private void distribute(List> validTargets) { - final int amountTargets = validTargets.size(); + int amountTargets = validTargets.size(); if (amountTargets == 0) return; @@ -204,18 +206,23 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity { ItemStack toDistribute = null; int leftovers = 0; + int remainingOutputs = amountTargets; for (boolean simulate : Iterate.trueAndFalse) { + if (remainingOutputs == 0) + return; + leftovers = 0; int index = indexStart; int stackSize = stackToDistribute.getCount(); - int splitStackSize = stackSize / amountTargets; - int splitRemainder = stackSize % amountTargets; + int splitStackSize = stackSize / remainingOutputs; + int splitRemainder = stackSize % remainingOutputs; int visited = 0; toDistribute = stackToDistribute.copy(); - if (!force && simulate) + if (!(force || split) && simulate) continue; + while (visited < amountTargets) { Pair pair = validTargets.get(index); BrassTunnelTileEntity tunnel = pair.getKey(); @@ -230,6 +237,8 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity { if (remainder == null || remainder.getCount() == count) { if (force) return; + if (split && simulate) + remainingOutputs--; continue; } @@ -457,19 +466,22 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity { compound.putBoolean("SyncedOutput", syncedOutputActive); compound.putBoolean("ConnectedLeft", connectedLeft); compound.putBoolean("ConnectedRight", connectedRight); - compound.put("StackToDistribute", stackToDistribute.serializeNBT()); compound.putFloat("DistributionProgress", distributionProgress); compound.putInt("PreviousIndex", previousOutputIndex); compound.putInt("DistanceLeft", distributionDistanceLeft); compound.putInt("DistanceRight", distributionDistanceRight); - compound.put("Targets", NBTHelper.writeCompoundList(distributionTargets, pair -> { - CompoundNBT nbt = new CompoundNBT(); - nbt.put("Pos", NBTUtil.writeBlockPos(pair.getKey())); - nbt.putInt("Face", pair.getValue() - .getIndex()); - return nbt; - })); + + for (boolean filtered : Iterate.trueAndFalse) { + compound.put(filtered ? "FilteredTargets" : "Targets", + NBTHelper.writeCompoundList(distributionTargets.get(filtered), pair -> { + CompoundNBT nbt = new CompoundNBT(); + nbt.put("Pos", NBTUtil.writeBlockPos(pair.getKey())); + nbt.putInt("Face", pair.getValue() + .getIndex()); + return nbt; + })); + } super.write(compound, clientPacket); } @@ -487,11 +499,15 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity { previousOutputIndex = compound.getInt("PreviousIndex"); distributionDistanceLeft = compound.getInt("DistanceLeft"); distributionDistanceRight = compound.getInt("DistanceRight"); - distributionTargets = NBTHelper.readCompoundList(compound.getList("Targets", NBT.TAG_COMPOUND), nbt -> { - BlockPos pos = NBTUtil.readBlockPos(nbt.getCompound("Pos")); - Direction face = Direction.byIndex(nbt.getInt("Face")); - return Pair.of(pos, face); - }); + + for (boolean filtered : Iterate.trueAndFalse) { + distributionTargets.set(filtered, NBTHelper + .readCompoundList(compound.getList(filtered ? "FilteredTargets" : "Targets", NBT.TAG_COMPOUND), nbt -> { + BlockPos pos = NBTUtil.readBlockPos(nbt.getCompound("Pos")); + Direction face = Direction.byIndex(nbt.getInt("Face")); + return Pair.of(pos, face); + })); + } super.read(compound, clientPacket); diff --git a/src/main/java/com/simibubi/create/content/logistics/block/depot/DepotBehaviour.java b/src/main/java/com/simibubi/create/content/logistics/block/depot/DepotBehaviour.java new file mode 100644 index 000000000..f79ef2fe2 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/block/depot/DepotBehaviour.java @@ -0,0 +1,379 @@ +package com.simibubi.create.content.logistics.block.depot; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.Supplier; + +import com.simibubi.create.content.contraptions.relays.belt.BeltHelper; +import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack; +import com.simibubi.create.content.logistics.block.funnel.AbstractFunnelBlock; +import com.simibubi.create.foundation.tileEntity.SmartTileEntity; +import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; +import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType; +import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour; +import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour.ProcessingResult; +import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour; +import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour; +import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour.TransportedResult; +import com.simibubi.create.foundation.utility.NBTHelper; +import com.simibubi.create.foundation.utility.VecHelper; + +import net.minecraft.block.BlockState; +import net.minecraft.inventory.InventoryHelper; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.nbt.ListNBT; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.util.Constants.NBT; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.items.ItemHandlerHelper; +import net.minecraftforge.items.ItemStackHandler; + +public class DepotBehaviour extends TileEntityBehaviour { + + public static BehaviourType TYPE = new BehaviourType<>(); + + TransportedItemStack heldItem; + List incoming; + ItemStackHandler processingOutputBuffer; + DepotItemHandler itemHandler; + LazyOptional lazyItemHandler; + TransportedItemStackHandlerBehaviour transportedHandler; + Supplier maxStackSize; + Supplier canAcceptItems; + Predicate canFunnelsPullFrom; + boolean allowMerge; + + public DepotBehaviour(SmartTileEntity te) { + super(te); + maxStackSize = () -> 64; + canAcceptItems = () -> true; + canFunnelsPullFrom = $ -> true; + incoming = new ArrayList<>(); + itemHandler = new DepotItemHandler(this); + lazyItemHandler = LazyOptional.of(() -> itemHandler); + processingOutputBuffer = new ItemStackHandler(8) { + protected void onContentsChanged(int slot) { + te.notifyUpdate(); + }; + }; + } + + public void enableMerging() { + allowMerge = true; + } + + @Override + public void tick() { + super.tick(); + + World world = tileEntity.getWorld(); + + for (Iterator iterator = incoming.iterator(); iterator.hasNext();) { + TransportedItemStack ts = iterator.next(); + if (!tick(ts)) + continue; + if (world.isRemote) + continue; + if (heldItem == null) { + heldItem = ts; + } else { + if (!ItemHandlerHelper.canItemStacksStack(heldItem.stack, ts.stack)) { + Vec3d vec = VecHelper.getCenterOf(tileEntity.getPos()); + InventoryHelper.spawnItemStack(tileEntity.getWorld(), vec.x, vec.y + .5f, vec.z, ts.stack); + } else { + heldItem.stack.grow(ts.stack.getCount()); + } + } + iterator.remove(); + tileEntity.notifyUpdate(); + } + + if (heldItem == null) + return; + if (!tick(heldItem)) + return; + + BlockPos pos = tileEntity.getPos(); + + if (world.isRemote) + return; + if (handleBeltFunnelOutput()) + return; + + BeltProcessingBehaviour processingBehaviour = + TileEntityBehaviour.get(world, pos.up(2), BeltProcessingBehaviour.TYPE); + if (processingBehaviour == null) + return; + if (!heldItem.locked && BeltProcessingBehaviour.isBlocked(world, pos)) + return; + + ItemStack previousItem = heldItem.stack; + boolean wasLocked = heldItem.locked; + ProcessingResult result = wasLocked ? processingBehaviour.handleHeldItem(heldItem, transportedHandler) + : processingBehaviour.handleReceivedItem(heldItem, transportedHandler); + if (result == ProcessingResult.REMOVE) { + heldItem = null; + tileEntity.sendData(); + return; + } + + heldItem.locked = result == ProcessingResult.HOLD; + if (heldItem.locked != wasLocked || !previousItem.equals(heldItem.stack, false)) + tileEntity.sendData(); + } + + protected boolean tick(TransportedItemStack heldItem) { + heldItem.prevBeltPosition = heldItem.beltPosition; + heldItem.prevSideOffset = heldItem.sideOffset; + float diff = .5f - heldItem.beltPosition; + if (diff > 1 / 512f) { + if (diff > 1 / 32f && !BeltHelper.isItemUpright(heldItem.stack)) + heldItem.angle += 1; + heldItem.beltPosition += diff / 4f; + } + return diff < 1 / 16f; + } + + private boolean handleBeltFunnelOutput() { + BlockState funnel = getWorld().getBlockState(getPos().up()); + Direction funnelFacing = AbstractFunnelBlock.getFunnelFacing(funnel); + if (funnelFacing == null || !canFunnelsPullFrom.test(funnelFacing.getOpposite())) + return false; + + for (int slot = 0; slot < processingOutputBuffer.getSlots(); slot++) { + ItemStack previousItem = processingOutputBuffer.getStackInSlot(slot); + if (previousItem.isEmpty()) + continue; + ItemStack afterInsert = tileEntity.getBehaviour(DirectBeltInputBehaviour.TYPE) + .tryExportingToBeltFunnel(previousItem, null, false); + if (afterInsert == null) + return false; + if (previousItem.getCount() != afterInsert.getCount()) { + processingOutputBuffer.setStackInSlot(slot, afterInsert); + tileEntity.notifyUpdate(); + return true; + } + } + + ItemStack previousItem = heldItem.stack; + ItemStack afterInsert = tileEntity.getBehaviour(DirectBeltInputBehaviour.TYPE) + .tryExportingToBeltFunnel(previousItem, null, false); + if (afterInsert == null) + return false; + if (previousItem.getCount() != afterInsert.getCount()) { + if (afterInsert.isEmpty()) + heldItem = null; + else + heldItem.stack = afterInsert; + tileEntity.notifyUpdate(); + return true; + } + + return false; + } + + @Override + public void remove() { + if (lazyItemHandler != null) + lazyItemHandler.invalidate(); + } + + @Override + public void write(CompoundNBT compound, boolean clientPacket) { + if (heldItem != null) + compound.put("HeldItem", heldItem.serializeNBT()); + compound.put("OutputBuffer", processingOutputBuffer.serializeNBT()); + if (canMergeItems() && !incoming.isEmpty()) + compound.put("Incoming", NBTHelper.writeCompoundList(incoming, TransportedItemStack::serializeNBT)); + } + + @Override + public void read(CompoundNBT compound, boolean clientPacket) { + heldItem = null; + if (compound.contains("HeldItem")) + heldItem = TransportedItemStack.read(compound.getCompound("HeldItem")); + processingOutputBuffer.deserializeNBT(compound.getCompound("OutputBuffer")); + if (canMergeItems()) { + ListNBT list = compound.getList("Incoming", NBT.TAG_COMPOUND); + incoming = NBTHelper.readCompoundList(list, TransportedItemStack::read); + } + } + + public void addSubBehaviours(List behaviours) { + behaviours.add(new DirectBeltInputBehaviour(tileEntity).allowingBeltFunnels() + .setInsertionHandler(this::tryInsertingFromSide)); + transportedHandler = new TransportedItemStackHandlerBehaviour(tileEntity, this::applyToAllItems) + .withStackPlacement(this::getWorldPositionOf); + behaviours.add(transportedHandler); + } + + public ItemStack getHeldItemStack() { + return heldItem == null ? ItemStack.EMPTY : heldItem.stack; + } + + public boolean canMergeItems() { + return allowMerge; + } + + public int getPresentStackSize() { + int cumulativeStackSize = 0; + cumulativeStackSize += getHeldItemStack().getCount(); + for (int slot = 0; slot < processingOutputBuffer.getSlots(); slot++) + cumulativeStackSize += processingOutputBuffer.getStackInSlot(slot) + .getCount(); + return cumulativeStackSize; + } + + public int getRemainingSpace() { + int cumulativeStackSize = getPresentStackSize(); + for (TransportedItemStack transportedItemStack : incoming) + cumulativeStackSize += transportedItemStack.stack.getCount(); + int fromGetter = maxStackSize.get(); + return (fromGetter == 0 ? 64 : fromGetter) - cumulativeStackSize; + } + + public ItemStack insert(TransportedItemStack heldItem, boolean simulate) { + if (!canAcceptItems.get()) + return heldItem.stack; + + if (canMergeItems()) { + int remainingSpace = getRemainingSpace(); + ItemStack inserted = heldItem.stack; + if (remainingSpace <= 0) + return inserted; + if (this.heldItem != null && !ItemHandlerHelper.canItemStacksStack(this.heldItem.stack, inserted)) + return inserted; + + ItemStack returned = ItemStack.EMPTY; + if (remainingSpace < inserted.getCount()) { + returned = ItemHandlerHelper.copyStackWithSize(heldItem.stack, inserted.getCount() - remainingSpace); + if (!simulate) { + TransportedItemStack copy = heldItem.copy(); + copy.stack.setCount(remainingSpace); + if (this.heldItem != null) + incoming.add(copy); + else + this.heldItem = copy; + } + } else { + if (!simulate) { + if (this.heldItem != null) + incoming.add(heldItem); + else + this.heldItem = heldItem; + } + } + return returned; + } + + if (!simulate) + this.heldItem = heldItem; + return ItemStack.EMPTY; + } + + public void setHeldItem(TransportedItemStack heldItem) { + this.heldItem = heldItem; + } + + public void removeHeldItem() { + this.heldItem = null; + } + + public void setCenteredHeldItem(TransportedItemStack heldItem) { + this.heldItem = heldItem; + this.heldItem.beltPosition = 0.5f; + this.heldItem.prevBeltPosition = 0.5f; + } + + public LazyOptional getItemCapability(Capability cap, Direction side) { + return lazyItemHandler.cast(); + } + + private ItemStack tryInsertingFromSide(TransportedItemStack transportedStack, Direction side, boolean simulate) { + ItemStack inserted = transportedStack.stack; + + if (!getHeldItemStack().isEmpty() && !canMergeItems()) + return inserted; + if (!isOutputEmpty() && !canMergeItems()) + return inserted; + if (!canAcceptItems.get()) + return inserted; + + int size = transportedStack.stack.getCount(); + transportedStack = transportedStack.copy(); + transportedStack.beltPosition = side.getAxis() + .isVertical() ? .5f : 0; + transportedStack.insertedFrom = side; + transportedStack.prevSideOffset = transportedStack.sideOffset; + transportedStack.prevBeltPosition = transportedStack.beltPosition; + ItemStack remainder = insert(transportedStack, simulate); + if (remainder.getCount() != size) + tileEntity.notifyUpdate(); + + return remainder; + } + + private void applyToAllItems(float maxDistanceFromCentre, + Function processFunction) { + if (heldItem == null) + return; + if (.5f - heldItem.beltPosition > maxDistanceFromCentre) + return; + + boolean dirty = false; + TransportedItemStack transportedItemStack = heldItem; + ItemStack stackBefore = transportedItemStack.stack.copy(); + TransportedResult result = processFunction.apply(transportedItemStack); + if (result == null || result.didntChangeFrom(stackBefore)) + return; + + dirty = true; + heldItem = null; + if (result.hasHeldOutput()) + setCenteredHeldItem(result.getHeldOutput()); + + for (TransportedItemStack added : result.getOutputs()) { + if (getHeldItemStack().isEmpty()) { + setCenteredHeldItem(added); + continue; + } + ItemStack remainder = ItemHandlerHelper.insertItemStacked(processingOutputBuffer, added.stack, false); + Vec3d vec = VecHelper.getCenterOf(tileEntity.getPos()); + InventoryHelper.spawnItemStack(tileEntity.getWorld(), vec.x, vec.y + .5f, vec.z, remainder); + } + + if (dirty) + tileEntity.notifyUpdate(); + } + + public boolean isEmpty() { + return heldItem == null && isOutputEmpty(); + } + + public boolean isOutputEmpty() { + for (int i = 0; i < processingOutputBuffer.getSlots(); i++) + if (!processingOutputBuffer.getStackInSlot(i) + .isEmpty()) + return false; + return true; + } + + private Vec3d getWorldPositionOf(TransportedItemStack transported) { + Vec3d offsetVec = new Vec3d(.5f, 14 / 16f, .5f); + return offsetVec.add(new Vec3d(tileEntity.getPos())); + } + + @Override + public BehaviourType getType() { + return TYPE; + } + +} diff --git a/src/main/java/com/simibubi/create/content/logistics/block/depot/DepotBlock.java b/src/main/java/com/simibubi/create/content/logistics/block/depot/DepotBlock.java index e86919e81..6b341c902 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/depot/DepotBlock.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/depot/DepotBlock.java @@ -2,27 +2,18 @@ package com.simibubi.create.content.logistics.block.depot; import javax.annotation.ParametersAreNonnullByDefault; -import com.simibubi.create.AllBlocks; import com.simibubi.create.AllShapes; import com.simibubi.create.AllTileEntities; -import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack; import com.simibubi.create.content.contraptions.wrench.IWrenchable; import com.simibubi.create.foundation.block.ITE; -import com.simibubi.create.foundation.item.ItemHelper; -import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; -import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour; import mcp.MethodsReturnNonnullByDefault; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; -import net.minecraft.entity.item.ItemEntity; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.inventory.InventoryHelper; -import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ActionResultType; -import net.minecraft.util.Direction; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockRayTraceResult; @@ -30,8 +21,6 @@ import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.world.IBlockReader; import net.minecraft.world.World; -import net.minecraftforge.items.ItemStackHandler; - @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault @@ -65,74 +54,18 @@ public class DepotBlock extends Block implements ITE, IWrenchab @Override public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult ray) { - if (ray.getFace() != Direction.UP) - return ActionResultType.PASS; - if (world.isRemote) - return ActionResultType.SUCCESS; - - withTileEntityDo(world, pos, te -> { - ItemStack heldItem = player.getHeldItem(hand); - boolean wasEmptyHanded = heldItem.isEmpty(); - boolean shouldntPlaceItem = AllBlocks.MECHANICAL_ARM.isIn(heldItem); - - ItemStack mainItemStack = te.getHeldItemStack(); - if (!mainItemStack.isEmpty()) { - player.inventory.placeItemBackInInventory(world, mainItemStack); - te.setHeldItem(null); - } - ItemStackHandler outputs = te.processingOutputBuffer; - for (int i = 0; i < outputs.getSlots(); i++) - player.inventory.placeItemBackInInventory(world, outputs.extractItem(i, 64, false)); - - if (!wasEmptyHanded && !shouldntPlaceItem) { - TransportedItemStack transported = new TransportedItemStack(heldItem); - transported.insertedFrom = player.getHorizontalFacing(); - transported.prevBeltPosition = .25f; - transported.beltPosition = .25f; - te.setHeldItem(transported); - player.setHeldItem(hand, ItemStack.EMPTY); - } - - te.markDirty(); - te.sendData(); - }); - - return ActionResultType.SUCCESS; + return SharedDepotBlockMethods.onUse(state, world, pos, player, hand, ray); } @Override public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) { - if (!state.hasTileEntity() || state.getBlock() == newState.getBlock()) - return; - withTileEntityDo(worldIn, pos, te -> { - ItemHelper.dropContents(worldIn, pos, te.processingOutputBuffer); - if (!te.getHeldItemStack() - .isEmpty()) - InventoryHelper.spawnItemStack(worldIn, pos.getX(), pos.getY(), pos.getZ(), te.getHeldItemStack()); - }); - worldIn.removeTileEntity(pos); + SharedDepotBlockMethods.onReplaced(state, worldIn, pos, newState, isMoving); } @Override public void onLanded(IBlockReader worldIn, Entity entityIn) { super.onLanded(worldIn, entityIn); - if (!AllBlocks.DEPOT.has(worldIn.getBlockState(entityIn.getPosition()))) - return; - if (!(entityIn instanceof ItemEntity)) - return; - if (!entityIn.isAlive()) - return; - if (entityIn.world.isRemote) - return; - ItemEntity itemEntity = (ItemEntity) entityIn; - DirectBeltInputBehaviour inputBehaviour = - TileEntityBehaviour.get(worldIn, entityIn.getPosition(), DirectBeltInputBehaviour.TYPE); - if (inputBehaviour == null) - return; - ItemStack remainder = inputBehaviour.handleInsertion(itemEntity.getItem(), Direction.DOWN, false); - itemEntity.setItem(remainder); - if (remainder.isEmpty()) - itemEntity.remove(); + SharedDepotBlockMethods.onLanded(worldIn, entityIn); } @Override @@ -142,11 +75,7 @@ public class DepotBlock extends Block implements ITE, IWrenchab @Override public int getComparatorInputOverride(BlockState blockState, World worldIn, BlockPos pos) { - try { - return ItemHelper.calcRedstoneFromInventory(getTileEntity(worldIn, pos).itemHandler); - } catch (TileEntityException ignored) { - } - return 0; + return SharedDepotBlockMethods.getComparatorInputOverride(blockState, worldIn, pos); } } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/depot/DepotItemHandler.java b/src/main/java/com/simibubi/create/content/logistics/block/depot/DepotItemHandler.java index c67813496..cfa588a2a 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/depot/DepotItemHandler.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/depot/DepotItemHandler.java @@ -8,9 +8,9 @@ import net.minecraftforge.items.IItemHandler; public class DepotItemHandler implements IItemHandler { private static final int MAIN_SLOT = 0; - private DepotTileEntity te; + private DepotBehaviour te; - public DepotItemHandler(DepotTileEntity te) { + public DepotItemHandler(DepotBehaviour te) { this.te = te; } @@ -29,16 +29,15 @@ public class DepotItemHandler implements IItemHandler { if (slot != MAIN_SLOT) return stack; if (!te.getHeldItemStack() - .isEmpty()) + .isEmpty() && !te.canMergeItems()) return stack; - if (!te.isOutputEmpty()) + if (!te.isOutputEmpty() && !te.canMergeItems()) return stack; - if (!simulate) { - te.setHeldItem(new TransportedItemStack(stack)); - te.markDirty(); - te.sendData(); - } - return ItemStack.EMPTY; + + ItemStack remainder = te.insert(new TransportedItemStack(stack), simulate); + if (!simulate && remainder != stack) + te.tileEntity.notifyUpdate(); + return remainder; } @Override @@ -55,15 +54,14 @@ public class DepotItemHandler implements IItemHandler { te.heldItem.stack = stack; if (stack.isEmpty()) te.heldItem = null; - te.markDirty(); - te.sendData(); + te.tileEntity.notifyUpdate(); } return extracted; } @Override public int getSlotLimit(int slot) { - return 64; + return slot == MAIN_SLOT ? te.maxStackSize.get() : 64; } @Override diff --git a/src/main/java/com/simibubi/create/content/logistics/block/depot/DepotRenderer.java b/src/main/java/com/simibubi/create/content/logistics/block/depot/DepotRenderer.java index 636f0c585..34e801c55 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/depot/DepotRenderer.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/depot/DepotRenderer.java @@ -5,6 +5,7 @@ import java.util.Random; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.content.contraptions.relays.belt.BeltHelper; import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack; +import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; import com.simibubi.create.foundation.utility.MatrixStacker; import com.simibubi.create.foundation.utility.VecHelper; @@ -30,43 +31,54 @@ public class DepotRenderer extends SafeTileEntityRenderer { @Override protected void renderSafe(DepotTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) { + renderItemsOf(te, partialTicks, ms, buffer, light, overlay, te.depotBehaviour); + } - TransportedItemStack transported = te.heldItem; + public static void renderItemsOf(SmartTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, + int light, int overlay, DepotBehaviour depotBehaviour) { + + TransportedItemStack transported = depotBehaviour.heldItem; MatrixStacker msr = MatrixStacker.of(ms); Vec3d itemPosition = VecHelper.getCenterOf(te.getPos()); ms.push(); ms.translate(.5f, 15 / 16f, .5f); - // Render main item - if (transported != null) { + if (transported != null) + depotBehaviour.incoming.add(transported); + + // Render main items + for (TransportedItemStack tis : depotBehaviour.incoming) { ms.push(); msr.nudge(0); - float offset = MathHelper.lerp(partialTicks, transported.prevBeltPosition, transported.beltPosition); - float sideOffset = MathHelper.lerp(partialTicks, transported.prevSideOffset, transported.sideOffset); + float offset = MathHelper.lerp(partialTicks, tis.prevBeltPosition, tis.beltPosition); + float sideOffset = MathHelper.lerp(partialTicks, tis.prevSideOffset, tis.sideOffset); - if (transported.insertedFrom.getAxis() + if (tis.insertedFrom.getAxis() .isHorizontal()) { - Vec3d offsetVec = new Vec3d(transported.insertedFrom.getOpposite() + Vec3d offsetVec = new Vec3d(tis.insertedFrom.getOpposite() .getDirectionVec()).scale(.5f - offset); ms.translate(offsetVec.x, offsetVec.y, offsetVec.z); - boolean alongX = transported.insertedFrom.rotateY() + boolean alongX = tis.insertedFrom.rotateY() .getAxis() == Axis.X; if (!alongX) sideOffset *= -1; ms.translate(alongX ? sideOffset : 0, 0, alongX ? 0 : sideOffset); } - ItemStack itemStack = transported.stack; - int angle = transported.angle; + ItemStack itemStack = tis.stack; + int angle = tis.angle; Random r = new Random(0); renderItem(ms, buffer, light, overlay, itemStack, angle, r, itemPosition); ms.pop(); } + if (transported != null) + depotBehaviour.incoming.remove(transported); + // Render output items - for (int i = 0; i < te.processingOutputBuffer.getSlots(); i++) { - ItemStack stack = te.processingOutputBuffer.getStackInSlot(i); + for (int i = 0; i < depotBehaviour.processingOutputBuffer.getSlots(); i++) { + ItemStack stack = depotBehaviour.processingOutputBuffer.getStackInSlot(i); if (stack.isEmpty()) continue; ms.push(); diff --git a/src/main/java/com/simibubi/create/content/logistics/block/depot/DepotTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/depot/DepotTileEntity.java index bc0f5ade9..1c6187d44 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/depot/DepotTileEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/depot/DepotTileEntity.java @@ -1,253 +1,35 @@ package com.simibubi.create.content.logistics.block.depot; import java.util.List; -import java.util.function.Function; -import com.simibubi.create.content.contraptions.relays.belt.BeltHelper; -import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack; import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; -import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour; -import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour.ProcessingResult; -import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour; -import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour; -import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour.TransportedResult; -import com.simibubi.create.foundation.utility.VecHelper; -import net.minecraft.inventory.InventoryHelper; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; -import net.minecraft.util.math.Vec3d; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.items.CapabilityItemHandler; -import net.minecraftforge.items.ItemHandlerHelper; -import net.minecraftforge.items.ItemStackHandler; public class DepotTileEntity extends SmartTileEntity { - TransportedItemStack heldItem; - ItemStackHandler processingOutputBuffer; - - DepotItemHandler itemHandler; - LazyOptional lazyItemHandler; - private TransportedItemStackHandlerBehaviour transportedHandler; + DepotBehaviour depotBehaviour; public DepotTileEntity(TileEntityType tileEntityTypeIn) { super(tileEntityTypeIn); - itemHandler = new DepotItemHandler(this); - lazyItemHandler = LazyOptional.of(() -> itemHandler); - processingOutputBuffer = new ItemStackHandler(8) { - protected void onContentsChanged(int slot) { - markDirty(); - sendData(); - }; - }; - } - - @Override - public void tick() { - super.tick(); - if (heldItem == null) - return; - - heldItem.prevBeltPosition = heldItem.beltPosition; - heldItem.prevSideOffset = heldItem.sideOffset; - float diff = .5f - heldItem.beltPosition; - if (diff > 1 / 512f) { - if (diff > 1 / 32f && !BeltHelper.isItemUpright(heldItem.stack)) - heldItem.angle += 1; - heldItem.beltPosition += diff / 4f; - } - - if (diff > 1 / 16f) - return; - if (world.isRemote) - return; - if (handleBeltFunnelOutput()) - return; - - BeltProcessingBehaviour processingBehaviour = - TileEntityBehaviour.get(world, pos.up(2), BeltProcessingBehaviour.TYPE); - if (processingBehaviour == null) - return; - if (!heldItem.locked && BeltProcessingBehaviour.isBlocked(world, pos)) - return; - - ItemStack previousItem = heldItem.stack; - boolean wasLocked = heldItem.locked; - ProcessingResult result = wasLocked ? processingBehaviour.handleHeldItem(heldItem, transportedHandler) - : processingBehaviour.handleReceivedItem(heldItem, transportedHandler); - if (result == ProcessingResult.REMOVE) { - heldItem = null; - sendData(); - return; - } - - heldItem.locked = result == ProcessingResult.HOLD; - if (heldItem.locked != wasLocked || !previousItem.equals(heldItem.stack, false)) - sendData(); - } - - private boolean handleBeltFunnelOutput() { - for (int slot = 0; slot < processingOutputBuffer.getSlots(); slot++) { - ItemStack previousItem = processingOutputBuffer.getStackInSlot(slot); - if (previousItem.isEmpty()) - continue; - ItemStack afterInsert = - getBehaviour(DirectBeltInputBehaviour.TYPE).tryExportingToBeltFunnel(previousItem, null); - if (afterInsert == null) - return false; - if (previousItem.getCount() != afterInsert.getCount()) { - processingOutputBuffer.setStackInSlot(slot, afterInsert); - notifyUpdate(); - return true; - } - } - - ItemStack previousItem = heldItem.stack; - ItemStack afterInsert = - getBehaviour(DirectBeltInputBehaviour.TYPE).tryExportingToBeltFunnel(previousItem, null); - if (afterInsert == null) - return false; - if (previousItem.getCount() != afterInsert.getCount()) { - if (afterInsert.isEmpty()) - heldItem = null; - else - heldItem.stack = afterInsert; - notifyUpdate(); - return true; - } - - return false; - } - - @Override - public void remove() { - super.remove(); - if (lazyItemHandler != null) - lazyItemHandler.invalidate(); - } - - @Override - public void write(CompoundNBT compound, boolean clientPacket) { - if (heldItem != null) - compound.put("HeldItem", heldItem.serializeNBT()); - compound.put("OutputBuffer", processingOutputBuffer.serializeNBT()); - super.write(compound, clientPacket); - } - - @Override - protected void read(CompoundNBT compound, boolean clientPacket) { - heldItem = null; - if (compound.contains("HeldItem")) - heldItem = TransportedItemStack.read(compound.getCompound("HeldItem")); - processingOutputBuffer.deserializeNBT(compound.getCompound("OutputBuffer")); - super.read(compound, clientPacket); } @Override public void addBehaviours(List behaviours) { - behaviours.add(new DirectBeltInputBehaviour(this).allowingBeltFunnels() - .setInsertionHandler(this::tryInsertingFromSide)); - transportedHandler = new TransportedItemStackHandlerBehaviour(this, this::applyToAllItems) - .withStackPlacement(this::getWorldPositionOf); - behaviours.add(transportedHandler); - } - - public ItemStack getHeldItemStack() { - return heldItem == null ? ItemStack.EMPTY : heldItem.stack; - } - - public void setHeldItem(TransportedItemStack heldItem) { - this.heldItem = heldItem; - } - - public void setCenteredHeldItem(TransportedItemStack heldItem) { - this.heldItem = heldItem; - this.heldItem.beltPosition = 0.5f; - this.heldItem.prevBeltPosition = 0.5f; + behaviours.add(depotBehaviour = new DepotBehaviour(this)); + depotBehaviour.addSubBehaviours(behaviours); } @Override public LazyOptional getCapability(Capability cap, Direction side) { if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) - return lazyItemHandler.cast(); + return depotBehaviour.getItemCapability(cap, side); return super.getCapability(cap, side); } - private ItemStack tryInsertingFromSide(TransportedItemStack transportedStack, Direction side, boolean simulate) { - ItemStack inserted = transportedStack.stack; - ItemStack empty = ItemStack.EMPTY; - - if (!getHeldItemStack().isEmpty()) - return inserted; - if (!isOutputEmpty()) - return inserted; - if (simulate) - return empty; - - transportedStack = transportedStack.copy(); - transportedStack.beltPosition = side.getAxis() - .isVertical() ? .5f : 0; - transportedStack.insertedFrom = side; - transportedStack.prevSideOffset = transportedStack.sideOffset; - transportedStack.prevBeltPosition = transportedStack.beltPosition; - setHeldItem(transportedStack); - markDirty(); - sendData(); - - return empty; - } - - private void applyToAllItems(float maxDistanceFromCentre, - Function processFunction) { - if (heldItem == null) - return; - if (.5f - heldItem.beltPosition > maxDistanceFromCentre) - return; - - boolean dirty = false; - TransportedItemStack transportedItemStack = heldItem; - ItemStack stackBefore = transportedItemStack.stack.copy(); - TransportedResult result = processFunction.apply(transportedItemStack); - if (result == null || result.didntChangeFrom(stackBefore)) - return; - - dirty = true; - heldItem = null; - if (result.hasHeldOutput()) - setCenteredHeldItem(result.getHeldOutput()); - - for (TransportedItemStack added : result.getOutputs()) { - if (getHeldItemStack().isEmpty()) { - setCenteredHeldItem(added); - continue; - } - ItemStack remainder = ItemHandlerHelper.insertItemStacked(processingOutputBuffer, added.stack, false); - Vec3d vec = VecHelper.getCenterOf(pos); - InventoryHelper.spawnItemStack(world, vec.x, vec.y + .5f, vec.z, remainder); - } - - if (dirty) { - markDirty(); - sendData(); - } - } - - public boolean isOutputEmpty() { - for (int i = 0; i < processingOutputBuffer.getSlots(); i++) - if (!processingOutputBuffer.getStackInSlot(i) - .isEmpty()) - return false; - return true; - } - - private Vec3d getWorldPositionOf(TransportedItemStack transported) { - Vec3d offsetVec = new Vec3d(.5f, 14 / 16f, .5f); - return offsetVec.add(new Vec3d(pos)); - } - } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorBlock.java b/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorBlock.java new file mode 100644 index 000000000..25b289876 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorBlock.java @@ -0,0 +1,152 @@ +package com.simibubi.create.content.logistics.block.depot; + +import java.util.Optional; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllItems; +import com.simibubi.create.AllShapes; +import com.simibubi.create.AllTileEntities; +import com.simibubi.create.content.contraptions.base.HorizontalKineticBlock; +import com.simibubi.create.content.logistics.block.depot.EjectorTileEntity.State; +import com.simibubi.create.foundation.block.ITE; +import com.simibubi.create.foundation.networking.AllPackets; +import com.simibubi.create.foundation.utility.VecHelper; + +import net.minecraft.block.BlockState; +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.ItemEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.Hand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.shapes.ISelectionContext; +import net.minecraft.util.math.shapes.VoxelShape; +import net.minecraft.world.IBlockReader; +import net.minecraft.world.IWorldReader; +import net.minecraft.world.World; + +public class EjectorBlock extends HorizontalKineticBlock implements ITE { + + public EjectorBlock(Properties properties) { + super(properties); + } + + @Override + public VoxelShape getShape(BlockState p_220053_1_, IBlockReader p_220053_2_, BlockPos p_220053_3_, + ISelectionContext p_220053_4_) { + return AllShapes.DEPOT; + } + + @Override + public float getSlipperiness(BlockState state, IWorldReader world, BlockPos pos, Entity entity) { + return getTileEntityOptional(world, pos).filter(ete -> ete.state == State.LAUNCHING) + .map($ -> 1f) + .orElse(super.getSlipperiness(state, world, pos, entity)); + } + + @Override + public void onFallenUpon(World p_180658_1_, BlockPos p_180658_2_, Entity p_180658_3_, float p_180658_4_) { + Optional tileEntityOptional = getTileEntityOptional(p_180658_1_, p_180658_2_); + if (tileEntityOptional.isPresent()) { + p_180658_3_.handleFallDamage(p_180658_4_, 0.0F); + return; + } + super.onFallenUpon(p_180658_1_, p_180658_2_, p_180658_3_, p_180658_4_); + } + + @Override + public void onLanded(IBlockReader worldIn, Entity entityIn) { + super.onLanded(worldIn, entityIn); + BlockPos position = entityIn.getPosition(); + if (!AllBlocks.WEIGHTED_EJECTOR.has(worldIn.getBlockState(position))) + return; + if (!entityIn.isAlive()) + return; + if (entityIn instanceof ItemEntity) { + SharedDepotBlockMethods.onLanded(worldIn, entityIn); + return; + } + + Optional teProvider = getTileEntityOptional(worldIn, position); + if (!teProvider.isPresent()) + return; + + EjectorTileEntity ejectorTileEntity = teProvider.get(); + if (ejectorTileEntity.getState() == State.RETRACTING) + return; + if (ejectorTileEntity.launcher.getHorizontalDistance() == 0) + return; + + if (entityIn.onGround) { + entityIn.onGround = false; + Vec3d center = VecHelper.getCenterOf(position) + .add(0, 7 / 16f, 0); + Vec3d positionVec = entityIn.getPositionVec(); + double diff = center.distanceTo(positionVec); + entityIn.setMotion(0, -0.125, 0); + Vec3d vec = center.add(positionVec) + .scale(.5f); + if (diff > 4 / 16f) { + entityIn.setPosition(vec.x, vec.y, vec.z); + return; + } + } + + ejectorTileEntity.launchAll(); + ejectorTileEntity.notifyUpdate(); + if (entityIn.world.isRemote) + AllPackets.channel.sendToServer(new EjectorTriggerPacket(ejectorTileEntity.getPos())); + } + + @Override + public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, + BlockRayTraceResult ray) { + if (AllItems.WRENCH.isIn(player.getHeldItem(hand))) + return ActionResultType.PASS; + return SharedDepotBlockMethods.onUse(state, world, pos, player, hand, ray); + } + + @Override + public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) { + withTileEntityDo(worldIn, pos, EjectorTileEntity::dropFlyingItems); + SharedDepotBlockMethods.onReplaced(state, worldIn, pos, newState, isMoving); + } + + @Override + public Axis getRotationAxis(BlockState state) { + return state.get(HORIZONTAL_FACING) + .rotateY() + .getAxis(); + } + + @Override + public boolean hasShaftTowards(IWorldReader world, BlockPos pos, BlockState state, Direction face) { + return getRotationAxis(state) == face.getAxis(); + } + + @Override + public TileEntity createTileEntity(BlockState state, IBlockReader world) { + return AllTileEntities.WEIGHTED_EJECTOR.create(); + } + + @Override + public Class getTileEntityClass() { + return EjectorTileEntity.class; + } + + @Override + public boolean hasComparatorInputOverride(BlockState state) { + return true; + } + + @Override + public int getComparatorInputOverride(BlockState blockState, World worldIn, BlockPos pos) { + return SharedDepotBlockMethods.getComparatorInputOverride(blockState, worldIn, pos); + } + +} diff --git a/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorElytraPacket.java b/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorElytraPacket.java new file mode 100644 index 000000000..a149bc92f --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorElytraPacket.java @@ -0,0 +1,51 @@ +package com.simibubi.create.content.logistics.block.depot; + +import java.util.function.Supplier; + +import com.simibubi.create.foundation.networking.SimplePacketBase; + +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.network.PacketBuffer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.fml.network.NetworkEvent.Context; + +public class EjectorElytraPacket extends SimplePacketBase { + + private BlockPos pos; + + public EjectorElytraPacket(BlockPos pos) { + this.pos = pos; + } + + public EjectorElytraPacket(PacketBuffer buffer) { + pos = buffer.readBlockPos(); + } + + @Override + public void write(PacketBuffer buffer) { + buffer.writeBlockPos(pos); + } + + @Override + public void handle(Supplier context) { + context.get() + .enqueueWork(() -> { + ServerPlayerEntity player = context.get() + .getSender(); + if (player == null) + return; + World world = player.world; + if (world == null || !world.isBlockPresent(pos)) + return; + TileEntity tileEntity = world.getTileEntity(pos); + if (tileEntity instanceof EjectorTileEntity) + ((EjectorTileEntity) tileEntity).deployElytra(player); + }); + context.get() + .setPacketHandled(true); + + } + +} diff --git a/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorItem.java b/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorItem.java new file mode 100644 index 000000000..100bcbf28 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorItem.java @@ -0,0 +1,52 @@ +package com.simibubi.create.content.logistics.block.depot; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.BlockItem; +import net.minecraft.item.BlockItemUseContext; +import net.minecraft.item.ItemStack; +import net.minecraft.item.ItemUseContext; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.fml.DistExecutor; +import net.minecraftforge.fml.common.Mod.EventBusSubscriber; + +@EventBusSubscriber +public class EjectorItem extends BlockItem { + + public EjectorItem(Block p_i48527_1_, Properties p_i48527_2_) { + super(p_i48527_1_, p_i48527_2_); + } + + @Override + public ActionResultType onItemUse(ItemUseContext ctx) { + PlayerEntity player = ctx.getPlayer(); + if (player != null && player.isSneaking()) + return ActionResultType.SUCCESS; + return super.onItemUse(ctx); + } + + @Override + protected BlockState getStateForPlacement(BlockItemUseContext p_195945_1_) { + BlockState stateForPlacement = super.getStateForPlacement(p_195945_1_); + return stateForPlacement; + } + + @Override + protected boolean onBlockPlaced(BlockPos pos, World world, PlayerEntity p_195943_3_, ItemStack p_195943_4_, + BlockState p_195943_5_) { + if (world.isRemote) + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> EjectorTargetHandler.flushSettings(pos)); + return super.onBlockPlaced(pos, world, p_195943_3_, p_195943_4_, p_195943_5_); + } + + @Override + public boolean canPlayerBreakBlockWhileHolding(BlockState state, World world, BlockPos pos, + PlayerEntity p_195938_4_) { + return !p_195938_4_.isSneaking(); + } + +} diff --git a/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorPlacementPacket.java b/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorPlacementPacket.java new file mode 100644 index 000000000..3cb0bfc71 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorPlacementPacket.java @@ -0,0 +1,68 @@ +package com.simibubi.create.content.logistics.block.depot; + +import java.util.function.Supplier; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.foundation.networking.SimplePacketBase; + +import net.minecraft.block.BlockState; +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.network.PacketBuffer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.fml.network.NetworkEvent.Context; + +public class EjectorPlacementPacket extends SimplePacketBase { + + private int h, v; + private BlockPos pos; + private Direction facing; + + public EjectorPlacementPacket(int h, int v, BlockPos pos, Direction facing) { + this.h = h; + this.v = v; + this.pos = pos; + this.facing = facing; + } + + public EjectorPlacementPacket(PacketBuffer buffer) { + h = buffer.readInt(); + v = buffer.readInt(); + pos = buffer.readBlockPos(); + facing = Direction.byIndex(buffer.readVarInt()); + } + + @Override + public void write(PacketBuffer buffer) { + buffer.writeInt(h); + buffer.writeInt(v); + buffer.writeBlockPos(pos); + buffer.writeVarInt(facing.getIndex()); + } + + @Override + public void handle(Supplier context) { + context.get() + .enqueueWork(() -> { + ServerPlayerEntity player = context.get() + .getSender(); + if (player == null) + return; + World world = player.world; + if (world == null || !world.isBlockPresent(pos)) + return; + TileEntity tileEntity = world.getTileEntity(pos); + BlockState state = world.getBlockState(pos); + if (tileEntity instanceof EjectorTileEntity) + ((EjectorTileEntity) tileEntity).setTarget(h, v); + if (AllBlocks.WEIGHTED_EJECTOR.has(state)) + world.setBlockState(pos, state.with(EjectorBlock.HORIZONTAL_FACING, facing)); + }); + context.get() + .setPacketHandled(true); + + } + +} diff --git a/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorRenderer.java b/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorRenderer.java new file mode 100644 index 000000000..1d0438af6 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorRenderer.java @@ -0,0 +1,97 @@ +package com.simibubi.create.content.logistics.block.depot; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.vertex.IVertexBuilder; +import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.content.contraptions.base.KineticTileEntity; +import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; +import com.simibubi.create.foundation.render.SuperByteBuffer; +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.IntAttached; +import com.simibubi.create.foundation.utility.MatrixStacker; +import com.simibubi.create.foundation.utility.VecHelper; + +import net.minecraft.block.BlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType; +import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.Vec3d; + +public class EjectorRenderer extends KineticTileEntityRenderer { + + public EjectorRenderer(TileEntityRendererDispatcher dispatcher) { + super(dispatcher); + } + + @Override + public boolean isGlobalRenderer(KineticTileEntity p_188185_1_) { + return true; + } + + @Override + protected void renderSafe(KineticTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, + int light, int overlay) { + super.renderSafe(te, partialTicks, ms, buffer, light, overlay); + + EjectorTileEntity ejector = (EjectorTileEntity) te; + SuperByteBuffer model = AllBlockPartials.EJECTOR_TOP.renderOn(te.getBlockState()); + IVertexBuilder vertexBuilder = buffer.getBuffer(RenderType.getSolid()); + Vec3d rotationOffset = VecHelper.voxelSpace(0, 11.25, 0.75); + float lidProgress = ((EjectorTileEntity) te).getLidProgress(partialTicks); + float angle = lidProgress * 70; + + applyLidAngle(te, rotationOffset, angle, model.matrixStacker()); + model.light(light) + .renderInto(ms, vertexBuilder); + + MatrixStacker msr = MatrixStacker.of(ms); + + for (IntAttached intAttached : ejector.launchedItems) { + ms.push(); + float time = intAttached.getFirst() + partialTicks; + Vec3d launchedItemLocation = ejector.getLaunchedItemLocation(time); + msr.translate(launchedItemLocation.subtract(new Vec3d(te.getPos()))); + Vec3d itemRotOffset = VecHelper.voxelSpace(0,3,0); + msr.translate(itemRotOffset); + msr.rotateY(AngleHelper.horizontalAngle(ejector.getFacing())); + msr.rotateX(time * 40); + msr.translateBack(itemRotOffset); + Minecraft.getInstance() + .getItemRenderer() + .renderItem(intAttached.getValue(), TransformType.GROUND, light, overlay, ms, buffer); + ms.pop(); + } + + DepotBehaviour behaviour = te.getBehaviour(DepotBehaviour.TYPE); + if (behaviour == null || behaviour.isEmpty()) + return; + + ms.push(); + applyLidAngle(te, rotationOffset, angle, msr); + msr.centre() + .rotateY(-180 - AngleHelper.horizontalAngle(te.getBlockState() + .get(EjectorBlock.HORIZONTAL_FACING))) + .unCentre(); + DepotRenderer.renderItemsOf(te, partialTicks, ms, buffer, light, overlay, behaviour); + ms.pop(); + } + + protected void applyLidAngle(KineticTileEntity te, Vec3d rotationOffset, float angle, MatrixStacker matrixStacker) { + matrixStacker.centre() + .rotateY(180 + AngleHelper.horizontalAngle(te.getBlockState() + .get(EjectorBlock.HORIZONTAL_FACING))) + .unCentre() + .translate(rotationOffset) + .rotateX(-angle) + .translateBack(rotationOffset); + } + + @Override + protected BlockState getRenderedBlockState(KineticTileEntity te) { + return shaft(getRotationAxisOf(te)); + } + +} diff --git a/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorTargetHandler.java b/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorTargetHandler.java new file mode 100644 index 000000000..bb1eee6ba --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorTargetHandler.java @@ -0,0 +1,269 @@ +package com.simibubi.create.content.logistics.block.depot; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllItems; +import com.simibubi.create.CreateClient; +import com.simibubi.create.foundation.config.AllConfigs; +import com.simibubi.create.foundation.networking.AllPackets; +import com.simibubi.create.foundation.utility.AnimationTickHolder; +import com.simibubi.create.foundation.utility.ColorHelper; +import com.simibubi.create.foundation.utility.Lang; +import com.simibubi.create.foundation.utility.VecHelper; + +import net.minecraft.block.BlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.player.ClientPlayerEntity; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.particles.RedstoneParticleData; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.Direction.AxisDirection; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.RayTraceResult.Type; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.shapes.VoxelShape; +import net.minecraft.util.text.StringTextComponent; +import net.minecraft.util.text.TextFormatting; +import net.minecraft.world.World; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.event.entity.player.PlayerInteractEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod.EventBusSubscriber; + +@EventBusSubscriber(value = Dist.CLIENT) +public class EjectorTargetHandler { + + static BlockPos currentSelection; + static ItemStack currentItem; + static long lastHoveredBlockPos = -1; + static EntityLauncher launcher; + + @SubscribeEvent + public static void rightClickingBlocksSelectsThem(PlayerInteractEvent.RightClickBlock event) { + if (currentItem == null) + return; + BlockPos pos = event.getPos(); + World world = event.getWorld(); + if (!world.isRemote) + return; + PlayerEntity player = event.getPlayer(); + if (player == null || player.isSpectator() || !player.isSneaking()) + return; + + String key = "weighted_ejector.target_set"; + TextFormatting colour = TextFormatting.GOLD; + player.sendStatusMessage(new StringTextComponent(Lang.translate(key)).applyTextStyle(colour), true); + currentSelection = pos; + launcher = null; + event.setCanceled(true); + event.setCancellationResult(ActionResultType.SUCCESS); + } + + @SubscribeEvent + public static void leftClickingBlocksDeselectsThem(PlayerInteractEvent.LeftClickBlock event) { + if (currentItem == null) + return; + if (!event.getWorld().isRemote) + return; + if (!event.getPlayer() + .isSneaking()) + return; + BlockPos pos = event.getPos(); + if (pos.equals(currentSelection)) { + currentSelection = null; + launcher = null; + event.setCanceled(true); + event.setCancellationResult(ActionResultType.SUCCESS); + } + } + + public static void flushSettings(BlockPos pos) { + if (currentItem == null) + return; + + int h = 0; + int v = 0; + + ClientPlayerEntity player = Minecraft.getInstance().player; + String key = "weighted_ejector.target_not_valid"; + TextFormatting colour = TextFormatting.WHITE; + + if (currentSelection == null) + key = "weighted_ejector.no_target"; + + Direction validTargetDirection = getValidTargetDirection(pos); + if (validTargetDirection == null) { + player.sendStatusMessage(new StringTextComponent(Lang.translate(key)).applyTextStyle(colour), true); + currentItem = null; + currentSelection = null; + return; + } + + key = "weighted_ejector.targeting"; + colour = TextFormatting.GREEN; + + player.sendStatusMessage(new StringTextComponent( + Lang.translate(key, currentSelection.getX(), currentSelection.getY(), currentSelection.getZ())) + .applyTextStyle(colour), + true); + + BlockPos diff = pos.subtract(currentSelection); + h = Math.abs(diff.getX() + diff.getZ()); + v = -diff.getY(); + + AllPackets.channel.sendToServer(new EjectorPlacementPacket(h, v, pos, validTargetDirection)); + currentSelection = null; + currentItem = null; + + } + + public static Direction getValidTargetDirection(BlockPos pos) { + if (currentSelection == null) + return null; + if (VecHelper.onSameAxis(pos, currentSelection, Axis.Y)) + return null; + + int xDiff = currentSelection.getX() - pos.getX(); + int zDiff = currentSelection.getZ() - pos.getZ(); + int max = AllConfigs.SERVER.kinetics.maxEjectorDistance.get(); + + if (Math.abs(xDiff) > max || Math.abs(zDiff) > max) + return null; + + if (xDiff == 0) + return Direction.getFacingFromAxis(zDiff < 0 ? AxisDirection.NEGATIVE : AxisDirection.POSITIVE, Axis.Z); + if (zDiff == 0) + return Direction.getFacingFromAxis(xDiff < 0 ? AxisDirection.NEGATIVE : AxisDirection.POSITIVE, Axis.X); + + return null; + } + + public static void tick() { + PlayerEntity player = Minecraft.getInstance().player; + + if (player == null) + return; + + ItemStack heldItemMainhand = player.getHeldItemMainhand(); + if (!AllBlocks.WEIGHTED_EJECTOR.isIn(heldItemMainhand)) { + currentItem = null; + } else { + if (heldItemMainhand != currentItem) { + currentSelection = null; + currentItem = heldItemMainhand; + } + drawOutline(currentSelection); + } + + checkForWrench(heldItemMainhand); + drawArc(); + } + + protected static void drawArc() { + Minecraft mc = Minecraft.getInstance(); + boolean wrench = AllItems.WRENCH.isIn(mc.player.getHeldItemMainhand()); + + if (currentSelection == null) + return; + if (currentItem == null && !wrench) + return; + + RayTraceResult objectMouseOver = mc.objectMouseOver; + if (!(objectMouseOver instanceof BlockRayTraceResult)) + return; + BlockRayTraceResult blockRayTraceResult = (BlockRayTraceResult) objectMouseOver; + if (blockRayTraceResult.getType() == Type.MISS) + return; + + BlockPos pos = blockRayTraceResult.getPos(); + if (!wrench) + pos = pos.offset(blockRayTraceResult.getFace()); + + int xDiff = currentSelection.getX() - pos.getX(); + int yDiff = currentSelection.getY() - pos.getY(); + int zDiff = currentSelection.getZ() - pos.getZ(); + int validX = Math.abs(zDiff) > Math.abs(xDiff) ? 0 : xDiff; + int validZ = Math.abs(zDiff) < Math.abs(xDiff) ? 0 : zDiff; + + BlockPos validPos = currentSelection.add(validX, yDiff, validZ); + Direction d = getValidTargetDirection(validPos); + if (d == null) + return; + if (launcher == null || lastHoveredBlockPos != pos.toLong()) { + lastHoveredBlockPos = pos.toLong(); + launcher = new EntityLauncher(Math.abs(validX + validZ), yDiff); + } + + double totalFlyingTicks = launcher.getTotalFlyingTicks() + 3; + int segments = (((int) totalFlyingTicks) / 3) + 1; + double tickOffset = totalFlyingTicks / segments; + boolean valid = xDiff == validX && zDiff == validZ; + int intColor = valid ? 0x9ede73 : 0xff7171; + Vec3d color = ColorHelper.getRGB(intColor); + RedstoneParticleData data = new RedstoneParticleData((float) color.x, (float) color.y, (float) color.z, 1); + ClientWorld world = mc.world; + + AxisAlignedBB bb = new AxisAlignedBB(0, 0, 0, 1, 0, 1).offset(currentSelection.add(-validX, -yDiff, -validZ)); + CreateClient.outliner.chaseAABB("valid", bb) + .colored(intColor) + .lineWidth(1 / 16f); + + for (int i = 0; i < segments; i++) { + double ticks = ((AnimationTickHolder.getRenderTime() / 3) % tickOffset) + i * tickOffset; + Vec3d vec = launcher.getGlobalPos(ticks, d, pos) + .add(xDiff - validX, 0, zDiff - validZ); + world.addParticle(data, vec.x, vec.y, vec.z, 0, 0, 0); + } + } + + private static void checkForWrench(ItemStack heldItem) { + if (!AllItems.WRENCH.isIn(heldItem)) + return; + RayTraceResult objectMouseOver = Minecraft.getInstance().objectMouseOver; + if (!(objectMouseOver instanceof BlockRayTraceResult)) + return; + BlockRayTraceResult result = (BlockRayTraceResult) objectMouseOver; + BlockPos pos = result.getPos(); + + TileEntity te = Minecraft.getInstance().world.getTileEntity(pos); + if (!(te instanceof EjectorTileEntity)) { + lastHoveredBlockPos = -1; + currentSelection = null; + return; + } + + if (lastHoveredBlockPos == -1 || lastHoveredBlockPos != pos.toLong()) { + EjectorTileEntity ejector = (EjectorTileEntity) te; + if (!ejector.getTargetPosition() + .equals(ejector.getPos())) + currentSelection = ejector.getTargetPosition(); + lastHoveredBlockPos = pos.toLong(); + launcher = null; + } + + if (lastHoveredBlockPos != -1) + drawOutline(currentSelection); + } + + private static void drawOutline(BlockPos selection) { + World world = Minecraft.getInstance().world; + if (currentSelection == null) + return; + + BlockPos pos = currentSelection; + BlockState state = world.getBlockState(pos); + VoxelShape shape = state.getShape(world, pos); + AxisAlignedBB boundingBox = shape.isEmpty() ? new AxisAlignedBB(BlockPos.ZERO) : shape.getBoundingBox(); + CreateClient.outliner.showAABB("target", boundingBox.offset(pos)) + .colored(0xffcb74) + .lineWidth(1 / 16f); + } + +} diff --git a/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorTileEntity.java new file mode 100644 index 000000000..88ca0f8f8 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorTileEntity.java @@ -0,0 +1,496 @@ +package com.simibubi.create.content.logistics.block.depot; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.content.contraptions.base.KineticTileEntity; +import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack; +import com.simibubi.create.content.logistics.block.funnel.AbstractFunnelBlock; +import com.simibubi.create.foundation.config.AllConfigs; +import com.simibubi.create.foundation.networking.AllPackets; +import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; +import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform; +import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour; +import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollValueBehaviour; +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.IntAttached; +import com.simibubi.create.foundation.utility.Lang; +import com.simibubi.create.foundation.utility.MatrixStacker; +import com.simibubi.create.foundation.utility.NBTHelper; +import com.simibubi.create.foundation.utility.VecHelper; +import com.simibubi.create.foundation.utility.animation.LerpedFloat; +import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser; + +import net.minecraft.block.BlockState; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.item.ItemEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.inventory.EquipmentSlotType; +import net.minecraft.item.ElytraItem; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.network.datasync.EntityDataManager; +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.SoundEvents; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.util.Constants.NBT; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.items.ItemStackHandler; + +public class EjectorTileEntity extends KineticTileEntity { + + List> launchedItems; + ScrollValueBehaviour maxStackSize; + DepotBehaviour depotBehaviour; + EntityLauncher launcher; + LerpedFloat lidProgress; + State state; + + public enum State { + CHARGED, LAUNCHING, RETRACTING; + } + + public EjectorTileEntity(TileEntityType typeIn) { + super(typeIn); + launcher = new EntityLauncher(1, 0); + lidProgress = LerpedFloat.linear() + .startWithValue(1); + state = State.RETRACTING; + launchedItems = new ArrayList<>(); + } + + @Override + public void addBehaviours(List behaviours) { + super.addBehaviours(behaviours); + behaviours.add(depotBehaviour = new DepotBehaviour(this)); + + maxStackSize = new ScrollValueBehaviour(Lang.translate("weighted_ejector.stack_size"), this, new EjectorSlot()) + .between(0, 64) + .withFormatter(i -> i == 0 ? "*" : String.valueOf(i)) + .onlyActiveWhen(() -> state == State.CHARGED) + .requiresWrench(); + behaviours.add(maxStackSize); + + depotBehaviour.maxStackSize = () -> maxStackSize.getValue(); + depotBehaviour.canAcceptItems = () -> state == State.CHARGED; + depotBehaviour.canFunnelsPullFrom = side -> side != getFacing(); + depotBehaviour.enableMerging(); + depotBehaviour.addSubBehaviours(behaviours); + } + + public void launchAll() { + if (state != State.CHARGED && !(world.isRemote && state == State.LAUNCHING)) + return; + + Direction facing = getFacing(); + List entities = + world.getEntitiesWithinAABB(Entity.class, new AxisAlignedBB(pos).grow(-1 / 16f, 0, -1 / 16f)); + + // Launch Items + if (!world.isRemote) + launchItems(); + + // Launch Entities + for (Entity entity : entities) { + boolean isPlayerEntity = entity instanceof PlayerEntity; + if (!entity.isAlive()) + continue; + if (entity instanceof ItemEntity) + continue; + + entity.onGround = false; + + if (isPlayerEntity != world.isRemote) + continue; + + entity.setPosition(pos.getX() + .5f, pos.getY() + 1, pos.getZ() + .5f); + launcher.applyMotion(entity, facing); + + if (!isPlayerEntity) + continue; + PlayerEntity playerEntity = (PlayerEntity) entity; + if (!(playerEntity.getItemStackFromSlot(EquipmentSlotType.CHEST) + .getItem() instanceof ElytraItem)) + continue; + + playerEntity.rotationYaw = facing.getHorizontalAngle(); + playerEntity.rotationPitch = -35; + playerEntity.setMotion(playerEntity.getMotion() + .scale(.75f)); + deployElytra(playerEntity); + AllPackets.channel.sendToServer(new EjectorElytraPacket(pos)); + } + + lidProgress.chase(1, .8f, Chaser.EXP); + state = State.LAUNCHING; + + if (!world.isRemote) { + world.playSound(null, pos, SoundEvents.BLOCK_WOODEN_TRAPDOOR_CLOSE, SoundCategory.BLOCKS, .5f, 1f); + world.playSound(null, pos, SoundEvents.BLOCK_CHEST_OPEN, SoundCategory.BLOCKS, .125f, 1.4f); + } + } + + public void deployElytra(PlayerEntity playerEntity) { + EntityHack.setElytraFlying(playerEntity); + } + + protected void launchItems() { + ItemStack heldItemStack = depotBehaviour.getHeldItemStack(); + Direction funnelFacing = getFacing().getOpposite(); + + if (AbstractFunnelBlock.getFunnelFacing(world.getBlockState(pos.up())) == funnelFacing) { + DirectBeltInputBehaviour directOutput = getBehaviour(DirectBeltInputBehaviour.TYPE); + + if (depotBehaviour.heldItem != null) { + ItemStack remainder = directOutput.tryExportingToBeltFunnel(heldItemStack, funnelFacing, false); + if (remainder == null) + ; + else if (remainder.isEmpty()) + depotBehaviour.removeHeldItem(); + else if (!remainder.isItemEqual(heldItemStack)) + depotBehaviour.heldItem.stack = remainder; + } + + for (Iterator iterator = depotBehaviour.incoming.iterator(); iterator.hasNext();) { + TransportedItemStack transportedItemStack = iterator.next(); + ItemStack stack = transportedItemStack.stack; + ItemStack remainder = directOutput.tryExportingToBeltFunnel(stack, funnelFacing, false); + if (remainder == null) + ; + else if (remainder.isEmpty()) + iterator.remove(); + else if (!remainder.isItemEqual(stack)) + transportedItemStack.stack = remainder; + } + + ItemStackHandler outputs = depotBehaviour.processingOutputBuffer; + for (int i = 0; i < outputs.getSlots(); i++) { + ItemStack remainder = + directOutput.tryExportingToBeltFunnel(outputs.getStackInSlot(i), funnelFacing, false); + if (remainder != null) + outputs.setStackInSlot(i, remainder); + } + return; + } + + if (depotBehaviour.heldItem != null) { + launchedItems.add(IntAttached.withZero(heldItemStack)); + depotBehaviour.removeHeldItem(); + } + + for (TransportedItemStack transportedItemStack : depotBehaviour.incoming) + launchedItems.add(IntAttached.withZero(transportedItemStack.stack)); + depotBehaviour.incoming.clear(); + + ItemStackHandler outputs = depotBehaviour.processingOutputBuffer; + for (int i = 0; i < outputs.getSlots(); i++) { + ItemStack extractItem = outputs.extractItem(i, 64, false); + if (!extractItem.isEmpty()) + launchedItems.add(IntAttached.withZero(extractItem)); + } + } + + protected Direction getFacing() { + BlockState blockState = getBlockState(); + if (!AllBlocks.WEIGHTED_EJECTOR.has(blockState)) + return Direction.UP; + Direction facing = blockState.get(EjectorBlock.HORIZONTAL_FACING); + return facing; + } + + @Override + public void tick() { + super.tick(); + + boolean doLogic = !world.isRemote || isVirtual(); + State prevState = state; + + float maxTime = Math.max(3, (float) launcher.getTotalFlyingTicks()); + + for (Iterator> iterator = launchedItems.iterator(); iterator.hasNext();) { + IntAttached intAttached = iterator.next(); + if (intAttached.exceeds((int) maxTime)) { + placeItemAtTarget(doLogic, maxTime, intAttached); + iterator.remove(); + } + intAttached.increment(); + } + + if (state == State.LAUNCHING) { + lidProgress.chase(1, .8f, Chaser.EXP); + lidProgress.tickChaser(); + if (lidProgress.getValue() > 1 - 1 / 16f && doLogic) { + state = State.RETRACTING; + lidProgress.setValue(1); + } + } + + if (state == State.CHARGED) { + lidProgress.setValue(0); + if (doLogic) + ejectIfTriggered(); + } + + if (state == State.RETRACTING) { + float value = MathHelper.clamp(lidProgress.getValue() - getWindUpSpeed(), 0, 1); + lidProgress.setValue(value); + + int soundRate = (int) (1 / (getWindUpSpeed() * 5)) + 1; + float volume = .125f; + float pitch = 1.5f - lidProgress.getValue(); + if (((int) world.getGameTime()) % soundRate == 0 && doLogic) + world.playSound(null, pos, SoundEvents.BLOCK_WOODEN_BUTTON_CLICK_OFF, SoundCategory.BLOCKS, volume, + pitch); + + if (lidProgress.getValue() == 0 && doLogic) { + state = State.CHARGED; + lidProgress.setValue(0); + + List entities = + world.getEntitiesWithinAABB(Entity.class, new AxisAlignedBB(pos).grow(-1 / 16f, 0, -1 / 16f)); + for (Entity entity : entities) + if (!(entity instanceof PlayerEntity)) + entity.setPosition(entity.getX(), entity.getY() + volume, entity.getZ()); + } + } + + if (state != prevState) + notifyUpdate(); + } + + protected void ejectIfTriggered() { + int presentStackSize = depotBehaviour.getPresentStackSize(); + if (presentStackSize == 0) + return; + if (presentStackSize < maxStackSize.getValue()) + return; + + Direction funnelFacing = getFacing().getOpposite(); + if (AbstractFunnelBlock.getFunnelFacing(world.getBlockState(pos.up())) == funnelFacing) { + DirectBeltInputBehaviour directOutput = getBehaviour(DirectBeltInputBehaviour.TYPE); + if (depotBehaviour.heldItem != null) { + ItemStack tryFunnel = + directOutput.tryExportingToBeltFunnel(depotBehaviour.getHeldItemStack(), funnelFacing, true); + if (tryFunnel == null || !tryFunnel.isEmpty()) + return; + } + } + + DirectBeltInputBehaviour targetOpenInv = getTargetOpenInv(); + + // Do not eject if target cannot accept held item + if (targetOpenInv != null && depotBehaviour.heldItem != null + && targetOpenInv.handleInsertion(depotBehaviour.getHeldItemStack(), Direction.UP, true) + .isItemEqual(depotBehaviour.getHeldItemStack())) + return; + + launchAll(); + notifyUpdate(); + } + + protected void placeItemAtTarget(boolean doLogic, float maxTime, IntAttached intAttached) { + if (!doLogic) + return; + + DirectBeltInputBehaviour targetOpenInv = getTargetOpenInv(); + if (targetOpenInv != null) { + ItemStack remainder = targetOpenInv.handleInsertion(intAttached.getValue(), Direction.UP, false); + intAttached.setSecond(remainder); + } + + if (intAttached.getValue() + .isEmpty()) + return; + + Vec3d ejectVec = getLaunchedItemLocation(maxTime); + Vec3d ejectMotionVec = getLaunchedItemMotion(maxTime); + ItemEntity item = new ItemEntity(world, ejectVec.x, ejectVec.y, ejectVec.z, intAttached.getValue()); + item.setMotion(ejectMotionVec); + item.setDefaultPickupDelay(); + world.addEntity(item); + } + + public DirectBeltInputBehaviour getTargetOpenInv() { + return TileEntityBehaviour.get(world, pos.up(launcher.getVerticalDistance()) + .offset(getFacing(), Math.max(1, launcher.getHorizontalDistance())), DirectBeltInputBehaviour.TYPE); + } + + public Vec3d getLaunchedItemLocation(float time) { + return launcher.getGlobalPos(time, getFacing().getOpposite(), pos); + } + + public Vec3d getLaunchedItemMotion(float time) { + return launcher.getGlobalVelocity(time, getFacing().getOpposite(), pos); + } + + public void dropFlyingItems() { + for (IntAttached intAttached : launchedItems) { + Vec3d ejectVec = getLaunchedItemLocation(intAttached.getFirst()); + Vec3d ejectMotionVec = getLaunchedItemMotion(intAttached.getFirst()); + ItemEntity item = new ItemEntity(world, 0, 0, 0, intAttached.getValue()); + item.setPos(ejectVec.x, ejectVec.y, ejectVec.z); + item.setMotion(ejectMotionVec); + item.setDefaultPickupDelay(); + world.addEntity(item); + } + launchedItems.clear(); + } + + public float getWindUpSpeed() { + int hd = launcher.getHorizontalDistance(); + int vd = launcher.getVerticalDistance(); + + float speedFactor = Math.abs(getSpeed()) / 256f; + float distanceFactor; + if (hd == 0 && vd == 0) + distanceFactor = 1; + else + distanceFactor = 1 * MathHelper.sqrt(Math.pow(hd, 2) + Math.pow(vd, 2)); + return speedFactor / distanceFactor; + } + + @Override + protected void write(CompoundNBT compound, boolean clientPacket) { + super.write(compound, clientPacket); + compound.putInt("HorizontalDistance", launcher.getHorizontalDistance()); + compound.putInt("VerticalDistance", launcher.getVerticalDistance()); + NBTHelper.writeEnum(compound, "State", state); + compound.put("Lid", lidProgress.writeNBT()); + compound.put("LaunchedItems", + NBTHelper.writeCompoundList(launchedItems, ia -> ia.serializeNBT(ItemStack::serializeNBT))); + } + + @Override + protected void read(CompoundNBT compound, boolean clientPacket) { + super.read(compound, clientPacket); + int horizontalDistance = compound.getInt("HorizontalDistance"); + int verticalDistance = compound.getInt("VerticalDistance"); + + if (launcher == null || launcher.getHorizontalDistance() != horizontalDistance + || launcher.getVerticalDistance() != verticalDistance) { + launcher.set(horizontalDistance, verticalDistance); + launcher.clamp(AllConfigs.SERVER.kinetics.maxEjectorDistance.get()); + } + + state = NBTHelper.readEnum(compound, "State", State.class); + lidProgress.readNBT(compound.getCompound("Lid"), clientPacket); + launchedItems = NBTHelper.readCompoundList(compound.getList("LaunchedItems", NBT.TAG_COMPOUND), + nbt -> IntAttached.read(nbt, ItemStack::read)); + } + + public void setTarget(int horizontalDistance, int verticalDistance) { + launcher.set(Math.max(1, horizontalDistance), verticalDistance); + if (horizontalDistance == 0 && verticalDistance == 0) { + state = State.CHARGED; + lidProgress.startWithValue(0); + } + sendData(); + } + + public BlockPos getTargetPosition() { + BlockState blockState = getBlockState(); + if (!AllBlocks.WEIGHTED_EJECTOR.has(blockState)) + return pos; + Direction facing = blockState.get(EjectorBlock.HORIZONTAL_FACING); + return pos.offset(facing, launcher.getHorizontalDistance()) + .up(launcher.getVerticalDistance()); + } + + @Override + public LazyOptional getCapability(Capability cap, Direction side) { + if (isItemHandlerCap(cap)) + return depotBehaviour.getItemCapability(cap, side); + return super.getCapability(cap, side); + } + + @Override + public boolean shouldRenderAsTE() { + return true; + } + + public float getLidProgress(float pt) { + return lidProgress.getValue(pt); + } + + public State getState() { + return state; + } + + @Override + @OnlyIn(Dist.CLIENT) + public AxisAlignedBB getRenderBoundingBox() { + return INFINITE_EXTENT_AABB; + } + + @Override + @OnlyIn(Dist.CLIENT) + public double getMaxRenderDistanceSquared() { + return super.getMaxRenderDistanceSquared() * 16; + } + + private static abstract class EntityHack extends Entity { + + public EntityHack(EntityType p_i48580_1_, World p_i48580_2_) { + super(p_i48580_1_, p_i48580_2_); + } + + public static void setElytraFlying(Entity e) { + EntityDataManager data = e.getDataManager(); + data.set(FLAGS, (byte) (data.get(FLAGS) | 1 << 7)); + } + + } + + private static class EjectorSlot extends ValueBoxTransform.Sided { + + @Override + protected Vec3d getLocalOffset(BlockState state) { + return new Vec3d(.5, 13 / 16f, .5).add(VecHelper.rotate(new Vec3d(0, 0, -.3), angle(state), Axis.Y)); + } + + @Override + protected void rotate(BlockState state, MatrixStack ms) { + MatrixStacker.of(ms) + .rotateY(angle(state)) + .rotateX(90); + } + + protected float angle(BlockState state) { + float horizontalAngle = AllBlocks.WEIGHTED_EJECTOR.has(state) + ? AngleHelper.horizontalAngle(state.get(EjectorBlock.HORIZONTAL_FACING)) + : 0; + return horizontalAngle; + } + + @Override + protected boolean isSideActive(BlockState state, Direction direction) { + return direction == Direction.UP; + } + + @Override + protected float getScale() { + return 0.2f; + } + + @Override + protected Vec3d getSouthLocation() { + return Vec3d.ZERO; + } + + } + +} diff --git a/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorTriggerPacket.java b/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorTriggerPacket.java new file mode 100644 index 000000000..fa9dd6a5e --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorTriggerPacket.java @@ -0,0 +1,29 @@ +package com.simibubi.create.content.logistics.block.depot; + +import com.simibubi.create.foundation.networking.TileEntityConfigurationPacket; + +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.math.BlockPos; + +public class EjectorTriggerPacket extends TileEntityConfigurationPacket { + + public EjectorTriggerPacket(BlockPos pos) { + super(pos); + } + + public EjectorTriggerPacket(PacketBuffer buffer) { + super(buffer); + } + + @Override + protected void writeSettings(PacketBuffer buffer) {} + + @Override + protected void readSettings(PacketBuffer buffer) {} + + @Override + protected void applySettings(EjectorTileEntity te) { + te.launchAll(); + } + +} diff --git a/src/main/java/com/simibubi/create/content/logistics/block/depot/EntityLauncher.java b/src/main/java/com/simibubi/create/content/logistics/block/depot/EntityLauncher.java new file mode 100644 index 000000000..cf91ddfef --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/block/depot/EntityLauncher.java @@ -0,0 +1,140 @@ +package com.simibubi.create.content.logistics.block.depot; + +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.VecHelper; + +import net.minecraft.entity.Entity; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; + +public class EntityLauncher { + + private int horizontalDistance; + private int verticalDistance; + private double yMotion; + private double xMotion; + private double totalFlyingTicks; + + public EntityLauncher(int horizontalDistance, int verticalDistance) { + set(horizontalDistance, verticalDistance); + } + + public void clamp(int max) { + set(Math.min(horizontalDistance, max), + MathHelper.signum(verticalDistance) * Math.min(Math.abs(verticalDistance), max)); + } + + public void set(int horizontalDistance, int verticalDistance) { + this.horizontalDistance = horizontalDistance; + this.verticalDistance = verticalDistance; + recalculateTrajectory(); + } + + public void applyMotion(Entity entity, Direction facing) { + Vec3d motionVec = new Vec3d(0, yMotion, xMotion); + motionVec = VecHelper.rotate(motionVec, AngleHelper.horizontalAngle(facing), Axis.Y); + entity.setMotion(motionVec.x, motionVec.y, motionVec.z); + } + + public int getHorizontalDistance() { + return horizontalDistance; + } + + public int getVerticalDistance() { + return verticalDistance; + } + + public double getTotalFlyingTicks() { + return totalFlyingTicks; + } + + public Vec3d getGlobalPos(double t, Direction d, BlockPos launcher) { + Vec3d start = new Vec3d(launcher.getX() + .5f, launcher.getY() + .5f, launcher.getZ() + .5f); + Vec3d vec = new Vec3d(0, y(t), x(t)); + return VecHelper.rotate(vec, 180 + AngleHelper.horizontalAngle(d), Axis.Y) + .add(start); + } + + public Vec3d getGlobalVelocity(double t, Direction d, BlockPos launcher) { + return VecHelper.rotate(new Vec3d(0, dy(t), dx(t)), 180 + AngleHelper.horizontalAngle(d), Axis.Y); + } + + public float x(double t) { + return (float) (xMotion * -10.6033 * (-1 + Math.pow(0.91, t))); + } + + public float y(double t) { + double f = Math.pow(0.98, t); + return (float) (yMotion * -49.4983 * f + 49.4983 * yMotion - 194.033 * f - 3.92 * t + 194.033); + } + + public float dx(double t) { + return (float) (xMotion * Math.pow(0.91, t)); + } + + public float dy(double t) { + double f = Math.pow(0.98, t); + return (float) (yMotion * f + ((f - 1) / (0.98 - 1)) * -0.0784); + } + + protected void recalculateTrajectory() { + double xTarget = this.horizontalDistance; + double yTarget = this.verticalDistance; + + /* + ** Iterated: + * Horizontal Motion fh(x) = x * 0.91 + * Vertical Motion fv(x) = (x - 0.08) * 0.98 + * (Gravity modification ignored) + * > See LivingEntity.travel() + * + ** n-th Iterative + * (= given initial velocity x, motion after t ticks) + * X'(x, t) = x * 0.91^t + * Y'(x, t) = x * 0.98^t + ((0.98^t - 1) / (0.98 - 1)) * -0.0784 + * + ** integral + * (= given intial velocity x, location offset after t ticks) + * X(x, t) = -10.6033x * (-1 + 0.91^t) + * Y(x, t) = -49.4983x * 0.98^t + 49.4983x - 194.033 * 0.98^t - 3.92t + 194.033 + * + ** argmax y + * (= given initial y velocity, ticks at which y reaches top) + * tPeak(x) = log(98 / (25x + 98)) / (2*log(7) - 2*log(5) - log(2)) + * + ** max y + * (= given initial y velocity, height offset at tPeak) + * yPeak(x) = 889.636 + 49.4983x + 0.032928/(98 + 25x) + 194.033 * log(1/(98 + 25x)) + * + ** yPeak inverse (Zelo's approximation) + * (= given yPeak, initial y velocity required to reach it at max) + * yMotion(h) = sqrt(2h/13) + 0.015h + * + ** Y'(x, t) inverse (Simi's approximation) + * (= given yTarget and initial y velocity, elapsed ticks when arc hits yTarget on its way down) + * t*(x, v) = sqrt(yPeak(v) - x) * 4.87 + 0.115 * (yPeak(v) - x) + tPeak(v) + * + ** xMotion + * (= given t* and xTarget, initial x velocity such that X'(x, t*) = xTarget) + * xMotion(t, x) = x / (-10.6033 * (-1 + 0.91^t)); + * + ** xError + * Interpolated correction function from observed inaccuracies in-game + * + */ + + double xError = (-0.0007 * Math.pow(xTarget + .5, 2) + 0.484) + - (Math.min(5, yTarget) / 5) * Math.min(1, 0.076 * xTarget - 0.0014 * xTarget * xTarget); + + double yPeak = Math.max(0, yTarget + (xTarget + .5) / 8f) + (xTarget <= 1 ? 1 : 4); + yMotion = Math.sqrt(2 * yPeak / 13) + 0.015 * yPeak; + double tPeak = Math.log(98 / (25 * yMotion + 98)) / (2 * Math.log(7) - 2 * Math.log(5) - Math.log(2)); + totalFlyingTicks = Math.sqrt(yPeak - yMotion) * 4.87 + 0.115 * (yPeak - yMotion) + tPeak; + xMotion = (xTarget - xError + .5) / (-10.6033 * (-1 + Math.pow(0.91, totalFlyingTicks))); + + } + +} diff --git a/src/main/java/com/simibubi/create/content/logistics/block/depot/SharedDepotBlockMethods.java b/src/main/java/com/simibubi/create/content/logistics/block/depot/SharedDepotBlockMethods.java new file mode 100644 index 000000000..442311b1b --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/block/depot/SharedDepotBlockMethods.java @@ -0,0 +1,111 @@ +package com.simibubi.create.content.logistics.block.depot; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack; +import com.simibubi.create.foundation.item.ItemHelper; +import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; +import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour; + +import net.minecraft.block.BlockState; +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.ItemEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.inventory.InventoryHelper; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.Direction; +import net.minecraft.util.Hand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.world.IBlockReader; +import net.minecraft.world.World; +import net.minecraftforge.items.ItemStackHandler; + +public class SharedDepotBlockMethods { + + protected static DepotBehaviour get(IBlockReader worldIn, BlockPos pos) { + return TileEntityBehaviour.get(worldIn, pos, DepotBehaviour.TYPE); + } + + public static ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, + BlockRayTraceResult ray) { + if (ray.getFace() != Direction.UP) + return ActionResultType.PASS; + if (world.isRemote) + return ActionResultType.SUCCESS; + + DepotBehaviour behaviour = get(world, pos); + if (behaviour == null) + return ActionResultType.PASS; + if (!behaviour.canAcceptItems.get()) + return ActionResultType.SUCCESS; + + ItemStack heldItem = player.getHeldItem(hand); + boolean wasEmptyHanded = heldItem.isEmpty(); + boolean shouldntPlaceItem = AllBlocks.MECHANICAL_ARM.isIn(heldItem); + + ItemStack mainItemStack = behaviour.getHeldItemStack(); + if (!mainItemStack.isEmpty()) { + player.inventory.placeItemBackInInventory(world, mainItemStack); + behaviour.removeHeldItem(); + } + ItemStackHandler outputs = behaviour.processingOutputBuffer; + for (int i = 0; i < outputs.getSlots(); i++) + player.inventory.placeItemBackInInventory(world, outputs.extractItem(i, 64, false)); + + if (!wasEmptyHanded && !shouldntPlaceItem) { + TransportedItemStack transported = new TransportedItemStack(heldItem); + transported.insertedFrom = player.getHorizontalFacing(); + transported.prevBeltPosition = .25f; + transported.beltPosition = .25f; + behaviour.setHeldItem(transported); + player.setHeldItem(hand, ItemStack.EMPTY); + } + + behaviour.tileEntity.notifyUpdate(); + return ActionResultType.SUCCESS; + } + + public static void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, + boolean isMoving) { + if (!state.hasTileEntity() || state.getBlock() == newState.getBlock()) + return; + DepotBehaviour behaviour = get(worldIn, pos); + if (behaviour == null) + return; + ItemHelper.dropContents(worldIn, pos, behaviour.processingOutputBuffer); + for (TransportedItemStack transportedItemStack : behaviour.incoming) + InventoryHelper.spawnItemStack(worldIn, pos.getX(), pos.getY(), pos.getZ(), transportedItemStack.stack); + if (!behaviour.getHeldItemStack() + .isEmpty()) + InventoryHelper.spawnItemStack(worldIn, pos.getX(), pos.getY(), pos.getZ(), behaviour.getHeldItemStack()); + worldIn.removeTileEntity(pos); + } + + public static void onLanded(IBlockReader worldIn, Entity entityIn) { + if (!(entityIn instanceof ItemEntity)) + return; + if (!entityIn.isAlive()) + return; + if (entityIn.world.isRemote) + return; + + ItemEntity itemEntity = (ItemEntity) entityIn; + DirectBeltInputBehaviour inputBehaviour = + TileEntityBehaviour.get(worldIn, entityIn.getPosition(), DirectBeltInputBehaviour.TYPE); + if (inputBehaviour == null) + return; + ItemStack remainder = inputBehaviour.handleInsertion(itemEntity.getItem(), Direction.DOWN, false); + itemEntity.setItem(remainder); + if (remainder.isEmpty()) + itemEntity.remove(); + } + + public static int getComparatorInputOverride(BlockState blockState, World worldIn, BlockPos pos) { + DepotBehaviour depotBehaviour = get(worldIn, pos); + if (depotBehaviour == null) + return 0; + return ItemHelper.calcRedstoneFromInventory(depotBehaviour.itemHandler); + } + +} diff --git a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInteractionPoint.java b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInteractionPoint.java index 4809bb3e1..df2866d43 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInteractionPoint.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInteractionPoint.java @@ -228,7 +228,7 @@ public abstract class ArmInteractionPoint { @Override boolean isValid(IBlockReader reader, BlockPos pos, BlockState state) { - return AllBlocks.DEPOT.has(state); + return AllBlocks.DEPOT.has(state) || AllBlocks.WEIGHTED_EJECTOR.has(state); } } diff --git a/src/main/java/com/simibubi/create/events/ClientEvents.java b/src/main/java/com/simibubi/create/events/ClientEvents.java index 3c19cdde8..b116c1530 100644 --- a/src/main/java/com/simibubi/create/events/ClientEvents.java +++ b/src/main/java/com/simibubi/create/events/ClientEvents.java @@ -21,6 +21,7 @@ import com.simibubi.create.content.curiosities.zapper.ZapperItem; import com.simibubi.create.content.curiosities.zapper.ZapperRenderHandler; import com.simibubi.create.content.curiosities.zapper.blockzapper.BlockzapperRenderHandler; import com.simibubi.create.content.curiosities.zapper.terrainzapper.WorldshaperRenderHandler; +import com.simibubi.create.content.logistics.block.depot.EjectorTargetHandler; import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPointHandler; import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.item.TooltipHelper; @@ -114,6 +115,7 @@ public class ClientEvents { ExtendoGripRenderHandler.tick(); // CollisionDebugger.tick(); ArmInteractionPointHandler.tick(); + EjectorTargetHandler.tick(); PlacementHelpers.tick(); CreateClient.outliner.tickOutlines(); CreateClient.ghostBlocks.tickGhosts(); diff --git a/src/main/java/com/simibubi/create/foundation/config/CKinetics.java b/src/main/java/com/simibubi/create/foundation/config/CKinetics.java index a38e7945c..c93875240 100644 --- a/src/main/java/com/simibubi/create/foundation/config/CKinetics.java +++ b/src/main/java/com/simibubi/create/foundation/config/CKinetics.java @@ -15,6 +15,7 @@ public class CKinetics extends ConfigBase { public ConfigInt kineticValidationFrequency = i(60, 5, "kineticValidationFrequency", Comments.kineticValidationFrequency); public ConfigFloat crankHungerMultiplier = f(.01f, 0, 1, "crankHungerMultiplier", Comments.crankHungerMultiplier); public ConfigInt minimumWindmillSails = i(8, 0, "minimumWindmillSails", Comments.minimumWindmillSails); + public ConfigInt maxEjectorDistance = i(32, 0, "maxEjectorDistance", Comments.maxEjectorDistance); public ConfigGroup fan = group(1, "encasedFan", "Encased Fan"); public ConfigInt fanPushDistance = i(20, 5, "fanPushDistance", Comments.fanPushDistance); @@ -81,6 +82,7 @@ public class CKinetics extends ConfigBase { static String disableStress = "Disable the Stress mechanic altogether."; static String kineticValidationFrequency = "Game ticks between Kinetic Blocks checking whether their source is still valid."; static String minimumWindmillSails = "Amount of sail-type blocks required for a windmill to assemble successfully."; + static String maxEjectorDistance = "Max Distance in blocks a Weighted Ejector can throw"; } public static enum DeployerAggroSetting { diff --git a/src/main/java/com/simibubi/create/foundation/data/recipe/StandardRecipeGen.java b/src/main/java/com/simibubi/create/foundation/data/recipe/StandardRecipeGen.java index abe18a5b6..5fddcde92 100644 --- a/src/main/java/com/simibubi/create/foundation/data/recipe/StandardRecipeGen.java +++ b/src/main/java/com/simibubi/create/foundation/data/recipe/StandardRecipeGen.java @@ -317,7 +317,7 @@ public class StandardRecipeGen extends CreateRecipeProvider { .patternLine("P") .patternLine("A") .patternLine("P")), - + GANTRY_PINION = create(AllBlocks.GANTRY_CARRIAGE).unlockedBy(I::andesiteCasing) .viaShaped(b -> b.key('B', ItemTags.PLANKS) .key('S', I.cog()) @@ -598,6 +598,14 @@ public class StandardRecipeGen extends CreateRecipeProvider { .patternLine("A") .patternLine("I")), + WEIGHTED_EJECTOR = create(AllBlocks.WEIGHTED_EJECTOR).unlockedBy(I::andesiteCasing) + .viaShaped(b -> b.key('A', AllItems.GOLDEN_SHEET.get()) + .key('D', AllBlocks.DEPOT.get()) + .key('I', I.cog()) + .patternLine("A") + .patternLine("D") + .patternLine("I")), + MECHANICAL_ARM = create(AllBlocks.MECHANICAL_ARM::get).unlockedBy(I::brassCasing) .returns(1) .viaShaped(b -> b.key('L', I.brassSheet()) diff --git a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java index 2d8d65d10..502b1655f 100644 --- a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java +++ b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java @@ -1,11 +1,22 @@ package com.simibubi.create.foundation.networking; +import static net.minecraftforge.fml.network.NetworkDirection.PLAY_TO_CLIENT; +import static net.minecraftforge.fml.network.NetworkDirection.PLAY_TO_SERVER; + +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.function.Supplier; + import com.simibubi.create.Create; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionDisassemblyPacket; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionStallPacket; import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryContraptionUpdatePacket; import com.simibubi.create.content.contraptions.components.structureMovement.glue.GlueEffectPacket; -import com.simibubi.create.content.contraptions.components.structureMovement.sync.*; +import com.simibubi.create.content.contraptions.components.structureMovement.sync.ClientMotionPacket; +import com.simibubi.create.content.contraptions.components.structureMovement.sync.ContraptionFluidPacket; +import com.simibubi.create.content.contraptions.components.structureMovement.sync.ContraptionInteractionPacket; +import com.simibubi.create.content.contraptions.components.structureMovement.sync.ContraptionSeatMappingPacket; +import com.simibubi.create.content.contraptions.components.structureMovement.sync.LimbSwingUpdatePacket; import com.simibubi.create.content.contraptions.components.structureMovement.train.CouplingCreationPacket; import com.simibubi.create.content.contraptions.components.structureMovement.train.capability.MinecartControllerUpdatePacket; import com.simibubi.create.content.contraptions.fluids.actors.FluidSplashPacket; @@ -13,18 +24,26 @@ import com.simibubi.create.content.contraptions.relays.advanced.sequencer.Config import com.simibubi.create.content.curiosities.symmetry.SymmetryEffectPacket; import com.simibubi.create.content.curiosities.tools.ExtendoGripInteractionPacket; import com.simibubi.create.content.curiosities.zapper.ZapperBeamPacket; +import com.simibubi.create.content.logistics.block.depot.EjectorElytraPacket; +import com.simibubi.create.content.logistics.block.depot.EjectorPlacementPacket; +import com.simibubi.create.content.logistics.block.depot.EjectorTriggerPacket; import com.simibubi.create.content.logistics.block.mechanicalArm.ArmPlacementPacket; import com.simibubi.create.content.logistics.item.filter.FilterScreenPacket; import com.simibubi.create.content.logistics.packet.ConfigureFlexcratePacket; import com.simibubi.create.content.logistics.packet.ConfigureStockswitchPacket; import com.simibubi.create.content.logistics.packet.FunnelFlapPacket; import com.simibubi.create.content.logistics.packet.TunnelFlapPacket; -import com.simibubi.create.content.schematics.packet.*; +import com.simibubi.create.content.schematics.packet.ConfigureSchematicannonPacket; +import com.simibubi.create.content.schematics.packet.InstantSchematicPacket; +import com.simibubi.create.content.schematics.packet.SchematicPlacePacket; +import com.simibubi.create.content.schematics.packet.SchematicSyncPacket; +import com.simibubi.create.content.schematics.packet.SchematicUploadPacket; import com.simibubi.create.foundation.command.ConfigureConfigPacket; import com.simibubi.create.foundation.command.HighlightPacket; import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringCountUpdatePacket; import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollValueUpdatePacket; import com.simibubi.create.foundation.utility.ServerSpeedProvider; + import net.minecraft.network.PacketBuffer; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; @@ -36,13 +55,6 @@ import net.minecraftforge.fml.network.PacketDistributor; import net.minecraftforge.fml.network.PacketDistributor.TargetPoint; import net.minecraftforge.fml.network.simple.SimpleChannel; -import java.util.function.BiConsumer; -import java.util.function.Function; -import java.util.function.Supplier; - -import static net.minecraftforge.fml.network.NetworkDirection.PLAY_TO_CLIENT; -import static net.minecraftforge.fml.network.NetworkDirection.PLAY_TO_SERVER; - public enum AllPackets { // Client to Server @@ -64,6 +76,9 @@ public enum AllPackets { INSTANT_SCHEMATIC(InstantSchematicPacket.class, InstantSchematicPacket::new, PLAY_TO_SERVER), SYNC_SCHEMATIC(SchematicSyncPacket.class, SchematicSyncPacket::new, PLAY_TO_SERVER), LEFT_CLICK(LeftClickPacket.class, LeftClickPacket::new, PLAY_TO_SERVER), + PLACE_EJECTOR(EjectorPlacementPacket.class, EjectorPlacementPacket::new, PLAY_TO_SERVER), + TRIGGER_EJECTOR(EjectorTriggerPacket.class, EjectorTriggerPacket::new, PLAY_TO_SERVER), + EJECTOR_ELYTRA(EjectorElytraPacket.class, EjectorElytraPacket::new, PLAY_TO_SERVER), // Server to Client SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new, PLAY_TO_CLIENT), diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndex.java b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndex.java index 9eaf3c289..3ade7e53e 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndex.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndex.java @@ -307,6 +307,7 @@ public class PonderIndex { .add(AllItems.BELT_CONNECTOR) .add(AllBlocks.CHUTE) .add(AllBlocks.DEPOT) + .add(AllBlocks.WEIGHTED_EJECTOR) .add(AllBlocks.BASIN) .add(AllBlocks.ANDESITE_FUNNEL) .add(AllBlocks.BRASS_FUNNEL) @@ -326,6 +327,7 @@ public class PonderIndex { .add(AllBlocks.CHUTE) .add(AllBlocks.SMART_CHUTE) .add(AllBlocks.DEPOT) + .add(AllBlocks.WEIGHTED_EJECTOR) .add(AllBlocks.MECHANICAL_ARM) .add(AllBlocks.ANDESITE_FUNNEL) .add(AllBlocks.BRASS_FUNNEL) diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/belt/DirectBeltInputBehaviour.java b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/belt/DirectBeltInputBehaviour.java index f7f0164e0..823568969 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/belt/DirectBeltInputBehaviour.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/belt/DirectBeltInputBehaviour.java @@ -98,7 +98,7 @@ public class DirectBeltInputBehaviour extends TileEntityBehaviour { } @Nullable - public ItemStack tryExportingToBeltFunnel(ItemStack stack, @Nullable Direction side) { + public ItemStack tryExportingToBeltFunnel(ItemStack stack, @Nullable Direction side, boolean simulate) { BlockPos funnelPos = tileEntity.getPos() .up(); World world = getWorld(); @@ -112,8 +112,10 @@ public class DirectBeltInputBehaviour extends TileEntityBehaviour { TileEntity te = world.getTileEntity(funnelPos); if (!(te instanceof FunnelTileEntity)) return null; - ItemStack insert = FunnelBlock.tryInsert(world, funnelPos, stack, false); - if (insert.getCount() != stack.getCount()) + if (funnelState.get(BeltFunnelBlock.POWERED)) + return stack; + ItemStack insert = FunnelBlock.tryInsert(world, funnelPos, stack, simulate); + if (insert.getCount() != stack.getCount() && !simulate) ((FunnelTileEntity) te).flap(true); return insert; } diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/scrollvalue/ScrollValueBehaviour.java b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/scrollvalue/ScrollValueBehaviour.java index 9f0f3c089..0a3ec1bbe 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/scrollvalue/ScrollValueBehaviour.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/scrollvalue/ScrollValueBehaviour.java @@ -2,6 +2,7 @@ package com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue; import java.util.function.Consumer; import java.util.function.Function; +import java.util.function.Supplier; import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.tileEntity.SmartTileEntity; @@ -33,6 +34,7 @@ public class ScrollValueBehaviour extends TileEntityBehaviour { Function formatter; Function unit; Function step; + private Supplier isActive; boolean needsWrench; public ScrollValueBehaviour(String label, SmartTileEntity te, ValueBoxTransform slot) { @@ -47,6 +49,7 @@ public class ScrollValueBehaviour extends TileEntityBehaviour { formatter = i -> Integer.toString(i); step = (c) -> 1; value = 0; + isActive = () -> true; ticksUntilScrollPacket = -1; } @@ -122,6 +125,11 @@ public class ScrollValueBehaviour extends TileEntityBehaviour { this.unit = unit; return this; } + + public ScrollValueBehaviour onlyActiveWhen(Supplier condition) { + isActive = condition; + return this; + } public ScrollValueBehaviour withStepFunction(Function step) { this.step = step; @@ -159,6 +167,10 @@ public class ScrollValueBehaviour extends TileEntityBehaviour { public BehaviourType getType() { return TYPE; } + + public boolean isActive() { + return isActive.get(); + } public boolean testHit(Vec3d hit) { BlockState state = tileEntity.getBlockState(); diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/scrollvalue/ScrollValueHandler.java b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/scrollvalue/ScrollValueHandler.java index 52b6ddf8e..87dd0a1fb 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/scrollvalue/ScrollValueHandler.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/scrollvalue/ScrollValueHandler.java @@ -40,6 +40,8 @@ public class ScrollValueHandler { ScrollValueBehaviour scrolling = TileEntityBehaviour.get(world, blockPos, ScrollValueBehaviour.TYPE); if (scrolling == null) return false; + if (!scrolling.isActive()) + return false; if (!mc.player.isAllowEdit()) return false; diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/scrollvalue/ScrollValueRenderer.java b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/scrollvalue/ScrollValueRenderer.java index 6171633ab..55ecc9761 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/scrollvalue/ScrollValueRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/scrollvalue/ScrollValueRenderer.java @@ -35,7 +35,9 @@ public class ScrollValueRenderer { ScrollValueBehaviour behaviour = TileEntityBehaviour.get(world, pos, ScrollValueBehaviour.TYPE); if (behaviour == null) return; - if (behaviour.needsWrench && !AllItems.WRENCH.isIn(Minecraft.getInstance().player.getHeldItemMainhand())) + if (!behaviour.isActive()) + return; + if (behaviour.needsWrench && !AllItems.WRENCH.isIn(mc.player.getHeldItemMainhand())) return; boolean highlight = behaviour.testHit(target.getHitVec()); diff --git a/src/main/java/com/simibubi/create/foundation/utility/IntAttached.java b/src/main/java/com/simibubi/create/foundation/utility/IntAttached.java index 6353b0d2d..157b533dc 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/IntAttached.java +++ b/src/main/java/com/simibubi/create/foundation/utility/IntAttached.java @@ -1,37 +1,56 @@ package com.simibubi.create.foundation.utility; +import java.util.function.Function; + +import net.minecraft.nbt.CompoundNBT; + public class IntAttached extends Pair { protected IntAttached(Integer first, V second) { super(first, second); } - + public static IntAttached with(int number, V value) { return new IntAttached<>(number, value); } - + public static IntAttached withZero(V value) { return new IntAttached<>(0, value); } - + public boolean isZero() { return first.intValue() == 0; } - + + public boolean exceeds(int value) { + return first.intValue() > value; + } + public boolean isOrBelowZero() { return first.intValue() <= 0; } - + public void increment() { first++; } - + public void decrement() { first--; } - + public V getValue() { return getSecond(); } + public CompoundNBT serializeNBT(Function serializer) { + CompoundNBT nbt = new CompoundNBT(); + nbt.put("Item", serializer.apply(getValue())); + nbt.putInt("Location", getFirst()); + return nbt; + } + + public static IntAttached read(CompoundNBT nbt, Function deserializer) { + return IntAttached.with(nbt.getInt("Location"), deserializer.apply(nbt.getCompound("Item"))); + } + } diff --git a/src/main/resources/assets/create/lang/default/messages.json b/src/main/resources/assets/create/lang/default/messages.json index 37ee82398..2131d38a8 100644 --- a/src/main/resources/assets/create/lang/default/messages.json +++ b/src/main/resources/assets/create/lang/default/messages.json @@ -443,6 +443,12 @@ "create.mechanical_arm.deposit_to": "Deposit items to %1$s", "create.mechanical_arm.summary": "Mechanical Arm has %1$s input(s) and %2$s output(s).", "create.mechanical_arm.points_outside_range": "%1$s selected interaction point(s) removed due to range limitations.", + + "create.weighted_ejector.target_set": "Target Selected", + "create.weighted_ejector.target_not_valid": "Ejecting to Adjacent block (Target was not Valid)", + "create.weighted_ejector.no_target": "Ejecting to Adjacent block (No Target was Selected)", + "create.weighted_ejector.targeting": "Ejecting to [%1$s,%2$s,%3$s]", + "create.weighted_ejector.stack_size": "Ejected Stack Size", "create.logistics.when_multiple_outputs_available": "When Multiple Outputs Available", diff --git a/src/main/resources/assets/create/models/block/weighted_ejector/block.json b/src/main/resources/assets/create/models/block/weighted_ejector/block.json new file mode 100644 index 000000000..962f1426d --- /dev/null +++ b/src/main/resources/assets/create/models/block/weighted_ejector/block.json @@ -0,0 +1,112 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "3": "create:block/weighted_ejector_casing", + "7": "create:block/andesite_casing", + "particle": "create:block/weighted_ejector_top" + }, + "elements": [ + { + "from": [0, 2, 14], + "to": [16, 11, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 7.25, 8]}, + "faces": { + "north": {"uv": [0, 10.5, 8, 15], "texture": "#3"}, + "east": {"uv": [0, 10.5, 1, 15], "texture": "#3"}, + "south": {"uv": [0, 10.5, 8, 15], "texture": "#3"}, + "west": {"uv": [7, 10.5, 8, 15], "texture": "#3"}, + "up": {"uv": [0, 7, 8, 8], "texture": "#3"} + } + }, + { + "from": [0, 0, 0], + "to": [16, 2, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 7.25, 8]}, + "faces": { + "north": {"uv": [0, 15, 8, 16], "texture": "#3"}, + "east": {"uv": [0, 15, 8, 16], "texture": "#3"}, + "south": {"uv": [0, 15, 8, 16], "texture": "#3"}, + "west": {"uv": [0, 15, 8, 16], "texture": "#3"}, + "up": {"uv": [0, 0, 16, 16], "rotation": 270, "texture": "#7"}, + "down": {"uv": [0, 0, 16, 16], "rotation": 270, "texture": "#7"} + } + }, + { + "from": [1, 2, 2], + "to": [15, 11, 14], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 7.25, 8]}, + "faces": { + "east": {"uv": [9, 2.5, 15, 7], "texture": "#3"}, + "west": {"uv": [9, 2.5, 15, 7], "texture": "#3"}, + "up": {"uv": [0.5, 1, 7.5, 7], "texture": "#3"} + } + }, + { + "from": [12, 11, 5], + "to": [15, 12, 11], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 7.25, 8]}, + "faces": { + "north": {"uv": [6, 2, 7.5, 2.5], "rotation": 180, "texture": "#3"}, + "east": {"uv": [10.5, 2, 13.5, 2.5], "texture": "#3"}, + "south": {"uv": [6, 5.5, 7.5, 6], "texture": "#3"}, + "west": {"uv": [6, 2.5, 6.5, 5.5], "rotation": 90, "texture": "#3"}, + "up": {"uv": [6, 2.5, 7.5, 5.5], "texture": "#3"} + } + }, + { + "from": [1, 11, 5], + "to": [4, 12, 11], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 7.25, 8]}, + "faces": { + "north": {"uv": [6, 5.5, 7.5, 6], "texture": "#3"}, + "east": {"uv": [6, 2.5, 6.5, 5.5], "rotation": 90, "texture": "#3"}, + "south": {"uv": [6, 2, 7.5, 2.5], "rotation": 180, "texture": "#3"}, + "west": {"uv": [10.5, 2, 13.5, 2.5], "texture": "#3"}, + "up": {"uv": [6, 2.5, 7.5, 5.5], "rotation": 180, "texture": "#3"} + } + }, + { + "from": [0, 2, 0], + "to": [16, 11, 2], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 7.25, 8]}, + "faces": { + "north": {"uv": [8, 10.5, 16, 15], "texture": "#3"}, + "east": {"uv": [7, 10.5, 8, 15], "texture": "#3"}, + "south": {"uv": [0, 10.5, 8, 15], "texture": "#3"}, + "west": {"uv": [0, 10.5, 1, 15], "texture": "#3"}, + "up": {"uv": [0, 0, 8, 1], "texture": "#3"} + } + }, + { + "from": [12, 9.5, -0.5], + "to": [14, 12.5, 2.5], + "faces": { + "north": {"uv": [8, 0, 9, 1.5], "texture": "#3"}, + "east": {"uv": [14, 0, 15.5, 1.5], "texture": "#3"}, + "south": {"uv": [8, 0, 9, 1.5], "rotation": 180, "texture": "#3"}, + "west": {"uv": [14, 0, 15.5, 1.5], "texture": "#3"}, + "up": {"uv": [8, 0, 9, 1.5], "rotation": 180, "texture": "#3"}, + "down": {"uv": [8, 0, 9, 1.5], "rotation": 180, "texture": "#3"} + } + }, + { + "from": [2, 9.5, -0.5], + "to": [4, 12.5, 2.5], + "faces": { + "north": {"uv": [8, 0, 9, 1.5], "texture": "#3"}, + "east": {"uv": [14, 0, 15.5, 1.5], "texture": "#3"}, + "south": {"uv": [8, 0, 9, 1.5], "rotation": 180, "texture": "#3"}, + "west": {"uv": [14, 0, 15.5, 1.5], "texture": "#3"}, + "up": {"uv": [8, 0, 9, 1.5], "rotation": 180, "texture": "#3"}, + "down": {"uv": [8, 0, 9, 1.5], "rotation": 180, "texture": "#3"} + } + } + ], + "groups": [ + { + "name": "casing", + "origin": [0, 0, 0], + "children": [0, 1, 2, 3, 4, 5, 6, 7] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/weighted_ejector/item.json b/src/main/resources/assets/create/models/block/weighted_ejector/item.json new file mode 100644 index 000000000..ac666180d --- /dev/null +++ b/src/main/resources/assets/create/models/block/weighted_ejector/item.json @@ -0,0 +1,247 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "0": "block/stripped_spruce_log_top", + "1": "create:block/axis", + "2": "block/stripped_spruce_log", + "3": "create:block/weighted_ejector_casing", + "4": "create:block/weighted_ejector_top", + "5": "create:block/weighted_ejector_inner", + "6": "create:block/axis_top", + "7": "create:block/andesite_casing", + "particle": "create:block/weighted_ejector_top" + }, + "elements": [ + { + "from": [0, 6, 6], + "to": [16, 10, 10], + "faces": { + "north": {"uv": [6, 0, 10, 16], "rotation": 90, "texture": "#1"}, + "east": {"uv": [6, 6, 10, 10], "texture": "#6"}, + "south": {"uv": [6, 0, 10, 16], "rotation": 90, "texture": "#1"}, + "west": {"uv": [6, 6, 10, 10], "texture": "#6"}, + "up": {"uv": [6, 0, 10, 16], "rotation": 90, "texture": "#1"}, + "down": {"uv": [6, 0, 10, 16], "rotation": 90, "texture": "#1"} + } + }, + { + "from": [4, 9.5, -0.5], + "to": [12, 12.5, 2.5], + "faces": { + "north": {"uv": [9, 0, 13, 1.5], "texture": "#3"}, + "east": {"uv": [12.5, 0, 13, 0.5], "texture": "#3"}, + "south": {"uv": [9, 0, 13, 1.5], "texture": "#3"}, + "west": {"uv": [12.5, 0, 13, 0.5], "texture": "#3"}, + "up": {"uv": [9, 0, 13, 1.5], "rotation": 180, "texture": "#3"}, + "down": {"uv": [9, 0, 13, 1.5], "texture": "#3"} + } + }, + { + "from": [6, 7, 1], + "to": [10, 11, 5], + "faces": { + "east": {"uv": [4, 8, 8, 12], "texture": "#0"}, + "south": {"uv": [5, 10, 9, 14], "texture": "#2"}, + "west": {"uv": [8, 8, 12, 12], "texture": "#0"}, + "down": {"uv": [5, 10, 9, 14], "texture": "#2"} + } + }, + { + "from": [7.5, 5, 1], + "to": [8.5, 11, 7], + "faces": { + "east": {"uv": [2, 8, 8, 14], "texture": "#0"}, + "south": {"uv": [13, 8, 14, 14], "texture": "#0"}, + "west": {"uv": [8, 8, 14, 14], "texture": "#0"}, + "down": {"uv": [13, 4, 14, 10], "texture": "#0"} + } + }, + { + "from": [0.9, 11, 1], + "to": [15.1, 13, 15], + "faces": { + "north": {"uv": [1, 14, 15, 16], "texture": "#4"}, + "east": {"uv": [1, 14, 15, 16], "texture": "#4"}, + "south": {"uv": [1, 14, 15, 16], "texture": "#4"}, + "west": {"uv": [1, 14, 15, 16], "texture": "#4"}, + "up": {"uv": [1, 0, 15, 14], "rotation": 180, "texture": "#4"}, + "down": {"uv": [1, 1, 15, 15], "texture": "#5"} + } + }, + { + "from": [7, 2, 1], + "to": [9, 11, 2], + "rotation": {"angle": 0, "axis": "x", "origin": [8, 11, 1]}, + "faces": { + "east": {"uv": [3, 0, 4, 9], "texture": "#2"}, + "south": {"uv": [3, 0, 5, 9], "texture": "#2"}, + "west": {"uv": [3, 0, 4, 9], "texture": "#2"}, + "down": {"uv": [3, 0, 5, 1], "texture": "#2"} + } + }, + { + "from": [7, 2, 0], + "to": [9, 11, 2], + "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 11, 1]}, + "faces": { + "north": {"uv": [3, 0, 5, 9], "texture": "#2"}, + "east": {"uv": [3, 0, 5, 9], "texture": "#2"}, + "south": {"uv": [3, 0, 5, 9], "texture": "#2"}, + "west": {"uv": [3, 0, 5, 9], "texture": "#2"}, + "up": {"uv": [0, 0, 2, 2], "texture": "#2"}, + "down": {"uv": [3, 0, 5, 2], "texture": "#2"} + } + }, + { + "from": [7, 2, 0], + "to": [9, 11, 2], + "rotation": {"angle": -45, "axis": "x", "origin": [8, 11, 1]}, + "faces": { + "north": {"uv": [3, 0, 5, 9], "texture": "#2"}, + "east": {"uv": [3, 0, 5, 9], "texture": "#2"}, + "south": {"uv": [3, 0, 5, 9], "texture": "#2"}, + "west": {"uv": [3, 0, 5, 9], "texture": "#2"}, + "up": {"uv": [0, 0, 2, 2], "texture": "#2"}, + "down": {"uv": [3, 0, 5, 2], "texture": "#2"} + } + }, + { + "from": [7, 10, 1], + "to": [9, 12, 10], + "rotation": {"angle": 22.5, "axis": "x", "origin": [8, 11, 1]}, + "faces": { + "north": {"uv": [0, 0, 2, 2], "rotation": 180, "texture": "#2"}, + "east": {"uv": [3, 0, 5, 9], "rotation": 90, "texture": "#2"}, + "south": {"uv": [3, 0, 5, 2], "texture": "#2"}, + "west": {"uv": [3, 0, 5, 9], "rotation": 270, "texture": "#2"}, + "up": {"uv": [3, 0, 5, 9], "texture": "#2"}, + "down": {"uv": [3, 0, 5, 9], "rotation": 180, "texture": "#2"} + } + }, + { + "from": [7, 10, 1], + "to": [9, 11, 10], + "rotation": {"angle": 0, "axis": "x", "origin": [8, 11, 1]}, + "faces": { + "east": {"uv": [3, 0, 4, 9], "rotation": 90, "texture": "#2"}, + "south": {"uv": [3, 0, 5, 1], "texture": "#2"}, + "west": {"uv": [3, 0, 4, 9], "rotation": 270, "texture": "#2"}, + "up": {"uv": [0, 0, 2, 9], "texture": "#2"}, + "down": {"uv": [3, 0, 5, 9], "rotation": 180, "texture": "#2"} + } + }, + { + "from": [0, 2, 14], + "to": [16, 11, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 7.25, 8]}, + "faces": { + "north": {"uv": [0, 10.5, 8, 15], "texture": "#3"}, + "east": {"uv": [0, 10.5, 1, 15], "texture": "#3"}, + "south": {"uv": [0, 10.5, 8, 15], "texture": "#3"}, + "west": {"uv": [7, 10.5, 8, 15], "texture": "#3"}, + "up": {"uv": [0, 7, 8, 8], "texture": "#3"} + } + }, + { + "from": [0, 0, 0], + "to": [16, 2, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 7.25, 8]}, + "faces": { + "north": {"uv": [0, 15, 8, 16], "texture": "#3"}, + "east": {"uv": [0, 15, 8, 16], "texture": "#3"}, + "south": {"uv": [0, 15, 8, 16], "texture": "#3"}, + "west": {"uv": [0, 15, 8, 16], "texture": "#3"}, + "up": {"uv": [0, 0, 16, 16], "rotation": 270, "texture": "#7"}, + "down": {"uv": [0, 0, 16, 16], "rotation": 270, "texture": "#7"} + } + }, + { + "from": [1, 2, 2], + "to": [15, 11, 14], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 7.25, 8]}, + "faces": { + "east": {"uv": [9, 2.5, 15, 7], "texture": "#3"}, + "west": {"uv": [9, 2.5, 15, 7], "texture": "#3"}, + "up": {"uv": [0.5, 1, 7.5, 7], "texture": "#3"} + } + }, + { + "from": [12, 11, 5], + "to": [15, 12, 11], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 7.25, 8]}, + "faces": { + "north": {"uv": [6, 2, 7.5, 2.5], "rotation": 180, "texture": "#3"}, + "east": {"uv": [10.5, 2, 13.5, 2.5], "texture": "#3"}, + "south": {"uv": [6, 5.5, 7.5, 6], "texture": "#3"}, + "west": {"uv": [6, 2.5, 6.5, 5.5], "rotation": 90, "texture": "#3"}, + "up": {"uv": [6, 2.5, 7.5, 5.5], "texture": "#3"} + } + }, + { + "from": [1, 11, 5], + "to": [4, 12, 11], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 7.25, 8]}, + "faces": { + "north": {"uv": [6, 5.5, 7.5, 6], "texture": "#3"}, + "east": {"uv": [6, 2.5, 6.5, 5.5], "rotation": 90, "texture": "#3"}, + "south": {"uv": [6, 2, 7.5, 2.5], "rotation": 180, "texture": "#3"}, + "west": {"uv": [10.5, 2, 13.5, 2.5], "texture": "#3"}, + "up": {"uv": [6, 2.5, 7.5, 5.5], "rotation": 180, "texture": "#3"} + } + }, + { + "from": [0, 2, 0], + "to": [16, 11, 2], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 7.25, 8]}, + "faces": { + "north": {"uv": [8, 10.5, 16, 15], "texture": "#3"}, + "east": {"uv": [7, 10.5, 8, 15], "texture": "#3"}, + "south": {"uv": [0, 10.5, 8, 15], "texture": "#3"}, + "west": {"uv": [0, 10.5, 1, 15], "texture": "#3"}, + "up": {"uv": [0, 0, 8, 1], "texture": "#3"} + } + }, + { + "from": [12, 9.5, -0.5], + "to": [14, 12.5, 2.5], + "faces": { + "north": {"uv": [8, 0, 9, 1.5], "texture": "#3"}, + "east": {"uv": [14, 0, 15.5, 1.5], "texture": "#3"}, + "south": {"uv": [8, 0, 9, 1.5], "rotation": 180, "texture": "#3"}, + "west": {"uv": [14, 0, 15.5, 1.5], "texture": "#3"}, + "up": {"uv": [8, 0, 9, 1.5], "rotation": 180, "texture": "#3"}, + "down": {"uv": [8, 0, 9, 1.5], "rotation": 180, "texture": "#3"} + } + }, + { + "from": [2, 9.5, -0.5], + "to": [4, 12.5, 2.5], + "faces": { + "north": {"uv": [8, 0, 9, 1.5], "texture": "#3"}, + "east": {"uv": [14, 0, 15.5, 1.5], "texture": "#3"}, + "south": {"uv": [8, 0, 9, 1.5], "rotation": 180, "texture": "#3"}, + "west": {"uv": [14, 0, 15.5, 1.5], "texture": "#3"}, + "up": {"uv": [8, 0, 9, 1.5], "rotation": 180, "texture": "#3"}, + "down": {"uv": [8, 0, 9, 1.5], "rotation": 180, "texture": "#3"} + } + } + ], + "groups": [ + { + "name": "Axle", + "origin": [0, 0, 0], + "children": [0] + }, + { + "name": "Panel", + "origin": [0, 0, 0], + "children": [1, 2, 3, 4, 5, 6, 7, 8, 9] + }, + { + "name": "casing", + "origin": [0, 0, 0], + "children": [10, 11, 12, 13, 14, 15, 16, 17] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/weighted_ejector/top.json b/src/main/resources/assets/create/models/block/weighted_ejector/top.json new file mode 100644 index 000000000..4aad7bdc9 --- /dev/null +++ b/src/main/resources/assets/create/models/block/weighted_ejector/top.json @@ -0,0 +1,126 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "0": "block/stripped_spruce_log_top", + "2": "block/stripped_spruce_log", + "3": "create:block/weighted_ejector_casing", + "4": "create:block/weighted_ejector_top", + "5": "create:block/weighted_ejector_inner", + "particle": "create:block/weighted_ejector_top" + }, + "elements": [ + { + "from": [4, 9.5, -0.5], + "to": [12, 12.5, 2.5], + "faces": { + "north": {"uv": [9, 0, 13, 1.5], "texture": "#3"}, + "east": {"uv": [12.5, 0, 13, 0.5], "texture": "#3"}, + "south": {"uv": [9, 0, 13, 1.5], "texture": "#3"}, + "west": {"uv": [12.5, 0, 13, 0.5], "texture": "#3"}, + "up": {"uv": [9, 0, 13, 1.5], "rotation": 180, "texture": "#3"}, + "down": {"uv": [9, 0, 13, 1.5], "texture": "#3"} + } + }, + { + "from": [6, 7, 1], + "to": [10, 11, 5], + "faces": { + "east": {"uv": [4, 8, 8, 12], "texture": "#0"}, + "south": {"uv": [5, 10, 9, 14], "texture": "#2"}, + "west": {"uv": [8, 8, 12, 12], "texture": "#0"}, + "down": {"uv": [5, 10, 9, 14], "texture": "#2"} + } + }, + { + "from": [7.5, 5, 1], + "to": [8.5, 11, 7], + "faces": { + "east": {"uv": [2, 8, 8, 14], "texture": "#0"}, + "south": {"uv": [13, 8, 14, 14], "texture": "#0"}, + "west": {"uv": [8, 8, 14, 14], "texture": "#0"}, + "down": {"uv": [13, 4, 14, 10], "texture": "#0"} + } + }, + { + "from": [0.9, 11, 1], + "to": [15.1, 13, 15], + "faces": { + "north": {"uv": [1, 14, 15, 16], "texture": "#4"}, + "east": {"uv": [1, 14, 15, 16], "texture": "#4"}, + "south": {"uv": [1, 14, 15, 16], "texture": "#4"}, + "west": {"uv": [1, 14, 15, 16], "texture": "#4"}, + "up": {"uv": [1, 0, 15, 14], "rotation": 180, "texture": "#4"}, + "down": {"uv": [1, 1, 15, 15], "texture": "#5"} + } + }, + { + "from": [7, 2, 1], + "to": [9, 11, 2], + "rotation": {"angle": 0, "axis": "x", "origin": [8, 11, 1]}, + "faces": { + "east": {"uv": [3, 0, 4, 9], "texture": "#2"}, + "south": {"uv": [3, 0, 5, 9], "texture": "#2"}, + "west": {"uv": [3, 0, 4, 9], "texture": "#2"}, + "down": {"uv": [3, 0, 5, 1], "texture": "#2"} + } + }, + { + "from": [7, 2, 0], + "to": [9, 11, 2], + "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 11, 1]}, + "faces": { + "north": {"uv": [3, 0, 5, 9], "texture": "#2"}, + "east": {"uv": [3, 0, 5, 9], "texture": "#2"}, + "south": {"uv": [3, 0, 5, 9], "texture": "#2"}, + "west": {"uv": [3, 0, 5, 9], "texture": "#2"}, + "up": {"uv": [0, 0, 2, 2], "texture": "#2"}, + "down": {"uv": [3, 0, 5, 2], "texture": "#2"} + } + }, + { + "from": [7, 2, 0], + "to": [9, 11, 2], + "rotation": {"angle": -45, "axis": "x", "origin": [8, 11, 1]}, + "faces": { + "north": {"uv": [3, 0, 5, 9], "texture": "#2"}, + "east": {"uv": [3, 0, 5, 9], "texture": "#2"}, + "south": {"uv": [3, 0, 5, 9], "texture": "#2"}, + "west": {"uv": [3, 0, 5, 9], "texture": "#2"}, + "up": {"uv": [0, 0, 2, 2], "texture": "#2"}, + "down": {"uv": [3, 0, 5, 2], "texture": "#2"} + } + }, + { + "from": [7, 10, 1], + "to": [9, 12, 10], + "rotation": {"angle": 22.5, "axis": "x", "origin": [8, 11, 1]}, + "faces": { + "north": {"uv": [0, 0, 2, 2], "rotation": 180, "texture": "#2"}, + "east": {"uv": [3, 0, 5, 9], "rotation": 90, "texture": "#2"}, + "south": {"uv": [3, 0, 5, 2], "texture": "#2"}, + "west": {"uv": [3, 0, 5, 9], "rotation": 270, "texture": "#2"}, + "up": {"uv": [3, 0, 5, 9], "texture": "#2"}, + "down": {"uv": [3, 0, 5, 9], "rotation": 180, "texture": "#2"} + } + }, + { + "from": [7, 10, 1], + "to": [9, 11, 10], + "rotation": {"angle": 0, "axis": "x", "origin": [8, 11, 1]}, + "faces": { + "east": {"uv": [3, 0, 4, 9], "rotation": 90, "texture": "#2"}, + "south": {"uv": [3, 0, 5, 1], "texture": "#2"}, + "west": {"uv": [3, 0, 4, 9], "rotation": 270, "texture": "#2"}, + "up": {"uv": [0, 0, 2, 9], "texture": "#2"}, + "down": {"uv": [3, 0, 5, 9], "rotation": 180, "texture": "#2"} + } + } + ], + "groups": [ + { + "name": "Panel", + "origin": [0, 0, 0], + "children": [0, 1, 2, 3, 4, 5, 6, 7, 8] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/weighted_ejector/weighted depot.bbmodel b/src/main/resources/assets/create/models/block/weighted_ejector/weighted depot.bbmodel new file mode 100644 index 000000000..0305dd1ec --- /dev/null +++ b/src/main/resources/assets/create/models/block/weighted_ejector/weighted depot.bbmodel @@ -0,0 +1 @@ +{"meta":{"format_version":"3.6","creation_time":1616422453,"model_format":"java_block","box_uv":false},"name":"block","parent":"","ambientocclusion":true,"front_gui_light":false,"visible_box":[1,1,0],"resolution":{"width":16,"height":16},"elements":[{"name":"cube","rescale":false,"from":[0,2,14],"to":[16,11,16],"autouv":0,"color":3,"locked":false,"origin":[8,7.25,8],"faces":{"north":{"uv":[0,10.5,8,15],"texture":3},"east":{"uv":[0,10.5,1,15],"texture":3},"south":{"uv":[0,10.5,8,15],"texture":3},"west":{"uv":[7,10.5,8,15],"texture":3},"up":{"uv":[0,7,8,8],"texture":3},"down":{"uv":[0,0,0,0],"rotation":180,"texture":null}},"uuid":"a674be97-1571-0e0b-9250-c02dc00a2797"},{"name":"cube","rescale":false,"from":[0,0,0],"to":[16,2,16],"autouv":0,"color":3,"locked":false,"origin":[8,7.25,8],"faces":{"north":{"uv":[0,15,8,16],"texture":3},"east":{"uv":[0,15,8,16],"texture":3},"south":{"uv":[0,15,8,16],"texture":3},"west":{"uv":[0,15,8,16],"texture":3},"up":{"uv":[0,0,16,16],"rotation":270,"texture":7},"down":{"uv":[0,0,16,16],"rotation":270,"texture":7}},"uuid":"c48d3cb9-83e0-0ec6-129d-3e6e43fb49ab"},{"name":"cube","rescale":false,"from":[1,2,2],"to":[15,11,14],"autouv":0,"color":3,"locked":false,"origin":[8,7.25,8],"faces":{"north":{"uv":[0,0,0,0],"texture":null},"east":{"uv":[9,2.5,15,7],"texture":3},"south":{"uv":[0,0,0,0],"texture":null},"west":{"uv":[9,2.5,15,7],"texture":3},"up":{"uv":[0.5,1,7.5,7],"texture":3},"down":{"uv":[0,0,14,12],"rotation":180,"texture":null}},"uuid":"5e95266f-b869-61ca-589e-903db5b8aa74"},{"name":"cube","rescale":false,"from":[12,11,5],"to":[15,12,11],"autouv":0,"color":3,"locked":false,"origin":[8,7.25,8],"faces":{"north":{"uv":[6,2,7.5,2.5],"rotation":180,"texture":3},"east":{"uv":[10.5,2,13.5,2.5],"texture":3},"south":{"uv":[6,5.5,7.5,6],"texture":3},"west":{"uv":[6,2.5,6.5,5.5],"rotation":90,"texture":3},"up":{"uv":[6,2.5,7.5,5.5],"texture":3},"down":{"uv":[0,0,0,0],"rotation":180,"texture":null}},"uuid":"106c49a4-7dc1-3b19-2f15-62f1d86e5293"},{"name":"cube","rescale":false,"from":[1,11,5],"to":[4,12,11],"autouv":0,"color":3,"locked":false,"origin":[8,7.25,8],"faces":{"north":{"uv":[6,5.5,7.5,6],"texture":3},"east":{"uv":[6,2.5,6.5,5.5],"rotation":90,"texture":3},"south":{"uv":[6,2,7.5,2.5],"rotation":180,"texture":3},"west":{"uv":[10.5,2,13.5,2.5],"texture":3},"up":{"uv":[6,2.5,7.5,5.5],"rotation":180,"texture":3},"down":{"uv":[0,0,0,0],"texture":null}},"uuid":"a3bc1576-a101-cc4c-0845-f0392b61c6e3"},{"name":"cube","rescale":false,"from":[0,2,0],"to":[16,11,2],"autouv":0,"color":3,"locked":false,"origin":[8,7.25,8],"faces":{"north":{"uv":[8,10.5,16,15],"texture":3},"east":{"uv":[7,10.5,8,15],"texture":3},"south":{"uv":[0,10.5,8,15],"texture":3},"west":{"uv":[0,10.5,1,15],"texture":3},"up":{"uv":[0,0,8,1],"texture":3},"down":{"uv":[0,0,0,0],"rotation":180,"texture":null}},"uuid":"2152c06f-ea59-15eb-3822-e035c2f43d08"},{"name":"cube","rescale":false,"from":[12,9.5,-0.5],"to":[14,12.5,2.5],"autouv":0,"color":4,"locked":false,"origin":[0,0,0],"faces":{"north":{"uv":[8,0,9,1.5],"texture":3},"east":{"uv":[14,0,15.5,1.5],"texture":3},"south":{"uv":[8,0,9,1.5],"rotation":180,"texture":3},"west":{"uv":[14,0,15.5,1.5],"texture":3},"up":{"uv":[8,0,9,1.5],"rotation":180,"texture":3},"down":{"uv":[8,0,9,1.5],"rotation":180,"texture":3}},"uuid":"10f7f63f-0c8b-5146-0935-762444523f31"},{"name":"cube","rescale":false,"from":[2,9.5,-0.5],"to":[4,12.5,2.5],"autouv":0,"color":4,"locked":false,"origin":[0,0,0],"faces":{"north":{"uv":[8,0,9,1.5],"texture":3},"east":{"uv":[14,0,15.5,1.5],"texture":3},"south":{"uv":[8,0,9,1.5],"rotation":180,"texture":3},"west":{"uv":[14,0,15.5,1.5],"texture":3},"up":{"uv":[8,0,9,1.5],"rotation":180,"texture":3},"down":{"uv":[8,0,9,1.5],"rotation":180,"texture":3}},"uuid":"afe59684-f9f0-ed62-87b6-b62cd840f2fb"},{"name":"cube","rescale":false,"from":[4,9.5,-0.5],"to":[12,12.5,2.5],"autouv":0,"color":4,"locked":false,"origin":[0,0,0],"faces":{"north":{"uv":[9,0,13,1.5],"texture":3},"east":{"uv":[12.5,0,13,0.5],"texture":3},"south":{"uv":[9,0,13,1.5],"texture":3},"west":{"uv":[12.5,0,13,0.5],"texture":3},"up":{"uv":[9,0,13,1.5],"rotation":180,"texture":3},"down":{"uv":[9,0,13,1.5],"texture":3}},"uuid":"6bd86311-c10a-fa98-5fa9-5b33da4930ca"},{"name":"cube","rescale":false,"from":[6,7,1],"to":[10,11,5],"autouv":0,"color":4,"locked":false,"origin":[0,0,0],"faces":{"north":{"uv":[0,0,0,0],"texture":null},"east":{"uv":[4,8,8,12],"texture":0},"south":{"uv":[5,10,9,14],"texture":2},"west":{"uv":[8,8,12,12],"texture":0},"up":{"uv":[0,0,0,0],"rotation":180,"texture":null},"down":{"uv":[5,10,9,14],"texture":2}},"uuid":"ee6630af-053d-e4d1-1164-e79131171389"},{"name":"cube","rescale":false,"from":[7.5,5,1],"to":[8.5,11,7],"autouv":0,"color":4,"locked":false,"origin":[0,0,0],"faces":{"north":{"uv":[0,0,0,0],"texture":null},"east":{"uv":[2,8,8,14],"texture":0},"south":{"uv":[13,8,14,14],"texture":0},"west":{"uv":[8,8,14,14],"texture":0},"up":{"uv":[0,0,0,0],"rotation":180,"texture":null},"down":{"uv":[13,4,14,10],"texture":0}},"uuid":"eca3e169-faa6-13fc-967c-1405b4e66f21"},{"name":"cube","rescale":false,"from":[0.9000000000000004,11,1],"to":[15.1,13,15],"autouv":0,"color":6,"locked":false,"origin":[0,0,0],"faces":{"north":{"uv":[1,14,15,16],"texture":4},"east":{"uv":[1,14,15,16],"texture":4},"south":{"uv":[1,14,15,16],"texture":4},"west":{"uv":[1,14,15,16],"texture":4},"up":{"uv":[1,0,15,14],"rotation":180,"texture":4},"down":{"uv":[1,1,15,15],"texture":5}},"uuid":"c49fdf59-60cf-5b45-76be-2529faf56110"},{"name":"cube","rescale":false,"from":[7,2,1],"to":[9,11,2],"autouv":0,"color":7,"locked":false,"origin":[8,11,1],"faces":{"north":{"uv":[0,0,0,0],"texture":null},"east":{"uv":[3,0,4,9],"texture":2},"south":{"uv":[3,0,5,9],"texture":2},"west":{"uv":[3,0,4,9],"texture":2},"up":{"uv":[0,0,0,0],"texture":null},"down":{"uv":[3,0,5,1],"texture":2}},"uuid":"bea540c0-ba6b-2d4a-bd04-86f425a0c680"},{"name":"cube","rescale":false,"from":[7,2,0],"to":[9,11,2],"autouv":0,"color":7,"locked":false,"rotation":[-22.5,0,0],"origin":[8,11,1],"faces":{"north":{"uv":[3,0,5,9],"texture":2},"east":{"uv":[3,0,5,9],"texture":2},"south":{"uv":[3,0,5,9],"texture":2},"west":{"uv":[3,0,5,9],"texture":2},"up":{"uv":[0,0,2,2],"texture":2},"down":{"uv":[3,0,5,2],"texture":2}},"uuid":"3a040566-653a-4930-d68a-97ef0a1d4154"},{"name":"cube","rescale":false,"from":[7,2,0],"to":[9,11,2],"autouv":0,"color":7,"locked":false,"rotation":[-45,0,0],"origin":[8,11,1],"faces":{"north":{"uv":[3,0,5,9],"texture":2},"east":{"uv":[3,0,5,9],"texture":2},"south":{"uv":[3,0,5,9],"texture":2},"west":{"uv":[3,0,5,9],"texture":2},"up":{"uv":[0,0,2,2],"texture":2},"down":{"uv":[3,0,5,2],"texture":2}},"uuid":"b82cb1ef-cd34-c8d4-d895-98a664fa405d"},{"name":"cube","rescale":false,"from":[7,10,1],"to":[9,12,10],"autouv":0,"color":7,"locked":false,"rotation":[22.5,0,0],"origin":[8,11,1],"faces":{"north":{"uv":[0,0,2,2],"rotation":180,"texture":2},"east":{"uv":[3,0,5,9],"rotation":90,"texture":2},"south":{"uv":[3,0,5,2],"texture":2},"west":{"uv":[3,0,5,9],"rotation":270,"texture":2},"up":{"uv":[3,0,5,9],"texture":2},"down":{"uv":[3,0,5,9],"rotation":180,"texture":2}},"uuid":"1ada72dc-e226-60ac-da09-66ce88d11b19"},{"name":"cube","rescale":false,"from":[7,10,1],"to":[9,11,10],"autouv":0,"color":7,"locked":false,"origin":[8,11,1],"faces":{"north":{"uv":[0,0,0,0],"rotation":180,"texture":null},"east":{"uv":[3,0,4,9],"rotation":90,"texture":2},"south":{"uv":[3,0,5,1],"texture":2},"west":{"uv":[3,0,4,9],"rotation":270,"texture":2},"up":{"uv":[0,0,2,9],"texture":2},"down":{"uv":[3,0,5,9],"rotation":180,"texture":2}},"uuid":"5befc358-0247-08e3-e6d1-dfa841cdda05"},{"name":"cube","rescale":false,"from":[0,6,6],"to":[16,10,10],"autouv":0,"color":3,"locked":false,"origin":[0,0,0],"faces":{"north":{"uv":[6,0,10,16],"rotation":90,"texture":1},"east":{"uv":[6,6,10,10],"texture":6},"south":{"uv":[6,0,10,16],"rotation":90,"texture":1},"west":{"uv":[6,6,10,10],"texture":6},"up":{"uv":[6,0,10,16],"rotation":90,"texture":1},"down":{"uv":[6,0,10,16],"rotation":90,"texture":1}},"uuid":"cf15d7da-6f45-fd25-9080-d0c90c10f76b"}],"outliner":[{"name":"Axle","origin":[0,0,0],"uuid":"7ab30dad-c865-a77f-95f8-b93d379e090e","export":true,"isOpen":true,"locked":false,"visibility":true,"autouv":0,"children":["cf15d7da-6f45-fd25-9080-d0c90c10f76b"]},{"name":"Panel","origin":[0,0,0],"uuid":"6a669390-7a59-afc7-3d32-bba3ee3187cd","export":true,"isOpen":true,"locked":false,"visibility":true,"autouv":0,"children":["6bd86311-c10a-fa98-5fa9-5b33da4930ca","ee6630af-053d-e4d1-1164-e79131171389","eca3e169-faa6-13fc-967c-1405b4e66f21","c49fdf59-60cf-5b45-76be-2529faf56110","bea540c0-ba6b-2d4a-bd04-86f425a0c680","3a040566-653a-4930-d68a-97ef0a1d4154","b82cb1ef-cd34-c8d4-d895-98a664fa405d","1ada72dc-e226-60ac-da09-66ce88d11b19","5befc358-0247-08e3-e6d1-dfa841cdda05"]},{"name":"casing","origin":[0,0,0],"uuid":"cc99560f-632d-2dff-7155-065b2a90e320","export":true,"isOpen":true,"locked":false,"visibility":true,"autouv":0,"children":["a674be97-1571-0e0b-9250-c02dc00a2797","c48d3cb9-83e0-0ec6-129d-3e6e43fb49ab","5e95266f-b869-61ca-589e-903db5b8aa74","106c49a4-7dc1-3b19-2f15-62f1d86e5293","a3bc1576-a101-cc4c-0845-f0392b61c6e3","2152c06f-ea59-15eb-3822-e035c2f43d08","10f7f63f-0c8b-5146-0935-762444523f31","afe59684-f9f0-ed62-87b6-b62cd840f2fb"]}],"textures":[{"path":"D:\\simon\\Minecraft\\Minecraft Assets\\minecraft\\textures\\block\\stripped_spruce_log_top.png","name":"stripped_spruce_log_top.png","folder":"block","namespace":"minecraft","id":"0","particle":false,"visible":true,"mode":"bitmap","saved":true,"uuid":"bbdca491-2930-e433-fa37-d0f3a0984b2e","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABd0lEQVQ4T4VTXUsCURCd69quaGREGQkLuxBYBD1VWFREVD87gnoI6lUwCBQEJRHJMHE3lxtnltG7m+m8zN2Ze8+eMx/q7szTRESTSUTZrIUjG77FLMsipWZ3tCbSOs6rm6qrL/fd6WUcxkFIOcdmv1ZYoa/vH84jZtpjvU3q+sTVVwcu1VtdzjlOnn3RIRoEsTcNMVilXKD7WocUJJxXygxw6G9xMpyouYwk2OgOyS+t0kOtRer21NPH/iZ1BiEHQXuRQUZ/MKR8zqbXZm8mAcGNYgwAMJEBL7R3ijbXAQxwngJUd7f5EYKwZveTvNJ6goiZF7YsAUUEwGgcJhgATJjgjDxomxJeGr1ZDZYBCIM/EqSI8wBMDcIAMQHjGqCNR16yC0I9CEY8FzILaQmJIpoMlrVRusA1kEmUNpqjnAays5qHTACe3z+SADK60vdFTBKTeLFXnt6VSZRlQuK/hXp6a8dFxHpGUUSytniUXm/5g7nmmQzRL1QsAdCcJPRPAAAAAElFTkSuQmCC"},{"path":"C:\\Users\\simon\\Desktop\\Forge 15\\Create\\src\\main\\resources\\assets\\create\\textures\\block\\axis.png","name":"axis.png","folder":"block","namespace":"create","id":"1","particle":false,"visible":true,"mode":"bitmap","saved":true,"uuid":"b948b196-c141-2578-3238-7176bb64ee97","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAo0lEQVQ4T6WTIQ4EIQxFO4IRIECAgLshMBwKO+fCggWDZVOSSVbMJjulkpTH/+X3gB/lvZ/WWhhjQO8drus6nlofD7ExhDCFEOsOGcAYA+cc5JzfK4gxTnxdKQW1VhrgPE/QWu8pQAulFEgpvRvit4XWGg2AFjjnQAJgDqSUawYkC3eQUAEJgEEyxiwLpBxsA/AXMERYW0FCCyTAvUxkwL/r/AGRGnYRGJZooQAAAABJRU5ErkJggg=="},{"path":"D:\\simon\\Minecraft\\Minecraft Assets\\minecraft\\textures\\block\\stripped_spruce_log.png","name":"stripped_spruce_log.png","folder":"block","namespace":"minecraft","id":"2","particle":false,"visible":true,"mode":"bitmap","saved":true,"uuid":"fdfd493e-f0b7-20a0-8910-4706acab87bd","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABiklEQVQ4T12Tu07DQBBFx69sHIgipQAkCsQHUPApNPRUfDaioKGIFJngrF9BZ8xN4mzjxLtz5u694+Tt5ekwK3Irs8yWeWZFlljdHixPzX9vYmesMs38uQyJff5E/81KANwtFlYPva1D7oVVHAHdYP6e4k3b2E2YWVkkvs//pu1GwOPqyrtCZ5MiqUFB3ffeDQBQIF+/cQS8vz4f7hfBAS61GGUDOO+2Lmau6js2xvkJgE1JlGzvWOa278za/uQJhZyv+s7aYRgVyJCH63C8H4dQABCA1AFgFWlqu9iMHpACBXjAVZDJQipLXQGyT/c8SdwbB6zmwZ3mAN2qrvdNQYntdh5snpsDdM0JgE7EyDrPXrkDkBcAjh5IgYZFKUgRzqOAyJgXJTHxgCuwJFumykSKPrY7k1caIp9EUmCMNW26NwMl03gKQFIoosY9EEAK5D5mCSBFl7Oy3ccTQPI5pPgEUYwC6CNzwOXXiMM4z/O8UNMK3I2sO5sowAM2NP+KT4Ue8/+w6Wvk3R8qiEVpS5vUkAAAAABJRU5ErkJggg=="},{"path":"C:\\Users\\simon\\Desktop\\Forge 15\\Create\\src\\main\\resources\\assets\\create\\textures\\block\\weighted_ejector_casing.png","name":"weighted_ejector_casing.png","folder":"block","namespace":"create","id":"3","particle":false,"visible":true,"mode":"bitmap","saved":true,"uuid":"69183538-6a6b-157f-362b-f5995cbfb50f","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAE40lEQVRYR+1XX0xbZRT/ldv2tpf+uwULV4uFTgcDZmC6xJiQLCYumULi9jgjPqDGRH1xMb4Yn/SFB1/EZBpn4oOJ0WhciBrJthhnpokbkIEEZLA2bFS6Qf9Q2t7eW2vOd73tvR0MaX3ceem9p+d836/nO7/z+2oZeXmkBADT579GXlbocVdz8DZ0PvE0nE4nOHBQFAWJRAJut5vlkt9o8XgcoihCVVVIkoRsNgtBEDA6OmqxEIB94Yfw+di7u25sDHjutbcx+8cMglKQuSORCAKBQDmkUCiwZ7vdDgJA39GmtLnVamVgxsbGagdwfORNLC//yQDQwrNzs+jt7mWb0iZk5GfVnZ5GMKgB1UGYKtDZfRBnP3rPVIHkpraIbj63tphuz7zwBpaWr+HMx2cseypdVTA7gunfJ5HL5dhXwwMiLlxZwc14whT6QEBEd7sfE3Naaemc+w4f2hbAo/39Ja/PB4/Xy2K3MhlsrK/jytTUHWD3BOCxrlZ8O5kpAzhy9EkkE8kyeAJFP4bneUSiUazF4yy2JRBAeygEWZYZaDL9BzMA1xeXkcloC5/os2L8l2vY7ggOH5BwaYVncS6XCx0Ph9lCvT0Hkc3JEJw8zv04gfn5eazGYqYK3i9J6OnpwVODg1DzWrWpiRmA9fg60uk0cx7dl9sRwP6whGiumcV5PB4IboEdRSjUgctnT4O3cVDu68f4+DiKxaIJAMdxGBoagpCYAVBC77GXNACn3jpVWlpY+k8AqAJXk3cCIBpPjZ+Gz+PELb7rrgDc6VmkMnk8fuLVSgWqj2CnJqQeOLeo9REdQWtQYhUgjkcvfgm/V8BkvJGd/05H0G67ga2sgr7jr2Nh7t8K/DRxodwUzx5y4fL8X9uyoLoJO3sPMADBYAg/f/UBRJ8X0Yx7xyb8u1RCM24incpi8JV3NADVNCQAkXgS7QEfSqUScrKCFr+AmchtdLUF8MWvGyYa0gv1wOL5T9HkFQBLAy5e5yA0NkL0+9HQ0IB0KoVUMomBjiJUtYRUZguhgWHEYisaADrD3775EA+2imzxyFoCkt+FvKzCwVshODgsraYQCvggKyqyuUoJdQDUhC1NlRzK1Y3WsFut7NVisWAjtYXwkWE2SS0nnz9ZCof34+oPn8DltIPjgOhqEsEWEZmczJK8LhvWkgqaXHYoxSLsVo51MU1CMklqY/nEAivHsZiCUkReBcuhTRVVhaxUmPHIsRcrAHQe64g9oo896nzV/cR1MuK7zmPqAaogmdXhxFpsBU2ixhR6pzXWE7fhdLjLefrMoB/AjoCC9clklFLdR9/rfqPP6DeR3vDiE31sWuqf1XvVJSQ7bboX/z0A9yrAWFDNAL1j79bxxhx6Xrj0/Z4vtWww0SAy6jk5iae5/Cbjs85l8hOfW6Q2k56Tn/K/++x95AvKriDoRu2w20BXuvJ9wKjnNK1oohmnlj7h9FFq1PPq+8Be88taoOt5o9NuorGTt5VnOInTjbWUSc/1SVhrPgNg1HOPi4eDtyObU5Ev5E1gBIcdtxIZk55TQD35DIBRz70eAbKchZKt/EuyCTbwvOZPb+ZNek4A6slnAIx63tqs/b2qtvSWBiidkU16Tr568ssAatVzYxPWdB+gCtSj5wSgnvwyC2rVc8r7X+4Dter5btK7233gH2OsXLxIyeUHAAAAAElFTkSuQmCC"},{"path":"C:\\Users\\simon\\Desktop\\Forge 15\\Create\\src\\main\\resources\\assets\\create\\textures\\block\\weighted_ejector_top.png","name":"weighted_ejector_top.png","folder":"block","namespace":"create","id":"4","particle":true,"visible":true,"mode":"bitmap","saved":true,"uuid":"ebcca8ed-240c-1b6e-7682-0179476a394c","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACLElEQVQ4T4VTTUwTURD+tt3av9dCcQsNYKCAxsTePHjw6o1E46kHb8bE2JOBGEMvhIQ0MQaIl149cOpREm5600TPcuCwQAlLLJTIT9/CrtvumnnlbWmJcS8zb2be975vdkYBgEKh4JGlLxqJSBfsii+D3LL8/NLysqJIgL29XyIRCoWEjUU7QHQ+v+hcdBwHd25n0Q2wu+8j284fqOoNBAk+oEBVA3BdwHU9NJtN3BxIYXJsFAulUpvB7MyMt1M14Ng2bo2N4OyUixd7WST7GHR9B4PpNIaGtA6D+WLR+7mpg/OGSL6+/wPhSFwwsi1T+INaCrOfRnDW4EgmWDcAMTg4OPJ1LjzSMf85C8dpXfYliNXiBl6uPIBpcsTjrFsCMdjaNQRAJqPhVe67AGi1PLgkHh7WPgJPXwTRl2RotfBvANJNEkpfc4hF4/h9fIyBVAqrH04FQCCgit5c60H95AQm5wL97cMNvPuWAzWNGkr2/fMveLZ4DyzOBNPs+Gh3E0mCvLD0ZB9swkBs/K7owXl1U/jEYHg4g1rt6DpA1TCgaRq2tqviFW5y3xIIxQ7rh5iamhAA1KtyudyZgwvLEmNM80BJXd/2i0kzsZMvy1p/Euk3UjDd3w/qBVkpiUDlhd4afxLpN9KSZNJp1Op139IysUQCvNEA5eVZ1ryZm2tLyOfzXiQc9nfhf45l26KkUqm0AaanH3vW5ZpGrqywjDWbDhhLoLdmfX1N+Qtlmygg+Q/yZwAAAABJRU5ErkJggg=="},{"path":"C:\\Users\\simon\\Desktop\\Forge 15\\Create\\src\\main\\resources\\assets\\create\\textures\\block\\weighted_ejector_inner.png","name":"weighted_ejector_inner.png","folder":"block","namespace":"create","id":"5","particle":false,"visible":true,"mode":"bitmap","saved":true,"uuid":"c9f14264-859c-957f-e9fd-615804f80729","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABrklEQVQ4T6WTu07DQBBFr71+xOaRB8IiQERDBX9AQ8MPpEuVgg+jSJUuP0BDQ01DB0WkoERBkCDZazvx2mjWWltWeBSZZqXdnaM7d2Y0bBka5Xe73UxxbNsukK5lbeD5alXcDYdDrQDM5x/ywTAMedbsanIUl4lJkqDTOcYGYL0uPzFmQie8BjCmI8uANM0ghEB9fw8nRx7uBoNcQa/Xy6bTOcKQ469E+pumAs1GA81Wo1Rw2+9nr+OJBJimCVJycy7Ao1yRW7Nw/8LAmCXV7LhOFUAKFp9L+H4A0zLAOcfVaYivGKjbkOfzuyPVmQaD4zjVEkjB22wOPwhgGDrCMMLlYSiTVTxOHJmYG1z7BeAHEGmKNE2kAhVlCSaEWKPZaG56QAqiOEKSiH89YIyh3faqJhKAh6E0SXlACqh+CuWBEAkcx90EUBc0TUOWJRUPlJHkgevugvNAAlqtOkajUTkH1IXFcgldZ9IDZSIB2vW8jXKqgJ8BNEhqfP2A4/qMyzlQgIexK8ecxpjC8w5KBbRMtES0PLQsdO77T0X91M6ZdVG8x3EM+l/swjYb/Q0cAwEgduvwJwAAAABJRU5ErkJggg=="},{"path":"C:\\Users\\simon\\Desktop\\Forge 15\\Create\\src\\main\\resources\\assets\\create\\textures\\block\\axis_top.png","name":"axis_top.png","folder":"block","namespace":"create","id":"6","particle":false,"visible":true,"mode":"bitmap","saved":true,"uuid":"69c7b327-9f59-d51a-b23f-e8c50e20fd12","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAaklEQVQ4T+2SMQ4AERBFv16h5W5atcohVGrXJBOhmL3A2rBa089L/ssTODxx+I8LwNyBc46VUui9g4iQc371NZXovWdjDFprqLUixrgHCCGwlBJjDJRSkFLaA1hrWWv9f8JqYDekj5BWJT4NbygR50R18wAAAABJRU5ErkJggg=="},{"path":"C:\\Users\\simon\\Desktop\\Forge 15\\Create\\src\\main\\resources\\assets\\create\\textures\\block\\andesite_casing.png","name":"andesite_casing.png","folder":"block","namespace":"create","id":"7","particle":false,"visible":true,"mode":"bitmap","saved":true,"uuid":"e651b58d-5e59-ec92-94cd-965bd6802735","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACeUlEQVQ4T32Tz2vTYBjHvzFpmqRpfnSuXec2x+qcuE30puBF8DLBw7wIAw8yNwTxNMF/QvAkCAqCV0EFQS+7O5QNWd1g4rZWZmfbuSVb2zdp0kXedySdDnwuyZP34ZPn/T7fh5ucngzwnyCERKeyLIPmh58cBeQGTqFBXIiiwIpbrX00mwRJVYMfBBA4jn23bAtyQgfP7UPgeXxdyiMCzL1+wop0VcRGdQ/ZlAbP9xETePB8gI1qDV1mEnXHBcDh3NgdrK19OwAMnR3F51ePYWgyEpKAH1sOuk0ZruchHoshCAIUKxayKRWKxKNUqeHC9btYXft+ADBMA6WPbyAIxzCc68RKqY6sLqLhNGFqCThuE792PehxIAhaWP9p4+KNe20A1WDh3VOYmoxcj4nF9SrO9KaxbdciQLFqoz9toE4I62Do6m0QZ+9vDXRVYh3ML5WQ68vAaTpQJBFJRcDC8iZOdOlRB4NXbsLasdoazL58hIzRBtDiMDIphQFUU4dP6rBrLrsCm8LMw5mgwzyO/PtnkQa0AwqQ4zEQ10MIONzB5YkH+DL/qS3i5txbJJRYpEFaU44ABvs7Iw3oFKIOZCmJldkXSKeS0JMSNu0mU5zenwbVIF/YikSs/CYYvTZ11Ei9GYMBChWLFdP5h1egADqZ8tYutu0Gui+Nt0WkY6RO7Osy2R8L5R1mGsf1IcUFZp7Vko2TaQOu56NBPJwfv4+V5Ty4iVsTwcDAaSx+eA5VFsHzQLFkoSdjokaobam9YyhbHjpUEV6rBVHgMTI2dWAkChgZHmXLFIZmGuzVd9qbSPOwRpHj7DxaJpqEa0tXNYx/V/lwXVjzB52xTSnD2+HhAAAAAElFTkSuQmCC"}]} \ No newline at end of file diff --git a/src/main/resources/assets/create/textures/block/weighted_ejector_casing.png b/src/main/resources/assets/create/textures/block/weighted_ejector_casing.png new file mode 100644 index 0000000000000000000000000000000000000000..502ecf49607f50725c84c6059aaa2f5033aca42c GIT binary patch literal 1308 zcmV+%1>^dOP)MyVBasLKfj~K=P$;lx zyWI`~K;O}(w7J!4Wnjj}#%c#}eB@0mFaOB^(89BGv*_*aWt-9_WaMYnot{Q8r~%bM zm@3fOeGq3qde2mWBkv6nOer`|eMT3T58PXMR_SCe-FAR14NpN7xl z#4Wz-t^nNWS)?*~JbvQUN(HKqV5cUe9yqtC^${IGYfxepAdW{behI%EE?(y#G&Vx?`_a(QfOIN_R5FQyjv`dGgj8k=p@CtX<-`4A7b zifr-7S^|>ag}ki7!CN6XI4rHE5DNGpD=M}8%#yq=8`hEvnp}1$#Ukuhj&(6j zLNZBeWBJ4aE61^zf>K0Y1U`Dx#C0;_yUt_k z0jeOG)#1ciYz0lC#uR#|HP#ci;dHpmdHT$tAHa@)g7wK{lv3SC-|K#(&*(Ri-tgiR zeQa9lpVfQSB_um-x)=XF0QV}uSWwLXy<_jz@x~l_UbyuAo-eg*Fwr0~>Nz=yr@8zl z3(Bq_=tk|Z+dx;k@_oRl=QOQoq8X=_KH>CHYSi=U z`@mlF%UYo8d85;AqOp^=m1j7K(~Y&1Nze63SZh85VAOMui-&`^Bb!r^FXT;N1cx2B z5*d@8Q$RiW41iJ3y&eIwoQ0CD{7bS4Ht@XWPjBW;dQJf9$!7qJdfwWs{k^KT^p*xF zosms?PQH5b%K&QCb7K?MbRVD!)T8GFpq~6P3u@JK%KKmL1GVb;ZqmEkec&HstX#ZE S$>j$C0000}qlpmx)P|pwl_V24KA|KQU%PC%gtQrX$OMG|eD{Kz)A?Cr2Lc27_Eduh+|_(>cPB zeo2CNIMgz@Oqf~I)?`N;$i3FIY2~u)%F2JK)kz2EH|H8nSCDrV>P8C237N1M_ zegM-lz&Xd&X^5{FsN0a|^SdL}nFfR7IMotJ!P{&OKL}tLI>Io*r8v?t=3`0$Qy)Mx#+V2h@edatU2$(gS580owJvjdH4h zp8+&TYJB~GaSZxj d?7}u1{S6!g0U&nk@FxHO002ovPDHLkV1o2Y(qaGr literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/weighted_ejector_top.png b/src/main/resources/assets/create/textures/block/weighted_ejector_top.png new file mode 100644 index 0000000000000000000000000000000000000000..2f81eab874c231339c3c52223071013445a2fc19 GIT binary patch literal 613 zcmV-r0-F7aP)WxI>sRwVy#MqO87(*|FgfuY*h?ibHaOzPK zZhF&1&vM|fKnY7Ml*mut!miuyntA1IX^C+!GjC?z_r7m-Mgf3Aq2Q6FFB*wR7wn2J zgWR(G{L=EWqDX+fyJ0=5KA=EV z18`lybv-njP23zvVRCE~3#C$Nb2eFuZ-G=_$> z4ukn((fhfngY$++zP|qh;YeICvMp2igIWr+pGI)j;7BG|Hvlm>I5_fkE!EltXl#x*xEG&KqjN%Rqne0Xtg}JBpx2tJ_1i)1ksmdXtnTf z0MbnoN?&t`MdSE=e2jrq3acMZ1wbI6ir!r7LH*IGRT zi9qFr-Wq=r={M4nWYTHW>UH1JGO0+oGgW zsk8y6ryqOP<(fvWtgwtVn+_ODptojyeNFibWt%7<`494E00000NkvXXu0mjfUP2wO literal 0 HcmV?d00001 From 1d2b51250c4844cfc6d0116a9296597a8a8d9b4a Mon Sep 17 00:00:00 2001 From: JozsefA Date: Thu, 25 Mar 2021 21:27:08 -0700 Subject: [PATCH 7/9] Instanced Ejectors and better hashing for BehaviourTypes. --- .../com/simibubi/create/AllTileEntities.java | 7 +-- .../block/depot/EjectorInstance.java | 60 +++++++++++++++++++ .../block/depot/EjectorRenderer.java | 22 ++++--- .../tileEntity/behaviour/BehaviourType.java | 4 ++ 4 files changed, 81 insertions(+), 12 deletions(-) create mode 100644 src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorInstance.java diff --git a/src/main/java/com/simibubi/create/AllTileEntities.java b/src/main/java/com/simibubi/create/AllTileEntities.java index cbeb1f51b..9a6671797 100644 --- a/src/main/java/com/simibubi/create/AllTileEntities.java +++ b/src/main/java/com/simibubi/create/AllTileEntities.java @@ -122,10 +122,7 @@ import com.simibubi.create.content.logistics.block.chute.ChuteRenderer; import com.simibubi.create.content.logistics.block.chute.ChuteTileEntity; import com.simibubi.create.content.logistics.block.chute.SmartChuteRenderer; import com.simibubi.create.content.logistics.block.chute.SmartChuteTileEntity; -import com.simibubi.create.content.logistics.block.depot.DepotRenderer; -import com.simibubi.create.content.logistics.block.depot.DepotTileEntity; -import com.simibubi.create.content.logistics.block.depot.EjectorRenderer; -import com.simibubi.create.content.logistics.block.depot.EjectorTileEntity; +import com.simibubi.create.content.logistics.block.depot.*; import com.simibubi.create.content.logistics.block.diodes.AdjustablePulseRepeaterTileEntity; import com.simibubi.create.content.logistics.block.diodes.AdjustableRepeaterInstance; import com.simibubi.create.content.logistics.block.diodes.AdjustableRepeaterRenderer; @@ -617,7 +614,7 @@ public class AllTileEntities { public static final TileEntityEntry WEIGHTED_EJECTOR = Create.registrate() .tileEntity("weighted_ejector", EjectorTileEntity::new) - .instance(() -> ShaftInstance::new) + .instance(() -> EjectorInstance::new) .validBlocks(AllBlocks.WEIGHTED_EJECTOR) .renderer(() -> EjectorRenderer::new) .register(); diff --git a/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorInstance.java b/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorInstance.java new file mode 100644 index 000000000..bb269009c --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorInstance.java @@ -0,0 +1,60 @@ +package com.simibubi.create.content.logistics.block.depot; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.content.contraptions.base.KineticTileEntity; +import com.simibubi.create.content.contraptions.relays.encased.ShaftInstance; +import com.simibubi.create.foundation.render.backend.instancing.IDynamicInstance; +import com.simibubi.create.foundation.render.backend.instancing.InstanceKey; +import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; +import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData; +import com.simibubi.create.foundation.utility.AnimationTickHolder; +import com.simibubi.create.foundation.utility.MatrixStacker; + +public class EjectorInstance extends ShaftInstance implements IDynamicInstance { + + protected final EjectorTileEntity tile; + + protected final InstanceKey plate; + + public EjectorInstance(InstancedTileRenderer dispatcher, EjectorTileEntity tile) { + super(dispatcher, tile); + this.tile = tile; + + plate = getTransformMaterial().getModel(AllBlockPartials.EJECTOR_TOP, blockState).createInstance(); + + pivotPlate(); + updateLight(); + } + + @Override + public void beginFrame() { + + if (tile.lidProgress.settled()) return; + + pivotPlate(); + } + + private void pivotPlate() { + float lidProgress = tile.getLidProgress(AnimationTickHolder.getPartialTicks()); + float angle = lidProgress * 70; + + MatrixStack ms = new MatrixStack(); + + EjectorRenderer.applyLidAngle(tile, angle, MatrixStacker.of(ms).translate(getInstancePosition())); + + plate.getInstance().setTransform(ms); + } + + @Override + public void updateLight() { + super.updateLight(); + relight(pos, plate.getInstance()); + } + + @Override + public void remove() { + super.remove(); + plate.delete(); + } +} diff --git a/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorRenderer.java b/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorRenderer.java index 1d0438af6..29eaeb995 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorRenderer.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/depot/EjectorRenderer.java @@ -6,6 +6,7 @@ import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.foundation.render.SuperByteBuffer; +import com.simibubi.create.foundation.render.backend.FastRenderDispatcher; import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.IntAttached; import com.simibubi.create.foundation.utility.MatrixStacker; @@ -22,6 +23,8 @@ import net.minecraft.util.math.Vec3d; public class EjectorRenderer extends KineticTileEntityRenderer { + static final Vec3d pivot = VecHelper.voxelSpace(0, 11.25, 0.75); + public EjectorRenderer(TileEntityRendererDispatcher dispatcher) { super(dispatcher); } @@ -37,15 +40,16 @@ public class EjectorRenderer extends KineticTileEntityRenderer { super.renderSafe(te, partialTicks, ms, buffer, light, overlay); EjectorTileEntity ejector = (EjectorTileEntity) te; - SuperByteBuffer model = AllBlockPartials.EJECTOR_TOP.renderOn(te.getBlockState()); IVertexBuilder vertexBuilder = buffer.getBuffer(RenderType.getSolid()); - Vec3d rotationOffset = VecHelper.voxelSpace(0, 11.25, 0.75); float lidProgress = ((EjectorTileEntity) te).getLidProgress(partialTicks); float angle = lidProgress * 70; - applyLidAngle(te, rotationOffset, angle, model.matrixStacker()); - model.light(light) - .renderInto(ms, vertexBuilder); + if (!FastRenderDispatcher.available(te.getWorld())) { + SuperByteBuffer model = AllBlockPartials.EJECTOR_TOP.renderOn(te.getBlockState()); + applyLidAngle(te, angle, model.matrixStacker()); + model.light(light) + .renderInto(ms, vertexBuilder); + } MatrixStacker msr = MatrixStacker.of(ms); @@ -70,7 +74,7 @@ public class EjectorRenderer extends KineticTileEntityRenderer { return; ms.push(); - applyLidAngle(te, rotationOffset, angle, msr); + applyLidAngle(te, angle, msr); msr.centre() .rotateY(-180 - AngleHelper.horizontalAngle(te.getBlockState() .get(EjectorBlock.HORIZONTAL_FACING))) @@ -79,7 +83,11 @@ public class EjectorRenderer extends KineticTileEntityRenderer { ms.pop(); } - protected void applyLidAngle(KineticTileEntity te, Vec3d rotationOffset, float angle, MatrixStacker matrixStacker) { + static void applyLidAngle(KineticTileEntity te, float angle, MatrixStacker matrixStacker) { + applyLidAngle(te, pivot, angle, matrixStacker); + } + + static void applyLidAngle(KineticTileEntity te, Vec3d rotationOffset, float angle, MatrixStacker matrixStacker) { matrixStacker.centre() .rotateY(180 + AngleHelper.horizontalAngle(te.getBlockState() .get(EjectorBlock.HORIZONTAL_FACING))) diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/BehaviourType.java b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/BehaviourType.java index 8b3f90827..d9fc571a8 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/BehaviourType.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/BehaviourType.java @@ -18,4 +18,8 @@ public class BehaviourType { return name; } + @Override + public int hashCode() { + return super.hashCode() * 31 * 493286711; // Better hash table distribution + } } From 5fa8a0b80883cefd2da6b9f9243d653efa2aaa2e Mon Sep 17 00:00:00 2001 From: grimmauld Date: Fri, 26 Mar 2021 09:11:25 +0100 Subject: [PATCH 8/9] Revert "Fix leave finding in saws so compatibility with other mods works" This is necessary to make the distance gathering work. Sorry me dumb dumb --- .../java/com/simibubi/create/foundation/utility/TreeCutter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/simibubi/create/foundation/utility/TreeCutter.java b/src/main/java/com/simibubi/create/foundation/utility/TreeCutter.java index 1432d99ff..32923920b 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/TreeCutter.java +++ b/src/main/java/com/simibubi/create/foundation/utility/TreeCutter.java @@ -208,7 +208,7 @@ public class TreeCutter { } private static boolean isLeaf(BlockState state) { - return state.has(LeavesBlock.DISTANCE) || state.isIn(BlockTags.LEAVES); + return state.has(LeavesBlock.DISTANCE); } } From 9c8d03569403ba832b072b3a223718bb53014dca Mon Sep 17 00:00:00 2001 From: grimmauld Date: Fri, 26 Mar 2021 13:35:45 +0100 Subject: [PATCH 9/9] Dya see the dye? --- src/generated/resources/.cache/cache | 30 ++-- .../assets/create/blockstates/fluid_pipe.json | 154 +++++++++--------- .../create/blockstates/radial_chassis.json | 96 +++++------ .../resources/assets/create/lang/en_us.json | 4 + .../assets/create/lang/unfinished/de_de.json | 6 +- .../assets/create/lang/unfinished/es_es.json | 6 +- .../assets/create/lang/unfinished/es_mx.json | 6 +- .../assets/create/lang/unfinished/fr_fr.json | 6 +- .../assets/create/lang/unfinished/it_it.json | 6 +- .../assets/create/lang/unfinished/ja_jp.json | 6 +- .../assets/create/lang/unfinished/ko_kr.json | 6 +- .../assets/create/lang/unfinished/nl_nl.json | 6 +- .../assets/create/lang/unfinished/pt_br.json | 6 +- .../assets/create/lang/unfinished/ru_ru.json | 6 +- .../assets/create/lang/unfinished/zh_cn.json | 6 +- .../assets/create/lang/unfinished/zh_tw.json | 6 +- .../logistics/item/filter/ItemAttribute.java | 37 ++--- .../item/filter/attribute/ColorAttribute.java | 86 ++++++++++ .../assets/create/lang/default/messages.json | 4 + 19 files changed, 312 insertions(+), 171 deletions(-) create mode 100644 src/main/java/com/simibubi/create/content/logistics/item/filter/attribute/ColorAttribute.java diff --git a/src/generated/resources/.cache/cache b/src/generated/resources/.cache/cache index c067095a9..a14f23093 100644 --- a/src/generated/resources/.cache/cache +++ b/src/generated/resources/.cache/cache @@ -140,7 +140,7 @@ de8a40b7daf1497d5aecee47a43b3e0b1d030b00 assets/create/blockstates/fancy_scoria_ fc9ac0a7e7191b93516719455a17177fa6524ecc assets/create/blockstates/fancy_weathered_limestone_bricks_slab.json b2a7c321b1795f20e7433f81a55ce4683de081b8 assets/create/blockstates/fancy_weathered_limestone_bricks_stairs.json 6372fe02ba0065acb0758121c45a15a1a8fdc5de assets/create/blockstates/fancy_weathered_limestone_bricks_wall.json -48086bf71a824faf14841b698050cc8544b09a9b assets/create/blockstates/fluid_pipe.json +3d97226b5e8d8f70ed08e45e78db1faf78d5e28b assets/create/blockstates/fluid_pipe.json f0eaab18e16c4f3f65ebf3b55b08f0dc445720fe assets/create/blockstates/fluid_tank.json 5408d92ab02af86539ac42971d4033545970bb3a assets/create/blockstates/fluid_valve.json e9da1794b6ece7f9aa8bcb43d42c23a55446133b assets/create/blockstates/flywheel.json @@ -337,7 +337,7 @@ e8b0a401c10d1ba67ed71ba31bd5f9bc28571b65 assets/create/blockstates/powered_toggl d06cd9a1101b18d306a786320aab12018b1325d6 assets/create/blockstates/purple_sail.json 92957119abd5fbcca36a113b2a80255fd70fc303 assets/create/blockstates/purple_seat.json 61035f8afe75ff7bbd291da5d8690bcbebe679eb assets/create/blockstates/purple_valve_handle.json -4439fc83a8c7370ab44b211a3fd48abde20a4728 assets/create/blockstates/radial_chassis.json +8d7e653bfd9846e684a0d3725595714a19201017 assets/create/blockstates/radial_chassis.json 45877c4d90a7185c2f304edbd67379d800920439 assets/create/blockstates/red_sail.json da1b08387af7afa0855ee8d040f620c01f20660a assets/create/blockstates/red_seat.json 722fc77bbf387af8a4016e42cbf9501d2b968881 assets/create/blockstates/red_valve_handle.json @@ -403,19 +403,19 @@ a3a11524cd3515fc01d905767b4b7ea782adaf03 assets/create/blockstates/yellow_seat.j 7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json ce0e5405da381a86625b908c569c5dbe347abdba assets/create/lang/en_ud.json -5383435fbb7d8be0c6cdc8a4ebfae072645e461f assets/create/lang/en_us.json -f67a8ceef1ec2091b53198e5509e80ac9e5b82c1 assets/create/lang/unfinished/de_de.json -174bd2c5b0fe4560030c4b5f92dd795ce7785245 assets/create/lang/unfinished/es_es.json -20783faf769c31e3d8200ebdc78256e6845e4fc6 assets/create/lang/unfinished/es_mx.json -c33171dd6390d80e39beef5c1511e72e7515c390 assets/create/lang/unfinished/fr_fr.json -38bff62b21ff5c241cab0e06cc161cd12162749e assets/create/lang/unfinished/it_it.json -c5a21a9238d491434fac9552c2372b0e2c5a8612 assets/create/lang/unfinished/ja_jp.json -fab3e5b787268d39fa3b1c31d923e9d4f4b66419 assets/create/lang/unfinished/ko_kr.json -62f4a359bf78057eaf9a3ef73766ee5e25833ce6 assets/create/lang/unfinished/nl_nl.json -4fd663de3f40c2e2c569de95cfce4167e8a42cb1 assets/create/lang/unfinished/pt_br.json -d431bca588528894340f8619cfcd82013eb04635 assets/create/lang/unfinished/ru_ru.json -752dee8e473eb96deaa7a6b1f8405a1313c99cec assets/create/lang/unfinished/zh_cn.json -efe100b3543f98a16f4230b7278a66f9bd00166c assets/create/lang/unfinished/zh_tw.json +e572959e40b9917e88e6b86b5b9ebbf091d5f1ba assets/create/lang/en_us.json +6d55a1325fc8bf894b92285f217b794e32575739 assets/create/lang/unfinished/de_de.json +77c60af805305234d28421be451a6091c9222d44 assets/create/lang/unfinished/es_es.json +d623da600d9f84f7ace4689b44e982746364cd36 assets/create/lang/unfinished/es_mx.json +41b68809a2c0267be7e6966274e00a69f370b743 assets/create/lang/unfinished/fr_fr.json +4606b3e7bcbb0b54802e52a800838343e84087ee assets/create/lang/unfinished/it_it.json +38e23ba73a515cb238d3899cc7517ff30223a3bc assets/create/lang/unfinished/ja_jp.json +0e34e4848b8e0ea0b73778477cc4790d6a637143 assets/create/lang/unfinished/ko_kr.json +3d790d06451adfab91ed133e80239df6e6221567 assets/create/lang/unfinished/nl_nl.json +d2e1804d40933c6b6e3badcc1ae197f80fb839af assets/create/lang/unfinished/pt_br.json +ae45aacb4418411dec1e6248637094efec94bd24 assets/create/lang/unfinished/ru_ru.json +ba653601c0452116fd5f8b820a136b4833dcb426 assets/create/lang/unfinished/zh_cn.json +1087875125ce70b1543df07e3957b14b5ef60e9f assets/create/lang/unfinished/zh_tw.json 846200eb548d3bfa2e77b41039de159b4b6cfb45 assets/create/models/block/acacia_window.json 1930fa3a3c98d53dd19e4ee7f55bc27fd47aa281 assets/create/models/block/acacia_window_pane_noside.json 1763ea2c9b981d187f5031ba608f3d5d3be3986a assets/create/models/block/acacia_window_pane_noside_alt.json diff --git a/src/generated/resources/assets/create/blockstates/fluid_pipe.json b/src/generated/resources/assets/create/blockstates/fluid_pipe.json index 80a25280c..a4cffcde7 100644 --- a/src/generated/resources/assets/create/blockstates/fluid_pipe.json +++ b/src/generated/resources/assets/create/blockstates/fluid_pipe.json @@ -61,9 +61,9 @@ { "when": { "down": "false", + "north": "true", "up": "true", - "south": "false", - "north": "true" + "south": "false" }, "apply": { "model": "create:block/fluid_pipe/lu_x" @@ -72,9 +72,9 @@ { "when": { "down": "false", + "north": "false", "up": "true", - "south": "true", - "north": "false" + "south": "true" }, "apply": { "model": "create:block/fluid_pipe/ru_x" @@ -83,9 +83,9 @@ { "when": { "down": "true", + "north": "true", "up": "false", - "south": "false", - "north": "true" + "south": "false" }, "apply": { "model": "create:block/fluid_pipe/ld_x" @@ -94,9 +94,9 @@ { "when": { "down": "true", + "north": "false", "up": "false", - "south": "true", - "north": "false" + "south": "true" }, "apply": { "model": "create:block/fluid_pipe/rd_x" @@ -105,9 +105,9 @@ { "when": { "down": "true", + "north": "false", "up": "true", - "south": "false", - "north": "false" + "south": "false" }, "apply": { "model": "create:block/fluid_pipe/ud_x" @@ -116,9 +116,9 @@ { "when": { "down": "false", + "north": "false", "up": "true", - "south": "false", - "north": "false" + "south": "false" }, "apply": { "model": "create:block/fluid_pipe/ud_x" @@ -127,9 +127,9 @@ { "when": { "down": "true", + "north": "false", "up": "false", - "south": "false", - "north": "false" + "south": "false" }, "apply": { "model": "create:block/fluid_pipe/ud_x" @@ -138,9 +138,9 @@ { "when": { "down": "false", + "north": "true", "up": "false", - "south": "true", - "north": "true" + "south": "true" }, "apply": { "model": "create:block/fluid_pipe/lr_x" @@ -149,9 +149,9 @@ { "when": { "down": "false", + "north": "true", "up": "false", - "south": "false", - "north": "true" + "south": "false" }, "apply": { "model": "create:block/fluid_pipe/lr_x" @@ -160,9 +160,9 @@ { "when": { "down": "false", + "north": "false", "up": "false", - "south": "true", - "north": "false" + "south": "true" }, "apply": { "model": "create:block/fluid_pipe/lr_x" @@ -171,9 +171,9 @@ { "when": { "down": "false", + "north": "false", "up": "false", - "south": "false", - "north": "false" + "south": "false" }, "apply": { "model": "create:block/fluid_pipe/none_x" @@ -181,10 +181,10 @@ }, { "when": { - "south": "true", "west": "true", + "east": "false", "north": "false", - "east": "false" + "south": "true" }, "apply": { "model": "create:block/fluid_pipe/lu_y" @@ -192,10 +192,10 @@ }, { "when": { - "south": "true", "west": "false", + "east": "true", "north": "false", - "east": "true" + "south": "true" }, "apply": { "model": "create:block/fluid_pipe/ru_y" @@ -203,10 +203,10 @@ }, { "when": { - "south": "false", "west": "true", + "east": "false", "north": "true", - "east": "false" + "south": "false" }, "apply": { "model": "create:block/fluid_pipe/ld_y" @@ -214,10 +214,10 @@ }, { "when": { - "south": "false", "west": "false", + "east": "true", "north": "true", - "east": "true" + "south": "false" }, "apply": { "model": "create:block/fluid_pipe/rd_y" @@ -225,10 +225,10 @@ }, { "when": { - "south": "true", "west": "false", + "east": "false", "north": "true", - "east": "false" + "south": "true" }, "apply": { "model": "create:block/fluid_pipe/ud_y" @@ -236,10 +236,10 @@ }, { "when": { - "south": "true", "west": "false", + "east": "false", "north": "false", - "east": "false" + "south": "true" }, "apply": { "model": "create:block/fluid_pipe/ud_y" @@ -247,10 +247,10 @@ }, { "when": { - "south": "false", "west": "false", + "east": "false", "north": "true", - "east": "false" + "south": "false" }, "apply": { "model": "create:block/fluid_pipe/ud_y" @@ -258,10 +258,10 @@ }, { "when": { - "south": "false", "west": "true", + "east": "true", "north": "false", - "east": "true" + "south": "false" }, "apply": { "model": "create:block/fluid_pipe/lr_y" @@ -269,10 +269,10 @@ }, { "when": { - "south": "false", "west": "true", + "east": "false", "north": "false", - "east": "false" + "south": "false" }, "apply": { "model": "create:block/fluid_pipe/lr_y" @@ -280,10 +280,10 @@ }, { "when": { - "south": "false", "west": "false", + "east": "true", "north": "false", - "east": "true" + "south": "false" }, "apply": { "model": "create:block/fluid_pipe/lr_y" @@ -291,10 +291,10 @@ }, { "when": { - "south": "false", "west": "false", + "east": "false", "north": "false", - "east": "false" + "south": "false" }, "apply": { "model": "create:block/fluid_pipe/none_y" @@ -302,10 +302,10 @@ }, { "when": { - "down": "false", - "up": "true", "west": "false", - "east": "true" + "down": "false", + "east": "true", + "up": "true" }, "apply": { "model": "create:block/fluid_pipe/lu_z" @@ -313,10 +313,10 @@ }, { "when": { - "down": "false", - "up": "true", "west": "true", - "east": "false" + "down": "false", + "east": "false", + "up": "true" }, "apply": { "model": "create:block/fluid_pipe/ru_z" @@ -324,10 +324,10 @@ }, { "when": { - "down": "true", - "up": "false", "west": "false", - "east": "true" + "down": "true", + "east": "true", + "up": "false" }, "apply": { "model": "create:block/fluid_pipe/ld_z" @@ -335,10 +335,10 @@ }, { "when": { - "down": "true", - "up": "false", "west": "true", - "east": "false" + "down": "true", + "east": "false", + "up": "false" }, "apply": { "model": "create:block/fluid_pipe/rd_z" @@ -346,10 +346,10 @@ }, { "when": { + "west": "false", "down": "true", - "up": "true", - "west": "false", - "east": "false" + "east": "false", + "up": "true" }, "apply": { "model": "create:block/fluid_pipe/ud_z" @@ -357,10 +357,10 @@ }, { "when": { + "west": "false", "down": "false", - "up": "true", - "west": "false", - "east": "false" + "east": "false", + "up": "true" }, "apply": { "model": "create:block/fluid_pipe/ud_z" @@ -368,10 +368,10 @@ }, { "when": { + "west": "false", "down": "true", - "up": "false", - "west": "false", - "east": "false" + "east": "false", + "up": "false" }, "apply": { "model": "create:block/fluid_pipe/ud_z" @@ -379,10 +379,10 @@ }, { "when": { - "down": "false", - "up": "false", "west": "true", - "east": "true" + "down": "false", + "east": "true", + "up": "false" }, "apply": { "model": "create:block/fluid_pipe/lr_z" @@ -390,10 +390,10 @@ }, { "when": { - "down": "false", - "up": "false", "west": "false", - "east": "true" + "down": "false", + "east": "true", + "up": "false" }, "apply": { "model": "create:block/fluid_pipe/lr_z" @@ -401,10 +401,10 @@ }, { "when": { - "down": "false", - "up": "false", "west": "true", - "east": "false" + "down": "false", + "east": "false", + "up": "false" }, "apply": { "model": "create:block/fluid_pipe/lr_z" @@ -412,10 +412,10 @@ }, { "when": { - "down": "false", - "up": "false", "west": "false", - "east": "false" + "down": "false", + "east": "false", + "up": "false" }, "apply": { "model": "create:block/fluid_pipe/none_z" diff --git a/src/generated/resources/assets/create/blockstates/radial_chassis.json b/src/generated/resources/assets/create/blockstates/radial_chassis.json index 8bd829ffc..9d00ea8b1 100644 --- a/src/generated/resources/assets/create/blockstates/radial_chassis.json +++ b/src/generated/resources/assets/create/blockstates/radial_chassis.json @@ -29,8 +29,8 @@ }, { "when": { - "axis": "x", - "sticky_south": "true" + "sticky_south": "true", + "axis": "x" }, "apply": { "model": "create:block/radial_chassis_side_x_sticky", @@ -39,8 +39,8 @@ }, { "when": { - "axis": "y", - "sticky_south": "true" + "sticky_south": "true", + "axis": "y" }, "apply": { "model": "create:block/radial_chassis_side_y_sticky" @@ -48,8 +48,8 @@ }, { "when": { - "axis": "z", - "sticky_south": "true" + "sticky_south": "true", + "axis": "z" }, "apply": { "model": "create:block/radial_chassis_side_x_sticky", @@ -59,8 +59,8 @@ }, { "when": { - "axis": "x", - "sticky_south": "false" + "sticky_south": "false", + "axis": "x" }, "apply": { "model": "create:block/radial_chassis_side_x", @@ -69,8 +69,8 @@ }, { "when": { - "axis": "y", - "sticky_south": "false" + "sticky_south": "false", + "axis": "y" }, "apply": { "model": "create:block/radial_chassis_side_y" @@ -78,8 +78,8 @@ }, { "when": { - "axis": "z", - "sticky_south": "false" + "sticky_south": "false", + "axis": "z" }, "apply": { "model": "create:block/radial_chassis_side_x", @@ -89,8 +89,8 @@ }, { "when": { - "axis": "x", - "sticky_west": "true" + "sticky_west": "true", + "axis": "x" }, "apply": { "model": "create:block/radial_chassis_side_x_sticky", @@ -99,8 +99,8 @@ }, { "when": { - "axis": "y", - "sticky_west": "true" + "sticky_west": "true", + "axis": "y" }, "apply": { "model": "create:block/radial_chassis_side_y_sticky", @@ -109,8 +109,8 @@ }, { "when": { - "axis": "z", - "sticky_west": "true" + "sticky_west": "true", + "axis": "z" }, "apply": { "model": "create:block/radial_chassis_side_z_sticky", @@ -119,8 +119,8 @@ }, { "when": { - "axis": "x", - "sticky_west": "false" + "sticky_west": "false", + "axis": "x" }, "apply": { "model": "create:block/radial_chassis_side_x", @@ -129,8 +129,8 @@ }, { "when": { - "axis": "y", - "sticky_west": "false" + "sticky_west": "false", + "axis": "y" }, "apply": { "model": "create:block/radial_chassis_side_y", @@ -139,8 +139,8 @@ }, { "when": { - "axis": "z", - "sticky_west": "false" + "sticky_west": "false", + "axis": "z" }, "apply": { "model": "create:block/radial_chassis_side_z", @@ -149,8 +149,8 @@ }, { "when": { - "axis": "x", - "sticky_north": "true" + "sticky_north": "true", + "axis": "x" }, "apply": { "model": "create:block/radial_chassis_side_x_sticky" @@ -158,8 +158,8 @@ }, { "when": { - "axis": "y", - "sticky_north": "true" + "sticky_north": "true", + "axis": "y" }, "apply": { "model": "create:block/radial_chassis_side_y_sticky", @@ -168,8 +168,8 @@ }, { "when": { - "axis": "z", - "sticky_north": "true" + "sticky_north": "true", + "axis": "z" }, "apply": { "model": "create:block/radial_chassis_side_x_sticky", @@ -178,8 +178,8 @@ }, { "when": { - "axis": "x", - "sticky_north": "false" + "sticky_north": "false", + "axis": "x" }, "apply": { "model": "create:block/radial_chassis_side_x" @@ -187,8 +187,8 @@ }, { "when": { - "axis": "y", - "sticky_north": "false" + "sticky_north": "false", + "axis": "y" }, "apply": { "model": "create:block/radial_chassis_side_y", @@ -197,8 +197,8 @@ }, { "when": { - "axis": "z", - "sticky_north": "false" + "sticky_north": "false", + "axis": "z" }, "apply": { "model": "create:block/radial_chassis_side_x", @@ -207,8 +207,8 @@ }, { "when": { - "axis": "x", - "sticky_east": "true" + "sticky_east": "true", + "axis": "x" }, "apply": { "model": "create:block/radial_chassis_side_x_sticky", @@ -217,8 +217,8 @@ }, { "when": { - "axis": "y", - "sticky_east": "true" + "sticky_east": "true", + "axis": "y" }, "apply": { "model": "create:block/radial_chassis_side_y_sticky", @@ -227,8 +227,8 @@ }, { "when": { - "axis": "z", - "sticky_east": "true" + "sticky_east": "true", + "axis": "z" }, "apply": { "model": "create:block/radial_chassis_side_z_sticky" @@ -236,8 +236,8 @@ }, { "when": { - "axis": "x", - "sticky_east": "false" + "sticky_east": "false", + "axis": "x" }, "apply": { "model": "create:block/radial_chassis_side_x", @@ -246,8 +246,8 @@ }, { "when": { - "axis": "y", - "sticky_east": "false" + "sticky_east": "false", + "axis": "y" }, "apply": { "model": "create:block/radial_chassis_side_y", @@ -256,8 +256,8 @@ }, { "when": { - "axis": "z", - "sticky_east": "false" + "sticky_east": "false", + "axis": "z" }, "apply": { "model": "create:block/radial_chassis_side_z" diff --git a/src/generated/resources/assets/create/lang/en_us.json b/src/generated/resources/assets/create/lang/en_us.json index 57cfdb221..690dd2fbe 100644 --- a/src/generated/resources/assets/create/lang/en_us.json +++ b/src/generated/resources/assets/create/lang/en_us.json @@ -1023,6 +1023,10 @@ "create.item_attributes.added_by.inverted": "was not added by %1$s", "create.item_attributes.has_enchant": "is enchanted with %1$s", "create.item_attributes.has_enchant.inverted": "is not enchanted with %1$s", + "create.item_attributes.color": "is dyed %1$s", + "create.item_attributes.color.inverted": "is not dyed %1$s", + "create.item_attributes.max_enchanted": "is enchanted at max level", + "create.item_attributes.max_enchanted.inverted": "is not enchanted at max level", "create.item_attributes.has_fluid": "contains %1$s", "create.item_attributes.has_fluid.inverted": "does not contain %1$s", "create.item_attributes.has_name": "has the custom name %1$s", diff --git a/src/generated/resources/assets/create/lang/unfinished/de_de.json b/src/generated/resources/assets/create/lang/unfinished/de_de.json index aec1cbcc7..8e489b370 100644 --- a/src/generated/resources/assets/create/lang/unfinished/de_de.json +++ b/src/generated/resources/assets/create/lang/unfinished/de_de.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1506", + "_": "Missing Localizations: 1510", "_": "->------------------------] Game Elements [------------------------<-", @@ -1024,6 +1024,10 @@ "create.item_attributes.added_by.inverted": "UNLOCALIZED: was not added by %1$s", "create.item_attributes.has_enchant": "UNLOCALIZED: is enchanted with %1$s", "create.item_attributes.has_enchant.inverted": "UNLOCALIZED: is not enchanted with %1$s", + "create.item_attributes.color": "UNLOCALIZED: is dyed %1$s", + "create.item_attributes.color.inverted": "UNLOCALIZED: is not dyed %1$s", + "create.item_attributes.max_enchanted": "UNLOCALIZED: is enchanted at max level", + "create.item_attributes.max_enchanted.inverted": "UNLOCALIZED: is not enchanted at max level", "create.item_attributes.has_fluid": "UNLOCALIZED: contains %1$s", "create.item_attributes.has_fluid.inverted": "UNLOCALIZED: does not contain %1$s", "create.item_attributes.has_name": "UNLOCALIZED: has the custom name %1$s", diff --git a/src/generated/resources/assets/create/lang/unfinished/es_es.json b/src/generated/resources/assets/create/lang/unfinished/es_es.json index 683a53505..22baf842f 100644 --- a/src/generated/resources/assets/create/lang/unfinished/es_es.json +++ b/src/generated/resources/assets/create/lang/unfinished/es_es.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 537", + "_": "Missing Localizations: 541", "_": "->------------------------] Game Elements [------------------------<-", @@ -1024,6 +1024,10 @@ "create.item_attributes.added_by.inverted": "no fue añadida por %1$s", "create.item_attributes.has_enchant": "está encantado con %1$s", "create.item_attributes.has_enchant.inverted": "no está encantado con %1$s", + "create.item_attributes.color": "UNLOCALIZED: is dyed %1$s", + "create.item_attributes.color.inverted": "UNLOCALIZED: is not dyed %1$s", + "create.item_attributes.max_enchanted": "UNLOCALIZED: is enchanted at max level", + "create.item_attributes.max_enchanted.inverted": "UNLOCALIZED: is not enchanted at max level", "create.item_attributes.has_fluid": "contiene %1$s", "create.item_attributes.has_fluid.inverted": "no contiene %1$s", "create.item_attributes.has_name": "tiene el nombre personalizado %1$s", diff --git a/src/generated/resources/assets/create/lang/unfinished/es_mx.json b/src/generated/resources/assets/create/lang/unfinished/es_mx.json index 970066780..854c8e156 100644 --- a/src/generated/resources/assets/create/lang/unfinished/es_mx.json +++ b/src/generated/resources/assets/create/lang/unfinished/es_mx.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1436", + "_": "Missing Localizations: 1440", "_": "->------------------------] Game Elements [------------------------<-", @@ -1024,6 +1024,10 @@ "create.item_attributes.added_by.inverted": "UNLOCALIZED: was not added by %1$s", "create.item_attributes.has_enchant": "UNLOCALIZED: is enchanted with %1$s", "create.item_attributes.has_enchant.inverted": "UNLOCALIZED: is not enchanted with %1$s", + "create.item_attributes.color": "UNLOCALIZED: is dyed %1$s", + "create.item_attributes.color.inverted": "UNLOCALIZED: is not dyed %1$s", + "create.item_attributes.max_enchanted": "UNLOCALIZED: is enchanted at max level", + "create.item_attributes.max_enchanted.inverted": "UNLOCALIZED: is not enchanted at max level", "create.item_attributes.has_fluid": "UNLOCALIZED: contains %1$s", "create.item_attributes.has_fluid.inverted": "UNLOCALIZED: does not contain %1$s", "create.item_attributes.has_name": "UNLOCALIZED: has the custom name %1$s", diff --git a/src/generated/resources/assets/create/lang/unfinished/fr_fr.json b/src/generated/resources/assets/create/lang/unfinished/fr_fr.json index 0add5245a..a41a33360 100644 --- a/src/generated/resources/assets/create/lang/unfinished/fr_fr.json +++ b/src/generated/resources/assets/create/lang/unfinished/fr_fr.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1218", + "_": "Missing Localizations: 1222", "_": "->------------------------] Game Elements [------------------------<-", @@ -1024,6 +1024,10 @@ "create.item_attributes.added_by.inverted": "n'a pas été ajouté par %1$s", "create.item_attributes.has_enchant": "est enchanté %1$s", "create.item_attributes.has_enchant.inverted": "n'est pas enchenté %1$s", + "create.item_attributes.color": "UNLOCALIZED: is dyed %1$s", + "create.item_attributes.color.inverted": "UNLOCALIZED: is not dyed %1$s", + "create.item_attributes.max_enchanted": "UNLOCALIZED: is enchanted at max level", + "create.item_attributes.max_enchanted.inverted": "UNLOCALIZED: is not enchanted at max level", "create.item_attributes.has_fluid": "contient %1$s", "create.item_attributes.has_fluid.inverted": "ne contient pas %1$s", "create.item_attributes.has_name": "est renommé %1$s", diff --git a/src/generated/resources/assets/create/lang/unfinished/it_it.json b/src/generated/resources/assets/create/lang/unfinished/it_it.json index 321d024fc..87fc548f2 100644 --- a/src/generated/resources/assets/create/lang/unfinished/it_it.json +++ b/src/generated/resources/assets/create/lang/unfinished/it_it.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 554", + "_": "Missing Localizations: 558", "_": "->------------------------] Game Elements [------------------------<-", @@ -1024,6 +1024,10 @@ "create.item_attributes.added_by.inverted": "non è stato aggiunto da %1$s", "create.item_attributes.has_enchant": "è stato incantato con %1$s", "create.item_attributes.has_enchant.inverted": "non è stato incantato con %1$s", + "create.item_attributes.color": "UNLOCALIZED: is dyed %1$s", + "create.item_attributes.color.inverted": "UNLOCALIZED: is not dyed %1$s", + "create.item_attributes.max_enchanted": "UNLOCALIZED: is enchanted at max level", + "create.item_attributes.max_enchanted.inverted": "UNLOCALIZED: is not enchanted at max level", "create.item_attributes.has_fluid": "contiene %1$s", "create.item_attributes.has_fluid.inverted": "non contiene %1$s", "create.item_attributes.has_name": "è stato rinominato in %1$s", diff --git a/src/generated/resources/assets/create/lang/unfinished/ja_jp.json b/src/generated/resources/assets/create/lang/unfinished/ja_jp.json index 5b64d94c6..245f96ca6 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ja_jp.json +++ b/src/generated/resources/assets/create/lang/unfinished/ja_jp.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 561", + "_": "Missing Localizations: 565", "_": "->------------------------] Game Elements [------------------------<-", @@ -1024,6 +1024,10 @@ "create.item_attributes.added_by.inverted": "%1$sによって追加されていないか", "create.item_attributes.has_enchant": "エンチャントされているか%1$s", "create.item_attributes.has_enchant.inverted": "エンチャントがされていないか", + "create.item_attributes.color": "UNLOCALIZED: is dyed %1$s", + "create.item_attributes.color.inverted": "UNLOCALIZED: is not dyed %1$s", + "create.item_attributes.max_enchanted": "UNLOCALIZED: is enchanted at max level", + "create.item_attributes.max_enchanted.inverted": "UNLOCALIZED: is not enchanted at max level", "create.item_attributes.has_fluid": "%1$sを含んでいるか", "create.item_attributes.has_fluid.inverted": "%1$sを含んでいないか", "create.item_attributes.has_name": "%1$sの名前が付けられているか", diff --git a/src/generated/resources/assets/create/lang/unfinished/ko_kr.json b/src/generated/resources/assets/create/lang/unfinished/ko_kr.json index b0845cb27..499ddcbc1 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ko_kr.json +++ b/src/generated/resources/assets/create/lang/unfinished/ko_kr.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 607", + "_": "Missing Localizations: 611", "_": "->------------------------] Game Elements [------------------------<-", @@ -1024,6 +1024,10 @@ "create.item_attributes.added_by.inverted": "%1$s모드가 추가하지 않음", "create.item_attributes.has_enchant": "UNLOCALIZED: is enchanted with %1$s", "create.item_attributes.has_enchant.inverted": "UNLOCALIZED: is not enchanted with %1$s", + "create.item_attributes.color": "UNLOCALIZED: is dyed %1$s", + "create.item_attributes.color.inverted": "UNLOCALIZED: is not dyed %1$s", + "create.item_attributes.max_enchanted": "UNLOCALIZED: is enchanted at max level", + "create.item_attributes.max_enchanted.inverted": "UNLOCALIZED: is not enchanted at max level", "create.item_attributes.has_fluid": "UNLOCALIZED: contains %1$s", "create.item_attributes.has_fluid.inverted": "UNLOCALIZED: does not contain %1$s", "create.item_attributes.has_name": "UNLOCALIZED: has the custom name %1$s", diff --git a/src/generated/resources/assets/create/lang/unfinished/nl_nl.json b/src/generated/resources/assets/create/lang/unfinished/nl_nl.json index c10eef86d..8c7090e72 100644 --- a/src/generated/resources/assets/create/lang/unfinished/nl_nl.json +++ b/src/generated/resources/assets/create/lang/unfinished/nl_nl.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1705", + "_": "Missing Localizations: 1709", "_": "->------------------------] Game Elements [------------------------<-", @@ -1024,6 +1024,10 @@ "create.item_attributes.added_by.inverted": "UNLOCALIZED: was not added by %1$s", "create.item_attributes.has_enchant": "UNLOCALIZED: is enchanted with %1$s", "create.item_attributes.has_enchant.inverted": "UNLOCALIZED: is not enchanted with %1$s", + "create.item_attributes.color": "UNLOCALIZED: is dyed %1$s", + "create.item_attributes.color.inverted": "UNLOCALIZED: is not dyed %1$s", + "create.item_attributes.max_enchanted": "UNLOCALIZED: is enchanted at max level", + "create.item_attributes.max_enchanted.inverted": "UNLOCALIZED: is not enchanted at max level", "create.item_attributes.has_fluid": "UNLOCALIZED: contains %1$s", "create.item_attributes.has_fluid.inverted": "UNLOCALIZED: does not contain %1$s", "create.item_attributes.has_name": "UNLOCALIZED: has the custom name %1$s", diff --git a/src/generated/resources/assets/create/lang/unfinished/pt_br.json b/src/generated/resources/assets/create/lang/unfinished/pt_br.json index e45ff7651..69c3540e9 100644 --- a/src/generated/resources/assets/create/lang/unfinished/pt_br.json +++ b/src/generated/resources/assets/create/lang/unfinished/pt_br.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1771", + "_": "Missing Localizations: 1775", "_": "->------------------------] Game Elements [------------------------<-", @@ -1024,6 +1024,10 @@ "create.item_attributes.added_by.inverted": "UNLOCALIZED: was not added by %1$s", "create.item_attributes.has_enchant": "UNLOCALIZED: is enchanted with %1$s", "create.item_attributes.has_enchant.inverted": "UNLOCALIZED: is not enchanted with %1$s", + "create.item_attributes.color": "UNLOCALIZED: is dyed %1$s", + "create.item_attributes.color.inverted": "UNLOCALIZED: is not dyed %1$s", + "create.item_attributes.max_enchanted": "UNLOCALIZED: is enchanted at max level", + "create.item_attributes.max_enchanted.inverted": "UNLOCALIZED: is not enchanted at max level", "create.item_attributes.has_fluid": "UNLOCALIZED: contains %1$s", "create.item_attributes.has_fluid.inverted": "UNLOCALIZED: does not contain %1$s", "create.item_attributes.has_name": "UNLOCALIZED: has the custom name %1$s", diff --git a/src/generated/resources/assets/create/lang/unfinished/ru_ru.json b/src/generated/resources/assets/create/lang/unfinished/ru_ru.json index 4869223bd..cd3635698 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ru_ru.json +++ b/src/generated/resources/assets/create/lang/unfinished/ru_ru.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 557", + "_": "Missing Localizations: 561", "_": "->------------------------] Game Elements [------------------------<-", @@ -1024,6 +1024,10 @@ "create.item_attributes.added_by.inverted": "не был добавлен %1$s", "create.item_attributes.has_enchant": "зачарован на %1$s", "create.item_attributes.has_enchant.inverted": "не зачарован на %1$s", + "create.item_attributes.color": "UNLOCALIZED: is dyed %1$s", + "create.item_attributes.color.inverted": "UNLOCALIZED: is not dyed %1$s", + "create.item_attributes.max_enchanted": "UNLOCALIZED: is enchanted at max level", + "create.item_attributes.max_enchanted.inverted": "UNLOCALIZED: is not enchanted at max level", "create.item_attributes.has_fluid": "содержит %1$s", "create.item_attributes.has_fluid.inverted": "не содержит %1$s", "create.item_attributes.has_name": "имеет нестандартное имя %1$s", diff --git a/src/generated/resources/assets/create/lang/unfinished/zh_cn.json b/src/generated/resources/assets/create/lang/unfinished/zh_cn.json index e1f1eeb33..add7d93b3 100644 --- a/src/generated/resources/assets/create/lang/unfinished/zh_cn.json +++ b/src/generated/resources/assets/create/lang/unfinished/zh_cn.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 555", + "_": "Missing Localizations: 559", "_": "->------------------------] Game Elements [------------------------<-", @@ -1024,6 +1024,10 @@ "create.item_attributes.added_by.inverted": "不是由%1$s添加", "create.item_attributes.has_enchant": "有附魔效果%1$s", "create.item_attributes.has_enchant.inverted": "没有附魔效果%1$s", + "create.item_attributes.color": "UNLOCALIZED: is dyed %1$s", + "create.item_attributes.color.inverted": "UNLOCALIZED: is not dyed %1$s", + "create.item_attributes.max_enchanted": "UNLOCALIZED: is enchanted at max level", + "create.item_attributes.max_enchanted.inverted": "UNLOCALIZED: is not enchanted at max level", "create.item_attributes.has_fluid": "包含%1$s", "create.item_attributes.has_fluid.inverted": "不包含%1$s", "create.item_attributes.has_name": "有自定义名称%1$s", diff --git a/src/generated/resources/assets/create/lang/unfinished/zh_tw.json b/src/generated/resources/assets/create/lang/unfinished/zh_tw.json index a0122693f..767b6f86c 100644 --- a/src/generated/resources/assets/create/lang/unfinished/zh_tw.json +++ b/src/generated/resources/assets/create/lang/unfinished/zh_tw.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 560", + "_": "Missing Localizations: 564", "_": "->------------------------] Game Elements [------------------------<-", @@ -1024,6 +1024,10 @@ "create.item_attributes.added_by.inverted": "不是由%1$s添加", "create.item_attributes.has_enchant": "有附魔效果%1$s", "create.item_attributes.has_enchant.inverted": "沒有附魔效果%1$s", + "create.item_attributes.color": "UNLOCALIZED: is dyed %1$s", + "create.item_attributes.color.inverted": "UNLOCALIZED: is not dyed %1$s", + "create.item_attributes.max_enchanted": "UNLOCALIZED: is enchanted at max level", + "create.item_attributes.max_enchanted.inverted": "UNLOCALIZED: is not enchanted at max level", "create.item_attributes.has_fluid": "包含%1$s", "create.item_attributes.has_fluid.inverted": "不包含%1$s", "create.item_attributes.has_name": "有自定義名稱%1$s", diff --git a/src/main/java/com/simibubi/create/content/logistics/item/filter/ItemAttribute.java b/src/main/java/com/simibubi/create/content/logistics/item/filter/ItemAttribute.java index ea1782646..1f6cdfa46 100644 --- a/src/main/java/com/simibubi/create/content/logistics/item/filter/ItemAttribute.java +++ b/src/main/java/com/simibubi/create/content/logistics/item/filter/ItemAttribute.java @@ -1,31 +1,15 @@ package com.simibubi.create.content.logistics.item.filter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.function.BiPredicate; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -import org.apache.commons.lang3.StringUtils; - -import com.google.common.base.Predicates; import com.simibubi.create.AllRecipeTypes; import com.simibubi.create.content.logistics.InWorldProcessing; -import com.simibubi.create.content.logistics.item.filter.attribute.BookAuthorAttribute; -import com.simibubi.create.content.logistics.item.filter.attribute.BookCopyAttribute; -import com.simibubi.create.content.logistics.item.filter.attribute.EnchantAttribute; -import com.simibubi.create.content.logistics.item.filter.attribute.FluidContentsAttribute; -import com.simibubi.create.content.logistics.item.filter.attribute.ItemNameAttribute; +import com.simibubi.create.content.logistics.item.filter.attribute.*; import com.simibubi.create.content.logistics.item.filter.attribute.astralsorcery.AstralSorceryAmuletAttribute; import com.simibubi.create.content.logistics.item.filter.attribute.astralsorcery.AstralSorceryAttunementAttribute; import com.simibubi.create.content.logistics.item.filter.attribute.astralsorcery.AstralSorceryCrystalAttribute; import com.simibubi.create.content.logistics.item.filter.attribute.astralsorcery.AstralSorceryPerkGemAttribute; import com.simibubi.create.foundation.utility.Lang; - import net.minecraft.client.resources.I18n; +import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.inventory.IInventory; import net.minecraft.item.BlockItem; import net.minecraft.item.Item; @@ -45,6 +29,12 @@ import net.minecraftforge.fml.ModList; import net.minecraftforge.forgespi.language.IModInfo; import net.minecraftforge.items.ItemStackHandler; import net.minecraftforge.items.wrapper.RecipeWrapper; +import org.apache.commons.lang3.StringUtils; + +import java.util.*; +import java.util.function.BiPredicate; +import java.util.function.Predicate; +import java.util.stream.Collectors; public interface ItemAttribute { @@ -54,6 +44,7 @@ public interface ItemAttribute { static ItemAttribute inTag = register(new InTag(new ResourceLocation("dummy"))); static ItemAttribute inItemGroup = register(new InItemGroup(ItemGroup.MISC)); static ItemAttribute hasEnchant = register(EnchantAttribute.EMPTY); + static ItemAttribute hasColor = register(ColorAttribute.EMPTY); static ItemAttribute hasFluid = register(FluidContentsAttribute.EMPTY); static ItemAttribute hasName = register(new ItemNameAttribute("dummy")); static ItemAttribute astralAmulet = register(new AstralSorceryAmuletAttribute("dummy", -1)); @@ -130,8 +121,9 @@ public interface ItemAttribute { RENAMED(ItemStack::hasDisplayName), DAMAGED(ItemStack::isDamaged), BADLY_DAMAGED(s -> s.isDamaged() && s.getDamage() / s.getMaxDamage() > 3 / 4f), - NOT_STACKABLE(Predicates.not(ItemStack::isStackable)), + NOT_STACKABLE(((Predicate) ItemStack::isStackable).negate()), EQUIPABLE(s -> s.getEquipmentSlot() != null), + MAX_ENCHANTED(StandardTraits::maxEnchanted), FURNACE_FUEL(AbstractFurnaceTileEntity::isFuel), WASHABLE(InWorldProcessing::isWashable), CRUSHABLE((s, w) -> testRecipe(s, w, AllRecipeTypes.CRUSHING.getType()) @@ -155,6 +147,13 @@ public interface ItemAttribute { .isPresent(); } + private static boolean maxEnchanted(ItemStack s) { + return EnchantmentHelper.getEnchantments(s.getEnchantmentTagList()) + .entrySet() + .stream() + .anyMatch(e -> e.getKey().getMaxLevel() <= e.getValue()); + } + private StandardTraits(BiPredicate test) { this.testWithWorld = test; } diff --git a/src/main/java/com/simibubi/create/content/logistics/item/filter/attribute/ColorAttribute.java b/src/main/java/com/simibubi/create/content/logistics/item/filter/attribute/ColorAttribute.java new file mode 100644 index 000000000..3d8fce2c9 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/item/filter/attribute/ColorAttribute.java @@ -0,0 +1,86 @@ +package com.simibubi.create.content.logistics.item.filter.attribute; + +import com.simibubi.create.content.logistics.item.filter.ItemAttribute; +import net.minecraft.item.DyeColor; +import net.minecraft.item.FireworkRocketItem; +import net.minecraft.item.FireworkStarItem; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.nbt.ListNBT; +import net.minecraft.util.text.TranslationTextComponent; + +import java.util.*; +import java.util.stream.Collectors; + +public class ColorAttribute implements ItemAttribute { + public static final ColorAttribute EMPTY = new ColorAttribute(DyeColor.PURPLE); + + public final DyeColor color; + + public ColorAttribute(DyeColor color) { + this.color = color; + } + + @Override + public boolean appliesTo(ItemStack itemStack) { + return findMatchingDyeColors(itemStack).stream().anyMatch(color::equals); + } + + @Override + public List listAttributesOf(ItemStack itemStack) { + return findMatchingDyeColors(itemStack).stream().map(ColorAttribute::new).collect(Collectors.toList()); + } + + private Collection findMatchingDyeColors(ItemStack stack) { + CompoundNBT nbt = stack.getTag(); + + DyeColor color = DyeColor.getColor(stack); + if (color != null) + return Collections.singletonList(color); + + Set colors = new HashSet<>(); + if (stack.getItem() instanceof FireworkRocketItem && nbt != null) { + ListNBT listnbt = nbt.getCompound("Fireworks").getList("Explosions", 10); + for (int i = 0; i < listnbt.size(); i++) { + colors.addAll(getFireworkStarColors(listnbt.getCompound(i))); + } + } + + if (stack.getItem() instanceof FireworkStarItem && nbt != null) { + colors.addAll(getFireworkStarColors(nbt.getCompound("Explosion"))); + } + + Arrays.stream(DyeColor.values()).filter(c -> stack.getItem().getRegistryName().getPath().startsWith(c.getTranslationKey() + "_")).forEach(colors::add); + + return colors; + } + + private Collection getFireworkStarColors(CompoundNBT compound) { + Set colors = new HashSet<>(); + Arrays.stream(compound.getIntArray("Colors")).mapToObj(DyeColor::byFireworkColor).forEach(colors::add); + Arrays.stream(compound.getIntArray("FadeColors")).mapToObj(DyeColor::byFireworkColor).forEach(colors::add); + return colors; + } + + @Override + public String getTranslationKey() { + return "color"; + } + + @Override + public Object[] getTranslationParameters() { + return new Object[]{new TranslationTextComponent(color.getTranslationKey()).getFormattedText()}; + } + + @Override + public void writeNBT(CompoundNBT nbt) { + nbt.putInt("id", color.getId()); + } + + @Override + public ItemAttribute readNBT(CompoundNBT nbt) { + return nbt.contains("id") ? + new ColorAttribute(DyeColor.byId(nbt.getInt("id"))) + : EMPTY; + } +} diff --git a/src/main/resources/assets/create/lang/default/messages.json b/src/main/resources/assets/create/lang/default/messages.json index 2131d38a8..a5176a70f 100644 --- a/src/main/resources/assets/create/lang/default/messages.json +++ b/src/main/resources/assets/create/lang/default/messages.json @@ -379,6 +379,10 @@ "create.item_attributes.has_enchant": "is enchanted with %1$s", "create.item_attributes.has_enchant.inverted": "is not enchanted with %1$s", + "create.item_attributes.color": "is dyed %1$s", + "create.item_attributes.color.inverted": "is not dyed %1$s", + "create.item_attributes.max_enchanted": "is enchanted at max level", + "create.item_attributes.max_enchanted.inverted": "is not enchanted at max level", "create.item_attributes.has_fluid": "contains %1$s", "create.item_attributes.has_fluid.inverted": "does not contain %1$s", "create.item_attributes.has_name": "has the custom name %1$s",