Loot tables for cargo crates?
This commit is contained in:
parent
c0364736f4
commit
75ffae542d
@ -32,10 +32,12 @@ class CargoCrateBlock(val color: DyeColor?) : RotatableMatteryBlock(
|
||||
return super.getStateForPlacement(context)?.setValue(IS_OPEN, false)
|
||||
}
|
||||
|
||||
@Suppress("OVERRIDE_DEPRECATION")
|
||||
override fun hasAnalogOutputSignal(p_60457_: BlockState): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
@Suppress("OVERRIDE_DEPRECATION")
|
||||
override fun getAnalogOutputSignal(p_60487_: BlockState, level: Level, p_60489_: BlockPos): Int {
|
||||
val tile = level.getBlockEntity(p_60489_) as? CargoCrateBlockEntity ?: return 0
|
||||
return AbstractContainerMenu.getRedstoneSignalFromContainer(tile.container)
|
||||
|
@ -1,28 +1,41 @@
|
||||
package ru.dbotthepony.mc.otm.block.entity
|
||||
|
||||
import net.minecraft.advancements.CriteriaTriggers
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.nbt.LongTag
|
||||
import net.minecraft.nbt.StringTag
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.sounds.SoundSource
|
||||
import net.minecraft.world.Container
|
||||
import net.minecraft.world.Containers
|
||||
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.ItemStack
|
||||
import net.minecraft.world.level.block.Block
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.level.gameevent.GameEvent
|
||||
import net.minecraft.world.level.storage.loot.LootContext
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import net.minecraftforge.common.capabilities.Capability
|
||||
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||
import net.minecraftforge.common.util.LazyOptional
|
||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||
import ru.dbotthepony.mc.otm.block.CargoCrateBlock
|
||||
import ru.dbotthepony.mc.otm.block.IDroppableContainer
|
||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||
import ru.dbotthepony.mc.otm.container.MatteryContainerFilter
|
||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||
import ru.dbotthepony.mc.otm.core.map
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
import ru.dbotthepony.mc.otm.menu.CargoCrateMenu
|
||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||
import ru.dbotthepony.mc.otm.container.set
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
import ru.dbotthepony.mc.otm.registry.MSoundEvents
|
||||
|
||||
class CargoCrateBlockEntity(
|
||||
@ -31,7 +44,18 @@ class CargoCrateBlockEntity(
|
||||
) : MatteryBlockEntity(MBlockEntities.CARGO_CRATE, p_155229_, p_155230_), IDroppableContainer {
|
||||
val container = MatteryContainer(this::setChanged, CAPACITY)
|
||||
private var interactingPlayers = 0
|
||||
val handler = container.handler()
|
||||
val handler = container.handler(object : MatteryContainerFilter {
|
||||
override fun preInsert(slot: Int, stack: ItemStack, simulate: Boolean) {
|
||||
unpackLootTable()
|
||||
}
|
||||
|
||||
override fun preExtract(slot: Int, amount: Int, simulate: Boolean) {
|
||||
unpackLootTable()
|
||||
}
|
||||
})
|
||||
|
||||
var lootTable: ResourceLocation? = null
|
||||
var lootTableSeed: Long? = null
|
||||
|
||||
override val droppableContainer: Container
|
||||
get() = container
|
||||
@ -72,20 +96,56 @@ class CargoCrateBlockEntity(
|
||||
return super.getCapability(cap, side)
|
||||
}
|
||||
|
||||
public override fun saveAdditional(nbt: CompoundTag) {
|
||||
override fun saveAdditional(nbt: CompoundTag) {
|
||||
super.saveAdditional(nbt)
|
||||
nbt[INVENTORY_KEY] = container.serializeNBT()
|
||||
|
||||
lootTable?.let { nbt[LOOT_TABLE_KEY] = it.toString() }
|
||||
lootTableSeed?.let { nbt[LOOT_TABLE_SEED_KEY] = it }
|
||||
}
|
||||
|
||||
override fun load(nbt: CompoundTag) {
|
||||
super.load(nbt)
|
||||
container.deserializeNBT(nbt[INVENTORY_KEY])
|
||||
|
||||
lootTable = nbt.map(LOOT_TABLE_KEY) { it: StringTag -> ResourceLocation.tryParse(it.asString) }
|
||||
lootTableSeed = (nbt[LOOT_TABLE_SEED_KEY] as LongTag?)?.asLong
|
||||
}
|
||||
|
||||
fun unpackLootTable(ply: Player? = null) {
|
||||
val lootTable = lootTable ?: return
|
||||
val lootTableSeed = lootTableSeed ?: 0L
|
||||
val server = level?.server ?: return
|
||||
|
||||
val loot = server.lootTables.get(lootTable)
|
||||
|
||||
if (ply is ServerPlayer) {
|
||||
CriteriaTriggers.GENERATE_LOOT.trigger(ply, lootTable)
|
||||
}
|
||||
|
||||
this.lootTable = null
|
||||
this.lootTableSeed = null
|
||||
|
||||
val context = LootContext.Builder(level as ServerLevel)
|
||||
.withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(this.worldPosition))
|
||||
.withOptionalRandomSeed(lootTableSeed)
|
||||
|
||||
if (ply != null) {
|
||||
context.withLuck(ply.luck).withParameter(LootContextParams.THIS_ENTITY, ply)
|
||||
}
|
||||
|
||||
Containers.dropContents(level as ServerLevel, blockPos, container)
|
||||
loot.fill(container, context.create(LootContextParamSets.CHEST))
|
||||
}
|
||||
|
||||
override val defaultDisplayName: Component
|
||||
get() = MACHINE_NAME
|
||||
|
||||
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
|
||||
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu? {
|
||||
if (lootTable != null && ply.isSpectator)
|
||||
return null
|
||||
|
||||
unpackLootTable(ply)
|
||||
return CargoCrateMenu(containerID, inventory, this)
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,16 @@ import net.minecraftforge.common.util.LazyOptional
|
||||
import net.minecraftforge.items.IItemHandler
|
||||
|
||||
interface MatteryContainerFilter {
|
||||
fun canInsert(slot: Int, stack: ItemStack): Boolean
|
||||
fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean
|
||||
fun canInsert(slot: Int, stack: ItemStack): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
fun preInsert(slot: Int, stack: ItemStack, simulate: Boolean) {}
|
||||
fun preExtract(slot: Int, amount: Int, simulate: Boolean) {}
|
||||
}
|
||||
|
||||
object MatteryContainerFilterOnlyIn : MatteryContainerFilter {
|
||||
@ -41,7 +49,7 @@ object MatteryContainerFilterBoth : MatteryContainerFilter {
|
||||
|
||||
class MatteryContainerHandler @JvmOverloads internal constructor(
|
||||
private val container: MatteryContainer,
|
||||
private val filter: MatteryContainerFilter = MatteryContainerFilterBoth,
|
||||
private val hooks: MatteryContainerFilter = MatteryContainerFilterBoth,
|
||||
) : IItemHandler {
|
||||
private var handler = LazyOptional.of<IItemHandler> { this }
|
||||
|
||||
@ -61,9 +69,10 @@ class MatteryContainerHandler @JvmOverloads internal constructor(
|
||||
override fun getStackInSlot(slot: Int) = container[slot]
|
||||
|
||||
override fun insertItem(slot: Int, stack: ItemStack, simulate: Boolean): ItemStack {
|
||||
if (!filter.canInsert(slot, stack))
|
||||
if (!hooks.canInsert(slot, stack))
|
||||
return stack
|
||||
|
||||
hooks.preInsert(slot, stack, simulate)
|
||||
val localStack = container[slot]
|
||||
|
||||
if (localStack.isEmpty) {
|
||||
@ -100,9 +109,11 @@ class MatteryContainerHandler @JvmOverloads internal constructor(
|
||||
|
||||
require(amount >= 0) { "Can not extract negative amount of items" }
|
||||
|
||||
hooks.preExtract(slot, amount, simulate)
|
||||
|
||||
val localStack = container.getItem(slot)
|
||||
if (localStack.isEmpty) return ItemStack.EMPTY
|
||||
if (!filter.canExtract(slot, amount, localStack)) return ItemStack.EMPTY
|
||||
if (!hooks.canExtract(slot, amount, localStack)) return ItemStack.EMPTY
|
||||
|
||||
val minimal = Math.min(amount, localStack.count)
|
||||
val copy = localStack.copy()
|
||||
@ -122,6 +133,6 @@ class MatteryContainerHandler @JvmOverloads internal constructor(
|
||||
}
|
||||
|
||||
override fun isItemValid(slot: Int, stack: ItemStack): Boolean {
|
||||
return filter.canInsert(slot, stack)
|
||||
return hooks.canInsert(slot, stack)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user