Block Wave Effect [From MCreative] [1.19.2/1.20.1, potentially 1.20.4+]

Started by Kleiders on

Topic category: User side tutorials

Joined Dec 2016
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
Block Wave Effect [From MCreative] [1.19.2/1.20.1, potentially 1.20.4+]
Thu, 08/08/2024 - 23:39 (edited)

This tutorial is provided by the MCreative Discord server!

Join us to get help, see more of our tutorials, or just chat with others

 

First, create a custom element named "Wave Effect". This is where we will store most of the wave logic. After that, copy this code, but replace "YourMod" with the main class of your mod. By default, it should be your Mod name starting with caps, but you can check the actual name by creating a "wait" block, and it will show as "YourMod.queueServerWork("

public class WaveEffect {
    public static void createShockwave(Level world, BlockPos center, int maxRadius, int damage) {
        for (int radius = 2; radius <= maxRadius; radius++) {
            for (BlockPos pos : getRing(center, radius)) {
                //Replace "YourMod" with the actual Mod class, in my case it's "BoltzyBreezeMod"
                YourMod.queueServerWork(radius * 4, () -> {
                    //Some Particles
                    if (world instanceof ServerLevel _level)
                        _level.getServer().getCommands().performPrefixedCommand(
                                new CommandSourceStack(CommandSource.NULL, new Vec3(pos.getX() + 0.5, (pos.getY() + 1.1), pos.getZ() + 0.5), Vec2.ZERO, _level, 4, "", Component.literal(""), _level.getServer(), null).withSuppressedOutput(),
                                ("/particle sweep_attack ~ ~ ~ 0 0 0 1 0 normal"));
                    // Displace the block at the current position
                    if (world.getBlockState(pos).getBlock() != Blocks.AIR) {
                        if (!((world.getBlockState(pos)).getBlock() == Blocks.WATER) && !world.isEmptyBlock(pos)) {
                            if (world instanceof ServerLevel _level)
                                _level.getServer().getCommands().performPrefixedCommand(
                                        new CommandSourceStack(CommandSource.NULL, new Vec3(pos.getX() + 0.5, (pos.getY()), pos.getZ() + 0.5), Vec2.ZERO, _level, 4, "", Component.literal(""), _level.getServer(), null).withSuppressedOutput(),
                                        ("/summon falling_block ~ ~1 ~ {BlockState:{Name:\"" + "" + ForgeRegistries.BLOCKS.getKey((world.getBlockState(pos)).getBlock()).toString() + "\"},Time:1,Motion:[" + "0.0,"
                                                + new java.text.DecimalFormat("##.##").format(0.2) + ",0.0" + "]}"));
                            if (world instanceof ServerLevel _level)
                                _level.getServer().getCommands().performPrefixedCommand(
                                        new CommandSourceStack(CommandSource.NULL, new Vec3(pos.getX() + 0.5, (pos.getY()), pos.getZ() + 0.5), Vec2.ZERO, _level, 4, "", Component.literal(""), _level.getServer(), null).withSuppressedOutput(),
                                        ("/fill ~ ~ ~ ~ ~ ~ air replace"));
                        }
                    }
                    // Damage entities within the current position
                    AABB aabb = new AABB(pos).inflate(0.5);
                    for (Entity entity : world.getEntitiesOfClass(LivingEntity.class, aabb)) {
                        if (entity instanceof Player) {

                            continue;

                        }
                        entity.hurt(new DamageSource(world.registryAccess().registryOrThrow(Registries.DAMAGE_TYPE).getHolderOrThrow(DamageTypes.FALL)), damage);
                        entity.setDeltaMovement(entity.getDeltaMovement().x(), 1.1, entity.getDeltaMovement().z);
                    }
                });
            }
        }
    }

    // Helper method to get a ring of blocks at a specific radius
    private static Iterable<BlockPos> getRing(BlockPos center, int radius) {
        List<BlockPos> positions = new ArrayList<>();
        for (int dx = -radius; dx <= radius; dx++) {
            for (int dz = -radius; dz <= radius; dz++) {
                if (Math.sqrt(dx * dx + dz * dz) >= radius - 0.5 && Math.sqrt(dx * dx + dz * dz) <= radius + 0.5) {
                    positions.add(center.offset(dx, 0, dz));
                }
            }
        }
        return positions;
    }
}

After pasting that code, press Ctrl + W to make it generate imports

 

To trigger this code, you will need the following procedure:
Execute command trigger to load dependencies
The empty command is neccesary to load dependencies onto the procedure

The code in the snippets is:
Snippet 1 (This is where the wave starts):  BlockPos center = new BlockPos((int)x, (int)y - 1,(int)z);
Snippet 2  (This triggers the wave): WaveEffect.createShockwave((Level)world, center, 8, 20);

Video showcase: https://i.imgur.com/keLMqzH.mp4

 

Edited by Kleiders on Thu, 08/08/2024 - 23:39