diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/Helpers.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/Helpers.kt new file mode 100644 index 000000000..f965c61cf --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/Helpers.kt @@ -0,0 +1,39 @@ +package ru.dbotthepony.mc.otm.block + +import net.minecraft.world.level.Level +import net.minecraft.world.level.block.entity.BlockEntity +import net.minecraft.world.level.block.entity.BlockEntityTicker +import net.minecraft.world.level.block.entity.BlockEntityType +import kotlin.reflect.KFunction1 + +inline fun KFunction1.blockServerTicker( + level: Level, + expected: BlockEntityType<*>, + provided: BlockEntityType<*> +): BlockEntityTicker? { + if (expected !== provided) { + return null + } + + if (level.isClientSide) { + return null + } + + return BlockEntityTicker { _, _, _, tile -> if (tile is R) this.invoke(tile) } +} + +inline fun KFunction1.blockClientTicker( + level: Level, + expected: BlockEntityType<*>, + provided: BlockEntityType<*> +): BlockEntityTicker? { + if (expected !== provided) { + return null + } + + if (!level.isClientSide) { + return null + } + + return BlockEntityTicker { _, _, _, tile -> if (tile is R) this.invoke(tile) } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BatteryBankBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BatteryBankBlockEntity.kt index 4fbfce689..6b90d5f04 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BatteryBankBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BatteryBankBlockEntity.kt @@ -1,6 +1,5 @@ package ru.dbotthepony.mc.otm.block.entity -import net.minecraft.MethodsReturnNonnullByDefault import net.minecraft.core.BlockPos import net.minecraft.core.Direction import net.minecraft.nbt.CompoundTag @@ -29,11 +28,11 @@ import ru.dbotthepony.mc.otm.container.MatteryContainerFilter import ru.dbotthepony.mc.otm.core.* import ru.dbotthepony.mc.otm.menu.BatteryBankMenu import ru.dbotthepony.mc.otm.registry.MBlockEntities -import javax.annotation.ParametersAreNonnullByDefault -@MethodsReturnNonnullByDefault -@ParametersAreNonnullByDefault class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : MatteryBlockEntity(MBlockEntities.BATTERY_BANK, p_155229_, p_155230_), IDroppableContainer { + var gaugeLevel by synchronizer.float() + private set + // 6 на 2 val container: MatteryContainer = object : MatteryContainer(this::setChanged, CAPACITY) { override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) { @@ -51,6 +50,8 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte level.setBlock(blockPos, state, Block.UPDATE_CLIENTS) } } + + gaugeLevel = (energy.batteryLevel / energy.maxBatteryLevel).toFloat() } } @@ -115,6 +116,9 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte } private fun distributeEnergy(isReceiving: Boolean, howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { + if (!howMuch.isPositive) + return ImpreciseFraction.ZERO + val distribution = getDistribution(isReceiving) if (distribution.maxThroughput.isZero) @@ -145,6 +149,7 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte if (!simulate && !summ.isZero) { setChangedLight() + gaugeLevel = (batteryLevel / maxBatteryLevel).toFloat() } return summ @@ -296,6 +301,8 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte } fun tick() { + synchronizeToPlayers() + if (isBlockedByRedstone) return diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/SynchronizedBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/SynchronizedBlockEntity.kt index 3eac48913..067a8a99c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/SynchronizedBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/SynchronizedBlockEntity.kt @@ -50,8 +50,8 @@ abstract class SynchronizedBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: val (x, y, z) = it.position (x - bx) * (x - bx) + - (y - by) * (y - by) + - (z - bz) * (z - bz) <= double + (y - by) * (y - by) + + (z - bz) * (z - bz) <= double }.forEach { val payload = synchronizer.computeEndpointFor(it).collectNetworkPayload() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterCapacitorBankBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterCapacitorBankBlockEntity.kt index 13c271fab..7cb4d5a03 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterCapacitorBankBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterCapacitorBankBlockEntity.kt @@ -35,8 +35,9 @@ import ru.dbotthepony.mc.otm.core.map import ru.dbotthepony.mc.otm.core.set import javax.annotation.ParametersAreNonnullByDefault -class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : - MatteryBlockEntity(MBlockEntities.MATTER_CAPACITOR_BANK, p_155229_, p_155230_), IMatterGraphNode, IMatterHandler, IDroppableContainer { +class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : MatteryBlockEntity(MBlockEntities.MATTER_CAPACITOR_BANK, p_155229_, p_155230_), IMatterGraphNode, IMatterHandler, IDroppableContainer { + var gaugeLevel by synchronizer.float() + private set override val matterNode = Graph6Node(this) private val resolverNode = LazyOptional.of { this } @@ -70,6 +71,9 @@ class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) } override fun receiveMatterInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { + if (!howMuch.isPositive) + return ImpreciseFraction.ZERO + @Suppress("NAME_SHADOWING") var howMuch = howMuch var summ = ImpreciseFraction.ZERO @@ -88,6 +92,10 @@ class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) } } + if (summ.isPositive && !simulate) { + gaugeLevel = (storedMatter / maxStoredMatter).toFloat() + } + return summ } @@ -96,6 +104,9 @@ class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) } override fun extractMatterInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { + if (!howMuch.isPositive) + return ImpreciseFraction.ZERO + @Suppress("NAME_SHADOWING") var howMuch = howMuch var summ = ImpreciseFraction.ZERO @@ -113,6 +124,11 @@ class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) } } } + + if (summ.isPositive && !simulate) { + gaugeLevel = (storedMatter / maxStoredMatter).toFloat() + } + return summ } @@ -141,6 +157,8 @@ class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) level.setBlock(blockPos, state, Block.UPDATE_CLIENTS) } } + + gaugeLevel = (storedMatter / maxStoredMatter).toFloat() } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/matter/MatterCapacitorBankBlock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/matter/MatterCapacitorBankBlock.kt index 5b700468f..1bd56c5a6 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/matter/MatterCapacitorBankBlock.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/matter/MatterCapacitorBankBlock.kt @@ -4,16 +4,22 @@ import net.minecraft.core.BlockPos import net.minecraft.core.Direction import net.minecraft.world.item.context.BlockPlaceContext import net.minecraft.world.level.BlockGetter +import net.minecraft.world.level.Level import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.EntityBlock import net.minecraft.world.level.block.entity.BlockEntity +import net.minecraft.world.level.block.entity.BlockEntityTicker +import net.minecraft.world.level.block.entity.BlockEntityType import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.level.block.state.StateDefinition import net.minecraft.world.phys.shapes.CollisionContext import net.minecraft.world.phys.shapes.VoxelShape import ru.dbotthepony.mc.otm.block.BatteryBankBlock import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock +import ru.dbotthepony.mc.otm.block.entity.SynchronizedBlockEntity import ru.dbotthepony.mc.otm.block.entity.matter.MatterCapacitorBankBlockEntity +import ru.dbotthepony.mc.otm.block.blockServerTicker +import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.shapes.BlockShapes class MatterCapacitorBankBlock : RotatableMatteryBlock(), EntityBlock { @@ -21,6 +27,14 @@ class MatterCapacitorBankBlock : RotatableMatteryBlock(), EntityBlock { return MatterCapacitorBankBlockEntity(blockPos, blockState) } + override fun getTicker( + p_153212_: Level, + p_153213_: BlockState, + p_153214_: BlockEntityType + ): BlockEntityTicker? { + return SynchronizedBlockEntity::synchronizeToPlayers.blockServerTicker(p_153212_, MBlockEntities.MATTER_CAPACITOR_BANK, p_153214_) + } + override fun getStateForPlacement(context: BlockPlaceContext): BlockState? { var state = super.getStateForPlacement(context) ?: return null @@ -60,4 +74,4 @@ class MatterCapacitorBankBlock : RotatableMatteryBlock(), EntityBlock { ) } } -} \ No newline at end of file +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/RenderHelper.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/RenderHelper.kt index 6fccfd823..a558572dd 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/RenderHelper.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/RenderHelper.kt @@ -22,6 +22,7 @@ private val identity = Matrix4f().also { it.setIdentity() } var zLevel = 0f var drawColor = RGBAColor(255, 255, 255, 255) +var is3DContext = false @JvmName("setDrawColor\$JVM") fun setDrawColor(color: RGBAColor) { @@ -44,7 +45,9 @@ fun drawTexturedRect( RenderSystem.enableTexture() RenderSystem.enableBlend() RenderSystem.defaultBlendFunc() - RenderSystem.depthFunc(GL11.GL_ALWAYS) + + if (!is3DContext) + RenderSystem.depthFunc(GL_ALWAYS) val builder = tesselator.builder @@ -303,7 +306,9 @@ fun drawRect( RenderSystem.enableBlend() RenderSystem.defaultBlendFunc() RenderSystem.setShader(GameRenderer::getPositionColorShader) - RenderSystem.depthFunc(GL11.GL_ALWAYS) + + if (!is3DContext) + RenderSystem.depthFunc(GL_ALWAYS) val tess = tesselator val builder = tess.builder @@ -346,7 +351,9 @@ fun drawLine( RenderSystem.enableBlend() RenderSystem.defaultBlendFunc() RenderSystem.setShader(GameRenderer::getPositionColorShader) - RenderSystem.depthFunc(GL11.GL_ALWAYS) + + if (!is3DContext) + RenderSystem.depthFunc(GL_ALWAYS) val tess = Tesselator.getInstance() val builder = tess.builder diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/BankRenderer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/BankRenderer.kt new file mode 100644 index 000000000..ea2d7d8e4 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/BankRenderer.kt @@ -0,0 +1,85 @@ +package ru.dbotthepony.mc.otm.client.render.blockentity + +import com.mojang.blaze3d.systems.RenderSystem +import com.mojang.blaze3d.vertex.PoseStack +import com.mojang.math.Vector3f +import net.minecraft.client.renderer.MultiBufferSource +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider +import org.lwjgl.opengl.GL30.* +import ru.dbotthepony.mc.otm.block.entity.BatteryBankBlockEntity +import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity +import ru.dbotthepony.mc.otm.block.entity.matter.MatterCapacitorBankBlockEntity +import ru.dbotthepony.mc.otm.client.render.SkinElement +import ru.dbotthepony.mc.otm.client.render.is3DContext +import ru.dbotthepony.mc.otm.client.screen.widget.MatterGaugePanel +import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel +import kotlin.math.PI + +abstract class BankRenderer(private val context: BlockEntityRendererProvider.Context) : BlockEntityRenderer { + protected abstract fun gaugeLevel(entity: T): Float + protected abstract val texture: SkinElement + + override fun render( + blockEntity: T, + p_112308_: Float, + stack: PoseStack, + p_112310_: MultiBufferSource, + p_112311_: Int, + p_112312_: Int + ) { + is3DContext = true + + try { + RenderSystem.enableDepthTest() + RenderSystem.depthFunc(GL_LEQUAL) + + stack.pushPose() + stack.scale(0.02f, 0.01f, 0.01f) + stack.translate(0.0, 0.0, -0.5) + + // ~50x100 canvas + + val width = 9f + val heightMax = 39.36f + + texture.renderPartial(stack, + x = 25f - width / 2f, + y = 30f, + width = width, + height = heightMax * gaugeLevel(blockEntity)) + + stack.mulPose(Vector3f.YP.rotation(PI.toFloat())) + stack.translate(-50.0, 0.0, -101.0) + + texture.renderPartial(stack, + x = 25f - width / 2f, + y = 30f, + width = width, + height = heightMax * gaugeLevel(blockEntity)) + + stack.popPose() + } finally { + is3DContext = false + } + } +} + +class BatteryBankRenderer(context: BlockEntityRendererProvider.Context) : BankRenderer(context) { + override fun gaugeLevel(entity: BatteryBankBlockEntity): Float { + return entity.gaugeLevel + } + + override val texture: SkinElement + get() = PowerGaugePanel.GAUGE_FOREGROUND +} + +class MatterBatteryBankRenderer(context: BlockEntityRendererProvider.Context) : BankRenderer(context) { + override fun gaugeLevel(entity: MatterCapacitorBankBlockEntity): Float { + return entity.gaugeLevel + } + + override val texture: SkinElement + get() = MatterGaugePanel.GAUGE_FOREGROUND +} + diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockEntities.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockEntities.kt index 5514cfdd4..06ff7984e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockEntities.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockEntities.kt @@ -13,9 +13,11 @@ import ru.dbotthepony.mc.otm.block.entity.blackhole.BlockEntityExplosionDebugger import ru.dbotthepony.mc.otm.block.entity.blackhole.BlockEntitySphereDebugger import ru.dbotthepony.mc.otm.block.entity.matter.* import ru.dbotthepony.mc.otm.block.entity.storage.* +import ru.dbotthepony.mc.otm.client.render.blockentity.BatteryBankRenderer import ru.dbotthepony.mc.otm.client.render.blockentity.BlackHoleRenderer import ru.dbotthepony.mc.otm.client.render.blockentity.EnergyCounterRenderer import ru.dbotthepony.mc.otm.client.render.blockentity.GravitationStabilizerRenderer +import ru.dbotthepony.mc.otm.client.render.blockentity.MatterBatteryBankRenderer object MBlockEntities { private val registry = DeferredRegister.create(ForgeRegistries.BLOCK_ENTITY_TYPES, OverdriveThatMatters.MOD_ID) @@ -65,6 +67,8 @@ object MBlockEntities { BlockEntityRenderers.register(BLACK_HOLE as BlockEntityType, ::BlackHoleRenderer) BlockEntityRenderers.register(GRAVITATION_STABILIZER as BlockEntityType, ::GravitationStabilizerRenderer) BlockEntityRenderers.register(ENERGY_COUNTER as BlockEntityType, ::EnergyCounterRenderer) + BlockEntityRenderers.register(BATTERY_BANK as BlockEntityType, ::BatteryBankRenderer) + BlockEntityRenderers.register(MATTER_CAPACITOR_BANK as BlockEntityType, ::MatterBatteryBankRenderer) } } }