Skip to content

Commit

Permalink
Fix copycat doors not being placed correctly by schematics
Browse files Browse the repository at this point in the history
  • Loading branch information
hlysine committed Oct 31, 2024
1 parent 40614e9 commit 1ed2473
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.simibubi.create.content.redstone.RoseQuartzLampBlock;
import com.simibubi.create.content.schematics.requirement.ISpecialBlockEntityItemRequirement;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.foundation.blockEntity.IMergeableBE;
import com.simibubi.create.foundation.utility.IPartialSafeNBT;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.MethodsReturnNonnullByDefault;
Expand Down Expand Up @@ -45,7 +46,7 @@
*/
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
public interface ICopycatBlockEntity extends ISpecialBlockEntityItemRequirement, ITransformableBlockEntity, IPartialSafeNBT {
public interface ICopycatBlockEntity extends ISpecialBlockEntityItemRequirement, ITransformableBlockEntity, IPartialSafeNBT, IMergeableBE {

void notifyUpdate();

Expand Down Expand Up @@ -168,6 +169,16 @@ default ItemRequirement getRequiredItems(BlockState state) {
return new ItemRequirement(ItemRequirement.ItemUseType.CONSUME, getConsumedItem());
}

@Override
default void accept(BlockEntity other) {
if (other instanceof ICopycatBlockEntity be) {
setMaterial(be.getMaterial());
setConsumedItem(be.getConsumedItem());
setCTEnabled(be.isCTEnabled());
BlockEntityUtils.redraw((BlockEntity) this);
}
}

@Override
default void transform(StructureTransform transform) {
setMaterialInternal(transform.apply(getMaterial()));
Expand Down Expand Up @@ -211,6 +222,7 @@ static void read(ICopycatBlockEntity self, CompoundTag tag, boolean clientPacket
static void writeSafe(ICopycatBlockEntity self, CompoundTag tag) {
ItemStack stackWithoutNBT = self.getConsumedItem().copy();
stackWithoutNBT.setTag(null);
BlockEntityUtils.saveMetadata((BlockEntity) self, tag);
write(tag, stackWithoutNBT, self.getMaterial(), self.isCTEnabled());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ static void read(IMultiStateCopycatBlockEntity self, CompoundTag tag, boolean cl
}

static void writeSafe(IMultiStateCopycatBlockEntity self, CompoundTag tag) {
BlockEntityUtils.saveMetadata((BlockEntity) self, tag);
tag.put("material_data", self.getMaterialItemStorage().serializeSafe());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.copycatsplus.copycats.mixin.copycat.door;

import com.simibubi.create.foundation.utility.BlockHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
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;

/**
* Fix a hidden bug in Create which causes a crash due to missing ID when merging block entities in schematic printing.
*/
@Mixin(BlockHelper.class)
public class BlockHelperMixin {
@Inject(
method = "placeSchematicBlock",
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/entity/BlockEntity;loadStatic(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/nbt/CompoundTag;)Lnet/minecraft/world/level/block/entity/BlockEntity;")
)
private static void placeSchematicBlock(Level world, BlockState state, BlockPos target, ItemStack stack, CompoundTag data, CallbackInfo ci) {
BlockEntity existingBlockEntity = world.getBlockEntity(target);
if (existingBlockEntity != null && existingBlockEntity.getBlockState().getBlock().equals(state.getBlock())) {
ResourceLocation resourceLocation = BlockEntityType.getKey(existingBlockEntity.getType());
assert resourceLocation != null;
data.putString("id", resourceLocation.toString());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.copycatsplus.copycats.mixin.copycat.door;

import com.copycatsplus.copycats.foundation.copycat.ICopycatBlock;
import com.copycatsplus.copycats.foundation.copycat.ICopycatBlockEntity;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.simibubi.create.content.schematics.cannon.SchematicannonBlockEntity;
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.level.block.state.properties.DoubleBlockHalf;
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 static net.minecraft.world.level.block.state.properties.BlockStateProperties.DOUBLE_BLOCK_HALF;

/**
* Force the schematicannon to place both the upper and lower halves of copycat doors
*/
@Mixin(SchematicannonBlockEntity.class)
public class SchematicannonBlockEntityMixin {
@Inject(
method = "shouldIgnoreBlockState",
at = @At("RETURN"),
cancellable = true
)
private void shouldIgnoreBlockStateMixin(BlockState state, BlockEntity be, CallbackInfoReturnable<Boolean> cir) {
if (state.hasProperty(DOUBLE_BLOCK_HALF) && be instanceof ICopycatBlockEntity) {
cir.setReturnValue(false);
}
}

/**
* Make an exception for the "protect block entities" setting so that the upper half of a copycat door can be placed
*/
@WrapOperation(
method = "shouldPlace",
at = @At(value = "FIELD", target = "Lcom/simibubi/create/content/schematics/cannon/SchematicannonBlockEntity;replaceBlockEntities:Z")
)
private boolean shouldPlace(SchematicannonBlockEntity instance, Operation<Boolean> original, BlockPos pos, BlockState state, BlockEntity be, BlockState toReplace,
BlockState toReplaceOther, boolean isNormalCube) {
boolean originalReplace = original.call(instance);
return originalReplace || (state.getBlock() instanceof ICopycatBlock && state.hasProperty(DOUBLE_BLOCK_HALF) && state.getValue(DOUBLE_BLOCK_HALF) == DoubleBlockHalf.UPPER);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.copycatsplus.copycats.mixin.foundation.copycat;

import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.block.entity.BlockEntity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;

@Mixin(BlockEntity.class)
public interface BlockEntityAccessor {
@Invoker
void callSaveMetadata(CompoundTag tag);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import com.copycatsplus.copycats.foundation.copycat.CopycatMaterialStore;
import com.copycatsplus.copycats.foundation.copycat.ICopycatBlockEntity;
import com.copycatsplus.copycats.foundation.copycat.multistate.IMultiStateCopycatBlockEntity;
import com.copycatsplus.copycats.mixin.foundation.copycat.BlockEntityAccessor;
import dev.architectury.injectables.annotations.ExpectPlatform;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.profiling.ProfilerFiller;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
Expand Down Expand Up @@ -38,6 +40,10 @@ public static void redraw(BlockEntity blockEntity) {
}
}

public static void saveMetadata(BlockEntity blockEntity, CompoundTag tag) {
((BlockEntityAccessor) blockEntity).callSaveMetadata(tag);
}

@ExpectPlatform
public static void requestModelDataUpdate(BlockEntity blockEntity) {

Expand Down
3 changes: 3 additions & 0 deletions common/src/main/resources/copycats-common.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
"compat.rubidium.BlockRendererMixin",
"copycat.VoxelShapeAccessor",
"copycat.cogwheel.CogWheelBlockItemMixin",
"copycat.door.BlockHelperMixin",
"copycat.door.SchematicannonBlockEntityMixin",
"copycat.fluid_pipe.FluidPipeBlockMixin",
"copycat.panel.CopycatPanelBlockMixin",
"copycat.slab.SeatMovementBehaviourMixin",
Expand All @@ -23,6 +25,7 @@
"entity.CatMixin",
"feature_toggle.CreativeModeTabsAccessor",
"foundation.copycat.BearingContraptionMixin",
"foundation.copycat.BlockEntityAccessor",
"foundation.copycat.BlockMixin",
"foundation.copycat.BlockStateBaseCacheMixin",
"foundation.copycat.BlockStateBaseMixin",
Expand Down

0 comments on commit 1ed2473

Please sign in to comment.