diff --git a/build.gradle b/build.gradle index 344b827..f9dfaf5 100644 --- a/build.gradle +++ b/build.gradle @@ -17,6 +17,9 @@ repositories { // See https://docs.gradle.org/current/userguide/declaring_repositories.html // for more information about repositories. } +loom { + accessWidenerPath = file("src/main/resources/name.accesswidener") +} fabricApi { configureDataGeneration() diff --git a/src/main/java/com/equilibrium/MITEequilibrium.java b/src/main/java/com/equilibrium/MITEequilibrium.java index f97baca..b48bd68 100644 --- a/src/main/java/com/equilibrium/MITEequilibrium.java +++ b/src/main/java/com/equilibrium/MITEequilibrium.java @@ -1,6 +1,7 @@ package com.equilibrium; -import com.equilibrium.block.ModBlocksTest; +import com.equilibrium.block.ModBlocks; + import com.equilibrium.item.Ingots; import com.equilibrium.item.ModItemGroup; import com.equilibrium.item.ModItems; @@ -9,6 +10,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static com.equilibrium.worldgen.ModOreGenerator.registerModOre; + public class MITEequilibrium implements ModInitializer { @@ -28,7 +31,7 @@ public void onInitialize() { //物品添加测试 ModItems.registerModItemTest(); //方块添加测试 - ModBlocksTest.registerModBlocks(); + ModBlocks.registerModBlocks(); //以下开始正式添加物品: @@ -38,7 +41,9 @@ public void onInitialize() { //添加锭 Ingots.registerModItemIngots(); + //注册矿物 + registerModOre(); diff --git a/src/main/java/com/equilibrium/MITEequilibriumDataGenerator.java b/src/main/java/com/equilibrium/MITEequilibriumDataGenerator.java index 8ff5933..91e10a0 100644 --- a/src/main/java/com/equilibrium/MITEequilibriumDataGenerator.java +++ b/src/main/java/com/equilibrium/MITEequilibriumDataGenerator.java @@ -1,11 +1,16 @@ package com.equilibrium; +import com.equilibrium.gen.ModRecipeGenerator; import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint; import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; +import net.minecraft.data.DataGenerator; public class MITEequilibriumDataGenerator implements DataGeneratorEntrypoint { @Override - public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) { + public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator){ + FabricDataGenerator.Pack pack=fabricDataGenerator.createPack(); + pack.addProvider(ModRecipeGenerator::new); } } diff --git a/src/main/java/com/equilibrium/block/ModBlocks.java b/src/main/java/com/equilibrium/block/ModBlocks.java new file mode 100644 index 0000000..f645058 --- /dev/null +++ b/src/main/java/com/equilibrium/block/ModBlocks.java @@ -0,0 +1,60 @@ +package com.equilibrium.block; + + +import net.minecraft.block.*; +import net.minecraft.block.piston.PistonBehavior; +import net.minecraft.item.BlockItem; +import net.minecraft.item.Item; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.sound.BlockSoundGroup; +import net.minecraft.util.Identifier; + +import static net.minecraft.block.Blocks.register; + +public class ModBlocks { + + public static final Block EXAMPLE_BLOCK = new Block(Block.Settings.create().strength(4.0f)); + //strength中第一个为硬度,第二个为爆炸抗性 + public static final Block UNDERWORLD_PORTAL = + new UnderworldPortalBlock( + AbstractBlock.Settings.create() + .noCollision() + .ticksRandomly() + .strength(-1.0F) + .sounds(BlockSoundGroup.GLASS) + .luminance(state -> 11) + .pistonBehavior(PistonBehavior.BLOCK) + ); + public static final Block OVERWORLD_PORTAL = + new UnderworldPortalBlock( + AbstractBlock.Settings.create() + .noCollision() + .ticksRandomly() + .strength(-1.0F) + .sounds(BlockSoundGroup.GLASS) + .luminance(state -> 11) + .pistonBehavior(PistonBehavior.BLOCK) + ); + + + + + + + + + + public static void registerModBlocks(){ + Registry.register(Registries.BLOCK, Identifier.of("miteequilibrium", "example_block"), EXAMPLE_BLOCK); + Registry.register(Registries.ITEM, Identifier.of("miteequilibrium", "example_block"), new BlockItem(EXAMPLE_BLOCK, new Item.Settings())); + + Registry.register(Registries.BLOCK, Identifier.of("miteequilibrium", "underworld_portalblock"), UNDERWORLD_PORTAL); + Registry.register(Registries.ITEM, Identifier.of("miteequilibrium", "underworld_portalblock"), new BlockItem(UNDERWORLD_PORTAL, new Item.Settings())); + + Registry.register(Registries.BLOCK, Identifier.of("miteequilibrium", "overworld_portalblock"), OVERWORLD_PORTAL); + Registry.register(Registries.ITEM, Identifier.of("miteequilibrium", "overworld_portalblock"), new BlockItem(OVERWORLD_PORTAL, new Item.Settings())); + + + } +} diff --git a/src/main/java/com/equilibrium/block/ModBlocksTest.java b/src/main/java/com/equilibrium/block/ModBlocksTest.java deleted file mode 100644 index dd82f90..0000000 --- a/src/main/java/com/equilibrium/block/ModBlocksTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.equilibrium.block; - -import net.minecraft.block.*; -import net.minecraft.item.BlockItem; -import net.minecraft.item.Item; -import net.minecraft.registry.Registries; -import net.minecraft.registry.Registry; -import net.minecraft.util.Identifier; - -import static net.minecraft.block.Blocks.register; - -public class ModBlocksTest { - - public static final Block EXAMPLE_BLOCK = new Block(Block.Settings.create().strength(4.0f)); - //strength中第一个为硬度,第二个为爆炸抗性 - - - - - - - - - - - - - - - - - public static void registerModBlocks(){ - Registry.register(Registries.BLOCK, Identifier.of("miteequilibrium", "example_block"), EXAMPLE_BLOCK); - Registry.register(Registries.ITEM, Identifier.of("miteequilibrium", "example_block"), new BlockItem(EXAMPLE_BLOCK, new Item.Settings())); - } -} diff --git a/src/main/java/com/equilibrium/block/OverworldPortalBlock.java b/src/main/java/com/equilibrium/block/OverworldPortalBlock.java new file mode 100644 index 0000000..a24e89b --- /dev/null +++ b/src/main/java/com/equilibrium/block/OverworldPortalBlock.java @@ -0,0 +1,107 @@ +package com.equilibrium.block; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Portal; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.particle.ParticleTypes; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvents; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.random.Random; +import net.minecraft.world.GameRules; +import net.minecraft.world.TeleportTarget; +import net.minecraft.world.World; +import net.minecraft.world.border.WorldBorder; +import org.jetbrains.annotations.Nullable; + +public class OverworldPortalBlock extends Block implements Portal { + public OverworldPortalBlock(Settings settings) { + super(settings); + } + + @Override + public int getPortalDelay(ServerWorld world, Entity entity) { + return entity instanceof PlayerEntity playerEntity + ? Math.max( + 1, + world.getGameRules() + .getInt(playerEntity.getAbilities().invulnerable ? GameRules.PLAYERS_NETHER_PORTAL_CREATIVE_DELAY : GameRules.PLAYERS_NETHER_PORTAL_DEFAULT_DELAY) + ) + : 0; + } + + + @Override + public TeleportTarget createTeleportTarget(ServerWorld world, Entity entity, BlockPos pos) { + //获取你的现有维度 + RegistryKey currentDimensionKey = world.getRegistryKey(); + + //注册自定义维度 + RegistryKey customDimensionKey = RegistryKey.of(RegistryKeys.WORLD, Identifier.of("miteequilibrium", "underworld")); + //创建自定义维度世界实例 + ServerWorld serverWorld = world.getServer().getWorld(customDimensionKey); + if (serverWorld!=null){ + System.out.println("weelll"); + }else{ + System.out.println("no!"); + } + //当自定义维度存在时(否则会产生空指针错误): + //世界边界限制器 + WorldBorder worldBorder = serverWorld.getWorldBorder(); + //1倍放大,参考下界是8倍 + BlockPos Pos = worldBorder.clamp(entity.getX() * 1, entity.getY(), entity.getZ() * 1); + + TeleportTarget.PostDimensionTransition postTransition = TeleportTarget.SEND_TRAVEL_THROUGH_PORTAL_PACKET; + + return TeleportTarget.missingSpawnBlock(serverWorld, entity, postTransition); + } + + + protected void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) { + if (entity.canUsePortals(false)) { + entity.tryUsePortal(this, pos); + } + } + @Override + public void randomDisplayTick(BlockState state, World world, BlockPos pos, Random random) { + if (random.nextInt(100) == 0) { + world.playSound( + (double)pos.getX() + 0.5, + (double)pos.getY() + 0.5, + (double)pos.getZ() + 0.5, + SoundEvents.BLOCK_PORTAL_AMBIENT, + SoundCategory.BLOCKS, + 0.5F, + random.nextFloat() * 0.4F + 0.8F, + false + ); + } + + for (int i = 0; i < 4; i++) { + double d = (double)pos.getX() + random.nextDouble(); + double e = (double)pos.getY() + random.nextDouble(); + double f = (double)pos.getZ() + random.nextDouble(); + double g = ((double)random.nextFloat() - 0.5) * 0.5; + double h = ((double)random.nextFloat() - 0.5) * 0.5; + double j = ((double)random.nextFloat() - 0.5) * 0.5; + int k = random.nextInt(2) * 2 - 1; + if (!world.getBlockState(pos.west()).isOf(this) && !world.getBlockState(pos.east()).isOf(this)) { + d = (double)pos.getX() + 0.5 + 0.25 * (double)k; + g = (double)(random.nextFloat() * 2.0F * (float)k); + } else { + f = (double)pos.getZ() + 0.5 + 0.25 * (double)k; + j = (double)(random.nextFloat() * 2.0F * (float)k); + } + + world.addParticle(ParticleTypes.PORTAL, d, e, f, g, h, j); + } + } + + +} diff --git a/src/main/java/com/equilibrium/block/UnderworldPortalBlock.java b/src/main/java/com/equilibrium/block/UnderworldPortalBlock.java new file mode 100644 index 0000000..08afc6f --- /dev/null +++ b/src/main/java/com/equilibrium/block/UnderworldPortalBlock.java @@ -0,0 +1,286 @@ +package com.equilibrium.block; + +import com.equilibrium.mixin.NetherPortalMixin; +import com.equilibrium.mixin.PortalForcerMixin; +import com.mojang.logging.LogUtils; +import com.mojang.serialization.MapCodec; +import net.minecraft.block.*; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityDimensions; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.SpawnReason; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.particle.ParticleTypes; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.resource.featuretoggle.FeatureSet; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvents; +import net.minecraft.state.StateManager; +import net.minecraft.state.property.EnumProperty; +import net.minecraft.state.property.Properties; +import net.minecraft.util.BlockRotation; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.random.Random; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.world.*; +import net.minecraft.world.border.WorldBorder; +import net.minecraft.world.dimension.DimensionType; +import net.minecraft.world.dimension.NetherPortal; +import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; + +import java.util.Optional; + +import static net.minecraft.world.TeleportTarget.missingSpawnBlock; + +public class UnderworldPortalBlock extends Block implements Portal{ + + + public static final MapCodec CODEC = createCodec(NetherPortalBlock::new); + public static final EnumProperty AXIS = Properties.HORIZONTAL_AXIS; + private static final Logger LOGGER = LogUtils.getLogger(); + protected static final int field_31196 = 2; + protected static final VoxelShape X_SHAPE = Block.createCuboidShape(0.0, 0.0, 6.0, 16.0, 16.0, 10.0); + protected static final VoxelShape Z_SHAPE = Block.createCuboidShape(6.0, 0.0, 0.0, 10.0, 16.0, 16.0); + + @Override + public MapCodec getCodec() { + return CODEC; + } + + public UnderworldPortalBlock(AbstractBlock.Settings settings) { + super(settings); + this.setDefaultState(this.stateManager.getDefaultState().with(AXIS, Direction.Axis.X)); + } + + @Override + protected VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + switch ((Direction.Axis)state.get(AXIS)) { + case Z: + return Z_SHAPE; + case X: + default: + return X_SHAPE; + } + } + + @Override + protected void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random random) { + if (world.getDimension().natural() && world.getGameRules().getBoolean(GameRules.DO_MOB_SPAWNING) && random.nextInt(2000) < world.getDifficulty().getId()) { + while (world.getBlockState(pos).isOf(this)) { + pos = pos.down(); + } + + if (world.getBlockState(pos).allowsSpawning(world, pos, EntityType.ZOMBIFIED_PIGLIN)) { + Entity entity = EntityType.ZOMBIFIED_PIGLIN.spawn(world, pos.up(), SpawnReason.STRUCTURE); + if (entity != null) { + entity.resetPortalCooldown(); + } + } + } + } + + @Override + protected BlockState getStateForNeighborUpdate( + BlockState state, Direction direction, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos + ) { + Direction.Axis axis = direction.getAxis(); + Direction.Axis axis2 = state.get(AXIS); + boolean bl = axis2 != axis && axis.isHorizontal(); + return !bl && !neighborState.isOf(this) && !new NetherPortal(world, pos, axis2).wasAlreadyValid() + ? Blocks.AIR.getDefaultState() + : super.getStateForNeighborUpdate(state, direction, neighborState, world, pos, neighborPos); + } + + @Override + protected void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) { + if (entity.canUsePortals(false)) { + entity.tryUsePortal(this, pos); + } + } + + @Override + public int getPortalDelay(ServerWorld world, Entity entity) { + return entity instanceof PlayerEntity playerEntity + ? Math.max( + 1, + world.getGameRules() + .getInt(playerEntity.getAbilities().invulnerable ? GameRules.PLAYERS_NETHER_PORTAL_CREATIVE_DELAY : GameRules.PLAYERS_NETHER_PORTAL_DEFAULT_DELAY) + ) + : 0; + } + + @Nullable + @Override + public TeleportTarget createTeleportTarget(ServerWorld world, Entity entity, BlockPos pos) { + + RegistryKey overworld = World.OVERWORLD; + RegistryKey underworld = RegistryKey.of(RegistryKeys.WORLD, Identifier.of("miteequilibrium", "underworld")); + RegistryKey registryKey = world.getRegistryKey() == underworld ? overworld : underworld; + + ServerWorld serverWorld = world.getServer().getWorld(registryKey); + if (serverWorld == null) { + return null; + } else { + boolean bl = serverWorld.getRegistryKey() == underworld; + WorldBorder worldBorder = serverWorld.getWorldBorder(); + double d = DimensionType.getCoordinateScaleFactor(world.getDimension(), serverWorld.getDimension()); + BlockPos blockPos = worldBorder.clamp(entity.getX() * d, entity.getY(), entity.getZ() * d); + return this.getOrCreateExitPortalTarget(serverWorld, entity, pos, blockPos, bl, worldBorder); + } + } + + @Nullable + private TeleportTarget getOrCreateExitPortalTarget( + ServerWorld world, Entity entity, BlockPos pos, BlockPos scaledPos, boolean inNether, WorldBorder worldBorder + ) { + Optional optional = world.getPortalForcer().getPortalPos(scaledPos, inNether, worldBorder); + BlockLocating.Rectangle rectangle; + TeleportTarget.PostDimensionTransition postDimensionTransition; + if (optional.isPresent()) { + BlockPos blockPos = (BlockPos)optional.get(); + BlockState blockState = world.getBlockState(blockPos); + rectangle = BlockLocating.getLargestRectangle( + blockPos, blockState.get(Properties.HORIZONTAL_AXIS), 21, Direction.Axis.Y, 21, posx -> world.getBlockState(posx) == blockState + ); + postDimensionTransition = TeleportTarget.SEND_TRAVEL_THROUGH_PORTAL_PACKET.then(entityx -> entityx.addPortalChunkTicketAt(blockPos)); + } else { + Direction.Axis axis = (Direction.Axis)entity.getWorld().getBlockState(pos).getOrEmpty(AXIS).orElse(Direction.Axis.X); + Optional optional2 = world.getPortalForcer().createPortal(scaledPos, axis); + if (optional2.isEmpty()) { + LOGGER.error("Unable to create a portal, likely target out of worldborder"); + return null; + } + + rectangle = (BlockLocating.Rectangle)optional2.get(); + postDimensionTransition = TeleportTarget.SEND_TRAVEL_THROUGH_PORTAL_PACKET.then(TeleportTarget.ADD_PORTAL_CHUNK_TICKET); + } + + return getExitPortalTarget(entity, pos, rectangle, world, postDimensionTransition); + } + + private static TeleportTarget getExitPortalTarget( + Entity entity, BlockPos pos, BlockLocating.Rectangle exitPortalRectangle, ServerWorld world, TeleportTarget.PostDimensionTransition postDimensionTransition + ) { + BlockState blockState = entity.getWorld().getBlockState(pos); + Direction.Axis axis; + Vec3d vec3d; + if (blockState.contains(Properties.HORIZONTAL_AXIS)) { + axis = blockState.get(Properties.HORIZONTAL_AXIS); + BlockLocating.Rectangle rectangle = BlockLocating.getLargestRectangle( + pos, axis, 21, Direction.Axis.Y, 21, posx -> entity.getWorld().getBlockState(posx) == blockState + ); + vec3d = entity.positionInPortal(axis, rectangle); + } else { + axis = Direction.Axis.X; + vec3d = new Vec3d(0.5, 0.0, 0.0); + } + + return getExitPortalTarget(world, exitPortalRectangle, axis, vec3d, entity, entity.getVelocity(), entity.getYaw(), entity.getPitch(), postDimensionTransition); + } + + private static TeleportTarget getExitPortalTarget( + ServerWorld world, + BlockLocating.Rectangle exitPortalRectangle, + Direction.Axis axis, + Vec3d positionInPortal, + Entity entity, + Vec3d velocity, + float yaw, + float pitch, + TeleportTarget.PostDimensionTransition postDimensionTransition + ) { + BlockPos blockPos = exitPortalRectangle.lowerLeft; + BlockState blockState = world.getBlockState(blockPos); + Direction.Axis axis2 = (Direction.Axis)blockState.getOrEmpty(Properties.HORIZONTAL_AXIS).orElse(Direction.Axis.X); + double d = (double)exitPortalRectangle.width; + double e = (double)exitPortalRectangle.height; + EntityDimensions entityDimensions = entity.getDimensions(entity.getPose()); + int i = axis == axis2 ? 0 : 90; + Vec3d vec3d = axis == axis2 ? velocity : new Vec3d(velocity.z, velocity.y, -velocity.x); + double f = (double)entityDimensions.width() / 2.0 + (d - (double)entityDimensions.width()) * positionInPortal.getX(); + double g = (e - (double)entityDimensions.height()) * positionInPortal.getY(); + double h = 0.5 + positionInPortal.getZ(); + boolean bl = axis2 == Direction.Axis.X; + Vec3d vec3d2 = new Vec3d((double)blockPos.getX() + (bl ? f : h), (double)blockPos.getY() + g, (double)blockPos.getZ() + (bl ? h : f)); + Vec3d vec3d3 = NetherPortal.findOpenPosition(vec3d2, world, entity, entityDimensions); + return new TeleportTarget(world, vec3d3, vec3d, yaw + (float)i, pitch, postDimensionTransition); + } + + @Override + public Portal.Effect getPortalEffect() { + return Portal.Effect.CONFUSION; + } + + @Override + public void randomDisplayTick(BlockState state, World world, BlockPos pos, Random random) { + if (random.nextInt(100) == 0) { + world.playSound( + (double)pos.getX() + 0.5, + (double)pos.getY() + 0.5, + (double)pos.getZ() + 0.5, + SoundEvents.BLOCK_PORTAL_AMBIENT, + SoundCategory.BLOCKS, + 0.5F, + random.nextFloat() * 0.4F + 0.8F, + false + ); + } + + for (int i = 0; i < 4; i++) { + double d = (double)pos.getX() + random.nextDouble(); + double e = (double)pos.getY() + random.nextDouble(); + double f = (double)pos.getZ() + random.nextDouble(); + double g = ((double)random.nextFloat() - 0.5) * 0.5; + double h = ((double)random.nextFloat() - 0.5) * 0.5; + double j = ((double)random.nextFloat() - 0.5) * 0.5; + int k = random.nextInt(2) * 2 - 1; + if (!world.getBlockState(pos.west()).isOf(this) && !world.getBlockState(pos.east()).isOf(this)) { + d = (double)pos.getX() + 0.5 + 0.25 * (double)k; + g = (double)(random.nextFloat() * 2.0F * (float)k); + } else { + f = (double)pos.getZ() + 0.5 + 0.25 * (double)k; + j = (double)(random.nextFloat() * 2.0F * (float)k); + } + + world.addParticle(ParticleTypes.PORTAL, d, e, f, g, h, j); + } + } + + @Override + public ItemStack getPickStack(WorldView world, BlockPos pos, BlockState state) { + return ItemStack.EMPTY; + } + + @Override + protected BlockState rotate(BlockState state, BlockRotation rotation) { + switch (rotation) { + case COUNTERCLOCKWISE_90: + case CLOCKWISE_90: + switch ((Direction.Axis)state.get(AXIS)) { + case Z: + return state.with(AXIS, Direction.Axis.X); + case X: + return state.with(AXIS, Direction.Axis.Z); + default: + return state; + } + default: + return state; + } + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + builder.add(AXIS); + } + + +} + diff --git a/src/main/java/com/equilibrium/gen/ModRecipeGenerator.java b/src/main/java/com/equilibrium/gen/ModRecipeGenerator.java new file mode 100644 index 0000000..85ac8c8 --- /dev/null +++ b/src/main/java/com/equilibrium/gen/ModRecipeGenerator.java @@ -0,0 +1,37 @@ +package com.equilibrium.gen; + +import com.equilibrium.item.Ingots; +import com.equilibrium.item.Tools; +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; +import net.minecraft.block.Blocks; +import net.minecraft.data.server.recipe.RecipeExporter; +import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder; +import net.minecraft.item.Item; +import net.minecraft.item.Items; +import net.minecraft.recipe.ShapedRecipe; +import net.minecraft.recipe.book.RecipeCategory; +import net.minecraft.registry.RegistryWrapper; +import net.minecraft.util.Identifier; + +import java.util.concurrent.CompletableFuture; + +public class ModRecipeGenerator extends FabricRecipeProvider { + public ModRecipeGenerator(FabricDataOutput output, CompletableFuture registriesFuture) { + super(output, registriesFuture); + } + + @Override + public void generate(RecipeExporter exporter) { + ShapedRecipeJsonBuilder.create(RecipeCategory.TOOLS, Tools.adamantium_axe). + pattern("XX"). + pattern("XY"). + pattern(" Y"). + input('X', Ingots.adamantium). + input('Y',Items.STICK). + criterion(FabricRecipeProvider.hasItem(Ingots.adamantium), + FabricRecipeProvider.conditionsFromItem(Ingots.adamantium)).offerTo(exporter, Identifier.of("adamantium_axe")); + + + } +} diff --git a/src/main/java/com/equilibrium/item/ModItemGroup.java b/src/main/java/com/equilibrium/item/ModItemGroup.java index 55b3a91..e3556cf 100644 --- a/src/main/java/com/equilibrium/item/ModItemGroup.java +++ b/src/main/java/com/equilibrium/item/ModItemGroup.java @@ -1,7 +1,8 @@ package com.equilibrium.item; import com.equilibrium.MITEequilibrium; -import com.equilibrium.block.ModBlocksTest; + +import com.equilibrium.block.ModBlocks; import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup; import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemStack; @@ -22,7 +23,7 @@ public class ModItemGroup { { entries.add(ModItems.test); entries.add(Items.BOOK);//可以加原版物品 - entries.add(ModBlocksTest.EXAMPLE_BLOCK); + entries.add(ModBlocks.EXAMPLE_BLOCK); } ).build()); diff --git a/src/main/java/com/equilibrium/mixin/AbstractFireBlockMixin.java b/src/main/java/com/equilibrium/mixin/AbstractFireBlockMixin.java new file mode 100644 index 0000000..f99ae39 --- /dev/null +++ b/src/main/java/com/equilibrium/mixin/AbstractFireBlockMixin.java @@ -0,0 +1,40 @@ +package com.equilibrium.mixin; + +import com.equilibrium.world.dimension.UnderworldPortal; +import net.minecraft.block.AbstractBlock; +import net.minecraft.block.AbstractFireBlock; +import net.minecraft.block.BlockState; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.World; +import net.minecraft.world.dimension.NetherPortal; +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 java.util.Optional; + +@Mixin(AbstractFireBlock.class) +public abstract class AbstractFireBlockMixin { + @Inject(method = "onBlockAdded",at=@At(value = "HEAD"), cancellable = true) + protected void onBlockAdded(BlockState state, World world, BlockPos pos, BlockState oldState, boolean notify, CallbackInfo ci) { + ci.cancel(); + if (!oldState.isOf(state.getBlock())) { + if (world.getRegistryKey()!=World.END) { + Optional optional = NetherPortal.getNewPortal(world, pos, Direction.Axis.X); + if (optional.isPresent()) { + ((NetherPortal)optional.get()).createPortal(); + ci.cancel(); + } + } + + if (!state.canPlaceAt(world, pos)) { + world.removeBlock(pos, false); + } + } + } +} diff --git a/src/main/java/com/equilibrium/mixin/ConcentricRingsStructurePlacementMixin.java b/src/main/java/com/equilibrium/mixin/ConcentricRingsStructurePlacementMixin.java new file mode 100644 index 0000000..48f7718 --- /dev/null +++ b/src/main/java/com/equilibrium/mixin/ConcentricRingsStructurePlacementMixin.java @@ -0,0 +1,39 @@ +package com.equilibrium.mixin; + +import net.minecraft.registry.Registerable; +import net.minecraft.registry.RegistryBuilder; +import net.minecraft.registry.RegistryEntryLookup; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.entry.RegistryEntryList; +import net.minecraft.registry.tag.BiomeTags; +import net.minecraft.structure.StructureSet; +import net.minecraft.structure.StructureSets; +import net.minecraft.util.Util; +import net.minecraft.util.math.Vec3i; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.dimension.DimensionTypeRegistrar; +import net.minecraft.world.gen.chunk.placement.ConcentricRingsStructurePlacement; +import net.minecraft.world.gen.chunk.placement.StructurePlacement; +import org.spongepowered.asm.mixin.*; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.Optional; + +@Mixin(ConcentricRingsStructurePlacement.class) +public abstract class ConcentricRingsStructurePlacementMixin implements StructureSets { + + + @Final + @Shadow + private int distance = 64; + + @Final + @Shadow + private int spread = 3; + + @Final + @Shadow + private int count =128; +} diff --git a/src/main/java/com/equilibrium/mixin/EnderEyeItemMixin.java b/src/main/java/com/equilibrium/mixin/EnderEyeItemMixin.java new file mode 100644 index 0000000..a4e2a51 --- /dev/null +++ b/src/main/java/com/equilibrium/mixin/EnderEyeItemMixin.java @@ -0,0 +1,65 @@ +package com.equilibrium.mixin; + +import net.minecraft.advancement.criterion.Criteria; +import net.minecraft.block.Blocks; +import net.minecraft.entity.EyeOfEnderEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.EnderEyeItem; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.registry.tag.StructureTags; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvents; +import net.minecraft.stat.Stats; +import net.minecraft.util.Hand; +import net.minecraft.util.TypedActionResult; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.hit.HitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.RaycastContext; +import net.minecraft.world.World; +import net.minecraft.world.event.GameEvent; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(EnderEyeItem.class) +public abstract class EnderEyeItemMixin extends Item { + public EnderEyeItemMixin(Settings settings) { + super(settings); + } + + @Override + public TypedActionResult use(World world, PlayerEntity user, Hand hand) { + ItemStack itemStack = user.getStackInHand(hand); + BlockHitResult blockHitResult = raycast(world, user, RaycastContext.FluidHandling.NONE); + if (blockHitResult.getType() == HitResult.Type.BLOCK && world.getBlockState(blockHitResult.getBlockPos()).isOf(Blocks.END_PORTAL_FRAME)) { + return TypedActionResult.pass(itemStack); + } else { + user.setCurrentHand(hand); + if (world instanceof ServerWorld serverWorld) { + BlockPos blockPos = serverWorld.locateStructure(StructureTags.EYE_OF_ENDER_LOCATED, user.getBlockPos(), 100, false); + if (blockPos != null && Math.abs(blockPos.getX()) > 12000 && Math.abs(blockPos.getZ()) > 12000) { + EyeOfEnderEntity eyeOfEnderEntity = new EyeOfEnderEntity(world, user.getX(), user.getBodyY(0.5), user.getZ()); + eyeOfEnderEntity.setItem(itemStack); + eyeOfEnderEntity.initTargetPos(blockPos); + world.emitGameEvent(GameEvent.PROJECTILE_SHOOT, eyeOfEnderEntity.getPos(), GameEvent.Emitter.of(user)); + world.spawnEntity(eyeOfEnderEntity); + if (user instanceof ServerPlayerEntity serverPlayerEntity) { + Criteria.USED_ENDER_EYE.trigger(serverPlayerEntity, blockPos); + } + + float f = MathHelper.lerp(world.random.nextFloat(), 0.33F, 0.5F); + world.playSound(null, user.getX(), user.getY(), user.getZ(), SoundEvents.ENTITY_ENDER_EYE_LAUNCH, SoundCategory.NEUTRAL, 1.0F, f); + itemStack.decrementUnlessCreative(1, user); + user.incrementStat(Stats.USED.getOrCreateStat(this)); + user.swingHand(hand, true); + return TypedActionResult.success(itemStack); + } + } + + return TypedActionResult.consume(itemStack); + } + } +} diff --git a/src/main/java/com/equilibrium/mixin/IdentifierMixin.java b/src/main/java/com/equilibrium/mixin/IdentifierMixin.java new file mode 100644 index 0000000..1cf73af --- /dev/null +++ b/src/main/java/com/equilibrium/mixin/IdentifierMixin.java @@ -0,0 +1,24 @@ +package com.equilibrium.mixin; +//实现注册自定义维度,后续生成自定义矿物 + +import net.minecraft.util.Identifier; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.Objects; + +import static net.minecraft.util.PathUtil.validatePath; + +@Mixin(Identifier.class) +public abstract class IdentifierMixin implements Comparable{ + @Inject(method = "ofVanilla", at = @At("HEAD")) + private static void ofVanilla(String path, CallbackInfoReturnable cir) { + //向Identifier类注入了一个条件 + }} + + diff --git a/src/main/java/com/equilibrium/mixin/MITEequilibriumMixin.java b/src/main/java/com/equilibrium/mixin/MITEequilibriumMixin.java index 9984920..2a18432 100644 --- a/src/main/java/com/equilibrium/mixin/MITEequilibriumMixin.java +++ b/src/main/java/com/equilibrium/mixin/MITEequilibriumMixin.java @@ -8,8 +8,9 @@ @Mixin(MinecraftServer.class) public class MITEequilibriumMixin { - @Inject(at = @At("HEAD"), method = "loadWorld") - private void init(CallbackInfo info) { - // This code is injected into the start of MinecraftServer.loadWorld()V - } + @Inject(at = @At("HEAD"), method = "loadWorld") + private void init(CallbackInfo info) { + // This code is injected into the start of MinecraftServer.loadWorld()V + + } } \ No newline at end of file diff --git a/src/main/java/com/equilibrium/mixin/NetherPortalBlockMixin.java b/src/main/java/com/equilibrium/mixin/NetherPortalBlockMixin.java new file mode 100644 index 0000000..4e2e642 --- /dev/null +++ b/src/main/java/com/equilibrium/mixin/NetherPortalBlockMixin.java @@ -0,0 +1,106 @@ +package com.equilibrium.mixin; + +import net.minecraft.block.Block; +import net.minecraft.block.NetherPortalBlock; +import net.minecraft.block.Portal; +import net.minecraft.entity.Entity; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.TeleportTarget; +import net.minecraft.world.World; +import net.minecraft.world.border.WorldBorder; +import net.minecraft.world.dimension.DimensionType; +import org.jetbrains.annotations.Nullable; +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; + +@Mixin(NetherPortalBlock.class) +public abstract class NetherPortalBlockMixin extends Block implements Portal { + + + @Shadow @Nullable protected abstract TeleportTarget getOrCreateExitPortalTarget(ServerWorld world, Entity entity, BlockPos pos, BlockPos scaledPos, boolean inNether, WorldBorder worldBorder); + + public NetherPortalBlockMixin(Settings settings) { + super(settings); + } + + @Inject(method = "createTeleportTarget",at=@At(value = "HEAD"),cancellable = true) + public void createTeleportTarget(ServerWorld world, Entity entity, BlockPos pos, CallbackInfoReturnable cir) { + cir.cancel(); + RegistryKey overworld = World.OVERWORLD; + RegistryKey nether = World.NETHER; + RegistryKey underworld = RegistryKey.of(RegistryKeys.WORLD, Identifier.of("miteequilibrium", "underworld")); + //获取目前的世界类型(访问注册方法) + RegistryKey registryKey = world.getRegistryKey(); + //传送后的世界类型 + RegistryKey teleport; + + if (registryKey == null) { + cir.setReturnValue(null); + } else { + ServerWorld serverWorld; + //缩放条件 + boolean inNether = world.getRegistryKey() == World.NETHER; + //世界边界限制 + WorldBorder worldBorder = world.getWorldBorder(); + //缩放倍率 + double d = DimensionType.getCoordinateScaleFactor(world.getDimension(), world.getDimension()); + BlockPos blockPos = worldBorder.clamp(entity.getX() * d, entity.getY(), entity.getZ() * d); + + boolean atBottom = Math.abs(blockPos.getY()-world.getBottomY())<5; + + + + //world.getRegistryKey()获取现在的世界 + //主世界传地下世界,地下世界也可以传主世界 + + + + + + + if(world.getRegistryKey()==overworld && atBottom){ + teleport=underworld; + } else if (world.getRegistryKey()==overworld && !atBottom) { + teleport=overworld; + } else if (world.getRegistryKey()==underworld && !atBottom) { + teleport=overworld; + } else if (world.getRegistryKey()==underworld && atBottom) { + teleport=nether; + } else if(world.getRegistryKey()==nether){ + teleport=underworld; + } + else { + teleport=world.getRegistryKey(); + } + + + serverWorld=world.getServer().getWorld(teleport); + cir.setReturnValue(this.getOrCreateExitPortalTarget(serverWorld, entity, pos, blockPos, inNether, worldBorder)); + + }} + + + + + + + + + + + + } + + + + + + + diff --git a/src/main/java/com/equilibrium/mixin/NetherPortalMixin.java b/src/main/java/com/equilibrium/mixin/NetherPortalMixin.java new file mode 100644 index 0000000..3759595 --- /dev/null +++ b/src/main/java/com/equilibrium/mixin/NetherPortalMixin.java @@ -0,0 +1,259 @@ +package com.equilibrium.mixin; + +import com.equilibrium.block.ModBlocks; +import com.equilibrium.block.UnderworldPortalBlock; +import net.minecraft.block.*; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.tag.BlockTags; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.*; +import net.minecraft.world.World; +import net.minecraft.world.WorldAccess; +import net.minecraft.world.dimension.NetherPortal; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.*; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(NetherPortal.class) +public abstract class NetherPortalMixin { +// +///* 测试用 +// @Inject(method = "getNewPortal",at = @At("HEAD")) +// private static void getNewPortal(WorldAccess world, BlockPos pos, Direction.Axis axis, CallbackInfoReturnable> cir) { +// System.out.println("getNewPortal()"); +// } +// @Inject(method = "getOrEmpty",at =@At("HEAD")) +// private static void getOrEmpty(WorldAccess world, BlockPos pos, Predicate validator, Direction.Axis axis, CallbackInfoReturnable> cir) { +// System.out.println("getOrEmpty()"); +// } +// @Inject(method = "getLowerCorner",at = @At("HEAD")) +// private void getLowerCorner(BlockPos pos, CallbackInfoReturnable cir) { +// System.out.println("getLowerCorner"); +// } +// @Inject(method = "getWidth()I",at = @At("HEAD")) +// private void getWidth(CallbackInfoReturnable cir) { +// System.out.println("getWidth()I"); +// } +// @Inject(method = "getWidth(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/Direction;)I",at = @At("HEAD")) +// private void getWidth(BlockPos pos, Direction direction, CallbackInfoReturnable cir) { +// System.out.println("getWidth(2)"); +// } +// @Inject(method = "getHeight",at = @At("HEAD")) +// private void getHeight(CallbackInfoReturnable cir) { +// System.out.println("getHeight"); +// } +// @Inject(method = "isHorizontalFrameValid",at = @At("HEAD")) +// private void isHorizontalFrameValid(BlockPos.Mutable pos, int height, CallbackInfoReturnable cir) { +// System.out.println("isHorizontalFrameValid"); +// } +// @Inject(method = "getPotentialHeight",at =@At("HEAD")) +// private void getPotentialHeight(BlockPos.Mutable pos, CallbackInfoReturnable cir) { +// System.out.println("getPotentialHeight"); +// } +// @Inject(method = "validStateInsidePortal",at = @At("HEAD")) +// private static void validStateInsidePortal(BlockState state, CallbackInfoReturnable cir) { +// System.out.println("validStateInsidePortal"); +// } +// @Inject(method = "isValid",at = @At("HEAD")) +// public void isValid(CallbackInfoReturnable cir) { +// System.out.println("isValid"); +// } +// @Inject(method = "createPortal",at =@At("HEAD")) +// public void createPortal(CallbackInfo ci) { +// System.out.println("createPortal()"); +// } +// @Inject(method = "wasAlreadyValid",at = @At("HEAD")) +// public void wasAlreadyValid(CallbackInfoReturnable cir) { +// System.out.println("wasAlreadyValid"); +// } +// @Inject(method = "entityPosInPortal",at = @At("HEAD")) +// private static void entityPosInPortal(BlockLocating.Rectangle portalRect, Direction.Axis portalAxis, Vec3d entityPos, EntityDimensions entityDimensions, CallbackInfoReturnable cir) { +// System.out.println("entityPosInPortal"); +// } +// @Inject(method = "findOpenPosition",at =@At("HEAD")) +// private static void findOpenPosition(Vec3d fallback, ServerWorld world, Entity entity, EntityDimensions dimensions, CallbackInfoReturnable cir) { +// System.out.println("findOpenPosition"); +// } +// */ +// +// @Unique +// private int getHeightFromBottom(){ +// if (this.lowerCorner != null) { +// return Math.abs(world.getBottomY()-this.lowerCorner.getY()); +// } +// else{ +// System.out.println("It might the portal doesn't exist"); +// return 384; +// } +// }; +// +// @Unique +// public RegistryKey getWorldDimension(ServerWorld world) { +// return world.getRegistryKey(); +// //RegistryKey registryKey = world.getRegistryKey() == World.NETHER ? World.OVERWORLD : World.NETHER; +// } +// +// +// @Shadow private @Nullable BlockPos lowerCorner; +// +// +// @Shadow @Final +// private WorldAccess world; +// +// +// +// @Inject(method = "isHorizontalFrameValid",at=@At(value = "HEAD")) +// //当传送门距离世界底部距离小于等于5时,传送门才可以被点亮 +// private void isHorizontalFrameValid(BlockPos.Mutable pos, int height, CallbackInfoReturnable cir) { +// +//// boolean getOldPortalStateIsTrue =cir.getReturnValue(); +//// int theHeightOfThePortalFromTheWorldBottom; +//// +//// +//// if(getOldPortalStateIsTrue && this.lowerCorner != null){ +//// +//// theHeightOfThePortalFromTheWorldBottom=getHeightFromBottom(); +//// +//// if(theHeightOfThePortalFromTheWorldBottom<=5){ +//// System.out.println("The height of the portal from world_bottom:"+(theHeightOfThePortalFromTheWorldBottom)); +//// cir.setReturnValue(true); +//// }else{ +//// System.out.println("The height of the portal from world_bottom:"+(theHeightOfThePortalFromTheWorldBottom)+">5"); +//// cir.setReturnValue(false); +//// } +//// }else{ +//// System.out.println("condition is false: getOldPortalStateIsTrue && this.lowerCorner != null "); +//// System.out.println("It might be this.lowerCorner is null(is the world now where the portal locate in existing?)"); +//// cir.setReturnValue(false); +//// } +// } +// +// +// //不要用accessible访问类的私有变量,直接用@Shadow好不好 +// @Shadow @Final +// private Direction.Axis axis; +// +// @Shadow @Final +// private Direction negativeDir; +// +// @Shadow @Final +// private int width; +// +// @Shadow +// private int height; +// +// @Shadow +// private final static AbstractBlock.ContextPredicate IS_VALID_FRAME_BLOCK = (state, world, pos) -> state.isOf(Blocks.OBSIDIAN); +// +// @Shadow +// private int foundPortalBlocks; +// +// +// +// +// +// +// +// +// +// +// +// +// +// @Inject(method = "getPotentialHeight",at =@At("HEAD"),cancellable = true) +// private void getPotentialHeight(BlockPos.Mutable pos, CallbackInfoReturnable cir) { +// for (int i = 0; i < 21; i++) { +// pos.set(this.lowerCorner).move(Direction.UP, i).move(this.negativeDir, -1); +// if (!IS_VALID_FRAME_BLOCK.test(this.world.getBlockState(pos), this.world, pos)) { +// cir.setReturnValue(i); +// } +// +// pos.set(this.lowerCorner).move(Direction.UP, i).move(this.negativeDir, this.width); +// if (!IS_VALID_FRAME_BLOCK.test(this.world.getBlockState(pos), this.world, pos)) { +// cir.setReturnValue(i); +// } +// +// for (int j = 0; j < this.width; j++) { +// pos.set(this.lowerCorner).move(Direction.UP, i).move(this.negativeDir, j); +// BlockState blockState = this.world.getBlockState(pos); +// if (!NetherPortal.validStateInsidePortal(blockState)) { +// cir.setReturnValue(i); +// } +// +// if (blockState.isOf(ModBlocks.UNDERWORLD_PORTAL)) { +// this.foundPortalBlocks++; +// } +// } +// } +// +// cir.setReturnValue(21); +// } +// +//// @Unique +//// private static boolean validStateInsidePortalForMixin(BlockState state) { +//// return state.isAir() || state.isIn(BlockTags.FIRE) || state.isOf(ModBlocks.UNDERWORLD_PORTAL); +//// } +// +// +// @Inject(method = "validStateInsidePortal",at=@At(value = "HEAD"), cancellable = true) +// private static void validStateInsidePortal(BlockState state, CallbackInfoReturnable cir) { +// cir.cancel(); +// cir.setReturnValue(state.isAir() || state.isIn(BlockTags.FIRE) || state.isOf(ModBlocks.UNDERWORLD_PORTAL)); +// } +// +// +// @Inject(method = "createPortal",at=@At(value = "HEAD"), cancellable = true) +// public void createPortal(CallbackInfo ci) { +// /* +// 规则:当传送门距离世界底部距离小于等于5时,传送门才可以被点亮为自定义的传送门方块 +// 1、在主世界,建立在距离底部小于等于5格距离的传送门,将传送到地下世界 +// 2、在地下世界,建立在距离底部小于等于5格距离的传送门,将传送到下界 +// 3、在地下世界,建立在距离底部大于5格距离的传送门,将传送到主世界 +// 4、在下界,任意位置的传送门,都将传送到地下世界 +// */ +// ci.cancel(); +// //记录当前注册的世界 +// RegistryKey registryKey = ((ServerWorld) world).getRegistryKey(); +// +// //是否距离底部小于5格距离 +// boolean locatedInBottom = getHeightFromBottom() <= 5; +// +// //是否是主世界 +// boolean overworld = (getWorldDimension((ServerWorld) world) == World.OVERWORLD); +// //是否是地下世界 +// boolean underworld = (getWorldDimension((ServerWorld) world) == RegistryKey.of(RegistryKeys.WORLD, Identifier.of("miteequilibrium", "underworld"))); +// +// //是否为下界 +// boolean netherworld = (getWorldDimension((ServerWorld) world) == World.NETHER); +// +// +// +// +// if (locatedInBottom && overworld) { +// //在主世界,建立在距离底部小于等于5格距离的传送门,将传送到地下世界 +// setUnderworldPortalBlock(); +// }else if ((!locatedInBottom) && underworld) { +// //在地下世界,建立在距离底部大于5格距离的传送门,将传送到主世界 +// setUnderworldPortalBlock(); +// } +// else{ +// ci.cancel(); +// +// } +// +// } +// +// @Unique +// private void setUnderworldPortalBlock() { +// BlockState blockState = Blocks.NETHER_PORTAL.getDefaultState().with(UnderworldPortalBlock.AXIS,this.axis); +// BlockPos.iterate(this.lowerCorner, this.lowerCorner.offset(Direction.UP, this.height - 1).offset(this.negativeDir, this.width - 1)) +// .forEach(pos -> this.world.setBlockState(pos, blockState, Block.NOTIFY_LISTENERS | Block.FORCE_STATE)); +// } + + +} diff --git a/src/main/java/com/equilibrium/mixin/PlayerEntityMixin.java b/src/main/java/com/equilibrium/mixin/PlayerEntityMixin.java new file mode 100644 index 0000000..5f90fda --- /dev/null +++ b/src/main/java/com/equilibrium/mixin/PlayerEntityMixin.java @@ -0,0 +1,52 @@ +package com.equilibrium.mixin; + +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.attribute.EntityAttributes; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.world.World; +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; + +@Mixin(PlayerEntity.class) + +//和源码构造方式一致,继承谁这里也跟着继承 +public abstract class PlayerEntityMixin extends LivingEntity { + + + @Shadow public abstract int getNextLevelExperience(); + + @Shadow public int experienceLevel; + + protected PlayerEntityMixin(EntityType entityType, World world) { + super(entityType, world); + } +//调用CallbackInfo类,修改返回值 +//以下是修改方块交互距离 + @Inject(method = "getBlockInteractionRange", at = @At("HEAD"), cancellable = true) + public void getBlockInteractionRange(CallbackInfoReturnable cir) { + cir.setReturnValue(3.0); + } +//以下修改实体交互距离 + @Inject(method = "getEntityInteractionRange", at = @At("HEAD"), cancellable = true) + public void getEntityInteractionRange(CallbackInfoReturnable cir) { + cir.setReturnValue(1.0); + } + + + @Inject(method = "getBlockBreakingSpeed", at = @At("RETURN"), cancellable = true) + public void getBlockBreakingSpeed(BlockState block, CallbackInfoReturnable cir) { + int level = this.experienceLevel; + float speed = cir.getReturnValue(); + System.out.println(speed); + float finalSpeed = speed*(0.025F)*(1+level*0.02F); + System.out.println(finalSpeed); + cir.setReturnValue(finalSpeed); + } + +}; diff --git a/src/main/java/com/equilibrium/mixin/PortalForcerMixin.java b/src/main/java/com/equilibrium/mixin/PortalForcerMixin.java new file mode 100644 index 0000000..b565987 --- /dev/null +++ b/src/main/java/com/equilibrium/mixin/PortalForcerMixin.java @@ -0,0 +1,85 @@ +package com.equilibrium.mixin; + +import com.equilibrium.block.ModBlocks; +import net.minecraft.block.Blocks; +import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.state.property.Properties; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3i; +import net.minecraft.world.border.WorldBorder; +import net.minecraft.world.dimension.PortalForcer; +import net.minecraft.world.poi.PointOfInterest; +import net.minecraft.world.poi.PointOfInterestStorage; +import net.minecraft.world.poi.PointOfInterestType; +import net.minecraft.world.poi.PointOfInterestTypes; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +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 java.util.Comparator; +import java.util.Optional; + +import static com.equilibrium.block.ModBlocks.UNDERWORLD_PORTAL; +import static net.minecraft.world.poi.PointOfInterestType.*; + +@Mixin(PortalForcer.class) +public abstract class PortalForcerMixin { + + + @Final + @Shadow private ServerWorld world; + + @Inject(method = "getPortalPos",at = @At("TAIL"),cancellable = true) + public void getPortalPos(BlockPos pos, boolean destIsNether, WorldBorder worldBorder, CallbackInfoReturnable> cir) { + System.out.println(cir.getReturnValue()); + } +// @Inject(method = "createPortal",at = @At("HEAD")) +// public void createPortal(BlockPos pos, Direction.Axis axis, CallbackInfoReturnable> cir) { +// System.out.println("getPortalPos"); +// } +// @Inject(method = "isBlockStateValid",at = @At("HEAD")) +// private void isBlockStateValid(BlockPos.Mutable pos, CallbackInfoReturnable cir) { +// System.out.println("isBlockStateValid"); +// } +// @Inject(method = "isValidPortalPos",at = @At("HEAD")) +// private void isValidPortalPos(BlockPos pos, BlockPos.Mutable temp, Direction portalDirection, int distanceOrthogonalToPortal, CallbackInfoReturnable cir) { +// System.out.println("isValidPortalPos"); +// } +// @Inject(method = "getPortalPos",at = @At("HEAD"), cancellable = true) +// public void getPortalPos(BlockPos pos, boolean destIsNether, WorldBorder worldBorder, CallbackInfoReturnable> cir) { +// cir.cancel(); +// PointOfInterestStorage pointOfInterestStorage = this.world.getPointOfInterestStorage(); +// int i = destIsNether ? 16 : 128; +// pointOfInterestStorage.preloadChunks(this.world, pos, i); +// +// Comparator distanceComparator = Comparator.comparingDouble(blockPos2 -> blockPos2.getSquaredDistance(pos)); +// Comparator yComparator = Comparator.comparingInt(BlockPos::getY); +// Comparator combinedComparator = distanceComparator.thenComparing(yComparator); +// +// +// RegistryKey.of(RegistryKeys.POINT_OF_INTEREST_TYPE, Identifier.of("miteequilibrium","underworld_portal")); +// PointOfInterestTypes.registerAndGetDefault((Registry) UNDERWORLD_PORTAL); +// +// +// +// +// cir.setReturnValue(pointOfInterestStorage.getInSquare( +// poiType -> poiType.matchesKey(PointOfInterestTypes.NETHER_PORTAL), pos, i, PointOfInterestStorage.OccupationStatus.ANY +// ) +// .map(PointOfInterest::getPos) +// .filter(worldBorder::contains) +// .filter(blockPos -> this.world.getBlockState(blockPos).contains(Properties.HORIZONTAL_AXIS)) +// .min(combinedComparator)); +// } + + + +} diff --git a/src/main/java/com/equilibrium/mixin/StrongholdGeneratorMixin.java b/src/main/java/com/equilibrium/mixin/StrongholdGeneratorMixin.java new file mode 100644 index 0000000..a6df0c5 --- /dev/null +++ b/src/main/java/com/equilibrium/mixin/StrongholdGeneratorMixin.java @@ -0,0 +1,59 @@ +package com.equilibrium.mixin; + +import net.minecraft.nbt.NbtCompound; +import net.minecraft.structure.StrongholdGenerator; +import net.minecraft.structure.StructurePiece; +import net.minecraft.structure.StructurePiecesHolder; +import net.minecraft.util.math.BlockBox; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.random.Random; +import org.jetbrains.annotations.Nullable; +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; +@Mixin(StrongholdGenerator.class) + +public abstract class StrongholdGeneratorMixin { + @Inject(method = "createPiece", at = @At(value = "HEAD"),cancellable = true) + private static void createPiece(Class pieceType, StructurePiecesHolder holder, Random random, int x, int y, int z, @Nullable Direction orientation, int chainLength, CallbackInfoReturnable cir) { + cir.cancel(); + StrongholdGenerator.Piece piece = null; + + if (pieceType == StrongholdGenerator.Corridor.class) { + piece = StrongholdGenerator.Corridor.create(holder, random, x, y, z, orientation, chainLength); + } else if (pieceType == StrongholdGenerator.PrisonHall.class) { + piece = StrongholdGenerator.PrisonHall.create(holder, random, x, y, z, orientation, chainLength); + } else if (pieceType == StrongholdGenerator.LeftTurn.class) { + piece = StrongholdGenerator.LeftTurn.create(holder, random, x, y, z, orientation, chainLength); + } else if (pieceType == StrongholdGenerator.RightTurn.class) { + piece = StrongholdGenerator.RightTurn.create(holder, random, x, y, z, orientation, chainLength); + } else if (pieceType == StrongholdGenerator.SquareRoom.class) { + piece = StrongholdGenerator.SquareRoom.create(holder, random, x, y, z, orientation, chainLength); + } else if (pieceType == StrongholdGenerator.Stairs.class) { + piece = StrongholdGenerator.Stairs.create(holder, random, x, y, z, orientation, chainLength); + } else if (pieceType == StrongholdGenerator.SpiralStaircase.class) { + piece = StrongholdGenerator.SpiralStaircase.create(holder, random, x, y, z, orientation, chainLength); + } else if (pieceType == StrongholdGenerator.FiveWayCrossing.class) { + piece = StrongholdGenerator.FiveWayCrossing.create(holder, random, x, y, z, orientation, chainLength); + } else if (pieceType == StrongholdGenerator.ChestCorridor.class) { + piece = StrongholdGenerator.ChestCorridor.create(holder, random, x, y, z, orientation, chainLength); + } else if (pieceType == StrongholdGenerator.Library.class) { + piece = StrongholdGenerator.Library.create(holder, random, x, y, z, orientation, chainLength); + } else if (pieceType == StrongholdGenerator.PortalRoom.class) { + if(Math.abs(x)<12000 && Math.abs(z)<12000) { + x = x+12000; + z = z+12000; + piece = StrongholdGenerator.PortalRoom.create(holder, x, y, z, orientation, chainLength); + }else{ + piece = StrongholdGenerator.PortalRoom.create(holder, x, y, z, orientation, chainLength); + } + + } + cir.setReturnValue(piece); + }} + + + + + diff --git a/src/main/java/com/equilibrium/mixin/StrongholdGeneratorStartMixin.java b/src/main/java/com/equilibrium/mixin/StrongholdGeneratorStartMixin.java new file mode 100644 index 0000000..4f244e0 --- /dev/null +++ b/src/main/java/com/equilibrium/mixin/StrongholdGeneratorStartMixin.java @@ -0,0 +1,51 @@ +package com.equilibrium.mixin; + +import net.minecraft.structure.StructurePieceType; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.random.Random; +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.ModifyArg; +import org.spongepowered.asm.mixin.injection.ModifyArgs; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.invoke.arg.Args; +import static net.minecraft.structure.StrongholdGenerator.*; + + +@Mixin(Start.class) +public class StrongholdGeneratorStartMixin extends SpiralStaircase { + public StrongholdGeneratorStartMixin(StructurePieceType structurePieceType, int chainLength, int x, int z, Direction orientation) { + super(structurePieceType, chainLength, x, z, orientation); + } + @ModifyArg(method = "(Lnet/minecraft/util/math/random/Random;II)V",at= @At(value = "INVOKE", target = "Lnet/minecraft/structure/StrongholdGenerator$SpiralStaircase;(Lnet/minecraft/structure/StructurePieceType;IIILnet/minecraft/util/math/Direction;)V"),index = 2) + private static int modifyConstructorArgsX(int x) { + return x; + } + @ModifyArg(method = "(Lnet/minecraft/util/math/random/Random;II)V",at= @At(value = "INVOKE", target = "Lnet/minecraft/structure/StrongholdGenerator$SpiralStaircase;(Lnet/minecraft/structure/StructurePieceType;IIILnet/minecraft/util/math/Direction;)V"),index = 3) + private static int modifyConstructorArgsZ(int z) { + return z; + } + + @ModifyArgs(method = "(Lnet/minecraft/util/math/random/Random;II)V",at= @At(value = "INVOKE", target = "Lnet/minecraft/structure/StrongholdGenerator$SpiralStaircase;(Lnet/minecraft/structure/StructurePieceType;IIILnet/minecraft/util/math/Direction;)V")) + private static void modifyConstructorArgsZ(Args args){ +// System.out.println(Optional.ofNullable(args.get(2))); +// System.out.println(Optional.ofNullable(args.get(3))); + + } + + + +// @Inject(method = "(Lnet/minecraft/util/math/random/Random;II)V", at = @At("TAIL")) +// public void start(Random random, int i, int j, CallbackInfo ci) { +// System.out.println("x= "+i+"z= "+j); +} + + + + + + + + + diff --git a/src/main/java/com/equilibrium/test.java b/src/main/java/com/equilibrium/test.java new file mode 100644 index 0000000..399a5a2 --- /dev/null +++ b/src/main/java/com/equilibrium/test.java @@ -0,0 +1,9 @@ +package com.equilibrium; + +import net.minecraft.world.dimension.NetherPortal; + +public class test { + public static void main(String[] args) { + System.out.println(1); + } +} diff --git a/src/main/java/com/equilibrium/world/dimension/UnderworldPortal.java b/src/main/java/com/equilibrium/world/dimension/UnderworldPortal.java new file mode 100644 index 0000000..3a41cff --- /dev/null +++ b/src/main/java/com/equilibrium/world/dimension/UnderworldPortal.java @@ -0,0 +1,275 @@ +package com.equilibrium.world.dimension; + +import com.equilibrium.block.ModBlocks; +import com.equilibrium.block.UnderworldPortalBlock; +import net.minecraft.block.*; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityDimensions; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.tag.BlockTags; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.*; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.util.shape.VoxelShapes; +import net.minecraft.world.BlockLocating; +import net.minecraft.world.World; +import net.minecraft.world.WorldAccess; +import net.minecraft.world.dimension.NetherPortal; +import net.minecraft.world.dimension.PortalManager; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; +import java.util.function.Predicate; + +public class UnderworldPortal { + private static final int MIN_WIDTH = 2; + public static final int MAX_WIDTH = 21; + private static final int MIN_HEIGHT = 3; + public static final int MAX_HEIGHT = 21; + private static final AbstractBlock.ContextPredicate IS_VALID_FRAME_BLOCK = (state, world, pos) -> state.isOf(Blocks.OBSIDIAN); + private static final float FALLBACK_THRESHOLD = 4.0F; + private static final double HEIGHT_STRETCH = 1.0; + private final WorldAccess world; + private final Direction.Axis axis; + private final Direction negativeDir; + private int foundPortalBlocks; + @Nullable + private BlockPos lowerCorner; + private int height; + private final int width; + + public static Optional getNewPortal(WorldAccess world, BlockPos pos, Direction.Axis axis) { + return getOrEmpty(world, pos, areaHelper -> areaHelper.isValid() && areaHelper.foundPortalBlocks == 0, axis); + } + + public static Optional getOrEmpty(WorldAccess world, BlockPos pos, Predicate validator, Direction.Axis axis) { + Optional optional = Optional.of(new UnderworldPortal(world, pos, axis)).filter(validator); + if (optional.isPresent()) { + return optional; + } else { + + Direction.Axis axis2 = axis == Direction.Axis.X ? Direction.Axis.Z : Direction.Axis.X; + return Optional.of(new UnderworldPortal(world, pos, axis2)).filter(validator); + } + } + + public UnderworldPortal(WorldAccess world, BlockPos pos, Direction.Axis axis) { + this.world = world; + this.axis = axis; + this.negativeDir = axis == Direction.Axis.X ? Direction.WEST : Direction.SOUTH; + this.lowerCorner = this.getLowerCorner(pos); + if (this.lowerCorner == null) { + this.lowerCorner = pos; + this.width = 1; + this.height = 1; + } else { + this.width = this.getWidth(); + if (this.width > 0) { + this.height = this.getHeight(); + } + } + } + + @Nullable + private BlockPos getLowerCorner(BlockPos pos) { + int i = Math.max(this.world.getBottomY(), pos.getY() - 21); + + while (pos.getY() > i && validStateInsidePortal(this.world.getBlockState(pos.down()))) { + pos = pos.down(); + } + + Direction direction = this.negativeDir.getOpposite(); + int j = this.getWidth(pos, direction) - 1; + return j < 0 ? null : pos.offset(direction, j); + } + + private int getWidth() { + int i = this.getWidth(this.lowerCorner, this.negativeDir); + return i >= 2 && i <= 21 ? i : 0; + } + + private int getWidth(BlockPos pos, Direction direction) { + BlockPos.Mutable mutable = new BlockPos.Mutable(); + + for (int i = 0; i <= 21; i++) { + mutable.set(pos).move(direction, i); + BlockState blockState = this.world.getBlockState(mutable); + if (!validStateInsidePortal(blockState)) { + if (IS_VALID_FRAME_BLOCK.test(blockState, this.world, mutable)) { + return i; + } + break; + } + + BlockState blockState2 = this.world.getBlockState(mutable.move(Direction.DOWN)); + if (!IS_VALID_FRAME_BLOCK.test(blockState2, this.world, mutable)) { + break; + } + } + + return 0; + } + + private int getHeight() { + BlockPos.Mutable mutable = new BlockPos.Mutable(); + int i = this.getPotentialHeight(mutable); + return i >= 3 && i <= 21 && this.isHorizontalFrameValid(mutable, i) ? i : 0; + } + + private boolean isHorizontalFrameValid(BlockPos.Mutable pos, int height) { + for (int i = 0; i < this.width; i++) { + BlockPos.Mutable mutable = pos.set(this.lowerCorner).move(Direction.UP, height).move(this.negativeDir, i); + if (!IS_VALID_FRAME_BLOCK.test(this.world.getBlockState(mutable), this.world, mutable)) { + return false; + } + } + + return true; + } + + private int getPotentialHeight(BlockPos.Mutable pos) { + for (int i = 0; i < 21; i++) { + pos.set(this.lowerCorner).move(Direction.UP, i).move(this.negativeDir, -1); + if (!IS_VALID_FRAME_BLOCK.test(this.world.getBlockState(pos), this.world, pos)) { + return i; + } + + pos.set(this.lowerCorner).move(Direction.UP, i).move(this.negativeDir, this.width); + if (!IS_VALID_FRAME_BLOCK.test(this.world.getBlockState(pos), this.world, pos)) { + return i; + } + + for (int j = 0; j < this.width; j++) { + pos.set(this.lowerCorner).move(Direction.UP, i).move(this.negativeDir, j); + BlockState blockState = this.world.getBlockState(pos); + if (!validStateInsidePortal(blockState)) { + return i; + } + + if (blockState.isOf(ModBlocks.UNDERWORLD_PORTAL)) { + this.foundPortalBlocks++; + } + } + } + + return 21; + } + + private static boolean validStateInsidePortal(BlockState state) { + return state.isAir() || state.isIn(BlockTags.FIRE) || state.isOf(ModBlocks.UNDERWORLD_PORTAL); + } + + public boolean isValid() { + return this.lowerCorner != null && this.width >= 2 && this.width <= 21 && this.height >= 3 && this.height <= 21; + } + + public void createPortal() { + /* + 规则:当传送门距离世界底部距离小于等于5时,传送门才可以被点亮为自定义的传送门方块 + 1、在主世界,建立在距离底部小于等于5格距离的传送门,将传送到地下世界 + 2、在地下世界,建立在距离底部小于等于5格距离的传送门,将传送到下界 + 3、在地下世界,建立在距离底部大于5格距离的传送门,将传送到主世界 + 4、在下界,任意位置的传送门,都将传送到地下世界 + */ + //记录当前注册的世界 + RegistryKey registryKey = ((ServerWorld) world).getRegistryKey(); + + //是否距离底部小于5格距离 + boolean locatedInBottom = getHeightFromBottom() <= 5; + + //是否是主世界 + boolean overworld = (getWorldDimension((ServerWorld) world) == World.OVERWORLD); + //是否是地下世界 + boolean underworld = (getWorldDimension((ServerWorld) world) == RegistryKey.of(RegistryKeys.WORLD, Identifier.of("miteequilibrium", "underworld"))); + + //是否为下界 + boolean netherworld = (getWorldDimension((ServerWorld) world) == World.NETHER); + + + if (locatedInBottom && overworld) { + //在主世界,建立在距离底部小于等于5格距离的传送门,将传送到地下世界 + setUnderworldPortalBlock(); + System.out.println("execute 1 "); + }else if ((!locatedInBottom) && underworld) { + //在地下世界,建立在距离底部大于5格距离的传送门,将传送到主世界 + setUnderworldPortalBlock(); + System.out.println("execute 2 "); + } + else{ + return; + + } + + } + + + public boolean wasAlreadyValid() { + return this.isValid() && this.foundPortalBlocks == this.width * this.height; + } + + public static Vec3d entityPosInPortal(BlockLocating.Rectangle portalRect, Direction.Axis portalAxis, Vec3d entityPos, EntityDimensions entityDimensions) { + double d = (double)portalRect.width - (double)entityDimensions.width(); + double e = (double)portalRect.height - (double)entityDimensions.height(); + BlockPos blockPos = portalRect.lowerLeft; + double g; + if (d > 0.0) { + double f = (double)blockPos.getComponentAlongAxis(portalAxis) + (double)entityDimensions.width() / 2.0; + g = MathHelper.clamp(MathHelper.getLerpProgress(entityPos.getComponentAlongAxis(portalAxis) - f, 0.0, d), 0.0, 1.0); + } else { + g = 0.5; + } + + double f; + if (e > 0.0) { + Direction.Axis axis = Direction.Axis.Y; + f = MathHelper.clamp(MathHelper.getLerpProgress(entityPos.getComponentAlongAxis(axis) - (double)blockPos.getComponentAlongAxis(axis), 0.0, e), 0.0, 1.0); + } else { + f = 0.0; + } + + Direction.Axis axis = portalAxis == Direction.Axis.X ? Direction.Axis.Z : Direction.Axis.X; + double h = entityPos.getComponentAlongAxis(axis) - ((double)blockPos.getComponentAlongAxis(axis) + 0.5); + return new Vec3d(g, f, h); + } + + public static Vec3d findOpenPosition(Vec3d fallback, ServerWorld world, Entity entity, EntityDimensions dimensions) { + if (!(dimensions.width() > 4.0F) && !(dimensions.height() > 4.0F)) { + double d = (double)dimensions.height() / 2.0; + Vec3d vec3d = fallback.add(0.0, d, 0.0); + VoxelShape voxelShape = VoxelShapes.cuboid(Box.of(vec3d, (double)dimensions.width(), 0.0, (double)dimensions.width()).stretch(0.0, 1.0, 0.0).expand(1.0E-6)); + Optional optional = world.findClosestCollision( + entity, voxelShape, vec3d, (double)dimensions.width(), (double)dimensions.height(), (double)dimensions.width() + ); + Optional optional2 = optional.map(pos -> pos.subtract(0.0, d, 0.0)); + return (Vec3d)optional2.orElse(fallback); + } else { + return fallback; + } + } + + private int getHeightFromBottom(){ + if (this.lowerCorner != null) { + return Math.abs(world.getBottomY()-this.lowerCorner.getY()); + } + else{ + System.out.println("It might the portal doesn't exist"); + return 384; + } + } + public RegistryKey getWorldDimension(ServerWorld world) { + return world.getRegistryKey(); + //RegistryKey registryKey = world.getRegistryKey() == World.NETHER ? World.OVERWORLD : World.NETHER; + } + + private void setUnderworldPortalBlock() { + BlockState blockState = ModBlocks.UNDERWORLD_PORTAL.getDefaultState().with(UnderworldPortalBlock.AXIS,this.axis); + BlockPos.iterate(this.lowerCorner, this.lowerCorner.offset(Direction.UP, this.height - 1).offset(this.negativeDir, this.width - 1)) + .forEach(pos -> this.world.setBlockState(pos, blockState, Block.NOTIFY_LISTENERS | Block.FORCE_STATE)); + } + + + + +} diff --git a/src/main/java/com/equilibrium/worldgen/ModOreGenerator.java b/src/main/java/com/equilibrium/worldgen/ModOreGenerator.java new file mode 100644 index 0000000..d8ea633 --- /dev/null +++ b/src/main/java/com/equilibrium/worldgen/ModOreGenerator.java @@ -0,0 +1,83 @@ +package com.equilibrium.worldgen; + +import net.fabricmc.fabric.api.biome.v1.BiomeModifications; +import net.fabricmc.fabric.api.biome.v1.BiomeSelectors; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.util.Identifier; +import net.minecraft.world.dimension.DimensionOptions; + +import net.minecraft.world.gen.GenerationStep; +import net.minecraft.world.gen.feature.PlacedFeature; + +public class ModOreGenerator { + //为主世界添加的矿物 + public static final RegistryKey CUSTOM_ORE_OVERWORLD = RegistryKey.of(RegistryKeys.PLACED_FEATURE, + Identifier.of("miteequilibrium","ore_custom_overworld")); + //为地下世界添加的矿物 + public static final RegistryKey CUSTOM_ORE_UNDERWORLD = RegistryKey.of(RegistryKeys.PLACED_FEATURE, + Identifier.of("miteequilibrium","ore_custom_underworld")); + + //为下界添加的矿物 + public static final RegistryKey CUSTOM_ORE_NETHER = RegistryKey.of(RegistryKeys.PLACED_FEATURE, + Identifier.of("miteequilibrium","ore_custom_nether")); + + //为末地添加的矿物 + public static final RegistryKey CUSTOM_ORE_END = RegistryKey.of(RegistryKeys.PLACED_FEATURE, + Identifier.of("miteequilibrium","ore_custom_end")); + + + //Identifier.of("miteequilibrium","ore_custom_xxx")格式,就是第一个填你的模组名字(也是文件夹名字),第二个填json名字,记得也去json文件里改名字 + + public static void registerModOre() { + //用自己实现的类在指定维度注册矿物 + //主世界添加矿物 + BiomeModifications.addFeature(context -> context.canGenerateIn(UnderWorldDimensionOptions.OVERWORLD), GenerationStep.Feature.UNDERGROUND_ORES, CUSTOM_ORE_OVERWORLD); + + + //地下世界添加矿物 + BiomeModifications.addFeature(context -> context.canGenerateIn(UnderWorldDimensionOptions.UNDERWORLD), GenerationStep.Feature.UNDERGROUND_ORES, CUSTOM_ORE_UNDERWORLD); + + + //下界添加矿物 + BiomeModifications.addFeature(context -> context.canGenerateIn(UnderWorldDimensionOptions.NETHER), GenerationStep.Feature.UNDERGROUND_ORES, CUSTOM_ORE_NETHER); + + //末地添加矿物 + BiomeModifications.addFeature(context -> context.canGenerateIn(UnderWorldDimensionOptions.END), GenerationStep.Feature.UNDERGROUND_ORES, CUSTOM_ORE_END); + + + + + //调用规则:替换UnderWorldDimensionOptions.后面的内容,具体去文件去看 + //CUSTOM_ORE_PLACED_KEY是注册的名字,随便改 + + + //我是如何实现的? + //首先重写net.minecraft.world.dimension.DimensionOptions;我命名为UnderWorldDimensionOptions + //在这里添加了一条代码: + //public static final RegistryKey UNDERWORLD = RegistryKey.of(RegistryKeys.DIMENSION, Identifier.of("miteequilibrium","underworld")); + //然后执行BiomeModifications.addFeature(context -> context.canGenerateIn(UnderWorldDimensionOptions.UNDERWORLD), GenerationStep.Feature.UNDERGROUND_ORES, CUSTOM_ORE_PLACED_KEY);即可 + + //你会发现这条代码执行的和官网上给出的示例不一样,fabric官网上在主世界添加矿物是这么写的: + //BiomeModifications.addFeature(BiomeSelectors.foundInOverworld(), GenerationStep.Feature.UNDERGROUND_ORES, CUSTOM_ORE_PLACED_KEY); + //首先我去翻了源码:BiomeSelectors.foundInOverworld()就是return context -> context.canGenerateIn(WorldDimensionOptions.OVERWORLD),于是两者等价 + + //但是如果要在自定义维度地下世界添加矿物呢,WorldDimensionOptions里面可没有地下世界成员,况且这个类是不可被修改的,用了record关键字 + //所以我把这个类复制粘贴重新生成了一个,命名为UnderWorldDimensionOptions + //添加了public static final RegistryKey UNDERWORLD = RegistryKey.of(RegistryKeys.DIMENSION, Identifier.ofVanilla("underworld")); + //问题又来了,Identifier.ofVanilla(String path)方法里可没有接收"underworld"的参数 + //好吧,我去翻了Identifier.ofVanilla(String path)源码: + + //public static Identifier ofVanilla(String path) { + // return new Identifier("minecraft", validatePath("minecraft", path)); + // } + //如果调用了Identifier.ofVanilla("underworld"),则return了一个实例化Identifier对象:始终是等价为Identifier.of("minecraft","underworld") + //那我干嘛还要用这个诡异的函数,我自己new一个不就好了 + //所以我改成:Identifier.of("miteequilibrium","underworld") + //很好,编译通过而且也正常生成了,这是1.21数据包想都别想的事情,居然在自定义世界生成自定义矿物,自己写代码去吧!(就是以上我说的这些) + + } +} + diff --git a/src/main/java/com/equilibrium/worldgen/UnderWorldDimensionOptions.java b/src/main/java/com/equilibrium/worldgen/UnderWorldDimensionOptions.java new file mode 100644 index 0000000..b0fad00 --- /dev/null +++ b/src/main/java/com/equilibrium/worldgen/UnderWorldDimensionOptions.java @@ -0,0 +1,29 @@ +package com.equilibrium.worldgen; + + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.util.Identifier; +import net.minecraft.world.dimension.DimensionOptions; +import net.minecraft.world.dimension.DimensionType; +import net.minecraft.world.gen.chunk.ChunkGenerator; + +public record UnderWorldDimensionOptions(RegistryEntry dimensionTypeEntry, ChunkGenerator chunkGenerator) { + public static final Codec CODEC = RecordCodecBuilder.create( + instance -> instance.group( + DimensionType.REGISTRY_CODEC.fieldOf("type").forGetter(net.minecraft.world.dimension.DimensionOptions::dimensionTypeEntry), + ChunkGenerator.CODEC.fieldOf("generator").forGetter(net.minecraft.world.dimension.DimensionOptions::chunkGenerator) + ) + .apply(instance, instance.stable(net.minecraft.world.dimension.DimensionOptions::new)) + ); + public static final RegistryKey OVERWORLD = RegistryKey.of(RegistryKeys.DIMENSION, Identifier.of("minecraft","overworld")); + public static final RegistryKey NETHER = RegistryKey.of(RegistryKeys.DIMENSION, Identifier.of("minecraft","the_nether")); + public static final RegistryKey END = RegistryKey.of(RegistryKeys.DIMENSION, Identifier.of("minecraft","the_end")); + public static final RegistryKey UNDERWORLD = RegistryKey.of(RegistryKeys.DIMENSION, Identifier.of("miteequilibrium","underworld")); + //调用规则:如果是原版世界,用Identifier.of("minecraft","xxx"),若为自定义维度,则用Identifier.of("miteeqilibrium","xxx") + +} + diff --git a/src/main/resources/data/miteequilibrium/dimension/underworld.json b/src/main/resources/data/miteequilibrium/dimension/underworld.json new file mode 100644 index 0000000..9da398a --- /dev/null +++ b/src/main/resources/data/miteequilibrium/dimension/underworld.json @@ -0,0 +1,11 @@ +{ + "type": "miteequilibrium:underworld", + "generator": { + "type": "minecraft:noise", + "settings": "miteequilibrium:underworld", + "biome_source": { + "type": "minecraft:fixed", + "biome": "miteequilibrium:underworld" + } + } +} diff --git a/src/main/resources/data/miteequilibrium/dimension_type/underworld.json b/src/main/resources/data/miteequilibrium/dimension_type/underworld.json new file mode 100644 index 0000000..5a819fb --- /dev/null +++ b/src/main/resources/data/miteequilibrium/dimension_type/underworld.json @@ -0,0 +1,23 @@ +{ + "ambient_light": 0.0, + "bed_works": true, + "coordinate_scale": 1.0, + "effects": "minecraft:overworld", + "has_ceiling": true, + "has_raids": true, + "has_skylight": true, + "height": 384, + "infiniburn": "#minecraft:infiniburn_overworld", + "logical_height": 384, + "min_y": -64, + "monster_spawn_block_light_limit": 0, + "monster_spawn_light_level": { + "type": "minecraft:uniform", + "max_inclusive": 7, + "min_inclusive": 0 + }, + "natural": true, + "piglin_safe": false, + "respawn_anchor_works": false, + "ultrawarm": false +} \ No newline at end of file diff --git a/src/main/resources/data/miteequilibrium/recipe/adamantium_axe.json b/src/main/resources/data/miteequilibrium/recipe/adamantium_axe.json new file mode 100644 index 0000000..a68e73a --- /dev/null +++ b/src/main/resources/data/miteequilibrium/recipe/adamantium_axe.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "equipment", + "key": { + "X": { + "item": "miteequilibrium:adamantium" + }, + "Y": { + "item": "minecraft:stick" + } + }, + "pattern": [ + "XX", + "XY", + " Y" + ], + "result": { + "count": 1, + "id": "miteequilibrium:adamantium_axe" + } +} \ No newline at end of file diff --git a/src/main/resources/data/miteequilibrium/recipe/adamantium_battle_axe.json b/src/main/resources/data/miteequilibrium/recipe/adamantium_battle_axe.json new file mode 100644 index 0000000..7290f3a --- /dev/null +++ b/src/main/resources/data/miteequilibrium/recipe/adamantium_battle_axe.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "equipment", + "key": { + "X": { + "item": "miteequilibrium:adamantium" + }, + "Y": { + "item": "minecraft:stick" + } + }, + "pattern": [ + "X X", + "XYX", + " Y " + ], + "result": { + "count": 1, + "id": "miteequilibrium:adamantium_battle_axe" + } +} \ No newline at end of file diff --git a/src/main/resources/data/miteequilibrium/worldgen/biome/underworld.json b/src/main/resources/data/miteequilibrium/worldgen/biome/underworld.json new file mode 100644 index 0000000..56f1e5c --- /dev/null +++ b/src/main/resources/data/miteequilibrium/worldgen/biome/underworld.json @@ -0,0 +1,15 @@ +{ + "temperature": 0.8, + "downfall": 0.4, + "has_precipitation": false, + "effects": { + "sky_color": 0, + "fog_color": 986896, + "water_color": 4159204, + "water_fog_color": 329011 + }, + "spawners": {}, + "spawn_costs": {}, + "carvers": {}, + "features": [] +} diff --git a/src/main/resources/data/miteequilibrium/worldgen/configured_feature/ore_custom_end.json b/src/main/resources/data/miteequilibrium/worldgen/configured_feature/ore_custom_end.json new file mode 100644 index 0000000..c15c2ba --- /dev/null +++ b/src/main/resources/data/miteequilibrium/worldgen/configured_feature/ore_custom_end.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:ore", + "config": { + "discard_chance_on_air_exposure": 0.0, + "size": 20, + "targets": [ + { + "state": { + "Name": "minecraft:end_rod" + }, + "target": { + "block": "minecraft:end_stone", + "predicate_type": "minecraft:block_match" + } + } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/data/miteequilibrium/worldgen/configured_feature/ore_custom_nether.json b/src/main/resources/data/miteequilibrium/worldgen/configured_feature/ore_custom_nether.json new file mode 100644 index 0000000..cf7f990 --- /dev/null +++ b/src/main/resources/data/miteequilibrium/worldgen/configured_feature/ore_custom_nether.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:ore", + "config": { + "discard_chance_on_air_exposure": 0.0, + "size": 20, + "targets": [ + { + "state": { + "Name": "minecraft:end_rod" + }, + "target": { + "block": "minecraft:netherrack", + "predicate_type": "minecraft:block_match" + } + } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/data/miteequilibrium/worldgen/configured_feature/ore_custom_overworld.json b/src/main/resources/data/miteequilibrium/worldgen/configured_feature/ore_custom_overworld.json new file mode 100644 index 0000000..fb236ab --- /dev/null +++ b/src/main/resources/data/miteequilibrium/worldgen/configured_feature/ore_custom_overworld.json @@ -0,0 +1,27 @@ +{ + "type": "minecraft:ore", + "config": { + "discard_chance_on_air_exposure": 0.0, + "size": 12, + "targets": [ + { + "state": { + "Name": "minecraft:end_rod" + }, + "target": { + "predicate_type": "minecraft:tag_match", + "tag": "minecraft:stone_ore_replaceables" + } + }, + { + "state": { + "Name": "minecraft:end_rod" + }, + "target": { + "predicate_type": "minecraft:tag_match", + "tag": "minecraft:deepslate_ore_replaceables" + } + } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/data/miteequilibrium/worldgen/configured_feature/ore_custom_underworld.json b/src/main/resources/data/miteequilibrium/worldgen/configured_feature/ore_custom_underworld.json new file mode 100644 index 0000000..fb236ab --- /dev/null +++ b/src/main/resources/data/miteequilibrium/worldgen/configured_feature/ore_custom_underworld.json @@ -0,0 +1,27 @@ +{ + "type": "minecraft:ore", + "config": { + "discard_chance_on_air_exposure": 0.0, + "size": 12, + "targets": [ + { + "state": { + "Name": "minecraft:end_rod" + }, + "target": { + "predicate_type": "minecraft:tag_match", + "tag": "minecraft:stone_ore_replaceables" + } + }, + { + "state": { + "Name": "minecraft:end_rod" + }, + "target": { + "predicate_type": "minecraft:tag_match", + "tag": "minecraft:deepslate_ore_replaceables" + } + } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/data/miteequilibrium/worldgen/noise_settings/underworld.json b/src/main/resources/data/miteequilibrium/worldgen/noise_settings/underworld.json new file mode 100644 index 0000000..5f282de --- /dev/null +++ b/src/main/resources/data/miteequilibrium/worldgen/noise_settings/underworld.json @@ -0,0 +1,242 @@ +{ + "sea_level": 144, + "disable_mob_generation": false, + "aquifers_enabled": true, + "ore_veins_enabled": true, + "legacy_random_source": false, + "default_block": { + "Name": "minecraft:stone" + }, + "default_fluid": { + "Name": "minecraft:water", + "Properties": { + "level": "0" + } + }, + "noise": { + "min_y": -64, + "height": 384, + "size_horizontal": 1, + "size_vertical": 2 + }, + "noise_router": { + "barrier": 0, + "fluid_level_floodedness": 0, + "fluid_level_spread": 0, + "lava": 0, + "temperature": 0, + "vegetation": 0, + "continents": 0, + "erosion": 0, + "depth": 0, + "ridges": 0, + "initial_density_without_jaggedness": 0, + "final_density": { + "type": "minecraft:squeeze", + "argument": { + "type": "minecraft:mul", + "argument1": 0.64, + "argument2": { + "type": "minecraft:interpolated", + "argument": { + "type": "minecraft:blend_density", + "argument": { + "type": "minecraft:add", + "argument1": 2.61, + "argument2": { + "type": "minecraft:mul", + "argument1": { + "type": "minecraft:y_clamped_gradient", + "from_y": 108, + "to_y": 140, + "from_value": 0, + "to_value": 1.1 + }, + "argument2": { + "type": "minecraft:add", + "argument1": -2.55, + "argument2": { + "type": "minecraft:add", + "argument1": 0.87, + "argument2": { + "type": "minecraft:mul", + "argument1": { + "type": "minecraft:y_clamped_gradient", + "from_y": 196, + "to_y": 384, + "from_value": 0.8, + "to_value": 0 + }, + "argument2": { + "type": "minecraft:add", + "argument1": "minecraft:overworld/caves/entrances", + "argument2": { + "type": "minecraft:add", + "argument1": { + "type": "minecraft:noise", + "noise": "minecraft:erosion", + "xz_scale": 1, + "y_scale": 16 + }, + "argument2": { + "type": "minecraft:add", + "argument1": -1.1, + "argument2": { + "type": "minecraft:add", + "argument1": { + "type": "minecraft:squeeze", + "argument": "minecraft:nether/base_3d_noise" + }, + "argument2": { + "type": "minecraft:squeeze", + "argument": "minecraft:overworld/base_3d_noise" + } + } + } + } + } + } + } + } + } + } + } + } + } + }, + "vein_toggle": 0, + "vein_ridged": 0, + "vein_gap": 0 + }, + "spawn_target": [], + "surface_rule": { + "type": "minecraft:sequence", + "sequence": [ + { + "type": "minecraft:sequence", + "sequence": [ + { + "type": "minecraft:sequence", + "sequence": [ + { + "type": "minecraft:condition", + "if_true": { + "type": "minecraft:not", + "invert": { + "type": "minecraft:vertical_gradient", + "random_name": "top_floor", + "true_at_and_below": { + "below_top": 5 + }, + "false_at_and_above": { + "below_top": 0 + } + } + }, + "then_run": { + "type": "minecraft:block", + "result_state": { + "Name": "minecraft:bedrock" + } + } + }, + { + "type": "minecraft:condition", + "if_true": { + "type": "minecraft:not", + "invert": { + "type": "minecraft:y_above", + "anchor": { + "absolute": 108 + }, + "surface_depth_multiplier": 2, + "add_stone_depth": false + } + }, + "then_run": { + "type": "minecraft:condition", + "if_true": { + "type": "minecraft:y_above", + "anchor": { + "absolute": 113 + }, + "surface_depth_multiplier": -1, + "add_stone_depth": false + }, + "then_run": { + "type": "minecraft:block", + "result_state": { + "Name": "minecraft:bedrock" + } + } + } + }, + { + "type": "minecraft:condition", + "if_true": { + "type": "minecraft:not", + "invert": { + "type": "minecraft:y_above", + "anchor": { + "absolute": -63 + }, + "surface_depth_multiplier": 2, + "add_stone_depth": false + } + }, + "then_run": { + "type": "minecraft:block", + "result_state": { + "Name": "minecraft:bedrock" + } + } + }, + { + "type": "minecraft:condition", + "if_true": { + "type": "minecraft:not", + "invert": { + "type": "minecraft:y_above", + "anchor": { + "absolute": -59 + }, + "surface_depth_multiplier": 0, + "add_stone_depth": false + } + }, + "then_run": { + "type": "minecraft:condition", + "if_true": { + "type": "minecraft:y_above", + "anchor": { + "absolute": -64 + }, + "surface_depth_multiplier": 0, + "add_stone_depth": false + }, + "then_run": { + "type": "minecraft:block", + "result_state": { + "Name": "minecraft:lava", + "Properties": { + "level": "0" + } + } + } + } + } + ] + }, + { + "type": "minecraft:sequence", + "sequence": [] + }, + { + "type": "minecraft:sequence", + "sequence": [] + } + ] + } + ] + } +} diff --git a/src/main/resources/data/miteequilibrium/worldgen/placed_feature/ore_custom_end.json b/src/main/resources/data/miteequilibrium/worldgen/placed_feature/ore_custom_end.json new file mode 100644 index 0000000..7053c27 --- /dev/null +++ b/src/main/resources/data/miteequilibrium/worldgen/placed_feature/ore_custom_end.json @@ -0,0 +1,27 @@ +{ + "feature": "miteequilibrium:ore_custom_end", + "placement": [ + { + "type": "minecraft:count", + "count": 20 + }, + { + "type": "minecraft:in_square" + }, + { + "type": "minecraft:height_range", + "height": { + "type": "minecraft:uniform", + "max_inclusive": { + "below_top": 10 + }, + "min_inclusive": { + "above_bottom": 10 + } + } + }, + { + "type": "minecraft:biome" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/miteequilibrium/worldgen/placed_feature/ore_custom_nether.json b/src/main/resources/data/miteequilibrium/worldgen/placed_feature/ore_custom_nether.json new file mode 100644 index 0000000..cd6d02e --- /dev/null +++ b/src/main/resources/data/miteequilibrium/worldgen/placed_feature/ore_custom_nether.json @@ -0,0 +1,27 @@ +{ + "feature": "miteequilibrium:ore_custom_nether", + "placement": [ + { + "type": "minecraft:count", + "count": 20 + }, + { + "type": "minecraft:in_square" + }, + { + "type": "minecraft:height_range", + "height": { + "type": "minecraft:uniform", + "max_inclusive": { + "below_top": 10 + }, + "min_inclusive": { + "above_bottom": 10 + } + } + }, + { + "type": "minecraft:biome" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/miteequilibrium/worldgen/placed_feature/ore_custom_overworld.json b/src/main/resources/data/miteequilibrium/worldgen/placed_feature/ore_custom_overworld.json new file mode 100644 index 0000000..988a8c8 --- /dev/null +++ b/src/main/resources/data/miteequilibrium/worldgen/placed_feature/ore_custom_overworld.json @@ -0,0 +1,27 @@ +{ + "feature": "miteequilibrium:ore_custom_overworld", + "placement": [ + { + "type": "minecraft:count", + "count": 20 + }, + { + "type": "minecraft:in_square" + }, + { + "type": "minecraft:height_range", + "height": { + "type": "minecraft:trapezoid", + "max_inclusive": { + "absolute": 70 + }, + "min_inclusive": { + "absolute": -24 + } + } + }, + { + "type": "minecraft:biome" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/miteequilibrium/worldgen/placed_feature/ore_custom_underworld.json b/src/main/resources/data/miteequilibrium/worldgen/placed_feature/ore_custom_underworld.json new file mode 100644 index 0000000..58013c7 --- /dev/null +++ b/src/main/resources/data/miteequilibrium/worldgen/placed_feature/ore_custom_underworld.json @@ -0,0 +1,27 @@ +{ + "feature": "miteequilibrium:ore_custom_underworld", + "placement": [ + { + "type": "minecraft:count", + "count": 20 + }, + { + "type": "minecraft:in_square" + }, + { + "type": "minecraft:height_range", + "height": { + "type": "minecraft:trapezoid", + "max_inclusive": { + "absolute": 70 + }, + "min_inclusive": { + "absolute": -24 + } + } + }, + { + "type": "minecraft:biome" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 46e4a48..8da425b 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -34,6 +34,7 @@ "java": ">=21", "fabric-api": "*" }, + "accessWidener": "name.accesswidener", "suggests": { "another-mod": "*" } diff --git a/src/main/resources/miteequilibrium.mixins.json b/src/main/resources/miteequilibrium.mixins.json index fb00476..9225eb6 100644 --- a/src/main/resources/miteequilibrium.mixins.json +++ b/src/main/resources/miteequilibrium.mixins.json @@ -1,11 +1,21 @@ { - "required": true, - "package": "com.equilibrium.mixin", - "compatibilityLevel": "JAVA_21", - "mixins": [ - "MITEequilibriumMixin" - ], - "injectors": { - "defaultRequire": 1 - } + "required": true, + "package": "com.equilibrium.mixin", + "compatibilityLevel": "JAVA_21", + "mixins": [ + "AbstractFireBlockMixin", + "ConcentricRingsStructurePlacementMixin", + "EnderEyeItemMixin", + "IdentifierMixin", + "MITEequilibriumMixin", + "NetherPortalBlockMixin", + "NetherPortalMixin", + "PlayerEntityMixin", + "PortalForcerMixin", + "StrongholdGeneratorMixin", + "StrongholdGeneratorStartMixin" + ], + "injectors": { + "defaultRequire": 1 + } } \ No newline at end of file diff --git a/src/main/resources/name.accesswidener b/src/main/resources/name.accesswidener new file mode 100644 index 0000000..e13c986 --- /dev/null +++ b/src/main/resources/name.accesswidener @@ -0,0 +1,24 @@ +accessWidener v1 named + +accessible method net/minecraft/block/NetherPortalBlock getOrCreateExitPortalTarget (Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/entity/Entity;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/BlockPos;ZLnet/minecraft/world/border/WorldBorder;)Lnet/minecraft/world/TeleportTarget; +accessible method net/minecraft/world/dimension/NetherPortal validStateInsidePortal (Lnet/minecraft/block/BlockState;)Z +accessible field net/minecraft/world/dimension/NetherPortal width I +accessible field net/minecraft/world/dimension/NetherPortal negativeDir Lnet/minecraft/util/math/Direction; +accessible field net/minecraft/world/dimension/NetherPortal height I +accessible field net/minecraft/world/dimension/NetherPortal axis Lnet/minecraft/util/math/Direction$Axis; +accessible field net/minecraft/world/dimension/NetherPortal lowerCorner Lnet/minecraft/util/math/BlockPos; +accessible class net/minecraft/structure/StrongholdGenerator$PieceData +accessible method net/minecraft/structure/StructurePiece getRandomHorizontalDirection (Lnet/minecraft/util/math/random/Random;)Lnet/minecraft/util/math/Direction; +accessible class net/minecraft/structure/StrongholdGenerator$Piece +accessible method net/minecraft/structure/StructurePiece applyZTransform (II)I +accessible field net/minecraft/structure/StructurePiece boundingBox Lnet/minecraft/util/math/BlockBox; +accessible method net/minecraft/structure/StrongholdGenerator checkRemainingPieces ()Z +accessible field net/minecraft/structure/StrongholdGenerator activePieceType Ljava/lang/Class; +accessible field net/minecraft/structure/StrongholdGenerator totalWeight I +accessible class net/minecraft/structure/StrongholdGenerator$PieceData +accessible field net/minecraft/structure/StrongholdGenerator possiblePieces Ljava/util/List; +accessible field net/minecraft/structure/StrongholdGenerator$PieceData weight I +accessible field net/minecraft/structure/StrongholdGenerator$PieceData pieceType Ljava/lang/Class; +accessible field net/minecraft/structure/StrongholdGenerator$PieceData generatedCount I +accessible method net/minecraft/structure/StrongholdGenerator createPiece (Ljava/lang/Class;Lnet/minecraft/structure/StructurePiecesHolder;Lnet/minecraft/util/math/random/Random;IIILnet/minecraft/util/math/Direction;I)Lnet/minecraft/structure/StrongholdGenerator$Piece; +accessible method net/minecraft/structure/StrongholdGenerator pickPiece (Lnet/minecraft/structure/StrongholdGenerator$Start;Lnet/minecraft/structure/StructurePiecesHolder;Lnet/minecraft/util/math/random/Random;IIILnet/minecraft/util/math/Direction;I)Lnet/minecraft/structure/StrongholdGenerator$Piece; \ No newline at end of file