diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootTables.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootTables.kt index 2deda7074..a69526acc 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootTables.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootTables.kt @@ -24,11 +24,11 @@ import net.minecraft.world.level.storage.loot.functions.SetItemCountFunction import net.minecraft.world.level.storage.loot.parameters.LootContextParamSet import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets import net.minecraft.world.level.storage.loot.predicates.LootItemBlockStatePropertyCondition -import net.minecraft.world.level.storage.loot.providers.nbt.ContextNbtProvider import net.minecraft.world.level.storage.loot.providers.number.ConstantValue import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity -import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity +import ru.dbotthepony.mc.otm.core.stream +import ru.dbotthepony.mc.otm.data.loot.CopyTileNbtFunction data class NbtCopy(val source: String, val destination: String, val strategy: CopyNbtFunction.MergeStrategy = CopyNbtFunction.MergeStrategy.REPLACE) @@ -155,91 +155,11 @@ class LootTables(generator: DataGenerator) : LootTableProvider(generator.packOut } } - fun tile(block: Block, f: (CopyNbtFunction.Builder) -> Unit = {}) { + fun tile(block: Block, vararg filterTags: String) { singleLootPool(LootContextParamSets.BLOCK, block.lootTable) { add(LootItem.lootTableItem(block).also { - it.apply(CopyNbtFunction.copyData(ContextNbtProvider.BLOCK_ENTITY).also { - it.copy("Name", "BlockEntityTag.Name") - f(it) - }) + it.apply(CopyTileNbtFunction(filterTags.stream())) }) } } - - fun tile(block: Block, vararg tags: NbtCopy) { - tile(block) { - for ((source, destination, strategy) in tags) { - it.copy(source, destination, strategy) - } - } - } - - fun basicTile(block: Block, vararg tags: NbtCopy) { - tile(block) { - for ((source, destination, strategy) in tags) { - it.copy(source, destination, strategy) - } - - for ((source, destination, strategy) in basicTags) { - it.copy(source, destination, strategy) - } - } - } - - fun poweredTile(block: Block, vararg tags: NbtCopy) { - tile(block) { - for ((source, destination, strategy) in tags) { - it.copy(source, destination, strategy) - } - - for ((source, destination, strategy) in poweredTags) { - it.copy(source, destination, strategy) - } - } - } - - fun workerTile(block: Block, vararg tags: NbtCopy) { - tile(block) { - for ((source, destination, strategy) in tags) { - it.copy(source, destination, strategy) - } - - for ((source, destination, strategy) in workerTags) { - it.copy(source, destination, strategy) - } - } - } - - fun matterWorkerTile(block: Block, vararg tags: NbtCopy) { - tile(block) { - for ((source, destination, strategy) in tags) { - it.copy(source, destination, strategy) - } - - for ((source, destination, strategy) in poweredMatterWorker) { - it.copy(source, destination, strategy) - } - } - } - - fun tile(block: Block, vararg tags: String) { - tile(block, *tags.map { NbtCopy(it, "BlockEntityTag.$it", CopyNbtFunction.MergeStrategy.REPLACE) }.toTypedArray()) - } - - // fix overload resolution by adding extra required argument - fun basicTile(block: Block, f: String, vararg tags: String) { - basicTile(block, *tags.map { TileNbtCopy(it) }.toMutableList().also { it.add(TileNbtCopy(f)) }.toTypedArray()) - } - - fun poweredTile(block: Block, f: String, vararg tags: String) { - poweredTile(block, *tags.map { TileNbtCopy(it) }.toMutableList().also { it.add(TileNbtCopy(f)) }.toTypedArray()) - } - - fun workerTile(block: Block, f: String, vararg tags: String) { - workerTile(block, *tags.map { TileNbtCopy(it) }.toMutableList().also { it.add(TileNbtCopy(f)) }.toTypedArray()) - } - - fun matterWorkerTile(block: Block, f: String, vararg tags: String) { - matterWorkerTile(block, *tags.map { TileNbtCopy(it) }.toMutableList().also { it.add(TileNbtCopy(f)) }.toTypedArray()) - } } 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 a6321136b..f6427365e 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 @@ -58,8 +58,6 @@ fun addLootTables(lootTables: LootTables) { lootTables.dropsSelf(MBlocks.METAL_BEAM) { condition(ExplosionCondition.survivesExplosion()) } lootTables.dropsSelf(MBlocks.TRITANIUM_INGOT_BLOCK) { condition(ExplosionCondition.survivesExplosion()) } - lootTables.tile(MBlocks.COBBLESTONE_GENERATOR) - lootTables.dropsSelf(MBlocks.ENGINE) { condition(ExplosionCondition.survivesExplosion()) } for (door in MBlocks.TRITANIUM_TRAPDOOR.values) @@ -133,41 +131,31 @@ fun addLootTables(lootTables: LootTables) { lootPool { item(Items.BLACK_DYE) { setCount(64) } } } + lootTables.tile(MBlocks.COBBLESTONE_GENERATOR) + lootTables.tile(MBlocks.ENERGY_SERVO) + lootTables.tile(MBlocks.ENERGY_COUNTER) + lootTables.tile(MBlocks.CHEMICAL_GENERATOR) + lootTables.tile(MBlocks.HOLO_SIGN) + lootTables.tile(MBlocks.STORAGE_CABLE) + lootTables.tile(MBlocks.ANDROID_STATION) + lootTables.tile(MBlocks.BATTERY_BANK) + lootTables.tile(MBlocks.DRIVE_VIEWER) - lootTables.tile(MBlocks.ENERGY_COUNTER, - EnergyCounterBlockEntity.IO_LIMIT_KEY, EnergyCounterBlockEntity.PASSED_ENERGY_KEY, - EnergyCounterBlockEntity.POWER_HISTORY_KEY, EnergyCounterBlockEntity.POWER_HISTORY_POINTER_KEY) + lootTables.tile(MBlocks.STORAGE_BUS) + lootTables.tile(MBlocks.STORAGE_IMPORTER) + lootTables.tile(MBlocks.STORAGE_EXPORTER) + lootTables.tile(MBlocks.STORAGE_POWER_SUPPLIER) + lootTables.tile(MBlocks.DRIVE_RACK) - lootTables.tile(MBlocks.CHEMICAL_GENERATOR, - ChemicalGeneratorBlockEntity.WORK_TICKS_KEY, - ChemicalGeneratorBlockEntity.WORK_TICKS_TOTAL_KEY, - ENERGY_KEY, - REDSTONE_CONTROL_KEY, - ) + lootTables.tile(MBlocks.MATTER_DECOMPOSER) + lootTables.tile(MBlocks.MATTER_REPLICATOR) + lootTables.tile(MBlocks.MATTER_RECYCLER) + lootTables.tile(MBlocks.MATTER_SCANNER) + lootTables.tile(MBlocks.PLATE_PRESS) - lootTables.tile(MBlocks.HOLO_SIGN, HoloSignBlockEntity.TEXT_KEY, HoloSignBlockEntity.REDSTONE_CONTROL_KEY) - - lootTables.dropsSelf(MBlocks.STORAGE_CABLE) - lootTables.poweredTile(MBlocks.ANDROID_STATION) - lootTables.basicTile(MBlocks.BATTERY_BANK) - lootTables.poweredTile(MBlocks.DRIVE_VIEWER) - - lootTables.poweredTile(MBlocks.STORAGE_BUS, TileNbtCopy(FILTER_KEY)) - lootTables.poweredTile(MBlocks.STORAGE_IMPORTER, TileNbtCopy(FILTER_KEY)) - lootTables.poweredTile(MBlocks.STORAGE_EXPORTER, TileNbtCopy(FILTER_KEY)) - lootTables.poweredTile(MBlocks.STORAGE_POWER_SUPPLIER, TileNbtCopy(StoragePowerSupplierBlockEntity.POWER_PASSED_KEY)) - lootTables.poweredTile(MBlocks.DRIVE_RACK) - - lootTables.matterWorkerTile(MBlocks.MATTER_DECOMPOSER) - lootTables.matterWorkerTile(MBlocks.MATTER_REPLICATOR) - lootTables.matterWorkerTile(MBlocks.MATTER_RECYCLER) - lootTables.workerTile(MBlocks.MATTER_SCANNER) - lootTables.workerTile(MBlocks.PLATE_PRESS) - - lootTables.basicTile(MBlocks.MATTER_PANEL, TileNbtCopy("tasks")) - lootTables.basicTile(MBlocks.PATTERN_STORAGE) - lootTables.basicTile(MBlocks.MATTER_CAPACITOR_BANK) - lootTables.poweredTile(MBlocks.MATTER_BOTTLER, - TileNbtCopy(MATTER_STORAGE_KEY), TileNbtCopy(MatterBottlerBlockEntity.IS_BOTTLING_KEY)) + lootTables.tile(MBlocks.MATTER_PANEL) + lootTables.tile(MBlocks.PATTERN_STORAGE) + lootTables.tile(MBlocks.MATTER_CAPACITOR_BANK) + lootTables.tile(MBlocks.MATTER_BOTTLER) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/MatteryBlock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/MatteryBlock.kt index 143fc75aa..f0da2a116 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/MatteryBlock.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/MatteryBlock.kt @@ -192,7 +192,7 @@ abstract class MatteryBlock @JvmOverloads constructor( newBlockState: BlockState, movedByPiston: Boolean ) { - if (!oldBlockState.`is`(newBlockState.block)) { + if (!oldBlockState.`is`(newBlockState.block) && !level.isClientSide) { val blockentity = level.getBlockEntity(blockPos) if (blockentity is MatteryBlockEntity) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryDeviceBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryDeviceBlockEntity.kt index be38c2d74..9eef5abfc 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryDeviceBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryDeviceBlockEntity.kt @@ -221,8 +221,27 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo val bottomDefault: ItemHandlerMode = determineDefaultMode(input, output, battery, RelativeSide.BOTTOM), ) { val sideless: IItemHandler + val possibleViews: ImmutableSet + val inputOutput: IItemHandler? init { + val builder = ImmutableSet.Builder() + + builder.add(ItemHandlerMode.DISABLED) + + if (input != null) builder.add(ItemHandlerMode.INPUT) + if (output != null) builder.add(ItemHandlerMode.OUTPUT) + if (input != null && output != null) builder.add(ItemHandlerMode.INPUT_OUTPUT) + if (battery != null) builder.add(ItemHandlerMode.BATTERY) + + possibleViews = builder.build() + + if (input != null && output != null) { + inputOutput = CombinedItemHandler(input, output) + } else { + inputOutput = null + } + val caps = ArrayList() if (input != null) caps.add(input) @@ -258,28 +277,6 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo put(RelativeSide.BOTTOM, bottomDefault) } - val possibleViews: ImmutableSet - val inputOutput: IItemHandler? - - init { - val builder = ImmutableSet.Builder() - - builder.add(ItemHandlerMode.DISABLED) - - if (input != null) builder.add(ItemHandlerMode.INPUT) - if (output != null) builder.add(ItemHandlerMode.OUTPUT) - if (input != null && output != null) builder.add(ItemHandlerMode.INPUT_OUTPUT) - if (battery != null) builder.add(ItemHandlerMode.BATTERY) - - possibleViews = builder.build() - - if (input != null && output != null) { - inputOutput = CombinedItemHandler(input, output) - } else { - inputOutput = null - } - } - inner class Piece( val side: RelativeSide, ) : IItemHandler, ITickable { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/data/loot/CopyTileNbtFunction.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/data/loot/CopyTileNbtFunction.kt new file mode 100644 index 000000000..c1958d418 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/data/loot/CopyTileNbtFunction.kt @@ -0,0 +1,77 @@ +package ru.dbotthepony.mc.otm.data.loot + +import com.google.common.collect.ImmutableList +import com.google.gson.JsonArray +import com.google.gson.JsonDeserializationContext +import com.google.gson.JsonObject +import com.google.gson.JsonPrimitive +import com.google.gson.JsonSerializationContext +import net.minecraft.nbt.CompoundTag +import net.minecraft.world.item.ItemStack +import net.minecraft.world.level.storage.loot.LootContext +import net.minecraft.world.level.storage.loot.Serializer +import net.minecraft.world.level.storage.loot.functions.LootItemFunction +import net.minecraft.world.level.storage.loot.functions.LootItemFunctionType +import net.minecraft.world.level.storage.loot.parameters.LootContextParams +import ru.dbotthepony.mc.otm.core.nbt.set +import ru.dbotthepony.mc.otm.core.set +import ru.dbotthepony.mc.otm.core.stream +import ru.dbotthepony.mc.otm.core.tagNotNull +import ru.dbotthepony.mc.otm.data.stream +import ru.dbotthepony.mc.otm.registry.MItemFunctionTypes +import java.util.stream.Stream + +class CopyTileNbtFunction(filter: Stream = Stream.empty()) : LootItemFunction, LootItemFunction.Builder { + constructor(filter: Collection) : this(filter.stream()) + constructor(vararg filter: String) : this(filter.stream()) + + val filter: ImmutableList = /*immutableList { + filter.forEach(this) + }*/ filter.collect(ImmutableList.toImmutableList()) + + override fun apply(t: ItemStack, u: LootContext): ItemStack { + val blockEntity = u.getParamOrNull(LootContextParams.BLOCK_ENTITY) ?: return t + val result = t.tagNotNull["BlockEntityTag"] as? CompoundTag + + val data = blockEntity.saveWithoutMetadata() + + for (k in filter) { + data.remove(k) + } + + if (result == null) { + t.tagNotNull["BlockEntityTag"] = data + } else { + for (k in data.allKeys) { + result[k] = data[k]!! + } + } + + return t + } + + override fun getType(): LootItemFunctionType { + return MItemFunctionTypes.COPY_TILE_NBT + } + + override fun build(): LootItemFunction { + return this + } + + companion object : Serializer { + override fun serialize( + pJson: JsonObject, + pValue: CopyTileNbtFunction, + pSerializationContext: JsonSerializationContext + ) { + pJson["filter"] = JsonArray().also { for (v in pValue.filter) it.add(v) } + } + + override fun deserialize( + pJson: JsonObject, + pSerializationContext: JsonDeserializationContext + ): CopyTileNbtFunction { + return CopyTileNbtFunction((pJson["filter"] as? JsonArray)?.stream()?.filter { it is JsonPrimitive }?.map { it.asString!! } ?: Stream.empty()) + } + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/input/ItemHandlerPlayerInput.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/input/ItemHandlerPlayerInput.kt index f28c3fc29..c565c407e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/input/ItemHandlerPlayerInput.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/input/ItemHandlerPlayerInput.kt @@ -9,10 +9,11 @@ import ru.dbotthepony.mc.otm.menu.MatteryMenu * [allowPull] and [allowPush] controls whenever player is allowed to change these options */ class ItemHandlerPlayerInput(val menu: MatteryMenu, val allowPull: Boolean = false, val allowPush: Boolean = false) { - inner class Piece(val side: RelativeSide) { - private val allowedFlags = MatteryDeviceBlockEntity.ItemHandlerMode.values().map { menu.mSynchronizer.bool() to it } + private val allowedFlags = MatteryDeviceBlockEntity.ItemHandlerMode.values().map { menu.mSynchronizer.bool() to it } + fun isAllowed(value: MatteryDeviceBlockEntity.ItemHandlerMode) = allowedFlags[value.ordinal].first.value - fun isAllowed(value: MatteryDeviceBlockEntity.ItemHandlerMode) = allowedFlags[value.ordinal].first.value + inner class Piece(val side: RelativeSide) { + fun isAllowed(value: MatteryDeviceBlockEntity.ItemHandlerMode) = this@ItemHandlerPlayerInput.isAllowed(value) val pull = BooleanInputWithFeedback(menu) val push = BooleanInputWithFeedback(menu) @@ -26,13 +27,9 @@ class ItemHandlerPlayerInput(val menu: MatteryMenu, val allowPull: Boolean = fal } fun configure(config: MatteryDeviceBlockEntity.ConfigurableItemHandler.Piece) { - for ((f, v) in allowedFlags) { - f.value = v in config.possibleViews - } - pull.with(config::automatePull) push.with(config::automatePush) - input.withSupplier { config.mode }.withConsumer { if (it in config.possibleViews) config.mode = it } + input.withSupplier { config.mode }.withConsumer { if (isAllowed(it)) config.mode = it } } } @@ -50,6 +47,10 @@ class ItemHandlerPlayerInput(val menu: MatteryMenu, val allowPull: Boolean = fal } fun configure(config: MatteryDeviceBlockEntity.ConfigurableItemHandler) { + for ((f, v) in allowedFlags) { + f.value = v in config.possibleViews + } + for ((side, v) in config.pieces) { pieces[side]!!.configure(v) pieces[side]!!.default = config.defaults[side]!! diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItemFunctionTypes.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItemFunctionTypes.kt index c19180a93..2e5645ad5 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItemFunctionTypes.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItemFunctionTypes.kt @@ -6,12 +6,14 @@ import net.minecraft.world.level.storage.loot.functions.LootItemFunctionType import net.minecraftforge.eventbus.api.IEventBus import net.minecraftforge.registries.DeferredRegister import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.data.loot.CopyTileNbtFunction import ru.dbotthepony.mc.otm.data.loot.RandomizerFunction object MItemFunctionTypes { private val registry = DeferredRegister.create(Registries.LOOT_FUNCTION_TYPE, OverdriveThatMatters.MOD_ID) val RANDOMIZER: LootItemFunctionType by registry.register("randomizer") { LootItemFunctionType(RandomizerFunction.Companion) } + val COPY_TILE_NBT: LootItemFunctionType by registry.register("copy_tile_nbt") { LootItemFunctionType(CopyTileNbtFunction.Companion) } internal fun register(bus: IEventBus) { registry.register(bus)