From dc23a1b947532332c85500b1b41a98eae1244857 Mon Sep 17 00:00:00 2001 From: alex_s168 <63254202+alex-s168@users.noreply.github.com> Date: Sat, 3 Aug 2024 11:24:33 +0000 Subject: [PATCH] finally properly rendering fuel tanks --- .../mixin/client/MixinMinecraft.java | 17 ++ ...CopiedFromCreateSuperRenderTypeBuffer.java | 93 +++++++ .../org/valkyrienskies/tournament/Shafts.kt | 242 ++++++++++++++---- .../tournament/TournamentEvents.kt | 1 + .../tournament/TournamentModels.kt | 21 ++ .../tournament/TournamentNetworking.kt | 109 ++++++-- .../TransparentFuelTankBlockEntityRender.kt | 27 +- .../tournament/blocks/FuelTankBlock.kt | 5 + .../tournament/ship/TournamentShips.kt | 3 +- .../textures/block/fuel_tank_half_solid.png | Bin 218 -> 209 bytes .../vs_tournament-common.mixins.json | 3 +- 11 files changed, 441 insertions(+), 80 deletions(-) create mode 100644 common/src/main/java/org/valkyrienskies/tournament/mixin/client/MixinMinecraft.java create mode 100644 common/src/main/java/org/valkyrienskies/tournament/util/rend/DefinitelyNotCopiedFromCreateSuperRenderTypeBuffer.java diff --git a/common/src/main/java/org/valkyrienskies/tournament/mixin/client/MixinMinecraft.java b/common/src/main/java/org/valkyrienskies/tournament/mixin/client/MixinMinecraft.java new file mode 100644 index 0000000..af7a08b --- /dev/null +++ b/common/src/main/java/org/valkyrienskies/tournament/mixin/client/MixinMinecraft.java @@ -0,0 +1,17 @@ +package org.valkyrienskies.tournament.mixin.client; + +import kotlin.Unit; +import net.minecraft.client.Minecraft; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.valkyrienskies.tournament.TournamentEvents; + +@Mixin(Minecraft.class) +public class MixinMinecraft { + @Inject(at = @At("TAIL"), method = "runTick") + private void runTick(boolean renderLevel, CallbackInfo ci) { + TournamentEvents.INSTANCE.getClientTick().emit(Unit.INSTANCE); + } +} diff --git a/common/src/main/java/org/valkyrienskies/tournament/util/rend/DefinitelyNotCopiedFromCreateSuperRenderTypeBuffer.java b/common/src/main/java/org/valkyrienskies/tournament/util/rend/DefinitelyNotCopiedFromCreateSuperRenderTypeBuffer.java new file mode 100644 index 0000000..cad0ad3 --- /dev/null +++ b/common/src/main/java/org/valkyrienskies/tournament/util/rend/DefinitelyNotCopiedFromCreateSuperRenderTypeBuffer.java @@ -0,0 +1,93 @@ +package org.valkyrienskies.tournament.util.rend; + +import com.mojang.blaze3d.vertex.BufferBuilder; +import com.mojang.blaze3d.vertex.VertexConsumer; +import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap; +import net.minecraft.Util; +import net.minecraft.client.renderer.ChunkBufferBuilderPack; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.Sheets; +import net.minecraft.client.resources.model.ModelBakery; + +import java.util.SortedMap; + +public class DefinitelyNotCopiedFromCreateSuperRenderTypeBuffer implements MultiBufferSource { + + private static final DefinitelyNotCopiedFromCreateSuperRenderTypeBuffer INSTANCE = new DefinitelyNotCopiedFromCreateSuperRenderTypeBuffer(); + + public static DefinitelyNotCopiedFromCreateSuperRenderTypeBuffer getInstance() { + return INSTANCE; + } + + private SuperRenderTypeBufferPhase earlyBuffer; + private SuperRenderTypeBufferPhase defaultBuffer; + private SuperRenderTypeBufferPhase lateBuffer; + + public DefinitelyNotCopiedFromCreateSuperRenderTypeBuffer() { + earlyBuffer = new SuperRenderTypeBufferPhase(); + defaultBuffer = new SuperRenderTypeBufferPhase(); + lateBuffer = new SuperRenderTypeBufferPhase(); + } + + public VertexConsumer getEarlyBuffer(RenderType type) { + return earlyBuffer.bufferSource.getBuffer(type); + } + + @Override + public VertexConsumer getBuffer(RenderType type) { + return defaultBuffer.bufferSource.getBuffer(type); + } + + public VertexConsumer getLateBuffer(RenderType type) { + return lateBuffer.bufferSource.getBuffer(type); + } + + public void draw() { + earlyBuffer.bufferSource.endBatch(); + defaultBuffer.bufferSource.endBatch(); + lateBuffer.bufferSource.endBatch(); + } + + public void draw(RenderType type) { + earlyBuffer.bufferSource.endBatch(type); + defaultBuffer.bufferSource.endBatch(type); + lateBuffer.bufferSource.endBatch(type); + } + + private static class SuperRenderTypeBufferPhase { + + // Visible clones from RenderBuffers + private final ChunkBufferBuilderPack fixedBufferPack = new ChunkBufferBuilderPack(); + private final SortedMap fixedBuffers = Util.make(new Object2ObjectLinkedOpenHashMap<>(), map -> { + map.put(Sheets.solidBlockSheet(), fixedBufferPack.builder(RenderType.solid())); + map.put(Sheets.cutoutBlockSheet(), fixedBufferPack.builder(RenderType.cutout())); + map.put(Sheets.bannerSheet(), fixedBufferPack.builder(RenderType.cutoutMipped())); + map.put(Sheets.translucentCullBlockSheet(), fixedBufferPack.builder(RenderType.translucent())); + put(map, Sheets.shieldSheet()); + put(map, Sheets.bedSheet()); + put(map, Sheets.shulkerBoxSheet()); + put(map, Sheets.signSheet()); + put(map, Sheets.chestSheet()); + put(map, RenderType.translucentNoCrumbling()); + put(map, RenderType.armorGlint()); + put(map, RenderType.armorEntityGlint()); + put(map, RenderType.glint()); + put(map, RenderType.glintDirect()); + put(map, RenderType.glintTranslucent()); + put(map, RenderType.entityGlint()); + put(map, RenderType.entityGlintDirect()); + put(map, RenderType.waterMask()); + ModelBakery.DESTROY_TYPES.forEach((p_173062_) -> { + put(map, p_173062_); + }); + }); + private final MultiBufferSource.BufferSource bufferSource = MultiBufferSource.immediateWithBuffers(fixedBuffers, new BufferBuilder(256)); + + private static void put(Object2ObjectLinkedOpenHashMap map, RenderType type) { + map.put(type, new BufferBuilder(type.bufferSize())); + } + + } + +} diff --git a/common/src/main/kotlin/org/valkyrienskies/tournament/Shafts.kt b/common/src/main/kotlin/org/valkyrienskies/tournament/Shafts.kt index d4213cf..974ee01 100644 --- a/common/src/main/kotlin/org/valkyrienskies/tournament/Shafts.kt +++ b/common/src/main/kotlin/org/valkyrienskies/tournament/Shafts.kt @@ -1,10 +1,14 @@ package org.valkyrienskies.tournament +import net.minecraft.client.multiplayer.ClientLevel import net.minecraft.core.BlockPos import net.minecraft.core.Direction import net.minecraft.server.level.ServerLevel +import net.minecraft.world.level.BlockGetter import net.minecraft.world.level.ChunkPos import net.minecraft.world.level.block.state.BlockState +import java.util.concurrent.CopyOnWriteArrayList +import kotlin.math.abs import kotlin.math.max import kotlin.math.min @@ -24,15 +28,56 @@ interface ShaftConsumer { fun dobreak(level: ServerLevel, pos: BlockPos, state: BlockState) } -class Shaft( - val level: ServerLevel, +interface CommonShaft { + val level: L val dir: Direction.Axis -) { + + val shaftChunks: MutableSet + val shaftBlocks: MutableSet> + + fun addShaftBlock(pos: BlockPos) { + val cp = ChunkPos(pos) + shaftBlocks += cp to pos + shaftChunks += cp + } + + fun removeShaftBlock(pos: BlockPos) { + val cp = ChunkPos(pos) + shaftBlocks -= cp to pos + val remaining = shaftBlocks.count { it.first == cp } + if (remaining == 0) { + shaftChunks -= cp + } + } +} + +class ClientShaft( + override val level: ClientLevel, + override val dir: Direction.Axis +): CommonShaft { + override val shaftChunks = mutableSetOf() + override val shaftBlocks = mutableSetOf>() + + var speed = 0.0f + + var visualRotation = 0.0f + private set + + internal fun tick() { + visualRotation -= speed + visualRotation %= 360.0f + } +} + +class ServerShaft( + override val level: ServerLevel, + override val dir: Direction.Axis +): CommonShaft { // should only be 2 val consumer = mutableListOf>() val statsThisTick = ShaftStats().also { it.reset() } - val shaftChunks = mutableSetOf() - val shaftBlocks = mutableSetOf>() + override val shaftChunks = mutableSetOf() + override val shaftBlocks = mutableSetOf>() fun wantSpeeds(): ClosedFloatingPointRange? { val all = consumer.map { it.second.wantSpeeds(level, it.first, level.getBlockState(it.first)) } @@ -51,33 +96,22 @@ class Shaft( } } - fun addShaftBlock(pos: BlockPos) { - val cp = ChunkPos(pos) - shaftBlocks += cp to pos - shaftChunks += cp - } - - fun removeShaftBlock(pos: BlockPos) { - val cp = ChunkPos(pos) - shaftBlocks -= cp to pos - val remaining = shaftBlocks.count { it.first == cp } - if (remaining == 0) { - shaftChunks -= cp - } - } - - fun mergeFrom(other: Shaft) { + fun mergeFrom(other: ServerShaft) { consumer += other.consumer shaftChunks += other.shaftChunks shaftBlocks += other.shaftBlocks } fun apply(force: Float, speed: Float) { - val effect = statsThisTick.force / force + val old = statsThisTick.force statsThisTick.force += force + val diff = statsThisTick.force - old + val effect = diff / statsThisTick.force + statsThisTick.speed *= speed * effect } + private var lastSpeed = 0.0f internal fun tick() { consumer.forEach { (pos, cons) -> val state = level.getBlockState(pos) @@ -85,8 +119,49 @@ class Shaft( cons.dobreak(level, pos, state) else cons.consume(level, pos, state, statsThisTick) } + + val diffSpeed = abs(lastSpeed - statsThisTick.speed) + if (diffSpeed > 0.5f) { + val first = shaftBlocks.first().second + TournamentNetworking.ShaftSpeedChange( + first.asLong(), + TournamentNetworking.ShaftSpeedChange.getAxis(dir), + statsThisTick.speed + ) + } + lastSpeed = statsThisTick.speed + statsThisTick.reset() } + + private fun alreadyAddedToParent() = + this in ServerShaftMan.get(level).shafts + + override fun addShaftBlock(pos: BlockPos) { + super.addShaftBlock(pos) + if (alreadyAddedToParent() && shaftBlocks.isNotEmpty()) { + val first = shaftBlocks.first().second + if (pos == first) return + TournamentNetworking.ShaftBlockChange( + first.asLong(), + listOf(pos.asLong()), + false + ).send() + } + } + + override fun removeShaftBlock(pos: BlockPos) { + super.removeShaftBlock(pos) + if (alreadyAddedToParent() && shaftBlocks.isNotEmpty()) { + val first = shaftBlocks.first().second + if (pos == first) return + TournamentNetworking.ShaftBlockChange( + first.asLong(), + listOf(pos.asLong()), + true + ).send() + } + } } fun Direction.Axis.directions() = @@ -102,19 +177,13 @@ fun BlockPos.posOnAxis(axis: Direction.Axis) = fun BlockPos.neighborBlocks() = listOf(this.above(), this.below(), this.north(), this.south(), this.east(), this.west()) -class ShaftMan(val level: ServerLevel) { - val shafts = mutableListOf() - - init { - TickScheduler.serverTickPerm { - shafts.forEach(Shaft::tick) - } - } +abstract class CommonShaftMan, L: BlockGetter>(val level: L) { + abstract val shafts: List fun shaftsInChunk(chunk: ChunkPos) = shafts.filter { chunk in it.shaftChunks } - fun shaftsAdjacentTo(pos: BlockPos): List { + fun shaftsAdjacentTo(pos: BlockPos): List { val toSearch = pos.neighborBlocks() + pos val interestingChunks = toSearch.map(::ChunkPos).toSet() val a = interestingChunks @@ -123,9 +192,89 @@ class ShaftMan(val level: ServerLevel) { return a } - fun shaftAdjacentTo(pos: BlockPos, axis: Direction.Axis): Shaft? = + fun shaftAdjacentTo(pos: BlockPos, axis: Direction.Axis): S? = shaftsAdjacentTo(pos).find { it.dir == axis } + fun shaftAt(pos: BlockPos): S? { + val cp = ChunkPos(pos) + return shafts.find { + cp in it.shaftChunks && + it.shaftBlocks.any { it.first == pos } + } + } +} + +class ClientShaftMan private constructor(level: ClientLevel): CommonShaftMan(level) { + override val shafts = CopyOnWriteArrayList() + + init { + TournamentEvents.clientTick.on { _ -> + shafts.forEach(ClientShaft::tick) + } + } + + fun eraseShaft(pos: BlockPos) { + shaftAt(pos)?.let(shafts::remove) + } + + fun getOrCreateShaft(pos: BlockPos, dir: Direction.Axis) = + shaftAt(pos) ?: ClientShaft(level, dir).also { + it.addShaftBlock(pos) + shafts.add(it) + } + + companion object { + private val all = mutableMapOf() + + fun get(level: ClientLevel) = + all.computeIfAbsent(level) { ClientShaftMan(it) } + } +} + +class ServerShaftMan private constructor(level: ServerLevel): CommonShaftMan(level) { + override val shafts = mutableListOf() + + private fun shaftAdd(shaft: ServerShaft) { + shafts += shaft + val shaftPos = shaft.shaftBlocks.first().second.asLong() + TournamentNetworking.ShaftSpeedChange( + shaftPos, + TournamentNetworking.ShaftSpeedChange.getAxis(shaft.dir), + 0.0f + ).send() + if (shaft.shaftBlocks.isNotEmpty()) { + val packed = shaft.shaftBlocks.mapNotNull { (_, pos) -> + val l = pos.asLong() + + if (l == shaftPos) null + else l + } + + TournamentNetworking.ShaftBlockChange( + shaftPos, + packed, + false + ).send() + } + } + + private fun shaftRemove(shaft: ServerShaft) { + shafts -= shaft + shaft.shaftBlocks.firstOrNull()?.second?.asLong()?.let { shaftPos -> + TournamentNetworking.ShaftBlockChange( + shaftPos, + listOf(shaftPos), + true + ).send() + } + } + + init { + TickScheduler.serverTickPerm { + shafts.forEach(ServerShaft::tick) + } + } + fun addConsumer(pos: BlockPos, block: ShaftConsumer, axis: Direction.Axis) { shaftAdjacentTo(pos, axis)?.let { it.consumer += pos to block } } @@ -136,25 +285,16 @@ class ShaftMan(val level: ServerLevel) { } } - @Deprecated(message = "Should not be used") - fun shaftAt(pos: BlockPos): Shaft? { - val cp = ChunkPos(pos) - return shafts.find { - cp in it.shaftChunks && - it.shaftBlocks.any { it.first == pos } - } - } - // remove / split fun removeShaft(pos: BlockPos) { val shaft = shaftAt(pos) ?: return shaft.removeShaftBlock(pos) val groups = shaft.shaftBlocks.groupBy { (it.second.posOnAxis(shaft.dir) - pos.posOnAxis(shaft.dir)) > 0 }.values val consumers = shaft.consumer.groupBy { (it.first.posOnAxis(shaft.dir) - pos.posOnAxis(shaft.dir)) > 0 }.values - shafts -= shaft - shafts += groups.zip(consumers).mapNotNull { (it, consumer) -> + shaftRemove(shaft) + groups.zip(consumers).mapNotNull { (it, consumer) -> if (it.isNotEmpty()) { - val res = Shaft(level, shaft.dir) + val res = ServerShaft(level, shaft.dir) res.consumer += consumer it.forEach { (cp, bp) -> @@ -164,28 +304,28 @@ class ShaftMan(val level: ServerLevel) { res } else null - } + }.forEach(::shaftAdd) } // extend neighbor shaft or create new shaft - fun placeOrGetShaft(pos: BlockPos, dir: Direction.Axis): Shaft { + fun placeOrGetShaft(pos: BlockPos, dir: Direction.Axis): ServerShaft { val a = shaftsAdjacentTo(pos) .filter { it.dir == dir } a.firstOrNull { it.shaftBlocks.any { it.first == pos } }?.let { return it } - val merge = a + Shaft(level, dir).also { it.addShaftBlock(pos) } + val merge = a + ServerShaft(level, dir).also { it.addShaftBlock(pos) } val acc = merge.first() - merge.forEach(shafts::remove) + merge.forEach(::shaftRemove) merge.drop(1).forEach { acc.mergeFrom(it) } - shafts += acc + shaftAdd(acc) return acc } companion object { - private val all = mutableMapOf() + private val all = mutableMapOf() fun get(level: ServerLevel) = - all.computeIfAbsent(level) { ShaftMan(it) } + all.computeIfAbsent(level) { ServerShaftMan(it) } } } diff --git a/common/src/main/kotlin/org/valkyrienskies/tournament/TournamentEvents.kt b/common/src/main/kotlin/org/valkyrienskies/tournament/TournamentEvents.kt index 4e0bca9..7d100a1 100644 --- a/common/src/main/kotlin/org/valkyrienskies/tournament/TournamentEvents.kt +++ b/common/src/main/kotlin/org/valkyrienskies/tournament/TournamentEvents.kt @@ -8,6 +8,7 @@ import org.valkyrienskies.core.impl.util.events.EventEmitterImpl object TournamentEvents { val itemHoverText = EventEmitterImpl() + val clientTick = EventEmitterImpl() data class ItemHoverText( val stack: ItemStack, diff --git a/common/src/main/kotlin/org/valkyrienskies/tournament/TournamentModels.kt b/common/src/main/kotlin/org/valkyrienskies/tournament/TournamentModels.kt index 2903977..25a5f92 100644 --- a/common/src/main/kotlin/org/valkyrienskies/tournament/TournamentModels.kt +++ b/common/src/main/kotlin/org/valkyrienskies/tournament/TournamentModels.kt @@ -8,6 +8,7 @@ import net.minecraft.client.resources.model.BakedModel import net.minecraft.resources.ResourceLocation import net.minecraft.world.level.block.entity.BlockEntity import org.valkyrienskies.tournament.services.TournamentPlatformHelper +import org.valkyrienskies.tournament.util.rend.DefinitelyNotCopiedFromCreateSuperRenderTypeBuffer object TournamentModels { @@ -45,6 +46,26 @@ object TournamentModels { getModel(resourceLocation) } + fun renderNow(matrixStack: PoseStack, blockEntity: BlockEntity, packedOverlay: Int) { + val level = blockEntity.level ?: return + val modRend = Minecraft.getInstance().blockRenderer.modelRenderer + + val buf = DefinitelyNotCopiedFromCreateSuperRenderTypeBuffer.getInstance() + modRend.tesselateWithAO( + level, + bakedModel, + blockEntity.blockState, + blockEntity.blockPos, + matrixStack, + buf.getBuffer(RenderType.cutout()), + checkSides, + level.random, + 42L, // Used in ModelBlockRenderer.class in renderModel, not sure what the right number is but this seems to work + packedOverlay + ) + buf.draw() + } + val renderer = object : Renderer { override fun render( matrixStack: PoseStack, diff --git a/common/src/main/kotlin/org/valkyrienskies/tournament/TournamentNetworking.kt b/common/src/main/kotlin/org/valkyrienskies/tournament/TournamentNetworking.kt index 94d53c7..f58fa16 100644 --- a/common/src/main/kotlin/org/valkyrienskies/tournament/TournamentNetworking.kt +++ b/common/src/main/kotlin/org/valkyrienskies/tournament/TournamentNetworking.kt @@ -1,7 +1,9 @@ package org.valkyrienskies.tournament import blitz.collections.remove +import net.minecraft.client.Minecraft import net.minecraft.core.BlockPos +import net.minecraft.core.Direction import net.minecraft.resources.ResourceLocation import org.valkyrienskies.core.api.ships.properties.ShipId import org.valkyrienskies.core.impl.game.ships.ShipObjectServerWorld @@ -50,15 +52,21 @@ object TournamentNetworking { // } } } + + fun clientHandler() { + val client = TournamentShips.Client[ship] + client.fuelType.set(fuelFuel()) + } } data class ShipThrusterChange( val ship: ShipId, - val posX: Int, - val posY: Int, - val posZ: Int, + val pos: Long, val throttle: Float, ): SimplePacket { + fun unpackPos() = + BlockPos.of(pos) + fun removed() = throttle < 0.0f @@ -70,6 +78,82 @@ object TournamentNetworking { // } } } + + fun clientHandler() { + val client = TournamentShips.Client[ship] + val idx = client.thrusters.index(unpackPos()) + if (removed()) { + client.thrusters.remove(idx) + } else { + client.thrusters[idx] = TournamentShips.Client.Data.Thruster(throttle) + } + } + } + + // add or delete blocks inside shaft or delete shaft (if blocks contains shaftpos) + data class ShaftBlockChange( + val shaftPos: Long, + val newBlocks: List, + val remove: Boolean + ): SimplePacket { + fun send() { + runIfServer { + // TODO after vs update + // with(vsCore.simplePacketNetworking) { + this.sendToAllClients() + // } + } + } + + fun clientHandler() { + val level = Minecraft.getInstance().level!! + val man = ClientShaftMan.get(level) + if (shaftPos in newBlocks) { + if (!remove) error("no.") + man.eraseShaft(BlockPos.of(shaftPos)) + } else { + val shaft = man.shaftAt(BlockPos.of(shaftPos))!! + if (remove) { + newBlocks.forEach { shaft.removeShaftBlock(BlockPos.of(it)) } + } else { + newBlocks.forEach { shaft.addShaftBlock(BlockPos.of(it)) } + } + } + } + } + + // change shaft speed or add shaft + data class ShaftSpeedChange( + val shaftPos: Long, // blockPos + val axis: Byte, + val speed: Float, + ): SimplePacket { + fun unpackPos() = + BlockPos.of(shaftPos) + + fun axis() = + Direction.Axis.entries[axis.toInt()] + + companion object { + fun getAxis(axis: Direction.Axis) = + axis.ordinal.toByte() + } + + fun send() { + runIfServer { + // TODO after vs update + // with(vsCore.simplePacketNetworking) { + this.sendToAllClients() + // } + } + } + + fun clientHandler() { + val level = Minecraft.getInstance().level!! + val man = ClientShaftMan.get(level) + val pos = unpackPos() + man.getOrCreateShaft(pos, axis()).speed = speed + } } fun register() { @@ -77,23 +161,16 @@ object TournamentNetworking { // with(vsCore.simplePacketNetworking) { ShipFuelTypeChange::class.register() ShipThrusterChange::class.register() + ShaftSpeedChange::class.register() + ShaftBlockChange::class.register() // } // TODO after vs update // with(vsCore.simplePacketNetworking) { - ShipFuelTypeChange::class.registerClientHandler { - val client = TournamentShips.Client[it.ship] - client.fuelType.set(it.fuelFuel()) - } - ShipThrusterChange::class.registerClientHandler { - val client = TournamentShips.Client[it.ship] - val idx = client.thrusters.index(BlockPos(it.posX, it.posY, it.posZ)) - if (it.removed()) { - client.thrusters.remove(idx) - } else { - client.thrusters[idx] = TournamentShips.Client.Data.Thruster(it.throttle) - } - } + ShipFuelTypeChange::class.registerClientHandler(ShipFuelTypeChange::clientHandler) + ShipThrusterChange::class.registerClientHandler(ShipThrusterChange::clientHandler) + ShaftSpeedChange::class.registerClientHandler(ShaftSpeedChange::clientHandler) + ShaftBlockChange::class.registerClientHandler(ShaftBlockChange::clientHandler) // } } } \ No newline at end of file diff --git a/common/src/main/kotlin/org/valkyrienskies/tournament/blockentity/render/TransparentFuelTankBlockEntityRender.kt b/common/src/main/kotlin/org/valkyrienskies/tournament/blockentity/render/TransparentFuelTankBlockEntityRender.kt index cf7c279..123ab6a 100644 --- a/common/src/main/kotlin/org/valkyrienskies/tournament/blockentity/render/TransparentFuelTankBlockEntityRender.kt +++ b/common/src/main/kotlin/org/valkyrienskies/tournament/blockentity/render/TransparentFuelTankBlockEntityRender.kt @@ -1,10 +1,10 @@ package org.valkyrienskies.tournament.blockentity.render -import com.mojang.blaze3d.systems.RenderSystem import com.mojang.blaze3d.vertex.PoseStack import net.minecraft.client.renderer.MultiBufferSource import net.minecraft.client.renderer.blockentity.BlockEntityRenderer import net.minecraft.core.Direction +import org.lwjgl.opengl.GL11 import org.valkyrienskies.tournament.TournamentModels import org.valkyrienskies.tournament.blockentity.FuelTankBlockEntity import org.valkyrienskies.tournament.util.extension.pose @@ -21,8 +21,6 @@ class TransparentFuelTankBlockEntityRender: packedLight: Int, packedOverlay: Int ) { - RenderSystem.disableCull() - if (be.wholeShipFillLevelSynced > 0.05f) { val byDir = List(Direction.entries.size) { index -> if (be.neighborsTransparent[index]) { @@ -59,15 +57,22 @@ class TransparentFuelTankBlockEntityRender: } } - TournamentModels.FUEL_TANK_FULL_TRANSPARENT.renderer.render( - pose, - be, - bufferSource, - packedLight, - packedOverlay - ) + val oldCull = GL11.glIsEnabled(GL11.GL_CULL_FACE) + GL11.glEnable(GL11.GL_CULL_FACE) + + val old = GL11.glGetInteger(GL11.GL_FRONT_FACE) + + GL11.glFrontFace(GL11.GL_CCW) + TournamentModels.FUEL_TANK_FULL_TRANSPARENT.renderNow(pose, be, packedOverlay) - RenderSystem.enableCull() + GL11.glFrontFace(GL11.GL_CW) + TournamentModels.FUEL_TANK_FULL_TRANSPARENT.renderNow(pose, be, packedOverlay) + + GL11.glFrontFace(old) + + if (!oldCull) { + GL11.glDisable(GL11.GL_CULL_FACE) + } } } \ No newline at end of file diff --git a/common/src/main/kotlin/org/valkyrienskies/tournament/blocks/FuelTankBlock.kt b/common/src/main/kotlin/org/valkyrienskies/tournament/blocks/FuelTankBlock.kt index 4a8642b..451a648 100644 --- a/common/src/main/kotlin/org/valkyrienskies/tournament/blocks/FuelTankBlock.kt +++ b/common/src/main/kotlin/org/valkyrienskies/tournament/blocks/FuelTankBlock.kt @@ -14,6 +14,7 @@ import net.minecraft.world.level.Level import net.minecraft.world.level.LevelAccessor import net.minecraft.world.level.block.BaseEntityBlock import net.minecraft.world.level.block.Block +import net.minecraft.world.level.block.Blocks import net.minecraft.world.level.block.RenderShape import net.minecraft.world.level.block.entity.BlockEntity import net.minecraft.world.level.block.entity.BlockEntityTicker @@ -22,6 +23,9 @@ import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.level.block.state.properties.SlabType import net.minecraft.world.level.material.Material import net.minecraft.world.phys.BlockHitResult +import net.minecraft.world.phys.shapes.CollisionContext +import net.minecraft.world.phys.shapes.Shapes +import net.minecraft.world.phys.shapes.VoxelShape import org.valkyrienskies.tournament.TournamentBlockEntities import org.valkyrienskies.tournament.blockentity.FuelTankBlockEntity import org.valkyrienskies.tournament.util.TitleType @@ -77,6 +81,7 @@ class FuelTankBlockFull( Properties .of(Material.METAL) .noOcclusion() + .isViewBlocking { _,_,_ -> !transparent } ), WorldlyContainerHolder, WithExRenderInfo { override fun onPlace(state: BlockState, level: Level, pos: BlockPos, oldState: BlockState, isMoving: Boolean) { diff --git a/common/src/main/kotlin/org/valkyrienskies/tournament/ship/TournamentShips.kt b/common/src/main/kotlin/org/valkyrienskies/tournament/ship/TournamentShips.kt index cbe023e..cd397e4 100644 --- a/common/src/main/kotlin/org/valkyrienskies/tournament/ship/TournamentShips.kt +++ b/common/src/main/kotlin/org/valkyrienskies/tournament/ship/TournamentShips.kt @@ -87,6 +87,7 @@ class TournamentShips: ShipForcesInducer { private val thrustersV2 = CopyOnWriteArrayList>() + // todo: use longs as keys? private val thrustersV2_2 = SyncBlockMap(BlockMap()) @@ -200,7 +201,7 @@ class TournamentShips: ShipForcesInducer { TournamentNetworking.ShipThrusterChange( physShip.id, - pos.x, pos.y, pos.z, + packed, throttle ).send() } diff --git a/common/src/main/resources/assets/vs_tournament/textures/block/fuel_tank_half_solid.png b/common/src/main/resources/assets/vs_tournament/textures/block/fuel_tank_half_solid.png index e245db8343949f548d64ae49bda01c0c53229191..7b567e01c04dce774864c96579291ef3a3387cc9 100644 GIT binary patch delta 194 zcmcb`c#&~}c)b7%GXn#|+q;i~fD~hKkh>G(&67IyKn`btM`SSr1Gg{;GcwGYBLNhY z2=EDU?U}!N#){2*j-5Mx?%L^#H@6))*|%{0qK$jhj{AHEstNLRaSW-Llbn(ukdpA@ zf8)f7o{j+@_FuU9zsILjoYn4B+~1=oQaFSHo+OJ{hlx~tZ|wB%3siadrR delta 203 zcmV;+05t#60onnO7k>x{0ssI2e-!Az0001?Nkl?>~?g zurM$%7^o{l_}m;E3=9k`%*+t(pTB?KfBMY8z`(}F3K6;U=qVF~b?Np){HmY5eg_d} zfl!vZ>UdQ1b8~ZZa6m*@csMyQ&Hno12izI_+}scmh<}(MNh~YL);1002ovPDHLk FV1g1uRCfRX diff --git a/common/src/main/resources/vs_tournament-common.mixins.json b/common/src/main/resources/vs_tournament-common.mixins.json index e1c0124..75c8be5 100644 --- a/common/src/main/resources/vs_tournament-common.mixins.json +++ b/common/src/main/resources/vs_tournament-common.mixins.json @@ -3,9 +3,10 @@ "package": "org.valkyrienskies.tournament.mixin", "compatibilityLevel": "JAVA_17", "client": [ + "client.MixinBlockClient", "client.MixinDebugRenderer", "client.MixinItemTooltips", - "client.MixinBlockClient" + "client.MixinMinecraft" ], "injectors": { "defaultRequire": 1