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)
|
return super.getStateForPlacement(context)?.setValue(IS_OPEN, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("OVERRIDE_DEPRECATION")
|
||||||
override fun hasAnalogOutputSignal(p_60457_: BlockState): Boolean {
|
override fun hasAnalogOutputSignal(p_60457_: BlockState): Boolean {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("OVERRIDE_DEPRECATION")
|
||||||
override fun getAnalogOutputSignal(p_60487_: BlockState, level: Level, p_60489_: BlockPos): Int {
|
override fun getAnalogOutputSignal(p_60487_: BlockState, level: Level, p_60489_: BlockPos): Int {
|
||||||
val tile = level.getBlockEntity(p_60489_) as? CargoCrateBlockEntity ?: return 0
|
val tile = level.getBlockEntity(p_60489_) as? CargoCrateBlockEntity ?: return 0
|
||||||
return AbstractContainerMenu.getRedstoneSignalFromContainer(tile.container)
|
return AbstractContainerMenu.getRedstoneSignalFromContainer(tile.container)
|
||||||
|
@ -1,28 +1,41 @@
|
|||||||
package ru.dbotthepony.mc.otm.block.entity
|
package ru.dbotthepony.mc.otm.block.entity
|
||||||
|
|
||||||
|
import net.minecraft.advancements.CriteriaTriggers
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.core.Direction
|
import net.minecraft.core.Direction
|
||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
|
import net.minecraft.nbt.LongTag
|
||||||
|
import net.minecraft.nbt.StringTag
|
||||||
import net.minecraft.network.chat.Component
|
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.sounds.SoundSource
|
||||||
import net.minecraft.world.Container
|
import net.minecraft.world.Container
|
||||||
|
import net.minecraft.world.Containers
|
||||||
import net.minecraft.world.entity.player.Inventory
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import net.minecraft.world.entity.player.Player
|
import net.minecraft.world.entity.player.Player
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu
|
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.Block
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import net.minecraft.world.level.gameevent.GameEvent
|
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.Capability
|
||||||
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||||
import net.minecraftforge.common.util.LazyOptional
|
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.CargoCrateBlock
|
||||||
import ru.dbotthepony.mc.otm.block.IDroppableContainer
|
import ru.dbotthepony.mc.otm.block.IDroppableContainer
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
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.menu.CargoCrateMenu
|
||||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
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
|
import ru.dbotthepony.mc.otm.registry.MSoundEvents
|
||||||
|
|
||||||
class CargoCrateBlockEntity(
|
class CargoCrateBlockEntity(
|
||||||
@ -31,7 +44,18 @@ class CargoCrateBlockEntity(
|
|||||||
) : MatteryBlockEntity(MBlockEntities.CARGO_CRATE, p_155229_, p_155230_), IDroppableContainer {
|
) : MatteryBlockEntity(MBlockEntities.CARGO_CRATE, p_155229_, p_155230_), IDroppableContainer {
|
||||||
val container = MatteryContainer(this::setChanged, CAPACITY)
|
val container = MatteryContainer(this::setChanged, CAPACITY)
|
||||||
private var interactingPlayers = 0
|
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
|
override val droppableContainer: Container
|
||||||
get() = container
|
get() = container
|
||||||
@ -72,20 +96,56 @@ class CargoCrateBlockEntity(
|
|||||||
return super.getCapability(cap, side)
|
return super.getCapability(cap, side)
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun saveAdditional(nbt: CompoundTag) {
|
override fun saveAdditional(nbt: CompoundTag) {
|
||||||
super.saveAdditional(nbt)
|
super.saveAdditional(nbt)
|
||||||
nbt[INVENTORY_KEY] = container.serializeNBT()
|
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) {
|
override fun load(nbt: CompoundTag) {
|
||||||
super.load(nbt)
|
super.load(nbt)
|
||||||
container.deserializeNBT(nbt[INVENTORY_KEY])
|
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
|
override val defaultDisplayName: Component
|
||||||
get() = MACHINE_NAME
|
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)
|
return CargoCrateMenu(containerID, inventory, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,8 +5,16 @@ import net.minecraftforge.common.util.LazyOptional
|
|||||||
import net.minecraftforge.items.IItemHandler
|
import net.minecraftforge.items.IItemHandler
|
||||||
|
|
||||||
interface MatteryContainerFilter {
|
interface MatteryContainerFilter {
|
||||||
fun canInsert(slot: Int, stack: ItemStack): Boolean
|
fun canInsert(slot: Int, stack: ItemStack): Boolean {
|
||||||
fun canExtract(slot: Int, amount: 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 {
|
object MatteryContainerFilterOnlyIn : MatteryContainerFilter {
|
||||||
@ -41,7 +49,7 @@ object MatteryContainerFilterBoth : MatteryContainerFilter {
|
|||||||
|
|
||||||
class MatteryContainerHandler @JvmOverloads internal constructor(
|
class MatteryContainerHandler @JvmOverloads internal constructor(
|
||||||
private val container: MatteryContainer,
|
private val container: MatteryContainer,
|
||||||
private val filter: MatteryContainerFilter = MatteryContainerFilterBoth,
|
private val hooks: MatteryContainerFilter = MatteryContainerFilterBoth,
|
||||||
) : IItemHandler {
|
) : IItemHandler {
|
||||||
private var handler = LazyOptional.of<IItemHandler> { this }
|
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 getStackInSlot(slot: Int) = container[slot]
|
||||||
|
|
||||||
override fun insertItem(slot: Int, stack: ItemStack, simulate: Boolean): ItemStack {
|
override fun insertItem(slot: Int, stack: ItemStack, simulate: Boolean): ItemStack {
|
||||||
if (!filter.canInsert(slot, stack))
|
if (!hooks.canInsert(slot, stack))
|
||||||
return stack
|
return stack
|
||||||
|
|
||||||
|
hooks.preInsert(slot, stack, simulate)
|
||||||
val localStack = container[slot]
|
val localStack = container[slot]
|
||||||
|
|
||||||
if (localStack.isEmpty) {
|
if (localStack.isEmpty) {
|
||||||
@ -100,9 +109,11 @@ class MatteryContainerHandler @JvmOverloads internal constructor(
|
|||||||
|
|
||||||
require(amount >= 0) { "Can not extract negative amount of items" }
|
require(amount >= 0) { "Can not extract negative amount of items" }
|
||||||
|
|
||||||
|
hooks.preExtract(slot, amount, simulate)
|
||||||
|
|
||||||
val localStack = container.getItem(slot)
|
val localStack = container.getItem(slot)
|
||||||
if (localStack.isEmpty) return ItemStack.EMPTY
|
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 minimal = Math.min(amount, localStack.count)
|
||||||
val copy = localStack.copy()
|
val copy = localStack.copy()
|
||||||
@ -122,6 +133,6 @@ class MatteryContainerHandler @JvmOverloads internal constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun isItemValid(slot: Int, stack: ItemStack): Boolean {
|
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