From 0ae1cd21fef85688bcd4cbf1d05eba49facb5893 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Sun, 14 Jan 2024 00:52:38 +0700 Subject: [PATCH 01/16] Fix secondary furnace recipes not using proper config values --- .../block/entity/tech/AbstractPoweredFurnaceBlockEntity.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/AbstractPoweredFurnaceBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/AbstractPoweredFurnaceBlockEntity.kt index ed41c96f8..404a0fa31 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/AbstractPoweredFurnaceBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/AbstractPoweredFurnaceBlockEntity.kt @@ -142,8 +142,8 @@ sealed class AbstractPoweredFurnaceBlockEntity

Date: Sun, 14 Jan 2024 10:51:15 +0700 Subject: [PATCH 02/16] How did i mess up left/right sprites of machine side controls again --- .../kotlin/ru/dbotthepony/mc/otm/client/render/Widgets18.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Widgets18.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Widgets18.kt index 8999e8f91..1835e22a0 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Widgets18.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Widgets18.kt @@ -157,8 +157,8 @@ object Widgets18 { } } - val LEFT_CONTROLS = SideControls() val RIGHT_CONTROLS = SideControls() + val LEFT_CONTROLS = SideControls() val TOP_CONTROLS = SideControls() val BOTTOM_CONTROLS = SideControls() val FRONT_CONTROLS = SideControls() From f97ad565d48144629380396853a1e22aaf55d6a4 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Wed, 17 Jan 2024 13:15:01 +0700 Subject: [PATCH 03/16] Multiblock test --- .../mc/otm/block/MultiblockTestBlock.kt | 23 + .../block/entity/MultiblockTestBlockEntity.kt | 75 +++ .../ru/dbotthepony/mc/otm/core/Multiblock.kt | 619 ++++++++++++++++++ .../mc/otm/core/math/BlockRotation.kt | 5 +- .../mc/otm/registry/MBlockEntities.kt | 6 + .../ru/dbotthepony/mc/otm/registry/MBlocks.kt | 3 + .../ru/dbotthepony/mc/otm/registry/MItems.kt | 1 + 7 files changed, 729 insertions(+), 3 deletions(-) create mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/block/MultiblockTestBlock.kt create mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MultiblockTestBlockEntity.kt create mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/core/Multiblock.kt diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/MultiblockTestBlock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/MultiblockTestBlock.kt new file mode 100644 index 000000000..20997844e --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/MultiblockTestBlock.kt @@ -0,0 +1,23 @@ +package ru.dbotthepony.mc.otm.block + +import net.minecraft.core.BlockPos +import net.minecraft.world.level.Level +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 ru.dbotthepony.mc.otm.block.entity.MultiblockTestBlockEntity + +class MultiblockTestBlock : MatteryBlock(), EntityBlock { + override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity { + return MultiblockTestBlockEntity(blockPos, blockState) + } + + override fun getTicker(level: Level, blockState: BlockState, blockEntityType: BlockEntityType): BlockEntityTicker? { + if (level.isClientSide) + return null + + return BlockEntityTicker { _, _, _, tile -> if (tile is MultiblockTestBlockEntity) tile.tick() } + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MultiblockTestBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MultiblockTestBlockEntity.kt new file mode 100644 index 000000000..a5bdd18f7 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MultiblockTestBlockEntity.kt @@ -0,0 +1,75 @@ +package ru.dbotthepony.mc.otm.block.entity + +import net.minecraft.core.BlockPos +import net.minecraft.tags.BlockTags +import net.minecraft.world.level.block.Blocks +import net.minecraft.world.level.block.entity.BlockEntity +import net.minecraft.world.level.block.entity.FurnaceBlockEntity +import net.minecraft.world.level.block.entity.HopperBlockEntity +import net.minecraft.world.level.block.state.BlockState +import ru.dbotthepony.mc.otm.core.multiblockConfiguration +import ru.dbotthepony.mc.otm.core.multiblockEntity +import ru.dbotthepony.mc.otm.registry.MBlockEntities +import ru.dbotthepony.mc.otm.registry.MBlocks + +class MultiblockTestBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryBlockEntity(MBlockEntities.MULTIBLOCK_TEST, blockPos, blockState) { + val config = CONFIG.create(blockPos) + + override fun tick() { + super.tick() + + if (config.update(level!!)) { + println("It matches!") + println("hopper block entities: ${config.blockEntities(HOPPERS)}") + } + } + + companion object { + private val HOPPERS = multiblockEntity() + private val FURNACES = multiblockEntity() + + val CONFIG = multiblockConfiguration { + block(MBlocks.MULTIBLOCK_TEST) + + and { + top { + or { + block(Blocks.HOPPER) + block(Blocks.CHEST) + block(BlockTags.PLANKS) + } + + tag(HOPPERS) + } + + left(Blocks.FURNACE) { + tag(FURNACES) + + top { + or { + block(Blocks.HOPPER) + block(Blocks.CHEST) + block(BlockTags.PLANKS) + } + + tag(HOPPERS) + } + } + + right(Blocks.FURNACE) { + tag(FURNACES) + + top { + or { + block(Blocks.HOPPER) + block(Blocks.CHEST) + block(BlockTags.PLANKS) + } + + tag(HOPPERS) + } + } + } + } + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/Multiblock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/Multiblock.kt new file mode 100644 index 000000000..b2b571c68 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/Multiblock.kt @@ -0,0 +1,619 @@ +package ru.dbotthepony.mc.otm.core + +import com.google.common.collect.ImmutableList +import com.google.common.collect.ImmutableSet +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap +import it.unimi.dsi.fastutil.objects.Object2ObjectFunction +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap +import it.unimi.dsi.fastutil.objects.ObjectArraySet +import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap +import net.minecraft.core.BlockPos +import net.minecraft.core.Direction +import net.minecraft.core.Vec3i +import net.minecraft.tags.TagKey +import net.minecraft.world.level.LevelAccessor +import net.minecraft.world.level.block.Block +import net.minecraft.world.level.block.Rotation +import net.minecraft.world.level.block.entity.BlockEntity +import net.minecraft.world.level.block.state.BlockState +import ru.dbotthepony.mc.otm.core.collect.collect +import ru.dbotthepony.mc.otm.core.collect.map +import ru.dbotthepony.mc.otm.core.math.RelativeSide +import ru.dbotthepony.mc.otm.core.math.plus +import java.util.Collections +import java.util.function.Predicate +import kotlin.reflect.KClass + +fun interface BlockPredicate { + fun test(pos: BlockPos, access: LevelAccessor): Boolean + + fun and(other: BlockPredicate): BlockPredicate { + return BlockPredicate { pos, access -> test(pos, access) && other.test(pos, access) } + } + + fun or(other: BlockPredicate): BlockPredicate { + return BlockPredicate { pos, access -> test(pos, access) || other.test(pos, access) } + } + + fun offset(offset: BlockPos): Positioned { + return Positioned(offset, this) + } + + fun offset(offset: Vec3i): Positioned { + return offset(BlockPos(offset)) + } + + data class Positioned(val offset: BlockPos, val parent: BlockPredicate) : BlockPredicate { + override fun test(pos: BlockPos, access: LevelAccessor): Boolean { + return parent.test(offset + pos, access) + } + + override fun offset(offset: BlockPos): Positioned { + return Positioned(this.offset + offset, parent) + } + } + + data class And(val nodes: ImmutableSet) : BlockPredicate { + constructor(vararg nodes: BlockPredicate) : this(ImmutableSet.copyOf(nodes)) + constructor(nodes: Set) : this(ImmutableSet.copyOf(nodes)) + + override fun test(pos: BlockPos, access: LevelAccessor): Boolean { + return nodes.all { it.test(pos, access) } + } + } + + data class Or(val nodes: ImmutableSet) : BlockPredicate { + constructor(vararg nodes: BlockPredicate) : this(ImmutableSet.copyOf(nodes)) + constructor(nodes: Set) : this(ImmutableSet.copyOf(nodes)) + + override fun test(pos: BlockPos, access: LevelAccessor): Boolean { + return nodes.any { it.test(pos, access) } + } + } + + object Air : BlockPredicate { + override fun test(pos: BlockPos, access: LevelAccessor): Boolean { + return access.isEmptyBlock(pos) + } + } + + object NotAir : BlockPredicate { + override fun test(pos: BlockPos, access: LevelAccessor): Boolean { + return !access.isEmptyBlock(pos) + } + } +} + +inline fun multiblockConfiguration(configurator: MultiblockBuilder.Node.() -> Unit): MultiblockFactory { + val builder = MultiblockBuilder() + configurator.invoke(builder.root()) + return builder.build() +} + +inline fun multiblockEntity(): MultiblockBuilder.EntityTag { + return MultiblockBuilder.EntityTag(T::class) +} + +class MultiblockBuilder { + private val nodes = Object2ObjectOpenHashMap() + + // not data classes to allow having multiple tags with same target + class EntityTag(val clazz: KClass) : Predicate { + override fun test(t: BlockEntity): Boolean { + return clazz.isInstance(t) + } + } + + enum class Strategy { + OR, AND + } + + @Suppress("unchecked_cast") + abstract class BlockPredicates> { + val predicates = ObjectArraySet() + val children = ObjectArraySet>() + + val blockStateTags = ObjectArraySet() + val blockTags = ObjectArraySet() + val blockEntityTags = ObjectArraySet>() + + fun tagBlockState(value: Any): T { + blockStateTags.add(value) + return this as T + } + + fun tagBlock(value: Any): T { + blockTags.add(value) + return this as T + } + + fun tag(value: EntityTag<*>): T { + blockEntityTags.add(value) + return this as T + } + + fun clear(): T { + predicates.clear() + return this as T + } + + fun predicate(predicate: BlockPredicate): T { + predicates.add(predicate) + return this as T + } + + fun block(block: Block): T { + predicates.add { pos, access -> access.getBlockState(pos).`is`(block) } + return this as T + } + + fun block(block: TagKey): T { + predicates.add { pos, access -> access.getBlockState(pos).`is`(block) } + return this as T + } + + fun air(): T { + predicate(BlockPredicate.Air) + return this as T + } + + fun block(state: BlockState): T { + predicates.add { pos, access -> access.getBlockState(pos) == state } + return this as T + } + + fun and(): And { + return And(this as T) + } + + fun or(): Or { + return Or(this as T) + } + + fun and(configurator: And.() -> Unit): And { + return And(this as T).also(configurator) + } + + fun or(configurator: Or.() -> Unit): Or { + return Or(this as T).also(configurator) + } + + protected fun build(pos: BlockPos): MultiblockFactory.Part { + return MultiblockFactory.Part( + pos, strategy, ImmutableList.copyOf(predicates), + children.stream().map { it.build(pos) }.collect(ImmutableList.toImmutableList()), + ImmutableSet.copyOf(blockStateTags), + ImmutableSet.copyOf(blockTags), + ImmutableSet.copyOf(blockEntityTags), + ) + } + + abstract val strategy: Strategy + } + + class And

>(val parent: P) : BlockPredicates>() { + init { + parent.children.add(this) + } + + fun end() = parent + + override val strategy: Strategy + get() = Strategy.AND + } + + class Or

>(val parent: P) : BlockPredicates>() { + init { + parent.children.add(this) + } + + fun end() = parent + + override val strategy: Strategy + get() = Strategy.OR + } + + /** + * Behaves as if being [Or] node + */ + inner class Node(val pos: BlockPos) : BlockPredicates() { + init { + check(nodes.put(pos, this) == null) { "Trying to create new node at $pos while already having one" } + } + + fun relative(diff: Vec3i): Node { + return node(pos + diff) + } + + fun relative(dir: Direction): Node { + return relative(dir.normal) + } + + fun relative(dir: RelativeSide): Node { + return relative(dir.default) + } + + fun front() = relative(RelativeSide.FRONT) + fun back() = relative(RelativeSide.BACK) + fun left() = relative(RelativeSide.LEFT) + fun right() = relative(RelativeSide.RIGHT) + fun top() = relative(RelativeSide.TOP) + fun bottom() = relative(RelativeSide.BOTTOM) + + fun front(block: Block) = relative(RelativeSide.FRONT).also { it.block(block) } + fun back(block: Block) = relative(RelativeSide.BACK).also { it.block(block) } + fun left(block: Block) = relative(RelativeSide.LEFT).also { it.block(block) } + fun right(block: Block) = relative(RelativeSide.RIGHT).also { it.block(block) } + fun top(block: Block) = relative(RelativeSide.TOP).also { it.block(block) } + fun bottom(block: Block) = relative(RelativeSide.BOTTOM).also { it.block(block) } + + fun front(block: BlockState) = relative(RelativeSide.FRONT).also { it.block(block) } + fun back(block: BlockState) = relative(RelativeSide.BACK).also { it.block(block) } + fun left(block: BlockState) = relative(RelativeSide.LEFT).also { it.block(block) } + fun right(block: BlockState) = relative(RelativeSide.RIGHT).also { it.block(block) } + fun top(block: BlockState) = relative(RelativeSide.TOP).also { it.block(block) } + fun bottom(block: BlockState) = relative(RelativeSide.BOTTOM).also { it.block(block) } + + fun front(predicate: BlockPredicate) = relative(RelativeSide.FRONT).also { it.predicate(predicate) } + fun back(predicate: BlockPredicate) = relative(RelativeSide.BACK).also { it.predicate(predicate) } + fun left(predicate: BlockPredicate) = relative(RelativeSide.LEFT).also { it.predicate(predicate) } + fun right(predicate: BlockPredicate) = relative(RelativeSide.RIGHT).also { it.predicate(predicate) } + fun top(predicate: BlockPredicate) = relative(RelativeSide.TOP).also { it.predicate(predicate) } + fun bottom(predicate: BlockPredicate) = relative(RelativeSide.BOTTOM).also { it.predicate(predicate) } + + fun front(configurator: Node.() -> Unit) = relative(RelativeSide.FRONT).also(configurator) + fun back(configurator: Node.() -> Unit) = relative(RelativeSide.BACK).also(configurator) + fun left(configurator: Node.() -> Unit) = relative(RelativeSide.LEFT).also(configurator) + fun right(configurator: Node.() -> Unit) = relative(RelativeSide.RIGHT).also(configurator) + fun top(configurator: Node.() -> Unit) = relative(RelativeSide.TOP).also(configurator) + fun bottom(configurator: Node.() -> Unit) = relative(RelativeSide.BOTTOM).also(configurator) + + fun front(block: Block, configurator: Node.() -> Unit) = relative(RelativeSide.FRONT).also { it.block(block) }.also(configurator) + fun back(block: Block, configurator: Node.() -> Unit) = relative(RelativeSide.BACK).also { it.block(block) }.also(configurator) + fun left(block: Block, configurator: Node.() -> Unit) = relative(RelativeSide.LEFT).also { it.block(block) }.also(configurator) + fun right(block: Block, configurator: Node.() -> Unit) = relative(RelativeSide.RIGHT).also { it.block(block) }.also(configurator) + fun top(block: Block, configurator: Node.() -> Unit) = relative(RelativeSide.TOP).also { it.block(block) }.also(configurator) + fun bottom(block: Block, configurator: Node.() -> Unit) = relative(RelativeSide.BOTTOM).also { it.block(block) }.also(configurator) + + fun front(block: BlockState, configurator: Node.() -> Unit) = relative(RelativeSide.FRONT).also { it.block(block) }.also(configurator) + fun back(block: BlockState, configurator: Node.() -> Unit) = relative(RelativeSide.BACK).also { it.block(block) }.also(configurator) + fun left(block: BlockState, configurator: Node.() -> Unit) = relative(RelativeSide.LEFT).also { it.block(block) }.also(configurator) + fun right(block: BlockState, configurator: Node.() -> Unit) = relative(RelativeSide.RIGHT).also { it.block(block) }.also(configurator) + fun top(block: BlockState, configurator: Node.() -> Unit) = relative(RelativeSide.TOP).also { it.block(block) }.also(configurator) + fun bottom(block: BlockState, configurator: Node.() -> Unit) = relative(RelativeSide.BOTTOM).also { it.block(block) }.also(configurator) + + fun front(predicate: BlockPredicate, configurator: Node.() -> Unit) = relative(RelativeSide.FRONT).also { it.predicate(predicate) }.also(configurator) + fun back(predicate: BlockPredicate, configurator: Node.() -> Unit) = relative(RelativeSide.BACK).also { it.predicate(predicate) }.also(configurator) + fun left(predicate: BlockPredicate, configurator: Node.() -> Unit) = relative(RelativeSide.LEFT).also { it.predicate(predicate) }.also(configurator) + fun right(predicate: BlockPredicate, configurator: Node.() -> Unit) = relative(RelativeSide.RIGHT).also { it.predicate(predicate) }.also(configurator) + fun top(predicate: BlockPredicate, configurator: Node.() -> Unit) = relative(RelativeSide.TOP).also { it.predicate(predicate) }.also(configurator) + fun bottom(predicate: BlockPredicate, configurator: Node.() -> Unit) = relative(RelativeSide.BOTTOM).also { it.predicate(predicate) }.also(configurator) + + fun build(): MultiblockFactory.Part { + return build(pos) + } + + override var strategy: Strategy = Strategy.OR + } + + fun node(at: BlockPos): Node { + return nodes[at] ?: Node(at) + } + + fun root() = node(BlockPos.ZERO) + fun root(configurator: Node.() -> Unit) = node(BlockPos.ZERO).also(configurator) + + fun copy(): MultiblockBuilder { + val copied = MultiblockBuilder() + + for ((k, v) in nodes) { + val node = copied.Node(k) + copied.nodes[k] = node + node.predicates.addAll(v.predicates) + } + + return copied + } + + fun build(): MultiblockFactory { + return MultiblockFactory(nodes.values.iterator().map { it.build() }.collect(ImmutableSet.toImmutableSet())) + } +} + +class MultiblockFactory(val north: ImmutableSet) { + data class Part( + val pos: BlockPos, + val strategy: MultiblockBuilder.Strategy, + val predicate: ImmutableList, + val children: ImmutableList, + val blockStateTags: ImmutableSet, + val blockTags: ImmutableSet, + val blockEntityTags: ImmutableSet>, + ) + + fun create(pos: BlockPos): Multiblock { + return Multiblock( + pos, + north, + south, + west, + east, + ) + } + + val south: ImmutableSet = north.iterator().map { it.copy(pos = it.pos.rotate(Rotation.CLOCKWISE_180)) }.collect(ImmutableSet.toImmutableSet()) + val west: ImmutableSet = north.iterator().map { it.copy(pos = it.pos.rotate(Rotation.COUNTERCLOCKWISE_90)) }.collect(ImmutableSet.toImmutableSet()) + val east: ImmutableSet = north.iterator().map { it.copy(pos = it.pos.rotate(Rotation.CLOCKWISE_90)) }.collect(ImmutableSet.toImmutableSet()) +} + +class Multiblock( + pos: BlockPos, + north: Collection, + south: Collection, + west: Collection, + east: Collection, +) { + var isValid = false + private set + + private val configurations = ArrayList() + + private class BEList(val tag: MultiblockBuilder.EntityTag) { + val list = ArrayList() + val set = ObjectArraySet() + val setView: Set = Collections.unmodifiableSet(set) + + fun add(blockEntity: BlockEntity) { + if (tag.test(blockEntity)) { + set.add(blockEntity as T) + list.add(blockEntity) + } + } + + fun remove(blockEntity: BlockEntity) { + if (tag.test(blockEntity)) { + check(list.remove(blockEntity as T)) { "Unable to remove $blockEntity from tag $tag" } + + if (blockEntity !in list) { + set.remove(blockEntity) + } + } + } + + fun clear() { + list.clear() + set.clear() + } + } + + private inner class Config(val pos: BlockPos, parts: Collection) { + private inner class Part(val pos: BlockPos, val prototype: MultiblockFactory.Part) { + private var blockEntity: BlockEntity? = null + private var blockState: BlockState? = null + private val assignedBlockEntityLists = ArrayList>(prototype.blockEntityTags.size) + private val assignedBlockStateLists = ArrayList>() + private val assignedBlockLists = ArrayList>() + private val children: ImmutableList = prototype.children.stream().map { Part(pos, it) }.collect(ImmutableList.toImmutableList()) + + init { + prototype.blockEntityTags.forEach { + assignedBlockEntityLists.add(tag2BlockEntity.computeIfAbsent(it, Object2ObjectFunction { _ -> BEList(it as MultiblockBuilder.EntityTag).also { blockEntityLists.add(it) } })) + } + + prototype.blockStateTags.forEach { + assignedBlockStateLists.add(tag2BlockState.computeIfAbsent(it, Object2ObjectFunction { Reference2IntOpenHashMap().also { blockStateLists.add(it) } })) + } + + prototype.blockTags.forEach { + assignedBlockLists.add(tag2Block.computeIfAbsent(it, Object2ObjectFunction { Object2IntOpenHashMap().also { blockLists.add(it) } })) + } + } + + private var lastSuccessfulPathPredicate = -1 + private var lastSuccessfulPathChildren = -1 + + fun test(levelAccessor: LevelAccessor): Boolean { + val test = when (prototype.strategy) { + MultiblockBuilder.Strategy.OR -> { + var status = true + + if (prototype.predicate.isNotEmpty()) { + if (lastSuccessfulPathPredicate != -1 && !prototype.predicate[lastSuccessfulPathPredicate].test(pos, levelAccessor)) { + lastSuccessfulPathPredicate = -1 + } + + if (lastSuccessfulPathPredicate == -1) { + lastSuccessfulPathPredicate = prototype.predicate.indexOfFirst { it.test(pos, levelAccessor) } + status = lastSuccessfulPathPredicate != -1 + } + } + + if (status && children.isNotEmpty()) { + if (lastSuccessfulPathChildren != -1 && !children[lastSuccessfulPathChildren].test(levelAccessor)) { + lastSuccessfulPathChildren = -1 + } + + if (lastSuccessfulPathChildren == -1) { + lastSuccessfulPathChildren = children.indexOfFirst { it.test(levelAccessor) } + status = lastSuccessfulPathChildren != -1 + } + } + + status + } + + MultiblockBuilder.Strategy.AND -> prototype.predicate.all { it.test(pos, levelAccessor) } && children.all { it.test(levelAccessor) } + } + + if (test) { + if (assignedBlockEntityLists.isNotEmpty()) { + val be1 = blockEntity + val be2 = levelAccessor.getBlockEntity(pos) + + if (be1 != be2) { + if (be1 != null) { + assignedBlockEntityLists.forEach { it.remove(be1) } + } + + if (be2 != null) { + assignedBlockEntityLists.forEach { it.add(be2) } + } + + blockEntity = be2 + } + } + + if (assignedBlockStateLists.isNotEmpty() || assignedBlockLists.isNotEmpty()) { + val state = levelAccessor.getBlockState(pos) + val old = blockState + + if (state != old) { + if (old != null) { + assignedBlockStateLists.forEach { + it[old] = it.getInt(old) - 1 + check(it.getInt(old) >= 0) { "Counter for block state $old turned negative" } + } + + assignedBlockLists.forEach { + it[old.block] = it.getInt(old.block) - 1 + check(it.getInt(old.block) >= 0) { "Counter for block ${old.block.registryName} turned negative" } + } + } + + assignedBlockStateLists.forEach { + it[state] = it.getInt(state) + 1 + } + + assignedBlockLists.forEach { + it[state.block] = it.getInt(state.block) + 1 + } + + blockState = state + } + } + } else { + clearFull() + } + + return test + } + + private fun clearFull() { + val blockEntity = blockEntity + + if (blockEntity != null) { + assignedBlockEntityLists.forEach { it.remove(blockEntity) } + } + + val blockState = blockState + + if (blockState != null) { + assignedBlockStateLists.forEach { + it[blockState] = it.getInt(blockState) - 1 + check(it.getInt(blockState) >= 0) { "Counter for block state $blockState turned negative" } + } + + assignedBlockLists.forEach { + it[blockState.block] = it.getInt(blockState.block) - 1 + check(it.getInt(blockState.block) >= 0) { "Counter for block ${blockState.block.registryName} turned negative" } + } + } + + this.blockEntity = null + this.blockState = null + + lastSuccessfulPathPredicate = -1 + lastSuccessfulPathChildren = -1 + + // avoid allocating iterator when empty + if (children.isNotEmpty()) + children.forEach { it.clearFull() } + } + + fun clear() { + blockEntity = null + blockState = null + + lastSuccessfulPathPredicate = -1 + lastSuccessfulPathChildren = -1 + + children.forEach { it.clear() } + } + } + + private val tag2BlockEntity = Object2ObjectOpenHashMap, BEList<*>>() + private val tag2BlockState = Object2ObjectOpenHashMap>() + private val tag2Block = Object2ObjectOpenHashMap>() + + private val blockEntityLists = ArrayList>() + private val blockStateLists = ArrayList>() + private val blockLists = ArrayList>() + + private val parts: ImmutableSet = parts.stream().map { Part(it.pos + pos, it) }.collect(ImmutableSet.toImmutableSet()) + + fun clear() { + blockEntityLists.forEach { it.clear() } + blockStateLists.forEach { it.clear() } + blockLists.forEach { it.clear() } + parts.forEach { it.clear() } + } + + fun update(levelAccessor: LevelAccessor): Boolean { + var valid = true + + for (part in parts) { + valid = part.test(levelAccessor) + if (!valid) break + } + + if (!valid) + clear() + + return valid + } + + fun blockEntities(tag: MultiblockBuilder.EntityTag): Set { + return (tag2BlockEntity[tag]?.setView ?: setOf()) as Set + } + } + + private val north = Config(pos, north).also { configurations.add(it) } + private val south = Config(pos, south).also { configurations.add(it) } + private val west = Config(pos, west).also { configurations.add(it) } + private val east = Config(pos, east).also { configurations.add(it) } + + private var activeConfig: Config? = null + + fun blockEntities(tag: MultiblockBuilder.EntityTag): Set { + return activeConfig?.blockEntities(tag) ?: setOf() + } + + fun update(levelAccessor: LevelAccessor): Boolean { + val activeConfig = activeConfig + + if (activeConfig != null && activeConfig.update(levelAccessor)) { + return true + } else if (activeConfig != null) { + for (config in configurations) { + if (config !== activeConfig && config.update(levelAccessor)) { + this.activeConfig = config + return true + } + } + + this.activeConfig = null + this.isValid = false + return false + } else { + for (config in configurations) { + if (config.update(levelAccessor)) { + this.activeConfig = config + this.isValid = true + return true + } + } + + return false + } + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/math/BlockRotation.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/math/BlockRotation.kt index 1985f0925..fee43c2be 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/math/BlockRotation.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/math/BlockRotation.kt @@ -1,6 +1,5 @@ package ru.dbotthepony.mc.otm.core.math -import com.google.common.collect.ImmutableMap import net.minecraft.core.BlockPos import net.minecraft.core.Direction import net.minecraft.core.Vec3i @@ -27,8 +26,8 @@ operator fun BlockPos.plus(other: BlockRotation): BlockPos { return this + other.normal } -enum class RelativeSide { - FRONT, BACK, LEFT, RIGHT, TOP, BOTTOM +enum class RelativeSide(val default: Direction) { + FRONT(Direction.NORTH), BACK(Direction.SOUTH), LEFT(Direction.WEST), RIGHT(Direction.EAST), TOP(Direction.UP), BOTTOM(Direction.DOWN) } /** 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 fea6ebb36..4db354925 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockEntities.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockEntities.kt @@ -44,6 +44,10 @@ object MBlockEntities { return registry.register(name) { BlockEntityType.Builder.of(factory, *blocks.map { it.get() }.toTypedArray()).build(null) } } + private fun register(name: String, factory: BlockEntityType.BlockEntitySupplier, blocks: Supplier): MDeferredRegister<*>.Entry> { + return registry.register(name) { BlockEntityType.Builder.of(factory, blocks.get()).build(null) } + } + private fun register(name: String, factory: BlockEntityType.BlockEntitySupplier, blocks: Map<*, Block>): MDeferredRegister<*>.Entry> { return registry.register(name) { BlockEntityType.Builder.of(factory, *blocks.values.toTypedArray()).build(null) } } @@ -87,6 +91,8 @@ object MBlockEntities { val POWERED_BLAST_FURNACE by register(MNames.POWERED_BLAST_FURNACE, ::PoweredBlastFurnaceBlockEntity, MBlocks.POWERED_BLAST_FURNACE) val POWERED_SMOKER by register(MNames.POWERED_SMOKER, ::PoweredSmokerBlockEntity, MBlocks.POWERED_SMOKER) + val MULTIBLOCK_TEST by register("multiblock_test", ::MultiblockTestBlockEntity, MBlocks::MULTIBLOCK_TEST) + val ENERGY_CABLES: Map> = SupplierMap(CablesConfig.E.entries.map { conf -> var selfFeed: Supplier> = Supplier { TODO() } selfFeed = register("${conf.name.lowercase()}_energy_cable", { a, b -> SimpleEnergyCableBlockEntity(selfFeed.get(), a, b, conf) }) as Supplier> diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlocks.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlocks.kt index f384631cf..b2539b7b2 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlocks.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlocks.kt @@ -27,6 +27,7 @@ import ru.dbotthepony.mc.otm.block.BlockSphereDebugger import ru.dbotthepony.mc.otm.block.EnergyCableBlock import ru.dbotthepony.mc.otm.block.MatterCableBlock import ru.dbotthepony.mc.otm.block.MatteryBlock +import ru.dbotthepony.mc.otm.block.MultiblockTestBlock import ru.dbotthepony.mc.otm.block.StorageCableBlock import ru.dbotthepony.mc.otm.block.addSimpleDescription import ru.dbotthepony.mc.otm.block.decorative.DevChestBlock @@ -253,6 +254,8 @@ object MBlocks { .strength(3f) ) } + val MULTIBLOCK_TEST by registry.register("multiblock_test") { MultiblockTestBlock() } + init { MRegistry.registerBlocks(registry) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItems.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItems.kt index 04411e1ea..96dc11e0a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItems.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItems.kt @@ -160,6 +160,7 @@ object MItems { val DEBUG_EXPLOSION_SMALL: Item by registry.register(MNames.DEBUG_EXPLOSION_SMALL) { BlockItem(MBlocks.DEBUG_EXPLOSION_SMALL, Item.Properties().stacksTo(64)) } val DEBUG_SPHERE_POINTS: Item by registry.register(MNames.DEBUG_SPHERE_POINTS) { BlockItem(MBlocks.DEBUG_SPHERE_POINTS, Item.Properties().stacksTo(64)) } + val MULTIBLOCK_TEST by registry.register("multiblock_test") { BlockItem(MBlocks.MULTIBLOCK_TEST, Properties().stacksTo(64)) } val TRITANIUM_ANVIL: List From c356cd703e3e1afafbe67d59aeaf51287856a652 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Wed, 17 Jan 2024 17:30:50 +0700 Subject: [PATCH 04/16] :mind_blown: More multiblock code --- .../mc/otm/mixin/BlockEntityMixin.java | 23 ++++++ .../ru/dbotthepony/mc/otm/core/Multiblock.kt | 74 +++++++++++++++++-- .../overdrive_that_matters.mixins.json | 1 + 3 files changed, 92 insertions(+), 6 deletions(-) create mode 100644 src/main/java/ru/dbotthepony/mc/otm/mixin/BlockEntityMixin.java diff --git a/src/main/java/ru/dbotthepony/mc/otm/mixin/BlockEntityMixin.java b/src/main/java/ru/dbotthepony/mc/otm/mixin/BlockEntityMixin.java new file mode 100644 index 000000000..f537e2951 --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/mixin/BlockEntityMixin.java @@ -0,0 +1,23 @@ +package ru.dbotthepony.mc.otm.mixin; + +import net.minecraft.world.level.block.entity.BlockEntity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import ru.dbotthepony.mc.otm.core.MultiblockKt; + +// because i know +// someone +// somewhere +// will try to break the system +// either on purpose or accidentally because of other mod +@Mixin(BlockEntity.class) +public abstract class BlockEntityMixin { + @Inject( + at = @At("TAIL"), + method = "setRemoved()V" + ) + public void setRemovedListener() { + MultiblockKt.onBlockEntityInvalidated((BlockEntity) (Object) this); + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/Multiblock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/Multiblock.kt index b2b571c68..6637b2fdf 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/Multiblock.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/Multiblock.kt @@ -11,19 +11,29 @@ import net.minecraft.core.BlockPos import net.minecraft.core.Direction import net.minecraft.core.Vec3i import net.minecraft.tags.TagKey +import net.minecraft.world.level.Level import net.minecraft.world.level.LevelAccessor import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.Rotation import net.minecraft.world.level.block.entity.BlockEntity import net.minecraft.world.level.block.state.BlockState +import ru.dbotthepony.mc.otm.core.collect.WeakHashSet import ru.dbotthepony.mc.otm.core.collect.collect import ru.dbotthepony.mc.otm.core.collect.map import ru.dbotthepony.mc.otm.core.math.RelativeSide import ru.dbotthepony.mc.otm.core.math.plus import java.util.Collections +import java.util.WeakHashMap import java.util.function.Predicate import kotlin.reflect.KClass +private val blockEntityListeners = WeakHashMap>>() + +fun onBlockEntityInvalidated(blockEntity: BlockEntity) { + blockEntityListeners[blockEntity.level]?.get(blockEntity)?.forEach { it.blockEntityRemoved(blockEntity) } + blockEntityListeners[blockEntity.level]?.remove(blockEntity) +} + fun interface BlockPredicate { fun test(pos: BlockPos, access: LevelAccessor): Boolean @@ -358,14 +368,20 @@ class Multiblock( private val configurations = ArrayList() - private class BEList(val tag: MultiblockBuilder.EntityTag) { + private inner class BEList(val tag: MultiblockBuilder.EntityTag) { val list = ArrayList() val set = ObjectArraySet() val setView: Set = Collections.unmodifiableSet(set) fun add(blockEntity: BlockEntity) { if (tag.test(blockEntity)) { - set.add(blockEntity as T) + if (set.add(blockEntity as T)) { + blockEntityListeners + .computeIfAbsent(blockEntity.level) { WeakHashMap() } + .computeIfAbsent(blockEntity) { WeakHashSet() } + .add(this@Multiblock) + } + list.add(blockEntity) } } @@ -376,11 +392,42 @@ class Multiblock( if (blockEntity !in list) { set.remove(blockEntity) + + val getSet = blockEntityListeners[blockEntity.level]?.get(blockEntity) + + if (getSet != null) { + getSet.remove(this@Multiblock) + + if (getSet.isEmpty()) { + blockEntityListeners[blockEntity.level]?.remove(blockEntity) + } + } } } } + fun blockEntityRemoved(blockEntity: BlockEntity): Boolean { + if (blockEntity in list) { + while (list.remove(blockEntity)) {} + set.remove(blockEntity) + + return true + } + + return false + } + fun clear() { + set.forEach { + val getSet = checkNotNull(blockEntityListeners[it.level]) { "Consistency check failed: No subscriber lists for level ${it.level}" }.get(it) + checkNotNull(getSet) { "Consistency check failed: No subscriber list for $it" } + check(getSet.remove(this@Multiblock)) { "Consistency check failed: Can't remove ${this@Multiblock} from $it subscriber list" } + + if (getSet.isEmpty()) { + blockEntityListeners[it.level]?.remove(it) + } + } + list.clear() set.clear() } @@ -471,12 +518,12 @@ class Multiblock( if (old != null) { assignedBlockStateLists.forEach { it[old] = it.getInt(old) - 1 - check(it.getInt(old) >= 0) { "Counter for block state $old turned negative" } + check(it.getInt(old) >= 0) { "Consistency check failed: Counter for block state $old turned negative" } } assignedBlockLists.forEach { it[old.block] = it.getInt(old.block) - 1 - check(it.getInt(old.block) >= 0) { "Counter for block ${old.block.registryName} turned negative" } + check(it.getInt(old.block) >= 0) { "Consistency check failed: Counter for block ${old.block.registryName} turned negative" } } } @@ -510,12 +557,12 @@ class Multiblock( if (blockState != null) { assignedBlockStateLists.forEach { it[blockState] = it.getInt(blockState) - 1 - check(it.getInt(blockState) >= 0) { "Counter for block state $blockState turned negative" } + check(it.getInt(blockState) >= 0) { "Consistency check failed: Counter for block state $blockState turned negative" } } assignedBlockLists.forEach { it[blockState.block] = it.getInt(blockState.block) - 1 - check(it.getInt(blockState.block) >= 0) { "Counter for block ${blockState.block.registryName} turned negative" } + check(it.getInt(blockState.block) >= 0) { "Consistency check failed: Counter for block ${blockState.block.registryName} turned negative" } } } @@ -575,6 +622,16 @@ class Multiblock( fun blockEntities(tag: MultiblockBuilder.EntityTag): Set { return (tag2BlockEntity[tag]?.setView ?: setOf()) as Set } + + fun blockEntityRemoved(blockEntity: BlockEntity): Boolean { + var any = false + + blockEntityLists.forEach { + any = it.blockEntityRemoved(blockEntity) || any + } + + return any + } } private val north = Config(pos, north).also { configurations.add(it) } @@ -585,9 +642,14 @@ class Multiblock( private var activeConfig: Config? = null fun blockEntities(tag: MultiblockBuilder.EntityTag): Set { + if (!isValid) return emptySet() return activeConfig?.blockEntities(tag) ?: setOf() } + fun blockEntityRemoved(blockEntity: BlockEntity) { + activeConfig?.blockEntityRemoved(blockEntity) + } + fun update(levelAccessor: LevelAccessor): Boolean { val activeConfig = activeConfig diff --git a/src/main/resources/overdrive_that_matters.mixins.json b/src/main/resources/overdrive_that_matters.mixins.json index aa7271058..37f1c45b8 100644 --- a/src/main/resources/overdrive_that_matters.mixins.json +++ b/src/main/resources/overdrive_that_matters.mixins.json @@ -6,6 +6,7 @@ "minVersion": "0.8", "refmap": "overdrive_that_matters.refmap.json", "mixins": [ + "BlockEntityMixin", "EnchantmentHelperMixin", "FoodDataMixin", "MixinPatchProjectileFinder", From 6999b42b1f33a32c70a621db9b47328937c7a9ff Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Wed, 17 Jan 2024 20:02:14 +0700 Subject: [PATCH 05/16] Since OTM does not specifically modify vanilla behavior when it's structures are in "default" state, accept connections to vanilla servers or server with OTM missing --- .../ru/dbotthepony/mc/otm/network/MatteryNetworkChannel.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/network/MatteryNetworkChannel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/network/MatteryNetworkChannel.kt index 7b69da821..ff1e4cf11 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/network/MatteryNetworkChannel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/network/MatteryNetworkChannel.kt @@ -38,7 +38,8 @@ interface MatteryPacket { abstract class MatteryNetworkChannel(val version: Int, val name: String) { val channel: SimpleChannel = ChannelBuilder .named(ResourceLocation(OverdriveThatMatters.MOD_ID, name)) - .acceptedVersions(Channel.VersionTest.exact(version)) + .clientAcceptedVersions { status, version -> (status == Channel.VersionTest.Status.MISSING || status == Channel.VersionTest.Status.VANILLA) || version == this.version } + .serverAcceptedVersions { status, version -> status == Channel.VersionTest.Status.PRESENT || version == this.version } .networkProtocolVersion(version) .simpleChannel() From 604029dcd500479c04d5b0387a6487da05d27fd3 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Wed, 17 Jan 2024 20:11:02 +0700 Subject: [PATCH 06/16] Add missing callback info --- .../java/ru/dbotthepony/mc/otm/mixin/BlockEntityMixin.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/ru/dbotthepony/mc/otm/mixin/BlockEntityMixin.java b/src/main/java/ru/dbotthepony/mc/otm/mixin/BlockEntityMixin.java index f537e2951..860683f11 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/mixin/BlockEntityMixin.java +++ b/src/main/java/ru/dbotthepony/mc/otm/mixin/BlockEntityMixin.java @@ -4,6 +4,7 @@ import net.minecraft.world.level.block.entity.BlockEntity; 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 ru.dbotthepony.mc.otm.core.MultiblockKt; // because i know @@ -17,7 +18,7 @@ public abstract class BlockEntityMixin { at = @At("TAIL"), method = "setRemoved()V" ) - public void setRemovedListener() { + public void setRemovedListener(CallbackInfo ci) { MultiblockKt.onBlockEntityInvalidated((BlockEntity) (Object) this); } } From d540cbef3c1387a98425b21c40c95eab4003fec6 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Thu, 18 Jan 2024 19:28:04 +0700 Subject: [PATCH 07/16] Overflow prevention inside painter block entity --- .../mc/otm/block/entity/decorative/PainterBlockEntity.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/PainterBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/PainterBlockEntity.kt index 7a65e1450..5b594f8de 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/PainterBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/PainterBlockEntity.kt @@ -66,8 +66,8 @@ class PainterBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryDe } override fun fill(resource: FluidStack, action: IFluidHandler.FluidAction): Int { - if (resource.isEmpty || resource.fluid != Fluids.WATER || waterStored() >= MAX_WATER_STORAGE) return 0 - val diff = (waterStored() + resource.amount).coerceAtMost(MAX_WATER_STORAGE) - waterStored() + if (resource.amount <= 0 || resource.fluid != Fluids.WATER || waterStored() >= MAX_WATER_STORAGE) return 0 + val diff = ((waterStored().toLong() + resource.amount.toLong()).coerceAtMost(MAX_WATER_STORAGE.toLong()) - waterStored().toLong()).toInt() if (action.simulate() || diff == 0) return diff dyeStored[null] = waterStored() + diff return diff From 26382d96019438f3a84cfe8fcb6f7da995394bbf Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Thu, 18 Jan 2024 23:22:31 +0700 Subject: [PATCH 08/16] Fix wrong blast resistance of tritanium striped block --- src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlocks.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlocks.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlocks.kt index b2539b7b2..14c471d08 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlocks.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlocks.kt @@ -229,7 +229,7 @@ object MBlocks { .sound(SoundType.BASALT) .requiresCorrectToolForDrops() .explosionResistance(80f) - .strength(4f) + .destroyTime(2.5f) ) } val TRITANIUM_STRIPED_STAIRS: Block by registry.register(MNames.TRITANIUM_STRIPED_STAIRS) { StairBlock( @@ -251,7 +251,7 @@ object MBlocks { .sound(SoundType.BASALT) .requiresCorrectToolForDrops() .explosionResistance(40f) - .strength(3f) + .destroyTime(1.5f) ) } val MULTIBLOCK_TEST by registry.register("multiblock_test") { MultiblockTestBlock() } From 317cb986133e2c5b26072ec4f193c1ca25367497 Mon Sep 17 00:00:00 2001 From: YuRaNnNzZZ Date: Fri, 19 Jan 2024 13:59:05 +0300 Subject: [PATCH 09/16] =?UTF-8?q?=D0=91=D0=BB=D0=BE=D0=BA=20=D0=B2=20?= =?UTF-8?q?=D1=82=D0=BE=D1=87=D0=BA=D0=B5=20559,=2062,=20-131=20=D1=81?= =?UTF-8?q?=D0=BE=D0=B4=D0=B5=D1=80=D0=B6=D0=B8=D1=82=20=D1=81=D0=BB=D0=B5?= =?UTF-8?q?=D0=B4=D1=83=D1=8E=D1=89=D1=83=D1=8E=20=D0=B8=D0=BD=D1=84=D0=BE?= =?UTF-8?q?=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D1=8E:=20-2147481752=20=D0=91?= =?UTF-8?q?=D0=BB=D0=BE=D0=BA=20=D0=B2=20=D1=82=D0=BE=D1=87=D0=BA=D0=B5=20?= =?UTF-8?q?559,=2062,=20-131=20=D1=81=D0=BE=D0=B4=D0=B5=D1=80=D0=B6=D0=B8?= =?UTF-8?q?=D1=82=20=D1=81=D0=BB=D0=B5=D0=B4=D1=83=D1=8E=D1=89=D1=83=D1=8E?= =?UTF-8?q?=20=D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D1=8E?= =?UTF-8?q?:=20-2147481786=20=D0=91=D0=BB=D0=BE=D0=BA=20=D0=B2=20=D1=82?= =?UTF-8?q?=D0=BE=D1=87=D0=BA=D0=B5=20559,=2062,=20-131=20=D1=81=D0=BE?= =?UTF-8?q?=D0=B4=D0=B5=D1=80=D0=B6=D0=B8=D1=82=20=D1=81=D0=BB=D0=B5=D0=B4?= =?UTF-8?q?=D1=83=D1=8E=D1=89=D1=83=D1=8E=20=D0=B8=D0=BD=D1=84=D0=BE=D1=80?= =?UTF-8?q?=D0=BC=D0=B0=D1=86=D0=B8=D1=8E:=201839=20=D0=91=D0=BB=D0=BE?= =?UTF-8?q?=D0=BA=20=D0=B2=20=D1=82=D0=BE=D1=87=D0=BA=D0=B5=20559,=2062,?= =?UTF-8?q?=20-131=20=D1=81=D0=BE=D0=B4=D0=B5=D1=80=D0=B6=D0=B8=D1=82=20?= =?UTF-8?q?=D1=81=D0=BB=D0=B5=D0=B4=D1=83=D1=8E=D1=89=D1=83=D1=8E=20=D0=B8?= =?UTF-8?q?=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D1=8E:=20-2147?= =?UTF-8?q?481832=20=D0=91=D0=BB=D0=BE=D0=BA=20=D0=B2=20=D1=82=D0=BE=D1=87?= =?UTF-8?q?=D0=BA=D0=B5=20559,=2062,=20-131=20=D1=81=D0=BE=D0=B4=D0=B5?= =?UTF-8?q?=D1=80=D0=B6=D0=B8=D1=82=20=D1=81=D0=BB=D0=B5=D0=B4=D1=83=D1=8E?= =?UTF-8?q?=D1=89=D1=83=D1=8E=20=D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8E:=20-2147481854=20=D0=91=D0=BB=D0=BE=D0=BA=20?= =?UTF-8?q?=D0=B2=20=D1=82=D0=BE=D1=87=D0=BA=D0=B5=20559,=2062,=20-131=20?= =?UTF-8?q?=D1=81=D0=BE=D0=B4=D0=B5=D1=80=D0=B6=D0=B8=D1=82=20=D1=81=D0=BB?= =?UTF-8?q?=D0=B5=D0=B4=D1=83=D1=8E=D1=89=D1=83=D1=8E=20=D0=B8=D0=BD=D1=84?= =?UTF-8?q?=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D1=8E:=201777?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mc/otm/block/entity/decorative/PainterBlockEntity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/PainterBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/PainterBlockEntity.kt index 7a65e1450..048239721 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/PainterBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/PainterBlockEntity.kt @@ -67,7 +67,7 @@ class PainterBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryDe override fun fill(resource: FluidStack, action: IFluidHandler.FluidAction): Int { if (resource.isEmpty || resource.fluid != Fluids.WATER || waterStored() >= MAX_WATER_STORAGE) return 0 - val diff = (waterStored() + resource.amount).coerceAtMost(MAX_WATER_STORAGE) - waterStored() + val diff = ((waterStored().toLong() + resource.amount.toLong()).coerceAtMost(MAX_WATER_STORAGE.toLong()) - waterStored().toLong()).toInt() if (action.simulate() || diff == 0) return diff dyeStored[null] = waterStored() + diff return diff From d669fcb28d03e557db680c712a600a3403a68cf2 Mon Sep 17 00:00:00 2001 From: YuRaNnNzZZ Date: Fri, 19 Jan 2024 15:55:48 +0300 Subject: [PATCH 10/16] =?UTF-8?q?=D1=88=D0=B8=D0=B7=D0=B0=20=D1=81=20?= =?UTF-8?q?=D0=BC=D0=BE=D0=B4=D0=B5=D0=BB=D1=8F=D0=BC=D0=B8=20=D0=B8=20?= =?UTF-8?q?=D0=B1=D0=BB=D0=BE=D0=BA=D1=81=D1=82=D0=B5=D0=B9=D1=82=D0=B0?= =?UTF-8?q?=D0=BC=D0=B8=20=D0=BA=D0=B0=D0=B1=D0=B5=D0=BB=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mc/otm/datagen/blocks/BlockModels.kt | 6 ++ .../mc/otm/datagen/blocks/BlockStates.kt | 44 +++++++++++ .../mc/otm/datagen/items/ItemModels.kt | 1 - .../datagen/models/MatteryModelProvider.kt | 13 ++++ .../blockstates/advanced_energy_cable.json | 74 ------------------- .../blockstates/crude_energy_cable.json | 74 ------------------- .../blockstates/matter_cable.json | 74 ------------------- .../blockstates/regular_energy_cable.json | 74 ------------------- .../blockstates/storage_cable.json | 74 ------------------- .../superconductor_energy_cable.json | 74 ------------------- .../models/block/base_cable_connection.json | 19 +++++ .../models/block/base_cable_core.json | 21 ++++++ .../block/storage_cable_connection.json | 20 ----- .../models/block/storage_cable_core.json | 22 ------ .../models/item/base_cable.json | 49 ++++++++++++ .../models/item/matter_cable.json | 50 +++++++++++++ .../models/item/storage_cable.json | 22 ------ 17 files changed, 202 insertions(+), 509 deletions(-) delete mode 100644 src/main/resources/assets/overdrive_that_matters/blockstates/advanced_energy_cable.json delete mode 100644 src/main/resources/assets/overdrive_that_matters/blockstates/crude_energy_cable.json delete mode 100644 src/main/resources/assets/overdrive_that_matters/blockstates/matter_cable.json delete mode 100644 src/main/resources/assets/overdrive_that_matters/blockstates/regular_energy_cable.json delete mode 100644 src/main/resources/assets/overdrive_that_matters/blockstates/storage_cable.json delete mode 100644 src/main/resources/assets/overdrive_that_matters/blockstates/superconductor_energy_cable.json create mode 100644 src/main/resources/assets/overdrive_that_matters/models/block/base_cable_connection.json create mode 100644 src/main/resources/assets/overdrive_that_matters/models/block/base_cable_core.json delete mode 100644 src/main/resources/assets/overdrive_that_matters/models/block/storage_cable_connection.json delete mode 100644 src/main/resources/assets/overdrive_that_matters/models/block/storage_cable_core.json create mode 100644 src/main/resources/assets/overdrive_that_matters/models/item/base_cable.json create mode 100644 src/main/resources/assets/overdrive_that_matters/models/item/matter_cable.json delete mode 100644 src/main/resources/assets/overdrive_that_matters/models/item/storage_cable.json diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/blocks/BlockModels.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/blocks/BlockModels.kt index 0919c9a83..884505d6c 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/blocks/BlockModels.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/blocks/BlockModels.kt @@ -10,6 +10,12 @@ fun addBlockModels(provider: MatteryBlockModelProvider) { resourceCubeAll(MBlocks.DEEPSLATE_TRITANIUM_ORE) resourceCubeAll(MBlocks.TRITANIUM_INGOT_BLOCK) + cable("crude_energy_cable", "block/power_cable_0") + cable("regular_energy_cable", "block/power_cable_1") + cable("advanced_energy_cable", "block/power_cable_2") + cable("superconductor_energy_cable", "block/power_cable_3") + cable("storage_cable", "block/storage_cable") + colored(MBlocks.COBBLESTONE_GENERATOR, listOf("0", "particle")) colored(MBlocks.ESSENCE_STORAGE, listOf("0", "particle")) colored(MBlocks.ITEM_MONITOR, listOf("0", "particle")) diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/blocks/BlockStates.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/blocks/BlockStates.kt index e9de264e2..cd07f3fde 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/blocks/BlockStates.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/blocks/BlockStates.kt @@ -191,5 +191,49 @@ fun addBlockStates(provider: MatteryBlockStateProvider) { part().modelFile(provider.models().getExistingFile(modLocation("storage_cable_core"))) .addModel().end() } + + with(provider.getMultipartBuilder(MBlocks.MATTER_CABLE)) { + for (dir in BlockRotationFreedom.DIRECTIONAL.possibleValues) { + part().modelFile(provider.models().getExistingFile(modLocation("matter_cable_connection"))) + .rotationX(dir.front.xRotationBlockstateSouth()) + .rotationY(dir.front.yRotationBlockstateSouth()) + .addModel() + .condition(CableBlock.MAPPING_CONNECTION_PROP[dir.front]!!, true) + .end() + } + + part().modelFile(provider.models().getExistingFile(modLocation("matter_cable_core"))) + .addModel().end() + } + + with(provider.getMultipartBuilder(MBlocks.STORAGE_CABLE)) { + for (dir in BlockRotationFreedom.DIRECTIONAL.possibleValues) { + part().modelFile(provider.models().getExistingFile(modLocation("storage_cable_connection"))) + .rotationX(dir.front.xRotationBlockstateSouth()) + .rotationY(dir.front.yRotationBlockstateSouth()) + .addModel() + .condition(CableBlock.MAPPING_CONNECTION_PROP[dir.front]!!, true) + .end() + } + + part().modelFile(provider.models().getExistingFile(modLocation("storage_cable_core"))) + .addModel().end() + } + + for (block in MBlocks.ENERGY_CABLES) { + with(provider.getMultipartBuilder(block.value)) { + for (dir in BlockRotationFreedom.DIRECTIONAL.possibleValues) { + part().modelFile(provider.models().getExistingFile(modLocation("${block.value.registryName!!.path}_connection"))) + .rotationX(dir.front.xRotationBlockstateSouth()) + .rotationY(dir.front.yRotationBlockstateSouth()) + .addModel() + .condition(CableBlock.MAPPING_CONNECTION_PROP[dir.front]!!, true) + .end() + } + + part().modelFile(provider.models().getExistingFile(modLocation("${block.value.registryName!!.path}_core"))) + .addModel().end() + } + } } } diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/items/ItemModels.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/items/ItemModels.kt index d3de3d6dc..2d3244968 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/items/ItemModels.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/items/ItemModels.kt @@ -172,7 +172,6 @@ fun addItemModels(provider: MatteryItemModelProvider) { provider.coloredWithBaseBlock(MItems.MATTER_SCANNER, "matter_scanner", "_idle") provider.coloredWithBaseBlock(MItems.MATTER_REPLICATOR, "matter_replicator", "_idle") provider.coloredWithBaseBlock(MItems.DRIVE_VIEWER, "drive_viewer", "_idle") - provider.block(MItems.MATTER_CABLE, "matter_cable_core") provider.coloredWithBaseBlock(MItems.MATTER_DECOMPOSER, "matter_decomposer", "_idle") provider.coloredWithBaseBlock(MItems.ENERGY_SERVO, "energy_servo") provider.coloredWithBaseBlock(MItems.ESSENCE_STORAGE, "essence_storage") diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/models/MatteryModelProvider.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/models/MatteryModelProvider.kt index 6384439fb..63ec5c1f1 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/models/MatteryModelProvider.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/models/MatteryModelProvider.kt @@ -142,4 +142,17 @@ class MatteryBlockModelProvider(event: GatherDataEvent) : BlockModelProvider(eve colored(modelName, state, textureKeys.associateWith { modelName }) } } + + fun cable(modelName: String, textureName: String) { + exec { + withExistingParent("block/${modelName}_core", modLocation("block/base_cable_core")) + .texture("0", textureName) + + withExistingParent("block/${modelName}_connection", modLocation("block/base_cable_connection")) + .texture("0", textureName) + + withExistingParent("item/${modelName}", modLocation("item/base_cable")) + .texture("0", textureName) + } + } } diff --git a/src/main/resources/assets/overdrive_that_matters/blockstates/advanced_energy_cable.json b/src/main/resources/assets/overdrive_that_matters/blockstates/advanced_energy_cable.json deleted file mode 100644 index ae8a815be..000000000 --- a/src/main/resources/assets/overdrive_that_matters/blockstates/advanced_energy_cable.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "multipart": [ - { - "apply": { - "model": "overdrive_that_matters:block/storage_cable_core" - } - }, - - { - "when": { - "connect_south": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection" - } - }, - - { - "when": { - "connect_west": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection", - "y": 90 - } - }, - - { - "when": { - "connect_north": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection", - "y": 180 - } - }, - - { - "when": { - "connect_east": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection", - "y": 270 - } - }, - - { - "when": { - "connect_up": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection", - "x": 90 - } - }, - - { - "when": { - "connect_down": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection", - "x": 270 - } - } - ] -} \ No newline at end of file diff --git a/src/main/resources/assets/overdrive_that_matters/blockstates/crude_energy_cable.json b/src/main/resources/assets/overdrive_that_matters/blockstates/crude_energy_cable.json deleted file mode 100644 index ae8a815be..000000000 --- a/src/main/resources/assets/overdrive_that_matters/blockstates/crude_energy_cable.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "multipart": [ - { - "apply": { - "model": "overdrive_that_matters:block/storage_cable_core" - } - }, - - { - "when": { - "connect_south": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection" - } - }, - - { - "when": { - "connect_west": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection", - "y": 90 - } - }, - - { - "when": { - "connect_north": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection", - "y": 180 - } - }, - - { - "when": { - "connect_east": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection", - "y": 270 - } - }, - - { - "when": { - "connect_up": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection", - "x": 90 - } - }, - - { - "when": { - "connect_down": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection", - "x": 270 - } - } - ] -} \ No newline at end of file diff --git a/src/main/resources/assets/overdrive_that_matters/blockstates/matter_cable.json b/src/main/resources/assets/overdrive_that_matters/blockstates/matter_cable.json deleted file mode 100644 index e751d40ea..000000000 --- a/src/main/resources/assets/overdrive_that_matters/blockstates/matter_cable.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "multipart": [ - { - "apply": { - "model": "overdrive_that_matters:block/matter_cable_core" - } - }, - - { - "when": { - "connect_south": true - }, - - "apply": { - "model": "overdrive_that_matters:block/matter_cable_connection" - } - }, - - { - "when": { - "connect_west": true - }, - - "apply": { - "model": "overdrive_that_matters:block/matter_cable_connection", - "y": 90 - } - }, - - { - "when": { - "connect_north": true - }, - - "apply": { - "model": "overdrive_that_matters:block/matter_cable_connection", - "y": 180 - } - }, - - { - "when": { - "connect_east": true - }, - - "apply": { - "model": "overdrive_that_matters:block/matter_cable_connection", - "y": 270 - } - }, - - { - "when": { - "connect_up": true - }, - - "apply": { - "model": "overdrive_that_matters:block/matter_cable_connection", - "x": 90 - } - }, - - { - "when": { - "connect_down": true - }, - - "apply": { - "model": "overdrive_that_matters:block/matter_cable_connection", - "x": 270 - } - } - ] -} \ No newline at end of file diff --git a/src/main/resources/assets/overdrive_that_matters/blockstates/regular_energy_cable.json b/src/main/resources/assets/overdrive_that_matters/blockstates/regular_energy_cable.json deleted file mode 100644 index ae8a815be..000000000 --- a/src/main/resources/assets/overdrive_that_matters/blockstates/regular_energy_cable.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "multipart": [ - { - "apply": { - "model": "overdrive_that_matters:block/storage_cable_core" - } - }, - - { - "when": { - "connect_south": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection" - } - }, - - { - "when": { - "connect_west": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection", - "y": 90 - } - }, - - { - "when": { - "connect_north": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection", - "y": 180 - } - }, - - { - "when": { - "connect_east": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection", - "y": 270 - } - }, - - { - "when": { - "connect_up": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection", - "x": 90 - } - }, - - { - "when": { - "connect_down": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection", - "x": 270 - } - } - ] -} \ No newline at end of file diff --git a/src/main/resources/assets/overdrive_that_matters/blockstates/storage_cable.json b/src/main/resources/assets/overdrive_that_matters/blockstates/storage_cable.json deleted file mode 100644 index ae8a815be..000000000 --- a/src/main/resources/assets/overdrive_that_matters/blockstates/storage_cable.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "multipart": [ - { - "apply": { - "model": "overdrive_that_matters:block/storage_cable_core" - } - }, - - { - "when": { - "connect_south": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection" - } - }, - - { - "when": { - "connect_west": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection", - "y": 90 - } - }, - - { - "when": { - "connect_north": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection", - "y": 180 - } - }, - - { - "when": { - "connect_east": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection", - "y": 270 - } - }, - - { - "when": { - "connect_up": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection", - "x": 90 - } - }, - - { - "when": { - "connect_down": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection", - "x": 270 - } - } - ] -} \ No newline at end of file diff --git a/src/main/resources/assets/overdrive_that_matters/blockstates/superconductor_energy_cable.json b/src/main/resources/assets/overdrive_that_matters/blockstates/superconductor_energy_cable.json deleted file mode 100644 index ae8a815be..000000000 --- a/src/main/resources/assets/overdrive_that_matters/blockstates/superconductor_energy_cable.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "multipart": [ - { - "apply": { - "model": "overdrive_that_matters:block/storage_cable_core" - } - }, - - { - "when": { - "connect_south": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection" - } - }, - - { - "when": { - "connect_west": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection", - "y": 90 - } - }, - - { - "when": { - "connect_north": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection", - "y": 180 - } - }, - - { - "when": { - "connect_east": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection", - "y": 270 - } - }, - - { - "when": { - "connect_up": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection", - "x": 90 - } - }, - - { - "when": { - "connect_down": true - }, - - "apply": { - "model": "overdrive_that_matters:block/storage_cable_connection", - "x": 270 - } - } - ] -} \ No newline at end of file diff --git a/src/main/resources/assets/overdrive_that_matters/models/block/base_cable_connection.json b/src/main/resources/assets/overdrive_that_matters/models/block/base_cable_connection.json new file mode 100644 index 000000000..c774f91ee --- /dev/null +++ b/src/main/resources/assets/overdrive_that_matters/models/block/base_cable_connection.json @@ -0,0 +1,19 @@ +{ + "parent": "block/block", + "texture_size": [16, 16], + "textures": { + "particle": "#0" + }, + "elements": [ + { + "from": [ 5, 5, 11 ], + "to": [ 11, 11, 16 ], + "faces": { + "down": {"uv": [6, 0, 11, 6],"rotation": 90, "texture": "#0" }, + "up": {"uv": [6, 0, 11, 6],"rotation": 90, "texture": "#0" }, + "west": {"uv": [6, 0, 11, 6], "texture": "#0" }, + "east": {"uv": [6, 0, 11, 6], "texture": "#0" } + } + } + ] +} diff --git a/src/main/resources/assets/overdrive_that_matters/models/block/base_cable_core.json b/src/main/resources/assets/overdrive_that_matters/models/block/base_cable_core.json new file mode 100644 index 000000000..353685030 --- /dev/null +++ b/src/main/resources/assets/overdrive_that_matters/models/block/base_cable_core.json @@ -0,0 +1,21 @@ +{ + "parent": "block/block", + "texture_size": [16, 16], + "textures": { + "particle": "#0" + }, + "elements": [ + { + "from": [ 5, 5, 5 ], + "to": [ 11, 11, 11 ], + "faces": { + "down": {"uv": [0, 0, 6, 6], "texture": "#0" }, + "up": {"uv": [0, 0, 6, 6], "texture": "#0" }, + "north": {"uv": [0, 0, 6, 6], "texture": "#0" }, + "south": {"uv": [0, 0, 6, 6], "texture": "#0" }, + "west": {"uv": [0, 0, 6, 6], "texture": "#0" }, + "east": {"uv": [0, 0, 6, 6], "texture": "#0" } + } + } + ] +} diff --git a/src/main/resources/assets/overdrive_that_matters/models/block/storage_cable_connection.json b/src/main/resources/assets/overdrive_that_matters/models/block/storage_cable_connection.json deleted file mode 100644 index 21034ce5a..000000000 --- a/src/main/resources/assets/overdrive_that_matters/models/block/storage_cable_connection.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "parent": "block/block", - "texture_size": [16, 16], - "textures": { - "connection": "overdrive_that_matters:block/storage_cable", - "particle": "overdrive_that_matters:block/storage_cable" - }, - "elements": [ - { - "from": [ 5, 5, 11 ], - "to": [ 11, 11, 16 ], - "faces": { - "down": {"uv": [6, 0, 11, 6],"rotation": 90, "texture": "#connection" }, - "up": {"uv": [6, 0, 11, 6],"rotation": 90, "texture": "#connection" }, - "west": {"uv": [6, 0, 11, 6], "texture": "#connection" }, - "east": {"uv": [6, 0, 11, 6], "texture": "#connection" } - } - } - ] -} diff --git a/src/main/resources/assets/overdrive_that_matters/models/block/storage_cable_core.json b/src/main/resources/assets/overdrive_that_matters/models/block/storage_cable_core.json deleted file mode 100644 index 82ce8a212..000000000 --- a/src/main/resources/assets/overdrive_that_matters/models/block/storage_cable_core.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "parent": "block/block", - "texture_size": [16, 16], - "textures": { - "core": "overdrive_that_matters:block/storage_cable", - "particle": "overdrive_that_matters:block/storage_cable" - }, - "elements": [ - { - "from": [ 5, 5, 5 ], - "to": [ 11, 11, 11 ], - "faces": { - "down": {"uv": [0, 0, 6, 6], "texture": "#core" }, - "up": {"uv": [0, 0, 6, 6], "texture": "#core" }, - "north": {"uv": [0, 0, 6, 6], "texture": "#core" }, - "south": {"uv": [0, 0, 6, 6], "texture": "#core" }, - "west": {"uv": [0, 0, 6, 6], "texture": "#core" }, - "east": {"uv": [0, 0, 6, 6], "texture": "#core" } - } - } - ] -} diff --git a/src/main/resources/assets/overdrive_that_matters/models/item/base_cable.json b/src/main/resources/assets/overdrive_that_matters/models/item/base_cable.json new file mode 100644 index 000000000..80b3fb46b --- /dev/null +++ b/src/main/resources/assets/overdrive_that_matters/models/item/base_cable.json @@ -0,0 +1,49 @@ +{ + "parent": "block/block", + "texture_size": [16, 16], + "textures": { + "particle": "#0" + }, + "elements": [ + { + "from": [5, 5, 5], + "to": [11, 11, 11], + "faces": { + "north": {"uv": [0, 0, 6, 6], "texture": "#0"}, + "south": {"uv": [0, 0, 6, 6], "texture": "#0"}, + "up": {"uv": [0, 0, 6, 6], "rotation": 180, "texture": "#0"}, + "down": {"uv": [0, 0, 6, 6], "rotation": 180, "texture": "#0"} + } + }, + { + "from": [0, 5, 5], + "to": [5, 11, 11], + "faces": { + "north": {"uv": [6, 0, 11, 6], "texture": "#0"}, + "south": {"uv": [6, 6, 11, 0], "rotation": 180, "texture": "#0"}, + "west": {"uv": [0, 0, 6, 6], "texture": "#0"}, + "up": {"uv": [6, 0, 11, 6], "rotation": 180, "texture": "#0"}, + "down": {"uv": [6, 0, 11, 6], "rotation": 180, "texture": "#0"} + } + }, + { + "from": [11, 5, 5], + "to": [16, 11, 11], + "faces": { + "north": {"uv": [11, 0, 16, 6], "texture": "#0"}, + "east": {"uv": [0, 0, 6, 6], "texture": "#0"}, + "south": {"uv": [11, 6, 16, 0], "rotation": 180, "texture": "#0"}, + "up": {"uv": [11, 0, 16, 6], "rotation": 180, "texture": "#0"}, + "down": {"uv": [11, 0, 16, 6], "rotation": 180, "texture": "#0"} + } + } + ], + "gui_light": "front", + "display": { + "gui": { + "rotation": [0, 0, 0], + "translation": [0, 0, 0], + "scale": [1, 1, 1] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/overdrive_that_matters/models/item/matter_cable.json b/src/main/resources/assets/overdrive_that_matters/models/item/matter_cable.json new file mode 100644 index 000000000..530e26553 --- /dev/null +++ b/src/main/resources/assets/overdrive_that_matters/models/item/matter_cable.json @@ -0,0 +1,50 @@ +{ + "parent": "block/block", + "texture_size": [16, 16], + "textures": { + "0": "overdrive_that_matters:block/matter_cable", + "particle": "#0" + }, + "elements": [ + { + "from": [6, 6, 6], + "to": [10, 10, 10], + "faces": { + "north": {"uv": [0, 0, 4, 4], "texture": "#0"}, + "south": {"uv": [0, 0, 4, 4], "texture": "#0"}, + "up": {"uv": [0, 0, 4, 4], "texture": "#0"}, + "down": {"uv": [0, 0, 4, 4], "texture": "#0"} + } + }, + { + "from": [0, 6, 6], + "to": [6, 10, 10], + "faces": { + "north": {"uv": [4, 0, 10, 4], "texture": "#0"}, + "south": {"uv": [10, 0, 4, 4], "texture": "#0"}, + "west": {"uv": [0, 0, 4, 4], "texture": "#0"}, + "up": {"uv": [10, 0, 4, 4], "texture": "#0"}, + "down": {"uv": [10, 0, 4, 4], "texture": "#0"} + } + }, + { + "from": [10, 6, 6], + "to": [16, 10, 10], + "faces": { + "north": {"uv": [10, 0, 16, 4], "texture": "#0"}, + "east": {"uv": [0, 0, 4, 4], "texture": "#0"}, + "south": {"uv": [16, 0, 10, 4], "texture": "#0"}, + "up": {"uv": [16, 0, 10, 4], "texture": "#0"}, + "down": {"uv": [16, 0, 10, 4], "texture": "#0"} + } + } + ], + "gui_light": "front", + "display": { + "gui": { + "rotation": [0, 0, 0], + "translation": [0, 0, 0], + "scale": [1, 1, 1] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/overdrive_that_matters/models/item/storage_cable.json b/src/main/resources/assets/overdrive_that_matters/models/item/storage_cable.json deleted file mode 100644 index e0355ccb3..000000000 --- a/src/main/resources/assets/overdrive_that_matters/models/item/storage_cable.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "parent": "block/block", - "texture_size": [16, 16], - "textures": { - "core": "overdrive_that_matters:block/storage_cable", - "particle": "overdrive_that_matters:block/storage_cable" - }, - "elements": [ - { - "from": [ 6, 6, 6 ], - "to": [ 10, 10, 10 ], - "faces": { - "down": {"uv": [0, 0, 4, 4], "texture": "#core" }, - "up": {"uv": [0, 0, 4, 4], "texture": "#core" }, - "north": {"uv": [0, 0, 4, 4], "texture": "#core" }, - "south": {"uv": [0, 0, 4, 4], "texture": "#core" }, - "west": {"uv": [0, 0, 4, 4], "texture": "#core" }, - "east": {"uv": [0, 0, 4, 4], "texture": "#core" } - } - } - ] -} From 8ebc611c7cbc27970c525b8e8a8626e71ec61c8b Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Sat, 20 Jan 2024 18:31:39 +0700 Subject: [PATCH 11/16] Custom splashes --- .../mc/otm/mixin/SplashManagerMixin.java | 40 +++++++++++++++++++ .../overdrive_that_matters.mixins.json | 3 +- 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 src/main/java/ru/dbotthepony/mc/otm/mixin/SplashManagerMixin.java diff --git a/src/main/java/ru/dbotthepony/mc/otm/mixin/SplashManagerMixin.java b/src/main/java/ru/dbotthepony/mc/otm/mixin/SplashManagerMixin.java new file mode 100644 index 000000000..99e17c70e --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/mixin/SplashManagerMixin.java @@ -0,0 +1,40 @@ +package ru.dbotthepony.mc.otm.mixin; + +import net.minecraft.client.resources.SplashManager; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.util.profiling.ProfilerFiller; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.List; + +@Mixin(SplashManager.class) +public abstract class SplashManagerMixin { + @Shadow + public List splashes; + + @Inject( + at = @At("TAIL"), + method = "apply(Ljava/util/List;Lnet/minecraft/server/packs/resources/ResourceManager;Lnet/minecraft/util/profiling/ProfilerFiller;)V" + ) + public void otmSplashes(List splashes, ResourceManager p_118879_, ProfilerFiller p_118880_, CallbackInfo ci) { + this.splashes.add("42 is the answer!"); + this.splashes.add("Now with matter!"); + this.splashes.add("Now with four dimensions!"); + this.splashes.add("Now with more ways to slice Creepers!"); + this.splashes.add("Batteries not included!"); + this.splashes.add("As it was 13 nanoseconds ago!"); + this.splashes.add("Smart AI is smart enough to fail Turing test!"); + this.splashes.add("Neural computing!"); + this.splashes.add("Swimming through quantum field!"); + this.splashes.add("For biological and digital alike!"); + this.splashes.add("Digital is the next form of Biological!"); + + this.splashes.add("Also try Starbound!"); + this.splashes.add("Also try No Man's Sky!"); + this.splashes.add("Also try Factorio!"); + } +} diff --git a/src/main/resources/overdrive_that_matters.mixins.json b/src/main/resources/overdrive_that_matters.mixins.json index 37f1c45b8..95ba2b017 100644 --- a/src/main/resources/overdrive_that_matters.mixins.json +++ b/src/main/resources/overdrive_that_matters.mixins.json @@ -23,6 +23,7 @@ ], "client": [ "MixinGameRenderer", - "MixinMinecraft" + "MixinMinecraft", + "SplashManagerMixin" ] } From 7c794126b655f26146a526cdbbd89c3f248444ae Mon Sep 17 00:00:00 2001 From: YuRaNnNzZZ Date: Sun, 21 Jan 2024 11:55:58 +0300 Subject: [PATCH 12/16] slurp --- .../mc/otm/datagen/lang/English.kt | 4 +- .../mc/otm/datagen/lang/Russian.kt | 4 +- .../entity/tech/EssenceStorageBlockEntity.kt | 39 +++++++++++++++++++ .../mc/otm/config/MachinesConfig.kt | 14 +++++++ .../resources/META-INF/accesstransformer.cfg | 2 + 5 files changed, 59 insertions(+), 4 deletions(-) diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt index c86a0526d..2140cb5ed 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt @@ -608,8 +608,8 @@ private fun items(provider: MatteryLanguageProvider) { add(MItems.ESSENCE_CAPSULE, "Essence Capsule") add(MItems.ESSENCE_DRIVE, "Essence Memory Holotape") add(MItems.ESSENCE_SERVO, "Essence Servo") - add(MItems.ESSENCE_SERVO, "desc", "Allows to 'pump' essence involving fleshy humanoids") - add(MItems.ESSENCE_SERVO, "desc2", "Can be used standalone, or as tool inside Essence Servo") + add(MItems.ESSENCE_SERVO, "desc", "Allows to absorb nearby experience orbs directly into essence storage") + add(MItems.ESSENCE_SERVO, "desc2", "Can be used as a tool to pump essence manually") add(MItems.NUTRIENT_PASTE, "Nutrient Paste") diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt index 579fac976..b975b1b16 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt @@ -612,8 +612,8 @@ private fun items(provider: MatteryLanguageProvider) { add(MItems.ESSENCE_CAPSULE, "Капсула эссенции") add(MItems.ESSENCE_DRIVE, "Голодиск воспоминаний андроида") add(MItems.ESSENCE_SERVO, "Помпа эссенции") - add(MItems.ESSENCE_SERVO, "desc", "Позволяет 'перекачивать' эссенцию гуманоидов из плоти") - add(MItems.ESSENCE_SERVO, "desc2", "Может быть использовано напрямую, или как инструмент внутри хранилища эссенции") + add(MItems.ESSENCE_SERVO, "desc", "Позволяет всасывать близлежащие сферы опыта напрямую в хранилище эссенции") + add(MItems.ESSENCE_SERVO, "desc2", "Может использоваться как инструмент для ручной перекачки эссенции") add(MItems.NUTRIENT_PASTE, "Питательная паста") diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EssenceStorageBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EssenceStorageBlockEntity.kt index 58a1d287c..09b936abb 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EssenceStorageBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EssenceStorageBlockEntity.kt @@ -1,6 +1,10 @@ package ru.dbotthepony.mc.otm.block.entity.tech import net.minecraft.core.BlockPos +import net.minecraft.server.level.ServerLevel +import net.minecraft.sounds.SoundEvents +import net.minecraft.sounds.SoundSource +import net.minecraft.world.entity.ExperienceOrb import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Player import net.minecraft.world.inventory.AbstractContainerMenu @@ -12,9 +16,13 @@ import net.minecraftforge.fluids.capability.IFluidHandler import ru.dbotthepony.mc.otm.block.entity.ExperienceStorage.Companion.XP_TO_LIQUID_RATIO import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity import ru.dbotthepony.mc.otm.capability.item.CombinedItemHandler +import ru.dbotthepony.mc.otm.config.MachinesConfig import ru.dbotthepony.mc.otm.container.HandlerFilter import ru.dbotthepony.mc.otm.container.MatteryContainer +import ru.dbotthepony.mc.otm.core.getEntitiesInEllipsoid +import ru.dbotthepony.mc.otm.core.math.Vector import ru.dbotthepony.mc.otm.item.EssenceCapsuleItem +import ru.dbotthepony.mc.otm.item.EssenceServoItem import ru.dbotthepony.mc.otm.menu.tech.EssenceStorageMenu import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MFluids @@ -146,6 +154,37 @@ class EssenceStorageBlockEntity(blockPos: BlockPos, blockState: BlockState) : Ma repairStack.damageValue -= repairPoints } } + + val servo = servoContainer[0] + + if (!servo.isEmpty && servo.item is EssenceServoItem && level is ServerLevel) { + val entities = level!!.getEntitiesInEllipsoid( + blockPos.center, + Vector( + MachinesConfig.EssenceStorage.RADIUS_HORIZONTAL, + MachinesConfig.EssenceStorage.RADIUS_VERTICAL, + MachinesConfig.EssenceStorage.RADIUS_HORIZONTAL + ) + ) { it is ExperienceOrb } + + for ((ent, _) in entities) { + ent as ExperienceOrb + + for (i in 1 .. ent.count) { + experienceStored += ent.value + ent.count-- + + level!!.playSound(null, ent.x, ent.y, ent.z, + SoundEvents.EXPERIENCE_ORB_PICKUP, SoundSource.BLOCKS, + 0.1F, 0.5F + level!!.random.nextFloat() * 0.25F + ) + } + + if (ent.count <= 0) { + ent.discard() + } + } + } } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/config/MachinesConfig.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/config/MachinesConfig.kt index cc3358134..5eff8cfc2 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/config/MachinesConfig.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/config/MachinesConfig.kt @@ -219,7 +219,21 @@ object MachinesConfig : AbstractConfig("machines") { } } + object EssenceStorage { + init { + builder.push(MNames.ESSENCE_STORAGE) + } + + val RADIUS_HORIZONTAL: Double by builder.defineInRange("RADIUS_HORIZONTAL", 5.0, 0.0, Double.MAX_VALUE / 4.0) + val RADIUS_VERTICAL: Double by builder.defineInRange("RADIUS_VERTICAL", 2.0, 0.0, Double.MAX_VALUE / 4.0) + + init { + builder.pop() + } + } + init { Upgrades + EssenceStorage } } diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index b77390770..69270ee06 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -163,6 +163,8 @@ public net.minecraft.world.entity.boss.wither.WitherBoss f_31432_ # TARGETING_CO public-f net.minecraft.world.entity.boss.wither.WitherBoss f_31431_ # LIVING_ENTITY_SELECTOR public net.minecraft.world.entity.ai.targeting.TargetingConditions f_26879_ # selector +public net.minecraft.world.entity.ExperienceOrb f_147072_ # count + public net.minecraft.advancements.critereon.InventoryChangeTrigger$TriggerInstance f_43179_ public net.minecraft.advancements.critereon.InventoryChangeTrigger$TriggerInstance f_43178_ public net.minecraft.advancements.critereon.InventoryChangeTrigger$TriggerInstance f_43177_ From 8a3ef344e3cda95d4a3d66d2391496ae3370a0a6 Mon Sep 17 00:00:00 2001 From: YuRaNnNzZZ Date: Sun, 21 Jan 2024 13:14:42 +0300 Subject: [PATCH 13/16] essence storage empty/filled blockstate --- .../mc/otm/datagen/blocks/BlockModels.kt | 4 +- .../mc/otm/datagen/blocks/BlockStates.kt | 18 ++- .../mc/otm/datagen/items/ItemModels.kt | 14 +- .../entity/tech/EssenceStorageBlockEntity.kt | 19 +++ .../mc/otm/block/tech/EssenceStorageBlock.kt | 14 ++ .../dbotthepony/mc/otm/registry/MRegistry.kt | 14 ++ .../models/block/essence_storage_empty.json | 124 ++++++++++++++++++ ...orage.json => essence_storage_filled.json} | 51 ++----- 8 files changed, 215 insertions(+), 43 deletions(-) create mode 100644 src/main/resources/assets/overdrive_that_matters/models/block/essence_storage_empty.json rename src/main/resources/assets/overdrive_that_matters/models/block/{essence_storage.json => essence_storage_filled.json} (76%) diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/blocks/BlockModels.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/blocks/BlockModels.kt index 884505d6c..a6b3eb704 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/blocks/BlockModels.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/blocks/BlockModels.kt @@ -17,11 +17,13 @@ fun addBlockModels(provider: MatteryBlockModelProvider) { cable("storage_cable", "block/storage_cable") colored(MBlocks.COBBLESTONE_GENERATOR, listOf("0", "particle")) - colored(MBlocks.ESSENCE_STORAGE, listOf("0", "particle")) colored(MBlocks.ITEM_MONITOR, listOf("0", "particle")) colored(MBlocks.MATTER_RECONSTRUCTOR, listOf("0", "particle")) colored(MBlocks.ENERGY_SERVO, listOf("0", "particle")) + colored("essence_storage", "_empty", listOf("0")) + colored("essence_storage", "_filled", listOf("0")) + colored("matter_capacitor_bank", listOf("1", "particle"), "mattercapacitorbank_frame") colored("battery_bank", listOf("0", "particle"), "batterybank_frame") diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/blocks/BlockStates.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/blocks/BlockStates.kt index cd07f3fde..68846f7b9 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/blocks/BlockStates.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/blocks/BlockStates.kt @@ -8,6 +8,7 @@ import ru.dbotthepony.mc.otm.block.decorative.CargoCrateBlock import ru.dbotthepony.mc.otm.block.entity.WorkerState import ru.dbotthepony.mc.otm.block.matter.MatterBottlerBlock import ru.dbotthepony.mc.otm.block.tech.AndroidChargerBlock +import ru.dbotthepony.mc.otm.block.tech.EssenceStorageBlock import ru.dbotthepony.mc.otm.core.math.BlockRotationFreedom import ru.dbotthepony.mc.otm.core.math.xRotationBlockstateNorth import ru.dbotthepony.mc.otm.core.math.xRotationBlockstateSouth @@ -112,7 +113,22 @@ fun addBlockStates(provider: MatteryBlockStateProvider) { provider.block(MBlocks.MATTER_RECONSTRUCTOR.values) provider.block(MBlocks.ENERGY_SERVO.values) provider.block(MBlocks.COBBLESTONE_GENERATOR.values) - provider.block(MBlocks.ESSENCE_STORAGE.values) + + provider.exec { + for (block in MBlocks.ESSENCE_STORAGE.values) { + provider.getVariantBuilder(block).forAllStates { + return@forAllStates arrayOf( + ConfiguredModel.builder() + .modelFile(provider.models().getExistingFile( + modLocation("${block.registryName!!.path}_${if (it.getValue( + EssenceStorageBlock.FILLED)) "filled" else "empty"}") + )) + .rotationY(it.getValue(BlockRotationFreedom.HORIZONTAL.property).front.yRotationBlockstateNorth()) + .buildLast() + ) + } + } + } provider.exec { for (crate in MRegistry.CARGO_CRATES.allBlocks.values) { diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/items/ItemModels.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/items/ItemModels.kt index 2d3244968..daadb672c 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/items/ItemModels.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/items/ItemModels.kt @@ -174,7 +174,6 @@ fun addItemModels(provider: MatteryItemModelProvider) { provider.coloredWithBaseBlock(MItems.DRIVE_VIEWER, "drive_viewer", "_idle") provider.coloredWithBaseBlock(MItems.MATTER_DECOMPOSER, "matter_decomposer", "_idle") provider.coloredWithBaseBlock(MItems.ENERGY_SERVO, "energy_servo") - provider.coloredWithBaseBlock(MItems.ESSENCE_STORAGE, "essence_storage") provider.coloredWithBaseBlock(MItems.MATTER_RECONSTRUCTOR, "matter_reconstructor") provider.coloredWithBaseBlock(MItems.POWERED_BLAST_FURNACE, "powered_blast_furnace", "_idle") @@ -187,10 +186,23 @@ fun addItemModels(provider: MatteryItemModelProvider) { provider.coloredWithBaseBlock(MItems.MATTER_RECYCLER, "matter_recycler", "_idle") provider.coloredWithBaseBlock(MItems.COBBLESTONE_GENERATOR, "cobblestone_generator") + provider.exec { + provider.withExistingParent("essence_storage", modLocation("block/essence_storage_empty")) + .override() + .predicate(modLocation("is_filled"), 1f) + .model(provider.withExistingParent("essence_storage_filled", modLocation("block/essence_storage_filled"))) + .end() + } + for (dye in DyeColor.entries) { provider.exec { provider.withExistingParent("android_charger_${dye.name.lowercase()}", modLocation("item/android_charger")).texture("0", modLocation("block/android_charger/${dye.name.lowercase()}")) provider.withExistingParent("matter_panel_${dye.name.lowercase()}", modLocation("item/matter_panel")).texture("texture", modLocation("block/matter_panel/${dye.name.lowercase()}")) + provider.withExistingParent("essence_storage_${dye.name.lowercase()}", modLocation("block/essence_storage_${dye.name.lowercase()}_empty")) + .override() + .predicate(modLocation("is_filled"), 1f) + .model(provider.withExistingParent("essence_storage_${dye.name.lowercase()}_filled", modLocation("block/essence_storage_${dye.name.lowercase()}_filled"))) + .end() } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EssenceStorageBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EssenceStorageBlockEntity.kt index 09b936abb..80c28c98e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EssenceStorageBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EssenceStorageBlockEntity.kt @@ -10,17 +10,20 @@ import net.minecraft.world.entity.player.Player import net.minecraft.world.inventory.AbstractContainerMenu import net.minecraft.world.item.ItemStack import net.minecraft.world.item.enchantment.Enchantments +import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.state.BlockState import net.minecraftforge.fluids.FluidStack import net.minecraftforge.fluids.capability.IFluidHandler import ru.dbotthepony.mc.otm.block.entity.ExperienceStorage.Companion.XP_TO_LIQUID_RATIO import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity +import ru.dbotthepony.mc.otm.block.tech.EssenceStorageBlock import ru.dbotthepony.mc.otm.capability.item.CombinedItemHandler import ru.dbotthepony.mc.otm.config.MachinesConfig import ru.dbotthepony.mc.otm.container.HandlerFilter import ru.dbotthepony.mc.otm.container.MatteryContainer import ru.dbotthepony.mc.otm.core.getEntitiesInEllipsoid import ru.dbotthepony.mc.otm.core.math.Vector +import ru.dbotthepony.mc.otm.core.util.countingLazy import ru.dbotthepony.mc.otm.item.EssenceCapsuleItem import ru.dbotthepony.mc.otm.item.EssenceServoItem import ru.dbotthepony.mc.otm.menu.tech.EssenceStorageMenu @@ -127,6 +130,14 @@ class EssenceStorageBlockEntity(blockPos: BlockPos, blockState: BlockState) : Ma return FluidStack(MFluids.LIQUID_XP, actualDrain) } + private val hasFillState by countingLazy(blockStateChangesCounter) { + this.blockState.hasProperty(EssenceStorageBlock.FILLED) + } + + private val isFilledState by countingLazy(blockStateChangesCounter) { + hasFillState && this.blockState.getValue(EssenceStorageBlock.FILLED) + } + override fun tick() { super.tick() @@ -186,5 +197,13 @@ class EssenceStorageBlockEntity(blockPos: BlockPos, blockState: BlockState) : Ma } } } + + if (hasFillState) { + val filled = experienceStored > 0 + + if (isFilledState != filled) { + level?.setBlock(blockPos, blockState.setValue(EssenceStorageBlock.FILLED, filled), Block.UPDATE_CLIENTS) + } + } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/EssenceStorageBlock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/EssenceStorageBlock.kt index c87982755..1628451d7 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/EssenceStorageBlock.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/EssenceStorageBlock.kt @@ -9,11 +9,14 @@ import net.minecraft.world.entity.player.Player import net.minecraft.world.item.DyeColor 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.level.block.state.properties.BooleanProperty import net.minecraft.world.level.material.MapColor import net.minecraft.world.level.material.PushReaction import net.minecraft.world.phys.BlockHitResult @@ -44,6 +47,8 @@ class EssenceStorageBlock(val color: DyeColor?) : RotatableMatteryBlock(Properti acceptor(TranslatableComponent("otm.gui.experience_levels", getLevelFromXp(l.asLong)).withStyle(ChatFormatting.GRAY)) } } + + registerDefaultState(getStateDefinition().any().setValue(FILLED, false)) } override fun newBlockEntity(pPos: BlockPos, pState: BlockState): BlockEntity { @@ -67,6 +72,11 @@ class EssenceStorageBlock(val color: DyeColor?) : RotatableMatteryBlock(Properti return super.use(blockState, level, blockPos, ply, hand, blockHitResult) } + override fun createBlockStateDefinition(builder: StateDefinition.Builder) { + super.createBlockStateDefinition(builder) + builder.add(FILLED) + } + private val shapes = getShapeForEachState(rotationProperty) { BlockShapes.ESSENCE_STORAGE.rotateFromNorth(it[rotationProperty]).computeShape() } @Suppress("override_deprecation") @@ -78,4 +88,8 @@ class EssenceStorageBlock(val color: DyeColor?) : RotatableMatteryBlock(Properti ): VoxelShape { return shapes[state]!! } + + companion object { + val FILLED = BooleanProperty.create("filled") + } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRegistry.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRegistry.kt index e53a262a6..417aae832 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRegistry.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRegistry.kt @@ -8,10 +8,12 @@ import net.minecraft.client.renderer.item.ItemProperties import net.minecraft.core.BlockPos import net.minecraft.core.cauldron.CauldronInteraction import net.minecraft.core.registries.Registries +import net.minecraft.nbt.CompoundTag import net.minecraft.resources.ResourceLocation import net.minecraft.world.entity.EntityType import net.minecraft.world.entity.ai.village.poi.PoiType import net.minecraft.world.entity.ai.village.poi.PoiTypes +import net.minecraft.world.item.BlockItem import net.minecraft.world.item.DyeColor import net.minecraft.world.item.DyeableArmorItem import net.minecraft.world.item.Item @@ -389,6 +391,18 @@ object MRegistry : IBlockItemRegistryAcceptor { } } } + + for (item in MItems.ESSENCE_STORAGE.values) { + ItemProperties.register(item, ResourceLocation(OverdriveThatMatters.MOD_ID, "is_filled")) { stack, _, _, _ -> + val tag = (stack.tag?.get(BlockItem.BLOCK_ENTITY_TAG) as? CompoundTag)?: return@register 0f + + if (tag.contains("experienceStored") && tag.getLong("experienceStored") > 0.0) { + 1f + } else { + 0f + } + } + } } } diff --git a/src/main/resources/assets/overdrive_that_matters/models/block/essence_storage_empty.json b/src/main/resources/assets/overdrive_that_matters/models/block/essence_storage_empty.json new file mode 100644 index 000000000..edbee1f08 --- /dev/null +++ b/src/main/resources/assets/overdrive_that_matters/models/block/essence_storage_empty.json @@ -0,0 +1,124 @@ +{ + "parent": "block/block", + "credit": "Made with Blockbench", + "render_type": "cutout", + "texture_size": [32, 64], + "textures": { + "0": "overdrive_that_matters:block/essence_storage", + "particle": "#0" + }, + "elements": [ + { + "name": "body", + "from": [0, 0, 0], + "to": [16, 2, 16], + "faces": { + "north": {"uv": [0, 4, 8, 4.5], "texture": "#0"}, + "east": {"uv": [0, 4, 8, 4.5], "texture": "#0"}, + "south": {"uv": [0, 4, 8, 4.5], "texture": "#0"}, + "west": {"uv": [0, 4, 8, 4.5], "texture": "#0"}, + "up": {"uv": [0, 0, 8, 4], "texture": "#0"}, + "down": {"uv": [0, 0, 8, 4], "texture": "#0"} + } + }, + { + "name": "body", + "from": [0, 3, 0], + "to": [16, 5, 16], + "faces": { + "north": {"uv": [8, 7.25, 16, 7.75], "texture": "#0"}, + "east": {"uv": [8, 7.25, 16, 7.75], "texture": "#0"}, + "south": {"uv": [8, 7.25, 16, 7.75], "texture": "#0"}, + "west": {"uv": [8, 7.25, 16, 7.75], "texture": "#0"}, + "up": {"uv": [0, 7.25, 8, 11.25], "rotation": 180, "texture": "#0"}, + "down": {"uv": [0, 0, 8, 4], "texture": "#0"} + } + }, + { + "name": "body", + "from": [9, 5, 0], + "to": [16, 16, 14], + "faces": { + "north": {"uv": [12, 0, 15.5, 2.75], "texture": "#0"}, + "east": {"uv": [9, 7.75, 16, 10.5], "texture": "#0"}, + "south": {"uv": [11, 4.5, 14.5, 7.25], "texture": "#0"}, + "west": {"uv": [0, 4.5, 7, 7.25], "texture": "#0"}, + "up": {"uv": [0, 7.75, 3.5, 11.25], "rotation": 180, "texture": "#0"} + } + }, + { + "name": "body", + "from": [0, 10, 14], + "to": [16, 16, 16], + "faces": { + "east": {"uv": [8, 7.75, 9, 9.25], "texture": "#0"}, + "south": {"uv": [0, 11.25, 8, 12.75], "texture": "#0"}, + "west": {"uv": [14.5, 4.5, 15.5, 6], "texture": "#0"}, + "up": {"uv": [0, 7.25, 8, 7.75], "rotation": 180, "texture": "#0"}, + "down": {"uv": [0, 7.25, 8, 7.75], "texture": "#0"} + } + }, + { + "name": "body", + "from": [0, 5, 9], + "to": [9, 16, 14], + "faces": { + "north": {"uv": [7, 4.5, 11.5, 7.25], "texture": "#0"}, + "south": {"uv": [5, 4.5, 9.5, 7.25], "texture": "#0"}, + "west": {"uv": [12, 4.5, 14.5, 7.25], "texture": "#0"}, + "up": {"uv": [3.5, 7.75, 8, 9], "rotation": 180, "texture": "#0"} + } + }, + { + "name": "body", + "from": [1, 2, 1], + "to": [15, 3, 15], + "faces": { + "north": {"uv": [0.5, 4.25, 7.5, 4.5], "texture": "#0"}, + "east": {"uv": [0.5, 4.25, 7.5, 4.5], "texture": "#0"}, + "south": {"uv": [0.5, 4.25, 7.5, 4.5], "texture": "#0"}, + "west": {"uv": [0.5, 4.25, 7.5, 4.5], "texture": "#0"} + } + }, + { + "name": "body", + "from": [1, 5, 14], + "to": [15, 10, 15], + "faces": { + "east": {"uv": [15.5, 10.5, 16, 11.75], "texture": "#0"}, + "south": {"uv": [8.5, 10.5, 15.5, 11.75], "texture": "#0"}, + "west": {"uv": [8, 10.5, 8.5, 11.75], "texture": "#0"} + } + }, + { + "name": "bottle", + "from": [1, 13, 1], + "to": [9, 15, 9], + "faces": { + "north": {"uv": [8, 2, 12, 2.5], "texture": "#0"}, + "west": {"uv": [8, 2, 12, 2.5], "texture": "#0"}, + "up": {"uv": [8, 0, 12, 2], "texture": "#0"}, + "down": {"uv": [8, 0, 12, 2], "texture": "#0"} + } + }, + { + "name": "bottle", + "from": [1, 5, 1], + "to": [9, 6, 9], + "faces": { + "north": {"uv": [8, 4.25, 12, 4.5], "texture": "#0"}, + "west": {"uv": [8, 4.25, 12, 4.5], "texture": "#0"}, + "up": {"uv": [8, 0, 12, 2], "texture": "#0"} + } + }, + { + "name": "bottle", + "from": [1, 6, 1], + "to": [9, 13, 9], + "faces": { + "north": {"uv": [8, 2.5, 12, 4.25], "texture": "#0"}, + "west": {"uv": [8, 2.5, 12, 4.25], "texture": "#0"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/overdrive_that_matters/models/block/essence_storage.json b/src/main/resources/assets/overdrive_that_matters/models/block/essence_storage_filled.json similarity index 76% rename from src/main/resources/assets/overdrive_that_matters/models/block/essence_storage.json rename to src/main/resources/assets/overdrive_that_matters/models/block/essence_storage_filled.json index b8cd1d055..f9420d560 100644 --- a/src/main/resources/assets/overdrive_that_matters/models/block/essence_storage.json +++ b/src/main/resources/assets/overdrive_that_matters/models/block/essence_storage_filled.json @@ -1,10 +1,12 @@ { + "parent": "block/block", "credit": "Made with Blockbench", "render_type": "cutout", "texture_size": [32, 64], "textures": { "0": "overdrive_that_matters:block/essence_storage", - "particle": "overdrive_that_matters:block/essence_storage" + "1": "overdrive_that_matters:block/liquid_xp_still", + "particle": "#0" }, "elements": [ { @@ -92,15 +94,15 @@ { "name": "experience", "from": [1.5, 5, 1.5], - "to": [8.5, 11, 8.5], + "to": [8.5, 13, 8.5], "faces": { - "north": {"uv": [8, 14.5, 11.5, 16], "texture": "#0"}, - "east": {"uv": [12.5, 12, 16, 13.5], "texture": "#0"}, - "south": {"uv": [9, 12, 12.5, 13.5], "texture": "#0"}, - "west": {"uv": [11.5, 14.5, 15, 16], "texture": "#0"}, - "up": {"uv": [9.5, 12.5, 13, 14.25], "texture": "#0"} + "north": {"uv": [7.5, 3, 14.5, 11], "texture": "#1"}, + "west": {"uv": [1.5, 3, 8.5, 11], "texture": "#1"} }, - "forge_data": { "block_light": 15, "sky_light": 15 } + "forge_data": { + "block_light": 15, + "sky_light": 15 + } }, { "name": "bottle", @@ -132,36 +134,5 @@ "west": {"uv": [8, 2.5, 12, 4.25], "texture": "#0"} } } - ], - "display": { - "thirdperson_righthand": { - "rotation": [75, 45, 0], - "translation": [0, 2.5, 0], - "scale": [0.375, 0.375, 0.375] - }, - "thirdperson_lefthand": { - "rotation": [75, 45, 0], - "translation": [0, 2.5, 0], - "scale": [0.375, 0.375, 0.375] - }, - "firstperson_righthand": { - "rotation": [0, 45, 0], - "scale": [0.4, 0.4, 0.4] - }, - "firstperson_lefthand": { - "rotation": [0, 225, 0], - "scale": [0.4, 0.4, 0.4] - }, - "ground": { - "translation": [0, 3, 0], - "scale": [0.25, 0.25, 0.25] - }, - "gui": { - "rotation": [30, 225, 0], - "scale": [0.625, 0.625, 0.625] - }, - "fixed": { - "scale": [0.5, 0.5, 0.5] - } - } + ] } \ No newline at end of file From 9ad1c8e82a379c483aaf154a7d32be0318e97640 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Sun, 21 Jan 2024 23:32:40 +0700 Subject: [PATCH 14/16] Micro optimize combinedcontainer stack iterator for best case scenario --- .../ru/dbotthepony/mc/otm/container/CombinedContainer.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/CombinedContainer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/CombinedContainer.kt index 36e2aa9d8..992139a7a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/CombinedContainer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/CombinedContainer.kt @@ -16,6 +16,7 @@ import net.minecraft.world.item.ItemStack import ru.dbotthepony.mc.otm.container.util.IContainerSlot import ru.dbotthepony.mc.otm.container.util.containerSlot import ru.dbotthepony.mc.otm.container.util.iterator +import ru.dbotthepony.mc.otm.container.util.slotIterator import ru.dbotthepony.mc.otm.core.collect.concatIterators import ru.dbotthepony.mc.otm.core.collect.filter import ru.dbotthepony.mc.otm.core.collect.flatMap @@ -154,6 +155,9 @@ class CombinedContainer(containers: Stream>>) : IM } override fun iterator(nonEmpty: Boolean): Iterator { + if (notFullCoverage.isEmpty()) + return fullCoverage.iterator().flatMap { it.iterator(nonEmpty) } + return concatIterators( fullCoverage.iterator().flatMap { it.iterator(nonEmpty) }, notFullCoverage.values.iterator().flatMap { it.iterator() }.map { it.item }.let { if (nonEmpty) it.filter { it.isNotEmpty } else it } From d18399795bd9869e9bfeff9b0f51355988ee8b8b Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Sun, 21 Jan 2024 23:33:03 +0700 Subject: [PATCH 15/16] Void/Unit subscripable --- .../dbotthepony/mc/otm/core/ISubscripable.kt | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/ISubscripable.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/ISubscripable.kt index 5bbd7b52e..75f487e45 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/ISubscripable.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/ISubscripable.kt @@ -66,6 +66,44 @@ interface ISubscriptable { } } +interface IUnitSubscripable : ISubscriptable { + fun addListener(listener: Runnable): ISubscriptable.L + + override fun addListener(listener: Consumer): ISubscriptable.L { + return addListener(Runnable { listener.accept(Unit) }) + } + + class Impl : IUnitSubscripable, Runnable { + private inner class L(val callback: Runnable) : ISubscriptable.L { + private var isRemoved = false + + init { + subscribers.add(this) + } + + override fun remove() { + if (!isRemoved) { + isRemoved = true + queue.add(this) + } + } + } + + private val subscribers = ReferenceLinkedOpenHashSet(0) + private val queue = ReferenceArraySet(0) + + override fun addListener(listener: Runnable): ISubscriptable.L { + return L(listener) + } + + override fun run() { + queue.forEach { subscribers.remove(it) } + queue.clear() + subscribers.forEach { it.callback.run() } + } + } +} + interface IFloatSubcripable : ISubscriptable { @Deprecated("Use type specific listener") override fun addListener(listener: Consumer): ISubscriptable.L { From 87e64a102a1c37b0676be8faed32f7ef77ef6273 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Mon, 22 Jan 2024 11:45:56 +0700 Subject: [PATCH 16/16] what --- .../models/item/matter_cable.json | 50 ------------------- 1 file changed, 50 deletions(-) delete mode 100644 src/main/resources/assets/overdrive_that_matters/models/item/matter_cable.json diff --git a/src/main/resources/assets/overdrive_that_matters/models/item/matter_cable.json b/src/main/resources/assets/overdrive_that_matters/models/item/matter_cable.json deleted file mode 100644 index 530e26553..000000000 --- a/src/main/resources/assets/overdrive_that_matters/models/item/matter_cable.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "parent": "block/block", - "texture_size": [16, 16], - "textures": { - "0": "overdrive_that_matters:block/matter_cable", - "particle": "#0" - }, - "elements": [ - { - "from": [6, 6, 6], - "to": [10, 10, 10], - "faces": { - "north": {"uv": [0, 0, 4, 4], "texture": "#0"}, - "south": {"uv": [0, 0, 4, 4], "texture": "#0"}, - "up": {"uv": [0, 0, 4, 4], "texture": "#0"}, - "down": {"uv": [0, 0, 4, 4], "texture": "#0"} - } - }, - { - "from": [0, 6, 6], - "to": [6, 10, 10], - "faces": { - "north": {"uv": [4, 0, 10, 4], "texture": "#0"}, - "south": {"uv": [10, 0, 4, 4], "texture": "#0"}, - "west": {"uv": [0, 0, 4, 4], "texture": "#0"}, - "up": {"uv": [10, 0, 4, 4], "texture": "#0"}, - "down": {"uv": [10, 0, 4, 4], "texture": "#0"} - } - }, - { - "from": [10, 6, 6], - "to": [16, 10, 10], - "faces": { - "north": {"uv": [10, 0, 16, 4], "texture": "#0"}, - "east": {"uv": [0, 0, 4, 4], "texture": "#0"}, - "south": {"uv": [16, 0, 10, 4], "texture": "#0"}, - "up": {"uv": [16, 0, 10, 4], "texture": "#0"}, - "down": {"uv": [16, 0, 10, 4], "texture": "#0"} - } - } - ], - "gui_light": "front", - "display": { - "gui": { - "rotation": [0, 0, 0], - "translation": [0, 0, 0], - "scale": [1, 1, 1] - } - } -} \ No newline at end of file