"Quick stack to nearby chests" prototype
This commit is contained in:
parent
091ffc8c9f
commit
d6f53946d9
@ -15,7 +15,6 @@ import ru.dbotthepony.mc.otm.capability.matter.IReplicationTaskProvider;
|
||||
import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage;
|
||||
import ru.dbotthepony.mc.otm.graph.matter.MatterNode;
|
||||
import ru.dbotthepony.mc.otm.graph.storage.StorageNode;
|
||||
import ru.dbotthepony.mc.otm.storage.StorageStack;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
@ -70,4 +69,8 @@ public class MatteryCapability {
|
||||
@Nonnull
|
||||
@NotNull
|
||||
public static final ItemCapability<IMatteryUpgrade, Void> UPGRADE = ItemCapability.createVoid(ResourceLocation.fromNamespaceAndPath(OverdriveThatMatters.MOD_ID, "machine_upgrade"), IMatteryUpgrade.class);
|
||||
|
||||
@Nonnull
|
||||
@NotNull
|
||||
public static final BlockCapability<IQuickStackContainer, Void> QUICK_STACK_CONTAINER = BlockCapability.createVoid(ResourceLocation.fromNamespaceAndPath(OverdriveThatMatters.MOD_ID, "quick_stack_container"), IQuickStackContainer.class);
|
||||
}
|
||||
|
@ -29,11 +29,15 @@ import net.minecraft.world.phys.Vec3
|
||||
import net.neoforged.neoforge.capabilities.Capabilities
|
||||
import ru.dbotthepony.mc.otm.block.decorative.CargoCrateBlock
|
||||
import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity
|
||||
import ru.dbotthepony.mc.otm.capability.IQuickStackContainer
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||
import ru.dbotthepony.mc.otm.container.slotted.FilteredContainerSlot
|
||||
import ru.dbotthepony.mc.otm.container.slotted.SlottedContainer
|
||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||
import ru.dbotthepony.mc.otm.core.otmRandom
|
||||
import ru.dbotthepony.mc.otm.menu.MatteryMenuSlot
|
||||
import ru.dbotthepony.mc.otm.menu.decorative.CargoCrateMenu
|
||||
import ru.dbotthepony.mc.otm.menu.makeSlots
|
||||
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
|
||||
import ru.dbotthepony.mc.otm.registry.game.MSoundEvents
|
||||
|
||||
@ -57,6 +61,10 @@ class CargoCrateBlockEntity(
|
||||
.build()
|
||||
.also(::addDroppableContainer)
|
||||
|
||||
init {
|
||||
exposeSideless(MatteryCapability.QUICK_STACK_CONTAINER, IQuickStackContainer.Simple(makeSlots(container, ::MatteryMenuSlot)))
|
||||
}
|
||||
|
||||
private var interactingPlayers = 0
|
||||
|
||||
override fun beforeDroppingItems(oldBlockState: BlockState, level: Level, blockPos: BlockPos, newBlockState: BlockState, movedByPiston: Boolean) {
|
||||
|
@ -0,0 +1,14 @@
|
||||
package ru.dbotthepony.mc.otm.capability
|
||||
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.inventory.Slot
|
||||
|
||||
interface IQuickStackContainer {
|
||||
fun getSlotsFor(player: ServerPlayer): Collection<Slot>
|
||||
|
||||
class Simple(private val slots: Collection<Slot>) : IQuickStackContainer {
|
||||
override fun getSlotsFor(player: ServerPlayer): Collection<Slot> {
|
||||
return slots
|
||||
}
|
||||
}
|
||||
}
|
@ -25,8 +25,11 @@ import ru.dbotthepony.mc.otm.client.setMousePos
|
||||
import ru.dbotthepony.mc.otm.client.shouldOpenVanillaInventory
|
||||
import ru.dbotthepony.mc.otm.core.math.integerDivisionDown
|
||||
import ru.dbotthepony.mc.otm.menu.ExopackInventoryMenu
|
||||
import ru.dbotthepony.mc.otm.menu.QuickMoveInput
|
||||
import ru.dbotthepony.mc.otm.network.ExopackMenuOpen
|
||||
import ru.dbotthepony.mc.otm.network.QuickStackPacket
|
||||
import yalter.mousetweaks.api.MouseTweaksDisableWheelTweak
|
||||
import java.util.function.IntConsumer
|
||||
|
||||
@MouseTweaksDisableWheelTweak
|
||||
class ExopackInventoryScreen(menu: ExopackInventoryMenu) : MatteryScreen<ExopackInventoryMenu>(menu, TranslatableComponent("otm.gui.exopack")) {
|
||||
@ -283,6 +286,17 @@ class ExopackInventoryScreen(menu: ExopackInventoryMenu) : MatteryScreen<Exopack
|
||||
|
||||
EffectListPanel(this, frame, menu.player, x - 56f, gridHeight = 6).tick()
|
||||
|
||||
val leftControls = DeviceControls(this, frame)
|
||||
leftControls.dockOnLeft = true
|
||||
leftControls.dockTop = 96f
|
||||
|
||||
leftControls.addButton(ButtonPanel.square18(
|
||||
this, leftControls,
|
||||
icon = Widgets18.RESTOCK_WITH_MOVE_TO_STORAGE,
|
||||
onPress = IntConsumer { PacketDistributor.sendToServer(QuickStackPacket(QuickMoveInput.Mode.RESTOCK_WITH_MOVE, true)) }).also {
|
||||
it.tooltips.add(QuickMoveInput.Mode.RESTOCK_WITH_MOVE.textToStorage)
|
||||
})
|
||||
|
||||
return frame
|
||||
}
|
||||
|
||||
|
@ -457,14 +457,13 @@ class DeviceControls<out S : MatteryScreen<*>>(
|
||||
return result
|
||||
}
|
||||
|
||||
private abstract inner class FoldableButtonPanel() : ButtonPanel<S>(screen, this@DeviceControls, width = 18f, height = 18f) {
|
||||
abstract inner class FoldableButtonPanel() : ButtonPanel<S>(screen, this@DeviceControls, width = 18f, height = 18f) {
|
||||
init {
|
||||
addButton(this)
|
||||
}
|
||||
|
||||
private var buttons: List<EditablePanel<S>>? = null
|
||||
|
||||
|
||||
fun makeButtons() {
|
||||
if (buttons == null) {
|
||||
buttons = doMakeButtons().also {
|
||||
|
@ -1,11 +1,24 @@
|
||||
package ru.dbotthepony.mc.otm.compat.vanilla
|
||||
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.world.Container
|
||||
import net.minecraft.world.flag.FeatureFlags
|
||||
import net.minecraft.world.inventory.MenuType
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.block.Blocks
|
||||
import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import net.minecraft.world.level.block.entity.ChestBlockEntity
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.neoforged.bus.api.IEventBus
|
||||
import net.neoforged.neoforge.capabilities.IBlockCapabilityProvider
|
||||
import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent
|
||||
import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent
|
||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||
import ru.dbotthepony.mc.otm.capability.IQuickStackContainer
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||
import ru.dbotthepony.mc.otm.menu.MatteryMenuSlot
|
||||
import ru.dbotthepony.mc.otm.menu.makeSlots
|
||||
import ru.dbotthepony.mc.otm.registry.MDeferredRegister
|
||||
|
||||
object VanillaMenuTypes {
|
||||
@ -22,9 +35,26 @@ object VanillaMenuTypes {
|
||||
|
||||
val SHULKER_BOX by registrar.register("shulker_box") { MenuType(::MatteryShulkerBoxMenu, FeatureFlags.VANILLA_SET) }
|
||||
|
||||
private fun provider(level: Level, pos: BlockPos, state: BlockState, blockEntity: BlockEntity?, context: Void?): IQuickStackContainer? {
|
||||
val container = blockEntity as? Container ?: return null
|
||||
return IQuickStackContainer.Simple(makeSlots(container, ::MatteryMenuSlot))
|
||||
}
|
||||
|
||||
fun registerCapabilities(event: RegisterCapabilitiesEvent) {
|
||||
event.registerBlock(
|
||||
MatteryCapability.QUICK_STACK_CONTAINER,
|
||||
::provider,
|
||||
Blocks.CHEST,
|
||||
Blocks.TRAPPED_CHEST,
|
||||
Blocks.SHULKER_BOX,
|
||||
Blocks.BARREL,
|
||||
)
|
||||
}
|
||||
|
||||
internal fun register(bus: IEventBus) {
|
||||
registrar.register(bus)
|
||||
bus.addListener(this::registerScreens)
|
||||
bus.addListener(this::registerCapabilities)
|
||||
}
|
||||
|
||||
private fun registerScreens(event: RegisterMenuScreensEvent) {
|
||||
|
@ -72,6 +72,7 @@ import java.util.random.RandomGenerator
|
||||
import java.util.stream.Stream
|
||||
import java.util.stream.StreamSupport
|
||||
import kotlin.NoSuchElementException
|
||||
import kotlin.enums.EnumEntries
|
||||
import kotlin.jvm.optionals.getOrNull
|
||||
import kotlin.math.ln
|
||||
import kotlin.math.sqrt
|
||||
@ -301,6 +302,10 @@ fun OutputStream.writeItemType(value: Item) {
|
||||
writeVarIntLE(BuiltInRegistries.ITEM.getId(value))
|
||||
}
|
||||
|
||||
fun <E : Enum<E>> FriendlyByteBuf.readEnum(entries: EnumEntries<E>): E {
|
||||
return entries[readVarInt()]
|
||||
}
|
||||
|
||||
fun <T : Any> FriendlyByteBuf.readType(registry: IdMap<T>): T {
|
||||
val id = readInt()
|
||||
return registry.byId(id) ?: throw NoSuchElementException("No such entry with ID $id")
|
||||
|
@ -435,6 +435,14 @@ operator fun Vec3i.times(int: Int): Vec3i = this.multiply(int)
|
||||
operator fun Direction.times(int: Int): Vec3i = this.normal.multiply(int)
|
||||
operator fun Vec3i.times(double: Double): Vector = Vector(x * double, y * double, z * double)
|
||||
|
||||
operator fun Vector.plus(direction: Vec3i): Vector = Vector(x + direction.x, y + direction.y, z + direction.z)
|
||||
operator fun Vector.plus(direction: Direction): Vector = plus(direction.normal)
|
||||
operator fun Vector.minus(direction: Vec3i): Vector = Vector(x - direction.x, y - direction.y, z - direction.z)
|
||||
operator fun Vector.minus(direction: Direction): Vector = minus(direction.normal)
|
||||
|
||||
operator fun Vec3i.plus(direction: Vector): Vector = Vector(x + direction.x, y + direction.y, z + direction.z)
|
||||
operator fun Vec3i.minus(direction: Vector): Vector = Vector(x - direction.x, y - direction.y, z - direction.z)
|
||||
|
||||
fun Vec3.toIntVector() = Vec3i(x.toInt(), y.toInt(), z.toInt())
|
||||
fun Vec3.roundToIntVector() = Vec3i(x.roundToInt(), y.roundToInt(), z.roundToInt())
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
package ru.dbotthepony.mc.otm.entity
|
||||
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.network.syncher.EntityDataAccessor
|
||||
import net.minecraft.network.syncher.SynchedEntityData
|
||||
import net.minecraft.world.entity.Entity
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import kotlin.properties.ReadWriteProperty
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
@ -17,3 +19,7 @@ class SynchedEntityDataDelegate<T>(private val type: EntityDataAccessor<T>, priv
|
||||
}
|
||||
|
||||
fun <T> SynchedEntityData.delegate(type: EntityDataAccessor<T>) = SynchedEntityDataDelegate(type, this)
|
||||
|
||||
fun Player.checkCanInteract(pos: BlockPos): Boolean {
|
||||
return mayInteract(level(), pos) && canInteractWithBlock(pos, 1.0)
|
||||
}
|
||||
|
@ -42,6 +42,7 @@ import ru.dbotthepony.mc.otm.container.util.containerSlotOrNull
|
||||
import ru.dbotthepony.mc.otm.core.ResourceLocation
|
||||
import ru.dbotthepony.mc.otm.core.collect.ConditionalSet
|
||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||
import ru.dbotthepony.mc.otm.entity.checkCanInteract
|
||||
import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback
|
||||
import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget
|
||||
import ru.dbotthepony.mc.otm.network.MatteryStreamCodec
|
||||
@ -346,13 +347,10 @@ abstract class MatteryMenu(
|
||||
override fun stillValid(player: Player): Boolean {
|
||||
if (tile == null) return true
|
||||
|
||||
if (player.level().getBlockEntity(tile.blockPos) !== tile) {
|
||||
if (player.level().getBlockEntity(tile.blockPos) !== tile)
|
||||
return false
|
||||
}
|
||||
|
||||
val pos = tile.blockPos
|
||||
|
||||
return player.distanceToSqr(pos.x.toDouble() + 0.5, pos.y.toDouble() + 0.5, pos.z.toDouble() + 0.5) <= 64.0
|
||||
return player.checkCanInteract(tile.blockPos)
|
||||
}
|
||||
|
||||
fun syncCarried() {
|
||||
|
@ -1,6 +1,7 @@
|
||||
package ru.dbotthepony.mc.otm.network
|
||||
|
||||
import it.unimi.dsi.fastutil.bytes.ByteArrayList
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.particles.ParticleTypes
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
@ -8,28 +9,47 @@ import net.minecraft.network.codec.StreamCodec
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload
|
||||
import net.minecraft.network.protocol.game.ClientboundSetCarriedItemPacket
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.entity.ai.attributes.Attributes
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.inventory.Slot
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.level.ChunkPos
|
||||
import net.minecraft.world.level.ClipBlockStateContext
|
||||
import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import net.neoforged.neoforge.common.NeoForgeMod
|
||||
import net.neoforged.neoforge.network.handling.IPayloadContext
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import ru.dbotthepony.kommons.math.RGBAColor
|
||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||
import ru.dbotthepony.mc.otm.capability.IQuickStackContainer
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||
import ru.dbotthepony.mc.otm.player.MatteryPlayer
|
||||
import ru.dbotthepony.mc.otm.player.matteryPlayer
|
||||
import ru.dbotthepony.mc.otm.client.minecraft
|
||||
import ru.dbotthepony.mc.otm.container.get
|
||||
import ru.dbotthepony.mc.otm.container.set
|
||||
import ru.dbotthepony.mc.otm.core.ResourceLocation
|
||||
import ru.dbotthepony.mc.otm.core.getChunkNow
|
||||
import ru.dbotthepony.mc.otm.core.math.Vector
|
||||
import ru.dbotthepony.mc.otm.core.math.component1
|
||||
import ru.dbotthepony.mc.otm.core.math.component2
|
||||
import ru.dbotthepony.mc.otm.core.math.component3
|
||||
import ru.dbotthepony.mc.otm.core.math.minus
|
||||
import ru.dbotthepony.mc.otm.core.math.plus
|
||||
import ru.dbotthepony.mc.otm.core.math.toRadians
|
||||
import ru.dbotthepony.mc.otm.core.otmRandom
|
||||
import ru.dbotthepony.mc.otm.core.position
|
||||
import ru.dbotthepony.mc.otm.core.readEnum
|
||||
import ru.dbotthepony.mc.otm.core.readItem
|
||||
import ru.dbotthepony.mc.otm.core.writeItem
|
||||
import ru.dbotthepony.mc.otm.entity.checkCanInteract
|
||||
import ru.dbotthepony.mc.otm.menu.ExopackInventoryMenu
|
||||
import ru.dbotthepony.mc.otm.menu.QuickMoveInput
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.collections.HashSet
|
||||
|
||||
class MatteryPlayerDataPacket(val bytes: ByteArrayList, val isPublic: Boolean, val target: UUID? = null) : CustomPacketPayload {
|
||||
fun write(buff: FriendlyByteBuf) {
|
||||
@ -414,6 +434,80 @@ object ResetExopackColorPacket : CustomPacketPayload {
|
||||
)
|
||||
}
|
||||
|
||||
// as separate packet so it can be put into non-mattery menus
|
||||
class QuickStackPacket(
|
||||
val mode: QuickMoveInput.Mode,
|
||||
val fromExopack: Boolean
|
||||
) : CustomPacketPayload {
|
||||
fun play(context: IPayloadContext) {
|
||||
val player = context.player() as ServerPlayer
|
||||
if (player.isSpectator) return
|
||||
val radius = player.blockInteractionRange()
|
||||
|
||||
val minChunkPos = ChunkPos(BlockPos.containing(player.position - Vector(radius, 0.0, radius)))
|
||||
val maxChunkPos = ChunkPos(BlockPos.containing(player.position + Vector(radius, 0.0, radius)))
|
||||
|
||||
val findCaps = ArrayList<Pair<BlockEntity, IQuickStackContainer>>()
|
||||
|
||||
for (x in minChunkPos.x .. maxChunkPos.x) {
|
||||
for (z in minChunkPos.z .. maxChunkPos.z) {
|
||||
val chunk = player.serverLevel().chunkSource.getChunkNow(x, z) ?: continue
|
||||
|
||||
for (blockEntity in chunk.blockEntities.values) {
|
||||
if (player.checkCanInteract(blockEntity.blockPos)) {
|
||||
val cap = player.level().getCapability(MatteryCapability.QUICK_STACK_CONTAINER, blockEntity.blockPos) ?: continue
|
||||
findCaps.add(blockEntity to cap)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (findCaps.isEmpty()) return
|
||||
|
||||
val eyes = player.eyePosition
|
||||
val ignoreBlockstates = HashSet<BlockState>()
|
||||
findCaps.forEach { (b, _) -> ignoreBlockstates.add(b.blockState) }
|
||||
|
||||
val slots = ArrayList<Slot>()
|
||||
|
||||
for ((blockEntity, cap) in findCaps) {
|
||||
// don't interact through walls
|
||||
val trace = player.serverLevel().isBlockInLine(ClipBlockStateContext(eyes, Vector.atCenterOf(blockEntity.blockPos)) {
|
||||
!it.isAir && it !in ignoreBlockstates
|
||||
})
|
||||
|
||||
if (trace.blockPos == blockEntity.blockPos) {
|
||||
slots.addAll(cap.getSlotsFor(player))
|
||||
}
|
||||
}
|
||||
|
||||
if (slots.isEmpty()) return
|
||||
|
||||
if (fromExopack)
|
||||
mode.move(player.matteryPlayer.exoPackMenu.playerCombinedInventorySlots, slots, player)
|
||||
else
|
||||
mode.move(slots, player.matteryPlayer.exoPackMenu.playerInventorySlots, player)
|
||||
}
|
||||
|
||||
override fun type(): CustomPacketPayload.Type<out CustomPacketPayload> {
|
||||
return TYPE
|
||||
}
|
||||
|
||||
fun write(buff: FriendlyByteBuf) {
|
||||
buff.writeEnum(mode)
|
||||
buff.writeBoolean(fromExopack)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val TYPE = CustomPacketPayload.Type<QuickStackPacket>(ResourceLocation(OverdriveThatMatters.MOD_ID, "quick_stack"))
|
||||
val CODEC: StreamCodec<FriendlyByteBuf, QuickStackPacket> = StreamCodec.ofMember(QuickStackPacket::write, ::read)
|
||||
|
||||
fun read(buff: FriendlyByteBuf): QuickStackPacket {
|
||||
return QuickStackPacket(buff.readEnum(QuickMoveInput.Mode.entries), buff.readBoolean())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ExopackSmokePacket(val player: UUID) : CustomPacketPayload {
|
||||
fun write(buff: FriendlyByteBuf) {
|
||||
buff.writeUUID(player)
|
||||
|
@ -20,7 +20,7 @@ import ru.dbotthepony.mc.otm.menu.matter.ReplicationRequestPacket
|
||||
import ru.dbotthepony.mc.otm.menu.matter.TasksChangePacket
|
||||
|
||||
internal fun registerNetworkPackets(event: RegisterPayloadHandlersEvent) {
|
||||
val r = event.registrar("1.5.0")
|
||||
val r = event.registrar("1.5.1")
|
||||
|
||||
// world
|
||||
r
|
||||
@ -54,6 +54,7 @@ internal fun registerNetworkPackets(event: RegisterPayloadHandlersEvent) {
|
||||
.playToServer(DisableExopackGlowPacket.TYPE, DisableExopackGlowPacket, DisableExopackGlowPacket::play)
|
||||
.playToServer(ResetExopackColorPacket.TYPE, ResetExopackColorPacket, ResetExopackColorPacket::play)
|
||||
.playToServer(SetExopackColorPacket.TYPE, SetExopackColorPacket.CODEC, SetExopackColorPacket::play)
|
||||
.playToServer(QuickStackPacket.TYPE, QuickStackPacket.CODEC, QuickStackPacket::play)
|
||||
|
||||
// otm player general
|
||||
r
|
||||
|
Loading…
Reference in New Issue
Block a user