DEV Community

nshmura
nshmura

Posted on

[Minecraft - Forge 1.16] Make explosion from client.

I built Explosion Mod in following sequence.

  1. Receive PlayerInteractEvent.LeftClickEmpty in client side.
  2. Send ExplosionMessage to server side.
  3. Make explosion in server side.

Code is written in Kotlin.

First, make ExplosionMessage class.

class ExplosionMessage(
    val x: Double,
    val y: Double,
    val z: Double
) {

    companion object {
        fun encode(message: ExplosionMessage, buf: PacketBuffer) {
            buf.writeDouble(message.x)
            buf.writeDouble(message.y)
            buf.writeDouble(message.z)
        }

        fun from(buf: PacketBuffer): ExplosionMessage {
            return ExplosionMessage(
                buf.readDouble(),
                buf.readDouble(),
                buf.readDouble()
            )
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Prepare SimpleChannel.

class ExampleMod {

    private val channel: SimpleChannel = NetworkRegistry.newSimpleChannel(
        ResourceLocation(MOD_ID, "main"),
        { PROTOCOL_VERSION },
        PROTOCOL_VERSION::equals,
        PROTOCOL_VERSION::equals
    )

    init {
        channel.registerMessage(
            0,
            ExplosionMessage::class.java,
            ExplosionMessage::encode,
            ExplosionMessage::from,
            this::handle
        )

        MinecraftForge.EVENT_BUS.register(this)
    }

    ...
Enter fullscreen mode Exit fullscreen mode

Receive PlayerInteractEvent.LeftClickEmpty.
This event is occurred in client side only.

    @SubscribeEvent
    fun on(event: PlayerInteractEvent.LeftClickEmpty) {
        val loc = Minecraft.getInstance().hitResult?.location
        if (loc == null) {
            return
        }

        logger.info("ExplosionMessage send: ${loc?.x} ${loc?.y} ${loc?.z} ")
        channel.sendToServer(ExplosionMessage(loc.x, loc.y, loc.z))
    }
Enter fullscreen mode Exit fullscreen mode

Handle ExplosionMessage.

    fun handle(message: ExplosionMessage, context: Supplier<NetworkEvent.Context>) {
        logger.info("ExplosionMessage received: ${message.x} ${message.y}  ${message.z} ")

        ServerLifecycleHooks.getCurrentServer().overworld().explode(
            null,
            message.x,
            message.y,
            message.z,
            4.0F,
            Explosion.Mode.BREAK
        )
    }
Enter fullscreen mode Exit fullscreen mode

Now we can explode any place where we want!
Screenshot

Discussion (0)