Shockwave visual effects or something

Fixes #118
This commit is contained in:
DBotThePony 2022-10-17 11:25:14 +07:00
parent dd686e23c5
commit e15c426135
Signed by: DBot
GPG Key ID: DCC23B5715498507
5 changed files with 138 additions and 2 deletions

View File

@ -18,7 +18,6 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import ru.dbotthepony.mc.otm.android.AndroidResearchManager;
import ru.dbotthepony.mc.otm.android.feature.EnderTeleporterFeature;
import ru.dbotthepony.mc.otm.android.feature.NanobotsArmorFeature;
import ru.dbotthepony.mc.otm.block.entity.SynchronizedBlockEntity;
import ru.dbotthepony.mc.otm.block.entity.blackhole.ExplosionQueue;
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
@ -31,6 +30,7 @@ import ru.dbotthepony.mc.otm.client.ClientTickHandlerKt;
import ru.dbotthepony.mc.otm.client.MatteryGUI;
import ru.dbotthepony.mc.otm.client.model.GravitationStabilizerModel;
import ru.dbotthepony.mc.otm.client.model.TritaniumArmorModel;
import ru.dbotthepony.mc.otm.client.render.ShockwaveRenderer;
import ru.dbotthepony.mc.otm.client.render.WidgetAtlasHolder;
import ru.dbotthepony.mc.otm.compat.mekanism.QIOKt;
import ru.dbotthepony.mc.otm.compat.mekanism.TooltipsKt;
@ -179,6 +179,8 @@ public final class OverdriveThatMatters {
EVENT_BUS.addListener(EventPriority.NORMAL, MatteryGUI.INSTANCE::onRenderGuiEvent);
EVENT_BUS.addListener(EventPriority.HIGH, MatteryGUI.INSTANCE::onLayerRenderEvent);
EVENT_BUS.addListener(EventPriority.NORMAL, ShockwaveRenderer.INSTANCE::onRender);
EVENT_BUS.addListener(EventPriority.NORMAL, ClientEventHandlerKt::onMovementInputUpdate);
EVENT_BUS.addListener(EventPriority.NORMAL, ClientEventHandlerKt::onScreenOpen);
EVENT_BUS.addListener(EventPriority.NORMAL, ClientEventHandlerKt::onPostScreenInit);

View File

@ -31,9 +31,11 @@ import ru.dbotthepony.mc.otm.core.times
import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.network.MatteryPacket
import ru.dbotthepony.mc.otm.network.ShockwaveEffectPacket
import ru.dbotthepony.mc.otm.network.enqueueWork
import ru.dbotthepony.mc.otm.network.packetHandled
import ru.dbotthepony.mc.otm.network.sender
import ru.dbotthepony.mc.otm.onceServer
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
import ru.dbotthepony.mc.otm.registry.MNames
import ru.dbotthepony.mc.otm.registry.ShockwaveDamageSource
@ -54,7 +56,9 @@ object TriggerShockwavePacket : MatteryPacket {
val shockwave = context.sender?.matteryPlayer?.getFeature(AndroidFeatures.SHOCKWAVE) as ShockwaveFeature? ?: return@enqueueWork
if (!shockwave.isOnCooldown && shockwave.isActive && shockwave.airTicks > 0) {
shockwave.shockwave()
onceServer { // delay by one tick so player update its position as well
shockwave.shockwave()
}
}
}
}
@ -93,6 +97,7 @@ class ShockwaveFeature(capability: MatteryPlayerCapability) : AndroidSwitchableF
if (ply is ServerPlayer) {
ShockwaveTrigger.trigger(ply as ServerPlayer)
MatteryPlayerNetworkChannel.sendTrackingAndSelf(ply, ShockwaveEffectPacket(ply.position))
}
// TODO: raycasting

View File

@ -0,0 +1,87 @@
package ru.dbotthepony.mc.otm.client.render
import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.blaze3d.vertex.BufferUploader
import com.mojang.blaze3d.vertex.DefaultVertexFormat
import com.mojang.blaze3d.vertex.VertexFormat
import com.mojang.math.Vector3f
import net.minecraft.client.renderer.GameRenderer
import net.minecraftforge.client.event.RenderLevelStageEvent
import org.lwjgl.opengl.GL11.GL_LESS
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.core.Vector
import ru.dbotthepony.mc.otm.core.component1
import ru.dbotthepony.mc.otm.core.component2
import ru.dbotthepony.mc.otm.core.component3
import ru.dbotthepony.mc.otm.core.linearInterpolation
import ru.dbotthepony.mc.otm.core.position
import ru.dbotthepony.mc.otm.network.ShockwaveEffectPacket
import kotlin.math.PI
object ShockwaveRenderer {
private val activeShockwaves = ArrayList<State>()
private class State(val pos: Vector, val finalRadius: Float = 6f) {
var radius = 0f
var lastRender = System.nanoTime()
init {
synchronized(activeShockwaves) {
activeShockwaves.add(this)
}
}
fun render(event: RenderLevelStageEvent): Boolean {
val diff = System.nanoTime() - lastRender
radius += diff / (1_000_000_000f / EXPANSION_PER_SECOND)
lastRender = System.nanoTime()
if (radius <= finalRadius) {
val builder = tesselator.builder
RenderSystem.setShader(GameRenderer::getPositionShader)
RenderSystem.setShaderColor(1f, 1f, 1f, linearInterpolation(radius / finalRadius, 0.5f, 0f))
RenderSystem.defaultBlendFunc()
RenderSystem.enableBlend()
RenderSystem.enableDepthTest()
RenderSystem.depthFunc(GL_LESS)
builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION)
event.poseStack.pushPose()
val (x, y, z) = event.camera.position
event.poseStack.translate(pos.x - x, pos.y - y + 0.1f, pos.z - z) // render slightly above landed position
event.poseStack.mulPose(Vector3f.XP.rotation(PI.toFloat() / 2f))
uploadArc(event.poseStack.last.pose, builder, x = 0f, y = 0f, innerRadius = (radius - 1f).coerceAtLeast(0f), outerRadius = radius, triangleFan = false)
event.poseStack.popPose()
BufferUploader.drawWithShader(builder.end())
}
return radius <= finalRadius
}
}
private const val EXPANSION_PER_SECOND = 18f
fun onRender(event: RenderLevelStageEvent) {
if (event.stage !== RenderLevelStageEvent.Stage.AFTER_TRANSLUCENT_BLOCKS) {
return
}
synchronized(activeShockwaves) {
val iterator = activeShockwaves.listIterator()
for (value in iterator) {
if (!value.render(event)) {
iterator.remove()
}
}
}
}
fun handle(packet: ShockwaveEffectPacket) {
State(packet.pos)
}
}

