diff --git a/src/generated/resources/data/extendedae_plus/advancements/recipes/misc/mirror_pattern_binding_tool.json b/src/generated/resources/data/extendedae_plus/advancements/recipes/misc/mirror_pattern_binding_tool.json new file mode 100644 index 0000000..3e4b048 --- /dev/null +++ b/src/generated/resources/data/extendedae_plus/advancements/recipes/misc/mirror_pattern_binding_tool.json @@ -0,0 +1,35 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_mirror_pattern_binding_tool": { + "conditions": { + "items": [ + { + "items": [ + "extendedae_plus:mirror_pattern_binding_tool" + ] + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "extendedae_plus:mirror_pattern_binding_tool" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_mirror_pattern_binding_tool", + "has_the_recipe" + ] + ], + "rewards": { + "recipes": [ + "extendedae_plus:mirror_pattern_binding_tool" + ] + }, + "sends_telemetry_event": false +} \ No newline at end of file diff --git a/src/generated/resources/data/extendedae_plus/advancements/recipes/misc/mirror_pattern_provider.json b/src/generated/resources/data/extendedae_plus/advancements/recipes/misc/mirror_pattern_provider.json new file mode 100644 index 0000000..11ac15e --- /dev/null +++ b/src/generated/resources/data/extendedae_plus/advancements/recipes/misc/mirror_pattern_provider.json @@ -0,0 +1,35 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_mirror_pattern_provider": { + "conditions": { + "items": [ + { + "items": [ + "extendedae_plus:mirror_pattern_provider" + ] + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "extendedae_plus:mirror_pattern_provider" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_mirror_pattern_provider", + "has_the_recipe" + ] + ], + "rewards": { + "recipes": [ + "extendedae_plus:mirror_pattern_provider" + ] + }, + "sends_telemetry_event": false +} \ No newline at end of file diff --git a/src/generated/resources/data/extendedae_plus/recipes/mirror_pattern_binding_tool.json b/src/generated/resources/data/extendedae_plus/recipes/mirror_pattern_binding_tool.json new file mode 100644 index 0000000..75486c8 --- /dev/null +++ b/src/generated/resources/data/extendedae_plus/recipes/mirror_pattern_binding_tool.json @@ -0,0 +1,27 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "key": { + "A": { + "item": "ae2:wireless_receiver" + }, + "B": { + "item": "minecraft:iron_ingot" + }, + "C": { + "item": "minecraft:redstone" + }, + "D": { + "item": "ae2:calculation_processor" + } + }, + "pattern": [ + " A", + "BCD", + "BBB" + ], + "result": { + "item": "extendedae_plus:mirror_pattern_binding_tool" + }, + "show_notification": true +} \ No newline at end of file diff --git a/src/generated/resources/data/extendedae_plus/recipes/mirror_pattern_provider.json b/src/generated/resources/data/extendedae_plus/recipes/mirror_pattern_provider.json new file mode 100644 index 0000000..be0c6b2 --- /dev/null +++ b/src/generated/resources/data/extendedae_plus/recipes/mirror_pattern_provider.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "key": { + "A": { + "item": "minecraft:glass" + }, + "B": { + "item": "ae2:pattern_provider" + } + }, + "pattern": [ + "AAA", + "ABA", + "AAA" + ], + "result": { + "item": "extendedae_plus:mirror_pattern_provider" + }, + "show_notification": true +} \ No newline at end of file diff --git a/src/main/java/com/extendedae_plus/ExtendedAEPlus.java b/src/main/java/com/extendedae_plus/ExtendedAEPlus.java index b401061..d337e25 100644 --- a/src/main/java/com/extendedae_plus/ExtendedAEPlus.java +++ b/src/main/java/com/extendedae_plus/ExtendedAEPlus.java @@ -1,11 +1,13 @@ package com.extendedae_plus; import appeng.api.storage.StorageCells; +import appeng.block.AEBaseEntityBlock; import appeng.menu.locator.MenuLocators; import com.extendedae_plus.api.storage.InfinityBigIntegerCellHandler; import com.extendedae_plus.client.ClientRegistrar; import com.extendedae_plus.client.ModKeybindings; import com.extendedae_plus.config.ModConfig; +import com.extendedae_plus.content.ae2.MirrorPatternProviderBlockEntity; import com.extendedae_plus.content.matrix.CrafterCorePlusBlockEntity; import com.extendedae_plus.content.matrix.PatternCorePlusBlockEntity; import com.extendedae_plus.init.*; @@ -106,6 +108,17 @@ public class ExtendedAEPlus { null ); + ((AEBaseEntityBlock) ModBlocks.MIRROR_PATTERN_PROVIDER.get()).setBlockEntity( + MirrorPatternProviderBlockEntity.class, + ModBlockEntities.MIRROR_PATTERN_PROVIDER_BE.get(), + null, + (level, pos, state, blockEntity) -> MirrorPatternProviderBlockEntity.serverTick( + level, + pos, + state, + (MirrorPatternProviderBlockEntity) blockEntity) + ); + }); } diff --git a/src/main/java/com/extendedae_plus/content/ae2/MirrorPatternProviderBlock.java b/src/main/java/com/extendedae_plus/content/ae2/MirrorPatternProviderBlock.java new file mode 100644 index 0000000..c2d3543 --- /dev/null +++ b/src/main/java/com/extendedae_plus/content/ae2/MirrorPatternProviderBlock.java @@ -0,0 +1,52 @@ +package com.extendedae_plus.content.ae2; + +import appeng.api.implementations.items.IMemoryCard; +import appeng.block.crafting.PatternProviderBlock; +import appeng.util.InteractionUtil; +import net.minecraft.core.BlockPos; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.BlockHitResult; +import org.jetbrains.annotations.Nullable; + +public class MirrorPatternProviderBlock extends PatternProviderBlock { + + @Override + public InteractionResult onActivated(Level level, BlockPos pos, Player player, InteractionHand hand, + @Nullable ItemStack heldItem, BlockHitResult hit) { + var mirror = this.getMirror(level, pos); + if (mirror == null) { + return InteractionResult.PASS; + } + + if (InteractionUtil.isInAlternateUseMode(player)) { + return InteractionResult.PASS; + } + + if (heldItem != null + && (InteractionUtil.canWrenchRotate(heldItem) || heldItem.getItem() instanceof IMemoryCard)) { + if (!level.isClientSide) { + player.displayClientMessage( + net.minecraft.network.chat.Component.translatable( + "extendedae_plus.message.mirror_pattern_provider.readonly"), + true); + } + return InteractionResult.sidedSuccess(level.isClientSide); + } + + if (!level.isClientSide) { + player.displayClientMessage(mirror.getStatusMessage(), true); + } + + return InteractionResult.sidedSuccess(level.isClientSide); + } + + @Nullable + private MirrorPatternProviderBlockEntity getMirror(Level level, BlockPos pos) { + var blockEntity = this.getBlockEntity(level, pos); + return blockEntity instanceof MirrorPatternProviderBlockEntity mirror ? mirror : null; + } +} diff --git a/src/main/java/com/extendedae_plus/content/ae2/MirrorPatternProviderBlockEntity.java b/src/main/java/com/extendedae_plus/content/ae2/MirrorPatternProviderBlockEntity.java new file mode 100644 index 0000000..071fd4e --- /dev/null +++ b/src/main/java/com/extendedae_plus/content/ae2/MirrorPatternProviderBlockEntity.java @@ -0,0 +1,432 @@ +package com.extendedae_plus.content.ae2; + +import appeng.api.config.Settings; +import appeng.api.inventories.InternalInventory; +import appeng.api.networking.IManagedGridNode; +import appeng.block.crafting.PatternProviderBlock; +import appeng.block.crafting.PushDirection; +import appeng.blockentity.crafting.PatternProviderBlockEntity; +import appeng.helpers.patternprovider.PatternProviderLogic; +import appeng.util.CustomNameUtil; +import appeng.util.SettingsFrom; +import appeng.util.inv.AppEngInternalInventory; +import com.extendedae_plus.init.ModBlockEntities; +import net.minecraft.core.BlockPos; +import net.minecraft.core.GlobalPos; +import net.minecraft.core.registries.Registries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.Tag; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; +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.state.BlockState; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.Objects; + +public class MirrorPatternProviderBlockEntity extends PatternProviderBlockEntity { + private static final String TAG_MASTER = "mirrorMaster"; + private static final String TAG_MASTER_DIMENSION = "dimension"; + private static final String TAG_MASTER_POS = "pos"; + private static final int SYNC_INTERVAL = 2; + private static final InternalInventory DISABLED_PATTERN_INVENTORY = new AppEngInternalInventory(0); + + @Nullable + private ResourceKey masterDimension; + + @Nullable + private BlockPos masterPos; + + public MirrorPatternProviderBlockEntity(BlockPos pos, BlockState blockState) { + super(ModBlockEntities.MIRROR_PATTERN_PROVIDER_BE.get(), pos, blockState); + } + + @Override + public boolean isVisibleInTerminal() { + return false; + } + + @Override + public InternalInventory getTerminalPatternInventory() { + return DISABLED_PATTERN_INVENTORY; + } + + @Override + protected PatternProviderLogic createLogic() { + return new MirrorLogic(this.getMainNode(), this); + } + + public static void serverTick(Level level, BlockPos pos, BlockState state, + MirrorPatternProviderBlockEntity blockEntity) { + if (level instanceof ServerLevel serverLevel) { + blockEntity.serverTick(serverLevel); + } + } + + private void serverTick(ServerLevel level) { + if (Math.floorMod(level.getGameTime() + this.getBlockPos().asLong(), SYNC_INTERVAL) != 0) { + return; + } + + this.syncBoundMaster(); + } + + @Override + public void onReady() { + super.onReady(); + if (this.getLevel() instanceof ServerLevel serverLevel) { + this.syncBoundMaster(); + } + } + + @Override + public void saveAdditional(CompoundTag data) { + super.saveAdditional(data); + + if (this.masterDimension != null && this.masterPos != null) { + var masterTag = new CompoundTag(); + masterTag.putString(TAG_MASTER_DIMENSION, this.masterDimension.location().toString()); + masterTag.putLong(TAG_MASTER_POS, this.masterPos.asLong()); + data.put(TAG_MASTER, masterTag); + } else { + data.remove(TAG_MASTER); + } + } + + @Override + public void loadTag(CompoundTag data) { + super.loadTag(data); + + this.masterDimension = null; + this.masterPos = null; + if (data.contains(TAG_MASTER, Tag.TAG_COMPOUND)) { + var masterTag = data.getCompound(TAG_MASTER); + if (masterTag.contains(TAG_MASTER_DIMENSION, Tag.TAG_STRING) + && masterTag.contains(TAG_MASTER_POS, Tag.TAG_LONG)) { + this.masterDimension = ResourceKey.create(Registries.DIMENSION, + new ResourceLocation(masterTag.getString(TAG_MASTER_DIMENSION))); + this.masterPos = BlockPos.of(masterTag.getLong(TAG_MASTER_POS)); + } + } + } + + @Override + public void addAdditionalDrops(Level level, BlockPos pos, List drops) { + var patternInventory = this.getPatternInventory(); + var snapshot = this.copyInventoryContents(patternInventory); + + this.clearInventory(patternInventory); + this.getLogic().updatePatterns(); + super.addAdditionalDrops(level, pos, drops); + + this.restoreInventoryContents(patternInventory, snapshot); + this.getLogic().updatePatterns(); + } + + @Override + public void clearContent() { + this.getLogic().clearContent(); + } + + public boolean bindToMaster(GlobalPos master) { + if (!(this.getLevel() instanceof ServerLevel serverLevel)) { + return false; + } + + if (master.pos().equals(this.getBlockPos()) && master.dimension().equals(serverLevel.dimension())) { + return false; + } + + var masterLevel = serverLevel.getServer().getLevel(master.dimension()); + if (masterLevel != null && masterLevel.hasChunkAt(master.pos())) { + var blockEntity = masterLevel.getBlockEntity(master.pos()); + if (isValidMaster(blockEntity)) { + return this.syncFromMaster((PatternProviderBlockEntity) blockEntity); + } + return false; + } + + var changed = !Objects.equals(this.masterDimension, master.dimension()) + || !Objects.equals(this.masterPos, master.pos()); + this.masterDimension = master.dimension(); + this.masterPos = master.pos().immutable(); + if (changed) { + this.saveChanges(); + this.markForUpdate(); + } + return true; + } + + @Nullable + public PatternProviderBlockEntity getMaster() { + if (this.masterDimension == null || this.masterPos == null || !(this.getLevel() instanceof ServerLevel serverLevel)) { + return null; + } + + var masterLevel = this.getMasterLevel(serverLevel); + if (masterLevel == null || !masterLevel.hasChunkAt(this.masterPos)) { + return null; + } + + var blockEntity = masterLevel.getBlockEntity(this.masterPos); + return isValidMaster(blockEntity) ? (PatternProviderBlockEntity) blockEntity : null; + } + + public Component createBoundMessage() { + if (this.masterPos != null) { + return Component.translatable( + "extendedae_plus.message.mirror_pattern_provider.bound", + this.masterPos.getX(), + this.masterPos.getY(), + this.masterPos.getZ()); + } + + return Component.translatable("extendedae_plus.message.mirror_pattern_provider.missing_master"); + } + + public Component getStatusMessage() { + if (this.masterPos != null) { + return Component.translatable( + "extendedae_plus.message.mirror_pattern_provider.following", + this.masterPos.getX(), + this.masterPos.getY(), + this.masterPos.getZ()); + } + + return Component.translatable("extendedae_plus.message.mirror_pattern_provider.missing_master"); + } + + private void syncBoundMaster() { + var master = this.getMaster(); + if (master != null) { + this.syncFromMaster(master); + return; + } + + if (this.shouldClearBrokenBinding()) { + this.clearMasterBinding(true); + } + } + + private boolean shouldClearBrokenBinding() { + if (this.masterDimension == null || this.masterPos == null || !(this.getLevel() instanceof ServerLevel serverLevel)) { + return true; + } + + var masterLevel = this.getMasterLevel(serverLevel); + if (masterLevel == null || !masterLevel.hasChunkAt(this.masterPos)) { + return false; + } + + return !isValidMaster(masterLevel.getBlockEntity(this.masterPos)); + } + + private void clearMasterBinding(boolean clearMirroredPatterns) { + var hadBinding = this.masterDimension != null || this.masterPos != null; + + this.masterDimension = null; + this.masterPos = null; + + var changed = hadBinding; + if (clearMirroredPatterns) { + changed |= this.clearMirroredPatterns(); + } + + if (changed) { + this.saveChanges(); + this.markForUpdate(); + } + } + + private boolean bindToMaster(PatternProviderBlockEntity master) { + var masterLevel = master.getLevel(); + if (masterLevel == null) { + return false; + } + + var newDimension = masterLevel.dimension(); + var newPos = master.getBlockPos().immutable(); + var changed = !Objects.equals(this.masterDimension, newDimension) || !Objects.equals(this.masterPos, newPos); + + this.masterDimension = newDimension; + this.masterPos = newPos; + + return changed; + } + + private boolean syncFromMaster(PatternProviderBlockEntity master) { + var changed = this.bindToMaster(master); + changed |= this.syncMirroredSettings(master); + changed |= this.syncMirroredPatterns(master); + + if (changed) { + this.saveChanges(); + this.markForUpdate(); + } + + return changed; + } + + private boolean syncMirroredSettings(PatternProviderBlockEntity master) { + if (!this.hasDifferentMirroredSettings(master)) { + return false; + } + + var settingsTag = new CompoundTag(); + master.getLogic().getConfigManager().writeToNBT(settingsTag); + settingsTag.putByte(PatternProviderBlock.PUSH_DIRECTION.getName(), + (byte) master.getBlockState().getValue(PatternProviderBlock.PUSH_DIRECTION).ordinal()); + CustomNameUtil.setCustomName(settingsTag, master.getCustomName()); + + super.importSettings(SettingsFrom.MEMORY_CARD, settingsTag, null); + this.getLogic().getConfigManager().readFromNBT(settingsTag); + + if (this.getPriority() != master.getPriority()) { + this.setPriority(master.getPriority()); + } + + return true; + } + + private boolean hasDifferentMirroredSettings(PatternProviderBlockEntity master) { + var mirrorLogic = this.getLogic(); + var masterLogic = master.getLogic(); + + return !Objects.equals(this.getCustomName(), master.getCustomName()) + || this.getPriority() != master.getPriority() + || mirrorLogic.getConfigManager().getSetting(Settings.BLOCKING_MODE) + != masterLogic.getConfigManager().getSetting(Settings.BLOCKING_MODE) + || mirrorLogic.getConfigManager().getSetting(Settings.PATTERN_ACCESS_TERMINAL) + != masterLogic.getConfigManager().getSetting(Settings.PATTERN_ACCESS_TERMINAL) + || mirrorLogic.getConfigManager().getSetting(Settings.LOCK_CRAFTING_MODE) + != masterLogic.getConfigManager().getSetting(Settings.LOCK_CRAFTING_MODE) + || this.getBlockState().getValue(PatternProviderBlock.PUSH_DIRECTION) + != master.getBlockState().getValue(PatternProviderBlock.PUSH_DIRECTION); + } + + private boolean syncMirroredPatterns(PatternProviderBlockEntity master) { + var mirrorInventory = this.getPatternInventory(); + var masterInventory = asPatternInventory(master.getLogic().getPatternInv()); + + if (this.hasSamePatterns(masterInventory, mirrorInventory)) { + return false; + } + + this.clearInventory(mirrorInventory); + for (int slot = 0; slot < masterInventory.size(); slot++) { + mirrorInventory.setItemDirect(slot, masterInventory.getStackInSlot(slot).copy()); + } + this.getLogic().updatePatterns(); + return true; + } + + private boolean clearMirroredPatterns() { + var patternInventory = this.getPatternInventory(); + if (this.isPatternInventoryEmpty(patternInventory)) { + return false; + } + + this.clearInventory(patternInventory); + this.getLogic().updatePatterns(); + return true; + } + + private boolean hasSamePatterns(AppEngInternalInventory masterInventory, AppEngInternalInventory mirrorInventory) { + if (masterInventory.size() != mirrorInventory.size()) { + return false; + } + + for (int slot = 0; slot < masterInventory.size(); slot++) { + if (!sameStack(masterInventory.getStackInSlot(slot), mirrorInventory.getStackInSlot(slot))) { + return false; + } + } + + return true; + } + + private boolean isPatternInventoryEmpty(AppEngInternalInventory inventory) { + for (int slot = 0; slot < inventory.size(); slot++) { + if (!inventory.getStackInSlot(slot).isEmpty()) { + return false; + } + } + + return true; + } + + private AppEngInternalInventory getPatternInventory() { + return ((MirrorLogic) this.getLogic()).getActualPatternInventory(); + } + + private ItemStack[] copyInventoryContents(AppEngInternalInventory inventory) { + var contents = new ItemStack[inventory.size()]; + for (int slot = 0; slot < inventory.size(); slot++) { + contents[slot] = inventory.getStackInSlot(slot).copy(); + } + return contents; + } + + private void restoreInventoryContents(AppEngInternalInventory inventory, ItemStack[] contents) { + this.clearInventory(inventory); + for (int slot = 0; slot < inventory.size(); slot++) { + inventory.setItemDirect(slot, contents[slot].copy()); + } + } + + private void clearInventory(AppEngInternalInventory inventory) { + for (int slot = 0; slot < inventory.size(); slot++) { + inventory.setItemDirect(slot, ItemStack.EMPTY); + } + } + + @Nullable + private ServerLevel getMasterLevel(ServerLevel serverLevel) { + if (serverLevel.dimension() == this.masterDimension) { + return serverLevel; + } + return serverLevel.getServer().getLevel(this.masterDimension); + } + + private static AppEngInternalInventory asPatternInventory(Object inventory) { + return (AppEngInternalInventory) inventory; + } + + private static boolean sameStack(ItemStack left, ItemStack right) { + if (left.isEmpty() && right.isEmpty()) { + return true; + } + + return ItemStack.isSameItemSameTags(left, right) && left.getCount() == right.getCount(); + } + + public static boolean isSupportedMaster(@Nullable BlockEntity blockEntity) { + return blockEntity != null + && blockEntity.getClass() == PatternProviderBlockEntity.class + && !blockEntity.isRemoved(); + } + + private static boolean isValidMaster(@Nullable BlockEntity blockEntity) { + return isSupportedMaster(blockEntity); + } + + private static final class MirrorLogic extends PatternProviderLogic { + private MirrorLogic(IManagedGridNode mainNode, MirrorPatternProviderBlockEntity mirrorHost) { + super(mainNode, mirrorHost); + } + + @Override + public InternalInventory getPatternInv() { + return DISABLED_PATTERN_INVENTORY; + } + + private AppEngInternalInventory getActualPatternInventory() { + return (AppEngInternalInventory) super.getPatternInv(); + } + } +} diff --git a/src/main/java/com/extendedae_plus/datagen/CraftingRecipes.java b/src/main/java/com/extendedae_plus/datagen/CraftingRecipes.java index 1b52732..33fc8a3 100644 --- a/src/main/java/com/extendedae_plus/datagen/CraftingRecipes.java +++ b/src/main/java/com/extendedae_plus/datagen/CraftingRecipes.java @@ -124,6 +124,28 @@ public class CraftingRecipes extends RecipeProvider { .define('B', EPPItemAndBlock.ASSEMBLER_MATRIX_WALL) .unlockedBy("has_quantum_ring", has(AEBlocks.QUANTUM_RING)) .save(consumer); + + //镜像样板供应器 + ShapedRecipeBuilder.shaped(RecipeCategory.MISC, ModItems.MIRROR_PATTERN_PROVIDER.get()) + .pattern("AAA") + .pattern("ABA") + .pattern("AAA") + .unlockedBy("has_mirror_pattern_provider",has(ModItems.MIRROR_PATTERN_PROVIDER.get())) + .define('A',Items.GLASS) + .define('B',AEBlocks.PATTERN_PROVIDER) + .save(consumer); + + //镜像样板绑定工具 + ShapedRecipeBuilder.shaped(RecipeCategory.MISC, ModItems.MIRROR_PATTERN_BINDING_TOOL.get()) + .pattern(" A") + .pattern("BCD") + .pattern("BBB") + .unlockedBy("has_mirror_pattern_binding_tool",has(ModItems.MIRROR_PATTERN_BINDING_TOOL.get())) + .define('A', AEItems.WIRELESS_RECEIVER) + .define('B', Items.IRON_INGOT) + .define('C', Items.REDSTONE) + .define('D', AEItems.CALCULATION_PROCESSOR) + .save(consumer); } private void addCraftingAccelerators(Consumer consumer) { diff --git a/src/main/java/com/extendedae_plus/init/ModBlockEntities.java b/src/main/java/com/extendedae_plus/init/ModBlockEntities.java index ca55796..7adf055 100644 --- a/src/main/java/com/extendedae_plus/init/ModBlockEntities.java +++ b/src/main/java/com/extendedae_plus/init/ModBlockEntities.java @@ -1,6 +1,7 @@ package com.extendedae_plus.init; import com.extendedae_plus.ExtendedAEPlus; +import com.extendedae_plus.content.ae2.MirrorPatternProviderBlockEntity; import com.extendedae_plus.content.matrix.CrafterCorePlusBlockEntity; import com.extendedae_plus.content.matrix.PatternCorePlusBlockEntity; import com.extendedae_plus.content.matrix.SpeedCorePlusBlockEntity; @@ -58,4 +59,9 @@ public final class ModBlockEntities { BLOCK_ENTITY_TYPES.register("assembler_matrix_upload_core", () -> BlockEntityType.Builder.of(UploadCoreBlockEntity::new, ModBlocks.ASSEMBLER_MATRIX_UPLOAD_CORE.get()).build(null)); + + public static final RegistryObject> MIRROR_PATTERN_PROVIDER_BE = + BLOCK_ENTITY_TYPES.register("mirror_pattern_provider", + () -> BlockEntityType.Builder.of(MirrorPatternProviderBlockEntity::new, + ModBlocks.MIRROR_PATTERN_PROVIDER.get()).build(null)); } diff --git a/src/main/java/com/extendedae_plus/init/ModBlocks.java b/src/main/java/com/extendedae_plus/init/ModBlocks.java index a2aea7e..551f504 100644 --- a/src/main/java/com/extendedae_plus/init/ModBlocks.java +++ b/src/main/java/com/extendedae_plus/init/ModBlocks.java @@ -4,6 +4,7 @@ import appeng.block.crafting.CraftingUnitBlock; import appeng.blockentity.crafting.CraftingBlockEntity; import appeng.core.definitions.AEBlockEntities; import com.extendedae_plus.ExtendedAEPlus; +import com.extendedae_plus.content.ae2.MirrorPatternProviderBlock; import com.extendedae_plus.content.crafting.EPlusCraftingUnitType; import com.extendedae_plus.content.matrix.CrafterCorePlusBlock; import com.extendedae_plus.content.matrix.PatternCorePlusBlock; @@ -126,4 +127,9 @@ public final class ModBlocks { return b; } ); + + public static final RegistryObject MIRROR_PATTERN_PROVIDER = BLOCKS.register( + "mirror_pattern_provider", + MirrorPatternProviderBlock::new + ); } diff --git a/src/main/java/com/extendedae_plus/init/ModCreativeTabs.java b/src/main/java/com/extendedae_plus/init/ModCreativeTabs.java index 4a6e2a2..a95e7f5 100644 --- a/src/main/java/com/extendedae_plus/init/ModCreativeTabs.java +++ b/src/main/java/com/extendedae_plus/init/ModCreativeTabs.java @@ -27,6 +27,8 @@ public final class ModCreativeTabs { output.accept(ModItems.ASSEMBLER_MATRIX_CRAFTER_PLUS.get()); //超级装配矩阵样板核心 output.accept(ModItems.ASSEMBLER_MATRIX_PATTERN_PLUS.get()); + output.accept(ModItems.MIRROR_PATTERN_PROVIDER.get()); + output.accept(ModItems.MIRROR_PATTERN_BINDING_TOOL.get()); //实体加速器&加速卡 diff --git a/src/main/java/com/extendedae_plus/init/ModItems.java b/src/main/java/com/extendedae_plus/init/ModItems.java index e62218e..f441fc9 100644 --- a/src/main/java/com/extendedae_plus/init/ModItems.java +++ b/src/main/java/com/extendedae_plus/init/ModItems.java @@ -10,6 +10,7 @@ import com.extendedae_plus.items.InfinityBigIntegerCellItem; import com.extendedae_plus.items.materials.ChannelCardItem; import com.extendedae_plus.items.materials.EntitySpeedCardItem; import com.extendedae_plus.items.materials.VirtualCraftingCardItem; +import com.extendedae_plus.items.tools.MirrorPatternBindingToolItem; import com.extendedae_plus.util.ModCheckUtils; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.Item; @@ -85,6 +86,16 @@ public final class ModItems { () -> new BlockItem(ModBlocks.CRAFTING_ACCELERATOR_1024x.get(), new Item.Properties()) ); + public static final RegistryObject MIRROR_PATTERN_PROVIDER = ITEMS.register( + "mirror_pattern_provider", + () -> new BlockItem(ModBlocks.MIRROR_PATTERN_PROVIDER.get(), new Item.Properties()) + ); + + public static final RegistryObject MIRROR_PATTERN_BINDING_TOOL = ITEMS.register( + "mirror_pattern_binding_tool", + () -> new MirrorPatternBindingToolItem(new Item.Properties()) + ); + public static final RegistryObject ENTITY_TICKER_PART_ITEM = ITEMS.register( "entity_speed_ticker", () -> new EntitySpeedTickerPartItem(new Item.Properties()) diff --git a/src/main/java/com/extendedae_plus/items/tools/MirrorPatternBindingToolItem.java b/src/main/java/com/extendedae_plus/items/tools/MirrorPatternBindingToolItem.java new file mode 100644 index 0000000..ce1c6f8 --- /dev/null +++ b/src/main/java/com/extendedae_plus/items/tools/MirrorPatternBindingToolItem.java @@ -0,0 +1,177 @@ +package com.extendedae_plus.items.tools; + +import appeng.blockentity.crafting.PatternProviderBlockEntity; +import com.extendedae_plus.content.ae2.MirrorPatternProviderBlockEntity; +import net.minecraft.core.BlockPos; +import net.minecraft.core.GlobalPos; +import net.minecraft.core.registries.Registries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.Tag; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +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.TooltipFlag; +import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class MirrorPatternBindingToolItem extends Item { + private static final String TAG_SELECTED_MASTER = "selectedMaster"; + private static final String TAG_DIMENSION = "dimension"; + private static final String TAG_POS = "pos"; + + public MirrorPatternBindingToolItem(Properties properties) { + super(properties.stacksTo(1)); + } + + @Override + public InteractionResult useOn(UseOnContext context) { + var level = context.getLevel(); + var player = context.getPlayer(); + var blockEntity = level.getBlockEntity(context.getClickedPos()); + var stack = context.getItemInHand(); + + if (blockEntity instanceof PatternProviderBlockEntity + && !(blockEntity instanceof MirrorPatternProviderBlockEntity)) { + if (player != null && player.isShiftKeyDown()) { + if (!level.isClientSide) { + if (MirrorPatternProviderBlockEntity.isSupportedMaster(blockEntity)) { + setSelectedMaster(stack, GlobalPos.of(level.dimension(), context.getClickedPos())); + player.displayClientMessage( + Component.translatable( + "extendedae_plus.message.mirror_binding_tool.selected", + context.getClickedPos().getX(), + context.getClickedPos().getY(), + context.getClickedPos().getZ()), + true); + } else { + player.displayClientMessage( + Component.translatable( + "extendedae_plus.message.mirror_binding_tool.only_normal_provider"), + true); + } + } + return InteractionResult.sidedSuccess(level.isClientSide); + } + + return InteractionResult.PASS; + } + + if (blockEntity instanceof MirrorPatternProviderBlockEntity mirror) { + if (!level.isClientSide) { + var selectedMaster = getSelectedMaster(stack); + if (selectedMaster == null) { + if (player != null) { + player.displayClientMessage( + Component.translatable("extendedae_plus.message.mirror_binding_tool.no_selection"), + true); + } + return InteractionResult.SUCCESS; + } + + if (mirror.bindToMaster(selectedMaster)) { + if (player != null) { + player.displayClientMessage(mirror.createBoundMessage(), true); + } + } else if (player != null) { + player.displayClientMessage( + Component.translatable("extendedae_plus.message.mirror_binding_tool.bind_failed"), + true); + } + } + + return InteractionResult.sidedSuccess(level.isClientSide); + } + + return InteractionResult.PASS; + } + + @Override + public void appendHoverText(ItemStack stack, @Nullable Level level, List tooltipComponents, + TooltipFlag tooltipFlag) { + super.appendHoverText(stack, level, tooltipComponents, tooltipFlag); + + tooltipComponents.add(Component.translatable("item.extendedae_plus.mirror_pattern_binding_tool.tip.select")); + tooltipComponents.add(Component.translatable("item.extendedae_plus.mirror_pattern_binding_tool.tip.bind")); + tooltipComponents.add(Component.translatable("item.extendedae_plus.mirror_pattern_binding_tool.tip.clear")); + + var selectedMaster = getSelectedMaster(stack); + if (selectedMaster != null) { + var pos = selectedMaster.pos(); + tooltipComponents.add(Component.translatable( + "item.extendedae_plus.mirror_pattern_binding_tool.selected", + pos.getX(), + pos.getY(), + pos.getZ())); + tooltipComponents.add(Component.translatable( + "item.extendedae_plus.mirror_pattern_binding_tool.dimension", + selectedMaster.dimension().location().toString())); + } else { + tooltipComponents.add(Component.translatable("item.extendedae_plus.mirror_pattern_binding_tool.unset")); + } + } + + private static void setSelectedMaster(ItemStack stack, GlobalPos master) { + var tag = stack.getOrCreateTag(); + var selectedTag = new CompoundTag(); + selectedTag.putString(TAG_DIMENSION, master.dimension().location().toString()); + selectedTag.putLong(TAG_POS, master.pos().asLong()); + tag.put(TAG_SELECTED_MASTER, selectedTag); + } + + private static void clearSelectedMaster(ItemStack stack) { + var tag = stack.getTag(); + if (tag != null) { + tag.remove(TAG_SELECTED_MASTER); + } + } + + @Nullable + private static GlobalPos getSelectedMaster(ItemStack stack) { + var tag = stack.getTag(); + if (tag == null || !tag.contains(TAG_SELECTED_MASTER, Tag.TAG_COMPOUND)) { + return null; + } + + var selectedTag = tag.getCompound(TAG_SELECTED_MASTER); + if (!selectedTag.contains(TAG_DIMENSION, Tag.TAG_STRING) || !selectedTag.contains(TAG_POS, Tag.TAG_LONG)) { + return null; + } + + return GlobalPos.of( + ResourceKey.create(Registries.DIMENSION, new ResourceLocation(selectedTag.getString(TAG_DIMENSION))), + BlockPos.of(selectedTag.getLong(TAG_POS))); + } + + @Override + public InteractionResultHolder use(Level level, Player player, InteractionHand usedHand) { + var stack = player.getItemInHand(usedHand); + + if (!player.isShiftKeyDown()) { + return InteractionResultHolder.pass(stack); + } + + if (!level.isClientSide) { + if (getSelectedMaster(stack) != null) { + clearSelectedMaster(stack); + player.displayClientMessage( + Component.translatable("extendedae_plus.message.mirror_binding_tool.cleared"), + true); + } else { + player.displayClientMessage( + Component.translatable("extendedae_plus.message.mirror_binding_tool.no_selection"), + true); + } + } + + return InteractionResultHolder.sidedSuccess(stack, level.isClientSide); + } +} diff --git a/src/main/java/com/extendedae_plus/mixin/appflux/AppfluxPatternProviderLogicMixin.java b/src/main/java/com/extendedae_plus/mixin/appflux/AppfluxPatternProviderLogicMixin.java index 31cbfd9..ffa890b 100644 --- a/src/main/java/com/extendedae_plus/mixin/appflux/AppfluxPatternProviderLogicMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/appflux/AppfluxPatternProviderLogicMixin.java @@ -6,6 +6,7 @@ import appeng.api.upgrades.UpgradeInventories; import appeng.helpers.patternprovider.PatternProviderLogic; import appeng.helpers.patternprovider.PatternProviderLogicHost; import com.extendedae_plus.compat.UpgradeSlotCompat; +import com.extendedae_plus.content.ae2.MirrorPatternProviderBlockEntity; import com.extendedae_plus.util.Logger; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -13,6 +14,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.lang.reflect.Field; +import java.lang.reflect.Method; /** * 当appflux存在时,修改PatternProviderLogic的升级槽数量为2个 @@ -28,26 +30,37 @@ public class AppfluxPatternProviderLogicMixin { at = @At("TAIL")) private void eap$modifyAppfluxUpgradeSlots(IManagedGridNode mainNode, PatternProviderLogicHost host, int patternInventorySize, CallbackInfo ci) { try { + if (host instanceof MirrorPatternProviderBlockEntity) { + return; + } // 只有当appflux存在且不启用我们的升级槽时才修改数量 if (!UpgradeSlotCompat.shouldEnableUpgradeSlots() && UpgradeSlotCompat.shouldEnableChannelCard()) { // 使用反射找到appflux的升级槽字段并替换 try { - Field upgradesField = this.getClass().getDeclaredField("af_$upgrades"); + Field upgradesField = PatternProviderLogic.class.getDeclaredField("af_$upgrades"); upgradesField.setAccessible(true); IUpgradeInventory currentUpgrades = (IUpgradeInventory) upgradesField.get(this); + Method onUpgradesChanged = null; + try { + onUpgradesChanged = PatternProviderLogic.class.getDeclaredMethod("af_$onUpgradesChanged"); + onUpgradesChanged.setAccessible(true); + } catch (NoSuchMethodException ignored) { + } if (currentUpgrades != null) { // 创建新的2槽升级槽 + Method finalOnUpgradesChanged = onUpgradesChanged; IUpgradeInventory newUpgrades = UpgradeInventories.forMachine( host.getTerminalIcon().getItem(), 2, () -> { try { - // 调用appflux的升级变更方法 - this.getClass().getDeclaredMethod("af_$onUpgradesChanged").invoke(this); + if (finalOnUpgradesChanged != null) { + finalOnUpgradesChanged.invoke(this); + } } catch (Exception e) { Logger.EAP$LOGGER.error("调用appflux升级变更方法失败", e); } @@ -64,6 +77,8 @@ public class AppfluxPatternProviderLogicMixin { // 替换升级槽 upgradesField.set(this, newUpgrades); } + } catch (NoSuchFieldException e) { + Logger.EAP$LOGGER.debug("未找到appflux升级槽字段,跳过升级槽兼容调整"); } catch (Exception e) { Logger.EAP$LOGGER.error("反射修改appflux升级槽失败", e); } diff --git a/src/main/resources/assets/extendedae_plus/blockstates/mirror_pattern_provider.json b/src/main/resources/assets/extendedae_plus/blockstates/mirror_pattern_provider.json new file mode 100644 index 0000000..9b8bc37 --- /dev/null +++ b/src/main/resources/assets/extendedae_plus/blockstates/mirror_pattern_provider.json @@ -0,0 +1,33 @@ +{ + "variants": { + "push_direction=all": { + "model": "extendedae_plus:block/mirror_pattern_provider" + }, + "push_direction=down": { + "model": "extendedae_plus:block/mirror_pattern_provider_oriented", + "x": 180 + }, + "push_direction=east": { + "model": "extendedae_plus:block/mirror_pattern_provider_oriented", + "x": 90, + "y": 90 + }, + "push_direction=north": { + "model": "extendedae_plus:block/mirror_pattern_provider_oriented", + "x": 90 + }, + "push_direction=south": { + "model": "extendedae_plus:block/mirror_pattern_provider_oriented", + "x": 90, + "y": 180 + }, + "push_direction=up": { + "model": "extendedae_plus:block/mirror_pattern_provider_oriented" + }, + "push_direction=west": { + "model": "extendedae_plus:block/mirror_pattern_provider_oriented", + "x": 90, + "y": 270 + } + } +} diff --git a/src/main/resources/assets/extendedae_plus/lang/en_us.json b/src/main/resources/assets/extendedae_plus/lang/en_us.json index bcf2f7c..111bdb4 100644 --- a/src/main/resources/assets/extendedae_plus/lang/en_us.json +++ b/src/main/resources/assets/extendedae_plus/lang/en_us.json @@ -68,6 +68,7 @@ "block.extendedae_plus.256x_crafting_accelerator": "256x Crafting Accelerator", "block.extendedae_plus.1024x_crafting_accelerator": "1024x Crafting Accelerator", "block.extendedae_plus.network_pattern_controller": "Pattern Supplier State Controller", + "block.extendedae_plus.mirror_pattern_provider": "Mirror Pattern Provider", "block.extendedae_plus.assembler_matrix_upload_core": "Assembler Matrix Upload Core", "block.extendedae_plus.assembler_matrix_speed_plus": "Assembler Matrix Speed Core Plus", "block.extendedae_plus.assembler_matrix_crafter_plus": "Assembler Matrix Crafter Core Plus", @@ -171,6 +172,14 @@ "item.extendedae_plus.channel_card.owner.player": "Owner: Player %s", "item.extendedae_plus.channel_card.owner.bound": "Bound to: %s", "item.extendedae_plus.channel_card.owner.cleared": "Owner binding cleared", + "item.extendedae_plus.mirror_pattern_provider": "Mirror Pattern Provider", + "item.extendedae_plus.mirror_pattern_binding_tool": "Mirror Pattern Binder", + "item.extendedae_plus.mirror_pattern_binding_tool.tip.select": "Sneak-right-click a standard pattern provider to record it", + "item.extendedae_plus.mirror_pattern_binding_tool.tip.bind": "Right-click a mirror pattern provider to bind it to the recorded master", + "item.extendedae_plus.mirror_pattern_binding_tool.tip.clear": "Sneak-right-click air to clear the recorded master", + "item.extendedae_plus.mirror_pattern_binding_tool.selected": "Recorded master provider: (%d, %d, %d)", + "item.extendedae_plus.mirror_pattern_binding_tool.dimension": "Dimension: %s", + "item.extendedae_plus.mirror_pattern_binding_tool.unset": "No master pattern provider recorded", "item.extendedae_plus.virtual_crafting_card": "Virtual Crafting Card", "item.extendedae_plus.virtual_crafting_card.tooltip_main": "Auto-completes crafting jobs once the current pattern is about to finish", "item.extendedae_plus.virtual_crafting_card.tooltip_detail": "Install inside a Pattern Provider upgrade slot", @@ -197,6 +206,15 @@ "extendedae_plus.chat.pattern_provider.global_toggle_applied": "Global toggle applied to %s pattern providers", "extendedae_plus.message.config_update_failed": "Mapping file update failed: %s", "extendedae_plus.message.config_delete_failed": "Mapping file delete failed: %s", + "extendedae_plus.message.mirror_pattern_provider.bound": "Mirror pattern provider bound to master provider: (%d, %d, %d)", + "extendedae_plus.message.mirror_pattern_provider.following": "Mirror pattern provider is following master provider: (%d, %d, %d)", + "extendedae_plus.message.mirror_pattern_provider.missing_master": "No standard master pattern provider is bound. Use the binder to bind one manually.", + "extendedae_plus.message.mirror_pattern_provider.readonly": "Mirror pattern provider has no standalone UI and follows the master's state and direction.", + "extendedae_plus.message.mirror_binding_tool.selected": "Recorded master pattern provider: (%d, %d, %d)", + "extendedae_plus.message.mirror_binding_tool.no_selection": "Sneak-right-click a standard pattern provider first to record it.", + "extendedae_plus.message.mirror_binding_tool.bind_failed": "Binding failed: the recorded position is not a valid standard pattern provider.", + "extendedae_plus.message.mirror_binding_tool.only_normal_provider": "This mirror binder only supports the standard pattern provider, not the extended one.", + "extendedae_plus.message.mirror_binding_tool.cleared": "Cleared the master pattern provider recorded in the binding tool.", "config.jade.plugin_extendedae_plus.wireless_transceiver_info": "Wireless Transceiver Info", "config.jade.plugin_extendedae_plus.wt_frequency": "Show Frequency", diff --git a/src/main/resources/assets/extendedae_plus/lang/zh_cn.json b/src/main/resources/assets/extendedae_plus/lang/zh_cn.json index 1fe0426..00ffb30 100644 --- a/src/main/resources/assets/extendedae_plus/lang/zh_cn.json +++ b/src/main/resources/assets/extendedae_plus/lang/zh_cn.json @@ -66,6 +66,7 @@ "block.extendedae_plus.256x_crafting_accelerator": "256x并行处理单元", "block.extendedae_plus.1024x_crafting_accelerator": "1024x并行处理单元", "block.extendedae_plus.network_pattern_controller": "样板供应器状态控制器", + "block.extendedae_plus.mirror_pattern_provider": "镜像样板供应器", "block.extendedae_plus.assembler_matrix_upload_core": "装配矩阵上传核心", "block.extendedae_plus.assembler_matrix_speed_plus": "超级装配矩阵速度核心", "block.extendedae_plus.assembler_matrix_crafter_plus": "超级装配矩阵合成核心", @@ -170,6 +171,14 @@ "item.extendedae_plus.channel_card.owner.player": "所有者:玩家 %s", "item.extendedae_plus.channel_card.owner.bound": "已绑定至:%s", "item.extendedae_plus.channel_card.owner.cleared": "已清除所有者绑定", + "item.extendedae_plus.mirror_pattern_provider": "镜像样板供应器", + "item.extendedae_plus.mirror_pattern_binding_tool": "镜像样板绑定器", + "item.extendedae_plus.mirror_pattern_binding_tool.tip.select": "潜行右键普通样板供应器:记录主供应器", + "item.extendedae_plus.mirror_pattern_binding_tool.tip.bind": "右键镜像样板供应器:绑定到当前记录的主供应器", + "item.extendedae_plus.mirror_pattern_binding_tool.tip.clear": "潜行右键空气:清空当前记录的主供应器", + "item.extendedae_plus.mirror_pattern_binding_tool.selected": "当前记录主供应器:(%d, %d, %d)", + "item.extendedae_plus.mirror_pattern_binding_tool.dimension": "维度:%s", + "item.extendedae_plus.mirror_pattern_binding_tool.unset": "当前未记录主样板供应器", "item.extendedae_plus.virtual_crafting_card": "虚拟合成卡", "item.extendedae_plus.virtual_crafting_card.tooltip_main": "当前样板即将完成时尝试终止剩余合成", "item.extendedae_plus.virtual_crafting_card.tooltip_detail": "需安装在样板供应器的升级槽内", @@ -196,6 +205,15 @@ "extendedae_plus.chat.pattern_provider.global_toggle_applied": "全局切换已应用到 %s 个样板供应器", "extendedae_plus.message.config_update_failed": "映射文件更新失败: %s", "extendedae_plus.message.config_delete_failed": "映射文件删除失败: %s", + "extendedae_plus.message.mirror_pattern_provider.bound": "镜像样板供应器已绑定到主供应器:(%d, %d, %d)", + "extendedae_plus.message.mirror_pattern_provider.following": "镜像样板供应器当前跟随主供应器:(%d, %d, %d)", + "extendedae_plus.message.mirror_pattern_provider.missing_master": "未绑定普通主样板供应器,请使用绑定器手动绑定", + "extendedae_plus.message.mirror_pattern_provider.readonly": "镜像样板供应器没有独立界面,状态与朝向会跟随主供应器", + "extendedae_plus.message.mirror_binding_tool.selected": "已记录主样板供应器:(%d, %d, %d)", + "extendedae_plus.message.mirror_binding_tool.no_selection": "请先潜行右键一个普通样板供应器进行记录", + "extendedae_plus.message.mirror_binding_tool.bind_failed": "绑定失败:记录的位置不是可用的普通样板供应器", + "extendedae_plus.message.mirror_binding_tool.only_normal_provider": "当前镜像样板绑定器只支持普通样板供应器,不支持扩展样板供应器", + "extendedae_plus.message.mirror_binding_tool.cleared": "已清空绑定工具中记录的主样板供应器", "config.jade.plugin_extendedae_plus.wireless_transceiver_info": "无线收发器信息", "config.jade.plugin_extendedae_plus.wt_frequency": "显示频率", diff --git a/src/main/resources/assets/extendedae_plus/models/block/mirror_pattern_provider.json b/src/main/resources/assets/extendedae_plus/models/block/mirror_pattern_provider.json new file mode 100644 index 0000000..ae4bf48 --- /dev/null +++ b/src/main/resources/assets/extendedae_plus/models/block/mirror_pattern_provider.json @@ -0,0 +1,6 @@ +{ + "parent": "block/cube_all", + "textures": { + "all": "extendedae_plus:block/mirror_pattern_provider/mirror_pattern_provider_default" + } +} diff --git a/src/main/resources/assets/extendedae_plus/models/block/mirror_pattern_provider_oriented.json b/src/main/resources/assets/extendedae_plus/models/block/mirror_pattern_provider_oriented.json new file mode 100644 index 0000000..eac4dd1 --- /dev/null +++ b/src/main/resources/assets/extendedae_plus/models/block/mirror_pattern_provider_oriented.json @@ -0,0 +1,12 @@ +{ + "parent": "block/cube", + "textures": { + "particle": "extendedae_plus:block/mirror_pattern_provider/mirror_pattern_provider_default", + "down": "extendedae_plus:block/mirror_pattern_provider/mirror_pattern_provider_back", + "up": "extendedae_plus:block/mirror_pattern_provider/mirror_pattern_provider_front", + "north": "extendedae_plus:block/mirror_pattern_provider/mirror_pattern_provider_side", + "south": "extendedae_plus:block/mirror_pattern_provider/mirror_pattern_provider_side", + "east": "extendedae_plus:block/mirror_pattern_provider/mirror_pattern_provider_side", + "west": "extendedae_plus:block/mirror_pattern_provider/mirror_pattern_provider_side" + } +} diff --git a/src/main/resources/assets/extendedae_plus/models/item/mirror_pattern_binding_tool.json b/src/main/resources/assets/extendedae_plus/models/item/mirror_pattern_binding_tool.json new file mode 100644 index 0000000..fc45941 --- /dev/null +++ b/src/main/resources/assets/extendedae_plus/models/item/mirror_pattern_binding_tool.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "extendedae_plus:item/mirror_pattern_binding_tool" + } +} diff --git a/src/main/resources/assets/extendedae_plus/models/item/mirror_pattern_provider.json b/src/main/resources/assets/extendedae_plus/models/item/mirror_pattern_provider.json new file mode 100644 index 0000000..08c5436 --- /dev/null +++ b/src/main/resources/assets/extendedae_plus/models/item/mirror_pattern_provider.json @@ -0,0 +1,3 @@ +{ + "parent": "extendedae_plus:block/mirror_pattern_provider" +} diff --git a/src/main/resources/assets/extendedae_plus/textures/block/mirror_pattern_provider/mirror_pattern_provider_back.png b/src/main/resources/assets/extendedae_plus/textures/block/mirror_pattern_provider/mirror_pattern_provider_back.png new file mode 100644 index 0000000..56a3057 Binary files /dev/null and b/src/main/resources/assets/extendedae_plus/textures/block/mirror_pattern_provider/mirror_pattern_provider_back.png differ diff --git a/src/main/resources/assets/extendedae_plus/textures/block/mirror_pattern_provider/mirror_pattern_provider_default.png b/src/main/resources/assets/extendedae_plus/textures/block/mirror_pattern_provider/mirror_pattern_provider_default.png new file mode 100644 index 0000000..edbb488 Binary files /dev/null and b/src/main/resources/assets/extendedae_plus/textures/block/mirror_pattern_provider/mirror_pattern_provider_default.png differ diff --git a/src/main/resources/assets/extendedae_plus/textures/block/mirror_pattern_provider/mirror_pattern_provider_front.png b/src/main/resources/assets/extendedae_plus/textures/block/mirror_pattern_provider/mirror_pattern_provider_front.png new file mode 100644 index 0000000..bbafd06 Binary files /dev/null and b/src/main/resources/assets/extendedae_plus/textures/block/mirror_pattern_provider/mirror_pattern_provider_front.png differ diff --git a/src/main/resources/assets/extendedae_plus/textures/block/mirror_pattern_provider/mirror_pattern_provider_side.png b/src/main/resources/assets/extendedae_plus/textures/block/mirror_pattern_provider/mirror_pattern_provider_side.png new file mode 100644 index 0000000..68fb7cb Binary files /dev/null and b/src/main/resources/assets/extendedae_plus/textures/block/mirror_pattern_provider/mirror_pattern_provider_side.png differ diff --git a/src/main/resources/assets/extendedae_plus/textures/item/mirror_pattern_binding_tool.png b/src/main/resources/assets/extendedae_plus/textures/item/mirror_pattern_binding_tool.png new file mode 100644 index 0000000..11c5e3e Binary files /dev/null and b/src/main/resources/assets/extendedae_plus/textures/item/mirror_pattern_binding_tool.png differ diff --git a/src/main/resources/data/extendedae_plus/loot_tables/blocks/mirror_pattern_provider.json b/src/main/resources/data/extendedae_plus/loot_tables/blocks/mirror_pattern_provider.json new file mode 100644 index 0000000..2871a31 --- /dev/null +++ b/src/main/resources/data/extendedae_plus/loot_tables/blocks/mirror_pattern_provider.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "extendedae_plus:mirror_pattern_provider" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} diff --git a/src/main/resources/data/minecraft/tags/blocks/mineable/pickaxe.json b/src/main/resources/data/minecraft/tags/blocks/mineable/pickaxe.json index 4ba8317..bc1e407 100644 --- a/src/main/resources/data/minecraft/tags/blocks/mineable/pickaxe.json +++ b/src/main/resources/data/minecraft/tags/blocks/mineable/pickaxe.json @@ -2,6 +2,7 @@ "replace": false, "values": [ "extendedae_plus:network_pattern_controller", + "extendedae_plus:mirror_pattern_provider", "extendedae_plus:wireless_transceiver", "extendedae_plus:assembler_matrix_upload_core", "extendedae_plus:assembler_matrix_speed_plus", diff --git a/src/main/resources/data/minecraft/tags/blocks/needs_stone_tool.json b/src/main/resources/data/minecraft/tags/blocks/needs_stone_tool.json index d22d32b..39f594e 100644 --- a/src/main/resources/data/minecraft/tags/blocks/needs_stone_tool.json +++ b/src/main/resources/data/minecraft/tags/blocks/needs_stone_tool.json @@ -1,6 +1,7 @@ { "replace": false, "values": [ + "extendedae_plus:mirror_pattern_provider", "extendedae_plus:wireless_transceiver", "extendedae_plus:assembler_matrix_upload_core", "extendedae_plus:assembler_matrix_speed_plus",