diff --git a/build.gradle b/build.gradle index a42d853c..d21d62bd 100644 --- a/build.gradle +++ b/build.gradle @@ -194,6 +194,8 @@ dependencies { runtimeOnly "curse.maven:applied-flux-965012:6649565" // 应用通量附属 runtimeOnly "curse.maven:glodium-957920:5821676" // ae flux 前置 runtimeOnly "maven.modrinth:guideme:21.1.15" // guideme + compileOnly "maven.modrinth:ae2-lightning-tech:${ae2lt_version}" + runtimeOnly "maven.modrinth:ae2-lightning-tech:${ae2lt_version}" // 饰品栏支持 compileOnly "top.theillusivec4.curios:curios-neoforge:${curios_version}+${minecraft_version}:api" diff --git a/gradle.properties b/gradle.properties index cfda0de4..673be7d5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -35,6 +35,7 @@ mod_description=A mod provided some utilities. ## Mod Compat mekanism_version = 1.21.1-10.7.18.84 ae_version = 19.2.17 +ae2lt_version = 1.1.4 emi_version = 1.1.20+1.21.1 jei_version = 19.27.0.340 curios_version = 9.5.1 diff --git a/src/generated/resources/assets/beyonddimensions/blockstates/lightning_pathway.json b/src/generated/resources/assets/beyonddimensions/blockstates/lightning_pathway.json new file mode 100644 index 00000000..27a20fe6 --- /dev/null +++ b/src/generated/resources/assets/beyonddimensions/blockstates/lightning_pathway.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "beyonddimensions:block/lightning_pathway" + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/beyonddimensions/models/block/lightning_pathway.json b/src/generated/resources/assets/beyonddimensions/models/block/lightning_pathway.json new file mode 100644 index 00000000..7f512c6e --- /dev/null +++ b/src/generated/resources/assets/beyonddimensions/models/block/lightning_pathway.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "beyonddimensions:block/lightning_pathway" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/beyonddimensions/models/item/lightning_pathway.json b/src/generated/resources/assets/beyonddimensions/models/item/lightning_pathway.json new file mode 100644 index 00000000..e3a96d48 --- /dev/null +++ b/src/generated/resources/assets/beyonddimensions/models/item/lightning_pathway.json @@ -0,0 +1,3 @@ +{ + "parent": "beyonddimensions:block/lightning_pathway" +} \ No newline at end of file diff --git a/src/generated/resources/data/beyonddimensions/advancement/recipes/misc/lightning_pathway.json b/src/generated/resources/data/beyonddimensions/advancement/recipes/misc/lightning_pathway.json new file mode 100644 index 00000000..98b5f37b --- /dev/null +++ b/src/generated/resources/data/beyonddimensions/advancement/recipes/misc/lightning_pathway.json @@ -0,0 +1,38 @@ +{ + "neoforge:conditions": [ + { + "type": "neoforge:mod_loaded", + "modid": "ae2lt" + } + ], + "parent": "minecraft:recipes/root", + "criteria": { + "has_the_recipe": { + "conditions": { + "recipe": "beyonddimensions:lightning_pathway" + }, + "trigger": "minecraft:recipe_unlocked" + }, + "unlock_lightning_pathway": { + "conditions": { + "items": [ + { + "items": "beyonddimensions:space_time_bar" + } + ] + }, + "trigger": "minecraft:inventory_changed" + } + }, + "requirements": [ + [ + "has_the_recipe", + "unlock_lightning_pathway" + ] + ], + "rewards": { + "recipes": [ + "beyonddimensions:lightning_pathway" + ] + } +} \ No newline at end of file diff --git a/src/generated/resources/data/beyonddimensions/loot_table/blocks/lightning_pathway.json b/src/generated/resources/data/beyonddimensions/loot_table/blocks/lightning_pathway.json new file mode 100644 index 00000000..c45f6fb0 --- /dev/null +++ b/src/generated/resources/data/beyonddimensions/loot_table/blocks/lightning_pathway.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "beyonddimensions:lightning_pathway" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "beyonddimensions:blocks/lightning_pathway" +} \ No newline at end of file diff --git a/src/generated/resources/data/beyonddimensions/recipe/lightning_pathway.json b/src/generated/resources/data/beyonddimensions/recipe/lightning_pathway.json new file mode 100644 index 00000000..a569feaf --- /dev/null +++ b/src/generated/resources/data/beyonddimensions/recipe/lightning_pathway.json @@ -0,0 +1,33 @@ +{ + "neoforge:conditions": [ + { + "type": "neoforge:mod_loaded", + "modid": "ae2lt" + } + ], + "type": "minecraft:crafting_shaped", + "category": "misc", + "key": { + "A": { + "item": "beyonddimensions:space_time_bar" + }, + "B": { + "item": "beyonddimensions:space_time_stable_frame" + }, + "C": { + "item": "minecraft:lightning_rod" + }, + "D": { + "item": "minecraft:ender_eye" + } + }, + "pattern": [ + "ABA", + "CDC", + "ABA" + ], + "result": { + "count": 1, + "id": "beyonddimensions:lightning_pathway" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/block/mineable/pickaxe.json b/src/generated/resources/data/minecraft/tags/block/mineable/pickaxe.json index c4a4bb08..20d48e6a 100644 --- a/src/generated/resources/data/minecraft/tags/block/mineable/pickaxe.json +++ b/src/generated/resources/data/minecraft/tags/block/mineable/pickaxe.json @@ -12,7 +12,7 @@ "beyonddimensions:net_smoker_block", "beyonddimensions:dimensional_connect_block", { - "id": "beyonddimensions:ars_source_pathway", + "id": "beyonddimensions:rs_net_pathway", "required": false }, { @@ -26,6 +26,10 @@ { "id": "beyonddimensions:rs_net_pathway", "required": false + }, + { + "id": "beyonddimensions:lightning_pathway", + "required": false } ] } \ No newline at end of file diff --git a/src/main/java/com/wintercogs/beyonddimensions/api/ids/BDBlockIds.java b/src/main/java/com/wintercogs/beyonddimensions/api/ids/BDBlockIds.java index d8102f08..00af5057 100644 --- a/src/main/java/com/wintercogs/beyonddimensions/api/ids/BDBlockIds.java +++ b/src/main/java/com/wintercogs/beyonddimensions/api/ids/BDBlockIds.java @@ -20,6 +20,7 @@ private BDBlockIds() // 模块方块 public static final String ARS_SOURCE_PATHWAY = "ars_source_pathway"; + public static final String LIGHTNING_PATHWAY = "lightning_pathway"; public static final String MANA_POOL_PATHWAY = "mana_pool_pathway"; public static final String SCHEMATICANNON_PATHWAY = "schematicannon_pathway"; public static final String RS_NET_PATHWAY = "rs_net_pathway"; diff --git a/src/main/java/com/wintercogs/beyonddimensions/integration/OtherModIds.java b/src/main/java/com/wintercogs/beyonddimensions/integration/OtherModIds.java index 3bc12f63..5a7f17cd 100644 --- a/src/main/java/com/wintercogs/beyonddimensions/integration/OtherModIds.java +++ b/src/main/java/com/wintercogs/beyonddimensions/integration/OtherModIds.java @@ -4,6 +4,7 @@ public final class OtherModIds { public static final String MEKANISM = "mekanism"; public static final String AE2 = "ae2"; + public static final String AE2_LIGHTNING_TECH = "ae2lt"; public static final String EMI = "emi"; public static final String JEI = "jei"; public static final String POLYMORPH = "polymorph"; diff --git a/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/AE2LTModule.java b/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/AE2LTModule.java new file mode 100644 index 00000000..3164ce31 --- /dev/null +++ b/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/AE2LTModule.java @@ -0,0 +1,96 @@ +package com.wintercogs.beyonddimensions.integration.module.ae2lt; + +import com.moakiee.ae2lt.api.AE2LTCapabilities; +import com.wintercogs.beyonddimensions.api.capability.helper.CapabilityHelper; +import com.wintercogs.beyonddimensions.api.capability.helper.wrapper.StackHandlerWrapperHelper; +import com.wintercogs.beyonddimensions.api.storage.key.StackKeyRegistry; +import com.wintercogs.beyonddimensions.integration.BDIntegrationModule; +import com.wintercogs.beyonddimensions.integration.IIntegrationModule; +import com.wintercogs.beyonddimensions.integration.OtherModIds; +import com.wintercogs.beyonddimensions.integration.module.ae2lt.block.entity.LightningPathwayBlockEntity; +import com.wintercogs.beyonddimensions.integration.module.ae2lt.datagen.AE2LTModuleBlockLootTableProvider; +import com.wintercogs.beyonddimensions.integration.module.ae2lt.datagen.AE2LTModuleBlockStateProvider; +import com.wintercogs.beyonddimensions.integration.module.ae2lt.datagen.AE2LTModuleRecipeProvider; +import com.wintercogs.beyonddimensions.integration.module.ae2lt.init.AE2LTModuleBlockEntities; +import com.wintercogs.beyonddimensions.integration.module.ae2lt.init.AE2LTModuleBlocks; +import com.wintercogs.beyonddimensions.integration.module.ae2lt.storage.LightningHandlerWrapper; +import com.wintercogs.beyonddimensions.integration.module.ae2lt.storage.LightningStackKey; +import com.wintercogs.beyonddimensions.integration.module.ae2lt.storage.LightningStackTypedHandler; +import com.wintercogs.beyonddimensions.integration.module.ae2lt.storage.LightningUnifiedStorageHandler; +import net.minecraft.core.HolderLookup; +import net.minecraft.data.DataGenerator; +import net.minecraft.data.PackOutput; +import net.minecraft.data.loot.LootTableProvider; +import net.minecraft.tags.BlockTags; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; +import net.neoforged.neoforge.common.data.ExistingFileHelper; +import net.neoforged.neoforge.data.event.GatherDataEvent; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +@BDIntegrationModule(modId = OtherModIds.AE2_LIGHTNING_TECH) +public class AE2LTModule implements IIntegrationModule +{ + @Override + public String modId() + { + return OtherModIds.AE2_LIGHTNING_TECH; + } + + @Override + public void onBootstrap(IEventBus modBus, IEventBus gameBus) + { + AE2LTModuleBlocks.register(modBus); + AE2LTModuleBlockEntities.register(modBus); + modBus.addListener(LightningPathwayBlockEntity::registerCapability); + } + + @Override + public void onCommonSetup(FMLCommonSetupEvent event) + { + StackKeyRegistry.registerType(LightningStackKey.HIGH_VOLTAGE); + CapabilityHelper.BlockCapabilityMap.put(LightningStackKey.ID, AE2LTCapabilities.LIGHTNING_ENERGY_BLOCK); + CapabilityHelper.registerUSHandler(LightningStackKey.HIGH_VOLTAGE, LightningUnifiedStorageHandler::new); + CapabilityHelper.registerStackTypedHandler(LightningStackKey.HIGH_VOLTAGE, LightningStackTypedHandler::new); + StackHandlerWrapperHelper.stackWrappers.put(LightningStackKey.ID, LightningHandlerWrapper::new); + } + + @Override + public void onBlockCreativeTabCollect(CreativeModeTab.ItemDisplayParameters parameters, CreativeModeTab.Output output) + { + output.accept(AE2LTModuleBlocks.LIGHTNING_PATHWAY); + } + + @Override + public void onDatagen(GatherDataEvent event) + { + DataGenerator generator = event.getGenerator(); + PackOutput output = generator.getPackOutput(); + ExistingFileHelper files = event.getExistingFileHelper(); + CompletableFuture registries = event.getLookupProvider(); + generator.addProvider(event.includeServer(), new LootTableProvider(output, Collections.emptySet(), + List.of(new LootTableProvider.SubProviderEntry( + AE2LTModuleBlockLootTableProvider::new, LootContextParamSets.BLOCK)), registries) + { + @Override + public @NotNull String getName() + { + return "BeyondDimensions AE2LT Module LootTable Provider"; + } + }); + generator.addProvider(event.includeClient(), new AE2LTModuleBlockStateProvider(output, files)); + generator.addProvider(event.includeServer(), new AE2LTModuleRecipeProvider(output, registries)); + } + + @Override + public void onBlockTagDatagen(HolderLookup.Provider provider, BlockTagAppender appender) + { + appender.addOptional(BlockTags.MINEABLE_WITH_PICKAXE, AE2LTModuleBlocks.LIGHTNING_PATHWAY.getId()); + } +} diff --git a/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/block/LightningPathwayBlock.java b/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/block/LightningPathwayBlock.java new file mode 100644 index 00000000..ad565519 --- /dev/null +++ b/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/block/LightningPathwayBlock.java @@ -0,0 +1,23 @@ +package com.wintercogs.beyonddimensions.integration.module.ae2lt.block; + +import com.wintercogs.beyonddimensions.common.block.NetedBlock; +import com.wintercogs.beyonddimensions.integration.module.ae2lt.block.entity.LightningPathwayBlockEntity; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.EntityBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; + +public class LightningPathwayBlock extends NetedBlock implements EntityBlock +{ + public LightningPathwayBlock(Properties properties) + { + super(properties); + } + + @Override + public @Nullable BlockEntity newBlockEntity(BlockPos pos, BlockState state) + { + return new LightningPathwayBlockEntity(pos, state); + } +} diff --git a/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/block/entity/LightningPathwayBlockEntity.java b/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/block/entity/LightningPathwayBlockEntity.java new file mode 100644 index 00000000..0d299ae3 --- /dev/null +++ b/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/block/entity/LightningPathwayBlockEntity.java @@ -0,0 +1,28 @@ +package com.wintercogs.beyonddimensions.integration.module.ae2lt.block.entity; + +import com.moakiee.ae2lt.api.AE2LTCapabilities; +import com.wintercogs.beyonddimensions.common.block.entity.NetedBlockEntity; +import com.wintercogs.beyonddimensions.integration.module.ae2lt.init.AE2LTModuleBlockEntities; +import com.wintercogs.beyonddimensions.integration.module.ae2lt.storage.LightningUnifiedStorageHandler; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.state.BlockState; +import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent; + +public class LightningPathwayBlockEntity extends NetedBlockEntity +{ + public LightningPathwayBlockEntity(BlockPos pos, BlockState state) + { + super(AE2LTModuleBlockEntities.LIGHTNING_PATHWAY_BLOCK_ENTITY.get(), pos, state); + } + + public static void registerCapability(RegisterCapabilitiesEvent event) + { + event.registerBlockEntity( + AE2LTCapabilities.LIGHTNING_ENERGY_BLOCK, + AE2LTModuleBlockEntities.LIGHTNING_PATHWAY_BLOCK_ENTITY.get(), + (be, side) -> be.getNet() == null + ? null + : new LightningUnifiedStorageHandler(be.getNet().getUnifiedStorage()) + ); + } +} diff --git a/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/datagen/AE2LTModuleBlockLootTableProvider.java b/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/datagen/AE2LTModuleBlockLootTableProvider.java new file mode 100644 index 00000000..3ed6ced3 --- /dev/null +++ b/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/datagen/AE2LTModuleBlockLootTableProvider.java @@ -0,0 +1,28 @@ +package com.wintercogs.beyonddimensions.integration.module.ae2lt.datagen; + +import com.wintercogs.beyonddimensions.datagen.util.BDBlockLootSubProvider; +import com.wintercogs.beyonddimensions.integration.module.ae2lt.init.AE2LTModuleBlocks; +import net.minecraft.core.Holder; +import net.minecraft.core.HolderLookup; +import net.minecraft.world.level.block.Block; +import org.jetbrains.annotations.NotNull; + +public class AE2LTModuleBlockLootTableProvider extends BDBlockLootSubProvider +{ + public AE2LTModuleBlockLootTableProvider(HolderLookup.Provider registries) + { + super(registries); + } + + @Override + protected void generate() + { + dropSelf(AE2LTModuleBlocks.LIGHTNING_PATHWAY.get()); + } + + @Override + protected @NotNull Iterable getKnownBlocks() + { + return AE2LTModuleBlocks.BLOCKS.getEntries().stream().map(Holder::value)::iterator; + } +} diff --git a/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/datagen/AE2LTModuleBlockStateProvider.java b/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/datagen/AE2LTModuleBlockStateProvider.java new file mode 100644 index 00000000..e3e721cf --- /dev/null +++ b/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/datagen/AE2LTModuleBlockStateProvider.java @@ -0,0 +1,27 @@ +package com.wintercogs.beyonddimensions.integration.module.ae2lt.datagen; + +import com.wintercogs.beyonddimensions.datagen.util.BDBlockStateProvider; +import com.wintercogs.beyonddimensions.integration.module.ae2lt.init.AE2LTModuleBlocks; +import net.minecraft.data.PackOutput; +import net.neoforged.neoforge.common.data.ExistingFileHelper; +import org.jetbrains.annotations.NotNull; + +public class AE2LTModuleBlockStateProvider extends BDBlockStateProvider +{ + public AE2LTModuleBlockStateProvider(PackOutput output, ExistingFileHelper helper) + { + super(output, helper); + } + + @Override + public @NotNull String getName() + { + return "BeyondDimensions AE2LT Module BlockState Provider"; + } + + @Override + protected void registerStatesAndModels() + { + blockWithItem(AE2LTModuleBlocks.LIGHTNING_PATHWAY); + } +} diff --git a/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/datagen/AE2LTModuleRecipeProvider.java b/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/datagen/AE2LTModuleRecipeProvider.java new file mode 100644 index 00000000..39d149b5 --- /dev/null +++ b/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/datagen/AE2LTModuleRecipeProvider.java @@ -0,0 +1,46 @@ +package com.wintercogs.beyonddimensions.integration.module.ae2lt.datagen; + +import com.wintercogs.beyonddimensions.common.init.BDItems; +import com.wintercogs.beyonddimensions.datagen.util.BDRecipeProvider; +import com.wintercogs.beyonddimensions.integration.OtherModIds; +import com.wintercogs.beyonddimensions.integration.module.ae2lt.init.AE2LTModuleBlocks; +import net.minecraft.core.HolderLookup; +import net.minecraft.data.PackOutput; +import net.minecraft.data.recipes.RecipeCategory; +import net.minecraft.data.recipes.RecipeOutput; +import net.minecraft.data.recipes.ShapedRecipeBuilder; +import net.minecraft.world.item.Items; +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.CompletableFuture; + +public class AE2LTModuleRecipeProvider extends BDRecipeProvider +{ + public AE2LTModuleRecipeProvider(PackOutput output, CompletableFuture registries) + { + super(output, registries); + } + + @Override + public @NotNull String getName() + { + return "BeyondDimensions AE2LT Module Recipe Provider"; + } + + @Override + protected void buildRecipes(RecipeOutput recipeOutput, HolderLookup.@NotNull Provider provider) + { + RecipeOutput compatOutput = recipeOutput.withConditions(modLoaded(OtherModIds.AE2_LIGHTNING_TECH)); + super.buildRecipes(compatOutput, provider); + ShapedRecipeBuilder.shaped(RecipeCategory.MISC, AE2LTModuleBlocks.LIGHTNING_PATHWAY.get()) + .pattern("ABA") + .pattern("CDC") + .pattern("ABA") + .define('A', BDItems.SPACE_TIME_BAR.get()) + .define('B', BDItems.SPACE_TIME_STABLE_FRAME.get()) + .define('C', Items.LIGHTNING_ROD) + .define('D', Items.ENDER_EYE) + .unlockedBy("unlock_lightning_pathway", has(BDItems.SPACE_TIME_BAR.get())) + .save(compatOutput); + } +} diff --git a/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/init/AE2LTModuleBlockEntities.java b/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/init/AE2LTModuleBlockEntities.java new file mode 100644 index 00000000..2f1a6cd8 --- /dev/null +++ b/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/init/AE2LTModuleBlockEntities.java @@ -0,0 +1,28 @@ +package com.wintercogs.beyonddimensions.integration.module.ae2lt.init; + +import com.wintercogs.beyonddimensions.api.ids.BDConstants; +import com.wintercogs.beyonddimensions.integration.module.ae2lt.block.entity.LightningPathwayBlockEntity; +import net.minecraft.core.registries.Registries; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.registries.DeferredRegister; + +import java.util.function.Supplier; + +public class AE2LTModuleBlockEntities +{ + public static final DeferredRegister> BLOCK_ENTITY_TYPES = + DeferredRegister.create(Registries.BLOCK_ENTITY_TYPE, BDConstants.MODID); + + public static final Supplier> LIGHTNING_PATHWAY_BLOCK_ENTITY = + BLOCK_ENTITY_TYPES.register("lightning_pathway_block_entity", () -> + BlockEntityType.Builder.of( + LightningPathwayBlockEntity::new, + AE2LTModuleBlocks.LIGHTNING_PATHWAY.get() + ).build(null)); + + public static void register(IEventBus eventBus) + { + BLOCK_ENTITY_TYPES.register(eventBus); + } +} diff --git a/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/init/AE2LTModuleBlocks.java b/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/init/AE2LTModuleBlocks.java new file mode 100644 index 00000000..efc8dd0f --- /dev/null +++ b/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/init/AE2LTModuleBlocks.java @@ -0,0 +1,37 @@ +package com.wintercogs.beyonddimensions.integration.module.ae2lt.init; + +import com.wintercogs.beyonddimensions.api.ids.BDBlockIds; +import com.wintercogs.beyonddimensions.api.ids.BDConstants; +import com.wintercogs.beyonddimensions.common.init.BDItems; +import com.wintercogs.beyonddimensions.integration.module.ae2lt.block.LightningPathwayBlock; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.registries.DeferredBlock; +import net.neoforged.neoforge.registries.DeferredRegister; + +import java.util.function.Supplier; + +public class AE2LTModuleBlocks +{ + public static final DeferredRegister.Blocks BLOCKS = DeferredRegister.createBlocks(BDConstants.MODID); + + public static final DeferredBlock LIGHTNING_PATHWAY = registerBlock( + BDBlockIds.LIGHTNING_PATHWAY, + () -> new LightningPathwayBlock(BlockBehaviour.Properties.of().strength(2f)) + ); + + private static DeferredBlock registerBlock(String name, Supplier block) + { + DeferredBlock result = BLOCKS.register(name, block); + BDItems.ITEMS.register(name, () -> new BlockItem(result.get(), new Item.Properties())); + return result; + } + + public static void register(IEventBus eventBus) + { + BLOCKS.register(eventBus); + } +} diff --git a/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/storage/LightningHandlerWrapper.java b/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/storage/LightningHandlerWrapper.java new file mode 100644 index 00000000..6fcd97b9 --- /dev/null +++ b/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/storage/LightningHandlerWrapper.java @@ -0,0 +1,84 @@ +package com.wintercogs.beyonddimensions.integration.module.ae2lt.storage; + +import com.moakiee.ae2lt.api.lightning.ILightningEnergyHandler; +import com.moakiee.ae2lt.api.lightning.LightningTier; +import com.wintercogs.beyonddimensions.api.capability.helper.wrapper.IStackHandlerWrapper; +import net.minecraft.resources.ResourceLocation; + +public final class LightningHandlerWrapper implements IStackHandlerWrapper +{ + private final ILightningEnergyHandler handler; + + public LightningHandlerWrapper(Object handler) + { + this.handler = (ILightningEnergyHandler) handler; + } + + private static LightningTier tier(int slot) + { + return switch (slot) + { + case 0 -> LightningTier.HIGH_VOLTAGE; + case 1 -> LightningTier.EXTREME_HIGH_VOLTAGE; + default -> throw new IndexOutOfBoundsException("Invalid lightning slot: " + slot); + }; + } + + @Override + public ResourceLocation getTypeId() + { + return LightningStackKey.ID; + } + + @Override + public int getSlots() + { + return 2; + } + + @Override + public LightningType getStackInSlot(int slot) + { + LightningTier tier = tier(slot); + return new LightningType(tier, handler.getStored(tier)); + } + + @Override + public long getCapacity(int slot) + { + return handler.getCapacity(tier(slot)); + } + + @Override + public boolean isStackValid(int slot, LightningType stack) + { + return stack.tier() == tier(slot) && handler.canInsert(stack.tier()); + } + + @Override + public long insert(int slot, LightningType stack, boolean simulate) + { + long amount = Math.max(0, stack.getStackCount()); + if (stack.tier() != tier(slot)) return amount; + return amount - handler.insert(stack.tier(), amount, simulate); + } + + @Override + public long insert(LightningType stack, boolean simulate) + { + long amount = Math.max(0, stack.getStackCount()); + return amount - handler.insert(stack.tier(), amount, simulate); + } + + @Override + public long extract(int slot, long amount, boolean simulate) + { + return handler.extract(tier(slot), Math.max(0, amount), simulate); + } + + @Override + public long extract(LightningType stack, boolean simulate) + { + return handler.extract(stack.tier(), Math.max(0, stack.getStackCount()), simulate); + } +} diff --git a/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/storage/LightningStackKey.java b/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/storage/LightningStackKey.java new file mode 100644 index 00000000..f79d5fc6 --- /dev/null +++ b/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/storage/LightningStackKey.java @@ -0,0 +1,171 @@ +package com.wintercogs.beyonddimensions.integration.module.ae2lt.storage; + +import com.moakiee.ae2lt.api.lightning.LightningTier; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import com.wintercogs.beyonddimensions.api.ids.BDConstants; +import com.wintercogs.beyonddimensions.api.storage.key.IStackKey; +import com.wintercogs.beyonddimensions.api.storage.key.IStackRender; +import com.wintercogs.beyonddimensions.api.storage.key.KeyAmount; +import com.wintercogs.beyonddimensions.api.storage.key.impl.LongStackKey; +import com.wintercogs.beyonddimensions.integration.OtherModIds; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.component.DataComponentPatch; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagKey; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Objects; +import java.util.stream.Stream; + +public final class LightningStackKey extends LongStackKey +{ + public static final ResourceLocation ID = ResourceLocation.fromNamespaceAndPath( + BDConstants.MODID, "stack_type/lightning"); + public static final LightningStackKey HIGH_VOLTAGE = new LightningStackKey(LightningTier.HIGH_VOLTAGE); + public static final LightningStackKey EXTREME_HIGH_VOLTAGE = new LightningStackKey(LightningTier.EXTREME_HIGH_VOLTAGE); + public static final MapCodec TYPE_CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + LightningTier.CODEC.fieldOf("tier").forGetter(LightningStackKey::tier) + ).apply(instance, LightningStackKey::of)); + + private final LightningTier tier; + + private LightningStackKey(LightningTier tier) + { + this.tier = Objects.requireNonNull(tier); + this.stack = new LightningType(tier, 0); + } + + public static LightningStackKey of(LightningTier tier) + { + return tier == LightningTier.EXTREME_HIGH_VOLTAGE ? EXTREME_HIGH_VOLTAGE : HIGH_VOLTAGE; + } + + public LightningTier tier() + { + return tier; + } + + @Override + public ResourceLocation getTypeID() + { + return ID; + } + + @Override + public MapCodec codec() + { + return TYPE_CODEC; + } + + @Override + public @Nullable KeyAmount fromStackObject(Object stack) + { + return stack instanceof LightningType lightning + ? new KeyAmount(of(lightning.tier()), lightning.getStackCount()) + : null; + } + + @Override + public @Nullable LightningStackKey fromSourceObject(Object key, DataComponentPatch ignored) + { + if (key instanceof LightningType lightning) return of(lightning.tier()); + if (key instanceof LightningTier lightningTier) return of(lightningTier); + return null; + } + + @Override + public String getModId() + { + return OtherModIds.AE2_LIGHTNING_TECH; + } + + @Override + public LightningStackKey getEmpty() + { + return HIGH_VOLTAGE; + } + + @Override + public @NotNull LightningType getSource() + { + return stack; + } + + @Override + public LightningType getEmptyStack() + { + return new LightningType(tier, 0); + } + + @Override + public boolean hasTag(TagKey tagKey) + { + return false; + } + + @Override + public Stream> getTags() + { + return Stream.empty(); + } + + @Override + public boolean isSame(IStackKey other) + { + return other instanceof LightningStackKey lightning && lightning.tier == tier; + } + + @Override + public boolean isSameTypeSameComponents(IStackKey other) + { + return isSame(other); + } + + @Override + public boolean equals(Object other) + { + return other instanceof LightningStackKey lightning && lightning.tier == tier; + } + + @Override + public int hashCode() + { + return 31 * ID.hashCode() + tier.hashCode(); + } + + @Override + public void serialize(RegistryFriendlyByteBuf buf) + { + LightningTier.STREAM_CODEC.encode(buf, tier); + } + + @Override + public @NotNull LightningStackKey deserialize(RegistryFriendlyByteBuf buf) + { + return of(LightningTier.STREAM_CODEC.decode(buf)); + } + + @Override + public @NotNull CompoundTag serializeNBT(HolderLookup.Provider access) + { + CompoundTag tag = new CompoundTag(); + tag.putString("tier", tier.getSerializedName()); + return tag; + } + + @Override + public @NotNull LightningStackKey deserializeNBT(CompoundTag nbt, HolderLookup.Provider access) + { + return of(LightningTier.fromSerializedName(nbt.getString("tier"))); + } + + @Override + public @NotNull IStackRender getRender() + { + return LightningStackKeyRender.INSTANCE; + } +} diff --git a/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/storage/LightningStackKeyRender.java b/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/storage/LightningStackKeyRender.java new file mode 100644 index 00000000..eb6440c5 --- /dev/null +++ b/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/storage/LightningStackKeyRender.java @@ -0,0 +1,105 @@ +package com.wintercogs.beyonddimensions.integration.module.ae2lt.storage; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.wintercogs.beyonddimensions.api.storage.key.IStackKey; +import com.wintercogs.beyonddimensions.api.storage.key.IStackRender; +import com.wintercogs.beyonddimensions.util.IngredientRenderer; +import com.wintercogs.beyonddimensions.util.StringFormat; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite; +import net.minecraft.network.chat.Component; +import net.minecraft.world.inventory.InventoryMenu; +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 net.minecraft.world.level.material.Fluids; +import net.neoforged.neoforge.client.ClientTooltipFlag; +import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.Optional; + +public final class LightningStackKeyRender implements IStackRender +{ + public static final LightningStackKeyRender INSTANCE = new LightningStackKeyRender(); + + private LightningStackKeyRender() + { + } + + @Override + public void render(GuiGraphics gui, IStackKey key, int x, int y) + { + var texture = IClientFluidTypeExtensions.of(Fluids.WATER).getStillTexture(); + var sprite = texture == null ? null + : Minecraft.getInstance().getTextureAtlas(InventoryMenu.BLOCK_ATLAS).apply(texture); + if (sprite != null && sprite.atlasLocation() != MissingTextureAtlasSprite.getLocation()) + { + int tint = key == LightningStackKey.EXTREME_HIGH_VOLTAGE ? 0xB050FF : 0x58DFFF; + IngredientRenderer.drawTiledSprite(gui, 16, 16, tint, 16, sprite, x, y); + } + } + + @Override + public void renderAmount(GuiGraphics gui, long amount, int x, int y) + { + String text = getCountText(amount); + if (text.isEmpty()) return; + float scale = 0.666f; + var pose = gui.pose(); + pose.pushPose(); + pose.translate(0, 0, 200); + pose.scale(scale, scale, scale); + RenderSystem.disableBlend(); + int width = Minecraft.getInstance().font.width(text); + int renderX = (int) ((x - 1 + 18.0f - width * scale) / scale); + int renderY = (int) ((y - 1 + 16.0f - 5.0f * scale) / scale); + gui.drawString(Minecraft.getInstance().font, text, renderX, renderY, 0xFFFFFF); + pose.popPose(); + } + + @Override + public String getCountText(long count) + { + return count < 0 ? "" : StringFormat.formatCount(count); + } + + @Override + public Component getDisplayName(IStackKey key) + { + return key instanceof LightningStackKey lightning + ? lightning.getRenderStack().getName() + : LightningStackKey.HIGH_VOLTAGE.getRenderStack().getName(); + } + + @Override + public List getTooltipLines(IStackKey key, long amount, Item.TooltipContext context, + @Nullable net.minecraft.world.entity.player.Player player, + TooltipFlag flag) + { + return List.of(getDisplayName(key), + Component.translatable("istack.beyonddimensions.storage_num.long_type", amount)); + } + + @Override + public Optional getTooltipImage(IStackKey key) + { + return Optional.empty(); + } + + @Override + public void renderTooltip(GuiGraphics gui, Font font, IStackKey key, long amount, int mouseX, int mouseY) + { + var minecraft = Minecraft.getInstance(); + var context = minecraft.level == null ? Item.TooltipContext.EMPTY : Item.TooltipContext.of(minecraft.level); + gui.renderTooltip(minecraft.font, + getTooltipLines(key, amount, context, minecraft.player, + ClientTooltipFlag.of(minecraft.options.advancedItemTooltips + ? TooltipFlag.Default.ADVANCED : TooltipFlag.Default.NORMAL)), + getTooltipImage(key), ItemStack.EMPTY, mouseX, mouseY); + } +} diff --git a/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/storage/LightningStackTypedHandler.java b/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/storage/LightningStackTypedHandler.java new file mode 100644 index 00000000..065527f0 --- /dev/null +++ b/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/storage/LightningStackTypedHandler.java @@ -0,0 +1,56 @@ +package com.wintercogs.beyonddimensions.integration.module.ae2lt.storage; + +import com.moakiee.ae2lt.api.lightning.ILightningEnergyHandler; +import com.moakiee.ae2lt.api.lightning.LightningTier; +import com.wintercogs.beyonddimensions.api.storage.handler.impl.StackHandler; +import com.wintercogs.beyonddimensions.api.storage.key.impl.EmptyStackKey; + +public final class LightningStackTypedHandler implements ILightningEnergyHandler +{ + private final StackHandler storage; + + public LightningStackTypedHandler(StackHandler storage) + { + this.storage = storage; + } + + @Override + public long getStored(LightningTier tier) + { + return storage.getBucket(LightningStackKey.of(tier)).map(bucket -> { + long total = 0; + for (int i = 0; i < bucket.size(); i++) + { + long amount = storage.getStackBySlot(bucket.get(i)).amount(); + if (Long.MAX_VALUE - total < amount) return Long.MAX_VALUE; + total += amount; + } + return total; + }).orElse(0L); + } + + @Override + public long getCapacity(LightningTier tier) + { + int occupied = storage.getBucket(LightningStackKey.of(tier)).map(StackHandler.SlotBucket::size).orElse(0); + int empty = storage.getBucket(EmptyStackKey.INSTANCE).map(StackHandler.SlotBucket::size).orElse(0); + long slots = (long) occupied + empty; + if (slots == 0) return 0; + long perSlot = Math.min(LightningStackKey.of(tier).getVanillaMaxStackSize(), storage.getSlotCapacity(0)); + return perSlot > Long.MAX_VALUE / slots ? Long.MAX_VALUE : perSlot * slots; + } + + @Override + public long insert(LightningTier tier, long amount, boolean simulate) + { + long requested = Math.max(0, amount); + long remainder = storage.insert(LightningStackKey.of(tier), requested, simulate).amount(); + return requested - remainder; + } + + @Override + public long extract(LightningTier tier, long amount, boolean simulate) + { + return storage.extract(LightningStackKey.of(tier), Math.max(0, amount), simulate, false).amount(); + } +} diff --git a/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/storage/LightningType.java b/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/storage/LightningType.java new file mode 100644 index 00000000..5adfbf25 --- /dev/null +++ b/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/storage/LightningType.java @@ -0,0 +1,72 @@ +package com.wintercogs.beyonddimensions.integration.module.ae2lt.storage; + +import com.moakiee.ae2lt.api.lightning.LightningTier; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import com.wintercogs.beyonddimensions.api.longtype.LongType; +import net.minecraft.network.chat.Component; + +import java.util.Objects; + +public class LightningType extends LongType +{ + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + LightningTier.CODEC.fieldOf("tier").forGetter(LightningType::tier), + Codec.LONG.fieldOf("amount").forGetter(LightningType::getStackCount) + ).apply(instance, LightningType::new)); + + private final LightningTier tier; + + public LightningType(LightningTier tier, long amount) + { + this.tier = Objects.requireNonNull(tier); + this.stackCount = amount; + } + + public LightningTier tier() + { + return tier; + } + + @Override + public Component getName() + { + return Component.translatable("types.beyonddimensions.lightning." + tier.getSerializedName()); + } + + @Override + public LightningType getEmpty() + { + return new LightningType(tier, 0); + } + + @Override + public LightningType copy() + { + return new LightningType(tier, stackCount); + } + + @Override + public LightningType copyWithAmount(long amount) + { + return new LightningType(tier, amount); + } + + @Override + public boolean isSame(LongType other) + { + return other instanceof LightningType lightning && lightning.tier == tier; + } + + @Override + public boolean equals(Object other) + { + return other instanceof LightningType lightning && lightning.tier == tier; + } + + @Override + public int hashCode() + { + return tier.hashCode(); + } +} diff --git a/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/storage/LightningUnifiedStorageHandler.java b/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/storage/LightningUnifiedStorageHandler.java new file mode 100644 index 00000000..0a6a8c0e --- /dev/null +++ b/src/main/java/com/wintercogs/beyonddimensions/integration/module/ae2lt/storage/LightningUnifiedStorageHandler.java @@ -0,0 +1,41 @@ +package com.wintercogs.beyonddimensions.integration.module.ae2lt.storage; + +import com.moakiee.ae2lt.api.lightning.ILightningEnergyHandler; +import com.moakiee.ae2lt.api.lightning.LightningTier; +import com.wintercogs.beyonddimensions.api.dimensionnet.UnifiedStorage; + +public final class LightningUnifiedStorageHandler implements ILightningEnergyHandler +{ + private final UnifiedStorage storage; + + public LightningUnifiedStorageHandler(UnifiedStorage storage) + { + this.storage = storage; + } + + @Override + public long getStored(LightningTier tier) + { + return storage.getStackByKey(LightningStackKey.of(tier)).amount(); + } + + @Override + public long getCapacity(LightningTier tier) + { + return storage.getSlotCapacity(0); + } + + @Override + public long insert(LightningTier tier, long amount, boolean simulate) + { + long requested = Math.max(0, amount); + long remainder = storage.insert(LightningStackKey.of(tier), requested, simulate).amount(); + return requested - remainder; + } + + @Override + public long extract(LightningTier tier, long amount, boolean simulate) + { + return storage.extract(LightningStackKey.of(tier), Math.max(0, amount), simulate, false).amount(); + } +} diff --git a/src/main/resources/assets/beyonddimensions/lang/en_us.json b/src/main/resources/assets/beyonddimensions/lang/en_us.json index 8a503c0f..a21058fe 100644 --- a/src/main/resources/assets/beyonddimensions/lang/en_us.json +++ b/src/main/resources/assets/beyonddimensions/lang/en_us.json @@ -224,5 +224,8 @@ "msg.beyonddimensions.primary_net.switch.cleared": "Primary network cleared", "msg.beyonddimensions.primary_net.switch.none_available": "No available network to switch to", "msg.beyonddimensions.primary_net.switch.invalid_target": "That network is unavailable or you are no longer a member", - "msg.beyonddimensions.primary_net.switch.no_other": "No other primary network is available" + "msg.beyonddimensions.primary_net.switch.no_other": "No other primary network is available", + "block.beyonddimensions.lightning_pathway": "Dimensional Lightning Pathway", + "types.beyonddimensions.lightning.high_voltage": "High-Voltage Lightning", + "types.beyonddimensions.lightning.extreme_high_voltage": "Extreme High-Voltage Lightning" } diff --git a/src/main/resources/assets/beyonddimensions/lang/zh_cn.json b/src/main/resources/assets/beyonddimensions/lang/zh_cn.json index 208b6f55..72b4b197 100644 --- a/src/main/resources/assets/beyonddimensions/lang/zh_cn.json +++ b/src/main/resources/assets/beyonddimensions/lang/zh_cn.json @@ -224,5 +224,8 @@ "msg.beyonddimensions.primary_net.switch.cleared": "已切换为无主网络", "msg.beyonddimensions.primary_net.switch.none_available": "当前没有可切换的网络", "msg.beyonddimensions.primary_net.switch.invalid_target": "目标网络不可用,或你已经不再属于该网络", - "msg.beyonddimensions.primary_net.switch.no_other": "没有其他可切换的主网络" + "msg.beyonddimensions.primary_net.switch.no_other": "没有其他可切换的主网络", + "block.beyonddimensions.lightning_pathway": "维度闪电接口", + "types.beyonddimensions.lightning.high_voltage": "高压闪电", + "types.beyonddimensions.lightning.extreme_high_voltage": "超高压闪电" } diff --git a/src/main/resources/assets/beyonddimensions/textures/block/lightning_pathway.png b/src/main/resources/assets/beyonddimensions/textures/block/lightning_pathway.png new file mode 100644 index 00000000..6a1850b7 Binary files /dev/null and b/src/main/resources/assets/beyonddimensions/textures/block/lightning_pathway.png differ diff --git a/src/main/templates/META-INF/neoforge.mods.toml b/src/main/templates/META-INF/neoforge.mods.toml index 0d147843..6e4747cc 100644 --- a/src/main/templates/META-INF/neoforge.mods.toml +++ b/src/main/templates/META-INF/neoforge.mods.toml @@ -93,6 +93,13 @@ config="${mod_id}.mixins.json" ordering="AFTER" side="BOTH" +[[dependencies.${mod_id}]] + modId="ae2lt" + type="optional" + versionRange="[1.0.2,)" + ordering="AFTER" + side="BOTH" + # Features are specific properties of the game environment, that you may want to declare you require. This example declares # that your mod requires GL version 3.2 or higher. Other features will be added. They are side aware so declaring this won't # stop your mod loading on the server for example.