Skip to content

Commit

Permalink
re-fix: A more reliable way to fix the Stair Shape Mirroring via a Mi…
Browse files Browse the repository at this point in the history
…xin into the Stairs Block Mirror function.
  • Loading branch information
sakura-ryoko committed Dec 21, 2024
1 parent c8650e5 commit 8d6932f
Show file tree
Hide file tree
Showing 11 changed files with 1,949 additions and 2,003 deletions.
2 changes: 2 additions & 0 deletions src/main/java/fi/dy/masa/litematica/config/Configs.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ public static class Generic
public static final ConfigBoolean EXECUTE_REQUIRE_TOOL = new ConfigBoolean("executeRequireHoldingTool", true).apply(GENERIC_KEY);
public static final ConfigBoolean FIX_CHEST_MIRROR = new ConfigBoolean("fixChestMirror", true).apply(GENERIC_KEY);
public static final ConfigBoolean FIX_RAIL_ROTATION = new ConfigBoolean("fixRailRotation", true).apply(GENERIC_KEY);
public static final ConfigBoolean FIX_STAIRS_MIRROR = new ConfigBoolean("fixStairsMirror", true).apply(GENERIC_KEY);
public static final ConfigBoolean GENERATE_LOWERCASE_NAMES = new ConfigBoolean("generateLowercaseNames", false).apply(GENERIC_KEY);
public static final ConfigBoolean HIGHLIGHT_BLOCK_IN_INV = new ConfigBoolean("highlightBlockInInventory", false).apply(GENERIC_KEY);
public static final ConfigBoolean ITEM_USE_PACKET_CHECK_BYPASS= new ConfigBoolean("itemUsePacketCheckBypass", true).apply(GENERIC_KEY);
Expand Down Expand Up @@ -130,6 +131,7 @@ public static class Generic
EXECUTE_REQUIRE_TOOL,
FIX_CHEST_MIRROR,
FIX_RAIL_ROTATION,
FIX_STAIRS_MIRROR,
GENERATE_LOWERCASE_NAMES,
HIGHLIGHT_BLOCK_IN_INV,
ITEM_USE_PACKET_CHECK_BYPASS,
Expand Down
71 changes: 71 additions & 0 deletions src/main/java/fi/dy/masa/litematica/mixin/MixinStairsBlock.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package fi.dy.masa.litematica.mixin;

import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.StairsBlock;
import net.minecraft.block.enums.StairShape;
import net.minecraft.util.BlockMirror;
import net.minecraft.util.BlockRotation;
import net.minecraft.util.math.Direction;
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.CallbackInfoReturnable;

import fi.dy.masa.litematica.config.Configs;

import static net.minecraft.block.StairsBlock.FACING;
import static net.minecraft.block.StairsBlock.SHAPE;

