Inspired by 2020's April Fools' 20w14infinite Snapshot, this mod brings endless randomly generated dimensions into Minecraft.
at master 144 lines 6.8 kB view raw
1package net.lerariemann.infinity.block.custom; 2 3import net.lerariemann.infinity.access.Timebombable; 4import net.lerariemann.infinity.util.InfinityMethods; 5import net.lerariemann.infinity.registry.var.ModCriteria; 6import net.lerariemann.infinity.registry.core.ModItems; 7import net.lerariemann.infinity.registry.var.ModSounds; 8import net.lerariemann.infinity.registry.var.ModStats; 9import net.lerariemann.infinity.util.teleport.PortalCreator; 10import net.minecraft.MethodsReturnNonnullByDefault; 11import net.minecraft.core.BlockPos; 12import net.minecraft.core.particles.ParticleTypes; 13//? if >1.21.9 { 14/*import net.minecraft.core.particles.PowerParticleOption; 15*///?} 16import net.minecraft.network.chat.Component; 17import net.minecraft.server.level.ServerLevel; 18import net.minecraft.server.level.ServerPlayer; 19import net.minecraft.sounds.SoundEvents; 20import net.minecraft.sounds.SoundSource; 21import net.minecraft.world.InteractionHand; 22import net.minecraft.world.InteractionResult; 23import net.minecraft.world.entity.AreaEffectCloud; 24import net.minecraft.world.entity.Entity; 25import net.minecraft.world.entity.player.Player; 26import net.minecraft.world.level.BlockGetter; 27import net.minecraft.world.level.Level; 28import net.minecraft.world.level.block.Block; 29import net.minecraft.world.level.block.Blocks; 30import net.minecraft.world.level.block.LevelEvent; 31import net.minecraft.world.level.block.RenderShape; 32import net.minecraft.world.level.block.state.BlockState; 33import net.minecraft.world.level.block.state.StateDefinition; 34import net.minecraft.world.level.block.state.properties.BooleanProperty; 35import net.minecraft.world.level.entity.EntityTypeTest; 36import net.minecraft.world.level.storage.LevelResource; 37import net.minecraft.world.phys.AABB; 38import net.minecraft.world.phys.BlockHitResult; 39import net.minecraft.world.phys.shapes.CollisionContext; 40import net.minecraft.world.phys.shapes.Shapes; 41import net.minecraft.world.phys.shapes.VoxelShape; 42import org.apache.commons.io.FileUtils; 43 44import java.io.IOException; 45import java.nio.file.Path; 46 47@MethodsReturnNonnullByDefault 48public class TimeBombBlock extends Block { 49 public static final BooleanProperty ACTIVE = BooleanProperty.create("active"); 50 public static final VoxelShape TOP_SHAPE = Block.box(3, 0, 3, 13, 2, 13); 51 public static final VoxelShape BOTTOM_SHAPE = Block.box(3, 12, 3, 13, 14, 13); 52 public static final VoxelShape INNER_SHAPE = Block.box(4, 2, 4, 12, 12, 12); 53 public static final VoxelShape TIP_SHAPE = Block.box(7, 14, 7, 9, 16, 9); 54 public static final VoxelShape SHAPE = Shapes.or(BOTTOM_SHAPE, TOP_SHAPE, INNER_SHAPE, TIP_SHAPE); 55 @Override 56 public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { 57 return SHAPE; 58 } 59 @Override 60 public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { 61 return SHAPE; 62 } 63 @Override 64 public RenderShape getRenderShape(BlockState state) { 65 return RenderShape.MODEL; 66 } 67 68 public TimeBombBlock(Properties settings) { 69 super(settings); 70 this.registerDefaultState(defaultBlockState().setValue(ACTIVE, false)); 71 } 72 73 @Override 74 protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) { 75 builder.add(ACTIVE); 76 } 77 78 void eraseWorld(ServerLevel world) { 79 ((Timebombable)world).infinity$timebomb(); 80 Path path = world.getServer().getWorldPath(LevelResource.DATAPACK_DIR).resolve(world.dimension().location().getPath()); 81 try { 82 FileUtils.deleteDirectory(path.toFile()); 83 } catch (IOException ignored) { 84 } 85 } 86 87 static AreaEffectCloud genCloud(Level world, BlockPos pos) { 88 AreaEffectCloud e = new AreaEffectCloud(world, pos.getCenter().x(), pos.getCenter().y(), pos.getCenter().z()); 89 //? if >1.21.9 { 90 /*e.setCustomParticle(PowerParticleOption.create(ParticleTypes.DRAGON_BREATH, 1)); 91 *///?} else if >1.21.5 { 92 e.setCustomParticle(ParticleTypes.DRAGON_BREATH); 93 //?} else { 94 /*e.setParticle(ParticleTypes.DRAGON_BREATH); 95 *///?} 96 e.setRadius(1.0f); 97 e.setDuration(3500); 98 e.setRadiusPerTick(0.006f); 99 world.levelEvent(LevelEvent.PARTICLES_DRAGON_FIREBALL_SPLASH, pos, 1); 100 return e; 101 } 102 103 @Override 104 //? if <1.21 { 105 /*public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { 106 *///?} else { 107 protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { 108 //?} 109 if (state.getValue(ACTIVE)) { 110 if (world instanceof ServerLevel w && !InfinityMethods.isTimebombed(w)) { 111 world.setBlockAndUpdate(pos, Blocks.AIR.defaultBlockState()); 112 world.getEntities(EntityTypeTest.forClass(AreaEffectCloud.class), AABB.ofSize(pos.getCenter(), 1.0, 1.0, 1.0), Entity::isAlive). 113 forEach(e -> e.remove(Entity.RemovalReason.DISCARDED)); 114 return InteractionResult.SUCCESS; 115 } //remove after regenerating a dimension 116 return InteractionResult.FAIL; 117 } 118 else if (player.getItemInHand(InteractionHand.MAIN_HAND).isEmpty()) { 119 if (player.isShiftKeyDown()) { 120 if (InfinityMethods.isInfinity(world)) { 121 if (world instanceof ServerLevel w && !InfinityMethods.isTimebombed(w)) { 122 eraseWorld(w); 123 world.addFreshEntity(genCloud(world, pos)); 124 player.awardStat(ModStats.WORLDS_DESTROYED_STAT, 1); 125 ModCriteria.DIMS_CLOSED.get().trigger((ServerPlayer)player); 126 world.setBlockAndUpdate(pos, state.setValue(ACTIVE, true)); 127 world.playSound(null, pos, ModSounds.IVORY_MUSIC_CHALLENGER_EVENT, SoundSource.RECORDS, 1f, 1f); 128 } //activate 129 return InteractionResult.SUCCESS; 130 } 131 else if (world instanceof ServerLevel) { 132 world.playSound(null, pos, ModSounds.portalFail, SoundSource.BLOCKS, 1f, 1f); 133 player.displayClientMessage(Component.translatable("error.infinity.timebomb.fail"), false); 134 } 135 } 136 else { 137 world.setBlockAndUpdate(pos, Blocks.AIR.defaultBlockState()); 138 if (!player.isCreative()) player.getInventory().add(ModItems.TIME_BOMB_ITEM.get().getDefaultInstance()); 139 return InteractionResult.SUCCESS; 140 } //pick up 141 } 142 return InteractionResult.PASS; 143 } 144}