Topic category: User side tutorials
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:
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