From 48d51205cf9fbc370db25dd3073e0d969737742e Mon Sep 17 00:00:00 2001 From: Swedz Date: Thu, 21 Nov 2024 16:30:40 -0500 Subject: [PATCH 01/89] Merge "Various internal machine api improvements" (#900) --- .../impl/MachineScreenPredicateTest.java | 20 +-- .../datagen/model/MachineCasingsProvider.java | 6 +- .../machines/MachineBlockEntityRenderer.java | 2 +- .../machines/gui/MachineMenuClient.java | 16 +-- .../machines/gui/MachineScreen.java | 13 +- .../machines/models/MachineBakedModel.java | 63 ++++---- .../machines/models/MachineModelBaker.java | 34 +++++ .../machines/models/MachineOverlaysJson.java | 70 +++++++++ .../machines/models/MachineUnbakedModel.java | 70 +++------ .../multiblocks/MultiblockMachineBER.java | 2 +- .../textures/MITextures.java | 2 +- .../api/energy/CableTierHolder.java | 28 ++++ .../model/MachineModelsToGenerate.java | 2 +- .../debug/DebugCommands.java | 4 +- .../inventory/BackgroundRenderedSlot.java | 11 ++ .../machines/ComponentStorage.java | 136 ++++++++++++++++++ .../machines/MachineBlockEntity.java | 75 ++-------- .../blockentities/hatches/EnergyHatch.java | 12 +- ...AbstractCraftingMultiblockBlockEntity.java | 40 +----- ...ElectricCraftingMultiblockBlockEntity.java | 9 +- .../GeneratorMultiblockBlockEntity.java | 48 ++----- .../LargeTankMultiblockBlockEntity.java | 37 +---- .../NuclearReactorMultiblockBlockEntity.java | 49 ++----- .../SteamBoilerMultiblockBlockEntity.java | 30 +--- .../SteamCraftingMultiblockBlockEntity.java | 5 +- .../machines/components/CasingComponent.java | 16 ++- .../components/OrientationComponent.java | 12 +- .../machines/gui/MachineMenuCommon.java | 8 +- .../machines/gui/MachineMenuServer.java | 11 +- .../machines/models/MachineCasing.java | 8 +- .../machines/models/MachineCasings.java | 28 ++-- .../multiblocks/HatchBlockEntity.java | 11 +- .../MultiblockMachineBlockEntity.java | 60 +++++++- .../machines/multiblocks/ShapeMatcher.java | 16 +-- .../network/machines/ChangeShapePacket.java | 2 +- .../network/machines/ReiLockSlotsPacket.java | 2 +- .../machines/SetAutoExtractPacket.java | 2 +- 37 files changed, 560 insertions(+), 400 deletions(-) create mode 100644 src/client/java/aztech/modern_industrialization/machines/models/MachineModelBaker.java create mode 100644 src/client/java/aztech/modern_industrialization/machines/models/MachineOverlaysJson.java create mode 100644 src/main/java/aztech/modern_industrialization/api/energy/CableTierHolder.java create mode 100644 src/main/java/aztech/modern_industrialization/machines/ComponentStorage.java diff --git a/src/client/java/aztech/modern_industrialization/compat/viewer/impl/MachineScreenPredicateTest.java b/src/client/java/aztech/modern_industrialization/compat/viewer/impl/MachineScreenPredicateTest.java index cd198d1fe..16b638aaf 100644 --- a/src/client/java/aztech/modern_industrialization/compat/viewer/impl/MachineScreenPredicateTest.java +++ b/src/client/java/aztech/modern_industrialization/compat/viewer/impl/MachineScreenPredicateTest.java @@ -24,24 +24,24 @@ package aztech.modern_industrialization.compat.viewer.impl; import aztech.modern_industrialization.compat.rei.machines.ReiMachineRecipes; -import aztech.modern_industrialization.machines.gui.GuiComponentClient; import aztech.modern_industrialization.machines.gui.MachineScreen; import aztech.modern_industrialization.machines.guicomponents.CraftingMultiblockGuiClient; +import java.util.Optional; public class MachineScreenPredicateTest { public static boolean test(ReiMachineRecipes.MachineScreenPredicate predicate, MachineScreen screen) { return switch (predicate) { case ANY -> true; - case MULTIBLOCK -> { - for (GuiComponentClient client : screen.getMenu().components) { - if (client instanceof CraftingMultiblockGuiClient cmGui) { - if (cmGui.isShapeValid) { - yield true; + case MULTIBLOCK -> screen.getMenu().components.findOrDefault( + client -> { + if (client instanceof CraftingMultiblockGuiClient cmGui) { + if (cmGui.isShapeValid) { + return Optional.of(true); + } } - } - } - yield false; - } + return Optional.empty(); + }, + false); }; } } diff --git a/src/client/java/aztech/modern_industrialization/datagen/model/MachineCasingsProvider.java b/src/client/java/aztech/modern_industrialization/datagen/model/MachineCasingsProvider.java index cabf5cb9f..af7196993 100644 --- a/src/client/java/aztech/modern_industrialization/datagen/model/MachineCasingsProvider.java +++ b/src/client/java/aztech/modern_industrialization/datagen/model/MachineCasingsProvider.java @@ -81,16 +81,16 @@ protected void registerModels() { } private void imitateBlock(MachineCasing casing, Block block) { - getBuilder(casing.name) + getBuilder(casing.key.toString()) .customLoader((bmb, existingFileHelper) -> new UseBlockModelModelBuilder<>(block, bmb, existingFileHelper)); } private void cubeBottomTop(MachineCasing casing, String side, String bottom, String top) { - cubeBottomTop(casing.name, MI.id(side), MI.id(bottom), MI.id(top)); + cubeBottomTop(casing.key.toString(), MI.id(side), MI.id(bottom), MI.id(top)); } private void cubeAll(MachineCasing casing, String side) { - cubeAll(casing.name, MI.id(side)); + cubeAll(casing.key.toString(), MI.id(side)); } @Override diff --git a/src/client/java/aztech/modern_industrialization/machines/MachineBlockEntityRenderer.java b/src/client/java/aztech/modern_industrialization/machines/MachineBlockEntityRenderer.java index 411d0daaa..ef31f3a4d 100644 --- a/src/client/java/aztech/modern_industrialization/machines/MachineBlockEntityRenderer.java +++ b/src/client/java/aztech/modern_industrialization/machines/MachineBlockEntityRenderer.java @@ -69,7 +69,7 @@ private BakedQuad getCachedQuad(MachineModelClientData data, Direction d) { var cachedQuads = quadCache.computeIfAbsent(casing, c -> new Object[36]); if (cachedQuads[cachedQuadIndex] == null) { - TextureAtlasSprite sprite = model == null ? null : MachineBakedModel.getSprite(model.getSprites(casing), d, facing, true); + TextureAtlasSprite sprite = model == null ? null : model.getSprite(model.getSprites(casing), d, facing, true); if (sprite != null) { var vc = new QuadBakingVertexConsumer(); cachedQuads[cachedQuadIndex] = ModelHelper.bakeSprite(vc, d, sprite, -2 * MachineBakedModel.Z_OFFSET); diff --git a/src/client/java/aztech/modern_industrialization/machines/gui/MachineMenuClient.java b/src/client/java/aztech/modern_industrialization/machines/gui/MachineMenuClient.java index 694019608..a4bee1d3a 100644 --- a/src/client/java/aztech/modern_industrialization/machines/gui/MachineMenuClient.java +++ b/src/client/java/aztech/modern_industrialization/machines/gui/MachineMenuClient.java @@ -27,6 +27,7 @@ import aztech.modern_industrialization.inventory.ConfigurableItemStack; import aztech.modern_industrialization.inventory.MIInventory; import aztech.modern_industrialization.inventory.SlotPositions; +import aztech.modern_industrialization.machines.ComponentStorage; import aztech.modern_industrialization.machines.GuiComponentsClient; import aztech.modern_industrialization.util.NbtHelper; import java.util.ArrayList; @@ -52,11 +53,11 @@ public static MachineMenuClient create(int syncId, Inventory playerInventory, Re SlotPositions fluidPositions = SlotPositions.read(buf); MIInventory inventory = new MIInventory(itemStacks, fluidStacks, itemPositions, fluidPositions); // Components - List components = new ArrayList<>(); + ComponentStorage components = new ComponentStorage<>(); int componentCount = buf.readInt(); for (int i = 0; i < componentCount; ++i) { ResourceLocation id = buf.readResourceLocation(); - components.add(GuiComponentsClient.get(id).createFromInitialData(buf)); + components.register(GuiComponentsClient.get(id).createFromInitialData(buf)); } // GUI params MachineGuiParameters guiParams = MachineGuiParameters.read(buf); @@ -64,9 +65,9 @@ public static MachineMenuClient create(int syncId, Inventory playerInventory, Re return new MachineMenuClient(syncId, playerInventory, inventory, components, guiParams); } - public final List components; + public final ComponentStorage components; - private MachineMenuClient(int syncId, Inventory playerInventory, MIInventory inventory, List components, + private MachineMenuClient(int syncId, Inventory playerInventory, MIInventory inventory, ComponentStorage components, MachineGuiParameters guiParams) { super(syncId, playerInventory, inventory, guiParams, components); this.components = components; @@ -74,12 +75,7 @@ private MachineMenuClient(int syncId, Inventory playerInventory, MIInventory inv @Nullable public T getComponent(Class klass) { - for (GuiComponentClient component : components) { - if (klass.isInstance(component)) { - return (T) component; - } - } - return null; + return components.get(klass).orElse(null); } @Override diff --git a/src/client/java/aztech/modern_industrialization/machines/gui/MachineScreen.java b/src/client/java/aztech/modern_industrialization/machines/gui/MachineScreen.java index ab75a6164..27b22c9ef 100644 --- a/src/client/java/aztech/modern_industrialization/machines/gui/MachineScreen.java +++ b/src/client/java/aztech/modern_industrialization/machines/gui/MachineScreen.java @@ -64,9 +64,7 @@ public class MachineScreen extends MIHandledScreen implements public MachineScreen(MachineMenuClient handler, Inventory inventory, Component title) { super(handler, inventory, title); - for (GuiComponentClient component : handler.components) { - renderers.add(component.createRenderer(this)); - } + handler.components.forEach(component -> renderers.add(component.createRenderer(this))); this.imageHeight = handler.guiParams.backgroundHeight; this.imageWidth = handler.guiParams.backgroundWidth; @@ -211,10 +209,15 @@ protected void renderBg(GuiGraphics guiGraphics, float delta, int mouseX, int mo private void renderConfigurableSlotBackgrounds(GuiGraphics guiGraphics) { for (Slot slot : this.menu.slots) { - if (slot instanceof BackgroundRenderedSlot brs) { + if (slot.isActive() && slot instanceof BackgroundRenderedSlot brs) { int px = leftPos + slot.x - 1; int py = topPos + slot.y - 1; - guiGraphics.blit(SLOT_ATLAS, px, py, brs.getBackgroundU(), brs.getBackgroundV(), 18, 18); + if (slot.getItem().isEmpty()) { + var atlas = brs.getBackgroundAtlasLocation(); + guiGraphics.blit(atlas == null ? SLOT_ATLAS : atlas, px, py, brs.getBackgroundU(), brs.getBackgroundV(), 18, 18); + } else { + guiGraphics.blit(SLOT_ATLAS, px, py, 0, 0, 18, 18); + } } } } diff --git a/src/client/java/aztech/modern_industrialization/machines/models/MachineBakedModel.java b/src/client/java/aztech/modern_industrialization/machines/models/MachineBakedModel.java index 8012f6007..ce537a945 100644 --- a/src/client/java/aztech/modern_industrialization/machines/models/MachineBakedModel.java +++ b/src/client/java/aztech/modern_industrialization/machines/models/MachineBakedModel.java @@ -23,7 +23,6 @@ */ package aztech.modern_industrialization.machines.models; -import aztech.modern_industrialization.MI; import aztech.modern_industrialization.util.ModelHelper; import java.util.ArrayList; import java.util.List; @@ -39,6 +38,7 @@ import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.resources.ResourceLocation; import net.minecraft.util.RandomSource; import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.block.state.BlockState; @@ -57,7 +57,8 @@ public class MachineBakedModel implements IDynamicBakedModel { public static final String CASING_FOLDER = "machine_casing"; public static ModelResourceLocation getCasingModelId(MachineCasing casing) { - return ModelResourceLocation.standalone(MI.id(CASING_FOLDER + "/" + casing.name)); + return ModelResourceLocation + .standalone(ResourceLocation.fromNamespaceAndPath(casing.key.getNamespace(), CASING_FOLDER + "/" + casing.key.getPath())); } public static BakedModel getCasingModel(MachineCasing casing) { @@ -65,14 +66,16 @@ public static BakedModel getCasingModel(MachineCasing casing) { } private final MachineCasing baseCasing; + private final int[] outputOverlayIndexes; private final TextureAtlasSprite[] defaultOverlays; - private final Map tieredOverlays; + private final Map tieredOverlays; private final MachineModelClientData defaultData; - MachineBakedModel(MachineCasing baseCasing, - TextureAtlasSprite[] defaultOverlays, - Map tieredOverlays) { + public MachineBakedModel(MachineCasing baseCasing, + int[] outputOverlayIndexes, TextureAtlasSprite[] defaultOverlays, + Map tieredOverlays) { this.baseCasing = baseCasing; + this.outputOverlayIndexes = outputOverlayIndexes; this.defaultOverlays = defaultOverlays; this.tieredOverlays = tieredOverlays; this.defaultData = new MachineModelClientData(baseCasing, Direction.NORTH); @@ -86,14 +89,14 @@ public TextureAtlasSprite[] getSprites(@Nullable MachineCasing casing) { if (casing == null) { return defaultOverlays; } - return tieredOverlays.getOrDefault(casing.name, defaultOverlays); + return tieredOverlays.getOrDefault(casing.key, defaultOverlays); } /** * Returns null if nothing should be rendered. */ @Nullable - public static TextureAtlasSprite getSprite(TextureAtlasSprite[] sprites, Direction side, Direction facingDirection, boolean isActive) { + public TextureAtlasSprite getSprite(TextureAtlasSprite[] sprites, Direction side, Direction facingDirection, boolean isActive) { int spriteId; if (side.getAxis().isHorizontal()) { spriteId = (facingDirection.get2DDataValue() - side.get2DDataValue() + 4) % 4 * 2; @@ -121,44 +124,50 @@ public ModelData getModelData(BlockAndTintGetter level, BlockPos pos, BlockState return getCasingModel(casing).getModelData(level, pos, state, modelData); } - @Override - public @NotNull List getQuads(@Nullable BlockState state, @Nullable Direction side, @NotNull RandomSource rand, - @NotNull ModelData extraData, @Nullable RenderType renderType) { - var data = extraData.get(MachineModelClientData.KEY); - if (data == null) { - data = defaultData; - } - - MachineCasing casing = Objects.requireNonNullElse(data.casing, baseCasing); - var sprites = getSprites(casing); - + protected @NotNull List getQuads(@Nullable BlockState state, @Nullable Direction side, @NotNull RandomSource rand, + @NotNull ModelData extraData, @Nullable RenderType renderType, + @NotNull MachineModelClientData data, @NotNull MachineCasing casing, + @NotNull TextureAtlasSprite[] sprites, @NotNull QuadBakingVertexConsumer vertexConsumer) { List quads = new ArrayList<>(); - var vc = new QuadBakingVertexConsumer(); if (side != null) { - // Casing quads.addAll(getCasingModel(casing).getQuads(state, side, rand, extraData, renderType)); - // Machine overlays + TextureAtlasSprite sprite = getSprite(sprites, side, data.frontDirection, false); if (sprite != null) { - quads.add(ModelHelper.bakeSprite(vc, side, sprite, -Z_OFFSET)); + quads.add(ModelHelper.bakeSprite(vertexConsumer, side, sprite, -Z_OFFSET)); } } - // Output overlays if (data.outputDirection != null && side == data.outputDirection) { - quads.add(ModelHelper.bakeSprite(vc, data.outputDirection, sprites[24], -3 * Z_OFFSET)); + quads.add(ModelHelper.bakeSprite(vertexConsumer, data.outputDirection, sprites[outputOverlayIndexes[0]], -3 * Z_OFFSET)); if (data.itemAutoExtract) { - quads.add(ModelHelper.bakeSprite(vc, data.outputDirection, sprites[25], -3 * Z_OFFSET)); + quads.add(ModelHelper.bakeSprite(vertexConsumer, data.outputDirection, sprites[outputOverlayIndexes[1]], -3 * Z_OFFSET)); } if (data.fluidAutoExtract) { - quads.add(ModelHelper.bakeSprite(vc, data.outputDirection, sprites[26], -3 * Z_OFFSET)); + quads.add(ModelHelper.bakeSprite(vertexConsumer, data.outputDirection, sprites[outputOverlayIndexes[2]], -3 * Z_OFFSET)); } } return quads; } + @Override + public @NotNull List getQuads(@Nullable BlockState state, @Nullable Direction side, @NotNull RandomSource rand, + @NotNull ModelData extraData, @Nullable RenderType renderType) { + var data = extraData.get(MachineModelClientData.KEY); + if (data == null) { + data = defaultData; + } + + MachineCasing casing = Objects.requireNonNullElse(data.casing, baseCasing); + var sprites = getSprites(casing); + + var vc = new QuadBakingVertexConsumer(); + + return getQuads(state, side, rand, extraData, renderType, data, casing, sprites, vc); + } + @Override public boolean useAmbientOcclusion() { return true; diff --git a/src/client/java/aztech/modern_industrialization/machines/models/MachineModelBaker.java b/src/client/java/aztech/modern_industrialization/machines/models/MachineModelBaker.java new file mode 100644 index 000000000..ebe775847 --- /dev/null +++ b/src/client/java/aztech/modern_industrialization/machines/models/MachineModelBaker.java @@ -0,0 +1,34 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.machines.models; + +import java.util.Map; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.resources.ResourceLocation; + +public interface MachineModelBaker { + MachineBakedModel bake(MachineCasing baseCasing, + int[] outputOverlayIndexes, TextureAtlasSprite[] defaultOverlays, + Map tieredOverlays); +} diff --git a/src/client/java/aztech/modern_industrialization/machines/models/MachineOverlaysJson.java b/src/client/java/aztech/modern_industrialization/machines/models/MachineOverlaysJson.java new file mode 100644 index 000000000..4ea8cca2e --- /dev/null +++ b/src/client/java/aztech/modern_industrialization/machines/models/MachineOverlaysJson.java @@ -0,0 +1,70 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.machines.models; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; +import java.lang.reflect.Field; +import net.minecraft.client.resources.model.Material; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.inventory.InventoryMenu; + +public interface MachineOverlaysJson { + Material[] toSpriteIds(); + + int[] getOutputSpriteIndexes(); + + Gson GSON = new GsonBuilder().registerTypeAdapter(ResourceLocation.class, new ResourceLocation.Serializer()).create(); + + static O parse(Class clazz, JsonObject json, MachineOverlaysJson defaultOverlay) { + O overlays = GSON.fromJson(json, clazz); + + if (defaultOverlay != null) { + try { + for (Field field : clazz.getDeclaredFields()) { + if (field.get(overlays) == null) { + field.set(overlays, field.get(defaultOverlay)); + } + } + } catch (IllegalAccessException ex) { + throw new RuntimeException("Failed to copy fields from default overlay", ex); + } + } + + return overlays; + } + + /** + * Select first non-null id, and convert it to a sprite id. + */ + default Material select(ResourceLocation... candidates) { + for (ResourceLocation id : candidates) { + if (id != null) { + return new Material(InventoryMenu.BLOCK_ATLAS, id); + } + } + return null; + } +} diff --git a/src/client/java/aztech/modern_industrialization/machines/models/MachineUnbakedModel.java b/src/client/java/aztech/modern_industrialization/machines/models/MachineUnbakedModel.java index 15a5ddd01..3029f47a8 100644 --- a/src/client/java/aztech/modern_industrialization/machines/models/MachineUnbakedModel.java +++ b/src/client/java/aztech/modern_industrialization/machines/models/MachineUnbakedModel.java @@ -24,8 +24,6 @@ package aztech.modern_industrialization.machines.models; import aztech.modern_industrialization.MI; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; import java.util.HashMap; import java.util.Map; @@ -38,34 +36,36 @@ import net.minecraft.client.resources.model.ModelState; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.GsonHelper; -import net.minecraft.world.inventory.InventoryMenu; import net.neoforged.neoforge.client.model.geometry.IGeometryBakingContext; import net.neoforged.neoforge.client.model.geometry.IGeometryLoader; import net.neoforged.neoforge.client.model.geometry.IUnbakedGeometry; -import org.jetbrains.annotations.Nullable; -public class MachineUnbakedModel implements IUnbakedGeometry { +public class MachineUnbakedModel implements IUnbakedGeometry> { public static final ResourceLocation LOADER_ID = MI.id("machine"); - public static final IGeometryLoader LOADER = (jsonObject, deserializationContext) -> { - return new MachineUnbakedModel(jsonObject); + public static final IGeometryLoader> LOADER = (jsonObject, deserializationContext) -> { + return new MachineUnbakedModel(OverlaysJson.class, MachineBakedModel::new, jsonObject); }; - private static final Gson GSON = new GsonBuilder().registerTypeAdapter(ResourceLocation.class, new ResourceLocation.Serializer()).create(); - + private final MachineModelBaker modelBaker; private final MachineCasing baseCasing; + private final int[] outputOverlayIndexes; private final Material[] defaultOverlays; - private final Map tieredOverlays = new HashMap<>(); + private final Map tieredOverlays = new HashMap<>(); + + public MachineUnbakedModel(Class overlayClass, MachineModelBaker modelBaker, JsonObject obj) { + this.modelBaker = modelBaker; - private MachineUnbakedModel(JsonObject obj) { this.baseCasing = MachineCasings.get(GsonHelper.getAsString(obj, "casing")); - var defaultOverlaysJson = OverlaysJson.parse(GsonHelper.getAsJsonObject(obj, "default_overlays"), null); + var defaultOverlaysJson = MachineOverlaysJson.parse(overlayClass, GsonHelper.getAsJsonObject(obj, "default_overlays"), null); + this.outputOverlayIndexes = defaultOverlaysJson.getOutputSpriteIndexes(); this.defaultOverlays = defaultOverlaysJson.toSpriteIds(); var tieredOverlays = GsonHelper.getAsJsonObject(obj, "tiered_overlays", new JsonObject()); for (var casingTier : tieredOverlays.keySet()) { - var casingOverlaysJson = OverlaysJson.parse(GsonHelper.getAsJsonObject(tieredOverlays, casingTier), defaultOverlaysJson); - this.tieredOverlays.put(casingTier, casingOverlaysJson.toSpriteIds()); + var casingOverlaysJson = MachineOverlaysJson.parse(overlayClass, GsonHelper.getAsJsonObject(tieredOverlays, casingTier), + defaultOverlaysJson); + this.tieredOverlays.put(ResourceLocation.parse(casingTier), casingOverlaysJson.toSpriteIds()); } } @@ -73,11 +73,11 @@ private MachineUnbakedModel(JsonObject obj) { public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Function spriteGetter, ModelState modelState, ItemOverrides overrides) { var defaultOverlays = loadSprites(spriteGetter, this.defaultOverlays); - var tieredOverlays = new HashMap(); + var tieredOverlays = new HashMap(); for (var entry : this.tieredOverlays.entrySet()) { tieredOverlays.put(entry.getKey(), loadSprites(spriteGetter, entry.getValue())); } - return new MachineBakedModel(baseCasing, defaultOverlays, tieredOverlays); + return modelBaker.bake(baseCasing, outputOverlayIndexes, defaultOverlays, tieredOverlays); } private static TextureAtlasSprite[] loadSprites(Function textureGetter, Material[] ids) { @@ -90,7 +90,7 @@ private static TextureAtlasSprite[] loadSprites(Function Component.literal("Successfully built multiblock at position %s. %d blocks updated.".formatted( diff --git a/src/main/java/aztech/modern_industrialization/inventory/BackgroundRenderedSlot.java b/src/main/java/aztech/modern_industrialization/inventory/BackgroundRenderedSlot.java index f0cb1f6a3..7a0af9d53 100644 --- a/src/main/java/aztech/modern_industrialization/inventory/BackgroundRenderedSlot.java +++ b/src/main/java/aztech/modern_industrialization/inventory/BackgroundRenderedSlot.java @@ -23,10 +23,21 @@ */ package aztech.modern_industrialization.inventory; +import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.Nullable; + /** * Implement this on a slot to render its background automatically. */ public interface BackgroundRenderedSlot { + /** + * @return the {@link ResourceLocation} of the slot atlas texture to use for the slot background. When null, uses the MI slot atlas + */ + @Nullable + default ResourceLocation getBackgroundAtlasLocation() { + return null; + } + default int getBackgroundU() { return 0; } diff --git a/src/main/java/aztech/modern_industrialization/machines/ComponentStorage.java b/src/main/java/aztech/modern_industrialization/machines/ComponentStorage.java new file mode 100644 index 000000000..d174f62d6 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/machines/ComponentStorage.java @@ -0,0 +1,136 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.machines; + +import aztech.modern_industrialization.machines.gui.GuiComponent; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Function; +import net.minecraft.resources.ResourceLocation; + +public sealed class ComponentStorage permits ComponentStorage.GuiServer, ComponentStorage.Server { + protected final List components = new ArrayList<>(); + + @SafeVarargs + public final void register(C... components) { + Collections.addAll(this.components, components); + } + + @SafeVarargs + public final void unregister(C... components) { + for (C component : components) { + this.components.remove(component); + } + } + + public final int size() { + return components.size(); + } + + public final C get(int index) { + return components.get(index); + } + + public final void forEach(Consumer action) { + components.forEach(action); + } + + public final void forEachIndexed(BiConsumer action) { + for (int i = 0; i < components.size(); i++) { + action.accept(i, components.get(i)); + } + } + + public final Optional get(Class clazz) { + for (C component : components) { + if (clazz.isInstance(component)) { + return Optional.of((T) component); + } + } + return Optional.empty(); + } + + public final List tryGet(Class clazz) { + List components = new ArrayList<>(); + for (C component : this.components) { + if (clazz.isInstance(component)) { + components.add((T) component); + } + } + return components; + } + + public final void forType(Class clazz, Consumer action) { + List component = tryGet(clazz); + for (T c : component) { + action.accept(c); + } + } + + public final R mapOrDefault(Class clazz, Function action, R defaultValue) { + List components = tryGet(clazz); + if (components.isEmpty()) { + return defaultValue; + } else if (components.size() == 1) { + return action.apply(components.get(0)); + } else { + throw new RuntimeException("Multiple components of type " + clazz.getName() + " found"); + } + } + + public final R findOrDefault(Function> action, R defaultValue) { + for (C component : components) { + Optional result = action.apply(component); + if (result.isPresent()) { + return result.get(); + } + } + return defaultValue; + } + + public final R findOrDefault(Class clazz, Function> action, R defaultValue) { + return findOrDefault(component -> clazz.isInstance(component) ? action.apply((T) component) : Optional.empty(), defaultValue); + } + + public static final class GuiServer extends ComponentStorage { + /** + * @throws RuntimeException if the component doesn't exist. + */ + public S get(ResourceLocation componentId) { + for (GuiComponent.Server component : components) { + if (component.getId().equals(componentId)) { + return (S) component; + } + } + throw new RuntimeException("Couldn't find component " + componentId); + } + } + + public static final class Server extends ComponentStorage { + } +} diff --git a/src/main/java/aztech/modern_industrialization/machines/MachineBlockEntity.java b/src/main/java/aztech/modern_industrialization/machines/MachineBlockEntity.java index 026f30410..c9994ef50 100644 --- a/src/main/java/aztech/modern_industrialization/machines/MachineBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/machines/MachineBlockEntity.java @@ -37,10 +37,7 @@ import aztech.modern_industrialization.util.NbtHelper; import aztech.modern_industrialization.util.WorldHelper; import java.util.ArrayList; -import java.util.Collections; import java.util.List; -import java.util.function.Consumer; -import java.util.function.Function; import net.minecraft.Util; import net.minecraft.core.Direction; import net.minecraft.core.HolderLookup; @@ -50,7 +47,6 @@ import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.game.ClientGamePacketListener; import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; -import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionHand; import net.minecraft.world.ItemInteractionResult; @@ -75,8 +71,8 @@ @SuppressWarnings("rawtypes") public abstract class MachineBlockEntity extends FastBlockEntity implements MenuProvider, WrenchableBlockEntity { - public final List guiComponents = new ArrayList<>(); - private final List icomponents = new ArrayList<>(); + protected final ComponentStorage.GuiServer guiComponents = new ComponentStorage.GuiServer(); + protected final ComponentStorage.Server icomponents = new ComponentStorage.Server(); public final MachineGuiParameters guiParams; /** * Server-side only: true if the next call to sync() will trigger a remesh. @@ -101,11 +97,11 @@ public MachineBlockEntity(BEP bep, MachineGuiParameters guiParams, OrientationCo } protected final void registerGuiComponent(GuiComponent.Server... components) { - Collections.addAll(guiComponents, components); + guiComponents.register(components); } protected final void registerComponents(IComponent... components) { - Collections.addAll(icomponents, components); + icomponents.register(components); } /** @@ -113,45 +109,12 @@ protected final void registerComponents(IComponent... components) { */ public abstract MIInventory getInventory(); - /** - * @throws RuntimeException if the component doesn't exist. - */ - @SuppressWarnings("unchecked") - public S getComponent(ResourceLocation componentId) { - for (GuiComponent.Server component : guiComponents) { - if (component.getId().equals(componentId)) { - return (S) component; - } - } - throw new RuntimeException("Couldn't find component " + componentId); - } - - private List tryGetComponent(Class clazz) { - List components = new ArrayList<>(); - for (var component : icomponents) { - if (clazz.isInstance(component)) { - components.add((T) component); - } - } - return components; + public final ComponentStorage.GuiServer getGuiComponents() { + return guiComponents; } - public final void forComponentType(Class clazz, Consumer action) { - List component = tryGetComponent(clazz); - for (T c : component) { - action.accept(c); - } - } - - public R mapComponentOrDefault(Class clazz, Function action, R defaultValue) { - List components = tryGetComponent(clazz); - if (components.isEmpty()) { - return defaultValue; - } else if (components.size() == 1) { - return action.apply(components.get(0)); - } else { - throw new RuntimeException("Multiple components of type " + clazz.getName() + " found"); - } + public final ComponentStorage.Server getComponents() { + return icomponents; } @Override @@ -176,10 +139,10 @@ public final void writeScreenOpeningData(RegistryFriendlyByteBuf buf) { inv.fluidPositions.write(buf); buf.writeInt(guiComponents.size()); // Write components - for (GuiComponent.Server component : guiComponents) { + guiComponents.forEach(component -> { buf.writeResourceLocation(component.getId()); component.writeInitialData(buf); - } + }); // Write GUI params guiParams.write(buf); } @@ -238,17 +201,13 @@ public CompoundTag getUpdateTag(HolderLookup.Provider registries) { CompoundTag tag = new CompoundTag(); tag.putBoolean("remesh", syncCausesRemesh); syncCausesRemesh = false; - for (IComponent component : icomponents) { - component.writeClientNbt(tag, registries); - } + icomponents.forEach(component -> component.writeClientNbt(tag, registries)); return tag; } @Override public final void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { - for (IComponent component : icomponents) { - component.writeNbt(tag, registries); - } + icomponents.forEach(component -> component.writeNbt(tag, registries)); } @Override @@ -258,14 +217,10 @@ public final void loadAdditional(CompoundTag tag, HolderLookup.Provider registri public final void load(CompoundTag tag, HolderLookup.Provider registries, boolean isUpgradingMachine) { if (!tag.contains("remesh")) { - for (IComponent component : icomponents) { - component.readNbt(tag, registries, isUpgradingMachine); - } + icomponents.forEach(component -> component.readNbt(tag, registries, isUpgradingMachine)); } else { boolean forceChunkRemesh = tag.getBoolean("remesh"); - for (IComponent component : icomponents) { - component.readClientNbt(tag, registries); - } + icomponents.forEach(component -> component.readClientNbt(tag, registries)); if (forceChunkRemesh) { WorldHelper.forceChunkRemesh(level, worldPosition); requestModelDataUpdate(); @@ -300,7 +255,7 @@ public static void registerFluidApi(BlockEntityType bet) { public List dropExtra() { List drops = new ArrayList<>(); - forComponentType(DropableComponent.class, u -> drops.add(u.getDrop())); + icomponents.forType(DropableComponent.class, u -> drops.add(u.getDrop())); return drops; } diff --git a/src/main/java/aztech/modern_industrialization/machines/blockentities/hatches/EnergyHatch.java b/src/main/java/aztech/modern_industrialization/machines/blockentities/hatches/EnergyHatch.java index 94805acf5..ce499efc1 100644 --- a/src/main/java/aztech/modern_industrialization/machines/blockentities/hatches/EnergyHatch.java +++ b/src/main/java/aztech/modern_industrialization/machines/blockentities/hatches/EnergyHatch.java @@ -25,6 +25,7 @@ import aztech.modern_industrialization.MICapabilities; import aztech.modern_industrialization.api.energy.CableTier; +import aztech.modern_industrialization.api.energy.CableTierHolder; import aztech.modern_industrialization.api.energy.EnergyApi; import aztech.modern_industrialization.api.energy.MIEnergyStorage; import aztech.modern_industrialization.api.machine.holder.EnergyComponentHolder; @@ -39,12 +40,13 @@ import java.util.List; import net.minecraft.world.level.block.entity.BlockEntityType; -public class EnergyHatch extends HatchBlockEntity implements EnergyComponentHolder { +public class EnergyHatch extends HatchBlockEntity implements EnergyComponentHolder, CableTierHolder { public EnergyHatch(BEP bep, String name, boolean input, CableTier tier) { super(bep, new MachineGuiParameters.Builder(name, false).build(), new OrientationComponent.Params(!input, false, false)); this.input = input; + this.tier = tier; this.energy = new EnergyComponent(this, 30 * 20 * tier.getEu()); insertable = energy.buildInsertable((CableTier tier2) -> tier2 == tier); @@ -55,7 +57,8 @@ public EnergyHatch(BEP bep, String name, boolean input, CableTier tier) { this.registerComponents(energy); } - private final boolean input; + protected final boolean input; + protected final CableTier tier; protected final EnergyComponent energy; protected final MIEnergyStorage insertable; @@ -71,6 +74,11 @@ public boolean upgradesToSteel() { return false; } + @Override + public CableTier getCableTier() { + return tier; + } + @Override public MIInventory getInventory() { return MIInventory.EMPTY; diff --git a/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/AbstractCraftingMultiblockBlockEntity.java b/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/AbstractCraftingMultiblockBlockEntity.java index 530d0b7ae..e36ffcd0a 100644 --- a/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/AbstractCraftingMultiblockBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/AbstractCraftingMultiblockBlockEntity.java @@ -32,10 +32,8 @@ import aztech.modern_industrialization.machines.guicomponents.ReiSlotLocking; import aztech.modern_industrialization.machines.models.MachineModelClientData; import aztech.modern_industrialization.machines.multiblocks.MultiblockMachineBlockEntity; -import aztech.modern_industrialization.machines.multiblocks.ShapeMatcher; import aztech.modern_industrialization.machines.multiblocks.ShapeTemplate; import aztech.modern_industrialization.util.Tickable; -import org.jetbrains.annotations.Nullable; public abstract class AbstractCraftingMultiblockBlockEntity extends MultiblockMachineBlockEntity implements Tickable, MultiblockInventoryComponentHolder, CrafterComponentHolder { @@ -56,8 +54,6 @@ public AbstractCraftingMultiblockBlockEntity(BEP bep, String name, OrientationCo */ protected abstract CrafterComponent.Behavior getBehavior(); - @Nullable - private ShapeMatcher shapeMatcher = null; private OperatingState operatingState = OperatingState.NOT_MATCHED; protected final ActiveShapeComponent activeShape; @@ -65,8 +61,6 @@ public AbstractCraftingMultiblockBlockEntity(BEP bep, String name, OrientationCo protected final CrafterComponent crafter; private final IsActiveComponent isActive; - protected abstract void onSuccessfulMatch(ShapeMatcher shapeMatcher); - public ShapeTemplate getActiveShape() { return activeShape.getActiveShape(); } @@ -121,37 +115,15 @@ public void tickExtra() { } - protected final void link() { - if (shapeMatcher == null) { - shapeMatcher = new ShapeMatcher(level, worldPosition, orientation.facingDirection, getActiveShape()); - shapeMatcher.registerListeners(level); - } - if (shapeMatcher.needsRematch()) { - operatingState = OperatingState.NOT_MATCHED; - shapeValid.shapeValid = false; - shapeMatcher.rematch(level); - - if (shapeMatcher.isMatchSuccessful()) { - inventory.rebuild(shapeMatcher); - - onSuccessfulMatch(shapeMatcher); - shapeValid.shapeValid = true; - operatingState = OperatingState.TRYING_TO_RESUME; - } - - if (shapeValid.update()) { - sync(false); - } - } + @Override + protected void onRematch() { + operatingState = OperatingState.NOT_MATCHED; } @Override - public final void unlink() { - if (shapeMatcher != null) { - shapeMatcher.unlinkHatches(); - shapeMatcher.unregisterListeners(level); - shapeMatcher = null; - } + protected void onMatchSuccessful() { + inventory.rebuild(shapeMatcher); + operatingState = OperatingState.TRYING_TO_RESUME; } private enum OperatingState { diff --git a/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/AbstractElectricCraftingMultiblockBlockEntity.java b/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/AbstractElectricCraftingMultiblockBlockEntity.java index 1b564feaf..764b600d0 100644 --- a/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/AbstractElectricCraftingMultiblockBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/AbstractElectricCraftingMultiblockBlockEntity.java @@ -28,7 +28,6 @@ import aztech.modern_industrialization.machines.components.*; import aztech.modern_industrialization.machines.guicomponents.CraftingMultiblockGui; import aztech.modern_industrialization.machines.multiblocks.HatchBlockEntity; -import aztech.modern_industrialization.machines.multiblocks.ShapeMatcher; import aztech.modern_industrialization.machines.multiblocks.ShapeTemplate; import aztech.modern_industrialization.util.Simulation; import java.util.ArrayList; @@ -62,7 +61,9 @@ public List getEnergyComponents() { } @Override - protected void onSuccessfulMatch(ShapeMatcher shapeMatcher) { + protected void onMatchSuccessful() { + super.onMatchSuccessful(); + energyInputs.clear(); for (HatchBlockEntity hatch : shapeMatcher.getMatchedHatches()) { hatch.appendEnergyInputs(energyInputs); @@ -76,13 +77,13 @@ protected ItemInteractionResult useItemOn(Player player, InteractionHand hand, D result = LubricantHelper.onUse(this.crafter, player, hand); } if (!result.consumesAction()) { - result = mapComponentOrDefault(UpgradeComponent.class, upgrade -> upgrade.onUse(this, player, hand), result); + result = icomponents.mapOrDefault(UpgradeComponent.class, upgrade -> upgrade.onUse(this, player, hand), result); } if (!result.consumesAction()) { result = redstoneControl.onUse(this, player, hand); } if (!result.consumesAction()) { - result = mapComponentOrDefault(OverdriveComponent.class, overdrive -> overdrive.onUse(this, player, hand), result); + result = icomponents.mapOrDefault(OverdriveComponent.class, overdrive -> overdrive.onUse(this, player, hand), result); } return result; } diff --git a/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/GeneratorMultiblockBlockEntity.java b/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/GeneratorMultiblockBlockEntity.java index 196047c34..9bfb1b2af 100644 --- a/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/GeneratorMultiblockBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/GeneratorMultiblockBlockEntity.java @@ -33,14 +33,12 @@ import aztech.modern_industrialization.machines.models.MachineModelClientData; import aztech.modern_industrialization.machines.multiblocks.HatchBlockEntity; import aztech.modern_industrialization.machines.multiblocks.MultiblockMachineBlockEntity; -import aztech.modern_industrialization.machines.multiblocks.ShapeMatcher; import aztech.modern_industrialization.machines.multiblocks.ShapeTemplate; import aztech.modern_industrialization.util.Simulation; import aztech.modern_industrialization.util.Tickable; import java.util.ArrayList; import java.util.List; import net.minecraft.network.chat.Component; -import org.jetbrains.annotations.Nullable; public class GeneratorMultiblockBlockEntity extends MultiblockMachineBlockEntity implements Tickable, EnergyListComponentHolder, MultiblockInventoryComponentHolder { @@ -64,8 +62,6 @@ public GeneratorMultiblockBlockEntity(BEP bep, registerGuiComponent(new SlotPanel.Server(this).withRedstoneControl(redstoneControl)); } - @Nullable - private ShapeMatcher shapeMatcher = null; private boolean allowNormalOperation = false; private final ActiveShapeComponent activeShape; @@ -89,13 +85,6 @@ public MultiblockInventoryComponent getMultiblockInventoryComponent() { return inventory; } - protected void onSuccessfulMatch(ShapeMatcher shapeMatcher) { - energyOutputs.clear(); - for (HatchBlockEntity hatch : shapeMatcher.getMatchedHatches()) { - hatch.appendEnergyOutputs(energyOutputs); - } - } - @Override public final MIInventory getInventory() { return MIInventory.EMPTY; @@ -143,36 +132,19 @@ public long insertEnergy(long value, Simulation simulation) { return inserted; } - protected final void link() { - if (shapeMatcher == null) { - shapeMatcher = new ShapeMatcher(level, worldPosition, orientation.facingDirection, getActiveShape()); - shapeMatcher.registerListeners(level); - } - if (shapeMatcher.needsRematch()) { - allowNormalOperation = false; - shapeValid.shapeValid = false; - shapeMatcher.rematch(level); - - if (shapeMatcher.isMatchSuccessful()) { - inventory.rebuild(shapeMatcher); - - onSuccessfulMatch(shapeMatcher); - shapeValid.shapeValid = true; - allowNormalOperation = true; - } - - if (shapeValid.update()) { - sync(false); - } - } + @Override + protected void onRematch() { + allowNormalOperation = false; } @Override - public final void unlink() { - if (shapeMatcher != null) { - shapeMatcher.unlinkHatches(); - shapeMatcher.unregisterListeners(level); - shapeMatcher = null; + protected void onMatchSuccessful() { + inventory.rebuild(shapeMatcher); + allowNormalOperation = true; + + energyOutputs.clear(); + for (HatchBlockEntity hatch : shapeMatcher.getMatchedHatches()) { + hatch.appendEnergyOutputs(energyOutputs); } } diff --git a/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/LargeTankMultiblockBlockEntity.java b/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/LargeTankMultiblockBlockEntity.java index b34af8ff4..b244851c1 100644 --- a/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/LargeTankMultiblockBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/LargeTankMultiblockBlockEntity.java @@ -54,7 +54,6 @@ import net.neoforged.neoforge.fluids.FluidType; import net.neoforged.neoforge.fluids.capability.IFluidHandler; import net.neoforged.neoforge.fluids.capability.templates.EmptyFluidHandler; -import org.jetbrains.annotations.Nullable; public class LargeTankMultiblockBlockEntity extends MultiblockMachineBlockEntity implements Tickable, FluidStorageComponentHolder { @@ -148,9 +147,6 @@ private static ShapeTemplate buildShape(int index) { return templateBuilder.build(); } - @Nullable - private ShapeMatcher shapeMatcher = null; - private final ActiveShapeComponent activeShape; private final FluidStorageComponent fluidStorage; @@ -223,36 +219,6 @@ public FluidStorageComponent getFluidStorageComponent() { @Override protected MachineModelClientData getMachineModelData() { return new MachineModelClientData(null, orientation.facingDirection); - - } - - protected final void link() { - if (shapeMatcher == null) { - shapeMatcher = new ShapeMatcher(level, worldPosition, orientation.facingDirection, getActiveShape()); - shapeMatcher.registerListeners(level); - } - if (shapeMatcher.needsRematch()) { - shapeValid.shapeValid = false; - shapeMatcher.rematch(level); - - if (shapeMatcher.isMatchSuccessful()) { - shapeValid.shapeValid = true; - onMatchSuccessful(); - } - - if (shapeValid.update()) { - sync(false); - } - } - } - - @Override - public final void unlink() { - if (shapeMatcher != null) { - shapeMatcher.unlinkHatches(); - shapeMatcher.unregisterListeners(level); - shapeMatcher = null; - } } @Override @@ -275,7 +241,8 @@ public static long getCapacityFromComponents(int xIndex, int yIndex, int zIndex) return volume * BUCKET_PER_STRUCTURE_BLOCK * FluidType.BUCKET_VOLUME; } - private void onMatchSuccessful() { + @Override + protected void onMatchSuccessful() { int index = activeShape.getActiveShapeIndex(); long capacity = getCapacityFromComponents(getXComponent(index), getYComponent(index), getZComponent(index)); fluidStorage.setCapacity(capacity); diff --git a/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/NuclearReactorMultiblockBlockEntity.java b/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/NuclearReactorMultiblockBlockEntity.java index c383de415..323494ac2 100644 --- a/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/NuclearReactorMultiblockBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/NuclearReactorMultiblockBlockEntity.java @@ -58,7 +58,6 @@ public class NuclearReactorMultiblockBlockEntity extends MultiblockMachineBlockE private final RedstoneControlComponent redstoneControl; private final IsActiveComponent isActive; private final NuclearEfficiencyHistoryComponent efficiencyHistory; - private ShapeMatcher shapeMatcher; private NuclearGrid nuclearGrid; private Supplier dataSupplier; @@ -125,7 +124,18 @@ public void tick() { } } - protected void onSuccessfulMatch(ShapeMatcher shapeMatcher) { + @Override + public ShapeTemplate getActiveShape() { + return activeShape.getActiveShape(); + } + + @Override + protected void onRematch() { + nuclearGrid = null; + } + + @Override + protected void onMatchSuccessful() { shapeValid.shapeValid = true; int size = gridLayout[activeShape.getActiveShapeIndex()].length; NuclearHatch[][] hatchesGrid = new NuclearHatch[size][size]; @@ -174,41 +184,6 @@ protected void onSuccessfulMatch(ShapeMatcher shapeMatcher) { }; } - @Override - public ShapeTemplate getActiveShape() { - return activeShape.getActiveShape(); - } - - protected final void link() { - if (shapeMatcher == null) { - shapeMatcher = new ShapeMatcher(level, worldPosition, orientation.facingDirection, getActiveShape()); - shapeMatcher.registerListeners(level); - } - if (shapeMatcher.needsRematch()) { - shapeValid.shapeValid = false; - nuclearGrid = null; - shapeMatcher.rematch(level); - - if (shapeMatcher.isMatchSuccessful()) { - shapeValid.shapeValid = true; - onSuccessfulMatch(shapeMatcher); - } - - if (shapeValid.update()) { - sync(false); - } - } - } - - @Override - public final void unlink() { - if (shapeMatcher != null) { - shapeMatcher.unlinkHatches(); - shapeMatcher.unregisterListeners(level); - shapeMatcher = null; - } - } - public static void registerReiShapes() { for (int i = 0; i < shapeTemplates.length; ++i) { ReiMachineRecipes.registerMultiblockShape("nuclear_reactor", shapeTemplates[i], "" + i); diff --git a/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/SteamBoilerMultiblockBlockEntity.java b/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/SteamBoilerMultiblockBlockEntity.java index 418e1ef49..0c3623775 100644 --- a/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/SteamBoilerMultiblockBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/SteamBoilerMultiblockBlockEntity.java @@ -35,7 +35,6 @@ import aztech.modern_industrialization.machines.guicomponents.TemperatureBar; import aztech.modern_industrialization.machines.models.MachineModelClientData; import aztech.modern_industrialization.machines.multiblocks.MultiblockMachineBlockEntity; -import aztech.modern_industrialization.machines.multiblocks.ShapeMatcher; import aztech.modern_industrialization.machines.multiblocks.ShapeTemplate; import aztech.modern_industrialization.util.Tickable; import java.util.List; @@ -44,7 +43,6 @@ public class SteamBoilerMultiblockBlockEntity extends MultiblockMachineBlockEntity implements Tickable { - private ShapeMatcher shapeMatcher; private final ShapeTemplate shapeTemplate; private final IsActiveComponent isActiveComponent; private final RedstoneControlComponent redstoneControl; @@ -81,33 +79,9 @@ public SteamBoilerMultiblockBlockEntity(BEP bep, ShapeTemplate shapeTemplate, St } - protected final void link() { - if (shapeMatcher == null) { - shapeMatcher = new ShapeMatcher(level, worldPosition, orientation.facingDirection, shapeTemplate); - shapeMatcher.registerListeners(level); - } - if (shapeMatcher.needsRematch()) { - shapeValid.shapeValid = false; - shapeMatcher.rematch(level); - - if (shapeMatcher.isMatchSuccessful()) { - inventory.rebuild(shapeMatcher); - shapeValid.shapeValid = true; - } - - if (shapeValid.update()) { - sync(false); - } - } - } - @Override - public final void unlink() { - if (shapeMatcher != null) { - shapeMatcher.unlinkHatches(); - shapeMatcher.unregisterListeners(level); - shapeMatcher = null; - } + protected void onMatchSuccessful() { + inventory.rebuild(shapeMatcher); } @Override diff --git a/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/SteamCraftingMultiblockBlockEntity.java b/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/SteamCraftingMultiblockBlockEntity.java index f7d26d5ea..469e3b628 100644 --- a/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/SteamCraftingMultiblockBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/SteamCraftingMultiblockBlockEntity.java @@ -30,7 +30,6 @@ import aztech.modern_industrialization.machines.guicomponents.CraftingMultiblockGui; import aztech.modern_industrialization.machines.helper.SteamHelper; import aztech.modern_industrialization.machines.multiblocks.HatchBlockEntity; -import aztech.modern_industrialization.machines.multiblocks.ShapeMatcher; import aztech.modern_industrialization.machines.multiblocks.ShapeTemplate; import aztech.modern_industrialization.machines.recipe.MachineRecipeType; import aztech.modern_industrialization.util.Simulation; @@ -68,7 +67,9 @@ protected CrafterComponent.Behavior getBehavior() { private boolean steelTier; @Override - protected void onSuccessfulMatch(ShapeMatcher shapeMatcher) { + protected void onMatchSuccessful() { + super.onMatchSuccessful(); + steelTier = false; for (HatchBlockEntity hatch : shapeMatcher.getMatchedHatches()) { diff --git a/src/main/java/aztech/modern_industrialization/machines/components/CasingComponent.java b/src/main/java/aztech/modern_industrialization/machines/components/CasingComponent.java index aaabf953e..be1ed0c49 100644 --- a/src/main/java/aztech/modern_industrialization/machines/components/CasingComponent.java +++ b/src/main/java/aztech/modern_industrialization/machines/components/CasingComponent.java @@ -24,6 +24,7 @@ package aztech.modern_industrialization.machines.components; import aztech.modern_industrialization.api.energy.CableTier; +import aztech.modern_industrialization.api.energy.CableTierHolder; import aztech.modern_industrialization.machines.IComponent; import aztech.modern_industrialization.machines.MachineBlockEntity; import aztech.modern_industrialization.machines.models.MachineCasing; @@ -42,15 +43,15 @@ import net.minecraft.world.level.block.Blocks; import org.jetbrains.annotations.Nullable; -public class CasingComponent implements IComponent, DropableComponent { +public class CasingComponent implements IComponent, DropableComponent, CableTierHolder { - private ItemStack casingStack = ItemStack.EMPTY; - private CableTier currentTier = CableTier.LV; + protected ItemStack casingStack = ItemStack.EMPTY; + protected CableTier currentTier = CableTier.LV; /** * Sets the current casing stack and update {@link #currentTier} accordingly. */ - private void setCasingStack(ItemStack stack) { + protected void setCasingStack(ItemStack stack) { casingStack = stack; // Compute tier @@ -109,7 +110,7 @@ public ItemInteractionResult onUse(MachineBlockEntity be, Player player, Interac return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; } - private void playCasingPlaceSound(MachineBlockEntity be) { + protected void playCasingPlaceSound(MachineBlockEntity be) { var blockKey = currentTier.itemKey; if (blockKey == null) { return; // no sound for LV @@ -141,6 +142,11 @@ public ItemStack getDrop() { return casingStack; } + @Override + public CableTier getCableTier() { + return currentTier; + } + public void setCasingServer(MachineBlockEntity be, ItemStack casing) { setCasingStack(casing); be.setChanged(); diff --git a/src/main/java/aztech/modern_industrialization/machines/components/OrientationComponent.java b/src/main/java/aztech/modern_industrialization/machines/components/OrientationComponent.java index a91b0241f..2e5229be6 100644 --- a/src/main/java/aztech/modern_industrialization/machines/components/OrientationComponent.java +++ b/src/main/java/aztech/modern_industrialization/machines/components/OrientationComponent.java @@ -89,7 +89,7 @@ public boolean useWrench(Player player, InteractionHand hand, Direction face) { return true; } } else { - if (face.getAxis().isHorizontal()) { + if (params.canBeVertical || face.getAxis().isHorizontal()) { facingDirection = face; } // We consume the event to prevent the GUI from opening. @@ -100,7 +100,7 @@ public boolean useWrench(Player player, InteractionHand hand, Direction face) { public void onPlaced(@Nullable LivingEntity placer, ItemStack itemStack) { // The placer can be null using some mods' automatic placement: pick NORTH arbitrarily. - Direction dir = placer != null ? placer.getDirection() : Direction.NORTH; + Direction dir = placer != null ? (params.canBeVertical ? placer.getNearestViewDirection() : placer.getDirection()) : Direction.NORTH; facingDirection = dir.getOpposite(); if (params.hasOutput) { outputDirection = dir; @@ -111,11 +111,17 @@ public static class Params { public final boolean hasOutput; public final boolean hasExtractItems; public final boolean hasExtractFluids; + public final boolean canBeVertical; - public Params(boolean hasOutput, boolean hasExtractItems, boolean hasExtractFluids) { + public Params(boolean hasOutput, boolean hasExtractItems, boolean hasExtractFluids, boolean canBeVertical) { this.hasOutput = hasOutput; this.hasExtractItems = hasExtractItems; this.hasExtractFluids = hasExtractFluids; + this.canBeVertical = canBeVertical; + } + + public Params(boolean hasOutput, boolean hasExtractItems, boolean hasExtractFluids) { + this(hasOutput, hasExtractItems, hasExtractFluids, false); } } diff --git a/src/main/java/aztech/modern_industrialization/machines/gui/MachineMenuCommon.java b/src/main/java/aztech/modern_industrialization/machines/gui/MachineMenuCommon.java index 591efa882..634aff0a6 100644 --- a/src/main/java/aztech/modern_industrialization/machines/gui/MachineMenuCommon.java +++ b/src/main/java/aztech/modern_industrialization/machines/gui/MachineMenuCommon.java @@ -29,7 +29,7 @@ import aztech.modern_industrialization.inventory.ConfigurableScreenHandler; import aztech.modern_industrialization.inventory.MIInventory; import aztech.modern_industrialization.inventory.SlotGroup; -import java.util.List; +import aztech.modern_industrialization.machines.ComponentStorage; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.inventory.Slot; @@ -38,7 +38,7 @@ public abstract class MachineMenuCommon extends ConfigurableScreenHandler implem public final MachineGuiParameters guiParams; MachineMenuCommon(int syncId, Inventory playerInventory, MIInventory inventory, MachineGuiParameters guiParams, - List guiComponents) { + ComponentStorage guiComponents) { super(MIRegistries.MACHINE_MENU.get(), syncId, playerInventory, inventory); this.guiParams = guiParams; @@ -53,9 +53,7 @@ public abstract class MachineMenuCommon extends ConfigurableScreenHandler implem } // Gui components first (we want to prioritize them with shift click) - for (var component : guiComponents) { - component.setupMenu(this); - } + guiComponents.forEach(component -> component.setupMenu(this)); // Configurable slots for (int i = 0; i < inventory.getItemStacks().size(); ++i) { diff --git a/src/main/java/aztech/modern_industrialization/machines/gui/MachineMenuServer.java b/src/main/java/aztech/modern_industrialization/machines/gui/MachineMenuServer.java index 44b635de6..4f700d1ce 100644 --- a/src/main/java/aztech/modern_industrialization/machines/gui/MachineMenuServer.java +++ b/src/main/java/aztech/modern_industrialization/machines/gui/MachineMenuServer.java @@ -39,19 +39,16 @@ public class MachineMenuServer extends MachineMenuCommon { protected final List trackedData; public MachineMenuServer(int syncId, Inventory playerInventory, MachineBlockEntity blockEntity, MachineGuiParameters guiParams) { - super(syncId, playerInventory, blockEntity.getInventory(), guiParams, blockEntity.guiComponents); + super(syncId, playerInventory, blockEntity.getInventory(), guiParams, blockEntity.getGuiComponents()); this.blockEntity = blockEntity; trackedData = new ArrayList<>(); - for (GuiComponent.Server component : blockEntity.guiComponents) { - trackedData.add(component.copyData()); - } + blockEntity.getGuiComponents().forEach(component -> trackedData.add(component.copyData())); } @Override public void broadcastChanges() { super.broadcastChanges(); - for (int i = 0; i < blockEntity.guiComponents.size(); ++i) { - GuiComponent.Server component = blockEntity.guiComponents.get(i); + blockEntity.getGuiComponents().forEachIndexed((i, component) -> { if (component.needsSync(trackedData.get(i))) { var buf = new RegistryFriendlyByteBuf(Unpooled.buffer(), blockEntity.getLevel().registryAccess()); component.writeCurrentData(buf); @@ -61,7 +58,7 @@ public void broadcastChanges() { trackedData.set(i, component.copyData()); buf.release(); } - } + }); } @Override diff --git a/src/main/java/aztech/modern_industrialization/machines/models/MachineCasing.java b/src/main/java/aztech/modern_industrialization/machines/models/MachineCasing.java index dd1fa9b5b..df6f8f259 100644 --- a/src/main/java/aztech/modern_industrialization/machines/models/MachineCasing.java +++ b/src/main/java/aztech/modern_industrialization/machines/models/MachineCasing.java @@ -23,10 +23,12 @@ */ package aztech.modern_industrialization.machines.models; +import net.minecraft.resources.ResourceLocation; + public class MachineCasing { - public final String name; + public final ResourceLocation key; - MachineCasing(String name) { - this.name = name; + MachineCasing(ResourceLocation key) { + this.key = key; } } diff --git a/src/main/java/aztech/modern_industrialization/machines/models/MachineCasings.java b/src/main/java/aztech/modern_industrialization/machines/models/MachineCasings.java index 53f961336..ae5c9a324 100644 --- a/src/main/java/aztech/modern_industrialization/machines/models/MachineCasings.java +++ b/src/main/java/aztech/modern_industrialization/machines/models/MachineCasings.java @@ -23,13 +23,15 @@ */ package aztech.modern_industrialization.machines.models; +import aztech.modern_industrialization.MI; import aztech.modern_industrialization.compat.kubejs.KubeJSProxy; import java.util.HashMap; import java.util.Map; +import net.minecraft.resources.ResourceLocation; public class MachineCasings { - public static final Map registeredCasings = new HashMap<>(); + public static final Map registeredCasings = new HashMap<>(); public static final MachineCasing BRICKED_BRONZE = create("bricked_bronze"); public static final MachineCasing BRICKED_STEEL = create("bricked_steel"); @@ -54,22 +56,30 @@ public class MachineCasings { KubeJSProxy.instance.fireRegisterMachineCasingsEvent(); } - public static MachineCasing create(String name) { - if (registeredCasings.containsKey(name)) { - throw new IllegalArgumentException("Duplicate machine casing definition: " + name); + public static MachineCasing create(ResourceLocation key) { + if (registeredCasings.containsKey(key)) { + throw new IllegalArgumentException("Duplicate machine casing definition: " + key); } - MachineCasing casing = new MachineCasing(name); - registeredCasings.put(name, casing); + MachineCasing casing = new MachineCasing(key); + registeredCasings.put(key, casing); return casing; } - public static MachineCasing get(String name) { - MachineCasing casing = registeredCasings.get(name); + public static MachineCasing create(String name) { + return create(MI.id(name)); + } + + public static MachineCasing get(ResourceLocation key) { + MachineCasing casing = registeredCasings.get(key); if (casing != null) { return casing; } else { - throw new IllegalArgumentException("Machine casing model \"" + name + "\" does not exist."); + throw new IllegalArgumentException("Machine casing model \"" + key + "\" does not exist."); } } + + public static MachineCasing get(String name) { + return get(ResourceLocation.isValidPath(name) ? MI.id(name) : ResourceLocation.parse(name)); + } } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/HatchBlockEntity.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/HatchBlockEntity.java index 43cbdbaff..8c81c74ad 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/HatchBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/HatchBlockEntity.java @@ -39,6 +39,7 @@ import java.util.Objects; import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.Nullable; @@ -51,19 +52,19 @@ public HatchBlockEntity(BEP bep, MachineGuiParameters guiParams, OrientationComp @Override public void writeClientNbt(CompoundTag tag, HolderLookup.Provider registries) { if (matchedCasing != null) { - tag.putString("matchedCasing", matchedCasing); + tag.putString("matchedCasing", matchedCasing.toString()); } } @Override public void readClientNbt(CompoundTag tag, HolderLookup.Provider registries) { - matchedCasing = tag.contains("matchedCasing") ? tag.getString("matchedCasing") : null; + matchedCasing = tag.contains("matchedCasing") ? ResourceLocation.tryParse(tag.getString("matchedCasing")) : null; } }); } - private String lastSyncedMachineCasing = null; - private String matchedCasing = null; + private ResourceLocation lastSyncedMachineCasing = null; + private ResourceLocation matchedCasing = null; public abstract HatchType getHatchType(); @@ -89,7 +90,7 @@ public void unlink() { } public void link(MachineCasing casing) { - matchedCasing = casing.name; + matchedCasing = casing.key; } protected void clearMachineLock() { diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBlockEntity.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBlockEntity.java index d68a51de4..d18ab0a2e 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBlockEntity.java @@ -33,6 +33,8 @@ import net.minecraft.world.phys.BlockHitResult; public abstract class MultiblockMachineBlockEntity extends MachineBlockEntity { + protected ShapeMatcher shapeMatcher; + public MultiblockMachineBlockEntity(BEP bep, MachineGuiParameters guiParams, OrientationComponent.Params orientationParams) { super(bep, guiParams, orientationParams); this.shapeValid = new ShapeValidComponent(); @@ -45,7 +47,61 @@ public boolean isShapeValid() { return shapeValid.shapeValid; } - public abstract void unlink(); + public ShapeMatcher getShapeMatcher() { + return shapeMatcher; + } + + public ShapeMatcher createShapeMatcher() { + return new ShapeMatcher(level, worldPosition, orientation.facingDirection, getActiveShape()); + } + + protected void onLink() { + } + + protected void onUnlink() { + } + + protected void onRematch() { + } + + protected void onMatchSuccessful() { + } + + protected void onMatchFailure() { + } + + protected void link() { + if (shapeMatcher == null) { + shapeMatcher = createShapeMatcher(); + shapeMatcher.registerListeners(level); + onLink(); + } + if (shapeMatcher.needsRematch()) { + shapeValid.shapeValid = false; + shapeMatcher.rematch(level); + onRematch(); + + if (shapeMatcher.isMatchSuccessful()) { + onMatchSuccessful(); + shapeValid.shapeValid = true; + } else { + onMatchFailure(); + } + + if (shapeValid.update()) { + sync(false); + } + } + } + + public void unlink() { + if (shapeMatcher != null) { + shapeMatcher.unlinkHatches(); + shapeMatcher.unregisterListeners(level); + onUnlink(); + shapeMatcher = null; + } + } @Override public boolean useWrench(Player player, InteractionHand hand, BlockHitResult hitResult) { @@ -59,7 +115,7 @@ public boolean useWrench(Player player, InteractionHand hand, BlockHitResult hit } @Override - public final void setRemoved() { + public void setRemoved() { super.setRemoved(); if (!level.isClientSide) { unlink(); diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java index f8c8eae8f..448b99cec 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java @@ -47,14 +47,14 @@ public ShapeMatcher(Level world, BlockPos controllerPos, Direction controllerDir this.hatchFlags = toWorldPos(controllerPos, controllerDirection, template.hatchFlags); } - private final BlockPos controllerPos; - private final ShapeTemplate template; - private final Map simpleMembers; - private final Map hatchFlags; + protected final BlockPos controllerPos; + protected final ShapeTemplate template; + protected final Map simpleMembers; + protected final Map hatchFlags; - private boolean needsRematch = true; - private boolean matchSuccessful = false; - private final List matchedHatches = new ArrayList<>(); + protected boolean needsRematch = true; + protected boolean matchSuccessful = false; + protected final List matchedHatches = new ArrayList<>(); /** * Convert a relative position in the shape template to the real position in the @@ -73,7 +73,7 @@ else if (controllerDirection == EAST) return rotatedPos.offset(controllerPos); } - private static Map toWorldPos(BlockPos controllerPos, Direction controllerDirection, Map templateMap) { + protected static Map toWorldPos(BlockPos controllerPos, Direction controllerDirection, Map templateMap) { Map result = new HashMap<>(); for (Map.Entry entry : templateMap.entrySet()) { result.put(toWorldPos(controllerPos, controllerDirection, entry.getKey()), entry.getValue()); diff --git a/src/main/java/aztech/modern_industrialization/network/machines/ChangeShapePacket.java b/src/main/java/aztech/modern_industrialization/network/machines/ChangeShapePacket.java index b92809545..84aacfeb2 100644 --- a/src/main/java/aztech/modern_industrialization/network/machines/ChangeShapePacket.java +++ b/src/main/java/aztech/modern_industrialization/network/machines/ChangeShapePacket.java @@ -50,7 +50,7 @@ public void handle(Context ctx) { AbstractContainerMenu menu = ctx.getPlayer().containerMenu; if (menu.containerId == syncId && menu instanceof MachineMenuServer machineMenu) { - ShapeSelection.Server shapeSelection = machineMenu.blockEntity.getComponent(GuiComponents.SHAPE_SELECTION); + ShapeSelection.Server shapeSelection = machineMenu.blockEntity.getGuiComponents().get(GuiComponents.SHAPE_SELECTION); shapeSelection.behavior.handleClick(shapeLine, clickedLeftButton ? -1 : +1); } } diff --git a/src/main/java/aztech/modern_industrialization/network/machines/ReiLockSlotsPacket.java b/src/main/java/aztech/modern_industrialization/network/machines/ReiLockSlotsPacket.java index 378aec6b6..9f0689be5 100644 --- a/src/main/java/aztech/modern_industrialization/network/machines/ReiLockSlotsPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/machines/ReiLockSlotsPacket.java @@ -48,7 +48,7 @@ public void handle(Context ctx) { AbstractContainerMenu sh = ctx.getPlayer().containerMenu; if (sh.containerId == containedId && sh instanceof MachineMenuServer screenHandler) { // Check that locking the slots is allowed in the first place - ReiSlotLocking.Server slotLocking = screenHandler.blockEntity.getComponent(GuiComponents.REI_SLOT_LOCKING); + ReiSlotLocking.Server slotLocking = screenHandler.blockEntity.getGuiComponents().get(GuiComponents.REI_SLOT_LOCKING); if (!slotLocking.allowLocking.get()) return; diff --git a/src/main/java/aztech/modern_industrialization/network/machines/SetAutoExtractPacket.java b/src/main/java/aztech/modern_industrialization/network/machines/SetAutoExtractPacket.java index 24ee14798..b8ef3181d 100644 --- a/src/main/java/aztech/modern_industrialization/network/machines/SetAutoExtractPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/machines/SetAutoExtractPacket.java @@ -50,7 +50,7 @@ public void handle(Context ctx) { if (ctx.getPlayer().containerMenu.containerId == syncId) { var screenHandler = (MachineMenuServer) ctx.getPlayer().containerMenu; - AutoExtract.Server autoExtract = screenHandler.blockEntity.getComponent(GuiComponents.AUTO_EXTRACT); + AutoExtract.Server autoExtract = screenHandler.blockEntity.getGuiComponents().get(GuiComponents.AUTO_EXTRACT); OrientationComponent orientation = autoExtract.getOrientation(); if (isItem) { orientation.extractItems = isExtract; From 7c90a8b9d1e3f243d64ba3a91f9f8ee0a5b1ed78 Mon Sep 17 00:00:00 2001 From: Swedz Date: Thu, 21 Nov 2024 16:31:40 -0500 Subject: [PATCH 02/89] Add structure-like support for multiblock shapes --- .../modern_industrialization/MIClient.java | 2 + .../StructureMultiblockControllerBER.java | 62 ++++ ...ructureMultiblockControllerEditScreen.java | 273 ++++++++++++++++++ .../StructureMultiblockHatchEditScreen.java | 192 ++++++++++++ .../StructureMultiblockMemberEditScreen.java | 180 ++++++++++++ .../proxy/ClientProxy.java | 27 ++ .../structure_multiblock_controller.json | 19 ++ .../structure_multiblock_hatch.json | 7 + .../structure_multiblock_member.json | 7 + .../modern_industrialization/lang/en_us.json | 8 + .../structure_multiblock_controller.json | 8 + .../block/structure_multiblock_hatch.json | 6 + .../block/structure_multiblock_member.json | 6 + .../item/structure_multiblock_controller.json | 3 + .../item/structure_multiblock_hatch.json | 3 + .../item/structure_multiblock_member.json | 3 + .../modern_industrialization/MIBlock.java | 40 +++ .../MIRegistries.java | 18 ++ .../modern_industrialization/MIText.java | 5 + .../StructureMultiblockControllerBlock.java | 80 +++++ ...uctureMultiblockControllerBlockEntity.java | 151 ++++++++++ .../StructureMultiblockHatchBlock.java | 66 +++++ .../StructureMultiblockHatchBlockEntity.java | 137 +++++++++ .../StructureMultiblockMemberBlock.java | 66 +++++ .../StructureMultiblockMemberBlockEntity.java | 159 ++++++++++ .../debug/DebugCommands.java | 11 + .../machines/multiblocks/HatchFlags.java | 8 +- .../machines/multiblocks/ShapeMatcher.java | 15 + .../machines/multiblocks/SimpleMember.java | 27 ++ .../network/MIPackets.java | 9 + .../StructureSaveControllerPacket.java | 67 +++++ .../StructureUpdateControllerPacket.java | 69 +++++ .../structure/StructureUpdateHatchPacket.java | 65 +++++ .../StructureUpdateMemberPacket.java | 64 ++++ .../proxy/CommonProxy.java | 12 + .../structure/MIStructureTemplateManager.java | 163 +++++++++++ .../structure_multiblock_controller_front.png | Bin 0 -> 366 bytes .../structure_multiblock_controller_side.png | Bin 0 -> 293 bytes .../block/structure_multiblock_hatch.png | Bin 0 -> 335 bytes .../block/structure_multiblock_member.png | Bin 0 -> 280 bytes 40 files changed, 2036 insertions(+), 2 deletions(-) create mode 100644 src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java create mode 100644 src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java create mode 100644 src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockHatchEditScreen.java create mode 100644 src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java create mode 100644 src/generated/resources/assets/modern_industrialization/blockstates/structure_multiblock_controller.json create mode 100644 src/generated/resources/assets/modern_industrialization/blockstates/structure_multiblock_hatch.json create mode 100644 src/generated/resources/assets/modern_industrialization/blockstates/structure_multiblock_member.json create mode 100644 src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_controller.json create mode 100644 src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_hatch.json create mode 100644 src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_member.json create mode 100644 src/generated/resources/assets/modern_industrialization/models/item/structure_multiblock_controller.json create mode 100644 src/generated/resources/assets/modern_industrialization/models/item/structure_multiblock_hatch.json create mode 100644 src/generated/resources/assets/modern_industrialization/models/item/structure_multiblock_member.json create mode 100644 src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlock.java create mode 100644 src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java create mode 100644 src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlock.java create mode 100644 src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlockEntity.java create mode 100644 src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlock.java create mode 100644 src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java create mode 100644 src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java create mode 100644 src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java create mode 100644 src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateHatchPacket.java create mode 100644 src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java create mode 100644 src/main/java/aztech/modern_industrialization/structure/MIStructureTemplateManager.java create mode 100644 src/main/resources/assets/modern_industrialization/textures/block/structure_multiblock_controller_front.png create mode 100644 src/main/resources/assets/modern_industrialization/textures/block/structure_multiblock_controller_side.png create mode 100644 src/main/resources/assets/modern_industrialization/textures/block/structure_multiblock_hatch.png create mode 100644 src/main/resources/assets/modern_industrialization/textures/block/structure_multiblock_member.png diff --git a/src/client/java/aztech/modern_industrialization/MIClient.java b/src/client/java/aztech/modern_industrialization/MIClient.java index a8d422d97..f46da1c2f 100644 --- a/src/client/java/aztech/modern_industrialization/MIClient.java +++ b/src/client/java/aztech/modern_industrialization/MIClient.java @@ -29,6 +29,7 @@ import aztech.modern_industrialization.blocks.storage.barrel.DeferredBarrelTextRenderer; import aztech.modern_industrialization.blocks.storage.barrel.client.BarrelTooltipComponent; import aztech.modern_industrialization.blocks.storage.tank.TankRenderer; +import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBER; import aztech.modern_industrialization.datagen.MIDatagenClient; import aztech.modern_industrialization.datagen.MIDatagenServer; import aztech.modern_industrialization.datagen.model.DelegatingModelBuilder; @@ -234,6 +235,7 @@ private static void registerBlockEntityRenderers(FMLClientSetupEvent event) { BlockEntityRenderers.register(MIRegistries.CREATIVE_BARREL_BE.get(), context -> new BarrelRenderer(0x000000)); BlockEntityRenderers.register(MIRegistries.CREATIVE_TANK_BE.get(), context -> new TankRenderer(0x000000)); + BlockEntityRenderers.register(MIRegistries.STRUCTURE_MULTIBLOCK_CONTROLLER_BE.get(), context -> new StructureMultiblockControllerBER()); blockEntityRendererRegistrations.forEach(Runnable::run); } diff --git a/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java b/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java new file mode 100644 index 000000000..bcf2106b2 --- /dev/null +++ b/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java @@ -0,0 +1,62 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.blocks.structure; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.renderer.LevelRenderer; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.levelgen.structure.BoundingBox; +import net.minecraft.world.phys.AABB; + +public class StructureMultiblockControllerBER implements BlockEntityRenderer { + @Override + public void render(StructureMultiblockControllerBlockEntity controller, float tickDelta, PoseStack matrices, MultiBufferSource vcs, int light, + int overlay) { + BlockPos pos = controller.getBlockPos(); + BoundingBox bounds = controller.getBounds(); + if (bounds == null) { + bounds = new BoundingBox(0, 0, 0, 0, 0, 0); + } + matrices.pushPose(); + VertexConsumer buffer = vcs.getBuffer(RenderType.lines()); + AABB box = AABB.of(bounds); + // MI.LOGGER.info("box: {}", box); + LevelRenderer.renderLineBox(matrices, buffer, box, 1, 1, 1, 1); + matrices.popPose(); + } + + @Override + public boolean shouldRenderOffScreen(StructureMultiblockControllerBlockEntity controller) { + return true; + } + + @Override + public AABB getRenderBoundingBox(StructureMultiblockControllerBlockEntity controller) { + return AABB.INFINITE; + } +} diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java new file mode 100644 index 000000000..59ee6065a --- /dev/null +++ b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java @@ -0,0 +1,273 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.gui.structure; + +import aztech.modern_industrialization.MIBlock; +import aztech.modern_industrialization.MIText; +import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlockEntity; +import aztech.modern_industrialization.machines.models.MachineCasing; +import aztech.modern_industrialization.network.structure.StructureSaveControllerPacket; +import aztech.modern_industrialization.network.structure.StructureUpdateControllerPacket; +import com.mojang.blaze3d.platform.InputConstants; +import java.util.Optional; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.CommonComponents; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.levelgen.structure.BoundingBox; + +public class StructureMultiblockControllerEditScreen extends Screen { + private static final int VALID_TEXT_COLOR = 0xE0E0E0; + private static final int INVALID_TEXT_COLOR = 0xE07272; + + private final StructureMultiblockControllerBlockEntity controller; + + private Button doneButton; + private Button cancelButton; + private Button saveButton; + + private EditBox idBox; + private EditBox casingBox; + + private EditBox posX; + private EditBox posY; + private EditBox posZ; + private EditBox sizeX; + private EditBox sizeY; + private EditBox sizeZ; + + public StructureMultiblockControllerEditScreen(StructureMultiblockControllerBlockEntity controller) { + super(Component.translatable(MIBlock.STRUCTURE_MULTIBLOCK_CONTROLLER.asBlock().getDescriptionId())); + this.controller = controller; + } + + private Optional getId() { + return Optional.ofNullable(ResourceLocation.tryParse(idBox.getValue())); + } + + private Optional getCasing() { + return Optional.ofNullable(StructureMultiblockControllerBlockEntity.formatCasing(casingBox.getValue())); + } + + // TODO this needs to be reworked to allow for negative sizes and whatnot + private Optional getBoundingBox() { + try { + int minX = Integer.parseInt(posX.getValue()); + int minY = Integer.parseInt(posY.getValue()); + int minZ = Integer.parseInt(posZ.getValue()); + BlockPos min = new BlockPos(minX, minY, minZ); + int maxX = Integer.parseInt(sizeX.getValue()) + minX - 1; + int maxY = Integer.parseInt(sizeY.getValue()) + minY - 1; + int maxZ = Integer.parseInt(sizeZ.getValue()) + minZ - 1; + BlockPos max = new BlockPos(maxX, maxY, maxZ); + return Optional.of(BoundingBox.fromCorners(min, max)); + } catch (NumberFormatException ignored) { + return Optional.empty(); + } + } + + private void updateId() { + boolean validId = idBox.getValue().isEmpty() || this.getId().isPresent(); + idBox.setTextColor(validId ? VALID_TEXT_COLOR : INVALID_TEXT_COLOR); + } + + private void updateCasing() { + boolean validCasing = casingBox.getValue().isEmpty() || this.getCasing().isPresent(); + casingBox.setTextColor(validCasing ? VALID_TEXT_COLOR : INVALID_TEXT_COLOR); + } + + private void updateAll() { + this.updateId(); + this.updateCasing(); + } + + private void done() { + this.sendToServer(); + minecraft.setScreen(null); + } + + private void sendToServer() { + minecraft.getConnection().send(new StructureUpdateControllerPacket( + controller.getBlockPos(), + idBox.getValue(), + casingBox.getValue(), + this.getBoundingBox().orElse(new BoundingBox(0, 0, 0, 0, 0, 0)))); + } + + private void cancel() { + minecraft.setScreen(null); + } + + private void save() { + this.sendToServer(); + minecraft.getConnection().send(new StructureSaveControllerPacket(controller.getBlockPos())); + } + + @Override + protected void init() { + this.addRenderableWidget( + doneButton = Button.builder(CommonComponents.GUI_DONE, button -> this.done()).bounds(width / 2 - 4 - 150, 210, 150, 20).build()); + this.addRenderableWidget( + cancelButton = Button.builder(CommonComponents.GUI_CANCEL, button -> this.cancel()).bounds(width / 2 + 4, 210, 150, 20).build()); + this.addRenderableWidget( + saveButton = Button.builder(Component.translatable("structure_block.button.save"), button -> this.save()) + .bounds(width / 2 + 4 + 100, 185, 50, 20).build()); + + idBox = new EditBox(font, width / 2 - 152, 50, 304, 20, MIText.StructureMultiblockStructureName.text()) { + @Override + public boolean charTyped(char codePoint, int modifiers) { + return ResourceLocation.isAllowedInResourceLocation(codePoint) && super.charTyped(codePoint, modifiers); + } + }; + idBox.setMaxLength(Short.MAX_VALUE); + idBox.setValue(controller.getInputId()); + idBox.setResponder(text -> this.updateId()); + this.addRenderableWidget(idBox); + + casingBox = new EditBox(font, width / 2 - 152, 90, 304, 20, MIText.StructureMultiblockHatchCasing.text()) { + @Override + public boolean charTyped(char codePoint, int modifiers) { + return ResourceLocation.isAllowedInResourceLocation(codePoint) && super.charTyped(codePoint, modifiers); + } + }; + casingBox.setMaxLength(Short.MAX_VALUE); + casingBox.setValue(controller.getInputCasing()); + casingBox.setResponder(text -> this.updateCasing()); + this.addRenderableWidget(casingBox); + + BoundingBox bounds = controller.getBounds(); + if (bounds == null) { + bounds = new BoundingBox(0, 0, 0, 0, 0, 0); + } + + posX = new EditBox(font, width / 2 - 152, 130, 80, 20, Component.translatable("structure_block.position.x")); + posX.setMaxLength(15); + posX.setValue(Integer.toString(bounds.minX())); + this.addRenderableWidget(posX); + posY = new EditBox(font, width / 2 - 72, 130, 80, 20, Component.translatable("structure_block.position.y")); + posY.setMaxLength(15); + posY.setValue(Integer.toString(bounds.minY())); + this.addRenderableWidget(posY); + posZ = new EditBox(font, width / 2 + 8, 130, 80, 20, Component.translatable("structure_block.position.z")); + posZ.setMaxLength(15); + posZ.setValue(Integer.toString(bounds.minZ())); + this.addRenderableWidget(posZ); + + sizeX = new EditBox(font, width / 2 - 152, 170, 80, 20, Component.translatable("structure_block.size.x")); + sizeX.setMaxLength(15); + sizeX.setValue(Integer.toString(bounds.maxX() - bounds.minX() + 1)); + this.addRenderableWidget(sizeX); + sizeY = new EditBox(font, width / 2 - 72, 170, 80, 20, Component.translatable("structure_block.size.y")); + sizeY.setMaxLength(15); + sizeY.setValue(Integer.toString(bounds.maxY() - bounds.minY() + 1)); + this.addRenderableWidget(sizeY); + sizeZ = new EditBox(font, width / 2 + 8, 170, 80, 20, Component.translatable("structure_block.size.z")); + sizeZ.setMaxLength(15); + sizeZ.setValue(Integer.toString(bounds.maxZ() - bounds.minZ() + 1)); + this.addRenderableWidget(sizeZ); + + this.updateAll(); + } + + @Override + public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) { + super.render(graphics, mouseX, mouseY, partialTick); + + graphics.drawCenteredString(font, title, width / 2, 20, 0xFFFFFF); + + graphics.drawString(font, MIText.StructureMultiblockStructureName.text(), width / 2 - 153, 40, 0xA0A0A0); + + graphics.drawString(font, MIText.StructureMultiblockHatchCasing.text(), width / 2 - 153, 80, 0xA0A0A0); + + graphics.drawString(font, Component.translatable("structure_block.position"), width / 2 - 153, 120, 0xA0A0A0); + + graphics.drawString(font, Component.translatable("structure_block.size"), width / 2 - 153, 160, 0xA0A0A0); + } + + @Override + public void renderBackground(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) { + this.renderTransparentBackground(guiGraphics); + } + + @Override + protected void setInitialFocus() { + this.setInitialFocus(idBox); + } + + @Override + public void resize(Minecraft minecraft, int width, int height) { + String idBoxValue = idBox.getValue(); + String casingBoxValue = casingBox.getValue(); + String posXValue = posX.getValue(); + String posYValue = posY.getValue(); + String posZValue = posZ.getValue(); + String sizeXValue = sizeX.getValue(); + String sizeYValue = sizeY.getValue(); + String sizeZValue = sizeZ.getValue(); + + this.init(minecraft, width, height); + + idBox.setValue(idBoxValue); + casingBox.setValue(casingBoxValue); + posX.setValue(posXValue); + posY.setValue(posYValue); + posZ.setValue(posZValue); + sizeX.setValue(sizeXValue); + sizeY.setValue(sizeYValue); + sizeZ.setValue(sizeZValue); + } + + @Override + public void onClose() { + this.cancel(); + } + + @Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + if (super.keyPressed(keyCode, scanCode, modifiers)) { + return true; + } else if (keyCode == InputConstants.KEY_RETURN || keyCode == InputConstants.KEY_NUMPADENTER) { + this.done(); + return true; + } + return false; + } + + @Override + public boolean isPauseScreen() { + return false; + } + + @Override + public void tick() { + if (controller.isRemoved()) { + this.onClose(); + } + } +} diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockHatchEditScreen.java b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockHatchEditScreen.java new file mode 100644 index 000000000..92f4c1b02 --- /dev/null +++ b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockHatchEditScreen.java @@ -0,0 +1,192 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.gui.structure; + +import aztech.modern_industrialization.MIBlock; +import aztech.modern_industrialization.MIText; +import aztech.modern_industrialization.blocks.structure.StructureMultiblockHatchBlockEntity; +import aztech.modern_industrialization.machines.models.MachineCasing; +import aztech.modern_industrialization.machines.multiblocks.HatchFlags; +import aztech.modern_industrialization.network.structure.StructureUpdateHatchPacket; +import com.mojang.blaze3d.platform.InputConstants; +import java.util.Optional; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.CommonComponents; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; + +public class StructureMultiblockHatchEditScreen extends Screen { + private static final int VALID_TEXT_COLOR = 0xE0E0E0; + private static final int INVALID_TEXT_COLOR = 0xE07272; + + private final StructureMultiblockHatchBlockEntity hatch; + + private Button doneButton; + private Button cancelButton; + + private EditBox casingBox; + + private EditBox flagsBox; + + public StructureMultiblockHatchEditScreen(StructureMultiblockHatchBlockEntity hatch) { + super(Component.translatable(MIBlock.STRUCTURE_MULTIBLOCK_HATCH.asBlock().getDescriptionId())); + this.hatch = hatch; + } + + private Optional getCasing() { + return Optional.ofNullable(StructureMultiblockHatchBlockEntity.formatCasing(casingBox.getValue())); + } + + private Optional getHatchFlags() { + return Optional.ofNullable(StructureMultiblockHatchBlockEntity.formatFlags(flagsBox.getValue())); + } + + private void updateCasing() { + boolean validCasing = casingBox.getValue().isEmpty() || this.getCasing().isPresent(); + casingBox.setTextColor(validCasing ? VALID_TEXT_COLOR : INVALID_TEXT_COLOR); + } + + private void updateFlags() { + boolean validFlags = flagsBox.getValue().isEmpty() || this.getHatchFlags().isPresent(); + flagsBox.setTextColor(validFlags ? VALID_TEXT_COLOR : INVALID_TEXT_COLOR); + } + + private void updateAll() { + this.updateCasing(); + this.updateFlags(); + } + + private void done() { + this.sendToServer(); + minecraft.setScreen(null); + } + + private void sendToServer() { + minecraft.getConnection().send(new StructureUpdateHatchPacket( + hatch.getBlockPos(), + casingBox.getValue(), + flagsBox.getValue())); + } + + private void cancel() { + minecraft.setScreen(null); + } + + @Override + protected void init() { + this.addRenderableWidget( + doneButton = Button.builder(CommonComponents.GUI_DONE, button -> this.done()).bounds(width / 2 - 4 - 150, 210, 150, 20).build()); + this.addRenderableWidget( + cancelButton = Button.builder(CommonComponents.GUI_CANCEL, button -> this.cancel()).bounds(width / 2 + 4, 210, 150, 20).build()); + + casingBox = new EditBox(font, width / 2 - 152, 50, 304, 20, MIText.StructureMultiblockHatchCasing.text()) { + @Override + public boolean charTyped(char codePoint, int modifiers) { + return ResourceLocation.isAllowedInResourceLocation(codePoint) && super.charTyped(codePoint, modifiers); + } + }; + casingBox.setMaxLength(Short.MAX_VALUE); + casingBox.setValue(hatch.getInputCasing()); + casingBox.setResponder(text -> this.updateCasing()); + this.addRenderableWidget(casingBox); + + flagsBox = new EditBox(font, width / 2 - 152, 90, 304, 20, MIText.StructureMultiblockHatchFlags.text()) { + @Override + public boolean charTyped(char codePoint, int modifiers) { + return (Character.isDigit(codePoint) || Character.isAlphabetic(codePoint) || codePoint == ';' || codePoint == '_') + && super.charTyped(codePoint, modifiers); + } + }; + flagsBox.setMaxLength(Short.MAX_VALUE); + flagsBox.setValue(hatch.getInputFlags()); + flagsBox.setResponder(text -> this.updateFlags()); + this.addRenderableWidget(flagsBox); + + this.updateAll(); + } + + @Override + public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) { + super.render(graphics, mouseX, mouseY, partialTick); + + graphics.drawCenteredString(font, title, width / 2, 20, 0xFFFFFF); + + graphics.drawString(font, MIText.StructureMultiblockHatchCasing.text(), width / 2 - 153, 40, 0xA0A0A0); + + graphics.drawString(font, MIText.StructureMultiblockHatchFlags.text(), width / 2 - 153, 80, 0xA0A0A0); + } + + @Override + public void renderBackground(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) { + this.renderTransparentBackground(guiGraphics); + } + + @Override + protected void setInitialFocus() { + this.setInitialFocus(casingBox); + } + + @Override + public void resize(Minecraft minecraft, int width, int height) { + String casingBoxValue = casingBox.getValue(); + String flagsBoxValue = flagsBox.getValue(); + + this.init(minecraft, width, height); + + casingBox.setValue(casingBoxValue); + flagsBox.setValue(flagsBoxValue); + } + + @Override + public void onClose() { + this.cancel(); + } + + @Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + if (super.keyPressed(keyCode, scanCode, modifiers)) { + return true; + } else if (keyCode == InputConstants.KEY_RETURN || keyCode == InputConstants.KEY_NUMPADENTER) { + this.done(); + return true; + } + return false; + } + + @Override + public boolean isPauseScreen() { + return false; + } + + @Override + public void tick() { + if (hatch.isRemoved()) { + this.onClose(); + } + } +} diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java new file mode 100644 index 000000000..9237b1df8 --- /dev/null +++ b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java @@ -0,0 +1,180 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.gui.structure; + +import aztech.modern_industrialization.MIBlock; +import aztech.modern_industrialization.MIText; +import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlockEntity; +import aztech.modern_industrialization.network.structure.StructureUpdateMemberPacket; +import com.mojang.blaze3d.platform.InputConstants; +import java.util.List; +import java.util.Optional; +import java.util.function.Predicate; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.CommonComponents; +import net.minecraft.network.chat.Component; +import net.minecraft.world.level.block.state.BlockState; + +public class StructureMultiblockMemberEditScreen extends Screen { + private static final int VALID_TEXT_COLOR = 0xE0E0E0; + private static final int INVALID_TEXT_COLOR = 0xE07272; + + private final StructureMultiblockMemberBlockEntity member; + + private Button doneButton; + private Button cancelButton; + + private EditBox previewBox; + private EditBox membersBox; + + public StructureMultiblockMemberEditScreen(StructureMultiblockMemberBlockEntity member) { + super(Component.translatable(MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.asBlock().getDescriptionId())); + this.member = member; + } + + private Optional getPreview() { + return Optional.ofNullable(StructureMultiblockMemberBlockEntity.formatPreview(previewBox.getValue())); + } + + private Optional>> getMembers() { + return Optional.ofNullable(StructureMultiblockMemberBlockEntity.formatMembers(membersBox.getValue())); + } + + private void updatePreview() { + boolean validPreview = previewBox.getValue().isEmpty() || this.getPreview().isPresent(); + previewBox.setTextColor(validPreview ? VALID_TEXT_COLOR : INVALID_TEXT_COLOR); + } + + private void updateMembers() { + boolean validMembers = membersBox.getValue().isEmpty() || this.getMembers().isPresent(); + membersBox.setTextColor(validMembers ? VALID_TEXT_COLOR : INVALID_TEXT_COLOR); + } + + private void updateAll() { + this.updatePreview(); + this.updateMembers(); + } + + private void done() { + this.sendToServer(); + minecraft.setScreen(null); + } + + private void sendToServer() { + minecraft.getConnection().send(new StructureUpdateMemberPacket( + member.getBlockPos(), + previewBox.getValue(), + membersBox.getValue())); + } + + private void cancel() { + minecraft.setScreen(null); + } + + @Override + protected void init() { + this.addRenderableWidget( + doneButton = Button.builder(CommonComponents.GUI_DONE, button -> this.done()).bounds(width / 2 - 4 - 150, 210, 150, 20).build()); + this.addRenderableWidget( + cancelButton = Button.builder(CommonComponents.GUI_CANCEL, button -> this.cancel()).bounds(width / 2 + 4, 210, 150, 20).build()); + + previewBox = new EditBox(font, width / 2 - 152, 50, 304, 20, MIText.StructureMultiblockMemberPreview.text()); + previewBox.setMaxLength(Short.MAX_VALUE); + previewBox.setValue(member.getInputPreview()); + previewBox.setResponder(text -> this.updatePreview()); + this.addRenderableWidget(previewBox); + + membersBox = new EditBox(font, width / 2 - 152, 90, 304, 20, MIText.StructureMultiblockMemberMembers.text()); + membersBox.setMaxLength(Short.MAX_VALUE); + membersBox.setValue(member.getInputMembers()); + membersBox.setResponder(text -> this.updateMembers()); + this.addRenderableWidget(membersBox); + + this.updateAll(); + } + + @Override + public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) { + super.render(graphics, mouseX, mouseY, partialTick); + + graphics.drawCenteredString(font, title, width / 2, 20, 0xFFFFFF); + + graphics.drawString(font, MIText.StructureMultiblockMemberPreview.text(), width / 2 - 153, 40, 0xA0A0A0); + + graphics.drawString(font, MIText.StructureMultiblockMemberMembers.text(), width / 2 - 153, 80, 0xA0A0A0); + } + + @Override + public void renderBackground(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) { + this.renderTransparentBackground(guiGraphics); + } + + @Override + protected void setInitialFocus() { + this.setInitialFocus(previewBox); + } + + @Override + public void resize(Minecraft minecraft, int width, int height) { + String previewBoxValue = previewBox.getValue(); + String membersBoxValue = membersBox.getValue(); + + this.init(minecraft, width, height); + + previewBox.setValue(previewBoxValue); + membersBox.setValue(membersBoxValue); + } + + @Override + public void onClose() { + this.cancel(); + } + + @Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + if (super.keyPressed(keyCode, scanCode, modifiers)) { + return true; + } else if (keyCode == InputConstants.KEY_RETURN || keyCode == InputConstants.KEY_NUMPADENTER) { + this.done(); + return true; + } + return false; + } + + @Override + public boolean isPauseScreen() { + return false; + } + + @Override + public void tick() { + if (member.isRemoved()) { + this.onClose(); + } + } +} diff --git a/src/client/java/aztech/modern_industrialization/proxy/ClientProxy.java b/src/client/java/aztech/modern_industrialization/proxy/ClientProxy.java index d8ef3c28e..87b4c7ec7 100644 --- a/src/client/java/aztech/modern_industrialization/proxy/ClientProxy.java +++ b/src/client/java/aztech/modern_industrialization/proxy/ClientProxy.java @@ -29,6 +29,12 @@ import aztech.modern_industrialization.blocks.storage.barrel.BarrelRenderer; import aztech.modern_industrialization.blocks.storage.tank.AbstractTankBlockEntity; import aztech.modern_industrialization.blocks.storage.tank.TankRenderer; +import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlockEntity; +import aztech.modern_industrialization.blocks.structure.StructureMultiblockHatchBlockEntity; +import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlockEntity; +import aztech.modern_industrialization.gui.structure.StructureMultiblockControllerEditScreen; +import aztech.modern_industrialization.gui.structure.StructureMultiblockHatchEditScreen; +import aztech.modern_industrialization.gui.structure.StructureMultiblockMemberEditScreen; import aztech.modern_industrialization.items.SteamDrillHooks; import aztech.modern_industrialization.machines.gui.MachineMenuClient; import aztech.modern_industrialization.machines.gui.MachineMenuCommon; @@ -152,4 +158,25 @@ public BlockState getMachineCasingBlockState(BlockState state, BlockAndTintGette // Couldn't find target state return state; } + + @Override + public void openStructureMultiblockControllerScreen(Player player, StructureMultiblockControllerBlockEntity controller) { + if (player.getCommandSenderWorld().isClientSide()) { + Minecraft.getInstance().setScreen(new StructureMultiblockControllerEditScreen(controller)); + } + } + + @Override + public void openStructureMultiblockHatchScreen(Player player, StructureMultiblockHatchBlockEntity hatch) { + if (player.getCommandSenderWorld().isClientSide()) { + Minecraft.getInstance().setScreen(new StructureMultiblockHatchEditScreen(hatch)); + } + } + + @Override + public void openStructureMultiblockMemberScreen(Player player, StructureMultiblockMemberBlockEntity member) { + if (player.getCommandSenderWorld().isClientSide()) { + Minecraft.getInstance().setScreen(new StructureMultiblockMemberEditScreen(member)); + } + } } diff --git a/src/generated/resources/assets/modern_industrialization/blockstates/structure_multiblock_controller.json b/src/generated/resources/assets/modern_industrialization/blockstates/structure_multiblock_controller.json new file mode 100644 index 000000000..3e7f146fc --- /dev/null +++ b/src/generated/resources/assets/modern_industrialization/blockstates/structure_multiblock_controller.json @@ -0,0 +1,19 @@ +{ + "variants": { + "facing=east": { + "model": "modern_industrialization:block/structure_multiblock_controller", + "y": 90 + }, + "facing=north": { + "model": "modern_industrialization:block/structure_multiblock_controller" + }, + "facing=south": { + "model": "modern_industrialization:block/structure_multiblock_controller", + "y": 180 + }, + "facing=west": { + "model": "modern_industrialization:block/structure_multiblock_controller", + "y": 270 + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/modern_industrialization/blockstates/structure_multiblock_hatch.json b/src/generated/resources/assets/modern_industrialization/blockstates/structure_multiblock_hatch.json new file mode 100644 index 000000000..7c9f6f6b6 --- /dev/null +++ b/src/generated/resources/assets/modern_industrialization/blockstates/structure_multiblock_hatch.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "modern_industrialization:block/structure_multiblock_hatch" + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/modern_industrialization/blockstates/structure_multiblock_member.json b/src/generated/resources/assets/modern_industrialization/blockstates/structure_multiblock_member.json new file mode 100644 index 000000000..db1dc2380 --- /dev/null +++ b/src/generated/resources/assets/modern_industrialization/blockstates/structure_multiblock_member.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "modern_industrialization:block/structure_multiblock_member" + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/modern_industrialization/lang/en_us.json b/src/generated/resources/assets/modern_industrialization/lang/en_us.json index 69142dc08..2962ca8b3 100644 --- a/src/generated/resources/assets/modern_industrialization/lang/en_us.json +++ b/src/generated/resources/assets/modern_industrialization/lang/en_us.json @@ -404,6 +404,9 @@ "block.modern_industrialization.steel_unpacker": "Steel Unpacker", "block.modern_industrialization.steel_water_pump": "Steel Water Pump", "block.modern_industrialization.steel_wiremill": "Steel Wiremill", + "block.modern_industrialization.structure_multiblock_controller": "Structure Multiblock Controller", + "block.modern_industrialization.structure_multiblock_hatch": "Structure Multiblock Hatch", + "block.modern_industrialization.structure_multiblock_member": "Structure Multiblock Member", "block.modern_industrialization.styrene": "Styrene", "block.modern_industrialization.styrene_butadiene": "Styrene-Butadiene", "block.modern_industrialization.styrene_butadiene_rubber": "Styrene-Butadiene Rubber", @@ -1691,6 +1694,11 @@ "text.modern_industrialization.SteamDrillProfit": "- Press %s to toggle 3x3 mining.", "text.modern_industrialization.SteamDrillToggle": "- Toggle Silk Touch with %s + %s.", "text.modern_industrialization.SteamDrillWaterHelp": "- Press %s on still or flowing water to fill.", + "text.modern_industrialization.StructureMultiblockHatchCasing": "Machine Casing", + "text.modern_industrialization.StructureMultiblockHatchFlags": "Hatch Flags", + "text.modern_industrialization.StructureMultiblockMemberMembers": "Members", + "text.modern_industrialization.StructureMultiblockMemberPreview": "Preview", + "text.modern_industrialization.StructureMultiblockStructureName": "Structure Name", "text.modern_industrialization.SuperconductorPowerOnly": "Can only connect to Superconductor cables and machines. Must be directly connected to a machine on at least one end of the tunnel.", "text.modern_industrialization.Temperature": "Temperature: %d °C", "text.modern_industrialization.TemperatureMode": "Temperature", diff --git a/src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_controller.json b/src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_controller.json new file mode 100644 index 000000000..2a22e1d49 --- /dev/null +++ b/src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_controller.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/orientable", + "textures": { + "front": "modern_industrialization:block/structure_multiblock_controller_front", + "side": "modern_industrialization:block/structure_multiblock_controller_side", + "top": "modern_industrialization:block/structure_multiblock_controller_side" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_hatch.json b/src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_hatch.json new file mode 100644 index 000000000..e7f08db80 --- /dev/null +++ b/src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_hatch.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "modern_industrialization:block/structure_multiblock_hatch" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_member.json b/src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_member.json new file mode 100644 index 000000000..74c3302dd --- /dev/null +++ b/src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_member.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "modern_industrialization:block/structure_multiblock_member" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/modern_industrialization/models/item/structure_multiblock_controller.json b/src/generated/resources/assets/modern_industrialization/models/item/structure_multiblock_controller.json new file mode 100644 index 000000000..8c93d21c0 --- /dev/null +++ b/src/generated/resources/assets/modern_industrialization/models/item/structure_multiblock_controller.json @@ -0,0 +1,3 @@ +{ + "parent": "modern_industrialization:block/structure_multiblock_controller" +} \ No newline at end of file diff --git a/src/generated/resources/assets/modern_industrialization/models/item/structure_multiblock_hatch.json b/src/generated/resources/assets/modern_industrialization/models/item/structure_multiblock_hatch.json new file mode 100644 index 000000000..7350f04c5 --- /dev/null +++ b/src/generated/resources/assets/modern_industrialization/models/item/structure_multiblock_hatch.json @@ -0,0 +1,3 @@ +{ + "parent": "modern_industrialization:block/structure_multiblock_hatch" +} \ No newline at end of file diff --git a/src/generated/resources/assets/modern_industrialization/models/item/structure_multiblock_member.json b/src/generated/resources/assets/modern_industrialization/models/item/structure_multiblock_member.json new file mode 100644 index 000000000..00613b81b --- /dev/null +++ b/src/generated/resources/assets/modern_industrialization/models/item/structure_multiblock_member.json @@ -0,0 +1,3 @@ +{ + "parent": "modern_industrialization:block/structure_multiblock_member" +} \ No newline at end of file diff --git a/src/main/java/aztech/modern_industrialization/MIBlock.java b/src/main/java/aztech/modern_industrialization/MIBlock.java index d805d2d44..35cffa635 100644 --- a/src/main/java/aztech/modern_industrialization/MIBlock.java +++ b/src/main/java/aztech/modern_industrialization/MIBlock.java @@ -35,6 +35,9 @@ import aztech.modern_industrialization.blocks.storage.tank.TankBlock; import aztech.modern_industrialization.blocks.storage.tank.TankItem; import aztech.modern_industrialization.blocks.storage.tank.creativetank.CreativeTankBlockEntity; +import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlock; +import aztech.modern_industrialization.blocks.structure.StructureMultiblockHatchBlock; +import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlock; import aztech.modern_industrialization.datagen.loot.MIBlockLoot; import aztech.modern_industrialization.datagen.model.BaseModelProvider; import aztech.modern_industrialization.definition.BlockDefinition; @@ -54,6 +57,7 @@ import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemDisplayContext; +import net.minecraft.world.item.Rarity; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.SoundType; import net.minecraft.world.level.block.state.BlockBehaviour; @@ -129,6 +133,42 @@ public static void init(IEventBus modBus) { public static final BlockDefinition CREATIVE_STORAGE_UNIT = block("Creative Storage Unit", "creative_storage_unit", BlockDefinitionParams.defaultStone().withBlockConstructor(CreativeStorageUnitBlock::new)); + + // TODO make these blocks not show up in the creative tab and dont give them mineable tags + public static final BlockDefinition STRUCTURE_MULTIBLOCK_CONTROLLER = block("Structure Multiblock Controller", + "structure_multiblock_controller", BlockDefinitionParams.defaultStone() + .withBlockConstructor(StructureMultiblockControllerBlock::new) + .withBlockItemConstructor((block, p) -> new BlockItem(block, p.rarity(Rarity.EPIC))) + .withModel((block, gen) -> { + String name = gen.name(block); + var model = gen.models().orientable(name, + gen.blockTexture("structure_multiblock_controller_side"), + gen.blockTexture("structure_multiblock_controller_front"), + gen.blockTexture("structure_multiblock_controller_side")); + gen.horizontalBlock(block, model); + gen.simpleBlockItem(block, model); + }) + .noLootTable()); + + public static final BlockDefinition STRUCTURE_MULTIBLOCK_HATCH = block("Structure Multiblock Hatch", + "structure_multiblock_hatch", BlockDefinitionParams.defaultStone() + .withBlockConstructor(StructureMultiblockHatchBlock::new) + .withBlockItemConstructor((block, p) -> new BlockItem(block, p.rarity(Rarity.EPIC))) + .withModel((block, gen) -> { + String name = gen.name(block); + gen.simpleBlockWithItem(block, gen.models().cubeAll(name, gen.blockTexture("structure_multiblock_hatch"))); + }) + .noLootTable()); + + public static final BlockDefinition STRUCTURE_MULTIBLOCK_MEMBER = block("Structure Multiblock Member", + "structure_multiblock_member", BlockDefinitionParams.defaultStone() + .withBlockConstructor(StructureMultiblockMemberBlock::new) + .withBlockItemConstructor((block, p) -> new BlockItem(block, p.rarity(Rarity.EPIC))) + .withModel((block, gen) -> { + String name = gen.name(block); + gen.simpleBlockWithItem(block, gen.models().cubeAll(name, gen.blockTexture("structure_multiblock_member"))); + }) + .noLootTable()); // Materials public static final BlockDefinition BLOCK_FIRE_CLAY_BRICKS = block("Fire Clay Bricks", "fire_clay_bricks", diff --git a/src/main/java/aztech/modern_industrialization/MIRegistries.java b/src/main/java/aztech/modern_industrialization/MIRegistries.java index 4bcf350aa..36446e15c 100644 --- a/src/main/java/aztech/modern_industrialization/MIRegistries.java +++ b/src/main/java/aztech/modern_industrialization/MIRegistries.java @@ -28,6 +28,9 @@ import aztech.modern_industrialization.blocks.forgehammer.ForgeHammerScreenHandler; import aztech.modern_industrialization.blocks.storage.barrel.CreativeBarrelBlockEntity; import aztech.modern_industrialization.blocks.storage.tank.creativetank.CreativeTankBlockEntity; +import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlockEntity; +import aztech.modern_industrialization.blocks.structure.StructureMultiblockHatchBlockEntity; +import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlockEntity; import aztech.modern_industrialization.compat.ae2.AECompatCondition; import aztech.modern_industrialization.machines.gui.MachineMenuCommon; import aztech.modern_industrialization.proxy.CommonProxy; @@ -70,6 +73,21 @@ public class MIRegistries { .register("creative_storage_unit", () -> { return BlockEntityType.Builder.of(CreativeStorageUnitBlockEntity::new, MIBlock.CREATIVE_STORAGE_UNIT.get()).build(null); }); + public static final Supplier> STRUCTURE_MULTIBLOCK_CONTROLLER_BE = BLOCK_ENTITIES + .register("structure_multiblock_controller", () -> { + return BlockEntityType.Builder.of(StructureMultiblockControllerBlockEntity::new, MIBlock.STRUCTURE_MULTIBLOCK_CONTROLLER.get()) + .build(null); + }); + public static final Supplier> STRUCTURE_MULTIBLOCK_HATCH_BE = BLOCK_ENTITIES + .register("structure_multiblock_hatch", () -> { + return BlockEntityType.Builder.of(StructureMultiblockHatchBlockEntity::new, MIBlock.STRUCTURE_MULTIBLOCK_HATCH.get()) + .build(null); + }); + public static final Supplier> STRUCTURE_MULTIBLOCK_MEMBER_BE = BLOCK_ENTITIES + .register("structure_multiblock_member", () -> { + return BlockEntityType.Builder.of(StructureMultiblockMemberBlockEntity::new, MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.get()) + .build(null); + }); // Conditions public static final DeferredRegister> CONDITIONS = DeferredRegister.create( diff --git a/src/main/java/aztech/modern_industrialization/MIText.java b/src/main/java/aztech/modern_industrialization/MIText.java index ccbbb7dcf..57b6a0296 100644 --- a/src/main/java/aztech/modern_industrialization/MIText.java +++ b/src/main/java/aztech/modern_industrialization/MIText.java @@ -246,6 +246,11 @@ public enum MIText { SteamDrillProfit("- Press %s to toggle 3x3 mining."), SteamDrillToggle("- Toggle Silk Touch with %s + %s."), SteamDrillWaterHelp("- Press %s on still or flowing water to fill."), + StructureMultiblockHatchCasing("Machine Casing"), + StructureMultiblockHatchFlags("Hatch Flags"), + StructureMultiblockMemberMembers("Members"), + StructureMultiblockMemberPreview("Preview"), + StructureMultiblockStructureName("Structure Name"), SuperconductorPowerOnly( "Can only connect to Superconductor cables and machines. Must be directly connected to a machine on at least one end of the tunnel."), Temperature("Temperature: %d °C"), diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlock.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlock.java new file mode 100644 index 000000000..948cbc171 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlock.java @@ -0,0 +1,80 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.blocks.structure; + +import aztech.modern_industrialization.proxy.CommonProxy; +import com.mojang.serialization.MapCodec; +import net.minecraft.core.BlockPos; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.EntityBlock; +import net.minecraft.world.level.block.GameMasterBlock; +import net.minecraft.world.level.block.HorizontalDirectionalBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.phys.BlockHitResult; + +public class StructureMultiblockControllerBlock extends HorizontalDirectionalBlock implements EntityBlock, GameMasterBlock { + private static final MapCodec CODEC = simpleCodec( + StructureMultiblockControllerBlock::new); + + public StructureMultiblockControllerBlock(Properties properties) { + super(properties); + } + + @Override + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { + BlockEntity blockEntity = level.getBlockEntity(pos); + if (blockEntity instanceof StructureMultiblockControllerBlockEntity controller && player.canUseGameMasterBlocks()) { + CommonProxy.INSTANCE.openStructureMultiblockControllerScreen(player, controller); + return InteractionResult.sidedSuccess(level.isClientSide()); + } else { + return InteractionResult.PASS; + } + } + + @Override + protected MapCodec codec() { + return CODEC; + } + + @Override + public BlockState getStateForPlacement(BlockPlaceContext context) { + return this.defaultBlockState().setValue(FACING, context.getHorizontalDirection().getOpposite()); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(FACING); + } + + @Override + public StructureMultiblockControllerBlockEntity newBlockEntity(BlockPos pos, BlockState state) { + return new StructureMultiblockControllerBlockEntity(pos, state); + } +} diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java new file mode 100644 index 000000000..7a90e22cc --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java @@ -0,0 +1,151 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.blocks.structure; + +import aztech.modern_industrialization.MI; +import aztech.modern_industrialization.MIRegistries; +import aztech.modern_industrialization.blocks.FastBlockEntity; +import aztech.modern_industrialization.machines.models.MachineCasing; +import aztech.modern_industrialization.machines.models.MachineCasings; +import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.nbt.Tag; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientGamePacketListener; +import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.structure.BoundingBox; +import org.jetbrains.annotations.Nullable; + +public class StructureMultiblockControllerBlockEntity extends FastBlockEntity { + private String inputId; + private String inputCasing; + + private ResourceLocation id; + private MachineCasing casing; + private BoundingBox bounds; + + public StructureMultiblockControllerBlockEntity(BlockPos pos, BlockState state) { + super(MIRegistries.STRUCTURE_MULTIBLOCK_CONTROLLER_BE.get(), pos, state); + } + + @Nullable + public String getInputId() { + return inputId; + } + + public void setInputId(String inputId) { + this.inputId = inputId; + id = ResourceLocation.tryParse(inputId); + } + + @Nullable + public String getInputCasing() { + return inputCasing; + } + + public void setInputCasing(String inputCasing) { + this.inputCasing = inputCasing; + casing = formatCasing(inputCasing); + } + + @Nullable + public BoundingBox getBounds() { + return bounds; + } + + public void setBounds(BoundingBox bounds) { + this.bounds = bounds; + } + + @Nullable + public ResourceLocation getId() { + return id; + } + + @Nullable + public static MachineCasing formatCasing(String input) { + if (input == null || input.isEmpty()) { + return null; + } + ResourceLocation casingId = null; + if (input.contains(":")) { + casingId = ResourceLocation.tryParse(input); + } else if (ResourceLocation.isValidPath(input)) { + casingId = MI.id(input); + } + if (casingId == null) { + return null; + } + if (MachineCasings.registeredCasings.containsKey(casingId)) { + return MachineCasings.get(casingId); + } + return null; + } + + @Override + public Packet getUpdatePacket() { + return ClientboundBlockEntityDataPacket.create(this); + } + + @Override + public CompoundTag getUpdateTag(HolderLookup.Provider registries) { + CompoundTag tag = new CompoundTag(); + this.saveAdditional(tag, registries); + return tag; + } + + @Override + protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.saveAdditional(tag, registries); + if (id != null) { + tag.putString("structure_id", inputId); + } + if (inputCasing != null) { + tag.putString("casing", inputCasing); + } + if (bounds != null) { + CompoundTag boundsTag = new CompoundTag(); + boundsTag.put("min", NbtUtils.writeBlockPos(new BlockPos(bounds.minX(), bounds.minY(), bounds.minZ()))); + boundsTag.put("max", NbtUtils.writeBlockPos(new BlockPos(bounds.maxX(), bounds.maxY(), bounds.maxZ()))); + tag.put("bounds", boundsTag); + } + } + + @Override + protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.loadAdditional(tag, registries); + this.setInputId(tag.getString("structure_id")); + this.setInputCasing(tag.getString("casing")); + if (tag.contains("bounds", Tag.TAG_COMPOUND)) { + CompoundTag boundsTag = tag.getCompound("bounds"); + BlockPos min = NbtUtils.readBlockPos(boundsTag, "min").orElseThrow(); + BlockPos max = NbtUtils.readBlockPos(boundsTag, "max").orElseThrow(); + bounds = BoundingBox.fromCorners(min, max); + } + } +} diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlock.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlock.java new file mode 100644 index 000000000..e423aa614 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlock.java @@ -0,0 +1,66 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.blocks.structure; + +import aztech.modern_industrialization.proxy.CommonProxy; +import com.mojang.serialization.MapCodec; +import net.minecraft.core.BlockPos; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.EntityBlock; +import net.minecraft.world.level.block.GameMasterBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; + +public class StructureMultiblockHatchBlock extends Block implements EntityBlock, GameMasterBlock { + private static final MapCodec CODEC = simpleCodec(StructureMultiblockHatchBlock::new); + + public StructureMultiblockHatchBlock(Properties properties) { + super(properties); + } + + @Override + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { + BlockEntity blockEntity = level.getBlockEntity(pos); + if (blockEntity instanceof StructureMultiblockHatchBlockEntity hatch && player.canUseGameMasterBlocks()) { + CommonProxy.INSTANCE.openStructureMultiblockHatchScreen(player, hatch); + return InteractionResult.sidedSuccess(level.isClientSide()); + } else { + return InteractionResult.PASS; + } + } + + @Override + protected MapCodec codec() { + return CODEC; + } + + @Override + public StructureMultiblockHatchBlockEntity newBlockEntity(BlockPos pos, BlockState state) { + return new StructureMultiblockHatchBlockEntity(pos, state); + } +} diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlockEntity.java new file mode 100644 index 000000000..abbe157cd --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlockEntity.java @@ -0,0 +1,137 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.blocks.structure; + +import aztech.modern_industrialization.MIRegistries; +import aztech.modern_industrialization.blocks.FastBlockEntity; +import aztech.modern_industrialization.machines.models.MachineCasing; +import aztech.modern_industrialization.machines.multiblocks.HatchFlags; +import aztech.modern_industrialization.machines.multiblocks.HatchType; +import java.util.Locale; +import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientGamePacketListener; +import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; + +public class StructureMultiblockHatchBlockEntity extends FastBlockEntity { + private String inputCasing; + private String inputFlags; + + private MachineCasing casing; + private HatchFlags flags = HatchFlags.NO_HATCH; + + public StructureMultiblockHatchBlockEntity(BlockPos pos, BlockState state) { + super(MIRegistries.STRUCTURE_MULTIBLOCK_HATCH_BE.get(), pos, state); + } + + @Nullable + public String getInputCasing() { + return inputCasing; + } + + public void setInputCasing(String inputCasing) { + this.inputCasing = inputCasing; + casing = formatCasing(inputCasing); + } + + @Nullable + public String getInputFlags() { + return inputFlags; + } + + public void setInputFlags(String inputFlags) { + this.inputFlags = inputFlags; + flags = formatFlags(inputFlags); + } + + @Nullable + public MachineCasing getCasing() { + return casing; + } + + @Nullable + public HatchFlags getFlags() { + return flags; + } + + @Nullable + public static MachineCasing formatCasing(String input) { + return StructureMultiblockControllerBlockEntity.formatCasing(input); + } + + @Nullable + public static HatchFlags formatFlags(String input) { + if (input == null || input.isEmpty()) { + return HatchFlags.NO_HATCH; + } + HatchFlags.Builder builder = new HatchFlags.Builder(); + for (String part : input.split(";")) { + try { + builder.with(Integer.parseInt(part)); + } catch (NumberFormatException ignored) { + try { + HatchType hatchType = HatchType.valueOf(part.toUpperCase(Locale.ROOT)); + builder.with(hatchType); + } catch (IllegalArgumentException ignored2) { + return null; + } + } + } + return builder.build(); + } + + @Override + public Packet getUpdatePacket() { + return ClientboundBlockEntityDataPacket.create(this); + } + + @Override + public CompoundTag getUpdateTag(HolderLookup.Provider registries) { + CompoundTag tag = new CompoundTag(); + this.saveAdditional(tag, registries); + return tag; + } + + @Override + protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.saveAdditional(tag, registries); + if (inputCasing != null) { + tag.putString("casing", inputCasing); + } + if (inputFlags != null) { + tag.putString("flags", inputFlags); + } + } + + @Override + protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.loadAdditional(tag, registries); + this.setInputCasing(tag.getString("casing")); + this.setInputFlags(tag.getString("flags")); + } +} diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlock.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlock.java new file mode 100644 index 000000000..065069360 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlock.java @@ -0,0 +1,66 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.blocks.structure; + +import aztech.modern_industrialization.proxy.CommonProxy; +import com.mojang.serialization.MapCodec; +import net.minecraft.core.BlockPos; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.EntityBlock; +import net.minecraft.world.level.block.GameMasterBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; + +public class StructureMultiblockMemberBlock extends Block implements EntityBlock, GameMasterBlock { + private static final MapCodec CODEC = simpleCodec(StructureMultiblockMemberBlock::new); + + public StructureMultiblockMemberBlock(Properties properties) { + super(properties); + } + + @Override + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { + BlockEntity blockEntity = level.getBlockEntity(pos); + if (blockEntity instanceof StructureMultiblockMemberBlockEntity member && player.canUseGameMasterBlocks()) { + CommonProxy.INSTANCE.openStructureMultiblockMemberScreen(player, member); + return InteractionResult.sidedSuccess(level.isClientSide()); + } else { + return InteractionResult.PASS; + } + } + + @Override + protected MapCodec codec() { + return CODEC; + } + + @Override + public StructureMultiblockMemberBlockEntity newBlockEntity(BlockPos pos, BlockState state) { + return new StructureMultiblockMemberBlockEntity(pos, state); + } +} diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java new file mode 100644 index 000000000..609fab899 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java @@ -0,0 +1,159 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.blocks.structure; + +import aztech.modern_industrialization.MIRegistries; +import aztech.modern_industrialization.blocks.FastBlockEntity; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; +import net.minecraft.commands.arguments.blocks.BlockStateParser; +import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientGamePacketListener; +import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.BlockTags; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; + +public class StructureMultiblockMemberBlockEntity extends FastBlockEntity { + private String inputPreview; + private String inputMembers; + + private BlockState preview; + private List> members; + + public StructureMultiblockMemberBlockEntity(BlockPos pos, BlockState state) { + super(MIRegistries.STRUCTURE_MULTIBLOCK_MEMBER_BE.get(), pos, state); + } + + @Nullable + public String getInputPreview() { + return inputPreview; + } + + public void setInputPreview(String inputPreview) { + this.inputPreview = inputPreview; + preview = formatPreview(inputPreview); + } + + @Nullable + public BlockState getPreview() { + return preview; + } + + @Nullable + public String getInputMembers() { + return inputMembers; + } + + public void setInputMembers(String inputPreview, String inputMembers) { + this.inputPreview = inputPreview; + this.inputMembers = inputMembers; + members = formatMembers(inputMembers); + } + + @Nullable + public List> getMembers() { + return members; + } + + @Nullable + public static BlockState formatPreview(String inputPreview) { + if (inputPreview == null || inputPreview.isEmpty()) { + return Blocks.AIR.defaultBlockState(); + } + var registry = BuiltInRegistries.BLOCK.asLookup(); + + try { + var blockResult = BlockStateParser.parseForBlock(registry, inputPreview, true); + return blockResult.blockState(); + } catch (CommandSyntaxException ignored) { + return null; + } + } + + @Nullable + public static List> formatMembers(String inputMembers) { + if (inputMembers == null || inputMembers.isEmpty()) { + return new ArrayList<>(); + } + var registry = BuiltInRegistries.BLOCK.asLookup(); + + List> predicates = new ArrayList<>(); + for (String part : inputMembers.split(";")) { + if (part.startsWith("#")) { + ResourceLocation tagId = ResourceLocation.tryParse(part.substring(1)); + if (tagId == null) { + return null; + } + var tag = BlockTags.create(tagId); + predicates.add(state -> state.is(tag)); + } else { + try { + var blockResult = BlockStateParser.parseForBlock(registry, part, true); + predicates.add(state -> state == blockResult.blockState()); + } catch (CommandSyntaxException ignored) { + return null; + } + } + } + return predicates; + } + + @Override + public Packet getUpdatePacket() { + return ClientboundBlockEntityDataPacket.create(this); + } + + @Override + public CompoundTag getUpdateTag(HolderLookup.Provider registries) { + CompoundTag tag = new CompoundTag(); + this.saveAdditional(tag, registries); + return tag; + } + + @Override + protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.saveAdditional(tag, registries); + if (inputPreview != null) { + tag.putString("preview", inputPreview); + } + if (inputMembers != null) { + tag.putString("members", inputMembers); + } + } + + @Override + protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.loadAdditional(tag, registries); + this.setInputMembers(tag.getString("preview"), tag.getString("members")); + } +} diff --git a/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java b/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java index 77e34e410..e9cba043e 100644 --- a/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java +++ b/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java @@ -99,6 +99,12 @@ public static void init() { return buildMultiblock(ctx.getSource(), getLoadedBlockPos(ctx, "controller_pos")); })) ) + .then(literal("test_structure") + .then(argument("structure_id", id())) + .then(argument("controller_pos", blockPos())) + .executes(ctx -> { + return testStructure(ctx.getSource(), getId(ctx, "structure_id"), getLoadedBlockPos(ctx, "controller_pos")); + })) ) ); }); @@ -183,4 +189,9 @@ private static int buildMultiblock(CommandSourceStack src, BlockPos controllerPo } return Command.SINGLE_SUCCESS; } + + private static int testStructure(CommandSourceStack src, ResourceLocation id, BlockPos controllerPos) { + // TODO do stuff + return Command.SINGLE_SUCCESS; + } } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/HatchFlags.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/HatchFlags.java index 821096a07..e47578061 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/HatchFlags.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/HatchFlags.java @@ -39,11 +39,15 @@ public boolean allows(HatchType type) { public static class Builder { private int flags = 0; - public Builder with(HatchType type) { - flags |= 1 << type.getId(); + public Builder with(int flag) { + flags |= 1 << flag; return this; } + public Builder with(HatchType type) { + return this.with(type.getId()); + } + public Builder with(HatchType... types) { for (HatchType type : types) { with(type); diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java index 448b99cec..22da0251f 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java @@ -56,6 +56,21 @@ public ShapeMatcher(Level world, BlockPos controllerPos, Direction controllerDir protected boolean matchSuccessful = false; protected final List matchedHatches = new ArrayList<>(); + /** + * Convert a real position in the world to a relative position in the shape template. + */ + public static BlockPos toTemplatePos(BlockPos controllerPos, Direction controllerDirection, BlockPos worldPos) { + BlockPos relativePos = worldPos.subtract(controllerPos); + if (controllerDirection == Direction.NORTH) + return new BlockPos(-relativePos.getX(), relativePos.getY(), relativePos.getZ()); + else if (controllerDirection == Direction.SOUTH) + return new BlockPos(relativePos.getX(), relativePos.getY(), -relativePos.getZ()); + else if (controllerDirection == Direction.EAST) + return new BlockPos(-relativePos.getZ(), relativePos.getY(), -relativePos.getX()); + else + return new BlockPos(relativePos.getZ(), relativePos.getY(), relativePos.getX()); + } + /** * Convert a relative position in the shape template to the real position in the * world. diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/SimpleMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/SimpleMember.java index 7abc15b2e..2cd58ff1b 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/SimpleMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/SimpleMember.java @@ -23,7 +23,9 @@ */ package aztech.modern_industrialization.machines.multiblocks; +import java.util.Collection; import java.util.Objects; +import java.util.function.Predicate; import java.util.function.Supplier; import net.minecraft.core.Direction; import net.minecraft.core.registries.BuiltInRegistries; @@ -91,4 +93,29 @@ public BlockState getPreviewState() { } }; } + + static SimpleMember anyOf(Collection> predicates, BlockState preview) { + Objects.requireNonNull(predicates); + if (predicates.isEmpty()) { + throw new IllegalArgumentException("Cannot use empty predicate collection"); + } + Objects.requireNonNull(preview); + + return new SimpleMember() { + @Override + public boolean matchesState(BlockState state) { + for (Predicate predicate : predicates) { + if (predicate.test(state)) { + return true; + } + } + return false; + } + + @Override + public BlockState getPreviewState() { + return preview; + } + }; + } } diff --git a/src/main/java/aztech/modern_industrialization/network/MIPackets.java b/src/main/java/aztech/modern_industrialization/network/MIPackets.java index eb3f55988..62c851cfc 100644 --- a/src/main/java/aztech/modern_industrialization/network/MIPackets.java +++ b/src/main/java/aztech/modern_industrialization/network/MIPackets.java @@ -42,6 +42,10 @@ import aztech.modern_industrialization.network.pipes.SetItemWhitelistPacket; import aztech.modern_industrialization.network.pipes.SetNetworkFluidPacket; import aztech.modern_industrialization.network.pipes.SetPriorityPacket; +import aztech.modern_industrialization.network.structure.StructureSaveControllerPacket; +import aztech.modern_industrialization.network.structure.StructureUpdateControllerPacket; +import aztech.modern_industrialization.network.structure.StructureUpdateHatchPacket; +import aztech.modern_industrialization.network.structure.StructureUpdateMemberPacket; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -90,6 +94,11 @@ private static

void register(String path, Class

clazz, register("set_item_whitelist", SetItemWhitelistPacket.class, SetItemWhitelistPacket.STREAM_CODEC); register("set_network_fluid", SetNetworkFluidPacket.class, SetNetworkFluidPacket.STREAM_CODEC); register("set_priority", SetPriorityPacket.class, SetPriorityPacket.STREAM_CODEC); + // Structure blocks + register("structure_save_controller", StructureSaveControllerPacket.class, StructureSaveControllerPacket.STREAM_CODEC); + register("structure_update_controller", StructureUpdateControllerPacket.class, StructureUpdateControllerPacket.STREAM_CODEC); + register("structure_update_hatch", StructureUpdateHatchPacket.class, StructureUpdateHatchPacket.STREAM_CODEC); + register("structure_update_member", StructureUpdateMemberPacket.class, StructureUpdateMemberPacket.STREAM_CODEC); } public static void init(RegisterPayloadHandlersEvent event) { diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java new file mode 100644 index 000000000..36f844e47 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java @@ -0,0 +1,67 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.network.structure; + +import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlock; +import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlockEntity; +import aztech.modern_industrialization.network.BasePacket; +import aztech.modern_industrialization.structure.MIStructureTemplateManager; +import io.netty.buffer.ByteBuf; +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; + +public record StructureSaveControllerPacket(BlockPos pos) implements BasePacket { + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + BlockPos.STREAM_CODEC, + StructureSaveControllerPacket::pos, + StructureSaveControllerPacket::new); + + @Override + public void handle(Context ctx) { + ctx.assertOnServer(); + + if (!ctx.getPlayer().canUseGameMasterBlocks()) { + return; + } + + Level level = ctx.getPlayer().level(); + + BlockState state = level.getBlockState(pos); + BlockEntity blockEntity = level.getBlockEntity(pos); + if (blockEntity instanceof StructureMultiblockControllerBlockEntity controller) { + if (controller.getBounds() == null) { + return; + } + // TODO dont do this on dedicated server maybe? + CompoundTag tag = MIStructureTemplateManager.fromWorld(level, pos, state.getValue(StructureMultiblockControllerBlock.FACING), + controller.getBounds()); + MIStructureTemplateManager.save(controller.getId(), tag); + } + } +} diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java new file mode 100644 index 000000000..fec9cbe15 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java @@ -0,0 +1,69 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.network.structure; + +import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlockEntity; +import aztech.modern_industrialization.network.BasePacket; +import io.netty.buffer.ByteBuf; +import net.minecraft.core.BlockPos; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.levelgen.structure.BoundingBox; + +public record StructureUpdateControllerPacket(BlockPos pos, String inputId, String inputCasing, BoundingBox bounds) implements BasePacket { + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + BlockPos.STREAM_CODEC, + StructureUpdateControllerPacket::pos, + ByteBufCodecs.STRING_UTF8, + StructureUpdateControllerPacket::inputId, + ByteBufCodecs.STRING_UTF8, + StructureUpdateControllerPacket::inputCasing, + ByteBufCodecs.fromCodec(BoundingBox.CODEC), + StructureUpdateControllerPacket::bounds, + StructureUpdateControllerPacket::new); + + @Override + public void handle(Context ctx) { + ctx.assertOnServer(); + + if (!ctx.getPlayer().canUseGameMasterBlocks()) { + return; + } + + Level level = ctx.getPlayer().level(); + + BlockEntity blockEntity = level.getBlockEntity(pos); + if (blockEntity instanceof StructureMultiblockControllerBlockEntity controller) { + controller.setInputId(inputId); + controller.setInputCasing(inputCasing); + controller.setBounds(bounds); + + controller.sync(); + controller.setChanged(); + } + } +} diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateHatchPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateHatchPacket.java new file mode 100644 index 000000000..4ee8b44c4 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateHatchPacket.java @@ -0,0 +1,65 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.network.structure; + +import aztech.modern_industrialization.blocks.structure.StructureMultiblockHatchBlockEntity; +import aztech.modern_industrialization.network.BasePacket; +import io.netty.buffer.ByteBuf; +import net.minecraft.core.BlockPos; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; + +public record StructureUpdateHatchPacket(BlockPos pos, String inputCasing, String inputFlags) implements BasePacket { + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + BlockPos.STREAM_CODEC, + StructureUpdateHatchPacket::pos, + ByteBufCodecs.STRING_UTF8, + StructureUpdateHatchPacket::inputCasing, + ByteBufCodecs.STRING_UTF8, + StructureUpdateHatchPacket::inputFlags, + StructureUpdateHatchPacket::new); + + @Override + public void handle(Context ctx) { + ctx.assertOnServer(); + + if (!ctx.getPlayer().canUseGameMasterBlocks()) { + return; + } + + Level level = ctx.getPlayer().level(); + + BlockEntity blockEntity = level.getBlockEntity(pos); + if (blockEntity instanceof StructureMultiblockHatchBlockEntity hatch) { + hatch.setInputCasing(inputCasing); + hatch.setInputFlags(inputFlags); + + hatch.sync(); + hatch.setChanged(); + } + } +} diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java new file mode 100644 index 000000000..a54049dee --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java @@ -0,0 +1,64 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.network.structure; + +import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlockEntity; +import aztech.modern_industrialization.network.BasePacket; +import io.netty.buffer.ByteBuf; +import net.minecraft.core.BlockPos; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; + +public record StructureUpdateMemberPacket(BlockPos pos, String inputPreview, String inputMembers) implements BasePacket { + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + BlockPos.STREAM_CODEC, + StructureUpdateMemberPacket::pos, + ByteBufCodecs.STRING_UTF8, + StructureUpdateMemberPacket::inputPreview, + ByteBufCodecs.STRING_UTF8, + StructureUpdateMemberPacket::inputMembers, + StructureUpdateMemberPacket::new); + + @Override + public void handle(Context ctx) { + ctx.assertOnServer(); + + if (!ctx.getPlayer().canUseGameMasterBlocks()) { + return; + } + + Level level = ctx.getPlayer().level(); + + BlockEntity blockEntity = level.getBlockEntity(pos); + if (blockEntity instanceof StructureMultiblockMemberBlockEntity member) { + member.setInputMembers(inputPreview, inputMembers); + + member.sync(); + member.setChanged(); + } + } +} diff --git a/src/main/java/aztech/modern_industrialization/proxy/CommonProxy.java b/src/main/java/aztech/modern_industrialization/proxy/CommonProxy.java index c4ef0bca6..6c1bc145c 100644 --- a/src/main/java/aztech/modern_industrialization/proxy/CommonProxy.java +++ b/src/main/java/aztech/modern_industrialization/proxy/CommonProxy.java @@ -25,6 +25,9 @@ import aztech.modern_industrialization.blocks.storage.barrel.BarrelBlockEntity; import aztech.modern_industrialization.blocks.storage.tank.AbstractTankBlockEntity; +import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlockEntity; +import aztech.modern_industrialization.blocks.structure.StructureMultiblockHatchBlockEntity; +import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlockEntity; import aztech.modern_industrialization.machines.gui.MachineMenuCommon; import aztech.modern_industrialization.thirdparty.fabrictransfer.api.fluid.FluidVariant; import aztech.modern_industrialization.thirdparty.fabrictransfer.api.fluid.FluidVariantAttributes; @@ -124,4 +127,13 @@ public MachineMenuCommon createClientMachineMenu(int syncId, Inventory playerInv public BlockState getMachineCasingBlockState(BlockState state, BlockAndTintGetter renderView, BlockPos pos) { return state; } + + public void openStructureMultiblockControllerScreen(Player player, StructureMultiblockControllerBlockEntity controller) { + } + + public void openStructureMultiblockHatchScreen(Player player, StructureMultiblockHatchBlockEntity hatch) { + } + + public void openStructureMultiblockMemberScreen(Player player, StructureMultiblockMemberBlockEntity member) { + } } diff --git a/src/main/java/aztech/modern_industrialization/structure/MIStructureTemplateManager.java b/src/main/java/aztech/modern_industrialization/structure/MIStructureTemplateManager.java new file mode 100644 index 000000000..eee7cf9b4 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/structure/MIStructureTemplateManager.java @@ -0,0 +1,163 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.structure; + +import static aztech.modern_industrialization.machines.multiblocks.ShapeMatcher.*; + +import aztech.modern_industrialization.MI; +import aztech.modern_industrialization.machines.models.MachineCasing; +import aztech.modern_industrialization.machines.multiblocks.ShapeTemplate; +import aztech.modern_industrialization.machines.multiblocks.SimpleMember; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import net.minecraft.FileUtil; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.NbtAccounter; +import net.minecraft.nbt.NbtIo; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.nbt.Tag; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.FastBufferedInputStream; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.structure.BoundingBox; +import net.neoforged.fml.loading.FMLPaths; +import org.jetbrains.annotations.Nullable; + +public final class MIStructureTemplateManager { + public static CompoundTag fromWorld(Level level, BlockPos controllerPos, Direction controllerDirection, BoundingBox bounds) { + CompoundTag tag = new CompoundTag(); + + BlockPos minPos = controllerPos.offset(bounds.minX(), bounds.minY(), bounds.minZ()); + BlockPos maxPos = controllerPos.offset(bounds.maxX(), bounds.maxY(), bounds.maxZ()); + + // TODO may be unnecessary to store this + CompoundTag boundsTag = new CompoundTag(); + boundsTag.put("min", NbtUtils.writeBlockPos(toTemplatePos(controllerPos, controllerDirection, minPos))); + boundsTag.put("max", NbtUtils.writeBlockPos(toTemplatePos(controllerPos, controllerDirection, maxPos))); + tag.put("bounds", boundsTag); + + List paletteStates = new ArrayList<>(); + ListTag palette = new ListTag(); + ListTag blocks = new ListTag(); + + for (BlockPos pos : BlockPos.betweenClosed(minPos, maxPos)) { + BlockState state = level.getBlockState(pos); + + CompoundTag blockTag = new CompoundTag(); + + blockTag.put("pos", NbtUtils.writeBlockPos(toTemplatePos(controllerPos, controllerDirection, pos))); + + if (!paletteStates.contains(state)) { + paletteStates.add(state); + palette.add(NbtUtils.writeBlockState(state)); + } + int paletteIndex = paletteStates.indexOf(state); + blockTag.putInt("state", paletteIndex); + + BlockEntity blockEntity = level.getBlockEntity(pos); + if (blockEntity != null) { + blockTag.put("nbt", blockEntity.saveWithId(level.registryAccess())); + } + + blocks.add(blockTag); + } + + tag.put("palette", palette); + tag.put("blocks", blocks); + + return tag; + } + + public static ShapeTemplate deserialize(MachineCasing hatchCasing, CompoundTag tag) { + var blockRegistry = BuiltInRegistries.BLOCK.asLookup(); + + ShapeTemplate.Builder builder = new ShapeTemplate.Builder(hatchCasing); + + ListTag palette = tag.getList("palette", Tag.TAG_COMPOUND); + ListTag blocks = tag.getList("blocks", Tag.TAG_COMPOUND); + + for (int i = 0; i < blocks.size(); i++) { + CompoundTag block = blocks.getCompound(i); + + BlockPos pos = NbtUtils.readBlockPos(block, "pos").orElseThrow(); + + int paletteIndex = block.getInt("state"); + BlockState state = NbtUtils.readBlockState(blockRegistry, palette.getCompound(paletteIndex)); + + /* + * TODO: + * - rotate blockstates ... that needs to be done in the ShapeMatcher? + * - get the simple member from the blockentity if its one of our structure blocks + */ + + builder.add(pos.getX(), pos.getY(), pos.getZ(), SimpleMember.forBlockState(state)); + } + + return builder.build(); + } + + private static Path path(ResourceLocation id) throws IOException { + var miFolder = FMLPaths.GAMEDIR.get().resolve(MI.ID); + var structuresFolder = miFolder + .resolve("structures") + .resolve(id.getNamespace()); + Files.createDirectories(structuresFolder); + return FileUtil.createPathToResource(structuresFolder, id.getPath(), ".nbt"); + } + + public static void save(ResourceLocation id, CompoundTag tag) { + try (OutputStream output = new FileOutputStream(path(id).toFile())) { + NbtIo.writeCompressed(tag, output); + } catch (Exception ex) { + MI.LOGGER.error("Failed to save structure '{}'", id, ex); + } + } + + @Nullable + public static CompoundTag load(ResourceLocation id) { + try (InputStream input = new FileInputStream(path(id).toFile()); + InputStream fastInput = new FastBufferedInputStream(input)) { + return NbtIo.readCompressed(fastInput, NbtAccounter.unlimitedHeap()); + } catch (Exception ex) { + MI.LOGGER.error("Failed to load structure '{}'", id, ex); + return null; + } + } + + private MIStructureTemplateManager() { + } +} diff --git a/src/main/resources/assets/modern_industrialization/textures/block/structure_multiblock_controller_front.png b/src/main/resources/assets/modern_industrialization/textures/block/structure_multiblock_controller_front.png new file mode 100644 index 0000000000000000000000000000000000000000..1d3247d1170b14ebbf854621a23ed325c196ab1b GIT binary patch literal 366 zcmV-!0g?WRP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0Ru@yK~y+TrIWD^ zf-n$<3$ht?VlXBSy0AGA-5hZAEqF5C!chmGz>Nh56XW0{#!=A!^f$G^qVXeeT${Vz z{cW8v3`@7+s?*`3excKCigm`5aT(8Iar(W!*xi07w$4wMiSoE|G>^oB;b1QT#)~y0T$0rzR>})va9Q!)Y(zVNe zg>BaO)Rg`I#m=laFV7oQT;pzvkE<4!lVdyaQ=KsJ{v|M6y z#Wdj~Gw#L(uqE8)KF5$#z3AY1o`&;l(im#ezR$nQ(~$NpjlpDd#)eZ2EwiTcJPF+z myIU$t>cH>o#d7`T~`bA3QxFnGH9xvXnlnZZL}xT8^r zlWD$PJ=5hKKNJ`)Gn+B6BurZ5wTS1`uTu#;NsB)_GNdVRY-r$^FyG-ElPAMggNz$l z4XPIp_8vBWFe~vPLpkH7l`RaL!Z)-r+A#z-8}oE9o><2!&G4Du@ZN$diH2lGTONmn zz1#vk&DX!j8QQMdQ)0*QfQMP2!SfK$k)!SHj5^`5I}2G|Cke>2I8Qqy+^Sr=ygGNs-h8wI3_KkB`nGI&=$?RiXcJXJq{=L?A z<~u-PA?^vfho#td Date: Thu, 21 Nov 2024 16:50:00 -0500 Subject: [PATCH 03/89] Blockstates respect orientation in ShapeMatcher --- .../machines/multiblocks/ShapeMatcher.java | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java index 22da0251f..e0fe9db14 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java @@ -23,8 +23,6 @@ */ package aztech.modern_industrialization.machines.multiblocks; -import static net.minecraft.core.Direction.*; - import aztech.modern_industrialization.machines.multiblocks.world.ChunkEventListener; import aztech.modern_industrialization.machines.multiblocks.world.ChunkEventListeners; import java.util.*; @@ -32,6 +30,7 @@ import net.minecraft.core.Direction; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Rotation; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.Nullable; @@ -42,12 +41,14 @@ public class ShapeMatcher implements ChunkEventListener { public ShapeMatcher(Level world, BlockPos controllerPos, Direction controllerDirection, ShapeTemplate template) { this.controllerPos = controllerPos; + this.controllerDirection = controllerDirection; this.template = template; this.simpleMembers = toWorldPos(controllerPos, controllerDirection, template.simpleMembers); this.hatchFlags = toWorldPos(controllerPos, controllerDirection, template.hatchFlags); } protected final BlockPos controllerPos; + protected final Direction controllerDirection; protected final ShapeTemplate template; protected final Map simpleMembers; protected final Map hatchFlags; @@ -77,11 +78,11 @@ else if (controllerDirection == Direction.EAST) */ public static BlockPos toWorldPos(BlockPos controllerPos, Direction controllerDirection, BlockPos templatePos) { BlockPos rotatedPos; - if (controllerDirection == NORTH) + if (controllerDirection == Direction.NORTH) rotatedPos = new BlockPos(-templatePos.getX(), templatePos.getY(), templatePos.getZ()); - else if (controllerDirection == SOUTH) + else if (controllerDirection == Direction.SOUTH) rotatedPos = new BlockPos(templatePos.getX(), templatePos.getY(), -templatePos.getZ()); - else if (controllerDirection == EAST) + else if (controllerDirection == Direction.EAST) rotatedPos = new BlockPos(-templatePos.getZ(), templatePos.getY(), -templatePos.getX()); else rotatedPos = new BlockPos(templatePos.getZ(), templatePos.getY(), templatePos.getX()); @@ -122,6 +123,16 @@ public void unlinkHatches() { matchSuccessful = false; needsRematch = true; } + + private Rotation rotation() { + return switch (controllerDirection) { + case NORTH -> Rotation.NONE; + case SOUTH -> Rotation.CLOCKWISE_180; + case WEST -> Rotation.CLOCKWISE_90; + case EAST -> Rotation.COUNTERCLOCKWISE_90; + default -> throw new IllegalStateException("Unexpected value: " + controllerDirection); + }; + } /** * Return true if there was a match, and append matched hatches to the list if @@ -132,7 +143,7 @@ public boolean matches(BlockPos pos, Level world, @Nullable List Date: Thu, 21 Nov 2024 23:08:02 -0500 Subject: [PATCH 04/89] Properly handle template and in-world block state rotations --- .../debug/DebugCommands.java | 39 ++++++++---- .../machines/multiblocks/ShapeMatcher.java | 60 ++++++++++++++----- .../structure/MIStructureTemplateManager.java | 3 +- 3 files changed, 73 insertions(+), 29 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java b/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java index e9cba043e..ed7f70608 100644 --- a/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java +++ b/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java @@ -23,20 +23,17 @@ */ package aztech.modern_industrialization.debug; -import static net.minecraft.commands.Commands.argument; -import static net.minecraft.commands.Commands.literal; -import static net.minecraft.commands.arguments.ResourceLocationArgument.getId; -import static net.minecraft.commands.arguments.ResourceLocationArgument.id; -import static net.minecraft.commands.arguments.coordinates.BlockPosArgument.blockPos; -import static net.minecraft.commands.arguments.coordinates.BlockPosArgument.getLoadedBlockPos; - import aztech.modern_industrialization.MIConfig; import aztech.modern_industrialization.machines.MachineBlockEntity; +import aztech.modern_industrialization.machines.models.MachineCasings; import aztech.modern_industrialization.machines.multiblocks.MultiblockMachineBlockEntity; +import aztech.modern_industrialization.machines.multiblocks.ShapeMatcher; +import aztech.modern_industrialization.machines.multiblocks.ShapeTemplate; import aztech.modern_industrialization.pipes.MIPipes; import aztech.modern_industrialization.pipes.api.PipeNetworkType; import aztech.modern_industrialization.pipes.impl.PipeNetworks; import aztech.modern_industrialization.stats.PlayerStatisticsData; +import aztech.modern_industrialization.structure.MIStructureTemplateManager; import com.mojang.brigadier.Command; import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; @@ -44,14 +41,21 @@ import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.SharedSuggestionProvider; import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.event.RegisterCommandsEvent; +import static net.minecraft.commands.Commands.*; +import static net.minecraft.commands.arguments.ResourceLocationArgument.*; +import static net.minecraft.commands.arguments.coordinates.BlockPosArgument.*; + public class DebugCommands { private static final SuggestionProvider PIPE_TYPES_SUGGESTION_PROVIDER = (context, builder) -> { return SharedSuggestionProvider.suggestResource(PipeNetworkType.getTypes().keySet().stream(), builder); @@ -100,11 +104,11 @@ public static void init() { })) ) .then(literal("test_structure") - .then(argument("structure_id", id())) - .then(argument("controller_pos", blockPos())) - .executes(ctx -> { - return testStructure(ctx.getSource(), getId(ctx, "structure_id"), getLoadedBlockPos(ctx, "controller_pos")); - })) + .then(argument("structure_id", id()) + .then(argument("controller_pos", blockPos()) + .executes(ctx -> { + return testStructure(ctx.getSource(), getId(ctx, "structure_id"), getLoadedBlockPos(ctx, "controller_pos")); + })))) ) ); }); @@ -191,7 +195,16 @@ private static int buildMultiblock(CommandSourceStack src, BlockPos controllerPo } private static int testStructure(CommandSourceStack src, ResourceLocation id, BlockPos controllerPos) { - // TODO do stuff + BlockState controllerState = src.getLevel().getBlockState(controllerPos); + if(controllerState.hasProperty(BlockStateProperties.HORIZONTAL_FACING)) { + CompoundTag tag = MIStructureTemplateManager.load(id); + ShapeTemplate shape = MIStructureTemplateManager.deserialize(MachineCasings.CLEAN_STAINLESS_STEEL, tag); + ShapeMatcher matcher = new ShapeMatcher(src.getLevel(), controllerPos, controllerState.getValue(BlockStateProperties.HORIZONTAL_FACING), shape); + matcher.rematch(src.getLevel()); + src.sendSuccess(() -> Component.literal("Match test results: %s".formatted(matcher.isMatchSuccessful())), true); + } else { + src.sendFailure(Component.literal("Block at position %s is not a controller.".formatted(controllerPos))); + } return Command.SINGLE_SUCCESS; } } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java index e0fe9db14..0e8ce6f37 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java @@ -25,7 +25,6 @@ import aztech.modern_industrialization.machines.multiblocks.world.ChunkEventListener; import aztech.modern_industrialization.machines.multiblocks.world.ChunkEventListeners; -import java.util.*; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.level.ChunkPos; @@ -35,6 +34,15 @@ import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + /** * Status of a multiblock shape bound to some position and direction. */ @@ -96,6 +104,40 @@ protected static Map toWorldPos(BlockPos controllerPos, Directi } return result; } + + private static Rotation templateRotation(Direction controllerDirection) { + return switch (controllerDirection) { + case SOUTH -> Rotation.NONE; + case NORTH -> Rotation.CLOCKWISE_180; + case EAST -> Rotation.CLOCKWISE_90; + case WEST -> Rotation.COUNTERCLOCKWISE_90; + default -> throw new IllegalStateException("Unexpected value: " + controllerDirection); + }; + } + + private static Rotation worldRotation(Direction controllerDirection) { + return switch (controllerDirection) { + case SOUTH -> Rotation.NONE; + case NORTH -> Rotation.CLOCKWISE_180; + case EAST -> Rotation.COUNTERCLOCKWISE_90; + case WEST -> Rotation.CLOCKWISE_90; + default -> throw new IllegalStateException("Unexpected value: " + controllerDirection); + }; + } + + /** + * Convert a in-world block state to a rotated block state as it should be saved for a shape template. + */ + public static BlockState toTemplateState(Level level, BlockPos pos, BlockState state, Direction controllerDirection) { + return state.rotate(level, pos, templateRotation(controllerDirection)); + } + + /** + * Convert a template block state to a rotated block state as it should be placed in world. + */ + public static BlockState toWorldState(Level level, BlockPos pos, BlockState state, Direction controllerDirection) { + return state.rotate(level, pos, worldRotation(controllerDirection)); + } public Set getPositions() { return new HashSet<>(simpleMembers.keySet()); @@ -123,16 +165,6 @@ public void unlinkHatches() { matchSuccessful = false; needsRematch = true; } - - private Rotation rotation() { - return switch (controllerDirection) { - case NORTH -> Rotation.NONE; - case SOUTH -> Rotation.CLOCKWISE_180; - case WEST -> Rotation.CLOCKWISE_90; - case EAST -> Rotation.COUNTERCLOCKWISE_90; - default -> throw new IllegalStateException("Unexpected value: " + controllerDirection); - }; - } /** * Return true if there was a match, and append matched hatches to the list if @@ -143,7 +175,7 @@ public boolean matches(BlockPos pos, Level world, @Nullable List Date: Thu, 21 Nov 2024 23:21:00 -0500 Subject: [PATCH 05/89] Add show bounds toggle to the controller --- .../StructureMultiblockControllerBER.java | 4 +- ...ructureMultiblockControllerEditScreen.java | 111 ++++++++++-------- ...uctureMultiblockControllerBlockEntity.java | 11 ++ .../StructureUpdateControllerPacket.java | 5 +- 4 files changed, 79 insertions(+), 52 deletions(-) diff --git a/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java b/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java index bcf2106b2..4bb66a9ab 100644 --- a/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java +++ b/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java @@ -37,6 +37,9 @@ public class StructureMultiblockControllerBER implements BlockEntityRenderer showBoundsBox; public StructureMultiblockControllerEditScreen(StructureMultiblockControllerBlockEntity controller) { super(Component.translatable(MIBlock.STRUCTURE_MULTIBLOCK_CONTROLLER.asBlock().getDescriptionId())); @@ -78,13 +81,13 @@ private Optional getCasing() { // TODO this needs to be reworked to allow for negative sizes and whatnot private Optional getBoundingBox() { try { - int minX = Integer.parseInt(posX.getValue()); - int minY = Integer.parseInt(posY.getValue()); - int minZ = Integer.parseInt(posZ.getValue()); + int minX = Integer.parseInt(posXBox.getValue()); + int minY = Integer.parseInt(posYBox.getValue()); + int minZ = Integer.parseInt(posZBox.getValue()); BlockPos min = new BlockPos(minX, minY, minZ); - int maxX = Integer.parseInt(sizeX.getValue()) + minX - 1; - int maxY = Integer.parseInt(sizeY.getValue()) + minY - 1; - int maxZ = Integer.parseInt(sizeZ.getValue()) + minZ - 1; + int maxX = Integer.parseInt(sizeXBox.getValue()) + minX - 1; + int maxY = Integer.parseInt(sizeYBox.getValue()) + minY - 1; + int maxZ = Integer.parseInt(sizeZBox.getValue()) + minZ - 1; BlockPos max = new BlockPos(maxX, maxY, maxZ); return Optional.of(BoundingBox.fromCorners(min, max)); } catch (NumberFormatException ignored) { @@ -117,7 +120,8 @@ private void sendToServer() { controller.getBlockPos(), idBox.getValue(), casingBox.getValue(), - this.getBoundingBox().orElse(new BoundingBox(0, 0, 0, 0, 0, 0)))); + this.getBoundingBox().orElse(new BoundingBox(0, 0, 0, 0, 0, 0)), + showBoundsBox.getValue())); } private void cancel() { @@ -127,6 +131,7 @@ private void cancel() { private void save() { this.sendToServer(); minecraft.getConnection().send(new StructureSaveControllerPacket(controller.getBlockPos())); + minecraft.setScreen(null); } @Override @@ -166,31 +171,35 @@ public boolean charTyped(char codePoint, int modifiers) { bounds = new BoundingBox(0, 0, 0, 0, 0, 0); } - posX = new EditBox(font, width / 2 - 152, 130, 80, 20, Component.translatable("structure_block.position.x")); - posX.setMaxLength(15); - posX.setValue(Integer.toString(bounds.minX())); - this.addRenderableWidget(posX); - posY = new EditBox(font, width / 2 - 72, 130, 80, 20, Component.translatable("structure_block.position.y")); - posY.setMaxLength(15); - posY.setValue(Integer.toString(bounds.minY())); - this.addRenderableWidget(posY); - posZ = new EditBox(font, width / 2 + 8, 130, 80, 20, Component.translatable("structure_block.position.z")); - posZ.setMaxLength(15); - posZ.setValue(Integer.toString(bounds.minZ())); - this.addRenderableWidget(posZ); - - sizeX = new EditBox(font, width / 2 - 152, 170, 80, 20, Component.translatable("structure_block.size.x")); - sizeX.setMaxLength(15); - sizeX.setValue(Integer.toString(bounds.maxX() - bounds.minX() + 1)); - this.addRenderableWidget(sizeX); - sizeY = new EditBox(font, width / 2 - 72, 170, 80, 20, Component.translatable("structure_block.size.y")); - sizeY.setMaxLength(15); - sizeY.setValue(Integer.toString(bounds.maxY() - bounds.minY() + 1)); - this.addRenderableWidget(sizeY); - sizeZ = new EditBox(font, width / 2 + 8, 170, 80, 20, Component.translatable("structure_block.size.z")); - sizeZ.setMaxLength(15); - sizeZ.setValue(Integer.toString(bounds.maxZ() - bounds.minZ() + 1)); - this.addRenderableWidget(sizeZ); + posXBox = new EditBox(font, width / 2 - 152, 130, 80, 20, Component.translatable("structure_block.position.x")); + posXBox.setMaxLength(15); + posXBox.setValue(Integer.toString(bounds.minX())); + this.addRenderableWidget(posXBox); + posYBox = new EditBox(font, width / 2 - 72, 130, 80, 20, Component.translatable("structure_block.position.y")); + posYBox.setMaxLength(15); + posYBox.setValue(Integer.toString(bounds.minY())); + this.addRenderableWidget(posYBox); + posZBox = new EditBox(font, width / 2 + 8, 130, 80, 20, Component.translatable("structure_block.position.z")); + posZBox.setMaxLength(15); + posZBox.setValue(Integer.toString(bounds.minZ())); + this.addRenderableWidget(posZBox); + + sizeXBox = new EditBox(font, width / 2 - 152, 170, 80, 20, Component.translatable("structure_block.size.x")); + sizeXBox.setMaxLength(15); + sizeXBox.setValue(Integer.toString(bounds.maxX() - bounds.minX() + 1)); + this.addRenderableWidget(sizeXBox); + sizeYBox = new EditBox(font, width / 2 - 72, 170, 80, 20, Component.translatable("structure_block.size.y")); + sizeYBox.setMaxLength(15); + sizeYBox.setValue(Integer.toString(bounds.maxY() - bounds.minY() + 1)); + this.addRenderableWidget(sizeYBox); + sizeZBox = new EditBox(font, width / 2 + 8, 170, 80, 20, Component.translatable("structure_block.size.z")); + sizeZBox.setMaxLength(15); + sizeZBox.setValue(Integer.toString(bounds.maxZ() - bounds.minZ() + 1)); + this.addRenderableWidget(sizeZBox); + + this.addRenderableWidget(showBoundsBox = CycleButton.onOffBuilder(controller.shouldShowBounds()) + .displayOnlyValue() + .create(width / 2 + 4 + 100, 130, 50, 20, Component.translatable("structure_block.show_boundingbox"))); this.updateAll(); } @@ -208,6 +217,8 @@ public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTi graphics.drawString(font, Component.translatable("structure_block.position"), width / 2 - 153, 120, 0xA0A0A0); graphics.drawString(font, Component.translatable("structure_block.size"), width / 2 - 153, 160, 0xA0A0A0); + + graphics.drawString(font, Component.translatable("structure_block.show_boundingbox"), width / 2 + 154 - font.width(Component.translatable("structure_block.show_boundingbox")), 120, 10526880); } @Override @@ -224,23 +235,23 @@ protected void setInitialFocus() { public void resize(Minecraft minecraft, int width, int height) { String idBoxValue = idBox.getValue(); String casingBoxValue = casingBox.getValue(); - String posXValue = posX.getValue(); - String posYValue = posY.getValue(); - String posZValue = posZ.getValue(); - String sizeXValue = sizeX.getValue(); - String sizeYValue = sizeY.getValue(); - String sizeZValue = sizeZ.getValue(); + String posXValue = posXBox.getValue(); + String posYValue = posYBox.getValue(); + String posZValue = posZBox.getValue(); + String sizeXValue = sizeXBox.getValue(); + String sizeYValue = sizeYBox.getValue(); + String sizeZValue = sizeZBox.getValue(); this.init(minecraft, width, height); idBox.setValue(idBoxValue); casingBox.setValue(casingBoxValue); - posX.setValue(posXValue); - posY.setValue(posYValue); - posZ.setValue(posZValue); - sizeX.setValue(sizeXValue); - sizeY.setValue(sizeYValue); - sizeZ.setValue(sizeZValue); + posXBox.setValue(posXValue); + posYBox.setValue(posYValue); + posZBox.setValue(posZValue); + sizeXBox.setValue(sizeXValue); + sizeYBox.setValue(sizeYValue); + sizeZBox.setValue(sizeZValue); } @Override diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java index 7a90e22cc..cde62faa2 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java @@ -48,6 +48,7 @@ public class StructureMultiblockControllerBlockEntity extends FastBlockEntity { private ResourceLocation id; private MachineCasing casing; private BoundingBox bounds; + private boolean showBounds; public StructureMultiblockControllerBlockEntity(BlockPos pos, BlockState state) { super(MIRegistries.STRUCTURE_MULTIBLOCK_CONTROLLER_BE.get(), pos, state); @@ -86,6 +87,14 @@ public void setBounds(BoundingBox bounds) { public ResourceLocation getId() { return id; } + + public boolean shouldShowBounds() { + return showBounds; + } + + public void setShowBounds(boolean showBounds) { + this.showBounds = showBounds; + } @Nullable public static MachineCasing formatCasing(String input) { @@ -134,6 +143,7 @@ protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) boundsTag.put("max", NbtUtils.writeBlockPos(new BlockPos(bounds.maxX(), bounds.maxY(), bounds.maxZ()))); tag.put("bounds", boundsTag); } + tag.putBoolean("show_bounds", showBounds); } @Override @@ -147,5 +157,6 @@ protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) BlockPos max = NbtUtils.readBlockPos(boundsTag, "max").orElseThrow(); bounds = BoundingBox.fromCorners(min, max); } + showBounds = tag.getBoolean("show_bounds"); } } diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java index fec9cbe15..4e2ec6cda 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java @@ -33,7 +33,7 @@ import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.levelgen.structure.BoundingBox; -public record StructureUpdateControllerPacket(BlockPos pos, String inputId, String inputCasing, BoundingBox bounds) implements BasePacket { +public record StructureUpdateControllerPacket(BlockPos pos, String inputId, String inputCasing, BoundingBox bounds, boolean showBounds) implements BasePacket { public static final StreamCodec STREAM_CODEC = StreamCodec.composite( BlockPos.STREAM_CODEC, @@ -44,6 +44,8 @@ public record StructureUpdateControllerPacket(BlockPos pos, String inputId, Stri StructureUpdateControllerPacket::inputCasing, ByteBufCodecs.fromCodec(BoundingBox.CODEC), StructureUpdateControllerPacket::bounds, + ByteBufCodecs.BOOL, + StructureUpdateControllerPacket::showBounds, StructureUpdateControllerPacket::new); @Override @@ -61,6 +63,7 @@ public void handle(Context ctx) { controller.setInputId(inputId); controller.setInputCasing(inputCasing); controller.setBounds(bounds); + controller.setShowBounds(showBounds); controller.sync(); controller.setChanged(); From 1f0512685aeb23754242c48c2519efbc29c54834 Mon Sep 17 00:00:00 2001 From: Swedz Date: Thu, 21 Nov 2024 23:25:24 -0500 Subject: [PATCH 06/89] Use file exists checks --- .../debug/DebugCommands.java | 4 ++++ .../structure/MIStructureTemplateManager.java | 15 ++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java b/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java index ed7f70608..2147942bc 100644 --- a/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java +++ b/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java @@ -198,6 +198,10 @@ private static int testStructure(CommandSourceStack src, ResourceLocation id, Bl BlockState controllerState = src.getLevel().getBlockState(controllerPos); if(controllerState.hasProperty(BlockStateProperties.HORIZONTAL_FACING)) { CompoundTag tag = MIStructureTemplateManager.load(id); + if (tag == null) { + src.sendFailure(Component.literal("Could not find structure by the id '%s'".formatted(id))); + return Command.SINGLE_SUCCESS; + } ShapeTemplate shape = MIStructureTemplateManager.deserialize(MachineCasings.CLEAN_STAINLESS_STEEL, tag); ShapeMatcher matcher = new ShapeMatcher(src.getLevel(), controllerPos, controllerState.getValue(BlockStateProperties.HORIZONTAL_FACING), shape); matcher.rematch(src.getLevel()); diff --git a/src/main/java/aztech/modern_industrialization/structure/MIStructureTemplateManager.java b/src/main/java/aztech/modern_industrialization/structure/MIStructureTemplateManager.java index 082813a2d..17f7b481d 100644 --- a/src/main/java/aztech/modern_industrialization/structure/MIStructureTemplateManager.java +++ b/src/main/java/aztech/modern_industrialization/structure/MIStructureTemplateManager.java @@ -148,9 +148,18 @@ public static void save(ResourceLocation id, CompoundTag tag) { @Nullable public static CompoundTag load(ResourceLocation id) { - try (InputStream input = new FileInputStream(path(id).toFile()); - InputStream fastInput = new FastBufferedInputStream(input)) { - return NbtIo.readCompressed(fastInput, NbtAccounter.unlimitedHeap()); + try { + Path path = path(id); + if(Files.exists(path)) { + try (InputStream input = new FileInputStream(path.toFile()); + InputStream fastInput = new FastBufferedInputStream(input)) { + return NbtIo.readCompressed(fastInput, NbtAccounter.unlimitedHeap()); + } catch (Exception ex) { + MI.LOGGER.error("Failed to load structure '{}'", id, ex); + return null; + } + } + return null; } catch (Exception ex) { MI.LOGGER.error("Failed to load structure '{}'", id, ex); return null; From 61b7fa55986c68e03f25251a68aba62e50238926 Mon Sep 17 00:00:00 2001 From: Swedz Date: Fri, 22 Nov 2024 00:10:12 -0500 Subject: [PATCH 07/89] Improve controller bounds checks --- .../StructureMultiblockControllerBER.java | 16 ++-- ...ructureMultiblockControllerEditScreen.java | 88 ++++++++++--------- .../modern_industrialization/lang/en_us.json | 1 + .../modern_industrialization/MIText.java | 1 + .../structure/StructureControllerBounds.java | 70 +++++++++++++++ ...uctureMultiblockControllerBlockEntity.java | 31 +++---- .../debug/DebugCommands.java | 13 +-- .../machines/multiblocks/ShapeMatcher.java | 45 +++++----- .../StructureSaveControllerPacket.java | 13 ++- .../StructureUpdateControllerPacket.java | 15 ++-- .../structure/StructureUpdateHatchPacket.java | 8 +- .../StructureUpdateMemberPacket.java | 8 +- .../structure/MIStructureTemplateManager.java | 22 ++--- 13 files changed, 211 insertions(+), 120 deletions(-) create mode 100644 src/main/java/aztech/modern_industrialization/blocks/structure/StructureControllerBounds.java diff --git a/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java b/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java index 4bb66a9ab..f47733530 100644 --- a/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java +++ b/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java @@ -30,7 +30,6 @@ import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; import net.minecraft.core.BlockPos; -import net.minecraft.world.level.levelgen.structure.BoundingBox; import net.minecraft.world.phys.AABB; public class StructureMultiblockControllerBER implements BlockEntityRenderer { @@ -41,15 +40,14 @@ public void render(StructureMultiblockControllerBlockEntity controller, float ti return; } BlockPos pos = controller.getBlockPos(); - BoundingBox bounds = controller.getBounds(); - if (bounds == null) { - bounds = new BoundingBox(0, 0, 0, 0, 0, 0); + StructureControllerBounds bounds = controller.getBounds(); + AABB box = bounds.aabb(); + if (box != null) { + matrices.pushPose(); + VertexConsumer buffer = vcs.getBuffer(RenderType.lines()); + LevelRenderer.renderLineBox(matrices, buffer, box, 1, 1, 1, 1); + matrices.popPose(); } - matrices.pushPose(); - VertexConsumer buffer = vcs.getBuffer(RenderType.lines()); - AABB box = AABB.of(bounds); - LevelRenderer.renderLineBox(matrices, buffer, box, 1, 1, 1, 1); - matrices.popPose(); } @Override diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java index 7e68721d1..68fd20279 100644 --- a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java @@ -25,6 +25,7 @@ import aztech.modern_industrialization.MIBlock; import aztech.modern_industrialization.MIText; +import aztech.modern_industrialization.blocks.structure.StructureControllerBounds; import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlockEntity; import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.network.structure.StructureSaveControllerPacket; @@ -37,11 +38,9 @@ import net.minecraft.client.gui.components.CycleButton; import net.minecraft.client.gui.components.EditBox; import net.minecraft.client.gui.screens.Screen; -import net.minecraft.core.BlockPos; import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.levelgen.structure.BoundingBox; public class StructureMultiblockControllerEditScreen extends Screen { private static final int VALID_TEXT_COLOR = 0xE0E0E0; @@ -62,7 +61,7 @@ public class StructureMultiblockControllerEditScreen extends Screen { private EditBox sizeXBox; private EditBox sizeYBox; private EditBox sizeZBox; - + private CycleButton showBoundsBox; public StructureMultiblockControllerEditScreen(StructureMultiblockControllerBlockEntity controller) { @@ -78,18 +77,15 @@ private Optional getCasing() { return Optional.ofNullable(StructureMultiblockControllerBlockEntity.formatCasing(casingBox.getValue())); } - // TODO this needs to be reworked to allow for negative sizes and whatnot - private Optional getBoundingBox() { + private Optional getBounds() { try { - int minX = Integer.parseInt(posXBox.getValue()); - int minY = Integer.parseInt(posYBox.getValue()); - int minZ = Integer.parseInt(posZBox.getValue()); - BlockPos min = new BlockPos(minX, minY, minZ); - int maxX = Integer.parseInt(sizeXBox.getValue()) + minX - 1; - int maxY = Integer.parseInt(sizeYBox.getValue()) + minY - 1; - int maxZ = Integer.parseInt(sizeZBox.getValue()) + minZ - 1; - BlockPos max = new BlockPos(maxX, maxY, maxZ); - return Optional.of(BoundingBox.fromCorners(min, max)); + int x = Integer.parseInt(posXBox.getValue()); + int y = Integer.parseInt(posYBox.getValue()); + int z = Integer.parseInt(posZBox.getValue()); + int sizeX = Integer.parseInt(sizeXBox.getValue()); + int sizeY = Integer.parseInt(sizeYBox.getValue()); + int sizeZ = Integer.parseInt(sizeZBox.getValue()); + return Optional.of(new StructureControllerBounds(x, y, z, sizeX, sizeY, sizeZ)); } catch (NumberFormatException ignored) { return Optional.empty(); } @@ -105,9 +101,15 @@ private void updateCasing() { casingBox.setTextColor(validCasing ? VALID_TEXT_COLOR : INVALID_TEXT_COLOR); } + private void updateBounds() { + boolean validBounds = this.getBounds().filter((b) -> !b.isEmpty()).isPresent(); + saveButton.active = validBounds; + } + private void updateAll() { this.updateId(); this.updateCasing(); + this.updateBounds(); } private void done() { @@ -120,7 +122,7 @@ private void sendToServer() { controller.getBlockPos(), idBox.getValue(), casingBox.getValue(), - this.getBoundingBox().orElse(new BoundingBox(0, 0, 0, 0, 0, 0)), + this.getBounds().orElse(new StructureControllerBounds(0, 0, 0, 1, 1, 1)), showBoundsBox.getValue())); } @@ -166,37 +168,40 @@ public boolean charTyped(char codePoint, int modifiers) { casingBox.setResponder(text -> this.updateCasing()); this.addRenderableWidget(casingBox); - BoundingBox bounds = controller.getBounds(); - if (bounds == null) { - bounds = new BoundingBox(0, 0, 0, 0, 0, 0); - } + StructureControllerBounds bounds = controller.getBounds(); posXBox = new EditBox(font, width / 2 - 152, 130, 80, 20, Component.translatable("structure_block.position.x")); posXBox.setMaxLength(15); - posXBox.setValue(Integer.toString(bounds.minX())); + posXBox.setValue(Integer.toString(bounds.x())); + posXBox.setResponder(text -> this.updateBounds()); this.addRenderableWidget(posXBox); posYBox = new EditBox(font, width / 2 - 72, 130, 80, 20, Component.translatable("structure_block.position.y")); posYBox.setMaxLength(15); - posYBox.setValue(Integer.toString(bounds.minY())); + posYBox.setValue(Integer.toString(bounds.y())); + posYBox.setResponder(text -> this.updateBounds()); this.addRenderableWidget(posYBox); posZBox = new EditBox(font, width / 2 + 8, 130, 80, 20, Component.translatable("structure_block.position.z")); posZBox.setMaxLength(15); - posZBox.setValue(Integer.toString(bounds.minZ())); + posZBox.setValue(Integer.toString(bounds.z())); + posZBox.setResponder(text -> this.updateBounds()); this.addRenderableWidget(posZBox); sizeXBox = new EditBox(font, width / 2 - 152, 170, 80, 20, Component.translatable("structure_block.size.x")); sizeXBox.setMaxLength(15); - sizeXBox.setValue(Integer.toString(bounds.maxX() - bounds.minX() + 1)); + sizeXBox.setValue(Integer.toString(bounds.sizeX())); + sizeXBox.setResponder(text -> this.updateBounds()); this.addRenderableWidget(sizeXBox); sizeYBox = new EditBox(font, width / 2 - 72, 170, 80, 20, Component.translatable("structure_block.size.y")); sizeYBox.setMaxLength(15); - sizeYBox.setValue(Integer.toString(bounds.maxY() - bounds.minY() + 1)); + sizeYBox.setValue(Integer.toString(bounds.sizeY())); + sizeYBox.setResponder(text -> this.updateBounds()); this.addRenderableWidget(sizeYBox); sizeZBox = new EditBox(font, width / 2 + 8, 170, 80, 20, Component.translatable("structure_block.size.z")); sizeZBox.setMaxLength(15); - sizeZBox.setValue(Integer.toString(bounds.maxZ() - bounds.minZ() + 1)); + sizeZBox.setValue(Integer.toString(bounds.sizeZ())); + sizeZBox.setResponder(text -> this.updateBounds()); this.addRenderableWidget(sizeZBox); - + this.addRenderableWidget(showBoundsBox = CycleButton.onOffBuilder(controller.shouldShowBounds()) .displayOnlyValue() .create(width / 2 + 4 + 100, 130, 50, 20, Component.translatable("structure_block.show_boundingbox"))); @@ -217,8 +222,9 @@ public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTi graphics.drawString(font, Component.translatable("structure_block.position"), width / 2 - 153, 120, 0xA0A0A0); graphics.drawString(font, Component.translatable("structure_block.size"), width / 2 - 153, 160, 0xA0A0A0); - - graphics.drawString(font, Component.translatable("structure_block.show_boundingbox"), width / 2 + 154 - font.width(Component.translatable("structure_block.show_boundingbox")), 120, 10526880); + + graphics.drawString(font, Component.translatable("structure_block.show_boundingbox"), + width / 2 + 154 - font.width(Component.translatable("structure_block.show_boundingbox")), 120, 10526880); } @Override @@ -235,23 +241,25 @@ protected void setInitialFocus() { public void resize(Minecraft minecraft, int width, int height) { String idBoxValue = idBox.getValue(); String casingBoxValue = casingBox.getValue(); - String posXValue = posXBox.getValue(); - String posYValue = posYBox.getValue(); - String posZValue = posZBox.getValue(); - String sizeXValue = sizeXBox.getValue(); - String sizeYValue = sizeYBox.getValue(); - String sizeZValue = sizeZBox.getValue(); + String posXBoxValue = posXBox.getValue(); + String posYBoxValue = posYBox.getValue(); + String posZBoxValue = posZBox.getValue(); + String sizeXBoxValue = sizeXBox.getValue(); + String sizeYBoxValue = sizeYBox.getValue(); + String sizeZBoxValue = sizeZBox.getValue(); + boolean showBoundsBoxValue = showBoundsBox.getValue(); this.init(minecraft, width, height); idBox.setValue(idBoxValue); casingBox.setValue(casingBoxValue); - posXBox.setValue(posXValue); - posYBox.setValue(posYValue); - posZBox.setValue(posZValue); - sizeXBox.setValue(sizeXValue); - sizeYBox.setValue(sizeYValue); - sizeZBox.setValue(sizeZValue); + posXBox.setValue(posXBoxValue); + posYBox.setValue(posYBoxValue); + posZBox.setValue(posZBoxValue); + sizeXBox.setValue(sizeXBoxValue); + sizeYBox.setValue(sizeYBoxValue); + sizeZBox.setValue(sizeZBoxValue); + showBoundsBox.setValue(showBoundsBoxValue); } @Override diff --git a/src/generated/resources/assets/modern_industrialization/lang/en_us.json b/src/generated/resources/assets/modern_industrialization/lang/en_us.json index 2962ca8b3..1479d6be8 100644 --- a/src/generated/resources/assets/modern_industrialization/lang/en_us.json +++ b/src/generated/resources/assets/modern_industrialization/lang/en_us.json @@ -1698,6 +1698,7 @@ "text.modern_industrialization.StructureMultiblockHatchFlags": "Hatch Flags", "text.modern_industrialization.StructureMultiblockMemberMembers": "Members", "text.modern_industrialization.StructureMultiblockMemberPreview": "Preview", + "text.modern_industrialization.StructureMultiblockSaveFailNoBounds": "Failed to save structure. The bounds provided are not valid.", "text.modern_industrialization.StructureMultiblockStructureName": "Structure Name", "text.modern_industrialization.SuperconductorPowerOnly": "Can only connect to Superconductor cables and machines. Must be directly connected to a machine on at least one end of the tunnel.", "text.modern_industrialization.Temperature": "Temperature: %d °C", diff --git a/src/main/java/aztech/modern_industrialization/MIText.java b/src/main/java/aztech/modern_industrialization/MIText.java index 57b6a0296..52827e53e 100644 --- a/src/main/java/aztech/modern_industrialization/MIText.java +++ b/src/main/java/aztech/modern_industrialization/MIText.java @@ -251,6 +251,7 @@ public enum MIText { StructureMultiblockMemberMembers("Members"), StructureMultiblockMemberPreview("Preview"), StructureMultiblockStructureName("Structure Name"), + StructureMultiblockSaveFailNoBounds("Failed to save structure. The bounds provided are not valid."), SuperconductorPowerOnly( "Can only connect to Superconductor cables and machines. Must be directly connected to a machine on at least one end of the tunnel."), Temperature("Temperature: %d °C"), diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureControllerBounds.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureControllerBounds.java new file mode 100644 index 000000000..d5d7e76bf --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureControllerBounds.java @@ -0,0 +1,70 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.blocks.structure; + +import com.mojang.serialization.Codec; +import java.util.stream.IntStream; +import net.minecraft.Util; +import net.minecraft.world.level.levelgen.structure.BoundingBox; +import net.minecraft.world.phys.AABB; +import org.jetbrains.annotations.Nullable; + +public record StructureControllerBounds(int x, int y, int z, int sizeX, int sizeY, int sizeZ) { + + public static final Codec CODEC = Codec.INT_STREAM.comapFlatMap( + (stream) -> Util.fixedSize(stream, 6).map((array) -> new StructureControllerBounds( + array[0], array[1], array[2], + array[3], array[4], array[5])), + (bounds) -> IntStream.of( + bounds.x(), bounds.y(), bounds.z(), + bounds.sizeX(), bounds.sizeY(), bounds.sizeZ())); + + public static final StructureControllerBounds EMPTY = new StructureControllerBounds(0, 0, 0, 0, 0, 0); + + public boolean isEmpty() { + return sizeX == 0 || sizeY == 0 || sizeZ == 0; + } + + @Nullable + public BoundingBox boundingBox() { + if (this.isEmpty()) { + return null; + } + int x1 = x; + int y1 = y; + int z1 = z; + int x2 = x + sizeX + Integer.compare(0, sizeX); + int y2 = y + sizeY + Integer.compare(0, sizeY); + int z2 = z + sizeZ + Integer.compare(0, sizeZ); + return new BoundingBox( + Math.min(x1, x2), Math.min(y1, y2), Math.min(z1, z2), + Math.max(x1, x2), Math.max(y1, y2), Math.max(z1, z2)); + } + + @Nullable + public AABB aabb() { + BoundingBox boundingBox = this.boundingBox(); + return boundingBox == null ? null : AABB.of(boundingBox); + } +} diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java index cde62faa2..337642980 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java @@ -38,7 +38,6 @@ import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.levelgen.structure.BoundingBox; import org.jetbrains.annotations.Nullable; public class StructureMultiblockControllerBlockEntity extends FastBlockEntity { @@ -47,7 +46,7 @@ public class StructureMultiblockControllerBlockEntity extends FastBlockEntity { private ResourceLocation id; private MachineCasing casing; - private BoundingBox bounds; + private StructureControllerBounds bounds = new StructureControllerBounds(0, 0, 0, 1, 1, 1); private boolean showBounds; public StructureMultiblockControllerBlockEntity(BlockPos pos, BlockState state) { @@ -75,11 +74,11 @@ public void setInputCasing(String inputCasing) { } @Nullable - public BoundingBox getBounds() { + public StructureControllerBounds getBounds() { return bounds; } - public void setBounds(BoundingBox bounds) { + public void setBounds(StructureControllerBounds bounds) { this.bounds = bounds; } @@ -87,11 +86,11 @@ public void setBounds(BoundingBox bounds) { public ResourceLocation getId() { return id; } - + public boolean shouldShowBounds() { return showBounds; } - + public void setShowBounds(boolean showBounds) { this.showBounds = showBounds; } @@ -137,12 +136,10 @@ protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) if (inputCasing != null) { tag.putString("casing", inputCasing); } - if (bounds != null) { - CompoundTag boundsTag = new CompoundTag(); - boundsTag.put("min", NbtUtils.writeBlockPos(new BlockPos(bounds.minX(), bounds.minY(), bounds.minZ()))); - boundsTag.put("max", NbtUtils.writeBlockPos(new BlockPos(bounds.maxX(), bounds.maxY(), bounds.maxZ()))); - tag.put("bounds", boundsTag); - } + CompoundTag boundsTag = new CompoundTag(); + boundsTag.put("origin", NbtUtils.writeBlockPos(new BlockPos(bounds.x(), bounds.y(), bounds.z()))); + boundsTag.put("size", NbtUtils.writeBlockPos(new BlockPos(bounds.sizeX(), bounds.sizeY(), bounds.sizeZ()))); + tag.put("bounds", boundsTag); tag.putBoolean("show_bounds", showBounds); } @@ -153,9 +150,13 @@ protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) this.setInputCasing(tag.getString("casing")); if (tag.contains("bounds", Tag.TAG_COMPOUND)) { CompoundTag boundsTag = tag.getCompound("bounds"); - BlockPos min = NbtUtils.readBlockPos(boundsTag, "min").orElseThrow(); - BlockPos max = NbtUtils.readBlockPos(boundsTag, "max").orElseThrow(); - bounds = BoundingBox.fromCorners(min, max); + BlockPos origin = NbtUtils.readBlockPos(boundsTag, "origin").orElseThrow(); + BlockPos size = NbtUtils.readBlockPos(boundsTag, "size").orElseThrow(); + bounds = new StructureControllerBounds( + origin.getX(), origin.getY(), origin.getZ(), + size.getX(), size.getY(), size.getZ()); + } else { + bounds = new StructureControllerBounds(0, 0, 0, 1, 1, 1); } showBounds = tag.getBoolean("show_bounds"); } diff --git a/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java b/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java index 2147942bc..cbb8d8a28 100644 --- a/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java +++ b/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java @@ -23,6 +23,10 @@ */ package aztech.modern_industrialization.debug; +import static net.minecraft.commands.Commands.*; +import static net.minecraft.commands.arguments.ResourceLocationArgument.*; +import static net.minecraft.commands.arguments.coordinates.BlockPosArgument.*; + import aztech.modern_industrialization.MIConfig; import aztech.modern_industrialization.machines.MachineBlockEntity; import aztech.modern_industrialization.machines.models.MachineCasings; @@ -52,10 +56,6 @@ import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.event.RegisterCommandsEvent; -import static net.minecraft.commands.Commands.*; -import static net.minecraft.commands.arguments.ResourceLocationArgument.*; -import static net.minecraft.commands.arguments.coordinates.BlockPosArgument.*; - public class DebugCommands { private static final SuggestionProvider PIPE_TYPES_SUGGESTION_PROVIDER = (context, builder) -> { return SharedSuggestionProvider.suggestResource(PipeNetworkType.getTypes().keySet().stream(), builder); @@ -196,14 +196,15 @@ private static int buildMultiblock(CommandSourceStack src, BlockPos controllerPo private static int testStructure(CommandSourceStack src, ResourceLocation id, BlockPos controllerPos) { BlockState controllerState = src.getLevel().getBlockState(controllerPos); - if(controllerState.hasProperty(BlockStateProperties.HORIZONTAL_FACING)) { + if (controllerState.hasProperty(BlockStateProperties.HORIZONTAL_FACING)) { CompoundTag tag = MIStructureTemplateManager.load(id); if (tag == null) { src.sendFailure(Component.literal("Could not find structure by the id '%s'".formatted(id))); return Command.SINGLE_SUCCESS; } ShapeTemplate shape = MIStructureTemplateManager.deserialize(MachineCasings.CLEAN_STAINLESS_STEEL, tag); - ShapeMatcher matcher = new ShapeMatcher(src.getLevel(), controllerPos, controllerState.getValue(BlockStateProperties.HORIZONTAL_FACING), shape); + ShapeMatcher matcher = new ShapeMatcher(src.getLevel(), controllerPos, controllerState.getValue(BlockStateProperties.HORIZONTAL_FACING), + shape); matcher.rematch(src.getLevel()); src.sendSuccess(() -> Component.literal("Match test results: %s".formatted(matcher.isMatchSuccessful())), true); } else { diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java index 0e8ce6f37..5b0f23974 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java @@ -25,15 +25,6 @@ import aztech.modern_industrialization.machines.multiblocks.world.ChunkEventListener; import aztech.modern_industrialization.machines.multiblocks.world.ChunkEventListeners; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Rotation; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import org.jetbrains.annotations.Nullable; - import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -42,6 +33,14 @@ import java.util.Map; import java.util.Objects; import java.util.Set; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Rotation; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; /** * Status of a multiblock shape bound to some position and direction. @@ -104,34 +103,34 @@ protected static Map toWorldPos(BlockPos controllerPos, Directi } return result; } - + private static Rotation templateRotation(Direction controllerDirection) { return switch (controllerDirection) { - case SOUTH -> Rotation.NONE; - case NORTH -> Rotation.CLOCKWISE_180; - case EAST -> Rotation.CLOCKWISE_90; - case WEST -> Rotation.COUNTERCLOCKWISE_90; - default -> throw new IllegalStateException("Unexpected value: " + controllerDirection); + case SOUTH -> Rotation.NONE; + case NORTH -> Rotation.CLOCKWISE_180; + case EAST -> Rotation.CLOCKWISE_90; + case WEST -> Rotation.COUNTERCLOCKWISE_90; + default -> throw new IllegalStateException("Unexpected value: " + controllerDirection); }; } - + private static Rotation worldRotation(Direction controllerDirection) { return switch (controllerDirection) { - case SOUTH -> Rotation.NONE; - case NORTH -> Rotation.CLOCKWISE_180; - case EAST -> Rotation.COUNTERCLOCKWISE_90; - case WEST -> Rotation.CLOCKWISE_90; - default -> throw new IllegalStateException("Unexpected value: " + controllerDirection); + case SOUTH -> Rotation.NONE; + case NORTH -> Rotation.CLOCKWISE_180; + case EAST -> Rotation.COUNTERCLOCKWISE_90; + case WEST -> Rotation.CLOCKWISE_90; + default -> throw new IllegalStateException("Unexpected value: " + controllerDirection); }; } - + /** * Convert a in-world block state to a rotated block state as it should be saved for a shape template. */ public static BlockState toTemplateState(Level level, BlockPos pos, BlockState state, Direction controllerDirection) { return state.rotate(level, pos, templateRotation(controllerDirection)); } - + /** * Convert a template block state to a rotated block state as it should be placed in world. */ diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java index 36f844e47..df0fdf1c8 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java @@ -23,14 +23,17 @@ */ package aztech.modern_industrialization.network.structure; +import aztech.modern_industrialization.MIText; import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlock; import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlockEntity; import aztech.modern_industrialization.network.BasePacket; import aztech.modern_industrialization.structure.MIStructureTemplateManager; import io.netty.buffer.ByteBuf; +import net.minecraft.ChatFormatting; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.codec.StreamCodec; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; @@ -46,16 +49,18 @@ public record StructureSaveControllerPacket(BlockPos pos) implements BasePacket public void handle(Context ctx) { ctx.assertOnServer(); - if (!ctx.getPlayer().canUseGameMasterBlocks()) { + Player player = ctx.getPlayer(); + Level level = player.level(); + + if (!player.canUseGameMasterBlocks()) { return; } - Level level = ctx.getPlayer().level(); - BlockState state = level.getBlockState(pos); BlockEntity blockEntity = level.getBlockEntity(pos); if (blockEntity instanceof StructureMultiblockControllerBlockEntity controller) { - if (controller.getBounds() == null) { + if (controller.getBounds().isEmpty()) { + player.sendSystemMessage(MIText.StructureMultiblockSaveFailNoBounds.text().withStyle(ChatFormatting.RED)); return; } // TODO dont do this on dedicated server maybe? diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java index 4e2ec6cda..68639204c 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java @@ -23,17 +23,19 @@ */ package aztech.modern_industrialization.network.structure; +import aztech.modern_industrialization.blocks.structure.StructureControllerBounds; import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlockEntity; import aztech.modern_industrialization.network.BasePacket; import io.netty.buffer.ByteBuf; import net.minecraft.core.BlockPos; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.levelgen.structure.BoundingBox; -public record StructureUpdateControllerPacket(BlockPos pos, String inputId, String inputCasing, BoundingBox bounds, boolean showBounds) implements BasePacket { +public record StructureUpdateControllerPacket(BlockPos pos, String inputId, String inputCasing, StructureControllerBounds bounds, boolean showBounds) + implements BasePacket { public static final StreamCodec STREAM_CODEC = StreamCodec.composite( BlockPos.STREAM_CODEC, @@ -42,7 +44,7 @@ public record StructureUpdateControllerPacket(BlockPos pos, String inputId, Stri StructureUpdateControllerPacket::inputId, ByteBufCodecs.STRING_UTF8, StructureUpdateControllerPacket::inputCasing, - ByteBufCodecs.fromCodec(BoundingBox.CODEC), + ByteBufCodecs.fromCodec(StructureControllerBounds.CODEC), StructureUpdateControllerPacket::bounds, ByteBufCodecs.BOOL, StructureUpdateControllerPacket::showBounds, @@ -52,12 +54,13 @@ public record StructureUpdateControllerPacket(BlockPos pos, String inputId, Stri public void handle(Context ctx) { ctx.assertOnServer(); - if (!ctx.getPlayer().canUseGameMasterBlocks()) { + Player player = ctx.getPlayer(); + Level level = player.level(); + + if (!player.canUseGameMasterBlocks()) { return; } - Level level = ctx.getPlayer().level(); - BlockEntity blockEntity = level.getBlockEntity(pos); if (blockEntity instanceof StructureMultiblockControllerBlockEntity controller) { controller.setInputId(inputId); diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateHatchPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateHatchPacket.java index 4ee8b44c4..e20d1f574 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateHatchPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateHatchPacket.java @@ -29,6 +29,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; @@ -47,12 +48,13 @@ public record StructureUpdateHatchPacket(BlockPos pos, String inputCasing, Strin public void handle(Context ctx) { ctx.assertOnServer(); - if (!ctx.getPlayer().canUseGameMasterBlocks()) { + Player player = ctx.getPlayer(); + Level level = player.level(); + + if (!player.canUseGameMasterBlocks()) { return; } - Level level = ctx.getPlayer().level(); - BlockEntity blockEntity = level.getBlockEntity(pos); if (blockEntity instanceof StructureMultiblockHatchBlockEntity hatch) { hatch.setInputCasing(inputCasing); diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java index a54049dee..4f95789a2 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java @@ -29,6 +29,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; @@ -47,12 +48,13 @@ public record StructureUpdateMemberPacket(BlockPos pos, String inputPreview, Str public void handle(Context ctx) { ctx.assertOnServer(); - if (!ctx.getPlayer().canUseGameMasterBlocks()) { + Player player = ctx.getPlayer(); + Level level = player.level(); + + if (!player.canUseGameMasterBlocks()) { return; } - Level level = ctx.getPlayer().level(); - BlockEntity blockEntity = level.getBlockEntity(pos); if (blockEntity instanceof StructureMultiblockMemberBlockEntity member) { member.setInputMembers(inputPreview, inputMembers); diff --git a/src/main/java/aztech/modern_industrialization/structure/MIStructureTemplateManager.java b/src/main/java/aztech/modern_industrialization/structure/MIStructureTemplateManager.java index 17f7b481d..3355215d5 100644 --- a/src/main/java/aztech/modern_industrialization/structure/MIStructureTemplateManager.java +++ b/src/main/java/aztech/modern_industrialization/structure/MIStructureTemplateManager.java @@ -26,6 +26,7 @@ import static aztech.modern_industrialization.machines.multiblocks.ShapeMatcher.*; import aztech.modern_industrialization.MI; +import aztech.modern_industrialization.blocks.structure.StructureControllerBounds; import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.ShapeTemplate; import aztech.modern_industrialization.machines.multiblocks.SimpleMember; @@ -58,17 +59,16 @@ import org.jetbrains.annotations.Nullable; public final class MIStructureTemplateManager { - public static CompoundTag fromWorld(Level level, BlockPos controllerPos, Direction controllerDirection, BoundingBox bounds) { - CompoundTag tag = new CompoundTag(); + public static CompoundTag fromWorld(Level level, BlockPos controllerPos, Direction controllerDirection, StructureControllerBounds bounds) { + if (bounds.isEmpty()) { + throw new IllegalArgumentException("Invalid bounds: %s".formatted(bounds)); + } - BlockPos minPos = controllerPos.offset(bounds.minX(), bounds.minY(), bounds.minZ()); - BlockPos maxPos = controllerPos.offset(bounds.maxX(), bounds.maxY(), bounds.maxZ()); + CompoundTag tag = new CompoundTag(); - // TODO may be unnecessary to store this - CompoundTag boundsTag = new CompoundTag(); - boundsTag.put("min", NbtUtils.writeBlockPos(toTemplatePos(controllerPos, controllerDirection, minPos))); - boundsTag.put("max", NbtUtils.writeBlockPos(toTemplatePos(controllerPos, controllerDirection, maxPos))); - tag.put("bounds", boundsTag); + BoundingBox boundsBox = bounds.boundingBox(); + BlockPos minPos = controllerPos.offset(boundsBox.minX(), boundsBox.minY(), boundsBox.minZ()); + BlockPos maxPos = controllerPos.offset(boundsBox.maxX(), boundsBox.maxY(), boundsBox.maxZ()); List paletteStates = new ArrayList<>(); ListTag palette = new ListTag(); @@ -150,9 +150,9 @@ public static void save(ResourceLocation id, CompoundTag tag) { public static CompoundTag load(ResourceLocation id) { try { Path path = path(id); - if(Files.exists(path)) { + if (Files.exists(path)) { try (InputStream input = new FileInputStream(path.toFile()); - InputStream fastInput = new FastBufferedInputStream(input)) { + InputStream fastInput = new FastBufferedInputStream(input)) { return NbtIo.readCompressed(fastInput, NbtAccounter.unlimitedHeap()); } catch (Exception ex) { MI.LOGGER.error("Failed to load structure '{}'", id, ex); From af8eafbfb63fdd2e67bd002802db59d048114839 Mon Sep 17 00:00:00 2001 From: Swedz Date: Fri, 22 Nov 2024 00:41:52 -0500 Subject: [PATCH 08/89] Check save file success --- .../java/aztech/modern_industrialization/MIText.java | 1 + .../structure/StructureSaveControllerPacket.java | 4 +++- .../structure/MIStructureTemplateManager.java | 12 +++++++++--- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/MIText.java b/src/main/java/aztech/modern_industrialization/MIText.java index 52827e53e..007a7bc59 100644 --- a/src/main/java/aztech/modern_industrialization/MIText.java +++ b/src/main/java/aztech/modern_industrialization/MIText.java @@ -252,6 +252,7 @@ public enum MIText { StructureMultiblockMemberPreview("Preview"), StructureMultiblockStructureName("Structure Name"), StructureMultiblockSaveFailNoBounds("Failed to save structure. The bounds provided are not valid."), + StructureMultiblockSaveFailUnknown("Failed to save structure. See logs for more info."), SuperconductorPowerOnly( "Can only connect to Superconductor cables and machines. Must be directly connected to a machine on at least one end of the tunnel."), Temperature("Temperature: %d °C"), diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java index df0fdf1c8..3388170a9 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java @@ -66,7 +66,9 @@ public void handle(Context ctx) { // TODO dont do this on dedicated server maybe? CompoundTag tag = MIStructureTemplateManager.fromWorld(level, pos, state.getValue(StructureMultiblockControllerBlock.FACING), controller.getBounds()); - MIStructureTemplateManager.save(controller.getId(), tag); + if (!MIStructureTemplateManager.save(controller.getId(), tag)) { + player.sendSystemMessage(MIText.StructureMultiblockSaveFailUnknown.text().withStyle(ChatFormatting.RED)); + } } } } diff --git a/src/main/java/aztech/modern_industrialization/structure/MIStructureTemplateManager.java b/src/main/java/aztech/modern_industrialization/structure/MIStructureTemplateManager.java index 3355215d5..804f09c0d 100644 --- a/src/main/java/aztech/modern_industrialization/structure/MIStructureTemplateManager.java +++ b/src/main/java/aztech/modern_industrialization/structure/MIStructureTemplateManager.java @@ -138,12 +138,18 @@ private static Path path(ResourceLocation id) throws IOException { return FileUtil.createPathToResource(structuresFolder, id.getPath(), ".nbt"); } - public static void save(ResourceLocation id, CompoundTag tag) { - try (OutputStream output = new FileOutputStream(path(id).toFile())) { - NbtIo.writeCompressed(tag, output); + public static boolean save(ResourceLocation id, CompoundTag tag) { + try { + try (OutputStream output = new FileOutputStream(path(id).toFile())) { + NbtIo.writeCompressed(tag, output); + return true; + } catch (Exception ex) { + MI.LOGGER.error("Failed to save structure '{}'", id, ex); + } } catch (Exception ex) { MI.LOGGER.error("Failed to save structure '{}'", id, ex); } + return false; } @Nullable From c52957f6b83220a0a50a72b02868697d79da2354 Mon Sep 17 00:00:00 2001 From: Swedz Date: Fri, 22 Nov 2024 00:42:03 -0500 Subject: [PATCH 09/89] Datagen --- .../resources/assets/modern_industrialization/lang/en_us.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/generated/resources/assets/modern_industrialization/lang/en_us.json b/src/generated/resources/assets/modern_industrialization/lang/en_us.json index 1479d6be8..dbedd7740 100644 --- a/src/generated/resources/assets/modern_industrialization/lang/en_us.json +++ b/src/generated/resources/assets/modern_industrialization/lang/en_us.json @@ -1699,6 +1699,7 @@ "text.modern_industrialization.StructureMultiblockMemberMembers": "Members", "text.modern_industrialization.StructureMultiblockMemberPreview": "Preview", "text.modern_industrialization.StructureMultiblockSaveFailNoBounds": "Failed to save structure. The bounds provided are not valid.", + "text.modern_industrialization.StructureMultiblockSaveFailUnknown": "Failed to save structure. See logs for more info.", "text.modern_industrialization.StructureMultiblockStructureName": "Structure Name", "text.modern_industrialization.SuperconductorPowerOnly": "Can only connect to Superconductor cables and machines. Must be directly connected to a machine on at least one end of the tunnel.", "text.modern_industrialization.Temperature": "Temperature: %d °C", From b58ab6c2d7e1a0631c630d5fe5614a2b760475cb Mon Sep 17 00:00:00 2001 From: Swedz Date: Fri, 22 Nov 2024 02:00:54 -0500 Subject: [PATCH 10/89] Handle structure user mistakes and send an informative message --- ...ructureMultiblockControllerEditScreen.java | 3 +- .../StructureMultiblockHatchEditScreen.java | 64 +++++++- .../StructureMultiblockMemberEditScreen.java | 5 +- .../modern_industrialization/lang/en_us.json | 7 +- .../modern_industrialization/MIText.java | 7 +- .../structure/StructureMemberOverride.java | 44 ++++++ ...uctureMultiblockControllerBlockEntity.java | 46 +++--- .../StructureMultiblockFormatters.java | 131 +++++++++++++++++ .../StructureMultiblockHatchBlockEntity.java | 98 +++++++++---- .../StructureMultiblockMemberBlockEntity.java | 71 +++------ .../StructureSaveControllerPacket.java | 19 +-- .../structure/StructureUpdateHatchPacket.java | 9 +- .../StructureUpdateMemberPacket.java | 3 +- .../structure/MIStructureTemplateManager.java | 137 +++++++++++++++--- 14 files changed, 496 insertions(+), 148 deletions(-) create mode 100644 src/main/java/aztech/modern_industrialization/blocks/structure/StructureMemberOverride.java create mode 100644 src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockFormatters.java diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java index 68fd20279..604348b3c 100644 --- a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java @@ -27,6 +27,7 @@ import aztech.modern_industrialization.MIText; import aztech.modern_industrialization.blocks.structure.StructureControllerBounds; import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlockEntity; +import aztech.modern_industrialization.blocks.structure.StructureMultiblockFormatters; import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.network.structure.StructureSaveControllerPacket; import aztech.modern_industrialization.network.structure.StructureUpdateControllerPacket; @@ -74,7 +75,7 @@ private Optional getId() { } private Optional getCasing() { - return Optional.ofNullable(StructureMultiblockControllerBlockEntity.formatCasing(casingBox.getValue())); + return Optional.ofNullable(StructureMultiblockFormatters.casing(casingBox.getValue())); } private Optional getBounds() { diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockHatchEditScreen.java b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockHatchEditScreen.java index 92f4c1b02..dcd653d1f 100644 --- a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockHatchEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockHatchEditScreen.java @@ -25,12 +25,15 @@ import aztech.modern_industrialization.MIBlock; import aztech.modern_industrialization.MIText; +import aztech.modern_industrialization.blocks.structure.StructureMultiblockFormatters; import aztech.modern_industrialization.blocks.structure.StructureMultiblockHatchBlockEntity; import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.HatchFlags; import aztech.modern_industrialization.network.structure.StructureUpdateHatchPacket; import com.mojang.blaze3d.platform.InputConstants; +import java.util.List; import java.util.Optional; +import java.util.function.Predicate; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; @@ -39,6 +42,7 @@ import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.block.state.BlockState; public class StructureMultiblockHatchEditScreen extends Screen { private static final int VALID_TEXT_COLOR = 0xE0E0E0; @@ -49,8 +53,10 @@ public class StructureMultiblockHatchEditScreen extends Screen { private Button doneButton; private Button cancelButton; - private EditBox casingBox; + private EditBox previewBox; + private EditBox membersBox; + private EditBox casingBox; private EditBox flagsBox; public StructureMultiblockHatchEditScreen(StructureMultiblockHatchBlockEntity hatch) { @@ -58,12 +64,30 @@ public StructureMultiblockHatchEditScreen(StructureMultiblockHatchBlockEntity ha this.hatch = hatch; } + private Optional getPreview() { + return Optional.ofNullable(StructureMultiblockFormatters.preview(previewBox.getValue())); + } + + private Optional>> getMembers() { + return Optional.ofNullable(StructureMultiblockFormatters.members(membersBox.getValue())); + } + private Optional getCasing() { - return Optional.ofNullable(StructureMultiblockHatchBlockEntity.formatCasing(casingBox.getValue())); + return Optional.ofNullable(StructureMultiblockFormatters.casing(casingBox.getValue())); } private Optional getHatchFlags() { - return Optional.ofNullable(StructureMultiblockHatchBlockEntity.formatFlags(flagsBox.getValue())); + return Optional.ofNullable(StructureMultiblockFormatters.hatchFlags(flagsBox.getValue())); + } + + private void updatePreview() { + boolean validPreview = previewBox.getValue().isEmpty() || this.getPreview().isPresent(); + previewBox.setTextColor(validPreview ? VALID_TEXT_COLOR : INVALID_TEXT_COLOR); + } + + private void updateMembers() { + boolean validMembers = membersBox.getValue().isEmpty() || this.getMembers().isPresent(); + membersBox.setTextColor(validMembers ? VALID_TEXT_COLOR : INVALID_TEXT_COLOR); } private void updateCasing() { @@ -77,6 +101,8 @@ private void updateFlags() { } private void updateAll() { + this.updatePreview(); + this.updateMembers(); this.updateCasing(); this.updateFlags(); } @@ -89,6 +115,8 @@ private void done() { private void sendToServer() { minecraft.getConnection().send(new StructureUpdateHatchPacket( hatch.getBlockPos(), + previewBox.getValue(), + membersBox.getValue(), casingBox.getValue(), flagsBox.getValue())); } @@ -104,7 +132,19 @@ protected void init() { this.addRenderableWidget( cancelButton = Button.builder(CommonComponents.GUI_CANCEL, button -> this.cancel()).bounds(width / 2 + 4, 210, 150, 20).build()); - casingBox = new EditBox(font, width / 2 - 152, 50, 304, 20, MIText.StructureMultiblockHatchCasing.text()) { + previewBox = new EditBox(font, width / 2 - 152, 50, 304, 20, MIText.StructureMultiblockMemberPreview.text()); + previewBox.setMaxLength(Short.MAX_VALUE); + previewBox.setValue(hatch.getInputPreview()); + previewBox.setResponder(text -> this.updatePreview()); + this.addRenderableWidget(previewBox); + + membersBox = new EditBox(font, width / 2 - 152, 90, 304, 20, MIText.StructureMultiblockMemberMembers.text()); + membersBox.setMaxLength(Short.MAX_VALUE); + membersBox.setValue(hatch.getInputMembers()); + membersBox.setResponder(text -> this.updateMembers()); + this.addRenderableWidget(membersBox); + + casingBox = new EditBox(font, width / 2 - 152, 130, 304, 20, MIText.StructureMultiblockHatchCasing.text()) { @Override public boolean charTyped(char codePoint, int modifiers) { return ResourceLocation.isAllowedInResourceLocation(codePoint) && super.charTyped(codePoint, modifiers); @@ -115,7 +155,7 @@ public boolean charTyped(char codePoint, int modifiers) { casingBox.setResponder(text -> this.updateCasing()); this.addRenderableWidget(casingBox); - flagsBox = new EditBox(font, width / 2 - 152, 90, 304, 20, MIText.StructureMultiblockHatchFlags.text()) { + flagsBox = new EditBox(font, width / 2 - 152, 170, 304, 20, MIText.StructureMultiblockHatchFlags.text()) { @Override public boolean charTyped(char codePoint, int modifiers) { return (Character.isDigit(codePoint) || Character.isAlphabetic(codePoint) || codePoint == ';' || codePoint == '_') @@ -136,9 +176,13 @@ public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTi graphics.drawCenteredString(font, title, width / 2, 20, 0xFFFFFF); - graphics.drawString(font, MIText.StructureMultiblockHatchCasing.text(), width / 2 - 153, 40, 0xA0A0A0); + graphics.drawString(font, MIText.StructureMultiblockMemberPreview.text(), width / 2 - 153, 40, 0xA0A0A0); + + graphics.drawString(font, MIText.StructureMultiblockMemberMembers.text(), width / 2 - 153, 80, 0xA0A0A0); + + graphics.drawString(font, MIText.StructureMultiblockHatchCasing.text(), width / 2 - 153, 120, 0xA0A0A0); - graphics.drawString(font, MIText.StructureMultiblockHatchFlags.text(), width / 2 - 153, 80, 0xA0A0A0); + graphics.drawString(font, MIText.StructureMultiblockHatchFlags.text(), width / 2 - 153, 160, 0xA0A0A0); } @Override @@ -148,16 +192,20 @@ public void renderBackground(GuiGraphics guiGraphics, int mouseX, int mouseY, fl @Override protected void setInitialFocus() { - this.setInitialFocus(casingBox); + this.setInitialFocus(previewBox); } @Override public void resize(Minecraft minecraft, int width, int height) { + String previewBoxValue = previewBox.getValue(); + String membersBoxValue = membersBox.getValue(); String casingBoxValue = casingBox.getValue(); String flagsBoxValue = flagsBox.getValue(); this.init(minecraft, width, height); + previewBox.setValue(previewBoxValue); + membersBox.setValue(membersBoxValue); casingBox.setValue(casingBoxValue); flagsBox.setValue(flagsBoxValue); } diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java index 9237b1df8..11a79a5e4 100644 --- a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java @@ -25,6 +25,7 @@ import aztech.modern_industrialization.MIBlock; import aztech.modern_industrialization.MIText; +import aztech.modern_industrialization.blocks.structure.StructureMultiblockFormatters; import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlockEntity; import aztech.modern_industrialization.network.structure.StructureUpdateMemberPacket; import com.mojang.blaze3d.platform.InputConstants; @@ -58,11 +59,11 @@ public StructureMultiblockMemberEditScreen(StructureMultiblockMemberBlockEntity } private Optional getPreview() { - return Optional.ofNullable(StructureMultiblockMemberBlockEntity.formatPreview(previewBox.getValue())); + return Optional.ofNullable(StructureMultiblockFormatters.preview(previewBox.getValue())); } private Optional>> getMembers() { - return Optional.ofNullable(StructureMultiblockMemberBlockEntity.formatMembers(membersBox.getValue())); + return Optional.ofNullable(StructureMultiblockFormatters.members(membersBox.getValue())); } private void updatePreview() { diff --git a/src/generated/resources/assets/modern_industrialization/lang/en_us.json b/src/generated/resources/assets/modern_industrialization/lang/en_us.json index dbedd7740..ef56af169 100644 --- a/src/generated/resources/assets/modern_industrialization/lang/en_us.json +++ b/src/generated/resources/assets/modern_industrialization/lang/en_us.json @@ -1698,8 +1698,13 @@ "text.modern_industrialization.StructureMultiblockHatchFlags": "Hatch Flags", "text.modern_industrialization.StructureMultiblockMemberMembers": "Members", "text.modern_industrialization.StructureMultiblockMemberPreview": "Preview", - "text.modern_industrialization.StructureMultiblockSaveFailNoBounds": "Failed to save structure. The bounds provided are not valid.", + "text.modern_industrialization.StructureMultiblockSaveFailInvalidBounds": "Failed to save structure. The bounds provided are not valid.", + "text.modern_industrialization.StructureMultiblockSaveFailMisconfiguredBlock": "Failed to save structure. The block at (%s) is not properly configured.", + "text.modern_industrialization.StructureMultiblockSaveFailNoController": "Failed to save structure. No controller could be found within the bounds.", + "text.modern_industrialization.StructureMultiblockSaveFailNoHatches": "Failed to save structure. No hatches could be found within the bounds.", + "text.modern_industrialization.StructureMultiblockSaveFailTooManyControllers": "Failed to save structure. Too many controllers exist within the bounds.", "text.modern_industrialization.StructureMultiblockSaveFailUnknown": "Failed to save structure. See logs for more info.", + "text.modern_industrialization.StructureMultiblockSaveSuccess": "The structure has been saved as %s.", "text.modern_industrialization.StructureMultiblockStructureName": "Structure Name", "text.modern_industrialization.SuperconductorPowerOnly": "Can only connect to Superconductor cables and machines. Must be directly connected to a machine on at least one end of the tunnel.", "text.modern_industrialization.Temperature": "Temperature: %d °C", diff --git a/src/main/java/aztech/modern_industrialization/MIText.java b/src/main/java/aztech/modern_industrialization/MIText.java index 007a7bc59..98cbefb5d 100644 --- a/src/main/java/aztech/modern_industrialization/MIText.java +++ b/src/main/java/aztech/modern_industrialization/MIText.java @@ -251,8 +251,13 @@ public enum MIText { StructureMultiblockMemberMembers("Members"), StructureMultiblockMemberPreview("Preview"), StructureMultiblockStructureName("Structure Name"), - StructureMultiblockSaveFailNoBounds("Failed to save structure. The bounds provided are not valid."), + StructureMultiblockSaveFailInvalidBounds("Failed to save structure. The bounds provided are not valid."), + StructureMultiblockSaveFailMisconfiguredBlock("Failed to save structure. The block at (%s) is not properly configured."), + StructureMultiblockSaveFailTooManyControllers("Failed to save structure. Too many controllers exist within the bounds."), + StructureMultiblockSaveFailNoController("Failed to save structure. No controller could be found within the bounds."), + StructureMultiblockSaveFailNoHatches("Failed to save structure. No hatches could be found within the bounds."), StructureMultiblockSaveFailUnknown("Failed to save structure. See logs for more info."), + StructureMultiblockSaveSuccess("The structure has been saved as %s."), SuperconductorPowerOnly( "Can only connect to Superconductor cables and machines. Must be directly connected to a machine on at least one end of the tunnel."), Temperature("Temperature: %d °C"), diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMemberOverride.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMemberOverride.java new file mode 100644 index 000000000..29d2530a5 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMemberOverride.java @@ -0,0 +1,44 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.blocks.structure; + +import aztech.modern_industrialization.machines.multiblocks.HatchFlags; +import aztech.modern_industrialization.machines.multiblocks.SimpleMember; +import net.minecraft.nbt.CompoundTag; + +public interface StructureMemberOverride { + default boolean isController() { + return false; + } + + SimpleMember getMemberOverride(); + + default HatchFlags getHatchFlagsOverride() { + return null; + } + + boolean isConfigurationValid(); + + void loadStructureData(CompoundTag tag); +} diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java index 337642980..55907bd9a 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java @@ -23,11 +23,10 @@ */ package aztech.modern_industrialization.blocks.structure; -import aztech.modern_industrialization.MI; import aztech.modern_industrialization.MIRegistries; import aztech.modern_industrialization.blocks.FastBlockEntity; import aztech.modern_industrialization.machines.models.MachineCasing; -import aztech.modern_industrialization.machines.models.MachineCasings; +import aztech.modern_industrialization.machines.multiblocks.SimpleMember; import net.minecraft.core.BlockPos; import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; @@ -40,7 +39,7 @@ import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.Nullable; -public class StructureMultiblockControllerBlockEntity extends FastBlockEntity { +public class StructureMultiblockControllerBlockEntity extends FastBlockEntity implements StructureMemberOverride { private String inputId; private String inputCasing; @@ -70,10 +69,9 @@ public String getInputCasing() { public void setInputCasing(String inputCasing) { this.inputCasing = inputCasing; - casing = formatCasing(inputCasing); + casing = StructureMultiblockFormatters.casing(inputCasing); } - @Nullable public StructureControllerBounds getBounds() { return bounds; } @@ -95,26 +93,21 @@ public void setShowBounds(boolean showBounds) { this.showBounds = showBounds; } - @Nullable - public static MachineCasing formatCasing(String input) { - if (input == null || input.isEmpty()) { - return null; - } - ResourceLocation casingId = null; - if (input.contains(":")) { - casingId = ResourceLocation.tryParse(input); - } else if (ResourceLocation.isValidPath(input)) { - casingId = MI.id(input); - } - if (casingId == null) { - return null; - } - if (MachineCasings.registeredCasings.containsKey(casingId)) { - return MachineCasings.get(casingId); - } + @Override + public boolean isController() { + return true; + } + + @Override + public SimpleMember getMemberOverride() { return null; } + @Override + public boolean isConfigurationValid() { + return !bounds.isEmpty(); + } + @Override public Packet getUpdatePacket() { return ClientboundBlockEntityDataPacket.create(this); @@ -144,8 +137,7 @@ protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) } @Override - protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { - super.loadAdditional(tag, registries); + public void loadStructureData(CompoundTag tag) { this.setInputId(tag.getString("structure_id")); this.setInputCasing(tag.getString("casing")); if (tag.contains("bounds", Tag.TAG_COMPOUND)) { @@ -160,4 +152,10 @@ protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) } showBounds = tag.getBoolean("show_bounds"); } + + @Override + protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.loadAdditional(tag, registries); + this.loadStructureData(tag); + } } diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockFormatters.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockFormatters.java new file mode 100644 index 000000000..ae1820d41 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockFormatters.java @@ -0,0 +1,131 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.blocks.structure; + +import aztech.modern_industrialization.MI; +import aztech.modern_industrialization.machines.models.MachineCasing; +import aztech.modern_industrialization.machines.models.MachineCasings; +import aztech.modern_industrialization.machines.multiblocks.HatchFlags; +import aztech.modern_industrialization.machines.multiblocks.HatchType; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.function.Predicate; +import net.minecraft.commands.arguments.blocks.BlockStateParser; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.BlockTags; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; + +public final class StructureMultiblockFormatters { + @Nullable + public static MachineCasing casing(String input) { + if (input == null || input.isEmpty()) { + return null; + } + ResourceLocation casingId = null; + if (input.contains(":")) { + casingId = ResourceLocation.tryParse(input); + } else if (ResourceLocation.isValidPath(input)) { + casingId = MI.id(input); + } + if (casingId == null) { + return null; + } + if (MachineCasings.registeredCasings.containsKey(casingId)) { + return MachineCasings.get(casingId); + } + return null; + } + + @Nullable + public static BlockState preview(String inputPreview) { + if (inputPreview == null || inputPreview.isEmpty()) { + return Blocks.AIR.defaultBlockState(); + } + var registry = BuiltInRegistries.BLOCK.asLookup(); + + try { + var blockResult = BlockStateParser.parseForBlock(registry, inputPreview, true); + return blockResult.blockState(); + } catch (CommandSyntaxException ignored) { + return null; + } + } + + @Nullable + public static List> members(String inputMembers) { + if (inputMembers == null || inputMembers.isEmpty()) { + return new ArrayList<>(); + } + var registry = BuiltInRegistries.BLOCK.asLookup(); + + List> predicates = new ArrayList<>(); + for (String part : inputMembers.split(";")) { + if (part.startsWith("#")) { + ResourceLocation tagId = ResourceLocation.tryParse(part.substring(1)); + if (tagId == null) { + return null; + } + var tag = BlockTags.create(tagId); + predicates.add(state -> state.is(tag)); + } else { + try { + var blockResult = BlockStateParser.parseForBlock(registry, part, true); + predicates.add(state -> state == blockResult.blockState()); + } catch (CommandSyntaxException ignored) { + return null; + } + } + } + return predicates; + } + + @Nullable + public static HatchFlags hatchFlags(String input) { + if (input == null || input.isEmpty()) { + return HatchFlags.NO_HATCH; + } + HatchFlags.Builder builder = new HatchFlags.Builder(); + for (String part : input.split(";")) { + try { + builder.with(Integer.parseInt(part)); + } catch (NumberFormatException ignored) { + try { + HatchType hatchType = HatchType.valueOf(part.toUpperCase(Locale.ROOT)); + builder.with(hatchType); + } catch (IllegalArgumentException ignored2) { + return null; + } + } + } + return builder.build(); + } + + private StructureMultiblockFormatters() { + } +} diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlockEntity.java index abbe157cd..9ba4af5ce 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlockEntity.java @@ -27,8 +27,9 @@ import aztech.modern_industrialization.blocks.FastBlockEntity; import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.HatchFlags; -import aztech.modern_industrialization.machines.multiblocks.HatchType; -import java.util.Locale; +import aztech.modern_industrialization.machines.multiblocks.SimpleMember; +import java.util.List; +import java.util.function.Predicate; import net.minecraft.core.BlockPos; import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; @@ -38,10 +39,14 @@ import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.Nullable; -public class StructureMultiblockHatchBlockEntity extends FastBlockEntity { +public class StructureMultiblockHatchBlockEntity extends FastBlockEntity implements StructureMemberOverride { + private String inputPreview; + private String inputMembers; private String inputCasing; private String inputFlags; + private BlockState preview; + private List> members; private MachineCasing casing; private HatchFlags flags = HatchFlags.NO_HATCH; @@ -49,6 +54,36 @@ public StructureMultiblockHatchBlockEntity(BlockPos pos, BlockState state) { super(MIRegistries.STRUCTURE_MULTIBLOCK_HATCH_BE.get(), pos, state); } + @Nullable + public String getInputPreview() { + return inputPreview; + } + + public void setInputPreview(String inputPreview) { + this.inputPreview = inputPreview; + preview = StructureMultiblockFormatters.preview(inputPreview); + } + + @Nullable + public BlockState getPreview() { + return preview; + } + + @Nullable + public String getInputMembers() { + return inputMembers; + } + + public void setInputMembers(String inputMembers) { + this.inputMembers = inputMembers; + members = StructureMultiblockFormatters.members(inputMembers); + } + + @Nullable + public List> getMembers() { + return members; + } + @Nullable public String getInputCasing() { return inputCasing; @@ -56,7 +91,7 @@ public String getInputCasing() { public void setInputCasing(String inputCasing) { this.inputCasing = inputCasing; - casing = formatCasing(inputCasing); + casing = StructureMultiblockFormatters.casing(inputCasing); } @Nullable @@ -66,7 +101,7 @@ public String getInputFlags() { public void setInputFlags(String inputFlags) { this.inputFlags = inputFlags; - flags = formatFlags(inputFlags); + flags = StructureMultiblockFormatters.hatchFlags(inputFlags); } @Nullable @@ -79,30 +114,22 @@ public HatchFlags getFlags() { return flags; } - @Nullable - public static MachineCasing formatCasing(String input) { - return StructureMultiblockControllerBlockEntity.formatCasing(input); + @Override + public SimpleMember getMemberOverride() { + return SimpleMember.anyOf(members, preview); } - @Nullable - public static HatchFlags formatFlags(String input) { - if (input == null || input.isEmpty()) { - return HatchFlags.NO_HATCH; - } - HatchFlags.Builder builder = new HatchFlags.Builder(); - for (String part : input.split(";")) { - try { - builder.with(Integer.parseInt(part)); - } catch (NumberFormatException ignored) { - try { - HatchType hatchType = HatchType.valueOf(part.toUpperCase(Locale.ROOT)); - builder.with(hatchType); - } catch (IllegalArgumentException ignored2) { - return null; - } - } - } - return builder.build(); + @Override + public HatchFlags getHatchFlagsOverride() { + return flags; + } + + @Override + public boolean isConfigurationValid() { + return preview != null && + members != null && !members.isEmpty() && + casing != null && + flags != null; } @Override @@ -120,6 +147,12 @@ public CompoundTag getUpdateTag(HolderLookup.Provider registries) { @Override protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { super.saveAdditional(tag, registries); + if (inputPreview != null) { + tag.putString("preview", inputPreview); + } + if (inputMembers != null) { + tag.putString("members", inputMembers); + } if (inputCasing != null) { tag.putString("casing", inputCasing); } @@ -129,9 +162,16 @@ protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) } @Override - protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { - super.loadAdditional(tag, registries); + public void loadStructureData(CompoundTag tag) { + this.setInputPreview(tag.getString("preview")); + this.setInputMembers(tag.getString("members")); this.setInputCasing(tag.getString("casing")); this.setInputFlags(tag.getString("flags")); } + + @Override + protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.loadAdditional(tag, registries); + this.loadStructureData(tag); + } } diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java index 609fab899..e5f865206 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java @@ -25,25 +25,19 @@ import aztech.modern_industrialization.MIRegistries; import aztech.modern_industrialization.blocks.FastBlockEntity; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import java.util.ArrayList; +import aztech.modern_industrialization.machines.multiblocks.SimpleMember; import java.util.List; import java.util.function.Predicate; -import net.minecraft.commands.arguments.blocks.BlockStateParser; import net.minecraft.core.BlockPos; import net.minecraft.core.HolderLookup; -import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.game.ClientGamePacketListener; import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.tags.BlockTags; -import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.Nullable; -public class StructureMultiblockMemberBlockEntity extends FastBlockEntity { +public class StructureMultiblockMemberBlockEntity extends FastBlockEntity implements StructureMemberOverride { private String inputPreview; private String inputMembers; @@ -61,7 +55,7 @@ public String getInputPreview() { public void setInputPreview(String inputPreview) { this.inputPreview = inputPreview; - preview = formatPreview(inputPreview); + preview = StructureMultiblockFormatters.preview(inputPreview); } @Nullable @@ -74,10 +68,9 @@ public String getInputMembers() { return inputMembers; } - public void setInputMembers(String inputPreview, String inputMembers) { - this.inputPreview = inputPreview; + public void setInputMembers(String inputMembers) { this.inputMembers = inputMembers; - members = formatMembers(inputMembers); + members = StructureMultiblockFormatters.members(inputMembers); } @Nullable @@ -85,47 +78,15 @@ public List> getMembers() { return members; } - @Nullable - public static BlockState formatPreview(String inputPreview) { - if (inputPreview == null || inputPreview.isEmpty()) { - return Blocks.AIR.defaultBlockState(); - } - var registry = BuiltInRegistries.BLOCK.asLookup(); - - try { - var blockResult = BlockStateParser.parseForBlock(registry, inputPreview, true); - return blockResult.blockState(); - } catch (CommandSyntaxException ignored) { - return null; - } + @Override + public SimpleMember getMemberOverride() { + return SimpleMember.anyOf(members, preview); } - @Nullable - public static List> formatMembers(String inputMembers) { - if (inputMembers == null || inputMembers.isEmpty()) { - return new ArrayList<>(); - } - var registry = BuiltInRegistries.BLOCK.asLookup(); - - List> predicates = new ArrayList<>(); - for (String part : inputMembers.split(";")) { - if (part.startsWith("#")) { - ResourceLocation tagId = ResourceLocation.tryParse(part.substring(1)); - if (tagId == null) { - return null; - } - var tag = BlockTags.create(tagId); - predicates.add(state -> state.is(tag)); - } else { - try { - var blockResult = BlockStateParser.parseForBlock(registry, part, true); - predicates.add(state -> state == blockResult.blockState()); - } catch (CommandSyntaxException ignored) { - return null; - } - } - } - return predicates; + @Override + public boolean isConfigurationValid() { + return preview != null && + members != null && !members.isEmpty(); } @Override @@ -151,9 +112,15 @@ protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) } } + @Override + public void loadStructureData(CompoundTag tag) { + this.setInputPreview(tag.getString("preview")); + this.setInputMembers(tag.getString("members")); + } + @Override protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { super.loadAdditional(tag, registries); - this.setInputMembers(tag.getString("preview"), tag.getString("members")); + this.loadStructureData(tag); } } diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java index 3388170a9..bfc0d7a4c 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java @@ -31,7 +31,6 @@ import io.netty.buffer.ByteBuf; import net.minecraft.ChatFormatting; import net.minecraft.core.BlockPos; -import net.minecraft.nbt.CompoundTag; import net.minecraft.network.codec.StreamCodec; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; @@ -59,15 +58,17 @@ public void handle(Context ctx) { BlockState state = level.getBlockState(pos); BlockEntity blockEntity = level.getBlockEntity(pos); if (blockEntity instanceof StructureMultiblockControllerBlockEntity controller) { - if (controller.getBounds().isEmpty()) { - player.sendSystemMessage(MIText.StructureMultiblockSaveFailNoBounds.text().withStyle(ChatFormatting.RED)); - return; - } // TODO dont do this on dedicated server maybe? - CompoundTag tag = MIStructureTemplateManager.fromWorld(level, pos, state.getValue(StructureMultiblockControllerBlock.FACING), - controller.getBounds()); - if (!MIStructureTemplateManager.save(controller.getId(), tag)) { - player.sendSystemMessage(MIText.StructureMultiblockSaveFailUnknown.text().withStyle(ChatFormatting.RED)); + MIStructureTemplateManager.FromWorldResult result = MIStructureTemplateManager.fromWorld(level, pos, + state.getValue(StructureMultiblockControllerBlock.FACING), controller.getBounds()); + if (result.isSuccess()) { + if (!MIStructureTemplateManager.save(controller.getId(), result.tag())) { + player.sendSystemMessage(MIText.StructureMultiblockSaveFailUnknown.text().withStyle(ChatFormatting.RED)); + } else { + player.sendSystemMessage(result.text(controller.getId().toString())); + } + } else { + player.sendSystemMessage(result.text().withStyle(ChatFormatting.RED)); } } } diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateHatchPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateHatchPacket.java index e20d1f574..51ae4004c 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateHatchPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateHatchPacket.java @@ -33,12 +33,17 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; -public record StructureUpdateHatchPacket(BlockPos pos, String inputCasing, String inputFlags) implements BasePacket { +public record StructureUpdateHatchPacket(BlockPos pos, String inputPreview, String inputMembers, String inputCasing, String inputFlags) + implements BasePacket { public static final StreamCodec STREAM_CODEC = StreamCodec.composite( BlockPos.STREAM_CODEC, StructureUpdateHatchPacket::pos, ByteBufCodecs.STRING_UTF8, + StructureUpdateHatchPacket::inputPreview, + ByteBufCodecs.STRING_UTF8, + StructureUpdateHatchPacket::inputMembers, + ByteBufCodecs.STRING_UTF8, StructureUpdateHatchPacket::inputCasing, ByteBufCodecs.STRING_UTF8, StructureUpdateHatchPacket::inputFlags, @@ -57,6 +62,8 @@ public void handle(Context ctx) { BlockEntity blockEntity = level.getBlockEntity(pos); if (blockEntity instanceof StructureMultiblockHatchBlockEntity hatch) { + hatch.setInputPreview(inputPreview); + hatch.setInputMembers(inputMembers); hatch.setInputCasing(inputCasing); hatch.setInputFlags(inputFlags); diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java index 4f95789a2..f24f4906a 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java @@ -57,7 +57,8 @@ public void handle(Context ctx) { BlockEntity blockEntity = level.getBlockEntity(pos); if (blockEntity instanceof StructureMultiblockMemberBlockEntity member) { - member.setInputMembers(inputPreview, inputMembers); + member.setInputPreview(inputPreview); + member.setInputMembers(inputMembers); member.sync(); member.setChanged(); diff --git a/src/main/java/aztech/modern_industrialization/structure/MIStructureTemplateManager.java b/src/main/java/aztech/modern_industrialization/structure/MIStructureTemplateManager.java index 804f09c0d..a09ea5b65 100644 --- a/src/main/java/aztech/modern_industrialization/structure/MIStructureTemplateManager.java +++ b/src/main/java/aztech/modern_industrialization/structure/MIStructureTemplateManager.java @@ -23,22 +23,14 @@ */ package aztech.modern_industrialization.structure; -import static aztech.modern_industrialization.machines.multiblocks.ShapeMatcher.*; - import aztech.modern_industrialization.MI; +import aztech.modern_industrialization.MIText; import aztech.modern_industrialization.blocks.structure.StructureControllerBounds; +import aztech.modern_industrialization.blocks.structure.StructureMemberOverride; import aztech.modern_industrialization.machines.models.MachineCasing; +import aztech.modern_industrialization.machines.multiblocks.HatchFlags; import aztech.modern_industrialization.machines.multiblocks.ShapeTemplate; import aztech.modern_industrialization.machines.multiblocks.SimpleMember; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; import net.minecraft.FileUtil; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -49,19 +41,88 @@ import net.minecraft.nbt.NbtIo; import net.minecraft.nbt.NbtUtils; import net.minecraft.nbt.Tag; +import net.minecraft.network.chat.MutableComponent; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.FastBufferedInputStream; import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.levelgen.structure.BoundingBox; import net.neoforged.fml.loading.FMLPaths; import org.jetbrains.annotations.Nullable; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import static aztech.modern_industrialization.machines.multiblocks.ShapeMatcher.*; + public final class MIStructureTemplateManager { - public static CompoundTag fromWorld(Level level, BlockPos controllerPos, Direction controllerDirection, StructureControllerBounds bounds) { + public enum ValidationResult { + INVALID_BOUNDS(false, MIText.StructureMultiblockSaveFailInvalidBounds), + MISCONFIGURED_BLOCK(false, MIText.StructureMultiblockSaveFailMisconfiguredBlock), + TOO_MANY_CONTROLLERS(false, MIText.StructureMultiblockSaveFailTooManyControllers), + NO_CONTROLLER(false, MIText.StructureMultiblockSaveFailNoController), + NO_HATCHES(false, MIText.StructureMultiblockSaveFailNoHatches), + SUCCESS(true, MIText.StructureMultiblockSaveSuccess); + + private final boolean success; + private final MIText text; + + ValidationResult(boolean success, MIText text) { + this.success = success; + this.text = text; + } + + public boolean isSuccess() { + return success; + } + + public MIText text() { + return text; + } + } + + public record FromWorldResult(CompoundTag tag, ValidationResult result, Object... args) { + public FromWorldResult { + Objects.requireNonNull(result); + if (tag == null && result.isSuccess()) { + throw new IllegalArgumentException("Cannot create successful result with no tag"); + } + } + + public FromWorldResult(ValidationResult result, Object... args) { + this(null, result, args); + } + + public FromWorldResult(CompoundTag tag, Object... args) { + this(tag, ValidationResult.SUCCESS, args); + } + + public boolean isSuccess() { + return result.isSuccess(); + } + + public MutableComponent text(Object... args) { + return result.text().text(args); + } + + public MutableComponent text() { + return this.text(args); + } + } + + public static FromWorldResult fromWorld(Level level, BlockPos controllerPos, Direction controllerDirection, StructureControllerBounds bounds) { if (bounds.isEmpty()) { - throw new IllegalArgumentException("Invalid bounds: %s".formatted(bounds)); + return new FromWorldResult(ValidationResult.INVALID_BOUNDS); } CompoundTag tag = new CompoundTag(); @@ -74,6 +135,9 @@ public static CompoundTag fromWorld(Level level, BlockPos controllerPos, Directi ListTag palette = new ListTag(); ListTag blocks = new ListTag(); + boolean hasController = false; + boolean hasHatch = false; + for (BlockPos pos : BlockPos.betweenClosed(minPos, maxPos)) { BlockState state = toTemplateState(level, pos, level.getBlockState(pos), controllerDirection); @@ -88,18 +152,40 @@ public static CompoundTag fromWorld(Level level, BlockPos controllerPos, Directi int paletteIndex = paletteStates.indexOf(state); blockTag.putInt("state", paletteIndex); + // TODO replace this direct member and hatch data BlockEntity blockEntity = level.getBlockEntity(pos); if (blockEntity != null) { + if (blockEntity instanceof StructureMemberOverride override) { + if (!override.isConfigurationValid()) { + return new FromWorldResult(ValidationResult.MISCONFIGURED_BLOCK, pos.toShortString()); + } + if (override.isController()) { + if (hasController) { + return new FromWorldResult(ValidationResult.TOO_MANY_CONTROLLERS); + } + hasController = true; + } + if (override.getHatchFlagsOverride() != null) { + hasHatch = true; + } + } blockTag.put("nbt", blockEntity.saveWithId(level.registryAccess())); } blocks.add(blockTag); } + if (!hasController) { + return new FromWorldResult(ValidationResult.NO_CONTROLLER); + } + if (!hasHatch) { + return new FromWorldResult(ValidationResult.NO_HATCHES); + } + tag.put("palette", palette); tag.put("blocks", blocks); - return tag; + return new FromWorldResult(tag); } public static ShapeTemplate deserialize(MachineCasing hatchCasing, CompoundTag tag) { @@ -118,12 +204,25 @@ public static ShapeTemplate deserialize(MachineCasing hatchCasing, CompoundTag t int paletteIndex = block.getInt("state"); BlockState state = NbtUtils.readBlockState(blockRegistry, palette.getCompound(paletteIndex)); - /* - * TODO: - * - get the simple member from the blockentity if its one of our structure blocks - */ + SimpleMember member = SimpleMember.forBlockState(state); + HatchFlags flags = null; + + // TODO replace this direct member and hatch data + if (block.contains("nbt", Tag.TAG_COMPOUND)) { + CompoundTag nbt = block.getCompound("nbt"); + if (state.getBlock() instanceof EntityBlock entityBlock) { + BlockEntity blockEntity = entityBlock.newBlockEntity(pos, state); + if (blockEntity instanceof StructureMemberOverride override) { + override.loadStructureData(nbt); + member = override.getMemberOverride(); + flags = override.getHatchFlagsOverride(); + } + } + } - builder.add(pos.getX(), pos.getY(), pos.getZ(), SimpleMember.forBlockState(state)); + if (member != null) { + builder.add(pos.getX(), pos.getY(), pos.getZ(), member, flags); + } } return builder.build(); From 8136dda05a5226e6cf9cc3ff18acbbbd2893d314 Mon Sep 17 00:00:00 2001 From: Swedz Date: Fri, 22 Nov 2024 04:19:24 -0500 Subject: [PATCH 11/89] Refactor structure storing format to store members directly --- ...ructureMultiblockControllerEditScreen.java | 2 +- .../StructureMultiblockHatchEditScreen.java | 6 +- .../StructureMultiblockMemberEditScreen.java | 6 +- .../structure/StructureMemberOverride.java | 12 +- ...uctureMultiblockControllerBlockEntity.java | 14 +-- .../StructureMultiblockHatchBlockEntity.java | 27 ++-- .../StructureMultiblockMemberBlockEntity.java | 22 ++-- .../debug/DebugCommands.java | 5 +- .../machines/multiblocks/HatchFlags.java | 7 +- .../machines/multiblocks/SimpleMember.java | 14 +-- .../structure/MIStructureTemplateManager.java | 118 ++++++++---------- .../StructureMultiblockFormatters.java | 16 +-- .../structure/member/StructureMember.java | 117 +++++++++++++++++ .../structure/member/StructureMemberTest.java | 52 ++++++++ .../member/StructureMemberTestState.java | 70 +++++++++++ .../member/StructureMemberTestTag.java | 72 +++++++++++ .../StructureSaveControllerPacket.java | 2 +- 17 files changed, 419 insertions(+), 143 deletions(-) rename src/main/java/aztech/modern_industrialization/{ => machines/multiblocks}/structure/MIStructureTemplateManager.java (75%) rename src/main/java/aztech/modern_industrialization/{blocks => machines/multiblocks}/structure/StructureMultiblockFormatters.java (87%) create mode 100644 src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java create mode 100644 src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTest.java create mode 100644 src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestState.java create mode 100644 src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestTag.java diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java index 604348b3c..90e4c4b68 100644 --- a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java @@ -27,8 +27,8 @@ import aztech.modern_industrialization.MIText; import aztech.modern_industrialization.blocks.structure.StructureControllerBounds; import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlockEntity; -import aztech.modern_industrialization.blocks.structure.StructureMultiblockFormatters; import aztech.modern_industrialization.machines.models.MachineCasing; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockFormatters; import aztech.modern_industrialization.network.structure.StructureSaveControllerPacket; import aztech.modern_industrialization.network.structure.StructureUpdateControllerPacket; import com.mojang.blaze3d.platform.InputConstants; diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockHatchEditScreen.java b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockHatchEditScreen.java index dcd653d1f..ec74d57fa 100644 --- a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockHatchEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockHatchEditScreen.java @@ -25,15 +25,15 @@ import aztech.modern_industrialization.MIBlock; import aztech.modern_industrialization.MIText; -import aztech.modern_industrialization.blocks.structure.StructureMultiblockFormatters; import aztech.modern_industrialization.blocks.structure.StructureMultiblockHatchBlockEntity; import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.HatchFlags; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockFormatters; +import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMemberTest; import aztech.modern_industrialization.network.structure.StructureUpdateHatchPacket; import com.mojang.blaze3d.platform.InputConstants; import java.util.List; import java.util.Optional; -import java.util.function.Predicate; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; @@ -68,7 +68,7 @@ private Optional getPreview() { return Optional.ofNullable(StructureMultiblockFormatters.preview(previewBox.getValue())); } - private Optional>> getMembers() { + private Optional> getMembers() { return Optional.ofNullable(StructureMultiblockFormatters.members(membersBox.getValue())); } diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java index 11a79a5e4..0f32c95a9 100644 --- a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java @@ -25,13 +25,13 @@ import aztech.modern_industrialization.MIBlock; import aztech.modern_industrialization.MIText; -import aztech.modern_industrialization.blocks.structure.StructureMultiblockFormatters; import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlockEntity; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockFormatters; +import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMemberTest; import aztech.modern_industrialization.network.structure.StructureUpdateMemberPacket; import com.mojang.blaze3d.platform.InputConstants; import java.util.List; import java.util.Optional; -import java.util.function.Predicate; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; @@ -62,7 +62,7 @@ private Optional getPreview() { return Optional.ofNullable(StructureMultiblockFormatters.preview(previewBox.getValue())); } - private Optional>> getMembers() { + private Optional> getMembers() { return Optional.ofNullable(StructureMultiblockFormatters.members(membersBox.getValue())); } diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMemberOverride.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMemberOverride.java index 29d2530a5..b2c8f1e28 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMemberOverride.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMemberOverride.java @@ -23,22 +23,14 @@ */ package aztech.modern_industrialization.blocks.structure; -import aztech.modern_industrialization.machines.multiblocks.HatchFlags; -import aztech.modern_industrialization.machines.multiblocks.SimpleMember; -import net.minecraft.nbt.CompoundTag; +import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; public interface StructureMemberOverride { default boolean isController() { return false; } - SimpleMember getMemberOverride(); - - default HatchFlags getHatchFlagsOverride() { - return null; - } + StructureMember getMemberOverride(); boolean isConfigurationValid(); - - void loadStructureData(CompoundTag tag); } diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java index 55907bd9a..5f29a2060 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java @@ -26,7 +26,8 @@ import aztech.modern_industrialization.MIRegistries; import aztech.modern_industrialization.blocks.FastBlockEntity; import aztech.modern_industrialization.machines.models.MachineCasing; -import aztech.modern_industrialization.machines.multiblocks.SimpleMember; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockFormatters; +import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; import net.minecraft.core.BlockPos; import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; @@ -99,7 +100,7 @@ public boolean isController() { } @Override - public SimpleMember getMemberOverride() { + public StructureMember getMemberOverride() { return null; } @@ -137,7 +138,8 @@ protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) } @Override - public void loadStructureData(CompoundTag tag) { + protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.loadAdditional(tag, registries); this.setInputId(tag.getString("structure_id")); this.setInputCasing(tag.getString("casing")); if (tag.contains("bounds", Tag.TAG_COMPOUND)) { @@ -152,10 +154,4 @@ public void loadStructureData(CompoundTag tag) { } showBounds = tag.getBoolean("show_bounds"); } - - @Override - protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { - super.loadAdditional(tag, registries); - this.loadStructureData(tag); - } } diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlockEntity.java index 9ba4af5ce..1de46eb11 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlockEntity.java @@ -27,9 +27,10 @@ import aztech.modern_industrialization.blocks.FastBlockEntity; import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.HatchFlags; -import aztech.modern_industrialization.machines.multiblocks.SimpleMember; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockFormatters; +import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; +import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMemberTest; import java.util.List; -import java.util.function.Predicate; import net.minecraft.core.BlockPos; import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; @@ -46,7 +47,7 @@ public class StructureMultiblockHatchBlockEntity extends FastBlockEntity impleme private String inputFlags; private BlockState preview; - private List> members; + private List members; private MachineCasing casing; private HatchFlags flags = HatchFlags.NO_HATCH; @@ -80,7 +81,7 @@ public void setInputMembers(String inputMembers) { } @Nullable - public List> getMembers() { + public List getMembers() { return members; } @@ -115,13 +116,8 @@ public HatchFlags getFlags() { } @Override - public SimpleMember getMemberOverride() { - return SimpleMember.anyOf(members, preview); - } - - @Override - public HatchFlags getHatchFlagsOverride() { - return flags; + public StructureMember getMemberOverride() { + return new StructureMember(preview, members, flags); } @Override @@ -162,16 +158,11 @@ protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) } @Override - public void loadStructureData(CompoundTag tag) { + protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.loadAdditional(tag, registries); this.setInputPreview(tag.getString("preview")); this.setInputMembers(tag.getString("members")); this.setInputCasing(tag.getString("casing")); this.setInputFlags(tag.getString("flags")); } - - @Override - protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { - super.loadAdditional(tag, registries); - this.loadStructureData(tag); - } } diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java index e5f865206..49a679747 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java @@ -25,9 +25,10 @@ import aztech.modern_industrialization.MIRegistries; import aztech.modern_industrialization.blocks.FastBlockEntity; -import aztech.modern_industrialization.machines.multiblocks.SimpleMember; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockFormatters; +import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; +import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMemberTest; import java.util.List; -import java.util.function.Predicate; import net.minecraft.core.BlockPos; import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; @@ -42,7 +43,7 @@ public class StructureMultiblockMemberBlockEntity extends FastBlockEntity implem private String inputMembers; private BlockState preview; - private List> members; + private List members; public StructureMultiblockMemberBlockEntity(BlockPos pos, BlockState state) { super(MIRegistries.STRUCTURE_MULTIBLOCK_MEMBER_BE.get(), pos, state); @@ -74,13 +75,13 @@ public void setInputMembers(String inputMembers) { } @Nullable - public List> getMembers() { + public List getMembers() { return members; } @Override - public SimpleMember getMemberOverride() { - return SimpleMember.anyOf(members, preview); + public StructureMember getMemberOverride() { + return new StructureMember(preview, members, null); } @Override @@ -112,15 +113,10 @@ protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) } } - @Override - public void loadStructureData(CompoundTag tag) { - this.setInputPreview(tag.getString("preview")); - this.setInputMembers(tag.getString("members")); - } - @Override protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { super.loadAdditional(tag, registries); - this.loadStructureData(tag); + this.setInputPreview(tag.getString("preview")); + this.setInputMembers(tag.getString("members")); } } diff --git a/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java b/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java index cbb8d8a28..e2222a204 100644 --- a/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java +++ b/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java @@ -27,17 +27,18 @@ import static net.minecraft.commands.arguments.ResourceLocationArgument.*; import static net.minecraft.commands.arguments.coordinates.BlockPosArgument.*; +import aztech.modern_industrialization.MIBlock; import aztech.modern_industrialization.MIConfig; import aztech.modern_industrialization.machines.MachineBlockEntity; import aztech.modern_industrialization.machines.models.MachineCasings; import aztech.modern_industrialization.machines.multiblocks.MultiblockMachineBlockEntity; import aztech.modern_industrialization.machines.multiblocks.ShapeMatcher; import aztech.modern_industrialization.machines.multiblocks.ShapeTemplate; +import aztech.modern_industrialization.machines.multiblocks.structure.MIStructureTemplateManager; import aztech.modern_industrialization.pipes.MIPipes; import aztech.modern_industrialization.pipes.api.PipeNetworkType; import aztech.modern_industrialization.pipes.impl.PipeNetworks; import aztech.modern_industrialization.stats.PlayerStatisticsData; -import aztech.modern_industrialization.structure.MIStructureTemplateManager; import com.mojang.brigadier.Command; import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; @@ -196,7 +197,7 @@ private static int buildMultiblock(CommandSourceStack src, BlockPos controllerPo private static int testStructure(CommandSourceStack src, ResourceLocation id, BlockPos controllerPos) { BlockState controllerState = src.getLevel().getBlockState(controllerPos); - if (controllerState.hasProperty(BlockStateProperties.HORIZONTAL_FACING)) { + if (controllerState.is(MIBlock.STRUCTURE_MULTIBLOCK_CONTROLLER.get())) { CompoundTag tag = MIStructureTemplateManager.load(id); if (tag == null) { src.sendFailure(Component.literal("Could not find structure by the id '%s'".formatted(id))); diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/HatchFlags.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/HatchFlags.java index e47578061..425244ced 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/HatchFlags.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/HatchFlags.java @@ -26,7 +26,7 @@ public class HatchFlags { public static final HatchFlags NO_HATCH = new Builder().build(); - private final int flags; + public final int flags; public HatchFlags(int flags) { this.flags = flags; @@ -36,6 +36,11 @@ public boolean allows(HatchType type) { return (flags & (1 << type.getId())) > 0; } + @Override + public boolean equals(Object o) { + return o instanceof HatchFlags other && flags == other.flags; + } + public static class Builder { private int flags = 0; diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/SimpleMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/SimpleMember.java index 2cd58ff1b..4a5d93ae8 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/SimpleMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/SimpleMember.java @@ -23,9 +23,9 @@ */ package aztech.modern_industrialization.machines.multiblocks; +import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMemberTest; import java.util.Collection; import java.util.Objects; -import java.util.function.Predicate; import java.util.function.Supplier; import net.minecraft.core.Direction; import net.minecraft.core.registries.BuiltInRegistries; @@ -94,18 +94,18 @@ public BlockState getPreviewState() { }; } - static SimpleMember anyOf(Collection> predicates, BlockState preview) { - Objects.requireNonNull(predicates); - if (predicates.isEmpty()) { - throw new IllegalArgumentException("Cannot use empty predicate collection"); + static SimpleMember anyOf(Collection members, BlockState preview) { + Objects.requireNonNull(members); + if (members.isEmpty()) { + throw new IllegalArgumentException("Cannot use empty member collection"); } Objects.requireNonNull(preview); return new SimpleMember() { @Override public boolean matchesState(BlockState state) { - for (Predicate predicate : predicates) { - if (predicate.test(state)) { + for (StructureMemberTest member : members) { + if (member.matchesState(state)) { return true; } } diff --git a/src/main/java/aztech/modern_industrialization/structure/MIStructureTemplateManager.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java similarity index 75% rename from src/main/java/aztech/modern_industrialization/structure/MIStructureTemplateManager.java rename to src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java index a09ea5b65..170d92ecc 100644 --- a/src/main/java/aztech/modern_industrialization/structure/MIStructureTemplateManager.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java @@ -21,16 +21,27 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package aztech.modern_industrialization.structure; +package aztech.modern_industrialization.machines.multiblocks.structure; + +import static aztech.modern_industrialization.machines.multiblocks.ShapeMatcher.*; import aztech.modern_industrialization.MI; import aztech.modern_industrialization.MIText; import aztech.modern_industrialization.blocks.structure.StructureControllerBounds; import aztech.modern_industrialization.blocks.structure.StructureMemberOverride; import aztech.modern_industrialization.machines.models.MachineCasing; -import aztech.modern_industrialization.machines.multiblocks.HatchFlags; import aztech.modern_industrialization.machines.multiblocks.ShapeTemplate; -import aztech.modern_industrialization.machines.multiblocks.SimpleMember; +import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; import net.minecraft.FileUtil; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -45,26 +56,12 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.util.FastBufferedInputStream; import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.levelgen.structure.BoundingBox; import net.neoforged.fml.loading.FMLPaths; import org.jetbrains.annotations.Nullable; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -import static aztech.modern_industrialization.machines.multiblocks.ShapeMatcher.*; - public final class MIStructureTemplateManager { public enum ValidationResult { INVALID_BOUNDS(false, MIText.StructureMultiblockSaveFailInvalidBounds), @@ -131,9 +128,9 @@ public static FromWorldResult fromWorld(Level level, BlockPos controllerPos, Dir BlockPos minPos = controllerPos.offset(boundsBox.minX(), boundsBox.minY(), boundsBox.minZ()); BlockPos maxPos = controllerPos.offset(boundsBox.maxX(), boundsBox.maxY(), boundsBox.maxZ()); - List paletteStates = new ArrayList<>(); - ListTag palette = new ListTag(); - ListTag blocks = new ListTag(); + List members = new ArrayList<>(); + ListTag membersTag = new ListTag(); + ListTag blocksTag = new ListTag(); boolean hasController = false; boolean hasHatch = false; @@ -145,34 +142,36 @@ public static FromWorldResult fromWorld(Level level, BlockPos controllerPos, Dir blockTag.put("pos", NbtUtils.writeBlockPos(toTemplatePos(controllerPos, controllerDirection, pos))); - if (!paletteStates.contains(state)) { - paletteStates.add(state); - palette.add(NbtUtils.writeBlockState(state)); - } - int paletteIndex = paletteStates.indexOf(state); - blockTag.putInt("state", paletteIndex); + StructureMember member = new StructureMember(state); - // TODO replace this direct member and hatch data BlockEntity blockEntity = level.getBlockEntity(pos); - if (blockEntity != null) { - if (blockEntity instanceof StructureMemberOverride override) { - if (!override.isConfigurationValid()) { - return new FromWorldResult(ValidationResult.MISCONFIGURED_BLOCK, pos.toShortString()); - } - if (override.isController()) { - if (hasController) { - return new FromWorldResult(ValidationResult.TOO_MANY_CONTROLLERS); - } - hasController = true; - } - if (override.getHatchFlagsOverride() != null) { - hasHatch = true; + if (blockEntity instanceof StructureMemberOverride override) { + if (!override.isConfigurationValid()) { + return new FromWorldResult(ValidationResult.MISCONFIGURED_BLOCK, pos.toShortString()); + } + if (override.isController()) { + if (hasController) { + return new FromWorldResult(ValidationResult.TOO_MANY_CONTROLLERS); } + hasController = true; + } + member = override.getMemberOverride(); + } + + if (member != null) { + if (member.hatchFlags() != null) { + hasHatch = true; + } + CompoundTag memberTag = new CompoundTag(); + member.save(memberTag); + if (!members.contains(member)) { + members.add(member); + membersTag.add(memberTag); } - blockTag.put("nbt", blockEntity.saveWithId(level.registryAccess())); + blockTag.putInt("member_index", members.indexOf(member)); } - blocks.add(blockTag); + blocksTag.add(blockTag); } if (!hasController) { @@ -182,8 +181,8 @@ public static FromWorldResult fromWorld(Level level, BlockPos controllerPos, Dir return new FromWorldResult(ValidationResult.NO_HATCHES); } - tag.put("palette", palette); - tag.put("blocks", blocks); + tag.put("members", membersTag); + tag.put("blocks", blocksTag); return new FromWorldResult(tag); } @@ -193,35 +192,18 @@ public static ShapeTemplate deserialize(MachineCasing hatchCasing, CompoundTag t ShapeTemplate.Builder builder = new ShapeTemplate.Builder(hatchCasing); - ListTag palette = tag.getList("palette", Tag.TAG_COMPOUND); + ListTag members = tag.getList("members", Tag.TAG_COMPOUND); ListTag blocks = tag.getList("blocks", Tag.TAG_COMPOUND); for (int i = 0; i < blocks.size(); i++) { - CompoundTag block = blocks.getCompound(i); - - BlockPos pos = NbtUtils.readBlockPos(block, "pos").orElseThrow(); - - int paletteIndex = block.getInt("state"); - BlockState state = NbtUtils.readBlockState(blockRegistry, palette.getCompound(paletteIndex)); + CompoundTag blockTag = blocks.getCompound(i); - SimpleMember member = SimpleMember.forBlockState(state); - HatchFlags flags = null; + BlockPos pos = NbtUtils.readBlockPos(blockTag, "pos").orElseThrow(); - // TODO replace this direct member and hatch data - if (block.contains("nbt", Tag.TAG_COMPOUND)) { - CompoundTag nbt = block.getCompound("nbt"); - if (state.getBlock() instanceof EntityBlock entityBlock) { - BlockEntity blockEntity = entityBlock.newBlockEntity(pos, state); - if (blockEntity instanceof StructureMemberOverride override) { - override.loadStructureData(nbt); - member = override.getMemberOverride(); - flags = override.getHatchFlagsOverride(); - } - } - } - - if (member != null) { - builder.add(pos.getX(), pos.getY(), pos.getZ(), member, flags); + if (blockTag.contains("member_index", Tag.TAG_INT)) { + int memberIndex = blockTag.getInt("member_index"); + StructureMember member = StructureMember.from(members.getCompound(memberIndex)); + builder.add(pos.getX(), pos.getY(), pos.getZ(), member, member.hatchFlags()); } } diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockFormatters.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockFormatters.java similarity index 87% rename from src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockFormatters.java rename to src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockFormatters.java index ae1820d41..efe01cba9 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockFormatters.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockFormatters.java @@ -21,18 +21,20 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package aztech.modern_industrialization.blocks.structure; +package aztech.modern_industrialization.machines.multiblocks.structure; import aztech.modern_industrialization.MI; import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.models.MachineCasings; import aztech.modern_industrialization.machines.multiblocks.HatchFlags; import aztech.modern_industrialization.machines.multiblocks.HatchType; +import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMemberTest; +import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMemberTestState; +import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMemberTestTag; import com.mojang.brigadier.exceptions.CommandSyntaxException; import java.util.ArrayList; import java.util.List; import java.util.Locale; -import java.util.function.Predicate; import net.minecraft.commands.arguments.blocks.BlockStateParser; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceLocation; @@ -78,13 +80,13 @@ public static BlockState preview(String inputPreview) { } @Nullable - public static List> members(String inputMembers) { + public static List members(String inputMembers) { if (inputMembers == null || inputMembers.isEmpty()) { return new ArrayList<>(); } var registry = BuiltInRegistries.BLOCK.asLookup(); - List> predicates = new ArrayList<>(); + List members = new ArrayList<>(); for (String part : inputMembers.split(";")) { if (part.startsWith("#")) { ResourceLocation tagId = ResourceLocation.tryParse(part.substring(1)); @@ -92,17 +94,17 @@ public static List> members(String inputMembers) { return null; } var tag = BlockTags.create(tagId); - predicates.add(state -> state.is(tag)); + members.add(new StructureMemberTestTag(tag)); } else { try { var blockResult = BlockStateParser.parseForBlock(registry, part, true); - predicates.add(state -> state == blockResult.blockState()); + members.add(new StructureMemberTestState(blockResult.blockState())); } catch (CommandSyntaxException ignored) { return null; } } } - return predicates; + return members; } @Nullable diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java new file mode 100644 index 000000000..0d83e722a --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java @@ -0,0 +1,117 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.machines.multiblocks.structure.member; + +import aztech.modern_industrialization.machines.multiblocks.HatchFlags; +import aztech.modern_industrialization.machines.multiblocks.SimpleMember; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.nbt.Tag; +import net.minecraft.world.level.block.state.BlockState; + +public record StructureMember(BlockState preview, List tests, HatchFlags hatchFlags) implements SimpleMember { + public StructureMember(BlockState state) { + this(state, List.of(new StructureMemberTestState(state)), null); + } + + @Override + public boolean matchesState(BlockState state) { + for (StructureMemberTest test : tests) { + if (test.matchesState(state)) { + return true; + } + } + return false; + } + + @Override + public BlockState getPreviewState() { + return preview; + } + + @Override + public boolean equals(Object o) { + if (o instanceof StructureMember other) { + return preview == other.preview() && + tests.containsAll(other.tests()) && other.tests().containsAll(tests) && + Objects.equals(hatchFlags, other.hatchFlags()); + } + return false; + } + + public void save(CompoundTag tag) { + tag.put("preview", NbtUtils.writeBlockState(preview)); + + ListTag testsTag = new ListTag(); + for (StructureMemberTest test : tests) { + CompoundTag testTag = new CompoundTag(); + testTag.putString("id", test.id()); + test.save(testTag); + testsTag.add(testTag); + } + tag.put("tests", testsTag); + + if (hatchFlags != null) { + tag.putInt("hatch_flags", hatchFlags.flags); + } + } + + public static StructureMember from(CompoundTag tag) { + if (tag.isEmpty() || + !tag.contains("preview", Tag.TAG_COMPOUND) || + !tag.contains("tests", Tag.TAG_LIST)) { + return null; + } + + var registry = BuiltInRegistries.BLOCK.asLookup(); + + BlockState preview = NbtUtils.readBlockState(registry, tag.getCompound("preview")); + + ListTag testsTag = tag.getList("tests", Tag.TAG_COMPOUND); + List tests = new ArrayList<>(); + for (int i = 0; i < testsTag.size(); i++) { + CompoundTag testTag = testsTag.getCompound(i); + StructureMemberTest test = StructureMemberTest.from(testTag); + if (test != null) { + tests.add(test); + } + } + if (tests.isEmpty()) { + return null; + } + + int hatchFlagsValue = tag.getInt("hatch_flags"); + HatchFlags hatchFlags = null; + if (hatchFlagsValue != 0) { + hatchFlags = new HatchFlags(hatchFlagsValue); + } + + return new StructureMember(preview, tests, hatchFlags); + } +} diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTest.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTest.java new file mode 100644 index 000000000..6e3b1bf80 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTest.java @@ -0,0 +1,52 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.machines.multiblocks.structure.member; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.Tag; +import net.minecraft.world.level.block.state.BlockState; + +public interface StructureMemberTest { + String id(); + + boolean matchesState(BlockState state); + + void load(CompoundTag tag); + + void save(CompoundTag tag); + + static StructureMemberTest from(CompoundTag tag) { + if (tag.contains("id", Tag.TAG_STRING)) { + String id = tag.getString("id"); + StructureMemberTest member = switch (id) { + case "tag" -> new StructureMemberTestTag(); + case "state" -> new StructureMemberTestState(); + default -> throw new IllegalStateException("Unexpected value: " + id); + }; + member.load(tag); + return member; + } + return null; + } +} diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestState.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestState.java new file mode 100644 index 000000000..4d48c8ec1 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestState.java @@ -0,0 +1,70 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.machines.multiblocks.structure.member; + +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.world.level.block.state.BlockState; + +public class StructureMemberTestState implements StructureMemberTest { + private BlockState blockState; + + public StructureMemberTestState(BlockState blockState) { + this.blockState = blockState; + } + + public StructureMemberTestState() { + this(null); + } + + @Override + public String id() { + return "state"; + } + + @Override + public boolean matchesState(BlockState state) { + return blockState == state; + } + + @Override + public void load(CompoundTag tag) { + var registry = BuiltInRegistries.BLOCK.asLookup(); + blockState = NbtUtils.readBlockState(registry, tag.getCompound("state")); + } + + @Override + public void save(CompoundTag tag) { + tag.put("state", NbtUtils.writeBlockState(blockState)); + } + + @Override + public boolean equals(Object o) { + if (o instanceof StructureMemberTestState other) { + return blockState == other.blockState; + } + return false; + } +} diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestTag.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestTag.java new file mode 100644 index 000000000..2de9bd1f9 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestTag.java @@ -0,0 +1,72 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.machines.multiblocks.structure.member; + +import net.minecraft.core.registries.Registries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagKey; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; + +public class StructureMemberTestTag implements StructureMemberTest { + private TagKey blockTag; + + public StructureMemberTestTag(TagKey blockTag) { + this.blockTag = blockTag; + } + + public StructureMemberTestTag() { + this(null); + } + + @Override + public String id() { + return "tag"; + } + + @Override + public boolean matchesState(BlockState state) { + return blockTag != null && state.is(blockTag); + } + + @Override + public void load(CompoundTag tag) { + blockTag = TagKey.create(Registries.BLOCK, ResourceLocation.parse(tag.getString("tag"))); + } + + @Override + public void save(CompoundTag tag) { + tag.putString("tag", blockTag.location().toString()); + } + + @Override + public boolean equals(Object o) { + if (o instanceof StructureMemberTestTag other) { + return blockTag == other.blockTag || + (blockTag != null && other.blockTag != null && blockTag.location().equals(other.blockTag.location())); + } + return false; + } +} diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java index bfc0d7a4c..f5af86d7f 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java @@ -26,8 +26,8 @@ import aztech.modern_industrialization.MIText; import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlock; import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlockEntity; +import aztech.modern_industrialization.machines.multiblocks.structure.MIStructureTemplateManager; import aztech.modern_industrialization.network.BasePacket; -import aztech.modern_industrialization.structure.MIStructureTemplateManager; import io.netty.buffer.ByteBuf; import net.minecraft.ChatFormatting; import net.minecraft.core.BlockPos; From 5062c9a50d6db5ac339523abfcd3f270ff7637c4 Mon Sep 17 00:00:00 2001 From: Swedz Date: Fri, 22 Nov 2024 04:22:25 -0500 Subject: [PATCH 12/89] Edit todo comments to use my name so I know which ones are mine --- src/main/java/aztech/modern_industrialization/MIBlock.java | 2 +- .../machines/multiblocks/ShapeMatcher.java | 4 ++-- .../network/structure/StructureSaveControllerPacket.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/MIBlock.java b/src/main/java/aztech/modern_industrialization/MIBlock.java index 35cffa635..c65e6bfdf 100644 --- a/src/main/java/aztech/modern_industrialization/MIBlock.java +++ b/src/main/java/aztech/modern_industrialization/MIBlock.java @@ -134,7 +134,7 @@ public static void init(IEventBus modBus) { public static final BlockDefinition CREATIVE_STORAGE_UNIT = block("Creative Storage Unit", "creative_storage_unit", BlockDefinitionParams.defaultStone().withBlockConstructor(CreativeStorageUnitBlock::new)); - // TODO make these blocks not show up in the creative tab and dont give them mineable tags + // TODO SWEDZ: make these blocks not show up in the creative tab and dont give them mineable tags public static final BlockDefinition STRUCTURE_MULTIBLOCK_CONTROLLER = block("Structure Multiblock Controller", "structure_multiblock_controller", BlockDefinitionParams.defaultStone() .withBlockConstructor(StructureMultiblockControllerBlock::new) diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java index 5b0f23974..068d06506 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java @@ -247,9 +247,9 @@ public int buildMultiblock(Level level) { int setBlocks = 0; for (var entry : simpleMembers.entrySet()) { - var current = level.getBlockState(entry.getKey()); // TODO account for rotation + var current = level.getBlockState(entry.getKey()); // TODO SWEDZ: account for rotation if (!entry.getValue().matchesState(current)) { - level.setBlockAndUpdate(entry.getKey(), entry.getValue().getPreviewState()); // TODO account for rotation + level.setBlockAndUpdate(entry.getKey(), entry.getValue().getPreviewState()); // TODO SWEDZ: account for rotation ++setBlocks; } } diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java index f5af86d7f..957591196 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java @@ -58,7 +58,7 @@ public void handle(Context ctx) { BlockState state = level.getBlockState(pos); BlockEntity blockEntity = level.getBlockEntity(pos); if (blockEntity instanceof StructureMultiblockControllerBlockEntity controller) { - // TODO dont do this on dedicated server maybe? + // TODO SWEDZ: dont do this on dedicated server maybe? MIStructureTemplateManager.FromWorldResult result = MIStructureTemplateManager.fromWorld(level, pos, state.getValue(StructureMultiblockControllerBlock.FACING), controller.getBounds()); if (result.isSuccess()) { From f1742c503bb8c1af0b3e8bed157adf36c7875346 Mon Sep 17 00:00:00 2001 From: Swedz Date: Fri, 22 Nov 2024 04:45:39 -0500 Subject: [PATCH 13/89] Respect rotations in ShapeMatcher build multiblock method --- .../machines/multiblocks/ShapeMatcher.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java index 068d06506..6699595f2 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java @@ -23,6 +23,7 @@ */ package aztech.modern_industrialization.machines.multiblocks; +import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; import aztech.modern_industrialization.machines.multiblocks.world.ChunkEventListener; import aztech.modern_industrialization.machines.multiblocks.world.ChunkEventListeners; import java.util.ArrayList; @@ -247,9 +248,14 @@ public int buildMultiblock(Level level) { int setBlocks = 0; for (var entry : simpleMembers.entrySet()) { - var current = level.getBlockState(entry.getKey()); // TODO SWEDZ: account for rotation + BlockPos pos = entry.getKey(); + var current = level.getBlockState(pos); if (!entry.getValue().matchesState(current)) { - level.setBlockAndUpdate(entry.getKey(), entry.getValue().getPreviewState()); // TODO SWEDZ: account for rotation + BlockState state = entry.getValue().getPreviewState(); + if (entry.getValue() instanceof StructureMember) { + state = toWorldState(level, pos, state, controllerDirection); + } + level.setBlockAndUpdate(pos, state); ++setBlocks; } } From c785fe0e1e72994c70832ac270bfc65e52a23908 Mon Sep 17 00:00:00 2001 From: Swedz Date: Fri, 22 Nov 2024 04:46:09 -0500 Subject: [PATCH 14/89] Add structures build command for testing structures --- .../debug/DebugCommands.java | 43 ++++++++++++++----- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java b/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java index e2222a204..6c725a0d6 100644 --- a/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java +++ b/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java @@ -43,6 +43,7 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; import com.mojang.brigadier.suggestion.SuggestionProvider; +import java.util.function.Consumer; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.SharedSuggestionProvider; import net.minecraft.core.BlockPos; @@ -104,12 +105,19 @@ public static void init() { return buildMultiblock(ctx.getSource(), getLoadedBlockPos(ctx, "controller_pos")); })) ) - .then(literal("test_structure") - .then(argument("structure_id", id()) - .then(argument("controller_pos", blockPos()) - .executes(ctx -> { - return testStructure(ctx.getSource(), getId(ctx, "structure_id"), getLoadedBlockPos(ctx, "controller_pos")); - })))) + .then(literal("structures") + .then(literal("test") + .then(argument("structure_id", id()) + .then(argument("controller_pos", blockPos()) + .executes(ctx -> { + return structuresTest(ctx.getSource(), getId(ctx, "structure_id"), getLoadedBlockPos(ctx, "controller_pos")); + })))) + .then(literal("build") + .then(argument("structure_id", id()) + .then(argument("controller_pos", blockPos()) + .executes(ctx -> { + return structuresBuild(ctx.getSource(), getId(ctx, "structure_id"), getLoadedBlockPos(ctx, "controller_pos")); + }))))) ) ); }); @@ -195,7 +203,7 @@ private static int buildMultiblock(CommandSourceStack src, BlockPos controllerPo return Command.SINGLE_SUCCESS; } - private static int testStructure(CommandSourceStack src, ResourceLocation id, BlockPos controllerPos) { + private static int structures(CommandSourceStack src, ResourceLocation id, BlockPos controllerPos, Consumer action) { BlockState controllerState = src.getLevel().getBlockState(controllerPos); if (controllerState.is(MIBlock.STRUCTURE_MULTIBLOCK_CONTROLLER.get())) { CompoundTag tag = MIStructureTemplateManager.load(id); @@ -206,11 +214,26 @@ private static int testStructure(CommandSourceStack src, ResourceLocation id, Bl ShapeTemplate shape = MIStructureTemplateManager.deserialize(MachineCasings.CLEAN_STAINLESS_STEEL, tag); ShapeMatcher matcher = new ShapeMatcher(src.getLevel(), controllerPos, controllerState.getValue(BlockStateProperties.HORIZONTAL_FACING), shape); - matcher.rematch(src.getLevel()); - src.sendSuccess(() -> Component.literal("Match test results: %s".formatted(matcher.isMatchSuccessful())), true); + action.accept(matcher); } else { - src.sendFailure(Component.literal("Block at position %s is not a controller.".formatted(controllerPos))); + src.sendFailure(Component.literal("Block at position %s is not a structure controller.".formatted(controllerPos.toShortString()))); } return Command.SINGLE_SUCCESS; } + + private static int structuresTest(CommandSourceStack src, ResourceLocation id, BlockPos controllerPos) { + return structures(src, id, controllerPos, (matcher) -> { + matcher.rematch(src.getLevel()); + boolean success = matcher.isMatchSuccessful(); + matcher.unlinkHatches(); + src.sendSuccess(() -> Component.literal("Match test results for %s at position %s: %s".formatted(id.toString(), controllerPos.toShortString(), success)), true); + }); + } + + private static int structuresBuild(CommandSourceStack src, ResourceLocation id, BlockPos controllerPos) { + return structures(src, id, controllerPos, (matcher) -> { + matcher.buildMultiblock(src.getLevel()); + src.sendSuccess(() -> Component.literal("Built multiblock %s at position %s".formatted(id.toString(), controllerPos.toShortString())), true); + }); + } } From 298508125d10c184271a19c9fe111d1bfa347d66 Mon Sep 17 00:00:00 2001 From: Swedz Date: Fri, 22 Nov 2024 04:56:55 -0500 Subject: [PATCH 15/89] Spotless --- .../modern_industrialization/debug/DebugCommands.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java b/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java index 6c725a0d6..360452a5c 100644 --- a/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java +++ b/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java @@ -226,14 +226,18 @@ private static int structuresTest(CommandSourceStack src, ResourceLocation id, B matcher.rematch(src.getLevel()); boolean success = matcher.isMatchSuccessful(); matcher.unlinkHatches(); - src.sendSuccess(() -> Component.literal("Match test results for %s at position %s: %s".formatted(id.toString(), controllerPos.toShortString(), success)), true); + src.sendSuccess( + () -> Component + .literal("Match test results for %s at position %s: %s".formatted(id.toString(), controllerPos.toShortString(), success)), + true); }); } private static int structuresBuild(CommandSourceStack src, ResourceLocation id, BlockPos controllerPos) { return structures(src, id, controllerPos, (matcher) -> { matcher.buildMultiblock(src.getLevel()); - src.sendSuccess(() -> Component.literal("Built multiblock %s at position %s".formatted(id.toString(), controllerPos.toShortString())), true); + src.sendSuccess(() -> Component.literal("Built multiblock %s at position %s".formatted(id.toString(), controllerPos.toShortString())), + true); }); } } From 433b30cc3067a226ee1398ea632b5cf0a5194a67 Mon Sep 17 00:00:00 2001 From: Swedz Date: Fri, 22 Nov 2024 04:58:06 -0500 Subject: [PATCH 16/89] Make structure blocks indestructible --- .../modern_industrialization/MIBlock.java | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/MIBlock.java b/src/main/java/aztech/modern_industrialization/MIBlock.java index c65e6bfdf..39cecd7d3 100644 --- a/src/main/java/aztech/modern_industrialization/MIBlock.java +++ b/src/main/java/aztech/modern_industrialization/MIBlock.java @@ -134,9 +134,8 @@ public static void init(IEventBus modBus) { public static final BlockDefinition CREATIVE_STORAGE_UNIT = block("Creative Storage Unit", "creative_storage_unit", BlockDefinitionParams.defaultStone().withBlockConstructor(CreativeStorageUnitBlock::new)); - // TODO SWEDZ: make these blocks not show up in the creative tab and dont give them mineable tags public static final BlockDefinition STRUCTURE_MULTIBLOCK_CONTROLLER = block("Structure Multiblock Controller", - "structure_multiblock_controller", BlockDefinitionParams.defaultStone() + "structure_multiblock_controller", BlockDefinitionParams.defaultCreativeOnly() .withBlockConstructor(StructureMultiblockControllerBlock::new) .withBlockItemConstructor((block, p) -> new BlockItem(block, p.rarity(Rarity.EPIC))) .withModel((block, gen) -> { @@ -147,28 +146,25 @@ public static void init(IEventBus modBus) { gen.blockTexture("structure_multiblock_controller_side")); gen.horizontalBlock(block, model); gen.simpleBlockItem(block, model); - }) - .noLootTable()); + })); public static final BlockDefinition STRUCTURE_MULTIBLOCK_HATCH = block("Structure Multiblock Hatch", - "structure_multiblock_hatch", BlockDefinitionParams.defaultStone() + "structure_multiblock_hatch", BlockDefinitionParams.defaultCreativeOnly() .withBlockConstructor(StructureMultiblockHatchBlock::new) .withBlockItemConstructor((block, p) -> new BlockItem(block, p.rarity(Rarity.EPIC))) .withModel((block, gen) -> { String name = gen.name(block); gen.simpleBlockWithItem(block, gen.models().cubeAll(name, gen.blockTexture("structure_multiblock_hatch"))); - }) - .noLootTable()); + })); public static final BlockDefinition STRUCTURE_MULTIBLOCK_MEMBER = block("Structure Multiblock Member", - "structure_multiblock_member", BlockDefinitionParams.defaultStone() + "structure_multiblock_member", BlockDefinitionParams.defaultCreativeOnly() .withBlockConstructor(StructureMultiblockMemberBlock::new) .withBlockItemConstructor((block, p) -> new BlockItem(block, p.rarity(Rarity.EPIC))) .withModel((block, gen) -> { String name = gen.name(block); gen.simpleBlockWithItem(block, gen.models().cubeAll(name, gen.blockTexture("structure_multiblock_member"))); - }) - .noLootTable()); + })); // Materials public static final BlockDefinition BLOCK_FIRE_CLAY_BRICKS = block("Fire Clay Bricks", "fire_clay_bricks", @@ -247,6 +243,14 @@ public static BlockDefinitionParams of(BlockBehaviour.Properties properti List.of(BlockTags.NEEDS_STONE_TOOL, BlockTags.MINEABLE_WITH_PICKAXE)); } + public static BlockDefinitionParams defaultCreativeOnly() { + return new BlockDefinitionParams<>( + BlockBehaviour.Properties.of().mapColor(MapColor.METAL).destroyTime(-1.0f).explosionResistance(3600000.0f), Block::new, + BlockItem::new, + (block, modelGenerator) -> modelGenerator.simpleBlockWithItem(block, modelGenerator.cubeAll(block)), + null, List.of()); + } + public static BlockDefinitionParams defaultStone() { return of(BlockBehaviour.Properties.of().mapColor(MapColor.METAL).destroyTime(4.0f).requiresCorrectToolForDrops()); } From 101402256e56fea055032795f110618d210f7008 Mon Sep 17 00:00:00 2001 From: Swedz Date: Fri, 22 Nov 2024 05:00:13 -0500 Subject: [PATCH 17/89] Ignore air and void blocks when serializing structure --- .../multiblocks/structure/MIStructureTemplateManager.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java index 170d92ecc..fb663f10e 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java @@ -56,6 +56,7 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.util.FastBufferedInputStream; import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.levelgen.structure.BoundingBox; @@ -138,6 +139,10 @@ public static FromWorldResult fromWorld(Level level, BlockPos controllerPos, Dir for (BlockPos pos : BlockPos.betweenClosed(minPos, maxPos)) { BlockState state = toTemplateState(level, pos, level.getBlockState(pos), controllerDirection); + if (state.isAir() || state.is(Blocks.STRUCTURE_VOID)) { + continue; + } + CompoundTag blockTag = new CompoundTag(); blockTag.put("pos", NbtUtils.writeBlockPos(toTemplatePos(controllerPos, controllerDirection, pos))); From a30f2710ff279a5f4b4a3908ef68cfa43f234a04 Mon Sep 17 00:00:00 2001 From: Swedz Date: Fri, 22 Nov 2024 05:07:10 -0500 Subject: [PATCH 18/89] Remove unused method --- .../machines/multiblocks/SimpleMember.java | 27 ------------------- 1 file changed, 27 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/SimpleMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/SimpleMember.java index 4a5d93ae8..7abc15b2e 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/SimpleMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/SimpleMember.java @@ -23,8 +23,6 @@ */ package aztech.modern_industrialization.machines.multiblocks; -import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMemberTest; -import java.util.Collection; import java.util.Objects; import java.util.function.Supplier; import net.minecraft.core.Direction; @@ -93,29 +91,4 @@ public BlockState getPreviewState() { } }; } - - static SimpleMember anyOf(Collection members, BlockState preview) { - Objects.requireNonNull(members); - if (members.isEmpty()) { - throw new IllegalArgumentException("Cannot use empty member collection"); - } - Objects.requireNonNull(preview); - - return new SimpleMember() { - @Override - public boolean matchesState(BlockState state) { - for (StructureMemberTest member : members) { - if (member.matchesState(state)) { - return true; - } - } - return false; - } - - @Override - public BlockState getPreviewState() { - return preview; - } - }; - } } From b84035a5950167158268a954c139eba620d361e5 Mon Sep 17 00:00:00 2001 From: Swedz Date: Fri, 22 Nov 2024 06:00:37 -0500 Subject: [PATCH 19/89] Include hatch casing in the structure file --- ...ructureMultiblockControllerBlockEntity.java | 17 +++++++++++------ .../debug/DebugCommands.java | 13 ++++++++----- .../structure/MIStructureTemplateManager.java | 18 ++++++++++++++++-- .../StructureSaveControllerPacket.java | 2 +- 4 files changed, 36 insertions(+), 14 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java index 5f29a2060..83611b4e3 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java @@ -73,6 +73,16 @@ public void setInputCasing(String inputCasing) { casing = StructureMultiblockFormatters.casing(inputCasing); } + @Nullable + public ResourceLocation getId() { + return id; + } + + @Nullable + public MachineCasing getCasing() { + return casing; + } + public StructureControllerBounds getBounds() { return bounds; } @@ -81,11 +91,6 @@ public void setBounds(StructureControllerBounds bounds) { this.bounds = bounds; } - @Nullable - public ResourceLocation getId() { - return id; - } - public boolean shouldShowBounds() { return showBounds; } @@ -106,7 +111,7 @@ public StructureMember getMemberOverride() { @Override public boolean isConfigurationValid() { - return !bounds.isEmpty(); + return casing != null && !bounds.isEmpty(); } @Override diff --git a/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java b/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java index 360452a5c..82796c454 100644 --- a/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java +++ b/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java @@ -30,7 +30,6 @@ import aztech.modern_industrialization.MIBlock; import aztech.modern_industrialization.MIConfig; import aztech.modern_industrialization.machines.MachineBlockEntity; -import aztech.modern_industrialization.machines.models.MachineCasings; import aztech.modern_industrialization.machines.multiblocks.MultiblockMachineBlockEntity; import aztech.modern_industrialization.machines.multiblocks.ShapeMatcher; import aztech.modern_industrialization.machines.multiblocks.ShapeTemplate; @@ -208,10 +207,14 @@ private static int structures(CommandSourceStack src, ResourceLocation id, Block if (controllerState.is(MIBlock.STRUCTURE_MULTIBLOCK_CONTROLLER.get())) { CompoundTag tag = MIStructureTemplateManager.load(id); if (tag == null) { - src.sendFailure(Component.literal("Could not find structure by the id '%s'".formatted(id))); + src.sendFailure(Component.literal("Could not find structure with the id %s".formatted(id))); + return Command.SINGLE_SUCCESS; + } + ShapeTemplate shape = MIStructureTemplateManager.deserialize(tag); + if (shape == null) { + src.sendFailure(Component.literal("Failed to read structure file for structure %s".formatted(id))); return Command.SINGLE_SUCCESS; } - ShapeTemplate shape = MIStructureTemplateManager.deserialize(MachineCasings.CLEAN_STAINLESS_STEEL, tag); ShapeMatcher matcher = new ShapeMatcher(src.getLevel(), controllerPos, controllerState.getValue(BlockStateProperties.HORIZONTAL_FACING), shape); action.accept(matcher); @@ -228,7 +231,7 @@ private static int structuresTest(CommandSourceStack src, ResourceLocation id, B matcher.unlinkHatches(); src.sendSuccess( () -> Component - .literal("Match test results for %s at position %s: %s".formatted(id.toString(), controllerPos.toShortString(), success)), + .literal("Match test results for %s at position %s: %s".formatted(id, controllerPos.toShortString(), success)), true); }); } @@ -236,7 +239,7 @@ private static int structuresTest(CommandSourceStack src, ResourceLocation id, B private static int structuresBuild(CommandSourceStack src, ResourceLocation id, BlockPos controllerPos) { return structures(src, id, controllerPos, (matcher) -> { matcher.buildMultiblock(src.getLevel()); - src.sendSuccess(() -> Component.literal("Built multiblock %s at position %s".formatted(id.toString(), controllerPos.toShortString())), + src.sendSuccess(() -> Component.literal("Built multiblock %s at position %s".formatted(id, controllerPos.toShortString())), true); }); } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java index fb663f10e..6d1287b53 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java @@ -30,6 +30,7 @@ import aztech.modern_industrialization.blocks.structure.StructureControllerBounds; import aztech.modern_industrialization.blocks.structure.StructureMemberOverride; import aztech.modern_industrialization.machines.models.MachineCasing; +import aztech.modern_industrialization.machines.models.MachineCasings; import aztech.modern_industrialization.machines.multiblocks.ShapeTemplate; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; import java.io.FileInputStream; @@ -118,13 +119,19 @@ public MutableComponent text() { } } - public static FromWorldResult fromWorld(Level level, BlockPos controllerPos, Direction controllerDirection, StructureControllerBounds bounds) { + public static FromWorldResult fromWorld(Level level, BlockPos controllerPos, Direction controllerDirection, + MachineCasing hatchCasing, StructureControllerBounds bounds) { + if (hatchCasing == null) { + return new FromWorldResult(ValidationResult.MISCONFIGURED_BLOCK, controllerPos.toShortString()); + } if (bounds.isEmpty()) { return new FromWorldResult(ValidationResult.INVALID_BOUNDS); } CompoundTag tag = new CompoundTag(); + tag.putString("hatch_casing", hatchCasing.key.toString()); + BoundingBox boundsBox = bounds.boundingBox(); BlockPos minPos = controllerPos.offset(boundsBox.minX(), boundsBox.minY(), boundsBox.minZ()); BlockPos maxPos = controllerPos.offset(boundsBox.maxX(), boundsBox.maxY(), boundsBox.maxZ()); @@ -192,9 +199,16 @@ public static FromWorldResult fromWorld(Level level, BlockPos controllerPos, Dir return new FromWorldResult(tag); } - public static ShapeTemplate deserialize(MachineCasing hatchCasing, CompoundTag tag) { + @Nullable + public static ShapeTemplate deserialize(CompoundTag tag) { var blockRegistry = BuiltInRegistries.BLOCK.asLookup(); + ResourceLocation hatchCasingId = ResourceLocation.tryParse(tag.getString("hatch_casing")); + if (hatchCasingId == null || !MachineCasings.registeredCasings.containsKey(hatchCasingId)) { + return null; + } + MachineCasing hatchCasing = MachineCasings.get(hatchCasingId); + ShapeTemplate.Builder builder = new ShapeTemplate.Builder(hatchCasing); ListTag members = tag.getList("members", Tag.TAG_COMPOUND); diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java index 957591196..f20681f5a 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java @@ -60,7 +60,7 @@ public void handle(Context ctx) { if (blockEntity instanceof StructureMultiblockControllerBlockEntity controller) { // TODO SWEDZ: dont do this on dedicated server maybe? MIStructureTemplateManager.FromWorldResult result = MIStructureTemplateManager.fromWorld(level, pos, - state.getValue(StructureMultiblockControllerBlock.FACING), controller.getBounds()); + state.getValue(StructureMultiblockControllerBlock.FACING), controller.getCasing(), controller.getBounds()); if (result.isSuccess()) { if (!MIStructureTemplateManager.save(controller.getId(), result.tag())) { player.sendSystemMessage(MIText.StructureMultiblockSaveFailUnknown.text().withStyle(ChatFormatting.RED)); From 17eaa1893710de27efc5d0438a5c33650f0a57c4 Mon Sep 17 00:00:00 2001 From: Swedz Date: Fri, 22 Nov 2024 06:05:30 -0500 Subject: [PATCH 20/89] Parameter null checks --- .../structure/MIStructureTemplateManager.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java index 6d1287b53..6b1c2c4e7 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java @@ -121,6 +121,10 @@ public MutableComponent text() { public static FromWorldResult fromWorld(Level level, BlockPos controllerPos, Direction controllerDirection, MachineCasing hatchCasing, StructureControllerBounds bounds) { + Objects.requireNonNull(level); + Objects.requireNonNull(controllerPos); + Objects.requireNonNull(controllerDirection); + Objects.requireNonNull(bounds); if (hatchCasing == null) { return new FromWorldResult(ValidationResult.MISCONFIGURED_BLOCK, controllerPos.toShortString()); } @@ -201,6 +205,8 @@ public static FromWorldResult fromWorld(Level level, BlockPos controllerPos, Dir @Nullable public static ShapeTemplate deserialize(CompoundTag tag) { + Objects.requireNonNull(tag); + var blockRegistry = BuiltInRegistries.BLOCK.asLookup(); ResourceLocation hatchCasingId = ResourceLocation.tryParse(tag.getString("hatch_casing")); @@ -230,6 +236,7 @@ public static ShapeTemplate deserialize(CompoundTag tag) { } private static Path path(ResourceLocation id) throws IOException { + Objects.requireNonNull(id); var miFolder = FMLPaths.GAMEDIR.get().resolve(MI.ID); var structuresFolder = miFolder .resolve("structures") @@ -239,6 +246,8 @@ private static Path path(ResourceLocation id) throws IOException { } public static boolean save(ResourceLocation id, CompoundTag tag) { + Objects.requireNonNull(id); + Objects.requireNonNull(tag); try { try (OutputStream output = new FileOutputStream(path(id).toFile())) { NbtIo.writeCompressed(tag, output); @@ -254,6 +263,7 @@ public static boolean save(ResourceLocation id, CompoundTag tag) { @Nullable public static CompoundTag load(ResourceLocation id) { + Objects.requireNonNull(id); try { Path path = path(id); if (Files.exists(path)) { From 3a6eafac8a1d8d0e48099e86a06436c4b2d4b0ff Mon Sep 17 00:00:00 2001 From: Swedz Date: Fri, 22 Nov 2024 06:07:58 -0500 Subject: [PATCH 21/89] Only store blocks with a member --- .../multiblocks/structure/MIStructureTemplateManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java index 6b1c2c4e7..6d13a410f 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java @@ -185,9 +185,9 @@ public static FromWorldResult fromWorld(Level level, BlockPos controllerPos, Dir membersTag.add(memberTag); } blockTag.putInt("member_index", members.indexOf(member)); - } - blocksTag.add(blockTag); + blocksTag.add(blockTag); + } } if (!hasController) { From cef0fb4282c1a2af224adfcf00b5270602366ddd Mon Sep 17 00:00:00 2001 From: Swedz Date: Fri, 22 Nov 2024 06:51:36 -0500 Subject: [PATCH 22/89] Fix loading blockstates too early --- .../StructureMultiblockHatchBlockEntity.java | 2 +- .../StructureMultiblockMemberBlockEntity.java | 2 +- .../kubejs/machine/ShapeTemplateHelper.java | 4 ++ .../machines/multiblocks/ShapeTemplate.java | 22 +++++++++ .../structure/MIStructureTemplateManager.java | 5 +- .../StructureMultiblockFormatters.java | 2 +- .../structure/member/StructureMember.java | 47 +++++++++++++++---- .../member/StructureMemberTestState.java | 24 +++++++--- 8 files changed, 84 insertions(+), 24 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlockEntity.java index 1de46eb11..11574877f 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlockEntity.java @@ -117,7 +117,7 @@ public HatchFlags getFlags() { @Override public StructureMember getMemberOverride() { - return new StructureMember(preview, members, flags); + return new StructureMember(() -> preview, members, flags); } @Override diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java index 49a679747..cf7650045 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java @@ -81,7 +81,7 @@ public List getMembers() { @Override public StructureMember getMemberOverride() { - return new StructureMember(preview, members, null); + return new StructureMember(() -> preview, members, null); } @Override diff --git a/src/main/java/aztech/modern_industrialization/compat/kubejs/machine/ShapeTemplateHelper.java b/src/main/java/aztech/modern_industrialization/compat/kubejs/machine/ShapeTemplateHelper.java index bdd494b35..0a9779425 100644 --- a/src/main/java/aztech/modern_industrialization/compat/kubejs/machine/ShapeTemplateHelper.java +++ b/src/main/java/aztech/modern_industrialization/compat/kubejs/machine/ShapeTemplateHelper.java @@ -31,6 +31,10 @@ import net.minecraft.resources.ResourceLocation; public interface ShapeTemplateHelper { + default ShapeTemplate structureShape(ResourceLocation id) { + return new ShapeTemplate.Structure(id).build(); + } + default ShapeTemplate.LayeredBuilder layeredShape(String hatchCasing, String[][] layers) { return new ShapeTemplate.LayeredBuilder(MachineCasings.get(hatchCasing), layers); } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java index 4f3fa8a2a..7f2e6df71 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java @@ -24,11 +24,13 @@ package aztech.modern_industrialization.machines.multiblocks; import aztech.modern_industrialization.machines.models.MachineCasing; +import aztech.modern_industrialization.machines.multiblocks.structure.MIStructureTemplateManager; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceLocation; import org.jetbrains.annotations.Nullable; /** @@ -200,4 +202,24 @@ public ShapeTemplate build() { return innerBuilder.build(); } } + + public static class Structure { + private final ResourceLocation id; + + public Structure(ResourceLocation id) { + this.id = id; + } + + public ShapeTemplate build() { + var tag = MIStructureTemplateManager.load(id); + if (tag == null) { + throw new IllegalStateException("Failed to load structure with id %s".formatted(id)); + } + ShapeTemplate template = MIStructureTemplateManager.deserialize(tag); + if (template == null) { + throw new IllegalStateException("Failed to parse structure with id %s".formatted(id)); + } + return template; + } + } } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java index 6d13a410f..b289b5dee 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java @@ -46,7 +46,6 @@ import net.minecraft.FileUtil; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; -import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.nbt.NbtAccounter; @@ -158,7 +157,7 @@ public static FromWorldResult fromWorld(Level level, BlockPos controllerPos, Dir blockTag.put("pos", NbtUtils.writeBlockPos(toTemplatePos(controllerPos, controllerDirection, pos))); - StructureMember member = new StructureMember(state); + StructureMember member = new StructureMember(() -> state); BlockEntity blockEntity = level.getBlockEntity(pos); if (blockEntity instanceof StructureMemberOverride override) { @@ -207,8 +206,6 @@ public static FromWorldResult fromWorld(Level level, BlockPos controllerPos, Dir public static ShapeTemplate deserialize(CompoundTag tag) { Objects.requireNonNull(tag); - var blockRegistry = BuiltInRegistries.BLOCK.asLookup(); - ResourceLocation hatchCasingId = ResourceLocation.tryParse(tag.getString("hatch_casing")); if (hatchCasingId == null || !MachineCasings.registeredCasings.containsKey(hatchCasingId)) { return null; diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockFormatters.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockFormatters.java index efe01cba9..5e8c1f185 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockFormatters.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockFormatters.java @@ -98,7 +98,7 @@ public static List members(String inputMembers) { } else { try { var blockResult = BlockStateParser.parseForBlock(registry, part, true); - members.add(new StructureMemberTestState(blockResult.blockState())); + members.add(new StructureMemberTestState(blockResult::blockState)); } catch (CommandSyntaxException ignored) { return null; } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java index 0d83e722a..b3b33ec06 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java @@ -26,8 +26,10 @@ import aztech.modern_industrialization.machines.multiblocks.HatchFlags; import aztech.modern_industrialization.machines.multiblocks.SimpleMember; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Objects; +import java.util.function.Supplier; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; @@ -35,11 +37,38 @@ import net.minecraft.nbt.Tag; import net.minecraft.world.level.block.state.BlockState; -public record StructureMember(BlockState preview, List tests, HatchFlags hatchFlags) implements SimpleMember { - public StructureMember(BlockState state) { +public final class StructureMember implements SimpleMember { + private final Supplier previewSupplier; + private final List tests; + private final HatchFlags hatchFlags; + + private BlockState preview; + + public StructureMember(Supplier preview, List tests, HatchFlags hatchFlags) { + this.previewSupplier = preview; + this.tests = tests; + this.hatchFlags = hatchFlags; + } + + public StructureMember(Supplier state) { this(state, List.of(new StructureMemberTestState(state)), null); } + public BlockState preview() { + if (preview == null) { + preview = previewSupplier.get(); + } + return preview; + } + + public List tests() { + return Collections.unmodifiableList(tests); + } + + public HatchFlags hatchFlags() { + return hatchFlags; + } + @Override public boolean matchesState(BlockState state) { for (StructureMemberTest test : tests) { @@ -52,21 +81,21 @@ public boolean matchesState(BlockState state) { @Override public BlockState getPreviewState() { - return preview; + return this.preview(); } @Override public boolean equals(Object o) { if (o instanceof StructureMember other) { - return preview == other.preview() && - tests.containsAll(other.tests()) && other.tests().containsAll(tests) && - Objects.equals(hatchFlags, other.hatchFlags()); + return this.preview() == other.preview() && + tests.containsAll(other.tests) && other.tests.containsAll(tests) && + Objects.equals(hatchFlags, other.hatchFlags); } return false; } public void save(CompoundTag tag) { - tag.put("preview", NbtUtils.writeBlockState(preview)); + tag.put("preview", NbtUtils.writeBlockState(this.preview())); ListTag testsTag = new ListTag(); for (StructureMemberTest test : tests) { @@ -89,9 +118,7 @@ public static StructureMember from(CompoundTag tag) { return null; } - var registry = BuiltInRegistries.BLOCK.asLookup(); - - BlockState preview = NbtUtils.readBlockState(registry, tag.getCompound("preview")); + Supplier preview = () -> NbtUtils.readBlockState(BuiltInRegistries.BLOCK.asLookup(), tag.getCompound("preview")); ListTag testsTag = tag.getList("tests", Tag.TAG_COMPOUND); List tests = new ArrayList<>(); diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestState.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestState.java index 4d48c8ec1..41a8025a1 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestState.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestState.java @@ -23,22 +23,32 @@ */ package aztech.modern_industrialization.machines.multiblocks.structure.member; +import java.util.function.Supplier; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtUtils; import net.minecraft.world.level.block.state.BlockState; public class StructureMemberTestState implements StructureMemberTest { + private Supplier blockStateSupplier; + private BlockState blockState; - public StructureMemberTestState(BlockState blockState) { - this.blockState = blockState; + public StructureMemberTestState(Supplier blockState) { + this.blockStateSupplier = blockState; } public StructureMemberTestState() { this(null); } + private BlockState blockState() { + if (blockState == null) { + blockState = blockStateSupplier.get(); + } + return blockState; + } + @Override public String id() { return "state"; @@ -46,24 +56,24 @@ public String id() { @Override public boolean matchesState(BlockState state) { - return blockState == state; + return this.blockState() == state; } @Override public void load(CompoundTag tag) { - var registry = BuiltInRegistries.BLOCK.asLookup(); - blockState = NbtUtils.readBlockState(registry, tag.getCompound("state")); + blockStateSupplier = () -> NbtUtils.readBlockState(BuiltInRegistries.BLOCK.asLookup(), tag.getCompound("state")); + blockState = null; } @Override public void save(CompoundTag tag) { - tag.put("state", NbtUtils.writeBlockState(blockState)); + tag.put("state", NbtUtils.writeBlockState(this.blockState())); } @Override public boolean equals(Object o) { if (o instanceof StructureMemberTestState other) { - return blockState == other.blockState; + return this.blockState() == other.blockState(); } return false; } From 5653a1eb3d5ec364e27f174c718fcda503da5e89 Mon Sep 17 00:00:00 2001 From: Swedz Date: Fri, 22 Nov 2024 21:06:32 -0500 Subject: [PATCH 23/89] Remove old todo --- .../network/structure/StructureSaveControllerPacket.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java index f20681f5a..76c545504 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java @@ -58,7 +58,6 @@ public void handle(Context ctx) { BlockState state = level.getBlockState(pos); BlockEntity blockEntity = level.getBlockEntity(pos); if (blockEntity instanceof StructureMultiblockControllerBlockEntity controller) { - // TODO SWEDZ: dont do this on dedicated server maybe? MIStructureTemplateManager.FromWorldResult result = MIStructureTemplateManager.fromWorld(level, pos, state.getValue(StructureMultiblockControllerBlock.FACING), controller.getCasing(), controller.getBounds()); if (result.isSuccess()) { From 10d4c8171efc6f40728c935af6fbf3334be2b103 Mon Sep 17 00:00:00 2001 From: Swedz Date: Fri, 22 Nov 2024 23:51:55 -0500 Subject: [PATCH 24/89] Render error boxes on misconfigured structure blocks when trying to save --- .../modern_industrialization/MIClient.java | 9 ++ .../structure/StructureMultiblockBER.java | 68 +++++++++ .../StructureMultiblockControllerBER.java | 25 ++-- .../client/MIRenderTypes.java | 39 ++++-- .../proxy/ClientProxy.java | 12 ++ .../util/RenderHelper.java | 16 ++- .../modern_industrialization/lang/en_us.json | 2 +- .../modern_industrialization/MIText.java | 2 +- .../structure/MIStructureTemplateManager.java | 107 +++++---------- .../structure/StructureResult.java | 129 ++++++++++++++++++ .../network/MIPackets.java | 2 + .../StructureMisconfiguredBlocksPacket.java | 66 +++++++++ .../StructureSaveControllerPacket.java | 21 ++- .../StructureUpdateControllerPacket.java | 5 + .../structure/StructureUpdateHatchPacket.java | 5 + .../StructureUpdateMemberPacket.java | 5 + .../proxy/CommonProxy.java | 5 + 17 files changed, 396 insertions(+), 122 deletions(-) create mode 100644 src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockBER.java create mode 100644 src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureResult.java create mode 100644 src/main/java/aztech/modern_industrialization/network/structure/StructureMisconfiguredBlocksPacket.java diff --git a/src/client/java/aztech/modern_industrialization/MIClient.java b/src/client/java/aztech/modern_industrialization/MIClient.java index f46da1c2f..d2c386918 100644 --- a/src/client/java/aztech/modern_industrialization/MIClient.java +++ b/src/client/java/aztech/modern_industrialization/MIClient.java @@ -29,6 +29,7 @@ import aztech.modern_industrialization.blocks.storage.barrel.DeferredBarrelTextRenderer; import aztech.modern_industrialization.blocks.storage.barrel.client.BarrelTooltipComponent; import aztech.modern_industrialization.blocks.storage.tank.TankRenderer; +import aztech.modern_industrialization.blocks.structure.StructureMultiblockBER; import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBER; import aztech.modern_industrialization.datagen.MIDatagenClient; import aztech.modern_industrialization.datagen.MIDatagenServer; @@ -104,6 +105,7 @@ import net.neoforged.neoforge.data.event.GatherDataEvent; import net.neoforged.neoforge.event.AddPackFindersEvent; import net.neoforged.neoforge.event.entity.player.ItemTooltipEvent; +import net.neoforged.neoforge.event.level.LevelEvent; @EventBusSubscriber(value = Dist.CLIENT, modid = MI.ID, bus = EventBusSubscriber.Bus.MOD) public class MIClient { @@ -150,6 +152,11 @@ private static void init(FMLConstructModEvent ignored) { } } }); + NeoForge.EVENT_BUS.addListener(LevelEvent.Unload.class, event -> { + if (event.getLevel().isClientSide()) { + StructureMultiblockBER.setMisconfigured(List.of()); + } + }); modBus.addListener(GatherDataEvent.class, event -> { MIDatagenClient.configure( @@ -236,6 +243,8 @@ private static void registerBlockEntityRenderers(FMLClientSetupEvent event) { BlockEntityRenderers.register(MIRegistries.CREATIVE_BARREL_BE.get(), context -> new BarrelRenderer(0x000000)); BlockEntityRenderers.register(MIRegistries.CREATIVE_TANK_BE.get(), context -> new TankRenderer(0x000000)); BlockEntityRenderers.register(MIRegistries.STRUCTURE_MULTIBLOCK_CONTROLLER_BE.get(), context -> new StructureMultiblockControllerBER()); + BlockEntityRenderers.register(MIRegistries.STRUCTURE_MULTIBLOCK_HATCH_BE.get(), context -> new StructureMultiblockBER<>()); + BlockEntityRenderers.register(MIRegistries.STRUCTURE_MULTIBLOCK_MEMBER_BE.get(), context -> new StructureMultiblockBER<>()); blockEntityRendererRegistrations.forEach(Runnable::run); } diff --git a/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockBER.java b/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockBER.java new file mode 100644 index 000000000..78ecbdce7 --- /dev/null +++ b/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockBER.java @@ -0,0 +1,68 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.blocks.structure; + +import aztech.modern_industrialization.util.RenderHelper; +import com.mojang.blaze3d.vertex.PoseStack; +import java.util.ArrayList; +import java.util.List; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.phys.AABB; + +public class StructureMultiblockBER implements BlockEntityRenderer { + private static List MISCONFIGURED_BLOCKS = new ArrayList<>(); + + public static void setMisconfigured(List positions) { + MISCONFIGURED_BLOCKS = new ArrayList<>(positions); + } + + public static void forgetMisconfigured(List positions) { + MISCONFIGURED_BLOCKS.removeAll(positions); + } + + @Override + public void render(T be, float tickDelta, PoseStack matrices, MultiBufferSource vcp, int light, int overlay) { + BlockPos pos = be.getBlockPos(); + if (MISCONFIGURED_BLOCKS.contains(pos) && (System.currentTimeMillis() / 500L) % 2 == 0) { + matrices.pushPose(); + matrices.translate(-0.005f, -0.005f, -0.005f); + matrices.scale(1.01f, 1.01f, 1.01f); + RenderHelper.drawOverlay(matrices, vcp, 1.0f, 111f / 256f, 111f / 256f, RenderHelper.FULL_LIGHT, overlay, false); + matrices.popPose(); + } + } + + @Override + public boolean shouldRenderOffScreen(T be) { + return true; + } + + @Override + public AABB getRenderBoundingBox(T be) { + return AABB.INFINITE; + } +} diff --git a/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java b/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java index f47733530..d4e8fe057 100644 --- a/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java +++ b/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java @@ -28,35 +28,26 @@ import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; import net.minecraft.core.BlockPos; import net.minecraft.world.phys.AABB; -public class StructureMultiblockControllerBER implements BlockEntityRenderer { +public class StructureMultiblockControllerBER extends StructureMultiblockBER { @Override - public void render(StructureMultiblockControllerBlockEntity controller, float tickDelta, PoseStack matrices, MultiBufferSource vcs, int light, + public void render(StructureMultiblockControllerBlockEntity be, float tickDelta, PoseStack matrices, MultiBufferSource vcp, int light, int overlay) { - if (!controller.shouldShowBounds()) { + super.render(be, tickDelta, matrices, vcp, light, overlay); + + if (!be.shouldShowBounds()) { return; } - BlockPos pos = controller.getBlockPos(); - StructureControllerBounds bounds = controller.getBounds(); + BlockPos pos = be.getBlockPos(); + StructureControllerBounds bounds = be.getBounds(); AABB box = bounds.aabb(); if (box != null) { matrices.pushPose(); - VertexConsumer buffer = vcs.getBuffer(RenderType.lines()); + VertexConsumer buffer = vcp.getBuffer(RenderType.lines()); LevelRenderer.renderLineBox(matrices, buffer, box, 1, 1, 1, 1); matrices.popPose(); } } - - @Override - public boolean shouldRenderOffScreen(StructureMultiblockControllerBlockEntity controller) { - return true; - } - - @Override - public AABB getRenderBoundingBox(StructureMultiblockControllerBlockEntity controller) { - return AABB.INFINITE; - } } diff --git a/src/client/java/aztech/modern_industrialization/client/MIRenderTypes.java b/src/client/java/aztech/modern_industrialization/client/MIRenderTypes.java index ccdef213c..5998f1516 100644 --- a/src/client/java/aztech/modern_industrialization/client/MIRenderTypes.java +++ b/src/client/java/aztech/modern_industrialization/client/MIRenderTypes.java @@ -25,11 +25,14 @@ import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.VertexFormat; +import net.minecraft.client.renderer.RenderStateShard; import net.minecraft.client.renderer.RenderType; public class MIRenderTypes { private static RenderType MACHINE_WRENCH_OVERLAY; - private static RenderType SOLID_HIGHLIGHT; // used by hatch preview and wrong block highlight + // used by hatch preview and wrong block highlight + private static RenderType SOLID_HIGHLIGHT_DEPTH; + private static RenderType SOLID_HIGHLIGHT_NO_DEPTH; public static RenderType machineOverlay() { if (MACHINE_WRENCH_OVERLAY == null) { @@ -38,11 +41,18 @@ public static RenderType machineOverlay() { return MACHINE_WRENCH_OVERLAY; } - public static RenderType solidHighlight() { - if (SOLID_HIGHLIGHT == null) { - SOLID_HIGHLIGHT = Factory.makeSolidHighlight(); + public static RenderType solidHighlight(boolean depth) { + if (depth) { + if (SOLID_HIGHLIGHT_DEPTH == null) { + SOLID_HIGHLIGHT_DEPTH = Factory.makeSolidHighlight(true); + } + return SOLID_HIGHLIGHT_DEPTH; + } else { + if (SOLID_HIGHLIGHT_NO_DEPTH == null) { + SOLID_HIGHLIGHT_NO_DEPTH = Factory.makeSolidHighlight(false); + } + return SOLID_HIGHLIGHT_NO_DEPTH; } - return SOLID_HIGHLIGHT; } // This is a subclass to get access to a bunch of fields and classes. @@ -63,14 +73,17 @@ private static RenderType makeMachineOverlay() { .createCompositeState(false)); } - private static RenderType makeSolidHighlight() { - return create("solid_highlight", DefaultVertexFormat.POSITION_COLOR_NORMAL, VertexFormat.Mode.QUADS, 65536, false, false, - CompositeState.builder() - .setTransparencyState(NO_TRANSPARENCY) - .setTextureState(NO_TEXTURE) - .setLightmapState(NO_LIGHTMAP) - .setShaderState(POSITION_COLOR_SHADER) - .createCompositeState(false)); + private static RenderType makeSolidHighlight(boolean depth) { + var builder = CompositeState.builder() + .setTransparencyState(NO_TRANSPARENCY) + .setTextureState(NO_TEXTURE) + .setLightmapState(NO_LIGHTMAP) + .setShaderState(POSITION_COLOR_SHADER); + if (!depth) { + builder = builder.setDepthTestState(RenderStateShard.NO_DEPTH_TEST); + } + return create("solid_highlight" + (depth ? "_depth" : "_no_depth"), DefaultVertexFormat.POSITION_COLOR_NORMAL, VertexFormat.Mode.QUADS, + 65536, false, false, builder.createCompositeState(false)); } } } diff --git a/src/client/java/aztech/modern_industrialization/proxy/ClientProxy.java b/src/client/java/aztech/modern_industrialization/proxy/ClientProxy.java index 87b4c7ec7..fc8fb3f54 100644 --- a/src/client/java/aztech/modern_industrialization/proxy/ClientProxy.java +++ b/src/client/java/aztech/modern_industrialization/proxy/ClientProxy.java @@ -29,6 +29,7 @@ import aztech.modern_industrialization.blocks.storage.barrel.BarrelRenderer; import aztech.modern_industrialization.blocks.storage.tank.AbstractTankBlockEntity; import aztech.modern_industrialization.blocks.storage.tank.TankRenderer; +import aztech.modern_industrialization.blocks.structure.StructureMultiblockBER; import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlockEntity; import aztech.modern_industrialization.blocks.structure.StructureMultiblockHatchBlockEntity; import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlockEntity; @@ -43,6 +44,8 @@ import aztech.modern_industrialization.machines.models.UseBlockModelBakedModel; import aztech.modern_industrialization.machines.multiblocks.HatchBlockEntity; import aztech.modern_industrialization.machines.multiblocks.MultiblockMachineBlockEntity; +import aztech.modern_industrialization.network.BasePacket; +import aztech.modern_industrialization.network.structure.StructureMisconfiguredBlocksPacket; import aztech.modern_industrialization.textures.TextureHelper; import aztech.modern_industrialization.util.RenderHelper; import java.util.Objects; @@ -179,4 +182,13 @@ public void openStructureMultiblockMemberScreen(Player player, StructureMultiblo Minecraft.getInstance().setScreen(new StructureMultiblockMemberEditScreen(member)); } } + + @Override + public void receiveStructureMisconfiguredBlocksPacket(StructureMisconfiguredBlocksPacket packet, BasePacket.Context ctx) { + if (packet.forget()) { + StructureMultiblockBER.forgetMisconfigured(packet.positions()); + } else { + StructureMultiblockBER.setMisconfigured(packet.positions()); + } + } } diff --git a/src/client/java/aztech/modern_industrialization/util/RenderHelper.java b/src/client/java/aztech/modern_industrialization/util/RenderHelper.java index 5c60d8ce0..2e1b6b530 100644 --- a/src/client/java/aztech/modern_industrialization/util/RenderHelper.java +++ b/src/client/java/aztech/modern_industrialization/util/RenderHelper.java @@ -75,13 +75,17 @@ public class RenderHelper { private static final float W = 0.05f; private static final ResourceLocation LOCKED_TEXTURE_LOCATION = MI.id("block/locked"); - public static void drawOverlay(PoseStack ms, MultiBufferSource vcp, float r, float g, float b, int light, int overlay) { - VertexConsumer vc = vcp.getBuffer(MIRenderTypes.solidHighlight()); + public static void drawOverlay(PoseStack ms, MultiBufferSource vcp, float r, float g, float b, int light, int overlay, boolean depth) { + VertexConsumer vc = vcp.getBuffer(MIRenderTypes.solidHighlight(depth)); for (BakedQuad overlayQuad : OVERLAY_QUADS.get()) { vc.putBulkData(ms.last(), overlayQuad, r, g, b, 1.0f, light, overlay); } } + public static void drawOverlay(PoseStack ms, MultiBufferSource vcp, float r, float g, float b, int light, int overlay) { + drawOverlay(ms, vcp, r, g, b, light, overlay, true); + } + static { OVERLAY_QUADS = Suppliers.memoize(() -> { var overlayQuads = new BakedQuad[24]; @@ -103,13 +107,17 @@ public static void drawOverlay(PoseStack ms, MultiBufferSource vcp, float r, flo private static final Supplier CUBE_QUADS; - public static void drawCube(PoseStack ms, MultiBufferSource vcp, float r, float g, float b, int light, int overlay) { - VertexConsumer vc = vcp.getBuffer(MIRenderTypes.solidHighlight()); + public static void drawCube(PoseStack ms, MultiBufferSource vcp, float r, float g, float b, int light, int overlay, boolean depth) { + VertexConsumer vc = vcp.getBuffer(MIRenderTypes.solidHighlight(depth)); for (BakedQuad cubeQuad : CUBE_QUADS.get()) { vc.putBulkData(ms.last(), cubeQuad, r, g, b, 1.0f, light, overlay); } } + public static void drawCube(PoseStack ms, MultiBufferSource vcp, float r, float g, float b, int light, int overlay) { + drawCube(ms, vcp, r, g, b, light, overlay, true); + } + static { CUBE_QUADS = Suppliers.memoize(() -> { var cubeQuads = new BakedQuad[6]; diff --git a/src/generated/resources/assets/modern_industrialization/lang/en_us.json b/src/generated/resources/assets/modern_industrialization/lang/en_us.json index ef56af169..c45e8d7ed 100644 --- a/src/generated/resources/assets/modern_industrialization/lang/en_us.json +++ b/src/generated/resources/assets/modern_industrialization/lang/en_us.json @@ -1699,7 +1699,7 @@ "text.modern_industrialization.StructureMultiblockMemberMembers": "Members", "text.modern_industrialization.StructureMultiblockMemberPreview": "Preview", "text.modern_industrialization.StructureMultiblockSaveFailInvalidBounds": "Failed to save structure. The bounds provided are not valid.", - "text.modern_industrialization.StructureMultiblockSaveFailMisconfiguredBlock": "Failed to save structure. The block at (%s) is not properly configured.", + "text.modern_industrialization.StructureMultiblockSaveFailMisconfiguredBlock": "Failed to save structure. Some blocks are not properly configured.", "text.modern_industrialization.StructureMultiblockSaveFailNoController": "Failed to save structure. No controller could be found within the bounds.", "text.modern_industrialization.StructureMultiblockSaveFailNoHatches": "Failed to save structure. No hatches could be found within the bounds.", "text.modern_industrialization.StructureMultiblockSaveFailTooManyControllers": "Failed to save structure. Too many controllers exist within the bounds.", diff --git a/src/main/java/aztech/modern_industrialization/MIText.java b/src/main/java/aztech/modern_industrialization/MIText.java index 98cbefb5d..8f92f456b 100644 --- a/src/main/java/aztech/modern_industrialization/MIText.java +++ b/src/main/java/aztech/modern_industrialization/MIText.java @@ -252,7 +252,7 @@ public enum MIText { StructureMultiblockMemberPreview("Preview"), StructureMultiblockStructureName("Structure Name"), StructureMultiblockSaveFailInvalidBounds("Failed to save structure. The bounds provided are not valid."), - StructureMultiblockSaveFailMisconfiguredBlock("Failed to save structure. The block at (%s) is not properly configured."), + StructureMultiblockSaveFailMisconfiguredBlock("Failed to save structure. Some blocks are not properly configured."), StructureMultiblockSaveFailTooManyControllers("Failed to save structure. Too many controllers exist within the bounds."), StructureMultiblockSaveFailNoController("Failed to save structure. No controller could be found within the bounds."), StructureMultiblockSaveFailNoHatches("Failed to save structure. No hatches could be found within the bounds."), diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java index b289b5dee..5ea1f56e1 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java @@ -26,7 +26,6 @@ import static aztech.modern_industrialization.machines.multiblocks.ShapeMatcher.*; import aztech.modern_industrialization.MI; -import aztech.modern_industrialization.MIText; import aztech.modern_industrialization.blocks.structure.StructureControllerBounds; import aztech.modern_industrialization.blocks.structure.StructureMemberOverride; import aztech.modern_industrialization.machines.models.MachineCasing; @@ -52,7 +51,6 @@ import net.minecraft.nbt.NbtIo; import net.minecraft.nbt.NbtUtils; import net.minecraft.nbt.Tag; -import net.minecraft.network.chat.MutableComponent; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.FastBufferedInputStream; import net.minecraft.world.level.Level; @@ -64,76 +62,31 @@ import org.jetbrains.annotations.Nullable; public final class MIStructureTemplateManager { - public enum ValidationResult { - INVALID_BOUNDS(false, MIText.StructureMultiblockSaveFailInvalidBounds), - MISCONFIGURED_BLOCK(false, MIText.StructureMultiblockSaveFailMisconfiguredBlock), - TOO_MANY_CONTROLLERS(false, MIText.StructureMultiblockSaveFailTooManyControllers), - NO_CONTROLLER(false, MIText.StructureMultiblockSaveFailNoController), - NO_HATCHES(false, MIText.StructureMultiblockSaveFailNoHatches), - SUCCESS(true, MIText.StructureMultiblockSaveSuccess); - - private final boolean success; - private final MIText text; - - ValidationResult(boolean success, MIText text) { - this.success = success; - this.text = text; - } - - public boolean isSuccess() { - return success; - } - - public MIText text() { - return text; - } - } - - public record FromWorldResult(CompoundTag tag, ValidationResult result, Object... args) { - public FromWorldResult { - Objects.requireNonNull(result); - if (tag == null && result.isSuccess()) { - throw new IllegalArgumentException("Cannot create successful result with no tag"); - } - } - - public FromWorldResult(ValidationResult result, Object... args) { - this(null, result, args); - } - - public FromWorldResult(CompoundTag tag, Object... args) { - this(tag, ValidationResult.SUCCESS, args); - } - - public boolean isSuccess() { - return result.isSuccess(); - } - - public MutableComponent text(Object... args) { - return result.text().text(args); - } - - public MutableComponent text() { - return this.text(args); - } - } - - public static FromWorldResult fromWorld(Level level, BlockPos controllerPos, Direction controllerDirection, + public static StructureResult fromWorld(ResourceLocation id, Level level, + BlockPos controllerPos, Direction controllerDirection, MachineCasing hatchCasing, StructureControllerBounds bounds) { + Objects.requireNonNull(id); Objects.requireNonNull(level); Objects.requireNonNull(controllerPos); Objects.requireNonNull(controllerDirection); Objects.requireNonNull(bounds); - if (hatchCasing == null) { - return new FromWorldResult(ValidationResult.MISCONFIGURED_BLOCK, controllerPos.toShortString()); - } if (bounds.isEmpty()) { - return new FromWorldResult(ValidationResult.INVALID_BOUNDS); + return new StructureResult.InvalidBounds(); + } + + List misconfiguredBlocks = new ArrayList<>(); + List controllerBlocks = new ArrayList<>(); + List hatchBlocks = new ArrayList<>(); + + if (hatchCasing == null) { + misconfiguredBlocks.add(controllerPos); } CompoundTag tag = new CompoundTag(); - tag.putString("hatch_casing", hatchCasing.key.toString()); + if (hatchCasing != null) { + tag.putString("hatch_casing", hatchCasing.key.toString()); + } BoundingBox boundsBox = bounds.boundingBox(); BlockPos minPos = controllerPos.offset(boundsBox.minX(), boundsBox.minY(), boundsBox.minZ()); @@ -143,9 +96,6 @@ public static FromWorldResult fromWorld(Level level, BlockPos controllerPos, Dir ListTag membersTag = new ListTag(); ListTag blocksTag = new ListTag(); - boolean hasController = false; - boolean hasHatch = false; - for (BlockPos pos : BlockPos.betweenClosed(minPos, maxPos)) { BlockState state = toTemplateState(level, pos, level.getBlockState(pos), controllerDirection); @@ -162,20 +112,21 @@ public static FromWorldResult fromWorld(Level level, BlockPos controllerPos, Dir BlockEntity blockEntity = level.getBlockEntity(pos); if (blockEntity instanceof StructureMemberOverride override) { if (!override.isConfigurationValid()) { - return new FromWorldResult(ValidationResult.MISCONFIGURED_BLOCK, pos.toShortString()); + misconfiguredBlocks.add(pos.immutable()); + continue; } if (override.isController()) { - if (hasController) { - return new FromWorldResult(ValidationResult.TOO_MANY_CONTROLLERS); + controllerBlocks.add(pos.immutable()); + if (controllerBlocks.size() > 1) { + continue; } - hasController = true; } member = override.getMemberOverride(); } if (member != null) { if (member.hatchFlags() != null) { - hasHatch = true; + hatchBlocks.add(pos.immutable()); } CompoundTag memberTag = new CompoundTag(); member.save(memberTag); @@ -189,17 +140,23 @@ public static FromWorldResult fromWorld(Level level, BlockPos controllerPos, Dir } } - if (!hasController) { - return new FromWorldResult(ValidationResult.NO_CONTROLLER); + if (controllerBlocks.isEmpty()) { + return new StructureResult.NoController(); + } + if (hatchBlocks.isEmpty()) { + return new StructureResult.NoHatches(); + } + if (controllerBlocks.size() > 1) { + return new StructureResult.TooManyControllers(controllerBlocks); } - if (!hasHatch) { - return new FromWorldResult(ValidationResult.NO_HATCHES); + if (!misconfiguredBlocks.isEmpty()) { + return new StructureResult.MisconfiguredBlocks(misconfiguredBlocks); } tag.put("members", membersTag); tag.put("blocks", blocksTag); - return new FromWorldResult(tag); + return new StructureResult.Success(id, tag); } @Nullable diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureResult.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureResult.java new file mode 100644 index 000000000..5144a6243 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureResult.java @@ -0,0 +1,129 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.machines.multiblocks.structure; + +import aztech.modern_industrialization.MIText; +import aztech.modern_industrialization.network.structure.StructureMisconfiguredBlocksPacket; +import java.util.ArrayList; +import java.util.List; +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.player.Player; + +public interface StructureResult { + default boolean isSuccess() { + return false; + } + + Component text(); + + default void sendMessage(Player player) { + player.sendSystemMessage(this.text()); + } + + default void send(Player player) { + this.sendMessage(player); + this.clearMisconfiguredBlocks(player); + } + + default void sendMisconfiguredBlocks(Player player, List positions) { + if (player instanceof ServerPlayer serverPlayer) { + StructureMisconfiguredBlocksPacket.misconfigured(positions).sendToClient(serverPlayer); + } + } + + default void clearMisconfiguredBlocks(Player player) { + this.sendMisconfiguredBlocks(player, new ArrayList<>()); + } + + final class Unknown implements StructureResult { + @Override + public Component text() { + return MIText.StructureMultiblockSaveFailUnknown.text().withStyle(ChatFormatting.RED); + } + } + + final class InvalidBounds implements StructureResult { + @Override + public Component text() { + return MIText.StructureMultiblockSaveFailInvalidBounds.text().withStyle(ChatFormatting.RED); + } + } + + record MisconfiguredBlocks(List positions) implements StructureResult { + @Override + public Component text() { + return MIText.StructureMultiblockSaveFailMisconfiguredBlock.text().withStyle(ChatFormatting.RED); + } + + @Override + public void send(Player player) { + this.sendMessage(player); + this.sendMisconfiguredBlocks(player, positions); + } + } + + record TooManyControllers(List positions) implements StructureResult { + @Override + public Component text() { + return MIText.StructureMultiblockSaveFailTooManyControllers.text().withStyle(ChatFormatting.RED); + } + + @Override + public void send(Player player) { + this.sendMessage(player); + this.sendMisconfiguredBlocks(player, positions); + } + } + + final class NoController implements StructureResult { + @Override + public Component text() { + return MIText.StructureMultiblockSaveFailNoController.text().withStyle(ChatFormatting.RED); + } + } + + final class NoHatches implements StructureResult { + @Override + public Component text() { + return MIText.StructureMultiblockSaveFailNoHatches.text().withStyle(ChatFormatting.RED); + } + } + + record Success(ResourceLocation structureId, CompoundTag tag) implements StructureResult { + @Override + public boolean isSuccess() { + return true; + } + + @Override + public Component text() { + return MIText.StructureMultiblockSaveSuccess.text(structureId.toString()); + } + } +} diff --git a/src/main/java/aztech/modern_industrialization/network/MIPackets.java b/src/main/java/aztech/modern_industrialization/network/MIPackets.java index 62c851cfc..3674fa60c 100644 --- a/src/main/java/aztech/modern_industrialization/network/MIPackets.java +++ b/src/main/java/aztech/modern_industrialization/network/MIPackets.java @@ -42,6 +42,7 @@ import aztech.modern_industrialization.network.pipes.SetItemWhitelistPacket; import aztech.modern_industrialization.network.pipes.SetNetworkFluidPacket; import aztech.modern_industrialization.network.pipes.SetPriorityPacket; +import aztech.modern_industrialization.network.structure.StructureMisconfiguredBlocksPacket; import aztech.modern_industrialization.network.structure.StructureSaveControllerPacket; import aztech.modern_industrialization.network.structure.StructureUpdateControllerPacket; import aztech.modern_industrialization.network.structure.StructureUpdateHatchPacket; @@ -95,6 +96,7 @@ private static

void register(String path, Class

clazz, register("set_network_fluid", SetNetworkFluidPacket.class, SetNetworkFluidPacket.STREAM_CODEC); register("set_priority", SetPriorityPacket.class, SetPriorityPacket.STREAM_CODEC); // Structure blocks + register("structure_misconfigured_blocks", StructureMisconfiguredBlocksPacket.class, StructureMisconfiguredBlocksPacket.STREAM_CODEC); register("structure_save_controller", StructureSaveControllerPacket.class, StructureSaveControllerPacket.STREAM_CODEC); register("structure_update_controller", StructureUpdateControllerPacket.class, StructureUpdateControllerPacket.STREAM_CODEC); register("structure_update_hatch", StructureUpdateHatchPacket.class, StructureUpdateHatchPacket.STREAM_CODEC); diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureMisconfiguredBlocksPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureMisconfiguredBlocksPacket.java new file mode 100644 index 000000000..4e81e1f8a --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureMisconfiguredBlocksPacket.java @@ -0,0 +1,66 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.network.structure; + +import aztech.modern_industrialization.network.BasePacket; +import aztech.modern_industrialization.proxy.CommonProxy; +import io.netty.buffer.ByteBuf; +import java.util.List; +import net.minecraft.core.BlockPos; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; + +public record StructureMisconfiguredBlocksPacket(List positions, boolean forget) implements BasePacket { + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.list().apply(BlockPos.STREAM_CODEC), + StructureMisconfiguredBlocksPacket::positions, + ByteBufCodecs.BOOL, + StructureMisconfiguredBlocksPacket::forget, + StructureMisconfiguredBlocksPacket::new); + + public static StructureMisconfiguredBlocksPacket misconfigured(List positions) { + return new StructureMisconfiguredBlocksPacket(positions, false); + } + + public static StructureMisconfiguredBlocksPacket forget(BlockPos pos) { + return new StructureMisconfiguredBlocksPacket(List.of(pos), true); + } + + @Override + public void handle(Context ctx) { + ctx.assertOnClient(); + + Player player = ctx.getPlayer(); + Level level = player.level(); + + if (!player.canUseGameMasterBlocks()) { + return; + } + + CommonProxy.INSTANCE.receiveStructureMisconfiguredBlocksPacket(this, ctx); + } +} diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java index 76c545504..a423a375d 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java @@ -23,15 +23,15 @@ */ package aztech.modern_industrialization.network.structure; -import aztech.modern_industrialization.MIText; import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlock; import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlockEntity; import aztech.modern_industrialization.machines.multiblocks.structure.MIStructureTemplateManager; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureResult; import aztech.modern_industrialization.network.BasePacket; import io.netty.buffer.ByteBuf; -import net.minecraft.ChatFormatting; import net.minecraft.core.BlockPos; import net.minecraft.network.codec.StreamCodec; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; @@ -58,17 +58,16 @@ public void handle(Context ctx) { BlockState state = level.getBlockState(pos); BlockEntity blockEntity = level.getBlockEntity(pos); if (blockEntity instanceof StructureMultiblockControllerBlockEntity controller) { - MIStructureTemplateManager.FromWorldResult result = MIStructureTemplateManager.fromWorld(level, pos, - state.getValue(StructureMultiblockControllerBlock.FACING), controller.getCasing(), controller.getBounds()); - if (result.isSuccess()) { - if (!MIStructureTemplateManager.save(controller.getId(), result.tag())) { - player.sendSystemMessage(MIText.StructureMultiblockSaveFailUnknown.text().withStyle(ChatFormatting.RED)); - } else { - player.sendSystemMessage(result.text(controller.getId().toString())); + ResourceLocation id = controller.getId(); + var result = MIStructureTemplateManager.fromWorld(id, + level, pos, state.getValue(StructureMultiblockControllerBlock.FACING), + controller.getCasing(), controller.getBounds()); + if (result instanceof StructureResult.Success success) { + if (!MIStructureTemplateManager.save(id, success.tag())) { + result = new StructureResult.Unknown(); } - } else { - player.sendSystemMessage(result.text().withStyle(ChatFormatting.RED)); } + result.send(player); } } } diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java index 68639204c..493ebbbd1 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java @@ -30,6 +30,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; +import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; @@ -70,6 +71,10 @@ public void handle(Context ctx) { controller.sync(); controller.setChanged(); + + if (player instanceof ServerPlayer serverPlayer && controller.isConfigurationValid()) { + StructureMisconfiguredBlocksPacket.forget(controller.getBlockPos()).sendToClient(serverPlayer); + } } } } diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateHatchPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateHatchPacket.java index 51ae4004c..d31c0c22b 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateHatchPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateHatchPacket.java @@ -29,6 +29,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; +import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; @@ -69,6 +70,10 @@ public void handle(Context ctx) { hatch.sync(); hatch.setChanged(); + + if (player instanceof ServerPlayer serverPlayer && hatch.isConfigurationValid()) { + StructureMisconfiguredBlocksPacket.forget(hatch.getBlockPos()).sendToClient(serverPlayer); + } } } } diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java index f24f4906a..0e906a5da 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java @@ -29,6 +29,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; +import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; @@ -62,6 +63,10 @@ public void handle(Context ctx) { member.sync(); member.setChanged(); + + if (player instanceof ServerPlayer serverPlayer && member.isConfigurationValid()) { + StructureMisconfiguredBlocksPacket.forget(member.getBlockPos()).sendToClient(serverPlayer); + } } } } diff --git a/src/main/java/aztech/modern_industrialization/proxy/CommonProxy.java b/src/main/java/aztech/modern_industrialization/proxy/CommonProxy.java index 6c1bc145c..626c1c0a1 100644 --- a/src/main/java/aztech/modern_industrialization/proxy/CommonProxy.java +++ b/src/main/java/aztech/modern_industrialization/proxy/CommonProxy.java @@ -29,6 +29,8 @@ import aztech.modern_industrialization.blocks.structure.StructureMultiblockHatchBlockEntity; import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlockEntity; import aztech.modern_industrialization.machines.gui.MachineMenuCommon; +import aztech.modern_industrialization.network.BasePacket; +import aztech.modern_industrialization.network.structure.StructureMisconfiguredBlocksPacket; import aztech.modern_industrialization.thirdparty.fabrictransfer.api.fluid.FluidVariant; import aztech.modern_industrialization.thirdparty.fabrictransfer.api.fluid.FluidVariantAttributes; import java.util.ArrayList; @@ -136,4 +138,7 @@ public void openStructureMultiblockHatchScreen(Player player, StructureMultibloc public void openStructureMultiblockMemberScreen(Player player, StructureMultiblockMemberBlockEntity member) { } + + public void receiveStructureMisconfiguredBlocksPacket(StructureMisconfiguredBlocksPacket packet, BasePacket.Context ctx) { + } } From ce02db2396706ba9e0183020b6ee9363d83f6c7c Mon Sep 17 00:00:00 2001 From: Swedz Date: Sat, 23 Nov 2024 05:17:41 -0500 Subject: [PATCH 25/89] Add support for reading structure files from both mod jars and the game directory --- .../aztech/modern_industrialization/MI.java | 6 +- .../debug/DebugCommands.java | 10 +- .../machines/multiblocks/ShapeTemplate.java | 10 +- .../structure/MIStructureTemplateManager.java | 120 +++++++++++++++--- .../StructureSaveControllerPacket.java | 7 +- 5 files changed, 115 insertions(+), 38 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/MI.java b/src/main/java/aztech/modern_industrialization/MI.java index ee870dfe1..f82c62768 100644 --- a/src/main/java/aztech/modern_industrialization/MI.java +++ b/src/main/java/aztech/modern_industrialization/MI.java @@ -42,6 +42,7 @@ import aztech.modern_industrialization.machines.init.MultiblockMachines; import aztech.modern_industrialization.machines.init.SingleBlockCraftingMachines; import aztech.modern_industrialization.machines.init.SingleBlockSpecialMachines; +import aztech.modern_industrialization.machines.multiblocks.structure.MIStructureTemplateManager; import aztech.modern_industrialization.machines.multiblocks.world.ChunkEventListeners; import aztech.modern_industrialization.materials.MIMaterials; import aztech.modern_industrialization.misc.autotest.MIAutoTesting; @@ -73,6 +74,7 @@ import net.neoforged.bus.api.IEventBus; import net.neoforged.fml.common.Mod; import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; +import net.neoforged.fml.javafmlmod.FMLModContainer; import net.neoforged.fml.loading.FMLPaths; import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent; import net.neoforged.neoforge.common.NeoForge; @@ -96,9 +98,11 @@ public static ResourceLocation id(String path) { return ResourceLocation.fromNamespaceAndPath(ID, path); } - public MI(IEventBus modBus, Dist dist) { + public MI(FMLModContainer container, IEventBus modBus, Dist dist) { KubeJSProxy.checkThatKubeJsIsLoaded(); + MIStructureTemplateManager.init(); + MIAdvancementTriggers.init(modBus); MIComponents.init(modBus); MIFluids.init(modBus); diff --git a/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java b/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java index 82796c454..c8e34f471 100644 --- a/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java +++ b/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java @@ -46,7 +46,6 @@ import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.SharedSuggestionProvider; import net.minecraft.core.BlockPos; -import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; @@ -205,16 +204,11 @@ private static int buildMultiblock(CommandSourceStack src, BlockPos controllerPo private static int structures(CommandSourceStack src, ResourceLocation id, BlockPos controllerPos, Consumer action) { BlockState controllerState = src.getLevel().getBlockState(controllerPos); if (controllerState.is(MIBlock.STRUCTURE_MULTIBLOCK_CONTROLLER.get())) { - CompoundTag tag = MIStructureTemplateManager.load(id); - if (tag == null) { + if (!MIStructureTemplateManager.exists(id)) { src.sendFailure(Component.literal("Could not find structure with the id %s".formatted(id))); return Command.SINGLE_SUCCESS; } - ShapeTemplate shape = MIStructureTemplateManager.deserialize(tag); - if (shape == null) { - src.sendFailure(Component.literal("Failed to read structure file for structure %s".formatted(id))); - return Command.SINGLE_SUCCESS; - } + ShapeTemplate shape = MIStructureTemplateManager.get(id); ShapeMatcher matcher = new ShapeMatcher(src.getLevel(), controllerPos, controllerState.getValue(BlockStateProperties.HORIZONTAL_FACING), shape); action.accept(matcher); diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java index 7f2e6df71..0ab890159 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java @@ -211,15 +211,7 @@ public Structure(ResourceLocation id) { } public ShapeTemplate build() { - var tag = MIStructureTemplateManager.load(id); - if (tag == null) { - throw new IllegalStateException("Failed to load structure with id %s".formatted(id)); - } - ShapeTemplate template = MIStructureTemplateManager.deserialize(tag); - if (template == null) { - throw new IllegalStateException("Failed to parse structure with id %s".formatted(id)); - } - return template; + return MIStructureTemplateManager.get(id); } } } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java index 5ea1f56e1..ac392376b 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java @@ -32,16 +32,18 @@ import aztech.modern_industrialization.machines.models.MachineCasings; import aztech.modern_industrialization.machines.multiblocks.ShapeTemplate; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; -import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.function.BiConsumer; import net.minecraft.FileUtil; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -58,10 +60,35 @@ import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.levelgen.structure.BoundingBox; +import net.neoforged.fml.ModList; import net.neoforged.fml.loading.FMLPaths; +import net.neoforged.neoforgespi.language.IModFileInfo; import org.jetbrains.annotations.Nullable; public final class MIStructureTemplateManager { + private static Map STRUCTURE_TEMPLATES; + + private static void assertLoaded() { + if (STRUCTURE_TEMPLATES == null) { + throw new IllegalStateException("Structure templates have not yet been loaded"); + } + } + + public static boolean exists(ResourceLocation id) { + assertLoaded(); + return STRUCTURE_TEMPLATES.containsKey(id); + } + + public static ShapeTemplate get(ResourceLocation id) { + assertLoaded(); + ShapeTemplate template = STRUCTURE_TEMPLATES.get(id); + if (template != null) { + return template; + } else { + throw new IllegalArgumentException("Structure shape template \"" + id.toString() + "\" does not exist."); + } + } + public static StructureResult fromWorld(ResourceLocation id, Level level, BlockPos controllerPos, Direction controllerDirection, MachineCasing hatchCasing, StructureControllerBounds bounds) { @@ -160,7 +187,7 @@ public static StructureResult fromWorld(ResourceLocation id, Level level, } @Nullable - public static ShapeTemplate deserialize(CompoundTag tag) { + private static ShapeTemplate deserialize(CompoundTag tag) { Objects.requireNonNull(tag); ResourceLocation hatchCasingId = ResourceLocation.tryParse(tag.getString("hatch_casing")); @@ -189,12 +216,15 @@ public static ShapeTemplate deserialize(CompoundTag tag) { return builder.build(); } + private static Path structuresPath() { + return FMLPaths.GAMEDIR.get() + .resolve(MI.ID) + .resolve("structures"); + } + private static Path path(ResourceLocation id) throws IOException { Objects.requireNonNull(id); - var miFolder = FMLPaths.GAMEDIR.get().resolve(MI.ID); - var structuresFolder = miFolder - .resolve("structures") - .resolve(id.getNamespace()); + var structuresFolder = structuresPath().resolve(id.getNamespace()); Files.createDirectories(structuresFolder); return FileUtil.createPathToResource(structuresFolder, id.getPath(), ".nbt"); } @@ -203,39 +233,97 @@ public static boolean save(ResourceLocation id, CompoundTag tag) { Objects.requireNonNull(id); Objects.requireNonNull(tag); try { - try (OutputStream output = new FileOutputStream(path(id).toFile())) { + try (OutputStream output = Files.newOutputStream(path(id))) { NbtIo.writeCompressed(tag, output); return true; } catch (Exception ex) { - MI.LOGGER.error("Failed to save structure '{}'", id, ex); + MI.LOGGER.error("Failed to save structure \"{}\"", id, ex); } } catch (Exception ex) { - MI.LOGGER.error("Failed to save structure '{}'", id, ex); + MI.LOGGER.error("Failed to save structure \"{}\"", id, ex); } return false; } @Nullable - public static CompoundTag load(ResourceLocation id) { - Objects.requireNonNull(id); + private static CompoundTag load(Path path) { + Objects.requireNonNull(path); try { - Path path = path(id); if (Files.exists(path)) { - try (InputStream input = new FileInputStream(path.toFile()); + try (InputStream input = Files.newInputStream(path); InputStream fastInput = new FastBufferedInputStream(input)) { return NbtIo.readCompressed(fastInput, NbtAccounter.unlimitedHeap()); } catch (Exception ex) { - MI.LOGGER.error("Failed to load structure '{}'", id, ex); + MI.LOGGER.error("Failed to load structure at \"{}\"", path, ex); return null; } } + MI.LOGGER.error("Could not find structure at \"{}\"", path); return null; } catch (Exception ex) { - MI.LOGGER.error("Failed to load structure '{}'", id, ex); + MI.LOGGER.error("Failed to load structure at \"{}\"", path, ex); return null; } } + private static void iterateStructureFiles(Path origin, BiConsumer action) throws IOException { + try (DirectoryStream subdirectories = Files.newDirectoryStream(origin, Files::isDirectory)) { + for (Path subdirectory : subdirectories) { + String namespace = subdirectory.getFileName().toString(); + try (DirectoryStream files = Files.newDirectoryStream(subdirectory)) { + for (Path file : files) { + if (file.toString().endsWith(".nbt")) { + String rawFileName = file.getFileName().toString(); + String path = rawFileName.substring(0, rawFileName.lastIndexOf('.')); + ResourceLocation id = ResourceLocation.fromNamespaceAndPath(namespace, path); + action.accept(id, file); + } + } + } + } + } + } + + private static void register(ResourceLocation id, Path path) { + CompoundTag structureTag = load(path); + if (structureTag != null) { + ShapeTemplate structure = deserialize(structureTag); + if (structure != null) { + STRUCTURE_TEMPLATES.put(id, structure); + } else { + MI.LOGGER.error("Failed to load structure with id \"{}\"", id); + } + } + } + + public static void init() { + if (STRUCTURE_TEMPLATES != null) { + throw new IllegalStateException("Structures have already been loaded"); + } + + STRUCTURE_TEMPLATES = new HashMap<>(); + + try { + var structuresPath = structuresPath(); + Files.createDirectories(structuresPath); + iterateStructureFiles(structuresPath, MIStructureTemplateManager::register); + + for (IModFileInfo modFile : ModList.get().getModFiles()) { + Path modStructuresPath = modFile.getFile().findResource("mi_structures"); + iterateStructureFiles(modStructuresPath, (id, path) -> { + if (STRUCTURE_TEMPLATES.containsKey(id)) { + return; + } + register(id, path); + }); + } + + MI.LOGGER.info("Loaded {} structures.", STRUCTURE_TEMPLATES.size()); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + private MIStructureTemplateManager() { } } diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java index a423a375d..3d20fab7c 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java @@ -62,10 +62,9 @@ public void handle(Context ctx) { var result = MIStructureTemplateManager.fromWorld(id, level, pos, state.getValue(StructureMultiblockControllerBlock.FACING), controller.getCasing(), controller.getBounds()); - if (result instanceof StructureResult.Success success) { - if (!MIStructureTemplateManager.save(id, success.tag())) { - result = new StructureResult.Unknown(); - } + if (result instanceof StructureResult.Success success && + !MIStructureTemplateManager.save(id, success.tag())) { + result = new StructureResult.Unknown(); } result.send(player); } From 882d1bf0149bc079acb3e835461aad9a74a3d5ca Mon Sep 17 00:00:00 2001 From: Swedz Date: Sat, 23 Nov 2024 07:31:02 -0500 Subject: [PATCH 26/89] Use correct variable when saving the structure id for a controller --- .../structure/StructureMultiblockControllerBlockEntity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java index 83611b4e3..07ea805bd 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java @@ -129,7 +129,7 @@ public CompoundTag getUpdateTag(HolderLookup.Provider registries) { @Override protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { super.saveAdditional(tag, registries); - if (id != null) { + if (inputId != null) { tag.putString("structure_id", inputId); } if (inputCasing != null) { From c652e5fc1885843edb861d7d36b855aa15f2a220 Mon Sep 17 00:00:00 2001 From: Swedz Date: Sat, 23 Nov 2024 09:51:32 -0500 Subject: [PATCH 27/89] Add button to load structures from the controller --- ...ructureMultiblockControllerEditScreen.java | 104 +++++++++++++++--- .../StructureMultiblockHatchEditScreen.java | 12 +- .../StructureMultiblockMemberEditScreen.java | 8 +- .../modern_industrialization/lang/en_us.json | 4 + .../modern_industrialization/MIText.java | 5 + .../structure/StructureControllerMode.java | 40 +++++++ ...uctureMultiblockControllerBlockEntity.java | 14 +++ .../StructureMultiblockHatchBlockEntity.java | 2 +- .../StructureMultiblockMemberBlockEntity.java | 2 +- .../debug/DebugCommands.java | 16 +-- .../machines/models/MachineCasing.java | 5 + .../machines/multiblocks/ShapeMatcher.java | 41 ++++++- .../StructureMultiblockFormatters.java | 60 ++++++++++ .../structure/member/StructureMember.java | 33 +++++- .../member/StructureMemberTestState.java | 2 +- .../member/StructureMemberTestTag.java | 4 + .../network/MIPackets.java | 2 + .../StructureLoadControllerPacket.java | 82 ++++++++++++++ .../StructureUpdateControllerPacket.java | 7 +- 19 files changed, 392 insertions(+), 51 deletions(-) create mode 100644 src/main/java/aztech/modern_industrialization/blocks/structure/StructureControllerMode.java create mode 100644 src/main/java/aztech/modern_industrialization/network/structure/StructureLoadControllerPacket.java diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java index 90e4c4b68..1ab40b00c 100644 --- a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java @@ -26,11 +26,15 @@ import aztech.modern_industrialization.MIBlock; import aztech.modern_industrialization.MIText; import aztech.modern_industrialization.blocks.structure.StructureControllerBounds; +import aztech.modern_industrialization.blocks.structure.StructureControllerMode; import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlockEntity; import aztech.modern_industrialization.machines.models.MachineCasing; +import aztech.modern_industrialization.machines.multiblocks.structure.MIStructureTemplateManager; import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockFormatters; +import aztech.modern_industrialization.network.structure.StructureLoadControllerPacket; import aztech.modern_industrialization.network.structure.StructureSaveControllerPacket; import aztech.modern_industrialization.network.structure.StructureUpdateControllerPacket; +import com.google.common.collect.ImmutableList; import com.mojang.blaze3d.platform.InputConstants; import java.util.Optional; import net.minecraft.client.Minecraft; @@ -38,6 +42,7 @@ import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.CycleButton; import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.gui.components.Tooltip; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; @@ -47,11 +52,15 @@ public class StructureMultiblockControllerEditScreen extends Screen { private static final int VALID_TEXT_COLOR = 0xE0E0E0; private static final int INVALID_TEXT_COLOR = 0xE07272; + private static final ImmutableList ALL_MODES = ImmutableList.copyOf(StructureControllerMode.values()); + private final StructureMultiblockControllerBlockEntity controller; private Button doneButton; private Button cancelButton; + private CycleButton modeButton; private Button saveButton; + private Button loadButton; private EditBox idBox; private EditBox casingBox; @@ -71,7 +80,11 @@ public StructureMultiblockControllerEditScreen(StructureMultiblockControllerBloc } private Optional getId() { - return Optional.ofNullable(ResourceLocation.tryParse(idBox.getValue())); + ResourceLocation id = ResourceLocation.tryParse(idBox.getValue()); + return switch (modeButton.getValue()) { + case SAVE -> Optional.ofNullable(id); + case LOAD -> id != null && MIStructureTemplateManager.exists(id) ? Optional.of(id) : Optional.empty(); + }; } private Optional getCasing() { @@ -92,9 +105,44 @@ private Optional getBounds() { } } + private void updateMode(StructureControllerMode mode) { + this.sendToServer(); + + saveButton.visible = false; + loadButton.visible = false; + casingBox.visible = false; + posXBox.visible = false; + posYBox.visible = false; + posZBox.visible = false; + sizeXBox.visible = false; + sizeYBox.visible = false; + sizeZBox.visible = false; + showBoundsBox.visible = false; + + switch (mode) { + case SAVE -> { + saveButton.visible = true; + casingBox.visible = true; + posXBox.visible = true; + posYBox.visible = true; + posZBox.visible = true; + sizeXBox.visible = true; + sizeYBox.visible = true; + sizeZBox.visible = true; + showBoundsBox.visible = true; + } + case LOAD -> { + loadButton.visible = true; + } + } + + idBox.setValue(idBox.getValue()); + } + private void updateId() { boolean validId = idBox.getValue().isEmpty() || this.getId().isPresent(); idBox.setTextColor(validId ? VALID_TEXT_COLOR : INVALID_TEXT_COLOR); + loadButton.active = validId; } private void updateCasing() { @@ -108,6 +156,7 @@ private void updateBounds() { } private void updateAll() { + this.updateMode(controller.getMode()); this.updateId(); this.updateCasing(); this.updateBounds(); @@ -119,12 +168,13 @@ private void done() { } private void sendToServer() { - minecraft.getConnection().send(new StructureUpdateControllerPacket( + new StructureUpdateControllerPacket( controller.getBlockPos(), + modeButton.getValue(), idBox.getValue(), casingBox.getValue(), this.getBounds().orElse(new StructureControllerBounds(0, 0, 0, 1, 1, 1)), - showBoundsBox.getValue())); + showBoundsBox.getValue()).sendToServer(); } private void cancel() { @@ -133,7 +183,13 @@ private void cancel() { private void save() { this.sendToServer(); - minecraft.getConnection().send(new StructureSaveControllerPacket(controller.getBlockPos())); + new StructureSaveControllerPacket(controller.getBlockPos()).sendToServer(); + minecraft.setScreen(null); + } + + private void load() { + this.sendToServer(); + new StructureLoadControllerPacket(controller.getBlockPos(), !hasShiftDown()).sendToServer(); minecraft.setScreen(null); } @@ -146,6 +202,16 @@ protected void init() { this.addRenderableWidget( saveButton = Button.builder(Component.translatable("structure_block.button.save"), button -> this.save()) .bounds(width / 2 + 4 + 100, 185, 50, 20).build()); + this.addRenderableWidget( + loadButton = Button.builder(Component.translatable("structure_block.button.load"), button -> this.load()) + .bounds(width / 2 + 4 + 100, 185, 50, 20) + .tooltip(Tooltip.create(MIText.StructureMultiblockLoadTooltip.text())) + .build()); + this.addRenderableWidget(modeButton = CycleButton.builder(StructureControllerMode::text) + .withValues(ALL_MODES, ALL_MODES) + .displayOnlyValue() + .withInitialValue(controller.getMode()) + .create(width / 2 - 4 - 150, 185, 50, 20, Component.literal("MODE"), (button, mode) -> this.updateMode(mode))); idBox = new EditBox(font, width / 2 - 152, 50, 304, 20, MIText.StructureMultiblockStructureName.text()) { @Override @@ -171,33 +237,33 @@ public boolean charTyped(char codePoint, int modifiers) { StructureControllerBounds bounds = controller.getBounds(); - posXBox = new EditBox(font, width / 2 - 152, 130, 80, 20, Component.translatable("structure_block.position.x")); + posXBox = new EditBox(font, width / 2 - 152, 130, 35, 20, Component.translatable("structure_block.position.x")); posXBox.setMaxLength(15); posXBox.setValue(Integer.toString(bounds.x())); posXBox.setResponder(text -> this.updateBounds()); this.addRenderableWidget(posXBox); - posYBox = new EditBox(font, width / 2 - 72, 130, 80, 20, Component.translatable("structure_block.position.y")); + posYBox = new EditBox(font, width / 2 - 117, 130, 35, 20, Component.translatable("structure_block.position.y")); posYBox.setMaxLength(15); posYBox.setValue(Integer.toString(bounds.y())); posYBox.setResponder(text -> this.updateBounds()); this.addRenderableWidget(posYBox); - posZBox = new EditBox(font, width / 2 + 8, 130, 80, 20, Component.translatable("structure_block.position.z")); + posZBox = new EditBox(font, width / 2 - 82, 130, 35, 20, Component.translatable("structure_block.position.z")); posZBox.setMaxLength(15); posZBox.setValue(Integer.toString(bounds.z())); posZBox.setResponder(text -> this.updateBounds()); this.addRenderableWidget(posZBox); - sizeXBox = new EditBox(font, width / 2 - 152, 170, 80, 20, Component.translatable("structure_block.size.x")); + sizeXBox = new EditBox(font, width / 2 - 47 + 8, 130, 35, 20, Component.translatable("structure_block.size.x")); sizeXBox.setMaxLength(15); sizeXBox.setValue(Integer.toString(bounds.sizeX())); sizeXBox.setResponder(text -> this.updateBounds()); this.addRenderableWidget(sizeXBox); - sizeYBox = new EditBox(font, width / 2 - 72, 170, 80, 20, Component.translatable("structure_block.size.y")); + sizeYBox = new EditBox(font, width / 2 - 4, 130, 35, 20, Component.translatable("structure_block.size.y")); sizeYBox.setMaxLength(15); sizeYBox.setValue(Integer.toString(bounds.sizeY())); sizeYBox.setResponder(text -> this.updateBounds()); this.addRenderableWidget(sizeYBox); - sizeZBox = new EditBox(font, width / 2 + 8, 170, 80, 20, Component.translatable("structure_block.size.z")); + sizeZBox = new EditBox(font, width / 2 + 31, 130, 35, 20, Component.translatable("structure_block.size.z")); sizeZBox.setMaxLength(15); sizeZBox.setValue(Integer.toString(bounds.sizeZ())); sizeZBox.setResponder(text -> this.updateBounds()); @@ -216,16 +282,22 @@ public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTi graphics.drawCenteredString(font, title, width / 2, 20, 0xFFFFFF); - graphics.drawString(font, MIText.StructureMultiblockStructureName.text(), width / 2 - 153, 40, 0xA0A0A0); + graphics.drawString(font, MIText.StructureMultiblockStructureName.text(), width / 2 - 152, 40, 0xA0A0A0); + + if (casingBox.visible) + graphics.drawString(font, MIText.StructureMultiblockHatchCasing.text(), width / 2 - 152, 80, 0xA0A0A0); - graphics.drawString(font, MIText.StructureMultiblockHatchCasing.text(), width / 2 - 153, 80, 0xA0A0A0); + if (posXBox.visible || posYBox.visible || posZBox.visible) + graphics.drawString(font, Component.translatable("structure_block.position"), width / 2 - 152, 120, 0xA0A0A0); - graphics.drawString(font, Component.translatable("structure_block.position"), width / 2 - 153, 120, 0xA0A0A0); + if (sizeXBox.visible || sizeYBox.visible || sizeZBox.visible) + graphics.drawString(font, Component.translatable("structure_block.size"), width / 2 - 47 + 8, 120, 0xA0A0A0); - graphics.drawString(font, Component.translatable("structure_block.size"), width / 2 - 153, 160, 0xA0A0A0); + if (showBoundsBox.visible) + graphics.drawString(font, Component.translatable("structure_block.show_boundingbox"), + width / 2 + 154 - font.width(Component.translatable("structure_block.show_boundingbox")), 120, 0xA0A0A0); - graphics.drawString(font, Component.translatable("structure_block.show_boundingbox"), - width / 2 + 154 - font.width(Component.translatable("structure_block.show_boundingbox")), 120, 10526880); + graphics.drawString(font, modeButton.getValue().textInfo(), width / 2 - 4 - 150, 175, 0xA0A0A0); } @Override diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockHatchEditScreen.java b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockHatchEditScreen.java index ec74d57fa..11bfa9b42 100644 --- a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockHatchEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockHatchEditScreen.java @@ -113,12 +113,12 @@ private void done() { } private void sendToServer() { - minecraft.getConnection().send(new StructureUpdateHatchPacket( + new StructureUpdateHatchPacket( hatch.getBlockPos(), previewBox.getValue(), membersBox.getValue(), casingBox.getValue(), - flagsBox.getValue())); + flagsBox.getValue()).sendToServer(); } private void cancel() { @@ -176,13 +176,13 @@ public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTi graphics.drawCenteredString(font, title, width / 2, 20, 0xFFFFFF); - graphics.drawString(font, MIText.StructureMultiblockMemberPreview.text(), width / 2 - 153, 40, 0xA0A0A0); + graphics.drawString(font, MIText.StructureMultiblockMemberPreview.text(), width / 2 - 152, 40, 0xA0A0A0); - graphics.drawString(font, MIText.StructureMultiblockMemberMembers.text(), width / 2 - 153, 80, 0xA0A0A0); + graphics.drawString(font, MIText.StructureMultiblockMemberMembers.text(), width / 2 - 152, 80, 0xA0A0A0); - graphics.drawString(font, MIText.StructureMultiblockHatchCasing.text(), width / 2 - 153, 120, 0xA0A0A0); + graphics.drawString(font, MIText.StructureMultiblockHatchCasing.text(), width / 2 - 152, 120, 0xA0A0A0); - graphics.drawString(font, MIText.StructureMultiblockHatchFlags.text(), width / 2 - 153, 160, 0xA0A0A0); + graphics.drawString(font, MIText.StructureMultiblockHatchFlags.text(), width / 2 - 152, 160, 0xA0A0A0); } @Override diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java index 0f32c95a9..d964b54b3 100644 --- a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java @@ -87,10 +87,10 @@ private void done() { } private void sendToServer() { - minecraft.getConnection().send(new StructureUpdateMemberPacket( + new StructureUpdateMemberPacket( member.getBlockPos(), previewBox.getValue(), - membersBox.getValue())); + membersBox.getValue()).sendToServer(); } private void cancel() { @@ -125,9 +125,9 @@ public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTi graphics.drawCenteredString(font, title, width / 2, 20, 0xFFFFFF); - graphics.drawString(font, MIText.StructureMultiblockMemberPreview.text(), width / 2 - 153, 40, 0xA0A0A0); + graphics.drawString(font, MIText.StructureMultiblockMemberPreview.text(), width / 2 - 152, 40, 0xA0A0A0); - graphics.drawString(font, MIText.StructureMultiblockMemberMembers.text(), width / 2 - 153, 80, 0xA0A0A0); + graphics.drawString(font, MIText.StructureMultiblockMemberMembers.text(), width / 2 - 152, 80, 0xA0A0A0); } @Override diff --git a/src/generated/resources/assets/modern_industrialization/lang/en_us.json b/src/generated/resources/assets/modern_industrialization/lang/en_us.json index c45e8d7ed..e17aabb0a 100644 --- a/src/generated/resources/assets/modern_industrialization/lang/en_us.json +++ b/src/generated/resources/assets/modern_industrialization/lang/en_us.json @@ -1696,6 +1696,10 @@ "text.modern_industrialization.SteamDrillWaterHelp": "- Press %s on still or flowing water to fill.", "text.modern_industrialization.StructureMultiblockHatchCasing": "Machine Casing", "text.modern_industrialization.StructureMultiblockHatchFlags": "Hatch Flags", + "text.modern_industrialization.StructureMultiblockLoadFailDoesntExist": "Failed to place the structure. No structure exists as %s.", + "text.modern_industrialization.StructureMultiblockLoadFailInvalidId": "Failed to place the structure. No id was provided.", + "text.modern_industrialization.StructureMultiblockLoadSuccess": "Successfully placed the structure %s.", + "text.modern_industrialization.StructureMultiblockLoadTooltip": "Hold SHIFT to place actual blocks instead of structure blocks.", "text.modern_industrialization.StructureMultiblockMemberMembers": "Members", "text.modern_industrialization.StructureMultiblockMemberPreview": "Preview", "text.modern_industrialization.StructureMultiblockSaveFailInvalidBounds": "Failed to save structure. The bounds provided are not valid.", diff --git a/src/main/java/aztech/modern_industrialization/MIText.java b/src/main/java/aztech/modern_industrialization/MIText.java index 8f92f456b..1f2b67111 100644 --- a/src/main/java/aztech/modern_industrialization/MIText.java +++ b/src/main/java/aztech/modern_industrialization/MIText.java @@ -27,6 +27,7 @@ import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; +// TODO SWEDZ: alphabetize public enum MIText { ModernIndustrialization("Modern Industrialization"), @@ -251,6 +252,10 @@ public enum MIText { StructureMultiblockMemberMembers("Members"), StructureMultiblockMemberPreview("Preview"), StructureMultiblockStructureName("Structure Name"), + StructureMultiblockLoadTooltip("Hold SHIFT to place actual blocks instead of structure blocks."), + StructureMultiblockLoadFailInvalidId("Failed to place the structure. No id was provided."), + StructureMultiblockLoadFailDoesntExist("Failed to place the structure. No structure exists as %s."), + StructureMultiblockLoadSuccess("Successfully placed the structure %s."), StructureMultiblockSaveFailInvalidBounds("Failed to save structure. The bounds provided are not valid."), StructureMultiblockSaveFailMisconfiguredBlock("Failed to save structure. Some blocks are not properly configured."), StructureMultiblockSaveFailTooManyControllers("Failed to save structure. Too many controllers exist within the bounds."), diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureControllerMode.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureControllerMode.java new file mode 100644 index 000000000..c47b5ca43 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureControllerMode.java @@ -0,0 +1,40 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.blocks.structure; + +import java.util.Locale; +import net.minecraft.network.chat.Component; + +public enum StructureControllerMode { + SAVE, + LOAD; + + public Component textInfo() { + return Component.translatable("structure_block.mode_info." + this.name().toLowerCase(Locale.ROOT)); + } + + public Component text() { + return Component.translatable("structure_block.mode." + this.name().toLowerCase(Locale.ROOT)); + } +} diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java index 07ea805bd..dd740e19e 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java @@ -28,6 +28,8 @@ import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockFormatters; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; +import java.util.Locale; +import java.util.Objects; import net.minecraft.core.BlockPos; import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; @@ -44,6 +46,8 @@ public class StructureMultiblockControllerBlockEntity extends FastBlockEntity im private String inputId; private String inputCasing; + private StructureControllerMode mode = StructureControllerMode.SAVE; + private ResourceLocation id; private MachineCasing casing; private StructureControllerBounds bounds = new StructureControllerBounds(0, 0, 0, 1, 1, 1); @@ -53,6 +57,14 @@ public StructureMultiblockControllerBlockEntity(BlockPos pos, BlockState state) super(MIRegistries.STRUCTURE_MULTIBLOCK_CONTROLLER_BE.get(), pos, state); } + public StructureControllerMode getMode() { + return mode; + } + + public void setMode(StructureControllerMode mode) { + this.mode = Objects.requireNonNull(mode); + } + @Nullable public String getInputId() { return inputId; @@ -129,6 +141,7 @@ public CompoundTag getUpdateTag(HolderLookup.Provider registries) { @Override protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { super.saveAdditional(tag, registries); + tag.putString("mode", mode.toString().toLowerCase(Locale.ROOT)); if (inputId != null) { tag.putString("structure_id", inputId); } @@ -145,6 +158,7 @@ protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) @Override protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { super.loadAdditional(tag, registries); + mode = StructureControllerMode.valueOf(tag.getString("mode").toUpperCase(Locale.ROOT)); this.setInputId(tag.getString("structure_id")); this.setInputCasing(tag.getString("casing")); if (tag.contains("bounds", Tag.TAG_COMPOUND)) { diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlockEntity.java index 11574877f..dc256e9fc 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlockEntity.java @@ -117,7 +117,7 @@ public HatchFlags getFlags() { @Override public StructureMember getMemberOverride() { - return new StructureMember(() -> preview, members, flags); + return new StructureMember(() -> preview, members, casing, flags); } @Override diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java index cf7650045..b70b6ad5c 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java @@ -81,7 +81,7 @@ public List getMembers() { @Override public StructureMember getMemberOverride() { - return new StructureMember(() -> preview, members, null); + return new StructureMember(() -> preview, members, null, null); } @Override diff --git a/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java b/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java index c8e34f471..31787c201 100644 --- a/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java +++ b/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java @@ -109,12 +109,6 @@ public static void init() { .then(argument("controller_pos", blockPos()) .executes(ctx -> { return structuresTest(ctx.getSource(), getId(ctx, "structure_id"), getLoadedBlockPos(ctx, "controller_pos")); - })))) - .then(literal("build") - .then(argument("structure_id", id()) - .then(argument("controller_pos", blockPos()) - .executes(ctx -> { - return structuresBuild(ctx.getSource(), getId(ctx, "structure_id"), getLoadedBlockPos(ctx, "controller_pos")); }))))) ) ); @@ -191,7 +185,7 @@ private static int buildMultiblock(CommandSourceStack src, BlockPos controllerPo var be = src.getLevel().getBlockEntity(controllerPos); if (be instanceof MultiblockMachineBlockEntity multiblock) { var shapeMatcher = multiblock.createShapeMatcher(); - int updatedBlocks = shapeMatcher.buildMultiblock(src.getLevel()); + int updatedBlocks = shapeMatcher.buildMultiblock(src.getLevel(), false); src.sendSuccess(() -> Component.literal("Successfully built multiblock at position %s. %d blocks updated.".formatted( controllerPos, updatedBlocks)), true); @@ -229,12 +223,4 @@ private static int structuresTest(CommandSourceStack src, ResourceLocation id, B true); }); } - - private static int structuresBuild(CommandSourceStack src, ResourceLocation id, BlockPos controllerPos) { - return structures(src, id, controllerPos, (matcher) -> { - matcher.buildMultiblock(src.getLevel()); - src.sendSuccess(() -> Component.literal("Built multiblock %s at position %s".formatted(id, controllerPos.toShortString())), - true); - }); - } } diff --git a/src/main/java/aztech/modern_industrialization/machines/models/MachineCasing.java b/src/main/java/aztech/modern_industrialization/machines/models/MachineCasing.java index df6f8f259..4d4fe8d62 100644 --- a/src/main/java/aztech/modern_industrialization/machines/models/MachineCasing.java +++ b/src/main/java/aztech/modern_industrialization/machines/models/MachineCasing.java @@ -31,4 +31,9 @@ public class MachineCasing { MachineCasing(ResourceLocation key) { this.key = key; } + + @Override + public boolean equals(Object o) { + return o instanceof MachineCasing other && key.equals(other.key); + } } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java index 6699595f2..b2150029a 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java @@ -23,6 +23,10 @@ */ package aztech.modern_industrialization.machines.multiblocks; +import aztech.modern_industrialization.MIBlock; +import aztech.modern_industrialization.blocks.structure.StructureMultiblockHatchBlockEntity; +import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlockEntity; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockFormatters; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; import aztech.modern_industrialization.machines.multiblocks.world.ChunkEventListener; import aztech.modern_industrialization.machines.multiblocks.world.ChunkEventListeners; @@ -244,15 +248,46 @@ public void unregisterListeners(Level world) { } } - public int buildMultiblock(Level level) { + public int buildMultiblock(Level level, boolean structureBlocks) { int setBlocks = 0; for (var entry : simpleMembers.entrySet()) { BlockPos pos = entry.getKey(); var current = level.getBlockState(pos); - if (!entry.getValue().matchesState(current)) { + if (!entry.getValue().matchesState(current) || structureBlocks) { BlockState state = entry.getValue().getPreviewState(); - if (entry.getValue() instanceof StructureMember) { + if (entry.getValue() instanceof StructureMember member) { + // TODO SWEDZ: there has gotta be a better way to do this + if (structureBlocks) { + boolean hasMultipleTests = member.tests().size() > 1; + boolean hasHatchFlags = member.hatchFlags() != null && member.hatchFlags().flags != 0; + + if (hasMultipleTests && !hasHatchFlags) { + state = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.asBlock().defaultBlockState(); + level.setBlockAndUpdate(pos, state); + StructureMultiblockMemberBlockEntity be = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.get().newBlockEntity(pos, state); + be.setInputPreview(StructureMultiblockFormatters.preview(member.preview())); + be.setInputMembers(StructureMultiblockFormatters.members(member.tests())); + level.setBlockEntity(be); + be.setChanged(); + be.sync(); + setBlocks++; + continue; + } else if (hasHatchFlags) { + state = MIBlock.STRUCTURE_MULTIBLOCK_HATCH.asBlock().defaultBlockState(); + level.setBlockAndUpdate(pos, state); + StructureMultiblockHatchBlockEntity be = MIBlock.STRUCTURE_MULTIBLOCK_HATCH.get().newBlockEntity(pos, state); + be.setInputPreview(StructureMultiblockFormatters.preview(member.preview())); + be.setInputMembers(StructureMultiblockFormatters.members(member.tests())); + be.setInputCasing(StructureMultiblockFormatters.casing(member.casing())); + be.setInputFlags(StructureMultiblockFormatters.hatchFlags(member.hatchFlags())); + level.setBlockEntity(be); + be.setChanged(); + be.sync(); + setBlocks++; + continue; + } + } state = toWorldState(level, pos, state, controllerDirection); } level.setBlockAndUpdate(pos, state); diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockFormatters.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockFormatters.java index 5e8c1f185..06da7a9bd 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockFormatters.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockFormatters.java @@ -64,6 +64,14 @@ public static MachineCasing casing(String input) { return null; } + @Nullable + public static String casing(MachineCasing casing) { + if (casing == null) { + return null; + } + return casing.key.toString(); + } + @Nullable public static BlockState preview(String inputPreview) { if (inputPreview == null || inputPreview.isEmpty()) { @@ -79,6 +87,14 @@ public static BlockState preview(String inputPreview) { } } + @Nullable + public static String preview(BlockState preview) { + if (preview == null) { + return null; + } + return BlockStateParser.serialize(preview); + } + @Nullable public static List members(String inputMembers) { if (inputMembers == null || inputMembers.isEmpty()) { @@ -107,6 +123,29 @@ public static List members(String inputMembers) { return members; } + @Nullable + public static String members(List members) { + if (members == null) { + return null; + } + + StringBuilder string = new StringBuilder(); + for (StructureMemberTest test : members) { + if (test instanceof StructureMemberTestTag testTag) { + if (!string.isEmpty()) { + string.append(";"); + } + string.append("#").append(testTag.blockTag().location()); + } else if (test instanceof StructureMemberTestState stateTest) { + if (!string.isEmpty()) { + string.append(";"); + } + string.append(BlockStateParser.serialize(stateTest.blockState())); + } + } + return string.toString(); + } + @Nullable public static HatchFlags hatchFlags(String input) { if (input == null || input.isEmpty()) { @@ -128,6 +167,27 @@ public static HatchFlags hatchFlags(String input) { return builder.build(); } + @Nullable + public static String hatchFlags(HatchFlags hatchFlags) { + if (hatchFlags == null || hatchFlags.flags == 0) { + return null; + } + + StringBuilder string = new StringBuilder(); + for (HatchType hatchType : HatchType.values()) { + if (hatchFlags.allows(hatchType)) { + if (!string.isEmpty()) { + string.append(";"); + } + string.append(hatchType.toString().toLowerCase(Locale.ROOT)); + } + } + if (string.isEmpty()) { + return String.valueOf(hatchFlags.flags); + } + return string.toString(); + } + private StructureMultiblockFormatters() { } } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java index b3b33ec06..a384937e9 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java @@ -23,6 +23,8 @@ */ package aztech.modern_industrialization.machines.multiblocks.structure.member; +import aztech.modern_industrialization.machines.models.MachineCasing; +import aztech.modern_industrialization.machines.models.MachineCasings; import aztech.modern_industrialization.machines.multiblocks.HatchFlags; import aztech.modern_industrialization.machines.multiblocks.SimpleMember; import java.util.ArrayList; @@ -35,23 +37,28 @@ import net.minecraft.nbt.ListTag; import net.minecraft.nbt.NbtUtils; import net.minecraft.nbt.Tag; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; public final class StructureMember implements SimpleMember { private final Supplier previewSupplier; private final List tests; + private final MachineCasing casing; private final HatchFlags hatchFlags; private BlockState preview; - public StructureMember(Supplier preview, List tests, HatchFlags hatchFlags) { + public StructureMember(Supplier preview, List tests, @Nullable MachineCasing casing, + @Nullable HatchFlags hatchFlags) { this.previewSupplier = preview; this.tests = tests; + this.casing = casing; this.hatchFlags = hatchFlags; } public StructureMember(Supplier state) { - this(state, List.of(new StructureMemberTestState(state)), null); + this(state, List.of(new StructureMemberTestState(state)), null, null); } public BlockState preview() { @@ -65,6 +72,12 @@ public List tests() { return Collections.unmodifiableList(tests); } + @Nullable + public MachineCasing casing() { + return casing; + } + + @Nullable public HatchFlags hatchFlags() { return hatchFlags; } @@ -89,6 +102,7 @@ public boolean equals(Object o) { if (o instanceof StructureMember other) { return this.preview() == other.preview() && tests.containsAll(other.tests) && other.tests.containsAll(tests) && + Objects.equals(casing, other.casing) && Objects.equals(hatchFlags, other.hatchFlags); } return false; @@ -106,6 +120,10 @@ public void save(CompoundTag tag) { } tag.put("tests", testsTag); + if (casing != null) { + tag.putString("casing", casing.key.toString()); + } + if (hatchFlags != null) { tag.putInt("hatch_flags", hatchFlags.flags); } @@ -133,12 +151,21 @@ public static StructureMember from(CompoundTag tag) { return null; } + MachineCasing casing = null; + if (tag.contains("casing", Tag.TAG_STRING)) { + ResourceLocation casingId = ResourceLocation.tryParse(tag.getString("casing")); + if (casingId == null || !MachineCasings.registeredCasings.containsKey(casingId)) { + return null; + } + casing = MachineCasings.get(casingId); + } + int hatchFlagsValue = tag.getInt("hatch_flags"); HatchFlags hatchFlags = null; if (hatchFlagsValue != 0) { hatchFlags = new HatchFlags(hatchFlagsValue); } - return new StructureMember(preview, tests, hatchFlags); + return new StructureMember(preview, tests, casing, hatchFlags); } } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestState.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestState.java index 41a8025a1..5042cffdb 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestState.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestState.java @@ -42,7 +42,7 @@ public StructureMemberTestState() { this(null); } - private BlockState blockState() { + public BlockState blockState() { if (blockState == null) { blockState = blockStateSupplier.get(); } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestTag.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestTag.java index 2de9bd1f9..db05db286 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestTag.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestTag.java @@ -41,6 +41,10 @@ public StructureMemberTestTag() { this(null); } + public TagKey blockTag() { + return blockTag; + } + @Override public String id() { return "tag"; diff --git a/src/main/java/aztech/modern_industrialization/network/MIPackets.java b/src/main/java/aztech/modern_industrialization/network/MIPackets.java index 3674fa60c..8c97ef558 100644 --- a/src/main/java/aztech/modern_industrialization/network/MIPackets.java +++ b/src/main/java/aztech/modern_industrialization/network/MIPackets.java @@ -42,6 +42,7 @@ import aztech.modern_industrialization.network.pipes.SetItemWhitelistPacket; import aztech.modern_industrialization.network.pipes.SetNetworkFluidPacket; import aztech.modern_industrialization.network.pipes.SetPriorityPacket; +import aztech.modern_industrialization.network.structure.StructureLoadControllerPacket; import aztech.modern_industrialization.network.structure.StructureMisconfiguredBlocksPacket; import aztech.modern_industrialization.network.structure.StructureSaveControllerPacket; import aztech.modern_industrialization.network.structure.StructureUpdateControllerPacket; @@ -96,6 +97,7 @@ private static

void register(String path, Class

clazz, register("set_network_fluid", SetNetworkFluidPacket.class, SetNetworkFluidPacket.STREAM_CODEC); register("set_priority", SetPriorityPacket.class, SetPriorityPacket.STREAM_CODEC); // Structure blocks + register("structure_load_controller", StructureLoadControllerPacket.class, StructureLoadControllerPacket.STREAM_CODEC); register("structure_misconfigured_blocks", StructureMisconfiguredBlocksPacket.class, StructureMisconfiguredBlocksPacket.STREAM_CODEC); register("structure_save_controller", StructureSaveControllerPacket.class, StructureSaveControllerPacket.STREAM_CODEC); register("structure_update_controller", StructureUpdateControllerPacket.class, StructureUpdateControllerPacket.STREAM_CODEC); diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureLoadControllerPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureLoadControllerPacket.java new file mode 100644 index 000000000..6a3a8becb --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureLoadControllerPacket.java @@ -0,0 +1,82 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.network.structure; + +import aztech.modern_industrialization.MIText; +import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlockEntity; +import aztech.modern_industrialization.machines.multiblocks.ShapeMatcher; +import aztech.modern_industrialization.machines.multiblocks.ShapeTemplate; +import aztech.modern_industrialization.machines.multiblocks.structure.MIStructureTemplateManager; +import aztech.modern_industrialization.network.BasePacket; +import io.netty.buffer.ByteBuf; +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; + +public record StructureLoadControllerPacket(BlockPos pos, boolean structureBlocks) implements BasePacket { + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + BlockPos.STREAM_CODEC, + StructureLoadControllerPacket::pos, + ByteBufCodecs.BOOL, + StructureLoadControllerPacket::structureBlocks, + StructureLoadControllerPacket::new); + + @Override + public void handle(Context ctx) { + ctx.assertOnServer(); + + Player player = ctx.getPlayer(); + Level level = player.level(); + + if (!player.canUseGameMasterBlocks()) { + return; + } + + BlockState state = level.getBlockState(pos); + BlockEntity blockEntity = level.getBlockEntity(pos); + if (blockEntity instanceof StructureMultiblockControllerBlockEntity controller) { + ResourceLocation id = controller.getId(); + if (id == null) { + player.sendSystemMessage(MIText.StructureMultiblockLoadFailInvalidId.text().withStyle(ChatFormatting.RED)); + return; + } + if (!MIStructureTemplateManager.exists(id)) { + player.sendSystemMessage(MIText.StructureMultiblockLoadFailDoesntExist.text(id.toString()).withStyle(ChatFormatting.RED)); + return; + } + ShapeTemplate template = MIStructureTemplateManager.get(id); + ShapeMatcher shapeMatcher = new ShapeMatcher(level, pos, state.getValue(BlockStateProperties.HORIZONTAL_FACING), template); + shapeMatcher.buildMultiblock(level, structureBlocks); + player.sendSystemMessage(MIText.StructureMultiblockLoadSuccess.text(id.toString())); + } + } +} diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java index 493ebbbd1..9e5ab5438 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java @@ -24,6 +24,7 @@ package aztech.modern_industrialization.network.structure; import aztech.modern_industrialization.blocks.structure.StructureControllerBounds; +import aztech.modern_industrialization.blocks.structure.StructureControllerMode; import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlockEntity; import aztech.modern_industrialization.network.BasePacket; import io.netty.buffer.ByteBuf; @@ -35,12 +36,15 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; -public record StructureUpdateControllerPacket(BlockPos pos, String inputId, String inputCasing, StructureControllerBounds bounds, boolean showBounds) +public record StructureUpdateControllerPacket(BlockPos pos, StructureControllerMode mode, String inputId, String inputCasing, + StructureControllerBounds bounds, boolean showBounds) implements BasePacket { public static final StreamCodec STREAM_CODEC = StreamCodec.composite( BlockPos.STREAM_CODEC, StructureUpdateControllerPacket::pos, + ByteBufCodecs.idMapper((i) -> StructureControllerMode.values()[i], Enum::ordinal), + StructureUpdateControllerPacket::mode, ByteBufCodecs.STRING_UTF8, StructureUpdateControllerPacket::inputId, ByteBufCodecs.STRING_UTF8, @@ -64,6 +68,7 @@ public void handle(Context ctx) { BlockEntity blockEntity = level.getBlockEntity(pos); if (blockEntity instanceof StructureMultiblockControllerBlockEntity controller) { + controller.setMode(mode); controller.setInputId(inputId); controller.setInputCasing(inputCasing); controller.setBounds(bounds); From 3b42812ccc5383143f16244d20e511ffbfd7f320 Mon Sep 17 00:00:00 2001 From: Swedz Date: Sat, 23 Nov 2024 11:10:36 -0500 Subject: [PATCH 28/89] Remove structure multiblock hatch block in favor of the member block being capable of both functionalities --- .../modern_industrialization/MIClient.java | 1 - .../StructureMultiblockHatchEditScreen.java | 240 ------------------ .../StructureMultiblockMemberEditScreen.java | 61 ++++- .../proxy/ClientProxy.java | 9 - .../structure_multiblock_hatch.json | 7 - .../modern_industrialization/lang/en_us.json | 1 - .../block/structure_multiblock_hatch.json | 6 - .../item/structure_multiblock_hatch.json | 3 - .../modern_industrialization/MIBlock.java | 10 - .../MIRegistries.java | 6 - .../StructureMultiblockHatchBlock.java | 66 ----- .../StructureMultiblockHatchBlockEntity.java | 168 ------------ .../StructureMultiblockMemberBlock.java | 4 +- .../StructureMultiblockMemberBlockEntity.java | 59 ++++- .../machines/multiblocks/ShapeMatcher.java | 22 +- .../structure/MIStructureTemplateManager.java | 13 +- .../network/MIPackets.java | 2 - .../structure/StructureUpdateHatchPacket.java | 79 ------ .../StructureUpdateMemberPacket.java | 23 +- .../proxy/CommonProxy.java | 4 - .../block/structure_multiblock_hatch.png | Bin 335 -> 0 bytes 21 files changed, 146 insertions(+), 638 deletions(-) delete mode 100644 src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockHatchEditScreen.java delete mode 100644 src/generated/resources/assets/modern_industrialization/blockstates/structure_multiblock_hatch.json delete mode 100644 src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_hatch.json delete mode 100644 src/generated/resources/assets/modern_industrialization/models/item/structure_multiblock_hatch.json delete mode 100644 src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlock.java delete mode 100644 src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlockEntity.java delete mode 100644 src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateHatchPacket.java delete mode 100644 src/main/resources/assets/modern_industrialization/textures/block/structure_multiblock_hatch.png diff --git a/src/client/java/aztech/modern_industrialization/MIClient.java b/src/client/java/aztech/modern_industrialization/MIClient.java index d2c386918..33c75857b 100644 --- a/src/client/java/aztech/modern_industrialization/MIClient.java +++ b/src/client/java/aztech/modern_industrialization/MIClient.java @@ -243,7 +243,6 @@ private static void registerBlockEntityRenderers(FMLClientSetupEvent event) { BlockEntityRenderers.register(MIRegistries.CREATIVE_BARREL_BE.get(), context -> new BarrelRenderer(0x000000)); BlockEntityRenderers.register(MIRegistries.CREATIVE_TANK_BE.get(), context -> new TankRenderer(0x000000)); BlockEntityRenderers.register(MIRegistries.STRUCTURE_MULTIBLOCK_CONTROLLER_BE.get(), context -> new StructureMultiblockControllerBER()); - BlockEntityRenderers.register(MIRegistries.STRUCTURE_MULTIBLOCK_HATCH_BE.get(), context -> new StructureMultiblockBER<>()); BlockEntityRenderers.register(MIRegistries.STRUCTURE_MULTIBLOCK_MEMBER_BE.get(), context -> new StructureMultiblockBER<>()); blockEntityRendererRegistrations.forEach(Runnable::run); diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockHatchEditScreen.java b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockHatchEditScreen.java deleted file mode 100644 index 11bfa9b42..000000000 --- a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockHatchEditScreen.java +++ /dev/null @@ -1,240 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2020 Azercoco & Technici4n - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package aztech.modern_industrialization.gui.structure; - -import aztech.modern_industrialization.MIBlock; -import aztech.modern_industrialization.MIText; -import aztech.modern_industrialization.blocks.structure.StructureMultiblockHatchBlockEntity; -import aztech.modern_industrialization.machines.models.MachineCasing; -import aztech.modern_industrialization.machines.multiblocks.HatchFlags; -import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockFormatters; -import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMemberTest; -import aztech.modern_industrialization.network.structure.StructureUpdateHatchPacket; -import com.mojang.blaze3d.platform.InputConstants; -import java.util.List; -import java.util.Optional; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.components.Button; -import net.minecraft.client.gui.components.EditBox; -import net.minecraft.client.gui.screens.Screen; -import net.minecraft.network.chat.CommonComponents; -import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.block.state.BlockState; - -public class StructureMultiblockHatchEditScreen extends Screen { - private static final int VALID_TEXT_COLOR = 0xE0E0E0; - private static final int INVALID_TEXT_COLOR = 0xE07272; - - private final StructureMultiblockHatchBlockEntity hatch; - - private Button doneButton; - private Button cancelButton; - - private EditBox previewBox; - private EditBox membersBox; - - private EditBox casingBox; - private EditBox flagsBox; - - public StructureMultiblockHatchEditScreen(StructureMultiblockHatchBlockEntity hatch) { - super(Component.translatable(MIBlock.STRUCTURE_MULTIBLOCK_HATCH.asBlock().getDescriptionId())); - this.hatch = hatch; - } - - private Optional getPreview() { - return Optional.ofNullable(StructureMultiblockFormatters.preview(previewBox.getValue())); - } - - private Optional> getMembers() { - return Optional.ofNullable(StructureMultiblockFormatters.members(membersBox.getValue())); - } - - private Optional getCasing() { - return Optional.ofNullable(StructureMultiblockFormatters.casing(casingBox.getValue())); - } - - private Optional getHatchFlags() { - return Optional.ofNullable(StructureMultiblockFormatters.hatchFlags(flagsBox.getValue())); - } - - private void updatePreview() { - boolean validPreview = previewBox.getValue().isEmpty() || this.getPreview().isPresent(); - previewBox.setTextColor(validPreview ? VALID_TEXT_COLOR : INVALID_TEXT_COLOR); - } - - private void updateMembers() { - boolean validMembers = membersBox.getValue().isEmpty() || this.getMembers().isPresent(); - membersBox.setTextColor(validMembers ? VALID_TEXT_COLOR : INVALID_TEXT_COLOR); - } - - private void updateCasing() { - boolean validCasing = casingBox.getValue().isEmpty() || this.getCasing().isPresent(); - casingBox.setTextColor(validCasing ? VALID_TEXT_COLOR : INVALID_TEXT_COLOR); - } - - private void updateFlags() { - boolean validFlags = flagsBox.getValue().isEmpty() || this.getHatchFlags().isPresent(); - flagsBox.setTextColor(validFlags ? VALID_TEXT_COLOR : INVALID_TEXT_COLOR); - } - - private void updateAll() { - this.updatePreview(); - this.updateMembers(); - this.updateCasing(); - this.updateFlags(); - } - - private void done() { - this.sendToServer(); - minecraft.setScreen(null); - } - - private void sendToServer() { - new StructureUpdateHatchPacket( - hatch.getBlockPos(), - previewBox.getValue(), - membersBox.getValue(), - casingBox.getValue(), - flagsBox.getValue()).sendToServer(); - } - - private void cancel() { - minecraft.setScreen(null); - } - - @Override - protected void init() { - this.addRenderableWidget( - doneButton = Button.builder(CommonComponents.GUI_DONE, button -> this.done()).bounds(width / 2 - 4 - 150, 210, 150, 20).build()); - this.addRenderableWidget( - cancelButton = Button.builder(CommonComponents.GUI_CANCEL, button -> this.cancel()).bounds(width / 2 + 4, 210, 150, 20).build()); - - previewBox = new EditBox(font, width / 2 - 152, 50, 304, 20, MIText.StructureMultiblockMemberPreview.text()); - previewBox.setMaxLength(Short.MAX_VALUE); - previewBox.setValue(hatch.getInputPreview()); - previewBox.setResponder(text -> this.updatePreview()); - this.addRenderableWidget(previewBox); - - membersBox = new EditBox(font, width / 2 - 152, 90, 304, 20, MIText.StructureMultiblockMemberMembers.text()); - membersBox.setMaxLength(Short.MAX_VALUE); - membersBox.setValue(hatch.getInputMembers()); - membersBox.setResponder(text -> this.updateMembers()); - this.addRenderableWidget(membersBox); - - casingBox = new EditBox(font, width / 2 - 152, 130, 304, 20, MIText.StructureMultiblockHatchCasing.text()) { - @Override - public boolean charTyped(char codePoint, int modifiers) { - return ResourceLocation.isAllowedInResourceLocation(codePoint) && super.charTyped(codePoint, modifiers); - } - }; - casingBox.setMaxLength(Short.MAX_VALUE); - casingBox.setValue(hatch.getInputCasing()); - casingBox.setResponder(text -> this.updateCasing()); - this.addRenderableWidget(casingBox); - - flagsBox = new EditBox(font, width / 2 - 152, 170, 304, 20, MIText.StructureMultiblockHatchFlags.text()) { - @Override - public boolean charTyped(char codePoint, int modifiers) { - return (Character.isDigit(codePoint) || Character.isAlphabetic(codePoint) || codePoint == ';' || codePoint == '_') - && super.charTyped(codePoint, modifiers); - } - }; - flagsBox.setMaxLength(Short.MAX_VALUE); - flagsBox.setValue(hatch.getInputFlags()); - flagsBox.setResponder(text -> this.updateFlags()); - this.addRenderableWidget(flagsBox); - - this.updateAll(); - } - - @Override - public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) { - super.render(graphics, mouseX, mouseY, partialTick); - - graphics.drawCenteredString(font, title, width / 2, 20, 0xFFFFFF); - - graphics.drawString(font, MIText.StructureMultiblockMemberPreview.text(), width / 2 - 152, 40, 0xA0A0A0); - - graphics.drawString(font, MIText.StructureMultiblockMemberMembers.text(), width / 2 - 152, 80, 0xA0A0A0); - - graphics.drawString(font, MIText.StructureMultiblockHatchCasing.text(), width / 2 - 152, 120, 0xA0A0A0); - - graphics.drawString(font, MIText.StructureMultiblockHatchFlags.text(), width / 2 - 152, 160, 0xA0A0A0); - } - - @Override - public void renderBackground(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) { - this.renderTransparentBackground(guiGraphics); - } - - @Override - protected void setInitialFocus() { - this.setInitialFocus(previewBox); - } - - @Override - public void resize(Minecraft minecraft, int width, int height) { - String previewBoxValue = previewBox.getValue(); - String membersBoxValue = membersBox.getValue(); - String casingBoxValue = casingBox.getValue(); - String flagsBoxValue = flagsBox.getValue(); - - this.init(minecraft, width, height); - - previewBox.setValue(previewBoxValue); - membersBox.setValue(membersBoxValue); - casingBox.setValue(casingBoxValue); - flagsBox.setValue(flagsBoxValue); - } - - @Override - public void onClose() { - this.cancel(); - } - - @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (super.keyPressed(keyCode, scanCode, modifiers)) { - return true; - } else if (keyCode == InputConstants.KEY_RETURN || keyCode == InputConstants.KEY_NUMPADENTER) { - this.done(); - return true; - } - return false; - } - - @Override - public boolean isPauseScreen() { - return false; - } - - @Override - public void tick() { - if (hatch.isRemoved()) { - this.onClose(); - } - } -} diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java index d964b54b3..3921a6e1e 100644 --- a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java @@ -26,6 +26,8 @@ import aztech.modern_industrialization.MIBlock; import aztech.modern_industrialization.MIText; import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlockEntity; +import aztech.modern_industrialization.machines.models.MachineCasing; +import aztech.modern_industrialization.machines.multiblocks.HatchFlags; import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockFormatters; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMemberTest; import aztech.modern_industrialization.network.structure.StructureUpdateMemberPacket; @@ -39,6 +41,7 @@ import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.block.state.BlockState; public class StructureMultiblockMemberEditScreen extends Screen { @@ -53,6 +56,9 @@ public class StructureMultiblockMemberEditScreen extends Screen { private EditBox previewBox; private EditBox membersBox; + private EditBox casingBox; + private EditBox flagsBox; + public StructureMultiblockMemberEditScreen(StructureMultiblockMemberBlockEntity member) { super(Component.translatable(MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.asBlock().getDescriptionId())); this.member = member; @@ -66,6 +72,14 @@ private Optional> getMembers() { return Optional.ofNullable(StructureMultiblockFormatters.members(membersBox.getValue())); } + private Optional getCasing() { + return Optional.ofNullable(StructureMultiblockFormatters.casing(casingBox.getValue())); + } + + private Optional getHatchFlags() { + return Optional.ofNullable(StructureMultiblockFormatters.hatchFlags(flagsBox.getValue())); + } + private void updatePreview() { boolean validPreview = previewBox.getValue().isEmpty() || this.getPreview().isPresent(); previewBox.setTextColor(validPreview ? VALID_TEXT_COLOR : INVALID_TEXT_COLOR); @@ -76,9 +90,21 @@ private void updateMembers() { membersBox.setTextColor(validMembers ? VALID_TEXT_COLOR : INVALID_TEXT_COLOR); } + private void updateCasing() { + boolean validCasing = casingBox.getValue().isEmpty() || this.getCasing().isPresent(); + casingBox.setTextColor(validCasing ? VALID_TEXT_COLOR : INVALID_TEXT_COLOR); + } + + private void updateFlags() { + boolean validFlags = flagsBox.getValue().isEmpty() || this.getHatchFlags().isPresent(); + flagsBox.setTextColor(validFlags ? VALID_TEXT_COLOR : INVALID_TEXT_COLOR); + } + private void updateAll() { this.updatePreview(); this.updateMembers(); + this.updateCasing(); + this.updateFlags(); } private void done() { @@ -90,7 +116,9 @@ private void sendToServer() { new StructureUpdateMemberPacket( member.getBlockPos(), previewBox.getValue(), - membersBox.getValue()).sendToServer(); + membersBox.getValue(), + casingBox.getValue(), + flagsBox.getValue()).sendToServer(); } private void cancel() { @@ -116,6 +144,29 @@ protected void init() { membersBox.setResponder(text -> this.updateMembers()); this.addRenderableWidget(membersBox); + casingBox = new EditBox(font, width / 2 - 152, 130, 304, 20, MIText.StructureMultiblockHatchCasing.text()) { + @Override + public boolean charTyped(char codePoint, int modifiers) { + return ResourceLocation.isAllowedInResourceLocation(codePoint) && super.charTyped(codePoint, modifiers); + } + }; + casingBox.setMaxLength(Short.MAX_VALUE); + casingBox.setValue(member.getInputCasing()); + casingBox.setResponder(text -> this.updateCasing()); + this.addRenderableWidget(casingBox); + + flagsBox = new EditBox(font, width / 2 - 152, 170, 304, 20, MIText.StructureMultiblockHatchFlags.text()) { + @Override + public boolean charTyped(char codePoint, int modifiers) { + return (Character.isDigit(codePoint) || Character.isAlphabetic(codePoint) || codePoint == ';' || codePoint == '_') + && super.charTyped(codePoint, modifiers); + } + }; + flagsBox.setMaxLength(Short.MAX_VALUE); + flagsBox.setValue(member.getInputFlags()); + flagsBox.setResponder(text -> this.updateFlags()); + this.addRenderableWidget(flagsBox); + this.updateAll(); } @@ -128,6 +179,10 @@ public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTi graphics.drawString(font, MIText.StructureMultiblockMemberPreview.text(), width / 2 - 152, 40, 0xA0A0A0); graphics.drawString(font, MIText.StructureMultiblockMemberMembers.text(), width / 2 - 152, 80, 0xA0A0A0); + + graphics.drawString(font, MIText.StructureMultiblockHatchCasing.text(), width / 2 - 152, 120, 0xA0A0A0); + + graphics.drawString(font, MIText.StructureMultiblockHatchFlags.text(), width / 2 - 152, 160, 0xA0A0A0); } @Override @@ -144,11 +199,15 @@ protected void setInitialFocus() { public void resize(Minecraft minecraft, int width, int height) { String previewBoxValue = previewBox.getValue(); String membersBoxValue = membersBox.getValue(); + String casingBoxValue = casingBox.getValue(); + String flagsBoxValue = flagsBox.getValue(); this.init(minecraft, width, height); previewBox.setValue(previewBoxValue); membersBox.setValue(membersBoxValue); + casingBox.setValue(casingBoxValue); + flagsBox.setValue(flagsBoxValue); } @Override diff --git a/src/client/java/aztech/modern_industrialization/proxy/ClientProxy.java b/src/client/java/aztech/modern_industrialization/proxy/ClientProxy.java index fc8fb3f54..504ee254d 100644 --- a/src/client/java/aztech/modern_industrialization/proxy/ClientProxy.java +++ b/src/client/java/aztech/modern_industrialization/proxy/ClientProxy.java @@ -31,10 +31,8 @@ import aztech.modern_industrialization.blocks.storage.tank.TankRenderer; import aztech.modern_industrialization.blocks.structure.StructureMultiblockBER; import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlockEntity; -import aztech.modern_industrialization.blocks.structure.StructureMultiblockHatchBlockEntity; import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlockEntity; import aztech.modern_industrialization.gui.structure.StructureMultiblockControllerEditScreen; -import aztech.modern_industrialization.gui.structure.StructureMultiblockHatchEditScreen; import aztech.modern_industrialization.gui.structure.StructureMultiblockMemberEditScreen; import aztech.modern_industrialization.items.SteamDrillHooks; import aztech.modern_industrialization.machines.gui.MachineMenuClient; @@ -169,13 +167,6 @@ public void openStructureMultiblockControllerScreen(Player player, StructureMult } } - @Override - public void openStructureMultiblockHatchScreen(Player player, StructureMultiblockHatchBlockEntity hatch) { - if (player.getCommandSenderWorld().isClientSide()) { - Minecraft.getInstance().setScreen(new StructureMultiblockHatchEditScreen(hatch)); - } - } - @Override public void openStructureMultiblockMemberScreen(Player player, StructureMultiblockMemberBlockEntity member) { if (player.getCommandSenderWorld().isClientSide()) { diff --git a/src/generated/resources/assets/modern_industrialization/blockstates/structure_multiblock_hatch.json b/src/generated/resources/assets/modern_industrialization/blockstates/structure_multiblock_hatch.json deleted file mode 100644 index 7c9f6f6b6..000000000 --- a/src/generated/resources/assets/modern_industrialization/blockstates/structure_multiblock_hatch.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "modern_industrialization:block/structure_multiblock_hatch" - } - } -} \ No newline at end of file diff --git a/src/generated/resources/assets/modern_industrialization/lang/en_us.json b/src/generated/resources/assets/modern_industrialization/lang/en_us.json index e17aabb0a..c1d7b200a 100644 --- a/src/generated/resources/assets/modern_industrialization/lang/en_us.json +++ b/src/generated/resources/assets/modern_industrialization/lang/en_us.json @@ -405,7 +405,6 @@ "block.modern_industrialization.steel_water_pump": "Steel Water Pump", "block.modern_industrialization.steel_wiremill": "Steel Wiremill", "block.modern_industrialization.structure_multiblock_controller": "Structure Multiblock Controller", - "block.modern_industrialization.structure_multiblock_hatch": "Structure Multiblock Hatch", "block.modern_industrialization.structure_multiblock_member": "Structure Multiblock Member", "block.modern_industrialization.styrene": "Styrene", "block.modern_industrialization.styrene_butadiene": "Styrene-Butadiene", diff --git a/src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_hatch.json b/src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_hatch.json deleted file mode 100644 index e7f08db80..000000000 --- a/src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_hatch.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "minecraft:block/cube_all", - "textures": { - "all": "modern_industrialization:block/structure_multiblock_hatch" - } -} \ No newline at end of file diff --git a/src/generated/resources/assets/modern_industrialization/models/item/structure_multiblock_hatch.json b/src/generated/resources/assets/modern_industrialization/models/item/structure_multiblock_hatch.json deleted file mode 100644 index 7350f04c5..000000000 --- a/src/generated/resources/assets/modern_industrialization/models/item/structure_multiblock_hatch.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "modern_industrialization:block/structure_multiblock_hatch" -} \ No newline at end of file diff --git a/src/main/java/aztech/modern_industrialization/MIBlock.java b/src/main/java/aztech/modern_industrialization/MIBlock.java index 39cecd7d3..a246a92a0 100644 --- a/src/main/java/aztech/modern_industrialization/MIBlock.java +++ b/src/main/java/aztech/modern_industrialization/MIBlock.java @@ -36,7 +36,6 @@ import aztech.modern_industrialization.blocks.storage.tank.TankItem; import aztech.modern_industrialization.blocks.storage.tank.creativetank.CreativeTankBlockEntity; import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlock; -import aztech.modern_industrialization.blocks.structure.StructureMultiblockHatchBlock; import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlock; import aztech.modern_industrialization.datagen.loot.MIBlockLoot; import aztech.modern_industrialization.datagen.model.BaseModelProvider; @@ -148,15 +147,6 @@ public static void init(IEventBus modBus) { gen.simpleBlockItem(block, model); })); - public static final BlockDefinition STRUCTURE_MULTIBLOCK_HATCH = block("Structure Multiblock Hatch", - "structure_multiblock_hatch", BlockDefinitionParams.defaultCreativeOnly() - .withBlockConstructor(StructureMultiblockHatchBlock::new) - .withBlockItemConstructor((block, p) -> new BlockItem(block, p.rarity(Rarity.EPIC))) - .withModel((block, gen) -> { - String name = gen.name(block); - gen.simpleBlockWithItem(block, gen.models().cubeAll(name, gen.blockTexture("structure_multiblock_hatch"))); - })); - public static final BlockDefinition STRUCTURE_MULTIBLOCK_MEMBER = block("Structure Multiblock Member", "structure_multiblock_member", BlockDefinitionParams.defaultCreativeOnly() .withBlockConstructor(StructureMultiblockMemberBlock::new) diff --git a/src/main/java/aztech/modern_industrialization/MIRegistries.java b/src/main/java/aztech/modern_industrialization/MIRegistries.java index 36446e15c..66d59c93a 100644 --- a/src/main/java/aztech/modern_industrialization/MIRegistries.java +++ b/src/main/java/aztech/modern_industrialization/MIRegistries.java @@ -29,7 +29,6 @@ import aztech.modern_industrialization.blocks.storage.barrel.CreativeBarrelBlockEntity; import aztech.modern_industrialization.blocks.storage.tank.creativetank.CreativeTankBlockEntity; import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlockEntity; -import aztech.modern_industrialization.blocks.structure.StructureMultiblockHatchBlockEntity; import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlockEntity; import aztech.modern_industrialization.compat.ae2.AECompatCondition; import aztech.modern_industrialization.machines.gui.MachineMenuCommon; @@ -78,11 +77,6 @@ public class MIRegistries { return BlockEntityType.Builder.of(StructureMultiblockControllerBlockEntity::new, MIBlock.STRUCTURE_MULTIBLOCK_CONTROLLER.get()) .build(null); }); - public static final Supplier> STRUCTURE_MULTIBLOCK_HATCH_BE = BLOCK_ENTITIES - .register("structure_multiblock_hatch", () -> { - return BlockEntityType.Builder.of(StructureMultiblockHatchBlockEntity::new, MIBlock.STRUCTURE_MULTIBLOCK_HATCH.get()) - .build(null); - }); public static final Supplier> STRUCTURE_MULTIBLOCK_MEMBER_BE = BLOCK_ENTITIES .register("structure_multiblock_member", () -> { return BlockEntityType.Builder.of(StructureMultiblockMemberBlockEntity::new, MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.get()) diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlock.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlock.java deleted file mode 100644 index e423aa614..000000000 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlock.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2020 Azercoco & Technici4n - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package aztech.modern_industrialization.blocks.structure; - -import aztech.modern_industrialization.proxy.CommonProxy; -import com.mojang.serialization.MapCodec; -import net.minecraft.core.BlockPos; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.EntityBlock; -import net.minecraft.world.level.block.GameMasterBlock; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.BlockHitResult; - -public class StructureMultiblockHatchBlock extends Block implements EntityBlock, GameMasterBlock { - private static final MapCodec CODEC = simpleCodec(StructureMultiblockHatchBlock::new); - - public StructureMultiblockHatchBlock(Properties properties) { - super(properties); - } - - @Override - protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { - BlockEntity blockEntity = level.getBlockEntity(pos); - if (blockEntity instanceof StructureMultiblockHatchBlockEntity hatch && player.canUseGameMasterBlocks()) { - CommonProxy.INSTANCE.openStructureMultiblockHatchScreen(player, hatch); - return InteractionResult.sidedSuccess(level.isClientSide()); - } else { - return InteractionResult.PASS; - } - } - - @Override - protected MapCodec codec() { - return CODEC; - } - - @Override - public StructureMultiblockHatchBlockEntity newBlockEntity(BlockPos pos, BlockState state) { - return new StructureMultiblockHatchBlockEntity(pos, state); - } -} diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlockEntity.java deleted file mode 100644 index dc256e9fc..000000000 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockHatchBlockEntity.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2020 Azercoco & Technici4n - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package aztech.modern_industrialization.blocks.structure; - -import aztech.modern_industrialization.MIRegistries; -import aztech.modern_industrialization.blocks.FastBlockEntity; -import aztech.modern_industrialization.machines.models.MachineCasing; -import aztech.modern_industrialization.machines.multiblocks.HatchFlags; -import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockFormatters; -import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; -import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMemberTest; -import java.util.List; -import net.minecraft.core.BlockPos; -import net.minecraft.core.HolderLookup; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.protocol.Packet; -import net.minecraft.network.protocol.game.ClientGamePacketListener; -import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; -import net.minecraft.world.level.block.state.BlockState; -import org.jetbrains.annotations.Nullable; - -public class StructureMultiblockHatchBlockEntity extends FastBlockEntity implements StructureMemberOverride { - private String inputPreview; - private String inputMembers; - private String inputCasing; - private String inputFlags; - - private BlockState preview; - private List members; - private MachineCasing casing; - private HatchFlags flags = HatchFlags.NO_HATCH; - - public StructureMultiblockHatchBlockEntity(BlockPos pos, BlockState state) { - super(MIRegistries.STRUCTURE_MULTIBLOCK_HATCH_BE.get(), pos, state); - } - - @Nullable - public String getInputPreview() { - return inputPreview; - } - - public void setInputPreview(String inputPreview) { - this.inputPreview = inputPreview; - preview = StructureMultiblockFormatters.preview(inputPreview); - } - - @Nullable - public BlockState getPreview() { - return preview; - } - - @Nullable - public String getInputMembers() { - return inputMembers; - } - - public void setInputMembers(String inputMembers) { - this.inputMembers = inputMembers; - members = StructureMultiblockFormatters.members(inputMembers); - } - - @Nullable - public List getMembers() { - return members; - } - - @Nullable - public String getInputCasing() { - return inputCasing; - } - - public void setInputCasing(String inputCasing) { - this.inputCasing = inputCasing; - casing = StructureMultiblockFormatters.casing(inputCasing); - } - - @Nullable - public String getInputFlags() { - return inputFlags; - } - - public void setInputFlags(String inputFlags) { - this.inputFlags = inputFlags; - flags = StructureMultiblockFormatters.hatchFlags(inputFlags); - } - - @Nullable - public MachineCasing getCasing() { - return casing; - } - - @Nullable - public HatchFlags getFlags() { - return flags; - } - - @Override - public StructureMember getMemberOverride() { - return new StructureMember(() -> preview, members, casing, flags); - } - - @Override - public boolean isConfigurationValid() { - return preview != null && - members != null && !members.isEmpty() && - casing != null && - flags != null; - } - - @Override - public Packet getUpdatePacket() { - return ClientboundBlockEntityDataPacket.create(this); - } - - @Override - public CompoundTag getUpdateTag(HolderLookup.Provider registries) { - CompoundTag tag = new CompoundTag(); - this.saveAdditional(tag, registries); - return tag; - } - - @Override - protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { - super.saveAdditional(tag, registries); - if (inputPreview != null) { - tag.putString("preview", inputPreview); - } - if (inputMembers != null) { - tag.putString("members", inputMembers); - } - if (inputCasing != null) { - tag.putString("casing", inputCasing); - } - if (inputFlags != null) { - tag.putString("flags", inputFlags); - } - } - - @Override - protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { - super.loadAdditional(tag, registries); - this.setInputPreview(tag.getString("preview")); - this.setInputMembers(tag.getString("members")); - this.setInputCasing(tag.getString("casing")); - this.setInputFlags(tag.getString("flags")); - } -} diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlock.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlock.java index 065069360..2d3d02046 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlock.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlock.java @@ -46,8 +46,8 @@ public StructureMultiblockMemberBlock(Properties properties) { @Override protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { BlockEntity blockEntity = level.getBlockEntity(pos); - if (blockEntity instanceof StructureMultiblockMemberBlockEntity member && player.canUseGameMasterBlocks()) { - CommonProxy.INSTANCE.openStructureMultiblockMemberScreen(player, member); + if (blockEntity instanceof StructureMultiblockMemberBlockEntity hatch && player.canUseGameMasterBlocks()) { + CommonProxy.INSTANCE.openStructureMultiblockMemberScreen(player, hatch); return InteractionResult.sidedSuccess(level.isClientSide()); } else { return InteractionResult.PASS; diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java index b70b6ad5c..db9419213 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java @@ -25,6 +25,8 @@ import aztech.modern_industrialization.MIRegistries; import aztech.modern_industrialization.blocks.FastBlockEntity; +import aztech.modern_industrialization.machines.models.MachineCasing; +import aztech.modern_industrialization.machines.multiblocks.HatchFlags; import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockFormatters; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMemberTest; @@ -41,9 +43,13 @@ public class StructureMultiblockMemberBlockEntity extends FastBlockEntity implements StructureMemberOverride { private String inputPreview; private String inputMembers; + private String inputCasing; + private String inputFlags; private BlockState preview; private List members; + private MachineCasing casing; + private HatchFlags flags = HatchFlags.NO_HATCH; public StructureMultiblockMemberBlockEntity(BlockPos pos, BlockState state) { super(MIRegistries.STRUCTURE_MULTIBLOCK_MEMBER_BE.get(), pos, state); @@ -79,15 +85,54 @@ public List getMembers() { return members; } + @Nullable + public String getInputCasing() { + return inputCasing; + } + + public void setInputCasing(String inputCasing) { + this.inputCasing = inputCasing; + casing = StructureMultiblockFormatters.casing(inputCasing); + } + + @Nullable + public String getInputFlags() { + return inputFlags; + } + + public void setInputFlags(String inputFlags) { + this.inputFlags = inputFlags; + flags = StructureMultiblockFormatters.hatchFlags(inputFlags); + } + + @Nullable + public MachineCasing getCasing() { + return casing; + } + + @Nullable + public HatchFlags getFlags() { + return flags; + } + @Override public StructureMember getMemberOverride() { - return new StructureMember(() -> preview, members, null, null); + if (casing == null || (flags == null || flags.flags == 0)) { + return new StructureMember(() -> preview, members, null, null); + } + return new StructureMember(() -> preview, members, casing, flags); } @Override public boolean isConfigurationValid() { - return preview != null && - members != null && !members.isEmpty(); + if (preview != null && members != null && !members.isEmpty()) { + boolean hasCasing = casing != null; + boolean hasHatchFlags = flags != null && flags.flags != 0; + boolean noCasing = (inputCasing == null || inputCasing.isEmpty()) && !hasCasing; + boolean noFlags = (inputFlags == null || inputFlags.isEmpty()) && !hasHatchFlags; + return (hasCasing && hasHatchFlags) || (noCasing && noFlags); + } + return false; } @Override @@ -111,6 +156,12 @@ protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) if (inputMembers != null) { tag.putString("members", inputMembers); } + if (inputCasing != null) { + tag.putString("casing", inputCasing); + } + if (inputFlags != null) { + tag.putString("flags", inputFlags); + } } @Override @@ -118,5 +169,7 @@ protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) super.loadAdditional(tag, registries); this.setInputPreview(tag.getString("preview")); this.setInputMembers(tag.getString("members")); + this.setInputCasing(tag.getString("casing")); + this.setInputFlags(tag.getString("flags")); } } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java index b2150029a..35d870230 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java @@ -24,7 +24,6 @@ package aztech.modern_industrialization.machines.multiblocks; import aztech.modern_industrialization.MIBlock; -import aztech.modern_industrialization.blocks.structure.StructureMultiblockHatchBlockEntity; import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlockEntity; import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockFormatters; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; @@ -260,27 +259,18 @@ public int buildMultiblock(Level level, boolean structureBlocks) { // TODO SWEDZ: there has gotta be a better way to do this if (structureBlocks) { boolean hasMultipleTests = member.tests().size() > 1; - boolean hasHatchFlags = member.hatchFlags() != null && member.hatchFlags().flags != 0; + boolean hasHatchFlags = member.casing() != null && member.hatchFlags() != null && member.hatchFlags().flags != 0; - if (hasMultipleTests && !hasHatchFlags) { + if (hasMultipleTests || hasHatchFlags) { state = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.asBlock().defaultBlockState(); level.setBlockAndUpdate(pos, state); StructureMultiblockMemberBlockEntity be = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.get().newBlockEntity(pos, state); be.setInputPreview(StructureMultiblockFormatters.preview(member.preview())); be.setInputMembers(StructureMultiblockFormatters.members(member.tests())); - level.setBlockEntity(be); - be.setChanged(); - be.sync(); - setBlocks++; - continue; - } else if (hasHatchFlags) { - state = MIBlock.STRUCTURE_MULTIBLOCK_HATCH.asBlock().defaultBlockState(); - level.setBlockAndUpdate(pos, state); - StructureMultiblockHatchBlockEntity be = MIBlock.STRUCTURE_MULTIBLOCK_HATCH.get().newBlockEntity(pos, state); - be.setInputPreview(StructureMultiblockFormatters.preview(member.preview())); - be.setInputMembers(StructureMultiblockFormatters.members(member.tests())); - be.setInputCasing(StructureMultiblockFormatters.casing(member.casing())); - be.setInputFlags(StructureMultiblockFormatters.hatchFlags(member.hatchFlags())); + if (hasHatchFlags) { + be.setInputCasing(StructureMultiblockFormatters.casing(member.casing())); + be.setInputFlags(StructureMultiblockFormatters.hatchFlags(member.hatchFlags())); + } level.setBlockEntity(be); be.setChanged(); be.sync(); diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java index ac392376b..868b0812c 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java @@ -35,6 +35,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.charset.StandardCharsets; import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; @@ -49,10 +50,10 @@ import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; -import net.minecraft.nbt.NbtAccounter; -import net.minecraft.nbt.NbtIo; import net.minecraft.nbt.NbtUtils; +import net.minecraft.nbt.SnbtPrinterTagVisitor; import net.minecraft.nbt.Tag; +import net.minecraft.nbt.TagParser; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.FastBufferedInputStream; import net.minecraft.world.level.Level; @@ -226,7 +227,7 @@ private static Path path(ResourceLocation id) throws IOException { Objects.requireNonNull(id); var structuresFolder = structuresPath().resolve(id.getNamespace()); Files.createDirectories(structuresFolder); - return FileUtil.createPathToResource(structuresFolder, id.getPath(), ".nbt"); + return FileUtil.createPathToResource(structuresFolder, id.getPath(), ".snbt"); } public static boolean save(ResourceLocation id, CompoundTag tag) { @@ -234,7 +235,7 @@ public static boolean save(ResourceLocation id, CompoundTag tag) { Objects.requireNonNull(tag); try { try (OutputStream output = Files.newOutputStream(path(id))) { - NbtIo.writeCompressed(tag, output); + output.write(new SnbtPrinterTagVisitor().visit(tag).getBytes(StandardCharsets.UTF_8)); return true; } catch (Exception ex) { MI.LOGGER.error("Failed to save structure \"{}\"", id, ex); @@ -252,7 +253,7 @@ private static CompoundTag load(Path path) { if (Files.exists(path)) { try (InputStream input = Files.newInputStream(path); InputStream fastInput = new FastBufferedInputStream(input)) { - return NbtIo.readCompressed(fastInput, NbtAccounter.unlimitedHeap()); + return TagParser.parseTag(new String(fastInput.readAllBytes(), StandardCharsets.UTF_8)); } catch (Exception ex) { MI.LOGGER.error("Failed to load structure at \"{}\"", path, ex); return null; @@ -272,7 +273,7 @@ private static void iterateStructureFiles(Path origin, BiConsumer files = Files.newDirectoryStream(subdirectory)) { for (Path file : files) { - if (file.toString().endsWith(".nbt")) { + if (file.toString().endsWith(".snbt")) { String rawFileName = file.getFileName().toString(); String path = rawFileName.substring(0, rawFileName.lastIndexOf('.')); ResourceLocation id = ResourceLocation.fromNamespaceAndPath(namespace, path); diff --git a/src/main/java/aztech/modern_industrialization/network/MIPackets.java b/src/main/java/aztech/modern_industrialization/network/MIPackets.java index 8c97ef558..85572bfdd 100644 --- a/src/main/java/aztech/modern_industrialization/network/MIPackets.java +++ b/src/main/java/aztech/modern_industrialization/network/MIPackets.java @@ -46,7 +46,6 @@ import aztech.modern_industrialization.network.structure.StructureMisconfiguredBlocksPacket; import aztech.modern_industrialization.network.structure.StructureSaveControllerPacket; import aztech.modern_industrialization.network.structure.StructureUpdateControllerPacket; -import aztech.modern_industrialization.network.structure.StructureUpdateHatchPacket; import aztech.modern_industrialization.network.structure.StructureUpdateMemberPacket; import java.util.ArrayList; import java.util.HashMap; @@ -101,7 +100,6 @@ private static

void register(String path, Class

clazz, register("structure_misconfigured_blocks", StructureMisconfiguredBlocksPacket.class, StructureMisconfiguredBlocksPacket.STREAM_CODEC); register("structure_save_controller", StructureSaveControllerPacket.class, StructureSaveControllerPacket.STREAM_CODEC); register("structure_update_controller", StructureUpdateControllerPacket.class, StructureUpdateControllerPacket.STREAM_CODEC); - register("structure_update_hatch", StructureUpdateHatchPacket.class, StructureUpdateHatchPacket.STREAM_CODEC); register("structure_update_member", StructureUpdateMemberPacket.class, StructureUpdateMemberPacket.STREAM_CODEC); } diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateHatchPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateHatchPacket.java deleted file mode 100644 index d31c0c22b..000000000 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateHatchPacket.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2020 Azercoco & Technici4n - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package aztech.modern_industrialization.network.structure; - -import aztech.modern_industrialization.blocks.structure.StructureMultiblockHatchBlockEntity; -import aztech.modern_industrialization.network.BasePacket; -import io.netty.buffer.ByteBuf; -import net.minecraft.core.BlockPos; -import net.minecraft.network.codec.ByteBufCodecs; -import net.minecraft.network.codec.StreamCodec; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.entity.BlockEntity; - -public record StructureUpdateHatchPacket(BlockPos pos, String inputPreview, String inputMembers, String inputCasing, String inputFlags) - implements BasePacket { - - public static final StreamCodec STREAM_CODEC = StreamCodec.composite( - BlockPos.STREAM_CODEC, - StructureUpdateHatchPacket::pos, - ByteBufCodecs.STRING_UTF8, - StructureUpdateHatchPacket::inputPreview, - ByteBufCodecs.STRING_UTF8, - StructureUpdateHatchPacket::inputMembers, - ByteBufCodecs.STRING_UTF8, - StructureUpdateHatchPacket::inputCasing, - ByteBufCodecs.STRING_UTF8, - StructureUpdateHatchPacket::inputFlags, - StructureUpdateHatchPacket::new); - - @Override - public void handle(Context ctx) { - ctx.assertOnServer(); - - Player player = ctx.getPlayer(); - Level level = player.level(); - - if (!player.canUseGameMasterBlocks()) { - return; - } - - BlockEntity blockEntity = level.getBlockEntity(pos); - if (blockEntity instanceof StructureMultiblockHatchBlockEntity hatch) { - hatch.setInputPreview(inputPreview); - hatch.setInputMembers(inputMembers); - hatch.setInputCasing(inputCasing); - hatch.setInputFlags(inputFlags); - - hatch.sync(); - hatch.setChanged(); - - if (player instanceof ServerPlayer serverPlayer && hatch.isConfigurationValid()) { - StructureMisconfiguredBlocksPacket.forget(hatch.getBlockPos()).sendToClient(serverPlayer); - } - } - } -} diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java index 0e906a5da..d827aff69 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java @@ -34,7 +34,8 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; -public record StructureUpdateMemberPacket(BlockPos pos, String inputPreview, String inputMembers) implements BasePacket { +public record StructureUpdateMemberPacket(BlockPos pos, String inputPreview, String inputMembers, String inputCasing, String inputFlags) + implements BasePacket { public static final StreamCodec STREAM_CODEC = StreamCodec.composite( BlockPos.STREAM_CODEC, @@ -43,6 +44,10 @@ public record StructureUpdateMemberPacket(BlockPos pos, String inputPreview, Str StructureUpdateMemberPacket::inputPreview, ByteBufCodecs.STRING_UTF8, StructureUpdateMemberPacket::inputMembers, + ByteBufCodecs.STRING_UTF8, + StructureUpdateMemberPacket::inputCasing, + ByteBufCodecs.STRING_UTF8, + StructureUpdateMemberPacket::inputFlags, StructureUpdateMemberPacket::new); @Override @@ -57,15 +62,17 @@ public void handle(Context ctx) { } BlockEntity blockEntity = level.getBlockEntity(pos); - if (blockEntity instanceof StructureMultiblockMemberBlockEntity member) { - member.setInputPreview(inputPreview); - member.setInputMembers(inputMembers); + if (blockEntity instanceof StructureMultiblockMemberBlockEntity hatch) { + hatch.setInputPreview(inputPreview); + hatch.setInputMembers(inputMembers); + hatch.setInputCasing(inputCasing); + hatch.setInputFlags(inputFlags); - member.sync(); - member.setChanged(); + hatch.sync(); + hatch.setChanged(); - if (player instanceof ServerPlayer serverPlayer && member.isConfigurationValid()) { - StructureMisconfiguredBlocksPacket.forget(member.getBlockPos()).sendToClient(serverPlayer); + if (player instanceof ServerPlayer serverPlayer && hatch.isConfigurationValid()) { + StructureMisconfiguredBlocksPacket.forget(hatch.getBlockPos()).sendToClient(serverPlayer); } } } diff --git a/src/main/java/aztech/modern_industrialization/proxy/CommonProxy.java b/src/main/java/aztech/modern_industrialization/proxy/CommonProxy.java index 626c1c0a1..371d0ba4b 100644 --- a/src/main/java/aztech/modern_industrialization/proxy/CommonProxy.java +++ b/src/main/java/aztech/modern_industrialization/proxy/CommonProxy.java @@ -26,7 +26,6 @@ import aztech.modern_industrialization.blocks.storage.barrel.BarrelBlockEntity; import aztech.modern_industrialization.blocks.storage.tank.AbstractTankBlockEntity; import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlockEntity; -import aztech.modern_industrialization.blocks.structure.StructureMultiblockHatchBlockEntity; import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlockEntity; import aztech.modern_industrialization.machines.gui.MachineMenuCommon; import aztech.modern_industrialization.network.BasePacket; @@ -133,9 +132,6 @@ public BlockState getMachineCasingBlockState(BlockState state, BlockAndTintGette public void openStructureMultiblockControllerScreen(Player player, StructureMultiblockControllerBlockEntity controller) { } - public void openStructureMultiblockHatchScreen(Player player, StructureMultiblockHatchBlockEntity hatch) { - } - public void openStructureMultiblockMemberScreen(Player player, StructureMultiblockMemberBlockEntity member) { } diff --git a/src/main/resources/assets/modern_industrialization/textures/block/structure_multiblock_hatch.png b/src/main/resources/assets/modern_industrialization/textures/block/structure_multiblock_hatch.png deleted file mode 100644 index 4b533be7627b1a4b84511ca722447fe1b6c65dd1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 335 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc!6%+Bjv*HQ$tGrI|IQydbL7LvpW$pl4Et5g zXQY{!8vmXDVhYEz6P~9VU%LCtH)cBh`T6^qvBANdHqTEVKN-Hrcp>nlnZZL}xT8^r zlWD$PJ=5hKKNJ`)Gn+B6BurZ5wTS1`uTu#;NsB)_GNdVRY-r$^FyG-ElPAMggNz$l z4XPIp_8vBWFe~vPLpkH7l`RaL!Z)-r+A#z-8}oE9o><2!&G4Du@ZN$diH2lGTONmn zz1#vk&DX!j8QQMdQ)0*QfQMP2!SfK$k)!SHj5^`5I}2G|Cke>2I8 Date: Sat, 23 Nov 2024 11:21:06 -0500 Subject: [PATCH 29/89] Rename StructureMultiblockFormatters to StructureMultiblockInputFormatters --- .../StructureMultiblockControllerEditScreen.java | 4 ++-- .../structure/StructureMultiblockMemberEditScreen.java | 10 +++++----- .../StructureMultiblockControllerBlockEntity.java | 4 ++-- .../StructureMultiblockMemberBlockEntity.java | 10 +++++----- .../machines/multiblocks/ShapeMatcher.java | 10 +++++----- ...rs.java => StructureMultiblockInputFormatters.java} | 4 ++-- 6 files changed, 21 insertions(+), 21 deletions(-) rename src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/{StructureMultiblockFormatters.java => StructureMultiblockInputFormatters.java} (98%) diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java index 1ab40b00c..a8e66234e 100644 --- a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java @@ -30,7 +30,7 @@ import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlockEntity; import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.structure.MIStructureTemplateManager; -import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockFormatters; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockInputFormatters; import aztech.modern_industrialization.network.structure.StructureLoadControllerPacket; import aztech.modern_industrialization.network.structure.StructureSaveControllerPacket; import aztech.modern_industrialization.network.structure.StructureUpdateControllerPacket; @@ -88,7 +88,7 @@ private Optional getId() { } private Optional getCasing() { - return Optional.ofNullable(StructureMultiblockFormatters.casing(casingBox.getValue())); + return Optional.ofNullable(StructureMultiblockInputFormatters.casing(casingBox.getValue())); } private Optional getBounds() { diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java index 3921a6e1e..c165b0ef9 100644 --- a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java @@ -28,7 +28,7 @@ import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlockEntity; import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.HatchFlags; -import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockFormatters; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockInputFormatters; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMemberTest; import aztech.modern_industrialization.network.structure.StructureUpdateMemberPacket; import com.mojang.blaze3d.platform.InputConstants; @@ -65,19 +65,19 @@ public StructureMultiblockMemberEditScreen(StructureMultiblockMemberBlockEntity } private Optional getPreview() { - return Optional.ofNullable(StructureMultiblockFormatters.preview(previewBox.getValue())); + return Optional.ofNullable(StructureMultiblockInputFormatters.preview(previewBox.getValue())); } private Optional> getMembers() { - return Optional.ofNullable(StructureMultiblockFormatters.members(membersBox.getValue())); + return Optional.ofNullable(StructureMultiblockInputFormatters.members(membersBox.getValue())); } private Optional getCasing() { - return Optional.ofNullable(StructureMultiblockFormatters.casing(casingBox.getValue())); + return Optional.ofNullable(StructureMultiblockInputFormatters.casing(casingBox.getValue())); } private Optional getHatchFlags() { - return Optional.ofNullable(StructureMultiblockFormatters.hatchFlags(flagsBox.getValue())); + return Optional.ofNullable(StructureMultiblockInputFormatters.hatchFlags(flagsBox.getValue())); } private void updatePreview() { diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java index dd740e19e..374694945 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java @@ -26,7 +26,7 @@ import aztech.modern_industrialization.MIRegistries; import aztech.modern_industrialization.blocks.FastBlockEntity; import aztech.modern_industrialization.machines.models.MachineCasing; -import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockFormatters; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockInputFormatters; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; import java.util.Locale; import java.util.Objects; @@ -82,7 +82,7 @@ public String getInputCasing() { public void setInputCasing(String inputCasing) { this.inputCasing = inputCasing; - casing = StructureMultiblockFormatters.casing(inputCasing); + casing = StructureMultiblockInputFormatters.casing(inputCasing); } @Nullable diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java index db9419213..5f54a4d2a 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java @@ -27,7 +27,7 @@ import aztech.modern_industrialization.blocks.FastBlockEntity; import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.HatchFlags; -import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockFormatters; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockInputFormatters; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMemberTest; import java.util.List; @@ -62,7 +62,7 @@ public String getInputPreview() { public void setInputPreview(String inputPreview) { this.inputPreview = inputPreview; - preview = StructureMultiblockFormatters.preview(inputPreview); + preview = StructureMultiblockInputFormatters.preview(inputPreview); } @Nullable @@ -77,7 +77,7 @@ public String getInputMembers() { public void setInputMembers(String inputMembers) { this.inputMembers = inputMembers; - members = StructureMultiblockFormatters.members(inputMembers); + members = StructureMultiblockInputFormatters.members(inputMembers); } @Nullable @@ -92,7 +92,7 @@ public String getInputCasing() { public void setInputCasing(String inputCasing) { this.inputCasing = inputCasing; - casing = StructureMultiblockFormatters.casing(inputCasing); + casing = StructureMultiblockInputFormatters.casing(inputCasing); } @Nullable @@ -102,7 +102,7 @@ public String getInputFlags() { public void setInputFlags(String inputFlags) { this.inputFlags = inputFlags; - flags = StructureMultiblockFormatters.hatchFlags(inputFlags); + flags = StructureMultiblockInputFormatters.hatchFlags(inputFlags); } @Nullable diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java index 35d870230..f7eeea06a 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java @@ -25,7 +25,7 @@ import aztech.modern_industrialization.MIBlock; import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlockEntity; -import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockFormatters; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockInputFormatters; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; import aztech.modern_industrialization.machines.multiblocks.world.ChunkEventListener; import aztech.modern_industrialization.machines.multiblocks.world.ChunkEventListeners; @@ -265,11 +265,11 @@ public int buildMultiblock(Level level, boolean structureBlocks) { state = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.asBlock().defaultBlockState(); level.setBlockAndUpdate(pos, state); StructureMultiblockMemberBlockEntity be = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.get().newBlockEntity(pos, state); - be.setInputPreview(StructureMultiblockFormatters.preview(member.preview())); - be.setInputMembers(StructureMultiblockFormatters.members(member.tests())); + be.setInputPreview(StructureMultiblockInputFormatters.preview(member.preview())); + be.setInputMembers(StructureMultiblockInputFormatters.members(member.tests())); if (hasHatchFlags) { - be.setInputCasing(StructureMultiblockFormatters.casing(member.casing())); - be.setInputFlags(StructureMultiblockFormatters.hatchFlags(member.hatchFlags())); + be.setInputCasing(StructureMultiblockInputFormatters.casing(member.casing())); + be.setInputFlags(StructureMultiblockInputFormatters.hatchFlags(member.hatchFlags())); } level.setBlockEntity(be); be.setChanged(); diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockFormatters.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockInputFormatters.java similarity index 98% rename from src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockFormatters.java rename to src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockInputFormatters.java index 06da7a9bd..e658fe215 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockFormatters.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockInputFormatters.java @@ -43,7 +43,7 @@ import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.Nullable; -public final class StructureMultiblockFormatters { +public final class StructureMultiblockInputFormatters { @Nullable public static MachineCasing casing(String input) { if (input == null || input.isEmpty()) { @@ -188,6 +188,6 @@ public static String hatchFlags(HatchFlags hatchFlags) { return string.toString(); } - private StructureMultiblockFormatters() { + private StructureMultiblockInputFormatters() { } } From 64025daf6316cf42bc9fc3e4f75b3930092255d4 Mon Sep 17 00:00:00 2001 From: Swedz Date: Sat, 23 Nov 2024 11:22:57 -0500 Subject: [PATCH 30/89] Consistent param names --- .../StructureMultiblockInputFormatters.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockInputFormatters.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockInputFormatters.java index e658fe215..5b3a0e464 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockInputFormatters.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockInputFormatters.java @@ -73,14 +73,14 @@ public static String casing(MachineCasing casing) { } @Nullable - public static BlockState preview(String inputPreview) { - if (inputPreview == null || inputPreview.isEmpty()) { + public static BlockState preview(String input) { + if (input == null || input.isEmpty()) { return Blocks.AIR.defaultBlockState(); } var registry = BuiltInRegistries.BLOCK.asLookup(); try { - var blockResult = BlockStateParser.parseForBlock(registry, inputPreview, true); + var blockResult = BlockStateParser.parseForBlock(registry, input, true); return blockResult.blockState(); } catch (CommandSyntaxException ignored) { return null; @@ -96,14 +96,14 @@ public static String preview(BlockState preview) { } @Nullable - public static List members(String inputMembers) { - if (inputMembers == null || inputMembers.isEmpty()) { + public static List members(String input) { + if (input == null || input.isEmpty()) { return new ArrayList<>(); } var registry = BuiltInRegistries.BLOCK.asLookup(); List members = new ArrayList<>(); - for (String part : inputMembers.split(";")) { + for (String part : input.split(";")) { if (part.startsWith("#")) { ResourceLocation tagId = ResourceLocation.tryParse(part.substring(1)); if (tagId == null) { From 24615a74529ef47c3734bf3b52045c4e0b6ec425 Mon Sep 17 00:00:00 2001 From: Swedz Date: Sat, 23 Nov 2024 11:59:11 -0500 Subject: [PATCH 31/89] Add member mode to explicitly require hatch fields when hatch mode is selected --- .../StructureMultiblockMemberEditScreen.java | 49 +++++++++++++++---- .../modern_industrialization/lang/en_us.json | 4 ++ .../modern_industrialization/MIText.java | 4 ++ .../blocks/structure/StructureMemberMode.java | 47 ++++++++++++++++++ ...uctureMultiblockControllerBlockEntity.java | 4 +- .../StructureMultiblockMemberBlockEntity.java | 31 ++++++++---- .../StructureUpdateMemberPacket.java | 25 ++++++---- 7 files changed, 134 insertions(+), 30 deletions(-) create mode 100644 src/main/java/aztech/modern_industrialization/blocks/structure/StructureMemberMode.java diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java index c165b0ef9..64c14148d 100644 --- a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java @@ -25,18 +25,21 @@ import aztech.modern_industrialization.MIBlock; import aztech.modern_industrialization.MIText; +import aztech.modern_industrialization.blocks.structure.StructureMemberMode; import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlockEntity; import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.HatchFlags; import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockInputFormatters; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMemberTest; import aztech.modern_industrialization.network.structure.StructureUpdateMemberPacket; +import com.google.common.collect.ImmutableList; import com.mojang.blaze3d.platform.InputConstants; import java.util.List; import java.util.Optional; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.CycleButton; import net.minecraft.client.gui.components.EditBox; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.CommonComponents; @@ -48,10 +51,13 @@ public class StructureMultiblockMemberEditScreen extends Screen { private static final int VALID_TEXT_COLOR = 0xE0E0E0; private static final int INVALID_TEXT_COLOR = 0xE07272; + private static final ImmutableList ALL_MODES = ImmutableList.copyOf(StructureMemberMode.values()); + private final StructureMultiblockMemberBlockEntity member; private Button doneButton; private Button cancelButton; + private CycleButton modeButton; private EditBox previewBox; private EditBox membersBox; @@ -80,6 +86,22 @@ private Optional getHatchFlags() { return Optional.ofNullable(StructureMultiblockInputFormatters.hatchFlags(flagsBox.getValue())); } + private void updateMode(StructureMemberMode mode) { + this.sendToServer(); + + casingBox.visible = false; + flagsBox.visible = false; + + switch (mode) { + case HATCH -> { + casingBox.visible = true; + flagsBox.visible = true; + } + case SIMPLE -> { + } + } + } + private void updatePreview() { boolean validPreview = previewBox.getValue().isEmpty() || this.getPreview().isPresent(); previewBox.setTextColor(validPreview ? VALID_TEXT_COLOR : INVALID_TEXT_COLOR); @@ -101,6 +123,7 @@ private void updateFlags() { } private void updateAll() { + this.updateMode(member.getMode()); this.updatePreview(); this.updateMembers(); this.updateCasing(); @@ -115,6 +138,7 @@ private void done() { private void sendToServer() { new StructureUpdateMemberPacket( member.getBlockPos(), + modeButton.getValue(), previewBox.getValue(), membersBox.getValue(), casingBox.getValue(), @@ -131,20 +155,25 @@ protected void init() { doneButton = Button.builder(CommonComponents.GUI_DONE, button -> this.done()).bounds(width / 2 - 4 - 150, 210, 150, 20).build()); this.addRenderableWidget( cancelButton = Button.builder(CommonComponents.GUI_CANCEL, button -> this.cancel()).bounds(width / 2 + 4, 210, 150, 20).build()); + this.addRenderableWidget(modeButton = CycleButton.builder(StructureMemberMode::text) + .withValues(ALL_MODES, ALL_MODES) + .displayOnlyValue() + .withInitialValue(member.getMode()) + .create(width / 2 - 4 - 150, 185, 50, 20, Component.literal("MODE"), (button, mode) -> this.updateMode(mode))); - previewBox = new EditBox(font, width / 2 - 152, 50, 304, 20, MIText.StructureMultiblockMemberPreview.text()); + previewBox = new EditBox(font, width / 2 - 152, 20, 304, 20, MIText.StructureMultiblockMemberPreview.text()); previewBox.setMaxLength(Short.MAX_VALUE); previewBox.setValue(member.getInputPreview()); previewBox.setResponder(text -> this.updatePreview()); this.addRenderableWidget(previewBox); - membersBox = new EditBox(font, width / 2 - 152, 90, 304, 20, MIText.StructureMultiblockMemberMembers.text()); + membersBox = new EditBox(font, width / 2 - 152, 60, 304, 20, MIText.StructureMultiblockMemberMembers.text()); membersBox.setMaxLength(Short.MAX_VALUE); membersBox.setValue(member.getInputMembers()); membersBox.setResponder(text -> this.updateMembers()); this.addRenderableWidget(membersBox); - casingBox = new EditBox(font, width / 2 - 152, 130, 304, 20, MIText.StructureMultiblockHatchCasing.text()) { + casingBox = new EditBox(font, width / 2 - 152, 100, 304, 20, MIText.StructureMultiblockHatchCasing.text()) { @Override public boolean charTyped(char codePoint, int modifiers) { return ResourceLocation.isAllowedInResourceLocation(codePoint) && super.charTyped(codePoint, modifiers); @@ -155,7 +184,7 @@ public boolean charTyped(char codePoint, int modifiers) { casingBox.setResponder(text -> this.updateCasing()); this.addRenderableWidget(casingBox); - flagsBox = new EditBox(font, width / 2 - 152, 170, 304, 20, MIText.StructureMultiblockHatchFlags.text()) { + flagsBox = new EditBox(font, width / 2 - 152, 140, 304, 20, MIText.StructureMultiblockHatchFlags.text()) { @Override public boolean charTyped(char codePoint, int modifiers) { return (Character.isDigit(codePoint) || Character.isAlphabetic(codePoint) || codePoint == ';' || codePoint == '_') @@ -174,15 +203,17 @@ public boolean charTyped(char codePoint, int modifiers) { public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) { super.render(graphics, mouseX, mouseY, partialTick); - graphics.drawCenteredString(font, title, width / 2, 20, 0xFFFFFF); + graphics.drawString(font, MIText.StructureMultiblockMemberPreview.text(), width / 2 - 152, 10, 0xA0A0A0); - graphics.drawString(font, MIText.StructureMultiblockMemberPreview.text(), width / 2 - 152, 40, 0xA0A0A0); + graphics.drawString(font, MIText.StructureMultiblockMemberMembers.text(), width / 2 - 152, 50, 0xA0A0A0); - graphics.drawString(font, MIText.StructureMultiblockMemberMembers.text(), width / 2 - 152, 80, 0xA0A0A0); + if (casingBox.visible) + graphics.drawString(font, MIText.StructureMultiblockHatchCasing.text(), width / 2 - 152, 90, 0xA0A0A0); - graphics.drawString(font, MIText.StructureMultiblockHatchCasing.text(), width / 2 - 152, 120, 0xA0A0A0); + if (flagsBox.visible) + graphics.drawString(font, MIText.StructureMultiblockHatchFlags.text(), width / 2 - 152, 130, 0xA0A0A0); - graphics.drawString(font, MIText.StructureMultiblockHatchFlags.text(), width / 2 - 152, 160, 0xA0A0A0); + graphics.drawString(font, modeButton.getValue().textInfo(), width / 2 - 4 - 150, 175, 0xA0A0A0); } @Override diff --git a/src/generated/resources/assets/modern_industrialization/lang/en_us.json b/src/generated/resources/assets/modern_industrialization/lang/en_us.json index c1d7b200a..415b827db 100644 --- a/src/generated/resources/assets/modern_industrialization/lang/en_us.json +++ b/src/generated/resources/assets/modern_industrialization/lang/en_us.json @@ -1700,6 +1700,10 @@ "text.modern_industrialization.StructureMultiblockLoadSuccess": "Successfully placed the structure %s.", "text.modern_industrialization.StructureMultiblockLoadTooltip": "Hold SHIFT to place actual blocks instead of structure blocks.", "text.modern_industrialization.StructureMultiblockMemberMembers": "Members", + "text.modern_industrialization.StructureMultiblockMemberModeHatch": "Hatch", + "text.modern_industrialization.StructureMultiblockMemberModeInfoHatch": "Hatch Mode - Include hatches", + "text.modern_industrialization.StructureMultiblockMemberModeInfoSimple": "Simple Mode - Just a block", + "text.modern_industrialization.StructureMultiblockMemberModeSimple": "Simple", "text.modern_industrialization.StructureMultiblockMemberPreview": "Preview", "text.modern_industrialization.StructureMultiblockSaveFailInvalidBounds": "Failed to save structure. The bounds provided are not valid.", "text.modern_industrialization.StructureMultiblockSaveFailMisconfiguredBlock": "Failed to save structure. Some blocks are not properly configured.", diff --git a/src/main/java/aztech/modern_industrialization/MIText.java b/src/main/java/aztech/modern_industrialization/MIText.java index 1f2b67111..18987851a 100644 --- a/src/main/java/aztech/modern_industrialization/MIText.java +++ b/src/main/java/aztech/modern_industrialization/MIText.java @@ -251,6 +251,10 @@ public enum MIText { StructureMultiblockHatchFlags("Hatch Flags"), StructureMultiblockMemberMembers("Members"), StructureMultiblockMemberPreview("Preview"), + StructureMultiblockMemberModeSimple("Simple"), + StructureMultiblockMemberModeHatch("Hatch"), + StructureMultiblockMemberModeInfoSimple("Simple Mode - Just a block"), + StructureMultiblockMemberModeInfoHatch("Hatch Mode - Include hatches"), StructureMultiblockStructureName("Structure Name"), StructureMultiblockLoadTooltip("Hold SHIFT to place actual blocks instead of structure blocks."), StructureMultiblockLoadFailInvalidId("Failed to place the structure. No id was provided."), diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMemberMode.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMemberMode.java new file mode 100644 index 000000000..b42adac4c --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMemberMode.java @@ -0,0 +1,47 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.blocks.structure; + +import aztech.modern_industrialization.MIText; +import net.minecraft.network.chat.Component; + +public enum StructureMemberMode { + HATCH(MIText.StructureMultiblockMemberModeInfoHatch, MIText.StructureMultiblockMemberModeHatch), + SIMPLE(MIText.StructureMultiblockMemberModeInfoSimple, MIText.StructureMultiblockMemberModeSimple); + + private final MIText textInfo, text; + + StructureMemberMode(MIText textInfo, MIText text) { + this.textInfo = textInfo; + this.text = text; + } + + public Component textInfo() { + return textInfo.text(); + } + + public Component text() { + return text.text(); + } +} diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java index 374694945..adb08e051 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java @@ -43,11 +43,11 @@ import org.jetbrains.annotations.Nullable; public class StructureMultiblockControllerBlockEntity extends FastBlockEntity implements StructureMemberOverride { + private StructureControllerMode mode = StructureControllerMode.SAVE; + private String inputId; private String inputCasing; - private StructureControllerMode mode = StructureControllerMode.SAVE; - private ResourceLocation id; private MachineCasing casing; private StructureControllerBounds bounds = new StructureControllerBounds(0, 0, 0, 1, 1, 1); diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java index 5f54a4d2a..a8254a2d3 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java @@ -31,6 +31,8 @@ import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMemberTest; import java.util.List; +import java.util.Locale; +import java.util.Objects; import net.minecraft.core.BlockPos; import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; @@ -41,6 +43,8 @@ import org.jetbrains.annotations.Nullable; public class StructureMultiblockMemberBlockEntity extends FastBlockEntity implements StructureMemberOverride { + private StructureMemberMode mode = StructureMemberMode.HATCH; + private String inputPreview; private String inputMembers; private String inputCasing; @@ -55,6 +59,14 @@ public StructureMultiblockMemberBlockEntity(BlockPos pos, BlockState state) { super(MIRegistries.STRUCTURE_MULTIBLOCK_MEMBER_BE.get(), pos, state); } + public StructureMemberMode getMode() { + return mode; + } + + public void setMode(StructureMemberMode mode) { + this.mode = Objects.requireNonNull(mode); + } + @Nullable public String getInputPreview() { return inputPreview; @@ -117,20 +129,19 @@ public HatchFlags getFlags() { @Override public StructureMember getMemberOverride() { - if (casing == null || (flags == null || flags.flags == 0)) { - return new StructureMember(() -> preview, members, null, null); - } - return new StructureMember(() -> preview, members, casing, flags); + return switch (mode) { + case HATCH -> new StructureMember(() -> preview, members, casing, flags); + case SIMPLE -> new StructureMember(() -> preview, members, null, null); + }; } @Override public boolean isConfigurationValid() { if (preview != null && members != null && !members.isEmpty()) { - boolean hasCasing = casing != null; - boolean hasHatchFlags = flags != null && flags.flags != 0; - boolean noCasing = (inputCasing == null || inputCasing.isEmpty()) && !hasCasing; - boolean noFlags = (inputFlags == null || inputFlags.isEmpty()) && !hasHatchFlags; - return (hasCasing && hasHatchFlags) || (noCasing && noFlags); + if (mode == StructureMemberMode.HATCH) { + return casing != null && flags != null && !inputFlags.isEmpty(); + } + return true; } return false; } @@ -150,6 +161,7 @@ public CompoundTag getUpdateTag(HolderLookup.Provider registries) { @Override protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { super.saveAdditional(tag, registries); + tag.putString("mode", mode.toString().toLowerCase(Locale.ROOT)); if (inputPreview != null) { tag.putString("preview", inputPreview); } @@ -167,6 +179,7 @@ protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) @Override protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { super.loadAdditional(tag, registries); + mode = StructureMemberMode.valueOf(tag.getString("mode").toUpperCase(Locale.ROOT)); this.setInputPreview(tag.getString("preview")); this.setInputMembers(tag.getString("members")); this.setInputCasing(tag.getString("casing")); diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java index d827aff69..1bd560014 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java @@ -23,6 +23,7 @@ */ package aztech.modern_industrialization.network.structure; +import aztech.modern_industrialization.blocks.structure.StructureMemberMode; import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlockEntity; import aztech.modern_industrialization.network.BasePacket; import io.netty.buffer.ByteBuf; @@ -34,12 +35,15 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; -public record StructureUpdateMemberPacket(BlockPos pos, String inputPreview, String inputMembers, String inputCasing, String inputFlags) +public record StructureUpdateMemberPacket(BlockPos pos, StructureMemberMode mode, String inputPreview, String inputMembers, String inputCasing, + String inputFlags) implements BasePacket { public static final StreamCodec STREAM_CODEC = StreamCodec.composite( BlockPos.STREAM_CODEC, StructureUpdateMemberPacket::pos, + ByteBufCodecs.idMapper((i) -> StructureMemberMode.values()[i], Enum::ordinal), + StructureUpdateMemberPacket::mode, ByteBufCodecs.STRING_UTF8, StructureUpdateMemberPacket::inputPreview, ByteBufCodecs.STRING_UTF8, @@ -62,17 +66,18 @@ public void handle(Context ctx) { } BlockEntity blockEntity = level.getBlockEntity(pos); - if (blockEntity instanceof StructureMultiblockMemberBlockEntity hatch) { - hatch.setInputPreview(inputPreview); - hatch.setInputMembers(inputMembers); - hatch.setInputCasing(inputCasing); - hatch.setInputFlags(inputFlags); + if (blockEntity instanceof StructureMultiblockMemberBlockEntity member) { + member.setMode(mode); + member.setInputPreview(inputPreview); + member.setInputMembers(inputMembers); + member.setInputCasing(inputCasing); + member.setInputFlags(inputFlags); - hatch.sync(); - hatch.setChanged(); + member.sync(); + member.setChanged(); - if (player instanceof ServerPlayer serverPlayer && hatch.isConfigurationValid()) { - StructureMisconfiguredBlocksPacket.forget(hatch.getBlockPos()).sendToClient(serverPlayer); + if (player instanceof ServerPlayer serverPlayer && member.isConfigurationValid()) { + StructureMisconfiguredBlocksPacket.forget(member.getBlockPos()).sendToClient(serverPlayer); } } } From c2b9576b5423564d2e85f5eb295bb0b6503126f1 Mon Sep 17 00:00:00 2001 From: Swedz Date: Sun, 24 Nov 2024 07:33:16 -0500 Subject: [PATCH 32/89] Make structure member use blockstates to store mode and add variable mode --- ...ructureMultiblockControllerEditScreen.java | 4 +- .../StructureMultiblockMemberEditScreen.java | 44 ++++++++-- .../structure_multiblock_controller.json | 23 +++++- .../structure_multiblock_member.json | 10 ++- .../modern_industrialization/lang/en_us.json | 7 +- ...=> structure_multiblock_member_hatch.json} | 2 +- .../structure_multiblock_member_simple.json | 6 ++ .../structure_multiblock_member_variable.json | 6 ++ .../item/structure_multiblock_member.json | 2 +- .../modern_industrialization/MIBlock.java | 12 ++- .../modern_industrialization/MIText.java | 7 +- .../structure/StructureControllerMode.java | 12 ++- .../blocks/structure/StructureMemberMode.java | 12 ++- .../StructureMultiblockControllerBlock.java | 15 ++-- ...uctureMultiblockControllerBlockEntity.java | 19 ++++- .../StructureMultiblockMemberBlock.java | 11 +++ .../StructureMultiblockMemberBlockEntity.java | 43 ++++++++-- .../kubejs/machine/ShapeTemplateHelper.java | 4 +- .../machines/multiblocks/ShapeMatcher.java | 48 +++++++---- .../machines/multiblocks/ShapeTemplate.java | 45 +++++++++- .../structure/MIStructureTemplateManager.java | 2 +- .../structure/member/StructureMember.java | 77 ++++++++++++++---- .../StructureUpdateMemberPacket.java | 9 +- .../block/structure_multiblock_member.png | Bin 280 -> 0 bytes .../structure_multiblock_member_hatch.png | Bin 0 -> 335 bytes .../structure_multiblock_member_simple.png | Bin 0 -> 362 bytes .../structure_multiblock_member_variable.png | Bin 0 -> 359 bytes 27 files changed, 339 insertions(+), 81 deletions(-) rename src/generated/resources/assets/modern_industrialization/models/block/{structure_multiblock_member.json => structure_multiblock_member_hatch.json} (90%) create mode 100644 src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_member_simple.json create mode 100644 src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_member_variable.json delete mode 100644 src/main/resources/assets/modern_industrialization/textures/block/structure_multiblock_member.png create mode 100644 src/main/resources/assets/modern_industrialization/textures/block/structure_multiblock_member_hatch.png create mode 100644 src/main/resources/assets/modern_industrialization/textures/block/structure_multiblock_member_simple.png create mode 100644 src/main/resources/assets/modern_industrialization/textures/block/structure_multiblock_member_variable.png diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java index a8e66234e..5019891f0 100644 --- a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java @@ -224,7 +224,7 @@ public boolean charTyped(char codePoint, int modifiers) { idBox.setResponder(text -> this.updateId()); this.addRenderableWidget(idBox); - casingBox = new EditBox(font, width / 2 - 152, 90, 304, 20, MIText.StructureMultiblockHatchCasing.text()) { + casingBox = new EditBox(font, width / 2 - 152, 90, 304, 20, MIText.StructureMultiblockCasing.text()) { @Override public boolean charTyped(char codePoint, int modifiers) { return ResourceLocation.isAllowedInResourceLocation(codePoint) && super.charTyped(codePoint, modifiers); @@ -285,7 +285,7 @@ public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTi graphics.drawString(font, MIText.StructureMultiblockStructureName.text(), width / 2 - 152, 40, 0xA0A0A0); if (casingBox.visible) - graphics.drawString(font, MIText.StructureMultiblockHatchCasing.text(), width / 2 - 152, 80, 0xA0A0A0); + graphics.drawString(font, MIText.StructureMultiblockCasing.text(), width / 2 - 152, 80, 0xA0A0A0); if (posXBox.visible || posYBox.visible || posZBox.visible) graphics.drawString(font, Component.translatable("structure_block.position"), width / 2 - 152, 120, 0xA0A0A0); diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java index 64c14148d..dc4483d4f 100644 --- a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java @@ -59,6 +59,8 @@ public class StructureMultiblockMemberEditScreen extends Screen { private Button cancelButton; private CycleButton modeButton; + private EditBox nameBox; + private EditBox previewBox; private EditBox membersBox; @@ -89,19 +91,34 @@ private Optional getHatchFlags() { private void updateMode(StructureMemberMode mode) { this.sendToServer(); + nameBox.visible = false; + previewBox.visible = false; + membersBox.visible = false; casingBox.visible = false; flagsBox.visible = false; switch (mode) { case HATCH -> { + previewBox.visible = true; + membersBox.visible = true; casingBox.visible = true; flagsBox.visible = true; } case SIMPLE -> { + previewBox.visible = true; + membersBox.visible = true; + } + case VARIABLE -> { + nameBox.visible = true; } } } + private void updateName() { + boolean validName = !nameBox.getValue().isEmpty(); + nameBox.setTextColor(validName ? VALID_TEXT_COLOR : INVALID_TEXT_COLOR); + } + private void updatePreview() { boolean validPreview = previewBox.getValue().isEmpty() || this.getPreview().isPresent(); previewBox.setTextColor(validPreview ? VALID_TEXT_COLOR : INVALID_TEXT_COLOR); @@ -124,6 +141,7 @@ private void updateFlags() { private void updateAll() { this.updateMode(member.getMode()); + this.updateName(); this.updatePreview(); this.updateMembers(); this.updateCasing(); @@ -139,6 +157,7 @@ private void sendToServer() { new StructureUpdateMemberPacket( member.getBlockPos(), modeButton.getValue(), + nameBox.getValue(), previewBox.getValue(), membersBox.getValue(), casingBox.getValue(), @@ -161,6 +180,12 @@ protected void init() { .withInitialValue(member.getMode()) .create(width / 2 - 4 - 150, 185, 50, 20, Component.literal("MODE"), (button, mode) -> this.updateMode(mode))); + nameBox = new EditBox(font, width / 2 - 152, 20, 304, 20, MIText.StructureMultiblockMemberName.text()); + nameBox.setMaxLength(Short.MAX_VALUE); + nameBox.setValue(member.getInputName()); + nameBox.setResponder(text -> this.updateName()); + this.addRenderableWidget(nameBox); + previewBox = new EditBox(font, width / 2 - 152, 20, 304, 20, MIText.StructureMultiblockMemberPreview.text()); previewBox.setMaxLength(Short.MAX_VALUE); previewBox.setValue(member.getInputPreview()); @@ -173,7 +198,7 @@ protected void init() { membersBox.setResponder(text -> this.updateMembers()); this.addRenderableWidget(membersBox); - casingBox = new EditBox(font, width / 2 - 152, 100, 304, 20, MIText.StructureMultiblockHatchCasing.text()) { + casingBox = new EditBox(font, width / 2 - 152, 100, 304, 20, MIText.StructureMultiblockCasing.text()) { @Override public boolean charTyped(char codePoint, int modifiers) { return ResourceLocation.isAllowedInResourceLocation(codePoint) && super.charTyped(codePoint, modifiers); @@ -184,7 +209,7 @@ public boolean charTyped(char codePoint, int modifiers) { casingBox.setResponder(text -> this.updateCasing()); this.addRenderableWidget(casingBox); - flagsBox = new EditBox(font, width / 2 - 152, 140, 304, 20, MIText.StructureMultiblockHatchFlags.text()) { + flagsBox = new EditBox(font, width / 2 - 152, 140, 304, 20, MIText.StructureMultiblockMemberHatchFlags.text()) { @Override public boolean charTyped(char codePoint, int modifiers) { return (Character.isDigit(codePoint) || Character.isAlphabetic(codePoint) || codePoint == ';' || codePoint == '_') @@ -203,15 +228,20 @@ public boolean charTyped(char codePoint, int modifiers) { public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) { super.render(graphics, mouseX, mouseY, partialTick); - graphics.drawString(font, MIText.StructureMultiblockMemberPreview.text(), width / 2 - 152, 10, 0xA0A0A0); + if (nameBox.visible) + graphics.drawString(font, MIText.StructureMultiblockMemberName.text(), width / 2 - 152, 10, 0xA0A0A0); + + if (previewBox.visible) + graphics.drawString(font, MIText.StructureMultiblockMemberPreview.text(), width / 2 - 152, 10, 0xA0A0A0); - graphics.drawString(font, MIText.StructureMultiblockMemberMembers.text(), width / 2 - 152, 50, 0xA0A0A0); + if (membersBox.visible) + graphics.drawString(font, MIText.StructureMultiblockMemberMembers.text(), width / 2 - 152, 50, 0xA0A0A0); if (casingBox.visible) - graphics.drawString(font, MIText.StructureMultiblockHatchCasing.text(), width / 2 - 152, 90, 0xA0A0A0); + graphics.drawString(font, MIText.StructureMultiblockCasing.text(), width / 2 - 152, 90, 0xA0A0A0); if (flagsBox.visible) - graphics.drawString(font, MIText.StructureMultiblockHatchFlags.text(), width / 2 - 152, 130, 0xA0A0A0); + graphics.drawString(font, MIText.StructureMultiblockMemberHatchFlags.text(), width / 2 - 152, 130, 0xA0A0A0); graphics.drawString(font, modeButton.getValue().textInfo(), width / 2 - 4 - 150, 175, 0xA0A0A0); } @@ -228,6 +258,7 @@ protected void setInitialFocus() { @Override public void resize(Minecraft minecraft, int width, int height) { + String nameBoxValue = nameBox.getValue(); String previewBoxValue = previewBox.getValue(); String membersBoxValue = membersBox.getValue(); String casingBoxValue = casingBox.getValue(); @@ -235,6 +266,7 @@ public void resize(Minecraft minecraft, int width, int height) { this.init(minecraft, width, height); + nameBox.setValue(nameBoxValue); previewBox.setValue(previewBoxValue); membersBox.setValue(membersBoxValue); casingBox.setValue(casingBoxValue); diff --git a/src/generated/resources/assets/modern_industrialization/blockstates/structure_multiblock_controller.json b/src/generated/resources/assets/modern_industrialization/blockstates/structure_multiblock_controller.json index 3e7f146fc..26107405c 100644 --- a/src/generated/resources/assets/modern_industrialization/blockstates/structure_multiblock_controller.json +++ b/src/generated/resources/assets/modern_industrialization/blockstates/structure_multiblock_controller.json @@ -1,17 +1,32 @@ { "variants": { - "facing=east": { + "facing=east,mode=load": { "model": "modern_industrialization:block/structure_multiblock_controller", "y": 90 }, - "facing=north": { + "facing=east,mode=save": { + "model": "modern_industrialization:block/structure_multiblock_controller", + "y": 90 + }, + "facing=north,mode=load": { "model": "modern_industrialization:block/structure_multiblock_controller" }, - "facing=south": { + "facing=north,mode=save": { + "model": "modern_industrialization:block/structure_multiblock_controller" + }, + "facing=south,mode=load": { "model": "modern_industrialization:block/structure_multiblock_controller", "y": 180 }, - "facing=west": { + "facing=south,mode=save": { + "model": "modern_industrialization:block/structure_multiblock_controller", + "y": 180 + }, + "facing=west,mode=load": { + "model": "modern_industrialization:block/structure_multiblock_controller", + "y": 270 + }, + "facing=west,mode=save": { "model": "modern_industrialization:block/structure_multiblock_controller", "y": 270 } diff --git a/src/generated/resources/assets/modern_industrialization/blockstates/structure_multiblock_member.json b/src/generated/resources/assets/modern_industrialization/blockstates/structure_multiblock_member.json index db1dc2380..625724914 100644 --- a/src/generated/resources/assets/modern_industrialization/blockstates/structure_multiblock_member.json +++ b/src/generated/resources/assets/modern_industrialization/blockstates/structure_multiblock_member.json @@ -1,7 +1,13 @@ { "variants": { - "": { - "model": "modern_industrialization:block/structure_multiblock_member" + "mode=hatch": { + "model": "modern_industrialization:block/structure_multiblock_member_hatch" + }, + "mode=simple": { + "model": "modern_industrialization:block/structure_multiblock_member_simple" + }, + "mode=variable": { + "model": "modern_industrialization:block/structure_multiblock_member_variable" } } } \ No newline at end of file diff --git a/src/generated/resources/assets/modern_industrialization/lang/en_us.json b/src/generated/resources/assets/modern_industrialization/lang/en_us.json index 415b827db..33951588d 100644 --- a/src/generated/resources/assets/modern_industrialization/lang/en_us.json +++ b/src/generated/resources/assets/modern_industrialization/lang/en_us.json @@ -1693,17 +1693,20 @@ "text.modern_industrialization.SteamDrillProfit": "- Press %s to toggle 3x3 mining.", "text.modern_industrialization.SteamDrillToggle": "- Toggle Silk Touch with %s + %s.", "text.modern_industrialization.SteamDrillWaterHelp": "- Press %s on still or flowing water to fill.", - "text.modern_industrialization.StructureMultiblockHatchCasing": "Machine Casing", - "text.modern_industrialization.StructureMultiblockHatchFlags": "Hatch Flags", + "text.modern_industrialization.StructureMultiblockCasing": "Machine Casing", "text.modern_industrialization.StructureMultiblockLoadFailDoesntExist": "Failed to place the structure. No structure exists as %s.", "text.modern_industrialization.StructureMultiblockLoadFailInvalidId": "Failed to place the structure. No id was provided.", "text.modern_industrialization.StructureMultiblockLoadSuccess": "Successfully placed the structure %s.", "text.modern_industrialization.StructureMultiblockLoadTooltip": "Hold SHIFT to place actual blocks instead of structure blocks.", + "text.modern_industrialization.StructureMultiblockMemberHatchFlags": "Hatch Flags", "text.modern_industrialization.StructureMultiblockMemberMembers": "Members", "text.modern_industrialization.StructureMultiblockMemberModeHatch": "Hatch", "text.modern_industrialization.StructureMultiblockMemberModeInfoHatch": "Hatch Mode - Include hatches", "text.modern_industrialization.StructureMultiblockMemberModeInfoSimple": "Simple Mode - Just a block", + "text.modern_industrialization.StructureMultiblockMemberModeInfoVariable": "Variable Mode - Filled in at runtime", "text.modern_industrialization.StructureMultiblockMemberModeSimple": "Simple", + "text.modern_industrialization.StructureMultiblockMemberModeVariable": "Variable", + "text.modern_industrialization.StructureMultiblockMemberName": "Member Name", "text.modern_industrialization.StructureMultiblockMemberPreview": "Preview", "text.modern_industrialization.StructureMultiblockSaveFailInvalidBounds": "Failed to save structure. The bounds provided are not valid.", "text.modern_industrialization.StructureMultiblockSaveFailMisconfiguredBlock": "Failed to save structure. Some blocks are not properly configured.", diff --git a/src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_member.json b/src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_member_hatch.json similarity index 90% rename from src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_member.json rename to src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_member_hatch.json index 74c3302dd..b530e5215 100644 --- a/src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_member.json +++ b/src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_member_hatch.json @@ -1,6 +1,6 @@ { "parent": "minecraft:block/cube_all", "textures": { - "all": "modern_industrialization:block/structure_multiblock_member" + "all": "modern_industrialization:block/structure_multiblock_member_hatch" } } \ No newline at end of file diff --git a/src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_member_simple.json b/src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_member_simple.json new file mode 100644 index 000000000..dd219547f --- /dev/null +++ b/src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_member_simple.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "modern_industrialization:block/structure_multiblock_member_simple" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_member_variable.json b/src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_member_variable.json new file mode 100644 index 000000000..a76debcc6 --- /dev/null +++ b/src/generated/resources/assets/modern_industrialization/models/block/structure_multiblock_member_variable.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "modern_industrialization:block/structure_multiblock_member_variable" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/modern_industrialization/models/item/structure_multiblock_member.json b/src/generated/resources/assets/modern_industrialization/models/item/structure_multiblock_member.json index 00613b81b..ca3e72608 100644 --- a/src/generated/resources/assets/modern_industrialization/models/item/structure_multiblock_member.json +++ b/src/generated/resources/assets/modern_industrialization/models/item/structure_multiblock_member.json @@ -1,3 +1,3 @@ { - "parent": "modern_industrialization:block/structure_multiblock_member" + "parent": "modern_industrialization:block/structure_multiblock_member_simple" } \ No newline at end of file diff --git a/src/main/java/aztech/modern_industrialization/MIBlock.java b/src/main/java/aztech/modern_industrialization/MIBlock.java index a246a92a0..7a9f856a7 100644 --- a/src/main/java/aztech/modern_industrialization/MIBlock.java +++ b/src/main/java/aztech/modern_industrialization/MIBlock.java @@ -63,6 +63,7 @@ import net.minecraft.world.level.material.MapColor; import net.neoforged.bus.api.IEventBus; import net.neoforged.neoforge.capabilities.Capabilities; +import net.neoforged.neoforge.client.model.generators.ConfiguredModel; import net.neoforged.neoforge.client.model.generators.ItemModelProvider; import net.neoforged.neoforge.client.model.generators.ModelFile; import net.neoforged.neoforge.registries.DeferredRegister; @@ -152,8 +153,15 @@ public static void init(IEventBus modBus) { .withBlockConstructor(StructureMultiblockMemberBlock::new) .withBlockItemConstructor((block, p) -> new BlockItem(block, p.rarity(Rarity.EPIC))) .withModel((block, gen) -> { - String name = gen.name(block); - gen.simpleBlockWithItem(block, gen.models().cubeAll(name, gen.blockTexture("structure_multiblock_member"))); + gen.getVariantBuilder(block).forAllStates(state -> { + var mode = state.getValue(StructureMultiblockMemberBlock.MODE); + String texture = "structure_multiblock_member_" + mode.getSerializedName(); + return ConfiguredModel.builder() + .modelFile(gen.models().cubeAll(texture, gen.blockTexture(texture))) + .build(); + }); + String simpleTexture = "structure_multiblock_member_simple"; + gen.simpleBlockItem(block, gen.models().cubeAll(simpleTexture, gen.blockTexture(simpleTexture))); })); // Materials diff --git a/src/main/java/aztech/modern_industrialization/MIText.java b/src/main/java/aztech/modern_industrialization/MIText.java index 18987851a..ff5c4387b 100644 --- a/src/main/java/aztech/modern_industrialization/MIText.java +++ b/src/main/java/aztech/modern_industrialization/MIText.java @@ -247,14 +247,17 @@ public enum MIText { SteamDrillProfit("- Press %s to toggle 3x3 mining."), SteamDrillToggle("- Toggle Silk Touch with %s + %s."), SteamDrillWaterHelp("- Press %s on still or flowing water to fill."), - StructureMultiblockHatchCasing("Machine Casing"), - StructureMultiblockHatchFlags("Hatch Flags"), + StructureMultiblockCasing("Machine Casing"), + StructureMultiblockMemberHatchFlags("Hatch Flags"), + StructureMultiblockMemberName("Member Name"), StructureMultiblockMemberMembers("Members"), StructureMultiblockMemberPreview("Preview"), StructureMultiblockMemberModeSimple("Simple"), StructureMultiblockMemberModeHatch("Hatch"), + StructureMultiblockMemberModeVariable("Variable"), StructureMultiblockMemberModeInfoSimple("Simple Mode - Just a block"), StructureMultiblockMemberModeInfoHatch("Hatch Mode - Include hatches"), + StructureMultiblockMemberModeInfoVariable("Variable Mode - Filled in at runtime"), StructureMultiblockStructureName("Structure Name"), StructureMultiblockLoadTooltip("Hold SHIFT to place actual blocks instead of structure blocks."), StructureMultiblockLoadFailInvalidId("Failed to place the structure. No id was provided."), diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureControllerMode.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureControllerMode.java index c47b5ca43..76189283c 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureControllerMode.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureControllerMode.java @@ -25,16 +25,22 @@ import java.util.Locale; import net.minecraft.network.chat.Component; +import net.minecraft.util.StringRepresentable; -public enum StructureControllerMode { +public enum StructureControllerMode implements StringRepresentable { SAVE, LOAD; public Component textInfo() { - return Component.translatable("structure_block.mode_info." + this.name().toLowerCase(Locale.ROOT)); + return Component.translatable("structure_block.mode_info." + this.getSerializedName()); } public Component text() { - return Component.translatable("structure_block.mode." + this.name().toLowerCase(Locale.ROOT)); + return Component.translatable("structure_block.mode." + this.getSerializedName()); + } + + @Override + public String getSerializedName() { + return this.name().toLowerCase(Locale.ROOT); } } diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMemberMode.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMemberMode.java index b42adac4c..2bfc77c2b 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMemberMode.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMemberMode.java @@ -24,11 +24,14 @@ package aztech.modern_industrialization.blocks.structure; import aztech.modern_industrialization.MIText; +import java.util.Locale; import net.minecraft.network.chat.Component; +import net.minecraft.util.StringRepresentable; -public enum StructureMemberMode { +public enum StructureMemberMode implements StringRepresentable { + SIMPLE(MIText.StructureMultiblockMemberModeInfoSimple, MIText.StructureMultiblockMemberModeSimple), HATCH(MIText.StructureMultiblockMemberModeInfoHatch, MIText.StructureMultiblockMemberModeHatch), - SIMPLE(MIText.StructureMultiblockMemberModeInfoSimple, MIText.StructureMultiblockMemberModeSimple); + VARIABLE(MIText.StructureMultiblockMemberModeInfoVariable, MIText.StructureMultiblockMemberModeVariable); private final MIText textInfo, text; @@ -44,4 +47,9 @@ public Component textInfo() { public Component text() { return text.text(); } + + @Override + public String getSerializedName() { + return this.name().toLowerCase(Locale.ROOT); + } } diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlock.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlock.java index 948cbc171..e9300e525 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlock.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlock.java @@ -37,14 +37,24 @@ import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.EnumProperty; import net.minecraft.world.phys.BlockHitResult; public class StructureMultiblockControllerBlock extends HorizontalDirectionalBlock implements EntityBlock, GameMasterBlock { private static final MapCodec CODEC = simpleCodec( StructureMultiblockControllerBlock::new); + public static final EnumProperty MODE = EnumProperty.create("mode", StructureControllerMode.class); + public StructureMultiblockControllerBlock(Properties properties) { super(properties); + this.registerDefaultState(stateDefinition.any() + .setValue(MODE, StructureControllerMode.SAVE)); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(MODE, FACING); } @Override @@ -68,11 +78,6 @@ public BlockState getStateForPlacement(BlockPlaceContext context) { return this.defaultBlockState().setValue(FACING, context.getHorizontalDirection().getOpposite()); } - @Override - protected void createBlockStateDefinition(StateDefinition.Builder builder) { - builder.add(FACING); - } - @Override public StructureMultiblockControllerBlockEntity newBlockEntity(BlockPos pos, BlockState state) { return new StructureMultiblockControllerBlockEntity(pos, state); diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java index adb08e051..867239162 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java @@ -23,6 +23,7 @@ */ package aztech.modern_industrialization.blocks.structure; +import aztech.modern_industrialization.MIBlock; import aztech.modern_industrialization.MIRegistries; import aztech.modern_industrialization.blocks.FastBlockEntity; import aztech.modern_industrialization.machines.models.MachineCasing; @@ -43,7 +44,7 @@ import org.jetbrains.annotations.Nullable; public class StructureMultiblockControllerBlockEntity extends FastBlockEntity implements StructureMemberOverride { - private StructureControllerMode mode = StructureControllerMode.SAVE; + private StructureControllerMode mode; private String inputId; private String inputCasing; @@ -55,6 +56,7 @@ public class StructureMultiblockControllerBlockEntity extends FastBlockEntity im public StructureMultiblockControllerBlockEntity(BlockPos pos, BlockState state) { super(MIRegistries.STRUCTURE_MULTIBLOCK_CONTROLLER_BE.get(), pos, state); + mode = state.getValue(StructureMultiblockControllerBlock.MODE); } public StructureControllerMode getMode() { @@ -62,7 +64,9 @@ public StructureControllerMode getMode() { } public void setMode(StructureControllerMode mode) { - this.mode = Objects.requireNonNull(mode); + Objects.requireNonNull(mode); + this.mode = mode; + this.updateBlockState(); } @Nullable @@ -172,5 +176,16 @@ protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) bounds = new StructureControllerBounds(0, 0, 0, 1, 1, 1); } showBounds = tag.getBoolean("show_bounds"); + this.updateBlockState(); + } + + private void updateBlockState() { + if (level != null) { + BlockPos pos = getBlockPos(); + BlockState state = level.getBlockState(pos); + if (state.is(MIBlock.STRUCTURE_MULTIBLOCK_CONTROLLER.get())) { + level.setBlock(pos, state.setValue(StructureMultiblockControllerBlock.MODE, mode), 2); + } + } } } diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlock.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlock.java index 2d3d02046..511b105fd 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlock.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlock.java @@ -34,13 +34,24 @@ import net.minecraft.world.level.block.GameMasterBlock; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.EnumProperty; import net.minecraft.world.phys.BlockHitResult; public class StructureMultiblockMemberBlock extends Block implements EntityBlock, GameMasterBlock { private static final MapCodec CODEC = simpleCodec(StructureMultiblockMemberBlock::new); + public static final EnumProperty MODE = EnumProperty.create("mode", StructureMemberMode.class); + public StructureMultiblockMemberBlock(Properties properties) { super(properties); + this.registerDefaultState(stateDefinition.any() + .setValue(MODE, StructureMemberMode.SIMPLE)); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(MODE); } @Override diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java index a8254a2d3..b8d2d5501 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java @@ -23,6 +23,7 @@ */ package aztech.modern_industrialization.blocks.structure; +import aztech.modern_industrialization.MIBlock; import aztech.modern_industrialization.MIRegistries; import aztech.modern_industrialization.blocks.FastBlockEntity; import aztech.modern_industrialization.machines.models.MachineCasing; @@ -43,8 +44,9 @@ import org.jetbrains.annotations.Nullable; public class StructureMultiblockMemberBlockEntity extends FastBlockEntity implements StructureMemberOverride { - private StructureMemberMode mode = StructureMemberMode.HATCH; + private StructureMemberMode mode; + private String inputName; private String inputPreview; private String inputMembers; private String inputCasing; @@ -57,6 +59,7 @@ public class StructureMultiblockMemberBlockEntity extends FastBlockEntity implem public StructureMultiblockMemberBlockEntity(BlockPos pos, BlockState state) { super(MIRegistries.STRUCTURE_MULTIBLOCK_MEMBER_BE.get(), pos, state); + mode = state.getValue(StructureMultiblockMemberBlock.MODE); } public StructureMemberMode getMode() { @@ -64,7 +67,17 @@ public StructureMemberMode getMode() { } public void setMode(StructureMemberMode mode) { - this.mode = Objects.requireNonNull(mode); + Objects.requireNonNull(mode); + this.mode = mode; + this.updateBlockState(); + } + + public String getInputName() { + return inputName; + } + + public void setInputName(String inputName) { + this.inputName = inputName; } @Nullable @@ -129,15 +142,18 @@ public HatchFlags getFlags() { @Override public StructureMember getMemberOverride() { - return switch (mode) { - case HATCH -> new StructureMember(() -> preview, members, casing, flags); - case SIMPLE -> new StructureMember(() -> preview, members, null, null); + return switch (getMode()) { + case HATCH -> StructureMember.hatch(() -> preview, members, casing, flags); + case SIMPLE -> StructureMember.simple(() -> preview, members); + case VARIABLE -> StructureMember.variable(inputName); }; } @Override public boolean isConfigurationValid() { - if (preview != null && members != null && !members.isEmpty()) { + if (mode == StructureMemberMode.VARIABLE) { + return inputName != null && !inputName.isEmpty(); + } else if (preview != null && members != null && !members.isEmpty()) { if (mode == StructureMemberMode.HATCH) { return casing != null && flags != null && !inputFlags.isEmpty(); } @@ -162,6 +178,9 @@ public CompoundTag getUpdateTag(HolderLookup.Provider registries) { protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { super.saveAdditional(tag, registries); tag.putString("mode", mode.toString().toLowerCase(Locale.ROOT)); + if (inputName != null) { + tag.putString("name", inputName); + } if (inputPreview != null) { tag.putString("preview", inputPreview); } @@ -180,9 +199,21 @@ protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { super.loadAdditional(tag, registries); mode = StructureMemberMode.valueOf(tag.getString("mode").toUpperCase(Locale.ROOT)); + this.setInputName(tag.getString("name")); this.setInputPreview(tag.getString("preview")); this.setInputMembers(tag.getString("members")); this.setInputCasing(tag.getString("casing")); this.setInputFlags(tag.getString("flags")); + this.updateBlockState(); + } + + private void updateBlockState() { + if (level != null) { + BlockPos pos = getBlockPos(); + BlockState state = level.getBlockState(pos); + if (state.is(MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.get())) { + level.setBlock(pos, state.setValue(StructureMultiblockMemberBlock.MODE, mode), 2); + } + } } } diff --git a/src/main/java/aztech/modern_industrialization/compat/kubejs/machine/ShapeTemplateHelper.java b/src/main/java/aztech/modern_industrialization/compat/kubejs/machine/ShapeTemplateHelper.java index 0a9779425..80afdf052 100644 --- a/src/main/java/aztech/modern_industrialization/compat/kubejs/machine/ShapeTemplateHelper.java +++ b/src/main/java/aztech/modern_industrialization/compat/kubejs/machine/ShapeTemplateHelper.java @@ -31,8 +31,8 @@ import net.minecraft.resources.ResourceLocation; public interface ShapeTemplateHelper { - default ShapeTemplate structureShape(ResourceLocation id) { - return new ShapeTemplate.Structure(id).build(); + default ShapeTemplate.Structure structureShape(ResourceLocation id) { + return new ShapeTemplate.Structure(id); } default ShapeTemplate.LayeredBuilder layeredShape(String hatchCasing, String[][] layers) { diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java index f7eeea06a..4974bdf71 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java @@ -24,6 +24,8 @@ package aztech.modern_industrialization.machines.multiblocks; import aztech.modern_industrialization.MIBlock; +import aztech.modern_industrialization.blocks.structure.StructureMemberMode; +import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlock; import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlockEntity; import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockInputFormatters; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; @@ -253,33 +255,45 @@ public int buildMultiblock(Level level, boolean structureBlocks) { for (var entry : simpleMembers.entrySet()) { BlockPos pos = entry.getKey(); var current = level.getBlockState(pos); - if (!entry.getValue().matchesState(current) || structureBlocks) { - BlockState state = entry.getValue().getPreviewState(); - if (entry.getValue() instanceof StructureMember member) { - // TODO SWEDZ: there has gotta be a better way to do this - if (structureBlocks) { - boolean hasMultipleTests = member.tests().size() > 1; - boolean hasHatchFlags = member.casing() != null && member.hatchFlags() != null && member.hatchFlags().flags != 0; - + if (entry.getValue() instanceof StructureMember member) { + // TODO SWEDZ: there has gotta be a better way to do this + boolean hasName = member.name() != null && !member.name().isEmpty(); + boolean hasMultipleTests = member.tests().size() > 1; + boolean hasHatchFlags = member.casing() != null && member.hatchFlags() != null && member.hatchFlags().flags != 0; + + if (structureBlocks || hasName) { + if (hasName || hasMultipleTests || hasHatchFlags) { + BlockState state = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.asBlock().defaultBlockState(); + StructureMultiblockMemberBlockEntity be = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.get().newBlockEntity(pos, state); + if (hasName) { + state = state.setValue(StructureMultiblockMemberBlock.MODE, StructureMemberMode.VARIABLE); + be.setMode(StructureMemberMode.VARIABLE); + be.setInputName(member.name()); + } if (hasMultipleTests || hasHatchFlags) { - state = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.asBlock().defaultBlockState(); - level.setBlockAndUpdate(pos, state); - StructureMultiblockMemberBlockEntity be = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.get().newBlockEntity(pos, state); be.setInputPreview(StructureMultiblockInputFormatters.preview(member.preview())); be.setInputMembers(StructureMultiblockInputFormatters.members(member.tests())); if (hasHatchFlags) { + state = state.setValue(StructureMultiblockMemberBlock.MODE, StructureMemberMode.HATCH); + be.setMode(StructureMemberMode.HATCH); be.setInputCasing(StructureMultiblockInputFormatters.casing(member.casing())); be.setInputFlags(StructureMultiblockInputFormatters.hatchFlags(member.hatchFlags())); + } else { + state = state.setValue(StructureMultiblockMemberBlock.MODE, StructureMemberMode.SIMPLE); + be.setMode(StructureMemberMode.SIMPLE); } - level.setBlockEntity(be); - be.setChanged(); - be.sync(); - setBlocks++; - continue; } + level.setBlockAndUpdate(pos, state); + level.setBlockEntity(be); + be.setChanged(); + be.sync(); + setBlocks++; + continue; } - state = toWorldState(level, pos, state, controllerDirection); } + } + if (!entry.getValue().matchesState(current)) { + BlockState state = toWorldState(level, pos, entry.getValue().getPreviewState(), controllerDirection); level.setBlockAndUpdate(pos, state); ++setBlocks; } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java index 0ab890159..1c4457570 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java @@ -25,9 +25,13 @@ import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.structure.MIStructureTemplateManager; +import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import net.minecraft.core.BlockPos; import net.minecraft.resources.ResourceLocation; @@ -204,14 +208,49 @@ public ShapeTemplate build() { } public static class Structure { - private final ResourceLocation id; + private final ShapeTemplate template; public Structure(ResourceLocation id) { - this.id = id; + ShapeTemplate referenceTemplate = MIStructureTemplateManager.get(id); + template = new ShapeTemplate(referenceTemplate.hatchCasing); + template.simpleMembers.putAll(referenceTemplate.simpleMembers); + template.hatchFlags.putAll(referenceTemplate.hatchFlags); + } + + public Structure replace(String name, SimpleMember member, @Nullable HatchFlags flags) { + List positions = new ArrayList<>(); + for (var entry : template.simpleMembers.entrySet()) { + SimpleMember other = entry.getValue(); + if (other instanceof StructureMember structureMember && Objects.equals(name, structureMember.name())) { + positions.add(entry.getKey()); + } + } + if (positions.isEmpty()) { + throw new IllegalArgumentException("No members with the name \"" + name + "\" could be found"); + } + for (BlockPos pos : positions) { + template.simpleMembers.put(pos, member); + if (flags != null) { + template.hatchFlags.put(pos, flags); + } + } + return this; + } + + public Structure replace(String name, SimpleMember member) { + return replace(name, member, null); } public ShapeTemplate build() { - return MIStructureTemplateManager.get(id); + for (SimpleMember member : template.simpleMembers.values()) { + if (member instanceof StructureMember structureMember) { + if (structureMember.name() != null) { + throw new IllegalArgumentException( + "Tried to build structure template without replacing member with the name \"" + structureMember.name() + "\""); + } + } + } + return template; } } } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java index 868b0812c..b5508dc2c 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java @@ -135,7 +135,7 @@ public static StructureResult fromWorld(ResourceLocation id, Level level, blockTag.put("pos", NbtUtils.writeBlockPos(toTemplatePos(controllerPos, controllerDirection, pos))); - StructureMember member = new StructureMember(() -> state); + StructureMember member = StructureMember.literal(() -> state); BlockEntity blockEntity = level.getBlockEntity(pos); if (blockEntity instanceof StructureMemberOverride override) { diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java index a384937e9..2a9db98c7 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java @@ -38,10 +38,12 @@ import net.minecraft.nbt.NbtUtils; import net.minecraft.nbt.Tag; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.Nullable; public final class StructureMember implements SimpleMember { + private final String name; private final Supplier previewSupplier; private final List tests; private final MachineCasing casing; @@ -49,19 +51,46 @@ public final class StructureMember implements SimpleMember { private BlockState preview; - public StructureMember(Supplier preview, List tests, @Nullable MachineCasing casing, - @Nullable HatchFlags hatchFlags) { + private StructureMember(@Nullable String name, @Nullable Supplier preview, List tests, + @Nullable MachineCasing casing, @Nullable HatchFlags hatchFlags) { + this.name = name; this.previewSupplier = preview; this.tests = tests; this.casing = casing; this.hatchFlags = hatchFlags; } - public StructureMember(Supplier state) { - this(state, List.of(new StructureMemberTestState(state)), null, null); + public static StructureMember literal(Supplier state) { + return new StructureMember(null, state, List.of(new StructureMemberTestState(state)), null, null); + } + + public static StructureMember variable(String name) { + Objects.requireNonNull(name); + return new StructureMember(name, null, List.of(), null, null); + } + + public static StructureMember simple(Supplier preview, List tests) { + Objects.requireNonNull(preview); + Objects.requireNonNull(tests); + return new StructureMember(null, preview, tests, null, null); + } + + public static StructureMember hatch(Supplier preview, List tests, MachineCasing casing, HatchFlags hatchFlags) { + Objects.requireNonNull(preview); + Objects.requireNonNull(tests); + Objects.requireNonNull(casing); + Objects.requireNonNull(hatchFlags); + return new StructureMember(null, preview, tests, casing, hatchFlags); + } + + public String name() { + return name; } public BlockState preview() { + if (previewSupplier == null) { + return null; + } if (preview == null) { preview = previewSupplier.get(); } @@ -84,6 +113,9 @@ public HatchFlags hatchFlags() { @Override public boolean matchesState(BlockState state) { + if (name != null) { + throw new IllegalStateException("Tried to use a structure member with a name without replacing it in the template."); + } for (StructureMemberTest test : tests) { if (test.matchesState(state)) { return true; @@ -94,13 +126,17 @@ public boolean matchesState(BlockState state) { @Override public BlockState getPreviewState() { - return this.preview(); + if (name != null) { + throw new IllegalStateException("Tried to use a structure member with a name without replacing it in the template."); + } + return this.preview() == null ? Blocks.AIR.defaultBlockState() : this.preview(); } @Override public boolean equals(Object o) { if (o instanceof StructureMember other) { - return this.preview() == other.preview() && + return Objects.equals(name, other.name) && + this.preview() == other.preview() && tests.containsAll(other.tests) && other.tests.containsAll(tests) && Objects.equals(casing, other.casing) && Objects.equals(hatchFlags, other.hatchFlags); @@ -109,7 +145,14 @@ public boolean equals(Object o) { } public void save(CompoundTag tag) { - tag.put("preview", NbtUtils.writeBlockState(this.preview())); + if (name != null) { + tag.putString("name", name); + } + + BlockState preview = this.preview(); + if (preview != null) { + tag.put("preview", NbtUtils.writeBlockState(preview)); + } ListTag testsTag = new ListTag(); for (StructureMemberTest test : tests) { @@ -118,7 +161,9 @@ public void save(CompoundTag tag) { test.save(testTag); testsTag.add(testTag); } - tag.put("tests", testsTag); + if (!testsTag.isEmpty()) { + tag.put("tests", testsTag); + } if (casing != null) { tag.putString("casing", casing.key.toString()); @@ -130,13 +175,16 @@ public void save(CompoundTag tag) { } public static StructureMember from(CompoundTag tag) { - if (tag.isEmpty() || - !tag.contains("preview", Tag.TAG_COMPOUND) || - !tag.contains("tests", Tag.TAG_LIST)) { + if (tag.isEmpty()) { return null; } - Supplier preview = () -> NbtUtils.readBlockState(BuiltInRegistries.BLOCK.asLookup(), tag.getCompound("preview")); + String name = tag.contains("name", Tag.TAG_STRING) ? tag.getString("name") : null; + + Supplier preview = null; + if (tag.contains("preview", Tag.TAG_COMPOUND)) { + preview = () -> NbtUtils.readBlockState(BuiltInRegistries.BLOCK.asLookup(), tag.getCompound("preview")); + } ListTag testsTag = tag.getList("tests", Tag.TAG_COMPOUND); List tests = new ArrayList<>(); @@ -147,9 +195,6 @@ public static StructureMember from(CompoundTag tag) { tests.add(test); } } - if (tests.isEmpty()) { - return null; - } MachineCasing casing = null; if (tag.contains("casing", Tag.TAG_STRING)) { @@ -166,6 +211,6 @@ public static StructureMember from(CompoundTag tag) { hatchFlags = new HatchFlags(hatchFlagsValue); } - return new StructureMember(preview, tests, casing, hatchFlags); + return new StructureMember(name, preview, tests, casing, hatchFlags); } } diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java index 1bd560014..de26a0628 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java @@ -34,17 +34,21 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; +import net.neoforged.neoforge.network.codec.NeoForgeStreamCodecs; -public record StructureUpdateMemberPacket(BlockPos pos, StructureMemberMode mode, String inputPreview, String inputMembers, String inputCasing, +public record StructureUpdateMemberPacket(BlockPos pos, StructureMemberMode mode, String inputName, String inputPreview, String inputMembers, + String inputCasing, String inputFlags) implements BasePacket { - public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + public static final StreamCodec STREAM_CODEC = NeoForgeStreamCodecs.composite( BlockPos.STREAM_CODEC, StructureUpdateMemberPacket::pos, ByteBufCodecs.idMapper((i) -> StructureMemberMode.values()[i], Enum::ordinal), StructureUpdateMemberPacket::mode, ByteBufCodecs.STRING_UTF8, + StructureUpdateMemberPacket::inputName, + ByteBufCodecs.STRING_UTF8, StructureUpdateMemberPacket::inputPreview, ByteBufCodecs.STRING_UTF8, StructureUpdateMemberPacket::inputMembers, @@ -68,6 +72,7 @@ public void handle(Context ctx) { BlockEntity blockEntity = level.getBlockEntity(pos); if (blockEntity instanceof StructureMultiblockMemberBlockEntity member) { member.setMode(mode); + member.setInputName(inputName); member.setInputPreview(inputPreview); member.setInputMembers(inputMembers); member.setInputCasing(inputCasing); diff --git a/src/main/resources/assets/modern_industrialization/textures/block/structure_multiblock_member.png b/src/main/resources/assets/modern_industrialization/textures/block/structure_multiblock_member.png deleted file mode 100644 index 320350ad1c7aa0762e37a9e461140077be4b44a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 280 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc!L^<)jv*HQ$tGrI|IQydbL7LvpW$pl4Et5g zXQY{!8vmXDVhYEz6P~9VU%LCtH)cBh`T6^q@rDCAY@S-LwVQ9&?5W|IZ&!cl^!}p9 zTsN-jC@{`QQqy+^Sr=ygGNs-h8wI3_KkB`nGI&=$?RiXcJXJq{=L?A z<~u-PA?^vfho#tdnlnZZL}xT8^r zlWD$PJ=5hKKNJ`)Gn+B6BurZ5wTS1`uTu#;NsB)_GNdVRY-r$^FyG-ElPAMggNz$l z4XPIp_8vBWFe~vPLpkH7l`RaL!Z)-r+A#z-8}oE9o><2!&G4Du@ZN$diH2lGTONmn zz1#vk&DX!j8QQMdQ)0*QfQMP2!SfK$k)!SHj5^`5I}2G|Cke>2I8vV~B~)hrMfJ^RY_SwDu3~FA6q0&i#>wh{`>!tg8L;#E++%hS zJh+1A@@=#CjfeMZ>3>?N+w~`;Ise6pzpu;R-JAQ1VcW+U2BvRTtOW)IgQu&X%Q~lo FCIBM~k#qn6 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/modern_industrialization/textures/block/structure_multiblock_member_variable.png b/src/main/resources/assets/modern_industrialization/textures/block/structure_multiblock_member_variable.png new file mode 100644 index 0000000000000000000000000000000000000000..dbf00e5420b3dba7c726c339b852f4a4e10fce4c GIT binary patch literal 359 zcmV-t0hs=YP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!Tm<%*L0Qx1A-X*R*;IGPyym2@b18D#H&adaod;sZuyYz+Xy7K@4002ovPDHLk FV1jF2llK4s literal 0 HcmV?d00001 From c402aca5b714018b99e35657311b04e9358ac18f Mon Sep 17 00:00:00 2001 From: Swedz Date: Sun, 24 Nov 2024 07:37:53 -0500 Subject: [PATCH 33/89] Use "type" instead of "id" for structure member tests --- .../multiblocks/structure/member/StructureMember.java | 2 +- .../multiblocks/structure/member/StructureMemberTest.java | 6 +++--- .../structure/member/StructureMemberTestState.java | 2 +- .../structure/member/StructureMemberTestTag.java | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java index 2a9db98c7..77f14f3e4 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java @@ -157,7 +157,7 @@ public void save(CompoundTag tag) { ListTag testsTag = new ListTag(); for (StructureMemberTest test : tests) { CompoundTag testTag = new CompoundTag(); - testTag.putString("id", test.id()); + testTag.putString("type", test.typeId()); test.save(testTag); testsTag.add(testTag); } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTest.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTest.java index 6e3b1bf80..1ebed767c 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTest.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTest.java @@ -28,7 +28,7 @@ import net.minecraft.world.level.block.state.BlockState; public interface StructureMemberTest { - String id(); + String typeId(); boolean matchesState(BlockState state); @@ -37,8 +37,8 @@ public interface StructureMemberTest { void save(CompoundTag tag); static StructureMemberTest from(CompoundTag tag) { - if (tag.contains("id", Tag.TAG_STRING)) { - String id = tag.getString("id"); + if (tag.contains("type", Tag.TAG_STRING)) { + String id = tag.getString("type"); StructureMemberTest member = switch (id) { case "tag" -> new StructureMemberTestTag(); case "state" -> new StructureMemberTestState(); diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestState.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestState.java index 5042cffdb..2a5ac6465 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestState.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestState.java @@ -50,7 +50,7 @@ public BlockState blockState() { } @Override - public String id() { + public String typeId() { return "state"; } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestTag.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestTag.java index db05db286..0b278bbe9 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestTag.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestTag.java @@ -46,7 +46,7 @@ public TagKey blockTag() { } @Override - public String id() { + public String typeId() { return "tag"; } From 703af39098ae49a5dd23dc8aff3545b56c80886e Mon Sep 17 00:00:00 2001 From: Swedz Date: Sun, 24 Nov 2024 07:43:31 -0500 Subject: [PATCH 34/89] Move the controller and member structure blocks to their own packages --- .../blocks/structure/StructureMultiblockControllerBER.java | 2 ++ .../structure/StructureMultiblockControllerEditScreen.java | 6 +++--- .../gui/structure/StructureMultiblockMemberEditScreen.java | 4 ++-- .../aztech/modern_industrialization/proxy/ClientProxy.java | 4 ++-- src/main/java/aztech/modern_industrialization/MIBlock.java | 4 ++-- .../java/aztech/modern_industrialization/MIRegistries.java | 4 ++-- .../{ => controller}/StructureControllerBounds.java | 2 +- .../structure/{ => controller}/StructureControllerMode.java | 2 +- .../StructureMultiblockControllerBlock.java | 2 +- .../StructureMultiblockControllerBlockEntity.java | 3 ++- .../blocks/structure/{ => member}/StructureMemberMode.java | 2 +- .../{ => member}/StructureMultiblockMemberBlock.java | 2 +- .../{ => member}/StructureMultiblockMemberBlockEntity.java | 3 ++- .../machines/multiblocks/ShapeMatcher.java | 6 +++--- .../multiblocks/structure/MIStructureTemplateManager.java | 2 +- .../network/structure/StructureLoadControllerPacket.java | 2 +- .../network/structure/StructureSaveControllerPacket.java | 4 ++-- .../network/structure/StructureUpdateControllerPacket.java | 6 +++--- .../network/structure/StructureUpdateMemberPacket.java | 4 ++-- .../aztech/modern_industrialization/proxy/CommonProxy.java | 4 ++-- 20 files changed, 36 insertions(+), 32 deletions(-) rename src/main/java/aztech/modern_industrialization/blocks/structure/{ => controller}/StructureControllerBounds.java (97%) rename src/main/java/aztech/modern_industrialization/blocks/structure/{ => controller}/StructureControllerMode.java (96%) rename src/main/java/aztech/modern_industrialization/blocks/structure/{ => controller}/StructureMultiblockControllerBlock.java (98%) rename src/main/java/aztech/modern_industrialization/blocks/structure/{ => controller}/StructureMultiblockControllerBlockEntity.java (97%) rename src/main/java/aztech/modern_industrialization/blocks/structure/{ => member}/StructureMemberMode.java (97%) rename src/main/java/aztech/modern_industrialization/blocks/structure/{ => member}/StructureMultiblockMemberBlock.java (98%) rename src/main/java/aztech/modern_industrialization/blocks/structure/{ => member}/StructureMultiblockMemberBlockEntity.java (98%) diff --git a/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java b/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java index d4e8fe057..4cc9d88c1 100644 --- a/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java +++ b/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java @@ -23,6 +23,8 @@ */ package aztech.modern_industrialization.blocks.structure; +import aztech.modern_industrialization.blocks.structure.controller.StructureControllerBounds; +import aztech.modern_industrialization.blocks.structure.controller.StructureMultiblockControllerBlockEntity; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; import net.minecraft.client.renderer.LevelRenderer; diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java index 5019891f0..1c0b76de9 100644 --- a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java @@ -25,9 +25,9 @@ import aztech.modern_industrialization.MIBlock; import aztech.modern_industrialization.MIText; -import aztech.modern_industrialization.blocks.structure.StructureControllerBounds; -import aztech.modern_industrialization.blocks.structure.StructureControllerMode; -import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlockEntity; +import aztech.modern_industrialization.blocks.structure.controller.StructureControllerBounds; +import aztech.modern_industrialization.blocks.structure.controller.StructureControllerMode; +import aztech.modern_industrialization.blocks.structure.controller.StructureMultiblockControllerBlockEntity; import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.structure.MIStructureTemplateManager; import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockInputFormatters; diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java index dc4483d4f..9583fe545 100644 --- a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java @@ -25,8 +25,8 @@ import aztech.modern_industrialization.MIBlock; import aztech.modern_industrialization.MIText; -import aztech.modern_industrialization.blocks.structure.StructureMemberMode; -import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlockEntity; +import aztech.modern_industrialization.blocks.structure.member.StructureMemberMode; +import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlockEntity; import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.HatchFlags; import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockInputFormatters; diff --git a/src/client/java/aztech/modern_industrialization/proxy/ClientProxy.java b/src/client/java/aztech/modern_industrialization/proxy/ClientProxy.java index 504ee254d..dc058d712 100644 --- a/src/client/java/aztech/modern_industrialization/proxy/ClientProxy.java +++ b/src/client/java/aztech/modern_industrialization/proxy/ClientProxy.java @@ -30,8 +30,8 @@ import aztech.modern_industrialization.blocks.storage.tank.AbstractTankBlockEntity; import aztech.modern_industrialization.blocks.storage.tank.TankRenderer; import aztech.modern_industrialization.blocks.structure.StructureMultiblockBER; -import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlockEntity; -import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlockEntity; +import aztech.modern_industrialization.blocks.structure.controller.StructureMultiblockControllerBlockEntity; +import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlockEntity; import aztech.modern_industrialization.gui.structure.StructureMultiblockControllerEditScreen; import aztech.modern_industrialization.gui.structure.StructureMultiblockMemberEditScreen; import aztech.modern_industrialization.items.SteamDrillHooks; diff --git a/src/main/java/aztech/modern_industrialization/MIBlock.java b/src/main/java/aztech/modern_industrialization/MIBlock.java index 7a9f856a7..77de26df0 100644 --- a/src/main/java/aztech/modern_industrialization/MIBlock.java +++ b/src/main/java/aztech/modern_industrialization/MIBlock.java @@ -35,8 +35,8 @@ import aztech.modern_industrialization.blocks.storage.tank.TankBlock; import aztech.modern_industrialization.blocks.storage.tank.TankItem; import aztech.modern_industrialization.blocks.storage.tank.creativetank.CreativeTankBlockEntity; -import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlock; -import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlock; +import aztech.modern_industrialization.blocks.structure.controller.StructureMultiblockControllerBlock; +import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlock; import aztech.modern_industrialization.datagen.loot.MIBlockLoot; import aztech.modern_industrialization.datagen.model.BaseModelProvider; import aztech.modern_industrialization.definition.BlockDefinition; diff --git a/src/main/java/aztech/modern_industrialization/MIRegistries.java b/src/main/java/aztech/modern_industrialization/MIRegistries.java index 66d59c93a..47bf968fd 100644 --- a/src/main/java/aztech/modern_industrialization/MIRegistries.java +++ b/src/main/java/aztech/modern_industrialization/MIRegistries.java @@ -28,8 +28,8 @@ import aztech.modern_industrialization.blocks.forgehammer.ForgeHammerScreenHandler; import aztech.modern_industrialization.blocks.storage.barrel.CreativeBarrelBlockEntity; import aztech.modern_industrialization.blocks.storage.tank.creativetank.CreativeTankBlockEntity; -import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlockEntity; -import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlockEntity; +import aztech.modern_industrialization.blocks.structure.controller.StructureMultiblockControllerBlockEntity; +import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlockEntity; import aztech.modern_industrialization.compat.ae2.AECompatCondition; import aztech.modern_industrialization.machines.gui.MachineMenuCommon; import aztech.modern_industrialization.proxy.CommonProxy; diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureControllerBounds.java b/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureControllerBounds.java similarity index 97% rename from src/main/java/aztech/modern_industrialization/blocks/structure/StructureControllerBounds.java rename to src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureControllerBounds.java index d5d7e76bf..a04c0d1a7 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureControllerBounds.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureControllerBounds.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package aztech.modern_industrialization.blocks.structure; +package aztech.modern_industrialization.blocks.structure.controller; import com.mojang.serialization.Codec; import java.util.stream.IntStream; diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureControllerMode.java b/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureControllerMode.java similarity index 96% rename from src/main/java/aztech/modern_industrialization/blocks/structure/StructureControllerMode.java rename to src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureControllerMode.java index 76189283c..35dbfd1fe 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureControllerMode.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureControllerMode.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package aztech.modern_industrialization.blocks.structure; +package aztech.modern_industrialization.blocks.structure.controller; import java.util.Locale; import net.minecraft.network.chat.Component; diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlock.java b/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlock.java similarity index 98% rename from src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlock.java rename to src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlock.java index e9300e525..a20c1f885 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlock.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlock.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package aztech.modern_industrialization.blocks.structure; +package aztech.modern_industrialization.blocks.structure.controller; import aztech.modern_industrialization.proxy.CommonProxy; import com.mojang.serialization.MapCodec; diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlockEntity.java similarity index 97% rename from src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java rename to src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlockEntity.java index 867239162..5a58fad3c 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlockEntity.java @@ -21,11 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package aztech.modern_industrialization.blocks.structure; +package aztech.modern_industrialization.blocks.structure.controller; import aztech.modern_industrialization.MIBlock; import aztech.modern_industrialization.MIRegistries; import aztech.modern_industrialization.blocks.FastBlockEntity; +import aztech.modern_industrialization.blocks.structure.StructureMemberOverride; import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockInputFormatters; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMemberMode.java b/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMemberMode.java similarity index 97% rename from src/main/java/aztech/modern_industrialization/blocks/structure/StructureMemberMode.java rename to src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMemberMode.java index 2bfc77c2b..b53e3f3c8 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMemberMode.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMemberMode.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package aztech.modern_industrialization.blocks.structure; +package aztech.modern_industrialization.blocks.structure.member; import aztech.modern_industrialization.MIText; import java.util.Locale; diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlock.java b/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlock.java similarity index 98% rename from src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlock.java rename to src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlock.java index 511b105fd..1207d5fbb 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlock.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlock.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package aztech.modern_industrialization.blocks.structure; +package aztech.modern_industrialization.blocks.structure.member; import aztech.modern_industrialization.proxy.CommonProxy; import com.mojang.serialization.MapCodec; diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlockEntity.java similarity index 98% rename from src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java rename to src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlockEntity.java index b8d2d5501..15bfa47c8 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockMemberBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlockEntity.java @@ -21,11 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package aztech.modern_industrialization.blocks.structure; +package aztech.modern_industrialization.blocks.structure.member; import aztech.modern_industrialization.MIBlock; import aztech.modern_industrialization.MIRegistries; import aztech.modern_industrialization.blocks.FastBlockEntity; +import aztech.modern_industrialization.blocks.structure.StructureMemberOverride; import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.HatchFlags; import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockInputFormatters; diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java index 4974bdf71..fb97279b8 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java @@ -24,9 +24,9 @@ package aztech.modern_industrialization.machines.multiblocks; import aztech.modern_industrialization.MIBlock; -import aztech.modern_industrialization.blocks.structure.StructureMemberMode; -import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlock; -import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlockEntity; +import aztech.modern_industrialization.blocks.structure.member.StructureMemberMode; +import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlock; +import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlockEntity; import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockInputFormatters; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; import aztech.modern_industrialization.machines.multiblocks.world.ChunkEventListener; diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java index b5508dc2c..0198ad1cd 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java @@ -26,8 +26,8 @@ import static aztech.modern_industrialization.machines.multiblocks.ShapeMatcher.*; import aztech.modern_industrialization.MI; -import aztech.modern_industrialization.blocks.structure.StructureControllerBounds; import aztech.modern_industrialization.blocks.structure.StructureMemberOverride; +import aztech.modern_industrialization.blocks.structure.controller.StructureControllerBounds; import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.models.MachineCasings; import aztech.modern_industrialization.machines.multiblocks.ShapeTemplate; diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureLoadControllerPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureLoadControllerPacket.java index 6a3a8becb..33aace72a 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureLoadControllerPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureLoadControllerPacket.java @@ -24,7 +24,7 @@ package aztech.modern_industrialization.network.structure; import aztech.modern_industrialization.MIText; -import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlockEntity; +import aztech.modern_industrialization.blocks.structure.controller.StructureMultiblockControllerBlockEntity; import aztech.modern_industrialization.machines.multiblocks.ShapeMatcher; import aztech.modern_industrialization.machines.multiblocks.ShapeTemplate; import aztech.modern_industrialization.machines.multiblocks.structure.MIStructureTemplateManager; diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java index 3d20fab7c..cf1a7f61f 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java @@ -23,8 +23,8 @@ */ package aztech.modern_industrialization.network.structure; -import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlock; -import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlockEntity; +import aztech.modern_industrialization.blocks.structure.controller.StructureMultiblockControllerBlock; +import aztech.modern_industrialization.blocks.structure.controller.StructureMultiblockControllerBlockEntity; import aztech.modern_industrialization.machines.multiblocks.structure.MIStructureTemplateManager; import aztech.modern_industrialization.machines.multiblocks.structure.StructureResult; import aztech.modern_industrialization.network.BasePacket; diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java index 9e5ab5438..a14652531 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java @@ -23,9 +23,9 @@ */ package aztech.modern_industrialization.network.structure; -import aztech.modern_industrialization.blocks.structure.StructureControllerBounds; -import aztech.modern_industrialization.blocks.structure.StructureControllerMode; -import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlockEntity; +import aztech.modern_industrialization.blocks.structure.controller.StructureControllerBounds; +import aztech.modern_industrialization.blocks.structure.controller.StructureControllerMode; +import aztech.modern_industrialization.blocks.structure.controller.StructureMultiblockControllerBlockEntity; import aztech.modern_industrialization.network.BasePacket; import io.netty.buffer.ByteBuf; import net.minecraft.core.BlockPos; diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java index de26a0628..f7180581d 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java @@ -23,8 +23,8 @@ */ package aztech.modern_industrialization.network.structure; -import aztech.modern_industrialization.blocks.structure.StructureMemberMode; -import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlockEntity; +import aztech.modern_industrialization.blocks.structure.member.StructureMemberMode; +import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlockEntity; import aztech.modern_industrialization.network.BasePacket; import io.netty.buffer.ByteBuf; import net.minecraft.core.BlockPos; diff --git a/src/main/java/aztech/modern_industrialization/proxy/CommonProxy.java b/src/main/java/aztech/modern_industrialization/proxy/CommonProxy.java index 371d0ba4b..1035b42d5 100644 --- a/src/main/java/aztech/modern_industrialization/proxy/CommonProxy.java +++ b/src/main/java/aztech/modern_industrialization/proxy/CommonProxy.java @@ -25,8 +25,8 @@ import aztech.modern_industrialization.blocks.storage.barrel.BarrelBlockEntity; import aztech.modern_industrialization.blocks.storage.tank.AbstractTankBlockEntity; -import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBlockEntity; -import aztech.modern_industrialization.blocks.structure.StructureMultiblockMemberBlockEntity; +import aztech.modern_industrialization.blocks.structure.controller.StructureMultiblockControllerBlockEntity; +import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlockEntity; import aztech.modern_industrialization.machines.gui.MachineMenuCommon; import aztech.modern_industrialization.network.BasePacket; import aztech.modern_industrialization.network.structure.StructureMisconfiguredBlocksPacket; From d7dd7ad4d5cbb83e76549d0c3c2243713a62a9b8 Mon Sep 17 00:00:00 2001 From: Swedz Date: Sun, 24 Nov 2024 09:12:27 -0500 Subject: [PATCH 35/89] Improve wording on variable member mode --- .../resources/assets/modern_industrialization/lang/en_us.json | 2 +- src/main/java/aztech/modern_industrialization/MIText.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/generated/resources/assets/modern_industrialization/lang/en_us.json b/src/generated/resources/assets/modern_industrialization/lang/en_us.json index 33951588d..7cbacf350 100644 --- a/src/generated/resources/assets/modern_industrialization/lang/en_us.json +++ b/src/generated/resources/assets/modern_industrialization/lang/en_us.json @@ -1703,7 +1703,7 @@ "text.modern_industrialization.StructureMultiblockMemberModeHatch": "Hatch", "text.modern_industrialization.StructureMultiblockMemberModeInfoHatch": "Hatch Mode - Include hatches", "text.modern_industrialization.StructureMultiblockMemberModeInfoSimple": "Simple Mode - Just a block", - "text.modern_industrialization.StructureMultiblockMemberModeInfoVariable": "Variable Mode - Filled in at runtime", + "text.modern_industrialization.StructureMultiblockMemberModeInfoVariable": "Variable Mode - Filled in at startup", "text.modern_industrialization.StructureMultiblockMemberModeSimple": "Simple", "text.modern_industrialization.StructureMultiblockMemberModeVariable": "Variable", "text.modern_industrialization.StructureMultiblockMemberName": "Member Name", diff --git a/src/main/java/aztech/modern_industrialization/MIText.java b/src/main/java/aztech/modern_industrialization/MIText.java index ff5c4387b..cba6e3f75 100644 --- a/src/main/java/aztech/modern_industrialization/MIText.java +++ b/src/main/java/aztech/modern_industrialization/MIText.java @@ -257,7 +257,7 @@ public enum MIText { StructureMultiblockMemberModeVariable("Variable"), StructureMultiblockMemberModeInfoSimple("Simple Mode - Just a block"), StructureMultiblockMemberModeInfoHatch("Hatch Mode - Include hatches"), - StructureMultiblockMemberModeInfoVariable("Variable Mode - Filled in at runtime"), + StructureMultiblockMemberModeInfoVariable("Variable Mode - Filled in at startup"), StructureMultiblockStructureName("Structure Name"), StructureMultiblockLoadTooltip("Hold SHIFT to place actual blocks instead of structure blocks."), StructureMultiblockLoadFailInvalidId("Failed to place the structure. No id was provided."), From 36ad2025374022cc714af14b19ba958ac9ce5a9d Mon Sep 17 00:00:00 2001 From: Swedz Date: Sun, 24 Nov 2024 09:15:18 -0500 Subject: [PATCH 36/89] Clean up structure member internals --- .../StructureMultiblockMemberEditScreen.java | 2 +- .../StructureMultiblockMemberBlockEntity.java | 2 +- .../machines/multiblocks/ShapeMatcher.java | 50 +---- .../machines/multiblocks/ShapeTemplate.java | 12 +- .../structure/MIStructureTemplateManager.java | 6 +- .../StructureMultiblockInputFormatters.java | 14 +- .../member/HatchStructureMember.java | 136 ++++++++++++ .../member/SimpleStructureMember.java | 172 +++++++++++++++ .../structure/member/StructureMember.java | 201 ++++-------------- .../member/VariableStructureMember.java | 118 ++++++++++ .../StateStructureMemberTest.java} | 25 ++- .../{ => test}/StructureMemberTest.java | 34 +-- .../TagStructureMemberTest.java} | 25 ++- 13 files changed, 554 insertions(+), 243 deletions(-) create mode 100644 src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java create mode 100644 src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java create mode 100644 src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/VariableStructureMember.java rename src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/{StructureMemberTestState.java => test/StateStructureMemberTest.java} (77%) rename src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/{ => test}/StructureMemberTest.java (67%) rename src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/{StructureMemberTestTag.java => test/TagStructureMemberTest.java} (77%) diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java index 9583fe545..781a6fe65 100644 --- a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java @@ -30,7 +30,7 @@ import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.HatchFlags; import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockInputFormatters; -import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMemberTest; +import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StructureMemberTest; import aztech.modern_industrialization.network.structure.StructureUpdateMemberPacket; import com.google.common.collect.ImmutableList; import com.mojang.blaze3d.platform.InputConstants; diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlockEntity.java index 15bfa47c8..34b3955ee 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlockEntity.java @@ -31,7 +31,7 @@ import aztech.modern_industrialization.machines.multiblocks.HatchFlags; import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockInputFormatters; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; -import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMemberTest; +import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StructureMemberTest; import java.util.List; import java.util.Locale; import java.util.Objects; diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java index fb97279b8..95b4b8ef8 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java @@ -23,11 +23,7 @@ */ package aztech.modern_industrialization.machines.multiblocks; -import aztech.modern_industrialization.MIBlock; -import aztech.modern_industrialization.blocks.structure.member.StructureMemberMode; -import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlock; -import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlockEntity; -import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockInputFormatters; +import aztech.modern_industrialization.blocks.FastBlockEntity; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; import aztech.modern_industrialization.machines.multiblocks.world.ChunkEventListener; import aztech.modern_industrialization.machines.multiblocks.world.ChunkEventListeners; @@ -256,40 +252,16 @@ public int buildMultiblock(Level level, boolean structureBlocks) { BlockPos pos = entry.getKey(); var current = level.getBlockState(pos); if (entry.getValue() instanceof StructureMember member) { - // TODO SWEDZ: there has gotta be a better way to do this - boolean hasName = member.name() != null && !member.name().isEmpty(); - boolean hasMultipleTests = member.tests().size() > 1; - boolean hasHatchFlags = member.casing() != null && member.hatchFlags() != null && member.hatchFlags().flags != 0; - - if (structureBlocks || hasName) { - if (hasName || hasMultipleTests || hasHatchFlags) { - BlockState state = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.asBlock().defaultBlockState(); - StructureMultiblockMemberBlockEntity be = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.get().newBlockEntity(pos, state); - if (hasName) { - state = state.setValue(StructureMultiblockMemberBlock.MODE, StructureMemberMode.VARIABLE); - be.setMode(StructureMemberMode.VARIABLE); - be.setInputName(member.name()); - } - if (hasMultipleTests || hasHatchFlags) { - be.setInputPreview(StructureMultiblockInputFormatters.preview(member.preview())); - be.setInputMembers(StructureMultiblockInputFormatters.members(member.tests())); - if (hasHatchFlags) { - state = state.setValue(StructureMultiblockMemberBlock.MODE, StructureMemberMode.HATCH); - be.setMode(StructureMemberMode.HATCH); - be.setInputCasing(StructureMultiblockInputFormatters.casing(member.casing())); - be.setInputFlags(StructureMultiblockInputFormatters.hatchFlags(member.hatchFlags())); - } else { - state = state.setValue(StructureMultiblockMemberBlock.MODE, StructureMemberMode.SIMPLE); - be.setMode(StructureMemberMode.SIMPLE); - } - } - level.setBlockAndUpdate(pos, state); - level.setBlockEntity(be); - be.setChanged(); - be.sync(); - setBlocks++; - continue; - } + var optionalStructureBlock = member.asStructureBlock(pos, structureBlocks); + if (optionalStructureBlock.isPresent()) { + BlockState state = optionalStructureBlock.get().getFirst(); + FastBlockEntity be = optionalStructureBlock.get().getSecond(); + level.setBlockAndUpdate(pos, state); + level.setBlockEntity(be); + be.setChanged(); + be.sync(); + setBlocks++; + continue; } } if (!entry.getValue().matchesState(current)) { diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java index 1c4457570..28816d4f6 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java @@ -25,7 +25,7 @@ import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.structure.MIStructureTemplateManager; -import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; +import aztech.modern_industrialization.machines.multiblocks.structure.member.VariableStructureMember; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -221,7 +221,7 @@ public Structure replace(String name, SimpleMember member, @Nullable HatchFlags List positions = new ArrayList<>(); for (var entry : template.simpleMembers.entrySet()) { SimpleMember other = entry.getValue(); - if (other instanceof StructureMember structureMember && Objects.equals(name, structureMember.name())) { + if (other instanceof VariableStructureMember structureMember && Objects.equals(name, structureMember.name())) { positions.add(entry.getKey()); } } @@ -243,11 +243,9 @@ public Structure replace(String name, SimpleMember member) { public ShapeTemplate build() { for (SimpleMember member : template.simpleMembers.values()) { - if (member instanceof StructureMember structureMember) { - if (structureMember.name() != null) { - throw new IllegalArgumentException( - "Tried to build structure template without replacing member with the name \"" + structureMember.name() + "\""); - } + if (member instanceof VariableStructureMember structureMember) { + throw new IllegalArgumentException( + "Tried to build structure template without replacing member with the name \"" + structureMember.name() + "\""); } } return template; diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java index 0198ad1cd..2e50cc666 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java @@ -31,6 +31,7 @@ import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.models.MachineCasings; import aztech.modern_industrialization.machines.multiblocks.ShapeTemplate; +import aztech.modern_industrialization.machines.multiblocks.structure.member.HatchStructureMember; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; import java.io.IOException; import java.io.InputStream; @@ -153,10 +154,11 @@ public static StructureResult fromWorld(ResourceLocation id, Level level, } if (member != null) { - if (member.hatchFlags() != null) { + if (member instanceof HatchStructureMember hatch && hatch.hatchFlags() != null) { hatchBlocks.add(pos.immutable()); } CompoundTag memberTag = new CompoundTag(); + memberTag.putString("type", member.typeId()); member.save(memberTag); if (!members.contains(member)) { members.add(member); @@ -210,7 +212,7 @@ private static ShapeTemplate deserialize(CompoundTag tag) { if (blockTag.contains("member_index", Tag.TAG_INT)) { int memberIndex = blockTag.getInt("member_index"); StructureMember member = StructureMember.from(members.getCompound(memberIndex)); - builder.add(pos.getX(), pos.getY(), pos.getZ(), member, member.hatchFlags()); + builder.add(pos.getX(), pos.getY(), pos.getZ(), member, member instanceof HatchStructureMember hatch ? hatch.hatchFlags() : null); } } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockInputFormatters.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockInputFormatters.java index 5b3a0e464..b11b85730 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockInputFormatters.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockInputFormatters.java @@ -28,9 +28,9 @@ import aztech.modern_industrialization.machines.models.MachineCasings; import aztech.modern_industrialization.machines.multiblocks.HatchFlags; import aztech.modern_industrialization.machines.multiblocks.HatchType; -import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMemberTest; -import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMemberTestState; -import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMemberTestTag; +import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StateStructureMemberTest; +import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StructureMemberTest; +import aztech.modern_industrialization.machines.multiblocks.structure.member.test.TagStructureMemberTest; import com.mojang.brigadier.exceptions.CommandSyntaxException; import java.util.ArrayList; import java.util.List; @@ -110,11 +110,11 @@ public static List members(String input) { return null; } var tag = BlockTags.create(tagId); - members.add(new StructureMemberTestTag(tag)); + members.add(new TagStructureMemberTest(tag)); } else { try { var blockResult = BlockStateParser.parseForBlock(registry, part, true); - members.add(new StructureMemberTestState(blockResult::blockState)); + members.add(new StateStructureMemberTest(blockResult::blockState)); } catch (CommandSyntaxException ignored) { return null; } @@ -131,12 +131,12 @@ public static String members(List members) { StringBuilder string = new StringBuilder(); for (StructureMemberTest test : members) { - if (test instanceof StructureMemberTestTag testTag) { + if (test instanceof TagStructureMemberTest testTag) { if (!string.isEmpty()) { string.append(";"); } string.append("#").append(testTag.blockTag().location()); - } else if (test instanceof StructureMemberTestState stateTest) { + } else if (test instanceof StateStructureMemberTest stateTest) { if (!string.isEmpty()) { string.append(";"); } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java new file mode 100644 index 000000000..73c3e618c --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java @@ -0,0 +1,136 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.machines.multiblocks.structure.member; + +import aztech.modern_industrialization.MIBlock; +import aztech.modern_industrialization.blocks.FastBlockEntity; +import aztech.modern_industrialization.blocks.structure.member.StructureMemberMode; +import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlock; +import aztech.modern_industrialization.machines.models.MachineCasing; +import aztech.modern_industrialization.machines.models.MachineCasings; +import aztech.modern_industrialization.machines.multiblocks.HatchFlags; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockInputFormatters; +import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StructureMemberTest; +import com.mojang.datafixers.util.Pair; +import java.util.List; +import java.util.Optional; +import java.util.function.Supplier; +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.Tag; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.block.state.BlockState; + +public class HatchStructureMember extends SimpleStructureMember { + protected MachineCasing casing; + protected HatchFlags hatchFlags; + + public HatchStructureMember(Supplier previewSupplier, List tests, MachineCasing casing, HatchFlags hatchFlags) { + super(previewSupplier, tests); + this.casing = casing; + this.hatchFlags = hatchFlags; + } + + public HatchStructureMember() { + } + + public MachineCasing casing() { + assertLoaded(); + return casing; + } + + public HatchFlags hatchFlags() { + assertLoaded(); + return hatchFlags; + } + + @Override + public String typeId() { + return "hatch"; + } + + @Override + public boolean isLoaded() { + return super.isLoaded() && casing != null && hatchFlags != null; + } + + @Override + public void load(CompoundTag tag) { + super.load(tag); + + if (!tag.contains("casing", Tag.TAG_STRING) || + !tag.contains("hatch_flags", Tag.TAG_INT)) { + throw new IllegalArgumentException("Invalid structure member format for type \"" + typeId() + "\": " + tag); + } + + ResourceLocation casingId = ResourceLocation.tryParse(tag.getString("casing")); + if (casingId == null || !MachineCasings.registeredCasings.containsKey(casingId)) { + throw new IllegalArgumentException("Invalid structure member format for type \"" + typeId() + "\": " + tag); + } + casing = MachineCasings.get(casingId); + + int hatchFlagsValue = tag.getInt("hatch_flags"); + hatchFlags = hatchFlagsValue == 0 ? HatchFlags.NO_HATCH : new HatchFlags(hatchFlagsValue); + } + + @Override + public void save(CompoundTag tag) { + super.save(tag); + + tag.putString("casing", casing.key.toString()); + + tag.putInt("hatch_flags", hatchFlags.flags); + } + + @Override + public Optional> asStructureBlock(BlockPos pos, boolean attempt) { + assertLoaded(); + + if (attempt) { + var state = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.asBlock().defaultBlockState(); + state = state.setValue(StructureMultiblockMemberBlock.MODE, StructureMemberMode.HATCH); + var be = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.get().newBlockEntity(pos, state); + be.setInputPreview(StructureMultiblockInputFormatters.preview(getPreviewState())); + be.setInputMembers(StructureMultiblockInputFormatters.members(tests)); + be.setInputCasing(StructureMultiblockInputFormatters.casing(casing)); + be.setInputFlags(StructureMultiblockInputFormatters.hatchFlags(hatchFlags)); + return Optional.of(Pair.of(state, be)); + } + + return Optional.empty(); + } + + @Override + public boolean equals(Object o) { + assertLoaded(); + if (o instanceof HatchStructureMember other && this.getClass() == other.getClass()) { + other.assertLoaded(); + return this.getPreviewState() == other.getPreviewState() && + tests.containsAll(other.tests) && other.tests.containsAll(tests) && + casing.equals(other.casing) && + hatchFlags.equals(other.hatchFlags); + } + return false; + } +} diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java new file mode 100644 index 000000000..67861e714 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java @@ -0,0 +1,172 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.machines.multiblocks.structure.member; + +import aztech.modern_industrialization.MIBlock; +import aztech.modern_industrialization.blocks.FastBlockEntity; +import aztech.modern_industrialization.blocks.structure.member.StructureMemberMode; +import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlock; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockInputFormatters; +import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StructureMemberTest; +import com.mojang.datafixers.util.Pair; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Supplier; +import net.minecraft.core.BlockPos; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.nbt.Tag; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; + +public class SimpleStructureMember implements StructureMember { + protected Supplier previewSupplier; + protected List tests; + + private BlockState preview; + + public SimpleStructureMember(Supplier previewSupplier, List tests) { + Objects.requireNonNull(previewSupplier); + Objects.requireNonNull(tests); + this.previewSupplier = previewSupplier; + this.tests = tests; + } + + public SimpleStructureMember() { + } + + public List tests() { + if (!isLoaded()) { + throw new IllegalStateException("Member is not loaded"); + } + return Collections.unmodifiableList(tests); + } + + @Override + public String typeId() { + return "simple"; + } + + @Override + public boolean isLoaded() { + return previewSupplier != null && tests != null; + } + + @Override + public void load(CompoundTag tag) { + Objects.requireNonNull(tag); + if (!tag.contains("preview", CompoundTag.TAG_COMPOUND) || + !tag.contains("tests", CompoundTag.TAG_LIST)) { + throw new IllegalArgumentException("Invalid structure member format for type \"" + typeId() + "\": " + tag); + } + + previewSupplier = () -> NbtUtils.readBlockState(BuiltInRegistries.BLOCK.asLookup(), tag.getCompound("preview")); + + ListTag testsTag = tag.getList("tests", Tag.TAG_COMPOUND); + if (testsTag.isEmpty()) { + throw new IllegalArgumentException("Member cannot have no tests: " + tag); + } + tests = new ArrayList<>(); + for (int i = 0; i < testsTag.size(); i++) { + CompoundTag testTag = testsTag.getCompound(i); + StructureMemberTest test = StructureMemberTest.from(testTag); + if (test != null) { + tests.add(test); + } + } + } + + @Override + public void save(CompoundTag tag) { + Objects.requireNonNull(tag); + StructureMember.super.save(tag); + + tag.put("preview", NbtUtils.writeBlockState(getPreviewState())); + + ListTag testsTag = new ListTag(); + for (StructureMemberTest test : tests) { + CompoundTag testTag = new CompoundTag(); + testTag.putString("type", test.typeId()); + test.save(testTag); + testsTag.add(testTag); + } + if (testsTag.isEmpty()) { + throw new IllegalArgumentException("Member cannot have no tests"); + } + tag.put("tests", testsTag); + } + + @Override + public Optional> asStructureBlock(BlockPos pos, boolean attempt) { + assertLoaded(); + + if (attempt && tests.size() > 1) { + var state = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.asBlock().defaultBlockState(); + state = state.setValue(StructureMultiblockMemberBlock.MODE, StructureMemberMode.SIMPLE); + var be = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.get().newBlockEntity(pos, state); + be.setInputPreview(StructureMultiblockInputFormatters.preview(getPreviewState())); + be.setInputMembers(StructureMultiblockInputFormatters.members(tests)); + return Optional.of(Pair.of(state, be)); + } + + return Optional.empty(); + } + + @Override + public boolean matchesState(BlockState state) { + for (StructureMemberTest test : tests) { + if (test.matchesState(state)) { + return true; + } + } + return false; + } + + @Override + public BlockState getPreviewState() { + if (preview == null) { + preview = previewSupplier.get(); + if (preview == null) { + preview = Blocks.AIR.defaultBlockState(); + } + } + return preview; + } + + @Override + public boolean equals(Object o) { + assertLoaded(); + if (o instanceof SimpleStructureMember other && this.getClass() == other.getClass()) { + other.assertLoaded(); + return this.getPreviewState() == other.getPreviewState() && + tests.containsAll(other.tests) && other.tests.containsAll(tests); + } + return false; + } +} diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java index 77f14f3e4..bc31086f3 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java @@ -23,194 +23,67 @@ */ package aztech.modern_industrialization.machines.multiblocks.structure.member; +import aztech.modern_industrialization.blocks.FastBlockEntity; import aztech.modern_industrialization.machines.models.MachineCasing; -import aztech.modern_industrialization.machines.models.MachineCasings; import aztech.modern_industrialization.machines.multiblocks.HatchFlags; import aztech.modern_industrialization.machines.multiblocks.SimpleMember; -import java.util.ArrayList; -import java.util.Collections; +import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StateStructureMemberTest; +import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StructureMemberTest; +import com.mojang.datafixers.util.Pair; import java.util.List; -import java.util.Objects; +import java.util.Optional; import java.util.function.Supplier; -import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; -import net.minecraft.nbt.NbtUtils; -import net.minecraft.nbt.Tag; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; -import org.jetbrains.annotations.Nullable; -public final class StructureMember implements SimpleMember { - private final String name; - private final Supplier previewSupplier; - private final List tests; - private final MachineCasing casing; - private final HatchFlags hatchFlags; +public interface StructureMember extends SimpleMember { + String typeId(); - private BlockState preview; + boolean isLoaded(); - private StructureMember(@Nullable String name, @Nullable Supplier preview, List tests, - @Nullable MachineCasing casing, @Nullable HatchFlags hatchFlags) { - this.name = name; - this.previewSupplier = preview; - this.tests = tests; - this.casing = casing; - this.hatchFlags = hatchFlags; - } - - public static StructureMember literal(Supplier state) { - return new StructureMember(null, state, List.of(new StructureMemberTestState(state)), null, null); - } - - public static StructureMember variable(String name) { - Objects.requireNonNull(name); - return new StructureMember(name, null, List.of(), null, null); - } - - public static StructureMember simple(Supplier preview, List tests) { - Objects.requireNonNull(preview); - Objects.requireNonNull(tests); - return new StructureMember(null, preview, tests, null, null); - } - - public static StructureMember hatch(Supplier preview, List tests, MachineCasing casing, HatchFlags hatchFlags) { - Objects.requireNonNull(preview); - Objects.requireNonNull(tests); - Objects.requireNonNull(casing); - Objects.requireNonNull(hatchFlags); - return new StructureMember(null, preview, tests, casing, hatchFlags); - } - - public String name() { - return name; - } - - public BlockState preview() { - if (previewSupplier == null) { - return null; - } - if (preview == null) { - preview = previewSupplier.get(); + default void assertLoaded() { + if (!isLoaded()) { + throw new IllegalStateException("Member is not loaded"); } - return preview; } - public List tests() { - return Collections.unmodifiableList(tests); - } + void load(CompoundTag tag); - @Nullable - public MachineCasing casing() { - return casing; + default void save(CompoundTag tag) { + assertLoaded(); } - @Nullable - public HatchFlags hatchFlags() { - return hatchFlags; - } + Optional> asStructureBlock(BlockPos pos, boolean attempt); - @Override - public boolean matchesState(BlockState state) { - if (name != null) { - throw new IllegalStateException("Tried to use a structure member with a name without replacing it in the template."); - } - for (StructureMemberTest test : tests) { - if (test.matchesState(state)) { - return true; - } - } - return false; + static SimpleStructureMember simple(Supplier preview, List tests) { + return new SimpleStructureMember(preview, tests); } - @Override - public BlockState getPreviewState() { - if (name != null) { - throw new IllegalStateException("Tried to use a structure member with a name without replacing it in the template."); - } - return this.preview() == null ? Blocks.AIR.defaultBlockState() : this.preview(); + static SimpleStructureMember literal(Supplier blockState) { + return simple(blockState, List.of(new StateStructureMemberTest(blockState))); } - @Override - public boolean equals(Object o) { - if (o instanceof StructureMember other) { - return Objects.equals(name, other.name) && - this.preview() == other.preview() && - tests.containsAll(other.tests) && other.tests.containsAll(tests) && - Objects.equals(casing, other.casing) && - Objects.equals(hatchFlags, other.hatchFlags); - } - return false; + static HatchStructureMember hatch(Supplier preview, List tests, MachineCasing casing, HatchFlags hatchFlags) { + return new HatchStructureMember(preview, tests, casing, hatchFlags); } - public void save(CompoundTag tag) { - if (name != null) { - tag.putString("name", name); - } - - BlockState preview = this.preview(); - if (preview != null) { - tag.put("preview", NbtUtils.writeBlockState(preview)); - } - - ListTag testsTag = new ListTag(); - for (StructureMemberTest test : tests) { - CompoundTag testTag = new CompoundTag(); - testTag.putString("type", test.typeId()); - test.save(testTag); - testsTag.add(testTag); - } - if (!testsTag.isEmpty()) { - tag.put("tests", testsTag); - } - - if (casing != null) { - tag.putString("casing", casing.key.toString()); - } - - if (hatchFlags != null) { - tag.putInt("hatch_flags", hatchFlags.flags); - } + static VariableStructureMember variable(String name) { + return new VariableStructureMember(name); } - public static StructureMember from(CompoundTag tag) { - if (tag.isEmpty()) { - return null; - } - - String name = tag.contains("name", Tag.TAG_STRING) ? tag.getString("name") : null; - - Supplier preview = null; - if (tag.contains("preview", Tag.TAG_COMPOUND)) { - preview = () -> NbtUtils.readBlockState(BuiltInRegistries.BLOCK.asLookup(), tag.getCompound("preview")); - } - - ListTag testsTag = tag.getList("tests", Tag.TAG_COMPOUND); - List tests = new ArrayList<>(); - for (int i = 0; i < testsTag.size(); i++) { - CompoundTag testTag = testsTag.getCompound(i); - StructureMemberTest test = StructureMemberTest.from(testTag); - if (test != null) { - tests.add(test); - } - } - - MachineCasing casing = null; - if (tag.contains("casing", Tag.TAG_STRING)) { - ResourceLocation casingId = ResourceLocation.tryParse(tag.getString("casing")); - if (casingId == null || !MachineCasings.registeredCasings.containsKey(casingId)) { - return null; - } - casing = MachineCasings.get(casingId); - } - - int hatchFlagsValue = tag.getInt("hatch_flags"); - HatchFlags hatchFlags = null; - if (hatchFlagsValue != 0) { - hatchFlags = new HatchFlags(hatchFlagsValue); - } - - return new StructureMember(name, preview, tests, casing, hatchFlags); + static StructureMember from(CompoundTag tag) { + if (!tag.contains("type", CompoundTag.TAG_STRING)) { + throw new IllegalArgumentException("Invalid structure member format: " + tag); + } + String type = tag.getString("type"); + StructureMember member = switch (type) { + case "simple" -> new SimpleStructureMember(); + case "hatch" -> new HatchStructureMember(); + case "variable" -> new VariableStructureMember(); + default -> throw new IllegalStateException("Unexpected value: " + type); + }; + member.load(tag); + return member; } } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/VariableStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/VariableStructureMember.java new file mode 100644 index 000000000..63131ef6a --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/VariableStructureMember.java @@ -0,0 +1,118 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.machines.multiblocks.structure.member; + +import aztech.modern_industrialization.MIBlock; +import aztech.modern_industrialization.blocks.FastBlockEntity; +import aztech.modern_industrialization.blocks.structure.member.StructureMemberMode; +import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlock; +import com.mojang.datafixers.util.Pair; +import java.util.Objects; +import java.util.Optional; +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.Tag; +import net.minecraft.world.level.block.state.BlockState; + +public class VariableStructureMember implements StructureMember { + protected String name; + + public VariableStructureMember(String name) { + Objects.requireNonNull(name); + this.name = name; + } + + public VariableStructureMember() { + } + + public String name() { + if (!isLoaded()) { + throw new IllegalStateException("Member is not loaded"); + } + return name; + } + + @Override + public String typeId() { + return "variable"; + } + + @Override + public boolean isLoaded() { + return name != null; + } + + @Override + public void load(CompoundTag tag) { + Objects.requireNonNull(tag); + if (!tag.contains("name", Tag.TAG_STRING)) { + throw new IllegalArgumentException("Invalid structure member format for type \"" + typeId() + "\": " + tag); + } + + name = tag.getString("name"); + if (name.isEmpty()) { + throw new IllegalArgumentException("Invalid structure member format for type \"" + typeId() + "\": " + tag); + } + } + + @Override + public void save(CompoundTag tag) { + Objects.requireNonNull(tag); + StructureMember.super.save(tag); + + tag.putString("name", name); + } + + @Override + public Optional> asStructureBlock(BlockPos pos, boolean attempt) { + assertLoaded(); + + var state = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.asBlock().defaultBlockState(); + state = state.setValue(StructureMultiblockMemberBlock.MODE, StructureMemberMode.VARIABLE); + var be = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.get().newBlockEntity(pos, state); + be.setInputName(name); + + return Optional.of(Pair.of(state, be)); + } + + @Override + public boolean matchesState(BlockState state) { + throw new UnsupportedOperationException("Tried to use a variable structure member without replacing it in the template."); + } + + @Override + public BlockState getPreviewState() { + throw new UnsupportedOperationException("Tried to use a variable structure member without replacing it in the template."); + } + + @Override + public boolean equals(Object o) { + assertLoaded(); + if (o instanceof VariableStructureMember other && this.getClass() == other.getClass()) { + other.assertLoaded(); + return name.equals(other.name); + } + return false; + } +} diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestState.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StateStructureMemberTest.java similarity index 77% rename from src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestState.java rename to src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StateStructureMemberTest.java index 2a5ac6465..6b93fc213 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestState.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StateStructureMemberTest.java @@ -21,24 +21,26 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package aztech.modern_industrialization.machines.multiblocks.structure.member; +package aztech.modern_industrialization.machines.multiblocks.structure.member.test; +import java.util.Objects; import java.util.function.Supplier; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtUtils; +import net.minecraft.nbt.Tag; import net.minecraft.world.level.block.state.BlockState; -public class StructureMemberTestState implements StructureMemberTest { +public class StateStructureMemberTest implements StructureMemberTest { private Supplier blockStateSupplier; private BlockState blockState; - public StructureMemberTestState(Supplier blockState) { + public StateStructureMemberTest(Supplier blockState) { this.blockStateSupplier = blockState; } - public StructureMemberTestState() { + public StateStructureMemberTest() { this(null); } @@ -59,20 +61,33 @@ public boolean matchesState(BlockState state) { return this.blockState() == state; } + @Override + public boolean isLoaded() { + return blockStateSupplier != null; + } + @Override public void load(CompoundTag tag) { + Objects.requireNonNull(tag); + if (!tag.contains("state", Tag.TAG_COMPOUND)) { + throw new IllegalArgumentException("Invalid structure member test format for type \"" + typeId() + "\": " + tag); + } + blockStateSupplier = () -> NbtUtils.readBlockState(BuiltInRegistries.BLOCK.asLookup(), tag.getCompound("state")); blockState = null; } @Override public void save(CompoundTag tag) { + Objects.requireNonNull(tag); + StructureMemberTest.super.save(tag); + tag.put("state", NbtUtils.writeBlockState(this.blockState())); } @Override public boolean equals(Object o) { - if (o instanceof StructureMemberTestState other) { + if (o instanceof StateStructureMemberTest other) { return this.blockState() == other.blockState(); } return false; diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTest.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StructureMemberTest.java similarity index 67% rename from src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTest.java rename to src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StructureMemberTest.java index 1ebed767c..67ed69bf1 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTest.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StructureMemberTest.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package aztech.modern_industrialization.machines.multiblocks.structure.member; +package aztech.modern_industrialization.machines.multiblocks.structure.member.test; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; @@ -32,21 +32,31 @@ public interface StructureMemberTest { boolean matchesState(BlockState state); + boolean isLoaded(); + + default void assertLoaded() { + if (!isLoaded()) { + throw new IllegalStateException("Member test is not loaded"); + } + } + void load(CompoundTag tag); - void save(CompoundTag tag); + default void save(CompoundTag tag) { + assertLoaded(); + } static StructureMemberTest from(CompoundTag tag) { - if (tag.contains("type", Tag.TAG_STRING)) { - String id = tag.getString("type"); - StructureMemberTest member = switch (id) { - case "tag" -> new StructureMemberTestTag(); - case "state" -> new StructureMemberTestState(); - default -> throw new IllegalStateException("Unexpected value: " + id); - }; - member.load(tag); - return member; + if (!tag.contains("type", Tag.TAG_STRING)) { + throw new IllegalArgumentException("Invalid structure member test format: " + tag); } - return null; + String type = tag.getString("type"); + StructureMemberTest test = switch (type) { + case "tag" -> new TagStructureMemberTest(); + case "state" -> new StateStructureMemberTest(); + default -> throw new IllegalStateException("Unexpected value: " + type); + }; + test.load(tag); + return test; } } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestTag.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/TagStructureMemberTest.java similarity index 77% rename from src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestTag.java rename to src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/TagStructureMemberTest.java index 0b278bbe9..0371de411 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberTestTag.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/TagStructureMemberTest.java @@ -21,23 +21,25 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package aztech.modern_industrialization.machines.multiblocks.structure.member; +package aztech.modern_industrialization.machines.multiblocks.structure.member.test; +import java.util.Objects; import net.minecraft.core.registries.Registries; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.Tag; import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagKey; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; -public class StructureMemberTestTag implements StructureMemberTest { +public class TagStructureMemberTest implements StructureMemberTest { private TagKey blockTag; - public StructureMemberTestTag(TagKey blockTag) { + public TagStructureMemberTest(TagKey blockTag) { this.blockTag = blockTag; } - public StructureMemberTestTag() { + public TagStructureMemberTest() { this(null); } @@ -55,19 +57,32 @@ public boolean matchesState(BlockState state) { return blockTag != null && state.is(blockTag); } + @Override + public boolean isLoaded() { + return blockTag != null; + } + @Override public void load(CompoundTag tag) { + Objects.requireNonNull(tag); + if (!tag.contains("tag", Tag.TAG_STRING)) { + throw new IllegalArgumentException("Invalid structure member test format for type \"" + typeId() + "\": " + tag); + } + blockTag = TagKey.create(Registries.BLOCK, ResourceLocation.parse(tag.getString("tag"))); } @Override public void save(CompoundTag tag) { + Objects.requireNonNull(tag); + StructureMemberTest.super.save(tag); + tag.putString("tag", blockTag.location().toString()); } @Override public boolean equals(Object o) { - if (o instanceof StructureMemberTestTag other) { + if (o instanceof TagStructureMemberTest other) { return blockTag == other.blockTag || (blockTag != null && other.blockTag != null && blockTag.location().equals(other.blockTag.location())); } From 701d04c401dc1241d56b65d5d312b781e5af3869 Mon Sep 17 00:00:00 2001 From: Swedz Date: Sun, 24 Nov 2024 09:18:45 -0500 Subject: [PATCH 37/89] Use assertLoaded --- .../multiblocks/structure/member/SimpleStructureMember.java | 4 +--- .../multiblocks/structure/member/VariableStructureMember.java | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java index 67861e714..922526350 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java @@ -62,9 +62,7 @@ public SimpleStructureMember() { } public List tests() { - if (!isLoaded()) { - throw new IllegalStateException("Member is not loaded"); - } + assertLoaded(); return Collections.unmodifiableList(tests); } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/VariableStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/VariableStructureMember.java index 63131ef6a..fc22e3bc1 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/VariableStructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/VariableStructureMember.java @@ -47,9 +47,7 @@ public VariableStructureMember() { } public String name() { - if (!isLoaded()) { - throw new IllegalStateException("Member is not loaded"); - } + assertLoaded(); return name; } From 5b2e4f3e6ea05eff97e21cdec9ae5a37ecc46816 Mon Sep 17 00:00:00 2001 From: Swedz Date: Sun, 24 Nov 2024 18:48:44 -0500 Subject: [PATCH 38/89] Clean up structure member and member test internals to do proper loaded and null checks --- .../member/HatchStructureMember.java | 3 ++ .../member/SimpleStructureMember.java | 9 +++--- .../structure/member/StructureMember.java | 32 +++++++++++-------- .../member/VariableStructureMember.java | 7 ++-- .../member/test/StateStructureMemberTest.java | 16 +++++++--- .../member/test/StructureMemberTest.java | 23 +++++++------ .../member/test/TagStructureMemberTest.java | 15 +++++---- 7 files changed, 65 insertions(+), 40 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java index 73c3e618c..fa2bf264d 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java @@ -34,6 +34,7 @@ import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StructureMemberTest; import com.mojang.datafixers.util.Pair; import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.function.Supplier; import net.minecraft.core.BlockPos; @@ -48,6 +49,8 @@ public class HatchStructureMember extends SimpleStructureMember { public HatchStructureMember(Supplier previewSupplier, List tests, MachineCasing casing, HatchFlags hatchFlags) { super(previewSupplier, tests); + Objects.requireNonNull(casing); + Objects.requireNonNull(hatchFlags); this.casing = casing; this.hatchFlags = hatchFlags; } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java index 922526350..2e7ab2ee2 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java @@ -45,7 +45,7 @@ import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; -public class SimpleStructureMember implements StructureMember { +public class SimpleStructureMember extends StructureMember { protected Supplier previewSupplier; protected List tests; @@ -78,7 +78,7 @@ public boolean isLoaded() { @Override public void load(CompoundTag tag) { - Objects.requireNonNull(tag); + super.load(tag); if (!tag.contains("preview", CompoundTag.TAG_COMPOUND) || !tag.contains("tests", CompoundTag.TAG_LIST)) { throw new IllegalArgumentException("Invalid structure member format for type \"" + typeId() + "\": " + tag); @@ -102,8 +102,7 @@ public void load(CompoundTag tag) { @Override public void save(CompoundTag tag) { - Objects.requireNonNull(tag); - StructureMember.super.save(tag); + super.save(tag); tag.put("preview", NbtUtils.writeBlockState(getPreviewState())); @@ -138,6 +137,7 @@ public Optional> asStructureBlock(BlockPos pos @Override public boolean matchesState(BlockState state) { + assertLoaded(); for (StructureMemberTest test : tests) { if (test.matchesState(state)) { return true; @@ -148,6 +148,7 @@ public boolean matchesState(BlockState state) { @Override public BlockState getPreviewState() { + assertLoaded(); if (preview == null) { preview = previewSupplier.get(); if (preview == null) { diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java index bc31086f3..2923d4acc 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java @@ -31,48 +31,54 @@ import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StructureMemberTest; import com.mojang.datafixers.util.Pair; import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.function.Supplier; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.level.block.state.BlockState; -public interface StructureMember extends SimpleMember { - String typeId(); +public abstract class StructureMember implements SimpleMember { + public abstract String typeId(); - boolean isLoaded(); + public abstract boolean isLoaded(); - default void assertLoaded() { + protected final void assertLoaded() { if (!isLoaded()) { throw new IllegalStateException("Member is not loaded"); } } - void load(CompoundTag tag); + public void load(CompoundTag tag) { + Objects.requireNonNull(tag); + } - default void save(CompoundTag tag) { + public void save(CompoundTag tag) { + Objects.requireNonNull(tag); assertLoaded(); } - Optional> asStructureBlock(BlockPos pos, boolean attempt); + public abstract Optional> asStructureBlock(BlockPos pos, boolean attempt); - static SimpleStructureMember simple(Supplier preview, List tests) { + public static SimpleStructureMember simple(Supplier preview, List tests) { return new SimpleStructureMember(preview, tests); } - static SimpleStructureMember literal(Supplier blockState) { + public static SimpleStructureMember literal(Supplier blockState) { return simple(blockState, List.of(new StateStructureMemberTest(blockState))); } - static HatchStructureMember hatch(Supplier preview, List tests, MachineCasing casing, HatchFlags hatchFlags) { + public static HatchStructureMember hatch(Supplier preview, List tests, MachineCasing casing, + HatchFlags hatchFlags) { return new HatchStructureMember(preview, tests, casing, hatchFlags); } - static VariableStructureMember variable(String name) { + public static VariableStructureMember variable(String name) { return new VariableStructureMember(name); } - static StructureMember from(CompoundTag tag) { + public static StructureMember from(CompoundTag tag) { + Objects.requireNonNull(tag); if (!tag.contains("type", CompoundTag.TAG_STRING)) { throw new IllegalArgumentException("Invalid structure member format: " + tag); } @@ -81,7 +87,7 @@ static StructureMember from(CompoundTag tag) { case "simple" -> new SimpleStructureMember(); case "hatch" -> new HatchStructureMember(); case "variable" -> new VariableStructureMember(); - default -> throw new IllegalStateException("Unexpected value: " + type); + default -> throw new IllegalStateException("Unexpected type: " + type); }; member.load(tag); return member; diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/VariableStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/VariableStructureMember.java index fc22e3bc1..73a93aa01 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/VariableStructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/VariableStructureMember.java @@ -35,7 +35,7 @@ import net.minecraft.nbt.Tag; import net.minecraft.world.level.block.state.BlockState; -public class VariableStructureMember implements StructureMember { +public class VariableStructureMember extends StructureMember { protected String name; public VariableStructureMember(String name) { @@ -63,7 +63,7 @@ public boolean isLoaded() { @Override public void load(CompoundTag tag) { - Objects.requireNonNull(tag); + super.load(tag); if (!tag.contains("name", Tag.TAG_STRING)) { throw new IllegalArgumentException("Invalid structure member format for type \"" + typeId() + "\": " + tag); } @@ -76,8 +76,7 @@ public void load(CompoundTag tag) { @Override public void save(CompoundTag tag) { - Objects.requireNonNull(tag); - StructureMember.super.save(tag); + super.save(tag); tag.putString("name", name); } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StateStructureMemberTest.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StateStructureMemberTest.java index 6b93fc213..6fd5dfef1 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StateStructureMemberTest.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StateStructureMemberTest.java @@ -29,14 +29,16 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtUtils; import net.minecraft.nbt.Tag; +import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; -public class StateStructureMemberTest implements StructureMemberTest { +public class StateStructureMemberTest extends StructureMemberTest { private Supplier blockStateSupplier; private BlockState blockState; public StateStructureMemberTest(Supplier blockState) { + Objects.requireNonNull(blockState); this.blockStateSupplier = blockState; } @@ -45,8 +47,12 @@ public StateStructureMemberTest() { } public BlockState blockState() { + assertLoaded(); if (blockState == null) { blockState = blockStateSupplier.get(); + if (blockState == null) { + blockState = Blocks.AIR.defaultBlockState(); + } } return blockState; } @@ -58,6 +64,7 @@ public String typeId() { @Override public boolean matchesState(BlockState state) { + assertLoaded(); return this.blockState() == state; } @@ -68,7 +75,7 @@ public boolean isLoaded() { @Override public void load(CompoundTag tag) { - Objects.requireNonNull(tag); + super.load(tag); if (!tag.contains("state", Tag.TAG_COMPOUND)) { throw new IllegalArgumentException("Invalid structure member test format for type \"" + typeId() + "\": " + tag); } @@ -79,15 +86,16 @@ public void load(CompoundTag tag) { @Override public void save(CompoundTag tag) { - Objects.requireNonNull(tag); - StructureMemberTest.super.save(tag); + super.save(tag); tag.put("state", NbtUtils.writeBlockState(this.blockState())); } @Override public boolean equals(Object o) { + assertLoaded(); if (o instanceof StateStructureMemberTest other) { + other.assertLoaded(); return this.blockState() == other.blockState(); } return false; diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StructureMemberTest.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StructureMemberTest.java index 67ed69bf1..e35789b99 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StructureMemberTest.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StructureMemberTest.java @@ -23,30 +23,35 @@ */ package aztech.modern_industrialization.machines.multiblocks.structure.member.test; +import java.util.Objects; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; import net.minecraft.world.level.block.state.BlockState; -public interface StructureMemberTest { - String typeId(); +public abstract class StructureMemberTest { + public abstract String typeId(); - boolean matchesState(BlockState state); + public abstract boolean matchesState(BlockState state); - boolean isLoaded(); + public abstract boolean isLoaded(); - default void assertLoaded() { + protected final void assertLoaded() { if (!isLoaded()) { throw new IllegalStateException("Member test is not loaded"); } } - void load(CompoundTag tag); + public void load(CompoundTag tag) { + Objects.requireNonNull(tag); + } - default void save(CompoundTag tag) { + public void save(CompoundTag tag) { + Objects.requireNonNull(tag); assertLoaded(); } - static StructureMemberTest from(CompoundTag tag) { + public static StructureMemberTest from(CompoundTag tag) { + Objects.requireNonNull(tag); if (!tag.contains("type", Tag.TAG_STRING)) { throw new IllegalArgumentException("Invalid structure member test format: " + tag); } @@ -54,7 +59,7 @@ static StructureMemberTest from(CompoundTag tag) { StructureMemberTest test = switch (type) { case "tag" -> new TagStructureMemberTest(); case "state" -> new StateStructureMemberTest(); - default -> throw new IllegalStateException("Unexpected value: " + type); + default -> throw new IllegalStateException("Unexpected type: " + type); }; test.load(tag); return test; diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/TagStructureMemberTest.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/TagStructureMemberTest.java index 0371de411..0d436f9af 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/TagStructureMemberTest.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/TagStructureMemberTest.java @@ -32,10 +32,11 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; -public class TagStructureMemberTest implements StructureMemberTest { +public class TagStructureMemberTest extends StructureMemberTest { private TagKey blockTag; public TagStructureMemberTest(TagKey blockTag) { + Objects.requireNonNull(blockTag); this.blockTag = blockTag; } @@ -54,7 +55,8 @@ public String typeId() { @Override public boolean matchesState(BlockState state) { - return blockTag != null && state.is(blockTag); + assertLoaded(); + return state.is(blockTag); } @Override @@ -64,7 +66,7 @@ public boolean isLoaded() { @Override public void load(CompoundTag tag) { - Objects.requireNonNull(tag); + super.load(tag); if (!tag.contains("tag", Tag.TAG_STRING)) { throw new IllegalArgumentException("Invalid structure member test format for type \"" + typeId() + "\": " + tag); } @@ -74,17 +76,18 @@ public void load(CompoundTag tag) { @Override public void save(CompoundTag tag) { - Objects.requireNonNull(tag); - StructureMemberTest.super.save(tag); + super.save(tag); tag.putString("tag", blockTag.location().toString()); } @Override public boolean equals(Object o) { + assertLoaded(); if (o instanceof TagStructureMemberTest other) { + other.assertLoaded(); return blockTag == other.blockTag || - (blockTag != null && other.blockTag != null && blockTag.location().equals(other.blockTag.location())); + blockTag.location().equals(other.blockTag.location()); } return false; } From c4ced43d62d7ea9517d597c6da9e156307179083 Mon Sep 17 00:00:00 2001 From: Swedz Date: Sun, 24 Nov 2024 18:54:41 -0500 Subject: [PATCH 39/89] Dont set null values --- .../structure/member/test/StateStructureMemberTest.java | 1 - .../structure/member/test/TagStructureMemberTest.java | 1 - 2 files changed, 2 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StateStructureMemberTest.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StateStructureMemberTest.java index 6fd5dfef1..396da15b8 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StateStructureMemberTest.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StateStructureMemberTest.java @@ -43,7 +43,6 @@ public StateStructureMemberTest(Supplier blockState) { } public StateStructureMemberTest() { - this(null); } public BlockState blockState() { diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/TagStructureMemberTest.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/TagStructureMemberTest.java index 0d436f9af..8b558f496 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/TagStructureMemberTest.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/TagStructureMemberTest.java @@ -41,7 +41,6 @@ public TagStructureMemberTest(TagKey blockTag) { } public TagStructureMemberTest() { - this(null); } public TagKey blockTag() { From e6b118b01f2772a5196abd5211ca15d2f79cf3a6 Mon Sep 17 00:00:00 2001 From: Swedz Date: Sun, 24 Nov 2024 21:37:25 -0500 Subject: [PATCH 40/89] Remove structure test command --- .../debug/DebugCommands.java | 43 ------------------- 1 file changed, 43 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java b/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java index 31787c201..fc7bf7dc0 100644 --- a/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java +++ b/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java @@ -27,13 +27,9 @@ import static net.minecraft.commands.arguments.ResourceLocationArgument.*; import static net.minecraft.commands.arguments.coordinates.BlockPosArgument.*; -import aztech.modern_industrialization.MIBlock; import aztech.modern_industrialization.MIConfig; import aztech.modern_industrialization.machines.MachineBlockEntity; import aztech.modern_industrialization.machines.multiblocks.MultiblockMachineBlockEntity; -import aztech.modern_industrialization.machines.multiblocks.ShapeMatcher; -import aztech.modern_industrialization.machines.multiblocks.ShapeTemplate; -import aztech.modern_industrialization.machines.multiblocks.structure.MIStructureTemplateManager; import aztech.modern_industrialization.pipes.MIPipes; import aztech.modern_industrialization.pipes.api.PipeNetworkType; import aztech.modern_industrialization.pipes.impl.PipeNetworks; @@ -42,7 +38,6 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; import com.mojang.brigadier.suggestion.SuggestionProvider; -import java.util.function.Consumer; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.SharedSuggestionProvider; import net.minecraft.core.BlockPos; @@ -51,8 +46,6 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.event.RegisterCommandsEvent; @@ -103,13 +96,6 @@ public static void init() { return buildMultiblock(ctx.getSource(), getLoadedBlockPos(ctx, "controller_pos")); })) ) - .then(literal("structures") - .then(literal("test") - .then(argument("structure_id", id()) - .then(argument("controller_pos", blockPos()) - .executes(ctx -> { - return structuresTest(ctx.getSource(), getId(ctx, "structure_id"), getLoadedBlockPos(ctx, "controller_pos")); - }))))) ) ); }); @@ -194,33 +180,4 @@ private static int buildMultiblock(CommandSourceStack src, BlockPos controllerPo } return Command.SINGLE_SUCCESS; } - - private static int structures(CommandSourceStack src, ResourceLocation id, BlockPos controllerPos, Consumer action) { - BlockState controllerState = src.getLevel().getBlockState(controllerPos); - if (controllerState.is(MIBlock.STRUCTURE_MULTIBLOCK_CONTROLLER.get())) { - if (!MIStructureTemplateManager.exists(id)) { - src.sendFailure(Component.literal("Could not find structure with the id %s".formatted(id))); - return Command.SINGLE_SUCCESS; - } - ShapeTemplate shape = MIStructureTemplateManager.get(id); - ShapeMatcher matcher = new ShapeMatcher(src.getLevel(), controllerPos, controllerState.getValue(BlockStateProperties.HORIZONTAL_FACING), - shape); - action.accept(matcher); - } else { - src.sendFailure(Component.literal("Block at position %s is not a structure controller.".formatted(controllerPos.toShortString()))); - } - return Command.SINGLE_SUCCESS; - } - - private static int structuresTest(CommandSourceStack src, ResourceLocation id, BlockPos controllerPos) { - return structures(src, id, controllerPos, (matcher) -> { - matcher.rematch(src.getLevel()); - boolean success = matcher.isMatchSuccessful(); - matcher.unlinkHatches(); - src.sendSuccess( - () -> Component - .literal("Match test results for %s at position %s: %s".formatted(id, controllerPos.toShortString(), success)), - true); - }); - } } From 2152731d16c499090bf626a1559033d87ad1e047 Mon Sep 17 00:00:00 2001 From: Swedz Date: Sun, 24 Nov 2024 21:41:42 -0500 Subject: [PATCH 41/89] Check structure variable member name directly --- .../machines/multiblocks/ShapeTemplate.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java index 28816d4f6..339d3546e 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java @@ -31,7 +31,6 @@ import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Set; import net.minecraft.core.BlockPos; import net.minecraft.resources.ResourceLocation; @@ -221,7 +220,7 @@ public Structure replace(String name, SimpleMember member, @Nullable HatchFlags List positions = new ArrayList<>(); for (var entry : template.simpleMembers.entrySet()) { SimpleMember other = entry.getValue(); - if (other instanceof VariableStructureMember structureMember && Objects.equals(name, structureMember.name())) { + if (other instanceof VariableStructureMember structureMember && name.equals(structureMember.name())) { positions.add(entry.getKey()); } } From 3c7e6900aeab6ec93556f79cf89ec507bf68bdf5 Mon Sep 17 00:00:00 2001 From: Swedz Date: Sun, 24 Nov 2024 21:59:15 -0500 Subject: [PATCH 42/89] Let controllers save to the current manager so controllers can load new/modified structures immediately --- .../structure/MIStructureTemplateManager.java | 21 ++++++++++++++++--- .../structure/StructureResult.java | 3 ++- .../StructureSaveControllerPacket.java | 9 +++++--- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java index 2e50cc666..989143928 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java @@ -78,19 +78,28 @@ private static void assertLoaded() { public static boolean exists(ResourceLocation id) { assertLoaded(); + Objects.requireNonNull(id); return STRUCTURE_TEMPLATES.containsKey(id); } public static ShapeTemplate get(ResourceLocation id) { assertLoaded(); + Objects.requireNonNull(id); ShapeTemplate template = STRUCTURE_TEMPLATES.get(id); if (template != null) { return template; } else { - throw new IllegalArgumentException("Structure shape template \"" + id.toString() + "\" does not exist."); + throw new IllegalArgumentException("Structure shape template \"" + id + "\" does not exist."); } } + public static void register(ResourceLocation id, ShapeTemplate template) { + assertLoaded(); + Objects.requireNonNull(id); + Objects.requireNonNull(template); + STRUCTURE_TEMPLATES.put(id, template); + } + public static StructureResult fromWorld(ResourceLocation id, Level level, BlockPos controllerPos, Direction controllerDirection, MachineCasing hatchCasing, StructureControllerBounds bounds) { @@ -186,7 +195,13 @@ public static StructureResult fromWorld(ResourceLocation id, Level level, tag.put("members", membersTag); tag.put("blocks", blocksTag); - return new StructureResult.Success(id, tag); + ShapeTemplate template = deserialize(tag); + if (template == null) { + MI.LOGGER.error("Failed to deserialize structure tag immediately after it was created. Have you changed the deserialier or serializer?"); + return new StructureResult.Unknown(); + } + + return new StructureResult.Success(id, template, tag); } @Nullable @@ -292,7 +307,7 @@ private static void register(ResourceLocation id, Path path) { if (structureTag != null) { ShapeTemplate structure = deserialize(structureTag); if (structure != null) { - STRUCTURE_TEMPLATES.put(id, structure); + register(id, structure); } else { MI.LOGGER.error("Failed to load structure with id \"{}\"", id); } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureResult.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureResult.java index 5144a6243..3db6a9d01 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureResult.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureResult.java @@ -24,6 +24,7 @@ package aztech.modern_industrialization.machines.multiblocks.structure; import aztech.modern_industrialization.MIText; +import aztech.modern_industrialization.machines.multiblocks.ShapeTemplate; import aztech.modern_industrialization.network.structure.StructureMisconfiguredBlocksPacket; import java.util.ArrayList; import java.util.List; @@ -115,7 +116,7 @@ public Component text() { } } - record Success(ResourceLocation structureId, CompoundTag tag) implements StructureResult { + record Success(ResourceLocation structureId, ShapeTemplate template, CompoundTag tag) implements StructureResult { @Override public boolean isSuccess() { return true; diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java index cf1a7f61f..20ac59919 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java @@ -62,9 +62,12 @@ public void handle(Context ctx) { var result = MIStructureTemplateManager.fromWorld(id, level, pos, state.getValue(StructureMultiblockControllerBlock.FACING), controller.getCasing(), controller.getBounds()); - if (result instanceof StructureResult.Success success && - !MIStructureTemplateManager.save(id, success.tag())) { - result = new StructureResult.Unknown(); + if (result instanceof StructureResult.Success success) { + if (MIStructureTemplateManager.save(id, success.tag())) { + MIStructureTemplateManager.register(id, success.template()); + } else { + result = new StructureResult.Unknown(); + } } result.send(player); } From 2cbe7f42086c3e5bd7a00fae4eb32f3f405efe89 Mon Sep 17 00:00:00 2001 From: Swedz Date: Sun, 24 Nov 2024 22:16:36 -0500 Subject: [PATCH 43/89] Split simple and literal member types so they are loaded differently --- .../member/HatchStructureMember.java | 4 +- .../member/LiteralStructureMember.java | 52 +++++++++++++++++++ .../member/SimpleStructureMember.java | 10 ++-- .../structure/member/StructureMember.java | 8 +-- .../member/VariableStructureMember.java | 2 +- 5 files changed, 64 insertions(+), 12 deletions(-) create mode 100644 src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java index fa2bf264d..eea12fba0 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java @@ -107,10 +107,10 @@ public void save(CompoundTag tag) { } @Override - public Optional> asStructureBlock(BlockPos pos, boolean attempt) { + public Optional> asStructureBlock(BlockPos pos, boolean required) { assertLoaded(); - if (attempt) { + if (required) { var state = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.asBlock().defaultBlockState(); state = state.setValue(StructureMultiblockMemberBlock.MODE, StructureMemberMode.HATCH); var be = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.get().newBlockEntity(pos, state); diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java new file mode 100644 index 000000000..08bf74410 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java @@ -0,0 +1,52 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.machines.multiblocks.structure.member; + +import aztech.modern_industrialization.blocks.FastBlockEntity; +import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StateStructureMemberTest; +import com.mojang.datafixers.util.Pair; +import java.util.List; +import java.util.Optional; +import java.util.function.Supplier; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.state.BlockState; + +public class LiteralStructureMember extends SimpleStructureMember { + public LiteralStructureMember(Supplier blockState) { + super(blockState, List.of(new StateStructureMemberTest(blockState))); + } + + public LiteralStructureMember() { + } + + @Override + public String typeId() { + return "literal"; + } + + @Override + public Optional> asStructureBlock(BlockPos pos, boolean required) { + return Optional.empty(); + } +} diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java index 2e7ab2ee2..eb238324d 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java @@ -51,10 +51,10 @@ public class SimpleStructureMember extends StructureMember { private BlockState preview; - public SimpleStructureMember(Supplier previewSupplier, List tests) { - Objects.requireNonNull(previewSupplier); + public SimpleStructureMember(Supplier preview, List tests) { + Objects.requireNonNull(preview); Objects.requireNonNull(tests); - this.previewSupplier = previewSupplier; + this.previewSupplier = preview; this.tests = tests; } @@ -120,10 +120,10 @@ public void save(CompoundTag tag) { } @Override - public Optional> asStructureBlock(BlockPos pos, boolean attempt) { + public Optional> asStructureBlock(BlockPos pos, boolean required) { assertLoaded(); - if (attempt && tests.size() > 1) { + if (required) { var state = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.asBlock().defaultBlockState(); state = state.setValue(StructureMultiblockMemberBlock.MODE, StructureMemberMode.SIMPLE); var be = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.get().newBlockEntity(pos, state); diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java index 2923d4acc..6cbd1ad0f 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java @@ -27,7 +27,6 @@ import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.HatchFlags; import aztech.modern_industrialization.machines.multiblocks.SimpleMember; -import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StateStructureMemberTest; import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StructureMemberTest; import com.mojang.datafixers.util.Pair; import java.util.List; @@ -58,14 +57,14 @@ public void save(CompoundTag tag) { assertLoaded(); } - public abstract Optional> asStructureBlock(BlockPos pos, boolean attempt); + public abstract Optional> asStructureBlock(BlockPos pos, boolean required); public static SimpleStructureMember simple(Supplier preview, List tests) { return new SimpleStructureMember(preview, tests); } - public static SimpleStructureMember literal(Supplier blockState) { - return simple(blockState, List.of(new StateStructureMemberTest(blockState))); + public static LiteralStructureMember literal(Supplier blockState) { + return new LiteralStructureMember(blockState); } public static HatchStructureMember hatch(Supplier preview, List tests, MachineCasing casing, @@ -85,6 +84,7 @@ public static StructureMember from(CompoundTag tag) { String type = tag.getString("type"); StructureMember member = switch (type) { case "simple" -> new SimpleStructureMember(); + case "literal" -> new LiteralStructureMember(); case "hatch" -> new HatchStructureMember(); case "variable" -> new VariableStructureMember(); default -> throw new IllegalStateException("Unexpected type: " + type); diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/VariableStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/VariableStructureMember.java index 73a93aa01..9d49c4a1f 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/VariableStructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/VariableStructureMember.java @@ -82,7 +82,7 @@ public void save(CompoundTag tag) { } @Override - public Optional> asStructureBlock(BlockPos pos, boolean attempt) { + public Optional> asStructureBlock(BlockPos pos, boolean required) { assertLoaded(); var state = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.asBlock().defaultBlockState(); From d6e16877fdf09ef5a05de22a93c9d9a936080f30 Mon Sep 17 00:00:00 2001 From: Swedz Date: Sun, 24 Nov 2024 23:06:34 -0500 Subject: [PATCH 44/89] Use "hatch_flags" to store hatch flags instead of "flags" --- .../StructureMultiblockMemberEditScreen.java | 2 +- .../StructureMultiblockMemberBlockEntity.java | 28 +++++++++---------- .../member/HatchStructureMember.java | 2 +- .../StructureUpdateMemberPacket.java | 2 +- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java index 781a6fe65..3bea37490 100644 --- a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java @@ -217,7 +217,7 @@ public boolean charTyped(char codePoint, int modifiers) { } }; flagsBox.setMaxLength(Short.MAX_VALUE); - flagsBox.setValue(member.getInputFlags()); + flagsBox.setValue(member.getInputHatchFlags()); flagsBox.setResponder(text -> this.updateFlags()); this.addRenderableWidget(flagsBox); diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlockEntity.java index 34b3955ee..318b2cdb4 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlockEntity.java @@ -51,12 +51,12 @@ public class StructureMultiblockMemberBlockEntity extends FastBlockEntity implem private String inputPreview; private String inputMembers; private String inputCasing; - private String inputFlags; + private String inputHatchFlags; private BlockState preview; private List members; private MachineCasing casing; - private HatchFlags flags = HatchFlags.NO_HATCH; + private HatchFlags hatchFlags = HatchFlags.NO_HATCH; public StructureMultiblockMemberBlockEntity(BlockPos pos, BlockState state) { super(MIRegistries.STRUCTURE_MULTIBLOCK_MEMBER_BE.get(), pos, state); @@ -122,13 +122,13 @@ public void setInputCasing(String inputCasing) { } @Nullable - public String getInputFlags() { - return inputFlags; + public String getInputHatchFlags() { + return inputHatchFlags; } - public void setInputFlags(String inputFlags) { - this.inputFlags = inputFlags; - flags = StructureMultiblockInputFormatters.hatchFlags(inputFlags); + public void setInputHatchFlags(String inputHatchFlags) { + this.inputHatchFlags = inputHatchFlags; + hatchFlags = StructureMultiblockInputFormatters.hatchFlags(inputHatchFlags); } @Nullable @@ -137,14 +137,14 @@ public MachineCasing getCasing() { } @Nullable - public HatchFlags getFlags() { - return flags; + public HatchFlags getHatchFlags() { + return hatchFlags; } @Override public StructureMember getMemberOverride() { return switch (getMode()) { - case HATCH -> StructureMember.hatch(() -> preview, members, casing, flags); + case HATCH -> StructureMember.hatch(() -> preview, members, casing, hatchFlags); case SIMPLE -> StructureMember.simple(() -> preview, members); case VARIABLE -> StructureMember.variable(inputName); }; @@ -156,7 +156,7 @@ public boolean isConfigurationValid() { return inputName != null && !inputName.isEmpty(); } else if (preview != null && members != null && !members.isEmpty()) { if (mode == StructureMemberMode.HATCH) { - return casing != null && flags != null && !inputFlags.isEmpty(); + return casing != null && hatchFlags != null && !inputHatchFlags.isEmpty(); } return true; } @@ -191,8 +191,8 @@ protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) if (inputCasing != null) { tag.putString("casing", inputCasing); } - if (inputFlags != null) { - tag.putString("flags", inputFlags); + if (inputHatchFlags != null) { + tag.putString("hatch_flags", inputHatchFlags); } } @@ -204,7 +204,7 @@ protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) this.setInputPreview(tag.getString("preview")); this.setInputMembers(tag.getString("members")); this.setInputCasing(tag.getString("casing")); - this.setInputFlags(tag.getString("flags")); + this.setInputHatchFlags(tag.getString("hatch_flags")); this.updateBlockState(); } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java index eea12fba0..fe50018b4 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java @@ -117,7 +117,7 @@ public Optional> asStructureBlock(BlockPos pos be.setInputPreview(StructureMultiblockInputFormatters.preview(getPreviewState())); be.setInputMembers(StructureMultiblockInputFormatters.members(tests)); be.setInputCasing(StructureMultiblockInputFormatters.casing(casing)); - be.setInputFlags(StructureMultiblockInputFormatters.hatchFlags(hatchFlags)); + be.setInputHatchFlags(StructureMultiblockInputFormatters.hatchFlags(hatchFlags)); return Optional.of(Pair.of(state, be)); } diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java index f7180581d..f9c791aef 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java @@ -76,7 +76,7 @@ public void handle(Context ctx) { member.setInputPreview(inputPreview); member.setInputMembers(inputMembers); member.setInputCasing(inputCasing); - member.setInputFlags(inputFlags); + member.setInputHatchFlags(inputFlags); member.sync(); member.setChanged(); From 560823c7e5243f32b40fb1cb0367914e7b50d655 Mon Sep 17 00:00:00 2001 From: Swedz Date: Mon, 25 Nov 2024 00:43:06 -0500 Subject: [PATCH 45/89] Display data about the member block in the icon and tooltip --- .../modern_industrialization/MIClient.java | 16 ++ .../ClientStructureMemberBlockTooltip.java | 230 ++++++++++++++++++ .../item/structure_multiblock_member.json | 22 +- .../modern_industrialization/MIBlock.java | 18 +- .../StructureMultiblockMemberBlockItem.java | 83 +++++++ 5 files changed, 363 insertions(+), 6 deletions(-) create mode 100644 src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java create mode 100644 src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlockItem.java diff --git a/src/client/java/aztech/modern_industrialization/MIClient.java b/src/client/java/aztech/modern_industrialization/MIClient.java index 33c75857b..3d85bf6e9 100644 --- a/src/client/java/aztech/modern_industrialization/MIClient.java +++ b/src/client/java/aztech/modern_industrialization/MIClient.java @@ -31,6 +31,8 @@ import aztech.modern_industrialization.blocks.storage.tank.TankRenderer; import aztech.modern_industrialization.blocks.structure.StructureMultiblockBER; import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBER; +import aztech.modern_industrialization.blocks.structure.member.StructureMemberMode; +import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlockItem; import aztech.modern_industrialization.datagen.MIDatagenClient; import aztech.modern_industrialization.datagen.MIDatagenServer; import aztech.modern_industrialization.datagen.model.DelegatingModelBuilder; @@ -43,6 +45,7 @@ import aztech.modern_industrialization.items.armor.HudRenderer; import aztech.modern_industrialization.items.armor.JetpackParticleAdder; import aztech.modern_industrialization.items.client.ClientConfigCardTooltip; +import aztech.modern_industrialization.items.client.ClientStructureMemberBlockTooltip; import aztech.modern_industrialization.machines.MachineBlock; import aztech.modern_industrialization.machines.MachineBlockEntityRenderer; import aztech.modern_industrialization.machines.MachineOverlayClient; @@ -253,6 +256,7 @@ private static void registerClientTooltipComponents(RegisterClientTooltipCompone event.register(BarrelTooltipData.class, BarrelTooltipComponent::new); event.register(ConfigCardItem.TooltipData.class, ClientConfigCardTooltip::new); event.register(SteamDrillItem.SteamDrillTooltipData.class, SteamDrillTooltipComponent::new); + event.register(StructureMultiblockMemberBlockItem.TooltipData.class, ClientStructureMemberBlockTooltip::new); } @SubscribeEvent @@ -272,6 +276,18 @@ private static void registerItemProperties(FMLClientSetupEvent event) { (stack, level, entity, seed) -> { return RedstoneControlModuleItem.isRequiresLowSignal(stack) ? 0 : 1; }); + ItemProperties.register(MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.asItem(), MI.id("member_mode"), + (stack, level, entity, seed) -> { + StructureMemberMode mode = StructureMultiblockMemberBlockItem.getMode(stack); + if (mode == null) { + return 0; + } + return switch (mode) { + case SIMPLE -> 0.0f; + case HATCH -> 0.5f; + case VARIABLE -> 1.0f; + }; + }); }); } } diff --git a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java new file mode 100644 index 000000000..2ac454220 --- /dev/null +++ b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java @@ -0,0 +1,230 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.items.client; + +import aztech.modern_industrialization.MITooltips; +import aztech.modern_industrialization.blocks.structure.member.StructureMemberMode; +import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlockItem; +import aztech.modern_industrialization.machines.multiblocks.HatchType; +import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StateStructureMemberTest; +import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StructureMemberTest; +import aztech.modern_industrialization.util.RenderHelper; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import net.minecraft.ChatFormatting; +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.ItemStack; +import org.joml.Matrix4f; + +// TODO SWEDZ: there has to be a better way to align all the text and stuff. maybe some kind of builder? +public final class ClientStructureMemberBlockTooltip implements ClientTooltipComponent { + private static final int TEXT_ROW_HEIGHT = 9; + private static final int TEXT_BEFORE_IMAGE_ROW_HEIGHT = TEXT_ROW_HEIGHT + 4; + private static final int IMAGE_ROW_HEIGHT = 20; + + private final StructureMultiblockMemberBlockItem.TooltipData data; + + private final ItemStack preview; + private final List members; + + public ClientStructureMemberBlockTooltip(StructureMultiblockMemberBlockItem.TooltipData data) { + this.data = data; + + preview = data.preview().getBlock().asItem().getDefaultInstance(); + + members = new ArrayList<>(); + for (StructureMemberTest member : data.members()) { + if (member instanceof StateStructureMemberTest stateTest) { + members.add(stateTest.blockState().getBlock().asItem().getDefaultInstance()); + } + } + } + + @Override + public int getHeight() { + int height = 0; + + height += TEXT_ROW_HEIGHT; + + if (renderName()) { + height += TEXT_ROW_HEIGHT; + } + + if (renderCasing()) { + height += TEXT_ROW_HEIGHT; + } + + if (renderPreview()) { + height += TEXT_BEFORE_IMAGE_ROW_HEIGHT; + height += IMAGE_ROW_HEIGHT; + } + + if (renderMembers()) { + height += TEXT_BEFORE_IMAGE_ROW_HEIGHT; + height += IMAGE_ROW_HEIGHT; + } + + if (renderHatch()) { + height += TEXT_ROW_HEIGHT; + for (HatchType hatchType : HatchType.values()) { + if (data.hatchFlags().allows(hatchType)) { + height += TEXT_ROW_HEIGHT; + } + } + } + + return height; + } + + @Override + public int getWidth(Font font) { + // TODO SWEDZ: get actual width + return 18 * 6; + } + + private void renderRowImage(List stacks, Font font, int x, int y, GuiGraphics graphics) { + int i = 0; + for (var stack : stacks) { + RenderHelper.renderAndDecorateItem(graphics, font, stack, x + i * 18, y); + if (++i >= 5) { + break; + } + } + } + + private void renderRowImageText(int count, Font font, int x, int y, Matrix4f matrix, MultiBufferSource.BufferSource buffer) { + if (count >= 6) { + font.drawInBatch(Component.literal("+ ...").withStyle(MITooltips.DEFAULT_STYLE), x + 18 * 5, y + 5, -1, true, matrix, buffer, + Font.DisplayMode.NORMAL, 0, 0xF000F0); + } + } + + private void renderRowText(Component text, Font font, int x, int y, Matrix4f matrix, MultiBufferSource.BufferSource buffer) { + font.drawInBatch(text, x, y, -1, true, matrix, buffer, Font.DisplayMode.NORMAL, 0, 0xF000F0); + } + + private boolean renderName() { + return data.mode() == StructureMemberMode.VARIABLE; + } + + private boolean renderPreview() { + return data.mode() == StructureMemberMode.SIMPLE || data.mode() == StructureMemberMode.HATCH; + } + + private boolean renderMembers() { + return data.mode() == StructureMemberMode.SIMPLE || data.mode() == StructureMemberMode.HATCH; + } + + private boolean renderCasing() { + return data.mode() == StructureMemberMode.HATCH; + } + + private boolean renderHatch() { + return data.mode() == StructureMemberMode.HATCH && data.hatchFlags().flags != 0; + } + + @Override + public void renderImage(Font font, int x, int y, GuiGraphics graphics) { + int lineY = y; + + lineY += TEXT_ROW_HEIGHT; + + if (renderName()) { + lineY += TEXT_ROW_HEIGHT; + } + + if (renderCasing()) { + lineY += TEXT_ROW_HEIGHT; + } + + if (renderPreview()) { + lineY += TEXT_BEFORE_IMAGE_ROW_HEIGHT; + renderRowImage(List.of(preview), font, x, lineY, graphics); + lineY += IMAGE_ROW_HEIGHT; + } + + if (renderMembers()) { + lineY += TEXT_BEFORE_IMAGE_ROW_HEIGHT; + renderRowImage(members, font, x, lineY, graphics); + lineY += IMAGE_ROW_HEIGHT; + } + + if (renderHatch()) { + lineY += TEXT_ROW_HEIGHT; + for (HatchType hatchType : HatchType.values()) { + if (data.hatchFlags().allows(hatchType)) { + lineY += TEXT_ROW_HEIGHT; + } + } + } + } + + @Override + public void renderText(Font font, int x, int y, Matrix4f matrix, MultiBufferSource.BufferSource buffer) { + int lineY = y; + + // TODO SWEDZ: use translations + renderRowText(Component.literal("Mode: ").append(data.mode().text()), font, x, lineY, matrix, buffer); + lineY += TEXT_ROW_HEIGHT; + + if (renderName()) { + renderRowText(Component.literal("Name: %s".formatted(data.name())), font, x, lineY, matrix, buffer); + lineY += TEXT_ROW_HEIGHT; + } + + if (renderCasing()) { + renderRowText(Component.literal("Casing: %s".formatted(data.casing().key.getPath())), font, x, lineY, matrix, buffer); + lineY += TEXT_ROW_HEIGHT; + } + + if (renderPreview()) { + renderRowText(Component.literal("Preview").withStyle(ChatFormatting.UNDERLINE), font, x, lineY, matrix, buffer); + lineY += TEXT_BEFORE_IMAGE_ROW_HEIGHT; + lineY += IMAGE_ROW_HEIGHT; + } + + if (renderMembers()) { + renderRowText(Component.literal("Members").withStyle(ChatFormatting.UNDERLINE), font, x, lineY, matrix, buffer); + lineY += TEXT_BEFORE_IMAGE_ROW_HEIGHT; + renderRowImageText(members.size(), font, x, lineY, matrix, buffer); + lineY += IMAGE_ROW_HEIGHT; + } + + if (renderHatch()) { + renderRowText(Component.literal("Hatches").withStyle(ChatFormatting.UNDERLINE), font, x, lineY, matrix, buffer); + lineY += TEXT_ROW_HEIGHT; + for (HatchType hatchType : HatchType.values()) { + if (data.hatchFlags().allows(hatchType)) { + renderRowText(Component.literal("- %s".formatted(hatchType.name().toLowerCase(Locale.ROOT))), font, x, lineY, matrix, buffer); + lineY += TEXT_ROW_HEIGHT; + } + } + } + } +} diff --git a/src/generated/resources/assets/modern_industrialization/models/item/structure_multiblock_member.json b/src/generated/resources/assets/modern_industrialization/models/item/structure_multiblock_member.json index ca3e72608..ca6c79229 100644 --- a/src/generated/resources/assets/modern_industrialization/models/item/structure_multiblock_member.json +++ b/src/generated/resources/assets/modern_industrialization/models/item/structure_multiblock_member.json @@ -1,3 +1,23 @@ { - "parent": "modern_industrialization:block/structure_multiblock_member_simple" + "parent": "modern_industrialization:block/structure_multiblock_member_simple", + "overrides": [ + { + "model": "modern_industrialization:block/structure_multiblock_member_simple", + "predicate": { + "modern_industrialization:member_mode": 0.0 + } + }, + { + "model": "modern_industrialization:block/structure_multiblock_member_hatch", + "predicate": { + "modern_industrialization:member_mode": 0.5 + } + }, + { + "model": "modern_industrialization:block/structure_multiblock_member_variable", + "predicate": { + "modern_industrialization:member_mode": 1.0 + } + } + ] } \ No newline at end of file diff --git a/src/main/java/aztech/modern_industrialization/MIBlock.java b/src/main/java/aztech/modern_industrialization/MIBlock.java index 77de26df0..9cc19cf4e 100644 --- a/src/main/java/aztech/modern_industrialization/MIBlock.java +++ b/src/main/java/aztech/modern_industrialization/MIBlock.java @@ -36,7 +36,9 @@ import aztech.modern_industrialization.blocks.storage.tank.TankItem; import aztech.modern_industrialization.blocks.storage.tank.creativetank.CreativeTankBlockEntity; import aztech.modern_industrialization.blocks.structure.controller.StructureMultiblockControllerBlock; +import aztech.modern_industrialization.blocks.structure.member.StructureMemberMode; import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlock; +import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlockItem; import aztech.modern_industrialization.datagen.loot.MIBlockLoot; import aztech.modern_industrialization.datagen.model.BaseModelProvider; import aztech.modern_industrialization.definition.BlockDefinition; @@ -151,17 +153,23 @@ public static void init(IEventBus modBus) { public static final BlockDefinition STRUCTURE_MULTIBLOCK_MEMBER = block("Structure Multiblock Member", "structure_multiblock_member", BlockDefinitionParams.defaultCreativeOnly() .withBlockConstructor(StructureMultiblockMemberBlock::new) - .withBlockItemConstructor((block, p) -> new BlockItem(block, p.rarity(Rarity.EPIC))) + .withBlockItemConstructor((block, p) -> new StructureMultiblockMemberBlockItem(block, p.rarity(Rarity.EPIC))) .withModel((block, gen) -> { + Function modelCreator = (mode) -> { + String texture = "structure_multiblock_member_" + mode.getSerializedName(); + return gen.models().cubeAll(texture, gen.blockTexture(texture)); + }; gen.getVariantBuilder(block).forAllStates(state -> { var mode = state.getValue(StructureMultiblockMemberBlock.MODE); - String texture = "structure_multiblock_member_" + mode.getSerializedName(); return ConfiguredModel.builder() - .modelFile(gen.models().cubeAll(texture, gen.blockTexture(texture))) + .modelFile(modelCreator.apply(mode)) .build(); }); - String simpleTexture = "structure_multiblock_member_simple"; - gen.simpleBlockItem(block, gen.models().cubeAll(simpleTexture, gen.blockTexture(simpleTexture))); + gen.itemModels().getBuilder(gen.name(block)) + .parent(modelCreator.apply(StructureMemberMode.SIMPLE)) + .override().predicate(MI.id("member_mode"), 0.0f).model(modelCreator.apply(StructureMemberMode.SIMPLE)).end() + .override().predicate(MI.id("member_mode"), 0.5f).model(modelCreator.apply(StructureMemberMode.HATCH)).end() + .override().predicate(MI.id("member_mode"), 1.0f).model(modelCreator.apply(StructureMemberMode.VARIABLE)).end(); })); // Materials diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlockItem.java b/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlockItem.java new file mode 100644 index 000000000..732086d8e --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlockItem.java @@ -0,0 +1,83 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.blocks.structure.member; + +import aztech.modern_industrialization.MIBlock; +import aztech.modern_industrialization.machines.models.MachineCasing; +import aztech.modern_industrialization.machines.multiblocks.HatchFlags; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockInputFormatters; +import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StructureMemberTest; +import java.util.List; +import java.util.Locale; +import java.util.Optional; +import net.minecraft.core.component.DataComponents; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.inventory.tooltip.TooltipComponent; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; + +public class StructureMultiblockMemberBlockItem extends BlockItem { + public StructureMultiblockMemberBlockItem(Block block, Properties properties) { + super(block, properties); + } + + public static StructureMemberMode getMode(ItemStack stack) { + if (!stack.is(MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.asItem())) { + return null; + } + + String modeId = stack.has(DataComponents.BLOCK_ENTITY_DATA) + ? stack.get(DataComponents.BLOCK_ENTITY_DATA).copyTag().getString("mode") + : ""; + if (!modeId.isEmpty()) { + return StructureMemberMode.valueOf(modeId.toUpperCase(Locale.ROOT)); + } + return StructureMemberMode.SIMPLE; + } + + @Override + public Optional getTooltipImage(ItemStack stack) { + if (stack.has(DataComponents.BLOCK_ENTITY_DATA)) { + StructureMemberMode mode = getMode(stack); + + CompoundTag beTag = stack.get(DataComponents.BLOCK_ENTITY_DATA).copyTag(); + + var name = beTag.getString("name"); + var preview = StructureMultiblockInputFormatters.preview(beTag.getString("preview")); + var members = StructureMultiblockInputFormatters.members(beTag.getString("members")); + var casing = StructureMultiblockInputFormatters.casing(beTag.getString("casing")); + var hatchFlags = StructureMultiblockInputFormatters.hatchFlags(beTag.getString("hatch_flags")); + + return Optional.of(new TooltipData(mode, name, preview, members, casing, hatchFlags)); + } + + return Optional.empty(); + } + + public record TooltipData(StructureMemberMode mode, String name, BlockState preview, List members, MachineCasing casing, + HatchFlags hatchFlags) implements TooltipComponent { + } +} From 69bd85f345ff26a94a987613333c315b5adf4ad5 Mon Sep 17 00:00:00 2001 From: Swedz Date: Mon, 25 Nov 2024 22:39:45 -0500 Subject: [PATCH 46/89] Clean up structure block item tooltip internals --- .../ClientStructureMemberBlockTooltip.java | 167 ++++++------------ 1 file changed, 52 insertions(+), 115 deletions(-) diff --git a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java index 2ac454220..f4141e576 100644 --- a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java +++ b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java @@ -33,6 +33,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; +import java.util.function.BiConsumer; import net.minecraft.ChatFormatting; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; @@ -40,12 +41,12 @@ import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.network.chat.Component; import net.minecraft.world.item.ItemStack; +import org.jetbrains.annotations.Nullable; import org.joml.Matrix4f; -// TODO SWEDZ: there has to be a better way to align all the text and stuff. maybe some kind of builder? public final class ClientStructureMemberBlockTooltip implements ClientTooltipComponent { private static final int TEXT_ROW_HEIGHT = 9; - private static final int TEXT_BEFORE_IMAGE_ROW_HEIGHT = TEXT_ROW_HEIGHT + 4; + private static final int TEXT_BEFORE_IMAGE_EXTRA_ROW_HEIGHT = 4; private static final int IMAGE_ROW_HEIGHT = 20; private final StructureMultiblockMemberBlockItem.TooltipData data; @@ -53,6 +54,8 @@ public final class ClientStructureMemberBlockTooltip implements ClientTooltipCom private final ItemStack preview; private final List members; + private final List lines = new ArrayList<>(); + public ClientStructureMemberBlockTooltip(StructureMultiblockMemberBlockItem.TooltipData data) { this.data = data; @@ -64,42 +67,64 @@ public ClientStructureMemberBlockTooltip(StructureMultiblockMemberBlockItem.Tool members.add(stateTest.blockState().getBlock().asItem().getDefaultInstance()); } } - } - - @Override - public int getHeight() { - int height = 0; - - height += TEXT_ROW_HEIGHT; - if (renderName()) { - height += TEXT_ROW_HEIGHT; - } + // TODO SWEDZ: use translations + lines.add(Component.literal("Mode: ").append(data.mode().text())); - if (renderCasing()) { - height += TEXT_ROW_HEIGHT; + if (data.mode() == StructureMemberMode.VARIABLE) { + lines.add(Component.literal("Name: %s".formatted(data.name()))); } - if (renderPreview()) { - height += TEXT_BEFORE_IMAGE_ROW_HEIGHT; - height += IMAGE_ROW_HEIGHT; + if (data.mode() == StructureMemberMode.HATCH) { + lines.add(Component.literal("Casing: %s".formatted(data.casing().key.getPath()))); } - if (renderMembers()) { - height += TEXT_BEFORE_IMAGE_ROW_HEIGHT; - height += IMAGE_ROW_HEIGHT; + if (data.mode() == StructureMemberMode.SIMPLE || data.mode() == StructureMemberMode.HATCH) { + lines.add(Component.literal("Preview").withStyle(ChatFormatting.UNDERLINE)); + lines.add(List.of(preview)); + lines.add(Component.literal("Members").withStyle(ChatFormatting.UNDERLINE)); + lines.add(members); } - if (renderHatch()) { - height += TEXT_ROW_HEIGHT; + if (data.mode() == StructureMemberMode.HATCH && data.hatchFlags().flags != 0) { + lines.add(Component.literal("Hatches").withStyle(ChatFormatting.UNDERLINE)); for (HatchType hatchType : HatchType.values()) { if (data.hatchFlags().allows(hatchType)) { - height += TEXT_ROW_HEIGHT; + lines.add(Component.literal("- %s".formatted(hatchType.name().toLowerCase(Locale.ROOT)))); + } + } + } + } + + private int iterateLines(int startY, @Nullable BiConsumer actionText, + @Nullable BiConsumer> actionStacks) { + int y = startY; + for (int i = 0; i < lines.size(); i++) { + Object line = lines.get(i); + if (i > 0) { + Object last = lines.get(i - 1); + if (line instanceof List) { + y += TEXT_BEFORE_IMAGE_EXTRA_ROW_HEIGHT; + } + } + if (line instanceof Component text) { + if (actionText != null) { + actionText.accept(y, text); } + y += TEXT_ROW_HEIGHT; + } else if (line instanceof List list) { + if (actionStacks != null) { + actionStacks.accept(y, list); + } + y += IMAGE_ROW_HEIGHT; } } + return y; + } - return height; + @Override + public int getHeight() { + return iterateLines(0, null, null); } @Override @@ -129,102 +154,14 @@ private void renderRowText(Component text, Font font, int x, int y, Matrix4f mat font.drawInBatch(text, x, y, -1, true, matrix, buffer, Font.DisplayMode.NORMAL, 0, 0xF000F0); } - private boolean renderName() { - return data.mode() == StructureMemberMode.VARIABLE; - } - - private boolean renderPreview() { - return data.mode() == StructureMemberMode.SIMPLE || data.mode() == StructureMemberMode.HATCH; - } - - private boolean renderMembers() { - return data.mode() == StructureMemberMode.SIMPLE || data.mode() == StructureMemberMode.HATCH; - } - - private boolean renderCasing() { - return data.mode() == StructureMemberMode.HATCH; - } - - private boolean renderHatch() { - return data.mode() == StructureMemberMode.HATCH && data.hatchFlags().flags != 0; - } - @Override public void renderImage(Font font, int x, int y, GuiGraphics graphics) { - int lineY = y; - - lineY += TEXT_ROW_HEIGHT; - - if (renderName()) { - lineY += TEXT_ROW_HEIGHT; - } - - if (renderCasing()) { - lineY += TEXT_ROW_HEIGHT; - } - - if (renderPreview()) { - lineY += TEXT_BEFORE_IMAGE_ROW_HEIGHT; - renderRowImage(List.of(preview), font, x, lineY, graphics); - lineY += IMAGE_ROW_HEIGHT; - } - - if (renderMembers()) { - lineY += TEXT_BEFORE_IMAGE_ROW_HEIGHT; - renderRowImage(members, font, x, lineY, graphics); - lineY += IMAGE_ROW_HEIGHT; - } - - if (renderHatch()) { - lineY += TEXT_ROW_HEIGHT; - for (HatchType hatchType : HatchType.values()) { - if (data.hatchFlags().allows(hatchType)) { - lineY += TEXT_ROW_HEIGHT; - } - } - } + iterateLines(y, null, (lineY, stacks) -> renderRowImage(stacks, font, x, lineY, graphics)); } @Override public void renderText(Font font, int x, int y, Matrix4f matrix, MultiBufferSource.BufferSource buffer) { - int lineY = y; - - // TODO SWEDZ: use translations - renderRowText(Component.literal("Mode: ").append(data.mode().text()), font, x, lineY, matrix, buffer); - lineY += TEXT_ROW_HEIGHT; - - if (renderName()) { - renderRowText(Component.literal("Name: %s".formatted(data.name())), font, x, lineY, matrix, buffer); - lineY += TEXT_ROW_HEIGHT; - } - - if (renderCasing()) { - renderRowText(Component.literal("Casing: %s".formatted(data.casing().key.getPath())), font, x, lineY, matrix, buffer); - lineY += TEXT_ROW_HEIGHT; - } - - if (renderPreview()) { - renderRowText(Component.literal("Preview").withStyle(ChatFormatting.UNDERLINE), font, x, lineY, matrix, buffer); - lineY += TEXT_BEFORE_IMAGE_ROW_HEIGHT; - lineY += IMAGE_ROW_HEIGHT; - } - - if (renderMembers()) { - renderRowText(Component.literal("Members").withStyle(ChatFormatting.UNDERLINE), font, x, lineY, matrix, buffer); - lineY += TEXT_BEFORE_IMAGE_ROW_HEIGHT; - renderRowImageText(members.size(), font, x, lineY, matrix, buffer); - lineY += IMAGE_ROW_HEIGHT; - } - - if (renderHatch()) { - renderRowText(Component.literal("Hatches").withStyle(ChatFormatting.UNDERLINE), font, x, lineY, matrix, buffer); - lineY += TEXT_ROW_HEIGHT; - for (HatchType hatchType : HatchType.values()) { - if (data.hatchFlags().allows(hatchType)) { - renderRowText(Component.literal("- %s".formatted(hatchType.name().toLowerCase(Locale.ROOT))), font, x, lineY, matrix, buffer); - lineY += TEXT_ROW_HEIGHT; - } - } - } + iterateLines(y, (lineY, text) -> renderRowText(text, font, x, lineY, matrix, buffer), + (lineY, stacks) -> renderRowImageText(stacks.size(), font, x, lineY, matrix, buffer)); } } From 617ddf536a38bf8b8bf7c42c853b53f9100d7930 Mon Sep 17 00:00:00 2001 From: Swedz Date: Mon, 25 Nov 2024 22:40:34 -0500 Subject: [PATCH 47/89] Remove unnecessary variables --- .../items/client/ClientStructureMemberBlockTooltip.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java index f4141e576..43337d89e 100644 --- a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java +++ b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java @@ -51,17 +51,14 @@ public final class ClientStructureMemberBlockTooltip implements ClientTooltipCom private final StructureMultiblockMemberBlockItem.TooltipData data; - private final ItemStack preview; - private final List members; - private final List lines = new ArrayList<>(); public ClientStructureMemberBlockTooltip(StructureMultiblockMemberBlockItem.TooltipData data) { this.data = data; - preview = data.preview().getBlock().asItem().getDefaultInstance(); + ItemStack preview = data.preview().getBlock().asItem().getDefaultInstance(); - members = new ArrayList<>(); + List members = new ArrayList<>(); for (StructureMemberTest member : data.members()) { if (member instanceof StateStructureMemberTest stateTest) { members.add(stateTest.blockState().getBlock().asItem().getDefaultInstance()); From 6f1c3ebab8867444dcc6a4941d3c7223fe5b1f94 Mon Sep 17 00:00:00 2001 From: Swedz Date: Tue, 26 Nov 2024 22:41:44 -0500 Subject: [PATCH 48/89] Use codecs to save and read structures as json --- .../machines/models/MachineCasing.java | 3 + .../machines/multiblocks/HatchFlags.java | 4 + .../machines/multiblocks/ShapeTemplate.java | 57 +++++++- .../structure/MIStructureTemplateManager.java | 122 +++++------------- .../structure/StructureResult.java | 3 +- .../member/HatchStructureMember.java | 67 +++------- .../member/LiteralStructureMember.java | 16 ++- .../member/SimpleStructureMember.java | 91 +++---------- .../structure/member/StructureMember.java | 44 +------ .../structure/member/StructureMemberType.java | 67 ++++++++++ .../member/VariableStructureMember.java | 48 ++----- .../member/test/StateStructureMemberTest.java | 56 +++----- .../member/test/StructureMemberTest.java | 45 ++----- .../member/test/StructureMemberTestType.java | 65 ++++++++++ .../member/test/TagStructureMemberTest.java | 46 ++----- .../StructureSaveControllerPacket.java | 2 +- .../util/MIExtraCodecs.java | 15 +++ 17 files changed, 330 insertions(+), 421 deletions(-) create mode 100644 src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberType.java create mode 100644 src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StructureMemberTestType.java diff --git a/src/main/java/aztech/modern_industrialization/machines/models/MachineCasing.java b/src/main/java/aztech/modern_industrialization/machines/models/MachineCasing.java index 4d4fe8d62..5fb7db7ce 100644 --- a/src/main/java/aztech/modern_industrialization/machines/models/MachineCasing.java +++ b/src/main/java/aztech/modern_industrialization/machines/models/MachineCasing.java @@ -23,9 +23,12 @@ */ package aztech.modern_industrialization.machines.models; +import com.mojang.serialization.Codec; import net.minecraft.resources.ResourceLocation; public class MachineCasing { + public static final Codec CODEC = ResourceLocation.CODEC.xmap(MachineCasings::get, casing -> casing.key); + public final ResourceLocation key; MachineCasing(ResourceLocation key) { diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/HatchFlags.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/HatchFlags.java index 425244ced..50403694e 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/HatchFlags.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/HatchFlags.java @@ -23,7 +23,11 @@ */ package aztech.modern_industrialization.machines.multiblocks; +import com.mojang.serialization.Codec; + public class HatchFlags { + public static final Codec CODEC = Codec.INT.xmap(HatchFlags::new, flags -> flags.flags); + public static final HatchFlags NO_HATCH = new Builder().build(); public final int flags; diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java index 339d3546e..cc05b1b6d 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java @@ -25,13 +25,12 @@ import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.structure.MIStructureTemplateManager; +import aztech.modern_industrialization.machines.multiblocks.structure.member.HatchStructureMember; +import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; import aztech.modern_industrialization.machines.multiblocks.structure.member.VariableStructureMember; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import java.util.*; import net.minecraft.core.BlockPos; import net.minecraft.resources.ResourceLocation; import org.jetbrains.annotations.Nullable; @@ -40,6 +39,52 @@ * An immutable description of a multiblock shape. */ public class ShapeTemplate { + public static final Codec STRUCTURE_CODEC = InternalStructureTemplate.CODEC + .xmap(structure -> { + Builder template = new Builder(structure.casing()); + for (InternalStructureBlockPos block : structure.blocks()) { + BlockPos pos = block.pos(); + int memberIndex = block.memberIndex(); + StructureMember member = structure.members().get(memberIndex); + template.add(pos.getX(), pos.getY(), pos.getZ(), member, + member instanceof HatchStructureMember hatch ? hatch.hatchFlags() : null); + } + return template.build(); + }, template -> { + List members = new ArrayList<>(); + List blocks = new ArrayList<>(); + for (var entry : template.simpleMembers.entrySet()) { + if (entry.getValue() instanceof StructureMember member) { + if (!members.contains(member)) { + members.add(member); + } + int memberIndex = members.indexOf(member); + blocks.add(new InternalStructureBlockPos(memberIndex, entry.getKey())); + } else { + throw new IllegalArgumentException( + "Cannot convert ShapeTemplate to a structure ShapeTemplate if all members aren't StructureMembers"); + } + } + return new InternalStructureTemplate(template.hatchCasing, blocks, members); + }); + + private record InternalStructureBlockPos(int memberIndex, BlockPos pos) { + private static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + Codec.INT.fieldOf("member_index").forGetter(InternalStructureBlockPos::memberIndex), + BlockPos.CODEC.fieldOf("pos").forGetter(InternalStructureBlockPos::pos)) + .apply(instance, InternalStructureBlockPos::new)); + } + + private record InternalStructureTemplate(MachineCasing casing, List blocks, List members) { + private static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + MachineCasing.CODEC.fieldOf("hatch_casing").forGetter(InternalStructureTemplate::casing), + InternalStructureBlockPos.CODEC.listOf().fieldOf("blocks").forGetter(InternalStructureTemplate::blocks), + StructureMember.CODEC.listOf().fieldOf("members").forGetter(InternalStructureTemplate::members)) + .apply(instance, InternalStructureTemplate::new)); + } + public final Map simpleMembers = new HashMap<>(); public final Map hatchFlags = new HashMap<>(); public final MachineCasing hatchCasing; diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java index 989143928..7274419d0 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java @@ -23,16 +23,21 @@ */ package aztech.modern_industrialization.machines.multiblocks.structure; -import static aztech.modern_industrialization.machines.multiblocks.ShapeMatcher.*; +import static aztech.modern_industrialization.machines.multiblocks.ShapeMatcher.toTemplatePos; +import static aztech.modern_industrialization.machines.multiblocks.ShapeMatcher.toTemplateState; import aztech.modern_industrialization.MI; import aztech.modern_industrialization.blocks.structure.StructureMemberOverride; import aztech.modern_industrialization.blocks.structure.controller.StructureControllerBounds; import aztech.modern_industrialization.machines.models.MachineCasing; -import aztech.modern_industrialization.machines.models.MachineCasings; +import aztech.modern_industrialization.machines.multiblocks.HatchFlags; import aztech.modern_industrialization.machines.multiblocks.ShapeTemplate; import aztech.modern_industrialization.machines.multiblocks.structure.member.HatchStructureMember; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.mojang.serialization.JsonOps; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -40,21 +45,11 @@ import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; import java.util.function.BiConsumer; import net.minecraft.FileUtil; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; -import net.minecraft.nbt.NbtUtils; -import net.minecraft.nbt.SnbtPrinterTagVisitor; -import net.minecraft.nbt.Tag; -import net.minecraft.nbt.TagParser; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.FastBufferedInputStream; import net.minecraft.world.level.Level; @@ -120,20 +115,12 @@ public static StructureResult fromWorld(ResourceLocation id, Level level, misconfiguredBlocks.add(controllerPos); } - CompoundTag tag = new CompoundTag(); - - if (hatchCasing != null) { - tag.putString("hatch_casing", hatchCasing.key.toString()); - } + ShapeTemplate.Builder template = new ShapeTemplate.Builder(hatchCasing); BoundingBox boundsBox = bounds.boundingBox(); BlockPos minPos = controllerPos.offset(boundsBox.minX(), boundsBox.minY(), boundsBox.minZ()); BlockPos maxPos = controllerPos.offset(boundsBox.maxX(), boundsBox.maxY(), boundsBox.maxZ()); - List members = new ArrayList<>(); - ListTag membersTag = new ListTag(); - ListTag blocksTag = new ListTag(); - for (BlockPos pos : BlockPos.betweenClosed(minPos, maxPos)) { BlockState state = toTemplateState(level, pos, level.getBlockState(pos), controllerDirection); @@ -141,10 +128,7 @@ public static StructureResult fromWorld(ResourceLocation id, Level level, continue; } - CompoundTag blockTag = new CompoundTag(); - - blockTag.put("pos", NbtUtils.writeBlockPos(toTemplatePos(controllerPos, controllerDirection, pos))); - + BlockPos templatePos = toTemplatePos(controllerPos, controllerDirection, pos); StructureMember member = StructureMember.literal(() -> state); BlockEntity blockEntity = level.getBlockEntity(pos); @@ -163,19 +147,12 @@ public static StructureResult fromWorld(ResourceLocation id, Level level, } if (member != null) { + HatchFlags hatchFlags = null; if (member instanceof HatchStructureMember hatch && hatch.hatchFlags() != null) { hatchBlocks.add(pos.immutable()); + hatchFlags = hatch.hatchFlags(); } - CompoundTag memberTag = new CompoundTag(); - memberTag.putString("type", member.typeId()); - member.save(memberTag); - if (!members.contains(member)) { - members.add(member); - membersTag.add(memberTag); - } - blockTag.putInt("member_index", members.indexOf(member)); - - blocksTag.add(blockTag); + template.add(templatePos.getX(), templatePos.getY(), templatePos.getZ(), member, hatchFlags); } } @@ -192,46 +169,7 @@ public static StructureResult fromWorld(ResourceLocation id, Level level, return new StructureResult.MisconfiguredBlocks(misconfiguredBlocks); } - tag.put("members", membersTag); - tag.put("blocks", blocksTag); - - ShapeTemplate template = deserialize(tag); - if (template == null) { - MI.LOGGER.error("Failed to deserialize structure tag immediately after it was created. Have you changed the deserialier or serializer?"); - return new StructureResult.Unknown(); - } - - return new StructureResult.Success(id, template, tag); - } - - @Nullable - private static ShapeTemplate deserialize(CompoundTag tag) { - Objects.requireNonNull(tag); - - ResourceLocation hatchCasingId = ResourceLocation.tryParse(tag.getString("hatch_casing")); - if (hatchCasingId == null || !MachineCasings.registeredCasings.containsKey(hatchCasingId)) { - return null; - } - MachineCasing hatchCasing = MachineCasings.get(hatchCasingId); - - ShapeTemplate.Builder builder = new ShapeTemplate.Builder(hatchCasing); - - ListTag members = tag.getList("members", Tag.TAG_COMPOUND); - ListTag blocks = tag.getList("blocks", Tag.TAG_COMPOUND); - - for (int i = 0; i < blocks.size(); i++) { - CompoundTag blockTag = blocks.getCompound(i); - - BlockPos pos = NbtUtils.readBlockPos(blockTag, "pos").orElseThrow(); - - if (blockTag.contains("member_index", Tag.TAG_INT)) { - int memberIndex = blockTag.getInt("member_index"); - StructureMember member = StructureMember.from(members.getCompound(memberIndex)); - builder.add(pos.getX(), pos.getY(), pos.getZ(), member, member instanceof HatchStructureMember hatch ? hatch.hatchFlags() : null); - } - } - - return builder.build(); + return new StructureResult.Success(id, template.build()); } private static Path structuresPath() { @@ -244,15 +182,16 @@ private static Path path(ResourceLocation id) throws IOException { Objects.requireNonNull(id); var structuresFolder = structuresPath().resolve(id.getNamespace()); Files.createDirectories(structuresFolder); - return FileUtil.createPathToResource(structuresFolder, id.getPath(), ".snbt"); + return FileUtil.createPathToResource(structuresFolder, id.getPath(), ".json"); } - public static boolean save(ResourceLocation id, CompoundTag tag) { + public static boolean save(ResourceLocation id, ShapeTemplate template) { Objects.requireNonNull(id); - Objects.requireNonNull(tag); + Objects.requireNonNull(template); try { + var json = ShapeTemplate.STRUCTURE_CODEC.encodeStart(JsonOps.INSTANCE, template).getOrThrow(); try (OutputStream output = Files.newOutputStream(path(id))) { - output.write(new SnbtPrinterTagVisitor().visit(tag).getBytes(StandardCharsets.UTF_8)); + output.write(new GsonBuilder().setPrettyPrinting().create().toJson(json).getBytes(StandardCharsets.UTF_8)); return true; } catch (Exception ex) { MI.LOGGER.error("Failed to save structure \"{}\"", id, ex); @@ -264,13 +203,13 @@ public static boolean save(ResourceLocation id, CompoundTag tag) { } @Nullable - private static CompoundTag load(Path path) { + private static JsonElement load(Path path) { Objects.requireNonNull(path); try { if (Files.exists(path)) { try (InputStream input = Files.newInputStream(path); InputStream fastInput = new FastBufferedInputStream(input)) { - return TagParser.parseTag(new String(fastInput.readAllBytes(), StandardCharsets.UTF_8)); + return JsonParser.parseString(new String(fastInput.readAllBytes(), StandardCharsets.UTF_8)); } catch (Exception ex) { MI.LOGGER.error("Failed to load structure at \"{}\"", path, ex); return null; @@ -290,7 +229,7 @@ private static void iterateStructureFiles(Path origin, BiConsumer files = Files.newDirectoryStream(subdirectory)) { for (Path file : files) { - if (file.toString().endsWith(".snbt")) { + if (file.toString().endsWith(".json")) { String rawFileName = file.getFileName().toString(); String path = rawFileName.substring(0, rawFileName.lastIndexOf('.')); ResourceLocation id = ResourceLocation.fromNamespaceAndPath(namespace, path); @@ -303,13 +242,13 @@ private static void iterateStructureFiles(Path origin, BiConsumer { - if (STRUCTURE_TEMPLATES.containsKey(id)) { - return; + if (!STRUCTURE_TEMPLATES.containsKey(id)) { + register(id, path); } - register(id, path); }); } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureResult.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureResult.java index 3db6a9d01..faee6ec93 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureResult.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureResult.java @@ -30,7 +30,6 @@ import java.util.List; import net.minecraft.ChatFormatting; import net.minecraft.core.BlockPos; -import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; @@ -116,7 +115,7 @@ public Component text() { } } - record Success(ResourceLocation structureId, ShapeTemplate template, CompoundTag tag) implements StructureResult { + record Success(ResourceLocation structureId, ShapeTemplate template) implements StructureResult { @Override public boolean isSuccess() { return true; diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java index fe50018b4..c3cce8a66 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java @@ -28,24 +28,31 @@ import aztech.modern_industrialization.blocks.structure.member.StructureMemberMode; import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlock; import aztech.modern_industrialization.machines.models.MachineCasing; -import aztech.modern_industrialization.machines.models.MachineCasings; import aztech.modern_industrialization.machines.multiblocks.HatchFlags; import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockInputFormatters; import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StructureMemberTest; +import aztech.modern_industrialization.util.MIExtraCodecs; import com.mojang.datafixers.util.Pair; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.function.Supplier; import net.minecraft.core.BlockPos; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.Tag; -import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.block.state.BlockState; -public class HatchStructureMember extends SimpleStructureMember { - protected MachineCasing casing; - protected HatchFlags hatchFlags; +public final class HatchStructureMember extends SimpleStructureMember { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance + .group( + MIExtraCodecs.LAZY_BLOCK_STATE.fieldOf("preview").forGetter(member -> member.previewSupplier), + StructureMemberTest.CODEC.listOf().fieldOf("tests").forGetter(HatchStructureMember::tests), + MachineCasing.CODEC.fieldOf("casing").forGetter(HatchStructureMember::casing), + HatchFlags.CODEC.fieldOf("hatch_flags").forGetter(HatchStructureMember::hatchFlags)) + .apply(instance, HatchStructureMember::new)); + + private final MachineCasing casing; + private final HatchFlags hatchFlags; public HatchStructureMember(Supplier previewSupplier, List tests, MachineCasing casing, HatchFlags hatchFlags) { super(previewSupplier, tests); @@ -55,61 +62,21 @@ public HatchStructureMember(Supplier previewSupplier, List type() { + return StructureMemberType.HATCH; } @Override public Optional> asStructureBlock(BlockPos pos, boolean required) { - assertLoaded(); - if (required) { var state = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.asBlock().defaultBlockState(); state = state.setValue(StructureMultiblockMemberBlock.MODE, StructureMemberMode.HATCH); @@ -126,9 +93,7 @@ public Optional> asStructureBlock(BlockPos pos @Override public boolean equals(Object o) { - assertLoaded(); if (o instanceof HatchStructureMember other && this.getClass() == other.getClass()) { - other.assertLoaded(); return this.getPreviewState() == other.getPreviewState() && tests.containsAll(other.tests) && other.tests.containsAll(tests) && casing.equals(other.casing) && diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java index 08bf74410..c73335f6c 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java @@ -25,24 +25,26 @@ import aztech.modern_industrialization.blocks.FastBlockEntity; import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StateStructureMemberTest; +import aztech.modern_industrialization.util.MIExtraCodecs; import com.mojang.datafixers.util.Pair; +import com.mojang.serialization.MapCodec; import java.util.List; import java.util.Optional; import java.util.function.Supplier; import net.minecraft.core.BlockPos; import net.minecraft.world.level.block.state.BlockState; -public class LiteralStructureMember extends SimpleStructureMember { - public LiteralStructureMember(Supplier blockState) { - super(blockState, List.of(new StateStructureMemberTest(blockState))); - } +public final class LiteralStructureMember extends SimpleStructureMember { + public static final MapCodec CODEC = MIExtraCodecs.LAZY_BLOCK_STATE + .xmap(LiteralStructureMember::new, member -> member.previewSupplier).fieldOf("state"); - public LiteralStructureMember() { + public LiteralStructureMember(Supplier previewSupplier) { + super(previewSupplier, List.of(new StateStructureMemberTest(previewSupplier))); } @Override - public String typeId() { - return "literal"; + public StructureMemberType type() { + return StructureMemberType.LITERAL; } @Override diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java index eb238324d..612ef686b 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java @@ -29,100 +29,49 @@ import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlock; import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockInputFormatters; import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StructureMemberTest; +import aztech.modern_industrialization.util.MIExtraCodecs; import com.mojang.datafixers.util.Pair; -import java.util.ArrayList; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.function.Supplier; import net.minecraft.core.BlockPos; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; -import net.minecraft.nbt.NbtUtils; -import net.minecraft.nbt.Tag; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; -public class SimpleStructureMember extends StructureMember { - protected Supplier previewSupplier; - protected List tests; +public sealed class SimpleStructureMember extends StructureMember permits HatchStructureMember, LiteralStructureMember { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance + .group( + MIExtraCodecs.LAZY_BLOCK_STATE.fieldOf("preview").forGetter(member -> member.previewSupplier), + StructureMemberTest.CODEC.listOf().fieldOf("tests").forGetter(SimpleStructureMember::tests)) + .apply(instance, SimpleStructureMember::new)); - private BlockState preview; + protected final Supplier previewSupplier; - public SimpleStructureMember(Supplier preview, List tests) { - Objects.requireNonNull(preview); + protected BlockState preview; + protected final List tests; + + public SimpleStructureMember(Supplier previewSupplier, List tests) { + Objects.requireNonNull(previewSupplier); Objects.requireNonNull(tests); - this.previewSupplier = preview; + this.previewSupplier = previewSupplier; this.tests = tests; } - public SimpleStructureMember() { - } - public List tests() { - assertLoaded(); return Collections.unmodifiableList(tests); } @Override - public String typeId() { - return "simple"; - } - - @Override - public boolean isLoaded() { - return previewSupplier != null && tests != null; - } - - @Override - public void load(CompoundTag tag) { - super.load(tag); - if (!tag.contains("preview", CompoundTag.TAG_COMPOUND) || - !tag.contains("tests", CompoundTag.TAG_LIST)) { - throw new IllegalArgumentException("Invalid structure member format for type \"" + typeId() + "\": " + tag); - } - - previewSupplier = () -> NbtUtils.readBlockState(BuiltInRegistries.BLOCK.asLookup(), tag.getCompound("preview")); - - ListTag testsTag = tag.getList("tests", Tag.TAG_COMPOUND); - if (testsTag.isEmpty()) { - throw new IllegalArgumentException("Member cannot have no tests: " + tag); - } - tests = new ArrayList<>(); - for (int i = 0; i < testsTag.size(); i++) { - CompoundTag testTag = testsTag.getCompound(i); - StructureMemberTest test = StructureMemberTest.from(testTag); - if (test != null) { - tests.add(test); - } - } - } - - @Override - public void save(CompoundTag tag) { - super.save(tag); - - tag.put("preview", NbtUtils.writeBlockState(getPreviewState())); - - ListTag testsTag = new ListTag(); - for (StructureMemberTest test : tests) { - CompoundTag testTag = new CompoundTag(); - testTag.putString("type", test.typeId()); - test.save(testTag); - testsTag.add(testTag); - } - if (testsTag.isEmpty()) { - throw new IllegalArgumentException("Member cannot have no tests"); - } - tag.put("tests", testsTag); + public StructureMemberType type() { + return StructureMemberType.SIMPLE; } @Override public Optional> asStructureBlock(BlockPos pos, boolean required) { - assertLoaded(); - if (required) { var state = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.asBlock().defaultBlockState(); state = state.setValue(StructureMultiblockMemberBlock.MODE, StructureMemberMode.SIMPLE); @@ -137,7 +86,6 @@ public Optional> asStructureBlock(BlockPos pos @Override public boolean matchesState(BlockState state) { - assertLoaded(); for (StructureMemberTest test : tests) { if (test.matchesState(state)) { return true; @@ -148,7 +96,6 @@ public boolean matchesState(BlockState state) { @Override public BlockState getPreviewState() { - assertLoaded(); if (preview == null) { preview = previewSupplier.get(); if (preview == null) { @@ -160,9 +107,7 @@ public BlockState getPreviewState() { @Override public boolean equals(Object o) { - assertLoaded(); if (o instanceof SimpleStructureMember other && this.getClass() == other.getClass()) { - other.assertLoaded(); return this.getPreviewState() == other.getPreviewState() && tests.containsAll(other.tests) && other.tests.containsAll(tests); } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java index 6cbd1ad0f..c95a78918 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java @@ -29,33 +29,20 @@ import aztech.modern_industrialization.machines.multiblocks.SimpleMember; import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StructureMemberTest; import com.mojang.datafixers.util.Pair; +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; import java.util.List; -import java.util.Objects; import java.util.Optional; import java.util.function.Supplier; import net.minecraft.core.BlockPos; -import net.minecraft.nbt.CompoundTag; import net.minecraft.world.level.block.state.BlockState; -public abstract class StructureMember implements SimpleMember { - public abstract String typeId(); +public sealed abstract class StructureMember implements SimpleMember permits SimpleStructureMember, VariableStructureMember { + public static final Codec CODEC = Codec.STRING.flatComapMap( + StructureMemberType::getType, type -> DataResult.success(type.name())) + .dispatch(member -> (StructureMemberType) member.type(), StructureMemberType::codec); - public abstract boolean isLoaded(); - - protected final void assertLoaded() { - if (!isLoaded()) { - throw new IllegalStateException("Member is not loaded"); - } - } - - public void load(CompoundTag tag) { - Objects.requireNonNull(tag); - } - - public void save(CompoundTag tag) { - Objects.requireNonNull(tag); - assertLoaded(); - } + public abstract StructureMemberType type(); public abstract Optional> asStructureBlock(BlockPos pos, boolean required); @@ -75,21 +62,4 @@ public static HatchStructureMember hatch(Supplier preview, List new SimpleStructureMember(); - case "literal" -> new LiteralStructureMember(); - case "hatch" -> new HatchStructureMember(); - case "variable" -> new VariableStructureMember(); - default -> throw new IllegalStateException("Unexpected type: " + type); - }; - member.load(tag); - return member; - } } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberType.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberType.java new file mode 100644 index 000000000..56c548b53 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberType.java @@ -0,0 +1,67 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.machines.multiblocks.structure.member; + +import com.google.common.collect.Maps; +import com.mojang.serialization.MapCodec; +import java.util.Map; + +public final class StructureMemberType { + private static final Map> TYPES = Maps.newHashMap(); + + public static final StructureMemberType LITERAL = register("literal", LiteralStructureMember.CODEC); + public static final StructureMemberType SIMPLE = register("simple", SimpleStructureMember.CODEC); + public static final StructureMemberType HATCH = register("hatch", HatchStructureMember.CODEC); + public static final StructureMemberType VARIABLE = register("variable", VariableStructureMember.CODEC); + + private static StructureMemberType register(String name, MapCodec codec) { + var type = new StructureMemberType<>(name, codec); + TYPES.put(name, type); + return type; + } + + static StructureMemberType getType(String name) { + var type = TYPES.get(name); + if (type == null) { + throw new IllegalArgumentException("No type could be found for the name \"" + name + "\""); + } + return type; + } + + private final String name; + private final MapCodec codec; + + public StructureMemberType(String name, MapCodec codec) { + this.name = name; + this.codec = codec; + } + + public String name() { + return name; + } + + public MapCodec codec() { + return codec; + } +} diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/VariableStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/VariableStructureMember.java index 9d49c4a1f..32a3c31cc 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/VariableStructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/VariableStructureMember.java @@ -28,63 +28,35 @@ import aztech.modern_industrialization.blocks.structure.member.StructureMemberMode; import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlock; import com.mojang.datafixers.util.Pair; +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; import java.util.Objects; import java.util.Optional; import net.minecraft.core.BlockPos; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.Tag; import net.minecraft.world.level.block.state.BlockState; -public class VariableStructureMember extends StructureMember { - protected String name; +public final class VariableStructureMember extends StructureMember { + public static final MapCodec CODEC = Codec.STRING.xmap(VariableStructureMember::new, VariableStructureMember::name) + .fieldOf("name"); + + private final String name; public VariableStructureMember(String name) { Objects.requireNonNull(name); this.name = name; } - public VariableStructureMember() { - } - public String name() { - assertLoaded(); return name; } @Override - public String typeId() { - return "variable"; - } - - @Override - public boolean isLoaded() { - return name != null; - } - - @Override - public void load(CompoundTag tag) { - super.load(tag); - if (!tag.contains("name", Tag.TAG_STRING)) { - throw new IllegalArgumentException("Invalid structure member format for type \"" + typeId() + "\": " + tag); - } - - name = tag.getString("name"); - if (name.isEmpty()) { - throw new IllegalArgumentException("Invalid structure member format for type \"" + typeId() + "\": " + tag); - } - } - - @Override - public void save(CompoundTag tag) { - super.save(tag); - - tag.putString("name", name); + public StructureMemberType type() { + return StructureMemberType.VARIABLE; } @Override public Optional> asStructureBlock(BlockPos pos, boolean required) { - assertLoaded(); - var state = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.asBlock().defaultBlockState(); state = state.setValue(StructureMultiblockMemberBlock.MODE, StructureMemberMode.VARIABLE); var be = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.get().newBlockEntity(pos, state); @@ -105,9 +77,7 @@ public BlockState getPreviewState() { @Override public boolean equals(Object o) { - assertLoaded(); if (o instanceof VariableStructureMember other && this.getClass() == other.getClass()) { - other.assertLoaded(); return name.equals(other.name); } return false; diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StateStructureMemberTest.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StateStructureMemberTest.java index 396da15b8..eb8da4d62 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StateStructureMemberTest.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StateStructureMemberTest.java @@ -23,30 +23,30 @@ */ package aztech.modern_industrialization.machines.multiblocks.structure.member.test; +import aztech.modern_industrialization.util.MIExtraCodecs; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import java.util.Objects; import java.util.function.Supplier; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.NbtUtils; -import net.minecraft.nbt.Tag; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; -public class StateStructureMemberTest extends StructureMemberTest { - private Supplier blockStateSupplier; +public final class StateStructureMemberTest extends StructureMemberTest { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance + .group( + MIExtraCodecs.LAZY_BLOCK_STATE.fieldOf("state").forGetter(test -> test.blockStateSupplier)) + .apply(instance, StateStructureMemberTest::new)); - private BlockState blockState; + private final Supplier blockStateSupplier; - public StateStructureMemberTest(Supplier blockState) { - Objects.requireNonNull(blockState); - this.blockStateSupplier = blockState; - } + private BlockState blockState; - public StateStructureMemberTest() { + public StateStructureMemberTest(Supplier blockStateSupplier) { + Objects.requireNonNull(blockStateSupplier); + this.blockStateSupplier = blockStateSupplier; } public BlockState blockState() { - assertLoaded(); if (blockState == null) { blockState = blockStateSupplier.get(); if (blockState == null) { @@ -57,44 +57,18 @@ public BlockState blockState() { } @Override - public String typeId() { - return "state"; + public StructureMemberTestType type() { + return StructureMemberTestType.STATE; } @Override public boolean matchesState(BlockState state) { - assertLoaded(); return this.blockState() == state; } - @Override - public boolean isLoaded() { - return blockStateSupplier != null; - } - - @Override - public void load(CompoundTag tag) { - super.load(tag); - if (!tag.contains("state", Tag.TAG_COMPOUND)) { - throw new IllegalArgumentException("Invalid structure member test format for type \"" + typeId() + "\": " + tag); - } - - blockStateSupplier = () -> NbtUtils.readBlockState(BuiltInRegistries.BLOCK.asLookup(), tag.getCompound("state")); - blockState = null; - } - - @Override - public void save(CompoundTag tag) { - super.save(tag); - - tag.put("state", NbtUtils.writeBlockState(this.blockState())); - } - @Override public boolean equals(Object o) { - assertLoaded(); if (o instanceof StateStructureMemberTest other) { - other.assertLoaded(); return this.blockState() == other.blockState(); } return false; diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StructureMemberTest.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StructureMemberTest.java index e35789b99..d18e4e49d 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StructureMemberTest.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StructureMemberTest.java @@ -23,45 +23,16 @@ */ package aztech.modern_industrialization.machines.multiblocks.structure.member.test; -import java.util.Objects; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.Tag; +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; import net.minecraft.world.level.block.state.BlockState; -public abstract class StructureMemberTest { - public abstract String typeId(); +public sealed abstract class StructureMemberTest permits StateStructureMemberTest, TagStructureMemberTest { + public static final Codec CODEC = Codec.STRING.flatComapMap( + StructureMemberTestType::getType, type -> DataResult.success(type.name())) + .dispatch(test -> (StructureMemberTestType) test.type(), StructureMemberTestType::codec); - public abstract boolean matchesState(BlockState state); - - public abstract boolean isLoaded(); - - protected final void assertLoaded() { - if (!isLoaded()) { - throw new IllegalStateException("Member test is not loaded"); - } - } + public abstract StructureMemberTestType type(); - public void load(CompoundTag tag) { - Objects.requireNonNull(tag); - } - - public void save(CompoundTag tag) { - Objects.requireNonNull(tag); - assertLoaded(); - } - - public static StructureMemberTest from(CompoundTag tag) { - Objects.requireNonNull(tag); - if (!tag.contains("type", Tag.TAG_STRING)) { - throw new IllegalArgumentException("Invalid structure member test format: " + tag); - } - String type = tag.getString("type"); - StructureMemberTest test = switch (type) { - case "tag" -> new TagStructureMemberTest(); - case "state" -> new StateStructureMemberTest(); - default -> throw new IllegalStateException("Unexpected type: " + type); - }; - test.load(tag); - return test; - } + public abstract boolean matchesState(BlockState state); } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StructureMemberTestType.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StructureMemberTestType.java new file mode 100644 index 000000000..4d900cb88 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StructureMemberTestType.java @@ -0,0 +1,65 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.machines.multiblocks.structure.member.test; + +import com.google.common.collect.Maps; +import com.mojang.serialization.MapCodec; +import java.util.Map; + +public final class StructureMemberTestType { + private static final Map> TYPES = Maps.newHashMap(); + + public static final StructureMemberTestType STATE = register("state", StateStructureMemberTest.CODEC); + public static final StructureMemberTestType TAG = register("tag", TagStructureMemberTest.CODEC); + + private static StructureMemberTestType register(String name, MapCodec codec) { + var type = new StructureMemberTestType<>(name, codec); + TYPES.put(name, type); + return type; + } + + static StructureMemberTestType getType(String name) { + var type = TYPES.get(name); + if (type == null) { + throw new IllegalArgumentException("No type could be found for the name \"" + name + "\""); + } + return type; + } + + private final String name; + private final MapCodec codec; + + public StructureMemberTestType(String name, MapCodec codec) { + this.name = name; + this.codec = codec; + } + + public String name() { + return name; + } + + public MapCodec codec() { + return codec; + } +} diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/TagStructureMemberTest.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/TagStructureMemberTest.java index 8b558f496..3a4fe2e20 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/TagStructureMemberTest.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/TagStructureMemberTest.java @@ -23,68 +23,44 @@ */ package aztech.modern_industrialization.machines.multiblocks.structure.member.test; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import java.util.Objects; import net.minecraft.core.registries.Registries; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.Tag; -import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagKey; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; -public class TagStructureMemberTest extends StructureMemberTest { - private TagKey blockTag; +public final class TagStructureMemberTest extends StructureMemberTest { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance + .group( + TagKey.codec(Registries.BLOCK).fieldOf("tag").forGetter(TagStructureMemberTest::blockTag)) + .apply(instance, TagStructureMemberTest::new)); + + private final TagKey blockTag; public TagStructureMemberTest(TagKey blockTag) { Objects.requireNonNull(blockTag); this.blockTag = blockTag; } - public TagStructureMemberTest() { - } - public TagKey blockTag() { return blockTag; } @Override - public String typeId() { - return "tag"; + public StructureMemberTestType type() { + return StructureMemberTestType.TAG; } @Override public boolean matchesState(BlockState state) { - assertLoaded(); return state.is(blockTag); } - @Override - public boolean isLoaded() { - return blockTag != null; - } - - @Override - public void load(CompoundTag tag) { - super.load(tag); - if (!tag.contains("tag", Tag.TAG_STRING)) { - throw new IllegalArgumentException("Invalid structure member test format for type \"" + typeId() + "\": " + tag); - } - - blockTag = TagKey.create(Registries.BLOCK, ResourceLocation.parse(tag.getString("tag"))); - } - - @Override - public void save(CompoundTag tag) { - super.save(tag); - - tag.putString("tag", blockTag.location().toString()); - } - @Override public boolean equals(Object o) { - assertLoaded(); if (o instanceof TagStructureMemberTest other) { - other.assertLoaded(); return blockTag == other.blockTag || blockTag.location().equals(other.blockTag.location()); } diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java index 20ac59919..ddb23b0ad 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java @@ -63,7 +63,7 @@ public void handle(Context ctx) { level, pos, state.getValue(StructureMultiblockControllerBlock.FACING), controller.getCasing(), controller.getBounds()); if (result instanceof StructureResult.Success success) { - if (MIStructureTemplateManager.save(id, success.tag())) { + if (MIStructureTemplateManager.save(id, success.template())) { MIStructureTemplateManager.register(id, success.template()); } else { result = new StructureResult.Unknown(); diff --git a/src/main/java/aztech/modern_industrialization/util/MIExtraCodecs.java b/src/main/java/aztech/modern_industrialization/util/MIExtraCodecs.java index 1903f85ec..6aa37400c 100644 --- a/src/main/java/aztech/modern_industrialization/util/MIExtraCodecs.java +++ b/src/main/java/aztech/modern_industrialization/util/MIExtraCodecs.java @@ -24,12 +24,16 @@ package aztech.modern_industrialization.util; import com.mojang.datafixers.util.Either; +import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; +import com.mojang.serialization.DynamicOps; import com.mojang.serialization.MapCodec; import java.util.List; import java.util.Optional; import java.util.function.Function; +import java.util.function.Supplier; +import net.minecraft.world.level.block.state.BlockState; import net.neoforged.neoforge.common.conditions.ConditionalOps; import net.neoforged.neoforge.common.util.NeoForgeExtraCodecs; @@ -37,6 +41,17 @@ public class MIExtraCodecs { public static final Codec FLOAT_01 = Codec.floatRange(0, 1); public static final Codec NON_NEGATIVE_LONG = longRange(0, Long.MAX_VALUE); public static final Codec POSITIVE_LONG = longRange(1, Long.MAX_VALUE); + public static final Codec> LAZY_BLOCK_STATE = new Codec<>() { + @Override + public DataResult, T>> decode(DynamicOps ops, T input) { + return DataResult.success(Pair.of(() -> BlockState.CODEC.decode(ops, input).getOrThrow().getFirst(), input)); + } + + @Override + public DataResult encode(Supplier input, DynamicOps ops, T prefix) { + return BlockState.CODEC.encode(input.get(), ops, prefix); + } + }; private static > Function> checkRange(final N minInclusive, final N maxInclusive) { return value -> { From 3fa4c563fba30d60a7f7a289b18c0a94ecad7373 Mon Sep 17 00:00:00 2001 From: Swedz Date: Tue, 26 Nov 2024 22:53:43 -0500 Subject: [PATCH 49/89] Require that structure ids include [0-9a-z_:] only to prevent subdirectories --- .../StructureMultiblockControllerEditScreen.java | 4 ++-- .../StructureMultiblockControllerBlockEntity.java | 2 +- .../StructureMultiblockInputFormatters.java | 14 ++++++++++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java index 1c0b76de9..7e02b2850 100644 --- a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java @@ -80,7 +80,7 @@ public StructureMultiblockControllerEditScreen(StructureMultiblockControllerBloc } private Optional getId() { - ResourceLocation id = ResourceLocation.tryParse(idBox.getValue()); + ResourceLocation id = StructureMultiblockInputFormatters.id(idBox.getValue()); return switch (modeButton.getValue()) { case SAVE -> Optional.ofNullable(id); case LOAD -> id != null && MIStructureTemplateManager.exists(id) ? Optional.of(id) : Optional.empty(); @@ -216,7 +216,7 @@ protected void init() { idBox = new EditBox(font, width / 2 - 152, 50, 304, 20, MIText.StructureMultiblockStructureName.text()) { @Override public boolean charTyped(char codePoint, int modifiers) { - return ResourceLocation.isAllowedInResourceLocation(codePoint) && super.charTyped(codePoint, modifiers); + return StructureMultiblockInputFormatters.isValidIdCharacter(codePoint) && super.charTyped(codePoint, modifiers); } }; idBox.setMaxLength(Short.MAX_VALUE); diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlockEntity.java index 5a58fad3c..0c8c362b8 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlockEntity.java @@ -77,7 +77,7 @@ public String getInputId() { public void setInputId(String inputId) { this.inputId = inputId; - id = ResourceLocation.tryParse(inputId); + id = StructureMultiblockInputFormatters.id(inputId); } @Nullable diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockInputFormatters.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockInputFormatters.java index b11b85730..f3fbfd7d0 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockInputFormatters.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockInputFormatters.java @@ -44,6 +44,20 @@ import org.jetbrains.annotations.Nullable; public final class StructureMultiblockInputFormatters { + public static boolean isValidIdCharacter(char character) { + return (character >= '0' && character <= '9') || (character >= 'a' && character <= 'z') || character == '_' || character == ':'; + } + + @Nullable + public static ResourceLocation id(String input) { + for (char character : input.toCharArray()) { + if (!isValidIdCharacter(character)) { + return null; + } + } + return ResourceLocation.tryParse(input); + } + @Nullable public static MachineCasing casing(String input) { if (input == null || input.isEmpty()) { From f14404da1ceecd0e8b6d0ea200cab5636df76c3c Mon Sep 17 00:00:00 2001 From: Swedz Date: Tue, 26 Nov 2024 22:56:28 -0500 Subject: [PATCH 50/89] Retain mode value when resizing edit screen --- .../gui/structure/StructureMultiblockControllerEditScreen.java | 2 ++ .../gui/structure/StructureMultiblockMemberEditScreen.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java index 7e02b2850..8c378c30b 100644 --- a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java @@ -312,6 +312,7 @@ protected void setInitialFocus() { @Override public void resize(Minecraft minecraft, int width, int height) { + StructureControllerMode modeButtonValue = modeButton.getValue(); String idBoxValue = idBox.getValue(); String casingBoxValue = casingBox.getValue(); String posXBoxValue = posXBox.getValue(); @@ -324,6 +325,7 @@ public void resize(Minecraft minecraft, int width, int height) { this.init(minecraft, width, height); + modeButton.setValue(modeButtonValue); idBox.setValue(idBoxValue); casingBox.setValue(casingBoxValue); posXBox.setValue(posXBoxValue); diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java index 3bea37490..23a3d6c8d 100644 --- a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java @@ -258,6 +258,7 @@ protected void setInitialFocus() { @Override public void resize(Minecraft minecraft, int width, int height) { + StructureMemberMode modeButtonValue = modeButton.getValue(); String nameBoxValue = nameBox.getValue(); String previewBoxValue = previewBox.getValue(); String membersBoxValue = membersBox.getValue(); @@ -266,6 +267,7 @@ public void resize(Minecraft minecraft, int width, int height) { this.init(minecraft, width, height); + modeButton.setValue(modeButtonValue); nameBox.setValue(nameBoxValue); previewBox.setValue(previewBoxValue); membersBox.setValue(membersBoxValue); From 0e6241acd4afbfd6819f521f585aa6ac5f28ad2c Mon Sep 17 00:00:00 2001 From: Swedz Date: Tue, 26 Nov 2024 23:03:02 -0500 Subject: [PATCH 51/89] Accurately get width of tooltip lines --- .../ClientStructureMemberBlockTooltip.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java index 43337d89e..0dd54872c 100644 --- a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java +++ b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java @@ -73,7 +73,7 @@ public ClientStructureMemberBlockTooltip(StructureMultiblockMemberBlockItem.Tool } if (data.mode() == StructureMemberMode.HATCH) { - lines.add(Component.literal("Casing: %s".formatted(data.casing().key.getPath()))); + lines.add(Component.literal("Casing: %s".formatted(data.casing().key.toString()))); } if (data.mode() == StructureMemberMode.SIMPLE || data.mode() == StructureMemberMode.HATCH) { @@ -126,8 +126,19 @@ public int getHeight() { @Override public int getWidth(Font font) { - // TODO SWEDZ: get actual width - return 18 * 6; + int width = 0; + for (Object line : lines) { + int lineWidth = 0; + if (line instanceof Component text) { + lineWidth = font.width(text.getVisualOrderText()); + } else if (line instanceof List list) { + lineWidth = 18 * 6; + } + if (lineWidth > width) { + width = lineWidth; + } + } + return width; } private void renderRowImage(List stacks, Font font, int x, int y, GuiGraphics graphics) { From 4885763ba8e7384c8e6cf6fc27cafd4cea2dbeff Mon Sep 17 00:00:00 2001 From: Swedz Date: Tue, 26 Nov 2024 23:05:37 -0500 Subject: [PATCH 52/89] Move structure edit screens to better fitting package --- .../structure/StructureMultiblockControllerEditScreen.java | 2 +- .../structure/StructureMultiblockMemberEditScreen.java | 2 +- .../aztech/modern_industrialization/proxy/ClientProxy.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) rename src/client/java/aztech/modern_industrialization/{gui => client/screen}/structure/StructureMultiblockControllerEditScreen.java (99%) rename src/client/java/aztech/modern_industrialization/{gui => client/screen}/structure/StructureMultiblockMemberEditScreen.java (99%) diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java b/src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockControllerEditScreen.java similarity index 99% rename from src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java rename to src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockControllerEditScreen.java index 8c378c30b..903947dd9 100644 --- a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockControllerEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockControllerEditScreen.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package aztech.modern_industrialization.gui.structure; +package aztech.modern_industrialization.client.screen.structure; import aztech.modern_industrialization.MIBlock; import aztech.modern_industrialization.MIText; diff --git a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java b/src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockMemberEditScreen.java similarity index 99% rename from src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java rename to src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockMemberEditScreen.java index 23a3d6c8d..bb733d9c6 100644 --- a/src/client/java/aztech/modern_industrialization/gui/structure/StructureMultiblockMemberEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockMemberEditScreen.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package aztech.modern_industrialization.gui.structure; +package aztech.modern_industrialization.client.screen.structure; import aztech.modern_industrialization.MIBlock; import aztech.modern_industrialization.MIText; diff --git a/src/client/java/aztech/modern_industrialization/proxy/ClientProxy.java b/src/client/java/aztech/modern_industrialization/proxy/ClientProxy.java index dc058d712..d535dcd90 100644 --- a/src/client/java/aztech/modern_industrialization/proxy/ClientProxy.java +++ b/src/client/java/aztech/modern_industrialization/proxy/ClientProxy.java @@ -32,8 +32,8 @@ import aztech.modern_industrialization.blocks.structure.StructureMultiblockBER; import aztech.modern_industrialization.blocks.structure.controller.StructureMultiblockControllerBlockEntity; import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlockEntity; -import aztech.modern_industrialization.gui.structure.StructureMultiblockControllerEditScreen; -import aztech.modern_industrialization.gui.structure.StructureMultiblockMemberEditScreen; +import aztech.modern_industrialization.client.screen.structure.StructureMultiblockControllerEditScreen; +import aztech.modern_industrialization.client.screen.structure.StructureMultiblockMemberEditScreen; import aztech.modern_industrialization.items.SteamDrillHooks; import aztech.modern_industrialization.machines.gui.MachineMenuClient; import aztech.modern_industrialization.machines.gui.MachineMenuCommon; From 1bcda121ed8fc8ce5faad6754e1bfd2675ec432d Mon Sep 17 00:00:00 2001 From: Swedz Date: Tue, 26 Nov 2024 23:08:36 -0500 Subject: [PATCH 53/89] Remove unnecessary constant fields --- .../client/ClientStructureMemberBlockTooltip.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java index 0dd54872c..3a88f4802 100644 --- a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java +++ b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java @@ -45,10 +45,6 @@ import org.joml.Matrix4f; public final class ClientStructureMemberBlockTooltip implements ClientTooltipComponent { - private static final int TEXT_ROW_HEIGHT = 9; - private static final int TEXT_BEFORE_IMAGE_EXTRA_ROW_HEIGHT = 4; - private static final int IMAGE_ROW_HEIGHT = 20; - private final StructureMultiblockMemberBlockItem.TooltipData data; private final List lines = new ArrayList<>(); @@ -101,19 +97,19 @@ private int iterateLines(int startY, @Nullable BiConsumer ac if (i > 0) { Object last = lines.get(i - 1); if (line instanceof List) { - y += TEXT_BEFORE_IMAGE_EXTRA_ROW_HEIGHT; + y += 4; } } if (line instanceof Component text) { if (actionText != null) { actionText.accept(y, text); } - y += TEXT_ROW_HEIGHT; + y += 9; } else if (line instanceof List list) { if (actionStacks != null) { actionStacks.accept(y, list); } - y += IMAGE_ROW_HEIGHT; + y += 20; } } return y; From 12015ef12d598fd6566722dae712d0c84bbf0f97 Mon Sep 17 00:00:00 2001 From: Swedz Date: Tue, 26 Nov 2024 23:31:54 -0500 Subject: [PATCH 54/89] Use Lazy for the lazy blockstate codec instead of a supplier --- .../StructureMultiblockInputFormatters.java | 3 ++- .../member/HatchStructureMember.java | 6 ++--- .../member/LiteralStructureMember.java | 6 ++--- .../member/SimpleStructureMember.java | 23 ++++++------------- .../structure/member/StructureMember.java | 7 +++--- .../member/test/StateStructureMemberTest.java | 23 ++++++------------- .../util/MIExtraCodecs.java | 10 ++++---- 7 files changed, 31 insertions(+), 47 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockInputFormatters.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockInputFormatters.java index f3fbfd7d0..e3df28a83 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockInputFormatters.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockInputFormatters.java @@ -41,6 +41,7 @@ import net.minecraft.tags.BlockTags; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; +import net.neoforged.neoforge.common.util.Lazy; import org.jetbrains.annotations.Nullable; public final class StructureMultiblockInputFormatters { @@ -128,7 +129,7 @@ public static List members(String input) { } else { try { var blockResult = BlockStateParser.parseForBlock(registry, part, true); - members.add(new StateStructureMemberTest(blockResult::blockState)); + members.add(new StateStructureMemberTest(Lazy.of(blockResult::blockState))); } catch (CommandSyntaxException ignored) { return null; } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java index c3cce8a66..aaf07cf76 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java @@ -38,14 +38,14 @@ import java.util.List; import java.util.Objects; import java.util.Optional; -import java.util.function.Supplier; import net.minecraft.core.BlockPos; import net.minecraft.world.level.block.state.BlockState; +import net.neoforged.neoforge.common.util.Lazy; public final class HatchStructureMember extends SimpleStructureMember { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance .group( - MIExtraCodecs.LAZY_BLOCK_STATE.fieldOf("preview").forGetter(member -> member.previewSupplier), + MIExtraCodecs.LAZY_BLOCK_STATE.fieldOf("preview").forGetter(member -> member.preview), StructureMemberTest.CODEC.listOf().fieldOf("tests").forGetter(HatchStructureMember::tests), MachineCasing.CODEC.fieldOf("casing").forGetter(HatchStructureMember::casing), HatchFlags.CODEC.fieldOf("hatch_flags").forGetter(HatchStructureMember::hatchFlags)) @@ -54,7 +54,7 @@ public final class HatchStructureMember extends SimpleStructureMember { private final MachineCasing casing; private final HatchFlags hatchFlags; - public HatchStructureMember(Supplier previewSupplier, List tests, MachineCasing casing, HatchFlags hatchFlags) { + public HatchStructureMember(Lazy previewSupplier, List tests, MachineCasing casing, HatchFlags hatchFlags) { super(previewSupplier, tests); Objects.requireNonNull(casing); Objects.requireNonNull(hatchFlags); diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java index c73335f6c..873dedec4 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java @@ -30,15 +30,15 @@ import com.mojang.serialization.MapCodec; import java.util.List; import java.util.Optional; -import java.util.function.Supplier; import net.minecraft.core.BlockPos; import net.minecraft.world.level.block.state.BlockState; +import net.neoforged.neoforge.common.util.Lazy; public final class LiteralStructureMember extends SimpleStructureMember { public static final MapCodec CODEC = MIExtraCodecs.LAZY_BLOCK_STATE - .xmap(LiteralStructureMember::new, member -> member.previewSupplier).fieldOf("state"); + .xmap(LiteralStructureMember::new, member -> member.preview).fieldOf("state"); - public LiteralStructureMember(Supplier previewSupplier) { + public LiteralStructureMember(Lazy previewSupplier) { super(previewSupplier, List.of(new StateStructureMemberTest(previewSupplier))); } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java index 612ef686b..37b42e27d 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java @@ -37,27 +37,24 @@ import java.util.List; import java.util.Objects; import java.util.Optional; -import java.util.function.Supplier; import net.minecraft.core.BlockPos; -import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; +import net.neoforged.neoforge.common.util.Lazy; public sealed class SimpleStructureMember extends StructureMember permits HatchStructureMember, LiteralStructureMember { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance .group( - MIExtraCodecs.LAZY_BLOCK_STATE.fieldOf("preview").forGetter(member -> member.previewSupplier), + MIExtraCodecs.LAZY_BLOCK_STATE.fieldOf("preview").forGetter(member -> member.preview), StructureMemberTest.CODEC.listOf().fieldOf("tests").forGetter(SimpleStructureMember::tests)) .apply(instance, SimpleStructureMember::new)); - protected final Supplier previewSupplier; - - protected BlockState preview; + protected final Lazy preview; protected final List tests; - public SimpleStructureMember(Supplier previewSupplier, List tests) { - Objects.requireNonNull(previewSupplier); + public SimpleStructureMember(Lazy preview, List tests) { + Objects.requireNonNull(preview); Objects.requireNonNull(tests); - this.previewSupplier = previewSupplier; + this.preview = preview; this.tests = tests; } @@ -96,13 +93,7 @@ public boolean matchesState(BlockState state) { @Override public BlockState getPreviewState() { - if (preview == null) { - preview = previewSupplier.get(); - if (preview == null) { - preview = Blocks.AIR.defaultBlockState(); - } - } - return preview; + return preview.get(); } @Override diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java index c95a78918..522ad2d1b 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java @@ -36,6 +36,7 @@ import java.util.function.Supplier; import net.minecraft.core.BlockPos; import net.minecraft.world.level.block.state.BlockState; +import net.neoforged.neoforge.common.util.Lazy; public sealed abstract class StructureMember implements SimpleMember permits SimpleStructureMember, VariableStructureMember { public static final Codec CODEC = Codec.STRING.flatComapMap( @@ -47,16 +48,16 @@ public sealed abstract class StructureMember implements SimpleMember permits Sim public abstract Optional> asStructureBlock(BlockPos pos, boolean required); public static SimpleStructureMember simple(Supplier preview, List tests) { - return new SimpleStructureMember(preview, tests); + return new SimpleStructureMember(Lazy.of(preview), tests); } public static LiteralStructureMember literal(Supplier blockState) { - return new LiteralStructureMember(blockState); + return new LiteralStructureMember(Lazy.of(blockState)); } public static HatchStructureMember hatch(Supplier preview, List tests, MachineCasing casing, HatchFlags hatchFlags) { - return new HatchStructureMember(preview, tests, casing, hatchFlags); + return new HatchStructureMember(Lazy.of(preview), tests, casing, hatchFlags); } public static VariableStructureMember variable(String name) { diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StateStructureMemberTest.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StateStructureMemberTest.java index eb8da4d62..a5d7944f8 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StateStructureMemberTest.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StateStructureMemberTest.java @@ -27,33 +27,24 @@ import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import java.util.Objects; -import java.util.function.Supplier; -import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; +import net.neoforged.neoforge.common.util.Lazy; public final class StateStructureMemberTest extends StructureMemberTest { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance .group( - MIExtraCodecs.LAZY_BLOCK_STATE.fieldOf("state").forGetter(test -> test.blockStateSupplier)) + MIExtraCodecs.LAZY_BLOCK_STATE.fieldOf("state").forGetter(test -> test.blockState)) .apply(instance, StateStructureMemberTest::new)); - private final Supplier blockStateSupplier; + private final Lazy blockState; - private BlockState blockState; - - public StateStructureMemberTest(Supplier blockStateSupplier) { - Objects.requireNonNull(blockStateSupplier); - this.blockStateSupplier = blockStateSupplier; + public StateStructureMemberTest(Lazy blockState) { + Objects.requireNonNull(blockState); + this.blockState = blockState; } public BlockState blockState() { - if (blockState == null) { - blockState = blockStateSupplier.get(); - if (blockState == null) { - blockState = Blocks.AIR.defaultBlockState(); - } - } - return blockState; + return blockState.get(); } @Override diff --git a/src/main/java/aztech/modern_industrialization/util/MIExtraCodecs.java b/src/main/java/aztech/modern_industrialization/util/MIExtraCodecs.java index 6aa37400c..2e1276d29 100644 --- a/src/main/java/aztech/modern_industrialization/util/MIExtraCodecs.java +++ b/src/main/java/aztech/modern_industrialization/util/MIExtraCodecs.java @@ -32,23 +32,23 @@ import java.util.List; import java.util.Optional; import java.util.function.Function; -import java.util.function.Supplier; import net.minecraft.world.level.block.state.BlockState; import net.neoforged.neoforge.common.conditions.ConditionalOps; +import net.neoforged.neoforge.common.util.Lazy; import net.neoforged.neoforge.common.util.NeoForgeExtraCodecs; public class MIExtraCodecs { public static final Codec FLOAT_01 = Codec.floatRange(0, 1); public static final Codec NON_NEGATIVE_LONG = longRange(0, Long.MAX_VALUE); public static final Codec POSITIVE_LONG = longRange(1, Long.MAX_VALUE); - public static final Codec> LAZY_BLOCK_STATE = new Codec<>() { + public static final Codec> LAZY_BLOCK_STATE = new Codec<>() { @Override - public DataResult, T>> decode(DynamicOps ops, T input) { - return DataResult.success(Pair.of(() -> BlockState.CODEC.decode(ops, input).getOrThrow().getFirst(), input)); + public DataResult, T>> decode(DynamicOps ops, T input) { + return DataResult.success(Pair.of(Lazy.of(() -> BlockState.CODEC.decode(ops, input).getOrThrow().getFirst()), input)); } @Override - public DataResult encode(Supplier input, DynamicOps ops, T prefix) { + public DataResult encode(Lazy input, DynamicOps ops, T prefix) { return BlockState.CODEC.encode(input.get(), ops, prefix); } }; From 625cf9bc048fd4abcc5c361759b1748eaa49f2cb Mon Sep 17 00:00:00 2001 From: Swedz Date: Wed, 27 Nov 2024 00:15:44 -0500 Subject: [PATCH 55/89] Clean up lazy codec creating --- .../util/MIExtraCodecs.java | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/util/MIExtraCodecs.java b/src/main/java/aztech/modern_industrialization/util/MIExtraCodecs.java index 2e1276d29..d4167ee1d 100644 --- a/src/main/java/aztech/modern_industrialization/util/MIExtraCodecs.java +++ b/src/main/java/aztech/modern_industrialization/util/MIExtraCodecs.java @@ -41,17 +41,7 @@ public class MIExtraCodecs { public static final Codec FLOAT_01 = Codec.floatRange(0, 1); public static final Codec NON_NEGATIVE_LONG = longRange(0, Long.MAX_VALUE); public static final Codec POSITIVE_LONG = longRange(1, Long.MAX_VALUE); - public static final Codec> LAZY_BLOCK_STATE = new Codec<>() { - @Override - public DataResult, T>> decode(DynamicOps ops, T input) { - return DataResult.success(Pair.of(Lazy.of(() -> BlockState.CODEC.decode(ops, input).getOrThrow().getFirst()), input)); - } - - @Override - public DataResult encode(Lazy input, DynamicOps ops, T prefix) { - return BlockState.CODEC.encode(input.get(), ops, prefix); - } - }; + public static final Codec> LAZY_BLOCK_STATE = lazy(BlockState.CODEC); private static > Function> checkRange(final N minInclusive, final N maxInclusive) { return value -> { @@ -84,4 +74,21 @@ public static MapCodec optionalFieldAlwaysWrite(Codec baseCodec, Strin return baseCodec.optionalFieldOf(field) .xmap(read -> read.orElse(defaultValue), Optional::of); } + + /** + * A codec that wraps another codec in a Lazy object. + */ + public static Codec> lazy(Codec baseCodec) { + return new Codec<>() { + @Override + public DataResult, T>> decode(DynamicOps ops, T input) { + return DataResult.success(Pair.of(Lazy.of(() -> baseCodec.decode(ops, input).getOrThrow().getFirst()), input)); + } + + @Override + public DataResult encode(Lazy input, DynamicOps ops, T prefix) { + return baseCodec.encode(input.get(), ops, prefix); + } + }; + } } From 404d0b4316cfc12986aba40e582709587d44dc31 Mon Sep 17 00:00:00 2001 From: Swedz Date: Wed, 27 Nov 2024 04:07:27 -0500 Subject: [PATCH 56/89] Clean up structure member tooltip and make casings render as an item --- .../ClientStructureMemberBlockTooltip.java | 92 +++++++++++++------ .../util/RenderHelper.java | 18 ++++ .../StructureMultiblockMemberBlockItem.java | 6 +- 3 files changed, 85 insertions(+), 31 deletions(-) diff --git a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java index 3a88f4802..461003e97 100644 --- a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java +++ b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java @@ -26,6 +26,8 @@ import aztech.modern_industrialization.MITooltips; import aztech.modern_industrialization.blocks.structure.member.StructureMemberMode; import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlockItem; +import aztech.modern_industrialization.machines.models.MachineCasing; +import aztech.modern_industrialization.machines.multiblocks.HatchFlags; import aztech.modern_industrialization.machines.multiblocks.HatchType; import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StateStructureMemberTest; import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StructureMemberTest; @@ -41,6 +43,7 @@ import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.network.chat.Component; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.Nullable; import org.joml.Matrix4f; @@ -52,51 +55,68 @@ public final class ClientStructureMemberBlockTooltip implements ClientTooltipCom public ClientStructureMemberBlockTooltip(StructureMultiblockMemberBlockItem.TooltipData data) { this.data = data; - ItemStack preview = data.preview().getBlock().asItem().getDefaultInstance(); - - List members = new ArrayList<>(); - for (StructureMemberTest member : data.members()) { - if (member instanceof StateStructureMemberTest stateTest) { - members.add(stateTest.blockState().getBlock().asItem().getDefaultInstance()); - } - } + StructureMemberMode mode = data.mode(); // TODO SWEDZ: use translations - lines.add(Component.literal("Mode: ").append(data.mode().text())); + lines.add(Component.literal("Mode: ").append(mode.text())); - if (data.mode() == StructureMemberMode.VARIABLE) { - lines.add(Component.literal("Name: %s".formatted(data.name()))); + if (mode == StructureMemberMode.VARIABLE) { + String name = data.name(); + if (name != null && !name.isEmpty()) { + lines.add(Component.literal("Name: %s".formatted(name))); + } } - if (data.mode() == StructureMemberMode.HATCH) { - lines.add(Component.literal("Casing: %s".formatted(data.casing().key.toString()))); - } + if (mode == StructureMemberMode.SIMPLE || mode == StructureMemberMode.HATCH) { + BlockState preview = data.preview(); + if (preview != null && !preview.isAir()) { + ItemStack previewStack = preview.getBlock().asItem().getDefaultInstance(); + lines.add(Component.literal("Preview:").withStyle(ChatFormatting.UNDERLINE)); + lines.add(List.of(previewStack)); + } - if (data.mode() == StructureMemberMode.SIMPLE || data.mode() == StructureMemberMode.HATCH) { - lines.add(Component.literal("Preview").withStyle(ChatFormatting.UNDERLINE)); - lines.add(List.of(preview)); - lines.add(Component.literal("Members").withStyle(ChatFormatting.UNDERLINE)); - lines.add(members); + List members = new ArrayList<>(); + if (data.members() != null) { + for (StructureMemberTest member : data.members()) { + if (member instanceof StateStructureMemberTest stateTest) { + members.add(stateTest.blockState().getBlock().asItem().getDefaultInstance()); + } + } + } + if (!members.isEmpty()) { + lines.add(Component.literal("Members:").withStyle(ChatFormatting.UNDERLINE)); + lines.add(members); + } } - if (data.mode() == StructureMemberMode.HATCH && data.hatchFlags().flags != 0) { - lines.add(Component.literal("Hatches").withStyle(ChatFormatting.UNDERLINE)); - for (HatchType hatchType : HatchType.values()) { - if (data.hatchFlags().allows(hatchType)) { - lines.add(Component.literal("- %s".formatted(hatchType.name().toLowerCase(Locale.ROOT)))); + if (mode == StructureMemberMode.HATCH) { + MachineCasing casing = data.casing(); + if (casing != null) { + lines.add(Component.literal("Casing:").withStyle(ChatFormatting.UNDERLINE)); + lines.add(casing); + } + + HatchFlags hatchFlags = data.hatchFlags(); + if (hatchFlags != null && hatchFlags.flags != 0) { + lines.add(Component.literal("Hatches:").withStyle(ChatFormatting.UNDERLINE)); + for (HatchType hatchType : HatchType.values()) { + if (hatchFlags.allows(hatchType)) { + lines.add(Component.literal("- %s".formatted(hatchType.name().toLowerCase(Locale.ROOT)))); + } } } } } private int iterateLines(int startY, @Nullable BiConsumer actionText, - @Nullable BiConsumer> actionStacks) { + @Nullable BiConsumer> actionStacks, + @Nullable BiConsumer actionCasing) { int y = startY; for (int i = 0; i < lines.size(); i++) { Object line = lines.get(i); if (i > 0) { Object last = lines.get(i - 1); - if (line instanceof List) { + if (line instanceof List || line instanceof MachineCasing) { y += 4; } } @@ -110,6 +130,11 @@ private int iterateLines(int startY, @Nullable BiConsumer ac actionStacks.accept(y, list); } y += 20; + } else if (line instanceof MachineCasing casing) { + if (actionCasing != null) { + actionCasing.accept(y, casing); + } + y += 20; } } return y; @@ -117,7 +142,7 @@ private int iterateLines(int startY, @Nullable BiConsumer ac @Override public int getHeight() { - return iterateLines(0, null, null); + return iterateLines(0, null, null, null); } @Override @@ -127,8 +152,10 @@ public int getWidth(Font font) { int lineWidth = 0; if (line instanceof Component text) { lineWidth = font.width(text.getVisualOrderText()); - } else if (line instanceof List list) { + } else if (line instanceof List) { lineWidth = 18 * 6; + } else if (line instanceof MachineCasing) { + lineWidth = 20; } if (lineWidth > width) { width = lineWidth; @@ -147,6 +174,10 @@ private void renderRowImage(List stacks, Font font, int x, int y, Gui } } + private void renderRowImage(MachineCasing casing, Font font, int x, int y, GuiGraphics graphics) { + RenderHelper.renderMachineCasingItem(graphics, casing, x, y); + } + private void renderRowImageText(int count, Font font, int x, int y, Matrix4f matrix, MultiBufferSource.BufferSource buffer) { if (count >= 6) { font.drawInBatch(Component.literal("+ ...").withStyle(MITooltips.DEFAULT_STYLE), x + 18 * 5, y + 5, -1, true, matrix, buffer, @@ -160,12 +191,13 @@ private void renderRowText(Component text, Font font, int x, int y, Matrix4f mat @Override public void renderImage(Font font, int x, int y, GuiGraphics graphics) { - iterateLines(y, null, (lineY, stacks) -> renderRowImage(stacks, font, x, lineY, graphics)); + iterateLines(y, null, (lineY, stacks) -> renderRowImage(stacks, font, x, lineY, graphics), + (lineY, casing) -> renderRowImage(casing, font, x, lineY, graphics)); } @Override public void renderText(Font font, int x, int y, Matrix4f matrix, MultiBufferSource.BufferSource buffer) { iterateLines(y, (lineY, text) -> renderRowText(text, font, x, lineY, matrix, buffer), - (lineY, stacks) -> renderRowImageText(stacks.size(), font, x, lineY, matrix, buffer)); + (lineY, stacks) -> renderRowImageText(stacks.size(), font, x, lineY, matrix, buffer), null); } } diff --git a/src/client/java/aztech/modern_industrialization/util/RenderHelper.java b/src/client/java/aztech/modern_industrialization/util/RenderHelper.java index 2e1b6b530..f47ee06e1 100644 --- a/src/client/java/aztech/modern_industrialization/util/RenderHelper.java +++ b/src/client/java/aztech/modern_industrialization/util/RenderHelper.java @@ -26,6 +26,8 @@ import aztech.modern_industrialization.MI; import aztech.modern_industrialization.client.MIRenderTypes; import aztech.modern_industrialization.compat.sodium.SodiumCompat; +import aztech.modern_industrialization.machines.models.MachineBakedModel; +import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.thirdparty.fabricrendering.MutableQuadView; import aztech.modern_industrialization.thirdparty.fabricrendering.QuadBuffer; import aztech.modern_industrialization.thirdparty.fabricrendering.QuadEmitter; @@ -53,6 +55,7 @@ import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.resources.model.BakedModel; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.resources.ResourceLocation; @@ -60,6 +63,7 @@ import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.ItemDisplayContext; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.EntityBlock; @@ -302,4 +306,18 @@ public static void renderAndDecorateItem(GuiGraphics guiGraphics, Font font, Ite guiGraphics.renderItem(stack, x, y); guiGraphics.renderItemDecorations(font, stack, x, y, text); } + + public static void renderMachineCasingItem(GuiGraphics guiGraphics, MachineCasing casing, int x, int y) { + var renderer = Minecraft.getInstance().getItemRenderer(); + var pose = guiGraphics.pose(); + + BakedModel casingModel = MachineBakedModel.getCasingModel(casing); + + pose.pushPose(); + pose.translate(x + 8, y + 8, 150); + pose.scale(16, -16, 16); + renderer.render(Items.STONE.getDefaultInstance(), ItemDisplayContext.GUI, false, pose, guiGraphics.bufferSource(), 0xF000F0, + OverlayTexture.NO_OVERLAY, casingModel); + pose.popPose(); + } } diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlockItem.java b/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlockItem.java index 732086d8e..e73f84086 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlockItem.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlockItem.java @@ -53,7 +53,11 @@ public static StructureMemberMode getMode(ItemStack stack) { ? stack.get(DataComponents.BLOCK_ENTITY_DATA).copyTag().getString("mode") : ""; if (!modeId.isEmpty()) { - return StructureMemberMode.valueOf(modeId.toUpperCase(Locale.ROOT)); + try { + return StructureMemberMode.valueOf(modeId.toUpperCase(Locale.ROOT)); + } catch (IllegalArgumentException ignored) { + return StructureMemberMode.SIMPLE; + } } return StructureMemberMode.SIMPLE; } From 3e1e4b61a7b02bed4c10f2fbb958f65d56785aef Mon Sep 17 00:00:00 2001 From: Swedz Date: Wed, 27 Nov 2024 05:52:52 -0500 Subject: [PATCH 57/89] Structure member tooltip to use translatable text, blocks to render inline with their label, and tag members now render too --- .../ClientStructureMemberBlockTooltip.java | 264 ++++++++++++------ .../modern_industrialization/lang/en_us.json | 6 + .../modern_industrialization/MIText.java | 6 + 3 files changed, 195 insertions(+), 81 deletions(-) diff --git a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java index 461003e97..381ec3ce5 100644 --- a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java +++ b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java @@ -23,6 +23,7 @@ */ package aztech.modern_industrialization.items.client; +import aztech.modern_industrialization.MIText; import aztech.modern_industrialization.MITooltips; import aztech.modern_industrialization.blocks.structure.member.StructureMemberMode; import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlockItem; @@ -31,18 +32,23 @@ import aztech.modern_industrialization.machines.multiblocks.HatchType; import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StateStructureMemberTest; import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StructureMemberTest; +import aztech.modern_industrialization.machines.multiblocks.structure.member.test.TagStructureMemberTest; import aztech.modern_industrialization.util.RenderHelper; import java.util.ArrayList; import java.util.List; import java.util.Locale; -import java.util.function.BiConsumer; -import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.chat.Component; +import net.minecraft.tags.TagKey; +import net.minecraft.util.FormattedCharSequence; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.Nullable; import org.joml.Matrix4f; @@ -50,20 +56,19 @@ public final class ClientStructureMemberBlockTooltip implements ClientTooltipComponent { private final StructureMultiblockMemberBlockItem.TooltipData data; - private final List lines = new ArrayList<>(); + private final List lines = new ArrayList<>(); public ClientStructureMemberBlockTooltip(StructureMultiblockMemberBlockItem.TooltipData data) { this.data = data; StructureMemberMode mode = data.mode(); - // TODO SWEDZ: use translations - lines.add(Component.literal("Mode: ").append(mode.text())); + lines.add(new ComponentLine(MIText.StructureMultiblockMemberTooltipMode.text(mode.text()))); if (mode == StructureMemberMode.VARIABLE) { String name = data.name(); if (name != null && !name.isEmpty()) { - lines.add(Component.literal("Name: %s".formatted(name))); + lines.add(new ComponentLine(MIText.StructureMultiblockMemberTooltipVariableName.text(name))); } } @@ -71,92 +76,63 @@ public ClientStructureMemberBlockTooltip(StructureMultiblockMemberBlockItem.Tool BlockState preview = data.preview(); if (preview != null && !preview.isAir()) { ItemStack previewStack = preview.getBlock().asItem().getDefaultInstance(); - lines.add(Component.literal("Preview:").withStyle(ChatFormatting.UNDERLINE)); - lines.add(List.of(previewStack)); + lines.add(new ItemStacksLine(MIText.StructureMultiblockMemberTooltipPreview.text().append(" "), + List.of(new ItemStacksLine.StackEntry(previewStack)))); } - List members = new ArrayList<>(); + List members = new ArrayList<>(); if (data.members() != null) { for (StructureMemberTest member : data.members()) { if (member instanceof StateStructureMemberTest stateTest) { - members.add(stateTest.blockState().getBlock().asItem().getDefaultInstance()); + members.add(new ItemStacksLine.StackEntry(stateTest.blockState().getBlock().asItem().getDefaultInstance())); + } else if (member instanceof TagStructureMemberTest tagTest) { + members.add(new ItemStacksLine.TagEntry(tagTest.blockTag())); } } } if (!members.isEmpty()) { - lines.add(Component.literal("Members:").withStyle(ChatFormatting.UNDERLINE)); - lines.add(members); + lines.add(new ItemStacksLine(MIText.StructureMultiblockMemberTooltipMembers.text().append(" "), members)); } } if (mode == StructureMemberMode.HATCH) { MachineCasing casing = data.casing(); if (casing != null) { - lines.add(Component.literal("Casing:").withStyle(ChatFormatting.UNDERLINE)); - lines.add(casing); + lines.add(new MachineCasingLine(MIText.StructureMultiblockMemberTooltipCasing.text().append(" "), casing)); } HatchFlags hatchFlags = data.hatchFlags(); if (hatchFlags != null && hatchFlags.flags != 0) { - lines.add(Component.literal("Hatches:").withStyle(ChatFormatting.UNDERLINE)); + StringBuilder hatchText = new StringBuilder(); for (HatchType hatchType : HatchType.values()) { if (hatchFlags.allows(hatchType)) { - lines.add(Component.literal("- %s".formatted(hatchType.name().toLowerCase(Locale.ROOT)))); + if (!hatchText.isEmpty()) { + hatchText.append(", "); + } + hatchText.append(hatchType.name().toLowerCase(Locale.ROOT)); } } + lines.add(new ComponentLine(MIText.StructureMultiblockMemberTooltipHatches.text().append(" "), + Component.literal(hatchText.toString()))); } } } - private int iterateLines(int startY, @Nullable BiConsumer actionText, - @Nullable BiConsumer> actionStacks, - @Nullable BiConsumer actionCasing) { - int y = startY; - for (int i = 0; i < lines.size(); i++) { - Object line = lines.get(i); - if (i > 0) { - Object last = lines.get(i - 1); - if (line instanceof List || line instanceof MachineCasing) { - y += 4; - } - } - if (line instanceof Component text) { - if (actionText != null) { - actionText.accept(y, text); - } - y += 9; - } else if (line instanceof List list) { - if (actionStacks != null) { - actionStacks.accept(y, list); - } - y += 20; - } else if (line instanceof MachineCasing casing) { - if (actionCasing != null) { - actionCasing.accept(y, casing); - } - y += 20; - } - } - return y; - } - @Override public int getHeight() { - return iterateLines(0, null, null, null); + Font font = Minecraft.getInstance().font; + int height = 0; + for (Line line : lines) { + height += line.height(font); + } + return height; } @Override public int getWidth(Font font) { int width = 0; - for (Object line : lines) { - int lineWidth = 0; - if (line instanceof Component text) { - lineWidth = font.width(text.getVisualOrderText()); - } else if (line instanceof List) { - lineWidth = 18 * 6; - } else if (line instanceof MachineCasing) { - lineWidth = 20; - } + for (Line line : lines) { + int lineWidth = line.width(font); if (lineWidth > width) { width = lineWidth; } @@ -164,40 +140,166 @@ public int getWidth(Font font) { return width; } - private void renderRowImage(List stacks, Font font, int x, int y, GuiGraphics graphics) { - int i = 0; - for (var stack : stacks) { - RenderHelper.renderAndDecorateItem(graphics, font, stack, x + i * 18, y); - if (++i >= 5) { - break; - } + @Override + public void renderImage(Font font, int x, int y, GuiGraphics graphics) { + int lineY = y; + for (Line line : lines) { + line.renderImage(font, x, lineY, graphics); + lineY += line.height(font); } } - private void renderRowImage(MachineCasing casing, Font font, int x, int y, GuiGraphics graphics) { - RenderHelper.renderMachineCasingItem(graphics, casing, x, y); + @Override + public void renderText(Font font, int x, int y, Matrix4f matrix, MultiBufferSource.BufferSource buffer) { + int lineY = y; + for (Line line : lines) { + line.renderText(font, x, lineY, matrix, buffer); + lineY += line.height(font); + } } - private void renderRowImageText(int count, Font font, int x, int y, Matrix4f matrix, MultiBufferSource.BufferSource buffer) { - if (count >= 6) { - font.drawInBatch(Component.literal("+ ...").withStyle(MITooltips.DEFAULT_STYLE), x + 18 * 5, y + 5, -1, true, matrix, buffer, - Font.DisplayMode.NORMAL, 0, 0xF000F0); + private interface Line { + int height(Font font); + + int width(Font font); + + default void renderImage(Font font, int x, int y, GuiGraphics graphics) { + } + + default void renderText(Font font, int x, int y, Matrix4f matrix, MultiBufferSource.BufferSource buffer) { } } - private void renderRowText(Component text, Font font, int x, int y, Matrix4f matrix, MultiBufferSource.BufferSource buffer) { - font.drawInBatch(text, x, y, -1, true, matrix, buffer, Font.DisplayMode.NORMAL, 0, 0xF000F0); + private record ComponentLine(@Nullable Component label, Component text) implements Line { + public ComponentLine(Component text) { + this(null, text); + } + + // 200 is the max width used by most tooltips + private static final int MAX_WIDTH = 200; + + private Component fullText() { + return label == null ? text : label.copy().append(text); + } + + private int labelWidth(Font font) { + return label == null ? 0 : font.width(label); + } + + @Override + public int height(Font font) { + return 9 * font.split(text, MAX_WIDTH - labelWidth(font)).size(); + } + + @Override + public int width(Font font) { + return Math.min(font.width(fullText().getVisualOrderText()), MAX_WIDTH); + } + + @Override + public void renderText(Font font, int x, int y, Matrix4f matrix, MultiBufferSource.BufferSource buffer) { + if (label != null) { + font.drawInBatch(label, x, y, -1, true, matrix, buffer, Font.DisplayMode.NORMAL, 0, 0xF000F0); + } + int labelWidth = labelWidth(font); + int lineY = y; + for (FormattedCharSequence line : font.split(text, MAX_WIDTH - labelWidth)) { + int lineX = x + labelWidth; + font.drawInBatch(line, lineX, lineY, -1, true, matrix, buffer, Font.DisplayMode.NORMAL, 0, 0xF000F0); + lineY += 9; + } + } } - @Override - public void renderImage(Font font, int x, int y, GuiGraphics graphics) { - iterateLines(y, null, (lineY, stacks) -> renderRowImage(stacks, font, x, lineY, graphics), - (lineY, casing) -> renderRowImage(casing, font, x, lineY, graphics)); + private record ItemStacksLine(Component label, List entries) implements Line { + + @Override + public int height(Font font) { + return 18; + } + + @Override + public int width(Font font) { + return font.width(label) + (18 * Math.min(6, entries.size())) + (entries.size() >= 6 ? font.width(Component.literal("+ ...")) : 0); + } + + @Override + public void renderImage(Font font, int x, int y, GuiGraphics graphics) { + int i = 0; + for (var entry : entries) { + if (entry.renderImage(font, x + (i * 18) + font.width(label), y + 1, graphics)) { + if (++i >= 5) { + break; + } + } + } + } + + @Override + public void renderText(Font font, int x, int y, Matrix4f matrix, MultiBufferSource.BufferSource buffer) { + font.drawInBatch(label, x, y + 5, -1, true, matrix, buffer, Font.DisplayMode.NORMAL, 0, 0xF000F0); + + if (entries.size() >= 6) { + font.drawInBatch(Component.literal("+ ...").withStyle(MITooltips.DEFAULT_STYLE), x + (18 * 5) + 2 + font.width(label), y + 5, -1, + true, matrix, buffer, + Font.DisplayMode.NORMAL, 0, 0xF000F0); + } + } + + private interface Entry { + boolean renderImage(Font font, int x, int y, GuiGraphics graphics); + } + + private record StackEntry(ItemStack stack) implements Entry { + @Override + public boolean renderImage(Font font, int x, int y, GuiGraphics graphics) { + RenderHelper.renderAndDecorateItem(graphics, font, stack, x, y); + return true; + } + } + + private record TagEntry(TagKey tag) implements Entry { + @Override + public boolean renderImage(Font font, int x, int y, GuiGraphics graphics) { + var maybeTag = BuiltInRegistries.BLOCK.getTag(tag); + ItemStack stack; + if (maybeTag.isPresent()) { + var blocks = maybeTag.get(); + stack = blocks.get(0).value().asItem().getDefaultInstance(); + } else { + stack = Items.BARRIER.getDefaultInstance(); + } + RenderHelper.renderAndDecorateItem(graphics, font, stack, x, y); + + graphics.pose().pushPose(); + graphics.pose().translate(0, 0, 200); + graphics.drawString(font, Component.literal("#").withStyle(MITooltips.DEFAULT_STYLE), x, y, 0xFFFFFF, true); + graphics.pose().popPose(); + + return true; + } + } } - @Override - public void renderText(Font font, int x, int y, Matrix4f matrix, MultiBufferSource.BufferSource buffer) { - iterateLines(y, (lineY, text) -> renderRowText(text, font, x, lineY, matrix, buffer), - (lineY, stacks) -> renderRowImageText(stacks.size(), font, x, lineY, matrix, buffer), null); + private record MachineCasingLine(Component label, MachineCasing casing) implements Line { + @Override + public int height(Font font) { + return 18; + } + + @Override + public int width(Font font) { + return font.width(label) + 20; + } + + @Override + public void renderImage(Font font, int x, int y, GuiGraphics graphics) { + RenderHelper.renderMachineCasingItem(graphics, casing, x + font.width(label), y + 1); + } + + @Override + public void renderText(Font font, int x, int y, Matrix4f matrix, MultiBufferSource.BufferSource buffer) { + font.drawInBatch(label, x, y + 5, -1, true, matrix, buffer, Font.DisplayMode.NORMAL, 0, 0xF000F0); + } } } diff --git a/src/generated/resources/assets/modern_industrialization/lang/en_us.json b/src/generated/resources/assets/modern_industrialization/lang/en_us.json index 7cbacf350..a8bab92f5 100644 --- a/src/generated/resources/assets/modern_industrialization/lang/en_us.json +++ b/src/generated/resources/assets/modern_industrialization/lang/en_us.json @@ -1708,6 +1708,12 @@ "text.modern_industrialization.StructureMultiblockMemberModeVariable": "Variable", "text.modern_industrialization.StructureMultiblockMemberName": "Member Name", "text.modern_industrialization.StructureMultiblockMemberPreview": "Preview", + "text.modern_industrialization.StructureMultiblockMemberTooltipCasing": "Casing:", + "text.modern_industrialization.StructureMultiblockMemberTooltipHatches": "Hatches:", + "text.modern_industrialization.StructureMultiblockMemberTooltipMembers": "Members:", + "text.modern_industrialization.StructureMultiblockMemberTooltipMode": "Mode: %s", + "text.modern_industrialization.StructureMultiblockMemberTooltipPreview": "Preview:", + "text.modern_industrialization.StructureMultiblockMemberTooltipVariableName": "Name: %s", "text.modern_industrialization.StructureMultiblockSaveFailInvalidBounds": "Failed to save structure. The bounds provided are not valid.", "text.modern_industrialization.StructureMultiblockSaveFailMisconfiguredBlock": "Failed to save structure. Some blocks are not properly configured.", "text.modern_industrialization.StructureMultiblockSaveFailNoController": "Failed to save structure. No controller could be found within the bounds.", diff --git a/src/main/java/aztech/modern_industrialization/MIText.java b/src/main/java/aztech/modern_industrialization/MIText.java index cba6e3f75..f75d46672 100644 --- a/src/main/java/aztech/modern_industrialization/MIText.java +++ b/src/main/java/aztech/modern_industrialization/MIText.java @@ -258,6 +258,12 @@ public enum MIText { StructureMultiblockMemberModeInfoSimple("Simple Mode - Just a block"), StructureMultiblockMemberModeInfoHatch("Hatch Mode - Include hatches"), StructureMultiblockMemberModeInfoVariable("Variable Mode - Filled in at startup"), + StructureMultiblockMemberTooltipMode("Mode: %s"), + StructureMultiblockMemberTooltipVariableName("Name: %s"), + StructureMultiblockMemberTooltipPreview("Preview:"), + StructureMultiblockMemberTooltipMembers("Members:"), + StructureMultiblockMemberTooltipCasing("Casing:"), + StructureMultiblockMemberTooltipHatches("Hatches:"), StructureMultiblockStructureName("Structure Name"), StructureMultiblockLoadTooltip("Hold SHIFT to place actual blocks instead of structure blocks."), StructureMultiblockLoadFailInvalidId("Failed to place the structure. No id was provided."), From 02522464e3f80f27bbb79877b1361a4fafe5bfbd Mon Sep 17 00:00:00 2001 From: Swedz Date: Wed, 27 Nov 2024 06:54:35 -0500 Subject: [PATCH 58/89] Render hatch icons on structure member tooltip --- .../ClientStructureMemberBlockTooltip.java | 59 ++++++++++-------- .../textures/gui/tooltip/hatch_icons.png | Bin 0 -> 1925 bytes 2 files changed, 32 insertions(+), 27 deletions(-) create mode 100644 src/main/resources/assets/modern_industrialization/textures/gui/tooltip/hatch_icons.png diff --git a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java index 381ec3ce5..8c8e8e227 100644 --- a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java +++ b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java @@ -23,6 +23,7 @@ */ package aztech.modern_industrialization.items.client; +import aztech.modern_industrialization.MI; import aztech.modern_industrialization.MIText; import aztech.modern_industrialization.MITooltips; import aztech.modern_industrialization.blocks.structure.member.StructureMemberMode; @@ -36,7 +37,6 @@ import aztech.modern_industrialization.util.RenderHelper; import java.util.ArrayList; import java.util.List; -import java.util.Locale; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; @@ -44,6 +44,7 @@ import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagKey; import net.minecraft.util.FormattedCharSequence; import net.minecraft.world.item.ItemStack; @@ -54,6 +55,8 @@ import org.joml.Matrix4f; public final class ClientStructureMemberBlockTooltip implements ClientTooltipComponent { + private static final ResourceLocation HATCH_ICON_ATLAS = MI.id("textures/gui/tooltip/hatch_icons.png"); + private final StructureMultiblockMemberBlockItem.TooltipData data; private final List lines = new ArrayList<>(); @@ -76,22 +79,22 @@ public ClientStructureMemberBlockTooltip(StructureMultiblockMemberBlockItem.Tool BlockState preview = data.preview(); if (preview != null && !preview.isAir()) { ItemStack previewStack = preview.getBlock().asItem().getDefaultInstance(); - lines.add(new ItemStacksLine(MIText.StructureMultiblockMemberTooltipPreview.text().append(" "), - List.of(new ItemStacksLine.StackEntry(previewStack)))); + lines.add(new IconsLine(MIText.StructureMultiblockMemberTooltipPreview.text().append(" "), + List.of(new IconsLine.StackEntry(previewStack)), 6)); } - List members = new ArrayList<>(); + List members = new ArrayList<>(); if (data.members() != null) { for (StructureMemberTest member : data.members()) { if (member instanceof StateStructureMemberTest stateTest) { - members.add(new ItemStacksLine.StackEntry(stateTest.blockState().getBlock().asItem().getDefaultInstance())); + members.add(new IconsLine.StackEntry(stateTest.blockState().getBlock().asItem().getDefaultInstance())); } else if (member instanceof TagStructureMemberTest tagTest) { - members.add(new ItemStacksLine.TagEntry(tagTest.blockTag())); + members.add(new IconsLine.TagEntry(tagTest.blockTag())); } } } if (!members.isEmpty()) { - lines.add(new ItemStacksLine(MIText.StructureMultiblockMemberTooltipMembers.text().append(" "), members)); + lines.add(new IconsLine(MIText.StructureMultiblockMemberTooltipMembers.text().append(" "), members, 6)); } } @@ -103,17 +106,13 @@ public ClientStructureMemberBlockTooltip(StructureMultiblockMemberBlockItem.Tool HatchFlags hatchFlags = data.hatchFlags(); if (hatchFlags != null && hatchFlags.flags != 0) { - StringBuilder hatchText = new StringBuilder(); + List hatches = new ArrayList<>(); for (HatchType hatchType : HatchType.values()) { if (hatchFlags.allows(hatchType)) { - if (!hatchText.isEmpty()) { - hatchText.append(", "); - } - hatchText.append(hatchType.name().toLowerCase(Locale.ROOT)); + hatches.add(new IconsLine.HatchEntry(hatchType)); } } - lines.add(new ComponentLine(MIText.StructureMultiblockMemberTooltipHatches.text().append(" "), - Component.literal(hatchText.toString()))); + lines.add(new IconsLine(MIText.StructureMultiblockMemberTooltipHatches.text().append(" "), hatches, 9)); } } } @@ -211,7 +210,7 @@ public void renderText(Font font, int x, int y, Matrix4f matrix, MultiBufferSour } } - private record ItemStacksLine(Component label, List entries) implements Line { + private record IconsLine(Component label, List entries, int maxToDisplay) implements Line { @Override public int height(Font font) { @@ -220,17 +219,17 @@ public int height(Font font) { @Override public int width(Font font) { - return font.width(label) + (18 * Math.min(6, entries.size())) + (entries.size() >= 6 ? font.width(Component.literal("+ ...")) : 0); + return font.width(label) + (18 * Math.min(maxToDisplay, entries.size())) + + (entries.size() > maxToDisplay ? font.width(Component.literal("+ ...")) : 0); } @Override public void renderImage(Font font, int x, int y, GuiGraphics graphics) { int i = 0; for (var entry : entries) { - if (entry.renderImage(font, x + (i * 18) + font.width(label), y + 1, graphics)) { - if (++i >= 5) { - break; - } + entry.renderImage(font, x + (i * 18) + font.width(label), y + 1, graphics); + if (++i >= maxToDisplay) { + break; } } } @@ -239,28 +238,28 @@ public void renderImage(Font font, int x, int y, GuiGraphics graphics) { public void renderText(Font font, int x, int y, Matrix4f matrix, MultiBufferSource.BufferSource buffer) { font.drawInBatch(label, x, y + 5, -1, true, matrix, buffer, Font.DisplayMode.NORMAL, 0, 0xF000F0); - if (entries.size() >= 6) { - font.drawInBatch(Component.literal("+ ...").withStyle(MITooltips.DEFAULT_STYLE), x + (18 * 5) + 2 + font.width(label), y + 5, -1, + if (entries.size() > maxToDisplay) { + font.drawInBatch(Component.literal("+ ...").withStyle(MITooltips.DEFAULT_STYLE), x + (18 * maxToDisplay) + 2 + font.width(label), + y + 5, -1, true, matrix, buffer, Font.DisplayMode.NORMAL, 0, 0xF000F0); } } private interface Entry { - boolean renderImage(Font font, int x, int y, GuiGraphics graphics); + void renderImage(Font font, int x, int y, GuiGraphics graphics); } private record StackEntry(ItemStack stack) implements Entry { @Override - public boolean renderImage(Font font, int x, int y, GuiGraphics graphics) { + public void renderImage(Font font, int x, int y, GuiGraphics graphics) { RenderHelper.renderAndDecorateItem(graphics, font, stack, x, y); - return true; } } private record TagEntry(TagKey tag) implements Entry { @Override - public boolean renderImage(Font font, int x, int y, GuiGraphics graphics) { + public void renderImage(Font font, int x, int y, GuiGraphics graphics) { var maybeTag = BuiltInRegistries.BLOCK.getTag(tag); ItemStack stack; if (maybeTag.isPresent()) { @@ -275,8 +274,14 @@ public boolean renderImage(Font font, int x, int y, GuiGraphics graphics) { graphics.pose().translate(0, 0, 200); graphics.drawString(font, Component.literal("#").withStyle(MITooltips.DEFAULT_STYLE), x, y, 0xFFFFFF, true); graphics.pose().popPose(); + } + } - return true; + private record HatchEntry(HatchType type) implements Entry { + @Override + public void renderImage(Font font, int x, int y, GuiGraphics graphics) { + int u = type.getId() * 16; + graphics.blit(HATCH_ICON_ATLAS, x, y, u, 0, 16, 16); } } } diff --git a/src/main/resources/assets/modern_industrialization/textures/gui/tooltip/hatch_icons.png b/src/main/resources/assets/modern_industrialization/textures/gui/tooltip/hatch_icons.png new file mode 100644 index 0000000000000000000000000000000000000000..82de11274b5eab97032504be4faeb14b3a0fb314 GIT binary patch literal 1925 zcmeHHYfO^|6#eKxv4A|XfD$5fj^`>!8Fm!3k;0IGyoCr@P(d(M9)(h*p=APVCJHiz zQi>}96?}l54`6~!B!F7!rvi3WEJA53h4!Ns`caDQ*dMch`@fi+n|toL$^CI|a(;=4 z3bR5wA^`xf3O^7M2LL7;)C4f!w9!(@9Va%1ijxFFOgMqy5<|{Aagvk?03Kj{U4%zS ztkVd??@8O>WAwN4-n`bzjO(blOCufI(NnZhOMh5U1U(sv6M0$Go)~(BgTX~Ncpq)69CIDDQ#s^DCwI?nmY79(5#vdjiO;#T8xB9)E7>Qn z@=2NJ3f$PiL+MqSn7R3eN&8_}FMS=xU_Xs_^(Lh98)vtns;gA`SjJLc3U*SMasV0H zqIjwi<625B2KMZQG%qv*H7&EY-ixhx8c+eX=GouZmSv|h@A6wukcM=dzQ@lMg~3;m z?7;*iF?x<;_oB#(QdlLXYXb%<8jJi3%=&0A*bR$14AkYRRDynVM#z9kYB2dXQY8kn z@s%z42M!kkfF1dtG9hNBNC3dBBRph(LJ3j%7FFv++4g8=$JU6rs_Ur1y7w_(n_f#R zk1p?ZQJ>oTYr@i&RfNB}2Quu;&cTV6ru4cnd2Y}1Q`9VKu{Kym2QQL}uZdu86O2_- zXvGBu1=iUQ?91D^m&a}lO1M6PL>8+-z*tqocV)&^<;{x%25k=n8^?xMrj4(3Feo20 zt}NcuSnmjG^f!K#@^ds(`|=RG(U62`?Q*;_ztblTQ+s*1tBRDC>U|A!kY%%O74Ua^Gm=pwG0~du^ZPqeXXkA=J5{ zINL|c0iu3i z&lzo|oRy{p%5KG@jcdg(C&37MJLcq)(K_Jr=LmFIE6A#7DMSK2&%NQl#?(a@{RJCm|wVJ+~J9 zk*QbbaIb^T7~@k1MpsvtB`gu{i|67q4BScmo6k4%&U*0pDGbC98L{%FLK&(WCv5i1 zI~HpMrA*HhBQpP)xl`e5&z+N_^CjBFYF#6JH%@umdk0$#TNr|0NH-QYBBRStZ?vK^5-!^g3@zB6LebJP54O zdo7K8^uEm19} Date: Wed, 27 Nov 2024 07:00:22 -0500 Subject: [PATCH 59/89] Account for liquid blocks in the member tooltip --- .../client/ClientStructureMemberBlockTooltip.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java index 8c8e8e227..ab487bb54 100644 --- a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java +++ b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java @@ -50,6 +50,7 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.LiquidBlock; import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.Nullable; import org.joml.Matrix4f; @@ -87,7 +88,17 @@ public ClientStructureMemberBlockTooltip(StructureMultiblockMemberBlockItem.Tool if (data.members() != null) { for (StructureMemberTest member : data.members()) { if (member instanceof StateStructureMemberTest stateTest) { - members.add(new IconsLine.StackEntry(stateTest.blockState().getBlock().asItem().getDefaultInstance())); + Block block = stateTest.blockState().getBlock(); + ItemStack stack; + if (block instanceof LiquidBlock liquidBlock) { + stack = liquidBlock.fluid.getBucket().getDefaultInstance(); + } else { + stack = block.asItem().getDefaultInstance(); + if (stack.isEmpty()) { + stack = Items.BUCKET.getDefaultInstance(); + } + } + members.add(new IconsLine.StackEntry(stack)); } else if (member instanceof TagStructureMemberTest tagTest) { members.add(new IconsLine.TagEntry(tagTest.blockTag())); } From 502f3680418e4d4028f1f9c537165def6c1748c0 Mon Sep 17 00:00:00 2001 From: Swedz Date: Wed, 27 Nov 2024 08:42:03 -0500 Subject: [PATCH 60/89] Include casing id in the tooltip --- .../items/client/ClientStructureMemberBlockTooltip.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java index ab487bb54..fe1692913 100644 --- a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java +++ b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java @@ -305,7 +305,7 @@ public int height(Font font) { @Override public int width(Font font) { - return font.width(label) + 20; + return font.width(label) + 20 + font.width(Component.literal(casing.key.toString())); } @Override @@ -316,6 +316,9 @@ public void renderImage(Font font, int x, int y, GuiGraphics graphics) { @Override public void renderText(Font font, int x, int y, Matrix4f matrix, MultiBufferSource.BufferSource buffer) { font.drawInBatch(label, x, y + 5, -1, true, matrix, buffer, Font.DisplayMode.NORMAL, 0, 0xF000F0); + + font.drawInBatch(Component.literal(casing.key.toString()), x + font.width(label) + 20, y + 5, -1, true, matrix, buffer, + Font.DisplayMode.NORMAL, 0, 0xF000F0); } } } From 574d9b96155f517ea314c3a03a3c6923ab889ec4 Mon Sep 17 00:00:00 2001 From: Swedz Date: Wed, 27 Nov 2024 10:08:34 -0500 Subject: [PATCH 61/89] Merge "Make machine model api more extensible" (#945) --- docs/ADDING_MACHINES.md | 6 +-- .../machines/models/MachineOverlaysJson.java | 3 -- .../modern_industrialization/lang/en_us.json | 23 ++++++++++ .../api/energy/CableTier.java | 2 +- .../machine/RegisterCasingsEventJS.java | 15 +++---- .../translation/TranslationProvider.java | 6 +++ .../machines/models/MachineCasing.java | 9 ++++ .../machines/models/MachineCasings.java | 44 ++++++++++--------- 8 files changed, 71 insertions(+), 37 deletions(-) diff --git a/docs/ADDING_MACHINES.md b/docs/ADDING_MACHINES.md index a3196abaa..2f1238780 100644 --- a/docs/ADDING_MACHINES.md +++ b/docs/ADDING_MACHINES.md @@ -327,12 +327,12 @@ remember that the top, side and bottom textures of a casing must be `modern_indu For example: ```js MIMachineEvents.registerCasings(event => { - // Register two casings. + // Register a casing. // This doesn't register any model! Either add models or add the top/side/bottom textures. - event.register("my_fancy_casing", "my_other_casing"); + event.register("fancy_casing", "Fancy"); // This registers a new casing with the same model as a diamond block! - event.registerBlockImitation("my_diamond_casing", "minecraft:diamond_block"); + event.registerBlockImitation("diamond_casing", "Diamond", "minecraft:diamond_block"); }) ``` diff --git a/src/client/java/aztech/modern_industrialization/machines/models/MachineOverlaysJson.java b/src/client/java/aztech/modern_industrialization/machines/models/MachineOverlaysJson.java index 4ea8cca2e..d5c508e15 100644 --- a/src/client/java/aztech/modern_industrialization/machines/models/MachineOverlaysJson.java +++ b/src/client/java/aztech/modern_industrialization/machines/models/MachineOverlaysJson.java @@ -56,9 +56,6 @@ static O parse(Class clazz, JsonObject json, return overlays; } - /** - * Select first non-null id, and convert it to a sprite id. - */ default Material select(ResourceLocation... candidates) { for (ResourceLocation id : candidates) { if (id != null) { diff --git a/src/generated/resources/assets/modern_industrialization/lang/en_us.json b/src/generated/resources/assets/modern_industrialization/lang/en_us.json index a8bab92f5..dd138ba8f 100644 --- a/src/generated/resources/assets/modern_industrialization/lang/en_us.json +++ b/src/generated/resources/assets/modern_industrialization/lang/en_us.json @@ -1092,6 +1092,29 @@ "key.categories.modern_industrialization.modern_industrialization": "Modern Industrialization", "key.modern_industrialization.toggle_3x3": "Toggle 3x3 Mining", "key.modern_industrialization.toggle_flight": "Toggle Flight", + "machine_casing.modern_industrialization.bricked_bronze": "Bricked Bronze", + "machine_casing.modern_industrialization.bricked_steel": "Bricked Steel", + "machine_casing.modern_industrialization.bricks": "Bricks", + "machine_casing.modern_industrialization.bronze": "Bronze", + "machine_casing.modern_industrialization.bronze_plated_bricks": "Bronze Plated Bricks", + "machine_casing.modern_industrialization.clean_stainless_steel_machine_casing": "Clean Stainless Steel", + "machine_casing.modern_industrialization.configurable_tank": "Configurable Tank", + "machine_casing.modern_industrialization.ev": "EV", + "machine_casing.modern_industrialization.firebricks": "Firebricks", + "machine_casing.modern_industrialization.frostproof_machine_casing": "Frostproof", + "machine_casing.modern_industrialization.heatproof_machine_casing": "Heatproof", + "machine_casing.modern_industrialization.hv": "HV", + "machine_casing.modern_industrialization.lv": "LV", + "machine_casing.modern_industrialization.mv": "MV", + "machine_casing.modern_industrialization.nuclear_casing": "Nuclear", + "machine_casing.modern_industrialization.plasma_handling_iridium_machine_casing": "Plasma Handling Iridium", + "machine_casing.modern_industrialization.solid_titanium_machine_casing": "Solid Titanium", + "machine_casing.modern_industrialization.stainless_steel_machine_casing_pipe": "Stainless Steel Pipe", + "machine_casing.modern_industrialization.steel": "Steel", + "machine_casing.modern_industrialization.steel_crate": "Steel Crate", + "machine_casing.modern_industrialization.superconductor": "Superconductor", + "machine_casing.modern_industrialization.titanium": "Titanium", + "machine_casing.modern_industrialization.titanium_machine_casing_pipe": "Titanium Pipe", "rei_categories.modern_industrialization.assembler": "Assembler", "rei_categories.modern_industrialization.bronze_compressor": "Compressor", "rei_categories.modern_industrialization.bronze_cutting_machine": "Cutting Machine", diff --git a/src/main/java/aztech/modern_industrialization/api/energy/CableTier.java b/src/main/java/aztech/modern_industrialization/api/energy/CableTier.java index 4f85f2f4c..6a1c12f5a 100644 --- a/src/main/java/aztech/modern_industrialization/api/energy/CableTier.java +++ b/src/main/java/aztech/modern_industrialization/api/energy/CableTier.java @@ -83,7 +83,7 @@ public CableTier(String name, String shortEnglishName, String longEnglishName, l this.longEnglishName = longEnglishName; this.eu = eu; this.itemKey = itemKey; - this.casing = MachineCasings.create(name); + this.casing = MachineCasings.create(name, shortEnglishName); this.builtin = builtin; } diff --git a/src/main/java/aztech/modern_industrialization/compat/kubejs/machine/RegisterCasingsEventJS.java b/src/main/java/aztech/modern_industrialization/compat/kubejs/machine/RegisterCasingsEventJS.java index 884fd2f34..0d4595442 100644 --- a/src/main/java/aztech/modern_industrialization/compat/kubejs/machine/RegisterCasingsEventJS.java +++ b/src/main/java/aztech/modern_industrialization/compat/kubejs/machine/RegisterCasingsEventJS.java @@ -30,22 +30,19 @@ import net.minecraft.resources.ResourceLocation; public class RegisterCasingsEventJS implements KubeEvent { - public void register(String... names) { - for (var name : names) { - if (name.contains(":")) { - throw new IllegalArgumentException("Casing name cannot contain ':'."); - } - - MachineCasings.create(name); + public void register(String name, String englishName) { + if (name.contains(":")) { + throw new IllegalArgumentException("Casing name cannot contain ':'."); } + MachineCasings.create(name, englishName); } - public void registerBlockImitation(String name, ResourceLocation block) { + public void registerBlockImitation(String name, String englishName, ResourceLocation block) { Objects.requireNonNull(block, "block may not be null"); if (name.contains(":")) { throw new IllegalArgumentException("Casing name cannot contain ':'."); } - MachineCasingImitations.imitationsToGenerate.put(MachineCasings.create(name), block); + MachineCasingImitations.imitationsToGenerate.put(MachineCasings.create(name, englishName), block); } } diff --git a/src/main/java/aztech/modern_industrialization/datagen/translation/TranslationProvider.java b/src/main/java/aztech/modern_industrialization/datagen/translation/TranslationProvider.java index dfeb2d4ec..337fd40e0 100644 --- a/src/main/java/aztech/modern_industrialization/datagen/translation/TranslationProvider.java +++ b/src/main/java/aztech/modern_industrialization/datagen/translation/TranslationProvider.java @@ -32,6 +32,7 @@ import aztech.modern_industrialization.datagen.tag.TagsToGenerate; import aztech.modern_industrialization.definition.Definition; import aztech.modern_industrialization.machines.blockentities.multiblocks.ElectricBlastFurnaceBlockEntity; +import aztech.modern_industrialization.machines.models.MachineCasings; import com.google.common.hash.Hashing; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -132,6 +133,11 @@ private void collectTranslationEntries() { addTranslation(cableTier.shortEnglishKey(), cableTier.shortEnglishName); addTranslation(cableTier.longEnglishKey(), cableTier.longEnglishName); } + + for (var casing : MachineCasings.registeredCasings.values()) { + var englishName = MachineCasings.casingNames.get(casing.key); + addTranslation(casing.getTranslationKey(), englishName); + } } @Override diff --git a/src/main/java/aztech/modern_industrialization/machines/models/MachineCasing.java b/src/main/java/aztech/modern_industrialization/machines/models/MachineCasing.java index 5fb7db7ce..b1ef132b0 100644 --- a/src/main/java/aztech/modern_industrialization/machines/models/MachineCasing.java +++ b/src/main/java/aztech/modern_industrialization/machines/models/MachineCasing.java @@ -24,6 +24,7 @@ package aztech.modern_industrialization.machines.models; import com.mojang.serialization.Codec; +import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; public class MachineCasing { @@ -35,6 +36,14 @@ public class MachineCasing { this.key = key; } + public String getTranslationKey() { + return "machine_casing.%s.%s".formatted(key.getNamespace(), key.getPath()); + } + + public Component getDisplayName() { + return Component.translatable(getTranslationKey()); + } + @Override public boolean equals(Object o) { return o instanceof MachineCasing other && key.equals(other.key); diff --git a/src/main/java/aztech/modern_industrialization/machines/models/MachineCasings.java b/src/main/java/aztech/modern_industrialization/machines/models/MachineCasings.java index ae5c9a324..767b006be 100644 --- a/src/main/java/aztech/modern_industrialization/machines/models/MachineCasings.java +++ b/src/main/java/aztech/modern_industrialization/machines/models/MachineCasings.java @@ -32,42 +32,44 @@ public class MachineCasings { public static final Map registeredCasings = new HashMap<>(); + public static final Map casingNames = new HashMap<>(); - public static final MachineCasing BRICKED_BRONZE = create("bricked_bronze"); - public static final MachineCasing BRICKED_STEEL = create("bricked_steel"); - public static final MachineCasing BRICKS = create("bricks"); - public static final MachineCasing BRONZE = create("bronze"); - public static final MachineCasing BRONZE_PLATED_BRICKS = create("bronze_plated_bricks"); - public static final MachineCasing CLEAN_STAINLESS_STEEL = create("clean_stainless_steel_machine_casing"); - public static final MachineCasing CONFIGURABLE_TANK = create("configurable_tank"); - public static final MachineCasing STAINLESS_STEEL_PIPE = create("stainless_steel_machine_casing_pipe"); - public static final MachineCasing FIREBRICKS = create("firebricks"); - public static final MachineCasing FROSTPROOF = create("frostproof_machine_casing"); - public static final MachineCasing HEATPROOF = create("heatproof_machine_casing"); - public static final MachineCasing STEEL = create("steel"); - public static final MachineCasing STEEL_CRATE = create("steel_crate"); - public static final MachineCasing TITANIUM = create("titanium"); - public static final MachineCasing TITANIUM_PIPE = create("titanium_machine_casing_pipe"); - public static final MachineCasing SOLID_TITANIUM = create("solid_titanium_machine_casing"); - public static final MachineCasing NUCLEAR = create("nuclear_casing"); - public static final MachineCasing PLASMA_HANDLING_IRIDIUM = create("plasma_handling_iridium_machine_casing"); + public static final MachineCasing BRICKED_BRONZE = create("bricked_bronze", "Bricked Bronze"); + public static final MachineCasing BRICKED_STEEL = create("bricked_steel", "Bricked Steel"); + public static final MachineCasing BRICKS = create("bricks", "Bricks"); + public static final MachineCasing BRONZE = create("bronze", "Bronze"); + public static final MachineCasing BRONZE_PLATED_BRICKS = create("bronze_plated_bricks", "Bronze Plated Bricks"); + public static final MachineCasing CLEAN_STAINLESS_STEEL = create("clean_stainless_steel_machine_casing", "Clean Stainless Steel"); + public static final MachineCasing CONFIGURABLE_TANK = create("configurable_tank", "Configurable Tank"); + public static final MachineCasing STAINLESS_STEEL_PIPE = create("stainless_steel_machine_casing_pipe", "Stainless Steel Pipe"); + public static final MachineCasing FIREBRICKS = create("firebricks", "Firebricks"); + public static final MachineCasing FROSTPROOF = create("frostproof_machine_casing", "Frostproof"); + public static final MachineCasing HEATPROOF = create("heatproof_machine_casing", "Heatproof"); + public static final MachineCasing STEEL = create("steel", "Steel"); + public static final MachineCasing STEEL_CRATE = create("steel_crate", "Steel Crate"); + public static final MachineCasing TITANIUM = create("titanium", "Titanium"); + public static final MachineCasing TITANIUM_PIPE = create("titanium_machine_casing_pipe", "Titanium Pipe"); + public static final MachineCasing SOLID_TITANIUM = create("solid_titanium_machine_casing", "Solid Titanium"); + public static final MachineCasing NUCLEAR = create("nuclear_casing", "Nuclear"); + public static final MachineCasing PLASMA_HANDLING_IRIDIUM = create("plasma_handling_iridium_machine_casing", "Plasma Handling Iridium"); static { KubeJSProxy.instance.fireRegisterMachineCasingsEvent(); } - public static MachineCasing create(ResourceLocation key) { + public static MachineCasing create(ResourceLocation key, String englishName) { if (registeredCasings.containsKey(key)) { throw new IllegalArgumentException("Duplicate machine casing definition: " + key); } MachineCasing casing = new MachineCasing(key); registeredCasings.put(key, casing); + casingNames.put(key, englishName); return casing; } - public static MachineCasing create(String name) { - return create(MI.id(name)); + public static MachineCasing create(String name, String englishName) { + return create(MI.id(name), englishName); } public static MachineCasing get(ResourceLocation key) { From c3c9a9230235a8759707e175f5e985f5a7249eeb Mon Sep 17 00:00:00 2001 From: Swedz Date: Wed, 27 Nov 2024 10:18:24 -0500 Subject: [PATCH 62/89] Use machine casing translations instead of casing id --- .../items/client/ClientStructureMemberBlockTooltip.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java index fe1692913..97fbbdcbd 100644 --- a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java +++ b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java @@ -305,7 +305,7 @@ public int height(Font font) { @Override public int width(Font font) { - return font.width(label) + 20 + font.width(Component.literal(casing.key.toString())); + return font.width(label) + 20 + font.width(casing.getDisplayName()); } @Override @@ -317,8 +317,8 @@ public void renderImage(Font font, int x, int y, GuiGraphics graphics) { public void renderText(Font font, int x, int y, Matrix4f matrix, MultiBufferSource.BufferSource buffer) { font.drawInBatch(label, x, y + 5, -1, true, matrix, buffer, Font.DisplayMode.NORMAL, 0, 0xF000F0); - font.drawInBatch(Component.literal(casing.key.toString()), x + font.width(label) + 20, y + 5, -1, true, matrix, buffer, - Font.DisplayMode.NORMAL, 0, 0xF000F0); + font.drawInBatch(casing.getDisplayName().copy().withStyle(MITooltips.DEFAULT_STYLE), x + font.width(label) + 20, y + 5, -1, true, matrix, buffer, Font.DisplayMode.NORMAL, 0, + 0xF000F0); } } } From 93aeb3bd21757f4949b9161411a131d64a68df80 Mon Sep 17 00:00:00 2001 From: Swedz Date: Wed, 27 Nov 2024 10:40:00 -0500 Subject: [PATCH 63/89] Merge "Make machine model api more extensible" (#945) --- .../machines/models/MachineCasing.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/aztech/modern_industrialization/machines/models/MachineCasing.java b/src/main/java/aztech/modern_industrialization/machines/models/MachineCasing.java index b1ef132b0..bc99fef4f 100644 --- a/src/main/java/aztech/modern_industrialization/machines/models/MachineCasing.java +++ b/src/main/java/aztech/modern_industrialization/machines/models/MachineCasing.java @@ -25,6 +25,7 @@ import com.mojang.serialization.Codec; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; import net.minecraft.resources.ResourceLocation; public class MachineCasing { @@ -40,7 +41,7 @@ public String getTranslationKey() { return "machine_casing.%s.%s".formatted(key.getNamespace(), key.getPath()); } - public Component getDisplayName() { + public MutableComponent getDisplayName() { return Component.translatable(getTranslationKey()); } From 6cda56001fc2a1de92996062eca8d5706dd07ed0 Mon Sep 17 00:00:00 2001 From: Swedz Date: Wed, 27 Nov 2024 10:44:48 -0500 Subject: [PATCH 64/89] Adjust text colors to be more consistent with other tooltips --- .../ClientStructureMemberBlockTooltip.java | 34 +++++++++++-------- .../structure/member/StructureMemberMode.java | 6 ++-- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java index 97fbbdcbd..f6cbd6e8f 100644 --- a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java +++ b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java @@ -44,6 +44,7 @@ import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagKey; import net.minecraft.util.FormattedCharSequence; @@ -67,12 +68,14 @@ public ClientStructureMemberBlockTooltip(StructureMultiblockMemberBlockItem.Tool StructureMemberMode mode = data.mode(); - lines.add(new ComponentLine(MIText.StructureMultiblockMemberTooltipMode.text(mode.text()))); + lines.add(new ComponentLine(MIText.StructureMultiblockMemberTooltipMode.text(mode.text().withStyle(MITooltips.HIGHLIGHT_STYLE)) + .withStyle(MITooltips.DEFAULT_STYLE))); if (mode == StructureMemberMode.VARIABLE) { String name = data.name(); if (name != null && !name.isEmpty()) { - lines.add(new ComponentLine(MIText.StructureMultiblockMemberTooltipVariableName.text(name))); + lines.add(new ComponentLine(MIText.StructureMultiblockMemberTooltipVariableName + .text(Component.literal(name).withStyle(MITooltips.HIGHLIGHT_STYLE)).withStyle(MITooltips.DEFAULT_STYLE))); } } @@ -80,7 +83,7 @@ public ClientStructureMemberBlockTooltip(StructureMultiblockMemberBlockItem.Tool BlockState preview = data.preview(); if (preview != null && !preview.isAir()) { ItemStack previewStack = preview.getBlock().asItem().getDefaultInstance(); - lines.add(new IconsLine(MIText.StructureMultiblockMemberTooltipPreview.text().append(" "), + lines.add(new IconsLine(MIText.StructureMultiblockMemberTooltipPreview.text().append(" ").withStyle(MITooltips.DEFAULT_STYLE), List.of(new IconsLine.StackEntry(previewStack)), 6)); } @@ -105,14 +108,16 @@ public ClientStructureMemberBlockTooltip(StructureMultiblockMemberBlockItem.Tool } } if (!members.isEmpty()) { - lines.add(new IconsLine(MIText.StructureMultiblockMemberTooltipMembers.text().append(" "), members, 6)); + lines.add(new IconsLine(MIText.StructureMultiblockMemberTooltipMembers.text().append(" ").withStyle(MITooltips.DEFAULT_STYLE), + members, 6)); } } if (mode == StructureMemberMode.HATCH) { MachineCasing casing = data.casing(); if (casing != null) { - lines.add(new MachineCasingLine(MIText.StructureMultiblockMemberTooltipCasing.text().append(" "), casing)); + lines.add(new MachineCasingLine(MIText.StructureMultiblockMemberTooltipCasing.text().append(" ").withStyle(MITooltips.DEFAULT_STYLE), + casing)); } HatchFlags hatchFlags = data.hatchFlags(); @@ -123,7 +128,8 @@ public ClientStructureMemberBlockTooltip(StructureMultiblockMemberBlockItem.Tool hatches.add(new IconsLine.HatchEntry(hatchType)); } } - lines.add(new IconsLine(MIText.StructureMultiblockMemberTooltipHatches.text().append(" "), hatches, 9)); + lines.add(new IconsLine(MIText.StructureMultiblockMemberTooltipHatches.text().append(" ").withStyle(MITooltips.DEFAULT_STYLE), + hatches, 9)); } } } @@ -180,8 +186,8 @@ default void renderText(Font font, int x, int y, Matrix4f matrix, MultiBufferSou } } - private record ComponentLine(@Nullable Component label, Component text) implements Line { - public ComponentLine(Component text) { + private record ComponentLine(@Nullable MutableComponent label, MutableComponent text) implements Line { + public ComponentLine(MutableComponent text) { this(null, text); } @@ -189,7 +195,7 @@ public ComponentLine(Component text) { private static final int MAX_WIDTH = 200; private Component fullText() { - return label == null ? text : label.copy().append(text); + return label == null ? text : label.append(text); } private int labelWidth(Font font) { @@ -221,7 +227,7 @@ public void renderText(Font font, int x, int y, Matrix4f matrix, MultiBufferSour } } - private record IconsLine(Component label, List entries, int maxToDisplay) implements Line { + private record IconsLine(MutableComponent label, List entries, int maxToDisplay) implements Line { @Override public int height(Font font) { @@ -250,7 +256,7 @@ public void renderText(Font font, int x, int y, Matrix4f matrix, MultiBufferSour font.drawInBatch(label, x, y + 5, -1, true, matrix, buffer, Font.DisplayMode.NORMAL, 0, 0xF000F0); if (entries.size() > maxToDisplay) { - font.drawInBatch(Component.literal("+ ...").withStyle(MITooltips.DEFAULT_STYLE), x + (18 * maxToDisplay) + 2 + font.width(label), + font.drawInBatch(Component.literal("+ ...").withStyle(MITooltips.HIGHLIGHT_STYLE), x + (18 * maxToDisplay) + 2 + font.width(label), y + 5, -1, true, matrix, buffer, Font.DisplayMode.NORMAL, 0, 0xF000F0); @@ -283,7 +289,7 @@ public void renderImage(Font font, int x, int y, GuiGraphics graphics) { graphics.pose().pushPose(); graphics.pose().translate(0, 0, 200); - graphics.drawString(font, Component.literal("#").withStyle(MITooltips.DEFAULT_STYLE), x, y, 0xFFFFFF, true); + graphics.drawString(font, Component.literal("#").withStyle(MITooltips.HIGHLIGHT_STYLE), x, y, 0xFFFFFF, true); graphics.pose().popPose(); } } @@ -317,8 +323,8 @@ public void renderImage(Font font, int x, int y, GuiGraphics graphics) { public void renderText(Font font, int x, int y, Matrix4f matrix, MultiBufferSource.BufferSource buffer) { font.drawInBatch(label, x, y + 5, -1, true, matrix, buffer, Font.DisplayMode.NORMAL, 0, 0xF000F0); - font.drawInBatch(casing.getDisplayName().copy().withStyle(MITooltips.DEFAULT_STYLE), x + font.width(label) + 20, y + 5, -1, true, matrix, buffer, Font.DisplayMode.NORMAL, 0, - 0xF000F0); + font.drawInBatch(casing.getDisplayName().withStyle(MITooltips.HIGHLIGHT_STYLE), x + font.width(label) + 20, y + 5, -1, true, matrix, + buffer, Font.DisplayMode.NORMAL, 0, 0xF000F0); } } } diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMemberMode.java b/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMemberMode.java index b53e3f3c8..6e17d8162 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMemberMode.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMemberMode.java @@ -25,7 +25,7 @@ import aztech.modern_industrialization.MIText; import java.util.Locale; -import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; import net.minecraft.util.StringRepresentable; public enum StructureMemberMode implements StringRepresentable { @@ -40,11 +40,11 @@ public enum StructureMemberMode implements StringRepresentable { this.text = text; } - public Component textInfo() { + public MutableComponent textInfo() { return textInfo.text(); } - public Component text() { + public MutableComponent text() { return text.text(); } From 9704b4904a1f005cb5f8a75ca0bb2830e5a31030 Mon Sep 17 00:00:00 2001 From: Swedz Date: Wed, 27 Nov 2024 10:53:47 -0500 Subject: [PATCH 65/89] Display preview block name in tooltip --- .../ClientStructureMemberBlockTooltip.java | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java index f6cbd6e8f..529c4fe91 100644 --- a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java +++ b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java @@ -84,7 +84,7 @@ public ClientStructureMemberBlockTooltip(StructureMultiblockMemberBlockItem.Tool if (preview != null && !preview.isAir()) { ItemStack previewStack = preview.getBlock().asItem().getDefaultInstance(); lines.add(new IconsLine(MIText.StructureMultiblockMemberTooltipPreview.text().append(" ").withStyle(MITooltips.DEFAULT_STYLE), - List.of(new IconsLine.StackEntry(previewStack)), 6)); + List.of(new IconsLine.StackEntry(previewStack)), 6, previewStack.getHoverName().copy())); } List members = new ArrayList<>(); @@ -109,7 +109,7 @@ public ClientStructureMemberBlockTooltip(StructureMultiblockMemberBlockItem.Tool } if (!members.isEmpty()) { lines.add(new IconsLine(MIText.StructureMultiblockMemberTooltipMembers.text().append(" ").withStyle(MITooltips.DEFAULT_STYLE), - members, 6)); + members, 6, null)); } } @@ -129,7 +129,7 @@ public ClientStructureMemberBlockTooltip(StructureMultiblockMemberBlockItem.Tool } } lines.add(new IconsLine(MIText.StructureMultiblockMemberTooltipHatches.text().append(" ").withStyle(MITooltips.DEFAULT_STYLE), - hatches, 9)); + hatches, 9, null)); } } } @@ -227,7 +227,7 @@ public void renderText(Font font, int x, int y, Matrix4f matrix, MultiBufferSour } } - private record IconsLine(MutableComponent label, List entries, int maxToDisplay) implements Line { + private record IconsLine(MutableComponent label, List entries, int maxToDisplay, @Nullable MutableComponent suffix) implements Line { @Override public int height(Font font) { @@ -237,7 +237,8 @@ public int height(Font font) { @Override public int width(Font font) { return font.width(label) + (18 * Math.min(maxToDisplay, entries.size())) - + (entries.size() > maxToDisplay ? font.width(Component.literal("+ ...")) : 0); + + (entries.size() > maxToDisplay ? font.width(Component.literal("+ ...")) : 0) + + (suffix != null ? font.width(suffix) : 0); } @Override @@ -254,12 +255,20 @@ public void renderImage(Font font, int x, int y, GuiGraphics graphics) { @Override public void renderText(Font font, int x, int y, Matrix4f matrix, MultiBufferSource.BufferSource buffer) { font.drawInBatch(label, x, y + 5, -1, true, matrix, buffer, Font.DisplayMode.NORMAL, 0, 0xF000F0); + x += font.width(label); if (entries.size() > maxToDisplay) { - font.drawInBatch(Component.literal("+ ...").withStyle(MITooltips.HIGHLIGHT_STYLE), x + (18 * maxToDisplay) + 2 + font.width(label), - y + 5, -1, - true, matrix, buffer, - Font.DisplayMode.NORMAL, 0, 0xF000F0); + x += (18 * maxToDisplay) + 2; + Component moreText = Component.literal("+ ...").withStyle(MITooltips.HIGHLIGHT_STYLE); + font.drawInBatch(moreText, x, y + 5, -1, true, matrix, buffer, Font.DisplayMode.NORMAL, 0, 0xF000F0); + x += font.width(moreText); + } else { + x += (18 * entries.size()) + 2; + } + + if (suffix != null) { + font.drawInBatch(suffix.withStyle(MITooltips.HIGHLIGHT_STYLE), x, y + 5, -1, true, matrix, buffer, Font.DisplayMode.NORMAL, 0, + 0xF000F0); } } From 2434caf482d94284b8c645ebb36f25f12cb47314 Mon Sep 17 00:00:00 2001 From: Swedz Date: Wed, 27 Nov 2024 19:09:44 -0500 Subject: [PATCH 66/89] Add actual translations for gui --- ...ructureMultiblockControllerEditScreen.java | 30 +++++++++---------- .../StructureMultiblockMemberEditScreen.java | 2 +- .../modern_industrialization/lang/en_us.json | 14 ++++++++- .../modern_industrialization/MIText.java | 14 ++++++++- 4 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockControllerEditScreen.java b/src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockControllerEditScreen.java index 903947dd9..fa1281f3c 100644 --- a/src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockControllerEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockControllerEditScreen.java @@ -200,18 +200,18 @@ protected void init() { this.addRenderableWidget( cancelButton = Button.builder(CommonComponents.GUI_CANCEL, button -> this.cancel()).bounds(width / 2 + 4, 210, 150, 20).build()); this.addRenderableWidget( - saveButton = Button.builder(Component.translatable("structure_block.button.save"), button -> this.save()) + saveButton = Button.builder(MIText.StructureMultiblockGuiSave.text(), button -> this.save()) .bounds(width / 2 + 4 + 100, 185, 50, 20).build()); this.addRenderableWidget( - loadButton = Button.builder(Component.translatable("structure_block.button.load"), button -> this.load()) + loadButton = Button.builder(MIText.StructureMultiblockGuiLoad.text(), button -> this.load()) .bounds(width / 2 + 4 + 100, 185, 50, 20) - .tooltip(Tooltip.create(MIText.StructureMultiblockLoadTooltip.text())) + .tooltip(Tooltip.create(MIText.StructureMultiblockGuiLoadTooltip.text())) .build()); this.addRenderableWidget(modeButton = CycleButton.builder(StructureControllerMode::text) .withValues(ALL_MODES, ALL_MODES) .displayOnlyValue() .withInitialValue(controller.getMode()) - .create(width / 2 - 4 - 150, 185, 50, 20, Component.literal("MODE"), (button, mode) -> this.updateMode(mode))); + .create(width / 2 - 4 - 150, 185, 50, 20, MIText.StructureMultiblockGuiMode.text(), (button, mode) -> this.updateMode(mode))); idBox = new EditBox(font, width / 2 - 152, 50, 304, 20, MIText.StructureMultiblockStructureName.text()) { @Override @@ -237,33 +237,33 @@ public boolean charTyped(char codePoint, int modifiers) { StructureControllerBounds bounds = controller.getBounds(); - posXBox = new EditBox(font, width / 2 - 152, 130, 35, 20, Component.translatable("structure_block.position.x")); + posXBox = new EditBox(font, width / 2 - 152, 130, 35, 20, MIText.StructureMultiblockGuiRelativePositionX.text()); posXBox.setMaxLength(15); posXBox.setValue(Integer.toString(bounds.x())); posXBox.setResponder(text -> this.updateBounds()); this.addRenderableWidget(posXBox); - posYBox = new EditBox(font, width / 2 - 117, 130, 35, 20, Component.translatable("structure_block.position.y")); + posYBox = new EditBox(font, width / 2 - 117, 130, 35, 20, MIText.StructureMultiblockGuiRelativePositionY.text()); posYBox.setMaxLength(15); posYBox.setValue(Integer.toString(bounds.y())); posYBox.setResponder(text -> this.updateBounds()); this.addRenderableWidget(posYBox); - posZBox = new EditBox(font, width / 2 - 82, 130, 35, 20, Component.translatable("structure_block.position.z")); + posZBox = new EditBox(font, width / 2 - 82, 130, 35, 20, MIText.StructureMultiblockGuiRelativePositionZ.text()); posZBox.setMaxLength(15); posZBox.setValue(Integer.toString(bounds.z())); posZBox.setResponder(text -> this.updateBounds()); this.addRenderableWidget(posZBox); - sizeXBox = new EditBox(font, width / 2 - 47 + 8, 130, 35, 20, Component.translatable("structure_block.size.x")); + sizeXBox = new EditBox(font, width / 2 - 47 + 8, 130, 35, 20, MIText.StructureMultiblockGuiStructureSizeX.text()); sizeXBox.setMaxLength(15); sizeXBox.setValue(Integer.toString(bounds.sizeX())); sizeXBox.setResponder(text -> this.updateBounds()); this.addRenderableWidget(sizeXBox); - sizeYBox = new EditBox(font, width / 2 - 4, 130, 35, 20, Component.translatable("structure_block.size.y")); + sizeYBox = new EditBox(font, width / 2 - 4, 130, 35, 20, MIText.StructureMultiblockGuiStructureSizeY.text()); sizeYBox.setMaxLength(15); sizeYBox.setValue(Integer.toString(bounds.sizeY())); sizeYBox.setResponder(text -> this.updateBounds()); this.addRenderableWidget(sizeYBox); - sizeZBox = new EditBox(font, width / 2 + 31, 130, 35, 20, Component.translatable("structure_block.size.z")); + sizeZBox = new EditBox(font, width / 2 + 31, 130, 35, 20, MIText.StructureMultiblockGuiStructureSizeZ.text()); sizeZBox.setMaxLength(15); sizeZBox.setValue(Integer.toString(bounds.sizeZ())); sizeZBox.setResponder(text -> this.updateBounds()); @@ -271,7 +271,7 @@ public boolean charTyped(char codePoint, int modifiers) { this.addRenderableWidget(showBoundsBox = CycleButton.onOffBuilder(controller.shouldShowBounds()) .displayOnlyValue() - .create(width / 2 + 4 + 100, 130, 50, 20, Component.translatable("structure_block.show_boundingbox"))); + .create(width / 2 + 4 + 100, 130, 50, 20, MIText.StructureMultiblockGuiShowBoundingBox.text())); this.updateAll(); } @@ -288,14 +288,14 @@ public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTi graphics.drawString(font, MIText.StructureMultiblockCasing.text(), width / 2 - 152, 80, 0xA0A0A0); if (posXBox.visible || posYBox.visible || posZBox.visible) - graphics.drawString(font, Component.translatable("structure_block.position"), width / 2 - 152, 120, 0xA0A0A0); + graphics.drawString(font, MIText.StructureMultiblockGuiRelativePosition.text(), width / 2 - 152, 120, 0xA0A0A0); if (sizeXBox.visible || sizeYBox.visible || sizeZBox.visible) - graphics.drawString(font, Component.translatable("structure_block.size"), width / 2 - 47 + 8, 120, 0xA0A0A0); + graphics.drawString(font, MIText.StructureMultiblockGuiStructureSize.text(), width / 2 - 47 + 8, 120, 0xA0A0A0); if (showBoundsBox.visible) - graphics.drawString(font, Component.translatable("structure_block.show_boundingbox"), - width / 2 + 154 - font.width(Component.translatable("structure_block.show_boundingbox")), 120, 0xA0A0A0); + graphics.drawString(font, MIText.StructureMultiblockGuiShowBoundingBox.text(), + width / 2 + 154 - font.width(MIText.StructureMultiblockGuiShowBoundingBox.text()), 120, 0xA0A0A0); graphics.drawString(font, modeButton.getValue().textInfo(), width / 2 - 4 - 150, 175, 0xA0A0A0); } diff --git a/src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockMemberEditScreen.java b/src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockMemberEditScreen.java index bb733d9c6..448822ece 100644 --- a/src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockMemberEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockMemberEditScreen.java @@ -178,7 +178,7 @@ protected void init() { .withValues(ALL_MODES, ALL_MODES) .displayOnlyValue() .withInitialValue(member.getMode()) - .create(width / 2 - 4 - 150, 185, 50, 20, Component.literal("MODE"), (button, mode) -> this.updateMode(mode))); + .create(width / 2 - 4 - 150, 185, 50, 20, MIText.StructureMultiblockGuiMode.text(), (button, mode) -> this.updateMode(mode))); nameBox = new EditBox(font, width / 2 - 152, 20, 304, 20, MIText.StructureMultiblockMemberName.text()); nameBox.setMaxLength(Short.MAX_VALUE); diff --git a/src/generated/resources/assets/modern_industrialization/lang/en_us.json b/src/generated/resources/assets/modern_industrialization/lang/en_us.json index dd138ba8f..3b154dad1 100644 --- a/src/generated/resources/assets/modern_industrialization/lang/en_us.json +++ b/src/generated/resources/assets/modern_industrialization/lang/en_us.json @@ -1717,10 +1717,22 @@ "text.modern_industrialization.SteamDrillToggle": "- Toggle Silk Touch with %s + %s.", "text.modern_industrialization.SteamDrillWaterHelp": "- Press %s on still or flowing water to fill.", "text.modern_industrialization.StructureMultiblockCasing": "Machine Casing", + "text.modern_industrialization.StructureMultiblockGuiLoad": "LOAD", + "text.modern_industrialization.StructureMultiblockGuiLoadTooltip": "Hold SHIFT to place actual blocks instead of structure blocks.", + "text.modern_industrialization.StructureMultiblockGuiMode": "MODE", + "text.modern_industrialization.StructureMultiblockGuiRelativePosition": "Relative Position", + "text.modern_industrialization.StructureMultiblockGuiRelativePositionX": "Relative Position X", + "text.modern_industrialization.StructureMultiblockGuiRelativePositionY": "Relative Position Y", + "text.modern_industrialization.StructureMultiblockGuiRelativePositionZ": "Relative Position Z", + "text.modern_industrialization.StructureMultiblockGuiSave": "SAVE", + "text.modern_industrialization.StructureMultiblockGuiShowBoundingBox": "Show Bounding Box", + "text.modern_industrialization.StructureMultiblockGuiStructureSize": "Structure Size", + "text.modern_industrialization.StructureMultiblockGuiStructureSizeX": "Structure Size X", + "text.modern_industrialization.StructureMultiblockGuiStructureSizeY": "Structure Size Y", + "text.modern_industrialization.StructureMultiblockGuiStructureSizeZ": "Structure Size Z", "text.modern_industrialization.StructureMultiblockLoadFailDoesntExist": "Failed to place the structure. No structure exists as %s.", "text.modern_industrialization.StructureMultiblockLoadFailInvalidId": "Failed to place the structure. No id was provided.", "text.modern_industrialization.StructureMultiblockLoadSuccess": "Successfully placed the structure %s.", - "text.modern_industrialization.StructureMultiblockLoadTooltip": "Hold SHIFT to place actual blocks instead of structure blocks.", "text.modern_industrialization.StructureMultiblockMemberHatchFlags": "Hatch Flags", "text.modern_industrialization.StructureMultiblockMemberMembers": "Members", "text.modern_industrialization.StructureMultiblockMemberModeHatch": "Hatch", diff --git a/src/main/java/aztech/modern_industrialization/MIText.java b/src/main/java/aztech/modern_industrialization/MIText.java index f75d46672..fb529502d 100644 --- a/src/main/java/aztech/modern_industrialization/MIText.java +++ b/src/main/java/aztech/modern_industrialization/MIText.java @@ -248,6 +248,19 @@ public enum MIText { SteamDrillToggle("- Toggle Silk Touch with %s + %s."), SteamDrillWaterHelp("- Press %s on still or flowing water to fill."), StructureMultiblockCasing("Machine Casing"), + StructureMultiblockGuiLoadTooltip("Hold SHIFT to place actual blocks instead of structure blocks."), + StructureMultiblockGuiSave("SAVE"), + StructureMultiblockGuiLoad("LOAD"), + StructureMultiblockGuiMode("MODE"), + StructureMultiblockGuiRelativePosition("Relative Position"), + StructureMultiblockGuiRelativePositionX("Relative Position X"), + StructureMultiblockGuiRelativePositionY("Relative Position Y"), + StructureMultiblockGuiRelativePositionZ("Relative Position Z"), + StructureMultiblockGuiStructureSize("Structure Size"), + StructureMultiblockGuiStructureSizeX("Structure Size X"), + StructureMultiblockGuiStructureSizeY("Structure Size Y"), + StructureMultiblockGuiStructureSizeZ("Structure Size Z"), + StructureMultiblockGuiShowBoundingBox("Show Bounding Box"), StructureMultiblockMemberHatchFlags("Hatch Flags"), StructureMultiblockMemberName("Member Name"), StructureMultiblockMemberMembers("Members"), @@ -265,7 +278,6 @@ public enum MIText { StructureMultiblockMemberTooltipCasing("Casing:"), StructureMultiblockMemberTooltipHatches("Hatches:"), StructureMultiblockStructureName("Structure Name"), - StructureMultiblockLoadTooltip("Hold SHIFT to place actual blocks instead of structure blocks."), StructureMultiblockLoadFailInvalidId("Failed to place the structure. No id was provided."), StructureMultiblockLoadFailDoesntExist("Failed to place the structure. No structure exists as %s."), StructureMultiblockLoadSuccess("Successfully placed the structure %s."), From 4995ce0f3e9f1b0ea279ab62f1e8a0faec0542f4 Mon Sep 17 00:00:00 2001 From: Swedz Date: Wed, 27 Nov 2024 19:12:30 -0500 Subject: [PATCH 67/89] Sort MIText --- .../modern_industrialization/MIText.java | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/MIText.java b/src/main/java/aztech/modern_industrialization/MIText.java index fb529502d..41ebbd621 100644 --- a/src/main/java/aztech/modern_industrialization/MIText.java +++ b/src/main/java/aztech/modern_industrialization/MIText.java @@ -27,7 +27,6 @@ import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; -// TODO SWEDZ: alphabetize public enum MIText { ModernIndustrialization("Modern Industrialization"), @@ -248,46 +247,46 @@ public enum MIText { SteamDrillToggle("- Toggle Silk Touch with %s + %s."), SteamDrillWaterHelp("- Press %s on still or flowing water to fill."), StructureMultiblockCasing("Machine Casing"), - StructureMultiblockGuiLoadTooltip("Hold SHIFT to place actual blocks instead of structure blocks."), - StructureMultiblockGuiSave("SAVE"), StructureMultiblockGuiLoad("LOAD"), + StructureMultiblockGuiLoadTooltip("Hold SHIFT to place actual blocks instead of structure blocks."), StructureMultiblockGuiMode("MODE"), StructureMultiblockGuiRelativePosition("Relative Position"), StructureMultiblockGuiRelativePositionX("Relative Position X"), StructureMultiblockGuiRelativePositionY("Relative Position Y"), StructureMultiblockGuiRelativePositionZ("Relative Position Z"), + StructureMultiblockGuiSave("SAVE"), + StructureMultiblockGuiShowBoundingBox("Show Bounding Box"), StructureMultiblockGuiStructureSize("Structure Size"), StructureMultiblockGuiStructureSizeX("Structure Size X"), StructureMultiblockGuiStructureSizeY("Structure Size Y"), StructureMultiblockGuiStructureSizeZ("Structure Size Z"), - StructureMultiblockGuiShowBoundingBox("Show Bounding Box"), + StructureMultiblockLoadFailDoesntExist("Failed to place the structure. No structure exists as %s."), + StructureMultiblockLoadFailInvalidId("Failed to place the structure. No id was provided."), + StructureMultiblockLoadSuccess("Successfully placed the structure %s."), StructureMultiblockMemberHatchFlags("Hatch Flags"), - StructureMultiblockMemberName("Member Name"), StructureMultiblockMemberMembers("Members"), - StructureMultiblockMemberPreview("Preview"), - StructureMultiblockMemberModeSimple("Simple"), StructureMultiblockMemberModeHatch("Hatch"), - StructureMultiblockMemberModeVariable("Variable"), - StructureMultiblockMemberModeInfoSimple("Simple Mode - Just a block"), StructureMultiblockMemberModeInfoHatch("Hatch Mode - Include hatches"), + StructureMultiblockMemberModeInfoSimple("Simple Mode - Just a block"), StructureMultiblockMemberModeInfoVariable("Variable Mode - Filled in at startup"), - StructureMultiblockMemberTooltipMode("Mode: %s"), - StructureMultiblockMemberTooltipVariableName("Name: %s"), - StructureMultiblockMemberTooltipPreview("Preview:"), - StructureMultiblockMemberTooltipMembers("Members:"), + StructureMultiblockMemberModeSimple("Simple"), + StructureMultiblockMemberModeVariable("Variable"), + StructureMultiblockMemberName("Member Name"), + StructureMultiblockMemberPreview("Preview"), StructureMultiblockMemberTooltipCasing("Casing:"), StructureMultiblockMemberTooltipHatches("Hatches:"), - StructureMultiblockStructureName("Structure Name"), - StructureMultiblockLoadFailInvalidId("Failed to place the structure. No id was provided."), - StructureMultiblockLoadFailDoesntExist("Failed to place the structure. No structure exists as %s."), - StructureMultiblockLoadSuccess("Successfully placed the structure %s."), + StructureMultiblockMemberTooltipMembers("Members:"), + StructureMultiblockMemberTooltipMode("Mode: %s"), + StructureMultiblockMemberTooltipPreview("Preview:"), + StructureMultiblockMemberTooltipVariableName("Name: %s"), StructureMultiblockSaveFailInvalidBounds("Failed to save structure. The bounds provided are not valid."), StructureMultiblockSaveFailMisconfiguredBlock("Failed to save structure. Some blocks are not properly configured."), - StructureMultiblockSaveFailTooManyControllers("Failed to save structure. Too many controllers exist within the bounds."), StructureMultiblockSaveFailNoController("Failed to save structure. No controller could be found within the bounds."), StructureMultiblockSaveFailNoHatches("Failed to save structure. No hatches could be found within the bounds."), + StructureMultiblockSaveFailTooManyControllers("Failed to save structure. Too many controllers exist within the bounds."), StructureMultiblockSaveFailUnknown("Failed to save structure. See logs for more info."), StructureMultiblockSaveSuccess("The structure has been saved as %s."), + StructureMultiblockStructureName("Structure Name"), SuperconductorPowerOnly( "Can only connect to Superconductor cables and machines. Must be directly connected to a machine on at least one end of the tunnel."), Temperature("Temperature: %d °C"), From 20047f26886f52a65133e13f97e95dbf713910c2 Mon Sep 17 00:00:00 2001 From: Swedz Date: Thu, 28 Nov 2024 02:59:02 -0500 Subject: [PATCH 68/89] Allow multiblock structures to save and compare block entity nbt --- .../modern_industrialization/MIClient.java | 4 +- .../structure/StructureMultiblockBER.java | 68 ------------------- .../StructureMultiblockControllerBER.java | 57 +++++++++++++--- ...ructureMultiblockControllerEditScreen.java | 46 ++++++++----- .../multiblocks/MultiblockErrorHighlight.java | 27 +++++--- .../multiblocks/MultiblockMachineBER.java | 24 +++++-- .../proxy/ClientProxy.java | 6 +- .../modern_industrialization/lang/en_us.json | 1 + .../modern_industrialization/MIText.java | 1 + ...uctureMultiblockControllerBlockEntity.java | 11 +++ .../machines/multiblocks/ShapeMatcher.java | 25 ++++++- .../machines/multiblocks/SimpleMember.java | 10 +-- .../structure/MIStructureTemplateManager.java | 22 +++--- .../member/LiteralStructureMember.java | 45 +++++++++++- .../member/SimpleStructureMember.java | 4 +- .../structure/member/StructureMember.java | 7 +- .../member/VariableStructureMember.java | 4 +- .../StructureSaveControllerPacket.java | 2 +- .../StructureUpdateControllerPacket.java | 8 ++- 19 files changed, 234 insertions(+), 138 deletions(-) delete mode 100644 src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockBER.java diff --git a/src/client/java/aztech/modern_industrialization/MIClient.java b/src/client/java/aztech/modern_industrialization/MIClient.java index 3d85bf6e9..7b8592d4a 100644 --- a/src/client/java/aztech/modern_industrialization/MIClient.java +++ b/src/client/java/aztech/modern_industrialization/MIClient.java @@ -29,7 +29,6 @@ import aztech.modern_industrialization.blocks.storage.barrel.DeferredBarrelTextRenderer; import aztech.modern_industrialization.blocks.storage.barrel.client.BarrelTooltipComponent; import aztech.modern_industrialization.blocks.storage.tank.TankRenderer; -import aztech.modern_industrialization.blocks.structure.StructureMultiblockBER; import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBER; import aztech.modern_industrialization.blocks.structure.member.StructureMemberMode; import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlockItem; @@ -157,7 +156,7 @@ private static void init(FMLConstructModEvent ignored) { }); NeoForge.EVENT_BUS.addListener(LevelEvent.Unload.class, event -> { if (event.getLevel().isClientSide()) { - StructureMultiblockBER.setMisconfigured(List.of()); + StructureMultiblockControllerBER.setMisconfigured(List.of()); } }); @@ -246,7 +245,6 @@ private static void registerBlockEntityRenderers(FMLClientSetupEvent event) { BlockEntityRenderers.register(MIRegistries.CREATIVE_BARREL_BE.get(), context -> new BarrelRenderer(0x000000)); BlockEntityRenderers.register(MIRegistries.CREATIVE_TANK_BE.get(), context -> new TankRenderer(0x000000)); BlockEntityRenderers.register(MIRegistries.STRUCTURE_MULTIBLOCK_CONTROLLER_BE.get(), context -> new StructureMultiblockControllerBER()); - BlockEntityRenderers.register(MIRegistries.STRUCTURE_MULTIBLOCK_MEMBER_BE.get(), context -> new StructureMultiblockBER<>()); blockEntityRendererRegistrations.forEach(Runnable::run); } diff --git a/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockBER.java b/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockBER.java deleted file mode 100644 index 78ecbdce7..000000000 --- a/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockBER.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2020 Azercoco & Technici4n - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package aztech.modern_industrialization.blocks.structure; - -import aztech.modern_industrialization.util.RenderHelper; -import com.mojang.blaze3d.vertex.PoseStack; -import java.util.ArrayList; -import java.util.List; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.phys.AABB; - -public class StructureMultiblockBER implements BlockEntityRenderer { - private static List MISCONFIGURED_BLOCKS = new ArrayList<>(); - - public static void setMisconfigured(List positions) { - MISCONFIGURED_BLOCKS = new ArrayList<>(positions); - } - - public static void forgetMisconfigured(List positions) { - MISCONFIGURED_BLOCKS.removeAll(positions); - } - - @Override - public void render(T be, float tickDelta, PoseStack matrices, MultiBufferSource vcp, int light, int overlay) { - BlockPos pos = be.getBlockPos(); - if (MISCONFIGURED_BLOCKS.contains(pos) && (System.currentTimeMillis() / 500L) % 2 == 0) { - matrices.pushPose(); - matrices.translate(-0.005f, -0.005f, -0.005f); - matrices.scale(1.01f, 1.01f, 1.01f); - RenderHelper.drawOverlay(matrices, vcp, 1.0f, 111f / 256f, 111f / 256f, RenderHelper.FULL_LIGHT, overlay, false); - matrices.popPose(); - } - } - - @Override - public boolean shouldRenderOffScreen(T be) { - return true; - } - - @Override - public AABB getRenderBoundingBox(T be) { - return AABB.INFINITE; - } -} diff --git a/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java b/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java index 4cc9d88c1..9395999d9 100644 --- a/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java +++ b/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java @@ -25,31 +25,68 @@ import aztech.modern_industrialization.blocks.structure.controller.StructureControllerBounds; import aztech.modern_industrialization.blocks.structure.controller.StructureMultiblockControllerBlockEntity; +import aztech.modern_industrialization.util.RenderHelper; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; +import java.util.ArrayList; +import java.util.List; import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; import net.minecraft.core.BlockPos; import net.minecraft.world.phys.AABB; -public class StructureMultiblockControllerBER extends StructureMultiblockBER { +public final class StructureMultiblockControllerBER implements BlockEntityRenderer { + private static List MISCONFIGURED_BLOCKS = new ArrayList<>(); + + public static void setMisconfigured(List positions) { + MISCONFIGURED_BLOCKS = new ArrayList<>(positions); + } + + public static void forgetMisconfigured(List positions) { + MISCONFIGURED_BLOCKS.removeAll(positions); + } + @Override public void render(StructureMultiblockControllerBlockEntity be, float tickDelta, PoseStack matrices, MultiBufferSource vcp, int light, int overlay) { - super.render(be, tickDelta, matrices, vcp, light, overlay); - - if (!be.shouldShowBounds()) { - return; - } BlockPos pos = be.getBlockPos(); StructureControllerBounds bounds = be.getBounds(); + AABB box = bounds.aabb(); if (box != null) { - matrices.pushPose(); - VertexConsumer buffer = vcp.getBuffer(RenderType.lines()); - LevelRenderer.renderLineBox(matrices, buffer, box, 1, 1, 1, 1); - matrices.popPose(); + if ((System.currentTimeMillis() / 500L) % 2 == 0) { + AABB worldBox = box.move(pos); + for (BlockPos misconfiguredPos : MISCONFIGURED_BLOCKS) { + if (worldBox.contains(misconfiguredPos.getX(), misconfiguredPos.getY(), misconfiguredPos.getZ())) { + matrices.pushPose(); + matrices.translate(misconfiguredPos.getX() - pos.getX(), misconfiguredPos.getY() - pos.getY(), + misconfiguredPos.getZ() - pos.getZ()); + matrices.translate(-0.005f, -0.005f, -0.005f); + matrices.scale(1.01f, 1.01f, 1.01f); + RenderHelper.drawOverlay(matrices, vcp, 1.0f, 111f / 256f, 111f / 256f, RenderHelper.FULL_LIGHT, overlay, false); + matrices.popPose(); + } + } + } + + if (be.shouldShowBounds()) { + matrices.pushPose(); + VertexConsumer buffer = vcp.getBuffer(RenderType.lines()); + LevelRenderer.renderLineBox(matrices, buffer, box, 1, 1, 1, 1); + matrices.popPose(); + } } } + + @Override + public boolean shouldRenderOffScreen(StructureMultiblockControllerBlockEntity be) { + return true; + } + + @Override + public AABB getRenderBoundingBox(StructureMultiblockControllerBlockEntity be) { + return AABB.INFINITE; + } } diff --git a/src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockControllerEditScreen.java b/src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockControllerEditScreen.java index fa1281f3c..19158be5d 100644 --- a/src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockControllerEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockControllerEditScreen.java @@ -73,6 +73,7 @@ public class StructureMultiblockControllerEditScreen extends Screen { private EditBox sizeZBox; private CycleButton showBoundsBox; + private CycleButton includeBlockEntitiesBox; public StructureMultiblockControllerEditScreen(StructureMultiblockControllerBlockEntity controller) { super(Component.translatable(MIBlock.STRUCTURE_MULTIBLOCK_CONTROLLER.asBlock().getDescriptionId())); @@ -118,6 +119,7 @@ private void updateMode(StructureControllerMode mode) { sizeYBox.visible = false; sizeZBox.visible = false; showBoundsBox.visible = false; + includeBlockEntitiesBox.visible = false; switch (mode) { case SAVE -> { @@ -130,6 +132,7 @@ private void updateMode(StructureControllerMode mode) { sizeYBox.visible = true; sizeZBox.visible = true; showBoundsBox.visible = true; + includeBlockEntitiesBox.visible = true; } case LOAD -> { loadButton.visible = true; @@ -174,7 +177,8 @@ private void sendToServer() { idBox.getValue(), casingBox.getValue(), this.getBounds().orElse(new StructureControllerBounds(0, 0, 0, 1, 1, 1)), - showBoundsBox.getValue()).sendToServer(); + showBoundsBox.getValue(), + includeBlockEntitiesBox.getValue()).sendToServer(); } private void cancel() { @@ -213,7 +217,7 @@ protected void init() { .withInitialValue(controller.getMode()) .create(width / 2 - 4 - 150, 185, 50, 20, MIText.StructureMultiblockGuiMode.text(), (button, mode) -> this.updateMode(mode))); - idBox = new EditBox(font, width / 2 - 152, 50, 304, 20, MIText.StructureMultiblockStructureName.text()) { + idBox = new EditBox(font, width / 2 - 152, 20, 304, 20, MIText.StructureMultiblockStructureName.text()) { @Override public boolean charTyped(char codePoint, int modifiers) { return StructureMultiblockInputFormatters.isValidIdCharacter(codePoint) && super.charTyped(codePoint, modifiers); @@ -224,7 +228,7 @@ public boolean charTyped(char codePoint, int modifiers) { idBox.setResponder(text -> this.updateId()); this.addRenderableWidget(idBox); - casingBox = new EditBox(font, width / 2 - 152, 90, 304, 20, MIText.StructureMultiblockCasing.text()) { + casingBox = new EditBox(font, width / 2 - 152, 60, 304, 20, MIText.StructureMultiblockCasing.text()) { @Override public boolean charTyped(char codePoint, int modifiers) { return ResourceLocation.isAllowedInResourceLocation(codePoint) && super.charTyped(codePoint, modifiers); @@ -237,33 +241,33 @@ public boolean charTyped(char codePoint, int modifiers) { StructureControllerBounds bounds = controller.getBounds(); - posXBox = new EditBox(font, width / 2 - 152, 130, 35, 20, MIText.StructureMultiblockGuiRelativePositionX.text()); + posXBox = new EditBox(font, width / 2 - 152, 100, 35, 20, MIText.StructureMultiblockGuiRelativePositionX.text()); posXBox.setMaxLength(15); posXBox.setValue(Integer.toString(bounds.x())); posXBox.setResponder(text -> this.updateBounds()); this.addRenderableWidget(posXBox); - posYBox = new EditBox(font, width / 2 - 117, 130, 35, 20, MIText.StructureMultiblockGuiRelativePositionY.text()); + posYBox = new EditBox(font, width / 2 - 117, 100, 35, 20, MIText.StructureMultiblockGuiRelativePositionY.text()); posYBox.setMaxLength(15); posYBox.setValue(Integer.toString(bounds.y())); posYBox.setResponder(text -> this.updateBounds()); this.addRenderableWidget(posYBox); - posZBox = new EditBox(font, width / 2 - 82, 130, 35, 20, MIText.StructureMultiblockGuiRelativePositionZ.text()); + posZBox = new EditBox(font, width / 2 - 82, 100, 35, 20, MIText.StructureMultiblockGuiRelativePositionZ.text()); posZBox.setMaxLength(15); posZBox.setValue(Integer.toString(bounds.z())); posZBox.setResponder(text -> this.updateBounds()); this.addRenderableWidget(posZBox); - sizeXBox = new EditBox(font, width / 2 - 47 + 8, 130, 35, 20, MIText.StructureMultiblockGuiStructureSizeX.text()); + sizeXBox = new EditBox(font, width / 2 - 47 + 8, 100, 35, 20, MIText.StructureMultiblockGuiStructureSizeX.text()); sizeXBox.setMaxLength(15); sizeXBox.setValue(Integer.toString(bounds.sizeX())); sizeXBox.setResponder(text -> this.updateBounds()); this.addRenderableWidget(sizeXBox); - sizeYBox = new EditBox(font, width / 2 - 4, 130, 35, 20, MIText.StructureMultiblockGuiStructureSizeY.text()); + sizeYBox = new EditBox(font, width / 2 - 4, 100, 35, 20, MIText.StructureMultiblockGuiStructureSizeY.text()); sizeYBox.setMaxLength(15); sizeYBox.setValue(Integer.toString(bounds.sizeY())); sizeYBox.setResponder(text -> this.updateBounds()); this.addRenderableWidget(sizeYBox); - sizeZBox = new EditBox(font, width / 2 + 31, 130, 35, 20, MIText.StructureMultiblockGuiStructureSizeZ.text()); + sizeZBox = new EditBox(font, width / 2 + 31, 100, 35, 20, MIText.StructureMultiblockGuiStructureSizeZ.text()); sizeZBox.setMaxLength(15); sizeZBox.setValue(Integer.toString(bounds.sizeZ())); sizeZBox.setResponder(text -> this.updateBounds()); @@ -271,7 +275,11 @@ public boolean charTyped(char codePoint, int modifiers) { this.addRenderableWidget(showBoundsBox = CycleButton.onOffBuilder(controller.shouldShowBounds()) .displayOnlyValue() - .create(width / 2 + 4 + 100, 130, 50, 20, MIText.StructureMultiblockGuiShowBoundingBox.text())); + .create(width / 2 + 4 + 100, 100, 50, 20, MIText.StructureMultiblockGuiShowBoundingBox.text())); + + this.addRenderableWidget(includeBlockEntitiesBox = CycleButton.onOffBuilder(controller.includeBlockEntities()) + .displayOnlyValue() + .create(width / 2 + 4 + 100, 140, 50, 20, MIText.StructureMultiblockGuiIncludeBlockEntities.text())); this.updateAll(); } @@ -280,22 +288,24 @@ public boolean charTyped(char codePoint, int modifiers) { public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) { super.render(graphics, mouseX, mouseY, partialTick); - graphics.drawCenteredString(font, title, width / 2, 20, 0xFFFFFF); - - graphics.drawString(font, MIText.StructureMultiblockStructureName.text(), width / 2 - 152, 40, 0xA0A0A0); + graphics.drawString(font, MIText.StructureMultiblockStructureName.text(), width / 2 - 152, 10, 0xA0A0A0); if (casingBox.visible) - graphics.drawString(font, MIText.StructureMultiblockCasing.text(), width / 2 - 152, 80, 0xA0A0A0); + graphics.drawString(font, MIText.StructureMultiblockCasing.text(), width / 2 - 152, 50, 0xA0A0A0); if (posXBox.visible || posYBox.visible || posZBox.visible) - graphics.drawString(font, MIText.StructureMultiblockGuiRelativePosition.text(), width / 2 - 152, 120, 0xA0A0A0); + graphics.drawString(font, MIText.StructureMultiblockGuiRelativePosition.text(), width / 2 - 152, 90, 0xA0A0A0); if (sizeXBox.visible || sizeYBox.visible || sizeZBox.visible) - graphics.drawString(font, MIText.StructureMultiblockGuiStructureSize.text(), width / 2 - 47 + 8, 120, 0xA0A0A0); + graphics.drawString(font, MIText.StructureMultiblockGuiStructureSize.text(), width / 2 - 47 + 8, 90, 0xA0A0A0); if (showBoundsBox.visible) graphics.drawString(font, MIText.StructureMultiblockGuiShowBoundingBox.text(), - width / 2 + 154 - font.width(MIText.StructureMultiblockGuiShowBoundingBox.text()), 120, 0xA0A0A0); + width / 2 + 154 - font.width(MIText.StructureMultiblockGuiShowBoundingBox.text()), 90, 0xA0A0A0); + + if (includeBlockEntitiesBox.visible) + graphics.drawString(font, MIText.StructureMultiblockGuiIncludeBlockEntities.text(), + width / 2 + 154 - font.width(MIText.StructureMultiblockGuiIncludeBlockEntities.text()), 130, 0xA0A0A0); graphics.drawString(font, modeButton.getValue().textInfo(), width / 2 - 4 - 150, 175, 0xA0A0A0); } @@ -322,6 +332,7 @@ public void resize(Minecraft minecraft, int width, int height) { String sizeYBoxValue = sizeYBox.getValue(); String sizeZBoxValue = sizeZBox.getValue(); boolean showBoundsBoxValue = showBoundsBox.getValue(); + boolean includeBlockEntitiesBoxValue = includeBlockEntitiesBox.getValue(); this.init(minecraft, width, height); @@ -335,6 +346,7 @@ public void resize(Minecraft minecraft, int width, int height) { sizeYBox.setValue(sizeYBoxValue); sizeZBox.setValue(sizeZBoxValue); showBoundsBox.setValue(showBoundsBoxValue); + includeBlockEntitiesBox.setValue(includeBlockEntitiesBoxValue); } @Override diff --git a/src/client/java/aztech/modern_industrialization/machines/multiblocks/MultiblockErrorHighlight.java b/src/client/java/aztech/modern_industrialization/machines/multiblocks/MultiblockErrorHighlight.java index 052628310..2eb28922b 100644 --- a/src/client/java/aztech/modern_industrialization/machines/multiblocks/MultiblockErrorHighlight.java +++ b/src/client/java/aztech/modern_industrialization/machines/multiblocks/MultiblockErrorHighlight.java @@ -26,28 +26,31 @@ import aztech.modern_industrialization.util.RenderHelper; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.ByteBufferBuilder; +import com.mojang.datafixers.util.Pair; import java.util.HashMap; import java.util.Map; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.Vec3; import net.neoforged.neoforge.client.event.RenderLevelStageEvent; +import net.neoforged.neoforge.client.model.data.ModelData; import net.neoforged.neoforge.common.NeoForge; import org.jetbrains.annotations.Nullable; public class MultiblockErrorHighlight { - private static final Map highlightQueue = new HashMap<>(); + private static final Map> highlightQueue = new HashMap<>(); private static final MultiBufferSource.BufferSource immediate = MultiBufferSource.immediate(new ByteBufferBuilder(128)); public static void init() { NeoForge.EVENT_BUS.addListener(MultiblockErrorHighlight::end); } - public static void enqueueHighlight(BlockPos pos, @Nullable BlockState state) { - highlightQueue.put(pos.immutable(), state); + public static void enqueueHighlight(BlockPos pos, @Nullable BlockState state, @Nullable BlockEntity blockEntity) { + highlightQueue.put(pos.immutable(), state != null ? Pair.of(state, blockEntity) : null); } private static void end(RenderLevelStageEvent event) { @@ -59,7 +62,7 @@ private static void end(RenderLevelStageEvent event) { var poseStack = event.getPoseStack(); poseStack.pushPose(); poseStack.mulPose(event.getModelViewMatrix()); - for (Map.Entry entry : highlightQueue.entrySet()) { + for (Map.Entry> entry : highlightQueue.entrySet()) { poseStack.pushPose(); Vec3 cameraPos = Minecraft.getInstance().gameRenderer.getMainCamera().getPosition(); BlockPos pos = entry.getKey(); @@ -69,12 +72,20 @@ private static void end(RenderLevelStageEvent event) { poseStack.translate(x + 0.25, y + 0.25, z + 0.25); poseStack.scale(0.5f, 0.5f, 0.5f); - BlockState state = entry.getValue(); - if (state == null) { + var value = entry.getValue(); + if (value == null) { RenderHelper.drawCube(poseStack, immediate, 1, 50f / 256, 50f / 256, 15728880, OverlayTexture.NO_OVERLAY); } else { - Minecraft.getInstance().getBlockRenderer().renderSingleBlock(state, poseStack, immediate, 15728880, - OverlayTexture.NO_OVERLAY); + BlockState state = value.getFirst(); + BlockEntity blockEntity = value.getSecond(); + var berDispatcher = Minecraft.getInstance().getBlockEntityRenderDispatcher(); + if (blockEntity != null && berDispatcher.getRenderer(blockEntity) != null) { + berDispatcher.render(blockEntity, 0, poseStack, immediate); + } else { + ModelData modelData = blockEntity == null ? ModelData.EMPTY : blockEntity.getModelData(); + var renderer = Minecraft.getInstance().getBlockRenderer(); + renderer.renderSingleBlock(state, poseStack, immediate, 15728880, OverlayTexture.NO_OVERLAY, modelData, null); + } } poseStack.popPose(); diff --git a/src/client/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBER.java b/src/client/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBER.java index c9aaedf15..025f442b9 100644 --- a/src/client/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBER.java +++ b/src/client/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBER.java @@ -27,6 +27,7 @@ import aztech.modern_industrialization.MITags; import aztech.modern_industrialization.machines.MachineBlock; import aztech.modern_industrialization.machines.MachineBlockEntityRenderer; +import aztech.modern_industrialization.machines.multiblocks.structure.member.LiteralStructureMember; import aztech.modern_industrialization.util.RenderHelper; import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.Minecraft; @@ -37,7 +38,10 @@ import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.AABB; import org.jetbrains.annotations.Nullable; @@ -50,6 +54,8 @@ public MultiblockMachineBER(BlockEntityRendererProvider.Context ctx) { public void render(MultiblockMachineBlockEntity be, float tickDelta, PoseStack matrices, MultiBufferSource vcp, int light, int overlay) { super.render(be, tickDelta, matrices, vcp, light, overlay); + Level level = be.getLevel(); + // Only render if holding a wrench AND if the shape is not valid. boolean drawHighlights = isHoldingWrench() && !be.isShapeValid(); HatchType hatchType = getHeldHatchType(); @@ -70,13 +76,23 @@ public void render(MultiblockMachineBlockEntity be, float tickDelta, PoseStack m } } if (drawHighlights) { - if (!matcher.matches(pos, be.getLevel(), null)) { - if (be.getLevel().getBlockState(pos).isAir()) { + if (!matcher.matches(pos, level, null)) { + if (level.getBlockState(pos).isAir()) { // Enqueue state preview - MultiblockErrorHighlight.enqueueHighlight(pos, matcher.getSimpleMember(pos).getPreviewState()); + SimpleMember member = matcher.getSimpleMember(pos); + BlockState state = ShapeMatcher.toWorldState(level, pos, member.getPreviewState(), matcher.controllerDirection); + BlockEntity blockEntity = null; + if (member instanceof LiteralStructureMember literalMember && state.getBlock() instanceof EntityBlock entityBlock) { + blockEntity = entityBlock.newBlockEntity(pos, state); + blockEntity.setLevel(level); + if (literalMember.nbt() != null) { + blockEntity.loadCustomOnly(literalMember.nbt(), level.registryAccess()); + } + } + MultiblockErrorHighlight.enqueueHighlight(pos, state, blockEntity); } else { // Enqueue red cube - MultiblockErrorHighlight.enqueueHighlight(pos, null); + MultiblockErrorHighlight.enqueueHighlight(pos, null, null); } } } diff --git a/src/client/java/aztech/modern_industrialization/proxy/ClientProxy.java b/src/client/java/aztech/modern_industrialization/proxy/ClientProxy.java index d535dcd90..bbc484106 100644 --- a/src/client/java/aztech/modern_industrialization/proxy/ClientProxy.java +++ b/src/client/java/aztech/modern_industrialization/proxy/ClientProxy.java @@ -29,7 +29,7 @@ import aztech.modern_industrialization.blocks.storage.barrel.BarrelRenderer; import aztech.modern_industrialization.blocks.storage.tank.AbstractTankBlockEntity; import aztech.modern_industrialization.blocks.storage.tank.TankRenderer; -import aztech.modern_industrialization.blocks.structure.StructureMultiblockBER; +import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBER; import aztech.modern_industrialization.blocks.structure.controller.StructureMultiblockControllerBlockEntity; import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlockEntity; import aztech.modern_industrialization.client.screen.structure.StructureMultiblockControllerEditScreen; @@ -177,9 +177,9 @@ public void openStructureMultiblockMemberScreen(Player player, StructureMultiblo @Override public void receiveStructureMisconfiguredBlocksPacket(StructureMisconfiguredBlocksPacket packet, BasePacket.Context ctx) { if (packet.forget()) { - StructureMultiblockBER.forgetMisconfigured(packet.positions()); + StructureMultiblockControllerBER.forgetMisconfigured(packet.positions()); } else { - StructureMultiblockBER.setMisconfigured(packet.positions()); + StructureMultiblockControllerBER.setMisconfigured(packet.positions()); } } } diff --git a/src/generated/resources/assets/modern_industrialization/lang/en_us.json b/src/generated/resources/assets/modern_industrialization/lang/en_us.json index 3b154dad1..0ad8a094d 100644 --- a/src/generated/resources/assets/modern_industrialization/lang/en_us.json +++ b/src/generated/resources/assets/modern_industrialization/lang/en_us.json @@ -1717,6 +1717,7 @@ "text.modern_industrialization.SteamDrillToggle": "- Toggle Silk Touch with %s + %s.", "text.modern_industrialization.SteamDrillWaterHelp": "- Press %s on still or flowing water to fill.", "text.modern_industrialization.StructureMultiblockCasing": "Machine Casing", + "text.modern_industrialization.StructureMultiblockGuiIncludeBlockEntities": "Include NBT", "text.modern_industrialization.StructureMultiblockGuiLoad": "LOAD", "text.modern_industrialization.StructureMultiblockGuiLoadTooltip": "Hold SHIFT to place actual blocks instead of structure blocks.", "text.modern_industrialization.StructureMultiblockGuiMode": "MODE", diff --git a/src/main/java/aztech/modern_industrialization/MIText.java b/src/main/java/aztech/modern_industrialization/MIText.java index 41ebbd621..57bbbc786 100644 --- a/src/main/java/aztech/modern_industrialization/MIText.java +++ b/src/main/java/aztech/modern_industrialization/MIText.java @@ -247,6 +247,7 @@ public enum MIText { SteamDrillToggle("- Toggle Silk Touch with %s + %s."), SteamDrillWaterHelp("- Press %s on still or flowing water to fill."), StructureMultiblockCasing("Machine Casing"), + StructureMultiblockGuiIncludeBlockEntities("Include NBT"), StructureMultiblockGuiLoad("LOAD"), StructureMultiblockGuiLoadTooltip("Hold SHIFT to place actual blocks instead of structure blocks."), StructureMultiblockGuiMode("MODE"), diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlockEntity.java index 0c8c362b8..8531fb2a1 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlockEntity.java @@ -54,6 +54,7 @@ public class StructureMultiblockControllerBlockEntity extends FastBlockEntity im private MachineCasing casing; private StructureControllerBounds bounds = new StructureControllerBounds(0, 0, 0, 1, 1, 1); private boolean showBounds; + private boolean includeBlockEntities; public StructureMultiblockControllerBlockEntity(BlockPos pos, BlockState state) { super(MIRegistries.STRUCTURE_MULTIBLOCK_CONTROLLER_BE.get(), pos, state); @@ -116,6 +117,14 @@ public void setShowBounds(boolean showBounds) { this.showBounds = showBounds; } + public boolean includeBlockEntities() { + return includeBlockEntities; + } + + public void setIncludeBlockEntities(boolean includeBlockEntities) { + this.includeBlockEntities = includeBlockEntities; + } + @Override public boolean isController() { return true; @@ -158,6 +167,7 @@ protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) boundsTag.put("size", NbtUtils.writeBlockPos(new BlockPos(bounds.sizeX(), bounds.sizeY(), bounds.sizeZ()))); tag.put("bounds", boundsTag); tag.putBoolean("show_bounds", showBounds); + tag.putBoolean("include_block_entities", includeBlockEntities); } @Override @@ -177,6 +187,7 @@ protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) bounds = new StructureControllerBounds(0, 0, 0, 1, 1, 1); } showBounds = tag.getBoolean("show_bounds"); + includeBlockEntities = tag.getBoolean("include_block_entities"); this.updateBlockState(); } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java index 95b4b8ef8..91d0a49f7 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java @@ -24,6 +24,7 @@ package aztech.modern_industrialization.machines.multiblocks; import aztech.modern_industrialization.blocks.FastBlockEntity; +import aztech.modern_industrialization.machines.multiblocks.structure.member.LiteralStructureMember; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; import aztech.modern_industrialization.machines.multiblocks.world.ChunkEventListener; import aztech.modern_industrialization.machines.multiblocks.world.ChunkEventListeners; @@ -37,8 +38,10 @@ import java.util.Set; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.Rotation; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; @@ -177,7 +180,8 @@ public boolean matches(BlockPos pos, Level world, @Nullable List block) { return new SimpleMember() { @Override - public boolean matchesState(BlockState state) { + public boolean matchesState(BlockState state, @Nullable BlockEntity blockEntity) { return state.is(block.get()); } @@ -67,7 +69,7 @@ static SimpleMember forBlockState(BlockState state) { return new SimpleMember() { @Override - public boolean matchesState(BlockState state2) { + public boolean matchesState(BlockState state2, @Nullable BlockEntity blockEntity) { return state == state2; } @@ -81,7 +83,7 @@ public BlockState getPreviewState() { static SimpleMember verticalChain() { return new SimpleMember() { @Override - public boolean matchesState(BlockState state) { + public boolean matchesState(BlockState state, @Nullable BlockEntity blockEntity) { return state.is(Blocks.CHAIN) && state.getValue(RotatedPillarBlock.AXIS) == Direction.Axis.Y; } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java index 7274419d0..fce163444 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java @@ -50,6 +50,7 @@ import net.minecraft.FileUtil; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.FastBufferedInputStream; import net.minecraft.world.level.Level; @@ -95,9 +96,15 @@ public static void register(ResourceLocation id, ShapeTemplate template) { STRUCTURE_TEMPLATES.put(id, template); } + @Nullable + public static CompoundTag maybeTag(@Nullable BlockEntity blockEntity) { + return blockEntity == null ? null : blockEntity.saveCustomOnly(blockEntity.getLevel().registryAccess()); + } + public static StructureResult fromWorld(ResourceLocation id, Level level, BlockPos controllerPos, Direction controllerDirection, - MachineCasing hatchCasing, StructureControllerBounds bounds) { + MachineCasing hatchCasing, StructureControllerBounds bounds, + boolean includeBlockEntities) { Objects.requireNonNull(id); Objects.requireNonNull(level); Objects.requireNonNull(controllerPos); @@ -123,15 +130,13 @@ public static StructureResult fromWorld(ResourceLocation id, Level level, for (BlockPos pos : BlockPos.betweenClosed(minPos, maxPos)) { BlockState state = toTemplateState(level, pos, level.getBlockState(pos), controllerDirection); - if (state.isAir() || state.is(Blocks.STRUCTURE_VOID)) { continue; } + BlockEntity blockEntity = level.getBlockEntity(pos); - BlockPos templatePos = toTemplatePos(controllerPos, controllerDirection, pos); - StructureMember member = StructureMember.literal(() -> state); + StructureMember member = StructureMember.literal(() -> state, includeBlockEntities ? blockEntity : null); - BlockEntity blockEntity = level.getBlockEntity(pos); if (blockEntity instanceof StructureMemberOverride override) { if (!override.isConfigurationValid()) { misconfiguredBlocks.add(pos.immutable()); @@ -152,6 +157,7 @@ public static StructureResult fromWorld(ResourceLocation id, Level level, hatchBlocks.add(pos.immutable()); hatchFlags = hatch.hatchFlags(); } + BlockPos templatePos = toTemplatePos(controllerPos, controllerDirection, pos); template.add(templatePos.getX(), templatePos.getY(), templatePos.getZ(), member, hatchFlags); } } @@ -159,15 +165,15 @@ public static StructureResult fromWorld(ResourceLocation id, Level level, if (controllerBlocks.isEmpty()) { return new StructureResult.NoController(); } - if (hatchBlocks.isEmpty()) { - return new StructureResult.NoHatches(); - } if (controllerBlocks.size() > 1) { return new StructureResult.TooManyControllers(controllerBlocks); } if (!misconfiguredBlocks.isEmpty()) { return new StructureResult.MisconfiguredBlocks(misconfiguredBlocks); } + if (hatchBlocks.isEmpty()) { + return new StructureResult.NoHatches(); + } return new StructureResult.Success(id, template.build()); } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java index 873dedec4..3b280d505 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java @@ -24,22 +24,40 @@ package aztech.modern_industrialization.machines.multiblocks.structure.member; import aztech.modern_industrialization.blocks.FastBlockEntity; +import aztech.modern_industrialization.machines.multiblocks.structure.MIStructureTemplateManager; import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StateStructureMemberTest; +import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StructureMemberTest; import aztech.modern_industrialization.util.MIExtraCodecs; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import java.util.List; import java.util.Optional; import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.neoforged.neoforge.common.util.Lazy; +import org.jetbrains.annotations.Nullable; public final class LiteralStructureMember extends SimpleStructureMember { - public static final MapCodec CODEC = MIExtraCodecs.LAZY_BLOCK_STATE - .xmap(LiteralStructureMember::new, member -> member.preview).fieldOf("state"); + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance + .group( + MIExtraCodecs.LAZY_BLOCK_STATE.fieldOf("state").forGetter(member -> member.preview), + CompoundTag.CODEC.optionalFieldOf("nbt").forGetter(member -> Optional.ofNullable(member.nbt()))) + .apply(instance, (preview, nbt) -> new LiteralStructureMember(preview, nbt.orElse(null)))); - public LiteralStructureMember(Lazy previewSupplier) { + private final CompoundTag nbt; + + public LiteralStructureMember(Lazy previewSupplier, @Nullable CompoundTag nbt) { super(previewSupplier, List.of(new StateStructureMemberTest(previewSupplier))); + this.nbt = nbt; + } + + @Nullable + public CompoundTag nbt() { + return nbt != null ? nbt.copy() : null; } @Override @@ -47,8 +65,29 @@ public StructureMemberType type() { return StructureMemberType.LITERAL; } + @Override + public boolean matchesState(BlockState state, @Nullable BlockEntity blockEntity) { + CompoundTag beTag = MIStructureTemplateManager.maybeTag(blockEntity); + for (StructureMemberTest test : tests) { + if (test.matchesState(state) && NbtUtils.compareNbt(nbt, beTag, true)) { + return true; + } + } + return false; + } + @Override public Optional> asStructureBlock(BlockPos pos, boolean required) { return Optional.empty(); } + + @Override + public boolean equals(Object o) { + if (o instanceof LiteralStructureMember other && this.getClass() == other.getClass()) { + return this.getPreviewState() == other.getPreviewState() && + tests.containsAll(other.tests) && other.tests.containsAll(tests) && + NbtUtils.compareNbt(nbt, other.nbt, true); + } + return false; + } } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java index 37b42e27d..8c57d2132 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java @@ -38,8 +38,10 @@ import java.util.Objects; import java.util.Optional; import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.neoforged.neoforge.common.util.Lazy; +import org.jetbrains.annotations.Nullable; public sealed class SimpleStructureMember extends StructureMember permits HatchStructureMember, LiteralStructureMember { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance @@ -82,7 +84,7 @@ public Optional> asStructureBlock(BlockPos pos } @Override - public boolean matchesState(BlockState state) { + public boolean matchesState(BlockState state, @Nullable BlockEntity blockEntity) { for (StructureMemberTest test : tests) { if (test.matchesState(state)) { return true; diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java index 522ad2d1b..2c5d7d987 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java @@ -27,6 +27,7 @@ import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.HatchFlags; import aztech.modern_industrialization.machines.multiblocks.SimpleMember; +import aztech.modern_industrialization.machines.multiblocks.structure.MIStructureTemplateManager; import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StructureMemberTest; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Codec; @@ -35,8 +36,10 @@ import java.util.Optional; import java.util.function.Supplier; import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.neoforged.neoforge.common.util.Lazy; +import org.jetbrains.annotations.Nullable; public sealed abstract class StructureMember implements SimpleMember permits SimpleStructureMember, VariableStructureMember { public static final Codec CODEC = Codec.STRING.flatComapMap( @@ -51,8 +54,8 @@ public static SimpleStructureMember simple(Supplier preview, List blockState) { - return new LiteralStructureMember(Lazy.of(blockState)); + public static LiteralStructureMember literal(Supplier blockState, @Nullable BlockEntity blockEntity) { + return new LiteralStructureMember(Lazy.of(blockState), MIStructureTemplateManager.maybeTag(blockEntity)); } public static HatchStructureMember hatch(Supplier preview, List tests, MachineCasing casing, diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/VariableStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/VariableStructureMember.java index 32a3c31cc..3a257fdeb 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/VariableStructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/VariableStructureMember.java @@ -33,7 +33,9 @@ import java.util.Objects; import java.util.Optional; import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; public final class VariableStructureMember extends StructureMember { public static final MapCodec CODEC = Codec.STRING.xmap(VariableStructureMember::new, VariableStructureMember::name) @@ -66,7 +68,7 @@ public Optional> asStructureBlock(BlockPos pos } @Override - public boolean matchesState(BlockState state) { + public boolean matchesState(BlockState state, @Nullable BlockEntity blockEntity) { throw new UnsupportedOperationException("Tried to use a variable structure member without replacing it in the template."); } diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java index ddb23b0ad..8a2283aec 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java @@ -61,7 +61,7 @@ public void handle(Context ctx) { ResourceLocation id = controller.getId(); var result = MIStructureTemplateManager.fromWorld(id, level, pos, state.getValue(StructureMultiblockControllerBlock.FACING), - controller.getCasing(), controller.getBounds()); + controller.getCasing(), controller.getBounds(), controller.includeBlockEntities()); if (result instanceof StructureResult.Success success) { if (MIStructureTemplateManager.save(id, success.template())) { MIStructureTemplateManager.register(id, success.template()); diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java index a14652531..f27d7bc23 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java @@ -35,12 +35,13 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; +import net.neoforged.neoforge.network.codec.NeoForgeStreamCodecs; public record StructureUpdateControllerPacket(BlockPos pos, StructureControllerMode mode, String inputId, String inputCasing, - StructureControllerBounds bounds, boolean showBounds) + StructureControllerBounds bounds, boolean showBounds, boolean includeBlockEntities) implements BasePacket { - public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + public static final StreamCodec STREAM_CODEC = NeoForgeStreamCodecs.composite( BlockPos.STREAM_CODEC, StructureUpdateControllerPacket::pos, ByteBufCodecs.idMapper((i) -> StructureControllerMode.values()[i], Enum::ordinal), @@ -53,6 +54,8 @@ public record StructureUpdateControllerPacket(BlockPos pos, StructureControllerM StructureUpdateControllerPacket::bounds, ByteBufCodecs.BOOL, StructureUpdateControllerPacket::showBounds, + ByteBufCodecs.BOOL, + StructureUpdateControllerPacket::includeBlockEntities, StructureUpdateControllerPacket::new); @Override @@ -73,6 +76,7 @@ public void handle(Context ctx) { controller.setInputCasing(inputCasing); controller.setBounds(bounds); controller.setShowBounds(showBounds); + controller.setIncludeBlockEntities(includeBlockEntities); controller.sync(); controller.setChanged(); From 3c54debbe67378628a8ab0d0a391ddb78d8fc3f4 Mon Sep 17 00:00:00 2001 From: Swedz Date: Fri, 29 Nov 2024 06:27:55 -0500 Subject: [PATCH 69/89] Listen to block entity updates for multiblock rematching --- .../world/ChunkEventListeners.java | 13 +++++- .../mixin/LevelMixin.java | 43 +++++++++++++++++++ .../modern_industrialization.mixins.json | 21 ++++----- 3 files changed, 65 insertions(+), 12 deletions(-) create mode 100644 src/main/java/aztech/modern_industrialization/mixin/LevelMixin.java diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/world/ChunkEventListeners.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/world/ChunkEventListeners.java index 00655f654..7e21b4519 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/world/ChunkEventListeners.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/world/ChunkEventListeners.java @@ -23,12 +23,14 @@ */ package aztech.modern_industrialization.machines.multiblocks.world; +import aztech.modern_industrialization.machines.MachineBlockEntity; import java.util.Set; import net.minecraft.core.BlockPos; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.event.level.BlockEvent; import net.neoforged.neoforge.event.level.ChunkEvent; @@ -69,12 +71,12 @@ public static void init() { }); NeoForge.EVENT_BUS.addListener(BlockEvent.NeighborNotifyEvent.class, event -> { if (event.getLevel() instanceof Level level) { - onBlockStateChange(level, new ChunkPos(event.getPos()), event.getPos()); + onBlockUpdate(level, new ChunkPos(event.getPos()), event.getPos()); } }); } - public static void onBlockStateChange(Level world, ChunkPos chunkPos, BlockPos pos) { + public static void onBlockUpdate(Level world, ChunkPos chunkPos, BlockPos pos) { // We skip block state changes that happen outside of the server thread. // Hopefully that won't cause problems. if (world instanceof ServerLevel serverLevel && serverLevel.getServer().isSameThread()) { @@ -87,6 +89,13 @@ public static void onBlockStateChange(Level world, ChunkPos chunkPos, BlockPos p } } + public static void onBlockEntityUpdate(Level world, BlockPos pos) { + BlockEntity blockEntity = world.getBlockEntity(pos); + if (!(blockEntity instanceof MachineBlockEntity)) { + onBlockUpdate(world, new ChunkPos(pos), pos); + } + } + private static void ensureServerThread(@Nullable MinecraftServer server) { if (server == null) { throw new RuntimeException("Null server!"); diff --git a/src/main/java/aztech/modern_industrialization/mixin/LevelMixin.java b/src/main/java/aztech/modern_industrialization/mixin/LevelMixin.java new file mode 100644 index 000000000..ba0b879a5 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/mixin/LevelMixin.java @@ -0,0 +1,43 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.mixin; + +import aztech.modern_industrialization.machines.multiblocks.world.ChunkEventListeners; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.Level; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(Level.class) +public class LevelMixin { + @Inject(method = "blockEntityChanged", at = @At("HEAD")) + public void blockEntityChanged(BlockPos pos, CallbackInfo ci) { + Level level = (Level) (Object) this; + if (!level.isClientSide()) { + ChunkEventListeners.onBlockEntityUpdate(level, pos); + } + } +} diff --git a/src/main/resources/modern_industrialization.mixins.json b/src/main/resources/modern_industrialization.mixins.json index a46448f5b..8e31d87df 100644 --- a/src/main/resources/modern_industrialization.mixins.json +++ b/src/main/resources/modern_industrialization.mixins.json @@ -1,13 +1,14 @@ { - "required": true, - "minVersion": "0.8", - "package": "aztech.modern_industrialization.mixin", - "compatibilityLevel": "JAVA_8", - "mixins": [ - "BlockStateBaseMixin", - "ItemStackMixin" - ], - "injectors": { - "defaultRequire": 1 + "required": true, + "minVersion": "0.8", + "package": "aztech.modern_industrialization.mixin", + "compatibilityLevel": "JAVA_8", + "mixins": [ + "BlockStateBaseMixin", + "ItemStackMixin", + "LevelMixin" + ], + "injectors": { + "defaultRequire": 1 } } From 84ae34b5e9c5ff38c9c6d81ba28bd8b8eb1d2330 Mon Sep 17 00:00:00 2001 From: Swedz Date: Fri, 29 Nov 2024 06:30:51 -0500 Subject: [PATCH 70/89] Handle block entity matching on the server instead of client --- .../multiblocks/MultiblockMachineBER.java | 2 +- .../components/ShapeValidComponent.java | 43 +++++++++++- .../MultiblockMachineBlockEntity.java | 2 +- .../machines/multiblocks/ShapeMatcher.java | 35 ++++++---- .../member/LiteralStructureMember.java | 6 +- .../StructureLoadControllerPacket.java | 2 +- .../util/NbtHelper.java | 69 +++++++++++++++++-- 7 files changed, 135 insertions(+), 24 deletions(-) diff --git a/src/client/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBER.java b/src/client/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBER.java index 025f442b9..d71ebfc58 100644 --- a/src/client/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBER.java +++ b/src/client/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBER.java @@ -76,7 +76,7 @@ public void render(MultiblockMachineBlockEntity be, float tickDelta, PoseStack m } } if (drawHighlights) { - if (!matcher.matches(pos, level, null)) { + if (!matcher.matches(pos, level)) { if (level.getBlockState(pos).isAir()) { // Enqueue state preview SimpleMember member = matcher.getSimpleMember(pos); diff --git a/src/main/java/aztech/modern_industrialization/machines/components/ShapeValidComponent.java b/src/main/java/aztech/modern_industrialization/machines/components/ShapeValidComponent.java index 0506b2c68..ccd93d030 100644 --- a/src/main/java/aztech/modern_industrialization/machines/components/ShapeValidComponent.java +++ b/src/main/java/aztech/modern_industrialization/machines/components/ShapeValidComponent.java @@ -24,8 +24,14 @@ package aztech.modern_industrialization.machines.components; import aztech.modern_industrialization.machines.IComponent; +import java.util.ArrayList; +import java.util.List; +import net.minecraft.core.BlockPos; import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.nbt.Tag; /** * Syncing whether the multiblock shape is currently valid with the clients, to @@ -34,13 +40,34 @@ public class ShapeValidComponent implements IComponent.ClientOnly { private boolean lastShapeValid = false; public boolean shapeValid = false; + private boolean mismatchingBlockEntitiesChanged = false; + + private final List mismatchingBlockEntities = new ArrayList<>(); + + public boolean isBlockEntityMatchingAt(BlockPos pos) { + return !mismatchingBlockEntities.contains(pos); + } + + // TODO SWEDZ: this causes update() to always return true + public void clearMisMatchingBlockEntities() { + mismatchingBlockEntities.clear(); + mismatchingBlockEntitiesChanged = true; + } + + public void addMisMatchingBlockEntity(BlockPos pos) { + if (!mismatchingBlockEntities.contains(pos)) { + mismatchingBlockEntities.add(pos); + mismatchingBlockEntitiesChanged = true; + } + } /** * Return true if this component should be synced with the client. */ public boolean update() { - if (lastShapeValid != shapeValid) { + if (lastShapeValid != shapeValid || mismatchingBlockEntitiesChanged) { lastShapeValid = shapeValid; + mismatchingBlockEntitiesChanged = false; return true; } return false; @@ -49,10 +76,24 @@ public boolean update() { @Override public void writeClientNbt(CompoundTag tag, HolderLookup.Provider registries) { tag.putBoolean("shapeValid", shapeValid); + ListTag mismatchingBlockEntitiesTag = new ListTag(); + for (BlockPos pos : mismatchingBlockEntities) { + CompoundTag blockTag = new CompoundTag(); + blockTag.put("pos", NbtUtils.writeBlockPos(pos)); + mismatchingBlockEntitiesTag.add(blockTag); + } + tag.put("mismatchingBlockEntities", mismatchingBlockEntitiesTag); } @Override public void readClientNbt(CompoundTag tag, HolderLookup.Provider registries) { shapeValid = tag.getBoolean("shapeValid"); + mismatchingBlockEntities.clear(); + ListTag mismatchingBlockEntitiesTag = tag.getList("mismatchingBlockEntities", Tag.TAG_COMPOUND); + for (Tag blockTag : mismatchingBlockEntitiesTag) { + if (blockTag instanceof CompoundTag blockCompoundTag) { + NbtUtils.readBlockPos(blockCompoundTag, "pos").ifPresent(mismatchingBlockEntities::add); + } + } } } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBlockEntity.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBlockEntity.java index d18ab0a2e..141c9141e 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBlockEntity.java @@ -52,7 +52,7 @@ public ShapeMatcher getShapeMatcher() { } public ShapeMatcher createShapeMatcher() { - return new ShapeMatcher(level, worldPosition, orientation.facingDirection, getActiveShape()); + return new ShapeMatcher(level, worldPosition, orientation.facingDirection, getActiveShape(), shapeValid); } protected void onLink() { diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java index 91d0a49f7..16f968285 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java @@ -24,6 +24,7 @@ package aztech.modern_industrialization.machines.multiblocks; import aztech.modern_industrialization.blocks.FastBlockEntity; +import aztech.modern_industrialization.machines.components.ShapeValidComponent; import aztech.modern_industrialization.machines.multiblocks.structure.member.LiteralStructureMember; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; import aztech.modern_industrialization.machines.multiblocks.world.ChunkEventListener; @@ -51,10 +52,12 @@ * Status of a multiblock shape bound to some position and direction. */ public class ShapeMatcher implements ChunkEventListener { - public ShapeMatcher(Level world, BlockPos controllerPos, Direction controllerDirection, ShapeTemplate template) { + public ShapeMatcher(Level world, BlockPos controllerPos, Direction controllerDirection, ShapeTemplate template, + @Nullable ShapeValidComponent shapeValid) { this.controllerPos = controllerPos; this.controllerDirection = controllerDirection; this.template = template; + this.shapeValid = shapeValid; this.simpleMembers = toWorldPos(controllerPos, controllerDirection, template.simpleMembers); this.hatchFlags = toWorldPos(controllerPos, controllerDirection, template.hatchFlags); } @@ -62,6 +65,8 @@ public ShapeMatcher(Level world, BlockPos controllerPos, Direction controllerDir protected final BlockPos controllerPos; protected final Direction controllerDirection; protected final ShapeTemplate template; + @Nullable + protected final ShapeValidComponent shapeValid; protected final Map simpleMembers; protected final Map hatchFlags; @@ -166,36 +171,40 @@ public void unlinkHatches() { } matchedHatches.clear(); + shapeValid.clearMisMatchingBlockEntities(); matchSuccessful = false; needsRematch = true; } /** - * Return true if there was a match, and append matched hatches to the list if - * it's not null. + * Return true if there was a match, and append matched hatches and mismatching block entities to the internal lists. */ - public boolean matches(BlockPos pos, Level world, @Nullable List hatches) { + public boolean matches(BlockPos pos, Level world) { SimpleMember simpleMember = simpleMembers.get(pos); if (simpleMember == null) return false; BlockState state = toTemplateState(world, pos, world.getBlockState(pos), controllerDirection); - BlockEntity blockEntity = world.getBlockEntity(pos); - if (simpleMember.matchesState(state, blockEntity)) - return true; - BlockEntity be = world.getBlockEntity(pos); + if (be instanceof HatchBlockEntity hatch) { HatchFlags flags = hatchFlags.get(pos); if (flags != null && flags.allows(hatch.getHatchType()) && !hatch.isMatched()) { - if (matchedHatches != null) { - matchedHatches.add(hatch); - } + matchedHatches.add(hatch); return true; } } - return false; + boolean matches = simpleMember.matchesState(state, be); + if (be != null && shapeValid != null) { + boolean client = world.isClientSide(); + if (client) { + return shapeValid.isBlockEntityMatchingAt(pos); + } else if (!matches) { + shapeValid.addMisMatchingBlockEntity(pos); + } + } + return matches; } public boolean needsRematch() { @@ -213,7 +222,7 @@ public void rematch(Level world) { for (BlockPos pos : simpleMembers.keySet()) { // TODO: check if the chunk is loaded - if (!matches(pos, world, matchedHatches)) { + if (!matches(pos, world)) { matchSuccessful = false; } } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java index 3b280d505..265540d13 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java @@ -28,6 +28,7 @@ import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StateStructureMemberTest; import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StructureMemberTest; import aztech.modern_industrialization.util.MIExtraCodecs; +import aztech.modern_industrialization.util.NbtHelper; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; @@ -35,7 +36,6 @@ import java.util.Optional; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.NbtUtils; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.neoforged.neoforge.common.util.Lazy; @@ -69,7 +69,7 @@ public StructureMemberType type() { public boolean matchesState(BlockState state, @Nullable BlockEntity blockEntity) { CompoundTag beTag = MIStructureTemplateManager.maybeTag(blockEntity); for (StructureMemberTest test : tests) { - if (test.matchesState(state) && NbtUtils.compareNbt(nbt, beTag, true)) { + if (test.matchesState(state) && NbtHelper.equals(nbt, beTag)) { return true; } } @@ -86,7 +86,7 @@ public boolean equals(Object o) { if (o instanceof LiteralStructureMember other && this.getClass() == other.getClass()) { return this.getPreviewState() == other.getPreviewState() && tests.containsAll(other.tests) && other.tests.containsAll(tests) && - NbtUtils.compareNbt(nbt, other.nbt, true); + NbtHelper.equals(nbt, other.nbt); } return false; } diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureLoadControllerPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureLoadControllerPacket.java index 33aace72a..5ab9884f7 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureLoadControllerPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureLoadControllerPacket.java @@ -74,7 +74,7 @@ public void handle(Context ctx) { return; } ShapeTemplate template = MIStructureTemplateManager.get(id); - ShapeMatcher shapeMatcher = new ShapeMatcher(level, pos, state.getValue(BlockStateProperties.HORIZONTAL_FACING), template); + ShapeMatcher shapeMatcher = new ShapeMatcher(level, pos, state.getValue(BlockStateProperties.HORIZONTAL_FACING), template, null); shapeMatcher.buildMultiblock(level, structureBlocks); player.sendSystemMessage(MIText.StructureMultiblockLoadSuccess.text(id.toString())); } diff --git a/src/main/java/aztech/modern_industrialization/util/NbtHelper.java b/src/main/java/aztech/modern_industrialization/util/NbtHelper.java index 7743961f7..a2061b879 100644 --- a/src/main/java/aztech/modern_industrialization/util/NbtHelper.java +++ b/src/main/java/aztech/modern_industrialization/util/NbtHelper.java @@ -25,16 +25,15 @@ import aztech.modern_industrialization.pipes.api.PipeEndpointType; import aztech.modern_industrialization.thirdparty.fabrictransfer.api.fluid.FluidVariant; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.function.Function; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.HolderLookup; import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; -import net.minecraft.nbt.StringTag; -import net.minecraft.nbt.Tag; +import net.minecraft.nbt.*; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.Item; import net.minecraft.world.level.material.Fluid; @@ -155,4 +154,66 @@ public static void putNonzeroInt(CompoundTag tag, String key, int i) { tag.putInt(key, i); } } + + /** + * A more reasonable version of NbtUtils#compareNbt that compares numeric tags without requiring they be of the same type. + */ + public static boolean equals(@Nullable Tag a, @Nullable Tag b) { + if (a == b) { + return true; + } + if (a == null || b == null) { + return false; + } + return switch (a) { + case CompoundTag tagA -> { + if (b instanceof CompoundTag tagB) { + if (tagA.size() != tagB.size()) { + yield false; + } + Set allKeys = new HashSet<>(); + allKeys.addAll(tagA.getAllKeys()); + allKeys.addAll(tagB.getAllKeys()); + for (String key : allKeys) { + Tag valueA = tagA.get(key); + Tag valueB = tagB.get(key); + if (!equals(valueA, valueB)) { + yield false; + } + } + yield true; + } + yield false; + } + case ListTag tagA -> { + if (b instanceof ListTag tagB) { + if (tagA.size() != tagB.size()) { + yield false; + } + for (int i = 0; i < tagA.size(); i++) { + Tag valueA = tagA.get(i); + Tag valueB = tagB.get(i); + if (!equals(valueA, valueB)) { + yield false; + } + } + yield true; + } + yield false; + } + case NumericTag tagA -> { + if (b instanceof NumericTag tagB) { + if (a instanceof DoubleTag || a instanceof FloatTag || b instanceof DoubleTag || b instanceof FloatTag) { + yield tagA.getAsDouble() == tagB.getAsDouble(); + } else if (a instanceof LongTag || b instanceof LongTag) { + yield tagA.getAsLong() == tagB.getAsLong(); + } else { + yield tagA.getAsInt() == tagB.getAsInt(); + } + } + yield false; + } + default -> a.equals(b); + }; + } } From c247f26844ff440138fdd929a3144f364c41167c Mon Sep 17 00:00:00 2001 From: Swedz Date: Fri, 29 Nov 2024 06:32:44 -0500 Subject: [PATCH 71/89] Consistency --- .../machines/components/ShapeValidComponent.java | 4 ++-- .../machines/multiblocks/ShapeMatcher.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/machines/components/ShapeValidComponent.java b/src/main/java/aztech/modern_industrialization/machines/components/ShapeValidComponent.java index ccd93d030..9b0c18eba 100644 --- a/src/main/java/aztech/modern_industrialization/machines/components/ShapeValidComponent.java +++ b/src/main/java/aztech/modern_industrialization/machines/components/ShapeValidComponent.java @@ -49,12 +49,12 @@ public boolean isBlockEntityMatchingAt(BlockPos pos) { } // TODO SWEDZ: this causes update() to always return true - public void clearMisMatchingBlockEntities() { + public void clearMismatchingBlockEntities() { mismatchingBlockEntities.clear(); mismatchingBlockEntitiesChanged = true; } - public void addMisMatchingBlockEntity(BlockPos pos) { + public void addMismatchingBlockEntity(BlockPos pos) { if (!mismatchingBlockEntities.contains(pos)) { mismatchingBlockEntities.add(pos); mismatchingBlockEntitiesChanged = true; diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java index 16f968285..9ae3b6839 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java @@ -171,7 +171,7 @@ public void unlinkHatches() { } matchedHatches.clear(); - shapeValid.clearMisMatchingBlockEntities(); + shapeValid.clearMismatchingBlockEntities(); matchSuccessful = false; needsRematch = true; } @@ -201,7 +201,7 @@ public boolean matches(BlockPos pos, Level world) { if (client) { return shapeValid.isBlockEntityMatchingAt(pos); } else if (!matches) { - shapeValid.addMisMatchingBlockEntity(pos); + shapeValid.addMismatchingBlockEntity(pos); } } return matches; From 148530c91d95a878aa0a7707855a7ce6cb4f0364 Mon Sep 17 00:00:00 2001 From: Swedz Date: Sat, 30 Nov 2024 04:23:06 -0500 Subject: [PATCH 72/89] Only send machine update if the mismatching blocks actually changed --- .../machines/components/ShapeValidComponent.java | 13 ++++++------- .../machines/multiblocks/ShapeMatcher.java | 11 ++++++++--- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/machines/components/ShapeValidComponent.java b/src/main/java/aztech/modern_industrialization/machines/components/ShapeValidComponent.java index 9b0c18eba..9ed442868 100644 --- a/src/main/java/aztech/modern_industrialization/machines/components/ShapeValidComponent.java +++ b/src/main/java/aztech/modern_industrialization/machines/components/ShapeValidComponent.java @@ -40,24 +40,21 @@ public class ShapeValidComponent implements IComponent.ClientOnly { private boolean lastShapeValid = false; public boolean shapeValid = false; - private boolean mismatchingBlockEntitiesChanged = false; - private final List mismatchingBlockEntities = new ArrayList<>(); + private List lastMismatchingBlockEntities = new ArrayList<>(); + private List mismatchingBlockEntities = new ArrayList<>(); public boolean isBlockEntityMatchingAt(BlockPos pos) { return !mismatchingBlockEntities.contains(pos); } - // TODO SWEDZ: this causes update() to always return true public void clearMismatchingBlockEntities() { mismatchingBlockEntities.clear(); - mismatchingBlockEntitiesChanged = true; } public void addMismatchingBlockEntity(BlockPos pos) { if (!mismatchingBlockEntities.contains(pos)) { mismatchingBlockEntities.add(pos); - mismatchingBlockEntitiesChanged = true; } } @@ -65,9 +62,11 @@ public void addMismatchingBlockEntity(BlockPos pos) { * Return true if this component should be synced with the client. */ public boolean update() { - if (lastShapeValid != shapeValid || mismatchingBlockEntitiesChanged) { + if (lastShapeValid != shapeValid + || !lastMismatchingBlockEntities.containsAll(mismatchingBlockEntities) + || !mismatchingBlockEntities.containsAll(lastMismatchingBlockEntities)) { lastShapeValid = shapeValid; - mismatchingBlockEntitiesChanged = false; + lastMismatchingBlockEntities = List.copyOf(mismatchingBlockEntities); return true; } return false; diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java index 9ae3b6839..cf0d8e342 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java @@ -60,6 +60,10 @@ public ShapeMatcher(Level world, BlockPos controllerPos, Direction controllerDir this.shapeValid = shapeValid; this.simpleMembers = toWorldPos(controllerPos, controllerDirection, template.simpleMembers); this.hatchFlags = toWorldPos(controllerPos, controllerDirection, template.hatchFlags); + + if (shapeValid != null && !world.isClientSide()) { + shapeValid.clearMismatchingBlockEntities(); + } } protected final BlockPos controllerPos; @@ -171,7 +175,9 @@ public void unlinkHatches() { } matchedHatches.clear(); - shapeValid.clearMismatchingBlockEntities(); + if (shapeValid != null) { + shapeValid.clearMismatchingBlockEntities(); + } matchSuccessful = false; needsRematch = true; } @@ -197,8 +203,7 @@ public boolean matches(BlockPos pos, Level world) { boolean matches = simpleMember.matchesState(state, be); if (be != null && shapeValid != null) { - boolean client = world.isClientSide(); - if (client) { + if (world.isClientSide()) { return shapeValid.isBlockEntityMatchingAt(pos); } else if (!matches) { shapeValid.addMismatchingBlockEntity(pos); From 92dcba5825a0353733a4d9c1c5e1b02052938f1e Mon Sep 17 00:00:00 2001 From: Swedz Date: Sat, 30 Nov 2024 05:01:43 -0500 Subject: [PATCH 73/89] Fix delay and flickering with multiblock display in world --- .../components/ShapeValidComponent.java | 18 +++++++----------- .../MultiblockMachineBlockEntity.java | 1 + .../machines/multiblocks/ShapeMatcher.java | 4 ---- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/machines/components/ShapeValidComponent.java b/src/main/java/aztech/modern_industrialization/machines/components/ShapeValidComponent.java index 9ed442868..2ab5da84e 100644 --- a/src/main/java/aztech/modern_industrialization/machines/components/ShapeValidComponent.java +++ b/src/main/java/aztech/modern_industrialization/machines/components/ShapeValidComponent.java @@ -24,8 +24,8 @@ package aztech.modern_industrialization.machines.components; import aztech.modern_industrialization.machines.IComponent; -import java.util.ArrayList; -import java.util.List; +import java.util.HashSet; +import java.util.Set; import net.minecraft.core.BlockPos; import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; @@ -41,8 +41,8 @@ public class ShapeValidComponent implements IComponent.ClientOnly { private boolean lastShapeValid = false; public boolean shapeValid = false; - private List lastMismatchingBlockEntities = new ArrayList<>(); - private List mismatchingBlockEntities = new ArrayList<>(); + private Set lastMismatchingBlockEntities = new HashSet<>(); + private Set mismatchingBlockEntities = new HashSet<>(); public boolean isBlockEntityMatchingAt(BlockPos pos) { return !mismatchingBlockEntities.contains(pos); @@ -53,20 +53,16 @@ public void clearMismatchingBlockEntities() { } public void addMismatchingBlockEntity(BlockPos pos) { - if (!mismatchingBlockEntities.contains(pos)) { - mismatchingBlockEntities.add(pos); - } + mismatchingBlockEntities.add(pos); } /** * Return true if this component should be synced with the client. */ public boolean update() { - if (lastShapeValid != shapeValid - || !lastMismatchingBlockEntities.containsAll(mismatchingBlockEntities) - || !mismatchingBlockEntities.containsAll(lastMismatchingBlockEntities)) { + if (lastShapeValid != shapeValid || !lastMismatchingBlockEntities.equals(mismatchingBlockEntities)) { lastShapeValid = shapeValid; - lastMismatchingBlockEntities = List.copyOf(mismatchingBlockEntities); + lastMismatchingBlockEntities = Set.copyOf(mismatchingBlockEntities); return true; } return false; diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBlockEntity.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBlockEntity.java index 141c9141e..98d102f06 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBlockEntity.java @@ -108,6 +108,7 @@ public boolean useWrench(Player player, InteractionHand hand, BlockHitResult hit if (super.useWrench(player, hand, hitResult)) { if (!level.isClientSide) { unlink(); + link(); } return true; } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java index cf0d8e342..076e27301 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java @@ -60,10 +60,6 @@ public ShapeMatcher(Level world, BlockPos controllerPos, Direction controllerDir this.shapeValid = shapeValid; this.simpleMembers = toWorldPos(controllerPos, controllerDirection, template.simpleMembers); this.hatchFlags = toWorldPos(controllerPos, controllerDirection, template.hatchFlags); - - if (shapeValid != null && !world.isClientSide()) { - shapeValid.clearMismatchingBlockEntities(); - } } protected final BlockPos controllerPos; From 63a7776d4216d45c2ab714d4fe5d205399e02f91 Mon Sep 17 00:00:00 2001 From: Swedz Date: Sat, 30 Nov 2024 05:12:21 -0500 Subject: [PATCH 74/89] Dont try to place blocks outside of the world --- .../machines/multiblocks/ShapeMatcher.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java index 076e27301..39a3b61b7 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java @@ -264,6 +264,9 @@ public int buildMultiblock(Level level, boolean structureBlocks) { for (var entry : simpleMembers.entrySet()) { BlockPos pos = entry.getKey(); + if (!level.isInWorldBounds(pos)) { + continue; + } CompoundTag nbt = null; if (entry.getValue() instanceof StructureMember member) { var optionalStructureBlock = member.asStructureBlock(pos, structureBlocks); From 2e902f8a927cbe19dbf44ecac01f1ebdea1cae4e Mon Sep 17 00:00:00 2001 From: Swedz Date: Sat, 30 Nov 2024 05:34:02 -0500 Subject: [PATCH 75/89] Force load lazy block states as soon as possible --- .../machines/multiblocks/ShapeTemplate.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java index cc05b1b6d..2ad9df281 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java @@ -23,21 +23,29 @@ */ package aztech.modern_industrialization.machines.multiblocks; +import aztech.modern_industrialization.MI; import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.structure.MIStructureTemplateManager; import aztech.modern_industrialization.machines.multiblocks.structure.member.HatchStructureMember; +import aztech.modern_industrialization.machines.multiblocks.structure.member.SimpleStructureMember; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; import aztech.modern_industrialization.machines.multiblocks.structure.member.VariableStructureMember; +import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StateStructureMemberTest; +import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StructureMemberTest; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import java.util.*; import net.minecraft.core.BlockPos; import net.minecraft.resources.ResourceLocation; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; import org.jetbrains.annotations.Nullable; /** * An immutable description of a multiblock shape. */ +@EventBusSubscriber(modid = MI.ID, bus = EventBusSubscriber.Bus.MOD) public class ShapeTemplate { public static final Codec STRUCTURE_CODEC = InternalStructureTemplate.CODEC .xmap(structure -> { @@ -85,12 +93,35 @@ private record InternalStructureTemplate(MachineCasing casing, List TEMPLATES = new ArrayList<>(); + public final Map simpleMembers = new HashMap<>(); public final Map hatchFlags = new HashMap<>(); public final MachineCasing hatchCasing; private ShapeTemplate(MachineCasing hatchCasing) { this.hatchCasing = hatchCasing; + TEMPLATES.add(this); + } + + /** + * Forces all lazy block states in structures to get loaded during startup as soon as blocks are in the registry. This prevents any delay later + * where we otherwise would need to be parsing json elements during play. + */ + @SubscribeEvent + private static void onSetup(FMLCommonSetupEvent event) { + for (ShapeTemplate template : TEMPLATES) { + for (SimpleMember member : template.simpleMembers.values()) { + if (member instanceof SimpleStructureMember simpleMember) { + simpleMember.getPreviewState(); + for (StructureMemberTest test : simpleMember.tests()) { + if (test instanceof StateStructureMemberTest stateTest) { + stateTest.blockState(); + } + } + } + } + } } public static class Builder { From ffdf5bbdfd7665c721ff4efeeb74b6f968117acd Mon Sep 17 00:00:00 2001 From: Swedz Date: Sat, 30 Nov 2024 06:14:13 -0500 Subject: [PATCH 76/89] Remove field for casing in controller --- ...ructureMultiblockControllerEditScreen.java | 35 ++----------------- ...uctureMultiblockControllerBlockEntity.java | 24 +------------ .../machines/multiblocks/ShapeMatcher.java | 12 ++++++- .../machines/multiblocks/ShapeTemplate.java | 15 ++++---- .../structure/MIStructureTemplateManager.java | 10 ++---- .../StructureSaveControllerPacket.java | 2 +- .../StructureUpdateControllerPacket.java | 8 ++--- 7 files changed, 29 insertions(+), 77 deletions(-) diff --git a/src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockControllerEditScreen.java b/src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockControllerEditScreen.java index 19158be5d..4b937c66d 100644 --- a/src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockControllerEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockControllerEditScreen.java @@ -28,7 +28,6 @@ import aztech.modern_industrialization.blocks.structure.controller.StructureControllerBounds; import aztech.modern_industrialization.blocks.structure.controller.StructureControllerMode; import aztech.modern_industrialization.blocks.structure.controller.StructureMultiblockControllerBlockEntity; -import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.structure.MIStructureTemplateManager; import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockInputFormatters; import aztech.modern_industrialization.network.structure.StructureLoadControllerPacket; @@ -63,7 +62,6 @@ public class StructureMultiblockControllerEditScreen extends Screen { private Button loadButton; private EditBox idBox; - private EditBox casingBox; private EditBox posXBox; private EditBox posYBox; @@ -88,10 +86,6 @@ private Optional getId() { }; } - private Optional getCasing() { - return Optional.ofNullable(StructureMultiblockInputFormatters.casing(casingBox.getValue())); - } - private Optional getBounds() { try { int x = Integer.parseInt(posXBox.getValue()); @@ -111,7 +105,6 @@ private void updateMode(StructureControllerMode mode) { saveButton.visible = false; loadButton.visible = false; - casingBox.visible = false; posXBox.visible = false; posYBox.visible = false; posZBox.visible = false; @@ -124,7 +117,6 @@ private void updateMode(StructureControllerMode mode) { switch (mode) { case SAVE -> { saveButton.visible = true; - casingBox.visible = true; posXBox.visible = true; posYBox.visible = true; posZBox.visible = true; @@ -148,11 +140,6 @@ private void updateId() { loadButton.active = validId; } - private void updateCasing() { - boolean validCasing = casingBox.getValue().isEmpty() || this.getCasing().isPresent(); - casingBox.setTextColor(validCasing ? VALID_TEXT_COLOR : INVALID_TEXT_COLOR); - } - private void updateBounds() { boolean validBounds = this.getBounds().filter((b) -> !b.isEmpty()).isPresent(); saveButton.active = validBounds; @@ -161,7 +148,6 @@ private void updateBounds() { private void updateAll() { this.updateMode(controller.getMode()); this.updateId(); - this.updateCasing(); this.updateBounds(); } @@ -175,7 +161,6 @@ private void sendToServer() { controller.getBlockPos(), modeButton.getValue(), idBox.getValue(), - casingBox.getValue(), this.getBounds().orElse(new StructureControllerBounds(0, 0, 0, 1, 1, 1)), showBoundsBox.getValue(), includeBlockEntitiesBox.getValue()).sendToServer(); @@ -217,7 +202,7 @@ protected void init() { .withInitialValue(controller.getMode()) .create(width / 2 - 4 - 150, 185, 50, 20, MIText.StructureMultiblockGuiMode.text(), (button, mode) -> this.updateMode(mode))); - idBox = new EditBox(font, width / 2 - 152, 20, 304, 20, MIText.StructureMultiblockStructureName.text()) { + idBox = new EditBox(font, width / 2 - 152, 60, 304, 20, MIText.StructureMultiblockStructureName.text()) { @Override public boolean charTyped(char codePoint, int modifiers) { return StructureMultiblockInputFormatters.isValidIdCharacter(codePoint) && super.charTyped(codePoint, modifiers); @@ -228,17 +213,6 @@ public boolean charTyped(char codePoint, int modifiers) { idBox.setResponder(text -> this.updateId()); this.addRenderableWidget(idBox); - casingBox = new EditBox(font, width / 2 - 152, 60, 304, 20, MIText.StructureMultiblockCasing.text()) { - @Override - public boolean charTyped(char codePoint, int modifiers) { - return ResourceLocation.isAllowedInResourceLocation(codePoint) && super.charTyped(codePoint, modifiers); - } - }; - casingBox.setMaxLength(Short.MAX_VALUE); - casingBox.setValue(controller.getInputCasing()); - casingBox.setResponder(text -> this.updateCasing()); - this.addRenderableWidget(casingBox); - StructureControllerBounds bounds = controller.getBounds(); posXBox = new EditBox(font, width / 2 - 152, 100, 35, 20, MIText.StructureMultiblockGuiRelativePositionX.text()); @@ -288,10 +262,9 @@ public boolean charTyped(char codePoint, int modifiers) { public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) { super.render(graphics, mouseX, mouseY, partialTick); - graphics.drawString(font, MIText.StructureMultiblockStructureName.text(), width / 2 - 152, 10, 0xA0A0A0); + graphics.drawCenteredString(font, title, width / 2, 20, 0xFFFFFF); - if (casingBox.visible) - graphics.drawString(font, MIText.StructureMultiblockCasing.text(), width / 2 - 152, 50, 0xA0A0A0); + graphics.drawString(font, MIText.StructureMultiblockStructureName.text(), width / 2 - 152, 50, 0xA0A0A0); if (posXBox.visible || posYBox.visible || posZBox.visible) graphics.drawString(font, MIText.StructureMultiblockGuiRelativePosition.text(), width / 2 - 152, 90, 0xA0A0A0); @@ -324,7 +297,6 @@ protected void setInitialFocus() { public void resize(Minecraft minecraft, int width, int height) { StructureControllerMode modeButtonValue = modeButton.getValue(); String idBoxValue = idBox.getValue(); - String casingBoxValue = casingBox.getValue(); String posXBoxValue = posXBox.getValue(); String posYBoxValue = posYBox.getValue(); String posZBoxValue = posZBox.getValue(); @@ -338,7 +310,6 @@ public void resize(Minecraft minecraft, int width, int height) { modeButton.setValue(modeButtonValue); idBox.setValue(idBoxValue); - casingBox.setValue(casingBoxValue); posXBox.setValue(posXBoxValue); posYBox.setValue(posYBoxValue); posZBox.setValue(posZBoxValue); diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlockEntity.java index 8531fb2a1..5e9d506bc 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlockEntity.java @@ -27,7 +27,6 @@ import aztech.modern_industrialization.MIRegistries; import aztech.modern_industrialization.blocks.FastBlockEntity; import aztech.modern_industrialization.blocks.structure.StructureMemberOverride; -import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockInputFormatters; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; import java.util.Locale; @@ -48,10 +47,8 @@ public class StructureMultiblockControllerBlockEntity extends FastBlockEntity im private StructureControllerMode mode; private String inputId; - private String inputCasing; private ResourceLocation id; - private MachineCasing casing; private StructureControllerBounds bounds = new StructureControllerBounds(0, 0, 0, 1, 1, 1); private boolean showBounds; private boolean includeBlockEntities; @@ -81,26 +78,11 @@ public void setInputId(String inputId) { id = StructureMultiblockInputFormatters.id(inputId); } - @Nullable - public String getInputCasing() { - return inputCasing; - } - - public void setInputCasing(String inputCasing) { - this.inputCasing = inputCasing; - casing = StructureMultiblockInputFormatters.casing(inputCasing); - } - @Nullable public ResourceLocation getId() { return id; } - @Nullable - public MachineCasing getCasing() { - return casing; - } - public StructureControllerBounds getBounds() { return bounds; } @@ -137,7 +119,7 @@ public StructureMember getMemberOverride() { @Override public boolean isConfigurationValid() { - return casing != null && !bounds.isEmpty(); + return !bounds.isEmpty(); } @Override @@ -159,9 +141,6 @@ protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) if (inputId != null) { tag.putString("structure_id", inputId); } - if (inputCasing != null) { - tag.putString("casing", inputCasing); - } CompoundTag boundsTag = new CompoundTag(); boundsTag.put("origin", NbtUtils.writeBlockPos(new BlockPos(bounds.x(), bounds.y(), bounds.z()))); boundsTag.put("size", NbtUtils.writeBlockPos(new BlockPos(bounds.sizeX(), bounds.sizeY(), bounds.sizeZ()))); @@ -175,7 +154,6 @@ protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) super.loadAdditional(tag, registries); mode = StructureControllerMode.valueOf(tag.getString("mode").toUpperCase(Locale.ROOT)); this.setInputId(tag.getString("structure_id")); - this.setInputCasing(tag.getString("casing")); if (tag.contains("bounds", Tag.TAG_COMPOUND)) { CompoundTag boundsTag = tag.getCompound("bounds"); BlockPos origin = NbtUtils.readBlockPos(boundsTag, "origin").orElseThrow(); diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java index 39a3b61b7..ce4155548 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java @@ -25,6 +25,8 @@ import aztech.modern_industrialization.blocks.FastBlockEntity; import aztech.modern_industrialization.machines.components.ShapeValidComponent; +import aztech.modern_industrialization.machines.models.MachineCasing; +import aztech.modern_industrialization.machines.multiblocks.structure.member.HatchStructureMember; import aztech.modern_industrialization.machines.multiblocks.structure.member.LiteralStructureMember; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; import aztech.modern_industrialization.machines.multiblocks.world.ChunkEventListener; @@ -232,7 +234,15 @@ public void rematch(Level world) { matchedHatches.clear(); } else { for (HatchBlockEntity hatch : matchedHatches) { - hatch.link(template.hatchCasing); + MachineCasing hatchCasing = template.hatchCasing; + SimpleMember member = simpleMembers.get(hatch.getBlockPos()); + if (member instanceof HatchStructureMember hatchMember) { + hatchCasing = hatchMember.casing(); + } + if (hatchCasing == null) { + throw new IllegalStateException("hatchCasing for a multiblock shape cannot be null without using hatch structure members"); + } + hatch.link(hatchCasing); } } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java index 2ad9df281..cb7493c09 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeTemplate.java @@ -49,7 +49,7 @@ public class ShapeTemplate { public static final Codec STRUCTURE_CODEC = InternalStructureTemplate.CODEC .xmap(structure -> { - Builder template = new Builder(structure.casing()); + Builder template = new Builder(null); for (InternalStructureBlockPos block : structure.blocks()) { BlockPos pos = block.pos(); int memberIndex = block.memberIndex(); @@ -73,7 +73,7 @@ public class ShapeTemplate { "Cannot convert ShapeTemplate to a structure ShapeTemplate if all members aren't StructureMembers"); } } - return new InternalStructureTemplate(template.hatchCasing, blocks, members); + return new InternalStructureTemplate(blocks, members); }); private record InternalStructureBlockPos(int memberIndex, BlockPos pos) { @@ -84,10 +84,9 @@ private record InternalStructureBlockPos(int memberIndex, BlockPos pos) { .apply(instance, InternalStructureBlockPos::new)); } - private record InternalStructureTemplate(MachineCasing casing, List blocks, List members) { + private record InternalStructureTemplate(List blocks, List members) { private static final Codec CODEC = RecordCodecBuilder.create(instance -> instance .group( - MachineCasing.CODEC.fieldOf("hatch_casing").forGetter(InternalStructureTemplate::casing), InternalStructureBlockPos.CODEC.listOf().fieldOf("blocks").forGetter(InternalStructureTemplate::blocks), StructureMember.CODEC.listOf().fieldOf("members").forGetter(InternalStructureTemplate::members)) .apply(instance, InternalStructureTemplate::new)); @@ -97,9 +96,13 @@ private record InternalStructureTemplate(MachineCasing casing, List simpleMembers = new HashMap<>(); public final Map hatchFlags = new HashMap<>(); + @Nullable public final MachineCasing hatchCasing; - private ShapeTemplate(MachineCasing hatchCasing) { + /** + * A null hatchCasing for a shape is only permitted if the shape is a structure as the hatch casing is determined by the hatch members. + */ + private ShapeTemplate(@Nullable MachineCasing hatchCasing) { this.hatchCasing = hatchCasing; TEMPLATES.add(this); } @@ -287,7 +290,7 @@ public static class Structure { public Structure(ResourceLocation id) { ShapeTemplate referenceTemplate = MIStructureTemplateManager.get(id); - template = new ShapeTemplate(referenceTemplate.hatchCasing); + template = new ShapeTemplate(null); template.simpleMembers.putAll(referenceTemplate.simpleMembers); template.hatchFlags.putAll(referenceTemplate.hatchFlags); } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java index fce163444..005459c78 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java @@ -29,7 +29,6 @@ import aztech.modern_industrialization.MI; import aztech.modern_industrialization.blocks.structure.StructureMemberOverride; import aztech.modern_industrialization.blocks.structure.controller.StructureControllerBounds; -import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.HatchFlags; import aztech.modern_industrialization.machines.multiblocks.ShapeTemplate; import aztech.modern_industrialization.machines.multiblocks.structure.member.HatchStructureMember; @@ -103,8 +102,7 @@ public static CompoundTag maybeTag(@Nullable BlockEntity blockEntity) { public static StructureResult fromWorld(ResourceLocation id, Level level, BlockPos controllerPos, Direction controllerDirection, - MachineCasing hatchCasing, StructureControllerBounds bounds, - boolean includeBlockEntities) { + StructureControllerBounds bounds, boolean includeBlockEntities) { Objects.requireNonNull(id); Objects.requireNonNull(level); Objects.requireNonNull(controllerPos); @@ -118,11 +116,7 @@ public static StructureResult fromWorld(ResourceLocation id, Level level, List controllerBlocks = new ArrayList<>(); List hatchBlocks = new ArrayList<>(); - if (hatchCasing == null) { - misconfiguredBlocks.add(controllerPos); - } - - ShapeTemplate.Builder template = new ShapeTemplate.Builder(hatchCasing); + ShapeTemplate.Builder template = new ShapeTemplate.Builder(null); BoundingBox boundsBox = bounds.boundingBox(); BlockPos minPos = controllerPos.offset(boundsBox.minX(), boundsBox.minY(), boundsBox.minZ()); diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java index 8a2283aec..a1c4aa8af 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java @@ -61,7 +61,7 @@ public void handle(Context ctx) { ResourceLocation id = controller.getId(); var result = MIStructureTemplateManager.fromWorld(id, level, pos, state.getValue(StructureMultiblockControllerBlock.FACING), - controller.getCasing(), controller.getBounds(), controller.includeBlockEntities()); + controller.getBounds(), controller.includeBlockEntities()); if (result instanceof StructureResult.Success success) { if (MIStructureTemplateManager.save(id, success.template())) { MIStructureTemplateManager.register(id, success.template()); diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java index f27d7bc23..485cc0017 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateControllerPacket.java @@ -35,21 +35,18 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; -import net.neoforged.neoforge.network.codec.NeoForgeStreamCodecs; -public record StructureUpdateControllerPacket(BlockPos pos, StructureControllerMode mode, String inputId, String inputCasing, +public record StructureUpdateControllerPacket(BlockPos pos, StructureControllerMode mode, String inputId, StructureControllerBounds bounds, boolean showBounds, boolean includeBlockEntities) implements BasePacket { - public static final StreamCodec STREAM_CODEC = NeoForgeStreamCodecs.composite( + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( BlockPos.STREAM_CODEC, StructureUpdateControllerPacket::pos, ByteBufCodecs.idMapper((i) -> StructureControllerMode.values()[i], Enum::ordinal), StructureUpdateControllerPacket::mode, ByteBufCodecs.STRING_UTF8, StructureUpdateControllerPacket::inputId, - ByteBufCodecs.STRING_UTF8, - StructureUpdateControllerPacket::inputCasing, ByteBufCodecs.fromCodec(StructureControllerBounds.CODEC), StructureUpdateControllerPacket::bounds, ByteBufCodecs.BOOL, @@ -73,7 +70,6 @@ public void handle(Context ctx) { if (blockEntity instanceof StructureMultiblockControllerBlockEntity controller) { controller.setMode(mode); controller.setInputId(inputId); - controller.setInputCasing(inputCasing); controller.setBounds(bounds); controller.setShowBounds(showBounds); controller.setIncludeBlockEntities(includeBlockEntities); From 41f556aba7ecbd437a155e7ebc7ede79e046a074 Mon Sep 17 00:00:00 2001 From: Swedz Date: Sat, 30 Nov 2024 23:53:18 -0500 Subject: [PATCH 77/89] Only render controller bounds if in save mode --- .../StructureMultiblockControllerBER.java | 45 ++++++++++--------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java b/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java index 9395999d9..0d93587f4 100644 --- a/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java +++ b/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java @@ -24,6 +24,7 @@ package aztech.modern_industrialization.blocks.structure; import aztech.modern_industrialization.blocks.structure.controller.StructureControllerBounds; +import aztech.modern_industrialization.blocks.structure.controller.StructureControllerMode; import aztech.modern_industrialization.blocks.structure.controller.StructureMultiblockControllerBlockEntity; import aztech.modern_industrialization.util.RenderHelper; import com.mojang.blaze3d.vertex.PoseStack; @@ -51,31 +52,33 @@ public static void forgetMisconfigured(List positions) { @Override public void render(StructureMultiblockControllerBlockEntity be, float tickDelta, PoseStack matrices, MultiBufferSource vcp, int light, int overlay) { - BlockPos pos = be.getBlockPos(); - StructureControllerBounds bounds = be.getBounds(); + if (be.getMode() == StructureControllerMode.SAVE) { + BlockPos pos = be.getBlockPos(); + StructureControllerBounds bounds = be.getBounds(); - AABB box = bounds.aabb(); - if (box != null) { - if ((System.currentTimeMillis() / 500L) % 2 == 0) { - AABB worldBox = box.move(pos); - for (BlockPos misconfiguredPos : MISCONFIGURED_BLOCKS) { - if (worldBox.contains(misconfiguredPos.getX(), misconfiguredPos.getY(), misconfiguredPos.getZ())) { - matrices.pushPose(); - matrices.translate(misconfiguredPos.getX() - pos.getX(), misconfiguredPos.getY() - pos.getY(), - misconfiguredPos.getZ() - pos.getZ()); - matrices.translate(-0.005f, -0.005f, -0.005f); - matrices.scale(1.01f, 1.01f, 1.01f); - RenderHelper.drawOverlay(matrices, vcp, 1.0f, 111f / 256f, 111f / 256f, RenderHelper.FULL_LIGHT, overlay, false); - matrices.popPose(); + AABB box = bounds.aabb(); + if (box != null) { + if ((System.currentTimeMillis() / 500L) % 2 == 0) { + AABB worldBox = box.move(pos); + for (BlockPos misconfiguredPos : MISCONFIGURED_BLOCKS) { + if (worldBox.contains(misconfiguredPos.getX(), misconfiguredPos.getY(), misconfiguredPos.getZ())) { + matrices.pushPose(); + matrices.translate(misconfiguredPos.getX() - pos.getX(), misconfiguredPos.getY() - pos.getY(), + misconfiguredPos.getZ() - pos.getZ()); + matrices.translate(-0.005f, -0.005f, -0.005f); + matrices.scale(1.01f, 1.01f, 1.01f); + RenderHelper.drawOverlay(matrices, vcp, 1.0f, 111f / 256f, 111f / 256f, RenderHelper.FULL_LIGHT, overlay, false); + matrices.popPose(); + } } } - } - if (be.shouldShowBounds()) { - matrices.pushPose(); - VertexConsumer buffer = vcp.getBuffer(RenderType.lines()); - LevelRenderer.renderLineBox(matrices, buffer, box, 1, 1, 1, 1); - matrices.popPose(); + if (be.shouldShowBounds()) { + matrices.pushPose(); + VertexConsumer buffer = vcp.getBuffer(RenderType.lines()); + LevelRenderer.renderLineBox(matrices, buffer, box, 1, 1, 1, 1); + matrices.popPose(); + } } } } From df97b56ee680c280c9eaa70d01155214ee093670 Mon Sep 17 00:00:00 2001 From: Swedz Date: Sun, 1 Dec 2024 00:50:00 -0500 Subject: [PATCH 78/89] Config option to export all mod structure files --- .../modern_industrialization/lang/en_us.json | 1 + .../aztech/modern_industrialization/MI.java | 4 ++ .../modern_industrialization/MIConfig.java | 3 + .../structure/MIStructureTemplateManager.java | 62 +++++++++++++++++-- 4 files changed, 65 insertions(+), 5 deletions(-) diff --git a/src/generated/resources/assets/modern_industrialization/lang/en_us.json b/src/generated/resources/assets/modern_industrialization/lang/en_us.json index 0ad8a094d..e9328ebd7 100644 --- a/src/generated/resources/assets/modern_industrialization/lang/en_us.json +++ b/src/generated/resources/assets/modern_industrialization/lang/en_us.json @@ -1493,6 +1493,7 @@ "text.autoconfig.modern_industrialization.option.enableHatchPlacementOverlay": "Show valid positions in multiblocks when holding a hatch", "text.autoconfig.modern_industrialization.option.enableInterMachineConnectedTextures": "Enable inter-machine connected textures. (Requires a suitable resource pack)", "text.autoconfig.modern_industrialization.option.enableNoEmiMessage": "Enable login message when EMI, JEI and REI are missing", + "text.autoconfig.modern_industrialization.option.exportStructureFiles": "Export all structure files to modern_industrialization/structures", "text.autoconfig.modern_industrialization.option.loadRuntimeGeneratedResources": "Additionally load resources in modern_industrialization/generated_resources", "text.autoconfig.modern_industrialization.option.maxDistillationTowerHeight": "Maximum height of the Distillation Tower multiblock (Restart needed)", "text.autoconfig.modern_industrialization.option.newVersionMessage": "Display when a new version is available", diff --git a/src/main/java/aztech/modern_industrialization/MI.java b/src/main/java/aztech/modern_industrialization/MI.java index f82c62768..82563b82d 100644 --- a/src/main/java/aztech/modern_industrialization/MI.java +++ b/src/main/java/aztech/modern_industrialization/MI.java @@ -186,6 +186,10 @@ public MI(FMLModContainer container, IEventBus modBus, Dist dist) { MIItem.ITEM_DEFINITIONS.values().forEach(ItemDefinition::onRegister); FluidNuclearComponent.init(); + + if (MIConfig.getConfig().exportStructureFiles) { + MIStructureTemplateManager.exportAll(); + } }); modBus.addListener(GatherDataEvent.class, event -> { diff --git a/src/main/java/aztech/modern_industrialization/MIConfig.java b/src/main/java/aztech/modern_industrialization/MIConfig.java index 917788ccb..8ec4f18d6 100644 --- a/src/main/java/aztech/modern_industrialization/MIConfig.java +++ b/src/main/java/aztech/modern_industrialization/MIConfig.java @@ -77,6 +77,9 @@ public class MIConfig implements ConfigData { @EnglishTranslation(value = "Additionally load resources in modern_industrialization/generated_resources") public boolean loadRuntimeGeneratedResources = false; @ConfigEntry.Gui.RequiresRestart + @EnglishTranslation(value = "Export all structure files to modern_industrialization/structures") + public boolean exportStructureFiles = false; + @ConfigEntry.Gui.RequiresRestart @EnglishTranslation(value = "Removes trades from the Industrialist villager (Restart needed)") public boolean removeIndustrialistTrades = false; @ConfigEntry.Gui.RequiresRestart diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java index 005459c78..cfe363530 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java @@ -185,23 +185,75 @@ private static Path path(ResourceLocation id) throws IOException { return FileUtil.createPathToResource(structuresFolder, id.getPath(), ".json"); } - public static boolean save(ResourceLocation id, ShapeTemplate template) { - Objects.requireNonNull(id); + private static JsonElement serialize(ShapeTemplate template) { Objects.requireNonNull(template); + return ShapeTemplate.STRUCTURE_CODEC.encodeStart(JsonOps.INSTANCE, template).getOrThrow(); + } + + private static boolean save(Path path, JsonElement json) { + Objects.requireNonNull(path); + Objects.requireNonNull(json); try { - var json = ShapeTemplate.STRUCTURE_CODEC.encodeStart(JsonOps.INSTANCE, template).getOrThrow(); - try (OutputStream output = Files.newOutputStream(path(id))) { + try (OutputStream output = Files.newOutputStream(path)) { output.write(new GsonBuilder().setPrettyPrinting().create().toJson(json).getBytes(StandardCharsets.UTF_8)); return true; } catch (Exception ex) { - MI.LOGGER.error("Failed to save structure \"{}\"", id, ex); + MI.LOGGER.error("Failed to save structure at \"{}\"", path, ex); } } catch (Exception ex) { + MI.LOGGER.error("Failed to save structure at \"{}\"", path, ex); + } + return false; + } + + private static boolean save(Path path, ShapeTemplate template) { + Objects.requireNonNull(path); + Objects.requireNonNull(template); + try { + JsonElement json = serialize(template); + return save(path, json); + } catch (Exception ex) { + MI.LOGGER.error("Failed to save structure at \"{}\"", path, ex); + } + return false; + } + + public static boolean save(ResourceLocation id, ShapeTemplate template) { + Objects.requireNonNull(id); + try { + return save(path(id), template); + } catch (IOException ex) { MI.LOGGER.error("Failed to save structure \"{}\"", id, ex); } return false; } + public static void exportAll() { + try { + for (IModFileInfo modFile : ModList.get().getModFiles()) { + Path modStructuresPath = modFile.getFile().findResource("mi_structures"); + iterateStructureFiles(modStructuresPath, (id, pathIn) -> { + try { + JsonElement json = load(pathIn); + Path pathOut = path(id); + if (Files.exists(pathOut)) { + JsonElement fileJson = load(pathOut); + if (!json.equals(fileJson)) { + save(pathOut, json); + } + } else { + save(pathOut, json); + } + } catch (IOException ex) { + MI.LOGGER.error("Failed to export structure \"{}\"", id, ex); + } + }); + } + } catch (IOException ex) { + MI.LOGGER.error("Failed to export structures", ex); + } + } + @Nullable private static JsonElement load(Path path) { Objects.requireNonNull(path); From 9742acfe57b1f843e0c207fcf586facaaf6d2ba1 Mon Sep 17 00:00:00 2001 From: Swedz Date: Sun, 1 Dec 2024 02:14:07 -0500 Subject: [PATCH 79/89] Load cable tiers before structures so that structures can use the cable tier casings --- src/main/java/aztech/modern_industrialization/MI.java | 3 ++- .../aztech/modern_industrialization/api/energy/CableTier.java | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/aztech/modern_industrialization/MI.java b/src/main/java/aztech/modern_industrialization/MI.java index 82563b82d..18961dfaa 100644 --- a/src/main/java/aztech/modern_industrialization/MI.java +++ b/src/main/java/aztech/modern_industrialization/MI.java @@ -24,6 +24,7 @@ package aztech.modern_industrialization; import aztech.modern_industrialization.api.datamaps.MIDataMaps; +import aztech.modern_industrialization.api.energy.CableTier; import aztech.modern_industrialization.blocks.WrenchableBlockEntity; import aztech.modern_industrialization.blocks.storage.barrel.BarrelBlock; import aztech.modern_industrialization.compat.ae2.MIAEAddon; @@ -101,8 +102,8 @@ public static ResourceLocation id(String path) { public MI(FMLModContainer container, IEventBus modBus, Dist dist) { KubeJSProxy.checkThatKubeJsIsLoaded(); + CableTier.init(); MIStructureTemplateManager.init(); - MIAdvancementTriggers.init(modBus); MIComponents.init(modBus); MIFluids.init(modBus); diff --git a/src/main/java/aztech/modern_industrialization/api/energy/CableTier.java b/src/main/java/aztech/modern_industrialization/api/energy/CableTier.java index 6a1c12f5a..810b9a296 100644 --- a/src/main/java/aztech/modern_industrialization/api/energy/CableTier.java +++ b/src/main/java/aztech/modern_industrialization/api/energy/CableTier.java @@ -187,4 +187,7 @@ public static List allTiers() { KubeJSProxy.instance.fireCableTiersEvent(); } + + public static void init() { + } } From 9f04d831e6479e3ccf8bf86df79b194c0d5aa39b Mon Sep 17 00:00:00 2001 From: Swedz Date: Sun, 1 Dec 2024 02:15:43 -0500 Subject: [PATCH 80/89] Make (most) MI multiblocks use structures! --- .../DistillationTowerBlockEntity.java | 18 +- .../ElectricBlastFurnaceBlockEntity.java | 13 +- .../machines/init/MultiblockMachines.java | 340 +-- .../advanced_large_steam_boiler.json | 386 ++++ .../modern_industrialization/coke_oven.json | 220 ++ .../distillation_tower_1.json | 180 ++ .../distillation_tower_10.json | 828 +++++++ .../distillation_tower_11.json | 900 ++++++++ .../distillation_tower_12.json | 972 ++++++++ .../distillation_tower_13.json | 1044 +++++++++ .../distillation_tower_14.json | 1116 ++++++++++ .../distillation_tower_15.json | 1188 ++++++++++ .../distillation_tower_2.json | 252 +++ .../distillation_tower_3.json | 324 +++ .../distillation_tower_4.json | 396 ++++ .../distillation_tower_5.json | 468 ++++ .../distillation_tower_6.json | 540 +++++ .../distillation_tower_7.json | 612 +++++ .../distillation_tower_8.json | 684 ++++++ .../distillation_tower_9.json | 756 +++++++ .../electric_blast_furnace.json | 290 +++ .../electric_quarry.json | 252 +++ .../fusion_reactor.json | 1978 +++++++++++++++++ .../heat_exchanger.json | 456 ++++ ..._pressure_advanced_large_steam_boiler.json | 386 ++++ .../high_pressure_large_steam_boiler.json | 314 +++ .../implosion_compressor.json | 298 +++ .../large_diesel_generator.json | 330 +++ .../large_steam_boiler.json | 314 +++ .../large_steam_turbine.json | 330 +++ .../oil_drilling_rig.json | 540 +++++ .../plasma_turbine.json | 330 +++ .../modern_industrialization/pressurizer.json | 196 ++ .../steam_blast_furnace.json | 284 +++ .../steam_quarry.json | 252 +++ .../vacuum_freezer.json | 292 +++ 36 files changed, 17729 insertions(+), 350 deletions(-) create mode 100644 src/main/resources/mi_structures/modern_industrialization/advanced_large_steam_boiler.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/coke_oven.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/distillation_tower_1.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/distillation_tower_10.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/distillation_tower_11.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/distillation_tower_12.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/distillation_tower_13.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/distillation_tower_14.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/distillation_tower_15.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/distillation_tower_2.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/distillation_tower_3.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/distillation_tower_4.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/distillation_tower_5.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/distillation_tower_6.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/distillation_tower_7.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/distillation_tower_8.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/distillation_tower_9.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/electric_blast_furnace.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/electric_quarry.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/fusion_reactor.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/heat_exchanger.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/high_pressure_advanced_large_steam_boiler.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/high_pressure_large_steam_boiler.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/implosion_compressor.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/large_diesel_generator.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/large_steam_boiler.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/large_steam_turbine.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/oil_drilling_rig.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/plasma_turbine.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/pressurizer.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/steam_blast_furnace.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/steam_quarry.json create mode 100644 src/main/resources/mi_structures/modern_industrialization/vacuum_freezer.json diff --git a/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/DistillationTowerBlockEntity.java b/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/DistillationTowerBlockEntity.java index a50b5094e..a2fbc504c 100644 --- a/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/DistillationTowerBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/DistillationTowerBlockEntity.java @@ -24,7 +24,6 @@ package aztech.modern_industrialization.machines.blockentities.multiblocks; import aztech.modern_industrialization.MI; -import aztech.modern_industrialization.MIBlock; import aztech.modern_industrialization.MIConfig; import aztech.modern_industrialization.MIText; import aztech.modern_industrialization.api.machine.holder.EnergyListComponentHolder; @@ -35,7 +34,6 @@ import aztech.modern_industrialization.machines.guicomponents.SlotPanel; import aztech.modern_industrialization.machines.init.MIMachineRecipeTypes; import aztech.modern_industrialization.machines.init.MachineTier; -import aztech.modern_industrialization.machines.models.MachineCasings; import aztech.modern_industrialization.machines.multiblocks.*; import aztech.modern_industrialization.machines.recipe.MachineRecipeType; import java.util.stream.IntStream; @@ -106,21 +104,9 @@ public static void registerReiShapes() { static { shapeTemplates = new ShapeTemplate[MAX_HEIGHT]; - - SimpleMember casing = SimpleMember.forBlock(MIBlock.BLOCK_DEFINITIONS.get(MI.id("clean_stainless_steel_machine_casing"))); - SimpleMember pipe = SimpleMember.forBlock(MIBlock.BLOCK_DEFINITIONS.get(MI.id("stainless_steel_machine_casing_pipe"))); - HatchFlags bottom = new HatchFlags.Builder().with(HatchType.ENERGY_INPUT, HatchType.FLUID_INPUT).build(); - HatchFlags layer = new HatchFlags.Builder().with(HatchType.FLUID_OUTPUT).build(); for (int i = 0; i < MAX_HEIGHT; ++i) { - ShapeTemplate.Builder builder = new ShapeTemplate.Builder(MachineCasings.CLEAN_STAINLESS_STEEL); - for (int y = 0; y <= i + 1; ++y) { - builder.add3by3(y, casing, y != 0, y == 0 ? bottom : layer); - if (y != 0) { - builder.add(0, y, 1, pipe, null); - - } - } - shapeTemplates[i] = builder.build(); + ShapeTemplate towerShape = new ShapeTemplate.Structure(MI.id("distillation_tower_%d".formatted(i + 1))).build(); + shapeTemplates[i] = towerShape; } } } diff --git a/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/ElectricBlastFurnaceBlockEntity.java b/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/ElectricBlastFurnaceBlockEntity.java index d2f985501..ad643e256 100644 --- a/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/ElectricBlastFurnaceBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/machines/blockentities/multiblocks/ElectricBlastFurnaceBlockEntity.java @@ -23,10 +23,7 @@ */ package aztech.modern_industrialization.machines.blockentities.multiblocks; -import static aztech.modern_industrialization.machines.multiblocks.HatchType.*; - import aztech.modern_industrialization.MI; -import aztech.modern_industrialization.MIBlock; import aztech.modern_industrialization.api.machine.holder.EnergyListComponentHolder; import aztech.modern_industrialization.compat.kubejs.KubeJSProxy; import aztech.modern_industrialization.compat.rei.machines.ReiMachineRecipes; @@ -36,7 +33,6 @@ import aztech.modern_industrialization.machines.guicomponents.SlotPanel; import aztech.modern_industrialization.machines.init.MIMachineRecipeTypes; import aztech.modern_industrialization.machines.init.MachineTier; -import aztech.modern_industrialization.machines.models.MachineCasings; import aztech.modern_industrialization.machines.multiblocks.*; import aztech.modern_industrialization.machines.recipe.MachineRecipe; import aztech.modern_industrialization.machines.recipe.MachineRecipeType; @@ -94,15 +90,8 @@ public Component getDisplayName() { for (int i = 0; i < tiers.size(); ++i) { var tier = tiers.get(i); - SimpleMember invarCasings = SimpleMember.forBlock(MIBlock.BLOCK_DEFINITIONS.get(MI.id("heatproof_machine_casing"))); SimpleMember coilsBlocks = SimpleMember.forBlockId(tier.coilBlockId()); - HatchFlags ebfHatches = new HatchFlags.Builder().with(ITEM_INPUT, ITEM_OUTPUT, FLUID_INPUT, FLUID_OUTPUT, ENERGY_INPUT).build(); - ShapeTemplate ebfShape = new ShapeTemplate.Builder(MachineCasings.HEATPROOF) - .add3by3(0, invarCasings, false, ebfHatches) - .add3by3(1, coilsBlocks, true, null) - .add3by3(2, coilsBlocks, true, null) - .add3by3(3, invarCasings, false, ebfHatches) - .build(); + ShapeTemplate ebfShape = new ShapeTemplate.Structure(MI.id("electric_blast_furnace")).replace("coil", coilsBlocks).build(); shapeTemplates[i] = ebfShape; } } diff --git a/src/main/java/aztech/modern_industrialization/machines/init/MultiblockMachines.java b/src/main/java/aztech/modern_industrialization/machines/init/MultiblockMachines.java index 8748fa485..9ded1aa1c 100644 --- a/src/main/java/aztech/modern_industrialization/machines/init/MultiblockMachines.java +++ b/src/main/java/aztech/modern_industrialization/machines/init/MultiblockMachines.java @@ -24,10 +24,8 @@ package aztech.modern_industrialization.machines.init; import static aztech.modern_industrialization.machines.models.MachineCasings.CLEAN_STAINLESS_STEEL; -import static aztech.modern_industrialization.machines.multiblocks.HatchType.*; import aztech.modern_industrialization.MI; -import aztech.modern_industrialization.MIBlock; import aztech.modern_industrialization.MIFluids; import aztech.modern_industrialization.api.energy.CableTier; import aztech.modern_industrialization.compat.kubejs.KubeJSProxy; @@ -40,11 +38,8 @@ import aztech.modern_industrialization.machines.components.OverclockComponent; import aztech.modern_industrialization.machines.guicomponents.CraftingMultiblockGui; import aztech.modern_industrialization.machines.guicomponents.ProgressBar; -import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.models.MachineCasings; -import aztech.modern_industrialization.machines.multiblocks.HatchFlags; import aztech.modern_industrialization.machines.multiblocks.ShapeTemplate; -import aztech.modern_industrialization.machines.multiblocks.SimpleMember; import aztech.modern_industrialization.machines.recipe.MachineRecipe; import aztech.modern_industrialization.machines.recipe.MachineRecipeType; import aztech.modern_industrialization.util.Rectangle; @@ -57,7 +52,6 @@ import java.util.stream.IntStream; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.entity.BlockEntityType; public class MultiblockMachines { @@ -86,46 +80,15 @@ public class MultiblockMachines { public static Supplier> FUSION_REACTOR; public static Supplier> PLASMA_TURBINE; - private static SimpleMember invarCasings; - - private static SimpleMember bronzePlatedBricks; - private static SimpleMember bronzePipe; - - private static SimpleMember frostproofMachineCasing; - - private static SimpleMember stainlessSteelClean; - private static SimpleMember stainlessSteelPipe; - - private static SimpleMember titaniumCasing; - private static SimpleMember titaniumPipe; - - - private static SimpleMember blastProofCasing; - - private static SimpleMember highlyAdvancedHull; - private static SimpleMember fusionChamber; - - private static SimpleMember plasmaHandlingIridium; - private static SimpleMember iridiumPipe; - - private static final HatchFlags fluidInputs = new HatchFlags.Builder().with(FLUID_INPUT).build(); - private static final HatchFlags energyOutput = new HatchFlags.Builder().with(ENERGY_OUTPUT).build(); - private static final HatchFlags energyInput = new HatchFlags.Builder().with(ENERGY_INPUT).build(); - - private static void cokeOven() { - SimpleMember bricks = SimpleMember.forBlock(() -> Blocks.BRICKS); - HatchFlags cokeOvenHatches = new HatchFlags.Builder().with(ITEM_INPUT).with(ITEM_OUTPUT).with(FLUID_INPUT).with(FLUID_OUTPUT).build(); - ShapeTemplate cokeOvenShape = new ShapeTemplate.Builder(MachineCasings.BRICKS).add3by3Levels(-1, 1, bricks, cokeOvenHatches).build(); + ShapeTemplate cokeOvenShape = new ShapeTemplate.Structure(MI.id("coke_oven")).build(); COKE_OVEN = MachineRegistrationHelper.registerMachine("Coke Oven", "coke_oven", bet -> new SteamCraftingMultiblockBlockEntity(bet, "coke_oven", cokeOvenShape, MIMachineRecipeTypes.COKE_OVEN, OverclockComponent.getDefaultCatalysts())); ReiMachineRecipes.registerMultiblockShape("coke_oven", cokeOvenShape); } private static void steamBlastFurnace() { - SimpleMember fireclayBricks = SimpleMember.forBlock(MIBlock.BLOCK_FIRE_CLAY_BRICKS); - HatchFlags sbfHatches = new HatchFlags.Builder().with(ITEM_INPUT, ITEM_OUTPUT, FLUID_INPUT, FLUID_OUTPUT).build(); - ShapeTemplate sbfShape = new ShapeTemplate.Builder(MachineCasings.FIREBRICKS).add3by3Levels(-1, 2, fireclayBricks, sbfHatches).build(); + ShapeTemplate sbfShape = new ShapeTemplate.Structure(MI.id("steam_blast_furnace")).build(); STEAM_BLAST_FURNACE = MachineRegistrationHelper.registerMachine("Steam Blast Furnace", "steam_blast_furnace", bet -> new SteamCraftingMultiblockBlockEntity(bet, "steam_blast_furnace", sbfShape, MIMachineRecipeTypes.BLAST_FURNACE, OverclockComponent.getDefaultCatalysts())); ReiMachineRecipes.registerMultiblockShape("steam_blast_furnace", sbfShape); @@ -138,42 +101,20 @@ private static void electricBlastFurnace() { } private static void steamBoilers() { - - HatchFlags slbHatchFlags = new HatchFlags.Builder().with(ITEM_INPUT, FLUID_INPUT, FLUID_OUTPUT).build(); - ShapeTemplate largeSteamBoilerShape = new ShapeTemplate.Builder(MachineCasings.HEATPROOF).add3by3(-1, invarCasings, false, slbHatchFlags) - .add3by3(0, bronzePlatedBricks, true, null).add3by3(1, bronzePlatedBricks, true, null).add3by3(2, bronzePlatedBricks, false, null) - .add(0, 0, 1, bronzePipe, null).add(0, 1, 1, bronzePipe, null).build(); - - + ShapeTemplate largeSteamBoilerShape = new ShapeTemplate.Structure(MI.id("large_steam_boiler")).build(); LARGE_STEAM_BOILER = MachineRegistrationHelper.registerMachine("Large Steam Boiler", "large_steam_boiler", bet -> new SteamBoilerMultiblockBlockEntity(bet, largeSteamBoilerShape, "large_steam_boiler", 256, false)); ReiMachineRecipes.registerMultiblockShape("large_steam_boiler", largeSteamBoilerShape); - ShapeTemplate advancedLargeSteamBoilerShape = new ShapeTemplate.Builder(MachineCasings.HEATPROOF) - .add3by3(-2, invarCasings, false, slbHatchFlags) - .add3by3(-1, bronzePlatedBricks, true, null) - .add3by3(0, bronzePlatedBricks, true, null) - .add3by3(1, bronzePlatedBricks, true, null) - .add3by3(2, bronzePlatedBricks, false, null) - .add(0, -1, 1, bronzePipe, null) - .add(0, 0, 1, bronzePipe, null) - .add(0, 1, 1, bronzePipe, null).build(); - + ShapeTemplate advancedLargeSteamBoilerShape = new ShapeTemplate.Structure(MI.id("advanced_large_steam_boiler")).build(); ADVANCED_LARGE_STEAM_BOILER = MachineRegistrationHelper.registerMachine("Advanced Large Steam Boiler", "advanced_large_steam_boiler", bet -> new SteamBoilerMultiblockBlockEntity(bet, advancedLargeSteamBoilerShape, "advanced_large_steam_boiler", 1024, false)); ReiMachineRecipes.registerMultiblockShape("advanced_large_steam_boiler", advancedLargeSteamBoilerShape); - ShapeTemplate highPressureLargeSteamBoilerShape = new ShapeTemplate.Builder(MachineCasings.HEATPROOF) - .add3by3(-1, invarCasings, false, slbHatchFlags) - .add3by3(0, stainlessSteelClean, true, null) - .add3by3(1, stainlessSteelClean, true, null) - .add3by3(2, stainlessSteelClean, false, null) - .add(0, 0, 1, stainlessSteelPipe, null) - .add(0, 1, 1, stainlessSteelPipe, null).build(); - + ShapeTemplate highPressureLargeSteamBoilerShape = new ShapeTemplate.Structure(MI.id("high_pressure_large_steam_boiler")).build(); HIGH_PRESSURE_LARGE_STEAM_BOILER = MachineRegistrationHelper.registerMachine( "High Pressure Large Steam Boiler", "high_pressure_large_steam_boiler", @@ -181,16 +122,7 @@ private static void steamBoilers() { 2048, true)); ReiMachineRecipes.registerMultiblockShape("high_pressure_large_steam_boiler", highPressureLargeSteamBoilerShape); - ShapeTemplate highPressureAdvancedLargeSteamBoilerShape = new ShapeTemplate.Builder(MachineCasings.HEATPROOF) - .add3by3(-2, invarCasings, false, slbHatchFlags) - .add3by3(-1, stainlessSteelClean, true, null) - .add3by3(0, stainlessSteelClean, true, null) - .add3by3(1, stainlessSteelClean, true, null) - .add3by3(2, stainlessSteelClean, false, null) - .add(0, -1, 1, stainlessSteelPipe, null) - .add(0, 0, 1, stainlessSteelPipe, null) - .add(0, 1, 1, stainlessSteelPipe, null).build(); - + ShapeTemplate highPressureAdvancedLargeSteamBoilerShape = new ShapeTemplate.Structure(MI.id("high_pressure_advanced_large_steam_boiler")).build(); HIGH_PRESSURE_ADVANCED_LARGE_STEAM_BOILER = MachineRegistrationHelper.registerMachine( "High Pressure Advanced Large Steam Boiler", "high_pressure_advanced_large_steam_boiler", @@ -200,41 +132,14 @@ private static void steamBoilers() { } private static void quarries() { - SimpleMember steelCasing = SimpleMember.forBlock(MIBlock.BLOCK_DEFINITIONS.get(MI.id("steel_machine_casing"))); - SimpleMember steelPipe = SimpleMember.forBlock(MIBlock.BLOCK_DEFINITIONS.get(MI.id("steel_machine_casing_pipe"))); - HatchFlags quarryHatchFlags = new HatchFlags.Builder().with(ITEM_INPUT, FLUID_INPUT, ITEM_OUTPUT).build(); - HatchFlags quarryElectricHatchFlags = new HatchFlags.Builder().with(ITEM_INPUT, ITEM_OUTPUT, ENERGY_INPUT).build(); - - ShapeTemplate.Builder quarryShapeBuilder = new ShapeTemplate.Builder(MachineCasings.STEEL).add3by3(0, steelCasing, true, quarryHatchFlags) - .add3by3(1, steelCasing, true, quarryHatchFlags); - - ShapeTemplate.Builder quarryElectricShapeBuilder = new ShapeTemplate.Builder(MachineCasings.STEEL) - .add3by3(0, steelCasing, true, quarryElectricHatchFlags).add3by3(1, steelCasing, true, quarryElectricHatchFlags); - - for (int y = 2; y <= 4; y++) { - quarryShapeBuilder.add(-1, y, 1, steelPipe, null); - quarryShapeBuilder.add(1, y, 1, steelPipe, null); - quarryElectricShapeBuilder.add(-1, y, 1, steelPipe, null); - quarryElectricShapeBuilder.add(1, y, 1, steelPipe, null); - } - quarryShapeBuilder.add(0, 4, 1, steelCasing, null); - quarryElectricShapeBuilder.add(0, 4, 1, steelCasing, null); - - SimpleMember chain = SimpleMember.verticalChain(); - - for (int y = 0; y <= 3; y++) { - quarryShapeBuilder.add(0, y, 1, chain, null); - quarryElectricShapeBuilder.add(0, y, 1, chain, null); - } - - ShapeTemplate quarryShape = quarryShapeBuilder.build(); - ShapeTemplate quarryElectricShape = quarryElectricShapeBuilder.build(); - + ShapeTemplate quarryShape = new ShapeTemplate.Structure(MI.id("steam_quarry")).build(); STEAM_QUARRY = MachineRegistrationHelper.registerMachine( "Steam Quarry", "steam_quarry", bet -> new SteamCraftingMultiblockBlockEntity(bet, "steam_quarry", quarryShape, MIMachineRecipeTypes.QUARRY, OverclockComponent.getDefaultCatalysts())); ReiMachineRecipes.registerMultiblockShape("steam_quarry", quarryShape); + + ShapeTemplate quarryElectricShape = new ShapeTemplate.Structure(MI.id("electric_quarry")).build(); ELECTRIC_QUARRY = MachineRegistrationHelper.registerMachine( "Electric Quarry", "electric_quarry", @@ -243,24 +148,7 @@ private static void quarries() { } private static void oilDrillingRig() { - SimpleMember steelCasing = SimpleMember.forBlock(MIBlock.BLOCK_DEFINITIONS.get(MI.id("steel_machine_casing"))); - SimpleMember steelPipe = SimpleMember.forBlock(MIBlock.BLOCK_DEFINITIONS.get(MI.id("steel_machine_casing_pipe"))); - SimpleMember chain = SimpleMember.verticalChain(); - HatchFlags hatchFlags = new HatchFlags.Builder().with(ITEM_INPUT).with(FLUID_OUTPUT).with(ENERGY_INPUT).build(); - - ShapeTemplate oilDrillingRigShape = new ShapeTemplate.LayeredBuilder(MachineCasings.STEEL, new String[][] { - { "C C", "C C", "C C", "CCCCC", " ", " ", " ", " ", " ", " " }, - { " ", " ", " ", "C C", " HHH ", " ", " ", " ", " ", " " }, - { " o o ", " o o ", " o o ", "CoPoC", " oPo ", " oPo ", " oPo ", " oPo ", " oPo ", "CCCCC" }, - { " ", " ", " ", "C C", " H#H ", " ", " ", " ", " ", " " }, - { "C C", "C C", "C C", "CCCCC", " ", " ", " " , " ", " ", " "}, - }) - .key('C', steelCasing, null) - .key('o', chain, null) - .key('P', steelPipe, null) - .key('H', steelCasing, hatchFlags) - .build(); - + ShapeTemplate oilDrillingRigShape = new ShapeTemplate.Structure(MI.id("oil_drilling_rig")).build(); OIL_DRILLING_RIG = MachineRegistrationHelper.registerMachine( "Oil Drilling Rig", "oil_drilling_rig", bet -> new ElectricCraftingMultiblockBlockEntity(bet, @@ -269,10 +157,7 @@ private static void oilDrillingRig() { } private static void vacuumFreezer() { - HatchFlags vacuumFreezerHatches = new HatchFlags.Builder().with(ITEM_INPUT).with(ITEM_OUTPUT).with(FLUID_INPUT).with(FLUID_OUTPUT) - .with(ENERGY_INPUT).build(); - ShapeTemplate vacuumFreezerShape = new ShapeTemplate.Builder(MachineCasings.FROSTPROOF) - .add3by3LevelsRoofed(-1, 2, frostproofMachineCasing, vacuumFreezerHatches).build(); + ShapeTemplate vacuumFreezerShape = new ShapeTemplate.Structure(MI.id("vacuum_freezer")).build(); VACUUM_FREEZER = MachineRegistrationHelper.registerMachine( "Vacuum Freezer", "vacuum_freezer", @@ -288,25 +173,7 @@ private static void distillationTower() { } private static void largeDieselGenerator() { - ShapeTemplate.Builder largeDieselGeneratorShapeBuilder = new ShapeTemplate.Builder(MachineCasings.SOLID_TITANIUM); - for (int z = 1; z < 4; z++) { - largeDieselGeneratorShapeBuilder.add(0, 0, z, z < 3 ? titaniumPipe : titaniumCasing, z == 3 ? energyOutput : null); - for (int x = -1; x < 2; x++) { - largeDieselGeneratorShapeBuilder.add(x, 1, z, titaniumCasing, null); - largeDieselGeneratorShapeBuilder.add(x, -1, z, titaniumCasing, null); - if (x != 0) { - largeDieselGeneratorShapeBuilder.add(x, 0, z, titaniumCasing, z < 3 ? fluidInputs : null); - } - } - } - for (int y = -1; y <= 1; y++) { - for (int x = -1; x <= 1; x++) { - if (x != 0 || y != 0) { - largeDieselGeneratorShapeBuilder.add(x, y, 0, titaniumPipe, null); - } - } - } - ShapeTemplate largeDieselGeneratorShape = largeDieselGeneratorShapeBuilder.build(); + ShapeTemplate largeDieselGeneratorShape = new ShapeTemplate.Structure(MI.id("large_diesel_generator")).build(); LARGE_DIESEL_GENERATOR = MachineRegistrationHelper.registerMachine( "Large Diesel Generator", "large_diesel_generator", bet -> @@ -316,32 +183,8 @@ private static void largeDieselGenerator() { ReiMachineRecipes.registerMultiblockShape("large_diesel_generator", largeDieselGeneratorShape); } - private static ShapeTemplate largeTurbineShape(MachineCasing mainCasing, SimpleMember casing, SimpleMember pipe) { - ShapeTemplate.Builder largeTurbineBuilder = new ShapeTemplate.Builder(mainCasing); - for (int z = 0; z < 4; z++) { - for (int x = -1; x <= 1; x++) { - for (int y = -1; y <= 1; y++) { - if (z == 0) { - if (x != 0 || y != 0) { - largeTurbineBuilder.add(x, y, z, casing, fluidInputs); - } - } else if (z == 3) { - largeTurbineBuilder.add(x, y, z, casing, (x == 0 && y == 0) ? energyOutput : null); - } else { - largeTurbineBuilder.add(x, y, z, pipe, null); - } - - } - } - } - return largeTurbineBuilder.build(); - - } - private static void largeSteamTurbine() { - ShapeTemplate largeSteamTurbineShape = largeTurbineShape(MachineCasings.CLEAN_STAINLESS_STEEL, - stainlessSteelClean, stainlessSteelPipe); - + ShapeTemplate largeSteamTurbineShape = new ShapeTemplate.Structure(MI.id("large_steam_turbine")).build(); LARGE_STEAM_TURBINE = MachineRegistrationHelper.registerMachine( "Large Steam Turbine", "large_steam_turbine", bet -> @@ -359,31 +202,7 @@ private static void largeSteamTurbine() { } private static void heatExchanger() { - ShapeTemplate.Builder heatExchangerShapeBuilder = new ShapeTemplate.Builder(MachineCasings.STAINLESS_STEEL_PIPE); - for (int z = 0; z < 5; z++) { - for (int x = -1; x <= 1; x++) { - for (int y = -1; y <= 1; y++) { - if (z > 0 && z < 4) { - - heatExchangerShapeBuilder.add(x, y, z, x == 1 ? invarCasings : x == 0 ? stainlessSteelPipe : frostproofMachineCasing, - ((y == 1 || y == -1) && x == 0) ? energyInput : null); - } else { - if (z != 0 || x != 0 || y != 0) { - HatchFlags flag; - if (x == 0) { - flag = new HatchFlags.Builder().with(z == 0 ? ITEM_INPUT : ITEM_OUTPUT).with(ENERGY_INPUT).build(); - } else { - boolean fluidOutput = (x == -1) ^ (z == 0); - flag = new HatchFlags.Builder().with(fluidOutput ? FLUID_OUTPUT : FLUID_INPUT).build(); - } - - heatExchangerShapeBuilder.add(x, y, z, stainlessSteelPipe, flag); - } - } - } - } - } - ShapeTemplate heatExchangerShape = heatExchangerShapeBuilder.build(); + ShapeTemplate heatExchangerShape = new ShapeTemplate.Structure(MI.id("heat_exchanger")).build(); HEAT_EXCHANGER = MachineRegistrationHelper.registerMachine( "Heat Exchanger", "heat_exchanger", @@ -393,24 +212,7 @@ private static void heatExchanger() { } private static void pressurizer() { - ShapeTemplate.Builder pressurizeShapeBuilder = new ShapeTemplate.Builder(MachineCasings.TITANIUM); - for (int y = -1; y < 3; y++) { - SimpleMember member = (y == -1 || y == 2) ? titaniumCasing : titaniumPipe; - HatchFlags flag = null; - if (y == -1) { - flag = new HatchFlags.Builder().with(ENERGY_INPUT, FLUID_OUTPUT).build(); - } else if (y == 2) { - flag = new HatchFlags.Builder().with(FLUID_INPUT, ITEM_INPUT).build(); - } - pressurizeShapeBuilder.add(-1, y, 1, member, flag); - pressurizeShapeBuilder.add(0, y, 1, member, flag); - pressurizeShapeBuilder.add(1, y, 1, member, flag); - pressurizeShapeBuilder.add(0, y, 2, member, flag); - if (y != 0) { - pressurizeShapeBuilder.add(0, y, 0, member, flag); - } - } - ShapeTemplate pressurizerShape = pressurizeShapeBuilder.build(); + ShapeTemplate pressurizerShape = new ShapeTemplate.Structure(MI.id("pressurizer")).build(); PRESSURIZER = MachineRegistrationHelper.registerMachine( "Pressurizer", "pressurizer", @@ -419,14 +221,7 @@ private static void pressurizer() { } private static void implosionCompressor() { - ShapeTemplate.Builder implosionCompressorShapeBuilder = new ShapeTemplate.Builder(MachineCasings.TITANIUM); - HatchFlags hatchs = new HatchFlags.Builder().with(ITEM_OUTPUT, ITEM_INPUT, ENERGY_INPUT).build(); - implosionCompressorShapeBuilder.add3by3(0, titaniumCasing, false, hatchs); - implosionCompressorShapeBuilder.add3by3(1, blastProofCasing, true, null); - implosionCompressorShapeBuilder.add3by3(2, blastProofCasing, true, null); - implosionCompressorShapeBuilder.add3by3(3, titaniumCasing, false, null); - - ShapeTemplate implosionCompressorShape = implosionCompressorShapeBuilder.build(); + ShapeTemplate implosionCompressorShape = new ShapeTemplate.Structure(MI.id("implosion_compressor")).build(); IMPLOSION_COMPRESSOR = MachineRegistrationHelper.registerMachine( "Implosion Compressor", "implosion_compressor", @@ -448,81 +243,7 @@ private static void largeTank() { } private static void fusionReactor() { - ShapeTemplate.Builder fusionReactorShapeBuilder = new ShapeTemplate.Builder(CableTier.EV.casing); - int[][] shapeEdge = new int[][]{ - {6, 1, 0, 0}, - {4, 3, 0, 0}, - {3, 3, 0, 0}, - {2, 2, 0, 0}, - {1, 2, 0, 0}, - {1, 2, 0, 0}, - {0, 2, 0, 0}, - }; - - - int[][] shapeCenter = new int[][]{ - {5, 2, 0, 0}, - {3, 2, 2, 0}, - {2, 1, 2, 2}, - {1, 1, 2, 1}, - {1, 1, 1, 1}, - {0, 1, 1, 1}, - {0, 1, 1, 1} - }; - - for (int y = -1; y <= 1; y++) { - - int[][] shape = (y == 0) ? shapeCenter : shapeEdge; - - for (int i = 0; i < 7; i++) { - int x = i + 1; - - for (int k = 0; k < 4; k++) { - int[] placement = shape[6 - i]; - int z0 = placement[0]; - int z1 = z0 + placement[1]; - int z2 = z1 + placement[2]; - int z3 = z2 + placement[3]; - for (int z = z0; z < z3; z++) { - if (z < z1 || z >= z2) { - fusionReactorShapeBuilder.add(x, y, z, highlyAdvancedHull); - fusionReactorShapeBuilder.add(-x, y, z, highlyAdvancedHull); - fusionReactorShapeBuilder.add(x, y, 14 - z, highlyAdvancedHull); - fusionReactorShapeBuilder.add(-x, y, 14 - z, highlyAdvancedHull); - } else if (z >= z1) { - fusionReactorShapeBuilder.add(x, y, z, fusionChamber); - fusionReactorShapeBuilder.add(-x, y, z, fusionChamber); - fusionReactorShapeBuilder.add(x, y, 14 - z, fusionChamber); - fusionReactorShapeBuilder.add(-x, y, 14 - z, fusionChamber); - } - } - } - - } - - HatchFlags flags = new HatchFlags.Builder().with(FLUID_INPUT, FLUID_OUTPUT, ENERGY_INPUT).build(); - - for (int l = 0; l < ((y == 0) ? 3 : 2); l++) { - if (!(y == 0 && l == 1)) { - - HatchFlags currentFlag = l == 0 ? flags : null; - - if (l != 0 || y != 0) { - fusionReactorShapeBuilder.add(0, y, l, highlyAdvancedHull, currentFlag); - } - fusionReactorShapeBuilder.add(0, y, 14 - l, highlyAdvancedHull, currentFlag); - fusionReactorShapeBuilder.add(-7 + l, y, 7, highlyAdvancedHull, currentFlag); - fusionReactorShapeBuilder.add(7 - l, y, 7, highlyAdvancedHull, currentFlag); - } else { - fusionReactorShapeBuilder.add(0, y, l, fusionChamber); - fusionReactorShapeBuilder.add(0, y, 14 - l, fusionChamber); - fusionReactorShapeBuilder.add(-7 + l, y, 7, fusionChamber); - fusionReactorShapeBuilder.add(7 - l, y, 7, fusionChamber); - } - } - } - - ShapeTemplate fusionReactorShape = fusionReactorShapeBuilder.build(); + ShapeTemplate fusionReactorShape = new ShapeTemplate.Structure(MI.id("fusion_reactor")).build(); FUSION_REACTOR = MachineRegistrationHelper.registerMachine( "Fusion Reactor", "fusion_reactor", @@ -533,9 +254,7 @@ private static void fusionReactor() { } private static void plasmaTurbine() { - ShapeTemplate plasmaTurbineShape = largeTurbineShape(MachineCasings.PLASMA_HANDLING_IRIDIUM, - plasmaHandlingIridium, iridiumPipe); - + ShapeTemplate plasmaTurbineShape = new ShapeTemplate.Structure(MI.id("plasma_turbine")).build(); PLASMA_TURBINE = MachineRegistrationHelper.registerMachine( "Plasma Turbine", "plasma_turbine", bet -> @@ -549,29 +268,6 @@ private static void plasmaTurbine() { } public static void init() { - - invarCasings = SimpleMember.forBlock(MIBlock.BLOCK_DEFINITIONS.get(MI.id("heatproof_machine_casing"))); - - bronzePlatedBricks = SimpleMember.forBlock(MIBlock.BLOCK_DEFINITIONS.get(MI.id("bronze_plated_bricks"))); - bronzePipe = SimpleMember.forBlock(MIBlock.BLOCK_DEFINITIONS.get(MI.id("bronze_machine_casing_pipe"))); - - frostproofMachineCasing = SimpleMember.forBlock(MIBlock.BLOCK_DEFINITIONS.get(MI.id("frostproof_machine_casing"))); - - stainlessSteelClean = SimpleMember.forBlock(MIBlock.BLOCK_DEFINITIONS.get(MI.id("clean_stainless_steel_machine_casing"))); - stainlessSteelPipe = SimpleMember.forBlock(MIBlock.BLOCK_DEFINITIONS.get(MI.id("stainless_steel_machine_casing_pipe"))); - - titaniumCasing = SimpleMember.forBlock(MIBlock.BLOCK_DEFINITIONS.get(MI.id("solid_titanium_machine_casing"))); - titaniumPipe = SimpleMember.forBlock(MIBlock.BLOCK_DEFINITIONS.get(MI.id("titanium_machine_casing_pipe"))); - - blastProofCasing = SimpleMember.forBlock(MIBlock.BLOCK_DEFINITIONS.get(MI.id("blastproof_casing"))); - - - highlyAdvancedHull = SimpleMember.forBlock(MIBlock.BLOCK_DEFINITIONS.get(MI.id("highly_advanced_machine_hull"))); - fusionChamber = SimpleMember.forBlock(MIBlock.BLOCK_DEFINITIONS.get(MI.id("fusion_chamber"))); - - plasmaHandlingIridium = SimpleMember.forBlock(MIBlock.BLOCK_DEFINITIONS.get(MI.id("plasma_handling_iridium_machine_casing"))); - iridiumPipe = SimpleMember.forBlock(MIBlock.BLOCK_DEFINITIONS.get(MI.id("iridium_machine_casing_pipe"))); - cokeOven(); steamBlastFurnace(); electricBlastFurnace(); diff --git a/src/main/resources/mi_structures/modern_industrialization/advanced_large_steam_boiler.json b/src/main/resources/mi_structures/modern_industrialization/advanced_large_steam_boiler.json new file mode 100644 index 000000000..0d2109bd0 --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/advanced_large_steam_boiler.json @@ -0,0 +1,386 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 2, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + -2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + -2, + 1 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + -2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + -2, + 1 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + -2, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + -2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + -1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + -1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + -1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + -1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + -1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + -1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + -1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + -1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + -1, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + -2, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + -2, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 2, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + -2, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 2, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 2, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 2, + 2 + ] + } + ], + "members": [ + { + "state": { + "Name": "modern_industrialization:bronze_plated_bricks" + }, + "type": "literal" + }, + { + "state": { + "Name": "modern_industrialization:bronze_machine_casing_pipe" + }, + "type": "literal" + }, + { + "preview": { + "Name": "modern_industrialization:heatproof_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:heatproof_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:heatproof_machine_casing", + "hatch_flags": 13, + "type": "hatch" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/coke_oven.json b/src/main/resources/mi_structures/modern_industrialization/coke_oven.json new file mode 100644 index 000000000..edc3d3029 --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/coke_oven.json @@ -0,0 +1,220 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + -1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + -1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + -1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + -1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + -1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + -1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + -1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + -1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + -1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 1 + ] + } + ], + "members": [ + { + "state": { + "Name": "minecraft:bricks" + }, + "type": "literal" + }, + { + "preview": { + "Name": "minecraft:bricks" + }, + "tests": [ + { + "state": { + "Name": "minecraft:bricks" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:bricks", + "hatch_flags": 15, + "type": "hatch" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_1.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_1.json new file mode 100644 index 000000000..b6b3bd206 --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_1.json @@ -0,0 +1,180 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 1 + ] + } + ], + "members": [ + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 20, + "type": "hatch" + }, + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 8, + "type": "hatch" + }, + { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "type": "literal" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_10.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_10.json new file mode 100644 index 000000000..90a80964f --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_10.json @@ -0,0 +1,828 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 9, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 9, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 9, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 10, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 10, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 10, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 7, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 7, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 7, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 3, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 8, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 8, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 8, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 4, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 9, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 7, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 9, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 7, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 9, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 5, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 7, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 10, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 8, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 10, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 8, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 10, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 6, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 8, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 9, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 7, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 9, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 7, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 9, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 7, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 3, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 10, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 8, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 10, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 8, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 10, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 8, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 4, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 2 + ] + } + ], + "members": [ + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 20, + "type": "hatch" + }, + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 8, + "type": "hatch" + }, + { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "type": "literal" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_11.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_11.json new file mode 100644 index 000000000..b4c8a917c --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_11.json @@ -0,0 +1,900 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 11, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 9, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 11, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 9, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 11, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 9, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 10, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 10, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 10, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 11, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 11, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 11, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 7, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 7, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 7, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 3, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 8, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 8, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 8, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 4, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 9, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 7, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 9, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 7, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 9, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 5, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 7, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 10, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 8, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 10, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 8, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 10, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 6, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 8, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 11, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 9, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 11, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 7, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 9, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 11, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 7, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 9, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 7, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 3, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 10, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 8, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 10, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 8, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 10, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 8, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 4, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 2 + ] + } + ], + "members": [ + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 20, + "type": "hatch" + }, + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 8, + "type": "hatch" + }, + { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "type": "literal" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_12.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_12.json new file mode 100644 index 000000000..22cb71a96 --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_12.json @@ -0,0 +1,972 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 11, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 9, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 11, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 9, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 11, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 9, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 12, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 10, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 12, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 10, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 12, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 10, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 11, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 11, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 11, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 7, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 7, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 7, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 3, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 12, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 12, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 12, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 8, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 8, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 8, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 4, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 9, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 7, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 9, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 7, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 9, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 5, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 7, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 10, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 8, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 10, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 8, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 10, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 6, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 8, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 11, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 9, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 11, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 7, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 9, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 11, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 7, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 9, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 7, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 3, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 12, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 10, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 12, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 8, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 10, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 12, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 8, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 10, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 8, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 4, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 2 + ] + } + ], + "members": [ + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 20, + "type": "hatch" + }, + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 8, + "type": "hatch" + }, + { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "type": "literal" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_13.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_13.json new file mode 100644 index 000000000..c191d191d --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_13.json @@ -0,0 +1,1044 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 13, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 11, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 13, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 9, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 11, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 13, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 9, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 11, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 9, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 12, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 10, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 12, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 10, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 12, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 10, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 13, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 11, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 13, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 11, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 13, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 11, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 7, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 7, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 7, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 3, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 12, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 12, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 12, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 8, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 8, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 8, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 4, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 13, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 13, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 13, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 9, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 7, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 9, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 7, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 9, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 5, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 7, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 10, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 8, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 10, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 8, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 10, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 6, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 8, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 11, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 9, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 11, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 7, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 9, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 11, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 7, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 9, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 7, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 3, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 12, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 10, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 12, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 8, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 10, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 12, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 8, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 10, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 8, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 4, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 2 + ] + } + ], + "members": [ + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 20, + "type": "hatch" + }, + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 8, + "type": "hatch" + }, + { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "type": "literal" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_14.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_14.json new file mode 100644 index 000000000..791c0c873 --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_14.json @@ -0,0 +1,1116 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 13, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 11, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 13, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 9, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 11, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 13, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 9, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 11, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 9, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 14, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 12, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 14, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 10, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 12, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 14, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 10, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 12, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 10, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 13, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 11, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 13, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 11, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 13, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 11, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 7, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 7, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 7, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 3, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 14, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 12, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 14, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 12, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 14, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 12, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 8, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 8, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 8, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 4, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 13, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 13, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 13, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 9, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 7, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 9, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 7, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 9, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 5, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 7, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 14, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 14, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 14, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 10, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 8, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 10, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 8, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 10, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 6, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 8, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 11, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 9, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 11, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 7, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 9, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 11, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 7, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 9, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 7, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 3, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 12, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 10, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 12, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 8, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 10, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 12, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 8, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 10, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 8, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 4, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 2 + ] + } + ], + "members": [ + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 20, + "type": "hatch" + }, + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 8, + "type": "hatch" + }, + { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "type": "literal" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_15.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_15.json new file mode 100644 index 000000000..a390b98e0 --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_15.json @@ -0,0 +1,1188 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 13, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 11, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 13, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 9, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 11, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 13, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 9, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 11, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 9, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 14, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 12, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 14, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 10, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 12, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 14, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 10, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 12, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 10, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 15, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 13, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 15, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 11, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 13, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 15, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 11, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 13, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 11, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 7, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 7, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 7, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 3, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 14, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 12, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 14, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 12, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 14, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 12, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 8, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 8, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 8, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 4, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 15, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 13, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 15, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 13, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 15, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 13, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 9, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 7, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 9, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 7, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 9, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 5, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 7, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 14, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 14, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 14, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 10, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 8, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 10, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 8, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 10, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 6, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 8, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 15, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 15, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 15, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 11, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 9, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 11, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 7, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 9, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 11, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 7, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 9, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 7, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 3, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 12, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 10, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 12, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 8, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 10, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 12, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 8, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 10, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 8, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 4, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 2 + ] + } + ], + "members": [ + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 20, + "type": "hatch" + }, + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 8, + "type": "hatch" + }, + { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "type": "literal" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_2.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_2.json new file mode 100644 index 000000000..8c9926316 --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_2.json @@ -0,0 +1,252 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 2 + ] + } + ], + "members": [ + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 20, + "type": "hatch" + }, + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 8, + "type": "hatch" + }, + { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "type": "literal" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_3.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_3.json new file mode 100644 index 000000000..195822265 --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_3.json @@ -0,0 +1,324 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 3, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 2 + ] + } + ], + "members": [ + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 20, + "type": "hatch" + }, + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 8, + "type": "hatch" + }, + { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "type": "literal" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_4.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_4.json new file mode 100644 index 000000000..3a2b28b88 --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_4.json @@ -0,0 +1,396 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 3, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 4, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 4, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 2 + ] + } + ], + "members": [ + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 20, + "type": "hatch" + }, + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 8, + "type": "hatch" + }, + { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "type": "literal" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_5.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_5.json new file mode 100644 index 000000000..4e73c6e01 --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_5.json @@ -0,0 +1,468 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 5, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 3, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 3, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 4, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 4, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 2 + ] + } + ], + "members": [ + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 20, + "type": "hatch" + }, + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 8, + "type": "hatch" + }, + { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "type": "literal" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_6.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_6.json new file mode 100644 index 000000000..50acd3f74 --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_6.json @@ -0,0 +1,540 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 5, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 6, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 3, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 3, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 4, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 4, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 2 + ] + } + ], + "members": [ + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 20, + "type": "hatch" + }, + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 8, + "type": "hatch" + }, + { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "type": "literal" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_7.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_7.json new file mode 100644 index 000000000..1aea8c67f --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_7.json @@ -0,0 +1,612 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 7, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 7, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 5, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 7, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 6, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 7, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 7, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 7, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 7, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 7, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 7, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 3, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 3, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 4, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 4, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 2 + ] + } + ], + "members": [ + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 20, + "type": "hatch" + }, + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 8, + "type": "hatch" + }, + { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "type": "literal" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_8.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_8.json new file mode 100644 index 000000000..78ed7a38d --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_8.json @@ -0,0 +1,684 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 7, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 7, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 5, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 7, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 8, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 8, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 6, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 8, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 7, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 7, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 7, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 7, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 7, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 7, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 3, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 3, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 8, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 8, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 8, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 8, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 8, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 8, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 4, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 4, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 2 + ] + } + ], + "members": [ + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 20, + "type": "hatch" + }, + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 8, + "type": "hatch" + }, + { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "type": "literal" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_9.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_9.json new file mode 100644 index 000000000..dad78247e --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_9.json @@ -0,0 +1,756 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 9, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 9, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 9, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 9, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 7, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 9, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 7, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 9, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 5, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 7, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 8, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 8, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 6, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 8, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 9, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 7, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 9, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 7, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 9, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 7, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 7, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 7, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 7, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 3, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 5, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 3, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 8, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 8, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 8, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 8, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 8, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 8, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 4, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 6, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 4, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 2 + ] + } + ], + "members": [ + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 20, + "type": "hatch" + }, + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 8, + "type": "hatch" + }, + { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "type": "literal" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/electric_blast_furnace.json b/src/main/resources/mi_structures/modern_industrialization/electric_blast_furnace.json new file mode 100644 index 000000000..d3fc7b21a --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/electric_blast_furnace.json @@ -0,0 +1,290 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 3, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 3, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 3, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 3, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 3, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 2 + ] + } + ], + "members": [ + { + "preview": { + "Name": "modern_industrialization:heatproof_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:heatproof_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:heatproof_machine_casing", + "hatch_flags": 31, + "type": "hatch" + }, + { + "name": "coil", + "type": "variable" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/electric_quarry.json b/src/main/resources/mi_structures/modern_industrialization/electric_quarry.json new file mode 100644 index 000000000..de911c97e --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/electric_quarry.json @@ -0,0 +1,252 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 3, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 1 + ] + }, + { + "member_index": 3, + "pos": [ + 0, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 1 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 2, + 1 + ] + } + ], + "members": [ + { + "preview": { + "Name": "modern_industrialization:steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:steel", + "hatch_flags": 31, + "type": "hatch" + }, + { + "state": { + "Name": "modern_industrialization:steel_machine_casing_pipe" + }, + "type": "literal" + }, + { + "state": { + "Properties": { + "waterlogged": "false", + "axis": "y" + }, + "Name": "minecraft:chain" + }, + "type": "literal" + }, + { + "state": { + "Name": "modern_industrialization:steel_machine_casing" + }, + "type": "literal" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/fusion_reactor.json b/src/main/resources/mi_structures/modern_industrialization/fusion_reactor.json new file mode 100644 index 000000000..82ac1da25 --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/fusion_reactor.json @@ -0,0 +1,1978 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -2, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -7, + 0, + 8 + ] + }, + { + "member_index": 0, + "pos": [ + 2, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -6, + 0, + 8 + ] + }, + { + "member_index": 0, + "pos": [ + -5, + 0, + 8 + ] + }, + { + "member_index": 0, + "pos": [ + 5, + 0, + 8 + ] + }, + { + "member_index": 1, + "pos": [ + 6, + 0, + 8 + ] + }, + { + "member_index": 0, + "pos": [ + 7, + 0, + 8 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + -1, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + -1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + -1, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -7, + 1, + 8 + ] + }, + { + "member_index": 2, + "pos": [ + -7, + -1, + 7 + ] + }, + { + "member_index": 0, + "pos": [ + -6, + 1, + 8 + ] + }, + { + "member_index": 0, + "pos": [ + -6, + -1, + 7 + ] + }, + { + "member_index": 0, + "pos": [ + 6, + 1, + 8 + ] + }, + { + "member_index": 0, + "pos": [ + 6, + -1, + 7 + ] + }, + { + "member_index": 0, + "pos": [ + 7, + 1, + 8 + ] + }, + { + "member_index": 2, + "pos": [ + 7, + -1, + 7 + ] + }, + { + "member_index": 2, + "pos": [ + -7, + 0, + 7 + ] + }, + { + "member_index": 1, + "pos": [ + -6, + 0, + 7 + ] + }, + { + "member_index": 0, + "pos": [ + -5, + 0, + 7 + ] + }, + { + "member_index": 0, + "pos": [ + 5, + 0, + 7 + ] + }, + { + "member_index": 1, + "pos": [ + 6, + 0, + 7 + ] + }, + { + "member_index": 2, + "pos": [ + 7, + 0, + 7 + ] + }, + { + "member_index": 2, + "pos": [ + -7, + 1, + 7 + ] + }, + { + "member_index": 0, + "pos": [ + -7, + -1, + 6 + ] + }, + { + "member_index": 0, + "pos": [ + -6, + 1, + 7 + ] + }, + { + "member_index": 0, + "pos": [ + -6, + -1, + 6 + ] + }, + { + "member_index": 0, + "pos": [ + 6, + 1, + 7 + ] + }, + { + "member_index": 0, + "pos": [ + 6, + -1, + 6 + ] + }, + { + "member_index": 2, + "pos": [ + 7, + 1, + 7 + ] + }, + { + "member_index": 0, + "pos": [ + 7, + -1, + 6 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + -1, + 14 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + -1, + 14 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + -1, + 14 + ] + }, + { + "member_index": 0, + "pos": [ + -7, + 0, + 6 + ] + }, + { + "member_index": 1, + "pos": [ + -6, + 0, + 6 + ] + }, + { + "member_index": 0, + "pos": [ + -5, + 0, + 6 + ] + }, + { + "member_index": 0, + "pos": [ + 5, + 0, + 6 + ] + }, + { + "member_index": 1, + "pos": [ + 6, + 0, + 6 + ] + }, + { + "member_index": 0, + "pos": [ + -2, + 0, + 14 + ] + }, + { + "member_index": 0, + "pos": [ + 7, + 0, + 6 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 14 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 0, + 14 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 14 + ] + }, + { + "member_index": 0, + "pos": [ + 2, + 0, + 14 + ] + }, + { + "member_index": 0, + "pos": [ + -7, + 1, + 6 + ] + }, + { + "member_index": 0, + "pos": [ + -6, + 1, + 6 + ] + }, + { + "member_index": 0, + "pos": [ + -6, + -1, + 5 + ] + }, + { + "member_index": 0, + "pos": [ + -5, + -1, + 5 + ] + }, + { + "member_index": 0, + "pos": [ + 5, + -1, + 5 + ] + }, + { + "member_index": 0, + "pos": [ + 6, + 1, + 6 + ] + }, + { + "member_index": 0, + "pos": [ + -3, + -1, + 13 + ] + }, + { + "member_index": 0, + "pos": [ + 6, + -1, + 5 + ] + }, + { + "member_index": 0, + "pos": [ + 7, + 1, + 6 + ] + }, + { + "member_index": 0, + "pos": [ + -2, + -1, + 13 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 14 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + -1, + 13 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 1, + 14 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + -1, + 13 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 14 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + -1, + 13 + ] + }, + { + "member_index": 0, + "pos": [ + 2, + -1, + 13 + ] + }, + { + "member_index": 0, + "pos": [ + 3, + -1, + 13 + ] + }, + { + "member_index": 0, + "pos": [ + -7, + 0, + 5 + ] + }, + { + "member_index": 1, + "pos": [ + -6, + 0, + 5 + ] + }, + { + "member_index": 0, + "pos": [ + -5, + 0, + 5 + ] + }, + { + "member_index": 0, + "pos": [ + -4, + 0, + 13 + ] + }, + { + "member_index": 0, + "pos": [ + 5, + 0, + 5 + ] + }, + { + "member_index": 0, + "pos": [ + -3, + 0, + 13 + ] + }, + { + "member_index": 1, + "pos": [ + 6, + 0, + 5 + ] + }, + { + "member_index": 1, + "pos": [ + -2, + 0, + 13 + ] + }, + { + "member_index": 0, + "pos": [ + 7, + 0, + 5 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 0, + 13 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 0, + 13 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 0, + 13 + ] + }, + { + "member_index": 1, + "pos": [ + 2, + 0, + 13 + ] + }, + { + "member_index": 0, + "pos": [ + 3, + 0, + 13 + ] + }, + { + "member_index": 0, + "pos": [ + 4, + 0, + 13 + ] + }, + { + "member_index": 0, + "pos": [ + -6, + 1, + 5 + ] + }, + { + "member_index": 0, + "pos": [ + -6, + -1, + 4 + ] + }, + { + "member_index": 0, + "pos": [ + -5, + 1, + 5 + ] + }, + { + "member_index": 0, + "pos": [ + -5, + -1, + 4 + ] + }, + { + "member_index": 0, + "pos": [ + 5, + 1, + 5 + ] + }, + { + "member_index": 0, + "pos": [ + -4, + -1, + 12 + ] + }, + { + "member_index": 0, + "pos": [ + -3, + 1, + 13 + ] + }, + { + "member_index": 0, + "pos": [ + 5, + -1, + 4 + ] + }, + { + "member_index": 0, + "pos": [ + 6, + 1, + 5 + ] + }, + { + "member_index": 0, + "pos": [ + -3, + -1, + 12 + ] + }, + { + "member_index": 0, + "pos": [ + -2, + 1, + 13 + ] + }, + { + "member_index": 0, + "pos": [ + 6, + -1, + 4 + ] + }, + { + "member_index": 0, + "pos": [ + -2, + -1, + 12 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 13 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 1, + 13 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 13 + ] + }, + { + "member_index": 0, + "pos": [ + 2, + 1, + 13 + ] + }, + { + "member_index": 0, + "pos": [ + 2, + -1, + 12 + ] + }, + { + "member_index": 0, + "pos": [ + 3, + 1, + 13 + ] + }, + { + "member_index": 0, + "pos": [ + 3, + -1, + 12 + ] + }, + { + "member_index": 0, + "pos": [ + 4, + -1, + 12 + ] + }, + { + "member_index": 0, + "pos": [ + -6, + 0, + 4 + ] + }, + { + "member_index": 1, + "pos": [ + -5, + 0, + 4 + ] + }, + { + "member_index": 0, + "pos": [ + -4, + 0, + 4 + ] + }, + { + "member_index": 0, + "pos": [ + -5, + 0, + 12 + ] + }, + { + "member_index": 0, + "pos": [ + 4, + 0, + 4 + ] + }, + { + "member_index": 1, + "pos": [ + -4, + 0, + 12 + ] + }, + { + "member_index": 1, + "pos": [ + 5, + 0, + 4 + ] + }, + { + "member_index": 1, + "pos": [ + -3, + 0, + 12 + ] + }, + { + "member_index": 0, + "pos": [ + 6, + 0, + 4 + ] + }, + { + "member_index": 0, + "pos": [ + -2, + 0, + 12 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 12 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 12 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 12 + ] + }, + { + "member_index": 0, + "pos": [ + 2, + 0, + 12 + ] + }, + { + "member_index": 1, + "pos": [ + 3, + 0, + 12 + ] + }, + { + "member_index": 1, + "pos": [ + 4, + 0, + 12 + ] + }, + { + "member_index": 0, + "pos": [ + 5, + 0, + 12 + ] + }, + { + "member_index": 0, + "pos": [ + -6, + 1, + 4 + ] + }, + { + "member_index": 0, + "pos": [ + -5, + 1, + 4 + ] + }, + { + "member_index": 0, + "pos": [ + -5, + -1, + 3 + ] + }, + { + "member_index": 0, + "pos": [ + -4, + -1, + 3 + ] + }, + { + "member_index": 0, + "pos": [ + -5, + -1, + 11 + ] + }, + { + "member_index": 0, + "pos": [ + -4, + 1, + 12 + ] + }, + { + "member_index": 0, + "pos": [ + 4, + -1, + 3 + ] + }, + { + "member_index": 0, + "pos": [ + 5, + 1, + 4 + ] + }, + { + "member_index": 0, + "pos": [ + -4, + -1, + 11 + ] + }, + { + "member_index": 0, + "pos": [ + -3, + 1, + 12 + ] + }, + { + "member_index": 0, + "pos": [ + 5, + -1, + 3 + ] + }, + { + "member_index": 0, + "pos": [ + 6, + 1, + 4 + ] + }, + { + "member_index": 0, + "pos": [ + -2, + 1, + 12 + ] + }, + { + "member_index": 0, + "pos": [ + 2, + 1, + 12 + ] + }, + { + "member_index": 0, + "pos": [ + 3, + 1, + 12 + ] + }, + { + "member_index": 0, + "pos": [ + 4, + 1, + 12 + ] + }, + { + "member_index": 0, + "pos": [ + 4, + -1, + 11 + ] + }, + { + "member_index": 0, + "pos": [ + 5, + -1, + 11 + ] + }, + { + "member_index": 0, + "pos": [ + -6, + 0, + 3 + ] + }, + { + "member_index": 1, + "pos": [ + -5, + 0, + 3 + ] + }, + { + "member_index": 1, + "pos": [ + -4, + 0, + 3 + ] + }, + { + "member_index": 0, + "pos": [ + -3, + 0, + 3 + ] + }, + { + "member_index": 0, + "pos": [ + -6, + 0, + 11 + ] + }, + { + "member_index": 0, + "pos": [ + 3, + 0, + 3 + ] + }, + { + "member_index": 1, + "pos": [ + -5, + 0, + 11 + ] + }, + { + "member_index": 1, + "pos": [ + 4, + 0, + 3 + ] + }, + { + "member_index": 1, + "pos": [ + -4, + 0, + 11 + ] + }, + { + "member_index": 1, + "pos": [ + 5, + 0, + 3 + ] + }, + { + "member_index": 0, + "pos": [ + -3, + 0, + 11 + ] + }, + { + "member_index": 0, + "pos": [ + 6, + 0, + 3 + ] + }, + { + "member_index": 0, + "pos": [ + 3, + 0, + 11 + ] + }, + { + "member_index": 1, + "pos": [ + 4, + 0, + 11 + ] + }, + { + "member_index": 1, + "pos": [ + 5, + 0, + 11 + ] + }, + { + "member_index": 0, + "pos": [ + 6, + 0, + 11 + ] + }, + { + "member_index": 0, + "pos": [ + -5, + 1, + 3 + ] + }, + { + "member_index": 0, + "pos": [ + -4, + 1, + 3 + ] + }, + { + "member_index": 0, + "pos": [ + -4, + -1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -3, + -1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -2, + -1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 2, + -1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -6, + -1, + 10 + ] + }, + { + "member_index": 0, + "pos": [ + -5, + 1, + 11 + ] + }, + { + "member_index": 0, + "pos": [ + 3, + -1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 4, + 1, + 3 + ] + }, + { + "member_index": 0, + "pos": [ + -5, + -1, + 10 + ] + }, + { + "member_index": 0, + "pos": [ + -4, + 1, + 11 + ] + }, + { + "member_index": 0, + "pos": [ + 4, + -1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 5, + 1, + 3 + ] + }, + { + "member_index": 0, + "pos": [ + 4, + 1, + 11 + ] + }, + { + "member_index": 0, + "pos": [ + 5, + 1, + 11 + ] + }, + { + "member_index": 0, + "pos": [ + 5, + -1, + 10 + ] + }, + { + "member_index": 0, + "pos": [ + 6, + -1, + 10 + ] + }, + { + "member_index": 0, + "pos": [ + -5, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -4, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -3, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -2, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 2, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -6, + 0, + 10 + ] + }, + { + "member_index": 1, + "pos": [ + 3, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -5, + 0, + 10 + ] + }, + { + "member_index": 1, + "pos": [ + 4, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -4, + 0, + 10 + ] + }, + { + "member_index": 0, + "pos": [ + 5, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 4, + 0, + 10 + ] + }, + { + "member_index": 1, + "pos": [ + 5, + 0, + 10 + ] + }, + { + "member_index": 0, + "pos": [ + 6, + 0, + 10 + ] + }, + { + "member_index": 0, + "pos": [ + -4, + 1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -3, + 1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -3, + -1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -2, + 1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -2, + -1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + -1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + -1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + -1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 2, + 1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -6, + 1, + 10 + ] + }, + { + "member_index": 0, + "pos": [ + 2, + -1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 3, + 1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -6, + -1, + 9 + ] + }, + { + "member_index": 0, + "pos": [ + -5, + 1, + 10 + ] + }, + { + "member_index": 0, + "pos": [ + 3, + -1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 4, + 1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -5, + -1, + 9 + ] + }, + { + "member_index": 0, + "pos": [ + 5, + 1, + 10 + ] + }, + { + "member_index": 0, + "pos": [ + 5, + -1, + 9 + ] + }, + { + "member_index": 0, + "pos": [ + 6, + 1, + 10 + ] + }, + { + "member_index": 0, + "pos": [ + 6, + -1, + 9 + ] + }, + { + "member_index": 0, + "pos": [ + -4, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -3, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -2, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -7, + 0, + 9 + ] + }, + { + "member_index": 1, + "pos": [ + 2, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -6, + 0, + 9 + ] + }, + { + "member_index": 0, + "pos": [ + 3, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -5, + 0, + 9 + ] + }, + { + "member_index": 0, + "pos": [ + 4, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 5, + 0, + 9 + ] + }, + { + "member_index": 1, + "pos": [ + 6, + 0, + 9 + ] + }, + { + "member_index": 0, + "pos": [ + 7, + 0, + 9 + ] + }, + { + "member_index": 0, + "pos": [ + -3, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -2, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 2, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -7, + -1, + 8 + ] + }, + { + "member_index": 0, + "pos": [ + -6, + 1, + 9 + ] + }, + { + "member_index": 0, + "pos": [ + 3, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -6, + -1, + 8 + ] + }, + { + "member_index": 0, + "pos": [ + -5, + 1, + 9 + ] + }, + { + "member_index": 0, + "pos": [ + 5, + 1, + 9 + ] + }, + { + "member_index": 0, + "pos": [ + 6, + 1, + 9 + ] + }, + { + "member_index": 0, + "pos": [ + 6, + -1, + 8 + ] + }, + { + "member_index": 0, + "pos": [ + 7, + -1, + 8 + ] + } + ], + "members": [ + { + "state": { + "Name": "modern_industrialization:highly_advanced_machine_hull" + }, + "type": "literal" + }, + { + "state": { + "Name": "modern_industrialization:fusion_chamber" + }, + "type": "literal" + }, + { + "preview": { + "Name": "modern_industrialization:highly_advanced_machine_hull" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:highly_advanced_machine_hull" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:ev", + "hatch_flags": 28, + "type": "hatch" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/heat_exchanger.json b/src/main/resources/mi_structures/modern_industrialization/heat_exchanger.json new file mode 100644 index 000000000..91edab44b --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/heat_exchanger.json @@ -0,0 +1,456 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 3, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 4, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 3, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 0, + 3 + ] + }, + { + "member_index": 4, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 3, + "pos": [ + 0, + 0, + 3 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + 0, + 4 + ] + }, + { + "member_index": 4, + "pos": [ + 1, + 0, + 3 + ] + }, + { + "member_index": 5, + "pos": [ + 0, + 0, + 4 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 4 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + -1, + 0 + ] + }, + { + "member_index": 6, + "pos": [ + 0, + -1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + -1, + 0 + ] + }, + { + "member_index": 6, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 7, + "pos": [ + 0, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + -1, + 1 + ] + }, + { + "member_index": 4, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 7, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 3 + ] + }, + { + "member_index": 7, + "pos": [ + 0, + -1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + -1, + 2 + ] + }, + { + "member_index": 4, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 7, + "pos": [ + 0, + 1, + 3 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + 1, + 4 + ] + }, + { + "member_index": 4, + "pos": [ + 1, + -1, + 1 + ] + }, + { + "member_index": 7, + "pos": [ + 0, + -1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + -1, + 3 + ] + }, + { + "member_index": 4, + "pos": [ + 1, + 1, + 3 + ] + }, + { + "member_index": 5, + "pos": [ + 0, + 1, + 4 + ] + }, + { + "member_index": 4, + "pos": [ + 1, + -1, + 2 + ] + }, + { + "member_index": 7, + "pos": [ + 0, + -1, + 3 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + -1, + 4 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 4 + ] + }, + { + "member_index": 4, + "pos": [ + 1, + -1, + 3 + ] + }, + { + "member_index": 5, + "pos": [ + 0, + -1, + 4 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + -1, + 4 + ] + } + ], + "members": [ + { + "preview": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:stainless_steel_machine_casing_pipe", + "hatch_flags": 4, + "type": "hatch" + }, + { + "state": { + "Name": "modern_industrialization:frostproof_machine_casing" + }, + "type": "literal" + }, + { + "preview": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:stainless_steel_machine_casing_pipe", + "hatch_flags": 8, + "type": "hatch" + }, + { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "type": "literal" + }, + { + "state": { + "Name": "modern_industrialization:heatproof_machine_casing" + }, + "type": "literal" + }, + { + "preview": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:stainless_steel_machine_casing_pipe", + "hatch_flags": 18, + "type": "hatch" + }, + { + "preview": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:stainless_steel_machine_casing_pipe", + "hatch_flags": 17, + "type": "hatch" + }, + { + "preview": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:stainless_steel_machine_casing_pipe", + "hatch_flags": 16, + "type": "hatch" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/high_pressure_advanced_large_steam_boiler.json b/src/main/resources/mi_structures/modern_industrialization/high_pressure_advanced_large_steam_boiler.json new file mode 100644 index 000000000..5d25886e6 --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/high_pressure_advanced_large_steam_boiler.json @@ -0,0 +1,386 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 2, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + -2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + -2, + 1 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + -2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + -2, + 1 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + -2, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + -2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + -1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + -1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + -1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + -1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + -1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + -1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + -1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + -1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + -1, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + -2, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + -2, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 2, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + -2, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 2, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 2, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 2, + 2 + ] + } + ], + "members": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "literal" + }, + { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "type": "literal" + }, + { + "preview": { + "Name": "modern_industrialization:heatproof_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:heatproof_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:heatproof_machine_casing", + "hatch_flags": 13, + "type": "hatch" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/high_pressure_large_steam_boiler.json b/src/main/resources/mi_structures/modern_industrialization/high_pressure_large_steam_boiler.json new file mode 100644 index 000000000..038de2dbb --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/high_pressure_large_steam_boiler.json @@ -0,0 +1,314 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + -1, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + -1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + -1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + -1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + -1, + 1 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + -1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + -1, + 1 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + -1, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + -1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 2, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 2, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 2, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 2, + 2 + ] + } + ], + "members": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "literal" + }, + { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "type": "literal" + }, + { + "preview": { + "Name": "modern_industrialization:heatproof_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:heatproof_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:heatproof_machine_casing", + "hatch_flags": 13, + "type": "hatch" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/implosion_compressor.json b/src/main/resources/mi_structures/modern_industrialization/implosion_compressor.json new file mode 100644 index 000000000..1d0214019 --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/implosion_compressor.json @@ -0,0 +1,298 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + 3, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 3, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + 3, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + 3, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 3, + 1 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + 3, + 1 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + 3, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 2 + ] + } + ], + "members": [ + { + "preview": { + "Name": "modern_industrialization:solid_titanium_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:solid_titanium_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:solid_titanium_machine_casing", + "hatch_flags": 19, + "type": "hatch" + }, + { + "state": { + "Name": "modern_industrialization:blastproof_casing" + }, + "type": "literal" + }, + { + "state": { + "Name": "modern_industrialization:solid_titanium_machine_casing" + }, + "type": "literal" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/large_diesel_generator.json b/src/main/resources/mi_structures/modern_industrialization/large_diesel_generator.json new file mode 100644 index 000000000..bbcd02e4d --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/large_diesel_generator.json @@ -0,0 +1,330 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + 0, + 3 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 3, + "pos": [ + 0, + 0, + 3 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + 0, + 3 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + -1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + -1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + -1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 1, + 1 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + -1, + 1 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + 1, + 3 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + -1, + 1 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + -1, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 1, + 3 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + -1, + 1 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + -1, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + -1, + 3 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + 1, + 3 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + -1, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + -1, + 3 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + -1, + 3 + ] + } + ], + "members": [ + { + "state": { + "Name": "modern_industrialization:titanium_machine_casing_pipe" + }, + "type": "literal" + }, + { + "preview": { + "Name": "modern_industrialization:solid_titanium_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:solid_titanium_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:solid_titanium_machine_casing", + "hatch_flags": 4, + "type": "hatch" + }, + { + "state": { + "Name": "modern_industrialization:solid_titanium_machine_casing" + }, + "type": "literal" + }, + { + "preview": { + "Name": "modern_industrialization:solid_titanium_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:solid_titanium_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:solid_titanium_machine_casing", + "hatch_flags": 32, + "type": "hatch" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/large_steam_boiler.json b/src/main/resources/mi_structures/modern_industrialization/large_steam_boiler.json new file mode 100644 index 000000000..0039fd49e --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/large_steam_boiler.json @@ -0,0 +1,314 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + -1, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + -1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + -1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + -1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + -1, + 1 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + -1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + -1, + 1 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + -1, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + -1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 2, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 2, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 2, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 2, + 2 + ] + } + ], + "members": [ + { + "state": { + "Name": "modern_industrialization:bronze_plated_bricks" + }, + "type": "literal" + }, + { + "state": { + "Name": "modern_industrialization:bronze_machine_casing_pipe" + }, + "type": "literal" + }, + { + "preview": { + "Name": "modern_industrialization:heatproof_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:heatproof_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:heatproof_machine_casing", + "hatch_flags": 13, + "type": "hatch" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/large_steam_turbine.json b/src/main/resources/mi_structures/modern_industrialization/large_steam_turbine.json new file mode 100644 index 000000000..2694d22b8 --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/large_steam_turbine.json @@ -0,0 +1,330 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + 0, + 3 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 3, + "pos": [ + 0, + 0, + 3 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + 0, + 3 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + -1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + -1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + -1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + -1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + 1, + 3 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + -1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + -1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 1, + 3 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + -1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + -1, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + -1, + 3 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + 1, + 3 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + -1, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + -1, + 3 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + -1, + 3 + ] + } + ], + "members": [ + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 4, + "type": "hatch" + }, + { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + }, + "type": "literal" + }, + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "literal" + }, + { + "preview": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:clean_stainless_steel_machine_casing", + "hatch_flags": 32, + "type": "hatch" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/oil_drilling_rig.json b/src/main/resources/mi_structures/modern_industrialization/oil_drilling_rig.json new file mode 100644 index 000000000..0dc5d4942 --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/oil_drilling_rig.json @@ -0,0 +1,540 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -2, + -2, + -1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + -2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + -2, + -2, + 3 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + -2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 2, + -2, + 3 + ] + }, + { + "member_index": 0, + "pos": [ + 2, + -3, + -1 + ] + }, + { + "member_index": 0, + "pos": [ + 2, + -1, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + 3, + 1 + ] + }, + { + "member_index": 3, + "pos": [ + 0, + 3, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -2, + -3, + -1 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + 3, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -2, + -1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -2, + -1, + 1 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + -1, + 1 + ] + }, + { + "member_index": 3, + "pos": [ + 0, + -1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -2, + -1, + 3 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + -1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + -1, + 3 + ] + }, + { + "member_index": 0, + "pos": [ + 2, + -1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + -1, + 3 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + -1, + 3 + ] + }, + { + "member_index": 0, + "pos": [ + 2, + -1, + 3 + ] + }, + { + "member_index": 0, + "pos": [ + 2, + -4, + -1 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + 4, + 1 + ] + }, + { + "member_index": 3, + "pos": [ + 0, + 4, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -2, + -4, + -1 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + 4, + 1 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 3, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + -4, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -2, + -4, + 3 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + -4, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 2, + -4, + 3 + ] + }, + { + "member_index": 0, + "pos": [ + -2, + 5, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 5, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 5, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 2, + -1, + -1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 5, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + -1, + -1 + ] + }, + { + "member_index": 0, + "pos": [ + 2, + 5, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + -1, + -1 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + -1, + -1 + ] + }, + { + "member_index": 3, + "pos": [ + 0, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -2, + -1, + -1 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -2, + -1, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + -3, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -2, + -3, + 3 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + -3, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 2, + -1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 2, + -3, + 3 + ] + }, + { + "member_index": 0, + "pos": [ + 2, + -2, + -1 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + 2, + 1 + ] + }, + { + "member_index": 3, + "pos": [ + 0, + 2, + 1 + ] + } + ], + "members": [ + { + "state": { + "Name": "modern_industrialization:steel_machine_casing" + }, + "type": "literal" + }, + { + "preview": { + "Name": "modern_industrialization:steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:steel", + "hatch_flags": 25, + "type": "hatch" + }, + { + "state": { + "Properties": { + "waterlogged": "false", + "axis": "y" + }, + "Name": "minecraft:chain" + }, + "type": "literal" + }, + { + "state": { + "Name": "modern_industrialization:steel_machine_casing_pipe" + }, + "type": "literal" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/plasma_turbine.json b/src/main/resources/mi_structures/modern_industrialization/plasma_turbine.json new file mode 100644 index 000000000..0945410a7 --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/plasma_turbine.json @@ -0,0 +1,330 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + 0, + 3 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 3, + "pos": [ + 0, + 0, + 3 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + 0, + 3 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + -1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + -1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + -1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + -1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + 1, + 3 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + -1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + -1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 1, + 3 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + -1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + -1, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + -1, + 3 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + 1, + 3 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + -1, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + -1, + 3 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + -1, + 3 + ] + } + ], + "members": [ + { + "preview": { + "Name": "modern_industrialization:plasma_handling_iridium_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:plasma_handling_iridium_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:plasma_handling_iridium_machine_casing", + "hatch_flags": 4, + "type": "hatch" + }, + { + "state": { + "Name": "modern_industrialization:iridium_machine_casing_pipe" + }, + "type": "literal" + }, + { + "state": { + "Name": "modern_industrialization:plasma_handling_iridium_machine_casing" + }, + "type": "literal" + }, + { + "preview": { + "Name": "modern_industrialization:plasma_handling_iridium_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:plasma_handling_iridium_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:plasma_handling_iridium_machine_casing", + "hatch_flags": 32, + "type": "hatch" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/pressurizer.json b/src/main/resources/mi_structures/modern_industrialization/pressurizer.json new file mode 100644 index 000000000..2cec64978 --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/pressurizer.json @@ -0,0 +1,196 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + -1, + -1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + -1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 1, + -1, + 1 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + -1, + 2 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + -1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 1 + ] + } + ], + "members": [ + { + "state": { + "Name": "modern_industrialization:titanium_machine_casing_pipe" + }, + "type": "literal" + }, + { + "preview": { + "Name": "modern_industrialization:solid_titanium_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:solid_titanium_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:solid_titanium_machine_casing", + "hatch_flags": 5, + "type": "hatch" + }, + { + "preview": { + "Name": "modern_industrialization:solid_titanium_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:solid_titanium_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:solid_titanium_machine_casing", + "hatch_flags": 24, + "type": "hatch" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/steam_blast_furnace.json b/src/main/resources/mi_structures/modern_industrialization/steam_blast_furnace.json new file mode 100644 index 000000000..4865c2d10 --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/steam_blast_furnace.json @@ -0,0 +1,284 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + -1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + -1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + -1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + -1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + -1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + -1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + -1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + -1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + -1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 2 + ] + } + ], + "members": [ + { + "state": { + "Name": "modern_industrialization:fire_clay_bricks" + }, + "type": "literal" + }, + { + "preview": { + "Name": "modern_industrialization:fire_clay_bricks" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:fire_clay_bricks" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:firebricks", + "hatch_flags": 15, + "type": "hatch" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/steam_quarry.json b/src/main/resources/mi_structures/modern_industrialization/steam_quarry.json new file mode 100644 index 000000000..7ccb02a4d --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/steam_quarry.json @@ -0,0 +1,252 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 3, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 3, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 3, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 4, + 1 + ] + }, + { + "member_index": 3, + "pos": [ + 0, + 4, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 4, + 1 + ] + }, + { + "member_index": 2, + "pos": [ + 0, + 2, + 1 + ] + } + ], + "members": [ + { + "preview": { + "Name": "modern_industrialization:steel_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:steel_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:steel", + "hatch_flags": 15, + "type": "hatch" + }, + { + "state": { + "Name": "modern_industrialization:steel_machine_casing_pipe" + }, + "type": "literal" + }, + { + "state": { + "Properties": { + "waterlogged": "false", + "axis": "y" + }, + "Name": "minecraft:chain" + }, + "type": "literal" + }, + { + "state": { + "Name": "modern_industrialization:steel_machine_casing" + }, + "type": "literal" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/mi_structures/modern_industrialization/vacuum_freezer.json b/src/main/resources/mi_structures/modern_industrialization/vacuum_freezer.json new file mode 100644 index 000000000..64de0644e --- /dev/null +++ b/src/main/resources/mi_structures/modern_industrialization/vacuum_freezer.json @@ -0,0 +1,292 @@ +{ + "blocks": [ + { + "member_index": 0, + "pos": [ + -1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 0, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 0, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + -1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + -1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + -1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 0 + ] + }, + { + "member_index": 0, + "pos": [ + -1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + -1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 1 + ] + }, + { + "member_index": 0, + "pos": [ + 0, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + -1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + -1, + 2 + ] + }, + { + "member_index": 0, + "pos": [ + 1, + 1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + -1, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + -1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + -1, + 2 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + 1, + 2, + 0 + ] + }, + { + "member_index": 1, + "pos": [ + 0, + 2, + 1 + ] + }, + { + "member_index": 1, + "pos": [ + -1, + 2, + 2 + ] + } + ], + "members": [ + { + "state": { + "Name": "modern_industrialization:frostproof_machine_casing" + }, + "type": "literal" + }, + { + "preview": { + "Name": "modern_industrialization:frostproof_machine_casing" + }, + "tests": [ + { + "state": { + "Name": "modern_industrialization:frostproof_machine_casing" + }, + "type": "state" + } + ], + "casing": "modern_industrialization:frostproof_machine_casing", + "hatch_flags": 31, + "type": "hatch" + } + ] +} \ No newline at end of file From 55665170e0f6af542e6cceabc490ecfb64c44f86 Mon Sep 17 00:00:00 2001 From: Swedz Date: Mon, 2 Dec 2024 01:08:17 -0500 Subject: [PATCH 81/89] Add structure wrench item --- .../StructureMultiblockWrenchHighlight.java | 89 +++++++++++++ .../modern_industrialization/lang/en_us.json | 10 ++ .../modern_industrialization/MIBlock.java | 2 +- .../MIComponents.java | 4 + .../modern_industrialization/MIItem.java | 3 + .../modern_industrialization/MIText.java | 9 ++ .../modern_industrialization/MITooltips.java | 7 ++ ...uctureMultiblockControllerBlockEntity.java | 23 +++- .../items/SortOrder.java | 1 + .../StructureMultiblockWrenchItem.java | 118 ++++++++++++++++++ .../structure/StructureWrenchSelection.java | 77 ++++++++++++ .../structure/MIStructureTemplateManager.java | 7 +- .../StructureSaveControllerPacket.java | 2 +- .../util/NbtHelper.java | 31 ++++- .../item/structure_multiblock_wrench.json | 29 +++++ .../item/structure_multiblock_wrench.png | Bin 0 -> 668 bytes 16 files changed, 399 insertions(+), 13 deletions(-) create mode 100644 src/client/java/aztech/modern_industrialization/items/StructureMultiblockWrenchHighlight.java create mode 100644 src/main/java/aztech/modern_industrialization/items/structure/StructureMultiblockWrenchItem.java create mode 100644 src/main/java/aztech/modern_industrialization/items/structure/StructureWrenchSelection.java create mode 100644 src/main/resources/assets/modern_industrialization/models/item/structure_multiblock_wrench.json create mode 100644 src/main/resources/assets/modern_industrialization/textures/item/structure_multiblock_wrench.png diff --git a/src/client/java/aztech/modern_industrialization/items/StructureMultiblockWrenchHighlight.java b/src/client/java/aztech/modern_industrialization/items/StructureMultiblockWrenchHighlight.java new file mode 100644 index 000000000..bd8d107e4 --- /dev/null +++ b/src/client/java/aztech/modern_industrialization/items/StructureMultiblockWrenchHighlight.java @@ -0,0 +1,89 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.items; + +import aztech.modern_industrialization.MI; +import aztech.modern_industrialization.MIComponents; +import aztech.modern_industrialization.MIItem; +import aztech.modern_industrialization.util.RenderHelper; +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.ByteBufferBuilder; +import java.util.ArrayList; +import java.util.List; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.phys.Vec3; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.client.event.RenderLevelStageEvent; + +@EventBusSubscriber(modid = MI.ID) +public class StructureMultiblockWrenchHighlight { + private static final MultiBufferSource.BufferSource immediate = MultiBufferSource.immediate(new ByteBufferBuilder(128)); + + @SubscribeEvent + private static void onRender(RenderLevelStageEvent event) { + if (event.getStage() != RenderLevelStageEvent.Stage.AFTER_LEVEL) { + return; + } + Player player = Minecraft.getInstance().player; + List positions = getWrenchSelectedPositions(player); + if (!positions.isEmpty()) { + RenderSystem.clear(256, Minecraft.ON_OSX); + var poseStack = event.getPoseStack(); + poseStack.pushPose(); + poseStack.mulPose(event.getModelViewMatrix()); + for (BlockPos pos : positions) { + poseStack.pushPose(); + Vec3 cameraPos = Minecraft.getInstance().gameRenderer.getMainCamera().getPosition(); + double x = pos.getX() - cameraPos.x; + double y = pos.getY() - cameraPos.y; + double z = pos.getZ() - cameraPos.z; + poseStack.translate(x - 0.005, y - 0.005, z - 0.005); + poseStack.scale(1.01f, 1.01f, 1.01f); + RenderHelper.drawOverlay(poseStack, immediate, 1, 111f / 256, 1, 15728880, OverlayTexture.NO_OVERLAY); + poseStack.popPose(); + } + poseStack.popPose(); + immediate.endBatch(); + } + } + + private static List getWrenchSelectedPositions(Player player) { + List positions = new ArrayList<>(); + positions.addAll(getWrenchSelectedPositions(player.getMainHandItem())); + positions.addAll(getWrenchSelectedPositions(player.getOffhandItem())); + return positions; + } + + private static List getWrenchSelectedPositions(ItemStack stack) { + return stack.is(MIItem.STRUCTURE_MULTIBLOCK_WRENCH.asItem()) && stack.has(MIComponents.STRUCTURE_WRENCH_SELECTION) + ? stack.get(MIComponents.STRUCTURE_WRENCH_SELECTION).positions() + : List.of(); + } +} diff --git a/src/generated/resources/assets/modern_industrialization/lang/en_us.json b/src/generated/resources/assets/modern_industrialization/lang/en_us.json index e9328ebd7..885c970c8 100644 --- a/src/generated/resources/assets/modern_industrialization/lang/en_us.json +++ b/src/generated/resources/assets/modern_industrialization/lang/en_us.json @@ -983,6 +983,7 @@ "item.modern_industrialization.steel_rod_magnetic": "Magnetic Steel Rod", "item.modern_industrialization.steel_tiny_dust": "Steel Tiny Dust", "item.modern_industrialization.steel_upgrade": "Steel Upgrade", + "item.modern_industrialization.structure_multiblock_wrench": "Structure Multiblock Wrench", "item.modern_industrialization.styrene_bucket": "Styrene Bucket", "item.modern_industrialization.styrene_butadiene_bucket": "Styrene-Butadiene Bucket", "item.modern_industrialization.styrene_butadiene_rubber_bucket": "Styrene-Butadiene Rubber Bucket", @@ -1759,6 +1760,15 @@ "text.modern_industrialization.StructureMultiblockSaveFailUnknown": "Failed to save structure. See logs for more info.", "text.modern_industrialization.StructureMultiblockSaveSuccess": "The structure has been saved as %s.", "text.modern_industrialization.StructureMultiblockStructureName": "Structure Name", + "text.modern_industrialization.StructureMultiblockWrenchAdded": "Added (%s) to the selection", + "text.modern_industrialization.StructureMultiblockWrenchApplied": "Applied selection to the controller", + "text.modern_industrialization.StructureMultiblockWrenchCleared": "Cleared the selection", + "text.modern_industrialization.StructureMultiblockWrenchHelp1": "Block selection:", + "text.modern_industrialization.StructureMultiblockWrenchHelp2": "- Press %s on a block to add it to the selection.", + "text.modern_industrialization.StructureMultiblockWrenchHelp3": "- Press %s + %s on a structure controller to save the selection to the controller.", + "text.modern_industrialization.StructureMultiblockWrenchHelp4": "Clear selection using %s + %s on air.", + "text.modern_industrialization.StructureMultiblockWrenchRemoved": "Removed (%s) from the selection", + "text.modern_industrialization.StructureMultiblockWrenchTooltip": "Selected %s blocks", "text.modern_industrialization.SuperconductorPowerOnly": "Can only connect to Superconductor cables and machines. Must be directly connected to a machine on at least one end of the tunnel.", "text.modern_industrialization.Temperature": "Temperature: %d °C", "text.modern_industrialization.TemperatureMode": "Temperature", diff --git a/src/main/java/aztech/modern_industrialization/MIBlock.java b/src/main/java/aztech/modern_industrialization/MIBlock.java index 9cc19cf4e..8bf288b60 100644 --- a/src/main/java/aztech/modern_industrialization/MIBlock.java +++ b/src/main/java/aztech/modern_industrialization/MIBlock.java @@ -254,7 +254,7 @@ public static BlockDefinitionParams defaultCreativeOnly() { BlockBehaviour.Properties.of().mapColor(MapColor.METAL).destroyTime(-1.0f).explosionResistance(3600000.0f), Block::new, BlockItem::new, (block, modelGenerator) -> modelGenerator.simpleBlockWithItem(block, modelGenerator.cubeAll(block)), - null, List.of()); + null, List.of()).sortOrder(SortOrder.CREATIVE_ITEMS); } public static BlockDefinitionParams defaultStone() { diff --git a/src/main/java/aztech/modern_industrialization/MIComponents.java b/src/main/java/aztech/modern_industrialization/MIComponents.java index 75c5a703c..4c057310a 100644 --- a/src/main/java/aztech/modern_industrialization/MIComponents.java +++ b/src/main/java/aztech/modern_industrialization/MIComponents.java @@ -25,6 +25,7 @@ import aztech.modern_industrialization.blocks.storage.ResourceStorage; import aztech.modern_industrialization.items.SteamDrillFuel; +import aztech.modern_industrialization.items.structure.StructureWrenchSelection; import aztech.modern_industrialization.pipes.item.SavedItemPipeConfig; import aztech.modern_industrialization.thirdparty.fabrictransfer.api.fluid.FluidVariant; import aztech.modern_industrialization.thirdparty.fabrictransfer.api.item.ItemVariant; @@ -58,6 +59,9 @@ public final class MIComponents { builder -> builder.persistent(Codec.BOOL).networkSynchronized(ByteBufCodecs.BOOL)); public static final Supplier> STEAM_DRILL_FUEL = COMPONENTS.registerComponentType("steam_drill_fuel", builder -> builder.persistent(SteamDrillFuel.CODEC)); + public static final Supplier> STRUCTURE_WRENCH_SELECTION = COMPONENTS.registerComponentType( + "structure_wrench_selection", + builder -> builder.persistent(StructureWrenchSelection.CODEC).networkSynchronized(StructureWrenchSelection.STREAM_CODEC)); public static final Supplier> WATER = COMPONENTS.registerComponentType("water", builder -> builder.persistent(ExtraCodecs.POSITIVE_INT)); diff --git a/src/main/java/aztech/modern_industrialization/MIItem.java b/src/main/java/aztech/modern_industrialization/MIItem.java index 3f0de1896..56337e0dd 100644 --- a/src/main/java/aztech/modern_industrialization/MIItem.java +++ b/src/main/java/aztech/modern_industrialization/MIItem.java @@ -33,6 +33,7 @@ import aztech.modern_industrialization.items.armor.MIArmorMaterials; import aztech.modern_industrialization.items.armor.QuantumArmorItem; import aztech.modern_industrialization.items.diesel_tools.DieselToolItem; +import aztech.modern_industrialization.items.structure.StructureMultiblockWrenchItem; import aztech.modern_industrialization.items.tools.QuantumSword; import aztech.modern_industrialization.nuclear.INeutronBehaviour; import aztech.modern_industrialization.nuclear.NuclearComponentItem; @@ -208,6 +209,8 @@ public static void init(IEventBus modBus) { public static final ItemDefinition CONFIG_CARD = item("Pipe Config Card", "config_card", ConfigCardItem::new, PIPES); + public static final ItemDefinition STRUCTURE_MULTIBLOCK_WRENCH = itemNoModel("Structure Multiblock Wrench", "structure_multiblock_wrench", StructureMultiblockWrenchItem::new, CREATIVE_ITEMS); + // @formatter:on public static ItemDefinition item( diff --git a/src/main/java/aztech/modern_industrialization/MIText.java b/src/main/java/aztech/modern_industrialization/MIText.java index 57bbbc786..ed7706f4b 100644 --- a/src/main/java/aztech/modern_industrialization/MIText.java +++ b/src/main/java/aztech/modern_industrialization/MIText.java @@ -288,6 +288,15 @@ public enum MIText { StructureMultiblockSaveFailUnknown("Failed to save structure. See logs for more info."), StructureMultiblockSaveSuccess("The structure has been saved as %s."), StructureMultiblockStructureName("Structure Name"), + StructureMultiblockWrenchAdded("Added (%s) to the selection"), + StructureMultiblockWrenchApplied("Applied selection to the controller"), + StructureMultiblockWrenchCleared("Cleared the selection"), + StructureMultiblockWrenchHelp1("Block selection:"), + StructureMultiblockWrenchHelp2("- Press %s on a block to add it to the selection."), + StructureMultiblockWrenchHelp3("- Press %s + %s on a structure controller to save the selection to the controller."), + StructureMultiblockWrenchHelp4("Clear selection using %s + %s on air."), + StructureMultiblockWrenchRemoved("Removed (%s) from the selection"), + StructureMultiblockWrenchTooltip("Selected %s blocks"), SuperconductorPowerOnly( "Can only connect to Superconductor cables and machines. Must be directly connected to a machine on at least one end of the tunnel."), Temperature("Temperature: %d °C"), diff --git a/src/main/java/aztech/modern_industrialization/MITooltips.java b/src/main/java/aztech/modern_industrialization/MITooltips.java index 01ab70958..fd8912cac 100644 --- a/src/main/java/aztech/modern_industrialization/MITooltips.java +++ b/src/main/java/aztech/modern_industrialization/MITooltips.java @@ -420,6 +420,13 @@ public Component parse(Double ratio) { line(MIText.PipeHelp2).arg("sneak", KEYBIND_PARSER).arg("use", KEYBIND_PARSER).build())) : Optional.empty(); }); + public static final TooltipAttachment STRUCTURE_MULTIBLOCK_WRENCH_HELP = TooltipAttachment.ofMultilines(MIItem.STRUCTURE_MULTIBLOCK_WRENCH, + List.of( + line(MIText.StructureMultiblockWrenchHelp1).build(), + line(MIText.StructureMultiblockWrenchHelp2).arg("use", KEYBIND_PARSER).build(), + line(MIText.StructureMultiblockWrenchHelp3).arg("sneak", KEYBIND_PARSER).arg("use", KEYBIND_PARSER).build(), + line(MIText.StructureMultiblockWrenchHelp4).arg("sneak", KEYBIND_PARSER).arg("use", KEYBIND_PARSER).build())); + // Long Tooltip with only text, no need of MIText public static final Map TOOLTIPS_ENGLISH_TRANSLATION = new HashMap<>(); diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlockEntity.java index 5e9d506bc..d8b03c63a 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlockEntity.java @@ -29,13 +29,14 @@ import aztech.modern_industrialization.blocks.structure.StructureMemberOverride; import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockInputFormatters; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; +import aztech.modern_industrialization.util.NbtHelper; +import java.util.ArrayList; +import java.util.List; import java.util.Locale; import java.util.Objects; import net.minecraft.core.BlockPos; import net.minecraft.core.HolderLookup; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.NbtUtils; -import net.minecraft.nbt.Tag; +import net.minecraft.nbt.*; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.game.ClientGamePacketListener; import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; @@ -53,6 +54,8 @@ public class StructureMultiblockControllerBlockEntity extends FastBlockEntity im private boolean showBounds; private boolean includeBlockEntities; + private List ignoreNBTPositions = List.of(); + public StructureMultiblockControllerBlockEntity(BlockPos pos, BlockState state) { super(MIRegistries.STRUCTURE_MULTIBLOCK_CONTROLLER_BE.get(), pos, state); mode = state.getValue(StructureMultiblockControllerBlock.MODE); @@ -88,6 +91,7 @@ public StructureControllerBounds getBounds() { } public void setBounds(StructureControllerBounds bounds) { + Objects.requireNonNull(bounds); this.bounds = bounds; } @@ -107,6 +111,15 @@ public void setIncludeBlockEntities(boolean includeBlockEntities) { this.includeBlockEntities = includeBlockEntities; } + public List getIgnoreNBTPositions() { + return ignoreNBTPositions; + } + + public void setIgnoreNBTPositions(List ignoreNBTPositions) { + Objects.requireNonNull(ignoreNBTPositions); + this.ignoreNBTPositions = ignoreNBTPositions; + } + @Override public boolean isController() { return true; @@ -147,6 +160,7 @@ protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) tag.put("bounds", boundsTag); tag.putBoolean("show_bounds", showBounds); tag.putBoolean("include_block_entities", includeBlockEntities); + NbtHelper.putBlockPosList(tag, "ignore_nbt_positions", ignoreNBTPositions); } @Override @@ -166,6 +180,9 @@ protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) } showBounds = tag.getBoolean("show_bounds"); includeBlockEntities = tag.getBoolean("include_block_entities"); + List ignoreNBTPositions = new ArrayList<>(); + NbtHelper.getBlockPosList(tag, "ignore_nbt_positions", ignoreNBTPositions); + this.ignoreNBTPositions = ignoreNBTPositions; this.updateBlockState(); } diff --git a/src/main/java/aztech/modern_industrialization/items/SortOrder.java b/src/main/java/aztech/modern_industrialization/items/SortOrder.java index fe4957365..c12107997 100644 --- a/src/main/java/aztech/modern_industrialization/items/SortOrder.java +++ b/src/main/java/aztech/modern_industrialization/items/SortOrder.java @@ -39,6 +39,7 @@ public final class SortOrder implements Comparable { public static final SortOrder CASINGS = new SortOrder(); public static final SortOrder COILS = new SortOrder(); public static final SortOrder BLOCKS_OTHERS = new SortOrder(); + public static final SortOrder CREATIVE_ITEMS = new SortOrder(); public static final SortOrder ORES = new SortOrder(); public static final SortOrder RAW_ORE_BLOCKS = new SortOrder(); public static final SortOrder STORAGE_BLOCKS = new SortOrder(); diff --git a/src/main/java/aztech/modern_industrialization/items/structure/StructureMultiblockWrenchItem.java b/src/main/java/aztech/modern_industrialization/items/structure/StructureMultiblockWrenchItem.java new file mode 100644 index 000000000..94b5e6716 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/items/structure/StructureMultiblockWrenchItem.java @@ -0,0 +1,118 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.items.structure; + +import aztech.modern_industrialization.MIComponents; +import aztech.modern_industrialization.MIText; +import aztech.modern_industrialization.blocks.structure.controller.StructureMultiblockControllerBlockEntity; +import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlockEntity; +import java.util.List; +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.InteractionResultHolder; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Rarity; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; + +public class StructureMultiblockWrenchItem extends Item { + public StructureMultiblockWrenchItem(Properties properties) { + super(properties + .stacksTo(1) + .rarity(Rarity.EPIC) + .component(MIComponents.STRUCTURE_WRENCH_SELECTION, StructureWrenchSelection.EMPTY)); + } + + @Override + public InteractionResult onItemUseFirst(ItemStack ignored, UseOnContext context) { + boolean isClientSide = context.getLevel().isClientSide(); + Player player = context.getPlayer(); + if (player == null) { + return InteractionResult.PASS; + } + boolean isShiftKeyDown = player.isShiftKeyDown(); + ItemStack stack = player.getItemInHand(context.getHand()); + BlockEntity blockEntity = context.getLevel().getBlockEntity(context.getClickedPos()); + if (blockEntity != null) { + boolean isStructureBlock = blockEntity instanceof StructureMultiblockControllerBlockEntity + || blockEntity instanceof StructureMultiblockMemberBlockEntity; + if (isStructureBlock) { + if (isShiftKeyDown && blockEntity instanceof StructureMultiblockControllerBlockEntity controller) { + if (!isClientSide) { + var selection = stack.get(MIComponents.STRUCTURE_WRENCH_SELECTION); + controller.setIgnoreNBTPositions(selection.positions()); + controller.sync(); + controller.setChanged(); + player.displayClientMessage(MIText.StructureMultiblockWrenchApplied.text(), true); + } + return InteractionResult.sidedSuccess(isClientSide); + } + } else if (!isShiftKeyDown) { + if (!isClientSide) { + var selection = stack.get(MIComponents.STRUCTURE_WRENCH_SELECTION); + BlockPos pos = blockEntity.getBlockPos(); + if (selection.contains(pos)) { + selection = selection.remove(pos); + player.displayClientMessage(MIText.StructureMultiblockWrenchRemoved.text(pos.toShortString()), true); + } else { + selection = selection.add(pos); + player.displayClientMessage(MIText.StructureMultiblockWrenchAdded.text(pos.toShortString()), true); + } + stack.set(MIComponents.STRUCTURE_WRENCH_SELECTION, selection); + } + return InteractionResult.sidedSuccess(isClientSide); + } + } + return InteractionResult.PASS; + } + + @Override + public InteractionResultHolder use(Level level, Player player, InteractionHand usedHand) { + if (player.isShiftKeyDown()) { + player.getItemInHand(usedHand).set(MIComponents.STRUCTURE_WRENCH_SELECTION, StructureWrenchSelection.EMPTY); + player.displayClientMessage(MIText.StructureMultiblockWrenchCleared.text(), true); + return InteractionResultHolder.sidedSuccess(player.getItemInHand(usedHand), level.isClientSide()); + } + return super.use(level, player, usedHand); + } + + @Override + public void appendHoverText(ItemStack stack, TooltipContext context, List tooltipComponents, TooltipFlag isAdvanced) { + var selection = stack.get(MIComponents.STRUCTURE_WRENCH_SELECTION); + if (selection != null && !selection.positions().isEmpty()) { + tooltipComponents.add(MIText.StructureMultiblockWrenchTooltip.text(selection.positions().size())); + } + } + + @Override + public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged) { + return !newStack.is(this) || slotChanged; + } +} diff --git a/src/main/java/aztech/modern_industrialization/items/structure/StructureWrenchSelection.java b/src/main/java/aztech/modern_industrialization/items/structure/StructureWrenchSelection.java new file mode 100644 index 000000000..0c344fcad --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/items/structure/StructureWrenchSelection.java @@ -0,0 +1,77 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.items.structure; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import io.netty.buffer.ByteBuf; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import net.minecraft.core.BlockPos; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; + +public record StructureWrenchSelection(List positions) { + public static final StructureWrenchSelection EMPTY = new StructureWrenchSelection(List.of()); + + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group(Codec.list(BlockPos.CODEC).fieldOf("positions").forGetter(StructureWrenchSelection::positions)) + .apply(instance, StructureWrenchSelection::new)); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + BlockPos.STREAM_CODEC.apply(ByteBufCodecs.list()), + StructureWrenchSelection::positions, + StructureWrenchSelection::new); + + public StructureWrenchSelection { + positions = Collections.unmodifiableList(positions); + } + + public static StructureWrenchSelection of(List positions) { + return positions.isEmpty() ? EMPTY : new StructureWrenchSelection(positions); + } + + public boolean contains(BlockPos pos) { + return positions.contains(pos); + } + + public StructureWrenchSelection add(BlockPos pos) { + if (contains(pos)) { + return this; + } + var newPositions = new ArrayList<>(positions); + newPositions.add(pos); + return new StructureWrenchSelection(Collections.unmodifiableList(newPositions)); + } + + public StructureWrenchSelection remove(BlockPos pos) { + if (!contains(pos)) { + return this; + } + var newPositions = new ArrayList<>(positions); + newPositions.remove(pos); + return newPositions.isEmpty() ? EMPTY : new StructureWrenchSelection(Collections.unmodifiableList(newPositions)); + } +} diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java index cfe363530..7b452fd96 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java @@ -102,12 +102,14 @@ public static CompoundTag maybeTag(@Nullable BlockEntity blockEntity) { public static StructureResult fromWorld(ResourceLocation id, Level level, BlockPos controllerPos, Direction controllerDirection, - StructureControllerBounds bounds, boolean includeBlockEntities) { + StructureControllerBounds bounds, boolean includeBlockEntities, + List ignoreNBTPositions) { Objects.requireNonNull(id); Objects.requireNonNull(level); Objects.requireNonNull(controllerPos); Objects.requireNonNull(controllerDirection); Objects.requireNonNull(bounds); + Objects.requireNonNull(ignoreNBTPositions); if (bounds.isEmpty()) { return new StructureResult.InvalidBounds(); } @@ -129,7 +131,8 @@ public static StructureResult fromWorld(ResourceLocation id, Level level, } BlockEntity blockEntity = level.getBlockEntity(pos); - StructureMember member = StructureMember.literal(() -> state, includeBlockEntities ? blockEntity : null); + StructureMember member = StructureMember.literal(() -> state, + includeBlockEntities && !ignoreNBTPositions.contains(pos) ? blockEntity : null); if (blockEntity instanceof StructureMemberOverride override) { if (!override.isConfigurationValid()) { diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java index a1c4aa8af..620376fc4 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java @@ -61,7 +61,7 @@ public void handle(Context ctx) { ResourceLocation id = controller.getId(); var result = MIStructureTemplateManager.fromWorld(id, level, pos, state.getValue(StructureMultiblockControllerBlock.FACING), - controller.getBounds(), controller.includeBlockEntities()); + controller.getBounds(), controller.includeBlockEntities(), controller.getIgnoreNBTPositions()); if (result instanceof StructureResult.Success success) { if (MIStructureTemplateManager.save(id, success.template())) { MIStructureTemplateManager.register(id, success.template()); diff --git a/src/main/java/aztech/modern_industrialization/util/NbtHelper.java b/src/main/java/aztech/modern_industrialization/util/NbtHelper.java index a2061b879..72614bdae 100644 --- a/src/main/java/aztech/modern_industrialization/util/NbtHelper.java +++ b/src/main/java/aztech/modern_industrialization/util/NbtHelper.java @@ -108,18 +108,37 @@ public static void getList(CompoundTag tag, String key, List list, Functi } } + public static int[] encodeBlockPos(BlockPos pos) { + return new int[] { pos.getX(), pos.getY(), pos.getZ() }; + } + + public static BlockPos decodeBlockPos(int[] pos) { + return new BlockPos(pos[0], pos[1], pos[2]); + } + public static void putBlockPos(CompoundTag tag, String key, @Nullable BlockPos pos) { if (pos != null) { - tag.putIntArray(key, new int[] { pos.getX(), pos.getY(), pos.getZ() }); + tag.putIntArray(key, encodeBlockPos(pos)); } } public static BlockPos getBlockPos(CompoundTag tag, String key) { - if (tag.contains(key)) { - int[] pos = tag.getIntArray(key); - return new BlockPos(pos[0], pos[1], pos[2]); - } else { - return null; + return tag.contains(key) ? decodeBlockPos(tag.getIntArray(key)) : null; + } + + public static void putBlockPosList(CompoundTag tag, String key, List list) { + ListTag listTag = new ListTag(); + for (BlockPos pos : list) { + listTag.add(new IntArrayTag(encodeBlockPos(pos))); + } + tag.put(key, listTag); + } + + public static void getBlockPosList(CompoundTag tag, String key, List list) { + list.clear(); + ListTag listTag = tag.getList(key, Tag.TAG_INT_ARRAY); + for (Tag entry : listTag) { + list.add(decodeBlockPos(((IntArrayTag) entry).getAsIntArray())); } } diff --git a/src/main/resources/assets/modern_industrialization/models/item/structure_multiblock_wrench.json b/src/main/resources/assets/modern_industrialization/models/item/structure_multiblock_wrench.json new file mode 100644 index 000000000..d290461cc --- /dev/null +++ b/src/main/resources/assets/modern_industrialization/models/item/structure_multiblock_wrench.json @@ -0,0 +1,29 @@ +{ + "parent": "item/generated", + "display": { + "thirdperson_righthand": { + "rotation": [ 0, -90, 10 ], + "translation": [ 0, 6.0, 0.5 ], + "scale": [ 0.85, 0.85, 0.85 ] + }, + "firstperson_righthand": { + "rotation": [ 0, -90, 25 ], + "translation": [ 1.13, 3.2, 1.13 ], + "scale": [ 0.68, 0.68, 0.68 ] + }, + "thirdperson_lefthand": { + "rotation": [ 0, 90, -10 ], + "translation": [ 0, 6.0, 0.5 ], + "scale": [ 0.85, 0.85, 0.85 ] + }, + + "firstperson_lefthand": { + "rotation": [ 0, 90, -25 ], + "translation": [ 1.13, 3.2, 1.13 ], + "scale": [ 0.68, 0.68, 0.68 ] + } + }, + "textures": { + "layer0": "modern_industrialization:item/structure_multiblock_wrench" + } +} diff --git a/src/main/resources/assets/modern_industrialization/textures/item/structure_multiblock_wrench.png b/src/main/resources/assets/modern_industrialization/textures/item/structure_multiblock_wrench.png new file mode 100644 index 0000000000000000000000000000000000000000..b641af1d908f136f0254089d9c6a9580c7dabc57 GIT binary patch literal 668 zcmV;N0%QG&P)4Tx04UFukvT{MK^TQU6E8%uFoj5pE!0XuRK!xE7z6_nBX||=ZVrX)8g?T# zmV#}-!lUsjY^=4luoVQs1H{tGO3_AS{bv(M5F$7*%*UH~kC`_RILw-sTiXYgop<8V zh&DSnuQj|-Pc1D33G1eti%pLws5(CHs8Q=}ugcVc z?+S;^Wj!f;Cfwu51%)4!ZWQ@damMF>$_zP)_^5D5Sj$wfQNiZ2V+jumcP1@c@&mI) zPAc9|Y-QKX(mmA+n^X48w9;jUi84WqDKre$SRqTEURiBXT;j4Hsp9YO{ZryH#I=Gc zjxkoT(0xDZ4}N#+rU&|qNzD?}F!j9eLjOF$ACB(k}Z~4`KL2^g>zd zJb>0sIKL`u#tvL;LHlD)cXVG0$_%8_@OCQSGzV=r(6mtOt+da{JtU;7$!pl#hwhAI zFIIVXV`XoDp7Hx5@>ga)Q>170>_x010qNS#tmY3ljhU3ljkVnw%H_006*AL_t(I zPhID#((>#MgT~7Ny2=|qBG4S#7L1j<@)<6Vl0vP~v z2}pBFZ3e^5M^_oa0>}W}PcRJgH+p!WW1L<90bI^T26zns0bBtJ19%M}q!|PVx`2>3 z25}hhOLD_CgV?wL-rNYwK&MWg!c0I=Kw)-fU;qF_4U%=RAMsTH0000 Date: Mon, 2 Dec 2024 01:18:18 -0500 Subject: [PATCH 82/89] Properly ignore nbt checks if there is no nbt on the member --- .../multiblocks/structure/member/LiteralStructureMember.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java index 265540d13..4c6ce3ee0 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java @@ -67,9 +67,10 @@ public StructureMemberType type() { @Override public boolean matchesState(BlockState state, @Nullable BlockEntity blockEntity) { - CompoundTag beTag = MIStructureTemplateManager.maybeTag(blockEntity); + boolean noNBT = nbt == null; + CompoundTag beTag = noNBT ? null : MIStructureTemplateManager.maybeTag(blockEntity); for (StructureMemberTest test : tests) { - if (test.matchesState(state) && NbtHelper.equals(nbt, beTag)) { + if (test.matchesState(state) && (noNBT || NbtHelper.equals(nbt, beTag))) { return true; } } From 6a11612c0b7d9773fb9dc3526ff9bf5b46e19e93 Mon Sep 17 00:00:00 2001 From: Swedz Date: Mon, 2 Dec 2024 06:38:05 -0500 Subject: [PATCH 83/89] Add nbt mode functionality for member blocks and the structure wrench --- ...ructureMultiblockControllerEditScreen.java | 27 ++++--- .../StructureMultiblockMemberEditScreen.java | 32 ++++++-- .../ClientStructureMemberBlockTooltip.java | 17 ++-- .../multiblocks/MultiblockMachineBER.java | 9 ++- .../modern_industrialization/lang/en_us.json | 16 +++- .../MIComponents.java | 8 +- .../modern_industrialization/MIText.java | 16 +++- .../modern_industrialization/MITooltips.java | 5 +- .../controller/StructureControllerMode.java | 5 +- ...uctureMultiblockControllerBlockEntity.java | 20 ++++- .../StructureMultiblockMemberBlockEntity.java | 22 +++++- .../StructureMultiblockMemberBlockItem.java | 10 ++- .../StructureMultiblockWrenchItem.java | 48 +++++++++--- .../structure/StructureWrenchSelection.java | 10 +-- .../machines/multiblocks/ShapeMatcher.java | 6 +- .../structure/MIStructureTemplateManager.java | 11 ++- .../StructureMultiblockInputFormatters.java | 47 ++++++++--- .../structure/StructureNBTMode.java | 77 +++++++++++++++++++ .../member/HatchStructureMember.java | 19 +++-- .../member/LiteralStructureMember.java | 39 +++------- .../member/SimpleStructureMember.java | 34 +++++--- .../structure/member/StructureMember.java | 17 ++-- .../member/StructureMemberEntry.java | 60 +++++++++++++++ .../member/test/StateStructureMemberTest.java | 43 +++++++---- .../member/test/StructureMemberTest.java | 5 +- .../member/test/TagStructureMemberTest.java | 12 +-- .../StructureSaveControllerPacket.java | 3 +- .../StructureUpdateMemberPacket.java | 12 +-- .../util/MIExtraCodecs.java | 38 +++++++++ .../util/NbtHelper.java | 68 ++++++++++++++-- .../advanced_large_steam_boiler.json | 22 ++++-- .../modern_industrialization/coke_oven.json | 16 ++-- .../distillation_tower_1.json | 26 +++++-- .../distillation_tower_10.json | 26 +++++-- .../distillation_tower_11.json | 26 +++++-- .../distillation_tower_12.json | 26 +++++-- .../distillation_tower_13.json | 26 +++++-- .../distillation_tower_14.json | 26 +++++-- .../distillation_tower_15.json | 26 +++++-- .../distillation_tower_2.json | 26 +++++-- .../distillation_tower_3.json | 26 +++++-- .../distillation_tower_4.json | 26 +++++-- .../distillation_tower_5.json | 26 +++++-- .../distillation_tower_6.json | 26 +++++-- .../distillation_tower_7.json | 26 +++++-- .../distillation_tower_8.json | 26 +++++-- .../distillation_tower_9.json | 26 +++++-- .../electric_blast_furnace.json | 10 ++- .../electric_quarry.json | 36 +++++---- .../fusion_reactor.json | 22 ++++-- .../heat_exchanger.json | 68 +++++++++++----- ..._pressure_advanced_large_steam_boiler.json | 22 ++++-- .../high_pressure_large_steam_boiler.json | 22 ++++-- .../implosion_compressor.json | 22 ++++-- .../large_diesel_generator.json | 32 +++++--- .../large_steam_boiler.json | 22 ++++-- .../large_steam_turbine.json | 32 +++++--- .../oil_drilling_rig.json | 36 +++++---- .../plasma_turbine.json | 32 +++++--- .../modern_industrialization/pressurizer.json | 26 +++++-- .../steam_blast_furnace.json | 16 ++-- .../steam_quarry.json | 36 +++++---- .../vacuum_freezer.json | 16 ++-- 63 files changed, 1158 insertions(+), 456 deletions(-) create mode 100644 src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureNBTMode.java create mode 100644 src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberEntry.java diff --git a/src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockControllerEditScreen.java b/src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockControllerEditScreen.java index 4b937c66d..661c4f6b5 100644 --- a/src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockControllerEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockControllerEditScreen.java @@ -55,11 +55,11 @@ public class StructureMultiblockControllerEditScreen extends Screen { private final StructureMultiblockControllerBlockEntity controller; - private Button doneButton; - private Button cancelButton; private CycleButton modeButton; private Button saveButton; private Button loadButton; + private Button doneButton; + private Button cancelButton; private EditBox idBox; @@ -184,23 +184,22 @@ private void load() { @Override protected void init() { - this.addRenderableWidget( - doneButton = Button.builder(CommonComponents.GUI_DONE, button -> this.done()).bounds(width / 2 - 4 - 150, 210, 150, 20).build()); - this.addRenderableWidget( - cancelButton = Button.builder(CommonComponents.GUI_CANCEL, button -> this.cancel()).bounds(width / 2 + 4, 210, 150, 20).build()); - this.addRenderableWidget( - saveButton = Button.builder(MIText.StructureMultiblockGuiSave.text(), button -> this.save()) - .bounds(width / 2 + 4 + 100, 185, 50, 20).build()); - this.addRenderableWidget( - loadButton = Button.builder(MIText.StructureMultiblockGuiLoad.text(), button -> this.load()) - .bounds(width / 2 + 4 + 100, 185, 50, 20) - .tooltip(Tooltip.create(MIText.StructureMultiblockGuiLoadTooltip.text())) - .build()); this.addRenderableWidget(modeButton = CycleButton.builder(StructureControllerMode::text) .withValues(ALL_MODES, ALL_MODES) .displayOnlyValue() .withInitialValue(controller.getMode()) .create(width / 2 - 4 - 150, 185, 50, 20, MIText.StructureMultiblockGuiMode.text(), (button, mode) -> this.updateMode(mode))); + this.addRenderableWidget(saveButton = Button.builder(MIText.StructureMultiblockGuiSave.text(), button -> this.save()) + .bounds(width / 2 + 4 + 100, 185, 50, 20) + .build()); + this.addRenderableWidget(loadButton = Button.builder(MIText.StructureMultiblockGuiLoad.text(), button -> this.load()) + .bounds(width / 2 + 4 + 100, 185, 50, 20) + .tooltip(Tooltip.create(MIText.StructureMultiblockGuiLoadTooltip.text())) + .build()); + this.addRenderableWidget( + doneButton = Button.builder(CommonComponents.GUI_DONE, button -> this.done()).bounds(width / 2 - 4 - 150, 210, 150, 20).build()); + this.addRenderableWidget( + cancelButton = Button.builder(CommonComponents.GUI_CANCEL, button -> this.cancel()).bounds(width / 2 + 4, 210, 150, 20).build()); idBox = new EditBox(font, width / 2 - 152, 60, 304, 20, MIText.StructureMultiblockStructureName.text()) { @Override diff --git a/src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockMemberEditScreen.java b/src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockMemberEditScreen.java index 448822ece..406cf01e9 100644 --- a/src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockMemberEditScreen.java +++ b/src/client/java/aztech/modern_industrialization/client/screen/structure/StructureMultiblockMemberEditScreen.java @@ -30,6 +30,8 @@ import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.HatchFlags; import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockInputFormatters; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureNBTMode; +import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMemberEntry; import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StructureMemberTest; import aztech.modern_industrialization.network.structure.StructureUpdateMemberPacket; import com.google.common.collect.ImmutableList; @@ -45,19 +47,20 @@ import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.block.state.BlockState; public class StructureMultiblockMemberEditScreen extends Screen { private static final int VALID_TEXT_COLOR = 0xE0E0E0; private static final int INVALID_TEXT_COLOR = 0xE07272; private static final ImmutableList ALL_MODES = ImmutableList.copyOf(StructureMemberMode.values()); + private static final ImmutableList ALL_NBT_MODES = ImmutableList.of(StructureNBTMode.STRONG, StructureNBTMode.WEAK); private final StructureMultiblockMemberBlockEntity member; + private CycleButton modeButton; + private CycleButton nbtModeButton; private Button doneButton; private Button cancelButton; - private CycleButton modeButton; private EditBox nameBox; @@ -72,7 +75,7 @@ public StructureMultiblockMemberEditScreen(StructureMultiblockMemberBlockEntity this.member = member; } - private Optional getPreview() { + private Optional getPreview() { return Optional.ofNullable(StructureMultiblockInputFormatters.preview(previewBox.getValue())); } @@ -96,6 +99,7 @@ private void updateMode(StructureMemberMode mode) { membersBox.visible = false; casingBox.visible = false; flagsBox.visible = false; + nbtModeButton.visible = false; switch (mode) { case HATCH -> { @@ -103,10 +107,12 @@ private void updateMode(StructureMemberMode mode) { membersBox.visible = true; casingBox.visible = true; flagsBox.visible = true; + nbtModeButton.visible = true; } case SIMPLE -> { previewBox.visible = true; membersBox.visible = true; + nbtModeButton.visible = true; } case VARIABLE -> { nameBox.visible = true; @@ -160,6 +166,7 @@ private void sendToServer() { nameBox.getValue(), previewBox.getValue(), membersBox.getValue(), + nbtModeButton.getValue(), casingBox.getValue(), flagsBox.getValue()).sendToServer(); } @@ -170,15 +177,20 @@ private void cancel() { @Override protected void init() { - this.addRenderableWidget( - doneButton = Button.builder(CommonComponents.GUI_DONE, button -> this.done()).bounds(width / 2 - 4 - 150, 210, 150, 20).build()); - this.addRenderableWidget( - cancelButton = Button.builder(CommonComponents.GUI_CANCEL, button -> this.cancel()).bounds(width / 2 + 4, 210, 150, 20).build()); this.addRenderableWidget(modeButton = CycleButton.builder(StructureMemberMode::text) .withValues(ALL_MODES, ALL_MODES) .displayOnlyValue() .withInitialValue(member.getMode()) .create(width / 2 - 4 - 150, 185, 50, 20, MIText.StructureMultiblockGuiMode.text(), (button, mode) -> this.updateMode(mode))); + this.addRenderableWidget(nbtModeButton = CycleButton.builder(StructureNBTMode::textGui) + .withValues(ALL_NBT_MODES, ALL_NBT_MODES) + .displayOnlyValue() + .withInitialValue(member.getNBTMode()) + .create(width / 2 + 4 + 100, 185, 50, 20, MIText.StructureMultiblockGuiNBTMode.text())); + this.addRenderableWidget( + doneButton = Button.builder(CommonComponents.GUI_DONE, button -> this.done()).bounds(width / 2 - 4 - 150, 210, 150, 20).build()); + this.addRenderableWidget( + cancelButton = Button.builder(CommonComponents.GUI_CANCEL, button -> this.cancel()).bounds(width / 2 + 4, 210, 150, 20).build()); nameBox = new EditBox(font, width / 2 - 152, 20, 304, 20, MIText.StructureMultiblockMemberName.text()); nameBox.setMaxLength(Short.MAX_VALUE); @@ -243,6 +255,10 @@ public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTi if (flagsBox.visible) graphics.drawString(font, MIText.StructureMultiblockMemberHatchFlags.text(), width / 2 - 152, 130, 0xA0A0A0); + if (nbtModeButton.visible) + graphics.drawString(font, MIText.StructureMultiblockMemberNBTMode.text(), + width / 2 + 154 - font.width(MIText.StructureMultiblockMemberNBTMode.text()), 175, 0xA0A0A0); + graphics.drawString(font, modeButton.getValue().textInfo(), width / 2 - 4 - 150, 175, 0xA0A0A0); } @@ -262,6 +278,7 @@ public void resize(Minecraft minecraft, int width, int height) { String nameBoxValue = nameBox.getValue(); String previewBoxValue = previewBox.getValue(); String membersBoxValue = membersBox.getValue(); + StructureNBTMode nbtModeButtonValue = nbtModeButton.getValue(); String casingBoxValue = casingBox.getValue(); String flagsBoxValue = flagsBox.getValue(); @@ -271,6 +288,7 @@ public void resize(Minecraft minecraft, int width, int height) { nameBox.setValue(nameBoxValue); previewBox.setValue(previewBoxValue); membersBox.setValue(membersBoxValue); + nbtModeButton.setValue(nbtModeButtonValue); casingBox.setValue(casingBoxValue); flagsBox.setValue(flagsBoxValue); } diff --git a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java index 529c4fe91..1f26b9246 100644 --- a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java +++ b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java @@ -52,7 +52,6 @@ import net.minecraft.world.item.Items; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.LiquidBlock; -import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.Nullable; import org.joml.Matrix4f; @@ -80,11 +79,17 @@ public ClientStructureMemberBlockTooltip(StructureMultiblockMemberBlockItem.Tool } if (mode == StructureMemberMode.SIMPLE || mode == StructureMemberMode.HATCH) { - BlockState preview = data.preview(); - if (preview != null && !preview.isAir()) { - ItemStack previewStack = preview.getBlock().asItem().getDefaultInstance(); - lines.add(new IconsLine(MIText.StructureMultiblockMemberTooltipPreview.text().append(" ").withStyle(MITooltips.DEFAULT_STYLE), - List.of(new IconsLine.StackEntry(previewStack)), 6, previewStack.getHoverName().copy())); + lines.add(new ComponentLine(MIText.StructureMultiblockNBTMode.text(data.nbtMode().textTooltip().withStyle(MITooltips.HIGHLIGHT_STYLE)) + .withStyle(MITooltips.DEFAULT_STYLE))); + + var preview = data.preview(); + if (preview != null) { + var previewState = preview.state().get(); + if (!previewState.isAir()) { + ItemStack previewStack = previewState.getBlock().asItem().getDefaultInstance(); + lines.add(new IconsLine(MIText.StructureMultiblockMemberTooltipPreview.text().append(" ").withStyle(MITooltips.DEFAULT_STYLE), + List.of(new IconsLine.StackEntry(previewStack)), 6, previewStack.getHoverName().copy())); + } } List members = new ArrayList<>(); diff --git a/src/client/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBER.java b/src/client/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBER.java index d71ebfc58..7f46be2b9 100644 --- a/src/client/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBER.java +++ b/src/client/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBER.java @@ -27,7 +27,7 @@ import aztech.modern_industrialization.MITags; import aztech.modern_industrialization.machines.MachineBlock; import aztech.modern_industrialization.machines.MachineBlockEntityRenderer; -import aztech.modern_industrialization.machines.multiblocks.structure.member.LiteralStructureMember; +import aztech.modern_industrialization.machines.multiblocks.structure.member.SimpleStructureMember; import aztech.modern_industrialization.util.RenderHelper; import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.Minecraft; @@ -82,11 +82,12 @@ public void render(MultiblockMachineBlockEntity be, float tickDelta, PoseStack m SimpleMember member = matcher.getSimpleMember(pos); BlockState state = ShapeMatcher.toWorldState(level, pos, member.getPreviewState(), matcher.controllerDirection); BlockEntity blockEntity = null; - if (member instanceof LiteralStructureMember literalMember && state.getBlock() instanceof EntityBlock entityBlock) { + if (member instanceof SimpleStructureMember simpleMember && state.getBlock() instanceof EntityBlock entityBlock) { blockEntity = entityBlock.newBlockEntity(pos, state); blockEntity.setLevel(level); - if (literalMember.nbt() != null) { - blockEntity.loadCustomOnly(literalMember.nbt(), level.registryAccess()); + var nbt = simpleMember.preview().nbt(); + if (nbt != null) { + blockEntity.loadCustomOnly(nbt, level.registryAccess()); } } MultiblockErrorHighlight.enqueueHighlight(pos, state, blockEntity); diff --git a/src/generated/resources/assets/modern_industrialization/lang/en_us.json b/src/generated/resources/assets/modern_industrialization/lang/en_us.json index 885c970c8..bad98f6ec 100644 --- a/src/generated/resources/assets/modern_industrialization/lang/en_us.json +++ b/src/generated/resources/assets/modern_industrialization/lang/en_us.json @@ -1723,6 +1723,9 @@ "text.modern_industrialization.StructureMultiblockGuiLoad": "LOAD", "text.modern_industrialization.StructureMultiblockGuiLoadTooltip": "Hold SHIFT to place actual blocks instead of structure blocks.", "text.modern_industrialization.StructureMultiblockGuiMode": "MODE", + "text.modern_industrialization.StructureMultiblockGuiNBTMode": "NBT MODE", + "text.modern_industrialization.StructureMultiblockGuiNBTModeStrong": "STRONG", + "text.modern_industrialization.StructureMultiblockGuiNBTModeWeak": "WEAK", "text.modern_industrialization.StructureMultiblockGuiRelativePosition": "Relative Position", "text.modern_industrialization.StructureMultiblockGuiRelativePositionX": "Relative Position X", "text.modern_industrialization.StructureMultiblockGuiRelativePositionY": "Relative Position Y", @@ -1744,6 +1747,7 @@ "text.modern_industrialization.StructureMultiblockMemberModeInfoVariable": "Variable Mode - Filled in at startup", "text.modern_industrialization.StructureMultiblockMemberModeSimple": "Simple", "text.modern_industrialization.StructureMultiblockMemberModeVariable": "Variable", + "text.modern_industrialization.StructureMultiblockMemberNBTMode": "NBT Mode:", "text.modern_industrialization.StructureMultiblockMemberName": "Member Name", "text.modern_industrialization.StructureMultiblockMemberPreview": "Preview", "text.modern_industrialization.StructureMultiblockMemberTooltipCasing": "Casing:", @@ -1752,6 +1756,7 @@ "text.modern_industrialization.StructureMultiblockMemberTooltipMode": "Mode: %s", "text.modern_industrialization.StructureMultiblockMemberTooltipPreview": "Preview:", "text.modern_industrialization.StructureMultiblockMemberTooltipVariableName": "Name: %s", + "text.modern_industrialization.StructureMultiblockNBTMode": "NBT Mode: %s", "text.modern_industrialization.StructureMultiblockSaveFailInvalidBounds": "Failed to save structure. The bounds provided are not valid.", "text.modern_industrialization.StructureMultiblockSaveFailMisconfiguredBlock": "Failed to save structure. Some blocks are not properly configured.", "text.modern_industrialization.StructureMultiblockSaveFailNoController": "Failed to save structure. No controller could be found within the bounds.", @@ -1762,11 +1767,16 @@ "text.modern_industrialization.StructureMultiblockStructureName": "Structure Name", "text.modern_industrialization.StructureMultiblockWrenchAdded": "Added (%s) to the selection", "text.modern_industrialization.StructureMultiblockWrenchApplied": "Applied selection to the controller", + "text.modern_industrialization.StructureMultiblockWrenchChangedMode": "Set mode to %s", "text.modern_industrialization.StructureMultiblockWrenchCleared": "Cleared the selection", "text.modern_industrialization.StructureMultiblockWrenchHelp1": "Block selection:", - "text.modern_industrialization.StructureMultiblockWrenchHelp2": "- Press %s on a block to add it to the selection.", - "text.modern_industrialization.StructureMultiblockWrenchHelp3": "- Press %s + %s on a structure controller to save the selection to the controller.", - "text.modern_industrialization.StructureMultiblockWrenchHelp4": "Clear selection using %s + %s on air.", + "text.modern_industrialization.StructureMultiblockWrenchHelp2": "- Press %s on air to change modes.", + "text.modern_industrialization.StructureMultiblockWrenchHelp3": "- Press %s on a block to add it to the selection.", + "text.modern_industrialization.StructureMultiblockWrenchHelp4": "- Press %s + %s on a structure controller to save the selection to the controller.", + "text.modern_industrialization.StructureMultiblockWrenchHelp5": "Clear selection using %s + %s on air.", + "text.modern_industrialization.StructureMultiblockWrenchNBTModeIgnore": "Ignore", + "text.modern_industrialization.StructureMultiblockWrenchNBTModeStrong": "Strong Include", + "text.modern_industrialization.StructureMultiblockWrenchNBTModeWeak": "Weak Include", "text.modern_industrialization.StructureMultiblockWrenchRemoved": "Removed (%s) from the selection", "text.modern_industrialization.StructureMultiblockWrenchTooltip": "Selected %s blocks", "text.modern_industrialization.SuperconductorPowerOnly": "Can only connect to Superconductor cables and machines. Must be directly connected to a machine on at least one end of the tunnel.", diff --git a/src/main/java/aztech/modern_industrialization/MIComponents.java b/src/main/java/aztech/modern_industrialization/MIComponents.java index 4c057310a..6ccf6db2b 100644 --- a/src/main/java/aztech/modern_industrialization/MIComponents.java +++ b/src/main/java/aztech/modern_industrialization/MIComponents.java @@ -26,6 +26,7 @@ import aztech.modern_industrialization.blocks.storage.ResourceStorage; import aztech.modern_industrialization.items.SteamDrillFuel; import aztech.modern_industrialization.items.structure.StructureWrenchSelection; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureNBTMode; import aztech.modern_industrialization.pipes.item.SavedItemPipeConfig; import aztech.modern_industrialization.thirdparty.fabrictransfer.api.fluid.FluidVariant; import aztech.modern_industrialization.thirdparty.fabrictransfer.api.item.ItemVariant; @@ -59,11 +60,14 @@ public final class MIComponents { builder -> builder.persistent(Codec.BOOL).networkSynchronized(ByteBufCodecs.BOOL)); public static final Supplier> STEAM_DRILL_FUEL = COMPONENTS.registerComponentType("steam_drill_fuel", builder -> builder.persistent(SteamDrillFuel.CODEC)); + public static final Supplier> WATER = COMPONENTS.registerComponentType("water", + builder -> builder.persistent(ExtraCodecs.POSITIVE_INT)); + public static final Supplier> STRUCTURE_WRENCH_MODE = COMPONENTS.registerComponentType( + "structure_wrench_mode", + builder -> builder.persistent(StructureNBTMode.CODEC).networkSynchronized(StructureNBTMode.STREAM_CODEC)); public static final Supplier> STRUCTURE_WRENCH_SELECTION = COMPONENTS.registerComponentType( "structure_wrench_selection", builder -> builder.persistent(StructureWrenchSelection.CODEC).networkSynchronized(StructureWrenchSelection.STREAM_CODEC)); - public static final Supplier> WATER = COMPONENTS.registerComponentType("water", - builder -> builder.persistent(ExtraCodecs.POSITIVE_INT)); public static final Supplier> FLUID_CONTENT = COMPONENTS.registerComponentType("fluid_content", builder -> builder.persistent(SimpleFluidContent.CODEC).networkSynchronized(SimpleFluidContent.STREAM_CODEC)); diff --git a/src/main/java/aztech/modern_industrialization/MIText.java b/src/main/java/aztech/modern_industrialization/MIText.java index ed7706f4b..60ba682f2 100644 --- a/src/main/java/aztech/modern_industrialization/MIText.java +++ b/src/main/java/aztech/modern_industrialization/MIText.java @@ -251,6 +251,9 @@ public enum MIText { StructureMultiblockGuiLoad("LOAD"), StructureMultiblockGuiLoadTooltip("Hold SHIFT to place actual blocks instead of structure blocks."), StructureMultiblockGuiMode("MODE"), + StructureMultiblockGuiNBTMode("NBT MODE"), + StructureMultiblockGuiNBTModeStrong("STRONG"), + StructureMultiblockGuiNBTModeWeak("WEAK"), StructureMultiblockGuiRelativePosition("Relative Position"), StructureMultiblockGuiRelativePositionX("Relative Position X"), StructureMultiblockGuiRelativePositionY("Relative Position Y"), @@ -272,6 +275,7 @@ public enum MIText { StructureMultiblockMemberModeInfoVariable("Variable Mode - Filled in at startup"), StructureMultiblockMemberModeSimple("Simple"), StructureMultiblockMemberModeVariable("Variable"), + StructureMultiblockMemberNBTMode("NBT Mode:"), StructureMultiblockMemberName("Member Name"), StructureMultiblockMemberPreview("Preview"), StructureMultiblockMemberTooltipCasing("Casing:"), @@ -280,6 +284,7 @@ public enum MIText { StructureMultiblockMemberTooltipMode("Mode: %s"), StructureMultiblockMemberTooltipPreview("Preview:"), StructureMultiblockMemberTooltipVariableName("Name: %s"), + StructureMultiblockNBTMode("NBT Mode: %s"), StructureMultiblockSaveFailInvalidBounds("Failed to save structure. The bounds provided are not valid."), StructureMultiblockSaveFailMisconfiguredBlock("Failed to save structure. Some blocks are not properly configured."), StructureMultiblockSaveFailNoController("Failed to save structure. No controller could be found within the bounds."), @@ -290,11 +295,16 @@ public enum MIText { StructureMultiblockStructureName("Structure Name"), StructureMultiblockWrenchAdded("Added (%s) to the selection"), StructureMultiblockWrenchApplied("Applied selection to the controller"), + StructureMultiblockWrenchChangedMode("Set mode to %s"), StructureMultiblockWrenchCleared("Cleared the selection"), StructureMultiblockWrenchHelp1("Block selection:"), - StructureMultiblockWrenchHelp2("- Press %s on a block to add it to the selection."), - StructureMultiblockWrenchHelp3("- Press %s + %s on a structure controller to save the selection to the controller."), - StructureMultiblockWrenchHelp4("Clear selection using %s + %s on air."), + StructureMultiblockWrenchHelp2("- Press %s on air to change modes."), + StructureMultiblockWrenchHelp3("- Press %s on a block to add it to the selection."), + StructureMultiblockWrenchHelp4("- Press %s + %s on a structure controller to save the selection to the controller."), + StructureMultiblockWrenchHelp5("Clear selection using %s + %s on air."), + StructureMultiblockWrenchNBTModeIgnore("Ignore"), + StructureMultiblockWrenchNBTModeStrong("Strong Include"), + StructureMultiblockWrenchNBTModeWeak("Weak Include"), StructureMultiblockWrenchRemoved("Removed (%s) from the selection"), StructureMultiblockWrenchTooltip("Selected %s blocks"), SuperconductorPowerOnly( diff --git a/src/main/java/aztech/modern_industrialization/MITooltips.java b/src/main/java/aztech/modern_industrialization/MITooltips.java index fd8912cac..b1e791e12 100644 --- a/src/main/java/aztech/modern_industrialization/MITooltips.java +++ b/src/main/java/aztech/modern_industrialization/MITooltips.java @@ -424,8 +424,9 @@ public Component parse(Double ratio) { List.of( line(MIText.StructureMultiblockWrenchHelp1).build(), line(MIText.StructureMultiblockWrenchHelp2).arg("use", KEYBIND_PARSER).build(), - line(MIText.StructureMultiblockWrenchHelp3).arg("sneak", KEYBIND_PARSER).arg("use", KEYBIND_PARSER).build(), - line(MIText.StructureMultiblockWrenchHelp4).arg("sneak", KEYBIND_PARSER).arg("use", KEYBIND_PARSER).build())); + line(MIText.StructureMultiblockWrenchHelp3).arg("use", KEYBIND_PARSER).build(), + line(MIText.StructureMultiblockWrenchHelp4).arg("sneak", KEYBIND_PARSER).arg("use", KEYBIND_PARSER).build(), + line(MIText.StructureMultiblockWrenchHelp5).arg("sneak", KEYBIND_PARSER).arg("use", KEYBIND_PARSER).build())); // Long Tooltip with only text, no need of MIText diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureControllerMode.java b/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureControllerMode.java index 35dbfd1fe..bc9f29958 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureControllerMode.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureControllerMode.java @@ -25,17 +25,18 @@ import java.util.Locale; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; import net.minecraft.util.StringRepresentable; public enum StructureControllerMode implements StringRepresentable { SAVE, LOAD; - public Component textInfo() { + public MutableComponent textInfo() { return Component.translatable("structure_block.mode_info." + this.getSerializedName()); } - public Component text() { + public MutableComponent text() { return Component.translatable("structure_block.mode." + this.getSerializedName()); } diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlockEntity.java index d8b03c63a..0d8d36f4c 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlockEntity.java @@ -55,6 +55,7 @@ public class StructureMultiblockControllerBlockEntity extends FastBlockEntity im private boolean includeBlockEntities; private List ignoreNBTPositions = List.of(); + private List weakNBTPositions = List.of(); public StructureMultiblockControllerBlockEntity(BlockPos pos, BlockState state) { super(MIRegistries.STRUCTURE_MULTIBLOCK_CONTROLLER_BE.get(), pos, state); @@ -117,7 +118,16 @@ public List getIgnoreNBTPositions() { public void setIgnoreNBTPositions(List ignoreNBTPositions) { Objects.requireNonNull(ignoreNBTPositions); - this.ignoreNBTPositions = ignoreNBTPositions; + this.ignoreNBTPositions = new ArrayList<>(ignoreNBTPositions); + } + + public List getWeakNBTPositions() { + return weakNBTPositions; + } + + public void setWeakNBTPositions(List weakNBTPositions) { + Objects.requireNonNull(weakNBTPositions); + this.weakNBTPositions = new ArrayList<>(weakNBTPositions); } @Override @@ -161,11 +171,13 @@ protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) tag.putBoolean("show_bounds", showBounds); tag.putBoolean("include_block_entities", includeBlockEntities); NbtHelper.putBlockPosList(tag, "ignore_nbt_positions", ignoreNBTPositions); + NbtHelper.putBlockPosList(tag, "weak_nbt_positions", weakNBTPositions); } @Override protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { super.loadAdditional(tag, registries); + mode = StructureControllerMode.valueOf(tag.getString("mode").toUpperCase(Locale.ROOT)); this.setInputId(tag.getString("structure_id")); if (tag.contains("bounds", Tag.TAG_COMPOUND)) { @@ -180,9 +192,15 @@ protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) } showBounds = tag.getBoolean("show_bounds"); includeBlockEntities = tag.getBoolean("include_block_entities"); + List ignoreNBTPositions = new ArrayList<>(); NbtHelper.getBlockPosList(tag, "ignore_nbt_positions", ignoreNBTPositions); this.ignoreNBTPositions = ignoreNBTPositions; + + List weakNBTPositions = new ArrayList<>(); + NbtHelper.getBlockPosList(tag, "weak_nbt_positions", weakNBTPositions); + this.weakNBTPositions = weakNBTPositions; + this.updateBlockState(); } diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlockEntity.java b/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlockEntity.java index 318b2cdb4..4e7d8be8b 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlockEntity.java @@ -30,7 +30,9 @@ import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.HatchFlags; import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockInputFormatters; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureNBTMode; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; +import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMemberEntry; import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StructureMemberTest; import java.util.List; import java.util.Locale; @@ -53,8 +55,9 @@ public class StructureMultiblockMemberBlockEntity extends FastBlockEntity implem private String inputCasing; private String inputHatchFlags; - private BlockState preview; + private StructureMemberEntry preview; private List members; + private StructureNBTMode nbtMode = StructureNBTMode.WEAK; private MachineCasing casing; private HatchFlags hatchFlags = HatchFlags.NO_HATCH; @@ -92,7 +95,7 @@ public void setInputPreview(String inputPreview) { } @Nullable - public BlockState getPreview() { + public StructureMemberEntry getPreview() { return preview; } @@ -111,6 +114,15 @@ public List getMembers() { return members; } + public StructureNBTMode getNBTMode() { + return nbtMode; + } + + public void setNBTMode(StructureNBTMode nbtMode) { + Objects.requireNonNull(nbtMode); + this.nbtMode = nbtMode; + } + @Nullable public String getInputCasing() { return inputCasing; @@ -144,8 +156,8 @@ public HatchFlags getHatchFlags() { @Override public StructureMember getMemberOverride() { return switch (getMode()) { - case HATCH -> StructureMember.hatch(() -> preview, members, casing, hatchFlags); - case SIMPLE -> StructureMember.simple(() -> preview, members); + case HATCH -> StructureMember.hatch(preview, members, nbtMode, casing, hatchFlags); + case SIMPLE -> StructureMember.simple(preview, members, nbtMode); case VARIABLE -> StructureMember.variable(inputName); }; } @@ -185,6 +197,7 @@ protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) if (inputPreview != null) { tag.putString("preview", inputPreview); } + tag.putString("nbt_mode", StructureMultiblockInputFormatters.nbtMode(nbtMode)); if (inputMembers != null) { tag.putString("members", inputMembers); } @@ -203,6 +216,7 @@ protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) this.setInputName(tag.getString("name")); this.setInputPreview(tag.getString("preview")); this.setInputMembers(tag.getString("members")); + nbtMode = StructureMultiblockInputFormatters.nbtMode(tag.getString("nbt_mode"), StructureNBTMode.WEAK); this.setInputCasing(tag.getString("casing")); this.setInputHatchFlags(tag.getString("hatch_flags")); this.updateBlockState(); diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlockItem.java b/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlockItem.java index e73f84086..0a31938c0 100644 --- a/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlockItem.java +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/member/StructureMultiblockMemberBlockItem.java @@ -27,6 +27,8 @@ import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.HatchFlags; import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockInputFormatters; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureNBTMode; +import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMemberEntry; import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StructureMemberTest; import java.util.List; import java.util.Locale; @@ -37,7 +39,6 @@ import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; public class StructureMultiblockMemberBlockItem extends BlockItem { public StructureMultiblockMemberBlockItem(Block block, Properties properties) { @@ -72,16 +73,17 @@ public Optional getTooltipImage(ItemStack stack) { var name = beTag.getString("name"); var preview = StructureMultiblockInputFormatters.preview(beTag.getString("preview")); var members = StructureMultiblockInputFormatters.members(beTag.getString("members")); + var nbtMode = StructureMultiblockInputFormatters.nbtMode(beTag.getString("nbt_mode"), StructureNBTMode.WEAK); var casing = StructureMultiblockInputFormatters.casing(beTag.getString("casing")); var hatchFlags = StructureMultiblockInputFormatters.hatchFlags(beTag.getString("hatch_flags")); - return Optional.of(new TooltipData(mode, name, preview, members, casing, hatchFlags)); + return Optional.of(new TooltipData(mode, name, preview, members, nbtMode, casing, hatchFlags)); } return Optional.empty(); } - public record TooltipData(StructureMemberMode mode, String name, BlockState preview, List members, MachineCasing casing, - HatchFlags hatchFlags) implements TooltipComponent { + public record TooltipData(StructureMemberMode mode, String name, StructureMemberEntry preview, List members, + StructureNBTMode nbtMode, MachineCasing casing, HatchFlags hatchFlags) implements TooltipComponent { } } diff --git a/src/main/java/aztech/modern_industrialization/items/structure/StructureMultiblockWrenchItem.java b/src/main/java/aztech/modern_industrialization/items/structure/StructureMultiblockWrenchItem.java index 94b5e6716..b863125d0 100644 --- a/src/main/java/aztech/modern_industrialization/items/structure/StructureMultiblockWrenchItem.java +++ b/src/main/java/aztech/modern_industrialization/items/structure/StructureMultiblockWrenchItem.java @@ -25,8 +25,10 @@ import aztech.modern_industrialization.MIComponents; import aztech.modern_industrialization.MIText; +import aztech.modern_industrialization.MITooltips; import aztech.modern_industrialization.blocks.structure.controller.StructureMultiblockControllerBlockEntity; import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlockEntity; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureNBTMode; import java.util.List; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; @@ -47,6 +49,7 @@ public StructureMultiblockWrenchItem(Properties properties) { super(properties .stacksTo(1) .rarity(Rarity.EPIC) + .component(MIComponents.STRUCTURE_WRENCH_MODE, StructureNBTMode.IGNORE) .component(MIComponents.STRUCTURE_WRENCH_SELECTION, StructureWrenchSelection.EMPTY)); } @@ -64,19 +67,33 @@ public InteractionResult onItemUseFirst(ItemStack ignored, UseOnContext context) boolean isStructureBlock = blockEntity instanceof StructureMultiblockControllerBlockEntity || blockEntity instanceof StructureMultiblockMemberBlockEntity; if (isStructureBlock) { - if (isShiftKeyDown && blockEntity instanceof StructureMultiblockControllerBlockEntity controller) { - if (!isClientSide) { - var selection = stack.get(MIComponents.STRUCTURE_WRENCH_SELECTION); - controller.setIgnoreNBTPositions(selection.positions()); - controller.sync(); - controller.setChanged(); - player.displayClientMessage(MIText.StructureMultiblockWrenchApplied.text(), true); + if (blockEntity instanceof StructureMultiblockControllerBlockEntity controller) { + if (isShiftKeyDown) { + if (!isClientSide) { + var mode = stack.getOrDefault(MIComponents.STRUCTURE_WRENCH_MODE, StructureNBTMode.IGNORE); + var selection = stack.getOrDefault(MIComponents.STRUCTURE_WRENCH_SELECTION, StructureWrenchSelection.EMPTY); + var positions = selection.positions(); + if (mode == StructureNBTMode.IGNORE) { + controller.getWeakNBTPositions().removeAll(positions); + controller.setIgnoreNBTPositions(positions); + } else if (mode == StructureNBTMode.WEAK) { + controller.getIgnoreNBTPositions().removeAll(positions); + controller.setWeakNBTPositions(selection.positions()); + } else { + return InteractionResult.sidedSuccess(isClientSide); + } + controller.sync(); + controller.setChanged(); + player.displayClientMessage(MIText.StructureMultiblockWrenchApplied.text(), true); + } + } else { + // TODO SWEDZ: load the controller settings for this wrench's mode into the wrench } return InteractionResult.sidedSuccess(isClientSide); } } else if (!isShiftKeyDown) { if (!isClientSide) { - var selection = stack.get(MIComponents.STRUCTURE_WRENCH_SELECTION); + var selection = stack.getOrDefault(MIComponents.STRUCTURE_WRENCH_SELECTION, StructureWrenchSelection.EMPTY); BlockPos pos = blockEntity.getBlockPos(); if (selection.contains(pos)) { selection = selection.remove(pos); @@ -95,16 +112,25 @@ public InteractionResult onItemUseFirst(ItemStack ignored, UseOnContext context) @Override public InteractionResultHolder use(Level level, Player player, InteractionHand usedHand) { + ItemStack stack = player.getItemInHand(usedHand); if (player.isShiftKeyDown()) { - player.getItemInHand(usedHand).set(MIComponents.STRUCTURE_WRENCH_SELECTION, StructureWrenchSelection.EMPTY); + stack.set(MIComponents.STRUCTURE_WRENCH_SELECTION, StructureWrenchSelection.EMPTY); player.displayClientMessage(MIText.StructureMultiblockWrenchCleared.text(), true); - return InteractionResultHolder.sidedSuccess(player.getItemInHand(usedHand), level.isClientSide()); + } else { + StructureNBTMode currentMode = stack.getOrDefault(MIComponents.STRUCTURE_WRENCH_MODE, StructureNBTMode.IGNORE); + StructureNBTMode newMode = currentMode == StructureNBTMode.IGNORE ? StructureNBTMode.WEAK : StructureNBTMode.IGNORE; + stack.set(MIComponents.STRUCTURE_WRENCH_MODE, newMode); + player.displayClientMessage(MIText.StructureMultiblockWrenchChangedMode.text(newMode.textTooltip()), true); } - return super.use(level, player, usedHand); + return InteractionResultHolder.sidedSuccess(player.getItemInHand(usedHand), level.isClientSide()); } @Override public void appendHoverText(ItemStack stack, TooltipContext context, List tooltipComponents, TooltipFlag isAdvanced) { + var nbtMode = stack.getOrDefault(MIComponents.STRUCTURE_WRENCH_MODE, StructureNBTMode.IGNORE); + tooltipComponents.add(MIText.StructureMultiblockNBTMode.text(nbtMode.textTooltip().withStyle(MITooltips.HIGHLIGHT_STYLE)) + .withStyle(MITooltips.DEFAULT_STYLE)); + var selection = stack.get(MIComponents.STRUCTURE_WRENCH_SELECTION); if (selection != null && !selection.positions().isEmpty()) { tooltipComponents.add(MIText.StructureMultiblockWrenchTooltip.text(selection.positions().size())); diff --git a/src/main/java/aztech/modern_industrialization/items/structure/StructureWrenchSelection.java b/src/main/java/aztech/modern_industrialization/items/structure/StructureWrenchSelection.java index 0c344fcad..e83d6acc6 100644 --- a/src/main/java/aztech/modern_industrialization/items/structure/StructureWrenchSelection.java +++ b/src/main/java/aztech/modern_industrialization/items/structure/StructureWrenchSelection.java @@ -24,7 +24,6 @@ package aztech.modern_industrialization.items.structure; import com.mojang.serialization.Codec; -import com.mojang.serialization.codecs.RecordCodecBuilder; import io.netty.buffer.ByteBuf; import java.util.ArrayList; import java.util.Collections; @@ -36,9 +35,8 @@ public record StructureWrenchSelection(List positions) { public static final StructureWrenchSelection EMPTY = new StructureWrenchSelection(List.of()); - public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance - .group(Codec.list(BlockPos.CODEC).fieldOf("positions").forGetter(StructureWrenchSelection::positions)) - .apply(instance, StructureWrenchSelection::new)); + public static final Codec CODEC = Codec.list(BlockPos.CODEC).xmap(StructureWrenchSelection::new, + StructureWrenchSelection::positions); public static final StreamCodec STREAM_CODEC = StreamCodec.composite( BlockPos.STREAM_CODEC.apply(ByteBufCodecs.list()), @@ -49,10 +47,6 @@ public record StructureWrenchSelection(List positions) { positions = Collections.unmodifiableList(positions); } - public static StructureWrenchSelection of(List positions) { - return positions.isEmpty() ? EMPTY : new StructureWrenchSelection(positions); - } - public boolean contains(BlockPos pos) { return positions.contains(pos); } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java index ce4155548..d7aa02cfb 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java @@ -27,7 +27,7 @@ import aztech.modern_industrialization.machines.components.ShapeValidComponent; import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.structure.member.HatchStructureMember; -import aztech.modern_industrialization.machines.multiblocks.structure.member.LiteralStructureMember; +import aztech.modern_industrialization.machines.multiblocks.structure.member.SimpleStructureMember; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; import aztech.modern_industrialization.machines.multiblocks.world.ChunkEventListener; import aztech.modern_industrialization.machines.multiblocks.world.ChunkEventListeners; @@ -289,8 +289,8 @@ public int buildMultiblock(Level level, boolean structureBlocks) { be.sync(); setBlocks++; continue; - } else if (member instanceof LiteralStructureMember literalMember) { - nbt = literalMember.nbt(); + } else if (member instanceof SimpleStructureMember simpleMember) { + nbt = simpleMember.preview().nbt(); } } var currentState = level.getBlockState(pos); diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java index 7b452fd96..5784870e6 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java @@ -103,13 +103,14 @@ public static CompoundTag maybeTag(@Nullable BlockEntity blockEntity) { public static StructureResult fromWorld(ResourceLocation id, Level level, BlockPos controllerPos, Direction controllerDirection, StructureControllerBounds bounds, boolean includeBlockEntities, - List ignoreNBTPositions) { + List ignoreNBTPositions, List weakNBTPositions) { Objects.requireNonNull(id); Objects.requireNonNull(level); Objects.requireNonNull(controllerPos); Objects.requireNonNull(controllerDirection); Objects.requireNonNull(bounds); Objects.requireNonNull(ignoreNBTPositions); + Objects.requireNonNull(weakNBTPositions); if (bounds.isEmpty()) { return new StructureResult.InvalidBounds(); } @@ -131,8 +132,12 @@ public static StructureResult fromWorld(ResourceLocation id, Level level, } BlockEntity blockEntity = level.getBlockEntity(pos); - StructureMember member = StructureMember.literal(() -> state, - includeBlockEntities && !ignoreNBTPositions.contains(pos) ? blockEntity : null); + boolean isIgnoreNBT = ignoreNBTPositions.contains(pos); + boolean isWeakNBT = weakNBTPositions.contains(pos); + StructureNBTMode nbtMode = !includeBlockEntities || isIgnoreNBT ? StructureNBTMode.IGNORE + : isWeakNBT ? StructureNBTMode.WEAK : StructureNBTMode.STRONG; + + StructureMember member = StructureMember.literal(state, includeBlockEntities && !isIgnoreNBT ? blockEntity : null, nbtMode); if (blockEntity instanceof StructureMemberOverride override) { if (!override.isConfigurationValid()) { diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockInputFormatters.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockInputFormatters.java index e3df28a83..d630855d3 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockInputFormatters.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureMultiblockInputFormatters.java @@ -28,6 +28,7 @@ import aztech.modern_industrialization.machines.models.MachineCasings; import aztech.modern_industrialization.machines.multiblocks.HatchFlags; import aztech.modern_industrialization.machines.multiblocks.HatchType; +import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMemberEntry; import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StateStructureMemberTest; import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StructureMemberTest; import aztech.modern_industrialization.machines.multiblocks.structure.member.test.TagStructureMemberTest; @@ -37,11 +38,11 @@ import java.util.Locale; import net.minecraft.commands.arguments.blocks.BlockStateParser; import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.BlockTags; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; -import net.neoforged.neoforge.common.util.Lazy; import org.jetbrains.annotations.Nullable; public final class StructureMultiblockInputFormatters { @@ -88,26 +89,37 @@ public static String casing(MachineCasing casing) { } @Nullable - public static BlockState preview(String input) { + public static StructureMemberEntry preview(String input) { if (input == null || input.isEmpty()) { - return Blocks.AIR.defaultBlockState(); + return new StructureMemberEntry(Blocks.AIR.defaultBlockState()); } var registry = BuiltInRegistries.BLOCK.asLookup(); try { var blockResult = BlockStateParser.parseForBlock(registry, input, true); - return blockResult.blockState(); + return new StructureMemberEntry(blockResult); } catch (CommandSyntaxException ignored) { return null; } } - @Nullable - public static String preview(BlockState preview) { - if (preview == null) { + private static String toString(StructureMemberEntry entry) { + if (entry == null) { return null; } - return BlockStateParser.serialize(preview); + BlockState state = entry.state().get(); + String stateString = BlockStateParser.serialize(state); + CompoundTag nbt = entry.nbt(); + String nbtString = nbt == null ? "" : nbt.toString(); + if (state == state.getBlock().defaultBlockState()) { + stateString = state.getBlockHolder().unwrapKey().map(key -> key.location().toString()).orElse("air"); + } + return stateString + nbtString; + } + + @Nullable + public static String preview(StructureMemberEntry preview) { + return toString(preview); } @Nullable @@ -129,7 +141,7 @@ public static List members(String input) { } else { try { var blockResult = BlockStateParser.parseForBlock(registry, part, true); - members.add(new StateStructureMemberTest(Lazy.of(blockResult::blockState))); + members.add(new StateStructureMemberTest(new StructureMemberEntry(blockResult))); } catch (CommandSyntaxException ignored) { return null; } @@ -155,12 +167,27 @@ public static String members(List members) { if (!string.isEmpty()) { string.append(";"); } - string.append(BlockStateParser.serialize(stateTest.blockState())); + string.append(toString(stateTest.entry())); } } return string.toString(); } + public static StructureNBTMode nbtMode(String input, StructureNBTMode fallback) { + if (input == null || input.isEmpty()) { + return fallback; + } + try { + return StructureNBTMode.valueOf(input.toUpperCase(Locale.ROOT)); + } catch (IllegalArgumentException ex) { + return fallback; + } + } + + public static String nbtMode(StructureNBTMode nbtMode) { + return nbtMode.getSerializedName(); + } + @Nullable public static HatchFlags hatchFlags(String input) { if (input == null || input.isEmpty()) { diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureNBTMode.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureNBTMode.java new file mode 100644 index 000000000..8c8dd29dc --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/StructureNBTMode.java @@ -0,0 +1,77 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.machines.multiblocks.structure; + +import aztech.modern_industrialization.MIText; +import com.mojang.serialization.Codec; +import io.netty.buffer.ByteBuf; +import java.util.Locale; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.util.StringRepresentable; + +public enum StructureNBTMode implements StringRepresentable { + STRONG(MIText.StructureMultiblockGuiNBTModeStrong, MIText.StructureMultiblockWrenchNBTModeStrong), + WEAK(MIText.StructureMultiblockGuiNBTModeWeak, MIText.StructureMultiblockWrenchNBTModeWeak), + IGNORE(null, MIText.StructureMultiblockWrenchNBTModeIgnore); + + public static final Codec CODEC = Codec.STRING.xmap(name -> StructureNBTMode.valueOf(name.toUpperCase(Locale.ROOT)), + mode -> mode.toString().toLowerCase(Locale.ROOT)); + + public static final StreamCodec STREAM_CODEC = ByteBufCodecs.STRING_UTF8 + .map(name -> StructureNBTMode.valueOf(name.toUpperCase(Locale.ROOT)), mode -> mode.toString().toLowerCase(Locale.ROOT)); + + private final MIText textGui, textTooltip; + + StructureNBTMode(MIText textGui, MIText textTooltip) { + this.textGui = textGui; + this.textTooltip = textTooltip; + } + + public boolean isStrong() { + return this == STRONG; + } + + public boolean isWeak() { + return this == WEAK; + } + + public boolean isIgnore() { + return this == IGNORE; + } + + public MutableComponent textGui() { + return textGui.text(); + } + + public MutableComponent textTooltip() { + return textTooltip.text(); + } + + @Override + public String getSerializedName() { + return this.name().toLowerCase(Locale.ROOT); + } +} diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java index aaf07cf76..c54212a4d 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java @@ -30,8 +30,8 @@ import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.HatchFlags; import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockInputFormatters; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureNBTMode; import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StructureMemberTest; -import aztech.modern_industrialization.util.MIExtraCodecs; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; @@ -40,22 +40,25 @@ import java.util.Optional; import net.minecraft.core.BlockPos; import net.minecraft.world.level.block.state.BlockState; -import net.neoforged.neoforge.common.util.Lazy; public final class HatchStructureMember extends SimpleStructureMember { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance .group( - MIExtraCodecs.LAZY_BLOCK_STATE.fieldOf("preview").forGetter(member -> member.preview), + StructureMemberEntry.CODEC.fieldOf("preview").forGetter(member -> member.preview), StructureMemberTest.CODEC.listOf().fieldOf("tests").forGetter(HatchStructureMember::tests), + StructureNBTMode.CODEC.optionalFieldOf("nbt_mode") + .forGetter(member -> member.nbtMode() != StructureNBTMode.WEAK ? Optional.of(member.nbtMode()) : Optional.empty()), MachineCasing.CODEC.fieldOf("casing").forGetter(HatchStructureMember::casing), HatchFlags.CODEC.fieldOf("hatch_flags").forGetter(HatchStructureMember::hatchFlags)) - .apply(instance, HatchStructureMember::new)); + .apply(instance, (preview, tests, nbtMode, casing, hatchFlags) -> new HatchStructureMember(preview, tests, + nbtMode.orElse(StructureNBTMode.WEAK), casing, hatchFlags))); private final MachineCasing casing; private final HatchFlags hatchFlags; - public HatchStructureMember(Lazy previewSupplier, List tests, MachineCasing casing, HatchFlags hatchFlags) { - super(previewSupplier, tests); + public HatchStructureMember(StructureMemberEntry preview, List tests, StructureNBTMode nbtMode, MachineCasing casing, + HatchFlags hatchFlags) { + super(preview, tests, nbtMode); Objects.requireNonNull(casing); Objects.requireNonNull(hatchFlags); this.casing = casing; @@ -81,7 +84,7 @@ public Optional> asStructureBlock(BlockPos pos var state = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.asBlock().defaultBlockState(); state = state.setValue(StructureMultiblockMemberBlock.MODE, StructureMemberMode.HATCH); var be = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.get().newBlockEntity(pos, state); - be.setInputPreview(StructureMultiblockInputFormatters.preview(getPreviewState())); + be.setInputPreview(StructureMultiblockInputFormatters.preview(preview)); be.setInputMembers(StructureMultiblockInputFormatters.members(tests)); be.setInputCasing(StructureMultiblockInputFormatters.casing(casing)); be.setInputHatchFlags(StructureMultiblockInputFormatters.hatchFlags(hatchFlags)); @@ -94,7 +97,7 @@ public Optional> asStructureBlock(BlockPos pos @Override public boolean equals(Object o) { if (o instanceof HatchStructureMember other && this.getClass() == other.getClass()) { - return this.getPreviewState() == other.getPreviewState() && + return preview.equals(other.preview) && tests.containsAll(other.tests) && other.tests.containsAll(tests) && casing.equals(other.casing) && hatchFlags.equals(other.hatchFlags); diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java index 4c6ce3ee0..bc64081b9 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java @@ -24,40 +24,28 @@ package aztech.modern_industrialization.machines.multiblocks.structure.member; import aztech.modern_industrialization.blocks.FastBlockEntity; -import aztech.modern_industrialization.machines.multiblocks.structure.MIStructureTemplateManager; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureNBTMode; import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StateStructureMemberTest; -import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StructureMemberTest; -import aztech.modern_industrialization.util.MIExtraCodecs; -import aztech.modern_industrialization.util.NbtHelper; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import java.util.List; import java.util.Optional; import net.minecraft.core.BlockPos; -import net.minecraft.nbt.CompoundTag; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; -import net.neoforged.neoforge.common.util.Lazy; import org.jetbrains.annotations.Nullable; public final class LiteralStructureMember extends SimpleStructureMember { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance .group( - MIExtraCodecs.LAZY_BLOCK_STATE.fieldOf("state").forGetter(member -> member.preview), - CompoundTag.CODEC.optionalFieldOf("nbt").forGetter(member -> Optional.ofNullable(member.nbt()))) - .apply(instance, (preview, nbt) -> new LiteralStructureMember(preview, nbt.orElse(null)))); + StructureMemberEntry.CODEC.fieldOf("value").forGetter(LiteralStructureMember::preview), + StructureNBTMode.CODEC.optionalFieldOf("nbt_mode") + .forGetter(member -> member.nbtMode() == StructureNBTMode.WEAK ? Optional.of(member.nbtMode()) : Optional.empty())) + .apply(instance, (value, mode) -> new LiteralStructureMember(value, mode.orElse(StructureNBTMode.STRONG)))); - private final CompoundTag nbt; - - public LiteralStructureMember(Lazy previewSupplier, @Nullable CompoundTag nbt) { - super(previewSupplier, List.of(new StateStructureMemberTest(previewSupplier))); - this.nbt = nbt; - } - - @Nullable - public CompoundTag nbt() { - return nbt != null ? nbt.copy() : null; + public LiteralStructureMember(StructureMemberEntry preview, StructureNBTMode nbtMode) { + super(preview, List.of(new StateStructureMemberTest(preview)), nbtMode); } @Override @@ -67,14 +55,7 @@ public StructureMemberType type() { @Override public boolean matchesState(BlockState state, @Nullable BlockEntity blockEntity) { - boolean noNBT = nbt == null; - CompoundTag beTag = noNBT ? null : MIStructureTemplateManager.maybeTag(blockEntity); - for (StructureMemberTest test : tests) { - if (test.matchesState(state) && (noNBT || NbtHelper.equals(nbt, beTag))) { - return true; - } - } - return false; + return tests.getFirst().matchesState(state, blockEntity, nbtMode); } @Override @@ -85,9 +66,7 @@ public Optional> asStructureBlock(BlockPos pos @Override public boolean equals(Object o) { if (o instanceof LiteralStructureMember other && this.getClass() == other.getClass()) { - return this.getPreviewState() == other.getPreviewState() && - tests.containsAll(other.tests) && other.tests.containsAll(tests) && - NbtHelper.equals(nbt, other.nbt); + return preview.equals(other.preview); } return false; } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java index 8c57d2132..96661cb38 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java @@ -28,8 +28,8 @@ import aztech.modern_industrialization.blocks.structure.member.StructureMemberMode; import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlock; import aztech.modern_industrialization.machines.multiblocks.structure.StructureMultiblockInputFormatters; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureNBTMode; import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StructureMemberTest; -import aztech.modern_industrialization.util.MIExtraCodecs; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; @@ -40,30 +40,42 @@ import net.minecraft.core.BlockPos; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; -import net.neoforged.neoforge.common.util.Lazy; import org.jetbrains.annotations.Nullable; public sealed class SimpleStructureMember extends StructureMember permits HatchStructureMember, LiteralStructureMember { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance .group( - MIExtraCodecs.LAZY_BLOCK_STATE.fieldOf("preview").forGetter(member -> member.preview), - StructureMemberTest.CODEC.listOf().fieldOf("tests").forGetter(SimpleStructureMember::tests)) - .apply(instance, SimpleStructureMember::new)); + StructureMemberEntry.CODEC.fieldOf("preview").forGetter(member -> member.preview), + StructureMemberTest.CODEC.listOf().fieldOf("tests").forGetter(SimpleStructureMember::tests), + StructureNBTMode.CODEC.optionalFieldOf("nbt_mode") + .forGetter(member -> member.nbtMode() != StructureNBTMode.WEAK ? Optional.of(member.nbtMode()) : Optional.empty())) + .apply(instance, (preview, tests, nbtMode) -> new SimpleStructureMember(preview, tests, nbtMode.orElse(StructureNBTMode.WEAK)))); - protected final Lazy preview; + protected final StructureMemberEntry preview; protected final List tests; + protected final StructureNBTMode nbtMode; - public SimpleStructureMember(Lazy preview, List tests) { + public SimpleStructureMember(StructureMemberEntry preview, List tests, StructureNBTMode nbtMode) { Objects.requireNonNull(preview); Objects.requireNonNull(tests); + Objects.requireNonNull(nbtMode); this.preview = preview; this.tests = tests; + this.nbtMode = nbtMode; + } + + public StructureMemberEntry preview() { + return preview; } public List tests() { return Collections.unmodifiableList(tests); } + public StructureNBTMode nbtMode() { + return nbtMode; + } + @Override public StructureMemberType type() { return StructureMemberType.SIMPLE; @@ -75,7 +87,7 @@ public Optional> asStructureBlock(BlockPos pos var state = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.asBlock().defaultBlockState(); state = state.setValue(StructureMultiblockMemberBlock.MODE, StructureMemberMode.SIMPLE); var be = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.get().newBlockEntity(pos, state); - be.setInputPreview(StructureMultiblockInputFormatters.preview(getPreviewState())); + be.setInputPreview(StructureMultiblockInputFormatters.preview(preview)); be.setInputMembers(StructureMultiblockInputFormatters.members(tests)); return Optional.of(Pair.of(state, be)); } @@ -86,7 +98,7 @@ public Optional> asStructureBlock(BlockPos pos @Override public boolean matchesState(BlockState state, @Nullable BlockEntity blockEntity) { for (StructureMemberTest test : tests) { - if (test.matchesState(state)) { + if (test.matchesState(state, blockEntity, nbtMode)) { return true; } } @@ -95,13 +107,13 @@ public boolean matchesState(BlockState state, @Nullable BlockEntity blockEntity) @Override public BlockState getPreviewState() { - return preview.get(); + return preview.state().get(); } @Override public boolean equals(Object o) { if (o instanceof SimpleStructureMember other && this.getClass() == other.getClass()) { - return this.getPreviewState() == other.getPreviewState() && + return preview.equals(other.preview) && tests.containsAll(other.tests) && other.tests.containsAll(tests); } return false; diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java index 2c5d7d987..5bd65d0bc 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMember.java @@ -28,13 +28,13 @@ import aztech.modern_industrialization.machines.multiblocks.HatchFlags; import aztech.modern_industrialization.machines.multiblocks.SimpleMember; import aztech.modern_industrialization.machines.multiblocks.structure.MIStructureTemplateManager; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureNBTMode; import aztech.modern_industrialization.machines.multiblocks.structure.member.test.StructureMemberTest; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; import java.util.List; import java.util.Optional; -import java.util.function.Supplier; import net.minecraft.core.BlockPos; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; @@ -50,17 +50,18 @@ public sealed abstract class StructureMember implements SimpleMember permits Sim public abstract Optional> asStructureBlock(BlockPos pos, boolean required); - public static SimpleStructureMember simple(Supplier preview, List tests) { - return new SimpleStructureMember(Lazy.of(preview), tests); + public static SimpleStructureMember simple(StructureMemberEntry preview, List tests, StructureNBTMode nbtMode) { + return new SimpleStructureMember(preview, tests, nbtMode); } - public static LiteralStructureMember literal(Supplier blockState, @Nullable BlockEntity blockEntity) { - return new LiteralStructureMember(Lazy.of(blockState), MIStructureTemplateManager.maybeTag(blockEntity)); + public static LiteralStructureMember literal(BlockState blockState, @Nullable BlockEntity blockEntity, StructureNBTMode nbtMode) { + return new LiteralStructureMember(new StructureMemberEntry(Lazy.of(() -> blockState), MIStructureTemplateManager.maybeTag(blockEntity)), + nbtMode); } - public static HatchStructureMember hatch(Supplier preview, List tests, MachineCasing casing, - HatchFlags hatchFlags) { - return new HatchStructureMember(Lazy.of(preview), tests, casing, hatchFlags); + public static HatchStructureMember hatch(StructureMemberEntry preview, List tests, StructureNBTMode nbtMode, + MachineCasing casing, HatchFlags hatchFlags) { + return new HatchStructureMember(preview, tests, nbtMode, casing, hatchFlags); } public static VariableStructureMember variable(String name) { diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberEntry.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberEntry.java new file mode 100644 index 000000000..d58348f3d --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/StructureMemberEntry.java @@ -0,0 +1,60 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.machines.multiblocks.structure.member; + +import aztech.modern_industrialization.util.MIExtraCodecs; +import aztech.modern_industrialization.util.NbtHelper; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import java.util.Optional; +import net.minecraft.commands.arguments.blocks.BlockStateParser; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.level.block.state.BlockState; +import net.neoforged.neoforge.common.util.Lazy; +import org.jetbrains.annotations.Nullable; + +public record StructureMemberEntry(Lazy state, @Nullable CompoundTag nbt) { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance + .group( + MIExtraCodecs.LAZY_BLOCK_STATE.fieldOf("state").forGetter(StructureMemberEntry::state), + CompoundTag.CODEC.optionalFieldOf("nbt").forGetter(entry -> Optional.ofNullable(entry.nbt()))) + .apply(instance, (state, nbt) -> new StructureMemberEntry(state, nbt.orElse(null)))); + + public StructureMemberEntry(BlockState state) { + this(Lazy.of(() -> state), null); + } + + public StructureMemberEntry(BlockStateParser.BlockResult result) { + this(Lazy.of(result::blockState), result.nbt()); + } + + @Override + public boolean equals(Object o) { + if (o instanceof StructureMemberEntry other) { + return state == other.state && + NbtHelper.equals(nbt, other.nbt); + } + return false; + } +} diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StateStructureMemberTest.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StateStructureMemberTest.java index a5d7944f8..29c44caed 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StateStructureMemberTest.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StateStructureMemberTest.java @@ -23,28 +23,38 @@ */ package aztech.modern_industrialization.machines.multiblocks.structure.member.test; -import aztech.modern_industrialization.util.MIExtraCodecs; +import aztech.modern_industrialization.machines.multiblocks.structure.MIStructureTemplateManager; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureNBTMode; +import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMemberEntry; +import aztech.modern_industrialization.util.NbtHelper; import com.mojang.serialization.MapCodec; -import com.mojang.serialization.codecs.RecordCodecBuilder; import java.util.Objects; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; -import net.neoforged.neoforge.common.util.Lazy; +import org.jetbrains.annotations.Nullable; public final class StateStructureMemberTest extends StructureMemberTest { - public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance - .group( - MIExtraCodecs.LAZY_BLOCK_STATE.fieldOf("state").forGetter(test -> test.blockState)) - .apply(instance, StateStructureMemberTest::new)); + public static final MapCodec CODEC = StructureMemberEntry.CODEC + .xmap(StateStructureMemberTest::new, StateStructureMemberTest::entry).fieldOf("value"); - private final Lazy blockState; + private final StructureMemberEntry entry; - public StateStructureMemberTest(Lazy blockState) { - Objects.requireNonNull(blockState); - this.blockState = blockState; + public StateStructureMemberTest(StructureMemberEntry entry) { + Objects.requireNonNull(entry); + this.entry = entry; + } + + public StructureMemberEntry entry() { + return entry; } public BlockState blockState() { - return blockState.get(); + return entry.state().get(); + } + + public CompoundTag nbt() { + return entry.nbt() != null ? entry.nbt().copy() : null; } @Override @@ -53,14 +63,17 @@ public StructureMemberTestType type() { } @Override - public boolean matchesState(BlockState state) { - return this.blockState() == state; + public boolean matchesState(BlockState state, @Nullable BlockEntity blockEntity, StructureNBTMode mode) { + CompoundTag nbt = entry.nbt(); + CompoundTag beNbt = MIStructureTemplateManager.maybeTag(blockEntity); + return this.blockState() == state + && (nbt == null || mode.isIgnore() || (mode.isStrong() ? NbtHelper.equals(nbt, beNbt) : NbtHelper.compare(nbt, beNbt))); } @Override public boolean equals(Object o) { if (o instanceof StateStructureMemberTest other) { - return this.blockState() == other.blockState(); + return entry.equals(other.entry); } return false; } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StructureMemberTest.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StructureMemberTest.java index d18e4e49d..ce05127a2 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StructureMemberTest.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/StructureMemberTest.java @@ -23,9 +23,12 @@ */ package aztech.modern_industrialization.machines.multiblocks.structure.member.test; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureNBTMode; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; +import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; public sealed abstract class StructureMemberTest permits StateStructureMemberTest, TagStructureMemberTest { public static final Codec CODEC = Codec.STRING.flatComapMap( @@ -34,5 +37,5 @@ public sealed abstract class StructureMemberTest permits StateStructureMemberTes public abstract StructureMemberTestType type(); - public abstract boolean matchesState(BlockState state); + public abstract boolean matchesState(BlockState state, @Nullable BlockEntity blockEntity, StructureNBTMode mode); } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/TagStructureMemberTest.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/TagStructureMemberTest.java index 3a4fe2e20..15396cca4 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/TagStructureMemberTest.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/test/TagStructureMemberTest.java @@ -23,19 +23,19 @@ */ package aztech.modern_industrialization.machines.multiblocks.structure.member.test; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureNBTMode; import com.mojang.serialization.MapCodec; -import com.mojang.serialization.codecs.RecordCodecBuilder; import java.util.Objects; import net.minecraft.core.registries.Registries; import net.minecraft.tags.TagKey; import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; public final class TagStructureMemberTest extends StructureMemberTest { - public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance - .group( - TagKey.codec(Registries.BLOCK).fieldOf("tag").forGetter(TagStructureMemberTest::blockTag)) - .apply(instance, TagStructureMemberTest::new)); + public static final MapCodec CODEC = TagKey.codec(Registries.BLOCK) + .xmap(TagStructureMemberTest::new, TagStructureMemberTest::blockTag).fieldOf("tag"); private final TagKey blockTag; @@ -54,7 +54,7 @@ public StructureMemberTestType type() { } @Override - public boolean matchesState(BlockState state) { + public boolean matchesState(BlockState state, @Nullable BlockEntity blockEntity, StructureNBTMode mode) { return state.is(blockTag); } diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java index 620376fc4..59daffbcb 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureSaveControllerPacket.java @@ -61,7 +61,8 @@ public void handle(Context ctx) { ResourceLocation id = controller.getId(); var result = MIStructureTemplateManager.fromWorld(id, level, pos, state.getValue(StructureMultiblockControllerBlock.FACING), - controller.getBounds(), controller.includeBlockEntities(), controller.getIgnoreNBTPositions()); + controller.getBounds(), controller.includeBlockEntities(), controller.getIgnoreNBTPositions(), + controller.getWeakNBTPositions()); if (result instanceof StructureResult.Success success) { if (MIStructureTemplateManager.save(id, success.template())) { MIStructureTemplateManager.register(id, success.template()); diff --git a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java index f9c791aef..5bb4033a5 100644 --- a/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java +++ b/src/main/java/aztech/modern_industrialization/network/structure/StructureUpdateMemberPacket.java @@ -25,7 +25,9 @@ import aztech.modern_industrialization.blocks.structure.member.StructureMemberMode; import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlockEntity; +import aztech.modern_industrialization.machines.multiblocks.structure.StructureNBTMode; import aztech.modern_industrialization.network.BasePacket; +import aztech.modern_industrialization.util.MIExtraCodecs; import io.netty.buffer.ByteBuf; import net.minecraft.core.BlockPos; import net.minecraft.network.codec.ByteBufCodecs; @@ -34,14 +36,11 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; -import net.neoforged.neoforge.network.codec.NeoForgeStreamCodecs; public record StructureUpdateMemberPacket(BlockPos pos, StructureMemberMode mode, String inputName, String inputPreview, String inputMembers, - String inputCasing, - String inputFlags) - implements BasePacket { + StructureNBTMode nbtMode, String inputCasing, String inputFlags) implements BasePacket { - public static final StreamCodec STREAM_CODEC = NeoForgeStreamCodecs.composite( + public static final StreamCodec STREAM_CODEC = MIExtraCodecs.composite( BlockPos.STREAM_CODEC, StructureUpdateMemberPacket::pos, ByteBufCodecs.idMapper((i) -> StructureMemberMode.values()[i], Enum::ordinal), @@ -52,6 +51,8 @@ public record StructureUpdateMemberPacket(BlockPos pos, StructureMemberMode mode StructureUpdateMemberPacket::inputPreview, ByteBufCodecs.STRING_UTF8, StructureUpdateMemberPacket::inputMembers, + StructureNBTMode.STREAM_CODEC, + StructureUpdateMemberPacket::nbtMode, ByteBufCodecs.STRING_UTF8, StructureUpdateMemberPacket::inputCasing, ByteBufCodecs.STRING_UTF8, @@ -75,6 +76,7 @@ public void handle(Context ctx) { member.setInputName(inputName); member.setInputPreview(inputPreview); member.setInputMembers(inputMembers); + member.setNBTMode(nbtMode); member.setInputCasing(inputCasing); member.setInputHatchFlags(inputFlags); diff --git a/src/main/java/aztech/modern_industrialization/util/MIExtraCodecs.java b/src/main/java/aztech/modern_industrialization/util/MIExtraCodecs.java index d4167ee1d..d5ba00de2 100644 --- a/src/main/java/aztech/modern_industrialization/util/MIExtraCodecs.java +++ b/src/main/java/aztech/modern_industrialization/util/MIExtraCodecs.java @@ -24,6 +24,7 @@ package aztech.modern_industrialization.util; import com.mojang.datafixers.util.Either; +import com.mojang.datafixers.util.Function8; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; @@ -32,6 +33,7 @@ import java.util.List; import java.util.Optional; import java.util.function.Function; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.world.level.block.state.BlockState; import net.neoforged.neoforge.common.conditions.ConditionalOps; import net.neoforged.neoforge.common.util.Lazy; @@ -91,4 +93,40 @@ public DataResult encode(Lazy input, DynamicOps ops, T prefix) { } }; } + + public static StreamCodec composite( + final StreamCodec codec1, final Function getter1, + final StreamCodec codec2, final Function getter2, + final StreamCodec codec3, final Function getter3, + final StreamCodec codec4, final Function getter4, + final StreamCodec codec5, final Function getter5, + final StreamCodec codec6, final Function getter6, + final StreamCodec codec7, final Function getter7, + final StreamCodec codec8, final Function getter8, + final Function8 function) { + return new StreamCodec<>() { + public C decode(B buf) { + T1 t1 = codec1.decode(buf); + T2 t2 = codec2.decode(buf); + T3 t3 = codec3.decode(buf); + T4 t4 = codec4.decode(buf); + T5 t5 = codec5.decode(buf); + T6 t6 = codec6.decode(buf); + T7 t7 = codec7.decode(buf); + T8 t8 = codec8.decode(buf); + return function.apply(t1, t2, t3, t4, t5, t6, t7, t8); + } + + public void encode(B buf, C value) { + codec1.encode(buf, getter1.apply(value)); + codec2.encode(buf, getter2.apply(value)); + codec3.encode(buf, getter3.apply(value)); + codec4.encode(buf, getter4.apply(value)); + codec5.encode(buf, getter5.apply(value)); + codec6.encode(buf, getter6.apply(value)); + codec7.encode(buf, getter7.apply(value)); + codec8.encode(buf, getter8.apply(value)); + } + }; + } } diff --git a/src/main/java/aztech/modern_industrialization/util/NbtHelper.java b/src/main/java/aztech/modern_industrialization/util/NbtHelper.java index 72614bdae..59de44f76 100644 --- a/src/main/java/aztech/modern_industrialization/util/NbtHelper.java +++ b/src/main/java/aztech/modern_industrialization/util/NbtHelper.java @@ -174,6 +174,16 @@ public static void putNonzeroInt(CompoundTag tag, String key, int i) { } } + public static boolean numericEquals(NumericTag a, NumericTag b) { + if (a instanceof DoubleTag || a instanceof FloatTag || b instanceof DoubleTag || b instanceof FloatTag) { + return a.getAsDouble() == b.getAsDouble(); + } else if (a instanceof LongTag || b instanceof LongTag) { + return a.getAsLong() == b.getAsLong(); + } else { + return a.getAsInt() == b.getAsInt(); + } + } + /** * A more reasonable version of NbtUtils#compareNbt that compares numeric tags without requiring they be of the same type. */ @@ -222,13 +232,59 @@ public static boolean equals(@Nullable Tag a, @Nullable Tag b) { } case NumericTag tagA -> { if (b instanceof NumericTag tagB) { - if (a instanceof DoubleTag || a instanceof FloatTag || b instanceof DoubleTag || b instanceof FloatTag) { - yield tagA.getAsDouble() == tagB.getAsDouble(); - } else if (a instanceof LongTag || b instanceof LongTag) { - yield tagA.getAsLong() == tagB.getAsLong(); - } else { - yield tagA.getAsInt() == tagB.getAsInt(); + yield numericEquals(tagA, tagB); + } + yield false; + } + default -> a.equals(b); + }; + } + + /** + * Similar to NbtHelper#equals, but only checks that b has all of the values of a, rather than they are equal. + */ + public static boolean compare(@Nullable Tag a, @Nullable Tag b) { + if (a == b) { + return true; + } + if (a == null || b == null) { + return false; + } + return switch (a) { + case CompoundTag tagA -> { + if (b instanceof CompoundTag tagB) { + for (String key : tagA.getAllKeys()) { + Tag valueA = tagA.get(key); + Tag valueB = tagB.get(key); + if (!compare(valueA, valueB)) { + yield false; + } } + yield true; + } + yield false; + } + case ListTag tagA -> { + if (b instanceof ListTag tagB) { + for (Tag valueA : tagA) { + boolean contains = false; + for (Tag valueB : tagB) { + if (compare(valueA, valueB)) { + contains = true; + break; + } + } + if (!contains) { + yield false; + } + } + yield true; + } + yield false; + } + case NumericTag tagA -> { + if (b instanceof NumericTag tagB) { + yield numericEquals(tagA, tagB); } yield false; } diff --git a/src/main/resources/mi_structures/modern_industrialization/advanced_large_steam_boiler.json b/src/main/resources/mi_structures/modern_industrialization/advanced_large_steam_boiler.json index 0d2109bd0..8296c329f 100644 --- a/src/main/resources/mi_structures/modern_industrialization/advanced_large_steam_boiler.json +++ b/src/main/resources/mi_structures/modern_industrialization/advanced_large_steam_boiler.json @@ -355,25 +355,33 @@ ], "members": [ { - "state": { - "Name": "modern_industrialization:bronze_plated_bricks" + "value": { + "state": { + "Name": "modern_industrialization:bronze_plated_bricks" + } }, "type": "literal" }, { - "state": { - "Name": "modern_industrialization:bronze_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:bronze_machine_casing_pipe" + } }, "type": "literal" }, { "preview": { - "Name": "modern_industrialization:heatproof_machine_casing" + "state": { + "Name": "modern_industrialization:heatproof_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:heatproof_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:heatproof_machine_casing" + } }, "type": "state" } diff --git a/src/main/resources/mi_structures/modern_industrialization/coke_oven.json b/src/main/resources/mi_structures/modern_industrialization/coke_oven.json index edc3d3029..7ac5f7175 100644 --- a/src/main/resources/mi_structures/modern_industrialization/coke_oven.json +++ b/src/main/resources/mi_structures/modern_industrialization/coke_oven.json @@ -195,19 +195,25 @@ ], "members": [ { - "state": { - "Name": "minecraft:bricks" + "value": { + "state": { + "Name": "minecraft:bricks" + } }, "type": "literal" }, { "preview": { - "Name": "minecraft:bricks" + "state": { + "Name": "minecraft:bricks" + } }, "tests": [ { - "state": { - "Name": "minecraft:bricks" + "value": { + "state": { + "Name": "minecraft:bricks" + } }, "type": "state" } diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_1.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_1.json index b6b3bd206..7ad2a0441 100644 --- a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_1.json +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_1.json @@ -140,12 +140,16 @@ "members": [ { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -156,12 +160,16 @@ }, { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -171,8 +179,10 @@ "type": "hatch" }, { - "state": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "type": "literal" } diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_10.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_10.json index 90a80964f..e5f1c3527 100644 --- a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_10.json +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_10.json @@ -788,12 +788,16 @@ "members": [ { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -804,12 +808,16 @@ }, { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -819,8 +827,10 @@ "type": "hatch" }, { - "state": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "type": "literal" } diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_11.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_11.json index b4c8a917c..8220c5684 100644 --- a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_11.json +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_11.json @@ -860,12 +860,16 @@ "members": [ { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -876,12 +880,16 @@ }, { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -891,8 +899,10 @@ "type": "hatch" }, { - "state": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "type": "literal" } diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_12.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_12.json index 22cb71a96..05caf7178 100644 --- a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_12.json +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_12.json @@ -932,12 +932,16 @@ "members": [ { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -948,12 +952,16 @@ }, { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -963,8 +971,10 @@ "type": "hatch" }, { - "state": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "type": "literal" } diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_13.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_13.json index c191d191d..d08b418b5 100644 --- a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_13.json +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_13.json @@ -1004,12 +1004,16 @@ "members": [ { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -1020,12 +1024,16 @@ }, { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -1035,8 +1043,10 @@ "type": "hatch" }, { - "state": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "type": "literal" } diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_14.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_14.json index 791c0c873..cba9cb784 100644 --- a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_14.json +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_14.json @@ -1076,12 +1076,16 @@ "members": [ { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -1092,12 +1096,16 @@ }, { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -1107,8 +1115,10 @@ "type": "hatch" }, { - "state": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "type": "literal" } diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_15.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_15.json index a390b98e0..16080681d 100644 --- a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_15.json +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_15.json @@ -1148,12 +1148,16 @@ "members": [ { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -1164,12 +1168,16 @@ }, { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -1179,8 +1187,10 @@ "type": "hatch" }, { - "state": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "type": "literal" } diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_2.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_2.json index 8c9926316..da3511c98 100644 --- a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_2.json +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_2.json @@ -212,12 +212,16 @@ "members": [ { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -228,12 +232,16 @@ }, { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -243,8 +251,10 @@ "type": "hatch" }, { - "state": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "type": "literal" } diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_3.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_3.json index 195822265..38333620d 100644 --- a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_3.json +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_3.json @@ -284,12 +284,16 @@ "members": [ { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -300,12 +304,16 @@ }, { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -315,8 +323,10 @@ "type": "hatch" }, { - "state": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "type": "literal" } diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_4.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_4.json index 3a2b28b88..b936c635a 100644 --- a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_4.json +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_4.json @@ -356,12 +356,16 @@ "members": [ { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -372,12 +376,16 @@ }, { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -387,8 +395,10 @@ "type": "hatch" }, { - "state": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "type": "literal" } diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_5.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_5.json index 4e73c6e01..97b3e6dee 100644 --- a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_5.json +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_5.json @@ -428,12 +428,16 @@ "members": [ { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -444,12 +448,16 @@ }, { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -459,8 +467,10 @@ "type": "hatch" }, { - "state": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "type": "literal" } diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_6.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_6.json index 50acd3f74..d0d532ea0 100644 --- a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_6.json +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_6.json @@ -500,12 +500,16 @@ "members": [ { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -516,12 +520,16 @@ }, { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -531,8 +539,10 @@ "type": "hatch" }, { - "state": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "type": "literal" } diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_7.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_7.json index 1aea8c67f..21e656ea0 100644 --- a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_7.json +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_7.json @@ -572,12 +572,16 @@ "members": [ { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -588,12 +592,16 @@ }, { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -603,8 +611,10 @@ "type": "hatch" }, { - "state": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "type": "literal" } diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_8.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_8.json index 78ed7a38d..e6d6d0dd0 100644 --- a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_8.json +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_8.json @@ -644,12 +644,16 @@ "members": [ { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -660,12 +664,16 @@ }, { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -675,8 +683,10 @@ "type": "hatch" }, { - "state": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "type": "literal" } diff --git a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_9.json b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_9.json index dad78247e..497532e6d 100644 --- a/src/main/resources/mi_structures/modern_industrialization/distillation_tower_9.json +++ b/src/main/resources/mi_structures/modern_industrialization/distillation_tower_9.json @@ -716,12 +716,16 @@ "members": [ { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -732,12 +736,16 @@ }, { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -747,8 +755,10 @@ "type": "hatch" }, { - "state": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "type": "literal" } diff --git a/src/main/resources/mi_structures/modern_industrialization/electric_blast_furnace.json b/src/main/resources/mi_structures/modern_industrialization/electric_blast_furnace.json index d3fc7b21a..b3333b639 100644 --- a/src/main/resources/mi_structures/modern_industrialization/electric_blast_furnace.json +++ b/src/main/resources/mi_structures/modern_industrialization/electric_blast_furnace.json @@ -268,12 +268,16 @@ "members": [ { "preview": { - "Name": "modern_industrialization:heatproof_machine_casing" + "state": { + "Name": "modern_industrialization:heatproof_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:heatproof_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:heatproof_machine_casing" + } }, "type": "state" } diff --git a/src/main/resources/mi_structures/modern_industrialization/electric_quarry.json b/src/main/resources/mi_structures/modern_industrialization/electric_quarry.json index de911c97e..1cc38b537 100644 --- a/src/main/resources/mi_structures/modern_industrialization/electric_quarry.json +++ b/src/main/resources/mi_structures/modern_industrialization/electric_quarry.json @@ -212,12 +212,16 @@ "members": [ { "preview": { - "Name": "modern_industrialization:steel_machine_casing" + "state": { + "Name": "modern_industrialization:steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:steel_machine_casing" + } }, "type": "state" } @@ -227,24 +231,30 @@ "type": "hatch" }, { - "state": { - "Name": "modern_industrialization:steel_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:steel_machine_casing_pipe" + } }, "type": "literal" }, { - "state": { - "Properties": { - "waterlogged": "false", - "axis": "y" - }, - "Name": "minecraft:chain" + "value": { + "state": { + "Properties": { + "waterlogged": "false", + "axis": "y" + }, + "Name": "minecraft:chain" + } }, "type": "literal" }, { - "state": { - "Name": "modern_industrialization:steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:steel_machine_casing" + } }, "type": "literal" } diff --git a/src/main/resources/mi_structures/modern_industrialization/fusion_reactor.json b/src/main/resources/mi_structures/modern_industrialization/fusion_reactor.json index 82ac1da25..4eb94917d 100644 --- a/src/main/resources/mi_structures/modern_industrialization/fusion_reactor.json +++ b/src/main/resources/mi_structures/modern_industrialization/fusion_reactor.json @@ -1947,25 +1947,33 @@ ], "members": [ { - "state": { - "Name": "modern_industrialization:highly_advanced_machine_hull" + "value": { + "state": { + "Name": "modern_industrialization:highly_advanced_machine_hull" + } }, "type": "literal" }, { - "state": { - "Name": "modern_industrialization:fusion_chamber" + "value": { + "state": { + "Name": "modern_industrialization:fusion_chamber" + } }, "type": "literal" }, { "preview": { - "Name": "modern_industrialization:highly_advanced_machine_hull" + "state": { + "Name": "modern_industrialization:highly_advanced_machine_hull" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:highly_advanced_machine_hull" + "value": { + "state": { + "Name": "modern_industrialization:highly_advanced_machine_hull" + } }, "type": "state" } diff --git a/src/main/resources/mi_structures/modern_industrialization/heat_exchanger.json b/src/main/resources/mi_structures/modern_industrialization/heat_exchanger.json index 91edab44b..e2f740125 100644 --- a/src/main/resources/mi_structures/modern_industrialization/heat_exchanger.json +++ b/src/main/resources/mi_structures/modern_industrialization/heat_exchanger.json @@ -356,12 +356,16 @@ "members": [ { "preview": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "type": "state" } @@ -371,19 +375,25 @@ "type": "hatch" }, { - "state": { - "Name": "modern_industrialization:frostproof_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:frostproof_machine_casing" + } }, "type": "literal" }, { "preview": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "type": "state" } @@ -393,25 +403,33 @@ "type": "hatch" }, { - "state": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "type": "literal" }, { - "state": { - "Name": "modern_industrialization:heatproof_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:heatproof_machine_casing" + } }, "type": "literal" }, { "preview": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "type": "state" } @@ -422,12 +440,16 @@ }, { "preview": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "type": "state" } @@ -438,12 +460,16 @@ }, { "preview": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "type": "state" } diff --git a/src/main/resources/mi_structures/modern_industrialization/high_pressure_advanced_large_steam_boiler.json b/src/main/resources/mi_structures/modern_industrialization/high_pressure_advanced_large_steam_boiler.json index 5d25886e6..c36af6af4 100644 --- a/src/main/resources/mi_structures/modern_industrialization/high_pressure_advanced_large_steam_boiler.json +++ b/src/main/resources/mi_structures/modern_industrialization/high_pressure_advanced_large_steam_boiler.json @@ -355,25 +355,33 @@ ], "members": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "literal" }, { - "state": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "type": "literal" }, { "preview": { - "Name": "modern_industrialization:heatproof_machine_casing" + "state": { + "Name": "modern_industrialization:heatproof_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:heatproof_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:heatproof_machine_casing" + } }, "type": "state" } diff --git a/src/main/resources/mi_structures/modern_industrialization/high_pressure_large_steam_boiler.json b/src/main/resources/mi_structures/modern_industrialization/high_pressure_large_steam_boiler.json index 038de2dbb..05f465783 100644 --- a/src/main/resources/mi_structures/modern_industrialization/high_pressure_large_steam_boiler.json +++ b/src/main/resources/mi_structures/modern_industrialization/high_pressure_large_steam_boiler.json @@ -283,25 +283,33 @@ ], "members": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "literal" }, { - "state": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "type": "literal" }, { "preview": { - "Name": "modern_industrialization:heatproof_machine_casing" + "state": { + "Name": "modern_industrialization:heatproof_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:heatproof_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:heatproof_machine_casing" + } }, "type": "state" } diff --git a/src/main/resources/mi_structures/modern_industrialization/implosion_compressor.json b/src/main/resources/mi_structures/modern_industrialization/implosion_compressor.json index 1d0214019..7d033fe3b 100644 --- a/src/main/resources/mi_structures/modern_industrialization/implosion_compressor.json +++ b/src/main/resources/mi_structures/modern_industrialization/implosion_compressor.json @@ -268,12 +268,16 @@ "members": [ { "preview": { - "Name": "modern_industrialization:solid_titanium_machine_casing" + "state": { + "Name": "modern_industrialization:solid_titanium_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:solid_titanium_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:solid_titanium_machine_casing" + } }, "type": "state" } @@ -283,14 +287,18 @@ "type": "hatch" }, { - "state": { - "Name": "modern_industrialization:blastproof_casing" + "value": { + "state": { + "Name": "modern_industrialization:blastproof_casing" + } }, "type": "literal" }, { - "state": { - "Name": "modern_industrialization:solid_titanium_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:solid_titanium_machine_casing" + } }, "type": "literal" } diff --git a/src/main/resources/mi_structures/modern_industrialization/large_diesel_generator.json b/src/main/resources/mi_structures/modern_industrialization/large_diesel_generator.json index bbcd02e4d..b01d34d84 100644 --- a/src/main/resources/mi_structures/modern_industrialization/large_diesel_generator.json +++ b/src/main/resources/mi_structures/modern_industrialization/large_diesel_generator.json @@ -283,19 +283,25 @@ ], "members": [ { - "state": { - "Name": "modern_industrialization:titanium_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:titanium_machine_casing_pipe" + } }, "type": "literal" }, { "preview": { - "Name": "modern_industrialization:solid_titanium_machine_casing" + "state": { + "Name": "modern_industrialization:solid_titanium_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:solid_titanium_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:solid_titanium_machine_casing" + } }, "type": "state" } @@ -305,19 +311,25 @@ "type": "hatch" }, { - "state": { - "Name": "modern_industrialization:solid_titanium_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:solid_titanium_machine_casing" + } }, "type": "literal" }, { "preview": { - "Name": "modern_industrialization:solid_titanium_machine_casing" + "state": { + "Name": "modern_industrialization:solid_titanium_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:solid_titanium_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:solid_titanium_machine_casing" + } }, "type": "state" } diff --git a/src/main/resources/mi_structures/modern_industrialization/large_steam_boiler.json b/src/main/resources/mi_structures/modern_industrialization/large_steam_boiler.json index 0039fd49e..22e6a11e5 100644 --- a/src/main/resources/mi_structures/modern_industrialization/large_steam_boiler.json +++ b/src/main/resources/mi_structures/modern_industrialization/large_steam_boiler.json @@ -283,25 +283,33 @@ ], "members": [ { - "state": { - "Name": "modern_industrialization:bronze_plated_bricks" + "value": { + "state": { + "Name": "modern_industrialization:bronze_plated_bricks" + } }, "type": "literal" }, { - "state": { - "Name": "modern_industrialization:bronze_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:bronze_machine_casing_pipe" + } }, "type": "literal" }, { "preview": { - "Name": "modern_industrialization:heatproof_machine_casing" + "state": { + "Name": "modern_industrialization:heatproof_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:heatproof_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:heatproof_machine_casing" + } }, "type": "state" } diff --git a/src/main/resources/mi_structures/modern_industrialization/large_steam_turbine.json b/src/main/resources/mi_structures/modern_industrialization/large_steam_turbine.json index 2694d22b8..b69fe4f29 100644 --- a/src/main/resources/mi_structures/modern_industrialization/large_steam_turbine.json +++ b/src/main/resources/mi_structures/modern_industrialization/large_steam_turbine.json @@ -284,12 +284,16 @@ "members": [ { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } @@ -299,25 +303,33 @@ "type": "hatch" }, { - "state": { - "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:stainless_steel_machine_casing_pipe" + } }, "type": "literal" }, { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "literal" }, { "preview": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:clean_stainless_steel_machine_casing" + } }, "type": "state" } diff --git a/src/main/resources/mi_structures/modern_industrialization/oil_drilling_rig.json b/src/main/resources/mi_structures/modern_industrialization/oil_drilling_rig.json index 0dc5d4942..ae13c27ae 100644 --- a/src/main/resources/mi_structures/modern_industrialization/oil_drilling_rig.json +++ b/src/main/resources/mi_structures/modern_industrialization/oil_drilling_rig.json @@ -499,19 +499,25 @@ ], "members": [ { - "state": { - "Name": "modern_industrialization:steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:steel_machine_casing" + } }, "type": "literal" }, { "preview": { - "Name": "modern_industrialization:steel_machine_casing" + "state": { + "Name": "modern_industrialization:steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:steel_machine_casing" + } }, "type": "state" } @@ -521,18 +527,22 @@ "type": "hatch" }, { - "state": { - "Properties": { - "waterlogged": "false", - "axis": "y" - }, - "Name": "minecraft:chain" + "value": { + "state": { + "Properties": { + "waterlogged": "false", + "axis": "y" + }, + "Name": "minecraft:chain" + } }, "type": "literal" }, { - "state": { - "Name": "modern_industrialization:steel_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:steel_machine_casing_pipe" + } }, "type": "literal" } diff --git a/src/main/resources/mi_structures/modern_industrialization/plasma_turbine.json b/src/main/resources/mi_structures/modern_industrialization/plasma_turbine.json index 0945410a7..683cf841b 100644 --- a/src/main/resources/mi_structures/modern_industrialization/plasma_turbine.json +++ b/src/main/resources/mi_structures/modern_industrialization/plasma_turbine.json @@ -284,12 +284,16 @@ "members": [ { "preview": { - "Name": "modern_industrialization:plasma_handling_iridium_machine_casing" + "state": { + "Name": "modern_industrialization:plasma_handling_iridium_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:plasma_handling_iridium_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:plasma_handling_iridium_machine_casing" + } }, "type": "state" } @@ -299,25 +303,33 @@ "type": "hatch" }, { - "state": { - "Name": "modern_industrialization:iridium_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:iridium_machine_casing_pipe" + } }, "type": "literal" }, { - "state": { - "Name": "modern_industrialization:plasma_handling_iridium_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:plasma_handling_iridium_machine_casing" + } }, "type": "literal" }, { "preview": { - "Name": "modern_industrialization:plasma_handling_iridium_machine_casing" + "state": { + "Name": "modern_industrialization:plasma_handling_iridium_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:plasma_handling_iridium_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:plasma_handling_iridium_machine_casing" + } }, "type": "state" } diff --git a/src/main/resources/mi_structures/modern_industrialization/pressurizer.json b/src/main/resources/mi_structures/modern_industrialization/pressurizer.json index 2cec64978..c9c3b6cc8 100644 --- a/src/main/resources/mi_structures/modern_industrialization/pressurizer.json +++ b/src/main/resources/mi_structures/modern_industrialization/pressurizer.json @@ -155,19 +155,25 @@ ], "members": [ { - "state": { - "Name": "modern_industrialization:titanium_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:titanium_machine_casing_pipe" + } }, "type": "literal" }, { "preview": { - "Name": "modern_industrialization:solid_titanium_machine_casing" + "state": { + "Name": "modern_industrialization:solid_titanium_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:solid_titanium_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:solid_titanium_machine_casing" + } }, "type": "state" } @@ -178,12 +184,16 @@ }, { "preview": { - "Name": "modern_industrialization:solid_titanium_machine_casing" + "state": { + "Name": "modern_industrialization:solid_titanium_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:solid_titanium_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:solid_titanium_machine_casing" + } }, "type": "state" } diff --git a/src/main/resources/mi_structures/modern_industrialization/steam_blast_furnace.json b/src/main/resources/mi_structures/modern_industrialization/steam_blast_furnace.json index 4865c2d10..335eb67e7 100644 --- a/src/main/resources/mi_structures/modern_industrialization/steam_blast_furnace.json +++ b/src/main/resources/mi_structures/modern_industrialization/steam_blast_furnace.json @@ -259,19 +259,25 @@ ], "members": [ { - "state": { - "Name": "modern_industrialization:fire_clay_bricks" + "value": { + "state": { + "Name": "modern_industrialization:fire_clay_bricks" + } }, "type": "literal" }, { "preview": { - "Name": "modern_industrialization:fire_clay_bricks" + "state": { + "Name": "modern_industrialization:fire_clay_bricks" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:fire_clay_bricks" + "value": { + "state": { + "Name": "modern_industrialization:fire_clay_bricks" + } }, "type": "state" } diff --git a/src/main/resources/mi_structures/modern_industrialization/steam_quarry.json b/src/main/resources/mi_structures/modern_industrialization/steam_quarry.json index 7ccb02a4d..42ce3d425 100644 --- a/src/main/resources/mi_structures/modern_industrialization/steam_quarry.json +++ b/src/main/resources/mi_structures/modern_industrialization/steam_quarry.json @@ -212,12 +212,16 @@ "members": [ { "preview": { - "Name": "modern_industrialization:steel_machine_casing" + "state": { + "Name": "modern_industrialization:steel_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:steel_machine_casing" + } }, "type": "state" } @@ -227,24 +231,30 @@ "type": "hatch" }, { - "state": { - "Name": "modern_industrialization:steel_machine_casing_pipe" + "value": { + "state": { + "Name": "modern_industrialization:steel_machine_casing_pipe" + } }, "type": "literal" }, { - "state": { - "Properties": { - "waterlogged": "false", - "axis": "y" - }, - "Name": "minecraft:chain" + "value": { + "state": { + "Properties": { + "waterlogged": "false", + "axis": "y" + }, + "Name": "minecraft:chain" + } }, "type": "literal" }, { - "state": { - "Name": "modern_industrialization:steel_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:steel_machine_casing" + } }, "type": "literal" } diff --git a/src/main/resources/mi_structures/modern_industrialization/vacuum_freezer.json b/src/main/resources/mi_structures/modern_industrialization/vacuum_freezer.json index 64de0644e..8c11893de 100644 --- a/src/main/resources/mi_structures/modern_industrialization/vacuum_freezer.json +++ b/src/main/resources/mi_structures/modern_industrialization/vacuum_freezer.json @@ -267,19 +267,25 @@ ], "members": [ { - "state": { - "Name": "modern_industrialization:frostproof_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:frostproof_machine_casing" + } }, "type": "literal" }, { "preview": { - "Name": "modern_industrialization:frostproof_machine_casing" + "state": { + "Name": "modern_industrialization:frostproof_machine_casing" + } }, "tests": [ { - "state": { - "Name": "modern_industrialization:frostproof_machine_casing" + "value": { + "state": { + "Name": "modern_industrialization:frostproof_machine_casing" + } }, "type": "state" } From 43dd8af09dfe4ca1eb280ee8c824df8162ae8ab3 Mon Sep 17 00:00:00 2001 From: Swedz Date: Mon, 2 Dec 2024 06:38:37 -0500 Subject: [PATCH 84/89] Add item tooltip to structure controller --- .../modern_industrialization/lang/en_us.json | 8 ++ .../modern_industrialization/MIBlock.java | 3 +- .../modern_industrialization/MIText.java | 8 ++ ...tructureMultiblockControllerBlockItem.java | 135 ++++++++++++++++++ 4 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlockItem.java diff --git a/src/generated/resources/assets/modern_industrialization/lang/en_us.json b/src/generated/resources/assets/modern_industrialization/lang/en_us.json index bad98f6ec..c675b55a0 100644 --- a/src/generated/resources/assets/modern_industrialization/lang/en_us.json +++ b/src/generated/resources/assets/modern_industrialization/lang/en_us.json @@ -1719,6 +1719,14 @@ "text.modern_industrialization.SteamDrillToggle": "- Toggle Silk Touch with %s + %s.", "text.modern_industrialization.SteamDrillWaterHelp": "- Press %s on still or flowing water to fill.", "text.modern_industrialization.StructureMultiblockCasing": "Machine Casing", + "text.modern_industrialization.StructureMultiblockControllerTooltipBoundsRelative": "Position: %s", + "text.modern_industrialization.StructureMultiblockControllerTooltipBoundsSize": "Size: %s", + "text.modern_industrialization.StructureMultiblockControllerTooltipIgnoreNBT": "Ignore NBT blocks: %s", + "text.modern_industrialization.StructureMultiblockControllerTooltipIncludeBlockEntities": "Block Entities: %s", + "text.modern_industrialization.StructureMultiblockControllerTooltipMode": "Mode: %s", + "text.modern_industrialization.StructureMultiblockControllerTooltipName": "Name: %s", + "text.modern_industrialization.StructureMultiblockControllerTooltipShowBounds": "Show Bounds: %s", + "text.modern_industrialization.StructureMultiblockControllerTooltipWeakNBT": "Weak NBT blocks: %s", "text.modern_industrialization.StructureMultiblockGuiIncludeBlockEntities": "Include NBT", "text.modern_industrialization.StructureMultiblockGuiLoad": "LOAD", "text.modern_industrialization.StructureMultiblockGuiLoadTooltip": "Hold SHIFT to place actual blocks instead of structure blocks.", diff --git a/src/main/java/aztech/modern_industrialization/MIBlock.java b/src/main/java/aztech/modern_industrialization/MIBlock.java index 8bf288b60..e9c660775 100644 --- a/src/main/java/aztech/modern_industrialization/MIBlock.java +++ b/src/main/java/aztech/modern_industrialization/MIBlock.java @@ -36,6 +36,7 @@ import aztech.modern_industrialization.blocks.storage.tank.TankItem; import aztech.modern_industrialization.blocks.storage.tank.creativetank.CreativeTankBlockEntity; import aztech.modern_industrialization.blocks.structure.controller.StructureMultiblockControllerBlock; +import aztech.modern_industrialization.blocks.structure.controller.StructureMultiblockControllerBlockItem; import aztech.modern_industrialization.blocks.structure.member.StructureMemberMode; import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlock; import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlockItem; @@ -139,7 +140,7 @@ public static void init(IEventBus modBus) { public static final BlockDefinition STRUCTURE_MULTIBLOCK_CONTROLLER = block("Structure Multiblock Controller", "structure_multiblock_controller", BlockDefinitionParams.defaultCreativeOnly() .withBlockConstructor(StructureMultiblockControllerBlock::new) - .withBlockItemConstructor((block, p) -> new BlockItem(block, p.rarity(Rarity.EPIC))) + .withBlockItemConstructor((block, p) -> new StructureMultiblockControllerBlockItem(block, p.rarity(Rarity.EPIC))) .withModel((block, gen) -> { String name = gen.name(block); var model = gen.models().orientable(name, diff --git a/src/main/java/aztech/modern_industrialization/MIText.java b/src/main/java/aztech/modern_industrialization/MIText.java index 60ba682f2..8aed8e6e3 100644 --- a/src/main/java/aztech/modern_industrialization/MIText.java +++ b/src/main/java/aztech/modern_industrialization/MIText.java @@ -247,6 +247,14 @@ public enum MIText { SteamDrillToggle("- Toggle Silk Touch with %s + %s."), SteamDrillWaterHelp("- Press %s on still or flowing water to fill."), StructureMultiblockCasing("Machine Casing"), + StructureMultiblockControllerTooltipName("Name: %s"), + StructureMultiblockControllerTooltipMode("Mode: %s"), + StructureMultiblockControllerTooltipBoundsRelative("Position: %s"), + StructureMultiblockControllerTooltipBoundsSize("Size: %s"), + StructureMultiblockControllerTooltipShowBounds("Show Bounds: %s"), + StructureMultiblockControllerTooltipIncludeBlockEntities("Block Entities: %s"), + StructureMultiblockControllerTooltipIgnoreNBT("Ignore NBT blocks: %s"), + StructureMultiblockControllerTooltipWeakNBT("Weak NBT blocks: %s"), StructureMultiblockGuiIncludeBlockEntities("Include NBT"), StructureMultiblockGuiLoad("LOAD"), StructureMultiblockGuiLoadTooltip("Hold SHIFT to place actual blocks instead of structure blocks."), diff --git a/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlockItem.java b/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlockItem.java new file mode 100644 index 000000000..e5d607e82 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/blocks/structure/controller/StructureMultiblockControllerBlockItem.java @@ -0,0 +1,135 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.blocks.structure.controller; + +import aztech.modern_industrialization.MIBlock; +import aztech.modern_industrialization.MIText; +import aztech.modern_industrialization.MITooltips; +import aztech.modern_industrialization.util.NbtHelper; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import net.minecraft.core.BlockPos; +import net.minecraft.core.component.DataComponents; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.nbt.Tag; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.level.block.Block; + +public class StructureMultiblockControllerBlockItem extends BlockItem { + public StructureMultiblockControllerBlockItem(Block block, Properties properties) { + super(block, properties); + } + + public static StructureControllerMode getMode(ItemStack stack) { + if (!stack.is(MIBlock.STRUCTURE_MULTIBLOCK_CONTROLLER.asItem())) { + return null; + } + + String modeId = stack.has(DataComponents.BLOCK_ENTITY_DATA) + ? stack.get(DataComponents.BLOCK_ENTITY_DATA).copyTag().getString("mode") + : ""; + if (!modeId.isEmpty()) { + try { + return StructureControllerMode.valueOf(modeId.toUpperCase(Locale.ROOT)); + } catch (IllegalArgumentException ignored) { + return StructureControllerMode.SAVE; + } + } + return StructureControllerMode.SAVE; + } + + @Override + public void appendHoverText(ItemStack stack, TooltipContext context, List tooltipComponents, TooltipFlag tooltipFlag) { + if (stack.has(DataComponents.BLOCK_ENTITY_DATA)) { + CompoundTag tag = stack.get(DataComponents.BLOCK_ENTITY_DATA).copyTag(); + + var mode = getMode(stack); + + tooltipComponents.add(MIText.StructureMultiblockControllerTooltipMode.text(mode.text().withStyle(MITooltips.HIGHLIGHT_STYLE)) + .withStyle(MITooltips.DEFAULT_STYLE)); + + if (tag.contains("structure_id", Tag.TAG_STRING)) { + var name = tag.getString("structure_id"); + tooltipComponents.add(MIText.StructureMultiblockControllerTooltipName + .text(Component.literal(name).withStyle(MITooltips.HIGHLIGHT_STYLE)).withStyle(MITooltips.DEFAULT_STYLE)); + } + + if (mode == StructureControllerMode.SAVE) { + if (tag.contains("bounds", Tag.TAG_COMPOUND)) { + CompoundTag boundsTag = tag.getCompound("bounds"); + BlockPos origin = NbtUtils.readBlockPos(boundsTag, "origin").orElseThrow(); + BlockPos size = NbtUtils.readBlockPos(boundsTag, "size").orElseThrow(); + var bounds = new StructureControllerBounds( + origin.getX(), origin.getY(), origin.getZ(), + size.getX(), size.getY(), size.getZ()); + tooltipComponents.add(MIText.StructureMultiblockControllerTooltipBoundsRelative.text( + Component.literal("(%d, %d, %d)".formatted(bounds.x(), bounds.y(), bounds.z())).withStyle(MITooltips.HIGHLIGHT_STYLE)) + .withStyle(MITooltips.DEFAULT_STYLE)); + tooltipComponents.add(MIText.StructureMultiblockControllerTooltipBoundsSize.text(Component + .literal("(%d, %d, %d)".formatted(bounds.sizeX(), bounds.sizeY(), bounds.sizeZ())).withStyle(MITooltips.HIGHLIGHT_STYLE)) + .withStyle(MITooltips.DEFAULT_STYLE)); + } + + if (tag.contains("show_bounds")) { + var showBounds = tag.getBoolean("show_bounds"); + tooltipComponents.add(MIText.StructureMultiblockControllerTooltipShowBounds + .text(Component.literal(Boolean.toString(showBounds)).withStyle(MITooltips.HIGHLIGHT_STYLE)) + .withStyle(MITooltips.DEFAULT_STYLE)); + } + + if (tag.contains("include_block_entities")) { + var includeBlockEntities = tag.getBoolean("include_block_entities"); + tooltipComponents.add(MIText.StructureMultiblockControllerTooltipIncludeBlockEntities + .text(Component.literal(Boolean.toString(includeBlockEntities)).withStyle(MITooltips.HIGHLIGHT_STYLE)) + .withStyle(MITooltips.DEFAULT_STYLE)); + } + + if (tag.contains("ignore_nbt_positions", Tag.TAG_LIST)) { + List ignoreNBTPositions = new ArrayList<>(); + NbtHelper.getBlockPosList(tag, "ignore_nbt_positions", ignoreNBTPositions); + if (!ignoreNBTPositions.isEmpty()) { + tooltipComponents.add(MIText.StructureMultiblockControllerTooltipIgnoreNBT + .text(Component.literal(Integer.toString(ignoreNBTPositions.size())).withStyle(MITooltips.HIGHLIGHT_STYLE)) + .withStyle(MITooltips.DEFAULT_STYLE)); + } + } + + if (tag.contains("weak_nbt_positions", Tag.TAG_LIST)) { + List weakNBTPositions = new ArrayList<>(); + NbtHelper.getBlockPosList(tag, "weak_nbt_positions", weakNBTPositions); + if (!weakNBTPositions.isEmpty()) { + tooltipComponents.add(MIText.StructureMultiblockControllerTooltipWeakNBT + .text(Component.literal(Integer.toString(weakNBTPositions.size())).withStyle(MITooltips.HIGHLIGHT_STYLE)) + .withStyle(MITooltips.DEFAULT_STYLE)); + } + } + } + } + } +} From 85d96a93e572285e208a0b066c954bf0c77093ee Mon Sep 17 00:00:00 2001 From: Swedz Date: Mon, 2 Dec 2024 06:57:55 -0500 Subject: [PATCH 85/89] Tooltip wording --- .../resources/assets/modern_industrialization/lang/en_us.json | 2 +- src/main/java/aztech/modern_industrialization/MIText.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/generated/resources/assets/modern_industrialization/lang/en_us.json b/src/generated/resources/assets/modern_industrialization/lang/en_us.json index c675b55a0..b83f86e4f 100644 --- a/src/generated/resources/assets/modern_industrialization/lang/en_us.json +++ b/src/generated/resources/assets/modern_industrialization/lang/en_us.json @@ -1779,7 +1779,7 @@ "text.modern_industrialization.StructureMultiblockWrenchCleared": "Cleared the selection", "text.modern_industrialization.StructureMultiblockWrenchHelp1": "Block selection:", "text.modern_industrialization.StructureMultiblockWrenchHelp2": "- Press %s on air to change modes.", - "text.modern_industrialization.StructureMultiblockWrenchHelp3": "- Press %s on a block to add it to the selection.", + "text.modern_industrialization.StructureMultiblockWrenchHelp3": "- Press %s on a block to add/remove it to/from the selection.", "text.modern_industrialization.StructureMultiblockWrenchHelp4": "- Press %s + %s on a structure controller to save the selection to the controller.", "text.modern_industrialization.StructureMultiblockWrenchHelp5": "Clear selection using %s + %s on air.", "text.modern_industrialization.StructureMultiblockWrenchNBTModeIgnore": "Ignore", diff --git a/src/main/java/aztech/modern_industrialization/MIText.java b/src/main/java/aztech/modern_industrialization/MIText.java index 8aed8e6e3..e54eaaeeb 100644 --- a/src/main/java/aztech/modern_industrialization/MIText.java +++ b/src/main/java/aztech/modern_industrialization/MIText.java @@ -307,7 +307,7 @@ public enum MIText { StructureMultiblockWrenchCleared("Cleared the selection"), StructureMultiblockWrenchHelp1("Block selection:"), StructureMultiblockWrenchHelp2("- Press %s on air to change modes."), - StructureMultiblockWrenchHelp3("- Press %s on a block to add it to the selection."), + StructureMultiblockWrenchHelp3("- Press %s on a block to add/remove it to/from the selection."), StructureMultiblockWrenchHelp4("- Press %s + %s on a structure controller to save the selection to the controller."), StructureMultiblockWrenchHelp5("Clear selection using %s + %s on air."), StructureMultiblockWrenchNBTModeIgnore("Ignore"), From 7c2c6af4e016840fe395ebe836fe6a382afc76c2 Mon Sep 17 00:00:00 2001 From: Swedz Date: Mon, 2 Dec 2024 07:09:59 -0500 Subject: [PATCH 86/89] Render tooltip to screen when looking at a structure block with wrench in hand --- .../modern_industrialization/MIClient.java | 8 ++--- .../StructureMultiblockWrenchHighlight.java | 36 ++++++++++++++++++- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/client/java/aztech/modern_industrialization/MIClient.java b/src/client/java/aztech/modern_industrialization/MIClient.java index 7b8592d4a..31e24d2fe 100644 --- a/src/client/java/aztech/modern_industrialization/MIClient.java +++ b/src/client/java/aztech/modern_industrialization/MIClient.java @@ -35,11 +35,7 @@ import aztech.modern_industrialization.datagen.MIDatagenClient; import aztech.modern_industrialization.datagen.MIDatagenServer; import aztech.modern_industrialization.datagen.model.DelegatingModelBuilder; -import aztech.modern_industrialization.items.ConfigCardItem; -import aztech.modern_industrialization.items.RedstoneControlModuleItem; -import aztech.modern_industrialization.items.SteamDrillHighlight; -import aztech.modern_industrialization.items.SteamDrillItem; -import aztech.modern_industrialization.items.SteamDrillTooltipComponent; +import aztech.modern_industrialization.items.*; import aztech.modern_industrialization.items.armor.ClientKeyHandler; import aztech.modern_industrialization.items.armor.HudRenderer; import aztech.modern_industrialization.items.armor.JetpackParticleAdder; @@ -260,6 +256,8 @@ private static void registerClientTooltipComponents(RegisterClientTooltipCompone @SubscribeEvent private static void registerGuiOverlays(RegisterGuiLayersEvent event) { event.registerAbove(VanillaGuiLayers.SELECTED_ITEM_NAME, MI.id("activation_status"), HudRenderer::onRenderHud); + event.registerAbove(VanillaGuiLayers.SELECTED_ITEM_NAME, MI.id("structure_multiblock_wrench"), + StructureMultiblockWrenchHighlight::onRenderHud); } @SubscribeEvent diff --git a/src/client/java/aztech/modern_industrialization/items/StructureMultiblockWrenchHighlight.java b/src/client/java/aztech/modern_industrialization/items/StructureMultiblockWrenchHighlight.java index bd8d107e4..985a8825b 100644 --- a/src/client/java/aztech/modern_industrialization/items/StructureMultiblockWrenchHighlight.java +++ b/src/client/java/aztech/modern_industrialization/items/StructureMultiblockWrenchHighlight.java @@ -26,17 +26,30 @@ import aztech.modern_industrialization.MI; import aztech.modern_industrialization.MIComponents; import aztech.modern_industrialization.MIItem; +import aztech.modern_industrialization.blocks.structure.controller.StructureMultiblockControllerBlockEntity; +import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlockEntity; +import aztech.modern_industrialization.machines.multiblocks.structure.MIStructureTemplateManager; import aztech.modern_industrialization.util.RenderHelper; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.ByteBufferBuilder; import java.util.ArrayList; import java.util.List; +import net.minecraft.client.DeltaTracker; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.core.BlockPos; +import net.minecraft.core.component.DataComponents; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.component.CustomData; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; @@ -47,7 +60,7 @@ public class StructureMultiblockWrenchHighlight { private static final MultiBufferSource.BufferSource immediate = MultiBufferSource.immediate(new ByteBufferBuilder(128)); @SubscribeEvent - private static void onRender(RenderLevelStageEvent event) { + private static void onRenderLevel(RenderLevelStageEvent event) { if (event.getStage() != RenderLevelStageEvent.Stage.AFTER_LEVEL) { return; } @@ -74,6 +87,22 @@ private static void onRender(RenderLevelStageEvent event) { } } + public static void onRenderHud(GuiGraphics guiGraphics, DeltaTracker deltaTracker) { + Minecraft mc = Minecraft.getInstance(); + if (mc.player != null && isHoldingWrench(mc.player) && mc.hitResult instanceof BlockHitResult hitResult) { + Level level = mc.level; + BlockPos pos = hitResult.getBlockPos(); + BlockState state = level.getBlockState(pos); + BlockEntity blockEntity = level.getBlockEntity(pos); + if (blockEntity instanceof StructureMultiblockControllerBlockEntity || blockEntity instanceof StructureMultiblockMemberBlockEntity) { + ItemStack stack = new ItemStack(state.getBlock().asItem()); + CompoundTag tag = MIStructureTemplateManager.maybeTag(blockEntity); + stack.set(DataComponents.BLOCK_ENTITY_DATA, CustomData.of(tag)); + guiGraphics.renderTooltip(mc.font, stack, mc.getWindow().getGuiScaledWidth() / 2, mc.getWindow().getGuiScaledHeight() / 2); + } + } + } + private static List getWrenchSelectedPositions(Player player) { List positions = new ArrayList<>(); positions.addAll(getWrenchSelectedPositions(player.getMainHandItem())); @@ -86,4 +115,9 @@ private static List getWrenchSelectedPositions(ItemStack stack) { ? stack.get(MIComponents.STRUCTURE_WRENCH_SELECTION).positions() : List.of(); } + + private static boolean isHoldingWrench(Player player) { + return player.getItemInHand(InteractionHand.MAIN_HAND).is(MIItem.STRUCTURE_MULTIBLOCK_WRENCH.asItem()) + || player.getItemInHand(InteractionHand.OFF_HAND).is(MIItem.STRUCTURE_MULTIBLOCK_WRENCH.asItem()); + } } From f69af3ad272621551330c662fca0729a671b9a2a Mon Sep 17 00:00:00 2001 From: Swedz Date: Mon, 2 Dec 2024 07:15:45 -0500 Subject: [PATCH 87/89] Only render tooltip to screen if no screen is open --- .../items/StructureMultiblockWrenchHighlight.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/java/aztech/modern_industrialization/items/StructureMultiblockWrenchHighlight.java b/src/client/java/aztech/modern_industrialization/items/StructureMultiblockWrenchHighlight.java index 985a8825b..e41bbf7c4 100644 --- a/src/client/java/aztech/modern_industrialization/items/StructureMultiblockWrenchHighlight.java +++ b/src/client/java/aztech/modern_industrialization/items/StructureMultiblockWrenchHighlight.java @@ -89,7 +89,7 @@ private static void onRenderLevel(RenderLevelStageEvent event) { public static void onRenderHud(GuiGraphics guiGraphics, DeltaTracker deltaTracker) { Minecraft mc = Minecraft.getInstance(); - if (mc.player != null && isHoldingWrench(mc.player) && mc.hitResult instanceof BlockHitResult hitResult) { + if (mc.screen == null && mc.player != null && isHoldingWrench(mc.player) && mc.hitResult instanceof BlockHitResult hitResult) { Level level = mc.level; BlockPos pos = hitResult.getBlockPos(); BlockState state = level.getBlockState(pos); From 85bcad87fbd42b1185b4856f76c413ef3ed0f280 Mon Sep 17 00:00:00 2001 From: Swedz Date: Sun, 9 Feb 2025 12:30:02 -0500 Subject: [PATCH 88/89] Fix conflicts --- .../modern_industrialization/MIClient.java | 8 +- .../StructureMultiblockControllerBER.java | 3 +- .../StructureMultiblockWrenchHighlight.java | 4 +- .../ClientStructureMemberBlockTooltip.java | 4 +- .../multiblocks/MultiblockMachineBER.java | 2 +- .../modern_industrialization/lang/en_us.json | 73 +++++++++++++++++++ .../api/energy/CableTier.java | 3 + .../debug/DebugCommands.java | 2 +- .../machines/models/MachineCasing.java | 3 + .../MultiblockMachineBlockEntity.java | 2 +- .../machines/multiblocks/ShapeMatcher.java | 3 +- 11 files changed, 92 insertions(+), 15 deletions(-) diff --git a/src/client/java/aztech/modern_industrialization/MIClient.java b/src/client/java/aztech/modern_industrialization/MIClient.java index d925fe28c..f5d220ab6 100644 --- a/src/client/java/aztech/modern_industrialization/MIClient.java +++ b/src/client/java/aztech/modern_industrialization/MIClient.java @@ -29,18 +29,14 @@ import aztech.modern_industrialization.blocks.storage.barrel.DeferredBarrelTextRenderer; import aztech.modern_industrialization.blocks.storage.barrel.client.BarrelTooltipComponent; import aztech.modern_industrialization.blocks.storage.tank.TankRenderer; -import aztech.modern_industrialization.client.MIRenderTypes; import aztech.modern_industrialization.blocks.structure.StructureMultiblockControllerBER; import aztech.modern_industrialization.blocks.structure.member.StructureMemberMode; import aztech.modern_industrialization.blocks.structure.member.StructureMultiblockMemberBlockItem; +import aztech.modern_industrialization.client.MIRenderTypes; import aztech.modern_industrialization.datagen.MIDatagenClient; import aztech.modern_industrialization.datagen.MIDatagenServer; import aztech.modern_industrialization.datagen.model.DelegatingModelBuilder; -import aztech.modern_industrialization.items.ConfigCardItem; -import aztech.modern_industrialization.items.RedstoneControlModuleItem; -import aztech.modern_industrialization.items.SteamDrillHighlight; -import aztech.modern_industrialization.items.SteamDrillItem; -import aztech.modern_industrialization.items.SteamDrillTooltipComponent; +import aztech.modern_industrialization.items.*; import aztech.modern_industrialization.items.armor.ClientKeyHandler; import aztech.modern_industrialization.items.armor.HudRenderer; import aztech.modern_industrialization.items.armor.JetpackParticleAdder; diff --git a/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java b/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java index 0d93587f4..b0a2fa01b 100644 --- a/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java +++ b/src/client/java/aztech/modern_industrialization/blocks/structure/StructureMultiblockControllerBER.java @@ -67,7 +67,8 @@ public void render(StructureMultiblockControllerBlockEntity be, float tickDelta, misconfiguredPos.getZ() - pos.getZ()); matrices.translate(-0.005f, -0.005f, -0.005f); matrices.scale(1.01f, 1.01f, 1.01f); - RenderHelper.drawOverlay(matrices, vcp, 1.0f, 111f / 256f, 111f / 256f, RenderHelper.FULL_LIGHT, overlay, false); + // TODO SWEDZ: render red overlay (255, 111, 111) + RenderHelper.drawOverlay(matrices, vcp, overlay); matrices.popPose(); } } diff --git a/src/client/java/aztech/modern_industrialization/items/StructureMultiblockWrenchHighlight.java b/src/client/java/aztech/modern_industrialization/items/StructureMultiblockWrenchHighlight.java index e41bbf7c4..25daca9f2 100644 --- a/src/client/java/aztech/modern_industrialization/items/StructureMultiblockWrenchHighlight.java +++ b/src/client/java/aztech/modern_industrialization/items/StructureMultiblockWrenchHighlight.java @@ -38,7 +38,6 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.core.BlockPos; import net.minecraft.core.component.DataComponents; import net.minecraft.nbt.CompoundTag; @@ -79,7 +78,8 @@ private static void onRenderLevel(RenderLevelStageEvent event) { double z = pos.getZ() - cameraPos.z; poseStack.translate(x - 0.005, y - 0.005, z - 0.005); poseStack.scale(1.01f, 1.01f, 1.01f); - RenderHelper.drawOverlay(poseStack, immediate, 1, 111f / 256, 1, 15728880, OverlayTexture.NO_OVERLAY); + // TODO SWEDZ: render magenta overlay (255, 111, 255) + RenderHelper.drawOverlay(poseStack, immediate, RenderHelper.FULL_LIGHT); poseStack.popPose(); } poseStack.popPose(); diff --git a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java index 1f26b9246..675c398f6 100644 --- a/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java +++ b/src/client/java/aztech/modern_industrialization/items/client/ClientStructureMemberBlockTooltip.java @@ -325,7 +325,7 @@ public int height(Font font) { @Override public int width(Font font) { - return font.width(label) + 20 + font.width(casing.getDisplayName()); + return font.width(label) + 20 + font.width(casing.getName()); } @Override @@ -337,7 +337,7 @@ public void renderImage(Font font, int x, int y, GuiGraphics graphics) { public void renderText(Font font, int x, int y, Matrix4f matrix, MultiBufferSource.BufferSource buffer) { font.drawInBatch(label, x, y + 5, -1, true, matrix, buffer, Font.DisplayMode.NORMAL, 0, 0xF000F0); - font.drawInBatch(casing.getDisplayName().withStyle(MITooltips.HIGHLIGHT_STYLE), x + font.width(label) + 20, y + 5, -1, true, matrix, + font.drawInBatch(casing.getName().withStyle(MITooltips.HIGHLIGHT_STYLE), x + font.width(label) + 20, y + 5, -1, true, matrix, buffer, Font.DisplayMode.NORMAL, 0, 0xF000F0); } } diff --git a/src/client/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBER.java b/src/client/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBER.java index b970605c2..54d38d922 100644 --- a/src/client/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBER.java +++ b/src/client/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBER.java @@ -76,7 +76,7 @@ public void render(MultiblockMachineBlockEntity be, float tickDelta, PoseStack m } } if (drawHighlights) { - if (!matcher.matches(pos, level, null)) { + if (!matcher.matches(pos, level)) { var existingState = level.getBlockState(pos); if (existingState.isAir() || /* approximate check for e.g. grass and snow */ existingState.canBeReplaced()) { // Enqueue state preview diff --git a/src/generated/resources/assets/modern_industrialization/lang/en_us.json b/src/generated/resources/assets/modern_industrialization/lang/en_us.json index d1dbbffcd..cc57bfea4 100644 --- a/src/generated/resources/assets/modern_industrialization/lang/en_us.json +++ b/src/generated/resources/assets/modern_industrialization/lang/en_us.json @@ -404,6 +404,8 @@ "block.modern_industrialization.steel_unpacker": "Steel Unpacker", "block.modern_industrialization.steel_water_pump": "Steel Water Pump", "block.modern_industrialization.steel_wiremill": "Steel Wiremill", + "block.modern_industrialization.structure_multiblock_controller": "Structure Multiblock Controller", + "block.modern_industrialization.structure_multiblock_member": "Structure Multiblock Member", "block.modern_industrialization.styrene": "Styrene", "block.modern_industrialization.styrene_butadiene": "Styrene-Butadiene", "block.modern_industrialization.styrene_butadiene_rubber": "Styrene-Butadiene Rubber", @@ -981,6 +983,7 @@ "item.modern_industrialization.steel_rod_magnetic": "Magnetic Steel Rod", "item.modern_industrialization.steel_tiny_dust": "Steel Tiny Dust", "item.modern_industrialization.steel_upgrade": "Steel Upgrade", + "item.modern_industrialization.structure_multiblock_wrench": "Structure Multiblock Wrench", "item.modern_industrialization.styrene_bucket": "Styrene Bucket", "item.modern_industrialization.styrene_butadiene_bucket": "Styrene-Butadiene Bucket", "item.modern_industrialization.styrene_butadiene_rubber_bucket": "Styrene-Butadiene Rubber Bucket", @@ -1478,6 +1481,7 @@ "text.autoconfig.modern_industrialization.option.enableHatchPlacementOverlay": "Show valid positions in multiblocks when holding a hatch", "text.autoconfig.modern_industrialization.option.enableInterMachineConnectedTextures": "Enable inter-machine connected textures. (Requires a suitable resource pack)", "text.autoconfig.modern_industrialization.option.enableNoEmiMessage": "Enable login message when EMI, JEI and REI are missing", + "text.autoconfig.modern_industrialization.option.exportStructureFiles": "Export all structure files to modern_industrialization/structures", "text.autoconfig.modern_industrialization.option.loadRuntimeGeneratedResources": "Additionally load resources in modern_industrialization/generated_resources", "text.autoconfig.modern_industrialization.option.maxDistillationTowerHeight": "Maximum height of the Distillation Tower multiblock (Restart needed)", "text.autoconfig.modern_industrialization.option.newVersionMessage": "Display when a new version is available", @@ -1704,6 +1708,75 @@ "text.modern_industrialization.SteamDrillProfit": "- Press %s to toggle 3x3 mining.", "text.modern_industrialization.SteamDrillToggle": "- Toggle Silk Touch with %s + %s.", "text.modern_industrialization.SteamDrillWaterHelp": "- Press %s on still or flowing water to fill.", + "text.modern_industrialization.StructureMultiblockCasing": "Machine Casing", + "text.modern_industrialization.StructureMultiblockControllerTooltipBoundsRelative": "Position: %s", + "text.modern_industrialization.StructureMultiblockControllerTooltipBoundsSize": "Size: %s", + "text.modern_industrialization.StructureMultiblockControllerTooltipIgnoreNBT": "Ignore NBT blocks: %s", + "text.modern_industrialization.StructureMultiblockControllerTooltipIncludeBlockEntities": "Block Entities: %s", + "text.modern_industrialization.StructureMultiblockControllerTooltipMode": "Mode: %s", + "text.modern_industrialization.StructureMultiblockControllerTooltipName": "Name: %s", + "text.modern_industrialization.StructureMultiblockControllerTooltipShowBounds": "Show Bounds: %s", + "text.modern_industrialization.StructureMultiblockControllerTooltipWeakNBT": "Weak NBT blocks: %s", + "text.modern_industrialization.StructureMultiblockGuiIncludeBlockEntities": "Include NBT", + "text.modern_industrialization.StructureMultiblockGuiLoad": "LOAD", + "text.modern_industrialization.StructureMultiblockGuiLoadTooltip": "Hold SHIFT to place actual blocks instead of structure blocks.", + "text.modern_industrialization.StructureMultiblockGuiMode": "MODE", + "text.modern_industrialization.StructureMultiblockGuiNBTMode": "NBT MODE", + "text.modern_industrialization.StructureMultiblockGuiNBTModeStrong": "STRONG", + "text.modern_industrialization.StructureMultiblockGuiNBTModeWeak": "WEAK", + "text.modern_industrialization.StructureMultiblockGuiRelativePosition": "Relative Position", + "text.modern_industrialization.StructureMultiblockGuiRelativePositionX": "Relative Position X", + "text.modern_industrialization.StructureMultiblockGuiRelativePositionY": "Relative Position Y", + "text.modern_industrialization.StructureMultiblockGuiRelativePositionZ": "Relative Position Z", + "text.modern_industrialization.StructureMultiblockGuiSave": "SAVE", + "text.modern_industrialization.StructureMultiblockGuiShowBoundingBox": "Show Bounding Box", + "text.modern_industrialization.StructureMultiblockGuiStructureSize": "Structure Size", + "text.modern_industrialization.StructureMultiblockGuiStructureSizeX": "Structure Size X", + "text.modern_industrialization.StructureMultiblockGuiStructureSizeY": "Structure Size Y", + "text.modern_industrialization.StructureMultiblockGuiStructureSizeZ": "Structure Size Z", + "text.modern_industrialization.StructureMultiblockLoadFailDoesntExist": "Failed to place the structure. No structure exists as %s.", + "text.modern_industrialization.StructureMultiblockLoadFailInvalidId": "Failed to place the structure. No id was provided.", + "text.modern_industrialization.StructureMultiblockLoadSuccess": "Successfully placed the structure %s.", + "text.modern_industrialization.StructureMultiblockMemberHatchFlags": "Hatch Flags", + "text.modern_industrialization.StructureMultiblockMemberMembers": "Members", + "text.modern_industrialization.StructureMultiblockMemberModeHatch": "Hatch", + "text.modern_industrialization.StructureMultiblockMemberModeInfoHatch": "Hatch Mode - Include hatches", + "text.modern_industrialization.StructureMultiblockMemberModeInfoSimple": "Simple Mode - Just a block", + "text.modern_industrialization.StructureMultiblockMemberModeInfoVariable": "Variable Mode - Filled in at startup", + "text.modern_industrialization.StructureMultiblockMemberModeSimple": "Simple", + "text.modern_industrialization.StructureMultiblockMemberModeVariable": "Variable", + "text.modern_industrialization.StructureMultiblockMemberNBTMode": "NBT Mode:", + "text.modern_industrialization.StructureMultiblockMemberName": "Member Name", + "text.modern_industrialization.StructureMultiblockMemberPreview": "Preview", + "text.modern_industrialization.StructureMultiblockMemberTooltipCasing": "Casing:", + "text.modern_industrialization.StructureMultiblockMemberTooltipHatches": "Hatches:", + "text.modern_industrialization.StructureMultiblockMemberTooltipMembers": "Members:", + "text.modern_industrialization.StructureMultiblockMemberTooltipMode": "Mode: %s", + "text.modern_industrialization.StructureMultiblockMemberTooltipPreview": "Preview:", + "text.modern_industrialization.StructureMultiblockMemberTooltipVariableName": "Name: %s", + "text.modern_industrialization.StructureMultiblockNBTMode": "NBT Mode: %s", + "text.modern_industrialization.StructureMultiblockSaveFailInvalidBounds": "Failed to save structure. The bounds provided are not valid.", + "text.modern_industrialization.StructureMultiblockSaveFailMisconfiguredBlock": "Failed to save structure. Some blocks are not properly configured.", + "text.modern_industrialization.StructureMultiblockSaveFailNoController": "Failed to save structure. No controller could be found within the bounds.", + "text.modern_industrialization.StructureMultiblockSaveFailNoHatches": "Failed to save structure. No hatches could be found within the bounds.", + "text.modern_industrialization.StructureMultiblockSaveFailTooManyControllers": "Failed to save structure. Too many controllers exist within the bounds.", + "text.modern_industrialization.StructureMultiblockSaveFailUnknown": "Failed to save structure. See logs for more info.", + "text.modern_industrialization.StructureMultiblockSaveSuccess": "The structure has been saved as %s.", + "text.modern_industrialization.StructureMultiblockStructureName": "Structure Name", + "text.modern_industrialization.StructureMultiblockWrenchAdded": "Added (%s) to the selection", + "text.modern_industrialization.StructureMultiblockWrenchApplied": "Applied selection to the controller", + "text.modern_industrialization.StructureMultiblockWrenchChangedMode": "Set mode to %s", + "text.modern_industrialization.StructureMultiblockWrenchCleared": "Cleared the selection", + "text.modern_industrialization.StructureMultiblockWrenchHelp1": "Block selection:", + "text.modern_industrialization.StructureMultiblockWrenchHelp2": "- Press %s on air to change modes.", + "text.modern_industrialization.StructureMultiblockWrenchHelp3": "- Press %s on a block to add/remove it to/from the selection.", + "text.modern_industrialization.StructureMultiblockWrenchHelp4": "- Press %s + %s on a structure controller to save the selection to the controller.", + "text.modern_industrialization.StructureMultiblockWrenchHelp5": "Clear selection using %s + %s on air.", + "text.modern_industrialization.StructureMultiblockWrenchNBTModeIgnore": "Ignore", + "text.modern_industrialization.StructureMultiblockWrenchNBTModeStrong": "Strong Include", + "text.modern_industrialization.StructureMultiblockWrenchNBTModeWeak": "Weak Include", + "text.modern_industrialization.StructureMultiblockWrenchRemoved": "Removed (%s) from the selection", + "text.modern_industrialization.StructureMultiblockWrenchTooltip": "Selected %s blocks", "text.modern_industrialization.SuperconductorPowerOnly": "Can only connect to Superconductor cables and machines. Must be directly connected to a machine on at least one end of the tunnel.", "text.modern_industrialization.Temperature": "Temperature: %d °C", "text.modern_industrialization.TemperatureMode": "Temperature", diff --git a/src/main/java/aztech/modern_industrialization/api/energy/CableTier.java b/src/main/java/aztech/modern_industrialization/api/energy/CableTier.java index 200659645..55778b2c0 100644 --- a/src/main/java/aztech/modern_industrialization/api/energy/CableTier.java +++ b/src/main/java/aztech/modern_industrialization/api/energy/CableTier.java @@ -188,4 +188,7 @@ public static List allTiers() { KubeJSProxy.instance.fireCableTiersEvent(); } + + public static void init() { + } } diff --git a/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java b/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java index 204a08ef9..8b2be87d4 100644 --- a/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java +++ b/src/main/java/aztech/modern_industrialization/debug/DebugCommands.java @@ -175,7 +175,7 @@ private static int buildMultiblock(CommandSourceStack src, BlockPos controllerPo if (be instanceof MultiblockMachineBlockEntity multiblock) { var shape = multiblock.getActiveShape(); var shapeMatcher = multiblock.createShapeMatcher(); - int updatedBlocks = shapeMatcher.buildMultiblock(src.getLevel()); + int updatedBlocks = shapeMatcher.buildMultiblock(src.getLevel(), false); src.sendSuccess(() -> Component.literal("Successfully built multiblock at position %s. %d blocks updated.".formatted( controllerPos, updatedBlocks)), true); diff --git a/src/main/java/aztech/modern_industrialization/machines/models/MachineCasing.java b/src/main/java/aztech/modern_industrialization/machines/models/MachineCasing.java index e2873b725..f750af503 100644 --- a/src/main/java/aztech/modern_industrialization/machines/models/MachineCasing.java +++ b/src/main/java/aztech/modern_industrialization/machines/models/MachineCasing.java @@ -23,6 +23,7 @@ */ package aztech.modern_industrialization.machines.models; +import com.mojang.serialization.Codec; import java.util.function.Supplier; import net.minecraft.Util; import net.minecraft.network.chat.Component; @@ -32,6 +33,8 @@ import org.jetbrains.annotations.Nullable; public class MachineCasing { + public static final Codec CODEC = ResourceLocation.CODEC.xmap(MachineCasings::get, casing -> casing.key); + public final ResourceLocation key; /** * Not null when registered as an imitation. The actual model might not be an imitation since it is resource pack driven. diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBlockEntity.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBlockEntity.java index 9d5a43bf9..ffe287340 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBlockEntity.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/MultiblockMachineBlockEntity.java @@ -50,7 +50,7 @@ public boolean isShapeValid() { } public ShapeMatcher createShapeMatcher() { - return new ShapeMatcher(level, worldPosition, orientation.facingDirection, getActiveShape()); + return new ShapeMatcher(level, worldPosition, orientation.facingDirection, getActiveShape(), shapeValid); } protected void onRematch(ShapeMatcher shapeMatcher) { diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java index 57ed12ee2..3e95639d8 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java @@ -23,13 +23,14 @@ */ package aztech.modern_industrialization.machines.multiblocks; +import static net.minecraft.core.Direction.*; + import aztech.modern_industrialization.blocks.FastBlockEntity; import aztech.modern_industrialization.machines.components.ShapeValidComponent; import aztech.modern_industrialization.machines.models.MachineCasing; import aztech.modern_industrialization.machines.multiblocks.structure.member.HatchStructureMember; import aztech.modern_industrialization.machines.multiblocks.structure.member.SimpleStructureMember; import aztech.modern_industrialization.machines.multiblocks.structure.member.StructureMember; -import aztech.modern_industrialization.machines.components.ShapeValidComponent; import aztech.modern_industrialization.machines.multiblocks.world.ChunkEventListener; import aztech.modern_industrialization.machines.multiblocks.world.ChunkEventListeners; import java.util.*; From 666681f3ccd10219063db05b48dab7e0efba3683 Mon Sep 17 00:00:00 2001 From: Swedz Date: Sun, 9 Feb 2025 12:52:40 -0500 Subject: [PATCH 89/89] Allow structure void to be used in structures to define literal air --- .../machines/multiblocks/ShapeMatcher.java | 10 ++++++---- .../structure/MIStructureTemplateManager.java | 5 ++++- .../structure/member/HatchStructureMember.java | 3 ++- .../structure/member/LiteralStructureMember.java | 6 +++++- .../structure/member/SimpleStructureMember.java | 2 +- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java index 3e95639d8..7b87702d7 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/ShapeMatcher.java @@ -284,11 +284,13 @@ public int buildMultiblock(Level level, boolean structureBlocks) { var optionalStructureBlock = member.asStructureBlock(pos, structureBlocks); if (optionalStructureBlock.isPresent()) { BlockState state = optionalStructureBlock.get().getFirst(); - FastBlockEntity be = optionalStructureBlock.get().getSecond(); level.setBlockAndUpdate(pos, state); - level.setBlockEntity(be); - be.setChanged(); - be.sync(); + FastBlockEntity be = optionalStructureBlock.get().getSecond(); + if (be != null) { + level.setBlockEntity(be); + be.setChanged(); + be.sync(); + } setBlocks++; continue; } else if (member instanceof SimpleStructureMember simpleMember) { diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java index 5784870e6..67a59cdc7 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/MIStructureTemplateManager.java @@ -127,9 +127,12 @@ public static StructureResult fromWorld(ResourceLocation id, Level level, for (BlockPos pos : BlockPos.betweenClosed(minPos, maxPos)) { BlockState state = toTemplateState(level, pos, level.getBlockState(pos), controllerDirection); - if (state.isAir() || state.is(Blocks.STRUCTURE_VOID)) { + if (state.isAir()) { continue; } + if (state.is(Blocks.STRUCTURE_VOID)) { + state = Blocks.AIR.defaultBlockState(); + } BlockEntity blockEntity = level.getBlockEntity(pos); boolean isIgnoreNBT = ignoreNBTPositions.contains(pos); diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java index c54212a4d..17011bf5f 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/HatchStructureMember.java @@ -40,6 +40,7 @@ import java.util.Optional; import net.minecraft.core.BlockPos; import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; public final class HatchStructureMember extends SimpleStructureMember { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance @@ -79,7 +80,7 @@ public StructureMemberType type() { } @Override - public Optional> asStructureBlock(BlockPos pos, boolean required) { + public Optional> asStructureBlock(BlockPos pos, boolean required) { if (required) { var state = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.asBlock().defaultBlockState(); state = state.setValue(StructureMultiblockMemberBlock.MODE, StructureMemberMode.HATCH); diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java index bc64081b9..2b5fa0b33 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/LiteralStructureMember.java @@ -32,6 +32,7 @@ import java.util.List; import java.util.Optional; import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.Nullable; @@ -59,7 +60,10 @@ public boolean matchesState(BlockState state, @Nullable BlockEntity blockEntity) } @Override - public Optional> asStructureBlock(BlockPos pos, boolean required) { + public Optional> asStructureBlock(BlockPos pos, boolean required) { + if (preview.state().get().isAir()) { + return Optional.of(new Pair<>(Blocks.STRUCTURE_VOID.defaultBlockState(), null)); + } return Optional.empty(); } diff --git a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java index 96661cb38..0578d49db 100644 --- a/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java +++ b/src/main/java/aztech/modern_industrialization/machines/multiblocks/structure/member/SimpleStructureMember.java @@ -82,7 +82,7 @@ public StructureMemberType type() { } @Override - public Optional> asStructureBlock(BlockPos pos, boolean required) { + public Optional> asStructureBlock(BlockPos pos, boolean required) { if (required) { var state = MIBlock.STRUCTURE_MULTIBLOCK_MEMBER.asBlock().defaultBlockState(); state = state.setValue(StructureMultiblockMemberBlock.MODE, StructureMemberMode.SIMPLE);