Powered Furnace, Blast Furnace, Smoker

This commit is contained in:
DBotThePony 2023-07-20 17:27:01 +07:00
parent 54bc1bdd40
commit 1f1b6e5f59
Signed by: DBot
GPG Key ID: DCC23B5715498507
29 changed files with 473 additions and 115 deletions

View File

@ -423,6 +423,10 @@ private fun blocks(provider: MatteryLanguageProvider) {
add(MBlocks.PLATE_PRESS, "Plate Press")
add(MBlocks.TWIN_PLATE_PRESS, "Twin Plate Press")
add(MBlocks.POWERED_FURNACE, "Powered Furnace")
add(MBlocks.POWERED_SMOKER, "Powered Smoker")
add(MBlocks.POWERED_BLAST_FURNACE, "Powered Blast Furnace")
add(MBlocks.MATTER_RECYCLER, "Matter Recycler")
add(MBlocks.ENERGY_SERVO, "Energy Servo")
add(MBlocks.ENERGY_SERVO, "desc", "Charges, Discharges or Exchanges energy of items")

View File

@ -426,6 +426,10 @@ private fun blocks(provider: MatteryLanguageProvider) {
add(MBlocks.PLATE_PRESS, "Пресс пластин")
add(MBlocks.TWIN_PLATE_PRESS, "Двойной пресс пластин")
add(MBlocks.POWERED_FURNACE, "Электрическая печь")
add(MBlocks.POWERED_BLAST_FURNACE, "Электрическая плавильная печь")
add(MBlocks.POWERED_SMOKER, "Электрическая коптильня")
add(MBlocks.MATTER_RECYCLER, "Перерабатыватель материи")
add(MBlocks.ENERGY_SERVO, "Энергетическая помпа")
add(MBlocks.ENERGY_SERVO, "Desc", "заряжает, разряжает и передаёт энергию между предметами")

View File

@ -154,6 +154,10 @@ fun addLootTables(lootTables: LootTables) {
lootTables.tile(MBlocks.PLATE_PRESS)
lootTables.tile(MBlocks.TWIN_PLATE_PRESS)
lootTables.tile(MBlocks.POWERED_FURNACE)
lootTables.tile(MBlocks.POWERED_SMOKER)
lootTables.tile(MBlocks.POWERED_BLAST_FURNACE)
lootTables.tile(MBlocks.MATTER_PANEL)
lootTables.tile(MBlocks.PATTERN_STORAGE)
lootTables.tile(MBlocks.MATTER_CAPACITOR_BANK)

View File

@ -161,6 +161,10 @@ fun addTags(tagsProvider: TagsProvider) {
MBlocks.TWIN_PLATE_PRESS,
MBlocks.MATTER_RECYCLER,
MBlocks.POWERED_FURNACE,
MBlocks.POWERED_SMOKER,
MBlocks.POWERED_BLAST_FURNACE,
MBlocks.STORAGE_BUS,
MBlocks.STORAGE_IMPORTER,
MBlocks.STORAGE_EXPORTER,

View File

@ -15,11 +15,9 @@ import ru.dbotthepony.mc.otm.capability.IMatteryUpgrade
import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.capability.matteryEnergy
import ru.dbotthepony.mc.otm.container.UpgradeContainer
import ru.dbotthepony.mc.otm.core.immutableList
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.nbt.getCompoundList
import ru.dbotthepony.mc.otm.core.nbt.map
import ru.dbotthepony.mc.otm.core.nbt.set
/**
@ -116,7 +114,7 @@ abstract class MatteryWorkerBlockEntity<JobType : IMachineJob>(
jobEventLoops.forEach { it.isIdling = false }
}
protected fun powerLevelUpdated() {
protected fun energyLevelUpdated() {
super.setChangedLight()
jobEventLoops.forEach { it.notify(MachineJobEventLoop.IdleReason.POWER) }
}

View File

@ -70,7 +70,7 @@ class MatterRecyclerBlockEntity(blockPos: BlockPos, blockState: BlockState)
val container = MatteryContainer(::itemContainerUpdated, 1).also(::addDroppableContainer)
val matterNode = SimpleMatterNode(matter = matter)
val energy = ProfiledEnergyStorage(WorkerEnergyStorage(::powerLevelUpdated, ENERGY_CONFIG))
val energy = ProfiledEnergyStorage(WorkerEnergyStorage(::energyLevelUpdated, ENERGY_CONFIG))
val itemConfig = ConfigurableItemHandler(input = container.handler(object : HandlerFilter {
override fun canInsert(slot: Int, stack: ItemStack): Boolean {

View File

@ -33,7 +33,6 @@ import ru.dbotthepony.mc.otm.core.math.set
import ru.dbotthepony.mc.otm.core.nbt.map
import ru.dbotthepony.mc.otm.core.nbt.set
import ru.dbotthepony.mc.otm.core.util.WriteOnce
import ru.dbotthepony.mc.otm.graph.matter.MatterGraph
import ru.dbotthepony.mc.otm.graph.matter.MatterNode
import ru.dbotthepony.mc.otm.matter.MatterManager
import ru.dbotthepony.mc.otm.menu.matter.MatterReplicatorMenu
@ -103,7 +102,7 @@ class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
}
override val upgrades = UpgradeContainer(this::setChangedLight, 3, UpgradeType.REPLICATOR)
val energy = ProfiledEnergyStorage(WorkerEnergyStorage(::powerLevelUpdated, upgrades.transform(ENERGY_VALUES)))
val energy = ProfiledEnergyStorage(WorkerEnergyStorage(::energyLevelUpdated, upgrades.transform(ENERGY_VALUES)))
val matter = ProfiledMatterStorage(MatterStorageImpl(::matterLevelUpdated, FlowDirection.INPUT, upgrades.matterCapacity(::MATTER_CAPACITY)))
val container = MatteryContainer(::itemContainerUpdated, 5).also(::addDroppableContainer)

View File

@ -38,7 +38,7 @@ class MatterScannerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
MatteryWorkerBlockEntity<MachineItemJob>(MBlockEntities.MATTER_SCANNER, p_155229_, p_155230_, ::MachineItemJob) {
val container = MatteryContainer(::itemContainerUpdated, 1).also(::addDroppableContainer)
val energy = ProfiledEnergyStorage(WorkerEnergyStorage(::powerLevelUpdated, ENERGY_VALUES))
val energy = ProfiledEnergyStorage(WorkerEnergyStorage(::energyLevelUpdated, ENERGY_VALUES))
val itemConfig = ConfigurableItemHandler(inputOutput = container.handler(object : HandlerFilter {
override fun canInsert(slot: Int, stack: ItemStack): Boolean {

View File

@ -12,7 +12,6 @@ import ru.dbotthepony.mc.otm.block.entity.JobContainer
import ru.dbotthepony.mc.otm.block.entity.JobStatus
import ru.dbotthepony.mc.otm.block.entity.MachineItemJob
import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity
import ru.dbotthepony.mc.otm.capability.IMatteryUpgrade
import ru.dbotthepony.mc.otm.capability.UpgradeType
import ru.dbotthepony.mc.otm.capability.energy.ProfiledEnergyStorage
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
@ -33,11 +32,12 @@ class PlatePressBlockEntity(
val isTwin: Boolean = false,
) : MatteryWorkerBlockEntity<MachineItemJob>(if (isTwin) MBlockEntities.TWIN_PLATE_PRESS else MBlockEntities.PLATE_PRESS, p_155229_, p_155230_, ::MachineItemJob, if (isTwin) 2 else 1) {
override val upgrades = UpgradeContainer(this::setChangedLight, if (isTwin) 4 else 3, UpgradeType.BASIC_PROCESSING)
val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::setChangedLight, upgrades.transform(MachinesConfig.PLATE_PRESS)))
val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::energyLevelUpdated, upgrades.transform(MachinesConfig.PLATE_PRESS)))
val inputContainer = MatteryContainer(this::itemContainerUpdated, if (isTwin) 2 else 1).also(::addDroppableContainer)
val outputContainer = MatteryContainer(this::itemContainerUpdated, if (isTwin) 2 else 1).also(::addDroppableContainer)
var experience = 0.0
private set
fun popExperience(player: ServerPlayer) {
val whole = experience.toInt()
@ -105,7 +105,7 @@ class PlatePressBlockEntity(
recipe.getResultItem(level.registryAccess()).copyWithCount(toProcess),
recipe.workTime.toDouble(),
BASELINE_CONSUMPTION * toProcess,
experience = recipe.experience.sample(level.random)))
experience = recipe.experience.sample(level.random) * toProcess))
}
override fun tick() {

View File

@ -0,0 +1,117 @@
package ru.dbotthepony.mc.otm.block.entity.tech
import net.minecraft.core.BlockPos
import net.minecraft.server.level.ServerLevel
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.Container
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
import net.minecraft.world.item.crafting.AbstractCookingRecipe
import net.minecraft.world.item.crafting.Recipe
import net.minecraft.world.item.crafting.RecipeType
import net.minecraft.world.level.block.entity.BlockEntityType
import net.minecraft.world.level.block.state.BlockState
import ru.dbotthepony.mc.otm.block.entity.JobContainer
import ru.dbotthepony.mc.otm.block.entity.JobStatus
import ru.dbotthepony.mc.otm.block.entity.MachineItemJob
import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity
import ru.dbotthepony.mc.otm.capability.CombinedItemHandler
import ru.dbotthepony.mc.otm.capability.UpgradeType
import ru.dbotthepony.mc.otm.capability.energy.ProfiledEnergyStorage
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.config.WorkerBalanceValues
import ru.dbotthepony.mc.otm.container.CombinedContainer
import ru.dbotthepony.mc.otm.container.HandlerFilter
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.container.UpgradeContainer
import ru.dbotthepony.mc.otm.container.balance
import ru.dbotthepony.mc.otm.core.immutableList
import ru.dbotthepony.mc.otm.menu.tech.PoweredFurnaceMenu
class PoweredFurnaceBlockEntity(
type: BlockEntityType<PoweredFurnaceBlockEntity>,
blockPos: BlockPos,
blockState: BlockState,
val recipeType: RecipeType<out AbstractCookingRecipe>,
val config: WorkerBalanceValues
) : MatteryWorkerBlockEntity<MachineItemJob>(type, blockPos, blockState, ::MachineItemJob, 2) {
override val upgrades = UpgradeContainer(this::setChangedLight, 2, UpgradeType.BASIC_PROCESSING)
val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::energyLevelUpdated, upgrades.transform(config)))
val inputs = immutableList(2) { MatteryContainer(this::itemContainerUpdated, 1) }
val outputs = immutableList(2) { MatteryContainer(this::itemContainerUpdated, 1) }
val energyConfig = ConfigurableEnergy(energy)
val itemConfig = ConfigurableItemHandler(
input = CombinedItemHandler(inputs.map { it.handler(HandlerFilter.OnlyIn) }),
output = CombinedItemHandler(outputs.map { it.handler(HandlerFilter.OnlyOut) }),
battery = batteryItemHandler
)
var experience = 0.0
private set
fun popExperience(player: ServerPlayer) {
val whole = experience.toInt()
if (whole > 0) {
experience -= whole
ExperienceOrb.award(player.level() as ServerLevel, player.position(), whole)
}
}
init {
savetables.stateful(::upgrades)
savetables.stateful(::energy)
savetables.double(::experience)
savetables.stateful(inputs, "input")
savetables.stateful(outputs, "output")
}
private val combined = CombinedContainer(inputs)
override fun tick() {
super.tick()
if (balanceInputs) {
combined.balance()
}
}
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
return PoweredFurnaceMenu(containerID, inventory, this)
}
override fun onJobFinish(job: MachineItemJob, id: Int): JobStatus {
if (outputs[id].fullyAddItem(job.itemStack)) {
experience += job.experience
return JobStatus.SUCCESS
}
return JobStatus.FAILURE_ITEM
}
override fun computeNextJob(id: Int): JobContainer<MachineItemJob> {
if (!energy.batteryLevel.isPositive)
return JobContainer.noEnergy()
if (inputs[id].isEmpty)
return JobContainer.noItem()
val level = level as? ServerLevel ?: return JobContainer.failure()
return level.recipeManager.getRecipeFor(recipeType as RecipeType<AbstractCookingRecipe>, inputs[id], level).map {
val output = it.assemble(inputs[id], level.registryAccess())
val toProcess = inputs[id][0].count.coerceAtMost(upgrades.processingItems + 1)
inputs[id][0].shrink(toProcess)
JobContainer.success(MachineItemJob(
output.copyWithCount(toProcess), it.cookingTime * config.workTimeMultiplier, config.powerConsumption * toProcess, it.experience * toProcess
))
}.orElse(JobContainer.noItem())
}
}

View File

@ -0,0 +1,27 @@
package ru.dbotthepony.mc.otm.block.tech
import net.minecraft.core.BlockPos
import net.minecraft.world.item.crafting.AbstractCookingRecipe
import net.minecraft.world.item.crafting.RecipeType
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.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.block.entity.tech.PoweredFurnaceBlockEntity
import ru.dbotthepony.mc.otm.config.WorkerBalanceValues
class PoweredFurnaceBlock(val type: () -> BlockEntityType<PoweredFurnaceBlockEntity>, val recipeType: RecipeType<out AbstractCookingRecipe>, val config: WorkerBalanceValues) : RotatableMatteryBlock(), EntityBlock {
override fun newBlockEntity(p_153215_: BlockPos, p_153216_: BlockState): PoweredFurnaceBlockEntity {
return PoweredFurnaceBlockEntity(type.invoke(), p_153215_, p_153216_, recipeType, config)
}
override fun <T : BlockEntity?> getTicker(p_153212_: Level, p_153213_: BlockState, p_153214_: BlockEntityType<T>): BlockEntityTicker<T>? {
if (p_153212_.isClientSide)
return null
return BlockEntityTicker { _, _, _, tile -> if (tile is PoweredFurnaceBlockEntity) tile.tick() }
}
}

View File

@ -0,0 +1,35 @@
package ru.dbotthepony.mc.otm.client.screen.tech
import net.minecraft.network.chat.Component
import net.minecraft.world.entity.player.Inventory
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.client.screen.panels.slot.BatterySlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls
import ru.dbotthepony.mc.otm.client.screen.panels.slot.SlotPanel
import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel
import ru.dbotthepony.mc.otm.client.screen.widget.WideProfiledPowerGaugePanel
import ru.dbotthepony.mc.otm.menu.tech.PoweredFurnaceMenu
import ru.dbotthepony.mc.otm.menu.tech.TwinPlatePressMenu
class PoweredFurnaceScreen(menu: PoweredFurnaceMenu, inventory: Inventory, title: Component) :
MatteryScreen<PoweredFurnaceMenu>(menu, inventory, title) {
override fun makeMainFrame(): FramePanel<MatteryScreen<*>> {
val frame = super.makeMainFrame()!!
WideProfiledPowerGaugePanel(this, frame, menu.profiledEnergy, LEFT_MARGIN, GAUGE_TOP_WITH_SLOT)
BatterySlotPanel(this, frame, menu.batterySlot, LEFT_MARGIN, SLOT_TOP_UNDER_GAUGE)
SlotPanel(this, frame, menu.inputSlots[0], 56f, PROGRESS_SLOT_TOP - 10f)
ProgressGaugePanel(this, frame, menu.progressGauge[0], 78f, PROGRESS_ARROW_TOP - 10f)
SlotPanel(this, frame, menu.outputSlots[0], 104f, PROGRESS_SLOT_TOP - 10f)
SlotPanel(this, frame, menu.inputSlots[1], 56f, PROGRESS_SLOT_TOP + 10f)
ProgressGaugePanel(this, frame, menu.progressGauge[1], 78f, PROGRESS_ARROW_TOP + 10f)
SlotPanel(this, frame, menu.outputSlots[1], 104f, PROGRESS_SLOT_TOP + 10f)
makeDeviceControls(this, frame, redstoneConfig = menu.redstoneConfig, energyConfig = menu.energyConfig, itemConfig = menu.itemConfig, balanceInputs = menu.balanceInputs, upgrades = menu.upgrades)
return frame
}
}

View File

@ -4,6 +4,8 @@ import net.minecraftforge.common.ForgeConfigSpec
import net.minecraftforge.fml.ModLoadingContext
import net.minecraftforge.fml.config.ModConfig
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.defineDecimal
import ru.dbotthepony.mc.otm.core.util.WriteOnce
abstract class AbstractConfig(private val configName: String, private val type: ModConfig.Type = ModConfig.Type.SERVER) {
@ -11,6 +13,65 @@ abstract class AbstractConfig(private val configName: String, private val type:
protected val builder = ForgeConfigSpec.Builder()
private var registered = false
fun verboseValues(name: String, storage: Decimal, receive: Decimal, extract: Decimal = receive): VerboseBalanceValues {
builder.push(name)
val obj = object : VerboseBalanceValues {
override val capacity: Decimal by builder.defineDecimal("capacity", storage, minimum = Decimal.ONE)
override val receive: Decimal by builder.defineDecimal("receive", receive, minimum = Decimal.ONE)
override val extract: Decimal by builder.defineDecimal("extract", extract, minimum = Decimal.ONE)
}
builder.pop()
return obj
}
fun batteryValues(name: String, storage: Decimal, receive: Decimal, extract: Decimal = receive, initialBatteryLevel: Decimal = Decimal.ZERO): BatteryBalanceValues {
builder.push(name)
val obj = object : BatteryBalanceValues {
override val capacity: Decimal by builder.defineDecimal("capacity", storage, minimum = Decimal.ONE)
override val receive: Decimal by builder.defineDecimal("receive", receive, minimum = Decimal.ONE)
override val extract: Decimal by builder.defineDecimal("extract", extract, minimum = Decimal.ONE)
override val initialBatteryLevel: Decimal by builder.defineDecimal("initialBatteryLevel", initialBatteryLevel, minimum = Decimal.ZERO)
}
builder.pop()
return obj
}
fun conciseValues(name: String, storage: Decimal, throughput: Decimal, configurator: ForgeConfigSpec.Builder.() -> Unit = {}): ConciseBalanceValues {
builder.push(name)
val obj = object : ConciseBalanceValues {
override val capacity: Decimal by builder.defineDecimal("capacity", storage, minimum = Decimal.ONE)
override val throughput: Decimal by builder.defineDecimal("throughput", throughput, minimum = Decimal.ONE)
}
configurator.invoke(builder)
builder.pop()
return obj
}
fun workerValues(name: String, storage: Decimal, throughput: Decimal, workTimeMultiplier: Double = 1.0, powerConsumption: Decimal, configurator: ForgeConfigSpec.Builder.() -> Unit = {}): WorkerBalanceValues {
builder.push(name)
val obj = object : WorkerBalanceValues {
override val capacity: Decimal by builder.defineDecimal("capacity", storage, minimum = Decimal.ONE)
override val throughput: Decimal by builder.defineDecimal("throughput", throughput, minimum = Decimal.ONE)
override val powerConsumption: Decimal by builder.defineDecimal("powerConsumption", powerConsumption, minimum = Decimal.ONE)
override val workTimeMultiplier: Double by builder.defineInRange("workTimeMultiplier", workTimeMultiplier, 0.0)
}
configurator.invoke(builder)
builder.pop()
return obj
}
fun register() {
check(!registered) { "Already registered config" }
registered = true

View File

@ -0,0 +1,23 @@
package ru.dbotthepony.mc.otm.config
import ru.dbotthepony.mc.otm.core.math.Decimal
interface ConciseBalanceValues {
val capacity: Decimal
val throughput: Decimal
}
interface WorkerBalanceValues : ConciseBalanceValues {
val workTimeMultiplier: Double
val powerConsumption: Decimal
}
interface BatteryBalanceValues : VerboseBalanceValues {
val initialBatteryLevel: Decimal
}
interface VerboseBalanceValues {
val capacity: Decimal
val receive: Decimal
val extract: Decimal
}

View File

@ -1,7 +0,0 @@
package ru.dbotthepony.mc.otm.config
import ru.dbotthepony.mc.otm.core.math.Decimal
interface BatteryBalanceValues : VerboseBalanceValues {
val initialBatteryLevel: Decimal
}

View File

@ -1,8 +0,0 @@
package ru.dbotthepony.mc.otm.config
import ru.dbotthepony.mc.otm.core.math.Decimal
interface ConciseBalanceValues {
val capacity: Decimal
val throughput: Decimal
}

View File

@ -5,48 +5,6 @@ import ru.dbotthepony.mc.otm.core.math.defineDecimal
import ru.dbotthepony.mc.otm.registry.MNames
object ItemsConfig : AbstractConfig("items") {
private fun verboseValues(name: String, storage: Decimal, receive: Decimal, extract: Decimal = receive): VerboseBalanceValues {
builder.push(name)
val obj = object : VerboseBalanceValues {
override val capacity: Decimal by builder.defineDecimal("capacity", storage, minimum = Decimal.ONE)
override val receive: Decimal by builder.defineDecimal("receive", receive, minimum = Decimal.ONE)
override val extract: Decimal by builder.defineDecimal("extract", extract, minimum = Decimal.ONE)
}
builder.pop()
return obj
}
private fun batteryValues(name: String, storage: Decimal, receive: Decimal, extract: Decimal = receive, initialBatteryLevel: Decimal = Decimal.ZERO): BatteryBalanceValues {
builder.push(name)
val obj = object : BatteryBalanceValues {
override val capacity: Decimal by builder.defineDecimal("capacity", storage, minimum = Decimal.ONE)
override val receive: Decimal by builder.defineDecimal("receive", receive, minimum = Decimal.ONE)
override val extract: Decimal by builder.defineDecimal("extract", extract, minimum = Decimal.ONE)
override val initialBatteryLevel: Decimal by builder.defineDecimal("initialBatteryLevel", initialBatteryLevel, minimum = Decimal.ZERO)
}
builder.pop()
return obj
}
private fun conciseValues(name: String, storage: Decimal, throughput: Decimal): ConciseBalanceValues {
builder.push(name)
val obj = object : ConciseBalanceValues {
override val capacity: Decimal by builder.defineDecimal("capacity", storage, minimum = Decimal.ONE)
override val throughput: Decimal by builder.defineDecimal("throughput", throughput, minimum = Decimal.ONE)
}
builder.pop()
return obj
}
init {
builder.push("EnergyBatteries")
}

View File

@ -44,6 +44,30 @@ object MachinesConfig : AbstractConfig("machines") {
val ANDROID_CHARGER = BlockEnergyStorageImpl.makeConfigEntry(builder, MNames.ANDROID_CHARGER, capacity = Decimal(1_000_000), throughput = Decimal(8192)) { AndroidCharger }
val POWERED_FURNACE = workerValues(
"POWERED_FURNACE",
storage = Decimal(40_000),
throughput = Decimal(200),
powerConsumption = Decimal(20),
workTimeMultiplier = 0.75
)
val POWERED_BLAST_FURNACE = workerValues(
"POWERED_BLAST_FURNACE",
storage = Decimal(40_000),
throughput = Decimal(200),
powerConsumption = Decimal(20),
workTimeMultiplier = 0.75
)
val POWERED_SMOKER = workerValues(
"POWERED_SMOKER",
storage = Decimal(40_000),
throughput = Decimal(200),
powerConsumption = Decimal(10),
workTimeMultiplier = 0.75
)
object Upgrades {
init {
builder.push("UPGRADES")

View File

@ -1,9 +0,0 @@
package ru.dbotthepony.mc.otm.config
import ru.dbotthepony.mc.otm.core.math.Decimal
interface VerboseBalanceValues {
val capacity: Decimal
val receive: Decimal
val extract: Decimal
}

View File

@ -5,31 +5,25 @@ import com.google.common.collect.ImmutableMap
import com.google.common.collect.ImmutableSet
import it.unimi.dsi.fastutil.ints.IntAVLTreeSet
import it.unimi.dsi.fastutil.ints.IntOpenHashSet
import it.unimi.dsi.fastutil.ints.IntSet
import it.unimi.dsi.fastutil.objects.Object2ObjectFunction
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap
import net.minecraft.world.Container
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.ItemStack
import ru.dbotthepony.mc.otm.core.GetterSetter
import ru.dbotthepony.mc.otm.core.stream
import java.util.LinkedList
import java.util.function.Consumer
import java.util.function.Supplier
import java.util.stream.Stream
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
open class ContainerProxy(containers: Stream<Pair<Container, Iterator<Int>>>) : Container {
data class ContainerSlot(val container: Container, val outerIndex: Int, val index: Int) : ReadWriteProperty<Any, ItemStack>, Supplier<ItemStack>, Consumer<ItemStack> {
class CombinedContainer(containers: Stream<Pair<Container, Iterator<Int>>>) : Container {
constructor(vararg containers: Container) : this(containers.stream().map { it to (0 until it.containerSize).iterator() })
constructor(containers: Collection<Container>) : this(containers.stream().map { it to (0 until it.containerSize).iterator() })
class ContainerSlot(val container: Container, val containerIndex: Int) : GetterSetter<ItemStack> {
var item: ItemStack
get() = container[index]
set(value) { container[index] = value }
override fun getValue(thisRef: Any, property: KProperty<*>): ItemStack {
return item
}
override fun setValue(thisRef: Any, property: KProperty<*>, value: ItemStack) {
this.item = value
}
get() = container[containerIndex]
set(value) { container[containerIndex] = value }
override fun get(): ItemStack {
return item
@ -42,25 +36,26 @@ open class ContainerProxy(containers: Stream<Pair<Container, Iterator<Int>>>) :
val isEmpty: Boolean get() = item.isEmpty
}
protected val slots: List<ContainerSlot>
protected val slotsMap: Map<Container, List<ContainerSlot>>
protected val containers: Set<Container>
protected val fullCoverage: List<Container>
protected val notFullCoverage: Map<Container, List<ContainerSlot>>
private val slots: List<ContainerSlot>
private val slotsMap: Map<Container, List<ContainerSlot>>
private val containers: Set<Container>
private val fullCoverage: List<Container>
private val notFullCoverage: Map<Container, List<ContainerSlot>>
init {
val list = ImmutableList.Builder<ContainerSlot>()
var i = 0
val validationMap = Reference2ObjectOpenHashMap<Container, IntOpenHashSet>()
val validationMap = Reference2ObjectOpenHashMap<Container, IntSet>()
val slotsMap = Reference2ObjectOpenHashMap<Container, ArrayList<ContainerSlot>>()
for ((container, slots) in containers) {
val validator = validationMap.computeIfAbsent(container, Object2ObjectFunction { IntOpenHashSet() })
val validator = validationMap.computeIfAbsent(container, Object2ObjectFunction { IntAVLTreeSet() })
val slotList = slotsMap.computeIfAbsent(container, Object2ObjectFunction { ArrayList() })
for (slot in slots) {
if (validator.add(slot)) {
val slotObj = ContainerSlot(container, i++, slot)
i++
val slotObj = ContainerSlot(container, slot)
list.add(slotObj)
slotList.add(slotObj)
} else {
@ -106,15 +101,17 @@ open class ContainerProxy(containers: Stream<Pair<Container, Iterator<Int>>>) :
}
override fun isEmpty(): Boolean {
for (container in fullCoverage)
if (!container.isEmpty)
return false
for (slots in notFullCoverage.values)
for (slot in slots)
if (!slot.isEmpty)
if (fullCoverage.isNotEmpty())
for (container in fullCoverage)
if (!container.isEmpty)
return false
if (notFullCoverage.isNotEmpty())
for (slots in notFullCoverage.values)
for (slot in slots)
if (!slot.isEmpty)
return false
return true
}
@ -129,16 +126,16 @@ open class ContainerProxy(containers: Stream<Pair<Container, Iterator<Int>>>) :
override fun removeItem(index: Int, count: Int): ItemStack {
val data = slots.getOrNull(index) ?: return ItemStack.EMPTY
return data.container.removeItem(data.index, count)
return data.container.removeItem(data.containerIndex, count)
}
override fun removeItemNoUpdate(index: Int): ItemStack {
val data = slots[index]
return data.container.removeItemNoUpdate(data.index)
val data = slots.getOrNull(index) ?: return ItemStack.EMPTY
return data.container.removeItemNoUpdate(data.containerIndex)
}
override fun setItem(index: Int, value: ItemStack) {
slots[index].item = value
slots.getOrNull(index)?.item = value
}
override fun setChanged() {
@ -147,6 +144,16 @@ open class ContainerProxy(containers: Stream<Pair<Container, Iterator<Int>>>) :
}
}
fun setChanged(index: Int) {
val data = slots.getOrNull(index) ?: return
if (data.container is MatteryContainer) {
data.container.setChanged(data.containerIndex)
} else {
data.container.setChanged()
}
}
override fun stillValid(player: Player): Boolean {
for (container in containers)
if (!container.stillValid(player))
@ -177,9 +184,9 @@ open class ContainerProxy(containers: Stream<Pair<Container, Iterator<Int>>>) :
return this
}
fun build(): ContainerProxy {
fun build(): CombinedContainer {
check(!built) { "Already built!" }
val value = ContainerProxy(values.stream())
val value = CombinedContainer(values.stream())
values.clear()
return value
}

View File

@ -1,5 +1,6 @@
package ru.dbotthepony.mc.otm.core.util
import com.google.common.collect.ImmutableList
import com.mojang.serialization.Codec
import net.minecraft.nbt.ByteTag
import net.minecraft.nbt.CompoundTag
@ -16,6 +17,7 @@ import net.minecraft.resources.ResourceLocation
import net.minecraftforge.common.util.INBTSerializable
import ru.dbotthepony.mc.otm.core.GetterSetter
import ru.dbotthepony.mc.otm.core.asGetterSetter
import ru.dbotthepony.mc.otm.core.immutableList
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.Vector
import ru.dbotthepony.mc.otm.core.nbt.set
@ -49,6 +51,12 @@ class Savetables : INBTSerializable<CompoundTag?> {
return stateful(getter, name, T::class.java)
}
inline fun <V : INBTSerializable<T?>, reified T : Tag> stateful(values: List<V>, name: String): ImmutableList<Stateful<V, T>> {
return immutableList(values.size) {
stateful(values[it], "${name}_$it", T::class.java)
}
}
fun <V : INBTSerializable<T?>, T : Tag> stateful(getter: Supplier<V>, name: String, type: Class<T>): Stateful<V, T> {
return Stateful(getter, name, type)
.withSerializer { it.serializeNBT() }

View File

@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.menu
import com.google.common.collect.ImmutableList
import net.minecraft.world.Container
import net.minecraft.world.SimpleContainer
import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.Slot
import net.minecraft.world.item.Item
@ -15,10 +16,20 @@ import ru.dbotthepony.mc.otm.core.GetterSetter
import ru.dbotthepony.mc.otm.core.immutableList
import ru.dbotthepony.mc.otm.runOnClient
/**
* Make slots for single container
*/
inline fun <C : Container, S : Slot> makeSlots(container: C, initializer: (C, Int) -> S): ImmutableList<S> {
return immutableList(container.containerSize) { initializer.invoke(container, it) }
}
/**
* Make slots for list of containers with single slot in them
*/
inline fun <S : Slot> makeSlots(containers: List<Container>?, size: Int, initializer: (Container, Int) -> S): ImmutableList<S> {
return immutableList(size) { initializer(containers?.get(it) ?: SimpleContainer(1), 0) }
}
open class MatterySlot(container: Container, index: Int, x: Int = 0, y: Int = 0) : Slot(container, index, x, y) {
var ignoreSpectators = true

View File

@ -0,0 +1,41 @@
package ru.dbotthepony.mc.otm.menu.tech
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.entity.player.Inventory
import ru.dbotthepony.mc.otm.block.entity.tech.PoweredFurnaceBlockEntity
import ru.dbotthepony.mc.otm.core.immutableList
import ru.dbotthepony.mc.otm.menu.MachineOutputSlot
import ru.dbotthepony.mc.otm.menu.MatteryPoweredMenu
import ru.dbotthepony.mc.otm.menu.MatterySlot
import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback
import ru.dbotthepony.mc.otm.menu.input.EnergyConfigPlayerInput
import ru.dbotthepony.mc.otm.menu.input.ItemConfigPlayerInput
import ru.dbotthepony.mc.otm.menu.makeSlots
import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget
import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget
import ru.dbotthepony.mc.otm.registry.MMenus
class PoweredFurnaceMenu(
containerID: Int,
inventory: Inventory,
tile: PoweredFurnaceBlockEntity? = null
) : MatteryPoweredMenu(MMenus.POWERED_FURNACE, containerID, inventory, tile) {
val inputSlots = makeSlots(tile?.inputs, 2, ::MatterySlot)
val outputSlots = makeSlots(tile?.outputs, 2) { c, s -> MachineOutputSlot(c, s) { tile?.popExperience(ply as ServerPlayer) } }
val progressGauge = immutableList(2) { ProgressGaugeWidget(this, tile?.jobEventLoops?.get(it)) }
val itemConfig = ItemConfigPlayerInput(this, tile?.itemConfig, allowPush = true)
val energyConfig = EnergyConfigPlayerInput(this, tile?.energyConfig, allowPull = true)
val profiledEnergy = ProfiledLevelGaugeWidget(this, tile?.energy, energyWidget)
val balanceInputs = BooleanInputWithFeedback(this)
val upgrades = makeUpgradeSlots(2, tile?.upgrades)
init {
if (tile != null) balanceInputs.with(tile::balanceInputs)
addStorageSlot(inputSlots)
addStorageSlot(outputSlots)
addInventorySlots()
}
}

View File

@ -59,6 +59,10 @@ object MBlockEntities {
val ANDROID_CHARGER_MIDDLE: BlockEntityType<AndroidChargerMiddleBlockEntity> by registry.register(MNames.ANDROID_CHARGER + "_middle") { BlockEntityType.Builder.of(::AndroidChargerMiddleBlockEntity, MBlocks.ANDROID_CHARGER).build(null) }
val ANDROID_CHARGER_TOP: BlockEntityType<AndroidChargerTopBlockEntity> by registry.register(MNames.ANDROID_CHARGER + "_top") { BlockEntityType.Builder.of(::AndroidChargerTopBlockEntity, MBlocks.ANDROID_CHARGER).build(null) }
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) }
val POWERED_SMOKER: BlockEntityType<PoweredFurnaceBlockEntity> by registry.register(MNames.POWERED_SMOKER) { BlockEntityType.Builder.of({ a, b -> MBlocks.POWERED_SMOKER.newBlockEntity(a, b) }, MBlocks.POWERED_SMOKER).build(null) }
val STORAGE_BUS: BlockEntityType<StorageBusBlockEntity> by registry.register(MNames.STORAGE_BUS) { BlockEntityType.Builder.of(::StorageBusBlockEntity, MBlocks.STORAGE_BUS).build(null) }
val STORAGE_IMPORTER: BlockEntityType<StorageImporterBlockEntity> by registry.register(MNames.STORAGE_IMPORTER) { BlockEntityType.Builder.of(::StorageImporterBlockEntity, MBlocks.STORAGE_IMPORTER).build(null) }
val STORAGE_EXPORTER: BlockEntityType<StorageExporterBlockEntity> by registry.register(MNames.STORAGE_EXPORTER) { BlockEntityType.Builder.of(::StorageExporterBlockEntity, MBlocks.STORAGE_EXPORTER).build(null) }

View File

@ -3,7 +3,6 @@ package ru.dbotthepony.mc.otm.registry
import net.minecraft.ChatFormatting
import net.minecraft.core.BlockPos
import net.minecraft.network.chat.Component
import net.minecraft.sounds.SoundEvents
import net.minecraft.util.valueproviders.UniformInt
import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.EntityType
@ -11,6 +10,7 @@ import net.minecraft.world.entity.monster.Zombie
import net.minecraft.world.item.DyeColor
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.TooltipFlag
import net.minecraft.world.item.crafting.RecipeType
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.block.*
import net.minecraft.world.level.block.state.BlockBehaviour
@ -61,6 +61,8 @@ import ru.dbotthepony.mc.otm.block.storage.StoragePowerSupplierBlock
import ru.dbotthepony.mc.otm.block.tech.AndroidChargerBlock
import ru.dbotthepony.mc.otm.block.tech.CobblerBlock
import ru.dbotthepony.mc.otm.block.tech.EssenceStorageBlock
import ru.dbotthepony.mc.otm.block.tech.PoweredFurnaceBlock
import ru.dbotthepony.mc.otm.config.MachinesConfig
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.collect.SupplierList
@ -86,6 +88,9 @@ object MBlocks {
val CHEMICAL_GENERATOR: Block by registry.register(MNames.CHEMICAL_GENERATOR) { ChemicalGeneratorBlock() }
val PLATE_PRESS: Block by registry.register(MNames.PLATE_PRESS) { PlatePressBlock() }
val TWIN_PLATE_PRESS: Block by registry.register(MNames.TWIN_PLATE_PRESS) { PlatePressBlock(isTwin = true) }
val POWERED_FURNACE: PoweredFurnaceBlock by registry.register(MNames.POWERED_FURNACE) { PoweredFurnaceBlock(MBlockEntities::POWERED_FURNACE, RecipeType.SMELTING, MachinesConfig.POWERED_FURNACE) }
val POWERED_BLAST_FURNACE: PoweredFurnaceBlock by registry.register(MNames.POWERED_BLAST_FURNACE) { PoweredFurnaceBlock(MBlockEntities::POWERED_BLAST_FURNACE, RecipeType.BLASTING, MachinesConfig.POWERED_BLAST_FURNACE) }
val POWERED_SMOKER: PoweredFurnaceBlock by registry.register(MNames.POWERED_SMOKER) { PoweredFurnaceBlock(MBlockEntities::POWERED_SMOKER, RecipeType.SMOKING, MachinesConfig.POWERED_SMOKER) }
val MATTER_RECYCLER: Block by registry.register(MNames.MATTER_RECYCLER) { MatterRecyclerBlock() }
val ENERGY_SERVO: Block by registry.register(MNames.ENERGY_SERVO) { EnergyServoBlock() }
val COBBLESTONE_GENERATOR: Block by registry.register(MNames.COBBLESTONE_GENERATOR) { CobblerBlock() }

View File

@ -66,6 +66,10 @@ object MItems {
val TWIN_PLATE_PRESS: BlockItem by registry.register(MNames.TWIN_PLATE_PRESS) { BlockItem(MBlocks.TWIN_PLATE_PRESS, DEFAULT_PROPERTIES) }
val MATTER_RECYCLER: BlockItem by registry.register(MNames.MATTER_RECYCLER) { BlockItem(MBlocks.MATTER_RECYCLER, DEFAULT_PROPERTIES) }
val POWERED_FURNACE: BlockItem by registry.register(MNames.POWERED_FURNACE) { BlockItem(MBlocks.POWERED_FURNACE, DEFAULT_PROPERTIES) }
val POWERED_BLAST_FURNACE: BlockItem by registry.register(MNames.POWERED_BLAST_FURNACE) { BlockItem(MBlocks.POWERED_BLAST_FURNACE, DEFAULT_PROPERTIES) }
val POWERED_SMOKER: BlockItem by registry.register(MNames.POWERED_SMOKER) { BlockItem(MBlocks.POWERED_SMOKER, DEFAULT_PROPERTIES) }
val STORAGE_BUS: BlockItem by registry.register(MNames.STORAGE_BUS) { BlockItem(MBlocks.STORAGE_BUS, DEFAULT_PROPERTIES) }
val STORAGE_IMPORTER: BlockItem by registry.register(MNames.STORAGE_IMPORTER) { BlockItem(MBlocks.STORAGE_IMPORTER, DEFAULT_PROPERTIES) }
val STORAGE_EXPORTER: BlockItem by registry.register(MNames.STORAGE_EXPORTER) { BlockItem(MBlocks.STORAGE_EXPORTER, DEFAULT_PROPERTIES) }
@ -139,7 +143,8 @@ object MItems {
val MACHINES = SupplierList(
::ANDROID_STATION, ::ANDROID_CHARGER, ::BATTERY_BANK, ::MATTER_DECOMPOSER, ::MATTER_CAPACITOR_BANK, ::MATTER_CABLE, ::PATTERN_STORAGE,
::MATTER_SCANNER, ::MATTER_PANEL, ::MATTER_REPLICATOR, ::MATTER_BOTTLER, ::ENERGY_COUNTER, ::CHEMICAL_GENERATOR,
::PLATE_PRESS, ::TWIN_PLATE_PRESS, ::MATTER_RECYCLER,
::MATTER_RECYCLER, ::PLATE_PRESS, ::TWIN_PLATE_PRESS, ::POWERED_FURNACE, ::POWERED_BLAST_FURNACE,
::POWERED_SMOKER,
// ::STORAGE_BUS, ::STORAGE_IMPORTER, ::STORAGE_EXPORTER, ::DRIVE_VIEWER,
// ::DRIVE_RACK, ::ITEM_MONITOR, ::STORAGE_CABLE, ::STORAGE_POWER_SUPPLIER,
::ENERGY_SERVO,

View File

@ -38,6 +38,7 @@ import ru.dbotthepony.mc.otm.client.screen.tech.EnergyCounterScreen
import ru.dbotthepony.mc.otm.client.screen.tech.EnergyServoScreen
import ru.dbotthepony.mc.otm.client.screen.tech.EssenceStorageScreen
import ru.dbotthepony.mc.otm.client.screen.tech.PlatePressScreen
import ru.dbotthepony.mc.otm.client.screen.tech.PoweredFurnaceScreen
import ru.dbotthepony.mc.otm.client.screen.tech.TwinPlatePressScreen
import ru.dbotthepony.mc.otm.menu.decorative.CargoCrateMenu
import ru.dbotthepony.mc.otm.menu.decorative.FluidTankMenu
@ -68,6 +69,7 @@ import ru.dbotthepony.mc.otm.menu.tech.EnergyCounterMenu
import ru.dbotthepony.mc.otm.menu.tech.EnergyServoMenu
import ru.dbotthepony.mc.otm.menu.tech.EssenceStorageMenu
import ru.dbotthepony.mc.otm.menu.tech.PlatePressMenu
import ru.dbotthepony.mc.otm.menu.tech.PoweredFurnaceMenu
import ru.dbotthepony.mc.otm.menu.tech.TwinPlatePressMenu
object MMenus {
@ -91,6 +93,7 @@ object MMenus {
val ENERGY_COUNTER: MenuType<EnergyCounterMenu> by registry.register(MNames.ENERGY_COUNTER) { MenuType(::EnergyCounterMenu, FeatureFlags.VANILLA_SET) }
val CHEMICAL_GENERATOR: MenuType<ChemicalGeneratorMenu> by registry.register(MNames.CHEMICAL_GENERATOR) { MenuType(::ChemicalGeneratorMenu, FeatureFlags.VANILLA_SET) }
val PLATE_PRESS: MenuType<PlatePressMenu> by registry.register(MNames.PLATE_PRESS) { MenuType(::PlatePressMenu, FeatureFlags.VANILLA_SET) }
val POWERED_FURNACE: MenuType<PoweredFurnaceMenu> by registry.register(MNames.POWERED_FURNACE) { MenuType(::PoweredFurnaceMenu, FeatureFlags.VANILLA_SET) }
val TWIN_PLATE_PRESS: MenuType<TwinPlatePressMenu> by registry.register(MNames.TWIN_PLATE_PRESS) { MenuType(::TwinPlatePressMenu, FeatureFlags.VANILLA_SET) }
val MATTER_RECYCLER: MenuType<MatterRecyclerMenu> by registry.register(MNames.MATTER_RECYCLER) { MenuType(::MatterRecyclerMenu, FeatureFlags.VANILLA_SET) }
val ENERGY_SERVO: MenuType<EnergyServoMenu> by registry.register(MNames.ENERGY_SERVO) { MenuType(::EnergyServoMenu, FeatureFlags.VANILLA_SET) }
@ -143,6 +146,7 @@ object MMenus {
MenuScreens.register(ESSENCE_STORAGE, ::EssenceStorageScreen)
MenuScreens.register(ITEM_REPAIER, ::MatterReconstructorScreen)
MenuScreens.register(FLUID_TANK, ::FluidTankScreen)
MenuScreens.register(POWERED_FURNACE, ::PoweredFurnaceScreen)
}
}
}

View File

@ -32,6 +32,9 @@ object MNames {
const val ENERGY_COUNTER = "energy_counter"
const val CHEMICAL_GENERATOR = "chemical_generator"
const val PLATE_PRESS = "plate_press"
const val POWERED_FURNACE = "powered_furnace"
const val POWERED_BLAST_FURNACE = "powered_blast_furnace"
const val POWERED_SMOKER = "powered_smoker"
const val TWIN_PLATE_PRESS = "twin_plate_press"
const val MATTER_RECYCLER = "matter_recycler"
const val ENERGY_SERVO = "energy_servo"

View File

@ -1,10 +1,16 @@
package ru.dbotthepony.mc.otm.registry
import com.google.common.collect.ImmutableSet
import com.google.common.collect.Streams
import net.minecraft.advancements.CriteriaTriggers
import net.minecraft.client.renderer.item.ItemProperties
import net.minecraft.core.BlockPos
import net.minecraft.core.Registry
import net.minecraft.core.registries.Registries
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.level.BlockGetter
import net.minecraft.world.level.block.*
import net.minecraft.world.level.block.state.BlockBehaviour
@ -17,6 +23,7 @@ import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent
import net.minecraftforge.fml.loading.FMLEnvironment
import net.minecraftforge.registries.NewRegistryEvent
import net.minecraftforge.registries.RegisterEvent
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.android.AndroidResearchResult
import ru.dbotthepony.mc.otm.android.AndroidResearchResults
@ -209,11 +216,40 @@ object MRegistry {
WallBlock(BlockBehaviour.Properties.copy(TRITANIUM_STRIPED_BLOCK.getBlock(colorA, colorB)))
})
private fun registerEvent(event: RegisterEvent) {
// mojang moment
if (event.registryKey == Registries.POINT_OF_INTEREST_TYPE) {
val reg = event.getVanillaRegistry<PoiType>() ?: throw IllegalStateException("POI registry is not a vanilla registry")
event.register(Registries.POINT_OF_INTEREST_TYPE, PoiTypes.BUTCHER.location()) {
val old = reg[PoiTypes.BUTCHER] ?: throw IllegalStateException("POI with type ${PoiTypes.ARMORER} does not exist")
if (old.`is`(MBlocks.POWERED_SMOKER.defaultBlockState())) {
old
} else {
PoiType(Streams.concat(old.matchingStates.stream(), MBlocks.POWERED_SMOKER.stateDefinition.possibleStates.stream()).collect(ImmutableSet.toImmutableSet()), old.maxTickets, old.validRange)
}
}
event.register(Registries.POINT_OF_INTEREST_TYPE, PoiTypes.ARMORER.location()) {
val old = reg[PoiTypes.ARMORER] ?: throw IllegalStateException("POI with type ${PoiTypes.ARMORER} does not exist")
if (old.`is`(MBlocks.POWERED_BLAST_FURNACE.defaultBlockState())) {
old
} else {
PoiType(Streams.concat(old.matchingStates.stream(), MBlocks.POWERED_BLAST_FURNACE.stateDefinition.possibleStates.stream()).collect(ImmutableSet.toImmutableSet()), old.maxTickets, old.validRange)
}
}
}
}
fun initialize(bus: IEventBus) {
bus.addListener(this::register)
bus.addListener(this::initializeClient)
bus.addListener(this::initializeCommon)
bus.addListener(MStats::registerVanilla)
bus.addListener(this::registerEvent)
MCreativeTabs.initialize(bus)