View File

@ -4,12 +4,14 @@ import java.util.function.Function
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.player.Player
import net.minecraftforge.network.NetworkDirection
import net.minecraftforge.network.NetworkEvent
import net.minecraftforge.network.NetworkRegistry
import net.minecraftforge.network.PacketDistributor
import net.minecraftforge.network.simple.SimpleChannel
import ru.dbotthepony.mc.otm.NULLABLE_MINECRAFT_SERVER
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import java.math.BigDecimal
import java.math.BigInteger
@ -61,6 +63,22 @@ abstract class MatteryNetworkChannel(val version: String, val name: String) {
}
}
fun sendTracking(entity: Entity, packet: Any) {
if ((NULLABLE_MINECRAFT_SERVER?.playerCount ?: 0) <= 0) {
return
}
channel.send(PacketDistributor.TRACKING_ENTITY.with { entity }, packet)
}
fun sendTrackingAndSelf(entity: Entity, packet: Any) {
if ((NULLABLE_MINECRAFT_SERVER?.playerCount ?: 0) <= 0) {
return
}
channel.send(PacketDistributor.TRACKING_ENTITY_AND_SELF.with { entity }, packet)
}
fun send(distributor: PacketDistributor.PacketTarget, packet: Any) = channel.send(distributor, packet)
private var nextNetworkPacketID = 0

View File

@ -6,12 +6,14 @@ import net.minecraft.network.chat.Component
import net.minecraft.network.protocol.game.ClientboundSetCarriedItemPacket
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.ItemStack
import net.minecraftforge.network.NetworkDirection.PLAY_TO_CLIENT
import net.minecraftforge.network.NetworkDirection.PLAY_TO_SERVER
import net.minecraftforge.network.NetworkEvent
import net.minecraftforge.network.PacketDistributor
import org.apache.logging.log4j.LogManager
import ru.dbotthepony.mc.otm.android.AndroidActiveFeature
import ru.dbotthepony.mc.otm.android.AndroidFeatureType
@ -24,8 +26,10 @@ import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.client.MatteryGUI
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.client.render.GlitchRenderer
import ru.dbotthepony.mc.otm.client.render.ShockwaveRenderer
import ru.dbotthepony.mc.otm.container.get
import ru.dbotthepony.mc.otm.container.set
import ru.dbotthepony.mc.otm.core.Vector
import ru.dbotthepony.mc.otm.menu.AndroidStationMenu
import ru.dbotthepony.mc.otm.menu.ExoSuitInventoryMenu
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
@ -448,6 +452,25 @@ class GlitchPacket(val millis: Long) : MatteryPacket {
}
}
class ShockwaveEffectPacket(val pos: Vector) : MatteryPacket {
override fun write(buff: FriendlyByteBuf) {
buff.writeDouble(pos.x)
buff.writeDouble(pos.y)
buff.writeDouble(pos.z)
}
override fun play(context: Supplier<NetworkEvent.Context>) {
context.packetHandled = true
ShockwaveRenderer.handle(this)
}
companion object {
fun read(buff: FriendlyByteBuf): ShockwaveEffectPacket {
return ShockwaveEffectPacket(Vector(buff.readDouble(), buff.readDouble(), buff.readDouble()))
}
}
}
object MatteryPlayerNetworkChannel : MatteryNetworkChannel(
version = "1",
name = "player"
@ -477,5 +500,6 @@ object MatteryPlayerNetworkChannel : MatteryNetworkChannel(
add(PickItemFromInventoryPacket::class, PickItemFromInventoryPacket.Companion::read, PLAY_TO_SERVER)
add(GlitchPacket::class, GlitchPacket.Companion::read, PLAY_TO_CLIENT)
add(ShockwaveEffectPacket::class, ShockwaveEffectPacket.Companion::read, PLAY_TO_CLIENT)
}
}