エクストリーム・エクスプロージョン・デモ
私は非常にブロックを爆発Minecraft modを書きます.
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()
}
}
Reference
この問題について(エクストリーム・エクスプロージョン・デモ), 我々は、より多くの情報をここで見つけました https://dev.to/nshmura/minecraft-forge-1-16-continuous-explosion-mod-26ioテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol