Energy cable tiers, fix some Client -> Server logic leaks in singleplayer
This commit is contained in:
parent
023081eaaa
commit
1c0cdb8b5b
@ -50,6 +50,7 @@ fun addLootTables(lootTables: LootTables) {
|
||||
lootTables.dropsSelf(MBlocks.METAL_BEAM) { condition(ExplosionCondition.survivesExplosion()) }
|
||||
lootTables.dropsSelf(MBlocks.TRITANIUM_INGOT_BLOCK) { condition(ExplosionCondition.survivesExplosion()) }
|
||||
lootTables.dropsSelf(MBlocks.TRITANIUM_BARS) { condition(ExplosionCondition.survivesExplosion()) }
|
||||
lootTables.dropsSelf(MBlocks.ENERGY_CABLES.values) { condition(ExplosionCondition.survivesExplosion()) }
|
||||
|
||||
lootTables.dropsSelf(MBlocks.INFINITE_WATER_SOURCE) { condition(ExplosionCondition.survivesExplosion()) }
|
||||
|
||||
|
@ -176,6 +176,7 @@ fun addTags(tagsProvider: TagsProvider) {
|
||||
tagsProvider.requiresPickaxe(MBlocks.TRITANIUM_DOOR.values, Tiers.IRON)
|
||||
tagsProvider.requiresPickaxe(MBlocks.TRITANIUM_TRAPDOOR.values, Tiers.IRON)
|
||||
tagsProvider.requiresPickaxe(MBlocks.PAINTER, Tiers.STONE)
|
||||
tagsProvider.requiresPickaxe(MBlocks.ENERGY_CABLES.values, Tiers.STONE)
|
||||
|
||||
tagsProvider.requiresPickaxe(listOf(
|
||||
MBlocks.ANDROID_STATION,
|
||||
|
@ -39,6 +39,7 @@ import ru.dbotthepony.mc.otm.client.render.blockentity.MatterBatteryBankRenderer
|
||||
import ru.dbotthepony.mc.otm.compat.adastra.AdAstraCompatKt;
|
||||
import ru.dbotthepony.mc.otm.compat.curios.CuriosCompatKt;
|
||||
import ru.dbotthepony.mc.otm.config.AndroidConfig;
|
||||
import ru.dbotthepony.mc.otm.config.CablesConfig;
|
||||
import ru.dbotthepony.mc.otm.config.ClientConfig;
|
||||
import ru.dbotthepony.mc.otm.config.ExopackConfig;
|
||||
import ru.dbotthepony.mc.otm.config.ItemsConfig;
|
||||
@ -142,6 +143,7 @@ public final class OverdriveThatMatters {
|
||||
|
||||
ClientConfig.INSTANCE.register();
|
||||
ServerConfig.INSTANCE.register();
|
||||
CablesConfig.INSTANCE.register();
|
||||
ServerCompatConfig.INSTANCE.register();
|
||||
AndroidConfig.INSTANCE.register();
|
||||
ExopackConfig.INSTANCE.register();
|
||||
|
@ -40,6 +40,9 @@ private val serverCounter = AtomicInteger()
|
||||
private var _server: MinecraftServer? = null
|
||||
val isClient: Boolean by lazy { FMLLoader.getDist() == Dist.CLIENT }
|
||||
|
||||
val UNIVERSE_TICKS get() = postServerTick.ticks
|
||||
val Level.ticksPassed get() = postWorldTick.computeIfAbsent(this) { TickList() }.ticks
|
||||
|
||||
fun <V> lazyPerServer(fn: (MinecraftServer) -> V): Lazy<V> {
|
||||
return AtomicallyInvalidatedLazy(serverCounter) {
|
||||
if (!SERVER_IS_LIVE)
|
||||
|
@ -129,8 +129,8 @@ class StorageCableBlock : CableBlock(Properties.of().mapColor(MapColor.METAL).re
|
||||
}
|
||||
}
|
||||
|
||||
class EnergyCableBlock : CableBlock(Properties.of().mapColor(MapColor.METAL).requiresCorrectToolForDrops().sound(SoundType.METAL).strength(1.0f, 6.0f)), EntityBlock {
|
||||
private val shapes = generateShapes(0.125)
|
||||
class EnergyCableBlock(val factory: (blockPos: BlockPos, blockState: BlockState) -> BlockEntity) : CableBlock(Properties.of().mapColor(MapColor.METAL).requiresCorrectToolForDrops().sound(SoundType.METAL).strength(1.0f, 6.0f)), EntityBlock {
|
||||
private val shapes = generateShapes(0.185)
|
||||
|
||||
@Suppress("OVERRIDE_DEPRECATION")
|
||||
override fun getShape(blockState: BlockState, accessor: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape {
|
||||
@ -138,6 +138,6 @@ class EnergyCableBlock : CableBlock(Properties.of().mapColor(MapColor.METAL).req
|
||||
}
|
||||
|
||||
override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity {
|
||||
return EnergyCableBlockEntity(blockPos, blockState)
|
||||
return factory(blockPos, blockState)
|
||||
}
|
||||
}
|
||||
|
@ -62,6 +62,7 @@ import java.util.function.Consumer
|
||||
import java.util.function.Predicate
|
||||
import java.util.function.Supplier
|
||||
import java.util.stream.Stream
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.properties.ReadWriteProperty
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
@ -109,6 +110,7 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
|
||||
protected val tickList = TickList()
|
||||
protected val blockStateChangesCounter = IntCounter()
|
||||
protected val dirtyListeners = ISubscriptable.Impl<Unit>()
|
||||
private val waitForServerLevel = ArrayList<() -> Unit>()
|
||||
|
||||
/**
|
||||
* Shared savetables, written both to level storage and to item tag
|
||||
@ -166,6 +168,14 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
|
||||
}
|
||||
}
|
||||
|
||||
protected fun waitForServerLevel(lambda: () -> Unit) {
|
||||
if (level is ServerLevel) {
|
||||
lambda.invoke()
|
||||
} else if (level == null) {
|
||||
waitForServerLevel.add(lambda)
|
||||
}
|
||||
}
|
||||
|
||||
interface SideListener<T> : Supplier<LazyOptional<T>>, ISubscriptable<LazyOptional<T>>
|
||||
|
||||
inner class Side(val side: RelativeSide) {
|
||||
@ -191,7 +201,7 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
|
||||
|
||||
override fun addListener(listener: Consumer<LazyOptional<T>>): ISubscriptable.L {
|
||||
val l = listeners.addListener(listener)
|
||||
listener.accept(value)
|
||||
if (level is ServerLevel) listener.accept(value)
|
||||
return l
|
||||
}
|
||||
|
||||
@ -521,6 +531,10 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
waitForServerLevel.forEach { it.invoke() }
|
||||
} else {
|
||||
waitForServerLevel.clear()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -179,7 +179,7 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
||||
}
|
||||
|
||||
init {
|
||||
tickList.once {
|
||||
waitForServerLevel {
|
||||
redstoneControl.addListener {
|
||||
updateTickerState()
|
||||
}
|
||||
@ -388,7 +388,7 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
||||
updateTickerState()
|
||||
}
|
||||
|
||||
tickList.once {
|
||||
waitForServerLevel {
|
||||
redstoneControl.addListener {
|
||||
updateTickerState()
|
||||
}
|
||||
@ -670,7 +670,7 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
||||
savetables.bool(::automatePush, "itemhandler_${side}_automatePush")
|
||||
savetables.enum(::mode, "itemhandler_${side}_mode", ItemHandlerMode::valueOf)
|
||||
|
||||
tickList.once {
|
||||
waitForServerLevel {
|
||||
redstoneControl.addListener {
|
||||
updateTickerState()
|
||||
}
|
||||
|
@ -2,8 +2,10 @@ package ru.dbotthepony.mc.otm.block.entity.cable
|
||||
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.block.Block
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||
import ru.dbotthepony.mc.otm.SERVER_IS_LIVE
|
||||
@ -12,13 +14,12 @@ import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
|
||||
import ru.dbotthepony.mc.otm.capability.FlowDirection
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||
import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage
|
||||
import ru.dbotthepony.mc.otm.core.ifPresentK
|
||||
import ru.dbotthepony.mc.otm.config.CablesConfig
|
||||
import ru.dbotthepony.mc.otm.core.math.BlockRotation
|
||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||
import ru.dbotthepony.mc.otm.core.math.RelativeSide
|
||||
import ru.dbotthepony.mc.otm.graph.GraphNode
|
||||
import ru.dbotthepony.mc.otm.onceServer
|
||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||
import java.util.Collections
|
||||
import java.util.EnumMap
|
||||
|
||||
@ -27,7 +28,7 @@ import java.util.EnumMap
|
||||
|
||||
// this allows simpler implementation and faster code, while also reducing possibility of duplication exploits
|
||||
|
||||
class EnergyCableBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryBlockEntity(MBlockEntities.ENERGY_CABLE, blockPos, blockState) {
|
||||
abstract class EnergyCableBlockEntity(type: BlockEntityType<*>, blockPos: BlockPos, blockState: BlockState) : MatteryBlockEntity(type, blockPos, blockState) {
|
||||
inner class CableSide(val side: RelativeSide) : IMatteryEnergyStorage {
|
||||
var isEnabled = true
|
||||
set(value) {
|
||||
@ -47,19 +48,17 @@ class EnergyCableBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte
|
||||
val neighbour = sides[side]!!.trackEnergy()
|
||||
|
||||
init {
|
||||
waitForServerLevel {
|
||||
neighbour.addListener {
|
||||
if (isEnabled) {
|
||||
if (it.isPresent) {
|
||||
if (it.resolve().get() !is CableSide) {
|
||||
node.graph.livelyNodes.add(node)
|
||||
}
|
||||
}
|
||||
|
||||
onceServer {
|
||||
updateBlockState(blockRotation.side2Dir(side), true)
|
||||
}
|
||||
} else {
|
||||
onceServer {
|
||||
updateBlockState(blockRotation.side2Dir(side), false)
|
||||
updateBlockState(blockRotation.side2Dir(side), it.isPresent || node.neighboursView[GraphNode.link(blockRotation.side2Dir(side))] != null)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -71,7 +70,7 @@ class EnergyCableBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte
|
||||
}
|
||||
|
||||
override fun receiveEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
|
||||
return node.graph.receiveEnergy(howMuch, simulate)
|
||||
return node.graph.receiveEnergy(howMuch, simulate, node, side)
|
||||
}
|
||||
|
||||
override var batteryLevel: Decimal
|
||||
@ -103,6 +102,11 @@ class EnergyCableBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte
|
||||
updateBlockState(link.direction, false)
|
||||
}
|
||||
}
|
||||
|
||||
val blockEntity get() = this@EnergyCableBlockEntity
|
||||
val canTraverse get() = energyThroughput > Decimal.ZERO
|
||||
val energyThroughput get() = this@EnergyCableBlockEntity.energyThroughput
|
||||
val position: BlockPos get() = this@EnergyCableBlockEntity.blockPos
|
||||
}
|
||||
|
||||
private fun updateBlockState(side: Direction, status: Boolean) {
|
||||
@ -112,7 +116,10 @@ class EnergyCableBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte
|
||||
level?.setBlock(blockPos, newState, Block.UPDATE_CLIENTS)
|
||||
}
|
||||
|
||||
override val blockRotation: BlockRotation
|
||||
// whenever this changes, graph#invalidatePathCache() MUST be called
|
||||
abstract val energyThroughput: Decimal
|
||||
|
||||
final override val blockRotation: BlockRotation
|
||||
get() = BlockRotation.NORTH
|
||||
|
||||
private val energySidesInternal = EnumMap<RelativeSide, CableSide>(RelativeSide::class.java)
|
||||
@ -134,3 +141,8 @@ class EnergyCableBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte
|
||||
exposeGlobally(MatteryCapability.ENERGY_CABLE_NODE, node)
|
||||
}
|
||||
}
|
||||
|
||||
class SimpleEnergyCableBlockEntity(type: BlockEntityType<*>, blockPos: BlockPos, blockState: BlockState, val config: CablesConfig.E) : EnergyCableBlockEntity(type, blockPos, blockState) {
|
||||
override val energyThroughput: Decimal
|
||||
get() = config.throughput
|
||||
}
|
||||
|
@ -1,23 +1,92 @@
|
||||
package ru.dbotthepony.mc.otm.block.entity.cable
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap
|
||||
import it.unimi.dsi.fastutil.objects.ObjectAVLTreeSet
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet
|
||||
import ru.dbotthepony.mc.otm.capability.receiveEnergy
|
||||
import ru.dbotthepony.mc.otm.core.ifPresentK
|
||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||
import ru.dbotthepony.mc.otm.core.math.RelativeSide
|
||||
import ru.dbotthepony.mc.otm.graph.GraphNodeList
|
||||
import kotlin.math.ln
|
||||
|
||||
class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableGraph>() {
|
||||
val livelyNodes = ObjectOpenHashSet<EnergyCableBlockEntity.Node>()
|
||||
|
||||
private val pathCache = Object2ObjectOpenHashMap<Pair<EnergyCableBlockEntity.Node, EnergyCableBlockEntity.Node>, Decimal?>()
|
||||
|
||||
private class SearchNode(val node: EnergyCableBlockEntity.Node, target: EnergyCableBlockEntity.Node, var parent: SearchNode? = null) : Comparable<SearchNode> {
|
||||
var heuristics: Double = node.position.distSqr(target.position) * 0.0001 - ln(node.energyThroughput.coerceAtMost(Decimal.LONG_MAX_VALUE).toDouble())
|
||||
|
||||
override fun compareTo(other: SearchNode): Int {
|
||||
return heuristics.compareTo(other.heuristics)
|
||||
}
|
||||
}
|
||||
|
||||
fun invalidatePathCache() {
|
||||
pathCache.clear()
|
||||
}
|
||||
|
||||
private fun getPath(a: EnergyCableBlockEntity.Node, b: EnergyCableBlockEntity.Node): Decimal? {
|
||||
if (!a.canTraverse || !b.canTraverse)
|
||||
return null
|
||||
|
||||
val key = a to b
|
||||
|
||||
if (key in pathCache)
|
||||
return pathCache[key]
|
||||
|
||||
// no free paths available, try to find extra one
|
||||
// while this use A* algorithm, this is done purely for biasing search towards end point (to speed up search),
|
||||
// on small cable networks simple flooding will do just fine, if we consider overloaded cables as closed flood gates
|
||||
val openNodes = ArrayList<SearchNode>()
|
||||
val seenNodes = ObjectOpenHashSet<EnergyCableBlockEntity.Node>()
|
||||
|
||||
openNodes.add(SearchNode(a, b))
|
||||
|
||||
while (openNodes.isNotEmpty()) {
|
||||
val first = openNodes.min()
|
||||
openNodes.remove(first)
|
||||
|
||||
if (first.node === b) {
|
||||
// solution found
|
||||
val solution = ArrayList<EnergyCableBlockEntity.Node>()
|
||||
|
||||
var last = first.parent
|
||||
solution.add(first.node)
|
||||
|
||||
while (last != null) {
|
||||
solution.add(last.node)
|
||||
last = last.parent
|
||||
}
|
||||
|
||||
val calc = solution.minOf { it.energyThroughput }
|
||||
pathCache[key] = calc
|
||||
return calc
|
||||
} else {
|
||||
for (neighbour in first.node.neighboursView.values) {
|
||||
if (!seenNodes.add(neighbour) || !neighbour.canTraverse) continue
|
||||
openNodes.add(SearchNode(neighbour, b, first))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// solution does not exist
|
||||
pathCache[key] = null
|
||||
return null
|
||||
}
|
||||
|
||||
override fun onNodeRemoved(node: EnergyCableBlockEntity.Node) {
|
||||
livelyNodes.remove(node)
|
||||
invalidatePathCache()
|
||||
}
|
||||
|
||||
override fun onNodeAdded(node: EnergyCableBlockEntity.Node) {
|
||||
livelyNodes.add(node)
|
||||
invalidatePathCache()
|
||||
}
|
||||
|
||||
fun receiveEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
|
||||
fun receiveEnergy(howMuch: Decimal, simulate: Boolean, fromNode: EnergyCableBlockEntity.Node, fromSide: RelativeSide): Decimal {
|
||||
val itr = livelyNodes.iterator()
|
||||
var received = Decimal.ZERO
|
||||
var residue = howMuch
|
||||
@ -27,19 +96,24 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
|
||||
|
||||
for (side in node.sides.values) {
|
||||
if (side.isEnabled) {
|
||||
if (fromNode === node && side.side === fromSide)
|
||||
continue
|
||||
|
||||
side.neighbour.get().ifPresentK {
|
||||
if (it !is EnergyCableBlockEntity.CableSide) {
|
||||
val limit = getPath(fromNode, node)
|
||||
hit = true
|
||||
|
||||
val thisReceived = it.receiveEnergy(residue, simulate)
|
||||
if (limit != null) {
|
||||
val thisReceived = it.receiveEnergy(residue.coerceAtMost(limit), simulate)
|
||||
received += thisReceived
|
||||
residue -= thisReceived
|
||||
|
||||
if (!residue.isPositive) return received
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hit) {
|
||||
itr.remove()
|
||||
|
28
src/main/kotlin/ru/dbotthepony/mc/otm/config/CablesConfig.kt
Normal file
28
src/main/kotlin/ru/dbotthepony/mc/otm/config/CablesConfig.kt
Normal file
@ -0,0 +1,28 @@
|
||||
package ru.dbotthepony.mc.otm.config
|
||||
|
||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||
import ru.dbotthepony.mc.otm.core.math.defineDecimal
|
||||
|
||||
object CablesConfig : AbstractConfig("cables") {
|
||||
enum class E(throughput: Decimal) {
|
||||
CRUDE(Decimal(160)),
|
||||
REGULAR(Decimal(1024)),
|
||||
ADVANCED(Decimal(8192)),
|
||||
SUPERCONDUCTOR(Decimal.POSITIVE_INFINITY);
|
||||
|
||||
init {
|
||||
builder.push(name)
|
||||
}
|
||||
|
||||
var throughput by builder
|
||||
.defineDecimal("THROUGHPUT", throughput, Decimal.ZERO)
|
||||
|
||||
init {
|
||||
builder.pop()
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
E.SUPERCONDUCTOR
|
||||
}
|
||||
}
|
@ -262,14 +262,14 @@ sealed class Decimal : Number(), Comparable<Decimal> {
|
||||
}
|
||||
|
||||
override fun compareTo(other: Decimal): Int {
|
||||
return if (other is Regular)
|
||||
return if (other === Zero)
|
||||
signum()
|
||||
else if (other is Regular)
|
||||
mag.compareTo(other.mag)
|
||||
else if (other === PositiveInfinity)
|
||||
-1
|
||||
else if (other === NegativeInfinity)
|
||||
1
|
||||
else if (other === Zero)
|
||||
signum()
|
||||
else
|
||||
throw RuntimeException("unreachable code")
|
||||
}
|
||||
|
@ -13,6 +13,8 @@ import ru.dbotthepony.mc.otm.core.math.plus
|
||||
import ru.dbotthepony.mc.otm.core.orNull
|
||||
import ru.dbotthepony.mc.otm.core.util.IConditionalTickable
|
||||
import ru.dbotthepony.mc.otm.core.util.ITickable
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
open class GraphNode<N : GraphNode<N, G>, G : GraphNodeList<N, G>>(val graphFactory: () -> G) {
|
||||
interface Link {
|
||||
@ -30,6 +32,7 @@ open class GraphNode<N : GraphNode<N, G>, G : GraphNodeList<N, G>>(val graphFact
|
||||
}
|
||||
|
||||
private val neighbours = Object2ObjectOpenHashMap<Link, N>()
|
||||
val neighboursView: Map<Link, N> = Collections.unmodifiableMap(neighbours)
|
||||
|
||||
var graph: G = graphFactory.invoke()
|
||||
internal set
|
||||
|
@ -15,7 +15,7 @@ import ru.dbotthepony.mc.otm.block.entity.tech.*
|
||||
import ru.dbotthepony.mc.otm.block.entity.blackhole.BlackHoleBlockEntity
|
||||
import ru.dbotthepony.mc.otm.block.entity.blackhole.BlockEntityExplosionDebugger
|
||||
import ru.dbotthepony.mc.otm.block.entity.blackhole.BlockEntitySphereDebugger
|
||||
import ru.dbotthepony.mc.otm.block.entity.cable.EnergyCableBlockEntity
|
||||
import ru.dbotthepony.mc.otm.block.entity.cable.SimpleEnergyCableBlockEntity
|
||||
import ru.dbotthepony.mc.otm.block.entity.decorative.CargoCrateBlockEntity
|
||||
import ru.dbotthepony.mc.otm.block.entity.decorative.DevChestBlockEntity
|
||||
import ru.dbotthepony.mc.otm.block.entity.decorative.FluidTankBlockEntity
|
||||
@ -30,6 +30,9 @@ import ru.dbotthepony.mc.otm.block.entity.tech.EnergyServoBlockEntity
|
||||
import ru.dbotthepony.mc.otm.block.entity.tech.GravitationStabilizerBlockEntity
|
||||
import ru.dbotthepony.mc.otm.block.entity.tech.PlatePressBlockEntity
|
||||
import ru.dbotthepony.mc.otm.client.render.blockentity.*
|
||||
import ru.dbotthepony.mc.otm.config.CablesConfig
|
||||
import ru.dbotthepony.mc.otm.core.collect.SupplierMap
|
||||
import ru.dbotthepony.mc.otm.core.getValue
|
||||
import java.util.function.Supplier
|
||||
|
||||
@Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS") // Type<*> is unused in BlockEntityType.Builder
|
||||
@ -74,7 +77,12 @@ object MBlockEntities {
|
||||
val DEV_CHEST by register(MNames.DEV_CHEST, ::DevChestBlockEntity, MBlocks::DEV_CHEST)
|
||||
val PAINTER by register(MNames.PAINTER, ::PainterBlockEntity, MBlocks::PAINTER)
|
||||
val MATTER_ENTANGLER by register(MNames.MATTER_ENTANGLER, ::MatterEntanglerBlockEntity, MBlocks::MATTER_ENTANGLER)
|
||||
val ENERGY_CABLE by register(MNames.ENERGY_CABLE, ::EnergyCableBlockEntity, MBlocks::ENERGY_CABLE)
|
||||
|
||||
val ENERGY_CABLES: Map<CablesConfig.E, BlockEntityType<*>> = SupplierMap(CablesConfig.E.entries.map { conf ->
|
||||
var selfFeed: Supplier<BlockEntityType<*>> = Supplier { TODO() }
|
||||
selfFeed = register("${conf.name.lowercase()}_energy_cable", { a, b -> SimpleEnergyCableBlockEntity(selfFeed.get(), a, b, conf) }) as Supplier<BlockEntityType<*>>
|
||||
conf to selfFeed::get
|
||||
})
|
||||
|
||||
val POWERED_FURNACE: BlockEntityType<PoweredFurnaceBlockEntity> by registry.register(MNames.POWERED_FURNACE) { BlockEntityType.Builder.of({ a, b -> MBlocks.POWERED_FURNACE.newBlockEntity(a, b) }, MBlocks.POWERED_FURNACE).build(null) }
|
||||
val POWERED_BLAST_FURNACE: BlockEntityType<PoweredFurnaceBlockEntity> by registry.register(MNames.POWERED_BLAST_FURNACE) { BlockEntityType.Builder.of({ a, b -> MBlocks.POWERED_BLAST_FURNACE.newBlockEntity(a, b) }, MBlocks.POWERED_BLAST_FURNACE).build(null) }
|
||||
|
@ -77,9 +77,11 @@ import ru.dbotthepony.mc.otm.block.tech.EssenceStorageBlock
|
||||
import ru.dbotthepony.mc.otm.block.tech.PhantomAttractorBlock
|
||||
import ru.dbotthepony.mc.otm.block.tech.PlatePressBlock
|
||||
import ru.dbotthepony.mc.otm.block.tech.PoweredFurnaceBlock
|
||||
import ru.dbotthepony.mc.otm.config.CablesConfig
|
||||
import ru.dbotthepony.mc.otm.config.MachinesConfig
|
||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||
import ru.dbotthepony.mc.otm.core.collect.SupplierList
|
||||
import ru.dbotthepony.mc.otm.core.collect.SupplierMap
|
||||
import ru.dbotthepony.mc.otm.shapes.BlockShapes
|
||||
|
||||
object MBlocks {
|
||||
@ -115,7 +117,10 @@ object MBlocks {
|
||||
val MATTER_RECONSTRUCTOR: MatterReconstructorBlock by registry.register(MNames.MATTER_RECONSTRUCTOR) { MatterReconstructorBlock() }
|
||||
val PAINTER: PainterBlock by registry.register(MNames.PAINTER) { PainterBlock() }
|
||||
val MATTER_ENTANGLER: MatterEntanglerBlock by registry.register(MNames.MATTER_ENTANGLER) { MatterEntanglerBlock() }
|
||||
val ENERGY_CABLE: EnergyCableBlock by registry.register(MNames.ENERGY_CABLE) { EnergyCableBlock() }
|
||||
|
||||
val ENERGY_CABLES: Map<CablesConfig.E, EnergyCableBlock> = SupplierMap(CablesConfig.E.entries.map { conf ->
|
||||
conf to registry.register("${conf.name.lowercase()}_energy_cable") { EnergyCableBlock { a, b -> MBlockEntities.ENERGY_CABLES[conf]!!.create(a, b)!! } }::get
|
||||
})
|
||||
|
||||
val STORAGE_BUS: Block by registry.register(MNames.STORAGE_BUS) { StorageBusBlock() }
|
||||
val STORAGE_IMPORTER: Block by registry.register(MNames.STORAGE_IMPORTER) { StorageImporterBlock() }
|
||||
|
@ -129,7 +129,7 @@ private fun CreativeModeTab.Output.fluids(value: Item) {
|
||||
|
||||
private fun addMainCreativeTabItems(consumer: CreativeModeTab.Output) {
|
||||
with(consumer) {
|
||||
accept(MItems.ENERGY_CABLE)
|
||||
accept(MItems.ENERGY_CABLES.values)
|
||||
accept(MItems.MACHINES)
|
||||
accept(MItems.MachineUpgrades.Basic.LIST)
|
||||
accept(MItems.MachineUpgrades.Normal.LIST)
|
||||
|
@ -17,9 +17,11 @@ import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||
import ru.dbotthepony.mc.otm.capability.ITieredUpgradeSet
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
|
||||
import ru.dbotthepony.mc.otm.capability.UpgradeType
|
||||
import ru.dbotthepony.mc.otm.config.CablesConfig
|
||||
import ru.dbotthepony.mc.otm.config.ItemsConfig
|
||||
import ru.dbotthepony.mc.otm.core.collect.SupplierList
|
||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||
import ru.dbotthepony.mc.otm.core.collect.SupplierMap
|
||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||
import ru.dbotthepony.mc.otm.item.*
|
||||
import ru.dbotthepony.mc.otm.item.exopack.ExopackProbeItem
|
||||
@ -46,7 +48,9 @@ object MItems {
|
||||
registry.register(bus)
|
||||
}
|
||||
|
||||
val ENERGY_CABLE: BlockItem by registry.register(MNames.ENERGY_CABLE) { BlockItem(MBlocks.ENERGY_CABLE, DEFAULT_PROPERTIES) }
|
||||
val ENERGY_CABLES: Map<CablesConfig.E, BlockItem> = SupplierMap(CablesConfig.E.entries.map { conf ->
|
||||
conf to registry.register("${conf.name.lowercase()}_energy_cable") { BlockItem(MBlocks.ENERGY_CABLES[conf]!!, DEFAULT_PROPERTIES) }::get
|
||||
})
|
||||
|
||||
val ANDROID_STATION: BlockItem by registry.register(MNames.ANDROID_STATION) { BlockItem(MBlocks.ANDROID_STATION, DEFAULT_PROPERTIES) }
|
||||
val ANDROID_CHARGER: BlockItem by registry.register(MNames.ANDROID_CHARGER) { BlockItem(MBlocks.ANDROID_CHARGER, DEFAULT_PROPERTIES) }
|
||||
|
@ -17,7 +17,6 @@ object MNames {
|
||||
const val DEV_CHEST = "dev_chest"
|
||||
const val PAINTER = "painter"
|
||||
const val MATTER_ENTANGLER = "matter_entangler"
|
||||
const val ENERGY_CABLE = "energy_cable"
|
||||
|
||||
// blocks
|
||||
const val ANDROID_STATION = "android_station"
|
||||
|
@ -0,0 +1,74 @@
|
||||
{
|
||||
"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
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
{
|
||||
"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
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
{
|
||||
"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
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
{
|
||||
"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
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue
Block a user