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 fbfc1924a..ec8988def 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 @@ -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") 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 bc91aed29..7eb5f2596 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 @@ -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", "заряжает, разряжает и передаёт энергию между предметами") diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootTablesData.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootTablesData.kt index 971a5b63f..d4d9e9566 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootTablesData.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootTablesData.kt @@ -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) diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/tags/Tags.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/tags/Tags.kt index b69231e57..5f9851f86 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/tags/Tags.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/tags/Tags.kt @@ -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, diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryWorkerBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryWorkerBlockEntity.kt index 42b5c7a49..78be6a527 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryWorkerBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryWorkerBlockEntity.kt @@ -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( jobEventLoops.forEach { it.isIdling = false } } - protected fun powerLevelUpdated() { + protected fun energyLevelUpdated() { super.setChangedLight() jobEventLoops.forEach { it.notify(MachineJobEventLoop.IdleReason.POWER) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterRecyclerBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterRecyclerBlockEntity.kt index aac8e8df3..fd31b7739 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterRecyclerBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterRecyclerBlockEntity.kt @@ -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 { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterReplicatorBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterReplicatorBlockEntity.kt index 8bcb8245d..a71405fc6 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterReplicatorBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterReplicatorBlockEntity.kt @@ -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) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterScannerBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterScannerBlockEntity.kt index 32ff3b70d..ad51f4083 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterScannerBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/matter/MatterScannerBlockEntity.kt @@ -38,7 +38,7 @@ class MatterScannerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : MatteryWorkerBlockEntity(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 { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/PlatePressBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/PlatePressBlockEntity.kt index b68d30b98..ea539f9fb 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/PlatePressBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/PlatePressBlockEntity.kt @@ -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(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() { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/PoweredFurnaceBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/PoweredFurnaceBlockEntity.kt new file mode 100644 index 000000000..7d04fe739 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/PoweredFurnaceBlockEntity.kt @@ -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, + blockPos: BlockPos, + blockState: BlockState, + val recipeType: RecipeType, + val config: WorkerBalanceValues +) : MatteryWorkerBlockEntity(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 { + 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, 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()) + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/PoweredFurnaceBlock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/PoweredFurnaceBlock.kt new file mode 100644 index 000000000..e6c0c95f6 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/PoweredFurnaceBlock.kt @@ -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, val recipeType: RecipeType, 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 getTicker(p_153212_: Level, p_153213_: BlockState, p_153214_: BlockEntityType): BlockEntityTicker? { + if (p_153212_.isClientSide) + return null + + return BlockEntityTicker { _, _, _, tile -> if (tile is PoweredFurnaceBlockEntity) tile.tick() } + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/PoweredFurnaceScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/PoweredFurnaceScreen.kt new file mode 100644 index 000000000..2f124d235 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/PoweredFurnaceScreen.kt @@ -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(menu, inventory, title) { + override fun makeMainFrame(): FramePanel> { + 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 + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/config/AbstractConfig.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/config/AbstractConfig.kt index 399ffca68..3beed9f61 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/config/AbstractConfig.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/config/AbstractConfig.kt @@ -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 diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/config/BalanceValues.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/config/BalanceValues.kt new file mode 100644 index 000000000..5a7ed0fbc --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/config/BalanceValues.kt @@ -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 +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/config/BatteryBalanceValues.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/config/BatteryBalanceValues.kt deleted file mode 100644 index 5cb55730a..000000000 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/config/BatteryBalanceValues.kt +++ /dev/null @@ -1,7 +0,0 @@ -package ru.dbotthepony.mc.otm.config - -import ru.dbotthepony.mc.otm.core.math.Decimal - -interface BatteryBalanceValues : VerboseBalanceValues { - val initialBatteryLevel: Decimal -} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/config/ConciseBalanceValues.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/config/ConciseBalanceValues.kt deleted file mode 100644 index 06b3e90bd..000000000 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/config/ConciseBalanceValues.kt +++ /dev/null @@ -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 -} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/config/ItemsConfig.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/config/ItemsConfig.kt index 02864211c..2bc71c21a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/config/ItemsConfig.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/config/ItemsConfig.kt @@ -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") } 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 e04ef4afb..65bdf5a4c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/config/MachinesConfig.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/config/MachinesConfig.kt @@ -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") diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/config/VerboseBalanceValues.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/config/VerboseBalanceValues.kt deleted file mode 100644 index 9b50f3bc2..000000000 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/config/VerboseBalanceValues.kt +++ /dev/null @@ -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 -} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/ContainerProxy.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/CombinedContainer.kt similarity index 68% rename from src/main/kotlin/ru/dbotthepony/mc/otm/container/ContainerProxy.kt rename to src/main/kotlin/ru/dbotthepony/mc/otm/container/CombinedContainer.kt index b8cb0a3ed..c37b8e51a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/ContainerProxy.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/CombinedContainer.kt @@ -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>>) : Container { - data class ContainerSlot(val container: Container, val outerIndex: Int, val index: Int) : ReadWriteProperty, Supplier, Consumer { +class CombinedContainer(containers: Stream>>) : Container { + constructor(vararg containers: Container) : this(containers.stream().map { it to (0 until it.containerSize).iterator() }) + constructor(containers: Collection) : this(containers.stream().map { it to (0 until it.containerSize).iterator() }) + + class ContainerSlot(val container: Container, val containerIndex: Int) : GetterSetter { 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>>) : val isEmpty: Boolean get() = item.isEmpty } - protected val slots: List - protected val slotsMap: Map> - protected val containers: Set - protected val fullCoverage: List - protected val notFullCoverage: Map> + private val slots: List + private val slotsMap: Map> + private val containers: Set + private val fullCoverage: List + private val notFullCoverage: Map> init { val list = ImmutableList.Builder() var i = 0 - val validationMap = Reference2ObjectOpenHashMap() + val validationMap = Reference2ObjectOpenHashMap() val slotsMap = Reference2ObjectOpenHashMap>() 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>>) : } 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>>) : 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>>) : } } + 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>>) : 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 } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/Savetables.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/Savetables.kt index 1948ff68f..ba1e29b5f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/Savetables.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/Savetables.kt @@ -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 { return stateful(getter, name, T::class.java) } + inline fun , reified T : Tag> stateful(values: List, name: String): ImmutableList> { + return immutableList(values.size) { + stateful(values[it], "${name}_$it", T::class.java) + } + } + fun , T : Tag> stateful(getter: Supplier, name: String, type: Class): Stateful { return Stateful(getter, name, type) .withSerializer { it.serializeNBT() } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/Slots.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/Slots.kt index 74bda90bd..5ba1b1ccf 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/Slots.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/Slots.kt @@ -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 makeSlots(container: C, initializer: (C, Int) -> S): ImmutableList { return immutableList(container.containerSize) { initializer.invoke(container, it) } } +/** + * Make slots for list of containers with single slot in them + */ +inline fun makeSlots(containers: List?, size: Int, initializer: (Container, Int) -> S): ImmutableList { + 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 diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/PoweredFurnaceMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/PoweredFurnaceMenu.kt new file mode 100644 index 000000000..c728c159f --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/PoweredFurnaceMenu.kt @@ -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() + } +} 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 4dd4a8041..5a2dfde67 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockEntities.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockEntities.kt @@ -59,6 +59,10 @@ object MBlockEntities { val ANDROID_CHARGER_MIDDLE: BlockEntityType by registry.register(MNames.ANDROID_CHARGER + "_middle") { BlockEntityType.Builder.of(::AndroidChargerMiddleBlockEntity, MBlocks.ANDROID_CHARGER).build(null) } val ANDROID_CHARGER_TOP: BlockEntityType by registry.register(MNames.ANDROID_CHARGER + "_top") { BlockEntityType.Builder.of(::AndroidChargerTopBlockEntity, MBlocks.ANDROID_CHARGER).build(null) } + val POWERED_FURNACE: BlockEntityType 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 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 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 by registry.register(MNames.STORAGE_BUS) { BlockEntityType.Builder.of(::StorageBusBlockEntity, MBlocks.STORAGE_BUS).build(null) } val STORAGE_IMPORTER: BlockEntityType by registry.register(MNames.STORAGE_IMPORTER) { BlockEntityType.Builder.of(::StorageImporterBlockEntity, MBlocks.STORAGE_IMPORTER).build(null) } val STORAGE_EXPORTER: BlockEntityType by registry.register(MNames.STORAGE_EXPORTER) { BlockEntityType.Builder.of(::StorageExporterBlockEntity, MBlocks.STORAGE_EXPORTER).build(null) } 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 474441f83..813a504a3 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlocks.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlocks.kt @@ -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() } 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 0fcb51a37..3afedaf0e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItems.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItems.kt @@ -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, diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MMenus.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MMenus.kt index 113c4803a..185878fd5 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MMenus.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MMenus.kt @@ -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 by registry.register(MNames.ENERGY_COUNTER) { MenuType(::EnergyCounterMenu, FeatureFlags.VANILLA_SET) } val CHEMICAL_GENERATOR: MenuType by registry.register(MNames.CHEMICAL_GENERATOR) { MenuType(::ChemicalGeneratorMenu, FeatureFlags.VANILLA_SET) } val PLATE_PRESS: MenuType by registry.register(MNames.PLATE_PRESS) { MenuType(::PlatePressMenu, FeatureFlags.VANILLA_SET) } + val POWERED_FURNACE: MenuType by registry.register(MNames.POWERED_FURNACE) { MenuType(::PoweredFurnaceMenu, FeatureFlags.VANILLA_SET) } val TWIN_PLATE_PRESS: MenuType by registry.register(MNames.TWIN_PLATE_PRESS) { MenuType(::TwinPlatePressMenu, FeatureFlags.VANILLA_SET) } val MATTER_RECYCLER: MenuType by registry.register(MNames.MATTER_RECYCLER) { MenuType(::MatterRecyclerMenu, FeatureFlags.VANILLA_SET) } val ENERGY_SERVO: MenuType 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) } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MNames.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MNames.kt index 37d3e2ad3..2cf4382a0 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MNames.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MNames.kt @@ -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" 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 443936596..ad4caab70 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRegistry.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRegistry.kt @@ -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() ?: 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)