DEV Community

nshmura
nshmura

Posted on

[Minecraft][Forge 1.16] Extrem Explosion Mod

I write minecraft mod which explode blocks extremely.

screenshot

package com.nshmura.doromod;

import net.minecraft.client.Minecraft
import net.minecraft.util.ResourceLocation
import net.minecraft.util.math.vector.Vector3d
import net.minecraft.world.Explosion
import net.minecraftforge.common.MinecraftForge
import net.minecraftforge.event.TickEvent
import net.minecraftforge.event.entity.player.PlayerInteractEvent
import net.minecraftforge.eventbus.api.SubscribeEvent
import net.minecraftforge.fml.common.Mod
import net.minecraftforge.fml.network.NetworkEvent
import net.minecraftforge.fml.network.NetworkRegistry
import net.minecraftforge.fml.network.simple.SimpleChannel
import net.minecraftforge.fml.server.ServerLifecycleHooks
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Logger
import java.util.function.Supplier


@Mod(ExampleMod.MOD_ID)
class ExampleMod {
    private val logger: Logger = LogManager.getLogger(MOD_ID)

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

    private var explosions: List<ContinuousExplosion> = emptyList()

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

        MinecraftForge.EVENT_BUS.register(this)
    }

    @SubscribeEvent
    fun on(event: PlayerInteractEvent.LeftClickEmpty) {
        val loc = Minecraft.getInstance().hitResult?.location
            ?: return
        logger.info("[HIT] ${loc.x} ${loc.y} ${loc.z}")

        explosions = explosions.plus(ContinuousExplosion(event, loc))
    }

    @SubscribeEvent
    fun on(event: TickEvent.ClientTickEvent) {
        explosions = explosions.mapNotNull {
            it.tick(event) { message ->
                channel.sendToServer(message)
                logger.info("[POS] ${message.x} ${message.y} ${message.z}")
            }
        }
    }

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

        ServerLifecycleHooks.getCurrentServer().overworld().explode(
            null,
            message.x,
            message.y,
            message.z,
            message.size,
            Explosion.Mode.BREAK
        )
    }

    companion object {
        const val MOD_ID: String = "doro_mod"
        private const val PROTOCOL_VERSION = "1"
    }
}

class ContinuousExplosion(
    private val event: PlayerInteractEvent.LeftClickEmpty,
    private val location: Vector3d
) {
    private var explodeCount = 0
    private var tickCount = 0

    fun tick(tick: TickEvent, handler: (ExplosionMessage) -> Unit): ContinuousExplosion? {
        if (tick.phase != TickEvent.Phase.START) {
            return this
        }
        tickCount++
        if (tickCount % WAIT_TICK != 0) {
            return this
        }

        val pos = moveTo(location, event.player.lookAngle, explodeCount * EXPLODE_DISTANCE)
        handler(ExplosionMessage(pos.x, pos.y, pos.z, EXPLODE_SIZE))

        explodeCount++
        return if (explodeCount >= EXPLODE_COUNT) {
            null
        } else {
            this
        }
    }

    private fun moveTo(position: Vector3d, angle: Vector3d, multiply: Double) =
        Vector3d(
            position.x + angle.x * multiply,
            position.y + angle.y * multiply,
            position.z + angle.z * multiply
        )

    companion object {
        private const val WAIT_TICK = 5
        private const val EXPLODE_COUNT = 25
        private const val EXPLODE_SIZE = 16F
        private const val EXPLODE_DISTANCE = 5.toDouble()
    }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
javana1 profile image
Javana1 • Edited

"Before you start programming, plan your strategy. Writing this exploding projectile mod is not as difficult as the minigame mod, but you must still design its complex parts.
First, you need to define these two actions to make the block.
Run when you start the mod.
Explode when it lands.
I like Minecraft servers for prison better. You can program much cool stuff there and explosions, among other things.
Once you start your block, you must make it explode when it hits the ground. You can browse LearnToMod's blocks to find a blast creation block in the Minecraft → World category that you can use to make the block explode when it hits the ground."