From 7b341980bd3e6cdbd7dd51f90dfbcdbd3a7548f5 Mon Sep 17 00:00:00 2001 From: 1820982382 Date: Sat, 1 Aug 2026 16:42:53 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 74 ++ gradle.properties | 18 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 43453 bytes gradle/wrapper/gradle-wrapper.properties | 8 + settings.gradle | 14 + .../ThaumicEnergistics.java | 208 +++++ .../api/IThETransportPermissions.java | 22 + .../api/grid/ICraftingIssuerHost.java | 6 + .../api/grid/IDigiVisSource.java | 7 + .../api/grid/IEssentiaGrid.java | 49 ++ .../api/grid/IEssentiaWatcher.java | 8 + .../api/grid/IEssentiaWatcherHost.java | 9 + .../api/storage/AspectStack.java | 8 + .../api/storage/IAspectStack.java | 4 + .../thaumicenergistics/client/ClientInit.java | 21 + .../client/ClientSetup.java | 82 ++ .../client/EssentiaKeyRenderHandler.java | 61 ++ .../render/RenderTileArcaneAssembler.java | 19 + .../client/render/RenderTileEVC.java | 19 + .../render/layer/GolemBackpackLayer.java | 90 ++ .../render/model/GolemBackpackModel.java | 181 ++++ .../common/WrenchFocusHandler.java | 56 ++ .../common/blocks/OrientableEntityBlock.java | 71 ++ .../common/blocks/ThEBaseEntityBlock.java | 47 + .../container/ContainerArcaneAssembler.java | 260 ++++++ .../ContainerArcaneCraftingTerminal.java | 393 +++++++++ .../ContainerDistillationPatternEncoder.java | 357 ++++++++ .../ContainerEssentiaCellTerminal.java | 20 + .../ContainerEssentiaCellWorkbench.java | 159 ++++ .../container/ContainerEssentiaExportBus.java | 85 ++ .../container/ContainerEssentiaImportBus.java | 57 ++ .../ContainerEssentiaLevelEmitter.java | 99 +++ .../ContainerEssentiaStorageBus.java | 165 ++++ .../ContainerEssentiaVibrationChamber.java | 19 + .../ContainerKnowledgeInscriber.java | 531 ++++++++++++ .../common/container/GuiArcaneAssembler.java | 109 +++ .../container/GuiArcaneCraftingTerminal.java | 86 ++ .../GuiDistillationPatternEncoder.java | 88 ++ .../container/GuiEssentiaCellTerminal.java | 15 + .../container/GuiEssentiaCellWorkbench.java | 133 +++ .../container/GuiEssentiaExportBus.java | 75 ++ .../container/GuiEssentiaImportBus.java | 63 ++ .../container/GuiEssentiaLevelEmitter.java | 102 +++ .../container/GuiEssentiaStorageBus.java | 91 ++ .../GuiEssentiaVibrationChamber.java | 15 + .../container/GuiKnowledgeInscriber.java | 101 +++ .../common/container/SimpleMenuProvider.java | 28 + .../common/container/ThEContainerBase.java | 48 + .../slot/ArcaneCraftingResultSlot.java | 133 +++ .../common/container/slot/GhostSlot.java | 31 + .../common/entities/BackpackSkins.java | 58 ++ .../common/entities/FacadeToSkinMapping.java | 84 ++ .../common/entities/GolemBackpackHandler.java | 265 ++++++ .../entities/GolemBackpackTickHandler.java | 323 +++++++ .../common/entities/WirelessAELinkGolem.java | 312 +++++++ .../features/FeatureAutocraftingArcane.java | 21 + .../common/features/FeatureCells.java | 20 + .../features/FeatureEssentiaIOBuses.java | 35 + .../features/FeatureEssentiaMonitoring.java | 15 + .../features/FeatureEssentiaProvider.java | 7 + .../FeatureEssentiaVibrationChamber.java | 21 + .../common/features/FeatureGolemBackpack.java | 11 + .../features/FeatureInfusionProvider.java | 16 + .../common/features/FeatureRegistry.java | 17 + .../features/FeatureVisRelayInterface.java | 17 + .../common/features/RecipeRegistration.java | 379 ++++++++ .../common/features/ThEFeatureBase.java | 43 + .../common/grid/AEPartGridBlock.java | 22 + .../common/grid/EssentiaGridService.java | 136 +++ .../common/grid/EssentiaMonitor.java | 15 + .../common/grid/EssentiaMonitorRegistry.java | 29 + .../common/grid/EssentiaWatcher.java | 48 + .../common/grid/GridEssentiaCache.java | 9 + .../integration/appeng/AEssentiaKey.java | 135 +++ .../integration/appeng/AEssentiaKeyType.java | 54 ++ .../appeng/EssentiaStorageChannel.java | 31 + .../appeng/ThEAppliedEnergistics.java | 7 + .../integration/jade/ThEJadePlugin.java | 24 + .../jade/VibrationChamberProvider.java | 123 +++ .../integration/tc/ArcaneCraftingPattern.java | 149 ++++ .../tc/EssentiaConversionHelper.java | 30 + .../integration/tc/PseudoResearchItem.java | 156 ++++ .../common/integration/tc/TCReflection.java | 165 ++++ .../common/integration/tc/ThEThaumcraft.java | 392 +++++++++ .../integration/tc/VisProviderProxy.java | 85 ++ .../inventory/HandlerKnowledgeCore.java | 148 ++++ .../common/items/ItemEssentiaCell.java | 226 +++++ .../common/items/ItemFocusAEWrench.java | 184 ++++ .../items/ItemGolemWirelessBackpack.java | 57 ++ .../items/PartItemArcaneCraftingTerminal.java | 43 + .../items/PartItemEssentiaExportBus.java | 49 ++ .../items/PartItemEssentiaImportBus.java | 49 ++ .../items/PartItemEssentiaLevelEmitter.java | 43 + .../items/PartItemEssentiaStorageBus.java | 48 + .../items/PartItemEssentiaTerminal.java | 43 + .../common/items/PartItemVisInterface.java | 24 + .../items/WirelessEssentiaTerminalItem.java | 43 + .../WirelessEssentiaTerminalMenuHost.java | 35 + .../network/CellWorkbenchC2SPacket.java | 118 +++ .../network/CellWorkbenchSyncPacket.java | 64 ++ .../network/GolemBackpackClientData.java | 74 ++ .../network/GolemBackpackSyncPacket.java | 69 ++ .../KnowledgeInscriberGhostSlotPacket.java | 52 ++ .../common/network/ThENetworking.java | 46 + .../parts/ArcaneCraftingTerminalPart.java | 117 +++ .../common/parts/EssentiaExportBusPart.java | 179 ++++ .../common/parts/EssentiaImportBusPart.java | 158 ++++ .../parts/EssentiaLevelEmitterPart.java | 298 +++++++ .../common/parts/EssentiaStorageBusPart.java | 132 +++ .../common/parts/EssentiaTerminalPart.java | 97 +++ .../common/parts/VisInterfacePart.java | 314 +++++++ .../common/storage/TransportPermissions.java | 33 + .../common/tiles/ThETileBase.java | 17 + .../common/tiles/TileArcaneAssembler.java | 819 ++++++++++++++++++ .../tiles/TileDistillationPatternEncoder.java | 57 ++ .../tiles/TileEssentiaCellWorkbench.java | 66 ++ .../common/tiles/TileEssentiaProvider.java | 202 +++++ .../tiles/TileEssentiaVibrationChamber.java | 357 ++++++++ .../common/tiles/TileInfusionProvider.java | 112 +++ .../common/tiles/TileKnowledgeInscriber.java | 80 ++ .../common/tiles/TileProviderBase.java | 183 ++++ .../thaumicenergistics/config/ThEConfig.java | 10 + .../init/ModBlockEntities.java | 52 ++ .../thaumicenergistics/init/ModBlocks.java | 103 +++ .../init/ModCreativeTab.java | 46 + .../thaumicenergistics/init/ModItems.java | 81 ++ .../thaumicenergistics/init/ModMenuTypes.java | 65 ++ .../integration/jei/Ae2JeiCompat.java | 20 + .../jei/ArcaneCraftingTransferInfo.java | 55 ++ .../jei/ArcaneRecipeTransferInfo.java | 60 ++ .../integration/jei/AspectIngredient.java | 16 + .../jei/AspectIngredientHelper.java | 73 ++ .../jei/AspectIngredientRenderer.java | 50 ++ .../integration/jei/AspectIngredientType.java | 18 + .../CellWorkbenchGhostIngredientHandler.java | 57 ++ .../jei/EssentiaIngredientConverter.java | 48 + .../jei/ThEArcaneCraftingTransferInfo.java | 53 ++ .../jei/ThEGhostIngredientHandler.java | 99 +++ .../integration/jei/ThEJeiPlugin.java | 100 +++ .../jei/ThEUseArcaneRecipeTransfer.java | 97 +++ .../jei/ThEUseCraftingRecipeTransfer.java | 236 +++++ .../mixins/ae2/MixinAbstractTerminalPart.java | 58 ++ .../mixins/ae2/MixinConfigMenuInventory.java | 89 ++ .../mixins/ae2/MixinCraftingTreeProcess.java | 7 + .../mixins/tc/MixinAspect.java | 7 + .../mixins/tc/MixinThaumonomiconScreen.java | 61 ++ .../mixins/tc/MixinVisRelayBlock.java | 44 + .../mixins/tc/ResearchPageIndexMixin.java | 26 + .../resources/META-INF/neoforge.mods.toml | 50 ++ .../services/snownee.jade.api.IWailaPlugin | 1 + ...n.api.integrations.jei.IngredientConverter | 1 + .../ae2/screens/arcane_crafting_terminal.json | 61 ++ .../ae2/screens/aspect_filter_selection.json | 23 + .../ae2/screens/essentia_level_emitter.json | 43 + .../blockstates/arcane_assembler.json | 1 + .../blockstates/distillation_encoder.json | 1 + .../blockstates/essentia_cell_workbench.json | 1 + .../blockstates/essentia_provider.json | 1 + .../essentia_vibration_chamber.json | 8 + .../blockstates/infusion_provider.json | 1 + .../blockstates/knowledge_inscriber.json | 1 + .../assets/thaumicenergistics/lang/en_us.json | 120 +++ .../assets/thaumicenergistics/lang/zh_cn.json | 138 +++ .../assets/thaumicenergistics/meta/logo.png | Bin 0 -> 220085 bytes .../models/block/arcane_assembler.json | 1 + .../models/block/distillation_encoder.json | 1 + .../models/block/essentia_cell_workbench.json | 8 + .../models/block/essentia_provider.json | 6 + .../block/essentia_vibration_chamber.json | 8 + .../models/block/infusion_provider.json | 1 + .../models/block/knowledge_inscriber.json | 8 + .../models/item/arcane_assembler.json | 1 + .../models/item/arcane_crafting_terminal.json | 12 + .../models/item/coalescence_core.json | 1 + .../models/item/diffusion_core.json | 1 + .../models/item/distillation_encoder.json | 1 + .../models/item/essentia_cell_16k.json | 1 + .../models/item/essentia_cell_1k.json | 1 + .../models/item/essentia_cell_4k.json | 1 + .../models/item/essentia_cell_64k.json | 1 + .../models/item/essentia_cell_creative.json | 1 + .../models/item/essentia_cell_workbench.json | 1 + .../models/item/essentia_export_bus.json | 46 + .../models/item/essentia_import_bus.json | 216 +++++ .../models/item/essentia_level_emitter.json | 20 + .../models/item/essentia_provider.json | 1 + .../models/item/essentia_storage_bus.json | 47 + .../models/item/essentia_terminal.json | 12 + .../item/essentia_vibration_chamber.json | 3 + .../models/item/focus_aewrench.json | 6 + .../models/item/golem_wifi_backpack.json | 6 + .../models/item/infusion_provider.json | 1 + .../models/item/knowledge_core.json | 6 + .../models/item/knowledge_inscriber.json | 3 + .../models/item/storage_casing.json | 6 + .../models/item/storage_component_16k.json | 6 + .../models/item/storage_component_1k.json | 6 + .../models/item/storage_component_4k.json | 6 + .../models/item/storage_component_64k.json | 6 + .../models/item/vis_interface.json | 6 + .../item/wireless_essentia_terminal.json | 6 + .../parts/arcane_crafting_terminal_base.json | 33 + .../arcane_crafting_terminal_has_channel.json | 22 + .../parts/arcane_crafting_terminal_off.json | 8 + .../parts/arcane_crafting_terminal_on.json | 8 + .../parts/essentia_export_bus_base.json | 59 ++ .../essentia_export_bus_has_channel.json | 17 + .../models/parts/essentia_export_bus_off.json | 17 + .../models/parts/essentia_export_bus_on.json | 17 + .../parts/essentia_import_bus_base.json | 59 ++ .../essentia_import_bus_has_channel.json | 33 + .../models/parts/essentia_import_bus_off.json | 17 + .../models/parts/essentia_import_bus_on.json | 33 + .../essentia_level_emitter_base_off.json | 28 + .../parts/essentia_level_emitter_base_on.json | 36 + ...ntia_level_emitter_status_has_channel.json | 33 + .../essentia_level_emitter_status_off.json | 25 + .../essentia_level_emitter_status_on.json | 33 + .../parts/essentia_storage_bus_base.json | 46 + .../essentia_storage_bus_has_channel.json | 17 + .../parts/essentia_storage_bus_off.json | 17 + .../models/parts/essentia_storage_bus_on.json | 17 + .../models/parts/essentia_terminal_base.json | 138 +++ .../parts/essentia_terminal_has_channel.json | 18 + .../models/parts/essentia_terminal_off.json | 9 + .../models/parts/essentia_terminal_on.json | 9 + .../models/parts/p2p/p2p_tunnel_vis.json | 6 + .../screens/aspect_filter_selection.json | 28 + .../screens/essentia_export_bus.json | 30 + .../screens/essentia_import_bus.json | 30 + .../screens/essentia_storage_bus.json | 38 + .../block/arcane_assembler_fallback.png | Bin 0 -> 2979 bytes .../block/distillation_encoder_face.png | Bin 0 -> 3644 bytes .../textures/block/e_vibration_face_ignis.png | Bin 0 -> 3832 bytes .../block/e_vibration_face_ignis.png.mcmeta | 5 + .../textures/block/e_vibration_face_off.png | Bin 0 -> 3221 bytes .../block/e_vibration_face_potentia.png | Bin 0 -> 3914 bytes .../e_vibration_face_potentia.png.mcmeta | 5 + .../textures/block/e_vibration_input.png | Bin 0 -> 3248 bytes .../block/essentia_cell_workbench_bottom.png | Bin 0 -> 3024 bytes .../block/essentia_cell_workbench_side.png | Bin 0 -> 3031 bytes .../block/essentia_cell_workbench_top.png | Bin 0 -> 3109 bytes .../textures/block/essentia_gas.png | Bin 0 -> 6844 bytes .../textures/block/essentia_gas.png.mcmeta | 5 + .../textures/block/essentia_provider.png | Bin 0 -> 3624 bytes .../block/essentia_provider_overlay.png | Bin 0 -> 3388 bytes .../textures/block/infusion_provider.png | Bin 0 -> 3603 bytes .../block/infusion_provider_overlay.png | Bin 0 -> 3200 bytes .../block/knowledge_inscriber_bottom.png | Bin 0 -> 2852 bytes .../block/knowledge_inscriber_side.png | Bin 0 -> 2972 bytes .../block/knowledge_inscriber_top.png | Bin 0 -> 3266 bytes .../textures/gui/arcane_assembler.png | Bin 0 -> 6244 bytes .../textures/gui/arcane_crafting.png | Bin 0 -> 9899 bytes .../textures/gui/distillation_encoder.png | Bin 0 -> 4058 bytes .../textures/gui/essentia_cell_workbench.png | Bin 0 -> 4198 bytes .../textures/gui/essentia_level_emitter.png | Bin 0 -> 3843 bytes .../textures/gui/essentia_terminal.png | Bin 0 -> 4163 bytes .../gui/essentia_vibration_chamber.png | Bin 0 -> 4812 bytes .../textures/gui/knowledge_inscriber.png | Bin 0 -> 4897 bytes .../textures/gui/priority.png | Bin 0 -> 1256 bytes .../textures/gui/states.png | Bin 0 -> 6282 bytes .../item/arcane_crafting_terminal.png | Bin 0 -> 3061 bytes .../textures/item/essentia_cell_16k.png | Bin 0 -> 3078 bytes .../textures/item/essentia_cell_1k.png | Bin 0 -> 3058 bytes .../textures/item/essentia_cell_4k.png | Bin 0 -> 3060 bytes .../textures/item/essentia_cell_64k.png | Bin 0 -> 3080 bytes .../textures/item/essentia_cell_casing.png | Bin 0 -> 3061 bytes .../textures/item/essentia_cell_creative.png | Bin 0 -> 3113 bytes .../textures/item/essentia_level_emitter.png | Bin 0 -> 3254 bytes .../textures/item/foci_aewrench.png | Bin 0 -> 3296 bytes .../textures/item/focus_aewrench.png | Bin 0 -> 3296 bytes .../textures/item/golem_wifi_backpack.png | Bin 0 -> 3064 bytes .../textures/item/knowledge_core.png | Bin 0 -> 15626 bytes .../textures/item/knowledge_core.png.mcmeta | 5 + .../item/material_coalescence_core.png | Bin 0 -> 3000 bytes .../textures/item/material_diffusion_core.png | Bin 0 -> 2945 bytes .../textures/item/storage_component_16k.png | Bin 0 -> 2974 bytes .../textures/item/storage_component_1k.png | Bin 0 -> 2971 bytes .../textures/item/storage_component_4k.png | Bin 0 -> 2961 bytes .../textures/item/storage_component_64k.png | Bin 0 -> 3053 bytes .../item/wireless_essentia_terminal.png | Bin 0 -> 3460 bytes .../textures/model/golemBackpack/Clay.png | Bin 0 -> 4252 bytes .../textures/model/golemBackpack/Diamond.png | Bin 0 -> 4208 bytes .../textures/model/golemBackpack/Flesh.png | Bin 0 -> 4410 bytes .../textures/model/golemBackpack/Gold.png | Bin 0 -> 4348 bytes .../textures/model/golemBackpack/Iron.png | Bin 0 -> 4234 bytes .../textures/model/golemBackpack/Stone.png | Bin 0 -> 4343 bytes .../textures/model/golemBackpack/Straw.png | Bin 0 -> 4405 bytes .../textures/model/golemBackpack/Tallow.png | Bin 0 -> 4242 bytes .../textures/model/golemBackpack/Thaum.png | Bin 0 -> 3836 bytes .../textures/model/golemBackpack/Wood.png | Bin 0 -> 4276 bytes .../arcane_crafting_overlay1.png | Bin 0 -> 1498 bytes .../arcane_crafting_overlay2.png | Bin 0 -> 2841 bytes .../arcane_crafting_overlay3.png | Bin 0 -> 1066 bytes .../arcane_crafting_overlay4.png | Bin 0 -> 2850 bytes .../arcane_crafting_side.png | Bin 0 -> 1605 bytes .../part/essentia_export_bus_face.png | Bin 0 -> 328 bytes .../part/essentia_import_bus_face.png | Bin 0 -> 300 bytes .../part/essentia_storage_bus_face.png | Bin 0 -> 301 bytes .../part/essentia_terminal/bright.png | Bin 0 -> 2996 bytes .../textures/part/essentia_terminal/dark.png | Bin 0 -> 1156 bytes .../part/essentia_terminal/medium.png | Bin 0 -> 1042 bytes .../textures/part/vis_interface.png | Bin 0 -> 7395 bytes .../textures/part/vis_interface.png.mcmeta | 5 + .../textures/part/vis_interface_runes.png | Bin 0 -> 2884 bytes .../textures/part/vis_interface_side.png | Bin 0 -> 3175 bytes .../textures/research/research_background.png | Bin 0 -> 279672 bytes .../textures/research/tab_icon.png | Bin 0 -> 5479 bytes .../recipe/essentia_cell_16k.json | 19 + .../recipe/essentia_cell_16k_shapeless.json | 12 + .../recipe/essentia_cell_1k.json | 19 + .../recipe/essentia_cell_1k_shapeless.json | 12 + .../recipe/essentia_cell_4k.json | 19 + .../recipe/essentia_cell_4k_shapeless.json | 12 + .../recipe/essentia_cell_64k.json | 19 + .../recipe/essentia_cell_64k_shapeless.json | 12 + .../essentia_cell_workbench_shapeless.json | 16 + .../recipe/storage_casing.json | 18 + .../wireless_essentia_terminal_shapeless.json | 19 + .../tags/item/essentia_cell_glass.json | 6 + .../tags/item/wisp_essences.json | 53 ++ .../resources/thaumicenergistics.mixins.json | 18 + 322 files changed, 15941 insertions(+) create mode 100644 build.gradle create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 settings.gradle create mode 100644 src/main/java/thaumicenergistics/ThaumicEnergistics.java create mode 100644 src/main/java/thaumicenergistics/api/IThETransportPermissions.java create mode 100644 src/main/java/thaumicenergistics/api/grid/ICraftingIssuerHost.java create mode 100644 src/main/java/thaumicenergistics/api/grid/IDigiVisSource.java create mode 100644 src/main/java/thaumicenergistics/api/grid/IEssentiaGrid.java create mode 100644 src/main/java/thaumicenergistics/api/grid/IEssentiaWatcher.java create mode 100644 src/main/java/thaumicenergistics/api/grid/IEssentiaWatcherHost.java create mode 100644 src/main/java/thaumicenergistics/api/storage/AspectStack.java create mode 100644 src/main/java/thaumicenergistics/api/storage/IAspectStack.java create mode 100644 src/main/java/thaumicenergistics/client/ClientInit.java create mode 100644 src/main/java/thaumicenergistics/client/ClientSetup.java create mode 100644 src/main/java/thaumicenergistics/client/EssentiaKeyRenderHandler.java create mode 100644 src/main/java/thaumicenergistics/client/render/RenderTileArcaneAssembler.java create mode 100644 src/main/java/thaumicenergistics/client/render/RenderTileEVC.java create mode 100644 src/main/java/thaumicenergistics/client/render/layer/GolemBackpackLayer.java create mode 100644 src/main/java/thaumicenergistics/client/render/model/GolemBackpackModel.java create mode 100644 src/main/java/thaumicenergistics/common/WrenchFocusHandler.java create mode 100644 src/main/java/thaumicenergistics/common/blocks/OrientableEntityBlock.java create mode 100644 src/main/java/thaumicenergistics/common/blocks/ThEBaseEntityBlock.java create mode 100644 src/main/java/thaumicenergistics/common/container/ContainerArcaneAssembler.java create mode 100644 src/main/java/thaumicenergistics/common/container/ContainerArcaneCraftingTerminal.java create mode 100644 src/main/java/thaumicenergistics/common/container/ContainerDistillationPatternEncoder.java create mode 100644 src/main/java/thaumicenergistics/common/container/ContainerEssentiaCellTerminal.java create mode 100644 src/main/java/thaumicenergistics/common/container/ContainerEssentiaCellWorkbench.java create mode 100644 src/main/java/thaumicenergistics/common/container/ContainerEssentiaExportBus.java create mode 100644 src/main/java/thaumicenergistics/common/container/ContainerEssentiaImportBus.java create mode 100644 src/main/java/thaumicenergistics/common/container/ContainerEssentiaLevelEmitter.java create mode 100644 src/main/java/thaumicenergistics/common/container/ContainerEssentiaStorageBus.java create mode 100644 src/main/java/thaumicenergistics/common/container/ContainerEssentiaVibrationChamber.java create mode 100644 src/main/java/thaumicenergistics/common/container/ContainerKnowledgeInscriber.java create mode 100644 src/main/java/thaumicenergistics/common/container/GuiArcaneAssembler.java create mode 100644 src/main/java/thaumicenergistics/common/container/GuiArcaneCraftingTerminal.java create mode 100644 src/main/java/thaumicenergistics/common/container/GuiDistillationPatternEncoder.java create mode 100644 src/main/java/thaumicenergistics/common/container/GuiEssentiaCellTerminal.java create mode 100644 src/main/java/thaumicenergistics/common/container/GuiEssentiaCellWorkbench.java create mode 100644 src/main/java/thaumicenergistics/common/container/GuiEssentiaExportBus.java create mode 100644 src/main/java/thaumicenergistics/common/container/GuiEssentiaImportBus.java create mode 100644 src/main/java/thaumicenergistics/common/container/GuiEssentiaLevelEmitter.java create mode 100644 src/main/java/thaumicenergistics/common/container/GuiEssentiaStorageBus.java create mode 100644 src/main/java/thaumicenergistics/common/container/GuiEssentiaVibrationChamber.java create mode 100644 src/main/java/thaumicenergistics/common/container/GuiKnowledgeInscriber.java create mode 100644 src/main/java/thaumicenergistics/common/container/SimpleMenuProvider.java create mode 100644 src/main/java/thaumicenergistics/common/container/ThEContainerBase.java create mode 100644 src/main/java/thaumicenergistics/common/container/slot/ArcaneCraftingResultSlot.java create mode 100644 src/main/java/thaumicenergistics/common/container/slot/GhostSlot.java create mode 100644 src/main/java/thaumicenergistics/common/entities/BackpackSkins.java create mode 100644 src/main/java/thaumicenergistics/common/entities/FacadeToSkinMapping.java create mode 100644 src/main/java/thaumicenergistics/common/entities/GolemBackpackHandler.java create mode 100644 src/main/java/thaumicenergistics/common/entities/GolemBackpackTickHandler.java create mode 100644 src/main/java/thaumicenergistics/common/entities/WirelessAELinkGolem.java create mode 100644 src/main/java/thaumicenergistics/common/features/FeatureAutocraftingArcane.java create mode 100644 src/main/java/thaumicenergistics/common/features/FeatureCells.java create mode 100644 src/main/java/thaumicenergistics/common/features/FeatureEssentiaIOBuses.java create mode 100644 src/main/java/thaumicenergistics/common/features/FeatureEssentiaMonitoring.java create mode 100644 src/main/java/thaumicenergistics/common/features/FeatureEssentiaProvider.java create mode 100644 src/main/java/thaumicenergistics/common/features/FeatureEssentiaVibrationChamber.java create mode 100644 src/main/java/thaumicenergistics/common/features/FeatureGolemBackpack.java create mode 100644 src/main/java/thaumicenergistics/common/features/FeatureInfusionProvider.java create mode 100644 src/main/java/thaumicenergistics/common/features/FeatureRegistry.java create mode 100644 src/main/java/thaumicenergistics/common/features/FeatureVisRelayInterface.java create mode 100644 src/main/java/thaumicenergistics/common/features/RecipeRegistration.java create mode 100644 src/main/java/thaumicenergistics/common/features/ThEFeatureBase.java create mode 100644 src/main/java/thaumicenergistics/common/grid/AEPartGridBlock.java create mode 100644 src/main/java/thaumicenergistics/common/grid/EssentiaGridService.java create mode 100644 src/main/java/thaumicenergistics/common/grid/EssentiaMonitor.java create mode 100644 src/main/java/thaumicenergistics/common/grid/EssentiaMonitorRegistry.java create mode 100644 src/main/java/thaumicenergistics/common/grid/EssentiaWatcher.java create mode 100644 src/main/java/thaumicenergistics/common/grid/GridEssentiaCache.java create mode 100644 src/main/java/thaumicenergistics/common/integration/appeng/AEssentiaKey.java create mode 100644 src/main/java/thaumicenergistics/common/integration/appeng/AEssentiaKeyType.java create mode 100644 src/main/java/thaumicenergistics/common/integration/appeng/EssentiaStorageChannel.java create mode 100644 src/main/java/thaumicenergistics/common/integration/appeng/ThEAppliedEnergistics.java create mode 100644 src/main/java/thaumicenergistics/common/integration/jade/ThEJadePlugin.java create mode 100644 src/main/java/thaumicenergistics/common/integration/jade/VibrationChamberProvider.java create mode 100644 src/main/java/thaumicenergistics/common/integration/tc/ArcaneCraftingPattern.java create mode 100644 src/main/java/thaumicenergistics/common/integration/tc/EssentiaConversionHelper.java create mode 100644 src/main/java/thaumicenergistics/common/integration/tc/PseudoResearchItem.java create mode 100644 src/main/java/thaumicenergistics/common/integration/tc/TCReflection.java create mode 100644 src/main/java/thaumicenergistics/common/integration/tc/ThEThaumcraft.java create mode 100644 src/main/java/thaumicenergistics/common/integration/tc/VisProviderProxy.java create mode 100644 src/main/java/thaumicenergistics/common/inventory/HandlerKnowledgeCore.java create mode 100644 src/main/java/thaumicenergistics/common/items/ItemEssentiaCell.java create mode 100644 src/main/java/thaumicenergistics/common/items/ItemFocusAEWrench.java create mode 100644 src/main/java/thaumicenergistics/common/items/ItemGolemWirelessBackpack.java create mode 100644 src/main/java/thaumicenergistics/common/items/PartItemArcaneCraftingTerminal.java create mode 100644 src/main/java/thaumicenergistics/common/items/PartItemEssentiaExportBus.java create mode 100644 src/main/java/thaumicenergistics/common/items/PartItemEssentiaImportBus.java create mode 100644 src/main/java/thaumicenergistics/common/items/PartItemEssentiaLevelEmitter.java create mode 100644 src/main/java/thaumicenergistics/common/items/PartItemEssentiaStorageBus.java create mode 100644 src/main/java/thaumicenergistics/common/items/PartItemEssentiaTerminal.java create mode 100644 src/main/java/thaumicenergistics/common/items/PartItemVisInterface.java create mode 100644 src/main/java/thaumicenergistics/common/items/WirelessEssentiaTerminalItem.java create mode 100644 src/main/java/thaumicenergistics/common/items/WirelessEssentiaTerminalMenuHost.java create mode 100644 src/main/java/thaumicenergistics/common/network/CellWorkbenchC2SPacket.java create mode 100644 src/main/java/thaumicenergistics/common/network/CellWorkbenchSyncPacket.java create mode 100644 src/main/java/thaumicenergistics/common/network/GolemBackpackClientData.java create mode 100644 src/main/java/thaumicenergistics/common/network/GolemBackpackSyncPacket.java create mode 100644 src/main/java/thaumicenergistics/common/network/KnowledgeInscriberGhostSlotPacket.java create mode 100644 src/main/java/thaumicenergistics/common/network/ThENetworking.java create mode 100644 src/main/java/thaumicenergistics/common/parts/ArcaneCraftingTerminalPart.java create mode 100644 src/main/java/thaumicenergistics/common/parts/EssentiaExportBusPart.java create mode 100644 src/main/java/thaumicenergistics/common/parts/EssentiaImportBusPart.java create mode 100644 src/main/java/thaumicenergistics/common/parts/EssentiaLevelEmitterPart.java create mode 100644 src/main/java/thaumicenergistics/common/parts/EssentiaStorageBusPart.java create mode 100644 src/main/java/thaumicenergistics/common/parts/EssentiaTerminalPart.java create mode 100644 src/main/java/thaumicenergistics/common/parts/VisInterfacePart.java create mode 100644 src/main/java/thaumicenergistics/common/storage/TransportPermissions.java create mode 100644 src/main/java/thaumicenergistics/common/tiles/ThETileBase.java create mode 100644 src/main/java/thaumicenergistics/common/tiles/TileArcaneAssembler.java create mode 100644 src/main/java/thaumicenergistics/common/tiles/TileDistillationPatternEncoder.java create mode 100644 src/main/java/thaumicenergistics/common/tiles/TileEssentiaCellWorkbench.java create mode 100644 src/main/java/thaumicenergistics/common/tiles/TileEssentiaProvider.java create mode 100644 src/main/java/thaumicenergistics/common/tiles/TileEssentiaVibrationChamber.java create mode 100644 src/main/java/thaumicenergistics/common/tiles/TileInfusionProvider.java create mode 100644 src/main/java/thaumicenergistics/common/tiles/TileKnowledgeInscriber.java create mode 100644 src/main/java/thaumicenergistics/common/tiles/TileProviderBase.java create mode 100644 src/main/java/thaumicenergistics/config/ThEConfig.java create mode 100644 src/main/java/thaumicenergistics/init/ModBlockEntities.java create mode 100644 src/main/java/thaumicenergistics/init/ModBlocks.java create mode 100644 src/main/java/thaumicenergistics/init/ModCreativeTab.java create mode 100644 src/main/java/thaumicenergistics/init/ModItems.java create mode 100644 src/main/java/thaumicenergistics/init/ModMenuTypes.java create mode 100644 src/main/java/thaumicenergistics/integration/jei/Ae2JeiCompat.java create mode 100644 src/main/java/thaumicenergistics/integration/jei/ArcaneCraftingTransferInfo.java create mode 100644 src/main/java/thaumicenergistics/integration/jei/ArcaneRecipeTransferInfo.java create mode 100644 src/main/java/thaumicenergistics/integration/jei/AspectIngredient.java create mode 100644 src/main/java/thaumicenergistics/integration/jei/AspectIngredientHelper.java create mode 100644 src/main/java/thaumicenergistics/integration/jei/AspectIngredientRenderer.java create mode 100644 src/main/java/thaumicenergistics/integration/jei/AspectIngredientType.java create mode 100644 src/main/java/thaumicenergistics/integration/jei/CellWorkbenchGhostIngredientHandler.java create mode 100644 src/main/java/thaumicenergistics/integration/jei/EssentiaIngredientConverter.java create mode 100644 src/main/java/thaumicenergistics/integration/jei/ThEArcaneCraftingTransferInfo.java create mode 100644 src/main/java/thaumicenergistics/integration/jei/ThEGhostIngredientHandler.java create mode 100644 src/main/java/thaumicenergistics/integration/jei/ThEJeiPlugin.java create mode 100644 src/main/java/thaumicenergistics/integration/jei/ThEUseArcaneRecipeTransfer.java create mode 100644 src/main/java/thaumicenergistics/integration/jei/ThEUseCraftingRecipeTransfer.java create mode 100644 src/main/java/thaumicenergistics/mixins/ae2/MixinAbstractTerminalPart.java create mode 100644 src/main/java/thaumicenergistics/mixins/ae2/MixinConfigMenuInventory.java create mode 100644 src/main/java/thaumicenergistics/mixins/ae2/MixinCraftingTreeProcess.java create mode 100644 src/main/java/thaumicenergistics/mixins/tc/MixinAspect.java create mode 100644 src/main/java/thaumicenergistics/mixins/tc/MixinThaumonomiconScreen.java create mode 100644 src/main/java/thaumicenergistics/mixins/tc/MixinVisRelayBlock.java create mode 100644 src/main/java/thaumicenergistics/mixins/tc/ResearchPageIndexMixin.java create mode 100644 src/main/resources/META-INF/neoforge.mods.toml create mode 100644 src/main/resources/META-INF/services/snownee.jade.api.IWailaPlugin create mode 100644 src/main/resources/META-INF/services/tamaized.ae2jeiintegration.api.integrations.jei.IngredientConverter create mode 100644 src/main/resources/assets/ae2/screens/arcane_crafting_terminal.json create mode 100644 src/main/resources/assets/ae2/screens/aspect_filter_selection.json create mode 100644 src/main/resources/assets/ae2/screens/essentia_level_emitter.json create mode 100644 src/main/resources/assets/thaumicenergistics/blockstates/arcane_assembler.json create mode 100644 src/main/resources/assets/thaumicenergistics/blockstates/distillation_encoder.json create mode 100644 src/main/resources/assets/thaumicenergistics/blockstates/essentia_cell_workbench.json create mode 100644 src/main/resources/assets/thaumicenergistics/blockstates/essentia_provider.json create mode 100644 src/main/resources/assets/thaumicenergistics/blockstates/essentia_vibration_chamber.json create mode 100644 src/main/resources/assets/thaumicenergistics/blockstates/infusion_provider.json create mode 100644 src/main/resources/assets/thaumicenergistics/blockstates/knowledge_inscriber.json create mode 100644 src/main/resources/assets/thaumicenergistics/lang/en_us.json create mode 100644 src/main/resources/assets/thaumicenergistics/lang/zh_cn.json create mode 100644 src/main/resources/assets/thaumicenergistics/meta/logo.png create mode 100644 src/main/resources/assets/thaumicenergistics/models/block/arcane_assembler.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/block/distillation_encoder.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/block/essentia_cell_workbench.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/block/essentia_provider.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/block/essentia_vibration_chamber.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/block/infusion_provider.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/block/knowledge_inscriber.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/arcane_assembler.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/arcane_crafting_terminal.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/coalescence_core.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/diffusion_core.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/distillation_encoder.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/essentia_cell_16k.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/essentia_cell_1k.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/essentia_cell_4k.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/essentia_cell_64k.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/essentia_cell_creative.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/essentia_cell_workbench.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/essentia_export_bus.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/essentia_import_bus.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/essentia_level_emitter.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/essentia_provider.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/essentia_storage_bus.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/essentia_terminal.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/essentia_vibration_chamber.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/focus_aewrench.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/golem_wifi_backpack.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/infusion_provider.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/knowledge_core.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/knowledge_inscriber.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/storage_casing.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/storage_component_16k.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/storage_component_1k.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/storage_component_4k.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/storage_component_64k.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/vis_interface.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/item/wireless_essentia_terminal.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/parts/arcane_crafting_terminal_base.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/parts/arcane_crafting_terminal_has_channel.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/parts/arcane_crafting_terminal_off.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/parts/arcane_crafting_terminal_on.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/parts/essentia_export_bus_base.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/parts/essentia_export_bus_has_channel.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/parts/essentia_export_bus_off.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/parts/essentia_export_bus_on.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/parts/essentia_import_bus_base.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/parts/essentia_import_bus_has_channel.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/parts/essentia_import_bus_off.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/parts/essentia_import_bus_on.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/parts/essentia_level_emitter_base_off.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/parts/essentia_level_emitter_base_on.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/parts/essentia_level_emitter_status_has_channel.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/parts/essentia_level_emitter_status_off.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/parts/essentia_level_emitter_status_on.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/parts/essentia_storage_bus_base.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/parts/essentia_storage_bus_has_channel.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/parts/essentia_storage_bus_off.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/parts/essentia_storage_bus_on.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/parts/essentia_terminal_base.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/parts/essentia_terminal_has_channel.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/parts/essentia_terminal_off.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/parts/essentia_terminal_on.json create mode 100644 src/main/resources/assets/thaumicenergistics/models/parts/p2p/p2p_tunnel_vis.json create mode 100644 src/main/resources/assets/thaumicenergistics/screens/aspect_filter_selection.json create mode 100644 src/main/resources/assets/thaumicenergistics/screens/essentia_export_bus.json create mode 100644 src/main/resources/assets/thaumicenergistics/screens/essentia_import_bus.json create mode 100644 src/main/resources/assets/thaumicenergistics/screens/essentia_storage_bus.json create mode 100644 src/main/resources/assets/thaumicenergistics/textures/block/arcane_assembler_fallback.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/block/distillation_encoder_face.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/block/e_vibration_face_ignis.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/block/e_vibration_face_ignis.png.mcmeta create mode 100644 src/main/resources/assets/thaumicenergistics/textures/block/e_vibration_face_off.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/block/e_vibration_face_potentia.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/block/e_vibration_face_potentia.png.mcmeta create mode 100644 src/main/resources/assets/thaumicenergistics/textures/block/e_vibration_input.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/block/essentia_cell_workbench_bottom.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/block/essentia_cell_workbench_side.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/block/essentia_cell_workbench_top.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/block/essentia_gas.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/block/essentia_gas.png.mcmeta create mode 100644 src/main/resources/assets/thaumicenergistics/textures/block/essentia_provider.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/block/essentia_provider_overlay.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/block/infusion_provider.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/block/infusion_provider_overlay.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/block/knowledge_inscriber_bottom.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/block/knowledge_inscriber_side.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/block/knowledge_inscriber_top.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/gui/arcane_assembler.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/gui/arcane_crafting.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/gui/distillation_encoder.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/gui/essentia_cell_workbench.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/gui/essentia_level_emitter.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/gui/essentia_terminal.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/gui/essentia_vibration_chamber.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/gui/knowledge_inscriber.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/gui/priority.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/gui/states.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/item/arcane_crafting_terminal.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/item/essentia_cell_16k.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/item/essentia_cell_1k.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/item/essentia_cell_4k.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/item/essentia_cell_64k.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/item/essentia_cell_casing.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/item/essentia_cell_creative.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/item/essentia_level_emitter.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/item/foci_aewrench.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/item/focus_aewrench.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/item/golem_wifi_backpack.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/item/knowledge_core.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/item/knowledge_core.png.mcmeta create mode 100644 src/main/resources/assets/thaumicenergistics/textures/item/material_coalescence_core.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/item/material_diffusion_core.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/item/storage_component_16k.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/item/storage_component_1k.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/item/storage_component_4k.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/item/storage_component_64k.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/item/wireless_essentia_terminal.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/model/golemBackpack/Clay.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/model/golemBackpack/Diamond.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/model/golemBackpack/Flesh.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/model/golemBackpack/Gold.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/model/golemBackpack/Iron.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/model/golemBackpack/Stone.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/model/golemBackpack/Straw.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/model/golemBackpack/Tallow.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/model/golemBackpack/Thaum.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/model/golemBackpack/Wood.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/part/arcane_crafting_terminal/arcane_crafting_overlay1.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/part/arcane_crafting_terminal/arcane_crafting_overlay2.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/part/arcane_crafting_terminal/arcane_crafting_overlay3.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/part/arcane_crafting_terminal/arcane_crafting_overlay4.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/part/arcane_crafting_terminal/arcane_crafting_side.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/part/essentia_export_bus_face.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/part/essentia_import_bus_face.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/part/essentia_storage_bus_face.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/part/essentia_terminal/bright.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/part/essentia_terminal/dark.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/part/essentia_terminal/medium.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/part/vis_interface.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/part/vis_interface.png.mcmeta create mode 100644 src/main/resources/assets/thaumicenergistics/textures/part/vis_interface_runes.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/part/vis_interface_side.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/research/research_background.png create mode 100644 src/main/resources/assets/thaumicenergistics/textures/research/tab_icon.png create mode 100644 src/main/resources/data/thaumicenergistics/recipe/essentia_cell_16k.json create mode 100644 src/main/resources/data/thaumicenergistics/recipe/essentia_cell_16k_shapeless.json create mode 100644 src/main/resources/data/thaumicenergistics/recipe/essentia_cell_1k.json create mode 100644 src/main/resources/data/thaumicenergistics/recipe/essentia_cell_1k_shapeless.json create mode 100644 src/main/resources/data/thaumicenergistics/recipe/essentia_cell_4k.json create mode 100644 src/main/resources/data/thaumicenergistics/recipe/essentia_cell_4k_shapeless.json create mode 100644 src/main/resources/data/thaumicenergistics/recipe/essentia_cell_64k.json create mode 100644 src/main/resources/data/thaumicenergistics/recipe/essentia_cell_64k_shapeless.json create mode 100644 src/main/resources/data/thaumicenergistics/recipe/essentia_cell_workbench_shapeless.json create mode 100644 src/main/resources/data/thaumicenergistics/recipe/storage_casing.json create mode 100644 src/main/resources/data/thaumicenergistics/recipe/wireless_essentia_terminal_shapeless.json create mode 100644 src/main/resources/data/thaumicenergistics/tags/item/essentia_cell_glass.json create mode 100644 src/main/resources/data/thaumicenergistics/tags/item/wisp_essences.json create mode 100644 src/main/resources/thaumicenergistics.mixins.json diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..abdeec5 --- /dev/null +++ b/build.gradle @@ -0,0 +1,74 @@ +plugins { + id 'net.neoforged.moddev' version '2.0.78' + id 'maven-publish' +} + +repositories { + mavenCentral() + def localRepository = mavenLocal() + remove(localRepository) + add(0, localRepository) + // CurseMaven for Jade and other mods + maven { + url "https://cursemaven.com" + content { + includeGroup "curse.maven" + } + } + // Modrinth for Jade + maven { + url "https://api.modrinth.com/maven" + } +} + +version = mod_version +group = mod_group + +var modName = mod_name +var mcVersion = minecraft_version +base { archivesName = "${modName}-${mcVersion}-neoforge" } + +java { + toolchain.languageVersion = JavaLanguageVersion.of(21) + withSourcesJar() +} + +neoForge { + version = neoforge_version + runs { + client { client() } + server { server() } + } + mods { "${mod_id}" { sourceSet sourceSets.main } } +} + +dependencies { + compileOnly "org.appliedenergistics:appliedenergistics2:19.2.17:api" + compileOnly "org.appliedenergistics:appliedenergistics2:19.2.17" // 加这行保留!!让AE2内部类可编译 + compileOnly files('library/thaumcraft-0.2.2.34-port.1.jar') + compileOnly files('library/jei-1.21.1-neoforge-19.39.0.368.jar') + compileOnly files('library/ae2jeiintegration-1.2.1.jar') + compileOnly "maven.modrinth:jade:${jade_version}" +} + + +tasks.withType(JavaCompile).configureEach { + it.options.encoding = 'UTF-8' + it.options.release = 21 +} + +var modVersion = mod_version +def loaderRange = project.findProperty('loader_version_range') ?: '[4,)' +def neoforgeRange = project.findProperty('neoforge_version_range') ?: '[21,)' +def mcRange = project.findProperty('minecraft_version_range') ?: '[1.21.1,1.22)' + +processResources { + filesMatching('META-INF/neoforge.mods.toml') { + expand([ + 'version': modVersion, 'loader_version_range': loaderRange, + 'neoforge_version_range': neoforgeRange, 'minecraft_version_range': mcRange + ]) + } +} + +jar { duplicatesStrategy = DuplicatesStrategy.EXCLUDE } diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..fcd0b01 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,18 @@ +# Project +mod_version=2.0.1-alpha +mod_group=thaumicenergistics + +# Mod +mod_name=ThaumicEnergistics +mod_id=thaumicenergistics +mod_author=Nividica & Community + +# Shared (must match root gradle.properties) +minecraft_version=1.21.1 +neoforge_version=21.1.234 + +# Dependency versions +ae2_version=19.2.17 +jei_version=19.39.0.368 +thaumcraft_version=0.2.2.34-port.1 +jade_version=15.9.1+neoforge diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..e6441136f3d4ba8a0da8d277868979cfbc8ad796 GIT binary patch literal 43453 zcma&N1CXTcmMvW9vTb(Rwr$&4wr$(C?dmSu>@vG-+vuvg^_??!{yS%8zW-#zn-LkA z5&1^$^{lnmUON?}LBF8_K|(?T0Ra(xUH{($5eN!MR#ZihR#HxkUPe+_R8Cn`RRs(P z_^*#_XlXmGv7!4;*Y%p4nw?{bNp@UZHv1?Um8r6)Fei3p@ClJn0ECfg1hkeuUU@Or zDaPa;U3fE=3L}DooL;8f;P0ipPt0Z~9P0)lbStMS)ag54=uL9ia-Lm3nh|@(Y?B`; zx_#arJIpXH!U{fbCbI^17}6Ri*H<>OLR%c|^mh8+)*h~K8Z!9)DPf zR2h?lbDZQ`p9P;&DQ4F0sur@TMa!Y}S8irn(%d-gi0*WxxCSk*A?3lGh=gcYN?FGl z7D=Js!i~0=u3rox^eO3i@$0=n{K1lPNU zwmfjRVmLOCRfe=seV&P*1Iq=^i`502keY8Uy-WNPwVNNtJFx?IwAyRPZo2Wo1+S(xF37LJZ~%i)kpFQ3Fw=mXfd@>%+)RpYQLnr}B~~zoof(JVm^^&f zxKV^+3D3$A1G;qh4gPVjhrC8e(VYUHv#dy^)(RoUFM?o%W-EHxufuWf(l*@-l+7vt z=l`qmR56K~F|v<^Pd*p~1_y^P0P^aPC##d8+HqX4IR1gu+7w#~TBFphJxF)T$2WEa zxa?H&6=Qe7d(#tha?_1uQys2KtHQ{)Qco)qwGjrdNL7thd^G5i8Os)CHqc>iOidS} z%nFEDdm=GXBw=yXe1W-ShHHFb?Cc70+$W~z_+}nAoHFYI1MV1wZegw*0y^tC*s%3h zhD3tN8b=Gv&rj}!SUM6|ajSPp*58KR7MPpI{oAJCtY~JECm)*m_x>AZEu>DFgUcby z1Qaw8lU4jZpQ_$;*7RME+gq1KySGG#Wql>aL~k9tLrSO()LWn*q&YxHEuzmwd1?aAtI zBJ>P=&$=l1efe1CDU;`Fd+_;&wI07?V0aAIgc(!{a z0Jg6Y=inXc3^n!U0Atk`iCFIQooHqcWhO(qrieUOW8X(x?(RD}iYDLMjSwffH2~tB z)oDgNBLB^AJBM1M^c5HdRx6fBfka`(LD-qrlh5jqH~);#nw|iyp)()xVYak3;Ybik z0j`(+69aK*B>)e_p%=wu8XC&9e{AO4c~O1U`5X9}?0mrd*m$_EUek{R?DNSh(=br# z#Q61gBzEpmy`$pA*6!87 zSDD+=@fTY7<4A?GLqpA?Pb2z$pbCc4B4zL{BeZ?F-8`s$?>*lXXtn*NC61>|*w7J* z$?!iB{6R-0=KFmyp1nnEmLsA-H0a6l+1uaH^g%c(p{iT&YFrbQ$&PRb8Up#X3@Zsk zD^^&LK~111%cqlP%!_gFNa^dTYT?rhkGl}5=fL{a`UViaXWI$k-UcHJwmaH1s=S$4 z%4)PdWJX;hh5UoK?6aWoyLxX&NhNRqKam7tcOkLh{%j3K^4Mgx1@i|Pi&}<^5>hs5 zm8?uOS>%)NzT(%PjVPGa?X%`N2TQCKbeH2l;cTnHiHppPSJ<7y-yEIiC!P*ikl&!B z%+?>VttCOQM@ShFguHVjxX^?mHX^hSaO_;pnyh^v9EumqSZTi+#f&_Vaija0Q-e*| z7ulQj6Fs*bbmsWp{`auM04gGwsYYdNNZcg|ph0OgD>7O}Asn7^Z=eI>`$2*v78;sj-}oMoEj&@)9+ycEOo92xSyY344^ z11Hb8^kdOvbf^GNAK++bYioknrpdN>+u8R?JxG=!2Kd9r=YWCOJYXYuM0cOq^FhEd zBg2puKy__7VT3-r*dG4c62Wgxi52EMCQ`bKgf*#*ou(D4-ZN$+mg&7$u!! z-^+Z%;-3IDwqZ|K=ah85OLwkO zKxNBh+4QHh)u9D?MFtpbl)us}9+V!D%w9jfAMYEb>%$A;u)rrI zuBudh;5PN}_6J_}l55P3l_)&RMlH{m!)ai-i$g)&*M`eN$XQMw{v^r@-125^RRCF0 z^2>|DxhQw(mtNEI2Kj(;KblC7x=JlK$@78`O~>V!`|1Lm-^JR$-5pUANAnb(5}B}JGjBsliK4& zk6y(;$e&h)lh2)L=bvZKbvh@>vLlreBdH8No2>$#%_Wp1U0N7Ank!6$dFSi#xzh|( zRi{Uw%-4W!{IXZ)fWx@XX6;&(m_F%c6~X8hx=BN1&q}*( zoaNjWabE{oUPb!Bt$eyd#$5j9rItB-h*5JiNi(v^e|XKAj*8(k<5-2$&ZBR5fF|JA z9&m4fbzNQnAU}r8ab>fFV%J0z5awe#UZ|bz?Ur)U9bCIKWEzi2%A+5CLqh?}K4JHi z4vtM;+uPsVz{Lfr;78W78gC;z*yTch~4YkLr&m-7%-xc ztw6Mh2d>_iO*$Rd8(-Cr1_V8EO1f*^@wRoSozS) zy1UoC@pruAaC8Z_7~_w4Q6n*&B0AjOmMWa;sIav&gu z|J5&|{=a@vR!~k-OjKEgPFCzcJ>#A1uL&7xTDn;{XBdeM}V=l3B8fE1--DHjSaxoSjNKEM9|U9#m2<3>n{Iuo`r3UZp;>GkT2YBNAh|b z^jTq-hJp(ebZh#Lk8hVBP%qXwv-@vbvoREX$TqRGTgEi$%_F9tZES@z8Bx}$#5eeG zk^UsLBH{bc2VBW)*EdS({yw=?qmevwi?BL6*=12k9zM5gJv1>y#ML4!)iiPzVaH9% zgSImetD@dam~e>{LvVh!phhzpW+iFvWpGT#CVE5TQ40n%F|p(sP5mXxna+Ev7PDwA zamaV4m*^~*xV+&p;W749xhb_X=$|LD;FHuB&JL5?*Y2-oIT(wYY2;73<^#46S~Gx| z^cez%V7x$81}UWqS13Gz80379Rj;6~WdiXWOSsdmzY39L;Hg3MH43o*y8ibNBBH`(av4|u;YPq%{R;IuYow<+GEsf@R?=@tT@!}?#>zIIn0CoyV!hq3mw zHj>OOjfJM3F{RG#6ujzo?y32m^tgSXf@v=J$ELdJ+=5j|=F-~hP$G&}tDZsZE?5rX ztGj`!S>)CFmdkccxM9eGIcGnS2AfK#gXwj%esuIBNJQP1WV~b~+D7PJTmWGTSDrR` zEAu4B8l>NPuhsk5a`rReSya2nfV1EK01+G!x8aBdTs3Io$u5!6n6KX%uv@DxAp3F@{4UYg4SWJtQ-W~0MDb|j-$lwVn znAm*Pl!?Ps&3wO=R115RWKb*JKoexo*)uhhHBncEDMSVa_PyA>k{Zm2(wMQ(5NM3# z)jkza|GoWEQo4^s*wE(gHz?Xsg4`}HUAcs42cM1-qq_=+=!Gk^y710j=66(cSWqUe zklbm8+zB_syQv5A2rj!Vbw8;|$@C!vfNmNV!yJIWDQ>{+2x zKjuFX`~~HKG~^6h5FntRpnnHt=D&rq0>IJ9#F0eM)Y-)GpRjiN7gkA8wvnG#K=q{q z9dBn8_~wm4J<3J_vl|9H{7q6u2A!cW{bp#r*-f{gOV^e=8S{nc1DxMHFwuM$;aVI^ zz6A*}m8N-&x8;aunp1w7_vtB*pa+OYBw=TMc6QK=mbA-|Cf* zvyh8D4LRJImooUaSb7t*fVfih<97Gf@VE0|z>NcBwBQze);Rh!k3K_sfunToZY;f2 z^HmC4KjHRVg+eKYj;PRN^|E0>Gj_zagfRbrki68I^#~6-HaHg3BUW%+clM1xQEdPYt_g<2K+z!$>*$9nQ>; zf9Bei{?zY^-e{q_*|W#2rJG`2fy@{%6u0i_VEWTq$*(ZN37|8lFFFt)nCG({r!q#9 z5VK_kkSJ3?zOH)OezMT{!YkCuSSn!K#-Rhl$uUM(bq*jY? zi1xbMVthJ`E>d>(f3)~fozjg^@eheMF6<)I`oeJYx4*+M&%c9VArn(OM-wp%M<-`x z7sLP1&3^%Nld9Dhm@$3f2}87!quhI@nwd@3~fZl_3LYW-B?Ia>ui`ELg z&Qfe!7m6ze=mZ`Ia9$z|ARSw|IdMpooY4YiPN8K z4B(ts3p%2i(Td=tgEHX z0UQ_>URBtG+-?0E;E7Ld^dyZ;jjw0}XZ(}-QzC6+NN=40oDb2^v!L1g9xRvE#@IBR zO!b-2N7wVfLV;mhEaXQ9XAU+>=XVA6f&T4Z-@AX!leJ8obP^P^wP0aICND?~w&NykJ#54x3_@r7IDMdRNy4Hh;h*!u(Ol(#0bJdwEo$5437-UBjQ+j=Ic>Q2z` zJNDf0yO6@mr6y1#n3)s(W|$iE_i8r@Gd@!DWDqZ7J&~gAm1#~maIGJ1sls^gxL9LLG_NhU!pTGty!TbhzQnu)I*S^54U6Yu%ZeCg`R>Q zhBv$n5j0v%O_j{QYWG!R9W?5_b&67KB$t}&e2LdMvd(PxN6Ir!H4>PNlerpBL>Zvyy!yw z-SOo8caEpDt(}|gKPBd$qND5#a5nju^O>V&;f890?yEOfkSG^HQVmEbM3Ugzu+UtH zC(INPDdraBN?P%kE;*Ae%Wto&sgw(crfZ#Qy(<4nk;S|hD3j{IQRI6Yq|f^basLY; z-HB&Je%Gg}Jt@={_C{L$!RM;$$|iD6vu#3w?v?*;&()uB|I-XqEKqZPS!reW9JkLewLb!70T7n`i!gNtb1%vN- zySZj{8-1>6E%H&=V}LM#xmt`J3XQoaD|@XygXjdZ1+P77-=;=eYpoEQ01B@L*a(uW zrZeZz?HJsw_4g0vhUgkg@VF8<-X$B8pOqCuWAl28uB|@r`19DTUQQsb^pfqB6QtiT z*`_UZ`fT}vtUY#%sq2{rchyfu*pCg;uec2$-$N_xgjZcoumE5vSI{+s@iLWoz^Mf; zuI8kDP{!XY6OP~q5}%1&L}CtfH^N<3o4L@J@zg1-mt{9L`s^z$Vgb|mr{@WiwAqKg zp#t-lhrU>F8o0s1q_9y`gQNf~Vb!F%70f}$>i7o4ho$`uciNf=xgJ>&!gSt0g;M>*x4-`U)ysFW&Vs^Vk6m%?iuWU+o&m(2Jm26Y(3%TL; zA7T)BP{WS!&xmxNw%J=$MPfn(9*^*TV;$JwRy8Zl*yUZi8jWYF>==j~&S|Xinsb%c z2?B+kpet*muEW7@AzjBA^wAJBY8i|#C{WtO_or&Nj2{=6JTTX05}|H>N2B|Wf!*3_ z7hW*j6p3TvpghEc6-wufFiY!%-GvOx*bZrhZu+7?iSrZL5q9}igiF^*R3%DE4aCHZ zqu>xS8LkW+Auv%z-<1Xs92u23R$nk@Pk}MU5!gT|c7vGlEA%G^2th&Q*zfg%-D^=f z&J_}jskj|Q;73NP4<4k*Y%pXPU2Thoqr+5uH1yEYM|VtBPW6lXaetokD0u z9qVek6Q&wk)tFbQ8(^HGf3Wp16gKmr>G;#G(HRBx?F`9AIRboK+;OfHaLJ(P>IP0w zyTbTkx_THEOs%Q&aPrxbZrJlio+hCC_HK<4%f3ZoSAyG7Dn`=X=&h@m*|UYO-4Hq0 z-Bq&+Ie!S##4A6OGoC~>ZW`Y5J)*ouaFl_e9GA*VSL!O_@xGiBw!AF}1{tB)z(w%c zS1Hmrb9OC8>0a_$BzeiN?rkPLc9%&;1CZW*4}CDDNr2gcl_3z+WC15&H1Zc2{o~i) z)LLW=WQ{?ricmC`G1GfJ0Yp4Dy~Ba;j6ZV4r{8xRs`13{dD!xXmr^Aga|C=iSmor% z8hi|pTXH)5Yf&v~exp3o+sY4B^^b*eYkkCYl*T{*=-0HniSA_1F53eCb{x~1k3*`W zr~};p1A`k{1DV9=UPnLDgz{aJH=-LQo<5%+Em!DNN252xwIf*wF_zS^!(XSm(9eoj z=*dXG&n0>)_)N5oc6v!>-bd(2ragD8O=M|wGW z!xJQS<)u70m&6OmrF0WSsr@I%T*c#Qo#Ha4d3COcX+9}hM5!7JIGF>7<~C(Ear^Sn zm^ZFkV6~Ula6+8S?oOROOA6$C&q&dp`>oR-2Ym3(HT@O7Sd5c~+kjrmM)YmgPH*tL zX+znN>`tv;5eOfX?h{AuX^LK~V#gPCu=)Tigtq9&?7Xh$qN|%A$?V*v=&-2F$zTUv z`C#WyIrChS5|Kgm_GeudCFf;)!WH7FI60j^0o#65o6`w*S7R@)88n$1nrgU(oU0M9 zx+EuMkC>(4j1;m6NoGqEkpJYJ?vc|B zOlwT3t&UgL!pX_P*6g36`ZXQ; z9~Cv}ANFnJGp(;ZhS(@FT;3e)0)Kp;h^x;$*xZn*k0U6-&FwI=uOGaODdrsp-!K$Ac32^c{+FhI-HkYd5v=`PGsg%6I`4d9Jy)uW0y%) zm&j^9WBAp*P8#kGJUhB!L?a%h$hJgQrx!6KCB_TRo%9{t0J7KW8!o1B!NC)VGLM5! zpZy5Jc{`r{1e(jd%jsG7k%I+m#CGS*BPA65ZVW~fLYw0dA-H_}O zrkGFL&P1PG9p2(%QiEWm6x;U-U&I#;Em$nx-_I^wtgw3xUPVVu zqSuKnx&dIT-XT+T10p;yjo1Y)z(x1fb8Dzfn8e yu?e%!_ptzGB|8GrCfu%p?(_ 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
NnX)EH+Nua)3Y(c z&{(nX_ht=QbJ%DzAya}!&uNu!4V0xI)QE$SY__m)SAKcN0P(&JcoK*Lxr@P zY&P=}&B3*UWNlc|&$Oh{BEqwK2+N2U$4WB7Fd|aIal`FGANUa9E-O)!gV`((ZGCc$ zBJA|FFrlg~9OBp#f7aHodCe{6= zay$6vN~zj1ddMZ9gQ4p32(7wD?(dE>KA2;SOzXRmPBiBc6g`eOsy+pVcHu=;Yd8@{ zSGgXf@%sKKQz~;!J;|2fC@emm#^_rnO0esEn^QxXgJYd`#FPWOUU5b;9eMAF zZhfiZb|gk8aJIw*YLp4!*(=3l8Cp{(%p?ho22*vN9+5NLV0TTazNY$B5L6UKUrd$n zjbX%#m7&F#U?QNOBXkiiWB*_tk+H?N3`vg;1F-I+83{M2!8<^nydGr5XX}tC!10&e z7D36bLaB56WrjL&HiiMVtpff|K%|*{t*ltt^5ood{FOG0<>k&1h95qPio)2`eL${YAGIx(b4VN*~nKn6E~SIQUuRH zQ+5zP6jfnP$S0iJ@~t!Ai3o`X7biohli;E zT#yXyl{bojG@-TGZzpdVDXhbmF%F9+-^YSIv|MT1l3j zrxOFq>gd2%U}?6}8mIj?M zc077Zc9fq(-)4+gXv?Az26IO6eV`RAJz8e3)SC7~>%rlzDwySVx*q$ygTR5kW2ds- z!HBgcq0KON9*8Ff$X0wOq$`T7ml(@TF)VeoF}x1OttjuVHn3~sHrMB++}f7f9H%@f z=|kP_?#+fve@{0MlbkC9tyvQ_R?lRdRJ@$qcB(8*jyMyeME5ns6ypVI1Xm*Zr{DuS zZ!1)rQfa89c~;l~VkCiHI|PCBd`S*2RLNQM8!g9L6?n`^evQNEwfO@&JJRme+uopQX0%Jo zgd5G&#&{nX{o?TQwQvF1<^Cg3?2co;_06=~Hcb6~4XWpNFL!WU{+CK;>gH%|BLOh7@!hsa(>pNDAmpcuVO-?;Bic17R}^|6@8DahH)G z!EmhsfunLL|3b=M0MeK2vqZ|OqUqS8npxwge$w-4pFVXFq$_EKrZY?BuP@Az@(k`L z`ViQBSk`y+YwRT;&W| z2e3UfkCo^uTA4}Qmmtqs+nk#gNr2W4 zTH%hhErhB)pkXR{B!q5P3-OM+M;qu~f>}IjtF%>w{~K-0*jPVLl?Chz&zIdxp}bjx zStp&Iufr58FTQ36AHU)0+CmvaOpKF;W@sMTFpJ`j;3d)J_$tNQI^c<^1o<49Z(~K> z;EZTBaVT%14(bFw2ob@?JLQ2@(1pCdg3S%E4*dJ}dA*v}_a4_P(a`cHnBFJxNobAv zf&Zl-Yt*lhn-wjZsq<9v-IsXxAxMZ58C@e0!rzhJ+D@9^3~?~yllY^s$?&oNwyH!#~6x4gUrfxplCvK#!f z$viuszW>MFEcFL?>ux*((!L$;R?xc*myjRIjgnQX79@UPD$6Dz0jutM@7h_pq z0Zr)#O<^y_K6jfY^X%A-ip>P%3saX{!v;fxT-*0C_j4=UMH+Xth(XVkVGiiKE#f)q z%Jp=JT)uy{&}Iq2E*xr4YsJ5>w^=#-mRZ4vPXpI6q~1aFwi+lQcimO45V-JXP;>(Q zo={U`{=_JF`EQj87Wf}{Qy35s8r1*9Mxg({CvOt}?Vh9d&(}iI-quvs-rm~P;eRA@ zG5?1HO}puruc@S{YNAF3vmUc2B4!k*yi))<5BQmvd3tr}cIs#9)*AX>t`=~{f#Uz0 z0&Nk!7sSZwJe}=)-R^$0{yeS!V`Dh7w{w5rZ9ir!Z7Cd7dwZcK;BT#V0bzTt>;@Cl z#|#A!-IL6CZ@eHH!CG>OO8!%G8&8t4)Ro@}USB*k>oEUo0LsljsJ-%5Mo^MJF2I8- z#v7a5VdJ-Cd%(a+y6QwTmi+?f8Nxtm{g-+WGL>t;s#epv7ug>inqimZCVm!uT5Pf6 ziEgQt7^%xJf#!aPWbuC_3Nxfb&CFbQy!(8ANpkWLI4oSnH?Q3f?0k1t$3d+lkQs{~(>06l&v|MpcFsyAv zin6N!-;pggosR*vV=DO(#+}4ps|5$`udE%Kdmp?G7B#y%H`R|i8skKOd9Xzx8xgR$>Zo2R2Ytktq^w#ul4uicxW#{ zFjG_RNlBroV_n;a7U(KIpcp*{M~e~@>Q#Av90Jc5v%0c>egEdY4v3%|K1XvB{O_8G zkTWLC>OZKf;XguMH2-Pw{BKbFzaY;4v2seZV0>^7Q~d4O=AwaPhP3h|!hw5aqOtT@ z!SNz}$of**Bl3TK209@F=Tn1+mgZa8yh(Png%Zd6Mt}^NSjy)etQrF zme*llAW=N_8R*O~d2!apJnF%(JcN??=`$qs3Y+~xs>L9x`0^NIn!8mMRFA_tg`etw z3k{9JAjnl@ygIiJcNHTy02GMAvBVqEss&t2<2mnw!; zU`J)0>lWiqVqo|ex7!+@0i>B~BSU1A_0w#Ee+2pJx0BFiZ7RDHEvE*ptc9md(B{&+ zKE>TM)+Pd>HEmdJao7U@S>nL(qq*A)#eLOuIfAS@j`_sK0UEY6OAJJ-kOrHG zjHx`g!9j*_jRcJ%>CE9K2MVf?BUZKFHY?EpV6ai7sET-tqk=nDFh-(65rhjtlKEY% z@G&cQ<5BKatfdA1FKuB=i>CCC5(|9TMW%K~GbA4}80I5%B}(gck#Wlq@$nO3%@QP_ z8nvPkJFa|znk>V92cA!K1rKtr)skHEJD;k8P|R8RkCq1Rh^&}Evwa4BUJz2f!2=MH zo4j8Y$YL2313}H~F7@J7mh>u%556Hw0VUOz-Un@ZASCL)y8}4XXS`t1AC*^>PLwIc zUQok5PFS=*#)Z!3JZN&eZ6ZDP^-c@StY*t20JhCnbMxXf=LK#;`4KHEqMZ-Ly9KsS zI2VUJGY&PmdbM+iT)zek)#Qc#_i4uH43 z@T5SZBrhNCiK~~esjsO9!qBpaWK<`>!-`b71Y5ReXQ4AJU~T2Njri1CEp5oKw;Lnm)-Y@Z3sEY}XIgSy%xo=uek(kAAH5MsV$V3uTUsoTzxp_rF=tx zV07vlJNKtJhCu`b}*#m&5LV4TAE&%KtHViDAdv#c^x`J7bg z&N;#I2GkF@SIGht6p-V}`!F_~lCXjl1BdTLIjD2hH$J^YFN`7f{Q?OHPFEM$65^!u zNwkelo*5+$ZT|oQ%o%;rBX$+?xhvjb)SHgNHE_yP%wYkkvXHS{Bf$OiKJ5d1gI0j< zF6N}Aq=(WDo(J{e-uOecxPD>XZ@|u-tgTR<972`q8;&ZD!cep^@B5CaqFz|oU!iFj zU0;6fQX&~15E53EW&w1s9gQQ~Zk16X%6 zjG`j0yq}4deX2?Tr(03kg>C(!7a|b9qFI?jcE^Y>-VhudI@&LI6Qa}WQ>4H_!UVyF z((cm&!3gmq@;BD#5P~0;_2qgZhtJS|>WdtjY=q zLnHH~Fm!cxw|Z?Vw8*~?I$g#9j&uvgm7vPr#&iZgPP~v~BI4jOv;*OQ?jYJtzO<^y z7-#C={r7CO810!^s(MT!@@Vz_SVU)7VBi(e1%1rvS!?PTa}Uv`J!EP3s6Y!xUgM^8 z4f!fq<3Wer_#;u!5ECZ|^c1{|q_lh3m^9|nsMR1#Qm|?4Yp5~|er2?W^7~cl;_r4WSme_o68J9p03~Hc%X#VcX!xAu%1`R!dfGJCp zV*&m47>s^%Ib0~-2f$6oSgn3jg8m%UA;ArcdcRyM5;}|r;)?a^D*lel5C`V5G=c~k zy*w_&BfySOxE!(~PI$*dwG><+-%KT5p?whOUMA*k<9*gi#T{h3DAxzAPxN&Xws8o9Cp*`PA5>d9*Z-ynV# z9yY*1WR^D8|C%I@vo+d8r^pjJ$>eo|j>XiLWvTWLl(^;JHCsoPgem6PvegHb-OTf| zvTgsHSa;BkbG=(NgPO|CZu9gUCGr$8*EoH2_Z#^BnxF0yM~t`|9ws_xZ8X8iZYqh! zAh;HXJ)3P&)Q0(&F>!LN0g#bdbis-cQxyGn9Qgh`q+~49Fqd2epikEUw9caM%V6WgP)532RMRW}8gNS%V%Hx7apSz}tn@bQy!<=lbhmAH=FsMD?leawbnP5BWM0 z5{)@EEIYMu5;u)!+HQWhQ;D3_Cm_NADNeb-f56}<{41aYq8p4=93d=-=q0Yx#knGYfXVt z+kMxlus}t2T5FEyCN~!}90O_X@@PQpuy;kuGz@bWft%diBTx?d)_xWd_-(!LmVrh**oKg!1CNF&LX4{*j|) zIvjCR0I2UUuuEXh<9}oT_zT#jOrJAHNLFT~Ilh9hGJPI1<5`C-WA{tUYlyMeoy!+U zhA#=p!u1R7DNg9u4|QfED-2TuKI}>p#2P9--z;Bbf4Op*;Q9LCbO&aL2i<0O$ByoI z!9;Ght733FC>Pz>$_mw(F`zU?`m@>gE`9_p*=7o=7av`-&ifU(^)UU`Kg3Kw`h9-1 z6`e6+im=|m2v`pN(2dE%%n8YyQz;#3Q-|x`91z?gj68cMrHl}C25|6(_dIGk*8cA3 zRHB|Nwv{@sP4W+YZM)VKI>RlB`n=Oj~Rzx~M+Khz$N$45rLn6k1nvvD^&HtsMA4`s=MmuOJID@$s8Ph4E zAmSV^+s-z8cfv~Yd(40Sh4JG#F~aB>WFoX7ykaOr3JaJ&Lb49=B8Vk-SQT9%7TYhv z?-Pprt{|=Y5ZQ1?od|A<_IJU93|l4oAfBm?3-wk{O<8ea+`}u%(kub(LFo2zFtd?4 zwpN|2mBNywv+d^y_8#<$r>*5+$wRTCygFLcrwT(qc^n&@9r+}Kd_u@Ithz(6Qb4}A zWo_HdBj#V$VE#l6pD0a=NfB0l^6W^g`vm^sta>Tly?$E&{F?TTX~DsKF~poFfmN%2 z4x`Dc{u{Lkqz&y!33;X}weD}&;7p>xiI&ZUb1H9iD25a(gI|`|;G^NwJPv=1S5e)j z;U;`?n}jnY6rA{V^ zxTd{bK)Gi^odL3l989DQlN+Zs39Xe&otGeY(b5>rlIqfc7Ap4}EC?j<{M=hlH{1+d zw|c}}yx88_xQr`{98Z!d^FNH77=u(p-L{W6RvIn40f-BldeF-YD>p6#)(Qzf)lfZj z?3wAMtPPp>vMehkT`3gToPd%|D8~4`5WK{`#+}{L{jRUMt zrFz+O$C7y8$M&E4@+p+oV5c%uYzbqd2Y%SSgYy#xh4G3hQv>V*BnuKQhBa#=oZB~w{azUB+q%bRe_R^ z>fHBilnRTUfaJ201czL8^~Ix#+qOHSO)A|xWLqOxB$dT2W~)e-r9;bm=;p;RjYahB z*1hegN(VKK+ztr~h1}YP@6cfj{e#|sS`;3tJhIJK=tVJ-*h-5y9n*&cYCSdg#EHE# zSIx=r#qOaLJoVVf6v;(okg6?*L_55atl^W(gm^yjR?$GplNP>BZsBYEf_>wM0Lc;T zhf&gpzOWNxS>m+mN92N0{;4uw`P+9^*|-1~$uXpggj4- z^SFc4`uzj2OwdEVT@}Q`(^EcQ_5(ZtXTql*yGzdS&vrS_w>~~ra|Nb5abwf}Y!uq6R5f&6g2ge~2p(%c< z@O)cz%%rr4*cRJ5f`n@lvHNk@lE1a*96Kw6lJ~B-XfJW%?&-y?;E&?1AacU@`N`!O z6}V>8^%RZ7SQnZ-z$(jsX`amu*5Fj8g!3RTRwK^`2_QHe;_2y_n|6gSaGyPmI#kA0sYV<_qOZc#-2BO%hX)f$s-Z3xlI!ub z^;3ru11DA`4heAu%}HIXo&ctujzE2!6DIGE{?Zs>2}J+p&C$rc7gJC35gxhflorvsb%sGOxpuWhF)dL_&7&Z99=5M0b~Qa;Mo!j&Ti_kXW!86N%n= zSC@6Lw>UQ__F&+&Rzv?gscwAz8IP!n63>SP)^62(HK98nGjLY2*e^OwOq`3O|C92? z;TVhZ2SK%9AGW4ZavTB9?)mUbOoF`V7S=XM;#3EUpR+^oHtdV!GK^nXzCu>tpR|89 zdD{fnvCaN^^LL%amZ^}-E+214g&^56rpdc@yv0b<3}Ys?)f|fXN4oHf$six)-@<;W&&_kj z-B}M5U*1sb4)77aR=@%I?|Wkn-QJVuA96an25;~!gq(g1@O-5VGo7y&E_srxL6ZfS z*R%$gR}dyONgju*D&?geiSj7SZ@ftyA|}(*Y4KbvU!YLsi1EDQQCnb+-cM=K1io78o!v*);o<XwjaQH%)uIP&Zm?)Nfbfn;jIr z)d#!$gOe3QHp}2NBak@yYv3m(CPKkwI|{;d=gi552u?xj9ObCU^DJFQp4t4e1tPzM zvsRIGZ6VF+{6PvqsplMZWhz10YwS={?`~O0Ec$`-!klNUYtzWA^f9m7tkEzCy<_nS z=&<(awFeZvt51>@o_~>PLs05CY)$;}Oo$VDO)?l-{CS1Co=nxjqben*O1BR>#9`0^ zkwk^k-wcLCLGh|XLjdWv0_Hg54B&OzCE^3NCP}~OajK-LuRW53CkV~Su0U>zN%yQP zH8UH#W5P3-!ToO-2k&)}nFe`t+mdqCxxAHgcifup^gKpMObbox9LFK;LP3}0dP-UW z?Zo*^nrQ6*$FtZ(>kLCc2LY*|{!dUn$^RW~m9leoF|@Jy|M5p-G~j%+P0_#orRKf8 zvuu5<*XO!B?1E}-*SY~MOa$6c%2cM+xa8}_8x*aVn~57v&W(0mqN1W`5a7*VN{SUH zXz98DDyCnX2EPl-`Lesf`=AQT%YSDb`$%;(jUTrNen$NPJrlpPDP}prI>Ml!r6bCT;mjsg@X^#&<}CGf0JtR{Ecwd&)2zuhr#nqdgHj+g2n}GK9CHuwO zk>oZxy{vcOL)$8-}L^iVfJHAGfwN$prHjYV0ju}8%jWquw>}_W6j~m<}Jf!G?~r5&Rx)!9JNX!ts#SGe2HzobV5); zpj@&`cNcO&q+%*<%D7za|?m5qlmFK$=MJ_iv{aRs+BGVrs)98BlN^nMr{V_fcl_;jkzRju+c-y?gqBC_@J0dFLq-D9@VN&-`R9U;nv$Hg?>$oe4N&Ht$V_(JR3TG^! zzJsbQbi zFE6-{#9{G{+Z}ww!ycl*7rRdmU#_&|DqPfX3CR1I{Kk;bHwF6jh0opI`UV2W{*|nn zf_Y@%wW6APb&9RrbEN=PQRBEpM(N1w`81s=(xQj6 z-eO0k9=Al|>Ej|Mw&G`%q8e$2xVz1v4DXAi8G};R$y)ww638Y=9y$ZYFDM$}vzusg zUf+~BPX>(SjA|tgaFZr_e0{)+z9i6G#lgt=F_n$d=beAt0Sa0a7>z-?vcjl3e+W}+ z1&9=|vC=$co}-Zh*%3588G?v&U7%N1Qf-wNWJ)(v`iO5KHSkC5&g7CrKu8V}uQGcfcz zmBz#Lbqwqy#Z~UzHgOQ;Q-rPxrRNvl(&u6ts4~0=KkeS;zqURz%!-ERppmd%0v>iRlEf+H$yl{_8TMJzo0 z>n)`On|7=WQdsqhXI?#V{>+~}qt-cQbokEbgwV3QvSP7&hK4R{Z{aGHVS3;+h{|Hz z6$Js}_AJr383c_+6sNR|$qu6dqHXQTc6?(XWPCVZv=)D#6_;D_8P-=zOGEN5&?~8S zl5jQ?NL$c%O)*bOohdNwGIKM#jSAC?BVY={@A#c9GmX0=T(0G}xs`-%f3r=m6-cpK z!%waekyAvm9C3%>sixdZj+I(wQlbB4wv9xKI*T13DYG^T%}zZYJ|0$Oj^YtY+d$V$ zAVudSc-)FMl|54n=N{BnZTM|!>=bhaja?o7s+v1*U$!v!qQ%`T-6fBvmdPbVmro&d zk07TOp*KuxRUSTLRrBj{mjsnF8`d}rMViY8j`jo~Hp$fkv9F_g(jUo#Arp;Xw0M$~ zRIN!B22~$kx;QYmOkos@%|5k)!QypDMVe}1M9tZfkpXKGOxvKXB!=lo`p?|R1l=tA zp(1}c6T3Fwj_CPJwVsYtgeRKg?9?}%oRq0F+r+kdB=bFUdVDRPa;E~~>2$w}>O>v=?|e>#(-Lyx?nbg=ckJ#5U6;RT zNvHhXk$P}m9wSvFyU3}=7!y?Y z=fg$PbV8d7g25&-jOcs{%}wTDKm>!Vk);&rr;O1nvO0VrU&Q?TtYVU=ir`te8SLlS zKSNmV=+vF|ATGg`4$N1uS|n??f}C_4Sz!f|4Ly8#yTW-FBfvS48Tef|-46C(wEO_%pPhUC5$-~Y?!0vFZ^Gu`x=m7X99_?C-`|h zfmMM&Y@zdfitA@KPw4Mc(YHcY1)3*1xvW9V-r4n-9ZuBpFcf{yz+SR{ zo$ZSU_|fgwF~aakGr(9Be`~A|3)B=9`$M-TWKipq-NqRDRQc}ABo*s_5kV%doIX7LRLRau_gd@Rd_aLFXGSU+U?uAqh z8qusWWcvgQ&wu{|sRXmv?sl=xc<$6AR$+cl& zFNh5q1~kffG{3lDUdvEZu5c(aAG~+64FxdlfwY^*;JSS|m~CJusvi-!$XR`6@XtY2 znDHSz7}_Bx7zGq-^5{stTRy|I@N=>*y$zz>m^}^{d&~h;0kYiq8<^Wq7Dz0w31ShO^~LUfW6rfitR0(=3;Uue`Y%y@ex#eKPOW zO~V?)M#AeHB2kovn1v=n^D?2{2jhIQd9t|_Q+c|ZFaWt+r&#yrOu-!4pXAJuxM+Cx z*H&>eZ0v8Y`t}8{TV6smOj=__gFC=eah)mZt9gwz>>W$!>b3O;Rm^Ig*POZP8Rl0f zT~o=Nu1J|lO>}xX&#P58%Yl z83`HRs5#32Qm9mdCrMlV|NKNC+Z~ z9OB8xk5HJ>gBLi+m@(pvpw)1(OaVJKs*$Ou#@Knd#bk+V@y;YXT?)4eP9E5{J%KGtYinNYJUH9PU3A}66c>Xn zZ{Bn0<;8$WCOAL$^NqTjwM?5d=RHgw3!72WRo0c;+houoUA@HWLZM;^U$&sycWrFd zE7ekt9;kb0`lps{>R(}YnXlyGY}5pPd9zBpgXeJTY_jwaJGSJQC#-KJqmh-;ad&F- z-Y)E>!&`Rz!HtCz>%yOJ|v(u7P*I$jqEY3}(Z-orn4 zlI?CYKNl`6I){#2P1h)y(6?i;^z`N3bxTV%wNvQW+eu|x=kbj~s8rhCR*0H=iGkSj zk23lr9kr|p7#qKL=UjgO`@UnvzU)`&fI>1Qs7ubq{@+lK{hH* zvl6eSb9%yngRn^T<;jG1SVa)eA>T^XX=yUS@NCKpk?ovCW1D@!=@kn;l_BrG;hOTC z6K&H{<8K#dI(A+zw-MWxS+~{g$tI7|SfP$EYKxA}LlVO^sT#Oby^grkdZ^^lA}uEF zBSj$weBJG{+Bh@Yffzsw=HyChS(dtLE3i*}Zj@~!_T-Ay7z=B)+*~3|?w`Zd)Co2t zC&4DyB!o&YgSw+fJn6`sn$e)29`kUwAc+1MND7YjV%lO;H2}fNy>hD#=gT ze+-aFNpyKIoXY~Vq-}OWPBe?Rfu^{ps8>Xy%42r@RV#*QV~P83jdlFNgkPN=T|Kt7 zV*M`Rh*30&AWlb$;ae130e@}Tqi3zx2^JQHpM>j$6x`#{mu%tZlwx9Gj@Hc92IuY* zarmT|*d0E~vt6<+r?W^UW0&#U&)8B6+1+;k^2|FWBRP9?C4Rk)HAh&=AS8FS|NQaZ z2j!iZ)nbEyg4ZTp-zHwVlfLC~tXIrv(xrP8PAtR{*c;T24ycA-;auWsya-!kF~CWZ zw_uZ|%urXgUbc@x=L=_g@QJ@m#5beS@6W195Hn7>_}z@Xt{DIEA`A&V82bc^#!q8$ zFh?z_Vn|ozJ;NPd^5uu(9tspo8t%&-U9Ckay-s@DnM*R5rtu|4)~e)`z0P-sy?)kc zs_k&J@0&0!q4~%cKL)2l;N*T&0;mqX5T{Qy60%JtKTQZ-xb%KOcgqwJmb%MOOKk7N zgq})R_6**{8A|6H?fO+2`#QU)p$Ei2&nbj6TpLSIT^D$|`TcSeh+)}VMb}LmvZ{O| ze*1IdCt3+yhdYVxcM)Q_V0bIXLgr6~%JS<<&dxIgfL=Vnx4YHuU@I34JXA|+$_S3~ zy~X#gO_X!cSs^XM{yzDGNM>?v(+sF#<0;AH^YrE8smx<36bUsHbN#y57K8WEu(`qHvQ6cAZPo=J5C(lSmUCZ57Rj6cx!e^rfaI5%w}unz}4 zoX=nt)FVNV%QDJH`o!u9olLD4O5fl)xp+#RloZlaA92o3x4->?rB4`gS$;WO{R;Z3>cG3IgFX2EA?PK^M}@%1%A;?f6}s&CV$cIyEr#q5;yHdNZ9h{| z-=dX+a5elJoDo?Eq&Og!nN6A)5yYpnGEp}?=!C-V)(*~z-+?kY1Q7qs#Rsy%hu_60rdbB+QQNr?S1 z?;xtjUv|*E3}HmuNyB9aFL5H~3Ho0UsmuMZELp1a#CA1g`P{-mT?BchuLEtK}!QZ=3AWakRu~?f9V~3F;TV`5%9Pcs_$gq&CcU}r8gOO zC2&SWPsSG{&o-LIGTBqp6SLQZPvYKp$$7L4WRRZ0BR$Kf0I0SCFkqveCp@f)o8W)! z$%7D1R`&j7W9Q9CGus_)b%+B#J2G;l*FLz#s$hw{BHS~WNLODV#(!u_2Pe&tMsq={ zdm7>_WecWF#D=?eMjLj=-_z`aHMZ=3_-&E8;ibPmM}61i6J3is*=dKf%HC>=xbj4$ zS|Q-hWQ8T5mWde6h@;mS+?k=89?1FU<%qH9B(l&O>k|u_aD|DY*@~(`_pb|B#rJ&g zR0(~(68fpUPz6TdS@4JT5MOPrqDh5_H(eX1$P2SQrkvN8sTxwV>l0)Qq z0pzTuvtEAKRDkKGhhv^jk%|HQ1DdF%5oKq5BS>szk-CIke{%js?~%@$uaN3^Uz6Wf z_iyx{bZ(;9y4X&>LPV=L=d+A}7I4GkK0c1Xts{rrW1Q7apHf-))`BgC^0^F(>At1* za@e7{lq%yAkn*NH8Q1{@{lKhRg*^TfGvv!Sn*ed*x@6>M%aaqySxR|oNadYt1mpUZ z6H(rupHYf&Z z29$5g#|0MX#aR6TZ$@eGxxABRKakDYtD%5BmKp;HbG_ZbT+=81E&=XRk6m_3t9PvD zr5Cqy(v?gHcYvYvXkNH@S#Po~q(_7MOuCAB8G$a9BC##gw^5mW16cML=T=ERL7wsk zzNEayTG?mtB=x*wc@ifBCJ|irFVMOvH)AFRW8WE~U()QT=HBCe@s$dA9O!@`zAAT) zaOZ7l6vyR+Nk_OOF!ZlZmjoImKh)dxFbbR~z(cMhfeX1l7S_`;h|v3gI}n9$sSQ>+3@AFAy9=B_y$)q;Wdl|C-X|VV3w8 z2S#>|5dGA8^9%Bu&fhmVRrTX>Z7{~3V&0UpJNEl0=N32euvDGCJ>#6dUSi&PxFW*s zS`}TB>?}H(T2lxBJ!V#2taV;q%zd6fOr=SGHpoSG*4PDaiG0pdb5`jelVipkEk%FV zThLc@Hc_AL1#D&T4D=w@UezYNJ%0=f3iVRuVL5H?eeZM}4W*bomebEU@e2d`M<~uW zf#Bugwf`VezG|^Qbt6R_=U0}|=k;mIIakz99*>FrsQR{0aQRP6ko?5<7bkDN8evZ& zB@_KqQG?ErKL=1*ZM9_5?Pq%lcS4uLSzN(Mr5=t6xHLS~Ym`UgM@D&VNu8e?_=nSFtF$u@hpPSmI4Vo_t&v?>$~K4y(O~Rb*(MFy_igM7 z*~yYUyR6yQgzWnWMUgDov!!g=lInM+=lOmOk4L`O?{i&qxy&D*_qorRbDwj6?)!ef z#JLd7F6Z2I$S0iYI={rZNk*<{HtIl^mx=h>Cim*04K4+Z4IJtd*-)%6XV2(MCscPiw_a+y*?BKbTS@BZ3AUao^%Zi#PhoY9Vib4N>SE%4>=Jco0v zH_Miey{E;FkdlZSq)e<{`+S3W=*ttvD#hB8w=|2aV*D=yOV}(&p%0LbEWH$&@$X3x~CiF-?ejQ*N+-M zc8zT@3iwkdRT2t(XS`d7`tJQAjRmKAhiw{WOqpuvFp`i@Q@!KMhwKgsA}%@sw8Xo5Y=F zhRJZg)O4uqNWj?V&&vth*H#je6T}}p_<>!Dr#89q@uSjWv~JuW(>FqoJ5^ho0%K?E z9?x_Q;kmcsQ@5=}z@tdljMSt9-Z3xn$k)kEjK|qXS>EfuDmu(Z8|(W?gY6-l z@R_#M8=vxKMAoi&PwnaIYw2COJM@atcgfr=zK1bvjW?9B`-+Voe$Q+H$j!1$Tjn+* z&LY<%)L@;zhnJlB^Og6I&BOR-m?{IW;tyYC%FZ!&Z>kGjHJ6cqM-F z&19n+e1=9AH1VrVeHrIzqlC`w9=*zfmrerF?JMzO&|Mmv;!4DKc(sp+jy^Dx?(8>1 zH&yS_4yL7m&GWX~mdfgH*AB4{CKo;+egw=PrvkTaoBU+P-4u?E|&!c z)DKc;>$$B6u*Zr1SjUh2)FeuWLWHl5TH(UHWkf zLs>7px!c5n;rbe^lO@qlYLzlDVp(z?6rPZel=YB)Uv&n!2{+Mb$-vQl=xKw( zve&>xYx+jW_NJh!FV||r?;hdP*jOXYcLCp>DOtJ?2S^)DkM{{Eb zS$!L$e_o0(^}n3tA1R3-$SNvgBq;DOEo}fNc|tB%%#g4RA3{|euq)p+xd3I8^4E&m zFrD%}nvG^HUAIKe9_{tXB;tl|G<%>yk6R;8L2)KUJw4yHJXUOPM>(-+jxq4R;z8H#>rnJy*)8N+$wA$^F zN+H*3t)eFEgxLw+Nw3};4WV$qj&_D`%ADV2%r zJCPCo%{=z7;`F98(us5JnT(G@sKTZ^;2FVitXyLe-S5(hV&Ium+1pIUB(CZ#h|g)u zSLJJ<@HgrDiA-}V_6B^x1>c9B6%~847JkQ!^KLZ2skm;q*edo;UA)~?SghG8;QbHh z_6M;ouo_1rq9=x$<`Y@EA{C%6-pEV}B(1#sDoe_e1s3^Y>n#1Sw;N|}8D|s|VPd+g z-_$QhCz`vLxxrVMx3ape1xu3*wjx=yKSlM~nFgkNWb4?DDr*!?U)L_VeffF<+!j|b zZ$Wn2$TDv3C3V@BHpSgv3JUif8%hk%OsGZ=OxH@8&4`bbf$`aAMchl^qN>Eyu3JH} z9-S!x8-s4fE=lad%Pkp8hAs~u?|uRnL48O|;*DEU! zuS0{cpk%1E0nc__2%;apFsTm0bKtd&A0~S3Cj^?72-*Owk3V!ZG*PswDfS~}2<8le z5+W^`Y(&R)yVF*tU_s!XMcJS`;(Tr`J0%>p=Z&InR%D3@KEzzI+-2)HK zuoNZ&o=wUC&+*?ofPb0a(E6(<2Amd6%uSu_^-<1?hsxs~0K5^f(LsGqgEF^+0_H=uNk9S0bb!|O8d?m5gQjUKevPaO+*VfSn^2892K~%crWM8+6 z25@V?Y@J<9w%@NXh-2!}SK_(X)O4AM1-WTg>sj1{lj5@=q&dxE^9xng1_z9w9DK>| z6Iybcd0e zyi;Ew!KBRIfGPGytQ6}z}MeXCfLY0?9%RiyagSp_D1?N&c{ zyo>VbJ4Gy`@Fv+5cKgUgs~na$>BV{*em7PU3%lloy_aEovR+J7TfQKh8BJXyL6|P8un-Jnq(ghd!_HEOh$zlv2$~y3krgeH;9zC}V3f`uDtW(%mT#944DQa~^8ZI+zAUu4U(j0YcDfKR$bK#gvn_{JZ>|gZ5+)u?T$w7Q%F^;!Wk?G z(le7r!ufT*cxS}PR6hIVtXa)i`d$-_1KkyBU>qmgz-=T};uxx&sKgv48akIWQ89F{ z0XiY?WM^~;|T8zBOr zs#zuOONzH?svv*jokd5SK8wG>+yMC)LYL|vLqm^PMHcT=`}V$=nIRHe2?h)8WQa6O zPAU}d`1y(>kZiP~Gr=mtJLMu`i<2CspL|q2DqAgAD^7*$xzM`PU4^ga`ilE134XBQ z99P(LhHU@7qvl9Yzg$M`+dlS=x^(m-_3t|h>S}E0bcFMn=C|KamQ)=w2^e)35p`zY zRV8X?d;s^>Cof2SPR&nP3E+-LCkS0J$H!eh8~k0qo$}00b=7!H_I2O+Ro@3O$nPdm ztmbOO^B+IHzQ5w>@@@J4cKw5&^_w6s!s=H%&byAbUtczPQ7}wfTqxxtQNfn*u73Qw zGuWsrky_ajPx-5`R<)6xHf>C(oqGf_Fw|-U*GfS?xLML$kv;h_pZ@Kk$y0X(S+K80 z6^|z)*`5VUkawg}=z`S;VhZhxyDfrE0$(PMurAxl~<>lfZa>JZ288ULK7D` zl9|#L^JL}Y$j*j`0-K6kH#?bRmg#5L3iB4Z)%iF@SqT+Lp|{i`m%R-|ZE94Np7Pa5 zCqC^V3}B(FR340pmF*qaa}M}+h6}mqE~7Sh!9bDv9YRT|>vBNAqv09zXHMlcuhKD| zcjjA(b*XCIwJ33?CB!+;{)vX@9xns_b-VO{i0y?}{!sdXj1GM8+$#v>W7nw;+O_9B z_{4L;C6ol?(?W0<6taGEn1^uG=?Q3i29sE`RfYCaV$3DKc_;?HsL?D_fSYg}SuO5U zOB_f4^vZ_x%o`5|C@9C5+o=mFy@au{s)sKw!UgC&L35aH(sgDxRE2De%(%OT=VUdN ziVLEmdOvJ&5*tCMKRyXctCwQu_RH%;m*$YK&m;jtbdH#Ak~13T1^f89tn`A%QEHWs~jnY~E}p_Z$XC z=?YXLCkzVSK+Id`xZYTegb@W8_baLt-Fq`Tv|=)JPbFsKRm)4UW;yT+J`<)%#ue9DPOkje)YF2fsCilK9MIIK>p*`fkoD5nGfmLwt)!KOT+> zOFq*VZktDDyM3P5UOg`~XL#cbzC}eL%qMB=Q5$d89MKuN#$6|4gx_Jt0Gfn8w&q}%lq4QU%6#jT*MRT% zrLz~C8FYKHawn-EQWN1B75O&quS+Z81(zN)G>~vN8VwC+e+y(`>HcxC{MrJ;H1Z4k zZWuv$w_F0-Ub%MVcpIc){4PGL^I7M{>;hS?;eH!;gmcOE66z3;Z1Phqo(t zVP(Hg6q#0gIKgsg7L7WE!{Y#1nI(45tx2{$34dDd#!Z0NIyrm)HOn5W#7;f4pQci# zDW!FI(g4e668kI9{2+mLwB+=#9bfqgX%!B34V-$wwSN(_cm*^{y0jQtv*4}eO^sOV z*9xoNvX)c9isB}Tgx&ZRjp3kwhTVK?r9;n!x>^XYT z@Q^7zp{rkIs{2mUSE^2!Gf6$6;j~&4=-0cSJJDizZp6LTe8b45;{AKM%v99}{{FfC zz709%u0mC=1KXTo(=TqmZQ;c?$M3z(!xah>aywrj40sc2y3rKFw4jCq+Y+u=CH@_V zxz|qeTwa>+<|H%8Dz5u>ZI5MmjTFwXS-Fv!TDd*`>3{krWoNVx$<133`(ftS?ZPyY z&4@ah^3^i`vL$BZa>O|Nt?ucewzsF)0zX3qmM^|waXr=T0pfIb0*$AwU=?Ipl|1Y; z*Pk6{C-p4MY;j@IJ|DW>QHZQJcp;Z~?8(Q+Kk3^0qJ}SCk^*n4W zu9ZFwLHUx-$6xvaQ)SUQcYd6fF8&x)V`1bIuX@>{mE$b|Yd(qomn3;bPwnDUc0F=; zh*6_((%bqAYQWQ~odER?h>1mkL4kpb3s7`0m@rDKGU*oyF)$j~Ffd4fXV$?`f~rHf zB%Y)@5SXZvfwm10RY5X?TEo)PK_`L6qgBp=#>fO49$D zDq8Ozj0q6213tV5Qq=;fZ0$|KroY{Dz=l@lU^J)?Ko@ti20TRplXzphBi>XGx4bou zEWrkNjz0t5j!_ke{g5I#PUlEU$Km8g8TE|XK=MkU@PT4T><2OVamoK;wJ}3X0L$vX zgd7gNa359*nc)R-0!`2X@FOTB`+oETOPc=ubp5R)VQgY+5BTZZJ2?9QwnO=dnulIUF3gFn;BODC2)65)HeVd%t86sL7Rv^Y+nbn+&l z6BAJY(ETvwI)Ts$aiE8rht4KD*qNyE{8{x6R|%akbTBzw;2+6Echkt+W+`u^XX z_z&x%n { + RecipeRegistration.registerAll(); + ThEThaumcraft.init(); + GridLinkables.register(ModItems.GOLEM_WIFI_BACKPACK.get(), ItemGolemWirelessBackpack.LINKABLE_HANDLER); + GridLinkables.register(ModItems.WIRELESS_ESSENTIA_TERMINAL.get(), + appeng.items.tools.powered.WirelessTerminalItem.LINKABLE_HANDLER); + }); + + FeatureRegistry.registerAll(); + } + + private void registerUpgrades(FMLCommonSetupEvent event) { + event.enqueueWork(() -> { + String essentiaIoBusGroup = GuiText.IOBuses.getTranslationKey(); + + var importBusItem = ModItems.ESSENTIA_IMPORT_BUS.get(); + Upgrades.add(AEItems.FUZZY_CARD, importBusItem, 1, essentiaIoBusGroup); + Upgrades.add(AEItems.REDSTONE_CARD, importBusItem, 1, essentiaIoBusGroup); + Upgrades.add(AEItems.CAPACITY_CARD, importBusItem, 5, essentiaIoBusGroup); + Upgrades.add(AEItems.SPEED_CARD, importBusItem, 4, essentiaIoBusGroup); + Upgrades.add(AEItems.INVERTER_CARD, importBusItem, 1, essentiaIoBusGroup); + + var exportBusItem = ModItems.ESSENTIA_EXPORT_BUS.get(); + Upgrades.add(AEItems.FUZZY_CARD, exportBusItem, 1, essentiaIoBusGroup); + Upgrades.add(AEItems.REDSTONE_CARD, exportBusItem, 1, essentiaIoBusGroup); + Upgrades.add(AEItems.CAPACITY_CARD, exportBusItem, 5, essentiaIoBusGroup); + Upgrades.add(AEItems.SPEED_CARD, exportBusItem, 4, essentiaIoBusGroup); + Upgrades.add(AEItems.CRAFTING_CARD, exportBusItem, 1, essentiaIoBusGroup); + + var storageBusItem = ModItems.ESSENTIA_STORAGE_BUS.get(); + Upgrades.add(AEItems.FUZZY_CARD, storageBusItem, 1); + Upgrades.add(AEItems.INVERTER_CARD, storageBusItem, 1); + Upgrades.add(AEItems.CAPACITY_CARD, storageBusItem, 5); + Upgrades.add(AEItems.VOID_CARD, storageBusItem, 1); + }); + } + + private void registerScreens(RegisterMenuScreensEvent event) { + event.register(ModMenuTypes.ESSENTIA_CELL_WORKBENCH.get(), GuiEssentiaCellWorkbench::new); + event.register(ModMenuTypes.EVC.get(), GuiEssentiaVibrationChamber::new); + event.register(ModMenuTypes.ARCANE_ASSEMBLER.get(), GuiArcaneAssembler::new); + event.register(ModMenuTypes.ESSENTIA_TERMINAL.get(), GuiEssentiaCellTerminal::new); + event.register(ModMenuTypes.KNOWLEDGE_INSCRIBER.get(), GuiKnowledgeInscriber::new); + event.register(ModMenuTypes.DISTILLATION_ENCODER.get(), GuiDistillationPatternEncoder::new); + + event.register(ModMenuTypes.ESSENTIA_IMPORT_BUS.get(), + (ContainerEssentiaImportBus menu, Inventory inv, Component title) + -> new GuiEssentiaImportBus(menu, inv, title, + StyleManager.loadStyleDoc("/screens/import_bus.json"))); + + event.register(ModMenuTypes.ESSENTIA_EXPORT_BUS.get(), + (ContainerEssentiaExportBus menu, Inventory inv, Component title) + -> new GuiEssentiaExportBus(menu, inv, title, + StyleManager.loadStyleDoc("/screens/export_bus.json"))); + + event.register(ModMenuTypes.ESSENTIA_STORAGE_BUS.get(), + (ContainerEssentiaStorageBus menu, Inventory inv, Component title) + -> new GuiEssentiaStorageBus(menu, inv, title, + StyleManager.loadStyleDoc("/screens/storage_bus.json"))); + + event.register(ModMenuTypes.ARCANE_CRAFTING_TERMINAL.get(), + (ContainerArcaneCraftingTerminal menu, Inventory inv, Component title) + -> new GuiArcaneCraftingTerminal(menu, inv, title, + StyleManager.loadStyleDoc("/screens/arcane_crafting_terminal.json"))); + + event.register(ModMenuTypes.ESSENTIA_LEVEL_EMITTER.get(), + (ContainerEssentiaLevelEmitter menu, Inventory inv, Component title) + -> new GuiEssentiaLevelEmitter(menu, inv, title, + StyleManager.loadStyleDoc("/screens/essentia_level_emitter.json"))); + } + + private void registerKeyTypes(net.neoforged.neoforge.registries.RegisterEvent event) { + LOG.info("registerKeyTypes fired, registryKey={}", event.getRegistryKey()); + if (event.getRegistryKey() == AEKeyType.REGISTRY_KEY) { + AEKeyTypesInternal.register(AEssentiaKeyType.INSTANCE); + LOG.info("AEssentiaKeyType registered successfully!"); + } + } + + private void registerCapabilities(RegisterCapabilitiesEvent event) { + LOG.info("Registering AE2 grid node capabilities..."); + event.registerBlockEntity( + AECapabilities.IN_WORLD_GRID_NODE_HOST, + ModBlockEntities.ESSENTIA_PROVIDER.get(), + (be, context) -> (appeng.api.networking.IInWorldGridNodeHost) be); + event.registerBlockEntity( + AECapabilities.IN_WORLD_GRID_NODE_HOST, + ModBlockEntities.INFUSION_PROVIDER.get(), + (be, context) -> (appeng.api.networking.IInWorldGridNodeHost) be); + event.registerBlockEntity( + AECapabilities.IN_WORLD_GRID_NODE_HOST, + ModBlockEntities.ESSENTIA_VIBRATION_CHAMBER.get(), + (be, context) -> (appeng.api.networking.IInWorldGridNodeHost) be); + // 装配器也实现 IInWorldGridNodeHost,必须注册 capability,否则 AE2 线缆连不上 → + // 装配器孤立成自己的网格,ME 终端看不到它提供的可合成配方。 + event.registerBlockEntity( + AECapabilities.IN_WORLD_GRID_NODE_HOST, + ModBlockEntities.ARCANE_ASSEMBLER.get(), + (be, context) -> (appeng.api.networking.IInWorldGridNodeHost) be); + } +} diff --git a/src/main/java/thaumicenergistics/api/IThETransportPermissions.java b/src/main/java/thaumicenergistics/api/IThETransportPermissions.java new file mode 100644 index 0000000..053c9a3 --- /dev/null +++ b/src/main/java/thaumicenergistics/api/IThETransportPermissions.java @@ -0,0 +1,22 @@ +package thaumicenergistics.api; + +import net.minecraft.resources.ResourceLocation; +import java.util.OptionalLong; + +/** 定义 ThaumicEnergistics 可交互的物品与方块实体。自 1.7.10 移植。 */ +public interface IThETransportPermissions { + /** 注册一个方块实体类,支持抽取与注入。 */ + boolean addTileToBoth(Class tileClass, int capacity); + /** 注册一个仅支持抽取的方块实体。 */ + boolean addTileToExtract(Class tileClass, int capacity); + /** 注册一个仅支持注入的方块实体。 */ + boolean addTileToInject(Class tileClass, int capacity); + /** 获取方块实体类已注册的容量;未注册返回空。 */ + OptionalLong getCapacityForTile(Class tileClass); + /** 检查该方块实体是否允许抽取。 */ + boolean canExtract(net.minecraft.world.level.block.entity.BlockEntity tile); + /** 检查该方块实体是否允许注入。 */ + boolean canInject(net.minecraft.world.level.block.entity.BlockEntity tile); + /** 注册一个带容量的容器物品类型。 */ + void addContainerItem(Class itemClass, int capacity, boolean canHoldPartial); +} diff --git a/src/main/java/thaumicenergistics/api/grid/ICraftingIssuerHost.java b/src/main/java/thaumicenergistics/api/grid/ICraftingIssuerHost.java new file mode 100644 index 0000000..3a28990 --- /dev/null +++ b/src/main/java/thaumicenergistics/api/grid/ICraftingIssuerHost.java @@ -0,0 +1,6 @@ +package thaumicenergistics.api.grid; + +/** 合成请求宿主 —— 接收合成请求。移植自 1.7.10。 */ +public interface ICraftingIssuerHost { + void launchCrafting(net.minecraft.resources.ResourceLocation aspectId, long amount); +} diff --git a/src/main/java/thaumicenergistics/api/grid/IDigiVisSource.java b/src/main/java/thaumicenergistics/api/grid/IDigiVisSource.java new file mode 100644 index 0000000..2ac494b --- /dev/null +++ b/src/main/java/thaumicenergistics/api/grid/IDigiVisSource.java @@ -0,0 +1,7 @@ +package thaumicenergistics.api.grid; + +/** 数字 vis 源——从 AE 网络提供 vis。移植自 1.7.10。 */ +public interface IDigiVisSource { + int consumeVis(net.minecraft.resources.ResourceLocation aspectId, int amount); + boolean isActive(); +} diff --git a/src/main/java/thaumicenergistics/api/grid/IEssentiaGrid.java b/src/main/java/thaumicenergistics/api/grid/IEssentiaGrid.java new file mode 100644 index 0000000..6a55050 --- /dev/null +++ b/src/main/java/thaumicenergistics/api/grid/IEssentiaGrid.java @@ -0,0 +1,49 @@ +package thaumicenergistics.api.grid; + +import net.minecraft.resources.ResourceLocation; +import appeng.api.networking.IGridService; +import thaumicenergistics.api.storage.IAspectStack; + +import java.util.List; + +/** + * AE2 Grid 网络的源质网格服务。 + * + * 通过 {@code grid.getCache(IEssentiaGrid.class)} 获取。 + * 提供源质的存取查询接口,供无线傀儡背包、源质提供器等使用。 + * + * 注意:这是方案A(轻量级)实现——源质作为独立的 GridService, + * 不注册为 AE2 的 AEKeyType。后续可升级为方案B(原生 AEKeyType 集成)。 + */ +public interface IEssentiaGrid extends IGridService { + + /** + * 获取网络中指定源质的存储量。 + * + * @param aspectId 源质 ID(如 "thaumcraft:ignis") + * @return 存储量,不存在返回 0 + */ + long getEssentiaAmount(ResourceLocation aspectId); + + /** + * 从网络提取源质。 + * + * @param aspectId 源质 ID + * @param amount 要提取的量 + * @param simulate true 为模拟,false 为实际执行 + * @return 实际提取的量 + */ + long extractEssentia(ResourceLocation aspectId, long amount, boolean simulate); + + /** + * 向网络注入源质。 + * + * @param aspectId 源质 ID + * @param amount 要注入的量 + * @param simulate true 为模拟,false 为实际执行 + * @return 无法注入的量(0 表示全部成功) + */ + long injectEssentia(ResourceLocation aspectId, long amount, boolean simulate); + + List getEssentiaList(); +} diff --git a/src/main/java/thaumicenergistics/api/grid/IEssentiaWatcher.java b/src/main/java/thaumicenergistics/api/grid/IEssentiaWatcher.java new file mode 100644 index 0000000..eeb9705 --- /dev/null +++ b/src/main/java/thaumicenergistics/api/grid/IEssentiaWatcher.java @@ -0,0 +1,8 @@ +package thaumicenergistics.api.grid; + +import net.minecraft.resources.ResourceLocation; + +/** 监听源质网格变化并通知宿主。移植自 1.7.10。 */ +public interface IEssentiaWatcher extends java.util.Collection { + IEssentiaWatcherHost getHost(); +} diff --git a/src/main/java/thaumicenergistics/api/grid/IEssentiaWatcherHost.java b/src/main/java/thaumicenergistics/api/grid/IEssentiaWatcherHost.java new file mode 100644 index 0000000..72b3e1c --- /dev/null +++ b/src/main/java/thaumicenergistics/api/grid/IEssentiaWatcherHost.java @@ -0,0 +1,9 @@ +package thaumicenergistics.api.grid; + +import net.minecraft.resources.ResourceLocation; + +/** 源质存量变化时通知宿主。移植自 1.7.10。 */ +public interface IEssentiaWatcherHost { + void onEssentiaChange(ResourceLocation aspectId, long storedAmount, long changeAmount); + void updateWatcher(IEssentiaWatcher newWatcher); +} diff --git a/src/main/java/thaumicenergistics/api/storage/AspectStack.java b/src/main/java/thaumicenergistics/api/storage/AspectStack.java new file mode 100644 index 0000000..91fd438 --- /dev/null +++ b/src/main/java/thaumicenergistics/api/storage/AspectStack.java @@ -0,0 +1,8 @@ +package thaumicenergistics.api.storage; +import net.minecraft.resources.ResourceLocation; + +public record AspectStack(ResourceLocation aspectId, long amount) implements IAspectStack { + public static final AspectStack EMPTY = new AspectStack(ResourceLocation.fromNamespaceAndPath("thaumicenergistics", "empty"), 0); + @Override public boolean isEmpty() { return amount <= 0; } + @Override public IAspectStack copy(long newAmount) { return new AspectStack(aspectId, newAmount); } +} diff --git a/src/main/java/thaumicenergistics/api/storage/IAspectStack.java b/src/main/java/thaumicenergistics/api/storage/IAspectStack.java new file mode 100644 index 0000000..68f792f --- /dev/null +++ b/src/main/java/thaumicenergistics/api/storage/IAspectStack.java @@ -0,0 +1,4 @@ +package thaumicenergistics.api.storage; +import net.minecraft.resources.ResourceLocation; + +public interface IAspectStack { ResourceLocation aspectId(); long amount(); boolean isEmpty(); IAspectStack copy(long newAmount); } diff --git a/src/main/java/thaumicenergistics/client/ClientInit.java b/src/main/java/thaumicenergistics/client/ClientInit.java new file mode 100644 index 0000000..b0ef989 --- /dev/null +++ b/src/main/java/thaumicenergistics/client/ClientInit.java @@ -0,0 +1,21 @@ +package thaumicenergistics.client; + +import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.common.integration.appeng.AEssentiaKey; +import thaumicenergistics.common.integration.appeng.AEssentiaKeyType; + +public final class ClientInit { + private ClientInit() {} + + public static void onClientSetup(FMLClientSetupEvent event) { + event.enqueueWork(() -> { + appeng.api.client.AEKeyRendering.register( + AEssentiaKeyType.INSTANCE, + AEssentiaKey.class, + new EssentiaKeyRenderHandler() + ); + ThaumicEnergistics.LOG.info("EssentiaKeyRenderHandler registered successfully!"); + }); + } +} \ No newline at end of file diff --git a/src/main/java/thaumicenergistics/client/ClientSetup.java b/src/main/java/thaumicenergistics/client/ClientSetup.java new file mode 100644 index 0000000..1c42f10 --- /dev/null +++ b/src/main/java/thaumicenergistics/client/ClientSetup.java @@ -0,0 +1,82 @@ +package thaumicenergistics.client; + +import net.minecraft.client.model.geom.EntityModelSet; +import net.minecraft.client.renderer.entity.EntityRenderer; +import net.minecraft.client.renderer.entity.MobRenderer; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.client.event.EntityRenderersEvent; +import net.neoforged.neoforge.client.event.RegisterColorHandlersEvent; +import thaumcraft.client.renderers.entity.LegacyGolemModel; +import thaumcraft.client.renderers.entity.ThaumcraftGolemRenderer; +import thaumcraft.common.entities.golem.ThaumcraftGolemEntity; +import thaumcraft.common.registry.TCEntityTypes; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.client.render.layer.GolemBackpackLayer; +import thaumicenergistics.client.render.model.GolemBackpackModel; +import thaumicenergistics.client.render.RenderTileArcaneAssembler; +import thaumicenergistics.client.render.RenderTileEVC; +import thaumicenergistics.init.ModBlockEntities; +import thaumicenergistics.init.ModItems; + +/** 客户端渲染注册的事件处理器。 */ +@EventBusSubscriber(modid = ThaumicEnergistics.MODID, value = Dist.CLIENT) +public final class ClientSetup { + + /** 背包模型的 LayerDefinition 注册 key */ + public static final net.minecraft.client.model.geom.ModelLayerLocation GOLEM_BACKPACK_LAYER = + new net.minecraft.client.model.geom.ModelLayerLocation( + net.minecraft.resources.ResourceLocation.fromNamespaceAndPath(ThaumicEnergistics.MODID, "golem_backpack"), + "main"); + + @SubscribeEvent + public static void registerBER(EntityRenderersEvent.RegisterRenderers event) { + event.registerBlockEntityRenderer(ModBlockEntities.ARCANE_ASSEMBLER.get(), RenderTileArcaneAssembler::new); + event.registerBlockEntityRenderer(ModBlockEntities.ESSENTIA_VIBRATION_CHAMBER.get(), RenderTileEVC::new); + } + + @SubscribeEvent + public static void registerLayerDefinitions(EntityRenderersEvent.RegisterLayerDefinitions event) { + event.registerLayerDefinition(GOLEM_BACKPACK_LAYER, GolemBackpackModel::createBodyLayer); + } + + @SubscribeEvent + public static void addEntityLayers(EntityRenderersEvent.AddLayers event) { + // 给 Thaumcraft 的傀儡渲染器添加背包渲染层 + EntityRenderer renderer = event.getRenderer(TCEntityTypes.GOLEM.get()); + if (renderer instanceof ThaumcraftGolemRenderer golemRenderer) { + EntityModelSet modelSet = event.getEntityModels(); + net.minecraft.client.model.geom.ModelPart backpackPart = modelSet.bakeLayer(GOLEM_BACKPACK_LAYER); + GolemBackpackModel backpackModel = new GolemBackpackModel(backpackPart); + golemRenderer.addLayer(new GolemBackpackLayer(golemRenderer, backpackModel)); + } + } + + @SubscribeEvent + public static void registerItemColors(RegisterColorHandlersEvent.Item event) { + // 给源质终端物品着色:完全对齐 AEColor.TRANSPARENT.getVariantByTintIndex() + event.register((stack, tintIndex) -> { + return switch (tintIndex) { + case 0 -> -1; // 不染色 + case 1 -> 0xFF5a479e; // Dark: 深紫色 + case 2 -> 0xFF915dcd; // Medium: 紫色 + case 3 -> 0xFFe2a3e3; // Bright: 淡紫色 + case 4 -> 0xFFb980d8; // Medium Bright: 中间紫 + default -> -1; + }; + }, ModItems.ESSENTIA_TERMINAL_ITEM.get()); + + // 给无线源质终端物品着色(与源质终端部件相同的紫色) + event.register((stack, tintIndex) -> { + return switch (tintIndex) { + case 0 -> -1; + case 1 -> 0xFF5a479e; + case 2 -> 0xFF915dcd; + case 3 -> 0xFFe2a3e3; + case 4 -> 0xFFb980d8; + default -> -1; + }; + }, ModItems.WIRELESS_ESSENTIA_TERMINAL.get()); + } +} diff --git a/src/main/java/thaumicenergistics/client/EssentiaKeyRenderHandler.java b/src/main/java/thaumicenergistics/client/EssentiaKeyRenderHandler.java new file mode 100644 index 0000000..8185824 --- /dev/null +++ b/src/main/java/thaumicenergistics/client/EssentiaKeyRenderHandler.java @@ -0,0 +1,61 @@ +package thaumicenergistics.client; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.Level; +import thaumicenergistics.common.integration.appeng.AEssentiaKey; + +import java.util.ArrayList; +import java.util.List; + +public class EssentiaKeyRenderHandler implements appeng.api.client.AEKeyRenderHandler { + + @Override + public void drawInGui(Minecraft minecraft, GuiGraphics guiGraphics, int x, int y, AEssentiaKey stack) { + String tag = stack.getId().getPath(); + // 渲染要素图标(透明背景):TC 的 aspect 图标是白色剪影,需用 aspect 颜色着色(与 JEI 的 AspectGuiRenderer 一致) + int color = getAspectColor(tag); + float r = ((color >> 16) & 0xFF) / 255.0f; + float g = ((color >> 8) & 0xFF) / 255.0f; + float b = (color & 0xFF) / 255.0f; + guiGraphics.setColor(r, g, b, 1.0f); + guiGraphics.blit(aspectTexture(tag), x, y, 0, 0, 16, 16, 16, 16); + guiGraphics.setColor(1.0f, 1.0f, 1.0f, 1.0f); + } + + /** 按 tag 缓存 aspect 贴图 RL,避免每帧 fromNamespaceAndPath。 */ + private static final java.util.Map TEXTURE_CACHE = new java.util.HashMap<>(); + + private static ResourceLocation aspectTexture(String tag) { + return TEXTURE_CACHE.computeIfAbsent(tag, + t -> ResourceLocation.fromNamespaceAndPath("thaumcraft", "textures/aspects/" + t + ".png")); + } + + /** 获取 aspect 的 ARGB 颜色(按 tag 查 Thaumcraft Aspect),未知返回白色。 */ + private static int getAspectColor(String tag) { + thaumcraft.api.aspects.Aspect aspect = thaumcraft.api.aspects.Aspect.getAspect(tag); + return aspect != null ? aspect.getColor() : 0xFFFFFFFF; + } + + @Override + public void drawOnBlockFace(PoseStack poseStack, MultiBufferSource buffers, AEssentiaKey what, + float scale, int combinedLight, Level level) { + } + + @Override + public Component getDisplayName(AEssentiaKey stack) { + return stack.getDisplayName(); // 由 AEssentiaKey.computeDisplayName() 返回源质真实名称 + } + + @Override + public List getTooltip(AEssentiaKey stack) { + List tooltip = new ArrayList<>(); + tooltip.add(stack.getDisplayName()); + tooltip.add(Component.literal(appeng.util.Platform.formatModName(stack.getModId()))); + return tooltip; + } +} \ No newline at end of file diff --git a/src/main/java/thaumicenergistics/client/render/RenderTileArcaneAssembler.java b/src/main/java/thaumicenergistics/client/render/RenderTileArcaneAssembler.java new file mode 100644 index 0000000..185beaf --- /dev/null +++ b/src/main/java/thaumicenergistics/client/render/RenderTileArcaneAssembler.java @@ -0,0 +1,19 @@ +package thaumicenergistics.client.render; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import thaumicenergistics.common.tiles.TileArcaneAssembler; + +/** 奥术装配器的渲染器——显示合成进度动画。 */ +public class RenderTileArcaneAssembler implements BlockEntityRenderer { + + public RenderTileArcaneAssembler(BlockEntityRendererProvider.Context ctx) {} + + @Override + public void render(TileArcaneAssembler tile, float partialTick, PoseStack poseStack, + MultiBufferSource buffer, int packedLight, int packedOverlay) { + // TODO: Render crafting progress bar and speed upgrade indicators + } +} diff --git a/src/main/java/thaumicenergistics/client/render/RenderTileEVC.java b/src/main/java/thaumicenergistics/client/render/RenderTileEVC.java new file mode 100644 index 0000000..217ee1f --- /dev/null +++ b/src/main/java/thaumicenergistics/client/render/RenderTileEVC.java @@ -0,0 +1,19 @@ +package thaumicenergistics.client.render; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import thaumicenergistics.common.tiles.TileEssentiaVibrationChamber; + +/** 源质谐振仓的渲染器——显示燃烧进度。 */ +public class RenderTileEVC implements BlockEntityRenderer { + + public RenderTileEVC(BlockEntityRendererProvider.Context ctx) {} + + @Override + public void render(TileEssentiaVibrationChamber tile, float partialTick, PoseStack poseStack, + MultiBufferSource buffer, int packedLight, int packedOverlay) { + // TODO: Render flame/burn animation proportional to burnProgress + } +} diff --git a/src/main/java/thaumicenergistics/client/render/layer/GolemBackpackLayer.java b/src/main/java/thaumicenergistics/client/render/layer/GolemBackpackLayer.java new file mode 100644 index 0000000..cdfb115 --- /dev/null +++ b/src/main/java/thaumicenergistics/client/render/layer/GolemBackpackLayer.java @@ -0,0 +1,90 @@ +package thaumicenergistics.client.render.layer; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.entity.RenderLayerParent; +import net.minecraft.client.renderer.entity.layers.RenderLayer; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.resources.ResourceLocation; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.api.distmarker.OnlyIn; +import thaumcraft.client.renderers.entity.LegacyGolemModel; +import thaumcraft.common.entities.golem.ThaumcraftGolemEntity; +import thaumicenergistics.client.render.model.GolemBackpackModel; +import thaumicenergistics.common.entities.BackpackSkins; +import thaumicenergistics.common.network.GolemBackpackClientData; +import thaumicenergistics.common.network.GolemBackpackSyncPacket; + +/** + * 傀儡无线背包渲染层。 + * 当傀儡装备了无线背包时,在背上渲染天线 + 背包盒(使用当前皮肤纹理),以及旋转的福鲁伊克斯珍珠(绿色=连接,红色=断开)。 + * 数据来源:{@link GolemBackpackClientData}(由 S2C 网络包更新)。 + * 皮肤和连接状态均从客户端缓存读取,不直接查询 NBT。 + */ +@OnlyIn(Dist.CLIENT) +public class GolemBackpackLayer extends RenderLayer { + + /** 默认纹理(Thaumium 皮肤) */ + private static final ResourceLocation DEFAULT_TEXTURE = + BackpackSkins.Thaumium.getTextureLocation(); + + /** 珍珠旋转速度(度/tick) */ + private static final float PEARL_ROTATION_SPEED = 2.0f; + + private final GolemBackpackModel model; + + public GolemBackpackLayer(RenderLayerParent parent, + GolemBackpackModel model) { + super(parent); + this.model = model; + } + + @Override + public void render(PoseStack poseStack, MultiBufferSource bufferSource, int packedLight, + ThaumcraftGolemEntity golem, float limbSwing, float limbSwingAmount, + float partialTick, float ageInTicks, float netHeadYaw, float headPitch) { + // 仅在傀儡装备了背包时渲染(从客户端缓存读取) + if (!GolemBackpackClientData.hasBackpack(golem)) { + return; + } + + // 从客户端缓存读取连接状态和皮肤 + boolean inRange = GolemBackpackClientData.isInRange(golem); + BackpackSkins skin = GolemBackpackClientData.getSkin(golem); + ResourceLocation texture = skin.getTextureLocation(); + + float pearlRotation = (golem.tickCount + partialTick) * PEARL_ROTATION_SPEED; + + VertexConsumer buffer = bufferSource.getBuffer(cutoutRenderType(texture)); + + // 对齐到傀儡身体 + poseStack.pushPose(); + // 傀儡模型尺寸约 0.4×0.95,背包放在背部偏上 + poseStack.scale(0.5f, 0.5f, 0.5f); + // 略微后移到背上 + poseStack.translate(0, 0.5, -1.5); + + model.renderToBuffer(poseStack, buffer, packedLight, OverlayTexture.NO_OVERLAY, pearlRotation); + + // 渲染珍珠(使用 entityTranslucent 允许半透明效果) + VertexConsumer pearlBuffer = bufferSource.getBuffer(translucentRenderType(texture)); + model.renderPearl(poseStack, pearlBuffer, packedLight, OverlayTexture.NO_OVERLAY, + pearlRotation, inRange); + + poseStack.popPose(); + } + + /** 按贴图缓存 RenderType,避免每帧创建(渲染主线程单线程安全)。 */ + private static final java.util.Map CUTOUT_CACHE = new java.util.HashMap<>(); + private static final java.util.Map TRANSLUCENT_CACHE = new java.util.HashMap<>(); + + private static RenderType cutoutRenderType(ResourceLocation tex) { + return CUTOUT_CACHE.computeIfAbsent(tex, RenderType::entityCutoutNoCull); + } + + private static RenderType translucentRenderType(ResourceLocation tex) { + return TRANSLUCENT_CACHE.computeIfAbsent(tex, RenderType::entityTranslucent); + } +} diff --git a/src/main/java/thaumicenergistics/client/render/model/GolemBackpackModel.java b/src/main/java/thaumicenergistics/client/render/model/GolemBackpackModel.java new file mode 100644 index 0000000..fc74244 --- /dev/null +++ b/src/main/java/thaumicenergistics/client/render/model/GolemBackpackModel.java @@ -0,0 +1,181 @@ +package thaumicenergistics.client.render.model; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.CubeListBuilder; +import net.minecraft.client.model.geom.builders.LayerDefinition; +import net.minecraft.client.model.geom.builders.MeshDefinition; +import net.minecraft.client.model.geom.builders.PartDefinition; +import org.joml.Matrix4f; +import org.joml.Vector4f; + +/** + * 傀儡无线背包模型(简化版)。 + * + * 包含三个部件:Antenna(天线,1×3×1)、PackBack(背包主体,2×6×6)、PackFront(背包前面板,1×2×4)。 + * 旋转的福鲁伊克斯珍珠由 GolemBackpackLayer 在渲染时手动绘制。 + * 对应 1.7.10 的 ModelGolemWifiBackpack,简化为统一的 Thaumium 皮肤。 + */ +public class GolemBackpackModel { + + private final ModelPart root; + + public GolemBackpackModel(ModelPart root) { + this.root = root; + } + + /** + * 创建 LayerDefinition,供 {@code EntityRenderersEvent.RegisterLayerDefinitions} 注册。 + * 纹理尺寸 16×16,与 1.7.10 一致。 + */ + public static LayerDefinition createBodyLayer() { + MeshDefinition mesh = new MeshDefinition(); + PartDefinition part = mesh.getRoot(); + + // 天线:1×3×1,纹理偏移 (10,0),X 轴旋转 180° + part.addOrReplaceChild("antenna", + CubeListBuilder.create().texOffs(10, 0) + .addBox(-0.5f, -6f, -0.5f, 1, 3, 1), + PartPose.rotation((float) Math.PI, 0, 0)); + + // 背包主体:2×6×6,纹理偏移 (0,0),X 轴旋转 180° + part.addOrReplaceChild("pack_back", + CubeListBuilder.create().texOffs(0, 0) + .addBox(-1f, -3f, -3f, 2, 6, 6), + PartPose.rotation((float) Math.PI, 0, 0)); + + // 背包前面板:1×2×4,纹理偏移 (2,0),X 轴旋转 180° + part.addOrReplaceChild("pack_front", + CubeListBuilder.create().texOffs(2, 0) + .addBox(-1.5f, -1f, -2f, 1, 2, 4), + PartPose.rotation((float) Math.PI, 0, 0)); + + return LayerDefinition.create(mesh, 16, 16); + } + + /** + * 渲染背包箱体(天线 + 主体 + 前面板)。 + */ + public void renderToBuffer(PoseStack poseStack, VertexConsumer buffer, + int light, int overlay, float pearlRotation) { + root.render(poseStack, buffer, light, overlay); + } + + /** + * 渲染旋转的福鲁伊克斯珍珠:位于天线上方,4 个面围绕天线绘制,随 pearlRotation 旋转。 + * UV 坐标:minU=0.5, maxU=0.84375, minV=0.375, maxV=0.71875(16×16 纹理)。 + * + * @param poseStack PoseStack + * @param buffer VertexConsumer + * @param light packed light + * @param overlay packed overlay + * @param pearlRotation 旋转角度(度) + * @param inRange true=正常紫色,false=红色(不在范围内) + */ + public void renderPearl(PoseStack poseStack, VertexConsumer buffer, + int light, int overlay, float pearlRotation, boolean inRange) { + float pearlScale = 0.2f; + float antennaWidth = 0.32f; + float faceDist = -0.013f / pearlScale; + float twoFD = faceDist + faceDist; + + // UV 坐标(16×16 纹理) + float minU = 8.0f / 16.0f; + float maxU = 13.5f / 16.0f; + float minV = 6.0f / 16.0f; + float maxV = 11.5f / 16.0f; + + // 颜色:不在范围内时红色 + int red = inRange ? 255 : 255; + int green = inRange ? 255 : 0; + int blue = inRange ? 255 : 0; + + poseStack.pushPose(); + + poseStack.mulPose(com.mojang.math.Axis.YP.rotationDegrees(pearlRotation)); + + poseStack.scale(pearlScale, pearlScale, pearlScale); + + // 左面 + poseStack.pushPose(); + poseStack.translate(-0.0955f, 0.275f, -0.045f); + drawPearlFace(poseStack, buffer, light, overlay, minU, maxU, minV, maxV, red, green, blue, 0, 0, 1); + // 右面 + poseStack.translate(0, 0, antennaWidth - twoFD); + drawPearlFace(poseStack, buffer, light, overlay, maxU, minU, minV, maxV, red, green, blue, 0, 0, -1); + poseStack.popPose(); + + // 前后两面(旋转 90°) + poseStack.pushPose(); + poseStack.mulPose(com.mojang.math.Axis.YP.rotationDegrees(90)); + poseStack.translate(-0.0955f, 0.275f, -0.045f - antennaWidth - faceDist); + drawPearlFace(poseStack, buffer, light, overlay, maxU, minU, minV, maxV, red, green, blue, 0, 0, -1); + poseStack.translate(0, 0, antennaWidth - twoFD); + drawPearlFace(poseStack, buffer, light, overlay, minU, maxU, minV, maxV, red, green, blue, 0, 0, 1); + poseStack.popPose(); + + poseStack.popPose(); + } + + /** + * 绘制珍珠的一个面(正反两面,共 8 个顶点),手动通过矩阵变换顶点坐标。 + * 使用 1.21.1 的 VertexConsumer 新 API:addVertex + setColor + setUv + setOverlay + setLight + setNormal。 + */ + private void drawPearlFace(PoseStack poseStack, VertexConsumer buffer, int light, int overlay, + float minU, float maxU, float minV, float maxV, + int r, int g, int b, float nx, float ny, float nz) { + Matrix4f matrix = poseStack.last().pose(); + + // 四个角点的本地坐标 + float[][] corners = { + {0, 0, 0}, // 左下 + {1, 0, 0}, // 右下 + {1, 1, 0}, // 右上 + {0, 1, 0} // 左上 + }; + + // 正面 UV + float[][] frontUvs = { + {maxU, maxV}, + {minU, maxV}, + {minU, minV}, + {maxU, minV} + }; + + // 背面 UV(镜像) + float[][] backUvs = { + {maxU, minV}, + {minU, minV}, + {minU, maxV}, + {maxU, maxV} + }; + + Vector4f transformed = new Vector4f(); + + // 正面 + for (int i = 0; i < 4; i++) { + transformed.set(corners[i][0], corners[i][1], corners[i][2], 1.0f); + matrix.transform(transformed); + buffer.addVertex(transformed.x, transformed.y, transformed.z) + .setColor(r, g, b, 255) + .setUv(frontUvs[i][0], frontUvs[i][1]) + .setOverlay(overlay) + .setLight(light) + .setNormal(nx, ny, nz); + } + + // 背面(逆序 + 翻转法线) + for (int i = 0; i < 4; i++) { + transformed.set(corners[i][0], corners[i][1], corners[i][2], 1.0f); + matrix.transform(transformed); + buffer.addVertex(transformed.x, transformed.y, transformed.z) + .setColor(r, g, b, 255) + .setUv(backUvs[i][0], backUvs[i][1]) + .setOverlay(overlay) + .setLight(light) + .setNormal(-nx, -ny, -nz); + } + } +} diff --git a/src/main/java/thaumicenergistics/common/WrenchFocusHandler.java b/src/main/java/thaumicenergistics/common/WrenchFocusHandler.java new file mode 100644 index 0000000..91571bc --- /dev/null +++ b/src/main/java/thaumicenergistics/common/WrenchFocusHandler.java @@ -0,0 +1,56 @@ +package thaumicenergistics.common; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Rotation; +import net.minecraft.world.level.block.state.BlockState; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent; +import thaumcraft.common.items.TCFunctionalItems; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.common.items.ItemFocusAEWrench; +import thaumicenergistics.init.ModItems; + +@EventBusSubscriber(modid = ThaumicEnergistics.MODID) +public final class WrenchFocusHandler { + + private WrenchFocusHandler() { + } + + @SubscribeEvent + public static void onLeftClickBlock(PlayerInteractEvent.LeftClickBlock event) { + Player player = event.getEntity(); + Level level = player.level(); + ItemStack heldStack = player.getMainHandItem(); + + if (!(heldStack.getItem() instanceof TCFunctionalItems.WandCastingItem wand)) { + return; + } + + ItemStack focusStack = wand.getFocus(heldStack); + if (focusStack.isEmpty() || focusStack.getItem() != ModItems.FOCUS_AEWRENCH.get()) { + return; + } + + if (!player.isShiftKeyDown()) { + return; + } + + if (level.isClientSide()) { + return; + } + + BlockPos pos = event.getPos(); + BlockState state = level.getBlockState(pos); + BlockState rotated = state.rotate(level, pos, Rotation.CLOCKWISE_90); + + if (rotated != state) { + level.setBlock(pos, rotated, 3); + ItemFocusAEWrench.spawnBeamParticles(level, player, pos); + event.setCanceled(true); + } + } +} \ No newline at end of file diff --git a/src/main/java/thaumicenergistics/common/blocks/OrientableEntityBlock.java b/src/main/java/thaumicenergistics/common/blocks/OrientableEntityBlock.java new file mode 100644 index 0000000..bfde4af --- /dev/null +++ b/src/main/java/thaumicenergistics/common/blocks/OrientableEntityBlock.java @@ -0,0 +1,71 @@ +package thaumicenergistics.common.blocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.ItemInteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +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.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.DirectionProperty; +import net.minecraft.world.phys.BlockHitResult; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; +import thaumcraft.api.aspects.IEssentiaContainerItem; +import thaumicenergistics.common.tiles.ThETileBase; +import thaumicenergistics.common.tiles.TileEssentiaVibrationChamber; + +public abstract class OrientableEntityBlock extends Block implements EntityBlock { + + public static final DirectionProperty FACING = DirectionProperty.create("facing", Direction.Plane.HORIZONTAL); + + protected OrientableEntityBlock(Properties props) { + super(props); + this.registerDefaultState(this.stateDefinition.any().setValue(FACING, Direction.NORTH)); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder builder) { + builder.add(FACING); + } + + @Override + public BlockState getStateForPlacement(BlockPlaceContext context) { + return this.defaultBlockState().setValue(FACING, context.getHorizontalDirection().getOpposite()); + } + + @Override + public abstract BlockEntity newBlockEntity(BlockPos pos, BlockState state); + + @Override + protected ItemInteractionResult useItemOn(ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { + if (level.isClientSide()) return ItemInteractionResult.SUCCESS; + BlockEntity be = level.getBlockEntity(pos); + if (!(be instanceof TileEssentiaVibrationChamber chamber)) return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; + // 检查手持物品是否为源质安瓿瓶 + if (!(stack.getItem() instanceof IEssentiaContainerItem container)) return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; + AspectList aspects = container.getAspects(stack); + if (aspects == null || aspects.size() == 0) return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; + Aspect aspect = aspects.getAspects()[0]; + if (aspect == Aspect.FIRE || aspect == Aspect.ENERGY) { + chamber.setSuctionType(aspect); + return ItemInteractionResult.SUCCESS; + } + return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; + } + + @Override + public void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean moved) { + if (!state.is(newState.getBlock())) { + BlockEntity be = level.getBlockEntity(pos); + if (be instanceof ThETileBase tb) tb.onBreakBlock(); + } + super.onRemove(state, level, pos, newState, moved); + } +} diff --git a/src/main/java/thaumicenergistics/common/blocks/ThEBaseEntityBlock.java b/src/main/java/thaumicenergistics/common/blocks/ThEBaseEntityBlock.java new file mode 100644 index 0000000..0c0bab4 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/blocks/ThEBaseEntityBlock.java @@ -0,0 +1,47 @@ +package thaumicenergistics.common.blocks; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.EntityBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityTicker; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.Level; +import thaumicenergistics.common.tiles.TileEssentiaProvider; +import thaumicenergistics.common.tiles.TileEssentiaVibrationChamber; +import thaumicenergistics.common.tiles.TileInfusionProvider; +import thaumicenergistics.common.tiles.ThETileBase; + +public abstract class ThEBaseEntityBlock extends Block implements EntityBlock { + protected ThEBaseEntityBlock(Properties p) { super(p); } + + @Override + public abstract BlockEntity newBlockEntity(BlockPos pos, BlockState state); + + @Override + public BlockEntityTicker getTicker(Level level, BlockState state, BlockEntityType type) { + if (level.isClientSide()) return null; + if (type == thaumicenergistics.init.ModBlockEntities.ESSENTIA_PROVIDER.get()) { + return createTicker((lvl, pos, st, be) -> ((TileEssentiaProvider) be).serverTick()); + } + if (type == thaumicenergistics.init.ModBlockEntities.INFUSION_PROVIDER.get()) { + return createTicker((lvl, pos, st, be) -> ((TileInfusionProvider) be).serverTick()); + } + return null; + } + + @SuppressWarnings("unchecked") + private static BlockEntityTicker createTicker(BlockEntityTicker ticker) { + return (BlockEntityTicker) ticker; + } + + @Override + public void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean moved) { + if (!state.is(newState.getBlock())) { + BlockEntity be = level.getBlockEntity(pos); + if (be instanceof ThETileBase tb) tb.onBreakBlock(); + } + super.onRemove(state, level, pos, newState, moved); + } +} diff --git a/src/main/java/thaumicenergistics/common/container/ContainerArcaneAssembler.java b/src/main/java/thaumicenergistics/common/container/ContainerArcaneAssembler.java new file mode 100644 index 0000000..5a0ad5a --- /dev/null +++ b/src/main/java/thaumicenergistics/common/container/ContainerArcaneAssembler.java @@ -0,0 +1,260 @@ +package thaumicenergistics.common.container; + +import appeng.core.definitions.AEItems; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; +import net.neoforged.neoforge.items.ItemStackHandler; +import net.neoforged.neoforge.items.SlotItemHandler; +import thaumcraft.api.IVisDiscountGear; +import thaumcraft.api.IWarpingGear; +import thaumicenergistics.common.tiles.TileArcaneAssembler; +import thaumicenergistics.init.ModMenuTypes; + +/** + * 奥术装配器 Container。 + * + * 坐标完全对应1.7.10 ThaumicEnergistics: + * 玩家背包 Y=115,快捷栏 Y=173 + * 3×7 配方槽 (26, 25) + * 知识核心 (187, 8) + * 4加速卡 (187, 26) + * 目标产物 (14, 87) + * 4折扣护甲槽 (210, 26) + * + * 不继承 ThEContainerBase,因为基类把玩家背包放在AE2标准 Y=169, + * 而奥术装配器GUI贴图的背包在更高位置 Y=115。 + */ +public class ContainerArcaneAssembler extends AbstractContainerMenu { + + // ===== 坐标常量(1:1 对应1.7.10) ===== + private static final int PLAYER_INV_X = 8; + private static final int PLAYER_INV_Y = 115; + private static final int HOTBAR_Y = PLAYER_INV_Y + 58; // 173 + + private static final int PATTERN_X = 26; + private static final int PATTERN_Y = 25; + private static final int PATTERN_ROWS = 3; + private static final int PATTERN_COLS = 7; + + private static final int KCORE_X = 187; + private static final int KCORE_Y = 8; + + private static final int UPGRADE_X = 187; + private static final int UPGRADE_Y = 26; + private static final int UPGRADE_COUNT = 4; + + private static final int TARGET_X = 14; + private static final int TARGET_Y = 87; + + private static final int ARMOR_X = 210; + private static final int ARMOR_Y = 26; + private static final int ARMOR_COUNT = 4; + + // ===== 槽位划分(quickMoveStack 用) ===== + // 顺序 = 玩家(36) → KCore(1) → 3×7配方(21) → 升级卡(4) → 目标(1) → 护甲(4) = 67 + private static final int PLAYER_END = 36; + private static final int KCORE_IDX = 36; + private static final int PATTERN_START = 37; + private static final int PATTERN_END = PATTERN_START + PATTERN_ROWS * PATTERN_COLS; // 58 + private static final int UPGRADE_START = PATTERN_END; // 58 + private static final int UPGRADE_END = UPGRADE_START + UPGRADE_COUNT; // 62 + private static final int TARGET_IDX = UPGRADE_END; // 62 + private static final int ARMOR_START = TARGET_IDX + 1; // 63 + private static final int ARMOR_END = ARMOR_START + ARMOR_COUNT; // 67 + + /** 升级卡 handler(独立4格,与 Tile 的 speedUpgrades 字段同步) */ + final ItemStackHandler upgradeHandler = new ItemStackHandler(UPGRADE_COUNT) { + @Override protected void onContentsChanged(int slot) { + super.onContentsChanged(slot); + if (assembler != null) { + int count = 0; + for (int i = 0; i < UPGRADE_COUNT; i++) + if (!getStackInSlot(i).isEmpty()) count++; + assembler.setSpeedUpgrades(count); + } + } + }; + + public final TileArcaneAssembler assembler; + + /** 服务端构造(由 Block#getMenuProvider 调用,不带 tile) */ + public ContainerArcaneAssembler(int id, Inventory inv) { + this(id, inv, (TileArcaneAssembler) null); + } + + /** 服务端构造(带 tile 引用) */ + public ContainerArcaneAssembler(int id, Inventory inv, TileArcaneAssembler tile) { + super(ModMenuTypes.ARCANE_ASSEMBLER.get(), id); + this.assembler = tile; + + // ===== 1. 玩家背包 3行 ===== + for (int r = 0; r < 3; r++) + for (int c = 0; c < 9; c++) + addSlot(new Slot(inv, c + r * 9 + 9, + PLAYER_INV_X + c * 18, PLAYER_INV_Y + r * 18)); + // ===== 2. 快捷栏 1行 ===== + for (int c = 0; c < 9; c++) + addSlot(new Slot(inv, c, PLAYER_INV_X + c * 18, HOTBAR_Y)); + + ItemStackHandler machineHandler = wrapMachineInventory(); + + // ===== 3. 知识核心 (Tile.KCORE_SLOT = 0) ===== + addSlot(new SlotItemHandler(machineHandler, TileArcaneAssembler.KCORE_SLOT, KCORE_X, KCORE_Y) { + @Override public boolean mayPlace(ItemStack stack) { + return stack.is(thaumicenergistics.init.ModItems.KNOWLEDGE_CORE.get()); + } + }); + + // ===== 4. 3×7 配方槽(只读展示) ===== + for (int r = 0; r < PATTERN_ROWS; r++) + for (int c = 0; c < PATTERN_COLS; c++) { + int invIdx = TileArcaneAssembler.PATTERN_SLOT_START + r * PATTERN_COLS + c; + addSlot(new SlotItemHandler(machineHandler, invIdx, + PATTERN_X + c * 18, PATTERN_Y + r * 18) { + @Override public boolean mayPlace(ItemStack s) { return false; } + @Override public boolean mayPickup(Player p) { return false; } + @Override public int getMaxStackSize() { return 1; } + }); + } + + // ===== 5. 4张AE2速度卡 ===== + for (int i = 0; i < UPGRADE_COUNT; i++) { + addSlot(new SlotItemHandler(upgradeHandler, i, UPGRADE_X, UPGRADE_Y + i * 18) { + @Override + public boolean mayPlace(ItemStack s) { + return AEItems.SPEED_CARD.is(s); + } + }); + } + + // ===== 6. 目标产物输出槽(只读展示) ===== + addSlot(new SlotItemHandler(machineHandler, TileArcaneAssembler.TARGET_SLOT, TARGET_X, TARGET_Y) { + @Override public boolean mayPlace(ItemStack s) { return false; } + @Override public boolean mayPickup(Player p) { return false; } + }); + + // ===== 7. 4个护甲折扣槽 ===== + for (int i = 0; i < ARMOR_COUNT; i++) { + final int armorIdx = i; + int invIdx = TileArcaneAssembler.ARMOR_SLOT_START + i; + final net.minecraft.world.entity.EquipmentSlot eq = switch (i) { + case 0 -> net.minecraft.world.entity.EquipmentSlot.HEAD; + case 1 -> net.minecraft.world.entity.EquipmentSlot.CHEST; + case 2 -> net.minecraft.world.entity.EquipmentSlot.LEGS; + default -> net.minecraft.world.entity.EquipmentSlot.FEET; + }; + addSlot(new SlotItemHandler(machineHandler, invIdx, ARMOR_X, ARMOR_Y + i * 18) { + @Override public boolean mayPlace(ItemStack s) { + if (s.getItem() instanceof IVisDiscountGear) return true; + if (s.getItem() instanceof IWarpingGear) return true; + if (s.getItem() instanceof net.minecraft.world.item.Equipable eqItem + && eqItem.getEquipmentSlot() == eq) return true; + return s.canEquip(eq, null); + } + @Override public void setChanged() { + super.setChanged(); + if (assembler != null) + assembler.onInventoryChanged(TileArcaneAssembler.ARMOR_SLOT_START + armorIdx); + } + }); + } + } + + /** 客户端构造(IMenuTypeExtension 反射调用) */ + public ContainerArcaneAssembler(int id, Inventory inv, RegistryFriendlyByteBuf buf) { + this(id, inv); + } + + private ItemStackHandler wrapMachineInventory() { + final net.minecraft.world.SimpleContainer inv = + (assembler != null) ? assembler.getInternalInventory() + : new net.minecraft.world.SimpleContainer(TileArcaneAssembler.SLOT_COUNT); + return new ItemStackHandler(inv.getContainerSize()) { + @Override public int getSlots() { return inv.getContainerSize(); } + @Override public ItemStack getStackInSlot(int slot) { return inv.getItem(slot); } + @Override public void setStackInSlot(int slot, ItemStack stack) { inv.setItem(slot, stack); } + @Override public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { + if (stack.isEmpty()) return ItemStack.EMPTY; + ItemStack cur = inv.getItem(slot); + if (!cur.isEmpty()) return stack; + if (!simulate) { + ItemStack cp = stack.copy(); cp.setCount(1); + inv.setItem(slot, cp); + } + ItemStack leftover = stack.copy(); + leftover.shrink(1); + return leftover; + } + @Override public ItemStack extractItem(int slot, int amount, boolean simulate) { + ItemStack cur = inv.getItem(slot); + if (cur.isEmpty()) return ItemStack.EMPTY; + int take = Math.min(amount, cur.getCount()); + ItemStack res = cur.copy(); res.setCount(take); + if (!simulate) { + ItemStack left = cur.copy(); left.shrink(take); + inv.setItem(slot, left.isEmpty() ? ItemStack.EMPTY : left); + } + return res; + } + @Override public int getSlotLimit(int slot) { return 1; } + }; + } + + // ===== Shift+点击 ===== + @Override public ItemStack quickMoveStack(Player player, int index) { + ItemStack result = ItemStack.EMPTY; + Slot slot = slots.get(index); + if (slot == null || !slot.hasItem()) return result; + ItemStack stack = slot.getItem(); + result = stack.copy(); + + if (index < PLAYER_END) { + // 玩家背包 → 知识核心 → 护甲 → 速度卡 → 背包↔快捷栏 + boolean merged = false; + + if (stack.is(thaumicenergistics.init.ModItems.KNOWLEDGE_CORE.get())) { + merged = moveItemStackTo(stack, KCORE_IDX, KCORE_IDX + 1, false); + } + + if (!merged && (stack.getItem() instanceof IVisDiscountGear + || stack.getItem() instanceof IWarpingGear + || stack.getItem() instanceof net.minecraft.world.item.ArmorItem + || stack.getItem() instanceof net.minecraft.world.item.Equipable)) { + for (int a = 0; a < ARMOR_COUNT && !merged; a++) { + Slot armorSlot = slots.get(ARMOR_START + a); + if (armorSlot.mayPlace(stack) && !armorSlot.hasItem()) { + ItemStack one = stack.copy(); one.setCount(1); + armorSlot.set(one); + stack.shrink(1); + merged = true; + } + } + } + + if (!merged && AEItems.SPEED_CARD.is(stack)) { + merged = moveItemStackTo(stack, UPGRADE_START, UPGRADE_END, false); + } + + if (!merged) { + if (index < 27) merged = moveItemStackTo(stack, 27, PLAYER_END, false); + else merged = moveItemStackTo(stack, 0, 27, false); + } + if (!merged) return ItemStack.EMPTY; + + } else { + // 机器槽 → 玩家背包 + if (!moveItemStackTo(stack, 0, PLAYER_END, true)) return ItemStack.EMPTY; + } + + if (stack.isEmpty()) slot.set(ItemStack.EMPTY); + else slot.setChanged(); + + return result; + } + + @Override public boolean stillValid(Player player) { return true; } +} diff --git a/src/main/java/thaumicenergistics/common/container/ContainerArcaneCraftingTerminal.java b/src/main/java/thaumicenergistics/common/container/ContainerArcaneCraftingTerminal.java new file mode 100644 index 0000000..7b289eb --- /dev/null +++ b/src/main/java/thaumicenergistics/common/container/ContainerArcaneCraftingTerminal.java @@ -0,0 +1,393 @@ +package thaumicenergistics.common.container; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.Container; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.CraftingInput; +import net.minecraft.world.item.crafting.RecipeType; + +import appeng.api.inventories.ISegmentedInventory; +import appeng.api.inventories.InternalInventory; +import appeng.api.networking.energy.IEnergySource; +import appeng.api.stacks.AEItemKey; +import appeng.api.storage.ITerminalHost; +import appeng.helpers.ICraftingGridMenu; +import appeng.menu.SlotSemantics; +import appeng.menu.guisync.GuiSync; +import appeng.menu.me.common.MEStorageMenu; +import appeng.menu.me.crafting.CraftConfirmMenu; +import appeng.menu.slot.AppEngSlot; +import appeng.menu.slot.CraftingMatrixSlot; +import appeng.me.storage.LinkStatusRespectingInventory; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; +import net.minecraft.world.item.crafting.Ingredient; +import thaumcraft.common.items.TCFunctionalItems; +import thaumcraft.common.lib.crafting.ThaumcraftCraftingManager; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.common.container.slot.ArcaneCraftingResultSlot; +import thaumicenergistics.common.parts.ArcaneCraftingTerminalPart; +import thaumicenergistics.init.ModMenuTypes; + +public class ContainerArcaneCraftingTerminal extends MEStorageMenu implements ICraftingGridMenu { + + @GuiSync(20) + public String requiredAspectsData = ""; + + @GuiSync(21) + public boolean hasValidRecipe = false; + + /** + * 防止 onTake 期间 slotsChanged 的中间态干扰配方检测。 + * 在 ArcaneCraftingResultSlot.onTake 开始前设为 true,完成后设为 false。 + */ + private boolean isCraftingResultBeingTaken = false; + + private final ISegmentedInventory craftingInventoryHost; + private final CraftingMatrixSlot[] craftingSlots = new CraftingMatrixSlot[9]; + private final ArcaneCraftingResultSlot resultSlot; + + public ContainerArcaneCraftingTerminal(int id, Inventory ip, ITerminalHost host) { + this(ModMenuTypes.ARCANE_CRAFTING_TERMINAL.get(), id, ip, host, true); + } + + public ContainerArcaneCraftingTerminal(MenuType menuType, int id, Inventory ip, ITerminalHost host, + boolean bindInventory) { + super(menuType, id, ip, host, bindInventory); + this.craftingInventoryHost = (ISegmentedInventory) host; + + var craftingGridInv = this.craftingInventoryHost.getSubInventory(ArcaneCraftingTerminalPart.INV_CRAFTING); + + for (int i = 0; i < 9; i++) { + this.craftingSlots[i] = new CraftingMatrixSlot(this, craftingGridInv, i); + this.addSlot(this.craftingSlots[i], SlotSemantics.CRAFTING_GRID); + } + + var linkStatusInventory = new LinkStatusRespectingInventory(host.getInventory(), this::getLinkStatus); + this.resultSlot = new ArcaneCraftingResultSlot(getPlayerInventory().player, craftingGridInv); + this.resultSlot.setRefreshCallback(() -> updateCurrentRecipeAndOutput(false)); + this.resultSlot.setContainer(this); + this.addSlot(this.resultSlot, SlotSemantics.CRAFTING_RESULT); + + var wandInv = this.craftingInventoryHost.getSubInventory(ArcaneCraftingTerminalPart.INV_WAND); + this.addSlot(new AppEngSlot(wandInv, ArcaneCraftingTerminalPart.WAND_SLOT_INDEX) { + @Override + public int getMaxStackSize() { + return 1; + } + + @Override + public void setChanged() { + super.setChanged(); + // 法杖槽变化时立即重检配方,更新 resultSlot 的 wandStack + updateCurrentRecipeAndOutput(false); + } + }, SlotSemantics.STORAGE); + + updateCurrentRecipeAndOutput(true); + } + + // ========== ICraftingGridMenu 实现 ========== + + @Override + public InternalInventory getCraftingMatrix() { + var inv = this.craftingInventoryHost.getSubInventory(ArcaneCraftingTerminalPart.INV_CRAFTING); + ThaumicEnergistics.LOG.debug("[ICraftingGrid] getCraftingMatrix called, size={}", inv.size()); + return inv; + } + + @Override + public void startAutoCrafting(List toCraft) { + CraftConfirmMenu.openWithCraftingList(getActionHost(), (ServerPlayer) getPlayer(), getLocator(), toCraft); + } + + @Override + public IEnergySource getEnergySource() { + return this.energySource; + } + + // ========== 配方检测 ========== + + @Override + public void slotsChanged(Container inventory) { + ThaumicEnergistics.LOG.debug("[A] slotsChanged fired, beingTaken={}, inventoryClass={}", + isCraftingResultBeingTaken, inventory.getClass().getSimpleName()); + if (!isCraftingResultBeingTaken) { + updateCurrentRecipeAndOutput(false); + } else { + ThaumicEnergistics.LOG.debug("[A] slotsChanged SKIPPED (beingTaken=true)"); + } + } + + public void setCraftingResultBeingTaken(boolean beingTaken) { + ThaumicEnergistics.LOG.debug("[A] setCraftingResultBeingTaken={}", beingTaken); + this.isCraftingResultBeingTaken = beingTaken; + } + + private static final int CENTIVIS = 100; + + private boolean hasEnoughVis(AspectList cost) { + ThaumicEnergistics.LOG.debug("[V] hasEnoughVis: cost={}", cost); + if (cost == null || cost.isEmpty()) { + ThaumicEnergistics.LOG.debug("[V] no cost, no wand needed"); + return true; + } + var wandInv = this.craftingInventoryHost.getSubInventory(ArcaneCraftingTerminalPart.INV_WAND); + var wandStack = wandInv.getStackInSlot(0); + ThaumicEnergistics.LOG.debug("[V] wandStack={}", wandStack); + if (wandStack.isEmpty()) { + ThaumicEnergistics.LOG.debug("[V] wandStack EMPTY"); + return false; + } + if (!(wandStack.getItem() instanceof TCFunctionalItems.WandCastingItem wand)) { + ThaumicEnergistics.LOG.debug("[V] not a WandCastingItem"); + return false; + } + var centivisCost = new AspectList(); + for (var aspect : cost.aspects()) { + centivisCost.add(aspect, cost.amount(aspect) * CENTIVIS); + } + boolean result = wand.consumeVisCost(wandStack, getPlayerInventory().player, centivisCost, false, true); + ThaumicEnergistics.LOG.debug("[V] consumeVisCost result={}", result); + return result; + } + + private void updateCurrentRecipeAndOutput(boolean forceUpdate) { + ThaumicEnergistics.LOG.debug("[R] === updateCurrentRecipeAndOutput forceUpdate={} ===", forceUpdate); + var player = getPlayerInventory().player; + var level = player.level(); + + boolean foundArcane = false; + AspectList requiredAspects = null; + + if (level.getServer() != null) { + var craftContainer = this.craftingInventoryHost.getSubInventory(ArcaneCraftingTerminalPart.INV_CRAFTING).toContainer(); + + ItemStack arcaneResult = ThaumcraftCraftingManager.findMatchingArcaneRecipe(craftContainer, player); + ThaumicEnergistics.LOG.debug("[R] findMatchingArcaneRecipe result={}", arcaneResult); + + if (!arcaneResult.isEmpty()) { + requiredAspects = ThaumcraftCraftingManager.findMatchingArcaneRecipeAspects(craftContainer, player); + ThaumicEnergistics.LOG.debug("[R] ARCANE MATCH! aspects={}, result={}", requiredAspects, arcaneResult); + foundArcane = true; + + if (hasEnoughVis(requiredAspects)) { + ThaumicEnergistics.LOG.debug("[R] Vis OK → showing result"); + resultSlot.setDisplayedCraftingOutput(arcaneResult); + } else { + ThaumicEnergistics.LOG.debug("[R] Vis INSUFFICIENT → result empty, but recipe recognized"); + resultSlot.setDisplayedCraftingOutput(ItemStack.EMPTY); + } + } else { + ThaumicEnergistics.LOG.debug("[R] No arcane recipe match"); + } + } + + if (!foundArcane) { + ThaumicEnergistics.LOG.debug("[R] No arcane match, trying vanilla..."); + var testItems = new ArrayList(this.craftingSlots.length); + for (var craftingSlot : this.craftingSlots) { + testItems.add(craftingSlot.getItem().copy()); + } + var testInput = CraftingInput.of(3, 3, testItems); + var recipeHolder = level.getRecipeManager().getRecipeFor(RecipeType.CRAFTING, testInput, level); + if (recipeHolder.isPresent()) { + ItemStack result = recipeHolder.get().value().assemble(testInput, level.registryAccess()); + ThaumicEnergistics.LOG.debug("[R] Vanilla match: {}, setting result slot", result); + resultSlot.setDisplayedCraftingOutput(result); + } else { + ThaumicEnergistics.LOG.debug("[R] No vanilla match either, clearing result slot"); + // 客户端不清空产物槽,@GuiSync 会同步服务端的正确状态 + if (!level.isClientSide()) { + resultSlot.setDisplayedCraftingOutput(ItemStack.EMPTY); + } + } + } + + if (foundArcane) { + // 服务端设置 @GuiSync 字段;客户端不应覆盖来自服务端的同步值 + ThaumicEnergistics.LOG.debug("[R] foundArcane branch: isClientSide={}", level.isClientSide()); + if (level.isClientSide()) { + ThaumicEnergistics.LOG.debug("[R] Client: keeping server-synced values, not overriding"); + return; + } + this.hasValidRecipe = true; + resultSlot.setRequiredAspects(requiredAspects); + var wandInv = this.craftingInventoryHost.getSubInventory(ArcaneCraftingTerminalPart.INV_WAND); + var ws = wandInv.getStackInSlot(0); + resultSlot.setWandStack(ws); + ThaumicEnergistics.LOG.debug("[R] SET state: hasValidRecipe=true, wandStack={}", ws); + + if (requiredAspects != null && requiredAspects.size() > 0) { + StringBuilder sb = new StringBuilder(); + for (Map.Entry entry : requiredAspects.aspects.entrySet()) { + if (!sb.isEmpty()) sb.append(","); + sb.append(entry.getKey().getTag()).append("=").append(entry.getValue()); + } + this.requiredAspectsData = sb.toString(); + ThaumicEnergistics.LOG.debug("[R] aspectsData={}", this.requiredAspectsData); + } else { + this.requiredAspectsData = ""; + ThaumicEnergistics.LOG.debug("[R] aspectsData=empty (no aspects)"); + } + } else { + ThaumicEnergistics.LOG.debug("[R] else branch: isClientSide={}, levelClass={}", + level.isClientSide(), level.getClass().getSimpleName()); + if (level.isClientSide()) { + ThaumicEnergistics.LOG.debug("[R] Client: not overriding synced values (no arcane recipe on client)"); + return; + } + this.requiredAspectsData = ""; + this.hasValidRecipe = false; + resultSlot.setRequiredAspects(null); + resultSlot.setWandStack(ItemStack.EMPTY); + ThaumicEnergistics.LOG.debug("[R] SET state: hasValidRecipe=false (no arcane recipe)"); + } + } + + public Map getParsedAspects() { + Map map = new LinkedHashMap<>(); + if (requiredAspectsData.isEmpty()) return map; + for (String part : requiredAspectsData.split(",")) { + String[] kv = part.split("="); + if (kv.length == 2) { + try { + map.put(kv[0], Integer.parseInt(kv[1])); + } catch (NumberFormatException ignored) { + } + } + } + return map; + } + + // ========== JEI 配方转移支持 ========== + + /** + * 确定给定 slot→ingredient 映射中哪些槽位无法从 ME 网络或玩家背包填充。 + * 移植自 CraftingTermMenu.findMissingIngredients。 + */ + public MissingIngredientSlots findMissingIngredients(Map ingredients) { + Set missingSlots = new HashSet<>(); + Set craftableSlots = new HashSet<>(); + + var reservedGridAmounts = new Object2IntOpenHashMap(); + var playerItems = getPlayerInventory().items; + var reservedPlayerItems = new int[playerItems.size()]; + + for (var entry : ingredients.entrySet()) { + var ingredient = entry.getValue(); + boolean found = false; + + for (int i = 0; i < playerItems.size(); i++) { + if (isPlayerInventorySlotLocked(i)) continue; + var stack = playerItems.get(i); + if (stack.getCount() - reservedPlayerItems[i] > 0 && ingredient.test(stack)) { + reservedPlayerItems[i]++; + found = true; + break; + } + } + + if (!found) { + if (hasIngredient(ingredient, reservedGridAmounts)) { + reservedGridAmounts.merge(ingredient, 1, Integer::sum); + found = true; + } + } + + if (!found) { + for (var stack : ingredient.getItems()) { + if (isCraftable(stack)) { + craftableSlots.add(entry.getKey()); + found = true; + break; + } + } + } + + if (!found) { + missingSlots.add(entry.getKey()); + } + } + + return new MissingIngredientSlots(missingSlots, craftableSlots); + } + + /** + * 检查 ME 网络中是否有指定材料的库存(含已预留量)。 + * 直接遍历 clientRepo 条目匹配 ingredient,确保不受 linkStatus 时序或 getByIngredient 实现细节影响。 + */ + public boolean hasIngredient(Ingredient ingredient, Object2IntOpenHashMap reservedAmounts) { + for (var slot : getSlots(SlotSemantics.CRAFTING_GRID)) { + var stackInSlot = slot.getItem(); + if (!stackInSlot.isEmpty() && ingredient.test(stackInSlot)) { + var reservedAmount = reservedAmounts.getOrDefault(slot, 0); + if (stackInSlot.getCount() > reservedAmount) { + reservedAmounts.merge(slot, 1, Integer::sum); + return true; + } + } + } + // 直接遍历 clientRepo 检查 ME 网络仓库 + var clientRepo = getClientRepo(); + if (clientRepo != null) { + for (var entry : clientRepo.getAllEntries()) { + if (!(entry.getWhat() instanceof AEItemKey itemKey)) continue; + if (entry.getStoredAmount() <= 0) continue; + if (!ingredient.test(itemKey.toStack())) continue; + var reservedAmount = reservedAmounts.getOrDefault(entry, 0); + if (entry.getStoredAmount() - reservedAmount >= 1) { + reservedAmounts.merge(entry, 1, Integer::sum); + return true; + } + } + } + return false; + } + + /** + * 检查物品是否可在 ME 网络中自动合成。 + * 移植自 CraftingTermMenu.isCraftable。 + */ + private boolean isCraftable(ItemStack itemStack) { + var clientRepo = getClientRepo(); + if (clientRepo != null) { + for (var stack : clientRepo.getAllEntries()) { + if (AEItemKey.matches(stack.getWhat(), itemStack) && stack.isCraftable()) { + return true; + } + } + } + return false; + } + + public record MissingIngredientSlots(Set missingSlots, Set craftableSlots) { + public int totalSize() { + return missingSlots.size() + craftableSlots.size(); + } + + public boolean anyMissingOrCraftable() { + return anyMissing() || anyCraftable(); + } + + public boolean anyMissing() { + return !missingSlots.isEmpty(); + } + + public boolean anyCraftable() { + return !craftableSlots.isEmpty(); + } + } +} diff --git a/src/main/java/thaumicenergistics/common/container/ContainerDistillationPatternEncoder.java b/src/main/java/thaumicenergistics/common/container/ContainerDistillationPatternEncoder.java new file mode 100644 index 0000000..7728efe --- /dev/null +++ b/src/main/java/thaumicenergistics/common/container/ContainerDistillationPatternEncoder.java @@ -0,0 +1,357 @@ +package thaumicenergistics.common.container; + +import appeng.api.crafting.PatternDetailsHelper; +import appeng.api.stacks.AEItemKey; +import appeng.api.stacks.GenericStack; +import appeng.core.definitions.AEItems; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.ClickType; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; +import net.neoforged.neoforge.items.ItemStackHandler; +import net.neoforged.neoforge.items.SlotItemHandler; +import thaumcraft.api.ThaumcraftApiHelper; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; +import thaumcraft.common.research.ThaumometerScanManager; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.common.integration.appeng.AEssentiaKey; +import thaumicenergistics.common.integration.tc.TCReflection; +import thaumicenergistics.common.tiles.TileDistillationPatternEncoder; +import thaumicenergistics.init.ModMenuTypes; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; + +public class ContainerDistillationPatternEncoder extends AbstractContainerMenu { + + private static final int PLAYER_INV_Y = 152; + private static final int HOTBAR_Y = 210; + private static final int PLAYER_INV_X = 8; + + private static final int SLOT_SOURCE_X = 15; + private static final int SLOT_SOURCE_Y = 69; + + private static final int SLOT_ASPECTS_X = 65; + private static final int SLOT_ASPECTS_Y = 24; + private static final int SLOT_ASPECTS_COUNT = 6; + + private static final int SLOT_SELECTED_X = 116; + private static final int SLOT_SELECTED_Y = 69; + + private static final int SLOT_BLANK_X = 146; + private static final int SLOT_BLANK_Y = 75; + + private static final int SLOT_ENCODED_X = 146; + private static final int SLOT_ENCODED_Y = 113; + + private static final int PLAYER_SLOTS = 36; + private static final int ASPECT_SLOT_START = 36; + private static final int SELECTED_SLOT = 42; + private static final int SOURCE_SLOT = 43; + private static final int BLANK_SLOT = 44; + private static final int ENCODED_SLOT = 45; + + private final TileDistillationPatternEncoder encoder; + private final Inventory playerInv; + + private final ItemStackHandler aspectInventory = new ItemStackHandler(SLOT_ASPECTS_COUNT + 1); + + private Aspect[] cachedAspects = new Aspect[0]; + private int selectedAspectIndex = -1; + + /** 上次解析的源物品,用于判定是否需要重新解析 aspects(避免每帧调用 getObjectAspects)。 */ + private ItemStack lastSourceItem = ItemStack.EMPTY; + + public ContainerDistillationPatternEncoder(int id, Inventory inv) { + this(id, inv, (TileDistillationPatternEncoder) null); + } + + public ContainerDistillationPatternEncoder(int id, Inventory inv, RegistryFriendlyByteBuf buf) { + this(id, inv, (TileDistillationPatternEncoder) null); + } + + public ContainerDistillationPatternEncoder(int id, Inventory inv, TileDistillationPatternEncoder encoder) { + super(ModMenuTypes.DISTILLATION_ENCODER.get(), id); + this.encoder = encoder; + this.playerInv = inv; + + for (int r = 0; r < 3; r++) + for (int c = 0; c < 9; c++) + addSlot(new Slot(inv, c + r * 9 + 9, PLAYER_INV_X + c * 18, PLAYER_INV_Y + r * 18)); + for (int c = 0; c < 9; c++) + addSlot(new Slot(inv, c, PLAYER_INV_X + c * 18, HOTBAR_Y)); + + for (int i = 0; i < SLOT_ASPECTS_COUNT; i++) { + int y = SLOT_ASPECTS_Y + i * 18; + addSlot(new SlotItemHandler(aspectInventory, i, SLOT_ASPECTS_X, y) { + @Override + public boolean mayPlace(ItemStack s) { return false; } + @Override + public boolean mayPickup(Player p) { return false; } + }); + } + + addSlot(new SlotItemHandler(aspectInventory, SLOT_ASPECTS_COUNT, SLOT_SELECTED_X, SLOT_SELECTED_Y) { + @Override + public boolean mayPlace(ItemStack s) { return false; } + @Override + public boolean mayPickup(Player p) { return false; } + }); + + if (encoder != null) { + // 源物品槽:绑定 Tile 槽 0(持久化到方块 NBT,关闭 GUI 不丢失) + addSlot(new SlotItemHandler(encoder.inventory, TileDistillationPatternEncoder.SLOT_SOURCE_ITEM, SLOT_SOURCE_X, SLOT_SOURCE_Y) { + @Override + public int getMaxStackSize() { return 1; } + }); + addSlot(new SlotItemHandler(encoder.inventory, TileDistillationPatternEncoder.SLOT_BLANK_PATTERNS, SLOT_BLANK_X, SLOT_BLANK_Y) { + @Override + public boolean mayPlace(ItemStack s) { return true; } + @Override + public int getMaxStackSize() { return 64; } + }); + addSlot(new SlotItemHandler(encoder.inventory, TileDistillationPatternEncoder.SLOT_ENCODED_PATTERN, SLOT_ENCODED_X, SLOT_ENCODED_Y) { + @Override + public boolean mayPlace(ItemStack s) { return false; } + }); + } else { + // 客户端兜底:三个槽各自独立(避免共享槽导致放入互相覆盖) + ItemStackHandler dummy = new ItemStackHandler(3); + addSlot(new SlotItemHandler(dummy, TileDistillationPatternEncoder.SLOT_SOURCE_ITEM, SLOT_SOURCE_X, SLOT_SOURCE_Y) { + @Override + public int getMaxStackSize() { return 1; } + }); + addSlot(new SlotItemHandler(dummy, TileDistillationPatternEncoder.SLOT_BLANK_PATTERNS, SLOT_BLANK_X, SLOT_BLANK_Y) { + @Override + public boolean mayPlace(ItemStack s) { return true; } + @Override + public int getMaxStackSize() { return 64; } + }); + addSlot(new SlotItemHandler(dummy, TileDistillationPatternEncoder.SLOT_ENCODED_PATTERN, SLOT_ENCODED_X, SLOT_ENCODED_Y) { + @Override + public boolean mayPlace(ItemStack s) { return false; } + }); + } + } + + /** 源物品槽内容。服务端从 Tile 槽 0 读(权威);客户端从槽同步内容读(encoder 为 null)。 */ + public ItemStack getSourceItem() { + if (encoder != null) { + return encoder.inventory.getStackInSlot(TileDistillationPatternEncoder.SLOT_SOURCE_ITEM); + } + if (SOURCE_SLOT >= 0 && SOURCE_SLOT < slots.size()) { + return slots.get(SOURCE_SLOT).getItem(); + } + return ItemStack.EMPTY; + } + + /** + * 源物品的 aspects:源物品变化(含 NBT/扫描数据)时才调用 {@code getObjectAspects} 重新解析, + * 否则返回缓存——每帧渲染调用仅做 O(1) 物品比较,不频繁请求 TC。 + */ + public Aspect[] getSourceAspects() { + ItemStack source = getSourceItem(); + if (!ItemStack.isSameItemSameComponents(source, lastSourceItem)) { + lastSourceItem = source.copy(); + if (source.isEmpty()) { + cachedAspects = new Aspect[0]; + if (selectedAspectIndex != -1) selectedAspectIndex = -1; + } else { + // 玩家必须已用魔导透镜扫描过"该物品"才显示其要素(等价 1.7.10 ScanManager 物品 hash 检查; + // 不能只看 hasDiscoveredAspect——玩家可能已发现全部要素但未扫描此物品) + if (!ThaumometerScanManager.hasBeenScanned(playerInv.player, source)) { + cachedAspects = new Aspect[0]; + } else { + AspectList aspects = ThaumcraftApiHelper.getObjectAspects(source); + if (aspects == null || aspects.size() == 0) { + cachedAspects = new Aspect[0]; + } else { + // 排序保证客户端/服务端解析顺序一致(GUI 第 X 格 = 编码输出的第 X 个要素) + Aspect[] arr = aspects.getAspects(); + Arrays.sort(arr, Comparator.comparing(a -> a.getTag() == null ? "" : a.getTag())); + cachedAspects = arr; + } + } + if (selectedAspectIndex >= cachedAspects.length) selectedAspectIndex = -1; + } + } + return cachedAspects; + } + + private void updateAspects() { + // 统一走缓存解析逻辑 + getSourceAspects(); + // aspect 槽只读显示,图标由 GUI 绘制(保持槽空) + for (int i = 0; i < SLOT_ASPECTS_COUNT; i++) { + aspectInventory.setStackInSlot(i, ItemStack.EMPTY); + } + } + + private void clearAspectSlots() { + for (int i = 0; i <= SLOT_ASPECTS_COUNT; i++) { + aspectInventory.setStackInSlot(i, ItemStack.EMPTY); + } + selectedAspectIndex = -1; + } + + public Aspect[] getCachedAspects() { + return cachedAspects; + } + + public int getSelectedAspectIndex() { + return selectedAspectIndex; + } + + public Aspect getSelectedAspect() { + if (selectedAspectIndex >= 0 && selectedAspectIndex < cachedAspects.length) { + return cachedAspects[selectedAspectIndex]; + } + return null; + } + + /** + * Encode 按钮可用的条件:源物品已配置 + 已选要素 + 空白样板槽有样板 + 成品槽为空。 + * 服务端从 Tile 读(权威);客户端 encoder 为 null,从同步的槽内容判断。 + */ + public boolean canEncode() { + if (getSelectedAspect() == null) return false; + if (getSourceItem().isEmpty()) return false; + if (encoder != null) { + if (encoder.inventory.getStackInSlot(TileDistillationPatternEncoder.SLOT_BLANK_PATTERNS).isEmpty()) return false; + return encoder.inventory.getStackInSlot(TileDistillationPatternEncoder.SLOT_ENCODED_PATTERN).isEmpty(); + } + if (BLANK_SLOT < 0 || BLANK_SLOT >= slots.size() || slots.get(BLANK_SLOT).getItem().isEmpty()) return false; + return ENCODED_SLOT >= 0 && ENCODED_SLOT < slots.size() && slots.get(ENCODED_SLOT).getItem().isEmpty(); + } + + public void onEncodePattern() { + if (encoder == null) return; + Aspect selected = getSelectedAspect(); + ItemStack source = getSourceItem(); + ItemStack blankSlot = encoder.inventory.getStackInSlot(TileDistillationPatternEncoder.SLOT_BLANK_PATTERNS); + ItemStack encodedSlot = encoder.inventory.getStackInSlot(TileDistillationPatternEncoder.SLOT_ENCODED_PATTERN); + ThaumicEnergistics.LOG.info("[DE] onEncodePattern: selected={}, selIdx={}, aspects={}, source={}, blank={}isBlank={}, encoded={}", + selected == null ? "null" : selected.getTag(), selectedAspectIndex, + getSourceAspects().length, + source.isEmpty() ? "EMPTY" : source.getItem().getDescriptionId(), + blankSlot.isEmpty() ? "EMPTY" : blankSlot.getItem().getDescriptionId(), + AEItems.BLANK_PATTERN.is(blankSlot), + encodedSlot.isEmpty() ? "EMPTY" : encodedSlot.getItem().getDescriptionId()); + + if (selected == null) return; + + if (source.isEmpty()) return; + + if (blankSlot.isEmpty()) return; + + // 验证必须是 AE2 空白样板,否则不消耗不编码(日志定位 is() 运行时行为) + if (!AEItems.BLANK_PATTERN.is(blankSlot)) { + ThaumicEnergistics.LOG.warn("[DE] Encode skipped: blank slot item={}, isBlankPattern={}", + blankSlot.getItem().getDescriptionId(), AEItems.BLANK_PATTERN.is(blankSlot)); + return; + } + + if (!encodedSlot.isEmpty()) return; + + blankSlot.shrink(1); + if (blankSlot.isEmpty()) { + encoder.inventory.setStackInSlot(TileDistillationPatternEncoder.SLOT_BLANK_PATTERNS, ItemStack.EMPTY); + } + + AEItemKey sourceKey = AEItemKey.of(source); + GenericStack input = new GenericStack(sourceKey, 1); + + // 蒸馏语义:源物品 → 选中源质,输出数量 = 源物品中该要素的数量(如骨头食欲=2 → 输出食欲×2) + ResourceLocation aspectId = TCReflection.getAspectId(selected); + if (aspectId == null) return; + AspectList objAspects = ThaumcraftApiHelper.getObjectAspects(source); + long amount = (objAspects != null) ? objAspects.getAmount(selected) : 1; + if (amount < 1) amount = 1; + GenericStack output = new GenericStack(AEssentiaKey.of(aspectId), amount); + + ItemStack encoded = PatternDetailsHelper.encodeProcessingPattern( + List.of(input), + List.of(output) + ); + + encoder.inventory.setStackInSlot(TileDistillationPatternEncoder.SLOT_ENCODED_PATTERN, encoded); + } + + @Override + public void clicked(int slotId, int dragType, ClickType clickType, Player player) { + if (slotId >= 0 && slotId < slots.size()) { + Slot slot = slots.get(slotId); + + if (slotId == SOURCE_SLOT) { + // 标准拖放处理(SlotItemHandler 已限制槽内 1 个),刷新 aspects + super.clicked(slotId, dragType, clickType, player); + updateAspects(); + ThaumicEnergistics.LOG.info("[DE] source slot clicked: item={}, count={}, aspects={}", + getSourceItem().getItem().getDescriptionId(), getSourceItem().getCount(), getSourceAspects().length); + return; + } + + if (slotId >= ASPECT_SLOT_START && slotId < ASPECT_SLOT_START + SLOT_ASPECTS_COUNT) { + int aspectIdx = slotId - ASPECT_SLOT_START; + // 始终记录用户选择(越界由 getSelectedAspect 校验),避免因 cachedAspects 状态导致服务端选择丢失 + selectedAspectIndex = aspectIdx; + ThaumicEnergistics.LOG.info("[DE] aspect clicked: idx={}, cached={}, selected={}", + aspectIdx, cachedAspects.length, selectedAspectIndex); + // selected 槽留空,图标由 GUI 绘制 + aspectInventory.setStackInSlot(SELECTED_SLOT - ASPECT_SLOT_START, ItemStack.EMPTY); + return; + } + } + super.clicked(slotId, dragType, clickType, player); + } + + @Override + public boolean clickMenuButton(Player player, int id) { + if (id == 0) { + onEncodePattern(); + return true; + } + return false; + } + + @Override + public ItemStack quickMoveStack(Player player, int idx) { + Slot slot = slots.get(idx); + if (!slot.hasItem()) return ItemStack.EMPTY; + + ItemStack stack = slot.getItem(); + ItemStack copy = stack.copy(); + + if (idx < PLAYER_SLOTS) { + // 空白样板/其他物品 shift → 尝试放入 blank 槽(mayPlace 已放宽,Encode 时验证) + if (!moveItemStackTo(stack, BLANK_SLOT, BLANK_SLOT + 1, false)) return ItemStack.EMPTY; + } else if (idx == BLANK_SLOT || idx == ENCODED_SLOT) { + if (!moveItemStackTo(stack, 0, PLAYER_SLOTS, false)) return ItemStack.EMPTY; + } else { + return ItemStack.EMPTY; + } + + if (stack.isEmpty()) slot.set(ItemStack.EMPTY); + else slot.setChanged(); + + return copy; + } + + @Override + public boolean stillValid(Player player) { + return true; + } + + @Override + public void removed(Player player) { + super.removed(player); + if (encoder != null && !encoder.getLevel().isClientSide) { + encoder.setChanged(); + } + } +} diff --git a/src/main/java/thaumicenergistics/common/container/ContainerEssentiaCellTerminal.java b/src/main/java/thaumicenergistics/common/container/ContainerEssentiaCellTerminal.java new file mode 100644 index 0000000..9a326d0 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/container/ContainerEssentiaCellTerminal.java @@ -0,0 +1,20 @@ +package thaumicenergistics.common.container; + +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.world.entity.player.Inventory; +import net.neoforged.neoforge.items.ItemStackHandler; +import net.neoforged.neoforge.items.SlotItemHandler; +import thaumicenergistics.init.ModMenuTypes; + +/** 源质元件终端的容器。基于网格的源质视图 + 元件槽。 */ +public class ContainerEssentiaCellTerminal extends ThEContainerBase { + final ItemStackHandler cellSlot = new ItemStackHandler(1); + final ItemStackHandler viewSlot = new ItemStackHandler(1); + + public ContainerEssentiaCellTerminal(int id, Inventory inv) { + super(ModMenuTypes.ESSENTIA_TERMINAL.get(), id, inv, 2); + addSlot(new SlotItemHandler(cellSlot, 0, 26, 16)); + addSlot(new SlotItemHandler(viewSlot, 0, 134, 16)); + } + public ContainerEssentiaCellTerminal(int id, Inventory inv, RegistryFriendlyByteBuf buf) { this(id, inv); } +} diff --git a/src/main/java/thaumicenergistics/common/container/ContainerEssentiaCellWorkbench.java b/src/main/java/thaumicenergistics/common/container/ContainerEssentiaCellWorkbench.java new file mode 100644 index 0000000..ba4267e --- /dev/null +++ b/src/main/java/thaumicenergistics/common/container/ContainerEssentiaCellWorkbench.java @@ -0,0 +1,159 @@ +package thaumicenergistics.common.container; + +import java.util.List; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; +import net.neoforged.neoforge.items.IItemHandler; +import net.neoforged.neoforge.items.ItemStackHandler; +import net.neoforged.neoforge.items.SlotItemHandler; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; +import thaumcraft.api.aspects.IEssentiaContainerItem; +import thaumicenergistics.common.integration.tc.TCReflection; +import thaumicenergistics.common.items.ItemEssentiaCell; +import thaumicenergistics.common.tiles.TileEssentiaCellWorkbench; +import thaumicenergistics.init.ModMenuTypes; + +/** + * 源质元件工作台容器:cell 槽绑定到方块实体(持久化),并提供分区编辑操作。 + * 对应 1.7.10 的 {@code ContainerEssentiaCellWorkbench},分区数据存储在 cell 的 AE2 CellConfig 上。 + */ +public class ContainerEssentiaCellWorkbench extends AbstractContainerMenu { + + /** cell 槽编号。 */ + public static final int SLOT_CELL = 0; + /** 玩家背包起始编号(1..27 背包,28..36 热栏)。 */ + private static final int PLAYER_INV_START = 1; + private static final int PLAYER_INV_END = 28; + private static final int HOTBAR_START = 28; + private static final int HOTBAR_END = 37; + + private final TileEssentiaCellWorkbench workbench; + + /** 兜底用空库存(workbench 为 null 时)。 */ + private final IItemHandler fallbackCell = new ItemStackHandler(1); + + public ContainerEssentiaCellWorkbench(int id, Inventory inv) { + this(id, inv, (TileEssentiaCellWorkbench) null); + } + + public ContainerEssentiaCellWorkbench(int id, Inventory inv, TileEssentiaCellWorkbench workbench) { + super(ModMenuTypes.ESSENTIA_CELL_WORKBENCH.get(), id); + this.workbench = workbench; + + IItemHandler cellHandler = workbench != null ? workbench.getCellInventory() : fallbackCell; + addSlot(new SlotItemHandler(cellHandler, 0, 152, 8)); + for (int r = 0; r < 3; r++) for (int c = 0; c < 9; c++) addSlot(new Slot(inv, c + r * 9 + 9, 8 + c * 18, 169 + r * 18)); + for (int c = 0; c < 9; c++) addSlot(new Slot(inv, c, 8 + c * 18, 227)); + } + + /** 客户端打开菜单用(IMenuTypeExtension 注册);workbench 为 null,分区操作走 C2S 到服务端。 */ + public ContainerEssentiaCellWorkbench(int id, Inventory inv, net.minecraft.network.RegistryFriendlyByteBuf buf) { + this(id, inv); + } + + // ===== 分区操作(由 GUI / 网络调用,服务端执行) ===== + + public boolean hasCell() { + return workbench != null && workbench.hasCell(); + } + + public List getPartitionAspects() { + if (workbench == null || !workbench.hasCell()) return List.of(); + return ItemEssentiaCell.getPartitionAspects(workbench.getCell()); + } + + public boolean addAspectToPartition(ResourceLocation aspectId) { + if (workbench == null || !workbench.hasCell()) return false; + boolean changed = ItemEssentiaCell.addAspectToPartition(workbench.getCell(), aspectId); + if (changed) workbench.setChanged(); + return changed; + } + + public boolean removeAspectFromPartition(ResourceLocation aspectId) { + if (workbench == null || !workbench.hasCell()) return false; + boolean changed = ItemEssentiaCell.removeAspectFromPartition(workbench.getCell(), aspectId); + if (changed) workbench.setChanged(); + return changed; + } + + public boolean replaceAspectInPartition(ResourceLocation from, ResourceLocation to) { + if (workbench == null || !workbench.hasCell()) return false; + boolean changed = ItemEssentiaCell.replaceAspectInPartition(workbench.getCell(), from, to); + if (changed) workbench.setChanged(); + return changed; + } + + public void clearPartitioning() { + if (workbench == null || !workbench.hasCell()) return; + ItemEssentiaCell.clearPartitioning(workbench.getCell()); + workbench.setChanged(); + } + + public void partitionToContents() { + if (workbench == null || !workbench.hasCell()) return; + ItemEssentiaCell.partitionToContents(workbench.getCell()); + workbench.setChanged(); + } + + /** + * 从物品中提取第一个源质方面(罐子/法杖等 IEssentiaContainerItem)。 + */ + public static ResourceLocation getAspectFromItem(ItemStack stack) { + if (stack == null || stack.isEmpty()) return null; + if (stack.getItem() instanceof IEssentiaContainerItem containerItem) { + AspectList aspects = containerItem.getAspects(stack); + if (aspects != null && aspects.size() > 0) { + Aspect first = aspects.getAspects()[0]; + if (first != null) return TCReflection.getAspectId(first); + } + } + return null; + } + + // ===== 快捷移动 / 生命周期 ===== + + @Override + public ItemStack quickMoveStack(Player player, int idx) { + if (workbench == null || idx < 0 || idx >= slots.size()) return ItemStack.EMPTY; + Slot slot = slots.get(idx); + if (!slot.hasItem()) return ItemStack.EMPTY; + + ItemStack stack = slot.getItem(); + ItemStack original = stack.copy(); + + if (idx == SLOT_CELL) { + // cell 槽 → 玩家背包 + if (!moveItemStackTo(stack, PLAYER_INV_START, HOTBAR_END, true)) return ItemStack.EMPTY; + } else if (idx < HOTBAR_END) { + // 玩家背包 → cell 槽(仅当 cell 槽空且物品是源质元件) + if (stack.getItem() instanceof ItemEssentiaCell && workbench.getCell().isEmpty()) { + if (!moveItemStackTo(stack, SLOT_CELL, SLOT_CELL + 1, false)) return ItemStack.EMPTY; + } else { + // 含源质物品 → 尝试添加分区(物品不消费,仅添加分区) + ResourceLocation aspectId = getAspectFromItem(stack); + if (aspectId != null && addAspectToPartition(aspectId)) { + return original; // 物品留在原槽 + } + return ItemStack.EMPTY; + } + } + + if (stack.isEmpty()) { + slot.set(ItemStack.EMPTY); + } else { + slot.setChanged(); + } + return original; + } + + @Override + public boolean stillValid(Player player) { + return workbench == null || workbench.hasLevel() && player.level().getBlockEntity(workbench.getBlockPos()) == workbench; + } +} diff --git a/src/main/java/thaumicenergistics/common/container/ContainerEssentiaExportBus.java b/src/main/java/thaumicenergistics/common/container/ContainerEssentiaExportBus.java new file mode 100644 index 0000000..a7056fc --- /dev/null +++ b/src/main/java/thaumicenergistics/common/container/ContainerEssentiaExportBus.java @@ -0,0 +1,85 @@ +package thaumicenergistics.common.container; + +import appeng.api.config.Settings; +import appeng.api.stacks.AEKey; +import appeng.api.util.IConfigManager; +import appeng.api.util.KeyTypeSelection; +import appeng.api.util.KeyTypeSelectionHost; +import appeng.menu.SlotSemantics; +import appeng.menu.guisync.GuiSync; +import appeng.menu.implementations.UpgradeableMenu; +import appeng.menu.interfaces.KeyTypeSelectionMenu; +import appeng.menu.interfaces.KeyTypeSelectionMenu.SyncedKeyTypes; +import appeng.menu.slot.FakeSlot; +import thaumicenergistics.common.parts.EssentiaExportBusPart; +import thaumicenergistics.init.ModMenuTypes; + +public class ContainerEssentiaExportBus extends UpgradeableMenu + implements KeyTypeSelectionMenu { + + @GuiSync(50) + public long storedEnergy; + + @GuiSync(51) + public SyncedKeyTypes exportKeyTypes = new SyncedKeyTypes(); + + public ContainerEssentiaExportBus(int id, net.minecraft.world.entity.player.Inventory ip, EssentiaExportBusPart host) { + super(ModMenuTypes.ESSENTIA_EXPORT_BUS.get(), id, ip, host); + registerClientAction("clear", this::clear); + } + + @Override + protected void setupConfig() { + var inv = getHost().getConfig().createMenuWrapper(); + for (int i = 0; i < 18; i++) { + this.addSlot(new FakeSlot(inv, i), SlotSemantics.CONFIG); + } + } + + @Override + public boolean isSlotEnabled(int idx) { + return true; + } + + @Override + protected void loadSettingsFromHost(IConfigManager cm) { + if (cm.hasSetting(Settings.REDSTONE_CONTROLLED)) { + this.setRedStoneMode(cm.getSetting(Settings.REDSTONE_CONTROLLED)); + } + } + + @Override + public void broadcastChanges() { + super.broadcastChanges(); + if (!isServerSide()) return; + this.storedEnergy = getHost().getStoredEnergy(); + if (getHost() instanceof KeyTypeSelectionHost selectionHost) { + var enabled = selectionHost.getKeyTypeSelection().enabled(); + if (!exportKeyTypes.keyTypes().equals(enabled)) { + exportKeyTypes = new SyncedKeyTypes(enabled); + } + } + } + + public void clear() { + if (isClientSide()) { + sendClientAction("clear"); + } else { + getHost().getConfig().clear(); + } + } + + public AEKey getConfiguredKey(int slot) { + return getHost().getConfig().getKey(slot); + } + + @Override + public KeyTypeSelection getServerKeyTypeSelection() { + return ((KeyTypeSelectionHost) getHost()).getKeyTypeSelection(); + } + + @Override + public SyncedKeyTypes getClientKeyTypeSelection() { + return exportKeyTypes; + } +} diff --git a/src/main/java/thaumicenergistics/common/container/ContainerEssentiaImportBus.java b/src/main/java/thaumicenergistics/common/container/ContainerEssentiaImportBus.java new file mode 100644 index 0000000..cada8e5 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/container/ContainerEssentiaImportBus.java @@ -0,0 +1,57 @@ +package thaumicenergistics.common.container; + +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.inventory.MenuType; + +import appeng.api.util.KeyTypeSelectionHost; +import appeng.core.definitions.AEItems; +import appeng.menu.implementations.UpgradeableMenu; +import appeng.menu.interfaces.KeyTypeSelectionMenu; +import appeng.menu.interfaces.KeyTypeSelectionMenu.SyncedKeyTypes; +import appeng.api.util.KeyTypeSelection; +import thaumicenergistics.common.parts.EssentiaImportBusPart; + +public class ContainerEssentiaImportBus extends UpgradeableMenu + implements KeyTypeSelectionMenu { + + @appeng.menu.guisync.GuiSync(20) + public SyncedKeyTypes importKeyTypes = new SyncedKeyTypes(); + + public ContainerEssentiaImportBus(MenuType menuType, int id, Inventory ip, EssentiaImportBusPart host) { + super(menuType, id, ip, host); + } + + @Override + protected void setupConfig() { + addExpandableConfigSlots(getHost().getConfig(), 2, 9, 5); + } + + @Override + public boolean isSlotEnabled(int idx) { + final int upgrades = getUpgrades().getInstalledUpgrades(AEItems.CAPACITY_CARD); + return upgrades > idx; + } + + @Override + public void broadcastChanges() { + super.broadcastChanges(); + if (isServerSide()) { + if (getHost() instanceof KeyTypeSelectionHost selectionHost) { + var enabled = selectionHost.getKeyTypeSelection().enabled(); + if (!importKeyTypes.keyTypes().equals(enabled)) { + importKeyTypes = new SyncedKeyTypes(enabled); + } + } + } + } + + @Override + public KeyTypeSelection getServerKeyTypeSelection() { + return ((KeyTypeSelectionHost) getHost()).getKeyTypeSelection(); + } + + @Override + public SyncedKeyTypes getClientKeyTypeSelection() { + return importKeyTypes; + } +} diff --git a/src/main/java/thaumicenergistics/common/container/ContainerEssentiaLevelEmitter.java b/src/main/java/thaumicenergistics/common/container/ContainerEssentiaLevelEmitter.java new file mode 100644 index 0000000..66763cb --- /dev/null +++ b/src/main/java/thaumicenergistics/common/container/ContainerEssentiaLevelEmitter.java @@ -0,0 +1,99 @@ +package thaumicenergistics.common.container; + +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.inventory.MenuType; +import appeng.api.config.RedstoneMode; +import appeng.api.config.Settings; +import appeng.api.stacks.AEKey; +import appeng.api.util.IConfigManager; +import appeng.menu.SlotSemantics; +import appeng.menu.guisync.GuiSync; +import appeng.menu.implementations.UpgradeableMenu; +import appeng.menu.slot.FakeSlot; +import thaumcraft.api.aspects.Aspect; +import thaumicenergistics.common.integration.appeng.AEssentiaKey; +import thaumicenergistics.common.parts.EssentiaLevelEmitterPart; + +/** + * 源质发信器 Menu — 与 AE2 原版 StorageLevelEmitterMenu 逻辑一致。 + * 使用 reportingValue 代替 thresholdLevel,与 AbstractLevelEmitterPart 对齐。 + */ +public class ContainerEssentiaLevelEmitter extends UpgradeableMenu { + + private static final String ACTION_SET_REPORTING_VALUE = "setReportingValue"; + + @GuiSync(10) + public long reportingValue; + + @GuiSync(11) + public String trackedAspectId = ""; + + @GuiSync(12) + public long currentLevel; + + public ContainerEssentiaLevelEmitter(MenuType menuType, int id, Inventory ip, EssentiaLevelEmitterPart host) { + super(menuType, id, ip, host); + registerClientAction(ACTION_SET_REPORTING_VALUE, Long.class, this::setReportingValue); + } + + @Override + protected void setupConfig() { + var inv = getHost().getConfig().createMenuWrapper(); + this.addSlot(new FakeSlot(inv, 0), SlotSemantics.CONFIG); + } + + @Override + public boolean isSlotEnabled(int idx) { + return true; + } + + @Override + protected void loadSettingsFromHost(IConfigManager cm) { + if (cm.hasSetting(Settings.REDSTONE_EMITTER)) { + this.setRedStoneMode(cm.getSetting(Settings.REDSTONE_EMITTER)); + } + } + + @Override + public void broadcastChanges() { + super.broadcastChanges(); + if (!isServerSide()) return; + + EssentiaLevelEmitterPart part = getHost(); + + long hostReporting = part.getReportingValue(); + if (this.reportingValue != hostReporting) { + this.reportingValue = hostReporting; + } + + long hostCurrent = part.getCurrentLevel(); + if (this.currentLevel != hostCurrent) { + this.currentLevel = hostCurrent; + } + + AEssentiaKey key = part.getConfiguredEssentiaKey(); + String aspectId = key != null ? key.getId().toString() : ""; + if (!this.trackedAspectId.equals(aspectId)) { + this.trackedAspectId = aspectId; + } + + // 红石模式由 IConfigManager 自动同步 + } + + public AEKey getConfiguredKey() { + return getHost().getConfig().getKey(0); + } + + public void setReportingValue(long value) { + if (isClientSide()) { + sendClientAction(ACTION_SET_REPORTING_VALUE, value); + } else { + getHost().setReportingValue(value); + } + } + + public Aspect getTrackedAspect() { + if (trackedAspectId.isEmpty()) return null; + return Aspect.getAspect(trackedAspectId); + } +} diff --git a/src/main/java/thaumicenergistics/common/container/ContainerEssentiaStorageBus.java b/src/main/java/thaumicenergistics/common/container/ContainerEssentiaStorageBus.java new file mode 100644 index 0000000..359a6bf --- /dev/null +++ b/src/main/java/thaumicenergistics/common/container/ContainerEssentiaStorageBus.java @@ -0,0 +1,165 @@ +package thaumicenergistics.common.container; + +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.inventory.MenuType; + +import appeng.api.config.AccessRestriction; +import appeng.api.config.FuzzyMode; +import appeng.api.config.Settings; +import appeng.api.config.StorageFilter; +import appeng.api.config.YesNo; +import appeng.api.stacks.AEKey; +import appeng.api.stacks.GenericStack; +import appeng.api.util.IConfigManager; +import appeng.core.definitions.AEItems; +import appeng.menu.guisync.GuiSync; +import appeng.menu.implementations.UpgradeableMenu; +import thaumicenergistics.common.parts.EssentiaStorageBusPart; + +import java.util.Collections; +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 严格参照 AE2 StorageBusMenu。 + * 直接继承 UpgradeableMenu:getHost().getConfig()、getHost().getUpgrades()、getHost().getConfigManager() + * 均来自 IOBusPart 原生实现,无需自行实现库存。 + */ +public class ContainerEssentiaStorageBus extends UpgradeableMenu { + + private static final String ACTION_CLEAR = "clear"; + private static final String ACTION_PARTITION = "partition"; + + @GuiSync(3) + public AccessRestriction rwMode = AccessRestriction.READ_WRITE; + @GuiSync(4) + public StorageFilter storageFilter = StorageFilter.EXTRACTABLE_ONLY; + @GuiSync(7) + public YesNo filterOnExtract = YesNo.YES; + @GuiSync(8) + public Component connectedTo; + + public ContainerEssentiaStorageBus(MenuType menuType, int id, Inventory ip, EssentiaStorageBusPart host) { + super(menuType, id, ip, host); + + registerClientAction(ACTION_CLEAR, this::clear); + registerClientAction(ACTION_PARTITION, this::partition); + + this.connectedTo = getConnectedDescription(host); + } + + @Override + protected void setupConfig() { + // 2行固定实格 + 5行可选淡色虚格 = 63格,完全对齐 AE2 StorageBusMenu.setupConfig() + addExpandableConfigSlots(getHost().getConfig(), 2, 9, 5); + } + + @Override + public boolean isSlotEnabled(int idx) { + // 1张容量升级卡启用1行虚格(idx=第idx组可选行),和AE2一致 + final int upgrades = getUpgrades().getInstalledUpgrades(AEItems.CAPACITY_CARD); + return upgrades > idx; + } + + @Override + public void broadcastChanges() { + super.broadcastChanges(); + this.connectedTo = getConnectedDescription(getHost()); + } + + @Override + protected void loadSettingsFromHost(IConfigManager cm) { + this.setFuzzyMode(cm.getSetting(Settings.FUZZY_MODE)); + this.setReadWriteMode(cm.getSetting(Settings.ACCESS)); + this.setStorageFilter(cm.getSetting(Settings.STORAGE_FILTER)); + this.setFilterOnExtract(cm.getSetting(Settings.FILTER_ON_EXTRACT)); + } + + public void clear() { + if (isClientSide()) { sendClientAction(ACTION_CLEAR); return; } + getHost().getConfig().clear(); + this.broadcastChanges(); + } + + public void partition() { + if (isClientSide()) { sendClientAction(ACTION_PARTITION); return; } + var inv = getHost().getConfig(); + Iterator it = Collections.emptyIterator(); + + // ============= ✅ 修复3根因:IOBusPart 里没有叫 getInternalHandler() 的方法 ============= + // AE2 StorageBusPart extends IOBusPart implements IStorageProvider 自己加了 getInternalHandler + // 我们的 EssentiaStorageBusPart 没有显式实现这个方法 → 反射软查,拿不到就跳过分区(不崩) + Object storage = null; + try { + try { + storage = getHost().getClass().getMethod("getInternalHandler").invoke(getHost()); + } catch (NoSuchMethodException ignored) { + storage = getHost().getClass().getMethod("getStorage").invoke(getHost()); + } + } catch (Throwable ignored) {} + + if (storage != null) { + try { + Object availableStacks = storage.getClass().getMethod("getAvailableStacks").invoke(storage); + if (availableStacks instanceof Iterable iter) { + @SuppressWarnings("unchecked") + Iterator keyIt = ((Iterable) iter).iterator(); + it = keyIt; + } + } catch (Throwable ignored) {} + } + + inv.beginBatch(); + try { + for (int x = 0; x < inv.size(); x++) { + if (it.hasNext() && this.isSlotEnabled(x / 9 - 2)) { + inv.setStack(x, new GenericStack(it.next(), 1)); + } else { + inv.setStack(x, null); + } + } + } finally { + inv.endBatch(); + } + this.broadcastChanges(); + } + + public boolean supportsFuzzySearch() { return hasUpgrade(AEItems.FUZZY_CARD); } + public AccessRestriction getReadWriteMode() { return this.rwMode; } + private void setReadWriteMode(AccessRestriction v) { this.rwMode = v; } + public StorageFilter getStorageFilter() { return this.storageFilter; } + private void setStorageFilter(StorageFilter v) { this.storageFilter = v; } + public YesNo getFilterOnExtract() { return this.filterOnExtract; } + public void setFilterOnExtract(YesNo v) { this.filterOnExtract = v; } + public Component getConnectedTo() { return connectedTo; } + public FuzzyMode getFuzzyMode() { return this.fzMode; } + + private static Component getConnectedDescription(EssentiaStorageBusPart p) { + java.lang.reflect.Method m = METHOD_CACHE.computeIfAbsent(p.getClass(), c -> { + try { return c.getMethod("getConnectedToDescription"); } + catch (NoSuchMethodException e) { return NO_METHOD; } + }); + if (m == NO_METHOD) return null; + try { + return (Component) m.invoke(p); + } catch (Throwable t) { + return null; + } + } + + /** 反射方法缓存哨兵:computeIfAbsent 返回非 null 才缓存(避免每次 getMethod)。 */ + private static final java.lang.reflect.Method NO_METHOD; + + static { + try { + NO_METHOD = Object.class.getMethod("toString"); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + + /** 反射方法缓存:broadcastChanges 每 tick 调用 getConnectedDescription,避免每次 getMethod。 */ + private static final Map, java.lang.reflect.Method> METHOD_CACHE = new ConcurrentHashMap<>(); +} diff --git a/src/main/java/thaumicenergistics/common/container/ContainerEssentiaVibrationChamber.java b/src/main/java/thaumicenergistics/common/container/ContainerEssentiaVibrationChamber.java new file mode 100644 index 0000000..3eeefd4 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/container/ContainerEssentiaVibrationChamber.java @@ -0,0 +1,19 @@ +package thaumicenergistics.common.container; + +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.inventory.Slot; +import net.neoforged.neoforge.items.ItemStackHandler; +import net.neoforged.neoforge.items.SlotItemHandler; +import thaumicenergistics.init.ModMenuTypes; + +/** 源质谐振仓的容器。1 个燃料槽 + 玩家背包。 */ +public class ContainerEssentiaVibrationChamber extends ThEContainerBase { + final ItemStackHandler fuelSlot = new ItemStackHandler(1); + + public ContainerEssentiaVibrationChamber(int id, Inventory inv) { + super(ModMenuTypes.EVC.get(), id, inv, 1); + addSlot(new SlotItemHandler(fuelSlot, 0, 80, 42)); + } + public ContainerEssentiaVibrationChamber(int id, Inventory inv, RegistryFriendlyByteBuf buf) { this(id, inv); } +} diff --git a/src/main/java/thaumicenergistics/common/container/ContainerKnowledgeInscriber.java b/src/main/java/thaumicenergistics/common/container/ContainerKnowledgeInscriber.java new file mode 100644 index 0000000..513453c --- /dev/null +++ b/src/main/java/thaumicenergistics/common/container/ContainerKnowledgeInscriber.java @@ -0,0 +1,531 @@ +package thaumicenergistics.common.container; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import net.minecraft.core.registries.Registries; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.tags.TagKey; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.Level; +import net.minecraft.world.SimpleContainer; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.ClickType; +import net.minecraft.world.inventory.DataSlot; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; +import net.neoforged.neoforge.items.ItemStackHandler; +import net.neoforged.neoforge.items.SlotItemHandler; +import thaumcraft.api.ThaumcraftApi; +import thaumcraft.api.aspects.AspectList; +import thaumcraft.api.crafting.IArcaneRecipe; +import thaumcraft.api.crafting.ShapedArcaneRecipe; +import thaumcraft.api.crafting.ShapelessArcaneRecipe; +import thaumicenergistics.common.container.slot.GhostSlot; +import thaumicenergistics.common.integration.tc.ArcaneCraftingPattern; +import thaumicenergistics.common.inventory.HandlerKnowledgeCore; +import thaumicenergistics.common.network.KnowledgeInscriberGhostSlotPacket; +import thaumicenergistics.common.tiles.TileKnowledgeInscriber; +import thaumicenergistics.init.ModItems; +import thaumicenergistics.init.ModMenuTypes; +import net.neoforged.neoforge.network.PacketDistributor; +import thaumicenergistics.ThaumicEnergistics; + +public class ContainerKnowledgeInscriber extends AbstractContainerMenu { + + public enum CoreSaveState { + Disabled_InvalidRecipe, + Disabled_CoreFull, + Disabled_MissingCore, + Enabled_Save, + Enabled_Delete + } + + private static final int MAXIMUM_PATTERNS = HandlerKnowledgeCore.MAXIMUM_STORED_PATTERNS; + + private static final int PLAYER_INV_Y = 162; + private static final int HOTBAR_Y = 220; + private static final int PLAYER_INV_X = 8; + + private static final int KCORE_SLOT_X = 186; + private static final int KCORE_SLOT_Y = 8; + + private static final int PATTERN_SLOT_X = 26; + private static final int PATTERN_SLOT_Y = 18; + private static final int PATTERN_ROWS = 3; + private static final int PATTERN_COLS = 7; + private static final int PATTERN_SPACING = 18; + + private static final int CRAFTING_SLOT_X = 26; + private static final int CRAFTING_SLOT_Y = 90; + private static final int CRAFTING_ROWS = 3; + private static final int CRAFTING_COLS = 3; + private static final int CRAFTING_GRID_SIZE = 9; + private static final int CRAFTING_SPACING = 18; + + private static final int RESULT_SLOT_X = 116; + private static final int RESULT_SLOT_Y = 108; + + private final HandlerKnowledgeCore kCoreHandler = new HandlerKnowledgeCore(); + private final TileKnowledgeInscriber tile; + private final Inventory playerInv; + + private final ItemStackHandler kCoreInventory = new ItemStackHandler(1) { + @Override + public boolean isItemValid(int slot, ItemStack stack) { + return stack.is(ModItems.KNOWLEDGE_CORE.get()); + } + + @Override + protected void onContentsChanged(int slot) { + onKCoreChanged(); + } + }; + + private final ItemStackHandler patternInventory = new ItemStackHandler(MAXIMUM_PATTERNS); + private final ItemStackHandler craftingInventory = new ItemStackHandler(CRAFTING_GRID_SIZE); + private final ItemStackHandler resultInventory = new ItemStackHandler(1); + + private final SimpleContainer craftingContainer = new SimpleContainer(CRAFTING_GRID_SIZE); + + private IArcaneRecipe activeRecipe = null; + private final DataSlot saveStateSlot; + + public ContainerKnowledgeInscriber(int id, Inventory inv) { + this(id, inv, (TileKnowledgeInscriber) null); + } + + public ContainerKnowledgeInscriber(int id, Inventory inv, RegistryFriendlyByteBuf buf) { + this(id, inv, (TileKnowledgeInscriber) null); + } + + public ContainerKnowledgeInscriber(int id, Inventory inv, TileKnowledgeInscriber tile) { + super(ModMenuTypes.KNOWLEDGE_INSCRIBER.get(), id); + this.tile = tile; + this.playerInv = inv; + ThaumicEnergistics.LOG.info("[KLGE] ContainerKnowledgeInscriber opened, id={}, hasTile={}, isClient={}", + id, tile != null, inv.player.level().isClientSide()); + + for (int r = 0; r < 3; r++) + for (int c = 0; c < 9; c++) + addSlot(new Slot(inv, c + r * 9 + 9, PLAYER_INV_X + c * 18, PLAYER_INV_Y + r * 18)); + for (int c = 0; c < 9; c++) + addSlot(new Slot(inv, c, PLAYER_INV_X + c * 18, HOTBAR_Y)); + + addSlot(new SlotItemHandler(kCoreInventory, 0, KCORE_SLOT_X, KCORE_SLOT_Y) { + @Override + public int getMaxStackSize() { return 1; } + }); + + initPatternSlots(); + initCraftingSlots(); + + addSlot(new SlotItemHandler(resultInventory, 0, RESULT_SLOT_X, RESULT_SLOT_Y) { + @Override + public boolean mayPlace(ItemStack s) { return false; } + @Override + public boolean mayPickup(Player p) { return false; } + }); + + saveStateSlot = addDataSlot(DataSlot.standalone()); + saveStateSlot.set(0); + + if (tile != null && tile.hasKCore()) { + ItemStack slotStack = tile.getKCore().copy(); + kCoreInventory.setStackInSlot(0, slotStack); + kCoreHandler.open(slotStack); + updatePatternSlots(); + } + } + + private void initPatternSlots() { + for (int r = 0; r < PATTERN_ROWS; r++) + for (int c = 0; c < PATTERN_COLS; c++) { + int idx = r * PATTERN_COLS + c; + int x = PATTERN_SLOT_X + c * PATTERN_SPACING; + int y = PATTERN_SLOT_Y + r * PATTERN_SPACING; + addSlot(new SlotItemHandler(patternInventory, idx, x, y) { + @Override + public boolean mayPlace(ItemStack s) { return false; } + @Override + public boolean mayPickup(Player p) { return false; } + @Override + public int getMaxStackSize() { return 1; } + }); + } + } + + private void initCraftingSlots() { + for (int r = 0; r < CRAFTING_ROWS; r++) + for (int c = 0; c < CRAFTING_COLS; c++) { + int idx = r * CRAFTING_COLS + c; + int x = CRAFTING_SLOT_X + c * CRAFTING_SPACING; + int y = CRAFTING_SLOT_Y + r * CRAFTING_SPACING; + addSlot(new GhostSlot(craftingContainer, idx, x, y)); + } + } + + private void syncKCoreToTile() { + if (tile != null) { + ItemStack kCore = kCoreInventory.getStackInSlot(0); + tile.inventory.setStackInSlot(TileKnowledgeInscriber.KCORE_SLOT, kCore.copy()); + tile.setChanged(); + } + } + + private void onKCoreChanged() { + ItemStack kCore = kCoreInventory.getStackInSlot(0); + if (kCore.isEmpty()) { + kCoreHandler.close(); + clearPatternSlots(); + } else if (!kCoreHandler.isHandlingCore(kCore)) { + kCoreHandler.open(kCore); + updatePatternSlots(); + } + + syncKCoreToTile(); + } + + private void clearPatternSlots() { + for (int i = 0; i < MAXIMUM_PATTERNS; i++) { + patternInventory.setStackInSlot(i, ItemStack.EMPTY); + } + } + + private void updatePatternSlots() { + ArrayList results = kCoreHandler.hasCore() + ? kCoreHandler.getStoredOutputs() + : new ArrayList<>(); + Iterator it = results.iterator(); + + for (int i = 0; i < MAXIMUM_PATTERNS; i++) { + if (it.hasNext()) { + patternInventory.setStackInSlot(i, it.next().copy()); + } else { + patternInventory.setStackInSlot(i, ItemStack.EMPTY); + } + } + } + + private CoreSaveState getSaveState() { + if (!kCoreHandler.hasCore()) { + return CoreSaveState.Disabled_MissingCore; + } + if (activeRecipe == null) { + return CoreSaveState.Disabled_InvalidRecipe; + } + + ItemStack result = resultInventory.getStackInSlot(0); + if (result.isEmpty()) { + return CoreSaveState.Disabled_InvalidRecipe; + } + + boolean isNew = !kCoreHandler.hasPatternFor(result); + if (isNew) { + return kCoreHandler.hasRoomToStorePattern() + ? CoreSaveState.Enabled_Save + : CoreSaveState.Disabled_CoreFull; + } else { + return CoreSaveState.Enabled_Delete; + } + } + + private void updateRecipe() { + for (int i = 0; i < CRAFTING_GRID_SIZE; i++) { + craftingContainer.setItem(i, craftingInventory.getStackInSlot(i).isEmpty() + ? ItemStack.EMPTY + : craftingInventory.getStackInSlot(i).copy()); + } + + activeRecipe = findArcaneRecipe(); + ThaumicEnergistics.LOG.info("[KLGE] updateRecipe: activeRecipe={}", activeRecipe); + + if (activeRecipe != null) { + ItemStack output = activeRecipe.getCraftingResult(craftingContainer); + ThaumicEnergistics.LOG.info("[KLGE] updateRecipe: output={}", output.isEmpty() ? "EMPTY" : output.getItem().toString()); + resultInventory.setStackInSlot(0, output); + } else { + ThaumicEnergistics.LOG.info("[KLGE] updateRecipe: no recipe matched → EMPTY"); + resultInventory.setStackInSlot(0, ItemStack.EMPTY); + } + + sendSaveState(); + } + + private IArcaneRecipe findArcaneRecipe() { + Level level = playerInv.player.level(); + if (level == null) { + ThaumicEnergistics.LOG.info("[KLGE] findArcaneRecipe: level is null"); + return null; + } + var recipes = ThaumcraftApi.getCraftingRecipes(); + ThaumicEnergistics.LOG.info("[KLGE] findArcaneRecipe: total recipes={}", recipes.size()); + int arcaneCount = 0; + for (Object recipe : recipes) { + if (recipe instanceof IArcaneRecipe arcaneRecipe) { + arcaneCount++; + try { + if (gridMatches(arcaneRecipe, craftingContainer)) { + ThaumicEnergistics.LOG.info("[KLGE] findArcaneRecipe: MATCH FOUND! recipe={}", + arcaneRecipe); + return arcaneRecipe; + } + } catch (Exception e) { + ThaumicEnergistics.LOG.info("[KLGE] findArcaneRecipe: exception on recipe={}: {}", + arcaneRecipe, e.getMessage()); + } + } + } + ThaumicEnergistics.LOG.info("[KLGE] findArcaneRecipe: no match among {} arcane recipes", arcaneCount); + return null; + } + + private boolean gridMatches(IArcaneRecipe recipe, SimpleContainer inv) { + if (recipe instanceof ShapedArcaneRecipe shaped) { + for (int x = 0; x <= 3 - shaped.width; x++) { + for (int y = 0; y <= 3 - shaped.height; y++) { + if (checkShaped(shaped, inv, x, y, false) || checkShaped(shaped, inv, x, y, true)) { + return true; + } + } + } + return false; + } + if (recipe instanceof ShapelessArcaneRecipe shapeless) { + ArrayList required = new ArrayList<>(shapeless.getInput()); + for (int slot = 0; slot < 9; slot++) { + ItemStack stack = inv.getItem(slot); + if (stack.isEmpty()) continue; + Iterator it = required.iterator(); + boolean inRecipe = false; + while (it.hasNext()) { + Object next = it.next(); + if (ingredientMatches(next, stack)) { + inRecipe = true; + it.remove(); + break; + } + } + if (!inRecipe) return false; + } + return required.isEmpty(); + } + return recipe.matches(inv, playerInv.player.level(), playerInv.player); + } + + private boolean checkShaped(ShapedArcaneRecipe recipe, SimpleContainer inv, int startX, int startY, boolean mirror) { + for (int x = 0; x < 3; x++) { + for (int y = 0; y < 3; y++) { + int subX = x - startX; + int subY = y - startY; + Object target = null; + if (subX >= 0 && subY >= 0 && subX < recipe.width && subY < recipe.height) { + target = mirror + ? recipe.input[recipe.width - subX - 1 + subY * recipe.width] + : recipe.input[subX + subY * recipe.width]; + } + if (ingredientMatches(target, inv.getItem(x + y * 3))) continue; + return false; + } + } + return true; + } + + private static boolean ingredientMatches(Object target, ItemStack input) { + if (target == null) return input.isEmpty(); + if (target instanceof ItemStack t) return stackMatches(t, input); + if (target instanceof List list) { + for (Object alt : list) { + if (alt instanceof ItemStack s && stackMatches(s, input)) return true; + } + return false; + } + if (target instanceof TagKey tag && tag.isFor(Registries.ITEM)) { + @SuppressWarnings("unchecked") + TagKey itemTag = (TagKey) tag; + return !input.isEmpty() && input.is(itemTag); + } + return false; + } + + private static boolean stackMatches(ItemStack target, ItemStack input) { + if (input.isEmpty()) return target.isEmpty(); + if (target.isEmpty()) return false; + return target.getItem() == input.getItem() + && (target.getComponentsPatch().isEmpty() || ItemStack.isSameItemSameComponents(target, input)); + } + + private void sendSaveState() { + if (tile != null && tile.getLevel() != null && !tile.getLevel().isClientSide) { + saveStateSlot.set(getSaveState().ordinal()); + } + } + + public void onSaveDelete() { + CoreSaveState state = getSaveState(); + if (state == CoreSaveState.Enabled_Save) { + savePattern(); + } else if (state == CoreSaveState.Enabled_Delete) { + deletePattern(); + } + } + + private void savePattern() { + if (activeRecipe == null) return; + + ItemStack[] inputs = new ItemStack[CRAFTING_GRID_SIZE]; + for (int i = 0; i < CRAFTING_GRID_SIZE; i++) { + ItemStack stack = craftingInventory.getStackInSlot(i); + inputs[i] = stack.isEmpty() ? ItemStack.EMPTY : stack.copy(); + } + + AspectList aspects = activeRecipe.getAspects(craftingContainer); + if (aspects == null) { + aspects = activeRecipe.getAspects(); + } + ItemStack result = resultInventory.getStackInSlot(0).copy(); + + ArcaneCraftingPattern pattern = new ArcaneCraftingPattern(aspects, result, inputs); + kCoreHandler.addPattern(pattern); + updatePatternSlots(); + sendSaveState(); + syncKCoreToTile(); + } + + private void deletePattern() { + ItemStack result = resultInventory.getStackInSlot(0); + ArcaneCraftingPattern pattern = kCoreHandler.getPatternForItem(result); + if (pattern != null) { + kCoreHandler.removePattern(pattern); + updatePatternSlots(); + sendSaveState(); + syncKCoreToTile(); + } + } + + public void onClearGrid() { + for (int i = 0; i < CRAFTING_GRID_SIZE; i++) { + craftingInventory.setStackInSlot(i, ItemStack.EMPTY); + craftingContainer.setItem(i, ItemStack.EMPTY); + } + activeRecipe = null; + resultInventory.setStackInSlot(0, ItemStack.EMPTY); + sendSaveState(); + } + + public CoreSaveState getCurrentSaveState() { + return CoreSaveState.values()[saveStateSlot.get()]; + } + + @Override + public void clicked(int slotId, int dragType, ClickType clickType, Player player) { + if (slotId >= 0 && slotId < slots.size()) { + Slot slot = slots.get(slotId); + if (slot instanceof GhostSlot ghostSlot) { + int gridIndex = ghostSlot.index; + ItemStack carried = getCarried(); + ItemStack newStack = carried.isEmpty() + ? ItemStack.EMPTY + : carried.copyWithCount(1); + ThaumicEnergistics.LOG.info("[KLGE] clicked GhostSlot idx={} side={} stack={}", + gridIndex, player.level().isClientSide() ? "CLIENT" : "SERVER", + newStack.isEmpty() ? "EMPTY" : newStack.getItem().toString()); + + ghostSlot.set(newStack); + + if (player.level().isClientSide) { + ThaumicEnergistics.LOG.info("[KLGE] CLIENT branch → onCraftingChangedClient + C2S"); + onCraftingChangedClient(); + PacketDistributor.sendToServer( + new KnowledgeInscriberGhostSlotPacket(containerId, gridIndex, newStack)); + } else { + ThaumicEnergistics.LOG.info("[KLGE] SERVER branch → onCraftingChanged"); + onCraftingChanged(); + } + return; + } + } + super.clicked(slotId, dragType, clickType, player); + } + + public void setGhostSlotOnServer(int slotIndex, ItemStack stack) { + if (slotIndex < 0 || slotIndex >= CRAFTING_GRID_SIZE) return; + ItemStack s = stack == null ? ItemStack.EMPTY : stack.copy(); + ThaumicEnergistics.LOG.info("[KLGE] setGhostSlotOnServer idx={} stack={}", + slotIndex, s.isEmpty() ? "EMPTY" : s.getItem().toString()); + craftingContainer.setItem(slotIndex, s); + int slotId = 37 + MAXIMUM_PATTERNS + slotIndex; + if (slotId < slots.size() && slots.get(slotId) instanceof GhostSlot) { + slots.get(slotId).set(s); + } + onCraftingChanged(); + } + + private void onCraftingChangedClient() { + ThaumicEnergistics.LOG.info("[KLGE] onCraftingChangedClient"); + for (int i = 0; i < CRAFTING_GRID_SIZE; i++) { + craftingInventory.setStackInSlot(i, craftingContainer.getItem(i).copy()); + } + updateRecipe(); + } + + private void onCraftingChanged() { + ThaumicEnergistics.LOG.info("[KLGE] onCraftingChanged"); + for (int i = 0; i < CRAFTING_GRID_SIZE; i++) { + craftingInventory.setStackInSlot(i, craftingContainer.getItem(i).copy()); + } + updateRecipe(); + } + + @Override + public boolean clickMenuButton(Player player, int id) { + if (id == 0) { + onSaveDelete(); + return true; + } else if (id == 1) { + onClearGrid(); + return true; + } + return false; + } + + @Override + public ItemStack quickMoveStack(Player player, int idx) { + Slot slot = slots.get(idx); + if (!slot.hasItem()) return ItemStack.EMPTY; + + ItemStack stack = slot.getItem(); + ItemStack copy = stack.copy(); + + if (idx < 36) { + if (stack.is(ModItems.KNOWLEDGE_CORE.get())) { + if (!moveItemStackTo(stack, 36, 37, false)) return ItemStack.EMPTY; + } else { + return ItemStack.EMPTY; + } + } else if (idx == 36) { + if (!moveItemStackTo(stack, 0, 36, false)) return ItemStack.EMPTY; + } else { + return ItemStack.EMPTY; + } + + if (stack.isEmpty()) slot.set(ItemStack.EMPTY); + else slot.setChanged(); + + return copy; + } + + @Override + public boolean stillValid(Player player) { + return true; + } + + @Override + public void removed(Player player) { + super.removed(player); + syncKCoreToTile(); + kCoreHandler.close(); + } +} diff --git a/src/main/java/thaumicenergistics/common/container/GuiArcaneAssembler.java b/src/main/java/thaumicenergistics/common/container/GuiArcaneAssembler.java new file mode 100644 index 0000000..ab943c9 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/container/GuiArcaneAssembler.java @@ -0,0 +1,109 @@ +package thaumicenergistics.common.container; + +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Inventory; +import thaumcraft.api.aspects.Aspect; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.common.tiles.TileArcaneAssembler; + +/** + * 奥术装配器 GUI。 + * + * 贴图 arcane_assembler.png = 256×256 画布,包含4块不连续区域: + * 第1块 主矩形:(0,0) → 176×197 + * 第2块 右上不规则:(179,0) → 上部32w(0~15y),下部55w(16~103y) + * 第3块 右下护甲区:(180,129) → 68×68 + * 第4块 底部7个Vis条:每个 4×16 像素,起始(42,202),步长18(42-45, 60-63, 78-81...) + * + * 仿1.7.10纹理裁剪方式:GUI分块blit,bar区域不随纹理整体绘制, + * 而是先画暗色背景,再从纹理Y=202处裁剪满bar按百分比叠加。 + */ +public class GuiArcaneAssembler extends AbstractContainerScreen { + + static final ResourceLocation TEX = ResourceLocation.fromNamespaceAndPath( + ThaumicEnergistics.MODID, "textures/gui/arcane_assembler.png"); + + // ===== 第4块 Vis条 ===== + private static final int VIS_BAR_X = 42; + private static final int VIS_BAR_Y = 202; + private static final int VIS_BAR_W = 4; + private static final int VIS_BAR_H = 16; + private static final int VIS_BAR_STEP = 18; + + // ===== 6原质 ===== + private static final Aspect[] VIS_ASPECTS = { + Aspect.AIR, Aspect.FIRE, Aspect.WATER, + Aspect.EARTH, Aspect.ORDER, Aspect.ENTROPY + }; + + public GuiArcaneAssembler(ContainerArcaneAssembler menu, Inventory inv, Component title) { + super(menu, inv, title); + this.imageWidth = 254; + this.imageHeight = 226; + this.inventoryLabelY = 115 - 12; + this.titleLabelY = 5; + } + + @Override + protected void renderBg(GuiGraphics g, float partialTicks, int mx, int my) { + int left = (this.width - this.imageWidth) / 2; + int top = (this.height - this.imageHeight) / 2; + + // ===== 分块绘制纹理(仿1.7.10,bar区域不参与blit) ===== + + // 第1块:主矩形 176×197 + g.blit(TEX, left, top, 0, 0, 176, 197); + + // 第2块:右上不规则区域(上部 32×16 + 下部 55×88) + g.blit(TEX, left + 179, top, 179, 0, 32, 16); + g.blit(TEX, left + 179, top + 16, 179, 16, 55, 88); + + // 第3块:右下正方形 68×68 + g.blit(TEX, left + 180, top + 129, 180, 129, 68, 68); + + // ===== 第4块:Vis条(纹理裁剪方式,仿1.7.10 drawVisBar) ===== + TileArcaneAssembler tile = this.menu.assembler; + final int maxCvis = 187 * 10; + for (int i = 0; i < 7; i++) { + int bx = left + VIS_BAR_X + i * VIS_BAR_STEP; + int by = top + VIS_BAR_Y; + + float ratio = 0f; + if (tile != null) { + if (i < 6) { + int cvis = tile.getStoredVis() != null ? tile.getStoredVis().getAmount(VIS_ASPECTS[i]) : 0; + ratio = Math.min(1f, (float) cvis / maxCvis); + } else { + ratio = tile.getCraftProgress(); + } + } + + // 空bar暗色背景(满bar不在此处,由纹理裁剪提供) + g.fill(bx, by, bx + VIS_BAR_W, by + VIS_BAR_H, 0x77222222); + + // 从纹理Y=202处裁剪满bar,按高度百分比叠加 + int fillHeight = Math.round(VIS_BAR_H * ratio); + if (fillHeight > 0) { + int srcX = VIS_BAR_X + i * VIS_BAR_STEP; + int srcY = VIS_BAR_Y + (VIS_BAR_H - fillHeight); + g.blit(TEX, bx, by + (VIS_BAR_H - fillHeight), srcX, srcY, VIS_BAR_W, fillHeight); + } + + // bar边框 + g.fill(bx - 1, by - 1, bx, by + VIS_BAR_H + 1, 0xAA000000); + g.fill(bx + VIS_BAR_W, by - 1, bx + VIS_BAR_W + 1, by + VIS_BAR_H + 1, 0xAA000000); + g.fill(bx - 1, by - 1, bx + VIS_BAR_W + 1, by, 0xAA000000); + g.fill(bx - 1, by + VIS_BAR_H, bx + VIS_BAR_W + 1, by + VIS_BAR_H + 1, 0xAA000000); + } + } + + @Override + public void render(GuiGraphics g, int mx, int my, float pt) { + this.renderBackground(g, mx, my, pt); + super.render(g, mx, my, pt); + this.renderTooltip(g, mx, my); + } +} \ No newline at end of file diff --git a/src/main/java/thaumicenergistics/common/container/GuiArcaneCraftingTerminal.java b/src/main/java/thaumicenergistics/common/container/GuiArcaneCraftingTerminal.java new file mode 100644 index 0000000..b0c6310 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/container/GuiArcaneCraftingTerminal.java @@ -0,0 +1,86 @@ +package thaumicenergistics.common.container; + +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.player.Inventory; +import appeng.menu.slot.AppEngCraftingSlot; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.client.gui.AspectGuiRenderer; +import appeng.client.gui.me.common.MEStorageScreen; +import appeng.client.gui.style.ScreenStyle; + +import java.util.Map; + +public class GuiArcaneCraftingTerminal extends MEStorageScreen { + + /** 6 个要素图标位置(左上角坐标) */ + private static final int[][] ASPECT_POSITIONS = { + {10, 95}, // 左列 第1行 + {10, 112}, // 左列 第2行 + {10, 128}, // 左列 第3行 + {80, 95}, // 右列 第1行 + {80, 112}, // 右列 第2行 + {80, 128}, // 右列 第3行 + }; + + private static final int ICON_SIZE = 14; + + public GuiArcaneCraftingTerminal(ContainerArcaneCraftingTerminal menu, Inventory playerInventory, + Component title, ScreenStyle style) { + super(menu, playerInventory, title, style); + } + + /** 合成结果槽锚点 Y(首次计算缓存,避免每帧遍历 slots)。 */ + private int cachedAnchorY = -1; + + @Override + public void drawFG(GuiGraphics guiGraphics, int offsetX, int offsetY, int mouseX, int mouseY) { + super.drawFG(guiGraphics, offsetX, offsetY, mouseX, mouseY); + + if (!this.menu.hasValidRecipe) return; + + Map aspectMap = this.menu.getParsedAspects(); + if (aspectMap.isEmpty()) return; + + // 获取合成结果槽的 Y 位置作为锚点(槽位置不变,首次计算后缓存,避免每帧遍历) + int anchorY; + if (cachedAnchorY < 0) { + for (var slot : this.menu.slots) { + // CRAFTING_RESULT 槽在 style JSON 中 bottom:140 + if (slot instanceof appeng.menu.slot.AppEngCraftingSlot) { + cachedAnchorY = slot.y; + break; + } + } + // 若找不到锚点则回退到硬编码值 + if (cachedAnchorY < 0) cachedAnchorY = 95; + } + anchorY = cachedAnchorY; + + // 要素圆圈 Y = 锚点 + 偏移(-16/1/17,对应纹理 95/112/128) + int[] aspectOffsets = { -16, 1, 17 }; + + int index = 0; + for (Map.Entry entry : aspectMap.entrySet()) { + if (index >= 6) break; + + Aspect aspect = Aspect.getAspect(entry.getKey()); + if (aspect != null) { + int col = index / 3; // 0=左列, 1=右列 + int row = index % 3; // 0~2 + + int x = (col == 0) ? 10 : 80; + int y = anchorY + aspectOffsets[row]; + + AspectGuiRenderer.draw(guiGraphics, aspect, x, y, ICON_SIZE, 1.0f); + + String amountStr = String.valueOf(entry.getValue()); + int textX = x + ICON_SIZE - this.font.width(amountStr) + 1; + int textY = y + ICON_SIZE - 6; + guiGraphics.drawString(this.font, amountStr, textX, textY, 0xFFFFFF, true); + + index++; + } + } + } +} diff --git a/src/main/java/thaumicenergistics/common/container/GuiDistillationPatternEncoder.java b/src/main/java/thaumicenergistics/common/container/GuiDistillationPatternEncoder.java new file mode 100644 index 0000000..6ed0a5a --- /dev/null +++ b/src/main/java/thaumicenergistics/common/container/GuiDistillationPatternEncoder.java @@ -0,0 +1,88 @@ +package thaumicenergistics.common.container; + +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Inventory; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.client.gui.AspectGuiRenderer; +import thaumicenergistics.ThaumicEnergistics; + +public class GuiDistillationPatternEncoder extends AbstractContainerScreen { + + private static final ResourceLocation TEX = ResourceLocation.fromNamespaceAndPath( + ThaumicEnergistics.MODID, "textures/gui/distillation_encoder.png"); + + private static final int GUI_WIDTH = 176; + private static final int GUI_HEIGHT = 234; + + /** Encode 按钮引用,按配置状态动态启用/禁用。 */ + private Button encodeButton; + + public GuiDistillationPatternEncoder(ContainerDistillationPatternEncoder menu, Inventory inv, Component title) { + super(menu, inv, title); + this.imageWidth = GUI_WIDTH; + this.imageHeight = GUI_HEIGHT; + this.inventoryLabelY = this.imageHeight - 94; + } + + @Override + protected void init() { + super.init(); + + int left = (width - imageWidth) / 2; + int top = (height - imageHeight) / 2; + + // Encode 按钮:对齐 1.7.10(146,94),位于 encoded 槽上方,不覆盖 selected 槽 (116,69); + // 仅当配置完成(源物品+选中要素+空白样板就绪)时可点击 + encodeButton = Button.builder(Component.literal("Encode"), btn -> { + this.minecraft.gameMode.handleInventoryButtonClick(this.menu.containerId, 0); + }).pos(left + 140, top + 94).size(34, 16).build(); + addRenderableWidget(encodeButton); + } + + @Override + protected void renderBg(GuiGraphics g, float pt, int mx, int my) { + int x = (width - imageWidth) / 2; + int y = (height - imageHeight) / 2; + g.blit(TEX, x, y, 0, 0, imageWidth, imageHeight); + + // 绘制源物品的 6 个 aspect 图标(aspect 槽 (65,24) 起,每格 18px);实时缓存解析(源物品变化才调 TC) + Aspect[] aspects = menu.getSourceAspects(); + for (int i = 0; i < 6; i++) { + if (i < aspects.length && aspects[i] != null) { + AspectGuiRenderer.draw(g, aspects[i], x + 65, y + 24 + i * 18, 16, 1.0f); + } + } + + // 源物品非空但解析不到要素(未扫描)→ 提示 + if (!menu.getSourceItem().isEmpty() && aspects.length == 0) { + g.drawCenteredString(font, + Component.translatable("thaumicenergistics.gui.distillation_encoder.not_scanned"), + x + 73, y + 78, 0xFFAAAAAA); + } + + // 绘制选中的 aspect 图标(selected 槽 (116,69)) + Aspect selected = menu.getSelectedAspect(); + if (selected != null) { + AspectGuiRenderer.draw(g, selected, x + 116, y + 69, 16, 1.0f); + } + } + + @Override + public void containerTick() { + super.containerTick(); + // Encode 按钮仅在配置完成(源物品+选中要素+空白样板就绪)时可点击 + if (encodeButton != null) { + encodeButton.active = menu.canEncode(); + } + } + + @Override + public void render(GuiGraphics g, int mx, int my, float pt) { + super.render(g, mx, my, pt); + renderTooltip(g, mx, my); + } +} diff --git a/src/main/java/thaumicenergistics/common/container/GuiEssentiaCellTerminal.java b/src/main/java/thaumicenergistics/common/container/GuiEssentiaCellTerminal.java new file mode 100644 index 0000000..b9faf30 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/container/GuiEssentiaCellTerminal.java @@ -0,0 +1,15 @@ +package thaumicenergistics.common.container; + +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Inventory; +import thaumicenergistics.ThaumicEnergistics; + +public class GuiEssentiaCellTerminal extends AbstractContainerScreen { + static final ResourceLocation TEX = ResourceLocation.fromNamespaceAndPath(ThaumicEnergistics.MODID,"textures/gui/essentia_terminal.png"); + public GuiEssentiaCellTerminal(ContainerEssentiaCellTerminal m, Inventory inv, Component t) { super(m,inv,t); imageWidth=176; imageHeight=166; inventoryLabelY=imageHeight-94; } + @Override protected void renderBg(GuiGraphics g, float pt, int mx, int my) { int x=(width-imageWidth)/2,y=(height-imageHeight)/2; g.blit(TEX,x,y,0,0,imageWidth,imageHeight); } + @Override public void render(GuiGraphics g, int mx, int my, float pt) { super.render(g,mx,my,pt); renderTooltip(g,mx,my); } +} diff --git a/src/main/java/thaumicenergistics/common/container/GuiEssentiaCellWorkbench.java b/src/main/java/thaumicenergistics/common/container/GuiEssentiaCellWorkbench.java new file mode 100644 index 0000000..6d3053f --- /dev/null +++ b/src/main/java/thaumicenergistics/common/container/GuiEssentiaCellWorkbench.java @@ -0,0 +1,133 @@ +package thaumicenergistics.common.container; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.item.ItemStack; +import appeng.api.client.AEKeyRendering; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.common.integration.appeng.AEssentiaKey; +import thaumicenergistics.common.network.CellWorkbenchC2SPacket; + +/** + * 源质元件工作台 GUI:显示 63 个分区格(9×7),支持点击添加/移除/替换源质分区,两个分区按钮。 + * 对应 1.7.10 的 {@code GuiEssentiaCellWorkbench}。 + */ +public class GuiEssentiaCellWorkbench extends AbstractContainerScreen { + + private static final ResourceLocation TEX = ResourceLocation.fromNamespaceAndPath(ThaumicEnergistics.MODID, "textures/gui/essentia_cell_workbench.png"); + private static final int GUI_WIDTH = 176, GUI_HEIGHT = 251; + /** 分区格布局常量(JEI ghost 拖拽也使用,故公开)。 */ + public static final int WIDGET_POS_X = 7, WIDGET_POS_Y = 28; + public static final int WIDGETS_PER_ROW = 9, WIDGET_ROWS = 7, NUMBER_OF_WIDGETS = 63; + public static final int WIDGET_SIZE = 18; + + /** 当前显示的分区列表(大小 63,null = 空分区格)。由 S2C 同步更新。 */ + private final List partitionSlots = new ArrayList<>(Collections.nCopies(NUMBER_OF_WIDGETS, null)); + + /** 上次检测到的 cell 槽内容,用于在放入/拿走 cell 时触发分区刷新。 */ + private ItemStack lastCellStack = ItemStack.EMPTY; + + public GuiEssentiaCellWorkbench(ContainerEssentiaCellWorkbench menu, Inventory inv, Component title) { + super(menu, inv, title); + imageWidth = GUI_WIDTH; + imageHeight = GUI_HEIGHT; + inventoryLabelY = imageHeight - 94; + } + + @Override + protected void init() { + super.init(); + // 分区为当前(P)与清除分区(C)按钮,位置对应 1.7.10(GUI 左外侧) + addRenderableWidget(Button.builder(Component.literal("P"), b -> CellWorkbenchC2SPacket.sendPartitionToContents()) + .bounds(leftPos - 18, topPos + 8, 18, 18).build()); + addRenderableWidget(Button.builder(Component.literal("C"), b -> CellWorkbenchC2SPacket.sendClear()) + .bounds(leftPos - 18, topPos + 28, 18, 18).build()); + // 打开时请求服务端分区列表 + CellWorkbenchC2SPacket.sendRequestPartitions(); + } + + @Override + protected void renderBg(GuiGraphics g, float pt, int mx, int my) { + int x = (width - imageWidth) / 2, y = (height - imageHeight) / 2; + g.blit(TEX, x, y, 0, 0, imageWidth, imageHeight); + + for (int i = 0; i < NUMBER_OF_WIDGETS; i++) { + ResourceLocation id = partitionSlots.get(i); + if (id != null) { + int col = i % WIDGETS_PER_ROW, row = i / WIDGETS_PER_ROW; + AEKeyRendering.drawInGui(minecraft, g, + x + WIDGET_POS_X + col * WIDGET_SIZE, + y + WIDGET_POS_Y + row * WIDGET_SIZE, + AEssentiaKey.of(id)); + } + } + } + + @Override + public boolean mouseClicked(double mx, double my, int btn) { + for (int i = 0; i < NUMBER_OF_WIDGETS; i++) { + int col = i % WIDGETS_PER_ROW, row = i / WIDGETS_PER_ROW; + int wx = leftPos + WIDGET_POS_X + col * WIDGET_SIZE; + int wy = topPos + WIDGET_POS_Y + row * WIDGET_SIZE; + if (mx >= wx && mx < wx + WIDGET_SIZE && my >= wy && my < wy + WIDGET_SIZE) { + handlePartitionClick(i); + return true; + } + } + return super.mouseClicked(mx, my, btn); + } + + /** + * 点击分区格:空 + 手持含源质物品 → 添加;有源质 + 空手 → 移除;有源质 + 不同源质 → 替换。 + */ + private void handlePartitionClick(int index) { + ResourceLocation current = index < partitionSlots.size() ? partitionSlots.get(index) : null; + ResourceLocation held = ContainerEssentiaCellWorkbench.getAspectFromItem(menu.getCarried()); + if (current == null && held != null) { + CellWorkbenchC2SPacket.sendAddAspect(held); + } else if (current != null && held == null) { + CellWorkbenchC2SPacket.sendRemoveAspect(current); + } else if (current != null && held != null && !current.equals(held)) { + CellWorkbenchC2SPacket.sendReplaceAspect(current, held); + } + } + + /** + * 服务端同步分区列表(S2C handler 调用)。 + */ + public void updatePartitions(List list) { + partitionSlots.clear(); + if (list.size() > NUMBER_OF_WIDGETS) { + partitionSlots.addAll(list.subList(0, NUMBER_OF_WIDGETS)); + } else { + partitionSlots.addAll(list); + } + for (int i = partitionSlots.size(); i < NUMBER_OF_WIDGETS; i++) { + partitionSlots.add(null); + } + } + + @Override + public void render(GuiGraphics g, int mx, int my, float pt) { + // 检测 cell 槽变化:放入已配置 cell → 重新请求分区;拿走 cell → 立即清空显示 + ItemStack cell = menu.slots.get(0).getItem(); + if (!ItemStack.matches(cell, lastCellStack)) { + lastCellStack = cell.copy(); + if (cell.isEmpty()) { + updatePartitions(List.of()); + } else { + CellWorkbenchC2SPacket.sendRequestPartitions(); + } + } + super.render(g, mx, my, pt); + renderTooltip(g, mx, my); + } +} diff --git a/src/main/java/thaumicenergistics/common/container/GuiEssentiaExportBus.java b/src/main/java/thaumicenergistics/common/container/GuiEssentiaExportBus.java new file mode 100644 index 0000000..e4d25f0 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/container/GuiEssentiaExportBus.java @@ -0,0 +1,75 @@ +package thaumicenergistics.common.container; + +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.player.Inventory; + +import appeng.api.config.FuzzyMode; +import appeng.api.config.RedstoneMode; +import appeng.api.config.SchedulingMode; +import appeng.api.config.Settings; +import appeng.api.config.YesNo; +import appeng.api.util.KeyTypeSelectionHost; +import appeng.client.gui.implementations.UpgradeableScreen; +import appeng.client.gui.style.ScreenStyle; +import appeng.client.gui.widgets.KeyTypeSelectionButton; +import appeng.client.gui.widgets.ServerSettingToggleButton; +import appeng.client.gui.widgets.SettingToggleButton; +import appeng.core.definitions.AEItems; +import appeng.core.localization.GuiText; +import thaumicenergistics.init.ModItems; + +public class GuiEssentiaExportBus extends UpgradeableScreen { + + private final SettingToggleButton redstoneMode; + private final SettingToggleButton fuzzyMode; + private final SettingToggleButton craftMode; + private final SettingToggleButton schedulingMode; + + public GuiEssentiaExportBus(ContainerEssentiaExportBus menu, Inventory playerInventory, + Component title, ScreenStyle style) { + super(menu, playerInventory, title, style); + + setTextContent("dialog_title", ModItems.ESSENTIA_EXPORT_BUS.get().getDescription()); + + if (menu.getHost() instanceof KeyTypeSelectionHost) { + addToLeftToolbar( + KeyTypeSelectionButton.create(this, menu.getHost(), GuiText.ConfigureImportedTypes.text())); + } + + this.redstoneMode = new ServerSettingToggleButton<>(Settings.REDSTONE_CONTROLLED, RedstoneMode.IGNORE); + addToLeftToolbar(this.redstoneMode); + + this.fuzzyMode = new ServerSettingToggleButton<>(Settings.FUZZY_MODE, FuzzyMode.IGNORE_ALL); + addToLeftToolbar(this.fuzzyMode); + + if (menu.getHost().getConfigManager().hasSetting(Settings.CRAFT_ONLY)) { + this.craftMode = new ServerSettingToggleButton<>(Settings.CRAFT_ONLY, YesNo.NO); + addToLeftToolbar(this.craftMode); + } else { + this.craftMode = null; + } + + if (menu.getHost().getConfigManager().hasSetting(Settings.SCHEDULING_MODE)) { + this.schedulingMode = new ServerSettingToggleButton<>(Settings.SCHEDULING_MODE, SchedulingMode.DEFAULT); + addToLeftToolbar(this.schedulingMode); + } else { + this.schedulingMode = null; + } + } + + @Override + protected void updateBeforeRender() { + super.updateBeforeRender(); + this.redstoneMode.set(menu.getRedStoneMode()); + this.redstoneMode.setVisibility(menu.hasUpgrade(AEItems.REDSTONE_CARD)); + this.fuzzyMode.set(menu.getFuzzyMode()); + this.fuzzyMode.setVisibility(menu.hasUpgrade(AEItems.FUZZY_CARD)); + if (this.craftMode != null) { + this.craftMode.set(menu.getCraftingMode()); + this.craftMode.setVisibility(menu.hasUpgrade(AEItems.CRAFTING_CARD)); + } + if (this.schedulingMode != null) { + this.schedulingMode.set(menu.getSchedulingMode()); + } + } +} diff --git a/src/main/java/thaumicenergistics/common/container/GuiEssentiaImportBus.java b/src/main/java/thaumicenergistics/common/container/GuiEssentiaImportBus.java new file mode 100644 index 0000000..c703484 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/container/GuiEssentiaImportBus.java @@ -0,0 +1,63 @@ +package thaumicenergistics.common.container; + +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.player.Inventory; + +import appeng.api.config.FuzzyMode; +import appeng.api.config.RedstoneMode; +import appeng.api.config.Settings; +import appeng.api.config.YesNo; +import appeng.api.util.KeyTypeSelectionHost; +import appeng.client.gui.implementations.UpgradeableScreen; +import appeng.client.gui.style.ScreenStyle; +import appeng.client.gui.widgets.KeyTypeSelectionButton; +import appeng.client.gui.widgets.ServerSettingToggleButton; +import appeng.client.gui.widgets.SettingToggleButton; +import appeng.core.definitions.AEItems; +import appeng.core.localization.GuiText; +import thaumicenergistics.init.ModItems; + +public class GuiEssentiaImportBus extends UpgradeableScreen { + + private final SettingToggleButton redstoneMode; + private final SettingToggleButton fuzzyMode; + private final SettingToggleButton craftMode; + + public GuiEssentiaImportBus(ContainerEssentiaImportBus menu, Inventory playerInventory, + Component title, ScreenStyle style) { + super(menu, playerInventory, title, style); + + setTextContent("dialog_title", ModItems.ESSENTIA_IMPORT_BUS.get().getDescription()); + + if (menu.getHost() instanceof KeyTypeSelectionHost) { + addToLeftToolbar( + KeyTypeSelectionButton.create(this, menu.getHost(), GuiText.ConfigureImportedTypes.text())); + } + + this.redstoneMode = new ServerSettingToggleButton<>(Settings.REDSTONE_CONTROLLED, RedstoneMode.IGNORE); + addToLeftToolbar(this.redstoneMode); + + this.fuzzyMode = new ServerSettingToggleButton<>(Settings.FUZZY_MODE, FuzzyMode.IGNORE_ALL); + addToLeftToolbar(this.fuzzyMode); + + if (menu.getHost().getConfigManager().hasSetting(Settings.CRAFT_ONLY)) { + this.craftMode = new ServerSettingToggleButton<>(Settings.CRAFT_ONLY, YesNo.NO); + addToLeftToolbar(this.craftMode); + } else { + this.craftMode = null; + } + } + + @Override + protected void updateBeforeRender() { + super.updateBeforeRender(); + this.redstoneMode.set(menu.getRedStoneMode()); + this.redstoneMode.setVisibility(menu.hasUpgrade(AEItems.REDSTONE_CARD)); + this.fuzzyMode.set(menu.getFuzzyMode()); + this.fuzzyMode.setVisibility(menu.hasUpgrade(AEItems.FUZZY_CARD)); + if (this.craftMode != null) { + this.craftMode.set(menu.getCraftingMode()); + this.craftMode.setVisibility(menu.hasUpgrade(AEItems.CRAFTING_CARD)); + } + } +} diff --git a/src/main/java/thaumicenergistics/common/container/GuiEssentiaLevelEmitter.java b/src/main/java/thaumicenergistics/common/container/GuiEssentiaLevelEmitter.java new file mode 100644 index 0000000..ab0a069 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/container/GuiEssentiaLevelEmitter.java @@ -0,0 +1,102 @@ +package thaumicenergistics.common.container; + +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Inventory; +import thaumcraft.api.aspects.Aspect; +import appeng.api.config.RedstoneMode; +import appeng.api.config.Settings; +import appeng.client.gui.NumberEntryType; +import appeng.client.gui.implementations.UpgradeableScreen; +import appeng.client.gui.style.ScreenStyle; +import appeng.client.gui.widgets.NumberEntryWidget; +import appeng.client.gui.widgets.ServerSettingToggleButton; +import appeng.client.gui.widgets.SettingToggleButton; +import thaumicenergistics.ThaumicEnergistics; + +/** + * 源质发信器 Screen — 与 AE2 原版 StorageLevelEmitterScreen 逻辑一致。 + */ +public class GuiEssentiaLevelEmitter extends UpgradeableScreen { + + private static final ResourceLocation ASPECT_SLOT_BG = + ThaumicEnergistics.id("textures/gui/essentia_terminal.png"); + + private final SettingToggleButton redstoneMode; + private final NumberEntryWidget level; + private long lastReportingValue; + + private static final int ASPECT_SLOT_X = 137; + private static final int ASPECT_SLOT_Y = 40; + + public GuiEssentiaLevelEmitter(ContainerEssentiaLevelEmitter menu, Inventory playerInventory, + Component title, ScreenStyle style) { + super(menu, playerInventory, title, style); + + this.redstoneMode = new ServerSettingToggleButton<>( + Settings.REDSTONE_EMITTER, RedstoneMode.HIGH_SIGNAL); + this.addToLeftToolbar(this.redstoneMode); + + this.level = widgets.addNumberEntryWidget("level", NumberEntryType.of(menu.getConfiguredKey())); + this.level.setTextFieldStyle(style.getWidget("levelInput")); + this.level.setLongValue(this.menu.reportingValue); + this.level.setOnChange(this::saveReportingValue); + this.level.setOnConfirm(this::onClose); + this.lastReportingValue = this.menu.reportingValue; + } + + @Override + protected void updateBeforeRender() { + super.updateBeforeRender(); + + // 更新数字输入类型(筛选可能已改变) + this.level.setType(NumberEntryType.of(menu.getConfiguredKey())); + this.level.setActive(true); + + if (this.lastReportingValue != this.menu.reportingValue) { + this.lastReportingValue = this.menu.reportingValue; + this.level.setLongValue(this.menu.reportingValue); + } + + this.redstoneMode.set(this.menu.getRedStoneMode()); + this.redstoneMode.setVisibility(true); + } + + @Override + public void drawFG(GuiGraphics guiGraphics, int offsetX, int offsetY, int mouseX, int mouseY) { + super.drawFG(guiGraphics, offsetX, offsetY, mouseX, mouseY); + + Aspect aspect = this.menu.getTrackedAspect(); + if (aspect != null) { + guiGraphics.drawString(this.font, aspect.getName(), + ASPECT_SLOT_X + 20, ASPECT_SLOT_Y + 4, 0xFFFFFF, false); + } + + guiGraphics.drawString(this.font, + "Current: " + this.menu.currentLevel, + 8, 70, 0xAAAAAA, false); + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + // 右键点击筛选槽清零 reportingValue + if (isPointInRegion(ASPECT_SLOT_X, ASPECT_SLOT_Y, 16, 16, mouseX, mouseY)) { + if (button == 1) { + this.menu.setReportingValue(0); + return true; + } + } + return super.mouseClicked(mouseX, mouseY, button); + } + + private void saveReportingValue() { + this.level.getLongValue().ifPresent(menu::setReportingValue); + } + + private boolean isPointInRegion(int x, int y, int w, int h, double mx, double my) { + int left = this.leftPos + x; + int top = this.topPos + y; + return mx >= left && mx < left + w && my >= top && my < top + h; + } +} diff --git a/src/main/java/thaumicenergistics/common/container/GuiEssentiaStorageBus.java b/src/main/java/thaumicenergistics/common/container/GuiEssentiaStorageBus.java new file mode 100644 index 0000000..e0ca5ce --- /dev/null +++ b/src/main/java/thaumicenergistics/common/container/GuiEssentiaStorageBus.java @@ -0,0 +1,91 @@ +package thaumicenergistics.common.container; + +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.player.Inventory; + +import appeng.api.config.ActionItems; +import appeng.api.config.FuzzyMode; +import appeng.client.gui.implementations.UpgradeableScreen; +import appeng.client.gui.style.PaletteColor; +import appeng.client.gui.style.ScreenStyle; +import appeng.client.gui.widgets.ActionButton; +import appeng.client.gui.widgets.ServerSettingToggleButton; +import appeng.client.gui.widgets.SettingToggleButton; +import appeng.core.definitions.AEItems; +import appeng.core.localization.GuiText; +import appeng.api.config.AccessRestriction; +import appeng.api.config.Settings; +import appeng.api.config.StorageFilter; +import appeng.api.config.YesNo; +import thaumicenergistics.init.ModItems; + +/** + * 源质存储总线GUI。 + * 使用 AE2 原生 /screens/storage_bus.json(布局/工具栏/优先级按钮/尺寸完全一致), + * 仅通过 setTextContent("dialog_title", ...) 覆盖标题为"源质存储总线"。 + */ +public class GuiEssentiaStorageBus extends UpgradeableScreen { + + private final SettingToggleButton rwMode; + private final SettingToggleButton storageFilter; + private final SettingToggleButton filterOnExtract; + private final SettingToggleButton fuzzyMode; + + public GuiEssentiaStorageBus(ContainerEssentiaStorageBus menu, Inventory playerInventory, + Component title, ScreenStyle style) { + super(menu, playerInventory, title, style); + + // ✅ 覆盖JSON中的 dialog_title 文本(原本是 gui.ae2.StorageBus → "存储总线") + setTextContent("dialog_title", ModItems.ESSENTIA_STORAGE_BUS.get().getDescription()); + + // 右上角优先级按钮(AE2原生JSON里定义了 openPriority widget) + widgets.addOpenPriorityButton(); + + // 左侧工具栏:清空 / 分区(始终显示) + addToLeftToolbar(new ActionButton(ActionItems.CLOSE, btn -> menu.clear())); + addToLeftToolbar(new ActionButton(ActionItems.COG, btn -> menu.partition())); + + // 存储过滤模式(始终显示) + this.storageFilter = new ServerSettingToggleButton<>(Settings.STORAGE_FILTER, StorageFilter.EXTRACTABLE_ONLY); + this.addToLeftToolbar(this.storageFilter); + + // 提取时应用过滤(始终显示) + this.filterOnExtract = new ServerSettingToggleButton<>(Settings.FILTER_ON_EXTRACT, YesNo.YES); + this.addToLeftToolbar(this.filterOnExtract); + + // 模糊模式(需要模糊升级卡才显示) + this.fuzzyMode = new ServerSettingToggleButton<>(Settings.FUZZY_MODE, FuzzyMode.IGNORE_ALL); + this.addToLeftToolbar(this.fuzzyMode); + + // 读写访问模式(始终显示) + this.rwMode = new ServerSettingToggleButton<>(Settings.ACCESS, AccessRestriction.READ_WRITE); + this.addToLeftToolbar(this.rwMode); + } + + @Override + protected void updateBeforeRender() { + super.updateBeforeRender(); + this.storageFilter.set(this.menu.getStorageFilter()); + this.rwMode.set(this.menu.getReadWriteMode()); + this.filterOnExtract.set(this.menu.getFilterOnExtract()); + this.fuzzyMode.set(this.menu.getFuzzyMode()); + this.fuzzyMode.setVisibility(menu.hasUpgrade(AEItems.FUZZY_CARD)); + } + + @Override + public void drawFG(GuiGraphics guiGraphics, int offsetX, int offsetY, int mouseX, int mouseY) { + super.drawFG(guiGraphics, offsetX, offsetY, mouseX, mouseY); + var poseStack = guiGraphics.pose(); + poseStack.pushPose(); + poseStack.translate(10, 17, 0); + poseStack.scale(0.6f, 0.6f, 1); + int color = style.getColor(PaletteColor.DEFAULT_TEXT_COLOR).toARGB(); + if (menu.getConnectedTo() != null) { + guiGraphics.drawString(font, GuiText.AttachedTo.text(menu.getConnectedTo()), 0, 0, color, false); + } else { + guiGraphics.drawString(font, GuiText.Unattached.text(), 0, 0, color, false); + } + poseStack.popPose(); + } +} diff --git a/src/main/java/thaumicenergistics/common/container/GuiEssentiaVibrationChamber.java b/src/main/java/thaumicenergistics/common/container/GuiEssentiaVibrationChamber.java new file mode 100644 index 0000000..d22ba21 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/container/GuiEssentiaVibrationChamber.java @@ -0,0 +1,15 @@ +package thaumicenergistics.common.container; + +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Inventory; +import thaumicenergistics.ThaumicEnergistics; + +public class GuiEssentiaVibrationChamber extends AbstractContainerScreen { + static final ResourceLocation TEX = ResourceLocation.fromNamespaceAndPath(ThaumicEnergistics.MODID,"textures/gui/essentia_vibration_chamber.png"); + public GuiEssentiaVibrationChamber(ContainerEssentiaVibrationChamber m, Inventory inv, Component t) { super(m,inv,t); imageWidth=176; imageHeight=166; inventoryLabelY=imageHeight-94; } + @Override protected void renderBg(GuiGraphics g, float pt, int mx, int my) { int x=(width-imageWidth)/2,y=(height-imageHeight)/2; g.blit(TEX,x,y,0,0,imageWidth,imageHeight); } + @Override public void render(GuiGraphics g, int mx, int my, float pt) { super.render(g,mx,my,pt); renderTooltip(g,mx,my); } +} diff --git a/src/main/java/thaumicenergistics/common/container/GuiKnowledgeInscriber.java b/src/main/java/thaumicenergistics/common/container/GuiKnowledgeInscriber.java new file mode 100644 index 0000000..a7279f2 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/container/GuiKnowledgeInscriber.java @@ -0,0 +1,101 @@ +package thaumicenergistics.common.container; + +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Inventory; +import thaumicenergistics.ThaumicEnergistics; + +/** + * 知识记录仪 GUI。 + * 从 1.7.10 GuiKnowledgeInscriber 移植。 + */ +public class GuiKnowledgeInscriber extends AbstractContainerScreen { + + private static final ResourceLocation TEX = ResourceLocation.fromNamespaceAndPath( + ThaumicEnergistics.MODID, "textures/gui/knowledge_inscriber.png"); + + private static final int GUI_WIDTH = 210; + private static final int GUI_HEIGHT = 244; + + private Button saveButton; + private Button clearButton; + + private ContainerKnowledgeInscriber.CoreSaveState saveState = + ContainerKnowledgeInscriber.CoreSaveState.Disabled_MissingCore; + + public GuiKnowledgeInscriber(ContainerKnowledgeInscriber menu, Inventory inv, Component title) { + super(menu, inv, title); + this.imageWidth = GUI_WIDTH; + this.imageHeight = GUI_HEIGHT; + this.inventoryLabelY = this.imageHeight - 94; + } + + @Override + protected void init() { + super.init(); + + int left = (width - imageWidth) / 2; + int top = (height - imageHeight) / 2; + + saveButton = Button.builder(Component.literal(""), btn -> { + this.minecraft.gameMode.handleInventoryButtonClick(this.menu.containerId, 0); + }).pos(left + 141, top + 109).size(38, 18).build(); + addRenderableWidget(saveButton); + + clearButton = Button.builder(Component.literal("C"), btn -> { + this.minecraft.gameMode.handleInventoryButtonClick(this.menu.containerId, 1); + }).pos(left + 80, top + 89).size(8, 8).build(); + addRenderableWidget(clearButton); + } + + @Override + protected void containerTick() { + super.containerTick(); + ContainerKnowledgeInscriber.CoreSaveState newState = menu.getCurrentSaveState(); + if (newState != saveState) { + saveState = newState; + updateSaveButton(); + } + } + + private void updateSaveButton() { + switch (saveState) { + case Disabled_MissingCore: + saveButton.active = false; + saveButton.setMessage(Component.literal("No Core")); + break; + case Disabled_InvalidRecipe: + saveButton.active = false; + saveButton.setMessage(Component.literal("Invalid")); + break; + case Disabled_CoreFull: + saveButton.active = false; + saveButton.setMessage(Component.literal("Full")); + break; + case Enabled_Save: + saveButton.active = true; + saveButton.setMessage(Component.literal("Save")); + break; + case Enabled_Delete: + saveButton.active = true; + saveButton.setMessage(Component.literal("Delete")); + break; + } + } + + @Override + protected void renderBg(GuiGraphics g, float pt, int mx, int my) { + int x = (width - imageWidth) / 2; + int y = (height - imageHeight) / 2; + g.blit(TEX, x, y, 0, 0, imageWidth, imageHeight); + } + + @Override + public void render(GuiGraphics g, int mx, int my, float pt) { + super.render(g, mx, my, pt); + renderTooltip(g, mx, my); + } +} diff --git a/src/main/java/thaumicenergistics/common/container/SimpleMenuProvider.java b/src/main/java/thaumicenergistics/common/container/SimpleMenuProvider.java new file mode 100644 index 0000000..4bddec7 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/container/SimpleMenuProvider.java @@ -0,0 +1,28 @@ +package thaumicenergistics.common.container; + +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.MenuProvider; + +import java.util.function.BiFunction; + +/** 不依赖AE2 SubMenu 体系的 MenuProvider,给三个总线打开自定义GUI用 */ +public record SimpleMenuProvider( + Component title, + MenuType type, + BiFunction factory +) implements MenuProvider { + + @Override + public Component getDisplayName() { + return title; + } + + @Override + public AbstractContainerMenu createMenu(int id, Inventory playerInv, Player player) { + return factory.apply(id, playerInv); + } +} \ No newline at end of file diff --git a/src/main/java/thaumicenergistics/common/container/ThEContainerBase.java b/src/main/java/thaumicenergistics/common/container/ThEContainerBase.java new file mode 100644 index 0000000..bda31a7 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/container/ThEContainerBase.java @@ -0,0 +1,48 @@ +package thaumicenergistics.common.container; + +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; + +/** 带玩家背包的基础容器。所有 ThE 容器都继承它。 */ +public abstract class ThEContainerBase extends AbstractContainerMenu { + protected final Inventory playerInv; + protected final int playerInvStart; + + // ===== AE2 标准坐标(源自 storage_bus.json + player_inventory.json)===== + // 所有 ThE 容器(无论是否走 UpgradeableMenu)都以此基准对齐。 + public static final int AE2_IMAGE_HEIGHT = 253; + public static final int AE2_PLAYER_INV_Y = AE2_IMAGE_HEIGHT - 84; // 169 + public static final int AE2_HOTBAR_Y = AE2_IMAGE_HEIGHT - 26; // 227 + public static final int AE2_PLAYER_INV_X = 8; + + protected ThEContainerBase(MenuType type, int id, Inventory playerInv, int customSlots) { + super(type, id); + this.playerInv = playerInv; + this.playerInvStart = customSlots; + addPlayerInventory(customSlots); + } + + private void addPlayerInventory(int start) { + for (int r = 0; r < 3; r++) for (int c = 0; c < 9; c++) + addSlot(new Slot(playerInv, c + r * 9 + 9, + AE2_PLAYER_INV_X + c * 18, AE2_PLAYER_INV_Y + r * 18)); + for (int c = 0; c < 9; c++) + addSlot(new Slot(playerInv, c, + AE2_PLAYER_INV_X + c * 18, AE2_HOTBAR_Y)); + } + + @Override public ItemStack quickMoveStack(Player p, int idx) { + ItemStack r = ItemStack.EMPTY; Slot s = slots.get(idx); + if (s.hasItem()) { ItemStack st = s.getItem(); r = st.copy(); + if (idx < playerInvStart) { if (!moveItemStackTo(st, playerInvStart, slots.size(), true)) return ItemStack.EMPTY; } + else if (!moveItemStackTo(st, 0, playerInvStart, false)) return ItemStack.EMPTY; + if (st.isEmpty()) s.set(ItemStack.EMPTY); else s.setChanged(); + } return r; + } + + @Override public boolean stillValid(Player p) { return true; } +} diff --git a/src/main/java/thaumicenergistics/common/container/slot/ArcaneCraftingResultSlot.java b/src/main/java/thaumicenergistics/common/container/slot/ArcaneCraftingResultSlot.java new file mode 100644 index 0000000..1f49da8 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/container/slot/ArcaneCraftingResultSlot.java @@ -0,0 +1,133 @@ +package thaumicenergistics.common.container.slot; + +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; + +import appeng.api.inventories.InternalInventory; +import appeng.menu.slot.AppEngCraftingSlot; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; +import thaumcraft.common.items.TCFunctionalItems; +import thaumcraft.common.lib.crafting.ThaumcraftCraftingManager; +import thaumicenergistics.common.container.ContainerArcaneCraftingTerminal; + +/** + * 奥术合成结果槽:在取走合成结果时消耗法杖要素。 + * 参考 TC4 1.21.1 ArcaneWorkbenchMenu.onResultTaken + consumeVis。 + */ +public class ArcaneCraftingResultSlot extends AppEngCraftingSlot { + + /** TC4 内部使用 centivis,1 vis = 100 centivis */ + private static final int CENTIVIS = 100; + + private AspectList requiredAspects = null; + private ItemStack wandStack = ItemStack.EMPTY; + private Runnable refreshCallback = null; + private ContainerArcaneCraftingTerminal container = null; + + public ArcaneCraftingResultSlot(Player player, InternalInventory craftingGridInv) { + super(player, craftingGridInv); + } + + public void setContainer(ContainerArcaneCraftingTerminal container) { + this.container = container; + } + + public void setRefreshCallback(Runnable callback) { + this.refreshCallback = callback; + } + + public void setRequiredAspects(AspectList aspects) { + this.requiredAspects = aspects; + } + + public void setWandStack(ItemStack wandStack) { + this.wandStack = wandStack; + } + + @Override + public boolean mayPickup(Player player) { + if (requiredAspects == null || requiredAspects.isEmpty()) { + return super.mayPickup(player); + } + + if (wandStack.isEmpty()) return false; + if (!(wandStack.getItem() instanceof TCFunctionalItems.WandCastingItem wand)) { + return false; + } + + AspectList centivisCost = new AspectList(); + for (Aspect aspect : requiredAspects.aspects()) { + centivisCost.add(aspect, requiredAspects.amount(aspect) * CENTIVIS); + } + return wand.consumeVisCost(wandStack, player, centivisCost, false, true); + } + + @Override + public void onTake(Player player, ItemStack stack) { + // 记录消耗前各合成格中的物品类型,用于消耗后从 ME 网络补充 + java.util.Map beforeItems = new java.util.HashMap<>(); + if (container != null) { + var grid = container.getCraftingMatrix(); + for (int i = 0; i < grid.size(); i++) { + var s = grid.getStackInSlot(i); + if (!s.isEmpty()) { + beforeItems.put(i, s.copy()); + } + } + } + + if (container != null) { + container.setCraftingResultBeingTaken(true); + } + try { + super.onTake(player, stack); + + if (requiredAspects != null && !requiredAspects.isEmpty() && !wandStack.isEmpty()) { + if (wandStack.getItem() instanceof TCFunctionalItems.WandCastingItem wand) { + AspectList centivisCost = new AspectList(); + for (Aspect aspect : requiredAspects.aspects()) { + centivisCost.add(aspect, requiredAspects.amount(aspect) * CENTIVIS); + } + wand.consumeVisCost(wandStack, player, centivisCost, true, true); + } + } + + // 从 ME 网络自动补充消耗掉的合成材料 + if (container != null && !beforeItems.isEmpty()) { + var grid = container.getCraftingMatrix(); + var node = container.getGridNode(); + if (node != null && node.getGrid() != null) { + var storage = node.getGrid().getStorageService().getInventory(); + var energy = container.getEnergySource(); + var actionSource = container.getActionSource(); + for (var entry : beforeItems.entrySet()) { + int slot = entry.getKey(); + var beforeItem = entry.getValue(); + var currentItem = grid.getStackInSlot(slot); + // 如果该格物品变少了(被消耗了),从网络提取补充 + if (currentItem.getCount() < beforeItem.getCount()) { + long needed = beforeItem.getCount() - currentItem.getCount(); + var key = appeng.api.stacks.AEItemKey.of(beforeItem); + if (key != null) { + long extracted = appeng.api.storage.StorageHelper.poweredExtraction( + energy, storage, key, needed, actionSource); + if (extracted > 0) { + var toPlace = beforeItem.copyWithCount((int) (currentItem.getCount() + extracted)); + grid.setItemDirect(slot, toPlace); + } + } + } + } + } + } + } finally { + if (container != null) { + container.setCraftingResultBeingTaken(false); + } + } + if (refreshCallback != null) { + refreshCallback.run(); + } + } +} diff --git a/src/main/java/thaumicenergistics/common/container/slot/GhostSlot.java b/src/main/java/thaumicenergistics/common/container/slot/GhostSlot.java new file mode 100644 index 0000000..75163a0 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/container/slot/GhostSlot.java @@ -0,0 +1,31 @@ +package thaumicenergistics.common.container.slot; + +import net.minecraft.world.Container; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; + +/** + * 幽灵物品槽,用于知识记录仪的合成网格。 + * 玩家可以放置任意物品,也可以取回。 + */ +public class GhostSlot extends Slot { + public GhostSlot(Container inv, int idx, int x, int y) { + super(inv, idx, x, y); + } + + @Override + public boolean mayPlace(ItemStack stack) { + return true; + } + + @Override + public boolean mayPickup(Player player) { + return true; + } + + @Override + public int getMaxStackSize() { + return 1; + } +} diff --git a/src/main/java/thaumicenergistics/common/entities/BackpackSkins.java b/src/main/java/thaumicenergistics/common/entities/BackpackSkins.java new file mode 100644 index 0000000..dd1efd8 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/entities/BackpackSkins.java @@ -0,0 +1,58 @@ +package thaumicenergistics.common.entities; + +import net.minecraft.resources.ResourceLocation; +import thaumicenergistics.ThaumicEnergistics; + +/** + * 傀儡无线背包皮肤枚举。 + * 每种皮肤对应一个纹理文件:{@code textures/model/golemBackpack/{texId}.png}。 + * 皮肤通过 AE2 Facade 物品右键傀儡来更换。 + * 对应 1.7.10 的 {@code ItemGolemWirelessBackpack.BackpackSkins}。 + */ +public enum BackpackSkins { + + Thaumium("Thaum"), + Stone("Stone"), + Straw("Straw"), + Wood("Wood"), + Flesh("Flesh"), + Clay("Clay"), + Iron("Iron"), + Tallow("Tallow"), + Gold("Gold"), + Diamond("Diamond"); + + public static final BackpackSkins[] VALUES = values(); + + /** 纹理文件 ID(不含路径和扩展名) */ + private final String texId; + + /** 延迟初始化的纹理 ResourceLocation */ + private ResourceLocation texture; + + BackpackSkins(String texId) { + this.texId = texId; + } + + /** + * 获取此皮肤的纹理 ResourceLocation。 + * 延迟初始化,避免在枚举构造期间调用 ThaumicEnergistics.MODID。 + */ + public ResourceLocation getTextureLocation() { + if (this.texture == null) { + this.texture = ResourceLocation.fromNamespaceAndPath( + ThaumicEnergistics.MODID, "textures/model/golemBackpack/" + this.texId + ".png"); + } + return this.texture; + } + + /** + * 从序号获取皮肤,越界时返回默认 Thaumium。 + */ + public static BackpackSkins fromOrdinal(int ordinal) { + if (ordinal < 0 || ordinal >= VALUES.length) { + return Thaumium; + } + return VALUES[ordinal]; + } +} diff --git a/src/main/java/thaumicenergistics/common/entities/FacadeToSkinMapping.java b/src/main/java/thaumicenergistics/common/entities/FacadeToSkinMapping.java new file mode 100644 index 0000000..53acf12 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/entities/FacadeToSkinMapping.java @@ -0,0 +1,84 @@ +package thaumicenergistics.common.entities; + +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.ResourceLocation; +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.Blocks; + +/** + * AE2 Facade → 背包皮肤映射。 + * 1.7.10 通过 ItemFacade.getBlock()/getMeta() 判断;1.21.1 解析 Facade 物品的底层方块。 + * 支持:Thaumium/Tallow/Wood/Flesh/Stone/Straw/Clay/Iron/Gold/Diamond(与 1.7.10 一致)。 + */ +public final class FacadeToSkinMapping { + + private FacadeToSkinMapping() {} + + /** + * 尝试从物品栈推断对应的背包皮肤。 + * + * 接受 AE2 Facade 物品或直接的方块物品。 + * + * @param stack 玩家手持的物品 + * @return 对应的皮肤,若不支持则返回 null + */ + public static BackpackSkins getSkinFromFacade(ItemStack stack) { + if (stack == null || stack.isEmpty()) { + return null; + } + + Block block = resolveFacadeBlock(stack); + if (block == null) { + return null; + } + + ResourceLocation blockId = BuiltInRegistries.BLOCK.getKey(block); + + // Thaumcraft 方块映射 + if (blockId.getNamespace().equals("thaumcraft")) { + String path = blockId.getPath(); + if (path.contains("thaumium") || path.contains("cosmetic_solid")) { + return BackpackSkins.Thaumium; + } + if (path.contains("tallow")) return BackpackSkins.Tallow; + if (path.contains("greatwood") || path.contains("magical_log")) return BackpackSkins.Wood; + if (path.contains("flesh") || path.contains("taint")) return BackpackSkins.Flesh; + } + + // 原版方块映射 + if (block == Blocks.STONE) return BackpackSkins.Stone; + if (block == Blocks.HAY_BLOCK) return BackpackSkins.Straw; + if (block == Blocks.BRICKS) return BackpackSkins.Clay; + if (block == Blocks.IRON_BLOCK) return BackpackSkins.Iron; + if (block == Blocks.GOLD_BLOCK) return BackpackSkins.Gold; + if (block == Blocks.DIAMOND_BLOCK) return BackpackSkins.Diamond; + + return null; + } + + /** + * 从物品栈解析对应方块:BlockItem 或 AE2 Facade(反射接口)。 + */ + private static Block resolveFacadeBlock(ItemStack stack) { + // 1) 直接是 BlockItem + if (stack.getItem() instanceof BlockItem blockItem) { + return blockItem.getBlock(); + } + + // 2) AE2 Facade 物品:尝试通过 IFacadeItem 接口获取纹理方块 + try { + if (stack.getItem() instanceof appeng.items.parts.FacadeItem facadeItem) { + net.minecraft.world.level.block.state.BlockState state = facadeItem.getTextureBlockState(stack); + if (state != null) { + return state.getBlock(); + } + } + } catch (Throwable ignored) { + // AE2 API 版本可能不兼容,静默忽略 + } + + return null; + } +} diff --git a/src/main/java/thaumicenergistics/common/entities/GolemBackpackHandler.java b/src/main/java/thaumicenergistics/common/entities/GolemBackpackHandler.java new file mode 100644 index 0000000..d93572b --- /dev/null +++ b/src/main/java/thaumicenergistics/common/entities/GolemBackpackHandler.java @@ -0,0 +1,265 @@ +package thaumicenergistics.common.entities; + +import java.util.Collections; +import java.util.Map; +import java.util.UUID; +import java.util.WeakHashMap; + +import net.minecraft.core.GlobalPos; +import net.minecraft.nbt.NbtOps; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent; +import thaumcraft.common.entities.golem.ThaumcraftGolemEntity; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.common.items.ItemGolemWirelessBackpack; +import thaumicenergistics.init.ModItems; + +/** + * 傀儡无线背包处理器:装备/拆卸/Facade 皮肤更换。 + * 对应 1.7.10 的 {@code WirelessGolemHandler} 中装备/Facade 交互部分。 + * 网络同步由 {@link thaumicenergistics.common.network.GolemBackpackSyncPacket} 处理。 + */ +@EventBusSubscriber(modid = ThaumicEnergistics.MODID) +public final class GolemBackpackHandler { + + private static final String NBT_KEY_LINK = "ThEWifiBackpackLink"; + /** NBT 键:背包皮肤序号(int) */ + private static final String NBT_KEY_SKIN = "ThEBackpackSkin"; + /** NBT 键:Facade 物品序列化 */ + private static final String NBT_KEY_FACADE = "ThEBackpackFacade"; + + /** + * 傀儡 UUID → 解码后的 home 位置缓存,避免每 tick 重复 GlobalPos.CODEC.parse NBT 解码。 + * 使用 WeakHashMap:golem 实体被 GC 后键自动回收,无泄漏;set/clear 时同步失效。 + */ + private static final Map LINK_CACHE = Collections.synchronizedMap(new WeakHashMap<>()); + + private GolemBackpackHandler() { + } + + @SubscribeEvent + public static void onEntityInteract(PlayerInteractEvent.EntityInteract event) { + if (!(event.getTarget() instanceof ThaumcraftGolemEntity golem)) { + return; + } + + Player player = event.getEntity(); + ItemStack held = player.getItemInHand(event.getHand()); + + if (held.isEmpty()) { + return; + } + + // 1) 手持无线背包物品 → 装备背包 + if (held.getItem() == ModItems.GOLEM_WIFI_BACKPACK.get()) { + if (event.getLevel().isClientSide()) { + event.setCancellationResult(InteractionResult.SUCCESS); + event.setCanceled(true); + return; + } + handleEquipBackpack(golem, player, held, event); + return; + } + + // 2) 手持 Golem 铃铛 + 蹲下 → 拆卸背包 + if (held.getItem() instanceof thaumcraft.common.items.GolemBellItem) { + if (event.getLevel().isClientSide()) { + return; + } + handleDismantleBackpack(golem, player, event); + return; + } + + // 3) 手持 AE2 Facade → 更换皮肤 + if (hasBackpack(golem)) { + BackpackSkins skin = FacadeToSkinMapping.getSkinFromFacade(held); + if (skin != null) { + if (event.getLevel().isClientSide()) { + event.setCancellationResult(InteractionResult.SUCCESS); + event.setCanceled(true); + return; + } + handleApplyFacade(golem, player, held, skin, event); + } + } + } + + private static void handleEquipBackpack(ThaumcraftGolemEntity golem, Player player, ItemStack held, + PlayerInteractEvent.EntityInteract event) { + if (!golem.isOwnedBy(player)) { + return; + } + + if (hasBackpack(golem)) { + return; + } + + ItemGolemWirelessBackpack backpackItem = (ItemGolemWirelessBackpack) held.getItem(); + GlobalPos linkedPos = backpackItem.getLinkedPosition(held); + if (linkedPos == null) { + return; + } + + setBackpackLink(golem, linkedPos); + // 默认皮肤为 Thaumium + setBackpackSkin(golem, BackpackSkins.Thaumium); + golem.level().playSound(null, golem.getX(), golem.getY(), golem.getZ(), + SoundEvents.ARMOR_EQUIP_LEATHER, SoundSource.NEUTRAL, 0.5F, 1.0F); + + if (!player.isCreative()) { + held.shrink(1); + } + + event.setCancellationResult(InteractionResult.SUCCESS); + event.setCanceled(true); + } + + private static void handleDismantleBackpack(ThaumcraftGolemEntity golem, Player player, + PlayerInteractEvent.EntityInteract event) { + if (!player.isShiftKeyDown()) { + return; + } + if (!golem.isOwnedBy(player)) { + return; + } + + GlobalPos linkedPos = getBackpackLink(golem); + if (linkedPos == null) { + return; + } + + ItemStack backpackStack = new ItemStack(ModItems.GOLEM_WIFI_BACKPACK.get()); + backpackStack.set(appeng.api.ids.AEComponents.WIRELESS_LINK_TARGET, linkedPos); + golem.spawnAtLocation(backpackStack); + + // 丢弃旧 Facade(如果有) + ItemStack oldFacade = getFacadeItem(golem); + if (!oldFacade.isEmpty() && !player.isCreative()) { + golem.spawnAtLocation(oldFacade); + } + + clearBackpackLink(golem); + clearBackpackSkin(golem); + clearFacadeItem(golem); + golem.level().playSound(null, golem.getX(), golem.getY(), golem.getZ(), + SoundEvents.ARMOR_EQUIP_LEATHER, SoundSource.NEUTRAL, 0.5F, 1.0F); + } + + /** + * 处理 Facade 皮肤更换。 + * 对应 1.7.10 的 {@code WirelessGolemHandler.customInteraction} 中的 Facade 分支。 + */ + private static void handleApplyFacade(ThaumcraftGolemEntity golem, Player player, ItemStack held, + BackpackSkins skin, PlayerInteractEvent.EntityInteract event) { + if (!golem.isOwnedBy(player)) { + return; + } + + ItemStack oldFacade = getFacadeItem(golem); + if (!oldFacade.isEmpty() && !player.isCreative()) { + golem.spawnAtLocation(oldFacade); + } + + ItemStack facadeCopy = held.copy(); + facadeCopy.setCount(1); + setFacadeItem(golem, facadeCopy); + + setBackpackSkin(golem, skin); + + if (!player.isCreative()) { + held.shrink(1); + } + + // 播放音效(对应 1.7.10 的 thaumcraft:cameraticks) + golem.level().playSound(null, golem.getX(), golem.getY(), golem.getZ(), + SoundEvents.ARMOR_EQUIP_LEATHER, SoundSource.NEUTRAL, 0.5F, 1.0F); + + event.setCancellationResult(InteractionResult.SUCCESS); + event.setCanceled(true); + } + + // ========== NBT 操作方法 ========== + + public static boolean hasBackpack(ThaumcraftGolemEntity golem) { + return golem.getPersistentData().contains(NBT_KEY_LINK); + } + + public static GlobalPos getBackpackLink(ThaumcraftGolemEntity golem) { + var tag = golem.getPersistentData(); + if (!tag.contains(NBT_KEY_LINK)) { + LINK_CACHE.remove(golem.getUUID()); + return null; + } + GlobalPos cached = LINK_CACHE.get(golem.getUUID()); + if (cached != null) { + return cached; + } + var linkTag = tag.getCompound(NBT_KEY_LINK); + GlobalPos decoded = GlobalPos.CODEC.parse(NbtOps.INSTANCE, linkTag).result().orElse(null); + if (decoded != null) { + LINK_CACHE.put(golem.getUUID(), decoded); + } + return decoded; + } + + public static void setBackpackLink(ThaumcraftGolemEntity golem, GlobalPos pos) { + var tag = golem.getPersistentData(); + GlobalPos.CODEC.encodeStart(NbtOps.INSTANCE, pos) + .result().ifPresent(encoded -> tag.put(NBT_KEY_LINK, encoded)); + LINK_CACHE.put(golem.getUUID(), pos); + } + + public static void clearBackpackLink(ThaumcraftGolemEntity golem) { + golem.getPersistentData().remove(NBT_KEY_LINK); + LINK_CACHE.remove(golem.getUUID()); + } + + public static BackpackSkins getBackpackSkin(ThaumcraftGolemEntity golem) { + int ordinal = golem.getPersistentData().getInt(NBT_KEY_SKIN); + return BackpackSkins.fromOrdinal(ordinal); + } + + public static void setBackpackSkin(ThaumcraftGolemEntity golem, BackpackSkins skin) { + golem.getPersistentData().putInt(NBT_KEY_SKIN, skin.ordinal()); + } + + /** + * 清除背包皮肤 NBT。 + */ + public static void clearBackpackSkin(ThaumcraftGolemEntity golem) { + golem.getPersistentData().remove(NBT_KEY_SKIN); + } + + /** + * 获取保存的 Facade 物品。 + */ + public static ItemStack getFacadeItem(ThaumcraftGolemEntity golem) { + var tag = golem.getPersistentData(); + if (!tag.contains(NBT_KEY_FACADE)) { + return ItemStack.EMPTY; + } + return ItemStack.parse(golem.level().registryAccess(), tag.getCompound(NBT_KEY_FACADE)) + .orElse(ItemStack.EMPTY); + } + + /** + * 保存 Facade 物品到 NBT。 + */ + public static void setFacadeItem(ThaumcraftGolemEntity golem, ItemStack facade) { + var encoded = (net.minecraft.nbt.CompoundTag) facade.save(golem.level().registryAccess()); + golem.getPersistentData().put(NBT_KEY_FACADE, encoded); + } + + /** + * 清除 Facade NBT。 + */ + public static void clearFacadeItem(ThaumcraftGolemEntity golem) { + golem.getPersistentData().remove(NBT_KEY_FACADE); + } +} diff --git a/src/main/java/thaumicenergistics/common/entities/GolemBackpackTickHandler.java b/src/main/java/thaumicenergistics/common/entities/GolemBackpackTickHandler.java new file mode 100644 index 0000000..f92d222 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/entities/GolemBackpackTickHandler.java @@ -0,0 +1,323 @@ +package thaumicenergistics.common.entities; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.GlobalPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.event.tick.EntityTickEvent; +import net.minecraft.world.Container; +import net.minecraft.world.level.Level; +import net.neoforged.neoforge.fluids.FluidStack; +import org.jetbrains.annotations.Nullable; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; +import thaumcraft.common.entities.golem.ThaumcraftGolemEntity; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.common.integration.tc.TCReflection; +import thaumicenergistics.common.network.GolemBackpackSyncPacket; +import net.neoforged.neoforge.network.PacketDistributor; + +/** + * 傀儡背包无线网络交互的 Tick 驱动 AI。 + * 按 1.7.10 的 AI 体系,根据傀儡核心类型执行不同 AE 网络操作: + * FILL(0)/GATHER(2) 物品、LIQUID(5) 流体、ESSENTIA(6) 源质。 + */ +@EventBusSubscriber(modid = ThaumicEnergistics.MODID) +public final class GolemBackpackTickHandler { + + /** + * 网络操作冷却时间(tick),与 1.7.10 {@code AIAENetworkGolem.NETWORK_COOLDOWN} 一致。 + */ + private static final int NETWORK_COOLDOWN = 20; + + /** + * 同步状态冷却时间(tick),与 1.7.10 的 18 tick 一致。 + */ + private static final int SYNC_COOLDOWN = 18; + + private GolemBackpackTickHandler() { + } + + @SubscribeEvent + public static void onEntityTick(EntityTickEvent.Post event) { + if (!(event.getEntity() instanceof ThaumcraftGolemEntity golem)) { + return; + } + + if (!(golem.level() instanceof ServerLevel)) { + return; + } + + if (!GolemBackpackHandler.hasBackpack(golem)) { + return; + } + + GlobalPos linkTarget = GolemBackpackHandler.getBackpackLink(golem); + if (linkTarget == null) { + return; + } + + // 同步背包连接状态到客户端(每 SYNC_COOLDOWN tick 一次) + syncBackpackStatus(golem, linkTarget); + + // 冷却检查:使用傀儡的 persistentData 存储冷却计时器 + int cooldown = golem.getPersistentData().getInt("ThEWifiCooldown"); + if (cooldown > 0) { + golem.getPersistentData().putInt("ThEWifiCooldown", cooldown - 1); + return; + } + + golem.getPersistentData().putInt("ThEWifiCooldown", NETWORK_COOLDOWN); + + WirelessAELinkGolem link = new WirelessAELinkGolem(golem, linkTarget); + if (!link.isConnected()) { + return; + } + + int maxRate = WirelessAELinkGolem.getMaxItemRate(golem); + + int core = golem.getCore(); + switch (core) { + case 0 -> doFill(golem, link, maxRate); + case 2 -> doGather(golem, link, maxRate); + case 5 -> doLiquid(golem, link); + case 6 -> doEssentia(golem, link); + default -> {} + } + } + + /** + * GATHER 核心 (ID=2): 傀儡手持物品时存入 AE 网络(对应 1.7.10 AIGolemWifiGather)。 + */ + private static void doGather(ThaumcraftGolemEntity golem, WirelessAELinkGolem link, int maxRate) { + ItemStack held = golem.carried(); + if (held.isEmpty()) { + return; + } + + link.depositStack(held, maxRate); + + if (held.isEmpty()) { + golem.setCarried(ItemStack.EMPTY); + golem.startActionTimer(); + } + } + + /** + * FILL 核心 (ID=0): 从 AE 网络提取物品给傀儡,用于填充 home 容器(对应 1.7.10 AIGolemWifiFill)。 + * 与 TC 原版 workFill() 的区别:原版从附近标记容器取物,无线背包版直接从 ME 网络取。 + */ + private static void doFill(ThaumcraftGolemEntity golem, WirelessAELinkGolem link, int maxRate) { + if (!golem.carried().isEmpty()) { + return; + } + + Container homeContainer = getHomeContainer(golem); + if (homeContainer == null) { + return; + } + + ItemStack filterToExtract = null; + int extractAmount = 0; + + for (int slot = 0; slot < 9; slot++) { + ItemStack filter = golem.getFilter(slot); + if (filter.isEmpty()) { + continue; + } + + int desired = Math.max(1, filter.getCount()); + int current = countInContainer(homeContainer, filter); + int needed = desired - current; + + if (needed <= 0) { + continue; + } + + if (!hasRoom(homeContainer, filter, golem.homeFacing())) { + continue; + } + + filterToExtract = filter.copyWithCount(1); + extractAmount = Math.min(needed, golem.carryLimit()); + break; + } + + if (filterToExtract == null) { + return; + } + + ItemStack request = filterToExtract.copyWithCount(extractAmount); + ItemStack extracted = link.extractStack(request, maxRate); + if (extracted != null && !extracted.isEmpty()) { + golem.setCarried(extracted); + golem.startActionTimer(); + } + } + + // ==================== 辅助方法 ==================== + + /** + * 获取傀儡 home 位置的容器(对应 TC 的 homeContainer())。 + */ + @Nullable + private static Container getHomeContainer(ThaumcraftGolemEntity golem) { + BlockPos home = golem.home(); + BlockPos apparatusPos = home.relative(golem.homeFacing().getOpposite()); + + Container container = containerAt(golem.level(), apparatusPos); + if (container != null) { + return container; + } + + return containerAt(golem.level(), home); + } + + @Nullable + private static Container containerAt(Level level, BlockPos pos) { + BlockEntity be = level.getBlockEntity(pos); + if (be instanceof Container container) { + return container; + } + return null; + } + + /** + * 计算容器中匹配物品的数量。 + * 对应 TC 的 {@code count()} 方法。 + */ + private static int countInContainer(Container container, ItemStack match) { + int count = 0; + for (int slot = 0; slot < container.getContainerSize(); slot++) { + ItemStack stack = container.getItem(slot); + if (ItemStack.isSameItemSameComponents(stack, match)) { + count += stack.getCount(); + } + } + return count; + } + + /** + * 检查容器是否还有空间放入指定物品(对应 TC 的 hasRoom())。 + */ + private static boolean hasRoom(Container container, ItemStack stack, Direction side) { + for (int slot = 0; slot < container.getContainerSize(); slot++) { + ItemStack existing = container.getItem(slot); + if (existing.isEmpty()) { + return true; + } + if (ItemStack.isSameItemSameComponents(existing, stack) && existing.getCount() < existing.getMaxStackSize()) { + return true; + } + } + return false; + } + + // ==================== 网络同步 ==================== + + /** + * 每 SYNC_COOLDOWN tick 发送背包连接状态 S2C 包(替代 1.7.10 DataWatcher 同步)。 + */ + private static void syncBackpackStatus(ThaumcraftGolemEntity golem, GlobalPos linkTarget) { + int syncCooldown = golem.getPersistentData().getInt("ThEWifiSyncCooldown"); + if (syncCooldown > 0) { + golem.getPersistentData().putInt("ThEWifiSyncCooldown", syncCooldown - 1); + return; + } + golem.getPersistentData().putInt("ThEWifiSyncCooldown", SYNC_COOLDOWN); + + WirelessAELinkGolem link = new WirelessAELinkGolem(golem, linkTarget); + boolean inRange = link.isConnected(); + int status = inRange + ? GolemBackpackSyncPacket.STATUS_IN_RANGE + : GolemBackpackSyncPacket.STATUS_OUT_OF_RANGE; + + BackpackSkins skin = GolemBackpackHandler.getBackpackSkin(golem); + + GolemBackpackSyncPacket packet = new GolemBackpackSyncPacket( + golem.getId(), status, skin.ordinal()); + PacketDistributor.sendToPlayersTrackingEntity(golem, packet); + } + + // ==================== LIQUID 核心 (ID=5) ==================== + + /** + * LIQUID 核心 (ID=5): 从 AE 网络提取流体给傀儡(对应 1.7.10 AIGolemWifiLiquid)。 + */ + private static void doLiquid(ThaumcraftGolemEntity golem, WirelessAELinkGolem link) { + FluidStack carried = golem.fluidCarried(); + if (!carried.isEmpty()) { + return; + } + + for (int slot = 0; slot < 9; slot++) { + ItemStack filter = golem.getFilter(slot); + if (filter.isEmpty()) continue; + + var fluidHandler = filter.getCapability(net.neoforged.neoforge.capabilities.Capabilities.FluidHandler.ITEM); + if (fluidHandler == null) continue; + + for (int tank = 0; tank < fluidHandler.getTanks(); tank++) { + FluidStack fluid = fluidHandler.getFluidInTank(tank); + if (fluid.isEmpty()) continue; + + int maxRate = WirelessAELinkGolem.getMaxFluidRate(golem); + int requestAmount = Math.min(golem.fluidCarryLimit(), maxRate); + FluidStack request = fluid.copyWithAmount(requestAmount); + FluidStack extracted = link.extractFluid(request, maxRate); + + if (extracted != null && !extracted.isEmpty()) { + golem.setFluidCarried(extracted); + golem.startActionTimer(); + return; + } + } + } + } + + // ==================== ESSENTIA 核心 (ID=6) ==================== + + /** + * ESSENTIA 核心 (ID=6): 傀儡与 AE 源质网络交互(对应 1.7.10 AIGolemWifiEssentia)。 + */ + private static void doEssentia(ThaumcraftGolemEntity golem, WirelessAELinkGolem link) { + Aspect aspect = golem.essentiaCarried(); + int amount = golem.essentiaAmount(); + + if (aspect != null && amount > 0) { + net.minecraft.resources.ResourceLocation aspectId = TCReflection.getAspectId(aspect); + int deposited = link.depositEssentia(aspectId, amount); + if (deposited > 0) { + int remaining = amount - deposited; + golem.setEssentiaCarried(remaining > 0 ? aspect : null, remaining); + golem.startActionTimer(); + } + return; + } + + for (int slot = 0; slot < 9; slot++) { + ItemStack filter = golem.getFilter(slot); + if (filter.isEmpty()) continue; + + if (filter.getItem() instanceof thaumcraft.api.aspects.IEssentiaContainerItem containerItem) { + AspectList aspectList = containerItem.getAspects(filter); + if (aspectList == null || aspectList.size() == 0) continue; + + for (Aspect filterAspect : aspectList.getAspects()) { + net.minecraft.resources.ResourceLocation aspectId = TCReflection.getAspectId(filterAspect); + int requestAmount = Math.min(golem.carryLimit(), WirelessAELinkGolem.getMaxEssentiaRate(golem)); + int extracted = link.extractEssentia(aspectId, requestAmount); + if (extracted > 0) { + golem.setEssentiaCarried(filterAspect, extracted); + golem.startActionTimer(); + return; + } + } + } + } + } +} diff --git a/src/main/java/thaumicenergistics/common/entities/WirelessAELinkGolem.java b/src/main/java/thaumicenergistics/common/entities/WirelessAELinkGolem.java new file mode 100644 index 0000000..4843531 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/entities/WirelessAELinkGolem.java @@ -0,0 +1,312 @@ +package thaumicenergistics.common.entities; + +import net.minecraft.core.GlobalPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import appeng.api.implementations.blockentities.IWirelessAccessPoint; +import appeng.api.networking.IGrid; +import appeng.api.networking.energy.IEnergyService; +import appeng.api.networking.security.IActionSource; +import appeng.api.stacks.AEFluidKey; +import appeng.api.stacks.AEItemKey; +import appeng.api.storage.MEStorage; +import appeng.api.storage.StorageHelper; +import appeng.blockentity.networking.WirelessAccessPointBlockEntity; +import appeng.util.Platform; +import net.neoforged.neoforge.fluids.FluidStack; +import org.jetbrains.annotations.Nullable; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.common.entities.golem.ThaumcraftGolemEntity; + +import java.util.Set; + +/** + * 傀儡与 AE2 无线网络的连接桥。 + * 提供物品/流体/源质的存取方法,供 {@link GolemBackpackTickHandler} 的 AI 逻辑调用。 + */ +public class WirelessAELinkGolem { + + private final ThaumcraftGolemEntity golem; + private final GlobalPos linkTarget; + private IGrid cachedGrid; + private IWirelessAccessPoint cachedAccessPoint; + private IActionSource actionSource; + private int tickCounter; + + public WirelessAELinkGolem(ThaumcraftGolemEntity golem, GlobalPos linkTarget) { + this.golem = golem; + this.linkTarget = linkTarget; + } + + @Nullable + public IGrid getGrid() { + tickCounter++; + if (tickCounter % 20 == 0 || cachedGrid == null) { + updateConnection(); + } + return cachedGrid; + } + + public boolean isConnected() { + return getGrid() != null; + } + + // ==================== 物品网络操作 ==================== + + /** + * 获取 AE2 网络的物品存储(MEStorage 同时处理物品和流体)。 + */ + @Nullable + public MEStorage getItemInventory() { + IGrid grid = getGrid(); + if (grid == null) return null; + return grid.getStorageService().getInventory(); + } + + @Nullable + public IEnergyService getEnergyService() { + IGrid grid = getGrid(); + if (grid == null) return null; + return grid.getEnergyService(); + } + + /** + * 将物品存入 AE 网络。 + * 使用 {@link StorageHelper#poweredInsert} 确保有足够能量时才存入。 + * + * @param stack 要存入的物品(调用后 count 会被减少) + * @param maxRate 每次操作最大存入数量 + */ + public void depositStack(ItemStack stack, int maxRate) { + MEStorage storage = getItemInventory(); + if (storage == null) return; + IEnergyService energy = getEnergyService(); + if (energy == null) return; + if (actionSource == null) return; + AEItemKey what = AEItemKey.of(stack); + if (what == null) return; + long depositSize = Math.min(stack.getCount(), maxRate); + long inserted = StorageHelper.poweredInsert(energy, storage, what, depositSize, actionSource); + stack.shrink((int) inserted); + } + + /** + * 从 AE 网络提取物品。 + * 使用 {@link StorageHelper#poweredExtraction} 确保有足够能量时才提取。 + * + * @param target 要提取的物品模板(数量为期望数量) + * @param maxRate 每次操作最大提取数量 + * @return 提取出的 ItemStack,可能为 null + */ + @Nullable + public ItemStack extractStack(ItemStack target, int maxRate) { + MEStorage storage = getItemInventory(); + if (storage == null) return null; + IEnergyService energy = getEnergyService(); + if (energy == null) return null; + if (actionSource == null) return null; + AEItemKey what = AEItemKey.of(target); + if (what == null) return null; + long requestSize = Math.min(target.getCount(), maxRate); + long extracted = StorageHelper.poweredExtraction(energy, storage, what, requestSize, actionSource); + if (extracted <= 0) return null; + return what.toStack((int) extracted); + } + + // ==================== 流体网络操作 ==================== + + /** + * 从 AE 网络提取流体。 + * + * @param target 要提取的流体模板 + * @param maxRateMb 每次操作最大提取量(mB) + * @return 提取出的 FluidStack,可能为 null + */ + @Nullable + public FluidStack extractFluid(FluidStack target, int maxRateMb) { + MEStorage storage = getItemInventory(); + if (storage == null) return null; + IEnergyService energy = getEnergyService(); + if (energy == null) return null; + if (actionSource == null) return null; + AEFluidKey what = AEFluidKey.of(target); + if (what == null) return null; + long requestSize = Math.min(target.getAmount(), maxRateMb); + long extracted = StorageHelper.poweredExtraction(energy, storage, what, requestSize, actionSource); + if (extracted <= 0) return null; + return what.toStack((int) extracted); + } + + /** + * 将流体存入 AE 网络。 + * + * @param fluid 流体栈(调用后 amount 会被减少) + * @param maxRateMb 每次操作最大存入量(mB) + */ + public void depositFluid(FluidStack fluid, int maxRateMb) { + MEStorage storage = getItemInventory(); + if (storage == null) return; + IEnergyService energy = getEnergyService(); + if (energy == null) return; + if (actionSource == null) return; + AEFluidKey what = AEFluidKey.of(fluid); + if (what == null) return; + long depositSize = Math.min(fluid.getAmount(), maxRateMb); + long inserted = StorageHelper.poweredInsert(energy, storage, what, depositSize, actionSource); + fluid.shrink((int) inserted); + } + + // ==================== 源质网络操作 ==================== + + @Nullable + public thaumicenergistics.api.grid.IEssentiaGrid getEssentiaGrid() { + IGrid grid = getGrid(); + if (grid == null) return null; + return grid.getService(thaumicenergistics.api.grid.IEssentiaGrid.class); + } + + /** + * 从 AE 网络提取源质。 + * + * @param aspectId 源质 ID(ResourceLocation,如 "thaumcraft:ignis") + * @param maxAmount 最大提取量 + * @return 实际提取的量 + */ + public int extractEssentia(net.minecraft.resources.ResourceLocation aspectId, int maxAmount) { + thaumicenergistics.api.grid.IEssentiaGrid essentiaGrid = getEssentiaGrid(); + if (essentiaGrid == null) return 0; + if (actionSource == null) return 0; + + int maxRate = getMaxEssentiaRate(golem); + int toExtract = Math.min(maxAmount, maxRate); + return (int) essentiaGrid.extractEssentia(aspectId, toExtract, false); + } + + /** + * 将源质存入 AE 网络。 + * + * @param aspectId 源质 ID(ResourceLocation) + * @param amount 要存入的量 + * @return 实际存入的量 + */ + public int depositEssentia(net.minecraft.resources.ResourceLocation aspectId, int amount) { + thaumicenergistics.api.grid.IEssentiaGrid essentiaGrid = getEssentiaGrid(); + if (essentiaGrid == null) return 0; + if (actionSource == null) return 0; + + int maxRate = getMaxEssentiaRate(golem); + int toDeposit = Math.min(amount, maxRate); + long rejected = essentiaGrid.injectEssentia(aspectId, toDeposit, false); + return toDeposit - (int) rejected; + } + + // ==================== 连接管理 ==================== + + private void updateConnection() { + cachedGrid = null; + cachedAccessPoint = null; + actionSource = null; + + Level level = golem.level(); + if (!(level instanceof ServerLevel serverLevel)) { + return; + } + + var linkedLevel = serverLevel.getServer().getLevel(linkTarget.dimension()); + if (linkedLevel == null) { + return; + } + + var be = Platform.getTickingBlockEntity(linkedLevel, linkTarget.pos()); + if (!(be instanceof IWirelessAccessPoint accessPoint)) { + return; + } + + IGrid grid = accessPoint.getGrid(); + if (grid == null) { + return; + } + + if (!isInRange(serverLevel, grid)) { + return; + } + + cachedGrid = grid; + cachedAccessPoint = accessPoint; + + // 创建 ActionSource:使用 AP 作为 MachineSource + if (accessPoint instanceof appeng.api.networking.security.IActionHost actionHost) { + actionSource = IActionSource.ofMachine(actionHost); + } + } + + private boolean isInRange(ServerLevel level, IGrid grid) { + Set accessPoints = grid.getActiveMachines(WirelessAccessPointBlockEntity.class); + if (accessPoints.isEmpty()) { + return false; + } + + double golemX = golem.getX(); + double golemY = golem.getY(); + double golemZ = golem.getZ(); + + for (WirelessAccessPointBlockEntity ap : accessPoints) { + if (!ap.isActive()) { + continue; + } + + var dc = ap.getLocation(); + if (dc.getLevel() != level) { + continue; + } + + double range = ap.getRange(); + double dx = dc.getPos().getX() - golemX; + double dy = dc.getPos().getY() - golemY; + double dz = dc.getPos().getZ() - golemZ; + double sqDist = dx * dx + dy * dy + dz * dz; + + if (sqDist <= range * range) { + return true; + } + } + + return false; + } + + // ==================== 速率计算 ==================== + + /** + * 物品交互速率(按 1.7.10 AIAENetworkGolem 速率表)。 + * 基础: 8/24/32,高级傀儡 ×2 + */ + public static int getMaxItemRate(ThaumcraftGolemEntity golem) { + int[] ITEM_RATES = {8, 24, 32}; + int rateMult = golem.isAdvanced() ? 2 : 1; + int orderUpgrades = Math.max(0, Math.min(2, golem.getUpgradeAmount(2))); + return ITEM_RATES[orderUpgrades] * rateMult; + } + + /** + * 流体交互速率(按 1.7.10 AIAENetworkGolem 速率表)。 + * 基础: 100/250/500 mB,高级傀儡 ×2 + */ + public static int getMaxFluidRate(ThaumcraftGolemEntity golem) { + int[] FLUID_RATES = {100, 250, 500}; + int rateMult = golem.isAdvanced() ? 2 : 1; + int orderUpgrades = Math.max(0, Math.min(2, golem.getUpgradeAmount(2))); + return FLUID_RATES[orderUpgrades] * rateMult; + } + + /** + * 源质交互速率(按 1.7.10 AIAENetworkGolem 速率表)。 + * 基础: 4/12/16,高级傀儡 ×2 + */ + public static int getMaxEssentiaRate(ThaumcraftGolemEntity golem) { + int[] ESS_RATES = {4, 12, 16}; + int rateMult = golem.isAdvanced() ? 2 : 1; + int orderUpgrades = Math.max(0, Math.min(2, golem.getUpgradeAmount(2))); + return ESS_RATES[orderUpgrades] * rateMult; + } +} diff --git a/src/main/java/thaumicenergistics/common/features/FeatureAutocraftingArcane.java b/src/main/java/thaumicenergistics/common/features/FeatureAutocraftingArcane.java new file mode 100644 index 0000000..341e14f --- /dev/null +++ b/src/main/java/thaumicenergistics/common/features/FeatureAutocraftingArcane.java @@ -0,0 +1,21 @@ +package thaumicenergistics.common.features; + +/** + * 功能:奥术自动合成。 + * 启用奥术装配器及相关合成样板。 + * 自 1.7.10 FeatureAutocrafting_Arcane 移植(约 7k 行)。 + */ +public class FeatureAutocraftingArcane extends ThEFeatureBase { + public FeatureAutocraftingArcane() { super("arcane_crafting_terminal"); } + + @Override + protected void doRegister() { + // Arcane Assembler 方块经 ModBlocks 注册 + // TODO: Register arcane crafting pattern encoder, crafting CPU integration + } + + @Override + protected void doPostInit() { + // TODO: Register arcane crafting recipes, research entries + } +} diff --git a/src/main/java/thaumicenergistics/common/features/FeatureCells.java b/src/main/java/thaumicenergistics/common/features/FeatureCells.java new file mode 100644 index 0000000..847a44e --- /dev/null +++ b/src/main/java/thaumicenergistics/common/features/FeatureCells.java @@ -0,0 +1,20 @@ +package thaumicenergistics.common.features; + +/** + * 源质存储元件功能。 + * 注册 cell 物品、元件工作台与存储组件物品。 + * 自 1.7.10 FeatureCells 移植(约 12k 行)。 + */ +public class FeatureCells extends ThEFeatureBase { + public FeatureCells() { super("cells"); } + + @Override + protected void doRegister() { + // 物品经 init 包的 ModItems 注册——本功能校验其存在 + } + + @Override + protected void doPostInit() { + // TODO: Register cell recipes, research entries, cell workbench functionality + } +} diff --git a/src/main/java/thaumicenergistics/common/features/FeatureEssentiaIOBuses.java b/src/main/java/thaumicenergistics/common/features/FeatureEssentiaIOBuses.java new file mode 100644 index 0000000..1e41d65 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/features/FeatureEssentiaIOBuses.java @@ -0,0 +1,35 @@ +package thaumicenergistics.common.features; + +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.init.ModItems; + +/** + * 功能:源质 IO 总线。 + * 启用源质输入/输出/存储总线Part部件 + * Part注册已移至模组主类ThaumicEnergistics构造方法中, + * 通过AE2官方PartHelper.registerPart() API完成, + * 本Feature负责功能开关、配方注册、研究数据等跨模组集成内容。 + */ +public class FeatureEssentiaIOBuses extends ThEFeatureBase { + public FeatureEssentiaIOBuses() { super("io_buses"); } + + @Override + protected void doRegister() { + // ===== Part核心注册已在ThaumicEnergistics构造方法中完成 ===== + // 原因:AE2 PartHelper.registerPart()需要DeferredItem注册完成后立即调用, + // Feature.register()的调用时机同样满足,但为了集中管理Part注册入口,统一在主类中处理。 + + // ===== 以下登记本Feature涉及的物品,供跨模组引用追踪 ===== + ThaumicEnergistics.LOG.info(" -> EssentiaImportBus PartItem: {} (ready)", + ModItems.ESSENTIA_IMPORT_BUS.getId()); + ThaumicEnergistics.LOG.info(" -> EssentiaExportBus PartItem: {} (pending)", + ModItems.ESSENTIA_EXPORT_BUS.getId()); + ThaumicEnergistics.LOG.info(" -> EssentiaStorageBus PartItem: {} (pending)", + ModItems.ESSENTIA_STORAGE_BUS.getId()); + } + + @Override + protected void doPostInit() { + // 后置初始化:注册神秘时代研究条目、AE2合成配方等 + } +} \ No newline at end of file diff --git a/src/main/java/thaumicenergistics/common/features/FeatureEssentiaMonitoring.java b/src/main/java/thaumicenergistics/common/features/FeatureEssentiaMonitoring.java new file mode 100644 index 0000000..c8643c2 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/features/FeatureEssentiaMonitoring.java @@ -0,0 +1,15 @@ +package thaumicenergistics.common.features; + +/** + * 源质监控功能。 + * 启用源质水平检测器、存储监控器与转换监控器部件。 + * 自 1.7.10 FeatureEssentiaMonitoring 移植(约 6k 行)。 + */ +public class FeatureEssentiaMonitoring extends ThEFeatureBase { + public FeatureEssentiaMonitoring() { super("monitoring"); } + + @Override + protected void doRegister() { + // TODO: Register monitoring-related parts when AE2 part API is integrated + } +} diff --git a/src/main/java/thaumicenergistics/common/features/FeatureEssentiaProvider.java b/src/main/java/thaumicenergistics/common/features/FeatureEssentiaProvider.java new file mode 100644 index 0000000..6f44f33 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/features/FeatureEssentiaProvider.java @@ -0,0 +1,7 @@ +package thaumicenergistics.common.features; + +/** 功能:源质供应器。从 AE 网络核心抽取源质。 */ +public class FeatureEssentiaProvider extends ThEFeatureBase { + public FeatureEssentiaProvider() { super("essentia_provider"); } + @Override protected void doRegister() {} +} diff --git a/src/main/java/thaumicenergistics/common/features/FeatureEssentiaVibrationChamber.java b/src/main/java/thaumicenergistics/common/features/FeatureEssentiaVibrationChamber.java new file mode 100644 index 0000000..b307efe --- /dev/null +++ b/src/main/java/thaumicenergistics/common/features/FeatureEssentiaVibrationChamber.java @@ -0,0 +1,21 @@ +package thaumicenergistics.common.features; + +/** + * 功能:源质谐振仓。 + * 启用基于源质的能量生产。 + * 自 1.7.10 FeatureEssentiaVibrationChamber 移植(约 4k 行)。 + */ +public class FeatureEssentiaVibrationChamber extends ThEFeatureBase { + public FeatureEssentiaVibrationChamber() { super("vibration_chamber"); } + + @Override + protected void doRegister() { + // EVC 方块经 ModBlocks 注册 + // TODO: Register fuel values for each essentia type + } + + @Override + protected void doPostInit() { + // TODO: Register EVC recipe, research entry + } +} diff --git a/src/main/java/thaumicenergistics/common/features/FeatureGolemBackpack.java b/src/main/java/thaumicenergistics/common/features/FeatureGolemBackpack.java new file mode 100644 index 0000000..c749d40 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/features/FeatureGolemBackpack.java @@ -0,0 +1,11 @@ +package thaumicenergistics.common.features; + +/** 功能:无线傀儡背包。启用傀儡访问 AE 网络。 */ +public class FeatureGolemBackpack extends ThEFeatureBase { + public FeatureGolemBackpack() { super("golem_backpack"); } + + @Override + protected void doRegister() { + // GridLinkables 注册在 commonSetup 阶段完成(需要物品已绑定) + } +} \ No newline at end of file diff --git a/src/main/java/thaumicenergistics/common/features/FeatureInfusionProvider.java b/src/main/java/thaumicenergistics/common/features/FeatureInfusionProvider.java new file mode 100644 index 0000000..eb21d5e --- /dev/null +++ b/src/main/java/thaumicenergistics/common/features/FeatureInfusionProvider.java @@ -0,0 +1,16 @@ +package thaumicenergistics.common.features; + +/** + * 功能:注魔供应器。 + * 为 TC 注魔自动供应源质。 + * 自 1.7.10 FeatureInfusionProvider 移植(约 4k 行)。 + */ +public class FeatureInfusionProvider extends ThEFeatureBase { + public FeatureInfusionProvider() { super("infusion_provider"); } + + @Override + protected void doRegister() { + // Infusion Provider 方块经 ModBlocks 注册 + // TODO: Register infusion detection and essentia delivery logic + } +} diff --git a/src/main/java/thaumicenergistics/common/features/FeatureRegistry.java b/src/main/java/thaumicenergistics/common/features/FeatureRegistry.java new file mode 100644 index 0000000..a4d3d31 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/features/FeatureRegistry.java @@ -0,0 +1,17 @@ +package thaumicenergistics.common.features; + +import thaumicenergistics.ThaumicEnergistics; + +public final class FeatureRegistry { + private FeatureRegistry() {} + private static final ThEFeatureBase[] FEATURES = { + new FeatureCells(), new FeatureEssentiaIOBuses(), new FeatureEssentiaMonitoring(), + new FeatureEssentiaVibrationChamber(), new FeatureInfusionProvider(), + new FeatureAutocraftingArcane(), new FeatureVisRelayInterface(), + new FeatureGolemBackpack(), new FeatureEssentiaProvider() + }; + public static void registerAll() { + for (var f : FEATURES) { ThaumicEnergistics.LOG.info("Feature [{}] {}", f.getName(), f.isEnabled() ? "enabled":"disabled"); f.register(); } + } + public static void postInitAll() { for (var f : FEATURES) f.postInit(); } +} diff --git a/src/main/java/thaumicenergistics/common/features/FeatureVisRelayInterface.java b/src/main/java/thaumicenergistics/common/features/FeatureVisRelayInterface.java new file mode 100644 index 0000000..a52ba0b --- /dev/null +++ b/src/main/java/thaumicenergistics/common/features/FeatureVisRelayInterface.java @@ -0,0 +1,17 @@ +package thaumicenergistics.common.features; + +import appeng.api.features.P2PTunnelAttunement; +import thaumicenergistics.init.ModItems; + +public class FeatureVisRelayInterface extends ThEFeatureBase { + public FeatureVisRelayInterface() { super("vis_interface"); } + + @Override + protected void doRegister() { + P2PTunnelAttunement.registerAttunementTag(ModItems.VIS_INTERFACE.get()); + } + + @Override + protected void doPostInit() { + } +} diff --git a/src/main/java/thaumicenergistics/common/features/RecipeRegistration.java b/src/main/java/thaumicenergistics/common/features/RecipeRegistration.java new file mode 100644 index 0000000..3fd6929 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/features/RecipeRegistration.java @@ -0,0 +1,379 @@ +package thaumicenergistics.common.features; + +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagKey; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.block.Blocks; +import thaumcraft.api.ThaumcraftApi; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; +import thaumcraft.api.crafting.CrucibleRecipe; +import thaumcraft.api.crafting.InfusionRecipe; +import thaumcraft.api.crafting.ShapedArcaneRecipe; +import thaumcraft.api.crafting.ShapelessArcaneRecipe; +import thaumcraft.common.vis.TCVisHelper; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.init.ModBlocks; +import thaumicenergistics.init.ModItems; + +public final class RecipeRegistration { + private RecipeRegistration() {} + + // ==================== 配方引用(供研究页面使用) ==================== + // 注魔配方 + public static InfusionRecipe ESSENTIA_PROVIDER; + public static InfusionRecipe INFUSION_PROVIDER; + public static InfusionRecipe ARCANE_ASSEMBLER; + // 奥术有序配方 + public static ShapedArcaneRecipe STORAGE_COMPONENT_1K; + public static ShapedArcaneRecipe STORAGE_COMPONENT_4K; + public static ShapedArcaneRecipe STORAGE_COMPONENT_16K; + public static ShapedArcaneRecipe STORAGE_COMPONENT_64K; + public static ShapedArcaneRecipe KNOWLEDGE_CORE_ITEM; + public static ShapedArcaneRecipe FOCUS_AEWRENCH_RECIPE; + public static ShapedArcaneRecipe GOLEM_WIFI_BACKPACK_RECIPE; + public static ShapedArcaneRecipe ESSENTIA_IMPORT_BUS; + public static ShapedArcaneRecipe ESSENTIA_EXPORT_BUS; + public static ShapedArcaneRecipe ESSENTIA_STORAGE_BUS; + public static ShapedArcaneRecipe KNOWLEDGE_INSCRIBER_BLOCK; + public static ShapedArcaneRecipe DISTILLATION_ENCODER_BLOCK; + // 奥术无序配方 + public static ShapelessArcaneRecipe DIFFUSION_CORE; + public static ShapelessArcaneRecipe COALESCENCE_CORE; + public static ShapelessArcaneRecipe ESSENTIA_LEVEL_EMITTER; + public static ShapelessArcaneRecipe ESSENTIA_TERMINAL; + public static ShapelessArcaneRecipe ARCANE_CRAFTING_TERMINAL; + public static ShapelessArcaneRecipe VIS_INTERFACE; + public static ShapelessArcaneRecipe ESSENTIA_VIBRATION_CHAMBER; + + private static final TagKey WISP_ESSENCES = tag("thaumicenergistics", "wisp_essences"); + + @SuppressWarnings("SameParameterValue") + private static TagKey tag(String ns, String path) { + return TagKey.create(Registries.ITEM, ResourceLocation.fromNamespaceAndPath(ns, path)); + } + + public static void registerAll() { + registerShapedArcane(); + registerShapelessArcane(); + registerInfusion(); + ThaumicEnergistics.LOG.info("ThaumicEnergistics recipes registered."); + } + + private static void registerShapedArcane() { + STORAGE_COMPONENT_1K = ThaumcraftApi.addArcaneCraftingRecipe("ESSENTIASTORAGE1K", stack(ModItems.STORAGE_COMPONENT_1K), + new AspectList().add(Aspect.FIRE, 3).add(Aspect.ORDER, 1), + "EQ ", + "QPQ", + " QE", + 'E', WISP_ESSENCES, + 'Q', ae("certus_quartz_crystal"), + 'P', ae("logic_processor")); + + STORAGE_COMPONENT_4K = ThaumcraftApi.addArcaneCraftingRecipe("ESSENTIASTORAGE4K", stack(ModItems.STORAGE_COMPONENT_4K), + new AspectList().add(Aspect.FIRE, 3).add(Aspect.ORDER, 2), + "EPE", + "1G1", + "E1E", + 'E', WISP_ESSENCES, + 'P', ae("calculation_processor"), + '1', stack(ModItems.STORAGE_COMPONENT_1K), + 'G', ae("quartz_glass")); + + STORAGE_COMPONENT_16K = ThaumcraftApi.addArcaneCraftingRecipe("ESSENTIASTORAGE16K", stack(ModItems.STORAGE_COMPONENT_16K), + new AspectList().add(Aspect.FIRE, 3).add(Aspect.ORDER, 4), + "SPE", + "4G4", + "E4S", + 'S', tc("salis_mundus"), + 'P', ae("engineering_processor"), + '4', stack(ModItems.STORAGE_COMPONENT_4K), + 'G', ae("quartz_glass"), + 'E', WISP_ESSENCES); + + STORAGE_COMPONENT_64K = ThaumcraftApi.addArcaneCraftingRecipe("ESSENTIASTORAGE64K", stack(ModItems.STORAGE_COMPONENT_64K), + new AspectList().add(Aspect.FIRE, 3).add(Aspect.ORDER, 8), + "SPS", + "6G6", + "S6S", + 'S', tc("salis_mundus"), + 'P', ae("engineering_processor"), + '6', stack(ModItems.STORAGE_COMPONENT_16K), + 'G', ae("quartz_glass")); + + KNOWLEDGE_CORE_ITEM = ThaumcraftApi.addArcaneCraftingRecipe("KNOWLEDGEINSCRIBER", stack(ModItems.KNOWLEDGE_CORE), + new AspectList().add(Aspect.WATER, 3).add(Aspect.ORDER, 3).add(Aspect.EARTH, 1), + "QlQ", + "lBl", + "QPQ", + 'Q', ae("quartz_glass"), + 'l', new ItemStack(Items.LAPIS_LAZULI, 4), + 'B', tc("zombie_brain"), + 'P', ae("calculation_processor")); + + FOCUS_AEWRENCH_RECIPE = ThaumcraftApi.addArcaneCraftingRecipe("FOCUS_AEWRENCH", stack(ModItems.FOCUS_AEWRENCH), + new AspectList().add(Aspect.AIR, 10).add(Aspect.FIRE, 10), + "AqF", + "qWq", + "FqA", + 'A', tc("air_shard"), + 'q', new ItemStack(Items.QUARTZ, 4), + 'F', tc("fire_shard"), + 'W', ae("certus_quartz_wrench")); + + GOLEM_WIFI_BACKPACK_RECIPE = ThaumcraftApi.addArcaneCraftingRecipe("GOLEMWIFI", stack(ModItems.GOLEM_WIFI_BACKPACK), + new AspectList().add(Aspect.AIR, 6).add(Aspect.FIRE, 4).add(Aspect.ORDER, 3), + "tIt", + "nRn", + "fCf", + 't', tc("thaumium_ingot"), + 'I', ae("interface"), + 'n', tc("nitor"), + 'R', ae("wireless_receiver"), + 'f', ae("fluix_crystal"), + 'C', ae("charger")); + + ESSENTIA_IMPORT_BUS = ThaumcraftApi.addArcaneCraftingRecipe("ESSENTIABUSES", stack(ModItems.ESSENTIA_IMPORT_BUS), + new AspectList().add(Aspect.FIRE, 2).add(Aspect.EARTH, 2).add(Aspect.WATER, 1), + "JDJ", + "IFI", + " ", + 'J', tc("warded_jar"), + 'D', stack(ModItems.DIFFUSION_CORE), + 'I', new ItemStack(Items.IRON_INGOT, 2), + 'F', tc("essentia_filter")); + + ESSENTIA_EXPORT_BUS = ThaumcraftApi.addArcaneCraftingRecipe("ESSENTIABUSES", stack(ModItems.ESSENTIA_EXPORT_BUS), + new AspectList().add(Aspect.FIRE, 2).add(Aspect.EARTH, 2).add(Aspect.WATER, 1), + "JCJ", + "IFI", + " ", + 'J', tc("warded_jar"), + 'C', stack(ModItems.COALESCENCE_CORE), + 'I', new ItemStack(Items.IRON_INGOT, 2), + 'F', tc("essentia_filter")); + + ESSENTIA_STORAGE_BUS = ThaumcraftApi.addArcaneCraftingRecipe("ESSENTIABUSES", stack(ModItems.ESSENTIA_STORAGE_BUS), + new AspectList().add(Aspect.EARTH, 3).add(Aspect.FIRE, 3).add(Aspect.WATER, 3), + "DCF", + "IGI", + " ", + 'D', stack(ModItems.DIFFUSION_CORE), + 'C', stack(ModItems.COALESCENCE_CORE), + 'F', tc("essentia_filter"), + 'I', new ItemStack(Items.IRON_INGOT, 2), + 'G', ae("quartz_glass")); + + KNOWLEDGE_INSCRIBER_BLOCK = ThaumcraftApi.addArcaneCraftingRecipe("KNOWLEDGEINSCRIBER", stack(ModBlocks.KNOWLEDGE_INSCRIBER), + new AspectList().add(Aspect.WATER, 5).add(Aspect.EARTH, 5).add(Aspect.FIRE, 5).add(Aspect.AIR, 5).add(Aspect.ORDER, 5).add(Aspect.ENTROPY, 5), + "ILI", + " T ", + "IPI", + 'I', new ItemStack(Items.IRON_INGOT, 4), + 'L', ae("monitor"), + 'T', tc("thaumonomicon"), + 'P', ae("logic_processor")); + + ThaumcraftApi.addArcaneCraftingRecipe("KNOWLEDGEINSCRIBER", stack(ModBlocks.KNOWLEDGE_INSCRIBER), + new AspectList().add(Aspect.WATER, 5).add(Aspect.EARTH, 5).add(Aspect.FIRE, 5).add(Aspect.AIR, 5).add(Aspect.ORDER, 5).add(Aspect.ENTROPY, 5), + "ILI", + " T ", + "IPI", + 'I', new ItemStack(Items.IRON_INGOT, 4), + 'L', ae("dark_monitor"), + 'T', tc("thaumonomicon"), + 'P', ae("logic_processor")); + + ThaumcraftApi.addArcaneCraftingRecipe("KNOWLEDGEINSCRIBER", stack(ModBlocks.KNOWLEDGE_INSCRIBER), + new AspectList().add(Aspect.WATER, 5).add(Aspect.EARTH, 5).add(Aspect.FIRE, 5).add(Aspect.AIR, 5).add(Aspect.ORDER, 5).add(Aspect.ENTROPY, 5), + "ILI", + " T ", + "IPI", + 'I', new ItemStack(Items.IRON_INGOT, 4), + 'L', ae("semi_dark_monitor"), + 'T', tc("thaumonomicon"), + 'P', ae("logic_processor")); + + + DISTILLATION_ENCODER_BLOCK = ThaumcraftApi.addArcaneCraftingRecipe("DISTILLATIONENCODER", stack(ModBlocks.DISTILLATION_ENCODER), + new AspectList().add(Aspect.ORDER, 5).add(Aspect.ENTROPY, 5).add(Aspect.FIRE, 3), + "ILI", + " G ", + "IPI", + 'I', new ItemStack(Items.IRON_INGOT, 4), + 'L', ae("monitor"), + 'G', tc("thaumometer"), + 'P', ae("engineering_processor")); + + ThaumcraftApi.addArcaneCraftingRecipe("DISTILLATIONENCODER", stack(ModBlocks.DISTILLATION_ENCODER), + new AspectList().add(Aspect.ORDER, 5).add(Aspect.ENTROPY, 5).add(Aspect.FIRE, 3), + "ILI", + " G ", + "IPI", + 'I', new ItemStack(Items.IRON_INGOT, 4), + 'L', ae("dark_monitor"), + 'G', tc("thaumometer"), + 'P', ae("engineering_processor")); + + ThaumcraftApi.addArcaneCraftingRecipe("DISTILLATIONENCODER", stack(ModBlocks.DISTILLATION_ENCODER), + new AspectList().add(Aspect.ORDER, 5).add(Aspect.ENTROPY, 5).add(Aspect.FIRE, 3), + "ILI", + " G ", + "IPI", + 'I', new ItemStack(Items.IRON_INGOT, 4), + 'L', ae("semi_dark_monitor"), + 'G', tc("thaumometer"), + 'P', ae("engineering_processor")); + } + + + private static void registerShapelessArcane() { + // 1. 扩散核心 + DIFFUSION_CORE = ThaumcraftApi.addShapelessArcaneCraftingRecipe("DIGISENTIA", stack(ModItems.DIFFUSION_CORE), + new AspectList().add(Aspect.WATER, 2).add(Aspect.ENTROPY, 2), + tc("quicksilver"), + tc("quicksilver"), + tc("quicksilver"), + tc("entropy_shard"), + ae("annihilation_core")); + + // 2. 凝聚核心 + COALESCENCE_CORE = ThaumcraftApi.addShapelessArcaneCraftingRecipe("DIGISENTIA", stack(ModItems.COALESCENCE_CORE), + new AspectList().add(Aspect.WATER, 2).add(Aspect.ORDER, 2), + tc("quicksilver"), + tc("quicksilver"), + tc("quicksilver"), + tc("order_shard"), + ae("formation_core")); + + // 3. 原质等级发射器 + ESSENTIA_LEVEL_EMITTER = ThaumcraftApi.addShapelessArcaneCraftingRecipe("ESSENTIAMONITORING", new ItemStack(ModItems.ESSENTIA_LEVEL_EMITTER.get(), 1), + new AspectList().add(Aspect.FIRE, 4), + ae("calculation_processor"), + new ItemStack(Items.REDSTONE_TORCH), + tc("salis_mundus")); + + // 4. 原质终端 + ESSENTIA_TERMINAL = ThaumcraftApi.addShapelessArcaneCraftingRecipe("ESSENTIATERMINAL", stack(ModItems.ESSENTIA_TERMINAL_ITEM), + new AspectList().add(Aspect.WATER, 5).add(Aspect.ORDER, 2).add(Aspect.FIRE, 1), + //'ae2:semi_dark_monitor' 'ae2:monitor' 'ae2:dark_monitor'三者任一 + ae("monitor"), + stack(ModItems.DIFFUSION_CORE), + stack(ModItems.COALESCENCE_CORE), + ae("logic_processor"), + tc("vis_filter")); + + ThaumcraftApi.addShapelessArcaneCraftingRecipe("ESSENTIATERMINAL", stack(ModItems.ESSENTIA_TERMINAL_ITEM), + new AspectList().add(Aspect.WATER, 5).add(Aspect.ORDER, 2).add(Aspect.FIRE, 1), + //'ae2:semi_dark_monitor' 'ae2:monitor' 'ae2:dark_monitor'三者任一 + ae("dark_monitor"), + stack(ModItems.DIFFUSION_CORE), + stack(ModItems.COALESCENCE_CORE), + ae("logic_processor"), + tc("vis_filter")); + + ThaumcraftApi.addShapelessArcaneCraftingRecipe("ESSENTIATERMINAL", stack(ModItems.ESSENTIA_TERMINAL_ITEM), + new AspectList().add(Aspect.WATER, 5).add(Aspect.ORDER, 2).add(Aspect.FIRE, 1), + //'ae2:semi_dark_monitor' 'ae2:monitor' 'ae2:dark_monitor'三者任一 + ae("semi_dark_monitor"), + stack(ModItems.DIFFUSION_CORE), + stack(ModItems.COALESCENCE_CORE), + ae("logic_processor"), + tc("vis_filter")); + + // 5. 奥术合成终端 + ARCANE_CRAFTING_TERMINAL = ThaumcraftApi.addShapelessArcaneCraftingRecipe("ARCANECRAFTINGTERMINAL", stack(ModItems.ARCANE_CRAFTING_TERMINAL_ITEM), + new AspectList().add(Aspect.AIR, 10).add(Aspect.EARTH, 10).add(Aspect.FIRE, 10).add(Aspect.WATER, 10).add(Aspect.ORDER, 10).add(Aspect.ENTROPY, 10), + ae("terminal"), + tc("arcane_workbench"), + ae("calculation_processor")); + + // 6. 源流接口 + VIS_INTERFACE = ThaumcraftApi.addShapelessArcaneCraftingRecipe("VISINTERFACE", stack(ModItems.VIS_INTERFACE), + new AspectList().add(Aspect.AIR, 2).add(Aspect.EARTH, 2).add(Aspect.FIRE, 2).add(Aspect.WATER, 2).add(Aspect.ORDER, 2).add(Aspect.ENTROPY, 2), + tc("balance_shard"), + ae("me_p2p_tunnel")); + + // 7. 原质振荡室 + ESSENTIA_VIBRATION_CHAMBER = ThaumcraftApi.addShapelessArcaneCraftingRecipe("ESSENTIAVIBRATIONCHAMBER", stack(ModBlocks.ESSENTIA_VIBRATION_CHAMBER), + new AspectList().add(Aspect.FIRE, 10).add(Aspect.WATER, 6).add(Aspect.ORDER, 4).add(Aspect.ENTROPY, 4), + ae("vibration_chamber"), + tc("jar_of_essentia"), + stack(ModItems.COALESCENCE_CORE)); + + } + + + private static void registerInfusion() { + // 1. 原质供应器 + ESSENTIA_PROVIDER = ThaumcraftApi.addInfusionCraftingRecipe("ESSENTIAPROVIDER", stack(ModBlocks.ESSENTIA_PROVIDER), + 1, new AspectList().add(Aspect.MECHANISM, 64).add(Aspect.MAGIC, 32).add(Aspect.ORDER, 32).add(Aspect.EXCHANGE, 16), + ae("interface"), + tc("water_shard"), + tc("water_shard"), + tc("salis_mundus"), + tc("salis_mundus"), + stack(ModItems.DIFFUSION_CORE), + stack(ModItems.COALESCENCE_CORE), + tc("essentia_filter"), + tc("essentia_filter")); + + // 2. 注魔供应器 + INFUSION_PROVIDER = ThaumcraftApi.addInfusionCraftingRecipe("INFUSIONPROVIDER", stack(ModBlocks.INFUSION_PROVIDER), + 3, new AspectList().add(Aspect.MECHANISM, 64).add(Aspect.MAGIC, 32).add(Aspect.ORDER, 32).add(Aspect.EXCHANGE, 16), + ae("interface"), + tc("essentia_mirror"), + tc("essentia_mirror"), + tc("air_shard"), + tc("air_shard"), + stack(ModItems.COALESCENCE_CORE), + stack(ModItems.COALESCENCE_CORE), + tc("salis_mundus"), + tc("salis_mundus")); + + // 3. 奥术装配器 + ARCANE_ASSEMBLER = ThaumcraftApi.addInfusionCraftingRecipe("ARCANEASSEMBLER", stack(ModBlocks.ARCANE_ASSEMBLER), + 5, new AspectList().add(Aspect.CRAFT, 64).add(Aspect.EXCHANGE, 32).add(Aspect.AURA, 16).add(Aspect.MAGIC, 16).add(Aspect.METAL, 8).add(Aspect.CRYSTAL, 8), + ae("molecular_assembler"), + tc("fire_shard"), + tc("entropy_shard"), + tc("order_shard"), + tc("balance_shard"), + tc("water_shard"), + tc("earth_shard"), + tc("air_shard"), + tc("salis_mundus"), + createFullVisScepter()); + + + + } + + private static ItemStack createFullVisScepter() { + ItemStack scepter = tc("silverwood_thaumium_scepter"); + if (scepter.isEmpty()) return scepter; + TCVisHelper.setWandParts(scepter, "silverwood", "thaumium", true); + int max = TCVisHelper.getWandMaxVis(scepter, "silverwood_thaumium_scepter"); + for (Aspect a : Aspect.getPrimalAspects()) { + TCVisHelper.storeVis(scepter, a, max, max); + } + return scepter; + } + + private static ItemStack stack(java.util.function.Supplier s) { + return new ItemStack(s.get()); + } + private static ItemStack tc(String name) { + return new ItemStack(net.minecraft.core.registries.BuiltInRegistries.ITEM.get( + ResourceLocation.fromNamespaceAndPath("thaumcraft", name))); + } + private static ItemStack ae(String name) { + return new ItemStack(net.minecraft.core.registries.BuiltInRegistries.ITEM.get( + ResourceLocation.fromNamespaceAndPath("ae2", name))); + } +} \ No newline at end of file diff --git a/src/main/java/thaumicenergistics/common/features/ThEFeatureBase.java b/src/main/java/thaumicenergistics/common/features/ThEFeatureBase.java new file mode 100644 index 0000000..f2bd898 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/features/ThEFeatureBase.java @@ -0,0 +1,43 @@ +package thaumicenergistics.common.features; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.config.ThEConfig; +import java.util.function.Supplier; + +/** + * 所有功能模块的基类。每个功能可独立启停。 + * 自 1.7.10 ThEFeatureBase 移植。 + */ +public abstract class ThEFeatureBase { + private final String name; + protected boolean enabled; + + protected ThEFeatureBase(String name) { + this.name = name; + this.enabled = ThEConfig.isFeatureEnabled(name); + } + + public final String getName() { return name; } + public final boolean isEnabled() { return enabled; } + + /** 模组构造期间调用,用于注册物品与方块。 */ + public void register() { + if (!enabled) return; + ThaumicEnergistics.LOG.info("Feature [{}] loading...", name); + doRegister(); + } + + /** 所有功能注册完成后调用,用于跨功能设置。 */ + public void postInit() { + if (!enabled) return; + doPostInit(); + } + + /** 覆写以注册本功能特有的方块/物品。 */ + protected abstract void doRegister(); + /** 覆写以进行注册后设置(配方、研究等)。 */ + protected void doPostInit() {} +} diff --git a/src/main/java/thaumicenergistics/common/grid/AEPartGridBlock.java b/src/main/java/thaumicenergistics/common/grid/AEPartGridBlock.java new file mode 100644 index 0000000..b562ee0 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/grid/AEPartGridBlock.java @@ -0,0 +1,22 @@ +package thaumicenergistics.common.grid; + +/** + * 表示连接到 AE2 网格的部件。 + * 对应 1.7.10 AEPartGridBlock——为 1.21.1 简化。 + * TODO: 通过 AE2 19.x API 完整连接 IGridNode。 + */ +public class AEPartGridBlock { + private final Object part; // 占位 PartBase 或 IPartItem + + public AEPartGridBlock(Object part) { this.part = part; } + + public double getIdlePowerUsage() { + // TODO: Delegate to part + return 1.0; + } + + public Object getGridNode() { + // TODO: AE2 IGridNode + return null; + } +} diff --git a/src/main/java/thaumicenergistics/common/grid/EssentiaGridService.java b/src/main/java/thaumicenergistics/common/grid/EssentiaGridService.java new file mode 100644 index 0000000..60ca826 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/grid/EssentiaGridService.java @@ -0,0 +1,136 @@ +package thaumicenergistics.common.grid; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import net.minecraft.resources.ResourceLocation; + +import appeng.api.networking.IGrid; +import appeng.api.networking.IGridServiceProvider; +import appeng.api.networking.security.IActionSource; +import appeng.api.networking.storage.IStorageService; +import appeng.api.storage.MEStorage; +import appeng.api.storage.StorageHelper; +import appeng.api.networking.security.IActionSource; +import thaumicenergistics.api.grid.IEssentiaGrid; +import thaumicenergistics.api.storage.AspectStack; +import thaumicenergistics.api.storage.IAspectStack; +import thaumicenergistics.common.integration.appeng.AEssentiaKey; + +/** + * 源质网格服务的实现。查询和提取源质时同时检查两个存储后端: + * Path A: EssentiaMonitor(注魔供应器/傀儡背包直接写入), + * Path B: AE2 原生存储(源质存储元件、输入总线等)。 + */ +public class EssentiaGridService implements IEssentiaGrid, IGridServiceProvider { + + private final EssentiaMonitor monitor; + private final IGrid grid; + + public EssentiaGridService(IGrid grid) { + this.monitor = EssentiaMonitorRegistry.getMonitor(grid); + this.grid = grid; + } + + private long getNativeAmount(ResourceLocation aspectId) { + var storage = getNativeStorage(); + if (storage == null) return 0; + var key = AEssentiaKey.of(aspectId); + if (key == null) return 0; + for (var entry : storage.getAvailableStacks()) { + if (entry.getKey() instanceof AEssentiaKey ek && ek.equals(key)) { + return entry.getLongValue(); + } + } + return 0; + } + + private long extractNative(ResourceLocation aspectId, long amount, boolean simulate) { + var storage = getNativeStorage(); + if (storage == null) return 0; + var key = AEssentiaKey.of(aspectId); + if (key == null) return 0; + return StorageHelper.poweredExtraction( + grid.getEnergyService(), storage, key, amount, + IActionSource.empty()); + } + + private MEStorage getNativeStorage() { + var sg = grid.getService(IStorageService.class); + return sg != null ? sg.getInventory() : null; + } + + @Override + public long getEssentiaAmount(ResourceLocation aspectId) { + long monitorAmt = monitor.get(aspectId); + long nativeAmt = getNativeAmount(aspectId); + return monitorAmt + nativeAmt; + } + + @Override + public long extractEssentia(ResourceLocation aspectId, long amount, boolean simulate) { + // 优先从 monitor 提取 + long monitorAmt = monitor.get(aspectId); + if (monitorAmt >= amount) { + if (!simulate) { + monitor.set(aspectId, monitorAmt - amount); + } + return amount; + } + + // monitor 不够,全部取出后再从 AE2 原生存储提取剩余 + long extracted = 0; + if (monitorAmt > 0) { + if (!simulate) { + monitor.set(aspectId, 0); + } + extracted = monitorAmt; + } + + long remaining = amount - extracted; + if (remaining > 0) { + long nativeExtracted = extractNative(aspectId, remaining, simulate); + extracted += nativeExtracted; + } + + return extracted; + } + + @Override + public long injectEssentia(ResourceLocation aspectId, long amount, boolean simulate) { + if (amount <= 0) return 0; + if (!simulate) { + long current = monitor.get(aspectId); + monitor.set(aspectId, current + amount); + } + return 0; + } + + @Override + public List getEssentiaList() { + Map merged = new LinkedHashMap<>(); + + for (var stack : monitor.list()) { + merged.put(stack.aspectId(), stack.amount()); + } + + var storage = getNativeStorage(); + if (storage != null) { + for (var entry : storage.getAvailableStacks()) { + if (entry.getKey() instanceof AEssentiaKey ek) { + merged.merge(ek.getId(), entry.getLongValue(), Long::sum); + } + } + } + + List result = new ArrayList<>(); + for (var entry : merged.entrySet()) { + if (entry.getValue() > 0) { + result.add(new AspectStack(entry.getKey(), entry.getValue())); + } + } + return result; + } +} \ No newline at end of file diff --git a/src/main/java/thaumicenergistics/common/grid/EssentiaMonitor.java b/src/main/java/thaumicenergistics/common/grid/EssentiaMonitor.java new file mode 100644 index 0000000..b09117f --- /dev/null +++ b/src/main/java/thaumicenergistics/common/grid/EssentiaMonitor.java @@ -0,0 +1,15 @@ +package thaumicenergistics.common.grid; +import java.util.*; +import java.util.concurrent.CopyOnWriteArrayList; +import net.minecraft.resources.ResourceLocation; +import thaumicenergistics.api.storage.AspectStack; +import thaumicenergistics.api.storage.IAspectStack; + +public class EssentiaMonitor { + private final Map storage = Collections.synchronizedMap(new LinkedHashMap<>()); + private final List listeners = new CopyOnWriteArrayList<>(); + public List list() { synchronized(storage) { return storage.entrySet().stream().map(e -> (IAspectStack)new AspectStack(e.getKey(), e.getValue())).toList(); } } + public long get(ResourceLocation id) { synchronized(storage) { return storage.getOrDefault(id, 0L); } } + public void addListener(Runnable r) { listeners.add(r); } + public void set(ResourceLocation id, long amt) { synchronized(storage) { storage.put(id, amt); } listeners.forEach(Runnable::run); } +} diff --git a/src/main/java/thaumicenergistics/common/grid/EssentiaMonitorRegistry.java b/src/main/java/thaumicenergistics/common/grid/EssentiaMonitorRegistry.java new file mode 100644 index 0000000..5c6ae31 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/grid/EssentiaMonitorRegistry.java @@ -0,0 +1,29 @@ +package thaumicenergistics.common.grid; + +import appeng.api.networking.IGrid; + +import java.util.Map; +import java.util.WeakHashMap; + +/** + * 管理 AE2 Grid → EssentiaMonitor 的映射。 + * 每个 AE2 网格对应一个独立的 EssentiaMonitor 实例, + * 确保不同网络的源质存储互不干扰。 + * 使用 WeakHashMap,当 Grid 被 GC 时自动清理。 + */ +public final class EssentiaMonitorRegistry { + + private EssentiaMonitorRegistry() {} + + private static final Map MONITORS = new WeakHashMap<>(); + + /** + * 获取指定 Grid 对应的 EssentiaMonitor。 + * 如果不存在则创建一个新的。 + */ + public static EssentiaMonitor getMonitor(IGrid grid) { + synchronized (MONITORS) { + return MONITORS.computeIfAbsent(grid, g -> new EssentiaMonitor()); + } + } +} diff --git a/src/main/java/thaumicenergistics/common/grid/EssentiaWatcher.java b/src/main/java/thaumicenergistics/common/grid/EssentiaWatcher.java new file mode 100644 index 0000000..f4d81be --- /dev/null +++ b/src/main/java/thaumicenergistics/common/grid/EssentiaWatcher.java @@ -0,0 +1,48 @@ +package thaumicenergistics.common.grid; + +import net.minecraft.resources.ResourceLocation; +import thaumicenergistics.api.grid.IEssentiaWatcher; +import thaumicenergistics.api.grid.IEssentiaWatcherHost; +import java.util.*; + +/** + * 监听源质网格的变化并通知 host。 + */ +public class EssentiaWatcher implements IEssentiaWatcher { + private final IEssentiaWatcherHost host; + private final Set watchedAspects = new HashSet<>(); + private final Map lastAmounts = new HashMap<>(); + private final EssentiaMonitor monitor; + + public EssentiaWatcher(IEssentiaWatcherHost host, EssentiaMonitor monitor) { + this.host = host; + this.monitor = monitor; + } + + @Override public IEssentiaWatcherHost getHost() { return host; } + @Override public int size() { return watchedAspects.size(); } + @Override public boolean isEmpty() { return watchedAspects.isEmpty(); } + @Override public boolean contains(Object o) { return watchedAspects.contains(o); } + @Override public Iterator iterator() { return watchedAspects.iterator(); } + @Override public Object[] toArray() { return watchedAspects.toArray(); } + @Override public T[] toArray(T[] a) { return watchedAspects.toArray(a); } + @Override public boolean add(ResourceLocation id) { return watchedAspects.add(id); } + @Override public boolean remove(Object o) { lastAmounts.remove(o); return watchedAspects.remove(o); } + @Override public boolean containsAll(Collection c) { return watchedAspects.containsAll(c); } + @Override public boolean addAll(Collection c) { return watchedAspects.addAll(c); } + @Override public boolean removeAll(Collection c) { lastAmounts.keySet().removeAll(c); return watchedAspects.removeAll(c); } + @Override public boolean retainAll(Collection c) { lastAmounts.keySet().retainAll(c); return watchedAspects.retainAll(c); } + @Override public void clear() { lastAmounts.clear(); watchedAspects.clear(); } + + /** 检查所有被监听的源质,并在变化时通知 host。 */ + public void tick() { + for (ResourceLocation id : watchedAspects) { + long current = monitor.get(id); + Long last = lastAmounts.get(id); + if (last == null || last != current) { + lastAmounts.put(id, current); + host.onEssentiaChange(id, current, 0); + } + } + } +} diff --git a/src/main/java/thaumicenergistics/common/grid/GridEssentiaCache.java b/src/main/java/thaumicenergistics/common/grid/GridEssentiaCache.java new file mode 100644 index 0000000..09dd9d6 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/grid/GridEssentiaCache.java @@ -0,0 +1,9 @@ +package thaumicenergistics.common.grid; +import java.util.*; +import net.minecraft.resources.ResourceLocation; +public class GridEssentiaCache { + private final Map data = Collections.synchronizedMap(new LinkedHashMap<>()); + public long get(ResourceLocation id) { return data.getOrDefault(id, 0L); } + public void put(ResourceLocation id, long amt) { data.put(id, amt); } + public Map snapshot() { synchronized(data) { return new LinkedHashMap<>(data); } } +} diff --git a/src/main/java/thaumicenergistics/common/integration/appeng/AEssentiaKey.java b/src/main/java/thaumicenergistics/common/integration/appeng/AEssentiaKey.java new file mode 100644 index 0000000..01e1f8c --- /dev/null +++ b/src/main/java/thaumicenergistics/common/integration/appeng/AEssentiaKey.java @@ -0,0 +1,135 @@ +package thaumicenergistics.common.integration.appeng; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtOps; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.resources.ResourceLocation; +import appeng.api.stacks.AEKey; +import appeng.api.stacks.AEKeyType; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public final class AEssentiaKey extends AEKey { + + /** id → key 实例的缓存;AEssentiaKey 不可变,且 equals/hashCode 基于 id。 */ + private static final Map CACHE = new ConcurrentHashMap<>(); + + /** + * 规范化 id 实例:所有同 id 的 AEssentiaKey 共享同一 ResourceLocation 实例。 + * AE2 的 KeyCounter 内部按 {@code getPrimaryKey()} 的引用相等分组(Reference2ObjectMap), + * 存储(NBT 反序列化)与 config(TCReflection 生成)的 id 若不共享实例会导致 AE2 tooltip 去重失败(同方面重复显示)。 + */ + private static final Map ID_CACHE = new ConcurrentHashMap<>(); + + public static final MapCodec MAP_CODEC = RecordCodecBuilder.mapCodec( + builder -> builder.group( + ResourceLocation.CODEC.fieldOf("id").forGetter(AEssentiaKey::getId) + ).apply(builder, AEssentiaKey::new) + ); + + public static final Codec CODEC = MAP_CODEC.codec(); + + public static final StreamCodec STREAM_CODEC = + StreamCodec.composite( + ResourceLocation.STREAM_CODEC, AEssentiaKey::getId, + AEssentiaKey::new + ); + + private final ResourceLocation id; + + @Override + protected Component computeDisplayName() { + // 使用 TC 源质的实际显示名称(如 "Aer" / "风"),而非翻译键 + String tag = id.getPath(); + if (thaumcraft.api.aspects.Aspect.aspects != null) { + for (thaumcraft.api.aspects.Aspect aspect : thaumcraft.api.aspects.Aspect.aspects.values()) { + if (aspect != null && aspect.getTag() != null && aspect.getTag().equalsIgnoreCase(tag)) { + return aspect.displayName(); + } + } + } + // 回退:翻译键 + return Component.translatable("aspect.thaumicenergistics." + tag); + } + + + public void addDrops(long amount, List drops, Level level, BlockPos pos) { + } + + @Override + public boolean hasComponents() { + return false; + } + + public AEssentiaKey(ResourceLocation id) { + this.id = ID_CACHE.computeIfAbsent(id, k -> k); + } + + @Override + public AEKeyType getType() { + return AEssentiaKeyType.INSTANCE; + } + + @Override + public AEKey dropSecondary() { + return this; + } + + @Override + public CompoundTag toTag(HolderLookup.Provider registries) { + var ops = registries.createSerializationContext(NbtOps.INSTANCE); + return (CompoundTag) CODEC.encodeStart(ops, this).getOrThrow(); + } + + @Override + public ResourceLocation getId() { + return id; + } + + @Override + public void writeToPacket(RegistryFriendlyByteBuf data) { + ResourceLocation.STREAM_CODEC.encode(data, id); + } + + public static AEssentiaKey fromPacket(RegistryFriendlyByteBuf data) { + return new AEssentiaKey(ResourceLocation.STREAM_CODEC.decode(data)); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof AEssentiaKey that)) return false; + return id.equals(that.id); + } + + @Override + public int hashCode() { + return id.hashCode(); + } + + @Override + public String toString() { + return "AEssentiaKey{" + id + "}"; + } + + @Override + public Object getPrimaryKey(){ + return id; + } + + + public static AEssentiaKey of(ResourceLocation id) { + return CACHE.computeIfAbsent(id, AEssentiaKey::new); + } +} \ No newline at end of file diff --git a/src/main/java/thaumicenergistics/common/integration/appeng/AEssentiaKeyType.java b/src/main/java/thaumicenergistics/common/integration/appeng/AEssentiaKeyType.java new file mode 100644 index 0000000..d140db0 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/integration/appeng/AEssentiaKeyType.java @@ -0,0 +1,54 @@ +package thaumicenergistics.common.integration.appeng; + +import com.mojang.serialization.MapCodec; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.resources.ResourceLocation; +import appeng.api.stacks.AEKey; +import appeng.api.stacks.AEKeyType; +import thaumicenergistics.ThaumicEnergistics; + +public final class AEssentiaKeyType extends AEKeyType { + + public static final ResourceLocation ID = ThaumicEnergistics.id("essentia"); + public static final AEssentiaKeyType INSTANCE = new AEssentiaKeyType(); + + private AEssentiaKeyType() { + super(ID, AEssentiaKey.class, Component.translatable("ae2.keytype.thaumicenergistics.essentia")); + } + + @Override + public MapCodec codec() { + return AEssentiaKey.MAP_CODEC; + } + + + public StreamCodec streamCodec() { + return AEssentiaKey.STREAM_CODEC; + } + + @Override + public AEKey readFromPacket(RegistryFriendlyByteBuf input) { + return AEssentiaKey.fromPacket(input); + } + + + public String formatAmount(long amount, boolean large) { + if (large) { + if (amount >= 1000000) return String.format("%.1fM", amount / 1000000.0); + if (amount >= 1000) return String.format("%.1fK", amount / 1000.0); + } + return Long.toString(amount); + } + + @Override + public int getAmountPerByte() { + return 1; + } + + @Override + public int getAmountPerUnit() { + return 1; + } +} \ No newline at end of file diff --git a/src/main/java/thaumicenergistics/common/integration/appeng/EssentiaStorageChannel.java b/src/main/java/thaumicenergistics/common/integration/appeng/EssentiaStorageChannel.java new file mode 100644 index 0000000..7117fee --- /dev/null +++ b/src/main/java/thaumicenergistics/common/integration/appeng/EssentiaStorageChannel.java @@ -0,0 +1,31 @@ +package thaumicenergistics.common.integration.appeng; + +import net.minecraft.resources.ResourceLocation; +import thaumicenergistics.api.storage.AspectStack; +import thaumicenergistics.api.storage.IAspectStack; +import appeng.api.stacks.AEKey; +import appeng.api.stacks.GenericStack; + +public final class EssentiaStorageChannel { + private EssentiaStorageChannel() {} + + public static GenericStack toGenericStack(IAspectStack stack) { + if (stack == null || stack.isEmpty()) return null; + AEssentiaKey key = AEssentiaKey.of(stack.aspectId()); + return new GenericStack(key, stack.amount()); + } + + public static IAspectStack fromGenericStack(Object obj) { + if (obj instanceof GenericStack gs) { + AEKey what = gs.what(); + if (what instanceof AEssentiaKey essKey) { + return new AspectStack(essKey.getId(), gs.amount()); + } + } + return AspectStack.EMPTY; + } + + public static AEssentiaKey toKey(ResourceLocation aspectId) { + return AEssentiaKey.of(aspectId); + } +} \ No newline at end of file diff --git a/src/main/java/thaumicenergistics/common/integration/appeng/ThEAppliedEnergistics.java b/src/main/java/thaumicenergistics/common/integration/appeng/ThEAppliedEnergistics.java new file mode 100644 index 0000000..efb6f0a --- /dev/null +++ b/src/main/java/thaumicenergistics/common/integration/appeng/ThEAppliedEnergistics.java @@ -0,0 +1,7 @@ +package thaumicenergistics.common.integration.appeng; +import org.slf4j.Logger; import org.slf4j.LoggerFactory; +public final class ThEAppliedEnergistics { + private static final Logger LOG = LoggerFactory.getLogger("ThE-AE2"); + private ThEAppliedEnergistics() {} + public static void init() { LOG.info("ThaumicEnergistics AE2 integration stub loaded."); } +} diff --git a/src/main/java/thaumicenergistics/common/integration/jade/ThEJadePlugin.java b/src/main/java/thaumicenergistics/common/integration/jade/ThEJadePlugin.java new file mode 100644 index 0000000..450ef3a --- /dev/null +++ b/src/main/java/thaumicenergistics/common/integration/jade/ThEJadePlugin.java @@ -0,0 +1,24 @@ +package thaumicenergistics.common.integration.jade; + +import net.minecraft.world.level.block.Block; +import snownee.jade.api.IWailaClientRegistration; +import snownee.jade.api.IWailaCommonRegistration; +import snownee.jade.api.IWailaPlugin; +import snownee.jade.api.WailaPlugin; +import thaumicenergistics.common.tiles.TileEssentiaVibrationChamber; +import thaumicenergistics.init.ModBlocks; + +@WailaPlugin +public class ThEJadePlugin implements IWailaPlugin { + + @Override + public void register(IWailaCommonRegistration registration) { + registration.registerBlockDataProvider(VibrationChamberProvider.INSTANCE, TileEssentiaVibrationChamber.class); + } + + @Override + public void registerClient(IWailaClientRegistration registration) { + Block chamberBlock = ModBlocks.ESSENTIA_VIBRATION_CHAMBER.get(); + registration.registerBlockComponent(VibrationChamberProvider.INSTANCE, chamberBlock.getClass()); + } +} diff --git a/src/main/java/thaumicenergistics/common/integration/jade/VibrationChamberProvider.java b/src/main/java/thaumicenergistics/common/integration/jade/VibrationChamberProvider.java new file mode 100644 index 0000000..61636f3 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/integration/jade/VibrationChamberProvider.java @@ -0,0 +1,123 @@ +package thaumicenergistics.common.integration.jade; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import snownee.jade.api.BlockAccessor; +import snownee.jade.api.IBlockComponentProvider; +import snownee.jade.api.IServerDataProvider; +import snownee.jade.api.ITooltip; +import snownee.jade.api.config.IPluginConfig; +import snownee.jade.api.ui.BoxStyle; +import snownee.jade.api.ui.IElementHelper; +import appeng.util.Platform; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.common.tiles.TileEssentiaVibrationChamber; + +public enum VibrationChamberProvider implements IBlockComponentProvider, IServerDataProvider { + INSTANCE; + + private static final ResourceLocation UID = ResourceLocation.fromNamespaceAndPath(ThaumicEnergistics.MODID, "vibration_chamber"); + private static final String TAG_STORED = "StoredEssentia"; + private static final String TAG_MAX = "MaxEssentia"; + private static final String TAG_BURN_TICKS = "BurnTicks"; + private static final String TAG_TOTAL_BURN = "TotalBurnTicks"; + private static final String TAG_ASPECT = "AspectTag"; + private static final String TAG_AE_PER_TICK = "AEPerTick"; + private static final String TAG_ENERGY_STORED = "StoredEnergy"; + private static final String TAG_ENERGY_MAX = "MaxEnergy"; + private static final String TAG_ENERGY_OUTPUT = "MaxOutput"; + private static final String TAG_GENERATING = "Generating"; + + @Override + public void appendTooltip(ITooltip tooltip, BlockAccessor accessor, IPluginConfig config) { + CompoundTag data = accessor.getServerData(); + if (data == null || data.isEmpty()) return; + + // 吸力类型 + if (data.contains(TAG_ASPECT)) { + String aspect = data.getString(TAG_ASPECT); + String aspectKey = "thaumicenergistics.aspect." + aspect; + tooltip.add(Component.translatable("thaumicenergistics.jade.suction_type", + Component.translatable(aspectKey))); + } + + // 源质存储量 + int stored = data.getInt(TAG_STORED); + int max = data.getInt(TAG_MAX); + tooltip.add(Component.translatable("thaumicenergistics.jade.essentia_stored", stored, max)); + + // 能量槽(ME 控制器格式:已存储 X AE / Y kAE) + double energyStored = data.getDouble(TAG_ENERGY_STORED); + double energyMax = data.getDouble(TAG_ENERGY_MAX); + double maxOutput = data.getDouble(TAG_ENERGY_OUTPUT); + tooltip.add(Component.translatable("thaumicenergistics.jade.energy_stored", + Platform.formatPower(energyStored, false), + Platform.formatPower(energyMax, false))); + // 可视化能量条 + 内嵌文字(FE 单位,1 AE = 2 FE);样式复刻 Jade 内置 EnergyStorageProvider.PROGRESS_BAR(深红渐变 + 灰色描边) + if (energyMax > 0) { + float pct = (float) Math.min(1.0, Math.max(0.0, energyStored / energyMax)); + String feText = formatFE(energyStored * 2) + " / " + formatFE(energyMax * 2); + IElementHelper helper = IElementHelper.get(); + tooltip.add(helper.progress(pct, Component.literal(feText), + helper.progressStyle().color(0xFFAA0000, 0xFF660000), + BoxStyle.getNestedBox(), true)); + } + tooltip.add(Component.translatable("thaumicenergistics.jade.energy_output", + String.format("%.0f", maxOutput))); + + boolean generating = data.getBoolean(TAG_GENERATING); + if (generating && energyStored < energyMax - 0.01) { + int burnTicks = data.getInt(TAG_BURN_TICKS); + int totalTicks = data.getInt(TAG_TOTAL_BURN); + double aePerTick = data.getDouble(TAG_AE_PER_TICK); + if (burnTicks > 0 && totalTicks > 0) { + double progress = 1.0 - (double) burnTicks / totalTicks; + int percent = (int) (progress * 100); + tooltip.add(Component.translatable("thaumicenergistics.jade.burning", percent, aePerTick)); + } + } else if (energyStored >= energyMax - 0.01) { + tooltip.add(Component.translatable("thaumicenergistics.jade.tank_full")); + } + } + + @Override + public void appendServerData(CompoundTag data, BlockAccessor accessor) { + if (accessor.getBlockEntity() instanceof TileEssentiaVibrationChamber chamber) { + data.putInt(TAG_STORED, chamber.getStoredEssentia()); + data.putInt(TAG_MAX, chamber.getMaxEssentia()); + data.putInt(TAG_BURN_TICKS, chamber.getBurnTicksRemaining()); + data.putInt(TAG_TOTAL_BURN, chamber.getTotalBurnTicks()); + data.putDouble(TAG_AE_PER_TICK, chamber.getAePerTick()); + data.putDouble(TAG_ENERGY_STORED, chamber.getStoredEnergy()); + data.putDouble(TAG_ENERGY_MAX, chamber.getMaxEnergyStorage()); + data.putDouble(TAG_ENERGY_OUTPUT, chamber.getMaxOutputPerTick()); + data.putBoolean(TAG_GENERATING, chamber.isActive()); + if (chamber.getSuctionType(null) != null) { + data.putString(TAG_ASPECT, chamber.getSuctionType(null).getTag()); + } + } + } + + @Override + public ResourceLocation getUid() { + return UID; + } + + /** + * 将 FE 能量值格式化为无空格缩写:0 → "0FE",16000 → "16KFE",12345 → "12.3KFE"。 + */ + private static String formatFE(double fe) { + final String[] prefixes = {"", "K", "M", "G", "T", "P"}; + int idx = 0; + double v = fe; + while (v >= 1000 && idx < prefixes.length - 1) { + v /= 1000; + idx++; + } + String num = (v == Math.floor(v) && !Double.isInfinite(v)) + ? String.valueOf((long) v) + : String.format("%.1f", v); + return num + prefixes[idx] + "FE"; + } +} \ No newline at end of file diff --git a/src/main/java/thaumicenergistics/common/integration/tc/ArcaneCraftingPattern.java b/src/main/java/thaumicenergistics/common/integration/tc/ArcaneCraftingPattern.java new file mode 100644 index 0000000..8acb399 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/integration/tc/ArcaneCraftingPattern.java @@ -0,0 +1,149 @@ +package thaumicenergistics.common.integration.tc; + +import java.util.List; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.RegistryAccess; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.item.ItemStack; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; + +/** + * 奥术合成样板,存储在知识核心中。 + * 从 1.7.10 ArcaneCraftingPattern 移植。 + */ +public class ArcaneCraftingPattern { + private static final String NBTKEY_INGREDIENT_NUM = "input#"; + private static final String NBTKEY_RESULT = "output"; + private static final String NBTKEY_ASPECTS = "aspects"; + private static final int GRID_SIZE = 9; + + /** 全局 RegistryAccess,用于 NBT 读写 */ + private static final HolderLookup.Provider REGISTRY_ACCESS = + RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY); + + protected AspectList aspects; + protected ItemStack[] ingredients = new ItemStack[GRID_SIZE]; + protected ItemStack result = ItemStack.EMPTY; + protected boolean isValid; + + public ArcaneCraftingPattern(AspectList aspects, ItemStack result, ItemStack[] ingredients) { + this.aspects = aspects.copy(); + this.result = result.copy(); + + boolean hasValidInput = false; + for (int i = 0; i < GRID_SIZE && i < ingredients.length; i++) { + if (ingredients[i] != null && !ingredients[i].isEmpty()) { + this.ingredients[i] = ingredients[i].copy(); + hasValidInput = true; + } + } + + this.isValid = this.aspects.size() > 0 && !this.result.isEmpty() && hasValidInput; + } + + public ArcaneCraftingPattern(CompoundTag data) { + this.aspects = new AspectList(); + readFromNBT(data); + } + + public boolean isPatternValid() { + return isValid; + } + + public AspectList getAspects() { + return aspects; + } + + public ItemStack getResult() { + return result; + } + + public ItemStack[] getIngredients() { + return ingredients; + } + + public Aspect[] getCachedAspects() { + return aspects.getAspects(); + } + + public int getAspectCost(Aspect aspect) { + return aspects.getAmount(aspect); + } + + @SuppressWarnings("unchecked") + public static boolean canSubstituteFor(Object target, ItemStack input) { + if (target instanceof ItemStack targetStack) { + return ItemStack.isSameItemSameComponents(targetStack, input); + } else if (target instanceof List) { + List items = (List) target; + for (ItemStack item : items) { + if (ItemStack.isSameItemSameComponents(item, input)) return true; + } + } + return false; + } + + public void readFromNBT(CompoundTag data) { + if (data == null) return; + + this.ingredients = new ItemStack[GRID_SIZE]; + this.isValid = true; + + if (data.contains(NBTKEY_ASPECTS)) { + this.aspects.readFromNBT(data.getCompound(NBTKEY_ASPECTS)); + } + + if (this.aspects.size() == 0) { + this.isValid = false; + return; + } + + for (int slot = 0; slot < GRID_SIZE; slot++) { + if (!data.contains(NBTKEY_INGREDIENT_NUM + slot)) continue; + + CompoundTag ingTag = data.getCompound(NBTKEY_INGREDIENT_NUM + slot); + if (ingTag.isEmpty()) { + this.isValid = false; + return; + } + + ItemStack stack = ItemStack.parseOptional(REGISTRY_ACCESS, ingTag); + if (stack.isEmpty()) { + this.isValid = false; + return; + } + this.ingredients[slot] = stack; + } + + if (data.contains(NBTKEY_RESULT)) { + CompoundTag resultTag = data.getCompound(NBTKEY_RESULT); + this.result = ItemStack.parseOptional(REGISTRY_ACCESS, resultTag); + if (this.result.isEmpty()) { + this.isValid = false; + } + } else { + this.isValid = false; + } + } + + public CompoundTag writeToNBT(CompoundTag data) { + CompoundTag aspectTag = new CompoundTag(); + this.aspects.writeToNBT(aspectTag); + data.put(NBTKEY_ASPECTS, aspectTag); + + for (int i = 0; i < GRID_SIZE; i++) { + if (this.ingredients[i] == null || this.ingredients[i].isEmpty()) continue; + // 1.21.1: ItemStack.save(Provider) 返回新的 Tag,不会写入传入的 CompoundTag。 + // 必须用返回值(之前用双参 save 并丢弃返回值,导致存了空 tag、配方反序列化全失败)。 + CompoundTag ingTag = (CompoundTag) this.ingredients[i].save(REGISTRY_ACCESS); + data.put(NBTKEY_INGREDIENT_NUM + i, ingTag); + } + + CompoundTag resultTag = (CompoundTag) this.result.save(REGISTRY_ACCESS); + data.put(NBTKEY_RESULT, resultTag); + + return data; + } +} diff --git a/src/main/java/thaumicenergistics/common/integration/tc/EssentiaConversionHelper.java b/src/main/java/thaumicenergistics/common/integration/tc/EssentiaConversionHelper.java new file mode 100644 index 0000000..3b6fb5f --- /dev/null +++ b/src/main/java/thaumicenergistics/common/integration/tc/EssentiaConversionHelper.java @@ -0,0 +1,30 @@ +package thaumicenergistics.common.integration.tc; + +import net.minecraft.resources.ResourceLocation; +import thaumicenergistics.api.storage.IAspectStack; +import thaumicenergistics.api.storage.AspectStack; +import java.util.Optional; + +/** + * 源质类型与数量转换辅助。 + * 1.7.10 用 AE 气体/流体桥接;1.21.1 用直接类型映射。 + */ +public final class EssentiaConversionHelper { + private EssentiaConversionHelper() {} + + /** 每单位源质转移的 AE 能量成本。1.7.10: 0.3 AE/单位。 */ + public static final double AE_PER_ESSENTIA = 0.3; + + /** 标准 TC 源质罐容量(单位)。 */ + public static final int JAR_CAPACITY = 64; + /** 标准 TC 药剂瓶容量(单位)。 */ + public static final int PHIAL_CAPACITY = 8; + + /** + * 在不同源质单位间转换。 + * TODO: 映射到实际 TC Aspect API。 + */ + public static Optional convert(IAspectStack input, String targetUnit) { + return Optional.of(input); + } +} diff --git a/src/main/java/thaumicenergistics/common/integration/tc/PseudoResearchItem.java b/src/main/java/thaumicenergistics/common/integration/tc/PseudoResearchItem.java new file mode 100644 index 0000000..7320171 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/integration/tc/PseudoResearchItem.java @@ -0,0 +1,156 @@ +package thaumicenergistics.common.integration.tc; + +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import thaumcraft.api.aspects.AspectList; +import thaumcraft.api.research.ResearchCategories; +import thaumcraft.api.research.ResearchItem; +import thaumcraft.api.research.ResearchPage; +import thaumcraft.common.research.TCResearchIndex; +import thaumicenergistics.ThaumicEnergistics; + +/** + * 伪前置桩节点。在 ThE 的研究 tab 中创建一个占位节点, + * 其图标、名称、页面全部指向 TC 原版研究,使得 ThE 节点可以跨分类连线。 + * + * 关键实现细节: + * - key 仍使用 PSEUDO_ 前缀(如 PSEUDO_VISPOWER),避免与原版研究在 TCResearchManager 的 CompoundTag 中冲突。 + * - 图标(icon_item/icon_resource)直接使用原版研究的图标,在 registerApiResearch 时会被正确拷贝到 TCResearchIndex.Entry。 + * - 页面(pages)直接使用原版研究的页面,使点击伪前置时能展示原版研究的内容。 + * - 名称翻译通过 ThE 的 lang 文件中添加 tc.research_name.PSEUDO_* 条目指向原版翻译 key 来解决。 + * - 解锁同步通过 ResearchCompletedEvent 事件监听实现,见 ThEThaumcraft.registerPseudoSync()。 + */ +public class PseudoResearchItem extends ResearchItem { + + /** 原版真实研究的 key,如 "DISTILESSENTIA" */ + private final String realKey; + + /** 原版真实研究所在分类,如 "ALCHEMY" */ + private final String realCategory; + + /** 指向的原版研究(用于 getName/getText/getPages 委托)。 */ + private ResearchItem realResearch; + + private PseudoResearchItem(String pseudoKey, String category, int column, int row, + ItemStack icon, String realKey, String realCategory) { + super(pseudoKey, category, new AspectList(), column, row, 1, icon); + this.realKey = realKey; + this.realCategory = realCategory; + // concealed: 当 parentsComplete 或 completed 时可见 + this.setStub().setConcealed(); + } + + private PseudoResearchItem(String pseudoKey, String category, int column, int row, + ResourceLocation icon, String realKey, String realCategory) { + super(pseudoKey, category, new AspectList(), column, row, 1, icon); + this.realKey = realKey; + this.realCategory = realCategory; + this.setStub().setConcealed(); + } + + /** + * 创建一个指向 TC 原版研究的伪前置。 + * + * @param pseudoKey 伪前置在 ThE tab 中的 key(如 "PSEUDO_DISTILESSENTIA") + * @param category ThE 研究分类(即 TAB) + * @param realKey TC 原版研究的 key(如 "DISTILESSENTIA") + * @param realCategory TC 原版研究所在分类(如 "ALCHEMY") + * @param column 伪前置的 X 坐标 + * @param row 伪前置的 Y 坐标 + */ + public static PseudoResearchItem newPseudo(String pseudoKey, String category, + String realKey, String realCategory, + int column, int row) { + var realCat = ResearchCategories.researchCategories.get(realCategory); + if (realCat == null) { + throw new IllegalArgumentException("TC category not found: " + realCategory); + } + ResearchItem realResearch = realCat.research.get(realKey); + if (realResearch == null) { + throw new IllegalArgumentException("TC research not found: " + realKey + " in " + realCategory); + } + + PseudoResearchItem pseudo; + // 图标第一优先:真实研究对应的物品(research_index.json 的 item 字段,TC tab 中即用此图标) + ItemStack realIcon = resolveRealIconItem(realKey); + if (!realIcon.isEmpty()) { + pseudo = new PseudoResearchItem(pseudoKey, category, column, row, realIcon, realKey, realCategory); + } else if (realResearch.icon_item != null && !realResearch.icon_item.isEmpty()) { + pseudo = new PseudoResearchItem(pseudoKey, category, column, row, realResearch.icon_item, realKey, realCategory); + } else if (realResearch.icon_resource != null) { + pseudo = new PseudoResearchItem(pseudoKey, category, column, row, realResearch.icon_resource, realKey, realCategory); + } else if (realCat.icon != null) { + // 备选:真实研究所在分类的图标 + pseudo = new PseudoResearchItem(pseudoKey, category, column, row, realCat.icon, realKey, realCategory); + } else { + // 最终备选:ThE 研究 tab 图标 + pseudo = new PseudoResearchItem(pseudoKey, category, column, row, + ResourceLocation.fromNamespaceAndPath(thaumicenergistics.ThaumicEnergistics.MODID, "textures/research/tab_icon.png"), + realKey, realCategory); + } + + // 保存真实研究引用:内容(名称/文字/页面)通过方法委托到真实研究(TC port 渲染调 getPages()) + pseudo.realResearch = realResearch; + + ThaumicEnergistics.LOG.debug("[Pseudo] {} ← {}:{} icon={}", + pseudoKey, realCategory, realKey, + pseudo.icon_item != null && !pseudo.icon_item.isEmpty() + ? pseudo.icon_item.getDescriptionId() : String.valueOf(pseudo.icon_resource)); + + return pseudo; + } + + /** + * 从 TC 的权威研究索引(research_index.json)解析真实研究对应的物品图标。 + */ + private static ItemStack resolveRealIconItem(String realKey) { + try { + return TCResearchIndex.entry(realKey) + .map(entry -> { + String itemId = entry.item(); + if (itemId == null || itemId.isEmpty()) return ItemStack.EMPTY; + ResourceLocation id = ResourceLocation.tryParse(itemId); + if (id == null) return ItemStack.EMPTY; + Item item = BuiltInRegistries.ITEM.get(id); + return (item == null || item == net.minecraft.world.item.Items.AIR) ? ItemStack.EMPTY : new ItemStack(item); + }) + .orElse(ItemStack.EMPTY); + } catch (Exception e) { + return ItemStack.EMPTY; + } + } + + public String realKey() { return realKey; } + + public String realCategory() { return realCategory; } + + // ===== 内容委托:TC port 渲染研究时调用 getName/getText/getPages,全部转发到真实研究 ===== + + @Override + public String getName() { + return realResearch != null ? realResearch.getName() : super.getName(); + } + + @Override + public String getText() { + return realResearch != null ? realResearch.getText() : super.getText(); + } + + @Override + public ResearchPage[] getPages() { + // 优先:原版研究 Java 页面(API 注册的研究有) + if (realResearch != null && realResearch.getPages() != null && realResearch.getPages().length > 0) { + return realResearch.getPages(); + } + // 兜底:原版研究页面在 research_index.json 的 pages 字段(页面 key,如 tc.research_page.DISTILESSENTIA.1) + // registerApiResearch 会从 ResearchPage.text 提取这些 key 作为 Entry.pages,渲染时据此显示原版内容 + return TCResearchIndex.entry(realKey) + .map(entry -> entry.pages().stream() + .filter(p -> p != null && !p.isBlank()) + .map(ResearchPage::new) + .toArray(ResearchPage[]::new)) + .orElse(new ResearchPage[0]); + } +} diff --git a/src/main/java/thaumicenergistics/common/integration/tc/TCReflection.java b/src/main/java/thaumicenergistics/common/integration/tc/TCReflection.java new file mode 100644 index 0000000..1e4d2e3 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/integration/tc/TCReflection.java @@ -0,0 +1,165 @@ +package thaumicenergistics.common.integration.tc; + +import java.util.Locale; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.block.entity.BlockEntity; +import org.jetbrains.annotations.Nullable; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; +import thaumcraft.api.aspects.IAspectContainer; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.api.storage.AspectStack; + +public final class TCReflection { + + /** aspect tag → ResourceLocation 缓存(tag 有界:6 个源质 + 已注册方面)。 */ + private static final Map ASPECT_ID_CACHE = new ConcurrentHashMap<>(); + + private TCReflection() {} + + @Nullable + public static AspectStack extractEssentia(@Nullable BlockEntity be, int maxAmount) { + if (be == null) { + ThaumicEnergistics.LOG.debug("[TCReflection] extractEssentia: be is null"); + return null; + } + if (!(be instanceof IAspectContainer container)) { + ThaumicEnergistics.LOG.debug("[TCReflection] extractEssentia: {} does not implement IAspectContainer", be.getClass().getName()); + return null; + } + + // ===== 路径A: 旧版 IAspectContainer API (getAspects) ===== + AspectList aspectList = container.getAspects(); + if (aspectList != null && aspectList.size() > 0) { + Aspect[] aspects = aspectList.getAspects(); + if (aspects != null) { + ThaumicEnergistics.LOG.debug("[TCReflection] extractEssentia: found {} aspects via getAspects()", aspects.length); + for (Aspect aspect : aspects) { + if (aspect == null) continue; + int amt = aspectList.getAmount(aspect); + if (amt <= 0) continue; + int toExtract = Math.min(amt, maxAmount); + if (container.takeFromContainer(aspect, toExtract)) { + be.setChanged(); + ResourceLocation id = getAspectId(aspect); + ThaumicEnergistics.LOG.debug("[TCReflection] extractEssentia: SUCCESS (API) - extracted {} of {}", toExtract, id); + return id != null ? new AspectStack(id, toExtract) : null; + } + } + } + } + + // ===== 路径B: TC 移植版反射回退 (getAspect/getAmount) ===== + ThaumicEnergistics.LOG.debug("[TCReflection] extractEssentia: getAspects() empty, trying reflection fallback for {}", be.getClass().getName()); + try { + java.lang.reflect.Method[] methods = getAspectMethods(be.getClass()); + if (methods.length < 2) { + return null; + } + Aspect aspect = (Aspect) methods[0].invoke(be); + int amount = (int) methods[1].invoke(be); + if (aspect != null && amount > 0) { + int toExtract = Math.min(amount, maxAmount); + if (container.takeFromContainer(aspect, toExtract)) { + be.setChanged(); + ResourceLocation id = getAspectId(aspect); + ThaumicEnergistics.LOG.debug("[TCReflection] extractEssentia: SUCCESS (reflection) - extracted {} of {}", toExtract, id); + return id != null ? new AspectStack(id, toExtract) : null; + } + ThaumicEnergistics.LOG.debug("[TCReflection] extractEssentia: takeFromContainer returned false for {} of {}", toExtract, aspect.getTag()); + } else { + ThaumicEnergistics.LOG.debug("[TCReflection] extractEssentia: reflection got aspect={}, amount={}", aspect, amount); + } + } catch (Exception e) { + ThaumicEnergistics.LOG.debug("[TCReflection] extractEssentia: reflection fallback error: {}", e.getMessage()); + } + + ThaumicEnergistics.LOG.debug("[TCReflection] extractEssentia: no extractable aspect found"); + return null; + } + + public static void returnEssentia(@Nullable BlockEntity be, AspectStack stack) { + if (be == null || stack.isEmpty()) return; + if (!(be instanceof IAspectContainer container)) return; + Aspect aspect = findAspectById(stack.aspectId()); + if (aspect == null) return; + container.addToContainer(aspect, (int) stack.amount()); + be.setChanged(); + } + + public static int insertEssentia(@Nullable BlockEntity be, AspectStack stack) { + if (be == null || stack.isEmpty()) return 0; + if (!(be instanceof IAspectContainer container)) return 0; + Aspect aspect = findAspectById(stack.aspectId()); + if (aspect == null) return 0; + int toInsert = (int) stack.amount(); + ThaumicEnergistics.LOG.debug("[TCReflection] insertEssentia: inserting {} of {} into {}", toInsert, stack.aspectId(), be.getClass().getName()); + int leftover = container.addToContainer(aspect, toInsert); + int added = toInsert - leftover; + ThaumicEnergistics.LOG.debug("[TCReflection] insertEssentia: added={}, leftover={}", added, leftover); + if (added > 0) { + be.setChanged(); + } + return added; + } + + @Nullable + public static Aspect findAspectById(ResourceLocation id) { + if (id == null) return null; + if (Aspect.aspects == null) return null; + ensureAspectCache(); + String lowerTag = id.getPath().toLowerCase(Locale.ROOT); + Aspect cached = ASPECT_BY_TAG.get(lowerTag); + if (cached != null) return cached; + // 缓存 miss:运行期(post-init)可能注册了新 aspect,回退一次实时遍历并补入缓存 + for (Aspect aspect : Aspect.aspects.values()) { + if (aspect != null && aspect.getTag() != null && aspect.getTag().equalsIgnoreCase(id.getPath())) { + ASPECT_BY_TAG.putIfAbsent(lowerTag, aspect); + return aspect; + } + } + return null; + } + + /** tag(小写) → Aspect 反向缓存,避免每次调用 O(n) 遍历 Aspect.aspects。 */ + private static final Map ASPECT_BY_TAG = new ConcurrentHashMap<>(); + private static volatile boolean aspectCacheBuilt = false; + + private static void ensureAspectCache() { + if (aspectCacheBuilt) return; + synchronized (ASPECT_BY_TAG) { + if (aspectCacheBuilt) return; + for (Aspect aspect : Aspect.aspects.values()) { + if (aspect != null && aspect.getTag() != null) { + ASPECT_BY_TAG.putIfAbsent(aspect.getTag().toLowerCase(Locale.ROOT), aspect); + } + } + aspectCacheBuilt = true; + } + } + + /** 按方块实体类缓存反射方法(getAspect/getAmount),避免每次调用 getMethod。 */ + private static final Map, java.lang.reflect.Method[]> REFLECT_METHOD_CACHE = new ConcurrentHashMap<>(); + + private static java.lang.reflect.Method[] getAspectMethods(Class clazz) { + return REFLECT_METHOD_CACHE.computeIfAbsent(clazz, c -> { + try { + return new java.lang.reflect.Method[] { c.getMethod("getAspect"), c.getMethod("getAmount") }; + } catch (NoSuchMethodException e) { + return new java.lang.reflect.Method[0]; + } + }); + } + + @Nullable + public static ResourceLocation getAspectId(@Nullable Aspect aspect) { + if (aspect == null) return null; + String tag = aspect.getTag(); + if (tag == null || tag.isEmpty()) return null; + return ASPECT_ID_CACHE.computeIfAbsent(tag.toLowerCase(Locale.ROOT), t -> + ResourceLocation.fromNamespaceAndPath("thaumcraft", t)); + } +} \ No newline at end of file diff --git a/src/main/java/thaumicenergistics/common/integration/tc/ThEThaumcraft.java b/src/main/java/thaumicenergistics/common/integration/tc/ThEThaumcraft.java new file mode 100644 index 0000000..bef5fdc --- /dev/null +++ b/src/main/java/thaumicenergistics/common/integration/tc/ThEThaumcraft.java @@ -0,0 +1,392 @@ +package thaumicenergistics.common.integration.tc; + +import java.util.HashMap; +import java.util.Map; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; +import thaumcraft.api.ThaumcraftApi; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; +import thaumcraft.api.events.ResearchCompletedEvent; +import thaumcraft.api.research.ResearchCategories; +import thaumcraft.api.research.ResearchItem; +import thaumcraft.api.research.ResearchPage; +import thaumcraft.api.crafting.IArcaneRecipe; +import thaumcraft.api.crafting.InfusionRecipe; +import thaumcraft.api.crafting.CrucibleRecipe; +import thaumcraft.common.research.TCResearchManager; +import net.neoforged.neoforge.common.NeoForge; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.common.features.RecipeRegistration; +import thaumicenergistics.init.ModBlocks; +import thaumicenergistics.init.ModItems; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 神秘能源 魔导手册研究注册 + * 严格按照 1.7.10 ResearchRegistry 布局移植 + * + * 1.7.10 伪前置(TC原版)映射: + * DISTILESSENTIA = 要素蒸馏 + * TUBEFILTER = 高级源质管道 + * MIRROR = 魔镜 + * INFUSION = 注魔 + * WARDEDARCANA = 守护之奥术 + * ALCHEMICALDUPLICATION = 炼金复制 + * FOCUSFIRE = 法杖核心 + * VISPOWER = 掌控魔力 + * SCEPTRE = 工艺权杖 + * COREUSE = 傀儡核心:使用 + * COREGATHER = 傀儡核心:聚集 + */ +public final class ThEThaumcraft { + private static final Logger LOG = LoggerFactory.getLogger("ThE-TC"); + static final String TAB = "THAUMICENERGISTICS"; + static final String MODID = ThaumicEnergistics.MODID; + + /** + * 原版研究 key → 伪前置 key 的映射。 + * 用于 ResearchCompletedEvent 事件监听:当原版研究解锁时,自动 complete 对应伪前置。 + */ + private static final Map REAL_TO_PSEUDO = new HashMap<>(); + + private ThEThaumcraft() {} + + public static void init() { + LOG.info("Registering ThaumicEnergistics research..."); + + ResearchCategories.registerCategory(TAB, + ResourceLocation.fromNamespaceAndPath(MODID, "textures/research/tab_icon.png"), + ResourceLocation.fromNamespaceAndPath("thaumcraft", "textures/gui/gui_researchback.png")); + + registerScanEvent(); + + // ⚠ 必须先在当前 tab 注册伪前置节点(替代 TC 原版研究), + // 否则 setParents 跨分类引用时线画不出来。 + registerPseudoParents(); + + // 注册事件监听:当 TC 原版研究解锁时,自动 complete 对应伪前置节点 + registerPseudoSync(); + + // 严格按照 1.7.10 FeatureRegistry 构造函数中的注册顺序 + // 1. FeatureThaumicEnergistics → BASEENERGISTICS (0,0) + registerBaseEnergistics(); + // 2. FeatureAutocrafting_Arcane → ARCANE_ASSEMBLER + KNOWLEDGE_INSCRIBER + registerArcaneAssembler(); + registerKnowledgeInscriber(); + // 3. FeatureCells → ESSENTIASTORAGE (0,2) 向左延伸 1k/4k/16k/64k + registerEssentiaStorage(); + // 4. FeatureACT → ARCANECRAFTINGTERMINAL (2,-1) + registerArcaneCraftingTerminal(); + // 5. FeatureVisRelayInterface → VISINTERFACE (4,-1) + registerVisInterface(); + // 6. FeatureEssentiaIOBuses → ESSENTIABUSES (-2,-2) + registerEssentiaBuses(); + // 7. FeatureInfusionProvider → INFUSIONPROVIDER (-5,-2) + registerInfusionProvider(); + // 8. FeatureEssentiaProvider → ESSENTIAPROVIDER (-2,-4) + registerEssentiaProvider(); + // 9. FeatureEssentiaMonitoring → ESSENTIATERMINAL (-1,-4) + registerEssentiaTerminal(); + // 10. FeatureConversionCores → DIGISENTIA (0,-2) + registerDigisentia(); + // 12. FeatureWrenchFocus → FOCUS_AEWRENCH (-3,-7) + registerFocusAEWrench(); + // 13. FeatureQuartzDupe → CERTUS_DUPE (-5,-5) + registerCertusDupe(); + // 14. FeatureEssentiaVibrationChamber → VIBRATIONCHAMBER (1,-4) + registerEssentiaVibrationChamber(); + // 15. FeatureAutocrafting_Essentia → DISTILLATIONENCODER (-4,-4) + registerDistillationEncoder(); + // 16. FeatureGolemBackpack → GOLEMWIFIBACKPACK (0,-6) + registerGolemWifiBackpack(); + + LOG.info("ThaumicEnergistics research registered ({} nodes).", 13); + } + + private static void registerScanEvent() { + ThaumcraftApi.registerScanEventhandler((scanner, level, player) -> + java.util.Optional.empty()); + } + + // ==================== 伪前置节点(跨分类引用 TC 原版研究) ==================== + // 在 ThE 研究 tab 中创建占位节点,使跨分类连线正常。 + // 坐标来自 1.7.10 ResearchRegistry.PseudoResearchTypes + //SCEPTRE(工艺权杖)、DISTILESSENTIA(要素蒸馏) 、WARDEDARCANA(守护之奥术)、VISPOWER(掌控魔力)、 + // TUBEFILTER(高级源质管道)、INFUSION(注魔) 、MIRROR(魔镜)、COREUSE(傀儡核心:使用) + private static void registerPseudoParents() { + // ALCHEMY + registerPseudo("DISTILESSENTIA", "ALCHEMY", -2, 0); + registerPseudo("TUBEFILTER", "ALCHEMY", -3, 0); + registerPseudo("ALCHEMICALDUPLICATION", "ALCHEMY", -5, -6); + // ARTIFICE + registerPseudo("MIRROR", "ARTIFICE", -4, 0); + registerPseudo("INFUSION", "ARTIFICE", -6, 0); + registerPseudo("WARDEDARCANA", "ARTIFICE", 1, 2); + // THAUMATURGY + registerPseudo("FOCUSFIRE", "THAUMATURGY", -4, -7); + registerPseudo("VISPOWER", "THAUMATURGY", 4, 0); + registerPseudo("SCEPTRE", "THAUMATURGY", 5, 0); + // GOLEMANCY + registerPseudo("COREGATHER", "GOLEMANCY", 1, -6); + } + + private static void registerPseudo(String realKey, String realCategory, int col, int row) { + String pseudoKey = "PSEUDO_" + realKey; + try { + PseudoResearchItem.newPseudo(pseudoKey, TAB, realKey, realCategory, col, row) + .registerResearchItem(); + // 记录映射,供事件监听使用 + REAL_TO_PSEUDO.put(realKey, pseudoKey); + } catch (Exception e) { + LOG.warn("伪前置注册失败: PSEUDO_{} (TC:{}/{})", realKey, realCategory, realKey); + } + } + + /** + * 注册事件监听:当 TC 原版研究被 complete 时,自动 complete 对应的伪前置节点。 + * 替代 1.7.10 的 sibling 机制——在 NeoForge 版本中 sibling 机制失效, + * 因为 {@code TCResearchIndex.Entry} 是不可变 record, + * 修改 {@code ResearchItem.siblings} 不会更新到 {@code TCResearchIndex}。 + */ + private static void registerPseudoSync() { + NeoForge.EVENT_BUS.addListener(ResearchCompletedEvent.class, (ResearchCompletedEvent rc) -> { + String completedKey = rc.researchKey(); + // 跳过 clue 解锁(key 以 @ 开头) + if (completedKey.startsWith("@")) return; + // 跳过 PSEUDO_ 节点完成事件,防止 complete() 触发二次事件造成连锁 + if (completedKey.startsWith("PSEUDO_")) return; + String pseudoKey = REAL_TO_PSEUDO.get(completedKey); + if (pseudoKey == null) return; + // 自动 complete 伪前置节点(不通知玩家) + try { + TCResearchManager.complete(rc.player(), pseudoKey, false); + } catch (Exception e) { + LOG.debug("伪前置自动解锁失败: {} → {}", completedKey, pseudoKey); + } + }); + } + + // ==================== 1. (0,0) BASEENERGISTICS 基础能源学==================== + //无前置 + private static void registerBaseEnergistics() { + new ResearchItem("BASEENERGISTICS", TAB, + new AspectList(), + 0, 0, + 0, + ResourceLocation.fromNamespaceAndPath(MODID, "textures/research/tab_icon.png")) + .setRound().setAutoUnlock() + .setPages(new ResearchPage("tc.research_text.BASEENERGISTICS")) + .registerResearchItem(); + } + + // ==================== 2. (6,-1) ARCANE_ASSEMBLER 奥术装配器==================== + // 前置: VISINTERFACE(要素中继接口) + SCEPTRE(工艺权杖) + private static void registerArcaneAssembler() { + new ResearchItem("ARCANEASSEMBLER", TAB, + new AspectList().add(Aspect.CRAFT, 10).add(Aspect.MAGIC, 10) + .add(Aspect.MECHANISM, 5).add(Aspect.ORDER, 5), + 6, -1, 3, new ItemStack(ModItems.ARCANE_ASSEMBLER_ITEM.get())) + .setRound().setParents("VISINTERFACE", "PSEUDO_SCEPTRE") + .setPages( + new ResearchPage("tc.research_text.ARCANEASSEMBLER.stage.1"), + new ResearchPage(RecipeRegistration.ARCANE_ASSEMBLER), + new ResearchPage("tc.research_text.ARCANEASSEMBLER.stage.2")) + .registerResearchItem(); + } + + // ==================== 2. (6,0) KNOWLEDGE_INSCRIBER 知识记录仪==================== + // 前置: ARCANEASSEMBLER(奥术装配器) + private static void registerKnowledgeInscriber() { + new ResearchItem("KNOWLEDGEINSCRIBER", TAB, + new AspectList().add(Aspect.MIND, 10).add(Aspect.MECHANISM, 5).add(Aspect.MAGIC, 5), + 6, 0, 3, new ItemStack(ModItems.KNOWLEDGE_INSCRIBER_ITEM.get())) + .setRound().setParents("ARCANEASSEMBLER") + .setPages( + new ResearchPage("tc.research_text.KNOWLEDGEINSCRIBER"), + new ResearchPage(RecipeRegistration.KNOWLEDGE_CORE_ITEM), + new ResearchPage(RecipeRegistration.KNOWLEDGE_INSCRIBER_BLOCK)) + .registerResearchItem(); + } + + // ==================== 3. (0,2) ESSENTIASTORAGE 源质存储==================== + // 前置: BASEENERGISTICS(基础能源学) + DISTILESSENTIA(要素蒸馏) + WARDEDARCANA(守护之奥术) + private static void registerEssentiaStorage() { + new ResearchItem("ESSENTIASTORAGE", TAB, + new AspectList().add(Aspect.ORDER, 1).add(Aspect.MAGIC, 1), + 0, 2, 2, new ItemStack(ModItems.ESSENTIA_CELL_1K.get())) + .setRound().setParents("BASEENERGISTICS", "PSEUDO_DISTILESSENTIA", "PSEUDO_WARDEDARCANA") + .setPages( + new ResearchPage("tc.research_text.ESSENTIASTORAGE"), + new ResearchPage(RecipeRegistration.STORAGE_COMPONENT_1K), + new ResearchPage(new IArcaneRecipe[]{RecipeRegistration.STORAGE_COMPONENT_4K, RecipeRegistration.STORAGE_COMPONENT_16K, RecipeRegistration.STORAGE_COMPONENT_64K})) + .registerResearchItem(); + } + + // ==================== 4. (2,-1) ARCANECRAFTINGTERMINAL 奥术合成终端==================== + // 前置: BASEENERGISTICS(基础能源学) + private static void registerArcaneCraftingTerminal() { + new ResearchItem("ARCANECRAFTINGTERMINAL", TAB, + new AspectList().add(Aspect.CRAFT, 10).add(Aspect.MAGIC, 10).add(Aspect.MECHANISM, 5), + 2, -1, 2, new ItemStack(ModItems.ARCANE_CRAFTING_TERMINAL_ITEM.get())) + .setRound().setParents("BASEENERGISTICS") + .setPages( + new ResearchPage("tc.research_text.ARCANECRAFTINGTERMINAL.stage.1"), + new ResearchPage(RecipeRegistration.ARCANE_CRAFTING_TERMINAL), + new ResearchPage("tc.research_text.ARCANECRAFTINGTERMINAL.stage.2")) + .registerResearchItem(); + } + + // ==================== 5. (4,-1) VISINTERFACE 要素中继接口==================== + // 前置: ARCANECRAFTINGTERMINAL(奥术合成终端) + VISPOWER(掌控魔力) + private static void registerVisInterface() { + new ResearchItem("VISINTERFACE", TAB, + new AspectList().add(Aspect.AURA, 10).add(Aspect.MAGIC, 5).add(Aspect.MECHANISM, 5), + 4, -1, 3, new ItemStack(ModItems.VIS_INTERFACE.get())) + .setRound().setParents("ARCANECRAFTINGTERMINAL", "PSEUDO_VISPOWER") + .setPages( + new ResearchPage("tc.research_text.VISINTERFACE"), + new ResearchPage(RecipeRegistration.VIS_INTERFACE)) + .registerResearchItem(); + } + + // ==================== 6. (-2,-2) ESSENTIABUSES 源质总线==================== + // 前置: DIGISENTIA(数字化源质) + TUBEFILTER(高级源质管道) + private static void registerEssentiaBuses() { + new ResearchItem("ESSENTIABUSES", TAB, + new AspectList().add(Aspect.MECHANISM, 5).add(Aspect.EXCHANGE, 5).add(Aspect.MAGIC, 3), + -2, -2, 2, new ItemStack(ModItems.ESSENTIA_IMPORT_BUS.get())) + .setRound().setParents("DIGISENTIA", "PSEUDO_TUBEFILTER") + .setPages( + new ResearchPage("tc.research_text.ESSENTIABUSES.stage.1"), + new ResearchPage(RecipeRegistration.ESSENTIA_IMPORT_BUS), + new ResearchPage(RecipeRegistration.ESSENTIA_EXPORT_BUS), + new ResearchPage(RecipeRegistration.ESSENTIA_STORAGE_BUS), + new ResearchPage("tc.research_text.ESSENTIABUSES.stage.2")) + .registerResearchItem(); + } + + // ==================== 7. (-5,-2) INFUSIONPROVIDER 注魔供应器==================== + // 前置: ESSENTIABUSES(源质总线) + INFUSION(注魔) + MIRROR(魔镜) + private static void registerInfusionProvider() { + new ResearchItem("INFUSIONPROVIDER", TAB, + new AspectList().add(Aspect.MECHANISM, 10).add(Aspect.MAGIC, 10) + .add(Aspect.ORDER, 8).add(Aspect.EXCHANGE, 5), + -5, -2, 3, new ItemStack(ModItems.INFUSION_PROVIDER_ITEM.get())) + .setRound().setParents("ESSENTIABUSES", "PSEUDO_INFUSION", "PSEUDO_MIRROR") + .setPages( + new ResearchPage("tc.research_text.INFUSIONPROVIDER.stage.1"), + new ResearchPage(RecipeRegistration.INFUSION_PROVIDER), + new ResearchPage("tc.research_text.INFUSIONPROVIDER.stage.2")) + .registerResearchItem(); + } + + // ==================== 8. (-2,-4) ESSENTIAPROVIDER 源质供应器==================== + // 前置: ESSENTIABUSES(源质总线) + private static void registerEssentiaProvider() { + new ResearchItem("ESSENTIAPROVIDER", TAB, + new AspectList().add(Aspect.MECHANISM, 8).add(Aspect.MAGIC, 8).add(Aspect.EXCHANGE, 5), + -2, -4, 3, new ItemStack(ModItems.ESSENTIA_PROVIDER_ITEM.get())) + .setRound().setParents("ESSENTIABUSES") + .setPages( + new ResearchPage("tc.research_text.ESSENTIAPROVIDER.stage.1"), + new ResearchPage(RecipeRegistration.ESSENTIA_PROVIDER), + new ResearchPage("tc.research_text.ESSENTIAPROVIDER.stage.2")) + .registerResearchItem(); + } + + // ==================== 9. (-1,-4) ESSENTIATERMINAL 源质终端==================== + // 前置: DIGISENTIA(数字化源质) + private static void registerEssentiaTerminal() { + new ResearchItem("ESSENTIATERMINAL", TAB, + new AspectList().add(Aspect.MAGIC, 5).add(Aspect.ORDER, 3).add(Aspect.MIND, 3), + -1, -4, 2, new ItemStack(ModItems.ESSENTIA_TERMINAL_ITEM.get())) + .setRound().setParents("DIGISENTIA") + .setPages( + new ResearchPage("tc.research_text.ESSENTIATERMINAL.stage.1"), + new ResearchPage(RecipeRegistration.ESSENTIA_TERMINAL), + new ResearchPage(RecipeRegistration.ESSENTIA_LEVEL_EMITTER), + new ResearchPage("tc.research_text.ESSENTIATERMINAL.stage.2")) + .registerResearchItem(); + } + + // ==================== 10. (0,-2) DIGISENTIA 数字化源质==================== + // 前置: BASEENERGISTICS(基础能源学) + DISTILESSENTIA(要素蒸馏) + private static void registerDigisentia() { + new ResearchItem("DIGISENTIA", TAB, + new AspectList().add(Aspect.ORDER, 5).add(Aspect.ENTROPY, 5).add(Aspect.MAGIC, 3), + 0, -2, 1, new ItemStack(ModItems.DIFFUSION_CORE.get())) + .setRound().setParents("BASEENERGISTICS", "PSEUDO_DISTILESSENTIA") + .setPages( + new ResearchPage("tc.research_text.DIGISENTIA.stage.1"), + new ResearchPage(RecipeRegistration.DIFFUSION_CORE), + new ResearchPage(RecipeRegistration.COALESCENCE_CORE), + new ResearchPage("tc.research_text.DIGISENTIA.stage.2")) + .registerResearchItem(); + } + + // ==================== 12. (-3,-7) FOCUS_AEWRENCH 法杖核心 AE扳手==================== + // 前置: BASEENERGISTICS(基础能源学) + FOCUSFIRE(法杖核心) + private static void registerFocusAEWrench() { + new ResearchItem("FOCUS_AEWRENCH", TAB, + new AspectList().add(Aspect.TOOL, 5).add(Aspect.ENERGY, 5).add(Aspect.MECHANISM, 3), + -3, -7, 3, new ItemStack(ModItems.FOCUS_AEWRENCH.get())) + .setRound().setParents("PSEUDO_FOCUSFIRE").setParentsHidden("BASEENERGISTICS") + .setPages( + new ResearchPage("tc.research_text.FOCUS_AEWRENCH"), + new ResearchPage(RecipeRegistration.FOCUS_AEWRENCH_RECIPE)) + .registerResearchItem(); + } + + // ==================== 13. (-5,-5) CERTUS_DUPE 赛特斯石英复制==================== + // 前置: ALCHEMICALDUPLICATION(炼金复制) + BASEENERGISTICS(基础能源学) + private static void registerCertusDupe() { + new ResearchItem("CERTUS_DUPE", TAB, + new AspectList().add(Aspect.CRYSTAL, 5).add(Aspect.MAGIC, 5).add(Aspect.EXCHANGE, 5), + -5, -5, 2, new ItemStack(appeng.core.definitions.AEItems.CERTUS_QUARTZ_CRYSTAL.asItem())) + .setRound().setParents("PSEUDO_ALCHEMICALDUPLICATION").setParentsHidden("BASEENERGISTICS") + .setPages(new ResearchPage("tc.research_text.CERTUS_DUPE")) + .registerResearchItem(); + } + + // ==================== 14. (1,-4) VIBRATIONCHAMBER 源质谐振仓==================== + // 前置: DIGISENTIA + private static void registerEssentiaVibrationChamber() { + new ResearchItem("ESSENTIAVIBRATIONCHAMBER", TAB, + new AspectList().add(Aspect.ENERGY, 8).add(Aspect.MECHANISM, 5).add(Aspect.FIRE, 3), + 1, -4, 3, new ItemStack(ModItems.ESSENTIA_VIBRATION_CHAMBER_ITEM.get())) + .setRound().setParents("DIGISENTIA") + .setPages( + new ResearchPage("tc.research_text.ESSENTIAVIBRATIONCHAMBER"), + new ResearchPage(RecipeRegistration.ESSENTIA_VIBRATION_CHAMBER)) + .registerResearchItem(); + } + + // ==================== 15. (-4,-4) DISTILLATIONENCODER 蒸馏编码台==================== + // 前置: ESSENTIABUSES + private static void registerDistillationEncoder() { + new ResearchItem("DISTILLATIONENCODER", TAB, + new AspectList().add(Aspect.MECHANISM, 5).add(Aspect.ORDER, 5).add(Aspect.ENTROPY, 5), + -4, -4, 3, new ItemStack(ModItems.DISTILLATION_ENCODER_ITEM.get())) + .setRound().setParents("ESSENTIABUSES") + .setPages( + new ResearchPage("tc.research_text.DISTILLATIONENCODER"), + new ResearchPage(RecipeRegistration.DISTILLATION_ENCODER_BLOCK)) + .registerResearchItem(); + } + + // ==================== 16. (0,-6) GOLEMWIFIBACKPACK 无线傀儡背包==================== + // 前置: DIGISENTIA + COREGATHER(傀儡核心:聚集) + private static void registerGolemWifiBackpack() { + new ResearchItem("GOLEMWIFIBACKPACK", TAB, + new AspectList().add(Aspect.MAGIC, 5).add(Aspect.MECHANISM, 5).add(Aspect.MIND, 3), + 0, -6, 3, new ItemStack(ModItems.GOLEM_WIFI_BACKPACK.get())) + .setRound().setParents("PSEUDO_COREGATHER").setParentsHidden("DIGISENTIA") + .setPages( + new ResearchPage("tc.research_text.GOLEMWIFI"), + new ResearchPage(RecipeRegistration.GOLEM_WIFI_BACKPACK_RECIPE)) + .registerResearchItem(); + } + +} \ No newline at end of file diff --git a/src/main/java/thaumicenergistics/common/integration/tc/VisProviderProxy.java b/src/main/java/thaumicenergistics/common/integration/tc/VisProviderProxy.java new file mode 100644 index 0000000..fd6a8d5 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/integration/tc/VisProviderProxy.java @@ -0,0 +1,85 @@ +package thaumicenergistics.common.integration.tc; + +import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.visnet.TileVisNode; +import thaumcraft.api.visnet.VisNetHandler; +import thaumicenergistics.init.ModBlockEntities; +import thaumicenergistics.common.parts.VisInterfacePart; + +import java.lang.ref.WeakReference; + +/** + * 注册到 {@link VisNetHandler} 的虚拟 TC vis 源,位于 Vis Interface "provider" 端前方。 + * 附近 TC 机器(法杖、奥术工作台等)吸取 vis 时,请求转交给所属 {@link VisInterfacePart}, + * 由其从所面对(或 P2P 连接的另一端)的 TC 中继抽取 vis。 + * + * 自 1.7.10 (RV3) 移植,适配 1.21.1 TileVisNode API。代理不放置为真实方块实体; + * 用宿主方块坐标构造,手动注入 level,使 {@link VisNetHandler#addSource} 能按 WorldCoordinates 存储。 + */ +public class VisProviderProxy extends TileVisNode { + /** + * vis 可被抽取的距离(格)。与 TC 中继范围一致,保证附近机器可用。 + */ + private static final int VIS_RANGE = 8; + + /** + * 所属 vis interface 部件。用弱引用持有,避免代理使部件(及所在 chunk)无法回收。 + */ + private WeakReference owner; + + public VisProviderProxy(BlockPos pos, BlockState state) { + super(ModBlockEntities.VIS_PROVIDER_PROXY.get(), pos, state); + this.owner = new WeakReference<>(null); + } + + /** + * 构造后绑定所属部件与世界(BlockEntityType supplier 无法传入 owner,故在此注入)。 + */ + public void bind(VisInterfacePart part, Level level) { + this.owner = new WeakReference<>(part); + // 真实方块实体的 level 由 chunk loader 设置;虚拟代理需手动注入。 + this.setLevel(level); + } + + @Override + public int getRange() { + return VisProviderProxy.VIS_RANGE; + } + + @Override + public boolean isSource() { + return true; + } + + /** + * 机器请求 vis 时由 {@link VisNetHandler#drainVis} 调用。 + * 转交所属部件执行实际的中继抽取(消耗 AE 能量)并处理递归保护。 + */ + @Override + public int consumeVis(Aspect aspect, int centivis) { + VisInterfacePart part = this.owner.get(); + if (part == null || !part.isActive()) { + return 0; + } + ResourceLocation aspectId = ResourceLocation.fromNamespaceAndPath("thaumcraft", aspect.tag()); + return part.consumeVis(aspectId, centivis); + } + + /** + * 无焦点过滤:供应任意要素的 vis(对应常见无焦点中继)。 + * 返回 -1 保持代理与所有请求节点兼容。 + */ + @Override + public byte getAttunement() { + return -1; + } + + @Override + public void invalidate() { + VisNetHandler.removeNode(this); + } +} diff --git a/src/main/java/thaumicenergistics/common/inventory/HandlerKnowledgeCore.java b/src/main/java/thaumicenergistics/common/inventory/HandlerKnowledgeCore.java new file mode 100644 index 0000000..38b92a1 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/inventory/HandlerKnowledgeCore.java @@ -0,0 +1,148 @@ +package thaumicenergistics.common.inventory; + +import java.util.ArrayList; +import net.minecraft.core.component.DataComponents; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.Tag; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.component.CustomData; +import thaumicenergistics.common.integration.tc.ArcaneCraftingPattern; +import thaumicenergistics.init.ModItems; + +/** + * 管理知识核心中存储的奥术合成样板。 + * 从 1.7.10 HandlerKnowledgeCore 移植。 + */ +public class HandlerKnowledgeCore { + private static final String NBTKEY_PATTERNS = "Patterns"; + public static final int MAXIMUM_STORED_PATTERNS = 21; + + private final ArrayList patterns = new ArrayList<>(MAXIMUM_STORED_PATTERNS); + private ItemStack kCore; + + public HandlerKnowledgeCore() {} + + public HandlerKnowledgeCore(ItemStack kCore) { + open(kCore); + } + + public void open(ItemStack kCore) { + close(); + this.kCore = kCore; + loadKCoreData(); + } + + public void close() { + this.kCore = null; + this.patterns.clear(); + } + + public boolean hasCore() { + return this.kCore != null; + } + + public boolean isHandlingCore(ItemStack kCore) { + if (this.kCore == null) return false; + if (kCore == null || kCore.isEmpty()) return false; + if (!kCore.is(ModItems.KNOWLEDGE_CORE.get())) return false; + return ItemStack.matches(this.kCore, kCore); + } + + public boolean hasRoomToStorePattern() { + return this.patterns.size() < MAXIMUM_STORED_PATTERNS; + } + + public boolean hasPatternFor(ItemStack resultStack) { + return getPatternForItem(resultStack) != null; + } + + public ArcaneCraftingPattern getPatternForItem(ItemStack resultStack) { + for (ArcaneCraftingPattern p : this.patterns) { + if (p != null && p.getResult() != null && !p.getResult().isEmpty()) { + if (ItemStack.isSameItem(p.getResult(), resultStack)) { + return p; + } + } + } + return null; + } + + public ArrayList getPatterns() { + return this.patterns; + } + + public ArrayList getStoredOutputs() { + ArrayList results = new ArrayList<>(); + for (ArcaneCraftingPattern p : this.patterns) { + if (p != null && p.getResult() != null && !p.getResult().isEmpty()) { + results.add(p.getResult().copy()); + } + } + return results; + } + + public void addPattern(ArcaneCraftingPattern pattern) { + if (pattern == null || !pattern.isPatternValid()) return; + if (!hasRoomToStorePattern()) return; + + ArcaneCraftingPattern existing = getPatternForItem(pattern.getResult()); + if (existing == null) { + this.patterns.add(pattern); + saveKCoreData(); + } + } + + public void removePattern(ArcaneCraftingPattern pattern) { + if (this.patterns.remove(pattern)) { + saveKCoreData(); + } + } + + private CompoundTag getOrCreateNBT() { + CustomData customData = this.kCore.get(DataComponents.CUSTOM_DATA); + if (customData == null) { + return new CompoundTag(); + } + return customData.copyTag(); + } + + private void setNBT(CompoundTag tag) { + this.kCore.set(DataComponents.CUSTOM_DATA, CustomData.of(tag)); + } + + private void loadKCoreData() { + this.patterns.clear(); + CompoundTag data = getOrCreateNBT(); + + if (data.contains(NBTKEY_PATTERNS)) { + ListTag plist = data.getList(NBTKEY_PATTERNS, Tag.TAG_COMPOUND); + for (int i = 0; i < plist.size(); i++) { + try { + ArcaneCraftingPattern pattern = new ArcaneCraftingPattern(plist.getCompound(i)); + if (pattern.isPatternValid()) { + this.patterns.add(pattern); + } + } catch (Exception ignored) {} + } + } + } + + private void saveKCoreData() { + CompoundTag data = getOrCreateNBT(); + ListTag plist = new ListTag(); + + for (ArcaneCraftingPattern pattern : this.patterns) { + if (pattern == null || !pattern.isPatternValid()) continue; + plist.add(pattern.writeToNBT(new CompoundTag())); + } + + if (!plist.isEmpty()) { + data.put(NBTKEY_PATTERNS, plist); + } else { + data.remove(NBTKEY_PATTERNS); + } + + setNBT(data); + } +} diff --git a/src/main/java/thaumicenergistics/common/items/ItemEssentiaCell.java b/src/main/java/thaumicenergistics/common/items/ItemEssentiaCell.java new file mode 100644 index 0000000..07e95d0 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/items/ItemEssentiaCell.java @@ -0,0 +1,226 @@ +package thaumicenergistics.common.items; + +import java.util.ArrayList; +import java.util.Optional; +import java.util.Set; + +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.inventory.tooltip.TooltipComponent; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import appeng.api.config.Actionable; +import appeng.api.config.FuzzyMode; +import appeng.api.stacks.AEKeyType; +import appeng.api.stacks.GenericStack; +import appeng.api.stacks.KeyCounter; +import appeng.api.storage.cells.IBasicCellItem; +import appeng.api.upgrades.IUpgradeInventory; +import appeng.api.upgrades.UpgradeInventories; +import appeng.items.contents.CellConfig; +import appeng.me.cells.BasicCellInventory; +import appeng.util.ConfigInventory; +import thaumicenergistics.common.integration.appeng.AEssentiaKey; +import thaumicenergistics.common.integration.appeng.AEssentiaKeyType; +import thaumicenergistics.config.ThEConfig; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class ItemEssentiaCell extends Item implements IBasicCellItem { + + private final String tier; + private final int totalBytes; + private final int bytesPerType; + private final int totalTypes; + private final double idleDrain; + + public ItemEssentiaCell(Item.Properties props, String tier, int kilobytes, int bytesPerType, int totalTypes, double idleDrain) { + super(props.stacksTo(1)); + this.tier = tier; + this.totalBytes = kilobytes * 1024; + this.bytesPerType = bytesPerType; + this.totalTypes = totalTypes; + this.idleDrain = idleDrain; + } + + @Override + public AEKeyType getKeyType() { + return AEssentiaKeyType.INSTANCE; + } + + @Override + public int getBytes(ItemStack cellItem) { + return this.totalBytes; + } + + @Override + public int getBytesPerType(ItemStack cellItem) { + return this.bytesPerType; + } + + @Override + public int getTotalTypes(ItemStack cellItem) { + return this.totalTypes; + } + + @Override + public double getIdleDrain() { + return this.idleDrain; + } + + @Override + public boolean isStorageCell(ItemStack i) { + return true; + } + + @Override + public boolean isBlackListed(ItemStack cellItem, appeng.api.stacks.AEKey requestedAddition) { + if (requestedAddition instanceof thaumicenergistics.common.integration.appeng.AEssentiaKey) { + return false; + } + return true; + } + + @Override + public IUpgradeInventory getUpgrades(ItemStack is) { + return UpgradeInventories.forItem(is, 3); + } + + @Override + public ConfigInventory getConfigInventory(ItemStack is) { + return CellConfig.create(Set.of(AEssentiaKeyType.INSTANCE), is); + } + + @Override + public FuzzyMode getFuzzyMode(ItemStack is) { + return FuzzyMode.IGNORE_ALL; + } + + @Override + public void setFuzzyMode(ItemStack is, FuzzyMode fzMode) { + } + + @Override + public void appendHoverText(ItemStack stack, TooltipContext ctx, List tooltip, TooltipFlag flag) { + this.addCellInformationToTooltip(stack, tooltip); + } + + @Override + public Optional getTooltipImage(ItemStack stack) { + // 渲染顶部源质图标(前5种存量最高的源质) + return this.getCellTooltipImage(stack); + } + + public String getTier() { return tier; } + + // ===== 分区辅助(基于 AE2 CellConfig,与 ME 终端分区互通) ===== + + @Nullable + private static ItemEssentiaCell getCellItem(ItemStack stack) { + return stack.getItem() instanceof ItemEssentiaCell cell ? cell : null; + } + + /** 获取 cell 的分区库存(63 槽 ConfigInventory),非 cell 返回 null。 */ + @Nullable + public static ConfigInventory getPartitionInventory(ItemStack stack) { + ItemEssentiaCell cell = getCellItem(stack); + return cell == null ? null : cell.getConfigInventory(stack); + } + + /** 获取分区列表(aspect 的 ResourceLocation)。 */ + public static List getPartitionAspects(ItemStack stack) { + ConfigInventory inv = getPartitionInventory(stack); + if (inv == null) return List.of(); + List result = new ArrayList<>(); + for (int i = 0; i < inv.size(); i++) { + if (inv.getKey(i) instanceof AEssentiaKey ek) result.add(ek.getId()); + } + return result; + } + + /** 添加一个 aspect 到分区;已存在或满返回 false。 */ + public static boolean addAspectToPartition(ItemStack stack, ResourceLocation aspectId) { + ConfigInventory inv = getPartitionInventory(stack); + if (inv == null) return false; + AEssentiaKey key = AEssentiaKey.of(aspectId); + for (int i = 0; i < inv.size(); i++) { + if (key.equals(inv.getKey(i))) return false; + } + for (int i = 0; i < inv.size(); i++) { + if (inv.getKey(i) == null) { + inv.insert(i, key, 1, Actionable.MODULATE); + return true; + } + } + return false; + } + + /** 从分区移除一个 aspect;不存在返回 false。 */ + public static boolean removeAspectFromPartition(ItemStack stack, ResourceLocation aspectId) { + ConfigInventory inv = getPartitionInventory(stack); + if (inv == null) return false; + for (int i = 0; i < inv.size(); i++) { + if (inv.getKey(i) instanceof AEssentiaKey ek && ek.getId().equals(aspectId)) { + inv.setStack(i, null); + return true; + } + } + return false; + } + + /** 用 to 替换分区中的 from;from 不存在返回 false。 */ + public static boolean replaceAspectInPartition(ItemStack stack, ResourceLocation from, ResourceLocation to) { + ConfigInventory inv = getPartitionInventory(stack); + if (inv == null) return false; + AEssentiaKey newKey = AEssentiaKey.of(to); + for (int i = 0; i < inv.size(); i++) { + if (inv.getKey(i) instanceof AEssentiaKey ek && ek.getId().equals(from)) { + inv.setStack(i, new GenericStack(newKey, 1)); + return true; + } + } + return false; + } + + /** 清空全部分区。 */ + public static void clearPartitioning(ItemStack stack) { + ConfigInventory inv = getPartitionInventory(stack); + if (inv != null) inv.clear(); + } + + /** 将 cell 当前存储的源质设为分区(对应 1.7.10 的 partitionToCellContents)。 */ + public static void partitionToContents(ItemStack stack) { + ConfigInventory inv = getPartitionInventory(stack); + if (inv == null) return; + inv.clear(); + BasicCellInventory cellInv = BasicCellInventory.createInventory(stack, null); + if (cellInv == null) return; + KeyCounter counter = new KeyCounter(); + cellInv.getAvailableStacks(counter); + int slot = 0; + for (var entry : counter) { + if (entry.getKey() instanceof AEssentiaKey ek && slot < inv.size()) { + inv.insert(slot++, ek, 1, Actionable.MODULATE); + } + } + } + + // ===== 工厂方法 ===== + public static ItemEssentiaCell create1k(Item.Properties props) { + return new ItemEssentiaCell(props, "1k", 1, 8, ThEConfig.CELL_MAX_TYPES, 0.5); + } + public static ItemEssentiaCell create4k(Item.Properties props) { + return new ItemEssentiaCell(props, "4k", 4, 8, ThEConfig.CELL_MAX_TYPES, 1.0); + } + public static ItemEssentiaCell create16k(Item.Properties props) { + return new ItemEssentiaCell(props, "16k", 16, 8, ThEConfig.CELL_MAX_TYPES, 1.5); + } + public static ItemEssentiaCell create64k(Item.Properties props) { + return new ItemEssentiaCell(props, "64k", 64, 8, ThEConfig.CELL_MAX_TYPES, 2.0); + } + public static ItemEssentiaCell createCreative(Item.Properties props) { + return new ItemEssentiaCell(props, "creative", Integer.MAX_VALUE / 1024, 8, 63, 0.0); + } +} \ No newline at end of file diff --git a/src/main/java/thaumicenergistics/common/items/ItemFocusAEWrench.java b/src/main/java/thaumicenergistics/common/items/ItemFocusAEWrench.java new file mode 100644 index 0000000..6f60a75 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/items/ItemFocusAEWrench.java @@ -0,0 +1,184 @@ +package thaumicenergistics.common.items; + +import appeng.blockentity.AEBaseBlockEntity; +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +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.level.ClipContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.HitResult; +import net.minecraft.world.phys.Vec3; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; +import thaumcraft.common.items.TCFunctionalItems; +import thaumcraft.common.vis.TCVisHelper; + +import java.util.List; + +public class ItemFocusAEWrench extends TCFunctionalItems.FocusItem { + + private static final AspectList CAST_COST = new AspectList().add(Aspect.FIRE, 10).add(Aspect.AIR, 10); + + public ItemFocusAEWrench() { + super(TCFunctionalItems.FocusEffect.FIRE, new Properties().stacksTo(1)); + } + + @Override + public int focusColor(ItemStack stack, float animationTicks) { + return Aspect.ENERGY.getColor(); + } + + @Override + public TCFunctionalItems.FocusCastingAnimation castingAnimation(ItemStack stack) { + return TCFunctionalItems.FocusCastingAnimation.WAVE; + } + + @Override + public boolean isVisCostPerTick(ItemStack stack) { + return false; + } + + @Override + public AspectList visCost(ItemStack stack) { + return CAST_COST; + } + + @Override + public boolean requiresContinuousUse(ItemStack stack) { + return false; + } + + @Override + public void clearContinuousState(ItemStack wandStack) { + } + + @Override + public boolean castContinuousFromWand(Level level, Player player, ItemStack wandStack, + TCFunctionalItems.WandCastingItem wand, int remainingUseDuration) { + return false; + } + + @Override + public InteractionResultHolder use(Level level, Player player, InteractionHand hand) { + ItemStack stack = player.getItemInHand(hand); + InteractionHand otherHand = hand == InteractionHand.MAIN_HAND ? InteractionHand.OFF_HAND : InteractionHand.MAIN_HAND; + ItemStack other = player.getItemInHand(otherHand); + Item item = other.getItem(); + if (item instanceof TCFunctionalItems.WandCastingItem wand) { + if (!level.isClientSide && wand.installFocus(other, stack, player)) { + level.playSound(null, player.blockPosition(), + net.minecraft.sounds.SoundEvents.ITEM_FRAME_ADD_ITEM, + net.minecraft.sounds.SoundSource.PLAYERS, 0.45f, 1.2f); + } + return InteractionResultHolder.sidedSuccess(stack, level.isClientSide); + } + return InteractionResultHolder.pass(stack); + } + + @Override + public void appendHoverText(ItemStack stack, TooltipContext context, List tooltip, TooltipFlag flag) { + AspectList cost = this.visCost(stack); + MutableComponent costLine = Component.translatable( + this.isVisCostPerTick(stack) ? "item.Focus.cost2" : "item.Focus.cost1") + .append(":").withStyle(ChatFormatting.GRAY); + for (Aspect aspect : cost.aspects()) { + costLine = costLine.append(Component.literal( + " " + TCVisHelper.formatCentivis(cost.amount(aspect))) + .withStyle(style -> style.withColor(aspect.color()))); + } + tooltip.add(costLine); + super.appendHoverText(stack, context, tooltip, flag); + } + + @Override + public boolean castFromWand(Level level, Player player, ItemStack wandStack, + TCFunctionalItems.WandCastingItem wand) { + ItemStack focusStack = wand.getFocus(wandStack); + if (focusStack.getItem() != this) { + return false; + } + + BlockHitResult hit = rayTrace(player, level, 24.0); + if (hit.getType() != HitResult.Type.BLOCK) { + return false; + } + + if (!player.isShiftKeyDown()) { + return false; + } + + AspectList cost = this.visCost(focusStack); + if (!wand.consumeVisCost(wandStack, player, cost, false)) { + player.displayClientMessage( + Component.translatable("message.thaumcraft.wand.not_enough_vis"), true); + return false; + } + if (!wand.consumeVisCost(wandStack, player, cost, true)) { + return false; + } + + BlockPos pos = hit.getBlockPos(); + boolean handled = handleWrenchAction(level, player, hit, wandStack); + + if (handled) { + spawnBeamParticles(level, player, pos); + return true; + } + + return false; + } + + private boolean handleWrenchAction(Level level, Player player, BlockHitResult hit, ItemStack wandStack) { + BlockPos pos = hit.getBlockPos(); + var blockEntity = level.getBlockEntity(pos); + + if (blockEntity instanceof AEBaseBlockEntity aeBlockEntity) { + InteractionResult result = aeBlockEntity.disassembleWithWrench(player, level, hit, wandStack); + return result.consumesAction(); + } + + return false; + } + + public static void spawnBeamParticles(Level level, Player player, BlockPos targetPos) { + if (!(level instanceof ServerLevel serverLevel) || !(player instanceof ServerPlayer serverPlayer)) { + return; + } + + Vec3 start = player.getEyePosition(1.0f); + Vec3 end = Vec3.atCenterOf(targetPos); + Vec3 direction = end.subtract(start); + double distance = direction.length(); + if (distance < 0.5) { + return; + } + Vec3 step = direction.normalize().scale(0.5); + + Vec3 current = start.add(step); + int steps = (int) (distance / 0.5); + for (int i = 0; i < steps; i++) { + serverLevel.sendParticles(serverPlayer, ParticleTypes.END_ROD, true, + current.x, current.y, current.z, + 1, 0.0, 0.0, 0.0, 0.0); + current = current.add(step); + } + } + + private static BlockHitResult rayTrace(Player player, Level level, double range) { + Vec3 eye = player.getEyePosition(1.0f); + Vec3 end = eye.add(player.getLookAngle().scale(range)); + return level.clip(new ClipContext(eye, end, ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player)); + } +} \ No newline at end of file diff --git a/src/main/java/thaumicenergistics/common/items/ItemGolemWirelessBackpack.java b/src/main/java/thaumicenergistics/common/items/ItemGolemWirelessBackpack.java new file mode 100644 index 0000000..3bc54e5 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/items/ItemGolemWirelessBackpack.java @@ -0,0 +1,57 @@ +package thaumicenergistics.common.items; + +import net.minecraft.core.GlobalPos; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import appeng.api.features.IGridLinkableHandler; +import appeng.api.ids.AEComponents; +import appeng.core.localization.GuiText; +import appeng.core.localization.Tooltips; + +import java.util.List; + +public class ItemGolemWirelessBackpack extends Item { + + public static final IGridLinkableHandler LINKABLE_HANDLER = new LinkableHandler(); + + public ItemGolemWirelessBackpack() { + super(new Item.Properties().stacksTo(1).durability(0)); + } + + @Override + public void appendHoverText(ItemStack stack, TooltipContext context, List lines, TooltipFlag flag) { + super.appendHoverText(stack, context, lines, flag); + if (getLinkedPosition(stack) == null) { + lines.add(Tooltips.of(GuiText.Unlinked, Tooltips.RED)); + } else { + lines.add(Tooltips.of(GuiText.Linked, Tooltips.GREEN)); + } + } + + public GlobalPos getLinkedPosition(ItemStack stack) { + return stack.get(AEComponents.WIRELESS_LINK_TARGET); + } + + public static boolean isLinked(ItemStack stack) { + return stack.get(AEComponents.WIRELESS_LINK_TARGET) != null; + } + + private static class LinkableHandler implements IGridLinkableHandler { + @Override + public boolean canLink(ItemStack stack) { + return stack.getItem() instanceof ItemGolemWirelessBackpack; + } + + @Override + public void link(ItemStack stack, GlobalPos pos) { + stack.set(AEComponents.WIRELESS_LINK_TARGET, pos); + } + + @Override + public void unlink(ItemStack stack) { + stack.remove(AEComponents.WIRELESS_LINK_TARGET); + } + } +} \ No newline at end of file diff --git a/src/main/java/thaumicenergistics/common/items/PartItemArcaneCraftingTerminal.java b/src/main/java/thaumicenergistics/common/items/PartItemArcaneCraftingTerminal.java new file mode 100644 index 0000000..a72f929 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/items/PartItemArcaneCraftingTerminal.java @@ -0,0 +1,43 @@ +package thaumicenergistics.common.items; + +import appeng.api.parts.IPartItem; +import appeng.api.parts.PartHelper; +import net.minecraft.network.chat.Component; +import net.minecraft.world.InteractionResult; +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 org.jetbrains.annotations.Nullable; +import thaumicenergistics.common.parts.ArcaneCraftingTerminalPart; + +import java.util.List; + +public class PartItemArcaneCraftingTerminal extends Item implements IPartItem { + + public PartItemArcaneCraftingTerminal(Properties properties) { + super(properties); + } + + @Override + public InteractionResult useOn(UseOnContext context) { + return PartHelper.usePartItem(context); + } + + @Override + public Class getPartClass() { + return ArcaneCraftingTerminalPart.class; + } + + @Override + public ArcaneCraftingTerminalPart createPart() { + return new ArcaneCraftingTerminalPart(this); + } + + @Override + public void appendHoverText(ItemStack stack, @Nullable Item.TooltipContext context, + List tooltip, TooltipFlag flag) { + super.appendHoverText(stack, context, tooltip, flag); + tooltip.add(Component.translatable("tooltip.thaumicenergistics.arcane_crafting_terminal.desc")); + } +} diff --git a/src/main/java/thaumicenergistics/common/items/PartItemEssentiaExportBus.java b/src/main/java/thaumicenergistics/common/items/PartItemEssentiaExportBus.java new file mode 100644 index 0000000..7f2a19f --- /dev/null +++ b/src/main/java/thaumicenergistics/common/items/PartItemEssentiaExportBus.java @@ -0,0 +1,49 @@ +package thaumicenergistics.common.items; + +import appeng.api.parts.IPartItem; +import appeng.api.parts.PartHelper; +import net.minecraft.network.chat.Component; +import net.minecraft.world.InteractionResult; +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 org.jetbrains.annotations.Nullable; +import thaumicenergistics.common.parts.EssentiaExportBusPart; + +import java.util.List; + +public class PartItemEssentiaExportBus extends Item implements IPartItem { + + public static PartItemEssentiaExportBus create() { + return new PartItemEssentiaExportBus(new Item.Properties().stacksTo(64)); + } + + public PartItemEssentiaExportBus(Properties properties) { + super(properties); + } + + @Override + public InteractionResult useOn(UseOnContext context) { + return PartHelper.usePartItem(context); + } + + @Override + public Class getPartClass() { + return EssentiaExportBusPart.class; + } + + // 传 this:本类实现了 IPartItem + @Override + public EssentiaExportBusPart createPart() { + return new EssentiaExportBusPart(this); + } + + @Override + public void appendHoverText(ItemStack stack, @Nullable Item.TooltipContext context, + List tooltip, TooltipFlag flag) { + super.appendHoverText(stack, context, tooltip, flag); + tooltip.add(Component.translatable("tooltip.thaumicenergistics.essentia_export_bus.desc")); + tooltip.add(Component.translatable("tooltip.thaumicenergistics.essentia_export_bus.hint")); + } +} \ No newline at end of file diff --git a/src/main/java/thaumicenergistics/common/items/PartItemEssentiaImportBus.java b/src/main/java/thaumicenergistics/common/items/PartItemEssentiaImportBus.java new file mode 100644 index 0000000..93156f7 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/items/PartItemEssentiaImportBus.java @@ -0,0 +1,49 @@ +package thaumicenergistics.common.items; + +import appeng.api.parts.IPartItem; +import appeng.api.parts.PartHelper; +import net.minecraft.network.chat.Component; +import net.minecraft.world.InteractionResult; +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 org.jetbrains.annotations.Nullable; +import thaumicenergistics.common.parts.EssentiaImportBusPart; + +import java.util.List; + +public class PartItemEssentiaImportBus extends Item implements IPartItem { + + public static PartItemEssentiaImportBus create() { + return new PartItemEssentiaImportBus(new Item.Properties().stacksTo(64)); + } + + public PartItemEssentiaImportBus(Properties properties) { + super(properties); + } + + @Override + public InteractionResult useOn(UseOnContext context) { + return PartHelper.usePartItem(context); + } + + @Override + public Class getPartClass() { + return EssentiaImportBusPart.class; + } + + // 构造器要求 IPartItem partItem,传 this 即可 + @Override + public EssentiaImportBusPart createPart() { + return new EssentiaImportBusPart(this); + } + + @Override + public void appendHoverText(ItemStack stack, @Nullable Item.TooltipContext context, + List tooltip, TooltipFlag flag) { + super.appendHoverText(stack, context, tooltip, flag); + tooltip.add(Component.translatable("tooltip.thaumicenergistics.essentia_import_bus.desc")); + tooltip.add(Component.translatable("tooltip.thaumicenergistics.essentia_import_bus.hint")); + } +} \ No newline at end of file diff --git a/src/main/java/thaumicenergistics/common/items/PartItemEssentiaLevelEmitter.java b/src/main/java/thaumicenergistics/common/items/PartItemEssentiaLevelEmitter.java new file mode 100644 index 0000000..61397ab --- /dev/null +++ b/src/main/java/thaumicenergistics/common/items/PartItemEssentiaLevelEmitter.java @@ -0,0 +1,43 @@ +package thaumicenergistics.common.items; + +import appeng.api.parts.IPartItem; +import appeng.api.parts.PartHelper; +import net.minecraft.network.chat.Component; +import net.minecraft.world.InteractionResult; +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 org.jetbrains.annotations.Nullable; +import thaumicenergistics.common.parts.EssentiaLevelEmitterPart; + +import java.util.List; + +public class PartItemEssentiaLevelEmitter extends Item implements IPartItem { + + public PartItemEssentiaLevelEmitter(Properties properties) { + super(properties); + } + + @Override + public InteractionResult useOn(UseOnContext context) { + return PartHelper.usePartItem(context); + } + + @Override + public Class getPartClass() { + return EssentiaLevelEmitterPart.class; + } + + @Override + public EssentiaLevelEmitterPart createPart() { + return new EssentiaLevelEmitterPart(this); + } + + @Override + public void appendHoverText(ItemStack stack, @Nullable Item.TooltipContext context, + List tooltip, TooltipFlag flag) { + super.appendHoverText(stack, context, tooltip, flag); + tooltip.add(Component.translatable("tooltip.thaumicenergistics.essentia_level_emitter.desc")); + } +} diff --git a/src/main/java/thaumicenergistics/common/items/PartItemEssentiaStorageBus.java b/src/main/java/thaumicenergistics/common/items/PartItemEssentiaStorageBus.java new file mode 100644 index 0000000..05817b1 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/items/PartItemEssentiaStorageBus.java @@ -0,0 +1,48 @@ +package thaumicenergistics.common.items; + +import appeng.api.parts.IPartItem; +import appeng.api.parts.PartHelper; +import net.minecraft.network.chat.Component; +import net.minecraft.world.InteractionResult; +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 org.jetbrains.annotations.Nullable; +import thaumicenergistics.common.parts.EssentiaStorageBusPart; + +import java.util.List; + +public class PartItemEssentiaStorageBus extends Item implements IPartItem { + + public static PartItemEssentiaStorageBus create() { + return new PartItemEssentiaStorageBus(new Item.Properties().stacksTo(64)); + } + + public PartItemEssentiaStorageBus(Properties properties) { + super(properties); + } + + @Override + public InteractionResult useOn(UseOnContext context) { + return PartHelper.usePartItem(context); + } + + @Override + public Class getPartClass() { + return EssentiaStorageBusPart.class; + } + + // 传 this:本类实现了 IPartItem + @Override + public EssentiaStorageBusPart createPart() { + return new EssentiaStorageBusPart(this); + } + + @Override + public void appendHoverText(ItemStack stack, @Nullable Item.TooltipContext context, + List tooltip, TooltipFlag flag) { + super.appendHoverText(stack, context, tooltip, flag); + tooltip.add(Component.translatable("tooltip.thaumicenergistics.essentia_storage_bus.desc")); + } +} \ No newline at end of file diff --git a/src/main/java/thaumicenergistics/common/items/PartItemEssentiaTerminal.java b/src/main/java/thaumicenergistics/common/items/PartItemEssentiaTerminal.java new file mode 100644 index 0000000..8ace266 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/items/PartItemEssentiaTerminal.java @@ -0,0 +1,43 @@ +package thaumicenergistics.common.items; + +import appeng.api.parts.IPartItem; +import appeng.api.parts.PartHelper; +import net.minecraft.network.chat.Component; +import net.minecraft.world.InteractionResult; +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 org.jetbrains.annotations.Nullable; +import thaumicenergistics.common.parts.EssentiaTerminalPart; + +import java.util.List; + +public class PartItemEssentiaTerminal extends Item implements IPartItem { + + public PartItemEssentiaTerminal(Properties properties) { + super(properties); + } + + @Override + public InteractionResult useOn(UseOnContext context) { + return PartHelper.usePartItem(context); + } + + @Override + public Class getPartClass() { + return EssentiaTerminalPart.class; + } + + @Override + public EssentiaTerminalPart createPart() { + return new EssentiaTerminalPart(this); + } + + @Override + public void appendHoverText(ItemStack stack, @Nullable TooltipContext context, + List tooltip, TooltipFlag flag) { + super.appendHoverText(stack, context, tooltip, flag); + tooltip.add(Component.translatable("tooltip.thaumicenergistics.essentia_terminal.desc")); + } +} \ No newline at end of file diff --git a/src/main/java/thaumicenergistics/common/items/PartItemVisInterface.java b/src/main/java/thaumicenergistics/common/items/PartItemVisInterface.java new file mode 100644 index 0000000..77dacd2 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/items/PartItemVisInterface.java @@ -0,0 +1,24 @@ +package thaumicenergistics.common.items; + +import appeng.items.parts.PartItem; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import org.jetbrains.annotations.Nullable; +import thaumicenergistics.common.parts.VisInterfacePart; + +import java.util.List; + +public class PartItemVisInterface extends PartItem { + + public PartItemVisInterface(Properties properties) { + super(properties, VisInterfacePart.class, VisInterfacePart::new); + } + + @Override + public void appendHoverText(ItemStack stack, @Nullable TooltipContext context, + List tooltip, TooltipFlag flag) { + super.appendHoverText(stack, context, tooltip, flag); + tooltip.add(Component.translatable("tooltip.thaumicenergistics.vis_interface.desc")); + } +} diff --git a/src/main/java/thaumicenergistics/common/items/WirelessEssentiaTerminalItem.java b/src/main/java/thaumicenergistics/common/items/WirelessEssentiaTerminalItem.java new file mode 100644 index 0000000..ca785b0 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/items/WirelessEssentiaTerminalItem.java @@ -0,0 +1,43 @@ +package thaumicenergistics.common.items; + +import java.util.function.DoubleSupplier; + +import org.jetbrains.annotations.Nullable; + +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.phys.BlockHitResult; +import appeng.helpers.WirelessTerminalMenuHost; +import appeng.items.tools.powered.WirelessTerminalItem; +import appeng.menu.locator.ItemMenuHostLocator; +import appeng.menu.me.common.MEStorageMenu; + +/** + * 无线源质终端物品。继承 AE2 的WirelessTerminalItem + * 右键使用时打开仅显示源质的 AE2 无线终端 GUI。 + */ +public class WirelessEssentiaTerminalItem extends WirelessTerminalItem { + + public WirelessEssentiaTerminalItem(DoubleSupplier powerCapacity, Properties props) { + super(powerCapacity, props); + } + + @Override + public MenuType getMenuType() { + return MEStorageMenu.WIRELESS_TYPE; + } + + @Override + @Nullable + public WirelessTerminalMenuHost getMenuHost( + Player player, + ItemMenuHostLocator locator, + @Nullable BlockHitResult hitResult) { + return new WirelessEssentiaTerminalMenuHost( + this, + player, + locator, + (p, subMenu) -> this.openFromInventory(p, locator, true)); + } +} diff --git a/src/main/java/thaumicenergistics/common/items/WirelessEssentiaTerminalMenuHost.java b/src/main/java/thaumicenergistics/common/items/WirelessEssentiaTerminalMenuHost.java new file mode 100644 index 0000000..d468522 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/items/WirelessEssentiaTerminalMenuHost.java @@ -0,0 +1,35 @@ +package thaumicenergistics.common.items; + +import java.util.function.BiConsumer; + +import net.minecraft.world.entity.player.Player; +import appeng.api.util.KeyTypeSelection; +import appeng.helpers.WirelessTerminalMenuHost; +import appeng.menu.ISubMenu; +import appeng.menu.locator.ItemMenuHostLocator; + +/** + * 无线源质终端的 MenuHost:继承 AE2 WirelessTerminalMenuHost,覆盖 getKeyTypeSelection() + * 仅允许源质类型(其余 WAP 连接/电力/存储复用父类)。 + */ +public class WirelessEssentiaTerminalMenuHost + extends WirelessTerminalMenuHost { + + public WirelessEssentiaTerminalMenuHost( + WirelessEssentiaTerminalItem item, + Player player, + ItemMenuHostLocator locator, + BiConsumer returnToMainMenu) { + super(item, player, locator, returnToMainMenu); + } + + /** + * 仅允许源质类型,禁止物品和流体(与 EssentiaTerminalPart 一致)。 + */ + @Override + public KeyTypeSelection getKeyTypeSelection() { + return new KeyTypeSelection( + () -> {}, + keyType -> keyType == thaumicenergistics.common.integration.appeng.AEssentiaKeyType.INSTANCE); + } +} diff --git a/src/main/java/thaumicenergistics/common/network/CellWorkbenchC2SPacket.java b/src/main/java/thaumicenergistics/common/network/CellWorkbenchC2SPacket.java new file mode 100644 index 0000000..02fb492 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/network/CellWorkbenchC2SPacket.java @@ -0,0 +1,118 @@ +package thaumicenergistics.common.network; + +import net.minecraft.client.Minecraft; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; +import net.neoforged.neoforge.network.PacketDistributor; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.common.container.ContainerEssentiaCellWorkbench; + +/** + * 客户端→服务端 网络包:源质元件工作台分区操作。 + * 操作类型见 ACTION_* 常量;aspectA/aspectB 仅在对应操作使用(其余传 EMPTY)。 + */ +public record CellWorkbenchC2SPacket( + int containerId, + int action, + ResourceLocation aspectA, + ResourceLocation aspectB +) implements CustomPacketPayload { + + public static final int ACTION_REQUEST = 0; + public static final int ACTION_ADD = 1; + public static final int ACTION_REMOVE = 2; + public static final int ACTION_REPLACE = 3; + public static final int ACTION_CLEAR = 4; + public static final int ACTION_PARTITION_TO_CONTENTS = 5; + + private static final ResourceLocation EMPTY = ResourceLocation.withDefaultNamespace("empty"); + + public static final Type TYPE = + new Type<>(ThaumicEnergistics.id("cell_workbench_c2s")); + + public static final StreamCodec STREAM_CODEC = + StreamCodec.composite( + ByteBufCodecs.VAR_INT, CellWorkbenchC2SPacket::containerId, + ByteBufCodecs.VAR_INT, CellWorkbenchC2SPacket::action, + ResourceLocation.STREAM_CODEC, CellWorkbenchC2SPacket::aspectA, + ResourceLocation.STREAM_CODEC, CellWorkbenchC2SPacket::aspectB, + CellWorkbenchC2SPacket::new + ); + + @Override + public Type type() { + return TYPE; + } + + // ===== 客户端静态发送(从当前打开的工作台菜单自动取 containerId) ===== + + private static void send(int action, ResourceLocation a, ResourceLocation b) { + var player = Minecraft.getInstance().player; + if (player == null) return; + PacketDistributor.sendToServer(new CellWorkbenchC2SPacket(player.containerMenu.containerId, action, a, b)); + } + + public static void sendRequestPartitions() { + send(ACTION_REQUEST, EMPTY, EMPTY); + } + + public static void sendAddAspect(ResourceLocation aspect) { + send(ACTION_ADD, aspect, EMPTY); + } + + public static void sendRemoveAspect(ResourceLocation aspect) { + send(ACTION_REMOVE, aspect, EMPTY); + } + + public static void sendReplaceAspect(ResourceLocation from, ResourceLocation to) { + send(ACTION_REPLACE, from, to); + } + + public static void sendClear() { + send(ACTION_CLEAR, EMPTY, EMPTY); + } + + public static void sendPartitionToContents() { + send(ACTION_PARTITION_TO_CONTENTS, EMPTY, EMPTY); + } + + // ===== 服务端处理 ===== + + public void handleOnServer(IPayloadContext ctx) { + ctx.enqueueWork(() -> { + if (ctx.player().containerMenu.containerId == this.containerId + && ctx.player().containerMenu instanceof ContainerEssentiaCellWorkbench menu) { + boolean changed; + switch (this.action) { + case ACTION_REQUEST -> { + if (ctx.player() instanceof net.minecraft.server.level.ServerPlayer sp) { + CellWorkbenchSyncPacket.sendToClient(sp, menu.getPartitionAspects()); + } + return; + } + case ACTION_ADD -> changed = menu.addAspectToPartition(this.aspectA); + case ACTION_REMOVE -> changed = menu.removeAspectFromPartition(this.aspectA); + case ACTION_REPLACE -> changed = menu.replaceAspectInPartition(this.aspectA, this.aspectB); + case ACTION_CLEAR -> { + menu.clearPartitioning(); + changed = true; + } + case ACTION_PARTITION_TO_CONTENTS -> { + menu.partitionToContents(); + changed = true; + } + default -> changed = false; + } + if (changed) { + if (ctx.player() instanceof net.minecraft.server.level.ServerPlayer sp) { + CellWorkbenchSyncPacket.sendToClient(sp, menu.getPartitionAspects()); + } + } + } + }); + } +} diff --git a/src/main/java/thaumicenergistics/common/network/CellWorkbenchSyncPacket.java b/src/main/java/thaumicenergistics/common/network/CellWorkbenchSyncPacket.java new file mode 100644 index 0000000..fd69135 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/network/CellWorkbenchSyncPacket.java @@ -0,0 +1,64 @@ +package thaumicenergistics.common.network; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.client.Minecraft; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerPlayer; +import net.neoforged.neoforge.network.PacketDistributor; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.common.container.GuiEssentiaCellWorkbench; + +/** + * 服务端→客户端 网络包:同步源质元件工作台的分区列表。 + * + * 客户端收到后更新 {@link GuiEssentiaCellWorkbench#updatePartitions},刷新 63 个分区格。 + */ +public record CellWorkbenchSyncPacket( + List partitions +) implements CustomPacketPayload { + + public static final Type TYPE = + new Type<>(ThaumicEnergistics.id("cell_workbench_sync")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.of( + (buf, pkt) -> { + buf.writeVarInt(pkt.partitions.size()); + for (ResourceLocation rl : pkt.partitions) { + ResourceLocation.STREAM_CODEC.encode(buf, rl); + } + }, + buf -> { + int n = buf.readVarInt(); + List list = new ArrayList<>(n); + for (int i = 0; i < n; i++) { + list.add(ResourceLocation.STREAM_CODEC.decode(buf)); + } + return new CellWorkbenchSyncPacket(list); + } + ); + + @Override + public Type type() { + return TYPE; + } + + /** 服务端发送分区列表到指定玩家。 */ + public static void sendToClient(ServerPlayer player, List partitions) { + PacketDistributor.sendToPlayer(player, new CellWorkbenchSyncPacket(partitions)); + } + + /** 客户端处理:更新打开的工作台 GUI 分区格。 */ + public void handleOnClient(IPayloadContext ctx) { + ctx.enqueueWork(() -> { + if (Minecraft.getInstance().screen instanceof GuiEssentiaCellWorkbench gui) { + gui.updatePartitions(this.partitions); + } + }); + } +} diff --git a/src/main/java/thaumicenergistics/common/network/GolemBackpackClientData.java b/src/main/java/thaumicenergistics/common/network/GolemBackpackClientData.java new file mode 100644 index 0000000..2060ba0 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/network/GolemBackpackClientData.java @@ -0,0 +1,74 @@ +package thaumicenergistics.common.network; + +import net.neoforged.api.distmarker.Dist; +import net.neoforged.api.distmarker.OnlyIn; +import thaumicenergistics.common.entities.BackpackSkins; +import thaumcraft.common.entities.golem.ThaumcraftGolemEntity; + +import java.util.Map; +import java.util.WeakHashMap; + +/** + * 客户端侧缓存:存储每个傀儡的背包连接状态和皮肤。 + * + * 由 {@link GolemBackpackSyncPacket#handleOnClient} 写入, + * 由 {@link thaumicenergistics.client.render.layer.GolemBackpackLayer} 读取。 + * + * 使用 WeakHashMap 以避免实体被 GC 后内存泄漏。 + * + * 对应 1.7.10 的 {@code WirelessClientData},但简化为静态缓存而非挂在 handlerData 上。 + */ +@OnlyIn(Dist.CLIENT) +public final class GolemBackpackClientData { + + private GolemBackpackClientData() {} + + /** 傀儡 → 连接状态 (0=无背包, 1=在范围内, 2=超出范围) */ + private static final Map connectionStatusMap = new WeakHashMap<>(); + + /** 傀儡 → 皮肤 */ + private static final Map skinMap = new WeakHashMap<>(); + + /** + * 更新傀儡的背包数据(由网络包处理器调用)。 + */ + public static void update(ThaumcraftGolemEntity golem, int connectionStatus, int skinOrdinal) { + if (connectionStatus == GolemBackpackSyncPacket.STATUS_NO_BACKPACK) { + connectionStatusMap.remove(golem); + skinMap.remove(golem); + } else { + connectionStatusMap.put(golem, connectionStatus); + skinMap.put(golem, BackpackSkins.fromOrdinal(skinOrdinal)); + } + } + + /** + * 获取傀儡的连接状态。 + * + * @return 0=无背包, 1=在范围内, 2=超出范围 + */ + public static int getConnectionStatus(ThaumcraftGolemEntity golem) { + return connectionStatusMap.getOrDefault(golem, GolemBackpackSyncPacket.STATUS_NO_BACKPACK); + } + + /** + * 傀儡是否装备了背包且在 AE 网络范围内。 + */ + public static boolean isInRange(ThaumcraftGolemEntity golem) { + return getConnectionStatus(golem) == GolemBackpackSyncPacket.STATUS_IN_RANGE; + } + + /** + * 傀儡是否装备了背包(无论是否在范围内)。 + */ + public static boolean hasBackpack(ThaumcraftGolemEntity golem) { + return getConnectionStatus(golem) != GolemBackpackSyncPacket.STATUS_NO_BACKPACK; + } + + /** + * 获取傀儡的背包皮肤。 + */ + public static BackpackSkins getSkin(ThaumcraftGolemEntity golem) { + return skinMap.getOrDefault(golem, BackpackSkins.Thaumium); + } +} diff --git a/src/main/java/thaumicenergistics/common/network/GolemBackpackSyncPacket.java b/src/main/java/thaumicenergistics/common/network/GolemBackpackSyncPacket.java new file mode 100644 index 0000000..8b3b256 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/network/GolemBackpackSyncPacket.java @@ -0,0 +1,69 @@ +package thaumicenergistics.common.network; + +import net.minecraft.client.Minecraft; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.world.entity.Entity; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.common.entities.BackpackSkins; +import thaumcraft.common.entities.golem.ThaumcraftGolemEntity; + +/** + * 服务端→客户端 网络包:同步傀儡背包的连接状态和皮肤。 + * + * 替代 1.7.10 的 DataWatcher 同步机制(SYNCFLAG_HAS_WIFI_IN_RANGE / OUT_OF_RANGE / NO_WIFI)。 + * + * 服务端每 18 tick 检测一次背包连接状态,变化时发送此包到所有追踪该傀儡的客户端。 + * 客户端收到后更新 {@link GolemBackpackClientData},供渲染层读取。 + */ +public record GolemBackpackSyncPacket( + /** 傀儡实体 ID */ + int entityId, + /** 连接状态:0=无背包, 1=在范围内, 2=超出范围 */ + int connectionStatus, + /** 皮肤序号(对应 {@link BackpackSkins} ordinal) */ + int skinOrdinal +) implements CustomPacketPayload { + + public static final Type TYPE = + new Type<>(ThaumicEnergistics.id("golem_backpack_sync")); + + public static final StreamCodec STREAM_CODEC = StreamCodec.of( + (buf, pkt) -> { + buf.writeVarInt(pkt.entityId); + buf.writeVarInt(pkt.connectionStatus); + buf.writeVarInt(pkt.skinOrdinal); + }, + buf -> new GolemBackpackSyncPacket( + buf.readVarInt(), + buf.readVarInt(), + buf.readVarInt() + ) + ); + + @Override + public Type type() { + return TYPE; + } + + /** 连接状态常量 */ + public static final int STATUS_NO_BACKPACK = 0; + public static final int STATUS_IN_RANGE = 1; + public static final int STATUS_OUT_OF_RANGE = 2; + + /** + * 客户端处理:更新该傀儡的客户端背包数据缓存。 + */ + public void handleOnClient(IPayloadContext ctx) { + // 在主线程上执行 + ctx.enqueueWork(() -> { + Entity entity = Minecraft.getInstance().level.getEntity(this.entityId); + if (entity instanceof ThaumcraftGolemEntity golem) { + GolemBackpackClientData.update(golem, this.connectionStatus, this.skinOrdinal); + } + }); + } +} diff --git a/src/main/java/thaumicenergistics/common/network/KnowledgeInscriberGhostSlotPacket.java b/src/main/java/thaumicenergistics/common/network/KnowledgeInscriberGhostSlotPacket.java new file mode 100644 index 0000000..956baf0 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/network/KnowledgeInscriberGhostSlotPacket.java @@ -0,0 +1,52 @@ +package thaumicenergistics.common.network; + +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.world.item.ItemStack; +import net.neoforged.neoforge.network.handling.IPayloadContext; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.common.container.ContainerKnowledgeInscriber; + +/** + * 客户端→服务端 网络包:同步知识记录仪合成网格中某个幽灵槽的内容。 + * 幽灵槽不走标准 Slot 同步流程(因为不消耗物品,只是摆个样子), + * 服务端需要知道客户端摆了什么才能计算奥术配方、更新保存按钮状态。 + */ +public record KnowledgeInscriberGhostSlotPacket( + /** Container 的 containerId,用来在服务端找到对应菜单实例 */ + int containerId, + /** 幽灵槽在合成网格中的索引(0-8) */ + int slotIndex, + /** 该槽要设置的物品 */ + ItemStack stack +) implements CustomPacketPayload { + + public static final Type TYPE = + new Type<>(ThaumicEnergistics.id("ki_ghost_slot")); + + public static final StreamCodec STREAM_CODEC = + StreamCodec.composite( + net.minecraft.network.codec.ByteBufCodecs.VAR_INT, KnowledgeInscriberGhostSlotPacket::containerId, + net.minecraft.network.codec.ByteBufCodecs.VAR_INT, KnowledgeInscriberGhostSlotPacket::slotIndex, + ItemStack.OPTIONAL_STREAM_CODEC, KnowledgeInscriberGhostSlotPacket::stack, + KnowledgeInscriberGhostSlotPacket::new + ); + + @Override + public Type type() { + return TYPE; + } + + /** + * 服务端处理:找到对应菜单,更新幽灵槽,重新计算配方。 + */ + public void handleOnServer(IPayloadContext ctx) { + ctx.enqueueWork(() -> { + if (ctx.player().containerMenu.containerId == this.containerId + && ctx.player().containerMenu instanceof ContainerKnowledgeInscriber menu) { + menu.setGhostSlotOnServer(this.slotIndex, this.stack); + } + }); + } +} diff --git a/src/main/java/thaumicenergistics/common/network/ThENetworking.java b/src/main/java/thaumicenergistics/common/network/ThENetworking.java new file mode 100644 index 0000000..4d9fc36 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/network/ThENetworking.java @@ -0,0 +1,46 @@ +package thaumicenergistics.common.network; + +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent; +import net.neoforged.neoforge.network.registration.PayloadRegistrar; + +public final class ThENetworking { + + private ThENetworking() {} + + public static void init(IEventBus modBus) { + modBus.addListener(ThENetworking::registerPayloads); + } + + private static void registerPayloads(RegisterPayloadHandlersEvent event) { + PayloadRegistrar registrar = event.registrar("thaumicenergistics").versioned("1"); + + // GolemBackpackSyncPacket — S2C(服务端→客户端,同步背包连接状态和皮肤) + registrar.playToClient( + GolemBackpackSyncPacket.TYPE, + GolemBackpackSyncPacket.STREAM_CODEC, + (pkt, ctx) -> ctx.enqueueWork(() -> pkt.handleOnClient(ctx)) + ); + + // KnowledgeInscriberGhostSlotPacket — C2S(客户端→服务端,同步知识记录仪幽灵槽) + registrar.playToServer( + KnowledgeInscriberGhostSlotPacket.TYPE, + KnowledgeInscriberGhostSlotPacket.STREAM_CODEC, + (pkt, ctx) -> pkt.handleOnServer(ctx) + ); + + // CellWorkbenchC2SPacket — C2S(客户端→服务端,源质元件工作台分区操作) + registrar.playToServer( + CellWorkbenchC2SPacket.TYPE, + CellWorkbenchC2SPacket.STREAM_CODEC, + (pkt, ctx) -> pkt.handleOnServer(ctx) + ); + + // CellWorkbenchSyncPacket — S2C(服务端→客户端,同步工作台分区列表) + registrar.playToClient( + CellWorkbenchSyncPacket.TYPE, + CellWorkbenchSyncPacket.STREAM_CODEC, + (pkt, ctx) -> pkt.handleOnClient(ctx) + ); + } +} diff --git a/src/main/java/thaumicenergistics/common/parts/ArcaneCraftingTerminalPart.java b/src/main/java/thaumicenergistics/common/parts/ArcaneCraftingTerminalPart.java new file mode 100644 index 0000000..adecd72 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/parts/ArcaneCraftingTerminalPart.java @@ -0,0 +1,117 @@ +package thaumicenergistics.common.parts; + +import java.util.List; + +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.phys.Vec3; +import appeng.api.inventories.InternalInventory; +import appeng.api.parts.IPartItem; +import appeng.api.parts.IPartModel; +import appeng.core.AppEng; +import appeng.items.parts.PartModels; +import appeng.menu.locator.MenuLocators; +import appeng.menu.MenuOpener; +import appeng.parts.PartModel; +import appeng.parts.reporting.AbstractTerminalPart; +import appeng.util.inv.AppEngInternalInventory; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.init.ModMenuTypes; + +public class ArcaneCraftingTerminalPart extends AbstractTerminalPart { + + public static final ResourceLocation INV_CRAFTING = AppEng.makeId("arcane_crafting_terminal_crafting"); + public static final ResourceLocation INV_WAND = ThaumicEnergistics.id("arcane_crafting_terminal_wand"); + + @PartModels + public static final ResourceLocation RL_BASE = ThaumicEnergistics.id("parts/arcane_crafting_terminal_base"); + @PartModels + public static final ResourceLocation RL_OFF = ThaumicEnergistics.id("parts/arcane_crafting_terminal_off"); + @PartModels + public static final ResourceLocation RL_HAS_CHANNEL = ThaumicEnergistics.id("parts/arcane_crafting_terminal_has_channel"); + @PartModels + public static final ResourceLocation RL_ON = ThaumicEnergistics.id("parts/arcane_crafting_terminal_on"); + + public static final IPartModel MODELS_OFF = new PartModel(RL_BASE, RL_OFF, MODEL_STATUS_OFF); + public static final IPartModel MODELS_ON = new PartModel(RL_BASE, RL_ON, MODEL_STATUS_ON); + public static final IPartModel MODELS_HAS_CHANNEL = new PartModel(RL_BASE, RL_ON, MODEL_STATUS_HAS_CHANNEL); + + public static final int WAND_SLOT_INDEX = 0; + + private final AppEngInternalInventory craftingGrid = new AppEngInternalInventory(this, 9); + private final AppEngInternalInventory wandInv = new AppEngInternalInventory(this, 1); + + public ArcaneCraftingTerminalPart(IPartItem partItem) { + super(partItem); + this.getMainNode().setIdlePowerUsage(0.5); + } + + @Override + public IPartModel getStaticModels() { + return this.selectModel(MODELS_OFF, MODELS_ON, MODELS_HAS_CHANNEL); + } + + @Override + public boolean onUseWithoutItem(Player player, Vec3 pos) { + if (!super.onUseWithoutItem(player, pos) && !player.level().isClientSide) { + MenuOpener.open(getMenuType(player), player, MenuLocators.forPart(this)); + } + return true; + } + + @Override + public MenuType getMenuType(Player player) { + return ModMenuTypes.ARCANE_CRAFTING_TERMINAL.get(); + } + + @Override + public void addAdditionalDrops(List drops, boolean wrenched) { + super.addAdditionalDrops(drops, wrenched); + for (var is : this.craftingGrid) { + if (!is.isEmpty()) { + drops.add(is); + } + } + for (var is : this.wandInv) { + if (!is.isEmpty()) { + drops.add(is); + } + } + } + + @Override + public void clearContent() { + super.clearContent(); + craftingGrid.clear(); + wandInv.clear(); + } + + @Override + public void readFromNBT(CompoundTag data, HolderLookup.Provider registries) { + super.readFromNBT(data, registries); + this.craftingGrid.readFromNBT(data, "craftingGrid", registries); + this.wandInv.readFromNBT(data, "wandInv", registries); + } + + @Override + public void writeToNBT(CompoundTag data, HolderLookup.Provider registries) { + super.writeToNBT(data, registries); + this.craftingGrid.writeToNBT(data, "craftingGrid", registries); + this.wandInv.writeToNBT(data, "wandInv", registries); + } + + @Override + public InternalInventory getSubInventory(ResourceLocation id) { + if (id.equals(INV_CRAFTING)) { + return craftingGrid; + } else if (id.equals(INV_WAND)) { + return wandInv; + } else { + return super.getSubInventory(id); + } + } +} diff --git a/src/main/java/thaumicenergistics/common/parts/EssentiaExportBusPart.java b/src/main/java/thaumicenergistics/common/parts/EssentiaExportBusPart.java new file mode 100644 index 0000000..6a855e0 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/parts/EssentiaExportBusPart.java @@ -0,0 +1,179 @@ +package thaumicenergistics.common.parts; + +import appeng.api.config.Actionable; +import appeng.api.config.PowerMultiplier; +import appeng.api.config.SchedulingMode; +import appeng.api.config.Settings; +import appeng.api.networking.IGrid; +import appeng.api.networking.security.IActionSource; +import appeng.api.parts.IPartCollisionHelper; +import appeng.api.parts.IPartItem; +import appeng.api.parts.IPartModel; +import appeng.api.stacks.GenericStack; +import appeng.api.util.IConfigManagerBuilder; +import appeng.api.util.KeyTypeSelection; +import appeng.api.util.KeyTypeSelectionHost; +import appeng.core.settings.TickRates; +import appeng.items.parts.PartModels; +import appeng.parts.PartModel; +import appeng.parts.automation.IOBusPart; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.IEssentiaTransport; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.api.storage.AspectStack; +import thaumicenergistics.common.integration.appeng.AEssentiaKey; +import thaumicenergistics.common.integration.appeng.AEssentiaKeyType; +import thaumicenergistics.common.integration.tc.EssentiaConversionHelper; +import thaumicenergistics.common.integration.tc.TCReflection; +import thaumicenergistics.init.ModMenuTypes; + +import java.util.Set; + +public class EssentiaExportBusPart extends IOBusPart + implements KeyTypeSelectionHost { + + @PartModels + public static final ResourceLocation RL_BASE = + ThaumicEnergistics.id("parts/essentia_export_bus_base"); + @PartModels + public static final ResourceLocation RL_OFF = + ThaumicEnergistics.id("parts/essentia_export_bus_off"); + @PartModels + public static final ResourceLocation RL_HAS_CHANNEL = + ThaumicEnergistics.id("parts/essentia_export_bus_has_channel"); + @PartModels + public static final ResourceLocation RL_ON = + ThaumicEnergistics.id("parts/essentia_export_bus_on"); + + public static final PartModel MODEL_OFF = new PartModel(RL_BASE, RL_OFF); + public static final PartModel MODEL_HAS_CHANNEL = new PartModel(RL_BASE, RL_HAS_CHANNEL); + public static final PartModel MODEL_ON = new PartModel(RL_BASE, RL_ON); + + private static final double IDLE_POWER = 0.5; + private static final double TRANSFER_POWER = EssentiaConversionHelper.AE_PER_ESSENTIA; + private static final int TRANSFER_RATE = 8; + + private boolean isWorkingFlag = false; + + private final KeyTypeSelection keyTypeSelection = new KeyTypeSelection( + selection -> { }, + keyType -> keyType == AEssentiaKeyType.INSTANCE); + + private long storedEnergy = 0; + + public EssentiaExportBusPart(IPartItem partItem) { + super(TickRates.ExportBus, Set.of(AEssentiaKeyType.INSTANCE), partItem); + this.getMainNode().setIdlePowerUsage(IDLE_POWER); + } + + @Override + protected void registerSettings(IConfigManagerBuilder builder) { + super.registerSettings(builder); + builder.registerSetting(Settings.SCHEDULING_MODE, SchedulingMode.DEFAULT); + } + + @Override + public void getBoxes(IPartCollisionHelper bch) { + bch.addBox(6, 6, 11, 10, 10, 13); + bch.addBox(5, 5, 13, 11, 11, 14); + bch.addBox(4, 4, 14, 12, 12, 16); + } + + @Override + public IPartModel getStaticModels() { + if (isWorkingFlag) return MODEL_ON; + if (getMainNode() != null && getMainNode().isOnline()) return MODEL_HAS_CHANNEL; + return MODEL_OFF; + } + + @Override + protected boolean doBusWork(IGrid grid) { + this.isWorkingFlag = false; + + Direction side = this.getSide(); + if (side == null) return false; + BlockPos adjacentPos = this.getBlockEntity().getBlockPos().relative(side); + Level levelRaw = this.getLevel(); + if (!(levelRaw instanceof ServerLevel level)) return false; + if (!level.isLoaded(adjacentPos)) return false; + BlockEntity adjacentBE = level.getBlockEntity(adjacentPos); + if (adjacentBE == null) return false; + + // 从 ConfigInventory 获取要导出的源质类型 + var configInv = getConfig(); + AEssentiaKey key = null; + for (int i = 0; i < configInv.size(); i++) { + var stack = configInv.getStack(i); + if (stack != null && stack.what() instanceof AEssentiaKey ek) { + key = ek; + break; + } + } + if (key == null) return false; + + long extracted = grid.getStorageService().getInventory().extract( + key, TRANSFER_RATE, Actionable.MODULATE, IActionSource.ofMachine(this)); + if (extracted <= 0) return false; + + // 尝试注入到相邻方块:先 IAspectContainer,再回退到 IEssentiaTransport + int injected = TCReflection.insertEssentia(adjacentBE, new AspectStack(key.getId(), extracted)); + if (injected <= 0 && adjacentBE instanceof IEssentiaTransport transport) { + Aspect aspect = TCReflection.findAspectById(key.getId()); + if (aspect != null) { + int want = (int) Math.min(extracted, Integer.MAX_VALUE); + injected = transport.addEssentia(aspect, want, side.getOpposite()); + } + } + if (injected < extracted) { + // 退回未注入的部分 + grid.getStorageService().getInventory().insert( + key, extracted - injected, Actionable.MODULATE, IActionSource.ofMachine(this)); + } + + if (injected > 0) { + this.storedEnergy = injected * (int) TRANSFER_POWER; + this.isWorkingFlag = true; + } + return injected > 0; + } + + @Override + public void readFromNBT(CompoundTag extra, HolderLookup.Provider registries) { + super.readFromNBT(extra, registries); + this.keyTypeSelection.readFromNBT(extra, registries); + this.storedEnergy = extra.getLong("storedEnergy"); + } + + @Override + public void writeToNBT(CompoundTag extra, HolderLookup.Provider registries) { + super.writeToNBT(extra, registries); + this.keyTypeSelection.writeToNBT(extra); + extra.putLong("storedEnergy", this.storedEnergy); + } + + @Override + protected MenuType getMenuType() { + return ModMenuTypes.ESSENTIA_EXPORT_BUS.get(); + } + + @Override + public int getUpgradeSlots() { return 4; } + + @Override + public KeyTypeSelection getKeyTypeSelection() { + return this.keyTypeSelection; + } + + public long getStoredEnergy() { + return storedEnergy; + } +} diff --git a/src/main/java/thaumicenergistics/common/parts/EssentiaImportBusPart.java b/src/main/java/thaumicenergistics/common/parts/EssentiaImportBusPart.java new file mode 100644 index 0000000..6922281 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/parts/EssentiaImportBusPart.java @@ -0,0 +1,158 @@ +package thaumicenergistics.common.parts; + +import appeng.api.config.Actionable; +import appeng.api.config.PowerMultiplier; +import appeng.api.config.SchedulingMode; +import appeng.api.config.Settings; +import appeng.api.networking.IGrid; +import appeng.api.networking.security.IActionSource; +import appeng.api.parts.IPartCollisionHelper; +import appeng.api.parts.IPartItem; +import appeng.api.parts.IPartModel; +import appeng.api.stacks.GenericStack; +import appeng.api.util.IConfigManagerBuilder; +import appeng.api.util.KeyTypeSelection; +import appeng.api.util.KeyTypeSelectionHost; +import appeng.core.settings.TickRates; +import appeng.items.parts.PartModels; +import appeng.parts.PartModel; +import appeng.parts.automation.IOBusPart; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.api.storage.AspectStack; +import thaumicenergistics.common.integration.appeng.AEssentiaKey; +import thaumicenergistics.common.integration.appeng.AEssentiaKeyType; +import thaumicenergistics.common.integration.tc.EssentiaConversionHelper; +import thaumicenergistics.common.integration.tc.TCReflection; +import thaumicenergistics.init.ModMenuTypes; + +import java.util.Set; + +public class EssentiaImportBusPart extends IOBusPart + implements KeyTypeSelectionHost { + + @PartModels + public static final ResourceLocation RL_BASE = + ThaumicEnergistics.id("parts/essentia_import_bus_base"); + @PartModels + public static final ResourceLocation RL_OFF = + ThaumicEnergistics.id("parts/essentia_import_bus_off"); + @PartModels + public static final ResourceLocation RL_HAS_CHANNEL = + ThaumicEnergistics.id("parts/essentia_import_bus_has_channel"); + @PartModels + public static final ResourceLocation RL_ON = + ThaumicEnergistics.id("parts/essentia_import_bus_on"); + + public static final PartModel MODEL_OFF = new PartModel(RL_BASE, RL_OFF); + public static final PartModel MODEL_HAS_CHANNEL = new PartModel(RL_BASE, RL_HAS_CHANNEL); + public static final PartModel MODEL_ON = new PartModel(RL_BASE, RL_ON); + + private static final int TRANSFER_RATE = 8; + private static final double IDLE_POWER = 0.5; + private static final double TRANSFER_POWER = EssentiaConversionHelper.AE_PER_ESSENTIA; + + private boolean isWorkingFlag = false; + + private final KeyTypeSelection keyTypeSelection = new KeyTypeSelection( + selection -> { }, + keyType -> keyType == AEssentiaKeyType.INSTANCE); + + public EssentiaImportBusPart(IPartItem partItem) { + super(TickRates.ImportBus, Set.of(AEssentiaKeyType.INSTANCE), partItem); + this.getMainNode().setIdlePowerUsage(IDLE_POWER); + } + + @Override + protected void registerSettings(IConfigManagerBuilder builder) { + super.registerSettings(builder); + builder.registerSetting(Settings.SCHEDULING_MODE, SchedulingMode.DEFAULT); + } + + @Override + public void getBoxes(IPartCollisionHelper bch) { + bch.addBox(6, 6, 11, 10, 10, 13); + bch.addBox(5, 5, 13, 11, 11, 14); + bch.addBox(4, 4, 14, 12, 12, 16); + } + + @Override + public IPartModel getStaticModels() { + if (isWorkingFlag) return MODEL_ON; + if (getMainNode() != null && getMainNode().isOnline()) return MODEL_HAS_CHANNEL; + return MODEL_OFF; + } + + @Override + protected boolean doBusWork(IGrid grid) { + this.isWorkingFlag = false; + + Direction side = this.getSide(); + if (side == null) return false; + BlockPos adjacentPos = this.getBlockEntity().getBlockPos().relative(side); + Level levelRaw = this.getLevel(); + if (!(levelRaw instanceof ServerLevel level)) return false; + if (!level.isLoaded(adjacentPos)) return false; + BlockEntity adjacentBE = level.getBlockEntity(adjacentPos); + if (adjacentBE == null) return false; + + AspectStack extracted = TCReflection.extractEssentia(adjacentBE, TRANSFER_RATE); + if (extracted == null || extracted.isEmpty()) return false; + + long injected = this.injectToNetwork(grid, extracted); + if (injected <= 0) { + TCReflection.returnEssentia(adjacentBE, extracted); + return false; + } + + double powerCost = injected * TRANSFER_POWER; + grid.getEnergyService().extractAEPower(powerCost, Actionable.MODULATE, PowerMultiplier.CONFIG); + + if (injected < extracted.amount()) { + long leftover = extracted.amount() - injected; + TCReflection.returnEssentia(adjacentBE, new AspectStack(extracted.aspectId(), leftover)); + } + this.isWorkingFlag = true; + return true; + } + + private long injectToNetwork(IGrid grid, AspectStack stack) { + AEssentiaKey key = AEssentiaKey.of(stack.aspectId()); + return grid.getStorageService().getInventory().insert( + key, stack.amount(), Actionable.MODULATE, + IActionSource.ofMachine(this)); + } + + @Override + public void readFromNBT(CompoundTag extra, HolderLookup.Provider registries) { + super.readFromNBT(extra, registries); + this.keyTypeSelection.readFromNBT(extra, registries); + } + + @Override + public void writeToNBT(CompoundTag extra, HolderLookup.Provider registries) { + super.writeToNBT(extra, registries); + this.keyTypeSelection.writeToNBT(extra); + } + + @Override + protected MenuType getMenuType() { + return ModMenuTypes.ESSENTIA_IMPORT_BUS.get(); + } + + @Override + public int getUpgradeSlots() { return 4; } + + @Override + public KeyTypeSelection getKeyTypeSelection() { + return this.keyTypeSelection; + } +} diff --git a/src/main/java/thaumicenergistics/common/parts/EssentiaLevelEmitterPart.java b/src/main/java/thaumicenergistics/common/parts/EssentiaLevelEmitterPart.java new file mode 100644 index 0000000..7bd31f6 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/parts/EssentiaLevelEmitterPart.java @@ -0,0 +1,298 @@ +package thaumicenergistics.common.parts; + +import java.util.List; +import java.util.Set; + +import org.jetbrains.annotations.Nullable; + +import net.minecraft.core.HolderLookup; +import net.minecraft.core.particles.DustParticleOptions; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.phys.Vec3; + +import appeng.api.config.Settings; +import appeng.api.crafting.IPatternDetails; +import appeng.api.networking.IGrid; +import appeng.api.networking.IStackWatcher; +import appeng.api.networking.crafting.ICraftingProvider; +import appeng.api.networking.crafting.ICraftingWatcherNode; +import appeng.api.networking.storage.IStorageWatcherNode; +import appeng.api.parts.IPartItem; +import appeng.api.parts.IPartModel; +import appeng.api.stacks.AEKey; +import appeng.api.stacks.KeyCounter; +import appeng.helpers.IConfigInvHost; +import appeng.hooks.ticking.TickHandler; +import appeng.items.parts.PartModels; +import appeng.menu.MenuOpener; +import appeng.menu.locator.MenuLocators; +import appeng.parts.PartModel; +import appeng.parts.automation.AbstractLevelEmitterPart; +import appeng.util.ConfigInventory; +import thaumcraft.api.aspects.Aspect; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.common.integration.appeng.AEssentiaKey; +import thaumicenergistics.common.integration.appeng.AEssentiaKeyType; +import thaumicenergistics.common.integration.tc.TCReflection; +import thaumicenergistics.init.ModMenuTypes; + +/** + * 源质发信器:与 AE2 原版 StorageLevelEmitterPart 逻辑一致, + * 但 ConfigInventory 仅支持 AEssentiaKeyType。 + * 使用 IStorageWatcherNode 实时监听源质变化,而非轮询。 + */ +public class EssentiaLevelEmitterPart extends AbstractLevelEmitterPart + implements IConfigInvHost, ICraftingProvider { + + @PartModels + public static final ResourceLocation RL_BASE_OFF = ThaumicEnergistics.id("parts/essentia_level_emitter_base_off"); + @PartModels + public static final ResourceLocation RL_BASE_ON = ThaumicEnergistics.id("parts/essentia_level_emitter_base_on"); + @PartModels + public static final ResourceLocation RL_STATUS_OFF = ThaumicEnergistics.id("parts/essentia_level_emitter_status_off"); + @PartModels + public static final ResourceLocation RL_STATUS_ON = ThaumicEnergistics.id("parts/essentia_level_emitter_status_on"); + @PartModels + public static final ResourceLocation RL_STATUS_HAS_CHANNEL = ThaumicEnergistics.id("parts/essentia_level_emitter_status_has_channel"); + + public static final PartModel MODEL_OFF_OFF = new PartModel(RL_BASE_OFF, RL_STATUS_OFF); + public static final PartModel MODEL_OFF_ON = new PartModel(RL_BASE_OFF, RL_STATUS_ON); + public static final PartModel MODEL_OFF_HAS_CHANNEL = new PartModel(RL_BASE_OFF, RL_STATUS_HAS_CHANNEL); + public static final PartModel MODEL_ON_OFF = new PartModel(RL_BASE_ON, RL_STATUS_OFF); + public static final PartModel MODEL_ON_ON = new PartModel(RL_BASE_ON, RL_STATUS_ON); + public static final PartModel MODEL_ON_HAS_CHANNEL = new PartModel(RL_BASE_ON, RL_STATUS_HAS_CHANNEL); + + private final ConfigInventory config = ConfigInventory.configTypes(1) + .supportedType(AEssentiaKeyType.INSTANCE) + .changeListener(this::configureWatchers) + .build(); + + private IStackWatcher storageWatcher; + private IStackWatcher craftingWatcher; + private long lastUpdateTick = -1; + + private final IStorageWatcherNode stackWatcherNode = new IStorageWatcherNode() { + @Override + public void updateWatcher(IStackWatcher newWatcher) { + storageWatcher = newWatcher; + configureWatchers(); + } + + @Override + public void onStackChange(AEKey what, long amount) { + if (what.equals(getConfiguredKey())) { + lastReportedValue = amount; + updateState(); + } else { + // 无筛选或模糊匹配时,限制每 tick 只更新一次 + long currentTick = TickHandler.instance().getCurrentTick(); + if (currentTick != lastUpdateTick) { + lastUpdateTick = currentTick; + updateReportingValue(getGridNode().getGrid()); + } + } + } + }; + + private final ICraftingWatcherNode craftingWatcherNode = new ICraftingWatcherNode() { + @Override + public void updateWatcher(IStackWatcher newWatcher) { + craftingWatcher = newWatcher; + configureWatchers(); + } + + @Override + public void onRequestChange(AEKey what) { + updateState(); + } + + @Override + public void onCraftableChange(AEKey what) { + } + }; + + public EssentiaLevelEmitterPart(IPartItem partItem) { + super(partItem); + + getMainNode().addService(IStorageWatcherNode.class, stackWatcherNode); + getMainNode().addService(ICraftingWatcherNode.class, craftingWatcherNode); + getMainNode().addService(ICraftingProvider.class, this); + } + + @Nullable + private AEKey getConfiguredKey() { + return config.getKey(0); + } + + @Override + protected final int getUpgradeSlots() { + return 1; + } + + @Override + public final void upgradesChanged() { + this.configureWatchers(); + } + + @Override + protected boolean hasDirectOutput() { + return false; // 源质发信器不支持合成卡 + } + + @Override + protected boolean getDirectOutput() { + return false; + } + + @Override + public List getAvailablePatterns() { + return List.of(); + } + + @Override + public boolean pushPattern(IPatternDetails patternDetails, KeyCounter[] inputHolder) { + return false; + } + + @Override + public boolean isBusy() { + return true; + } + + @Override + public Set getEmitableItems() { + return Set.of(); + } + + @Override + protected void onReportingValueChanged() { + getMainNode().ifPresent(this::updateReportingValue); + } + + @Override + protected void configureWatchers() { + var myStack = getConfiguredKey(); + + if (this.storageWatcher != null) { + this.storageWatcher.reset(); + } + + if (this.craftingWatcher != null) { + this.craftingWatcher.reset(); + } + + ICraftingProvider.requestUpdate(getMainNode()); + + if (this.storageWatcher != null) { + if (myStack == null) { + this.storageWatcher.setWatchAll(true); + } else { + this.storageWatcher.add(myStack); + } + } + + getMainNode().ifPresent(this::updateReportingValue); + updateState(); + } + + private void updateReportingValue(IGrid grid) { + if (grid == null) return; + var myStack = getConfiguredKey(); + var allStacks = grid.getStorageService().getInventory().getAvailableStacks(); + + if (myStack == null) { + this.lastReportedValue = 0; + // 遍历所有存储中的源质(直接查询可用堆叠,非缓存) + for (var st : allStacks) { + if (st.getKey() instanceof AEssentiaKey) { + this.lastReportedValue += st.getLongValue(); + if (this.lastReportedValue > this.getReportingValue()) { + break; + } + } + } + } else { + // KeyCounter.get() 用 Reference2LongMap(引用比较),自定义 AEKey 需要 equals() 遍历 + this.lastReportedValue = 0; + for (var st : allStacks) { + if (st.getKey() instanceof AEssentiaKey ek && ek.equals(myStack)) { + this.lastReportedValue = st.getLongValue(); + break; + } + } + } + + this.updateState(); + } + + @Override + public void readFromNBT(CompoundTag data, HolderLookup.Provider registries) { + super.readFromNBT(data, registries); + config.readFromChildTag(data, "config", registries); + } + + @Override + public void writeToNBT(CompoundTag data, HolderLookup.Provider registries) { + super.writeToNBT(data, registries); + config.writeToChildTag(data, "config", registries); + } + + @Override + public boolean onUseWithoutItem(Player player, Vec3 pos) { + if (!isClientSide()) { + MenuOpener.open(ModMenuTypes.ESSENTIA_LEVEL_EMITTER.get(), player, MenuLocators.forPart(this)); + } + return true; + } + + @Override + public ConfigInventory getConfig() { + return config; + } + + @Override + public IPartModel getStaticModels() { + if (this.isActive() && this.isPowered()) { + return this.isLevelEmitterOn() ? MODEL_ON_HAS_CHANNEL : MODEL_OFF_HAS_CHANNEL; + } else if (this.isPowered()) { + return this.isLevelEmitterOn() ? MODEL_ON_ON : MODEL_OFF_ON; + } else { + return this.isLevelEmitterOn() ? MODEL_ON_OFF : MODEL_OFF_OFF; + } + } + + // ========== 向后兼容方法(供 Container/GUI 使用) ========== + + /** + * 获取网络中当前存储量(= lastReportedValue)。 + */ + public long getCurrentLevel() { + return lastReportedValue; + } + + @Nullable + public AEssentiaKey getConfiguredEssentiaKey() { + AEKey key = config.getKey(0); + return key instanceof AEssentiaKey ek ? ek : null; + } + + @Nullable + public Aspect getTrackedAspect() { + AEssentiaKey key = getConfiguredEssentiaKey(); + if (key == null) return null; + return Aspect.getAspect(key.getId().getPath()); + } + + public void setTrackedAspect(Aspect aspect) { + if (aspect == null) { + config.setStack(0, null); + } else { + ResourceLocation id = TCReflection.getAspectId(aspect); + if (id != null) { + config.setStack(0, new appeng.api.stacks.GenericStack(AEssentiaKey.of(id), 1)); + } + } + } +} diff --git a/src/main/java/thaumicenergistics/common/parts/EssentiaStorageBusPart.java b/src/main/java/thaumicenergistics/common/parts/EssentiaStorageBusPart.java new file mode 100644 index 0000000..6790cb0 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/parts/EssentiaStorageBusPart.java @@ -0,0 +1,132 @@ +package thaumicenergistics.common.parts; + +import appeng.api.config.Actionable; +import appeng.api.networking.IGrid; +import appeng.api.networking.security.IActionSource; +import appeng.api.parts.IPartCollisionHelper; +import appeng.api.parts.IPartItem; +import appeng.api.parts.IPartModel; +import appeng.api.util.KeyTypeSelection; +import appeng.api.util.KeyTypeSelectionHost; +import appeng.core.settings.TickRates; +import appeng.items.parts.PartModels; +import appeng.parts.PartModel; +import appeng.parts.automation.IOBusPart; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.api.storage.AspectStack; +import thaumicenergistics.common.integration.appeng.AEssentiaKey; +import thaumicenergistics.common.integration.appeng.AEssentiaKeyType; +import thaumicenergistics.common.integration.tc.TCReflection; +import thaumicenergistics.init.ModMenuTypes; + +import java.util.Set; + +public class EssentiaStorageBusPart extends IOBusPart + implements KeyTypeSelectionHost { + + @PartModels + public static final ResourceLocation RL_BASE = + ThaumicEnergistics.id("parts/essentia_storage_bus_base"); + @PartModels + public static final ResourceLocation RL_OFF = + ThaumicEnergistics.id("parts/essentia_storage_bus_off"); + @PartModels + public static final ResourceLocation RL_HAS_CHANNEL = + ThaumicEnergistics.id("parts/essentia_storage_bus_has_channel"); + @PartModels + public static final ResourceLocation RL_ON = + ThaumicEnergistics.id("parts/essentia_storage_bus_on"); + + public static final PartModel MODEL_OFF = new PartModel(RL_BASE, RL_OFF); + public static final PartModel MODEL_HAS_CHANNEL = new PartModel(RL_BASE, RL_HAS_CHANNEL); + public static final PartModel MODEL_ON = new PartModel(RL_BASE, RL_ON); + + private static final double IDLE_POWER = 1.0; + private static final int TRANSFER_RATE = 8; + private boolean isWorkingFlag = false; + + private final KeyTypeSelection keyTypeSelection = new KeyTypeSelection( + selection -> { }, + keyType -> keyType == AEssentiaKeyType.INSTANCE); + + public EssentiaStorageBusPart(IPartItem partItem) { + super(TickRates.StorageBus, Set.of(AEssentiaKeyType.INSTANCE), partItem); + this.getMainNode().setIdlePowerUsage(IDLE_POWER); + } + + @Override + public void getBoxes(IPartCollisionHelper bch) { + bch.addBox(5, 5, 12, 11, 11, 14); + bch.addBox(2, 2, 14, 14, 14, 15); + bch.addBox(3, 3, 15, 13, 13, 16); + } + + @Override + public IPartModel getStaticModels() { + if (isWorkingFlag) return MODEL_ON; + if (getMainNode() != null && getMainNode().isOnline()) return MODEL_HAS_CHANNEL; + return MODEL_OFF; + } + + @Override + protected boolean doBusWork(IGrid grid) { + this.isWorkingFlag = false; + + Direction side = this.getSide(); + if (side == null) return false; + BlockPos adjacentPos = this.getBlockEntity().getBlockPos().relative(side); + Level levelRaw = this.getLevel(); + if (!(levelRaw instanceof ServerLevel level)) return false; + if (!level.isLoaded(adjacentPos)) return false; + BlockEntity adjacentBE = level.getBlockEntity(adjacentPos); + if (adjacentBE == null) return false; + + AspectStack extracted = TCReflection.extractEssentia(adjacentBE, TRANSFER_RATE); + if (extracted == null || extracted.isEmpty()) return false; + + this.insertIntoNetwork(grid, extracted); + this.isWorkingFlag = true; + return true; + } + + private void insertIntoNetwork(IGrid grid, AspectStack stack) { + AEssentiaKey key = AEssentiaKey.of(stack.aspectId()); + grid.getStorageService().getInventory().insert( + key, stack.amount(), Actionable.MODULATE, + IActionSource.ofMachine(this)); + } + + @Override + public KeyTypeSelection getKeyTypeSelection() { + return this.keyTypeSelection; + } + + @Override + public void readFromNBT(CompoundTag extra, HolderLookup.Provider registries) { + super.readFromNBT(extra, registries); + this.keyTypeSelection.readFromNBT(extra, registries); + } + + @Override + public void writeToNBT(CompoundTag extra, HolderLookup.Provider registries) { + super.writeToNBT(extra, registries); + this.keyTypeSelection.writeToNBT(extra); + } + + @Override + protected MenuType getMenuType() { + return ModMenuTypes.ESSENTIA_STORAGE_BUS.get(); + } + + @Override + public int getUpgradeSlots() { return 4; } +} diff --git a/src/main/java/thaumicenergistics/common/parts/EssentiaTerminalPart.java b/src/main/java/thaumicenergistics/common/parts/EssentiaTerminalPart.java new file mode 100644 index 0000000..57f1e1c --- /dev/null +++ b/src/main/java/thaumicenergistics/common/parts/EssentiaTerminalPart.java @@ -0,0 +1,97 @@ +package thaumicenergistics.common.parts; + +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.phys.Vec3; +import appeng.api.parts.IPartItem; +import appeng.api.parts.IPartModel; +import appeng.api.util.KeyTypeSelection; +import appeng.items.parts.PartModels; +import appeng.menu.me.common.MEStorageMenu; +import appeng.parts.PartModel; +import appeng.parts.reporting.AbstractTerminalPart; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.common.integration.appeng.AEssentiaKeyType; + +public class EssentiaTerminalPart extends AbstractTerminalPart { + + @PartModels + public static final ResourceLocation RL_BASE = ThaumicEnergistics.id("parts/essentia_terminal_base"); + + @PartModels + public static final ResourceLocation RL_OFF = ThaumicEnergistics.id("parts/essentia_terminal_off"); + + @PartModels + public static final ResourceLocation RL_HAS_CHANNEL = ThaumicEnergistics.id("parts/essentia_terminal_has_channel"); + + @PartModels + public static final ResourceLocation RL_ON = ThaumicEnergistics.id("parts/essentia_terminal_on"); + + public static final IPartModel MODELS_OFF = new PartModel(RL_BASE, RL_OFF, MODEL_STATUS_OFF); + public static final IPartModel MODELS_ON = new PartModel(RL_BASE, RL_ON, MODEL_STATUS_ON); + public static final IPartModel MODELS_HAS_CHANNEL = new PartModel(RL_BASE, RL_ON, MODEL_STATUS_HAS_CHANNEL); + + /** + * 自定义 KeyTypeSelection:只允许源质类型,禁止物品和流体。 + * 父类 AbstractTerminalPart 的 private 字段 keyTypeSelection 是 keyType -> true(全类型), + * 这里通过覆盖 getKeyTypeSelection() 返回本实例,使 MEStorageMenu 只看到源质。 + */ + private final KeyTypeSelection essentiaOnlyKeyTypeSelection = new KeyTypeSelection( + this::saveChanges, + keyType -> keyType == AEssentiaKeyType.INSTANCE); + + public EssentiaTerminalPart(IPartItem partItem) { + super(partItem); + } + + @Override + public IPartModel getStaticModels() { + return this.selectModel(MODELS_OFF, MODELS_ON, MODELS_HAS_CHANNEL); + } + + @Override + public MenuType getMenuType(Player player) { + return MEStorageMenu.TYPE; + } + + @Override + public boolean onUseWithoutItem(Player player, Vec3 pos) { + if (!super.onUseWithoutItem(player, pos) && !player.level().isClientSide) { + appeng.menu.MenuOpener.open(getMenuType(player), player, + appeng.menu.locator.MenuLocators.forPart(this)); + } + return true; + } + + /** + * 返回自定义的 KeyTypeSelection,只包含 AEssentiaKeyType。 + * MEStorageMenu.broadcastChanges() 通过此接口获取可用类型,GUI 据此过滤显示。 + */ + @Override + public KeyTypeSelection getKeyTypeSelection() { + return this.essentiaOnlyKeyTypeSelection; + } + + /** + * 覆盖 NBT 读取:父类先读(更新父类 private 字段),然后本类用自己的实例再读。 + * 父类 private 字段会被忽略,因为 getKeyTypeSelection() 返回本类实例。 + */ + @Override + public void readFromNBT(CompoundTag data, HolderLookup.Provider registries) { + super.readFromNBT(data, registries); + this.essentiaOnlyKeyTypeSelection.readFromNBT(data, registries); + } + + /** + * 覆盖 NBT 写入:父类先写(写入父类 private 字段的全类型),然后本类用自己的实例覆盖。 + * writeToNBT 使用 tag.put("enabledKeyTypes", ...),后写入覆盖先写入,最终只保存源质类型。 + */ + @Override + public void writeToNBT(CompoundTag data, HolderLookup.Provider registries) { + super.writeToNBT(data, registries); + this.essentiaOnlyKeyTypeSelection.writeToNBT(data); + } +} diff --git a/src/main/java/thaumicenergistics/common/parts/VisInterfacePart.java b/src/main/java/thaumicenergistics/common/parts/VisInterfacePart.java new file mode 100644 index 0000000..c7740c8 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/parts/VisInterfacePart.java @@ -0,0 +1,314 @@ +package thaumicenergistics.common.parts; + +import appeng.api.config.Actionable; +import appeng.api.config.PowerMultiplier; +import appeng.api.networking.IGrid; +import appeng.api.networking.IGridNode; +import appeng.api.networking.energy.IEnergyService; +import appeng.api.networking.ticking.IGridTickable; +import appeng.api.networking.ticking.TickRateModulation; +import appeng.api.networking.ticking.TickingRequest; +import appeng.api.parts.IPartCollisionHelper; +import appeng.api.parts.IPartItem; +import appeng.api.parts.IPartModel; +import appeng.parts.p2p.P2PModels; +import appeng.parts.p2p.P2PTunnelPart; +import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.visnet.VisNetHandler; +import thaumcraft.common.blockentities.VisRelayBlockEntity; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.api.grid.IDigiVisSource; +import thaumicenergistics.common.integration.tc.VisProviderProxy; + +import java.util.List; + +/** + * 桥接 AE2 ME 网络与 TC vis 网络。作为 P2P 隧道成对连接两端: + * 面对 TC4 {@link VisRelayBlockEntity} 的一端可从其中抽取 vis(消耗 AE 能量), + * 该 vis 对隧道其余端可用。不面对中继但与中继端相连的端, + * 会向 TC 的 {@link VisNetHandler} 注册虚拟 {@link VisProviderProxy}, + * 使附近 TC 机器(法杖、奥术工作台等)可直接从 AE 网格吸取 vis。 + * 自 1.7.10 (RV3 PartVisInterface) 移植,适配 1.21.1 AE2 P2P + ResourceLocation-aspect API。 + */ +public class VisInterfacePart extends P2PTunnelPart implements IGridTickable, IDigiVisSource { + + public static final ResourceLocation MODEL_VIS_INTERFACE = ThaumicEnergistics.id("parts/p2p/p2p_tunnel_vis"); + + private static final P2PModels MODELS = new P2PModels(MODEL_VIS_INTERFACE); + + public static List getModels() { + return MODELS.getModels(); + } + + /** 每次成功 vis 请求消耗的 AE 能量(AE 单位)。固定成本,与 RV3 一致。 */ + private static final double POWER_PER_REQUESTED_VIS = 4.0; + + /** 抽取颜色在没有新抽取后保持点亮的时间(ms),超时清除。 */ + private static final long TIME_TO_CLEAR = 500L; + + private static final String NBT_KEY_UID = "uid"; + private static final String NBT_KEY_IS_PROVIDER = "isProvider"; + + private long uid = 0; + private boolean isProvider = false; + + /** 当前抽取中的要素颜色(用于动画眼睛);0 = 空闲。 */ + private int visDrainingColor = 0; + private long lastColorUpdate = 0; + + /** 为 provider 端注册到 VisNetHandler 的虚拟 vis 源。 */ + private VisProviderProxy visProviderProxy = null; + private boolean providerActive = false; + + /** consumeVis 跨 P2P 端委托的重入保护。 */ + private boolean inConsume = false; + + public VisInterfacePart(IPartItem partItem) { + super(partItem); + this.uid = System.currentTimeMillis() ^ this.hashCode(); + } + + @Override + public IPartModel getStaticModels() { + return MODELS.getModel(this.isPowered(), this.isActive()); + } + + @Override + public void getBoxes(IPartCollisionHelper bch) { + bch.addBox(6, 6, 15, 10, 10, 16); + bch.addBox(4, 4, 14, 12, 12, 15); + bch.addBox(5, 5, 13, 11, 11, 14); + } + + @Override + public int getLightLevel() { + return isActive() ? 8 : 0; + } + + public long getUID() { + return uid; + } + + public boolean isVisProvider() { + return isProvider; + } + + public void setIsVisProvider(boolean provider) { + this.isProvider = provider; + if (getHost() != null) { + getHost().markForUpdate(); + } + } + + public IGrid getGrid() { + if (this.getMainNode() == null) return null; + return this.getMainNode().getGrid(); + } + + // ===== IDigiVisSource ===== + + @Override + public boolean isActive() { + return super.isActive(); + } + + /** + * 抽取指定要素的 vis,返回实际获得的量(centivis)。 + * 解析隧道中真正面对中继的一端并从其抽取,消耗 AE 能量支付传输。 + */ + @Override + public int consumeVis(ResourceLocation aspectId, int amount) { + if (!isActive() || inConsume) { + return 0; + } + inConsume = true; + try { + VisInterfacePart src = findRelayEnd(); + if (src == null) { + return 0; + } + if (src == this) { + return drawFromRelay(getRelay(), aspectId, amount); + } + // 委托给真正面对中继的那一端。 + return src.consumeVis(aspectId, amount); + } finally { + inConsume = false; + } + } + + // ===== Relay 检测与 vis 抽取 ===== + + /** + * 该部件面对的 TC4 vis 中继,无则 null。中继对 vis 传输是全向的,无需朝向检查。 + */ + private VisRelayBlockEntity getRelay() { + Level level = getLevel(); + if (level == null || getBlockEntity() == null) { + return null; + } + BlockPos front = getBlockEntity().getBlockPos().relative(getSide()); + BlockEntity be = level.getBlockEntity(front); + if (be instanceof VisRelayBlockEntity relay) { + return relay; + } + return null; + } + + /** + * 找到面对中继的隧道端:优先 P2P 输入端,其次任一输出端,最后自身。 + */ + private VisInterfacePart findRelayEnd() { + VisInterfacePart input = getInput(); + if (input != null && input.getRelay() != null) { + return input; + } + for (VisInterfacePart output : getOutputs()) { + if (output.getRelay() != null) { + return output; + } + } + if (getRelay() != null) { + return this; + } + return null; + } + + private int drawFromRelay(VisRelayBlockEntity relay, ResourceLocation aspectId, int centivis) { + if (relay == null) { + return 0; + } + Aspect aspect = rlToAspect(aspectId); + if (aspect == null) { + return 0; + } + IEnergyService energy = getMainNode() != null && getMainNode().getGrid() != null + ? getMainNode().getGrid().getEnergyService() + : null; + if (energy == null) { + return 0; + } + // 先确认能量足够支付传输成本。 + double simulated = energy.extractAEPower(POWER_PER_REQUESTED_VIS, Actionable.SIMULATE, PowerMultiplier.CONFIG); + if (simulated < POWER_PER_REQUESTED_VIS) { + return 0; + } + int amountReceived = relay.consumeVis(aspect, centivis); + if (amountReceived > 0) { + energy.extractAEPower(POWER_PER_REQUESTED_VIS, Actionable.MODULATE, PowerMultiplier.CONFIG); + setDrainColor(aspect.color()); + } + return amountReceived; + } + + // ===== Provider(VisNetHandler 源)管理 ===== + + /** + * 该端自身不面对中继、但隧道另一端面对时,作为 TC4 网络的 vis 源。 + */ + private boolean shouldProvide() { + if (getRelay() != null) { + return false; + } + VisInterfacePart relayEnd = findRelayEnd(); + return relayEnd != null && relayEnd != this; + } + + private void registerProvider() { + Level level = getLevel(); + if (level == null || getBlockEntity() == null) { + return; + } + if (visProviderProxy != null) { + providerActive = true; + return; + } + BlockPos front = getBlockEntity().getBlockPos().relative(getSide()); + BlockState state = level.getBlockState(front); + VisProviderProxy proxy = new VisProviderProxy(front, state); + proxy.bind(this, level); + VisNetHandler.addSource(level, proxy); + this.visProviderProxy = proxy; + this.providerActive = true; + this.isProvider = true; + } + + private void removeProvider() { + if (visProviderProxy != null) { + VisNetHandler.removeNode(visProviderProxy); + this.visProviderProxy = null; + } + this.providerActive = false; + this.isProvider = false; + } + + private void setDrainColor(int color) { + if (color != 0) { + if (color == visDrainingColor) { + lastColorUpdate = System.currentTimeMillis(); + return; + } + if ((System.currentTimeMillis() - lastColorUpdate) <= (TIME_TO_CLEAR / 2)) { + return; + } + lastColorUpdate = System.currentTimeMillis(); + } + this.visDrainingColor = color; + if (getHost() != null) { + getHost().markForUpdate(); + } + } + + // ===== Ticking ===== + + @Override + public TickingRequest getTickingRequest(IGridNode node) { + return new TickingRequest(30, 30, false); + } + + @Override + public TickRateModulation tickingRequest(IGridNode node, int ticksSinceLastCall) { + if (!isActive()) { + removeProvider(); + return TickRateModulation.SAME; + } + if (shouldProvide() && !providerActive) { + registerProvider(); + } else if (!shouldProvide() && providerActive) { + removeProvider(); + } + if (visDrainingColor != 0 && (System.currentTimeMillis() - lastColorUpdate) > TIME_TO_CLEAR) { + setDrainColor(0); + } + return TickRateModulation.SAME; + } + + // ===== NBT ===== + + @Override + public void readFromNBT(CompoundTag tag, HolderLookup.Provider registries) { + super.readFromNBT(tag, registries); + this.uid = tag.getLong(NBT_KEY_UID); + this.isProvider = tag.getBoolean(NBT_KEY_IS_PROVIDER); + } + + @Override + public void writeToNBT(CompoundTag tag, HolderLookup.Provider registries) { + super.writeToNBT(tag, registries); + tag.putLong(NBT_KEY_UID, this.uid); + tag.putBoolean(NBT_KEY_IS_PROVIDER, this.isProvider); + } + + // ===== Aspect <-> ResourceLocation 辅助 ===== + + private static Aspect rlToAspect(ResourceLocation rl) { + return Aspect.get(rl.getPath()); + } +} diff --git a/src/main/java/thaumicenergistics/common/storage/TransportPermissions.java b/src/main/java/thaumicenergistics/common/storage/TransportPermissions.java new file mode 100644 index 0000000..e5c58f7 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/storage/TransportPermissions.java @@ -0,0 +1,33 @@ +package thaumicenergistics.common.storage; + +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.item.Item; +import thaumicenergistics.api.IThETransportPermissions; +import java.util.*; + +public class TransportPermissions implements IThETransportPermissions { + private final Map, Integer> tileExtract = new HashMap<>(); + private final Map, Integer> tileInject = new HashMap<>(); + private final Map, ContainerItemInfo> itemPerms = new HashMap<>(); + + @Override + public boolean addTileToBoth(Class c, int cap) { + boolean a = addTileToExtract(c, cap); boolean b = addTileToInject(c, cap); return a || b; + } + @Override + public boolean addTileToExtract(Class c, int cap) { return tileExtract.putIfAbsent(c, cap) == null; } + @Override + public boolean addTileToInject(Class c, int cap) { return tileInject.putIfAbsent(c, cap) == null; } + @Override + public java.util.OptionalLong getCapacityForTile(Class c) { + Integer v = tileExtract.get(c); return v != null ? java.util.OptionalLong.of(v) : java.util.OptionalLong.empty(); + } + @Override + public boolean canExtract(BlockEntity tile) { return tile != null && tileExtract.containsKey(tile.getClass()); } + @Override + public boolean canInject(BlockEntity tile) { return tile != null && tileInject.containsKey(tile.getClass()); } + @Override + public void addContainerItem(Class c, int cap, boolean partial) { itemPerms.put(c, new ContainerItemInfo(cap, partial)); } + + public record ContainerItemInfo(int capacity, boolean canHoldPartial) {} +} diff --git a/src/main/java/thaumicenergistics/common/tiles/ThETileBase.java b/src/main/java/thaumicenergistics/common/tiles/ThETileBase.java new file mode 100644 index 0000000..74bdb06 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/tiles/ThETileBase.java @@ -0,0 +1,17 @@ +package thaumicenergistics.common.tiles; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; + +public abstract class ThETileBase extends BlockEntity { + protected boolean isActive; + public ThETileBase(BlockEntityType type, BlockPos pos, BlockState state) { super(type, pos, state); } + public boolean isActive() { return isActive; } + public void onBreakBlock() {} + @Override protected void loadAdditional(CompoundTag tag, HolderLookup.Provider reg) { super.loadAdditional(tag, reg); isActive = tag.getBoolean("Active"); } + @Override protected void saveAdditional(CompoundTag tag, HolderLookup.Provider reg) { super.saveAdditional(tag, reg); tag.putBoolean("Active", isActive); } +} diff --git a/src/main/java/thaumicenergistics/common/tiles/TileArcaneAssembler.java b/src/main/java/thaumicenergistics/common/tiles/TileArcaneAssembler.java new file mode 100644 index 0000000..6e3abc9 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/tiles/TileArcaneAssembler.java @@ -0,0 +1,819 @@ +package thaumicenergistics.common.tiles; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.Hashtable; +import java.util.List; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.Containers; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.Nullable; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.Container; +import net.minecraft.world.SimpleContainer; + +import appeng.api.config.Actionable; +import appeng.api.config.PowerMultiplier; +import appeng.api.crafting.IPatternDetails; +import appeng.api.implementations.blockentities.ICraftingMachine; +import appeng.api.implementations.blockentities.PatternContainerGroup; +import appeng.api.networking.GridFlags; +import appeng.api.networking.GridHelper; +import appeng.api.networking.IGrid; +import appeng.api.networking.IGridNode; +import appeng.api.networking.IGridNodeListener; +import appeng.api.networking.IManagedGridNode; +import appeng.api.networking.IInWorldGridNodeHost; +import appeng.api.networking.crafting.ICraftingProvider; +import appeng.api.networking.energy.IEnergyService; +import appeng.api.networking.security.IActionHost; +import appeng.api.networking.security.IActionSource; +import appeng.api.networking.storage.IStorageService; +import appeng.api.networking.ticking.IGridTickable; +import appeng.api.networking.ticking.TickRateModulation; +import appeng.api.networking.ticking.TickingRequest; +import appeng.api.stacks.AEItemKey; +import appeng.api.stacks.AEKey; +import appeng.api.stacks.GenericStack; +import appeng.api.stacks.KeyCounter; +import appeng.api.util.AECableType; + +import thaumcraft.api.IVisDiscountGear; +import thaumcraft.api.IWarpingGear; +import thaumcraft.api.ThaumcraftApi; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; +import thaumcraft.api.crafting.IArcaneRecipe; + +import thaumicenergistics.api.grid.IEssentiaGrid; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.common.integration.tc.ArcaneCraftingPattern; +import thaumicenergistics.common.integration.tc.TCReflection; +import thaumicenergistics.common.inventory.HandlerKnowledgeCore; +import thaumicenergistics.init.ModBlockEntities; +import thaumicenergistics.init.ModItems; + +public class TileArcaneAssembler extends ThETileBase + implements IInWorldGridNodeHost, IActionHost, IGridTickable, ICraftingProvider, ICraftingMachine { + + public static final Aspect[] PRIMALS = { + Aspect.AIR, Aspect.FIRE, Aspect.WATER, + Aspect.EARTH, Aspect.ORDER, Aspect.ENTROPY + }; + + private static final int CVIS_MULTIPLIER = 10; + private static final int MAX_STORED_CVIS = 187 * CVIS_MULTIPLIER; + private static final int BASE_TICKS_PER_CRAFT = 20; + private static final double IDLE_POWER = 0.0; + private static final double ACTIVE_POWER = 1.5; + private static final double WARP_POWER_PERCENT = 0.15; + private static final int MAX_SPEED_UPGRADES = 4; + private static final int VIS_REPLENISH_INTERVAL = 5; + /** 每次实际 vis 变化累计达到该值才调用一次 setChanged(约 4×5=20 tick),避免合成期间 chunk 持续处于 unsaved 状态。 */ + private static final int SET_CHANGED_INTERVAL = 4; + + public static final int SLOT_COUNT = 27; + public static final int KCORE_SLOT = 0; + public static final int PATTERN_SLOT_START = 1; + public static final int PATTERN_SLOT_END = 21; + public static final int TARGET_SLOT = 22; + public static final int ARMOR_SLOT_START = 23; + public static final int ARMOR_SLOT_END = 26; + + protected final IManagedGridNode mainNode; + private final IActionSource actionSource; + + private final IGridNodeListener nodeListener = new IGridNodeListener<>() { + @Override + public void onSaveChanges(TileArcaneAssembler owner, IGridNode node) { + owner.setChanged(); + } + + @Override + public void onStateChanged(TileArcaneAssembler owner, IGridNode node, State state) { + if (state == State.POWER) { + owner.isActive = owner.mainNode.isActive(); + } + owner.markForUpdate(); + } + }; + + private boolean isCrafting = false; + private int craftTickCounter = 0; + private int speedUpgrades = 0; + /** + * 从内存卡粘贴的 vis_interface P2P 频率;装配器优先从该频率的 vis_interface P2P 端抽 vis。 + * 0 = 未设置,走 essentia 网络。对应 1.7.10 的 visSourceInfo,但用 P2P 频率替代位置(适配 neo P2P 设计)。 + */ + private short visSourceFreq = 0; + private AspectList storedVis = new AspectList(); + private Hashtable visDiscount = new Hashtable<>(); + private float warpPowerMultiplier = 1.0F; + private IArcaneRecipe currentRecipe = null; + private AspectList currentRecipeAspects = new AspectList(); + private ItemStack currentResult = ItemStack.EMPTY; + private int visTickCounter = 0; + /** replenishVis 的 setChanged 节流计数。 */ + private int visSetChangedCounter = 0; + private boolean stalePatterns = false; + /** 客户端接收全量槽位同步包时置 true,跳过 setItem 连锁的 setChanged/onInventoryChanged(客户端无网格,这些逻辑无意义)。 */ + private boolean loadingFromClientTag = false; + private Direction attachmentSide = Direction.NORTH; + + private final SimpleContainer internalInventory = new SimpleContainer(SLOT_COUNT) { + @Override + public void setItem(int slot, ItemStack stack) { + super.setItem(slot, stack); + if (loadingFromClientTag) return; + TileArcaneAssembler.this.setChanged(); + TileArcaneAssembler.this.onInventoryChanged(slot); + } + }; + + public TileArcaneAssembler(BlockPos pos, BlockState state) { + super(ModBlockEntities.ARCANE_ASSEMBLER.get(), pos, state); + + mainNode = GridHelper.createManagedNode(this, nodeListener) + .setVisualRepresentation(thaumicenergistics.init.ModItems.ARCANE_ASSEMBLER_ITEM.get()) + .setInWorldNode(true) + .setTagName("proxy") + .setFlags(GridFlags.REQUIRE_CHANNEL) + .setExposedOnSides(EnumSet.allOf(Direction.class)) + .addService(IGridTickable.class, this) + .addService(ICraftingProvider.class, this); + mainNode.setIdlePowerUsage(IDLE_POWER); + actionSource = IActionSource.ofMachine(this); + + for (Aspect primal : PRIMALS) { + visDiscount.put(primal, 0.8F); + } + } + + @Override + public void onLoad() { + super.onLoad(); + if (level != null && !level.isClientSide()) { + mainNode.create(level, getBlockPos()); + } + } + + @Override + public void setRemoved() { + super.setRemoved(); + if (mainNode != null) mainNode.destroy(); + } + + @Override + public void onBreakBlock() { + super.onBreakBlock(); + if (level != null && !level.isClientSide) { + for (int i = 0; i < SLOT_COUNT; i++) { + if (i >= PATTERN_SLOT_START && i <= PATTERN_SLOT_END) continue; + if (i == TARGET_SLOT) continue; + ItemStack stack = internalInventory.getItem(i); + if (!stack.isEmpty()) { + Containers.dropItemStack(level, worldPosition.getX(), worldPosition.getY(), worldPosition.getZ(), stack); + } + } + } + } + + @Override + @Nullable + public IGridNode getGridNode(Direction dir) { + return mainNode.getNode(); + } + + @Override + @Nullable + public IGridNode getActionableNode() { + return mainNode.getNode(); + } + + public AECableType getCableConnectionType(Direction dir) { + return AECableType.SMART; + } + + @Override + public TickingRequest getTickingRequest(IGridNode node) { + // 第三个参数是 isSleeping。之前传 !isCrafting,装配器放置时 isCrafting=false → isSleeping=true, + // 节点一注册就休眠且无法自唤醒(tickingRequest 不被调用就永远无法返回 WAKE), + // 导致 stalePatterns 的延迟 requestUpdate 永不触发、vis 不补充、合成不推进。 + // 改为 false(不休眠),由 tickingRequest 返回的 TickRateModulation 动态控制速率。 + return new TickingRequest(1, 20, false); + } + + @Override + public TickRateModulation tickingRequest(IGridNode node, int ticksSinceLast) { + if (level == null || level.isClientSide()) return TickRateModulation.SLEEP; + IGrid grid = node.getGrid(); + if (grid == null) return TickRateModulation.IDLE; + + if (!mainNode.isActive()) return TickRateModulation.IDLE; + + if (stalePatterns) { + ICraftingProvider.requestUpdate(mainNode); + stalePatterns = false; + } + + visTickCounter++; + if (visTickCounter >= VIS_REPLENISH_INTERVAL) { + visTickCounter = 0; + // 仅合成中或 vis 未满时才抽(满时每 5 tick 空转会白跑 P2P/网格查询) + if (isCrafting || !storedVisFull()) { + replenishVis(grid); + } + } + + if (isCrafting) { + return craftingTick(grid, ticksSinceLast); + } + + return TickRateModulation.IDLE; + } + + /** 全部原质元素均已达到缓存上限。 */ + private boolean storedVisFull() { + for (Aspect primal : PRIMALS) { + if (storedVis.getAmount(primal) < MAX_STORED_CVIS) { + return false; + } + } + return true; + } + + private void replenishVis(IGrid grid) { + // 优先从内存卡配置的 vis_interface P2P 源抽 vis(1.7.10 vis 源机制,适配 neo P2P) + if (visSourceFreq != 0) { + appeng.me.service.P2PService p2p = appeng.me.service.P2PService.get(grid); + if (p2p != null) { + appeng.parts.p2p.P2PTunnelPart input = p2p.getInput(visSourceFreq); + if (input instanceof thaumicenergistics.common.parts.VisInterfacePart visSource) { + for (Aspect primal : PRIMALS) { + int needed = MAX_STORED_CVIS - storedVis.getAmount(primal); + if (needed <= 0) continue; + ResourceLocation id = TCReflection.getAspectId(primal); + if (id == null) continue; + int got = visSource.consumeVis(id, needed); + if (got > 0) { + storedVis.add(primal, got); + maybeMarkVisDirty(); + } + } + return; // 有 vis 源时只用它(1.7.10 行为:源不可用则不抽) + } + } + return; // 频率设了但找不到 vis_interface P2P 输入 → 不抽 + } + + // 无 vis 源:从 essentia 网络抽(neo 默认行为) + IEssentiaGrid essentiaGrid = grid.getService(IEssentiaGrid.class); + if (essentiaGrid == null) return; + + for (Aspect primal : PRIMALS) { + int currentCvis = storedVis.getAmount(primal); + int needed = MAX_STORED_CVIS - currentCvis; + if (needed <= 0) continue; + + ResourceLocation id = TCReflection.getAspectId(primal); + if (id == null) continue; + + int neededEssentia = (needed + CVIS_MULTIPLIER - 1) / CVIS_MULTIPLIER; + long extracted = essentiaGrid.extractEssentia(id, neededEssentia, false); + if (extracted > 0) { + int cvisGained = (int) (extracted * CVIS_MULTIPLIER); + storedVis.add(primal, cvisGained); + maybeMarkVisDirty(); + } + } + } + + /** + * replenishVis 抽到 vis 时调用:累计变化次数,每 SET_CHANGED_INTERVAL 次才标记一次 chunk dirty。 + * 降低合成期间持续磁盘写放大;storedVis 最终仍会在合成完成路径(craftingTick)或区块保存时落盘。 + */ + private void maybeMarkVisDirty() { + if (++visSetChangedCounter >= SET_CHANGED_INTERVAL) { + visSetChangedCounter = 0; + setChanged(); + } + } + + private TickRateModulation craftingTick(IGrid grid, int ticksSinceLast) { + if (currentResult.isEmpty()) { + isCrafting = false; + return TickRateModulation.IDLE; + } + + boolean enoughVis = hasEnoughVisForCraft(); + if (!enoughVis) { + ThaumicEnergistics.LOG.debug("[AA] craftingTick: vis 不足,等待补充 (storedVis cvis={})", storedVis.visSize()); + return TickRateModulation.SAME; + } + + int ticksPerCraft = ticksPerCraft(); + + if (craftTickCounter >= ticksPerCraft) { + IStorageService storage = grid.getService(IStorageService.class); + if (storage == null) return TickRateModulation.IDLE; + + ItemStack output = currentResult.copy(); + AEItemKey outputKey = AEItemKey.of(output); + if (outputKey == null) return TickRateModulation.IDLE; + + long inserted = storage.getInventory().insert( + outputKey, output.getCount(), Actionable.SIMULATE, actionSource); + if (inserted < output.getCount()) { + ThaumicEnergistics.LOG.debug("[AA] craftingTick: 产物无法插入网络(模拟 inserted={}/{}),等待", inserted, output.getCount()); + return TickRateModulation.SAME; + } + + consumeVisForCraft(); + + storage.getInventory().insert( + outputKey, output.getCount(), Actionable.MODULATE, actionSource); + ThaumicEnergistics.LOG.debug("[AA] craftingTick: 完成!插入产物 {}x{} 到网络", outputKey, output.getCount()); + + isCrafting = false; + currentRecipe = null; + currentResult = ItemStack.EMPTY; + currentRecipeAspects = new AspectList(); + internalInventory.setItem(TARGET_SLOT, ItemStack.EMPTY); + setChanged(); + markForUpdate(); + + return TickRateModulation.URGENT; + } + + double powerRequired = (ACTIVE_POWER + (ACTIVE_POWER * speedUpgrades) / 2.0) * warpPowerMultiplier; + IEnergyService energy = grid.getService(IEnergyService.class); + if (energy != null) { + double need = powerRequired * ticksSinceLast; + double extracted = energy.extractAEPower(need, Actionable.MODULATE, PowerMultiplier.CONFIG); + if (extracted >= need * 0.9) { + craftTickCounter += ticksSinceLast; + ThaumicEnergistics.LOG.debug("[AA] craftingTick: 推进 {}/{} (抽电 {}/{})", craftTickCounter, ticksPerCraft, extracted, need); + } else { + ThaumicEnergistics.LOG.debug("[AA] craftingTick: 能量不足 (抽到 {}/{}),不推进", extracted, need); + } + } + + return TickRateModulation.SAME; + } + + private void consumeVisForCraft() { + if (currentRecipeAspects == null || currentRecipeAspects.isEmpty()) return; + for (Aspect aspect : currentRecipeAspects.getAspects()) { + int requiredCvis = getRequiredCvisForAspect(aspect); + int current = storedVis.getAmount(aspect); + storedVis.reduce(aspect, Math.min(requiredCvis, current)); + } + setChanged(); + } + + private boolean hasEnoughVisForCraft() { + if (currentRecipeAspects == null || currentRecipeAspects.isEmpty()) return true; + for (Aspect aspect : currentRecipeAspects.getAspects()) { + int requiredCvis = getRequiredCvisForAspect(aspect); + if (storedVis.getAmount(aspect) < requiredCvis) return false; + } + return true; + } + + private int getRequiredCvisForAspect(Aspect aspect) { + if (currentRecipeAspects == null) return 0; + int baseCost = currentRecipeAspects.getAmount(aspect) * CVIS_MULTIPLIER; + float discount = visDiscount.getOrDefault(aspect, 1.0F); + return Math.max(0, Math.round(baseCost * discount)); + } + + private int ticksPerCraft() { + return Math.max(4, BASE_TICKS_PER_CRAFT - (4 * speedUpgrades)); + } + + private void calculateVisDiscounts() { + for (Aspect primal : PRIMALS) { + float discount = 0.8F; + + for (int i = 0; i < 4; i++) { + ItemStack armor = internalInventory.getItem(ARMOR_SLOT_START + i); + if (!armor.isEmpty() && armor.getItem() instanceof IVisDiscountGear gear) { + try { + discount -= gear.getVisDiscount(armor, null, primal) / 100.0F; + } catch (Exception ignored) {} + } + } + + visDiscount.put(primal, Math.max(0.1F, discount)); + } + + warpPowerMultiplier = 1.0F; + for (int i = 0; i < 4; i++) { + ItemStack armor = internalInventory.getItem(ARMOR_SLOT_START + i); + if (!armor.isEmpty() && armor.getItem() instanceof IWarpingGear gear) { + try { + warpPowerMultiplier += gear.getWarp(armor, null) * WARP_POWER_PERCENT; + } catch (Exception ignored) {} + } + } + } + + @Override + public List getAvailablePatterns() { + ItemStack kCore = internalInventory.getItem(KCORE_SLOT); + if (kCore.isEmpty() || !kCore.is(ModItems.KNOWLEDGE_CORE.get())) { + return List.of(); + } + + HandlerKnowledgeCore handler = new HandlerKnowledgeCore(kCore); + if (!handler.hasCore()) { + return List.of(); + } + + List result = new ArrayList<>(); + List patterns = handler.getPatterns(); + for (ArcaneCraftingPattern acp : patterns) { + if (acp == null || !acp.isPatternValid()) continue; + ArcaneAssemblerPattern ap = buildArcanePattern(acp); + if (ap != null) { + result.add(ap); + ThaumicEnergistics.LOG.debug("[AA] getAvailablePatterns: pattern primaryOutput={}, definition={}", + ap.getPrimaryOutput(), ap.getDefinition()); + } + } + ThaumicEnergistics.LOG.debug("[AA] getAvailablePatterns: kCore valid={}, handler patterns={}, returned={}", + !kCore.isEmpty(), patterns.size(), result.size()); + return result; + } + + @Override + public boolean pushPattern(IPatternDetails patternDetails, KeyCounter[] inputHolder) { + ThaumicEnergistics.LOG.info("[AA] pushPattern(provider) called, pattern={}, isArcanePattern={}", + patternDetails, patternDetails instanceof ArcaneAssemblerPattern); + if (patternDetails instanceof ArcaneAssemblerPattern arcanePattern) { + return beginCrafting(arcanePattern); + } + return false; + } + + private ArcaneAssemblerPattern buildArcanePattern(ArcaneCraftingPattern acp) { + ItemStack result = acp.getResult(); + if (result == null || result.isEmpty()) return null; + + AspectList aspects = acp.getAspects(); + ItemStack[] ingredients = acp.getIngredients(); + + List inputs = new ArrayList<>(); + if (ingredients != null) { + for (ItemStack ing : ingredients) { + if (ing == null || ing.isEmpty()) continue; + AEItemKey key = AEItemKey.of(ing); + if (key != null) { + inputs.add(new GenericStack(key, ing.getCount())); + } + } + } + + return new ArcaneAssemblerPattern(AEItemKey.of(result), null, aspects, result, inputs); + } + + private boolean beginCrafting(ArcaneAssemblerPattern arcanePattern) { + AspectList aspects = arcanePattern.getAspects(); + ItemStack result = arcanePattern.getResultStack(); + ThaumicEnergistics.LOG.info("[AA] beginCrafting: isCrafting={}, active={}, aspectsEmpty={}, resultEmpty={}", + isCrafting, mainNode.isActive(), + aspects == null || aspects.isEmpty(), result.isEmpty()); + if (isCrafting || !mainNode.isActive()) return false; + if (aspects == null || aspects.isEmpty() || result.isEmpty()) return false; + + this.isCrafting = true; + this.craftTickCounter = 0; + this.currentRecipe = arcanePattern.getRecipe(); + this.currentRecipeAspects = aspects.copy(); + this.currentResult = result.copy(); + this.internalInventory.setItem(TARGET_SLOT, result.copy()); + setChanged(); + markForUpdate(); + ThaumicEnergistics.LOG.info("[AA] beginCrafting: STARTED, result={}, aspects={}", result, aspects.visSize()); + return true; + } + + @Override + public boolean isBusy() { + return isCrafting; + } + + @Override + public PatternContainerGroup getCraftingMachineInfo() { + ItemStack icon = new ItemStack(thaumicenergistics.init.ModItems.ARCANE_ASSEMBLER_ITEM.get()); + return new PatternContainerGroup( + AEItemKey.of(icon), + net.minecraft.network.chat.Component.translatable("block.thaumicenergistics.arcane_assembler"), + List.of() + ); + } + + @Override + public boolean pushPattern(IPatternDetails patternDetails, KeyCounter[] inputs, Direction ejectionDirection) { + if (patternDetails instanceof ArcaneAssemblerPattern arcanePattern) { + return beginCrafting(arcanePattern); + } + return false; + } + + @Override + public boolean acceptsPlans() { + return !isCrafting; + } + + @Nullable + public IArcaneRecipe findMatchingArcaneRecipe(Container craftingGrid) { + if (level == null) return null; + for (Object recipeObj : ThaumcraftApi.getCraftingRecipes()) { + if (recipeObj instanceof IArcaneRecipe recipe) { + try { + if (recipe.matches(craftingGrid, level, null)) { + return recipe; + } + } catch (Exception ignored) {} + } + } + return null; + } + + public boolean isCrafting() { return isCrafting; } + public int getSpeedUpgrades() { return speedUpgrades; } + public int getCraftTickCounter() { return craftTickCounter; } + public int getTicksPerCraft() { return ticksPerCraft(); } + public float getCraftProgress() { + if (!isCrafting || ticksPerCraft() <= 0) return 0f; + return Math.min(1f, (float) craftTickCounter / ticksPerCraft()); + } + public AspectList getStoredVis() { return storedVis; } + public SimpleContainer getInternalInventory() { return internalInventory; } + public float getVisDiscountForAspect(Aspect aspect) { return visDiscount.getOrDefault(aspect, 1.0F); } + public float getWarpPowerMultiplier() { return warpPowerMultiplier; } + + public void setSpeedUpgrades(int count) { + this.speedUpgrades = Math.min(count, MAX_SPEED_UPGRADES); + setChanged(); + } + + public short getVisSourceFreq() { return visSourceFreq; } + + /** + * 内存卡右键装配器:读 P2P 频率,设为 vis 源。 + * 复刻 1.7.10 onMemoryCardActivate,但用 P2P 频率替代 DigiVisSourceData 位置(适配 neo vis_interface P2P)。 + * 卡上有 EXPORTED_P2P_FREQUENCY → 存频率;空白卡 → 清空;其它 → 无效。 + */ + public void onMemoryCardActivate(net.minecraft.world.entity.player.Player player, + appeng.api.implementations.items.IMemoryCard memoryCard, + net.minecraft.world.item.ItemStack heldItem) { + Short freq = heldItem.get(appeng.api.ids.AEComponents.EXPORTED_P2P_FREQUENCY); + if (freq != null) { + // 卡上带 P2P 频率(从 vis_interface shift+右键复制来的)→ 设为 vis 源 + this.visSourceFreq = freq; + this.setChanged(); + memoryCard.notifyUser(player, appeng.api.implementations.items.MemoryCardMessages.SETTINGS_LOADED); + } else if (heldItem.get(appeng.api.ids.AEComponents.EXPORTED_SETTINGS_SOURCE) == null) { + // 空白卡 → 清空 vis 源 + if (this.visSourceFreq != 0) { + this.visSourceFreq = 0; + this.setChanged(); + } + memoryCard.notifyUser(player, appeng.api.implementations.items.MemoryCardMessages.SETTINGS_CLEARED); + } else { + // 卡上有其它配置(非 P2P 频率)→ 不兼容 + memoryCard.notifyUser(player, appeng.api.implementations.items.MemoryCardMessages.INVALID_MACHINE); + } + } + + public void onInventoryChanged(int slot) { + if (slot == KCORE_SLOT) { + stalePatterns = true; + updatePatternSlots(); + // 直接通知 AE2 合成服务重新拉取 getAvailablePatterns()。 + // 之前仅靠 tickingRequest 里处理 stalePatterns 再 requestUpdate, + // 但节点休眠时 tickingRequest 不被调用,AE2 永远学不到 kCore 里的样板 → ME 终端无可合成项。 + // 守卫 getGrid()!=null:装配器未连 ME 网络(无相邻 cable)时 getGrid() 为 null, + // 此时 requestUpdate 内部 node.getGrid().getCraftingService() 会 NPE,导致 kCore 插入事务回滚 → "无法绑定"。 + if (level != null && !level.isClientSide() && mainNode.getGrid() != null) { + ThaumicEnergistics.LOG.info("[AA] kCore slot changed → requestUpdate"); + ICraftingProvider.requestUpdate(mainNode); + } + } + if (slot >= ARMOR_SLOT_START && slot <= ARMOR_SLOT_END) { + calculateVisDiscounts(); + } + if (slot >= PATTERN_SLOT_START && slot <= PATTERN_SLOT_END) { + stalePatterns = true; + } + setChanged(); + } + + private void updatePatternSlots() { + ItemStack kCore = internalInventory.getItem(KCORE_SLOT); + if (kCore.isEmpty() || !kCore.is(ModItems.KNOWLEDGE_CORE.get())) { + for (int i = PATTERN_SLOT_START; i <= PATTERN_SLOT_END; i++) { + internalInventory.setItem(i, ItemStack.EMPTY); + } + return; + } + + HandlerKnowledgeCore handler = new HandlerKnowledgeCore(kCore); + ArrayList outputs = handler.hasCore() ? handler.getStoredOutputs() : new ArrayList<>(); + for (int i = PATTERN_SLOT_START; i <= PATTERN_SLOT_END; i++) { + int idx = i - PATTERN_SLOT_START; + if (idx < outputs.size()) { + internalInventory.setItem(i, outputs.get(idx).copy()); + } else { + internalInventory.setItem(i, ItemStack.EMPTY); + } + } + } + + public void markForUpdate() { + if (level != null) { + setChanged(); + level.sendBlockUpdated(worldPosition, getBlockState(), getBlockState(), 3); + } + } + + @Override + public CompoundTag getUpdateTag(HolderLookup.Provider reg) { + CompoundTag tag = super.getUpdateTag(reg); + for (int i = 0; i < SLOT_COUNT; i++) { + ItemStack stack = internalInventory.getItem(i); + if (!stack.isEmpty()) { + tag.put("Slot" + i, stack.save(reg)); + } + } + return tag; + } + + @Override + public void handleUpdateTag(CompoundTag tag, HolderLookup.Provider reg) { + super.handleUpdateTag(tag, reg); + loadingFromClientTag = true; + try { + for (int i = 0; i < SLOT_COUNT; i++) { + if (tag.contains("Slot" + i)) { + ItemStack stack = ItemStack.parseOptional(reg, tag.getCompound("Slot" + i)); + internalInventory.setItem(i, stack); + } else { + internalInventory.setItem(i, ItemStack.EMPTY); + } + } + } finally { + loadingFromClientTag = false; + } + } + + @Override + protected void loadAdditional(CompoundTag tag, HolderLookup.Provider reg) { + super.loadAdditional(tag, reg); + mainNode.loadFromNBT(tag); + mainNode.setIdlePowerUsage(isCrafting ? ACTIVE_POWER : IDLE_POWER); + + if (tag.contains("AttachSide")) attachmentSide = Direction.from3DDataValue(tag.getInt("AttachSide")); + isCrafting = tag.getBoolean("IsCrafting"); + craftTickCounter = tag.getInt("CraftTick"); + speedUpgrades = tag.getInt("SpeedUpgrades"); + visSourceFreq = tag.contains("VisSourceFreq") ? tag.getShort("VisSourceFreq") : 0; + + storedVis = new AspectList(); + if (tag.contains("StoredVis")) { + CompoundTag visTag = tag.getCompound("StoredVis"); + for (Aspect primal : PRIMALS) { + String key = primal.getTag(); + if (visTag.contains(key)) { + storedVis.add(primal, visTag.getInt(key)); + } + } + } + + for (int i = 0; i < SLOT_COUNT; i++) { + if (tag.contains("Slot" + i)) { + ItemStack stack = ItemStack.parseOptional(reg, tag.getCompound("Slot" + i)); + internalInventory.setItem(i, stack); + } else { + internalInventory.setItem(i, ItemStack.EMPTY); + } + } + + updatePatternSlots(); + stalePatterns = true; + calculateVisDiscounts(); + } + + @Override + protected void saveAdditional(CompoundTag tag, HolderLookup.Provider reg) { + super.saveAdditional(tag, reg); + tag.putInt("AttachSide", attachmentSide.get3DDataValue()); + mainNode.saveToNBT(tag); + tag.putBoolean("IsCrafting", isCrafting); + tag.putInt("CraftTick", craftTickCounter); + tag.putInt("SpeedUpgrades", speedUpgrades); + if (visSourceFreq != 0) tag.putShort("VisSourceFreq", visSourceFreq); + + CompoundTag visTag = new CompoundTag(); + for (Aspect primal : PRIMALS) { + int amount = storedVis.getAmount(primal); + if (amount > 0) { + visTag.putInt(primal.getTag(), amount); + } + } + tag.put("StoredVis", visTag); + + for (int i = 0; i < SLOT_COUNT; i++) { + ItemStack stack = internalInventory.getItem(i); + if (!stack.isEmpty()) { + tag.put("Slot" + i, stack.save(reg)); + } + } + } + + public static class ArcaneAssemblerPattern implements IPatternDetails { + private final AEItemKey definition; + private final IArcaneRecipe recipe; + private final AspectList aspects; + private final ItemStack resultStack; + private final IInput[] inputs; + + public ArcaneAssemblerPattern(AEItemKey definition, IArcaneRecipe recipe, + AspectList aspects, ItemStack resultStack, + List inputStacks) { + this.definition = definition; + this.recipe = recipe; + this.aspects = aspects; + this.resultStack = resultStack; + this.inputs = new IInput[inputStacks.size()]; + for (int i = 0; i < inputStacks.size(); i++) { + GenericStack stack = inputStacks.get(i); + this.inputs[i] = new IInput() { + @Override + public GenericStack[] getPossibleInputs() { + return new GenericStack[]{stack}; + } + + @Override + public long getMultiplier() { + return 1; + } + + @Override + public boolean isValid(AEKey input, Level level) { + return input instanceof AEItemKey itemKey + && stack.what() instanceof AEItemKey stackKey + && itemKey.equals(stackKey); + } + + @Nullable + @Override + public AEKey getRemainingKey(AEKey what) { + return null; + } + }; + } + } + + @Override + public AEItemKey getDefinition() { return definition; } + + @Override + public IInput[] getInputs() { return inputs; } + + @Override + public List getOutputs() { + return List.of(new GenericStack(AEItemKey.of(resultStack), resultStack.getCount())); + } + + @Override + public boolean supportsPushInputsToExternalInventory() { + return false; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ArcaneAssemblerPattern other)) return false; + return definition != null && definition.equals(other.definition); + } + + @Override + public int hashCode() { + return definition != null ? definition.hashCode() : 0; + } + + public IArcaneRecipe getRecipe() { return recipe; } + public AspectList getAspects() { return aspects; } + public ItemStack getResultStack() { return resultStack; } + } +} diff --git a/src/main/java/thaumicenergistics/common/tiles/TileDistillationPatternEncoder.java b/src/main/java/thaumicenergistics/common/tiles/TileDistillationPatternEncoder.java new file mode 100644 index 0000000..9003e04 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/tiles/TileDistillationPatternEncoder.java @@ -0,0 +1,57 @@ +package thaumicenergistics.common.tiles; + +import appeng.core.definitions.AEItems; +import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.state.BlockState; +import net.neoforged.neoforge.items.ItemStackHandler; +import thaumicenergistics.init.ModBlockEntities; + +public class TileDistillationPatternEncoder extends ThETileBase { + public static final int SLOT_SOURCE_ITEM = 0; + public static final int SLOT_BLANK_PATTERNS = 1; + public static final int SLOT_ENCODED_PATTERN = 2; + public static final int SLOT_TOTAL_COUNT = 3; + + private static final String NBTKEY_INVENTORY = "inventory"; + + public final ItemStackHandler inventory = new ItemStackHandler(SLOT_TOTAL_COUNT) { + @Override + public boolean isItemValid(int slot, ItemStack stack) { + // blank 槽放宽:接受任意物品(Encode 时验证是否为 AE2 空白样板) + if (slot == SLOT_BLANK_PATTERNS) return true; + if (slot == SLOT_ENCODED_PATTERN) return false; + return true; + } + + @Override + protected void onContentsChanged(int slot) { + setChanged(); + } + }; + + public TileDistillationPatternEncoder(BlockPos pos, BlockState state) { + super(ModBlockEntities.DISTILLATION_ENCODER.get(), pos, state); + } + + public boolean hasPatterns() { + return !inventory.getStackInSlot(SLOT_ENCODED_PATTERN).isEmpty() + || !inventory.getStackInSlot(SLOT_BLANK_PATTERNS).isEmpty(); + } + + @Override + protected void loadAdditional(CompoundTag tag, HolderLookup.Provider reg) { + super.loadAdditional(tag, reg); + if (tag.contains(NBTKEY_INVENTORY)) { + inventory.deserializeNBT(reg, tag.getCompound(NBTKEY_INVENTORY)); + } + } + + @Override + protected void saveAdditional(CompoundTag tag, HolderLookup.Provider reg) { + super.saveAdditional(tag, reg); + tag.put(NBTKEY_INVENTORY, inventory.serializeNBT(reg)); + } +} diff --git a/src/main/java/thaumicenergistics/common/tiles/TileEssentiaCellWorkbench.java b/src/main/java/thaumicenergistics/common/tiles/TileEssentiaCellWorkbench.java new file mode 100644 index 0000000..1a7ccaf --- /dev/null +++ b/src/main/java/thaumicenergistics/common/tiles/TileEssentiaCellWorkbench.java @@ -0,0 +1,66 @@ +package thaumicenergistics.common.tiles; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.neoforged.neoforge.items.ItemStackHandler; +import thaumicenergistics.common.items.ItemEssentiaCell; +import thaumicenergistics.init.ModBlockEntities; + +/** + * 源质元件工作台方块实体:持久化保存一个源质元件(cell),并提供分区编辑入口。 + * 对应 1.7.10 的 {@code TileEssentiaCellWorkbench},分区数据存储在 cell 物品的 AE2 CellConfig 上。 + */ +public class TileEssentiaCellWorkbench extends BlockEntity { + + public static final int SLOT_CELL = 0; + private static final String NBT_KEY_CELL_INVENTORY = "CellInventory"; + + /** 单格 cell 槽,只允许放入 ItemEssentiaCell。 */ + private final ItemStackHandler cellInventory = new ItemStackHandler(1) { + @Override + public boolean isItemValid(int slot, ItemStack stack) { + return stack.isEmpty() || stack.getItem() instanceof ItemEssentiaCell; + } + + @Override + protected void onContentsChanged(int slot) { + super.onContentsChanged(slot); + setChanged(); + } + }; + + public TileEssentiaCellWorkbench(BlockPos pos, BlockState state) { + super(ModBlockEntities.ESSENTIA_CELL_WORKBENCH.get(), pos, state); + } + + public ItemStackHandler getCellInventory() { + return cellInventory; + } + + /** 当前放入的源质元件,空则为 EMPTY。 */ + public ItemStack getCell() { + return cellInventory.getStackInSlot(SLOT_CELL); + } + + public boolean hasCell() { + return !cellInventory.getStackInSlot(SLOT_CELL).isEmpty(); + } + + @Override + protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.saveAdditional(tag, registries); + tag.put(NBT_KEY_CELL_INVENTORY, cellInventory.serializeNBT(registries)); + } + + @Override + protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.loadAdditional(tag, registries); + if (tag.contains(NBT_KEY_CELL_INVENTORY)) { + cellInventory.deserializeNBT(registries, tag.getCompound(NBT_KEY_CELL_INVENTORY)); + } + } +} diff --git a/src/main/java/thaumicenergistics/common/tiles/TileEssentiaProvider.java b/src/main/java/thaumicenergistics/common/tiles/TileEssentiaProvider.java new file mode 100644 index 0000000..70a5a63 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/tiles/TileEssentiaProvider.java @@ -0,0 +1,202 @@ +package thaumicenergistics.common.tiles; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.IEssentiaTransport; +import thaumcraft.common.essentia.EssentiaTransport; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.api.storage.IAspectStack; +import thaumicenergistics.init.ModBlockEntities; +import thaumicenergistics.init.ModItems; + +import java.util.List; + +public class TileEssentiaProvider extends TileProviderBase implements IEssentiaTransport, EssentiaTransport { + + private static final int TICK_RATE_IDLE = 15; + private static final int TICK_RATE_URGENT = 5; + private int tickCount; + private int tickRate = TICK_RATE_IDLE; + + public TileEssentiaProvider(BlockPos pos, BlockState state) { + super(ModBlockEntities.ESSENTIA_PROVIDER.get(), pos, state); + } + + @Override + protected ItemStack getItemFromTile() { + return new ItemStack(ModItems.ESSENTIA_PROVIDER_ITEM.get()); + } + + @Override + protected double getIdlePowerUsage() { + return 3.0; + } + + /** getEssentiaList 短时缓存:TC 管道 suction 每 tick 调 getEssentiaType,避免每 tick 全量遍历。 */ + private List cachedEssentiaList = java.util.List.of(); + private int essentiaListCacheTimer = 0; + private static final int ESSENTIA_LIST_CACHE_TICKS = 20; + + private List getCachedEssentiaList() { + if (essentiaListCacheTimer <= 0) { + essentiaListCacheTimer = ESSENTIA_LIST_CACHE_TICKS; + cachedEssentiaList = essentiaGrid != null ? essentiaGrid.getEssentiaList() : java.util.List.of(); + } + return cachedEssentiaList; + } + + public void serverTick() { + if (level == null || level.isClientSide()) return; + if (!mainNode.isActive()) return; + + if (essentiaListCacheTimer > 0) essentiaListCacheTimer--; + + if (++tickCount >= tickRate) { + tickCount = 0; + tickRate = TICK_RATE_IDLE; + takeEssentiaFromTransportNeighbors(); + } + } + + // ===== IEssentiaTransport ===== + + @Override + public boolean isConnectable(Direction side) { + return true; + } + + @Override + public boolean canInputFrom(Direction side) { + return true; + } + + @Override + public boolean canOutputTo(Direction side) { + return true; + } + + @Override + public void setSuction(Aspect aspect, int amount) { + } + + @Override + public Aspect getSuctionType(Direction side) { + return null; // 接受所有类型 + } + + @Override + public int getSuctionAmount(Direction side) { + return 8; // 最大吸力 + } + + @Override + public int takeEssentia(Aspect aspect, int amount, Direction side) { + ThaumicEnergistics.LOG.debug("[MyHano-E] takeEssentia: aspect={}, amount={}, side={}, active={}", + aspect != null ? aspect.getTag() : "null", amount, side, mainNode.isActive()); + if (!mainNode.isActive()) return 0; + long extracted = extractEssentiaFromNetwork(aspect, amount, false); + ThaumicEnergistics.LOG.debug("[MyHano-E] takeEssentia result={}", extracted); + if (extracted > 0) { + tickRate = TICK_RATE_URGENT; + } + return (int) extracted; + } + + @Override + public int addEssentia(Aspect aspect, int amount, Direction side) { + ThaumicEnergistics.LOG.debug("[MyHano-E] addEssentia: aspect={}, amount={}, side={}, active={}", + aspect != null ? aspect.getTag() : "null", amount, side, mainNode.isActive()); + if (!mainNode.isActive()) return 0; + long rejected = injectEssentiaToNetwork(aspect, amount, false); + long accepted = amount - rejected; + if (accepted > 0) { + ThaumicEnergistics.LOG.debug("[MyHano-E] addEssentia accepted={}", accepted); + tickRate = TICK_RATE_URGENT; + } + return (int) accepted; + } + + @Override + public Aspect getEssentiaType(Direction side) { + Aspect wanted = getNeighborWantedAspect(side); + if (wanted != null && getAspectAmountInNetwork(wanted) > 0) { + return wanted; + } + // 邻居无特定需求时,返回网络中第一种有存量的源质(列表短时缓存,避免 TC 管道每 tick suction 全量遍历) + if (essentiaGrid != null) { + for (var stack : getCachedEssentiaList()) { + if (stack.amount() > 0) { + return Aspect.getAspect(stack.aspectId().getPath()); + } + } + } + return null; + } + + @Override + public int getEssentiaAmount(Direction side) { + Aspect wanted = getNeighborWantedAspect(side); + if (wanted != null) { + return (int) Math.min(getAspectAmountInNetwork(wanted), Integer.MAX_VALUE); + } + return 0; + } + + @Override + public int getMinimumSuction() { + return 1; + } + + @Override + public boolean renderExtendedTube() { + return false; + } + + // ===== 内部 ===== + + private Aspect getNeighborWantedAspect(Direction side) { + BlockPos neighborPos = worldPosition.relative(side); + BlockEntity neighbor = level.getBlockEntity(neighborPos); + if (neighbor instanceof IEssentiaTransport transport) { + return transport.getSuctionType(side.getOpposite()); + } + return null; + } + + private void takeEssentiaFromTransportNeighbors() { + for (Direction side : Direction.values()) { + if (!canInputFrom(side)) continue; + + BlockPos sourcePos = worldPosition.relative(side); + BlockEntity sourceTile = level.getBlockEntity(sourcePos); + if (!(sourceTile instanceof IEssentiaTransport source)) continue; + + Direction sourceSide = side.getOpposite(); + if (!source.canOutputTo(sourceSide)) continue; + if (source.getEssentiaAmount(sourceSide) <= 0) continue; + + int dSuck = getSuctionAmount(side); + if (dSuck < source.getMinimumSuction() || dSuck < source.getSuctionAmount(sourceSide)) { + continue; + } + + Aspect sourceAspect = source.getEssentiaType(sourceSide); + if (sourceAspect == null) continue; + + // 模拟注入 + long simulated = injectEssentiaToNetwork(sourceAspect, 1, true); + if (simulated == 0) { + // 实际提取并注入 + int taken = source.takeEssentia(sourceAspect, 1, sourceSide); + if (taken > 0) { + injectEssentiaToNetwork(sourceAspect, taken, false); + tickRate = TICK_RATE_URGENT; + } + } + } + } +} \ No newline at end of file diff --git a/src/main/java/thaumicenergistics/common/tiles/TileEssentiaVibrationChamber.java b/src/main/java/thaumicenergistics/common/tiles/TileEssentiaVibrationChamber.java new file mode 100644 index 0000000..c5997e0 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/tiles/TileEssentiaVibrationChamber.java @@ -0,0 +1,357 @@ +package thaumicenergistics.common.tiles; + +import java.util.EnumSet; +import java.util.Set; + +import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.Nullable; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.entity.BlockEntity; + +import appeng.api.config.Actionable; +import appeng.api.networking.GridFlags; +import appeng.api.networking.GridHelper; +import appeng.api.networking.IGrid; +import appeng.api.networking.IGridNode; +import appeng.api.networking.IGridNodeListener; +import appeng.api.networking.IManagedGridNode; +import appeng.api.networking.IInWorldGridNodeHost; +import appeng.api.networking.energy.IEnergyService; +import appeng.api.networking.ticking.IGridTickable; +import appeng.api.networking.ticking.TickRateModulation; +import appeng.api.networking.ticking.TickingRequest; +import appeng.api.util.AECableType; + +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.IEssentiaTransport; +import thaumcraft.common.essentia.EssentiaTransport; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.api.grid.IEssentiaGrid; +import thaumicenergistics.common.integration.appeng.AEssentiaKey; +import thaumicenergistics.common.integration.tc.TCReflection; +import thaumicenergistics.init.ModBlockEntities; + +public class TileEssentiaVibrationChamber extends ThETileBase implements IInWorldGridNodeHost, IGridTickable, IEssentiaTransport, EssentiaTransport { + + private static final int MAX_ESSENTIA = 64; + private static final int BASE_BURN_TICKS = 800; + private static final double BASE_AE_PER_TICK = 20.0; + private static final int IDLE_POWER = 1; + + // 能量槽配置:8KFE = 8000 AE,对外最大输出 400 AE/t + public static final double MAX_ENERGY_STORAGE = 8000.0; + public static final double MAX_OUTPUT_PER_TICK = 400.0; + + protected final IManagedGridNode mainNode; + private final IGridNodeListener nodeListener = new IGridNodeListener<>() { + @Override public void onSaveChanges(TileEssentiaVibrationChamber owner, IGridNode node) { owner.setChanged(); } + @Override public void onStateChanged(TileEssentiaVibrationChamber owner, IGridNode node, State state) { + if (state == State.POWER) owner.isActive = owner.mainNode.isActive(); + owner.markForUpdate(); + } + }; + + private Direction attachmentSide = Direction.NORTH; + private int burnTicksRemaining; + private int totalBurnTicks; + private double aePerTick; + private int storedEssentia; + private Aspect currentAspect; + private Aspect suctionAspect = Aspect.ENERGY; + + private double storedEnergy; + + public TileEssentiaVibrationChamber(BlockPos pos, BlockState state) { + super(ModBlockEntities.ESSENTIA_VIBRATION_CHAMBER.get(), pos, state); + mainNode = GridHelper.createManagedNode(this, nodeListener) + .setVisualRepresentation(thaumicenergistics.init.ModItems.ESSENTIA_VIBRATION_CHAMBER_ITEM.get()) + .setInWorldNode(true) + .setTagName("proxy") + .setFlags(GridFlags.REQUIRE_CHANNEL) + .setExposedOnSides(EnumSet.allOf(Direction.class)) + .addService(IGridTickable.class, this); + } + + @Override + public void onLoad() { + super.onLoad(); + if (level != null && !level.isClientSide()) { + mainNode.create(level, getBlockPos()); + } + } + + @Override + public void setRemoved() { + super.setRemoved(); + if (mainNode != null) mainNode.destroy(); + } + + @Override @Nullable + public IGridNode getGridNode(Direction dir) { return mainNode.getNode(); } + public AECableType getCableConnectionType(Direction dir) { return AECableType.SMART; } + + @Override + public TickingRequest getTickingRequest(IGridNode node) { + return new TickingRequest(10, 40, false); + } + + @Override + public TickRateModulation tickingRequest(IGridNode node, int ticksSinceLast) { + if (level == null || level.isClientSide()) return TickRateModulation.IDLE; + IGrid grid = node.getGrid(); + if (grid == null) return TickRateModulation.IDLE; + + IEnergyService energy = grid.getService(IEnergyService.class); + + // 1) 能量槽对外输出:最多 MAX_OUTPUT_PER_TICK AE/t + if (storedEnergy > 0 && energy != null) { + double toOutput = Math.min(storedEnergy, MAX_OUTPUT_PER_TICK * ticksSinceLast); + if (toOutput > 0) { + double rejected = energy.injectPower(toOutput, Actionable.MODULATE); + storedEnergy -= (toOutput - rejected); + if (storedEnergy < 0) storedEnergy = 0; + setChanged(); + } + } + + // 2) 能量槽已满时停止发电(但仍抽取源质以备槽空后立即使用) + if (storedEssentia < MAX_ESSENTIA) { + takeEssentiaFromNeighbors(); + if (storedEssentia < MAX_ESSENTIA) { + pullEssentiaFromNetwork(); + } + } + + // 若能量槽已满(或等于),不消耗源质发电 + if (storedEnergy >= MAX_ENERGY_STORAGE - 0.01) { + // 保持燃烧状态标记,以便 Jade/UI 显示"蓄能中" + if (isActive) return TickRateModulation.SAME; + return TickRateModulation.IDLE; + } + + // 3) 消耗源质燃烧 -> 能量先进槽 + if (burnTicksRemaining > 0) { + double toGenerate = aePerTick * ticksSinceLast; + double space = MAX_ENERGY_STORAGE - storedEnergy; + double accepted = Math.min(toGenerate, space); + if (accepted > 0) { + storedEnergy += accepted; + if (storedEnergy > MAX_ENERGY_STORAGE) storedEnergy = MAX_ENERGY_STORAGE; + setChanged(); + } + burnTicksRemaining -= ticksSinceLast; + if (burnTicksRemaining <= 0) { + isActive = false; + setChanged(); + } else { + return TickRateModulation.SAME; + } + } + + if (burnTicksRemaining <= 0 && storedEssentia > 0) { + if (startBurning()) { + storedEssentia--; + isActive = true; + setChanged(); + return TickRateModulation.URGENT; + } + } + return TickRateModulation.SAME; + } + + private void takeEssentiaFromNeighbors() { + int space = MAX_ESSENTIA - storedEssentia; + if (space <= 0) return; + for (Direction side : Direction.values()) { + BlockPos sourcePos = worldPosition.relative(side); + BlockEntity sourceTile = level.getBlockEntity(sourcePos); + if (!(sourceTile instanceof IEssentiaTransport source)) continue; + Direction sourceSide = side.getOpposite(); + boolean canOut = source.canOutputTo(sourceSide); + Aspect srcType = source.getEssentiaType(sourceSide); + int srcAmt = source.getEssentiaAmount(sourceSide); + if (!canOut) continue; + if (srcType == null) continue; + String srcTag = srcType.getTag(); + if (!srcTag.equals("ignis") && !srcTag.equals("potentia") && !srcTag.equals("energy")) continue; + + if (space <= 0) return; + + int want = Math.min(1, space); + int taken = source.takeEssentia(srcType, want, sourceSide); + if (taken > 0) { + storedEssentia += taken; + currentAspect = srcType; + suctionAspect = srcType; + setChanged(); + return; + } + } + } + + private IEssentiaGrid essentiaGrid; + + private boolean getEssentiaMonitor() { + IGridNode node = mainNode.getNode(); + if (node == null) return false; + IGrid grid = node.getGrid(); + if (grid == null) return false; + essentiaGrid = grid.getService(IEssentiaGrid.class); + return essentiaGrid != null; + } + + private void pullEssentiaFromNetwork() { + if (!getEssentiaMonitor()) return; + int space = MAX_ESSENTIA - storedEssentia; + if (space <= 0) return; + + if (currentAspect != null && isFuelAspect(currentAspect)) { + ResourceLocation id = TCReflection.getAspectId(currentAspect); + if (id != null && essentiaGrid.getEssentiaAmount(id) > 0) { + long extracted = essentiaGrid.extractEssentia(id, 1, false); + if (extracted > 0) { + storedEssentia += (int) extracted; + setChanged(); + return; + } + } + } + + var list = essentiaGrid.getEssentiaList(); + for (var stack : list) { + if (stack.amount() <= 0) continue; + Aspect aspect = Aspect.getAspect(stack.aspectId().getPath()); + if (!isFuelAspect(aspect)) continue; + long extracted = essentiaGrid.extractEssentia(stack.aspectId(), 1, false); + if (extracted > 0) { + storedEssentia += (int) extracted; + currentAspect = aspect; + setChanged(); + return; + } + } + } + + private boolean startBurning() { + if (currentAspect == null) currentAspect = Aspect.FIRE; + + boolean isPotentia = currentAspect != null && (currentAspect == Aspect.ENERGY || currentAspect.getTag().equals("potentia") || currentAspect.getTag().equals("energy")); + int burnTime = isPotentia ? (int)(BASE_BURN_TICKS / 1.6f) : BASE_BURN_TICKS / 2; + double power = isPotentia ? BASE_AE_PER_TICK * 1.6 : BASE_AE_PER_TICK; + + burnTicksRemaining = burnTime; + totalBurnTicks = burnTime; + aePerTick = power; + return true; + } + + @Override public boolean isConnectable(Direction side) { return true; } + @Override public boolean canInputFrom(Direction side) { return true; } + @Override public boolean canOutputTo(Direction side) { return true; } + @Override public void setSuction(Aspect aspect, int amount) { + this.suctionAspect = aspect; + } + @Override public Aspect getSuctionType(Direction side) { + return suctionAspect; + } + @Override public int getSuctionAmount(Direction side) { return 128; } + + private boolean isFuelAspect(Aspect aspect) { + if (aspect == null) return false; + String tag = aspect.getTag(); + return tag.equals("ignis") || tag.equals("potentia") || tag.equals("energy"); + } + + @Override + public int takeEssentia(Aspect aspect, int amount, Direction side) { return 0; } + + @Override + public int addEssentia(Aspect aspect, int amount, Direction side) { + if (storedEssentia >= MAX_ESSENTIA) return 0; + if (!isFuelAspect(aspect)) return 0; + + int space = MAX_ESSENTIA - storedEssentia; + int toAdd = Math.min(amount, space); + storedEssentia += toAdd; + currentAspect = aspect; + if (toAdd > 0) setChanged(); + return toAdd; + } + + @Override + public Aspect getEssentiaType(Direction side) { + if (storedEssentia <= 0) return null; + return currentAspect; + } + + @Override + public int getEssentiaAmount(Direction side) { + return storedEssentia; + } + + @Override public int getMinimumSuction() { return 1; } + @Override public boolean renderExtendedTube() { return false; } + + public void setSuctionType(Aspect aspect) { + if (aspect == Aspect.FIRE || aspect == Aspect.ENERGY) { + suctionAspect = aspect; + setChanged(); + markForUpdate(); + } + } + + public int getStoredEssentia() { return storedEssentia; } + public int getMaxEssentia() { return MAX_ESSENTIA; } + public double getAePerTick() { return aePerTick; } + public int getBurnTicksRemaining() { return burnTicksRemaining; } + public int getTotalBurnTicks() { return totalBurnTicks; } + public float getBurnProgress() { return totalBurnTicks > 0 ? 1f - (float)burnTicksRemaining / totalBurnTicks : 0f; } + + // 能量槽访问器 + public double getStoredEnergy() { return storedEnergy; } + public double getMaxEnergyStorage() { return MAX_ENERGY_STORAGE; } + public double getMaxOutputPerTick() { return MAX_OUTPUT_PER_TICK; } + public float getEnergyFillProgress() { return (float)(storedEnergy / MAX_ENERGY_STORAGE); } + + public void markForUpdate() { + if (level != null) { + setChanged(); + level.sendBlockUpdated(worldPosition, getBlockState(), getBlockState(), 3); + } + } + + @Override + protected void loadAdditional(CompoundTag tag, HolderLookup.Provider reg) { + super.loadAdditional(tag, reg); + if (tag.contains("AttachSide")) attachmentSide = Direction.from3DDataValue(tag.getInt("AttachSide")); + mainNode.loadFromNBT(tag); + mainNode.setIdlePowerUsage(IDLE_POWER); + burnTicksRemaining = tag.getInt("BurnTicks"); + totalBurnTicks = tag.getInt("TotalBurnTicks"); + aePerTick = tag.getDouble("AEPerTick"); + storedEssentia = tag.getInt("StoredEssentia"); + storedEnergy = tag.getDouble("StoredEnergy"); + if (storedEnergy > MAX_ENERGY_STORAGE) storedEnergy = MAX_ENERGY_STORAGE; + if (tag.contains("AspectTag")) currentAspect = Aspect.getAspect(tag.getString("AspectTag")); + if (tag.contains("SuctionTag")) suctionAspect = Aspect.getAspect(tag.getString("SuctionTag")); + } + + @Override + protected void saveAdditional(CompoundTag tag, HolderLookup.Provider reg) { + super.saveAdditional(tag, reg); + tag.putInt("AttachSide", attachmentSide.get3DDataValue()); + mainNode.saveToNBT(tag); + tag.putInt("BurnTicks", burnTicksRemaining); + tag.putInt("TotalBurnTicks", totalBurnTicks); + tag.putDouble("AEPerTick", aePerTick); + tag.putInt("StoredEssentia", storedEssentia); + tag.putDouble("StoredEnergy", storedEnergy); + if (currentAspect != null) tag.putString("AspectTag", currentAspect.getTag()); + if (suctionAspect != null) tag.putString("SuctionTag", suctionAspect.getTag()); + } +} \ No newline at end of file diff --git a/src/main/java/thaumicenergistics/common/tiles/TileInfusionProvider.java b/src/main/java/thaumicenergistics/common/tiles/TileInfusionProvider.java new file mode 100644 index 0000000..db76175 --- /dev/null +++ b/src/main/java/thaumicenergistics/common/tiles/TileInfusionProvider.java @@ -0,0 +1,112 @@ +package thaumicenergistics.common.tiles; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.state.BlockState; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; +import thaumcraft.api.aspects.IAspectSource; +import thaumcraft.common.registry.TCParticles; +import thaumicenergistics.init.ModBlockEntities; +import thaumicenergistics.init.ModItems; + +public class TileInfusionProvider extends TileProviderBase implements IAspectSource { + + public TileInfusionProvider(BlockPos pos, BlockState state) { + super(ModBlockEntities.INFUSION_PROVIDER.get(), pos, state); + } + + @Override + protected ItemStack getItemFromTile() { + return new ItemStack(ModItems.INFUSION_PROVIDER_ITEM.get()); + } + + @Override + protected double getIdlePowerUsage() { + return 5.0; + } + + public void serverTick() { + } + + // ===== IAspectSource ===== + + @Override + public AspectList getAspects() { + // 注魔供应器不存储源质;返回空列表避免调用方(TC 管道 suction)NPE + return new AspectList(); + } + + @Override + public void setAspects(AspectList aspects) { + } + + @Override + public boolean doesContainerAccept(Aspect tag) { + return false; + } + + @Override + public int addToContainer(Aspect tag, int amount) { + return 0; + } + + @Override + public boolean takeFromContainer(Aspect tag, int amount) { + if (!mainNode.isActive()) return false; + long extracted = extractEssentiaFromNetwork(tag, amount, false); + if (extracted >= amount) { + doParticleFX(tag.getColor()); + return true; + } + return false; + } + + @Override + @Deprecated + public boolean takeFromContainer(AspectList ot) { + return false; + } + + @Override + public boolean doesContainerContainAmount(Aspect tag, int amount) { + if (!mainNode.isActive()) return false; + return getAspectAmountInNetwork(tag) >= amount; + } + + @Override + @Deprecated + public boolean doesContainerContain(AspectList ot) { + return false; + } + + @Override + public int containerContains(Aspect tag) { + if (!mainNode.isActive()) return 0; + return (int) Math.min(getAspectAmountInNetwork(tag), Integer.MAX_VALUE); + } + + // ===== 粒子 ===== + + private void doParticleFX(int aspectColor) { + if (!(level instanceof ServerLevel serverLevel)) return; + + float red = (aspectColor >> 16 & 0xFF) / 255.0F; + float green = (aspectColor >> 8 & 0xFF) / 255.0F; + float blue = (aspectColor & 0xFF) / 255.0F; + + double x = worldPosition.getX() + 0.5; + double y = worldPosition.getY() + 0.5; + double z = worldPosition.getZ() + 0.5; + + for (int i = 0; i < 5; i++) { + serverLevel.sendParticles( + TCParticles.BLOCK_RUNE.get(), + x + level.random.nextFloat() * 0.6 - 0.3, + y + level.random.nextFloat() * 0.4 - 0.1, + z + level.random.nextFloat() * 0.6 - 0.3, + 1, 0, 0, 0, 0.05); + } + } +} \ No newline at end of file diff --git a/src/main/java/thaumicenergistics/common/tiles/TileKnowledgeInscriber.java b/src/main/java/thaumicenergistics/common/tiles/TileKnowledgeInscriber.java new file mode 100644 index 0000000..056754d --- /dev/null +++ b/src/main/java/thaumicenergistics/common/tiles/TileKnowledgeInscriber.java @@ -0,0 +1,80 @@ +package thaumicenergistics.common.tiles; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.Containers; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.state.BlockState; +import net.neoforged.neoforge.items.ItemStackHandler; +import thaumicenergistics.init.ModBlockEntities; +import thaumicenergistics.init.ModItems; + +public class TileKnowledgeInscriber extends ThETileBase { + public static final int KCORE_SLOT = 0; + private static final String NBTKEY_KCORE = "kcore"; + + public final ItemStackHandler inventory = new ItemStackHandler(1) { + @Override + public boolean isItemValid(int slot, ItemStack stack) { + return stack.is(ModItems.KNOWLEDGE_CORE.get()); + } + + @Override + protected void onContentsChanged(int slot) { + setChanged(); + } + }; + + public TileKnowledgeInscriber(BlockPos pos, BlockState state) { + super(ModBlockEntities.KNOWLEDGE_INSCRIBER.get(), pos, state); + } + + public boolean hasKCore() { + return !inventory.getStackInSlot(KCORE_SLOT).isEmpty(); + } + + public ItemStack getKCore() { + return inventory.getStackInSlot(KCORE_SLOT); + } + + @Override + public void onBreakBlock() { + super.onBreakBlock(); + if (level != null && !level.isClientSide) { + ItemStack stack = inventory.getStackInSlot(KCORE_SLOT); + if (!stack.isEmpty()) { + Containers.dropItemStack(level, worldPosition.getX(), worldPosition.getY(), worldPosition.getZ(), stack); + } + } + } + + @Override + protected void loadAdditional(CompoundTag tag, HolderLookup.Provider reg) { + super.loadAdditional(tag, reg); + if (tag.contains(NBTKEY_KCORE)) { + inventory.deserializeNBT(reg, tag.getCompound(NBTKEY_KCORE)); + } + } + + @Override + protected void saveAdditional(CompoundTag tag, HolderLookup.Provider reg) { + super.saveAdditional(tag, reg); + tag.put(NBTKEY_KCORE, inventory.serializeNBT(reg)); + } + + @Override + public CompoundTag getUpdateTag(HolderLookup.Provider reg) { + CompoundTag tag = super.getUpdateTag(reg); + tag.put(NBTKEY_KCORE, inventory.serializeNBT(reg)); + return tag; + } + + @Override + public void handleUpdateTag(CompoundTag tag, HolderLookup.Provider reg) { + super.handleUpdateTag(tag, reg); + if (tag.contains(NBTKEY_KCORE)) { + inventory.deserializeNBT(reg, tag.getCompound(NBTKEY_KCORE)); + } + } +} diff --git a/src/main/java/thaumicenergistics/common/tiles/TileProviderBase.java b/src/main/java/thaumicenergistics/common/tiles/TileProviderBase.java new file mode 100644 index 0000000..7b820ae --- /dev/null +++ b/src/main/java/thaumicenergistics/common/tiles/TileProviderBase.java @@ -0,0 +1,183 @@ +package thaumicenergistics.common.tiles; + +import appeng.api.networking.GridFlags; +import appeng.api.networking.GridHelper; +import appeng.api.networking.IGrid; +import appeng.api.networking.IGridNode; +import appeng.api.networking.IGridNodeListener; +import appeng.api.networking.IInWorldGridNodeHost; +import appeng.api.networking.IManagedGridNode; +import appeng.api.util.AECableType; +import appeng.api.util.AEColor; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import thaumcraft.api.aspects.Aspect; +import thaumicenergistics.common.integration.tc.TCReflection; +import org.jetbrains.annotations.Nullable; + +import thaumicenergistics.api.grid.IEssentiaGrid; +import java.util.EnumSet; +import java.util.Set; + +public abstract class TileProviderBase extends ThETileBase implements IInWorldGridNodeHost { + + private static final String NBT_ATTACH_SIDE = "AttachSide"; + private static final String NBT_COLOR = "TEColor"; + private static final String NBT_COLOR_FORCED = "ColorForced"; + + protected final IManagedGridNode mainNode; + protected Direction attachmentSide = Direction.NORTH; + protected AEColor providerColor = AEColor.TRANSPARENT; + protected boolean isColorForced; + protected IEssentiaGrid essentiaGrid; + + private final IGridNodeListener nodeListener = new IGridNodeListener<>() { + @Override + public void onSaveChanges(TileProviderBase owner, IGridNode node) { + owner.setChanged(); + } + + @Override + public void onStateChanged(TileProviderBase owner, IGridNode node, State state) { + if (state == State.POWER) { + owner.onPowerChange(owner.isActive()); + } + owner.markForUpdate(); + } + }; + + public TileProviderBase(BlockEntityType type, BlockPos pos, BlockState state) { + super(type, pos, state); + this.mainNode = GridHelper.createManagedNode(this, nodeListener) + .setVisualRepresentation(getItemFromTile()) + .setInWorldNode(true) + .setTagName("proxy") + .setFlags(GridFlags.REQUIRE_CHANNEL) + .setExposedOnSides(EnumSet.allOf(Direction.class)); + } + + protected abstract ItemStack getItemFromTile(); + protected abstract double getIdlePowerUsage(); + + @Override + public void onLoad() { + super.onLoad(); + if (level != null && !level.isClientSide()) { + mainNode.create(level, getBlockPos()); + } + } + + @Override + public void setRemoved() { + super.setRemoved(); + if (mainNode != null) { + mainNode.destroy(); + } + } + + @Override + public void onChunkUnloaded() { + super.onChunkUnloaded(); + if (mainNode != null) { + mainNode.destroy(); + } + } + + @Override + protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.loadAdditional(tag, registries); + if (tag.contains(NBT_ATTACH_SIDE)) { + attachmentSide = Direction.from3DDataValue(tag.getInt(NBT_ATTACH_SIDE)); + } + if (tag.contains(NBT_COLOR)) { + providerColor = AEColor.values()[tag.getInt(NBT_COLOR)]; + mainNode.setGridColor(providerColor); + } + isColorForced = tag.getBoolean(NBT_COLOR_FORCED); + mainNode.loadFromNBT(tag); + mainNode.setIdlePowerUsage(getIdlePowerUsage()); + } + + @Override + protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.saveAdditional(tag, registries); + tag.putInt(NBT_ATTACH_SIDE, attachmentSide.get3DDataValue()); + tag.putInt(NBT_COLOR, providerColor.ordinal()); + tag.putBoolean(NBT_COLOR_FORCED, isColorForced); + mainNode.saveToNBT(tag); + } + + public void markForUpdate() { + if (level != null) { + setChanged(); + level.sendBlockUpdated(worldPosition, getBlockState(), getBlockState(), 3); + } + } + + // ===== IInWorldGridNodeHost ===== + + @Override + @Nullable + public IGridNode getGridNode(Direction dir) { + var node = mainNode.getNode(); + return node; + } + + public AECableType getCableConnectionType(Direction dir) { + return AECableType.SMART; + } + + public Set getGridConnectableSides() { + return EnumSet.allOf(Direction.class); + } + + public IManagedGridNode getMainNode() { + return mainNode; + } + + public boolean isActive() { + return mainNode.isActive(); + } + + protected void onPowerChange(boolean isPowered) { + } + + // ===== Essentia 网格访问 ===== + + protected boolean getEssentiaMonitor() { + IGridNode node = mainNode.getNode(); + if (node == null) return false; + IGrid grid = node.getGrid(); + if (grid == null) return false; + essentiaGrid = grid.getService(IEssentiaGrid.class); + return essentiaGrid != null; + } + + protected long getAspectAmountInNetwork(Aspect aspect) { + if (!getEssentiaMonitor()) return 0; + ResourceLocation id = TCReflection.getAspectId(aspect); + if (id == null) return 0; + long amount = essentiaGrid.getEssentiaAmount(id); + return amount; + } + + protected long extractEssentiaFromNetwork(Aspect aspect, long amount, boolean simulate) { + if (!getEssentiaMonitor()) return 0; + ResourceLocation id = TCReflection.getAspectId(aspect); + if (id == null) return 0; + return essentiaGrid.extractEssentia(id, amount, simulate); + } + + protected long injectEssentiaToNetwork(Aspect aspect, long amount, boolean simulate) { + if (!getEssentiaMonitor()) return 0; + ResourceLocation id = TCReflection.getAspectId(aspect); + if (id == null) return 0; + return essentiaGrid.injectEssentia(id, amount, simulate); + } +} \ No newline at end of file diff --git a/src/main/java/thaumicenergistics/config/ThEConfig.java b/src/main/java/thaumicenergistics/config/ThEConfig.java new file mode 100644 index 0000000..35fb395 --- /dev/null +++ b/src/main/java/thaumicenergistics/config/ThEConfig.java @@ -0,0 +1,10 @@ +package thaumicenergistics.config; +import java.util.Set; +public final class ThEConfig { + private ThEConfig() {} + public static final double EVC_POWER_PER_TICK = 5.0; + public static final int CELL_1K = 1024, CELL_4K = 4096, CELL_16K = 16384, CELL_64K = 65536; + public static final int CELL_MAX_TYPES = 12; + private static final Set ENABLED = Set.of("cells","io_buses","monitoring","arcane_crafting_terminal","essentia_provider","infusion_provider","vibration_chamber","vis_interface","golem_backpack"); + public static boolean isFeatureEnabled(String n) { return ENABLED.contains(n); } +} diff --git a/src/main/java/thaumicenergistics/init/ModBlockEntities.java b/src/main/java/thaumicenergistics/init/ModBlockEntities.java new file mode 100644 index 0000000..cfe6551 --- /dev/null +++ b/src/main/java/thaumicenergistics/init/ModBlockEntities.java @@ -0,0 +1,52 @@ +package thaumicenergistics.init; + +import net.minecraft.core.registries.Registries; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.neoforged.neoforge.registries.DeferredRegister; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.common.tiles.*; +import thaumicenergistics.common.integration.tc.VisProviderProxy; +import java.util.function.Supplier; + +public final class ModBlockEntities { + private ModBlockEntities() {} + public static final DeferredRegister> REGISTRY = + DeferredRegister.create(Registries.BLOCK_ENTITY_TYPE, ThaumicEnergistics.MODID); + + public static final Supplier> ESSENTIA_PROVIDER = + REGISTRY.register("essentia_provider", + () -> BlockEntityType.Builder.of(TileEssentiaProvider::new, ModBlocks.ESSENTIA_PROVIDER.get()).build(null)); + + public static final Supplier> INFUSION_PROVIDER = + REGISTRY.register("infusion_provider", + () -> BlockEntityType.Builder.of(TileInfusionProvider::new, ModBlocks.INFUSION_PROVIDER.get()).build(null)); + + public static final Supplier> ARCANE_ASSEMBLER = + REGISTRY.register("arcane_assembler", + () -> BlockEntityType.Builder.of(TileArcaneAssembler::new, ModBlocks.ARCANE_ASSEMBLER.get()).build(null)); + + public static final Supplier> ESSENTIA_VIBRATION_CHAMBER = + REGISTRY.register("essentia_vibration_chamber", + () -> BlockEntityType.Builder.of(TileEssentiaVibrationChamber::new, ModBlocks.ESSENTIA_VIBRATION_CHAMBER.get()).build(null)); + + public static final Supplier> KNOWLEDGE_INSCRIBER = + REGISTRY.register("knowledge_inscriber", + () -> BlockEntityType.Builder.of(TileKnowledgeInscriber::new, ModBlocks.KNOWLEDGE_INSCRIBER.get()).build(null)); + + public static final Supplier> DISTILLATION_ENCODER = + REGISTRY.register("distillation_encoder", + () -> BlockEntityType.Builder.of(TileDistillationPatternEncoder::new, ModBlocks.DISTILLATION_ENCODER.get()).build(null)); + + public static final Supplier> ESSENTIA_CELL_WORKBENCH = + REGISTRY.register("essentia_cell_workbench", + () -> BlockEntityType.Builder.of(TileEssentiaCellWorkbench::new, ModBlocks.ESSENTIA_CELL_WORKBENCH.get()).build(null)); + + /** + * 虚拟的 Thaumcraft vis 源,供 vis 接口的提供端使用。 + * 不作为真实方块放置;由 {@link thaumicenergistics.common.parts.VisInterfacePart} + * 在运行时构造并注入到 VisNetHandler。 + */ + public static final Supplier> VIS_PROVIDER_PROXY = + REGISTRY.register("vis_provider_proxy", + () -> BlockEntityType.Builder.of(VisProviderProxy::new).build(null)); +} diff --git a/src/main/java/thaumicenergistics/init/ModBlocks.java b/src/main/java/thaumicenergistics/init/ModBlocks.java new file mode 100644 index 0000000..ed84eb3 --- /dev/null +++ b/src/main/java/thaumicenergistics/init/ModBlocks.java @@ -0,0 +1,103 @@ +package thaumicenergistics.init; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.MenuProvider; +import net.minecraft.world.SimpleMenuProvider; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.MapColor; +import net.neoforged.neoforge.registries.DeferredBlock; +import net.neoforged.neoforge.registries.DeferredRegister; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.common.blocks.OrientableEntityBlock; +import thaumicenergistics.common.blocks.ThEBaseEntityBlock; +import thaumicenergistics.common.tiles.*; +import net.minecraft.network.chat.Component; + +public final class ModBlocks { + private ModBlocks() {} + public static final DeferredRegister.Blocks REGISTRY = DeferredRegister.createBlocks(ThaumicEnergistics.MODID); + private static final BlockBehaviour.Properties P = BlockBehaviour.Properties.of().mapColor(MapColor.STONE).strength(2f).sound(SoundType.STONE); + + public static final DeferredBlock ESSENTIA_PROVIDER = REGISTRY.register("essentia_provider", () -> new ThEBaseEntityBlock(P) { public net.minecraft.world.level.block.entity.BlockEntity newBlockEntity(BlockPos pos, BlockState st) { return new TileEssentiaProvider(pos, st); } }); + public static final DeferredBlock INFUSION_PROVIDER = REGISTRY.register("infusion_provider", () -> new ThEBaseEntityBlock(P) { public net.minecraft.world.level.block.entity.BlockEntity newBlockEntity(BlockPos pos, BlockState st) { return new TileInfusionProvider(pos, st); } }); + public static final DeferredBlock ARCANE_ASSEMBLER = REGISTRY.register("arcane_assembler", () -> new ThEBaseEntityBlock(P) { + public net.minecraft.world.level.block.entity.BlockEntity newBlockEntity(BlockPos pos, BlockState st) { return new TileArcaneAssembler(pos, st); } + @Override + protected net.minecraft.world.ItemInteractionResult useItemOn(net.minecraft.world.item.ItemStack stack, BlockState state, net.minecraft.world.level.Level level, BlockPos pos, net.minecraft.world.entity.player.Player player, net.minecraft.world.InteractionHand hand, net.minecraft.world.phys.BlockHitResult hit) { + // 手持 AE2 内存卡:交给装配器处理(读 P2P 频率设 vis 源 / 清空),不打开 GUI。 + // 1.21 方块 useItemOn 先于物品 useOn,返回 sidedSuccess 消费交互(也阻止内存卡自身 shift 清空)。 + if (stack.getItem() instanceof appeng.api.implementations.items.IMemoryCard memoryCard + && level.getBlockEntity(pos) instanceof TileArcaneAssembler tile) { + if (!level.isClientSide) { + tile.onMemoryCardActivate(player, memoryCard, stack); + } + return net.minecraft.world.ItemInteractionResult.sidedSuccess(level.isClientSide()); + } + if (!level.isClientSide) { + player.openMenu(state.getMenuProvider(level, pos)); + } + return net.minecraft.world.ItemInteractionResult.SUCCESS; + } + @Override + protected net.minecraft.world.MenuProvider getMenuProvider(BlockState state, net.minecraft.world.level.Level level, BlockPos pos) { + TileArcaneAssembler tile = (TileArcaneAssembler) level.getBlockEntity(pos); + return new SimpleMenuProvider( + (id, inv, p) -> new thaumicenergistics.common.container.ContainerArcaneAssembler(id, inv, tile), + Component.translatable("block.thaumicenergistics.arcane_assembler")); + } + }); + public static final DeferredBlock ESSENTIA_VIBRATION_CHAMBER = REGISTRY.register("essentia_vibration_chamber", () -> new OrientableEntityBlock(P) { public net.minecraft.world.level.block.entity.BlockEntity newBlockEntity(BlockPos pos, BlockState st) { return new TileEssentiaVibrationChamber(pos, st); } }); + public static final DeferredBlock KNOWLEDGE_INSCRIBER = REGISTRY.register("knowledge_inscriber", () -> new ThEBaseEntityBlock(P) { + public net.minecraft.world.level.block.entity.BlockEntity newBlockEntity(BlockPos pos, BlockState st) { return new TileKnowledgeInscriber(pos, st); } + @Override + protected net.minecraft.world.ItemInteractionResult useItemOn(net.minecraft.world.item.ItemStack stack, BlockState state, net.minecraft.world.level.Level level, BlockPos pos, net.minecraft.world.entity.player.Player player, net.minecraft.world.InteractionHand hand, net.minecraft.world.phys.BlockHitResult hit) { + if (!level.isClientSide) player.openMenu(state.getMenuProvider(level, pos)); + return net.minecraft.world.ItemInteractionResult.SUCCESS; + } + @Override + protected net.minecraft.world.MenuProvider getMenuProvider(BlockState state, net.minecraft.world.level.Level level, BlockPos pos) { + TileKnowledgeInscriber tile = (TileKnowledgeInscriber) level.getBlockEntity(pos); + return new SimpleMenuProvider( + (id, inv, p) -> new thaumicenergistics.common.container.ContainerKnowledgeInscriber(id, inv, tile), + Component.translatable("block.thaumicenergistics.knowledge_inscriber")); + } + }); + public static final DeferredBlock DISTILLATION_ENCODER = REGISTRY.register("distillation_encoder", () -> new ThEBaseEntityBlock(P) { + public net.minecraft.world.level.block.entity.BlockEntity newBlockEntity(BlockPos pos, BlockState st) { return new TileDistillationPatternEncoder(pos, st); } + @Override + protected net.minecraft.world.ItemInteractionResult useItemOn(net.minecraft.world.item.ItemStack stack, BlockState state, net.minecraft.world.level.Level level, BlockPos pos, net.minecraft.world.entity.player.Player player, net.minecraft.world.InteractionHand hand, net.minecraft.world.phys.BlockHitResult hit) { + if (!level.isClientSide) player.openMenu(state.getMenuProvider(level, pos)); + return net.minecraft.world.ItemInteractionResult.SUCCESS; + } + @Override + protected net.minecraft.world.MenuProvider getMenuProvider(BlockState state, net.minecraft.world.level.Level level, BlockPos pos) { + TileDistillationPatternEncoder tile = (TileDistillationPatternEncoder) level.getBlockEntity(pos); + return new SimpleMenuProvider( + (id, inv, p) -> new thaumicenergistics.common.container.ContainerDistillationPatternEncoder(id, inv, tile), + Component.translatable("block.thaumicenergistics.distillation_encoder")); + } + }); + public static final DeferredBlock ESSENTIA_CELL_WORKBENCH = REGISTRY.register("essentia_cell_workbench", () -> new ThEBaseEntityBlock(P) { + @Override + public net.minecraft.world.level.block.entity.BlockEntity newBlockEntity(BlockPos pos, BlockState state) { + return new TileEssentiaCellWorkbench(pos, state); + } + @Override + protected net.minecraft.world.ItemInteractionResult useItemOn(net.minecraft.world.item.ItemStack stack, BlockState state, net.minecraft.world.level.Level level, BlockPos pos, net.minecraft.world.entity.player.Player player, net.minecraft.world.InteractionHand hand, net.minecraft.world.phys.BlockHitResult hit) { + if (!level.isClientSide) player.openMenu(state.getMenuProvider(level, pos)); + return net.minecraft.world.ItemInteractionResult.SUCCESS; + } + @Override + protected net.minecraft.world.MenuProvider getMenuProvider(BlockState state, net.minecraft.world.level.Level level, BlockPos pos) { + net.minecraft.world.level.block.entity.BlockEntity be = level.getBlockEntity(pos); + if (be instanceof TileEssentiaCellWorkbench workbench) { + return new SimpleMenuProvider((id, inv, p) -> new thaumicenergistics.common.container.ContainerEssentiaCellWorkbench(id, inv, workbench), + Component.translatable("block.thaumicenergistics.essentia_cell_workbench")); + } + return null; + } + }); +} diff --git a/src/main/java/thaumicenergistics/init/ModCreativeTab.java b/src/main/java/thaumicenergistics/init/ModCreativeTab.java new file mode 100644 index 0000000..b081df7 --- /dev/null +++ b/src/main/java/thaumicenergistics/init/ModCreativeTab.java @@ -0,0 +1,46 @@ +package thaumicenergistics.init; + +import net.minecraft.core.registries.Registries; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.ItemStack; +import net.neoforged.neoforge.registries.DeferredRegister; +import thaumcraft.api.aspects.Aspect; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.common.integration.appeng.AEssentiaKey; +import thaumicenergistics.common.integration.tc.TCReflection; +import appeng.api.stacks.GenericStack; + +import java.util.function.Supplier; + +public final class ModCreativeTab { + private ModCreativeTab() {} + public static final DeferredRegister REGISTRY = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, ThaumicEnergistics.MODID); + public static final Supplier TAB = REGISTRY.register("tab", () -> CreativeModeTab.builder() + .title(Component.translatable("itemGroup.thaumicenergistics")) + .icon(() -> new ItemStack(ModItems.ESSENTIA_CELL_64K.get())) + .displayItems((params, output) -> { + output.accept(ModItems.ESSENTIA_CELL_1K.get()); output.accept(ModItems.ESSENTIA_CELL_4K.get()); + output.accept(ModItems.ESSENTIA_CELL_16K.get()); output.accept(ModItems.ESSENTIA_CELL_64K.get()); + output.accept(ModItems.ESSENTIA_CELL_CREATIVE.get()); + output.accept(ModItems.STORAGE_COMPONENT_1K.get()); output.accept(ModItems.STORAGE_COMPONENT_4K.get()); + output.accept(ModItems.STORAGE_COMPONENT_16K.get()); output.accept(ModItems.STORAGE_COMPONENT_64K.get()); + output.accept(ModItems.STORAGE_CASING.get()); + output.accept(ModItems.COALESCENCE_CORE.get()); output.accept(ModItems.DIFFUSION_CORE.get()); + output.accept(ModItems.KNOWLEDGE_CORE.get()); + output.accept(ModItems.FOCUS_AEWRENCH.get()); output.accept(ModItems.GOLEM_WIFI_BACKPACK.get()); + output.accept(ModItems.WIRELESS_ESSENTIA_TERMINAL.get()); + output.accept(ModItems.ESSENTIA_IMPORT_BUS.get()); output.accept(ModItems.ESSENTIA_EXPORT_BUS.get()); + output.accept(ModItems.ESSENTIA_STORAGE_BUS.get()); output.accept(ModItems.ESSENTIA_TERMINAL_ITEM.get()); + output.accept(ModItems.ARCANE_CRAFTING_TERMINAL_ITEM.get()); output.accept(ModItems.ESSENTIA_LEVEL_EMITTER.get()); + output.accept(ModItems.VIS_INTERFACE.get()); + output.accept(ModItems.ESSENTIA_PROVIDER_ITEM.get()); output.accept(ModItems.INFUSION_PROVIDER_ITEM.get()); + output.accept(ModItems.ARCANE_ASSEMBLER_ITEM.get()); output.accept(ModItems.ESSENTIA_VIBRATION_CHAMBER_ITEM.get()); + output.accept(ModItems.KNOWLEDGE_INSCRIBER_ITEM.get()); output.accept(ModItems.ESSENTIA_CELL_WORKBENCH_ITEM.get()); + output.accept(ModItems.DISTILLATION_ENCODER_ITEM.get()); + + // 源质虚拟物品不再在创造标签页中注册(避免玩家拿到物品栏) + // 它们通过 JEI 插件注册,仅作为 ghost ingredient 可拖拽到 AE 筛选槽 + // 如果没有 JEI,玩家可以通过拖拽源质罐子到筛选槽来设置筛选 + }).build()); +} diff --git a/src/main/java/thaumicenergistics/init/ModItems.java b/src/main/java/thaumicenergistics/init/ModItems.java new file mode 100644 index 0000000..6a3844c --- /dev/null +++ b/src/main/java/thaumicenergistics/init/ModItems.java @@ -0,0 +1,81 @@ +package thaumicenergistics.init; + +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.Item; +import net.neoforged.neoforge.registries.DeferredItem; +import net.neoforged.neoforge.registries.DeferredRegister; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.common.items.*; + +public final class ModItems { + private ModItems() {} + public static final DeferredRegister.Items REGISTRY = DeferredRegister.createItems(ThaumicEnergistics.MODID); + + public static final DeferredItem ESSENTIA_CELL_1K = REGISTRY.registerItem("essentia_cell_1k", ItemEssentiaCell::create1k); + public static final DeferredItem ESSENTIA_CELL_4K = REGISTRY.registerItem("essentia_cell_4k", ItemEssentiaCell::create4k); + public static final DeferredItem ESSENTIA_CELL_16K = REGISTRY.registerItem("essentia_cell_16k", ItemEssentiaCell::create16k); + public static final DeferredItem ESSENTIA_CELL_64K = REGISTRY.registerItem("essentia_cell_64k", ItemEssentiaCell::create64k); + public static final DeferredItem ESSENTIA_CELL_CREATIVE = REGISTRY.registerItem("essentia_cell_creative", ItemEssentiaCell::createCreative); + public static final DeferredItem STORAGE_COMPONENT_1K = REGISTRY.registerSimpleItem("storage_component_1k"); + public static final DeferredItem STORAGE_COMPONENT_4K = REGISTRY.registerSimpleItem("storage_component_4k"); + public static final DeferredItem STORAGE_COMPONENT_16K = REGISTRY.registerSimpleItem("storage_component_16k"); + public static final DeferredItem STORAGE_COMPONENT_64K = REGISTRY.registerSimpleItem("storage_component_64k"); + public static final DeferredItem STORAGE_CASING = REGISTRY.registerSimpleItem("storage_casing"); + public static final DeferredItem COALESCENCE_CORE = REGISTRY.registerSimpleItem("coalescence_core"); + public static final DeferredItem DIFFUSION_CORE = REGISTRY.registerSimpleItem("diffusion_core"); + public static final DeferredItem KNOWLEDGE_CORE = REGISTRY.register("knowledge_core", + () -> new Item(new Item.Properties().stacksTo(1))); + public static final DeferredItem FOCUS_AEWRENCH = REGISTRY.register("focus_aewrench", + () -> new ItemFocusAEWrench()); + public static final DeferredItem WIRELESS_ESSENTIA_TERMINAL = REGISTRY.register( + "wireless_essentia_terminal", + () -> new WirelessEssentiaTerminalItem( + appeng.core.AEConfig.instance().getWirelessTerminalBattery(), + new Item.Properties().stacksTo(1))); + public static final DeferredItem GOLEM_WIFI_BACKPACK = REGISTRY.register("golem_wifi_backpack", + ItemGolemWirelessBackpack::new); + + public static final DeferredItem ESSENTIA_IMPORT_BUS = + REGISTRY.register( + "essentia_import_bus", + () -> new PartItemEssentiaImportBus(new Item.Properties().stacksTo(64)) + ); + + public static final DeferredItem ESSENTIA_EXPORT_BUS = + REGISTRY.register( + "essentia_export_bus", + () -> new PartItemEssentiaExportBus(new Item.Properties().stacksTo(64)) + ); + + public static final DeferredItem ESSENTIA_STORAGE_BUS = + REGISTRY.register( + "essentia_storage_bus", + () -> new PartItemEssentiaStorageBus(new Item.Properties().stacksTo(64)) + ); + + public static final DeferredItem ESSENTIA_TERMINAL_ITEM = + REGISTRY.register( + "essentia_terminal", + () -> new PartItemEssentiaTerminal(new Item.Properties().stacksTo(64)) + ); + + public static final DeferredItem ARCANE_CRAFTING_TERMINAL_ITEM = + REGISTRY.register("arcane_crafting_terminal", + () -> new PartItemArcaneCraftingTerminal(new Item.Properties().stacksTo(64))); + + public static final DeferredItem ESSENTIA_LEVEL_EMITTER = + REGISTRY.register("essentia_level_emitter", + () -> new PartItemEssentiaLevelEmitter(new Item.Properties().stacksTo(64))); + + public static final DeferredItem VIS_INTERFACE = + REGISTRY.register("vis_interface", + () -> new PartItemVisInterface(new Item.Properties().stacksTo(64))); + + public static final DeferredItem ESSENTIA_PROVIDER_ITEM = REGISTRY.registerSimpleBlockItem(ModBlocks.ESSENTIA_PROVIDER); + public static final DeferredItem INFUSION_PROVIDER_ITEM = REGISTRY.registerSimpleBlockItem(ModBlocks.INFUSION_PROVIDER); + public static final DeferredItem ARCANE_ASSEMBLER_ITEM = REGISTRY.registerSimpleBlockItem(ModBlocks.ARCANE_ASSEMBLER); + public static final DeferredItem ESSENTIA_VIBRATION_CHAMBER_ITEM = REGISTRY.registerSimpleBlockItem(ModBlocks.ESSENTIA_VIBRATION_CHAMBER); + public static final DeferredItem KNOWLEDGE_INSCRIBER_ITEM = REGISTRY.registerSimpleBlockItem(ModBlocks.KNOWLEDGE_INSCRIBER); + public static final DeferredItem ESSENTIA_CELL_WORKBENCH_ITEM = REGISTRY.registerSimpleBlockItem(ModBlocks.ESSENTIA_CELL_WORKBENCH); + public static final DeferredItem DISTILLATION_ENCODER_ITEM = REGISTRY.registerSimpleBlockItem(ModBlocks.DISTILLATION_ENCODER); +} \ No newline at end of file diff --git a/src/main/java/thaumicenergistics/init/ModMenuTypes.java b/src/main/java/thaumicenergistics/init/ModMenuTypes.java new file mode 100644 index 0000000..7f12ac1 --- /dev/null +++ b/src/main/java/thaumicenergistics/init/ModMenuTypes.java @@ -0,0 +1,65 @@ +package thaumicenergistics.init; + +import appeng.api.storage.ITerminalHost; +import appeng.menu.implementations.MenuTypeBuilder; +import net.minecraft.core.registries.Registries; +import net.minecraft.network.chat.Component; +import net.minecraft.world.inventory.MenuType; +import net.neoforged.neoforge.common.extensions.IMenuTypeExtension; +import net.neoforged.neoforge.registries.DeferredRegister; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.common.container.*; +import thaumicenergistics.common.parts.EssentiaExportBusPart; +import thaumicenergistics.common.parts.EssentiaImportBusPart; +import thaumicenergistics.common.parts.EssentiaLevelEmitterPart; +import thaumicenergistics.common.parts.EssentiaStorageBusPart; + +import java.util.function.Supplier; + +public final class ModMenuTypes { + private ModMenuTypes() {} + public static final DeferredRegister> REGISTRY = + DeferredRegister.create(Registries.MENU, ThaumicEnergistics.MODID); + + public static final Supplier> ESSENTIA_CELL_WORKBENCH = + REGISTRY.register("essentia_cell_workbench", () -> IMenuTypeExtension.create(ContainerEssentiaCellWorkbench::new)); + public static final Supplier> EVC = + REGISTRY.register("essentia_vibration_chamber", () -> IMenuTypeExtension.create(ContainerEssentiaVibrationChamber::new)); + public static final Supplier> ARCANE_ASSEMBLER = + REGISTRY.register("arcane_assembler", () -> IMenuTypeExtension.create(ContainerArcaneAssembler::new)); + public static final Supplier> ESSENTIA_TERMINAL = + REGISTRY.register("essentia_terminal", () -> IMenuTypeExtension.create(ContainerEssentiaCellTerminal::new)); + public static final Supplier> KNOWLEDGE_INSCRIBER = + REGISTRY.register("knowledge_inscriber", () -> IMenuTypeExtension.create(ContainerKnowledgeInscriber::new)); + public static final Supplier> DISTILLATION_ENCODER = + REGISTRY.register("distillation_encoder", () -> IMenuTypeExtension.create(ContainerDistillationPatternEncoder::new)); + + public static final Supplier> ESSENTIA_IMPORT_BUS = + REGISTRY.register("essentia_import_bus", () -> + MenuTypeBuilder.create(ContainerEssentiaImportBus::new, EssentiaImportBusPart.class) + .withMenuTitle(host -> host.getName() != null ? host.getName() : Component.empty()) + .build("essentia_import_bus")); + + public static final Supplier> ESSENTIA_EXPORT_BUS = + REGISTRY.register("essentia_export_bus", () -> + MenuTypeBuilder.create(ContainerEssentiaExportBus::new, EssentiaExportBusPart.class) + .withMenuTitle(host -> host.getName() != null ? host.getName() : Component.empty()) + .build("essentia_export_bus")); + + public static final Supplier> ESSENTIA_STORAGE_BUS = + REGISTRY.register("essentia_storage_bus", () -> + MenuTypeBuilder.create(ContainerEssentiaStorageBus::new, EssentiaStorageBusPart.class) + .withMenuTitle(host -> host.getName() != null ? host.getName() : Component.empty()) + .build("essentia_storage_bus")); + + public static final Supplier> ARCANE_CRAFTING_TERMINAL = + REGISTRY.register("arcane_crafting_terminal", () -> + MenuTypeBuilder.create(ContainerArcaneCraftingTerminal::new, ITerminalHost.class) + .build("arcane_crafting_terminal")); + + public static final Supplier> ESSENTIA_LEVEL_EMITTER = + REGISTRY.register("essentia_level_emitter", () -> + MenuTypeBuilder.create(ContainerEssentiaLevelEmitter::new, EssentiaLevelEmitterPart.class) + .withMenuTitle(host -> host.getName() != null ? host.getName() : Component.empty()) + .build("essentia_level_emitter")); +} diff --git a/src/main/java/thaumicenergistics/integration/jei/Ae2JeiCompat.java b/src/main/java/thaumicenergistics/integration/jei/Ae2JeiCompat.java new file mode 100644 index 0000000..e333f4c --- /dev/null +++ b/src/main/java/thaumicenergistics/integration/jei/Ae2JeiCompat.java @@ -0,0 +1,20 @@ +package thaumicenergistics.integration.jei; + +import tamaized.ae2jeiintegration.api.integrations.jei.IngredientConverters; + +/** + * AE2-JEI-Integration 兼容注册的隔离类。 + * 仅被 {@link ThEJeiPlugin} 通过反射调用({@code Class.forName} + {@code getMethod("register").invoke}), + * 本类(及其引用的 ae2jei 库类)只在库存在时才被类加载器解析。 + * 因此只装 JEI 时不会因引用缺失而 NoClassDefFoundError,双装时拖拽转换完整生效。 + */ +public final class Ae2JeiCompat { + + private Ae2JeiCompat() { + } + + /** 注册源质转换器到 AE2-JEI-Integration(支持从 JEI 拖拽源质到 AE2 筛选槽)。 */ + public static void register() { + IngredientConverters.register(new EssentiaIngredientConverter()); + } +} diff --git a/src/main/java/thaumicenergistics/integration/jei/ArcaneCraftingTransferInfo.java b/src/main/java/thaumicenergistics/integration/jei/ArcaneCraftingTransferInfo.java new file mode 100644 index 0000000..adbde55 --- /dev/null +++ b/src/main/java/thaumicenergistics/integration/jei/ArcaneCraftingTransferInfo.java @@ -0,0 +1,55 @@ +package thaumicenergistics.integration.jei; + +import java.util.List; +import java.util.Optional; + +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.crafting.CraftingRecipe; +import net.minecraft.world.item.crafting.RecipeHolder; + +import mezz.jei.api.constants.RecipeTypes; +import mezz.jei.api.recipe.transfer.IRecipeTransferInfo; + +import appeng.menu.SlotSemantics; +import thaumicenergistics.common.container.ContainerArcaneCraftingTerminal; +import thaumicenergistics.init.ModMenuTypes; + +/** + * 为奥术合成终端提供 JEI 配方转移的槽位映射。 + * 让 JEI 知道哪些槽是合成格(CRAFTING_GRID)、哪些是玩家背包。 + * 实际转移走网络由 ThEUseCraftingRecipeTransfer 处理。 + */ +public class ArcaneCraftingTransferInfo + implements IRecipeTransferInfo> { + + @Override + public Class getContainerClass() { + return ContainerArcaneCraftingTerminal.class; + } + + @Override + public Optional> getMenuType() { + return Optional.of(ModMenuTypes.ARCANE_CRAFTING_TERMINAL.get()); + } + + @Override + public mezz.jei.api.recipe.RecipeType> getRecipeType() { + return RecipeTypes.CRAFTING; + } + + @Override + public boolean canHandle(ContainerArcaneCraftingTerminal menu, RecipeHolder recipe) { + return true; + } + + @Override + public List getRecipeSlots(ContainerArcaneCraftingTerminal menu, RecipeHolder recipe) { + return menu.getSlots(appeng.menu.SlotSemantics.CRAFTING_GRID); + } + + @Override + public List getInventorySlots(ContainerArcaneCraftingTerminal menu, RecipeHolder recipe) { + return menu.getSlots(appeng.menu.SlotSemantics.PLAYER_INVENTORY); + } +} diff --git a/src/main/java/thaumicenergistics/integration/jei/ArcaneRecipeTransferInfo.java b/src/main/java/thaumicenergistics/integration/jei/ArcaneRecipeTransferInfo.java new file mode 100644 index 0000000..2b2f974 --- /dev/null +++ b/src/main/java/thaumicenergistics/integration/jei/ArcaneRecipeTransferInfo.java @@ -0,0 +1,60 @@ +package thaumicenergistics.integration.jei; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.inventory.Slot; + +import mezz.jei.api.recipe.RecipeType; +import mezz.jei.api.recipe.transfer.IRecipeTransferInfo; +import appeng.menu.SlotSemantics; +import thaumcraft.integration.jei.JeiArcaneRecipe; +import thaumcraft.integration.jei.ThaumcraftJeiPlugin; +import thaumicenergistics.common.container.ContainerArcaneCraftingTerminal; +import thaumicenergistics.init.ModMenuTypes; + +/** + * JEI 配方转移信息:支持 TC4 奥术配方(JeiArcaneRecipe)。 + * 与 ArcaneCraftingTransferInfo(vanilla 合成)配合使用。 + */ +public class ArcaneRecipeTransferInfo implements IRecipeTransferInfo { + + @Override + public Class getContainerClass() { + return ContainerArcaneCraftingTerminal.class; + } + + @Override + public Optional> getMenuType() { + return Optional.of(ModMenuTypes.ARCANE_CRAFTING_TERMINAL.get()); + } + + @Override + public RecipeType getRecipeType() { + return ThaumcraftJeiPlugin.ARCANE; + } + + @Override + public boolean canHandle(ContainerArcaneCraftingTerminal menu, JeiArcaneRecipe recipe) { + return true; + } + + @Override + public List getRecipeSlots(ContainerArcaneCraftingTerminal menu, JeiArcaneRecipe recipe) { + return menu.getSlots(SlotSemantics.CRAFTING_GRID); + } + + @Override + public List getInventorySlots(ContainerArcaneCraftingTerminal menu, JeiArcaneRecipe recipe) { + List inventorySlots = new ArrayList<>(); + var playerInv = menu.getPlayerInventory(); + for (Slot slot : menu.slots) { + if (slot != null && slot.container == playerInv) { + inventorySlots.add(slot); + } + } + return inventorySlots; + } +} diff --git a/src/main/java/thaumicenergistics/integration/jei/AspectIngredient.java b/src/main/java/thaumicenergistics/integration/jei/AspectIngredient.java new file mode 100644 index 0000000..3a95efd --- /dev/null +++ b/src/main/java/thaumicenergistics/integration/jei/AspectIngredient.java @@ -0,0 +1,16 @@ +package thaumicenergistics.integration.jei; + +import thaumcraft.api.aspects.Aspect; + +/** + * JEI 自定义成分:持有 Thaumcraft Aspect 实例。 + * 不创建虚拟物品,不污染物品注册表。 + * JEI 侧边栏直接显示要素图标,支持搜索和拖拽。 + */ +public record AspectIngredient(Aspect aspect) { + + @Override + public String toString() { + return "AspectIngredient{" + aspect.getTag() + "}"; + } +} diff --git a/src/main/java/thaumicenergistics/integration/jei/AspectIngredientHelper.java b/src/main/java/thaumicenergistics/integration/jei/AspectIngredientHelper.java new file mode 100644 index 0000000..f68ff12 --- /dev/null +++ b/src/main/java/thaumicenergistics/integration/jei/AspectIngredientHelper.java @@ -0,0 +1,73 @@ +package thaumicenergistics.integration.jei; + +import net.minecraft.resources.ResourceLocation; + +import mezz.jei.api.ingredients.IIngredientHelper; +import mezz.jei.api.ingredients.subtypes.UidContext; +import thaumcraft.api.aspects.Aspect; +import thaumicenergistics.common.integration.tc.TCReflection; + +@SuppressWarnings("removal") +public class AspectIngredientHelper implements IIngredientHelper { + + public static final AspectIngredientHelper INSTANCE = new AspectIngredientHelper(); + + private AspectIngredientHelper() {} + + @Override + public AspectIngredientType getIngredientType() { + return AspectIngredientType.INSTANCE; + } + + @Override + public String getDisplayName(AspectIngredient ingredient) { + if (ingredient == null || ingredient.aspect() == null) return "Unknown"; + return ingredient.aspect().getName(); + } + + @Override + public Object getUid(AspectIngredient ingredient, UidContext context) { + if (ingredient == null || ingredient.aspect() == null) return "thaumcraft:unknown"; + ResourceLocation id = TCReflection.getAspectId(ingredient.aspect()); + return id != null ? id.toString() : "thaumcraft:" + ingredient.aspect().getTag(); + } + + @Override + public String getUniqueId(AspectIngredient ingredient, UidContext context) { + return getUid(ingredient, context).toString(); + } + + @Override + public ResourceLocation getResourceLocation(AspectIngredient ingredient) { + if (ingredient == null || ingredient.aspect() == null) return ResourceLocation.withDefaultNamespace("air"); + ResourceLocation id = TCReflection.getAspectId(ingredient.aspect()); + return id != null ? id : ResourceLocation.withDefaultNamespace(ingredient.aspect().getTag()); + } + + @Override + public AspectIngredient copyIngredient(AspectIngredient ingredient) { + return ingredient; + } + + @Override + public boolean isValidIngredient(AspectIngredient ingredient) { + return ingredient != null && ingredient.aspect() != null; + } + + @Override + public boolean isIngredientOnServer(AspectIngredient ingredient) { + return true; + } + + @Override + public String getErrorInfo(AspectIngredient ingredient) { + if (ingredient == null) return "Null AspectIngredient"; + if (ingredient.aspect() == null) return "Null Aspect"; + return "Aspect: " + ingredient.aspect().getTag(); + } + + @Override + public String getDisplayModId(AspectIngredient ingredient) { + return "thaumcraft"; + } +} diff --git a/src/main/java/thaumicenergistics/integration/jei/AspectIngredientRenderer.java b/src/main/java/thaumicenergistics/integration/jei/AspectIngredientRenderer.java new file mode 100644 index 0000000..986250d --- /dev/null +++ b/src/main/java/thaumicenergistics/integration/jei/AspectIngredientRenderer.java @@ -0,0 +1,50 @@ +package thaumicenergistics.integration.jei; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.TooltipFlag; + +import mezz.jei.api.ingredients.IIngredientRenderer; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.client.gui.AspectGuiRenderer; + +public class AspectIngredientRenderer implements IIngredientRenderer { + + public static final AspectIngredientRenderer INSTANCE = new AspectIngredientRenderer(); + + private static final int SIZE = 16; + + private AspectIngredientRenderer() {} + + @Override + public void render(GuiGraphics guiGraphics, AspectIngredient ingredient) { + if (ingredient != null && ingredient.aspect() != null) { + AspectGuiRenderer.draw(guiGraphics, ingredient.aspect(), 0, 0, SIZE, 1.0f); + } + } + + @Override + public List getTooltip(AspectIngredient ingredient, TooltipFlag tooltipFlag) { + List tooltip = new ArrayList<>(); + if (ingredient == null || ingredient.aspect() == null) { + return tooltip; + } + Aspect aspect = ingredient.aspect(); + tooltip.add(Component.literal(aspect.getName())); + tooltip.add(Component.literal(aspect.getTag()).withStyle(style -> style.withColor(0x888888))); + return tooltip; + } + + @Override + public int getWidth() { + return SIZE; + } + + @Override + public int getHeight() { + return SIZE; + } +} diff --git a/src/main/java/thaumicenergistics/integration/jei/AspectIngredientType.java b/src/main/java/thaumicenergistics/integration/jei/AspectIngredientType.java new file mode 100644 index 0000000..d7725a3 --- /dev/null +++ b/src/main/java/thaumicenergistics/integration/jei/AspectIngredientType.java @@ -0,0 +1,18 @@ +package thaumicenergistics.integration.jei; + +import mezz.jei.api.ingredients.IIngredientType; + +/** + * JEI 自定义成分类型:AspectIngredient。 + */ +public class AspectIngredientType implements IIngredientType { + + public static final AspectIngredientType INSTANCE = new AspectIngredientType(); + + private AspectIngredientType() {} + + @Override + public Class getIngredientClass() { + return AspectIngredient.class; + } +} diff --git a/src/main/java/thaumicenergistics/integration/jei/CellWorkbenchGhostIngredientHandler.java b/src/main/java/thaumicenergistics/integration/jei/CellWorkbenchGhostIngredientHandler.java new file mode 100644 index 0000000..7f4cc3c --- /dev/null +++ b/src/main/java/thaumicenergistics/integration/jei/CellWorkbenchGhostIngredientHandler.java @@ -0,0 +1,57 @@ +package thaumicenergistics.integration.jei; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.client.renderer.Rect2i; +import net.minecraft.resources.ResourceLocation; + +import mezz.jei.api.gui.handlers.IGhostIngredientHandler; +import mezz.jei.api.ingredients.ITypedIngredient; + +import thaumicenergistics.common.container.GuiEssentiaCellWorkbench; +import thaumicenergistics.common.integration.tc.TCReflection; +import thaumicenergistics.common.network.CellWorkbenchC2SPacket; + +/** + * 源质元件工作台分区格的 JEI 拖拽支持:从 JEI 拖拽要素到 63 个分区格之一 → 添加该要素分区。 + * 纯 JEI API 实现,不依赖 AE2-JEI-Integration(只装 JEI 即可用)。 + */ +public class CellWorkbenchGhostIngredientHandler implements IGhostIngredientHandler { + + @Override + public List> getTargetsTyped(GuiEssentiaCellWorkbench gui, ITypedIngredient ingredient, boolean doStart) { + List> targets = new ArrayList<>(); + if (!(ingredient.getIngredient() instanceof AspectIngredient)) { + return targets; + } + // 63 个分区格都是拖放目标 + for (int i = 0; i < GuiEssentiaCellWorkbench.NUMBER_OF_WIDGETS; i++) { + int col = i % GuiEssentiaCellWorkbench.WIDGETS_PER_ROW; + int row = i / GuiEssentiaCellWorkbench.WIDGETS_PER_ROW; + int wx = gui.getGuiLeft() + GuiEssentiaCellWorkbench.WIDGET_POS_X + col * GuiEssentiaCellWorkbench.WIDGET_SIZE; + int wy = gui.getGuiTop() + GuiEssentiaCellWorkbench.WIDGET_POS_Y + row * GuiEssentiaCellWorkbench.WIDGET_SIZE; + targets.add(new Target<>() { + @Override + public Rect2i getArea() { + return new Rect2i(wx, wy, GuiEssentiaCellWorkbench.WIDGET_SIZE, GuiEssentiaCellWorkbench.WIDGET_SIZE); + } + + @Override + public void accept(I ingredient) { + if (ingredient instanceof AspectIngredient ai && ai.aspect() != null) { + ResourceLocation aspectId = TCReflection.getAspectId(ai.aspect()); + if (aspectId != null) { + CellWorkbenchC2SPacket.sendAddAspect(aspectId); + } + } + } + }); + } + return targets; + } + + @Override + public void onComplete() { + } +} diff --git a/src/main/java/thaumicenergistics/integration/jei/EssentiaIngredientConverter.java b/src/main/java/thaumicenergistics/integration/jei/EssentiaIngredientConverter.java new file mode 100644 index 0000000..a85efde --- /dev/null +++ b/src/main/java/thaumicenergistics/integration/jei/EssentiaIngredientConverter.java @@ -0,0 +1,48 @@ +package thaumicenergistics.integration.jei; + +import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.Nullable; + +import mezz.jei.api.ingredients.IIngredientType; + +import appeng.api.stacks.GenericStack; +import appeng.api.stacks.AEKey; +import tamaized.ae2jeiintegration.api.integrations.jei.IngredientConverter; +import thaumcraft.api.aspects.Aspect; +import thaumicenergistics.common.integration.appeng.AEssentiaKey; +import thaumicenergistics.common.integration.tc.TCReflection; + +/** + * 源质转换器:GenericStack(AEssentiaKey) ↔ AspectIngredient。 + * 通过 ServiceLoader 自动注册到 AE2-JEI-Integration。 + * 实现从 JEI 拖拽源质到 AE2 筛选槽的功能。 + */ +public class EssentiaIngredientConverter implements IngredientConverter { + + @Override + public IIngredientType getIngredientType() { + return AspectIngredientType.INSTANCE; + } + + @Override + public @Nullable AspectIngredient getIngredientFromStack(GenericStack stack) { + if (stack == null) return null; + AEKey what = stack.what(); + if (what instanceof AEssentiaKey essentiaKey) { + ResourceLocation id = essentiaKey.getId(); + Aspect aspect = Aspect.getAspect(id.getPath()); + if (aspect != null) { + return new AspectIngredient(aspect); + } + } + return null; + } + + @Override + public @Nullable GenericStack getStackFromIngredient(AspectIngredient ingredient) { + if (ingredient == null || ingredient.aspect() == null) return null; + var aspectId = TCReflection.getAspectId(ingredient.aspect()); + if (aspectId == null) return null; + return new GenericStack(AEssentiaKey.of(aspectId), 1); + } +} diff --git a/src/main/java/thaumicenergistics/integration/jei/ThEArcaneCraftingTransferInfo.java b/src/main/java/thaumicenergistics/integration/jei/ThEArcaneCraftingTransferInfo.java new file mode 100644 index 0000000..b1ddf27 --- /dev/null +++ b/src/main/java/thaumicenergistics/integration/jei/ThEArcaneCraftingTransferInfo.java @@ -0,0 +1,53 @@ +package thaumicenergistics.integration.jei; + +import java.util.List; +import java.util.Optional; + +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.crafting.CraftingRecipe; +import net.minecraft.world.item.crafting.RecipeHolder; + +import mezz.jei.api.constants.RecipeTypes; +import mezz.jei.api.recipe.RecipeType; +import mezz.jei.api.recipe.transfer.IRecipeTransferInfo; +import appeng.menu.SlotSemantics; +import thaumicenergistics.common.container.ContainerArcaneCraftingTerminal; +import thaumicenergistics.init.ModMenuTypes; + +/** + * JEI 配方转移信息:告诉 JEI 哪些槽位是合成网格,哪些是玩家背包。 + * 这样 JEI 的 "+" 按钮就能将配方转移到奥术合成台。 + */ +public class ThEArcaneCraftingTransferInfo implements IRecipeTransferInfo> { + + @Override + public Class getContainerClass() { + return ContainerArcaneCraftingTerminal.class; + } + + @Override + public Optional> getMenuType() { + return Optional.of(ModMenuTypes.ARCANE_CRAFTING_TERMINAL.get()); + } + + @Override + public RecipeType> getRecipeType() { + return RecipeTypes.CRAFTING; + } + + @Override + public boolean canHandle(ContainerArcaneCraftingTerminal container, RecipeHolder recipe) { + return true; + } + + @Override + public List getRecipeSlots(ContainerArcaneCraftingTerminal container, RecipeHolder recipe) { + return container.getSlots(SlotSemantics.CRAFTING_GRID); + } + + @Override + public List getInventorySlots(ContainerArcaneCraftingTerminal container, RecipeHolder recipe) { + return container.getSlots(SlotSemantics.PLAYER_INVENTORY); + } +} diff --git a/src/main/java/thaumicenergistics/integration/jei/ThEGhostIngredientHandler.java b/src/main/java/thaumicenergistics/integration/jei/ThEGhostIngredientHandler.java new file mode 100644 index 0000000..526af49 --- /dev/null +++ b/src/main/java/thaumicenergistics/integration/jei/ThEGhostIngredientHandler.java @@ -0,0 +1,99 @@ +package thaumicenergistics.integration.jei; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.renderer.Rect2i; +import net.minecraft.world.item.ItemStack; + +import mezz.jei.api.gui.handlers.IGhostIngredientHandler; +import mezz.jei.api.ingredients.ITypedIngredient; + +import appeng.api.stacks.GenericStack; +import appeng.menu.AEBaseMenu; +import appeng.menu.slot.FakeSlot; + +/** + * 处理从 JEI 拖拽到 AE2 Screen 的筛选槽。 + * 支持两种拖拽方式: + * 1. 拖拽 WrappedGenericStack ItemStack(AE2 原生支持) + * 2. 拖拽 AspectIngredient(自定义成分类型) + */ +public class ThEGhostIngredientHandler implements IGhostIngredientHandler { + + @Override + public List> getTargetsTyped(Screen screen, ITypedIngredient ingredient, boolean doStart) { + List> targets = new ArrayList<>(); + + if (!(screen instanceof appeng.client.gui.AEBaseScreen aeScreen)) { + return targets; + } + + if (!(aeScreen.getMenu() instanceof AEBaseMenu menu)) { + return targets; + } + + if (!canHandleIngredient(ingredient)) { + return targets; + } + + for (var slot : menu.slots) { + if (slot instanceof FakeSlot fakeSlot) { + targets.add(new Target<>() { + @Override + public Rect2i getArea() { + return new Rect2i( + aeScreen.getGuiLeft() + fakeSlot.x, + aeScreen.getGuiTop() + fakeSlot.y, + 16, 16 + ); + } + + @Override + public void accept(I ingredient) { + handleIngredientDrop(ingredient, fakeSlot); + } + }); + } + } + + return targets; + } + + private boolean canHandleIngredient(ITypedIngredient ingredient) { + if (ingredient.getIngredient() instanceof AspectIngredient) { + return true; + } + if (ingredient.getIngredient() instanceof ItemStack stack) { + return GenericStack.unwrapItemStack(stack) != null; + } + return false; + } + + private void handleIngredientDrop(I ingredient, FakeSlot fakeSlot) { + ItemStack targetStack = ItemStack.EMPTY; + + if (ingredient instanceof AspectIngredient ai && ai.aspect() != null) { + // AspectIngredient → WrappedGenericStack ItemStack + var aspectId = thaumicenergistics.common.integration.tc.TCReflection.getAspectId(ai.aspect()); + if (aspectId != null) { + var key = thaumicenergistics.common.integration.appeng.AEssentiaKey.of(aspectId); + targetStack = GenericStack.wrapInItemStack(key, 0); + } + } else if (ingredient instanceof ItemStack stack) { + // WrappedGenericStack ItemStack(AE2 原生支持,直接放入) + if (GenericStack.unwrapItemStack(stack) != null) { + targetStack = stack; + } + } + + if (!targetStack.isEmpty()) { + fakeSlot.set(targetStack); + } + } + + @Override + public void onComplete() { + } +} diff --git a/src/main/java/thaumicenergistics/integration/jei/ThEJeiPlugin.java b/src/main/java/thaumicenergistics/integration/jei/ThEJeiPlugin.java new file mode 100644 index 0000000..311e106 --- /dev/null +++ b/src/main/java/thaumicenergistics/integration/jei/ThEJeiPlugin.java @@ -0,0 +1,100 @@ +package thaumicenergistics.integration.jei; + +import java.util.ArrayList; +import java.util.List; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; + +import mezz.jei.api.IModPlugin; +import mezz.jei.api.JeiPlugin; +import mezz.jei.api.registration.IGuiHandlerRegistration; +import mezz.jei.api.registration.IModIngredientRegistration; +import mezz.jei.api.registration.IRecipeTransferRegistration; + +import static mezz.jei.api.constants.RecipeTypes.CRAFTING; +import net.minecraft.resources.ResourceLocation; + +import thaumcraft.api.aspects.Aspect; +import thaumcraft.integration.jei.ThaumcraftJeiPlugin; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.common.container.GuiEssentiaCellWorkbench; +import thaumicenergistics.common.integration.tc.TCReflection; + +/** + * JEI 插件:将源质注册为自定义 IIngredient 类型显示在 JEI 成分列表中。 + * 拖拽功能由 AE2-JEI-Integration 模组的 GhostIngredientHandler + IngredientConverter 处理。 + * 不创建虚拟物品,不污染物品注册表。 + */ +@JeiPlugin +public class ThEJeiPlugin implements IModPlugin { + + private static final Codec CODEC = ResourceLocation.CODEC.flatXmap( + rl -> { + Aspect aspect = Aspect.getAspect(rl.getPath()); + if (aspect != null) return DataResult.success(new AspectIngredient(aspect)); + return DataResult.error(() -> "Unknown aspect: " + rl); + }, + ai -> { + ResourceLocation id = TCReflection.getAspectId(ai.aspect()); + ResourceLocation result = id != null ? id : ResourceLocation.withDefaultNamespace(ai.aspect().getTag()); + return DataResult.success(result); + } + ); + + public ThEJeiPlugin() { + // 可选集成:AE2-JEI-Integration 存在时注册源质拖拽转换(拖拽进 AE2 筛选槽); + // 不存在时跳过——只装 JEI 也能正常使用 JEI 显示/配方转移/ghost 拖拽。 + try { + Class.forName("tamaized.ae2jeiintegration.api.integrations.jei.IngredientConverters"); + Class.forName("thaumicenergistics.integration.jei.Ae2JeiCompat") + .getMethod("register").invoke(null); + ThaumicEnergistics.LOG.info("[JEI] AE2-JEI-Integration detected, essentia drag-conversion registered"); + } catch (ClassNotFoundException e) { + ThaumicEnergistics.LOG.info("[JEI] AE2-JEI-Integration not present, essentia drag-conversion unavailable (optional)"); + } catch (ReflectiveOperationException e) { + ThaumicEnergistics.LOG.warn("[JEI] AE2-JEI-Integration registration failed: {}", e.toString()); + } + } + + @Override + public ResourceLocation getPluginUid() { + return ThaumicEnergistics.id("jei"); + } + + @Override + public void registerIngredients(IModIngredientRegistration registration) { + List ingredients = new ArrayList<>(); + if (Aspect.aspects != null) { + for (Aspect aspect : Aspect.aspects.values()) { + if (aspect != null && aspect.getTag() != null) { + ingredients.add(new AspectIngredient(aspect)); + } + } + } + registration.register( + AspectIngredientType.INSTANCE, + ingredients, + AspectIngredientHelper.INSTANCE, + AspectIngredientRenderer.INSTANCE, + CODEC + ); + } + + @Override + public void registerRecipeTransferHandlers(IRecipeTransferRegistration registration) { + ThaumicEnergistics.LOG.info("[JEI] Registering ThEUseCraftingRecipeTransfer for ArcaneCraftingTerminal"); + // 注册 IRecipeTransferInfo 让 JEI 显示 "+" 按钮 + registration.addRecipeTransferHandler(new ArcaneCraftingTransferInfo()); + registration.addRecipeTransferHandler(new ArcaneRecipeTransferInfo()); + // 注册 IRecipeTransferHandler 让点击 "+" 时走 ME 网络 + registration.addRecipeTransferHandler(new ThEUseCraftingRecipeTransfer(registration.getTransferHelper()), CRAFTING); + registration.addRecipeTransferHandler(new ThEUseArcaneRecipeTransfer(registration.getTransferHelper()), ThaumcraftJeiPlugin.ARCANE); + } + + @Override + public void registerGuiHandlers(IGuiHandlerRegistration registration) { + // 源质元件工作台:从 JEI 拖拽要素到分区格添加分区(纯 JEI API,可选功能) + registration.addGhostIngredientHandler(GuiEssentiaCellWorkbench.class, new CellWorkbenchGhostIngredientHandler()); + } +} diff --git a/src/main/java/thaumicenergistics/integration/jei/ThEUseArcaneRecipeTransfer.java b/src/main/java/thaumicenergistics/integration/jei/ThEUseArcaneRecipeTransfer.java new file mode 100644 index 0000000..4ff0318 --- /dev/null +++ b/src/main/java/thaumicenergistics/integration/jei/ThEUseArcaneRecipeTransfer.java @@ -0,0 +1,97 @@ +package thaumicenergistics.integration.jei; + +import java.util.Objects; +import java.util.Optional; + +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.core.NonNullList; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.Ingredient; + +import mezz.jei.api.gui.builder.ITooltipBuilder; +import mezz.jei.api.gui.ingredient.IRecipeSlotsView; +import mezz.jei.api.recipe.RecipeIngredientRole; +import mezz.jei.api.recipe.transfer.IRecipeTransferError; +import mezz.jei.api.recipe.transfer.IRecipeTransferHandler; +import mezz.jei.api.recipe.transfer.IRecipeTransferHandlerHelper; + +import org.jetbrains.annotations.Nullable; + +import appeng.core.network.serverbound.FillCraftingGridFromRecipePacket; +import net.neoforged.neoforge.network.PacketDistributor; + +import thaumcraft.integration.jei.JeiArcaneRecipe; +import thaumcraft.integration.jei.ThaumcraftJeiPlugin; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.common.container.ContainerArcaneCraftingTerminal; +import thaumicenergistics.init.ModMenuTypes; + +/** + * 奥术合成终端专用的 JEI 奥术配方转移处理器。 + * 点击 "+" 时发送 FillCraftingGridFromRecipePacket 从 ME 网络填充材料。 + */ +public class ThEUseArcaneRecipeTransfer + implements IRecipeTransferHandler { + + private final IRecipeTransferHandlerHelper helper; + + public ThEUseArcaneRecipeTransfer(IRecipeTransferHandlerHelper helper) { + this.helper = helper; + } + + @Override + public Class getContainerClass() { + return ContainerArcaneCraftingTerminal.class; + } + + @Override + public Optional> getMenuType() { + return Optional.of(ModMenuTypes.ARCANE_CRAFTING_TERMINAL.get()); + } + + @Override + public mezz.jei.api.recipe.RecipeType getRecipeType() { + return ThaumcraftJeiPlugin.ARCANE; + } + + @Override + public IRecipeTransferError transferRecipe( + ContainerArcaneCraftingTerminal menu, + JeiArcaneRecipe recipe, + IRecipeSlotsView display, + net.minecraft.world.entity.player.Player player, + boolean maxTransfer, + boolean doTransfer) { + + ThaumicEnergistics.LOG.info("[JEI-Arcane] transferRecipe called, recipeId={}, doTransfer={}", + recipe.id(), doTransfer); + + boolean craftMissing = AbstractContainerScreen.hasControlDown(); + + // 预览:始终 null(绿色按钮),由服务端处理实际缺失 + if (!doTransfer) { + return null; + } + + // 构建模板物品列表(9 格,对应 3x3 合成格) + var templateItems = NonNullList.withSize(9, ItemStack.EMPTY); + var inputs = recipe.inputs(); + for (int i = 0; i < templateItems.size() && i < inputs.size(); i++) { + var variants = inputs.get(i); + if (variants != null && !variants.isEmpty()) { + templateItems.set(i, variants.get(0).copyWithCount(1)); + } + } + + // 奥术配方不在 vanilla 配方管理器中,recipeId 传 null + // 服务端会用 Ingredient.of(templateItems) 重建,然后从 ME 网络提取 + var packet = new FillCraftingGridFromRecipePacket(null, templateItems, craftMissing); + ThaumicEnergistics.LOG.info("[JEI-Arcane] Sending FillCraftingGridFromRecipePacket, templateCount={}", + templateItems.stream().filter(s -> !s.isEmpty()).count()); + PacketDistributor.sendToServer(packet); + + return null; + } +} diff --git a/src/main/java/thaumicenergistics/integration/jei/ThEUseCraftingRecipeTransfer.java b/src/main/java/thaumicenergistics/integration/jei/ThEUseCraftingRecipeTransfer.java new file mode 100644 index 0000000..1554211 --- /dev/null +++ b/src/main/java/thaumicenergistics/integration/jei/ThEUseCraftingRecipeTransfer.java @@ -0,0 +1,236 @@ +package thaumicenergistics.integration.jei; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.core.NonNullList; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.CraftingRecipe; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.RecipeHolder; +import net.minecraft.world.item.crafting.RecipeType; +import net.neoforged.neoforge.network.PacketDistributor; + +import mezz.jei.api.gui.builder.ITooltipBuilder; +import mezz.jei.api.gui.ingredient.IRecipeSlotsView; +import mezz.jei.api.recipe.RecipeIngredientRole; +import mezz.jei.api.recipe.transfer.IRecipeTransferError; +import mezz.jei.api.recipe.transfer.IRecipeTransferHandler; +import mezz.jei.api.recipe.transfer.IRecipeTransferHandlerHelper; + +import org.jetbrains.annotations.Nullable; + +import appeng.core.network.serverbound.FillCraftingGridFromRecipePacket; +import appeng.util.CraftingRecipeUtil; + +import net.minecraft.world.inventory.MenuType; +import thaumicenergistics.ThaumicEnergistics; +import thaumicenergistics.common.container.ContainerArcaneCraftingTerminal; +import thaumicenergistics.init.ModMenuTypes; + +import static appeng.integration.modules.itemlists.TransferHelper.BLUE_PLUS_BUTTON_COLOR; +import static appeng.integration.modules.itemlists.TransferHelper.BLUE_SLOT_HIGHLIGHT_COLOR; +import static appeng.integration.modules.itemlists.TransferHelper.ORANGE_PLUS_BUTTON_COLOR; +import static appeng.integration.modules.itemlists.TransferHelper.RED_SLOT_HIGHLIGHT_COLOR; + +/** + * 奥术合成终端专用的 JEI 配方转移处理器。 + * 预览时使用 findMissingIngredients 检查 ME 网络物品可用性, + * 实际转移时发送 FillCraftingGridFromRecipePacket 从 ME 网络填充材料。 + * + * 参考 AE2-JEI-Integration 的 UseCraftingRecipeTransfer 实现。 + */ +public class ThEUseCraftingRecipeTransfer + implements IRecipeTransferHandler> { + + private static final int CRAFTING_GRID_WIDTH = 3; + private static final int CRAFTING_GRID_HEIGHT = 3; + + private final IRecipeTransferHandlerHelper helper; + + public ThEUseCraftingRecipeTransfer(IRecipeTransferHandlerHelper helper) { + this.helper = helper; + } + + @Override + public Class getContainerClass() { + return ContainerArcaneCraftingTerminal.class; + } + + @Override + public Optional> getMenuType() { + return Optional.of(ModMenuTypes.ARCANE_CRAFTING_TERMINAL.get()); + } + + @Override + public mezz.jei.api.recipe.RecipeType> getRecipeType() { + return mezz.jei.api.constants.RecipeTypes.CRAFTING; + } + + @Override + public IRecipeTransferError transferRecipe( + ContainerArcaneCraftingTerminal menu, + RecipeHolder recipeHolder, + IRecipeSlotsView display, + net.minecraft.world.entity.player.Player player, + boolean maxTransfer, + boolean doTransfer) { + + var recipe = recipeHolder.value(); + ThaumicEnergistics.LOG.info("[JEI] transferRecipe called, recipeId={}, doTransfer={}, player={}", + recipeHolder.id(), doTransfer, player.getName().getString()); + if (recipe.getType() != RecipeType.CRAFTING) { + ThaumicEnergistics.LOG.warn("[JEI] Not a crafting recipe, type={}", recipe.getType()); + return helper.createInternalError(); + } + if (recipe.getIngredients().isEmpty()) { + return helper.createInternalError(); + } + if (!recipe.canCraftInDimensions(CRAFTING_GRID_WIDTH, CRAFTING_GRID_HEIGHT)) { + return helper.createInternalError(); + } + + boolean craftMissing = AbstractContainerScreen.hasControlDown(); + // 自行构建 slot→ingredient 映射(0-8 对应 3x3 合成格), + // 不依赖 helper.getGuiSlotIndexToIngredientMap(需要 IRecipeTransferInfo 才能正确工作) + var slotToIngredientMap = buildSlotToIngredientMap(recipe); + var missingSlots = menu.findMissingIngredients(slotToIngredientMap); + ThaumicEnergistics.LOG.info("[JEI] missingSlots: missing={}, craftable={}, total={}", + missingSlots.missingSlots().size(), missingSlots.craftableSlots().size(), missingSlots.totalSize()); + + // 全部缺失 → 红色,无法点击 + if (missingSlots.missingSlots().size() == slotToIngredientMap.size()) { + ThaumicEnergistics.LOG.info("[JEI] All items missing, returning NO_ITEMS error"); + var inputSlots = display.getSlotViews(RecipeIngredientRole.INPUT); + var missingSlotViews = missingSlots.missingSlots().stream() + .map(idx -> idx < inputSlots.size() ? inputSlots.get(idx) : null) + .filter(Objects::nonNull) + .toList(); + return helper.createUserErrorForMissingSlots( + appeng.core.localization.ItemModText.NO_ITEMS.text(), missingSlotViews); + } + + // 预览:检查缺失情况,返回对应的错误渲染 + if (!doTransfer) { + if (missingSlots.totalSize() != 0) { + int color = missingSlots.anyMissing() ? ORANGE_PLUS_BUTTON_COLOR : BLUE_PLUS_BUTTON_COLOR; + return new MissingSlotsError(missingSlots, craftMissing, color); + } + // 全部物品都有 → null = 绿色按钮 + return null; + } + + // 实际转移:发送 ME 网络填充包 + var templateItems = NonNullList.withSize(9, ItemStack.EMPTY); + var ingredients = CraftingRecipeUtil.ensure3by3CraftingMatrix(recipe); + for (int i = 0; i < ingredients.size() && i < 9; i++) { + var ingredient = ingredients.get(i); + if (!ingredient.isEmpty()) { + var items = ingredient.getItems(); + if (items.length > 0) { + templateItems.set(i, items[0].copyWithCount(1)); + } + } + } + + @Nullable + ResourceLocation recipeId = recipeHolder.id(); + if (recipeId != null && player.level().getRecipeManager().byKey(recipeId).isEmpty()) { + recipeId = null; + } + + var packet = new FillCraftingGridFromRecipePacket(recipeId, templateItems, craftMissing); + ThaumicEnergistics.LOG.info("[JEI] Sending FillCraftingGridFromRecipePacket, recipeId={}, templateCount={}, craftMissing={}", + recipeId, templateItems.stream().filter(s -> !s.isEmpty()).count(), craftMissing); + PacketDistributor.sendToServer(packet); + + return null; + } + + /** + * 根据配方构建 3x3 合成格的 slot index → ingredient 映射。 + * 使用 CraftingRecipeUtil.ensure3by3CraftingMatrix 确保 9 格对齐, + * 与实际转移时的索引体系完全一致。 + */ + private static Map buildSlotToIngredientMap(CraftingRecipe recipe) { + var ingredients = CraftingRecipeUtil.ensure3by3CraftingMatrix(recipe); + Map map = new HashMap<>(); + for (int i = 0; i < ingredients.size() && i < 9; i++) { + var ing = ingredients.get(i); + if (!ing.isEmpty()) { + map.put(i, ing); + } + } + return map; + } + + /** + * 缺失/可合成物品的预览错误渲染器。 + * 参考 AE2-JEI-Integration.UseCraftingRecipeTransfer.ErrorRenderer。 + */ + private record MissingSlotsError( + ContainerArcaneCraftingTerminal.MissingIngredientSlots indices, + boolean craftMissing, + int color) implements IRecipeTransferError { + + @Override + public Type getType() { + return Type.COSMETIC; + } + + @Override + public int getButtonHighlightColor() { + return color; + } + + @Override + public void showError(GuiGraphics guiGraphics, int mouseX, int mouseY, + IRecipeSlotsView slots, int recipeX, int recipeY) { + var poseStack = guiGraphics.pose(); + poseStack.pushPose(); + poseStack.translate(recipeX, recipeY, 0); + + var slotViews = slots.getSlotViews(RecipeIngredientRole.INPUT); + for (int i = 0; i < slotViews.size(); i++) { + var slotView = slotViews.get(i); + boolean missing = indices.missingSlots().contains(i); + boolean craftable = indices.craftableSlots().contains(i); + if (missing || craftable) { + slotView.drawHighlight( + guiGraphics, + missing ? RED_SLOT_HIGHLIGHT_COLOR : BLUE_SLOT_HIGHLIGHT_COLOR); + } + } + + poseStack.popPose(); + } + + @Override + public int getMissingCountHint() { + return indices.missingSlots().size(); + } + + @Override + public void getTooltip(ITooltipBuilder tooltip) { + int missing = indices.missingSlots().size(); + int craftable = indices.craftableSlots().size(); + if (missing > 0) { + tooltip.add(net.minecraft.network.chat.Component.translatable( + "jei.tooltip.transfer.missing", missing)); + } + if (craftable > 0) { + tooltip.add(net.minecraft.network.chat.Component.translatable( + "jei.tooltip.transfer.craftable", craftable)); + } + if (craftMissing) { + tooltip.add(net.minecraft.network.chat.Component.translatable( + "jei.tooltip.transfer.ctrl.click")); + } + } + } +} diff --git a/src/main/java/thaumicenergistics/mixins/ae2/MixinAbstractTerminalPart.java b/src/main/java/thaumicenergistics/mixins/ae2/MixinAbstractTerminalPart.java new file mode 100644 index 0000000..001fe40 --- /dev/null +++ b/src/main/java/thaumicenergistics/mixins/ae2/MixinAbstractTerminalPart.java @@ -0,0 +1,58 @@ +package thaumicenergistics.mixins.ae2; + +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; +import appeng.api.util.KeyTypeSelection; +import appeng.api.util.KeyTypeSelectionHost; +import appeng.parts.reporting.AbstractTerminalPart; +import thaumicenergistics.common.integration.appeng.AEssentiaKeyType; +import thaumicenergistics.common.parts.EssentiaTerminalPart; + +/** + * 在普通 ME 终端的 KeyTypeSelection 中始终禁用 AEssentiaKeyType。 + * ⚠ KeyTypeSelection.readFromNBT (line 101) 会先全部 setValue(false) 再读 NBT 恢复, + * 所以仅仅在构造器 TAIL 注入是不够的——readFromNBT 会把构造器的修改完全清掉。 + * 需要同时在 readFromNBT TAIL 再注入一次,确保 essentia 始终被禁用。 + * EssentiaTerminalPart 覆盖了 getKeyTypeSelection() 返回自己的实例,不受影响。 + */ +@Mixin(AbstractTerminalPart.class) +public abstract class MixinAbstractTerminalPart implements KeyTypeSelectionHost { + + /** + * 构造器 TAIL:新放置的终端,在 keyTypeSelection 初始化后禁用 essentia。 + */ + @Inject(method = "", at = @At("TAIL")) + private void removeEssentiaFromRegularTerminal(CallbackInfo ci) { + if ((Object) this instanceof EssentiaTerminalPart) return; + doDisableEssentia(); + } + + /** + * readFromNBT TAIL:从存档加载后,readFromNBT 会重置 keyTypeSelection, + * 需要再次禁用 essentia 以确保不会被 NBT 恢复重新打开。 + */ + @Inject(method = "readFromNBT", at = @At("TAIL")) + private void onReadFromNBT(CallbackInfo ci) { + if ((Object) this instanceof EssentiaTerminalPart) return; + doDisableEssentia(); + } + + private void doDisableEssentia() { + try { + KeyTypeSelection sel = this.getKeyTypeSelection(); + // 先检查是否包含 AEssentiaKeyType(可能 keyTypeSelection 还没完全初始化) + try { + if (sel.isEnabled(AEssentiaKeyType.INSTANCE)) { + sel.setEnabled(AEssentiaKeyType.INSTANCE, false); + } + } catch (IllegalArgumentException e) { + // keyTypeSelection 中不包含 AEssentiaKeyType → 无需操作 + } + } catch (Exception e) { + // 构造阶段 host 为空,saveChanges() → getHost().markForSave() 会 NPE + // setEnabled 内部的 map 修改已完成,catch 忽略 + } + } +} diff --git a/src/main/java/thaumicenergistics/mixins/ae2/MixinConfigMenuInventory.java b/src/main/java/thaumicenergistics/mixins/ae2/MixinConfigMenuInventory.java new file mode 100644 index 0000000..4e67e33 --- /dev/null +++ b/src/main/java/thaumicenergistics/mixins/ae2/MixinConfigMenuInventory.java @@ -0,0 +1,89 @@ +package thaumicenergistics.mixins.ae2; + +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import net.minecraft.world.item.ItemStack; +import thaumcraft.api.aspects.Aspect; +import thaumcraft.api.aspects.AspectList; +import thaumcraft.api.aspects.IEssentiaContainerItem; +import appeng.api.stacks.GenericStack; +import appeng.helpers.externalstorage.GenericStackInv; +import appeng.util.ConfigMenuInventory; +import thaumicenergistics.common.integration.appeng.AEssentiaKey; +import thaumicenergistics.common.integration.appeng.AEssentiaKeyType; +import thaumicenergistics.common.integration.tc.TCReflection; + +/** + * Mixin ConfigMenuInventory:在 AE2 原有的 ItemStack→AEKey 转换失败后, + * 追加 Thaumcraft 源质容器物品的检测。 + * + * 当玩家把装有源质的罐子({@code thaumcraft:jar_of_essentia})或药水 + * 拖入 AE 设备的筛选槽时,AE2 原生逻辑不认识这类物品,返回 null。 + * 此 Mixin 在原方法返回 null 后拦截,检测物品是否为 + * {@link IEssentiaContainerItem},若则提取其中的源质转为 {@link AEssentiaKey}。 + * + * 这使得在没有 JEI 的情况下,玩家也能通过拖拽源质罐子到筛选槽来设置源质筛选。 + */ +@Mixin(ConfigMenuInventory.class) +public abstract class MixinConfigMenuInventory { + + @Shadow(remap = false) + @Final + private GenericStackInv inv; + + /** + * 在 convertToSuitableStack 返回 null 时拦截, + * 检测物品是否为 Thaumcraft 源质容器并转换。 + */ + @Inject( + method = "convertToSuitableStack", + at = @At("RETURN"), + cancellable = true + ) + private void convertEssentiaContainer(ItemStack stack, + CallbackInfoReturnable<@Nullable GenericStack> cir) { + // 如果 AE2 原生逻辑已经成功转换,不做任何事 + if (cir.getReturnValue() != null) { + return; + } + + // 空栈无需处理 + if (stack == null || stack.isEmpty()) { + return; + } + + // 检查底层 ConfigInventory 是否支持源质类型 + if (!this.inv.isSupportedType(AEssentiaKeyType.INSTANCE)) { + return; + } + + // 检测是否为 Thaumcraft 源质容器物品 + if (stack.getItem() instanceof IEssentiaContainerItem containerItem) { + AspectList aspects = containerItem.getAspects(stack); + if (aspects == null || aspects.size() == 0) { + return; + } + + // 取第一个源质(罐子通常只装一种) + Aspect firstAspect = aspects.getAspects()[0]; + if (firstAspect == null) { + return; + } + + var aspectId = TCReflection.getAspectId(firstAspect); + if (aspectId == null) { + return; + } + + AEssentiaKey key = AEssentiaKey.of(aspectId); + long amount = aspects.getAmount(firstAspect); + cir.setReturnValue(new GenericStack(key, amount)); + } + } +} diff --git a/src/main/java/thaumicenergistics/mixins/ae2/MixinCraftingTreeProcess.java b/src/main/java/thaumicenergistics/mixins/ae2/MixinCraftingTreeProcess.java new file mode 100644 index 0000000..b7493d1 --- /dev/null +++ b/src/main/java/thaumicenergistics/mixins/ae2/MixinCraftingTreeProcess.java @@ -0,0 +1,7 @@ +package thaumicenergistics.mixins.ae2; +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(targets = "appeng.crafting.CraftingTreeProcess", remap = false) +public abstract class MixinCraftingTreeProcess { + @Inject(method = "", at = @At("RETURN"), remap = false) + private void onConstructed(CallbackInfo ci) {} +} diff --git a/src/main/java/thaumicenergistics/mixins/tc/MixinAspect.java b/src/main/java/thaumicenergistics/mixins/tc/MixinAspect.java new file mode 100644 index 0000000..89a53f2 --- /dev/null +++ b/src/main/java/thaumicenergistics/mixins/tc/MixinAspect.java @@ -0,0 +1,7 @@ +package thaumicenergistics.mixins.tc; +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(targets = "thaumcraft.api.aspects.Aspect", remap = false) +public abstract class MixinAspect { + @Inject(method = "", at = @At("RETURN"), remap = false) + private void onConstructed(CallbackInfo ci) {} +} diff --git a/src/main/java/thaumicenergistics/mixins/tc/MixinThaumonomiconScreen.java b/src/main/java/thaumicenergistics/mixins/tc/MixinThaumonomiconScreen.java new file mode 100644 index 0000000..9e57924 --- /dev/null +++ b/src/main/java/thaumicenergistics/mixins/tc/MixinThaumonomiconScreen.java @@ -0,0 +1,61 @@ +package thaumicenergistics.mixins.tc; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import net.minecraft.client.Minecraft; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.api.distmarker.OnlyIn; + +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 thaumcraft.client.gui.ThaumonomiconData; +import thaumcraft.client.gui.ThaumonomiconScreen; +import thaumcraft.common.research.TCResearchManager; + +/** + * 研究节点"逐渐显现"(仅神秘能源分类):只显示"已解锁研究节点的后继" + * (parents 中存在已解锁节点)——无已解锁前置链的孤立节点隐藏。 + * 伪前置(PSEUDO_ 开头)不受过滤影响(默认显现、解锁跟随真实节点)。 + */ +@OnlyIn(Dist.CLIENT) +@Mixin(ThaumonomiconScreen.class) +public abstract class MixinThaumonomiconScreen { + + private static final String TH_E_CATEGORY = "THAUMICENERGISTICS"; + + @Inject(method = "visibleEntries", at = @At("RETURN"), cancellable = true) + private void thE$filterInaccessible(CallbackInfoReturnable> cir) { + List all = cir.getReturnValue(); + if (all == null || all.isEmpty()) return; + // 只过滤神秘能源分类(TC 原版分类保持原样) + if (!TH_E_CATEGORY.equals(all.get(0).category())) return; + + var player = Minecraft.getInstance().player; + if (player == null) return; + Set completed = new HashSet<>(TCResearchManager.completedKeys(player)); + + List filtered = new ArrayList<>(all.size()); + for (ThaumonomiconData.Entry e : all) { + // 伪前置不受影响(默认显现) + if (e.key().startsWith("PSEUDO_")) { + filtered.add(e); + continue; + } + if (completed.contains(e.key())) { + filtered.add(e); + continue; + } + // 可达:parents 中存在已解锁节点(已解锁节点的后继) + if (e.parents().stream().anyMatch(completed::contains)) { + filtered.add(e); + } + } + cir.setReturnValue(filtered); + } +} diff --git a/src/main/java/thaumicenergistics/mixins/tc/MixinVisRelayBlock.java b/src/main/java/thaumicenergistics/mixins/tc/MixinVisRelayBlock.java new file mode 100644 index 0000000..80cb557 --- /dev/null +++ b/src/main/java/thaumicenergistics/mixins/tc/MixinVisRelayBlock.java @@ -0,0 +1,44 @@ +package thaumicenergistics.mixins.tc; + +import appeng.block.networking.CableBusBlock; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.DirectionProperty; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +/** + * TC4 的 {@code VisRelayBlock} 是壁挂方块:其 {@code canSurvive} 仅当附着面 + * 是坚固面({@code isFaceSturdy})时才返回 true。AE2 线缆总线不坚固, + * 因此 vis 中继无法挂在线缆上——这使它无法直接放在 ThE Vis Interface(线缆部件)上方。 + * + * 此 mixin 允许 AE2 {@link CableBusBlock} 作为有效支撑,使中继可放置在 + * Vis Interface 旁边。实际 vis 网络连接仍由 {@code VisInterfacePart.getRelay()} 决定, + * 仅当中继真正面对 Vis Interface 部件时才建立连接。 + */ +@Mixin(targets = "thaumcraft.common.blocks.VisRelayBlock", remap = false) +public abstract class MixinVisRelayBlock { + + @Shadow + public static DirectionProperty FACING; + + @Inject(method = "canSurvive", at = @At("RETURN"), cancellable = true, remap = false) + private void thE_allowCableSupport(BlockState state, LevelReader level, BlockPos pos, + CallbackInfoReturnable cir) { + if (cir.getReturnValue()) { + return; + } + Direction facing = state.getValue(FACING); + BlockPos support = pos.relative(facing.getOpposite()); + Block supportBlock = level.getBlockState(support).getBlock(); + if (supportBlock instanceof CableBusBlock) { + cir.setReturnValue(true); + } + } +} diff --git a/src/main/java/thaumicenergistics/mixins/tc/ResearchPageIndexMixin.java b/src/main/java/thaumicenergistics/mixins/tc/ResearchPageIndexMixin.java new file mode 100644 index 0000000..5651e97 --- /dev/null +++ b/src/main/java/thaumicenergistics/mixins/tc/ResearchPageIndexMixin.java @@ -0,0 +1,26 @@ +package thaumicenergistics.mixins.tc; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; +import thaumcraft.common.research.ResearchPageIndex; + +import java.util.Set; + +@Mixin(value = ResearchPageIndex.class, remap = false) +public abstract class ResearchPageIndexMixin { + + @Redirect( + method = "load", + at = @At( + value = "INVOKE", + target = "Ljava/util/Set;equals(Ljava/lang/Object;)Z" + ) + ) + private static boolean fixEquals(Set instance, Object other) { + if (other instanceof Set indexSet) { + return indexSet.containsAll(instance); + } + return instance.equals(other); + } +} \ No newline at end of file diff --git a/src/main/resources/META-INF/neoforge.mods.toml b/src/main/resources/META-INF/neoforge.mods.toml new file mode 100644 index 0000000..a5020aa --- /dev/null +++ b/src/main/resources/META-INF/neoforge.mods.toml @@ -0,0 +1,50 @@ +modLoader="javafml" +loaderVersion="${loader_version_range}" +license="MIT" + +[[mods]] +modId="thaumicenergistics" +version="${version}" +displayName="ThaumicEnergistics" +description="Bridges Thaumcraft Essentia with Applied Energistics 2 ME networks." +authors="Nividica, Community" +logoFile="assets/thaumicenergistics/meta/logo.png" +displayTest="IGNORE_ALL_VERSION" + +[[dependencies.thaumicenergistics]] +modId="neoforge" +type="required" +versionRange="${neoforge_version_range}" +ordering="NONE" +side="BOTH" + +[[dependencies.thaumicenergistics]] +modId="minecraft" +type="required" +versionRange="${minecraft_version_range}" +ordering="NONE" +side="BOTH" + +[[dependencies.thaumicenergistics]] +modId="ae2" +type="required" +versionRange="[19,)" +ordering="AFTER" +side="BOTH" + +[[dependencies.thaumicenergistics]] +modId="thaumcraft" +type="required" +versionRange="[0,)" +ordering="AFTER" +side="BOTH" + +[[dependencies.thaumicenergistics]] +modId="jei" +type="optional" +versionRange="[19,)" +ordering="NONE" +side="CLIENT" + +[[mixins]] +config="thaumicenergistics.mixins.json" diff --git a/src/main/resources/META-INF/services/snownee.jade.api.IWailaPlugin b/src/main/resources/META-INF/services/snownee.jade.api.IWailaPlugin new file mode 100644 index 0000000..9ea4127 --- /dev/null +++ b/src/main/resources/META-INF/services/snownee.jade.api.IWailaPlugin @@ -0,0 +1 @@ +thaumicenergistics.common.integration.jade.ThEJadePlugin diff --git a/src/main/resources/META-INF/services/tamaized.ae2jeiintegration.api.integrations.jei.IngredientConverter b/src/main/resources/META-INF/services/tamaized.ae2jeiintegration.api.integrations.jei.IngredientConverter new file mode 100644 index 0000000..efb8c3f --- /dev/null +++ b/src/main/resources/META-INF/services/tamaized.ae2jeiintegration.api.integrations.jei.IngredientConverter @@ -0,0 +1 @@ +thaumicenergistics.integration.jei.EssentiaIngredientConverter diff --git a/src/main/resources/assets/ae2/screens/arcane_crafting_terminal.json b/src/main/resources/assets/ae2/screens/arcane_crafting_terminal.json new file mode 100644 index 0000000..a86657c --- /dev/null +++ b/src/main/resources/assets/ae2/screens/arcane_crafting_terminal.json @@ -0,0 +1,61 @@ +{ + "$schema": "../schema.json", + "includes": ["terminals/terminal.json"], + "slots": { + "CRAFTING_GRID": { + "left": 26, + "bottom": 158, + "grid": "BREAK_AFTER_3COLS" + }, + "CRAFTING_RESULT": { + "left": 134, + "bottom": 140 + }, + "STORAGE": { + "left": 136, + "bottom": 163 + } + }, + "text": { + "dialog_title": { + "text": { + "translate": "item.thaumicenergistics.arcane_crafting_terminal" + }, + "position": { + "left": 8, + "top": 6 + } + }, + "crafting_grid_title": { + "text": { + "translate": "gui.thaumicenergistics.ArcaneCraftingTerminal" + }, + "position": { + "left": 8, + "bottom": 177 + } + } + }, + "terminalStyle": { + "header": { + "texture": "thaumicenergistics:textures/gui/arcane_crafting.png", + "srcRect": [0, 0, 195, 17] + }, + "firstRow": { + "texture": "thaumicenergistics:textures/gui/arcane_crafting.png", + "srcRect": [0, 17, 195, 18] + }, + "row": { + "texture": "thaumicenergistics:textures/gui/arcane_crafting.png", + "srcRect": [0, 35, 195, 18] + }, + "lastRow": { + "texture": "thaumicenergistics:textures/gui/arcane_crafting.png", + "srcRect": [0, 53, 195, 18] + }, + "bottom": { + "texture": "thaumicenergistics:textures/gui/arcane_crafting.png", + "srcRect": [0, 71, 195, 180] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/ae2/screens/aspect_filter_selection.json b/src/main/resources/assets/ae2/screens/aspect_filter_selection.json new file mode 100644 index 0000000..2cdda0d --- /dev/null +++ b/src/main/resources/assets/ae2/screens/aspect_filter_selection.json @@ -0,0 +1,23 @@ +{ + "$schema": "../schema.json", + "includes": ["common/common.json"], + "generatedBackground": { + "width": 520 + }, + "text": { + "dialog_title": { + "position": { + "left": 8, + "top": 7 + } + } + }, + "widgets": { + "back": { + "left": 496, + "top": -5, + "width": 20, + "height": 20 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/ae2/screens/essentia_level_emitter.json b/src/main/resources/assets/ae2/screens/essentia_level_emitter.json new file mode 100644 index 0000000..097f835 --- /dev/null +++ b/src/main/resources/assets/ae2/screens/essentia_level_emitter.json @@ -0,0 +1,43 @@ +{ + "$schema": "schema.json", + "includes": [ + "common/common.json", + "common/player_inventory.json", + "common/toolbox.json" + ], + "background": { + "texture": "guis/level_emitter.png", + "srcRect": [0, 0, 176, 186] + }, + "slots": { + "CONFIG": { + "left": 137, + "top": 40 + } + }, + "text": { + "dialog_title": { + "text": { + "translate": "item.thaumicenergistics.essentia_level_emitter" + }, + "position": { + "left": 8, + "top": 6 + } + } + }, + "widgets": { + "level": { + "left": 20, + "top": 17, + "width": 138, + "height": 62 + }, + "levelInput": { + "left": 23, + "top": 42, + "width": 103, + "height": 12 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/blockstates/arcane_assembler.json b/src/main/resources/assets/thaumicenergistics/blockstates/arcane_assembler.json new file mode 100644 index 0000000..72f53e9 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/blockstates/arcane_assembler.json @@ -0,0 +1 @@ +{"variants":{"":{"model":"thaumicenergistics:block/arcane_assembler"}}} diff --git a/src/main/resources/assets/thaumicenergistics/blockstates/distillation_encoder.json b/src/main/resources/assets/thaumicenergistics/blockstates/distillation_encoder.json new file mode 100644 index 0000000..45b413e --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/blockstates/distillation_encoder.json @@ -0,0 +1 @@ +{"variants":{"":{"model":"thaumicenergistics:block/distillation_encoder"}}} diff --git a/src/main/resources/assets/thaumicenergistics/blockstates/essentia_cell_workbench.json b/src/main/resources/assets/thaumicenergistics/blockstates/essentia_cell_workbench.json new file mode 100644 index 0000000..194302f --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/blockstates/essentia_cell_workbench.json @@ -0,0 +1 @@ +{"variants":{"":{"model":"thaumicenergistics:block/essentia_cell_workbench"}}} diff --git a/src/main/resources/assets/thaumicenergistics/blockstates/essentia_provider.json b/src/main/resources/assets/thaumicenergistics/blockstates/essentia_provider.json new file mode 100644 index 0000000..4a328ae --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/blockstates/essentia_provider.json @@ -0,0 +1 @@ +{"variants":{"":{"model":"thaumicenergistics:block/essentia_provider"}}} diff --git a/src/main/resources/assets/thaumicenergistics/blockstates/essentia_vibration_chamber.json b/src/main/resources/assets/thaumicenergistics/blockstates/essentia_vibration_chamber.json new file mode 100644 index 0000000..e5ffa34 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/blockstates/essentia_vibration_chamber.json @@ -0,0 +1,8 @@ +{ + "variants": { + "facing=north": { "model": "thaumicenergistics:block/essentia_vibration_chamber" }, + "facing=south": { "model": "thaumicenergistics:block/essentia_vibration_chamber", "y": 180 }, + "facing=west": { "model": "thaumicenergistics:block/essentia_vibration_chamber", "y": 270 }, + "facing=east": { "model": "thaumicenergistics:block/essentia_vibration_chamber", "y": 90 } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/blockstates/infusion_provider.json b/src/main/resources/assets/thaumicenergistics/blockstates/infusion_provider.json new file mode 100644 index 0000000..321af7c --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/blockstates/infusion_provider.json @@ -0,0 +1 @@ +{"variants":{"":{"model":"thaumicenergistics:block/infusion_provider"}}} diff --git a/src/main/resources/assets/thaumicenergistics/blockstates/knowledge_inscriber.json b/src/main/resources/assets/thaumicenergistics/blockstates/knowledge_inscriber.json new file mode 100644 index 0000000..ea2f98f --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/blockstates/knowledge_inscriber.json @@ -0,0 +1 @@ +{"variants":{"":{"model":"thaumicenergistics:block/knowledge_inscriber"}}} diff --git a/src/main/resources/assets/thaumicenergistics/lang/en_us.json b/src/main/resources/assets/thaumicenergistics/lang/en_us.json new file mode 100644 index 0000000..15959c4 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/lang/en_us.json @@ -0,0 +1,120 @@ +{ + "itemGroup.thaumicenergistics": "Thaumic Energistics", + "block.thaumicenergistics.essentia_provider": "Essentia Provider", + "block.thaumicenergistics.infusion_provider": "Infusion Provider", + "block.thaumicenergistics.arcane_assembler": "Arcane Assembler", + "block.thaumicenergistics.knowledge_inscriber": "Knowledge Inscriber", + "block.thaumicenergistics.essentia_cell_workbench": "Essentia Cell Workbench", + "block.thaumicenergistics.essentia_vibration_chamber": "Essentia Vibration Chamber", + "block.thaumicenergistics.distillation_encoder": "Distillation Encoder", + "item.thaumicenergistics.essentia_cell_1k": "1k ME Essentia Storage Cell", + "item.thaumicenergistics.essentia_cell_4k": "4k ME Essentia Storage Cell", + "item.thaumicenergistics.essentia_cell_16k": "16k ME Essentia Storage Cell", + "item.thaumicenergistics.essentia_cell_64k": "64k ME Essentia Storage Cell", + "item.thaumicenergistics.essentia_cell_creative": "Creative ME Essentia Storage Cell", + "item.thaumicenergistics.storage_component_1k": "1k ME Essentia Storage Component", + "item.thaumicenergistics.storage_component_4k": "4k ME Essentia Storage Component", + "item.thaumicenergistics.storage_component_16k": "16k ME Essentia Storage Component", + "item.thaumicenergistics.storage_component_64k": "64k ME Essentia Storage Component", + "item.thaumicenergistics.storage_casing": "ME Essentia Storage Housing", + "item.thaumicenergistics.coalescence_core": "Coalescence Core", + "item.thaumicenergistics.diffusion_core": "Diffusion Core", + "item.thaumicenergistics.knowledge_core": "Knowledge Core", + "item.thaumicenergistics.focus_aewrench": "Focus: AE Wrench", + "item.thaumicenergistics.golem_wifi_backpack": "Wireless Golem Backpack", + "item.thaumicenergistics.wireless_essentia_terminal": "Wireless Essentia Terminal", + "item.thaumicenergistics.essentia_import_bus": "Essentia Import Bus", + "item.thaumicenergistics.essentia_export_bus": "Essentia Export Bus", + "item.thaumicenergistics.essentia_storage_bus": "Essentia Storage Bus", + "item.thaumicenergistics.essentia_terminal": "Essentia Terminal", + "item.thaumicenergistics.arcane_crafting_terminal": "Arcane Crafting Terminal", + "item.thaumicenergistics.essentia_level_emitter": "Essentia Level Emitter", + "item.thaumicenergistics.vis_interface": "Vis Interface", + "tooltip.thaumicenergistics.essentia_import_bus.desc": "Extracts essentia from adjacent containers into the ME network", + "tooltip.thaumicenergistics.essentia_import_bus.hint": "Place on a cable facing jars, alembics or any essentia container", + "tooltip.thaumicenergistics.essentia_export_bus.desc": "Inserts essentia from the ME network into adjacent containers", + "tooltip.thaumicenergistics.essentia_export_bus.hint": "Place on a cable facing jars, infusion altars or any essentia receptacle", + "tooltip.thaumicenergistics.essentia_storage_bus.desc": "Bidirectionally syncs an external essentia container with the ME network", + "tooltip.thaumicenergistics.essentia_storage_bus.hint": "Place on a cable facing an essentia container to use it as network storage", + "tooltip.thaumicenergistics.essentia_terminal.desc": "View and extract essentia from the ME network", + "ae2.keytype.thaumicenergistics.essentia": "Essentia", + "tc.research_category.THAUMICENERGISTICS": "Thaumic Energistics", + "tc.research_name.BASEENERGISTICS": "Basic Energistics", + "tc.research_text.BASEENERGISTICS": "You have discovered a curious resonance between AE2's mechanical networks and Thaumaturgy. The precision of AE devices seems capable of sensing and manipulating essentia, that mysterious form of matter.", + "tc.research_name.FOCUS_AEWRENCH": "Focus: AE Wrench", + "tc.research_text.FOCUS_AEWRENCH": "By condensing the functionality of an AE wrench into a wand focus, you can manipulate AE network devices without switching tools.", + "tc.research_name.DIGISENTIA": "Digitized Essentia", + "tc.research_text.DIGISENTIA.stage.1": "Though essentia is a mystical substance, you have discovered it can be processed using AE's digital technology. The key lies in two cores: a Diffusion Core to decompose essentia into digital signals, and a Coalescence Core to reassemble digital signals back into essentia.", + "tc.research_text.DIGISENTIA.stage.2": "You have successfully crafted the Diffusion Core and Coalescence Core. They will serve as the foundation of your entire Thaumic Energistics system.", + "tc.research_name.ESSENTIASTORAGE1K": "Essentia Storage: 1k", + "tc.research_text.ESSENTIASTORAGE1K": "Using the Coalescence Core and wisp essences, you can create ME storage cells capable of storing essentia. The 1k cell is the most basic model, holding a modest amount of a single essentia type.", + "tc.research_name.ESSENTIASTORAGE": "Essentia Storage", + "tc.research_text.ESSENTIASTORAGE": "Using Coalescence Cores and wisp essences, you can create ME storage cells capable of storing essentia. Available in 1k, 4k, 16k, and 64k variants.", + "tc.research_name.ESSENTIASTORAGE4K": "Essentia Storage: 4k", + "tc.research_text.ESSENTIASTORAGE4K": "Building upon the 1k cell, you can create a larger 4k essentia storage cell.", + "tc.research_name.ESSENTIASTORAGE16K": "Essentia Storage: 16k", + "tc.research_text.ESSENTIASTORAGE16K": "The 16k essentia storage cell can hold a considerable amount of essentia.", + "tc.research_name.ESSENTIASTORAGE64K": "Essentia Storage: 64k", + "tc.research_text.ESSENTIASTORAGE64K": "The 64k essentia storage cell represents the current pinnacle of this technology, capable of storing vast quantities of essentia.", + "tc.research_name.ESSENTIABUSES": "Essentia Buses", + "tc.research_text.ESSENTIABUSES.stage.1": "Using Diffusion and Coalescence Cores, you can create three types of essentia buses: the Import Bus extracts essentia from external containers into the ME network, the Export Bus outputs essentia from the network into external containers, and the Storage Bus maps external containers as ME network storage units.", + "tc.research_text.ESSENTIABUSES.stage.2": "Essentia buses are the bridge between the physical world and the digital essentia realm. Attach them to an ME cable facing an essentia container to activate them.", + "tc.research_name.ESSENTIATERMINAL": "Essentia Terminal", + "tc.research_text.ESSENTIATERMINAL.stage.1": "The Essentia Terminal allows you to view all essentia stored in your ME network, just like browsing items. You can insert and extract essentia directly from the terminal.", + "tc.research_text.ESSENTIATERMINAL.stage.2": "The Essentia Terminal can only view and manipulate essentia — it cannot access items or fluids. It is purpose-built for essentia management.", + "tc.research_name.ARCANECRAFTINGTERMINAL": "Arcane Crafting Terminal", + "tc.research_text.ARCANECRAFTINGTERMINAL.stage.1": "By combining an ME Terminal with an Arcane Worktable, you can perform arcane crafting directly within the ME network.", + "tc.research_text.ARCANECRAFTINGTERMINAL.stage.2": "The Arcane Crafting Terminal requires vis from a wand or wand focus. Ensure your wand has sufficient vis to complete the crafting.", + "tc.research_name.ESSENTIAPROVIDER": "Essentia Provider", + "tc.research_text.ESSENTIAPROVIDER.stage.1": "The Essentia Provider automatically extracts essentia from the ME network and supplies it to adjacent essentia containers. This is invaluable for devices that consume large amounts of essentia.", + "tc.research_text.ESSENTIAPROVIDER.stage.2": "Place the Essentia Provider adjacent to an essentia container, and it will automatically replenish the container up to the configured level.", + "tc.research_name.INFUSIONPROVIDER": "Infusion Provider", + "tc.research_text.INFUSIONPROVIDER.stage.1": "The Infusion Provider is an upgraded Essentia Provider. It can directly inject essentia from the ME network into an Infusion Altar, fully automating the infusion process.", + "tc.research_text.INFUSIONPROVIDER.stage.2": "Place the Infusion Provider beneath an Infusion Altar, and it will automatically supply the required essentia during infusion. No more manual jar placement!", + "tc.research_name.ARCANEASSEMBLER": "Arcane Assembler", + "tc.research_text.ARCANEASSEMBLER.stage.1": "The Arcane Assembler is the arcane version of the ME Molecular Assembler. It can automatically execute arcane crafting recipes, perfectly merging magic with automation.", + "tc.research_text.ARCANEASSEMBLER.stage.2": "Connected to the ME network, the Arcane Assembler can process arcane crafting tasks automatically. It requires vis from a wand to drive the crafting process.", + "tc.research_name.ESSENTIAVIBRATIONCHAMBER": "Essentia Vibration Chamber", + "tc.research_text.ESSENTIAVIBRATIONCHAMBER": "The Essentia Vibration Chamber converts essentia into AE power. Different essentia types provide different energy values — more complex essentia yields more energy. It offers a way to turn surplus essentia into usable power.", + "tc.research_name.KNOWLEDGEINSCRIBER": "Knowledge Inscriber", + "tc.research_text.KNOWLEDGEINSCRIBER": "The Knowledge Inscriber converts Thaumaturgical research notes into Knowledge Cores that the AE network can recognize. It bridges the gap between arcane knowledge and digital storage.", + "tc.research_name.DISTILLATIONENCODER": "Distillation Encoder", + "tc.research_text.DISTILLATIONENCODER": "The Distillation Encoder can automatically distill essentia from items and import it into the ME network. It combines the advantages of an essentia alembic with the AE network.", + "tc.research_name.VISINTERFACE": "Vis Relay Interface", + "tc.research_text.VISINTERFACE": "The Vis Relay Interface allows you to transport vis (magical energy) through the ME network, enabling long-distance vis supply. It uses P2P tunnel technology to relay vis from one node to another.", + "tc.research_name.GOLEMWIFI": "Wireless Golem Backpack", + "tc.research_text.GOLEMWIFI": "The Wireless Golem Backpack allows a golem to directly access items in the ME network. A golem equipped with this backpack acts as a mobile AE interface, enabling remote item access.", + + "tc.research_name.CERTUS_DUPE": "Certus Quartz Duplication", + "tc.research_text.CERTUS_DUPE": "Using alchemical duplication, you can duplicate certus quartz crystals. This provides a renewable source of certus quartz for your AE network.", + + "tc.research_text.ARCANEASSEMBLER": "The arcane version of the ME Molecular Assembler, capable of automated arcane crafting.", + "tc.research_text.ARCANECRAFTINGTERMINAL": "Combine an ME Terminal with an Arcane Worktable for direct arcane crafting in the ME network.", + "tc.research_text.ESSENTIABUSES": "Essentia Import, Export, and Storage Buses bridge physical essentia containers with the ME network.", + "tc.research_text.INFUSIONPROVIDER": "Automatically supplies essentia from the ME network to an Infusion Altar.", + "tc.research_text.ESSENTIAPROVIDER": "Automatically extracts essentia from the ME network and supplies adjacent containers.", + "tc.research_text.ESSENTIATERMINAL": "View and manage all essentia stored in your ME network.", + "tc.research_text.DIGISENTIA": "Digitize essentia using Diffusion and Coalescence Cores for processing by the ME network.", + + "tc.research_name.PSEUDO_DISTILESSENTIA": "Essentia Distillation", + "tc.research_name.PSEUDO_TUBEFILTER": "Advanced Essentia Tubes", + "tc.research_name.PSEUDO_ALCHEMICALDUPLICATION": "Alchemical Duplication", + "tc.research_name.PSEUDO_MIRROR": "Mirror Magic", + "tc.research_name.PSEUDO_INFUSION": "Infusion", + "tc.research_name.PSEUDO_WARDEDARCANA": "Warded Arcana", + "tc.research_name.PSEUDO_FOCUSFIRE": "Wand Foci", + "tc.research_name.PSEUDO_VISPOWER": "Harnessing Vis", + "tc.research_name.PSEUDO_SCEPTRE": "Crafting Scepters", + "tc.research_name.PSEUDO_COREGATHER": "Golem Core: Gather", + + "thaumicenergistics.jade.suction_type": "Suction: %s", + "thaumicenergistics.jade.essentia_stored": "Essentia: %d / %d", + "thaumicenergistics.jade.burning": "Burning %d%%, %.1f AE/tick", + "thaumicenergistics.aspect.ignis": "Ignis", + "thaumicenergistics.aspect.potentia": "Potentia", + "thaumicenergistics.aspect.energy": "Energy", + "thaumicenergistics.jade.energy_stored": "Stored: %s / %s", + "thaumicenergistics.jade.energy_output": "Output Limit: %s AE/tick", + "thaumicenergistics.jade.tank_full": "Tank full, generation stopped", + "thaumicenergistics.gui.distillation_encoder.not_scanned": "Not scanned" +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/lang/zh_cn.json b/src/main/resources/assets/thaumicenergistics/lang/zh_cn.json new file mode 100644 index 0000000..4ab0eca --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/lang/zh_cn.json @@ -0,0 +1,138 @@ +{ + "itemGroup.thaumicenergistics": "神秘能源", + "block.thaumicenergistics.essentia_provider": "源质供应器", + "block.thaumicenergistics.infusion_provider": "注魔供应器", + "block.thaumicenergistics.arcane_assembler": "奥术装配器", + "block.thaumicenergistics.knowledge_inscriber": "知识记录仪", + "block.thaumicenergistics.essentia_cell_workbench": "源质元件工作台", + "block.thaumicenergistics.essentia_vibration_chamber": "源质谐振仓", + "block.thaumicenergistics.distillation_encoder": "蒸馏编码台", + "item.thaumicenergistics.essentia_cell_1k": "1k ME 源质存储元件", + "item.thaumicenergistics.essentia_cell_4k": "4k ME 源质存储元件", + "item.thaumicenergistics.essentia_cell_16k": "16k ME 源质存储元件", + "item.thaumicenergistics.essentia_cell_64k": "64k ME 源质存储元件", + "item.thaumicenergistics.essentia_cell_creative": "创造 ME 源质存储元件", + "item.thaumicenergistics.storage_component_1k": "1k ME 源质存储组件", + "item.thaumicenergistics.storage_component_4k": "4k ME 源质存储组件", + "item.thaumicenergistics.storage_component_16k": "16k ME 源质存储组件", + "item.thaumicenergistics.storage_component_64k": "64k ME 源质存储组件", + "item.thaumicenergistics.storage_casing": "ME源质存储外壳", + "item.thaumicenergistics.coalescence_core": "聚集核心", + "item.thaumicenergistics.diffusion_core": "扩散核心", + "item.thaumicenergistics.knowledge_core": "知识核心", + "item.thaumicenergistics.focus_aewrench": "法杖核心:AE扳手", + "item.thaumicenergistics.golem_wifi_backpack": "无线傀儡背包", + "item.thaumicenergistics.wireless_essentia_terminal": "无线源质终端", + "item.thaumicenergistics.essentia_import_bus": "源质输入总线", + "item.thaumicenergistics.essentia_export_bus": "源质输出总线", + "item.thaumicenergistics.essentia_storage_bus": "源质存储总线", + "item.thaumicenergistics.essentia_terminal": "源质终端", + "item.thaumicenergistics.arcane_crafting_terminal": "奥术合成终端", + "item.thaumicenergistics.essentia_level_emitter": "源质发信器", + "item.thaumicenergistics.vis_interface": "要素中继接口", + "tooltip.thaumicenergistics.essentia_import_bus.desc": "从相邻的源质容器抽取源质导入ME网络", + "tooltip.thaumicenergistics.essentia_import_bus.hint": "贴在线缆上,对准罐子/蒸馏器等源质容器", + "tooltip.thaumicenergistics.essentia_export_bus.desc": "从ME网络抽取源质输出到相邻的源质容器", + "tooltip.thaumicenergistics.essentia_export_bus.hint": "贴在线缆上,对准罐子/注魔台等源质容器", + "tooltip.thaumicenergistics.essentia_storage_bus.desc": "将相邻的源质容器与ME网络双向同步", + "tooltip.thaumicenergistics.essentia_storage_bus.hint": "贴在线缆上,把外部源质容器当作ME存储单元使用", + "tooltip.thaumicenergistics.essentia_terminal.desc": "查看并取出/存入源质", + "ae2.keytype.thaumicenergistics.essentia": "源质", + + + "tc.research_category.THAUMICENERGISTICS": "神秘能源", + + "tc.research_name.BASEENERGISTICS": "基础能源学", + "tc.research_text.BASEENERGISTICS": "你发现AE2的机械网络与神秘学之间存在奇妙的共鸣。精密的AE设备似乎能够感知并操控源质这种神秘的物质形态。", + + "tc.research_name.FOCUS_AEWRENCH": "法杖核心:AE扳手", + "tc.research_text.FOCUS_AEWRENCH": "将AE扳手的功能凝聚到法杖核心中,让你无需切换工具即可操控AE网络设备。", + + "tc.research_name.DIGISENTIA": "数字化源质", + "tc.research_text.DIGISENTIA.stage.1": "源质虽然是一种神秘物质,但你发现它可以用AE的数字化技术进行处理。关键在于制造两种核心:扩散核心用于将源质分解为数字信号,凝聚核心用于将数字信号重组为源质。", + "tc.research_text.DIGISENTIA.stage.2": "你成功制作了扩散核心和凝聚核心。它们将是你构建整个神秘能源系统的基石。", + + "tc.research_name.ESSENTIASTORAGE": "源质存储", + "tc.research_text.ESSENTIASTORAGE": "利用凝聚核心和天域之华制造ME源质存储元件,有1k、4k、16k、64k四种容量。", + "tc.research_name.ESSENTIASTORAGE1K": "源质存储:1k", + "tc.research_text.ESSENTIASTORAGE1K": "利用凝聚核心和天域之华,你可以制造出能够存储源质的ME存储元件。1k元件是最基础的型号,可以存储少量单一类型的源质。", + "tc.research_name.ESSENTIASTORAGE4K": "源质存储:4k", + "tc.research_text.ESSENTIASTORAGE4K": "在1k元件的基础上,你可以制造容量更大的4k源质存储元件。", + "tc.research_name.ESSENTIASTORAGE16K": "源质存储:16k", + "tc.research_text.ESSENTIASTORAGE16K": "16k源质存储元件能够存储相当可观的源质。", + "tc.research_name.ESSENTIASTORAGE64K": "源质存储:64k", + "tc.research_text.ESSENTIASTORAGE64K": "64k源质存储元件是当前技术的极限,能够存储海量源质。", + + "tc.research_name.ESSENTIABUSES": "源质总线", + "tc.research_text.ESSENTIABUSES.stage.1": "通过扩散核心和凝聚核心,你可以制造出三种源质总线:输入总线从外部容器抽取源质进入ME网络,输出总线将网络中的源质输出到外部容器,存储总线则将外部容器映射为ME网络的存储单元。", + "tc.research_text.ESSENTIABUSES.stage.2": "源质总线是连接物理世界与数字源质世界的桥梁。将总线贴在ME线缆上,对准源质容器即可生效。", + + "tc.research_name.ESSENTIATERMINAL": "源质终端", + "tc.research_text.ESSENTIATERMINAL.stage.1": "源质终端允许你像查看物品一样查看ME网络中存储的所有源质。你可以在终端中直接存取源质,无需手动操作罐子。", + "tc.research_text.ESSENTIATERMINAL.stage.2": "源质终端只能查看和操作源质,无法查看物品或流体。它专门为源质管理而设计。", + + "tc.research_name.ARCANECRAFTINGTERMINAL": "奥术合成终端", + "tc.research_text.ARCANECRAFTINGTERMINAL.stage.1": "将ME终端与奥术工作台结合,你可以在ME网络中直接进行奥术合成。", + "tc.research_text.ARCANECRAFTINGTERMINAL.stage.2": "奥术合成终端需要消耗法杖或法杖核心中的魔力。确保你的法杖有足够的vis来完成合成。", + + "tc.research_name.ESSENTIAPROVIDER": "源质供应器", + "tc.research_text.ESSENTIAPROVIDER.stage.1": "源质供应器能够自动从ME网络中抽取源质,供应给相邻的源质容器。这对于需要大量源质的设备(如蒸馏器)非常有用。", + "tc.research_text.ESSENTIAPROVIDER.stage.2": "将源质供应器贴在源质容器旁边,它就会自动补充容器中的源质,直到达到设定值。", + + "tc.research_name.INFUSIONPROVIDER": "注魔供应器", + "tc.research_text.INFUSIONPROVIDER.stage.1": "注魔供应器是源质供应器的升级版。它可以直接将ME网络中的源质注入到注魔祭坛中,完全自动化注魔过程。", + "tc.research_text.INFUSIONPROVIDER.stage.2": "将注魔供应器放置在注魔祭坛下方,它会在注魔过程中自动提供所需的源质。你不再需要手动摆放源质罐子。", + + "tc.research_name.ARCANEASSEMBLER": "奥术装配器", + "tc.research_text.ARCANEASSEMBLER.stage.1": "奥术装配器是ME分子装配室的奥术版本。它能够自动执行奥术合成配方,将魔法与自动化完美结合。", + "tc.research_text.ARCANEASSEMBLER.stage.2": "连接到ME网络后,奥术装配器可以自动处理奥术合成任务。它需要消耗法杖中的vis来驱动合成过程。", + + "tc.research_name.ESSENTIAVIBRATIONCHAMBER": "源质谐振仓", + "tc.research_text.ESSENTIAVIBRATIONCHAMBER": "源质谐振仓可以将源质转化为AE能量。不同的源质具有不同的能量值,源质越复杂,产生的能量越多。它提供了一种将多余的源质转化为可用能源的方式。", + + "tc.research_name.KNOWLEDGEINSCRIBER": "知识记录仪", + "tc.research_text.KNOWLEDGEINSCRIBER": "知识记录仪能够将神秘学研究笔记转化为AE网络可识别的知识核心。它桥接了神秘学知识与数字存储之间的鸿沟。", + + "tc.research_name.DISTILLATIONENCODER": "蒸馏编码台", + "tc.research_text.DISTILLATIONENCODER": "蒸馏编码台可以自动将物品中的源质蒸馏出来并导入ME网络。它结合了源质蒸馏器和AE网络的优势。", + + "tc.research_name.VISINTERFACE": "要素中继接口", + "tc.research_text.VISINTERFACE": "要素中继接口允许你通过ME网络传输vis(魔力),实现远距离的vis供应。它使用P2P通道技术,将vis从一个节点传输到另一个节点。", + + "tc.research_name.GOLEMWIFI": "无线傀儡背包", + "tc.research_text.GOLEMWIFI": "无线傀儡背包让傀儡能够直接访问ME网络中的物品。装备此背包的傀儡可以作为移动的AE接口,实现远程物品存取。", + + + "tc.research_name.CERTUS_DUPE": "赛特斯石英复制", + "tc.research_text.CERTUS_DUPE": "利用炼金复制技术,你可以复制赛特斯石英水晶。这为你的AE网络提供了可再生的赛特斯石英来源。", + + "tc.research_text.ARCANEASSEMBLER": "ME分子装配室的神秘版本,能够自动执行奥术合成。", + "tc.research_text.ARCANECRAFTINGTERMINAL": "将ME终端与奥术工作台结合,在ME网络中直接进行奥术合成。", + "tc.research_text.ESSENTIABUSES": "源质输入、输出和存储总线,桥接物理世界与ME网络。", + "tc.research_text.INFUSIONPROVIDER": "自动从ME网络向注魔祭坛提供源质。", + "tc.research_text.ESSENTIAPROVIDER": "自动从ME网络提取源质供给相邻容器。", + "tc.research_text.ESSENTIATERMINAL": "查看和管理ME网络中存储的所有源质。", + "tc.research_text.DIGISENTIA": "利用扩散核心和会聚核心将源质数字化,交由ME网络处理。", + + "tc.research_name.PSEUDO_DISTILESSENTIA": "要素蒸馏", + "tc.research_name.PSEUDO_TUBEFILTER": "高级源质管道", + "tc.research_name.PSEUDO_ALCHEMICALDUPLICATION": "炼金复制", + "tc.research_name.PSEUDO_MIRROR": "魔镜", + "tc.research_name.PSEUDO_INFUSION": "注魔", + "tc.research_name.PSEUDO_WARDEDARCANA": "守护之奥术", + "tc.research_name.PSEUDO_FOCUSFIRE": "法杖核心", + "tc.research_name.PSEUDO_VISPOWER": "掌控魔力", + "tc.research_name.PSEUDO_SCEPTRE": "工艺权杖", + "tc.research_name.PSEUDO_COREGATHER": "傀儡核心:聚集", + + "thaumicenergistics.jade.suction_type": "吸力: %s", + "thaumicenergistics.jade.essentia_stored": "源质: %d / %d", + "thaumicenergistics.jade.burning": "燃烧 %d%%, %.1f AE/tick", + "thaumicenergistics.aspect.ignis": "火", + "thaumicenergistics.aspect.potentia": "能量", + "thaumicenergistics.aspect.energy": "能量", + "thaumicenergistics.jade.energy_stored": "已存储: %s / %s", + "thaumicenergistics.jade.energy_output": "输出上限: %s AE/tick", + "thaumicenergistics.jade.tank_full": "能量槽已满,停止发电", + "thaumicenergistics.gui.distillation_encoder.not_scanned": "未扫描" +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/meta/logo.png b/src/main/resources/assets/thaumicenergistics/meta/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..dfa0126d54999befea5a13ff0d30e57ace7399e6 GIT binary patch literal 220085 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

*+fJYT%Hk3`Fx%aqNH{_pMpt?D#2B#leho* z9A(>b`}3_jn7oN&%A|umyA^>=$&5S*kAtn3Me}C3>%f&-6{tSnBkg&Ir0t{DbirzJ zQmw*Ol0O@aJaWykK@YqU?K(31RdFdiHzu!QQv?zV`6+4FvGrGLrvj>Hg{!omoZu>0 zS|w-fW6u3aRVn-|>+cOC^4z&R{{?P6)D#Gc%;&9#H$Prk^?LFh6`a)jVDH~c;yid> zdAci!A}6-?ys43Y6@i!~vTFE@C8sGU*S>RQcD?=F^8ZDa=8>-0mRTW?OpH@fO`CLh z^S@bcR|tFMUQ58X2%xfjEzf@(N9=aHy}64g;q^wWdWDcp{47eNdfrxEX!mm2^Sj+n zBC~3gtCirXfluYx>~=eJUAO0FSiZvE%!dyRMbz@Vdyi>-JqI^lXwSEtt2vJt$31Ef zIZ%)X2Sx?qT3Ar^jTJP;&RvQORBID>Lq;r|t`2d}OvKCD*+okQ<(lQEx`$dnQ}u?J zbmtjac%)4ae&lzMlPGopV+4g+*?fre6e;d`tHVPh%+q6i%UA+;*!; zL-`%HMi=V+R(70B81#^zW5zm)Ib5@f_153A*m;1A?d#f#Udf1f8kendYlC!{^{;&T z)ohKTXt3^K7V78s(?ZBLC>2}Qa(|p`tK!ZZti|)lxm{teg_Q!Vs<4Se(==Et7IN4O zzvrsOX-9-JdCktd_XNl$^=2!3#Jd`jpyYRo&)`|nD(KGZMb$<* zs&Em@#v#yU3D^;>;%~F&S0Qf)$zl0Alr2*%F zRt|5a@l}vHOHyqTP!4k|#bGN-^|>m@){p`=AF%^Q?17}JMkbE2*@xOcEZtKKddv7` zeSZm(${RL(EPF{oNqfeMOKW&b!F9bU&0B&!WqeRy7EmEF}yH~g~}22)eeJS3ndKlAKe6%wS( z6BtF}z*ei&6oc0WT9y(iQm2RJsNZQdyxgy3J$C6WdiJr$^yA9&K{4BH(&8aA%(L(+ z;TjuWwV%o%sRpqqUW=`qEi$5#9Hlo_1p_m_?KN2Tu)QxPgQ-7_KbYm64s&?C-J?FAI&=%*O0`Sr2+E@8a{n?|ZCPD`{8EXp4Pj zZQEk8Sh(+JVcFX~!u*hOPvvtqo6W8ELHS+Q)zP*gSoy?C4`$e_K}4)DDv5_h#cUg> zRYBFOL_JqD1+{zZb*}!siuW!ve?5)53d*X2VcSyWLdP$Q3KlgtG`mR{E@jgcZ`Lzs zs+>7`CMDi{az1Ey{cDx9XAHwhh2ju+37*H~u9+z))PWBzhOuh%qRaa8VWiqXOhT)< z!k~4)qsQVp;VQ-JhpUXyDj7YM&K(%c+ z=~KO3)!yK0(>^EOqqPE&z06C6&90>$A=^U$c|R?e%LBxrkO0eG*>1N7`!%J6&1Q2; z>7>?x&!(>Huv)Edjm|EN`Q2`Jz>ly=Q%U|-tJVHFSew~aY0W)30YeI2z~dgqG2QSn zd6^=jsX*`b`)YkxFA(#A>D`AHS1ncPs0!YLdQ}$gB|QpSR;D3dz_c5`*5k3z zxX122<_XUmU+H&iP`^iZ@emh9;$o7N3Me)x-^Hk>Y-IKPJeyj6Pm~OaHQq{d&01vU zpYZ3XVHqk3o45X+^wvV6%-*iC#%)!m(7zHOxD8i+ z)&}NMomz%Fw~QFZwWysk@G1M>lBv{t?~=c< z*jMTH^E{(6YwqK<@RV(8xi{Yb9v7(med)jRBsO)8CGawDq&$Pd4=6#Mwfg1j7GWyu zQQp1Q>o$I{g3tuagNu8nI-dD;DOCYp? z%iI4vxsCU>8mG%a)9T>Mz!@*eEAL-vov1dN4X!Ms-JiFyi|@z-|0P`?xQ^xM7{oK%_>yglqUh;;Hw}(FId;6pm~#ZRA#RxM=8it{j7yQ zm7e)nFt&%PVnBNiX8aP^mql>_?t*Y|o5bT1c)kG&;ZglV1-WvtRPdPhJC$ppcaVB( zs3a{6`7^<@W!EfgD;+!A58L(!U!x7c1@12V1f_Xb?GO7qtsSwFOOWxL-_$|qk>6_V4iy}1&x`wP zd{C-NP9;x@=*R2N6|5J)JzoIz{%{a1%-kC3&kLMZqNm1ka;wJf0ZXi5BNDr*3-o6p zQ4e9W_h73*CHbrIXcW1TS=Y*VLj^kzG2yxJy#Lu@tbE-j>NTQ~Vkq--w}IOmv0Q6M zs&`)v9a20VHp^idq78(0FpDCrDRj(!AIAbVuJKx(_8JSDUXkAH`g=1Ilu^-cx08lf z-h2b)m!T3R-v8dr3?AESul4Hc>HzVnAynmTwm-v(s7;uxxf#D}Mp65EIAa8~u6(r@2EL0>fb&%K40EI3vT&DhB z%~V$}t%uSuwC7!qa)t6nSKf8~y`QV8DLl6>57nuS7gg21=f>sfxV>aTwOqV$mYk{c zJt^*sH$y>9aI>g@(xKnQ(_W1==H9KR{IC|Q${x37(W|OvHuLZX%G7%Ep4Fx|ZL<8V zg_gO!!7{~T`@c2cGP8%239BCY$G|fnwggjM9GK_FStp$ai70*Tzk%zMaxZd%8M z8Z2U=nA$)OHRZ~Kc)cE`BIBrp#DiNETh#Mvul0Zx0Z#>!+N^W$|9{r?=K$l`7b-ZB z4=BD~?$^;bv;8!a(3?6pFayO>9sQrE$Og#)%47UFSmjuAK2bGqyL*9gMi zb*O|x`Eqy?Q3a#d)}PffcUgaLWAC>2yu1X}Biu4-W-Dv2J>?Z~o{cn*Dpx2& z>s1iSd%dPZ_x#gUCBm7LCw=nBMqXB{3?S6-dCru)>2kFVrdkjx_|_QeUbX0H>1*wR zW6wurdYrX;!%h^Ls-|2}tp;V;s%8Q!A9zL_Y6dgjXi?h=Qo-C?Q`N3ucCJUdWQ50C ze=mts#2Hn6v1VIUn%?js|S1dV`_7^;ZNv_AF4=vUWX`XT8_TQl!+Mb^mkK?XACZ0joRuj3XN}SAB??^WsF~HA6x1rrT9EVz zPM-UYI$#u3rDRebfsmgY6DU-b!byNvg>zD)U?HyutsI_esKhbJkz#$Tth31XYNR)H zczGloZ;YikAmSJr!2zx2X|8N!~7I=9@zmR$|_j#U=%uN8QC5J zrV>oG|Cu{b?#GhMl;?qx-KzGWc(3m1nu^%!gWqj@4 z*hL-$!<+`yuCed3H*~`rT;fTDR5Iql?8;1~rZ!>UXlB4OYu{>L)c_bvFjLN3HE9?J zZH5Vt@iaV7d_J43Lz{>AsnNIWx6KHOY8hJAyh=QIDxM;PdILj_t-nGpJ^qL4!}1xU z)?X#@mSD)74f{PcF9u%!yYO_>`tupB&W4(sDPONbSiJqO&VSzH_F5DfTs=uiC42mtxENpL`YeC#g&UjWfvyS;$D!#|D=jaW} z@z&pK87bKR7(vxmC0=51EI8Bxf(QRwX&OI6m7McA!3=(z1hQ?Z*P>EYUTyy~;nAB* zt%ysiugnf)9uwR4UKN?xvp-f3DAkhPpWc|% zySkQoPIi1RYW?{cDe|Xh=dITN*!l0h2cBX?O{kn9_uJY^Wxk?}G89yMte@n;h74bL zbD=$Q2TM_EJw5e;*RngW_v~ev9^ph8=_o`0W3YFPAmeFf?}B!ym)C<6t-F@T$W;N5 z4+Zuz=Jl`jf4Oa<_#ZW;hQ~&&y`PFiqpA$mTUU}yZWD08u+PbZ_IUk|ks@pU6MRr9 zsF{g;9#Wx9Jv@JXE4O5n!}2I>;lRiMzXvL5W}>Z{FRh4Ip81wtQ*Y9r>ZPknjiqDW z-1%eszqbBdO{@K)P?TdxhI&pmA@^z`|GfSln#$|1_H3>7$DdnbAtyDS zBcD=9Dfh^l`IxfqZM|yHEB)0A>{ZSTsoq5{z&CGuc$_5EnBQIy^JGqnVCS*;6|$iE zN1ng4`d$yN_T+=LSN;(b z&+E@RUXO*%2d7uv@pLz@*KQL#W;t^bS{%#NK2q19DnFa>vYVh<1LY{kh?lqip0uyF z|M~3U_Jp_RJaoXumg0tH-THV;tt!$~5qfO@D`}#NhrIqavE(Y7*Pqvx&rWtjv@KI_ z|J(I1BYJLCP9EdZW0!KaqM$n_qA8-4f{bdGs>dVqGypF zwjx$0IUa)bv#dWCUy6{Z5?=3JzRUW13Lmb-najd!+tw!5@Ygx$@bn(Oa5Zs@Upmzf z<4UGh_1A{VsM+qG0gYnt^26kV%7dkj+1z^Ub#IZpKwGn1Rn?UTuhs~7-VhTdLdlFW*A29Ti$0|vRMoFtOuLA7GkX;wLnfYFLsf${ z(+CfWRvP7U{kEs&Nu}-rSt*Fo8!_k+?-XNMB?EWy!dFOvVpOZjR#iZpI28uH3dY`C zamBDc=G&|`<*`=4-KldEfg`#lhmo|!IIs)DpDoK z<+Hr?=kcB%_d)G{rHZJTz<8b*HG?BndGeTIb&lL+|8pUv0x`EnYTOs^obz}NywA8L z!U0P$y*=3?pA%(z9P^c|(n$SYZhhALICvUejU(h09>><-;}O-2!qj=K*53>0D(U2y zsnDm^3jj4(n_ZYZn!PuNmZv+_Y&eyahWpAjJII>8*<(I>EJ+2oDOs3ZG)2g(4ZZOQ zb9d!8C@A{a^F1boQ`hH>ZLRhB8KUMx%QKS|X|vJLZ91gRj-sJyQ`6#w^vX$8%A0>^<_Xf?7RdoJWxLTo%DahE)pNEGizn~$K2KF3oZZ!= zT{+#5U2>X9{bR<^&#-?R(JmS^ixx2kVE#4bpiw=tk0G>4JU|QGYR;z&xoxNu++3J502!iPF^L>%xy3Gtf>WTkn#qM zaNpY-P~%C$YU|I_thiTJOX5`3!`Ze??rOG|HKzNq%-8e$S7aW~G{}ysthp(A2!l6! zz^gtLnT-9Vl>vx?9+h8$BJx-VG_IuhIn>4#tAvXQTIwG8{jN=JJBHTPo;{P#6r#fW zrHtoP&r%KH@sdDQ?RjX6T7OTcZqe7;fGYM{=OAn+j&ZB%f6Vz`Lp?p6HV;5Kw*IxT z)}F2TvGrH`UuoIdw%Su})YkuiG@N6GzlW{yqj31)?9pgA6 zjnh<`>sK3Gzq-QqYKOE<82f~nTbx~=qrb|Cf3=Wz^1K5+|KE4Yo{ z3(w_CRb=+r9s6ESWpZr&xvKC+Ju11W-TxLQXMzwDTAAd;4uYybt144fk+Mk;?|)Bu zz=tb8V{R+f_CJ&0yaZf%(R+KlhM0Isol+Ng=ZGD#tM-oStrsGw8hv`p;KV@9cA{GC z{8#2P-asx@rLrDfnac1wdF$_;|Hmf0u{z+ceh9VwU-LlN|Cw3tN@J%E&~X@V2jAdJ zozz3)Y*0agHAk*v)4>j83}ZsS>2dw)8r$y=h_71Q+nwQFe;?fkCm7!>@W~H8#K~Vi zLv98D;g*At$1L|UGZolt1TgN$tMR64c!q)rYx8`S2A;2lozZHi~|5-m_HBm%ak)B0+4|K`?61v_jJJ- zA>6K1kj(>*0U25M`VkOAL>dxy+b!Pt_Pcnic^h%vAR%F!6JGZN+IJ(`Rf8dn7>D_Q zLfvjq!6wHTj~;YwU+`lyx;@g7@}%|%czp1A>#zDfJo}iZV3q4Eh6-xJ)iFK*s|q}1 zLRB{&G0S6_Dpbmo04XiJg%{P(1{DC|P}$Ex16Z7tN+U!iozT2RMk zIMnvPeQq`W5C7i2?_EdEvi@Dy$@RBz{BF0~_solIOF_}<-gy0MLUAtA(2?O*T<<>|nW1+ZhJw_0D^%LZ$#b8is9 zu~D9d&{i|RP`$?Tb?cZ^>zP@7x6+z>ePr%!Dqm(b+nXy8ukWi!TuOSUNJpM|lD8IW zjIA0h;pxmhCbiOgs{rT`r^@;(c-+(Xmai*lSG~79jZ5tjPio1NvUp&Ww|98`3rgUr zJh)P<4G;0wU!io0@L3})dL%RpU#p~r$;!vhr1Et;$VC+kj4;~Yx!dhzVWjrIwSZOU z+OhR7``;EGJZIq8`X8I0piopVR;YjOI|xn+lxxOOzgq&wPdNr9Z>e8wV=f3 z%Uzxavy^K{Pv7^q+{w7A^7uHG9BSXo0*QN5$2=D{Zytu?N~m^_+W%_G+c7q^+W#!G ztI5`w9H)Fp)cSi|mGb#^|JUX>SYoNS{uU)*QzQGX)z<%*?YX!9s*3m8$u*yOKL7ch zyFDN#9`?``G<)E0JPhc!JvMKyvG{6-hd;VN-zIGCZ?HQX(66`Hop1Ln@r()b4kZHT zJO}alA;pBrh(H7~5|F3goimUJV1We| zp+y)n^4J5pnG%DT(S$fb{{e_0AOmP(Q#}Y3!OxQ;9AhjiwRXWh7ye0L_Kd>UoA25cn;oB5pR%+3Q&r;RI`1xh=iwOp5V0U zJ??is(vUEWBXXKv*ro|++6HacP4BO%% zXx@J|peyN_4JyiqT=gJ1L1QkFH(#5jjh!jU_yf?YRS91c`ON8NR zRcv^6zI@)X5m1dk!RyNVzqbA!nV8?B(z|D^z2X|F_fnw*we_!&N>zc!>#tf0Jj%5Y zQkjdkCmt&J>=w+MGE$m*8+}4Iwul*6Z6g*xTq7gQfqagNunQRxLqHd?ucVPDs64Ja zgk=M4Gh)*LO#`Gn{X1m^b0D9R1H?Fe{;VU<3HwSvEQaR=p<*_-H*SU9XH4pci3)L}Vh&QmJCaWud zw(zT03D#V@JmQi1on9hw3}&t=EmVJ!4{^ni_h5g|F)`;nc_^gGGhuVJ!PT27lQB3KTxoWZr0K1oY`fnzW+4IAj+Qz6FlNxJt+*NCp8UHGo_RMK) z;b84eJuX05lfti1=!05+k4VbxFJ6C7y<<5dwf*n4eC#t}Zh$gM`&rI^&lQ!|Tq&&f z0o_hD;=aoM0fm5^1HuSIM5Hkz@6tZ7222*RIYkUPB8H5FfCQk85lzVGVnA#ILIz?R z5SxJ5HHZlaxj`6b=pdx20!dRS&*NO8w9Qi(EuUcnqpkJvGkgnHkA1lO=%7ud2=3a3ytMDUzJ`uByPpvODiEx5+~ZK9J*T7@@U$ybP_gA%>JgaGy z?C=@mwL_SXp?Fk^ILhyfO$zs3?h1}Ocxd|yeMCY=_^3e|GV+j-`wW5^iWDOP7p!8gQ++%-TK zfCPjzBIJp17eWK1fRGXp5<+YdQimotXvYPb&>@6~7$*=R2Otk4@-Sj5_veM(qXRxc zgfm7JEIkdYf@W&+25;=Em$iCqP9=%58_ibEirl2Mlgg^rv;3`%b5-08E03um3p{pE zS*TjpJs&up{LLHip?ZQfQls}?sBHXT^M`<;A94L^gO7ju3Euzl`*{76D=fZqg6`!K z!w7uRT%rBz_YEJJ+`tZ(Yoi zwSb5T)(!!PO+<(jQSRz{*I0ZtVU+{YIQ71B%os6ZhzYv~3E^pr9P5UeRMTN?{tm$%?_8(9snbNkLF%|9)R(1D1E8cYxAMKEX{KZ zJNAz!v8hRC6tvHkm||C|>r?UxFGKZ4*($hEZEl8BZL*-uKs?`OOMbHOBd?8Mj6~wBNKF@{Dex?l=wzZ<Bcb3})tb8a3vpw*KVc5&96j6*N zw5tEBU{>zKd)@~Yn&(Q?lT>-hzHJq#XU}728T~8Cjg=R2!m(T~4-y-`E+)v9q{H${ zY@p`(>*X^n`lF`kDYc9ZysFQx5X9YXcZ+bSR4@FQ3ROI&RPx?e_VG}TdJ1u>4ejDy z`!Sci1IXR}1rtK1!zE2R^f4p83CIcP$AldQjB$s>r_BF7{bICkI?M*;x0`C3FB`*Hr1;#j4;Td_V(#JH1?(*=% zL~a8n$UIKr{WN6sVZbiz@a8|?ATQ>Z_oJ{U*o7|6%whA816*iP4bbp>w`+Z84?6eQ z<=zZqH9KDQ?bsrf``Mn4d(E&$!IpMxqB1OEro8p}=KiRcDSNFAk7rP`$E->HRC1#{ zr#<-A-oH%-yh%z2)yM49kW#|&;tT)r=O&V= zBM-6+=5k*}PGqmolTE3rK_!LbINlo3sn)-IZb1gDX4xD4X^mHyxTt0-sJ^$CfGU(y zL8@Fy+vmkbL>6{eGD`1y6@!|``m#E}gK6#ai81cyDHJ)GRRVaff1C)~vxA4G*!8zl z_v~}sZnp<#kX`@svxReElYHA!;Dpqh6ToR%D;Dq6){<^$L}NK~cZt-msx zh+(eQ7A;yV@#ggwc^uLA33l=@t6zh^7lbV~{G~7LrhYN0D`T2!*N= znOV)~1s`;Z@W}z$GVXZ_m%ScF4w-qZ_$>AvVmCCKL@CvTno*$SXEmuM@3%v#(d{Hr zX}y`>RMy4@L^gQhy<2{_wdCGzw+HWi+qQeyozFFuV0r%Y_T1{a4$I~87HOEzLbd+< z{;+8kKOe4uOY+h*&3=Csw8l%KxwXUm7R6XsBaoGs0`GrL%vcJjq~vOjynWBxLag9T zac~0(Naf}}j>rfYb_qR3?DBwj{-^I@xSug>c1ST}2qO>!LKx?8ZeRAvNp4I7u3lYX z`^gqfyP5*^%!ySX~diBE4=*p6&?)t z5kJfbO+p?gs2yPhhG9Y=#)LGENMT9}c=Y9672}za17&)m2$?KjvWKM&ZZ-&WTSlQZ%9zE|9((N*URR|#_N;en)7p5J0wYnD zxzANSd$?PopREoHV#C3xv@~qMvOJtpWm^t`eU3F$%eDrX?8XWJmWg@$zkDtuMV9ng z?pf`L@+|wlKTrWEZ}!@RKh@$?Ej`6O^7gFP76E{^X`1~Y`jY9fb54P=bIxe4Ta07I zI1U)Xh~~1z!++}$QqCBgjNBxoJVD;DtjBh~nJ~XZ+W_<#7-mUY2osrSX3X!UYiZK2 zr;w&t-pqRT{R@$iinCj})|`+-Mnc9g4oKGn(9b>iIF=neG39drvYyGVdTSi46?@Yo zTBuE2lQ>y8tyUc?zj#mT!P&JMj^ZT|o*z3K+$i%1`}MM6R7=B?ckm0$eL2rYQ#~8o zTU9~Tlc{)GZADJ;7~HB~sn&m=bq8R%Uf}%k3LoDOc>S`+fPj7`q4wx8c02ssUwLoe z8VeD!N>lJ8uYcEd2h8WYuD`8r6ziE=dhFNkDH_x)07W<|Rak9cP6;+$*CC~Z&1NHg z!xcBiBkn0Fs8T-Mb^lwazEq+N>GOJeV_TJ-u{RIB6m?zK9o%bKKRYSTYP>mcsWGM& zB`F1D+qRM~+RS(MLzn-rAibc}<-Xb&eX zEyF0!i3SFpeYgI0ee)%>p@vsrp66lV5p^yavWRAjK(&B4T!i z3kMde#o;RC`S414Z#)zBTJ|)N)+UqpeV@DQI*e&Vj`K^D6Upl0jJQvKw?9b2oXt-k zgfIdjqzRS`?IdxF5ls^j;~dbCX49E^-}M+AuMS1qr?NdKK5&^K%;qCC)_BbZRLRZk zOH+gIz22#3M8lPof&)1LP^?jAy4&iT9o^UkO2J{aLRS^HH$t=~U*yU{AtIhBj$MEI z=NRIY2*-@ePu)ZQn;BpIzx*k3KVS#}I|OXU9X|hSpTgo~F(=Hy?f2TCrldcX$i@kp zN8<6?N~*o&5iAt})qbr68@uM^-ncKy!GmX2Tjuj(vA9LbwC|KMm#LW(S^1hmzPM7h z_h8!~MdHt_)(C}zCEF<5{ci)B^)TT5 zuT%y0Ot2)u<#M^dHa7HHEEZTS7Pk_>-EMb~juyMC(kiBo~vsg1#~jq2HXXaiR^%$h&OZuVp}3S#Eufe%jeD`;Mh*vLmc=+T2PA(h# zJO7(sm|9Q`X77bCJ1zR7a1|?8^?y~X!h6TmJFV7VwP)0D3nqW60Va0pmp%CGd!|}E zZ2aO408uWEUQ0$9(PP@sur{>u- zdis6N_?3O9XPV>nFu8~3p&*{bNx@?^$=X4Wu*@rX5b*RbJ;LK(c?hHiIR$hl4ce19 zc|n9UNkn7Zv*VeuTx0!v)t%B~bI?%^T`E!Y?%yT>TotNbq-t+?GB>5#umOWBP7luX z-oKh0kAt7*-M|6SR@}#YAvj6q{jcms`TE%-z4o56XFH=>3VN@d{XE-%y$+NlO<4@{ zfR_*gw%hGNE5@4f@cUrRmAHpr8`;Wgpqf>*J>yi%j=2uyGYUdrlL*TTDD9cHY#8nZ z98^&OSgbpopPb>vn``t)7(&LQfA~Wkb z^fV21;jyVqj30`8T+Bd529CAS0wP-H8S=u=z+9_q^Faiw_=hjti8kN^F@CJVjg0OsjwOV1Z zSls%$B?>BHn@Ym$8gLS0d+W+_wtV(-xjYzr#ff*TzIe;7F#wCz0_}qqSDzj5=F8W> zGU5EQrx?3oBB8}8N|$OvL4Es&pGvS3`569I^WiOb!0SWVwN{pr7FJc#Hbq|aAW;uGwFjtzso8Q=9aJg-+TRmq zxo4Qno%XzxnIsz9FgY*AfMn((D@1|&%J$tThqAJMRonn2apm!@mh_|;<4RfMsVO{- zc!NsgLdu5{@vPqT-=@=Q=NP*%oxEg^*hGJ>J@KR@SNgsK@@ zwr+x60b>zFm9*HsZuh?;wR-!XA!XHXR#OaZf^V;3x7+P2ciwZ>5}1`1c5Jl0MvDfs z-EYlCmRlKoUz`XtFU8(xDa1o*1E`>MYvy$Z+O7re0q_0qp5fEiEdnCOZp4^pq8euZ z^-7k?mGl1Q#z`_3%ed7LC*qnJs#b{Ue30^i&vtzK!vPs+8sw%$7{knVj}!Dh55O45 zwAb9{K$R21eo)4(ARFOAFdnJOlQOUqlSMSFgV+ISVi&n;sAc7>8~OF~)2?(cV=o|xx- zVFPg!n~C$1;a1v;1H%wEs}k6MUdeV!&s@3o*~6SaPfdmM>^apTT_c1l>1WN5N1c(p zzdYo}66ut#S^cc7&bg}RmWMY@Px&q=lPfhWMv>~2aTU)w;H1VPJN$l^wc71=2k)eE z#kBt|0ooGoSR2m?g(CfOLd;x@aU8MR?QRX{u{OI(oy3WZl?>(r<<~M#8%$!D+}U!> zNULGuuHlAJ9&YGnN15K`5Z+haaaNF_K;5&IYnl$_R*HOt%wDJ~UB6r;6lIBV+CFF_{-| zO!L&O;ij^T5lw4Iap4Bp@Qh=;dEXqQrbO$evJG=$XAcks>ndVi=>zW%g?WzdE$uk+ zt*YB=F^t1>ZNoV1176ckYK1%&5jyLb&IF3`|Jq%L0iT?^OvsufLk3&aE@+9I1%Ab}TT*nZl<^Lc17%7cj%T2bjx->1+GRm@&?uKU+j6xRvJfa zueaE4b{MujcAFiB-R!~_rX*syT41qWVs*Mg+ch^yMYxTW#1Qw1N;$Bnq$M3D5hJES zJSiimNekUBI<$*!3RGdf#@Rc(RB=-tmiK{R#x*9xo;2|x#yJ>H&#%E^wVV)+fPG-* z*3Z5thzV96hbf5m+aBBN?IZ(Pc37;ISgn`)z#d}6*blhgY_NH~!S;GPjUMd>AOy5+ zgKoLNYJP_6(-l(J?t}2HKIlv|+iiB(UQM63z20HB-R%vOVvOh(ExP$ymg^$%V8me3uy_Qu?qpxO`D_;a9RVs2OHq7y)vaA&FI36m%s%!F`&^&{u z8u63=VT)b%byo<8-T%Wd>?>DqqM3#F3wcakw<88(}Z%A?6_vDOP zjZzFDOqIif23WVicQUZu0Yi^G4#;WTo6(FhVf%W6{(8jj^)+@^J6vCH(QkVULyvCP zpve(f1f(SpPg|@{R#=~`u{vF$TefrMeyG7$15<8QRtOmT5o14~-}czN+2H!s2G>{D zQ!v`?Fzyo22XtM7unJh7by%IQadN%J@??e8=^EW)lHu8^-9m?H7%}XI`QIMnFk%?S zDWK+zv7dbV$2=m3gt%&Pe(xM7VX9<9yzv>&a~9igcIbBl#$ig#FfZNodE?%3X*UkY zA)#9?aCZL`=OJL#tPpTWE=qIz0~zRd6N7UcMr=1zP}#oT;Ofm5yX^*{4LDhy;Qpig z=(=`-&-)RnAMyI-8(h77gEz0QvAN!0x7lIbjflBH7h1GuEtU_KI6FN>zdghH>;$Xz z0$~~UXhKd?);#nBHg7h#dNF<8n^&)~*=#UuM}#3DBB1Fay7dyvizQAkPH=K|ij&h5 ztWQ^Hy5<&pnb$w3Ndh|dQ$?JHaYh%$DH+-JxW3-(wXv~laB+Eoi~by^_s`IF?LM(q zkgqy~%JUx6hz7Z?16tW`pZD*SLCfg?`tgA9{@ah&Tp>F(57?nstkA-C?m> zq3c?#PF6TOKgH?A8R9ykiOsD!^0u00o`r|_c(c>X*O{=yE@R#vR0J~nxfcHR41_!u zw+G{^^;f(cmFOvgUxCuut3h!!cs!~nIa6|7CVnYdD)TfHFUAXWo ztn%)!jqml^ER2A#ibt8=sDN&hPi_s^pRuq!6Hv#(f>-@26&L|bP+z#2X11?HGh9cq z+UUqoh-V=n&Hc@WUmyfDp}~MzO3*~9?^D^+&8CpJGH5OMb!Y*Uik9fV_VspC1@XijKPrX6E+u`Km z1gn!3a@S5tPt>p@&%Mqm-vshk*SLCljn}WCK4tlLgLRo?`j>49(REa^E9$ zR~XKE?4E2f{L+AvN8{9~STC?xEpBDV0h1+ee?8#p)oZ+Z`5K!y8w|VoFdWCJ%AUQ# zF=RBc!FqFwS645w{twrO5MBnh*IR5}U*q-5D{QW=F%EMznI^|Tq^Vsn>}LP*At5vk zPIf2AFEY;mm*=<1P-#jb$01?d4cJ_7vANn{w;8b8_PBm?jqUZ6Y=vFG*^kfh@(T;@an}IT)%jO@JYb>gA<&*JVEoK-6J09JYjcl zi{Y~a#xITtPcuTuSe>kI4oYY_XU-YJw#Vkp^?c7e^!p!9)ug(}bjmis*n;lP2_QGLFjFUTyH^C9ovYwJ@A!kyP={$c4 zYciv(L6yBPn>I1w%?38*k*-F@dN8fEKCMmMQ-`%uso1qre)ygxELX6qRiIQmER$7< zgmsluMp8T=>Ho*sp9kBL~m;ne8I|+g$xR|6&G9-}< zGDI>=(;-?6Dg1~3QP^RJ!{Kn)VKTxFN=x%TbqaAXj- z-NQM1+_DcxFsbA&9*?GEU*l)hJN}L7YsC1V6lgP*n8eA^^Y%=(&l)u429;7D8beR+ z%Tk@Q7}HJ7rN_rRz~E55Vw_7LMFpc-?HIS$c205btcLTA4_3lLEqArQ`0!eIBe|;>6x!(n>Hbt*vQnP39!UI>&4dX&)IDU%8_0^i?^@?g)V%D0&$44AKouk&u2Ou#)iyX8j-$=4+h5kU%{%b?^ zBNg%sp5ElFqm%aDw%|Juv~F8AmmBK$O5Byl4-{2~Fd4!@u`WWkDG*vBYlU7q>P5xn*(GoMq1Ta04Q>Cv ztD&2g_4S6;)sppc!)8^{R))4T*xE2VpK-jp#q3#uUTEr7gS+zk>GIh%=TFYLKD(y5 z)EqoH;`HeORKh10#^VE=b;t_DHR#{4EPic`{Ar1J4V01?ZT+)am0Ul&=KAuQ_2ruE zBgN6PV~VQ@PWvjlX`4>27-R$P+@Zf|S^Uxx`TG>=jZW@XfXda-jo8`84s@ews)pso zlB=^zHp>cKx46b2RsywA0zaC?yEhgX&V+4P(@*)X$_k5aH+cxRg+Gci+8_Nd~73arRaI`x2}%nqQ3Fh&uwk zf?fzVO96CKa@H|RC?%UdhFuAhm;P6Z;W2jo;XdiFB^#6O8>82ZWvb7+fv}aJq#8~z zYt5F2E(D0ogVOry-|kY`#uA6P7VR`n!PUhTPai&Eakgagof#+Z-bQaMRomdSL*g(4 z*iujo`U#HqUBk2g_>%lj=g3T9TT8j#u(()oeX+z`XpX;ijC`uFjiJ=#(2c(1bZ3<0gun`gwu0*COE$msO@7n={mXu?A5_nM@C>gfRZ*sp&8grJSEk{C+N*+v zAhR*>)mUYf;!=;zL{n6yFi51h`6*q6R8g`|J0Z4Z9Ye^69gDal5>|^bC@pO7rq~-P zfMDGDNO9If09ag+j}?{sOsx7}A?iP5LB(Lpn72O4@=CN6=TUVkd;N5wyp5@|p8w^%>4dcgT9 zpZgT#dX+mj{Jz8Bz<6%Eu#QX!a+!0zSWrKzdF2;hDWya;9QJdsWhGY8;Zb z>^4Y;&K8~Uk7*4x4O*D(+}v4u5nWYe%;yK#wxKR7G=3eG6aZ;JmcO)RLnf5x{!2k? zEsb$BjiGTZ+<`nV5DE`Aj1j^L32B{HPisy3#CP@HwN)`Q*3Wy#gq6_;n1tglu~e`CVr+Y`*H zMz`L4$qK{l?hGd#S*9?TE%iqGgvd#ZkzfTvNRXzpVsJF8ns5E}Z}Fu+_kG?dsbdB7 zfW??P7ayq4177V@Fia%@W8y6_h%Ns6Ju*73toCU(#KASBd&X_|xV=Bt$xA6j#sR-a z?^jiIqop6xp?YPpuvI-KT9s-A#~knQ`Gs@**t{wX=mURxkJ-^!5KnQn$J8q0sy_wJ z?w`k4f*B&^d5MO!tjv@L@|ocFIdBJdV*~vsC*j4&?C{q`(d#moB9aw?h?h z(aWYf#WxEUy`>EahWU4#<;0eDu_Drq4I1F+odaP6!hsSwpi%!S0dt{fAX4z71uzTYdwG-p1UbNT)f zv#2}MJ>mW9W!KPg-a)U(1lCDJE-3%|8u1Smby?HO7L7&=%k=IP2UJfhPgg?$3gaZ! zY=bEd+{$tJvkT;Jcht*=e^GQK(3HvNDNu`za%(`w3bXrlmt_? zeDMEzmrwq0KZBSDsN@|asK=8`59i!|NwR$9it7CpdaeCF6M{^35#RcCuvo0TmU2B|^WWpgW-r*39Q7udbu62mK3s@aJFm>3*6!vnXk9#a|#DUpzUvca)7z?jr-Y&4W=Kc_hFG2L%WQZz=%_s=kF8IRG( z!h|HIfrS>_vCvfie0xEfvDSHKQ`rm8Y_J-^MI69W_P(*-L27gq3u}2wso4hflmSDEo)GKDrWB)6G_`$7T>W@gDcO1qsGsgW>Oe0Nv*lKUHK2q*C<&Ru8ArBKOn%vMaB_?*puJ}~{M0FjZyuqQ z>4p1{3E9~1Zvz?$poi;wbv{vj@~;U zyOh+|4V5jCAJ6&Hzx%z2slaCVDyKEjf?l?~|F_;_^~=kSBIXkdob=z9!Q=n(Bi{Po zyzS@cJB)?Sf$lg%90~5eFa<3zWy|Hyo^$yRFFor(2xON87^Bg6xlv#Jb>b!hFKChp z)Lb#WHRHsba<6#-*ILZ7yh$qpbhpMY9R#qBm^{C8DIWi?^jN{3F`IOC7g`7+5#BuzILtgma7r68B+sKIm z38pq&eDi`2|KUUG4_j;p6qKF3sucp^9M!MY%%?N>ilVG48rh%=!^tO(x%`uVVGDUVcWj>p7 z^dEkn_Oj)@zx8dN{la5J<-A*+20yXIGq^UC@53;qccE zX%`K8UDL>lyFd7V&;8*q_&t(IP<`d8aMJPOkG#UYFWzVQaK$(N<~Mlu%je*%w_?Dc zX>k*H^T*#Dm=2-7K|HJ7S8<0`Q%^$*fmLHPvrt7Y1~;YDB*XKh|DG^dgn}b+2QqG} z_Vebr;D}W?Qx#))oheXb3VEKYW>ZN+>?9Y{v{G~Av49%#^JC^gj1?Fg8SDf5#p@qq zCSssl%FiKWMTCDpMbi!)?qc1E*y%28llSYNk}^&K>f%;?Do)07!g1mdj~I5G3HQw_ zVpMDl(~o5bQ-F~aIwW*oskpwyE(J*CInapYhTrFOc0>H3yY|L98r$*aJL^^> z9N9!dCQ)y}@%P`x-E~y+mJ7M^pJlAC$fZO5{u@WmkaK6|&@j1dA?`1U-;SMx?V#7x48z}-?zfBT%pS5~;H>x_7JU6f={ zHnY8uPj~Q3DN#<5%`)bnopbt$Q|hNRPyUC;oc-62!3s>LTyCtT)`rSzDyuOw!||t& zcD>wWaYlBK4NQ-NcMf^shhJj--hyxa)o)XMyF^NdbHdm0*598{f{*_8 z2b_NT7Gfp_3FPezz1MS)h#ZRhGm85&KJm(@x%d6|`Nm)Tb?ic8T$dtpKr&(E>1AUR1V`-c*yOKQSqsD@8|rXFM7;m z2(PCP{{7Fzz}L9Ty^nS`rVS9|C$cQt^3YQ=^07J1e$={4Iy9v~4bD2W>4Zz1598LF zPTSQD2wdarj%wFfrk6@UwtnaWCASq&>p&R`twR`#5r*0{-1*UaWIr%xJ+H7Ga=8@- zho4D0EW%2hQfzKDsNZvdP@3i+HORgQu^w;*0{f9h)eY$)HVjps^FE+)8@ zqp2H8Tk-NweT>N~bJ|UVl?In}9`n{=b(gIk!Rb%kVfC#Q%U@UwE$|*Ye=sXJ`^Qgt z?T@~W>rno^K7Bt+cb$Z2wP{$bSFAT{^)W z+PBto&6_{<25nLx@3n0^ zP_O!cl;UQGz_u_rrv!ge0yDjWTdF!8)0|HgaASbEuoWLy$9({7nkMOMkg|)7=iFgZ z5q4zakwpk*8%yxwpuP{BnX;hXsyYTO_jnGG+U(&bh+n)h-r*Q(&;@NmA-a~9v&cbC z){CoH4Az-IF4o;}OG@#)V{PAoRw5kIX`J)EXaeCBf0Lul4D4Gr8= zeC#J)_ti{hL3M#zfXbu~>ds({rK&6DzwMCqudWcAZiCwnL?{&HA;3OS(RcV2?7 zt?snL)CSvHGUGle3d8*`+~JMi@fzw-P;Y9S zwBCg*_u#Z#W<%>)HyWc1_kQnfuD-J9Hlypi!&oe>)x7yrZ}aL;yzDzP#($p31y*ix z9u_-jsmo)<>worje*J&_Rc~e5X(2%Q_CFs6@Q}OQE7!$EMBl0pzpuA-4uxXk zsxrm94wHfqbspYRh}sY5+o9iiii#FjvHfg21m=you7%egc1Plo=$N;CU%{r@?$2BQ zl=w<2aq3m&Qq_B$=%hH{ahpC&0>UIHE;Qpp_<3eIV_?300yOcwJ#-m#&iR)6n5J%Q z7?KLq`)1hj4GfuOrw#9`<_>6O=_*FM1q%sx!;&?gca4cBq-JWuIkHZ|tnFk3m*r zbace^)j16w$^POGzl=J`&=_Pc5t&4xI=YZWDuK25N>V%YktKU0$9+u?@}N=*loG5T zZLn(tGvDeS(9hikdMaD@{JRRu!{)oq-vv0)YqR#1W|)+@t#QbXnTP2BaN2qQ8|fJa z-V4W9*1h;huTs{VkqqV|LJp&Xy7Z{*&AKEjBo5)b2wnIUz{#5@s9Or%YF}Mu(znw^ zcaQ8Qdu`j|jvVt(PuYB}?xqQ@lOpzkQ0CH8^>VPnAv4jL5e54YFH9s5v|3{i;qd#9 zss7~(C8cLac6|_(fR4;QJCrNU>p%9Ur$jk}Qr`5!I*V=Xjt01MV6{K!c_85H{WEho3#~I$ zPfFa{BIjzT@?+Hf_TRqb>$j!sXSoQ3EIeNyJknXZVGUCpVS0aI*;ABk0Er9O2DmPf z3ji=W0Klj%20}Q2X)L-n-dM-Etz2P`lve_Bzn(&QFr|{}h6~zIFdN7YB$H3%lwWT= z%c7GSc3oxNEE|vxr@XS^4#+W7N*v65EN#<}y`8}?N>rxEoj^K+aSA6K^|J~Zhn)D1 zi|icJ;`dHTwIzC3UzKZQ2O_k+wr(#XKa6!;AouI937V><+-zvC8Yb@-=*H4in$~I> zqj}+-yNDb=GE&>tcs!GheF&83=C%r$uw4t;=}XJqsycp0W8Lbpws8uh6L#yu13V7i zV{_;bd=&d*j|Jqo`VA4^JqRz=6-Wi;Fj})t#|G@Y|+Qo*C~^m6m2aIkbS}s>JFqd1XAnJBiWw^>>lf2 zhd7J)K2jnzDed?0@5iI>)Ci#e@4mY-1oRXbA*IeUrp7i_wTB4$Fsm9K<`AGHYCZ)c zaCHN1jiMKEi!vW6o-1l|1NqstmwkKGh5i@_TXt;_9quYAe_V+=RsMs zmT6OLtzNsTX7%l5=h7;%z5Z@6&-Vj6kROLP|GiImD$=y0h$)YZ4qIEp^9{NNrtY1S zL??ak=epV%n!5F^R~t6W$Eyyjd~gw7v&CNzlF9slEH6CQSZv+Wq>wk~>0x(7bis9i zJlYQU*y;2SNroQ_>;&Bql`FdTzcB+puulfJaLVqFl%J9Jfw%8OgnMs0DsX6RkZ;N^ zSPPFHcira+$>xclg_Cvj>V&yUk4@-19Zp03MlsCJvrI6V&Ttd3izUK=(0E#xW3M0d z_CPmS*Cm5O_)f>rAMn_UK5^Vx6XCF}rruOkWepDBVDeibm6m1Nw8C$!i1cdrz zsZYeRI8)uJ5CZhxJ}K8!dp%V(4>u@!UuS_3%C{pArywQn5^U3S2XR1M3z5)p!vlEi z0r%CczXl)DR7WdvnM6$r+QNEjud`mcPNaRRL$0b29&jfd=vx-I@Q0W)0*Ay2NiK4P z^}*uC;nJ0>!h*{M>Wuv_CdHCJ#Uj8vD;Zn^M`%Q*%^xv4ii}TxNDIV&{OdU~@xuTj5sz zIY}jvg(Q=T=CZ;y)^|X)hJD|M?sFXVRo~Jk&R{SZA?G)uJ zWt@=$PNfdsSUD}F3>NEiq$pG=knuiet+;B99mrzY&y=-v3Y^vl@jl7wKc}wi(b;zh z1dMs}srmZY`5*72SSTe7ZYdL$Fo^9#)2FCy;oP|ofGG`x_)LrU&X~k(j7NJOcsr)y z?cdu>o9p2+&bkjD+I1Xh?@>LWUWQ0;J^y8 zX$V}idocEa*lIgeKc>|_pczZOZYZxel*mQpRB_d^7smJy=X?jK*JlvUAn1%wc2Esl>sG|BJE9Oi`D^MHyVQs)4`#!dL5%45 zg+sD~+_&n5f0$wNJk~x855BmyJ2w04tJwYk>H%u;0i2Q-9n+x*g;-Ma_|(}HI$Xu5 z@vzEzUi){<$0B9IG={2|QVvRGaW$AS;Rt`GcUeo(xKhfW@!v^tq~q`E*Q-~W3)jD| zytURlXzqP#p*_Mqq#edGt*I_Zytm@2z7N`M+mh$`PNyUcw&8b$>)($r`ui9&lSxUX z$4OzxTG(eVn_90})NM=$K9zuGsVX~FnUA%o;*9rsbg~{)V};!!q@BTDY`oQ`_97<6 zcA%et)+CW0e3W>(;_u&~u1SHE3MrIF9t+tC!QgeTP1Ie8s?YfF818=vigFvDhgjWx zj$`N$&|73i{?j{v5_VnKY)9|2#-bZ9MAMcH)v9E9xn#XwbEu~XnIX1p>#ZcIW2aRg z(@J^@opTP^_~2j%aG(FYR@YcNzq$TWBoELVX^->LJPgR}zS0-Fm3;T_P<61^9!H3Q zYbkIjA-!gLXT59Lw(f;6-tZ;L^y9-#DG&Cu&cak6Hx>r!m~X)gCk85BYOg1OQyslf z2v4}z+IZVrVbQ|+w5F#y25raWXATE#w->wh*-G27V_&?pzdF#P?yPXR23OjSLe?W1 zyjq`gmMl|PCy*+;Q5}V?*SK31f~!*I5;2%33<@bd^^j&3&uQcLJDhLFNbYc7ri?B^ zB>X;bQ{3`Rt$&I)oRXy-Q+bOGXX1`TEUXgq@Kf{FR00wr{X@=lEKePCvilZ&>hoi; zT0DO3y8-b&?>nt=;TQ_JgqVtO&10jTSXJ+aHE}mSDzn}`1bnsZEKUeyKJy|MW$md;@2@cjb;pZ0gW-sCjH)2*R=08+M*H&Bm@X)S z2(-Rat~!++rcigtsAOMO}(k8D{rIOHVw10Dbo+;oegY9G3td!*n+$I z7R3#R8}yC_>0?CVLK(xVtuRH4zQ`-x=Li7XS$TgP5~`76CG>8 zY=ujFWED!19nDZGqiPIItI@TlF1&ME*wzgz<&<|V!OYeL)zm<@>km_Qec$8f=v&m% z2Vi3d`^=_nJdkNqdvtQ6X-$J^4cSG;(c=Rqk8WdE2HPbTYz~36s06{4t{; zM?h8R#~*gP-a>YVanOlz!rK%B*mDcUVp4cuV_)el^2!)KF)n=57WmIB1Z8D?q| z#I%Jt`?cNSY`Uu0b}n86$<=wNbz8R4q2@+q6H{5DQd_%9he!O{1}fudrJ_a9D2-Ig zYgIcp(AH9|r|rwtB?-c-X!&ahuRoaE_X=%YOWlQTSk_VN7SkA-vSG8_P?aTBS<%!D zZKGl1m|Pc}JUKv~3G|r(W2nVu;BRNryNB8B__S-yimi}MFjEho+dzF00bfw`VcQO9 zd*^!3@-FEUX)zxeI7`t5N71*4LzS9=N9_h&1vb&yalv8U^&Bj&qaR8ye$z#`)Qgh} z;xWgz!`2P?j|(Xh{d}$?d`or(Du(&7i)MU1g{*7iTLDJM&SG`@v&NdynX#1qAW|wr zN?+;AK|p2;;S1RTJ%1k;99Bvqtnm1P?w6E4IcTnGoVNb+t=K_Srx3&`&4>74>DAWa zwstJdoZ^P3g5W;2%CYx9Zqui5LH)IknW~IcYAGeQ)QmSgOH=yop<-LC5*N>KQ@rvq zv6xiw50i;-|A+VA&)DPS##&2V*E^K86sw@Ww{YIxG|i3fX_%yh!YJ|j#pw8OZr>+k zDKQtVHIvDN$z*ba&KKe~!u9W;b)V>j#YA1#JJPRXN_?@1T8J$PpH*y^8jBCbQnE=_ zNs7WYreHHB1Ru|<;+G>n2u4A2&d>IowTN{m=FlDPh>o*t9o0pJwQlg?PEkk35cfM9 zp;wuzE3B4Sr?E<6rNBzL>v`2tgW@?VUiqmi2dK-O1?J3tuUUhtbFm^(XT zY08#zSyHYyY!(~JvZh(oh{iEJn{u?6p`J+Wwe4KsS}#{CT29_M<-zy8fIe%u`a2hh ztV2zA_k8@y5hCyX#=S)A&PJe{dx_wsciS2|R4mywyRkd-{uua?0uYL>sXom31JE6T z>sWFI+lk@~z`YLkXScnAaFk5kAx)`o^`j2qRZ!A@k-?V7CkuGDun@T&ClA}TcLNnp zNU!{6oy5DVi0!DO!wvMNJv;5VXvDEYmk96@;izKUWeANQ7}nl(>uX&H*tCXv)nFP! zCbrrF@mx6$O!50aw*D#lP>kV-yL)lv8dfQB=V0FmZfyO-$}3frjB&@qLq7$4OCjD< z-GZ^AX$-`cs(G}hAyImVgYt2p@DXI8lI&qxiZcyL`1Q<^Gd$Gn~boZQ;7?k3iu{4{8 z)#ZxovuidNYua_gz%v2{G+cT@8+0^;r*X^ z*VD^-8PFa~B?KZg#pt>CH^vnmtxEP|gr2+ZhIYFMDoPS<&~W{A+tM`cPBInN*F)>s zZF%USrS6Svwy!ul%>tyCwpFUjwEGmHUmNE-e{hv-IrhQQdvtf$i7J``p$1%Scw!}knWSbAmIx;Cn1BP?_3ybu*QGB={j6)M~`>g&7cF^ z4KKTr zeJMIrih~~tzr@z6afd5>j=ffUKmSe%#)Q{2)~@cqud1q@eH1eqQhfgY+UvSzI-TwW z(Y9@AnkL!t(OOd!#o#&@w!HgsLp(ALlZDXEG{xy3lQQo2UjMzRvGkZrU)A+lWklgI$K)2OLzu`PMYmCFWPeV5pvhmWd{*VQKP%7a@ z5&LmAKO97z!;Nzmc^(jOyMW^7k#xxHu3gvjavkVKvstXUcydYk;hOpTQ|?~fg4!FK zH0y?{t*Km1ey`xxr*8A=Z+VTw*N!^*S&I>x^?FTHHHeACE1`;QyT1p?btvr{VhlF8 zZ|4XJ@;$@AimpW~-1g6c$}*|oB_&4LUD{fg>rgMbrCg2`9FBLNLXm}^wjdt7cg0b6L zl>%fY(cVX;({;D>ZazbcEqL^)N^8Jb2-v!jih%s*I{{waSZ>?z&L=><5QsdT1ubspHESNb8m3)3K{0STrUK6{F!( zz@xF5atbq$0=K2+y(t897&KDvKuWVb9%+sNr^Y~vyLuWTIr|SWRVj75)VjnS+Ob3; zH7ZDTal)i7zSfkUdjDDdvxz;$WBvOW8=$xQ ztJxdOQ%Y7_jqRpS9z3=B!7r zua_nDMaA(q51B6}nAXy6TAEEmLybO$SAW}Eyz;{@L*@ghZZ%d~obvkf*H;T{YY{?u zm6{zmw(2B7yBEj~3a&d`_(8D6TK^GtTba9FW-dVNyNITAW6ZKsq4X`@?Jutb;D#B0 zY8I3_s6|kY+OCT;47^2n@CaOjnUGWw?C6jJ5dha5p;4@3%X$cr^Uw407E+Q4pIjJA zSNY4Ki=wsZ5~S_mzURRzr3SxvzYon2$cGK(wjKiXw4q4ENGeHIWMo0zlvpzkj9RecD&ivfl4{5|z~{r9J&W@FG>cx^qUFg5O$Bfbv< zHE&EdFV&h#k>pcexT%*fTnr^uS8+&`luR-;=wJua)NUr=70{e@L8a!N3z7*zRJ~A) z5Fj$;4>_#?f$5G&Ic!ShrB@TP_#1$f-oT|hkaLwG6yEryyNe!qE&?94?R40iwm~c$ z(~Ak(7<8p+%7(_(EZY^|`^UbYlXq_6GB2KDF`iN% zy00mr3Mo5t4FalK|9^cJ-N~%_doe@86Z2J5FTHg^uoBx}qSv?=UK`$GcNO%aj*IO^ z8~vYa-QZe_ZrV;cF1T*DZBd8UnF7h}v>Jzb{1!tXwju(9@XHRMF~*G8;BXUuZ^>@m zrLvuUi&walQh~f_AG`Cbqec4f=!AW`=Z1@B=z&UHC;{7>^<=r?;GH>_KYKBZWQNqh zLG`re{3}nn^SOIN_ocUD-6x`xT>lR95?AOc1+Y|wcw_yeYH&=FHB2~S&~8jAimR%4 z4w^FOh=Xv7A0J;wESeMEe+pQfvX)IHJ!2BVV>9;D-%FX7#8#uRwdmM&j&bY57Wo*? zYR9-MYM-a@9DUFm!%Bo>k+2IC@0qw$(cf=B>+V5!F=#LT+|b#rr+ET2O*33)?4cfN z0K`nNl+5zJwN9F|#K_EeHafOR;&xG-rKAw)TS`-(S$2WNB@{_;J7A@hyV@97V>@^6 zeWPjM7!2Za^Jt*8u>9z!{5f8f;^j zJe^>5r>k9SKP$z;Omh19TOAkNqHXKP1PX-gW?XG&+Oj34b^l)k6YJ>UC6Tywtzju- zXAINTs9liHl;ZN6m)ns+KeZln73${lY7m0i@oI}!*bTO;{q@B&y}o7BQxJP>g0;qv z1OmBPW9+V!EQ~5PNvV7_ABYJB?6ocHPXq~1H`fjUS|Q3kq^;4-%aH=vkBF4ZL@F{L$C>84a5Q-@nPM@@Co!nuFS zXd|U0m(tSS850J4_IRcq>z>CIY08}~Og=)ydstzoSOxovrd0QIAI&&!eTTNFDRG<> zV<2U!GS=Nm6^|)8;F!iq?5>s?hs0?9P%1opwsGPWQuF%nh-ca%sICv#DJ$F<92h&S zO(v6}-5!Dll~OxSa51Mn{@gHGNY2p5Hq1U9>v(puuO&GIWbND5#%<^3xG)rnp+GXj z4T(_&q%lNo-!3J~pqTnr^ejg$?z41s2`D(32w{{CW7G7~o8$)Y!N6GWo zud)oM9M*a;R}WaS&LJy-T4o;Xq_U6&dhs|leK0im@y#Tec%)ha;4Cvr>phYfS5DA6NHT$oZzfBUf5=kR%N(8 z*CDN?3zVJ&H)c-OS#&pFayG=s51%vu=A`s$g0VVWIIG18CvL}njYH2&ff6Fw$`FMoJntn)9yUO0E^#!mdY{@ zD3x14C>az*!R*cf)0d{Kua_RL(o+vTT9;kufE0oAAbQU1x8EqN#UQJlB4D# z10vrzs&z$OR^Nq zkCVpm`+DkDs+}K$oZ^{sER!2cYdYmtHrCo56A(&yn8%odlww`TVGr*$ z9vy_wEKUMbDF4*@kF8-0>&iO;D^Fr_8&rbB-+3Zy5JwkqL z&K198y;_?#7MDplQjjTJ18!9yHoj65LXO(M#<+nULx-+jb=Fd8jjr2{uiR6z7=q0( zOb{RxD5qf43Bv>(3xU8?zHKgw4*B0#cir6H8jEfMLR;p%6H=t!Xuz9tTN}Pf~oBrL8p8s-#?Qs5doJIq8Cs z9b{VjT0$x@n3weY=#)~D?OSPQCa_<%fr{O(2#j?%1xMm8OWU;Qw)O5SZ3xD611+xq zzgBBM8gN}=l}K9sOSL_8loS+7pba>sP~j$_*aWT{ zU-kM3VO1E8hGuu?oP6<=^;cIOWNN&6;zLef{JCQ$(+So%CexzRocDl3 z(ZBy)LTOqir*c?ixd+ z$H6>455t2yc8(0CMN^_IsQ?pq3R0-{m|B%Gm`Q>C;(Jc9mBN4-KKm3uJx;K~bqmk` za7I67l{?0A7&AzT*FV*%7z6l?A@WnjYf2tE{Ju~uC-$I^{nvX`{EhKu^!;&631eo@ z6i9ig7e%pSl+y?KEX%ePdb|L!Abkn}pK9f#oXKv0SvnCJV=PX0%3Hz*chzqaA-j37 z*eZzGt%6y6yTa`Z_J=WIpbyX%=1Q{MfV_jviIU+O@A4ym?kXV%#6 zV6Q2c8&Ai3w!l2o%<9RY55Gmcch{gi9smbz)B4Zs=w^e1nCbM!t;N-0g69TI{-D(7 zcC`CO)vru1Gwckub-2}*U^ff~T!18Z+k~ZWxu>+FT>w<;+xJRHRF;z;O>ws!GJ`zN zFw!To7Q3e<+66gd2PTNy_Fp_oUx-0#zEdvV&VajX&5Im^;nwGG^U+`X2wUmFnz(lj z6oAMCAN+sb=Y{4a4nKQHu1bpOguKYfC%IoAsk|$o@m-i|Q?XudSX?exE|<_)?7xJ| zU%22CzxC~H@E2R3^%OX6A3FPafq9G|Zi9!3z?g8) zzUPr@v8TN&WO8hn0;TmvCSjstj2Wn6W8I4QEKC`BrRMizYZ`m5kFl-BKzd{MJeCZm z5d34GpX%hql+2i-mZIpzY^feSpGyArfxr9jkLi1|O z*ghJ-GTLApLt8cIvOzo&2uX0ryWw!jrJ{Vg@wT3F>w!H6vboU)?HtOC));FM8;O0x zA&-GcH|M+(EWWzpw!P&|Vw@esN^Y8YsG%S0lY~AHyFvBLI*(``+TP9%?d6^-rIaL} z-(G;O6)IC?dDiKRJO6u1dAZ$T7H)C9=+24G^@%JBfvtYC+&v&)I)$;Ca#2yQOB^tnO(>=lWF|ZLTrqSc ztZ~q6lP>?veAVweI(;{z3(Zm6b|(w&!*}0uA70!5InM5kF$)s16mr!EUW3uTdm^1c z8;25#A}^4)CFU*TIq6f0!Q&N#+{(U&m4dN`wrQx!in^{awH>5nLxzH%>)Qb==jm&K z2#WRVo7g18_^wb{qe{2`TUAEqhRr;h_w_`Krl>Vx|Kl=DBPZpFf5v7=jT zwvu|z;W?gK|9Av5w*E0YAmx}Du0c3oPYKneIxu6wd(43{h202U-C~iM)U)h=uivk6 za@UB4-Cd= zob4RiI?&QURqEBfT1#ElRI8f0Y?zQ?=wwqxR~b8>r5ItbmZ73iN)A9dd7^NqBJjNK zt4=|lWi0>6HFgU5Z_a4y2B+y-?JZ5+P}UWbvz+2_2G(thd>}(mKWVsn|BCvkWplpv zj#`tP>EVon!#P==Q4|weT8xntcP2D1(5hZUF4F1cD=QLQTSNygFXF~?F;$Q&y?U%%ee ztQTv_b+uJi>yg?WT3b309X-!tyCChsexU&k!tcSh)`LQyZOxAMd!Jaz9@>@*kPdCM z*Sha#-`(f-=>N9XY?d1@-@B=p%lR<+u-2knR}GsEZ(&=%SM`?K)!Uz1?REV(%MI)0 zhVr_^uIwP!Y8-=L5IFBHC*3fTa?W9-Ac@iG3n*rhA{y|~+#0s^MYNX8_v_o>!}f1a8zr|uyY z1jlH8@jb_Y=NOnZ7Cht6i@EzTC@zIph~;GWNz;bUI~Mi2p(XJ@asB(mY;65gf<0qQ zid5Hc42hl^3&qJzcwgbzDRi+5u?KOBzHjv>mEvNF!jy$!+{OxT+-NgY<89T@mMyw& z(5_=Kkd!Os9Y)1LZPj1=c{e5G;S`lJ)m!Ol@$jr-!LLBP$febb>0B z2lfEQXxgg9c8No~ZrLn1)J;v^=7GZ&0iVSNUA8Exx-LS25&k98wWeHG zl*^Lk<$~+WC3RhMusrabcB`q|2KP*mp>Rgiwl&LkNxiDOgSDWT79MM19OZgLwXRrP zE?F!V)Qgg7n-AhTE(pa6#rmT)WmQpbHkihcPco*nnO|eoOT#MiLU8)>DWCY`@9?XC z;VU@3)rRk{Ouc%1$$)BSv zeCdyWp9c}P8liTp@6bLq1jL2y?C|UfE96vg+h?B|2Efp>JN*0c967AQQ*xbS2X;!n zHYKu?q64R9z$sbRG4B3YU{6uT!T^^_pkl$5I7p{v!DB7&SSc?|1bS>jh}R0+*`Zu& zYW+iG{`1y9WMn;W{hyaS#P=2(2aP3jad#m$kc!n#!;W~|{R#I;uYi}u?UR(1;26Cl z1w0viZmX{SdcCGvZ>Y-#Q)_4})G%95xP5+)$!bDtJCO?qrkev=>)WbI2uI z4bob!{?Rp?pIWhQHy~g>pD{l=K&cFe#< zBshbt91s7}2go1IF_RWK&p6_cnVfZVD~b4+qk5~N`t@=<5AKnCuIom8;E)d`xj67I zXlpTzM&nHc@>>OZqmkW&wV!;;Tp=of`8(S4y<5wwT*Cboul>ZUJ1=sUE3C-L?@lS+ zn6mnnRiM|ht>O?MH1MuNy)Vh-Y!Kx!+M;ViRhKkYV~-r4`!nCed;iIMm}<*hU1S;a8mm2gazwr%(Z2*%CK$AhkyNj><>Ds zwkDqz933BavvA2~wc+aGisjXc&0<5dt|*@5h%?{9AIy!qPDdeg9{zV9l6@?LdtRqt zHlHJvAFB*)#LjM26&bJn){k-d>zBO$v)}2=i}3rl?@Ac$4P=${!aI$F3jx>N!7e*K zzSg+bq3f2?RIJUKlTY8~$Nqz#pg5jDXQbzh!8!&STz`Ov0vi2U5>_Cw%Tyc~Qf4Ln zffxSW7;KdS_>Sp}hwbBi!ZVD}CC8BBsa9)>5wuV4b8PlHCUKhr6plU9u_A7a?;cZ! zV zJ_(L>?X}ihKlIc;``SPu#6P~Uwry#fmd*8=`a31^LU6o1KsuN%CKQ_t*@7^Fwryxz zz-pxHyt70{r4a(>1VxiE`PYi#Un}GTNpq^vnMK|Qch{i4&K|_22gfN(jFG7rsGJHBDBL;hq1mTZAFLa(*}(}yOz?_-1*Xd zzW8T8k31B7ySp!M_1XWQ8ywq(b68<1ZN=oB2})&Xtyw-^QGKf-yU3UmGX9DV-KKUeLjs*2TjR_G5kv+D!0>j|tRtu@e? z!8*5fEv=U1QqcU`1hWN`fpgL&_qH6|Vt zSJx>k)v-XD5)28gT|=7E7}q*HxI>%JRC_oz8W;n4#l|oxZg_mpH`zNbsRyv{%uWTI zRD~UXUyNA_LC+~>)0hW%47QHfV4qcYO5Z--6Z_UbM)1eacI-1l1b@nOXbg;(0{M+$ z9#Y+%c+8U8TQOMAIk!c*$ASi9Vht%_nHyR#y;zCMnE#6@N2@8)I_TQM*0wZQv@@Nj zwb@ohI8-+a?`c+BQM%Hrpo zx@GMQEe1{1sm~c2GzzcMCAC9*%Twr{{oGS#^C?F!9d)fsn7@6%-QRtWCx7!Jgut7s zbiQKRTaBUn=VdK!F1i0hFY%fG`KPdROZ9j|@xlaq-VTBxLt=pIbl(ly8Psvc8^7}{ zWTr5+_3c=<-LTm-Lw)Rk7k>APy!W5Ki_>;n^E>|wBm5lIbs{g=E|_b~)bhE1=kvVz zTi--yn(Ol`59BfygYiHxd~#u}_8_)QaPr0pZ~x{`@Y;{R=A}`kqy04v|I9xCyFf(0 zx4Lbx+TVxYFW!#S4Ks94qf=H=eofz5lceabQJ_rs zf>aXyb&IwQXUj8Q`N3C^M;X}@iTU{!`Lr7o)CSvXjBD{b!M6=fpNe(VGvy@fZ)?Q6 zE1v$n$F#rebzc4Q$FRoq+BiE*1C=Yj_s@Na`3rM?<7d7`yJ?X^;<{%k0P6(K`reOr zTSkG#p{>RU4+NavpYvn??vL=&7hd)%ampd2g3KY5|2!*hI=Q99p;7@hKAU=Eb|~zT zYJrD;Hw0$In&7F!IR?X~TB#}Xld%Aw3dAW&)tJ<5N-XDw$3#LCf8V@11mDF5JaHA6 z>d5ZXCW!-n9Nbc)iWEa3rb&nEKW3owJQRCuUz@UvjWssL41vZJ_Tu#)OLkHwKCwVi zie4E8^L|ff@n0Ux0QL?2Z*b40Z|fZ#%~@PtP`4G@wYV;To1jJuJwb*C=+8eNJP;_O z$Sg>q$b>|Rjxr)0#X;r)OjaT@MLx|@r-#(b1@**#uN8L7X^-@Kmebcx5XS$kM3Bu3 z?*H}|Fty?F-}?wmFPCDmuInN=iUi~sU*}W5`%`3x8ExBOga=Lu=Tn@c^C8Kf2J?r;83f7{@r_{Q7qvAqR$pub^AylP9d-gH|xexc0Wc z{b=XyKkyFszxM&Z{$KnWAN}GZbZY`opg=p}HU5Pg^aQlAG}dzT`U!9U@LRn3!*6-o zqtnQV!eWq_*Ryx*wynbodCavdo~w>&nx_J4TwTVMPfy_-b4Cln!J%T<*nymyk;ilB zv7i_7mt!ZfFkp>UvauM?nC5-lZjRf>p&mf0y&rdC$Hoca-wS^)M(W3jS4#0OHu)N( zq{ZJA2i4RVA#RzE?WO0ro83?kO|`rZXvr!4zFDi-l6gE;_}lOa=B{ zZdGN9;!ckEgCH*)LUzdE!;I6nZX>eZ4Xjr>BY^q%(^dAuE#1RdynBURc(iOU#4&k! zhL}nO2CO5W6lC)Qia#+ytrSW+aFW~KbJx?~LY-@Wy7@y#!1D2i%|{!5&{@I!lLvGn z>Zm;9pg3gmlLghsYtT>}WZZiD7N{r*>MDNGWhdoz#nm@2eV`VW=?gQT1egw;52$Iz z%fIJU?tb5WKKR-1@a$L4Xx0tP1V^tP^YW+f^7?On138ztiNgwmwqD`Pw1(3!-@@?* z-}$@WVe`=ft1TiIOzzCM^TsK!{Tr`w^4baFKx~`dy-11dD(_AJ$7q9?NDe=J%xC`m z_wejrJ>%+Ymt1{tMR`%8Yaf&kUpVCOr2}rib;|4i#v90)f`Se;Z$Nv%ojg=jXEpLv z@WQ7a@ZfVV@Zgj85xGE21R?_`t>^G}U5m+N!t1~Hb&g&+#I-(1zWn)@Je^JS9P#eu z4*W{4KUlDOxI{>w5We=quOg*yALM zZ=B(*Bb#Ns^yODDwZ{{LlD}R=$qmYdYN9xO{gf~LFTWqNHhkkBe1nT`o^$=tHS4n# zqIE-}b8vUY;S0Aoef1V^{P4#)xPO2wB%%PPoc}Hv%q`9KKuX!A#??$%4X0YHshM~@ zLk+(xMhM3hSC}Bg61OpxH+JeuiNo}uu8`9mgQvpa&|?U8@GJqYAk_+vXWc!5d<;}K zMs-Ui3}dD!p@B^bBowew&%`7QuCG+pkgPBL!hiAw;2+Jv>=qg zDu#-7*vNsQM{jN+0%a`lRgTnRSMxo0w3+oBa?$B*OGPeoa-&c}f)==Z>lNM$)CegD zMKmvt;t5)!yIWXb4Q}NS)|<(Q4CGuQ3-1W#D>mcj(p@~0N+OMdmBnr>nC|xrg`7#`Om%Z~ zgUGz>r^TRDwj*WQ(+wqZaQw0>i>)j)4pV!J5g{ca12xZ3Gv&J=&Uuu0=GU37%d-BB zHBty>r*qUSLrf&du7e>&XE@UZ4dI5?xU&w|Iz-!5TU{{Uv19E5vA3%A@}txiI%``s z^K>qed9=3_65Ck+xw=cH3J(Ue&J4gY0)rGJm{Nlg$V?zIiBs0Ez3Kv!mAKm9ubRlA zOMvsjMp6c?&<=!V8VlNXV;20nsIGNteDHR9E(_@s zCMA%$+-ly3iejBLvC&?w&~JL{M^tN#(_k8nYs}!vCUS`?B-yM$6y0^>nHH$-&+=?g zsEcV+p_*22WD&Lu_f;g}xf6n^#>7}cE6bS8(^u%>c^4w;dkfg`>p-3eUp*qqn{Z8|118wdQcId&@18}kl$ zo{>pPM?Xyb!gv;Q*5iUT)=(dl29K{f<#IQMZcokT<7XAGf4?XG@_+hQe1)FM1jcmO zQ(VZ{rmq*C@H-r|v|ucvtB`%=(($(K&F|1gCjkXg2wdicItCXtu{F#Pvh%L)L^)6n z?F3Hw0id;ARocZqgQd9@HPfYJGJi`=7|dvy7rU?wf{R8ic@y1$FZ zEI5mCji=MezWoZ=uG&k;AP%$^A(00HG57bIkq>Hr19!W7o^&E9Jw?fn6ePF4a0}Zw zPldA%>spXqWhuoVtP*w#THSiZxJ>wf+;jPz9sJ9?hu%HYZjPKQM3Hqbh#a21b+#L2 zbVe`c-oYBxO?vrqa2xYjEGs)<4j)$ zDP@OCmp=KCpk_T!-FX?@-VrAEzmF1~GM`0j7d$UNVi-CJ&L>6kAP+`gZct!!&JG!8 zXv*V;!O0eUsU{LNDUd>SR=9l<+;zA*ZFlD^S=YtLR5qy6sZ8xiV#cl8lq_dFXAF_W zaZm}h&0`=~7$CxyZFq?1dA?)k8SAR|)pZ~AQ#10=b2}a*q}tkXz)OLmVxD%24i<9A zQ?1|>&wGp$A4QIkO;F~uL@_-D5(aQtKRDxyf?H^VmPe&N>w;Zzy4-NP^Xg^6@gB@3#xq~hDy0V z=n%d=jr4RIV+>YUB+^&cu2;Fc=@C6VClzoYdvEbjgr0T52zupRCtdzDhdzH-J5-t%4* zs#EI=x+g*bYI{w+7Jolhh-qMBt;`gHI-Up-#Rlwp3v}u|fm3t~E#NQjX zTI23yT)Bq&-bGOiif?1mwEYz~p~h_5A1 zYHrv<_r@(_q6G1S8594H5ra2m`Gg##LPMvt9c^GXXePQ1?X^{a@$!5mFEPzy77H?pr_+l*UcjZm`KXAKMeceveQx#?6`~# z)m9)~ieUF3cI;N={q;LJdy&+5|xi)kLhD|6L%v~IA)L=m(G1d&9J7lH(^GNuz56?unn*p!4D;0LvEzYsy z$1X)+u%guP=ly+&&^oSL!#;@}-VebrfA6og|NBa)9i=({itHX#e*Ns0GB_-MKRVjJ zhsGJ7Oa+Ok==7BPu|Y4p8dnM`Q^P(JLJWbOE_rss+teZ*s;k0;^6z4A`a?JF=sQp` z_cvan*jXz6^ROKn%45bT^)ca+)VMIL#$tqX?Bq7)ogG$g;Xxm}g2jh)tPU50?ZS>j z|NB{%-LU)|3tm0oaEwo%I@iPR8AFSw5`cL88rzYkWLZ-!`V_S*)v}JCL2Ash?-_+_ z9j|}f^+BAh?wHP%Hv7CRX%3@M1~_ARdJb0lgP{AEQr%>N;_Dx=#@&WpEJA z#ACniu{O$1#v`^eo&jz zRd#~6*tTiM01`L;yQ@yOvt_pvr2B(7Jg8!c#Ou+iY1TX+p!{ zCbz*llwRHKSTWwBwJyoOb%C#K&wU@BrFA!SpFMK*@@NrBqJc56?0iq|I$%1zS@bN=u;dIh^a3Gb`@u*(?+_~DQZ zoUua1vQ+gM2mP^1IUarXK)k-HAJZ0zX1<&wS%KdR#fi>mROnyca_3NlNEDg$d|?ujf^V?farAl4oc9 z{`Z)G@Vc9(8I>j-yt9J@rSFEM9Mk&i7!!TzE9r1V62Jd(S0g?L!%j@<%!~tKyeH#5 z5VI7*^^f;m{QjpzeNx5Am=x~Vs5+Hsq)_tDOO%ozy&l_<5}x0eHOK!uoWq7MSBk3` z{{8-E!&y@*7={l#Wm-Shj))KZxP=x!n3Q-y>fnnHoYYGeA7){DZOk4rm3^mzTxvGf z|BTietu;kaBoB_*tReOJV`$;A{SmHz%5Wk^Z^q!5800esLK=IvV+IoafgdB7Q^{uk z@;|Rj6u10hYSfq)cX$nPWtr+uq%!5eI&-O6Y#+2zXGi#b z`}99j_tsy#5Q4g{F~%^RPRa9p=pKZ$yZ-wolS$ItBX!=#_aE<{K9P$%1F_9&{QjrJ zTT+Ex2ud6CLLVy(QYicws}VlKl;%oo@G>?|7~7+%^M6cmC{7H=gnGhf68@8=D!>%5 zAobFZ@j>^A&cqo<%91XH0(>3^Y~7UtYUO@*jwhME590NW z(f@IP+Xq^UJ8W&+?j%cNW08H`iPSmr|IhiKG8s$V-@Z;?yuVZD(pWLKuNa8Y`KfrA z8mp$x{uE2Wbo(X?XFp@~wK1?nYJ-hcbz?8!*bSyWYfN)^jN_N0$2_man+lw%c4R8> zhgthr%XsXw$L?dF;X*2zNYQY{GQ2U{$FYihtYb1ZtLqQc-U-NWKGy*hWe@=NZ`x$1 zhXCn)!Yr&vwx zdFvnV>9IXG#+yzBvy|`n*!UvehpBE_{QF@iAobpk%~Mn3mw0`~685pScM3o}Hme<5 z|FCTxwxNrnxY1=yt!W=v`#%d?`0=?N+Hl4l%08h;?Q?4_MN#a$Gof={>fS>f!`PfX z1yqZ>DbMTJq^Nq&TmLa(w0)fMv3Qv3HjWjssq;IvkH_A{R2&QFl-V#NNwvYo+8AS% z%vccJ2kJ^47GrXWDb>1tocYv296r3bt@hnyO{qX1q9{|KVuPqK#p(Tyu4`;Ciw27NUdMi)S53ne84NVvFG4*<+opZZ9T- z6M;F)R;E=5?>XP=3OG8+-;UB){7_*6d!m@M?9XV#_xap-SIW=)4>jt%J_YbfA70F z$m8c1z85_`t!>-gs@qzmwG??iP-ElDG=)2f6OZ@|4(H{mZqXRGJPttNyB}BX@qP|l z)BR`m2}chOORaw@F6`{N#Mu{u5@V5;c>TwK!eiZ?m|~nl+K&}WV?{>)Y~oHs>ith8 zsVOEv>iScOVHkI^UKOct_r&0`)C})=0J#(uAccM$d)ZUE%BdiiIuv3}-?5oYi1JST z{+NW~K3UvURzB8R9m|?yFjsu=q~>#}*3Z6dZ)}ZI+5gy#daR-e_etAos;c7rV!^l9 zil$Ya>z3_Q)FiX=X;(dWDsuxZ&kc%dy^u<#Bv~#IINH{r?N+YVAC?v&9g|6hX)RiN z&otLDA#wrJ+;xP|9+KvL@$c00z#j$4Mx z_I=jItNAreOI{SrrW0(`IY|L?Q|;Wbe}~Cj`13KSHkKrf(eQCVA3OhJrLw-W8=ldz zFcmqor7HjM{fWm&AtoTTPva3vs@s+tfsFx<Z#^ztC zEO9IWd7ck(>Yzwf%AuZf+?tA?_r6x&zFA9nIHi)0eRHa@=l|T6bl2-vQc_#RFBM;+ zrUAUid(ly#)CnjdI!?a@>BUPxVy$<^vv}}u@;qlgnV_}iylkk-mRH1zyPfJ>YTu9fQ;*F+zuWbXpK%C^iYud35*+iU z`*$Jb*&S1NQuD*-1-0;SNpZ@@g4`G*B1S*Q`zn-RO(iR_-gkJ8#L8`PH4{?x_Gx^l zK&)dHrb2jq4A-`lWzBN4rmkx?RY_U3Op1cr$A?TN1(RYzk?$&$<#|4cmBfLtM{}oW zwQ+zQv!9JeF=L5bAMAUydpw&C3#ahR31x0m)$%ab?e42JjHq|v9OKRipKwOch%x(Jp9D+*YfIT*% zh&wV_+qRTtxx+_|UxJhuZmJzM*0z0KHJ9SBjxuVDmYNuJ$4b})|z@=_j8^^lV+?OSXMUJtq_b5S(%)3$@krd)L)uJEc>y7~k z$7XP`fyq8Da7r6`40zb@*?rYed|%`cYyk zu!l6dF&595*L4r13k^~FaZgn@JiWZ)>BTvl)r!?-Mb$dy(+PETo7<-+93FPQ3p*GR zlKlBtcqe}U`#(=1xI~4{7F=Fk z^XTjuSBq=K+Do);~^U$3WF% ziC+xhjU`=EXG+{DiQoS)0n6exYU)>tb3TRwPqlUTAp-XaN<5D`m*RkrRn94@)tFn( z*cf4q-jzB4_lW|G@eNZ|-#&lf5d0P&zVW@sK)Es7zcIvS_^e_->$vJ0sBBqAmMK2* z+CBdLdkx<_w>-RRczC6GxDu3k!Q^m?Vn!|nhldkv0n0`st-|Gw&BZxYWw2I&wU~{h zXcgzn)j|jwM0+)_+VmBh2tqiC;>WJEhGKcdW*2I8$@q_?pJLKB=)q>`;~Z zu9S*gAAs^aA2i?7>X2zVSB2PtI6xD$WjH<;na3 zRw(Xl1mBl8d~WUr^PklE$4rPgfTmi-F{`Jik;URVsUVUi8q3A?f)5`*;mNaSJX@}LIC+`P@jZ-CWG#GOS#s;N>lOs~t`HDf*Yysg zV=SJ8>lG#=VRz(t0L}PJO_`9z=l@uOn3{!;(ZEx9gZTXj-+$eU7=@c4mNOjd+sEyl z_(oDU9sj))+BH=*$AFjAjg6rd#}3T6%GgIENIk$*OEIO#yH5)_uAs(}g0ZegoS3AP zv&Lp}V+l@((u~a{Qfr%qgKR*@50HMJ`x2E!J6T<9M`z zv!*4RIZT%0BKivG1^J0T8V*pF`9b!nmUBKg}D+ONP!d% ziRGoa;=QXC|7>|eG4=MKrqm?CBUYox)&<2++aX2ZF zLeN^MTFbvaH~iJ_I2!!nW_5|vC8x#wCgo`4g-QuRgwHnS7LNs@RFEIzyN|8^^Jp;p zc)TeK$T1LSY6g2l!gi1HVSix8Bd=8QG05qT(B)Dir8o&ljkCtsHmS;ejGgj4I+C9W zdqJP3X}D}HAKm)`@7y^;QL}0q8sKh`pUr9@)FxJs(&AK%_zW*7_@hPoy zG{(?6OC<&EOz}THZurBu4hC#XN`5uo8zJAn$0fuawO)8D)eVaGaG2;m51$ae|6`s4 z@mi$DykoS|)cTFFjLq!6;PThZ7IC8fE$56L`M zZN(K%s!|$5`;VdFpJy>SrU{Tb{Nvf@SnwDFF6~?Yv7}))GbWHG^yZ-+)oxfVm%Ni- z@k_2s?M+UEuwW%$dg+K;vkYN164TkfcJn$RC_0m!zQUHh5sd^XH1}T=e6*$OieDX(#JYF zsXa5c{wbbsJnKwZU#3_q;b(XWaD~?q&(LG@o7j~t)xu3t z4UI9BRn7HkMb&CDDJe3=Y%=LsCkp8tS>!1mk9+z(p|wUyK~@x$#UX9o&{zxBfVN~+ ziL2LK6pGq9Ox=)WiY(aoaoc;$ku6Mk`u)E9>x%B_t>jR{^TPYR5a3uQO zod07QDsd7JpYbUGa~2-LV^)S^8rv}{J9Y3qFEEUK-xx*Ud4RkA1xUT5@!=BQ_ZW(O zj0c`Vy`}(uF$g2Y+fE&-@pr{?l+R1TV%pVMbrh;RrIe-i;R?pC=Vn&T&|Y-bcmPq; zuqi8Kv!cl8EOs4IwM;U@G?UN>gtK5;Bo^lkBFOh#tV9Jk-AT%JR;g`W@niFAe!l)V zw2tF!0yE2d4_aTxpLP-B#Pe+_X9eGF8aN__kKiO;n7UPC+6lo(VB_YeoetplPX zQyKH=l%v_4QrCRDt#~V&@_Lcs+M3J7ijNixj$gTr?mViTwL=w}n$M=*|G4eD5Azbz z|6-nfisBaTkw$B(rs3J;f+y$aY^n-1IiMZLDq)cX%6wHbVw+;`` zZNpMXoG~0a!?9@)dc&exacgpjMxaDze$*vnVUUdztN8p+b*n-kWH=TI*S`nvg&m+C zGq8_l7@C{Kdp{n3rF0(lF_=PT#@PDXu;o7H4l|~sJ=W3-TX-q()mSw!*4|IGy<_l7 zs@;^DBkt3HPjL<7jlNG{WS^KpN+cvTpGzeL@!>Zn3^Ue>k6WLqz>@NC9;+5pBZL%S zFYE@yGkzfiwgVA0TGO;GS?YF}%boTCb@9pQ0~}wJV>e!k3!KhV#q#xu^K*sr4TlOQdED-FIBW~cMTICbY-`zUG_~=*;=;PF!gmN~aSp6Y>o5-qRPTS@UFXY6^X)?NbXk$x z4bq*EXBh_Lg=G?oTKm+=LZD0-RQ9mRlbQvx?} zH8A%6$DH^09^$T1%+?6^St`jKtD46|cv5ZJ5EzxxeTdh;4-|c6AA-q57dSJic;~?_ ze*CiKuRN*ws9N*P)U-{>rmFbqx9@Q>QCOoUvYC);N&IGs;wjltTLN)7IUGv`@(brrPJJ`E`mOvTwu@ zQ;YiNA7+y=uw;yKH>R8y)7oNc-8NA9vp^dkoIzk+PE}fLW4$O$(}C$^Cpu$y53#X( z-g)kTR2h>Z;}zNP^`>HJDqawVX)bQ?&O@|zyvA`tI<`Mky4A6qNs`vFne|+gM{|Xt}3m zabw`9v9|eGbsir+`)1|eO`9?$3J@PCDUNyg0>+1Jd}xogu44pgN>hGp)<5=w#vO_= znqVq1iZ{gbOk7ee+W21fspgG!MdAZ5OxnVi;>I45{onT*?M{L<8Eva^MuEz}Y|T~t zjGIy5Su9;Cgg^;FQDhv?r@Y>3+{FT+E%$FtP+i6Eoa@lW?8S z`tNf?46Da|9h%f3A9o;9BepSsT?$_iwsS*3S6m5?0SV*oM@nus6wyevO;fU}VMieD zGQ{AbI0;R4Bf`Wl{26Twd6w~D0>AgwjNkI|U5xV_>$@|>-NItEMmdMTdMa2@4en#v zghfxxzKA{R$KL<29esmWFD0!ptjmgL*Gs;xk9qvk7dgIvp9ixko3i1K+n}2YjRXPC z-IUtxlc3P9^(NK|j-=ox?@E5?#TTiYyEtPw$t82wJI*;|XWHa~@!%M4V&C~cW_23J zhW?)rUooKcqY-6DrwgwuOdL}9u#{D5*ojNc)W>urLJUZ+sh^Dr_ooaO#wzr<4LBx1 z61Qqo@_1ut;rJy=wfgqy?v5b}_qo}8H`Qq>gHGWK#%7Z7!i{m*Q(52h=C-L!FAl=- zY-#K}Qw9<#dEhva3TLU?U@mc8%hAugEmBzjZ{;w4GUuxpEY=FTr;-FPg&>)f=)%!_ z&h0$s#m5zTB6;a>f>HvE^S~ZE-WA!07Eir!sibw^$RzyySei362KsK$$zx_ZvAS72 zYD?iE;)-zJ`yY3BLL_?F?(D0cSlTtLHpgUYQ}2J@@r&0#u6X0UGp6wnR-CBu)W_`JcOAIPR+q;~>i+#xF#VA z+&N3rHmn=XlRKZMJ-WqINv_rvmt~DI4TZG04hLi1_8vmK#@PA~YI0cy2u^ary@{Zf z5@Q_FIc%#jy2Uz&?M7#D5*2?>`2MH5qVfI+|4yt!-(P3H|FqUaKu?Kh^}iSTpoE5J zVFH>OW%pfy@cmC|z>I-V`)lceds$2e*tdbl0%Ho`6RVk}0@_$>GNcnc&-gxN_%J4% zGKRVxdx=sloiRk|*yoMSwZ;r?QitUj@NMimQ#P9WjAl~7CxzJFxBhX!4^h)M(4o!) z;QFt#!g)JX>AcE|ZIQxwa~7E)mGwc_rPn{4g~bY9xs=GFz&gjD{`@J|t>gZ@pul2c zg#358Cb3dt+%*}i6!w88_fe+yC71iUIw_9sn37e>q$q_{PQ4%TJ{w#AvG+f|hp=Kv z8E?cLk=RsZ%(bf5Nl(q7pK*&a8Vo+!z4NU-u@hm$3bIb(Abzq2;nRA7zvm{=IyhSOzBz2t+5n8svCT53$hOZ&B|ach)qLEp3KhHJpC1$FNg?S| z-IDk@3n6gf97}?e0;h6}(FoacSXeNY(inscx;4lf^UL@eL%Y>L+J;PJoJz^9iNxVB zz1o?O1Bd;2?s{=zwR7Mn5~0+3g>A?&+1`EYKSonZy`yorCl0u-2fwy#8Z|f5fgHV5%*( zSgVJ<8FoQ>s?^w+ZH)31+K<{qVG>rRVeko=FCo%jNkt|Vxl(BBD1@WYmb$UDl|#3h zkH2!@TkWE+p5>0rY}{%Nle!(=x3x$>^(weRdfQ~5S$AE$bmt--6^@OC;wV=kC+=OCQXhd6{77m-RpQ({M1>cx)(+E@!vsjSddN45L4fqI>h$b*^Z3{;(y0$ncBE1 zA)kGo=qcLTKBq3%&8)p_rt~j0h9YxJW;q8EWM)}okXxJd?mI;i!5nu0L>FY+4&b7s zq{wrG?6lwU=y}IDC39@w_G{67zC|z=(hElyS3=H^*}w**+gcFJj*CLC9PgY zG){O^41;~z+euILj`!SlRfI7HV=YQ5jP=ha%W|^JALyd%TEqa+6zFP9yI>f%bnRXn z$W*HCJBH8i{=PPz{a~#@NJXY3d6uENbsMu&y%7kz?`gH}KGWg|4szj@3G*!T0x2U} z+c29L35|#P2!eFhVwuahSYU{fFD+XX+{};oma@Y%9 z!0N?WQfHL#lofQ_?4HF^qPnCrl|05KU1Mipe17#+v^IuTYm9L?=bumAG`j%pex}}G zBjN-+?taD8Lm>oB({$fuutx7BH$_o&DtbPd$^%wIiuDqn3w;t8Czn|`H;MyGOa)-1 z3P}MB;=uGgbBZx#rhTaTF}Qz9t~MnZIEEr0n|H?7nNsI^p5xhAS0dH68cSIAN#X8G zq{hT2#?a7X61}PWO|_@uKoBELU0=;OOD+u4X@SbTkGgV}ZYNr z8>*(Esw?WYMYqORML498Op1c(WWwQe%HhGBBF~4)J?@sJ)D^?Zun!t_+fr6FP1|6s zqsVg(W;13}A8?(uXk*w^70dO8x~^&4mRf5jlY+z9jKley`E*8>XJpX`F63Cd?%#FO zP*pXXx}vNa%DV0XdY{C~A#s^ZCd{W3W)uHQWs0mn@A?GG`JmVuLtXp8G?^6Sxt~81 zRGqEX-T(H_ylz^`x}t3wa+NWk&5%m&+($pRjlCuYM7Omxb@wdmnsr&SDQk>wQL+!F z8f!fnB+CmX(<#$DM`FmboXK>`d{QuTj%+qVN$Ka{-F<4UI|aNvZWWorbr zR3If89^6+p4Rzfhluwq+%?52PN_u8VmSqS)^>cdb#}HD=F3HnWO-tQ2ES5{G)=Ue3 z?OC2P$ud-yZAGaPS{!4dN-5A|Sye2TORB13RhE=>O{=|ceW4Tw^I2!R=*aU4lcJ!Q z6d)yXKHsUHLk)lsAJAhJv^H!uYc8*^DXWUAt})tlh<(=u^a(;K9F9U|6h+R_;SqVJ zu+F3WvrHvB4`H0mvW&@O;w%0Xsx>7NUmxO9lFr(%3#A-k2Wx*la#V$EW_;$A^yRpJP1YF$&Ds9*AejDaEtCV%t^( zorG%!N7I~DU2(N)m>9#ftDgIL8c{oc3>avwWmA@1Traq|UQjkI)5(N;0SHBQ72k~+ zYEYTUE-3bf6iwYwRwbLVqN*y4bsQZZar@RSj{2b59pcONip6@(YF)D4tSRdT-8M)m zndJpaWfaqb!-E6ry5?Xu=U_f(Iw?@m9*Cc3%F}vhpY;I-ST{bQSgbZIRx8$(zxJkW zsf~%%&3#rc>s#DYMy>X)z(sGgN2s+XJ5J zrt!&PqnS<$jt>u*PA24Cuxi?tb_j~P3%(6ySyDGOxsV(m9dJuPF)7H^O+E0?=%fda z>h8WSuNPb`H(V{d`>IPa=S7h!>x2G8LTwyMNS~O^CS+2O2$*B(Gf=n z2ZIw>RaPvPON{mJQmYM{y1_W-lexu`LJ4jkA9H%^7ALt!Z98iRlzUt_jL|zo5gpwn zL*{zHa=GB@dck6`^!M8(<*pkW9?T|WfI?7A3X18J!-E4_t%t6k2oU_?^=M;!lHY2o zs-$Wf7ONE(7nf9Zh0(SfDJnm%kQsTNc{G7BNF|w0rrbI{=J@!S>7-yfosx^}#`#|q z{?EdAl4bcepvOW9DWjGUwx3eFiUVe!v4k^%F&W4>@Tbt>&*K`7wY5{C0;%A)j~v3elQchkC0(eXlLak&2RoJRsug7msE zSf$9j=b??nQGhZS*LXy54*_t0oNz5^Y!aj`MzB9V~2vaX;`gRTrZY9ySn6ZyDR@%oB;Cz>8EG@1B=rAHvg?_0lrVu!2Y*#Ko- zbG=@3y;yOzSaP*qv8)>^C%G=}P)-i0C&#R(_k885Em?WZU9;hZ>ou>J*W7Cx-=3V$ zIhf6cwH%PW#=u}s(z32f%BrR+OV;Z(*XuQ_#s{_<#pdWWzEZx(e{foHM+nNg=Ir8< z$LAM3y}0Drx?y?nBH78Sbx}oatw{6)}HBH+hRmSSzMILWX_`!V2 zkKd9*>pCtZhW*^NdRNOO=NFeeJiFlWvkR^_6)Q1iRouc&k6GG`Z|h@b51%GA6RqG*B5whlhMn=6vo&-`%O|n#-$eF0U6X4Iio8GwJBSGZG;K@WwA59_)ndWL zq&+-e zLmi1woij_#JyTUrtbZF*Ut;y1koJ+%gx)t_PFdQ;Jm7tt+f>Vb%+hY3<>_||K1%^I zQb|BcF)QWAzE3P6#ibon?TY^yyYH0oK#Ff129ng?2=6~$|FC;wto1f6LLimG37BBX zXu3e}$j}Hh2-_L93E%n>BwOrZa-xl4Q&ucjD;{w~b>{^x)-|SCl1(MT>S2Z%^Ov>O zlvTym^@6MA(pP0wg=u_MaXq_>IeZm+>s40y9PI?l$p+^tE-o)Qd-jaW%PTIchU>#u zs9t`P=I{hD$(bv~iIN;BiLrtU?(+Vo;v1`)FK!<4rJ_b;3aKO__mz5zsuHjN4wBni z)^)?hV!`9HXFR*QVpCOI=65*1`&q8?TbxXDj*6VB)hx87mN~hE!{aGVWqe~<^2^I5 z-?O~thw^Hu0D3xCKj(AKQC5}bE?-`8v0SjKDqP*r)D_F7<$Q9VX8tOd$FFiJW}MHa zobi}9q~!YQipNi%@Zs4xkJUZSUilRIEwuTS$*Z9RHtgkNk<1fs%-GFYb zR_hJVuC91|e!?r@nUla3Q5;LZsTYsKTzaa?J> z^mc|e4XgEvM^Ddqe11;dG+3><3cf73Wu1EH)dA%sJ2Rb9Hi$syM+F8OZqZ}GF)bHU6oZ;21i{=fSV z4TEtCg1-+;7hgjPOtnw&<$0<>@faW!0vMY$KTm;b41FGB1!85fH~^1n%%_rseeLtH zR{1_u^cZ4!On@gA+X(rs;k|~a-I!OrGk(A!gvDVggk$1r=AvOP1k!p`vXT<%wlmNa z{$Zf%SWDR%zg$%{)ybRGMpL&nFBKI^9w1Oy>*rZ9Pr7Y2tL2ijiwiE68?M|8J$VUr zdYks-Mb;RmN^vxuQ@0LL)!<;g-thR@ITz;_Tu)x){Qk!&Co}3vK_wK*2m~3z2`;LZ z(pgr(Mhf)dl%Fd<#(MRX-#KeB#^SP@n3ORF%D^)=hO5nnXIIxedis>B>jjU+F;8Fn zexArf8Uy!nh}D9|X{3`#mvJc+*(7JGz{wmvopEk0|E$cpJgfQX7guC;#cVny>nige zyjPYLPtKq5~uycGFCMlTg_>fvs$fq{N#+sPoMF4 z{yLBDyiI+0N+Tr~y5;?*#%N2`NE)m8xhwc>TJcKZ-SLdpTrXEVKEL3@r%!oydCg_< z0uS%J&RKrKwN=!vMYn4xy;+Zw5>$@L3sg3t5Q;4GXFxN%%d`A8zoy^d)GRsD3zVyH zXk6wn`J9XF9*@j~vJe~`WE8mpV|drx=Kbj#R0Wjz5smVow>vY*-Q$9@#KI6lOk2pU+=l$vHd~^B+7j{nB3g+z<_a`gvJD3)5kP8kq zJX=W?%>-NIEK5P23079IbS)FrA_A&Y-L@>(B^Q<9>xZAm9UODs3Le@ixE#|obTsaqDh&} zJTr<~<`^NEk1dR0wO(^}dC8M!=RCW-X44uT z9lp)`(-&xp0wX;=&uWV{4O$q4kmN#=E6GF&Z_g|RE-yf4{Ax4d8y{5s`=7L&7WtNc z-*t$py5`ySH6NXwarW$jC&zEGy!&xVIbow6ZM7yh6%P(1GwDD`7Fuv!3T!qbpG+t+ ziRf?&Qq8lakn(4L z9>6Q5?3L1R-WNzy^t71DmkRVL3QMYUFlM%q0wJapyv8~YDInLr#B86PUq8!Bf$UOA zUA*=&W+D_b8638(^+C&dZFYgBbTG4ylWD<$k~H;(^|~1ZJKCmVQ&qnGPA|-H^BGia z!`1aQ=U3Nk8clQf0NrS0U6M=PQDnM%PK-RPa~SLRj=0YNjzDq0H}8H7RlundoK7cb z=_{UzkThgerlvHO%37|juc%wg2e-eBo!^3dLM;_%o0`VfNG#VvAVr22-a^v~fy=-N z0h5BCFCQ?uI_G!2><<@$YmAYuH`J}HV_8*PTwQba?2KnuSA6I2P0k*C50|oFv05@+ zJmuBnoY!w>ymkKoDHPwnHvH`4lK09IqY7$~vnFGcP00?Yd{9;Ve?L_GuRhfbNOTnd z5BqM*zv6X1c;OzBnwKXNUYyNwDx-98=>(e=+O}dM9Cg$3Y;n$$%S*m<{7F8%^)Z^+ z2^wEDw#HH$fwAD~3R|u?IL;`MXbjRh7ONE>ot^Q)4Y~c;V1d9n5%gbf3p{#$_WBS>drE((>X|vC@{`SXk<^;$v)(VhU0X zi07En*rWWPU0(Ci({rAlU-J0)9Uf0#=Da;(QEKe!8K1w~@MnMEH6~KhTFJDKOqJk# z)A0ZP)k}W%gOW{g$ZR6e^@gU@ym~YN{NbNvxd&b4Ip5A-=Hc`{$GPH6TP}?v)0Wy= z4yTfdFdT@6sg{^Va#0yJ4LA(>#Bz6L$c#f&Ew@d@b+h8d$uU?*p(IY_d{sT*_URF& zwOllCEfhxN2rRWWtgQvz(rlKjjx%aw23yu%#j)=Y#obA3Elt~UdA;Px#W^26J!7$2 z^U?G*-amYm3o)UQ8MbNB)iozMNTbQHEE|V$lF6h%6%(p_f>Jpu%TaPW!dg1VfAc}h zpZe^SJOC3`b<szGN3Ah2zVX;!>;a)eYF0*h$9a$YK?#OG}m&sAei`IuB>Y#cELa7)eDs(3+3BGieDUJ>gU^C%bSyLxizSyA7pztrR(C$h<-JdH-b$XHUvRj5%)j;V zV}9(d2UurtR+9R!WlNzlDj{f`rELwHO4B%jww9$3oNZR9&4yo}e1dPyUZN^asT)Vz zuDrdj11BW38e46sHVZ!U@fUe8@m%GmuDQ5c@aX9oA6>8b;NJIgKEK6ka!R?bD6cN~ zZEqd%ldqm~JGV^nouJPi&iKh!=RBz_fBDz0_?4ALx(P0uPz#I3VI?>Lb7?uAPIzIG zvoV_Uddc?WeS=CDTwgV8&d>RwR}}w?-}DMEPeEEsYc++) zm?*``f#T19-yPmM-SA(1tHnu+v^BPAcPCQtgTj#=NSX}JtzlzZ%5}q0euzOJrQ(JA_nAJ^ ze6VR*HkK=+&?pd{46ZX6t8s0KsY*8bkk&e~?j0Rt2=zg}(VFYUiic0n`0&Y7&Q~Sx z-}*d{CU;q?8BJSqWY&D)j^ax%-{UVu8*IvdIjU6`nR{ z4YsYY^#*h62qP5ASzL$ZsGFAMrsQ(D=F$8$HV-~dolUu3Rji*q z7+7rIyf`Ha6N{#dRj(=Gm{hN%+XDOZc;ks&l6`D6ZnWLjg%GS&Uf`ZbSba`G9)d6jWN`^#W+Lb1Y&x~`Slg$ zvyZr1UQ^aBR=7dMMF@eU{~p`5pft`p?Cc)yrOzV-v__*ayl^xfL}Z*zFerc`&rv5Q z{GMY+{b7pLaG_%*)!I*#A3;0<|`y8plxy0nmZH0=kFbGARO9QE-tTl zc=m*|>jfX&{azNgUZRu*%f*K3@{%8VZO-p_ZO)rhgK?hgEbw%sV`q5bQ1ZY3(kcJv zUtaOm(pQJIvnU}j*5P!+-Ml5Uj*DeW-L@Q>8h5$k-ek&8z4iik3(!JwFq`s+-WGgm zW%(OlEBO~s8)}u2<$_jAs>a}I6KF(>yP@Gtc<z1E=cg54E6}6lV+6w}K(+=BMTI z@p4D5DLi`y;I{Bd;$rE8`TLI_^QaQMd*=tap50<06zl5?K6y*>2S0P4x8{mD4LKIs zdpBg3k3X35<@<*`Zs2cz^(nvjbcM|ew3J{PT(coZ^QD(x@@JOq3Q#1g4y$vn6^oC3 z7L!f5DqA+oYmQvS@BQ>^914SW4mFGhEYqo=$RtP7@#T5NuN0OKbb-+ZV6UcwEheA^@>KOgzs_1?13}8w_ zJEgW3Q~SOfN!OUZHzw&c1o+*I2U3-P%KJP{e70N__{{B`Pu@1Xr!)TQ zdlkQMt#HMJi4^2gAT;DoBCX&X)hYkzX@$M-xZ7Ot=?4Y#e8RI;%{R_UHg)625p9F1 zH~i)|AMn~l&{~78DlV5Ru9j;aPF`a*yT?Wyuv~4Z)=M7D96$c*A+Jpw8iz32d);>- z0(_M}$MR?268!Ie#qz$gTpPp0We5wZ)f_0z)#8fx&o3#^eD=MweINFzsy*FwjZ@mzfUdD^&8Oabm*@9K z2-D#DgrKh1oGlhCS8MK#pTx~}SS;4mO-I`{eDKab`x3PF=gwNs3Xwv9u~-aE)1Y+A zyUI1Mn%f=(=o|`(9>B)dZMu=e_Ya)_!}wjq$nk9#Qp*22rPdUS^T%lJ@KR5SR)jy3 zYDwpm+d|La9J)MiVaI^A+-yHLQV7-bQa_)Qh)hw(Qlp4%UbvUd_ETMg__9s;ET<~{ zT+1tE`n~Lc9F`SJIby7Q1tNuGBm`p$8lmZM2o%x@ z#)V^NG-BCx%+FSgRf#kL)piJHz1c&bVGmAG;cWWCc)Nx5&@1B)Rw4#&+owdw?W&~fp=QykdclOGQXP_5f!ND_y z=0ABB{!d@Ce98FlW*sQm2Ws8$OAics((&@X;YXgn%Ezx(>?uKQ9j~8t{Ee?3@@o&4 zwB3sRsp5N{xyJQUKxb*zD-KUjnYW6!_n)Pk?XzgSMu6#R?p~|7JrPvSp>VxSsW;&9 z>SF@uB#mwvxrUET3=f+Tr#&rFW0^>YrRCkXX8h>;ZgF!Wxlt)vE4VouF_V5YQ3?UV z;e?>ohMCiR_fE}crttY@hU?`Dh3GXDdVtqJw=>ot)WssBGls6yEVba#^l4;cDYf;u z6X%##CHu;ud!<8qH8_6>$_+To7{d#@g7wLo-3ngb8~6AS3l0nxExf(3=@o0WgVk!q z!~6GIA1N$8lqDwd13=6?b;VRKofTSNJ{9V9?TdPX<6ahtmcpCB|slPGJzt zq~Sy5oR3Z<|7@{?70wId*xuv8`jH3yS(QSbSE&(Gsckz>77HF69&@~Ccw_%VEcS14 z+&Px>IR}O2-+j*wUfL;;&R?np7KHPl*sxeKzJ*>2#~*xV%5!@aKl^KMa?-YZ_^AVa z;(d3yQG#g%&VbPxZ8TlivO=-A`ZT8QsI}{r==@q0rlaWvfSh%{Ghi)(UKO!V;+`2B z)S{!Y9#=#k4>6o~6)*8a-?ZFC<|2vZ9CPjAc%B?yma)ue&Mq!zc#uO|=k(OK&AYeB z!-k(XtmIQ(wK;puobf>p2pEC}b9(D39(}A-m;3HHT1?LVGDmw$sgb2RH}Ss-sd)oF zLn(z+3RUzfOE`pZ6i!kKf7uA@(ZkLetTrs2qXEXiPEmM;C8treoSK@26^tplQYcO; ze<^7xIH;g9meLqjeYrFQ)5kQp7{jYe3Da6{F@=JyQFQ$ny~ zmOQspV)U4~F}zu?X^|A7z*YtS;A?Y!>f;9kQYm07csbCvZJD3Wd7m@9YM-X-#{w3M zbser-Vf2!BU$6Mlr*`?|)sn&)Oy?+p=ca-`^U)jpv$v-FH?Q316Hi{@_DJ~sU<@a7 z&-s3P`~;Kf1R*rW)Yz`ZnU;?{ah3hTQuteIgS9~VB+dm=!p2&D$Mu$9{ANut-t)72 zEJZ)tJvr@o>gkG?u9i#+N!Mw#=|EeQb12FA1#Jw=)tZyzQ|_vg-;lF@p9!RJ;7so! z?%U$l8ARZDv7ub{A|`7&rbbZM7H2)(@#?7ZcEhGcBK_+MF3jRxKc6p(f`i$JQP=S5 z>56wv1jY#zqNkSkdr26a6F6sR>zb3ZCC6t=N^2=Fv{rZ9{tMNag!VDdp49NiP<2D@1TGbLjE7BF$-*r>qWR<(|+|Z=00q zHapRjRclIxE!S4hwWMS1|yS;w+YLn#w@Al z6w+!^$yiQNF3uo_3)LFCX#pdA7*fU|oJXHxHEpwC-7L_$qqYVmE37IwHog*=REpNt zoLOi^#fSo3DGpVEtj6r@`rxMV)lH5H81CC}EHH?Q)J;QMYg_@fz_){u80%=X<@S{w zUfeAytiQy)Osx;tuCKTqV1~=ZIZWH~gT)EIQr|-E?_4Crdjp^=>KKa1@Qv>M&jP_KFE?p1^}$i6+xpoSM)-S!vnHDUQybHoFAlSggG zi2&ymrL)*V@P&sfeu~GfV+X^Lx@}oCHBwuYuvk&xghg9}H7&MVGo$0j-}M9^-}e=a z>*Z;M^JX1WDf#rB5g)$wG?nrm*;aQn>lO3W5@#&k^cFAdO?hMukMx=|y=Elf`B}*o z>A#S_OxU26!&v8&E5TTF+*L~+vfnF#8Bfy^f<^5?OcN~1IFxW`=?#69P&lhM7m&kO z*UP%W7~$uo)=?>tuEUvzVuW`Xb0D0!pn^D<n{{FP<;FDz^ZO& zTGO9bfwR69Zk<3FaK?c#c)>G^unwzzvRKMqDp#@@H4SIn^q1heZ8=@6=(-XGeRrTQ z(cO>)`*yo_ePV#S5QD69bZy7ks^(}u=YhMz!|^TF#e}nEL$g|NV=DNbCwADEz9S*~ zgw^(4o8dw~*Y=09Q0T6u>qk=0%p|v_JM0#M${CCRgQF-E)=5OuP!x)#7}Fuqo$(k9 z1XVTS^Y=TN7k#2Mu!p3S$kAxC2MZx^Wy#&?l=s$>e|W#<`V%|n@v;ZJrAEnN{ND(9 zZEIoYl-W`jR?0mpY~!ac+FTnq)dh$zrqsMVb%CZpaVfxEd@+TY(KZTQ>a%UDwzt{5 zUWQoTc7cYO+GQ?zmubSsuMrE_#GRLTv=I7ShkGHcL^eM!98Nf#EhwC3R7ffz5Khx9 zJAUe8cer(Ri~y#xpp=5T>u>^gijoe)5`hqkT?d^ueEDd>=O0>5Izy{q?L1IUA+gpa zyFg*U2;Im`&uhQR9H}*GRAHQ;a|VqEcvNtvwZQb76vz>caZAZA)hid(!Zv zta%`=vUZlPZIRkA6^_%^(ps;j?Gqq>Ic*XoA!v2Ss;*fy4TrPatksBiy+(B%Go#sW z94}p+p`5{JP1|-jH|R$kZ_^HR&$iR7J5ASlYMs`a-9j*yj#gO4r2?mhKD-xKlII{* z>l{iIjH?2r`~_f~;ACZ}wPEcf4?D?!{>!KQ+4pxC=TL=WG8!=+kC20Lhg1|J|2}{G z{UslKVvmDTpsYvWJL|m5VU*+=>o$&b)=G>}eH+|ts!3tN>VdB4Q$c4soY5Y*r4)q} zK53B>H=KVdLHPe}oJ3m>DszY)XV91FJz&#@*euSqEQ+G=8U%|oj!sUQFIT)idY+~n zvuZ8PdW~(?Jauivjgh1h7KNaYVpE~#a80`FkfKk<5C~_PIfKv^C)sq}Os^Fng=AD# z2-#qeXw&u2R-(#^;|_lAUmWwtpYxS_RThk@3aK^YUMa9B%U-Wu@)Pf>`2MHg&5d!1 zH9ncN31gtD0Z< zO3fQ?+|Q-hcu*VbeV1ePy?Bh_92A8Y36WUnY%j(F)_I<^#aHY&{AZMY#ujU_htF&n zIn`S8lxjHAj#f%q=cuJ%1T0!Z+XpkG?6C&tI1AIa{OY#j6v=#g4QDh{2fIQrK{69# zK5%`4?K)28b575eUI(4NO7DS3#yYh1{O7i=agAeFt*DAUjByyiN`WaPax&suhYcTo zatEBh?hv^HkbHj?*OiU4-o(yPM0k^I|X-kOZH@iat*EZrW;;=A+m4ASBc}Q;@O=Q z|MXOIZy`8qVcl7b_D}3{Cz8MNm4@GSYr$-!SdCg{t!8I7VT7PigU2@PO3SBif_4J! zKndA{KLfY4aE;uc;qEJAoTbnjqYb(TQ95gTNoKDhF^o||0jW?H`rK|*ct^jo^v~3S zMf5ZDzSH46C|35i#v)R5^h%Q+khome9NHa@M+Y>bWL0kKVb?SourbIt!)R ztXt0LBs5#`7pcSvukBt4e+KLjEBdvXjYmAYzuJ7s@s+vJdc!CQpJ(pAEQXm*sxo^gdg&=Q zvs|T^GBk;+yi_2JsaCo7NPWg_T=pD*E(anD6NI?!9)IrG7d%Iw%gy`aOEBdaw+-c< zdY-AQG!zla(bVGZL5k%tr~{_NYI1VC^k5u;r4lW(qCgwV>8e3CYp$rCkBpb>bOQhg z*W-ZvJWBU-E8DkMtuYi`!+R&Ed}XzZ5hVzN=_@0|MFefkmEY`bhIy5r^Eu&s>wW+u z^_4i*qh6Jgel8u!^X6oEwQ(q?DUG3^04fTnQFN?3O^ZS)59)H(Jf>4%thYg37E|VG zhq1LBsDjElmSsg#%&5=iyncAZgVPh1>$-0m>*56lDIv63T-y&75UBaO!~ zSgWzFLrD0WUp(aY{)pSVC0Mh;B=}$>yig7xo$#$?+qY)%s&CKl73>KgGza9b>o0?0 z-%BZRy_IL-Y%hZ1O>O3C#3?0J3)h{$oO*`9ffVFT!&-iznAgt<2aBG@}x!Yq9$?RB*#m~q;TAx6zt22w;nXK+HH``L**Hs zuTm9E#$yh4r-+9QZ+8{eDV!-i6GDPhl7BqE&Z|qwk6b_E&a`1?;>~bolQGlrh^kbc z>n@AF687)uW4+tx;cw1=zfU)@#QD*YFs9$@AdDAzvc_UX|8MY#Sjyosj=gQ$dA)b% zk|>4ZF=_&VRFch+rKCskQe^~u6O-=b#(XzO@b++eLLS|hMs3#Ow`g69sVJ^>aa z1*qbJWJpRjBjNt?x5glq=cJn+S#GV}bQ~CsxH2jk%^T*@3+0T2Wg-;<$7FZJ7uu`5 z_8NTp$}u-bOV;Z())*#}2@)ua!b@NyaJ|1pDJ4cqh;UMaZE85a4hzb{Z%B)D;!>`7 z$`d&yXPUb7bM~lVrV-m$=1}UX3pdrKPF*~q{(P!}zD#m;n{Z7E9GCKL4_`N2lpH!g zB~X(B!sS4Fsj){25&up-?{l4r6fZwNh8XU2pNE&u18r(8Xsn_Tiq?8HEvubx>2XmR zNx;U5X_!-6z-rBEwPL0^w6=6ejP)1#VD^&3dR+Mbjkb0_gU8X)VT30^30wF|y`LEl zvs5ya&CUBsAKW`HO&5nNNthHvXrf69pwdSO= zESrvFG)5Hst*_T~tw8H3&WwB@9@f@6kcve)VOdO(PM|EDl`{_6WmR{uUg0`VvBTD! zb{$_@8-C?mNBp6W-oZG#seEK_3oE7Ya=yZDk}sUVI1hZA4d2C{qrT&_cz&+?xv9}O z;j26&6-b3JKB+RwVx(8gv(B7XSX-=`2XwyclZqaQjsZF=sI_Ik6znP6U%cmzeq~>VTF4EKVm^> za7Lh!n4bJ+hopGpgt%RdD~z97o8EuiVy(d9DOt|?oWb@I(1-z-k&yXzzMIr`n#Nil zscRT3=v;>|9fj2#%qp%Hcx1cibus!RAZ0j~!X%~Wy%#zV!b`-KWx=hz9iBXC_+nd7 zN=GGODtz)(JBO(xC!=fp{d$*|&)(+!I}41pjK^!F5X>eMc4kxGxpO`#R7%lF2??!| zl!fZ>s~CczNwjz48F^TZ#@gJ&W=Khurcm%X3S4{v$26;y$9m{KcG(4;s(e#UYjLJY zCh)`;`Zj=D>a)iICmw6WXvS316;jaR=M`_r7~q$)$qnCQc)p>-S?G2Ya?DffpQ4-$ z_liV-6*v?Kg>fCa_vgkboNi7?NfTo&I{fGeLH%i`c^m&mm0M8Ep(-NA&V|) zc5~qw4Be6*yt3=y&Zy+bSRQs3t-)D^qd>|6=`_Y@pH(N4p$#Z-GvD=r(Mf}o7Sn1P z+hL?-qzy%1HQQeFB(#uq!?|^qL%D-;FgG151Dya|fx062`}GJ>?xRK$B?Q(%+tUL} zKT^dg=>dDrA$8vxpPym$8oCq+%$}3!=6*B!1ls40x`^Ds5QK` za+uoTT9351#^CxS@G)$S^XKd4{*>SUOwB*PS2Ndr0wlaep&#-1^*U3Mf3~{A7uGc& zo*ePXs|(t$p>Ae0o#x8k4iiQw>8o2M9zXws9P=i2AQ9G6rs$FX&Y2CE(zxEg9VnD| zM-Gw$bHrJL?ljg)I?ytvUNu-8-p|z%KeWkpzB}*~F8IO9H6dF-E zW(pLpA1`>Iuyi=bsRdJ>&+>}J=5SUV*KfWAuv-9B@gqM44b(-o{q(&XF zZhHJ3;&qCh@8V673YyD2XYM;?GWr@pM+RZ&|24vj|fJ_vg-ubih?~HPfkY6WUxO%=794&U1< zy2>*%$&CVRtLbUN=WAj-$960vyUuZHy*%zfN1RD|^nbuS$S_30WL7!HsHzx`MqF2h zwl(On2bNV=6P@Z*5GUAo!Uuwr^D%e}S3S^t|zN(Uc-ea)&b^gm1&XaC6L0zaRd> z=T?2IS@}+lR3N-Vm$L$^3as4aSC=EcaJt|FyGy?J`Wa86aTeOC_HFp8z*&#de$4!8 zvj+V|;S5$7aG>CF{_@qFoVk1W?f|xdR976+?lejkUXR^^F^)#Ts3@s+DqgD#zJ9#ouAKA1X5qcm z+bMdgDazu)9?RjTQh#5Bi<+yJQ*-4U2YDN%>7BTc#niaV1XOY}=p3CZ*IwRc7!zNR z+wcVO>kk_|)xwF<@+pbWoCR#Es*h=GId`{|xj~HVPmKUloXFhzhb^p>aF83GtM{|Q z8bfPfqTuGJr0Xopc1?%vIjX)dCk0!_3PK29g)0w0`QukcynJw-X`%S|oe5fZn>pyV zy%=h*=3(KZv(HS)7 zoO$8SIn|~|V!h=3H)kGiAUqD?nX40jDfNOV<4Wu*~g~FzYOp1!eq2ARQFWQgWW0 zgfyg-Qei0CWP7A^sY>pQ4dzUvcO}MZe<>K>`uZt_vbhv;!t!dhpw(Y3x zh@DCzO^4APqU%_%HPi7`>dsR4>sm^Wt9XnxvvINy3kBV)rFh=5=x5UOpfmb5K0J=G zC{*ED9ZK;BUJ|@{+VNli<{6^DAP@?pJTkhI0;3&93bd*))lGiAY53wRM||>l!4E%m z3QqS);fT?w>Z@LJ(FiM!O=z6Z9&G5qSiotdE&GnU3lflY{Ew4+WqswXq(oRK^dKf< zk;1Z9!V^`&tmJ%#ZN0X^5I5SkrR!RpGo0v>wk*)buYgvL3660gD5Xz|O4n-uL}2C6 zB{ZZ}hrqa4ZZ>B33}cX@D7Z44@FNpAUP?ayV2!m<$dXYxLQ2mTs4buku2k$yri`XD zzBS+Bs}E23;A+nITwkJuU@{qdpj=dm$F|fL;^1(h=e)I3fUB_bOwHL-l&jo4{_%`C zjhx?hX>Jo!NjZw;X7{<|WLxJT=E3I#azYSYPFyDSJaf-?n@CQq$afi%KE)G{UFyQh z)m}1#+9nemCled`7|zd*Eu7UI6D66bFdjr;ycdI0Fxx~GEE+${+(96E8B@`>SX~dIi!18TL;gaC$`9xL$iW#p z={PfR)>>Apj>ENP;RdXM=;yQj`Rp%eAp~7D_1{fHBMMY0%nDyvy$JMJ05AlPH~PEkUg3>4BYj)=4`QKzN&e% zJ>W!^tQv!D8*H~iNqFJrK08H;kd8tcRFC?0K_DMwYINV}7?9x@x0w&qcTLX!&TeR9 zz7n-T7wn=gMp+2{Rpa?co^u`s@ATbuYL0T6_sde8?=q+$I z$bRt{Ejhl>0m`!6{9RELR8{p@mve}*Wm$S-sIFs#;g7yJ*s9#f*B5Pr_ClwRZ24I4<~&f*ti;*9?9!`Wo!FcB37VmfwQu259ar7 zOlLICQ-7@Utz2y#kD9KhW=R_1Rl$t0*d9~hf_C2^n4+W?LlLeI9?pUlNT;CD+$jax z^xrLCvvh2k-q>F-g4EY=#gT%zj*?|jOeg4Miz*b~mbdu}UpnDu-nZlnNZyPMYfM@7|eK-k5p`>9pGwcY^ zD<}&uTqB%URI|=L1`^D9bJ&eiTW|g&tXEKUhDuqKay(o#ob|#ss+VaFyIs9V^d`AA z*3a3s5ojlV}d84W88l>ov?iX=SvGzo+AQ@ssd~cn5DR{krf#z09#}D2abNkBE z{PllzkB9RmWm#cSXj_1gtSKn_WVyB$BQ(XRU^TkUUw!3>KVG!Fe8*G!tdu?>m7YOk zjJcrW9(P=e)I2h*#KOPJ(W7#XUE6fQV?=vy&VAX%kfKXuUA{8aU266oUrsinb-0YW zUI-)$tJ`hDE!!^U94~#C|EBo!sp>sPMT^CQQgiQA;*whbluU2xG7~~jmK92s$X@Kl zSV`wf7M;d+4r?UVRo)ZZotqQbK-)YV6+I?HJbXs$0CTR8Ip{!l9jD6`>$Ue-pH4>X z&8AGp;|)FLV%x3%z4NbWakRpD^{8HfYS_`LPXs~^?u7)|fhY=$kXRvsg2D(ijuOvF zt&G_Sg^0e=H$ylJSOQWgoB`)FMp&%uXVNIXact10^U8HSlvwr^zLKIB@aThGAKXPi z#X?*RrYN;(v2TEG!5VJ@O;7FfASX7sh0aNg^COX}s65@Tmrae&+Hi(8XQNN3%A&wj zC7(Fx_}rpkG%9FtOoYPK79mQ0<&oecJ9ED0YKg|1kQ9BD-gX^Fr*qzX@Q??`C%kPB zSj#a>E2--hZnflUCHMpHy}_-K!&oSK{cR_?AdnR9`=LE7`atc;`#rwE_WRIU&;OPZ z)r-`4yx&EvjN9NvymY8_Ui$8PpDcLqPd?3G`xlS+yI(%xq-nj-VxbU4i4$X>^a+gf zAU+{$I$7}-zpnWUHynFAJ%CmCWH}UCk~j(}sHF34daEf5!;d3TTbPplD@* z5r(hcTk_&w>8*l;Ie%PXhee6jdUHV!9n~<_hWA!#tn9}al2NJn*recvA9#kp{gwNC z;og$dRfp*$r~>0E&x(+e#`ZD93QA!aUA@A8`Lz@N^Bb^RiF1kNV5XkJdJX?y#DXbt z8#)waNL@Cmx$ZWwTbL}w7OSatath3lLvE)`P;#y6@b{q{ZAiz8O=7~uPtB!cWMs-< zCM8OZ(~~1E0*;YkLicS z*7jP{?lI(e%1!05{JmmDOK}o^wgI&f|#dzd>m@jw@_grghEwY0h z0ejZ65G`xb;Ftj8%`7;D8Mq*SOCX?u=l9afYvKgL^!n|Bz-~5JqrT-{6$Lx8Wg-mD zNQ^UR3?m#fp*Sr|{`o5>eEQivkBk=Q34-gTFhwXN6*36U^-<1&Pu32YuE$0%=X=;~ z#t+U(oRd8*7SQw^2fLZuhR-X-u!+_CsZ=65|)@Gn1m$XCn(3)8Z4ipEHk^GalY z?bRL3>X7HhjrT8+ey+Z*8y=mUa&$6hZ6se)Pcmo1`s5gMcE*kn{KQ9};r-V~>?qsg zBYYxc&ACEcxUT2%%O`x&SsdNDbmst&>l4BORl+JZ1ZzA7U%_X9LU5R5d5!}5t<-dJp&3|-VGA_#tEQ_HN zrH%1c!%8qI46^H}HQYNfbY;t)(FifZXbZ}nSN4GrRcdc+Vwg68oGD1Vp}67%pf`Vhjtl9jVntE1U#<~di_`_mSd4TS1Xd`%dEB6l!AYMu$o~9`L?IT&|E}vE zyO*@qn@W9iFZA(fbEyvT36J$qs$kC<{@_aoeCoNY{LL>t;InTpXu1|>d-_1(fq`0j z>aKQzN(suHG5@zOobkW@-UEuhgY7PWY3*bB8N>50a$+Vq;8hMV$0dByRF#+u#Fy!g z$Ft}#Nr<(%!`Fysz;Qr|XDm7U&{V>Zs_;W?@DTMKcNW4~Yp#=!y3|u+l9WY^Vu z!7vBh=A@SzujJI{;toVgZ+?)6@z27yueI~wID_l?s2#YjH}w#{lIsC9DSd>T9B!Pf zXk%E_YmQG(dF$a3-zc8uTjDn3w`%^(p5s6j=Rr190<(^Z5*&;QMoMvIQZUzodZqm= zU2Jr%HbNs|%kBcbZ;)+tJ_vi$hCWm8D?B3Y(6+iLPjQ{M5E0&e=^05*W9+`dWDt_Vqb-ug2$9sw+ z3fIwTP2F^?>zY%!&u^;dcwO(X>S~(#Ayd)vhd=oYzxzGcxKTL@=Qd*ohfSXUL0Qdn zo#h6L;a%B1S$Ji_st^>`@${bH zKl$M&`SYi5D!Dp-o*soZbY(%N_e=` zhtFV*@y>XQ6-8NW)GrH=;oJs1^4G(IHc9hanPw9uJfNH5AkyB(#sSU*xqsu^I zxx^%O35Ptyuu9*i)|N|t;;u&ufo?OGQ)+e}2IG*|9tYHImu%dL7}`qP#uFhBG6z7+ zsW8Pf#m)KyvbPg;coejD3TwR{3$Ce-uhy0^a6<`Z%5hd}ZeE%38*d-6Y#r0G z*Prg&>R}ft4iNF4NhR_rHpGPs-Z@6nvL_v94(~1|9H++6_OvI@CAW`ZG{U_T<2KZw z3s4k%?{gFW1HIzE`1NC|s=^6Hs~jjxB@|1k_!ajQUs&#Q;7*x|4vgiYopP@pvnZyt zUCsLBn3t}X{DBWY!^iLLaHBLn*jm%`-hD;sGAfP(XluBITn~!Fd38Cz2kkk(ZvcY^ zEqA{+^+uw%>sqGc5m&G5Bb8**Yoyy=6t4nC!f>UM{M1Ko^SfTu{I$=%&42&pwO_lU zr}QboP9->;uX+7&$*+8;3zEl_l4;yY9nP>03NF!~^RwlO#d3)?n(1`L?#>R=$+#c&8BE(^ zdc4a-7@n#W|K100@y)Y_fAWnJUY&RScT_kj=!D0zltwdBmS6tP8GrO+GYCejsX{gU zTt)6uO0`dN60O_7X4?Y&WtVbn5V8%tmzqK6IMb<$GuFu6W+;;qcu7_9IUV+}dd=CT zrV^9z^K3M|gNq`k@D^TlskUZv-j(3@$Lk*p=!Bm;79P4ld)z#`o)_&AR7mH%F^g0< zl&7NzfslRsJ(^*~n>^+&htFI0?b3DIF<&g0FIU_jJ;Rw3oGuqkyHjo+JcYC!TK96K z0cYJfM{VG=Hk@>ZrZ$*XV4U)kfj~tprQ040GYJI7c$G%iw@amQDC4DHt!p;Ho*~(k z=ij#~OLQ+md7vy6nwgaBD92IV^4i++@=gWg34iam=KRk-u!rgYeJY_%sWXOi#?89* zZedEvjcjO~bQcJe6HI`cO0W`|d#=GsuTMX3Ev_1XcCvTodc0uRcK+$n%fI*CGp@`^ ze)d-%aNLctrN2-cKs(J6!Lgk3hT8KebK|S!&bG9thuo?&N8jHtnT*j&`R5JZp-c6qHO4Sfk{5Og{uiHml2Se5Z+~%#Ga6KZk{;xCG_P4M zEx-2a34i!QHz|6B2NxF;cqhbSNVu&9bIw)}eZu0sy#*;EPKY5&GNDYb5a)*1>d&|G zovML|rKH%{!G<8}vM4B3$+#MErO>>s-3EXutwTCVAxi#VUtROUwB(6hkHt|+o~u6w ziT;3A4=eI;o$H?7D5W=3kwUOouQ@tB;r^o|j5)N}m7dP5!|vD}M3SrB61bqH~VUL212a!Q-B*^S@96Z@y9*b3 zih`6wYsbj#RF$2x`^-_-wu#i_Y(8_9VyZ>FjrJ8QqlK4etkZtkj6a1+j|E!7sx2kp zl2R5+wa`=i?;MRS*P^)$jUCh2QqMPah~qU&iWY4^zurJWSVtusJEMXUNo{IQSA%|b zKTGGF_quKUQjUnSqWd7?5vAIAAWo|d zbEB}XKvH16n5_T*K*h}r^XbI;N-42jcV5up5YF^L)3B$!z|5JlDBIF@+H0dbhcWgs zwY|xB%#F@+Q)yb`(YD9h(5fkGUC|4Mts9ERetfTB@Ia3&nc>h0^G~-Y> ze(;HscmM7?{FUE0;h(%bcIhmvCDg}kC_%j z)oBpUc!^nUywhA!WRqn7xy4319s)H~W4X4kxV0+~UBSIWfq;rbnv@W1=i0n1g#|M-gUh$!i?DqYjz8pC4c zXq{l%<4Hu1o)$t-7A2}E5kdkE)mP&iD^%z89hCANE5W%ReD3^Tz#4JxM=yJ^rcH9+ zk2m}?R)D}*Y!U>dAytcIb58vtd{m*ukg`!Z3 zvMQ1N;S-ryxpB|an$@~yxn9$0&16)uJDpKhCB_(`_CNhE2UzVx=d1Fxl|i`Ta~%ZfF)(;nUhUTsmi6qYEtyA9Ka_|jAEPC zccP{j1JmO6_BQSI7}%HUF1(ZVj{|XP{u)>Kp0ee7kW}x?R7fi6*pUuZ3Qn<`KD&Qj zCiz@bBcZsm)7r9X8qOAHtX69l(`S*pyR6?n!PaYDcyfa5)yqUr4({0vLdZ#&$Mh1&zA}x2S3e^~9cEYSsNMZe4E%6MM6ih}H zH@c1|W|~*$11Hx9HLRnm3iR$ifBv&e{?qUAd!lLz#^Vu_(a2ZqQeLRshonRsgYG)& zw&i%SWVNm-1YF(SVSjJWR~G$uQ#}ISSVP@v&Kk>W#;~x4c_+YD$j&0PS6=fHsy!u0 zkZiffm%=89^)w-)O&@SqtX3<2;%3LEuT}i{FHd>6ZgKUBSq0DDm@-k4+q+|)zrM>0 z*QY#twPLsQ7MZT60u=(US}xeQh>4&>7OM(w5+LW0uD5`d{cxzyApCKA4JCi&gLxWx_TKs{(u^%S&$39(!*`J*oj{^gsBGb>Tj zdDff;+c<1zJpInmqrU@#64kq$$=)z!6Q7({q_dK5++QJur)L>sJPYLlZpV2a`VBk5 z8_EphBirvS(W@2?-7jOkj_eM=Hyb-N~5myRqh1k2+9QKQa)Q9%N=E z{Pou)Q+Lb{Jw2ipl9ADjsu5*boO8j41h!AgjdQHmHLKN%`$s37Eten!C+zcyXA5RZ zp0io15q3PH)0VFs8Ooycal@QrMZ^Wqfb;mJ>lFa|Km@*9S$=io>+SLl0HQ)Wh(jgFp8sh{8sIH9p_QQ@p_t}^2utJjw|J?&f)Q zo%cmwt+@B-mEM%cw0L6vim$-u4CQX_{q{qOj7`PQ*^4s`} zsfsnlLk};HFoSs~60s@iQxeGF6iPotOXe^Fq54z!yyKQn{2C!rI@P%dpT+Q_2m9z=!n1WS>NTt1p0~XJy2Kd| zm=mGS;f3`-Z^RB6taXm2Y5iq>GUxuoLk{N)zIEecJQNiV*A2RDxK%iR2t~KydG<= z1ZTWeq~Kh2a6r-)N+QaF=SGI5GJL)94^cbaQ=NKKjJ+9eEernY*DODJXUW~kiiPw+ zTJ+xZLKeLTvzI_^>W2Ah&8luVwk6-*d4bjq;iXSxDq zHyZ9>H%@nj7!<(HmC?5O8e9OVT1%}BC-XUP-aq862akAow&wNn8Q!YyFs~}CmF!Lp zKm4BSeDcnSiWVijNA>Uwt#zp0)0IAKNS(Xk{2Oa&JA>7lu9HY>kVez2 zB&QChQn5EWAH{4gJ#~%>FN>1tbixyRYurPRR(DSF*S|RDPk+KPtrW&uszCs0&;scH z*J;gS)v#FBOhv&+2=5}N4d@orYM#0}Vk{*H-y2TjVYZ_SUx}|Ab%2F{IRZPYcMpAmYWx!fZ*SC#ZEkIabrCUd5eaCK6 zij8QEH-&MJ0fGn7nW9ik$0L5^>4yL3YaL1nM#3_7UL2`ahBNJ$yD9(gH}^SSAM#yS z)(9af3W-wXd2-YjM|IP%S}&=WOO~rOhi-?jx~KV8v%_>(u)BYS@z}?!v&Dj&Q$zj8 z&{>NuOa339f515KRc&kzis}XVhV&as~p-t$AwQ_$f?hfqWWF-jE45r@OxwZX4TfPTCaI@ zbjr#6j7QBLVn<=yuBU7%oG9sppiw1nFCB};f_AlJ-LyWCNgt?0ABi_L!jMP_fmDLl zSk{dfkU2b=b9A=k^}Y8puWqua{bjGahL1e4!$|lbKNyG9b>~~hs}-wtgE0!Fz-fW# zyeG6n;?#)KTHuVs+3tcdi-Chb*Ww4z$ zPI1Dcyf<0DlvGk;gyf|INi$z^Jf84y0dw6j8c%4Aq3s-&0<*u%VO#Kb9!OrEG(20* z*%2!`9J&Wc8RPeH)3wybaLRvD;$AIrrA|^WVB@Ia}A9t=6=* zLa4%{y{!*K7EndOm)|(!gU^?ku4C0SNF^Ed?SI+Vej*|Dype5fT8>W6cyN5e*Ont* zoxDsvxkAH)Zq*@8jVvVlBa2)ebGBZyZgm7uwNzEPk<=AZVTB((l!c-!N}ntVuQo@( zD)9l;ZFtgcr#U%Wa(Hsee7U4HS5U@zcRJm>a}8!8!cp{{`Z1?!kG&D>l@cKxc2r&xQsM9hH&t0s3a{t~B~B^+ z!J7@=b9>ISdkQB6r79@Ob73QZRvVV}n&Y!M4-b#&)IJhFLNaZG>(*Q?EI;txyB@^Z z$2Q;Lk&j6ahs9x$yYzCp>D$0xDKJ=EC8l04*RtJ)R8LW7QUJ2l<$amESooST@;8TQ z52qPHO!&-w_~7`Is+)7RUZZ-{u@hjN^`;Snl9cfm zofEzbV4S7xEc4ZxWovkJ<$WynpQq6!>%{`MUP0UN>6h+oXi7$RoSmJqtQ$@jOCB7Z zFh5&x${kcC*p(JhI?kkJj-xFL)=1`cgIu4{_Cgb*(TJ)nH`VmIZhZD%H!RmH=JPp6 zr*r1^CZZCXgv1Nz6qLo7R}X7;Cks~f8tq^_9x<*)jOF==XAt(-SBhu5H7i+ia;6Yg zQ(`%8HH%JxkaW&r#uL=R4&Sb8zBS*a)GL(en8>wXhh7h0UhJ@*?9<2zYcb_;wZhEr z@q%0MGvEI{e?#@N=dV{0jyYQ_S&M5ROPm%sBR#5FNK`fE+s7Rbj#qT` zie=Lwm0~;^_4bh?s;YbpgFsM8dVhMuH|rhV*nOJn;3{WlEz7et%ax`oG}m_|UwmVZ zz4s8YI;3q44&{YO3UB*4sr+SI76nCbdg4%ws*>qs#CTLOos8L;P7tzJtLypuown5V znpItMx>$02vfymF;B>XZiG!XO?OQh9M$;z>59cjSyegbrK4Iw7=1NKK6;uA)=N5eb^#wPI1vrfm zp5yOi#mVYAU--J=|M){CP1~}r*UT3yj^=YtPER;nE~q9qm?^<>Z4jNn8NpI1rdP+T zG&HL<&1%KE>nKZ)Xs^nWQaGgYN_YcUu`Con^U+=Y+!t!xq@vRTi$Dvn%7}J!wqrGs z+?(EFRUGhJ%?i0ZWzwDbWTj7US~WwLGfXvMT~y40)yXNhC-8?p{3JU{(Di!r{sOg3 zO~a`ip|F^8%Flg%#ee((!+zxpj-o0lRk0D^shgIg(^Kvr9x-36Iouu7IfrgrbiJl) z*8I@>?odc@+S6N=loyPtj4_mDNm-T`=%+;rgq92JIV#$=R{6GnlTupCT^zXzG}iQv zFU1&bz0LIGod~;JCa98ojhr}3N~k6`UbsxyCnYoxquz4@GTU$pu{7^x7=un57ONFU zr*n=^7p&`+RvYhdWjcg4bOzp@zQA(lDY~Zh+;eNGlwgEoM@YKagyRN&;ngcVUpka2 z0K<%x=dEt0cfIUlFUsP2Z7*vD)=8GdT~^nhWVv&|!YWSIE$h0*wKcaY%e$`6C~Su{ zhShS(!=n=pPv;z+opHLXX|3YX&Na%B#Cx~wDFYTQj zuI}wol?8<;&XM#&P)K<0U>8+Ow43pnZ_hbt);y}Ac7j4#tQ5?xVct5V5{!1PFj6;A z!YiQ_&LN$_7A2i4STzl+)rw|y4_(js*skM$|GVDLY*OJ&hj5mY`JA^N9ddLs_p|oZ znw6Y#Z@k;P=!GCcKdbx~Z(CkeXWVwjteS>W7R+X2u3g#ZU|%4Wq8unjF*c$<=hM*$ zTfoh|G1H>MiiV@k(zFs;3aV0YW))xJX%5$Wtj=n7M2FBVm0NRj(lRbJ$1B6GY`8v? zD4|$u$*8E9%|`4^MqInHi@j#5&xHe zx#my4ca7{iZ>8FIJhag??V4r1;_&EzQW%-++okHIheFu*;Uxdh*K@8 z#fV3G#dJKTY0r4;-XrcE9jZ;vu1sALbqJ<%>I<0`krU_;6cS$SR6g5RTb=xEB0i^J=^Q{ zJHgRtm!JFMA%Egs4HKa^U^eF*t=24;YfcwuoYf8YC(m+ZN1U!}n$;X#FZjT%U4H+^ zp7Z>C&ZVcV+rrWsXtF6pb1KM(L48|gz0KM*b;;&9(K&H~T-!X=S`I%`%JMaZzE4r} za>{n83Ogrvo9ZOQw7eAJJZ@=k`!&!S;x0!@2`^TgOKIqborh3>B9#<`%Uz~BSEw0ts3pg(<80m1bsduu_9g|mmb1C0(a;#hJ$5+K`-}>Q zQU>XK>rM84-yQ+pQ>KJRTO&P+*Qo+m7C0fOS1rrVU*@_wgKo|DJ%7;8yBtP$ELUsh z%O&4FbsXudtjiH^%j>MmJ+Aux8gCvgxIQkqB^^trIjtps^;=^;zI&Z3-7!z>71&B~ zuva3bV7+cRT`swIy5P-ISm_<4I^gy372e>0xskZln*GXnH#1$Mii)=y$$$06K6|d@ zxvJ(lBl*BgZhWgZd!ui|J8QXB7~Z?<_{zTEtKV6%)}_~_Hv%oeDv(AZl*36)Cma$F zx)IKzt)bH$rq!5k3GErOTl4$gb-=&>eJ?S>cQFd*=Z&Xl3+^8+dF|A3)a|hrg;c&8Nt}NrCF5$u zwJZDF+?n&mdBf?lWoJ?_Q7vbbELMu&YCGPXw7h&{jAp_Ex5MkkugAF5jBZKhz}M=I zwrja79J{6E-tm$NhMm)fXD3UZ?^>+Y?Cne$jV8VwEnvNFIXPYM#_@{Rk1Y?DJ2cZ9 zFuKa>OmepDXxk2JJ5U|1E&;{cOUIx8Y{7dE6i@9qp1IcXVr98@)sGy<;}JKMWJlg( zRa-`5gLNHU2dBjz|MhnYo-#)~Rh=-R1tHN^BZQ$91z)qz@TKJekJgsv^bk1X$!D(d z(?9$^ZcZd+uf>kD{S5!S+vA{@)*W$O2)^&G=5POI!*nFMvtMy#ra)S5?H5>WI6i~g zPIx4yOeI`DD5+G#>7zql-XC#mx8TjU8ou*j!J8+R6T8oudYU7#OMP1MaNe<6wSD_v zpx1`OhXOkp@w1Ogo~sI;oOV2SV0o_4?C(C#Rw{zn^wS@|#;Se9fBW@?AH@j+qM%pK z$2f`6g0{6N1wv?q^H#3bSvu#irpD?urdy)inh!j6z@PZ8=XlrEg31|;u@u55KUFp2 z+Rlv9F6gvFccw?lOCF97_{-l~@X_%pPnRbYuI|%09)zPwD2ziAF4_ z^Oy)sf(DmLl*0A54ullEruX^h<_0w-+CeD{J4M0Oa*A+{u5GF3r>xg4I7cfrhbzZn zKXcb8j8F)%rdB0VDbz6eQ+_7xgaaWFs9t(=us-z_sqc5UIOh?hbZf?DjcwNm2S4<_ z+eoW>y=-3;p6U^wX`bY)EU867V;uXsVRyCW;bO@fD~o9r2PKroqPv=vlH9j5errA9 zwMUvCZXN&8Es1iT+*V4(o6Ro2)ErPu6t{K@UO8=ev<9uuD8+($V!0|LP1|r|G{$Jh zy;|^fH|F!Jg4t2a|9n?*_eR;9b~xk(IbA_11$QU#d!E{*H3h%+%AC4gVWq@K*<%zW zQd%0Ju%hq*!)k=n7~_%1ZBrw-T0 zA1@qCkY+%riwz4y_2NJS%g9K2_U=_GX4VY>ykZqQxhyK^{bCAKbj zxa>d_yyYf1T_S#~=J$U<^T8LUl+tZH)HioTe>YVQ{`B|Wk}`lvAV@}H3vH-Kk-_I>+(AZRZ$=(W8QPU z<+I;jfv&x(T_t>UA~-0ZKBPjFB_N z(P2T`8JzBz&`=n`+w+HL-LbAa7Ar$*d^O!T?Y*6QVTnN}T7bX6h1zf~5d!5TUVG95 zY5pon^Ih6ji~ptm)d8#z+oP7*$b;j`3*3!Tt_ACnb*_ zIrhsnWmhm;&N*of%UbiGYcLbX?VXA{&e5DKc&)ZPFa@HRQA&j^6!&dG?O^13kq!|H zFA2tl;>BIXpLnU{dv8zqTVHy}Hx3sxx;H72FtT3QqmzObe6a62tnLt|;d`IE#;4!& zZa(qc4R)19>TaV^F7WgliQvlKF0-lR(TPGAV4H@zIb>{WCTNx#PFqk8FP-Djl4&AmaYssoL2x(|LI9iWz8cx@ORoim1hS^N8)`q5a9$^kV(i1*&Jm#&g;Zsi- zCSyOY7>_GvyE}BVl6kxGCO>M;Sg$#KbjI??bKI>kAUhW2nsu>cd3eOCyNW7iPzapX ztXm60Vx6bH72^><_}*Lm<8Qsr;%vpPSmDZ!vU4oYMjV~B2shzuDVXh5+_|Z^zEgm- zT%E2tJv`yvR|@{Xzw^A@BUwnhl zzIsTdJj=sVK@Gaoo(W>S9jY8F{@ABp;P-s^32scFZ4I-@ghx%q;kv-+6l#eg z^rl3*zpNZWDx^>#6{;$cvPbhf!J;uV+S38Oc76iLjbKs;{@{nM@$u)b^7H@vb^iWW zAJSS-y+?x(9;D~zAO@WO4$gQw-Lp4#_#Gd7lJ9@{4o~lw>?()EBAuncvtLB0n^DgA z^ot`t`|yY_-CLl$&U*?J1yWU*s-jaR3tf1TqMrAUYw6lkbiL%|>m&Zar#`?3pV(tZ zTAa2RqrF_Rbr%#OW5vm#nCiODgX4bYXMV>0-XH(b3u5#su5#)!jOW&=wr)-YCT{WP ze8ywZml$*xn*rqJ^0~Ho{2uYFJ~gjMDdpwBaJddaZpIyB0^$)xP9-j+iETr$r_|-P z;RKl}KKHxWM69b{%JJ%ea8)NFl6a-B?ymp@n2m!NCNs&Pv{OYme)d!nGZyYZ0cy zY3-{o;GewK@~SSVjpHLv?eXMZ!S1-^XwfpaCHtk|N@ZDS%VF)Pq@=VRue^Q4D~pcz zKXJeh+!|3i13if5-pcUnhu}oV?a7E2pSa4YGaR>;PJ0CVtP+fbW8J~p3OXbB##<+x ztu>v4-}T~Eo*fxVr%{3n!XQ1ge&aFjoa4+Y?st-Vwd0q+`G_}8);yZ8IGr!io%VBX z;K_p>?(B^C@Y4r;^qFfswO_HX`pQjfgfSG-p@i_2WlxhTq~y(o;UB+cdDJ<^rQoAa z?(*c0Vx}ZZ2ajq?YZT6Uk&#(xxiJD-&F9}d=9{OQrt_AnKm6hqKCtiI_q;@?xe$M1 zK@A7Iv4EfbCvP&R;MFT9AfODS6M`Db5MLeb2ILTAq2L z;LeR1Uw&mpU5`*sgVpTrR=oSp7=)l(%=wv5?(*FADN+jR&hX_0eEyqfoE){h`NqI#mi4$r7Glx55J+!^>V&Kz~NcV z*WWs!?JT20@`Ep3;pLkZm2#fvPh`k6j1Fbd)7m7*t>EpY<(IzlkT1V^!W&0R9?jR( zX6T$+uJ4SvePzNE2QxnL;uAb~ZOXw!u|I;+c~>-P{g|&%=Q729j^DFv92{xIgI4le zZ=dqz*AF>fYaY(moUSzsZF|!j$yma{wB*kIh^MZO`Tm!m;MT0-Y9&y3;TfkpoYB4b zj(yCSEW8WDJL#|d)t^7V&_kc!%PzsVeV(FK#S*4*dwCl$Eo{NZt^JgnR`_$V_(M+g zW}6gk4vC(s{!__Ls*91TXj9{bTvucp`ak~v;TfdH195^9CmpGEk1zC%q+y~`-*gQ6 zKd-H%MKLW3#>%Ur1v|!5e;gO&Ji|W;`sd=#@dm>|@@iwfI0qiZ-8d)(2D$mSk*Z@+ zVyxX*(JCo1Qt_yhEUln6mX)?>At^Zei2!F8@N>CfYymJ`qu@EC^7z?l3X0)MD@-Z!o&AAr> z-F38W%Y4=F*|!@0Ki};5t+y?vvy`&s-8T)U(R}-XV_7?pno+5E|5Fo$l6>QyX1Ovv z|Kx<*H)ee4l_jfg;>S0gV>VSh_e4oiNWT2qlAnCvjGzAG6|U}7XyY(KP1T~Y_nzvL!kgEO3&H+KQ1)4d z5T0(SggZ~16LH>a0Q9onQqnnCYM6J9+Bh%9WNiO^VO9zzN-!=Y`;}xQIk#QL`R-z` zx3Nhcg0W}FISf;J8We^f45vkdEj8=~;@{R6v zgv3ut#iqItDc7!;_Z_3Xb6~<8?|xgWKjpHP`nheuxs*fJWr;}&+?Gn(LIizE5GUs2 zI|SPJw(MA1y0$}0<;^JQeV}`N_6>UTTrnp2{$>+ggz&R7C3|Ho>?W`~XOK8%N+6uX znBgFLp$r35ZlKgbC!xe=`>Gcgks<&OTFXdkM$&`Lv=H9U*;tG)2qiZ%mKNawcoqr? zSBk-RUH3Auz2jbgXbWr5*08|;j1X>fp%3OA8#kKXVQg3Vi_lry>t2h^Yd;2HHF}`# zo@UZR@t}Ku|AL~B`>($i9lmO;Dc0Ut$$NvSQ*;` zh&-O6>w3kz95nkMo!)!AN=Ir6F;5&Ti1(n|<1k)TDsD zF};CIuT_G;S+6mnGV$N|#}xD~o2lmH zR<~UMA&NV0k)>R*Vwu;JSxMaL4~+og>Ux{1U8+SKj}^92yTYFhyBaw^^UJ7W+pJh~ z+U+T7+cx{!_}PY^JHFh*4U+;g=8RY3^+(8!?zZefI0Ef8#sQ}T=}dVJ?b>9dj!hda ztmg&7b2En!Al2qj4S>8&#V^k*0Ri4R5m3%zJ3}{o|3Slfcn$-Gyl?wkV?lz^Ltp{j z^}tH!|2$;tuD`5?%EKD73ABSE70#Q{$RT+hoUD2oP+>%LR{D_En~Ol;k)BwSfXvq? zDZM8*K8X@NkZ1tJx}mive8NFr`461_A>fIGw)&vgz43U*VN9Q#X$^%!I!UE^H8#;# zAzma5RVYSEo*VBVH@2E#TR7aqt98v{x#a%gA#dM5;`prQp}Wc#mL*MD;FdM-ySu}W zf7flk=lLC;*qfj`hjo%dNjj}LT&$VR6kmOF&R1SPVcmAT@?c5bHrS#=+J@<@26nA~qGeuwGoo^@b$Q&|mz6 z1FP$$Q+)?Z_En(ktIB~leXg1)CIWcm@-HvA9$ z{`GgXw;y#vpy*?S89D=fHQt|fu}N@(H48ioV)skgch#IRKDiB^w?xpj#%ttDU#+R zvMlRoTS8Nj_-6&l?%Av&RSI9k4zwgD*DqYq}aGf4MEykgTmXwO6i{s zu__-vNIEyzRQ46gASL+@d<;b2#ufD6dEn0uiGdqHNpV2zTYiBdPYm!pH{a-kZSR;j z#3Q8ys`TeyU6=u$ufG@sLWD&iduiCgRqx_{)xGWMYTa^pe8R)SLmoVO$b*wLUumD= ztlDQfEtsy?eE2=r`N@yn;$1f@_Q!(4by#O9ROubR&|IG>CS%1XpV{ZTpWR1DN!`K! z_#1EYfB&U7c;mEXcCf?M{XLYFtZR!j9YWW9?X5G8)(70!>66laHN=L2!N#@}CC;sa z`+a7t^%t8I(Wo=Locd?cYk#X=cc$ps9Yc3ybN+fs-9ow^k1|NH2ma*=VAY^eA4-T` zWVXH~e0g?UL_W%9d z5z_Qsl0l|3~+T4%psJO)Z$V4JGc^_G(2{LnbLsbt)+PlKS4TATCF-_v8q|ibH}BA7T-LJ;k}(78gQ)T8238UY)-;8^tLG%gbTST=4ue za>*%;is2cZ+h3kbw~E9b3de4tLtwm~;qx$Bv#uK+93Au8oA)_7K4j5Jz9e4aw`#?6 zS1ZbH%@4hFgWvJOKJU6&Fs)$R$3Iz0oHJPCP|o|5fF3Gll=c#|J^&kg>I z|Na#|^TvvAy|uuJ5xO?GcFFS0@NlPP*}_dJeWhi+!O3tb4cHK`8D4DYMdxEekpRq| zKZ|g0tAyj^@KD9Dp#9z~l=l$VeIlH~Fva_JpssF{`5xN;uD`Hdk28_I8I9Av)h=aP zX8YWn#4qhI#}7@pF2s(ZS{3IB$*@K#k+W^y6PtY~#iqqC@iNL`Vk|ab&vSZYjNQt~ zd2c>T5csUMC;>&GHp$wsxBdJ-dRF~<#p|C_AI<5L6ggm8Yv2E&b+mfwq(ylq)dVEplz=^pk zJeRDc)+v4_VY@%4D43J`&28iyJ|NXGiT7X%fVd54co{n&<@S~vqr|}|9);w_OqZ>H zE}2V71II~ON}E5|ReC4qKL*7Pzb|`bukbtO42!~j+%ye`$H%-|GB!W^1CKJp5;rHF; zCx7lYIXtYuwK#3CO^0nQ&VaUkQ&o8S(l9Ox_g@^0b0fLS;!Fx)n<}*8amY4l=y3gW zVB?f-#qgR%->u4Z8e{XCFs6rCn<0LL22{C9I9A0>orP2^u@Ut#23n^&tzk^d#gq#m z-~}bG{n6J9=}W$AL8jk)Y$qJ|N9PTm8(DOhS@2ktk zF!5T(fW@3-@_>?!$7b;!Pf<7Hiy&?XhV;=eI1f0Q94;f*4GQ1i7{j`0dGP3%2Ztwo zqrS%L@+Q-2hl6p+&H9*~iQ+?dukh?uiFDeV!Z?Suo=L!kz2hrbfuPgcgOZ%>XP?6B zCUiAF`Qbf&{x<||?*u0McIl*06vEGtJ@&$Q#22Ya`X7-iQORwz47?FY-8c1Vsh%fxGeq;-#3n>sq>#JTyyf< zv2|&VB@~Z@Q|lkbtW-DoG6S*;75X+BSDZzJ?U`+tM{J)NR@}Ko3onLkm1`=Ii0wy* z&6~Oi!_AQko+-=Jl-zBMd=EG4Wt#4}S#(Y;CO6+tZKRxDe7tFLU4_(P8#Z3b-#$(% za^BIYU=&s|@p^3QB;*jg@xDv_Oz6Fx!%W0gYP^Q2DnGpNwvCZe42t2v#{o62vQsL9 zVS==+J0lW4-?{UV!?dKp%S4!9*gLw8sG1;b*n>-qB~PHLompc+Eb+LhkVJ zzUF~Fp;*s(*Rxl6>dKf(_3dZjTf|13k2+Ey-lDG#H_sE$UCaDz$xGKQ6FRJ#VLFYm zUdr|Mm5S+TATpT?fV0ak##EvlKhu=vL#klN?T>AHAY>ZF9n{OlaiL|Wa~_SawZ4!< zhc>}+M_^c66+H8}a?YLq@L8t5_qO<-irew!8lUeFTa@d_r4p^UEo0(vk({fb{_8`vyWL8LaswmEnTM3)2*U6H_4Ls%l$zAik7ya=w@O9E9robYCF78bI&zZ*~Q(a z;kDw=6h6N=XoelE3ws@?8;!Ma*p8Xof>tX|mzsMkL$}ua(1))wEd)x~3v<_DvKi|$ z#4Y~|YiY9`&T|mUth=@p~H;IDV}-PF%MB zsZMilWE#ih%Lbh=o@I$ZrZS%x9xNK9e3qMP0MxK)#PI2ku;FVhcI4G+C0iJrz z92zy%u}WzXq>{(@v&G=1Fo8~8Cb`5j+Bz#siM5Nq+b6y<>@I|G72VbgWhlXUlqnvPN5+ z>A1B&=K6lcWaQoau)6n=-|j<^TK~98-gZ9Xi#jfl;&>Q$iE`b#u(L44?O2g7?rMeW z>G}E9=I4j^ZQFLU{=*#*Cp@{>6t92Wjt&v|IVy0jqncCNjN^aKvm=#&#TRa>FiI7h zah$pA{Kr3Yp=uwxVDW{zZ9Y<#WwH$rUplGTM@~`goglR17DFm)N_m*aNcwG{x-e^t zD~D889VZ1jSGrUco5CFAvbJ37JZ^EunQIEzk_+g$pxuZ@dXoC`NJh}@ho|@JEaPiwV*9Etq^lFrZc!sV>``zpT5D3-4bIwZ&@k{iOM&8 zu5l|p*Fw!z^Qo#Z)r|=+!xR-awfoxZIMxq;SJ(CCGmS>0WL3X$ z3=15@;@3%a_)-PaaQ4HvlA|ccVC;c)vn^hxuq?5YW~wWf0;+D4B~QiflsKCWFZ387 zk+V=ufqiml;nbq!S|xF3V4L7Us%?}*z;|8uSj#0RuNptNIH-#Rttj|@wF*X~ik;~gg+q6st;0D3XoR$U>*0d4^%cfb&sR3ac;ORuvE4h& zfQLPIq1Emzt98xM$()nZIj^0LXl;pZ8mwM(Fe~}7?|O#oyTv&L5WJ&Trc0Az+Qh<4 zxzSMU?U1^N!u3z>xm-aLezxJ6go$Em4j=BPP}nO3o`qP5RAQH7%nS*C{O^=flx2D0 z?}t4)bOGXcHavr&+Ys;haQ$-~*i_s|?fsmxW@;_AfxvSfBVm%9i~oaE@CDjhDtM)+ zXF0B7&htCBiBgF{i~vq?sdJQy)SO`(ttXXXg@2A)&Z)WaHfhzIo_ngA9@?9^*;zbu zOwArs8GZP(L#3MAbeCz?Z*yOZ*MA!zCx_gRFRPrQRcifHZS8O@5GN3+Ly{Y*q$pOY zww_F=sO2yfsrAp%nNmq_3al7c3d1ECSJJT&QJe_m5Wd@Hi76C+s-^yz73vms#_;Eh zLNTf;_I9RRAD?mW6s#z{!kQBZ(eaJ@EB?`!PWa&$;Ofp83yi92V^TveeVQ7JS?eWy zm#Y;IADwXj;W6`7%h!(gSm=_ro+HhgANuGEymWVmow4*<`u*%2T+%Ef7rWwTI<%xy zRLj(uG1P5Hv1f)D5w2Md1Y1?rV;5Jdy_>@Iq{bv67AV(gNZlX9d5z=$a5loEVThNp z{(N|Dl~S8gKzNsgm*ln>6<@R|yiK?^@ytJ7|5R}lu78dqm>P%1>mQCFiugdKD!5c| zN*&hRd_2BDQq@?BJG-q4y9~*j3e<6hwXF@6t8Q~G?)VVK?W=7F_f+zbYiXw{{B0=B z+;}6WTc69!;{$LR3O6^WPG#e%DlkW#ihn;ODk*+w{5`{i90TFDbu&@{HirVwJ^R#5 zJ5D}Q7VqQ^?Fn>3hWMAD{VDVjU*A;d71g9dUOt z+_wX0FD}kPY)?)P;xhhsPPsHi)!x=p&vo)ru_#{i6vBRUp@+1CTstk!5_6!XRI4X- zvE&ruQghrCkSlc&Z3A1y-zBafwk=-j!cSe&sY)y*-VtxUPX{^YJB-+EeG}TTqsY*<`{G zy;txzzjUA0mf(7^RUwf`mbKx({0)UOC%o&rLR;@!J|0z!stP6Ob+rXur?JMeZdw+r z6-UQ&j*sV@oGrQ6?en>}Di*DxULW(_@4v|(`}Fg?`}UMl8ZSbR-6)x*X4c{7A1;=- zixr>$m;#s^Pvk~Lm&LPK3}smVFrf@l)-jho9vy~zAzuG@92YVSVj-Droy>5qJ?syy z^#;$CN^0Zo>5u?~E%?;kl1ijmRRu5d)XDfvj>tDW30a z6IDr7DY-U&*j~v!(44&LuyMkTl@dAG7O-=P$~Nj%4#bqh5yW$x)Mn1n)wY4!VjMtj zED~m~A#g1PZpv{YW3W$Zq!OaRQzAq;>)EjK%YElK_@w;gV^ChIlaR}hx5@jaKyo>y zs2m?YH$%THVZ00<5huI@t{{A$uqun`NhuC-oFIks-FTiGKA)7pM-JT^^PZ)YRAmVW zZmEKw_~444|MeAC6*wcnNt{qPQE*f{{?g|QK7OO-cigS1q@yg0jn4kyWM!_5Q2;sULrlk3F?Z+jKZ%Q8+Jo+DnC|E~Ff7G>$p3 zPeLx(Z|e+g!;yrzgaO4Ko~O}hv`H#Lp_Fhx#Nt3PcRox=;ExvoME5SWt1+=dw5 zrfPT@Up0rA4_k$C%Qb$_oM=w!*~fbz)vnz(2FfJ`IiOQKGfYudA76jTs49_C@TY$0 zDL(hjFY%>Ajj9S};}UD3ZXKo*)Rg>-`+{#SO5S(NaBI|1v`Z##g>nYl+vqwBji~6V zs~n13e0i?<&f6M|#;jUC`R=Ry=^uNM4?MXGMpMe(d8`M-IVUe9sv$yq*u&x8ii3CD zVoqT);`kBEWQRW&CSEC#uCQ8-JEbYyPK-mzjZjhr!?6B2s#T8S85Uk)B9cmIhSwOt zadFWRKJTziA16iOEPHs*Se7<-enM5u@R`K|O4|z86k0xoUx?3A>OD3s_mrSO3f-G) zQ^w{UabSyIGe$|rbc`@-dd!*=9&1zOgf((i;kJu-8#N-;8r}xdOSP?2bg5iB<(&ZE zQi^ps-T8Rk27pD(^^9LDxBe;Pmdn;Z1@?$J>pAnEaQ#zl-5j7UXPdi?DUlmFr7ruF z1#p~zhQW4QP|vXoQVC5CIh_J@hE%uVdxgd!A)qLiJY9DFLxGZ5IW7mHjMqP=QEe_9 zpy*%c&;PNP__M$8b?$XF&p%PoIl-&<8x{*e-4@7MLAk$+xH)5CTjq<7*WWy3aoPYQ zjDfu?f-6@FY+bN+1=Fh<{pNi}Lh}2*_ZfcVyKnQ-6BDHFXtkw~-qzPRi%Yb5Q)eLt zAf`ZZ!_N*%dMTgsunUq?my7im;`kS?$?!T|*FB~YkP>x?&wnb8h825m{Zo?MA;V#q zeGg2DvMev4*~5JsQc_cZ#PC^$#Z8KJl48`vt^T-Z$!Shp*t5}E<}T{g`A>Bpb7=g{ z_q?nnkVDmOqoRn6Xn#r(F8;USqHJqNq^jA}TyI;eI(&$!mRGI~7*`NEFxfV6Vf@`w zv&R%)JI66inS;c7*r{5=za@Q|;9-Xy=4Ow#h?=6uo#~qeW+ZaQUDDqeqZLcOxwzBQvb z*yrf9#^@ zhUXKSZ1uKKQ<8_#;2?0yiqj&E4_FE*EPlr1!PQfkb5!_td^fxmKoP#bwf<+d5`t zStiGlpDN^4pmQaq*{h&P` zp8xQ_g$Z*wqffCB!q2hI$Y|U8hp{2o>CI_>gh|H*VVP8rOD$q>QFgRpsZNSBeG{&qq^?fgJGW zvh`0K>N&-fvm9kFZb_zi$DiKg?({0}fBqUT+!>*@ zrL7G@I;3-8{l)G~k7`e_6jI%X)cU9N^W$nR9z(&vpE{@>NJBeKFf0j!WUbNZO}{i<)W+$H1t|(BJ`W5t8n4n>5$9O}$wS z${{UtE`2Ha-Q4=8L>^KAk=VT}Mos6mm51+}qPGpym-uMoWnVb(cbbDC#a<2yPmtw z2k#y*|B;TBF+5r>`P{V!tZTuIYZV831$?YRQE=^g$%kLOPPaC+Ys+{f!8!_IafL$( zN1-InnhQMhRPnLRH7tjI4~3pWnpnz&B}Ds&NyG5-Wm!I^%$BO;!u5|qqjBpu{P(%< zojU(v;*mQCaiNjYR*2VsG#XvlTf^(eZg0cq4}Awxc!1&jr#fgkdS#B4kxV)>VqD?+ z$BBMQ!#>2M#d|8H4^YHEn37t}UFNxpU|aiO8$UgT#*HhaZ53lIz>&K!Qq+>1NK8)4 zI|YPE&6BpxlH<02iV_xXka!Lrw`#WW9b=#HRF$9VEDWHzZ9+b|u|$d&8}GGLwVlEU zq}D(6eL~f}_~679OMGC%b=bB)bINw{e@o#d;&D|Rh*Q;CJm*h!t#U2<7`dDi8i_|H z;f1hGsy2RBDdCxT{ZqiA%a}At*-QZlZ(}N)MOw|YP>lCSXlHrq+JqOb9iThGXatk7 zq-`wg#xNR5ra-40MP-o~oCffhxe@}b={o^=wZfeBacWGMN(y7fNjxqL_h}5qjn^xM zR~jz4@Y0TF-%2UEuDj5&iUq3TPHT=al52;DDsS6xG;ti?W@kD8{oeCk9}r zMsk;N(Nh%d7}z#2Z&IMiRHrlNiIGeEht!3es#bIBn`^zNF4olZ&#hw&^hqgdr9gKnAXMBY%xOmC zs;v~jFlQi=v+&FT3R5%qR6-P1W2x@h;4&qI^cSynI1JAE>RJi7G6qvRr1I9PWd&oU zK!P(Gfu&T=YqEQxSfmuF#Qupd(aSnBxn%X7V0DJ>QHqZqV?1&Sbh$ZnXnmT)+r;NC z9z*3utf_8XDqe0I4TQ7x)F>(keBBoR!*xkvV`2rn9Bno}d#R3QiuS#Y5}i6Pp^{zP zqL05%NYN`o%EPwVc}htvr$Uxe8;h&_95Q)Z>orC4Pkq_c%se%ZN@bSYH0X0Jv|NUn z0u|-jI4Lx|*g}ojCRdmX+Bpt#EXkV+WT_c-YW;IGt8IT5k7>5C1>!b)44B(it>)a5 zQgi;CQq#5>Un-ePje6qsPq7&;Lmh8RyyHYJ=Li*d24dx|ZRbDc#>ej!R`w~gq42wf zRbVc;%_Y$xb!nis2?Wl9HC`50A`xD#)vL=n3l^La2xBRP0O9BI&XK&7Q~NcQe5HWG z?_~W`@gY@&#Bng!?MTJs`1fI=FaX<9*ohR=BE_>$#h{!qQH*zr+wJivIMr?*_H8H{ zlS-0eFZi4?XYL%wU4@*`Q@kfqRe!2G7thCIM1QJdm2!%^aG}RK&^bUyPJ28h6&eG0 z!lYqaf{^;)IeETZmKJmVQo6d^w7lb=PgU;QRE}~gW0!$IQVKzr>Eq|<94Sy%&Jr}_ zNxzeJb1I>TpLz|uXro7#ALLK4!?wtq;y%Xuz)H6<9s5x|astV5~z`0p< zPP{1BEeJ1~*r_VsdxLLvsQeWt%c=7pu5p|M#_EiN16wG7l1j!?ot6|RDF#1n*2Gza zlt|ZqKP^Qs=2sDK4j%N!J62WE@i}%I-I$+&Vhe&==ym5Q|-0f{)q*0E?fVu z>n$#R`;h=OPvV zQ+p!DRmAHb?$4B<*6>}nRs7+sJXYDu6+AK1AV#gH)*$Y5=DIE0ygGo5H1B1j>F~3L zYg**8;8e>cm6fDg=Bey4m1*WYU}GR&?xM;)l+ao)RKdHfm7AK=q+}>lU4)#ON-EID z0W#hsLl8@Gjl)YPC21ON%+%a1cJ0Y^N>a%4;a9kUQZw?D7D3L~Bz2L;$w7?FPI(f? zRF2S>AkNgc=?Ub_UveDc)Mc2{CyZt>T@DLF|{cLbPM-Ss=E?jfbqC(TiZSk zAlvj2E~_--A|e#-i0vig&lL+x#eWVR-G*c*>^$TWwpf}s#Au{61acbQ+ZYL{^Pe-U zNuB?co-xU9&{u~R`e)r!c0vvNq- z+}wJbvRAy(Q!T8=G;I^~jChul1FEIw^V=?>R5cw}7OCfu3KBW6Ln^?=v+~^c$f3#e z!X0F*(``V(6d-Qf_YM!`w#zKV$&J@PzLetik1vw=x#f7*@%mo|2+grVa-EP^K`hms z$;l1Jl~9aU0|zYumgpN5|X7ZnzA+x($34S2U@>lbUy#@yx?ur0aS7KCzRmCM?@xdbkEmST)eDmhDay<*gM3?@y12#1S24EU+!D7WWx zES1#yr@AG%Zp=Gb|2W2^=)$>Y9_u9J#vyUCxee%<+F#pd)8W324TEwfL<4IfRm8>5 zHKd@%=RfYo#Lq9Mfsz91rT%^RzNthuwf;Gin|F%%kJ%l$qAB({0eZHFIIqxSz(P)e zXWL9Nm8s^2`MKa0f+|w_@hO?T)a&LbOWTmo@psChk8^@7vE66tkmRUaIe=ZxK`wW3 zq-Ywsx%M{y_0;;LD!%yp} zDHEM-{N&tONJ-)5SOuwlvrRuD{I20^$LkOSc2XFO7>JjnjBaat#=7n?gCP#=IZ>sQ zuEu4|mzM+txppzRlTer;4gnau!P@$IOo0II~Cr zKXSifZfuTbvn@z(Lz(9w`j=hIIX-Yo{x63zekb13DIQ^}f=E@1xzR&Tpk&*eej7zB zg=9|Q8se%ghoZe~{ojcbQ!X&(D#~r3kZrhy93nk*01JbBtWuT(0p+sl_*up-WtS;; z#R+gOfrtZGywBsn6mpnz`zWpqbLS%b6+XXVFT~7+a3-4*)`$aiydP3)k$T?S_G&8D zq>OmN@0Pk;a;Wsw+ND5`@g*9s|2A=*RAroc?@+#VXh-K_4$j;V+LI_E!R3FUy+@%o4HGt|@%!HnDP#kk`z;6#e> zMRP64oP6p#ohfXaO@zL)IdI)&ZS44c!mKQoOU;>-T!w5#4cp4P9o=a8$rhqn= zS#_o;hdE2y@EHz#%~WS+n=wi%IOKqwDba|Oz)8GzIVstc$wdtKi2;DQj!#Uj%C+L+ zN;76+ga$P!wXUIx9!x+|u7*-d%CdayEXM4O7^Id;w&QL=96N^B40Xrj*p<^X4})Zk zHckQgV(pDMxyf1jZc})SFO_gakuwR}cK*Z5GzIDl&vuGE5YCrF8e3c?r=(cJ{TkYh z=334<=26ZeGOV^^e)mATOBGP@MHpN4#=x}@$QSSXu2ruf~!HFp{DXPb? zk%xens(f>mNX#qWHpk9Myrz({m(Am1Ui}alx6L0@t;ATsC8bIhKgS&CE%hGp{3`}G z~n9N;qk zeH>iF=aJJh&*4B~+)KzyP8sclNmtkjh|gN6kd{*MO3i0uO@iT^$8*!rLNp~%vJIS; zTHiP+O5uodmYgXDPD&Ln1oK^1rKeEap$0-qt05i@4e#?#*e2ok9`2?%X2*256o5L1 z!AZ^T!+1TY=EYc)xcVN{-iCcKB!|O(*tY(Uq0}?3d?~$(oSwsGhW>Z|-ap)m;=PP! z^{@Nuf9lU|L+t)`zTdXjeWw-jWx;IQZ1CUKXZ^SJ{kAFY{hO@G|CD|8PTb%Abw1l~ z_g?uodHHk+T^54d5{C1s%|NpPwo?lf} b@&6qF>00sqgJ+i-00000NkvXXu0mjfR5Sf* literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/models/block/arcane_assembler.json b/src/main/resources/assets/thaumicenergistics/models/block/arcane_assembler.json new file mode 100644 index 0000000..d4b7f52 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/block/arcane_assembler.json @@ -0,0 +1 @@ +{"parent":"minecraft:block/cube_all","textures":{"all":"thaumicenergistics:block/arcane_assembler_fallback"}} diff --git a/src/main/resources/assets/thaumicenergistics/models/block/distillation_encoder.json b/src/main/resources/assets/thaumicenergistics/models/block/distillation_encoder.json new file mode 100644 index 0000000..5efdba7 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/block/distillation_encoder.json @@ -0,0 +1 @@ +{"parent":"minecraft:block/cube_all","textures":{"all":"thaumicenergistics:block/distillation_encoder_face"}} diff --git a/src/main/resources/assets/thaumicenergistics/models/block/essentia_cell_workbench.json b/src/main/resources/assets/thaumicenergistics/models/block/essentia_cell_workbench.json new file mode 100644 index 0000000..1300bd0 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/block/essentia_cell_workbench.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/cube_bottom_top", + "textures": { + "top": "thaumicenergistics:block/essentia_cell_workbench_top", + "bottom": "thaumicenergistics:block/essentia_cell_workbench_bottom", + "side": "thaumicenergistics:block/essentia_cell_workbench_side" + } +} diff --git a/src/main/resources/assets/thaumicenergistics/models/block/essentia_provider.json b/src/main/resources/assets/thaumicenergistics/models/block/essentia_provider.json new file mode 100644 index 0000000..a1b14e1 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/block/essentia_provider.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "thaumicenergistics:block/essentia_provider" + } +} diff --git a/src/main/resources/assets/thaumicenergistics/models/block/essentia_vibration_chamber.json b/src/main/resources/assets/thaumicenergistics/models/block/essentia_vibration_chamber.json new file mode 100644 index 0000000..9dc8f9f --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/block/essentia_vibration_chamber.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/orientable", + "textures": { + "front": "thaumicenergistics:block/e_vibration_face_off", + "side": "thaumicenergistics:block/e_vibration_input", + "top": "thaumicenergistics:block/e_vibration_input" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/models/block/infusion_provider.json b/src/main/resources/assets/thaumicenergistics/models/block/infusion_provider.json new file mode 100644 index 0000000..6ac41bb --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/block/infusion_provider.json @@ -0,0 +1 @@ +{"parent":"minecraft:block/cube_all","textures":{"all":"thaumicenergistics:block/infusion_provider"}} diff --git a/src/main/resources/assets/thaumicenergistics/models/block/knowledge_inscriber.json b/src/main/resources/assets/thaumicenergistics/models/block/knowledge_inscriber.json new file mode 100644 index 0000000..fe14f65 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/block/knowledge_inscriber.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/cube_bottom_top", + "textures": { + "top": "thaumicenergistics:block/knowledge_inscriber_top", + "bottom": "thaumicenergistics:block/knowledge_inscriber_bottom", + "side": "thaumicenergistics:block/knowledge_inscriber_side" + } +} diff --git a/src/main/resources/assets/thaumicenergistics/models/item/arcane_assembler.json b/src/main/resources/assets/thaumicenergistics/models/item/arcane_assembler.json new file mode 100644 index 0000000..bac9d2b --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/arcane_assembler.json @@ -0,0 +1 @@ +{"parent":"thaumicenergistics:block/arcane_assembler"} diff --git a/src/main/resources/assets/thaumicenergistics/models/item/arcane_crafting_terminal.json b/src/main/resources/assets/thaumicenergistics/models/item/arcane_crafting_terminal.json new file mode 100644 index 0000000..d38dc2f --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/arcane_crafting_terminal.json @@ -0,0 +1,12 @@ +{ +"parent": "ae2:item/display_base", +"textures": { +"front_base": "thaumicenergistics:part/arcane_crafting_terminal/arcane_crafting_overlay1", +"front_bright": "thaumicenergistics:part/arcane_crafting_terminal/arcane_crafting_overlay3", +"front_medium": "thaumicenergistics:part/arcane_crafting_terminal/arcane_crafting_overlay2", +"front_dark": "thaumicenergistics:part/arcane_crafting_terminal/arcane_crafting_overlay1", +"front_medium_bright": "thaumicenergistics:part/arcane_crafting_terminal/arcane_crafting_overlay2", +"back": "ae2:part/monitor_back_no_status", +"sides": "thaumicenergistics:part/arcane_crafting_terminal/arcane_crafting_side" +} +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/models/item/coalescence_core.json b/src/main/resources/assets/thaumicenergistics/models/item/coalescence_core.json new file mode 100644 index 0000000..5558e0c --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/coalescence_core.json @@ -0,0 +1 @@ +{"parent":"minecraft:item/generated","textures":{"layer0":"thaumicenergistics:item/material_coalescence_core"}} diff --git a/src/main/resources/assets/thaumicenergistics/models/item/diffusion_core.json b/src/main/resources/assets/thaumicenergistics/models/item/diffusion_core.json new file mode 100644 index 0000000..6d4f29e --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/diffusion_core.json @@ -0,0 +1 @@ +{"parent":"minecraft:item/generated","textures":{"layer0":"thaumicenergistics:item/material_diffusion_core"}} diff --git a/src/main/resources/assets/thaumicenergistics/models/item/distillation_encoder.json b/src/main/resources/assets/thaumicenergistics/models/item/distillation_encoder.json new file mode 100644 index 0000000..8b7b33a --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/distillation_encoder.json @@ -0,0 +1 @@ +{"parent":"thaumicenergistics:block/distillation_encoder"} diff --git a/src/main/resources/assets/thaumicenergistics/models/item/essentia_cell_16k.json b/src/main/resources/assets/thaumicenergistics/models/item/essentia_cell_16k.json new file mode 100644 index 0000000..3daaa89 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/essentia_cell_16k.json @@ -0,0 +1 @@ +{"parent":"minecraft:item/generated","textures":{"layer0":"thaumicenergistics:item/essentia_cell_16k"}} diff --git a/src/main/resources/assets/thaumicenergistics/models/item/essentia_cell_1k.json b/src/main/resources/assets/thaumicenergistics/models/item/essentia_cell_1k.json new file mode 100644 index 0000000..3f61c20 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/essentia_cell_1k.json @@ -0,0 +1 @@ +{"parent":"minecraft:item/generated","textures":{"layer0":"thaumicenergistics:item/essentia_cell_1k"}} diff --git a/src/main/resources/assets/thaumicenergistics/models/item/essentia_cell_4k.json b/src/main/resources/assets/thaumicenergistics/models/item/essentia_cell_4k.json new file mode 100644 index 0000000..10ee3b7 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/essentia_cell_4k.json @@ -0,0 +1 @@ +{"parent":"minecraft:item/generated","textures":{"layer0":"thaumicenergistics:item/essentia_cell_4k"}} diff --git a/src/main/resources/assets/thaumicenergistics/models/item/essentia_cell_64k.json b/src/main/resources/assets/thaumicenergistics/models/item/essentia_cell_64k.json new file mode 100644 index 0000000..50dbb86 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/essentia_cell_64k.json @@ -0,0 +1 @@ +{"parent":"minecraft:item/generated","textures":{"layer0":"thaumicenergistics:item/essentia_cell_64k"}} diff --git a/src/main/resources/assets/thaumicenergistics/models/item/essentia_cell_creative.json b/src/main/resources/assets/thaumicenergistics/models/item/essentia_cell_creative.json new file mode 100644 index 0000000..a95d50b --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/essentia_cell_creative.json @@ -0,0 +1 @@ +{"parent":"minecraft:item/generated","textures":{"layer0":"thaumicenergistics:item/essentia_cell_creative"}} diff --git a/src/main/resources/assets/thaumicenergistics/models/item/essentia_cell_workbench.json b/src/main/resources/assets/thaumicenergistics/models/item/essentia_cell_workbench.json new file mode 100644 index 0000000..2e6600e --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/essentia_cell_workbench.json @@ -0,0 +1 @@ +{"parent":"thaumicenergistics:block/essentia_cell_workbench"} diff --git a/src/main/resources/assets/thaumicenergistics/models/item/essentia_export_bus.json b/src/main/resources/assets/thaumicenergistics/models/item/essentia_export_bus.json new file mode 100644 index 0000000..1d3af92 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/essentia_export_bus.json @@ -0,0 +1,46 @@ +{ + "credit": "Made with Blockbench by Sea_Kerman - ThaumicEnergistics Essentia Export Bus", + "parent": "ae2:item/part_base", + "textures": { + "sides": "ae2:part/export_bus_sides", + "front": "thaumicenergistics:part/essentia_export_bus_face" + }, + "elements": [ + { + "from": [4, 4, 7], + "to": [12, 12, 9], + "faces": { + "north": { "uv": [4, 4, 12, 12], "texture": "#front" }, + "east": { "uv": [0, 4, 2, 12], "rotation": 180, "texture": "#sides" }, + "south": { "uv": [4, 4, 12, 12], "texture": "#sides" }, + "west": { "uv": [14, 4, 16, 12], "rotation": 180, "texture": "#sides" }, + "up": { "uv": [4, 0, 12, 2], "texture": "#sides" }, + "down": { "uv": [4, 14, 12, 16], "texture": "#sides" } + } + }, + { + "from": [5, 5, 9], + "to": [11, 11, 10], + "faces": { + "north": { "uv": [5, 5, 11, 11], "texture": "#front" }, + "east": { "uv": [13, 5, 14, 11], "texture": "#sides" }, + "south": { "uv": [5, 5, 11, 11], "texture": "#sides" }, + "west": { "uv": [2, 5, 3, 11], "texture": "#sides" }, + "up": { "uv": [5, 2, 11, 3], "texture": "#sides" }, + "down": { "uv": [5, 13, 11, 14], "texture": "#sides" } + } + }, + { + "from": [6, 6, 10], + "to": [10, 10, 11], + "faces": { + "north": { "uv": [6, 6, 10, 10], "texture": "#front" }, + "east": { "uv": [3, 6, 4, 10], "texture": "#sides" }, + "south": { "uv": [6, 6, 10, 10], "texture": "#sides" }, + "west": { "uv": [12, 6, 13, 10], "texture": "#sides" }, + "up": { "uv": [6, 12, 10, 13], "texture": "#sides" }, + "down": { "uv": [6, 3, 10, 4], "texture": "#sides" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/models/item/essentia_import_bus.json b/src/main/resources/assets/thaumicenergistics/models/item/essentia_import_bus.json new file mode 100644 index 0000000..c46e365 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/essentia_import_bus.json @@ -0,0 +1,216 @@ +{ + "credit": "Made with Blockbench by Sea_Kerman - ThaumicEnergistics Essentia Import Bus", + "parent": "ae2:item/part_base", + "textures": { + "sides": "ae2:part/import_bus_sides", + "front": "thaumicenergistics:part/essentia_import_bus_face" + }, + "elements": [ + { + "from": [ + 4, + 4, + 7 + ], + "to": [ + 12, + 12, + 9 + ], + "faces": { + "north": { + "uv": [ + 4, + 4, + 12, + 12 + ], + "texture": "#front" + }, + "east": { + "uv": [ + 0, + 4, + 2, + 12 + ], + "rotation": 180, + "texture": "#sides" + }, + "south": { + "uv": [ + 4, + 4, + 12, + 12 + ], + "texture": "#sides" + }, + "west": { + "uv": [ + 14, + 4, + 16, + 12 + ], + "rotation": 180, + "texture": "#sides" + }, + "up": { + "uv": [ + 4, + 0, + 12, + 2 + ], + "texture": "#sides" + }, + "down": { + "uv": [ + 4, + 14, + 12, + 16 + ], + "texture": "#sides" + } + } + }, + { + "from": [ + 5, + 5, + 9 + ], + "to": [ + 11, + 11, + 10 + ], + "faces": { + "north": { + "uv": [ + 5, + 5, + 11, + 11 + ], + "texture": "#front" + }, + "east": { + "uv": [ + 13, + 5, + 14, + 11 + ], + "texture": "#sides" + }, + "south": { + "uv": [ + 5, + 5, + 11, + 11 + ], + "texture": "#sides" + }, + "west": { + "uv": [ + 2, + 5, + 3, + 11 + ], + "texture": "#sides" + }, + "up": { + "uv": [ + 5, + 2, + 11, + 3 + ], + "texture": "#sides" + }, + "down": { + "uv": [ + 5, + 13, + 11, + 14 + ], + "texture": "#sides" + } + } + }, + { + "from": [ + 6, + 6, + 10 + ], + "to": [ + 10, + 10, + 11 + ], + "faces": { + "north": { + "uv": [ + 6, + 6, + 10, + 10 + ], + "texture": "#front" + }, + "east": { + "uv": [ + 3, + 6, + 4, + 10 + ], + "texture": "#sides" + }, + "south": { + "uv": [ + 6, + 6, + 10, + 10 + ], + "texture": "#sides" + }, + "west": { + "uv": [ + 12, + 6, + 13, + 10 + ], + "texture": "#sides" + }, + "up": { + "uv": [ + 6, + 12, + 10, + 13 + ], + "texture": "#sides" + }, + "down": { + "uv": [ + 6, + 3, + 10, + 4 + ], + "texture": "#sides" + } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/models/item/essentia_level_emitter.json b/src/main/resources/assets/thaumicenergistics/models/item/essentia_level_emitter.json new file mode 100644 index 0000000..b2eb7fd --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/essentia_level_emitter.json @@ -0,0 +1,20 @@ +{ + "parent": "ae2:item/part_base", + "textures": { + "emitter": "ae2:part/level_emitter_off" + }, + "elements": [ + { + "from": [7, 6, 7], + "to": [9, 10, 9], + "faces": { + "north": { "uv": [6, 7, 10, 9], "rotation": 90, "texture": "#emitter" }, + "east": { "uv": [6, 7, 10, 9], "rotation": 90, "texture": "#emitter" }, + "south": { "uv": [6, 7, 10, 9], "rotation": 90, "texture": "#emitter" }, + "west": { "uv": [6, 7, 10, 9], "rotation": 90, "texture": "#emitter" }, + "up": { "uv": [6, 7, 8, 9], "texture": "#emitter" }, + "down": { "uv": [8, 7, 10, 9], "texture": "#emitter" } + } + } + ] +} diff --git a/src/main/resources/assets/thaumicenergistics/models/item/essentia_provider.json b/src/main/resources/assets/thaumicenergistics/models/item/essentia_provider.json new file mode 100644 index 0000000..493abea --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/essentia_provider.json @@ -0,0 +1 @@ +{"parent":"thaumicenergistics:block/essentia_provider"} diff --git a/src/main/resources/assets/thaumicenergistics/models/item/essentia_storage_bus.json b/src/main/resources/assets/thaumicenergistics/models/item/essentia_storage_bus.json new file mode 100644 index 0000000..8ccbae0 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/essentia_storage_bus.json @@ -0,0 +1,47 @@ +{ + "credit": "Made with Blockbench by Sea_Kerman", + "parent": "ae2:item/part_base", + "textures": { + "sides": "ae2:part/storage_bus_sides", + "back": "ae2:part/storage_bus_back", + "front": "thaumicenergistics:part/essentia_storage_bus_face" + }, + "elements": [ + { + "from": [3, 3, 6], + "to": [13, 13, 7], + "faces": { + "north": { "uv": [3, 3, 13, 13], "texture": "#front" }, + "east": { "uv": [15, 3, 16, 13], "texture": "#sides" }, + "south": { "uv": [3, 3, 13, 13], "texture": "#back" }, + "west": { "uv": [0, 3, 1, 13], "texture": "#sides" }, + "up": { "uv": [3, 0, 13, 1], "texture": "#sides" }, + "down": { "uv": [3, 15, 13, 16], "texture": "#sides" } + } + }, + { + "from": [2, 2, 7], + "to": [14, 14, 8], + "faces": { + "north": { "uv": [2, 2, 14, 14], "texture": "#front" }, + "east": { "uv": [14, 2, 15, 14], "texture": "#sides" }, + "south": { "uv": [2, 2, 14, 14], "texture": "#back" }, + "west": { "uv": [1, 2, 2, 14], "texture": "#sides" }, + "up": { "uv": [2, 1, 14, 2], "texture": "#sides" }, + "down": { "uv": [2, 14, 14, 15], "texture": "#sides" } + } + }, + { + "from": [5, 5, 8], + "to": [11, 11, 10], + "faces": { + "north": { "uv": [5, 5, 11, 11], "texture": "#front" }, + "east": { "uv": [6, 5, 8, 11], "texture": "#sides" }, + "south": { "uv": [5, 5, 11, 11], "texture": "#back" }, + "west": { "uv": [8, 5, 10, 11], "texture": "#sides" }, + "up": { "uv": [5, 8, 11, 10], "texture": "#sides" }, + "down": { "uv": [5, 6, 11, 8], "texture": "#sides" } + } + } + ] +} diff --git a/src/main/resources/assets/thaumicenergistics/models/item/essentia_terminal.json b/src/main/resources/assets/thaumicenergistics/models/item/essentia_terminal.json new file mode 100644 index 0000000..65bb5b0 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/essentia_terminal.json @@ -0,0 +1,12 @@ +{ + "parent": "ae2:item/display_base", + "textures": { + "front_base": "thaumicenergistics:part/essentia_terminal/bright", + "front_bright": "thaumicenergistics:part/essentia_terminal/bright", + "front_medium": "thaumicenergistics:part/essentia_terminal/medium", + "front_dark": "thaumicenergistics:part/essentia_terminal/dark", + "front_medium_bright": "thaumicenergistics:part/essentia_terminal/medium", + "back": "ae2:part/monitor_back_no_status", + "sides": "ae2:part/monitor_sides" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/models/item/essentia_vibration_chamber.json b/src/main/resources/assets/thaumicenergistics/models/item/essentia_vibration_chamber.json new file mode 100644 index 0000000..05c47a4 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/essentia_vibration_chamber.json @@ -0,0 +1,3 @@ +{ + "parent": "thaumicenergistics:block/essentia_vibration_chamber" +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/models/item/focus_aewrench.json b/src/main/resources/assets/thaumicenergistics/models/item/focus_aewrench.json new file mode 100644 index 0000000..f96b3ef --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/focus_aewrench.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "thaumicenergistics:item/focus_aewrench" + } +} diff --git a/src/main/resources/assets/thaumicenergistics/models/item/golem_wifi_backpack.json b/src/main/resources/assets/thaumicenergistics/models/item/golem_wifi_backpack.json new file mode 100644 index 0000000..c3f618e --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/golem_wifi_backpack.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "thaumicenergistics:item/golem_wifi_backpack" + } +} diff --git a/src/main/resources/assets/thaumicenergistics/models/item/infusion_provider.json b/src/main/resources/assets/thaumicenergistics/models/item/infusion_provider.json new file mode 100644 index 0000000..09ca233 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/infusion_provider.json @@ -0,0 +1 @@ +{"parent":"thaumicenergistics:block/infusion_provider"} diff --git a/src/main/resources/assets/thaumicenergistics/models/item/knowledge_core.json b/src/main/resources/assets/thaumicenergistics/models/item/knowledge_core.json new file mode 100644 index 0000000..c1fca26 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/knowledge_core.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "thaumicenergistics:item/knowledge_core" + } +} diff --git a/src/main/resources/assets/thaumicenergistics/models/item/knowledge_inscriber.json b/src/main/resources/assets/thaumicenergistics/models/item/knowledge_inscriber.json new file mode 100644 index 0000000..46a7693 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/knowledge_inscriber.json @@ -0,0 +1,3 @@ +{ + "parent": "thaumicenergistics:block/knowledge_inscriber" +} diff --git a/src/main/resources/assets/thaumicenergistics/models/item/storage_casing.json b/src/main/resources/assets/thaumicenergistics/models/item/storage_casing.json new file mode 100644 index 0000000..950deb0 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/storage_casing.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "thaumicenergistics:item/essentia_cell_casing" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/models/item/storage_component_16k.json b/src/main/resources/assets/thaumicenergistics/models/item/storage_component_16k.json new file mode 100644 index 0000000..585398b --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/storage_component_16k.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "thaumicenergistics:item/storage_component_16k" + } +} diff --git a/src/main/resources/assets/thaumicenergistics/models/item/storage_component_1k.json b/src/main/resources/assets/thaumicenergistics/models/item/storage_component_1k.json new file mode 100644 index 0000000..fc17d05 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/storage_component_1k.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "thaumicenergistics:item/storage_component_1k" + } +} diff --git a/src/main/resources/assets/thaumicenergistics/models/item/storage_component_4k.json b/src/main/resources/assets/thaumicenergistics/models/item/storage_component_4k.json new file mode 100644 index 0000000..8da05e1 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/storage_component_4k.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "thaumicenergistics:item/storage_component_4k" + } +} diff --git a/src/main/resources/assets/thaumicenergistics/models/item/storage_component_64k.json b/src/main/resources/assets/thaumicenergistics/models/item/storage_component_64k.json new file mode 100644 index 0000000..2376d3d --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/storage_component_64k.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "thaumicenergistics:item/storage_component_64k" + } +} diff --git a/src/main/resources/assets/thaumicenergistics/models/item/vis_interface.json b/src/main/resources/assets/thaumicenergistics/models/item/vis_interface.json new file mode 100644 index 0000000..944dabc --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/vis_interface.json @@ -0,0 +1,6 @@ +{ + "parent": "ae2:item/p2p_tunnel_base", + "textures": { + "type": "thaumicenergistics:part/vis_interface" + } +} diff --git a/src/main/resources/assets/thaumicenergistics/models/item/wireless_essentia_terminal.json b/src/main/resources/assets/thaumicenergistics/models/item/wireless_essentia_terminal.json new file mode 100644 index 0000000..dfa736f --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/item/wireless_essentia_terminal.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "thaumicenergistics:item/wireless_essentia_terminal" + } +} diff --git a/src/main/resources/assets/thaumicenergistics/models/parts/arcane_crafting_terminal_base.json b/src/main/resources/assets/thaumicenergistics/models/parts/arcane_crafting_terminal_base.json new file mode 100644 index 0000000..8c6c04e --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/parts/arcane_crafting_terminal_base.json @@ -0,0 +1,33 @@ +{ +"textures": { +"sides": "thaumicenergistics:part/arcane_crafting_terminal/arcane_crafting_side", +"particle": "ae2:part/monitor_back_no_status", +"back": "ae2:part/monitor_back_no_status", +"front": "ae2:part/monitor_front" +}, +"elements": [ +{ +"from": [2, 2, 0], +"to": [14, 14, 2], +"faces": { +"north": { "uv": [2, 2, 14, 14], "texture": "#front" }, +"east": { "uv": [14, 2, 16, 14], "texture": "#sides" }, +"south": { "uv": [2, 2, 14, 14], "texture": "#back" }, +"west": { "uv": [0, 2, 2, 14], "texture": "#sides" }, +"up": { "uv": [2, 0, 14, 2], "texture": "#sides" }, +"down": { "uv": [2, 14, 14, 16], "texture": "#sides" } +} +}, +{ +"from": [4, 4, 2], +"to": [12, 12, 3], +"faces": { +"east": { "uv": [11, 4, 12, 12], "texture": "#back" }, +"south": { "uv": [4, 4, 12, 12], "texture": "#back" }, +"west": { "uv": [4, 4, 5, 12], "texture": "#back" }, +"up": { "uv": [4, 4, 12, 5], "texture": "#back" }, +"down": { "uv": [4, 11, 12, 12], "texture": "#back" } +} +} +] +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/models/parts/arcane_crafting_terminal_has_channel.json b/src/main/resources/assets/thaumicenergistics/models/parts/arcane_crafting_terminal_has_channel.json new file mode 100644 index 0000000..65a6089 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/parts/arcane_crafting_terminal_has_channel.json @@ -0,0 +1,22 @@ +{ +"textures": { +"lightsBright": "thaumicenergistics:part/arcane_crafting_terminal/arcane_crafting_overlay3", +"lightsMedium": "thaumicenergistics:part/arcane_crafting_terminal/arcane_crafting_overlay2", +"lightsDark": "thaumicenergistics:part/arcane_crafting_terminal/arcane_crafting_overlay1", +"grid": "thaumicenergistics:part/arcane_crafting_terminal/arcane_crafting_overlay4" +}, +"elements": [ +{ "from": [2, 2, 0], "to": [14, 14, 2], "faces": { +"north": { "texture": "#lightsBright", "tintindex": 3, "neoforge_data": { "block_light": 15, "sky_light": 15 } } +}}, +{ "from": [2, 2, 0], "to": [14, 14, 2], "faces": { +"north": { "texture": "#lightsMedium", "tintindex": 2, "neoforge_data": { "block_light": 15, "sky_light": 15 } } +}}, +{ "from": [2, 2, 0], "to": [14, 14, 2], "faces": { +"north": { "texture": "#lightsDark", "tintindex": 1, "neoforge_data": { "block_light": 15, "sky_light": 15 } } +}}, +{ "from": [2, 2, 0], "to": [14, 14, 2], "faces": { +"north": { "texture": "#grid", "neoforge_data": { "block_light": 15, "sky_light": 15 } } +}} +] +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/models/parts/arcane_crafting_terminal_off.json b/src/main/resources/assets/thaumicenergistics/models/parts/arcane_crafting_terminal_off.json new file mode 100644 index 0000000..a497560 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/parts/arcane_crafting_terminal_off.json @@ -0,0 +1,8 @@ +{ +"parent": "ae2:part/display_off", +"textures": { +"lightsBright": "thaumicenergistics:part/arcane_crafting_terminal/arcane_crafting_overlay3", +"lightsMedium": "thaumicenergistics:part/arcane_crafting_terminal/arcane_crafting_overlay2", +"lightsDark": "thaumicenergistics:part/arcane_crafting_terminal/arcane_crafting_overlay1" +} +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/models/parts/arcane_crafting_terminal_on.json b/src/main/resources/assets/thaumicenergistics/models/parts/arcane_crafting_terminal_on.json new file mode 100644 index 0000000..a497560 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/parts/arcane_crafting_terminal_on.json @@ -0,0 +1,8 @@ +{ +"parent": "ae2:part/display_off", +"textures": { +"lightsBright": "thaumicenergistics:part/arcane_crafting_terminal/arcane_crafting_overlay3", +"lightsMedium": "thaumicenergistics:part/arcane_crafting_terminal/arcane_crafting_overlay2", +"lightsDark": "thaumicenergistics:part/arcane_crafting_terminal/arcane_crafting_overlay1" +} +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/models/parts/essentia_export_bus_base.json b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_export_bus_base.json new file mode 100644 index 0000000..7a9577a --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_export_bus_base.json @@ -0,0 +1,59 @@ +{ + "credit": "Made with Blockbench by Sea_Kerman", + "textures": { + "sides": "ae2:part/export_bus_sides", + "sidesStatus": "ae2:part/monitor_sides_status", + "particle": "ae2:part/monitor_back", + "back": "ae2:part/monitor_back", + "front": "thaumicenergistics:part/essentia_export_bus_face" + }, + "elements": [ + { + "from": [4, 4, 0], + "to": [12, 12, 2], + "faces": { + "north": { "uv": [4, 4, 12, 12], "texture": "#front" }, + "east": { "uv": [14, 4, 16, 12], "texture": "#sides" }, + "south": { "uv": [4, 4, 12, 12], "texture": "#sides" }, + "west": { "uv": [0, 4, 2, 12], "texture": "#sides" }, + "up": { "uv": [4, 0, 12, 2], "texture": "#sides" }, + "down": { "uv": [4, 14, 12, 16], "texture": "#sides" } + } + }, + { + "from": [5, 5, 2], + "to": [11, 11, 3], + "faces": { + "north": { "uv": [5, 5, 11, 11], "texture": "#front" }, + "east": { "uv": [13, 5, 14, 11], "texture": "#sides" }, + "south": { "uv": [5, 5, 11, 11], "texture": "#sides" }, + "west": { "uv": [2, 5, 3, 11], "texture": "#sides" }, + "up": { "uv": [5, 2, 11, 3], "texture": "#sides" }, + "down": { "uv": [5, 13, 11, 14], "texture": "#sides" } + } + }, + { + "from": [6, 6, 3], + "to": [10, 10, 4], + "faces": { + "north": { "uv": [6, 6, 10, 10], "texture": "#front" }, + "east": { "uv": [12, 6, 13, 10], "texture": "#sides" }, + "south": { "uv": [6, 6, 10, 10], "texture": "#back" }, + "west": { "uv": [3, 6, 4, 10], "texture": "#sides" }, + "up": { "uv": [6, 3, 10, 4], "texture": "#sides" }, + "down": { "uv": [6, 12, 10, 13], "texture": "#sides" } + } + }, + { + "from": [6, 6, 4], + "to": [10, 10, 5], + "faces": { + "east": { "uv": [11, 6, 12, 10], "texture": "#sidesStatus" }, + "south": { "uv": [6, 6, 10, 10], "texture": "#back" }, + "west": { "uv": [4, 6, 5, 10], "texture": "#sidesStatus" }, + "up": { "uv": [6, 4, 10, 5], "texture": "#sidesStatus" }, + "down": { "uv": [6, 11, 10, 12], "texture": "#sidesStatus" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/models/parts/essentia_export_bus_has_channel.json b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_export_bus_has_channel.json new file mode 100644 index 0000000..51bff62 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_export_bus_has_channel.json @@ -0,0 +1,17 @@ +{ + "textures": { + "indicator": "ae2:part/monitor_sides_status_has_channel" + }, + "elements": [ + { + "from": [6, 6, 4], + "to": [10, 10, 5], + "faces": { + "down": { "texture": "#indicator", "tintindex": 1, "neoforge_data": { "block_light": 15, "sky_light": 15 } }, + "up": { "texture": "#indicator", "tintindex": 1, "neoforge_data": { "block_light": 15, "sky_light": 15 } }, + "east": { "texture": "#indicator", "tintindex": 1, "neoforge_data": { "block_light": 15, "sky_light": 15 } }, + "west": { "texture": "#indicator", "tintindex": 1, "neoforge_data": { "block_light": 15, "sky_light": 15 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/models/parts/essentia_export_bus_off.json b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_export_bus_off.json new file mode 100644 index 0000000..4e10656 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_export_bus_off.json @@ -0,0 +1,17 @@ +{ + "textures": { + "indicator": "ae2:part/monitor_sides_status_off" + }, + "elements": [ + { + "from": [6, 6, 4], + "to": [10, 10, 5], + "faces": { + "down": { "texture": "#indicator" }, + "up": { "texture": "#indicator" }, + "east": { "texture": "#indicator" }, + "west": { "texture": "#indicator" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/models/parts/essentia_export_bus_on.json b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_export_bus_on.json new file mode 100644 index 0000000..018306c --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_export_bus_on.json @@ -0,0 +1,17 @@ +{ + "textures": { + "indicator": "ae2:part/monitor_sides_status_on" + }, + "elements": [ + { + "from": [6, 6, 4], + "to": [10, 10, 5], + "faces": { + "down": { "texture": "#indicator", "tintindex": 3, "neoforge_data": { "block_light": 15, "sky_light": 15 } }, + "up": { "texture": "#indicator", "tintindex": 3, "neoforge_data": { "block_light": 15, "sky_light": 15 } }, + "east": { "texture": "#indicator", "tintindex": 3, "neoforge_data": { "block_light": 15, "sky_light": 15 } }, + "west": { "texture": "#indicator", "tintindex": 3, "neoforge_data": { "block_light": 15, "sky_light": 15 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/models/parts/essentia_import_bus_base.json b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_import_bus_base.json new file mode 100644 index 0000000..26c010c --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_import_bus_base.json @@ -0,0 +1,59 @@ +{ + "credit": "Made with Blockbench by Sea_Kerman", + "textures": { + "sides": "ae2:part/import_bus_sides", + "sidesStatus": "ae2:part/monitor_sides_status", + "particle": "ae2:part/monitor_back", + "back": "ae2:part/monitor_back", + "front": "thaumicenergistics:part/essentia_import_bus_face" + }, + "elements": [ + { + "from": [4, 4, 0], + "to": [12, 12, 2], + "faces": { + "north": { "uv": [4, 4, 12, 12], "texture": "#front" }, + "east": { "uv": [14, 4, 16, 12], "texture": "#sides" }, + "south": { "uv": [4, 4, 12, 12], "texture": "#sides" }, + "west": { "uv": [0, 4, 2, 12], "texture": "#sides" }, + "up": { "uv": [4, 0, 12, 2], "texture": "#sides" }, + "down": { "uv": [4, 14, 12, 16], "texture": "#sides" } + } + }, + { + "from": [5, 5, 2], + "to": [11, 11, 3], + "faces": { + "north": { "uv": [5, 5, 11, 11], "texture": "#front" }, + "east": { "uv": [13, 5, 14, 11], "texture": "#sides" }, + "south": { "uv": [5, 5, 11, 11], "texture": "#sides" }, + "west": { "uv": [2, 5, 3, 11], "texture": "#sides" }, + "up": { "uv": [5, 2, 11, 3], "texture": "#sides" }, + "down": { "uv": [5, 13, 11, 14], "texture": "#sides" } + } + }, + { + "from": [6, 6, 3], + "to": [10, 10, 4], + "faces": { + "north": { "uv": [6, 6, 10, 10], "texture": "#front" }, + "east": { "uv": [12, 6, 13, 10], "texture": "#sides" }, + "south": { "uv": [6, 6, 10, 10], "texture": "#back" }, + "west": { "uv": [3, 6, 4, 10], "texture": "#sides" }, + "up": { "uv": [6, 3, 10, 4], "texture": "#sides" }, + "down": { "uv": [6, 12, 10, 13], "texture": "#sides" } + } + }, + { + "from": [6, 6, 4], + "to": [10, 10, 5], + "faces": { + "east": { "uv": [11, 6, 12, 10], "texture": "#sidesStatus" }, + "south": { "uv": [6, 6, 10, 10], "texture": "#back" }, + "west": { "uv": [4, 6, 5, 10], "texture": "#sidesStatus" }, + "up": { "uv": [6, 4, 10, 5], "texture": "#sidesStatus" }, + "down": { "uv": [6, 11, 10, 12], "texture": "#sidesStatus" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/models/parts/essentia_import_bus_has_channel.json b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_import_bus_has_channel.json new file mode 100644 index 0000000..36899db --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_import_bus_has_channel.json @@ -0,0 +1,33 @@ +{ + "textures": { + "indicator": "ae2:part/monitor_sides_status_has_channel" + }, + "elements": [ + { + "from": [6, 6, 4], + "to": [10, 10, 5], + "faces": { + "down": { + "texture": "#indicator", + "tintindex": 1, + "neoforge_data": { "block_light": 15, "sky_light": 15 } + }, + "up": { + "texture": "#indicator", + "tintindex": 1, + "neoforge_data": { "block_light": 15, "sky_light": 15 } + }, + "east": { + "texture": "#indicator", + "tintindex": 1, + "neoforge_data": { "block_light": 15, "sky_light": 15 } + }, + "west": { + "texture": "#indicator", + "tintindex": 1, + "neoforge_data": { "block_light": 15, "sky_light": 15 } + } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/models/parts/essentia_import_bus_off.json b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_import_bus_off.json new file mode 100644 index 0000000..4e10656 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_import_bus_off.json @@ -0,0 +1,17 @@ +{ + "textures": { + "indicator": "ae2:part/monitor_sides_status_off" + }, + "elements": [ + { + "from": [6, 6, 4], + "to": [10, 10, 5], + "faces": { + "down": { "texture": "#indicator" }, + "up": { "texture": "#indicator" }, + "east": { "texture": "#indicator" }, + "west": { "texture": "#indicator" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/models/parts/essentia_import_bus_on.json b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_import_bus_on.json new file mode 100644 index 0000000..40e9a34 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_import_bus_on.json @@ -0,0 +1,33 @@ +{ + "textures": { + "indicator": "ae2:part/monitor_sides_status_on" + }, + "elements": [ + { + "from": [6, 6, 4], + "to": [10, 10, 5], + "faces": { + "down": { + "texture": "#indicator", + "tintindex": 3, + "neoforge_data": { "block_light": 15, "sky_light": 15 } + }, + "up": { + "texture": "#indicator", + "tintindex": 3, + "neoforge_data": { "block_light": 15, "sky_light": 15 } + }, + "east": { + "texture": "#indicator", + "tintindex": 3, + "neoforge_data": { "block_light": 15, "sky_light": 15 } + }, + "west": { + "texture": "#indicator", + "tintindex": 3, + "neoforge_data": { "block_light": 15, "sky_light": 15 } + } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/models/parts/essentia_level_emitter_base_off.json b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_level_emitter_base_off.json new file mode 100644 index 0000000..1daf4b0 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_level_emitter_base_off.json @@ -0,0 +1,28 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "particle": "ae2:part/level_emitter_off", + "emitter": "ae2:part/level_emitter_off", + "sides": "ae2:part/monitor_sides" + }, + "elements": [ + { + "from": [7, 7, 0], + "to": [9, 9, 4], + "faces": { + "north": { "uv": [4, 7, 6, 9], "texture": "#emitter" }, + "east": { "uv": [6, 7, 10, 9], "rotation": 180, "texture": "#emitter" }, + "west": { "uv": [6, 7, 10, 9], "texture": "#emitter" }, + "up": { "uv": [6, 9, 10, 7], "rotation": 90, "texture": "#emitter" }, + "down": { "uv": [6, 9, 10, 7], "rotation": 270, "texture": "#emitter" } + } + }, + { + "from": [7, 7, 4], + "to": [9, 9, 5], + "faces": { + "south": { "uv": [7, 7, 9, 9], "texture": "#sides" } + } + } + ] +} diff --git a/src/main/resources/assets/thaumicenergistics/models/parts/essentia_level_emitter_base_on.json b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_level_emitter_base_on.json new file mode 100644 index 0000000..b2bfaa7 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_level_emitter_base_on.json @@ -0,0 +1,36 @@ +{ + "credit": "Made with Blockbench", + "ambientocclusion": false, + "textures": { + "particle": "ae2:part/level_emitter_off", + "emitter": "ae2:part/level_emitter_off" + }, + "elements": [ + { + "from": [7, 7, 3], + "to": [9, 9, 4], + "faces": { + "east": { "uv": [9, 7, 10, 9], "rotation": 180, "texture": "#emitter" }, + "west": { "uv": [9, 7, 10, 9], "texture": "#emitter" }, + "up": { "uv": [9, 7, 10, 9], "rotation": 90, "texture": "#emitter" }, + "down": { "uv": [9, 7, 10, 9], "rotation": 270, "texture": "#emitter" } + } + }, + { + "from": [7, 7, 0], + "to": [9, 9, 3], + "shade": false, + "faces": { + "north": { + "uv": [4, 9, 6, 11], + "rotation": 270, + "texture": "#emitter" + }, + "east": { "uv": [9, 9, 6, 11], "texture": "#emitter" }, + "west": { "uv": [6, 11, 9, 9], "texture": "#emitter" }, + "up": { "uv": [6, 9, 9, 11], "rotation": 90, "texture": "#emitter" }, + "down": { "uv": [9, 11, 6, 9], "rotation": 90, "texture": "#emitter" } + } + } + ] +} diff --git a/src/main/resources/assets/thaumicenergistics/models/parts/essentia_level_emitter_status_has_channel.json b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_level_emitter_status_has_channel.json new file mode 100644 index 0000000..897306a --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_level_emitter_status_has_channel.json @@ -0,0 +1,33 @@ +{ + "textures": { + "indicator": "ae2:part/monitor_sides_status_has_channel" + }, + "elements": [ + { + "from": [7, 7, 4], + "to": [9, 9, 5], + "faces": { + "down": { + "texture": "#indicator", + "tintindex": 1, + "neoforge_data": { "block_light": 15, "sky_light": 15 } + }, + "up": { + "texture": "#indicator", + "tintindex": 1, + "neoforge_data": { "block_light": 15, "sky_light": 15 } + }, + "east": { + "texture": "#indicator", + "tintindex": 1, + "neoforge_data": { "block_light": 15, "sky_light": 15 } + }, + "west": { + "texture": "#indicator", + "tintindex": 1, + "neoforge_data": { "block_light": 15, "sky_light": 15 } + } + } + } + ] +} diff --git a/src/main/resources/assets/thaumicenergistics/models/parts/essentia_level_emitter_status_off.json b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_level_emitter_status_off.json new file mode 100644 index 0000000..88be3f1 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_level_emitter_status_off.json @@ -0,0 +1,25 @@ +{ + "textures": { + "indicator": "ae2:part/monitor_sides_status_off" + }, + "elements": [ + { + "from": [7, 7, 4], + "to": [9, 9, 5], + "faces": { + "down": { + "texture": "#indicator" + }, + "up": { + "texture": "#indicator" + }, + "east": { + "texture": "#indicator" + }, + "west": { + "texture": "#indicator" + } + } + } + ] +} diff --git a/src/main/resources/assets/thaumicenergistics/models/parts/essentia_level_emitter_status_on.json b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_level_emitter_status_on.json new file mode 100644 index 0000000..8a8ad42 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_level_emitter_status_on.json @@ -0,0 +1,33 @@ +{ + "textures": { + "indicator": "ae2:part/monitor_sides_status_on" + }, + "elements": [ + { + "from": [7, 7, 4], + "to": [9, 9, 5], + "faces": { + "down": { + "texture": "#indicator", + "tintindex": 3, + "neoforge_data": { "block_light": 15, "sky_light": 15 } + }, + "up": { + "texture": "#indicator", + "tintindex": 3, + "neoforge_data": { "block_light": 15, "sky_light": 15 } + }, + "east": { + "texture": "#indicator", + "tintindex": 3, + "neoforge_data": { "block_light": 15, "sky_light": 15 } + }, + "west": { + "texture": "#indicator", + "tintindex": 3, + "neoforge_data": { "block_light": 15, "sky_light": 15 } + } + } + } + ] +} diff --git a/src/main/resources/assets/thaumicenergistics/models/parts/essentia_storage_bus_base.json b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_storage_bus_base.json new file mode 100644 index 0000000..0010d6c --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_storage_bus_base.json @@ -0,0 +1,46 @@ +{ + "credit": "Made with Blockbench by Sea_Kerman", + "textures": { + "sides": "ae2:part/storage_bus_sides", + "back": "ae2:part/storage_bus_back", + "front": "thaumicenergistics:part/essentia_storage_bus_face" + }, + "elements": [ + { + "from": [3, 3, 0], + "to": [13, 13, 2], + "faces": { + "north": { "uv": [3, 3, 13, 13], "texture": "#front" }, + "east": { "uv": [14, 3, 16, 13], "texture": "#sides" }, + "south": { "uv": [3, 3, 13, 13], "texture": "#sides" }, + "west": { "uv": [0, 3, 2, 13], "texture": "#sides" }, + "up": { "uv": [3, 0, 13, 2], "texture": "#sides" }, + "down": { "uv": [3, 14, 13, 16], "texture": "#sides" } + } + }, + { + "from": [2, 2, 2], + "to": [14, 14, 3], + "faces": { + "north": { "uv": [2, 2, 14, 14], "texture": "#front" }, + "east": { "uv": [13, 2, 14, 14], "texture": "#sides" }, + "south": { "uv": [2, 2, 14, 14], "texture": "#sides" }, + "west": { "uv": [2, 2, 3, 14], "texture": "#sides" }, + "up": { "uv": [2, 2, 14, 3], "texture": "#sides" }, + "down": { "uv": [2, 13, 14, 14], "texture": "#sides" } + } + }, + { + "from": [5, 5, 3], + "to": [11, 11, 5], + "faces": { + "north": { "uv": [5, 5, 11, 11], "texture": "#front" }, + "east": { "uv": [6, 5, 8, 11], "texture": "#sides" }, + "south": { "uv": [5, 5, 11, 11], "texture": "#back" }, + "west": { "uv": [8, 5, 10, 11], "texture": "#sides" }, + "up": { "uv": [5, 3, 11, 5], "texture": "#sides" }, + "down": { "uv": [5, 11, 11, 13], "texture": "#sides" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/models/parts/essentia_storage_bus_has_channel.json b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_storage_bus_has_channel.json new file mode 100644 index 0000000..8d8f515 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_storage_bus_has_channel.json @@ -0,0 +1,17 @@ +{ + "textures": { + "indicator": "ae2:part/monitor_sides_status_has_channel" + }, + "elements": [ + { + "from": [5, 5, 3], + "to": [11, 11, 5], + "faces": { + "down": { "texture": "#indicator" }, + "up": { "texture": "#indicator" }, + "east": { "texture": "#indicator" }, + "west": { "texture": "#indicator" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/models/parts/essentia_storage_bus_off.json b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_storage_bus_off.json new file mode 100644 index 0000000..bd0c9de --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_storage_bus_off.json @@ -0,0 +1,17 @@ +{ + "textures": { + "indicator": "ae2:part/monitor_sides_status_off" + }, + "elements": [ + { + "from": [5, 5, 3], + "to": [11, 11, 5], + "faces": { + "down": { "texture": "#indicator" }, + "up": { "texture": "#indicator" }, + "east": { "texture": "#indicator" }, + "west": { "texture": "#indicator" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/models/parts/essentia_storage_bus_on.json b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_storage_bus_on.json new file mode 100644 index 0000000..ad40a80 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_storage_bus_on.json @@ -0,0 +1,17 @@ +{ + "textures": { + "indicator": "ae2:part/monitor_sides_status_on" + }, + "elements": [ + { + "from": [5, 5, 3], + "to": [11, 11, 5], + "faces": { + "down": { "texture": "#indicator" }, + "up": { "texture": "#indicator" }, + "east": { "texture": "#indicator" }, + "west": { "texture": "#indicator" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/models/parts/essentia_terminal_base.json b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_terminal_base.json new file mode 100644 index 0000000..6d86aa3 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_terminal_base.json @@ -0,0 +1,138 @@ +{ + "credit": "对齐 AE2 monitor_base.json", + "textures": { + "sides": "ae2:part/monitor_sides", + "particle": "ae2:part/monitor_back_no_status", + "back": "ae2:part/monitor_back_no_status", + "front": "ae2:part/monitor_front" + }, + "elements": [ + { + "from": [ + 2, + 2, + 0 + ], + "to": [ + 14, + 14, + 2 + ], + "faces": { + "north": { + "uv": [ + 2, + 2, + 14, + 14 + ], + "texture": "#front" + }, + "east": { + "uv": [ + 14, + 2, + 16, + 14 + ], + "texture": "#sides" + }, + "south": { + "uv": [ + 2, + 2, + 14, + 14 + ], + "texture": "#back" + }, + "west": { + "uv": [ + 0, + 2, + 2, + 14 + ], + "texture": "#sides" + }, + "up": { + "uv": [ + 2, + 0, + 14, + 2 + ], + "texture": "#sides" + }, + "down": { + "uv": [ + 2, + 14, + 14, + 16 + ], + "texture": "#sides" + } + } + }, + { + "from": [ + 4, + 4, + 2 + ], + "to": [ + 12, + 12, + 3 + ], + "faces": { + "east": { + "uv": [ + 11, + 4, + 12, + 12 + ], + "texture": "#back" + }, + "south": { + "uv": [ + 4, + 4, + 12, + 12 + ], + "texture": "#back" + }, + "west": { + "uv": [ + 4, + 4, + 5, + 12 + ], + "texture": "#back" + }, + "up": { + "uv": [ + 4, + 4, + 12, + 5 + ], + "texture": "#back" + }, + "down": { + "uv": [ + 4, + 11, + 12, + 12 + ], + "texture": "#back" + } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/models/parts/essentia_terminal_has_channel.json b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_terminal_has_channel.json new file mode 100644 index 0000000..f9e1c4e --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_terminal_has_channel.json @@ -0,0 +1,18 @@ +{ + "textures": { + "lightsBright": "thaumicenergistics:part/essentia_terminal/bright", + "lightsMedium": "thaumicenergistics:part/essentia_terminal/medium", + "lightsDark": "thaumicenergistics:part/essentia_terminal/dark" + }, + "elements": [ + { "from": [2, 2, 0], "to": [14, 14, 2], "faces": { + "north": { "texture": "#lightsBright", "tintindex": 3, "neoforge_data": { "block_light": 15, "sky_light": 15 } } + }}, + { "from": [2, 2, 0], "to": [14, 14, 2], "faces": { + "north": { "texture": "#lightsMedium", "tintindex": 2, "neoforge_data": { "block_light": 15, "sky_light": 15 } } + }}, + { "from": [2, 2, 0], "to": [14, 14, 2], "faces": { + "north": { "texture": "#lightsDark", "tintindex": 1, "neoforge_data": { "block_light": 15, "sky_light": 15 } } + }} + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/models/parts/essentia_terminal_off.json b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_terminal_off.json new file mode 100644 index 0000000..7842ce3 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_terminal_off.json @@ -0,0 +1,9 @@ +{ + "credit": "对齐 AE2 terminal_off.json:parent继承display_off的3层覆层,只改textures路径", + "parent": "ae2:part/display_off", + "textures": { + "lightsBright": "thaumicenergistics:part/essentia_terminal/bright", + "lightsMedium": "thaumicenergistics:part/essentia_terminal/medium", + "lightsDark": "thaumicenergistics:part/essentia_terminal/dark" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/models/parts/essentia_terminal_on.json b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_terminal_on.json new file mode 100644 index 0000000..7842ce3 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/parts/essentia_terminal_on.json @@ -0,0 +1,9 @@ +{ + "credit": "对齐 AE2 terminal_off.json:parent继承display_off的3层覆层,只改textures路径", + "parent": "ae2:part/display_off", + "textures": { + "lightsBright": "thaumicenergistics:part/essentia_terminal/bright", + "lightsMedium": "thaumicenergistics:part/essentia_terminal/medium", + "lightsDark": "thaumicenergistics:part/essentia_terminal/dark" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/models/parts/p2p/p2p_tunnel_vis.json b/src/main/resources/assets/thaumicenergistics/models/parts/p2p/p2p_tunnel_vis.json new file mode 100644 index 0000000..a3b9fcf --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/models/parts/p2p/p2p_tunnel_vis.json @@ -0,0 +1,6 @@ +{ + "parent": "ae2:part/p2p/p2p_tunnel_base", + "textures": { + "type": "thaumicenergistics:part/vis_interface" + } +} diff --git a/src/main/resources/assets/thaumicenergistics/screens/aspect_filter_selection.json b/src/main/resources/assets/thaumicenergistics/screens/aspect_filter_selection.json new file mode 100644 index 0000000..a381b16 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/screens/aspect_filter_selection.json @@ -0,0 +1,28 @@ +{ + "$schema": "../schema.json", + "includes": ["common/common.json"], + "generatedBackground": { + "width": 300 + }, + "text": { + "dialog_title": { + "position": { + "left": 8, + "top": 7 + } + } + }, + "widgets": { + "back": { + "left": 276, + "top": -5, + "width": 20, + "height": 20 + }, + "aspects": { + "left": 10, + "top": 20, + "width": 280 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/screens/essentia_export_bus.json b/src/main/resources/assets/thaumicenergistics/screens/essentia_export_bus.json new file mode 100644 index 0000000..bb220b9 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/screens/essentia_export_bus.json @@ -0,0 +1,30 @@ +{ + "$schema": "schema.json", + "includes": [ + "/screens/common/common.json", + "/screens/common/player_inventory.json", + "/screens/common/toolbox.json" + ], + "background": { + "texture": "ae2:guis/storagebus.png", + "srcRect": [0, 0, 176, 253] + }, + "slots": { + "CONFIG": { + "left": 8, + "top": 29, + "grid": "BREAK_AFTER_9COLS" + } + }, + "text": { + "dialog_title": { + "text": { + "translate": "item.thaumicenergistics.essentia_export_bus" + }, + "position": { + "left": 8, + "top": 6 + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/screens/essentia_import_bus.json b/src/main/resources/assets/thaumicenergistics/screens/essentia_import_bus.json new file mode 100644 index 0000000..38681e6 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/screens/essentia_import_bus.json @@ -0,0 +1,30 @@ +{ + "$schema": "schema.json", + "includes": [ + "/screens/common/common.json", + "/screens/common/player_inventory.json", + "/screens/common/toolbox.json" + ], + "background": { + "texture": "ae2:guis/storagebus.png", + "srcRect": [0, 0, 176, 253] + }, + "slots": { + "CONFIG": { + "left": 8, + "top": 29, + "grid": "BREAK_AFTER_9COLS" + } + }, + "text": { + "dialog_title": { + "text": { + "translate": "item.thaumicenergistics.essentia_import_bus" + }, + "position": { + "left": 8, + "top": 6 + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/screens/essentia_storage_bus.json b/src/main/resources/assets/thaumicenergistics/screens/essentia_storage_bus.json new file mode 100644 index 0000000..69ba576 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/screens/essentia_storage_bus.json @@ -0,0 +1,38 @@ +{ + "$schema": "schema.json", + "includes": [ + "/screens/common/common.json", + "/screens/common/player_inventory.json", + "/screens/common/toolbox.json" + ], + "background": { + "texture": "ae2:guis/storagebus.png", + "srcRect": [0, 0, 176, 253] + }, + "slots": { + "CONFIG": { + "left": 8, + "top": 29, + "grid": "BREAK_AFTER_9COLS" + } + }, + "text": { + "dialog_title": { + "text": { + "translate": "item.thaumicenergistics.essentia_storage_bus" + }, + "position": { + "left": 8, + "top": 6 + } + } + }, + "widgets": { + "openPriority": { + "left": 152, + "top": -5, + "width": 20, + "height": 20 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/textures/block/arcane_assembler_fallback.png b/src/main/resources/assets/thaumicenergistics/textures/block/arcane_assembler_fallback.png new file mode 100644 index 0000000000000000000000000000000000000000..0b6d63b770d36af75541c8527e29015810caa58f GIT binary patch literal 2979 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/block/distillation_encoder_face.png b/src/main/resources/assets/thaumicenergistics/textures/block/distillation_encoder_face.png new file mode 100644 index 0000000000000000000000000000000000000000..27df013dc197007e30e9abd464deb6a26d140082 GIT binary patch literal 3644 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 Hu0mjfg~J2Z literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/block/e_vibration_face_potentia.png b/src/main/resources/assets/thaumicenergistics/textures/block/e_vibration_face_potentia.png new file mode 100644 index 0000000000000000000000000000000000000000..1a2cdce383761336a38b783aa4e0bebf71134dba GIT binary patch literal 3914 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 Y09wOyP#pM_s{jB107*qoM6N<$f+o;gbpQYW literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/block/e_vibration_face_potentia.png.mcmeta b/src/main/resources/assets/thaumicenergistics/textures/block/e_vibration_face_potentia.png.mcmeta new file mode 100644 index 0000000..f6730e3 --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/textures/block/e_vibration_face_potentia.png.mcmeta @@ -0,0 +1,5 @@ +{ + "animation": { + "frametime": 4 + } +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/textures/block/e_vibration_input.png b/src/main/resources/assets/thaumicenergistics/textures/block/e_vibration_input.png new file mode 100644 index 0000000000000000000000000000000000000000..a4f39d358111f07d2285235bb624e81f79c112a7 GIT binary patch literal 3248 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 A`~Uy| literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/gui/arcane_assembler.png b/src/main/resources/assets/thaumicenergistics/textures/gui/arcane_assembler.png new file mode 100644 index 0000000000000000000000000000000000000000..dea1b5f452a85c5f59d7e4c52974f630fdb5af51 GIT binary patch literal 6244 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/gui/arcane_crafting.png b/src/main/resources/assets/thaumicenergistics/textures/gui/arcane_crafting.png new file mode 100644 index 0000000000000000000000000000000000000000..2bfb862c21905b8ac30b979ddee127fc405317c7 GIT binary patch literal 9899 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/gui/distillation_encoder.png b/src/main/resources/assets/thaumicenergistics/textures/gui/distillation_encoder.png new file mode 100644 index 0000000000000000000000000000000000000000..727e045f76f76549868810067607628341ad0cc4 GIT binary patch literal 4058 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/gui/essentia_cell_workbench.png b/src/main/resources/assets/thaumicenergistics/textures/gui/essentia_cell_workbench.png new file mode 100644 index 0000000000000000000000000000000000000000..f8b05eb82ed6f72b3c131b197c44d7fe8a7c214e GIT binary patch literal 4198 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 UXKN)|eKrNUnnoJcFo&pr0O$~8;s5{u literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/gui/essentia_terminal.png b/src/main/resources/assets/thaumicenergistics/textures/gui/essentia_terminal.png new file mode 100644 index 0000000000000000000000000000000000000000..edcfdee7f28aef0c573a043df9e0454f6c73694f GIT binary patch literal 4163 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 UR*$*Q9-JQf+D3?SEr@RT0LD&GXNmO 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 Bd&K|% literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/gui/knowledge_inscriber.png b/src/main/resources/assets/thaumicenergistics/textures/gui/knowledge_inscriber.png new file mode 100644 index 0000000000000000000000000000000000000000..4385c3286c23f7fba42fee7945467a11ad09f170 GIT binary patch literal 4897 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/gui/priority.png b/src/main/resources/assets/thaumicenergistics/textures/gui/priority.png new file mode 100644 index 0000000000000000000000000000000000000000..1ba06a2b1f01e1d9a344ea324ddf3bed3b02556c GIT binary patch literal 1256 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 D`*5~A literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/item/essentia_cell_16k.png b/src/main/resources/assets/thaumicenergistics/textures/item/essentia_cell_16k.png new file mode 100644 index 0000000000000000000000000000000000000000..794b41f4557ef26011fe268fd5f1c8c2a33a010d GIT binary patch literal 3078 zcmV+h4EghkP)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0003oNkld?q>IP@8Bhu%VqC-_h#lsFf+RS0cyniyGR|rJU$>py_kqV zM7~j^tO>SiGRXkI7~?J4WHXDj3z4pfYusHsq_?xC^D(SC+&8S zCg0Z|nGlf!E$olhGIor@ez}^&hu3B4o{cdA00cARtka7o0RTl&xc&gZx-9Xr**N(9 z^(pLuO)?)`CcE#$wZF14Mx6GqBG`}p=Pp!xQU|*p2oax67e%nnch@T3IA;6~016eh U4t6PRMgRZ+07*qoM6N<$f}zj3;Q#;t literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/item/essentia_cell_1k.png b/src/main/resources/assets/thaumicenergistics/textures/item/essentia_cell_1k.png new file mode 100644 index 0000000000000000000000000000000000000000..fb69ef330a4f54680cf70c38faf5708ded96683f GIT binary patch literal 3058 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 AzW@LL literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/item/essentia_cell_4k.png b/src/main/resources/assets/thaumicenergistics/textures/item/essentia_cell_4k.png new file mode 100644 index 0000000000000000000000000000000000000000..2ddd57fce88faa3e5e2634523010be6fcbd1a12a GIT binary patch literal 3060 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 D`*5~A literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/item/essentia_cell_creative.png b/src/main/resources/assets/thaumicenergistics/textures/item/essentia_cell_creative.png new file mode 100644 index 0000000000000000000000000000000000000000..d726763451d837c247cbc1d8788bf356bdabb741 GIT binary patch literal 3113 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/item/foci_aewrench.png b/src/main/resources/assets/thaumicenergistics/textures/item/foci_aewrench.png new file mode 100644 index 0000000000000000000000000000000000000000..515676f9e63e0f568f97383cb9a7023b07f52ed8 GIT binary patch literal 3296 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/item/knowledge_core.png.mcmeta b/src/main/resources/assets/thaumicenergistics/textures/item/knowledge_core.png.mcmeta new file mode 100644 index 0000000..034019f --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/textures/item/knowledge_core.png.mcmeta @@ -0,0 +1,5 @@ +{ + "animation": { + "frametime": 3 + } +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/textures/item/material_coalescence_core.png b/src/main/resources/assets/thaumicenergistics/textures/item/material_coalescence_core.png new file mode 100644 index 0000000000000000000000000000000000000000..7b83e340971667882e69073c61b5bac10c2162ff GIT binary patch literal 3000 zcmV;p3rF;cP)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0002vNkl1p=5JjItLYzL3PN)c5MWjg~aAV&iEINiRupqWfDG=681Zk{h z3!^$9RQn3%rwF8oWygt0k%57oVdnAqyBkU3oVei3_*+0#Rr)o+IVWQb&bgzIXv)O0 zER|*1XWexjMNvd20h*>!k|Y51eNURE01U%Gp67dz%dd^aZVqoB=hga!=jA;BkGFR} zH}QHl`}P+06ue%oiQ^c6r`>|h_6C4)9I+24D6rN>Ap`)7F#v=Ru+~nRh@{E%-m7g} udGB>-M$%z`B9sIA)^gaMZ!kMU#fTJD&0000KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z00022Nkl1u68}C12akB2TgNDlCa$$@d(c>XNN;Uz`henc7~Y1X2y4}tp--e rG{6KN)F7#oeJ^}^D+&Dn&-5Aq1W#VWFkD6f00000NkvXXu0mjfEf#Q1 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/item/storage_component_16k.png b/src/main/resources/assets/thaumicenergistics/textures/item/storage_component_16k.png new file mode 100644 index 0000000000000000000000000000000000000000..565acd53200c4d4ec33637acfa0e31b4e30f40fd GIT binary patch literal 2974 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 RI}-o^002ovPDHLkV1nEhdu{*# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/item/storage_component_4k.png b/src/main/resources/assets/thaumicenergistics/textures/item/storage_component_4k.png new file mode 100644 index 0000000000000000000000000000000000000000..2344cfb881d6e5dad585e1813b61b5bced19fba2 GIT binary patch literal 2961 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 Hu0mjfvMYRn literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/item/storage_component_64k.png b/src/main/resources/assets/thaumicenergistics/textures/item/storage_component_64k.png new file mode 100644 index 0000000000000000000000000000000000000000..b0e09245a00c60af7ddd8de2aae06a8d05b5ec0f GIT binary patch literal 3053 zcmVKLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0003PNklsbPJ39!hpR9TV({R8TJAT zdj-V{h@|imsh`D|FcTFQ#;(mNe&oN+plO=aLM;2R?Ral``^a`99w3B(wN@2O zgc1>sPfrBk;_Q4c6*jvq0B_H)YBU35%-$+QlmNHaH=~953#-MF5W@c~QZZO#HPkuw v39#91llJ-D{4c0jT9hjHhry|ZDfk=!c8Rp^Li_Bu00000NkvXXu0mjfi5RaV literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/item/wireless_essentia_terminal.png b/src/main/resources/assets/thaumicenergistics/textures/item/wireless_essentia_terminal.png new file mode 100644 index 0000000000000000000000000000000000000000..04e425a9c42b3aca11805f5c75a96094d8fbd2d9 GIT binary patch literal 3460 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 mvOTJ6Z2NRo_22&;{~Z8j$7DL9f;w&h0000 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/model/golemBackpack/Clay.png b/src/main/resources/assets/thaumicenergistics/textures/model/golemBackpack/Clay.png new file mode 100644 index 0000000000000000000000000000000000000000..3e8f4b7387ef2fd20ce7cbdd4c9803e771f31773 GIT binary patch literal 4252 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 A0RR91 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/model/golemBackpack/Gold.png b/src/main/resources/assets/thaumicenergistics/textures/model/golemBackpack/Gold.png new file mode 100644 index 0000000000000000000000000000000000000000..6c98730ec65364c9d1cfc5c8863adfe6b166afa9 GIT binary patch literal 4348 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/model/golemBackpack/Stone.png b/src/main/resources/assets/thaumicenergistics/textures/model/golemBackpack/Stone.png new file mode 100644 index 0000000000000000000000000000000000000000..ea52fceec4b2b257988899c00372e4a275cadae9 GIT binary patch literal 4343 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/model/golemBackpack/Thaum.png b/src/main/resources/assets/thaumicenergistics/textures/model/golemBackpack/Thaum.png new file mode 100644 index 0000000000000000000000000000000000000000..effad48564cac485be6da2fdb78231014a807f62 GIT binary patch literal 3836 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 OY3u3g=d#Wzp$Pz^Log!% literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/part/arcane_crafting_terminal/arcane_crafting_overlay2.png b/src/main/resources/assets/thaumicenergistics/textures/part/arcane_crafting_terminal/arcane_crafting_overlay2.png new file mode 100644 index 0000000000000000000000000000000000000000..0e008ce66d97d8607a9b6e86a9ed2f848b17f13e GIT binary patch literal 2841 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 A82|tP literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/part/arcane_crafting_terminal/arcane_crafting_side.png b/src/main/resources/assets/thaumicenergistics/textures/part/arcane_crafting_terminal/arcane_crafting_side.png new file mode 100644 index 0000000000000000000000000000000000000000..a9a340157a2f5964ff52c4918f23f0dc11f949af GIT binary patch literal 1605 zcmbVMX;2eq7>=UAAZlxCMMmhFv<60#%`PltBf$xqM4}B~NR?8AF3A_jKz5VOVnP%V za8#yys4T*rH&gR?;ALg`;LU%`+^&0v#K;Ul{T>sk^wx0kWJOggzFN%laoHCBU0$37qTJkBo%qi!O@yfWlcN^wI zVl^{_tB7sp{gdno$SQ!!njX!)& zjWL>JI;DDCi(AS0xh!jy!LY;O5Ids8G?N1(IF7>-6h=`IXCbl|QY`5dQFeikK?&>z z#%yKHGzEDX$!xlSmGe1IpIyOX)oPy;Q}*#daUp}9q!mWQ64+w#-fPU-&g#IwZoJUi zt}nC#SO@HM0b}6uVG{VjT?}zcfKS)V>5gNOmttiE14x!;^faCCtALbTnx*Zzv=t%Nfqbk~nr%R_7?BYpNs$qc#ziEKpdtx~CbMx1v8#BvxNKzfQMIm-+ZAuA&O5 zYhmr2;z-aJ*n_mi7N;-4yL)Vlx<}VMzWB%OyLY&gLRr5|D}JX4Q?r$A9+j521M@kL(g>(@>K&h;Vm13 z$}>)$(9i9@?&5Dd`(GixL}Fo;@)WdGgt(#||B6oOih8=+cId@**s`dk}kI=d6+Zt};M9 zDDt0qrtYhf5ZA2mzi&3)4k(yEvRsPsufxWylK~F~-ss!zz854s6JMEKAO7a8nXLPc zsx;%g|AmtJD}~nrTYfKHo9iiVT$%Yp^SY7^)AxM)+7Na7#(O)50@BVNajORR|58)^ zc*nl!{k=EZ4xG;v4Q$aN70l<382sMmg<YU6vy#zlAGI-QiWg(X0UV+#T29upzba{fwNoRz|D7X@gbai12;i3h=M~=bcs-? ze`4;dN<(oJpZ>N7J+fv zV|Va^DFU=|q(ebJj>w)hn;VVsCQz%K_t%Qs?2}(D!D&v8AfFl5BG&-?#lq+U=Sy_m z;qn@;ZaQp@BCK%~W%CCOpePhxT~TR;l#(P#5HcW&S~x#keuBlP7l#}lw3(bq+Hr|h zV`TRY;Z2tVQaJ7&OXgpe>?xoZ3xe>ThbbJ6>~f$V3--4qN?YdN7GoT(wqkDpB5Izn a3j6`HFkWCKs7^ru0000z@X#XPVZ z=$%}+@Ey(vhluG=-k-VgOCbbo)*G}Iq(_Qyrg(haa(?~(=SEKftG9uhyNo1BcAImK zwr#n+{O}AsfKrMq%P7l|rfIO&lBOwnp0gc2VIMF$g)xS@uIc+8=NwW>q?9PE2awZ2 z*x{#zz&W>TfG7(08$@$3#t_Fb)>@>L#Bq#L3O$SV0~S$0*L4&{fe^nxS5<`!Pl1>J y0n6t#R~IXW!7>j6PL4G?Sm2O6Jbiiwhrl<_)>1S_c;T-A00007!Oep7viFHQ;0Mb0wPG;iHQrDNy%g} z3&npk?;jrT|K5ZDmaxU@;k>OsB|^Y{w?|JE$6hJH$wZQjBu~o&7dNj0K-mGs+HiY6 z4NASc+PFHhg_JTF`%pXZj-YP40aaB2P?jYCd7cB1W!X;{jZZM2x4{Hwv)Csn*2aC> zk`eN@hO6;$_G6 zWq~mb<0NL1!u!XU^QW0Y#VIWjkI!$xVSlf0MdeC{8r11}00000NkvXXu0mjfr~Q8A literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/part/essentia_terminal/bright.png b/src/main/resources/assets/thaumicenergistics/textures/part/essentia_terminal/bright.png new file mode 100644 index 0000000000000000000000000000000000000000..ef88e6d5f63e4ccd9d3336bd3fb5f4103f666f1c GIT binary patch literal 2996 zcmV;l3rqBgP)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0002rNklZ~ori~-P>dMYtZf|Bx*_J#~YF2E!SFxrU7 zv*QXEG^@9>0MinT-ah{tMr8;xVOshO(1!Pc)~yXNoMpg7-Kjs8+3**QsMbulvZgi9 qGi(S)S2+7j5WN44Hh{kea18)`bYh2Z`6+Jz0000l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|8K--E^(yW49+@N*=dA3R!B_#z``ugSN z<$C4Ddih1^`i7R4mih)p`bI{&Koz>hm3bwJ6}oxF$}kgLQj3#|G7CyF^YauyCMG83 zmzLNn0bL65LT&-v*t}wBFaZNhzap_f-%!s0;1ij}d6o0*Z5qoJX(IWVYQO`KeT;biJ&Y3Aev zWV#r^^t$9Hm*%GCmB93-AoLpH)C)=pxdlL*T~doO%TiO^it=+6z&^Ih#OW4GH=O1{ z^`_u<3oxPJ@P|IoG5Vl*MT%#b5HRt8nDA5!Eakt zaqG?0gWOF9BFDDNaByXXuYY(l_`?7CH&Ra)I?EmA<7`~8LSucVugR+ot-_DqD&3y& z_ulun)r%P%rpah;`ryF80z?U$>{BAI)%#vn$-V7#+2rn&uG-^;TQnJ#AKquZ!CIyy znjwa97iamCnw^LA1wy_VYIQAQ-=NdI&$)N)3}42>2K(N9v|f0$Y2PoK^NOC6Hr9BV zc`$cq&q43xw_ugKVDtubdgd2V~LpS zp=<%250`Uv{bsaL4GK)ry0AyKd4toI)OlP77GB64}c+Vim#KUm&L3G6; S7lu?&x!~#Q=d#Wzp$P!GFoYEV literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/part/essentia_terminal/medium.png b/src/main/resources/assets/thaumicenergistics/textures/part/essentia_terminal/medium.png new file mode 100644 index 0000000000000000000000000000000000000000..e0c2d3216f093c90ee9a49117f9b6acb619420d2 GIT binary patch literal 1042 zcmaJ=O=#0l91nJmQQ0oy_k_3X-~^jA>DQ92ZnbH*q8+s@tfG@;$=e#YhvrO6DO(b7!*cDekEO#5&whcjp#7i9}l5fzO=kkI7`n1-@CbAA=}Qk1Jh z%jR${c|uf>&d3giDd{F*Q&ewX$&{5zh`|_~(2OwsW9c~!G&M{Q2a?{T8HIUmux!Ch zc_^!tClx`Z`;LO%l1Kz}h-FaHrwm&xh3Sf}NY>6VOM?moPloBuq;km=h$0Ju02A;i zUY-LXf#Cvvf#Z$<-plz|&dc(GhvP(lNaTW``q3nsrH+efDPE05c40b?u_>}_u~=k^ zJ_cD6EGGy8>*ZOV_Yj1~o-wdo@)&k!O+kXTVreGUkO3S;c?=bBm?oKSmY|z;S;MZj zi8PEY$tKG&UZit`zW)@qvoj`S)6hl*OCc9G-syxg#i#{kjI1m| zQ?)Lp@(3e4k4zAag05lBP*Kr7T!AN(V#2VoY$z}xg=r$dXqqbeLJ>abi-$O0h_pK9 zkHmajw@;FyL7s~V@j#6$A*G;01J}6f7Pq@0*KvYwlE@OYv}vfuEu@1=#iG_Ymq0_k zDpzfsORyoACCRYPz5aF2wIgC4XIXbG+0=ax4PthSxcc4WwRQ3$77|h zNh`y7uSQ1C?a3|mf1meUN-=Z7$5z+x q*H1gzPp>@s!iMfQ=Vz}!YuZbVYzxpmnU|~1D^0|Pq$kHl=l=lUdrk=e literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/part/vis_interface.png b/src/main/resources/assets/thaumicenergistics/textures/part/vis_interface.png new file mode 100644 index 0000000000000000000000000000000000000000..b3b73061026e4d8b695ea18736ab3492a3ee14ae GIT binary patch literal 7395 zcmZWtXEs3Cf9k)lKoK|~w9MT$%r`ueI*AV~h>8XecjJ0sugxqpfaAj9dUff`pP2 zPrvBzMG*sqm$vmI0HC_`_W=RfxvT&{X>?yr&Dhx0)7SHntEU&2j+z>mmyf6O{Rd6} z;6IgT=3;KP!K{2VcYxB1#-!?bnleGTOi{5I#w31WZVEcxXzrJjOeXF08XBbReFf3r z_;^ellZgoRGs^Ff74BE@PhUqr8#rAIdhI^Ze6%)nUiS^LUXIVJ9f9DW)alw%CNdc6 zx2P-h3r~BydKOp2kXTAyFMtkOdyo6k*;Nog2vJhH#)E^j0wDi!Dky+6$iYc)L|wps zqOxp3m~arzH%U$pieUthf$^v!0I3PW5hcXBvQ&1i7AES

IMKeOh;7%K&b%< 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/part/vis_interface.png.mcmeta b/src/main/resources/assets/thaumicenergistics/textures/part/vis_interface.png.mcmeta new file mode 100644 index 0000000..034019f --- /dev/null +++ b/src/main/resources/assets/thaumicenergistics/textures/part/vis_interface.png.mcmeta @@ -0,0 +1,5 @@ +{ + "animation": { + "frametime": 3 + } +} \ No newline at end of file diff --git a/src/main/resources/assets/thaumicenergistics/textures/part/vis_interface_runes.png b/src/main/resources/assets/thaumicenergistics/textures/part/vis_interface_runes.png new file mode 100644 index 0000000000000000000000000000000000000000..24d55303aafafb5685b6aad713227b9a16f4e210 GIT binary patch literal 2884 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 N002ovPDHLkV1n6N@CyI{ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaumicenergistics/textures/research/research_background.png b/src/main/resources/assets/thaumicenergistics/textures/research/research_background.png new file mode 100644 index 0000000000000000000000000000000000000000..f1ae3628a8ae56d63cba7acaf859bb3cb6ff9cb4 GIT binary patch literal 279672 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%0Ab67 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/data/thaumicenergistics/recipe/essentia_cell_16k.json b/src/main/resources/data/thaumicenergistics/recipe/essentia_cell_16k.json new file mode 100644 index 0000000..94e3bf8 --- /dev/null +++ b/src/main/resources/data/thaumicenergistics/recipe/essentia_cell_16k.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "key": { + "W": { "tag": "thaumicenergistics:essentia_cell_glass" }, + "R": { "item": "minecraft:redstone" }, + "C": { "item": "thaumicenergistics:storage_component_16k" }, + "T": { "item": "thaumcraft:thaumium_ingot" } + }, + "pattern": [ + "WRW", + "RCR", + "TTT" + ], + "result": { + "count": 1, + "id": "thaumicenergistics:essentia_cell_16k" + } +} \ No newline at end of file diff --git a/src/main/resources/data/thaumicenergistics/recipe/essentia_cell_16k_shapeless.json b/src/main/resources/data/thaumicenergistics/recipe/essentia_cell_16k_shapeless.json new file mode 100644 index 0000000..d9ce19a --- /dev/null +++ b/src/main/resources/data/thaumicenergistics/recipe/essentia_cell_16k_shapeless.json @@ -0,0 +1,12 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + { "item": "thaumicenergistics:storage_casing" }, + { "item": "thaumicenergistics:storage_component_16k" } + ], + "result": { + "count": 1, + "id": "thaumicenergistics:essentia_cell_16k" + } +} \ No newline at end of file diff --git a/src/main/resources/data/thaumicenergistics/recipe/essentia_cell_1k.json b/src/main/resources/data/thaumicenergistics/recipe/essentia_cell_1k.json new file mode 100644 index 0000000..1c67fd6 --- /dev/null +++ b/src/main/resources/data/thaumicenergistics/recipe/essentia_cell_1k.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "key": { + "W": { "tag": "thaumicenergistics:essentia_cell_glass" }, + "R": { "item": "minecraft:redstone" }, + "C": { "item": "thaumicenergistics:storage_component_1k" }, + "T": { "item": "thaumcraft:thaumium_ingot" } + }, + "pattern": [ + "WRW", + "RCR", + "TTT" + ], + "result": { + "count": 1, + "id": "thaumicenergistics:essentia_cell_1k" + } +} \ No newline at end of file diff --git a/src/main/resources/data/thaumicenergistics/recipe/essentia_cell_1k_shapeless.json b/src/main/resources/data/thaumicenergistics/recipe/essentia_cell_1k_shapeless.json new file mode 100644 index 0000000..f9069c3 --- /dev/null +++ b/src/main/resources/data/thaumicenergistics/recipe/essentia_cell_1k_shapeless.json @@ -0,0 +1,12 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + { "item": "thaumicenergistics:storage_casing" }, + { "item": "thaumicenergistics:storage_component_1k" } + ], + "result": { + "count": 1, + "id": "thaumicenergistics:essentia_cell_1k" + } +} \ No newline at end of file diff --git a/src/main/resources/data/thaumicenergistics/recipe/essentia_cell_4k.json b/src/main/resources/data/thaumicenergistics/recipe/essentia_cell_4k.json new file mode 100644 index 0000000..f1dd2a1 --- /dev/null +++ b/src/main/resources/data/thaumicenergistics/recipe/essentia_cell_4k.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "key": { + "W": { "tag": "thaumicenergistics:essentia_cell_glass" }, + "R": { "item": "minecraft:redstone" }, + "C": { "item": "thaumicenergistics:storage_component_4k" }, + "T": { "item": "thaumcraft:thaumium_ingot" } + }, + "pattern": [ + "WRW", + "RCR", + "TTT" + ], + "result": { + "count": 1, + "id": "thaumicenergistics:essentia_cell_4k" + } +} \ No newline at end of file diff --git a/src/main/resources/data/thaumicenergistics/recipe/essentia_cell_4k_shapeless.json b/src/main/resources/data/thaumicenergistics/recipe/essentia_cell_4k_shapeless.json new file mode 100644 index 0000000..a67a792 --- /dev/null +++ b/src/main/resources/data/thaumicenergistics/recipe/essentia_cell_4k_shapeless.json @@ -0,0 +1,12 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + { "item": "thaumicenergistics:storage_casing" }, + { "item": "thaumicenergistics:storage_component_4k" } + ], + "result": { + "count": 1, + "id": "thaumicenergistics:essentia_cell_4k" + } +} \ No newline at end of file diff --git a/src/main/resources/data/thaumicenergistics/recipe/essentia_cell_64k.json b/src/main/resources/data/thaumicenergistics/recipe/essentia_cell_64k.json new file mode 100644 index 0000000..9a36041 --- /dev/null +++ b/src/main/resources/data/thaumicenergistics/recipe/essentia_cell_64k.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "key": { + "W": { "tag": "thaumicenergistics:essentia_cell_glass" }, + "R": { "item": "minecraft:redstone" }, + "C": { "item": "thaumicenergistics:storage_component_64k" }, + "T": { "item": "thaumcraft:thaumium_ingot" } + }, + "pattern": [ + "WRW", + "RCR", + "TTT" + ], + "result": { + "count": 1, + "id": "thaumicenergistics:essentia_cell_64k" + } +} \ No newline at end of file diff --git a/src/main/resources/data/thaumicenergistics/recipe/essentia_cell_64k_shapeless.json b/src/main/resources/data/thaumicenergistics/recipe/essentia_cell_64k_shapeless.json new file mode 100644 index 0000000..c1916e5 --- /dev/null +++ b/src/main/resources/data/thaumicenergistics/recipe/essentia_cell_64k_shapeless.json @@ -0,0 +1,12 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + { "item": "thaumicenergistics:storage_casing" }, + { "item": "thaumicenergistics:storage_component_64k" } + ], + "result": { + "count": 1, + "id": "thaumicenergistics:essentia_cell_64k" + } +} \ No newline at end of file diff --git a/src/main/resources/data/thaumicenergistics/recipe/essentia_cell_workbench_shapeless.json b/src/main/resources/data/thaumicenergistics/recipe/essentia_cell_workbench_shapeless.json new file mode 100644 index 0000000..0039246 --- /dev/null +++ b/src/main/resources/data/thaumicenergistics/recipe/essentia_cell_workbench_shapeless.json @@ -0,0 +1,16 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + { + "item": "thaumicenergistics:storage_component_1k" + }, + { + "item": "ae2:cell_workbench" + } + ], + "result": { + "count": 1, + "id": "thaumicenergistics:essentia_cell_workbench" + } +} \ No newline at end of file diff --git a/src/main/resources/data/thaumicenergistics/recipe/storage_casing.json b/src/main/resources/data/thaumicenergistics/recipe/storage_casing.json new file mode 100644 index 0000000..1968514 --- /dev/null +++ b/src/main/resources/data/thaumicenergistics/recipe/storage_casing.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "key": { + "W": { "tag": "thaumicenergistics:essentia_cell_glass" }, + "R": { "item": "minecraft:redstone" }, + "T": { "item": "thaumcraft:thaumium_ingot" } + }, + "pattern": [ + "WRW", + "R R", + "TTT" + ], + "result": { + "count": 1, + "id": "thaumicenergistics:storage_casing" + } +} \ No newline at end of file diff --git a/src/main/resources/data/thaumicenergistics/recipe/wireless_essentia_terminal_shapeless.json b/src/main/resources/data/thaumicenergistics/recipe/wireless_essentia_terminal_shapeless.json new file mode 100644 index 0000000..01a8c15 --- /dev/null +++ b/src/main/resources/data/thaumicenergistics/recipe/wireless_essentia_terminal_shapeless.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + { + "item": "ae2:wireless_receiver" + }, + { + "item": "ae2:dense_energy_cell" + }, + { + "item": "thaumicenergistics:essentia_terminal" + } + ], + "result": { + "count": 1, + "id": "thaumicenergistics:wireless_essentia_terminal" + } +} \ No newline at end of file diff --git a/src/main/resources/data/thaumicenergistics/tags/item/essentia_cell_glass.json b/src/main/resources/data/thaumicenergistics/tags/item/essentia_cell_glass.json new file mode 100644 index 0000000..64d659a --- /dev/null +++ b/src/main/resources/data/thaumicenergistics/tags/item/essentia_cell_glass.json @@ -0,0 +1,6 @@ +{ + "values": [ + "ae2:quartz_glass", + "thaumcraft:warded_glass" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/thaumicenergistics/tags/item/wisp_essences.json b/src/main/resources/data/thaumicenergistics/tags/item/wisp_essences.json new file mode 100644 index 0000000..91ba1a6 --- /dev/null +++ b/src/main/resources/data/thaumicenergistics/tags/item/wisp_essences.json @@ -0,0 +1,53 @@ +{ +"values": [ +"thaumcraft:wisp_essence", +"thaumcraft:wisp_essence_aer", +"thaumcraft:wisp_essence_alienis", +"thaumcraft:wisp_essence_aqua", +"thaumcraft:wisp_essence_arbor", +"thaumcraft:wisp_essence_auram", +"thaumcraft:wisp_essence_bestia", +"thaumcraft:wisp_essence_cognitio", +"thaumcraft:wisp_essence_corpus", +"thaumcraft:wisp_essence_exanimis", +"thaumcraft:wisp_essence_fabrico", +"thaumcraft:wisp_essence_fames", +"thaumcraft:wisp_essence_gelum", +"thaumcraft:wisp_essence_herba", +"thaumcraft:wisp_essence_humanus", +"thaumcraft:wisp_essence_ignis", +"thaumcraft:wisp_essence_instrumentum", +"thaumcraft:wisp_essence_iter", +"thaumcraft:wisp_essence_limus", +"thaumcraft:wisp_essence_lucrum", +"thaumcraft:wisp_essence_lux", +"thaumcraft:wisp_essence_machina", +"thaumcraft:wisp_essence_messis", +"thaumcraft:wisp_essence_metallum", +"thaumcraft:wisp_essence_meto", +"thaumcraft:wisp_essence_mortuus", +"thaumcraft:wisp_essence_motus", +"thaumcraft:wisp_essence_ordo", +"thaumcraft:wisp_essence_pannus", +"thaumcraft:wisp_essence_perditio", +"thaumcraft:wisp_essence_perfodio", +"thaumcraft:wisp_essence_permutatio", +"thaumcraft:wisp_essence_potentia", +"thaumcraft:wisp_essence_praecantatio", +"thaumcraft:wisp_essence_sano", +"thaumcraft:wisp_essence_sensus", +"thaumcraft:wisp_essence_spiritus", +"thaumcraft:wisp_essence_telum", +"thaumcraft:wisp_essence_tempestas", +"thaumcraft:wisp_essence_tenebrae", +"thaumcraft:wisp_essence_terra", +"thaumcraft:wisp_essence_tutamen", +"thaumcraft:wisp_essence_vacuos", +"thaumcraft:wisp_essence_venenum", +"thaumcraft:wisp_essence_victus", +"thaumcraft:wisp_essence_vinculum", +"thaumcraft:wisp_essence_vitium", +"thaumcraft:wisp_essence_vitreus", +"thaumcraft:wisp_essence_volatus" +] +} \ No newline at end of file diff --git a/src/main/resources/thaumicenergistics.mixins.json b/src/main/resources/thaumicenergistics.mixins.json new file mode 100644 index 0000000..543151e --- /dev/null +++ b/src/main/resources/thaumicenergistics.mixins.json @@ -0,0 +1,18 @@ +{ + "required": false, + "package": "thaumicenergistics.mixins", + "compatibilityLevel": "JAVA_21", + "refmap": "thaumicenergistics.refmap.json", + "mixins": [ + "ae2.MixinCraftingTreeProcess", + "ae2.MixinAbstractTerminalPart", + "ae2.MixinConfigMenuInventory", + "tc.MixinAspect", + "tc.MixinVisRelayBlock" + ], + "client": [ + "tc.ResearchPageIndexMixin", + "tc.MixinThaumonomiconScreen" + ], + "server": [] +} \ No newline at end of file