@Mixin(StairsBlock.class)
public abstract class MixinStairsBlock extends Block
{
public MixinStairsBlock(Settings settings)
{
super(settings);
}

@Inject(method = "mirror", at = @At(value = "HEAD"), cancellable = true)
private void litematica_fixStairsMirror(BlockState state, BlockMirror mirror, CallbackInfoReturnable<BlockState> cir)
{
if (Configs.Generic.FIX_STAIRS_MIRROR.getBooleanValue())
{
Direction direction = state.get(FACING);
StairShape stairShape = state.get(SHAPE);

// Fixes X Axis for FRONT_BACK being inverted for INNER_LEFT / INNER_RIGHT
if (direction.getAxis() == Direction.Axis.X && mirror == BlockMirror.FRONT_BACK)
{
cir.setReturnValue(
switch (stairShape)
{
case INNER_LEFT -> state.rotate(BlockRotation.CLOCKWISE_180).with(SHAPE, StairShape.INNER_RIGHT);
case INNER_RIGHT -> state.rotate(BlockRotation.CLOCKWISE_180).with(SHAPE, StairShape.INNER_LEFT);
case OUTER_LEFT -> state.rotate(BlockRotation.CLOCKWISE_180).with(SHAPE, StairShape.OUTER_RIGHT);
case OUTER_RIGHT -> state.rotate(BlockRotation.CLOCKWISE_180).with(SHAPE, StairShape.OUTER_LEFT);
default -> state.rotate(BlockRotation.CLOCKWISE_180);
}
);

cir.cancel();
}
// Fixes missing Axis STAIR_SHAPE flips
else if ((direction.getAxis() == Direction.Axis.X && mirror == BlockMirror.LEFT_RIGHT) ||
(direction.getAxis() == Direction.Axis.Z && mirror == BlockMirror.FRONT_BACK))
{
cir.setReturnValue(
switch (stairShape)
{
case INNER_LEFT -> state.with(SHAPE, StairShape.INNER_RIGHT);
case INNER_RIGHT -> state.with(SHAPE, StairShape.INNER_LEFT);
case OUTER_LEFT -> state.with(SHAPE, StairShape.OUTER_RIGHT);
case OUTER_RIGHT -> state.with(SHAPE, StairShape.OUTER_LEFT);
default -> state;
}
);

cir.cancel();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -221,73 +221,10 @@ public static boolean placeBlocksWithinChunk(World world, ChunkPos chunkPos, Str
continue;
}

// Fix Stair Rotation / Mirroring
StairShape stairShape = null;

if (state.getBlock() instanceof StairsBlock && mirrorMain != BlockMirror.NONE)
{
stairShape = state.get(Properties.STAIR_SHAPE);
/*
System.out.printf("placeBlocksWithinChunk() - STAIRS: pre-Mirror:0: pos: [%s] // state [%s]\n",
pos.toShortString(), state.toString());
*/
}

if (mirrorMain != BlockMirror.NONE) { state = state.mirror(mirrorMain); }
if (mirrorSub != BlockMirror.NONE) { state = state.mirror(mirrorSub); }
if (rotationCombined != BlockRotation.NONE) { state = state.rotate(rotationCombined); }

if (state.getBlock() instanceof StairsBlock && stairShape != null)
{
/*
System.out.printf("placeBlocksWithinChunk() - STAIRS:post-Mirror:1: pos: [%s] // state [%s] (ORG Shape: %s)\n",
pos.toShortString(), state.toString(),
stairShape.name());
*/

if (mirrorMain != BlockMirror.NONE && stairShape != StairShape.STRAIGHT)
{
StairShape newShape = IMixinStairsBlock.litematica_invokeGetStairShape(state, world, pos);

// Best case scenario, and don't cross Outer/Inner types
if (newShape != StairShape.STRAIGHT &&
!((stairShape == StairShape.INNER_LEFT || stairShape == StairShape.INNER_RIGHT) &&
newShape == StairShape.OUTER_LEFT || newShape == StairShape.OUTER_RIGHT) &&
!((stairShape == StairShape.OUTER_LEFT || stairShape == StairShape.OUTER_RIGHT) &&
newShape == StairShape.INNER_LEFT || newShape == StairShape.INNER_RIGHT)
)
{
state = state.with(StairsBlock.SHAPE, newShape);
}
else
{
// Flip Shape if Invoker fails (It works? :)
if (stairShape == StairShape.INNER_LEFT)
{
state = state.with(StairsBlock.SHAPE, StairShape.INNER_RIGHT);
}
else if (stairShape == StairShape.INNER_RIGHT)
{
state = state.with(StairsBlock.SHAPE, StairShape.INNER_LEFT);
}
else if (stairShape == StairShape.OUTER_LEFT)
{
state = state.with(StairsBlock.SHAPE, StairShape.OUTER_RIGHT);
}
else if (stairShape == StairShape.OUTER_RIGHT)
{
state = state.with(StairsBlock.SHAPE, StairShape.OUTER_LEFT);
}
}
}

/*
System.out.printf("placeBlocksWithinChunk() - STAIRS:post-Mirror:2: pos: [%s] // state [%s] (ORG Shape: %s)\n",
pos.toShortString(), state.toString(),
stairShape.name());
*/
}

BlockEntity te = world.getBlockEntity(pos);

if (te != null)
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/assets/litematica/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"litematica.config.generic.name.executeRequireHoldingTool": "executeRequireHoldingTool",
"litematica.config.generic.name.fixChestMirror": "fixChestMirror",
"litematica.config.generic.name.fixRailRotation": "fixRailRotation",
"litematica.config.generic.name.fixStairsMirror": "fixStairsMirror",
"litematica.config.generic.name.generateLowercaseNames": "generateLowercaseNames",
"litematica.config.generic.name.highlightBlockInInventory": "highlightBlockInInventory",
"litematica.config.generic.name.itemUsePacketCheckBypass": "itemUsePacketCheckBypass",
Expand Down Expand Up @@ -263,6 +264,7 @@
"litematica.config.generic.comment.executeRequireHoldingTool": "Require holding an enabled tool item\nfor the executeOperation hotkey to work",
"litematica.config.generic.comment.fixChestMirror": "Enable a fix to the broken chest mirror code in vanilla",
"litematica.config.generic.comment.fixRailRotation": "If true, then a fix is applied for the vanilla bug in rails,\nwhere the 180 degree rotations of straight north-south and\neast-west rails rotate 90 degrees counterclockwise instead >_>",
"litematica.config.generic.comment.fixStairsMirror": "If true, then a fix is applied for the vanilla bug in stairs,\nwhere the Stair Shapes are not handled correctly depending\non which Block Facing Axis they are oriented upon.",
"litematica.config.generic.comment.generateLowercaseNames": "If enabled, then by default the suggested schematic names\nwill be lowercase and using underscores instead of spaces",
"litematica.config.generic.comment.highlightBlockInInventory": "When enabled, highlights the item (including Shulker Boxes containing it)\nof the looked at block in the schematic",
"litematica.config.generic.comment.itemUsePacketCheckBypass": "Bypass the new distance/coordinate check that was added in 1.18.2.\n\nThat check breaks the \"accurate placement protocol\" and causes\nany blocks placed with a rotation (or other property) request to just become ghost blocks.\n\nThere is basically no need to ever disable this.\nThe check didn't even exist ever before 1.18.2.",
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/assets/litematica/lang/es_es.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"litematica.config.generic.name.executeRequireHoldingTool": "Requiere Sostener Herramienta para Ejecutar",
"litematica.config.generic.name.fixChestMirror": "Corregir Espejo de Cofre",
"litematica.config.generic.name.fixRailRotation": "Corregir Rotación de Riel",
"litematica.config.generic.name.fixStairsMirror": "fixStairsMirror",
"litematica.config.generic.name.generateLowercaseNames": "Generar Nombres en Minúsculas",
"litematica.config.generic.name.highlightBlockInInventory": "Resaltar Bloque en Inventario",
"litematica.config.generic.name.itemUsePacketCheckBypass": "Eliminar Chequeo de Paquete de Uso de Elemento",
Expand Down Expand Up @@ -258,6 +259,7 @@
"litematica.config.generic.comment.executeRequireHoldingTool": "Requiere tener un elemento herramienta Habilatado\npara que la tecla de acceso rápido executeOperation funcione",
"litematica.config.generic.comment.fixChestMirror": "Habilita una solución al código de espejo de cofre roto en vanilla",
"litematica.config.generic.comment.fixRailRotation": "Si es verdadero, entonces se aplica una solución al error de rails en vanilla,\nde donde la rotación de 180 grados de rieles norte-sur y\neast-west gira 90 grados en sentido antihorario en lugar >_>",
"litematica.config.generic.comment.fixStairsMirror": "If true, then a fix is applied for the vanilla bug in stairs,\nwhere the Stair Shapes are not handled correctly depending\non which Block Facing Axis they are oriented upon.",
"litematica.config.generic.comment.generateLowercaseNames": "Si está Habilatado, entonces por defecto los nombres de esquema sugeridos\nserán en minúsculas y usarán guiones bajos en lugar de espacios",
"litematica.config.generic.comment.highlightBlockInInventory": "Cuando está Habilatado, resalta el artículo (incluyendo las Cajas Shulker que lo contienen)\ndel bloque observado en el esquema",
"litematica.config.generic.comment.itemUsePacketCheckBypass": "Elimina la nueva verificación de distancia/coordenada que fue añadida en 1.18.2.\n\nDicha verificación rompe el \"protocolo de colocación precisa\" y causa\ntu bloques colocados con una rotación (u otra propiedad) solicitud se conviertan en bloques fantasma.\n\nBásicamente, no hay necesidad de desactivar esto nunca.\nLa verificación ni siquiera existió antes de 1.18.2.",
Expand Down
5 changes: 4 additions & 1 deletion src/main/resources/assets/litematica/lang/it_it.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"litematica.config.generic.name.executeRequireHoldingTool": "eseguireRichiedeStrumentoInMano",
"litematica.config.generic.name.fixChestMirror": "correggiSpecchioCassa",
"litematica.config.generic.name.fixRailRotation": "correggiRotazioneBinario",
"litematica.config.generic.name.fixStairsMirror": "fixStairsMirror",
"litematica.config.generic.name.generateLowercaseNames": "generaNomiMinuscoli",
"litematica.config.generic.name.highlightBlockInInventory": "evidenziaBloccoInInventario",
"litematica.config.generic.name.itemUsePacketCheckBypass": "bypassControlloPacchettoUsoOggetto",
Expand Down Expand Up @@ -258,6 +259,7 @@
"litematica.config.generic.comment.executeRequireHoldingTool": "Richiedi di tenere un oggetto strumento abilitato\nper far funzionare il tasto di scelta rapida executeOperation.",
"litematica.config.generic.comment.fixChestMirror": "Abilita una correzione per il codice di specchiatura delle casse\nrotto nella versione Vanilla.",
"litematica.config.generic.comment.fixRailRotation": "Se vero, viene applicata una correzione per il bug Vanilla nelle rotaie,\nnel quale le rotazioni a 180 gradi delle rotaie dritte nord-sud e\neast-west ruotano di 90 gradi in senso antiorario invece di ruotare di 180 gradi.",
"litematica.config.generic.comment.fixStairsMirror": "If true, then a fix is applied for the vanilla bug in stairs,\nwhere the Stair Shapes are not handled correctly depending\non which Block Facing Axis they are oriented upon.",
"litematica.config.generic.comment.generateLowercaseNames": "Se abilitato, i nomi degli schemi suggeriti saranno\nper impostazione predefinita in minuscolo e con l'uso di underscore invece di spazi.",
"litematica.config.generic.comment.highlightBlockInInventory": "Se abilitato, evidenzia l'oggetto (compresi i Shulker Boxes che lo contengono)\ndel blocco osservato nello schema.",
"litematica.config.generic.comment.itemUsePacketCheckBypass": "Ignora il nuovo controllo distanza/coordinata aggiunto in 1.18.2.\n\nQuesto controllo rompe il \"protocollo di posizionamento accurato\" e causa\nche i blocchi posizionati con una richiesta di rotazione (o altra proprietà) diventino solo blocchi fantasma.\n\nNon c'è praticamente nessun motivo per disabilitare questa opzione.\nIl controllo non è mai esistito prima della versione 1.18.2.",
Expand Down Expand Up @@ -922,5 +924,6 @@
"litematica.tool_mode.name.paste_schematic": "Incolla Schema nel mondo",
"litematica.tool_mode.name.rebuild": "Modifica Schema",
"litematica.tool_mode.name.replace_block": "Sostituisci blocco",
"litematica.tool_mode.name.schematic_placement": "Posizionamento Schema"
"litematica.tool_mode.name.schematic_placement": "Posizionamento Schema",
"modmenu.descriptionTranslation.litematica": "Modern mod schematic for LiteLoader, Rift, Fabric, etc."
}
5 changes: 4 additions & 1 deletion src/main/resources/assets/litematica/lang/ja_jp.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"litematica.config.generic.name.executeRequireHoldingTool": "executeRequireHoldingTool",
"litematica.config.generic.name.fixChestMirror": "fixChestMirror",
"litematica.config.generic.name.fixRailRotation": "fixRailRotation",
"litematica.config.generic.name.fixStairsMirror": "fixStairsMirror",
"litematica.config.generic.name.generateLowercaseNames": "generateLowercaseNames",
"litematica.config.generic.name.highlightBlockInInventory": "highlightBlockInInventory",
"litematica.config.generic.name.itemUsePacketCheckBypass": "itemUsePacketCheckBypass",
Expand Down Expand Up @@ -258,6 +259,7 @@
"litematica.config.generic.comment.executeRequireHoldingTool": "Require holding an enabled tool item\nfor the executeOperation hotkey to work",
"litematica.config.generic.comment.fixChestMirror": "Enable a fix to the broken chest mirror code in vanilla",
"litematica.config.generic.comment.fixRailRotation": "If true, then a fix is applied for the vanilla bug in rails,\nwhere the 180 degree rotations of straight north-south and\neast-west rails rotate 90 degrees counterclockwise instead >_>",
"litematica.config.generic.comment.fixStairsMirror": "If true, then a fix is applied for the vanilla bug in stairs,\nwhere the Stair Shapes are not handled correctly depending\non which Block Facing Axis they are oriented upon.",
"litematica.config.generic.comment.generateLowercaseNames": "If enabled, then by default the suggested schematic names\nwill be lowercase and using underscores instead of spaces",
"litematica.config.generic.comment.highlightBlockInInventory": "When enabled, highlights the item (including Shulker Boxes containing it)\nof the looked at block in the schematic",
"litematica.config.generic.comment.itemUsePacketCheckBypass": "Bypass the new distance/coordinate check that was added in 1.18.2.\n\nThat check breaks the \"accurate placement protocol\" and causes\nany blocks placed with a rotation (or other property) request to just become ghost blocks.\n\nThere is basically no need to ever disable this.\nThe check didn't even exist ever before 1.18.2.",
Expand Down Expand Up @@ -922,5 +924,6 @@
"litematica.tool_mode.name.paste_schematic": "スキーマティックをワールドにペースト",
"litematica.tool_mode.name.rebuild": "スキーマティックの編集",
"litematica.tool_mode.name.replace_block": "ブロックを置換",
"litematica.tool_mode.name.schematic_placement": "スキーマティックの配置"
"litematica.tool_mode.name.schematic_placement": "スキーマティックの配置",
"modmenu.descriptionTranslation.litematica": "Modern mod schematic for LiteLoader, Rift, Fabric, etc."
}
Loading

0 comments on commit 8d6932f

Please sign in to comment.