Create separate loot item function for saving tile nbt data
This commit is contained in:
parent
5b12be2ac4
commit
a9b28a66ca
@ -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())
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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<ItemHandlerMode>
|
||||
val inputOutput: IItemHandler?
|
||||
|
||||
init {
|
||||
val builder = ImmutableSet.Builder<ItemHandlerMode>()
|
||||
|
||||
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<IItemHandler>()
|
||||
|
||||
if (input != null) caps.add(input)
|
||||
@ -258,28 +277,6 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
|
||||
put(RelativeSide.BOTTOM, bottomDefault)
|
||||
}
|
||||
|
||||
val possibleViews: ImmutableSet<ItemHandlerMode>
|
||||
val inputOutput: IItemHandler?
|
||||
|
||||
init {
|
||||
val builder = ImmutableSet.Builder<ItemHandlerMode>()
|
||||
|
||||
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 {
|
||||
|
@ -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<out String> = Stream.empty()) : LootItemFunction, LootItemFunction.Builder {
|
||||
constructor(filter: Collection<String>) : this(filter.stream())
|
||||
constructor(vararg filter: String) : this(filter.stream())
|
||||
|
||||
val filter: ImmutableList<String> = /*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<CopyTileNbtFunction> {
|
||||
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())
|
||||
}
|
||||
}
|
||||
}
|
@ -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]!!
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user