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